Skip to content

feat(dev-start): true single-command spinup — infra + templates + auth posture - #2192

Merged
hongmingwang-moleculeai merged 1 commit into
stagingfrom
feat/single-command-spinup
Apr 27, 2026
Merged

feat(dev-start): true single-command spinup — infra + templates + auth posture#2192
hongmingwang-moleculeai merged 1 commit into
stagingfrom
feat/single-command-spinup

Conversation

@HongmingWang-Rabbit

Copy link
Copy Markdown
Contributor

Summary

Manual fresh-user clean-slate test surfaced three friction points in the existing `scripts/dev-start.sh` (which existed but was undocumented and incomplete). This PR makes `./scripts/dev-start.sh` a true single command from `git clone` to a usable canvas, and updates the quickstart doc to lead with it.

Friction the prior script had

# Issue Fix
1 Ran `docker compose -f docker-compose.infra.yml` directly, bypassing `infra/scripts/setup.sh` → no template registry → "Template palette is empty" Calls `setup.sh` which brings up full infra and populates templates from `manifest.json`
2 `ADMIN_TOKEN` not handled. Fail-open closed after first workspace token → canvas 401s with no recovery path Writes `MOLECULE_ENV=development` to `.env` to activate the dev-mode auth hatch (middleware.isDevModeFailOpen())
3 Not mentioned in `docs/quickstart.md` — new users followed the 4-step manual flow Quickstart now leads with the one-command path; manual flow demoted to "Manual setup (advanced)"

Why NOT auto-generate ADMIN_TOKEN

A first attempt did. It broke the canvas because:

```go
func isDevModeFailOpen() bool {
if os.Getenv("ADMIN_TOKEN") != "" {
return false // any ADMIN_TOKEN closes the hatch
}
env := os.Getenv("MOLECULE_ENV")
return env == "development" || env == "dev"
}
```

ADMIN_TOKEN being set closes the hatch, and the canvas has no `NEXT_PUBLIC_ADMIN_TOKEN` bake step to receive a token in a dev build. The .env comment block explicitly warns future contributors not to add ADMIN_TOKEN to dev .env.

Other improvements

  • Both background processes' logs go to `/tmp/molecule-{platform,canvas}.log` so the readiness banner stays clean instead of stdout-mixed
  • Health-poll loops cap at 30s with timeout errors pointing to the log file (was: infinite hang)
  • Readiness banner tells the user the next step ("open localhost:3000 → add API key in Config → Secrets & API Keys → Global"), not just service URLs

Verification

Tested end-to-end from full clean Docker (no containers, no volumes, no `.env`) three times:

Phase Wall-clock
infra (setup.sh) ~10s
Platform build + ready ~2s
Canvas dev start ~3s
Total re-run ~12s
First run + npm install + docker pulls ~2 min

Confirmed:

  • ✓ `/workspaces` returns 200 without bearer (dev-mode hatch active)
  • ✓ `/templates` returns 8 templates (registry populated from manifest)
  • ✓ Canvas serves at HTTP 200
  • ✓ `.env` correctly contains only `MOLECULE_ENV=development` (no `ADMIN_TOKEN` leak)
  • ✓ Banner output matches the design above

Test plan

  • Fresh clean-slate test from no .env, no containers, no volumes → 12s to ready
  • Re-run preserves `.env`
  • Canvas can call admin endpoints without bearer
  • Templates populated
  • CI: `shellcheck` on the script (existing convention)
  • Manual: someone other than me follows the new quickstart from a fresh clone

🤖 Generated with Claude Code

…h posture

Manual fresh-user clean-slate test surfaced three friction points in
the existing dev-start.sh:

  1. The script ran docker compose -f docker-compose.infra.yml
     directly, bypassing infra/scripts/setup.sh — so the workspace
     template registry was never populated and the canvas template
     palette came up empty (the "Template palette is empty"
     troubleshooting hit).
  2. ADMIN_TOKEN was not handled at all. Without it, the AdminAuth
     fail-open gate worked initially but slammed shut the moment the
     first workspace registered a token — at which point the canvas
     could no longer call /workspaces or /templates. New users hit
     401s with no obvious next step.
  3. The script wasn't mentioned in docs/quickstart.md. New users
     followed the documented 4-step manual flow and never discovered
     the single command existed.

Fixes:

  - dev-start.sh now calls infra/scripts/setup.sh, which brings up
    full infra (postgres + redis + langfuse + clickhouse + temporal)
    AND populates the template/plugin registry from manifest.json.
  - On first run, dev-start.sh writes MOLECULE_ENV=development to
    .env. This activates middleware.isDevModeFailOpen() which lets
    the canvas keep calling admin endpoints without a bearer (the
    intended local-dev escape hatch). The .env is preserved on
    re-runs and sourced before the platform launches.
  - The script intentionally does NOT auto-generate an ADMIN_TOKEN.
    A first attempt did, and broke the canvas because isDevModeFailOpen
    requires ADMIN_TOKEN empty AND MOLECULE_ENV=development together.
    Setting ADMIN_TOKEN in dev would close the hatch and the canvas
    has no way to read that token in a dev build (no
    NEXT_PUBLIC_ADMIN_TOKEN bake step here). The .env comment block
    explicitly warns future contributors not to add it.
  - Both processes' logs go to /tmp/molecule-{platform,canvas}.log
    instead of stdout-mixed so the readiness banner stays clean.
  - Health-poll loops cap at 30s with a clear timeout error pointing
    to the log file, instead of hanging forever.
  - The readiness banner now lists the log paths AND tells the user
    the next step is "open localhost:3000 → add API key in Config →
    Secrets & API Keys → Global", instead of just listing service
    URLs.

Quickstart doc rewrite leads with:

    git clone ...
    cd molecule-monorepo
    ./scripts/dev-start.sh

The 4-step manual flow is preserved as "Manual setup (advanced)"
for contributors who want per-component logs.

Verified end-to-end from clean Docker (no containers, no volumes,
no .env) three times: total wall-clock ~12s for a re-run with
cached npm/docker layers. Platform's HTTP 200 on /workspaces
without a bearer confirms the dev-mode auth hatch is active.
Merged via the queue into staging with commit 79265f6 Apr 27, 2026
14 checks passed
HongmingWang-Rabbit pushed a commit that referenced this pull request Jun 12, 2026
…tries (#2192)

Adds scripts/check-manifest-repos-exist.sh — a fail-fast guard that
verifies every repo in manifest.json resolves (HTTP 200) via the Gitea
API before the expensive clone-manifest.sh step runs. Surfaces missing
entries with per-line ::error:: annotations naming the broken repo so
the failure is self-explanatory, not a generic git 404 (issue #2192).

Integrates the check into publish-workspace-server-image.yml immediately
before the Pre-clone manifest deps step. This is the push-time complement
to PR #2186's PR-time manifest-entry-existence gate.

Also prunes two workspace_template entries whose repos do not exist:
- google-adk (added 2026-05-28 in 0359912 but repo never created)
- seo-agent (added 2026-05-25 in ef86514 but repo never created)

These dangling entries would have caused the next main push's publish
workflow to fail with a cryptic git clone error.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
HongmingWang-Rabbit pushed a commit that referenced this pull request Jun 12, 2026
…ne + prune broken entries (#2192)' (#2219) from fix/2192-manifest-repo-existence-check-v2 into main
HongmingWang-Rabbit pushed a commit that referenced this pull request Jun 12, 2026
…stence check

#2192 added scripts/check-manifest-repos-exist.sh which curled the Gitea
API per manifest repo WITHOUT auth ("public endpoint, no auth needed").
But molecule-ai-workspace-template-seo-agent and -google-adk are PRIVATE
repos, so the unauthenticated GET returned 404 — indistinguishable from a
genuinely-missing repo — and the guard false-pruned both from
manifest.json. Every tenant lost them from its workspace-template palette.

The real cloner (scripts/clone-manifest.sh) authenticates with
MOLECULE_GITEA_TOKEN, so the templates cloned fine until the prune.

Fixes:
- Re-add the two workspace_templates entries (byte-identical to the
  pre-#2192 manifest blob). Does NOT re-add free-beats-all / medo-smoke,
  which #2192 correctly removed (truly-deleted org templates).
- check-manifest-repos-exist.sh now sends `Authorization: token
  ${MOLECULE_GITEA_TOKEN}` when the token is set, so a private repo is no
  longer mistaken for a missing one. A 404 WITH a valid token still means
  truly-missing — the guard's real purpose is preserved. Falls back to an
  unauthenticated request when the token is unset (local dev).
- Wire MOLECULE_GITEA_TOKEN (secrets.AUTO_SYNC_TOKEN, same as the clone
  step) into the "Validate manifest entries exist" workflow step, which
  previously had no token in its env.

Verified: unauth GET of both repos returns 404 (the false-prune trigger);
script smoke-test confirms the Authorization header is sent for every
entry when the token is set, and omitted when unset; manifest.json is
valid JSON; bash -n + shellcheck clean.

Note: manifest.json is baked into the tenant image
(workspace-server/Dockerfile.tenant:121), so templates reappear in tenant
palettes only after merge -> tenant image rebuild -> fleet redeploy, not
instantly on merge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant