Skip to content

feat: wasmJs browser demo, Astro/Starlight docs site, and GitHub Pages CI/CD - #3

Merged
tstapler merged 9 commits into
mainfrom
stelekit-documentation-and-branding
Apr 19, 2026
Merged

tstapler merged 9 commits into
mainfrom
stelekit-documentation-and-branding

Conversation

@tstapler

Copy link
Copy Markdown
Owner

What?

Implements the SteleKit documentation and branding milestone:

  • Browser demo: Migrates the web target from js(IR) to wasmJs (Compose Multiplatform canvas), running the full app in-browser with an in-memory demo graph
  • Docs site: Astro + Starlight site at stelekit.stapler.dev with 5 user docs pages and 4 developer docs pages
  • CI/CD: GitHub Actions pipeline that builds the wasmJs bundle and deploys the Astro site to GitHub Pages
  • Custom domain: stelekit.stapler.dev via Cloudflare CNAME + site/public/CNAME

Why?

SteleKit needs a public web presence and a way for potential users to try the app without installing anything. The wasmJs Compose target lets us ship the real app (not a React wrapper) to the browser.

How?

wasmJs browser demo

  • kmp/build.gradle.kts: js(IR)wasmJs { browser(); binaries.executable() }, removed sql.js/web-worker deps
  • DemoFileSystem: in-memory FileSystem implementation serving fake markdown pages under /demo/ — no SQLite required in-browser
  • GraphBackend.IN_MEMORY passed to GraphManager so the browser target skips all SQLDelight migration code
  • coi-serviceworker.min.js injected for SharedArrayBuffer/COOP/COEP headers required by Skiko

commonMain multiplatform cleanup (required for wasmJs to compile)

  • Moved opentelemetry-api dep from commonMainjvmCommonMain
  • Added expect/actual OtelRepositoryWrappers — JVM wraps repos with OTel instrumentation, wasmJs/iOS are no-ops
  • Fixed @Volatile@kotlin.concurrent.Volatile, Dispatchers.IOPlatformDispatcher.IO, java.io.FileFileSystem interface, String.format("%.2f") → inline rounding, putIfAbsent → Kotlin equivalent
  • GraphManager: defaultBackend constructor param, Clock.System for timestamps, fileSystem.renameFile()

Gradle toolchain fix

  • settings.gradle.kts: changed PREFER_SETTINGSPREFER_PROJECT so Kotlin's wasmJs plugin can register its own Ivy repos for Node.js, Yarn, and Binaryen downloads (PREFER_SETTINGS was blocking them, causing build failure)

Astro site

  • site/: Astro + Starlight, configured for stelekit.stapler.dev
  • Landing page, /demo/ embed page, 9 documentation pages
  • site/public/CNAME for GitHub Pages custom domain

CI/CD

  • .github/workflows/pages.yml: two-job pipeline — build-demo (wasmJs bundle) + build-site (Astro, embeds demo artifact) → deploy

Testing

  • ./gradlew :kmp:compileKotlinWasmJs -PenableJs=true — compiles clean
  • ./gradlew :kmp:wasmJsBrowserDistribution -PenableJs=true — full production bundle builds (5.56 MiB app wasm + 7.91 MiB Skiko wasm)
  • ./gradlew jvmTest — existing JVM tests unaffected

Type of Change

  • New feature (non-breaking change that adds functionality)
  • Refactoring (no functional changes) — commonMain multiplatform cleanup

Additional Notes

  • site/ is excluded by the global ~/.gitignore; CI uses git add -f workaround. Consider adding a repo-level .gitignore entry to explicitly track site/.
  • wasmJs bundle is ~13.5 MiB uncompressed; Brotli compression on Cloudflare will bring this to ~3–4 MiB on the wire.

🤖 Generated with Claude Code

tstapler and others added 3 commits April 18, 2026 13:31
Adds the implementation plan for the GitHub Pages site (Astro + Starlight),
two-job CI pipeline, landing page content, demo page with graceful fallback,
user docs, and developer docs. Includes three ADRs for site framework,
CI architecture, and GitHub Pages deployment decisions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ipeline

