molecule-core/workspace-server/internal/handlers
Hongming Wang f6e6a64ba9 fix(canvas): forward-port dynamic runtime dropdown from staging (PR #1526)
PR #1526 shipped the /templates registry + canvas dynamic Runtime /
Model / Required-Env fields on 2026-04-22 — but merged into the
staging branch, not main. The staging→main promotion PR #1496 has
been open unmerged for a while with 1172 commits divergence, so
prod (which builds from main) still carries the old hardcoded
dropdown.

Symptom seen on hongmingwang.moleculesai.app today:

- New Hermes Agent workspace (template declares runtime: hermes) loads
  Config tab → Runtime dropdown shows "LangGraph (default)" because
  there's no <option value="hermes"> in the hardcoded list; it falls
  back to empty-value silently.
- Model field is a plain TextInput with static placeholder
  "e.g. anthropic:claude-sonnet-4-6" — should be a combobox populated
  from the selected runtime's models[].
- Required Env Vars is a TagList with static placeholder
  "e.g. CLAUDE_CODE_OAUTH_TOKEN" — should auto-populate from the
  selected model's required_env.
- Net effect: "Save & Deploy" sends empty model + empty env to the
  provisioner → workspace instant-fails.

This PR cherry-picks the exact three files from PR #1526 (#359dc61
on staging) forward to main, without pulling the other 1171
commits:

- canvas/src/components/tabs/ConfigTab.tsx
  - RuntimeOption interface + FALLBACK_RUNTIME_OPTIONS (hermes,
    gemini-cli included)
  - useEffect fetches /templates and populates runtimeOptions
    dynamically
  - dropdown renders from runtimeOptions (no hardcoded list)
  - Model becomes a combobox with datalist of available models
    per selected runtime
  - Required Env Vars auto-populates from the selected model's
    required_env on model change

- workspace-server/internal/handlers/templates.go
  - /templates endpoint returns [{id, name, runtime, models}] with
    per-template models registry (id, name, required_env)

- workspace-server/internal/handlers/templates_test.go
  - Tests for runtime+models parsing and legacy top-level model
    fallback

The canvas Runtime dropdown now resolves "hermes" correctly;
Model dropdown shows the models[] from the hermes template; Env
auto-populates with HERMES_API_KEY (or whichever model selected).

Verified locally:
  - workspace-server builds clean
  - Template handler tests pass: TestTemplatesList_RuntimeAndModelsRegistry,
    TestTemplatesList_LegacyTopLevelModel, TestTemplatesList_NonexistentDir

Follow-up: the staging→main promotion gap (#1496) is the
underlying process issue. Either merge that PR or adopt a policy
of landing fixes directly on main (as several PRs have today).
Files here were chosen minimally to avoid pulling unrelated staging
changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 14:28:38 -07:00
..
a2a_proxy_helpers.go fix(restart): support SaaS control-plane provisioner (unblocks Platform Go build too) (#1512) 2026-04-21 22:56:01 +00:00
a2a_proxy_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
a2a_proxy.go fix(restart): support SaaS control-plane provisioner (unblocks Platform Go build too) (#1512) 2026-04-21 22:56:01 +00:00
activity_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
activity.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
admin_memories_test.go fix(tenant-guard): allowlist /registry/register + /registry/heartbeat (#1236) 2026-04-21 02:47:27 +00:00
admin_memories.go fix(org-api-tokens): add org_id column, close requireCallerOwnsOrg regression 2026-04-21 01:34:05 +00:00
admin_schedules_health_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
admin_schedules_health.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
admin_test_token_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
admin_test_token.go fix(security): close IDOR gaps on /admin/test-token and /orgs/:id/allowlist 2026-04-20 23:29:27 +00:00
agent_git_identity_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
agent_git_identity.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
agent_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
agent.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
approvals_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
approvals.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
artifacts_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
artifacts.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
audit_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
audit.go fix: guard HMAC slice truncation in audit chain verification (fixes #1332) (#1339) 2026-04-21 07:52:11 +00:00
budget_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
budget.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
bundle.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
channels_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
channels.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
checkpoints_integration_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
checkpoints_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
checkpoints.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
config_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
config.go fix(security): cap webhook + config PATCH bodies (H3/H4) 2026-04-19 01:23:03 -07:00
container_files.go fix(P0): CWE-22 path traversal in copyFilesToContainer + ContextMenu test 2026-04-21 16:56:47 +00:00
delegation_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
delegation.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
discovery_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
discovery.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
events_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
events.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
github_token_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
github_token.go fix(go): replace $1 literal with resp.Body.Close() in 7 files (#1247) 2026-04-21 03:18:21 +00:00
handlers_additional_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
handlers_extended_test.go Fix TestExtended_WorkspaceDelete missing sqlmock expectations 2026-04-20 01:13:52 -07:00
handlers_test.go fix(security): strip current_task from public GET /workspaces/:id (closes #955) 2026-04-18 07:48:59 -07:00
hermes_messages_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
hermes_messages.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
hibernation_test.go feat(platform): 409 guard on /hibernate when active_tasks > 0 (closes #822) 2026-04-18 12:09:52 -07:00
mcp_test.go fix(security): backport SSRF defence (CWE-918) to main — isSafeURL in a2a_proxy.go (#1292) (#1302) 2026-04-21 07:06:42 +00:00
mcp_tools.go fix(restart): support SaaS control-plane provisioner (unblocks Platform Go build too) (#1512) 2026-04-21 22:56:01 +00:00
mcp.go fix: CWE-78 rm scope, go vet failures, delegation idempotency 2026-04-21 18:22:30 +00:00
memories_test.go test: GLOBAL memory delimiter spoofing escape + LOCAL scope untouched 2026-04-18 11:54:52 -07:00
memories.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
memory_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
memory.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
org_helpers.go fix: CWE-78 rm scope, go vet failures, delegation idempotency 2026-04-21 18:22:30 +00:00
org_import.go fix: CWE-78 rm scope, go vet failures, delegation idempotency 2026-04-21 18:22:30 +00:00
org_include_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
org_include.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
org_path_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
org_plugin_allowlist_test.go fix(auth): F1094 — requireCallerOwnsOrg reads org_id not created_by (#1200) (#1220) 2026-04-21 02:11:27 +00:00
org_plugin_allowlist.go fix(auth): F1094 — requireCallerOwnsOrg reads org_id not created_by (#1200) (#1220) 2026-04-21 02:11:27 +00:00
org_prompt_ref_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
org_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
org_tokens_test.go fix(org-tokens): rate-limit mint, bound list, correct audit provenance 2026-04-20 14:22:38 -07:00
org_tokens.go fix(platform): unblock SaaS workspace registration end-to-end 2026-04-21 03:06:46 -07:00
org.go fix: CWE-78 rm scope, go vet failures, delegation idempotency 2026-04-21 18:22:30 +00:00
plugins_install_pipeline_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
plugins_install_pipeline.go fix(security): close F1086 err.Error() leaks in plugin install pipeline + provision (#1206) 2026-04-21 03:54:50 +00:00
plugins_install.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
plugins_listing.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
plugins_sources.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
plugins_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
plugins.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
registry_test.go Merge remote-tracking branch 'origin/staging' into feat/bootstrap-failed-and-console-proxy 2026-04-20 17:31:16 -07:00
registry.go fix(platform): address code review — saasMode fallthrough, revoke in SaaS, warn-once on typo 2026-04-21 03:49:13 -07:00
restart_context_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
restart_context.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
schedules_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
schedules.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
secrets_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
secrets.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
security_regression_685_686_687_688_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
socket.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
sse_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
sse.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
ssrf_test.go fix(core): resolve main build — remove duplicate SSRF function declarations 2026-04-21 17:03:36 +00:00
ssrf.go fix: CWE-78 rm scope, go vet failures, delegation idempotency 2026-04-21 18:22:30 +00:00
team_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
team.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
template_import_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
template_import.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
templates_test.go fix(canvas): forward-port dynamic runtime dropdown from staging (PR #1526) 2026-04-22 14:28:38 -07:00
templates.go fix(canvas): forward-port dynamic runtime dropdown from staging (PR #1526) 2026-04-22 14:28:38 -07:00
terminal_test.go fix(terminal): correct CP branch to SSH-only (no docker exec) 2026-04-21 18:39:00 -07:00
terminal.go fix(ci): unblock main CI on ubuntu-latest — IPv6-safe addr + MagicMock seed 2026-04-22 13:18:46 -07:00
tokens_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
tokens.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
traces_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
traces.go fix(go): replace $1 literal with resp.Body.Close() in 7 files (#1247) 2026-04-21 03:18:21 +00:00
transcript_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
transcript.go fix(go): replace $1 literal with resp.Body.Close() in 7 files (#1247) 2026-04-21 03:18:21 +00:00
viewport_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
viewport.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
webhooks_test.go feat: event-driven cron triggers + auto-push hook for agent productivity 2026-04-19 20:26:35 -07:00
webhooks_workflow_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
webhooks.go fix: multiple platform handler bug fixes 2026-04-20 05:01:01 +00:00
workspace_bootstrap_test.go feat(platform): bootstrap-failed + console endpoints for CP watcher 2026-04-20 17:11:34 -07:00
workspace_bootstrap.go fix(security): sanitize error details in BootstrapFailed, provision, and plugin install (#1219) 2026-04-21 02:11:38 +00:00
workspace_budget_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
workspace_crud.go fix: CWE-78 rm scope, go vet failures, delegation idempotency 2026-04-21 18:22:30 +00:00
workspace_metrics_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
workspace_metrics.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
workspace_preflight_test.go chore: code-review cleanup on today's shipped PRs 2026-04-20 16:04:57 -07:00
workspace_preflight.go chore: code-review cleanup on today's shipped PRs 2026-04-20 16:04:57 -07:00
workspace_provision_test.go fix(restart): support SaaS control-plane provisioner (unblocks Platform Go build too) (#1512) 2026-04-21 22:56:01 +00:00
workspace_provision.go feat(workspace): persist CP-returned EC2 instance_id on provision 2026-04-21 17:56:15 -07:00
workspace_restart_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
workspace_restart.go fix(restart): support SaaS control-plane provisioner (unblocks Platform Go build too) (#1512) 2026-04-21 22:56:01 +00:00
workspace_test.go test: add cascade schedule disable tests for #1027 2026-04-19 22:00:50 -07:00
workspace.go fix: CWE-78 rm scope, go vet failures, delegation idempotency 2026-04-21 18:22:30 +00:00