From 4bacf2c2f8ee48cbeecda7985bfccd1772e777f3 Mon Sep 17 00:00:00 2001 From: dirtydishes Date: Tue, 19 May 2026 14:59:58 -0400 Subject: [PATCH] publish docs index and github pages workflow --- .beads/issues.jsonl | 1 + .github/workflows/docs-pages.yml | 56 ++ docs/index.html | 638 ++++++++++++++++++ .../2026-05-19-publish-docs-pages-index.html | 195 ++++++ scripts/generate-docs-index.mjs | 421 ++++++++++++ 5 files changed, 1311 insertions(+) create mode 100644 .github/workflows/docs-pages.yml create mode 100644 docs/index.html create mode 100644 docs/turns/2026-05-19-publish-docs-pages-index.html create mode 100644 scripts/generate-docs-index.mjs diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index a1ec579..e6a01f4 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -14,6 +14,7 @@ {"_type":"issue","id":"islandflow-ayo","title":"Drop stale backlog events from live fanout","description":"Follow-up to live freshness rollout: /ws/live was still fanning out stale backlog events for freshness-gated channels, which kept tape panes in Live feed behind despite active synthetic ingest. Gate fanout and cache ingest by freshness for options/nbbo/equities/flow.","status":"closed","priority":1,"issue_type":"bug","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-04-28T21:26:39Z","created_by":"dirtydishes","updated_at":"2026-04-28T21:26:44Z","started_at":"2026-04-28T21:26:44Z","closed_at":"2026-04-28T21:26:44Z","close_reason":"Completed","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"islandflow-0v6","title":"Fix tape freshness, NBBO coverage, pause controls, and filter popup","description":"Implement the tape fixes requested for synthetic options notional sizing, strict live freshness, live-mode pause/resume behavior, stronger NBBO snapshot coverage, and moving flow filters behind a popup. Includes server-side live cache changes, web terminal state/UI changes, and tests for synthetic pricing, live snapshot freshness/NBBO retention, and live pause/filter interactions.","status":"closed","priority":1,"issue_type":"task","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-04-28T21:02:52Z","created_by":"dirtydishes","updated_at":"2026-04-28T21:13:38Z","started_at":"2026-04-28T21:02:57Z","closed_at":"2026-04-28T21:13:38Z","close_reason":"Completed","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"islandflow-e4r","title":"Implement smart-money flow filtering and synthetic firehose modes","description":"Implement the approved multi-surface plan for named synthetic market profiles, options raw-vs-signal filtering, live/API filter contracts, Tape page client-side flow filters, firehose-readiness improvements, tests, and README updates.","status":"closed","priority":1,"issue_type":"feature","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-04-28T20:10:49Z","created_by":"dirtydishes","updated_at":"2026-04-28T20:29:29Z","started_at":"2026-04-28T20:10:53Z","closed_at":"2026-04-28T20:29:29Z","close_reason":"Implemented synthetic market profiles, options signal-path filtering, signal-aware API/replay contracts, Tape page filters, tests, and README updates. Follow-up tracked in islandflow-biq.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"islandflow-tqk","title":"publish docs/ to github pages with navigable index","description":"Set up docs deployment so repository docs are published to dirtydishes.github.io/islandflow/docs with a nicer, browsable experience than a raw file listing.","status":"closed","priority":2,"issue_type":"feature","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-19T18:56:02Z","created_by":"dirtydishes","updated_at":"2026-05-19T18:59:55Z","started_at":"2026-05-19T18:56:04Z","closed_at":"2026-05-19T18:59:55Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"islandflow-lm6","title":"Clarify repo turn documentation scope","description":"Update AGENTS.md so repository turn documentation clearly uses repo-local docs/turns and impeccable styling, without inheriting global non-repo computer-task styling.","status":"closed","priority":2,"issue_type":"task","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-19T12:05:07Z","created_by":"dirtydishes","updated_at":"2026-05-19T12:06:12Z","started_at":"2026-05-19T12:05:14Z","closed_at":"2026-05-19T12:06:12Z","close_reason":"Verified AGENTS.md now scopes repo turn docs to docs/turns and makes impeccable the styling authority; added turn documentation.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"islandflow-6iq","title":"Update README for current project state","description":"Resolve README merge conflicts and document the current project state, including the smart money classification taxonomy, Next.js update, and deployment workflow changes.","status":"closed","priority":2,"issue_type":"task","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-19T11:37:24Z","created_by":"dirtydishes","updated_at":"2026-05-19T11:40:01Z","started_at":"2026-05-19T11:37:31Z","closed_at":"2026-05-19T11:40:01Z","close_reason":"README conflict resolved and current project state documented, including smart-money taxonomy, Next.js update, and deployment workflow.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"islandflow-lib","title":"Upgrade apps/web to Next.js 16.2.6","description":"Upgrade the web app dependency stack to Next.js 16.2.6 with React 19, refresh Bun and mirrored Docker workspace lockfiles, keep runtime behavior unchanged, fix any focused web test fallout, validate the web build and targeted route tests, and document the completed work.","status":"closed","priority":2,"issue_type":"task","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-19T11:04:51Z","created_by":"dirtydishes","updated_at":"2026-05-19T11:31:23Z","started_at":"2026-05-19T11:04:57Z","closed_at":"2026-05-19T11:31:23Z","close_reason":"Upgraded apps/web to Next.js 16.2.6 with React 19, refreshed Bun lockfiles including the Docker workspace mirror, fixed the React 19 nullable ref type issue, and validated the web build, focused tests, Docker workspace sync, and route smoke checks.","dependency_count":0,"dependent_count":0,"comment_count":0} diff --git a/.github/workflows/docs-pages.yml b/.github/workflows/docs-pages.yml new file mode 100644 index 0000000..9c4db98 --- /dev/null +++ b/.github/workflows/docs-pages.yml @@ -0,0 +1,56 @@ +name: Publish Docs + +on: + push: + branches: + - main + paths: + - "docs/**" + - "scripts/generate-docs-index.mjs" + - ".github/workflows/docs-pages.yml" + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Configure Pages + uses: actions/configure-pages@v5 + + - name: Build docs index + run: node scripts/generate-docs-index.mjs + + - name: Prepare static site payload + run: | + mkdir -p site/docs + cp -R docs/. site/docs/ + printf '%s\n' 'Islandflow DocsContinue to docs' > site/index.html + touch site/.nojekyll + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v3 + with: + path: site + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..211c5ac --- /dev/null +++ b/docs/index.html @@ -0,0 +1,638 @@ + + + + + + Islandflow Docs + + + +
+
+

Islandflow docs index

+

A browsable index of files under docs/ with filtering and grouped navigation.

+
+ +
+
35 of 35 files shown
+ + +
+ +
+
+

turns 28

+ +
+ + +
+

daily-git 1

+ +
+ + +
+

general 2

+ +
+ + +
+

plans 2

+ +
+ + +
+

root 2

+ +
+
+

No files match that filter.

+
+ + + + diff --git a/docs/turns/2026-05-19-publish-docs-pages-index.html b/docs/turns/2026-05-19-publish-docs-pages-index.html new file mode 100644 index 0000000..9946b33 --- /dev/null +++ b/docs/turns/2026-05-19-publish-docs-pages-index.html @@ -0,0 +1,195 @@ + + + + + + Turn Report - Publish Docs to GitHub Pages + + + +
+

Publish docs/ to GitHub Pages with navigable index

+

Completed on May 19, 2026 at 9:38 AM ET.

+ +
+

Summary

+

+ Added an automated docs publishing flow to GitHub Pages and generated a new + docs/index.html browsing experience so docs are easy to navigate at + /islandflow/docs/. +

+
+ +
+

Changes Made

+
    +
  • Added scripts/generate-docs-index.mjs to build a browsable index of files under docs/.
  • +
  • Added .github/workflows/docs-pages.yml to publish docs to GitHub Pages on pushes to main.
  • +
  • Generated docs/index.html from current docs content.
  • +
  • Configured deployment artifact layout so docs are available at /docs/ under the project Pages site.
  • +