- Migrate browser target from js(IR) to wasmJs with Compose CanvasBasedWindow
- Add DemoFileSystem for in-memory demo graph content (no SQLite needed)
- Add coi-serviceworker.min.js for SharedArrayBuffer/COOP/COEP on GitHub Pages
- Create Astro + Starlight documentation site (site/) with 5 user docs and 4 developer docs
- Add landing page and /demo page embedding the wasmJs app
- Set up GitHub Actions pages.yml with build-demo + build-site + deploy pipeline
- Configure custom domain stelekit.stapler.dev via CNAME
- Move OpenTelemetry API dependency from commonMain to jvmCommonMain
- Add expect/actual OtelRepositoryWrappers for wasmJs (no-op) vs JVM (instrumented)
- Fix commonMain JVM leakage: @volatile, Dispatchers.IO, java.io.File, String.format
- Fix settings.gradle.kts repositoriesMode to PREFER_PROJECT for wasmJs toolchain downloads

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n files

- Fix settings.gradle.kts: PREFER_PROJECT mode allows Kotlin wasmJs plugin to
  register Node.js/Yarn/Binaryen Ivy repos (PREFER_SETTINGS blocked them)
- Add GitHub Actions pages.yml workflow for CI/CD deploy pipeline
- Add expect/actual OtelRepositoryWrappers across all platforms
- Move OTel instrumented repos to jvmCommonMain source set
- Add DemoFileSystem, coi-serviceworker, updated index.html for wasmJs
- Add iOS OtelProvider actual stubs
- Update site pages (index.astro, demo.astro) with correct base paths
- Add project_plans research artifacts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 18, 2026 22:50
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a public web presence for SteleKit by introducing an Astro/Starlight documentation site, a wasmJs browser demo entry point, and a GitHub Pages deployment workflow, plus multiplatform cleanup needed for wasmJs compilation.

Changes:

  • Migrates the web target from js(IR) to wasmJs and adds wasmJs-specific platform implementations + demo graph filesystem.
  • Adds site/ Astro + Starlight docs/landing/demo pages and initial user/developer documentation content.
  • Adds GitHub Pages workflow and Gradle settings tweaks to support wasmJs toolchain resolution and deployment.

Reviewed changes

Copilot reviewed 77 out of 94 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
site/tsconfig.json Adds strict TS config for the Astro project.
site/src/pages/index.astro New custom marketing landing page (non-Starlight layout).
site/src/pages/demo.astro New demo wrapper page that conditionally embeds the demo artifact.
site/src/content/docs/user/search.mdx New user docs page: Search.
site/src/content/docs/user/outliner.mdx New user docs page: Outliner.
site/src/content/docs/user/journals.mdx New user docs page: Journals.
site/src/content/docs/user/getting-started.mdx New user docs page: Getting Started.
site/src/content/docs/user/backlinks.mdx New user docs page: Backlinks.
site/src/content/docs/developer/module-structure.mdx New developer docs page: module/source set overview.
site/src/content/docs/developer/contributing.mdx New developer docs page: contribution process.
site/src/content/docs/developer/build.mdx New developer docs page: build/test commands.
site/src/content/docs/developer/architecture.mdx New developer docs page: architecture overview.
site/src/content.config.ts Sets up Starlight docs content collection/schema.
site/public/favicon.svg Adds site favicon asset.
site/public/.nojekyll Disables Jekyll processing for GitHub Pages output.
site/package.json Defines Astro/Starlight dependencies and scripts.
site/astro.config.mjs Astro/Starlight config including site/base and sidebar.
site/README.md Template README for the site directory.
site/.vscode/launch.json Adds VS Code launch config for Astro dev server.
site/.vscode/extensions.json Recommends the Astro VS Code extension.
site/.gitignore Ignores dist, .astro, node_modules, env files, etc.
settings.gradle.kts Switches repositories mode to allow wasm toolchain repos.
project_plans/stelekit-documentation-and-branding/research/synthesis.md Adds research synthesis supporting the chosen approach.
project_plans/stelekit-documentation-and-branding/research/research_plan.md Adds research plan document.
project_plans/stelekit-documentation-and-branding/research/findings-stack.md Adds stack evaluation findings.
project_plans/stelekit-documentation-and-branding/research/findings-pitfalls.md Adds wasm/browser + Pages pitfalls findings.
project_plans/stelekit-documentation-and-branding/research/findings-features.md Adds feature/IA research findings.
project_plans/stelekit-documentation-and-branding/research/findings-architecture.md Adds CI/site/demo architecture research findings.
project_plans/stelekit-documentation-and-branding/requirements.md Adds requirements document for the milestone.
project_plans/stelekit-documentation-and-branding/decisions/ADR-003-github-pages-nojekyll-coi.md Adds ADR for Pages + .nojekyll + COI service worker approach.
project_plans/stelekit-documentation-and-branding/decisions/ADR-002-monorepo-two-job-ci.md Adds ADR for monorepo two-job CI strategy.
project_plans/stelekit-documentation-and-branding/decisions/ADR-001-astro-starlight.md Adds ADR selecting Astro + Starlight.
kmp/webpack.config.js Removes custom webpack config (no longer needed).
kmp/webpack.config.d/sqljs-config.js Removes sql.js copy-webpack setup (no longer needed).
kmp/src/wasmJsMain/resources/index.html Adds wasmJs demo bootstrap HTML (canvas + COI service worker).
kmp/src/wasmJsMain/resources/coi-serviceworker.min.js Adds COOP/COEP service worker shim for SharedArrayBuffer.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/util/Time.js.kt Adds wasmJs PlatformTime implementation.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/ui/theme/DynamicColorScheme.js.kt wasmJs actual: disables dynamic colors.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/ui/components/PlatformFrameTimeOverlay.js.kt wasmJs actual: frame-time overlay stub.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/ui/components/DebugMenuOverlay.js.kt wasmJs actual: debug menu stub.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/ui/PlatformClipboardProvider.js.kt wasmJs clipboard provider implementation.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/ui/PlatformBottomBar.js.kt wasmJs actual: bottom bar stub.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/ui/PlatformBackHandler.js.kt wasmJs actual: back handler stub.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/ui/ModifierExtensions.js.kt wasmJs actual: navigation input + long-press behavior stubs.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/platform/ResourceLoader.js.kt wasmJs resource loader stub.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/platform/PlatformSettings.kt wasmJs settings via localStorage.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/platform/PlatformFileSystem.kt wasmJs filesystem stub implementation.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/platform/GitManager.kt wasmJs git manager stub implementation.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/platform/DynamicColorSupport.js.kt wasmJs actual: dynamic color support false.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/platform/DemoFileSystem.kt Adds in-memory demo filesystem with seeded markdown pages.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/performance/OtelRepositoryWrappers.js.kt wasmJs actual: OTel repo wrapping no-op.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/performance/OtelProvider.js.kt wasmJs actual: OTel provider no-op/unsupported.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/performance/DeviceInfo.js.kt wasmJs device info actual implementation.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/db/PlatformUtils.js.kt wasmJs DB path/migration utils.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/db/DriverFactory.js.kt wasmJs driver factory stub (forces IN_MEMORY backend).
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/coroutines/PlatformDispatcher.js.kt wasmJs dispatcher mapping.
kmp/src/wasmJsMain/kotlin/dev/stapler/stelekit/browser/Main.kt Adds wasmJs Compose CanvasBasedWindow entry point.
kmp/src/jvmMain/kotlin/dev/stapler/stelekit/platform/PlatformFileSystem.kt Adds JVM renameFile override delegating to base implementation.
kmp/src/jvmMain/kotlin/dev/stapler/stelekit/performance/OtelProvider.jvm.kt Adjusts OTel provider API to return Any for common expect/actual.
kmp/src/jvmCommonMain/kotlin/dev/stapler/stelekit/platform/JvmFileSystemBase.kt Adds rename/move helper implementation.
kmp/src/jvmCommonMain/kotlin/dev/stapler/stelekit/performance/OtelRepositoryWrappers.jvm.kt Adds JVM OTel repo wrappers via tracer casting.
kmp/src/jvmCommonMain/kotlin/dev/stapler/stelekit/performance/OtelCoroutineContext.kt Adds coroutine helper for executing within a span.
kmp/src/jvmCommonMain/kotlin/dev/stapler/stelekit/performance/InstrumentedSearchRepository.kt Adds instrumented search repository wrapper (delegating).
kmp/src/jvmCommonMain/kotlin/dev/stapler/stelekit/performance/InstrumentedPageRepository.kt Adds instrumented page repository wrapper (spans around writes).
kmp/src/jsMain/resources/index.html Removes old JS(IR) demo bootstrap page.
kmp/src/jsMain/kotlin/dev/stapler/stelekit/util/Time.js.kt Removes old JS(IR) PlatformTime impl.
kmp/src/jsMain/kotlin/dev/stapler/stelekit/platform/PlatformFileSystem.kt Removes old JS(IR) filesystem stub implementation.
kmp/src/jsMain/kotlin/dev/stapler/stelekit/db/DriverFactory.js.kt Removes old sql.js worker driver wiring.
kmp/src/jsMain/kotlin/dev/stapler/stelekit/browser/Main.kt Removes old JS(IR) DOM-based entry point.
kmp/src/iosMain/kotlin/dev/stapler/stelekit/performance/OtelRepositoryWrappers.ios.kt Adds iOS OTel repo wrapper no-ops.
kmp/src/iosMain/kotlin/dev/stapler/stelekit/performance/OtelProvider.ios.kt Adds iOS OTel provider no-op/unsupported.
kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/onboarding/Onboarding.kt Switches onboarding APIs to FileSystem abstraction.
kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/StelekitViewModel.kt Uses FileSystem + PlatformDispatcher.IO in one call site.
kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/App.kt Accepts injected GraphManager and uses FileSystem; adjusts formatting logic.
kmp/src/commonMain/kotlin/dev/stapler/stelekit/repository/RepositoryFactory.kt Centralizes OTel wrapping and uses V7 UUID generator for session IDs.
kmp/src/commonMain/kotlin/dev/stapler/stelekit/platform/FileSystem.kt Adds renameFile API to filesystem abstraction.
kmp/src/commonMain/kotlin/dev/stapler/stelekit/performance/RingBufferSpanExporter.kt Removes synchronization annotations from ring buffer exporter.
kmp/src/commonMain/kotlin/dev/stapler/stelekit/performance/OtelRepositoryWrappers.kt Adds expect declarations for repo wrapping per platform.
kmp/src/commonMain/kotlin/dev/stapler/stelekit/performance/OtelProvider.kt Makes OTel API types Any in common to avoid non-wasm deps.
kmp/src/commonMain/kotlin/dev/stapler/stelekit/performance/HistogramWriter.kt Switches to PlatformDispatcher.IO.
kmp/src/commonMain/kotlin/dev/stapler/stelekit/performance/HistogramRetentionJob.kt Switches to PlatformDispatcher.IO.
kmp/src/commonMain/kotlin/dev/stapler/stelekit/performance/DebugBuildConfig.kt Uses @kotlin.concurrent.Volatile.
kmp/src/commonMain/kotlin/dev/stapler/stelekit/db/SidecarManager.kt Replaces putIfAbsent with Kotlin map equivalent.
kmp/src/commonMain/kotlin/dev/stapler/stelekit/db/GraphWriter.kt Switches to FileSystem abstraction.
kmp/src/commonMain/kotlin/dev/stapler/stelekit/db/GraphManager.kt Adds default backend parameter, uses filesystem rename, and updates timestamp calls.
kmp/src/androidMain/kotlin/dev/stapler/stelekit/performance/OtelProvider.android.kt Adjusts OTel provider API to return Any for common expect/actual.
kmp/build.gradle.kts Adds wasmJs target and moves OTel API dep to JVM/Android-only source set.
kmp/README.md Updates platform listing and commands for wasmJs.
docs/tasks/stelekit-site.md Adds detailed implementation plan for the docs site + CI.
docs/tasks/browser-wasm-demo.md Adds detailed plan for wasmJs demo migration.
docs/tasks/TODO.md Adds two new top-level tasks for site + wasm demo.
.github/workflows/pages.yml Adds Pages build/deploy workflow (build demo + build site + deploy).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread site/src/content/docs/user/outliner.mdx Outdated
Comment thread site/src/content/docs/developer/module-structure.mdx
Comment thread .github/workflows/pages.yml
Comment thread site/src/content/docs/developer/build.mdx
Comment thread kmp/README.md Outdated
Comment thread kmp/src/commonMain/kotlin/dev/stapler/stelekit/db/GraphManager.kt
Comment thread kmp/src/wasmJsMain/resources/index.html
Comment thread site/src/content/docs/user/getting-started.mdx
tstapler and others added 5 commits April 18, 2026 15:59
…README

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… repos

