Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
217 commits
Select commit Hold shift + click to select a range
08cdcd9
Add client plugin support and dynamic visualization handling
romer8 Apr 1, 2026
64c8122
Enhance dynamic panel handling in DashboardLayout and add layout util…
romer8 Apr 1, 2026
149685a
Refactor panel layout utility to use slot-based approach for dynamic …
romer8 Apr 3, 2026
4482a2d
Implement chat sidebar functionality with context management and dyna…
romer8 Apr 5, 2026
e354f58
Add architecture document for TethysDash chatbox integration
romer8 Apr 5, 2026
a791422
Add TethysDash MCP server and inline data visualization support
romer8 Apr 6, 2026
fc9488d
feat: integrate chatbox component and update dependencies
romer8 Apr 8, 2026
458d028
feat: add chatbox plugin integration and enhance client plugin regist…
romer8 Apr 9, 2026
ccbcc5a
feat: implement runtime plugin registration and synchronization with …
romer8 Apr 9, 2026
7012d9f
feat: enhance plugin management with runtime registry and auto-save f…
romer8 Apr 10, 2026
f5eb81b
feat: enhance visualization management with plugin removal and metada…
romer8 Apr 12, 2026
005073a
feat: add variable input and intake plugin tools for dynamic visualiz…
romer8 Apr 12, 2026
705c9a4
feat: update dependencies and improve dashboard functionality
romer8 Apr 14, 2026
1b3e2c5
fix(mcp): remove hardcoded examples from render_plugin tool description
romer8 Apr 14, 2026
0f6061a
fix(dashboard): validate grid items and support per-panel source in b…
romer8 Apr 15, 2026
11dfb4b
fix(mcp): enhance list_intake_plugins description and return format f…
romer8 Apr 15, 2026
23e8ddd
fix(mcp): align visualization source names with Default registry
romer8 Apr 15, 2026
6158027
fix(map): transform EPSG:4326 coordinates and assign CRS for inline G…
romer8 Apr 15, 2026
a90c6f6
feat(mcp): redesign create_map_visualization with markers, geocoding,…
romer8 Apr 15, 2026
b1a5309
fix(mcp): use top-level args instead of inlineData for Map, Text, Cus…
romer8 Apr 15, 2026
b82e9bc
fix(mcp): omit null args from map visualization to fix edit modal
romer8 Apr 15, 2026
e850aa0
feat(mcp): split map tools + update-visualization event
romer8 Apr 16, 2026
b684d04
fix(dashboard): batch layer updates per UUID to prevent stale ref
romer8 Apr 16, 2026
efcf189
fix(mcp,dashboard): ESRI attributeVariables key, ref timing, dict coe…
romer8 Apr 16, 2026
3eb27e1
Merge remote-tracking branch 'origin/main' into feature/tethysdash-mc…
romer8 Apr 16, 2026
534678b
fix(mcp): GeoJSON source placement + geojson_url parameter + dict coe…
romer8 Apr 16, 2026
21bab3f
feat(mcp): support dropdown, slider, and additional variable input types
romer8 Apr 17, 2026
09828b8
docs: update CLAUDE.md with MCP server, data contracts, and docs/solu…
romer8 Apr 17, 2026
48d7792
test(mcp): add contract tests for all MCP tool output shapes
romer8 Apr 17, 2026
c60a2b5
test(e2e): add Playwright JS infrastructure with SQLite fixtures
romer8 Apr 17, 2026
bfddb32
fix(e2e): use system Chromium, fix CSRF mock, verify first test passes
romer8 Apr 17, 2026
12c4d81
test(e2e): add full Playwright E2E test coverage (34 tests passing)
romer8 Apr 18, 2026
0176e98
test: address code review findings (167 + 36 tests passing)
romer8 Apr 18, 2026
3cb830b
fix: skip cleanup_old_jsons on first-time init and prime harvester in…
romer8 Apr 19, 2026
0dfb229
refactor: address ce:review findings on cleanup_old_jsons guard
romer8 Apr 19, 2026
b9d758c
feat: add three project-level test-runner skills
romer8 Apr 20, 2026
cadf102
fix: declare missing deps, fix py3.11 test compatibility, wire [test]…
romer8 Apr 20, 2026
eb63f95
fix: Jest test debt + process-group cleanup in test-* skills
romer8 Apr 20, 2026
3fecbd8
test: unskip DashboardView + retry flaky TextEditor keyboard test
romer8 Apr 20, 2026
319aec7
feat(mcp): R3a — all create tools return server-assigned UUIDs
romer8 Apr 21, 2026
a7cda39
feat(mcp): R7 — shared editableSchemas whitelist for the patch protocol
romer8 Apr 21, 2026
2ae5033
feat(mcp): R1-R10 — patch_visualization tool for generic update protocol
romer8 Apr 21, 2026
fa3e9c2
feat(dashboard): R4/R5b/R13 — apply_patch reducer branch + first Jest…
romer8 Apr 21, 2026
d2d9ebe
feat(chatbox): R6 — ChatSidebar state injection + in-turn delta
romer8 Apr 21, 2026
c6a474f
feat(validation): R15 — pre-ship canary harness (one-time local ritual)
romer8 Apr 21, 2026
1e95c20
feat(validation): Ollama Cloud support in R15 harness
romer8 Apr 21, 2026
c252651
feat(chatbox): update path handling for inline visualizations and enh…
romer8 Apr 21, 2026
acba2f2
feat(error): ErrorBoundary accepts fallback prop (node or render fn)
romer8 Apr 22, 2026
a6bf4b8
feat(error): add TileErrorFallback — compact in-tile render-error UI
romer8 Apr 22, 2026
de9dc2d
feat(dashboard): wrap BaseVisualization in per-tile ErrorBoundary
romer8 Apr 22, 2026
f9dad37
refactor: apply ce:review safe_auto fixes + consolidate P1/P2 session…
romer8 Apr 22, 2026
3831d62
feat(mcp): tighten patch_visualization + create_card against ce:revie…
romer8 Apr 22, 2026
92dd73d
feat(chatbox): wire toolErrorCheck + bound afterToolExecution + guard…
romer8 Apr 22, 2026
3c2c3c7
feat(plugin-patch): add plugin-source editable-path resolver + patter…
romer8 Apr 22, 2026
ab89e7f
feat(plugin-patch): add Intake llm_editable_args / llm_non_editable_a…
romer8 Apr 22, 2026
d687c9f
feat(plugin-patch): add client_custom llmEditableArgs/llmNonEditableA…
romer8 Apr 22, 2026
a16dc53
feat(plugin-patch): dispatch patch_visualization by plugin source + t…
romer8 Apr 22, 2026
fcc7e34
feat(plugin-patch): surface plugin whitelists in list_available_visua…
romer8 Apr 22, 2026
218067d
feat(plugin-patch): add inspect_editable_paths CLI subcommand (R13)
romer8 Apr 22, 2026
732035f
feat(plugin-patch): gate chatbox on dashboard edit permission (R11)
romer8 Apr 22, 2026
9399233
docs(plugin-patch): document LLM-editability conventions and chatbox …
romer8 Apr 22, 2026
807e4e4
feat(plugin-patch): wire server-computed plugin whitelists into LLM i…
romer8 Apr 22, 2026
09583e6
chore(plugin-patch): rebuild bundle with plugin-patch protocol changes
romer8 Apr 22, 2026
7d308f5
fix(plugin-patch): inspect_editable_paths CLI missed legacy visualiza…
romer8 Apr 23, 2026
4b961d4
refactor(plugin-patch): drop R10 pattern deny-list — editors are trus…
romer8 Apr 23, 2026
4045ec5
fix(e2e): swap native-<select> assertions for getByRole('combobox')
romer8 Apr 23, 2026
47fee50
chore(webpack): suppress benign import.meta warning from @huggingface…
romer8 Apr 23, 2026
dfbd08c
chore: rebuild bundle with chatbox dropdown + error-recovery fixes
romer8 Apr 23, 2026
72504b6
chore: rebuild bundle with MCP health + transports (Unit 7a)
romer8 Apr 23, 2026
a7d8f3b
test(e2e): MCP server panel + in-chat signal coverage (Unit 7b)
romer8 Apr 23, 2026
e9040d6
chore: rebuild bundle with chatbox toolbar wrap fix
romer8 Apr 23, 2026
b8af0f1
feat(chat-sidebar): pin TethysDash welcome copy + rebuild bundle
romer8 Apr 23, 2026
16897af
chore: rebuild bundle with scheduler-wiring fix
romer8 Apr 24, 2026
e1efba8
test(e2e): cover scheduler wiring for add/toggle/remove
romer8 Apr 24, 2026
73789ce
chore: rebuild bundle with chatbox TDZ fix
romer8 Apr 24, 2026
e94462d
chore: rebuild bundle with review fixes (13 findings)
romer8 Apr 24, 2026
abf0bb7
test(e2e): apply ce:review tethysapp-side cleanups (10 of 12 findings)
romer8 Apr 24, 2026
53d5c1a
test(e2e): cover MCP probe scheduler hardening (Units 1-3) + bundle r…
romer8 Apr 26, 2026
cf063eb
test(e2e): loosen scheme-allowlist regex to match new ERROR_COPY wording
romer8 Apr 26, 2026
232c44d
test(jest): polyfill Web Streams to unblock 33 suites blocked by msw …
romer8 Apr 26, 2026
0f60e56
chore: refresh package-lock.json for chatbox-core devDep additions
romer8 Apr 26, 2026
9402f36
chore(jest): gate Base.test.js + VariableInput.test.js (pre-existing …
romer8 Apr 26, 2026
75b77f7
test(e2e): close 1 of 3 .fixme tests; clarify the remaining 2
romer8 Apr 26, 2026
7a7063e
chore(deps): repoint @chatbox/core file: link to lib/chatbox-core
romer8 May 2, 2026
cd84bc6
docs: update chatbox-core paths and note npm publication trajectory
romer8 May 2, 2026
b794478
test(e2e): close .fixme cluster + rebuild bundle from new chatbox-core
romer8 May 4, 2026
d43f858
Merge pull request #90 from tethysplatform/feat/close-fixme-cluster
romer8 May 4, 2026
8c3580f
test(dashboard): cover same-UUID-twice apply ordering + rebuild bundle
romer8 May 4, 2026
c23c322
Merge pull request #91 from tethysplatform/fix/patch-atomicity-and-tu…
romer8 May 4, 2026
12cba51
chore(bundle): rebuild from chatbox-core anthropic adaptive thinking
romer8 May 4, 2026
f065cf4
Merge pull request #92 from tethysplatform/feat/anthropic-adaptive-th…
romer8 May 4, 2026
d50f2c5
test(mcp): add renderable-tag guard + fix two latent tag bugs
romer8 May 5, 2026
74d0f52
feat(chat): wire dispatch-feedback rule + tighten render-tool descrip…
romer8 May 5, 2026
2ceadba
fix(map): ESRI LAYERS directive parsing + canonical add_map_service_l…
romer8 May 5, 2026
51e4279
Merge origin/main into feature/tethysdash-mcp-server
romer8 May 5, 2026
d26bd7b
feat(mcp): plan 004 — builder parity, Static Image, SSRF guard
romer8 May 6, 2026
27b64b6
revert(mcp): defer URL safety / SSRF guard to plan 005
romer8 May 6, 2026
2d1d294
fix(mcp): tighten Static Image None/empty validation; pin attribute_v…
romer8 May 6, 2026
a2a83e1
chore(mcp): plan 004 P2 cleanup — discoverability + dead code + annot…
romer8 May 6, 2026
05a42c1
chore(mcp): plan 004 P2/P3 follow-ups — JS parity test, geojson_url b…
romer8 May 6, 2026
51a9ec6
Merge pull request #93 from tethysplatform/feature/004-mcp-builder-pa…
romer8 May 6, 2026
9319b1c
feat(mcp): plan 005 B2 — advanced layer/source metadata dicts
romer8 May 6, 2026
b1dedfa
feat(mcp): plan 005 B3 — add_dynamic_map_layer runtime plugin tool
romer8 May 6, 2026
b805a01
feat(mcp): plan 005 S2 — inline GeoJSON size cap at MCP boundary
romer8 May 6, 2026
3bcc325
chore(mcp): plan 005 P1+P2 safe_auto fixes from /ce:review
romer8 May 6, 2026
172d719
feat(mcp): plan 005 P1+P2 gated_auto fixes from /ce:review
romer8 May 6, 2026
5f3bad7
Merge pull request #94 from tethysplatform/feature/005-mcp-advanced-m…
romer8 May 6, 2026
47dd1da
fix(plugin_helpers): ArcGIS attribute-fetch hardening
romer8 May 6, 2026
44cd5ff
Merge pull request #95 from tethysplatform/fix/arcgis-attribute-fetch…
romer8 May 6, 2026
283e577
chore(mcp): tighten layer_props dispatch + extract advanced-dict vali…
romer8 May 6, 2026
34406bf
Merge pull request #96 from tethysplatform/chore/mcp-tighten-layer-pr…
romer8 May 6, 2026
52efb96
test(mcp): direct coverage for _resolve_dynamic_map_layer_plugin bran…
romer8 May 6, 2026
fdb001e
Merge pull request #97 from tethysplatform/test/resolve-dynamic-map-l…
romer8 May 6, 2026
0d812b3
refactor(plugins): runtime-only custom visualization plugins
romer8 May 6, 2026
87166bf
Merge pull request #98 from tethysplatform/refactor/runtime-only-cust…
romer8 May 6, 2026
743e20f
feat(devcontainer): backend-only devcontainer for TethysDash
romer8 May 6, 2026
1f78fb2
chore(frontend): rebuild bundle after chatbox-core loopback gate removal
romer8 May 6, 2026
fdaf64e
Merge pull request #99 from tethysplatform/feat/devcontainer-backend-…
romer8 May 6, 2026
47fe112
fix(dashboard): scroll the dashboard column so bottom-row resize hand…
romer8 May 7, 2026
ed6ac2d
Merge pull request #100 from tethysplatform/fix/dashboard-overflow-bo…
romer8 May 7, 2026
d9386e1
fix(controllers): log unhandled exceptions in ollama-proxy
romer8 May 7, 2026
cb23388
Merge pull request #101 from tethysplatform/fix/ollama-proxy-error-lo…
romer8 May 7, 2026
f181564
fix(mcp): close /args/layers whole-array escape in patch_visualization
romer8 May 7, 2026
2c30796
fix(controllers): log ollama-proxy stream errors
romer8 May 7, 2026
5dbe6d6
feat(mcp): add GeoTIFF source type for map layers
romer8 May 7, 2026
396a00c
Merge pull request #102 from tethysplatform/feat/mcp-geotiff-source-type
romer8 May 7, 2026
16f5ba4
fix(mcp): coerce replace->add on Map layer paths and surface patch fa…
romer8 May 7, 2026
013a228
Merge pull request #103 from tethysplatform/fix/patch-replace-coerce-…
romer8 May 7, 2026
51005e5
fix(mcp): validate UUID-typed tool args at the patch-tool boundary
romer8 May 7, 2026
439eab4
Merge pull request #104 from tethysplatform/fix/uuid-validation-mcp-t…
romer8 May 7, 2026
fe082b8
fix(mcp): nest ESRI Feature Service params + URL-encode WHERE/TIME
romer8 May 7, 2026
a48fb31
Merge pull request #105 from tethysplatform/fix/esri-feature-params-s…
romer8 May 7, 2026
cb60ca4
fix(mcp): close Tier-1 producer/consumer parity gaps in add_map_servi…
romer8 May 7, 2026
4977694
Merge pull request #106 from tethysplatform/fix/mcp-renderer-parity-t…
romer8 May 7, 2026
b5c2656
feat(mcp): inject per-source-type arg-routing templates for add_map_s…
romer8 May 7, 2026
c616b3c
Merge pull request #107 from tethysplatform/feat/mcp-arg-routing-temp…
romer8 May 7, 2026
19de7b8
feat(viz): derive OL style.color for GeoTIFF layers at render time (#…
romer8 May 7, 2026
82cc2bc
refactor(mcp): replace add_map_service_layer umbrella with 11 per-sou…
romer8 May 8, 2026
a240bc7
fix(mcp): convert pydantic ValidationError on tool input to typed env…
romer8 May 8, 2026
5ab2f26
feat(mcp): migrate /sse → /mcp Streamable HTTP, env-driven CORS, loop…
romer8 May 8, 2026
1944ec1
feat(chatbox): persist chat conversation per dashboard in localStorag…
romer8 May 8, 2026
e338010
chore: bump chatbox-core file: link reference to 0.6.0
romer8 May 9, 2026
9591396
fix(chatbox): add escape clause to dashboard-edit system framing
romer8 May 9, 2026
7b6aafb
fix(mcp): rename patch_visualization input args to {uuid, ops}
romer8 May 9, 2026
a769f36
fix(mcp): richer validation envelope for LLM single-retry recovery
romer8 May 9, 2026
5922203
feat(mcp): per-tool-call observability + log-noise filters
romer8 May 9, 2026
36b78ce
revert: today's debug arc — re-applied via PR fix/mcp-debug-arc-2026-…
romer8 May 9, 2026
1d794f9
fix(mcp): debug-arc 2026-05-09 — framing escape clause, patch_visuali…
romer8 May 9, 2026
e8bbf91
fix(mcp): mutually-exclusive create-vs-patch routing rule on tool des…
romer8 May 9, 2026
8d5a37a
Revert "fix(mcp): mutually-exclusive create-vs-patch routing rule on …
romer8 May 9, 2026
8328d73
fix(mcp): mutually-exclusive create-vs-patch routing rule on tool des…
romer8 May 9, 2026
2c6b64b
fix(mcp): reject empty data + clamp w/h on create_* / render_* tools
romer8 May 9, 2026
a051edb
Revert "fix(mcp): reject empty data + clamp w/h on create_* / render_…
romer8 May 9, 2026
1ce06cc
fix(mcp): reject empty data + clamp w/h on create_* / render_* tools …
romer8 May 9, 2026
8c2cdaa
feat(dashboard): copy-UUID icon on every grid item (#4)
romer8 May 10, 2026
9deff5c
fix(dashboard): scope DataViewer tab CSS to stop double scrollbar lea…
romer8 May 10, 2026
3346731
feat(mcp): add 4 slash-command prompt templates (Phase 3a)
romer8 May 10, 2026
690b98a
feat(mcp): add 9 visualization-create slash-command prompts (Phase 3b)
romer8 May 11, 2026
fc887d8
fix(mcp): pin Phase 3b create_*/register_* tools in BM25 always_visible
romer8 May 11, 2026
a739750
refactor(mcp): drop BM25SearchTransform, trust chatbox-core embedding…
romer8 May 11, 2026
adf2835
feat(mcp): add 12 layer-add slash-command prompts (Phase 3c)
romer8 May 11, 2026
6591090
fix(mcp): enrich Phase 3c layer prompt bodies with optional-arg vocab…
romer8 May 11, 2026
dddd67f
docs(claude): refresh MCP section for post-Phase-3c architecture
romer8 May 11, 2026
a0ce89c
fix(dashboard): copy only the bare UUID, not tile metadata (#114)
romer8 May 11, 2026
bc8346f
refactor: archive Playwright suite to aquaveo, remove from upstream s…
romer8 May 11, 2026
ea0750b
refactor(deps): drop broken legacy chatbox file: link (#117)
romer8 May 11, 2026
a44cbfb
fix(mcp): two critical correctness fixes — fastmcp prod dep + stale a…
romer8 May 11, 2026
b93a1ca
refactor: delete R15 pre-ship validation harness (NotImplementedError…
romer8 May 11, 2026
ba6cfe9
refactor: add save_runtime_plugin_registry() helper, consolidate 3-si…
romer8 May 11, 2026
186fb37
feat: add anonymous /runtime-plugins/list/ endpoint for standalone MC…
romer8 May 12, 2026
6d4d2c5
chore: rebuild React bundle + backfill #6 CHANGELOG + ignore runtime …
romer8 May 12, 2026
7701af0
refactor: remove embedded MCP server (extract to Aquaveo/tethysdash_m…
romer8 May 12, 2026
29b7bc8
feat(devcontainer): bake React bundle at image build (multi-stage) (#…
romer8 May 12, 2026
5546837
chore(devcontainer): bump @aquaveo/chatbox-core 0.6.0 → 0.6.1 (#125)
romer8 May 18, 2026
5195678
fix(model): stop inserting phantom empty grid item on dashboard creat…
romer8 May 18, 2026
35ff282
fix(chatbox): assert dashboard_state authority over prior tool-call h…
romer8 May 18, 2026
2f9737f
chore(devcontainer): bump @aquaveo/chatbox-core 0.6.1 → 0.6.3 (#128)
romer8 May 18, 2026
03243bb
chore(devcontainer): bump @aquaveo/chatbox-core 0.6.3 → 0.6.4 (#129)
romer8 May 18, 2026
05b7c08
feat(chatbox): enable MCP result-by-reference protocol on Chatbox mount
romer8 May 19, 2026
59406be
feat(chatbox): wire /clear slash command to clear per-dashboard chat …
romer8 May 19, 2026
ee070a2
fix(chatbox): always inject dashboard_state so AUTHORITATIVE clause f…
romer8 May 20, 2026
cab4bcd
chore: strip plan references from code comments
romer8 May 20, 2026
7f241f9
Merge origin/main into feature/tethysdash-mcp-server
romer8 May 20, 2026
09e2042
build: rebuild React bundle after main merge
romer8 May 20, 2026
ff1a7aa
fix(chatbox): return string from toolErrorCheck, not wrapper object
romer8 May 21, 2026
e11bc27
Merge origin/main into feature/tethysdash-mcp-server
romer8 May 21, 2026
f8fef80
Add license information for bundled JavaScript files and update manif…
romer8 May 21, 2026
bd65aa2
fix(webpack): proxy hashed bundle paths to Tethys, keep main.js in de…
romer8 May 21, 2026
b3c6590
fix(chatbox): add configure_popup_modal_layer exception to PRIORITY c…
romer8 May 21, 2026
6b2966e
fix(viz): short-circuit Edit Visualization preview to featurePending …
romer8 May 22, 2026
f56fa45
feat(devcontainer): pre-install FIRO-Tethys workshop plugins in image
romer8 May 22, 2026
d0481bb
Revert "feat(devcontainer): pre-install FIRO-Tethys workshop plugins …
romer8 May 22, 2026
d0475f3
chore(frontend): rebuild React bundle against chatbox-core 0.15.0
romer8 May 22, 2026
3cdc59a
chore(frontend): rebuild against chatbox-core 0.15.1 (anthropic tempe…
romer8 May 22, 2026
51904d4
chore(frontend): rebuild against chatbox-core 0.15.2 (openai fix + Re…
romer8 May 22, 2026
5eefa2d
build: rebuild React bundle with chatbox-core /clear fix
romer8 May 27, 2026
41aa490
build: rebuild React bundle with /clear context usage reset
romer8 May 27, 2026
337bee5
build: rebuild React bundle with Gemini provider support
romer8 May 27, 2026
f329863
feat: add generic LLM proxy for CORS-blocked providers + rebuild bundle
romer8 May 27, 2026
ca02906
fix: pass Google API key as query param, not Bearer token
romer8 May 28, 2026
44e2f37
build: rebuild React bundle with Gemini baseUrl fallback fix
romer8 May 28, 2026
34c0916
fix: revert to Authorization Bearer for Google OpenAI-compat endpoint
romer8 May 28, 2026
6e4edde
build: rebuild React bundle with Gemini adapter debug logging
romer8 May 28, 2026
2597ddb
build: rebuild with Gemini SSE buffer fix
romer8 May 28, 2026
a461b5c
build: rebuild with Gemini tool_calls merge fix
romer8 May 28, 2026
fa0bda9
build: rebuild with Gemini adapter message wrapper fix
romer8 May 28, 2026
42b154d
build: rebuild with Gemini Beta label
romer8 May 28, 2026
c670fef
feat: add llm-proxy/google/ generic forwarder for @google/genai SDK +…
romer8 May 28, 2026
80dd973
build: rebuild with Gemini proxy-forcing fix
romer8 May 28, 2026
76a4f9d
build: rebuild with Gemini absolute proxy URL fix
romer8 May 28, 2026
4bda267
build: rebuild with Gemini fetch-wrapper trailing-slash fix
romer8 May 28, 2026
ad78025
build: rebuild with Gemini CSRF token injection
romer8 May 28, 2026
d070aa4
build: rebuild with Beta label removed from Gemini provider
romer8 May 28, 2026
97aefc9
build: rebuild with capped ChatErrorPanel height
romer8 May 28, 2026
67e4cde
feat(controllers): proxy route for Ollama /v1/chat/completions OpenAI…
romer8 May 28, 2026
4441010
feat: incremental tile streaming — host listeners + edit/delete/reord…
romer8 May 28, 2026
ab7dd63
chore: bump @aquaveo/chatbox-core 0.16.0-beta.0 → 0.16.1-beta.0 + reb…
romer8 May 29, 2026
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
55 changes: 55 additions & 0 deletions .claude/skills/test-all/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
name: test-all
description: Run the full TethysDash test sweep in a self-contained `.venv-test/` — the full Python suite (includes MCP contracts) plus Jest. Rebuilds the React bundle first. Writes a pass/fail report. First run with a cold venv takes 2-5 minutes; subsequent runs are faster.
argument-hint: (none)
---

Run the full TethysDash test sweep. Write results to `test-results/reports/<ISO-timestamp>-test-all.md`.

On preflight, bootstrap, or bundle-build failure, STOP and tell the user exactly what to fix. On per-suite failure, continue to the next suite and aggregate results.

1. **System preflight**. Verify these are on PATH: `python3`, `node`, `npm`. If any is missing, stop with remediation text naming the missing binary.

2. **Venv bootstrap**. From the repo root:
- Compute `sha256sum pyproject.toml | awk '{print $1}'`.
- If `.venv-test/.pyproject-hash` matches, reuse. Otherwise recreate: `python3 -m venv .venv-test`, `.venv-test/bin/pip install --upgrade pip --quiet`, `.venv-test/bin/pip install -e ".[test]" --quiet` (the `[test]` extras pull in `fastmcp` so the MCP server imports cleanly), then write the new hash.
- On `pip install -e ".[test]"` failure: stop, surface stderr, exit non-zero.

3. **Node deps**. From the repo root, if `package-lock.json` exists use `npm ci`; otherwise `npm install`.

4. **Build the bundle**. `npm run build`. Failure here is fatal — stop.

5. **Start report file** at `test-results/reports/<ISO-timestamp>-test-all.md`:
```
# test-all run — <ISO-timestamp>

**Commit:** <git rev-parse HEAD>
**Python:** <.venv-test/bin/python --version> (.venv-test)
**Node:** <node --version>

```

6. **Full Python suite**. `.venv-test/bin/pytest --reuse-db --no-cov -q tethysapp/tethysdash/tests/`. Capture exit code and duration. This sweep covers MCP contracts, integrated tests, and unit tests.

7. **Jest**. From the repo root: `npm test`. Capture exit code and duration.

8. **Finalize report**. Append a summary table and, for any failing suite, the last ~50 lines of its output:
```
| Suite | Result | Duration | Count |
|--------------|--------|----------|-----------------------|
| python-suite | <pass|FAIL> | <d> | <N passed / M failed> |
| jest | <pass|FAIL> | <d> | <N passed / M failed> |

**Result:** <PASS | FAIL (N of 2 suites failed)>
```
Note: MCP contracts are implicit in `python-suite`; they are not surfaced as a separate row because the sweep runs them via the single pytest invocation.

9. **Tell the user**: one-sentence summary plus report file path.

10. **Exit**. Non-zero if any suite failed; zero otherwise.

## Notes for maintainers

- First run on a cold venv is 2–5 minutes; subsequent runs on a warm venv are roughly `pytest time + npm run build + npm test` (~1.5–3 min).
- For day-to-day iteration on Python-only changes, prefer `test-backend` (fastest). For React-only iteration, run `npm test` directly — there's no dedicated front-end skill (Jest needs neither a venv nor a running Tethys server).
- The Playwright E2E suite was archived in May 2026; see `CLAUDE.md` → "Playwright suite — archived" for the rationale and the `aquaveo` archive branch. If Playwright is reintroduced, this skill grows back a Playwright step gated by the charter at `docs/brainstorms/2026-05-11-tethysdash-playwright-smoke-charter-requirements.md` (firoh workspace).
49 changes: 49 additions & 0 deletions .claude/skills/test-backend/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
name: test-backend
description: Run the full TethysDash Python pytest suite (MCP contracts + integrated + unit) in a self-contained `.venv-test/`. Python-only — no Node, no bundle, no server. Fastest skill. Writes a pass/fail report.
argument-hint: (none)
---

Run the full Python test suite. Write results to `test-results/reports/<ISO-timestamp>-test-backend.md`.

On preflight or bootstrap failure, STOP and tell the user exactly what to fix. On per-suite failure, continue to report finalization and exit non-zero.

1. **System preflight**. Verify `python3` is on PATH (`command -v python3`). If missing, stop with: "ERROR: python3 not found on PATH. Install Python 3.10+ and retry." Do NOT check node/npm/tethys — this skill is Python-only.

2. **Venv bootstrap**. From the repo root:
- Compute the target hash: `sha256sum pyproject.toml | awk '{print $1}'`.
- If `.venv-test/.pyproject-hash` exists and matches, reuse the venv (fast path).
- Otherwise: remove `.venv-test/` if present, create fresh with `python3 -m venv .venv-test`, then `.venv-test/bin/pip install --upgrade pip --quiet` and `.venv-test/bin/pip install -e ".[test]" --quiet`. The `[test]` extras pull in `fastmcp` (declared in `pyproject.toml` under `[project.optional-dependencies].test`) so the MCP contract tests can import. Write the new hash to `.venv-test/.pyproject-hash`.
- If `pip install -e ".[test]"` fails, stop and surface stderr to the user. Do not attempt any test run.

3. **Start report file**. Create `test-results/reports/` if it does not exist. Write the report file with this header:
```
# test-backend run — <ISO-timestamp>

**Commit:** <git rev-parse HEAD>
**Python:** <.venv-test/bin/python --version> (.venv-test)

```

4. **Python suite**. Run `.venv-test/bin/pytest --reuse-db --no-cov -q tethysapp/tethysdash/tests/` from the repo root. Capture exit code, wall-clock duration, and the full output.

5. **Finalize report**. Append a summary table and, if the suite failed, the last ~50 lines of output:
```
| Suite | Result | Duration | Count |
|--------------|--------|----------|------------------|
| python-suite | <pass|FAIL> | <duration> | <N passed / M failed> |

**Result:** <PASS | FAIL>
```
Parse the pass/fail count from pytest's final summary line (`=== N passed, M failed in Xs ===`). If the suite failed, append a `## Failure details` section with the last 50 lines of output.

6. **Tell the user**: one sentence summary plus the report file path.

7. **Exit**. Non-zero if the suite failed; zero otherwise.

## Notes for maintainers

- The venv is cached. If someone edits `pyproject.toml` (adds/removes a dep), the next run will automatically recreate `.venv-test/`.
- To force a rebuild without touching `pyproject.toml`, delete `.venv-test/` and re-run.
- This skill covers `tests/integrated_tests/` and `tests/unit_tests/` — everything under `tethysapp/tethysdash/tests/`. (The MCP contract suite that used to live at `tests/mcp/` was moved to the standalone repo `Aquaveo/tethysdash_mcps` when the embedded MCP server was extracted.)
- On a warm venv, a full green run today is ~25–60 seconds. Cold first-run with `pip install -e .` is 60–120 seconds plus suite time.
63 changes: 63 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# TethysDash devcontainer. Multi-stage: node:20-slim builds the React bundle;
# python:3.11-slim runtime pulls it in. Node lives only in stage 1.

# Stage 1: frontend bundle
FROM node:20-slim AS frontend-builder

WORKDIR /build

COPY package.json package-lock.json ./

# Swap `@chatbox/core` file: link → published npm alias; the sibling source
# isn't in this build context. Bump version when chatbox-core releases.
RUN sed -i \
's|"@chatbox/core": "file:\.\./lib/chatbox-core"|"@chatbox/core": "npm:@aquaveo/chatbox-core@0.16.1-beta.0"|' \
package.json \
&& rm package-lock.json \
&& npm install --no-audit --no-fund

# Explicit COPYs (not `COPY . .`) so Python-only changes don't bust the npm layer.
COPY babel.config.json jsconfig.json ./
COPY reactapp/ ./reactapp/
COPY tethysapp/tethysdash/public/ ./tethysapp/tethysdash/public/

RUN npm run build

# Stage 2: runtime (python:3.11-slim, pip-only)
FROM python:3.11-slim

ENV TETHYS_HOME=/root/.tethys
ENV TETHYS_PERSIST=/root/.tethys
ENV VIRTUAL_ENV=/opt/venv
ENV PATH="${VIRTUAL_ENV}/bin:${PATH}"
ENV PYTHONDONTWRITEBYTECODE=1
ENV PIP_DISABLE_PIP_VERSION_CHECK=1

# build-essential + libpq-dev for psycopg2-binary source fallback; rest is dev hygiene.
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
libpq-dev \
git \
curl \
ca-certificates \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

RUN python -m venv "${VIRTUAL_ENV}"

WORKDIR /workspaces/tethysapp-tethys_dash

COPY . .

RUN pip install --no-cache-dir -e ".[test]"

# Overlay the fresh bundle from stage 1, clobbering any stale main.js from `COPY . .`.
COPY --from=frontend-builder \
/build/tethysapp/tethysdash/public/frontend/ \
/workspaces/tethysapp-tethys_dash/tethysapp/tethysdash/public/frontend/

EXPOSE 8000

# No CMD: devcontainer host keeps the container alive via overrideCommand;
# contributor runs `bash .devcontainer/run.sh` to start the server.
121 changes: 121 additions & 0 deletions .devcontainer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Backend-only devcontainer for TethysDash

A self-contained dev environment for working on the Python / Django / Tethys side of TethysDash. Pip-only (no conda), SQLite (no Postgres), no Node / Webpack. The frontend is served from the bundled `tethysapp/tethysdash/public/frontend/` assets that are committed to the repo.

If you need to do React work, use the conda-based workflow described in the top-level `README.md` instead — that path runs `npm start` and `tethys manage start` together.

## Open in dev container

**VS Code**: install the *Dev Containers* extension, open the `tethysapp-tethys_dash/` folder, then run **Dev Containers: Reopen in Container** from the command palette.

**Codex / other devcontainer-aware editors**: open the same folder and accept the rebuild prompt.

The first build runs `apt install`, creates an `/opt/venv` Python venv, `pip install -e .[test]`, and runs the MCP contract suite as a build-time gate (so dep-resolution regressions surface before you ever open a shell). Expect a few minutes on first build; subsequent rebuilds are fast.

## What `postCreateCommand` does

After the image builds, the host fires `bash .devcontainer/init.sh`, which runs two bash scripts in order:

- `scripts/tethyscore.sh` — generates `portal_config.yml`, sets dev-mode settings (`DEBUG=True`, `ALLOWED_HOSTS=['*']`, SQLite ENGINE), runs `tethys db migrate`, and creates the default superuser. Mirrors the role of `tethys_portal_firo/docker/tethyscore.sls`.
- `scripts/devcontainer-app.sh` — provisions the SQLite persistent store at the tethysdash app workspace, links it to `tethysdash:ps_database:primary_db`, runs `tethys syncstores tethysdash`, and finally touches the marker file. Mirrors the role of `tethys_portal_firo/docker/salt/init_apps.sls`.

Both scripts gate on `${TETHYS_PERSIST}/tethysdash_devcontainer_setup_complete`. If the marker exists, they exit without doing anything. The marker is touched only after `devcontainer-app.sh` reaches its end, so a partial failure leaves the marker absent and `init.sh` reruns cleanly.

**Why bash instead of Salt?** The `.sls` pattern is the canonical Aquaveo provisioning style, and we initially planned to use it here. In practice, pip-distributed Salt has incomplete install_requires on slim Python base images (missing `looseversion`, `distro`, and others), and the SaltProject apt repo isn't reliably reachable from all build environments. Bash gives us identical idempotence semantics (marker-file gating, ordered execution, env-var-driven settings) without any of the install fragility — at the cost of losing Salt's declarative DSL. The two-tier split (portal vs app) and the marker-file pattern are preserved 1:1 from the `.sls` precedent.

## Start the server

After `postCreateCommand` finishes, open a terminal in the container and:

```bash
bash .devcontainer/run.sh
```

That runs `tethys manage start -p 0.0.0.0:8000`. The forwarded port lands at `http://localhost:8000/` on your host. Log in with `admin` / `admin`, then the app is at:

```
http://localhost:8000/apps/tethysdash/
```

(Tethys mounts all apps under `/apps/<app_name>/`. Bare `/tethysdash/` will 404.)

## Edit-and-reload

The app is installed editable (`pip install -e .[test]`). Editing any `.py` file under `tethysapp/tethysdash/` triggers Django's autoreload — just save and refresh the browser.

If you change `pyproject.toml` (e.g., add a Python dep), run `pip install -e .[test]` again in the container terminal to refresh the venv.

## Run tests

(The MCP contract suite was moved out with the embedded MCP server — it now
lives in the standalone repo `Aquaveo/tethysdash_mcps`. Run it from that repo
via `./scripts/setup-mcp.sh --setup && .venv-mcp/bin/python -m pytest test_mcp/`.)

Backend tests:

```bash
python -m pytest --reuse-db
```

The Jest / Playwright frontend suites are NOT run from this container by design — see "Out of scope" below.

## Out of scope

This devcontainer intentionally does **not**:

- Install Node, npm, or Webpack — frontend rebuilds happen on your host.
- Provision Postgres, Redis, GeoServer, or any other service container.
- Mount your host's `~/.tethys/` directory — container state is isolated.
- Persist `~/.tethys/` or the SQLite store across `Rebuild Container Without Cache`. (The SQLite store is under `tethysapp/tethysdash/workspaces/`, which IS bind-mounted, so it does survive plain `Rebuild Container`. The portal_config and the marker file live in the container's `/root/.tethys/` and get wiped on full rebuilds.)

If you need any of these, fall back to the conda-based workflow in the top-level `README.md`.

## Frontend bundle staleness

The dev server serves whatever is in `tethysapp/tethysdash/public/frontend/` — the bundle committed to the repo. If you're reviewing a frontend PR, that bundle may not reflect the React changes.

Quick check on your host (NOT inside the container):

```bash
git log -1 --format=%h -- tethysapp/tethysdash/public/frontend/
git log -1 --format=%h -- reactapp/
```

If the second commit is newer than the first, run `npm run build` on your host to refresh the bundle before opening the devcontainer.

The devcontainer cannot detect or fix this for you — it's intentionally backend-only.

## Troubleshooting

### Re-bootstrap from a half-broken state

If something inside Tethys gets into an inconsistent state (schema mismatch, deleted persistent store, etc.):

```bash
rm -f $TETHYS_PERSIST/tethysdash_devcontainer_setup_complete
bash .devcontainer/init.sh
```

That removes the marker and re-runs all Salt states. Note this re-creates the SQLite store from scratch — any dashboards you saved will be gone.

### `DisallowedHost (400)` after `bash run.sh`

The Salt state's `tethys settings --set ALLOWED_HOSTS "['*']"` must have run. If you started the server before `init.sh` finished, restart the server.

### `tethys gen portal_config --overwrite` prompt

Should not happen — `--overwrite` is the explicit flag for this case. If you somehow hit a prompt (Ctrl-C and re-run), the marker-gate prevents this state from re-running anyway.

### Don't run `git clean -fdx` casually

The bundled frontend (`tethysapp/tethysdash/public/frontend/`) is committed and ignored by `.gitignore` patterns (it's exempted), and the SQLite dev store sits under `tethysapp/tethysdash/workspaces/`. A wide `git clean -fdx` can nuke either; prefer `git clean -fd` and review what's about to be removed.

### Don't push this image to a registry

The image bakes in `admin / admin` superuser credentials. It is dev-only. Pushing to a registry leaks those defaults — and the image is otherwise unhardened (DEBUG=True, ALLOWED_HOSTS=['*'], remoteUser=root).

## Reference

- Plan: `docs/plans/2026-05-06-001-feat-backend-only-devcontainer-plan.md` (workspace-level, outside this subrepo).
- Brainstorm: `docs/brainstorms/2026-05-06-backend-only-devcontainer-requirements.md`.
- Pattern source: `tethysapp-agwa/.devcontainer/` (sibling Aquaveo repo, conda-based; we adopted the file layout but diverged on env mgmt).
24 changes: 24 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "TethysDash Backend Devcontainer",
"build": {
"dockerfile": "Dockerfile",
"context": ".."
},
"workspaceFolder": "/workspaces/tethysapp-tethys_dash",
"appPort": [8000],
"forwardPorts": [8000],
"postCreateCommand": "bash .devcontainer/init.sh",
"remoteUser": "root",
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"donjayamanne.python-extension-pack"
],
"settings": {
"python.defaultInterpreterPath": "/opt/venv/bin/python",
"python.terminal.activateEnvironment": false
}
}
}
}
22 changes: 22 additions & 0 deletions .devcontainer/init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
# Devcontainer postCreateCommand. Runs the two-stage idempotent setup:
# scripts/tethyscore.sh — portal-level Tethys setup
# scripts/devcontainer-app.sh — tethysdash app-specific setup
#
# The two-script split mirrors the workspace pattern at
# tethys_portal_firo/docker/tethyscore.sls + ./salt/init_apps.sls —
# implemented in bash because pip-installed Salt has incomplete
# transitive deps and the SaltProject apt repo isn't reliably reachable
# from all build environments.
#
# Idempotence: every step is gated by
# ${TETHYS_PERSIST}/tethysdash_devcontainer_setup_complete. Re-running
# after first-time setup is a no-op until the marker is removed (see
# .devcontainer/README.md > Troubleshooting).

set -euo pipefail

cd "$(dirname "$0")"

bash scripts/tethyscore.sh
bash scripts/devcontainer-app.sh
8 changes: 8 additions & 0 deletions .devcontainer/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
# Start the TethysDash dev server inside the devcontainer.
# Bind to 0.0.0.0 so the host's forwarded port reaches it.

set -euo pipefail

echo "Starting Tethys dev server on 0.0.0.0:8000 (DEBUG=True)..."
exec tethys manage start -p 0.0.0.0:8000
Loading