Commit Graph

11 Commits

Author SHA1 Message Date
Hongming Wang
50decfd326 chore(compose): wire MOLECULE_ENV, GHCR_USER/TOKEN, MOLECULE_IMAGE_PLATFORM
Three env vars the platform now reads:

- MOLECULE_ENV=development (default) — activates the WorkspaceAuth /
  AdminAuth dev fail-open path so the canvas's bearer-less requests pass
  through. Also unlocks RFC-1918 relaxation in the SSRF guard so docker-
  bridge IPs work. Override to 'production' for staged deploys.

- GHCR_USER + GHCR_TOKEN — feed POST /admin/workspace-images/refresh's
  ImagePull auth payload. Both empty → endpoint can pull cached/public
  images only. Set with a fine-grained PAT (read:packages on Molecule-AI
  org) to pull private GHCR images.

- MOLECULE_IMAGE_PLATFORM=linux/amd64 (default) — workspace-template-*
  images ship single-arch amd64. On Apple Silicon hosts, the daemon's
  native linux/arm64/v8 request misses the manifest and pulls fail.
  Forcing amd64 makes Docker Desktop run them under Rosetta — slower
  (~2-3×) but functional.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-26 10:14:47 -07:00
Hongming Wang
9ad803a802
fix(quickstart): make README cp-paste flow bugless end-to-end (#1871)
Reproducing the README's quickstart on a clean clone surfaced seven
independent bugs between `git clone` and seeing the Canvas in a browser.
Each fix is minimal and local-dev-only — the SaaS/EC2 provisioner path
(issue #1822) is untouched.

Bugs fixed:

1. `infra/scripts/setup.sh` applied migrations via raw psql, bypassing
   the platform's `schema_migrations` tracker. The platform then re-ran
   every migration on first boot and crashed on non-idempotent ALTER
   TABLE statements (e.g. `036_org_api_tokens_org_id.up.sql`). Dropped
   the migration block — `workspace-server/internal/db/postgres.go:53`
   already tracks and skips applied files.

2. `.env.example` shipped `DATABASE_URL=postgres://USER:PASS@postgres:...`
   with literal `USER:PASS` placeholders and the Docker-internal hostname
   `postgres`. A `cp .env.example .env` followed by `go run ./cmd/server`
   on the host failed with `dial tcp: lookup postgres: no such host`.
   Replaced with working `dev:dev@localhost:5432` defaults that match
   `docker-compose.infra.yml`.

3. `docker-compose.infra.yml` and `docker-compose.yml` set
   `CLICKHOUSE_URL: clickhouse://...:9000/...`. Langfuse v2 rejects
   anything other than `http://` or `https://`, so the container
   crash-looped and returned HTTP 500. Switched to
   `http://...:8123` (HTTP interface) and added `CLICKHOUSE_MIGRATION_URL`
   for the migration-time native-protocol connection. Also removed
   `LANGFUSE_AUTO_CLICKHOUSE_MIGRATION_DISABLED` so migrations actually
   run.

4. `canvas/package.json` dev script crashed with `EADDRINUSE :::8080`
   when `.env` was sourced before `npm run dev` — Next.js reads `PORT`
   from env and the platform owns 8080. Pinned `dev` to
   `-p 3000` so sourced env can't hijack it. `start` left as-is because
   production `node server.js` (Dockerfile CMD) must respect `PORT`
   from the orchestrator.

5. README/CONTRIBUTING told users to clone `Molecule-AI/molecule-monorepo`
   — that repo 404s; the actual name is `molecule-core`. The Railway
   and Render deploy buttons had the same broken URL. Replaced in both
   English and Chinese READMEs and in CONTRIBUTING. Internal identifiers
   (Go module path, Docker network `molecule-monorepo-net`, Python helper
   `molecule-monorepo-status`) deliberately left alone — renaming those
   is an invasive refactor orthogonal to this fix.

6. README quickstart was missing `cp .env.example .env`. Users who went
   straight from `git clone` to `./infra/scripts/setup.sh` got a script
   that warned about an unset `ADMIN_TOKEN` (harmless) but then couldn't
   run the platform without figuring out the env setup on their own.
   Added the step in both READMEs and CONTRIBUTING. Deliberately NOT
   generating `ADMIN_TOKEN`/`SECRETS_ENCRYPTION_KEY` here — the e2e-api
   suite (`tests/e2e/test_api.sh`) assumes AdminAuth fallback mode
   (no server-side `ADMIN_TOKEN`), which is how CI runs it.

7. CI shellcheck only covered `tests/e2e/*.sh` — `infra/scripts/setup.sh`
   is in the critical path of every new-user onboarding but was never
   linted. Extended the `shellcheck` job and the `changes` filter to
   cover `infra/scripts/`. `scripts/` deliberately excluded until its
   pre-existing SC3040/SC3043 warnings are cleaned up separately.

Verification (fresh nuke-and-rebuild following the updated README):

- `docker compose -f docker-compose.infra.yml down -v` + `rm .env`
- `cp .env.example .env` → defaults work as-is
- `bash infra/scripts/setup.sh` — clean, no migration errors, all 6
  infra containers healthy
- `cd workspace-server && go run ./cmd/server` — "Applied 41 migrations
  (0 already applied)", platform on :8080/health 200
- `cd canvas && npm install && npm run dev` — Canvas on :3000/ 200
  even with `.env` sourced (PORT=8080 in env)
- `bash tests/e2e/test_api.sh` — **61 passed, 0 failed**
- `cd canvas && npx vitest run` — **900 tests passed**
- `cd canvas && npm run build` — production build clean
- `shellcheck --severity=warning infra/scripts/*.sh` — clean
- Langfuse `/api/public/health` 200 (was 500)

Scope notes:

- SaaS/EC2 parity (issue #1822): all files touched here are local-dev
  surface. Canvas container uses `node server.js` with `ENV PORT=3000`
  in `canvas/Dockerfile` — the `-p 3000` pin in `package.json` dev
  script only affects `npm run dev`, not the production CMD.
- Test coverage (issue #1821): project policy is tiered coverage floors,
  not a blanket 100% target. Files touched here are shell scripts,
  YAML, Markdown, and one package.json script — not classes covered
  by the coverage matrix.
- No overlap with open PRs — searched `setup.sh`, `quickstart`,
  `langfuse`, `clickhouse`, `migration`, `README`; nothing conflicts.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: molecule-ai[bot] <276602405+molecule-ai[bot]@users.noreply.github.com>
2026-04-23 19:53:43 +00:00
rabbitblood
b0ea25cc36 fix(canvas): add NEXT_PUBLIC_ADMIN_TOKEN + CSP_DEV_MODE to docker-compose
Canvas needs AdminAuth token to fetch /workspaces (gated since PR #729)
and CSP_DEV_MODE to allow cross-port fetches in local Docker.

These were added earlier but lost on nuke+rebuild because they weren't
committed to staging.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 12:19:12 -07:00
Hongming Wang
dd878b819b fix: remaining platform/ path references in scripts, tests, compose
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 00:32:03 -07:00
Hongming Wang
479a027e4b chore: open-source restructure — rename dirs, remove internal files, scrub secrets
Renames:
- platform/ → workspace-server/ (Go module path stays as "platform" for
  external dep compat — will update after plugin module republish)
- workspace-template/ → workspace/

Removed (moved to separate repos or deleted):
- PLAN.md — internal roadmap (move to private project board)
- HANDOFF.md, AGENTS.md — one-time internal session docs
- .claude/ — gitignored entirely (local agent config)
- infra/cloudflare-worker/ → Molecule-AI/molecule-tenant-proxy
- org-templates/molecule-dev/ → standalone template repo
- .mcp-eval/ → molecule-mcp-server repo
- test-results/ — ephemeral, gitignored

Security scrubbing:
- Cloudflare account/zone/KV IDs → placeholders
- Real EC2 IPs → <EC2_IP> in all docs
- CF token prefix, Neon project ID, Fly app names → redacted
- Langfuse dev credentials → parameterized
- Personal runner username/machine name → generic

Community files:
- CONTRIBUTING.md — build, test, branch conventions
- CODE_OF_CONDUCT.md — Contributor Covenant 2.1

All Dockerfiles, CI workflows, docker-compose, railway.toml, render.yaml,
README, CLAUDE.md updated for new directory names.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 00:24:44 -07:00
246b963d5d docs(env): audit .env.example completeness after platform sprint (issue #782)
Adds two missing env vars to .env.example + docker-compose.yml platform block:

1. HIBERNATION_IDLE_MINUTES (default 60)
   Source: issue #724 / workspace hibernation feature.
   Note: currently configured per-workspace via the hibernation_idle_minutes
   DB column. This placeholder documents the planned global-default env var;
   the platform does not yet read it. Per-workspace DB column is active now.

2. PLUGIN_ALLOW_UNPINNED (empty = false)
   Source: issue #768 / PR #775 (supply chain hardening, not yet merged).
   Pre-emptive documentation — takes effect when PR #775 lands.

ADMIN_TOKEN (item 3): already present with clear generation instructions
(openssl rand -base64 32) and NEVER-commit reminder. No changes needed.

docker-compose.yml cross-check — vars present in .env.example but absent from
the platform service env block (flagged, not fixed in this PR — all have safe
compiled-in defaults and are optional):
  SECRETS_ENCRYPTION_KEY, AWARENESS_URL, MOLECULE_ENV, MOLECULE_IN_DOCKER,
  MOLECULE_ENABLE_TEST_TOKENS, MOLECULE_ORG_ID, CP_PROVISION_URL,
  ACTIVITY_RETENTION_DAYS, ACTIVITY_CLEANUP_INTERVAL_HOURS,
  REMOTE_LIVENESS_STALE_AFTER, PLUGIN_INSTALL_{BODY_MAX_BYTES,FETCH_TIMEOUT,
  MAX_DIR_BYTES}, TIER{2,3,4}_{MEMORY_MB,CPU_SHARES}, WORKSPACE_DIR.
These are not forwarded by docker-compose because they either auto-detect or
have safe defaults — operators override them via .env on the host. Adding
all of them to docker-compose would be noisy; a separate cleanup issue tracks
this.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 16:55:55 +00:00
aa38fc55ed fix(infra): wire ADMIN_TOKEN env placeholder to close issue #684 (PR #729)
Backend Engineer's PR #729 introduces ADMIN_TOKEN — when set, only that value
is accepted on /admin/* and /approvals/* routes, replacing the vulnerable
workspace-bearer fallback. Without the env var wired into deployments the fix
is code-only and the vulnerability stays open in every running instance.

Changes:
- `docker-compose.yml`: adds ADMIN_TOKEN env var to the platform service
  (blank default = backward-compat fallback, i.e. still vulnerable until set).
  NOTE: docker-compose.infra.yml has no platform service — the platform lives
  only in the full-stack docker-compose.yml, so that is the correct file.
- `.env.example`: documents ADMIN_TOKEN with generation instructions and a
  clear warning that it must be set to close #684.
- `infra/scripts/setup.sh`: prints a visible warning when ADMIN_TOKEN is unset
  so operators know the vulnerability is still open in that deployment.
- `CLAUDE.md`: adds ADMIN_TOKEN to the env vars reference section.

No Go code changed — go build ./... passes clean.

Part of fix for #684 / PR #729

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 15:21:35 +00:00
rabbitblood
3609b7ab8c feat(platform): wire github-app-auth plugin for per-installation tokens
Integrates github.com/Molecule-AI/molecule-ai-plugin-github-app-auth.
When GITHUB_APP_ID is set, the platform constructs a plugin
Authenticator at boot and registers it as an EnvMutator on the
WorkspaceHandler. Every workspace provision then gets a fresh
GITHUB_TOKEN / GH_TOKEN injected from the App's installation token
(rotates ~hourly, refresh 5 min before expiry).

Verified live this turn:
- Platform boot log: `github-app-auth: registered, 1 mutator(s) in chain`
- `docker exec ws-<id> gh auth status` → `Logged in as molecule-ai[bot] (GH_TOKEN)`
- `gh issue list --repo Molecule-AI/molecule-core` returns real data
  (Hermes #498/#499/#500 visible from inside a workspace container)

## Changes
- platform/go.mod + go.sum: new dep on the plugin
- platform/cmd/server/main.go: import + conditional registration
  (soft-skip when GITHUB_APP_ID is unset for self-hosted/dev)
- docker-compose.yml: pass GITHUB_APP_* env + bind-mount private key

## Drive-by
.gitignore: exclude /org-templates /plugins /workspace-configs-templates
— these dirs are populated locally by clone-manifest.sh from the
standalone repos, should never be committed to core. Without this rule
my previous git add -A staged 33 embedded git dirs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 12:52:20 -07:00
rabbitblood
239e211d3d fix(compose): platform build context must be repo root, not ./platform
The platform Dockerfile COPYs paths relative to the repo root —
\`COPY platform/go.mod\`, \`COPY platform/migrations\`,
\`COPY workspace-configs-templates\`. The compose file was setting
\`context: ./platform\`, which silently caused those COPY layers to
miss + stop invalidating cache.

Symptom (caught 2026-04-16 10:22 UTC): after PR #417 (memory schema
migration 023) merged + I ran \`docker compose up -d --build platform\`,
the rebuild was a no-op. Image SHA didn't change, container booted with
old migration set, \`Applied 22 migrations\` instead of the expected 23.
Migration 023 file was on disk locally but never reached the image.

Workaround was \`docker build -t molecule-monorepo-platform:fresh -f
platform/Dockerfile .\` from repo root → SHA changed, migration 023
applied. This commit makes \`docker compose up -d --build platform\`
work correctly without the manual workaround.

CI workflow already builds with \`context: .\` + \`file: ./platform/Dockerfile\`
(per the comment at the top of platform/Dockerfile). This change just
aligns the local compose file with what CI does.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 03:25:58 -07:00
Canvas Agent
4a95aa3e98 feat(ci): auto-publish canvas Docker image to GHCR on canvas/** merges
Closes #399.

## Root cause
`publish-platform-image.yml` existed for the Go platform image but there
was no equivalent for the canvas. After every canvas PR merged, CI ran
`npm run build` and passed — but the live container at :3000 was never
updated. The `canvas-deploy-reminder` job only posted a comment asking
operators to manually rebuild, which was consistently missed.

## What this adds
- `.github/workflows/publish-canvas-image.yml`: triggers on `canvas/**`
  changes to main (and `workflow_dispatch`). Mirrors the platform workflow:
  macOS Keychain isolation, QEMU for linux/amd64, Buildx, GHCR push with
  `:latest` + `:sha-<7>` tags.
  - `NEXT_PUBLIC_PLATFORM_URL` / `NEXT_PUBLIC_WS_URL` resolve from
    `workflow_dispatch` inputs → `CANVAS_PLATFORM_URL` / `CANVAS_WS_URL`
    repo secrets → `localhost:8080` defaults (safe for self-hosted dev).
  - Inputs are passed via env vars (not direct `${{ }}` interpolation) to
    prevent shell injection from string inputs.

- `docker-compose.yml`: adds `image: ghcr.io/molecule-ai/canvas:latest`
  to the canvas service so `docker compose pull canvas && docker compose
  up -d canvas` applies the new image. `build:` is retained for local
  development. Adds a comment clarifying that `NEXT_PUBLIC_*` runtime env
  vars are ignored by the standalone bundle (build-time only).

- `ci.yml`: updates `canvas-deploy-reminder` commit comment to reference
  `docker compose pull` as the fast path, with `docker compose build` as
  the local-source fallback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 09:23:26 +00:00
Hongming Wang
24fec62d7f initial commit — Molecule AI platform
Forked clean from public hackathon repo (Starfire-AgentTeam, BSL 1.1)
with full rebrand to Molecule AI under github.com/Molecule-AI/molecule-monorepo.

Brand: Starfire → Molecule AI.
Slug: starfire / agent-molecule → molecule.
Env vars: STARFIRE_* → MOLECULE_*.
Go module: github.com/agent-molecule/platform → github.com/Molecule-AI/molecule-monorepo/platform.
Python packages: starfire_plugin → molecule_plugin, starfire_agent → molecule_agent.
DB: agentmolecule → molecule.

History truncated; see public repo for prior commits and contributor
attribution. Verified green: go test -race ./... (platform), pytest
(workspace-template 1129 + sdk 132), vitest (canvas 352), build (mcp).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 11:55:37 -07:00