mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
Encrypt and store secret ENV vars in the repo with dotenvx (#114)
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> Co-authored-by: Matt Rubens <mrubens@users.noreply.github.com> Co-authored-by: John Richmond <5629+jr@users.noreply.github.com>
This commit is contained in:
parent
680a96fc9f
commit
5edb2f8bb6
74 changed files with 1032 additions and 965 deletions
|
|
@ -1,31 +0,0 @@
|
|||
# docker compose build base
|
||||
|
||||
FROM node:20-slim AS base
|
||||
|
||||
# Install pnpm
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN corepack enable
|
||||
|
||||
# Install common system packages
|
||||
RUN apt update && \
|
||||
apt install -y \
|
||||
curl \
|
||||
git \
|
||||
vim \
|
||||
jq \
|
||||
netcat-openbsd \
|
||||
apt-transport-https \
|
||||
ca-certificates \
|
||||
gnupg \
|
||||
lsb-release \
|
||||
wget \
|
||||
gpg \
|
||||
gh \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Docker cli
|
||||
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \
|
||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \
|
||||
&& apt update && apt install -y docker-ce-cli \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
|
@ -1,12 +1,41 @@
|
|||
# docker compose build roomote-api
|
||||
# docker compose build roomote-api && docker compose up roomote-api
|
||||
|
||||
FROM roo-code-cloud-base AS base
|
||||
FROM node:20-slim AS base
|
||||
|
||||
# Install pnpm
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN corepack enable
|
||||
|
||||
# Install common system packages
|
||||
RUN apt update && \
|
||||
apt install -y \
|
||||
curl \
|
||||
git \
|
||||
vim \
|
||||
jq \
|
||||
netcat-openbsd \
|
||||
apt-transport-https \
|
||||
ca-certificates \
|
||||
gnupg \
|
||||
lsb-release \
|
||||
wget \
|
||||
gpg \
|
||||
gh \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Docker cli
|
||||
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \
|
||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \
|
||||
&& apt update && apt install -y docker-ce-cli \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /roo
|
||||
|
||||
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json ./
|
||||
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json .env.* ./
|
||||
COPY packages/config-eslint/package.json ./packages/config-eslint/
|
||||
COPY packages/config-typescript/package.json ./packages/config-typescript/
|
||||
COPY packages/env/package.json ./packages/env/
|
||||
COPY packages/db/package.json ./packages/db/
|
||||
COPY packages/ipc/package.json ./packages/ipc/
|
||||
COPY apps/roomote/package.json ./apps/roomote/
|
||||
|
|
@ -15,13 +44,14 @@ RUN pnpm install
|
|||
|
||||
COPY packages/config-eslint ./packages/config-eslint/
|
||||
COPY packages/config-typescript ./packages/config-typescript/
|
||||
COPY packages/env ./packages/env/
|
||||
COPY packages/db ./packages/db/
|
||||
COPY packages/ipc ./packages/ipc/
|
||||
COPY apps/roomote ./apps/roomote/
|
||||
|
||||
WORKDIR /roo/apps/roomote
|
||||
RUN node_modules/.bin/next build
|
||||
RUN npx dotenvx run -f ../../.env.${APP_ENV:-development} -- node_modules/.bin/next build
|
||||
|
||||
EXPOSE 3001
|
||||
ENV NODE_ENV=production
|
||||
CMD ["node_modules/.bin/next", "start", "--port", "3001"]
|
||||
CMD ["sh", "-c", "npx dotenvx run -f ../../.env.${APP_ENV:-development} -- node_modules/.bin/next start --port 3001"]
|
||||
|
|
|
|||
|
|
@ -1,12 +1,41 @@
|
|||
# docker compose build roomote-controller
|
||||
# docker compose build roomote-controller && docker compose up roomote-controller
|
||||
|
||||
FROM roo-code-cloud-base AS base
|
||||
FROM node:20-slim AS base
|
||||
|
||||
# Install pnpm
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN corepack enable
|
||||
|
||||
# Install common system packages
|
||||
RUN apt update && \
|
||||
apt install -y \
|
||||
curl \
|
||||
git \
|
||||
vim \
|
||||
jq \
|
||||
netcat-openbsd \
|
||||
apt-transport-https \
|
||||
ca-certificates \
|
||||
gnupg \
|
||||
lsb-release \
|
||||
wget \
|
||||
gpg \
|
||||
gh \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Docker cli
|
||||
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \
|
||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \
|
||||
&& apt update && apt install -y docker-ce-cli \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /roo
|
||||
|
||||
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
||||
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json .env.* ./
|
||||
COPY packages/config-eslint/package.json ./packages/config-eslint/
|
||||
COPY packages/config-typescript/package.json ./packages/config-typescript/
|
||||
COPY packages/env/package.json ./packages/env/
|
||||
COPY packages/db/package.json ./packages/db/
|
||||
COPY packages/ipc/package.json ./packages/ipc/
|
||||
COPY apps/roomote/package.json ./apps/roomote/
|
||||
|
|
@ -15,11 +44,13 @@ RUN pnpm install
|
|||
|
||||
COPY packages/config-eslint ./packages/config-eslint/
|
||||
COPY packages/config-typescript ./packages/config-typescript/
|
||||
COPY packages/env ./packages/env/
|
||||
COPY packages/db ./packages/db/
|
||||
COPY packages/ipc ./packages/ipc/
|
||||
COPY apps/roomote ./apps/roomote/
|
||||
|
||||
WORKDIR /roo/apps/roomote
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV HOST_EXECUTION_METHOD=docker
|
||||
CMD ["pnpm", "controller"]
|
||||
CMD ["sh", "-c", "npx dotenvx run -f ../../.env.${APP_ENV:-development} -- tsx src/lib/controller.ts"]
|
||||
|
|
|
|||
|
|
@ -1,22 +1,52 @@
|
|||
# docker compose build roomote-dashboard
|
||||
# docker compose build roomote-dashboard && docker compose up roomote-dashboard
|
||||
|
||||
FROM roo-code-cloud-base AS base
|
||||
FROM node:20-slim AS base
|
||||
|
||||
# Install pnpm
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN corepack enable
|
||||
|
||||
# Install common system packages
|
||||
RUN apt update && \
|
||||
apt install -y \
|
||||
curl \
|
||||
git \
|
||||
vim \
|
||||
jq \
|
||||
netcat-openbsd \
|
||||
apt-transport-https \
|
||||
ca-certificates \
|
||||
gnupg \
|
||||
lsb-release \
|
||||
wget \
|
||||
gpg \
|
||||
gh \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Docker cli
|
||||
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \
|
||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \
|
||||
&& apt update && apt install -y docker-ce-cli \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /roo
|
||||
|
||||
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
||||
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json .env.* ./
|
||||
COPY packages/config-eslint/package.json ./packages/config-eslint/
|
||||
COPY packages/config-typescript/package.json ./packages/config-typescript/
|
||||
COPY packages/env/package.json ./packages/env/
|
||||
COPY apps/roomote-dashboard/package.json ./apps/roomote-dashboard/
|
||||
|
||||
RUN pnpm install
|
||||
|
||||
COPY packages/config-eslint ./packages/config-eslint/
|
||||
COPY packages/config-typescript ./packages/config-typescript/
|
||||
COPY packages/env ./packages/env/
|
||||
COPY apps/roomote-dashboard ./apps/roomote-dashboard/
|
||||
|
||||
WORKDIR /roo/apps/roomote-dashboard
|
||||
|
||||
EXPOSE 3002
|
||||
ENV NODE_ENV=production
|
||||
CMD ["pnpm", "dev"]
|
||||
CMD ["sh", "-c", "npx dotenvx run -f ../../.env.${APP_ENV:-development} -- tsx src/index.ts"]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,34 @@
|
|||
# docker compose build roomote-worker
|
||||
# Note: Requires $GH_TOKEN to be set as build argument.
|
||||
# docker compose build roomote-worker && docker compose up roomote-worker
|
||||
|
||||
FROM roo-code-cloud-base AS base
|
||||
FROM node:20-slim AS base
|
||||
|
||||
# Install pnpm
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN corepack enable
|
||||
|
||||
# Install common system packages
|
||||
RUN apt update && \
|
||||
apt install -y \
|
||||
curl \
|
||||
git \
|
||||
vim \
|
||||
jq \
|
||||
netcat-openbsd \
|
||||
apt-transport-https \
|
||||
ca-certificates \
|
||||
gnupg \
|
||||
lsb-release \
|
||||
wget \
|
||||
gpg \
|
||||
gh \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Docker cli
|
||||
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \
|
||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \
|
||||
&& apt update && apt install -y docker-ce-cli \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install additional worker-specific packages
|
||||
RUN apt update && \
|
||||
|
|
@ -39,11 +66,12 @@ WORKDIR /roo/repos/Roo-Code
|
|||
RUN gh repo set-default RooCodeInc/Roo-Code
|
||||
RUN pnpm install
|
||||
|
||||
# Install dependencies
|
||||
WORKDIR /roo
|
||||
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
||||
|
||||
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json .env.* ./
|
||||
COPY packages/config-eslint/package.json ./packages/config-eslint/
|
||||
COPY packages/config-typescript/package.json ./packages/config-typescript/
|
||||
COPY packages/env/package.json ./packages/env/
|
||||
COPY packages/db/package.json ./packages/db/
|
||||
COPY packages/ipc/package.json ./packages/ipc/
|
||||
COPY apps/roomote/package.json ./apps/roomote/
|
||||
|
|
@ -52,11 +80,13 @@ RUN pnpm install
|
|||
|
||||
COPY packages/config-eslint ./packages/config-eslint/
|
||||
COPY packages/config-typescript ./packages/config-typescript/
|
||||
COPY packages/env ./packages/env/
|
||||
COPY packages/db ./packages/db/
|
||||
COPY packages/ipc ./packages/ipc/
|
||||
COPY apps/roomote ./apps/roomote/
|
||||
|
||||
WORKDIR /roo/apps/roomote
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV HOST_EXECUTION_METHOD=docker
|
||||
CMD ["pnpm", "worker"]
|
||||
CMD ["sh", "-c", "npx dotenvx run -f ../../.env.${APP_ENV:-development} -- tsx src/lib/controller.ts"]
|
||||
|
|
|
|||
|
|
@ -28,3 +28,6 @@ knip.json
|
|||
# next.js
|
||||
**/.next/
|
||||
.vercel
|
||||
|
||||
# env
|
||||
.env.keys
|
||||
|
|
|
|||
0
.env
0
.env
24
.env.development
Normal file
24
.env.development
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#/-------------------[DOTENV_PUBLIC_KEY]--------------------/
|
||||
#/ public-key encryption for .env files /
|
||||
#/ [how it works](https://dotenvx.com/encryption) /
|
||||
#/----------------------------------------------------------/
|
||||
DOTENV_PUBLIC_KEY_DEVELOPMENT="022703b50cc07889c89fc1425f6a780fc2cd813976eb5c9ed710687e550a0e1083"
|
||||
|
||||
# .env.development
|
||||
DATABASE_URL=encrypted:BHEnYqWD6ebRKQM5nSA9ETE9BERgb1KghegFptV61hZSoF267Iv1wXbJnMRSqvF8ZIMkr2FSlx3YhGRX+fmo82xEZdtiyy58PCVVHsPWaliX03TFqrEY8KyKRtkX8zbNccTf+rEtQ9Gq0TzGlhKp0fWe22IprYdMKJpmF8pJmFjCf91SbmpnUwuUuo93UI/dGOCUkNi+Uw==
|
||||
REDIS_URL=encrypted:BOG9yPmE7Gx/5tqBwICkJGmsd/SyfsRhCtzFhZSz2D8bZdmR+AcJVoDlBSG2PPxbtSEPrm1Bv51vmN5pArO5+vm+Uu9IPaUzSA6/5IDGgw0MsFiSTcmkQq8KQHXyRArrm+bwSMbvyG9tzdNpRbgjkh6vvg==
|
||||
|
||||
CLICKHOUSE_URL=encrypted:BJ9IPsZpsMW7rNYj89ZDfNAtpeAIIFmRcruWSgOTIsx6/ou3layaIwU/l5Nv5PEMqOWVZSWIU4+D6AEVprxCm9QzILWoBirEQRXBFMHAd5h0DgfRdDANB4/N6VyGKWJUPWLYbuOjs3qcJ54exM5mICapG0wgG/GlIEOyvAojuw==
|
||||
CLICKHOUSE_PASSWORD=encrypted:BJ4Fdj7rqLD/7ElnUW2c5vuq/30mfXKTZBpxeUc1/kOSx5HzQZWgzSKam95l9pnP+EXuVgdofHwmsj2P9CN/+fm2OpdNwSG4yhFQkn27kj2nsaNiK/eyNchnprU0dlOnJUiYlcyENtAa
|
||||
|
||||
CLERK_SECRET_KEY=encrypted:BOd1VAy8MDjf1xmeiN3/ez4TDwmSDgvpLkA27q+lIFlLAc953bwA4aUlU1FlDuoiVoouQJnn+1lLNHqkZ9l7ZInDB3fHGJYQYOHKY2563kOj24GBC5lNWRr2I8xU+Q2OuXSlTddYflHedqwZvhNOA9GCXd8kdxRqQ3xYRmxvj0XS1jUhvxmaBwFiGbZx+zd+Lspj
|
||||
|
||||
GH_WEBHOOK_SECRET=encrypted:BG5ptaSJzmurbp1p1QTSl2Iyl6OQT5ONbjW4tbxQAdgUi+iOMHeFISIsRIFVCsLGKNDE9yOfV/NTzGfwwlG5s7xkvYffIIIRtZLr049ImgLHr14wXNrU+BQkU4QNHhA6P7GiQ+wfGocn28uJxtEirpSizhdSrfkusyYIt+iCTd2C
|
||||
GH_TOKEN=encrypted:BGQvKArqcFk+y2UmBmzUZVBo6cNtDH20i0kHiqoGDRqAoFUJkc2hEumU6ukK+OSoATTLSAtRxfjwNLf9VTjHaGkRn4jExqNhvMCDLQqP8nTQ6NWvssvfb9e8RY4KAjTqXBBK1sCNfSWN647y+9pcTho4SMpmpb18clhuBkT0TlF7lyyckVE5aeM=
|
||||
|
||||
OPENROUTER_API_KEY=encrypted:BA3bYeSEXFA0jnw3lmzLKz53ekkGr0K6sDLN6+nFGsa0TdJrYoKI5IcRPCMWuXIoLR1dlRi61eziWMQt0e2MgLU8zcR+zKif/2twlIzFlTU7OtFSwC1DPknxAG0pf3e2LSTDiLU4hRKgYbdJn8coA3rf/YY9NRVlmJV1gDLb9KVL89IWgT+fEn3Tzh383dSolr1ec/9RyAYVGpIYTg4O57OzQ9TaZp6InWs=
|
||||
|
||||
SLACK_API_TOKEN=encrypted:BI5T2ZFY35FaOfSzPT8qQyUdhJs+fmL6wOFp8cVd4hM0xcSJ8va+vk1CCpltNrk25uXCd8D+fQnITb3G+L/1z1X8eqZVobqRwxO39wTcqVv1d9AQSLxAmYcEoAEWowiXQei2qS+AMcBSjZhDfURbdOfYo1+XHj0NdfspvsB1YwC+3CN3iZC/TSVBkzcQDy82Db541HnfFxhIQg==
|
||||
|
||||
|
||||
|
||||
22
.env.preview
Normal file
22
.env.preview
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#/-------------------[DOTENV_PUBLIC_KEY]--------------------/
|
||||
#/ public-key encryption for .env files /
|
||||
#/ [how it works](https://dotenvx.com/encryption) /
|
||||
#/----------------------------------------------------------/
|
||||
DOTENV_PUBLIC_KEY_PREVIEW="03daea73b84e36000e1ecd63e339e6a49793b3212a48929896d0e7d8a8c94b0525"
|
||||
|
||||
# .env.preview
|
||||
DATABASE_URL=encrypted:BOJ23F02TQxTqP7t+e1ViPBO13fODlyM9Nhb0cuEQRHjc8cQmL8e5kU8+pGKSBD4Skh03cHp327GrM3cQLfu7F20zFIazrXv6dg4urA6umlgZJpyc+N8GodZ+BUCKWBf554gcouQAp/OJN0CZgOlboP3982dCxMfUKdx3nPZVVH7QoNmfk5tIwfHTUYqGMuN7KIdjUopVsaGvAxpqz7X53RkbnOpH2AAZDFzsdeLNV6/PIhjzuIh
|
||||
REDIS_URL=encrypted:BOFDUP0rzhc/kIMljZ1QG4zOQROGFOApVU8kswfA/cJy09K103SS8V2t6wrWyWu3ZgwmBfNm3gQnrm8aP8ZNfFpTrm/V3azkeV+huzXLV81mkbu0zioO5f5OrPzvR5TVOz5+cQFVQdWzwGS/ZXDoLalmvIzPZ0u3nmFPRyMT9EJM8yGb59kF6E8OdfPFzO/Cw3K4xJtalufR2k+C5FZLC8AR6TFVUgQ+jlxSu66Zd5tAVGWk3QxAinn+kd41cqzENkKf0rBm1dG/DLZ00ggI
|
||||
|
||||
CLICKHOUSE_URL=encrypted:BFauYbJKvW/D63ZYffeTG8EEmb7icwBJkKobendgtsn9C1mG7AkAhmcr23pJSRjjhFAiNfxZyn92mWXzZFBbulhTgFo461Ppz/y4oq/8bvLv1WKSZHG9E0BrQLx4QYHX+KymDX6pabvUftKpbQq3TnRPDjtdlYPEjxTTXCBYM7gjKsWCzp8pp6tXCrtfSqzbXB5xy0A2Rw==
|
||||
CLICKHOUSE_PASSWORD=encrypted:BCZQ1MN8NoNoPVF3WxcIJLjSY5euH47/CVL4ESwAk0f6OZ6lstKFW4AaPrg5Wdd3uf9oPzcYM/dwawqhQ7bqYdtx76cBYbrtmHrirBWfvTlzX5knaV1E1xFE03jPvDGAAkK8RRU6UTQKC2lUq48=
|
||||
|
||||
CLERK_SECRET_KEY=encrypted:BIJlh3p2P0zzTxgP9AwYarPeT3DsHs44M4fTP+ZQfDWwjtZw4QVbNMh2NBKbSOO/bH1XTVOFPZzy7N/NXIygmqeSJwdVLwAanb0eJKq2dNbwN0MAVsPTgL0U4t5A+9ytLRcdYeivoFzQ49wL1J6D38cdYSTKXQwcO3GDCRycylBZdOOzHbP8mE/y46d4RkuK7nay
|
||||
|
||||
GH_WEBHOOK_SECRET=encrypted:BBVpX03MCeoEzrJbeP+bdWzB2bkDQ9VYMhZiRFckoBjN8foBb5oSI8YbyPKkRPCycfSTRirCddLzvNY/Q1Joe7pvynYubY0hW6YnbmVEaC6UYP27rGcWdJStMNfCI9OXvYaV765bjbmfBh59j+6FBTHzWuTS+xy84eRpcrzNiYjZ
|
||||
GH_TOKEN=encrypted:BMB+HR14pdhTojK7exBUDaWpiQGDWziDR5cdUMM/I24MpkdCtZrvHsf+uTc/gTSnP6uGzOHc1xQAQG3OOGxA6IBls13Gv8wvVDOUdPm0NoyFSGMAqE7HbBi6GFSuNstuRNy92QJo86ZWH7La8llJXCNZ3juzFESD/rfAD1odhBkzBVDXfPdDonM=
|
||||
|
||||
OPENROUTER_API_KEY=encrypted:BDoXCMz3fV5DXa89cwd77/pZhw6tVIw96LvtyZEFwFQtQV1Qk+ZmtQoObiKZkfI4y1ZvpOSL2ivXfS7YY8QtLnl8uEG550FHq6s0FZsVdua+SlmoUhJOK0zV341GadCG3bc5aSMB5Wha6ml51CJzy/AKud4U4Zi3eXaj+nMxeXF8wtnHsw51JQ3F7N9VnYklyrb5FEin2SVovg3TPZk40saP8Q/YyDyU8e8=
|
||||
|
||||
SLACK_API_TOKEN=encrypted:BFmTkof1HoUg2UTgpm2wWdv5ZqVuldkgU5xLhGjgGFqRG7sOnAF5QdUVAfjV+890FbGF/BxBcb7bJsjMdf6+krq5U8p8Il2lucELdg1BoWisGcoy1+OCYoLxWm4RDrI/zovC09vaSnIdgIpz4T/4sNRbY5U8r7KaKXSCDPp2rCTUAC9Fc5cODlurbnMbfmPaFJIxKktqm5rfXg==
|
||||
|
||||
22
.env.production
Normal file
22
.env.production
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#/-------------------[DOTENV_PUBLIC_KEY]--------------------/
|
||||
#/ public-key encryption for .env files /
|
||||
#/ [how it works](https://dotenvx.com/encryption) /
|
||||
#/----------------------------------------------------------/
|
||||
DOTENV_PUBLIC_KEY_PRODUCTION="0220845c470bea52e1a524ffb098188cd9560b3610032586efdd7580cd3bf5798f"
|
||||
|
||||
# .env.production
|
||||
DATABASE_URL=encrypted:BMAmRVLIX9odtXaqSTZwduXFizp16qjO/vmXKfrsAlLW1jrkgWpltAl6AkVpACQehua2oopJPeTISffC+qRhEHOw/kkn94ePuMrldS9Z5V6XlbT6eXJJIRVO81S1yFqipzDj00m3HwlvxlT4y912MPAfwApdzx888Tu7Dix6UODVSyiqEHfXc0/WNKo3ly1NDjT/VjIxcIIqRCXMYkTc7thLBfY5KltajL+U4MOOpPLK7lzRDd1v
|
||||
REDIS_URL=encrypted:BIsj6USwbqPSaFIoun8Gii1x/n2JTmpTEvMIKbN82noNRg0Wt1xJ8GEbrNB0UXxZ3Q7p/Ugf7zUu79MqsF2Nnkh5PkXxBJku0L4JNb2eoWZdiKHFaHVf5HAFG6yyIQtKVHWjS82BOA/QQMiZkgZ2VVYwB6zvrDNkIuI6tGCVdRkAm9grvPjgHDFc6ggd0o4OotBoK5mN0UdF5Jl+ILALNyZAsc8mvVJmtJSLvFWbjRe4bM14usNRGkq48ekuoyndt6g/3AzIvlUL4dsrd7TJosVWEpA=
|
||||
|
||||
CLICKHOUSE_URL=encrypted:BNN8odgd5JZkV1lxYKejudbFTMClmNzerqnNTT1ALZxVH6en86Kn4kv2nb1ykFtp+NSED84BLBwrd2UdclIuaHpKreDtgVBnND34St2e+Coo52XJyvCFdgJ5E8KlDEPEukn6Ju+/oJORzhEUBUclPnrtQjOwIufEjojt9jZQ8tq6Hf/Y5c6CNgY+OeMjq5tjf6EX5uIs4g==
|
||||
CLICKHOUSE_PASSWORD=encrypted:BGDdYw0Se+gkPbdpqzbrWq40r+B4s1iW4CGS61Ybq8eZzKs+b9KjD3fBqI3Z8n5mETSLheNFaYsanFj+1IzsdOz0t8YpapXmZAZyCDWLBmXrh49vlf+hhfrgdC1L/JO4H5wL/d01g+iDuuwJZz0=
|
||||
|
||||
CLERK_SECRET_KEY=encrypted:BDV4gzZvpKtTMWjY/5eTjuq99u13Ukr941xK4kvMvmKNEvf18znpa8vXDS9VZhKG/Od1Sp1axCv5YEDq7x9u3YE+hcS5NrldE6uOqbTwzO6HLYvHdiT/PKDiEmUmnW8p4GrS+MqaNlY9JNie/TSUzebLzvN5SzWIZfiiLXoHLFuTtrvoJ9NU2GZWjtSwXT0ndCkW
|
||||
|
||||
GH_WEBHOOK_SECRET=encrypted:BAoBNKhYwOuEAVJTBdEhmM2E+P9EiJJO1Zuf6v3xkDziWVIgTkjy0HPgN3+v4HauJCcQSzRBojd99QoyhTARmNGM55V3S9ErBWO/aS1rVJbWhRq25xHGBZU/r36a5kbpYA9t8u4oQ1O0b0E9U/xGmukqqrbWAZmi6GLjkcFiARAQ
|
||||
GH_TOKEN=encrypted:BN93qO9v+VfEZFaIdRwyhwR2CPM0rw1QUE9SSm/qjIT6W9XnL4Gg6EStB9zfldMIA4oD+MEQqsfllXCIcpjNHfUlbeFeM+Ma9a1lhP5oD4B5pKlZW+qVk3Ne5Yr/c0okgyzGUp2RzWENIyDvxubMevBczZ6Uo36yjqlvhUcRYhfRB2wWx7Y4I8Q=
|
||||
|
||||
OPENROUTER_API_KEY=encrypted:BLBANC6AI/i5gHIeiBaY5lOogEEahxSLAvsxUpk6Z1FXtfrIEj/6EKA/CE1LzHOJEZNIXHTtlb41ONGQWuRFtgDcvbhSthZ5XZB4c9dcdPz0cxEU4RfWSRwjQxYZ8OMs1oLdr7NV8oR6IYwJ43lVfuePBYit7zX125Mp/25R7Kl50oSVREHnlfhtOMTOTQqLI7LutgGvQiDym1Ji1BFDaTBd4rTrkoymYxo=
|
||||
|
||||
SLACK_API_TOKEN=encrypted:BHrN/c76f9fFC6XlzfgRnrb2NXK1jlGrq5XbSqk0FM+t4BaLFGILW4RruQRnbBVVm4dGNVCP395H0rHXAQsFd25nPYbBUXiHY42Ap2jBfy3xVqm3dWhapffv4+MiTMdEJvpVY+yyxJwNAu2RFEEnI5I4UpogpY7yMFvHyzV2Jym3/9pJ1svQpCPqAzz79SXRLDQq8w1b7LmQhA==
|
||||
|
||||
21
.env.test
Normal file
21
.env.test
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#/-------------------[DOTENV_PUBLIC_KEY]--------------------/
|
||||
#/ public-key encryption for .env files /
|
||||
#/ [how it works](https://dotenvx.com/encryption) /
|
||||
#/----------------------------------------------------------/
|
||||
DOTENV_PUBLIC_KEY_TEST="02852f7005fb38145aa0d7a0a356158ba31dffeb6cb0280aa9671ee9a7673ddc94"
|
||||
|
||||
# .env.test
|
||||
DATABASE_URL=encrypted:BBzcyQFl877jbvtrWEoYrvA+AX1xRsVPyjQwlL/5yUyFsVFN/CXVbHFooQPzesG46YemJNkYzWGebMDWNZNbPc09rAROipuDwOvipkb6MS9E2IRUuQqUDVtnvlCuDD0VK+7492RpKfrFB73owT83EiQw/XJt+FMFSIW+FK09fE3mIDAOIeNdfBPwZoOiaAeVTQ==
|
||||
REDIS_URL=encrypted:BFF5ijYrLHtSlP9lxZVKsXB6RLV2dXJFzFxpk3+mVp0aA8r2Ez7g6nW7PWivmDxJjlCLg1nA27pR/Gzezg4GLXbqwDY9zV+e7Z7P46QHVvToRKDmGAuOV4CsKGTURHjLVof4K156CIu0ltyEUy7bhJuXtYqgoik=
|
||||
|
||||
CLICKHOUSE_URL=encrypted:BH8OZoeYgQo7Gc0MgfTSM03qQR6qdR6/cx8t25vHOv9+SOLnddFcle/WbtnzXvUsiLGNO3/IKlwx5WRBqzfDwSnbnPend+1kRZT1GO4qZp+JXWGY7bqQExplzA+YUrMj2NQEqPg3xORK7EkHTRLJ0CZYghKSAw==
|
||||
CLICKHOUSE_PASSWORD=encrypted:BKa4hWylvhPLPG+MpqIdAfyNAYZY1DzxMVHxIqb294W9Ec/V7TV2Reb68mZIKsFHJ7931cbEX7rgq5qIHHedJzW9t43GsX6k2SIdF4LFMIvYBEVhdRk4Yeu1aQpZ+pxpqtAyLMEOl/Mg
|
||||
|
||||
CLERK_SECRET_KEY=encrypted:BGDuYROAkWIQ6nS75BFIqFlNm1nuCU8o9AOODPSs3+yxoLv8X3G0UGDI5V8xFxvN0lNgK2FBTG3GqkbEOeVZAQHXEzEJGsIQZ7Yb+/WMw6PR6CQEuvX/oKqlrNiLsyhS2St4DICSJERdR8foHA==
|
||||
|
||||
GH_WEBHOOK_SECRET=encrypted:BPqZwnjqQE1EXxEZhAlM5lHSMseL3blLLB2XsK50/1k77AUTtRBWHY7V/1KN5CvYocieNVury1L7t8zuxyr4vk0ZIcZZsvsLYzWu/4CiIieHc1/oh0HqjG6ZCl86EwCscPEVBgQ=
|
||||
GH_TOKEN=encrypted:BGefstTA/5VjgS/e9iy7TCvM64YaKDDgp3SSr6IUGZfWrfqAhyMZe5VmxyNlNEV/UeodnnNEzT+mMtwq1HG1PWDnxl9gepXyJfulWIIx2x7SzaUfChQFXCjLKQ/AwZunnZ1HmjSreD1J
|
||||
|
||||
OPENROUTER_API_KEY=encrypted:BJHyYNaUsHiU6By54yUA2lG48W6NFuafGOr6Sc4XDopmTB9WulF1LbWrP0hiHY+GcWNhb3JR6V4XSOoqQDjNPza65uJCVOob1bWdC1vVoLBjxLev19OUI53jCi0kQVuNYz7P7zI5/YTWk0noSDU=
|
||||
|
||||
SLACK_API_TOKEN=encrypted:BDkskSYEb9SYQLpS0LyyOMgS7pVOyha9agMrS15iQUBoeULTzXbfGxEc+w3oEUa7mFyuRW+gHpo1jqEYicc2Nm9xXawDFsfhoTgXkhUdDlAVsJY/jctWtw97Hb9qLvigRrJWyx7ha5wUMg==
|
||||
9
.github/workflows/CI.yml
vendored
9
.github/workflows/CI.yml
vendored
|
|
@ -5,10 +5,13 @@ on:
|
|||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
NODE_VERSION: 20.19.2
|
||||
PNPM_VERSION: 10.12.1
|
||||
DOTENV_PRIVATE_KEY_TEST: ${{ secrets.DOTENV_PRIVATE_KEY_TEST }}
|
||||
DOTENV_PRIVATE_KEY_DEVELOPMENT: ${{ secrets.DOTENV_PRIVATE_KEY_DEVELOPMENT }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
|
@ -31,6 +34,8 @@ jobs:
|
|||
run: pnpm install
|
||||
- name: Build workspaces
|
||||
run: pnpm build
|
||||
env:
|
||||
DOTENV_PRIVATE_KEY_PRODUCTION: ${{ secrets.DOTENV_PRIVATE_KEY_PRODUCTION }}
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -132,7 +137,7 @@ jobs:
|
|||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
- name: Migrate production database
|
||||
run: npx drizzle-kit migrate
|
||||
run: pnpm db:production:migrate
|
||||
working-directory: packages/db
|
||||
env:
|
||||
DATABASE_URL: ${{ secrets.PRODUCTION_DATABASE_URL }}
|
||||
DOTENV_PRIVATE_KEY_PRODUCTION: ${{ secrets.DOTENV_PRIVATE_KEY_PRODUCTION }}
|
||||
|
|
|
|||
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -9,9 +9,8 @@ node_modules
|
|||
Thumbs.db
|
||||
|
||||
# .env
|
||||
.env*.local
|
||||
.env*.preview
|
||||
.env*.production
|
||||
.env.keys
|
||||
.env.local
|
||||
|
||||
# turbo
|
||||
.turbo
|
||||
|
|
|
|||
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
|
|
@ -5,6 +5,7 @@
|
|||
"csstools.postcss",
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"vitest.explorer",
|
||||
"yoavbls.pretty-ts-errors"
|
||||
"yoavbls.pretty-ts-errors",
|
||||
"tamasfe.even-better-toml"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
"scripts": {
|
||||
"lint": "eslint src --ext=ts --max-warnings=0",
|
||||
"check-types": "tsc --noEmit",
|
||||
"dev": "tsx src/index.ts",
|
||||
"dev": "dotenvx run -f ../../.env.development -- tsx src/index.ts",
|
||||
"clean": "rimraf .turbo"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,11 @@ import { createBullBoard } from '@bull-board/api';
|
|||
import express from 'express';
|
||||
import type { Express, Request, Response } from 'express';
|
||||
|
||||
const redis = new Redis(process.env.REDIS_URL || 'redis://localhost:6380', {
|
||||
if (!process.env.REDIS_URL) {
|
||||
throw new Error('REDIS_URL is not set');
|
||||
}
|
||||
|
||||
const redis = new Redis(process.env.REDIS_URL, {
|
||||
maxRetriesPerRequest: null,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "@roo-code-cloud/config-typescript/base.json",
|
||||
"include": ["src/**/*.ts"],
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
DATABASE_URL=postgres://postgres:password@postgres:5432/development
|
||||
REDIS_URL=redis://localhost:6379
|
||||
|
||||
GH_WEBHOOK_SECRET=your-webhook-secret-here
|
||||
GH_TOKEN=your-token-here
|
||||
|
||||
OPENROUTER_API_KEY=sk-or-v1-...
|
||||
|
||||
SLACK_API_TOKEN=xoxb-...
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import type { NextConfig } from 'next';
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
serverExternalPackages: ['postgres', 'ioredis', 'bullmq'],
|
||||
serverExternalPackages: ['ioredis', 'bullmq'],
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
|
|
|
|||
|
|
@ -5,19 +5,22 @@
|
|||
"scripts": {
|
||||
"lint": "next lint --max-warnings 0",
|
||||
"check-types": "tsc --noEmit",
|
||||
"test": "vitest",
|
||||
"dev": "next dev --port 3001",
|
||||
"build": "next build",
|
||||
"start": "next start --port 3001",
|
||||
"clean": "rimraf .next .turbo",
|
||||
"worker": "tsx src/lib/worker.ts",
|
||||
"controller": "tsx src/lib/controller.ts"
|
||||
"test": "dotenvx run -f ../../.env.test -- vitest",
|
||||
"dev": "dotenvx run -f ../../.env.development -- next dev --turbopack --port 3001",
|
||||
"build": "dotenvx run -f ../../.env.production -- next build",
|
||||
"start": "dotenvx run -f ../../.env.production -- next start --port 3001",
|
||||
"worker": "dotenvx run -f ../../.env.development -- tsx src/lib/worker.ts",
|
||||
"controller": "dotenvx run -f ../../.env.development -- tsx src/lib/controller.ts",
|
||||
"cli": "dotenvx run -f ../../.env.development -- tsx src/cli.ts",
|
||||
"clean": "rimraf .next .turbo"
|
||||
},
|
||||
"dependencies": {
|
||||
"@roo-code-cloud/db": "workspace:^",
|
||||
"@roo-code-cloud/env": "workspace:^",
|
||||
"@roo-code-cloud/ipc": "workspace:^",
|
||||
"@roo-code/types": "^1.29.0",
|
||||
"bullmq": "^5.37.0",
|
||||
"cmd-ts": "^0.13.0",
|
||||
"drizzle-orm": "^0.44.2",
|
||||
"execa": "^9.6.0",
|
||||
"ioredis": "^5.6.1",
|
||||
|
|
|
|||
|
|
@ -1,12 +1,31 @@
|
|||
import { NextResponse } from 'next/server';
|
||||
|
||||
import { db } from '@roo-code-cloud/db/server';
|
||||
import { Env } from '@roo-code-cloud/env';
|
||||
|
||||
import { redis } from '@/lib';
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
const services = { database: false, redis: false };
|
||||
const hosts = { database: 'unknown', redis: 'unknown' };
|
||||
|
||||
try {
|
||||
const databaseUrl = new URL(Env.DATABASE_URL);
|
||||
hosts.database = databaseUrl.hostname;
|
||||
} catch (error) {
|
||||
console.error('Failed to parse DATABASE_URL:', error);
|
||||
}
|
||||
|
||||
try {
|
||||
const redisUrl = new URL(
|
||||
process.env.REDIS_URL || 'redis://localhost:6379',
|
||||
);
|
||||
|
||||
hosts.redis = redisUrl.hostname;
|
||||
} catch (error) {
|
||||
console.error('Failed to parse REDIS_URL:', error);
|
||||
}
|
||||
|
||||
try {
|
||||
await db.execute('SELECT 1');
|
||||
|
|
@ -22,10 +41,11 @@ export async function GET() {
|
|||
console.error('Redis health check failed:', error);
|
||||
}
|
||||
|
||||
const allHealthy = Object.values(services).every(Boolean);
|
||||
const isHealthy = Object.values(services).every(Boolean);
|
||||
|
||||
return NextResponse.json(
|
||||
{ status: allHealthy ? 'ok' : 'error', services },
|
||||
{ status: allHealthy ? 200 : 500 },
|
||||
{ status: isHealthy ? 'ok' : 'error', services, hosts },
|
||||
{ status: isHealthy ? 200 : 500 },
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Health check error:', error);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { db, cloudJobs } from '@roo-code-cloud/db/server';
|
||||
import { createJobSchema, db, cloudJobs } from '@roo-code-cloud/db/server';
|
||||
|
||||
import { createJobSchema } from '@/types';
|
||||
import { enqueue } from '@/lib';
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { NextResponse } from 'next/server';
|
||||
import { z } from 'zod';
|
||||
|
||||
import type { JobPayload } from '@/types';
|
||||
import type { JobPayload } from '@roo-code-cloud/db';
|
||||
|
||||
import { createAndEnqueueJob } from './utils';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { NextResponse } from 'next/server';
|
||||
import { z } from 'zod';
|
||||
|
||||
import type { JobPayload } from '@/types';
|
||||
import type { JobPayload } from '@roo-code-cloud/db';
|
||||
|
||||
import { createAndEnqueueJob } from './utils';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { NextResponse } from 'next/server';
|
||||
import { z } from 'zod';
|
||||
|
||||
import type { JobPayload } from '@/types';
|
||||
import type { JobPayload } from '@roo-code-cloud/db';
|
||||
|
||||
import { createAndEnqueueJob } from './utils';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
import { createHmac } from 'crypto';
|
||||
|
||||
import { db, cloudJobs } from '@roo-code-cloud/db/server';
|
||||
import {
|
||||
type JobType,
|
||||
type JobPayload,
|
||||
db,
|
||||
cloudJobs,
|
||||
} from '@roo-code-cloud/db/server';
|
||||
|
||||
import type { JobType, JobPayload } from '@/types';
|
||||
import { enqueue } from '@/lib';
|
||||
|
||||
export function verifySignature(
|
||||
|
|
|
|||
311
apps/roomote/src/cli.ts
Normal file
311
apps/roomote/src/cli.ts
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
import * as path from 'path';
|
||||
import * as os from 'node:os';
|
||||
|
||||
import {
|
||||
command,
|
||||
run,
|
||||
string,
|
||||
number,
|
||||
option,
|
||||
subcommands,
|
||||
optional,
|
||||
} from 'cmd-ts';
|
||||
|
||||
import type { JobPayload } from '@roo-code-cloud/db';
|
||||
|
||||
import {
|
||||
fixGitHubIssue,
|
||||
processIssueComment,
|
||||
processPullRequestComment,
|
||||
} from '@/lib/jobs';
|
||||
import { runTask } from '@/lib/runTask';
|
||||
import { Logger } from '@/lib/logger';
|
||||
|
||||
const logger = new Logger({
|
||||
logDir: path.resolve(os.tmpdir(), 'logs'),
|
||||
filename: 'cli.log',
|
||||
tag: 'worker',
|
||||
});
|
||||
|
||||
const fixIssueCommand = command({
|
||||
name: 'fix-issue',
|
||||
description: 'Fix a GitHub issue',
|
||||
args: {
|
||||
repo: option({
|
||||
type: string,
|
||||
long: 'repo',
|
||||
short: 'r',
|
||||
description: 'Repository name (e.g., owner/repo)',
|
||||
}),
|
||||
issue: option({
|
||||
type: number,
|
||||
long: 'issue',
|
||||
short: 'i',
|
||||
description: 'Issue number',
|
||||
}),
|
||||
title: option({
|
||||
type: string,
|
||||
long: 'title',
|
||||
short: 't',
|
||||
description: 'Issue title',
|
||||
}),
|
||||
body: option({
|
||||
type: string,
|
||||
long: 'body',
|
||||
short: 'b',
|
||||
description: 'Issue body/description',
|
||||
}),
|
||||
labels: option({
|
||||
type: optional(string),
|
||||
long: 'labels',
|
||||
short: 'l',
|
||||
description: 'Issue labels (comma-separated: -l "bug,enhancement")',
|
||||
}),
|
||||
},
|
||||
handler: async ({ repo, issue, title, body, labels }) => {
|
||||
try {
|
||||
console.log('🔧 Fixing GitHub issue...');
|
||||
|
||||
const payload: JobPayload<'github.issue.fix'> = {
|
||||
repo,
|
||||
issue,
|
||||
title,
|
||||
body,
|
||||
labels: labels ? labels.split(',').map((l) => l.trim()) : [],
|
||||
};
|
||||
|
||||
const result = await fixGitHubIssue(payload);
|
||||
|
||||
console.log('✅ Issue fix completed successfully!');
|
||||
console.log(`Repository: ${result.repo}`);
|
||||
console.log(`Issue: #${result.issue}`);
|
||||
console.log('Result:', result.result);
|
||||
} catch (error) {
|
||||
console.error('❌ Error fixing issue:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const respondIssueCommentCommand = command({
|
||||
name: 'respond-issue-comment',
|
||||
description: 'Respond to a GitHub issue comment',
|
||||
args: {
|
||||
repo: option({
|
||||
type: string,
|
||||
long: 'repo',
|
||||
short: 'r',
|
||||
description: 'Repository name (e.g., owner/repo)',
|
||||
}),
|
||||
issueNumber: option({
|
||||
type: number,
|
||||
long: 'issue-number',
|
||||
description: 'Issue number',
|
||||
}),
|
||||
issueTitle: option({
|
||||
type: string,
|
||||
long: 'issue-title',
|
||||
description: 'Issue title',
|
||||
}),
|
||||
issueBody: option({
|
||||
type: string,
|
||||
long: 'issue-body',
|
||||
description: 'Issue body',
|
||||
}),
|
||||
commentId: option({
|
||||
type: number,
|
||||
long: 'comment-id',
|
||||
description: 'Comment ID',
|
||||
}),
|
||||
commentBody: option({
|
||||
type: string,
|
||||
long: 'comment-body',
|
||||
description: 'Comment body',
|
||||
}),
|
||||
commentAuthor: option({
|
||||
type: string,
|
||||
long: 'comment-author',
|
||||
description: 'Comment author',
|
||||
}),
|
||||
commentUrl: option({
|
||||
type: string,
|
||||
long: 'comment-url',
|
||||
description: 'Comment URL',
|
||||
}),
|
||||
},
|
||||
handler: async (args) => {
|
||||
try {
|
||||
console.log('💬 Responding to GitHub issue comment...');
|
||||
|
||||
const payload: JobPayload<'github.issue.comment.respond'> = {
|
||||
repo: args.repo,
|
||||
issueNumber: args.issueNumber,
|
||||
issueTitle: args.issueTitle,
|
||||
issueBody: args.issueBody,
|
||||
commentId: args.commentId,
|
||||
commentBody: args.commentBody,
|
||||
commentAuthor: args.commentAuthor,
|
||||
commentUrl: args.commentUrl,
|
||||
};
|
||||
|
||||
const result = await processIssueComment(payload);
|
||||
|
||||
console.log('✅ Issue comment response completed successfully!');
|
||||
console.log('Result:', result);
|
||||
} catch (error) {
|
||||
console.error('❌ Error responding to issue comment:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const respondPrCommentCommand = command({
|
||||
name: 'respond-pr-comment',
|
||||
description: 'Respond to a GitHub PR comment',
|
||||
args: {
|
||||
repo: option({
|
||||
type: string,
|
||||
long: 'repo',
|
||||
short: 'r',
|
||||
description: 'Repository name (e.g., owner/repo)',
|
||||
}),
|
||||
prNumber: option({
|
||||
type: number,
|
||||
long: 'pr-number',
|
||||
description: 'PR number',
|
||||
}),
|
||||
prTitle: option({
|
||||
type: string,
|
||||
long: 'pr-title',
|
||||
description: 'PR title',
|
||||
}),
|
||||
prBody: option({
|
||||
type: string,
|
||||
long: 'pr-body',
|
||||
description: 'PR body',
|
||||
}),
|
||||
prBranch: option({
|
||||
type: string,
|
||||
long: 'pr-branch',
|
||||
description: 'PR branch',
|
||||
}),
|
||||
baseRef: option({
|
||||
type: string,
|
||||
long: 'base-ref',
|
||||
description: 'Base reference',
|
||||
}),
|
||||
commentId: option({
|
||||
type: number,
|
||||
long: 'comment-id',
|
||||
description: 'Comment ID',
|
||||
}),
|
||||
commentBody: option({
|
||||
type: string,
|
||||
long: 'comment-body',
|
||||
description: 'Comment body',
|
||||
}),
|
||||
commentAuthor: option({
|
||||
type: string,
|
||||
long: 'comment-author',
|
||||
description: 'Comment author',
|
||||
}),
|
||||
commentType: option({
|
||||
type: string,
|
||||
long: 'comment-type',
|
||||
description: 'Comment type (issue_comment or review_comment)',
|
||||
}),
|
||||
commentUrl: option({
|
||||
type: string,
|
||||
long: 'comment-url',
|
||||
description: 'Comment URL',
|
||||
}),
|
||||
},
|
||||
handler: async (args) => {
|
||||
try {
|
||||
console.log('💬 Responding to GitHub PR comment...');
|
||||
|
||||
if (
|
||||
args.commentType !== 'issue_comment' &&
|
||||
args.commentType !== 'review_comment'
|
||||
) {
|
||||
throw new Error(
|
||||
'Comment type must be either "issue_comment" or "review_comment"',
|
||||
);
|
||||
}
|
||||
|
||||
const payload: JobPayload<'github.pr.comment.respond'> = {
|
||||
repo: args.repo,
|
||||
prNumber: args.prNumber,
|
||||
prTitle: args.prTitle,
|
||||
prBody: args.prBody,
|
||||
prBranch: args.prBranch,
|
||||
baseRef: args.baseRef,
|
||||
commentId: args.commentId,
|
||||
commentBody: args.commentBody,
|
||||
commentAuthor: args.commentAuthor,
|
||||
commentType: args.commentType as 'issue_comment' | 'review_comment',
|
||||
commentUrl: args.commentUrl,
|
||||
};
|
||||
|
||||
const result = await processPullRequestComment(payload);
|
||||
|
||||
console.log('✅ PR comment response completed successfully!');
|
||||
console.log('Result:', result);
|
||||
} catch (error) {
|
||||
console.error('❌ Error responding to PR comment:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const promptCommand = command({
|
||||
name: 'prompt',
|
||||
description: 'Prompt',
|
||||
args: {
|
||||
text: option({
|
||||
type: string,
|
||||
long: 'text',
|
||||
description: 'Text to test',
|
||||
}),
|
||||
mode: option({
|
||||
type: string,
|
||||
long: 'mode',
|
||||
description: 'Mode to use: code, ask, architect',
|
||||
}),
|
||||
workspacePath: option({
|
||||
type: string,
|
||||
long: 'workspace-path',
|
||||
description: 'Workspace path',
|
||||
}),
|
||||
},
|
||||
handler: async ({ text, mode, workspacePath }) => {
|
||||
if (!['code', 'ask', 'architect'].includes(mode)) {
|
||||
throw new Error('Invalid mode');
|
||||
}
|
||||
|
||||
console.log(`${text} (${mode}) in ${workspacePath}`);
|
||||
|
||||
await runTask({
|
||||
jobType: 'test.prompt',
|
||||
jobPayload: { text },
|
||||
prompt: text,
|
||||
logger,
|
||||
notify: false,
|
||||
workspacePath,
|
||||
settings: { mode },
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const app = subcommands({
|
||||
name: 'roomote-cli',
|
||||
description: 'Roomote CLI - Run jobs directly from the command line',
|
||||
cmds: {
|
||||
'fix-issue': fixIssueCommand,
|
||||
'respond-issue-comment': respondIssueCommentCommand,
|
||||
'respond-pr-comment': respondPrCommentCommand,
|
||||
prompt: promptCommand,
|
||||
},
|
||||
});
|
||||
|
||||
run(app, process.argv.slice(2));
|
||||
|
|
@ -81,11 +81,7 @@ export class WorkerController {
|
|||
`--name roomote-${workerId}`,
|
||||
'--rm',
|
||||
'--network roo-code-cloud_default',
|
||||
'-e HOST_EXECUTION_METHOD=docker',
|
||||
`-e GH_TOKEN=${process.env.GH_TOKEN}`,
|
||||
`-e DATABASE_URL=${process.env.DATABASE_URL}`,
|
||||
`-e REDIS_URL=${process.env.REDIS_URL}`,
|
||||
`-e NODE_ENV=${process.env.NODE_ENV}`,
|
||||
'-v /var/run/docker.sock:/var/run/docker.sock',
|
||||
'-v /tmp/roomote:/var/log/roomote',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
import { eq } from 'drizzle-orm';
|
||||
import { Job } from 'bullmq';
|
||||
|
||||
import { db, cloudJobs, type UpdateCloudJob } from '@roo-code-cloud/db/server';
|
||||
|
||||
import type { JobType, JobStatus, JobParams, JobPayload } from '@/types';
|
||||
import {
|
||||
type JobType,
|
||||
type JobStatus,
|
||||
type JobParams,
|
||||
type JobPayload,
|
||||
type UpdateCloudJob,
|
||||
db,
|
||||
cloudJobs,
|
||||
} from '@roo-code-cloud/db/server';
|
||||
|
||||
import { fixGitHubIssue } from './jobs/fixGitHubIssue';
|
||||
import { processPullRequestComment } from './jobs/processPullRequestComment';
|
||||
|
|
@ -26,7 +32,7 @@ export async function processJob<T extends JobType>({
|
|||
payload as JobPayload<'github.issue.fix'>,
|
||||
{
|
||||
onTaskStarted: async (
|
||||
slackThreadTs: string | null,
|
||||
slackThreadTs: string | null | undefined,
|
||||
_rooTaskId: string,
|
||||
) => {
|
||||
if (slackThreadTs) {
|
||||
|
|
@ -48,7 +54,7 @@ export async function processJob<T extends JobType>({
|
|||
payload as JobPayload<'github.issue.comment.respond'>,
|
||||
{
|
||||
onTaskStarted: async (
|
||||
slackThreadTs: string | null,
|
||||
slackThreadTs: string | null | undefined,
|
||||
_rooTaskId: string,
|
||||
) => {
|
||||
if (slackThreadTs) {
|
||||
|
|
@ -70,7 +76,7 @@ export async function processJob<T extends JobType>({
|
|||
payload as JobPayload<'github.pr.comment.respond'>,
|
||||
{
|
||||
onTaskStarted: async (
|
||||
slackThreadTs: string | null,
|
||||
slackThreadTs: string | null | undefined,
|
||||
_rooTaskId: string,
|
||||
) => {
|
||||
if (slackThreadTs) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import * as path from 'path';
|
||||
import * as os from 'node:os';
|
||||
|
||||
import type { JobType, JobPayload } from '@/types';
|
||||
import type { JobType, JobPayload } from '@roo-code-cloud/db';
|
||||
|
||||
import { runTask, type RunTaskCallbacks } from '../runTask';
|
||||
import { Logger } from '../logger';
|
||||
|
|
@ -46,7 +46,6 @@ Your job isn't done until you've created a pull request. Try to solve any git is
|
|||
jobType,
|
||||
jobPayload,
|
||||
prompt,
|
||||
publish: async () => {},
|
||||
logger: new Logger({
|
||||
logDir: path.resolve(os.tmpdir(), 'logs'),
|
||||
filename: 'worker.log',
|
||||
|
|
|
|||
3
apps/roomote/src/lib/jobs/index.ts
Normal file
3
apps/roomote/src/lib/jobs/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export { fixGitHubIssue } from './fixGitHubIssue';
|
||||
export { processIssueComment } from './processIssueComment';
|
||||
export { processPullRequestComment } from './processPullRequestComment';
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import * as path from 'path';
|
||||
import * as os from 'node:os';
|
||||
|
||||
import type { JobType, JobPayload } from '@/types';
|
||||
import type { JobType, JobPayload } from '@roo-code-cloud/db';
|
||||
|
||||
import { runTask, type RunTaskCallbacks } from '../runTask';
|
||||
import { Logger } from '../logger';
|
||||
|
|
@ -58,7 +58,6 @@ gh api repos/${jobPayload.repo}/issues/${jobPayload.issueNumber}/comments --meth
|
|||
jobType,
|
||||
jobPayload,
|
||||
prompt,
|
||||
publish: async () => {},
|
||||
logger: new Logger({
|
||||
logDir: path.resolve(os.tmpdir(), 'logs'),
|
||||
filename: 'worker.log',
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import * as path from 'path';
|
||||
import * as os from 'node:os';
|
||||
|
||||
import type { JobType, JobPayload } from '@/types';
|
||||
import type { JobType, JobPayload } from '@roo-code-cloud/db';
|
||||
|
||||
import { runTask, type RunTaskCallbacks } from '../runTask';
|
||||
import { Logger } from '../logger';
|
||||
|
|
@ -72,7 +72,6 @@ Do not create a new pull request - work directly on the existing PR branch.
|
|||
jobType,
|
||||
jobPayload,
|
||||
prompt,
|
||||
publish: async () => {},
|
||||
logger: new Logger({
|
||||
logDir: path.resolve(os.tmpdir(), 'logs'),
|
||||
filename: 'worker.log',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Queue, Job } from 'bullmq';
|
||||
|
||||
import type { JobTypes, JobPayload, JobParams } from '@/types';
|
||||
import type { JobTypes, JobPayload, JobParams } from '@roo-code-cloud/db';
|
||||
|
||||
import { redis } from './redis';
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import pWaitFor from 'p-wait-for';
|
|||
import { execa } from 'execa';
|
||||
|
||||
import {
|
||||
type TaskEvent,
|
||||
type RooCodeSettings,
|
||||
TaskCommandName,
|
||||
RooCodeEventName,
|
||||
IpcMessageType,
|
||||
|
|
@ -14,7 +14,7 @@ import {
|
|||
} from '@roo-code/types';
|
||||
import { IpcClient } from '@roo-code-cloud/ipc';
|
||||
|
||||
import type { JobPayload, JobType } from '@/types';
|
||||
import type { JobPayload, JobType } from '@roo-code-cloud/db';
|
||||
|
||||
import { Logger } from './logger';
|
||||
import { isDockerContainer } from './utils';
|
||||
|
|
@ -31,12 +31,12 @@ class SubprocessTimeoutError extends Error {
|
|||
|
||||
export type RunTaskCallbacks = {
|
||||
onTaskStarted?: (
|
||||
slackThreadTs: string | null,
|
||||
slackThreadTs: string | null | undefined,
|
||||
rooTaskId: string,
|
||||
) => Promise<void>;
|
||||
onTaskAborted?: (slackThreadTs: string | null) => Promise<void>;
|
||||
onTaskAborted?: (slackThreadTs: string | null | undefined) => Promise<void>;
|
||||
onTaskCompleted?: (
|
||||
slackThreadTs: string | null,
|
||||
slackThreadTs: string | null | undefined,
|
||||
success: boolean,
|
||||
duration: number,
|
||||
rooTaskId?: string,
|
||||
|
|
@ -49,24 +49,28 @@ type RunTaskOptions<T extends JobType> = {
|
|||
jobType: T;
|
||||
jobPayload: JobPayload<T>;
|
||||
prompt: string;
|
||||
publish: (taskEvent: TaskEvent) => Promise<void>;
|
||||
logger: Logger;
|
||||
callbacks?: RunTaskCallbacks;
|
||||
notify?: boolean;
|
||||
workspacePath?: string;
|
||||
settings?: RooCodeSettings;
|
||||
};
|
||||
|
||||
export const runTask = async <T extends JobType>({
|
||||
jobType,
|
||||
jobPayload,
|
||||
prompt,
|
||||
publish,
|
||||
logger,
|
||||
callbacks,
|
||||
notify = true,
|
||||
workspacePath = '/roo/repos/Roo-Code',
|
||||
settings = {},
|
||||
}: RunTaskOptions<T>) => {
|
||||
const workspacePath = '/roo/repos/Roo-Code'; // findGitRoot(process.cwd())
|
||||
const ipcSocketPath = path.resolve(
|
||||
os.tmpdir(),
|
||||
`${crypto.randomUUID().slice(0, 8)}.sock`,
|
||||
);
|
||||
|
||||
const env = { ROO_CODE_IPC_SOCKET_PATH: ipcSocketPath };
|
||||
const controller = new AbortController();
|
||||
const cancelSignal = controller.signal;
|
||||
|
|
@ -124,8 +128,8 @@ export const runTask = async <T extends JobType>({
|
|||
let rooTaskId: string | undefined;
|
||||
let isClientDisconnected = false;
|
||||
|
||||
const slackNotifier = new SlackNotifier(logger);
|
||||
let slackThreadTs: string | null = null;
|
||||
const slackNotifier = notify ? new SlackNotifier(logger) : undefined;
|
||||
let slackThreadTs: string | null | undefined = null;
|
||||
|
||||
const ignoreEvents: Record<'broadcast' | 'log', RooCodeEventName[]> = {
|
||||
broadcast: [RooCodeEventName.Message],
|
||||
|
|
@ -138,11 +142,6 @@ export const runTask = async <T extends JobType>({
|
|||
client.on(IpcMessageType.TaskEvent, async (taskEvent) => {
|
||||
const { eventName, payload } = taskEvent;
|
||||
|
||||
// Publish all events except for these to Redis.
|
||||
if (!ignoreEvents.broadcast.includes(eventName)) {
|
||||
await publish({ ...taskEvent });
|
||||
}
|
||||
|
||||
// Log all events except for these.
|
||||
// For message events we only log non-partial messages.
|
||||
if (
|
||||
|
|
@ -158,7 +157,7 @@ export const runTask = async <T extends JobType>({
|
|||
rooTaskId = payload[0];
|
||||
|
||||
if (rooTaskId) {
|
||||
slackThreadTs = await slackNotifier.postTaskStarted({
|
||||
slackThreadTs = await slackNotifier?.postTaskStarted({
|
||||
jobType,
|
||||
jobPayload,
|
||||
rooTaskId,
|
||||
|
|
@ -174,7 +173,7 @@ export const runTask = async <T extends JobType>({
|
|||
taskAbortedAt = Date.now();
|
||||
|
||||
if (slackThreadTs) {
|
||||
await slackNotifier.postTaskUpdated(
|
||||
await slackNotifier?.postTaskUpdated(
|
||||
slackThreadTs,
|
||||
'Task was aborted',
|
||||
'warning',
|
||||
|
|
@ -190,7 +189,7 @@ export const runTask = async <T extends JobType>({
|
|||
taskFinishedAt = Date.now();
|
||||
|
||||
if (slackThreadTs) {
|
||||
await slackNotifier.postTaskCompleted(
|
||||
await slackNotifier?.postTaskCompleted(
|
||||
slackThreadTs,
|
||||
true,
|
||||
taskFinishedAt - taskStartedAt,
|
||||
|
|
@ -220,6 +219,7 @@ export const runTask = async <T extends JobType>({
|
|||
configuration: {
|
||||
...EVALS_SETTINGS,
|
||||
openRouterApiKey: process.env.OPENROUTER_API_KEY,
|
||||
...settings,
|
||||
},
|
||||
text: prompt,
|
||||
newTab: true,
|
||||
|
|
@ -239,7 +239,7 @@ export const runTask = async <T extends JobType>({
|
|||
logger.error('time limit reached');
|
||||
|
||||
if (slackThreadTs) {
|
||||
await slackNotifier.postTaskUpdated(
|
||||
await slackNotifier?.postTaskUpdated(
|
||||
slackThreadTs,
|
||||
'Task timed out after 30 minutes',
|
||||
'error',
|
||||
|
|
@ -266,7 +266,7 @@ export const runTask = async <T extends JobType>({
|
|||
logger.error('client disconnected before task finished');
|
||||
|
||||
if (slackThreadTs) {
|
||||
await slackNotifier.postTaskUpdated(
|
||||
await slackNotifier?.postTaskUpdated(
|
||||
slackThreadTs,
|
||||
'Client disconnected before task completion',
|
||||
'error',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { JobPayload, JobType } from '@/types';
|
||||
import type { JobPayload, JobType } from '@roo-code-cloud/db';
|
||||
|
||||
import { Logger } from './logger';
|
||||
|
||||
export interface SlackMessage {
|
||||
|
|
|
|||
|
|
@ -10,16 +10,12 @@ import { processJob } from './job';
|
|||
// --interactive \
|
||||
// --tty \
|
||||
// --network roo-code-cloud_default \
|
||||
// -e HOST_EXECUTION_METHOD=docker \
|
||||
// -e GH_TOKEN=$GH_TOKEN \
|
||||
// -e DATABASE_URL=postgres://postgres:password@postgres:5432/development \
|
||||
// -e REDIS_URL=redis://redis:6379 \
|
||||
// -e NODE_ENV=production \
|
||||
// -v /var/run/docker.sock:/var/run/docker.sock \
|
||||
// -v /tmp/roomote:/var/log/roomote \
|
||||
// roomote-worker sh -c "bash"
|
||||
|
||||
async function processSingleJob() {
|
||||
async function processNextJob() {
|
||||
const worker = new Worker('roomote', undefined, {
|
||||
autorun: false,
|
||||
connection: redis,
|
||||
|
|
@ -69,4 +65,4 @@ if (!process.env.GH_TOKEN) {
|
|||
throw new Error('GH_TOKEN is not set');
|
||||
}
|
||||
|
||||
processSingleJob();
|
||||
processNextJob();
|
||||
|
|
|
|||
|
|
@ -1,61 +0,0 @@
|
|||
import { z } from 'zod';
|
||||
|
||||
export const createJobSchema = z.discriminatedUnion('type', [
|
||||
z.object({
|
||||
type: z.literal('github.issue.fix'),
|
||||
payload: z.object({
|
||||
repo: z.string(),
|
||||
issue: z.number(),
|
||||
title: z.string(),
|
||||
body: z.string(),
|
||||
labels: z.array(z.string()).optional(),
|
||||
}),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal('github.issue.comment.respond'),
|
||||
payload: z.object({
|
||||
repo: z.string(),
|
||||
issueNumber: z.number(),
|
||||
issueTitle: z.string(),
|
||||
issueBody: z.string(),
|
||||
commentId: z.number(),
|
||||
commentBody: z.string(),
|
||||
commentAuthor: z.string(),
|
||||
commentUrl: z.string(),
|
||||
}),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal('github.pr.comment.respond'),
|
||||
payload: z.object({
|
||||
repo: z.string(),
|
||||
prNumber: z.number(),
|
||||
prTitle: z.string(),
|
||||
prBody: z.string(),
|
||||
prBranch: z.string(),
|
||||
baseRef: z.string(),
|
||||
commentId: z.number(),
|
||||
commentBody: z.string(),
|
||||
commentAuthor: z.string(),
|
||||
commentType: z.enum(['issue_comment', 'review_comment']),
|
||||
commentUrl: z.string(),
|
||||
}),
|
||||
}),
|
||||
]);
|
||||
|
||||
export type CreateJob = z.infer<typeof createJobSchema>;
|
||||
|
||||
export type JobTypes = {
|
||||
[K in CreateJob['type']]: Extract<CreateJob, { type: K }>['payload'];
|
||||
};
|
||||
|
||||
export type JobType = keyof JobTypes;
|
||||
|
||||
export type JobStatus = 'pending' | 'processing' | 'completed' | 'failed';
|
||||
|
||||
export type JobPayload<T extends JobType = JobType> = JobTypes[T];
|
||||
|
||||
export type JobParams<T extends JobType> = {
|
||||
jobId: number;
|
||||
type: T;
|
||||
payload: JobPayload<T>;
|
||||
};
|
||||
|
|
@ -1,24 +1,9 @@
|
|||
# NOTE: Sensitive ENV vars are overridden with their real values in .env.local
|
||||
# for local development and in the "Environment Variables" setting on Vercel
|
||||
# for production (https://vercel.com/roo-code/roo-code-cloud/settings/environment-variables).
|
||||
|
||||
# Postgres
|
||||
DATABASE_URL=postgres://foo:bar@baz:5432/jabberworky
|
||||
|
||||
# ClickHouse
|
||||
CLICKHOUSE_URL=https://fake.url
|
||||
CLICKHOUSE_PASSWORD=fake-password
|
||||
|
||||
# Clerk
|
||||
CLERK_SECRET_KEY=fake-secret-key
|
||||
|
||||
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
|
||||
NEXT_PUBLIC_CLERK_FRONTEND_API=https://fake.url
|
||||
|
||||
# https://clerk.com/docs/deployments/clerk-environment-variables#sign-in-and-sign-up-redirects
|
||||
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_ZXBpYy1jaGFtb2lzLTg1LmNsZXJrLmFjY291bnRzLmRldiQ
|
||||
NEXT_PUBLIC_CLERK_FRONTEND_API=https://epic-chamois-85.clerk.accounts.dev
|
||||
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
|
||||
NEXT_PUBLIC_CLERK_SIGN_IN_FORCE_REDIRECT_URL=/
|
||||
NEXT_PUBLIC_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL=/
|
||||
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
|
||||
NEXT_PUBLIC_CLERK_SIGN_IN_FORCE_REDIRECT_URL=/authorized
|
||||
NEXT_PUBLIC_CLERK_SIGN_UP_FORCE_REDIRECT_URL=/authorized
|
||||
NEXT_PUBLIC_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL=/authorized
|
||||
NEXT_PUBLIC_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL=/authorized
|
||||
NEXT_PUBLIC_CLERK_SIGN_UP_FORCE_REDIRECT_URL=/
|
||||
NEXT_PUBLIC_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL=/
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
DATABASE_URL=postgres://postgres:password@localhost:5432/development
|
||||
CLICKHOUSE_URL=http://localhost:8123/default
|
||||
CLICKHOUSE_PASSWORD=password
|
||||
2
apps/web/.env.production
Normal file
2
apps/web/.env.production
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_Y2xlcmsucm9vY29kZS5jb20k
|
||||
NEXT_PUBLIC_CLERK_FRONTEND_API=https://clerk.roocode.com
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
DATABASE_URL=postgres://postgres:password@localhost:5432/test
|
||||
CLICKHOUSE_URL=http://localhost:8123/default
|
||||
CLICKHOUSE_PASSWORD=password
|
||||
|
|
@ -49,10 +49,8 @@ Create an `.env.local` file and fill out the required secrets, including:
|
|||
- `CLICKHOUSE_URL`
|
||||
- `CLICKHOUSE_PASSWORD`
|
||||
- `CLERK_SECRET_KEY`
|
||||
- `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY`
|
||||
- `NEXT_PUBLIC_CLERK_FRONTEND_API`
|
||||
|
||||
You can now start the Next.js app and [Spotlight](https://spotlightjs.com/) with:
|
||||
You can now start the Next.js app with:
|
||||
|
||||
```sh
|
||||
pnpm dev
|
||||
|
|
|
|||
|
|
@ -1,14 +1,9 @@
|
|||
import type { NextConfig } from 'next';
|
||||
import withBundleAnalyzer from '@next/bundle-analyzer';
|
||||
import { withSentryConfig } from '@sentry/nextjs';
|
||||
import createNextIntlPlugin from 'next-intl/plugin';
|
||||
|
||||
const withNextIntl = createNextIntlPlugin();
|
||||
|
||||
const bundleAnalyzer = withBundleAnalyzer({
|
||||
enabled: process.env.ANALYZE === 'true',
|
||||
});
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
eslint: { dirs: ['.'] },
|
||||
poweredByHeader: false,
|
||||
|
|
@ -20,7 +15,7 @@ const nextConfig: NextConfig = {
|
|||
// },
|
||||
};
|
||||
|
||||
export default withSentryConfig(bundleAnalyzer(withNextIntl(nextConfig)), {
|
||||
export default withSentryConfig(withNextIntl(nextConfig), {
|
||||
// For all available options, see:
|
||||
// https://github.com/getsentry/sentry-webpack-plugin#options
|
||||
// FIXME: Add your Sentry organization and project names
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@
|
|||
"scripts": {
|
||||
"lint": "next lint --max-warnings 0",
|
||||
"check-types": "tsc --noEmit",
|
||||
"test": "dotenvx run -f .env.test -f .env -- vitest run",
|
||||
"dev": "next dev --turbopack",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"test": "dotenvx run -f ../../.env.test -- vitest",
|
||||
"dev": "dotenvx run -f ../../.env.development -- next dev --turbopack",
|
||||
"build": "dotenvx run -f ../../.env.production -- next build",
|
||||
"start": "dotenvx run -f ../../.env.production -- next start",
|
||||
"clean": "rimraf .next .turbo out"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
@ -16,7 +16,6 @@
|
|||
"@clerk/themes": "^2.2.48",
|
||||
"@clickhouse/client": "^1.11.1",
|
||||
"@hookform/resolvers": "^5.0.1",
|
||||
"@logtail/pino": "^0.5.5",
|
||||
"@radix-ui/react-accordion": "^1.2.11",
|
||||
"@radix-ui/react-checkbox": "^1.3.2",
|
||||
"@radix-ui/react-dialog": "^1.1.14",
|
||||
|
|
@ -32,9 +31,9 @@
|
|||
"@radix-ui/react-toast": "^1.2.14",
|
||||
"@radix-ui/react-tooltip": "^1.2.7",
|
||||
"@roo-code-cloud/db": "workspace:^",
|
||||
"@roo-code-cloud/env": "workspace:^",
|
||||
"@roo-code/types": "^1.29.0",
|
||||
"@sentry/nextjs": "^9.23.0",
|
||||
"@t3-oss/env-nextjs": "^0.13.6",
|
||||
"@tailwindcss/postcss": "^4.1.8",
|
||||
"@tanstack/react-query": "^5.79.0",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
|
|
@ -74,7 +73,6 @@
|
|||
"devDependencies": {
|
||||
"@clerk/testing": "^1.7.5",
|
||||
"@eslint/js": "^9.27.0",
|
||||
"@next/bundle-analyzer": "^15.3.3",
|
||||
"@next/eslint-plugin-next": "^15.3.3",
|
||||
"@roo-code-cloud/config-eslint": "workspace:^",
|
||||
"@roo-code-cloud/config-typescript": "workspace:^",
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@
|
|||
import { NextRequest } from 'next/server';
|
||||
import { auth } from '@clerk/nextjs/server';
|
||||
|
||||
import { Env } from '@roo-code-cloud/env';
|
||||
|
||||
import { type AuthResult, type ApiAuthResult, isOrgRole } from '@/types';
|
||||
import { Env, logger } from '@/lib/server';
|
||||
import { logger } from '@/lib/server';
|
||||
// import {
|
||||
// type AgentTokenPayload,
|
||||
// validateAgentToken,
|
||||
|
|
|
|||
|
|
@ -9,9 +9,6 @@ export async function register() {
|
|||
// Sentry DSN
|
||||
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
|
||||
|
||||
// Enable Spotlight in development
|
||||
spotlight: process.env.NODE_ENV === 'development',
|
||||
|
||||
// Adjust this value in production, or use tracesSampler for greater control
|
||||
tracesSampleRate: 1,
|
||||
|
||||
|
|
@ -30,9 +27,6 @@ export async function register() {
|
|||
// Sentry DSN
|
||||
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
|
||||
|
||||
// Enable Spotlight in development
|
||||
spotlight: process.env.NODE_ENV === 'development',
|
||||
|
||||
// Adjust this value in production, or use tracesSampler for greater control
|
||||
tracesSampleRate: 1,
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@
|
|||
|
||||
import jwt from 'jsonwebtoken';
|
||||
|
||||
vi.mock('@roo-code-cloud/env', () => ({
|
||||
Env: {
|
||||
CLERK_SECRET_KEY: 'test-secret-key-for-jwt-testing',
|
||||
},
|
||||
}));
|
||||
|
||||
import {
|
||||
getAgentToken,
|
||||
refreshAgentTokenIfNeeded,
|
||||
|
|
@ -10,14 +16,9 @@ import {
|
|||
} from '../agent-auth';
|
||||
|
||||
describe('agent-auth', () => {
|
||||
const originalEnv = process.env;
|
||||
const testSecret = 'test-secret-key-for-jwt-testing';
|
||||
|
||||
beforeEach(() => {
|
||||
// Reset environment variables
|
||||
process.env = { ...originalEnv };
|
||||
process.env.CLERK_SECRET_KEY = testSecret;
|
||||
|
||||
// Mock Date.now() to return a consistent timestamp
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date('2023-01-01T00:00:00Z'));
|
||||
|
|
@ -25,7 +26,6 @@ describe('agent-auth', () => {
|
|||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers();
|
||||
process.env = originalEnv;
|
||||
});
|
||||
|
||||
describe('getAgentToken', () => {
|
||||
|
|
@ -51,7 +51,13 @@ describe('agent-auth', () => {
|
|||
});
|
||||
|
||||
it('should use fallback secret when CLERK_SECRET_KEY is not set', async () => {
|
||||
delete process.env.CLERK_SECRET_KEY;
|
||||
// Import the mocked module to modify it
|
||||
const { Env } = await import('@roo-code-cloud/env');
|
||||
const mockedEnv = vi.mocked(Env);
|
||||
|
||||
// Update the mock to use fallback secret
|
||||
mockedEnv.CLERK_SECRET_KEY = 'fallback-secret';
|
||||
|
||||
const token = await getAgentToken('agent-123', 'org-456');
|
||||
|
||||
// Token should still be valid with fallback secret
|
||||
|
|
@ -61,6 +67,9 @@ describe('agent-auth', () => {
|
|||
// Verify it was signed with the fallback secret
|
||||
const decoded = jwt.verify(token, 'fallback-secret') as AgentTokenPayload;
|
||||
expect(decoded.sub).toBe('agent-123');
|
||||
|
||||
// Reset back to test secret
|
||||
mockedEnv.CLERK_SECRET_KEY = testSecret;
|
||||
});
|
||||
|
||||
it('should set correct expiration time (15 minutes)', async () => {
|
||||
|
|
@ -240,7 +249,13 @@ describe('agent-auth', () => {
|
|||
});
|
||||
|
||||
it('should use fallback secret when CLERK_SECRET_KEY is not set', async () => {
|
||||
delete process.env.CLERK_SECRET_KEY;
|
||||
// Import the mocked module to modify it
|
||||
const { Env } = await import('@roo-code-cloud/env');
|
||||
const mockedEnv = vi.mocked(Env);
|
||||
|
||||
// Update the mock to use fallback secret
|
||||
mockedEnv.CLERK_SECRET_KEY = 'fallback-secret';
|
||||
|
||||
const token = jwt.sign(validPayload, 'fallback-secret', {
|
||||
algorithm: 'HS256',
|
||||
});
|
||||
|
|
@ -248,6 +263,9 @@ describe('agent-auth', () => {
|
|||
const result = await validateAgentToken(token);
|
||||
|
||||
expect(result).toEqual(validPayload);
|
||||
|
||||
// Reset back to test secret
|
||||
mockedEnv.CLERK_SECRET_KEY = testSecret;
|
||||
});
|
||||
|
||||
it('should throw error for invalid JWT signature', async () => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import jwt from 'jsonwebtoken';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { Env } from '@roo-code-cloud/env';
|
||||
|
||||
const agentTokenPayloadSchema = z.object({
|
||||
sub: z.string().min(1, 'Subject (sub) is required'),
|
||||
org_id: z.string().min(1, 'Organization ID is required'),
|
||||
|
|
@ -24,7 +26,7 @@ export async function getAgentToken(agentId: string, orgId: string) {
|
|||
iat: Math.floor(Date.now() / 1000),
|
||||
exp: Math.floor(Date.now() / 1000) + 15 * 60, // 15 minutes
|
||||
},
|
||||
process.env.CLERK_SECRET_KEY || 'fallback-secret',
|
||||
Env.CLERK_SECRET_KEY,
|
||||
{ algorithm: 'HS256' },
|
||||
);
|
||||
}
|
||||
|
|
@ -58,11 +60,9 @@ export async function validateAgentToken(
|
|||
token: string,
|
||||
): Promise<AgentTokenPayload> {
|
||||
try {
|
||||
const rawPayload = jwt.verify(
|
||||
token,
|
||||
process.env.CLERK_SECRET_KEY || 'fallback-secret',
|
||||
{ algorithms: ['HS256'] },
|
||||
);
|
||||
const rawPayload = jwt.verify(token, Env.CLERK_SECRET_KEY, {
|
||||
algorithms: ['HS256'],
|
||||
});
|
||||
|
||||
const parseResult = agentTokenPayloadSchema.safeParse(rawPayload);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { createClient } from '@clickhouse/client';
|
||||
|
||||
import { Env } from './env';
|
||||
import { Env } from '@roo-code-cloud/env';
|
||||
|
||||
export const analytics = createClient({
|
||||
url: Env.CLICKHOUSE_URL,
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
import { createEnv } from '@t3-oss/env-nextjs';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const Env = createEnv({
|
||||
server: {
|
||||
CLERK_SECRET_KEY: z.string().min(1),
|
||||
DATABASE_URL: z.string(),
|
||||
LOGTAIL_SOURCE_TOKEN: z.string().optional(),
|
||||
CLICKHOUSE_URL: z.string().min(1),
|
||||
CLICKHOUSE_PASSWORD: z.string().min(1),
|
||||
},
|
||||
client: {
|
||||
NEXT_PUBLIC_APP_URL: z.string().optional(),
|
||||
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string().min(1),
|
||||
NEXT_PUBLIC_CLERK_SIGN_IN_URL: z.string().min(1),
|
||||
NEXT_PUBLIC_CLERK_SIGN_IN_FORCE_REDIRECT_URL: z.string().min(1),
|
||||
NEXT_PUBLIC_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL: z.string().min(1),
|
||||
NEXT_PUBLIC_CLERK_SIGN_UP_URL: z.string().min(1),
|
||||
NEXT_PUBLIC_CLERK_SIGN_UP_FORCE_REDIRECT_URL: z.string().min(1),
|
||||
NEXT_PUBLIC_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL: z.string().min(1),
|
||||
},
|
||||
shared: {
|
||||
NODE_ENV: z.enum(['test', 'development', 'production']).optional(),
|
||||
},
|
||||
// You need to destructure all the keys manually.
|
||||
runtimeEnv: {
|
||||
CLERK_SECRET_KEY: process.env.CLERK_SECRET_KEY,
|
||||
DATABASE_URL: process.env.DATABASE_URL,
|
||||
LOGTAIL_SOURCE_TOKEN: process.env.LOGTAIL_SOURCE_TOKEN,
|
||||
NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
|
||||
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY:
|
||||
process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,
|
||||
NEXT_PUBLIC_CLERK_SIGN_IN_URL: process.env.NEXT_PUBLIC_CLERK_SIGN_IN_URL,
|
||||
NEXT_PUBLIC_CLERK_SIGN_IN_FORCE_REDIRECT_URL:
|
||||
process.env.NEXT_PUBLIC_CLERK_SIGN_IN_FORCE_REDIRECT_URL,
|
||||
NEXT_PUBLIC_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL:
|
||||
process.env.NEXT_PUBLIC_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL,
|
||||
NEXT_PUBLIC_CLERK_SIGN_UP_URL: process.env.NEXT_PUBLIC_CLERK_SIGN_UP_URL,
|
||||
NEXT_PUBLIC_CLERK_SIGN_UP_FORCE_REDIRECT_URL:
|
||||
process.env.NEXT_PUBLIC_CLERK_SIGN_UP_FORCE_REDIRECT_URL,
|
||||
NEXT_PUBLIC_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL:
|
||||
process.env.NEXT_PUBLIC_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL,
|
||||
NODE_ENV: process.env.NODE_ENV,
|
||||
CLICKHOUSE_URL: process.env.CLICKHOUSE_URL,
|
||||
CLICKHOUSE_PASSWORD: process.env.CLICKHOUSE_PASSWORD,
|
||||
},
|
||||
});
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
export { Env } from './env';
|
||||
export { logger } from './logger';
|
||||
export { handleError } from './api';
|
||||
export { analytics } from './analytics';
|
||||
|
|
|
|||
|
|
@ -1,17 +1,6 @@
|
|||
import pino, { type DestinationStream } from 'pino';
|
||||
import pretty from 'pino-pretty';
|
||||
import logtail from '@logtail/pino';
|
||||
|
||||
import { Env } from './env';
|
||||
|
||||
const stream: DestinationStream = Env.LOGTAIL_SOURCE_TOKEN
|
||||
? pino.multistream([
|
||||
await logtail({
|
||||
sourceToken: Env.LOGTAIL_SOURCE_TOKEN,
|
||||
options: { sendLogsToBetterStack: true },
|
||||
}),
|
||||
{ stream: pretty() }, // Prints logs to the console.
|
||||
])
|
||||
: pretty({ colorize: true });
|
||||
const stream: DestinationStream = pretty({ colorize: true });
|
||||
|
||||
export const logger = pino({ base: undefined }, stream);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,6 @@
|
|||
name: roo-code-cloud
|
||||
|
||||
services:
|
||||
base:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: .docker/Dockerfile.base
|
||||
image: roo-code-cloud-base
|
||||
|
||||
postgres:
|
||||
container_name: roo-code-cloud-postgres
|
||||
image: postgres:17.5
|
||||
|
|
@ -67,7 +61,7 @@ services:
|
|||
dockerfile: .docker/Dockerfile.roomote-dashboard
|
||||
image: roo-code-cloud-roomote-dashboard
|
||||
env_file:
|
||||
- .env
|
||||
- .env.keys
|
||||
ports:
|
||||
- "3002:3002"
|
||||
depends_on:
|
||||
|
|
@ -81,7 +75,7 @@ services:
|
|||
dockerfile: .docker/Dockerfile.roomote-api
|
||||
image: roo-code-cloud-roomote-api
|
||||
env_file:
|
||||
- .env
|
||||
- .env.keys
|
||||
ports:
|
||||
- "3001:3001"
|
||||
volumes:
|
||||
|
|
@ -97,11 +91,9 @@ services:
|
|||
build:
|
||||
context: .
|
||||
dockerfile: .docker/Dockerfile.roomote-controller
|
||||
args:
|
||||
- GH_TOKEN=${GH_TOKEN}
|
||||
image: roo-code-cloud-roomote-controller
|
||||
env_file:
|
||||
- .env
|
||||
- .env.keys
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /tmp/roomote/controller:/var/log/roomote
|
||||
|
|
@ -116,11 +108,9 @@ services:
|
|||
build:
|
||||
context: .
|
||||
dockerfile: .docker/Dockerfile.roomote-worker
|
||||
args:
|
||||
- GH_TOKEN=${GH_TOKEN}
|
||||
image: roomote-worker
|
||||
env_file:
|
||||
- .env
|
||||
- .env.keys
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /tmp/roomote/worker:/var/log/roomote
|
||||
|
|
|
|||
21
fly.roomote-api.toml
Normal file
21
fly.roomote-api.toml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
|
||||
#
|
||||
# Deploy with: `fly deploy --config fly.roomote-api.toml`
|
||||
|
||||
app = "roomote-api"
|
||||
primary_region = "sjc" # See `fly platform regions`
|
||||
|
||||
[env]
|
||||
APP_ENV = "production"
|
||||
|
||||
[build]
|
||||
dockerfile = ".docker/Dockerfile.roomote-api"
|
||||
ignorefile = ".dockerignore"
|
||||
|
||||
[http_service]
|
||||
internal_port = 3001
|
||||
force_https = true
|
||||
min_machines_running = 0
|
||||
|
||||
[[vm]]
|
||||
size = "performance-1x" # See `fly platform vm-sizes`
|
||||
16
fly.roomote-controller.toml
Normal file
16
fly.roomote-controller.toml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
|
||||
#
|
||||
# Deploy with: `fly deploy --config fly.roomote-controller.toml`
|
||||
|
||||
app = "roomote-controller"
|
||||
primary_region = "sjc" # See `fly platform regions`
|
||||
|
||||
[env]
|
||||
APP_ENV = "production"
|
||||
|
||||
[build]
|
||||
dockerfile = ".docker/Dockerfile.roomote-controller"
|
||||
ignorefile = ".dockerignore"
|
||||
|
||||
[[vm]]
|
||||
size = "performance-2x" # See `fly platform vm-sizes`
|
||||
21
fly.roomote-dashboard.toml
Normal file
21
fly.roomote-dashboard.toml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
|
||||
#
|
||||
# Deploy with: `fly deploy --config fly.roomote-dashboard.toml`
|
||||
|
||||
app = "roomote-dashboard"
|
||||
primary_region = "sjc" # See `fly platform regions`
|
||||
|
||||
[env]
|
||||
APP_ENV = "production"
|
||||
|
||||
[build]
|
||||
dockerfile = ".docker/Dockerfile.roomote-dashboard"
|
||||
ignorefile = ".dockerignore"
|
||||
|
||||
[http_service]
|
||||
internal_port = 3002
|
||||
force_https = true
|
||||
min_machines_running = 0
|
||||
|
||||
[[vm]]
|
||||
size = "performance-1x" # See `fly platform vm-sizes`
|
||||
19
package.json
19
package.json
|
|
@ -8,15 +8,22 @@
|
|||
"test": "turbo test --log-order grouped --output-logs new-only",
|
||||
"build": "turbo build --log-order grouped --output-logs new-only",
|
||||
"clean": "turbo clean --log-order grouped --output-logs new-only && rimraf .turbo",
|
||||
"db:up": "docker compose up postgres clickhouse -d --wait && pnpm --filter @roo-code-cloud/db db:migrate && pnpm --filter @roo-code-cloud/db db:test:push --force",
|
||||
"db:down": "docker compose down postgres clickhouse",
|
||||
"db:up": "docker compose up postgres clickhouse redis -d --wait && pnpm --filter @roo-code-cloud/db db:migrate && pnpm --filter @roo-code-cloud/db db:test:push --force",
|
||||
"db:down": "docker compose down postgres clickhouse redis",
|
||||
"db:generate": "pnpm --filter @roo-code-cloud/db db:generate",
|
||||
"db:migrate": "pnpm --filter @roo-code-cloud/db db:migrate",
|
||||
"db:reset": "pnpm db:down && rimraf .docker/data .docker/logs && pnpm db:up",
|
||||
"services:build": "docker compose build base && docker compose build roomote-api roomote-dashboard roomote-controller roomote-worker",
|
||||
"services:up": "docker compose up redis roomote-dashboard roomote-api -d --wait",
|
||||
"services:down": "docker compose down redis roomote-dashboard roomote-api",
|
||||
"tunnel": "ngrok http 3001 --domain cte.ngrok.dev"
|
||||
"services:build": "docker compose build --build-arg GH_TOKEN=$(npx dotenvx get GH_TOKEN -f .env.development) roomote-dashboard roomote-api roomote-controller roomote-worker",
|
||||
"services:up": "docker compose up roomote-dashboard roomote-api -d --wait",
|
||||
"services:down": "docker compose down roomote-dashboard roomote-api",
|
||||
"tunnel": "ngrok http 3001 --domain cte.ngrok.dev",
|
||||
"env:decrypt:test": "dotenvx decrypt -f .env.test --stdout",
|
||||
"env:decrypt:development": "dotenvx decrypt -f .env.development --stdout",
|
||||
"env:decrypt:preview": "dotenvx decrypt -f .env.preview --stdout",
|
||||
"env:decrypt:production": "dotenvx decrypt -f .env.production --stdout",
|
||||
"deploy:roomote-dashboard": "fly deploy --config fly.roomote-dashboard.toml",
|
||||
"deploy:roomote-api": "fly deploy --config fly.roomote-api.toml",
|
||||
"deploy:roomote-controller": "fly deploy --config fly.roomote-controller.toml"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@dotenvx/dotenvx": "^1.44.2",
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
DATABASE_URL=postgres://postgres:password@localhost:5432/development
|
||||
CLICKHOUSE_URL=http://localhost:8123/default
|
||||
CLICKHOUSE_PASSWORD=password
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
DATABASE_URL=postgres://postgres:password@localhost:5432/test
|
||||
CLICKHOUSE_URL=http://localhost:8123/default
|
||||
CLICKHOUSE_PASSWORD=password
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
import { defineConfig } from 'drizzle-kit';
|
||||
|
||||
import { Env } from '@roo-code-cloud/env';
|
||||
|
||||
export default defineConfig({
|
||||
schema: './src/schema.ts',
|
||||
out: './drizzle',
|
||||
dialect: 'postgresql',
|
||||
dbCredentials: {
|
||||
url: process.env.DATABASE_URL!,
|
||||
url: Env.DATABASE_URL,
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -19,13 +19,17 @@
|
|||
"lint": "eslint src --ext=ts --max-warnings=0",
|
||||
"check-types": "tsc --noEmit",
|
||||
"clean": "rimraf .turbo",
|
||||
"drizzle-kit": "tsx node_modules/drizzle-kit/bin.cjs",
|
||||
"db:generate": "dotenvx run -f .env.development -- drizzle-kit generate",
|
||||
"db:migrate": "dotenvx run -f .env.development -- drizzle-kit migrate",
|
||||
"db:push": "dotenvx run -f .env.development -- drizzle-kit push",
|
||||
"db:test:push": "dotenvx run -f .env.test -- drizzle-kit push"
|
||||
"drizzle-kit:test": "NODE_ENV=test dotenvx run -f ../../.env.test -- tsx node_modules/drizzle-kit/bin.cjs",
|
||||
"drizzle-kit:development": "NODE_ENV=development dotenvx run -f ../../.env.development -- tsx node_modules/drizzle-kit/bin.cjs",
|
||||
"drizzle-kit:production": "NODE_ENV=production dotenvx run -f ../../.env.production -- tsx node_modules/drizzle-kit/bin.cjs",
|
||||
"db:generate": "pnpm drizzle-kit:development generate",
|
||||
"db:migrate": "pnpm drizzle-kit:development migrate",
|
||||
"db:push": "pnpm drizzle-kit:development push",
|
||||
"db:test:push": "pnpm drizzle-kit:test push",
|
||||
"db:production:migrate": "pnpm drizzle-kit:production migrate"
|
||||
},
|
||||
"dependencies": {
|
||||
"@roo-code-cloud/env": "workspace:^",
|
||||
"@roo-code/types": "^1.29.0",
|
||||
"drizzle-orm": "^0.44.2",
|
||||
"postgres": "^3.4.7",
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
import { drizzle } from 'drizzle-orm/postgres-js';
|
||||
import postgres from 'postgres';
|
||||
|
||||
import { Env } from '@roo-code-cloud/env';
|
||||
|
||||
import * as schema from './schema';
|
||||
|
||||
const client = postgres(process.env.DATABASE_URL!, { prepare: false });
|
||||
const client = postgres(Env.DATABASE_URL, { prepare: false });
|
||||
const db = drizzle({ client, schema });
|
||||
|
||||
if (process.env.NODE_ENV === 'test') {
|
||||
if (
|
||||
!process.env.DATABASE_URL!.includes('test') ||
|
||||
!process.env.DATABASE_URL!.includes('localhost')
|
||||
) {
|
||||
throw new Error('DATABASE_URL is not a test database');
|
||||
}
|
||||
if (
|
||||
Env.NODE_ENV === 'test' &&
|
||||
(!Env.DATABASE_URL.includes('test') ||
|
||||
!Env.DATABASE_URL.includes('localhost'))
|
||||
) {
|
||||
throw new Error('DATABASE_URL is not a test database');
|
||||
}
|
||||
|
||||
const disconnect = async () => client.end();
|
||||
|
|
|
|||
|
|
@ -122,6 +122,12 @@ export const createJobSchema = z.discriminatedUnion('type', [
|
|||
commentUrl: z.string(),
|
||||
}),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal('test.prompt'),
|
||||
payload: z.object({
|
||||
text: z.string(),
|
||||
}),
|
||||
}),
|
||||
]);
|
||||
|
||||
export type CreateJob = z.infer<typeof createJobSchema>;
|
||||
|
|
@ -129,7 +135,6 @@ export type CreateJob = z.infer<typeof createJobSchema>;
|
|||
export type JobTypes = {
|
||||
[K in CreateJob['type']]: Extract<CreateJob, { type: K }>['payload'];
|
||||
};
|
||||
|
||||
/**
|
||||
* JobType, JobStatus, JobPayload, JobParams
|
||||
*/
|
||||
|
|
|
|||
4
packages/env/eslint.config.mjs
vendored
Normal file
4
packages/env/eslint.config.mjs
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import { config } from "@roo-code-cloud/config-eslint/base"
|
||||
|
||||
/** @type {import("eslint").Linter.Config} */
|
||||
export default [...config]
|
||||
23
packages/env/package.json
vendored
Normal file
23
packages/env/package.json
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "@roo-code-cloud/env",
|
||||
"private": true,
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"scripts": {
|
||||
"lint": "eslint src --ext=ts --max-warnings=0",
|
||||
"check-types": "tsc --noEmit",
|
||||
"test": "dotenvx run -f ../../.env.test -- vitest",
|
||||
"clean": "rimraf .turbo"
|
||||
},
|
||||
"dependencies": {
|
||||
"@roo-code/types": "^1.26.0",
|
||||
"@t3-oss/env-nextjs": "^0.13.6",
|
||||
"zod": "^3.25.41"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@roo-code-cloud/config-eslint": "workspace:^",
|
||||
"@roo-code-cloud/config-typescript": "workspace:^",
|
||||
"@types/node": "^24.0.3",
|
||||
"vitest": "^3.2.4"
|
||||
}
|
||||
}
|
||||
9
packages/env/src/__tests__/index.test.ts
vendored
Normal file
9
packages/env/src/__tests__/index.test.ts
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import { Env } from '../index';
|
||||
|
||||
describe('Env', () => {
|
||||
it('should be defined', () => {
|
||||
expect(Env.NODE_ENV).toBeDefined();
|
||||
expect(Env.DATABASE_URL).toContain('postgres://');
|
||||
expect(Env.DATABASE_URL).toContain('test');
|
||||
});
|
||||
});
|
||||
25
packages/env/src/index.ts
vendored
Normal file
25
packages/env/src/index.ts
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import { createEnv } from '@t3-oss/env-nextjs';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const Env = createEnv({
|
||||
shared: {
|
||||
NODE_ENV: z.enum(['test', 'development', 'production']),
|
||||
},
|
||||
server: {
|
||||
DATABASE_URL: z.string(),
|
||||
REDIS_URL: z.string(),
|
||||
CLICKHOUSE_URL: z.string().min(1),
|
||||
CLICKHOUSE_PASSWORD: z.string().min(1),
|
||||
CLERK_SECRET_KEY: z.string().min(1),
|
||||
},
|
||||
client: {},
|
||||
// You need to destructure all the keys manually.
|
||||
runtimeEnv: {
|
||||
NODE_ENV: process.env.NODE_ENV,
|
||||
DATABASE_URL: process.env.DATABASE_URL,
|
||||
REDIS_URL: process.env.REDIS_URL,
|
||||
CLICKHOUSE_URL: process.env.CLICKHOUSE_URL,
|
||||
CLICKHOUSE_PASSWORD: process.env.CLICKHOUSE_PASSWORD,
|
||||
CLERK_SECRET_KEY: process.env.CLERK_SECRET_KEY,
|
||||
},
|
||||
});
|
||||
8
packages/env/tsconfig.json
vendored
Normal file
8
packages/env/tsconfig.json
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"extends": "@roo-code-cloud/config-typescript/base.json",
|
||||
"compilerOptions": {
|
||||
"types": ["vitest/globals"]
|
||||
},
|
||||
"include": ["src", "scripts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
9
packages/env/vitest.config.ts
vendored
Normal file
9
packages/env/vitest.config.ts
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import { defineConfig } from 'vitest/config';
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
globals: true,
|
||||
watch: false,
|
||||
reporters: ['dot'],
|
||||
},
|
||||
});
|
||||
446
pnpm-lock.yaml
generated
446
pnpm-lock.yaml
generated
|
|
@ -42,6 +42,9 @@ importers:
|
|||
'@roo-code-cloud/db':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/db
|
||||
'@roo-code-cloud/env':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/env
|
||||
'@roo-code-cloud/ipc':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/ipc
|
||||
|
|
@ -51,6 +54,9 @@ importers:
|
|||
bullmq:
|
||||
specifier: ^5.37.0
|
||||
version: 5.54.3
|
||||
cmd-ts:
|
||||
specifier: ^0.13.0
|
||||
version: 0.13.0
|
||||
drizzle-orm:
|
||||
specifier: ^0.44.2
|
||||
version: 0.44.2(@electric-sql/pglite@0.3.0)(@libsql/client-wasm@0.15.5)(@opentelemetry/api@1.9.0)(@types/pg@8.15.2)(pg@8.15.6)(postgres@3.4.7)
|
||||
|
|
@ -152,9 +158,6 @@ importers:
|
|||
'@hookform/resolvers':
|
||||
specifier: ^5.0.1
|
||||
version: 5.0.1(react-hook-form@7.56.4(react@19.1.0))
|
||||
'@logtail/pino':
|
||||
specifier: ^0.5.5
|
||||
version: 0.5.5(pino@9.7.0)
|
||||
'@radix-ui/react-accordion':
|
||||
specifier: ^1.2.11
|
||||
version: 1.2.11(@types/react-dom@19.1.6(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||
|
|
@ -200,15 +203,15 @@ importers:
|
|||
'@roo-code-cloud/db':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/db
|
||||
'@roo-code-cloud/env':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/env
|
||||
'@roo-code/types':
|
||||
specifier: ^1.29.0
|
||||
version: 1.29.0
|
||||
'@sentry/nextjs':
|
||||
specifier: ^9.23.0
|
||||
version: 9.23.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(next@15.3.3(@babel/core@7.27.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(webpack@5.99.9)
|
||||
'@t3-oss/env-nextjs':
|
||||
specifier: ^0.13.6
|
||||
version: 0.13.6(arktype@2.1.20)(typescript@5.8.3)(zod@3.25.41)
|
||||
'@tailwindcss/postcss':
|
||||
specifier: ^4.1.8
|
||||
version: 4.1.8
|
||||
|
|
@ -321,9 +324,6 @@ importers:
|
|||
'@eslint/js':
|
||||
specifier: ^9.27.0
|
||||
version: 9.27.0
|
||||
'@next/bundle-analyzer':
|
||||
specifier: ^15.3.3
|
||||
version: 15.3.3
|
||||
'@next/eslint-plugin-next':
|
||||
specifier: ^15.3.3
|
||||
version: 15.3.3
|
||||
|
|
@ -434,6 +434,9 @@ importers:
|
|||
|
||||
packages/db:
|
||||
dependencies:
|
||||
'@roo-code-cloud/env':
|
||||
specifier: workspace:^
|
||||
version: link:../env
|
||||
'@roo-code/types':
|
||||
specifier: ^1.29.0
|
||||
version: 1.29.0
|
||||
|
|
@ -460,6 +463,31 @@ importers:
|
|||
specifier: ^0.31.1
|
||||
version: 0.31.1
|
||||
|
||||
packages/env:
|
||||
dependencies:
|
||||
'@roo-code/types':
|
||||
specifier: ^1.26.0
|
||||
version: 1.29.0
|
||||
'@t3-oss/env-nextjs':
|
||||
specifier: ^0.13.6
|
||||
version: 0.13.6(arktype@2.1.20)(typescript@5.8.3)(zod@3.25.41)
|
||||
zod:
|
||||
specifier: ^3.25.41
|
||||
version: 3.25.41
|
||||
devDependencies:
|
||||
'@roo-code-cloud/config-eslint':
|
||||
specifier: workspace:^
|
||||
version: link:../config-eslint
|
||||
'@roo-code-cloud/config-typescript':
|
||||
specifier: workspace:^
|
||||
version: link:../config-typescript
|
||||
'@types/node':
|
||||
specifier: ^24.0.3
|
||||
version: 24.0.3
|
||||
vitest:
|
||||
specifier: ^3.2.4
|
||||
version: 3.2.4(@types/debug@4.1.12)(@types/node@24.0.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)
|
||||
|
||||
packages/ipc:
|
||||
dependencies:
|
||||
'@roo-code/types':
|
||||
|
|
@ -721,10 +749,6 @@ packages:
|
|||
resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@discoveryjs/json-ext@0.5.7':
|
||||
resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
|
||||
'@dotenvx/dotenvx@1.44.2':
|
||||
resolution: {integrity: sha512-2C44+G2dch4cB6zw7+oGQ9VcFQuuVhc5xOzfVvY7iUEj2PRhiVMIB6SpNMK1V5TvpdqrAqCYFjclK18Mh9vwNQ==}
|
||||
hasBin: true
|
||||
|
|
@ -1290,27 +1314,6 @@ packages:
|
|||
'@libsql/core@0.15.9':
|
||||
resolution: {integrity: sha512-4OVdeAmuaCUq5hYT8NNn0nxlO9AcA/eTjXfUZ+QK8MT3Dz7Z76m73x7KxjU6I64WyXX98dauVH2b9XM+d84npw==}
|
||||
|
||||
'@logtail/core@0.5.4':
|
||||
resolution: {integrity: sha512-UlbxvUg5MDroqk6gEhtfKuuBShrvD/VaXl3T3jGU1U6I19Y1OwfB7e681LvH7RbsCAnOJFziM/7rMQib/CJTdg==}
|
||||
|
||||
'@logtail/node@0.5.5':
|
||||
resolution: {integrity: sha512-hSZDjl2wFRxe/+pxSlYNSpm0V3a2ZsiWqBifvtCBHTriwrNkd0LjQtedRlrjoBBumVxIMGdDOCPayAIbcux5YQ==}
|
||||
|
||||
'@logtail/pino@0.5.5':
|
||||
resolution: {integrity: sha512-RNGWSWmqXHmchWm0MZS69JfnEAULck2uTrbh0/rZDBhnsZjsUTXmviDsA+zfjLr6Y702CmPLwx7ctlhHK7pbEw==}
|
||||
peerDependencies:
|
||||
pino: ^7.0.0 || ^8.0.0 || ^9.0.0
|
||||
|
||||
'@logtail/tools@0.5.4':
|
||||
resolution: {integrity: sha512-S0PtfWOVVgvb36q8mLksMw910mO2TahDaqIYnUM/ZEYX+AwqKRGov4zt/X33zHRzCFVpSKoZFv7bFs8TBie/pQ==}
|
||||
|
||||
'@logtail/types@0.5.3':
|
||||
resolution: {integrity: sha512-5uKf1xQ7wRqSW0lYIwDpXdXcFHxPKH5EM22MoEjwTpd8suymOYuEdx9qCCHCYey4uOhPq7x6OkZf86bTO83JsA==}
|
||||
|
||||
'@msgpack/msgpack@2.8.0':
|
||||
resolution: {integrity: sha512-h9u4u/jiIRKbq25PM+zymTyW6bhTzELvOoUd+AvYriWOAKpLGnIamaET3pnHYoI5iYphAHBI4ayx0MehR+VVPQ==}
|
||||
engines: {node: '>= 10'}
|
||||
|
||||
'@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3':
|
||||
resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==}
|
||||
cpu: [arm64]
|
||||
|
|
@ -1341,9 +1344,6 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@next/bundle-analyzer@15.3.3':
|
||||
resolution: {integrity: sha512-9gddnjACK6yOa5IkmeFyzcwZh2rscsb6ZspTd7tymPYKQM96fJuKjn9HrRtPNKiMm7ExKNadAJqREmHdBgHZ9A==}
|
||||
|
||||
'@next/env@15.3.3':
|
||||
resolution: {integrity: sha512-OdiMrzCl2Xi0VTjiQQUK0Xh7bJHnOuET2s+3V+Y40WJBAXrJeGA3f+I8MZJ/YQ3mVGi5XGR1L66oFlgqXhQ4Vw==}
|
||||
|
||||
|
|
@ -1615,9 +1615,6 @@ packages:
|
|||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
'@polka/url@1.0.0-next.29':
|
||||
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
|
||||
|
||||
'@prisma/instrumentation@6.8.2':
|
||||
resolution: {integrity: sha512-5NCTbZjw7a+WIZ/ey6G8SY+YKcyM2zBF0hOT1muvqC9TbVtTCr5Qv3RL/2iNDOzLUHEvo4I1uEfioyfuNOGK8Q==}
|
||||
peerDependencies:
|
||||
|
|
@ -2294,9 +2291,6 @@ packages:
|
|||
'@roo-code/types@1.29.0':
|
||||
resolution: {integrity: sha512-bovFOCVQYuWnV2Cvdcx5tWp8aUpF0tEoxN0rS05hzzwdDeDxB6F6q5orKsQqghTS0yqv5pYclQLZRyAV7oBsbw==}
|
||||
|
||||
'@roo-code/types@1.28.0':
|
||||
resolution: {integrity: sha512-kJAWDaY80BLPRxVa1Nz3Fuj7tvnSVMsRlpgNq3YXvFyQwWsui7DZz/AgX5qm+CwcAHXHBPmCUn5oV5XnEAEykw==}
|
||||
|
||||
'@schummar/icu-type-parser@1.21.5':
|
||||
resolution: {integrity: sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw==}
|
||||
|
||||
|
|
@ -2762,9 +2756,6 @@ packages:
|
|||
'@types/shimmer@1.2.0':
|
||||
resolution: {integrity: sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==}
|
||||
|
||||
'@types/stack-trace@0.0.33':
|
||||
resolution: {integrity: sha512-O7in6531Bbvlb2KEsJ0dq0CHZvc3iWSR5ZYMtvGgnHA56VgriAN/AU2LorfmcvAl2xc9N5fbCTRyMRRl8nd74g==}
|
||||
|
||||
'@types/tedious@4.0.14':
|
||||
resolution: {integrity: sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==}
|
||||
|
||||
|
|
@ -2923,10 +2914,6 @@ packages:
|
|||
'@xtuc/long@4.2.2':
|
||||
resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
|
||||
|
||||
abort-controller@3.0.0:
|
||||
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
|
||||
engines: {node: '>=6.5'}
|
||||
|
||||
accepts@2.0.0:
|
||||
resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
|
@ -2941,15 +2928,6 @@ packages:
|
|||
peerDependencies:
|
||||
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||
|
||||
acorn-walk@8.3.4:
|
||||
resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
||||
acorn@8.14.1:
|
||||
resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
|
||||
acorn@8.15.0:
|
||||
resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
|
@ -3084,9 +3062,6 @@ packages:
|
|||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
base64-js@1.5.1:
|
||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||
|
||||
binary-extensions@2.3.0:
|
||||
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
|
||||
engines: {node: '>=8'}
|
||||
|
|
@ -3116,9 +3091,6 @@ packages:
|
|||
buffer-from@1.1.2:
|
||||
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
|
||||
|
||||
buffer@6.0.3:
|
||||
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
|
||||
|
||||
bullmq@5.54.3:
|
||||
resolution: {integrity: sha512-MVK2pOkB3hvrIcubwI8dS4qWHJLNKakKPpgRBTw91sIpPZArmvZ4t2hvryyEaJXJbAS/JHd6pKYOUd+RGRkWQQ==}
|
||||
|
||||
|
|
@ -3236,6 +3208,9 @@ packages:
|
|||
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
cmd-ts@0.13.0:
|
||||
resolution: {integrity: sha512-nsnxf6wNIM/JAS7T/x/1JmbEsjH0a8tezXqqpaL0O6+eV0/aDEnRxwjxpu0VzDdRcaC1ixGSbRlUuf/IU59I4g==}
|
||||
|
||||
cmdk@1.1.1:
|
||||
resolution: {integrity: sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==}
|
||||
peerDependencies:
|
||||
|
|
@ -3273,10 +3248,6 @@ packages:
|
|||
commander@2.20.3:
|
||||
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
|
||||
|
||||
commander@7.2.0:
|
||||
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
|
||||
engines: {node: '>= 10'}
|
||||
|
||||
commondir@1.0.1:
|
||||
resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
|
||||
|
||||
|
|
@ -3410,9 +3381,6 @@ packages:
|
|||
dateformat@4.6.3:
|
||||
resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==}
|
||||
|
||||
debounce@1.2.1:
|
||||
resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==}
|
||||
|
||||
debug@4.4.1:
|
||||
resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
|
|
@ -3476,6 +3444,9 @@ packages:
|
|||
devlop@1.1.0:
|
||||
resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
|
||||
|
||||
didyoumean@1.2.2:
|
||||
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
|
||||
|
||||
doctrine@2.1.0:
|
||||
resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
|
@ -3604,9 +3575,6 @@ packages:
|
|||
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
duplexer@0.1.2:
|
||||
resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
|
||||
|
||||
eastasianwidth@0.2.0:
|
||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||
|
||||
|
|
@ -3822,10 +3790,6 @@ packages:
|
|||
resolution: {integrity: sha512-2QiHxshejKgJrYMzSI9MEHrvhmzxBL+eLyiM5IiyjDBySkgwS2+tdtnO3gbx8pEisu/yOFCIhfCb63gCEu0yBQ==}
|
||||
engines: {node: '>=13.0.0'}
|
||||
|
||||
event-target-shim@5.0.1:
|
||||
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
eventemitter3@4.0.7:
|
||||
resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
|
||||
|
||||
|
|
@ -4080,10 +4044,6 @@ packages:
|
|||
graphemer@1.4.0:
|
||||
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
|
||||
|
||||
gzip-size@6.0.0:
|
||||
resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
hard-rejection@2.1.0:
|
||||
resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==}
|
||||
engines: {node: '>=6'}
|
||||
|
|
@ -4138,9 +4098,6 @@ packages:
|
|||
resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
html-escaper@2.0.2:
|
||||
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
|
||||
|
||||
html-url-attributes@3.0.1:
|
||||
resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==}
|
||||
|
||||
|
|
@ -4180,9 +4137,6 @@ packages:
|
|||
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
ieee754@1.2.1:
|
||||
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
||||
|
||||
ignore@5.3.2:
|
||||
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
|
||||
engines: {node: '>= 4'}
|
||||
|
|
@ -4344,10 +4298,6 @@ packages:
|
|||
resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
is-plain-object@5.0.0:
|
||||
resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
is-potential-custom-element-name@1.0.1:
|
||||
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
|
||||
|
||||
|
|
@ -4669,9 +4619,6 @@ packages:
|
|||
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
|
||||
hasBin: true
|
||||
|
||||
loupe@3.1.3:
|
||||
resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==}
|
||||
|
||||
loupe@3.1.4:
|
||||
resolution: {integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==}
|
||||
|
||||
|
|
@ -4916,10 +4863,6 @@ packages:
|
|||
module-details-from-path@1.0.4:
|
||||
resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==}
|
||||
|
||||
mrmime@2.0.1:
|
||||
resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
|
||||
|
|
@ -5105,10 +5048,6 @@ packages:
|
|||
resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
opener@1.5.2:
|
||||
resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==}
|
||||
hasBin: true
|
||||
|
||||
optionator@0.9.4:
|
||||
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
|
|
@ -5273,9 +5212,6 @@ packages:
|
|||
engines: {node: '>=0.10'}
|
||||
hasBin: true
|
||||
|
||||
pino-abstract-transport@1.2.0:
|
||||
resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==}
|
||||
|
||||
pino-abstract-transport@2.0.0:
|
||||
resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==}
|
||||
|
||||
|
|
@ -5388,10 +5324,6 @@ packages:
|
|||
process-warning@5.0.0:
|
||||
resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==}
|
||||
|
||||
process@0.11.10:
|
||||
resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
|
||||
engines: {node: '>= 0.6.0'}
|
||||
|
||||
progress@2.0.3:
|
||||
resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
|
@ -5543,10 +5475,6 @@ packages:
|
|||
readable-stream@2.3.8:
|
||||
resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
|
||||
|
||||
readable-stream@4.7.0:
|
||||
resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
|
||||
readdirp@3.6.0:
|
||||
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
|
||||
engines: {node: '>=8.10.0'}
|
||||
|
|
@ -5728,10 +5656,6 @@ packages:
|
|||
resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
serialize-error@8.1.0:
|
||||
resolution: {integrity: sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
serialize-javascript@6.0.2:
|
||||
resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
|
||||
|
||||
|
|
@ -5805,10 +5729,6 @@ packages:
|
|||
simple-swizzle@0.2.2:
|
||||
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
|
||||
|
||||
sirv@2.0.4:
|
||||
resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==}
|
||||
engines: {node: '>= 10'}
|
||||
|
||||
slice-ansi@5.0.0:
|
||||
resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
|
@ -5870,9 +5790,6 @@ packages:
|
|||
stack-generator@2.0.10:
|
||||
resolution: {integrity: sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==}
|
||||
|
||||
stack-trace@0.0.10:
|
||||
resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==}
|
||||
|
||||
stackback@0.0.2:
|
||||
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
|
||||
|
||||
|
|
@ -5952,9 +5869,6 @@ packages:
|
|||
string_decoder@1.1.1:
|
||||
resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
|
||||
|
||||
string_decoder@1.3.0:
|
||||
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
||||
|
||||
stringify-entities@4.0.4:
|
||||
resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
|
||||
|
||||
|
|
@ -6137,10 +6051,6 @@ packages:
|
|||
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
|
||||
engines: {node: '>=0.6'}
|
||||
|
||||
totalist@3.0.1:
|
||||
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
tough-cookie@5.1.2:
|
||||
resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==}
|
||||
engines: {node: '>=16'}
|
||||
|
|
@ -6231,10 +6141,6 @@ packages:
|
|||
resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
type-fest@0.20.2:
|
||||
resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
type-fest@0.6.0:
|
||||
resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==}
|
||||
engines: {node: '>=8'}
|
||||
|
|
@ -6497,11 +6403,6 @@ packages:
|
|||
resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
webpack-bundle-analyzer@4.10.1:
|
||||
resolution: {integrity: sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==}
|
||||
engines: {node: '>= 10.13.0'}
|
||||
hasBin: true
|
||||
|
||||
webpack-sources@3.3.0:
|
||||
resolution: {integrity: sha512-77R0RDmJfj9dyv5p3bM5pOHa+X8/ZkO9c7kpDstigkC4nIDobadsfSGCwB4bKhMVxqAok8tajaoR8rirM7+VFQ==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
|
|
@ -6588,18 +6489,6 @@ packages:
|
|||
wrappy@1.0.2:
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
|
||||
ws@7.5.10:
|
||||
resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==}
|
||||
engines: {node: '>=8.3.0'}
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: ^5.0.2
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
|
||||
ws@8.18.2:
|
||||
resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
|
|
@ -6975,8 +6864,6 @@ snapshots:
|
|||
|
||||
'@csstools/css-tokenizer@3.0.4': {}
|
||||
|
||||
'@discoveryjs/json-ext@0.5.7': {}
|
||||
|
||||
'@dotenvx/dotenvx@1.44.2':
|
||||
dependencies:
|
||||
commander: 11.1.0
|
||||
|
|
@ -7394,36 +7281,6 @@ snapshots:
|
|||
js-base64: 3.7.7
|
||||
optional: true
|
||||
|
||||
'@logtail/core@0.5.4':
|
||||
dependencies:
|
||||
'@logtail/tools': 0.5.4
|
||||
'@logtail/types': 0.5.3
|
||||
serialize-error: 8.1.0
|
||||
|
||||
'@logtail/node@0.5.5':
|
||||
dependencies:
|
||||
'@logtail/core': 0.5.4
|
||||
'@logtail/types': 0.5.3
|
||||
'@msgpack/msgpack': 2.8.0
|
||||
'@types/stack-trace': 0.0.33
|
||||
minimatch: 9.0.5
|
||||
stack-trace: 0.0.10
|
||||
|
||||
'@logtail/pino@0.5.5(pino@9.7.0)':
|
||||
dependencies:
|
||||
'@logtail/node': 0.5.5
|
||||
'@logtail/types': 0.5.3
|
||||
pino: 9.7.0
|
||||
pino-abstract-transport: 1.2.0
|
||||
|
||||
'@logtail/tools@0.5.4':
|
||||
dependencies:
|
||||
'@logtail/types': 0.5.3
|
||||
|
||||
'@logtail/types@0.5.3': {}
|
||||
|
||||
'@msgpack/msgpack@2.8.0': {}
|
||||
|
||||
'@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3':
|
||||
optional: true
|
||||
|
||||
|
|
@ -7442,13 +7299,6 @@ snapshots:
|
|||
'@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3':
|
||||
optional: true
|
||||
|
||||
'@next/bundle-analyzer@15.3.3':
|
||||
dependencies:
|
||||
webpack-bundle-analyzer: 4.10.1
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
|
||||
'@next/env@15.3.3': {}
|
||||
|
||||
'@next/eslint-plugin-next@15.3.3':
|
||||
|
|
@ -7746,8 +7596,6 @@ snapshots:
|
|||
playwright: 1.52.0
|
||||
optional: true
|
||||
|
||||
'@polka/url@1.0.0-next.29': {}
|
||||
|
||||
'@prisma/instrumentation@6.8.2(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
|
|
@ -8359,8 +8207,6 @@ snapshots:
|
|||
|
||||
'@roo-code/types@1.29.0': {}
|
||||
|
||||
'@roo-code/types@1.28.0': {}
|
||||
|
||||
'@schummar/icu-type-parser@1.21.5': {}
|
||||
|
||||
'@sec-ant/readable-stream@0.4.1': {}
|
||||
|
|
@ -8850,7 +8696,7 @@ snapshots:
|
|||
'@types/pg@8.15.2':
|
||||
dependencies:
|
||||
'@types/node': 22.15.32
|
||||
pg-protocol: 1.10.0
|
||||
pg-protocol: 1.10.2
|
||||
pg-types: 4.0.2
|
||||
|
||||
'@types/pg@8.6.1':
|
||||
|
|
@ -8884,8 +8730,6 @@ snapshots:
|
|||
|
||||
'@types/shimmer@1.2.0': {}
|
||||
|
||||
'@types/stack-trace@0.0.33': {}
|
||||
|
||||
'@types/tedious@4.0.14':
|
||||
dependencies:
|
||||
'@types/node': 22.15.32
|
||||
|
|
@ -9032,6 +8876,14 @@ snapshots:
|
|||
optionalDependencies:
|
||||
vite: 6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)
|
||||
|
||||
'@vitest/mocker@3.2.4(vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))':
|
||||
dependencies:
|
||||
'@vitest/spy': 3.2.4
|
||||
estree-walker: 3.0.3
|
||||
magic-string: 0.30.17
|
||||
optionalDependencies:
|
||||
vite: 6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)
|
||||
|
||||
'@vitest/pretty-format@3.2.4':
|
||||
dependencies:
|
||||
tinyrainbow: 2.0.0
|
||||
|
|
@ -9140,10 +8992,6 @@ snapshots:
|
|||
|
||||
'@xtuc/long@4.2.2': {}
|
||||
|
||||
abort-controller@3.0.0:
|
||||
dependencies:
|
||||
event-target-shim: 5.0.1
|
||||
|
||||
accepts@2.0.0:
|
||||
dependencies:
|
||||
mime-types: 3.0.1
|
||||
|
|
@ -9157,12 +9005,6 @@ snapshots:
|
|||
dependencies:
|
||||
acorn: 8.15.0
|
||||
|
||||
acorn-walk@8.3.4:
|
||||
dependencies:
|
||||
acorn: 8.15.0
|
||||
|
||||
acorn@8.14.1: {}
|
||||
|
||||
acorn@8.15.0: {}
|
||||
|
||||
agent-base@6.0.2:
|
||||
|
|
@ -9308,8 +9150,6 @@ snapshots:
|
|||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
base64-js@1.5.1: {}
|
||||
|
||||
binary-extensions@2.3.0: {}
|
||||
|
||||
body-parser@2.2.0:
|
||||
|
|
@ -9350,11 +9190,6 @@ snapshots:
|
|||
|
||||
buffer-from@1.1.2: {}
|
||||
|
||||
buffer@6.0.3:
|
||||
dependencies:
|
||||
base64-js: 1.5.1
|
||||
ieee754: 1.2.1
|
||||
|
||||
bullmq@5.54.3:
|
||||
dependencies:
|
||||
cron-parser: 4.9.0
|
||||
|
|
@ -9411,7 +9246,7 @@ snapshots:
|
|||
assertion-error: 2.0.1
|
||||
check-error: 2.1.1
|
||||
deep-eql: 5.0.2
|
||||
loupe: 3.1.3
|
||||
loupe: 3.1.4
|
||||
pathval: 2.0.0
|
||||
|
||||
chalk@3.0.0:
|
||||
|
|
@ -9479,6 +9314,15 @@ snapshots:
|
|||
|
||||
cluster-key-slot@1.1.2: {}
|
||||
|
||||
cmd-ts@0.13.0:
|
||||
dependencies:
|
||||
chalk: 4.1.2
|
||||
debug: 4.4.1
|
||||
didyoumean: 1.2.2
|
||||
strip-ansi: 6.0.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
cmdk@1.1.1(@types/react-dom@19.1.6(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
|
||||
dependencies:
|
||||
'@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.6)(react@19.1.0)
|
||||
|
|
@ -9519,8 +9363,6 @@ snapshots:
|
|||
|
||||
commander@2.20.3: {}
|
||||
|
||||
commander@7.2.0: {}
|
||||
|
||||
commondir@1.0.1: {}
|
||||
|
||||
concat-map@0.0.1: {}
|
||||
|
|
@ -9650,8 +9492,6 @@ snapshots:
|
|||
|
||||
dateformat@4.6.3: {}
|
||||
|
||||
debounce@1.2.1: {}
|
||||
|
||||
debug@4.4.1:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
|
@ -9701,6 +9541,8 @@ snapshots:
|
|||
dependencies:
|
||||
dequal: 2.0.3
|
||||
|
||||
didyoumean@1.2.2: {}
|
||||
|
||||
doctrine@2.1.0:
|
||||
dependencies:
|
||||
esutils: 2.0.3
|
||||
|
|
@ -9749,8 +9591,6 @@ snapshots:
|
|||
es-errors: 1.3.0
|
||||
gopd: 1.2.0
|
||||
|
||||
duplexer@0.1.2: {}
|
||||
|
||||
eastasianwidth@0.2.0: {}
|
||||
|
||||
easy-stack@1.0.1: {}
|
||||
|
|
@ -10101,8 +9941,6 @@ snapshots:
|
|||
copyfiles: 2.4.1
|
||||
strong-type: 0.1.6
|
||||
|
||||
event-target-shim@5.0.1: {}
|
||||
|
||||
eventemitter3@4.0.7: {}
|
||||
|
||||
eventemitter3@5.0.1: {}
|
||||
|
|
@ -10397,10 +10235,6 @@ snapshots:
|
|||
|
||||
graphemer@1.4.0: {}
|
||||
|
||||
gzip-size@6.0.0:
|
||||
dependencies:
|
||||
duplexer: 0.1.2
|
||||
|
||||
hard-rejection@2.1.0: {}
|
||||
|
||||
has-bigints@1.1.0: {}
|
||||
|
|
@ -10465,8 +10299,6 @@ snapshots:
|
|||
dependencies:
|
||||
whatwg-encoding: 3.1.1
|
||||
|
||||
html-escaper@2.0.2: {}
|
||||
|
||||
html-url-attributes@3.0.1: {}
|
||||
|
||||
http-errors@2.0.0:
|
||||
|
|
@ -10510,8 +10342,6 @@ snapshots:
|
|||
dependencies:
|
||||
safer-buffer: 2.1.2
|
||||
|
||||
ieee754@1.2.1: {}
|
||||
|
||||
ignore@5.3.2: {}
|
||||
|
||||
ignore@7.0.4: {}
|
||||
|
|
@ -10676,8 +10506,6 @@ snapshots:
|
|||
|
||||
is-plain-obj@4.1.0: {}
|
||||
|
||||
is-plain-object@5.0.0: {}
|
||||
|
||||
is-potential-custom-element-name@1.0.1: {}
|
||||
|
||||
is-promise@4.0.0: {}
|
||||
|
|
@ -10994,8 +10822,6 @@ snapshots:
|
|||
dependencies:
|
||||
js-tokens: 4.0.0
|
||||
|
||||
loupe@3.1.3: {}
|
||||
|
||||
loupe@3.1.4: {}
|
||||
|
||||
lower-case@2.0.2:
|
||||
|
|
@ -11348,8 +11174,6 @@ snapshots:
|
|||
|
||||
module-details-from-path@1.0.4: {}
|
||||
|
||||
mrmime@2.0.1: {}
|
||||
|
||||
ms@2.1.3: {}
|
||||
|
||||
msgpackr-extract@3.0.3:
|
||||
|
|
@ -11556,8 +11380,6 @@ snapshots:
|
|||
dependencies:
|
||||
mimic-function: 5.0.1
|
||||
|
||||
opener@1.5.2: {}
|
||||
|
||||
optionator@0.9.4:
|
||||
dependencies:
|
||||
deep-is: 0.1.4
|
||||
|
|
@ -11673,8 +11495,7 @@ snapshots:
|
|||
|
||||
pg-protocol@1.10.0: {}
|
||||
|
||||
pg-protocol@1.10.2:
|
||||
optional: true
|
||||
pg-protocol@1.10.2: {}
|
||||
|
||||
pg-types@2.2.0:
|
||||
dependencies:
|
||||
|
|
@ -11718,11 +11539,6 @@ snapshots:
|
|||
|
||||
pidtree@0.6.0: {}
|
||||
|
||||
pino-abstract-transport@1.2.0:
|
||||
dependencies:
|
||||
readable-stream: 4.7.0
|
||||
split2: 4.2.0
|
||||
|
||||
pino-abstract-transport@2.0.0:
|
||||
dependencies:
|
||||
split2: 4.2.0
|
||||
|
|
@ -11834,8 +11650,6 @@ snapshots:
|
|||
|
||||
process-warning@5.0.0: {}
|
||||
|
||||
process@0.11.10: {}
|
||||
|
||||
progress@2.0.3: {}
|
||||
|
||||
prop-types@15.8.1:
|
||||
|
|
@ -12018,14 +11832,6 @@ snapshots:
|
|||
string_decoder: 1.1.1
|
||||
util-deprecate: 1.0.2
|
||||
|
||||
readable-stream@4.7.0:
|
||||
dependencies:
|
||||
abort-controller: 3.0.0
|
||||
buffer: 6.0.3
|
||||
events: 3.3.0
|
||||
process: 0.11.10
|
||||
string_decoder: 1.3.0
|
||||
|
||||
readdirp@3.6.0:
|
||||
dependencies:
|
||||
picomatch: 2.3.1
|
||||
|
|
@ -12288,10 +12094,6 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
serialize-error@8.1.0:
|
||||
dependencies:
|
||||
type-fest: 0.20.2
|
||||
|
||||
serialize-javascript@6.0.2:
|
||||
dependencies:
|
||||
randombytes: 2.1.0
|
||||
|
|
@ -12409,12 +12211,6 @@ snapshots:
|
|||
is-arrayish: 0.3.2
|
||||
optional: true
|
||||
|
||||
sirv@2.0.4:
|
||||
dependencies:
|
||||
'@polka/url': 1.0.0-next.29
|
||||
mrmime: 2.0.1
|
||||
totalist: 3.0.1
|
||||
|
||||
slice-ansi@5.0.0:
|
||||
dependencies:
|
||||
ansi-styles: 6.2.1
|
||||
|
|
@ -12478,8 +12274,6 @@ snapshots:
|
|||
dependencies:
|
||||
stackframe: 1.3.4
|
||||
|
||||
stack-trace@0.0.10: {}
|
||||
|
||||
stackback@0.0.2: {}
|
||||
|
||||
stackframe@1.3.4: {}
|
||||
|
|
@ -12584,10 +12378,6 @@ snapshots:
|
|||
dependencies:
|
||||
safe-buffer: 5.1.2
|
||||
|
||||
string_decoder@1.3.0:
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
stringify-entities@4.0.4:
|
||||
dependencies:
|
||||
character-entities-html4: 2.1.0
|
||||
|
|
@ -12737,8 +12527,6 @@ snapshots:
|
|||
|
||||
toidentifier@1.0.1: {}
|
||||
|
||||
totalist@3.0.1: {}
|
||||
|
||||
tough-cookie@5.1.2:
|
||||
dependencies:
|
||||
tldts: 6.1.86
|
||||
|
|
@ -12807,8 +12595,6 @@ snapshots:
|
|||
|
||||
type-fest@0.18.1: {}
|
||||
|
||||
type-fest@0.20.2: {}
|
||||
|
||||
type-fest@0.6.0: {}
|
||||
|
||||
type-fest@0.7.1: {}
|
||||
|
|
@ -13073,6 +12859,27 @@ snapshots:
|
|||
- tsx
|
||||
- yaml
|
||||
|
||||
vite-node@3.2.4(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0):
|
||||
dependencies:
|
||||
cac: 6.7.14
|
||||
debug: 4.4.1
|
||||
es-module-lexer: 1.7.0
|
||||
pathe: 2.0.3
|
||||
vite: 6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- jiti
|
||||
- less
|
||||
- lightningcss
|
||||
- sass
|
||||
- sass-embedded
|
||||
- stylus
|
||||
- sugarss
|
||||
- supports-color
|
||||
- terser
|
||||
- tsx
|
||||
- yaml
|
||||
|
||||
vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.27)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)):
|
||||
dependencies:
|
||||
debug: 4.4.1
|
||||
|
|
@ -13135,6 +12942,23 @@ snapshots:
|
|||
tsx: 4.20.3
|
||||
yaml: 2.8.0
|
||||
|
||||
vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0):
|
||||
dependencies:
|
||||
esbuild: 0.25.5
|
||||
fdir: 6.4.5(picomatch@4.0.2)
|
||||
picomatch: 4.0.2
|
||||
postcss: 8.5.4
|
||||
rollup: 4.41.1
|
||||
tinyglobby: 0.2.14
|
||||
optionalDependencies:
|
||||
'@types/node': 24.0.3
|
||||
fsevents: 2.3.3
|
||||
jiti: 2.4.2
|
||||
lightningcss: 1.30.1
|
||||
terser: 5.43.1
|
||||
tsx: 4.20.3
|
||||
yaml: 2.8.0
|
||||
|
||||
vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0):
|
||||
dependencies:
|
||||
'@types/chai': 5.2.2
|
||||
|
|
@ -13264,6 +13088,49 @@ snapshots:
|
|||
- tsx
|
||||
- yaml
|
||||
|
||||
vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0):
|
||||
dependencies:
|
||||
'@types/chai': 5.2.2
|
||||
'@vitest/expect': 3.2.4
|
||||
'@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))
|
||||
'@vitest/pretty-format': 3.2.4
|
||||
'@vitest/runner': 3.2.4
|
||||
'@vitest/snapshot': 3.2.4
|
||||
'@vitest/spy': 3.2.4
|
||||
'@vitest/utils': 3.2.4
|
||||
chai: 5.2.0
|
||||
debug: 4.4.1
|
||||
expect-type: 1.2.1
|
||||
magic-string: 0.30.17
|
||||
pathe: 2.0.3
|
||||
picomatch: 4.0.2
|
||||
std-env: 3.9.0
|
||||
tinybench: 2.9.0
|
||||
tinyexec: 0.3.2
|
||||
tinyglobby: 0.2.14
|
||||
tinypool: 1.1.1
|
||||
tinyrainbow: 2.0.0
|
||||
vite: 6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)
|
||||
vite-node: 3.2.4(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)
|
||||
why-is-node-running: 2.3.0
|
||||
optionalDependencies:
|
||||
'@types/debug': 4.1.12
|
||||
'@types/node': 24.0.3
|
||||
jsdom: 26.1.0
|
||||
transitivePeerDependencies:
|
||||
- jiti
|
||||
- less
|
||||
- lightningcss
|
||||
- msw
|
||||
- sass
|
||||
- sass-embedded
|
||||
- stylus
|
||||
- sugarss
|
||||
- supports-color
|
||||
- terser
|
||||
- tsx
|
||||
- yaml
|
||||
|
||||
w3c-xmlserializer@5.0.0:
|
||||
dependencies:
|
||||
xml-name-validator: 5.0.0
|
||||
|
|
@ -13279,25 +13146,6 @@ snapshots:
|
|||
|
||||
webidl-conversions@7.0.0: {}
|
||||
|
||||
webpack-bundle-analyzer@4.10.1:
|
||||
dependencies:
|
||||
'@discoveryjs/json-ext': 0.5.7
|
||||
acorn: 8.14.1
|
||||
acorn-walk: 8.3.4
|
||||
commander: 7.2.0
|
||||
debounce: 1.2.1
|
||||
escape-string-regexp: 4.0.0
|
||||
gzip-size: 6.0.0
|
||||
html-escaper: 2.0.2
|
||||
is-plain-object: 5.0.0
|
||||
opener: 1.5.2
|
||||
picocolors: 1.1.1
|
||||
sirv: 2.0.4
|
||||
ws: 7.5.10
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
|
||||
webpack-sources@3.3.0: {}
|
||||
|
||||
webpack-sources@3.3.3: {}
|
||||
|
|
@ -13427,8 +13275,6 @@ snapshots:
|
|||
|
||||
wrappy@1.0.2: {}
|
||||
|
||||
ws@7.5.10: {}
|
||||
|
||||
ws@8.18.2: {}
|
||||
|
||||
xml-name-validator@5.0.0: {}
|
||||
|
|
|
|||
|
|
@ -1,87 +0,0 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
// npx tsx scripts/find-missing-translations.ts
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
function extractKeys(obj: any, prefix = ''): string[] {
|
||||
let keys: string[] = [];
|
||||
|
||||
for (const key in obj) {
|
||||
const currentKey = prefix ? `${prefix}.${key}` : key;
|
||||
|
||||
if (typeof obj[key] === 'object' && obj[key] !== null) {
|
||||
keys = [...keys, ...extractKeys(obj[key], currentKey)];
|
||||
} else {
|
||||
keys.push(currentKey);
|
||||
}
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const rootDir = path.resolve(__dirname, '..');
|
||||
const localesDir = path.join('src', 'i18n', 'locales');
|
||||
|
||||
const files = fs
|
||||
.readdirSync(path.join(rootDir, localesDir))
|
||||
.filter((file) => file.endsWith('.json'))
|
||||
.map((file) => path.join(rootDir, localesDir, file));
|
||||
|
||||
const localeKeys: { [locale: string]: Set<string> } = {};
|
||||
const allKeys = new Set<string>();
|
||||
|
||||
for (const file of files) {
|
||||
const keys = extractKeys(JSON.parse(fs.readFileSync(file, 'utf8')));
|
||||
const relativePath = path.join(localesDir, path.basename(file));
|
||||
localeKeys[relativePath] = new Set(keys);
|
||||
|
||||
for (const key of keys) {
|
||||
allKeys.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
Object.entries(localeKeys).forEach(([locale, keys]) => {
|
||||
const missingKeys = Array.from(allKeys).filter((key) => !keys.has(key));
|
||||
|
||||
if (missingKeys.length > 0) {
|
||||
console.log(
|
||||
`\n[${locale}] Missing ${missingKeys.length} translation(s):`,
|
||||
);
|
||||
|
||||
const groupedMissing = new Map<string, string[]>();
|
||||
|
||||
for (const key of missingKeys) {
|
||||
const parts = key.split('.');
|
||||
|
||||
if (parts.length >= 2) {
|
||||
const namespace = parts[0];
|
||||
const subKey = parts.slice(1).join('.');
|
||||
|
||||
if (namespace && subKey) {
|
||||
if (!groupedMissing.has(namespace)) {
|
||||
groupedMissing.set(namespace, []);
|
||||
}
|
||||
|
||||
const group = groupedMissing.get(namespace);
|
||||
|
||||
if (group) {
|
||||
group.push(subKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const [namespace, keys] of groupedMissing.entries()) {
|
||||
console.log(`${namespace}`);
|
||||
keys.forEach((key) => console.log(`\t${key}`));
|
||||
}
|
||||
} else {
|
||||
console.log(`\n[${locale}] No missing translations`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
main();
|
||||
|
|
@ -1,221 +0,0 @@
|
|||
// npx dotenvx run -f .env.development -f .env.local -- tsx scripts/test-agent-endpoint.ts [orgId] [agent] [baseUrl]
|
||||
|
||||
import postgres from 'postgres';
|
||||
import { drizzle } from 'drizzle-orm/postgres-js';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import crypto from 'crypto';
|
||||
|
||||
import { agents, users } from '@/db/schema';
|
||||
import { getAgentToken } from '@/lib/server/agent-auth';
|
||||
|
||||
const client = postgres(process.env.DATABASE_URL!);
|
||||
const db = drizzle(client);
|
||||
|
||||
interface TestConfig {
|
||||
orgId: string;
|
||||
agentName: string;
|
||||
baseUrl: string;
|
||||
}
|
||||
|
||||
async function createTestAgent(config: TestConfig): Promise<string> {
|
||||
console.log('🤖 Creating test agent...');
|
||||
|
||||
try {
|
||||
const existingAgent = await db
|
||||
.select()
|
||||
.from(agents)
|
||||
.where(eq(agents.displayName, config.agentName))
|
||||
.limit(1);
|
||||
|
||||
if (existingAgent.length > 0) {
|
||||
console.log(`✅ Using existing agent: ${existingAgent[0]!.id}`);
|
||||
return existingAgent[0]!.id;
|
||||
}
|
||||
|
||||
const existingUsers = await db.select().from(users).limit(1);
|
||||
let createdByUserId: string;
|
||||
|
||||
if (existingUsers.length > 0) {
|
||||
createdByUserId = existingUsers[0]!.id;
|
||||
console.log(`📋 Using existing user as creator: ${createdByUserId}`);
|
||||
} else {
|
||||
const testUserId = `user_${crypto.randomBytes(12).toString('hex')}`;
|
||||
|
||||
const testUserData = {
|
||||
id: testUserId,
|
||||
orgId: config.orgId,
|
||||
orgRole: 'admin',
|
||||
name: 'Test User',
|
||||
email: 'test@example.com',
|
||||
imageUrl: 'https://example.com/avatar.png',
|
||||
entity: {},
|
||||
};
|
||||
|
||||
console.log(`👤 Creating test user: ${testUserId}`);
|
||||
const [newUser] = await db.insert(users).values(testUserData).returning();
|
||||
createdByUserId = newUser!.id;
|
||||
}
|
||||
|
||||
const agentId = `agent_${crypto.randomBytes(12).toString('hex')}`;
|
||||
|
||||
const agentData = {
|
||||
id: agentId,
|
||||
orgId: config.orgId,
|
||||
displayName: config.agentName,
|
||||
description: 'Test agent created by script',
|
||||
createdByUserId: createdByUserId,
|
||||
};
|
||||
|
||||
const [newAgent] = await db.insert(agents).values(agentData).returning();
|
||||
|
||||
if (!newAgent) {
|
||||
throw new Error('Failed to create agent in database');
|
||||
}
|
||||
|
||||
console.log(`✅ Created agent: ${newAgent.id}`);
|
||||
return newAgent.id;
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to create agent:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function testEndpoint(token: string, baseUrl: string) {
|
||||
console.log('🌐 Testing endpoint...');
|
||||
|
||||
const url = `${baseUrl}/api/me`;
|
||||
console.log(`📡 Request URL: ${url}`);
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': 'TestScript/1.0',
|
||||
},
|
||||
});
|
||||
|
||||
console.log(
|
||||
`📡 Response status: ${response.status} ${response.statusText}`,
|
||||
);
|
||||
|
||||
console.log(
|
||||
`📡 Response content-type: ${response.headers.get('content-type')}`,
|
||||
);
|
||||
|
||||
const contentType = response.headers.get('content-type');
|
||||
const isJson = contentType && contentType.includes('application/json');
|
||||
|
||||
if (isJson) {
|
||||
const responseData = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
console.log('✅ Success! Response data:');
|
||||
console.log(JSON.stringify(responseData, null, 2));
|
||||
} else {
|
||||
console.log('❌ Error response:');
|
||||
console.log(JSON.stringify(responseData, null, 2));
|
||||
}
|
||||
} else {
|
||||
const responseText = await response.text();
|
||||
|
||||
if (response.status === 404) {
|
||||
console.log('❌ Endpoint not found (404)');
|
||||
console.log('💡 This might mean:');
|
||||
console.log(' - The server is not running');
|
||||
console.log(' - The endpoint does not exist');
|
||||
console.log(' - The API route is not implemented');
|
||||
console.log(
|
||||
`📄 Response preview: ${responseText.substring(0, 200)}...`,
|
||||
);
|
||||
} else {
|
||||
console.log(`❌ Non-JSON response (${response.status})`);
|
||||
console.log(`📄 Response: ${responseText.substring(0, 500)}...`);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to call endpoint:', error);
|
||||
|
||||
if (error instanceof Error && error.message.includes('ECONNREFUSED')) {
|
||||
console.log(
|
||||
'💡 Connection refused - is the server running on http://localhost:3000?',
|
||||
);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function cleanup(agentId: string): Promise<void> {
|
||||
console.log('🧹 Cleaning up test agent...');
|
||||
|
||||
try {
|
||||
await db.delete(agents).where(eq(agents.id, agentId));
|
||||
console.log('✅ Test agent cleaned up');
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to cleanup agent:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const config: TestConfig = {
|
||||
orgId: process.argv[2] || 'org_2wbhchVXZMQl8OS1yt0mrDazCpW',
|
||||
agentName: process.argv[3] || 'TestAgent',
|
||||
baseUrl: process.argv[4] || 'http://localhost:3000',
|
||||
};
|
||||
|
||||
console.log('🚀 Starting agent endpoint test...');
|
||||
console.log(` Org ID: ${config.orgId}`);
|
||||
console.log(` Agent Name: ${config.agentName}`);
|
||||
console.log(` Base URL: ${config.baseUrl}`);
|
||||
console.log('');
|
||||
|
||||
let agentId: string | null = null;
|
||||
|
||||
try {
|
||||
agentId = await createTestAgent(config);
|
||||
const token = await getAgentToken(agentId, config.orgId);
|
||||
await testEndpoint(token, config.baseUrl);
|
||||
|
||||
console.log('');
|
||||
console.log('🎉 Test completed successfully!');
|
||||
} catch (error) {
|
||||
console.error('');
|
||||
console.error('💥 Test failed:', error);
|
||||
process.exit(1);
|
||||
} finally {
|
||||
if (agentId) {
|
||||
await cleanup(agentId);
|
||||
}
|
||||
|
||||
await client.end();
|
||||
}
|
||||
}
|
||||
|
||||
// Print usage if help requested
|
||||
if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
||||
console.log(`
|
||||
Usage: tsx scripts/test-agent-endpoint.ts [orgId] [agentName] [baseUrl]
|
||||
|
||||
Arguments:
|
||||
orgId - Organization ID to test with (default: org_default_test)
|
||||
agentName - Name for the test agent (default: TestAgent)
|
||||
baseUrl - Base URL of the API (default: http://localhost:3000)
|
||||
|
||||
Examples:
|
||||
tsx scripts/test-agent-endpoint.ts
|
||||
tsx scripts/test-agent-endpoint.ts org_123 MyTestAgent http://localhost:3000
|
||||
tsx scripts/test-agent-endpoint.ts org_456 ProductionAgent https://api.example.com
|
||||
|
||||
Environment Variables Required:
|
||||
DATABASE_URL - PostgreSQL connection string
|
||||
CLERK_SECRET_KEY - Clerk secret key for JWT signing
|
||||
`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error('Unhandled error:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
{
|
||||
"$schema": "https://turbo.build/schema.json",
|
||||
"globalPassThroughEnv": [
|
||||
"DOTENV_PRIVATE_KEY_TEST",
|
||||
"DOTENV_PRIVATE_KEY_DEVELOPMENT",
|
||||
"DOTENV_PRIVATE_KEY_PREVIEW",
|
||||
"DOTENV_PRIVATE_KEY_PRODUCTION"
|
||||
],
|
||||
"tasks": {
|
||||
"lint": {},
|
||||
"check-types": {},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue