3884580aaa
2 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| ada1008012 |
feat(plugins): plugin drift detector + queue + admin apply endpoint (#123)
## Summary Adds the version-subscription drift detection and operator-apply workflow for per-workspace plugin tracking (core#113). ## Components **Migration** (`20260510000000_plugin_drift_queue`): - Adds `installed_sha` column to `workspace_plugins` — records the commit SHA installed so the drift sweeper can compare against upstream. - Creates `plugin_update_queue` table with status: pending | applied | dismissed. - Adds partial unique index to prevent duplicate pending rows per (workspace_id, plugin_name). **GithubResolver** (`github.go`): - `LastFetchSHA` field + `LastSHA()` getter — populated by `Fetch` after a successful shallow clone (captured before `.git` is stripped). Used by the install pipeline to seed `installed_sha`. - `ResolveRef(ctx, spec)` method — resolves a plugin spec to its full commit SHA using `git fetch --depth=1 + git rev-parse`. Used by the drift sweeper to get the current upstream SHA for a tracked ref (tag:vX.Y.Z, tag:latest, sha:…, or bare branch). **Drift sweeper** (`plugins/drift_sweeper.go`): - Periodic sweep every 1h: SELECTs rows where `tracked_ref != 'none' AND installed_sha IS NOT NULL`, resolves upstream SHA, queues drift if different. - `ListPendingUpdates()` — reads pending queue rows for the admin endpoint. - `ApplyDriftUpdate()` — marks entry applied (idempotent). - ctx.Err() guard on ticker arm to avoid post-shutdown work. **Install pipeline** (`plugins_install_pipeline.go`, `plugins_tracking.go`, `plugins_install.go`): - `stageResult.InstalledSHA` field — carries the SHA from Fetch to the DB. - `recordWorkspacePluginInstall` now accepts and stores `installed_sha`. - `deleteWorkspacePluginRow` — removes tracking row on uninstall so a stale SHA doesn't prevent the next install from creating a fresh row. - Both Docker and EIC uninstall paths call `deleteWorkspacePluginRow`. **Admin endpoints** (`handlers/admin_plugin_drift.go`): - `GET /admin/plugin-updates-pending` — list all pending drift entries. - `POST /admin/plugin-updates/:id/apply` — re-installs plugin from source_raw (re-fetching the same tracked ref), records the new SHA, marks entry applied, triggers workspace restart. Idempotent (already-applied returns 200). **Router wiring** (`router.go`, `cmd/server/main.go`): - Plugin registry created in main.go and shared between PluginsHandler and drift sweeper. - `router.Setup` accepts optional `pluginResolver` param. - `PluginsHandler.Sources()` export for the sweeper wiring pattern. ## Tests - `plugins/github_test.go` — `ResolveRef` coverage (invalid spec, git error, not-found mapping, no-panic for all ref shapes). - `plugins/drift_sweeper_test.go` — `ResolveRef` happy path, stub resolver interface compliance. - `handlers/admin_plugin_drift_test.go` — ListPending (empty, non-empty, DB error), Apply (not found, already applied, already dismissed, workspace_plugins missing). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
|||
|
|
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> |