PREFER_PROJECT broke Kotlin Native iOS compilation with a
KotlinNativeBundleBuildService provider conflict. Switch back to
PREFER_SETTINGS and explicitly declare Node.js, Yarn, and Binaryen Ivy
repositories so the wasmJs toolchain can resolve them without giving the
plugin free rein to add project-level repos.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Keep branch version which adds Binaryen Ivy repo on top of main's
Node.js + Yarn repos — required for wasmJs production bundle build.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix hardcoded /stelekit/ base in 3 doc links (outliner, getting-started x2)
- Fix jsMain → wasmJsMain in module-structure and build docs
- Fix DemoFileSystem + GraphManager imports: kotlin.time.Clock → kotlinx.datetime.Clock
- Fix kmp/README task name: wasmJsBrowserProductionWebpack → wasmJsBrowserDistribution
- Use performance.now() in Time.js.kt for monotonic, sub-ms precision timing
- Update RingBufferSpanExporter KDoc: remove false thread-safety claim
- pages.yml: fall back to last successful run's demo artifact for site-only deploys

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
kotlinx.datetime.Clock is a typealias in 0.7.1; Kotlin typealiases do not
forward nested objects so Clock.System is unresolved via the alias.
kotlin.time.Clock.System is the correct direct reference.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@tstapler
tstapler merged commit 4774c51 into main Apr 19, 2026
5 checks passed
tstapler added a commit that referenced this pull request Apr 27, 2026
Move 29 completed docs/tasks/ plans to docs/archive/tasks/ based on
evidence of implementation in the codebase and merged PRs. Update
docs/tasks/TODO.md to mark SteleKit site, browser WASM demo, all-pages
view, and recent pages as complete.

