@gokulvenkatareddy/cortex 0.1.7
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 +1295 -0
- package/apps/octogent/.github/workflows/ci.yml +40 -0
- package/apps/octogent/.shims/claude +4 -0
- package/apps/octogent/AGENTS.md +71 -0
- package/apps/octogent/CONTRIBUTING.md +72 -0
- package/apps/octogent/LICENSE +21 -0
- package/apps/octogent/README.md +184 -0
- package/apps/octogent/apps/api/AGENTS.md +32 -0
- package/apps/octogent/apps/api/package.json +19 -0
- package/apps/octogent/apps/api/src/agentStateDetection.ts +181 -0
- package/apps/octogent/apps/api/src/claudeSessionScanner.ts +235 -0
- package/apps/octogent/apps/api/src/claudeSkills.ts +182 -0
- package/apps/octogent/apps/api/src/claudeUsage.ts +922 -0
- package/apps/octogent/apps/api/src/cli.ts +595 -0
- package/apps/octogent/apps/api/src/codeIntelStore.ts +46 -0
- package/apps/octogent/apps/api/src/codexUsage.ts +278 -0
- package/apps/octogent/apps/api/src/createApiServer/codeIntelRoutes.ts +60 -0
- package/apps/octogent/apps/api/src/createApiServer/conversationRoutes.ts +128 -0
- package/apps/octogent/apps/api/src/createApiServer/deckRoutes.ts +873 -0
- package/apps/octogent/apps/api/src/createApiServer/gitParsers.ts +140 -0
- package/apps/octogent/apps/api/src/createApiServer/gitRoutes.ts +214 -0
- package/apps/octogent/apps/api/src/createApiServer/miscRoutes.ts +316 -0
- package/apps/octogent/apps/api/src/createApiServer/monitorParsers.ts +137 -0
- package/apps/octogent/apps/api/src/createApiServer/monitorRoutes.ts +95 -0
- package/apps/octogent/apps/api/src/createApiServer/requestHandler.ts +311 -0
- package/apps/octogent/apps/api/src/createApiServer/requestParsers.ts +25 -0
- package/apps/octogent/apps/api/src/createApiServer/routeHelpers.ts +97 -0
- package/apps/octogent/apps/api/src/createApiServer/security.ts +70 -0
- package/apps/octogent/apps/api/src/createApiServer/terminalParsers.ts +167 -0
- package/apps/octogent/apps/api/src/createApiServer/terminalRoutes.ts +315 -0
- package/apps/octogent/apps/api/src/createApiServer/types.ts +24 -0
- package/apps/octogent/apps/api/src/createApiServer/uiStateParsers.ts +255 -0
- package/apps/octogent/apps/api/src/createApiServer/upgradeHandler.ts +38 -0
- package/apps/octogent/apps/api/src/createApiServer/usageRoutes.ts +84 -0
- package/apps/octogent/apps/api/src/createApiServer.ts +176 -0
- package/apps/octogent/apps/api/src/deck/readDeckTentacles.ts +595 -0
- package/apps/octogent/apps/api/src/githubRepoSummary.ts +397 -0
- package/apps/octogent/apps/api/src/logging.ts +9 -0
- package/apps/octogent/apps/api/src/monitor/defaults.ts +3 -0
- package/apps/octogent/apps/api/src/monitor/index.ts +8 -0
- package/apps/octogent/apps/api/src/monitor/repository.ts +303 -0
- package/apps/octogent/apps/api/src/monitor/service.ts +349 -0
- package/apps/octogent/apps/api/src/monitor/types.ts +120 -0
- package/apps/octogent/apps/api/src/monitor/xProvider.ts +587 -0
- package/apps/octogent/apps/api/src/projectPersistence.ts +377 -0
- package/apps/octogent/apps/api/src/prompts/index.ts +10 -0
- package/apps/octogent/apps/api/src/prompts/promptResolver.ts +145 -0
- package/apps/octogent/apps/api/src/runtimeMetadata.ts +69 -0
- package/apps/octogent/apps/api/src/server.ts +80 -0
- package/apps/octogent/apps/api/src/setupState.ts +80 -0
- package/apps/octogent/apps/api/src/setupStatus.ts +174 -0
- package/apps/octogent/apps/api/src/startupPrerequisites.ts +146 -0
- package/apps/octogent/apps/api/src/terminalRuntime/channelMessaging.ts +87 -0
- package/apps/octogent/apps/api/src/terminalRuntime/claudeTranscript.ts +279 -0
- package/apps/octogent/apps/api/src/terminalRuntime/constants.ts +15 -0
- package/apps/octogent/apps/api/src/terminalRuntime/conversations.ts +492 -0
- package/apps/octogent/apps/api/src/terminalRuntime/gitOperations.ts +341 -0
- package/apps/octogent/apps/api/src/terminalRuntime/hookProcessor.ts +405 -0
- package/apps/octogent/apps/api/src/terminalRuntime/protocol.ts +46 -0
- package/apps/octogent/apps/api/src/terminalRuntime/ptyEnvironment.ts +50 -0
- package/apps/octogent/apps/api/src/terminalRuntime/registry.ts +423 -0
- package/apps/octogent/apps/api/src/terminalRuntime/sessionRuntime.ts +671 -0
- package/apps/octogent/apps/api/src/terminalRuntime/systemClients.ts +432 -0
- package/apps/octogent/apps/api/src/terminalRuntime/types.ts +157 -0
- package/apps/octogent/apps/api/src/terminalRuntime/worktreeManager.ts +135 -0
- package/apps/octogent/apps/api/src/terminalRuntime.ts +567 -0
- package/apps/octogent/apps/api/src/usageUtils.ts +16 -0
- package/apps/octogent/apps/api/src/ws-shim.d.ts +28 -0
- package/apps/octogent/apps/api/tests/agentStateDetection.test.ts +67 -0
- package/apps/octogent/apps/api/tests/claudeUsage.test.ts +583 -0
- package/apps/octogent/apps/api/tests/codexUsage.test.ts +107 -0
- package/apps/octogent/apps/api/tests/createApiServer.test.ts +3207 -0
- package/apps/octogent/apps/api/tests/githubRepoSummary.test.ts +100 -0
- package/apps/octogent/apps/api/tests/logging.test.ts +33 -0
- package/apps/octogent/apps/api/tests/monitorApi.test.ts +467 -0
- package/apps/octogent/apps/api/tests/monitorCore.test.ts +104 -0
- package/apps/octogent/apps/api/tests/promptResolver.test.ts +109 -0
- package/apps/octogent/apps/api/tests/protocol.test.ts +14 -0
- package/apps/octogent/apps/api/tests/sessionRuntime.test.ts +608 -0
- package/apps/octogent/apps/api/tests/startupPrerequisites.test.ts +70 -0
- package/apps/octogent/apps/api/tests/upgradeHandler.test.ts +40 -0
- package/apps/octogent/apps/api/tests/xMonitorProvider.test.ts +109 -0
- package/apps/octogent/apps/api/tsconfig.json +7 -0
- package/apps/octogent/apps/api/vitest.config.ts +7 -0
- package/apps/octogent/apps/web/AGENTS.md +38 -0
- package/apps/octogent/apps/web/index.html +13 -0
- package/apps/octogent/apps/web/package.json +32 -0
- package/apps/octogent/apps/web/public/octopus-favicon.svg +26 -0
- package/apps/octogent/apps/web/src/App.tsx +646 -0
- package/apps/octogent/apps/web/src/app/canvas/types.ts +34 -0
- package/apps/octogent/apps/web/src/app/codeIntelAggregation.ts +278 -0
- package/apps/octogent/apps/web/src/app/constants.ts +28 -0
- package/apps/octogent/apps/web/src/app/conversationNormalizers.ts +135 -0
- package/apps/octogent/apps/web/src/app/formatTimestamp.ts +18 -0
- package/apps/octogent/apps/web/src/app/githubMetrics.ts +76 -0
- package/apps/octogent/apps/web/src/app/githubNormalizers.ts +91 -0
- package/apps/octogent/apps/web/src/app/hooks/useAgentRuntimeStates.ts +18 -0
- package/apps/octogent/apps/web/src/app/hooks/useBackendLivenessPolling.ts +53 -0
- package/apps/octogent/apps/web/src/app/hooks/useCanvasGraphData.ts +449 -0
- package/apps/octogent/apps/web/src/app/hooks/useCanvasTransform.ts +260 -0
- package/apps/octogent/apps/web/src/app/hooks/useClaudeUsagePolling.ts +40 -0
- package/apps/octogent/apps/web/src/app/hooks/useClickOutside.ts +30 -0
- package/apps/octogent/apps/web/src/app/hooks/useCodeIntelRuntime.ts +83 -0
- package/apps/octogent/apps/web/src/app/hooks/useCodexUsagePolling.ts +35 -0
- package/apps/octogent/apps/web/src/app/hooks/useConsoleKeyboardShortcuts.ts +31 -0
- package/apps/octogent/apps/web/src/app/hooks/useConversationsRuntime.ts +377 -0
- package/apps/octogent/apps/web/src/app/hooks/useForceSimulation.ts +319 -0
- package/apps/octogent/apps/web/src/app/hooks/useGitHubPrimaryViewModel.ts +143 -0
- package/apps/octogent/apps/web/src/app/hooks/useGithubSummaryPolling.ts +28 -0
- package/apps/octogent/apps/web/src/app/hooks/useInitialColumnsHydration.ts +64 -0
- package/apps/octogent/apps/web/src/app/hooks/useMonitorRuntime.ts +220 -0
- package/apps/octogent/apps/web/src/app/hooks/usePersistedUiState.ts +536 -0
- package/apps/octogent/apps/web/src/app/hooks/usePollingData.ts +79 -0
- package/apps/octogent/apps/web/src/app/hooks/usePromptLibrary.ts +185 -0
- package/apps/octogent/apps/web/src/app/hooks/useTentacleGitLifecycle.ts +530 -0
- package/apps/octogent/apps/web/src/app/hooks/useTerminalCompletionNotification.ts +94 -0
- package/apps/octogent/apps/web/src/app/hooks/useTerminalMutations.ts +266 -0
- package/apps/octogent/apps/web/src/app/hooks/useTerminalStateReconciliation.ts +23 -0
- package/apps/octogent/apps/web/src/app/hooks/useUsageHeatmapPolling.ts +43 -0
- package/apps/octogent/apps/web/src/app/hooks/useWorkspaceSetup.ts +80 -0
- package/apps/octogent/apps/web/src/app/hotkeys.ts +31 -0
- package/apps/octogent/apps/web/src/app/monitorNormalizers.ts +145 -0
- package/apps/octogent/apps/web/src/app/notificationSounds.ts +164 -0
- package/apps/octogent/apps/web/src/app/terminalRuntimeStateStore.ts +261 -0
- package/apps/octogent/apps/web/src/app/terminalState.ts +21 -0
- package/apps/octogent/apps/web/src/app/types.ts +42 -0
- package/apps/octogent/apps/web/src/app/uiStateNormalizers.ts +113 -0
- package/apps/octogent/apps/web/src/app/usageNormalizers.ts +58 -0
- package/apps/octogent/apps/web/src/components/ActiveAgentsSidebar.tsx +60 -0
- package/apps/octogent/apps/web/src/components/ActivityPrimaryView.tsx +21 -0
- package/apps/octogent/apps/web/src/components/AgentStateBadge.tsx +47 -0
- package/apps/octogent/apps/web/src/components/CanvasPrimaryView.tsx +1532 -0
- package/apps/octogent/apps/web/src/components/ClearAllConversationsDialog.tsx +33 -0
- package/apps/octogent/apps/web/src/components/CodeIntelArcDiagram.tsx +245 -0
- package/apps/octogent/apps/web/src/components/CodeIntelPrimaryView.tsx +104 -0
- package/apps/octogent/apps/web/src/components/CodeIntelTreemap.tsx +138 -0
- package/apps/octogent/apps/web/src/components/ConsolePrimaryNav.tsx +31 -0
- package/apps/octogent/apps/web/src/components/ConversationsPrimaryView.tsx +243 -0
- package/apps/octogent/apps/web/src/components/DeckPrimaryView.tsx +613 -0
- package/apps/octogent/apps/web/src/components/DeleteTentacleDialog.tsx +91 -0
- package/apps/octogent/apps/web/src/components/EmptyOctopus.tsx +715 -0
- package/apps/octogent/apps/web/src/components/GitHubPrimaryView.tsx +494 -0
- package/apps/octogent/apps/web/src/components/MonitorPrimaryView.tsx +475 -0
- package/apps/octogent/apps/web/src/components/PrimaryViewRouter.tsx +99 -0
- package/apps/octogent/apps/web/src/components/PromptsPrimaryView.tsx +243 -0
- package/apps/octogent/apps/web/src/components/RuntimeStatusStrip.tsx +273 -0
- package/apps/octogent/apps/web/src/components/SettingsPrimaryView.tsx +92 -0
- package/apps/octogent/apps/web/src/components/SidebarActionPanel.tsx +124 -0
- package/apps/octogent/apps/web/src/components/SidebarConversationsList.tsx +279 -0
- package/apps/octogent/apps/web/src/components/SidebarPromptsList.tsx +116 -0
- package/apps/octogent/apps/web/src/components/TelemetryTape.tsx +106 -0
- package/apps/octogent/apps/web/src/components/TentacleGitActionsDialog.tsx +341 -0
- package/apps/octogent/apps/web/src/components/Terminal.tsx +524 -0
- package/apps/octogent/apps/web/src/components/TerminalPromptPicker.tsx +140 -0
- package/apps/octogent/apps/web/src/components/UsageHeatmap.tsx +702 -0
- package/apps/octogent/apps/web/src/components/canvas/CanvasTentaclePanel.tsx +485 -0
- package/apps/octogent/apps/web/src/components/canvas/CanvasTerminalColumn.tsx +89 -0
- package/apps/octogent/apps/web/src/components/canvas/DeleteAllTerminalsDialog.tsx +221 -0
- package/apps/octogent/apps/web/src/components/canvas/OctopusNode.tsx +307 -0
- package/apps/octogent/apps/web/src/components/canvas/SessionNode.tsx +185 -0
- package/apps/octogent/apps/web/src/components/deck/ActionCards.tsx +118 -0
- package/apps/octogent/apps/web/src/components/deck/AddTentacleForm.tsx +269 -0
- package/apps/octogent/apps/web/src/components/deck/DeckBottomActions.tsx +56 -0
- package/apps/octogent/apps/web/src/components/deck/TentaclePod.tsx +334 -0
- package/apps/octogent/apps/web/src/components/deck/WorkspaceSetupCard.tsx +105 -0
- package/apps/octogent/apps/web/src/components/deck/octopusVisuals.ts +72 -0
- package/apps/octogent/apps/web/src/components/terminalReplay.ts +62 -0
- package/apps/octogent/apps/web/src/components/terminalWheel.ts +54 -0
- package/apps/octogent/apps/web/src/components/ui/ActionButton.tsx +34 -0
- package/apps/octogent/apps/web/src/components/ui/ConfirmationDialog.tsx +86 -0
- package/apps/octogent/apps/web/src/components/ui/MarkdownContent.tsx +43 -0
- package/apps/octogent/apps/web/src/components/ui/SettingsToggle.tsx +34 -0
- package/apps/octogent/apps/web/src/components/ui/StatusBadge.tsx +24 -0
- package/apps/octogent/apps/web/src/main.tsx +17 -0
- package/apps/octogent/apps/web/src/runtime/HttpTerminalSnapshotReader.ts +87 -0
- package/apps/octogent/apps/web/src/runtime/runtimeEndpoints.ts +412 -0
- package/apps/octogent/apps/web/src/styles/chrome-and-buttons.css +272 -0
- package/apps/octogent/apps/web/src/styles/console-canvas-activity.css +358 -0
- package/apps/octogent/apps/web/src/styles/console-canvas-canvas.css +1843 -0
- package/apps/octogent/apps/web/src/styles/console-canvas-code-intel.css +227 -0
- package/apps/octogent/apps/web/src/styles/console-canvas-conversations.css +705 -0
- package/apps/octogent/apps/web/src/styles/console-canvas-deck.css +1524 -0
- package/apps/octogent/apps/web/src/styles/console-canvas-github.css +541 -0
- package/apps/octogent/apps/web/src/styles/console-canvas-monitor.css +595 -0
- package/apps/octogent/apps/web/src/styles/console-canvas-pixpack.css +81 -0
- package/apps/octogent/apps/web/src/styles/console-canvas-prompts.css +474 -0
- package/apps/octogent/apps/web/src/styles/console-canvas-settings.css +207 -0
- package/apps/octogent/apps/web/src/styles/console-chrome-status-nav.css +441 -0
- package/apps/octogent/apps/web/src/styles/console-overrides-telemetry.css +320 -0
- package/apps/octogent/apps/web/src/styles/console-theme-tokens.css +25 -0
- package/apps/octogent/apps/web/src/styles/cortex-theme.css +412 -0
- package/apps/octogent/apps/web/src/styles/foundation.css +100 -0
- package/apps/octogent/apps/web/src/styles/sidebar-and-scrollbars.css +447 -0
- package/apps/octogent/apps/web/src/styles/terminal-and-status.css +356 -0
- package/apps/octogent/apps/web/src/styles.css +25 -0
- package/apps/octogent/apps/web/src/types/ws.d.ts +23 -0
- package/apps/octogent/apps/web/tests/CanvasPrimaryView.test.tsx +347 -0
- package/apps/octogent/apps/web/tests/HttpTerminalSnapshotReader.test.tsx +54 -0
- package/apps/octogent/apps/web/tests/RuntimeStatusStrip.test.tsx +70 -0
- package/apps/octogent/apps/web/tests/Terminal.test.tsx +87 -0
- package/apps/octogent/apps/web/tests/add-tentacle-form.test.tsx +48 -0
- package/apps/octogent/apps/web/tests/app-github-runtime.test.tsx +162 -0
- package/apps/octogent/apps/web/tests/app-monitor-runtime.test.tsx +657 -0
- package/apps/octogent/apps/web/tests/app-shell-navigation.test.tsx +109 -0
- package/apps/octogent/apps/web/tests/app-swarm-refresh.test.tsx +268 -0
- package/apps/octogent/apps/web/tests/app-ui-state-persistence.test.tsx +116 -0
- package/apps/octogent/apps/web/tests/app-workspace-setup.test.tsx +217 -0
- package/apps/octogent/apps/web/tests/canvas-tentacle-panel.test.tsx +195 -0
- package/apps/octogent/apps/web/tests/delete-all-terminals-dialog.test.tsx +76 -0
- package/apps/octogent/apps/web/tests/githubMetrics.test.tsx +52 -0
- package/apps/octogent/apps/web/tests/hotkeys.test.tsx +44 -0
- package/apps/octogent/apps/web/tests/runtimeEndpoints.test.tsx +240 -0
- package/apps/octogent/apps/web/tests/setup.ts +39 -0
- package/apps/octogent/apps/web/tests/tentacle-pod.test.tsx +62 -0
- package/apps/octogent/apps/web/tests/terminalReplay.test.ts +71 -0
- package/apps/octogent/apps/web/tests/terminalState.test.tsx +49 -0
- package/apps/octogent/apps/web/tests/terminalWheel.test.tsx +51 -0
- package/apps/octogent/apps/web/tests/test-utils/appTestHarness.ts +48 -0
- package/apps/octogent/apps/web/tests/uiPrimitives.test.tsx +31 -0
- package/apps/octogent/apps/web/tests/useAgentRuntimeStates.test.tsx +47 -0
- package/apps/octogent/apps/web/tsconfig.json +8 -0
- package/apps/octogent/apps/web/vite.api.bundle.config.mts +32 -0
- package/apps/octogent/apps/web/vite.config.ts +22 -0
- package/apps/octogent/bin/octogent +3 -0
- package/apps/octogent/biome.json +21 -0
- package/apps/octogent/docs/concepts/mental-model.md +79 -0
- package/apps/octogent/docs/concepts/runtime-and-api.md +60 -0
- package/apps/octogent/docs/concepts/tentacles.md +85 -0
- package/apps/octogent/docs/getting-started/installation.md +54 -0
- package/apps/octogent/docs/getting-started/quickstart.md +79 -0
- package/apps/octogent/docs/guides/inter-agent-messaging.md +43 -0
- package/apps/octogent/docs/guides/orchestrating-child-agents.md +49 -0
- package/apps/octogent/docs/guides/working-with-todos.md +56 -0
- package/apps/octogent/docs/index.md +40 -0
- package/apps/octogent/docs/reference/api.md +103 -0
- package/apps/octogent/docs/reference/cli.md +71 -0
- package/apps/octogent/docs/reference/experimental-features.md +28 -0
- package/apps/octogent/docs/reference/filesystem-layout.md +62 -0
- package/apps/octogent/docs/reference/troubleshooting.md +49 -0
- package/apps/octogent/package.json +35 -0
- package/apps/octogent/packages/core/AGENTS.md +31 -0
- package/apps/octogent/packages/core/package.json +12 -0
- package/apps/octogent/packages/core/src/adapters/InMemoryTerminalSnapshotReader.ts +10 -0
- package/apps/octogent/packages/core/src/application/buildTerminalList.ts +13 -0
- package/apps/octogent/packages/core/src/domain/agentRuntime.ts +18 -0
- package/apps/octogent/packages/core/src/domain/channel.ts +8 -0
- package/apps/octogent/packages/core/src/domain/completionSound.ts +14 -0
- package/apps/octogent/packages/core/src/domain/conversation.ts +48 -0
- package/apps/octogent/packages/core/src/domain/deck.ts +33 -0
- package/apps/octogent/packages/core/src/domain/git.ts +32 -0
- package/apps/octogent/packages/core/src/domain/monitor.ts +62 -0
- package/apps/octogent/packages/core/src/domain/setup.ts +27 -0
- package/apps/octogent/packages/core/src/domain/terminal.ts +17 -0
- package/apps/octogent/packages/core/src/domain/uiState.ts +22 -0
- package/apps/octogent/packages/core/src/domain/usage.ts +60 -0
- package/apps/octogent/packages/core/src/index.ts +15 -0
- package/apps/octogent/packages/core/src/ports/TerminalSnapshotReader.ts +5 -0
- package/apps/octogent/packages/core/src/util/typeCoercion.ts +20 -0
- package/apps/octogent/packages/core/tests/buildTerminalList.test.ts +75 -0
- package/apps/octogent/packages/core/tsconfig.json +7 -0
- package/apps/octogent/packages/core/tsconfig.tsbuildinfo +1 -0
- package/apps/octogent/packages/core/vitest.config.ts +7 -0
- package/apps/octogent/pnpm-lock.yaml +3212 -0
- package/apps/octogent/pnpm-workspace.yaml +3 -0
- package/apps/octogent/prompts/meta-prompt-generator.md +223 -0
- package/apps/octogent/prompts/octoboss-clean-contexts.md +30 -0
- package/apps/octogent/prompts/octoboss-reorganize-tentacles.md +29 -0
- package/apps/octogent/prompts/octoboss-reorganize-todos.md +27 -0
- package/apps/octogent/prompts/sandbox-init.md +3 -0
- package/apps/octogent/prompts/swarm-parent.md +83 -0
- package/apps/octogent/prompts/swarm-worker.md +50 -0
- package/apps/octogent/prompts/tentacle-context-init.md +1 -0
- package/apps/octogent/prompts/tentacle-planner.md +110 -0
- package/apps/octogent/prompts/tentacle-reorganize-todos.md +20 -0
- package/apps/octogent/prompts/tentacle-update-tentacle.md +18 -0
- package/apps/octogent/scripts/build-package.mjs +23 -0
- package/apps/octogent/scripts/dev.mjs +158 -0
- package/apps/octogent/scripts/smoke-public-install.mjs +271 -0
- package/apps/octogent/static/images/octogent-header.png +0 -0
- package/apps/octogent/static/images/preview_1.jpg +0 -0
- package/apps/octogent/static/images/preview_2.jpg +0 -0
- package/apps/octogent/static/images/preview_3.jpg +0 -0
- package/apps/octogent/static/images/preview_4.jpg +0 -0
- package/apps/octogent/static/images/preview_5.jpg +0 -0
- package/apps/octogent/static/images/preview_6.jpg +0 -0
- package/apps/octogent/tsconfig.base.json +16 -0
- package/bin/AGI +3 -0
- package/bin/AGI-install-app +71 -0
- package/bin/AGI-ui +16 -0
- package/bin/AGI-voice +15 -0
- package/bin/AGI-web +16 -0
- package/bin/cortex +109 -0
- package/bin/cortex-octogent +99 -0
- package/bin/import-specifier.mjs +13 -0
- package/bin/import-specifier.test.mjs +13 -0
- package/bin/octo +150 -0
- package/dist/cli.mjs +555650 -0
- package/package.json +157 -0
- package/scripts/setup-wizard.ts +390 -0
package/package.json
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gokulvenkatareddy/cortex",
|
|
3
|
+
"version": "0.1.7",
|
|
4
|
+
"description": "CORTEX — Autonomous AGI Terminal. Any LLM, one command. NVIDIA, OpenAI, Gemini, Groq, Ollama and more.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"cortex": "./bin/cortex",
|
|
8
|
+
"cortex-setup": "./bin/cortex",
|
|
9
|
+
"cortex-octogent": "./bin/cortex-octogent",
|
|
10
|
+
"octo": "./bin/octo"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"bin/",
|
|
14
|
+
"dist/cli.mjs",
|
|
15
|
+
"scripts/setup-wizard.ts",
|
|
16
|
+
"apps/octogent/",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"setup": "bun run scripts/setup-wizard.ts",
|
|
21
|
+
"build": "bun run scripts/build.ts",
|
|
22
|
+
"dev": "bun run build && node dist/cli.mjs",
|
|
23
|
+
"dev:profile": "bun run scripts/provider-launch.ts",
|
|
24
|
+
"dev:profile:fast": "bun run scripts/provider-launch.ts auto --fast --bare",
|
|
25
|
+
"dev:codex": "bun run scripts/provider-launch.ts codex",
|
|
26
|
+
"dev:openai": "bun run scripts/provider-launch.ts openai",
|
|
27
|
+
"dev:gemini": "bun run scripts/provider-launch.ts gemini",
|
|
28
|
+
"dev:ollama": "bun run scripts/provider-launch.ts ollama",
|
|
29
|
+
"dev:ollama:fast": "bun run scripts/provider-launch.ts ollama --fast --bare",
|
|
30
|
+
"dev:atomic-chat": "bun run scripts/provider-launch.ts atomic-chat",
|
|
31
|
+
"profile:init": "bun run scripts/provider-bootstrap.ts",
|
|
32
|
+
"profile:recommend": "bun run scripts/provider-recommend.ts",
|
|
33
|
+
"profile:auto": "bun run scripts/provider-recommend.ts --apply",
|
|
34
|
+
"profile:codex": "bun run profile:init -- --provider codex --model codexplan",
|
|
35
|
+
"profile:fast": "bun run profile:init -- --provider ollama --model llama3.2:3b",
|
|
36
|
+
"profile:code": "bun run profile:init -- --provider ollama --model qwen2.5-coder:7b",
|
|
37
|
+
"dev:fast": "bun run profile:fast && bun run dev:ollama:fast",
|
|
38
|
+
"dev:code": "bun run profile:code && bun run dev:profile",
|
|
39
|
+
"start": "node dist/cli.mjs",
|
|
40
|
+
"test": "bun test",
|
|
41
|
+
"test:coverage": "bun test --coverage --coverage-reporter=lcov --coverage-dir=coverage --max-concurrency=1 && bun run scripts/render-coverage-heatmap.ts",
|
|
42
|
+
"test:coverage:ui": "bun run scripts/render-coverage-heatmap.ts",
|
|
43
|
+
"security:pr-scan": "bun run scripts/pr-intent-scan.ts",
|
|
44
|
+
"test:provider-recommendation": "bun test src/utils/providerRecommendation.test.ts src/utils/providerProfile.test.ts",
|
|
45
|
+
"typecheck": "tsc --noEmit",
|
|
46
|
+
"smoke": "bun run build && node dist/cli.mjs --version",
|
|
47
|
+
"verify:privacy": "bun run scripts/verify-no-phone-home.ts",
|
|
48
|
+
"build:verified": "bun run build && bun run verify:privacy",
|
|
49
|
+
"test:provider": "bun test src/services/api/*.test.ts src/utils/context.test.ts",
|
|
50
|
+
"doctor:runtime": "bun run scripts/system-check.ts",
|
|
51
|
+
"doctor:runtime:json": "bun run scripts/system-check.ts --json",
|
|
52
|
+
"doctor:report": "bun run scripts/system-check.ts --out reports/doctor-runtime.json",
|
|
53
|
+
"hardening:check": "bun run smoke && bun run doctor:runtime",
|
|
54
|
+
"hardening:strict": "bun run typecheck && bun run hardening:check",
|
|
55
|
+
"prepack": "npm run build && cd apps/octogent && pnpm install && pnpm build"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@alcalzone/ansi-tokenize": "0.3.0",
|
|
59
|
+
"@anthropic-ai/sandbox-runtime": "0.0.46",
|
|
60
|
+
"@commander-js/extra-typings": "12.1.0",
|
|
61
|
+
"@growthbook/growthbook": "1.6.5",
|
|
62
|
+
"@inquirer/prompts": "^8.4.0",
|
|
63
|
+
"@mendable/firecrawl-js": "4.18.1",
|
|
64
|
+
"@modelcontextprotocol/sdk": "1.29.0",
|
|
65
|
+
"@opentelemetry/api": "1.9.1",
|
|
66
|
+
"@opentelemetry/api-logs": "0.214.0",
|
|
67
|
+
"@opentelemetry/core": "2.6.1",
|
|
68
|
+
"@opentelemetry/exporter-logs-otlp-http": "0.214.0",
|
|
69
|
+
"@opentelemetry/exporter-trace-otlp-grpc": "0.57.2",
|
|
70
|
+
"@opentelemetry/resources": "2.6.1",
|
|
71
|
+
"@opentelemetry/sdk-logs": "0.214.0",
|
|
72
|
+
"@opentelemetry/sdk-metrics": "2.6.1",
|
|
73
|
+
"@opentelemetry/sdk-trace-base": "2.6.1",
|
|
74
|
+
"@opentelemetry/sdk-trace-node": "2.6.1",
|
|
75
|
+
"@opentelemetry/semantic-conventions": "1.40.0",
|
|
76
|
+
"ajv": "8.18.0",
|
|
77
|
+
"auto-bind": "5.0.1",
|
|
78
|
+
"axios": "1.14.0",
|
|
79
|
+
"bidi-js": "1.0.3",
|
|
80
|
+
"chalk": "5.6.2",
|
|
81
|
+
"chokidar": "4.0.3",
|
|
82
|
+
"cli-boxes": "3.0.0",
|
|
83
|
+
"cli-highlight": "2.1.11",
|
|
84
|
+
"code-excerpt": "4.0.0",
|
|
85
|
+
"commander": "12.1.0",
|
|
86
|
+
"cross-spawn": "7.0.6",
|
|
87
|
+
"diff": "8.0.3",
|
|
88
|
+
"duck-duck-scrape": "^2.2.7",
|
|
89
|
+
"emoji-regex": "10.6.0",
|
|
90
|
+
"env-paths": "3.0.0",
|
|
91
|
+
"execa": "9.6.1",
|
|
92
|
+
"fflate": "0.8.2",
|
|
93
|
+
"figures": "6.1.0",
|
|
94
|
+
"fuse.js": "7.1.0",
|
|
95
|
+
"get-east-asian-width": "1.5.0",
|
|
96
|
+
"google-auth-library": "9.15.1",
|
|
97
|
+
"https-proxy-agent": "7.0.6",
|
|
98
|
+
"ignore": "7.0.5",
|
|
99
|
+
"indent-string": "5.0.0",
|
|
100
|
+
"jsonc-parser": "3.3.1",
|
|
101
|
+
"lodash-es": "4.18.0",
|
|
102
|
+
"lru-cache": "11.2.7",
|
|
103
|
+
"marked": "15.0.12",
|
|
104
|
+
"p-map": "7.0.4",
|
|
105
|
+
"picomatch": "4.0.4",
|
|
106
|
+
"proper-lockfile": "4.1.2",
|
|
107
|
+
"qrcode": "1.5.4",
|
|
108
|
+
"react": "19.2.4",
|
|
109
|
+
"react-compiler-runtime": "1.0.0",
|
|
110
|
+
"react-reconciler": "0.33.0",
|
|
111
|
+
"semver": "7.7.4",
|
|
112
|
+
"sharp": "^0.34.5",
|
|
113
|
+
"shell-quote": "1.8.3",
|
|
114
|
+
"signal-exit": "4.1.0",
|
|
115
|
+
"stack-utils": "2.0.6",
|
|
116
|
+
"strip-ansi": "7.2.0",
|
|
117
|
+
"supports-hyperlinks": "3.2.0",
|
|
118
|
+
"tree-kill": "1.2.2",
|
|
119
|
+
"turndown": "7.2.2",
|
|
120
|
+
"type-fest": "4.41.0",
|
|
121
|
+
"undici": "7.24.6",
|
|
122
|
+
"usehooks-ts": "3.1.1",
|
|
123
|
+
"vscode-languageserver-protocol": "3.17.5",
|
|
124
|
+
"wrap-ansi": "9.0.2",
|
|
125
|
+
"ws": "8.20.0",
|
|
126
|
+
"xss": "1.0.15",
|
|
127
|
+
"yaml": "2.8.3",
|
|
128
|
+
"zod": "3.25.76"
|
|
129
|
+
},
|
|
130
|
+
"devDependencies": {
|
|
131
|
+
"@types/bun": "1.3.11",
|
|
132
|
+
"@types/node": "25.5.0",
|
|
133
|
+
"@types/react": "19.2.14",
|
|
134
|
+
"typescript": "5.9.3"
|
|
135
|
+
},
|
|
136
|
+
"engines": {
|
|
137
|
+
"node": ">=20.0.0"
|
|
138
|
+
},
|
|
139
|
+
"repository": {
|
|
140
|
+
"type": "git",
|
|
141
|
+
"url": "https://gitlawb.com/z6MkqDnb7Siv3Cwj7pGJq4T5EsUisECqR8KpnDLwcaZq5TPr/cortex"
|
|
142
|
+
},
|
|
143
|
+
"keywords": [
|
|
144
|
+
"cortex-code",
|
|
145
|
+
"openai",
|
|
146
|
+
"llm",
|
|
147
|
+
"cli",
|
|
148
|
+
"agent",
|
|
149
|
+
"deepseek",
|
|
150
|
+
"ollama",
|
|
151
|
+
"gemini"
|
|
152
|
+
],
|
|
153
|
+
"license": "SEE LICENSE FILE",
|
|
154
|
+
"publishConfig": {
|
|
155
|
+
"access": "public"
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
/**
|
|
4
|
+
* CORTEX Setup Wizard — works when installed globally via npm
|
|
5
|
+
* Stores ALL config in ~/.cortex/ (user's home dir, not the npm package)
|
|
6
|
+
* So API keys are saved on the user's own machine, never in the repo.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import * as fs from 'fs'
|
|
10
|
+
import * as path from 'path'
|
|
11
|
+
import * as os from 'os'
|
|
12
|
+
import * as readline from 'readline'
|
|
13
|
+
import { spawn } from 'child_process'
|
|
14
|
+
import { fileURLToPath } from 'url'
|
|
15
|
+
|
|
16
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
17
|
+
|
|
18
|
+
// ─── User config dir: ~/.cortex/ ─────────────────────────────────────────────
|
|
19
|
+
// This is where ALL user data lives — API keys, profile, settings.
|
|
20
|
+
// It's on the user's machine, NOT in the npm package folder.
|
|
21
|
+
const CONFIG_DIR = path.join(os.homedir(), '.cortex')
|
|
22
|
+
const CONFIG_ENV = path.join(CONFIG_DIR, '.env')
|
|
23
|
+
const CONFIG_JSON = path.join(CONFIG_DIR, 'profile.json')
|
|
24
|
+
|
|
25
|
+
// ─── ANSI Colors ─────────────────────────────────────────────────────────────
|
|
26
|
+
const C = {
|
|
27
|
+
reset: '\x1b[0m',
|
|
28
|
+
bold: '\x1b[1m',
|
|
29
|
+
dim: '\x1b[2m',
|
|
30
|
+
green: '\x1b[32m',
|
|
31
|
+
cyan: '\x1b[36m',
|
|
32
|
+
yellow: '\x1b[33m',
|
|
33
|
+
red: '\x1b[31m',
|
|
34
|
+
white: '\x1b[97m',
|
|
35
|
+
magenta: '\x1b[35m',
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ─── Provider Catalog ────────────────────────────────────────────────────────
|
|
39
|
+
const PROVIDERS = [
|
|
40
|
+
{
|
|
41
|
+
id: 'nvidia',
|
|
42
|
+
name: '🟢 NVIDIA NIM',
|
|
43
|
+
desc: 'DeepSeek, Mistral, Kimi, Qwen, Nemotron & 20+ more',
|
|
44
|
+
keyName: 'NVIDIA_API_KEY',
|
|
45
|
+
keyUrl: 'https://build.nvidia.com → "Get API Key" (free)',
|
|
46
|
+
baseUrl: 'https://integrate.api.nvidia.com/v1',
|
|
47
|
+
models: [
|
|
48
|
+
{ id: 'deepseek-ai/deepseek-v4-pro', name: 'DeepSeek V4 Pro · flagship reasoning' },
|
|
49
|
+
{ id: 'deepseek-ai/deepseek-v4-flash', name: 'DeepSeek V4 Flash · fast, low rate-limits' },
|
|
50
|
+
{ id: 'mistralai/devstral-2-123b-instruct-2512', name: 'Devstral 2 123B · coding specialist' },
|
|
51
|
+
{ id: 'mistralai/mistral-large-3-675b-instruct-2512', name: 'Mistral Large 3 675B · most powerful Mistral' },
|
|
52
|
+
{ id: 'moonshotai/kimi-k2.6', name: 'Kimi K2.6 · multimodal all-rounder'},
|
|
53
|
+
{ id: 'qwen/qwen3-coder-480b-a35b-instruct', name: 'Qwen3 Coder 480B · massive code model' },
|
|
54
|
+
{ id: 'nvidia/nemotron-3-super-120b-a12b', name: 'Nemotron 3 Super 120B · NVIDIA flagship' },
|
|
55
|
+
{ id: 'minimaxai/minimax-m2.7', name: 'MiniMax M2.7 · fast coding' },
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: 'openai',
|
|
60
|
+
name: '⚡ OpenAI',
|
|
61
|
+
desc: 'GPT-4o, GPT-4.1, o3, o4-mini',
|
|
62
|
+
keyName: 'OPENAI_API_KEY',
|
|
63
|
+
keyUrl: 'https://platform.openai.com/api-keys',
|
|
64
|
+
baseUrl: 'https://api.openai.com/v1',
|
|
65
|
+
models: [
|
|
66
|
+
{ id: 'gpt-4o', name: 'GPT-4o · best all-rounder' },
|
|
67
|
+
{ id: 'gpt-4.1', name: 'GPT-4.1 · latest flagship' },
|
|
68
|
+
{ id: 'o4-mini', name: 'o4-mini · fast reasoning' },
|
|
69
|
+
{ id: 'o3', name: 'o3 · deep reasoning' },
|
|
70
|
+
{ id: 'gpt-4o-mini', name: 'GPT-4o Mini · cheap & fast' },
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: 'gemini',
|
|
75
|
+
name: '✨ Google Gemini',
|
|
76
|
+
desc: 'Gemini 2.0 Flash, Gemini 2.5 Pro',
|
|
77
|
+
keyName: 'GEMINI_API_KEY',
|
|
78
|
+
keyUrl: 'https://aistudio.google.com/apikey (free)',
|
|
79
|
+
baseUrl: null,
|
|
80
|
+
models: [
|
|
81
|
+
{ id: 'gemini-2.0-flash', name: 'Gemini 2.0 Flash · fast & capable' },
|
|
82
|
+
{ id: 'gemini-2.5-pro', name: 'Gemini 2.5 Pro · most capable' },
|
|
83
|
+
{ id: 'gemini-1.5-pro', name: 'Gemini 1.5 Pro · 1M context' },
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: 'groq',
|
|
88
|
+
name: '🚀 Groq',
|
|
89
|
+
desc: 'Ultra-fast inference — Llama, Mistral, Gemma',
|
|
90
|
+
keyName: 'GROQ_API_KEY',
|
|
91
|
+
keyUrl: 'https://console.groq.com/keys (free)',
|
|
92
|
+
baseUrl: 'https://api.groq.com/openai/v1',
|
|
93
|
+
models: [
|
|
94
|
+
{ id: 'llama-3.3-70b-versatile', name: 'Llama 3.3 70B · fast & capable' },
|
|
95
|
+
{ id: 'llama3-70b-8192', name: 'Llama3 70B · 8K context' },
|
|
96
|
+
{ id: 'mixtral-8x7b-32768', name: 'Mixtral 8x7B · 32K context' },
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: 'huggingface',
|
|
101
|
+
name: '🤗 HuggingFace',
|
|
102
|
+
desc: '500+ open source models via HF Inference Router',
|
|
103
|
+
keyName: 'HUGGINGFACE_API_KEY',
|
|
104
|
+
keyUrl: 'https://huggingface.co/settings/tokens (free)',
|
|
105
|
+
baseUrl: 'https://router.huggingface.co/v1',
|
|
106
|
+
models: [
|
|
107
|
+
{ id: 'Qwen/Qwen2.5-Coder-32B-Instruct', name: 'Qwen2.5 Coder 32B · coding' },
|
|
108
|
+
{ id: 'meta-llama/Llama-3.3-70B-Instruct', name: 'Llama 3.3 70B · general' },
|
|
109
|
+
{ id: 'mistralai/Mistral-7B-Instruct-v0.3', name: 'Mistral 7B · fast' },
|
|
110
|
+
],
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: 'openrouter',
|
|
114
|
+
name: '🔀 OpenRouter',
|
|
115
|
+
desc: '100+ models (Claude, GPT-4, Gemini) with one key',
|
|
116
|
+
keyName: 'OPENAI_API_KEY',
|
|
117
|
+
keyUrl: 'https://openrouter.ai/keys',
|
|
118
|
+
baseUrl: 'https://openrouter.ai/api/v1',
|
|
119
|
+
models: [
|
|
120
|
+
{ id: 'anthropic/claude-opus-4', name: 'Claude Opus 4 · most capable' },
|
|
121
|
+
{ id: 'google/gemini-2.0-flash-001', name: 'Gemini 2.0 Flash · fast' },
|
|
122
|
+
{ id: 'openai/gpt-4o', name: 'GPT-4o · balanced' },
|
|
123
|
+
{ id: 'meta-llama/llama-3.3-70b', name: 'Llama 3.3 70B · open source' },
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
id: 'ollama',
|
|
128
|
+
name: '🏠 Ollama (Local)',
|
|
129
|
+
desc: '100% private — runs on your machine, no API key',
|
|
130
|
+
keyName: null,
|
|
131
|
+
keyUrl: 'https://ollama.com → install, then: ollama pull llama3.2',
|
|
132
|
+
baseUrl: 'http://localhost:11434/v1',
|
|
133
|
+
models: [
|
|
134
|
+
{ id: 'llama3.2', name: 'Llama 3.2 · general purpose' },
|
|
135
|
+
{ id: 'qwen2.5-coder', name: 'Qwen2.5 Coder · coding focused' },
|
|
136
|
+
{ id: 'mistral', name: 'Mistral 7B · fast' },
|
|
137
|
+
{ id: 'codellama', name: 'CodeLlama · code completion' },
|
|
138
|
+
],
|
|
139
|
+
},
|
|
140
|
+
]
|
|
141
|
+
|
|
142
|
+
// ─── Terminal Helpers ─────────────────────────────────────────────────────────
|
|
143
|
+
function clear() { process.stdout.write('\x1bc') }
|
|
144
|
+
|
|
145
|
+
function banner() {
|
|
146
|
+
console.log()
|
|
147
|
+
console.log(`${C.bold}${C.cyan} ╔══════════════════════════════════════════════════════╗${C.reset}`)
|
|
148
|
+
console.log(`${C.bold}${C.cyan} ║ ${C.white}CORTEX${C.cyan} — Autonomous AGI Terminal ║${C.reset}`)
|
|
149
|
+
console.log(`${C.bold}${C.cyan} ║ ${C.dim}Any LLM · One command · Open source${C.cyan} ║${C.reset}`)
|
|
150
|
+
console.log(`${C.bold}${C.cyan} ╚══════════════════════════════════════════════════════╝${C.reset}`)
|
|
151
|
+
console.log()
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function ask(q: string): Promise<string> {
|
|
155
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
|
|
156
|
+
return new Promise(resolve => { rl.question(q, a => { rl.close(); resolve(a.trim()) }) })
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function askSecret(q: string): Promise<string> {
|
|
160
|
+
return new Promise(resolve => {
|
|
161
|
+
process.stdout.write(q)
|
|
162
|
+
let input = ''
|
|
163
|
+
process.stdin.setRawMode?.(true)
|
|
164
|
+
process.stdin.resume()
|
|
165
|
+
process.stdin.setEncoding('utf8')
|
|
166
|
+
const onData = (ch: string) => {
|
|
167
|
+
if (ch === '\r' || ch === '\n' || ch === '\u0004') {
|
|
168
|
+
process.stdin.removeListener('data', onData)
|
|
169
|
+
process.stdin.setRawMode?.(false)
|
|
170
|
+
process.stdout.write('\n')
|
|
171
|
+
resolve(input.trim())
|
|
172
|
+
} else if (ch === '\u0003') { process.exit() }
|
|
173
|
+
else if (ch === '\u007f') { if (input.length > 0) { input = input.slice(0,-1); process.stdout.write('\b \b') } }
|
|
174
|
+
else { input += ch; process.stdout.write('*') }
|
|
175
|
+
}
|
|
176
|
+
process.stdin.on('data', onData)
|
|
177
|
+
})
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async function pickNumber(q: string, max: number): Promise<number> {
|
|
181
|
+
while (true) {
|
|
182
|
+
const a = await ask(q)
|
|
183
|
+
const n = parseInt(a)
|
|
184
|
+
if (!isNaN(n) && n >= 1 && n <= max) return n - 1
|
|
185
|
+
console.log(`${C.red} ✗ Enter a number from 1 to ${max}${C.reset}`)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// ─── Config Persistence (in ~/.cortex/) ──────────────────────────────────────
|
|
190
|
+
function ensureConfigDir() {
|
|
191
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
192
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 }) // owner-only
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function readUserEnv(): Record<string, string> {
|
|
197
|
+
if (!fs.existsSync(CONFIG_ENV)) return {}
|
|
198
|
+
const lines = fs.readFileSync(CONFIG_ENV, 'utf8').split('\n')
|
|
199
|
+
const result: Record<string, string> = {}
|
|
200
|
+
for (const line of lines) {
|
|
201
|
+
const m = line.match(/^([A-Z_]+)=(.*)$/)
|
|
202
|
+
if (m) result[m[1]] = m[2]
|
|
203
|
+
}
|
|
204
|
+
return result
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function writeUserEnv(updates: Record<string, string>) {
|
|
208
|
+
ensureConfigDir()
|
|
209
|
+
const existing = readUserEnv()
|
|
210
|
+
const merged = { ...existing, ...updates }
|
|
211
|
+
// Remove empty values
|
|
212
|
+
const content = Object.entries(merged)
|
|
213
|
+
.filter(([, v]) => v && v.length > 0)
|
|
214
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
215
|
+
.join('\n')
|
|
216
|
+
fs.writeFileSync(CONFIG_ENV, content + '\n', { encoding: 'utf8', mode: 0o600 }) // owner read-write only
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function writeUserProfile(data: object) {
|
|
220
|
+
ensureConfigDir()
|
|
221
|
+
fs.writeFileSync(CONFIG_JSON, JSON.stringify(data, null, 2) + '\n', { encoding: 'utf8', mode: 0o600 })
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function readUserProfile(): Record<string, string> | null {
|
|
225
|
+
if (!fs.existsSync(CONFIG_JSON)) return null
|
|
226
|
+
try { return JSON.parse(fs.readFileSync(CONFIG_JSON, 'utf8')) } catch { return null }
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// ─── Main Wizard ──────────────────────────────────────────────────────────────
|
|
230
|
+
export async function runSetupWizard() {
|
|
231
|
+
clear()
|
|
232
|
+
banner()
|
|
233
|
+
|
|
234
|
+
console.log(`${C.bold}${C.white} Welcome to CORTEX! Let's get you set up.${C.reset}`)
|
|
235
|
+
console.log(`${C.dim} This runs once. After setup, just type ${C.bold}cortex${C.dim} to start.${C.reset}`)
|
|
236
|
+
console.log(`${C.dim} Your API keys are stored in ${C.bold}~/.cortex/.env${C.dim} (your machine only).${C.reset}`)
|
|
237
|
+
console.log()
|
|
238
|
+
|
|
239
|
+
// Check if already configured
|
|
240
|
+
const existingProfile = readUserProfile()
|
|
241
|
+
if (existingProfile?.provider) {
|
|
242
|
+
console.log(`${C.yellow} ⚡ Existing setup found: ${C.bold}${existingProfile.providerName}${C.yellow} · ${existingProfile.model}${C.reset}`)
|
|
243
|
+
const reconf = await ask(` Reconfigure? [y/N]: `)
|
|
244
|
+
if (reconf.toLowerCase() !== 'y') {
|
|
245
|
+
console.log(`\n${C.green} ✓ Using existing configuration. Launching CORTEX...\n${C.reset}`)
|
|
246
|
+
return readUserEnv()
|
|
247
|
+
}
|
|
248
|
+
console.log()
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// ── Step 1: Provider ────────────────────────────────────────────────────
|
|
252
|
+
console.log(`${C.bold}${C.yellow} Step 1 — Choose your AI provider:${C.reset}\n`)
|
|
253
|
+
PROVIDERS.forEach((p, i) => {
|
|
254
|
+
console.log(` ${C.bold}${C.cyan}${String(i + 1).padStart(2)}.${C.reset} ${C.bold}${p.name}${C.reset}`)
|
|
255
|
+
console.log(` ${C.dim}${p.desc}${C.reset}`)
|
|
256
|
+
})
|
|
257
|
+
console.log()
|
|
258
|
+
|
|
259
|
+
const pi = await pickNumber(` ${C.bold}Enter number [1-${PROVIDERS.length}]: ${C.reset}`, PROVIDERS.length)
|
|
260
|
+
const provider = PROVIDERS[pi]
|
|
261
|
+
|
|
262
|
+
clear(); banner()
|
|
263
|
+
console.log(` ${C.green}✓ Provider: ${C.bold}${provider.name}${C.reset}\n`)
|
|
264
|
+
|
|
265
|
+
// ── Step 2: API Key ─────────────────────────────────────────────────────
|
|
266
|
+
let apiKey = ''
|
|
267
|
+
const existingEnv = readUserEnv()
|
|
268
|
+
|
|
269
|
+
if (provider.keyName) {
|
|
270
|
+
const existingKey = existingEnv[provider.keyName] || process.env[provider.keyName] || ''
|
|
271
|
+
console.log(`${C.bold}${C.yellow} Step 2 — API Key:${C.reset}\n`)
|
|
272
|
+
console.log(` ${C.dim}Get your key here (it's free):${C.reset}`)
|
|
273
|
+
console.log(` ${C.bold}${C.cyan} ${provider.keyUrl}${C.reset}\n`)
|
|
274
|
+
|
|
275
|
+
if (existingKey && existingKey.length > 8) {
|
|
276
|
+
const masked = existingKey.slice(0, 6) + '****' + existingKey.slice(-4)
|
|
277
|
+
console.log(` ${C.dim}Found saved key: ${C.bold}${masked}${C.reset}`)
|
|
278
|
+
const use = await ask(` Use this key? [Y/n]: `)
|
|
279
|
+
if (use.toLowerCase() !== 'n') {
|
|
280
|
+
apiKey = existingKey
|
|
281
|
+
console.log(` ${C.green}✓ Using saved key${C.reset}`)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (!apiKey) {
|
|
286
|
+
apiKey = await askSecret(` ${C.bold}Paste your API key: ${C.reset}`)
|
|
287
|
+
if (!apiKey || apiKey.length < 8) {
|
|
288
|
+
console.log(`\n${C.red} ✗ Key too short. Run ${C.bold}cortex setup${C.reset}${C.red} to try again.${C.reset}\n`)
|
|
289
|
+
process.exit(1)
|
|
290
|
+
}
|
|
291
|
+
console.log(` ${C.green}✓ Key received!${C.reset}`)
|
|
292
|
+
}
|
|
293
|
+
} else {
|
|
294
|
+
console.log(`${C.bold}${C.yellow} Step 2 — API Key:${C.reset}\n`)
|
|
295
|
+
console.log(` ${C.green}✓ No key needed — Ollama runs locally on your machine!${C.reset}`)
|
|
296
|
+
console.log(` ${C.dim}Make sure Ollama is running: ${C.bold}ollama serve${C.reset}`)
|
|
297
|
+
await ask(`\n Press Enter to continue...`)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// ── Step 3: Model ───────────────────────────────────────────────────────
|
|
301
|
+
clear(); banner()
|
|
302
|
+
console.log(` ${C.green}✓ Provider: ${C.bold}${provider.name}${C.reset}`)
|
|
303
|
+
if (apiKey) console.log(` ${C.green}✓ API Key: ${C.bold}****${apiKey.slice(-4)}${C.reset}`)
|
|
304
|
+
console.log()
|
|
305
|
+
console.log(`${C.bold}${C.yellow} Step 3 — Choose your starting model:${C.reset}`)
|
|
306
|
+
console.log(` ${C.dim}(Switch anytime with ${C.bold}/model${C.dim} inside CORTEX)${C.reset}\n`)
|
|
307
|
+
|
|
308
|
+
provider.models.forEach((m, i) => {
|
|
309
|
+
console.log(` ${C.bold}${C.cyan}${String(i + 1).padStart(2)}.${C.reset} ${C.dim}${m.name}${C.reset}`)
|
|
310
|
+
})
|
|
311
|
+
console.log()
|
|
312
|
+
|
|
313
|
+
const mi = await pickNumber(` ${C.bold}Enter number [1-${provider.models.length}]: ${C.reset}`, provider.models.length)
|
|
314
|
+
const model = provider.models[mi]
|
|
315
|
+
|
|
316
|
+
// ── Build env vars ──────────────────────────────────────────────────────
|
|
317
|
+
clear(); banner()
|
|
318
|
+
console.log(`${C.bold}${C.white} Saving your configuration to ~/.cortex/ ...${C.reset}\n`)
|
|
319
|
+
|
|
320
|
+
const envUpdates: Record<string, string> = {
|
|
321
|
+
CORTEX_PROVIDER: provider.id,
|
|
322
|
+
CORTEX_NVIDIA_ONLY: provider.id === 'nvidia' ? '1' : '0',
|
|
323
|
+
OPENAI_MODEL: model.id,
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
if (provider.baseUrl) {
|
|
327
|
+
envUpdates['OPENAI_BASE_URL'] = provider.baseUrl
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (provider.id === 'nvidia') {
|
|
331
|
+
envUpdates['NVIDIA_API_KEY'] = apiKey
|
|
332
|
+
envUpdates['NVIDIA_MODEL_ID'] = model.id
|
|
333
|
+
envUpdates['NVIDIA_BASE_URL'] = provider.baseUrl!
|
|
334
|
+
envUpdates['OPENAI_API_KEY'] = apiKey
|
|
335
|
+
} else if (provider.id === 'openai') {
|
|
336
|
+
envUpdates['OPENAI_API_KEY'] = apiKey
|
|
337
|
+
} else if (provider.id === 'gemini') {
|
|
338
|
+
envUpdates['GEMINI_API_KEY'] = apiKey
|
|
339
|
+
// Gemini uses its own provider path
|
|
340
|
+
} else if (provider.id === 'groq') {
|
|
341
|
+
envUpdates['GROQ_API_KEY'] = apiKey
|
|
342
|
+
envUpdates['OPENAI_API_KEY'] = apiKey
|
|
343
|
+
} else if (provider.id === 'huggingface') {
|
|
344
|
+
envUpdates['HUGGINGFACE_API_KEY'] = apiKey
|
|
345
|
+
envUpdates['OPENAI_API_KEY'] = apiKey
|
|
346
|
+
} else if (provider.id === 'openrouter') {
|
|
347
|
+
envUpdates['OPENAI_API_KEY'] = apiKey
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Save to ~/.cortex/.env
|
|
351
|
+
writeUserEnv(envUpdates)
|
|
352
|
+
|
|
353
|
+
// Save profile metadata (no keys)
|
|
354
|
+
writeUserProfile({
|
|
355
|
+
provider: provider.id,
|
|
356
|
+
providerName: provider.name,
|
|
357
|
+
model: model.id,
|
|
358
|
+
modelName: model.name,
|
|
359
|
+
configuredAt: new Date().toISOString(),
|
|
360
|
+
})
|
|
361
|
+
|
|
362
|
+
console.log(` ${C.green}✓ Config saved to ${C.bold}~/.cortex/.env${C.reset}`)
|
|
363
|
+
console.log(` ${C.green}✓ Provider: ${C.bold}${provider.name}${C.reset}`)
|
|
364
|
+
console.log(` ${C.green}✓ Model: ${C.bold}${model.id}${C.reset}\n`)
|
|
365
|
+
|
|
366
|
+
console.log(`${C.bold}${C.green} ╔═══════════════════════════════════════╗${C.reset}`)
|
|
367
|
+
console.log(`${C.bold}${C.green} ║ 🎉 CORTEX is ready! ║${C.reset}`)
|
|
368
|
+
console.log(`${C.bold}${C.green} ╚═══════════════════════════════════════╝${C.reset}\n`)
|
|
369
|
+
console.log(` ${C.dim}Tip: Inside CORTEX, type ${C.bold}/model${C.dim} to switch models.${C.reset}`)
|
|
370
|
+
console.log(` ${C.dim}Tip: Type ${C.bold}cortex setup${C.dim} to switch providers anytime.${C.reset}\n`)
|
|
371
|
+
|
|
372
|
+
return { ...readUserEnv(), ...envUpdates }
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Export config loader for the main CLI to use
|
|
376
|
+
export function loadUserConfig(): Record<string, string> {
|
|
377
|
+
return readUserEnv()
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export function isConfigured(): boolean {
|
|
381
|
+
const env = readUserEnv()
|
|
382
|
+
return !!(
|
|
383
|
+
env['NVIDIA_API_KEY'] ||
|
|
384
|
+
env['OPENAI_API_KEY'] ||
|
|
385
|
+
env['GEMINI_API_KEY'] ||
|
|
386
|
+
env['GROQ_API_KEY'] ||
|
|
387
|
+
env['HUGGINGFACE_API_KEY'] ||
|
|
388
|
+
env['CORTEX_PROVIDER'] === 'ollama'
|
|
389
|
+
)
|
|
390
|
+
}
|