docs: update all CLAUDE.md files to reflect current codebase state#1
Open
neerajs71 wants to merge 175 commits into
Open
docs: update all CLAUDE.md files to reflect current codebase state#1neerajs71 wants to merge 175 commits into
neerajs71 wants to merge 175 commits into
Conversation
The project has grown from a simple Hello World into a full well-data visualization app with DLIS/LAS/WSON viewers, a tab system, app registry, and Google Drive integration. All CLAUDE.md files now document the actual current architecture, components, state management, and conventions. https://claude.ai/code/session_0124NnsMao3HQF3u2smci3Ho
…y to well schematic - Display Options popup: To Scale/Autoscale, Directional/Straight, X/Y/Dia Scale sliders, Preserve Aspect, Hide/Show Plot - Edit panels for Open Hole, Cased Hole, Cementing, and Formation Strata with add/edit/delete - Updated toolbar with section toggles and edit buttons - Save/Download button to export edited WSON files - Responsive display controls update SVG rendering in real-time https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Adds minimum-curvature survey calculation and directional SVG rendering: - WellDirection class: minimum-curvature algorithm converts (MD, Inc, Az) survey stations to (Northing, TVD) using ratio-factor method - buildDirPath(): generates directionally-warped SVG polygon paths for symmetric well sections (open hole, casing, completions) - buildDirSide(): generates one-sided annular polygons for cement fill between borehole wall and casing string - geo derived now extracts wellProfile/survey data from WSON, builds WellDirection instance, computes canvas extents from max deviation - dirAxis: curved SVG centerline following wellbore trajectory - syD(): depth → SVG-y using TVD instead of MD in directional mode - Directional toggle disabled with indicator when no survey data found - Canvas width auto-expands to fit horizontal well deviation https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
…c endpoint - Add /api/schematic POST endpoint with pure-JS arc geometry (no turf dependency): controlSegment, buildSegments, autoNodes DTX with shoelace area formula - Port WellDirection class to match dlis exactly: dirWarp([x,y]) uses slerp between q1u/q2u for proper arc interpolation, getPerpendicular2D for offsets - Add txPoint() unified coordinate transform covering all 4 modes: straight/directional × normal/autoscale - Fix canvas extent calculation: replace wellDir.getPos() with wellDir.dirWarp([0,md]) - Handle dlis config.* nested WSON format (openHole, casedHole, etc.) - Build verified clean https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
- geo derived now uses getSrc() matching fetchDirData — fixes dlis config.* format - completions _top/_bot support both top/bot absolute depths and cursor+length format - fetchDirData nodes handle completions with top/bot or length, perforations guarded - Add default node [0, maxDepth] when no completions/perfs found (matches dlis) - autoNodes: skip zero-length intervals, guard against Infinity weights https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
- perfArrows rewritten to use txPoint — handles directional arc-slerp + autoscale DTX - wellDir and dtx exposed from geo derived for use in template - Perforation arrows correctly offset perpendicular to the well in directional mode https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
…mode - jsonToSvgContent now builds paths in raw coords (diameter inches, depth meters) then applies txPoint per-point — matches dlis buildComponent.ts approach - hasDir, wellDir, dtx, autoScale from geo passed through to transform function - Component shapes now follow arc-slerp path in directional mode + respect DTX https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Initial tree only loads 2 levels; recursively fetch subfolders to find first file of each target type regardless of depth. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Move deep Drive search to /api/dev-tabs endpoint — single client round-trip instead of many sequential client fetches. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Data arrives synchronously in onMount — no async race condition. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Single search query per extension — instant instead of many sequential folder fetches across deep directory tree. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
static/activeTabs.json lists filenames to search on Drive and open on load. Edit the file to change which tabs appear automatically. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Matches dlis approach: find activeTabs.json in Drive workspace folder, parse tabs entries, resolve each file ID by name search, return for auto-opening on load. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Watches datasourceStore.tree, traverses path with lazy folder loading, calls tabStore.openFile matching exact sidebar-click behaviour. Hardcoded paths live in src/lib/samples/index.js. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Case-insensitive path lookup so minor name differences are tolerated. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
…-style edit panels - Add reusable FloatingPanel component (draggable, frosted glass, gradient header) - Collapse all layer toggles+edit buttons into a single Layers toolbar button - Layers panel shows toggle switches + edit pencil for each layer - Display Options and Edit panels now use FloatingPanel (draggable, resizable) - Toolbar reduced to 3 buttons: Info | Layers | Display https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Module-level variable survives route transitions — sample tabs open once per browser session, not on every page remount. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Module-level Map caches displayOpts + layer visibility per tab.id. Directional mode, scale settings and layer toggles now survive tab switching and navigation. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Replace four separate edit FloatingPanels with a single tabbed 'Schematic Editor' floating panel (OH | CH | Cement | Strata tabs). Clicking ✎ in the Layers panel opens the editor at the right tab. Added Edit toolbar button to toggle the editor directly. Enter key saves inline row edits; compact dlis-style table design. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Adds a 5th tab ('Completions') to the unified schematic editor FloatingPanel.
Follows dlis PopupCompletionsEditor pattern:
- Search bar filters by description/tool_comp with count display
- Card list shows description, tool_comp, OD/length/weight, joints info
- ↑/↓ reorder buttons, ✎ edit, ✕ delete per card
- Inline add/edit form (2-col grid, blue-50 bg, Enter-to-save)
- Fields: description, tool_comp, OD, OD multiplier, length, weight,
no. joints, avg joint length
- Completions layer row ✎ button now links to comp tab
https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
- Move completions editor out of schematic editor into its own FloatingPanel (400px wide, opens from toolbar ⚙ button) - Typeahead dropdown appears below search input while typing, showing matching completions as compact rows (description + tool_comp/OD/length) clicking a row jumps straight to its inline edit form - Full list always visible below, with ↑↓ reorder, ✎ edit, ✕ delete - Active edit row highlighted blue in the list - Remove 'comp' tab from schematic editor tabs https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
- Install xlsx package
- POST /api/schematic { action: 'filtercomps', q } loads comp_list.xlsx
from static/ at server startup; multi-word search against search_string
column (all words must match); returns up to 30 items
- Completions Editor search now calls the API (200ms debounce)
and shows a dropdown of catalog matches with a 'Catalog — click to
pre-fill form' header; selecting an item populates the Add form fields
(description, tool_comp, od, od_multiplier, length, weight, joints)
- Falls back gracefully when comp_list.xlsx is absent
- Place comp_list.xlsx in static/ to enable catalog search
https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
57 completion components with fields: comp_id, category, sub_category, description, od, length, weight, company, grade, tool_comp, search_string, etc. Powers the filtercomps API for catalog search in the Completions Editor. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
interactivity() must be called inside a Canvas child component, not at page script level. Removing it since the test page doesn't need click interaction on 3D objects. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Threlte requires OrbitControls to be a child of a Camera component, not a sibling. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
- Extend dgeo format with `operator` field per horizon ("none"|"RA"|"RAI"|"RB"|"RBI")
- DgeoApp: operator selector buttons in horizon list strip (5 small buttons per horizon)
- DgeoApp: SVG line styling by operator — RA/RAI=dashed, RB/RBI=bold, none=default
- DgeoApp: addHorizon/initDefault/loadFile/toJSON all handle operator field
- manifoldSolid.js: RA/RAI clipping phase using manifold.intersect() before subtract loop
- RA: clips all shallower manifolds where the horizon cuts up through them
- RAI: clips only the immediate shallower neighbour
- RB/RBI: no change needed (standard subtract already creates correct channel body)
- W1_geology.dgeo sample updated with operator:"none" on all 6 horizons
https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
- Vertical panel (196px) replaces horizontal strip; horizons shown in user-defined array order = stratigraphic insertion order - Up/Down arrow buttons per horizon to reorder (moveHorizon()) - Operator buttons (·/RA/RAI/RB/RBI) shown per horizon with tooltips - Domain X/Depth inputs moved into the bottom of the panel - 2D SVG bands still use depth-sorted horizons for correct visual display - 3D view receives unsorted horizons so buildLayerSolids processes in order - manifoldSolid.js: removed depth sort; processes in received array order with degenerate-layer guard (triVerts.length === 0) https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
- Remove vertical side panel; replace with FloatingPanel triggered from toolbar - Toolbar button (table icon) toggles the Horizons panel - Panel shows tabular list: ↑↓ | color | name | ref depth (m) | operators | delete - Ref depth input shows avg depth of horizon points; changing it shifts all points - Up/down arrows reorder horizons in stratigraphic array order - Operator buttons ·/RA/RAI/RB/RBI per row with descriptive tooltips - Domain inputs restored to 2D view bar https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
- Add operator reference legend at bottom of panel (·/RA/RAI/RB/RBI) with full descriptions of each geological operator - Color-code active operator buttons: green=deposit, orange=RA/RAI, purple=RB/RBI - Full tooltips on each operator button describing exact geometric effect - Legend uses matching color coding for quick visual identification https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
- Panel width: 520 → 340px (fits ~360px mobile screens) - Table column widths tightened: ↑↓=22, swatch=16, depth=58, ops=112, del=16 - Row gap reduced 6→4px; padding tightened https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
- Setting camera up to [0,0,-1] makes OrbitControls treat depth (Z) as the orbit axis, so horizontal drag rotates around the stratigraphic column as expected in geological viewing - Position camera above and in front of the block (-Z = above surface) - minPolarAngle=0.05 allows near-bird's-eye view - maxPolarAngle=PI*0.72 limits tilt to ~130° to prevent flipping below - Wider fov (50) and far=500 for better scene coverage https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Adds a 📏 Ruler toggle button in the 3D controls bar that displays three calibrated rulers on the block edges: - Depth ruler (right face, Z-axis): tick marks in metres - Distance ruler (front-bottom edge, X-axis): tick marks in km - Strike ruler (right-bottom edge, Y-axis): tick marks in km Rulers use HTML labels via @threlte/extras HTML component so they always face the camera and remain legible at any orbit angle. Geometry is derived and disposed correctly on reactive updates. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Previously each horizon's solid spanned surface → horizon depth, so the first solid appeared as a block at the top of the view. Geologically, deposition fills from the horizon depth DOWN to the model base. - Warp formula: vert[2] = hz + (WY - hz) * vert[2] / WY (top face → horizon depth, base face stays at WY) - Subtraction flipped: mf[i].subtract(mf[i+1]) — shallower minus deeper gives the inter-horizon band; deepest layer = mf[last] alone (to base) - RA/RAI intersect clipping still correct with bottom-up solids https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Adds smooth NURBS surface rendering alongside the existing bilinear surfaces for comparison, and real-time intersection curves on a sliding slice plane — all using WebGL (works on iOS and all browsers). Architecture: - nurbs/railsToNURBS.js: converts rails → NURBSSurfaceParams; pads to ≥4 rails by interpolating intermediate rails in the largest gap, ensuring cubic degree in the V (strike) direction - nurbs/nurbsEval.glsl.js: GLSL fragment shader porting the WGSL compute shader from pyenthu/dlis — evaluates one NURBS surface point per fragment via Cox-de Boor basis functions - nurbs/nurbsGpgpu.js: WebGL GPGPU evaluator using Three.js float render target + readRenderTargetPixels; caches vertex positions - Dgeo3DView.svelte: 〜 NURBS toggle + Slice slider (0..strikeKm) - Dgeo3DScene.svelte: NURBS mesh overlay at 38% opacity with wireframe, slice curves extracted per-frame from cached vertex grid (CPU O(res)), purple slice plane that moves with the slider Existing bilinear surfaces unchanged; NURBS is additive overlay only. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
- width: min(560px, calc(100vw - 16px)) — shrinks on narrow screens - initial left position: 8px (was 40px) — stays on-screen on mobile - rail strip max-width: min(280px, 40vw) — prevents header overflow https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
The $effect that built nurbsCache was both reading it (in the disposal loop) and writing it. In Svelte 5 this creates an infinite re-run cycle that freezes all UI event handling — buttons stop responding, including Add Horizon and the horizons table toggle. Fix: use untrack() around nurbsCache writes so the effect doesn't register a read-dependency on the value it produces. Disposal is handled exclusively by the separate cleanup effect which only reads in its teardown function. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
- Replace WebGL GPGPU NURBS evaluator with CPU Cox-de Boor (nurbsCpu.js) World-space coords (0–10) were being clipped to [0,1] by RGBA8 float texture fallback on many devices, causing surfaces to appear at the wrong position. CPU evaluation is ~5 ms for a 40×40 grid and works everywhere. - Default rail count raised to 10 (configurable via "Rails:" number input in the 3D toolbar). addHorizon() now persists evenly-spaced rails; getRails() fallback also uses defaultRailCount for legacy horizons. - Rename "Slice:" → "Y:" for the strike-direction slice slider. - Remove untrack() hack; nurbsCache is now a clean $derived.by(). https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
- nurbsGpgpu.js: normalise control points to [0,1] before GPU upload, denormalise on readback — fixes surfaces appearing at top of block when the device falls back from FloatType to RGBA8 render targets (which clips world-space coords > 1.0) - Dgeo3DScene: create NurbsGpgpu synchronously as a plain (non-reactive) variable + onDestroy cleanup; eliminates the reactive loop that was caused by gpgpu being $state (write in $effect → nurbsCache derived recomputes → disposal $effect triggers → repeat) - NurbsCpu kept as silent fallback in the evaluator loop https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Adds NurbsWebGpu — a WebGPU compute shader NURBS evaluator using the WGSL shader from pyenthu/dlis shaders/compute.wgsl. Adaptations from the original: - positionUniform removed (world-space control points, no offset needed) - Output: 1 vec4/vertex (position only; Three.js computes normals on CPU) - Bindings renumbered 0–4 - Control point index changed from U-major to V-major to match railsToNURBS() layout: cpIndex = (startV + l) * numControlPointsU + (startU + k) Evaluator chain: WebGPU (async init) → WebGL GPGPU → CPU. Dgeo3DScene uses an async $effect to await WebGPU evaluation; webgpuReady $state triggers a cache rebuild once the device is ready. Falls back silently to WebGL GPGPU or CPU on devices without WebGPU. iOS 26 + Chrome confirmed WebGPU support — storage buffer output avoids the RGBA8 float-clamping issue that affected the WebGL approach. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Remove sync read of nurbsCache from the !showNurbs branch — reading and writing the same $state in one $effect causes Svelte 5 to re-run infinitely. Geometry disposal is handled by the dedicated disposal $effect's cleanup fn. Also add cancellation token so stale async evaluate() results are discarded when the effect re-runs (e.g. showNurbs toggled off mid-flight). https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
adjustDepth() was only shifting h.points (the 2D profile) but not h.rails[*].points. Since the 3D surface (both normal and NURBS) is built from rail points, changing the depth in the Stratigraphic Column had no visible effect in the 3D view. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
…i-1)
Two fixes in one commit:
1. manifoldSolid.js — rewrite layer stacking to match pyenthu/dlis geostore.ts:
- Sort horizons DEEPEST FIRST (largest avg rail depth)
- Layer[0] = solid[0] (basement, no subtraction)
- Layer[i] = solid[i].subtract(solid[i-1]) for i > 0
solid[i] shallower → larger; solid[i-1] deeper → smaller; result = band ✓
- Remove RA/RAI/RB/RBI operator clipping (deposition operator only for now)
- Add avgRailDepth() helper for reliable depth sorting
2. DgeoApp.svelte — adjustDepth() now shifts h.rails[*].points by the same
delta as h.points, so changing the reference depth in the Stratigraphic
Column moves the 3D surface too (already committed separately).
https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
- Add visible:true to all horizon objects (new + default) - Add toggleVisibility(id) that flips h.visible and marks dirty - Eye button in each row (blue=visible, grey=hidden) with SVG icons - Dgeo3DScene: filter surfaces, NURBS cache, and solid block rendering by h.visible !== false so hidden horizons disappear instantly in 3D https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Wrap all NURBS meshes, slice curves, and slice plane in a T.Group offset by WX+1.5 in X so the NURBS surfaces appear to the right of the geological block rather than overlapping it. Also increase NURBS opacity to 0.75 and add a ghost wireframe outline box behind the NURBS panel. https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Prevents sweep self-intersections by ensuring every rail always touches the left and right walls of the cross-section. Drag locking (2D + 3D): - onSvgMouseMove: identify leftmost/rightmost point by X value; lock its X to domX.min / domX.max while leaving Y (depth) free to move - onDragMove (3D rail editor): same logic for rail control points Geometry building (defensive): - buildGridGeo: sort rail points by X before arc-length sampling, then snap sampled[0].x = domX.min, sampled[last].x = domX.max - railsToNURBS: same sort + snap; domX now passed as opt - buildSolidManifold (manifoldSolid.js): same sort + snap; domX threaded through buildLayerSolids → opts https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
- DgeoApp: viewMode '2d' → '3d', showSolids false → true - Dgeo3DView: showNurbs false → true https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
buildNurbsLayerSolids() in manifoldSolid.js: - Takes the GPU-evaluated NURBS positions array per horizon - buildNurbsSolid(): bilinearly interpolates the NURBS Z-grid inside manifold warp() — same closed-solid technique as buildSolidManifold but driven by the high-quality NURBS surface instead of the bilinear grid - Sorts deepest-first by avg surface Z, then subtracts: solid[i] - solid[i-1] - Same CSG deposition logic as the bilinear path Dgeo3DScene.svelte: - Adds id field to nurbsCache entries for identification - New nurbsSolidBlocks $state + async $effect: rebuilds whenever nurbsCache or showSolids changes (with cancellation) - NURBS T.Group shows solid blocks when Solidify is on, falls back to raw NURBS surfaces while building or when Solidify is off Result: left panel = bilinear manifold CSG, right panel = NURBS manifold CSG https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
1. Dgeo3DView: editRailsSorted fallback generates defaultRailCount (10) evenly-spaced rails instead of 2 when a horizon has no saved rails 2. DgeoEditPopup: popup is now full-width (left:8px; right:8px; calc(100%-16px)) and only draggable in Y — no more horizontal drift off-screen; editor body height raised to 300px 3. Dgeo2DRailEditor: clicking to add a point now inserts it at the correct X-sorted position instead of appending to the end; polyline uses a sorted-by-X copy (ptsLine) so it always draws left→right; drag/delete still use the original-order pts array for correct index tracking https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
Geometry builders (buildGridGeo, railsToNURBS, buildSolidManifold): - Remove X-sort on rail points before sampleArcLength — arc-length order is now preserved so folds that double back in X render correctly - Endpoint snap stays, but keyed to array index 0 / last, not min/max X Drag locking (2D + 3D): - Endpoint detection now uses array index 0 and n-1 (not min/max X find) - First point always locked to domX.min, last to domX.max; middle points free Dgeo2DRailEditor: - onSvgClick: remove X-sort; insert new point between the two consecutive neighbours whose segment midpoint is closest to the click position - ptsLine removed; polyline draws in arc-length (insertion) order so folds are visible in the editor - pts stays in original order for drag/delete index tracking https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
polyStr() and bandPath() now use insertion/arc-length order matching the
underlying data. The {@const sorted} template variable is gone; label
placement uses the last point (right wall endpoint) directly.
https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
- MAX_CP 64→512, MAX_KNOT 16→40 in GLSL shader (supports 36 U × 14 V) - nurbsGpgpu.js: pre-allocate 512 CP uniforms, knot arrays of 40 - nCtrlU now derived from actual rail point count (clamped to 36) instead of the hardcoded 8, so fold geometry with many points is faithfully captured https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
When clicking '+ Add horizon', a modal opens with 6 preset shapes:
- Flat, Dome (anticline), Undulating (sinusoidal)
- Fold (anticline-syncline), Fold forward (right-vergent overturned),
Fold backward (left-vergent overturned)
Fold forward/backward presets generate points that actually double back
in X, creating genuine overturned fold geometry compatible with the
arc-length NURBS parameterization.
Each preset populates both points[] (2D cross-section) and rails[]
(3D, one rail per defaultRailCount position across strike).
https://claude.ai/code/session_012tQZKTp1FJbrKf8PsyVMLd
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The project has grown from a simple Hello World into a full well-data
visualization app with DLIS/LAS/WSON viewers, a tab system, app registry,
and Google Drive integration. All CLAUDE.md files now document the actual
current architecture, components, state management, and conventions.
https://claude.ai/code/session_0124NnsMao3HQF3u2smci3Ho