+
+ +
+

Context

+

+ The repository already stores operational and implementation documentation under + docs/, but there was no dedicated GitHub Pages pipeline and no curated + index page for discovery. This task focused on syncing that folder to Pages and + making it easy to browse by category and filename. +

+
+ +
+

Important Implementation Details

+
    +
  • The index generator excludes hidden files and avoids self-including docs/index.html.
  • +
  • Files are grouped by first path segment (turns, general, plans, and others) with quick category chips.
  • +
  • The index includes client-side filtering so users can search docs by path text in-browser.
  • +
  • Pages deployment packages a site/ payload where docs are copied into site/docs and root redirects to ./docs/.
  • +
+
+ +
+

Relevant Diff Snippets

+

+ Snippets are shown in a compact style aligned with diffs.com presentation patterns. +

+
+++ .github/workflows/docs-pages.yml
+name: Publish Docs
+on:
+  push:
+    branches: [main]
+    paths:
+      - "docs/**"
+      - "scripts/generate-docs-index.mjs"
+      - ".github/workflows/docs-pages.yml"
+  workflow_dispatch:
+
+jobs:
+  build:
+    steps:
+      - uses: actions/checkout@v4
+      - uses: actions/configure-pages@v5
+      - run: node scripts/generate-docs-index.mjs
+      - run: cp -R docs/. site/docs/
+      - uses: actions/upload-pages-artifact@v3
+  deploy:
+    needs: build
+    steps:
+      - uses: actions/deploy-pages@v4
+
+++ scripts/generate-docs-index.mjs
+const files = await collectDocsFiles(docsDir);
+const html = renderDocument(files);
+await fs.writeFile(outputFile, html, "utf8");
+
+// Generated index features:
+// - grouped sections
+// - search filter
+// - file size and modified time metadata
+// - links preserving docs folder structure
+
+ +
+

Expected Impact for End-Users

+
    +
  • Docs are reachable via a stable Pages URL path: dirtydishes.github.io/islandflow/docs/.
  • +
  • Readers can quickly scan categories and search by filename instead of relying on raw directory browsing.
  • +
  • New docs added to the repository are published automatically on main pushes.
  • +
+
+ +
+

Validation

+
    +
  • Ran node scripts/generate-docs-index.mjs successfully.
  • +
  • Ran node --check scripts/generate-docs-index.mjs for syntax validation.
  • +
  • Confirmed generated index contains expected navigation/search markers and category anchors.
  • +
+
+ +
+

Issues, Limitations, and Mitigations

+
    +
  • GitHub Pages must be enabled for this repository and set to GitHub Actions deployment.
  • +
  • The index reflects files present at build time and does not include full-text search inside documents.
  • +
  • Markdown files are linked as-is; rendering behavior depends on GitHub Pages static hosting behavior.
  • +
+
+ +
+

Follow-up Work

+
    +
  • Add a docs landing page summary for key collections (turn docs, runbooks, daily notes).
  • +
  • Optionally add link-checking in CI for docs URLs and local references.
  • +
  • Consider tagging docs with metadata for richer filtering by date, topic, and type.
  • +
