arrayview 0.13.0__tar.gz → 0.15.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. {arrayview-0.13.0 → arrayview-0.15.0}/.claude/skills/ui-consistency-audit/SKILL.md +2 -2
  2. {arrayview-0.13.0 → arrayview-0.15.0}/.claude/skills/viewer-ui-checklist/SKILL.md +14 -4
  3. arrayview-0.15.0/.github/copilot-instructions.md +39 -0
  4. {arrayview-0.13.0 → arrayview-0.15.0}/.gitignore +2 -1
  5. arrayview-0.15.0/.ignore +1 -0
  6. arrayview-0.15.0/.mex/AGENTS.md +9 -0
  7. arrayview-0.15.0/.mex/ROUTER.md +86 -0
  8. arrayview-0.15.0/.mex/SETUP.md +228 -0
  9. arrayview-0.15.0/.mex/SYNC.md +62 -0
  10. arrayview-0.15.0/.mex/context/architecture.md +90 -0
  11. arrayview-0.15.0/.mex/context/conventions.md +96 -0
  12. arrayview-0.15.0/.mex/context/decisions.md +70 -0
  13. arrayview-0.15.0/.mex/context/frontend.md +140 -0
  14. arrayview-0.15.0/.mex/context/project-state.md +34 -0
  15. arrayview-0.15.0/.mex/context/render-pipeline.md +110 -0
  16. arrayview-0.15.0/.mex/context/setup.md +66 -0
  17. arrayview-0.15.0/.mex/context/stack.md +59 -0
  18. arrayview-0.15.0/.mex/patterns/INDEX.md +29 -0
  19. arrayview-0.15.0/.mex/patterns/README.md +170 -0
  20. arrayview-0.15.0/.mex/patterns/add-file-format.md +96 -0
  21. arrayview-0.15.0/.mex/patterns/add-server-endpoint.md +86 -0
  22. arrayview-0.15.0/.mex/patterns/debug-render.md +126 -0
  23. arrayview-0.15.0/.mex/patterns/frontend-change.md +98 -0
  24. arrayview-0.15.0/.opencode/opencode.json +4 -0
  25. arrayview-0.15.0/.vscode/settings.json +208 -0
  26. arrayview-0.15.0/AGENTS.md +50 -0
  27. {arrayview-0.13.0 → arrayview-0.15.0}/CONTRIBUTING.md +1 -2
  28. arrayview-0.15.0/IMMERSIVE_ANIMATION.md +43 -0
  29. {arrayview-0.13.0 → arrayview-0.15.0}/PKG-INFO +1 -1
  30. {arrayview-0.13.0 → arrayview-0.15.0}/docs/display.md +1 -1
  31. {arrayview-0.13.0 → arrayview-0.15.0}/docs/loading.md +5 -0
  32. {arrayview-0.13.0 → arrayview-0.15.0}/docs/viewing.md +1 -1
  33. arrayview-0.15.0/plans/2026-04-14-immersive-animation.md +388 -0
  34. {arrayview-0.13.0 → arrayview-0.15.0}/pyproject.toml +1 -1
  35. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/ARCHITECTURE.md +41 -12
  36. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/_app.py +2 -1
  37. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/_io.py +8 -0
  38. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/_launcher.py +281 -172
  39. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/_render.py +86 -66
  40. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/_server.py +112 -41
  41. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/_session.py +106 -17
  42. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/_shell.html +80 -27
  43. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/_stdio_server.py +51 -13
  44. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/_viewer.html +3149 -632
  45. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/_vscode.py +221 -77
  46. arrayview-0.15.0/src/arrayview/arrayview-opener.vsix +0 -0
  47. arrayview-0.15.0/src/arrayview/gsap.min.js +11 -0
  48. {arrayview-0.13.0 → arrayview-0.15.0}/tests/test_api.py +86 -0
  49. {arrayview-0.13.0 → arrayview-0.15.0}/tests/test_browser.py +34 -2
  50. {arrayview-0.13.0 → arrayview-0.15.0}/tests/test_command_reachability.py +1 -1
  51. arrayview-0.15.0/tests/test_cross_mode_parametrized.py +214 -0
  52. {arrayview-0.13.0 → arrayview-0.15.0}/tests/test_interactions.py +45 -23
  53. arrayview-0.15.0/tests/test_loading_server.py +107 -0
  54. {arrayview-0.13.0 → arrayview-0.15.0}/tests/test_mode_roundtrip.py +3 -1
  55. arrayview-0.15.0/tests/test_view_component_integration.py +381 -0
  56. arrayview-0.15.0/tests/test_view_component_unit.py +165 -0
  57. {arrayview-0.13.0 → arrayview-0.15.0}/tests/visual_smoke.py +135 -44
  58. {arrayview-0.13.0 → arrayview-0.15.0}/uv.lock +1 -1
  59. arrayview-0.15.0/vscode-extension/AGENTS.md +26 -0
  60. {arrayview-0.13.0 → arrayview-0.15.0}/vscode-extension/extension.js +85 -10
  61. {arrayview-0.13.0 → arrayview-0.15.0}/vscode-extension/package.json +11 -1
  62. arrayview-0.13.0/AGENTS.md +0 -53
  63. arrayview-0.13.0/src/arrayview/arrayview-opener.vsix +0 -0
  64. {arrayview-0.13.0 → arrayview-0.15.0}/.claude/skills/invocation-consistency/SKILL.md +0 -0
  65. {arrayview-0.13.0 → arrayview-0.15.0}/.claude/skills/modes-consistency/SKILL.md +0 -0
  66. {arrayview-0.13.0 → arrayview-0.15.0}/.claude/skills/visual-bug-fixing/SKILL.md +0 -0
  67. {arrayview-0.13.0 → arrayview-0.15.0}/.github/workflows/docs.yml +0 -0
  68. {arrayview-0.13.0 → arrayview-0.15.0}/.github/workflows/python-publish.yml +0 -0
  69. {arrayview-0.13.0 → arrayview-0.15.0}/.python-version +0 -0
  70. {arrayview-0.13.0 → arrayview-0.15.0}/LICENSE +0 -0
  71. {arrayview-0.13.0 → arrayview-0.15.0}/README.md +0 -0
  72. {arrayview-0.13.0 → arrayview-0.15.0}/docs/comparing.md +0 -0
  73. {arrayview-0.13.0 → arrayview-0.15.0}/docs/configuration.md +0 -0
  74. {arrayview-0.13.0 → arrayview-0.15.0}/docs/index.md +0 -0
  75. {arrayview-0.13.0 → arrayview-0.15.0}/docs/logo.png +0 -0
  76. {arrayview-0.13.0 → arrayview-0.15.0}/docs/measurement.md +0 -0
  77. {arrayview-0.13.0 → arrayview-0.15.0}/docs/remote.md +0 -0
  78. {arrayview-0.13.0 → arrayview-0.15.0}/docs/stylesheets/extra.css +0 -0
  79. {arrayview-0.13.0 → arrayview-0.15.0}/matlab/arrayview.m +0 -0
  80. {arrayview-0.13.0 → arrayview-0.15.0}/mkdocs.yml +0 -0
  81. {arrayview-0.13.0 → arrayview-0.15.0}/plans/webview/LOG.md +0 -0
  82. {arrayview-0.13.0 → arrayview-0.15.0}/scripts/demo.py +0 -0
  83. {arrayview-0.13.0 → arrayview-0.15.0}/scripts/release.sh +0 -0
  84. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/__init__.py +0 -0
  85. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/__main__.py +0 -0
  86. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/_config.py +0 -0
  87. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/_icon.png +0 -0
  88. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/_platform.py +0 -0
  89. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/_segmentation.py +0 -0
  90. {arrayview-0.13.0 → arrayview-0.15.0}/src/arrayview/_torch.py +0 -0
  91. {arrayview-0.13.0 → arrayview-0.15.0}/tests/conftest.py +0 -0
  92. {arrayview-0.13.0 → arrayview-0.15.0}/tests/make_vectorfield_test_arrays.py +0 -0
  93. {arrayview-0.13.0 → arrayview-0.15.0}/tests/test_cli.py +0 -0
  94. {arrayview-0.13.0 → arrayview-0.15.0}/tests/test_config.py +0 -0
  95. {arrayview-0.13.0 → arrayview-0.15.0}/tests/test_large_arrays.py +0 -0
  96. {arrayview-0.13.0 → arrayview-0.15.0}/tests/test_mode_consistency.py +0 -0
  97. {arrayview-0.13.0 → arrayview-0.15.0}/tests/test_mode_matrix.py +0 -0
  98. {arrayview-0.13.0 → arrayview-0.15.0}/tests/test_nifti_meta.py +0 -0
  99. {arrayview-0.13.0 → arrayview-0.15.0}/tests/test_rgb_pixel_art.py +0 -0
  100. {arrayview-0.13.0 → arrayview-0.15.0}/tests/test_torch.py +0 -0
  101. {arrayview-0.13.0 → arrayview-0.15.0}/tests/ui_audit.py +0 -0
  102. {arrayview-0.13.0 → arrayview-0.15.0}/vscode-extension/LICENSE +0 -0
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: ui-consistency-audit
3
- description: Use when implementing or modifying any visual feature, layout, keyboard shortcut, or mode-specific behavior in arrayview. Proactively identifies all affected mode combinations before coding, prescribes per-mode behavior, checks for UI clashes, and runs a Playwright-based visual audit after implementation. Absorbs and replaces the modes-consistency skill.
3
+ description: Use when the user explicitly requests a full visual audit, when validating UI work for a release, or when diagnosing a cross-mode visual regression in arrayview. Proactively identifies all affected mode combinations, prescribes per-mode behavior, checks for UI clashes, and runs a Playwright-based visual audit after implementation. Absorbs and replaces the modes-consistency skill.
4
4
  ---
5
5
 
6
6
  # ArrayView UI Consistency Audit
7
7
 
8
8
  ## Rule
9
9
 
10
- Every visual change must be verified across **all applicable mode × array-count combinations** before it ships. This skill has two phases: a **proactive phase** (before coding) that plans the cross-mode behavior, and a **reactive phase** (after coding) that runs an automated visual audit.
10
+ This is the **full** visual audit path. Do not invoke it by default for every UI change. During normal feature development, do targeted verification for the specific area touched. Use this skill when the user explicitly asks for a broad visual check, when a regression spans modes/layouts, or when validating UI work for a release. This skill has two phases: a **proactive phase** (before coding) that plans the cross-mode behavior, and a **reactive phase** (after coding) that runs an automated visual audit.
11
11
 
12
12
  ---
13
13
 
@@ -1,13 +1,15 @@
1
1
  ---
2
2
  name: viewer-ui-checklist
3
- description: Use when adding keyboard shortcuts, changing layout, or making any UI change to arrayview. Ensures visual_smoke.py, help overlay, and README stay in sync.
3
+ description: Use when the user explicitly asks to sync UI docs/help/test coverage, or when preparing a UI change for release. Ensures visual_smoke.py, help overlay, and docs/ stay in sync.
4
4
  ---
5
5
 
