@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,1243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* New Project Overlay V2
|
|
3
|
+
*
|
|
4
|
+
* Modal overlay for the /new wizard - creates new projects with structured workflow.
|
|
5
|
+
* Uses BaseOverlayV2 for TerminalUI integration.
|
|
6
|
+
*
|
|
7
|
+
* Steps:
|
|
8
|
+
* 0. Project type (new vs existing)
|
|
9
|
+
* 1. Project name
|
|
10
|
+
* 2. Description
|
|
11
|
+
* 3. Repo pattern (single vs two-repo)
|
|
12
|
+
* 4. Tech stack
|
|
13
|
+
* 5. Coding standards
|
|
14
|
+
* 6. Initialize git?
|
|
15
|
+
* 7. Workflow mode
|
|
16
|
+
* 8. Confirmation
|
|
17
|
+
*
|
|
18
|
+
* Note: All projects are tracked in the database. File-based backlog was deprecated.
|
|
19
|
+
*/
|
|
20
|
+
import chalk from 'chalk';
|
|
21
|
+
import * as fs from 'fs';
|
|
22
|
+
import * as path from 'path';
|
|
23
|
+
import { execSync } from 'child_process';
|
|
24
|
+
import { BaseOverlayV2, renderBorder } from '../../base/index.js';
|
|
25
|
+
import { checkGitConfig } from '../../../utils/git-config.js';
|
|
26
|
+
import { TECH_STACK_LABELS, CODING_STANDARDS_LABELS, REPO_PATTERN_LABELS, generateProject, isValidProjectName, projectExists, generateCompilrMdForImport, } from '../../../templates/index.js';
|
|
27
|
+
import { getProjectsPath, ensureProjectsDirectory } from '../../../settings/paths.js';
|
|
28
|
+
import { detectProjectInfo, validateImportPath, getLanguageLabel, getFrameworkLabel, } from '../../../utils/project-detection.js';
|
|
29
|
+
import { projectRepository } from '../../../db/repositories/index.js';
|
|
30
|
+
// =============================================================================
|
|
31
|
+
// Constants
|
|
32
|
+
// =============================================================================
|
|
33
|
+
const TECH_STACK_OPTIONS = ['react-node-pg', 'react-python-pg', 'vue-node-pg', 'custom'];
|
|
34
|
+
const CODING_STANDARDS_OPTIONS = ['strict', 'relaxed', 'custom'];
|
|
35
|
+
const REPO_PATTERN_OPTIONS = ['single', 'two-repo'];
|
|
36
|
+
const WORKFLOW_MODE_OPTIONS = ['flexible', 'guided'];
|
|
37
|
+
const WORKFLOW_MODE_LABELS = {
|
|
38
|
+
flexible: 'Flexible (user-driven, exploratory)',
|
|
39
|
+
guided: 'Guided (structured step-by-step workflow)',
|
|
40
|
+
};
|
|
41
|
+
// =============================================================================
|
|
42
|
+
// Step Helpers
|
|
43
|
+
// =============================================================================
|
|
44
|
+
function getMaxOptionsForStep(step) {
|
|
45
|
+
switch (step) {
|
|
46
|
+
case 0:
|
|
47
|
+
return 2;
|
|
48
|
+
case 3:
|
|
49
|
+
return REPO_PATTERN_OPTIONS.length;
|
|
50
|
+
case 4:
|
|
51
|
+
return TECH_STACK_OPTIONS.length;
|
|
52
|
+
case 5:
|
|
53
|
+
return CODING_STANDARDS_OPTIONS.length;
|
|
54
|
+
case 6:
|
|
55
|
+
return 2;
|
|
56
|
+
case 7:
|
|
57
|
+
return WORKFLOW_MODE_OPTIONS.length;
|
|
58
|
+
case 8:
|
|
59
|
+
return 2;
|
|
60
|
+
default:
|
|
61
|
+
return 0;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function isSelectionStep(step) {
|
|
65
|
+
return [0, 3, 4, 5, 6, 7, 8].includes(step);
|
|
66
|
+
}
|
|
67
|
+
function isInputStep(step) {
|
|
68
|
+
return [1, 2].includes(step);
|
|
69
|
+
}
|
|
70
|
+
// =============================================================================
|
|
71
|
+
// Init Overlay V2 Implementation
|
|
72
|
+
// =============================================================================
|
|
73
|
+
export class NewProjectOverlayV2 extends BaseOverlayV2 {
|
|
74
|
+
type = 'inline';
|
|
75
|
+
id = 'new-project-overlay-v2';
|
|
76
|
+
constructor() {
|
|
77
|
+
super({
|
|
78
|
+
step: 0,
|
|
79
|
+
projectType: null,
|
|
80
|
+
projectName: '',
|
|
81
|
+
description: '',
|
|
82
|
+
repoPattern: null,
|
|
83
|
+
techStack: null,
|
|
84
|
+
codingStandards: null,
|
|
85
|
+
initGit: true,
|
|
86
|
+
gitRemote: '',
|
|
87
|
+
workflowMode: 'flexible',
|
|
88
|
+
gitConfigChecked: false,
|
|
89
|
+
gitConfigValid: false,
|
|
90
|
+
gitUserName: null,
|
|
91
|
+
gitUserEmail: null,
|
|
92
|
+
gitRemoteInputMode: false,
|
|
93
|
+
// Import project state
|
|
94
|
+
importPath: '',
|
|
95
|
+
detectedProject: null,
|
|
96
|
+
importGitChoice: null,
|
|
97
|
+
importStep: 0,
|
|
98
|
+
// UI state
|
|
99
|
+
selectedIndex: 0,
|
|
100
|
+
inputBuffer: '',
|
|
101
|
+
error: null,
|
|
102
|
+
isGenerating: false,
|
|
103
|
+
});
|
|
104
|
+
this.minHeight = 20; // Prevent jitter between steps
|
|
105
|
+
}
|
|
106
|
+
// ===========================================================================
|
|
107
|
+
// Rendering
|
|
108
|
+
// ===========================================================================
|
|
109
|
+
renderContent(context) {
|
|
110
|
+
const s = context.styles;
|
|
111
|
+
// Show generating state if applicable
|
|
112
|
+
if (this.state.isGenerating) {
|
|
113
|
+
return this.renderGenerating(s);
|
|
114
|
+
}
|
|
115
|
+
const lines = [];
|
|
116
|
+
const border = renderBorder(context.width, s);
|
|
117
|
+
// Check if we're in import flow (projectType === 'existing')
|
|
118
|
+
if (this.state.projectType === 'existing') {
|
|
119
|
+
// Import flow header
|
|
120
|
+
lines.push(border);
|
|
121
|
+
lines.push(' ' + s.primaryBold('Import Existing Project') + s.muted(` [${String(this.state.importStep + 1)}/5]`));
|
|
122
|
+
lines.push('');
|
|
123
|
+
// Import step content
|
|
124
|
+
switch (this.state.importStep) {
|
|
125
|
+
case 0:
|
|
126
|
+
lines.push(...this.renderImportStep1(s));
|
|
127
|
+
break;
|
|
128
|
+
case 1:
|
|
129
|
+
lines.push(...this.renderImportStep2(s));
|
|
130
|
+
break;
|
|
131
|
+
case 2:
|
|
132
|
+
lines.push(...this.renderImportStep3(s));
|
|
133
|
+
break;
|
|
134
|
+
case 3:
|
|
135
|
+
lines.push(...this.renderImportStep4(s));
|
|
136
|
+
break;
|
|
137
|
+
case 4:
|
|
138
|
+
lines.push(...this.renderImportStep5(s));
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
// Footer for import flow
|
|
142
|
+
lines.push(...this.renderImportStepFooter(s));
|
|
143
|
+
return lines;
|
|
144
|
+
}
|
|
145
|
+
// Header for new project flow
|
|
146
|
+
lines.push(border);
|
|
147
|
+
lines.push(' ' + s.primaryBold('Initialize New Project') + s.muted(` [${String(this.state.step)}/8]`));
|
|
148
|
+
lines.push('');
|
|
149
|
+
// Step content
|
|
150
|
+
switch (this.state.step) {
|
|
151
|
+
case 0:
|
|
152
|
+
lines.push(...this.renderStep0(s));
|
|
153
|
+
break;
|
|
154
|
+
case 1:
|
|
155
|
+
lines.push(...this.renderStep1(s));
|
|
156
|
+
break;
|
|
157
|
+
case 2:
|
|
158
|
+
lines.push(...this.renderStep2(s));
|
|
159
|
+
break;
|
|
160
|
+
case 3:
|
|
161
|
+
lines.push(...this.renderStep3(s));
|
|
162
|
+
break;
|
|
163
|
+
case 4:
|
|
164
|
+
lines.push(...this.renderStep4(s));
|
|
165
|
+
break;
|
|
166
|
+
case 5:
|
|
167
|
+
lines.push(...this.renderStep5(s));
|
|
168
|
+
break;
|
|
169
|
+
case 6:
|
|
170
|
+
lines.push(...this.renderStep6(s));
|
|
171
|
+
break;
|
|
172
|
+
case 7:
|
|
173
|
+
lines.push(...this.renderStep7(s));
|
|
174
|
+
break;
|
|
175
|
+
case 8:
|
|
176
|
+
lines.push(...this.renderStep8(s));
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
// Footer
|
|
180
|
+
lines.push(...this.renderStepFooter(s));
|
|
181
|
+
return lines;
|
|
182
|
+
}
|
|
183
|
+
renderGenerating(s) {
|
|
184
|
+
const lines = [];
|
|
185
|
+
lines.push('');
|
|
186
|
+
lines.push(s.primary(` Creating project "${this.state.projectName}"...`));
|
|
187
|
+
lines.push('');
|
|
188
|
+
return lines;
|
|
189
|
+
}
|
|
190
|
+
renderStepFooter(s) {
|
|
191
|
+
const lines = [];
|
|
192
|
+
lines.push('');
|
|
193
|
+
if (this.state.step === 0) {
|
|
194
|
+
lines.push(s.muted(' Up/Down Navigate | Enter Select | q/Esc Cancel'));
|
|
195
|
+
}
|
|
196
|
+
else if (this.state.step === 8) {
|
|
197
|
+
lines.push(s.muted(' Up/Down Navigate | Enter Confirm | Esc Back'));
|
|
198
|
+
}
|
|
199
|
+
else if (isSelectionStep(this.state.step)) {
|
|
200
|
+
lines.push(s.muted(' Up/Down Navigate | Enter Select | Esc Back'));
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
lines.push(s.muted(' Enter Confirm | Esc Back'));
|
|
204
|
+
}
|
|
205
|
+
return lines;
|
|
206
|
+
}
|
|
207
|
+
renderSelectionOption(s, index, label, disabled = false) {
|
|
208
|
+
const isSelected = index === this.state.selectedIndex;
|
|
209
|
+
const prefix = isSelected ? ' > ' : ' ';
|
|
210
|
+
if (disabled) {
|
|
211
|
+
return s.muted(prefix + label + ' (coming soon)');
|
|
212
|
+
}
|
|
213
|
+
return isSelected ? s.primary(prefix + label) : s.muted(prefix + label);
|
|
214
|
+
}
|
|
215
|
+
// ===========================================================================
|
|
216
|
+
// Step Renderers
|
|
217
|
+
// ===========================================================================
|
|
218
|
+
renderStep0(s) {
|
|
219
|
+
const lines = [];
|
|
220
|
+
lines.push(chalk.bold(' What would you like to do?'));
|
|
221
|
+
lines.push('');
|
|
222
|
+
lines.push(this.renderSelectionOption(s, 0, '1. Start a new project'));
|
|
223
|
+
lines.push(this.renderSelectionOption(s, 1, '2. Add workflow to existing project'));
|
|
224
|
+
lines.push('');
|
|
225
|
+
if (this.state.selectedIndex === 0) {
|
|
226
|
+
lines.push(s.muted(' Start fresh with a structured project layout'));
|
|
227
|
+
lines.push(s.muted(' optimized for AI-assisted development.'));
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
lines.push(s.muted(' Import an existing codebase and add'));
|
|
231
|
+
lines.push(s.muted(' compilr workflow tracking.'));
|
|
232
|
+
}
|
|
233
|
+
return lines;
|
|
234
|
+
}
|
|
235
|
+
renderStep1(s) {
|
|
236
|
+
const lines = [];
|
|
237
|
+
lines.push(chalk.bold(' Project name'));
|
|
238
|
+
lines.push('');
|
|
239
|
+
lines.push(` > ${this.state.inputBuffer}|`);
|
|
240
|
+
lines.push('');
|
|
241
|
+
if (this.state.error) {
|
|
242
|
+
lines.push(s.error(` ${this.state.error}`));
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
lines.push(s.muted(' Use lowercase letters, numbers, hyphens (e.g., my-saas-app)'));
|
|
246
|
+
lines.push(s.muted(' 2-50 characters, must start with a letter'));
|
|
247
|
+
}
|
|
248
|
+
return lines;
|
|
249
|
+
}
|
|
250
|
+
renderStep2(s) {
|
|
251
|
+
const lines = [];
|
|
252
|
+
lines.push(chalk.bold(' What are you building?'));
|
|
253
|
+
lines.push('');
|
|
254
|
+
lines.push(` > ${this.state.inputBuffer}|`);
|
|
255
|
+
lines.push('');
|
|
256
|
+
if (this.state.error) {
|
|
257
|
+
lines.push(s.error(` ${this.state.error}`));
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
lines.push(s.muted(' Brief description (1-2 sentences)'));
|
|
261
|
+
lines.push(s.muted(' Example: "A task management SaaS for small teams"'));
|
|
262
|
+
}
|
|
263
|
+
return lines;
|
|
264
|
+
}
|
|
265
|
+
renderStep3(s) {
|
|
266
|
+
const lines = [];
|
|
267
|
+
lines.push(chalk.bold(' Documentation structure'));
|
|
268
|
+
lines.push('');
|
|
269
|
+
for (let i = 0; i < REPO_PATTERN_OPTIONS.length; i++) {
|
|
270
|
+
const pattern = REPO_PATTERN_OPTIONS[i];
|
|
271
|
+
lines.push(this.renderSelectionOption(s, i, `${String(i + 1)}. ${REPO_PATTERN_LABELS[pattern]}`));
|
|
272
|
+
}
|
|
273
|
+
lines.push('');
|
|
274
|
+
lines.push(s.muted(' Single repo: All files in one repository'));
|
|
275
|
+
lines.push(s.muted(' Two repos: Code and docs in separate repositories'));
|
|
276
|
+
return lines;
|
|
277
|
+
}
|
|
278
|
+
renderStep4(s) {
|
|
279
|
+
const lines = [];
|
|
280
|
+
lines.push(chalk.bold(' Tech stack'));
|
|
281
|
+
lines.push('');
|
|
282
|
+
for (let i = 0; i < TECH_STACK_OPTIONS.length; i++) {
|
|
283
|
+
const stack = TECH_STACK_OPTIONS[i];
|
|
284
|
+
lines.push(this.renderSelectionOption(s, i, `${String(i + 1)}. ${TECH_STACK_LABELS[stack]}`));
|
|
285
|
+
}
|
|
286
|
+
lines.push('');
|
|
287
|
+
lines.push(s.muted(' Choose a preset or configure later'));
|
|
288
|
+
return lines;
|
|
289
|
+
}
|
|
290
|
+
renderStep5(s) {
|
|
291
|
+
const lines = [];
|
|
292
|
+
lines.push(chalk.bold(' Coding standards preset'));
|
|
293
|
+
lines.push('');
|
|
294
|
+
for (let i = 0; i < CODING_STANDARDS_OPTIONS.length; i++) {
|
|
295
|
+
const standard = CODING_STANDARDS_OPTIONS[i];
|
|
296
|
+
lines.push(this.renderSelectionOption(s, i, `${String(i + 1)}. ${CODING_STANDARDS_LABELS[standard]}`));
|
|
297
|
+
}
|
|
298
|
+
lines.push('');
|
|
299
|
+
lines.push(s.muted(' Strict: Full TypeScript with strict mode + ESLint'));
|
|
300
|
+
lines.push(s.muted(' Relaxed: TypeScript with basic strict mode'));
|
|
301
|
+
lines.push(s.muted(' Custom: Configure your own standards later'));
|
|
302
|
+
return lines;
|
|
303
|
+
}
|
|
304
|
+
renderStep6(s) {
|
|
305
|
+
const lines = [];
|
|
306
|
+
// Check git config on first render of this step
|
|
307
|
+
if (!this.state.gitConfigChecked) {
|
|
308
|
+
const config = checkGitConfig();
|
|
309
|
+
this.state.gitConfigChecked = true;
|
|
310
|
+
this.state.gitConfigValid = config.hasName && config.hasEmail;
|
|
311
|
+
this.state.gitUserName = config.userName;
|
|
312
|
+
this.state.gitUserEmail = config.userEmail;
|
|
313
|
+
}
|
|
314
|
+
// Git remote URL input mode
|
|
315
|
+
if (this.state.gitRemoteInputMode) {
|
|
316
|
+
lines.push(chalk.bold(' Git remote URL (optional)'));
|
|
317
|
+
lines.push('');
|
|
318
|
+
lines.push(' Enter the URL of your git remote repository.');
|
|
319
|
+
lines.push(' Useful for tracking even if the repo already exists.');
|
|
320
|
+
lines.push(' You can skip this and set it later via /projects (e key).');
|
|
321
|
+
lines.push('');
|
|
322
|
+
lines.push(` > ${this.state.inputBuffer}█`);
|
|
323
|
+
lines.push('');
|
|
324
|
+
lines.push(s.muted(' Enter Continue · Esc Skip'));
|
|
325
|
+
return lines;
|
|
326
|
+
}
|
|
327
|
+
// Main selection
|
|
328
|
+
lines.push(chalk.bold(' Initialize git repository?'));
|
|
329
|
+
lines.push('');
|
|
330
|
+
lines.push(this.renderSelectionOption(s, 0, 'Yes'));
|
|
331
|
+
lines.push(this.renderSelectionOption(s, 1, 'No'));
|
|
332
|
+
lines.push('');
|
|
333
|
+
if (this.state.gitConfigValid) {
|
|
334
|
+
lines.push(s.muted(' Creates git repo with initial commit'));
|
|
335
|
+
lines.push(s.muted(` Git user: ${this.state.gitUserName ?? ''} <${this.state.gitUserEmail ?? ''}>`));
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
lines.push(s.warning(' ⚠ Git config not set - initial commit will be skipped'));
|
|
339
|
+
if (!this.state.gitUserName) {
|
|
340
|
+
lines.push(s.muted(' Missing: git config --global user.name'));
|
|
341
|
+
}
|
|
342
|
+
if (!this.state.gitUserEmail) {
|
|
343
|
+
lines.push(s.muted(' Missing: git config --global user.email'));
|
|
344
|
+
}
|
|
345
|
+
lines.push(s.muted(' Configure via /config or run git config commands'));
|
|
346
|
+
}
|
|
347
|
+
return lines;
|
|
348
|
+
}
|
|
349
|
+
renderStep7(s) {
|
|
350
|
+
const lines = [];
|
|
351
|
+
lines.push(chalk.bold(' Workflow mode'));
|
|
352
|
+
lines.push('');
|
|
353
|
+
for (let i = 0; i < WORKFLOW_MODE_OPTIONS.length; i++) {
|
|
354
|
+
const mode = WORKFLOW_MODE_OPTIONS[i];
|
|
355
|
+
const suffix = i === 0 ? ' (recommended)' : '';
|
|
356
|
+
lines.push(this.renderSelectionOption(s, i, `${String(i + 1)}. ${WORKFLOW_MODE_LABELS[mode]}${suffix}`));
|
|
357
|
+
}
|
|
358
|
+
lines.push('');
|
|
359
|
+
lines.push(s.muted(' Flexible: Work at your own pace, agent responds to requests'));
|
|
360
|
+
lines.push(s.muted(' Guided: Agent suggests next steps, tracks work item progress'));
|
|
361
|
+
return lines;
|
|
362
|
+
}
|
|
363
|
+
renderStep8(s) {
|
|
364
|
+
const lines = [];
|
|
365
|
+
lines.push(chalk.bold(' Ready to create project?'));
|
|
366
|
+
lines.push('');
|
|
367
|
+
lines.push(` Project: ${s.primary(this.state.projectName)}`);
|
|
368
|
+
lines.push(` Location: ${s.primary('./' + this.state.projectName + '/')}`);
|
|
369
|
+
lines.push(` Structure: ${s.primary(this.state.repoPattern === 'single' ? 'Single repo' : 'Two repos')}`);
|
|
370
|
+
lines.push(` Tech: ${s.primary(this.state.techStack ? TECH_STACK_LABELS[this.state.techStack] : 'Not set')}`);
|
|
371
|
+
lines.push(` Standards: ${s.primary(this.state.codingStandards ? CODING_STANDARDS_LABELS[this.state.codingStandards] : 'Not set')}`);
|
|
372
|
+
lines.push(` Git: ${s.primary(this.state.initGit ? 'Yes' : 'No')}`);
|
|
373
|
+
if (this.state.gitRemote) {
|
|
374
|
+
lines.push(` Remote: ${s.primary(this.state.gitRemote)}`);
|
|
375
|
+
}
|
|
376
|
+
lines.push(` Workflow: ${s.primary(WORKFLOW_MODE_LABELS[this.state.workflowMode])}`);
|
|
377
|
+
if (this.state.repoPattern === 'two-repo') {
|
|
378
|
+
lines.push('');
|
|
379
|
+
lines.push(s.muted(` Docs repo: ./${this.state.projectName}-docs/`));
|
|
380
|
+
}
|
|
381
|
+
lines.push('');
|
|
382
|
+
if (this.state.error) {
|
|
383
|
+
lines.push(s.error(` ${this.state.error}`));
|
|
384
|
+
lines.push('');
|
|
385
|
+
}
|
|
386
|
+
lines.push(this.renderSelectionOption(s, 0, 'Create'));
|
|
387
|
+
lines.push(this.renderSelectionOption(s, 1, 'Cancel'));
|
|
388
|
+
return lines;
|
|
389
|
+
}
|
|
390
|
+
// ===========================================================================
|
|
391
|
+
// Import Step Renderers
|
|
392
|
+
// ===========================================================================
|
|
393
|
+
renderImportStep1(s) {
|
|
394
|
+
const lines = [];
|
|
395
|
+
lines.push(chalk.bold(' Enter path to existing project'));
|
|
396
|
+
lines.push('');
|
|
397
|
+
lines.push(` > ${this.state.inputBuffer}|`);
|
|
398
|
+
lines.push('');
|
|
399
|
+
if (this.state.error) {
|
|
400
|
+
lines.push(s.error(` ${this.state.error}`));
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
lines.push(s.muted(' Enter absolute or relative path to project directory'));
|
|
404
|
+
lines.push(s.muted(' Tab for autocomplete'));
|
|
405
|
+
}
|
|
406
|
+
return lines;
|
|
407
|
+
}
|
|
408
|
+
renderImportStep2(s) {
|
|
409
|
+
const lines = [];
|
|
410
|
+
const detected = this.state.detectedProject;
|
|
411
|
+
if (!detected) {
|
|
412
|
+
lines.push(s.error(' No project detected'));
|
|
413
|
+
return lines;
|
|
414
|
+
}
|
|
415
|
+
lines.push(chalk.bold(' Project Detection Results'));
|
|
416
|
+
lines.push('');
|
|
417
|
+
// Name
|
|
418
|
+
const nameIcon = detected.nameSource !== 'folder' ? s.success('✓') : s.warning('⚠');
|
|
419
|
+
const nameNote = detected.nameSource !== 'folder' ? `(from ${detected.nameSource})` : '(from folder name)';
|
|
420
|
+
lines.push(` ${nameIcon} Name: ${s.primary(detected.displayName)} ${s.muted(nameNote)}`);
|
|
421
|
+
// Language
|
|
422
|
+
const langIcon = detected.language ? s.success('✓') : s.warning('⚠');
|
|
423
|
+
const langLabel = getLanguageLabel(detected.language);
|
|
424
|
+
lines.push(` ${langIcon} Language: ${s.primary(langLabel)}`);
|
|
425
|
+
// Framework
|
|
426
|
+
if (detected.framework) {
|
|
427
|
+
lines.push(` ${s.success('✓')} Framework: ${s.primary(getFrameworkLabel(detected.framework))}`);
|
|
428
|
+
}
|
|
429
|
+
else if (detected.language) {
|
|
430
|
+
lines.push(` ${s.muted('-')} Framework: ${s.muted('Not detected')}`);
|
|
431
|
+
}
|
|
432
|
+
// Git
|
|
433
|
+
if (detected.hasGit && detected.gitRemote) {
|
|
434
|
+
lines.push(` ${s.success('✓')} Git: ${s.primary(detected.gitRemote)}`);
|
|
435
|
+
}
|
|
436
|
+
else if (detected.hasGit) {
|
|
437
|
+
lines.push(` ${s.warning('⚠')} Git: ${s.muted('No remote configured')}`);
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
lines.push(` ${s.warning('⚠')} Git: ${s.muted('Not initialized')}`);
|
|
441
|
+
}
|
|
442
|
+
// COMPILR.md
|
|
443
|
+
if (detected.hasCompilrMd) {
|
|
444
|
+
lines.push(` ${s.success('✓')} COMPILR.md: ${s.primary('Found')}`);
|
|
445
|
+
}
|
|
446
|
+
else if (detected.hasClaudeMd) {
|
|
447
|
+
lines.push(` ${s.success('✓')} CLAUDE.md: ${s.primary('Found (will use as COMPILR.md)')}`);
|
|
448
|
+
}
|
|
449
|
+
else {
|
|
450
|
+
lines.push(` ${s.muted('○')} COMPILR.md: ${s.muted('Will be created')}`);
|
|
451
|
+
}
|
|
452
|
+
lines.push('');
|
|
453
|
+
lines.push(s.muted(' Press Enter to continue, or Esc to go back'));
|
|
454
|
+
return lines;
|
|
455
|
+
}
|
|
456
|
+
renderImportStep3(s) {
|
|
457
|
+
const lines = [];
|
|
458
|
+
const detected = this.state.detectedProject;
|
|
459
|
+
lines.push(chalk.bold(' Git Repository Setup'));
|
|
460
|
+
lines.push('');
|
|
461
|
+
// Custom input mode for remote URL
|
|
462
|
+
if (this.state.importGitChoice === 'custom' || this.state.importGitChoice === 'init') {
|
|
463
|
+
lines.push(' Enter git remote URL:');
|
|
464
|
+
lines.push('');
|
|
465
|
+
lines.push(` > ${this.state.inputBuffer}|`);
|
|
466
|
+
lines.push('');
|
|
467
|
+
lines.push(s.muted(' Enter to confirm, Esc to cancel'));
|
|
468
|
+
return lines;
|
|
469
|
+
}
|
|
470
|
+
if (detected?.hasGit && detected.gitRemote) {
|
|
471
|
+
// Has git with remote
|
|
472
|
+
lines.push(` Detected remote: ${s.primary(detected.gitRemote)}`);
|
|
473
|
+
lines.push('');
|
|
474
|
+
lines.push(this.renderSelectionOption(s, 0, 'Use detected remote'));
|
|
475
|
+
lines.push(this.renderSelectionOption(s, 1, 'Enter different remote URL'));
|
|
476
|
+
lines.push(this.renderSelectionOption(s, 2, 'Skip git remote (local only)'));
|
|
477
|
+
}
|
|
478
|
+
else if (detected?.hasGit) {
|
|
479
|
+
// Has git but no remote
|
|
480
|
+
lines.push(' Git repository found but no remote configured.');
|
|
481
|
+
lines.push('');
|
|
482
|
+
lines.push(this.renderSelectionOption(s, 0, 'Enter remote URL'));
|
|
483
|
+
lines.push(this.renderSelectionOption(s, 1, 'Skip git remote (local only)'));
|
|
484
|
+
}
|
|
485
|
+
else {
|
|
486
|
+
// No git
|
|
487
|
+
lines.push(' No git repository found.');
|
|
488
|
+
lines.push('');
|
|
489
|
+
lines.push(this.renderSelectionOption(s, 0, 'Initialize git and enter remote URL'));
|
|
490
|
+
lines.push(this.renderSelectionOption(s, 1, 'Initialize git (local only)'));
|
|
491
|
+
lines.push(this.renderSelectionOption(s, 2, 'Skip git initialization'));
|
|
492
|
+
}
|
|
493
|
+
return lines;
|
|
494
|
+
}
|
|
495
|
+
renderImportStep4(s) {
|
|
496
|
+
const lines = [];
|
|
497
|
+
lines.push(chalk.bold(' Workflow mode'));
|
|
498
|
+
lines.push('');
|
|
499
|
+
for (let i = 0; i < WORKFLOW_MODE_OPTIONS.length; i++) {
|
|
500
|
+
const mode = WORKFLOW_MODE_OPTIONS[i];
|
|
501
|
+
const suffix = i === 0 ? ' (recommended)' : '';
|
|
502
|
+
lines.push(this.renderSelectionOption(s, i, `${String(i + 1)}. ${WORKFLOW_MODE_LABELS[mode]}${suffix}`));
|
|
503
|
+
}
|
|
504
|
+
lines.push('');
|
|
505
|
+
lines.push(s.muted(' Flexible: Work at your own pace, agent responds to requests'));
|
|
506
|
+
lines.push(s.muted(' Guided: Agent suggests next steps, tracks work item progress'));
|
|
507
|
+
return lines;
|
|
508
|
+
}
|
|
509
|
+
renderImportStep5(s) {
|
|
510
|
+
const lines = [];
|
|
511
|
+
const detected = this.state.detectedProject;
|
|
512
|
+
lines.push(chalk.bold(' Ready to import project?'));
|
|
513
|
+
lines.push('');
|
|
514
|
+
lines.push(` Path: ${s.primary(this.state.importPath)}`);
|
|
515
|
+
lines.push(` Name: ${s.primary(detected?.displayName ?? 'Unknown')}`);
|
|
516
|
+
lines.push(` Language: ${s.primary(getLanguageLabel(detected?.language ?? null))}`);
|
|
517
|
+
if (detected?.framework) {
|
|
518
|
+
lines.push(` Framework: ${s.primary(getFrameworkLabel(detected.framework))}`);
|
|
519
|
+
}
|
|
520
|
+
lines.push(` Git Remote: ${s.primary(this.state.gitRemote || 'None')}`);
|
|
521
|
+
lines.push(` Workflow: ${s.primary(WORKFLOW_MODE_LABELS[this.state.workflowMode])}`);
|
|
522
|
+
lines.push('');
|
|
523
|
+
lines.push(chalk.bold(' Will create:'));
|
|
524
|
+
if (!detected?.hasCompilrMd && !detected?.hasClaudeMd) {
|
|
525
|
+
lines.push(` ${s.success('✓')} COMPILR.md (project context file)`);
|
|
526
|
+
}
|
|
527
|
+
lines.push(` ${s.success('✓')} .compilr/config.json (local config)`);
|
|
528
|
+
lines.push(` ${s.success('✓')} Database entry (project tracking)`);
|
|
529
|
+
// Note if project is outside the standard projects folder
|
|
530
|
+
const projectsFolder = getProjectsPath();
|
|
531
|
+
if (!this.state.importPath.startsWith(projectsFolder)) {
|
|
532
|
+
lines.push('');
|
|
533
|
+
lines.push(s.muted(' Note: This project is outside your projects folder.'));
|
|
534
|
+
lines.push(s.muted(` It will be tracked at its current location.`));
|
|
535
|
+
}
|
|
536
|
+
lines.push('');
|
|
537
|
+
if (this.state.error) {
|
|
538
|
+
lines.push(s.error(` ${this.state.error}`));
|
|
539
|
+
lines.push('');
|
|
540
|
+
}
|
|
541
|
+
lines.push(this.renderSelectionOption(s, 0, 'Import'));
|
|
542
|
+
lines.push(this.renderSelectionOption(s, 1, 'Cancel'));
|
|
543
|
+
return lines;
|
|
544
|
+
}
|
|
545
|
+
renderImportStepFooter(s) {
|
|
546
|
+
const lines = [];
|
|
547
|
+
lines.push('');
|
|
548
|
+
if (this.state.importStep === 0) {
|
|
549
|
+
lines.push(s.muted(' Enter Confirm | Tab Autocomplete | Esc Cancel'));
|
|
550
|
+
}
|
|
551
|
+
else if (this.state.importStep === 4) {
|
|
552
|
+
lines.push(s.muted(' Up/Down Navigate | Enter Confirm | Esc Back'));
|
|
553
|
+
}
|
|
554
|
+
else if (this.state.importStep === 1) {
|
|
555
|
+
lines.push(s.muted(' Enter Continue | Esc Back'));
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
lines.push(s.muted(' Up/Down Navigate | Enter Select | Esc Back'));
|
|
559
|
+
}
|
|
560
|
+
return lines;
|
|
561
|
+
}
|
|
562
|
+
// ===========================================================================
|
|
563
|
+
// Key Handling
|
|
564
|
+
// ===========================================================================
|
|
565
|
+
handleKey(key) {
|
|
566
|
+
// Ctrl+C always cancels
|
|
567
|
+
if (this.isInterruptKey(key)) {
|
|
568
|
+
return this.close({ created: false });
|
|
569
|
+
}
|
|
570
|
+
// Import flow handling
|
|
571
|
+
if (this.state.projectType === 'existing') {
|
|
572
|
+
return this.handleImportKey(key);
|
|
573
|
+
}
|
|
574
|
+
// 'q' key on step 0 cancels
|
|
575
|
+
if (this.state.step === 0 && key.name === 'q') {
|
|
576
|
+
return this.close({ created: false });
|
|
577
|
+
}
|
|
578
|
+
// Escape on step 0 cancels, otherwise goes back
|
|
579
|
+
if (key.name === 'escape') {
|
|
580
|
+
// In git remote input mode, Esc skips to next step
|
|
581
|
+
if (this.state.gitRemoteInputMode) {
|
|
582
|
+
this.state.gitRemoteInputMode = false;
|
|
583
|
+
this.state.gitRemote = '';
|
|
584
|
+
this.state.inputBuffer = '';
|
|
585
|
+
this.state.step = 7;
|
|
586
|
+
this.state.selectedIndex = 0;
|
|
587
|
+
return this.rerender();
|
|
588
|
+
}
|
|
589
|
+
if (this.state.step === 0) {
|
|
590
|
+
return this.close({ created: false });
|
|
591
|
+
}
|
|
592
|
+
this.prevStep();
|
|
593
|
+
return this.rerender();
|
|
594
|
+
}
|
|
595
|
+
// Handle git remote URL input mode (sub-step of step 6)
|
|
596
|
+
if (this.state.gitRemoteInputMode) {
|
|
597
|
+
return this.handleGitRemoteInput(key);
|
|
598
|
+
}
|
|
599
|
+
// Handle selection steps
|
|
600
|
+
if (isSelectionStep(this.state.step)) {
|
|
601
|
+
return this.handleSelectionKey(key);
|
|
602
|
+
}
|
|
603
|
+
// Handle input steps
|
|
604
|
+
if (isInputStep(this.state.step)) {
|
|
605
|
+
return this.handleInputKey(key);
|
|
606
|
+
}
|
|
607
|
+
return this.noAction();
|
|
608
|
+
}
|
|
609
|
+
handleSelectionKey(key) {
|
|
610
|
+
const maxOptions = getMaxOptionsForStep(this.state.step);
|
|
611
|
+
// j/k for vim-style navigation
|
|
612
|
+
if (key.name === 'j' && this.state.selectedIndex < maxOptions - 1) {
|
|
613
|
+
this.state.selectedIndex++;
|
|
614
|
+
return this.rerender();
|
|
615
|
+
}
|
|
616
|
+
if (key.name === 'k' && this.state.selectedIndex > 0) {
|
|
617
|
+
this.state.selectedIndex--;
|
|
618
|
+
return this.rerender();
|
|
619
|
+
}
|
|
620
|
+
if (this.isUpKey(key) && this.state.selectedIndex > 0) {
|
|
621
|
+
this.state.selectedIndex--;
|
|
622
|
+
return this.rerender();
|
|
623
|
+
}
|
|
624
|
+
if (this.isDownKey(key) && this.state.selectedIndex < maxOptions - 1) {
|
|
625
|
+
this.state.selectedIndex++;
|
|
626
|
+
return this.rerender();
|
|
627
|
+
}
|
|
628
|
+
if (this.isEnterKey(key)) {
|
|
629
|
+
return this.handleSelectionEnter();
|
|
630
|
+
}
|
|
631
|
+
return this.noAction();
|
|
632
|
+
}
|
|
633
|
+
async handleSelectionEnter() {
|
|
634
|
+
// Step 0 - choose between new and existing project
|
|
635
|
+
if (this.state.step === 0) {
|
|
636
|
+
if (this.state.selectedIndex === 0) {
|
|
637
|
+
// New project
|
|
638
|
+
this.state.projectType = 'new';
|
|
639
|
+
this.state.step = 1;
|
|
640
|
+
this.state.inputBuffer = '';
|
|
641
|
+
this.state.selectedIndex = 0;
|
|
642
|
+
this.state.error = null;
|
|
643
|
+
}
|
|
644
|
+
else {
|
|
645
|
+
// Import existing project
|
|
646
|
+
this.state.projectType = 'existing';
|
|
647
|
+
this.state.importStep = 0;
|
|
648
|
+
this.state.inputBuffer = '';
|
|
649
|
+
this.state.selectedIndex = 0;
|
|
650
|
+
this.state.error = null;
|
|
651
|
+
}
|
|
652
|
+
return this.rerender();
|
|
653
|
+
}
|
|
654
|
+
// Step 8 - confirmation
|
|
655
|
+
if (this.state.step === 8) {
|
|
656
|
+
if (this.state.selectedIndex === 1) {
|
|
657
|
+
// Cancel
|
|
658
|
+
return this.close({ created: false });
|
|
659
|
+
}
|
|
660
|
+
// Verify all required fields are set
|
|
661
|
+
if (!this.state.repoPattern || !this.state.techStack || !this.state.codingStandards) {
|
|
662
|
+
this.state.error = 'Missing configuration values';
|
|
663
|
+
return this.rerender();
|
|
664
|
+
}
|
|
665
|
+
// Show generating state
|
|
666
|
+
this.state.isGenerating = true;
|
|
667
|
+
// Create project
|
|
668
|
+
const config = {
|
|
669
|
+
name: this.state.projectName,
|
|
670
|
+
description: this.state.description,
|
|
671
|
+
repoPattern: this.state.repoPattern,
|
|
672
|
+
techStack: this.state.techStack,
|
|
673
|
+
codingStandards: this.state.codingStandards,
|
|
674
|
+
initGit: this.state.initGit,
|
|
675
|
+
};
|
|
676
|
+
try {
|
|
677
|
+
// Ensure projects directory exists and create project there
|
|
678
|
+
ensureProjectsDirectory();
|
|
679
|
+
const projectsPath = getProjectsPath();
|
|
680
|
+
const result = await generateProject(config, projectsPath);
|
|
681
|
+
if (result.success) {
|
|
682
|
+
return this.close({
|
|
683
|
+
created: true,
|
|
684
|
+
projectPath: result.projectPath,
|
|
685
|
+
docsPath: result.docsPath,
|
|
686
|
+
filesCreated: result.filesCreated,
|
|
687
|
+
trackInDatabase: true, // Always track in database
|
|
688
|
+
workflowMode: this.state.workflowMode,
|
|
689
|
+
projectName: this.state.projectName,
|
|
690
|
+
description: this.state.description,
|
|
691
|
+
gitRemote: this.state.gitRemote || undefined,
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
else {
|
|
695
|
+
this.state.isGenerating = false;
|
|
696
|
+
this.state.error = result.error ?? 'Unknown error';
|
|
697
|
+
return this.rerender();
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
catch (error) {
|
|
701
|
+
this.state.isGenerating = false;
|
|
702
|
+
this.state.error = error.message;
|
|
703
|
+
return this.rerender();
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
this.nextStep();
|
|
707
|
+
return this.rerender();
|
|
708
|
+
}
|
|
709
|
+
handleInputKey(key) {
|
|
710
|
+
if (this.isEnterKey(key)) {
|
|
711
|
+
if (this.validateInput()) {
|
|
712
|
+
this.nextStep();
|
|
713
|
+
}
|
|
714
|
+
return this.rerender();
|
|
715
|
+
}
|
|
716
|
+
if (key.name === 'backspace') {
|
|
717
|
+
this.state.inputBuffer = this.state.inputBuffer.slice(0, -1);
|
|
718
|
+
this.state.error = null;
|
|
719
|
+
return this.rerender();
|
|
720
|
+
}
|
|
721
|
+
// Regular character input
|
|
722
|
+
if (key.char && key.char.length === 1 && key.char >= ' ' && key.char <= '~') {
|
|
723
|
+
this.state.inputBuffer += key.char;
|
|
724
|
+
this.state.error = null;
|
|
725
|
+
return this.rerender();
|
|
726
|
+
}
|
|
727
|
+
return this.noAction();
|
|
728
|
+
}
|
|
729
|
+
handleGitRemoteInput(key) {
|
|
730
|
+
// Enter - confirm and move to next step
|
|
731
|
+
if (this.isEnterKey(key)) {
|
|
732
|
+
this.state.gitRemote = this.state.inputBuffer.trim();
|
|
733
|
+
this.state.gitRemoteInputMode = false;
|
|
734
|
+
this.state.inputBuffer = '';
|
|
735
|
+
this.state.step = 7;
|
|
736
|
+
this.state.selectedIndex = 0;
|
|
737
|
+
return this.rerender();
|
|
738
|
+
}
|
|
739
|
+
// Backspace - delete last character
|
|
740
|
+
if (key.name === 'backspace') {
|
|
741
|
+
this.state.inputBuffer = this.state.inputBuffer.slice(0, -1);
|
|
742
|
+
return this.rerender();
|
|
743
|
+
}
|
|
744
|
+
// Regular character input
|
|
745
|
+
if (key.char && key.char.length === 1 && key.char >= ' ' && key.char <= '~') {
|
|
746
|
+
this.state.inputBuffer += key.char;
|
|
747
|
+
return this.rerender();
|
|
748
|
+
}
|
|
749
|
+
return this.noAction();
|
|
750
|
+
}
|
|
751
|
+
// ===========================================================================
|
|
752
|
+
// Import Flow Key Handling
|
|
753
|
+
// ===========================================================================
|
|
754
|
+
handleImportKey(key) {
|
|
755
|
+
// Escape handling for import flow
|
|
756
|
+
if (key.name === 'escape') {
|
|
757
|
+
// In git remote custom input mode, cancel and go back to selection
|
|
758
|
+
if (this.state.importGitChoice === 'custom' || this.state.importGitChoice === 'init') {
|
|
759
|
+
this.state.importGitChoice = null;
|
|
760
|
+
this.state.inputBuffer = '';
|
|
761
|
+
return this.rerender();
|
|
762
|
+
}
|
|
763
|
+
// Step 0: go back to project type selection
|
|
764
|
+
if (this.state.importStep === 0) {
|
|
765
|
+
this.state.projectType = null;
|
|
766
|
+
this.state.step = 0;
|
|
767
|
+
this.state.selectedIndex = 1; // Keep "existing" selected
|
|
768
|
+
this.state.error = null;
|
|
769
|
+
return this.rerender();
|
|
770
|
+
}
|
|
771
|
+
// Other steps: go back
|
|
772
|
+
this.prevImportStep();
|
|
773
|
+
return this.rerender();
|
|
774
|
+
}
|
|
775
|
+
// Handle based on current step
|
|
776
|
+
switch (this.state.importStep) {
|
|
777
|
+
case 0: // Path input
|
|
778
|
+
return this.handleImportPathInput(key);
|
|
779
|
+
case 1: // Detection results (just Enter to continue)
|
|
780
|
+
if (this.isEnterKey(key)) {
|
|
781
|
+
this.nextImportStep();
|
|
782
|
+
return this.rerender();
|
|
783
|
+
}
|
|
784
|
+
return this.noAction();
|
|
785
|
+
case 2: // Git configuration
|
|
786
|
+
return this.handleImportGitStep(key);
|
|
787
|
+
case 3: // Workflow mode
|
|
788
|
+
return this.handleImportWorkflowStep(key);
|
|
789
|
+
case 4: // Confirmation
|
|
790
|
+
return this.handleImportConfirmation(key);
|
|
791
|
+
default:
|
|
792
|
+
return this.noAction();
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
handleImportPathInput(key) {
|
|
796
|
+
// Enter - validate and continue
|
|
797
|
+
if (this.isEnterKey(key)) {
|
|
798
|
+
const inputPath = this.state.inputBuffer.trim();
|
|
799
|
+
if (!inputPath) {
|
|
800
|
+
this.state.error = 'Path is required';
|
|
801
|
+
return this.rerender();
|
|
802
|
+
}
|
|
803
|
+
// Resolve to absolute path
|
|
804
|
+
const absolutePath = path.isAbsolute(inputPath)
|
|
805
|
+
? inputPath
|
|
806
|
+
: path.resolve(process.cwd(), inputPath);
|
|
807
|
+
// Validate path
|
|
808
|
+
const validation = validateImportPath(absolutePath);
|
|
809
|
+
if (!validation.valid) {
|
|
810
|
+
this.state.error = validation.error ?? 'Invalid path';
|
|
811
|
+
return this.rerender();
|
|
812
|
+
}
|
|
813
|
+
// Check if already tracked in database
|
|
814
|
+
const existingProject = projectRepository.getByPath(absolutePath);
|
|
815
|
+
if (existingProject) {
|
|
816
|
+
this.state.error = `Already tracked as "${existingProject.displayName}"`;
|
|
817
|
+
return this.rerender();
|
|
818
|
+
}
|
|
819
|
+
// Detect project info
|
|
820
|
+
this.state.importPath = absolutePath;
|
|
821
|
+
this.state.detectedProject = detectProjectInfo(absolutePath);
|
|
822
|
+
this.state.error = null;
|
|
823
|
+
this.nextImportStep();
|
|
824
|
+
return this.rerender();
|
|
825
|
+
}
|
|
826
|
+
// Tab - autocomplete
|
|
827
|
+
if (key.name === 'tab') {
|
|
828
|
+
const completedPath = this.autocompleteImportPath(this.state.inputBuffer);
|
|
829
|
+
if (completedPath) {
|
|
830
|
+
this.state.inputBuffer = completedPath;
|
|
831
|
+
this.state.error = null;
|
|
832
|
+
}
|
|
833
|
+
return this.rerender();
|
|
834
|
+
}
|
|
835
|
+
// Backspace
|
|
836
|
+
if (key.name === 'backspace') {
|
|
837
|
+
this.state.inputBuffer = this.state.inputBuffer.slice(0, -1);
|
|
838
|
+
this.state.error = null;
|
|
839
|
+
return this.rerender();
|
|
840
|
+
}
|
|
841
|
+
// Regular character input
|
|
842
|
+
if (key.char && key.char.length === 1 && key.char >= ' ' && key.char <= '~') {
|
|
843
|
+
this.state.inputBuffer += key.char;
|
|
844
|
+
this.state.error = null;
|
|
845
|
+
return this.rerender();
|
|
846
|
+
}
|
|
847
|
+
return this.noAction();
|
|
848
|
+
}
|
|
849
|
+
handleImportGitStep(key) {
|
|
850
|
+
const detected = this.state.detectedProject;
|
|
851
|
+
// In custom URL input mode
|
|
852
|
+
if (this.state.importGitChoice === 'custom' || this.state.importGitChoice === 'init') {
|
|
853
|
+
if (this.isEnterKey(key)) {
|
|
854
|
+
this.state.gitRemote = this.state.inputBuffer.trim();
|
|
855
|
+
this.state.inputBuffer = '';
|
|
856
|
+
this.state.importGitChoice = null;
|
|
857
|
+
this.nextImportStep();
|
|
858
|
+
return this.rerender();
|
|
859
|
+
}
|
|
860
|
+
if (key.name === 'backspace') {
|
|
861
|
+
this.state.inputBuffer = this.state.inputBuffer.slice(0, -1);
|
|
862
|
+
return this.rerender();
|
|
863
|
+
}
|
|
864
|
+
if (key.char && key.char.length === 1 && key.char >= ' ' && key.char <= '~') {
|
|
865
|
+
this.state.inputBuffer += key.char;
|
|
866
|
+
return this.rerender();
|
|
867
|
+
}
|
|
868
|
+
return this.noAction();
|
|
869
|
+
}
|
|
870
|
+
// Navigation
|
|
871
|
+
const maxOptions = this.getImportGitMaxOptions();
|
|
872
|
+
if ((key.name === 'j' || this.isDownKey(key)) && this.state.selectedIndex < maxOptions - 1) {
|
|
873
|
+
this.state.selectedIndex++;
|
|
874
|
+
return this.rerender();
|
|
875
|
+
}
|
|
876
|
+
if ((key.name === 'k' || this.isUpKey(key)) && this.state.selectedIndex > 0) {
|
|
877
|
+
this.state.selectedIndex--;
|
|
878
|
+
return this.rerender();
|
|
879
|
+
}
|
|
880
|
+
// Enter to select
|
|
881
|
+
if (this.isEnterKey(key)) {
|
|
882
|
+
if (detected?.hasGit && detected.gitRemote) {
|
|
883
|
+
// Has git with remote
|
|
884
|
+
switch (this.state.selectedIndex) {
|
|
885
|
+
case 0: // Use detected
|
|
886
|
+
this.state.gitRemote = detected.gitRemote;
|
|
887
|
+
this.nextImportStep();
|
|
888
|
+
break;
|
|
889
|
+
case 1: // Custom
|
|
890
|
+
this.state.importGitChoice = 'custom';
|
|
891
|
+
this.state.inputBuffer = '';
|
|
892
|
+
break;
|
|
893
|
+
case 2: // Skip
|
|
894
|
+
this.state.gitRemote = '';
|
|
895
|
+
this.nextImportStep();
|
|
896
|
+
break;
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
else if (detected?.hasGit) {
|
|
900
|
+
// Has git but no remote
|
|
901
|
+
switch (this.state.selectedIndex) {
|
|
902
|
+
case 0: // Enter URL
|
|
903
|
+
this.state.importGitChoice = 'custom';
|
|
904
|
+
this.state.inputBuffer = '';
|
|
905
|
+
break;
|
|
906
|
+
case 1: // Skip
|
|
907
|
+
this.state.gitRemote = '';
|
|
908
|
+
this.nextImportStep();
|
|
909
|
+
break;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
else {
|
|
913
|
+
// No git
|
|
914
|
+
switch (this.state.selectedIndex) {
|
|
915
|
+
case 0: // Init + URL
|
|
916
|
+
this.state.importGitChoice = 'init';
|
|
917
|
+
this.state.inputBuffer = '';
|
|
918
|
+
this.state.initGit = true;
|
|
919
|
+
break;
|
|
920
|
+
case 1: // Init only
|
|
921
|
+
this.state.initGit = true;
|
|
922
|
+
this.state.gitRemote = '';
|
|
923
|
+
this.nextImportStep();
|
|
924
|
+
break;
|
|
925
|
+
case 2: // Skip
|
|
926
|
+
this.state.initGit = false;
|
|
927
|
+
this.state.gitRemote = '';
|
|
928
|
+
this.nextImportStep();
|
|
929
|
+
break;
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
return this.rerender();
|
|
933
|
+
}
|
|
934
|
+
return this.noAction();
|
|
935
|
+
}
|
|
936
|
+
handleImportWorkflowStep(key) {
|
|
937
|
+
const maxOptions = WORKFLOW_MODE_OPTIONS.length;
|
|
938
|
+
// Navigation
|
|
939
|
+
if ((key.name === 'j' || this.isDownKey(key)) && this.state.selectedIndex < maxOptions - 1) {
|
|
940
|
+
this.state.selectedIndex++;
|
|
941
|
+
return this.rerender();
|
|
942
|
+
}
|
|
943
|
+
if ((key.name === 'k' || this.isUpKey(key)) && this.state.selectedIndex > 0) {
|
|
944
|
+
this.state.selectedIndex--;
|
|
945
|
+
return this.rerender();
|
|
946
|
+
}
|
|
947
|
+
// Enter to select
|
|
948
|
+
if (this.isEnterKey(key)) {
|
|
949
|
+
this.state.workflowMode = WORKFLOW_MODE_OPTIONS[this.state.selectedIndex];
|
|
950
|
+
this.nextImportStep();
|
|
951
|
+
return this.rerender();
|
|
952
|
+
}
|
|
953
|
+
return this.noAction();
|
|
954
|
+
}
|
|
955
|
+
handleImportConfirmation(key) {
|
|
956
|
+
// Navigation
|
|
957
|
+
if ((key.name === 'j' || this.isDownKey(key)) && this.state.selectedIndex < 1) {
|
|
958
|
+
this.state.selectedIndex++;
|
|
959
|
+
return this.rerender();
|
|
960
|
+
}
|
|
961
|
+
if ((key.name === 'k' || this.isUpKey(key)) && this.state.selectedIndex > 0) {
|
|
962
|
+
this.state.selectedIndex--;
|
|
963
|
+
return this.rerender();
|
|
964
|
+
}
|
|
965
|
+
// Enter to confirm
|
|
966
|
+
if (this.isEnterKey(key)) {
|
|
967
|
+
if (this.state.selectedIndex === 1) {
|
|
968
|
+
// Cancel
|
|
969
|
+
return this.close({ created: false });
|
|
970
|
+
}
|
|
971
|
+
// Import project
|
|
972
|
+
return this.executeImport();
|
|
973
|
+
}
|
|
974
|
+
return this.noAction();
|
|
975
|
+
}
|
|
976
|
+
executeImport() {
|
|
977
|
+
const detected = this.state.detectedProject;
|
|
978
|
+
if (!detected) {
|
|
979
|
+
this.state.error = 'No project detected';
|
|
980
|
+
return this.rerender();
|
|
981
|
+
}
|
|
982
|
+
this.state.isGenerating = true;
|
|
983
|
+
try {
|
|
984
|
+
// Create .compilr directory
|
|
985
|
+
const compilrDir = path.join(this.state.importPath, '.compilr');
|
|
986
|
+
if (!fs.existsSync(compilrDir)) {
|
|
987
|
+
fs.mkdirSync(compilrDir, { recursive: true });
|
|
988
|
+
}
|
|
989
|
+
// Create .compilr/config.json
|
|
990
|
+
const configContent = JSON.stringify({
|
|
991
|
+
version: 1,
|
|
992
|
+
projectPath: this.state.importPath,
|
|
993
|
+
workflow_mode: this.state.workflowMode,
|
|
994
|
+
created_at: new Date().toISOString(),
|
|
995
|
+
}, null, 2);
|
|
996
|
+
fs.writeFileSync(path.join(compilrDir, 'config.json'), configContent, 'utf-8');
|
|
997
|
+
// Create COMPILR.md if it doesn't exist
|
|
998
|
+
if (!detected.hasCompilrMd && !detected.hasClaudeMd) {
|
|
999
|
+
const compilrMdContent = generateCompilrMdForImport({
|
|
1000
|
+
name: detected.name,
|
|
1001
|
+
displayName: detected.displayName,
|
|
1002
|
+
path: this.state.importPath,
|
|
1003
|
+
detected,
|
|
1004
|
+
workflowMode: this.state.workflowMode,
|
|
1005
|
+
});
|
|
1006
|
+
fs.writeFileSync(path.join(this.state.importPath, 'COMPILR.md'), compilrMdContent, 'utf-8');
|
|
1007
|
+
}
|
|
1008
|
+
// Initialize git if requested and not already initialized
|
|
1009
|
+
if (this.state.initGit && !detected.hasGit) {
|
|
1010
|
+
try {
|
|
1011
|
+
execSync('git init', { cwd: this.state.importPath, stdio: 'ignore' });
|
|
1012
|
+
}
|
|
1013
|
+
catch {
|
|
1014
|
+
// Git init failed - not critical
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
// Return success - database registration is handled by the command handler
|
|
1018
|
+
return this.close({
|
|
1019
|
+
created: true,
|
|
1020
|
+
imported: true,
|
|
1021
|
+
projectPath: this.state.importPath,
|
|
1022
|
+
trackInDatabase: true,
|
|
1023
|
+
workflowMode: this.state.workflowMode,
|
|
1024
|
+
projectName: detected.name,
|
|
1025
|
+
description: undefined, // No description for imports
|
|
1026
|
+
gitRemote: this.state.gitRemote || undefined,
|
|
1027
|
+
detectedProject: detected,
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
1030
|
+
catch (error) {
|
|
1031
|
+
this.state.isGenerating = false;
|
|
1032
|
+
this.state.error = error.message;
|
|
1033
|
+
return this.rerender();
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
getImportGitMaxOptions() {
|
|
1037
|
+
const detected = this.state.detectedProject;
|
|
1038
|
+
if (detected?.hasGit && detected.gitRemote)
|
|
1039
|
+
return 3;
|
|
1040
|
+
if (detected?.hasGit)
|
|
1041
|
+
return 2;
|
|
1042
|
+
return 3;
|
|
1043
|
+
}
|
|
1044
|
+
nextImportStep() {
|
|
1045
|
+
this.state.importStep = Math.min(4, this.state.importStep + 1);
|
|
1046
|
+
this.state.selectedIndex = 0;
|
|
1047
|
+
this.state.error = null;
|
|
1048
|
+
}
|
|
1049
|
+
prevImportStep() {
|
|
1050
|
+
this.state.importStep = Math.max(0, this.state.importStep - 1);
|
|
1051
|
+
this.state.selectedIndex = 0;
|
|
1052
|
+
this.state.error = null;
|
|
1053
|
+
}
|
|
1054
|
+
autocompleteImportPath(input) {
|
|
1055
|
+
if (!input)
|
|
1056
|
+
return null;
|
|
1057
|
+
try {
|
|
1058
|
+
// Resolve the input to determine directory and prefix
|
|
1059
|
+
const resolvedInput = input.startsWith('/')
|
|
1060
|
+
? input
|
|
1061
|
+
: path.resolve(process.cwd(), input);
|
|
1062
|
+
let dir;
|
|
1063
|
+
let prefix;
|
|
1064
|
+
if (fs.existsSync(resolvedInput) && fs.statSync(resolvedInput).isDirectory()) {
|
|
1065
|
+
// Input is a complete directory, list its contents
|
|
1066
|
+
dir = resolvedInput;
|
|
1067
|
+
prefix = '';
|
|
1068
|
+
}
|
|
1069
|
+
else {
|
|
1070
|
+
// Input is partial, get parent directory and prefix
|
|
1071
|
+
dir = path.dirname(resolvedInput);
|
|
1072
|
+
prefix = path.basename(resolvedInput).toLowerCase();
|
|
1073
|
+
}
|
|
1074
|
+
if (!fs.existsSync(dir))
|
|
1075
|
+
return null;
|
|
1076
|
+
// Get directory contents
|
|
1077
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true })
|
|
1078
|
+
.filter((e) => e.isDirectory())
|
|
1079
|
+
.filter((e) => !e.name.startsWith('.')) // Hide hidden directories
|
|
1080
|
+
.map((e) => e.name);
|
|
1081
|
+
// Find matches
|
|
1082
|
+
const matches = entries.filter((name) => name.toLowerCase().startsWith(prefix));
|
|
1083
|
+
if (matches.length === 0)
|
|
1084
|
+
return null;
|
|
1085
|
+
if (matches.length === 1) {
|
|
1086
|
+
// Single match - complete it with trailing slash
|
|
1087
|
+
const completed = path.join(dir, matches[0]);
|
|
1088
|
+
// Keep relative if input was relative
|
|
1089
|
+
if (!input.startsWith('/')) {
|
|
1090
|
+
const relative = path.relative(process.cwd(), completed);
|
|
1091
|
+
return relative + '/';
|
|
1092
|
+
}
|
|
1093
|
+
return completed + '/';
|
|
1094
|
+
}
|
|
1095
|
+
// Multiple matches - find common prefix
|
|
1096
|
+
const sortedMatches = matches.sort();
|
|
1097
|
+
const first = sortedMatches[0];
|
|
1098
|
+
const last = sortedMatches[sortedMatches.length - 1];
|
|
1099
|
+
let common = '';
|
|
1100
|
+
for (let i = 0; i < first.length; i++) {
|
|
1101
|
+
if (first[i] === last[i]) {
|
|
1102
|
+
common += first[i];
|
|
1103
|
+
}
|
|
1104
|
+
else {
|
|
1105
|
+
break;
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
if (common.length > prefix.length) {
|
|
1109
|
+
const completed = path.join(dir, common);
|
|
1110
|
+
if (!input.startsWith('/')) {
|
|
1111
|
+
return path.relative(process.cwd(), completed);
|
|
1112
|
+
}
|
|
1113
|
+
return completed;
|
|
1114
|
+
}
|
|
1115
|
+
return null;
|
|
1116
|
+
}
|
|
1117
|
+
catch {
|
|
1118
|
+
return null;
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
// ===========================================================================
|
|
1122
|
+
// Step Navigation
|
|
1123
|
+
// ===========================================================================
|
|
1124
|
+
nextStep() {
|
|
1125
|
+
switch (this.state.step) {
|
|
1126
|
+
// Note: step 0 is handled in handleSelectionEnter() since it branches to import flow
|
|
1127
|
+
case 1:
|
|
1128
|
+
this.state.projectName = this.state.inputBuffer.trim();
|
|
1129
|
+
this.state.step = 2;
|
|
1130
|
+
this.state.inputBuffer = '';
|
|
1131
|
+
break;
|
|
1132
|
+
case 2:
|
|
1133
|
+
this.state.description = this.state.inputBuffer.trim();
|
|
1134
|
+
this.state.step = 3;
|
|
1135
|
+
this.state.selectedIndex = 0;
|
|
1136
|
+
break;
|
|
1137
|
+
case 3:
|
|
1138
|
+
this.state.repoPattern = REPO_PATTERN_OPTIONS[this.state.selectedIndex];
|
|
1139
|
+
this.state.step = 4;
|
|
1140
|
+
this.state.selectedIndex = 0;
|
|
1141
|
+
break;
|
|
1142
|
+
case 4:
|
|
1143
|
+
this.state.techStack = TECH_STACK_OPTIONS[this.state.selectedIndex];
|
|
1144
|
+
this.state.step = 5;
|
|
1145
|
+
this.state.selectedIndex = 0;
|
|
1146
|
+
break;
|
|
1147
|
+
case 5:
|
|
1148
|
+
this.state.codingStandards = CODING_STANDARDS_OPTIONS[this.state.selectedIndex];
|
|
1149
|
+
this.state.step = 6;
|
|
1150
|
+
this.state.selectedIndex = 0;
|
|
1151
|
+
break;
|
|
1152
|
+
case 6:
|
|
1153
|
+
this.state.initGit = this.state.selectedIndex === 0;
|
|
1154
|
+
// Always prompt for git remote URL (useful even if not initializing git)
|
|
1155
|
+
// User might have an existing repo on GitHub they want to associate
|
|
1156
|
+
this.state.gitRemoteInputMode = true;
|
|
1157
|
+
this.state.inputBuffer = '';
|
|
1158
|
+
break;
|
|
1159
|
+
case 7:
|
|
1160
|
+
this.state.workflowMode = WORKFLOW_MODE_OPTIONS[this.state.selectedIndex];
|
|
1161
|
+
this.state.step = 8;
|
|
1162
|
+
this.state.selectedIndex = 0;
|
|
1163
|
+
break;
|
|
1164
|
+
}
|
|
1165
|
+
this.state.error = null;
|
|
1166
|
+
}
|
|
1167
|
+
prevStep() {
|
|
1168
|
+
switch (this.state.step) {
|
|
1169
|
+
case 1:
|
|
1170
|
+
this.state.step = 0;
|
|
1171
|
+
this.state.selectedIndex = 0;
|
|
1172
|
+
break;
|
|
1173
|
+
case 2:
|
|
1174
|
+
this.state.step = 1;
|
|
1175
|
+
this.state.inputBuffer = this.state.projectName;
|
|
1176
|
+
break;
|
|
1177
|
+
case 3:
|
|
1178
|
+
this.state.step = 2;
|
|
1179
|
+
this.state.inputBuffer = this.state.description;
|
|
1180
|
+
break;
|
|
1181
|
+
case 4:
|
|
1182
|
+
this.state.step = 3;
|
|
1183
|
+
this.state.selectedIndex = this.state.repoPattern ? REPO_PATTERN_OPTIONS.indexOf(this.state.repoPattern) : 0;
|
|
1184
|
+
break;
|
|
1185
|
+
case 5:
|
|
1186
|
+
this.state.step = 4;
|
|
1187
|
+
this.state.selectedIndex = this.state.techStack ? TECH_STACK_OPTIONS.indexOf(this.state.techStack) : 0;
|
|
1188
|
+
break;
|
|
1189
|
+
case 6:
|
|
1190
|
+
this.state.step = 5;
|
|
1191
|
+
this.state.selectedIndex = this.state.codingStandards ? CODING_STANDARDS_OPTIONS.indexOf(this.state.codingStandards) : 0;
|
|
1192
|
+
break;
|
|
1193
|
+
case 7:
|
|
1194
|
+
this.state.step = 6;
|
|
1195
|
+
this.state.selectedIndex = this.state.initGit ? 0 : 1;
|
|
1196
|
+
break;
|
|
1197
|
+
case 8:
|
|
1198
|
+
this.state.step = 7;
|
|
1199
|
+
this.state.selectedIndex = WORKFLOW_MODE_OPTIONS.indexOf(this.state.workflowMode);
|
|
1200
|
+
break;
|
|
1201
|
+
}
|
|
1202
|
+
this.state.error = null;
|
|
1203
|
+
}
|
|
1204
|
+
validateInput() {
|
|
1205
|
+
if (this.state.step === 1) {
|
|
1206
|
+
const name = this.state.inputBuffer.trim();
|
|
1207
|
+
if (!name) {
|
|
1208
|
+
this.state.error = 'Project name is required';
|
|
1209
|
+
return false;
|
|
1210
|
+
}
|
|
1211
|
+
if (!isValidProjectName(name)) {
|
|
1212
|
+
this.state.error = 'Invalid name. Use lowercase letters, numbers, hyphens (2-50 chars, start with letter)';
|
|
1213
|
+
return false;
|
|
1214
|
+
}
|
|
1215
|
+
if (projectExists(name)) {
|
|
1216
|
+
this.state.error = `Directory "${name}" already exists`;
|
|
1217
|
+
return false;
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
if (this.state.step === 2) {
|
|
1221
|
+
const desc = this.state.inputBuffer.trim();
|
|
1222
|
+
if (!desc) {
|
|
1223
|
+
this.state.error = 'Description is required';
|
|
1224
|
+
return false;
|
|
1225
|
+
}
|
|
1226
|
+
if (desc.length < 10) {
|
|
1227
|
+
this.state.error = 'Description too short (min 10 characters)';
|
|
1228
|
+
return false;
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
return true;
|
|
1232
|
+
}
|
|
1233
|
+
// ===========================================================================
|
|
1234
|
+
// Close Summary
|
|
1235
|
+
// ===========================================================================
|
|
1236
|
+
getCloseSummary(result) {
|
|
1237
|
+
const s = this.getStyles();
|
|
1238
|
+
if (!result.created) {
|
|
1239
|
+
return s.warning('Init cancelled');
|
|
1240
|
+
}
|
|
1241
|
+
return null;
|
|
1242
|
+
}
|
|
1243
|
+
}
|