Archived: android-features-integration (PR #31), android-readiness,
android-ux-overhaul, block-state-management-refactor, browser-wasm-demo
(PR #3), direct-sql-write-enforcement, fdroid-setup (PR #42),
file-registry-refactor, hashtag-links, journal-service-extraction,
migration-framework, mobile-voice-mode (PR #27), page-term-highlighting,
perf-export-and-query-tracing, performance-monitoring (PR #38),
progressive-loading-tasks, robust-demo-graph, search-improvements (PR #22),
span-viewer-improvements, stelekit-export, stelekit-import, stelekit-performance,
stelekit-site (PR #3), watcher-data-loss-fix, wiki-link-autocomplete,
all-pages-view, recent-pages, TODO-root (outdated root TODO.md).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
tstapler added a commit that referenced this pull request Sep 1, 2026
Closes Epic 8.2 of the android-git-saf-shadow-worktree plan: zero test
coverage of AndroidGitRepository against a real Robolectric shadow
worktree (finding #8).

- AndroidGitRepositoryShadowWorktreeTest: init/stageSubdir/commit/status
  end-to-end; merge()'s conflict-path SAF mapping (regression guard for
  commit 61b689fa61); checkoutFile() SAF write-back round trip;
  resolveForJGit() literal regression test (validation.md Gap #2).
- GitPathResolverChainTest: shadowWorktreeFor() direct-access-wins/
  caching/per-subpath-key decision logic; sweepOrphans() stale-vs-fresh-
  vs-markerless orphan sweep.
- AndroidGitRepositoryStorageGuardTest: StatFs pre-clone storage guard,
  error and happy path (validation.md Gap #3), using Robolectric's
  ShadowStatFs (confirmed via javap against shadows-framework:4.16 —
  registerStats(path, totalBlocks, freeBlocks, availableBlocks),
  BLOCK_SIZE=4096).

Marks AndroidGitRepository.shadowWorktreeFor/resolveForJGit internal
(was private) for direct test access — no other production logic
changed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CYKvFLTDH53wzEkXzaaajF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants