Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.git
.next
apps/*/.next
coverage
node_modules
Dockerfile
Expand All @@ -10,3 +11,4 @@ docker-compose.yml
*.log
*.tsbuildinfo
generated/prisma
apps/*/generated/prisma
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ pnpm-debug.log*
/prisma/dev.db
/prisma/dev.db-journal
/generated/prisma
/apps/web/generated/prisma

# typescript
*.tsbuildinfo
next-env.d.ts

# workspace package installs
node_modules/
21 changes: 15 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,23 @@ WORKDIR /app

FROM base AS deps
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY apps/web/package.json ./apps/web/package.json
COPY packages/cli/package.json ./packages/cli/package.json
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile

FROM base AS builder
ENV AUTH_SECRET="docker-build-placeholder"
ENV DATABASE_URL="postgresql://agentbridge:agentbridge@localhost:5432/agentbridge?schema=public"
COPY --from=deps /app/node_modules ./node_modules
COPY --from=deps /app/apps/web/node_modules ./apps/web/node_modules
COPY . .
RUN pnpm build
RUN pnpm prisma generate
RUN pnpm build:web

FROM base AS prod-deps
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY apps/web/package.json ./apps/web/package.json
COPY packages/cli/package.json ./packages/cli/package.json
RUN --mount=type=cache,id=pnpm-prod,target=/pnpm/store pnpm install --frozen-lockfile --prod

FROM base AS runner
Expand All @@ -32,11 +38,14 @@ RUN addgroup --system --gid 1001 nodejs \
&& adduser --system --uid 1001 nextjs

COPY --from=prod-deps --chown=nextjs:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/generated ./generated
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next ./apps/web/.next
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/generated ./apps/web/generated
COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma
COPY --from=builder --chown=nextjs:nodejs /app/package.json ./package.json
COPY --from=builder --chown=nextjs:nodejs /app/pnpm-workspace.yaml ./pnpm-workspace.yaml
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/package.json ./apps/web/package.json
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/next.config.mjs ./apps/web/next.config.mjs
COPY --from=builder --chown=nextjs:nodejs /app/prisma.config.ts ./prisma.config.ts
COPY --from=builder --chown=nextjs:nodejs /app/docker-entrypoint.sh ./docker-entrypoint.sh

Expand All @@ -47,4 +56,4 @@ USER nextjs
EXPOSE 3000

ENTRYPOINT ["./docker-entrypoint.sh"]
CMD ["node", "server.js"]
CMD ["pnpm", "--filter", "@agentbridge/web", "start", "--", "-H", "0.0.0.0"]
22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ Another fun detail: **Kaito is currently the most frequent code pusher in this r

## Preview

![AgentBridge project dashboard preview](public/readme/agentbridge-preview-1.jpg)
![AgentBridge project dashboard preview](apps/web/public/readme/agentbridge-preview-1.jpg)

![AgentBridge task board preview](public/readme/agentbridge-preview-2.jpg)
![AgentBridge task board preview](apps/web/public/readme/agentbridge-preview-2.jpg)

![AgentBridge agent coordination preview](public/readme/agentbridge-preview-3.jpg)
![AgentBridge agent coordination preview](apps/web/public/readme/agentbridge-preview-3.jpg)

## Current capabilities

Expand Down Expand Up @@ -180,7 +180,7 @@ You can generate a new company bearer token later from dashboard company setting

## OpenClaw setup with the CLI

The repository includes a publish-ready `cli/` workspace package for setting up AgentBridge in OpenClaw workspaces.
The repository includes a publish-ready `packages/cli/` workspace package for setting up AgentBridge in OpenClaw workspaces.

After the CLI is published to npm, the intended install-free usage is:

Expand Down Expand Up @@ -311,6 +311,15 @@ Useful Agent API resources:
- The current implementation exposes dashboard read-review state through task read marker fields documented in `/api/openapi` and `agent-skill/SKILL.md`.
- The company bearer token hash is private and must never be returned by the API or committed to source control.

## Repository layout

AgentBridge is organized as a pnpm workspace:

- `apps/web/` contains the Next.js dashboard and API routes.
- `packages/cli/` contains the publishable `agentbridge` CLI package.
- `prisma/` and Prisma scripts stay at the repository root; Prisma client output is generated into `apps/web/generated/prisma`.
- Root `package.json` scripts orchestrate workspace commands with pnpm filters.

## Development commands

Run these from the repository root:
Expand All @@ -329,8 +338,11 @@ corepack pnpm prisma:generate
corepack pnpm prisma:migrate
corepack pnpm prisma:studio
corepack pnpm format
corepack pnpm build:web
corepack pnpm cli:dev -- init --every 1h
corepack pnpm cli:typecheck
corepack pnpm cli:build
corepack pnpm cli:pack
```

For contribution conventions, branch expectations, and QA checklist, see [CONTRIBUTING.md](CONTRIBUTING.md).
Expand Down Expand Up @@ -366,7 +378,7 @@ For production-like environments:
1. Provide a managed PostgreSQL `DATABASE_URL`.
2. Set a strong `AUTH_SECRET`.
3. Run migrations with `prisma migrate deploy` as part of release startup or deployment automation.
4. Generate Prisma client code before building, or use the existing `build` script.
4. Generate Prisma client code before building, or use the existing root `build`/`build:web` scripts.
5. Seed or create the first operator account through an approved operational process.
6. Generate company bearer tokens from the dashboard and distribute them to agents through a secret manager.
7. Monitor `GET /api/health` after deploys. Treat HTTP `200` as ready and HTTP `503` as the app running but not ready because database connectivity failed.
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ export async function PATCH(request: NextRequest, { params }: RouteContext) {
data.summaryUpdatedAt = data.note ? new Date() : null
}
const shouldClearNextStatusReads = !hasReadBy && (statusChanged || noteChanged)
const updatedTask = await prisma.$transaction(async (tx) => {
const updatedTask = await prisma.$transaction(async (tx: typeof prisma) => {
if (hasReadBy) {
await tx.taskReadMarker.deleteMany({
where: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ export async function POST(request: NextRequest) {
)
}

const task = await prisma.$transaction(async (tx) => {
const task = await prisma.$transaction(async (tx: typeof prisma) => {
await tx.projectAgent.createMany({
data: [{ projectId: project.id, agentId: assignedAgentId }],
skipDuplicates: true,
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export async function PUT(request: Request, { params }: RouteContext) {
.filter((agent) => !previousAgentIds.has(agent.id))
.map((agent) => agent.name)

const projectAgents = await prisma.$transaction(async (tx) => {
const projectAgents = await prisma.$transaction(async (tx: typeof prisma) => {
await tx.projectAgent.deleteMany({
where: {
projectId: project.id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ export async function PATCH(request: Request, { params }: RouteContext) {
const statusChanged = nextStatus !== task.status
const noteChanged = note !== undefined && (note || null) !== task.note
const shouldClearNextStatusReads = !hasReadByAgentIds && (statusChanged || noteChanged)
const updatedTask = await prisma.$transaction(async (tx) => {
const updatedTask = await prisma.$transaction(async (tx: typeof prisma) => {
if (hasReadByAgentIds) {
await tx.taskReadMarker.deleteMany({
where: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ const openApiDocument = swaggerJsdoc({
},
security: [{ bearerAuth: [] }],
},
apis: ["./app/api/agent/**/*.ts", "./app/api/agent/route.ts"],
apis: ["./apps/web/app/api/agent/**/*.ts", "./apps/web/app/api/agent/route.ts"],
})

export function GET() {
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
"use client"

import * as React from "react"
import { ThemeProvider as NextThemesProvider, useTheme } from "next-themes"
import {
ThemeProvider as NextThemesProvider,
type ThemeProviderProps,
useTheme,
} from "next-themes"

function ThemeProvider({
children,
...props
}: React.ComponentProps<typeof NextThemesProvider>) {
function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return (
<NextThemesProvider
attribute="class"
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 3 additions & 1 deletion lib/prisma.ts → apps/web/lib/prisma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ if (!connectionString) {
throw new Error("DATABASE_URL is not set")
}

type AgentBridgePrismaClient = InstanceType<typeof PrismaClient>

const globalForPrisma = globalThis as unknown as {
prisma?: PrismaClient
prisma?: AgentBridgePrismaClient
}

const adapter = new PrismaPg({ connectionString })
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
49 changes: 49 additions & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "@agentbridge/web",
"version": "0.0.1",
"type": "module",
"private": true,
"scripts": {
"dev": "next dev --turbopack",
"build": "next build --webpack",
"start": "next start",
"lint": "eslint",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@prisma/adapter-pg": "^7.8.0",
"@prisma/client": "^7.8.0",
"@tanstack/react-query": "^5.100.9",
"bcryptjs": "^3.0.3",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"dotenv": "^17.4.2",
"jose": "^6.2.3",
"lucide-react": "^1.14.0",
"next": "16.1.7",
"next-themes": "^0.4.6",
"pg": "^8.20.0",
"radix-ui": "^1.4.3",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"shadcn": "^4.7.0",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-dist": "^5.32.5",
"tailwind-merge": "^3.5.0",
"tw-animate-css": "^1.4.0"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
"@tailwindcss/postcss": "^4.2.1",
"@types/node": "^25.5.0",
"@types/pg": "^8.20.0",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@types/swagger-jsdoc": "^6.0.4",
"eslint": "^9.39.4",
"eslint-config-next": "16.1.7",
"postcss": "^8",
"tailwindcss": "^4.2.1",
"typescript": "^5.9.3"
}
}
File renamed without changes.
File renamed without changes.
44 changes: 44 additions & 0 deletions apps/web/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"compilerOptions": {
"target": "ES2017",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"strictFunctionTypes": false,
"noImplicitAny": false,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"baseUrl": ".",
"paths": {
"@/*": [
"./*"
]
}
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
".next/dev/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}
51 changes: 14 additions & 37 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,60 +1,37 @@
{
"name": "AgentBridge",
"name": "agentbridge-monorepo",
"version": "0.0.1",
"type": "module",
"private": true,
"scripts": {
"dev": "next dev --turbopack",
"build": "prisma generate && next build",
"start": "next start",
"lint": "eslint",
"dev": "corepack pnpm --filter @agentbridge/web dev",
"build": "corepack pnpm prisma:generate && corepack pnpm --filter @agentbridge/web build && corepack pnpm --filter agentbridge build",
"build:web": "corepack pnpm prisma:generate && corepack pnpm --filter @agentbridge/web build",
"start": "corepack pnpm --filter @agentbridge/web start",
"lint": "corepack pnpm --filter @agentbridge/web lint",
"lint:web": "corepack pnpm --filter @agentbridge/web lint",
"format": "prettier --write \"**/*.{ts,tsx}\"",
"prisma:generate": "prisma generate",
"prisma:migrate": "prisma migrate dev",
"prisma:seed": "tsx scripts/seed-admin.ts",
"prisma:studio": "prisma studio",
"pretypecheck": "prisma generate",
"typecheck": "tsc --noEmit",
"typecheck": "corepack pnpm prisma:generate && corepack pnpm --filter @agentbridge/web typecheck && corepack pnpm --filter agentbridge typecheck",
"typecheck:web": "corepack pnpm prisma:generate && corepack pnpm --filter @agentbridge/web typecheck",
"cli:dev": "corepack pnpm --filter agentbridge dev",
"cli:build": "corepack pnpm --filter agentbridge build",
"cli:typecheck": "corepack pnpm --filter agentbridge typecheck",
"cli:pack": "corepack pnpm --filter agentbridge pack:dry-run"
},
"dependencies": {
"devDependencies": {
"@prisma/adapter-pg": "^7.8.0",
"@prisma/client": "^7.8.0",
"@tanstack/react-query": "^5.100.9",
"@types/node": "^25.5.0",
"@types/pg": "^8.20.0",
"bcryptjs": "^3.0.3",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"dotenv": "^17.4.2",
"jose": "^6.2.3",
"lucide-react": "^1.14.0",
"next": "16.1.7",
"next-themes": "^0.4.6",
"pg": "^8.20.0",
"prisma": "^7.8.0",
"radix-ui": "^1.4.3",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"shadcn": "^4.7.0",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-dist": "^5.32.5",
"tailwind-merge": "^3.5.0",
"tw-animate-css": "^1.4.0"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
"@tailwindcss/postcss": "^4.2.1",
"@types/node": "^25.5.0",
"@types/pg": "^8.20.0",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@types/swagger-jsdoc": "^6.0.4",
"eslint": "^9.39.4",
"eslint-config-next": "16.1.7",
"postcss": "^8",
"prettier": "^3.8.1",
"prettier-plugin-tailwindcss": "^0.7.2",
"prisma": "^7.8.0",
"tailwindcss": "^4.2.1",
"tsx": "^4.21.0",
"typescript": "^5.9.3"
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion cli/README.md → packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Before publish, test the built package locally:

```bash
corepack pnpm --filter agentbridge build
node cli/dist/index.js openclaw status --workspace ~/.openclaw
node packages/cli/dist/index.js openclaw status --workspace ~/.openclaw
```

## Project init vs agent setup
Expand Down
2 changes: 1 addition & 1 deletion cli/package.json → packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"repository": {
"type": "git",
"url": "git+https://github.com/Vann-Dev/AgentBridge.git",
"directory": "cli"
"directory": "packages/cli"
},
"bugs": {
"url": "https://github.com/Vann-Dev/AgentBridge/issues"
Expand Down
File renamed without changes.
Loading
Loading