+
+
+ + diff --git a/scripts/generate-docs-index.mjs b/scripts/generate-docs-index.mjs new file mode 100644 index 0000000..cf64a9d --- /dev/null +++ b/scripts/generate-docs-index.mjs @@ -0,0 +1,421 @@ +import { promises as fs } from "node:fs"; +import path from "node:path"; + +const docsDir = path.resolve(process.cwd(), "docs"); +const outputFile = path.join(docsDir, "index.html"); + +const dateFormatter = new Intl.DateTimeFormat("en-US", { + dateStyle: "medium", + timeStyle: "short", +}); + +function escapeHtml(value) { + return value + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll('"', """) + .replaceAll("'", "'"); +} + +function formatBytes(bytes) { + if (bytes < 1024) { + return `${bytes} B`; + } + + const units = ["KB", "MB", "GB"]; + let size = bytes / 1024; + let unitIndex = 0; + + while (size >= 1024 && unitIndex < units.length - 1) { + size /= 1024; + unitIndex += 1; + } + + return `${size.toFixed(size >= 10 ? 0 : 1)} ${units[unitIndex]}`; +} + +function docsHref(relativePath) { + const encoded = relativePath + .split("/") + .map((part) => encodeURIComponent(part)) + .join("/"); + return `./${encoded}`; +} + +async function collectDocsFiles(rootDir, currentDir = rootDir, acc = []) { + const entries = await fs.readdir(currentDir, { withFileTypes: true }); + const sortedEntries = entries.sort((a, b) => a.name.localeCompare(b.name)); + + for (const entry of sortedEntries) { + if (entry.name.startsWith(".")) { + continue; + } + + const absolutePath = path.join(currentDir, entry.name); + const relativePath = path.relative(rootDir, absolutePath).replaceAll(path.sep, "/"); + + if (relativePath === "index.html") { + continue; + } + + if (entry.isDirectory()) { + await collectDocsFiles(rootDir, absolutePath, acc); + continue; + } + + if (entry.isFile()) { + const stats = await fs.stat(absolutePath); + + acc.push({ + relativePath, + category: relativePath.includes("/") ? relativePath.split("/")[0] : "root", + sizeBytes: stats.size, + modifiedAt: stats.mtime, + }); + } + } + + return acc; +} + +function groupByCategory(items) { + const groups = new Map(); + for (const item of items) { + if (!groups.has(item.category)) { + groups.set(item.category, []); + } + groups.get(item.category).push(item); + } + return groups; +} + +function sortedCategories(groups) { + const preferredOrder = ["turns", "daily-git", "general", "plans", "root"]; + const groupNames = [...groups.keys()]; + return groupNames.sort((a, b) => { + const aIndex = preferredOrder.indexOf(a); + const bIndex = preferredOrder.indexOf(b); + + if (aIndex !== -1 || bIndex !== -1) { + if (aIndex === -1) return 1; + if (bIndex === -1) return -1; + return aIndex - bIndex; + } + + return a.localeCompare(b); + }); +} + +function renderDocument(items) { + const sortedItems = [...items].sort((a, b) => b.modifiedAt.getTime() - a.modifiedAt.getTime()); + const groups = groupByCategory(sortedItems); + const categories = sortedCategories(groups); + const totalCount = sortedItems.length; + + const categoryChips = categories + .map((category) => { + const count = groups.get(category).length; + return `${escapeHtml( + category + )} ${count}`; + }) + .join("\n"); + + const groupsMarkup = categories + .map((category) => { + const entries = groups.get(category); + const entryMarkup = entries + .map((entry) => { + const extension = path.extname(entry.relativePath).replace(".", "") || "file"; + const searchable = `${entry.relativePath} ${category}`.toLowerCase(); + return ` +
  • + ${escapeHtml( + entry.relativePath + )} +
    + ${escapeHtml(extension)} + ${escapeHtml(formatBytes(entry.sizeBytes))} + ${escapeHtml(dateFormatter.format(entry.modifiedAt))} +
    +
  • + `; + }) + .join("\n"); + + return ` +
    +

    ${escapeHtml(category)} ${entries.length}

    + +
    + `; + }) + .join("\n"); + + return ` + + + + + Islandflow Docs + + + +
    +
    +

    Islandflow docs index

    +

    A browsable index of files under docs/ with filtering and grouped navigation.

    +
    + +
    +
    ${totalCount} of ${totalCount} files shown
    + + +
    + +
    ${groupsMarkup}
    +

    No files match that filter.

    +
    + + + + +`; +} + +async function main() { + const files = await collectDocsFiles(docsDir); + const html = renderDocument(files); + await fs.writeFile(outputFile, html, "utf8"); + console.log(`Generated ${outputFile} with ${files.length} entries.`); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +});