From 8a1c396bade6a580e08f2afd4425e222d0693ae1 Mon Sep 17 00:00:00 2001
From: bbopen
Date: Sat, 21 Mar 2026 15:25:48 -0700
Subject: [PATCH 1/3] feat(docs): redesign hero with llm copy block and
extracted features
---
docs/.vitepress/theme/components/Hero3D.vue | 320 ++++++++++++++++----
docs/index.md | 13 -
docs/public/llms-full.txt | 60 ++--
scripts/generate-llms-full.mjs | 3 +-
4 files changed, 292 insertions(+), 104 deletions(-)
diff --git a/docs/.vitepress/theme/components/Hero3D.vue b/docs/.vitepress/theme/components/Hero3D.vue
index 2ec79875..5db40ec6 100644
--- a/docs/.vitepress/theme/components/Hero3D.vue
+++ b/docs/.vitepress/theme/components/Hero3D.vue
@@ -7,12 +7,39 @@ const { site } = useData()
const canvasRef = ref(null)
let threeScene: ThreeSceneReturn | null = null
let scrollTicking = false
-let scrollRafId: number | null = null
+
+const features = [
+ { icon: '๐', title: 'Full Type Safety', details: 'TypeScript definitions generated directly from Python source analysis via AST โ no manual type writing.' },
+ { icon: '๐', title: 'Multi-Runtime', details: 'One API across Node.js, Bun, Deno (subprocess), and browsers (Pyodide WebAssembly).' },
+ { icon: 'โก', title: 'Rich Data Types', details: 'First-class support for numpy, pandas, scipy, torch, and sklearn with Apache Arrow binary transport.' },
+ { icon: '๐ ', title: 'Zero-Config CLI', details: 'Run npx tywrap generate and get production-ready TypeScript wrappers with a single command.' }
+]
function getBase(): string {
return site.value.base || '/'
}
+const copied = ref(false)
+let copyTimeout: number
+
+async function copyPrompt() {
+ try {
+ const response = await fetch(getBase() + 'llms-full.txt')
+ if (!response.ok) throw new Error('Failed to fetch llms-full.txt')
+ const text = await response.text()
+
+ await navigator.clipboard.writeText(text)
+
+ copied.value = true
+ if (copyTimeout) clearTimeout(copyTimeout)
+ copyTimeout = window.setTimeout(() => {
+ copied.value = false
+ }, 2500)
+ } catch (err) {
+ console.error('Failed to copy prompt: ', err)
+ }
+}
+
// Ensure the scroll event is throttled by requestAnimationFrame
function onScroll() {
if (!scrollTicking && threeScene && threeScene.onScroll) {
@@ -88,12 +115,36 @@ onBeforeUnmount(() => {
+
+
+
+
+
+
{{ feature.icon }}
+
+
{{ feature.title }}
+
+
@@ -127,16 +178,25 @@ onBeforeUnmount(() => {
.hero-section {
position: relative;
- min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
- align-items: flex-start; /* Force left alignment */
+ align-items: flex-start;
z-index: 10;
width: 100%;
- padding-bottom: 5rem;
- /* Align to Vitepress standard left container edge */
+ padding-bottom: 2rem;
+ padding-top: 8rem;
+ box-sizing: border-box;
padding-left: max(24px, calc((100vw - var(--vp-layout-max-width, 1152px)) / 2));
+ padding-right: max(24px, calc((100vw - var(--vp-layout-max-width, 1152px)) / 2));
+}
+
+@media (min-width: 1024px) {
+ .hero-section {
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+ }
}
/* ----------------------------------------------------------------
@@ -144,9 +204,10 @@ onBeforeUnmount(() => {
---------------------------------------------------------------- */
.hero-content {
position: relative;
- max-width: 44rem; /* Restrict width to keep left-aligned */
- padding-top: 4rem;
+ max-width: 44rem;
+ width: 100%;
text-align: left;
+ flex: 1;
}
.hero-headline {
@@ -205,76 +266,211 @@ onBeforeUnmount(() => {
flex-direction: column;
align-items: flex-start;
gap: 1.5rem;
+ width: 100%;
}
-@media (min-width: 640px) {
- .hero-actions {
- flex-direction: row;
- }
+.copy-agent-block {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ gap: 1rem;
}
-.btn-primary,
-.btn-secondary {
- display: inline-flex;
+.copy-instruction {
+ font-size: 0.95rem;
+ color: #9ca3af;
+ font-family: var(--vp-font-family-mono);
+ margin: 0;
+ letter-spacing: -0.01em;
+}
+
+.prompt-copy-container {
+ display: flex;
align-items: center;
- justify-content: center;
+ justify-content: space-between;
width: 100%;
- padding: 1rem 2.5rem;
+ max-width: 32rem;
+ padding: 1rem 1.25rem;
+ background: rgba(15, 15, 15, 0.6);
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ border-radius: 0.75rem;
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
+ cursor: pointer;
+ transition: all 0.2s ease;
+ color: #d1d5db;
+ font-family: var(--vp-font-family-mono);
+ font-size: 0.95rem;
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.2);
+}
+
+.prompt-copy-container:hover {
+ background: rgba(25, 25, 25, 0.8);
+ border-color: rgba(255, 255, 255, 0.2);
+ transform: translateY(-2px);
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -2px rgba(0, 0, 0, 0.3);
+}
+
+.prompt-copy-container:active {
+ transform: translateY(1px);
+ box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.4);
+}
+
+.prompt-copy-container.copied {
+ background: rgba(16, 185, 129, 0.15);
+ border-color: rgba(16, 185, 129, 0.4);
+ color: #10b981;
+}
+
+.prompt-text {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ overflow: hidden;
+ text-align: left;
+}
+
+.prompt-prefix {
+ color: #f4b459; /* Amber/Python focus */
font-weight: 700;
- font-size: 1.125rem;
- border-radius: 9999px;
- text-align: center;
- transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+ user-select: none;
+}
+
+.prompt-url {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.copy-icon-wrapper {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ color: #9ca3af;
+ flex-shrink: 0;
+ margin-left: 1rem;
+ transition: color 0.2s ease;
+}
+
+.prompt-copy-container:hover .copy-icon-wrapper {
+ color: #ffffff;
+}
+
+.prompt-copy-container.copied .copy-icon-wrapper {
+ color: #10b981;
+}
+
+.copied-label {
+ font-size: 0.85rem;
+ font-weight: 600;
+ animation: fadeIn 0.3s ease;
+}
+
+/* Secondary Link */
+.link-secondary {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ font-size: 0.95rem;
+ color: #9ca3af;
text-decoration: none;
- cursor: pointer;
- letter-spacing: 0.05em;
+ font-weight: 500;
+ transition: color 0.2s ease;
+ margin-top: 0.25rem;
+}
+
+.link-secondary:hover {
+ color: #ffffff;
+}
+
+.link-secondary .arrow {
+ transition: transform 0.2s ease;
+}
+
+.link-secondary:hover .arrow {
+ transform: translateX(4px);
}
-@media (min-width: 640px) {
- .btn-primary,
- .btn-secondary {
- width: auto;
+/* ----------------------------------------------------------------
+ Features (Right Column)
+ ---------------------------------------------------------------- */
+.hero-features {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ margin-top: 3rem;
+ width: 100%;
+ max-width: 28rem;
+ flex-shrink: 0;
+}
+
+@media (min-width: 1024px) {
+ .hero-features {
+ margin-top: 0;
+ margin-left: 4rem;
}
}
-/* Brutalist modern key style for buttons, adapting Hermes 4 feel */
-.btn-primary {
- background: #f4b459; /* Amber/Python focus */
- color: #000000;
- border: 2px solid transparent;
- box-shadow: 0 4px 0 #b45309, 0 10px 20px -5px rgba(245, 158, 11, 0.4);
+.feature-card {
+ display: flex;
+ align-items: flex-start;
+ background: rgba(15, 15, 15, 0.65);
+ border: 1px solid rgba(255, 255, 255, 0.08);
+ border-radius: 1rem;
+ padding: 1.25rem;
+ backdrop-filter: blur(20px);
+ -webkit-backdrop-filter: blur(20px);
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
+ transition: transform 0.2s ease, background 0.2s ease, border-color 0.2s ease;
}
-.btn-primary:hover {
- background: #fcd34d;
- box-shadow: 0 6px 0 #d97706, 0 15px 30px -5px rgba(245, 158, 11, 0.6);
- transform: translateY(-2px);
+.feature-card:hover {
+ background: rgba(25, 25, 25, 0.85);
+ transform: translateX(-4px);
+ border-color: rgba(255, 255, 255, 0.2);
}
-.btn-primary:active {
- box-shadow: 0 0px 0 #b45309, 0 5px 10px -5px rgba(245, 158, 11, 0.4);
- transform: translateY(4px);
+.feature-icon {
+ font-size: 1.5rem;
+ margin-right: 1.25rem;
+ background: rgba(255, 255, 255, 0.05);
+ padding: 0.5rem;
+ border-radius: 0.5rem;
+ border: 1px solid rgba(255, 255, 255, 0.05);
}
-.btn-secondary {
- background: rgba(255, 255, 255, 0.03);
- backdrop-filter: blur(12px);
- -webkit-backdrop-filter: blur(12px);
- color: #ffffff;
- border: 1px solid rgba(255, 255, 255, 0.2);
- box-shadow: 0 4px 0 rgba(255, 255, 255, 0.1), 0 10px 30px rgba(0, 0, 0, 0.2);
+.feature-text {
+ flex: 1;
}
-.btn-secondary:hover {
- background: rgba(255, 255, 255, 0.08);
- border-color: rgba(255, 255, 255, 0.4);
- box-shadow: 0 6px 0 rgba(255, 255, 255, 0.2), 0 15px 40px rgba(0, 0, 0, 0.3);
- transform: translateY(-2px);
+.feature-title {
+ color: #fff;
+ font-size: 1rem;
+ font-weight: 600;
+ margin: 0 0 0.5rem 0;
+ line-height: 1.2;
}
-.btn-secondary:active {
- box-shadow: 0 0px 0 rgba(255, 255, 255, 0.2), 0 5px 10px rgba(0, 0, 0, 0.2);
- transform: translateY(4px);
+.feature-details {
+ color: #d1d5db;
+ font-size: 0.9rem;
+ margin: 0;
+ line-height: 1.6;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
+}
+
+.feature-details :deep(code) {
+ background: rgba(255, 255, 255, 0.1);
+ padding: 0.1rem 0.3rem;
+ border-radius: 4px;
+ font-family: var(--vp-font-family-mono);
+ font-size: 0.8em;
+}
+
+@keyframes fadeIn {
+ from { opacity: 0; }
+ to { opacity: 1; }
}
/* ----------------------------------------------------------------
@@ -303,6 +499,10 @@ onBeforeUnmount(() => {
animation-delay: 0.4s;
}
+.delay-3 {
+ animation-delay: 0.6s;
+}
+
/* Disable all decorative animations for motion-sensitive users */
@media (prefers-reduced-motion: reduce) {
.fade-up {
diff --git a/docs/index.md b/docs/index.md
index 73790a76..7967f887 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -1,19 +1,6 @@
---
layout: home
-features:
- - icon: ๐
- title: Full Type Safety
- details: TypeScript definitions generated directly from Python source analysis via AST โ no manual type writing.
- - icon: ๐
- title: Multi-Runtime
- details: One API across Node.js, Bun, Deno (subprocess), and browsers (Pyodide WebAssembly).
- - icon: โก
- title: Rich Data Types
- details: First-class support for numpy, pandas, scipy, torch, and sklearn with Apache Arrow binary transport.
- - icon: ๐
- title: Zero-Config CLI
- details: Run `npx tywrap generate` and get production-ready TypeScript wrappers with a single command.
---
## Quick Start
diff --git a/docs/public/llms-full.txt b/docs/public/llms-full.txt
index 24dbfea9..a7ab63e1 100644
--- a/docs/public/llms-full.txt
+++ b/docs/public/llms-full.txt
@@ -413,14 +413,14 @@ const [sinValue, cosValue, tanValue] = await Promise.all([
## Next Steps
-- [Configuration Guide](/guide/configuration) - Complete configuration reference
-- [Runtime Guides](/guide/runtimes/node) - Platform-specific setup
-- [Examples](/examples/) - Usage patterns and examples
-- [Troubleshooting](/troubleshooting/) - Common issues and solutions
+- [Configuration Guide](https://bbopen.github.io/tywrap/guide/configuration) - Complete configuration reference
+- [Runtime Guides](https://bbopen.github.io/tywrap/guide/runtimes/node) - Platform-specific setup
+- [Examples](https://bbopen.github.io/tywrap/examples/) - Usage patterns and examples
+- [Troubleshooting](https://bbopen.github.io/tywrap/troubleshooting/) - Common issues and solutions
## Support
-- [Troubleshooting Guide](/troubleshooting/)
+- [Troubleshooting Guide](https://bbopen.github.io/tywrap/troubleshooting/)
- [GitHub Issues](https://github.com/bbopen/tywrap/issues)
- [GitHub Discussions](https://github.com/bbopen/tywrap/discussions)
@@ -790,7 +790,7 @@ export default defineConfig({
});
```
-See [Environment Variables](/reference/env-vars) for the full implemented list.
+See [Environment Variables](https://bbopen.github.io/tywrap/reference/env-vars) for the full implemented list.
## Advanced Configuration Patterns
@@ -1001,13 +1001,13 @@ python3 -c "import your_module; print(your_module.__file__)"
}
```
-For more troubleshooting, see [Troubleshooting Guide](/troubleshooting/).
+For more troubleshooting, see [Troubleshooting Guide](https://bbopen.github.io/tywrap/troubleshooting/).
## Next Steps
-- [Runtime Guides](/guide/runtimes/node) - Platform-specific configuration
-- [Examples](/examples/) - Configuration examples
-- [API Reference](/reference/api/) - Complete API documentation
+- [Runtime Guides](https://bbopen.github.io/tywrap/guide/runtimes/node) - Platform-specific configuration
+- [Examples](https://bbopen.github.io/tywrap/examples/) - Configuration examples
+- [API Reference](https://bbopen.github.io/tywrap/reference/api/) - Complete API documentation
---
@@ -1696,10 +1696,10 @@ function getNextBridge() {
## Next Steps
-- [Configuration Guide](/guide/configuration) - Complete configuration reference
-- [Examples](/examples/) - Usage examples and patterns
-- [Troubleshooting](/troubleshooting/) - Common issues and solutions
-- [API Reference](/reference/api/) - Complete API documentation
+- [Configuration Guide](https://bbopen.github.io/tywrap/guide/configuration) - Complete configuration reference
+- [Examples](https://bbopen.github.io/tywrap/examples/) - Usage examples and patterns
+- [Troubleshooting](https://bbopen.github.io/tywrap/troubleshooting/) - Common issues and solutions
+- [API Reference](https://bbopen.github.io/tywrap/reference/api/) - Complete API documentation
---
@@ -1782,7 +1782,7 @@ setRuntimeBridge(new NodeBridge({
## Environment Variables
-The same `TYWRAP_*` env vars work under Bun. See the [environment variables reference](/reference/env-vars).
+The same `TYWRAP_*` env vars work under Bun. See the [environment variables reference](https://bbopen.github.io/tywrap/reference/env-vars).
## Troubleshooting
@@ -1804,8 +1804,8 @@ tywrap works with [Deno](https://deno.land/) 1.46+ using the same `NodeBridge` a
**Deno Deploy does NOT support subprocess execution.** Because `NodeBridge` spawns a Python subprocess, it cannot run in Deno Deploy.
**Alternatives for Deno Deploy:**
-- Use [`PyodideBridge`](/guide/runtimes/browser) โ runs Python in-browser via WebAssembly (no subprocess)
-- Use [`HttpBridge`](/guide/runtimes/http) โ connects to a remote Python server over HTTP
+- Use [`PyodideBridge`](https://bbopen.github.io/tywrap/guide/runtimes/browser) โ runs Python in-browser via WebAssembly (no subprocess)
+- Use [`HttpBridge`](https://bbopen.github.io/tywrap/guide/runtimes/http) โ connects to a remote Python server over HTTP
## Installation
@@ -1864,13 +1864,13 @@ See the [Node.js guide](./node) for the full `NodeBridgeOptions` reference โ a
## Environment Variables
-The same `TYWRAP_*` env vars work under Deno. See the [environment variables reference](/reference/env-vars).
+The same `TYWRAP_*` env vars work under Deno. See the [environment variables reference](https://bbopen.github.io/tywrap/reference/env-vars).
## Troubleshooting
**`PermissionDenied: Requires run access to "python3"`** โ Add `--allow-run=python3` to your `deno run` command.
-**`NotSupported: Subprocess access is not allowed`** โ You are running in Deno Deploy. Switch to [`PyodideBridge`](/guide/runtimes/browser) or [`HttpBridge`](/guide/runtimes/http).
+**`NotSupported: Subprocess access is not allowed`** โ You are running in Deno Deploy. Switch to [`PyodideBridge`](https://bbopen.github.io/tywrap/guide/runtimes/browser) or [`HttpBridge`](https://bbopen.github.io/tywrap/guide/runtimes/http).
See the [Node.js troubleshooting guide](./node) for additional patterns.
@@ -2002,7 +2002,7 @@ setRuntimeBridge(new HttpBridge({
`HttpBridge` expects a server that accepts POST requests with JSON/Arrow payloads. You must implement or deploy a compatible server endpoint. The protocol is stateless โ each call is an independent POST request.
-> **Note:** A built-in server command is not yet available. See the [API reference](/reference/api/) for the expected request/response format.
+> **Note:** A built-in server command is not yet available. See the [API reference](https://bbopen.github.io/tywrap/reference/api/) for the expected request/response format.
## Apache Arrow
@@ -2022,7 +2022,7 @@ registerArrowDecoder(bytes => tableFromIPC(bytes));
| `TYWRAP_CODEC_FALLBACK=json` | Disable Arrow, use JSON only |
| `TYWRAP_CODEC_MAX_BYTES` | Cap max response size |
-See the [environment variables reference](/reference/env-vars).
+See the [environment variables reference](https://bbopen.github.io/tywrap/reference/env-vars).
## Security
@@ -2161,7 +2161,7 @@ export default defineConfig({
});
```
-See the [Configuration guide](/guide/configuration) for the full config surface.
+See the [Configuration guide](https://bbopen.github.io/tywrap/guide/configuration) for the full config surface.
---
@@ -2770,12 +2770,12 @@ await counter.disposeHandle();
## More Docs
-- [Getting started](/guide/getting-started)
-- [Configuration](/guide/configuration)
-- [Node runtime](/guide/runtimes/node)
-- [Browser runtime](/guide/runtimes/browser)
-- [Troubleshooting](/troubleshooting/)
-- [Type mapping](/reference/type-mapping)
+- [Getting started](https://bbopen.github.io/tywrap/guide/getting-started)
+- [Configuration](https://bbopen.github.io/tywrap/guide/configuration)
+- [Node runtime](https://bbopen.github.io/tywrap/guide/runtimes/node)
+- [Browser runtime](https://bbopen.github.io/tywrap/guide/runtimes/browser)
+- [Troubleshooting](https://bbopen.github.io/tywrap/troubleshooting/)
+- [Type mapping](https://bbopen.github.io/tywrap/reference/type-mapping)
---
@@ -3429,6 +3429,6 @@ npx tsc --noEmit --traceResolution
```
This troubleshooting guide covers the most common issues. For runtime-specific detail, see:
-- [Node.js Runtime](/guide/runtimes/node)
-- [Browser Runtime (Pyodide)](/guide/runtimes/browser)
+- [Node.js Runtime](https://bbopen.github.io/tywrap/guide/runtimes/node)
+- [Browser Runtime (Pyodide)](https://bbopen.github.io/tywrap/guide/runtimes/browser)
- [Build Tool Issues](#build-tool-issues)
diff --git a/scripts/generate-llms-full.mjs b/scripts/generate-llms-full.mjs
index bfb816e6..bf6ee16c 100644
--- a/scripts/generate-llms-full.mjs
+++ b/scripts/generate-llms-full.mjs
@@ -77,7 +77,8 @@ async function main() {
const sections = [];
for (const file of orderedDocs) {
- const text = await readFile(file, 'utf8');
+ let text = await readFile(file, 'utf8');
+ text = text.replaceAll('](/', '](https://bbopen.github.io/tywrap/');
sections.push(`\n${text.trimEnd()}\n`);
}
From d62b06472100f07969de941b7efd01e1627171d2 Mon Sep 17 00:00:00 2001
From: bbopen
Date: Sat, 21 Mar 2026 16:25:39 -0700
Subject: [PATCH 2/3] fix(docs): address CodeRabbit review feedback on link
generation and scrollRafId
---
docs/.vitepress/theme/components/Hero3D.vue | 1 +
docs/public/llms-full.txt | 27 ++++++---------------
scripts/generate-llms-full.mjs | 22 ++++++++++++++++-
3 files changed, 29 insertions(+), 21 deletions(-)
diff --git a/docs/.vitepress/theme/components/Hero3D.vue b/docs/.vitepress/theme/components/Hero3D.vue
index 5db40ec6..226fec78 100644
--- a/docs/.vitepress/theme/components/Hero3D.vue
+++ b/docs/.vitepress/theme/components/Hero3D.vue
@@ -7,6 +7,7 @@ const { site } = useData()
const canvasRef = ref(null)
let threeScene: ThreeSceneReturn | null = null
let scrollTicking = false
+let scrollRafId: number | null = null
const features = [
{ icon: '๐', title: 'Full Type Safety', details: 'TypeScript definitions generated directly from Python source analysis via AST โ no manual type writing.' },
diff --git a/docs/public/llms-full.txt b/docs/public/llms-full.txt
index a7ab63e1..35799255 100644
--- a/docs/public/llms-full.txt
+++ b/docs/public/llms-full.txt
@@ -7,19 +7,6 @@
---
layout: home
-features:
- - icon: ๐
- title: Full Type Safety
- details: TypeScript definitions generated directly from Python source analysis via AST โ no manual type writing.
- - icon: ๐
- title: Multi-Runtime
- details: One API across Node.js, Bun, Deno (subprocess), and browsers (Pyodide WebAssembly).
- - icon: โก
- title: Rich Data Types
- details: First-class support for numpy, pandas, scipy, torch, and sklearn with Apache Arrow binary transport.
- - icon: ๐
- title: Zero-Config CLI
- details: Run `npx tywrap generate` and get production-ready TypeScript wrappers with a single command.
---
## Quick Start
@@ -1054,9 +1041,9 @@ Do you need subprocess-based Python execution?
| Bridge | Export | Guide |
|--------|--------|-------|
-| `NodeBridge` | `tywrap/node` | [Node.js](./node) ยท [Bun](./bun) ยท [Deno](./deno) |
-| `PyodideBridge` | `tywrap/pyodide` | [Browser](./browser) |
-| `HttpBridge` | `tywrap/http` | [HTTP](./http) |
+| `NodeBridge` | `tywrap/node` | [Node.js](https://bbopen.github.io/tywrap/guide/runtimes/node) ยท [Bun](https://bbopen.github.io/tywrap/guide/runtimes/bun) ยท [Deno](https://bbopen.github.io/tywrap/guide/runtimes/deno) |
+| `PyodideBridge` | `tywrap/pyodide` | [Browser](https://bbopen.github.io/tywrap/guide/runtimes/browser) |
+| `HttpBridge` | `tywrap/http` | [HTTP](https://bbopen.github.io/tywrap/guide/runtimes/http) |
---
@@ -1732,7 +1719,7 @@ setRuntimeBridge(new NodeBridge({
## Configuration Options
-`NodeBridge` accepts the same options under Bun as under Node.js. See the [Node.js guide](./node) for the full option reference.
+`NodeBridge` accepts the same options under Bun as under Node.js. See the [Node.js guide](https://bbopen.github.io/tywrap/guide/runtimes/node) for the full option reference.
Key options:
@@ -1790,7 +1777,7 @@ The same `TYWRAP_*` env vars work under Bun. See the [environment variables refe
**Subprocess times out** โ Increase `timeoutMs`. Verify `pip install tywrap-ir` ran in the correct environment.
-See the [Node.js troubleshooting guide](./node) for additional patterns โ all apply equally to Bun.
+See the [Node.js troubleshooting guide](https://bbopen.github.io/tywrap/guide/runtimes/node) for additional patterns โ all apply equally to Bun.
---
@@ -1852,7 +1839,7 @@ deno check src/index.ts
## Configuration Options
-See the [Node.js guide](./node) for the full `NodeBridgeOptions` reference โ all options work identically in Deno.
+See the [Node.js guide](https://bbopen.github.io/tywrap/guide/runtimes/node) for the full `NodeBridgeOptions` reference โ all options work identically in Deno.
## When to Use Each Bridge in Deno
@@ -1872,7 +1859,7 @@ The same `TYWRAP_*` env vars work under Deno. See the [environment variables ref
**`NotSupported: Subprocess access is not allowed`** โ You are running in Deno Deploy. Switch to [`PyodideBridge`](https://bbopen.github.io/tywrap/guide/runtimes/browser) or [`HttpBridge`](https://bbopen.github.io/tywrap/guide/runtimes/http).
-See the [Node.js troubleshooting guide](./node) for additional patterns.
+See the [Node.js troubleshooting guide](https://bbopen.github.io/tywrap/guide/runtimes/node) for additional patterns.
---
diff --git a/scripts/generate-llms-full.mjs b/scripts/generate-llms-full.mjs
index bf6ee16c..2e060583 100644
--- a/scripts/generate-llms-full.mjs
+++ b/scripts/generate-llms-full.mjs
@@ -78,7 +78,27 @@ async function main() {
const sections = [];
for (const file of orderedDocs) {
let text = await readFile(file, 'utf8');
- text = text.replaceAll('](/', '](https://bbopen.github.io/tywrap/');
+
+ // Resolve relative links based on the file's directory path
+ const dirMatch = file.match(/^docs\/(.*\/)/);
+ const dirPath = dirMatch ? dirMatch[1] : '';
+ const baseUrl = `https://bbopen.github.io/tywrap/${dirPath}`;
+
+ text = text.replace(/\]\(([^)]+)\)/g, (match, href) => {
+ if (/^(https?:|mailto:|#)/.test(href)) {
+ return match;
+ }
+ if (href.startsWith('/')) {
+ return `](https://bbopen.github.io/tywrap${href})`;
+ }
+ try {
+ const url = new URL(href, baseUrl);
+ return `](${url.href})`;
+ } catch (e) {
+ return match;
+ }
+ });
+
sections.push(`\n${text.trimEnd()}\n`);
}
From ce56ad10cfbebf29a907021d55e622eee11e85e1 Mon Sep 17 00:00:00 2001
From: bbopen
Date: Sat, 21 Mar 2026 16:28:14 -0700
Subject: [PATCH 3/3] fix(docs): resolve CodeRabbit nitpicks regarding
copyTimeout and base URL config
---
docs/.vitepress/theme/components/Hero3D.vue | 9 +++++++--
scripts/generate-llms-full.mjs | 12 ++++++++++--
2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/docs/.vitepress/theme/components/Hero3D.vue b/docs/.vitepress/theme/components/Hero3D.vue
index 226fec78..15e4fa52 100644
--- a/docs/.vitepress/theme/components/Hero3D.vue
+++ b/docs/.vitepress/theme/components/Hero3D.vue
@@ -21,7 +21,7 @@ function getBase(): string {
}
const copied = ref(false)
-let copyTimeout: number
+let copyTimeout: number | null = null
async function copyPrompt() {
try {
@@ -32,9 +32,10 @@ async function copyPrompt() {
await navigator.clipboard.writeText(text)
copied.value = true
- if (copyTimeout) clearTimeout(copyTimeout)
+ if (copyTimeout !== null) window.clearTimeout(copyTimeout)
copyTimeout = window.setTimeout(() => {
copied.value = false
+ copyTimeout = null
}, 2500)
} catch (err) {
console.error('Failed to copy prompt: ', err)
@@ -83,6 +84,10 @@ function onResize() {
}
onBeforeUnmount(() => {
+ if (copyTimeout !== null) {
+ window.clearTimeout(copyTimeout)
+ copyTimeout = null
+ }
if (scrollRafId !== null) {
window.cancelAnimationFrame(scrollRafId)
scrollRafId = null
diff --git a/scripts/generate-llms-full.mjs b/scripts/generate-llms-full.mjs
index 2e060583..8b901bab 100644
--- a/scripts/generate-llms-full.mjs
+++ b/scripts/generate-llms-full.mjs
@@ -75,6 +75,13 @@ async function main() {
'',
].join('\n');
+ // Derive the canonical site base from the shared VitePress config
+ const configText = await readFile('docs/.vitepress/config.ts', 'utf8');
+ const baseMatch = configText.match(/base:\s*['"]([^'"]+)['"]/);
+ const basePath = baseMatch ? baseMatch[1] : '/';
+ const siteHost = 'https://bbopen.github.io';
+ const canonicalBase = new URL(basePath, siteHost).href;
+
const sections = [];
for (const file of orderedDocs) {
let text = await readFile(file, 'utf8');
@@ -82,14 +89,15 @@ async function main() {
// Resolve relative links based on the file's directory path
const dirMatch = file.match(/^docs\/(.*\/)/);
const dirPath = dirMatch ? dirMatch[1] : '';
- const baseUrl = `https://bbopen.github.io/tywrap/${dirPath}`;
+ const baseUrl = new URL(dirPath, canonicalBase).href;
text = text.replace(/\]\(([^)]+)\)/g, (match, href) => {
if (/^(https?:|mailto:|#)/.test(href)) {
return match;
}
if (href.startsWith('/')) {
- return `](https://bbopen.github.io/tywrap${href})`;
+ // Root-relative links resolve against the canonical base (removing the leading slash)
+ return `](${new URL(href.slice(1), canonicalBase).href})`;
}
try {
const url = new URL(href, baseUrl);