@compilr-dev/cli 0.5.0 → 0.5.1
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 +236 -68
- 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 +266 -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 +244 -23
- 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 +5 -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 +3 -2
- package/dist/repl-v2.d.ts +401 -2
- package/dist/repl-v2.js +2577 -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 +108 -0
- package/dist/tool-names.js +227 -0
- package/dist/tools/anchor-tools.d.ts +4 -4
- package/dist/tools/anchor-tools.js +1 -1
- package/dist/tools/artifact-tools.d.ts +42 -0
- package/dist/tools/artifact-tools.js +328 -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-wrappers.d.ts +5 -3
- package/dist/tools/backlog-wrappers.js +16 -1
- package/dist/tools/backlog.d.ts +2 -2
- package/dist/tools/backlog.js +1 -1
- package/dist/tools/db-tools.d.ts +8 -61
- package/dist/tools/db-tools.js +8 -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/document-db.d.ts +5 -5
- package/dist/tools/document-db.js +1 -1
- 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/plan-tools.d.ts +54 -0
- package/dist/tools/plan-tools.js +338 -0
- package/dist/tools/platform-adapter.d.ts +29 -0
- package/dist/tools/platform-adapter.js +394 -0
- package/dist/tools/project-db.d.ts +5 -73
- package/dist/tools/project-db.js +5 -336
- package/dist/tools/recall-work-tool.d.ts +18 -0
- package/dist/tools/recall-work-tool.js +82 -0
- package/dist/tools/workitem-db.d.ts +43 -11
- package/dist/tools/workitem-db.js +186 -5
- package/dist/tools.d.ts +67 -2
- package/dist/tools.js +237 -47
- 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 +51 -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.js +5 -1
- 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 +512 -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 +25 -12
- 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/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,650 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Session Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages per-project session persistence. Each project has its own
|
|
5
|
+
* session directory with terminal-scoped sessions and optional history.
|
|
6
|
+
*
|
|
7
|
+
* Directory structure:
|
|
8
|
+
* ~/.compilr-dev/sessions/
|
|
9
|
+
* ├── project-{id}/
|
|
10
|
+
* │ ├── current-{8hex}.json # Active session (terminal-scoped)
|
|
11
|
+
* │ └── history/ # Previous sessions (optional)
|
|
12
|
+
* │ └── {timestamp}.json
|
|
13
|
+
* └── global/
|
|
14
|
+
* └── current-{8hex}.json # Quick chat mode (no project)
|
|
15
|
+
*/
|
|
16
|
+
import * as fs from 'fs';
|
|
17
|
+
import * as path from 'path';
|
|
18
|
+
import { getSessionsPath } from '../settings/paths.js';
|
|
19
|
+
import { truncatePlain as truncate } from '@compilr-dev/ui-core/utils';
|
|
20
|
+
import { getActiveTerminalSessionId } from '../multi-agent/session-registry.js';
|
|
21
|
+
import { getDb } from '../db/index.js';
|
|
22
|
+
import { getTeamCheckpointer } from '../multi-agent/checkpointer.js';
|
|
23
|
+
// =============================================================================
|
|
24
|
+
// Constants
|
|
25
|
+
// =============================================================================
|
|
26
|
+
const GLOBAL_SESSION_DIR = 'global';
|
|
27
|
+
const HISTORY_DIR = 'history';
|
|
28
|
+
/**
|
|
29
|
+
* Get the current session filename, scoped to this terminal.
|
|
30
|
+
* Requires an active terminal session ID.
|
|
31
|
+
*/
|
|
32
|
+
function getCurrentSessionFilename() {
|
|
33
|
+
const sessionId = getActiveTerminalSessionId();
|
|
34
|
+
if (sessionId) {
|
|
35
|
+
return `current-${sessionId.slice(0, 8)}.json`;
|
|
36
|
+
}
|
|
37
|
+
// Shouldn't happen — terminal session is always registered at startup.
|
|
38
|
+
// Use a random prefix to avoid collisions if it somehow does.
|
|
39
|
+
const fallback = Math.random().toString(16).slice(2, 10);
|
|
40
|
+
return `current-${fallback}.json`;
|
|
41
|
+
}
|
|
42
|
+
// =============================================================================
|
|
43
|
+
// Project Session Manager
|
|
44
|
+
// =============================================================================
|
|
45
|
+
export class ProjectSessionManager {
|
|
46
|
+
sessionsPath;
|
|
47
|
+
constructor(sessionsPath) {
|
|
48
|
+
this.sessionsPath = sessionsPath ?? getSessionsPath();
|
|
49
|
+
}
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// Path Helpers
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
/**
|
|
54
|
+
* Get the session directory for a project.
|
|
55
|
+
*/
|
|
56
|
+
getProjectSessionDir(projectId) {
|
|
57
|
+
if (projectId === null) {
|
|
58
|
+
return path.join(this.sessionsPath, GLOBAL_SESSION_DIR);
|
|
59
|
+
}
|
|
60
|
+
return path.join(this.sessionsPath, `project-${String(projectId)}`);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get the path to the current session file for a project.
|
|
64
|
+
* Uses terminal-scoped filename when multi-terminal is active.
|
|
65
|
+
*/
|
|
66
|
+
getCurrentSessionPath(projectId) {
|
|
67
|
+
return path.join(this.getProjectSessionDir(projectId), getCurrentSessionFilename());
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get the path to the history directory for a project.
|
|
71
|
+
*/
|
|
72
|
+
getHistoryDir(projectId) {
|
|
73
|
+
return path.join(this.getProjectSessionDir(projectId), HISTORY_DIR);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Ensure project session directory exists.
|
|
77
|
+
*/
|
|
78
|
+
ensureProjectSessionDir(projectId) {
|
|
79
|
+
const dir = this.getProjectSessionDir(projectId);
|
|
80
|
+
if (!fs.existsSync(dir)) {
|
|
81
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
// Save/Load Operations
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
/**
|
|
88
|
+
* Save a session for a project.
|
|
89
|
+
* Overwrites the current session file.
|
|
90
|
+
*/
|
|
91
|
+
async saveProjectSession(projectId, projectName, state, workflowState) {
|
|
92
|
+
this.ensureProjectSessionDir(projectId);
|
|
93
|
+
const session = {
|
|
94
|
+
sessionId: state.sessionId,
|
|
95
|
+
projectId,
|
|
96
|
+
projectName,
|
|
97
|
+
messages: state.messages,
|
|
98
|
+
todos: state.todos,
|
|
99
|
+
turnCount: state.turnCount,
|
|
100
|
+
totalTokensUsed: state.totalTokensUsed,
|
|
101
|
+
workflowState,
|
|
102
|
+
createdAt: new Date().toISOString(),
|
|
103
|
+
updatedAt: new Date().toISOString(),
|
|
104
|
+
};
|
|
105
|
+
// Check if current session exists - preserve createdAt
|
|
106
|
+
const existingPath = this.getCurrentSessionPath(projectId);
|
|
107
|
+
if (fs.existsSync(existingPath)) {
|
|
108
|
+
try {
|
|
109
|
+
const existing = JSON.parse(fs.readFileSync(existingPath, 'utf-8'));
|
|
110
|
+
session.createdAt = existing.createdAt;
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// Ignore parse errors
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const content = JSON.stringify(session, null, 2);
|
|
117
|
+
await fs.promises.writeFile(existingPath, content, 'utf-8');
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Load the current session for a project.
|
|
121
|
+
* Returns null if no session exists.
|
|
122
|
+
*/
|
|
123
|
+
async loadProjectSession(projectId) {
|
|
124
|
+
const sessionPath = this.getCurrentSessionPath(projectId);
|
|
125
|
+
if (!fs.existsSync(sessionPath))
|
|
126
|
+
return null;
|
|
127
|
+
try {
|
|
128
|
+
const content = await fs.promises.readFile(sessionPath, 'utf-8');
|
|
129
|
+
return JSON.parse(content);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Load a specific terminal's session file by prefix.
|
|
137
|
+
* Used when resuming another terminal's session from the resume overlay.
|
|
138
|
+
*/
|
|
139
|
+
async loadProjectSessionByPrefix(projectId, terminalPrefix) {
|
|
140
|
+
const dir = this.getProjectSessionDir(projectId);
|
|
141
|
+
const sessionPath = path.join(dir, `current-${terminalPrefix}.json`);
|
|
142
|
+
if (!fs.existsSync(sessionPath))
|
|
143
|
+
return null;
|
|
144
|
+
try {
|
|
145
|
+
const content = await fs.promises.readFile(sessionPath, 'utf-8');
|
|
146
|
+
return JSON.parse(content);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Delete a specific terminal's current session file.
|
|
154
|
+
*/
|
|
155
|
+
async deleteSessionByPrefix(projectId, terminalPrefix) {
|
|
156
|
+
const dir = this.getProjectSessionDir(projectId);
|
|
157
|
+
const sessionPath = path.join(dir, `current-${terminalPrefix}.json`);
|
|
158
|
+
if (!fs.existsSync(sessionPath))
|
|
159
|
+
return false;
|
|
160
|
+
try {
|
|
161
|
+
await fs.promises.unlink(sessionPath);
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Claim a session from another terminal by renaming its file to this terminal's prefix.
|
|
170
|
+
* This makes the session "owned" by the current terminal so other terminals won't see it
|
|
171
|
+
* as available.
|
|
172
|
+
*/
|
|
173
|
+
claimSession(projectId, fromPrefix, toPrefix) {
|
|
174
|
+
const dir = this.getProjectSessionDir(projectId);
|
|
175
|
+
const fromPath = path.join(dir, `current-${fromPrefix}.json`);
|
|
176
|
+
const toPath = path.join(dir, `current-${toPrefix}.json`);
|
|
177
|
+
if (!fs.existsSync(fromPath))
|
|
178
|
+
return false;
|
|
179
|
+
try {
|
|
180
|
+
fs.renameSync(fromPath, toPath);
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Check if a project has a current session for this terminal.
|
|
189
|
+
*/
|
|
190
|
+
hasProjectSession(projectId) {
|
|
191
|
+
return fs.existsSync(this.getCurrentSessionPath(projectId));
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Fast check: does the current project have a session modified within maxAge ms?
|
|
195
|
+
* Uses fs.statSync — O(1) instead of scanning all session directories.
|
|
196
|
+
*/
|
|
197
|
+
hasRecentSessionFast(projectId, maxAgeMs = 24 * 60 * 60 * 1000) {
|
|
198
|
+
const sessionPath = this.getCurrentSessionPath(projectId);
|
|
199
|
+
try {
|
|
200
|
+
const stat = fs.statSync(sessionPath);
|
|
201
|
+
return Date.now() - stat.mtimeMs < maxAgeMs;
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Archive the current session to history (before starting fresh).
|
|
209
|
+
*/
|
|
210
|
+
async archiveCurrentSession(projectId) {
|
|
211
|
+
const currentPath = this.getCurrentSessionPath(projectId);
|
|
212
|
+
if (!fs.existsSync(currentPath)) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
try {
|
|
216
|
+
const historyDir = this.getHistoryDir(projectId);
|
|
217
|
+
fs.mkdirSync(historyDir, { recursive: true });
|
|
218
|
+
// Generate timestamp-based filename
|
|
219
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
220
|
+
const historyPath = path.join(historyDir, `${timestamp}.json`);
|
|
221
|
+
// Move current to history
|
|
222
|
+
await fs.promises.rename(currentPath, historyPath);
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Delete the current session for a project.
|
|
231
|
+
*/
|
|
232
|
+
async deleteCurrentSession(projectId) {
|
|
233
|
+
const currentPath = this.getCurrentSessionPath(projectId);
|
|
234
|
+
if (!fs.existsSync(currentPath)) {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
try {
|
|
238
|
+
await fs.promises.unlink(currentPath);
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// ---------------------------------------------------------------------------
|
|
246
|
+
// Listing Operations
|
|
247
|
+
// ---------------------------------------------------------------------------
|
|
248
|
+
/**
|
|
249
|
+
* List all sessions grouped by project.
|
|
250
|
+
*/
|
|
251
|
+
async listAllSessions() {
|
|
252
|
+
const result = new Map();
|
|
253
|
+
if (!fs.existsSync(this.sessionsPath)) {
|
|
254
|
+
return result;
|
|
255
|
+
}
|
|
256
|
+
const entries = await fs.promises.readdir(this.sessionsPath, { withFileTypes: true });
|
|
257
|
+
for (const entry of entries) {
|
|
258
|
+
if (!entry.isDirectory())
|
|
259
|
+
continue;
|
|
260
|
+
let projectId = null;
|
|
261
|
+
if (entry.name === GLOBAL_SESSION_DIR) {
|
|
262
|
+
projectId = null;
|
|
263
|
+
}
|
|
264
|
+
else if (entry.name.startsWith('project-')) {
|
|
265
|
+
const idStr = entry.name.replace('project-', '');
|
|
266
|
+
projectId = parseInt(idStr, 10);
|
|
267
|
+
if (isNaN(projectId))
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
const sessions = await this.listProjectSessions(projectId);
|
|
274
|
+
if (sessions.length > 0) {
|
|
275
|
+
result.set(projectId, sessions);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return result;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* List sessions for a specific project (all current terminals + history).
|
|
282
|
+
*/
|
|
283
|
+
async listProjectSessions(projectId) {
|
|
284
|
+
const sessions = [];
|
|
285
|
+
// Load ALL terminal-scoped current sessions (not just ours)
|
|
286
|
+
const currentSessions = await this.listAllCurrentSessions(projectId);
|
|
287
|
+
sessions.push(...currentSessions);
|
|
288
|
+
// Load history sessions
|
|
289
|
+
const historyDir = this.getHistoryDir(projectId);
|
|
290
|
+
if (fs.existsSync(historyDir)) {
|
|
291
|
+
const historyFiles = await fs.promises.readdir(historyDir);
|
|
292
|
+
for (const file of historyFiles) {
|
|
293
|
+
if (!file.endsWith('.json'))
|
|
294
|
+
continue;
|
|
295
|
+
try {
|
|
296
|
+
const content = await fs.promises.readFile(path.join(historyDir, file), 'utf-8');
|
|
297
|
+
const session = JSON.parse(content);
|
|
298
|
+
sessions.push(this.toSessionInfo(session, false));
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
// Skip invalid files
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
// Sort by updatedAt descending
|
|
306
|
+
sessions.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
|
|
307
|
+
return sessions;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Scan a project directory for ALL current-*.json files (not just this terminal's).
|
|
311
|
+
* Returns a ProjectSessionInfo for each one found.
|
|
312
|
+
*/
|
|
313
|
+
async listAllCurrentSessions(projectId) {
|
|
314
|
+
const dir = this.getProjectSessionDir(projectId);
|
|
315
|
+
if (!fs.existsSync(dir))
|
|
316
|
+
return [];
|
|
317
|
+
const files = await fs.promises.readdir(dir);
|
|
318
|
+
const sessions = [];
|
|
319
|
+
for (const file of files) {
|
|
320
|
+
// Match current-{8hex}.json only (skip legacy current.json)
|
|
321
|
+
if (!/^current-[a-f0-9]{8}\.json$/.test(file))
|
|
322
|
+
continue;
|
|
323
|
+
try {
|
|
324
|
+
const content = await fs.promises.readFile(path.join(dir, file), 'utf-8');
|
|
325
|
+
const session = JSON.parse(content);
|
|
326
|
+
const terminalPrefix = this.extractTerminalPrefix(file);
|
|
327
|
+
sessions.push(this.toSessionInfo(session, true, terminalPrefix));
|
|
328
|
+
}
|
|
329
|
+
catch {
|
|
330
|
+
// Skip invalid files
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return sessions;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Extract the 8-hex terminal prefix from a session filename.
|
|
337
|
+
*/
|
|
338
|
+
extractTerminalPrefix(filename) {
|
|
339
|
+
const match = /^current-([a-f0-9]{8})\.json$/.exec(filename);
|
|
340
|
+
return match ? match[1] : null;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Look up terminal info (label, active status) from the terminal_sessions table.
|
|
344
|
+
* If the terminal has exited (row deleted), returns a fallback label from the prefix.
|
|
345
|
+
*/
|
|
346
|
+
getTerminalInfo(prefix) {
|
|
347
|
+
try {
|
|
348
|
+
// Check for active terminal first
|
|
349
|
+
const row = getDb().prepare(`SELECT label, status FROM terminal_sessions WHERE id LIKE ? || '%' LIMIT 1`).get(prefix);
|
|
350
|
+
if (row) {
|
|
351
|
+
return {
|
|
352
|
+
label: row.label ?? `Terminal ${prefix.slice(0, 4)}`,
|
|
353
|
+
isActive: row.status === 'active',
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
catch {
|
|
358
|
+
// DB not available — fall through to fallback
|
|
359
|
+
}
|
|
360
|
+
// Terminal exited and row was deleted — generate fallback label
|
|
361
|
+
return { label: `Terminal ${prefix.slice(0, 4)}`, isActive: false };
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Convert ProjectSession to ProjectSessionInfo.
|
|
365
|
+
*/
|
|
366
|
+
toSessionInfo(session, isCurrent, terminalPrefix) {
|
|
367
|
+
// Extract preview from last actual user message (not tool_result)
|
|
368
|
+
let preview = '';
|
|
369
|
+
// Filter to only user messages that have actual text content (not tool_result)
|
|
370
|
+
const userTextMessages = session.messages.filter((m) => {
|
|
371
|
+
if (m.role !== 'user')
|
|
372
|
+
return false;
|
|
373
|
+
// String content is always user text
|
|
374
|
+
if (typeof m.content === 'string')
|
|
375
|
+
return true;
|
|
376
|
+
// Array content - check if it has text blocks (not just tool_result)
|
|
377
|
+
if (Array.isArray(m.content)) {
|
|
378
|
+
return m.content.some((b) => b.type === 'text');
|
|
379
|
+
}
|
|
380
|
+
return false;
|
|
381
|
+
});
|
|
382
|
+
if (userTextMessages.length > 0) {
|
|
383
|
+
const lastUserMsg = userTextMessages[userTextMessages.length - 1];
|
|
384
|
+
if (typeof lastUserMsg.content === 'string') {
|
|
385
|
+
preview = lastUserMsg.content;
|
|
386
|
+
}
|
|
387
|
+
else if (Array.isArray(lastUserMsg.content)) {
|
|
388
|
+
const textBlock = lastUserMsg.content.find((b) => b.type === 'text');
|
|
389
|
+
if (textBlock?.type === 'text') {
|
|
390
|
+
preview = textBlock.text;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
// Truncate preview
|
|
395
|
+
const maxPreviewLen = 100;
|
|
396
|
+
if (preview.length > maxPreviewLen) {
|
|
397
|
+
preview = truncate(preview, maxPreviewLen);
|
|
398
|
+
}
|
|
399
|
+
// Sanitize preview (remove markdown, newlines)
|
|
400
|
+
preview = preview.replace(/^#+\s*/gm, '').replace(/\n/g, ' ').trim();
|
|
401
|
+
// Build session ID that preserves terminal identity
|
|
402
|
+
let sessionId;
|
|
403
|
+
if (isCurrent) {
|
|
404
|
+
const projectSuffix = session.projectId !== null ? String(session.projectId) : 'global';
|
|
405
|
+
sessionId = terminalPrefix
|
|
406
|
+
? `current-${terminalPrefix}-${projectSuffix}`
|
|
407
|
+
: `current-${projectSuffix}`;
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
sessionId = session.sessionId;
|
|
411
|
+
}
|
|
412
|
+
// Look up terminal info from DB if we have a prefix
|
|
413
|
+
let terminalLabel = null;
|
|
414
|
+
let isActiveTerminal = false;
|
|
415
|
+
if (terminalPrefix) {
|
|
416
|
+
const ownSessionId = getActiveTerminalSessionId();
|
|
417
|
+
const ownPrefix = ownSessionId ? ownSessionId.slice(0, 8) : null;
|
|
418
|
+
if (terminalPrefix === ownPrefix) {
|
|
419
|
+
// This is our own session — use our known label
|
|
420
|
+
isActiveTerminal = true;
|
|
421
|
+
try {
|
|
422
|
+
const row = getDb().prepare(`SELECT label FROM terminal_sessions WHERE id = ? LIMIT 1`).get(ownSessionId);
|
|
423
|
+
terminalLabel = row?.label ?? 'This terminal';
|
|
424
|
+
}
|
|
425
|
+
catch {
|
|
426
|
+
terminalLabel = 'This terminal';
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
const info = this.getTerminalInfo(terminalPrefix);
|
|
431
|
+
terminalLabel = info.label;
|
|
432
|
+
isActiveTerminal = info.isActive;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
// Look up team agent count from team file (if terminal-scoped)
|
|
436
|
+
let teamAgentCount = 0;
|
|
437
|
+
if (terminalPrefix) {
|
|
438
|
+
try {
|
|
439
|
+
teamAgentCount = getTeamCheckpointer().getTeamAgentCountByPrefix(session.projectId, terminalPrefix);
|
|
440
|
+
}
|
|
441
|
+
catch {
|
|
442
|
+
// Best effort
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
return {
|
|
446
|
+
sessionId,
|
|
447
|
+
createdAt: session.createdAt,
|
|
448
|
+
updatedAt: session.updatedAt,
|
|
449
|
+
messageCount: session.messages.length,
|
|
450
|
+
preview,
|
|
451
|
+
projectId: session.projectId,
|
|
452
|
+
projectName: session.projectName,
|
|
453
|
+
workflowMode: session.workflowState?.mode,
|
|
454
|
+
terminalPrefix: terminalPrefix ?? null,
|
|
455
|
+
terminalLabel,
|
|
456
|
+
isActiveTerminal,
|
|
457
|
+
teamAgentCount,
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
// ---------------------------------------------------------------------------
|
|
461
|
+
// Cleanup
|
|
462
|
+
// ---------------------------------------------------------------------------
|
|
463
|
+
/**
|
|
464
|
+
* Delete legacy (pre-multi-terminal) files from all project session directories.
|
|
465
|
+
* Removes: current.json, team.json, shared-context.json, agent-{id}.json (no 8-hex prefix).
|
|
466
|
+
* Call once at startup. Safe to call multiple times (no-op if no legacy files).
|
|
467
|
+
*/
|
|
468
|
+
async cleanupLegacyFiles() {
|
|
469
|
+
if (!fs.existsSync(this.sessionsPath))
|
|
470
|
+
return 0;
|
|
471
|
+
let deleted = 0;
|
|
472
|
+
// Legacy file patterns (no 8-hex terminal prefix)
|
|
473
|
+
const isLegacyFile = (name) => {
|
|
474
|
+
if (name === 'current.json')
|
|
475
|
+
return true;
|
|
476
|
+
if (name === 'team.json')
|
|
477
|
+
return true;
|
|
478
|
+
if (name === 'shared-context.json')
|
|
479
|
+
return true;
|
|
480
|
+
// agent-{id}.json but NOT agent-{8hex}-{id}.json
|
|
481
|
+
if (name.startsWith('agent-') && name.endsWith('.json')) {
|
|
482
|
+
// New format: agent-{8hex}-{id}.json — has two dashes after "agent-"
|
|
483
|
+
const rest = name.slice('agent-'.length, -'.json'.length);
|
|
484
|
+
// If rest matches {8hex}-{anything}, it's new format → NOT legacy
|
|
485
|
+
if (/^[a-f0-9]{8}-.+$/.test(rest))
|
|
486
|
+
return false;
|
|
487
|
+
return true;
|
|
488
|
+
}
|
|
489
|
+
return false;
|
|
490
|
+
};
|
|
491
|
+
try {
|
|
492
|
+
const entries = await fs.promises.readdir(this.sessionsPath, { withFileTypes: true });
|
|
493
|
+
for (const entry of entries) {
|
|
494
|
+
if (!entry.isDirectory())
|
|
495
|
+
continue;
|
|
496
|
+
const dirPath = path.join(this.sessionsPath, entry.name);
|
|
497
|
+
try {
|
|
498
|
+
const files = await fs.promises.readdir(dirPath);
|
|
499
|
+
for (const file of files) {
|
|
500
|
+
if (isLegacyFile(file)) {
|
|
501
|
+
try {
|
|
502
|
+
await fs.promises.unlink(path.join(dirPath, file));
|
|
503
|
+
deleted++;
|
|
504
|
+
}
|
|
505
|
+
catch {
|
|
506
|
+
// Ignore individual file errors
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
catch {
|
|
512
|
+
// Ignore directory read errors
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
catch {
|
|
517
|
+
// Ignore top-level errors
|
|
518
|
+
}
|
|
519
|
+
return deleted;
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Delete old history sessions beyond retention limit.
|
|
523
|
+
*/
|
|
524
|
+
async cleanupHistory(projectId, maxHistoryCount = 10) {
|
|
525
|
+
const historyDir = this.getHistoryDir(projectId);
|
|
526
|
+
if (!fs.existsSync(historyDir)) {
|
|
527
|
+
return 0;
|
|
528
|
+
}
|
|
529
|
+
const files = await fs.promises.readdir(historyDir);
|
|
530
|
+
const jsonFiles = files.filter((f) => f.endsWith('.json'));
|
|
531
|
+
if (jsonFiles.length <= maxHistoryCount) {
|
|
532
|
+
return 0;
|
|
533
|
+
}
|
|
534
|
+
// Sort by filename (timestamp-based, oldest first)
|
|
535
|
+
jsonFiles.sort();
|
|
536
|
+
const toDelete = jsonFiles.slice(0, jsonFiles.length - maxHistoryCount);
|
|
537
|
+
let deleted = 0;
|
|
538
|
+
for (const file of toDelete) {
|
|
539
|
+
try {
|
|
540
|
+
await fs.promises.unlink(path.join(historyDir, file));
|
|
541
|
+
deleted++;
|
|
542
|
+
}
|
|
543
|
+
catch {
|
|
544
|
+
// Ignore errors
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return deleted;
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Clean up old sessions across all projects based on retention days.
|
|
551
|
+
* Only deletes history files — current sessions are always preserved.
|
|
552
|
+
* Returns count of deleted files.
|
|
553
|
+
*/
|
|
554
|
+
async cleanupOldSessions(retentionDays) {
|
|
555
|
+
if (retentionDays <= 0)
|
|
556
|
+
return 0; // 0 = forever, no cleanup
|
|
557
|
+
if (!fs.existsSync(this.sessionsPath))
|
|
558
|
+
return 0;
|
|
559
|
+
const cutoffMs = Date.now() - (retentionDays * 24 * 60 * 60 * 1000);
|
|
560
|
+
let totalDeleted = 0;
|
|
561
|
+
try {
|
|
562
|
+
const entries = await fs.promises.readdir(this.sessionsPath, { withFileTypes: true });
|
|
563
|
+
for (const entry of entries) {
|
|
564
|
+
if (!entry.isDirectory())
|
|
565
|
+
continue;
|
|
566
|
+
const historyDir = path.join(this.sessionsPath, entry.name, HISTORY_DIR);
|
|
567
|
+
if (!fs.existsSync(historyDir))
|
|
568
|
+
continue;
|
|
569
|
+
try {
|
|
570
|
+
const files = await fs.promises.readdir(historyDir);
|
|
571
|
+
for (const file of files) {
|
|
572
|
+
if (!file.endsWith('.json'))
|
|
573
|
+
continue;
|
|
574
|
+
const filePath = path.join(historyDir, file);
|
|
575
|
+
try {
|
|
576
|
+
const stat = await fs.promises.stat(filePath);
|
|
577
|
+
if (stat.mtimeMs < cutoffMs) {
|
|
578
|
+
await fs.promises.unlink(filePath);
|
|
579
|
+
totalDeleted++;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
catch {
|
|
583
|
+
// Skip individual file errors
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
catch {
|
|
588
|
+
// Skip directory read errors
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
catch {
|
|
593
|
+
// Best effort cleanup
|
|
594
|
+
}
|
|
595
|
+
return totalDeleted;
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Delete all history files for a specific project.
|
|
599
|
+
* Optionally also deletes the current session.
|
|
600
|
+
* Returns count of deleted files.
|
|
601
|
+
*/
|
|
602
|
+
async deleteProjectHistory(projectId, includeCurrentSession = false) {
|
|
603
|
+
let deleted = 0;
|
|
604
|
+
// Delete history files
|
|
605
|
+
const historyDir = this.getHistoryDir(projectId);
|
|
606
|
+
if (fs.existsSync(historyDir)) {
|
|
607
|
+
try {
|
|
608
|
+
const files = await fs.promises.readdir(historyDir);
|
|
609
|
+
for (const file of files) {
|
|
610
|
+
if (!file.endsWith('.json'))
|
|
611
|
+
continue;
|
|
612
|
+
try {
|
|
613
|
+
await fs.promises.unlink(path.join(historyDir, file));
|
|
614
|
+
deleted++;
|
|
615
|
+
}
|
|
616
|
+
catch {
|
|
617
|
+
// Skip individual file errors
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
catch {
|
|
622
|
+
// Best effort
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
// Optionally delete current session
|
|
626
|
+
if (includeCurrentSession) {
|
|
627
|
+
const currentPath = this.getCurrentSessionPath(projectId);
|
|
628
|
+
if (fs.existsSync(currentPath)) {
|
|
629
|
+
try {
|
|
630
|
+
await fs.promises.unlink(currentPath);
|
|
631
|
+
deleted++;
|
|
632
|
+
}
|
|
633
|
+
catch {
|
|
634
|
+
// Best effort
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
return deleted;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
// =============================================================================
|
|
642
|
+
// Singleton Instance
|
|
643
|
+
// =============================================================================
|
|
644
|
+
let _instance = null;
|
|
645
|
+
export function getProjectSessionManager() {
|
|
646
|
+
if (!_instance) {
|
|
647
|
+
_instance = new ProjectSessionManager();
|
|
648
|
+
}
|
|
649
|
+
return _instance;
|
|
650
|
+
}
|