* chore: remove legacy orchestrator, trading and one-off script leftovers The repository still carried the pre-evOo prototype: a Python orchestrator, the old HTML "evoo-platform" cockpit (whose test ran in the root unit suite), an apex-trading package, the hot-reload deploy.sh for it, a permissions manifest, an architecture note with local file links, agent handoff notes, a Steve Jobs persona template and about ninety one-off scripts that probe a developer database with hard-coded local URLs. None of it is used by the product, CI or the real deploy in ops/evo-deploy. Delete those files, drop the evoo-platform test glob from the root vitest config, the Cockpit section from .env.example and the dead biome and gitignore entries, and update the docs that listed the removed tools. scripts/start-tmux.sh no longer starts the removed sentinel and resolves the checkout from its own location instead of a machine-specific path; scripts/seed-ollama.ts requires DATABASE_URL instead of falling back to a local URL with a username. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MRtGG9ARfqqhma3t85Ro2u * fix(web): drop trading and persona prompts from the conversation shell The web shell still showed leftovers from the trading prototype: composer chips with German trading and "Steve Jobs" prompts, trading suggestion chips under the empty conversation line, a German trading hero for the empty transcript, and a German "data protection" status panel in the sidebar. They suggested actions the product does not have and added persistent chrome. Remove the composer chips and their helper, the empty-state chips and the hero (the empty conversation keeps its existing one-line start hint), the sidebar trading indicator and the data trust panel. The new-bot E2E now asserts the plain empty state; the sidebar spec no longer expects the trading status, and the placeholder Steve Jobs spec with no assertions is gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MRtGG9ARfqqhma3t85Ro2u Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * refactor: remove the trading bot status integration With the sidebar trading indicator gone, the only remaining consumer of the trading bot status was a banner in General settings that reused the same component. evOo is a personal assistant; a status proxy and poller for one external trading service, configured through service-specific TRADING_BOT_URL and VITE_TRADING_BOT_URL variables, does not belong in the core product. Remove the settings banner and its prop plumbing, the web poller, the indicator component, the /api/trading-bot/status proxy, the shared core contract, the env loading and both variables from .env.example, together with their tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MRtGG9ARfqqhma3t85Ro2u * chore: remove one-off database scripts and a stale review note packages/db carried four hand-run scripts outside the package build that query or seed a developer database with a hard-coded connection string, one of them for a specific account. docs/VOICE-FIRST-REVIEW.md was a one-time verification note for a workflow that no longer exists and named private machines and local paths. Nothing references them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MRtGG9ARfqqhma3t85Ro2u * chore: replace machine-specific paths and addresses with placeholders ORIGIN.md pinned the intended checkout to an absolute path under a personal home directory, docs/LOCAL-SETUP.md listed folders on one developer's machine, and two tests used what looks like a real tailnet address. Use a home-relative path, drop the machine-specific folder list, and use 100.100.100.100 in the tests; it is still inside 100.64.0.0/10, so both tests check the same thing as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MRtGG9ARfqqhma3t85Ro2u * test(web): drop the trading status from the shell contrast test main's contrast test now waits for the sidebar trading status before measuring; this branch removes that status. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MRtGG9ARfqqhma3t85Ro2u --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>
195 lines
8.1 KiB
TypeScript
195 lines
8.1 KiB
TypeScript
import {
|
|
resolveCloudAgentProvider,
|
|
resolveDeploymentModel,
|
|
resolveSandboxProvider,
|
|
} from "@rakazo/adapters";
|
|
import {
|
|
resolveAuthSecret,
|
|
resolveEncryptionKey,
|
|
resolveScreenProxySecret,
|
|
resolveSupervisorToken,
|
|
} from "@rakazo/core";
|
|
|
|
export { resolveCloudAgentProvider, resolveSandboxProvider } from "@rakazo/adapters";
|
|
|
|
export interface AppEnv {
|
|
nodeEnv: string;
|
|
desktopStackToken?: string;
|
|
databaseUrl: string;
|
|
realtimeDatabaseUrl: string;
|
|
authSecret: string;
|
|
authUrl: string;
|
|
webOrigin: string;
|
|
privacyPolicyUrl?: string;
|
|
apiUrl: string;
|
|
apiHost: string;
|
|
signupsEnabled: string | undefined;
|
|
signupAllowlist: string | undefined;
|
|
onboardingScanHome: string | undefined;
|
|
encryptionKey: string;
|
|
dataDir: string;
|
|
/** Opt-in Pi JSONL session recording under DATA_DIR/pi-sessions. Default off. */
|
|
piSessionRecording: boolean;
|
|
sandboxSupervisorUrl: string;
|
|
sandboxSupervisorToken: string | undefined;
|
|
screenProxySecret: string;
|
|
sandboxProvider: string;
|
|
cloudAgentProvider: string;
|
|
cloudAgentSpaceId: string | undefined;
|
|
cursorApiKey: string | undefined;
|
|
agentRuntime: string;
|
|
deploymentModelKey: string | undefined;
|
|
e2bApiKey: string | undefined;
|
|
daytonaApiKey: string | undefined;
|
|
daytonaApiUrl: string | undefined;
|
|
daytonaTarget: string | undefined;
|
|
boxApiKey: string | undefined;
|
|
boxApiUrl: string | undefined;
|
|
composioApiKey: string | undefined;
|
|
/** Optional integrations.sh-compatible catalog base URL. */
|
|
integrationsCatalogUrl: string | undefined;
|
|
pipedreamClientId: string | undefined;
|
|
pipedreamClientSecret: string | undefined;
|
|
pipedreamProjectId: string | undefined;
|
|
pipedreamEnvironment: "development" | "production";
|
|
sendblueApiKeyId: string | undefined;
|
|
sendblueApiSecret: string | undefined;
|
|
sendblueSigningSecret: string | undefined;
|
|
sendbluePhoneNumber: string | undefined;
|
|
smtpUrl: string | undefined;
|
|
emailFrom: string | undefined;
|
|
emailEmulator: boolean;
|
|
slackBotToken: string | undefined;
|
|
slackSigningSecret: string | undefined;
|
|
whatsappAccessToken: string | undefined;
|
|
whatsappPhoneNumberId: string | undefined;
|
|
whatsappAppSecret: string | undefined;
|
|
whatsappVerifyToken: string | undefined;
|
|
telegramBotToken: string | undefined;
|
|
telegramWebhookSecret: string | undefined;
|
|
larkAppId: string | undefined;
|
|
larkAppSecret: string | undefined;
|
|
larkVerificationToken: string | undefined;
|
|
larkEncryptKey: string | undefined;
|
|
larkDomain: string | undefined;
|
|
/** Unknown chat senders auto-provision their own accounts when true. */
|
|
messagingOpenSignup: boolean;
|
|
/** Bot that owns team/external chat rooms on the messaging surface. */
|
|
teamChatBotId: string | undefined;
|
|
/** Optional model override for ambient engagement judging. */
|
|
teamChatJudgeProvider: string | undefined;
|
|
teamChatJudgeModel: string | undefined;
|
|
defaultProvider: string;
|
|
defaultModel: string;
|
|
wakeupDriver: string;
|
|
mcpStdioEnabled: boolean;
|
|
mcpStdioAllowedCommands: string[];
|
|
port: number;
|
|
gitSha: string | undefined;
|
|
/** Private Compose control-network URL for the opt-in updater sidecar. */
|
|
updaterUrl: string | undefined;
|
|
/** Bearer shared with the updater; never sent to the browser. */
|
|
updaterToken: string | undefined;
|
|
/** Current application image tag; used for compose manual-upgrade command selection. */
|
|
imageTag: string | undefined;
|
|
}
|
|
|
|
export function loadEnv(source: NodeJS.ProcessEnv = process.env): AppEnv {
|
|
const authSecret = resolveAuthSecret(source);
|
|
const sandboxProvider = resolveSandboxProvider(source);
|
|
const cloudAgentProvider = resolveCloudAgentProvider(source);
|
|
const deploymentModel = resolveDeploymentModel(source);
|
|
const updaterUrl = optional(source.RAKAZO_UPDATER_URL);
|
|
const updaterToken = optional(source.RAKAZO_UPDATER_TOKEN);
|
|
return {
|
|
nodeEnv: source.NODE_ENV ?? "",
|
|
databaseUrl: required(source, "DATABASE_URL"),
|
|
realtimeDatabaseUrl: source.REALTIME_DATABASE_URL ?? required(source, "DATABASE_URL"),
|
|
desktopStackToken: optional(source.RAKAZO_DESKTOP_STACK_TOKEN),
|
|
authSecret,
|
|
authUrl: source.BETTER_AUTH_URL ?? source.WEB_ORIGIN ?? "http://127.0.0.1:5173",
|
|
webOrigin: source.WEB_ORIGIN ?? "http://127.0.0.1:5173",
|
|
privacyPolicyUrl: optional(source.PRIVACY_POLICY_URL),
|
|
apiUrl: source.API_URL ?? "http://127.0.0.1:3100",
|
|
apiHost: source.API_HOST ?? "127.0.0.1",
|
|
signupsEnabled: source.SIGNUPS_ENABLED,
|
|
signupAllowlist: source.SIGNUP_ALLOWLIST,
|
|
onboardingScanHome: optional(source.ONBOARDING_SCAN_HOME),
|
|
encryptionKey: resolveEncryptionKey(source),
|
|
dataDir: source.DATA_DIR ?? "./data",
|
|
piSessionRecording: source.PI_SESSION_RECORDING === "true",
|
|
sandboxSupervisorUrl: source.SANDBOX_SUPERVISOR_URL ?? "http://127.0.0.1:7091",
|
|
sandboxSupervisorToken:
|
|
sandboxProvider === "docker" ? resolveSupervisorToken(source) : undefined,
|
|
screenProxySecret: resolveScreenProxySecret(source),
|
|
sandboxProvider,
|
|
cloudAgentProvider,
|
|
cloudAgentSpaceId: optional(source.CLOUD_AGENT_SPACE_ID),
|
|
cursorApiKey: optional(source.CURSOR_API_KEY),
|
|
agentRuntime: source.AGENT_RUNTIME ?? "pi",
|
|
// Provider, model and key resolve together: see resolveDeploymentModel.
|
|
deploymentModelKey: deploymentModel.key,
|
|
e2bApiKey: source.E2B_API_KEY,
|
|
daytonaApiKey: source.DAYTONA_API_KEY,
|
|
daytonaApiUrl: source.DAYTONA_API_URL,
|
|
daytonaTarget: source.DAYTONA_TARGET,
|
|
boxApiKey: source.BOX_API_KEY,
|
|
boxApiUrl: source.BOX_API_URL ?? source.BOX_BASE_URL,
|
|
composioApiKey: source.COMPOSIO_API_KEY,
|
|
integrationsCatalogUrl: optional(source.INTEGRATIONS_CATALOG_URL),
|
|
pipedreamClientId: optional(source.PIPEDREAM_CLIENT_ID),
|
|
pipedreamClientSecret: optional(source.PIPEDREAM_CLIENT_SECRET),
|
|
pipedreamProjectId: optional(source.PIPEDREAM_PROJECT_ID),
|
|
pipedreamEnvironment:
|
|
source.PIPEDREAM_ENVIRONMENT === "production" ? "production" : "development",
|
|
sendblueApiKeyId: optional(source.SENDBLUE_API_KEY_ID),
|
|
sendblueApiSecret: optional(source.SENDBLUE_API_SECRET),
|
|
sendblueSigningSecret: optional(source.SENDBLUE_SIGNING_SECRET),
|
|
sendbluePhoneNumber: optional(source.SENDBLUE_PHONE_NUMBER),
|
|
smtpUrl: optional(source.SMTP_URL),
|
|
emailFrom: optional(source.EMAIL_FROM),
|
|
emailEmulator: source.EMAIL_EMULATOR === "true" && source.NODE_ENV !== "production",
|
|
slackBotToken: optional(source.SLACK_BOT_TOKEN),
|
|
slackSigningSecret: optional(source.SLACK_SIGNING_SECRET),
|
|
whatsappAccessToken: optional(source.WHATSAPP_ACCESS_TOKEN),
|
|
whatsappPhoneNumberId: optional(source.WHATSAPP_PHONE_NUMBER_ID),
|
|
whatsappAppSecret: optional(source.WHATSAPP_APP_SECRET),
|
|
whatsappVerifyToken: optional(source.WHATSAPP_VERIFY_TOKEN),
|
|
telegramBotToken: optional(source.TELEGRAM_BOT_TOKEN),
|
|
telegramWebhookSecret: optional(source.TELEGRAM_WEBHOOK_SECRET_TOKEN),
|
|
larkAppId: optional(source.LARK_APP_ID),
|
|
larkAppSecret: optional(source.LARK_APP_SECRET),
|
|
larkVerificationToken: optional(source.LARK_VERIFICATION_TOKEN),
|
|
larkEncryptKey: optional(source.LARK_ENCRYPT_KEY),
|
|
larkDomain: optional(source.LARK_DOMAIN),
|
|
messagingOpenSignup: source.MESSAGING_OPEN_SIGNUP === "true",
|
|
teamChatBotId: optional(source.TEAM_CHAT_BOT_ID) ?? optional(source.SLACK_RAKAZO_BOT_ID),
|
|
teamChatJudgeProvider: optional(source.TEAM_CHAT_JUDGE_PROVIDER),
|
|
teamChatJudgeModel: optional(source.TEAM_CHAT_JUDGE_MODEL),
|
|
defaultProvider: deploymentModel.provider,
|
|
defaultModel: deploymentModel.model,
|
|
wakeupDriver: source.WAKEUP_DRIVER ?? "graphile",
|
|
mcpStdioEnabled: source.MCP_STDIO_ENABLED === "true",
|
|
mcpStdioAllowedCommands: (source.MCP_STDIO_ALLOWED_COMMANDS ?? "")
|
|
.split(",")
|
|
.map((value) => value.trim())
|
|
.filter(Boolean),
|
|
port: Number(source.API_PORT ?? 3100),
|
|
gitSha: optional(source.GIT_SHA) ?? optional(source.RAKAZO_GIT_SHA),
|
|
updaterUrl,
|
|
updaterToken,
|
|
imageTag: optional(source.RAKAZO_IMAGE_TAG),
|
|
};
|
|
}
|
|
|
|
function required(source: NodeJS.ProcessEnv, key: string): string {
|
|
const value = source[key];
|
|
if (!value) throw new Error(`Missing ${key}`);
|
|
return value;
|
|
}
|
|
|
|
function optional(value: string | undefined): string | undefined {
|
|
const trimmed = value?.trim();
|
|
return trimmed || undefined;
|
|
}
|