├── docs
├── .nvmrc
├── src
│ ├── lib
│ │ ├── constants.ts
│ │ └── utils.ts
│ ├── app
│ │ ├── favicon.ico
│ │ ├── docs
│ │ │ ├── layout.tsx
│ │ │ └── [...slug]
│ │ │ │ ├── page.tsx
│ │ │ │ └── loading.tsx
│ │ ├── api
│ │ │ └── docs
│ │ │ │ ├── navigation
│ │ │ │ └── route.ts
│ │ │ │ ├── raw
│ │ │ │ ├── [...slug]
│ │ │ │ │ └── route.ts
│ │ │ │ └── route.ts
│ │ │ │ └── search
│ │ │ │ └── route.ts
│ │ └── layout.tsx
│ ├── components
│ │ ├── ui
│ │ │ ├── skeleton.tsx
│ │ │ ├── collapsible.tsx
│ │ │ ├── textarea.tsx
│ │ │ ├── label.tsx
│ │ │ ├── input.tsx
│ │ │ ├── separator.tsx
│ │ │ ├── progress.tsx
│ │ │ ├── slider.tsx
│ │ │ ├── switch.tsx
│ │ │ ├── badge.tsx
│ │ │ ├── tooltip.tsx
│ │ │ └── avatar.tsx
│ │ ├── theme-provider.tsx
│ │ └── mode-toggle.tsx
│ └── docs
│ │ ├── terminology
│ │ ├── index.md
│ │ └── backtesting.md
│ │ ├── the0-CLI
│ │ ├── index.md
│ │ └── installation.md
│ │ ├── index.md
│ │ └── custom-bot-development
│ │ └── index.md
├── public
│ ├── docs
│ │ ├── backtesting-1.png
│ │ ├── backtesting-2.png
│ │ └── test-doc-image.png
│ ├── vercel.svg
│ └── next.svg
├── postcss.config.js
├── postcss.config.mjs
├── next.config.mjs
├── components.json
├── tsconfig.json
└── README.md
├── services
├── 0vers33r
│ ├── src
│ │ ├── __init__.py
│ │ ├── common
│ │ │ ├── __init__.py
│ │ │ └── logging.py
│ │ ├── services
│ │ │ ├── __init__.py
│ │ │ ├── firestore_database.py
│ │ │ └── cloud_storage.py
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ └── test_samples
│ │ │ │ └── js_code_injection.js
│ │ └── interfaces
│ │ │ └── __init__.py
│ ├── .gitignore
│ └── Dockerfile
└── the0-ai
│ ├── api
│ ├── __init__.py
│ ├── models
│ │ └── __init__.py
│ └── schemas.py
│ ├── the0
│ ├── tools
│ │ └── __init__.py
│ ├── __init__.py
│ └── agents
│ │ ├── __init__.py
│ │ └── base.py
│ ├── tests
│ ├── api
│ │ └── __init__.py
│ ├── __init__.py
│ └── the0
│ │ ├── tools
│ │ └── __init__.py
│ │ └── __init__.py
│ ├── alembic
│ ├── README
│ └── script.py.mako
│ ├── .gitignore
│ ├── entrypoint.sh
│ ├── .env.example
│ ├── pytest.ini
│ └── Dockerfile
├── .gitignore
├── frontend
├── src
│ ├── lib
│ │ ├── constants.ts
│ │ ├── auth
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── utils.ts
│ │ ├── result.ts
│ │ ├── bot-type.ts
│ │ ├── config.ts
│ │ ├── axios.ts
│ │ ├── auth-fetch.ts
│ │ └── users.ts
│ ├── components
│ │ ├── spinner
│ │ │ ├── index.ts
│ │ │ └── Spinner.tsx
│ │ ├── plotting
│ │ │ └── index.ts
│ │ ├── dashboard
│ │ │ ├── index.ts
│ │ │ └── CustomTable.tsx
│ │ ├── trading-view
│ │ │ └── index.ts
│ │ ├── main-navigation
│ │ │ ├── index.ts
│ │ │ └── nav-item.tsx
│ │ ├── settings
│ │ │ ├── api-section.tsx
│ │ │ └── profile-section.tsx
│ │ ├── ui
│ │ │ ├── skeleton.tsx
│ │ │ ├── collapsible.tsx
│ │ │ ├── textarea.tsx
│ │ │ ├── label.tsx
│ │ │ ├── input.tsx
│ │ │ ├── separator.tsx
│ │ │ ├── progress.tsx
│ │ │ ├── toaster.tsx
│ │ │ ├── slider.tsx
│ │ │ ├── switch.tsx
│ │ │ ├── badge.tsx
│ │ │ ├── tooltip.tsx
│ │ │ └── avatar.tsx
│ │ ├── theme-provider.tsx
│ │ ├── ai-agent
│ │ │ ├── chat
│ │ │ │ ├── TypingIndicator.tsx
│ │ │ │ ├── ChatPanel.tsx
│ │ │ │ └── ChatInput.tsx
│ │ │ ├── ui
│ │ │ │ ├── label.tsx
│ │ │ │ ├── textarea.tsx
│ │ │ │ ├── separator.tsx
│ │ │ │ ├── input.tsx
│ │ │ │ ├── sonner.tsx
│ │ │ │ ├── slider.tsx
│ │ │ │ └── switch.tsx
│ │ │ ├── artifacts
│ │ │ │ └── FileTree.tsx
│ │ │ ├── layout
│ │ │ │ └── CollapsibleArtifactsPanel.tsx
│ │ │ └── common
│ │ │ │ └── ArtifactIndicator.tsx
│ │ ├── custom-bots
│ │ │ ├── status-badge.tsx
│ │ │ ├── loading-detail-state.tsx
│ │ │ ├── empty-state.tsx
│ │ │ ├── loading-state.tsx
│ │ │ └── status-header.tsx
│ │ ├── auth
│ │ │ └── with-auth.tsx
│ │ └── mode-toggle.tsx
│ ├── app
│ │ ├── favicon.ico
│ │ ├── providers.tsx
│ │ ├── settings
│ │ │ ├── profile
│ │ │ │ └── page.tsx
│ │ │ └── api-settings
│ │ │ │ └── page.tsx
│ │ ├── custom-bots
│ │ │ ├── page.tsx
│ │ │ ├── [name]
│ │ │ │ └── page.tsx
│ │ │ └── not-found.tsx
│ │ ├── page.tsx
│ │ ├── api
│ │ │ ├── ai-agent
│ │ │ │ ├── chat
│ │ │ │ │ ├── route.ts
│ │ │ │ │ └── stream
│ │ │ │ │ │ └── route.ts
│ │ │ │ ├── sessions
│ │ │ │ │ └── route.ts
│ │ │ │ └── artifacts
│ │ │ │ │ ├── route.ts
│ │ │ │ │ └── [filename]
│ │ │ │ │ └── route.ts
│ │ │ ├── custom-bots
│ │ │ │ └── route.ts
│ │ │ └── api-keys
│ │ │ │ └── stats
│ │ │ │ └── summary
│ │ │ │ └── route.ts
│ │ ├── register
│ │ │ └── page.tsx
│ │ ├── install-cli
│ │ │ ├── layout.tsx
│ │ │ └── loading.tsx
│ │ └── layout.tsx
│ ├── types
│ │ ├── operation.ts
│ │ ├── index.ts
│ │ └── ai-agent.ts
│ ├── stores
│ │ └── ai-agent
│ │ │ ├── themeStore.ts
│ │ │ ├── settingsStore.ts
│ │ │ └── uiStore.ts
│ └── middleware.ts
├── postcss.config.js
├── public
│ ├── docs
│ │ ├── backtesting-1.png
│ │ ├── backtesting-2.png
│ │ └── test-doc-image.png
│ ├── vercel.svg
│ └── next.svg
├── __mocks__
│ ├── remark-gfm.js
│ ├── remark-breaks.js
│ ├── react-markdown.js
│ ├── uuid.js
│ └── react-syntax-highlighter.js
├── postcss.config.mjs
├── next.config.mjs
├── components.json
├── tsconfig.json
├── jest.config.ts
└── README.md
├── api
├── .gitignore
├── src
│ ├── common
│ │ ├── index.ts
│ │ ├── entites
│ │ │ └── base.entity.ts
│ │ ├── result.ts
│ │ └── repository.ts
│ ├── database
│ │ ├── migrations
│ │ │ ├── 0002_petite_doctor_faustus.sql
│ │ │ ├── 0001_breezy_sentinels.sql
│ │ │ └── meta
│ │ │ │ └── _journal.json
│ │ ├── schema
│ │ │ └── index.ts
│ │ └── migrate.ts
│ ├── backtest
│ │ ├── backtest.constants.ts
│ │ ├── dto
│ │ │ └── create-backtest.dto.ts
│ │ ├── entities
│ │ │ └── backtest.entity.ts
│ │ ├── backtest.module.ts
│ │ └── backtest.repository.ts
│ ├── app.service.ts
│ ├── auth
│ │ ├── dto
│ │ │ └── validate-token.dto.ts
│ │ ├── current-user.decorator.ts
│ │ ├── auth-combined.decorator.ts
│ │ └── auth.module.ts
│ ├── api-key
│ │ ├── api-key.decorator.ts
│ │ ├── models
│ │ │ └── api-key.model.ts
│ │ ├── dto
│ │ │ ├── api-key-created-response.dto.ts
│ │ │ ├── api-key-response.dto.ts
│ │ │ └── create-api-key.dto.ts
│ │ └── api-key.module.ts
│ ├── bot
│ │ ├── dto
│ │ │ ├── update-bot.dto.ts
│ │ │ └── create-bot.dto.ts
│ │ ├── entities
│ │ │ └── bot.entity.ts
│ │ ├── bot.repository.ts
│ │ ├── bot.constants.ts
│ │ └── bot.module.ts
│ ├── nats
│ │ └── nats.module.ts
│ ├── app.controller.ts
│ ├── logs
│ │ ├── logs.module.ts
│ │ ├── dto
│ │ │ └── get-logs-query.dto.ts
│ │ └── logs.controller.ts
│ ├── app.controller.spec.ts
│ ├── custom-bot
│ │ └── custom-bot.module.ts
│ ├── app.module.ts
│ ├── main.ts
│ └── config
│ │ └── configuration.ts
├── tsconfig.build.json
├── nest-cli.json
├── test
│ ├── jest-e2e.json
│ └── app.e2e-spec.ts
├── .dockerignore
├── tsconfig.json
└── drizzle.config.ts
├── cli
├── .gitignore
├── stories
│ └── story.example.md
├── .the0ignore.example
└── Makefile
├── runtime
├── .gitignore
├── internal
│ ├── fixtures
│ │ ├── js-test-bot.zip
│ │ ├── py-test-bot.zip
│ │ └── py-multi-test-bot.zip
│ ├── util
│ │ ├── validators.go
│ │ ├── paritioning.go
│ │ └── cron.go
│ ├── metrics
│ │ └── segment_metrics.go
│ ├── model
│ │ └── executable.go
│ ├── constants
│ │ └── database.go
│ ├── bot-runner
│ │ └── server
│ │ │ └── master.go
│ ├── backtest-runner
│ │ ├── server
│ │ │ └── master.go
│ │ └── model
│ │ │ └── backtest.go
│ ├── bot-scheduler
│ │ └── server
│ │ │ └── master.go
│ └── docker-runner
│ │ └── entrypoints
│ │ └── code_entrypoint_factory.go
├── pb
│ └── worker.proto
├── start-application.sh
├── .dockerignore
├── deploy
│ └── README.md
└── Makefile
├── site
├── src
│ ├── app
│ │ ├── favicon.ico
│ │ ├── page.tsx
│ │ └── layout.tsx
│ ├── lib
│ │ ├── utils.ts
│ │ └── constants.ts
│ └── components
│ │ ├── theme-provider.tsx
│ │ ├── ui
│ │ ├── input.tsx
│ │ └── badge.tsx
│ │ ├── mode-toggle.tsx
│ │ └── landing-page
│ │ └── hero.tsx
├── .prettierrc
├── postcss.config.js
├── public
│ ├── vercel.svg
│ ├── window.svg
│ ├── file.svg
│ ├── globe.svg
│ └── next.svg
├── next.config.ts
├── components.json
├── eslint.config.mjs
├── .gitignore
├── tsconfig.json
├── README.md
└── package.json
├── k8s
├── Chart.yaml
└── templates
│ └── ingress.yaml
├── .github
└── workflows
│ └── cli.yml
└── docker
└── .env.example
/docs/.nvmrc:
--------------------------------------------------------------------------------
1 | 22.19.0
--------------------------------------------------------------------------------
/services/0vers33r/src/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/services/the0-ai/api/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/services/0vers33r/src/common/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/services/0vers33r/src/services/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/services/0vers33r/src/tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/services/the0-ai/the0/tools/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | **/*/.claude
2 | CLAUDE.md
3 | notes/
--------------------------------------------------------------------------------
/services/the0-ai/the0/__init__.py:
--------------------------------------------------------------------------------
1 | from . import agent
2 |
--------------------------------------------------------------------------------
/docs/src/lib/constants.ts:
--------------------------------------------------------------------------------
1 | export const APP_NAME = "the0";
2 |
--------------------------------------------------------------------------------
/services/the0-ai/tests/api/__init__.py:
--------------------------------------------------------------------------------
1 | # API tests package
2 |
--------------------------------------------------------------------------------
/frontend/src/lib/constants.ts:
--------------------------------------------------------------------------------
1 | export const APP_NAME = "the0";
2 |
--------------------------------------------------------------------------------
/services/the0-ai/alembic/README:
--------------------------------------------------------------------------------
1 | Generic single-database configuration.
--------------------------------------------------------------------------------
/services/the0-ai/tests/__init__.py:
--------------------------------------------------------------------------------
1 | # Test package for the0-ai service
2 |
--------------------------------------------------------------------------------
/services/the0-ai/tests/the0/tools/__init__.py:
--------------------------------------------------------------------------------
1 | # Tools tests package
2 |
--------------------------------------------------------------------------------
/api/.gitignore:
--------------------------------------------------------------------------------
1 | dist/
2 | node_modules
3 | package-lock.json
4 | .env
5 | .idea/
--------------------------------------------------------------------------------
/api/src/common/index.ts:
--------------------------------------------------------------------------------
1 | export { Result, Ok, Failure } from "./result";
2 |
--------------------------------------------------------------------------------
/services/0vers33r/.gitignore:
--------------------------------------------------------------------------------
1 | **/*/*.pyc
2 | .claude/
3 | CLAUDE.md
4 | venv/
--------------------------------------------------------------------------------
/services/the0-ai/tests/the0/__init__.py:
--------------------------------------------------------------------------------
1 | # Agent and tools tests package
2 |
--------------------------------------------------------------------------------
/cli/.gitignore:
--------------------------------------------------------------------------------
1 | the0-cli
2 | the0
3 |
4 | bin
5 | INITIAL.md
6 | .claude/
7 | CLAUDE.md
--------------------------------------------------------------------------------
/api/src/database/migrations/0002_petite_doctor_faustus.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE IF EXISTS "user_bots";
--------------------------------------------------------------------------------
/frontend/src/components/spinner/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Spinner } from "./Spinner";
2 |
--------------------------------------------------------------------------------
/frontend/src/components/plotting/index.ts:
--------------------------------------------------------------------------------
1 | export { default as PlotModal } from "./PlotModal";
2 |
--------------------------------------------------------------------------------
/frontend/src/components/dashboard/index.ts:
--------------------------------------------------------------------------------
1 | export { default as CustomTable } from "./CustomTable";
2 |
--------------------------------------------------------------------------------
/api/src/database/migrations/0001_breezy_sentinels.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "custom_bots" ADD COLUMN "review" jsonb;
--------------------------------------------------------------------------------
/docs/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexanderwanyoike/the0/HEAD/docs/src/app/favicon.ico
--------------------------------------------------------------------------------
/runtime/.gitignore:
--------------------------------------------------------------------------------
1 | pb/*.go
2 | bad-bot.zip
3 | bad-bot/
4 | CHANGE.md
5 | PR_MESSAGE.md
6 | build/
7 | notes/
--------------------------------------------------------------------------------
/site/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexanderwanyoike/the0/HEAD/site/src/app/favicon.ico
--------------------------------------------------------------------------------
/frontend/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexanderwanyoike/the0/HEAD/frontend/src/app/favicon.ico
--------------------------------------------------------------------------------
/frontend/src/components/trading-view/index.ts:
--------------------------------------------------------------------------------
1 | export { default as TradingViewChart } from "./TradingViewChart";
2 |
--------------------------------------------------------------------------------
/docs/public/docs/backtesting-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexanderwanyoike/the0/HEAD/docs/public/docs/backtesting-1.png
--------------------------------------------------------------------------------
/docs/public/docs/backtesting-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexanderwanyoike/the0/HEAD/docs/public/docs/backtesting-2.png
--------------------------------------------------------------------------------
/docs/public/docs/test-doc-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexanderwanyoike/the0/HEAD/docs/public/docs/test-doc-image.png
--------------------------------------------------------------------------------
/site/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": true,
3 | "singleQuote": false,
4 | "tabWidth": 2,
5 | "trailingComma": "all"
6 | }
7 |
--------------------------------------------------------------------------------
/docs/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/frontend/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/site/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/api/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
4 | }
5 |
--------------------------------------------------------------------------------
/frontend/public/docs/backtesting-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexanderwanyoike/the0/HEAD/frontend/public/docs/backtesting-1.png
--------------------------------------------------------------------------------
/frontend/public/docs/backtesting-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexanderwanyoike/the0/HEAD/frontend/public/docs/backtesting-2.png
--------------------------------------------------------------------------------
/frontend/public/docs/test-doc-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexanderwanyoike/the0/HEAD/frontend/public/docs/test-doc-image.png
--------------------------------------------------------------------------------
/api/src/common/entites/base.entity.ts:
--------------------------------------------------------------------------------
1 | export interface BaseEntity {
2 | id: string;
3 | createdAt?: Date;
4 | updatedAt?: Date;
5 | }
6 |
--------------------------------------------------------------------------------
/frontend/__mocks__/remark-gfm.js:
--------------------------------------------------------------------------------
1 | // Mock for remark-gfm
2 | module.exports = function remarkGfm() {
3 | return function () {};
4 | };
5 |
--------------------------------------------------------------------------------
/runtime/internal/fixtures/js-test-bot.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexanderwanyoike/the0/HEAD/runtime/internal/fixtures/js-test-bot.zip
--------------------------------------------------------------------------------
/runtime/internal/fixtures/py-test-bot.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexanderwanyoike/the0/HEAD/runtime/internal/fixtures/py-test-bot.zip
--------------------------------------------------------------------------------
/frontend/__mocks__/remark-breaks.js:
--------------------------------------------------------------------------------
1 | // Mock for remark-breaks
2 | module.exports = function remarkBreaks() {
3 | return function () {};
4 | };
5 |
--------------------------------------------------------------------------------
/runtime/internal/fixtures/py-multi-test-bot.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexanderwanyoike/the0/HEAD/runtime/internal/fixtures/py-multi-test-bot.zip
--------------------------------------------------------------------------------
/services/0vers33r/src/common/logging.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 |
4 | logging.basicConfig(level=logging.INFO)
5 | logger = logging.getLogger(__name__)
6 |
--------------------------------------------------------------------------------
/site/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/frontend/src/types/operation.ts:
--------------------------------------------------------------------------------
1 | export type Operation = {
2 | type: "subscription_update_confirm" | "payment_method_update";
3 | operationData?: any;
4 | };
5 |
--------------------------------------------------------------------------------
/api/src/backtest/backtest.constants.ts:
--------------------------------------------------------------------------------
1 | // NATS topics for backtest events
2 | export const BACKTEST_TOPICS = {
3 | CREATED: "the0.backtest.created",
4 | } as const;
5 |
--------------------------------------------------------------------------------
/docs/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/api/src/app.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from "@nestjs/common";
2 |
3 | @Injectable()
4 | export class AppService {
5 | getHello(): string {
6 | return "Hello World!";
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/frontend/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/frontend/src/components/main-navigation/index.ts:
--------------------------------------------------------------------------------
1 | export { Sidebar } from "./sidebar";
2 | export { NavItem } from "./nav-item";
3 | export { UserActionsButton } from "./user-actions-button";
4 |
--------------------------------------------------------------------------------
/services/the0-ai/api/models/__init__.py:
--------------------------------------------------------------------------------
1 | from .database import Base, ChatSession, ChatMessage, Artifact, Setting
2 |
3 | __all__ = ["Base", "ChatSession", "ChatMessage", "Artifact", "Setting"]
4 |
--------------------------------------------------------------------------------
/frontend/__mocks__/react-markdown.js:
--------------------------------------------------------------------------------
1 | // Mock for react-markdown
2 | module.exports = function Markdown({ children }) {
3 | return typeof children === "string" ? children : String(children);
4 | };
5 |
--------------------------------------------------------------------------------
/services/the0-ai/.gitignore:
--------------------------------------------------------------------------------
1 | venv
2 | INTIAL.md
3 | .env
4 | bots
5 | testprompt.md
6 | notes/
7 | .data/
8 | data/
9 | **/*.pyc
10 | dist/
11 | build/
12 | .pytest_cache/
13 | */**/__pycache__
--------------------------------------------------------------------------------
/api/src/auth/dto/validate-token.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsNotEmpty, IsString } from "class-validator";
2 |
3 | export class ValidateTokenDto {
4 | @IsNotEmpty()
5 | @IsString()
6 | token: string;
7 | }
8 |
--------------------------------------------------------------------------------
/api/src/api-key/api-key.decorator.ts:
--------------------------------------------------------------------------------
1 | import { SetMetadata } from "@nestjs/common";
2 |
3 | export const API_KEY_AUTH_KEY = "apiKeyAuth";
4 | export const ApiKeyAuth = () => SetMetadata(API_KEY_AUTH_KEY, true);
5 |
--------------------------------------------------------------------------------
/api/src/bot/dto/update-bot.dto.ts:
--------------------------------------------------------------------------------
1 | import { PartialType } from "@nestjs/mapped-types";
2 | import { CreateBotDto } from "./create-bot.dto";
3 |
4 | export class UpdateBotDto extends PartialType(CreateBotDto) {}
5 |
--------------------------------------------------------------------------------
/docs/src/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { clsx, type ClassValue } from "clsx";
2 | import { twMerge } from "tailwind-merge";
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs));
6 | }
7 |
--------------------------------------------------------------------------------
/site/src/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { type ClassValue, clsx } from "clsx";
2 | import { twMerge } from "tailwind-merge";
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs));
6 | }
7 |
--------------------------------------------------------------------------------
/api/nest-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/nest-cli",
3 | "collection": "@nestjs/schematics",
4 | "sourceRoot": "src",
5 | "compilerOptions": {
6 | "deleteOutDir": true
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/services/the0-ai/the0/agents/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | the0 agents package.
3 |
4 | Multi-Agent System (MAS) for automated trading bot creation.
5 | """
6 |
7 | from the0.agents import base
8 |
9 | __all__ = ["base"]
10 |
--------------------------------------------------------------------------------
/frontend/src/types/index.ts:
--------------------------------------------------------------------------------
1 | export type { Backtest } from "./backtest";
2 | export type {
3 | Message,
4 | ArtifactFile,
5 | ChatRequest,
6 | ChatResponse,
7 | StreamChunk,
8 | ApiError,
9 | } from "./ai-agent";
10 |
--------------------------------------------------------------------------------
/api/src/bot/entities/bot.entity.ts:
--------------------------------------------------------------------------------
1 | export class Bot {
2 | name: string;
3 | id: string;
4 | config: any;
5 | topic: string;
6 | createdAt: Date;
7 | updatedAt: Date;
8 | userId: string;
9 | customBotId: string;
10 | }
11 |
--------------------------------------------------------------------------------
/frontend/__mocks__/uuid.js:
--------------------------------------------------------------------------------
1 | // Mock for uuid
2 | let counter = 0;
3 |
4 | function v4() {
5 | return `mock-uuid-${counter++}`;
6 | }
7 |
8 | module.exports = { v4 };
9 | module.exports.v4 = v4;
10 | module.exports.default = { v4 };
11 |
--------------------------------------------------------------------------------
/frontend/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | reactStrictMode: true,
4 | pageExtensions: ["js", "jsx", "ts", "tsx"],
5 | output: "standalone",
6 | };
7 |
8 | export default nextConfig;
9 |
--------------------------------------------------------------------------------
/api/test/jest-e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "moduleFileExtensions": ["js", "json", "ts"],
3 | "rootDir": ".",
4 | "testEnvironment": "node",
5 | "testRegex": ".e2e-spec.ts$",
6 | "transform": {
7 | "^.+\\.(t|j)s$": "ts-jest"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/services/the0-ai/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | echo "Starting the0-ai service..."
5 |
6 | # Run migrations
7 | alembic upgrade head
8 |
9 | # Start the application
10 | exec python -m uvicorn api.main:app --host 0.0.0.0 --port 8000
--------------------------------------------------------------------------------
/api/src/api-key/models/api-key.model.ts:
--------------------------------------------------------------------------------
1 | export interface ApiKey {
2 | id: string;
3 | userId: string;
4 | name: string;
5 | key: string;
6 | isActive: boolean;
7 | createdAt: Date;
8 | updatedAt: Date;
9 | lastUsedAt?: Date;
10 | }
11 |
--------------------------------------------------------------------------------
/frontend/src/components/settings/api-section.tsx:
--------------------------------------------------------------------------------
1 | import { ApiKeySection } from "./api-key-section";
2 |
3 | export function ApiSection() {
4 | return (
5 |
8 | );
9 | }
10 |
--------------------------------------------------------------------------------
/site/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 |
3 | const nextConfig: NextConfig = {
4 | output: 'export',
5 | trailingSlash: true,
6 | images: {
7 | unoptimized: true
8 | }
9 | };
10 |
11 | export default nextConfig;
12 |
--------------------------------------------------------------------------------
/api/src/api-key/dto/api-key-created-response.dto.ts:
--------------------------------------------------------------------------------
1 | import { ApiKeyResponseDto } from "@/api-key/dto/api-key-response.dto";
2 |
3 | export class ApiKeyCreatedResponseDto extends ApiKeyResponseDto {
4 | key: string; // Full key only returned on creation
5 | }
6 |
--------------------------------------------------------------------------------
/api/src/api-key/dto/api-key-response.dto.ts:
--------------------------------------------------------------------------------
1 | export class ApiKeyResponseDto {
2 | id: string;
3 | userId: string;
4 | name: string;
5 | key: string;
6 | isActive: boolean;
7 | createdAt: Date;
8 | updatedAt: Date;
9 | lastUsedAt?: Date;
10 | }
11 |
--------------------------------------------------------------------------------
/api/src/bot/dto/create-bot.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsNotEmpty, IsObject, IsString } from "class-validator";
2 |
3 | export class CreateBotDto {
4 | @IsNotEmpty()
5 | @IsString()
6 | name: string;
7 |
8 | @IsNotEmpty()
9 | @IsObject()
10 | config: any;
11 | }
12 |
--------------------------------------------------------------------------------
/api/src/backtest/dto/create-backtest.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsNotEmpty, IsObject, IsString } from "class-validator";
2 |
3 | export class CreateBacktestDto {
4 | @IsNotEmpty()
5 | @IsString()
6 | name: string;
7 |
8 | @IsNotEmpty()
9 | @IsObject()
10 | config: any;
11 | }
12 |
--------------------------------------------------------------------------------
/api/src/backtest/entities/backtest.entity.ts:
--------------------------------------------------------------------------------
1 | export class Backtest {
2 | name: string;
3 | id: string;
4 | config: any;
5 | analysis: any | null;
6 | status: string;
7 | createdAt: Date;
8 | updatedAt: Date;
9 | userId: string;
10 | customBotId: string;
11 | }
12 |
--------------------------------------------------------------------------------
/frontend/src/app/providers.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { ThemeProvider } from "next-themes";
4 | import { ReactNode } from "react";
5 |
6 | export function Providers({ children }: { children: ReactNode }) {
7 | return {children} ;
8 | }
9 |
--------------------------------------------------------------------------------
/site/src/lib/constants.ts:
--------------------------------------------------------------------------------
1 | // Documentation and external links
2 | export const DOCS_URLS = {
3 | main: process.env.NEXT_PUBLIC_DOCS_URL || "https://docs.the0.dev",
4 | github:
5 | process.env.NEXT_PUBLIC_GITHUB_URL ||
6 | "https://github.com/alexanderwanyoike/the0",
7 | } as const;
8 |
--------------------------------------------------------------------------------
/frontend/src/lib/auth/index.ts:
--------------------------------------------------------------------------------
1 | // JWT Auth Service
2 | export { JwtAuthService } from "./jwt-auth.service";
3 |
4 | // Types
5 | export type {
6 | AuthUser,
7 | LoginCredentials,
8 | RegisterCredentials,
9 | AuthResponse,
10 | ApiResponse,
11 | ApiError,
12 | Result,
13 | } from "./types";
14 |
--------------------------------------------------------------------------------
/api/src/auth/current-user.decorator.ts:
--------------------------------------------------------------------------------
1 | import { createParamDecorator, ExecutionContext } from "@nestjs/common";
2 |
3 | export const CurrentUser = createParamDecorator(
4 | (data: unknown, ctx: ExecutionContext) => {
5 | const request = ctx.switchToHttp().getRequest();
6 | return request.user;
7 | },
8 | );
9 |
--------------------------------------------------------------------------------
/api/src/database/schema/index.ts:
--------------------------------------------------------------------------------
1 | // Re-export all schema tables and types
2 | export * from "./users";
3 | export * from "./custom-bots";
4 | // Logs are stored in external storage (MinIO/S3), not in database
5 |
6 | // Re-export connection utilities
7 | export { getDatabase, getDatabaseConfig, schema } from "../connection";
8 |
--------------------------------------------------------------------------------
/api/src/nats/nats.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from "@nestjs/common";
2 | import { ConfigModule } from "@nestjs/config";
3 | import { NatsService } from "./nats.service";
4 |
5 | @Module({
6 | imports: [ConfigModule],
7 | providers: [NatsService],
8 | exports: [NatsService],
9 | })
10 | export class NatsModule {}
11 |
--------------------------------------------------------------------------------
/frontend/src/app/settings/profile/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { ProfileSection } from "@/components/settings/profile-section";
3 | import { withAuth } from "@/components/auth/with-auth";
4 |
5 | function ProfileSettingsPage() {
6 | return ;
7 | }
8 |
9 | export default withAuth(ProfileSettingsPage);
10 |
--------------------------------------------------------------------------------
/services/the0-ai/.env.example:
--------------------------------------------------------------------------------
1 | GOOGLE_GENAI_USE_VERTEXAI=FALSE
2 | GOOGLE_API_KEY=YEAH_THIS_IS_A_FAKE_KEY
3 |
4 | # Tavily API Configuration (for Researcher Agent web search)
5 | # Get your API key from: https://tavily.com
6 | TAVILY_API_KEY=your_tavily_api_key_here
7 | TAVILY_SEARCH_DEPTH=advanced # Options: basic, advanced
8 | TAVILY_MAX_RESULTS=5
--------------------------------------------------------------------------------
/api/src/app.controller.ts:
--------------------------------------------------------------------------------
1 | import { Controller, Get } from "@nestjs/common";
2 | import { AppService } from "./app.service";
3 |
4 | @Controller()
5 | export class AppController {
6 | constructor(private readonly appService: AppService) {}
7 |
8 | @Get()
9 | getHello(): string {
10 | return this.appService.getHello();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/runtime/internal/util/validators.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | // import (
4 | // "github.com/google/uuid"
5 | // )
6 |
7 | func ValidateUUID(id string) bool {
8 | // Always return true to allow any bot ID format (not just UUIDs)
9 | return true
10 | // Original UUID validation:
11 | // _, err := uuid.Parse(id)
12 | // return err == nil
13 | }
14 |
--------------------------------------------------------------------------------
/runtime/internal/util/paritioning.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import (
4 | "hash/crc32"
5 | )
6 |
7 | func GetSegmentId(id string, maxSegments int) int32 {
8 | // Generate a segment ID based on the bot ID using a hash function
9 | hash := crc32.ChecksumIEEE([]byte(id))
10 | segmentID := int32(hash % uint32(maxSegments))
11 |
12 | return segmentID
13 | }
14 |
--------------------------------------------------------------------------------
/docs/src/components/ui/skeleton.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from "@/lib/utils";
2 |
3 | function Skeleton({
4 | className,
5 | ...props
6 | }: React.HTMLAttributes) {
7 | return (
8 |
12 | );
13 | }
14 |
15 | export { Skeleton };
16 |
--------------------------------------------------------------------------------
/docs/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | import withMarkdoc from "@markdoc/next.js";
3 |
4 | const nextConfig = withMarkdoc()({
5 | reactStrictMode: true,
6 | pageExtensions: ["md", "mdoc", "js", "jsx", "ts", "tsx"],
7 | trailingSlash: true,
8 | images: {
9 | unoptimized: true,
10 | },
11 | });
12 |
13 | export default nextConfig;
14 |
--------------------------------------------------------------------------------
/docs/src/components/theme-provider.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import {
5 | ThemeProvider as NextThemesProvider,
6 | ThemeProviderProps,
7 | } from "next-themes";
8 |
9 | export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
10 | return {children} ;
11 | }
12 |
--------------------------------------------------------------------------------
/frontend/src/components/ui/skeleton.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from "@/lib/utils";
2 |
3 | function Skeleton({
4 | className,
5 | ...props
6 | }: React.HTMLAttributes) {
7 | return (
8 |
12 | );
13 | }
14 |
15 | export { Skeleton };
16 |
--------------------------------------------------------------------------------
/site/src/components/theme-provider.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import {
5 | ThemeProvider as NextThemesProvider,
6 | ThemeProviderProps,
7 | } from "next-themes";
8 |
9 | export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
10 | return {children} ;
11 | }
12 |
--------------------------------------------------------------------------------
/frontend/src/components/theme-provider.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import {
5 | ThemeProvider as NextThemesProvider,
6 | ThemeProviderProps,
7 | } from "next-themes";
8 |
9 | export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
10 | return {children} ;
11 | }
12 |
--------------------------------------------------------------------------------
/frontend/src/app/settings/api-settings/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { ProfileSection } from "@/components/settings/profile-section";
3 | import { withAuth } from "@/components/auth/with-auth";
4 | import { ApiSection } from "@/components/settings/api-section";
5 |
6 | function ApiSettings() {
7 | return ;
8 | }
9 |
10 | export default withAuth(ApiSettings);
11 |
--------------------------------------------------------------------------------
/api/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 | .npm
4 | .git
5 | .gitignore
6 | README.md
7 | .env
8 | .env.local
9 | .env.production.local
10 | .env.test.local
11 | .DS_Store
12 | Thumbs.db
13 | coverage
14 | .nyc_output
15 | *.log
16 | dist
17 | build
18 | .vscode
19 | .idea
20 | *.swp
21 | *.swo
22 | test
23 | *.test.ts
24 | *.spec.ts
25 | __tests__
26 | jest.config.js
27 | .github
--------------------------------------------------------------------------------
/api/src/bot/bot.repository.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from "@nestjs/common";
2 | import { Bot } from "./entities/bot.entity";
3 | import { RoleRepository } from "@/common/role.repository";
4 |
5 | @Injectable()
6 | export class BotRepository extends RoleRepository {
7 | protected readonly tableName = "bots" as const;
8 |
9 | constructor() {
10 | super();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/services/the0-ai/pytest.ini:
--------------------------------------------------------------------------------
1 | [tool:pytest]
2 | minversion = 6.0
3 | testpaths = tests
4 | python_files = test_*.py
5 | python_classes = Test*
6 | python_functions = test_*
7 | addopts =
8 | -v
9 | --tb=short
10 | --strict-markers
11 | --disable-warnings
12 | --asyncio-mode=auto
13 | markers =
14 | asyncio: mark test as async
15 | slow: mark test as slow running
--------------------------------------------------------------------------------
/site/public/window.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/site/public/file.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/api/src/common/result.ts:
--------------------------------------------------------------------------------
1 | export type Result = {
2 | data: T | null;
3 | error: E | null;
4 | success: boolean;
5 | };
6 |
7 | const Failure = (error: E): Result => ({
8 | data: null,
9 | error,
10 | success: false,
11 | });
12 |
13 | const Ok = (data: T): Result => ({
14 | data,
15 | error: null,
16 | success: true,
17 | });
18 |
19 | export { Failure, Ok };
20 |
--------------------------------------------------------------------------------
/docs/src/components/ui/collapsible.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
4 |
5 | const Collapsible = CollapsiblePrimitive.Root;
6 |
7 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
8 |
9 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
10 |
11 | export { Collapsible, CollapsibleTrigger, CollapsibleContent };
12 |
--------------------------------------------------------------------------------
/frontend/src/components/ui/collapsible.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
4 |
5 | const Collapsible = CollapsiblePrimitive.Root;
6 |
7 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
8 |
9 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
10 |
11 | export { Collapsible, CollapsibleTrigger, CollapsibleContent };
12 |
--------------------------------------------------------------------------------
/runtime/internal/metrics/segment_metrics.go:
--------------------------------------------------------------------------------
1 | package metrics
2 |
3 | // SegmentMetrics represents the metrics exposed for HPA
4 | type SegmentMetrics struct {
5 | TotalSegments int `json:"total_segments"`
6 | AssignedSegments int `json:"assigned_segments"`
7 | OrphanedSegments int `json:"orphaned_segments"`
8 | AvailableWorkers int `json:"available_workers"`
9 | SegmentBacklog int `json:"segment_backlog"`
10 | }
11 |
--------------------------------------------------------------------------------
/frontend/src/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { clsx, type ClassValue } from "clsx";
2 | import { twMerge } from "tailwind-merge";
3 | import { CustomBotConfig } from "@/types/custom-bots";
4 |
5 | export function cn(...inputs: ClassValue[]) {
6 | return twMerge(clsx(inputs));
7 | }
8 |
9 | export function canBotBeBacktested(config: CustomBotConfig): boolean {
10 | return !!(config.entrypoints?.backtest && config.schema?.backtest);
11 | }
12 |
--------------------------------------------------------------------------------
/runtime/internal/model/executable.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | type Executable struct {
4 | ID string
5 | Runtime string
6 | Entrypoint string // Either `bot` or `backtest`
7 | EntrypointFiles map[string]string
8 | Config map[string]interface{}
9 | FilePath string
10 | IsLongRunning bool
11 | PersistResults bool
12 | Segment int32 // Worker segment for container labeling
13 | }
14 |
--------------------------------------------------------------------------------
/site/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "default",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.ts",
8 | "css": "src/app/globals.css",
9 | "baseColor": "slate",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "utils": "@/lib/utils"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/api/src/api-key/api-key.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from "@nestjs/common";
2 | import { ApiKeyController } from "./api-key.controller";
3 | import { ApiKeyService } from "./api-key.service";
4 | import { ApiKeyRepository } from "./api-key.repository";
5 |
6 | @Module({
7 | controllers: [ApiKeyController],
8 | providers: [ApiKeyService, ApiKeyRepository],
9 | exports: [ApiKeyService, ApiKeyRepository],
10 | })
11 | export class ApiKeyModule {}
12 |
--------------------------------------------------------------------------------
/frontend/src/lib/result.ts:
--------------------------------------------------------------------------------
1 | export type Result = Success | Failure;
2 |
3 | export interface Success {
4 | data: T;
5 | success: true;
6 | }
7 |
8 | export interface Failure {
9 | error: E;
10 | success: false;
11 | }
12 |
13 | export const Ok = (data: T): Result => ({
14 | data,
15 | success: true,
16 | });
17 |
18 | export const Failure = (error: E): Result => ({
19 | error,
20 | success: false,
21 | });
22 |
--------------------------------------------------------------------------------
/k8s/Chart.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v2
2 | name: the0
3 | description: A distributed trading bot platform with backtesting, bot scheduling, and security analysis
4 | type: application
5 | version: 0.1.0
6 | appVersion: "1.0.0"
7 | keywords:
8 | - trading
9 | - bots
10 | - backtesting
11 | - automation
12 | - fintech
13 | home: https://github.com/your-org/the0-oss
14 | sources:
15 | - https://github.com/your-org/the0-oss
16 | maintainers:
17 | - name: the0 Team
18 | email: team@the0.com
--------------------------------------------------------------------------------
/api/src/api-key/dto/create-api-key.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsString, IsNotEmpty, MaxLength, MinLength } from "class-validator";
2 |
3 | export class CreateApiKeyDto {
4 | @IsString({ message: "name must be a string" })
5 | @IsNotEmpty({ message: "name should not be empty" })
6 | @MinLength(3, {
7 | message: "name must be longer than or equal to 3 characters",
8 | })
9 | @MaxLength(50, {
10 | message: "name must be shorter than or equal to 50 characters",
11 | })
12 | name: string;
13 | }
14 |
--------------------------------------------------------------------------------
/api/src/common/repository.ts:
--------------------------------------------------------------------------------
1 | import { Result } from "./result";
2 |
3 | export default interface Repository {
4 | create: (args: any) => Promise>;
5 | findAll: (userId: string) => Promise>;
6 | findOne: (userId: string, id: string) => Promise>;
7 | update: (
8 | userId: string,
9 | id: string,
10 | args: any,
11 | ) => Promise>;
12 | remove: (userId: string, id: string) => Promise>;
13 | }
14 |
--------------------------------------------------------------------------------
/api/src/logs/logs.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from "@nestjs/common";
2 | import { LogsService } from "./logs.service";
3 | import { LogsController } from "./logs.controller";
4 | import { ConfigModule } from "@nestjs/config";
5 | import { BotModule } from "@/bot/bot.module";
6 | import { ApiKeyModule } from "@/api-key/api-key.module";
7 |
8 | @Module({
9 | imports: [ConfigModule, BotModule, ApiKeyModule],
10 | controllers: [LogsController],
11 | providers: [LogsService],
12 | })
13 | export class LogsModule {}
14 |
--------------------------------------------------------------------------------
/frontend/src/components/settings/profile-section.tsx:
--------------------------------------------------------------------------------
1 | import { ProfileForm } from "./profile-form";
2 | import { PasswordForm } from "./password-form";
3 | import { DeleteAccount } from "./delete-account";
4 | import { Separator } from "@/components/ui/separator";
5 |
6 | export function ProfileSection() {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/frontend/src/app/custom-bots/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import React from "react";
3 | import { withAuth } from "@/components/auth/with-auth";
4 | import DashboardLayout from "@/components/layouts/dashboard-layout";
5 | import CustomBotsDashboard from "@/components/custom-bots/custom-bots-dashboard";
6 |
7 | const CustomBotsPage: React.FC = () => {
8 | return (
9 |
10 |
11 |
12 | );
13 | };
14 |
15 | export default withAuth(CustomBotsPage);
16 |
--------------------------------------------------------------------------------
/frontend/src/stores/ai-agent/themeStore.ts:
--------------------------------------------------------------------------------
1 | import { create } from "zustand";
2 | import { persist } from "zustand/middleware";
3 |
4 | interface ThemeStore {
5 | isDark: boolean;
6 | toggleTheme: () => void;
7 | }
8 |
9 | export const useThemeStore = create()(
10 | persist(
11 | (set) => ({
12 | isDark: true, // Default to dark mode
13 | toggleTheme: () => set((state) => ({ isDark: !state.isDark })),
14 | }),
15 | {
16 | name: "theme-storage",
17 | },
18 | ),
19 | );
20 |
--------------------------------------------------------------------------------
/runtime/pb/worker.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | package botscheduler.worker.v1;
4 | option go_package = "./pb";
5 |
6 | message Request {
7 | string data = 1;
8 | }
9 |
10 |
11 | message Response {
12 | string data = 1;
13 | }
14 |
15 |
16 | service Worker {
17 | // Client to server -> Client heartbeat to check connection
18 | rpc Heartbeat(Request) returns (Response) {};
19 |
20 | // Server to client -> Server push to notify client
21 | rpc RebalanceSubscription(Request) returns (stream Response) {};
22 | }
--------------------------------------------------------------------------------
/frontend/src/lib/bot-type.ts:
--------------------------------------------------------------------------------
1 | export const sanitizeBotType = (botType: string): string =>
2 | botType.replace(/\//g, "_");
3 |
4 | export const splitBotType = (
5 | botType: string,
6 | ): {
7 | vendor: string;
8 | type: string;
9 | name: string;
10 | } => {
11 | const [vendor, type, name] = botType.split("/");
12 | if (!vendor || !type || !name) {
13 | throw new Error(
14 | "Invalid bot type format. Expected format: vendor/type/name",
15 | );
16 | }
17 | return { vendor, type, name };
18 | };
19 |
--------------------------------------------------------------------------------
/cli/stories/story.example.md:
--------------------------------------------------------------------------------
1 | ## FEATURE:
2 |
3 | [Insert your feature here]
4 |
5 | ## EXAMPLES:
6 |
7 | [Provide and explain examples that you have in the `examples/` folder]
8 |
9 | ## DOCUMENTATION:
10 |
11 | [List out any documentation (web pages, sources for an MCP server like Crawl4AI RAG, etc.) that will need to be referenced during development]
12 |
13 | ## OTHER CONSIDERATIONS:
14 |
15 | [Any other considerations or specific requirements - great place to include gotchas that you see AI coding assistants miss with your projects a lot]
--------------------------------------------------------------------------------
/docs/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "new-york",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.ts",
8 | "css": "src/app/globals.css",
9 | "baseColor": "neutral",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "utils": "@/lib/utils",
16 | "ui": "@/components/ui",
17 | "lib": "@/lib",
18 | "hooks": "@/hooks"
19 | },
20 | "iconLibrary": "lucide"
21 | }
22 |
--------------------------------------------------------------------------------
/frontend/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "new-york",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.ts",
8 | "css": "src/app/globals.css",
9 | "baseColor": "neutral",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "utils": "@/lib/utils",
16 | "ui": "@/components/ui",
17 | "lib": "@/lib",
18 | "hooks": "@/hooks"
19 | },
20 | "iconLibrary": "lucide"
21 | }
22 |
--------------------------------------------------------------------------------
/api/src/auth/auth-combined.decorator.ts:
--------------------------------------------------------------------------------
1 | import { SetMetadata } from "@nestjs/common";
2 |
3 | export const COMBINED_AUTH_KEY = "combinedAuth";
4 | export const CombinedAuth = () => SetMetadata(COMBINED_AUTH_KEY, true);
5 |
6 | // src/auth/decorators/auth-type.decorator.ts
7 | import { createParamDecorator, ExecutionContext } from "@nestjs/common";
8 |
9 | export const AuthType = createParamDecorator(
10 | (data: unknown, ctx: ExecutionContext) => {
11 | const request = ctx.switchToHttp().getRequest();
12 | return request.user?.authType || "unknown";
13 | },
14 | );
15 |
--------------------------------------------------------------------------------
/api/src/bot/bot.constants.ts:
--------------------------------------------------------------------------------
1 | export const BOT_TYPE_PATTERN =
2 | /^[a-z0-9]+(-[a-z0-9]+)*\/[a-z0-9]+(-[a-z0-9]+)*$/;
3 |
4 | // NATS topics for bot events (match runtime expectations)
5 | export const BOT_TOPICS = {
6 | CREATED: "the0.bot.created",
7 | UPDATED: "the0.bot.updated",
8 | DELETED: "the0.bot.deleted",
9 | } as const;
10 |
11 | // NATS topics for scheduled bot events
12 | export const SCHEDULED_BOT_TOPICS = {
13 | CREATED: "the0.bot-schedule.created",
14 | UPDATED: "the0.bot-schedule.updated",
15 | DELETED: "the0.bot-schedule.deleted",
16 | } as const;
17 |
--------------------------------------------------------------------------------
/runtime/internal/constants/database.go:
--------------------------------------------------------------------------------
1 | package constants
2 |
3 | // Database configurations for each service
4 | const (
5 | // Separate database names to avoid conflicts
6 | BOT_RUNNER_DB_NAME = "bot_runner"
7 | BOT_RUNNER_COLLECTION = "bots"
8 | BACKTEST_RUNNER_DB_NAME = "backtest_runner"
9 | BACKTEST_COLLECTION = "backtests"
10 | BOT_SCHEDULER_DB_NAME = "bot_scheduler"
11 | BOT_SCHEDULE_COLLECTION = "bot_schedules"
12 |
13 | // Default service ports
14 | BOT_RUNNER_PORT = 50051
15 | BACKTEST_RUNNER_PORT = 50052
16 | BOT_SCHEDULER_PORT = 50053
17 | )
18 |
--------------------------------------------------------------------------------
/services/0vers33r/src/interfaces/__init__.py:
--------------------------------------------------------------------------------
1 | from typing import Protocol, Dict, Any
2 |
3 |
4 | class StorageInterface(Protocol):
5 | """Interface for storage operations"""
6 |
7 | def download_file(self, gcs_path: str) -> bytes:
8 | """Download file from storage and return bytes"""
9 | ...
10 |
11 |
12 | class DatabaseInterface(Protocol):
13 | """Interface for database operations"""
14 |
15 | def update_bot_status(
16 | self, bot_id: str, status: str, review_data: Dict[str, Any]
17 | ) -> None:
18 | """Update bot status in database"""
19 | ...
20 |
--------------------------------------------------------------------------------
/api/src/logs/dto/get-logs-query.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsOptional, IsString, IsInt, Min, Max } from "class-validator";
2 | import { Transform } from "class-transformer";
3 |
4 | export class GetLogsQueryDto {
5 | @IsOptional()
6 | @IsString()
7 | date?: string;
8 |
9 | @IsOptional()
10 | @IsString()
11 | dateRange?: string;
12 |
13 | @IsOptional()
14 | @Transform(({ value }) => parseInt(value))
15 | @IsInt()
16 | @Min(1)
17 | @Max(1000)
18 | limit?: number;
19 |
20 | @IsOptional()
21 | @Transform(({ value }) => parseInt(value))
22 | @IsInt()
23 | @Min(0)
24 | offset?: number;
25 | }
26 |
--------------------------------------------------------------------------------
/runtime/start-application.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -xe -o pipefail
3 |
4 | # Check if docker socket is already available (Docker-in-Docker case)
5 | if [ -S /var/run/docker.sock ]; then
6 | echo "Docker socket already available, skipping dockerd startup"
7 | else
8 | echo "Starting dockerd..."
9 | # Start dockerd in background
10 | /usr/bin/dockerd --iptables=false --ip6tables=false --bridge=none -D &
11 | # Wait for Docker daemon to be ready
12 | sleep 5
13 | fi
14 |
15 | # Verify Docker is working
16 | docker info || exit 1
17 |
18 | # Start the application as worker
19 | exec ./runtime -worker
--------------------------------------------------------------------------------
/site/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import { dirname } from "path";
2 | import { fileURLToPath } from "url";
3 | import { FlatCompat } from "@eslint/eslintrc";
4 |
5 | const __filename = fileURLToPath(import.meta.url);
6 | const __dirname = dirname(__filename);
7 |
8 | const compat = new FlatCompat({
9 | baseDirectory: __dirname,
10 | });
11 |
12 | const eslintConfig = [
13 | ...compat.extends("next/core-web-vitals", "next/typescript", "prettier"),
14 | ...compat.plugins("prettier"),
15 | {
16 | rules: {
17 | "prettier/prettier": "error",
18 | },
19 | },
20 | ];
21 |
22 | export default eslintConfig;
23 |
--------------------------------------------------------------------------------
/runtime/.dockerignore:
--------------------------------------------------------------------------------
1 | # Binaries
2 | *.exe
3 | *.exe~
4 | *.dll
5 | *.so
6 | *.dylib
7 | *.test
8 | *.out
9 |
10 | # Vendor directory (if you use vendoring)
11 | vendor/
12 |
13 | # Logs
14 | logs
15 | *.log
16 |
17 | # Build output
18 | dist/
19 | build/
20 | bin/
21 | out/
22 |
23 | # Environment files
24 | .env
25 | .env.*
26 |
27 | # OS generated files
28 | .DS_Store
29 | Thumbs.db
30 |
31 | # IDE/editor folders
32 | .idea/
33 | .vscode/
34 | *.swp
35 |
36 | # Docker files (optional)
37 | Dockerfile*
38 | docker-compose*
39 |
40 | # Node modules (if not used, can be removed)
41 | node_modules/
42 | bower_components/
--------------------------------------------------------------------------------
/docs/src/app/docs/layout.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { DocsLayout } from "@/components/docs/docs-layout";
3 | import { Metadata } from "next";
4 |
5 | export const metadata: Metadata = {
6 | title: "Documentation | Theo",
7 | description: "Comprehensive documentation for the Theo trading bot platform",
8 | keywords: ["trading bots", "documentation", "API", "guide", "theo"],
9 | };
10 |
11 | interface DocsLayoutPageProps {
12 | children: React.ReactNode;
13 | }
14 |
15 | export default function DocsLayoutPage({ children }: DocsLayoutPageProps) {
16 | return {children} ;
17 | }
18 |
--------------------------------------------------------------------------------
/docs/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/frontend/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/api/src/database/migrations/meta/_journal.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "5",
3 | "dialect": "pg",
4 | "entries": [
5 | {
6 | "idx": 0,
7 | "version": "5",
8 | "when": 1753488645005,
9 | "tag": "0000_tan_maginty",
10 | "breakpoints": true
11 | },
12 | {
13 | "idx": 1,
14 | "version": "5",
15 | "when": 1753497594306,
16 | "tag": "0001_breezy_sentinels",
17 | "breakpoints": true
18 | },
19 | {
20 | "idx": 2,
21 | "version": "5",
22 | "when": 1760273667702,
23 | "tag": "0002_petite_doctor_faustus",
24 | "breakpoints": true
25 | }
26 | ]
27 | }
--------------------------------------------------------------------------------
/site/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.*
7 | .yarn/*
8 | !.yarn/patches
9 | !.yarn/plugins
10 | !.yarn/releases
11 | !.yarn/versions
12 |
13 | # testing
14 | /coverage
15 |
16 | # next.js
17 | /.next/
18 | /out/
19 |
20 | # production
21 | /build
22 |
23 | # misc
24 | .DS_Store
25 | *.pem
26 |
27 | # debug
28 | npm-debug.log*
29 | yarn-debug.log*
30 | yarn-error.log*
31 | .pnpm-debug.log*
32 |
33 | # env files (can opt-in for committing if needed)
34 | .env*
35 |
36 | # vercel
37 | .vercel
38 |
39 | # typescript
40 | *.tsbuildinfo
41 | next-env.d.ts
42 |
--------------------------------------------------------------------------------
/docs/src/docs/terminology/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Terminology"
3 | description: "Key terms and concepts in algorithmic trading"
4 | order: 2
5 | ---
6 |
7 | # Terminology
8 |
9 | Understanding the key terms and concepts used in algorithmic trading and the the0 platform.
10 |
11 | ## Core Concepts
12 |
13 | - **[Bots](./bots)** - The core trading instances that execute strategies in the0
14 | - **[Custom Bots](./custom-bots)** - User-created trading algorithms
15 | - **[Bot Deployment](./bot-deploment)** - Creating and managing bot instances
16 | - **[Live Trading](./live-trading)** - Real money trading execution
17 | - **[Market Data](./market-data)** - Real-time and historical trading information
18 |
--------------------------------------------------------------------------------
/frontend/src/app/page.tsx:
--------------------------------------------------------------------------------
1 | import { NavigationMenu } from "@/components/landing-page/navigation-menu";
2 | import { HeroSection } from "@/components/landing-page/hero";
3 | import { FeaturesSection } from "@/components/landing-page/features";
4 | import { HowItWorksSection } from "@/components/landing-page/how-it-works";
5 | import { Footer } from "@/components/landing-page/footer";
6 |
7 | export default function LandingPage() {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/frontend/src/components/ai-agent/chat/TypingIndicator.tsx:
--------------------------------------------------------------------------------
1 | export function TypingIndicator() {
2 | return (
3 |
4 |
15 |
the0 is thinking...
16 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/frontend/__mocks__/react-syntax-highlighter.js:
--------------------------------------------------------------------------------
1 | // Mock for react-syntax-highlighter
2 | const { createElement } = require("react");
3 |
4 | const SyntaxHighlighter = function ({ children, language, ...props }) {
5 | return createElement(
6 | "pre",
7 | {
8 | "data-language": language,
9 | ...props,
10 | },
11 | createElement("code", null, children),
12 | );
13 | };
14 |
15 | // Export all named exports that might be used
16 | module.exports = SyntaxHighlighter;
17 | module.exports.default = SyntaxHighlighter;
18 | module.exports.Prism = SyntaxHighlighter;
19 | module.exports.Light = SyntaxHighlighter;
20 |
21 | // Mock styles
22 | module.exports.vscDarkPlus = {};
23 | module.exports.vs = {};
24 |
--------------------------------------------------------------------------------
/api/src/app.controller.spec.ts:
--------------------------------------------------------------------------------
1 | import { Test, TestingModule } from "@nestjs/testing";
2 | import { AppController } from "./app.controller";
3 | import { AppService } from "./app.service";
4 |
5 | describe("AppController", () => {
6 | let appController: AppController;
7 |
8 | beforeEach(async () => {
9 | const app: TestingModule = await Test.createTestingModule({
10 | controllers: [AppController],
11 | providers: [AppService],
12 | }).compile();
13 |
14 | appController = app.get(AppController);
15 | });
16 |
17 | describe("root", () => {
18 | it('should return "Hello World!"', () => {
19 | expect(appController.getHello()).toBe("Hello World!");
20 | });
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/docs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": true,
7 | "noEmit": true,
8 | "esModuleInterop": true,
9 | "module": "esnext",
10 | "moduleResolution": "bundler",
11 | "resolveJsonModule": true,
12 | "isolatedModules": true,
13 | "jsx": "preserve",
14 | "incremental": true,
15 | "plugins": [
16 | {
17 | "name": "next"
18 | }
19 | ],
20 | "paths": {
21 | "@/*": ["./src/*"]
22 | },
23 | "target": "ES2017"
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
--------------------------------------------------------------------------------
/site/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./src/*"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
--------------------------------------------------------------------------------
/frontend/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": true,
7 | "noEmit": true,
8 | "esModuleInterop": true,
9 | "module": "esnext",
10 | "moduleResolution": "bundler",
11 | "resolveJsonModule": true,
12 | "isolatedModules": true,
13 | "jsx": "preserve",
14 | "incremental": true,
15 | "plugins": [
16 | {
17 | "name": "next"
18 | }
19 | ],
20 | "paths": {
21 | "@/*": ["./src/*"]
22 | },
23 | "target": "ES2017"
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
--------------------------------------------------------------------------------
/api/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "declaration": true,
5 | "removeComments": true,
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "allowSyntheticDefaultImports": true,
9 | "esModuleInterop": true,
10 | "target": "es2017",
11 | "sourceMap": true,
12 | "outDir": "./dist",
13 | "baseUrl": "./",
14 | "incremental": true,
15 | "skipLibCheck": true,
16 | "strictNullChecks": false,
17 | "noImplicitAny": false,
18 | "strictBindCallApply": false,
19 | "forceConsistentCasingInFileNames": false,
20 | "noFallthroughCasesInSwitch": false,
21 | "paths": {
22 | "@/*": ["./src/*"],
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/api/test/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { Test, TestingModule } from "@nestjs/testing";
2 | import { INestApplication } from "@nestjs/common";
3 | import * as request from "supertest";
4 | import { AppModule } from "../src/app.module";
5 |
6 | describe("AppController (e2e)", () => {
7 | let app: INestApplication;
8 |
9 | beforeEach(async () => {
10 | const moduleFixture: TestingModule = await Test.createTestingModule({
11 | imports: [AppModule],
12 | }).compile();
13 |
14 | app = moduleFixture.createNestApplication();
15 | await app.init();
16 | });
17 |
18 | it("/ (GET)", () => {
19 | return request(app.getHttpServer())
20 | .get("/")
21 | .expect(200)
22 | .expect("Hello World!");
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/docs/src/app/api/docs/navigation/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest, NextResponse } from "next/server";
2 | import { DocsFileSystem } from "@/lib/docs/file-system";
3 |
4 | export async function GET(request: NextRequest) {
5 | try {
6 | const fileSystem = new DocsFileSystem();
7 | const navigation = await fileSystem.getNavigationTree();
8 |
9 | return NextResponse.json({
10 | success: true,
11 | data: navigation,
12 | });
13 | } catch (error: any) {
14 | console.error("Error fetching docs navigation:", error);
15 | return NextResponse.json(
16 | {
17 | success: false,
18 | error: "Failed to load documentation navigation",
19 | },
20 | { status: 500 },
21 | );
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/docs/src/docs/the0-CLI/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "the0 CLI"
3 | description: "Command-line interface for the0 platform"
4 | order: 3
5 | ---
6 |
7 | # the0 CLI
8 |
9 | The command-line interface for interacting with the the0 platform. Create, deploy, and manage your trading bots from the terminal.
10 |
11 | ## Getting Started
12 |
13 | - **[Installation](./installation)** - Install and set up the CLI
14 | - **[Authentication](./authentication)** - Connect to your the0 account
15 |
16 | ## Bot Management
17 |
18 | - **[Bot Commands](./bot-commands)** - Create and manage bots
19 | - **[Custom Bot Commands](./bot-commands)** - Create and manage custom bots
20 |
21 | ## CLI Reference
22 |
23 | Complete command reference and examples for all CLI operations.
24 |
--------------------------------------------------------------------------------
/runtime/internal/util/cron.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import (
4 | "fmt"
5 | "github.com/robfig/cron/v3"
6 | "time"
7 | )
8 |
9 | func CalculateNextExecutionTime(
10 | cronExpr string,
11 | t time.Time,
12 | ) (time.Time, error) {
13 | // Try to parse with seconds first (6-field format)
14 | parser := cron.NewParser(cron.Second | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor)
15 | schedule, err := parser.Parse(cronExpr)
16 | if err != nil {
17 | // If that fails, try standard 5-field format (without seconds)
18 | schedule, err = cron.ParseStandard(cronExpr)
19 | if err != nil {
20 | return time.Time{}, fmt.Errorf("failed to parse cron expression: %v", err)
21 | }
22 | }
23 |
24 | return schedule.Next(t), nil
25 | }
26 |
--------------------------------------------------------------------------------
/docs/src/components/ui/textarea.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | import { cn } from "@/lib/utils";
4 |
5 | const Textarea = React.forwardRef<
6 | HTMLTextAreaElement,
7 | React.ComponentProps<"textarea">
8 | >(({ className, ...props }, ref) => {
9 | return (
10 |
18 | );
19 | });
20 | Textarea.displayName = "Textarea";
21 |
22 | export { Textarea };
23 |
--------------------------------------------------------------------------------
/frontend/src/components/custom-bots/status-badge.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { STATUS_CONFIG } from "@/components/custom-bots/constants";
3 |
4 | export const StatusBadge = ({ status, review }: any) => {
5 | const config = STATUS_CONFIG[status] || STATUS_CONFIG.pending_review;
6 | const Icon = config.icon;
7 |
8 | return (
9 |
12 |
13 | {config.text}
14 | {review?.threatSummary?.threatLevel && (
15 |
16 | ({review?.threatSummary?.threatLevel})
17 |
18 | )}
19 |
20 | );
21 | };
22 |
--------------------------------------------------------------------------------
/frontend/src/components/ui/textarea.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | import { cn } from "@/lib/utils";
4 |
5 | const Textarea = React.forwardRef<
6 | HTMLTextAreaElement,
7 | React.ComponentProps<"textarea">
8 | >(({ className, ...props }, ref) => {
9 | return (
10 |
18 | );
19 | });
20 | Textarea.displayName = "Textarea";
21 |
22 | export { Textarea };
23 |
--------------------------------------------------------------------------------
/services/the0-ai/alembic/script.py.mako:
--------------------------------------------------------------------------------
1 | """${message}
2 |
3 | Revision ID: ${up_revision}
4 | Revises: ${down_revision | comma,n}
5 | Create Date: ${create_date}
6 |
7 | """
8 | from typing import Sequence, Union
9 |
10 | from alembic import op
11 | import sqlalchemy as sa
12 | ${imports if imports else ""}
13 |
14 | # revision identifiers, used by Alembic.
15 | revision: str = ${repr(up_revision)}
16 | down_revision: Union[str, None] = ${repr(down_revision)}
17 | branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
18 | depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
19 |
20 |
21 | def upgrade() -> None:
22 | ${upgrades if upgrades else "pass"}
23 |
24 |
25 | def downgrade() -> None:
26 | ${downgrades if downgrades else "pass"}
27 |
--------------------------------------------------------------------------------
/docs/src/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Documentation"
3 | description: "the0 platform documentation"
4 | order: 0
5 | ---
6 |
7 | # the0 Documentation
8 |
9 | Welcome to the comprehensive documentation for the0 platform. This documentation covers everything you need to know about algorithmic trading with the0.
10 |
11 | ## Getting Started
12 |
13 | Start with [Welcome to the0](./welcome-to-the0) to understand the platform and its capabilities.
14 |
15 | ## Documentation Sections
16 |
17 | - **[Welcome to the0](./welcome-to-the0)** - Platform introduction and overview
18 | - **[Terminology](./terminology)** - Key terms and concepts
19 | - **[the0 CLI](./the0-cli)** - Command-line interface documentation
20 | - **[Custom Bot Development](./custom-bot-development)** - Build your own trading bots
21 |
--------------------------------------------------------------------------------
/frontend/src/lib/config.ts:
--------------------------------------------------------------------------------
1 | // Configuration for external services
2 | // Uses NEXT_PUBLIC_ for build-time embedding and runtime flexibility
3 |
4 | export const getDocsUrl = (): string => {
5 | // Primary: Use NEXT_PUBLIC_DOCS_URL (embedded at build time)
6 | // Fallback: Use /docs for backward compatibility
7 | return process.env.NEXT_PUBLIC_DOCS_URL || "/docs";
8 | };
9 |
10 | export const getAiAgentUrl = (): string => {
11 | // Use AI_AGENT_API_URL for server-side API calls
12 | return process.env.AI_AGENT_API_URL || "http://localhost:8000";
13 | };
14 |
15 | export const config = {
16 | docsUrl: getDocsUrl(),
17 | aiAgentUrl: getAiAgentUrl(),
18 | appName: process.env.NEXT_PUBLIC_APP_NAME || "the0",
19 | appVersion: process.env.NEXT_PUBLIC_APP_VERSION || "1.0.0",
20 | };
21 |
--------------------------------------------------------------------------------
/frontend/src/lib/axios.ts:
--------------------------------------------------------------------------------
1 | export const getErrorMessage = (error: any): string => {
2 | if (error.response) {
3 | return (
4 | error?.response?.data?.error?.message ||
5 | error?.response?.data?.message ||
6 | error?.response?.statusText ||
7 | error?.response?.message ||
8 | "Unknown error"
9 | );
10 | }
11 |
12 | if (error.request) {
13 | return "No response received from server";
14 | }
15 |
16 | return `Error: ${error.message}`;
17 | };
18 |
19 | export const getErrorStatusCode = (error: any): number => {
20 | if (error.response) {
21 | return error.response.status;
22 | }
23 |
24 | if (error.request) {
25 | return 500; // No response received, consider it a server error
26 | }
27 |
28 | return 500; // Default to server error for other cases
29 | };
30 |
--------------------------------------------------------------------------------
/frontend/src/components/custom-bots/loading-detail-state.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Skeleton } from "@/components/ui/skeleton";
3 |
4 | export const LoadingState = () => (
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | );
23 |
--------------------------------------------------------------------------------
/frontend/src/components/ai-agent/ui/label.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import * as LabelPrimitive from "@radix-ui/react-label";
3 | import { cva, type VariantProps } from "class-variance-authority";
4 |
5 | import { cn } from "@/lib/utils";
6 |
7 | const labelVariants = cva(
8 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
9 | );
10 |
11 | const Label = React.forwardRef<
12 | React.ElementRef,
13 | React.ComponentPropsWithoutRef &
14 | VariantProps
15 | >(({ className, ...props }, ref) => (
16 |
21 | ));
22 | Label.displayName = LabelPrimitive.Root.displayName;
23 |
24 | export { Label };
25 |
--------------------------------------------------------------------------------
/runtime/internal/bot-runner/server/master.go:
--------------------------------------------------------------------------------
1 | package server
2 |
3 | import (
4 | "os"
5 | core "runtime/internal/core"
6 | "runtime/internal/util"
7 | )
8 |
9 | type BotRunnerMaster struct {
10 | master *core.Master
11 | }
12 |
13 | func (m *BotRunnerMaster) Start() {
14 | util.LogMaster("Starting Bot Runner")
15 | m.master.Start()
16 | }
17 |
18 | func (m *BotRunnerMaster) Stop() {
19 | util.LogMaster("Stopping Bot Runner")
20 | m.master.Stop()
21 | }
22 |
23 | func NewMaster(
24 | mongoUri string,
25 | dbName string,
26 | collectionName string,
27 | address string,
28 | ) *BotRunnerMaster {
29 | baseMaster, err := core.NewMaster(mongoUri, dbName, collectionName, address)
30 | if err != nil {
31 | util.LogMaster("Failed to create master: %v", err)
32 | os.Exit(1)
33 | }
34 | return &BotRunnerMaster{
35 | master: baseMaster,
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/docs/src/components/ui/label.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as LabelPrimitive from "@radix-ui/react-label";
5 | import { cva, type VariantProps } from "class-variance-authority";
6 |
7 | import { cn } from "@/lib/utils";
8 |
9 | const labelVariants = cva(
10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
11 | );
12 |
13 | const Label = React.forwardRef<
14 | React.ElementRef,
15 | React.ComponentPropsWithoutRef &
16 | VariantProps
17 | >(({ className, ...props }, ref) => (
18 |
23 | ));
24 | Label.displayName = LabelPrimitive.Root.displayName;
25 |
26 | export { Label };
27 |
--------------------------------------------------------------------------------
/frontend/src/components/ui/label.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as LabelPrimitive from "@radix-ui/react-label";
5 | import { cva, type VariantProps } from "class-variance-authority";
6 |
7 | import { cn } from "@/lib/utils";
8 |
9 | const labelVariants = cva(
10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
11 | );
12 |
13 | const Label = React.forwardRef<
14 | React.ElementRef,
15 | React.ComponentPropsWithoutRef &
16 | VariantProps
17 | >(({ className, ...props }, ref) => (
18 |
23 | ));
24 | Label.displayName = LabelPrimitive.Root.displayName;
25 |
26 | export { Label };
27 |
--------------------------------------------------------------------------------
/frontend/src/components/ai-agent/artifacts/FileTree.tsx:
--------------------------------------------------------------------------------
1 | import { ScrollArea } from "@/components/ui/scroll-area";
2 | import { FileTreeItem } from "./FileTreeItem";
3 | import { ArtifactFile } from "@/types";
4 |
5 | interface FileTreeProps {
6 | files: ArtifactFile[];
7 | selectedFile: ArtifactFile | null;
8 | onFileSelect: (file: ArtifactFile) => void;
9 | }
10 |
11 | export function FileTree({ files, selectedFile, onFileSelect }: FileTreeProps) {
12 | return (
13 |
14 |
15 | {files.map((file) => (
16 |
23 | ))}
24 |
25 |
26 | );
27 | }
28 |
--------------------------------------------------------------------------------
/docs/src/components/ui/input.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | import { cn } from "@/lib/utils";
4 |
5 | const Input = React.forwardRef>(
6 | ({ className, type, ...props }, ref) => {
7 | return (
8 |
17 | );
18 | },
19 | );
20 | Input.displayName = "Input";
21 |
22 | export { Input };
23 |
--------------------------------------------------------------------------------
/frontend/src/components/ui/input.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | import { cn } from "@/lib/utils";
4 |
5 | const Input = React.forwardRef>(
6 | ({ className, type, ...props }, ref) => {
7 | return (
8 |
17 | );
18 | },
19 | );
20 | Input.displayName = "Input";
21 |
22 | export { Input };
23 |
--------------------------------------------------------------------------------
/site/src/components/ui/input.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | import { cn } from "@/lib/utils";
4 |
5 | const Input = React.forwardRef>(
6 | ({ className, type, ...props }, ref) => {
7 | return (
8 |
17 | );
18 | },
19 | );
20 | Input.displayName = "Input";
21 |
22 | export { Input };
23 |
--------------------------------------------------------------------------------
/frontend/src/components/auth/with-auth.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import React, { useEffect } from "react";
3 | import { useRouter } from "next/navigation";
4 | import { useAuth } from "@/contexts/auth-context";
5 |
6 | export function withAuth(Component: React.ComponentType
) {
7 | const ProtectedRoute = function (props: P) {
8 | const { user, loading } = useAuth();
9 | const router = useRouter();
10 |
11 | useEffect(() => {
12 | if (!loading && !user) {
13 | router.replace("/login");
14 | }
15 | }, [user, loading, router]);
16 |
17 | // Show nothing while loading or redirecting
18 | if (loading || !user) {
19 | return null;
20 | }
21 |
22 | // If authenticated, render component
23 | return ;
24 | };
25 |
26 | ProtectedRoute.displayName = "ProtectedRoute";
27 | return ProtectedRoute;
28 | }
29 |
--------------------------------------------------------------------------------
/runtime/internal/backtest-runner/server/master.go:
--------------------------------------------------------------------------------
1 | package server
2 |
3 | import (
4 | "os"
5 | core "runtime/internal/core"
6 | "runtime/internal/util"
7 | )
8 |
9 | type BacktestRunnerMaster struct {
10 | master *core.Master
11 | }
12 |
13 | func (m *BacktestRunnerMaster) Start() {
14 | util.LogMaster("Starting Backtest Runner")
15 | m.master.Start()
16 | }
17 |
18 | func (m *BacktestRunnerMaster) Stop() {
19 | util.LogMaster("Stopping Backtest Runner")
20 | m.master.Stop()
21 | }
22 |
23 | func NewMaster(
24 | mongoUri string,
25 | dbName string,
26 | collectionName string,
27 | address string,
28 | ) *BacktestRunnerMaster {
29 | baseMaster, err := core.NewMaster(mongoUri, dbName, collectionName, address)
30 | if err != nil {
31 | util.LogMaster("Failed to create master: %v", err)
32 | os.Exit(1)
33 | }
34 | return &BacktestRunnerMaster{
35 | master: baseMaster,
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/site/src/app/page.tsx:
--------------------------------------------------------------------------------
1 | import { Navigation } from "@/components/landing-page/navigation";
2 | import { Footer } from "@/components/landing-page/footer";
3 | import { HeroSection } from "@/components/landing-page/hero";
4 | import { FeaturesSection } from "@/components/landing-page/features";
5 | import { QuickStartSection } from "@/components/landing-page/quick-start";
6 | import { CodeShowcaseSection } from "@/components/landing-page/code-showcase";
7 | import { ArchitectureSection } from "@/components/landing-page/architecture";
8 |
9 | export default function LandingPage() {
10 | return (
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/services/the0-ai/api/schemas.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel
2 | from typing import List, Optional, Dict, Any, Literal
3 |
4 |
5 | class ChatRequest(BaseModel):
6 | message: str
7 | session_id: Optional[str] = None
8 |
9 |
10 | class ChatResponse(BaseModel):
11 | response: str
12 | session_id: str
13 | artifacts: Optional[List[str]] = None
14 |
15 |
16 | class ArtifactResponse(BaseModel):
17 | filename: str
18 | content: str
19 | version: int
20 |
21 |
22 | class HealthResponse(BaseModel):
23 | status: str
24 | message: str
25 |
26 |
27 | class ApiKeyRequest(BaseModel):
28 | api_key: str
29 |
30 |
31 | class StreamChunk(BaseModel):
32 | type: Literal["content", "artifacts", "complete", "error"]
33 | content: Optional[str] = None
34 | artifacts: Optional[List[str]] = None
35 | session_id: Optional[str] = None
36 | error: Optional[str] = None
37 |
--------------------------------------------------------------------------------
/api/src/custom-bot/custom-bot.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from "@nestjs/common";
2 | import { CustomBotController } from "./custom-bot.controller";
3 | import { CustomBotService } from "./custom-bot.service";
4 | import { CustomBotRepository } from "./custom-bot.repository";
5 | import { StorageService } from "./storage.service";
6 | import { CustomBotEventsService } from "./custom-bot-events.service";
7 | import { ApiKeyModule } from "@/api-key/api-key.module";
8 | import { NatsModule } from "@/nats/nats.module";
9 | import { ConfigModule } from "@nestjs/config";
10 |
11 | @Module({
12 | imports: [ConfigModule, ApiKeyModule, NatsModule],
13 | controllers: [CustomBotController],
14 | providers: [
15 | CustomBotService,
16 | CustomBotRepository,
17 | StorageService,
18 | CustomBotEventsService,
19 | ],
20 | exports: [CustomBotService, CustomBotRepository],
21 | })
22 | export class CustomBotModule {}
23 |
--------------------------------------------------------------------------------
/frontend/src/components/ai-agent/ui/textarea.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | import { cn } from "@/lib/utils";
4 |
5 | export interface TextareaProps
6 | extends React.TextareaHTMLAttributes {}
7 |
8 | const Textarea = React.forwardRef(
9 | ({ className, ...props }, ref) => {
10 | return (
11 |
19 | );
20 | },
21 | );
22 | Textarea.displayName = "Textarea";
23 |
24 | export { Textarea };
25 |
--------------------------------------------------------------------------------
/runtime/internal/bot-scheduler/server/master.go:
--------------------------------------------------------------------------------
1 | package server
2 |
3 | import (
4 | "os"
5 | core "runtime/internal/core"
6 | "runtime/internal/util"
7 | )
8 |
9 | type BotSchedulerMaster struct {
10 | master *core.Master
11 | }
12 |
13 | func (m *BotSchedulerMaster) Start() {
14 | util.LogMaster("Starting Bot Scheduler")
15 | m.master.Start()
16 | }
17 |
18 | func (m *BotSchedulerMaster) Stop() {
19 | util.LogMaster("Stopping Bot Scheduler")
20 | m.master.Stop()
21 | }
22 |
23 | func NewMaster(
24 | mongoUri string,
25 | dbName string,
26 | collectionName string,
27 | address string,
28 | ) *BotSchedulerMaster {
29 | baseMaster, err := core.NewMaster(
30 | mongoUri,
31 | dbName,
32 | collectionName,
33 | address,
34 | )
35 | if err != nil {
36 | util.LogMaster("Failed to create master: %v", err)
37 | os.Exit(1)
38 | }
39 | return &BotSchedulerMaster{
40 | master: baseMaster,
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/frontend/src/components/ai-agent/ui/separator.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import * as SeparatorPrimitive from "@radix-ui/react-separator";
3 |
4 | import { cn } from "@/lib/utils";
5 |
6 | const Separator = React.forwardRef<
7 | React.ElementRef,
8 | React.ComponentPropsWithoutRef
9 | >(
10 | (
11 | { className, orientation = "horizontal", decorative = true, ...props },
12 | ref,
13 | ) => (
14 |
25 | ),
26 | );
27 | Separator.displayName = SeparatorPrimitive.Root.displayName;
28 |
29 | export { Separator };
30 |
--------------------------------------------------------------------------------
/frontend/src/lib/auth/types.ts:
--------------------------------------------------------------------------------
1 | export interface AuthUser {
2 | id: string;
3 | username: string;
4 | email: string;
5 | firstName?: string;
6 | lastName?: string;
7 | isActive: boolean;
8 | isEmailVerified: boolean;
9 | }
10 |
11 | export interface LoginCredentials {
12 | email: string;
13 | password: string;
14 | }
15 |
16 | export interface RegisterCredentials {
17 | username: string;
18 | email: string;
19 | password: string;
20 | firstName?: string;
21 | lastName?: string;
22 | }
23 |
24 | export interface AuthResponse {
25 | token: string;
26 | user: AuthUser;
27 | }
28 |
29 | export interface ApiResponse {
30 | success: boolean;
31 | data?: T;
32 | message?: string;
33 | }
34 |
35 | export interface ApiError {
36 | message: string;
37 | statusCode?: number;
38 | }
39 |
40 | export interface Result {
41 | success: boolean;
42 | data?: T;
43 | error?: E;
44 | }
45 |
--------------------------------------------------------------------------------
/services/the0-ai/the0/agents/base.py:
--------------------------------------------------------------------------------
1 | """
2 | Shared utilities and base configurations for the0 agents.
3 | """
4 |
5 | # Agent configuration constants
6 | DEFAULT_MODEL = "gemini-2.5-flash"
7 | DEFAULT_TEMPERATURE = 0.7
8 |
9 | # State management keys (used in Story 5)
10 | STATE_KEY_RESEARCH = "research_data"
11 | STATE_KEY_BOT_METADATA = "bot_metadata"
12 |
13 |
14 | # Shared utility functions
15 | def format_citations(sources: list) -> str:
16 | """
17 | Format sources as markdown citations.
18 |
19 | Args:
20 | sources: List of source dictionaries with 'title' and 'url' keys
21 |
22 | Returns:
23 | Markdown-formatted citations string
24 | """
25 | citations = []
26 | for i, source in enumerate(sources, 1):
27 | title = source.get("title", "Source")
28 | url = source.get("url", "")
29 | citations.append(f"{i}. [{title}]({url})")
30 | return "\n".join(citations)
31 |
--------------------------------------------------------------------------------
/docs/src/components/ui/separator.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as SeparatorPrimitive from "@radix-ui/react-separator";
5 |
6 | import { cn } from "@/lib/utils";
7 |
8 | const Separator = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(
12 | (
13 | { className, orientation = "horizontal", decorative = true, ...props },
14 | ref,
15 | ) => (
16 |
27 | ),
28 | );
29 | Separator.displayName = SeparatorPrimitive.Root.displayName;
30 |
31 | export { Separator };
32 |
--------------------------------------------------------------------------------
/.github/workflows/cli.yml:
--------------------------------------------------------------------------------
1 | name: CLI Service
2 |
3 | on:
4 | push:
5 | branches: [ main, develop ]
6 | paths:
7 | - 'cli/**'
8 | - '.github/workflows/cli.yml'
9 | pull_request:
10 | branches: [ main, develop ]
11 | paths:
12 | - 'cli/**'
13 | - '.github/workflows/cli.yml'
14 |
15 | jobs:
16 | test:
17 | runs-on: ubuntu-latest
18 |
19 | steps:
20 | - name: Checkout code
21 | uses: actions/checkout@v4
22 |
23 | - name: Setup Go
24 | uses: actions/setup-go@v5
25 | with:
26 | go-version: '1.24.1'
27 | cache-dependency-path: cli/go.sum
28 |
29 | - name: Download dependencies
30 | working-directory: ./cli
31 | run: go mod download
32 |
33 | - name: Run tests
34 | working-directory: ./cli
35 | run: go test ./tests/...
36 |
37 | - name: Build CLI binary
38 | working-directory: ./cli
39 | run: go build -o the0 .
--------------------------------------------------------------------------------
/api/src/backtest/backtest.module.ts:
--------------------------------------------------------------------------------
1 | import { Module, forwardRef } from "@nestjs/common";
2 | import { ConfigModule } from "@nestjs/config";
3 | import { BacktestService } from "./backtest.service";
4 | import { BacktestController } from "./backtest.controller";
5 | import { BacktestRepository } from "./backtest.repository";
6 | import { BacktestValidator } from "./backtest.validator";
7 | import { BacktestEventsService } from "./backtest-events.service";
8 | import { CustomBotModule } from "@/custom-bot/custom-bot.module";
9 | import { ApiKeyModule } from "@/api-key/api-key.module";
10 | import { NatsModule } from "@/nats/nats.module";
11 | @Module({
12 | imports: [ConfigModule, ApiKeyModule, CustomBotModule, NatsModule],
13 | controllers: [BacktestController],
14 | providers: [
15 | BacktestService,
16 | BacktestRepository,
17 | BacktestValidator,
18 | BacktestEventsService,
19 | ],
20 | })
21 | export class BacktestModule {}
22 |
--------------------------------------------------------------------------------
/docs/src/components/ui/progress.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as ProgressPrimitive from "@radix-ui/react-progress";
5 |
6 | import { cn } from "@/lib/utils";
7 |
8 | const Progress = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(({ className, value, ...props }, ref) => (
12 |
20 |
24 |
25 | ));
26 | Progress.displayName = ProgressPrimitive.Root.displayName;
27 |
28 | export { Progress };
29 |
--------------------------------------------------------------------------------
/frontend/src/components/ui/separator.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as SeparatorPrimitive from "@radix-ui/react-separator";
5 |
6 | import { cn } from "@/lib/utils";
7 |
8 | const Separator = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(
12 | (
13 | { className, orientation = "horizontal", decorative = true, ...props },
14 | ref,
15 | ) => (
16 |
27 | ),
28 | );
29 | Separator.displayName = SeparatorPrimitive.Root.displayName;
30 |
31 | export { Separator };
32 |
--------------------------------------------------------------------------------
/frontend/src/components/ui/progress.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as ProgressPrimitive from "@radix-ui/react-progress";
5 |
6 | import { cn } from "@/lib/utils";
7 |
8 | const Progress = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(({ className, value, ...props }, ref) => (
12 |
20 |
24 |
25 | ));
26 | Progress.displayName = ProgressPrimitive.Root.displayName;
27 |
28 | export { Progress };
29 |
--------------------------------------------------------------------------------
/frontend/src/app/api/ai-agent/chat/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest, NextResponse } from "next/server";
2 | import { getAiAgentUrl } from "@/lib/config";
3 |
4 | export async function POST(request: NextRequest) {
5 | try {
6 | const body = await request.json();
7 | const aiAgentUrl = getAiAgentUrl();
8 |
9 | const response = await fetch(`${aiAgentUrl}/chat`, {
10 | method: "POST",
11 | headers: {
12 | "Content-Type": "application/json",
13 | },
14 | body: JSON.stringify(body),
15 | });
16 |
17 | if (!response.ok) {
18 | throw new Error(`AI Agent API error: ${response.statusText}`);
19 | }
20 |
21 | const data = await response.json();
22 | return NextResponse.json(data);
23 | } catch (error) {
24 | console.error("AI Agent chat error:", error);
25 | return NextResponse.json(
26 | { error: "Failed to communicate with AI agent" },
27 | { status: 500 },
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/services/0vers33r/src/services/firestore_database.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, Any
2 |
3 | from firebase_admin import firestore
4 |
5 |
6 | class FirestoreDatabase:
7 | """Firestore database implementation"""
8 |
9 | def __init__(self):
10 | self.db = firestore.client()
11 |
12 | def update_bot_status(
13 | self, bot_id: str, status: str, review_data: Dict[str, Any]
14 | ) -> None:
15 | """Update bot status in Firestore"""
16 | # Replace placeholder with actual server timestamp
17 | if review_data.get("reviewedAt") == "SERVER_TIMESTAMP":
18 | review_data["reviewedAt"] = firestore.SERVER_TIMESTAMP
19 |
20 | bot_ref = self.db.collection("custom-bots").document(bot_id)
21 | bot_ref.update(
22 | {
23 | "status": status,
24 | "review": review_data,
25 | "updatedAt": firestore.SERVER_TIMESTAMP,
26 | }
27 | )
28 |
--------------------------------------------------------------------------------
/frontend/src/components/ai-agent/ui/input.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | import { cn } from "@/lib/utils";
4 |
5 | export interface InputProps
6 | extends React.InputHTMLAttributes {}
7 |
8 | const Input = React.forwardRef(
9 | ({ className, type, ...props }, ref) => {
10 | return (
11 |
20 | );
21 | },
22 | );
23 | Input.displayName = "Input";
24 |
25 | export { Input };
26 |
--------------------------------------------------------------------------------
/services/0vers33r/src/tests/test_samples/js_code_injection.js:
--------------------------------------------------------------------------------
1 | // JavaScript Code Injection Test Sample
2 | // This file contains patterns that should trigger JavaScript YARA rules
3 |
4 | const userInput = process.argv[2] || 'alert("test")';
5 |
6 | // Critical: eval() usage
7 | const result = eval(userInput);
8 |
9 | // Critical: Function constructor
10 | const maliciousFunc = new Function('return ' + userInput)();
11 |
12 | // Critical: VM execution
13 | const vm = require('vm');
14 | vm.runInNewContext(userInput);
15 |
16 | // Suspicious: Dynamic imports with eval
17 | const dynamicModule = import(eval('module_name'));
18 |
19 | // Suspicious: Obfuscated code patterns
20 | const obfuscated = String.fromCharCode(97, 108, 101, 114, 116);
21 |
22 | // DOM manipulation with user input (XSS potential)
23 | if (typeof document !== 'undefined') {
24 | document.getElementById('content').innerHTML = userInput;
25 | }
26 |
27 | console.log('Code injection test completed');
--------------------------------------------------------------------------------
/frontend/src/components/ui/toaster.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useToast } from "@/hooks/use-toast";
4 | import {
5 | Toast,
6 | ToastClose,
7 | ToastDescription,
8 | ToastProvider,
9 | ToastTitle,
10 | ToastViewport,
11 | } from "@/components/ui/toast";
12 |
13 | export function Toaster() {
14 | const { toasts } = useToast();
15 |
16 | return (
17 |
18 | {toasts.map(function ({ id, title, description, action, ...props }) {
19 | return (
20 |
21 |
22 | {title && {title} }
23 | {description && (
24 | {description}
25 | )}
26 |
27 | {action}
28 |
29 |
30 | );
31 | })}
32 |
33 |
34 | );
35 | }
36 |
--------------------------------------------------------------------------------
/frontend/src/app/register/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useEffect } from "react";
4 | import { useRouter } from "next/navigation";
5 | import { useAuth } from "@/contexts/auth-context";
6 | import { RegisterForm } from "@/components/auth/register-form";
7 | import { NavigationMenu } from "@/components/landing-page/navigation-menu";
8 |
9 | export default function RegisterPage() {
10 | const router = useRouter();
11 | const { user } = useAuth();
12 |
13 | useEffect(() => {
14 | if (user) {
15 | router.push("/dashboard");
16 | }
17 | }, [user, router]);
18 |
19 | return (
20 |
21 | {/* Navigation */}
22 |
23 |
24 | {/* Login Form */}
25 |
30 |
31 | );
32 | }
33 |
--------------------------------------------------------------------------------
/api/src/bot/bot.module.ts:
--------------------------------------------------------------------------------
1 | import { Module, forwardRef } from "@nestjs/common";
2 | import { BotService } from "./bot.service";
3 | import { BotController } from "./bot.controller";
4 | import { BotRepository } from "./bot.repository";
5 | import { HttpModule } from "@nestjs/axios";
6 | import { BotValidator } from "./bot.validator";
7 | import { ConfigModule } from "@nestjs/config";
8 | import { CustomBotModule } from "@/custom-bot/custom-bot.module";
9 | import { ApiKeyModule } from "@/api-key/api-key.module";
10 | // UserBotsModule removed for OSS version
11 | import { NatsModule } from "@/nats/nats.module";
12 | // FeatureGateModule removed for OSS version
13 |
14 | @Module({
15 | imports: [
16 | HttpModule,
17 | ConfigModule,
18 | CustomBotModule,
19 | ApiKeyModule,
20 | NatsModule,
21 | ],
22 | controllers: [BotController],
23 | providers: [BotService, BotRepository, BotValidator],
24 | exports: [BotService, BotRepository, BotValidator],
25 | })
26 | export class BotModule {}
27 |
--------------------------------------------------------------------------------
/site/public/globe.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/api/src/auth/auth.module.ts:
--------------------------------------------------------------------------------
1 | import { Global, Module } from "@nestjs/common";
2 | import { JwtModule } from "@nestjs/jwt";
3 | import { PassportModule } from "@nestjs/passport";
4 | import { AuthController } from "./auth.controller";
5 | import { AuthService } from "./auth.service";
6 | import { JwtStrategy } from "./jwt.strategy";
7 | import { ApiKeyModule } from "@/api-key/api-key.module";
8 |
9 | @Global()
10 | @Module({
11 | imports: [
12 | PassportModule.register({ defaultStrategy: "jwt" }),
13 | JwtModule.register({
14 | secret:
15 | process.env.JWT_SECRET || "the0-oss-jwt-secret-change-in-production",
16 | signOptions: {
17 | expiresIn: process.env.JWT_EXPIRES_IN || "24h",
18 | issuer: "the0-oss-api",
19 | audience: "the0-oss-clients",
20 | },
21 | }),
22 | ApiKeyModule,
23 | ],
24 | providers: [JwtStrategy, AuthService],
25 | exports: [PassportModule, JwtModule, AuthService],
26 | controllers: [AuthController],
27 | })
28 | export class AuthModule {}
29 |
--------------------------------------------------------------------------------
/cli/.the0ignore.example:
--------------------------------------------------------------------------------
1 | # Example .the0ignore file for the0 custom bot deployment
2 |
3 | # Exclude log files but keep important ones
4 | *.log
5 | !production.log
6 | !important.log
7 |
8 | # Exclude temporary files
9 | *.tmp
10 | *.temp
11 | **/*.cache
12 |
13 | # Exclude test directories and files
14 | test/
15 | tests/
16 | __tests__/
17 | *_test.py
18 | test_*.py
19 |
20 | # Exclude documentation (except main README)
21 | docs/**/*.md
22 | !docs/README.md
23 |
24 | # Exclude development and build artifacts
25 | .env
26 | .env.local
27 | build/
28 | dist/
29 | **/*.pyc
30 | **/*.pyo
31 | __pycache__/
32 |
33 | # Exclude OS-specific files
34 | .DS_Store
35 | Thumbs.db
36 | desktop.ini
37 |
38 | # Exclude IDE/editor files
39 | .vscode/
40 | .idea/
41 | *.swp
42 | *.swo
43 | *~
44 |
45 | # Exclude configuration files except production
46 | config_*
47 | !config_production.yaml
48 | !config_prod.json
49 |
50 | # Note: vendor/ and node_modules/ are automatically protected
51 | # and will never be ignored regardless of patterns above
--------------------------------------------------------------------------------
/frontend/src/types/ai-agent.ts:
--------------------------------------------------------------------------------
1 | export interface Message {
2 | id: string;
3 | content: string;
4 | role: "user" | "assistant" | "system";
5 | timestamp: Date;
6 | isTyping?: boolean;
7 | artifacts?: string[];
8 | isStreaming?: boolean;
9 | isComplete?: boolean;
10 | }
11 |
12 | export interface ArtifactFile {
13 | id: string;
14 | name: string;
15 | content: string;
16 | language: string;
17 | type: "file" | "folder";
18 | children?: ArtifactFile[];
19 | isExpanded?: boolean;
20 | }
21 |
22 | export interface ChatRequest {
23 | message: string;
24 | session_id?: string;
25 | }
26 |
27 | export interface ChatResponse {
28 | response: string;
29 | session_id: string;
30 | artifacts?: string[];
31 | }
32 |
33 | export interface StreamChunk {
34 | type: "content" | "artifacts" | "complete" | "error";
35 | content?: string;
36 | artifacts?: string[];
37 | session_id?: string;
38 | error?: string;
39 | }
40 |
41 | export interface ApiError {
42 | message: string;
43 | status?: number;
44 | }
45 |
--------------------------------------------------------------------------------
/services/the0-ai/Dockerfile:
--------------------------------------------------------------------------------
1 | # Use Python slim image
2 | FROM python:3.11-slim
3 |
4 | # Set working directory
5 | WORKDIR /app
6 |
7 | # Install system dependencies
8 | RUN apt-get update && apt-get install -y \
9 | gcc \
10 | && rm -rf /var/lib/apt/lists/*
11 |
12 | # Copy requirements and install Python dependencies
13 | COPY requirements.txt .
14 | RUN pip install --no-cache-dir -r requirements.txt
15 |
16 | # Copy application code
17 | COPY . .
18 |
19 | # Set environment variables
20 | ENV PYTHONPATH=/app
21 | ENV PYTHONUNBUFFERED=1
22 |
23 | # Create non-root user
24 | RUN groupadd -r appuser && useradd -r -g appuser appuser
25 | RUN chown -R appuser:appuser /app
26 | USER appuser
27 |
28 | # Expose port
29 | EXPOSE 8000
30 |
31 | # Health check
32 | HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
33 | CMD python -c "import requests; requests.get('http://localhost:8000/health', timeout=5)"
34 |
35 | # Make entrypoint executable and start
36 | RUN chmod +x entrypoint.sh
37 | CMD ["./entrypoint.sh"]
--------------------------------------------------------------------------------
/frontend/src/components/ai-agent/ui/sonner.tsx:
--------------------------------------------------------------------------------
1 | import { useTheme } from "next-themes";
2 | import { Toaster as Sonner } from "sonner";
3 |
4 | type ToasterProps = React.ComponentProps;
5 |
6 | const Toaster = ({ ...props }: ToasterProps) => {
7 | const { theme = "system" } = useTheme();
8 |
9 | return (
10 |
26 | );
27 | };
28 |
29 | export { Toaster };
30 |
--------------------------------------------------------------------------------
/frontend/src/app/api/ai-agent/sessions/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest, NextResponse } from "next/server";
2 | import { getAiAgentUrl } from "@/lib/config";
3 |
4 | export async function GET(request: NextRequest) {
5 | try {
6 | const { searchParams } = new URL(request.url);
7 | const userId = searchParams.get("user_id") || "default-user";
8 | const aiAgentUrl = getAiAgentUrl();
9 |
10 | const response = await fetch(
11 | `${aiAgentUrl}/chat/sessions?user_id=${userId}`,
12 | {
13 | method: "GET",
14 | headers: {
15 | "Content-Type": "application/json",
16 | },
17 | },
18 | );
19 |
20 | if (!response.ok) {
21 | throw new Error(`AI Agent API error: ${response.statusText}`);
22 | }
23 |
24 | const data = await response.json();
25 | return NextResponse.json(data);
26 | } catch (error) {
27 | console.error("AI Agent sessions error:", error);
28 | return NextResponse.json(
29 | { error: "Failed to fetch sessions" },
30 | { status: 500 },
31 | );
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/runtime/internal/docker-runner/entrypoints/code_entrypoint_factory.go:
--------------------------------------------------------------------------------
1 | package entrypoints
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | type codeEntrypointFactory struct {
8 | entryPointType string
9 | runtime string
10 | }
11 |
12 | func NewCodeEntrypointFactory(
13 | entryPointType, runtime string,
14 | ) *codeEntrypointFactory {
15 | return &codeEntrypointFactory{
16 | entryPointType: entryPointType,
17 | runtime: runtime,
18 | }
19 | }
20 |
21 | func (f *codeEntrypointFactory) GetCode() (string, error) {
22 | switch f.entryPointType {
23 | case "backtest":
24 | switch f.runtime {
25 | case "nodejs20":
26 | return NodeJsBacktestEntrypoint, nil
27 | case "python3", "python3.11":
28 | return PythonBacktestEntrypoint, nil
29 | }
30 | case "bot":
31 | switch f.runtime {
32 | case "nodejs20":
33 | return NodeJsBotEntrypoint, nil
34 | case "python3", "python3.11":
35 | return PythonBotEntrypoint, nil
36 | }
37 | }
38 | return "", fmt.Errorf("unsupported entry point type or runtime: %s, %s", f.entryPointType, f.runtime)
39 | }
40 |
--------------------------------------------------------------------------------
/api/src/app.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from "@nestjs/common";
2 | import { AppController } from "./app.controller";
3 | import { AppService } from "./app.service";
4 | import { BotModule } from "./bot/bot.module";
5 | import { AuthModule } from "./auth/auth.module";
6 | import { BacktestModule } from "./backtest/backtest.module";
7 | import { ConfigModule } from "@nestjs/config";
8 | import { CustomBotModule } from "./custom-bot/custom-bot.module";
9 | import { ApiKeyModule } from "./api-key/api-key.module";
10 | import { LogsModule } from "./logs/logs.module";
11 | import { NatsModule } from "./nats/nats.module";
12 | import configuration from "./config/configuration";
13 |
14 | @Module({
15 | imports: [
16 | ConfigModule.forRoot({
17 | load: [configuration],
18 | isGlobal: true,
19 | }),
20 | BotModule,
21 | AuthModule,
22 | BacktestModule,
23 | CustomBotModule,
24 | ApiKeyModule,
25 | LogsModule,
26 | NatsModule,
27 | ],
28 | controllers: [AppController],
29 | providers: [AppService],
30 | })
31 | export class AppModule {}
32 |
--------------------------------------------------------------------------------
/frontend/src/app/install-cli/layout.tsx:
--------------------------------------------------------------------------------
1 | import { Metadata } from "next";
2 | import { NavigationMenu } from "@/components/landing-page/navigation-menu";
3 |
4 | export const metadata: Metadata = {
5 | title: "Install THE0 CLI | THE0 Platform",
6 | description:
7 | "Download and install the THE0 CLI for managing trading bots, deploying algorithms, and interacting with the platform.",
8 | openGraph: {
9 | title: "Install THE0 CLI",
10 | description:
11 | "Get started with THE0 by installing our command-line interface.",
12 | type: "website",
13 | },
14 | twitter: {
15 | card: "summary_large_image",
16 | title: "Install THE0 CLI",
17 | description:
18 | "Download and install the THE0 CLI for managing trading bots from the command line.",
19 | },
20 | };
21 |
22 | export default function InstallCliLayout({
23 | children,
24 | }: {
25 | children: React.ReactNode;
26 | }) {
27 | return (
28 |
29 |
30 | {children}
31 |
32 | );
33 | }
34 |
--------------------------------------------------------------------------------
/docker/.env.example:
--------------------------------------------------------------------------------
1 | # The0 OSS Configuration
2 | # Copy this file to .env and modify the values as needed
3 |
4 | # Version
5 | THE0_VERSION=1.0.0
6 |
7 | # Docker Images (change these to use your own registry)
8 | THE0_API_IMAGE=the0/api:latest
9 | THE0_RUNTIME_IMAGE=the0/runtime:latest
10 | THE0_FRONTEND_IMAGE=the0/frontend:latest
11 |
12 | # Service Ports
13 | API_PORT=3000
14 | FRONTEND_PORT=3001
15 | RUNTIME_PORT=8080
16 |
17 | # Infrastructure Ports
18 | POSTGRES_PORT=5432
19 | REDIS_PORT=6379
20 | NATS_PORT=4222
21 | NATS_MONITOR_PORT=8222
22 | MINIO_API_PORT=9000
23 | MINIO_CONSOLE_PORT=9001
24 |
25 | # Database Configuration
26 | POSTGRES_PASSWORD=the0_secure_password_change_me
27 |
28 | # MinIO Configuration
29 | MINIO_USER=the0admin
30 | MINIO_PASSWORD=the0_secure_password_change_me
31 |
32 | # Security Configuration (CRITICAL: Change in production!)
33 | JWT_SECRET=your-super-secret-jwt-key-at-least-32-characters-long-change-this
34 |
35 | # Runtime Configuration
36 | LOG_LEVEL=info
37 | MAX_CONCURRENT_BOTS=10
38 | BOT_EXECUTION_TIMEOUT=300s
39 | MAX_MEMORY_MB=512
40 | MAX_CPU_SHARES=1024
--------------------------------------------------------------------------------
/frontend/src/stores/ai-agent/settingsStore.ts:
--------------------------------------------------------------------------------
1 | import { create } from "zustand";
2 | import { persist } from "zustand/middleware";
3 |
4 | interface SettingsStore {
5 | streamingEnabled: boolean;
6 | typewriterEnabled: boolean;
7 | typewriterSpeed: number; // Characters per second
8 | setStreamingEnabled: (enabled: boolean) => void;
9 | setTypewriterEnabled: (enabled: boolean) => void;
10 | setTypewriterSpeed: (speed: number) => void;
11 | }
12 |
13 | export const useSettingsStore = create()(
14 | persist(
15 | (set) => ({
16 | streamingEnabled: true, // Default to enabled
17 | typewriterEnabled: true, // Default to enabled
18 | typewriterSpeed: 50, // Default 50 characters per second
19 | setStreamingEnabled: (enabled) => set({ streamingEnabled: enabled }),
20 | setTypewriterEnabled: (enabled) => set({ typewriterEnabled: enabled }),
21 | setTypewriterSpeed: (speed) =>
22 | set({ typewriterSpeed: Math.max(10, Math.min(200, speed)) }), // Clamp between 10-200
23 | }),
24 | {
25 | name: "settings-storage",
26 | },
27 | ),
28 | );
29 |
--------------------------------------------------------------------------------
/frontend/src/app/api/ai-agent/artifacts/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest, NextResponse } from "next/server";
2 | import { getAiAgentUrl } from "@/lib/config";
3 |
4 | export async function GET(request: NextRequest) {
5 | try {
6 | const { searchParams } = new URL(request.url);
7 | const sessionId = searchParams.get("session_id");
8 | const aiAgentUrl = getAiAgentUrl();
9 |
10 | let url = `${aiAgentUrl}/artifacts`;
11 | if (sessionId) {
12 | url = `${aiAgentUrl}/artifacts/session/${sessionId}`;
13 | }
14 |
15 | const response = await fetch(url, {
16 | method: "GET",
17 | headers: {
18 | "Content-Type": "application/json",
19 | },
20 | });
21 |
22 | if (!response.ok) {
23 | throw new Error(`AI Agent API error: ${response.statusText}`);
24 | }
25 |
26 | const data = await response.json();
27 | return NextResponse.json(data);
28 | } catch (error) {
29 | console.error("AI Agent artifacts error:", error);
30 | return NextResponse.json(
31 | { error: "Failed to fetch artifacts" },
32 | { status: 500 },
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/frontend/src/app/api/custom-bots/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest, NextResponse } from "next/server";
2 | import { withAdminAuth } from "@/lib/middleware/admin-auth";
3 |
4 | export async function GET(req: NextRequest) {
5 | return withAdminAuth(req, async (req: NextRequest) => {
6 | const token = req.headers.get("Authorization");
7 |
8 | try {
9 | const response = await fetch(`${process.env.BOT_API_URL}/custom-bots`, {
10 | method: "GET",
11 | headers: {
12 | "Content-Type": "application/json",
13 | Authorization: token,
14 | } as HeadersInit,
15 | });
16 |
17 | if (!response.ok) {
18 | return NextResponse.json(
19 | { error: "Failed to fetch custom bots" },
20 | { status: response.status },
21 | );
22 | }
23 |
24 | const result = await response.json();
25 | return NextResponse.json(result);
26 | } catch (error) {
27 | console.error("Error fetching custom bots:", error);
28 | return NextResponse.json(
29 | { error: "Internal server error" },
30 | { status: 500 },
31 | );
32 | }
33 | });
34 | }
35 |
--------------------------------------------------------------------------------
/docs/src/app/api/docs/raw/[...slug]/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest, NextResponse } from "next/server";
2 | import { DocsFileSystem } from "@/lib/docs/file-system";
3 |
4 | /**
5 | * GET /api/docs/raw/[...slug]
6 | * Returns raw markdown content for LLM consumption
7 | */
8 | export async function GET(
9 | request: NextRequest,
10 | { params }: { params: Promise<{ slug: string[] }> },
11 | ) {
12 | try {
13 | const { slug } = await params;
14 | const fileSystem = new DocsFileSystem();
15 | const doc = await fileSystem.getDocContent(slug);
16 |
17 | if (!doc) {
18 | return NextResponse.json(
19 | { error: "Document not found" },
20 | { status: 404 },
21 | );
22 | }
23 |
24 | // Return raw markdown as plain text
25 | return new NextResponse(doc.content, {
26 | status: 200,
27 | headers: {
28 | "Content-Type": "text/markdown; charset=utf-8",
29 | },
30 | });
31 | } catch (error) {
32 | console.error("Error fetching raw markdown:", error);
33 | return NextResponse.json(
34 | { error: "Failed to fetch document" },
35 | { status: 500 },
36 | );
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/frontend/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import "@/styles/globals.css";
2 | import { Inter as FontSans } from "next/font/google";
3 | import { ThemeProvider } from "@/components/theme-provider";
4 | import { cn } from "@/lib/utils";
5 | import { AuthProvider } from "@/contexts/auth-context";
6 | import { Toaster } from "@/components/ui/toaster";
7 | import React from "react";
8 |
9 | const fontSans = FontSans({
10 | subsets: ["latin"],
11 | variable: "--font-sans",
12 | });
13 |
14 | export default function RootLayout({
15 | children,
16 | }: Readonly<{
17 | children: React.ReactNode;
18 | }>) {
19 | return (
20 |
21 |
22 |
28 |
34 | {children}
35 |
36 |
37 |
38 |
39 | );
40 | }
41 |
--------------------------------------------------------------------------------
/api/src/main.ts:
--------------------------------------------------------------------------------
1 | import { ValidationPipe } from "@nestjs/common";
2 | import { NestFactory } from "@nestjs/core";
3 | import { AppModule } from "./app.module";
4 | import { runMigrations } from "./database/migrate";
5 |
6 | async function bootstrap() {
7 | // Run database migrations before starting the application
8 | console.log("🔄 Running database migrations...");
9 | await runMigrations();
10 | console.log("✅ Database migrations completed");
11 |
12 | const app = await NestFactory.create(AppModule);
13 |
14 | // Enable CORS for OSS version
15 | app.enableCors({
16 | origin: process.env.FRONTEND_URL || "http://localhost:3001",
17 | credentials: true,
18 | });
19 |
20 | // Global validation pipe
21 | app.useGlobalPipes(
22 | new ValidationPipe({
23 | whitelist: true,
24 | forbidNonWhitelisted: true,
25 | transform: true,
26 | }),
27 | );
28 |
29 | const port = process.env.PORT || 3000;
30 | await app.listen(port, "0.0.0.0");
31 |
32 | console.log(`🚀 The0 API is running on port ${port}`);
33 | }
34 |
35 | bootstrap().catch((error) => {
36 | console.error("Failed to start The0 API:", error);
37 | process.exit(1);
38 | });
39 |
--------------------------------------------------------------------------------
/docs/src/components/ui/slider.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as SliderPrimitive from "@radix-ui/react-slider";
5 |
6 | import { cn } from "@/lib/utils";
7 |
8 | const Slider = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(({ className, ...props }, ref) => (
12 |
20 |
21 |
22 |
23 |
24 |
25 | ));
26 | Slider.displayName = SliderPrimitive.Root.displayName;
27 |
28 | export { Slider };
29 |
--------------------------------------------------------------------------------
/site/README.md:
--------------------------------------------------------------------------------
1 | # the0 Landing Site
2 |
3 | A lightweight landing site for [the0.dev](https://the0.dev) that provides access to:
4 |
5 | - GitHub repository
6 | - Documentation
7 | - CLI installation
8 | - Platform overview
9 |
10 | ## Development
11 |
12 | ```bash
13 | # Install dependencies
14 | yarn install
15 |
16 | # Run development server
17 | yarn dev
18 |
19 | # Build for production
20 | yarn build
21 |
22 | # Start production server
23 | yarn start
24 | ```
25 |
26 | ## Tech Stack
27 |
28 | - Next.js 15 with App Router
29 | - React 19
30 | - TypeScript
31 | - Tailwind CSS v4
32 | - shadcn/ui components
33 | - Radix UI primitives
34 |
35 | ## Structure
36 |
37 | - `/src/app` - Pages and layouts
38 | - `/src/components` - Reusable components
39 | - `/src/lib` - Utilities and configurations
40 |
41 | ## Features
42 |
43 | - Dark/light theme support
44 | - Responsive design
45 | - Static site generation ready
46 | - No authentication required
47 | - Minimal dependencies
48 |
49 | ## Pages
50 |
51 | - `/` - Landing page with hero, features, and how-it-works
52 | - `/install-cli` - CLI installation guide
53 | - `/docs` - Documentation overview
54 | - `/about` - About the0 platform
55 |
--------------------------------------------------------------------------------
/frontend/src/components/ui/slider.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as SliderPrimitive from "@radix-ui/react-slider";
5 |
6 | import { cn } from "@/lib/utils";
7 |
8 | const Slider = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(({ className, ...props }, ref) => (
12 |
20 |
21 |
22 |
23 |
24 |
25 | ));
26 | Slider.displayName = SliderPrimitive.Root.displayName;
27 |
28 | export { Slider };
29 |
--------------------------------------------------------------------------------
/frontend/jest.config.ts:
--------------------------------------------------------------------------------
1 | // jest.config.ts
2 | import type { Config } from "jest";
3 | import nextJest from "next/jest";
4 |
5 | const createJestConfig = nextJest({
6 | dir: "./",
7 | });
8 |
9 | const customJestConfig: Config = {
10 | setupFilesAfterEnv: ["/jest.setup.ts"],
11 | testEnvironment: "jest-fixed-jsdom",
12 | moduleNameMapper: {
13 | "^@/(.*)$": "/src/$1",
14 | "^react-markdown$": "/__mocks__/react-markdown.js",
15 | "^remark-gfm$": "/__mocks__/remark-gfm.js",
16 | "^remark-breaks$": "/__mocks__/remark-breaks.js",
17 | "^react-syntax-highlighter$":
18 | "/__mocks__/react-syntax-highlighter.js",
19 | "^react-syntax-highlighter/dist/esm/(.*)$":
20 | "/__mocks__/react-syntax-highlighter.js",
21 | "^uuid$": "/__mocks__/uuid.js",
22 | },
23 | testPathIgnorePatterns: ["/.next/", "/node_modules/"],
24 |
25 | transformIgnorePatterns: [
26 | "/node_modules/(?!(string-width|strip-ansi|ansi-regex|cliui))",
27 | ],
28 | testEnvironmentOptions: {
29 | customExportConditions: [""],
30 | },
31 | };
32 |
33 | export default createJestConfig(customJestConfig);
34 |
--------------------------------------------------------------------------------
/frontend/src/components/ai-agent/chat/ChatPanel.tsx:
--------------------------------------------------------------------------------
1 | import { MessageList } from "./MessageList";
2 | import { ChatInput } from "./ChatInput";
3 | import { useStreamingChat } from "@/hooks/ai-agent/useStreamingChat";
4 | import { useSettingsStore } from "@/stores/ai-agent/settingsStore";
5 |
6 | export function ChatPanel() {
7 | const { streamingEnabled } = useSettingsStore();
8 | const { messages, sendMessage, isStreaming } = useStreamingChat();
9 |
10 | return (
11 |
12 |
13 |
Chat with the0
14 |
15 | Describe your trading strategy and I'll help you build it
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | sendMessage(message, streamingEnabled)}
26 | disabled={isStreaming}
27 | />
28 |
29 |
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/frontend/src/components/ai-agent/ui/slider.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import * as SliderPrimitive from "@radix-ui/react-slider";
3 | import { cn } from "@/lib/utils";
4 |
5 | const Slider = React.forwardRef<
6 | React.ElementRef,
7 | React.ComponentPropsWithoutRef
8 | >(({ className, ...props }, ref) => (
9 |
17 |
18 |
19 |
20 |
21 |
22 | ));
23 | Slider.displayName = SliderPrimitive.Root.displayName;
24 |
25 | export { Slider };
26 |
--------------------------------------------------------------------------------
/services/0vers33r/src/services/cloud_storage.py:
--------------------------------------------------------------------------------
1 | from google.cloud import storage as gcs
2 |
3 |
4 | class GCSStorageClient:
5 | """Google Cloud Storage implementation"""
6 |
7 | def __init__(self):
8 | self.storage_client = gcs.Client()
9 |
10 | def download_file(self, gcs_path: str) -> bytes:
11 | """Download file from GCS"""
12 | if not gcs_path.startswith("gs://"):
13 | raise ValueError("Invalid GCS path format")
14 |
15 | # Parse GCS path
16 | path_parts = gcs_path[5:].split("/", 1) # Remove 'gs://' prefix
17 | if len(path_parts) != 2:
18 | raise ValueError("Malformed GCS path")
19 |
20 | bucket_name, blob_name = path_parts
21 |
22 | # Download the file
23 | bucket = self.storage_client.bucket(bucket_name)
24 | blob = bucket.blob(blob_name)
25 |
26 | if not blob.exists():
27 | raise FileNotFoundError(f"File not found: {gcs_path}")
28 |
29 | # Check file size (prevent ZIP bombs)
30 | blob.reload()
31 | if blob.size > 1 * 1024 * 1024 * 1024: # 1GB limit
32 | raise ValueError("File too large")
33 |
34 | return blob.download_as_bytes()
35 |
--------------------------------------------------------------------------------
/runtime/internal/backtest-runner/model/backtest.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | type Backtest struct {
4 | ID string `bson:"id"`
5 | SegmentId int32 `bson:"segment_id"`
6 | Config map[string]interface{} `bson:"config"`
7 | CustomBotVersion CustomBotVersion `bson:"custom"`
8 | }
9 |
10 | type CustomBotVersion struct {
11 | Version string `json:"version"`
12 | Config APIBotConfig `json:"config"`
13 | FilePath string `json:"filePath"`
14 | CreatedAt string `json:"createdAt"`
15 | UpdatedAt string `json:"updatedAt"`
16 | }
17 |
18 | type APIBotConfig struct {
19 | Name string `json:"name"`
20 | Description string `json:"description"`
21 | Runtime string `json:"runtime,omitempty" default:"python3.11"`
22 | Version string `json:"version"`
23 | Author string `json:"author"`
24 | Type string `json:"type"`
25 | Entrypoints map[string]string `json:"entrypoints"`
26 | Schema map[string]interface{} `json:"schema"`
27 | Readme string `json:"readme"`
28 | Metadata map[string]interface{} `json:"metadata"`
29 | }
30 |
--------------------------------------------------------------------------------
/site/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import { Inter as FontSans } from "next/font/google";
3 | import { ThemeProvider } from "@/components/theme-provider";
4 | import { cn } from "@/lib/utils";
5 | import "./globals.css";
6 |
7 | const fontSans = FontSans({
8 | subsets: ["latin"],
9 | variable: "--font-sans",
10 | });
11 |
12 | export const metadata: Metadata = {
13 | title: "the0 - Open Source Algorithmic Trading Platform",
14 | description:
15 | "Build and deploy algorithmic trading bots with Python or JavaScript. Open source platform for automated trading strategies.",
16 | };
17 |
18 | export default function RootLayout({
19 | children,
20 | }: Readonly<{
21 | children: React.ReactNode;
22 | }>) {
23 | return (
24 |
25 |
31 |
37 | {children}
38 |
39 |
40 |
41 | );
42 | }
43 |
--------------------------------------------------------------------------------
/frontend/src/components/ai-agent/ui/switch.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import * as SwitchPrimitives from "@radix-ui/react-switch";
3 | import { cn } from "@/lib/utils";
4 |
5 | const Switch = React.forwardRef<
6 | React.ElementRef,
7 | React.ComponentPropsWithoutRef
8 | >(({ className, ...props }, ref) => (
9 |
17 |
22 |
23 | ));
24 | Switch.displayName = SwitchPrimitives.Root.displayName;
25 |
26 | export { Switch };
27 |
--------------------------------------------------------------------------------
/frontend/src/middleware.ts:
--------------------------------------------------------------------------------
1 | import { NextResponse } from "next/server";
2 | import type { NextRequest } from "next/server";
3 |
4 | export function middleware(request: NextRequest) {
5 | // Check if maintenance mode is enabled
6 | const maintenanceMode = process.env.NEXT_PUBLIC_MAINTENANCE_MODE === "true";
7 |
8 | // If maintenance mode is enabled and not already on maintenance page
9 | if (maintenanceMode && !request.nextUrl.pathname.startsWith("/maintenance")) {
10 | return NextResponse.redirect(new URL("/maintenance", request.url));
11 | }
12 |
13 | // If maintenance mode is disabled and trying to access maintenance page, redirect to home
14 | if (!maintenanceMode && request.nextUrl.pathname.startsWith("/maintenance")) {
15 | return NextResponse.redirect(new URL("/", request.url));
16 | }
17 |
18 | // Pass through all other requests
19 | return NextResponse.next();
20 | }
21 |
22 | export const config = {
23 | matcher: [
24 | /*
25 | * Match all request paths except for the ones starting with:
26 | * - api (API routes)
27 | * - _next/static (static files)
28 | * - _next/image (image optimization files)
29 | * - favicon.ico (favicon file)
30 | */
31 | "/((?!api|_next/static|_next/image|favicon.ico).*)",
32 | ],
33 | };
34 |
--------------------------------------------------------------------------------
/frontend/src/app/api/ai-agent/artifacts/[filename]/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest, NextResponse } from "next/server";
2 | import { getAiAgentUrl } from "@/lib/config";
3 |
4 | export async function GET(
5 | request: NextRequest,
6 | context: { params: Promise<{ filename: string }> },
7 | ) {
8 | try {
9 | const params = await context.params;
10 | const { searchParams } = new URL(request.url);
11 | const sessionId = searchParams.get("session_id");
12 | const aiAgentUrl = getAiAgentUrl();
13 |
14 | let url = `${aiAgentUrl}/artifacts/${params.filename}`;
15 | if (sessionId) {
16 | url = `${aiAgentUrl}/artifacts/session/${sessionId}/${params.filename}`;
17 | }
18 |
19 | const response = await fetch(url, {
20 | method: "GET",
21 | headers: {
22 | "Content-Type": "application/json",
23 | },
24 | });
25 |
26 | if (!response.ok) {
27 | throw new Error(`AI Agent API error: ${response.statusText}`);
28 | }
29 |
30 | const data = await response.json();
31 | return NextResponse.json(data);
32 | } catch (error) {
33 | console.error("AI Agent artifact error:", error);
34 | return NextResponse.json(
35 | { error: "Failed to fetch artifact" },
36 | { status: 500 },
37 | );
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/frontend/src/components/spinner/Spinner.tsx:
--------------------------------------------------------------------------------
1 | interface SpinnerProps {
2 | size?: "sm" | "md" | "lg";
3 | color?: string;
4 | }
5 |
6 | const Spinner: React.FC = ({
7 | size = "md",
8 | color = "text-blue-600",
9 | }) => {
10 | const sizeClasses = {
11 | sm: "w-6 h-6",
12 | md: "w-8 h-8",
13 | lg: "w-12 h-12",
14 | };
15 |
16 | return (
17 |
41 | );
42 | };
43 |
44 | export default Spinner;
45 |
--------------------------------------------------------------------------------
/site/src/components/ui/badge.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { cva, type VariantProps } from "class-variance-authority";
3 |
4 | import { cn } from "@/lib/utils";
5 |
6 | const badgeVariants = cva(
7 | "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
8 | {
9 | variants: {
10 | variant: {
11 | default:
12 | "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
13 | secondary:
14 | "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
15 | destructive:
16 | "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
17 | outline: "text-foreground",
18 | },
19 | },
20 | defaultVariants: {
21 | variant: "default",
22 | },
23 | },
24 | );
25 |
26 | export interface BadgeProps
27 | extends React.HTMLAttributes,
28 | VariantProps {}
29 |
30 | function Badge({ className, variant, ...props }: BadgeProps) {
31 | return (
32 |
33 | );
34 | }
35 |
36 | export { Badge, badgeVariants };
37 |
--------------------------------------------------------------------------------
/docs/src/components/ui/switch.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as SwitchPrimitives from "@radix-ui/react-switch";
5 |
6 | import { cn } from "@/lib/utils";
7 |
8 | const Switch = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(({ className, ...props }, ref) => (
12 |
20 |
25 |
26 | ));
27 | Switch.displayName = SwitchPrimitives.Root.displayName;
28 |
29 | export { Switch };
30 |
--------------------------------------------------------------------------------
/docs/src/docs/the0-CLI/installation.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Installation"
3 | description: "How to install the the0 CLI"
4 | tags: ["cli", "installation"]
5 | order: 1
6 | ---
7 |
8 | # Installation
9 |
10 | The the0 CLI is the command-line interface for managing your trading bots, deploying custom algorithms, and interacting with the the0 platform ecosystem.
11 |
12 | ---
13 |
14 | ## Installation Guide
15 |
16 | For detailed installation instructions, please visit our dedicated installation page:
17 |
18 | 👉 [**Install the0 CLI**](/install-cli)
19 |
20 | This page will guide you through:
21 |
22 | - System requirements
23 | - Platform-specific installation steps
24 | - Verification of successful installation
25 | - Initial setup and configuration
26 |
27 | ---
28 |
29 | ## Quick Verification
30 |
31 | After installation, verify the CLI is working:
32 |
33 | ```bash
34 | # Check CLI version
35 | the0 --version
36 |
37 | # View available commands
38 | the0 --help
39 | ```
40 |
41 | ---
42 |
43 | ## Next Steps
44 |
45 | Once installed, proceed to:
46 |
47 | - [Authentication](/docs/the0-cli/authentication) - Set up your API credentials
48 | - [Bot Commands](/docs/the0-cli/bot-commands) - Learn to manage bot instances
49 | - [Custom Bot Commands](/docs/the0-cli/custom-bot-commands) - Deploy your own bots
50 |
--------------------------------------------------------------------------------
/frontend/src/components/ui/switch.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as SwitchPrimitives from "@radix-ui/react-switch";
5 |
6 | import { cn } from "@/lib/utils";
7 |
8 | const Switch = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(({ className, ...props }, ref) => (
12 |
20 |
25 |
26 | ));
27 | Switch.displayName = SwitchPrimitives.Root.displayName;
28 |
29 | export { Switch };
30 |
--------------------------------------------------------------------------------
/docs/src/components/ui/badge.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { cva, type VariantProps } from "class-variance-authority";
3 |
4 | import { cn } from "@/lib/utils";
5 |
6 | const badgeVariants = cva(
7 | "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
8 | {
9 | variants: {
10 | variant: {
11 | default:
12 | "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
13 | secondary:
14 | "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
15 | destructive:
16 | "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",
17 | outline: "text-foreground",
18 | },
19 | },
20 | defaultVariants: {
21 | variant: "default",
22 | },
23 | },
24 | );
25 |
26 | export interface BadgeProps
27 | extends React.HTMLAttributes,
28 | VariantProps {}
29 |
30 | function Badge({ className, variant, ...props }: BadgeProps) {
31 | return (
32 |
33 | );
34 | }
35 |
36 | export { Badge, badgeVariants };
37 |
--------------------------------------------------------------------------------
/frontend/src/app/api/ai-agent/chat/stream/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest } from "next/server";
2 | import { getAiAgentUrl } from "@/lib/config";
3 |
4 | export async function POST(request: NextRequest) {
5 | try {
6 | const body = await request.json();
7 | const aiAgentUrl = getAiAgentUrl();
8 |
9 | const response = await fetch(`${aiAgentUrl}/chat/stream`, {
10 | method: "POST",
11 | headers: {
12 | "Content-Type": "application/json",
13 | },
14 | body: JSON.stringify(body),
15 | });
16 |
17 | if (!response.ok) {
18 | throw new Error(`AI Agent API error: ${response.statusText}`);
19 | }
20 |
21 | // Stream the response back to the client
22 | return new Response(response.body, {
23 | status: response.status,
24 | headers: {
25 | "Content-Type": "text/event-stream",
26 | "Cache-Control": "no-cache",
27 | Connection: "keep-alive",
28 | "X-Accel-Buffering": "no",
29 | },
30 | });
31 | } catch (error) {
32 | console.error("AI Agent stream error:", error);
33 | return new Response(
34 | JSON.stringify({ error: "Failed to communicate with AI agent" }),
35 | {
36 | status: 500,
37 | headers: { "Content-Type": "application/json" },
38 | },
39 | );
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/frontend/src/components/ui/badge.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { cva, type VariantProps } from "class-variance-authority";
3 |
4 | import { cn } from "@/lib/utils";
5 |
6 | const badgeVariants = cva(
7 | "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
8 | {
9 | variants: {
10 | variant: {
11 | default:
12 | "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
13 | secondary:
14 | "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
15 | destructive:
16 | "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",
17 | outline: "text-foreground",
18 | },
19 | },
20 | defaultVariants: {
21 | variant: "default",
22 | },
23 | },
24 | );
25 |
26 | export interface BadgeProps
27 | extends React.HTMLAttributes,
28 | VariantProps {}
29 |
30 | function Badge({ className, variant, ...props }: BadgeProps) {
31 | return (
32 |
33 | );
34 | }
35 |
36 | export { Badge, badgeVariants };
37 |
--------------------------------------------------------------------------------
/docs/src/app/api/docs/search/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest, NextResponse } from "next/server";
2 | import { DocsSearchService } from "@/lib/docs/search-service";
3 |
4 | export async function GET(request: NextRequest) {
5 | try {
6 | const { searchParams } = new URL(request.url);
7 | const query = searchParams.get("q");
8 | const type = searchParams.get("type") || "search"; // 'search' or 'suggestions'
9 |
10 | if (!query || query.length < 2) {
11 | return NextResponse.json({
12 | success: true,
13 | data: [],
14 | });
15 | }
16 |
17 | const searchService = DocsSearchService.getInstance();
18 |
19 | // Ensure index is built
20 | await searchService.indexDocuments();
21 |
22 | let results;
23 | if (type === "suggestions") {
24 | results = await searchService.getSuggestions(query);
25 | } else {
26 | results = await searchService.search(query);
27 | }
28 |
29 | return NextResponse.json({
30 | success: true,
31 | data: results,
32 | });
33 | } catch (error: any) {
34 | console.error("Error performing docs search:", error);
35 | return NextResponse.json(
36 | {
37 | success: false,
38 | error: "Failed to search documentation",
39 | },
40 | { status: 500 },
41 | );
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/docs/src/docs/custom-bot-development/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Custom Bot Development"
3 | description: "Build your own trading bots on the0 platform"
4 | order: 4
5 | ---
6 |
7 | # Custom Bot Development
8 |
9 | Learn how to create, test, and deploy custom trading bots on the the0 platform. Build sophisticated trading strategies using Python or JavaScript.
10 |
11 | ## Getting Started
12 |
13 | - **[Quick Start Guide](./quick-start-guide)** - Build your first custom bot
14 | - **[Development Environment](./development-environment)** - Set up your development workspace
15 | - **[Bot Configuration](./bot-configuration)** - Configure your bot settings
16 |
17 | ## Core Concepts
18 |
19 | - **[Bot Types](./bot-types)** - Scheduled vs real-time execution
20 | - **[Bot Structure](./bot-structure)** - Project organization and files
21 | - **[Entry Points](./entry-points)** - Main functions and interfaces
22 |
23 | ## Development Guide
24 |
25 | - **[Overview](./overview)** - Understanding custom bot development
26 | - **[Testing and Debugging](./testing-and-debugging)** - Test your bots locally
27 | - **[Backtesting](./backtesting)** - Implementing backtesting
28 |
29 | ## Advanced Topics
30 |
31 | - **[Backtesting](./backtesting)** - Test strategies with historical data
32 | - **[Compliance](./compliance)** - Code review and platform requirements
33 |
--------------------------------------------------------------------------------
/site/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "site",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev --turbopack",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint",
10 | "format": "prettier --write ."
11 | },
12 | "dependencies": {
13 | "@radix-ui/react-dialog": "^1.1.3",
14 | "@radix-ui/react-dropdown-menu": "^2.1.4",
15 | "@radix-ui/react-slot": "^1.1.0",
16 | "@types/react-syntax-highlighter": "^15.5.13",
17 | "class-variance-authority": "^0.7.1",
18 | "clsx": "^2.1.1",
19 | "lucide-react": "^0.468.0",
20 | "next": "15.4.5",
21 | "next-themes": "^0.4.4",
22 | "react": "19.1.0",
23 | "react-dom": "19.1.0",
24 | "react-syntax-highlighter": "^15.6.1",
25 | "tailwind-merge": "^2.6.0",
26 | "tailwindcss-animate": "^1.0.7"
27 | },
28 | "devDependencies": {
29 | "@eslint/eslintrc": "^3",
30 | "@types/node": "^20",
31 | "@types/react": "^19",
32 | "@types/react-dom": "^19",
33 | "autoprefixer": "^10.4.20",
34 | "eslint": "^9",
35 | "eslint-config-next": "15.4.5",
36 | "eslint-config-prettier": "^10.1.8",
37 | "eslint-plugin-prettier": "^5.5.4",
38 | "postcss": "^8.4.40",
39 | "prettier": "^3.6.2",
40 | "tailwindcss": "^3.4.7",
41 | "typescript": "^5"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/api/src/logs/logs.controller.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Controller,
3 | Get,
4 | Param,
5 | Query,
6 | UseGuards,
7 | BadRequestException,
8 | NotFoundException,
9 | } from "@nestjs/common";
10 | import { LogsService } from "./logs.service";
11 | import { GetLogsQueryDto } from "./dto/get-logs-query.dto";
12 | import { AuthCombinedGuard } from "@/auth/auth-combined.guard";
13 |
14 | @Controller("logs")
15 | @UseGuards(AuthCombinedGuard)
16 | export class LogsController {
17 | constructor(private readonly logsService: LogsService) {}
18 |
19 | @Get(":botId")
20 | async getLogs(
21 | @Param("botId") botId: string,
22 | @Query() query: GetLogsQueryDto,
23 | ) {
24 | const result = await this.logsService.getLogs(botId, {
25 | date: query.date,
26 | dateRange: query.dateRange,
27 | limit: query.limit || 100,
28 | offset: query.offset || 0,
29 | });
30 |
31 | if (!result.success) {
32 | if (
33 | result.error?.includes("not found") ||
34 | result.error?.includes("access denied")
35 | ) {
36 | throw new NotFoundException(result.error);
37 | }
38 | throw new BadRequestException(result.error);
39 | }
40 |
41 | return {
42 | success: true,
43 | data: result.data,
44 | message: "Logs retrieved successfully",
45 | };
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/docs/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/site/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/frontend/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/frontend/src/app/custom-bots/[name]/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import React from "react";
3 | import { useParams } from "next/navigation";
4 | import { withAuth } from "@/components/auth/with-auth";
5 | import DashboardLayout from "@/components/layouts/dashboard-layout";
6 | import { CustomBotDetailPage } from "@/components/custom-bots/custom-bot-detail-page";
7 |
8 | interface CustomBotDetailPageProps {
9 | params: { name: string };
10 | }
11 |
12 | const CustomBotDetailPageWrapper: React.FC = () => {
13 | const params = useParams();
14 | const botName = params?.name as string;
15 |
16 | if (!botName) {
17 | return (
18 |
19 |
20 |
21 |
22 | Invalid Bot Name
23 |
24 |
25 | The bot name parameter is missing.
26 |
27 |
28 |
29 |
30 | );
31 | }
32 |
33 | return (
34 |
35 |
36 |
37 | );
38 | };
39 |
40 | export default withAuth(CustomBotDetailPageWrapper);
41 |
--------------------------------------------------------------------------------
/docs/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import "@/styles/globals.css";
2 | import { Inter as FontSans } from "next/font/google";
3 | import { ThemeProvider } from "@/components/theme-provider";
4 | import { cn } from "@/lib/utils";
5 | import type { Metadata } from "next";
6 |
7 | const fontSans = FontSans({
8 | subsets: ["latin"],
9 | variable: "--font-sans",
10 | });
11 |
12 | export const metadata: Metadata = {
13 | title: "the0 Documentation",
14 | description:
15 | "Comprehensive documentation for the0 algorithmic trading platform",
16 | keywords: [
17 | "trading bots",
18 | "documentation",
19 | "API",
20 | "guide",
21 | "the0",
22 | "algorithmic trading",
23 | ],
24 | };
25 |
26 | export default function RootLayout({
27 | children,
28 | }: Readonly<{
29 | children: React.ReactNode;
30 | }>) {
31 | return (
32 |
33 |
34 |
40 |
46 | {children}
47 |
48 |
49 |
50 | );
51 | }
52 |
--------------------------------------------------------------------------------
/api/src/config/configuration.ts:
--------------------------------------------------------------------------------
1 | export default () => ({
2 | // Bot runtime configuration
3 | BOT_TYPE_API_KEY: process.env.BOT_TYPE_API_KEY || "",
4 |
5 | // Frontend configuration
6 | FRONTEND_URL: process.env.FRONTEND_URL || "http://localhost:3001",
7 |
8 | // MinIO/S3 storage configuration for OSS
9 | MINIO_ENDPOINT: process.env.MINIO_ENDPOINT || "localhost",
10 | MINIO_EXTERNAL_ENDPOINT:
11 | process.env.MINIO_EXTERNAL_ENDPOINT ||
12 | process.env.MINIO_ENDPOINT ||
13 | "localhost:9000",
14 | MINIO_PORT: process.env.MINIO_PORT || "9000",
15 | MINIO_USE_SSL: process.env.MINIO_USE_SSL || "false",
16 | MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY || "minioadmin",
17 | MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY || "minioadmin",
18 |
19 | // Storage buckets
20 | CUSTOM_BOTS_BUCKET: process.env.CUSTOM_BOTS_BUCKET || "custom-bots",
21 | LOG_BUCKET: process.env.LOG_BUCKET || "logs",
22 | BACKTEST_BUCKET: process.env.BACKTEST_BUCKET || "backtests",
23 |
24 | // Database configuration
25 | DATABASE_URL: process.env.DATABASE_URL || "sqlite:data.db",
26 |
27 | // NATS configuration
28 | NATS_URLs: process.env.NATS_URLS || "nats://localhost:4222",
29 |
30 | // JWT configuration
31 | JWT_SECRET: process.env.JWT_SECRET || "your-secret-key-change-in-production",
32 | JWT_EXPIRES_IN: process.env.JWT_EXPIRES_IN || "24h",
33 | });
34 |
--------------------------------------------------------------------------------
/frontend/src/app/api/api-keys/stats/summary/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest, NextResponse } from "next/server";
2 | import { withAdminAuth } from "@/lib/middleware/admin-auth";
3 |
4 | export async function GET(req: NextRequest) {
5 | return withAdminAuth(req, async (req: NextRequest) => {
6 | try {
7 | const token = req.headers.get("Authorization");
8 |
9 | const response = await fetch(
10 | `${process.env.BOT_API_URL}/api-keys/stats/summary`,
11 | {
12 | method: "GET",
13 | headers: {
14 | "Content-Type": "application/json",
15 | Authorization: token,
16 | } as HeadersInit,
17 | },
18 | );
19 |
20 | if (!response.ok) {
21 | return NextResponse.json(
22 | { error: await response.json() },
23 | { status: response.status },
24 | );
25 | }
26 |
27 | let data = await response.json();
28 | return NextResponse.json(data);
29 | } catch (error: any) {
30 | console.error("Error fetching API key stats:", error);
31 | return NextResponse.json(
32 | {
33 | error: {
34 | message: "Error fetching API key stats",
35 | statusCode: 500,
36 | error: "Internal Server Error",
37 | },
38 | },
39 | { status: 500 },
40 | );
41 | }
42 | });
43 | }
44 |
--------------------------------------------------------------------------------
/frontend/src/components/custom-bots/empty-state.tsx:
--------------------------------------------------------------------------------
1 | import { Bot } from "lucide-react";
2 | import React from "react";
3 | import Link from "next/link";
4 |
5 | export const EmptyState = () => (
6 |
7 |
8 |
9 |
10 |
No Custom Bots
11 |
12 | You haven't uploaded any custom trading bots yet. Use the CLI to
13 | upload your first bot and get started with automated trading.
14 |
15 |
16 |
Get Started
17 |
18 | the0 custom-bot deploy
19 |
20 |
21 | Deploy your custom bot via CLI and track its approval status here.{" "}
22 |
26 | View docs
27 |
28 |
29 |
30 |
31 | );
32 |
--------------------------------------------------------------------------------
/services/0vers33r/Dockerfile:
--------------------------------------------------------------------------------
1 | # 0vers33r Security Analysis Service Dockerfile
2 | FROM python:3.11-slim
3 |
4 | # Set working directory
5 | WORKDIR /app
6 |
7 | # Install system dependencies
8 | RUN apt-get update && apt-get install -y \
9 | gcc \
10 | g++ \
11 | libyara-dev \
12 | pkg-config \
13 | git \
14 | curl \
15 | && rm -rf /var/lib/apt/lists/*
16 |
17 | # Copy requirements first for better caching
18 | COPY requirements.txt .
19 |
20 | # Install Python dependencies
21 | RUN pip install --no-cache-dir -r requirements.txt
22 |
23 | # Copy application code
24 | COPY . .
25 |
26 | # Create log directory
27 | RUN mkdir -p /var/log && chmod 755 /var/log
28 |
29 | # Create non-root user for security
30 | RUN groupadd -r analyzer && useradd -r -g analyzer analyzer
31 |
32 | # Set ownership of the application
33 | RUN chown -R analyzer:analyzer /app /var/log
34 |
35 | # Switch to non-root user
36 | USER analyzer
37 |
38 | # Set environment variables
39 | ENV PYTHONPATH=/app
40 | ENV PYTHONUNBUFFERED=1
41 |
42 | # Health check
43 | HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
44 | CMD python -c "import asyncio; from src.services.nats_client import NATSClient; asyncio.run(NATSClient().connect())" || exit 1
45 |
46 | # Expose port (if needed for health checks)
47 | EXPOSE 8080
48 |
49 | # Run the service
50 | CMD ["python", "main.py"]
--------------------------------------------------------------------------------
/docs/src/components/ui/tooltip.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as TooltipPrimitive from "@radix-ui/react-tooltip";
5 |
6 | import { cn } from "@/lib/utils";
7 |
8 | const TooltipProvider = TooltipPrimitive.Provider;
9 |
10 | const Tooltip = TooltipPrimitive.Root;
11 |
12 | const TooltipTrigger = TooltipPrimitive.Trigger;
13 |
14 | const TooltipContent = React.forwardRef<
15 | React.ElementRef,
16 | React.ComponentPropsWithoutRef
17 | >(({ className, sideOffset = 4, ...props }, ref) => (
18 |
19 |
28 |
29 | ));
30 | TooltipContent.displayName = TooltipPrimitive.Content.displayName;
31 |
32 | export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
33 |
--------------------------------------------------------------------------------
/api/src/backtest/backtest.repository.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from "@nestjs/common";
2 | import { RoleRepository } from "@/common/role.repository";
3 | import { Backtest } from "./entities/backtest.entity";
4 | import { Result, Ok, Failure } from "@/common/result";
5 | import { eq } from "drizzle-orm";
6 |
7 | @Injectable()
8 | export class BacktestRepository extends RoleRepository {
9 | protected readonly tableName = "backtests" as const;
10 |
11 | async updateStatus(
12 | backtestId: string,
13 | status: string,
14 | ): Promise> {
15 | try {
16 | console.log(`🔄 Updating backtest ${backtestId} status to ${status}`);
17 |
18 | const result = await this.db
19 | .update(this.table)
20 | .set({
21 | status,
22 | updatedAt: new Date(),
23 | })
24 | .where(eq(this.table.id, backtestId))
25 | .returning();
26 |
27 | if (result.length === 0) {
28 | console.log(`❌ No backtest found with ID: ${backtestId}`);
29 | return Failure(`Backtest not found: ${backtestId}`);
30 | }
31 |
32 | console.log(
33 | `✅ Successfully updated backtest ${backtestId} status to ${status}`,
34 | );
35 | return Ok(undefined);
36 | } catch (error: any) {
37 | console.error(`❌ Error updating backtest status:`, error);
38 | return Failure(error.message);
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/docs/src/components/mode-toggle.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import { Moon, Sun } from "lucide-react";
5 | import { useTheme } from "next-themes";
6 |
7 | import { Button } from "@/components/ui/button";
8 | import {
9 | DropdownMenu,
10 | DropdownMenuContent,
11 | DropdownMenuItem,
12 | DropdownMenuTrigger,
13 | } from "@/components/ui/dropdown-menu";
14 |
15 | export function ModeToggle() {
16 | const { setTheme } = useTheme();
17 |
18 | return (
19 |
20 |
21 |
22 |
23 |
24 | Toggle theme
25 |
26 |
27 |
28 | setTheme("light")}>
29 | Light
30 |
31 | setTheme("dark")}>
32 | Dark
33 |
34 | setTheme("system")}>
35 | System
36 |
37 |
38 |
39 | );
40 | }
41 |
--------------------------------------------------------------------------------
/frontend/src/components/ui/tooltip.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as TooltipPrimitive from "@radix-ui/react-tooltip";
5 |
6 | import { cn } from "@/lib/utils";
7 |
8 | const TooltipProvider = TooltipPrimitive.Provider;
9 |
10 | const Tooltip = TooltipPrimitive.Root;
11 |
12 | const TooltipTrigger = TooltipPrimitive.Trigger;
13 |
14 | const TooltipContent = React.forwardRef<
15 | React.ElementRef,
16 | React.ComponentPropsWithoutRef
17 | >(({ className, sideOffset = 4, ...props }, ref) => (
18 |
19 |
28 |
29 | ));
30 | TooltipContent.displayName = TooltipPrimitive.Content.displayName;
31 |
32 | export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
33 |
--------------------------------------------------------------------------------
/site/src/components/mode-toggle.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import { Moon, Sun } from "lucide-react";
5 | import { useTheme } from "next-themes";
6 |
7 | import { Button } from "@/components/ui/button";
8 | import {
9 | DropdownMenu,
10 | DropdownMenuContent,
11 | DropdownMenuItem,
12 | DropdownMenuTrigger,
13 | } from "@/components/ui/dropdown-menu";
14 |
15 | export function ModeToggle() {
16 | const { setTheme } = useTheme();
17 |
18 | return (
19 |
20 |
21 |
22 |
23 |
24 | Toggle theme
25 |
26 |
27 |
28 | setTheme("light")}>
29 | Light
30 |
31 | setTheme("dark")}>
32 | Dark
33 |
34 | setTheme("system")}>
35 | System
36 |
37 |
38 |
39 | );
40 | }
41 |
--------------------------------------------------------------------------------
/frontend/src/components/mode-toggle.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import { Moon, Sun } from "lucide-react";
5 | import { useTheme } from "next-themes";
6 |
7 | import { Button } from "@/components/ui/button";
8 | import {
9 | DropdownMenu,
10 | DropdownMenuContent,
11 | DropdownMenuItem,
12 | DropdownMenuTrigger,
13 | } from "@/components/ui/dropdown-menu";
14 |
15 | export function ModeToggle() {
16 | const { setTheme } = useTheme();
17 |
18 | return (
19 |
20 |
21 |
22 |
23 |
24 | Toggle theme
25 |
26 |
27 |
28 | setTheme("light")}>
29 | Light
30 |
31 | setTheme("dark")}>
32 | Dark
33 |
34 | setTheme("system")}>
35 | System
36 |
37 |
38 |
39 | );
40 | }
41 |
--------------------------------------------------------------------------------
/frontend/src/components/ai-agent/layout/CollapsibleArtifactsPanel.tsx:
--------------------------------------------------------------------------------
1 | import { ArtifactsPanel } from "@/components/ai-agent/artifacts/ArtifactsPanel";
2 | import { ArtifactToolbar } from "@/components/ai-agent/artifacts/ArtifactToolbar";
3 | import { useArtifacts } from "@/hooks/ai-agent/useArtifacts";
4 | import { useArtifactsStore } from "@/stores/ai-agent/artifactsStore";
5 |
6 | export function CollapsibleArtifactsPanel() {
7 | const { files } = useArtifacts();
8 | const { forceShow, setForceShow } = useArtifactsStore();
9 |
10 | const shouldShow = forceShow && files.length > 0;
11 |
12 | if (!shouldShow) {
13 | return null; // Only show when explicitly requested and files exist
14 | }
15 |
16 | return (
17 |
18 |
19 |
20 |
21 |
Bot Files
22 |
23 | {files.length} artifact{files.length !== 1 ? "s" : ""} available
24 |
25 |
26 |
setForceShow(false)} />
27 |
28 |
29 |
32 |
33 |
34 | );
35 | }
36 |
--------------------------------------------------------------------------------
/frontend/src/app/install-cli/loading.tsx:
--------------------------------------------------------------------------------
1 | import { Terminal } from "lucide-react";
2 |
3 | export default function Loading() {
4 | return (
5 |
6 |
7 |
12 |
13 |
14 |
Loading CLI Installation
15 |
16 | Preparing your installation experience...
17 |
18 |
19 |
20 |
36 |
37 |
38 | );
39 | }
40 |
--------------------------------------------------------------------------------
/api/src/database/migrate.ts:
--------------------------------------------------------------------------------
1 | import { migrate } from "drizzle-orm/postgres-js/migrator";
2 | import { migrate as migrateSqlite } from "drizzle-orm/better-sqlite3/migrator";
3 | import { getDatabase, getDatabaseConfig } from "./connection";
4 | import { join } from "path";
5 |
6 | async function runMigrations() {
7 | const config = getDatabaseConfig();
8 | const db = getDatabase();
9 | const migrationsPath =
10 | process.env.MIGRATIONS_PATH || join(__dirname, "migrations");
11 |
12 | console.log(`Running migrations for ${config.type} database...`);
13 | console.log(`Migration path: ${migrationsPath}`);
14 |
15 | try {
16 | if (config.type === "sqlite") {
17 | migrateSqlite(db, { migrationsFolder: migrationsPath });
18 | console.log("✅ SQLite migrations completed successfully");
19 | } else {
20 | await migrate(db, { migrationsFolder: migrationsPath });
21 | console.log("✅ PostgreSQL migrations completed successfully");
22 | }
23 | } catch (error) {
24 | console.error("❌ Migration failed:", error);
25 | process.exit(1);
26 | }
27 | }
28 |
29 | // Run migrations if this file is executed directly
30 | if (require.main === module) {
31 | runMigrations()
32 | .then(() => {
33 | console.log("🎉 Database migration completed");
34 | process.exit(0);
35 | })
36 | .catch((error) => {
37 | console.error("❌ Migration script failed:", error);
38 | process.exit(1);
39 | });
40 | }
41 |
42 | export { runMigrations };
43 |
--------------------------------------------------------------------------------
/frontend/src/components/custom-bots/loading-state.tsx:
--------------------------------------------------------------------------------
1 | import { Card, CardContent, CardHeader } from "@/components/ui/card";
2 | import { Skeleton } from "@/components/ui/skeleton";
3 | import React from "react";
4 |
5 | export const LoadingState = () => (
6 |
7 | {Array.from({ length: 6 }).map((_, i) => (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | ))}
34 |
35 | );
36 |
--------------------------------------------------------------------------------
/frontend/src/components/ai-agent/common/ArtifactIndicator.tsx:
--------------------------------------------------------------------------------
1 | import { FileText, Download } from "lucide-react";
2 | import { Button } from "@/components/ui/button";
3 |
4 | interface ArtifactIndicatorProps {
5 | artifacts: string[];
6 | onViewArtifacts?: () => void;
7 | }
8 |
9 | export function ArtifactIndicator({
10 | artifacts,
11 | onViewArtifacts,
12 | }: ArtifactIndicatorProps) {
13 | if (artifacts.length === 0) return null;
14 |
15 | return (
16 |
17 |
18 |
19 |
20 | {artifacts.length} file{artifacts.length !== 1 ? "s" : ""} generated
21 |
22 |
23 |
24 |
25 | {artifacts.map((artifact, index) => (
26 |
30 | {artifact}
31 |
32 | ))}
33 |
34 |
35 | {onViewArtifacts && (
36 |
42 |
43 | View Files
44 |
45 | )}
46 |
47 | );
48 | }
49 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | # or
12 | pnpm dev
13 | # or
14 | bun dev
15 | ```
16 |
17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18 |
19 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
20 |
21 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
22 |
23 | ## Learn More
24 |
25 | To learn more about Next.js, take a look at the following resources:
26 |
27 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29 |
30 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
31 |
32 | ## Deploy on Vercel
33 |
34 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35 |
36 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
37 |
--------------------------------------------------------------------------------
/frontend/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | # or
12 | pnpm dev
13 | # or
14 | bun dev
15 | ```
16 |
17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18 |
19 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
20 |
21 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
22 |
23 | ## Learn More
24 |
25 | To learn more about Next.js, take a look at the following resources:
26 |
27 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29 |
30 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
31 |
32 | ## Deploy on Vercel
33 |
34 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35 |
36 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
37 |
--------------------------------------------------------------------------------
/frontend/src/stores/ai-agent/uiStore.ts:
--------------------------------------------------------------------------------
1 | import { create } from "zustand";
2 |
3 | type Theme = "light" | "dark" | "system";
4 |
5 | interface UIStore {
6 | theme: Theme;
7 | sidebarWidth: number;
8 | isFileTreeCollapsed: boolean;
9 | setTheme: (theme: Theme) => void;
10 | setSidebarWidth: (width: number) => void;
11 | toggleFileTree: () => void;
12 | setFileTreeCollapsed: (collapsed: boolean) => void;
13 | }
14 |
15 | export const useUIStore = create((set) => ({
16 | theme: "system",
17 | sidebarWidth: 400,
18 | isFileTreeCollapsed: false,
19 |
20 | setTheme: (theme) => {
21 | set(() => ({ theme }));
22 |
23 | // Apply theme to document
24 | const root = document.documentElement;
25 |
26 | if (theme === "dark") {
27 | root.classList.add("dark");
28 | } else if (theme === "light") {
29 | root.classList.remove("dark");
30 | } else {
31 | // System theme
32 | const systemTheme = window.matchMedia(
33 | "(prefers-color-scheme: dark)",
34 | ).matches;
35 | if (systemTheme) {
36 | root.classList.add("dark");
37 | } else {
38 | root.classList.remove("dark");
39 | }
40 | }
41 | },
42 |
43 | setSidebarWidth: (width) =>
44 | set(() => ({ sidebarWidth: Math.max(280, Math.min(600, width)) })),
45 |
46 | toggleFileTree: () =>
47 | set((state) => ({ isFileTreeCollapsed: !state.isFileTreeCollapsed })),
48 |
49 | setFileTreeCollapsed: (collapsed) =>
50 | set(() => ({ isFileTreeCollapsed: collapsed })),
51 | }));
52 |
--------------------------------------------------------------------------------
/frontend/src/components/custom-bots/status-header.tsx:
--------------------------------------------------------------------------------
1 | import { Badge } from "@/components/ui/badge";
2 | import React from "react";
3 | import {
4 | STATUS_CONFIG,
5 | THREAT_COLORS,
6 | } from "@/components/custom-bots/constants";
7 |
8 | export const StatusHeader = ({ bot }: any) => {
9 | const config = STATUS_CONFIG[bot.status];
10 | const Icon = config.icon;
11 |
12 | return (
13 |
14 |
15 |
16 |
17 |
18 |
19 |
{config.text}
20 | {bot.status.replace("_", " ")}
21 |
22 |
{config.description}
23 |
24 | {bot.review?.threatSummary?.threatLevel && (
25 |
26 | Threat Level:
27 |
31 | {bot.review?.threatSummary?.threatLevel.toUpperCase()}
32 |
33 |
34 | )}
35 |
36 |
37 | );
38 | };
39 |
--------------------------------------------------------------------------------
/site/src/components/landing-page/hero.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import Link from "next/link";
3 | import { Github } from "lucide-react";
4 | import { Button } from "@/components/ui/button";
5 |
6 | export function HeroSection() {
7 | return (
8 |
9 |
10 |
11 |
12 | the0
13 | Open source algorithmic
14 | trading platform
15 |
16 |
17 | Create, deploy, and manage trading bots with ease. Whether
18 | you're building a simple DCA strategy or complex multi-asset
19 | arbitrage algorithms, the0 provides the infrastructure and tools you
20 | need.
21 |
22 |
23 | {/* Main CTA Buttons */}
24 |
25 |
29 |
30 |
31 | View on GitHub
32 |
33 |
34 |
35 |
36 |
37 |
38 | );
39 | }
40 |
--------------------------------------------------------------------------------
/runtime/deploy/README.md:
--------------------------------------------------------------------------------
1 | # Bot Runner Deployment
2 |
3 | ## ⚡ Quick Deploy
4 |
5 | ```bash
6 | # 1. Update image and MongoDB config in runtime.yaml
7 | # 2. Deploy everything
8 | kubectl apply -f runtime.yaml
9 |
10 | # 3. Check status
11 | kubectl get pods -n runtime
12 | ```
13 |
14 | ## 📁 Files
15 |
16 | - **`runtime.yaml`** - Complete deployment configuration (everything you need!)
17 | - **`DEPLOYMENT_GUIDE.md`** - Detailed deployment instructions and troubleshooting
18 |
19 | ## 🎯 What You Get
20 |
21 | ✅ **Native Autoscaler** - Zero external dependencies
22 | ✅ **Leader Election** - High availability master-worker coordination
23 | ✅ **Single-Segment Architecture** - Perfect 1:1 scaling
24 | ✅ **Health Checks** - Kubernetes readiness/liveness probes
25 | ✅ **RBAC** - Minimal required permissions
26 | ✅ **Production Ready** - Resource limits, security contexts
27 |
28 | ## 🔧 Configuration
29 |
30 | **Required Changes:**
31 | 1. **Image**: Update `image: runtime:latest` with your registry
32 | 2. **MongoDB**: Update `MONGO_URI` in ConfigMap
33 | 3. **Segments**: Set `MAX_SEGMENT` for your workload
34 |
35 | **Everything else works out of the box!**
36 |
37 | ## 📊 Monitoring
38 |
39 | ```bash
40 | # Watch autoscaler in action
41 | kubectl logs -f deployment/runtime -n runtime | grep Scaling
42 |
43 | # Check metrics
44 | kubectl port-forward svc/runtime-service 8080:8080 -n runtime
45 | curl localhost:8080/metrics/segments
46 | ```
47 |
48 | ## ❓ Need Help?
49 |
50 | See **`DEPLOYMENT_GUIDE.md`** for detailed instructions and troubleshooting.
--------------------------------------------------------------------------------
/frontend/src/components/dashboard/CustomTable.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | interface TableProps {
3 | headers: string[];
4 | data: Record[];
5 | keyField: string;
6 | }
7 |
8 | const CustomTable: React.FC = ({ headers, data, keyField }) => {
9 | return (
10 |
11 |
12 |
13 |
14 | {headers.map((header, index) => (
15 |
16 | {header}
17 |
18 | ))}
19 |
20 |
21 |
22 | {data.map((row, rowIndex) => (
23 |
27 | {headers.map((header, cellIndex) => (
28 |
32 | {row[header.toLowerCase()]}
33 |
34 | ))}
35 |
36 | ))}
37 |
38 |
39 |
40 | );
41 | };
42 |
43 | export default CustomTable;
44 |
--------------------------------------------------------------------------------
/k8s/templates/ingress.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.ingress.enabled }}
2 | ---
3 | apiVersion: networking.k8s.io/v1
4 | kind: Ingress
5 | metadata:
6 | name: {{ include "the0.fullname" . }}-ingress
7 | labels:
8 | {{- include "the0.labels" . | nindent 4 }}
9 | {{- with .Values.ingress.annotations }}
10 | annotations:
11 | {{- toYaml . | nindent 4 }}
12 | {{- end }}
13 | spec:
14 | {{- if .Values.ingress.className }}
15 | ingressClassName: {{ .Values.ingress.className }}
16 | {{- end }}
17 | {{- if .Values.ingress.tls }}
18 | tls:
19 | {{- range .Values.ingress.tls }}
20 | - hosts:
21 | {{- range .hosts }}
22 | - {{ . | quote }}
23 | {{- end }}
24 | secretName: {{ .secretName }}
25 | {{- end }}
26 | {{- end }}
27 | rules:
28 | {{- range .Values.ingress.hosts }}
29 | - host: {{ .host | quote }}
30 | http:
31 | paths:
32 | {{- range .paths }}
33 | - path: {{ .path }}
34 | pathType: {{ .pathType }}
35 | backend:
36 | service:
37 | name: {{ include "the0.fullname" $ }}-{{ .service }}
38 | port:
39 | {{- if eq .service "frontend" }}
40 | number: {{ $.Values.the0Frontend.port }}
41 | {{- else if eq .service "api" }}
42 | number: {{ $.Values.the0Api.port }}
43 | {{- else if eq .service "minio" }}
44 | number: {{ $.Values.minio.port }}
45 | {{- end }}
46 | {{- end }}
47 | {{- end }}
48 | {{- end }}
--------------------------------------------------------------------------------
/docs/src/app/docs/[...slug]/page.tsx:
--------------------------------------------------------------------------------
1 | import { Metadata } from "next";
2 | import { notFound } from "next/navigation";
3 | import { DocsFileSystem } from "@/lib/docs/file-system";
4 | import { DocsContent } from "@/components/docs/doc-content";
5 | interface DocsPageProps {
6 | params: Promise<{ slug: string[] }>;
7 | }
8 |
9 | export async function generateStaticParams() {
10 | const fileSystem = new DocsFileSystem();
11 | const allDocs = await fileSystem.getAllDocs();
12 |
13 | return allDocs.map((doc) => ({
14 | slug: doc.slug,
15 | }));
16 | }
17 |
18 | export async function generateMetadata({
19 | params,
20 | }: DocsPageProps): Promise {
21 | const { slug } = await params;
22 | const fileSystem = new DocsFileSystem();
23 | const doc = await fileSystem.getDocContent(slug);
24 |
25 | if (!doc) {
26 | return {
27 | title: "Documentation Not Found | Theo",
28 | };
29 | }
30 |
31 | return {
32 | title: `${doc.frontmatter.title || "Documentation"} | Theo`,
33 | description: doc.frontmatter.description || "Theo platform documentation",
34 | keywords: doc.frontmatter.tags || [],
35 | };
36 | }
37 |
38 | export default async function DocsPage({ params }: DocsPageProps) {
39 | const { slug } = await params;
40 | const fileSystem = new DocsFileSystem();
41 | const doc = await fileSystem.getDocContent(slug);
42 |
43 | if (!doc) {
44 | notFound();
45 | }
46 |
47 | return (
48 |
53 | );
54 | }
55 |
--------------------------------------------------------------------------------
/frontend/src/components/main-navigation/nav-item.tsx:
--------------------------------------------------------------------------------
1 | import Link from "next/link";
2 | import { cn } from "@/lib/utils";
3 | import {
4 | Tooltip,
5 | TooltipContent,
6 | TooltipProvider,
7 | TooltipTrigger,
8 | } from "@/components/ui/tooltip";
9 | import { JSX } from "react";
10 |
11 | interface NavItemProps {
12 | href: string;
13 | icon: (props: React.SVGProps) => JSX.Element;
14 | name: string;
15 | isActive: boolean;
16 | isCollapsed: boolean;
17 | }
18 |
19 | export function NavItem({
20 | href,
21 | icon: Icon,
22 | name,
23 | isActive,
24 | isCollapsed,
25 | }: NavItemProps) {
26 | const link = (
27 |
36 |
40 | {!isCollapsed && {name} }
41 |
42 | );
43 |
44 | if (isCollapsed) {
45 | return (
46 |
47 |
48 | {link}
49 |
50 | {name}
51 |
52 |
53 |
54 | );
55 | }
56 |
57 | return link;
58 | }
59 |
--------------------------------------------------------------------------------
/runtime/Makefile:
--------------------------------------------------------------------------------
1 | # Variables
2 | BINARY_NAME=runtime
3 | BUILD_DIR=./build
4 | DOCKER_TAG=latest
5 |
6 | # Go related variables
7 | GOBIN=$(shell go env GOBIN)
8 |
9 | .PHONY: install-proto-tools build-proto go-build clean docker-build up down test test-unit test-integration test-all fmt
10 |
11 | # Protocol Buffer related targets
12 | install-proto-tools:
13 | @echo "Installing Protocol Buffer and gRPC tools..."
14 | go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
15 | go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
16 | @echo "Done! Make sure $(GOBIN) is in your PATH."
17 | @echo "Current PATH: $(PATH)"
18 |
19 | build-proto:
20 | @echo "Building Protocol Buffers..."
21 | protoc --go_out=. --go-grpc_out=. pb/worker.proto
22 | @echo "Done! Generated files are in ./pkg/proto."
23 |
24 | # Build related targets
25 | go-build: install-proto-tools build-proto
26 | @echo "Building the project..."
27 | go build -o $(BUILD_DIR)/$(BINARY_NAME) ./cmd/app
28 | @echo "Done! Executable is in the build directory."
29 |
30 | clean:
31 | @echo "Cleaning up..."
32 | rm -rf $(BUILD_DIR)/$(BINARY_NAME)
33 | @echo "Done! Cleaned up the build files."
34 |
35 | # Docker related targets
36 | docker-build:
37 | @echo "Building Docker image..."
38 | docker build -t $(BINARY_NAME):$(DOCKER_TAG) .
39 | @echo "Done! Docker image is built."
40 |
41 | # Test related targets
42 | test:
43 | @echo "Running all tests..."
44 | go test -v ./...
45 | @echo "Done! All tests completed."
46 |
47 | fmt:
48 | @echo "Formatting code..."
49 | go fmt ./...
50 | @echo "Done! Code is formatted."
--------------------------------------------------------------------------------
/docs/src/app/api/docs/raw/route.ts:
--------------------------------------------------------------------------------
1 | import { NextResponse } from "next/server";
2 | import { DocsFileSystem } from "@/lib/docs/file-system";
3 |
4 | /**
5 | * GET /api/docs/raw
6 | * Returns a list of all available documentation files for LLM navigation
7 | */
8 | export async function GET() {
9 | try {
10 | const fileSystem = new DocsFileSystem();
11 | const navigation = await fileSystem.getNavigationTree();
12 |
13 | // Flatten the navigation tree into a list of paths with metadata
14 | const flattenDocs = (items: any[], prefix: string = ""): any[] => {
15 | let result: any[] = [];
16 |
17 | for (const item of items) {
18 | const path = prefix ? `${prefix}/${item.slug}` : item.slug;
19 |
20 | if (item.type === "file") {
21 | result.push({
22 | path: path,
23 | url: `/api/docs/raw/${path}/`,
24 | title: item.title,
25 | description: item.description,
26 | });
27 | }
28 |
29 | if (item.children && item.children.length > 0) {
30 | result = result.concat(flattenDocs(item.children, path));
31 | }
32 | }
33 |
34 | return result;
35 | };
36 |
37 | const docs = flattenDocs(navigation);
38 |
39 | return NextResponse.json({
40 | success: true,
41 | count: docs.length,
42 | docs: docs,
43 | });
44 | } catch (error) {
45 | console.error("Error fetching docs index:", error);
46 | return NextResponse.json(
47 | { success: false, error: "Failed to fetch docs index" },
48 | { status: 500 },
49 | );
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/docs/src/app/docs/[...slug]/loading.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Skeleton } from "@/components/ui/skeleton";
3 |
4 | export default function DocsLoading() {
5 | return (
6 |
7 |
8 |
9 | {/* Header skeleton */}
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | {/* Content skeleton */}
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | );
43 | }
44 |
--------------------------------------------------------------------------------
/cli/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for the0 CLI
2 |
3 | .PHONY: build test clean install lint
4 |
5 | # Version can be overridden, defaults to 0.0.0-dev for local development
6 | VERSION ?= 0.0.0-dev
7 |
8 | # Build the CLI binary
9 | build:
10 | go build -ldflags="-X main.VERSION=$(VERSION)" -o bin/the0 .
11 |
12 | # Run tests
13 | test:
14 | go test ./... -v
15 |
16 | # Run tests with coverage
17 | test-coverage:
18 | go test ./... -v -coverprofile=coverage.out
19 | go tool cover -html=coverage.out -o coverage.html
20 |
21 | # Clean build artifacts
22 | clean:
23 | rm -rf bin/
24 | rm -f coverage.out coverage.html
25 | rm -f bot_*.zip
26 |
27 | # Install dependencies
28 | deps:
29 | go mod tidy
30 | go mod download
31 |
32 | # Lint the code
33 | lint:
34 | golangci-lint run
35 |
36 | # Install the CLI locally
37 | install: build
38 | cp bin/the0 ~/bin/the0
39 |
40 | # Run the CLI in development mode
41 | dev: build
42 | ./bin/the0
43 |
44 | # Format code
45 | fmt:
46 | go fmt ./...
47 |
48 | # Verify everything is ready for release
49 | verify: fmt lint test build
50 | @echo "✅ All checks passed!"
51 |
52 | # Release build with optimizations
53 | release:
54 | CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s -X main.VERSION=$(VERSION)" -o bin/the0-linux-amd64 .
55 | CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags="-w -s -X main.VERSION=$(VERSION)" -o bin/the0-darwin-amd64 .
56 | CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -ldflags="-w -s -X main.VERSION=$(VERSION)" -o bin/the0-darwin-arm64 .
57 | CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="-w -s -X main.VERSION=$(VERSION)" -o bin/the0-windows-amd64.exe .
58 |
59 |
--------------------------------------------------------------------------------
/docs/src/components/ui/avatar.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as AvatarPrimitive from "@radix-ui/react-avatar";
5 |
6 | import { cn } from "@/lib/utils";
7 |
8 | const Avatar = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(({ className, ...props }, ref) => (
12 |
20 | ));
21 | Avatar.displayName = AvatarPrimitive.Root.displayName;
22 |
23 | const AvatarImage = React.forwardRef<
24 | React.ElementRef,
25 | React.ComponentPropsWithoutRef
26 | >(({ className, ...props }, ref) => (
27 |
32 | ));
33 | AvatarImage.displayName = AvatarPrimitive.Image.displayName;
34 |
35 | const AvatarFallback = React.forwardRef<
36 | React.ElementRef,
37 | React.ComponentPropsWithoutRef
38 | >(({ className, ...props }, ref) => (
39 |
47 | ));
48 | AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
49 |
50 | export { Avatar, AvatarImage, AvatarFallback };
51 |
--------------------------------------------------------------------------------
/frontend/src/app/custom-bots/not-found.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Link from "next/link";
3 | import DashboardLayout from "@/components/layouts/dashboard-layout";
4 | import { Button } from "@/components/ui/button";
5 | import { Bot, ArrowLeft, Home } from "lucide-react";
6 |
7 | export default function NotFound() {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
Custom Bot Not Found
17 |
18 | The custom bot you're looking for doesn't exist or you
19 | don't have permission to view it.
20 |
21 |
22 |
23 |
24 |
25 |
26 | Back to Custom Bots
27 |
28 |
29 |
30 |
31 |
32 | Go to Dashboard
33 |
34 |
35 |
36 |
37 |
38 |
39 | );
40 | }
41 |
--------------------------------------------------------------------------------
/frontend/src/components/ui/avatar.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as AvatarPrimitive from "@radix-ui/react-avatar";
5 |
6 | import { cn } from "@/lib/utils";
7 |
8 | const Avatar = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(({ className, ...props }, ref) => (
12 |
20 | ));
21 | Avatar.displayName = AvatarPrimitive.Root.displayName;
22 |
23 | const AvatarImage = React.forwardRef<
24 | React.ElementRef,
25 | React.ComponentPropsWithoutRef
26 | >(({ className, ...props }, ref) => (
27 |
32 | ));
33 | AvatarImage.displayName = AvatarPrimitive.Image.displayName;
34 |
35 | const AvatarFallback = React.forwardRef<
36 | React.ElementRef,
37 | React.ComponentPropsWithoutRef
38 | >(({ className, ...props }, ref) => (
39 |
47 | ));
48 | AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
49 |
50 | export { Avatar, AvatarImage, AvatarFallback };
51 |
--------------------------------------------------------------------------------
/frontend/src/lib/auth-fetch.ts:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | export interface AuthFetchOptions extends RequestInit {
4 | skipTokenRefresh?: boolean;
5 | }
6 |
7 | // Global auth service reference - will be set by auth context
8 | let globalAuthService: any = null;
9 | let globalLogout: (() => Promise) | null = null;
10 |
11 | // Function to set the auth service from the context
12 | export const setAuthFetchService = (
13 | authService: any,
14 | logoutFn: () => Promise,
15 | ) => {
16 | globalAuthService = authService;
17 | globalLogout = logoutFn;
18 | };
19 |
20 | export async function authFetch(
21 | url: string,
22 | options: AuthFetchOptions = {},
23 | ): Promise {
24 | if (!globalAuthService) {
25 | throw new Error("Auth service not initialized");
26 | }
27 |
28 | const token = globalAuthService.getToken();
29 |
30 | if (!token) {
31 | throw new Error("Not authenticated");
32 | }
33 |
34 | const { skipTokenRefresh, ...fetchOptions } = options;
35 |
36 | const requestOptions: RequestInit = {
37 | ...fetchOptions,
38 | headers: {
39 | "Content-Type": "application/json",
40 | ...fetchOptions.headers,
41 | Authorization: `Bearer ${token}`,
42 | },
43 | };
44 |
45 | const response = await fetch(url, requestOptions);
46 |
47 | // If 401 and not skipping refresh, use centralized logout
48 | if (response.status === 401 && !skipTokenRefresh) {
49 | if (globalLogout) {
50 | await globalLogout();
51 | } else if (globalAuthService) {
52 | globalAuthService.logout();
53 | }
54 | throw new Error("Authentication failed");
55 | }
56 |
57 | return response;
58 | }
59 |
--------------------------------------------------------------------------------
/frontend/src/lib/users.ts:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { Failure, Ok, Result } from "@/lib/result";
3 | import { UserService, ApiUser } from "@/lib/api/user.service";
4 | // Use ApiUser as UserData for compatibility
5 | export type UserData = ApiUser;
6 |
7 | export type UserRepositoryError = {
8 | error: string;
9 | status: number;
10 | };
11 |
12 | export class UserRepository {
13 | static async create(
14 | userId: string,
15 | email: string,
16 | displayName?: string | null,
17 | ): Promise> {
18 | return await UserService.createUser({
19 | userId,
20 | email,
21 | displayName: displayName || undefined,
22 | });
23 | }
24 |
25 | static async get(
26 | userId: string,
27 | ): Promise> {
28 | return await UserService.getUser(userId);
29 | }
30 |
31 | static async update(
32 | userId: string,
33 | data: Partial,
34 | ): Promise> {
35 | const result = await UserService.updateUser(userId, {
36 | displayName: data.displayName || undefined,
37 | photoURL: data.photoURL || undefined,
38 | });
39 | if (result.success) {
40 | return Ok(null);
41 | }
42 | return Failure(result.error!);
43 | }
44 |
45 | static async updateLastLogin(
46 | userId: string,
47 | ): Promise> {
48 | return await UserService.updateLastLogin(userId);
49 | }
50 |
51 | static async deleteUser(
52 | userId: string,
53 | ): Promise> {
54 | return await UserService.deleteUser(userId);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/frontend/src/components/ai-agent/chat/ChatInput.tsx:
--------------------------------------------------------------------------------
1 | import { useState, KeyboardEvent } from "react";
2 | import { Button } from "@/components/ui/button";
3 | import { Textarea } from "@/components/ui/textarea";
4 | import { Send } from "lucide-react";
5 |
6 | interface ChatInputProps {
7 | onSendMessage: (message: string) => void;
8 | disabled?: boolean;
9 | }
10 |
11 | export function ChatInput({ onSendMessage, disabled = false }: ChatInputProps) {
12 | const [message, setMessage] = useState("");
13 |
14 | const handleSend = () => {
15 | if (message.trim() && !disabled) {
16 | onSendMessage(message.trim());
17 | setMessage("");
18 | }
19 | };
20 |
21 | const handleKeyDown = (e: KeyboardEvent) => {
22 | if (e.key === "Enter" && !e.shiftKey) {
23 | e.preventDefault();
24 | handleSend();
25 | }
26 | };
27 |
28 | return (
29 |
30 |
31 |
40 |
46 |
47 | Send message
48 |
49 |
50 | );
51 | }
52 |
--------------------------------------------------------------------------------
/api/drizzle.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from 'drizzle-kit';
2 |
3 | // Load config directly from environment variables
4 | const databaseUrl = process.env.DATABASE_URL;
5 | const databaseType = process.env.DATABASE_TYPE || 'sqlite';
6 |
7 | // Parse PostgreSQL URL if provided
8 | let dbConfig: any = {};
9 | if (databaseType === 'postgresql' && databaseUrl) {
10 | const url = new URL(databaseUrl);
11 | dbConfig = {
12 | host: url.hostname,
13 | port: parseInt(url.port) || 5432,
14 | user: url.username,
15 | password: url.password,
16 | database: url.pathname.slice(1),
17 | };
18 | }
19 |
20 | export default (databaseType === 'sqlite'
21 | ? {
22 | schema: [
23 | './src/database/schema/users.ts',
24 | './src/database/schema/custom-bots.ts',
25 | './src/database/schema/bots.ts',
26 | './src/database/schema/backtests.ts'
27 | ],
28 | out: './src/database/migrations',
29 | driver: 'better-sqlite' as const,
30 | dbCredentials: { url: databaseUrl || './data/the0.db' },
31 | verbose: true,
32 | strict: true,
33 | }
34 | : {
35 | schema: [
36 | './src/database/schema/users.ts',
37 | './src/database/schema/custom-bots.ts',
38 | './src/database/schema/bots.ts',
39 | './src/database/schema/backtests.ts'
40 | ],
41 | out: './src/database/migrations',
42 | driver: 'pg' as const,
43 | dbCredentials: {
44 | connectionString: databaseUrl || `postgresql://${dbConfig.user}:${dbConfig.password}@${dbConfig.host}:${dbConfig.port}/${dbConfig.database}`,
45 | },
46 | verbose: true,
47 | strict: true,
48 | }) satisfies Config;
--------------------------------------------------------------------------------
/docs/src/docs/terminology/backtesting.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Backtesting"
3 | description: "Testing trading strategies with historical data"
4 | tags: ["terminology", "backtesting", "testing"]
5 | order: 6
6 | ---
7 |
8 | # Backtesting
9 |
10 | Backtesting is the process of testing a trading strategy using historical market data to evaluate its potential performance. In the0, developers can implement any backtesting logic they prefer, including sophisticated methods like walk-forward analysis and Monte Carlo simulations. The platform requires backtest functions to return results in a structured format containing **metrics**, **plots**, and **tables**. see the [Backtest Development Guide](/docs/custom-bot-development/backtesting) for more details on implementation.
11 |
12 |  
13 |
14 | ---
15 |
16 | ## Overview
17 |
18 | Backtesting allows traders to:
19 |
20 | - Evaluate strategy performance before risking real capital
21 | - Identify potential issues and edge cases
22 | - Optimize parameters for better results
23 | - Build confidence in their trading approach
24 |
25 | ---
26 |
27 | ## How to perform Backtesting
28 |
29 | To perform backtesting for a Custom Bot.
30 |
31 | ### Custom Bots
32 |
33 | - Go to the [Custom Bots](/custom-bots) section
34 | - Select a bot and click "Backtest"
35 | - Configure the backtest parameters (date range, data source, etc.)
36 | - Run the backtest and view results
37 |
38 | ---
39 |
40 | ## Related Terms
41 |
42 | - [Custom Bots](/docs/terminology/custom-bots) - Define backtest entry points
43 | - [Monitoring](/docs/terminology/monitoring) - Track live performance vs backtest
44 |
--------------------------------------------------------------------------------