6
6
  # ArrayView UI Checklist
7
7
 
8
8
  ## Rule
9
9
 
10
- Every UI change to arrayview MUST be reflected in `tests/visual_smoke.py`, the help overlay, and (when user-facing) `README.md` before the task is complete.
10
+ This is the release/explicit-sync checklist for UI work. Do not invoke it by default for every UI edit during development. Use it when the user explicitly asks for the full sync, or when preparing a UI change for release.
11
+
12
+ `README.md` is intentionally minimal and stable — do **not** add per-feature shortcuts or behavior to it. User-facing docs live in `docs/` and are organized by topic (`display.md`, `viewing.md`, `comparing.md`, `loading.md`, `measurement.md`, `remote.md`, `configuration.md`).
11
13
 
12
14
  ## What counts as a UI change
13
15
 
@@ -17,7 +19,7 @@ Every UI change to arrayview MUST be reflected in `tests/visual_smoke.py`, the h
17
19
  - Layout changes (canvas sizing, colorbar position, overlays)
18
20
  - New overlay, dialog, or panel
19
21
 
20
- ## Steps (mandatory, in order)
22
+ ## Steps (when this checklist is invoked)
21
23
 
22
24
  1. **Update coverage table** at the top of `visual_smoke.py`
23
25
  - If shortcut is now testable: change `✗` to `✓ NN` with scenario number
@@ -40,8 +42,16 @@ Every UI change to arrayview MUST be reflected in `tests/visual_smoke.py`, the h
40
42
  - Include a `hint` for non-obvious shortcuts
41
43
  - Use the `docs-style` skill for formatting rules
42
44
 
43
- 6. **Update `README.md`** if the change is user-facing (new CLI flag, new API, new mode)
45
+ 6. **Update the matching `docs/*.md` page** for any user-facing change. Pick the page by topic:
46
+ - `display.md` — colormaps, range, log scale, themes, masking, layout toggles
47
+ - `viewing.md` — navigation, zoom, slice/dim shortcuts, multiview, projections
48
+ - `comparing.md` — compare mode, overlay, diff, registration
49
+ - `loading.md` — file formats, CLI, Python/Julia/MATLAB API
50
+ - `measurement.md` — ROI, hover, pixel info
51
+ - `remote.md` — VS Code Remote, tunneling
52
+ - `configuration.md` — settings, env vars, persistence
44
53
  - Use the `docs-style` skill for formatting rules
54
+ - Do **not** touch `README.md` for per-feature changes — it's intentionally stable
45
55
 
46
56
  ## Red flags — STOP
47
57
 
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: agents
3
+ description: Always-loaded project anchor. Read this first. Contains project identity, non-negotiables, commands, and pointer to ROUTER.md for full context.
4
+ last_updated: [YYYY-MM-DD]
5
+ ---
6
+
7
+ # [Project Name]
8
+
9
+ ## What This Is
10
+ <!-- One sentence. What does this project do?
11
+ Length: 1 sentence maximum.
12
+ Not a tagline — a factual description of what the software does.
13
+ Example: "A REST API for managing inventory across multiple warehouse locations." -->
14
+
15
+ ## Non-Negotiables
16
+ <!-- Hard rules the agent must never violate. Not preferences — rules.
17
+ These are the things that, if broken, cause real damage to the codebase.
18
+ Length: 3-7 items maximum. More than 7 means the list has not been prioritised.
19
+ Example:
20
+ - Never write database queries outside of the repository layer
21
+ - Never commit secrets or API keys
22
+ - Always handle errors explicitly — no silent failures -->
23
+
24
+ ## Commands
25
+ <!-- The exact commands needed to work on this project.
26
+ Include: run dev server, run tests, run linter, build.
27
+ Use the actual commands from this codebase — not placeholders.
28
+ Example:
29
+ - Dev: `npm run dev`
30
+ - Test: `npm test`
31
+ - Lint: `npm run lint`
32
+ - Build: `npm run build` -->
33
+
34
+ ## After Every Task
35
+ After completing any task: update `.mex/ROUTER.md` project state and any `.mex/` files that are now out of date. If no pattern existed for the task you just completed, create one in `.mex/patterns/`.
36
+
37
+ ## Navigation
38
+ At the start of every session, read `.mex/ROUTER.md` before doing anything else.
39
+ For full project context, patterns, and task guidance — everything is there.
@@ -33,4 +33,5 @@ site/
33
33
  van_gogh/
