Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,10 @@ logs/
Thumbs.db
.DS_Store

# Web dashboard build artifacts
web/node_modules/
web/dist/
web/.env

# uv
.python-version
113 changes: 110 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,107 @@ jobs:
name: test-results-${{ matrix.python-version }}
path: junit.xml

dashboard-lint:
name: Dashboard Lint
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 22
cache: npm
cache-dependency-path: web/package-lock.json
- run: npm ci
working-directory: web
- run: npm run lint
working-directory: web

dashboard-type-check:
name: Dashboard Type Check
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 22
cache: npm
cache-dependency-path: web/package-lock.json
- run: npm ci
working-directory: web
- run: npm run type-check
working-directory: web

dashboard-test:
name: Dashboard Test
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 22
cache: npm
cache-dependency-path: web/package-lock.json
- run: npm ci
working-directory: web
- run: npm run test -- --coverage
working-directory: web

dashboard-build:
name: Dashboard Build
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 22
cache: npm
cache-dependency-path: web/package-lock.json
- run: npm ci
working-directory: web
- name: Production build
run: npm run build
working-directory: web

dashboard-audit:
name: Dashboard Security Audit
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 22
cache: npm
cache-dependency-path: web/package-lock.json
- run: npm ci
working-directory: web
- name: npm audit (critical + high)
run: npm audit --audit-level=high
working-directory: web

ci-pass:
name: CI Pass
if: always()
needs: [lint, type-check, test]
needs: [lint, type-check, test, dashboard-lint, dashboard-type-check, dashboard-test, dashboard-build, dashboard-audit]
runs-on: ubuntu-latest
permissions: {}
steps:
Expand All @@ -111,11 +208,21 @@ jobs:
LINT_RESULT: ${{ needs.lint.result }}
TYPE_CHECK_RESULT: ${{ needs.type-check.result }}
TEST_RESULT: ${{ needs.test.result }}
DASHBOARD_LINT_RESULT: ${{ needs.dashboard-lint.result }}
DASHBOARD_TYPE_CHECK_RESULT: ${{ needs.dashboard-type-check.result }}
DASHBOARD_TEST_RESULT: ${{ needs.dashboard-test.result }}
DASHBOARD_BUILD_RESULT: ${{ needs.dashboard-build.result }}
DASHBOARD_AUDIT_RESULT: ${{ needs.dashboard-audit.result }}
run: |
if [[ "$LINT_RESULT" != "success" || \
"$TYPE_CHECK_RESULT" != "success" || \
"$TEST_RESULT" != "success" ]]; then
echo "CI failed: lint=$LINT_RESULT, type-check=$TYPE_CHECK_RESULT, test=$TEST_RESULT"
"$TEST_RESULT" != "success" || \
"$DASHBOARD_LINT_RESULT" != "success" || \
"$DASHBOARD_TYPE_CHECK_RESULT" != "success" || \
"$DASHBOARD_TEST_RESULT" != "success" || \
"$DASHBOARD_BUILD_RESULT" != "success" || \
"$DASHBOARD_AUDIT_RESULT" != "success" ]]; then
echo "CI failed: lint=$LINT_RESULT, type-check=$TYPE_CHECK_RESULT, test=$TEST_RESULT, dashboard-lint=$DASHBOARD_LINT_RESULT, dashboard-type-check=$DASHBOARD_TYPE_CHECK_RESULT, dashboard-test=$DASHBOARD_TEST_RESULT, dashboard-build=$DASHBOARD_BUILD_RESULT, dashboard-audit=$DASHBOARD_AUDIT_RESULT"
exit 1
fi
echo "All CI checks passed"
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ htmlcov/
coverage.xml
.coverage
.coverage.*
web/coverage/

# Environment variables
.env
Expand All @@ -49,6 +50,11 @@ Thumbs.db
# Web UI
web/node_modules/
web/dist/
*.tsbuildinfo
web/vite.config.d.ts
web/vite.config.js
web/vitest.config.d.ts
web/vitest.config.js
Comment on lines +53 to +57
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

These lines ignore generated JavaScript and TypeScript declaration files for your Vite and Vitest configurations. While this is likely correct because you've written the configurations in TypeScript (.ts), it's an uncommon setup that might confuse new contributors. Consider adding a comment to clarify that these are build artifacts and are intentionally ignored.


# Documentation build output (Zensical)
_site/
Expand Down
28 changes: 26 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
- **What**: Framework for building synthetic organizations — autonomous AI agents orchestrated as a virtual company
- **Python**: 3.14+ (PEP 649 native lazy annotations)
- **License**: BUSL-1.1 (converts to Apache 2.0 on 2030-02-27)
- **Layout**: `src/ai_company/` (src layout), `tests/` (unit/integration/e2e)
- **Layout**: `src/ai_company/` (src layout), `tests/` (unit/integration/e2e), `web/` (Vue 3 dashboard)
- **Design**: [DESIGN_SPEC.md](DESIGN_SPEC.md) (pointer to `docs/design/` pages)

## Design Spec (MANDATORY)
Expand Down Expand Up @@ -43,6 +43,17 @@ uv run zensical build # build docs (output: _site/docs/)
uv run zensical serve # local docs preview (http://127.0.0.1:8000)
```

### Web Dashboard

```bash
npm --prefix web install # install frontend deps
npm --prefix web run dev # dev server (http://localhost:5173)
npm --prefix web run build # production build
npm --prefix web run lint # ESLint
npm --prefix web run type-check # vue-tsc type checking
npm --prefix web run test # Vitest unit tests
```

## Documentation

- **Docs source**: `docs/` (Markdown, built with Zensical)
Expand Down Expand Up @@ -75,7 +86,7 @@ curl http://localhost:3000/api/v1/health # backend (via web proxy)
```

- **Backend**: 3-stage build (builder → setup → distroless runtime), Chainguard Python, non-root (UID 65532), CIS-hardened
- **Web**: `nginxinc/nginx-unprivileged`, SPA routing, API/WebSocket proxy to backend
- **Web**: `nginxinc/nginx-unprivileged`, Vue 3 SPA (PrimeVue + Tailwind CSS), SPA routing, API/WebSocket proxy to backend
- **Config**: all Docker files in `docker/` — Dockerfiles, compose, `.env.example`
- **CI**: `.github/workflows/docker.yml` — build → scan → push to GHCR + cosign sign (images only pushed after Trivy/Grype scans pass)
- **Build context**: single root `.dockerignore` (both images build with `context: .`)
Expand All @@ -101,6 +112,18 @@ src/ai_company/
security/ # SecOps agent, rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, output scan response policies (redact/withhold/log-only/autonomy-tiered), risk classifier, risk tier classifier, action type registry, ToolInvoker security integration, progressive trust (4 strategies: disabled/weighted/per-category/milestone), autonomy levels (presets, resolver, change strategy), timeout policies (park/resume)
templates/ # Pre-built company templates, personality presets, and builder
tools/ # Tool registry, built-in tools (file_system/, git, sandbox/, code_runner), MCP bridge (mcp/), role-based access

web/ # Vue 3 + PrimeVue + Tailwind CSS dashboard
src/
api/ # Axios client, endpoint modules, TypeScript types (mirrors backend Pydantic models)
components/ # Vue components organized by feature (agents/, approvals/, budget/, common/, dashboard/, layout/, messages/, org-chart/, tasks/)
composables/ # Reusable composition functions (useAuth, usePolling, useOptimisticUpdate)
router/ # Vue Router config with auth guards
stores/ # Pinia stores (auth, agents, tasks, budget, messages, approvals, websocket, analytics, company, providers)
styles/ # Global CSS and PrimeVue theme configuration
utils/ # Constants, formatters, error helpers
views/ # Page-level components (LoginPage, SetupPage, PlaceholderHome; feature pages in PR 2)
__tests__/ # Vitest unit tests (organized by feature)
```

## Shell Usage
Expand Down Expand Up @@ -207,3 +230,4 @@ src/ai_company/
- **Groups**: `test` (pytest + plugins), `dev` (includes test + ruff, mypy, pre-commit, commitizen)
- **Required**: `mem0ai` (Mem0 memory backend — the default and currently only backend)
- **Install**: `uv sync` installs everything (dev group is default)
- **Web dashboard**: Node.js 20+, dependencies in `web/package.json` (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, ESLint, vue-tsc)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ graph TB

## Status

Core framework complete — agent engine, multi-agent coordination, API, security, HR, memory (including Mem0 backend adapter), and budget systems are implemented. Remaining: approval workflow gates, CLI, web dashboard. See the [roadmap](docs/roadmap/index.md) for details.
Core framework complete — agent engine, multi-agent coordination, API, security, HR, memory (including Mem0 backend adapter), and budget systems are implemented. Web dashboard (Vue 3 + PrimeVue + Tailwind CSS) is built. Remaining: approval workflow gates, CLI. See the [roadmap](docs/roadmap/index.md) for details.

## License

Expand Down
18 changes: 16 additions & 2 deletions docker/web/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
# syntax=docker/dockerfile:1

# =============================================================================
# SynthOrg Web — Non-root nginx container (CIS hardening applied via compose.yml)
# SynthOrg Web — Multi-stage build: Node builder → nginx runtime
# CIS hardening applied via compose.yml (no-new-privileges, drop caps, etc.)
# =============================================================================

# Stage 1: Build Vue dashboard (non-root for defense-in-depth)
FROM node:22-alpine@sha256:3a4802e64ab5181c7870d6ddd8c824c2efc42873baae37d1971451668659483b AS builder
RUN addgroup -S build && adduser -S build -G build
WORKDIR /app
COPY --chown=build:build web/package.json web/package-lock.json ./
# Run npm ci as build user so node_modules (including .vite cache) is owned by
# the same user that runs the build — avoids permission errors in Vite.
USER build
RUN npm ci
COPY --chown=build:build web/ ./
RUN npm run build

# Stage 2: Serve with nginx
FROM nginxinc/nginx-unprivileged:1.29.5-alpine@sha256:aec540f08f99df3c830549d5dd7bfaf63e01cbbb499e37400c5af9f8e8554e9f

LABEL org.opencontainers.image.title="synthorg-web" \
Expand All @@ -14,7 +28,7 @@ LABEL org.opencontainers.image.title="synthorg-web" \
org.opencontainers.image.vendor="Aureliolo"

COPY web/nginx.conf /etc/nginx/conf.d/default.conf
COPY web/index.html web/style.css web/app.js /usr/share/nginx/html/
COPY --from=builder /app/dist/ /usr/share/nginx/html/

EXPOSE 8080

Expand Down
9 changes: 5 additions & 4 deletions docs/design/operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -933,7 +933,7 @@ future CLI tool are thin clients that call the API -- they contain no business l
| |
+-------v--+ +---v--------+
| Web UI | | CLI Tool |
| (Future) | | (Future) |
| (Vue 3) | | (Future) |
+----------+ +-----------+
```

