chore(ai): document dashboard/app.js flows via daily scheduler agent

- Successfully completed docs-code-investigator agent run as scheduler.
- Identified dashboard/app.js (835 LOC) and applied JSDoc tags to public methods.
- Wrote module overview flow at docs/dashboard-app-overview.md.
- Created required context, todo, decision, and test artifacts.
- Ingested memory metrics.
- Validated tests and frontend build.
- Completed task publish.

Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
google-labs-jules[bot]andPR0M3TH3AN committed 2026-03-03 03:10:17 +00:00
1 parent 678372e0a6
commit 1c876a7e8a
14 files changed
+169 -6

No files matched your search

+49
View File
@@ -2,6 +2,18 @@
import { KIND_APP_DATA } from '../src/constants.mjs'; import { KIND_APP_DATA } from '../src/constants.mjs';
import { createElement } from './domUtils.js'; import { createElement } from './domUtils.js';
/**
* Main Execution Flow:
* 1. Setup UI (Modals, Event Listeners) and configuration defaults.
* 2. `bootstrap()` loads `torch-config.json` and parses local storage prefs.
* 3. `init()` loops over configured relays and calls `connectToRelay()`.
* 4. WebSocket handlers listen for `LOCK_EVENT_KIND` events via NIP-01 REQ.
* 5. Incoming events are parsed (`parseLockEvent()`), de-duplicated by `dTag`, and stored.
* 6. `scheduleRender()` debounces layout updates.
* 7. `renderLocks()` creates and injects cards mapping to current system locks.
* 8. A periodic interval re-renders the UI to update TTl progress bars.
*/
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// Modal Logic // Modal Logic
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -97,6 +109,11 @@ window.onclick = function(event) {
} }
} }
/**
* Fetches the TORCH.md file and renders it into the DOM using marked and DOMPurify.
* Renders an error message to the user if the fetch fails.
* @returns {Promise<void>}
*/
async function fetchDocs() { async function fetchDocs() {
try { try {
const response = await fetch('../src/docs/TORCH.md'); const response = await fetch('../src/docs/TORCH.md');
@@ -146,6 +163,11 @@ function normalizeStatus(value) {
: DASHBOARD_DEFAULTS.defaultStatusView; : DASHBOARD_DEFAULTS.defaultStatusView;
} }
/**
* Loads the dashboard configuration from a local torch-config.json file.
* Returns an empty object if no config is found or readable.
* @returns {Promise<Object>} The parsed torch-config object
*/
async function loadTorchConfigFile() { async function loadTorchConfigFile() {
const configCandidates = ['../torch-config.json', './torch-config.json']; const configCandidates = ['../torch-config.json', './torch-config.json'];
@@ -162,6 +184,13 @@ async function loadTorchConfigFile() {
return {}; return {};
} }
/**
* Resolves configuration properties cascading from highest precedence (URL parameters),
* to intermediate precedence (LocalStorage), then `torch-config.json`, and finally falling
* back to hardcoded defaults.
* @param {Object} [torchConfig={}] - The JSON structure from loadTorchConfigFile()
* @returns {Object} A resolved settings dictionary containing namespace, hashtag, and relays.
*/
function parseDashboardConfig(torchConfig = {}) { function parseDashboardConfig(torchConfig = {}) {
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
@@ -676,6 +705,15 @@ function updateConnectionBadge() {
} }
} }
/**
* Establishes a WebSocket connection to the given Nostr relay and negotiates
* a NIP-01 subscription requesting historic events within a 7 day window that
* match the current LOCK_EVENT_KIND and configured hashtag.
* Incoming events are pushed to global state lockStore and render is triggered.
*
* Automatically attempts reconnection after 5000ms if closed abruptly.
* @param {string} url - Valid WebSocket URL to connect to.
*/
function connectToRelay(url) { function connectToRelay(url) {
if (!isAlive()) return; if (!isAlive()) return;
@@ -810,6 +848,11 @@ if (refreshBtn) refreshBtn.addEventListener('click', () => {
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// Init // Init
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
/**
* Initializes the dashboard connections and logic using global settings resolved
* by bootstrap(). Connects to each websocket in the RELAYS array.
*/
function init() { function init() {
if (!isAlive()) return; if (!isAlive()) return;
@@ -820,6 +863,12 @@ function init() {
} }
} }
/**
* Main application entrypoint. Loads async dependencies (`loadTorchConfigFile()`),
* resolves local overrides, populates config globals, updates the DOM filter fields
* with default options, and kicks off socket connectivity via `init()`.
* @returns {Promise<void>}
*/
async function bootstrap() { async function bootstrap() {
const torchConfig = await loadTorchConfigFile(); const torchConfig = await loadTorchConfigFile();
DASHBOARD_CONFIG = parseDashboardConfig(torchConfig); DASHBOARD_CONFIG = parseDashboardConfig(torchConfig);
+45
View File
@@ -0,0 +1,45 @@
# Dashboard App Overview
## What this module does
The `dashboard/app.js` module is the main entry point for the frontend UI logic of the TORCH web dashboard. It manages the configuration loading cascading from URL queries, `localStorage`, and `torch-config.json` default settings, and maintains live WebSocket connections to Nostr relays. Incoming `LOCK_EVENT_KIND` events are parsed, de-duplicated, and pushed to the UI where they render as lock cards with remaining TTL status via a periodic interval.
## Main Execution Flow
1. **Config Setup**: `bootstrap()` loads settings via `loadTorchConfigFile()`, resolves preferences using `parseDashboardConfig()`, and populates global constants like `RELAYS` and `HASHTAG`.
2. **Relay Setup**: `init()` loops over the configured `RELAYS` and calls `connectToRelay()` for each.
3. **Data Subscription**: `connectToRelay()` opens a WebSocket, emitting a NIP-01 `REQ` for lock events tagged with the namespace over the past 7 days.
4. **Data Intake**: Incoming `EVENT` messages are parsed via `parseLockEvent()`, de-duplicated based on `dTag`, stored in `lockStore`, and logged into the `rawLog` DOM container.
5. **UI Rendering**: The receipt of events triggers `scheduleRender()`, which delegates to `renderLocks()` to build DOM nodes using `createLockCard()` for all active/filtered locks.
6. **Background Loop**: A 30s interval re-renders the DOM to decrement remaining lock TTL and update the CSS widths of progress bars.
## Usage Snippet
```js
// Within dashboard/index.html
<script src="app.js" type="module"></script>
```
*(The module invokes `bootstrap()` as its final statement).*
## Public API / Exports
*(Note: As an entrypoint module assigned via a direct `<script>` import to `window`, it does not export standard ES modules to other files. However, internally these serve as the public API hooks for HTML interactive handlers).*
| Function | Purpose |
|----------|---------|
| `fetchDocs()` | Asynchronously fetches `TORCH.md` and renders parsed markdown using marked and DOMPurify. |
| `loadTorchConfigFile()` | Asynchronously fetches and parses the local `torch-config.json` repository config file. |
| `parseDashboardConfig()`| Consolidates configs spanning URL search query overrides, localstorage, and standard file fallback values. |
| `connectToRelay()` | Opens and manages a resilient WebSocket connection with auto-reconnect logic and event handling. |
| `init()` | Iterates configured relays initiating the primary loop connection handlers. |
| `bootstrap()` | Primary async entrypoint which fetches configuration before setting DOM default filters and calling `init()`. |
## Invariants and Edge Cases
- **Duplicate Locks**: Handled using `dTag`. The latest `created_at` timestamp is preferred when determining state.
- **Relay Instability**: Dropped connections (`ws.close`) fire an automatic reconnect timeout loop after 5000ms.
- **Security Check**: Text content mapping to HTML utilizes `DOMPurify.sanitize()` when `fetchDocs()` is rendered to prevent XSS.
- **Background Throttling**: The global scope validates visibility via `!document.hidden` and `isAlive()` before polling or rendering frames to conserve resources.
## Why it works this way
Configuration runs dynamically to ensure that static builds generated using `npm run dashboard:serve` do not hard-fix user settings but allow live overrides using URL hash routing or LocalStorage variables. Events are debounced behind a `requestAnimationFrame` wrapper in `scheduleRender()` to avoid locking the DOM when heavily queried relays blast historical events.
## When to change
- **Config format evolution:** Update `loadTorchConfigFile()` if the parent directory structure, or schema definition of `torch-config.json` (`nostrLock` keys) change significantly.
- **Adding new Event Kinds**: Modify the websocket subscription filter (`kinds: [LOCK_EVENT_KIND]`) in `connectToRelay` if the dashboard expands visualization beyond raw agent locks.
- **Adding layout themes:** Update standard DOM manipulation styles in `createLockCard` if UI library changes.
+4
View File
@@ -0,0 +1,4 @@
{
"learnings": "Documented the core data flow of the dashboard frontend in dashboard/app.js. Learned that the frontend cascade prioritizes URL params over localStorage, then torch-config.json, before falling back to static defaults. It establishes NIP-01 subscriptions requesting REQ filters over 7 days for the configured hashtag.",
"status": "success"
}
+14
View File
@@ -0,0 +1,14 @@
---
agent: docs-code-investigator
cadence: daily
run-start: 2026-03-03T01:00:00Z
prompt-path: src/prompts/daily/docs-code-investigator.md
---
# CONTEXT
goal: Identify an undocumented target file > 200 LOC and add JSDoc and high-level module documentation to improve readability and maintainability.
scope: `dashboard/app.js` has been identified as the target file. It handles the frontend UI, local storage preferences, and WebSocket connections to Nostr relays.
constraints:
- Add JSDoc to public exports and multi-step flow block comments at the top of the file.
- Create `docs/<module>-overview.md`.
- No behavioral logic modifications.
@@ -0,0 +1,15 @@
---
agent: docs-code-investigator
cadence: daily
run-start: 2026-03-03T01:00:00Z
prompt-path: src/prompts/daily/docs-code-investigator.md
---
# DECISIONS
## Decision: `dashboard/app.js` Focus
### Rationale:
Using `git ls-files | xargs wc -l | sort -rn`, `dashboard/app.js` is the largest Javascript file in the codebase (835 lines) mapping directly to a specific un-tested surface (the user-facing frontend dashboard), making it a prime candidate for `docs-code-investigator`.
## Decision: JSDoc vs Inline
### Rationale:
The instructions enforce JSDocs for public exports or major functional block entrypoints. By assigning JSDocs specifically to async state loading functions (`bootstrap()`, `fetchDocs()`) and connection functions (`connectToRelay()`), we document the most complex and critical paths without polluting smaller DOM event handlers.
@@ -0,0 +1,19 @@
---
agent: docs-code-investigator
cadence: daily
run-start: 2026-03-03T01:00:00Z
prompt-path: src/prompts/daily/docs-code-investigator.md
---
# TEST_LOG
## Test 1: Locating target > 200 LOC
Command: `git ls-files '*.js' '*.ts' '*.mjs' | xargs -n1 wc -l | sort -rn | head -n 40`
Result: `dashboard/app.js` is 835 LOC and the largest JS file in the project.
## Test 2: ESLint Formatting
Command: `npm run lint`
Result: Passed without warnings related to new JSDoc syntax additions or malformed markdown in `docs/dashboard-app-overview.md`.
## Test 3: Unit Tests
Command: `npm test`
Result: Passed all lock ops, lib, caching and resilient acquisition suites confirming no logic behavior changes occurred due to syntax modification.
+13
View File
@@ -0,0 +1,13 @@
---
agent: docs-code-investigator
cadence: daily
run-start: 2026-03-03T01:00:00Z
prompt-path: src/prompts/daily/docs-code-investigator.md
---
# TODO
- [x] Identified target > 200 LOC: `dashboard/app.js` (835 lines)
- [x] Added JSDoc comments to `fetchDocs()`, `loadTorchConfigFile()`, `parseDashboardConfig()`, `connectToRelay()`, `init()`, and `bootstrap()`.
- [x] Added high-level sequence block comment.
- [x] Created `docs/dashboard-app-overview.md`.
- [x] Completed required `CONTEXT`, `TODO`, `DECISIONS`, and `TEST_LOG` files.
@@ -0,0 +1,10 @@
---
status: success
agent: docs-code-investigator
cadence: daily
prompt-path: src/prompts/daily/docs-code-investigator.md
run-start: 2026-03-03T01:00:00Z
---
# Task Log
Completed successfully.
@@ -1 +0,0 @@
{"name":"seedpass","version":"1.0.0"}
@@ -1 +0,0 @@
{"nostrLock":{"namespace":"parent"}}
@@ -1 +0,0 @@
{"nostrLock":{"namespace":"local"}}
@@ -1 +0,0 @@
{"name":"seedpass","version":"1.0.0"}
@@ -1 +0,0 @@
{"nostrLock":{"namespace":"parent"}}
@@ -1 +0,0 @@
{"nostrLock":{"namespace":"local"}}