@compilr-dev/cli 0.4.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 +254 -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 +134 -4
- package/dist/agent.js +345 -166
- package/dist/anchors/index.d.ts +9 -0
- package/dist/anchors/index.js +9 -0
- package/dist/anchors/project-anchors.d.ts +79 -0
- package/dist/anchors/project-anchors.js +202 -0
- 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/index.d.ts +2 -1
- 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.d.ts +13 -0
- package/dist/commands-v2/handlers/context.js +533 -0
- package/dist/commands-v2/handlers/core.d.ts +14 -0
- package/dist/commands-v2/handlers/core.js +290 -0
- package/dist/commands-v2/handlers/debug.d.ts +11 -0
- package/dist/commands-v2/handlers/debug.js +177 -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 +25 -0
- package/dist/commands-v2/handlers/index.js +63 -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.d.ts +22 -0
- package/dist/commands-v2/handlers/project.js +1035 -0
- 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 +17 -0
- package/dist/commands-v2/handlers/settings.js +417 -0
- 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 +14 -0
- package/dist/commands-v2/index.js +18 -0
- package/dist/commands-v2/registry.d.ts +52 -0
- package/dist/commands-v2/registry.js +114 -0
- package/dist/commands-v2/types.d.ts +153 -0
- package/dist/commands-v2/types.js +7 -0
- package/dist/commands.js +123 -7
- 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 +615 -179
- package/dist/input-handlers/index.d.ts +7 -0
- package/dist/input-handlers/index.js +7 -0
- package/dist/input-handlers/memory-handler.d.ts +26 -0
- package/dist/input-handlers/memory-handler.js +69 -0
- 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.d.ts +63 -0
- package/dist/repl-helpers.js +319 -0
- package/dist/repl-v2.d.ts +554 -0
- package/dist/repl-v2.js +3286 -0
- 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 +156 -13
- package/dist/settings/index.js +377 -24
- package/dist/settings/mcp-config.d.ts +76 -0
- package/dist/settings/mcp-config.js +143 -0
- package/dist/settings/paths.d.ts +114 -0
- package/dist/settings/paths.js +270 -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 -58
- package/dist/templates/config-json.d.ts +1 -25
- package/dist/templates/index.d.ts +2 -0
- package/dist/templates/index.js +35 -75
- package/dist/themes/colors.js +3 -1
- package/dist/themes/registry.d.ts +5 -36
- package/dist/themes/registry.js +11 -95
- package/dist/themes/types.d.ts +3 -38
- package/dist/themes/types.js +2 -2
- package/dist/tool-names.d.ts +108 -0
- package/dist/tool-names.js +227 -0
- package/dist/tools/anchor-tools.d.ts +31 -0
- package/dist/tools/anchor-tools.js +255 -0
- 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 +56 -0
- package/dist/tools/backlog-wrappers.js +353 -0
- package/dist/tools/backlog.d.ts +2 -2
- package/dist/tools/backlog.js +2 -2
- package/dist/tools/db-tools.d.ts +12 -0
- package/dist/tools/db-tools.js +14 -0
- 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 +43 -0
- package/dist/tools/document-db.js +220 -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/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 +34 -0
- package/dist/tools/project-db.js +39 -0
- 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 +135 -0
- package/dist/tools/workitem-db.js +730 -0
- package/dist/tools.d.ts +67 -2
- package/dist/tools.js +238 -38
- package/dist/ui/ask-user-overlay.d.ts +2 -2
- package/dist/ui/ask-user-overlay.js +443 -535
- package/dist/ui/ask-user-simple-overlay.d.ts +2 -2
- package/dist/ui/ask-user-simple-overlay.js +182 -209
- package/dist/ui/autocomplete-controller.d.ts +42 -0
- package/dist/ui/autocomplete-controller.js +384 -0
- package/dist/ui/base/index.d.ts +26 -0
- package/dist/ui/base/index.js +33 -0
- package/dist/ui/base/inline-overlay-utils.d.ts +217 -0
- package/dist/ui/base/inline-overlay-utils.js +320 -0
- package/dist/ui/base/inline-overlay.d.ts +159 -0
- package/dist/ui/base/inline-overlay.js +257 -0
- package/dist/ui/base/key-utils.d.ts +15 -0
- package/dist/ui/base/key-utils.js +30 -0
- package/dist/ui/base/overlay-base-v2.d.ts +203 -0
- package/dist/ui/base/overlay-base-v2.js +260 -0
- package/dist/ui/base/overlay-base.d.ts +156 -0
- package/dist/ui/base/overlay-base.js +238 -0
- package/dist/ui/base/overlay-lifecycle.d.ts +65 -0
- package/dist/ui/base/overlay-lifecycle.js +159 -0
- package/dist/ui/base/overlay-types.d.ts +185 -0
- package/dist/ui/base/overlay-types.js +7 -0
- package/dist/ui/base/render-utils.d.ts +27 -0
- package/dist/ui/base/render-utils.js +36 -0
- package/dist/ui/base/screen-stack.d.ts +148 -0
- package/dist/ui/base/screen-stack.js +184 -0
- package/dist/ui/base/tabbed-list-overlay-v2.d.ts +118 -0
- package/dist/ui/base/tabbed-list-overlay-v2.js +335 -0
- package/dist/ui/base/tabbed-list-overlay.d.ts +153 -0
- package/dist/ui/base/tabbed-list-overlay.js +369 -0
- 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.d.ts +75 -4
- package/dist/ui/conversation.js +376 -165
- package/dist/ui/diff.d.ts +7 -1
- package/dist/ui/diff.js +85 -48
- package/dist/ui/ephemeral.d.ts +1 -1
- package/dist/ui/ephemeral.js +4 -10
- package/dist/ui/features/index.d.ts +34 -0
- package/dist/ui/features/index.js +34 -0
- package/dist/ui/features/input-feature.d.ts +85 -0
- package/dist/ui/features/input-feature.js +238 -0
- package/dist/ui/features/list-feature.d.ts +155 -0
- package/dist/ui/features/list-feature.js +244 -0
- package/dist/ui/features/pagination-feature.d.ts +154 -0
- package/dist/ui/features/pagination-feature.js +238 -0
- package/dist/ui/features/search-feature.d.ts +148 -0
- package/dist/ui/features/search-feature.js +185 -0
- package/dist/ui/features/tab-feature.d.ts +194 -0
- package/dist/ui/features/tab-feature.js +307 -0
- 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 +181 -7
- package/dist/ui/footer.js +523 -74
- package/dist/ui/guardrail-overlay.d.ts +29 -0
- package/dist/ui/guardrail-overlay.js +145 -0
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +1 -3
- package/dist/ui/input-controller.d.ts +51 -0
- package/dist/ui/input-controller.js +176 -0
- package/dist/ui/input-prompt.d.ts +135 -33
- package/dist/ui/input-prompt.js +728 -337
- package/dist/ui/iteration-limit-overlay.d.ts +2 -2
- package/dist/ui/iteration-limit-overlay.js +92 -128
- package/dist/ui/keyboard-handler.d.ts +57 -0
- package/dist/ui/keyboard-handler.js +557 -0
- package/dist/ui/keys-overlay.d.ts +1 -0
- package/dist/ui/keys-overlay.js +203 -141
- package/dist/ui/line-utils.d.ts +88 -0
- package/dist/ui/line-utils.js +150 -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 +157 -0
- package/dist/ui/live-region.js +379 -0
- package/dist/ui/mascot/expressions.d.ts +32 -0
- package/dist/ui/mascot/expressions.js +213 -0
- package/dist/ui/mascot/index.d.ts +8 -0
- package/dist/ui/mascot/index.js +8 -0
- package/dist/ui/mascot/renderer.d.ts +19 -0
- package/dist/ui/mascot/renderer.js +132 -0
- 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.d.ts +45 -0
- package/dist/ui/overlay/impl/agents-overlay-v2.js +814 -0
- package/dist/ui/overlay/impl/anchors-overlay-v2.d.ts +47 -0
- package/dist/ui/overlay/impl/anchors-overlay-v2.js +749 -0
- package/dist/ui/overlay/impl/arch-type-overlay-v2.d.ts +37 -0
- package/dist/ui/overlay/impl/arch-type-overlay-v2.js +240 -0
- 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.d.ts +72 -0
- package/dist/ui/overlay/impl/ask-user-overlay-v2.js +581 -0
- package/dist/ui/overlay/impl/ask-user-simple-overlay-v2.d.ts +46 -0
- package/dist/ui/overlay/impl/ask-user-simple-overlay-v2.js +204 -0
- 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 +52 -0
- package/dist/ui/overlay/impl/backlog-overlay-v2.js +681 -0
- 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.d.ts +33 -0
- package/dist/ui/overlay/impl/commands-overlay-v2.js +439 -0
- package/dist/ui/overlay/impl/config-overlay-v2.d.ts +111 -0
- package/dist/ui/overlay/impl/config-overlay-v2.js +718 -0
- 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 +57 -0
- package/dist/ui/overlay/impl/dashboard-overlay-v2.js +382 -0
- 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.d.ts +45 -0
- package/dist/ui/overlay/impl/docs-overlay-v2.js +117 -0
- package/dist/ui/overlay/impl/document-detail-overlay-v2.d.ts +84 -0
- package/dist/ui/overlay/impl/document-detail-overlay-v2.js +1112 -0
- 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/guardrail-overlay-v2.d.ts +43 -0
- package/dist/ui/overlay/impl/guardrail-overlay-v2.js +114 -0
- package/dist/ui/overlay/impl/help-overlay-v2.d.ts +57 -0
- package/dist/ui/overlay/impl/help-overlay-v2.js +287 -0
- package/dist/ui/overlay/impl/init-setup-overlay-v2.d.ts +25 -0
- package/dist/ui/overlay/impl/init-setup-overlay-v2.js +97 -0
- package/dist/ui/overlay/impl/iteration-limit-overlay-v2.d.ts +35 -0
- package/dist/ui/overlay/impl/iteration-limit-overlay-v2.js +105 -0
- package/dist/ui/overlay/impl/keys-overlay-v2.d.ts +41 -0
- package/dist/ui/overlay/impl/keys-overlay-v2.js +248 -0
- 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/mascot-overlay-v2.d.ts +41 -0
- package/dist/ui/overlay/impl/mascot-overlay-v2.js +138 -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 +93 -0
- package/dist/ui/overlay/impl/model-overlay-v2.js +1143 -0
- package/dist/ui/overlay/impl/model-warning-overlay-v2.d.ts +46 -0
- package/dist/ui/overlay/impl/model-warning-overlay-v2.js +132 -0
- package/dist/ui/overlay/impl/new-overlay-v2.d.ts +108 -0
- package/dist/ui/overlay/impl/new-overlay-v2.js +1243 -0
- 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.d.ts +36 -0
- package/dist/ui/overlay/impl/permission-overlay-v2.js +380 -0
- 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 +37 -0
- package/dist/ui/overlay/impl/projects-overlay-v2.js +733 -0
- 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/theme-overlay-v2.d.ts +42 -0
- package/dist/ui/overlay/impl/theme-overlay-v2.js +135 -0
- package/dist/ui/overlay/impl/tools-overlay-v2.d.ts +47 -0
- package/dist/ui/overlay/impl/tools-overlay-v2.js +214 -0
- package/dist/ui/overlay/impl/tutorial-overlay-v2.d.ts +45 -0
- package/dist/ui/overlay/impl/tutorial-overlay-v2.js +212 -0
- package/dist/ui/overlay/impl/workflow-overlay-v2.d.ts +80 -0
- package/dist/ui/overlay/impl/workflow-overlay-v2.js +641 -0
- package/dist/ui/overlay/index.d.ts +52 -0
- package/dist/ui/overlay/index.js +54 -0
- package/dist/ui/overlay/key-utils.d.ts +6 -0
- package/dist/ui/overlay/key-utils.js +6 -0
- package/dist/ui/overlay/types.d.ts +140 -0
- package/dist/ui/overlay/types.js +22 -0
- package/dist/ui/overlay-manager.d.ts +43 -0
- package/dist/ui/overlay-manager.js +238 -0
- package/dist/ui/overlays.d.ts +0 -4
- package/dist/ui/overlays.js +4 -460
- package/dist/ui/permission-overlay.d.ts +1 -1
- package/dist/ui/permission-overlay.js +189 -300
- package/dist/ui/providers/types.d.ts +178 -0
- package/dist/ui/providers/types.js +9 -0
- package/dist/ui/render-modes.d.ts +36 -0
- package/dist/ui/render-modes.js +44 -0
- package/dist/ui/startup-menu.d.ts +36 -0
- package/dist/ui/startup-menu.js +236 -0
- package/dist/ui/status-bar-controller.d.ts +33 -0
- package/dist/ui/status-bar-controller.js +99 -0
- package/dist/ui/subagent-renderer.d.ts +117 -0
- package/dist/ui/subagent-renderer.js +318 -0
- package/dist/ui/terminal-autocomplete-utils.d.ts +23 -0
- package/dist/ui/terminal-autocomplete-utils.js +83 -0
- package/dist/ui/terminal-codes.d.ts +94 -0
- package/dist/ui/terminal-codes.js +124 -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 +220 -0
- package/dist/ui/terminal-renderer.js +750 -0
- package/dist/ui/terminal-types.d.ts +179 -0
- package/dist/ui/terminal-types.js +34 -0
- package/dist/ui/terminal-ui.d.ts +331 -0
- package/dist/ui/terminal-ui.js +819 -0
- package/dist/ui/terminal.d.ts +20 -0
- package/dist/ui/terminal.js +72 -0
- package/dist/ui/todo-zone.d.ts +19 -1
- package/dist/ui/todo-zone.js +124 -38
- package/dist/ui/tool-formatters.d.ts +16 -0
- package/dist/ui/tool-formatters.js +1027 -0
- 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/debug-log.d.ts +28 -0
- package/dist/utils/debug-log.js +57 -0
- 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 +39 -17
- package/dist/utils/open-browser.d.ts +5 -0
- package/dist/utils/open-browser.js +32 -0
- package/dist/utils/path-safety.d.ts +56 -0
- package/dist/utils/path-safety.js +240 -0
- 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/dist/workflow/guided-mode-injector.d.ts +42 -0
- package/dist/workflow/guided-mode-injector.js +191 -0
- package/dist/workflow/index.d.ts +8 -0
- package/dist/workflow/index.js +8 -0
- package/dist/workflow/step-criteria.d.ts +62 -0
- package/dist/workflow/step-criteria.js +150 -0
- package/dist/workflow/step-tracker.d.ts +92 -0
- package/dist/workflow/step-tracker.js +141 -0
- package/package.json +32 -12
- package/dist/index.old.d.ts +0 -7
- package/dist/index.old.js +0 -1014
- package/dist/repl.d.ts +0 -121
- package/dist/repl.js +0 -1878
- 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.d.ts +0 -12
- package/dist/ui/agents-overlay.js +0 -501
- package/dist/ui/arch-type-overlay.d.ts +0 -20
- package/dist/ui/arch-type-overlay.js +0 -229
- package/dist/ui/backlog-overlay.d.ts +0 -17
- package/dist/ui/backlog-overlay.js +0 -786
- package/dist/ui/commands-overlay.d.ts +0 -11
- package/dist/ui/commands-overlay.js +0 -410
- package/dist/ui/config-overlay.d.ts +0 -34
- package/dist/ui/config-overlay.js +0 -977
- package/dist/ui/init-overlay.d.ts +0 -24
- package/dist/ui/init-overlay.js +0 -525
- package/dist/ui/input-prompt-v2.d.ts +0 -179
- package/dist/ui/input-prompt-v2.js +0 -991
- package/dist/ui/model-warning-overlay.d.ts +0 -30
- package/dist/ui/model-warning-overlay.js +0 -171
- package/dist/ui/tools-overlay.d.ts +0 -26
- package/dist/ui/tools-overlay.js +0 -278
- package/dist/ui/tutorial-overlay.d.ts +0 -10
- package/dist/ui/tutorial-overlay.js +0 -936
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-Based Episode Store
|
|
3
|
+
*
|
|
4
|
+
* Persists work episodes to a JSON file per project.
|
|
5
|
+
* Uses an in-memory cache — all reads are synchronous, writes are async (fire-and-forget).
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import { EFFORT_ORDER } from '@compilr-dev/agents';
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// Constants
|
|
12
|
+
// =============================================================================
|
|
13
|
+
const DEFAULT_MAX_EPISODES = 1000;
|
|
14
|
+
const DEFAULT_MAX_AGE_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// Implementation
|
|
17
|
+
// =============================================================================
|
|
18
|
+
export class FileEpisodeStore {
|
|
19
|
+
filePath;
|
|
20
|
+
maxEpisodes;
|
|
21
|
+
maxAgeMs;
|
|
22
|
+
_episodes = null; // lazy-loaded
|
|
23
|
+
flushPromise = null;
|
|
24
|
+
constructor(options) {
|
|
25
|
+
this.filePath = options.filePath;
|
|
26
|
+
this.maxEpisodes = options.maxEpisodes ?? DEFAULT_MAX_EPISODES;
|
|
27
|
+
this.maxAgeMs = options.maxAgeMs ?? DEFAULT_MAX_AGE_MS;
|
|
28
|
+
}
|
|
29
|
+
/** Lazy-load and return the in-memory episode cache */
|
|
30
|
+
get episodes() {
|
|
31
|
+
if (this._episodes === null) {
|
|
32
|
+
this._episodes = this.loadFromDisk();
|
|
33
|
+
}
|
|
34
|
+
return this._episodes;
|
|
35
|
+
}
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
// Write methods
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
save(episode) {
|
|
40
|
+
this.episodes.push(episode);
|
|
41
|
+
void this.flush();
|
|
42
|
+
}
|
|
43
|
+
saveBatch(episodes) {
|
|
44
|
+
if (episodes.length === 0)
|
|
45
|
+
return;
|
|
46
|
+
this.episodes.push(...episodes);
|
|
47
|
+
void this.flush();
|
|
48
|
+
}
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Read methods (synchronous — read from cache)
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
getAll() {
|
|
53
|
+
return [...this.episodes];
|
|
54
|
+
}
|
|
55
|
+
getByFiles(files) {
|
|
56
|
+
const fileSet = new Set(files);
|
|
57
|
+
return this.episodes.filter((ep) => ep.files.some((f) => fileSet.has(f)));
|
|
58
|
+
}
|
|
59
|
+
getByAgent(agentId) {
|
|
60
|
+
return this.episodes.filter((ep) => ep.agentId === agentId);
|
|
61
|
+
}
|
|
62
|
+
getBySession(sessionId) {
|
|
63
|
+
return this.episodes.filter((ep) => ep.sessionId === sessionId);
|
|
64
|
+
}
|
|
65
|
+
getByTimeRange(start, end) {
|
|
66
|
+
return this.episodes.filter((ep) => ep.timestamp >= start && ep.timestamp <= end);
|
|
67
|
+
}
|
|
68
|
+
getRecent(count) {
|
|
69
|
+
return this.episodes.slice(-count);
|
|
70
|
+
}
|
|
71
|
+
getWorkSummary() {
|
|
72
|
+
const eps = this.episodes;
|
|
73
|
+
// Agent breakdown
|
|
74
|
+
const agentMap = new Map();
|
|
75
|
+
for (const ep of eps) {
|
|
76
|
+
const entry = agentMap.get(ep.agentId) ?? { count: 0, maxEffort: 'trivial', timeMs: 0 };
|
|
77
|
+
entry.count++;
|
|
78
|
+
if (EFFORT_ORDER.indexOf(ep.effort) > EFFORT_ORDER.indexOf(entry.maxEffort)) {
|
|
79
|
+
entry.maxEffort = ep.effort;
|
|
80
|
+
}
|
|
81
|
+
entry.timeMs += ep.durationMs ?? 0;
|
|
82
|
+
agentMap.set(ep.agentId, entry);
|
|
83
|
+
}
|
|
84
|
+
// Top files
|
|
85
|
+
const fileCount = new Map();
|
|
86
|
+
for (const ep of eps) {
|
|
87
|
+
for (const f of ep.files) {
|
|
88
|
+
fileCount.set(f, (fileCount.get(f) ?? 0) + 1);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const topFiles = [...fileCount.entries()]
|
|
92
|
+
.sort((a, b) => b[1] - a[1])
|
|
93
|
+
.slice(0, 10)
|
|
94
|
+
.map(([p, touchCount]) => ({ path: p, touchCount }));
|
|
95
|
+
// Uncommitted work: episodes after last git_commit episode
|
|
96
|
+
let lastCommitIdx = -1;
|
|
97
|
+
for (let i = eps.length - 1; i >= 0; i--) {
|
|
98
|
+
if (eps[i].action === 'commit') {
|
|
99
|
+
lastCommitIdx = i;
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const uncommittedWork = lastCommitIdx >= 0 ? eps.slice(lastCommitIdx + 1) : [...eps];
|
|
104
|
+
return {
|
|
105
|
+
episodeCount: eps.length,
|
|
106
|
+
totalEffort: this.getTotalEffort(eps),
|
|
107
|
+
timeSpentMs: eps.reduce((sum, ep) => sum + (ep.durationMs ?? 0), 0),
|
|
108
|
+
agentBreakdown: [...agentMap.entries()].map(([agentId, entry]) => ({
|
|
109
|
+
agentId,
|
|
110
|
+
episodeCount: entry.count,
|
|
111
|
+
maxEffort: entry.maxEffort,
|
|
112
|
+
timeSpentMs: entry.timeMs,
|
|
113
|
+
})),
|
|
114
|
+
topFiles,
|
|
115
|
+
uncommittedWork,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
getTotalEffort(episodes) {
|
|
119
|
+
const eps = episodes ?? this.episodes;
|
|
120
|
+
if (eps.length === 0)
|
|
121
|
+
return 'trivial';
|
|
122
|
+
return maxEffort(eps);
|
|
123
|
+
}
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
// Cleanup
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
cleanup(maxAgeMs) {
|
|
128
|
+
const cutoff = new Date(Date.now() - (maxAgeMs ?? this.maxAgeMs)).toISOString();
|
|
129
|
+
const before = this.episodes.length;
|
|
130
|
+
this._episodes = this.episodes.filter((ep) => ep.timestamp > cutoff);
|
|
131
|
+
const removed = before - this._episodes.length;
|
|
132
|
+
if (removed > 0) {
|
|
133
|
+
void this.flush();
|
|
134
|
+
}
|
|
135
|
+
return removed;
|
|
136
|
+
}
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
// Internal
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
loadFromDisk() {
|
|
141
|
+
try {
|
|
142
|
+
if (!fs.existsSync(this.filePath))
|
|
143
|
+
return [];
|
|
144
|
+
const raw = fs.readFileSync(this.filePath, 'utf-8');
|
|
145
|
+
const data = JSON.parse(raw);
|
|
146
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- runtime data from disk, version may differ
|
|
147
|
+
if (data.version === 1 && Array.isArray(data.episodes)) {
|
|
148
|
+
return data.episodes;
|
|
149
|
+
}
|
|
150
|
+
return [];
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// Corrupted file — start fresh
|
|
154
|
+
return [];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async flush() {
|
|
158
|
+
// Coalesce concurrent flushes
|
|
159
|
+
if (this.flushPromise)
|
|
160
|
+
return this.flushPromise;
|
|
161
|
+
this.flushPromise = (async () => {
|
|
162
|
+
try {
|
|
163
|
+
const dir = path.dirname(this.filePath);
|
|
164
|
+
await fs.promises.mkdir(dir, { recursive: true });
|
|
165
|
+
// Prune to max episodes (keep most recent)
|
|
166
|
+
const eps = this.episodes;
|
|
167
|
+
const prunedEpisodes = eps.length > this.maxEpisodes ? eps.slice(-this.maxEpisodes) : eps;
|
|
168
|
+
if (prunedEpisodes !== eps) {
|
|
169
|
+
this._episodes = prunedEpisodes;
|
|
170
|
+
}
|
|
171
|
+
const data = {
|
|
172
|
+
version: 1,
|
|
173
|
+
episodes: prunedEpisodes,
|
|
174
|
+
lastCleanup: new Date().toISOString(),
|
|
175
|
+
};
|
|
176
|
+
await fs.promises.writeFile(this.filePath, JSON.stringify(data, null, 2), 'utf-8');
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
// Silently fail — episodes are best-effort, never crash the CLI
|
|
180
|
+
}
|
|
181
|
+
finally {
|
|
182
|
+
this.flushPromise = null;
|
|
183
|
+
}
|
|
184
|
+
})();
|
|
185
|
+
return this.flushPromise;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// =============================================================================
|
|
189
|
+
// Helpers (module-private)
|
|
190
|
+
// =============================================================================
|
|
191
|
+
function maxEffort(episodes) {
|
|
192
|
+
let max = 'trivial';
|
|
193
|
+
for (const ep of episodes) {
|
|
194
|
+
if (EFFORT_ORDER.indexOf(ep.effort) > EFFORT_ORDER.indexOf(max)) {
|
|
195
|
+
max = ep.effort;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return max;
|
|
199
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Episodic Memory Types (CLI)
|
|
3
|
+
*
|
|
4
|
+
* Re-exports core types from @compilr-dev/agents and adds CLI-internal types.
|
|
5
|
+
*/
|
|
6
|
+
export type { Effort, WorkEpisode, EffortSignals, EffortWeights, EffortSummary, ProjectWorkSummary, WorkAtRisk, EpisodeStore, } from '@compilr-dev/agents';
|
|
7
|
+
/**
|
|
8
|
+
* Pending tool signal — accumulated during a batch window before
|
|
9
|
+
* being rolled into a WorkEpisode.
|
|
10
|
+
*/
|
|
11
|
+
export interface PendingToolSignal {
|
|
12
|
+
/** Tool name that was invoked */
|
|
13
|
+
toolName: string;
|
|
14
|
+
/** Files affected by this tool call */
|
|
15
|
+
files: string[];
|
|
16
|
+
/** Lines changed, if known */
|
|
17
|
+
linesChanged: number;
|
|
18
|
+
/** Duration of the tool call in milliseconds */
|
|
19
|
+
durationMs: number;
|
|
20
|
+
/** Whether the tool call succeeded */
|
|
21
|
+
success: boolean;
|
|
22
|
+
/** ISO timestamp of the tool call */
|
|
23
|
+
timestamp: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* On-disk format for the episodes JSON file.
|
|
27
|
+
*/
|
|
28
|
+
export interface EpisodeFile {
|
|
29
|
+
/** File format version */
|
|
30
|
+
version: 1;
|
|
31
|
+
/** All stored episodes */
|
|
32
|
+
episodes: import('@compilr-dev/agents').WorkEpisode[];
|
|
33
|
+
/** ISO timestamp of last cleanup */
|
|
34
|
+
lastCleanup: string;
|
|
35
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Work At Risk Query
|
|
3
|
+
*
|
|
4
|
+
* Pure function to query episodes by affected files and build a WorkAtRisk summary.
|
|
5
|
+
* Used by guardrails and rehearsal to warn about destructive operations.
|
|
6
|
+
*/
|
|
7
|
+
import type { EpisodeStore, WorkAtRisk } from '@compilr-dev/agents';
|
|
8
|
+
/**
|
|
9
|
+
* Query episodes that touch any of the given files and build a WorkAtRisk summary.
|
|
10
|
+
* Returns null if no episodes are at risk.
|
|
11
|
+
*/
|
|
12
|
+
export declare function queryWorkAtRisk(store: EpisodeStore, files: string[]): WorkAtRisk | null;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Work At Risk Query
|
|
3
|
+
*
|
|
4
|
+
* Pure function to query episodes by affected files and build a WorkAtRisk summary.
|
|
5
|
+
* Used by guardrails and rehearsal to warn about destructive operations.
|
|
6
|
+
*/
|
|
7
|
+
import { EFFORT_ORDER } from '@compilr-dev/agents';
|
|
8
|
+
/**
|
|
9
|
+
* Query episodes that touch any of the given files and build a WorkAtRisk summary.
|
|
10
|
+
* Returns null if no episodes are at risk.
|
|
11
|
+
*/
|
|
12
|
+
export function queryWorkAtRisk(store, files) {
|
|
13
|
+
const episodes = store.getByFiles(files);
|
|
14
|
+
if (episodes.length === 0)
|
|
15
|
+
return null;
|
|
16
|
+
// Max effort
|
|
17
|
+
let totalEffort = 'trivial';
|
|
18
|
+
for (const ep of episodes) {
|
|
19
|
+
if (EFFORT_ORDER.indexOf(ep.effort) > EFFORT_ORDER.indexOf(totalEffort)) {
|
|
20
|
+
totalEffort = ep.effort;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// Agent attribution: "agentId (terminalPrefix)"
|
|
24
|
+
const seen = new Set();
|
|
25
|
+
const agentAttribution = [];
|
|
26
|
+
for (const ep of episodes) {
|
|
27
|
+
const key = `${ep.agentId} (${ep.terminalPrefix})`;
|
|
28
|
+
if (!seen.has(key)) {
|
|
29
|
+
seen.add(key);
|
|
30
|
+
agentAttribution.push(key);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Warning message
|
|
34
|
+
const fileCount = new Set(episodes.flatMap(ep => ep.files)).size;
|
|
35
|
+
const warningMessage = `⚠️ ${String(episodes.length)} episode(s) of work (effort: ${totalEffort}) ` +
|
|
36
|
+
`on ${String(fileCount)} file(s) by ${agentAttribution.join(', ')} would be affected.`;
|
|
37
|
+
return { episodes, totalEffort, agentAttribution, warningMessage };
|
|
38
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Work Summary Anchor
|
|
3
|
+
*
|
|
4
|
+
* Manages an auto-generated anchor that summarizes work done in the current session.
|
|
5
|
+
* Updated automatically after each episode batch is flushed.
|
|
6
|
+
*/
|
|
7
|
+
import type { EpisodeStore, ProjectWorkSummary } from '@compilr-dev/agents';
|
|
8
|
+
import type { AnchorManager } from '@compilr-dev/sdk';
|
|
9
|
+
export interface WorkSummaryAnchorConfig {
|
|
10
|
+
store: EpisodeStore;
|
|
11
|
+
projectId: string;
|
|
12
|
+
getAnchorManager: (projectId: string) => AnchorManager;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Build the anchor content string from the store's work summary.
|
|
16
|
+
* Returns null when there are no episodes to summarize.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildWorkSummaryContent(summary: ProjectWorkSummary): string | null;
|
|
19
|
+
/**
|
|
20
|
+
* Update the work summary anchor for a project.
|
|
21
|
+
* Removes existing anchor (if any) and adds updated one.
|
|
22
|
+
*/
|
|
23
|
+
export declare function updateWorkSummaryAnchor(config: WorkSummaryAnchorConfig): void;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Work Summary Anchor
|
|
3
|
+
*
|
|
4
|
+
* Manages an auto-generated anchor that summarizes work done in the current session.
|
|
5
|
+
* Updated automatically after each episode batch is flushed.
|
|
6
|
+
*/
|
|
7
|
+
const ANCHOR_TAG = 'episode-work-summary';
|
|
8
|
+
/**
|
|
9
|
+
* Build the anchor content string from the store's work summary.
|
|
10
|
+
* Returns null when there are no episodes to summarize.
|
|
11
|
+
*/
|
|
12
|
+
export function buildWorkSummaryContent(summary) {
|
|
13
|
+
if (summary.episodeCount === 0)
|
|
14
|
+
return null;
|
|
15
|
+
const lines = ['[Session Work Summary]'];
|
|
16
|
+
lines.push(`Episodes: ${String(summary.episodeCount)}, Effort: ${summary.totalEffort}, Time: ${formatMs(summary.timeSpentMs)}`);
|
|
17
|
+
if (summary.agentBreakdown.length > 0) {
|
|
18
|
+
const agents = summary.agentBreakdown
|
|
19
|
+
.map(a => `${a.agentId}(${String(a.episodeCount)})`)
|
|
20
|
+
.join(', ');
|
|
21
|
+
lines.push(`Agents: ${agents}`);
|
|
22
|
+
}
|
|
23
|
+
if (summary.topFiles.length > 0) {
|
|
24
|
+
const files = summary.topFiles.slice(0, 5)
|
|
25
|
+
.map(f => f.path.split('/').pop() ?? f.path)
|
|
26
|
+
.join(', ');
|
|
27
|
+
lines.push(`Top files: ${files}`);
|
|
28
|
+
}
|
|
29
|
+
if (summary.uncommittedWork.length > 0) {
|
|
30
|
+
lines.push(`Uncommitted: ${String(summary.uncommittedWork.length)} episode(s)`);
|
|
31
|
+
}
|
|
32
|
+
return lines.join('\n');
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Update the work summary anchor for a project.
|
|
36
|
+
* Removes existing anchor (if any) and adds updated one.
|
|
37
|
+
*/
|
|
38
|
+
export function updateWorkSummaryAnchor(config) {
|
|
39
|
+
const { store, projectId, getAnchorManager: getManager } = config;
|
|
40
|
+
const manager = getManager(projectId);
|
|
41
|
+
const summary = store.getWorkSummary();
|
|
42
|
+
const content = buildWorkSummaryContent(summary);
|
|
43
|
+
// Remove existing work summary anchor
|
|
44
|
+
const existing = manager.getAll().find((a) => a.tags?.includes(ANCHOR_TAG));
|
|
45
|
+
if (existing)
|
|
46
|
+
manager.remove(existing.id);
|
|
47
|
+
// Add new anchor if there's content
|
|
48
|
+
if (content) {
|
|
49
|
+
manager.add({
|
|
50
|
+
content,
|
|
51
|
+
priority: 'info',
|
|
52
|
+
scope: 'persistent',
|
|
53
|
+
tags: [ANCHOR_TAG],
|
|
54
|
+
projectId,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Format milliseconds to a human-readable string (e.g., "2h 15m", "45s").
|
|
60
|
+
*/
|
|
61
|
+
function formatMs(ms) {
|
|
62
|
+
if (ms < 1000)
|
|
63
|
+
return `${String(ms)}ms`;
|
|
64
|
+
const totalSeconds = Math.floor(ms / 1000);
|
|
65
|
+
if (totalSeconds < 60)
|
|
66
|
+
return `${String(totalSeconds)}s`;
|
|
67
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
68
|
+
if (minutes < 60)
|
|
69
|
+
return `${String(minutes)}m`;
|
|
70
|
+
const hours = Math.floor(minutes / 60);
|
|
71
|
+
const remainingMinutes = minutes % 60;
|
|
72
|
+
return remainingMinutes > 0 ? `${String(hours)}h ${String(remainingMinutes)}m` : `${String(hours)}h`;
|
|
73
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coin System
|
|
3
|
+
*
|
|
4
|
+
* Manages arcade coins for the games easter egg.
|
|
5
|
+
* Coins are earned through productive CLI usage and spent to play games.
|
|
6
|
+
*/
|
|
7
|
+
export interface CoinData {
|
|
8
|
+
coins: number;
|
|
9
|
+
totalEarned: number;
|
|
10
|
+
totalSpent: number;
|
|
11
|
+
lastDailyBonus: string | null;
|
|
12
|
+
}
|
|
13
|
+
export declare const COIN_COST_START_GAME = 1;
|
|
14
|
+
export declare const COIN_COST_CONTINUE = 2;
|
|
15
|
+
export declare const COIN_REWARD_WORK_ITEM = 1;
|
|
16
|
+
export declare const COIN_REWARD_FIRST_PROJECT = 3;
|
|
17
|
+
export declare const COIN_REWARD_DAILY_BONUS = 1;
|
|
18
|
+
export declare const COIN_REWARD_HIGH_SCORE = 2;
|
|
19
|
+
/**
|
|
20
|
+
* Get current coin data
|
|
21
|
+
*/
|
|
22
|
+
export declare function getCoinData(): CoinData;
|
|
23
|
+
/**
|
|
24
|
+
* Get current coin balance
|
|
25
|
+
*/
|
|
26
|
+
export declare function getCoins(): number;
|
|
27
|
+
/**
|
|
28
|
+
* Check if player has enough coins
|
|
29
|
+
*/
|
|
30
|
+
export declare function hasCoins(amount: number): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Spend coins (returns true if successful)
|
|
33
|
+
*/
|
|
34
|
+
export declare function spendCoins(amount: number): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Earn coins
|
|
37
|
+
*/
|
|
38
|
+
export declare function earnCoins(amount: number, reason?: string): void;
|
|
39
|
+
/**
|
|
40
|
+
* Check and award daily bonus if eligible
|
|
41
|
+
*/
|
|
42
|
+
export declare function checkDailyBonus(): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Award coins for completing a work item
|
|
45
|
+
*/
|
|
46
|
+
export declare function awardWorkItemCompletion(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Award coins for creating first project
|
|
49
|
+
*/
|
|
50
|
+
export declare function awardFirstProject(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Award coins for achieving a high score
|
|
53
|
+
*/
|
|
54
|
+
export declare function awardHighScore(): void;
|
|
55
|
+
/**
|
|
56
|
+
* Clear cache (for testing)
|
|
57
|
+
*/
|
|
58
|
+
export declare function clearCoinCache(): void;
|
|
59
|
+
/**
|
|
60
|
+
* Format coins for display (e.g., "●●●○○" for 3/5)
|
|
61
|
+
*/
|
|
62
|
+
export declare function formatCoinsDisplay(current: number, max?: number): string;
|
|
63
|
+
/**
|
|
64
|
+
* Get a short coin display string
|
|
65
|
+
*/
|
|
66
|
+
export declare function getCoinsDisplayShort(): string;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coin System
|
|
3
|
+
*
|
|
4
|
+
* Manages arcade coins for the games easter egg.
|
|
5
|
+
* Coins are earned through productive CLI usage and spent to play games.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import * as os from 'os';
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// Constants
|
|
12
|
+
// =============================================================================
|
|
13
|
+
const CONFIG_DIR = path.join(os.homedir(), '.compilr-dev');
|
|
14
|
+
const GAMES_FILE = path.join(CONFIG_DIR, 'games.json');
|
|
15
|
+
const DEFAULT_COIN_DATA = {
|
|
16
|
+
coins: 3, // Start with 3 free coins!
|
|
17
|
+
totalEarned: 3,
|
|
18
|
+
totalSpent: 0,
|
|
19
|
+
lastDailyBonus: null,
|
|
20
|
+
};
|
|
21
|
+
// Coin costs
|
|
22
|
+
export const COIN_COST_START_GAME = 1;
|
|
23
|
+
export const COIN_COST_CONTINUE = 2;
|
|
24
|
+
// Coin rewards
|
|
25
|
+
export const COIN_REWARD_WORK_ITEM = 1;
|
|
26
|
+
export const COIN_REWARD_FIRST_PROJECT = 3;
|
|
27
|
+
export const COIN_REWARD_DAILY_BONUS = 1;
|
|
28
|
+
export const COIN_REWARD_HIGH_SCORE = 2;
|
|
29
|
+
// =============================================================================
|
|
30
|
+
// In-memory cache
|
|
31
|
+
// =============================================================================
|
|
32
|
+
let coinCache = null;
|
|
33
|
+
// =============================================================================
|
|
34
|
+
// Persistence
|
|
35
|
+
// =============================================================================
|
|
36
|
+
function loadFromDisk() {
|
|
37
|
+
try {
|
|
38
|
+
if (fs.existsSync(GAMES_FILE)) {
|
|
39
|
+
const data = fs.readFileSync(GAMES_FILE, 'utf-8');
|
|
40
|
+
const parsed = JSON.parse(data);
|
|
41
|
+
return { ...DEFAULT_COIN_DATA, ...parsed };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Ignore errors
|
|
46
|
+
}
|
|
47
|
+
return { ...DEFAULT_COIN_DATA };
|
|
48
|
+
}
|
|
49
|
+
function saveToDisk(data) {
|
|
50
|
+
try {
|
|
51
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
52
|
+
fs.writeFileSync(GAMES_FILE, JSON.stringify(data, null, 2), 'utf-8');
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
console.error('Failed to save coin data:', error);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// =============================================================================
|
|
59
|
+
// Public API
|
|
60
|
+
// =============================================================================
|
|
61
|
+
/**
|
|
62
|
+
* Get current coin data
|
|
63
|
+
*/
|
|
64
|
+
export function getCoinData() {
|
|
65
|
+
if (coinCache) {
|
|
66
|
+
return coinCache;
|
|
67
|
+
}
|
|
68
|
+
coinCache = loadFromDisk();
|
|
69
|
+
return coinCache;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get current coin balance
|
|
73
|
+
*/
|
|
74
|
+
export function getCoins() {
|
|
75
|
+
return getCoinData().coins;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Check if player has enough coins
|
|
79
|
+
*/
|
|
80
|
+
export function hasCoins(amount) {
|
|
81
|
+
return getCoins() >= amount;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Spend coins (returns true if successful)
|
|
85
|
+
*/
|
|
86
|
+
export function spendCoins(amount) {
|
|
87
|
+
const data = getCoinData();
|
|
88
|
+
if (data.coins < amount) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
data.coins -= amount;
|
|
92
|
+
data.totalSpent += amount;
|
|
93
|
+
coinCache = data;
|
|
94
|
+
saveToDisk(data);
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Earn coins
|
|
99
|
+
*/
|
|
100
|
+
export function earnCoins(amount, reason) {
|
|
101
|
+
const data = getCoinData();
|
|
102
|
+
data.coins += amount;
|
|
103
|
+
data.totalEarned += amount;
|
|
104
|
+
coinCache = data;
|
|
105
|
+
saveToDisk(data);
|
|
106
|
+
// Log for debugging (could be made optional)
|
|
107
|
+
if (reason) {
|
|
108
|
+
// Silent for now - could add notification later
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Check and award daily bonus if eligible
|
|
113
|
+
*/
|
|
114
|
+
export function checkDailyBonus() {
|
|
115
|
+
const data = getCoinData();
|
|
116
|
+
const today = new Date().toISOString().split('T')[0];
|
|
117
|
+
if (data.lastDailyBonus !== today) {
|
|
118
|
+
data.lastDailyBonus = today;
|
|
119
|
+
data.coins += COIN_REWARD_DAILY_BONUS;
|
|
120
|
+
data.totalEarned += COIN_REWARD_DAILY_BONUS;
|
|
121
|
+
coinCache = data;
|
|
122
|
+
saveToDisk(data);
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Award coins for completing a work item
|
|
129
|
+
*/
|
|
130
|
+
export function awardWorkItemCompletion() {
|
|
131
|
+
earnCoins(COIN_REWARD_WORK_ITEM, 'work_item_completed');
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Award coins for creating first project
|
|
135
|
+
*/
|
|
136
|
+
export function awardFirstProject() {
|
|
137
|
+
earnCoins(COIN_REWARD_FIRST_PROJECT, 'first_project');
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Award coins for achieving a high score
|
|
141
|
+
*/
|
|
142
|
+
export function awardHighScore() {
|
|
143
|
+
earnCoins(COIN_REWARD_HIGH_SCORE, 'high_score');
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Clear cache (for testing)
|
|
147
|
+
*/
|
|
148
|
+
export function clearCoinCache() {
|
|
149
|
+
coinCache = null;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Format coins for display (e.g., "●●●○○" for 3/5)
|
|
153
|
+
*/
|
|
154
|
+
export function formatCoinsDisplay(current, max = 10) {
|
|
155
|
+
const filled = Math.min(current, max);
|
|
156
|
+
const empty = Math.max(0, max - filled);
|
|
157
|
+
return '●'.repeat(filled) + '○'.repeat(empty);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get a short coin display string
|
|
161
|
+
*/
|
|
162
|
+
export function getCoinsDisplayShort() {
|
|
163
|
+
const coins = getCoins();
|
|
164
|
+
return `${String(coins)} coin${coins !== 1 ? 's' : ''}`;
|
|
165
|
+
}
|