34
34
  cig_presentation/
35
35
  docs/superpowers
36
- .playwright-mcp/
36
+ .playwright-mcp/
37
+ dev/TODO.md
@@ -0,0 +1 @@
1
+ .worktrees/
@@ -0,0 +1,9 @@
1
+ ---
2
+ name: agents
3
+ description: Lightweight pointer to ROUTER.md for task routing.
4
+ last_updated: 2026-04-14
5
+ ---
6
+
7
+ # arrayview
8
+
9
+ Use `.mex/ROUTER.md` only when you need project state, routing, or a matching task pattern.
@@ -0,0 +1,86 @@
1
+ ---
2
+ name: router
3
+ description: Navigation hub for task routing, project state, and behavioral guidance. Start here, then load the minimum extra context needed for the task.
4
+ edges:
5
+ - target: context/project-state.md
6
+ condition: when the task depends on what is currently shipped, in progress, or recently changed
7
+ - target: context/architecture.md
8
+ condition: when working on system design, integrations, or understanding how components connect
9
+ - target: context/stack.md
10
+ condition: when working with specific technologies, libraries, or making tech decisions
11
+ - target: context/conventions.md
12
+ condition: when writing new code, reviewing code, or unsure about project patterns
13
+ - target: context/decisions.md
14
+ condition: when making architectural choices or understanding why something is built a certain way
15
+ - target: context/setup.md
16
+ condition: when setting up the dev environment or running the project for the first time
17
+ - target: context/frontend.md
18
+ condition: when working on _viewer.html — modes, reconcilers, command registry, View Component System
19
+ - target: context/render-pipeline.md
20
+ condition: when working on rendering, colormaps, LUTs, caching, or the render thread
21
+ - target: patterns/INDEX.md
22
+ condition: when starting a task — check the pattern index for a matching pattern file
23
+ last_updated: 2026-04-15
24
+ ---
25
+
26
+ # arrayview — Router
27
+
28
+ ## What This Is
29
+ Python package for interactively viewing multi-dimensional arrays (numpy, NIfTI, zarr, etc.) with a FastAPI backend, single-file HTML/JS frontend, and multi-environment display routing (Jupyter, VS Code, SSH, native window).
30
+
31
+ ## Non-Negotiables
32
+ - Never split `_viewer.html` — entire frontend is one self-contained file, no build step
33
+ - All heavy imports (numpy, matplotlib, nibabel, FastAPI, uvicorn) must be lazy — CLI fast path stays near-zero cost
34
+ - New rendering features must be consistent across all six invocation environments
35
+ - Global state lives in `_session.py` only — `SESSIONS`, `SERVER_LOOP`, `VIEWER_SOCKETS` never redefined elsewhere
36
+ - Render thread must remain a raw `threading.Thread` + `SimpleQueue`, not `concurrent.futures`
37
+
38
+ ## Commands
39
+ - Test: `uv run pytest tests/`
40
+ - Visual smoke: `uv run pytest tests/visual_smoke.py`
41
+ - CLI: `uvx arrayview <file>`
42
+ - Build: `uv build`
43
+
44
+ ## Context Budget
45
+
46
+ 1. Start with this file plus **at most one pattern and one context file**.
47
+ 2. Treat frontmatter `edges` as **optional suggestions**, not a preload list.
48
+ 3. Follow **one extra edge only when blocked**. Do not recursively fan out through second-hop edges.
49
+ 4. Load `context/project-state.md` only when the task depends on current shipped or in-progress work.
50
+ 5. For UI, animation, or behavior bugs: ask plain-English clarification questions **before** reading git history, large diffs, or broad source sweeps.
51
+
52
+ ## Current Project State
53
+
54
+ Load `context/project-state.md` only when you need active-workstream or recent-shipping detail.
55
+
56
+ ## Routing Table
57
+
58
+ | Task type | Load |
59
+ |-----------|------|
60
+ | Checking current shipped / in-progress status | `context/project-state.md` |
61
+ | Understanding system architecture | `context/architecture.md` |
62
+ | Working with a specific technology | `context/stack.md` |
63
+ | Writing or reviewing code | `context/conventions.md` |
64
+ | Making a design decision | `context/decisions.md` |
65
+ | Setting up or running the project | `context/setup.md` |
66
+ | Editing `_viewer.html` (frontend) | `context/frontend.md` + `patterns/frontend-change.md` |
67
+ | Render pipeline, colormaps, caching | `context/render-pipeline.md` |
68
+ | Adding a new file format | `patterns/add-file-format.md` |
69
+ | Adding a server route / WebSocket endpoint | `patterns/add-server-endpoint.md` |
70
+ | Visual bugs / render artifacts | `patterns/debug-render.md` |
71
+ | Any specific task | Check `patterns/INDEX.md` for a matching pattern |
72
+
73
+ ## Behavioural Contract
74
+
75
+ 1. **CONTEXT** — Load from the routing table. Start small: this file + one pattern + one context file is the default cap. Do not preload unrelated docs.
76
+ 2. **CLARIFY** — If the task is about UI behavior, animation, or UX expectations, ask plain-English questions before deep investigation.
77
+ 3. **BUILD** — Do the work. If deviating from an established pattern, say so before writing code.
78
+ 4. **VERIFY** — If a pattern file was loaded, use its Verify section. Otherwise use the shared Verify Checklist in `context/conventions.md`.
79
+ 5. **DEBUG** — If verification fails, check `patterns/INDEX.md` for one debug pattern, fix, then re-run VERIFY.
80
+ 6. **GROW** — After completing the task: create/update patterns, update stale context files, and update `context/project-state.md` if significant.
81
+
82
+ ## After Completing a Task
83
+
84
+ - [ ] Update `context/project-state.md` if shipped or in-progress status changed
85
+ - [ ] Update any stale `.mex/context/` or `.mex/patterns/` files touched by the task
86
+ - [ ] If this revealed a repeatable workflow, add or update a pattern in `.mex/patterns/`
@@ -0,0 +1,228 @@
1
+ # Setup — Populate This Scaffold
2
+
3
+ This file contains the prompts to populate the scaffold. It is NOT the dev environment setup — for that, see `context/setup.md` after population.
4
+
5
+ This scaffold is currently empty. Follow the steps below to populate it for your project.
6
+
7
+ ## Recommended: Use setup.sh
8
+
9
+ ```bash
10
+ .mex/setup.sh
11
+ ```
12
+
13
+ The script handles everything automatically:
14
+ 1. Detects your project state (existing codebase, fresh project, or partial)
15
+ 2. Asks which AI tool you use and copies the right config file
16
+ 3. Pre-scans your codebase with `mex init` to build a structured brief (~5-8k tokens vs ~50k from AI exploration)
17
+ 4. Builds and runs the population prompt — or prints it for manual paste
18
+
19
+ If you want to populate manually instead, use the prompts below.
20
+
21
+ ## Detecting Your State
22
+
23
+ **Existing codebase?** Follow Option A.
24
+ **Fresh project, nothing built yet?** Follow Option B.
25
+ **Partially built?** Follow Option A — the agent will flag empty slots it cannot fill yet.
26
+
27
+ ---
28
+
29
+ ## Option A — Existing Codebase
30
+
31
+ Paste the following prompt into your agent:
32
+
33
+ ---
34
+
35
+ **SETUP PROMPT — copy everything between the lines:**
36
+
37
+ ```
38
+ You are going to populate an AI context scaffold for this project.
39
+ The scaffold lives in the root of this repository.
40
+
41
+ Read the following files in order before doing anything else:
42
+ 1. ROUTER.md — understand the scaffold structure
43
+ 2. context/architecture.md — read the annotation comments to understand what belongs there
44
+ 3. context/stack.md — same
45
+ 4. context/conventions.md — same
46
+ 5. context/decisions.md — same
47
+ 6. context/setup.md — same
48
+
49
+ Then explore this codebase:
50
+ - Read the main entry point(s)
51
+ - Read the folder structure
52
+ - Read 2-3 representative files from each major layer
53
+ - Read any existing README or documentation
54
+
55
+ PASS 1 — Populate knowledge files:
56
+
57
+ Populate each context/ file by replacing the annotation comments
58
+ with real content from this codebase. Follow the annotation instructions exactly.
59
+ For each slot:
60
+ - Use the actual names, patterns, and structures from this codebase
61
+ - Do not use generic examples
62
+ - Do not leave any slot empty — if you cannot determine the answer,
63
+ write "[TO DETERMINE]" and explain what information is needed
64
+ - Keep length within the guidance given in each annotation
65
+
66
+ Then assess: does this project have domains complex enough that cramming
67
+ them into architecture.md would make it too long or too shallow?
68
+ If yes, create additional domain-specific context files in context/.
69
+ Examples: a project with a complex auth system gets context/auth.md.
70
+ A data pipeline gets context/ingestion.md. A project with Stripe gets
71
+ context/payments.md. Use the same YAML frontmatter format (name,
72
+ description, triggers, edges, last_updated). Only create these for
73
+ domains that have real depth — not for simple integrations that fit
74
+ in a few lines of architecture.md.
75
+
76
+ After populating context/ files, update ROUTER.md:
77
+ - Fill in the Current Project State section based on what you found
78
+ - Add rows to the routing table for any domain-specific context files you created
79
+
80
+ Update AGENTS.md:
81
+ - Fill in the project name, one-line description, non-negotiables, and commands
82
+
83
+ PASS 2 — Generate starter patterns:
84
+
85
+ Read patterns/README.md for the format and categories.
86
+
87
+ Generate 3-5 starter patterns for the most common and most dangerous task
88
+ types in this project. Focus on:
89
+ - The 1-2 tasks a developer does most often (e.g., add endpoint, add component)
90
+ - The 1-2 integrations with the most non-obvious gotchas
91
+ - 1 debug pattern for the most common failure boundary
92
+
93
+ Each pattern should be specific to this project — real file paths, real gotchas,
94
+ real verify steps derived from the code you read in Pass 1.
95
+ Use the format in patterns/README.md. Name descriptively (e.g., add-endpoint.md).
96
+
97
+ Do NOT try to generate a pattern for every possible task type. The scaffold
98
+ grows incrementally — the behavioural contract (step 5: GROW) will create
99
+ new patterns from real work as the project evolves. Setup just seeds the most
100
+ critical ones.
101
+
102
+ After generating patterns, update patterns/INDEX.md with a row for each
103
+ pattern file you created. For multi-section patterns, add one row per task
104
+ section using anchor links (see INDEX.md annotation for format).
105
+
106
+ PASS 3 — Wire the web:
107
+
108
+ Re-read every file you just wrote (context/ files, pattern files, ROUTER.md).
109
+ For each file, add or update the `edges` array in the YAML frontmatter.
110
+ Each edge should point to another scaffold file that is meaningfully related,
111
+ with a `condition` explaining when an agent should follow that edge.
112
+
113
+ Rules for edges:
114
+ - Every context/ file should have at least 2 edges
115
+ - Every pattern file should have at least 1 edge (usually to the relevant context file)
116
+ - Edges should be bidirectional where it makes sense (if A links to B, consider B linking to A)
117
+ - Use relative paths (e.g., context/stack.md, patterns/add-endpoint.md)
118
+ - Pattern files can edge to other patterns (e.g., debug pattern → related task pattern)
119
+
120
+ Important: only write content derived from the codebase.
121
+ Do not include system-injected text (dates, reminders, etc.)
122
+ in any scaffold file.
123
+
124
+ When done, confirm which files were populated and flag any slots
125
+ you could not fill with confidence.
126
+ ```
127
+
128
+ ---
129
+
130
+ ## Option B — Fresh Project
131
+
132
+ Paste the following prompt into your agent:
133
+
134
+ ---
135
+
136
+ **SETUP PROMPT — copy everything between the lines:**
137
+
138
+ ```
139
+ You are going to populate an AI context scaffold for a project that
140
+ is just starting. Nothing is built yet.
141
+
142
+ Read the following files in order before doing anything else:
143
+ 1. ROUTER.md — understand the scaffold structure
144
+ 2. All files in context/ — read the annotation comments in each
145
+
146
+ Then ask me the following questions one section at a time.
147
+ Wait for my answer before moving to the next section:
148
+
149
+ 1. What does this project do? (one sentence)
150
+ 2. What are the hard rules — things that must never happen in this codebase?
151
+ 3. What is the tech stack? (language, framework, database, key libraries)
152
+ 4. Why did you choose this stack over alternatives?
153
+ 5. How will the major pieces connect? Describe the flow of a typical request/action.
154
+ 6. What patterns do you want to enforce from day one?
155
+ 7. What are you deliberately NOT building or using?
156
+
157
+ After I answer, populate the context/ files based on my answers.
158
+ For any slot you cannot fill yet, write "[TO BE DETERMINED]" and note
159
+ what needs to be decided before it can be filled.
160
+
161
+ Then assess: based on my answers, does this project have domains complex
162
+ enough that cramming them into architecture.md would make it too long
163
+ or too shallow? If yes, create additional domain-specific context files
164
+ in context/. Examples: a project with a complex auth system gets
165
+ context/auth.md. A data pipeline gets context/ingestion.md. A project
166
+ with Stripe gets context/payments.md. Use the same YAML frontmatter
167
+ format (name, description, triggers, edges, last_updated). Only create
168
+ these for domains that have real depth — not for simple integrations
169
+ that fit in a few lines of architecture.md. For fresh projects, mark
170
+ domain-specific unknowns with "[TO BE DETERMINED — populate after first
171
+ implementation]".
172
+
173
+ Update ROUTER.md current state to reflect that this is a new project.
174
+ Add rows to the routing table for any domain-specific context files you created.
175
+ Update AGENTS.md with the project name, description, non-negotiables, and commands.
176
+
177
+ Read patterns/README.md for the format and categories.
178
+
179
+ Generate 2-3 starter patterns for the most obvious task types you can
180
+ anticipate for this stack. Focus on the tasks a developer will do first.
181
+ Mark unknowns with "[VERIFY AFTER FIRST IMPLEMENTATION]".
182
+
183
+ Do NOT try to anticipate every possible pattern. The scaffold grows
184
+ incrementally — the behavioural contract (step 5: GROW) will create
185
+ new patterns from real work as the project evolves. Setup just seeds
186
+ the most critical ones.
187
+
188
+ After generating patterns, update patterns/INDEX.md with a row for each
189
+ pattern file you created.
190
+
191
+ PASS 3 — Wire the web:
192
+
193
+ Re-read every file you just wrote (context/ files, pattern files, ROUTER.md).
194
+ For each file, add or update the `edges` array in the YAML frontmatter.
195
+ Each edge should point to another scaffold file that is meaningfully related,
196
+ with a `condition` explaining when an agent should follow that edge.
197
+
198
+ Rules for edges:
199
+ - Every context/ file should have at least 2 edges
200
+ - Every pattern file should have at least 1 edge
201
+ - Edges should be bidirectional where it makes sense
202
+ - Use relative paths (e.g., context/stack.md, patterns/add-endpoint.md)
203
+
204
+ Important: only write content derived from your answers.
205
+ Do not include system-injected text (dates, reminders, etc.)
206
+ in any scaffold file.
207
+ ```
208
+
209
+ ---
210
+
211
+ ## After Setup
212
+
213
+ **Verify** by starting a fresh session and asking your agent:
214
+ "Read `.mex/ROUTER.md` and tell me what you now know about this project."
215
+
216
+ A well-populated scaffold should give the agent enough to:
217
+ - Describe the architecture without looking at code
218
+ - Name the non-negotiable conventions
219
+ - Know which files to load for any given task type
220
+ - Know which patterns exist for common task types
221
+
222
+ ## Keeping It Fresh
223
+
224
+ Once the scaffold is populated, use these to keep it aligned with your codebase:
225
+
226
+ - **`mex check`** — detect drift (zero tokens, zero AI)
227
+ - **`.mex/SYNC.md`** — interactive drift check + targeted or full resync
228
+ - **`mex watch`** — auto drift score after every commit
@@ -0,0 +1,62 @@
1
+ # Sync — Realign This Scaffold
2
+
3
+ ## Recommended: Use sync.sh
4
+
5
+ ```bash
6
+ .mex/sync.sh
7
+ ```
8
+
9
+ The script runs drift detection first, shows you exactly what's wrong, then offers:
10
+ 1. **Targeted sync** — AI fixes only the flagged files (fastest, cheapest)
11
+ 2. **Full resync** — AI re-reads everything and updates all scaffold files
12
+ 3. **Prompt export** — shows the prompts for manual paste
13
+ 4. **Exit** — fix it yourself
14
+
15
+ ## Quick Check
16
+
17
+ ```bash
18
+ mex check # full drift report
19
+ mex check --quiet # one-liner: "drift score 85/100 (1 error)"
20
+ mex sync --dry-run # preview targeted fix prompts
21
+ ```
22
+
23
+ ## Manual Resync
24
+
25
+ If you prefer to paste a prompt manually, or don't have the CLI built:
26
+
27
+ ---
28
+
29
+ **SYNC PROMPT — copy everything between the lines:**
30
+
31
+ ```
32
+ You are going to resync the AI context scaffold for this project.
33
+ The scaffold may be out of date — the codebase has changed since it was last populated.
34
+
35
+ First, read all files in context/ to understand the current scaffold state.
36
+ Then explore what has changed in the codebase since the scaffold was last updated.
37
+ Check the last_updated dates in the YAML frontmatter of each file.
38
+
39
+ For each context/ file:
40
+ 1. Compare the current scaffold content to the actual codebase
41
+ 2. Identify what has changed, been added, or been removed
42
+ 3. Update the file to reflect the current state
43
+
44
+ Critical rules for updating:
45
+ - Use surgical, targeted edits — NOT full file rewrites. Read the existing content,
46
+ identify what changed, and update only those sections.
47
+ - PRESERVE YAML frontmatter structure. Never delete or rewrite the entire frontmatter block.
48
+ Edit individual fields only. The edges, triggers, name, and description fields must
49
+ survive every sync. If you need to update edges, add or remove individual entries —
50
+ do not replace the entire array.
51
+ - In context/decisions.md: NEVER delete existing decisions.
52
+ If a decision has changed, mark the old entry as "Superseded by [new decision title]"
53
+ and add the new decision above it with today's date.
54
+ - In all other files: update content to reflect current reality
55
+ - Update last_updated in the YAML frontmatter of every file you change
56
+ - After updating each file, update ROUTER.md Current Project State
57
+
58
+ When done, report:
59
+ - Which files were updated and what changed
60
+ - Any decisions that were superseded
61
+ - Any slots that could not be filled with confidence
62
+ ```
@@ -0,0 +1,90 @@
1
+ ---
2
+ name: architecture
3
+ description: How the major pieces of arrayview connect and flow. Load when working on system design, integrations, or understanding how components interact.
4
+ triggers:
5
+ - "architecture"
6
+ - "system design"
7
+ - "how does X connect to Y"
8
+ - "integration"
9
+ - "flow"
10
+ - "data flow"
11
+ - "display routing"
12
+ edges:
13
+ - target: context/stack.md
14
+ condition: when specific technology details are needed
15
+ - target: context/decisions.md
16
+ condition: when understanding why the architecture is structured this way
17
+ - target: context/frontend.md
18
+ condition: when the task involves _viewer.html, modes, reconcilers, or the View Component System
19
+ - target: context/render-pipeline.md
20
+ condition: when the task involves slice extraction, colormaps, caching, or the render thread
21
+ last_updated: 2026-04-15
22
+ ---
23
+
24
+ # Architecture
25
+
26
+ ## System Overview
27
+
28
+ ```
29
+ CLI / Python API (view() or uvx arrayview <file>)
30
+ └─ _launcher.py → FastAPI server (_server.py, uvicorn) [network mode]
31
+ → _stdio_server.py [VS Code direct webview]
32
+
33
+ Server (either mode)
34
+ ├─ _session.py Session objects, global state, render thread, caches
35
+ ├─ _render.py extract_slice → apply_complex_mode → render_rgba → PNG pipeline
36
+ └─ _io.py load_data() — npy/npz/nii/zarr/h5/mat/tif/pt routing
37
+
38
+ Browser (_viewer.html — single self-contained HTML+JS+CSS file)
39
+ ├─ WebSocket /ws/{sid} binary PNG slices from server
40
+ ├─ GET /meta/{sid} session metadata on first load
41
+ └─ Canvas + UI colorbars, eggs, dynamic islands, mode transitions
42
+ ```
43
+
44
+ A `view()` call creates a `Session`, starts the FastAPI server if not running,
45
+ registers the session via HTTP POST `/load`, then opens a display for the detected
46
+ environment (Jupyter inline, VS Code SimpleBrowser or direct webview, native
47
+ pywebview, or system browser).
48
+
49
+ ## Key Components
50
+
51
+ - **`_launcher.py`** — CLI parser, `view()` API, `ViewHandle`, server lifecycle, SSH relay, file watching. Heavy imports (`_session`, `_render`, `_io`, uvicorn) are all lazy to keep the CLI fast path near-zero cost.
52
+ - **`_server.py`** — FastAPI app with all REST and WebSocket routes (`/meta/{sid}`, `/load`, `/slice`, `/ws/{sid}`, `/seg/*`, `/reload`, etc.). Dispatches render work to the render thread via `_render()` from `_session.py`.
53
+ - **`_session.py`** — Single source of global mutable state: `SESSIONS`, `SERVER_LOOP`, `VIEWER_SOCKETS`, `VIEWER_SIDS`, `SHELL_SOCKETS`. Owns the render thread (`_RENDER_QUEUE`, `_RENDER_THREAD`), prefetch pool, and the `Session` class with its three LRU caches.
54
+ - **`_render.py`** — Stateless rendering functions: `extract_slice()`, `apply_complex_mode()`, `render_rgba()`, `render_rgb_rgba()`, `render_mosaic()`, `extract_projection()`. Owns colormap LUTs (`LUTS` dict, lazy-initialized by `_init_luts()`).
55
+ - **`_io.py`** — All file-format loading behind `load_data(filepath)`. Lazy nibabel import for NIfTI. Handles `.npy`, `.npz`, `.nii/.nii.gz`, `.zarr`, `.zarr.zip`, `.pt/.pth`, `.h5/.hdf5`, `.tif/.tiff`, `.mat`. Extensions registered in `_SUPPORTED_EXTS`.
56
+ - **`_platform.py`** — Environment detection: checks jupyter → vscode → julia → ssh → terminal in priority order. Results cached. Never short-circuit this order.
57
+ - **`_vscode.py`** — VS Code extension install/management, signal-file IPC, shared-memory IPC, SimpleBrowser and direct webview opening.
58
+ - **`_stdio_server.py`** — Alternative to FastAPI for VS Code tunnel (direct webview): JSON on stdin, length-prefixed binary on stdout.
59
+ - **`_viewer.html`** — The entire frontend (~15 600 lines). CSS + JS in one file, no build step. Canvas-based rendering, WebSocket binary protocol, all viewing modes, reconcilers, command registry. See `context/frontend.md`.
60
+
61
+ ## Display Routing
62
+
63
+ | Environment | Default display | Server mode |
64
+ |---|---|---|
65
+ | Jupyter | Inline iframe | network |
66
+ | VS Code local | Simple Browser | network |
67
+ | VS Code tunnel | Direct webview (stdio) | stdio |
68
+ | Julia | System browser | network |
69
+ | CLI / Python script | Native pywebview | network |
70
+ | SSH terminal | VS Code ext via TCP relay (prints URL on failure) | network |
71
+
72
+ Detection logic: `_platform.py`. Display opening: `_launcher.py` + `_vscode.py`.
73
+
74
+ ## External Dependencies
75
+
76
+ - **FastAPI + uvicorn** — async HTTP/WebSocket server, lazy-imported in `_launcher.py`. Never call uvicorn directly — use the `_uvicorn()` accessor.
77
+ - **nibabel** — NIfTI file loading. Lazy-imported in `_io.py` via `_nib()`. Only loaded for `.nii` / `.nii.gz`.
78
+ - **numpy** — Core array type throughout. The only non-lazy import in the render path.
79
+ - **matplotlib** — Colormap LUT generation only. Lazy, initialized once by `_init_luts()` in `_render.py`.
80
+ - **qmricolors** — Registers the `lipari` and `navia` colormaps. Git dependency (`oscarvanderheide/qmricolors`).
81
+ - **zarr** — Lazy chunk access for `.zarr` / `.zarr.zip`. Chunk presets via `zarr_chunk_preset()` in `_session.py`.
82
+ - **pywebview** — Native OS window. Lazy, only started when `_can_native_window()` is true.
83
+
84
+ ## What Does NOT Exist Here
85
+
86
+ - No persistent storage — sessions are in-memory only; nothing is written to disk by the server.
87
+ - No authentication or multi-user access control — server binds to localhost.
88
+ - No build step for the frontend — `_viewer.html` is a single static file served from package resources.
89
+ - No background job queue — heavy ops run in the render thread or prefetch pool, both owned by `_session.py`.
90
+ - No nnInteractive server — `_segmentation.py` is a pure HTTP client to a separately running nnInteractive process.