Skip to content

Latest commit

 

History

History
249 lines (163 loc) · 15.4 KB

File metadata and controls

249 lines (163 loc) · 15.4 KB

ChronoCluster Live — Operational & Verification Manual

This document is both an end-user operational guide (how to use the extension) and a functional test plan (how to verify every moving part works end-to-end). Read Part 1 to install, Part 2 to use it, Part 3 to verify it.


Part 1 — Installing the Extension

Prerequisites

  • Node.js 20+ and npm on PATH.
  • A Chromium-based browser (Chrome, Edge, Brave, Arc). Firefox is not supported yet — the manifest is MV3 Chromium-flavor.
  • ~200 MB of free disk for node_modules/.

First build

git clone https://github.com/Mintsolester/Chronocluster.git
cd Chronocluster
npm install          # ~30s, pulls Vite, Pixi, d3-force, Dexie, CRXJS
npm run build        # ~6s, type-checks then emits dist/

After the build, dist/ contains the loadable extension:

  • manifest.json
  • service-worker-loader.js (CRXJS shim → assets/background.ts-*.js)
  • index.html + assets/index-*.js (the constellation page)
  • assets/worker-*.js (d3-force physics)
  • icons/icon.png

Load unpacked

  1. Visit chrome://extensions.
  2. Toggle Developer mode on (top right).
  3. Click Load unpacked.
  4. Select the dist/ folder inside your clone.
  5. You should see ChronoCluster Live in the list with no red error badge and the default icon visible in the Chrome toolbar.

Live dev mode (optional)

npm run dev

CRXJS emits into dist/ with HMR. Load the same dist/ folder as above. Edits to src/App.tsx, src/renderer.ts, etc. will hot-reload the constellation page without needing a rebuild.


Part 2 — Using ChronoCluster

Opening the constellation

Click the ChronoCluster icon in your Chrome toolbar. A dedicated full tab opens at chrome-extension://<id>/index.html. Clicking the icon again focuses the existing tab rather than opening a duplicate.