Expand Down Expand Up @@ -966,10 +966,11 @@ future CLI tool are thin clients that call the API -- they contain no business l

### Web UI Features

!!! warning "Planned"
!!! info "In Progress"

The Web UI is a planned future component (Vue 3). The API is fully self-sufficient for
all operations.
The Web UI is being built as a Vue 3 + PrimeVue + Tailwind CSS dashboard (core
infrastructure merged; page views and feature components in progress). The API
remains fully self-sufficient for all operations — the dashboard is a thin client.

- **Dashboard**: Real-time company overview, active tasks, spending
- **Org Chart**: Visual hierarchy, click to inspect any agent
Expand Down
15 changes: 14 additions & 1 deletion docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,26 @@ synthorg/
e2e/ # Full system tests
docs/ # Developer documentation
docker/ # Dockerfiles, Compose, .env.example
web/ # Web UI scaffold (nginx + placeholder)
web/ # Vue 3 web dashboard (PrimeVue + Tailwind CSS)
.github/ # CI workflows, dependabot, actions
pyproject.toml # Project config (deps, tools, linters)
DESIGN_SPEC.md # Pointer to design specification pages
CLAUDE.md # AI assistant quick reference
```

## Web Dashboard Development

The Vue 3 dashboard lives in `web/`. Prerequisites: **Node.js 20+**.

```bash
npm --prefix web install # install frontend deps
npm --prefix web run dev # dev server at http://localhost:5173
npm --prefix web run lint # ESLint
npm --prefix web run type-check # vue-tsc type checking
npm --prefix web run test # Vitest unit tests
npm --prefix web run build # production build
```

## IDE Setup

### VS Code / Cursor
Expand Down
7 changes: 6 additions & 1 deletion docs/roadmap/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@ The SynthOrg core framework is complete. The following subsystems are built and
- Configuration (YAML loading, Pydantic validation, company templates with inheritance)
- Container packaging (Docker, Chainguard distroless, CI/CD pipelines)

## In Progress

| Area | Description |
|------|-------------|
| **Web dashboard** | Vue 3 + PrimeVue + Tailwind CSS frontend for monitoring and managing the synthetic organization (core infrastructure merged, page views pending) |

## Remaining Work

| Area | Description |
|------|-------------|
| **Approval workflow gates** | Runtime wiring for human-in-the-loop approval queues |
| **CLI** | Terminal interface wrapping the REST API (may not be needed) |
| **Web dashboard** | Vue 3 frontend for monitoring and managing the synthetic organization |

## Tracking

Expand Down
6 changes: 3 additions & 3 deletions docs/user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ docker compose -f docker/compose.yml up -d

The web dashboard is at [http://localhost:3000](http://localhost:3000).

Container configuration (ports, storage paths, log level) is defined in `docker/.env`. Organization setup and templates will be configurable through the dashboard once available.
Container configuration (ports, storage paths, log level) is defined in `docker/.env`. Organization setup is done via the dashboard. Custom template editing through the UI is planned for a future release.

!!! danger "Work in Progress"
SynthOrg is under active development. The web dashboard, templates, and many features described here are **not yet available**. Check the [GitHub repository](https://github.com/Aureliolo/synthorg) for current status.
!!! info "Active Development"
SynthOrg is under active development. The web dashboard is available for monitoring and managing the organization. Templates and some features described here may evolve. Check the [GitHub repository](https://github.com/Aureliolo/synthorg) for current status.

## Templates

Expand Down
2 changes: 2 additions & 0 deletions web/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# API base URL — empty for production (relative paths), set for dev if not using Vite proxy
VITE_API_BASE_URL=
29 changes: 0 additions & 29 deletions web/app.js

This file was deleted.

Loading
Loading