Reading the map

  • Glowing blue circle (#00A3FF, alpha 1.0) — a tab that is currently open.
  • Dim gray circle (#555555, alpha 0.45) — a tab that has been closed. It remains in the graph as a historical shadow; links connecting to/from it stay drawn.
  • Thin blue line — a parent → child link. A parent is the tab from which a child was opened (via click, middle-click, or target="_blank"). Typed/bookmark/reload navigations have no parent and appear as roots.
  • Clustering — every domain has a deterministic "gravity point" on a golden-angle spiral. Tabs from the same domain drift toward each other, forming a solar system. A brand-new domain is assigned the next available slot without disturbing existing clusters.

HUD (top-left)

Row Meaning
Nodes Total tabs seen (open + closed).
Open Currently open tabs (isOpen: true).
Edges Parent/child links recorded.
FPS Render-loop frames per second. Expect ~60.
LOD on when nodes > 2000 (labels hidden, radii shrink).

Toolbar (top-right)

Button Action
Export Downloads a JSON snapshot of nodes + edges for backup / transport.
Import Reads a JSON snapshot and bulkPuts it into Dexie. Existing rows with matching ids are overwritten; others preserved.
Seed 500 Dev-only — visible when npm run dev or an unminified build is loaded. Inserts 500 synthetic nodes + edges across 4 domains so you can stress the physics + LOD. Hidden in production builds.
Clear Sends { type: "clearAll" } to the service worker, which truncates nodes, edges, meta, and wipes chrome.storage.session. Asks for confirmation first.

Pan & Zoom

  • Drag (left mouse button) — pan the viewport.
  • Scroll / pinch — zoom toward the cursor.
  • Release after drag — momentum; the viewport decelerates naturally.

Persistence

Every 5 seconds the page flushes the current (x, y) of every node back into Dexie. When you reload the constellation tab, nodes warm-start at their persisted positions and the simulation reaches steady state in ~100 ms instead of re-laying out from scratch.

What's recorded

ChronoCluster observes:

  • chrome.tabs.onCreated — new tab (with optional openerTabId for parentage).
  • chrome.tabs.onUpdated — URL or title change, patches the existing node.
  • chrome.tabs.onRemoved — flips isOpen: false, sets closedAt.
  • chrome.webNavigation.onCreatedNavigationTarget — Ctrl/Cmd-click, middle-click, target="_blank" open-in-new-tab. Records parent from sourceTabId.
  • chrome.webNavigation.onCommitted — same-tab navigation. If transitionType === "link", parent = previous node in that tab; otherwise the new node is a root.

ChronoCluster does not request host_permissions and does not inject content scripts. It never reads page content — only URLs, titles, and tab-level events that Chrome already hands to extensions with the tabs + webNavigation permissions.

Data location

  • Node / edge graph: IndexedDB database ChronoClusterGraph (visible in DevTools → Application → IndexedDB).
  • Per-tab routing caches: chrome.storage.session under keys chronocluster.lastNodeByTab and chronocluster.nodeForTab. Session storage is wiped on browser restart; this is intentional — history in Dexie persists, only the live "which tab maps to which node" cache resets.

Nothing leaves your machine. There are no network calls.


Part 3 — Functional Test Plan

Run through this checklist after any meaningful change. Each test is independent; the Expect line is the pass criterion.

3.1 Build & install

  • T1.1 — Clean build. rm -rf dist node_modules && npm install && npm run build. Expect: tsc --noEmit passes silently; Vite build completes; dist/manifest.json, dist/service-worker-loader.js, dist/index.html, at least one dist/assets/worker-*.js, and dist/assets/background.ts-*.js all exist.
  • T1.2 — Manifest sanity. cat dist/manifest.json. Expect: manifest_version: 3; permissions: ["tabs","webNavigation","storage"]; no host_permissions; background.service_worker points to service-worker-loader.js.
  • T1.3 — Load unpacked. In chrome://extensions → Developer mode → Load unpacked → pick dist/. Expect: Extension appears with no errors; the Service worker link is active (click it to open DevTools on the background).

3.2 Full-tab opening

  • T2.1 — Action click opens new tab. Click the toolbar icon. Expect: A new tab opens at chrome-extension://<id>/index.html. The HUD shows Nodes: 0 | Open: ~1 (the constellation tab itself is a node). Empty-state text "Open a few tabs…" is visible.
  • T2.2 — Singleton tab. Click the action icon again while the constellation tab is open. Expect: Chrome switches focus to the existing constellation tab; no duplicate is opened.

3.3 Tab observation

  • T3.1 — Typed URL → root node. In a fresh tab, type https://example.com into the omnibox. Expect: In the constellation, a new glowing node appears with no incoming link. The HUD Nodes and Open counters both increase by 1.
  • T3.2 — Link click in same tab → child node. On example.com, click the "More information…" link. Expect: A new glowing node appears, connected to the previous node by a thin line. Edge count +1.
  • T3.3 — Ctrl-click / middle-click → child in new tab. On any page with links, Ctrl-click (Cmd-click on Mac) a link. Expect: The new tab appears as a glowing child of the source tab with a visible link line. This hits onCreatedNavigationTarget, which is the priority-1 parent resolver.
  • T3.4 — target="_blank" link. Open https://www.w3.org/TR/html52/semantics.html#the-a-element-attributes (or any page with target="_blank" links) and click one. Expect: Same as T3.3 — parent correctly resolved via sourceTabId.
  • T3.5 — Title updates. Wait for a page to finish loading. Expect: Hover the node (or zoom in) — the label beneath the disc shows the page title, not the raw URL. (Labels hidden once LOD triggers; see T6.1.)
  • T3.6 — Close tab → dims. Close one of your open test tabs. Expect: Its node transitions to gray at alpha ~0.45. Link lines remain. Open counter decreases; Nodes unchanged.
  • T3.7 — Reload same tab. Reload a test tab (Ctrl+R). Expect: A new root node is created (transition type reloadparentId: null). This is intentional — a reload breaks the "link" chain.

3.4 Domain gravity

  • T4.1 — Solar system forms. Open 5+ tabs on one domain (e.g. several Wikipedia articles across different paths: Ctrl-click from a seed Wikipedia page 5 times). Expect: All 5 nodes drift toward the same region of the canvas, forming a visible cluster, while tabs from other domains sit in a different region.
  • T4.2 — New domain does not disturb existing clusters. After T4.1, open 3 tabs on a brand-new domain. Expect: The existing Wikipedia cluster stays roughly where it was. The new domain's nodes form their own cluster in a different spiral slot.

3.5 Persistence

  • T5.1 — 5-second flush writes positions. Watch nodes settle for ~10 seconds. In DevTools → Application → IndexedDB → ChronoClusterGraphnodes, pick any row. Expect: x and y fields are numbers, not null.
  • T5.2 — Warm-start on reload. Reload the constellation tab (Ctrl+R). Expect: Nodes appear at their saved positions within ~100 ms; the simulation does not visibly re-layout from scratch. FPS stays high throughout.
  • T5.3 — Survives browser restart. Quit Chrome fully, reopen, click the ChronoCluster icon. Expect: All historical nodes (open and closed) still present; positions persisted. Note: chrome.storage.session clears on restart, so new navigations in old tabs will create new root nodes — this is correct behavior.

3.6 LOD & performance (dev build only)

Only the dev build exposes the Seed 500 button.

  • T6.1 — Seed below threshold. Run npm run dev, reload dist/ in chrome://extensions, open the constellation. Click Seed 500 four times. Expect: ~2000 nodes visible; LOD indicator flips to on; labels disappear; node radii shrink by ~40 %.
  • T6.2 — FPS holds under load. After T6.1, watch the FPS counter for 30 seconds while panning. Expect: FPS stays ≥ 55. If it drops below 45, inspect the Worker in DevTools → Sources → worker-*.js for long tick times.

3.7 Pan & zoom

  • T7.1 — Drag to pan. Mouse-down on empty canvas, drag. Expect: Viewport follows smoothly; on release, momentum deceleration.
  • T7.2 — Wheel to zoom. Scroll wheel over a cluster. Expect: Zoom centers on the cursor; labels re-layout cleanly.
  • T7.3 — Pinch on trackpad. Two-finger pinch on a trackpad. Expect: Zoom in/out responsively.

3.8 Snapshot round-trip

  • T8.1 — Export. With at least 10 nodes present, click Export. Expect: A chronocluster.json file downloads. Open it — confirm version: 1, exportedAt timestamp, and arrays nodes and edges with populated entries.
  • T8.2 — Import. Click Clear to wipe, then Import and pick the JSON from T8.1. Expect: All nodes/edges return, positions included. HUD counts match the pre-clear state.

3.9 Clear history

  • T9.1 — Confirm prompt. Click Clear. Expect: Browser confirm() dialog. Cancel → nothing happens.
  • T9.2 — Nuclear wipe. Click Clear again, confirm. Expect: HUD resets to Nodes: 0 | Edges: 0 | Open: 0. IndexedDB → ChronoClusterGraph tables are empty. chrome.storage.session keys chronocluster.lastNodeByTab and chronocluster.nodeForTab are gone (inspect in the service worker DevTools Console: await chrome.storage.session.get(null)).

3.10 Quick automated spot-check

Open the service worker DevTools (from chrome://extensions) and run:

const db = await (async () => {
  const all = indexedDB.databases ? await indexedDB.databases() : [];
  return all.find(d => d.name === "ChronoClusterGraph");
})();
console.log(db);

Expect: A database entry with name: "ChronoClusterGraph" and a numeric version.


Part 4 — Troubleshooting

Nothing happens when I click the icon

  • Open chrome://extensions. Is the extension enabled? Any red error badge?
  • Click the Service worker link to open its DevTools. Console errors there usually point to a failed import or a Dexie migration issue.
  • Try rebuilding: rm -rf dist && npm run build, then reload the extension from chrome://extensions.

Nodes appear but there are no link lines

  • chrome.webNavigation permission may have been dropped. Check dist/manifest.json contains "webNavigation" in permissions.
  • Certain pages (e.g. chrome:// URLs, PDF viewer) are filtered out by handleNavCommitted. This is intentional.

FPS is low with few nodes

  • Open the constellation tab's DevTools (F12). In the Performance tab, record ~5 seconds. Look for long tasks in the main thread — most likely suspects are useLiveQuery diffing or Pixi label creation.
  • Try disabling strict mode temporarily (src/main.tsx) — StrictMode doubles effects in dev, which can mask FPS.

Parents are wrong after a browser restart

  • Expected. chrome.storage.session is cleared on restart, so new navigations in tabs that were already open will appear as roots. Fresh tabs opened from links after restart will still resolve correctly via onCreatedNavigationTarget.

Clear button does nothing

  • Check the service worker DevTools Console for Error in chrome.runtime.onMessage. If the worker was suspended, the onMessage handler may have missed the event — reload the constellation tab and try again.

Inspecting live state

  • Graph data: Constellation tab DevTools → Application → IndexedDB → ChronoClusterGraph.
  • Tab-routing cache: Service worker DevTools Console → await chrome.storage.session.get(null).
  • Message traffic: Constellation tab DevTools → Sources → worker-*.js, set breakpoints in the message handler.

Part 5 — Uninstall / Reset

  • Soft reset (keep installed, drop all data): click Clear in the toolbar.
  • Full uninstall: chrome://extensions → Remove. Dexie database persists until Chrome garbage-collects the extension origin; to delete immediately, also use DevTools → Application → Clear storage → Clear site data on chrome-extension://<id>.
  • Wipe and rebuild from source: rm -rf dist node_modules && npm install && npm run build, then reload unpacked.

Part 6 — Architecture Cheatsheet

Quick architectural reference:

Context File Allowed to touch Forbidden
Service worker src/background.ts chrome.*, Dexie writes, chrome.storage.session DOM, Pixi, Worker
Full-tab page src/main.tsx, src/App.tsx, src/hooks/* DOM, Pixi, spawns physics Worker, Dexie reads via useLiveQuery chrome.tabs.* writes
Physics worker src/worker.ts d3-force, transferable buffers DOM, Dexie, chrome.*

Parent resolution priority (in src/lib/observers.ts):

  1. onCreatedNavigationTarget.sourceTabId → last node of source tab.
  2. onCreated.openerTabId → last node of opener tab.
  3. onCommitted with transitionType === "link" → last node of same tab.
  4. Anything else → null (root).

Domain gravity (golden-angle spiral, src/lib/domainGravity.ts): angle = i · 2.39996, radius = 140 · √(i+1), i = lexically-sorted domain index.

LOD (src/lib/lod.ts): labels hidden and radii × 0.6 once nodeCount > 2000.