diff --git a/background-ralph/src/trigger/ralph-loop.ts b/background-ralph/src/trigger/ralph-loop.ts
index a9caa52..30721f9 100644
--- a/background-ralph/src/trigger/ralph-loop.ts
+++ b/background-ralph/src/trigger/ralph-loop.ts
@@ -11,42 +11,6 @@ import { appendStatus, agentOutputStream, type TokenUsage, type Prd } from "./st
const execAsync = promisify(exec)
const anthropic = new Anthropic()
-const DEFAULT_PAUSE_EVERY = 5
-
-type TestResult = { hasTests: false } | { hasTests: true; passed: boolean; output: string }
-
-async function runTestsIfExist(repoPath: string): Promise {
- try {
- const packageJsonPath = join(repoPath, "package.json")
- const packageJson = JSON.parse(await readFile(packageJsonPath, "utf-8"))
-
- // Check if test script exists and is meaningful
- const testScript = packageJson.scripts?.test
- if (!testScript || testScript.includes("no test specified")) {
- return { hasTests: false }
- }
-
- logger.info("Running tests", { testScript })
-
- try {
- const { stdout, stderr } = await execAsync("npm test", {
- cwd: repoPath,
- timeout: 120000 // 2 minute timeout
- })
- logger.info("Tests passed", { stdout: stdout.slice(-500) })
- return { hasTests: true, passed: true, output: stdout + stderr }
- } catch (error) {
- const err = error as { stdout?: string; stderr?: string; message?: string }
- const output = (err.stdout ?? "") + (err.stderr ?? "") + (err.message ?? "")
- logger.info("Tests failed", { output: output.slice(-500) })
- return { hasTests: true, passed: false, output }
- }
- } catch {
- // No package.json or parse error
- return { hasTests: false }
- }
-}
-
export type RalphLoopPayload = {
repoUrl: string
prompt: string
@@ -230,22 +194,6 @@ Rules:
}
}
-async function summarizeChanges(diff: string): Promise {
- const response = await anthropic.messages.create({
- model: "claude-sonnet-4-20250514",
- max_tokens: 100,
- messages: [
- {
- role: "user",
- content: `Summarize these git changes in one line (max 72 chars) for a commit message. Be specific about what changed, not generic. No quotes around the message.\n\n${diff.slice(0, 4000)}`,
- },
- ],
- })
- const text = response.content[0]
- if (text.type !== "text") return "Agent changes"
- return text.text.slice(0, 72)
-}
-
async function createPullRequest(
owner: string,
repo: string,
@@ -283,53 +231,6 @@ async function createPullRequest(
}
}
-async function commitAndPush(
- repoPath: string,
- repoUrl: string,
- githubToken: string
-): Promise<{ branchUrl: string; prUrl: string | null } | null> {
- const parsed = parseGitHubUrl(repoUrl)
- logger.info("parseGitHubUrl result", { parsed, repoUrl })
- if (!parsed) return null
-
- const branchName = `ralph-${Date.now()}`
- logger.info("Creating branch", { branchName })
-
- // Configure git user for commits
- await execAsync(`git -C ${repoPath} config user.email "ralph@trigger.dev"`)
- await execAsync(`git -C ${repoPath} config user.name "Ralph (Trigger.dev)"`)
-
- // Create and checkout new branch
- await execAsync(`git -C ${repoPath} checkout -b ${branchName}`)
-
- // Stage all changes
- await execAsync(`git -C ${repoPath} add -A`)
-
- // Check if there are changes to commit
- const { stdout: status } = await execAsync(`git -C ${repoPath} status --porcelain`)
- logger.info("Git status", { status: status.trim() || "(empty)" })
- if (!status.trim()) return null
-
- // Get diff for summarization
- const { stdout: diff } = await execAsync(`git -C ${repoPath} diff --cached`)
- const commitMessage = await summarizeChanges(diff || status)
-
- // Commit
- await execAsync(`git -C ${repoPath} commit -m "${commitMessage.replace(/"/g, '\\"')}"`)
-
- // Set up authenticated remote and push
- const authUrl = `https://${githubToken}@github.com/${parsed.owner}/${parsed.repo}.git`
- await execAsync(`git -C ${repoPath} remote set-url origin ${authUrl}`)
- await execAsync(`git -C ${repoPath} push -u origin ${branchName}`)
-
- const branchUrl = `https://github.com/${parsed.owner}/${parsed.repo}/tree/${branchName}`
-
- // Create PR
- const prUrl = await createPullRequest(parsed.owner, parsed.repo, branchName, commitMessage, githubToken)
-
- return { branchUrl, prUrl }
-}
-
export const ralphLoop = task({
id: "ralph-loop",
maxDuration: 3600,
@@ -453,6 +354,7 @@ build/
const stories = approvedPrd.stories.filter(s => !s.passes)
let completedStories = 0
let userStopped = false
+ const progressLog: string[] = [] // In-memory progress for Ralph loop
for (let i = 0; i < stories.length && !userStopped; i++) {
const story = stories[i]
@@ -464,6 +366,7 @@ build/
type: "story_start",
message: `Starting story ${storyNum}/${totalStories}: ${story.title}`,
story: {
+ id: story.id,
current: storyNum,
total: totalStories,
title: story.title,
@@ -473,16 +376,16 @@ build/
await agentOutputStream.append(`\n\n=== Story ${storyNum}/${totalStories}: ${story.title} ===\n\n`)
- // Build story-specific prompt
- const progressHint = storyNum > 1
- ? `\n\nIMPORTANT: Read progress.txt first to see what previous stories accomplished. Build on that work.`
+ // Build story-specific prompt with inline progress (Ralph loop pattern)
+ const progressContext = progressLog.length > 0
+ ? `\n\n## Previous Stories Completed\n${progressLog.join('\n\n')}\n\nBuild on this work.`
: ""
const storyPrompt = `You are working in a cloned git repository at: ${repoPath}
All file paths should be relative to this directory (e.g., "README.md" not "/README.md").
Overall task: ${prompt}
-${progressHint}
+${progressContext}
Current story (${storyNum}/${totalStories}): ${story.title}
Acceptance criteria:
@@ -531,11 +434,18 @@ Complete this story. When done, the acceptance criteria should be met. Use Read,
await waitUntilComplete()
// Check for changes and commit
+ let storyCommitHash: string | undefined
+ let storyCommitUrl: string | undefined
const { stdout: status } = await execAsync(`git -C ${repoPath} status --porcelain`)
if (status.trim()) {
await execAsync(`git -C ${repoPath} add -A`)
await execAsync(`git -C ${repoPath} commit -m "${story.title.replace(/"/g, '\\"')}"`)
- logger.info("Committed story", { story: story.title })
+ const { stdout: hash } = await execAsync(`git -C ${repoPath} rev-parse HEAD`)
+ storyCommitHash = hash.trim()
+ if (parsed) {
+ storyCommitUrl = `https://github.com/${parsed.owner}/${parsed.repo}/commit/${storyCommitHash}`
+ }
+ logger.info("Committed story", { story: story.title, commitHash: storyCommitHash })
}
// Run build check if package.json has build script
@@ -559,29 +469,23 @@ Complete this story. When done, the acceptance criteria should be met. Use Read,
completedStories++
- // Update progress.txt in repo
- const progressEntry = `## ${story.title}\nCompleted: ${new Date().toISOString().split("T")[0]}\nAcceptance criteria:\n${story.acceptance.map(c => `- ${c}`).join("\n")}\n\n`
- const progressPath = join(repoPath, "progress.txt")
- try {
- await appendFile(progressPath, progressEntry)
- // Stage progress.txt
- await execAsync(`git -C ${repoPath} add progress.txt`)
- } catch {
- // First story, create file
- await writeFile(progressPath, progressEntry)
- await execAsync(`git -C ${repoPath} add progress.txt`)
- }
+ // Update in-memory progress (Ralph loop pattern - no file in repo)
+ progressLog.push(`### ${story.title}\n- ${story.acceptance.join('\n- ')}`)
// Story complete status
await appendStatus({
type: "story_complete",
message: `Completed story ${storyNum}/${totalStories}: ${story.title}`,
story: {
+ id: story.id,
current: storyNum,
total: totalStories,
title: story.title,
acceptance: story.acceptance,
},
+ commitHash: storyCommitHash,
+ commitUrl: storyCommitUrl,
+ progress: progressLog.join('\n\n'),
usage,
})
@@ -603,6 +507,15 @@ Complete this story. When done, the acceptance criteria should be met. Use Read,
type: "waitpoint",
message: `Story "${story.title}" complete. Continue to next story?`,
diff: currentDiff,
+ story: {
+ id: story.id,
+ current: storyNum,
+ total: totalStories,
+ title: story.title,
+ acceptance: story.acceptance,
+ },
+ commitHash: storyCommitHash,
+ commitUrl: storyCommitUrl,
waitpoint: {
tokenId: token.id,
publicAccessToken: token.publicAccessToken,
diff --git a/background-ralph/src/trigger/streams.ts b/background-ralph/src/trigger/streams.ts
index 9d64b55..0a0bff3 100644
--- a/background-ralph/src/trigger/streams.ts
+++ b/background-ralph/src/trigger/streams.ts
@@ -60,11 +60,15 @@ export type StatusUpdate = {
usage?: TokenUsage
prd?: Prd
story?: {
+ id: string
current: number
total: number
title: string
acceptance: string[]
}
+ commitHash?: string
+ commitUrl?: string
+ progress?: string // In-memory progress log (Ralph loop pattern)
}
// Status updates - use string stream with manual JSON serialization
From 6caa82cfcfb8024ba2e9bb3dcb56413b3369c975 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Tue, 13 Jan 2026 14:05:00 +0000
Subject: [PATCH 14/72] Started implementing new layout
---
background-ralph/README.md | 97 +
background-ralph/next.config.mjs | 4 +-
background-ralph/package.json | 3 +
background-ralph/pnpm-lock.yaml | 1707 ++++++++++++++++-
background-ralph/src/app/globals.css | 117 +-
background-ralph/src/app/layout.tsx | 11 +-
background-ralph/src/app/page.tsx | 12 +-
.../src/components/agent-output.tsx | 87 +
.../src/components/help-modal.tsx | 65 +
.../src/components/kanban-board.tsx | 110 ++
.../src/components/keyboard-handler.tsx | 73 +
background-ralph/src/components/ralph-app.tsx | 131 +-
.../src/components/run-viewer.tsx | 185 +-
.../src/components/shortcut-footer.tsx | 36 +
.../src/components/story-card.tsx | 95 +
.../src/components/story-editor.tsx | 85 +
background-ralph/src/trigger/ralph-loop.ts | 25 +-
background-ralph/src/trigger/streams.ts | 4 +
background-ralph/tailwind.config.ts | 7 +-
19 files changed, 2628 insertions(+), 226 deletions(-)
create mode 100644 background-ralph/README.md
create mode 100644 background-ralph/src/components/agent-output.tsx
create mode 100644 background-ralph/src/components/help-modal.tsx
create mode 100644 background-ralph/src/components/kanban-board.tsx
create mode 100644 background-ralph/src/components/keyboard-handler.tsx
create mode 100644 background-ralph/src/components/shortcut-footer.tsx
create mode 100644 background-ralph/src/components/story-card.tsx
create mode 100644 background-ralph/src/components/story-editor.tsx
diff --git a/background-ralph/README.md b/background-ralph/README.md
new file mode 100644
index 0000000..3e61e30
--- /dev/null
+++ b/background-ralph/README.md
@@ -0,0 +1,97 @@
+# background ralph
+
+Autonomous coding agent that clones a GitHub repo, generates a PRD, and executes stories one at a time with human-in-the-loop approval gates.
+
+## overview
+
+Point Ralph at any GitHub repository with a natural language prompt. It explores the codebase, generates a PRD with stories, and executes each story autonomously using Claude. Between stories, you can review changes and decide whether to continue, stop, or approve the final result.
+
+## tech stack
+
+- [**next.js**](https://nextjs.org/) ā frontend react framework (app router)
+- [**claude agent sdk**](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk) ā autonomous coding agent
+- [**trigger.dev**](https://trigger.dev/docs) ā background task orchestration with realtime streams
+- [**streamdown**](https://github.com/vercel/streamdown) ā streaming markdown rendering
+- [**tailwind css**](https://tailwindcss.com/) + [**shadcn/ui**](https://ui.shadcn.com/) ā styling
+- [**zod**](https://zod.dev/) ā input validation
+
+## setup & running locally
+
+1. Clone the repo:
+ ```bash
+ git clone https://github.com/triggerdotdev/background-ralph.git
+ cd background-ralph
+ ```
+
+2. Install dependencies:
+ ```bash
+ pnpm install
+ ```
+
+3. Copy environment variables:
+ ```bash
+ cp .env.example .env
+ ```
+
+4. Fill in your `.env` file:
+
+ | Variable | Description | Get it |
+ |----------|-------------|--------|
+ | `TRIGGER_PROJECT_REF` | Your Trigger.dev project reference | [trigger.dev/dashboard](https://cloud.trigger.dev) ā Create project |
+ | `TRIGGER_SECRET_KEY` | Your Trigger.dev secret key | Project settings ā API keys |
+ | `ANTHROPIC_API_KEY` | Claude API key | [console.anthropic.com](https://console.anthropic.com/) |
+ | `GITHUB_TOKEN` | (Optional) GitHub PAT with repo scope | [github.com/settings/tokens](https://github.com/settings/tokens) |
+
+ Without `GITHUB_TOKEN`, changes are ephemeral. With it, Ralph creates a branch and pushes commits.
+
+5. Start both dev servers (in separate terminals):
+ ```bash
+ # Terminal 1: Next.js frontend
+ pnpm dev
+
+ # Terminal 2: Trigger.dev worker
+ pnpm dev:trigger
+ ```
+
+6. Open [http://localhost:3000](http://localhost:3000)
+
+## how it works
+
+The [`ralphLoop`](src/trigger/ralph-loop.ts) task orchestrates the entire workflow:
+
+1. **Clone repo** ā Clones the target GitHub repository to a temp directory
+2. **Explore** ā Shallow exploration (files, package.json, README) to understand the codebase
+3. **Generate PRD** ā Claude generates a PRD with 3-7 stories based on the prompt
+4. **PRD review gate** ā Waitpoint for human to edit/approve the PRD
+5. **Story loop** ā For each story:
+ - Stream status to frontend via realtime streams
+ - Run Claude agent with file tools (Read, Write, Edit, Bash)
+ - Commit changes to branch
+ - Approval gate (unless yolo mode)
+6. **Push** ā Push branch to GitHub and create PR
+
+Realtime streams provide live updates:
+- [`statusStream`](src/trigger/streams.ts) ā Status updates, PRD, story progress
+- [`agentOutputStream`](src/trigger/streams.ts) ā Claude's output (streamed markdown)
+
+## relevant code
+
+| Capability | File |
+|------------|------|
+| Main orchestrator task | [`src/trigger/ralph-loop.ts`](src/trigger/ralph-loop.ts) |
+| Realtime stream definitions | [`src/trigger/streams.ts`](src/trigger/streams.ts) |
+| Run viewer with kanban board | [`src/components/run-viewer.tsx`](src/components/run-viewer.tsx) |
+| Kanban board component | [`src/components/kanban-board.tsx`](src/components/kanban-board.tsx) |
+| Streaming markdown output | [`src/components/agent-output.tsx`](src/components/agent-output.tsx) |
+| Story editor modal | [`src/components/story-editor.tsx`](src/components/story-editor.tsx) |
+| Keyboard shortcuts | [`src/components/keyboard-handler.tsx`](src/components/keyboard-handler.tsx) |
+| Server action to trigger run | [`src/app/actions.ts`](src/app/actions.ts) |
+| Input validation schemas | [`src/lib/schemas.ts`](src/lib/schemas.ts) |
+
+## learn more
+
+- [**trigger.dev realtime streams**](https://trigger.dev/docs/realtime) ā streaming data to frontend
+- [**trigger.dev react hooks**](https://trigger.dev/docs/frontend/react-hooks) ā `useRealtimeRun`, `useRealtimeStream`
+- [**trigger.dev waitpoints**](https://trigger.dev/docs/wait) ā human-in-the-loop patterns
+- [**claude agent sdk**](https://github.com/anthropics/claude-agent-sdk) ā autonomous coding agent
+- [**streamdown**](https://streamdown.ai/) ā streaming markdown component
diff --git a/background-ralph/next.config.mjs b/background-ralph/next.config.mjs
index 1d61478..31a41f2 100644
--- a/background-ralph/next.config.mjs
+++ b/background-ralph/next.config.mjs
@@ -1,4 +1,6 @@
/** @type {import('next').NextConfig} */
-const nextConfig = {}
+const nextConfig = {
+ transpilePackages: ["streamdown", "shiki"],
+}
export default nextConfig
diff --git a/background-ralph/package.json b/background-ralph/package.json
index 2c7dd07..f1a4eb6 100644
--- a/background-ralph/package.json
+++ b/background-ralph/package.json
@@ -8,15 +8,18 @@
"@trigger.dev/sdk": "4.3.2",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
+ "geist": "^1.5.1",
"lucide-react": "^0.562.0",
"next": "14.2.21",
"react": "^18",
"react-dom": "^18",
+ "streamdown": "^2.0.1",
"tailwind-merge": "^3.4.0",
"tailwindcss-animate": "^1.0.7",
"zod": "^4.3.5"
},
"devDependencies": {
+ "@tailwindcss/typography": "^0.5.19",
"@trigger.dev/build": "4.3.2",
"@types/node": "^20",
"@types/react": "^18",
diff --git a/background-ralph/pnpm-lock.yaml b/background-ralph/pnpm-lock.yaml
index 2c1e1c4..5412547 100644
--- a/background-ralph/pnpm-lock.yaml
+++ b/background-ralph/pnpm-lock.yaml
@@ -32,6 +32,9 @@ importers:
clsx:
specifier: ^2.1.1
version: 2.1.1
+ geist:
+ specifier: ^1.5.1
+ version: 1.5.1(next@14.2.21(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
lucide-react:
specifier: ^0.562.0
version: 0.562.0(react@18.3.1)
@@ -44,6 +47,9 @@ importers:
react-dom:
specifier: ^18
version: 18.3.1(react@18.3.1)
+ streamdown:
+ specifier: ^2.0.1
+ version: 2.0.1(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(react@18.3.1)
tailwind-merge:
specifier: ^3.4.0
version: 3.4.0
@@ -54,6 +60,9 @@ importers:
specifier: ^4.3.5
version: 4.3.5
devDependencies:
+ '@tailwindcss/typography':
+ specifier: ^0.5.19
+ version: 0.5.19(tailwindcss@3.4.19)
'@trigger.dev/build':
specifier: 4.3.2
version: 4.3.2(magicast@0.3.5)(supports-color@10.2.2)(typescript@5.9.3)
@@ -221,144 +230,300 @@ packages:
cpu: [ppc64]
os: [aix]
+ '@esbuild/aix-ppc64@0.27.2':
+ resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
'@esbuild/android-arm64@0.23.1':
resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
+ '@esbuild/android-arm64@0.27.2':
+ resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
'@esbuild/android-arm@0.23.1':
resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
+ '@esbuild/android-arm@0.27.2':
+ resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
'@esbuild/android-x64@0.23.1':
resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
+ '@esbuild/android-x64@0.27.2':
+ resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
'@esbuild/darwin-arm64@0.23.1':
resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
+ '@esbuild/darwin-arm64@0.27.2':
+ resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
'@esbuild/darwin-x64@0.23.1':
resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
+ '@esbuild/darwin-x64@0.27.2':
+ resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
'@esbuild/freebsd-arm64@0.23.1':
resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
+ '@esbuild/freebsd-arm64@0.27.2':
+ resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
'@esbuild/freebsd-x64@0.23.1':
resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
+ '@esbuild/freebsd-x64@0.27.2':
+ resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
'@esbuild/linux-arm64@0.23.1':
resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
+ '@esbuild/linux-arm64@0.27.2':
+ resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
'@esbuild/linux-arm@0.23.1':
resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
+ '@esbuild/linux-arm@0.27.2':
+ resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
'@esbuild/linux-ia32@0.23.1':
resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
+ '@esbuild/linux-ia32@0.27.2':
+ resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
'@esbuild/linux-loong64@0.23.1':
resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
+ '@esbuild/linux-loong64@0.27.2':
+ resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
'@esbuild/linux-mips64el@0.23.1':
resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
+ '@esbuild/linux-mips64el@0.27.2':
+ resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
'@esbuild/linux-ppc64@0.23.1':
resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
+ '@esbuild/linux-ppc64@0.27.2':
+ resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
'@esbuild/linux-riscv64@0.23.1':
resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
+ '@esbuild/linux-riscv64@0.27.2':
+ resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
'@esbuild/linux-s390x@0.23.1':
resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
+ '@esbuild/linux-s390x@0.27.2':
+ resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
'@esbuild/linux-x64@0.23.1':
resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
+ '@esbuild/linux-x64@0.27.2':
+ resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.27.2':
+ resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
'@esbuild/netbsd-x64@0.23.1':
resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==}
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
+ '@esbuild/netbsd-x64@0.27.2':
+ resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
'@esbuild/openbsd-arm64@0.23.1':
resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
+ '@esbuild/openbsd-arm64@0.27.2':
+ resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
'@esbuild/openbsd-x64@0.23.1':
resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==}
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
+ '@esbuild/openbsd-x64@0.27.2':
+ resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openharmony-arm64@0.27.2':
+ resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
'@esbuild/sunos-x64@0.23.1':
resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
+ '@esbuild/sunos-x64@0.27.2':
+ resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
'@esbuild/win32-arm64@0.23.1':
resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
+ '@esbuild/win32-arm64@0.27.2':
+ resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
'@esbuild/win32-ia32@0.23.1':
resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
+ '@esbuild/win32-ia32@0.27.2':
+ resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
'@esbuild/win32-x64@0.23.1':
resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==}
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
+ '@esbuild/win32-x64@0.27.2':
+ resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
'@eslint-community/eslint-utils@4.9.1':
resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -823,6 +988,27 @@ packages:
'@s2-dev/streamstore@0.17.6':
resolution: {integrity: sha512-ocjZfKaPKmo2yhudM58zVNHv3rBLSbTKkabVoLFn9nAxU6iLrR2CO3QmSo7/waohI3EZHAWxF/Pw8kA8d6QH2g==}
+ '@shikijs/core@3.21.0':
+ resolution: {integrity: sha512-AXSQu/2n1UIQekY8euBJlvFYZIw0PHY63jUzGbrOma4wPxzznJXTXkri+QcHeBNaFxiiOljKxxJkVSoB3PjbyA==}
+
+ '@shikijs/engine-javascript@3.21.0':
+ resolution: {integrity: sha512-ATwv86xlbmfD9n9gKRiwuPpWgPENAWCLwYCGz9ugTJlsO2kOzhOkvoyV/UD+tJ0uT7YRyD530x6ugNSffmvIiQ==}
+
+ '@shikijs/engine-oniguruma@3.21.0':
+ resolution: {integrity: sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ==}
+
+ '@shikijs/langs@3.21.0':
+ resolution: {integrity: sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA==}
+
+ '@shikijs/themes@3.21.0':
+ resolution: {integrity: sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw==}
+
+ '@shikijs/types@3.21.0':
+ resolution: {integrity: sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA==}
+
+ '@shikijs/vscode-textmate@10.0.2':
+ resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
+
'@socket.io/component-emitter@3.1.2':
resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==}
@@ -838,6 +1024,11 @@ packages:
'@swc/helpers@0.5.5':
resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==}
+ '@tailwindcss/typography@0.5.19':
+ resolution: {integrity: sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==}
+ peerDependencies:
+ tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1'
+
'@trigger.dev/build@4.3.2':
resolution: {integrity: sha512-MYr2+Sphd9Zeu44q5eLRp+jXj0Km5r9QGjtnmRKFDxK79MbGoL65M8yFXNmMkJmzsBQHcA5USSIJR3QJJnV7kQ==}
engines: {node: '>=18.20.0'}
@@ -893,9 +1084,30 @@ packages:
'@types/cors@2.8.19':
resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==}
+ '@types/debug@4.1.12':
+ resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
+
+ '@types/estree-jsx@1.0.5':
+ resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==}
+
+ '@types/estree@1.0.8':
+ resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
+
+ '@types/hast@3.0.4':
+ resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
+
'@types/json5@0.0.29':
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
+ '@types/katex@0.16.8':
+ resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==}
+
+ '@types/mdast@4.0.4':
+ resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
+
+ '@types/ms@2.1.0':
+ resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
+
'@types/node@20.19.27':
resolution: {integrity: sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==}
@@ -916,6 +1128,12 @@ packages:
'@types/tinycolor2@1.4.6':
resolution: {integrity: sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw==}
+ '@types/unist@2.0.11':
+ resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
+
+ '@types/unist@3.0.3':
+ resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
+
'@typescript-eslint/eslint-plugin@8.52.0':
resolution: {integrity: sha512-okqtOgqu2qmZJ5iN4TWlgfF171dZmx2FzdOv2K/ixL2LZWDStL8+JgQerI2sa8eAEfoydG9+0V96m7V+P8yE1Q==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -1206,6 +1424,9 @@ packages:
resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
engines: {node: '>= 0.4'}
+ bail@2.0.2:
+ resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
+
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
@@ -1288,6 +1509,9 @@ packages:
caniuse-lite@1.0.30001763:
resolution: {integrity: sha512-mh/dGtq56uN98LlNX9qdbKnzINhX0QzhiWBFEkFfsFO4QyCvL8YegrJAazCwXIeqkIob8BlZPGM3xdnY+sgmvQ==}
+ ccount@2.0.1:
+ resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
+
chalk@4.1.2:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'}
@@ -1296,6 +1520,18 @@ packages:
resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==}
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
+ character-entities-html4@2.1.0:
+ resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
+
+ character-entities-legacy@3.0.0:
+ resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
+
+ character-entities@2.0.2:
+ resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
+
+ character-reference-invalid@2.0.1:
+ resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==}
+
chokidar@3.6.0:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
@@ -1339,10 +1575,17 @@ packages:
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+ comma-separated-tokens@2.0.3:
+ resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
+
commander@4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
+ commander@8.3.0:
+ resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
+ engines: {node: '>= 12'}
+
commander@9.5.0:
resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==}
engines: {node: ^12.20.0 || >=14}
@@ -1445,6 +1688,9 @@ packages:
supports-color:
optional: true
+ decode-named-character-reference@1.2.0:
+ resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==}
+
deep-is@0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
@@ -1486,6 +1732,9 @@ packages:
destr@2.0.5:
resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==}
+ devlop@1.1.0:
+ resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
+
didyoumean@1.2.2:
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
@@ -1545,6 +1794,10 @@ packages:
resolution: {integrity: sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==}
engines: {node: '>=10.2.0'}
+ entities@6.0.1:
+ resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
+ engines: {node: '>=0.12'}
+
environment@1.1.0:
resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==}
engines: {node: '>=18'}
@@ -1586,6 +1839,11 @@ packages:
engines: {node: '>=18'}
hasBin: true
+ esbuild@0.27.2:
+ resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==}
+ engines: {node: '>=18'}
+ hasBin: true
+
escape-html@1.0.3:
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
@@ -1593,6 +1851,10 @@ packages:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
engines: {node: '>=10'}
+ escape-string-regexp@5.0.0:
+ resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
+ engines: {node: '>=12'}
+
eslint-config-next@14.2.21:
resolution: {integrity: sha512-bi1Mn6LxWdQod9qvOBuhBhN4ZpBYH5DuyDunbZt6lye3zlohJyM0T5/oFokRPNl2Mqt3/+uwHxr8XKOkPe852A==}
peerDependencies:
@@ -1701,6 +1963,9 @@ packages:
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
engines: {node: '>=4.0'}
+ estree-util-is-identifier-name@3.0.0:
+ resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==}
+
esutils@2.0.3:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
@@ -1740,6 +2005,9 @@ packages:
exsolve@1.0.8:
resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==}
+ extend@3.0.2:
+ resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
+
fast-check@3.23.2:
resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==}
engines: {node: '>=8.0.0'}
@@ -1836,10 +2104,19 @@ packages:
functions-have-names@1.2.3:
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
+ geist@1.5.1:
+ resolution: {integrity: sha512-mAHZxIsL2o3ZITFaBVFBnwyDOw+zNLYum6A6nIjpzCGIO8QtC3V76XF2RnZTyLx1wlDTmMDy8jg3Ib52MIjGvQ==}
+ peerDependencies:
+ next: '>=13.2.0'
+
generator-function@2.0.1:
resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==}
engines: {node: '>= 0.4'}
+ get-east-asian-width@1.4.0:
+ resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==}
+ engines: {node: '>=18'}
+
get-intrinsic@1.3.0:
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
engines: {node: '>= 0.4'}
@@ -1940,10 +2217,58 @@ packages:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
+ hast-util-from-dom@5.0.1:
+ resolution: {integrity: sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==}
+
+ hast-util-from-html-isomorphic@2.0.0:
+ resolution: {integrity: sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==}
+
+ hast-util-from-html@2.0.3:
+ resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==}
+
+ hast-util-from-parse5@8.0.3:
+ resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==}
+
+ hast-util-is-element@3.0.0:
+ resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==}
+
+ hast-util-parse-selector@4.0.0:
+ resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==}
+
+ hast-util-raw@9.1.0:
+ resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==}
+
+ hast-util-sanitize@5.0.2:
+ resolution: {integrity: sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==}
+
+ hast-util-to-html@9.0.5:
+ resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==}
+
+ hast-util-to-jsx-runtime@2.3.6:
+ resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==}
+
+ hast-util-to-parse5@8.0.1:
+ resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==}
+
+ hast-util-to-text@4.0.2:
+ resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==}
+
+ hast-util-whitespace@3.0.0:
+ resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
+
+ hastscript@9.0.1:
+ resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==}
+
hono@4.11.3:
resolution: {integrity: sha512-PmQi306+M/ct/m5s66Hrg+adPnkD5jiO6IjA7WhWw0gSBSo1EcRegwuI1deZ+wd5pzCGynCcn2DprnE4/yEV4w==}
engines: {node: '>=16.9.0'}
+ html-url-attributes@3.0.1:
+ resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==}
+
+ html-void-elements@3.0.0:
+ resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
+
http-errors@2.0.1:
resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==}
engines: {node: '>= 0.8'}
@@ -1992,6 +2317,9 @@ packages:
resolution: {integrity: sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==}
engines: {node: ^18.17.0 || >=20.5.0}
+ inline-style-parser@0.2.7:
+ resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==}
+
internal-slot@1.1.0:
resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
engines: {node: '>= 0.4'}
@@ -2000,6 +2328,12 @@ packages:
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
engines: {node: '>= 0.10'}
+ is-alphabetical@2.0.1:
+ resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==}
+
+ is-alphanumerical@2.0.1:
+ resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==}
+
is-array-buffer@3.0.5:
resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==}
engines: {node: '>= 0.4'}
@@ -2039,6 +2373,9 @@ packages:
resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==}
engines: {node: '>= 0.4'}
+ is-decimal@2.0.1:
+ resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==}
+
is-docker@3.0.0:
resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -2064,6 +2401,9 @@ packages:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
+ is-hexadecimal@2.0.1:
+ resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
+
is-inside-container@1.0.0:
resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
engines: {node: '>=14.16'}
@@ -2093,6 +2433,10 @@ packages:
resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
engines: {node: '>=8'}
+ is-plain-obj@4.1.0:
+ resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
+ engines: {node: '>=12'}
+
is-promise@4.0.0:
resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
@@ -2216,6 +2560,10 @@ packages:
resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==}
engines: {node: '>=4.0'}
+ katex@0.16.27:
+ resolution: {integrity: sha512-aeQoDkuRWSqQN6nSvVCEFvfXdqo1OQiCmmW1kc9xSdjutPv7BGO7pqY9sQRJpMOGrEdfDgF2TfRXe5eUAD2Waw==}
+ hasBin: true
+
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
@@ -2247,6 +2595,9 @@ packages:
long@5.3.2:
resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
+ longest-streak@3.1.0:
+ resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
+
loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
@@ -2262,6 +2613,14 @@ packages:
magicast@0.3.5:
resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==}
+ markdown-table@3.0.4:
+ resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
+
+ marked@17.0.1:
+ resolution: {integrity: sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg==}
+ engines: {node: '>= 20'}
+ hasBin: true
+
matchit@1.1.0:
resolution: {integrity: sha512-+nGYoOlfHmxe5BW5tE0EMJppXEwdSf8uBA1GTZC7Q77kbT35+VKLYJMzVNWCHSsga1ps1tPYFtFyvxvKzWVmMA==}
engines: {node: '>=6'}
@@ -2270,6 +2629,54 @@ packages:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
+ mdast-util-find-and-replace@3.0.2:
+ resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==}
+
+ mdast-util-from-markdown@2.0.2:
+ resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==}
+
+ mdast-util-gfm-autolink-literal@2.0.1:
+ resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==}
+
+ mdast-util-gfm-footnote@2.1.0:
+ resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==}
+
+ mdast-util-gfm-strikethrough@2.0.0:
+ resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==}
+
+ mdast-util-gfm-table@2.0.0:
+ resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==}
+
+ mdast-util-gfm-task-list-item@2.0.0:
+ resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==}
+
+ mdast-util-gfm@3.1.0:
+ resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==}
+
+ mdast-util-math@3.0.0:
+ resolution: {integrity: sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==}
+
+ mdast-util-mdx-expression@2.0.1:
+ resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==}
+
+ mdast-util-mdx-jsx@3.2.0:
+ resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==}
+
+ mdast-util-mdxjs-esm@2.0.1:
+ resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==}
+
+ mdast-util-phrasing@4.1.0:
+ resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==}
+
+ mdast-util-to-hast@13.2.1:
+ resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==}
+
+ mdast-util-to-markdown@2.1.2:
+ resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==}
+
+ mdast-util-to-string@4.0.0:
+ resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
+
media-typer@1.1.0:
resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==}
engines: {node: '>= 0.8'}
@@ -2285,6 +2692,122 @@ packages:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
+ micromark-core-commonmark@2.0.3:
+ resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==}
+
+ micromark-extension-cjk-friendly-gfm-strikethrough@1.2.3:
+ resolution: {integrity: sha512-gSPnxgHDDqXYOBvQRq6lerrq9mjDhdtKn+7XETuXjxWcL62yZEfUdA28Ml1I2vDIPfAOIKLa0h2XDSGkInGHFQ==}
+ engines: {node: '>=16'}
+ peerDependencies:
+ micromark: ^4.0.0
+ micromark-util-types: ^2.0.0
+ peerDependenciesMeta:
+ micromark-util-types:
+ optional: true
+
+ micromark-extension-cjk-friendly-util@2.1.1:
+ resolution: {integrity: sha512-egs6+12JU2yutskHY55FyR48ZiEcFOJFyk9rsiyIhcJ6IvWB6ABBqVrBw8IobqJTDZ/wdSr9eoXDPb5S2nW1bg==}
+ engines: {node: '>=16'}
+ peerDependencies:
+ micromark-util-types: '*'
+ peerDependenciesMeta:
+ micromark-util-types:
+ optional: true
+
+ micromark-extension-cjk-friendly@1.2.3:
+ resolution: {integrity: sha512-gRzVLUdjXBLX6zNPSnHGDoo+ZTp5zy+MZm0g3sv+3chPXY7l9gW+DnrcHcZh/jiPR6MjPKO4AEJNp4Aw6V9z5Q==}
+ engines: {node: '>=16'}
+ peerDependencies:
+ micromark: ^4.0.0
+ micromark-util-types: ^2.0.0
+ peerDependenciesMeta:
+ micromark-util-types:
+ optional: true
+
+ micromark-extension-gfm-autolink-literal@2.1.0:
+ resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==}
+
+ micromark-extension-gfm-footnote@2.1.0:
+ resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==}
+
+ micromark-extension-gfm-strikethrough@2.1.0:
+ resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==}
+
+ micromark-extension-gfm-table@2.1.1:
+ resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==}
+
+ micromark-extension-gfm-tagfilter@2.0.0:
+ resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==}
+
+ micromark-extension-gfm-task-list-item@2.1.0:
+ resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==}
+
+ micromark-extension-gfm@3.0.0:
+ resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==}
+
+ micromark-extension-math@3.1.0:
+ resolution: {integrity: sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==}
+
+ micromark-factory-destination@2.0.1:
+ resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==}
+
+ micromark-factory-label@2.0.1:
+ resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==}
+
+ micromark-factory-space@2.0.1:
+ resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==}
+
+ micromark-factory-title@2.0.1:
+ resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==}
+
+ micromark-factory-whitespace@2.0.1:
+ resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==}
+
+ micromark-util-character@2.1.1:
+ resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
+
+ micromark-util-chunked@2.0.1:
+ resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==}
+
+ micromark-util-classify-character@2.0.1:
+ resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==}
+
+ micromark-util-combine-extensions@2.0.1:
+ resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==}
+
+ micromark-util-decode-numeric-character-reference@2.0.2:
+ resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==}
+
+ micromark-util-decode-string@2.0.1:
+ resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==}
+
+ micromark-util-encode@2.0.1:
+ resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
+
+ micromark-util-html-tag-name@2.0.1:
+ resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==}
+
+ micromark-util-normalize-identifier@2.0.1:
+ resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==}
+
+ micromark-util-resolve-all@2.0.1:
+ resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==}
+
+ micromark-util-sanitize-uri@2.0.1:
+ resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
+
+ micromark-util-subtokenize@2.1.0:
+ resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==}
+
+ micromark-util-symbol@2.0.1:
+ resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
+
+ micromark-util-types@2.0.2:
+ resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==}
+
+ micromark@4.0.2:
+ resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==}
+
micromatch@4.0.8:
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
engines: {node: '>=8.6'}
@@ -2482,6 +3005,12 @@ packages:
resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
engines: {node: '>=12'}
+ oniguruma-parser@0.12.1:
+ resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==}
+
+ oniguruma-to-es@4.3.4:
+ resolution: {integrity: sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==}
+
open@10.2.0:
resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==}
engines: {node: '>=18'}
@@ -2518,6 +3047,12 @@ packages:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
engines: {node: '>=6'}
+ parse-entities@4.0.2:
+ resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==}
+
+ parse5@7.3.0:
+ resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
+
parseurl@1.3.3:
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
engines: {node: '>= 0.8'}
@@ -2632,6 +3167,10 @@ packages:
peerDependencies:
postcss: ^8.2.14
+ postcss-selector-parser@6.0.10:
+ resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
+ engines: {node: '>=4'}
+
postcss-selector-parser@6.1.2:
resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
engines: {node: '>=4'}
@@ -2658,6 +3197,9 @@ packages:
prop-types@15.8.1:
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
+ property-information@7.1.0:
+ resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
+
protobufjs@7.5.4:
resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==}
engines: {node: '>=12.0.0'}
@@ -2718,28 +3260,87 @@ packages:
resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
engines: {node: '>= 0.4'}
+ regex-recursion@6.0.2:
+ resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==}
+
+ regex-utilities@2.3.0:
+ resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==}
+
+ regex@6.1.0:
+ resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==}
+
regexp.prototype.flags@1.5.4:
resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
engines: {node: '>= 0.4'}
- require-from-string@2.0.2:
- resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
- engines: {node: '>=0.10.0'}
+ rehype-harden@1.1.7:
+ resolution: {integrity: sha512-j5DY0YSK2YavvNGV+qBHma15J9m0WZmRe8posT5AtKDS6TNWtMVTo6RiqF8SidfcASYz8f3k2J/1RWmq5zTXUw==}
- require-in-the-middle@7.5.2:
- resolution: {integrity: sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==}
- engines: {node: '>=8.6.0'}
+ rehype-katex@7.0.1:
+ resolution: {integrity: sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==}
- resolve-from@4.0.0:
- resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
- engines: {node: '>=4'}
+ rehype-raw@7.0.0:
+ resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==}
- resolve-pkg-maps@1.0.0:
- resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+ rehype-sanitize@6.0.0:
+ resolution: {integrity: sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==}
- resolve@1.22.11:
- resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==}
- engines: {node: '>= 0.4'}
+ remark-cjk-friendly-gfm-strikethrough@1.2.3:
+ resolution: {integrity: sha512-bXfMZtsaomK6ysNN/UGRIcasQAYkC10NtPmP0oOHOV8YOhA2TXmwRXCku4qOzjIFxAPfish5+XS0eIug2PzNZA==}
+ engines: {node: '>=16'}
+ peerDependencies:
+ '@types/mdast': ^4.0.0
+ unified: ^11.0.0
+ peerDependenciesMeta:
+ '@types/mdast':
+ optional: true
+
+ remark-cjk-friendly@1.2.3:
+ resolution: {integrity: sha512-UvAgxwlNk+l9Oqgl/9MWK2eWRS7zgBW/nXX9AthV7nd/3lNejF138E7Xbmk9Zs4WjTJGs721r7fAEc7tNFoH7g==}
+ engines: {node: '>=16'}
+ peerDependencies:
+ '@types/mdast': ^4.0.0
+ unified: ^11.0.0
+ peerDependenciesMeta:
+ '@types/mdast':
+ optional: true
+
+ remark-gfm@4.0.1:
+ resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==}
+
+ remark-math@6.0.0:
+ resolution: {integrity: sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==}
+
+ remark-parse@11.0.0:
+ resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==}
+
+ remark-rehype@11.1.2:
+ resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==}
+
+ remark-stringify@11.0.0:
+ resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
+
+ remend@1.0.2:
+ resolution: {integrity: sha512-Kcr8qu3OcfX9pjVjzj3KC1B7jVZKofQzX1UEQ5W5LPS/pFTgOjF58zDBgdi6NDw86Ro8vOS0S0Yyf9r7CprmGg==}
+
+ require-from-string@2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
+ require-in-the-middle@7.5.2:
+ resolution: {integrity: sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==}
+ engines: {node: '>=8.6.0'}
+
+ resolve-from@4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+
+ resolve-pkg-maps@1.0.0:
+ resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+
+ resolve@1.22.11:
+ resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==}
+ engines: {node: '>= 0.4'}
hasBin: true
resolve@2.0.0-next.5:
@@ -2831,6 +3432,9 @@ packages:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
+ shiki@3.21.0:
+ resolution: {integrity: sha512-N65B/3bqL/TI2crrXr+4UivctrAGEjmsib5rPMMPpFp1xAx/w03v8WZ9RDDFYteXoEgY7qZ4HGgl5KBIu1153w==}
+
side-channel-list@1.0.0:
resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
engines: {node: '>= 0.4'}
@@ -2883,6 +3487,9 @@ packages:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
+ space-separated-tokens@2.0.2:
+ resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
+
stable-hash@0.0.5:
resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==}
@@ -2897,6 +3504,11 @@ packages:
resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==}
engines: {node: '>= 0.4'}
+ streamdown@2.0.1:
+ resolution: {integrity: sha512-PcsA0DdoJPzS5YiTk3cAzH/HZ5A+cKuluWjYzUga/wjFBf8LQt/zWN8YtPzC7Jnt8MbAKQNKrhwrSS3T73h2Qw==}
+ peerDependencies:
+ react: ^18.0.0 || ^19.0.0
+
streamsearch@1.1.0:
resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
engines: {node: '>=10.0.0'}
@@ -2932,6 +3544,9 @@ packages:
resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
engines: {node: '>= 0.4'}
+ stringify-entities@4.0.4:
+ resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
+
strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
@@ -2952,6 +3567,12 @@ packages:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
+ style-to-js@1.1.21:
+ resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==}
+
+ style-to-object@1.0.14:
+ resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==}
+
styled-jsx@5.1.1:
resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==}
engines: {node: '>= 12.0.0'}
@@ -3058,6 +3679,12 @@ packages:
engines: {node: '>=18.20.0'}
hasBin: true
+ trim-lines@3.0.1:
+ resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
+
+ trough@2.2.0:
+ resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
+
trouter@2.0.1:
resolution: {integrity: sha512-kr8SKKw94OI+xTGOkfsvwZQ8mWoikZDd2n8XZHjJVZUARZT+4/VV6cacRS6CLsH9bNm+HFIPU1Zx4CnNnb4qlQ==}
engines: {node: '>=6'}
@@ -3143,6 +3770,30 @@ packages:
undici-types@6.21.0:
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
+ unified@11.0.5:
+ resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
+
+ unist-util-find-after@5.0.0:
+ resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==}
+
+ unist-util-is@6.0.1:
+ resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==}
+
+ unist-util-position@5.0.0:
+ resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
+
+ unist-util-remove-position@5.0.0:
+ resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==}
+
+ unist-util-stringify-position@4.0.0:
+ resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
+
+ unist-util-visit-parents@6.0.2:
+ resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==}
+
+ unist-util-visit@5.0.0:
+ resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==}
+
unpipe@1.0.0:
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
engines: {node: '>= 0.8'}
@@ -3169,6 +3820,18 @@ packages:
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
+ vfile-location@5.0.3:
+ resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==}
+
+ vfile-message@4.0.3:
+ resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==}
+
+ vfile@6.0.3:
+ resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
+
+ web-namespaces@2.0.1:
+ resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
+
which-boxed-primitive@1.1.1:
resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
engines: {node: '>= 0.4'}
@@ -3292,6 +3955,9 @@ packages:
zod@4.3.5:
resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==}
+ zwitch@2.0.4:
+ resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
+
snapshots:
'@alloc/quick-lru@5.2.0': {}
@@ -3412,75 +4078,153 @@ snapshots:
'@esbuild/aix-ppc64@0.23.1':
optional: true
+ '@esbuild/aix-ppc64@0.27.2':
+ optional: true
+
'@esbuild/android-arm64@0.23.1':
optional: true
+ '@esbuild/android-arm64@0.27.2':
+ optional: true
+
'@esbuild/android-arm@0.23.1':
optional: true
+ '@esbuild/android-arm@0.27.2':
+ optional: true
+
'@esbuild/android-x64@0.23.1':
optional: true
+ '@esbuild/android-x64@0.27.2':
+ optional: true
+
'@esbuild/darwin-arm64@0.23.1':
optional: true
+ '@esbuild/darwin-arm64@0.27.2':
+ optional: true
+
'@esbuild/darwin-x64@0.23.1':
optional: true
+ '@esbuild/darwin-x64@0.27.2':
+ optional: true
+
'@esbuild/freebsd-arm64@0.23.1':
optional: true
+ '@esbuild/freebsd-arm64@0.27.2':
+ optional: true
+
'@esbuild/freebsd-x64@0.23.1':
optional: true
+ '@esbuild/freebsd-x64@0.27.2':
+ optional: true
+
'@esbuild/linux-arm64@0.23.1':
optional: true
+ '@esbuild/linux-arm64@0.27.2':
+ optional: true
+
'@esbuild/linux-arm@0.23.1':
optional: true
+ '@esbuild/linux-arm@0.27.2':
+ optional: true
+
'@esbuild/linux-ia32@0.23.1':
optional: true
+ '@esbuild/linux-ia32@0.27.2':
+ optional: true
+
'@esbuild/linux-loong64@0.23.1':
optional: true
+ '@esbuild/linux-loong64@0.27.2':
+ optional: true
+
'@esbuild/linux-mips64el@0.23.1':
optional: true
+ '@esbuild/linux-mips64el@0.27.2':
+ optional: true
+
'@esbuild/linux-ppc64@0.23.1':
optional: true
+ '@esbuild/linux-ppc64@0.27.2':
+ optional: true
+
'@esbuild/linux-riscv64@0.23.1':
optional: true
+ '@esbuild/linux-riscv64@0.27.2':
+ optional: true
+
'@esbuild/linux-s390x@0.23.1':
optional: true
+ '@esbuild/linux-s390x@0.27.2':
+ optional: true
+
'@esbuild/linux-x64@0.23.1':
optional: true
+ '@esbuild/linux-x64@0.27.2':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.27.2':
+ optional: true
+
'@esbuild/netbsd-x64@0.23.1':
optional: true
+ '@esbuild/netbsd-x64@0.27.2':
+ optional: true
+
'@esbuild/openbsd-arm64@0.23.1':
optional: true
+ '@esbuild/openbsd-arm64@0.27.2':
+ optional: true
+
'@esbuild/openbsd-x64@0.23.1':
optional: true
+ '@esbuild/openbsd-x64@0.27.2':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.27.2':
+ optional: true
+
'@esbuild/sunos-x64@0.23.1':
optional: true
+ '@esbuild/sunos-x64@0.27.2':
+ optional: true
+
'@esbuild/win32-arm64@0.23.1':
optional: true
+ '@esbuild/win32-arm64@0.27.2':
+ optional: true
+
'@esbuild/win32-ia32@0.23.1':
optional: true
+ '@esbuild/win32-ia32@0.27.2':
+ optional: true
+
'@esbuild/win32-x64@0.23.1':
optional: true
+ '@esbuild/win32-x64@0.27.2':
+ optional: true
+
'@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)':
dependencies:
eslint: 8.57.1
@@ -3890,6 +4634,39 @@ snapshots:
dependencies:
'@protobuf-ts/runtime': 2.11.1
+ '@shikijs/core@3.21.0':
+ dependencies:
+ '@shikijs/types': 3.21.0
+ '@shikijs/vscode-textmate': 10.0.2
+ '@types/hast': 3.0.4
+ hast-util-to-html: 9.0.5
+
+ '@shikijs/engine-javascript@3.21.0':
+ dependencies:
+ '@shikijs/types': 3.21.0
+ '@shikijs/vscode-textmate': 10.0.2
+ oniguruma-to-es: 4.3.4
+
+ '@shikijs/engine-oniguruma@3.21.0':
+ dependencies:
+ '@shikijs/types': 3.21.0
+ '@shikijs/vscode-textmate': 10.0.2
+
+ '@shikijs/langs@3.21.0':
+ dependencies:
+ '@shikijs/types': 3.21.0
+
+ '@shikijs/themes@3.21.0':
+ dependencies:
+ '@shikijs/types': 3.21.0
+
+ '@shikijs/types@3.21.0':
+ dependencies:
+ '@shikijs/vscode-textmate': 10.0.2
+ '@types/hast': 3.0.4
+
+ '@shikijs/vscode-textmate@10.0.2': {}
+
'@socket.io/component-emitter@3.1.2': {}
'@sodaru/yup-to-json-schema@2.0.1': {}
@@ -3903,6 +4680,11 @@ snapshots:
'@swc/counter': 0.1.3
tslib: 2.8.1
+ '@tailwindcss/typography@0.5.19(tailwindcss@3.4.19)':
+ dependencies:
+ postcss-selector-parser: 6.0.10
+ tailwindcss: 3.4.19
+
'@trigger.dev/build@4.3.2(magicast@0.3.5)(supports-color@10.2.2)(typescript@5.9.3)':
dependencies:
'@prisma/config': 6.19.1(magicast@0.3.5)
@@ -4017,8 +4799,30 @@ snapshots:
dependencies:
'@types/node': 20.19.27
+ '@types/debug@4.1.12':
+ dependencies:
+ '@types/ms': 2.1.0
+
+ '@types/estree-jsx@1.0.5':
+ dependencies:
+ '@types/estree': 1.0.8
+
+ '@types/estree@1.0.8': {}
+
+ '@types/hast@3.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
'@types/json5@0.0.29': {}
+ '@types/katex@0.16.8': {}
+
+ '@types/mdast@4.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/ms@2.1.0': {}
+
'@types/node@20.19.27':
dependencies:
undici-types: 6.21.0
@@ -4038,6 +4842,10 @@ snapshots:
'@types/tinycolor2@1.4.6': {}
+ '@types/unist@2.0.11': {}
+
+ '@types/unist@3.0.3': {}
+
'@typescript-eslint/eslint-plugin@8.52.0(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3)':
dependencies:
'@eslint-community/regexpp': 4.12.2
@@ -4334,6 +5142,8 @@ snapshots:
axobject-query@4.1.0: {}
+ bail@2.0.2: {}
+
balanced-match@1.0.2: {}
base64id@2.0.0: {}
@@ -4438,6 +5248,8 @@ snapshots:
caniuse-lite@1.0.30001763: {}
+ ccount@2.0.1: {}
+
chalk@4.1.2:
dependencies:
ansi-styles: 4.3.0
@@ -4445,6 +5257,14 @@ snapshots:
chalk@5.6.2: {}
+ character-entities-html4@2.1.0: {}
+
+ character-entities-legacy@3.0.0: {}
+
+ character-entities@2.0.2: {}
+
+ character-reference-invalid@2.0.1: {}
+
chokidar@3.6.0:
dependencies:
anymatch: 3.1.3
@@ -4491,8 +5311,12 @@ snapshots:
color-name@1.1.4: {}
+ comma-separated-tokens@2.0.3: {}
+
commander@4.1.1: {}
+ commander@8.3.0: {}
+
commander@9.5.0: {}
concat-map@0.0.1: {}
@@ -4570,6 +5394,10 @@ snapshots:
optionalDependencies:
supports-color: 10.2.2
+ decode-named-character-reference@1.2.0:
+ dependencies:
+ character-entities: 2.0.2
+
deep-is@0.1.4: {}
deepmerge-ts@7.1.5: {}
@@ -4603,6 +5431,10 @@ snapshots:
destr@2.0.5: {}
+ devlop@1.1.0:
+ dependencies:
+ dequal: 2.0.3
+
didyoumean@1.2.2: {}
dlv@1.1.3: {}
@@ -4676,6 +5508,8 @@ snapshots:
- supports-color
- utf-8-validate
+ entities@6.0.1: {}
+
environment@1.1.0: {}
es-abstract@1.24.1:
@@ -4806,10 +5640,41 @@ snapshots:
'@esbuild/win32-ia32': 0.23.1
'@esbuild/win32-x64': 0.23.1
+ esbuild@0.27.2:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.27.2
+ '@esbuild/android-arm': 0.27.2
+ '@esbuild/android-arm64': 0.27.2
+ '@esbuild/android-x64': 0.27.2
+ '@esbuild/darwin-arm64': 0.27.2
+ '@esbuild/darwin-x64': 0.27.2
+ '@esbuild/freebsd-arm64': 0.27.2
+ '@esbuild/freebsd-x64': 0.27.2
+ '@esbuild/linux-arm': 0.27.2
+ '@esbuild/linux-arm64': 0.27.2
+ '@esbuild/linux-ia32': 0.27.2
+ '@esbuild/linux-loong64': 0.27.2
+ '@esbuild/linux-mips64el': 0.27.2
+ '@esbuild/linux-ppc64': 0.27.2
+ '@esbuild/linux-riscv64': 0.27.2
+ '@esbuild/linux-s390x': 0.27.2
+ '@esbuild/linux-x64': 0.27.2
+ '@esbuild/netbsd-arm64': 0.27.2
+ '@esbuild/netbsd-x64': 0.27.2
+ '@esbuild/openbsd-arm64': 0.27.2
+ '@esbuild/openbsd-x64': 0.27.2
+ '@esbuild/openharmony-arm64': 0.27.2
+ '@esbuild/sunos-x64': 0.27.2
+ '@esbuild/win32-arm64': 0.27.2
+ '@esbuild/win32-ia32': 0.27.2
+ '@esbuild/win32-x64': 0.27.2
+
escape-html@1.0.3: {}
escape-string-regexp@4.0.0: {}
+ escape-string-regexp@5.0.0: {}
+
eslint-config-next@14.2.21(eslint@8.57.1)(typescript@5.9.3):
dependencies:
'@next/eslint-plugin-next': 14.2.21
@@ -5006,6 +5871,8 @@ snapshots:
estraverse@5.3.0: {}
+ estree-util-is-identifier-name@3.0.0: {}
+
esutils@2.0.3: {}
etag@1.8.1: {}
@@ -5075,6 +5942,8 @@ snapshots:
exsolve@1.0.8: {}
+ extend@3.0.2: {}
+
fast-check@3.23.2:
dependencies:
pure-rand: 6.1.0
@@ -5172,8 +6041,14 @@ snapshots:
functions-have-names@1.2.3: {}
+ geist@1.5.1(next@14.2.21(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)):
+ dependencies:
+ next: 14.2.21(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+
generator-function@2.0.1: {}
+ get-east-asian-width@1.4.0: {}
+
get-intrinsic@1.3.0:
dependencies:
call-bind-apply-helpers: 1.0.2
@@ -5294,8 +6169,138 @@ snapshots:
dependencies:
function-bind: 1.1.2
+ hast-util-from-dom@5.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ hastscript: 9.0.1
+ web-namespaces: 2.0.1
+
+ hast-util-from-html-isomorphic@2.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-from-dom: 5.0.1
+ hast-util-from-html: 2.0.3
+ unist-util-remove-position: 5.0.0
+
+ hast-util-from-html@2.0.3:
+ dependencies:
+ '@types/hast': 3.0.4
+ devlop: 1.1.0
+ hast-util-from-parse5: 8.0.3
+ parse5: 7.3.0
+ vfile: 6.0.3
+ vfile-message: 4.0.3
+
+ hast-util-from-parse5@8.0.3:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ devlop: 1.1.0
+ hastscript: 9.0.1
+ property-information: 7.1.0
+ vfile: 6.0.3
+ vfile-location: 5.0.3
+ web-namespaces: 2.0.1
+
+ hast-util-is-element@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hast-util-parse-selector@4.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hast-util-raw@9.1.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ '@ungap/structured-clone': 1.3.0
+ hast-util-from-parse5: 8.0.3
+ hast-util-to-parse5: 8.0.1
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.2.1
+ parse5: 7.3.0
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.0.0
+ vfile: 6.0.3
+ web-namespaces: 2.0.1
+ zwitch: 2.0.4
+
+ hast-util-sanitize@5.0.2:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@ungap/structured-clone': 1.3.0
+ unist-util-position: 5.0.0
+
+ hast-util-to-html@9.0.5:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ ccount: 2.0.1
+ comma-separated-tokens: 2.0.3
+ hast-util-whitespace: 3.0.0
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.2.1
+ property-information: 7.1.0
+ space-separated-tokens: 2.0.2
+ stringify-entities: 4.0.4
+ zwitch: 2.0.4
+
+ hast-util-to-jsx-runtime@2.3.6:
+ dependencies:
+ '@types/estree': 1.0.8
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ comma-separated-tokens: 2.0.3
+ devlop: 1.1.0
+ estree-util-is-identifier-name: 3.0.0
+ hast-util-whitespace: 3.0.0
+ mdast-util-mdx-expression: 2.0.1
+ mdast-util-mdx-jsx: 3.2.0
+ mdast-util-mdxjs-esm: 2.0.1
+ property-information: 7.1.0
+ space-separated-tokens: 2.0.2
+ style-to-js: 1.1.21
+ unist-util-position: 5.0.0
+ vfile-message: 4.0.3
+ transitivePeerDependencies:
+ - supports-color
+
+ hast-util-to-parse5@8.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ comma-separated-tokens: 2.0.3
+ devlop: 1.1.0
+ property-information: 7.1.0
+ space-separated-tokens: 2.0.2
+ web-namespaces: 2.0.1
+ zwitch: 2.0.4
+
+ hast-util-to-text@4.0.2:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ hast-util-is-element: 3.0.0
+ unist-util-find-after: 5.0.0
+
+ hast-util-whitespace@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hastscript@9.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ comma-separated-tokens: 2.0.3
+ hast-util-parse-selector: 4.0.0
+ property-information: 7.1.0
+ space-separated-tokens: 2.0.2
+
hono@4.11.3: {}
+ html-url-attributes@3.0.1: {}
+
+ html-void-elements@3.0.0: {}
+
http-errors@2.0.1:
dependencies:
depd: 2.0.0
@@ -5341,6 +6346,8 @@ snapshots:
ini@5.0.0: {}
+ inline-style-parser@0.2.7: {}
+
internal-slot@1.1.0:
dependencies:
es-errors: 1.3.0
@@ -5349,6 +6356,13 @@ snapshots:
ipaddr.js@1.9.1: {}
+ is-alphabetical@2.0.1: {}
+
+ is-alphanumerical@2.0.1:
+ dependencies:
+ is-alphabetical: 2.0.1
+ is-decimal: 2.0.1
+
is-array-buffer@3.0.5:
dependencies:
call-bind: 1.0.8
@@ -5397,6 +6411,8 @@ snapshots:
call-bound: 1.0.4
has-tostringtag: 1.0.2
+ is-decimal@2.0.1: {}
+
is-docker@3.0.0: {}
is-extglob@2.1.1: {}
@@ -5419,6 +6435,8 @@ snapshots:
dependencies:
is-extglob: 2.1.1
+ is-hexadecimal@2.0.1: {}
+
is-inside-container@1.0.0:
dependencies:
is-docker: 3.0.0
@@ -5438,6 +6456,8 @@ snapshots:
is-path-inside@3.0.3: {}
+ is-plain-obj@4.1.0: {}
+
is-promise@4.0.0: {}
is-regex@1.2.1:
@@ -5558,6 +6578,10 @@ snapshots:
object.assign: 4.1.7
object.values: 1.2.1
+ katex@0.16.27:
+ dependencies:
+ commander: 8.3.0
+
keyv@4.5.4:
dependencies:
json-buffer: 3.0.1
@@ -5585,6 +6609,8 @@ snapshots:
long@5.3.2: {}
+ longest-streak@3.1.0: {}
+
loose-envify@1.4.0:
dependencies:
js-tokens: 4.0.0
@@ -5601,12 +6627,181 @@ snapshots:
'@babel/types': 7.28.5
source-map-js: 1.2.1
+ markdown-table@3.0.4: {}
+
+ marked@17.0.1: {}
+
matchit@1.1.0:
dependencies:
'@arr/every': 1.0.1
math-intrinsics@1.1.0: {}
+ mdast-util-find-and-replace@3.0.2:
+ dependencies:
+ '@types/mdast': 4.0.4
+ escape-string-regexp: 5.0.0
+ unist-util-is: 6.0.1
+ unist-util-visit-parents: 6.0.2
+
+ mdast-util-from-markdown@2.0.2:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ decode-named-character-reference: 1.2.0
+ devlop: 1.1.0
+ mdast-util-to-string: 4.0.0
+ micromark: 4.0.2
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-decode-string: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+ unist-util-stringify-position: 4.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-autolink-literal@2.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ ccount: 2.0.1
+ devlop: 1.1.0
+ mdast-util-find-and-replace: 3.0.2
+ micromark-util-character: 2.1.1
+
+ mdast-util-gfm-footnote@2.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.2
+ mdast-util-to-markdown: 2.1.2
+ micromark-util-normalize-identifier: 2.0.1
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-strikethrough@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.0.2
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-table@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ markdown-table: 3.0.4
+ mdast-util-from-markdown: 2.0.2
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-task-list-item@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.2
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm@3.1.0:
+ dependencies:
+ mdast-util-from-markdown: 2.0.2
+ mdast-util-gfm-autolink-literal: 2.0.1
+ mdast-util-gfm-footnote: 2.1.0
+ mdast-util-gfm-strikethrough: 2.0.0
+ mdast-util-gfm-table: 2.0.0
+ mdast-util-gfm-task-list-item: 2.0.0
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-math@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ longest-streak: 3.1.0
+ mdast-util-from-markdown: 2.0.2
+ mdast-util-to-markdown: 2.1.2
+ unist-util-remove-position: 5.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdx-expression@2.0.1:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.2
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdx-jsx@3.2.0:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ ccount: 2.0.1
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.2
+ mdast-util-to-markdown: 2.1.2
+ parse-entities: 4.0.2
+ stringify-entities: 4.0.4
+ unist-util-stringify-position: 4.0.0
+ vfile-message: 4.0.3
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdxjs-esm@2.0.1:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.2
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-phrasing@4.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ unist-util-is: 6.0.1
+
+ mdast-util-to-hast@13.2.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ '@ungap/structured-clone': 1.3.0
+ devlop: 1.1.0
+ micromark-util-sanitize-uri: 2.0.1
+ trim-lines: 3.0.1
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.0.0
+ vfile: 6.0.3
+
+ mdast-util-to-markdown@2.1.2:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ longest-streak: 3.1.0
+ mdast-util-phrasing: 4.1.0
+ mdast-util-to-string: 4.0.0
+ micromark-util-classify-character: 2.0.1
+ micromark-util-decode-string: 2.0.1
+ unist-util-visit: 5.0.0
+ zwitch: 2.0.4
+
+ mdast-util-to-string@4.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+
media-typer@1.1.0: {}
merge-descriptors@2.0.0: {}
@@ -5615,6 +6810,239 @@ snapshots:
merge2@1.4.1: {}
+ micromark-core-commonmark@2.0.3:
+ dependencies:
+ decode-named-character-reference: 1.2.0
+ devlop: 1.1.0
+ micromark-factory-destination: 2.0.1
+ micromark-factory-label: 2.0.1
+ micromark-factory-space: 2.0.1
+ micromark-factory-title: 2.0.1
+ micromark-factory-whitespace: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-chunked: 2.0.1
+ micromark-util-classify-character: 2.0.1
+ micromark-util-html-tag-name: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-subtokenize: 2.1.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-cjk-friendly-gfm-strikethrough@1.2.3(micromark-util-types@2.0.2)(micromark@4.0.2):
+ dependencies:
+ devlop: 1.1.0
+ get-east-asian-width: 1.4.0
+ micromark: 4.0.2
+ micromark-extension-cjk-friendly-util: 2.1.1(micromark-util-types@2.0.2)
+ micromark-util-character: 2.1.1
+ micromark-util-chunked: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-symbol: 2.0.1
+ optionalDependencies:
+ micromark-util-types: 2.0.2
+
+ micromark-extension-cjk-friendly-util@2.1.1(micromark-util-types@2.0.2):
+ dependencies:
+ get-east-asian-width: 1.4.0
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ optionalDependencies:
+ micromark-util-types: 2.0.2
+
+ micromark-extension-cjk-friendly@1.2.3(micromark-util-types@2.0.2)(micromark@4.0.2):
+ dependencies:
+ devlop: 1.1.0
+ micromark: 4.0.2
+ micromark-extension-cjk-friendly-util: 2.1.1(micromark-util-types@2.0.2)
+ micromark-util-chunked: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-symbol: 2.0.1
+ optionalDependencies:
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-autolink-literal@2.1.0:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-footnote@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.3
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-strikethrough@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.1
+ micromark-util-classify-character: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-table@2.1.1:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-tagfilter@2.0.0:
+ dependencies:
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-task-list-item@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm@3.0.0:
+ dependencies:
+ micromark-extension-gfm-autolink-literal: 2.1.0
+ micromark-extension-gfm-footnote: 2.1.0
+ micromark-extension-gfm-strikethrough: 2.1.0
+ micromark-extension-gfm-table: 2.1.1
+ micromark-extension-gfm-tagfilter: 2.0.0
+ micromark-extension-gfm-task-list-item: 2.1.0
+ micromark-util-combine-extensions: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-math@3.1.0:
+ dependencies:
+ '@types/katex': 0.16.8
+ devlop: 1.1.0
+ katex: 0.16.27
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-destination@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-label@2.0.1:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-space@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-title@2.0.1:
+ dependencies:
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-whitespace@2.0.1:
+ dependencies:
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-character@2.1.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-chunked@2.0.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-classify-character@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-combine-extensions@2.0.1:
+ dependencies:
+ micromark-util-chunked: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-decode-numeric-character-reference@2.0.2:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-decode-string@2.0.1:
+ dependencies:
+ decode-named-character-reference: 1.2.0
+ micromark-util-character: 2.1.1
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-encode@2.0.1: {}
+
+ micromark-util-html-tag-name@2.0.1: {}
+
+ micromark-util-normalize-identifier@2.0.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-resolve-all@2.0.1:
+ dependencies:
+ micromark-util-types: 2.0.2
+
+ micromark-util-sanitize-uri@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-encode: 2.0.1
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-subtokenize@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-symbol@2.0.1: {}
+
+ micromark-util-types@2.0.2: {}
+
+ micromark@4.0.2:
+ dependencies:
+ '@types/debug': 4.1.12
+ debug: 4.4.3(supports-color@10.2.2)
+ decode-named-character-reference: 1.2.0
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.3
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-chunked: 2.0.1
+ micromark-util-combine-extensions: 2.0.1
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-encode: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-subtokenize: 2.1.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+ transitivePeerDependencies:
+ - supports-color
+
micromatch@4.0.8:
dependencies:
braces: 3.0.3
@@ -5809,6 +7237,14 @@ snapshots:
dependencies:
mimic-fn: 4.0.0
+ oniguruma-parser@0.12.1: {}
+
+ oniguruma-to-es@4.3.4:
+ dependencies:
+ oniguruma-parser: 0.12.1
+ regex: 6.1.0
+ regex-recursion: 6.0.2
+
open@10.2.0:
dependencies:
default-browser: 5.4.0
@@ -5857,6 +7293,20 @@ snapshots:
dependencies:
callsites: 3.1.0
+ parse-entities@4.0.2:
+ dependencies:
+ '@types/unist': 2.0.11
+ character-entities-legacy: 3.0.0
+ character-reference-invalid: 2.0.1
+ decode-named-character-reference: 1.2.0
+ is-alphanumerical: 2.0.1
+ is-decimal: 2.0.1
+ is-hexadecimal: 2.0.1
+
+ parse5@7.3.0:
+ dependencies:
+ entities: 6.0.1
+
parseurl@1.3.3: {}
partysocket@1.1.10:
@@ -5941,6 +7391,11 @@ snapshots:
postcss: 8.5.6
postcss-selector-parser: 6.1.2
+ postcss-selector-parser@6.0.10:
+ dependencies:
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
+
postcss-selector-parser@6.1.2:
dependencies:
cssesc: 3.0.0
@@ -5973,6 +7428,8 @@ snapshots:
object-assign: 4.1.1
react-is: 16.13.1
+ property-information@7.1.0: {}
+
protobufjs@7.5.4:
dependencies:
'@protobufjs/aspromise': 1.1.2
@@ -6050,6 +7507,16 @@ snapshots:
get-proto: 1.0.1
which-builtin-type: 1.2.1
+ regex-recursion@6.0.2:
+ dependencies:
+ regex-utilities: 2.3.0
+
+ regex-utilities@2.3.0: {}
+
+ regex@6.1.0:
+ dependencies:
+ regex-utilities: 2.3.0
+
regexp.prototype.flags@1.5.4:
dependencies:
call-bind: 1.0.8
@@ -6059,6 +7526,96 @@ snapshots:
gopd: 1.2.0
set-function-name: 2.0.2
+ rehype-harden@1.1.7:
+ dependencies:
+ unist-util-visit: 5.0.0
+
+ rehype-katex@7.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/katex': 0.16.8
+ hast-util-from-html-isomorphic: 2.0.0
+ hast-util-to-text: 4.0.2
+ katex: 0.16.27
+ unist-util-visit-parents: 6.0.2
+ vfile: 6.0.3
+
+ rehype-raw@7.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-raw: 9.1.0
+ vfile: 6.0.3
+
+ rehype-sanitize@6.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-sanitize: 5.0.2
+
+ remark-cjk-friendly-gfm-strikethrough@1.2.3(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(unified@11.0.5):
+ dependencies:
+ micromark-extension-cjk-friendly-gfm-strikethrough: 1.2.3(micromark-util-types@2.0.2)(micromark@4.0.2)
+ unified: 11.0.5
+ optionalDependencies:
+ '@types/mdast': 4.0.4
+ transitivePeerDependencies:
+ - micromark
+ - micromark-util-types
+
+ remark-cjk-friendly@1.2.3(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(unified@11.0.5):
+ dependencies:
+ micromark-extension-cjk-friendly: 1.2.3(micromark-util-types@2.0.2)(micromark@4.0.2)
+ unified: 11.0.5
+ optionalDependencies:
+ '@types/mdast': 4.0.4
+ transitivePeerDependencies:
+ - micromark
+ - micromark-util-types
+
+ remark-gfm@4.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-gfm: 3.1.0
+ micromark-extension-gfm: 3.0.0
+ remark-parse: 11.0.0
+ remark-stringify: 11.0.0
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-math@6.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-math: 3.0.0
+ micromark-extension-math: 3.1.0
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-parse@11.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.0.2
+ micromark-util-types: 2.0.2
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-rehype@11.1.2:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ mdast-util-to-hast: 13.2.1
+ unified: 11.0.5
+ vfile: 6.0.3
+
+ remark-stringify@11.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-to-markdown: 2.1.2
+ unified: 11.0.5
+
+ remend@1.0.2: {}
+
require-from-string@2.0.2: {}
require-in-the-middle@7.5.2(supports-color@10.2.2):
@@ -6197,6 +7754,17 @@ snapshots:
shebang-regex@3.0.0: {}
+ shiki@3.21.0:
+ dependencies:
+ '@shikijs/core': 3.21.0
+ '@shikijs/engine-javascript': 3.21.0
+ '@shikijs/engine-oniguruma': 3.21.0
+ '@shikijs/langs': 3.21.0
+ '@shikijs/themes': 3.21.0
+ '@shikijs/types': 3.21.0
+ '@shikijs/vscode-textmate': 10.0.2
+ '@types/hast': 3.0.4
+
side-channel-list@1.0.0:
dependencies:
es-errors: 1.3.0
@@ -6281,6 +7849,8 @@ snapshots:
source-map@0.6.1: {}
+ space-separated-tokens@2.0.2: {}
+
stable-hash@0.0.5: {}
statuses@2.0.2: {}
@@ -6292,6 +7862,36 @@ snapshots:
es-errors: 1.3.0
internal-slot: 1.1.0
+ streamdown@2.0.1(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(react@18.3.1):
+ dependencies:
+ clsx: 2.1.1
+ esbuild: 0.27.2
+ hast-util-to-jsx-runtime: 2.3.6
+ html-url-attributes: 3.0.1
+ katex: 0.16.27
+ marked: 17.0.1
+ react: 18.3.1
+ rehype-harden: 1.1.7
+ rehype-katex: 7.0.1
+ rehype-raw: 7.0.0
+ rehype-sanitize: 6.0.0
+ remark-cjk-friendly: 1.2.3(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(unified@11.0.5)
+ remark-cjk-friendly-gfm-strikethrough: 1.2.3(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(unified@11.0.5)
+ remark-gfm: 4.0.1
+ remark-math: 6.0.0
+ remark-parse: 11.0.0
+ remark-rehype: 11.1.2
+ remend: 1.0.2
+ shiki: 3.21.0
+ tailwind-merge: 3.4.0
+ unified: 11.0.5
+ unist-util-visit: 5.0.0
+ transitivePeerDependencies:
+ - '@types/mdast'
+ - micromark
+ - micromark-util-types
+ - supports-color
+
streamsearch@1.1.0: {}
string-width@4.2.3:
@@ -6356,6 +7956,11 @@ snapshots:
define-properties: 1.2.1
es-object-atoms: 1.1.1
+ stringify-entities@4.0.4:
+ dependencies:
+ character-entities-html4: 2.1.0
+ character-entities-legacy: 3.0.0
+
strip-ansi@6.0.1:
dependencies:
ansi-regex: 5.0.1
@@ -6370,6 +7975,14 @@ snapshots:
strip-json-comments@3.1.1: {}
+ style-to-js@1.1.21:
+ dependencies:
+ style-to-object: 1.0.14
+
+ style-to-object@1.0.14:
+ dependencies:
+ inline-style-parser: 0.2.7
+
styled-jsx@5.1.1(react@18.3.1):
dependencies:
client-only: 0.0.1
@@ -6571,6 +8184,10 @@ snapshots:
- utf-8-validate
- valibot
+ trim-lines@3.0.1: {}
+
+ trough@2.2.0: {}
+
trouter@2.0.1:
dependencies:
matchit: 1.1.0
@@ -6660,6 +8277,49 @@ snapshots:
undici-types@6.21.0: {}
+ unified@11.0.5:
+ dependencies:
+ '@types/unist': 3.0.3
+ bail: 2.0.2
+ devlop: 1.1.0
+ extend: 3.0.2
+ is-plain-obj: 4.1.0
+ trough: 2.2.0
+ vfile: 6.0.3
+
+ unist-util-find-after@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+
+ unist-util-is@6.0.1:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-remove-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-visit: 5.0.0
+
+ unist-util-stringify-position@4.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-visit-parents@6.0.2:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+
+ unist-util-visit@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+ unist-util-visit-parents: 6.0.2
+
unpipe@1.0.0: {}
unrs-resolver@1.11.1:
@@ -6700,6 +8360,23 @@ snapshots:
vary@1.1.2: {}
+ vfile-location@5.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile: 6.0.3
+
+ vfile-message@4.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-stringify-position: 4.0.0
+
+ vfile@6.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile-message: 4.0.3
+
+ web-namespaces@2.0.1: {}
+
which-boxed-primitive@1.1.1:
dependencies:
is-bigint: 1.1.0
@@ -6808,3 +8485,5 @@ snapshots:
zod@3.25.76: {}
zod@4.3.5: {}
+
+ zwitch@2.0.4: {}
diff --git a/background-ralph/src/app/globals.css b/background-ralph/src/app/globals.css
index 18323ca..d381f5a 100644
--- a/background-ralph/src/app/globals.css
+++ b/background-ralph/src/app/globals.css
@@ -4,57 +4,51 @@
@layer base {
:root {
- --background: 0 0% 100%;
- --foreground: 0 0% 3.9%;
+ /* Slate-based palette (Linear-inspired) */
+ --background: 210 20% 98%;
+ --foreground: 222 47% 11%;
--card: 0 0% 100%;
- --card-foreground: 0 0% 3.9%;
+ --card-foreground: 222 47% 11%;
--popover: 0 0% 100%;
- --popover-foreground: 0 0% 3.9%;
- --primary: 0 0% 9%;
- --primary-foreground: 0 0% 98%;
- --secondary: 0 0% 96.1%;
- --secondary-foreground: 0 0% 9%;
- --muted: 0 0% 96.1%;
- --muted-foreground: 0 0% 45.1%;
- --accent: 0 0% 96.1%;
- --accent-foreground: 0 0% 9%;
- --destructive: 0 84.2% 60.2%;
+ --popover-foreground: 222 47% 11%;
+ --primary: 222 47% 11%;
+ --primary-foreground: 210 20% 98%;
+ --secondary: 214 32% 91%;
+ --secondary-foreground: 222 47% 11%;
+ --muted: 214 32% 91%;
+ --muted-foreground: 215 16% 47%;
+ --accent: 214 32% 91%;
+ --accent-foreground: 222 47% 11%;
+ --destructive: 0 84% 60%;
--destructive-foreground: 0 0% 98%;
- --border: 0 0% 89.8%;
- --input: 0 0% 89.8%;
- --ring: 0 0% 3.9%;
- --chart-1: 12 76% 61%;
- --chart-2: 173 58% 39%;
- --chart-3: 197 37% 24%;
- --chart-4: 43 74% 66%;
- --chart-5: 27 87% 67%;
- --radius: 0.5rem
+ --border: 214 32% 91%;
+ --input: 214 32% 91%;
+ --ring: 222 47% 11%;
+
+ /* Consistent 6px radius (subtle) */
+ --radius: 0.375rem;
}
+
.dark {
- --background: 0 0% 3.9%;
- --foreground: 0 0% 98%;
- --card: 0 0% 3.9%;
- --card-foreground: 0 0% 98%;
- --popover: 0 0% 3.9%;
- --popover-foreground: 0 0% 98%;
- --primary: 0 0% 98%;
- --primary-foreground: 0 0% 9%;
- --secondary: 0 0% 14.9%;
- --secondary-foreground: 0 0% 98%;
- --muted: 0 0% 14.9%;
- --muted-foreground: 0 0% 63.9%;
- --accent: 0 0% 14.9%;
- --accent-foreground: 0 0% 98%;
- --destructive: 0 62.8% 30.6%;
+ --background: 222 47% 11%;
+ --foreground: 210 20% 98%;
+ --card: 222 47% 11%;
+ --card-foreground: 210 20% 98%;
+ --popover: 222 47% 11%;
+ --popover-foreground: 210 20% 98%;
+ --primary: 210 20% 98%;
+ --primary-foreground: 222 47% 11%;
+ --secondary: 217 33% 17%;
+ --secondary-foreground: 210 20% 98%;
+ --muted: 217 33% 17%;
+ --muted-foreground: 215 20% 65%;
+ --accent: 217 33% 17%;
+ --accent-foreground: 210 20% 98%;
+ --destructive: 0 62% 30%;
--destructive-foreground: 0 0% 98%;
- --border: 0 0% 14.9%;
- --input: 0 0% 14.9%;
- --ring: 0 0% 83.1%;
- --chart-1: 220 70% 50%;
- --chart-2: 160 60% 45%;
- --chart-3: 30 80% 55%;
- --chart-4: 280 65% 60%;
- --chart-5: 340 75% 55%
+ --border: 217 33% 17%;
+ --input: 217 33% 17%;
+ --ring: 212 27% 84%;
}
}
@@ -62,7 +56,40 @@
* {
@apply border-border;
}
+
body {
@apply bg-background text-foreground;
+ font-feature-settings: "rlig" 1, "calt" 1;
+ }
+
+ /* Tighter line heights for app UI */
+ h1, h2, h3, h4, h5, h6 {
+ @apply tracking-tight;
+ }
+}
+
+/* Custom scrollbar (subtle) */
+@layer utilities {
+ .scrollbar-thin {
+ scrollbar-width: thin;
+ scrollbar-color: hsl(var(--muted-foreground) / 0.3) transparent;
+ }
+
+ .scrollbar-thin::-webkit-scrollbar {
+ width: 6px;
+ height: 6px;
+ }
+
+ .scrollbar-thin::-webkit-scrollbar-track {
+ background: transparent;
+ }
+
+ .scrollbar-thin::-webkit-scrollbar-thumb {
+ background: hsl(var(--muted-foreground) / 0.3);
+ border-radius: 3px;
+ }
+
+ .scrollbar-thin::-webkit-scrollbar-thumb:hover {
+ background: hsl(var(--muted-foreground) / 0.5);
}
}
diff --git a/background-ralph/src/app/layout.tsx b/background-ralph/src/app/layout.tsx
index dd6db2c..c7d047a 100644
--- a/background-ralph/src/app/layout.tsx
+++ b/background-ralph/src/app/layout.tsx
@@ -1,11 +1,8 @@
import type { Metadata } from "next"
-import { Inter } from "next/font/google"
+import { GeistSans } from "geist/font/sans"
+import { GeistMono } from "geist/font/mono"
import "./globals.css"
-const inter = Inter({
- subsets: ["latin"],
-})
-
export const metadata: Metadata = {
title: "Background Ralph",
description: "Autonomous Claude Code agent running Ralph Wiggum loops",
@@ -17,8 +14,8 @@ export default function RootLayout({
children: React.ReactNode
}>) {
return (
-
-
+
+
{children}
diff --git a/background-ralph/src/app/page.tsx b/background-ralph/src/app/page.tsx
index b622143..82ba8f2 100644
--- a/background-ralph/src/app/page.tsx
+++ b/background-ralph/src/app/page.tsx
@@ -2,10 +2,14 @@ import { RalphApp } from "@/components/ralph-app"
export default function Home() {
return (
-
-
-
Background Ralph
-
Autonomous Claude Code agent
+
+
+
+ Background Ralph
+
+
+ Autonomous Claude Code agent
+
diff --git a/background-ralph/src/components/agent-output.tsx b/background-ralph/src/components/agent-output.tsx
new file mode 100644
index 0000000..0296f6a
--- /dev/null
+++ b/background-ralph/src/components/agent-output.tsx
@@ -0,0 +1,87 @@
+"use client"
+
+import { useRef, useEffect, useState } from "react"
+import { Streamdown } from "streamdown"
+
+type Props = {
+ content: string
+}
+
+export function AgentOutput({ content }: Props) {
+ const containerRef = useRef
(null)
+ const [isCollapsed, setIsCollapsed] = useState(false)
+ const [isAutoScroll, setIsAutoScroll] = useState(true)
+
+ // Auto-scroll when new content arrives (if not paused)
+ useEffect(() => {
+ if (isAutoScroll && containerRef.current) {
+ containerRef.current.scrollTop = containerRef.current.scrollHeight
+ }
+ }, [content, isAutoScroll])
+
+ // Pause auto-scroll on user interaction
+ function handleScroll() {
+ if (!containerRef.current) return
+ const { scrollTop, scrollHeight, clientHeight } = containerRef.current
+ const isAtBottom = scrollHeight - scrollTop - clientHeight < 50
+ setIsAutoScroll(isAtBottom)
+ }
+
+ if (isCollapsed) {
+ return (
+
+
+
+ )
+ }
+
+ return (
+
+ {/* Header */}
+
+
+ Agent output
+
+
+ {!isAutoScroll && (
+
+ )}
+
+
+
+
+ {/* Content */}
+
+ {content ? (
+
+ {content}
+
+ ) : (
+
+ Waiting for agent output...
+
+ )}
+
+
+ )
+}
diff --git a/background-ralph/src/components/help-modal.tsx b/background-ralph/src/components/help-modal.tsx
new file mode 100644
index 0000000..4d0d47a
--- /dev/null
+++ b/background-ralph/src/components/help-modal.tsx
@@ -0,0 +1,65 @@
+"use client"
+
+import { useEffect } from "react"
+
+type Props = {
+ isOpen: boolean
+ onClose: () => void
+}
+
+const shortcuts = [
+ { key: "C", action: "Continue to next story" },
+ { key: "S", action: "Stop execution" },
+ { key: "E", action: "Edit selected story" },
+ { key: "ā / k", action: "Navigate up" },
+ { key: "ā / j", action: "Navigate down" },
+ { key: "?", action: "Show this help" },
+ { key: "Esc", action: "Close modal" },
+]
+
+export function HelpModal({ isOpen, onClose }: Props) {
+ // Close on escape
+ useEffect(() => {
+ function handleKeyDown(e: KeyboardEvent) {
+ if (e.key === "Escape") onClose()
+ }
+ if (isOpen) {
+ window.addEventListener("keydown", handleKeyDown)
+ return () => window.removeEventListener("keydown", handleKeyDown)
+ }
+ }, [isOpen, onClose])
+
+ if (!isOpen) return null
+
+ return (
+
+ {/* Backdrop */}
+
+
+ {/* Modal */}
+
+
+ Keyboard shortcuts
+
+
+
+ {shortcuts.map(({ key, action }) => (
+
+ {action}
+
+ {key}
+
+
+ ))}
+
+
+
+
+
+ )
+}
diff --git a/background-ralph/src/components/kanban-board.tsx b/background-ralph/src/components/kanban-board.tsx
new file mode 100644
index 0000000..c0e13f1
--- /dev/null
+++ b/background-ralph/src/components/kanban-board.tsx
@@ -0,0 +1,110 @@
+import type { Prd, Story } from "@/trigger/streams"
+import { StoryCard } from "./story-card"
+
+type Props = {
+ prd: Prd
+ completedStoryIds: Set
+ currentStoryId?: string
+ storyDiffs?: Map
+ onEditStory?: (story: Story) => void
+}
+
+function KanbanColumn({
+ title,
+ stories,
+ status,
+ emptyText,
+ diffs,
+ onEdit,
+}: {
+ title: string
+ stories: Story[]
+ status: "pending" | "in_progress" | "done"
+ emptyText: string
+ diffs?: Map
+ onEdit?: (story: Story) => void
+}) {
+ const headerStyle = {
+ pending: "text-slate-500",
+ in_progress: "text-blue-600",
+ done: "text-emerald-600",
+ }[status]
+
+ const countStyle = {
+ pending: "bg-slate-100 text-slate-500",
+ in_progress: "bg-blue-100 text-blue-600",
+ done: "bg-emerald-100 text-emerald-600",
+ }[status]
+
+ return (
+
+ {/* Column header */}
+
+
+ {title}
+
+
+ {stories.length}
+
+
+
+ {/* Cards */}
+
+ {stories.length === 0 ? (
+
{emptyText}
+ ) : (
+ stories.map((story) => (
+
+ ))
+ )}
+
+
+ )
+}
+
+export function KanbanBoard({ prd, completedStoryIds, currentStoryId, storyDiffs, onEditStory }: Props) {
+ const pendingStories: Story[] = []
+ const inProgressStories: Story[] = []
+ const doneStories: Story[] = []
+
+ for (const story of prd.stories) {
+ if (completedStoryIds.has(story.id)) {
+ doneStories.push(story)
+ } else if (story.id === currentStoryId) {
+ inProgressStories.push(story)
+ } else {
+ pendingStories.push(story)
+ }
+ }
+
+ return (
+
+
+
+
+
+ )
+}
diff --git a/background-ralph/src/components/keyboard-handler.tsx b/background-ralph/src/components/keyboard-handler.tsx
new file mode 100644
index 0000000..3c5f194
--- /dev/null
+++ b/background-ralph/src/components/keyboard-handler.tsx
@@ -0,0 +1,73 @@
+"use client"
+
+import { useEffect, useCallback } from "react"
+
+type Props = {
+ onContinue?: () => void
+ onStop?: () => void
+ onEdit?: () => void
+ onHelp: () => void
+ onNavigateUp?: () => void
+ onNavigateDown?: () => void
+ disabled?: boolean
+}
+
+export function useKeyboardShortcuts({
+ onContinue,
+ onStop,
+ onEdit,
+ onHelp,
+ onNavigateUp,
+ onNavigateDown,
+ disabled,
+}: Props) {
+ const handleKeyDown = useCallback(
+ (e: KeyboardEvent) => {
+ // Don't fire shortcuts when typing in inputs
+ const target = e.target as HTMLElement
+ if (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable) {
+ return
+ }
+
+ if (disabled) return
+
+ switch (e.key.toLowerCase()) {
+ case "c":
+ e.preventDefault()
+ onContinue?.()
+ break
+ case "s":
+ e.preventDefault()
+ onStop?.()
+ break
+ case "e":
+ e.preventDefault()
+ onEdit?.()
+ break
+ case "?":
+ e.preventDefault()
+ onHelp()
+ break
+ case "arrowup":
+ case "k":
+ e.preventDefault()
+ onNavigateUp?.()
+ break
+ case "arrowdown":
+ case "j":
+ e.preventDefault()
+ onNavigateDown?.()
+ break
+ case "escape":
+ // Let modals handle escape
+ break
+ }
+ },
+ [onContinue, onStop, onEdit, onHelp, onNavigateUp, onNavigateDown, disabled]
+ )
+
+ useEffect(() => {
+ window.addEventListener("keydown", handleKeyDown)
+ return () => window.removeEventListener("keydown", handleKeyDown)
+ }, [handleKeyDown])
+}
diff --git a/background-ralph/src/components/ralph-app.tsx b/background-ralph/src/components/ralph-app.tsx
index 6622324..44778f5 100644
--- a/background-ralph/src/components/ralph-app.tsx
+++ b/background-ralph/src/components/ralph-app.tsx
@@ -6,7 +6,6 @@ import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
import { Label } from "@/components/ui/label"
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { RunViewer } from "@/components/run-viewer"
type RunState = {
@@ -45,78 +44,86 @@ export function RalphApp() {
return (
- {/* Form - greyed out when running */}
-
-
- Start a task
+ {/* Form section */}
+
+
+
Start a task
{isRunning && (
-
-
-
-
-
+
-
-
+ {error && (
+
{error}
+ )}
+
+
+ {isPending ? "Starting..." : "Start task"}
+
+
+
- {/* Run viewer - inline below form */}
+ {/* Run viewer */}
{runState && (
-
-
-
- Run: {runState.runId}
-
-
-
+
+
+ Run
+ {runState.runId}
+
+
-
-
+
+
)}
)
diff --git a/background-ralph/src/components/run-viewer.tsx b/background-ralph/src/components/run-viewer.tsx
index 0246c01..db02644 100644
--- a/background-ralph/src/components/run-viewer.tsx
+++ b/background-ralph/src/components/run-viewer.tsx
@@ -2,7 +2,13 @@
import { useState } from "react"
import { useRealtimeRun, useRealtimeStream, useWaitToken } from "@trigger.dev/react-hooks"
-import { statusStream, agentOutputStream, type StatusUpdate, type Prd } from "@/trigger/streams"
+import { statusStream, agentOutputStream, type StatusUpdate, type Prd, type Story } from "@/trigger/streams"
+import { KanbanBoard } from "./kanban-board"
+import { AgentOutput } from "./agent-output"
+import { StoryEditor } from "./story-editor"
+import { HelpModal } from "./help-modal"
+import { ShortcutFooter } from "./shortcut-footer"
+import { useKeyboardShortcuts } from "./keyboard-handler"
import type { ralphLoop } from "@/trigger/ralph-loop"
import { Button } from "@/components/ui/button"
import { cancelRun } from "@/app/actions"
@@ -60,57 +66,6 @@ function ApprovalGate({
)
}
-type StoryResult = {
- commitHash?: string
- commitUrl?: string
-}
-
-function StoryList({
- prd,
- completedStories,
- currentStoryId,
-}: {
- prd: Prd
- completedStories: Map
- currentStoryId?: string
-}) {
- return (
-
-
- Stories ({completedStories.size}/{prd.stories.length} complete)
-
-
- {prd.stories.map((story, i) => {
- const result = completedStories.get(story.id)
- const isComplete = !!result
- const isCurrent = story.id === currentStoryId
- return (
-
-
- {isComplete ? "ā" : `${i + 1}.`}
-
-
{story.title}
- {result?.commitUrl && (
-
- commit
-
- )}
- {isCurrent &&
in progress}
-
- )
- })}
-
-
- )
-}
function PRDEditor({
prd,
@@ -172,6 +127,10 @@ const terminalStatuses = ["COMPLETED", "CANCELED", "FAILED", "CRASHED", "SYSTEM_
export function RunViewer({ runId, accessToken }: Props) {
const [isCanceling, setIsCanceling] = useState(false)
const [cancelError, setCancelError] = useState()
+ const [editingStory, setEditingStory] = useState(null)
+ const [localPrdOverride, setLocalPrdOverride] = useState(null)
+ const [showHelp, setShowHelp] = useState(false)
+ const [selectedStoryIndex, setSelectedStoryIndex] = useState(0)
const { run, error: runError } = useRealtimeRun(runId, {
accessToken,
@@ -197,10 +156,6 @@ export function RunViewer({ runId, accessToken }: Props) {
accessToken,
})
- if (runError) {
- return Error: {runError.message}
- }
-
// Parse JSON strings back to objects
const statusParts: StatusUpdate[] = (rawStatusParts ?? []).map(part => {
try {
@@ -219,20 +174,37 @@ export function RunViewer({ runId, accessToken }: Props) {
const pendingPrdReview = latestStatus?.type === "prd_review" ? { waitpoint: latestStatus.waitpoint, prd: latestStatus.prd } : null
// Derive PRD from status events (prd_generated takes precedence over prd_review)
- const currentPrd = statusParts.reduce((acc, s) => {
+ // Use local override if user has edited stories
+ const serverPrd = statusParts.reduce((acc, s) => {
if (s.type === "prd_generated" && s.prd) return s.prd
if (s.type === "prd_review" && s.prd && !acc) return s.prd
return acc
}, null)
+ const currentPrd = localPrdOverride ?? serverPrd
+
+ // Handle story editing
+ function handleEditStory(story: Story) {
+ setEditingStory(story)
+ }
- // Derive completed stories from story_complete events
- const completedStories = new Map()
+ function handleSaveStory(updated: Story) {
+ if (!currentPrd) return
+ const updatedStories = currentPrd.stories.map(s =>
+ s.id === updated.id ? updated : s
+ )
+ setLocalPrdOverride({ ...currentPrd, stories: updatedStories })
+ setEditingStory(null)
+ }
+
+ // Derive completed stories and per-story diffs from story_complete events
+ const completedStoryIds = new Set()
+ const storyDiffs = new Map()
for (const s of statusParts) {
if (s.type === "story_complete" && s.story?.id) {
- completedStories.set(s.story.id, {
- commitHash: s.commitHash,
- commitUrl: s.commitUrl,
- })
+ completedStoryIds.add(s.story.id)
+ if (s.story.diff) {
+ storyDiffs.set(s.story.id, s.story.diff)
+ }
}
}
@@ -248,6 +220,37 @@ export function RunViewer({ runId, accessToken }: Props) {
console.log("[RunViewer] latestStatus:", latestStatus)
console.log("[RunViewer] pendingWaitpoint:", pendingWaitpoint)
+ // Get pending stories for keyboard navigation
+ const pendingStories = currentPrd?.stories.filter(s =>
+ !completedStoryIds.has(s.id) && s.id !== currentStoryId
+ ) ?? []
+
+ // Keyboard shortcuts
+ useKeyboardShortcuts({
+ onHelp: () => setShowHelp(true),
+ onEdit: () => {
+ const story = pendingStories[selectedStoryIndex]
+ if (story) setEditingStory(story)
+ },
+ onNavigateUp: () => {
+ setSelectedStoryIndex(Math.max(0, selectedStoryIndex - 1))
+ },
+ onNavigateDown: () => {
+ setSelectedStoryIndex(Math.min(pendingStories.length - 1, selectedStoryIndex + 1))
+ },
+ disabled: !!editingStory || showHelp,
+ })
+
+ // Handle run error
+ if (runError) {
+ return (
+
+
Error loading run: {runError.message}
+
setShowHelp(false)} />
+
+ )
+ }
+
return (
{/* Run status + token usage + cancel */}
@@ -393,17 +396,7 @@ export function RunViewer({ runId, accessToken }: Props) {
if (pendingWaitpoint) {
return (
-
- {latestStatus?.commitUrl && (
-
- View commit ā
-
- )}
+
-
+
+
+ Stories ({completedStoryIds.size}/{currentPrd.stories.length} complete)
+
+
+
)}
{/* Agent output */}
-
-
- {agentOutput || "Waiting for agent output..."}
-
-
+
{/* Status history */}
{statusParts.length > 0 && (
@@ -451,6 +447,29 @@ export function RunViewer({ runId, accessToken }: Props) {
)}
+
+ {/* Footer with shortcuts */}
+ {currentPrd && (
+
setShowHelp(true)}
+ />
+ )}
+
+ {/* Modals */}
+ {editingStory && (
+ setEditingStory(null)}
+ />
+ )}
+
+ setShowHelp(false)}
+ />
)
}
diff --git a/background-ralph/src/components/shortcut-footer.tsx b/background-ralph/src/components/shortcut-footer.tsx
new file mode 100644
index 0000000..11e0b68
--- /dev/null
+++ b/background-ralph/src/components/shortcut-footer.tsx
@@ -0,0 +1,36 @@
+type Props = {
+ completedCount: number
+ totalCount: number
+ onHelp: () => void
+}
+
+export function ShortcutFooter({ completedCount, totalCount, onHelp }: Props) {
+ return (
+
+
+
+ C
+ Continue
+
+
+ S
+ Stop
+
+
+ E
+ Edit
+
+
+ ?
+ Help
+
+
+
+ {completedCount}/{totalCount} stories
+
+
+ )
+}
diff --git a/background-ralph/src/components/story-card.tsx b/background-ralph/src/components/story-card.tsx
new file mode 100644
index 0000000..c608076
--- /dev/null
+++ b/background-ralph/src/components/story-card.tsx
@@ -0,0 +1,95 @@
+"use client"
+
+import { useState } from "react"
+import type { Story } from "@/trigger/streams"
+
+type StoryStatus = "pending" | "in_progress" | "done"
+
+type Props = {
+ story: Story
+ status: StoryStatus
+ diff?: string
+ onEdit?: (story: Story) => void
+}
+
+export function StoryCard({ story, status, diff, onEdit }: Props) {
+ const [isDiffOpen, setIsDiffOpen] = useState(false)
+
+ const indicator = {
+ pending: { icon: "ā", color: "text-slate-400" },
+ in_progress: { icon: "ā", color: "text-blue-500" },
+ done: { icon: "ā", color: "text-emerald-500" },
+ }[status]
+
+ const cardStyle = {
+ pending: "bg-white border-slate-200 hover:border-slate-300",
+ in_progress: "bg-blue-50/50 border-blue-200 shadow-sm shadow-blue-100",
+ done: "bg-slate-50 border-slate-200",
+ }[status]
+
+ return (
+
+ {/* Header */}
+
+ {indicator.icon}
+ {story.id}
+ {status === "in_progress" && (
+
+ working
+
+ )}
+
+
+ {/* Title */}
+
+ {story.title}
+
+
+ {/* Acceptance criteria */}
+
+ {story.acceptance.slice(0, 2).map((criterion, i) => (
+ -
+ ā¢
+ {criterion}
+
+ ))}
+ {story.acceptance.length > 2 && (
+ -
+ +{story.acceptance.length - 2} more
+
+ )}
+
+
+ {/* Actions */}
+
+ {status === "pending" && onEdit && (
+ onEdit(story)}
+ className="text-[11px] text-slate-500 hover:text-slate-700 font-medium"
+ >
+ Edit
+
+ )}
+ {status === "done" && diff && (
+ setIsDiffOpen(!isDiffOpen)}
+ className="text-[11px] text-slate-500 hover:text-slate-700 font-medium flex items-center gap-1"
+ >
+ Diff {isDiffOpen ? "ā²" : "ā¼"}
+
+ )}
+
+
+ {/* Diff viewer (collapsed by default) */}
+ {isDiffOpen && diff && (
+
+ )}
+
+ )
+}
diff --git a/background-ralph/src/components/story-editor.tsx b/background-ralph/src/components/story-editor.tsx
new file mode 100644
index 0000000..d06e731
--- /dev/null
+++ b/background-ralph/src/components/story-editor.tsx
@@ -0,0 +1,85 @@
+"use client"
+
+import { useState } from "react"
+import type { Story } from "@/trigger/streams"
+import { Button } from "@/components/ui/button"
+
+type Props = {
+ story: Story
+ onSave: (updated: Story) => void
+ onCancel: () => void
+}
+
+export function StoryEditor({ story, onSave, onCancel }: Props) {
+ const [title, setTitle] = useState(story.title)
+ const [acceptance, setAcceptance] = useState(story.acceptance.join("\n"))
+
+ function handleSave() {
+ onSave({
+ ...story,
+ title: title.trim(),
+ acceptance: acceptance.split("\n").map(s => s.trim()).filter(Boolean),
+ })
+ }
+
+ return (
+
+ {/* Backdrop */}
+
+
+ {/* Modal */}
+
+
+ Edit story
+
+
+ {/* ID (read-only) */}
+
+
+ {/* Title */}
+
+
+ setTitle(e.target.value)}
+ className="w-full px-3 py-2 border border-slate-200 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
+ />
+
+
+ {/* Acceptance criteria */}
+
+
+
+
+ {/* Actions */}
+
+
+ Cancel
+
+
+ Save
+
+
+
+
+ )
+}
diff --git a/background-ralph/src/trigger/ralph-loop.ts b/background-ralph/src/trigger/ralph-loop.ts
index 30721f9..db7d586 100644
--- a/background-ralph/src/trigger/ralph-loop.ts
+++ b/background-ralph/src/trigger/ralph-loop.ts
@@ -338,8 +338,9 @@ build/
await writeFile(gitignorePath, defaultIgnores)
}
- // Create branch for all commits
- const branchName = `ralph-${Date.now()}`
+ // Create branch for all commits (slugify PRD name)
+ const slug = approvedPrd.name.toLowerCase().replace(/[^a-z0-9]+/g, '-').slice(0, 40)
+ const branchName = `ralph/${slug}`
await execAsync(`git -C ${repoPath} checkout -b ${branchName}`)
// Cumulative token usage
@@ -435,16 +436,12 @@ Complete this story. When done, the acceptance criteria should be met. Use Read,
// Check for changes and commit
let storyCommitHash: string | undefined
- let storyCommitUrl: string | undefined
const { stdout: status } = await execAsync(`git -C ${repoPath} status --porcelain`)
if (status.trim()) {
await execAsync(`git -C ${repoPath} add -A`)
await execAsync(`git -C ${repoPath} commit -m "${story.title.replace(/"/g, '\\"')}"`)
const { stdout: hash } = await execAsync(`git -C ${repoPath} rev-parse HEAD`)
storyCommitHash = hash.trim()
- if (parsed) {
- storyCommitUrl = `https://github.com/${parsed.owner}/${parsed.repo}/commit/${storyCommitHash}`
- }
logger.info("Committed story", { story: story.title, commitHash: storyCommitHash })
}
@@ -472,7 +469,18 @@ Complete this story. When done, the acceptance criteria should be met. Use Read,
// Update in-memory progress (Ralph loop pattern - no file in repo)
progressLog.push(`### ${story.title}\n- ${story.acceptance.join('\n- ')}`)
- // Story complete status
+ // Capture per-story diff for UI
+ let storyDiff = ""
+ if (storyCommitHash) {
+ try {
+ const { stdout: diff } = await execAsync(`git -C ${repoPath} diff HEAD~1`)
+ storyDiff = diff
+ } catch {
+ // No diff available
+ }
+ }
+
+ // Story complete status (commit URLs only available after push)
await appendStatus({
type: "story_complete",
message: `Completed story ${storyNum}/${totalStories}: ${story.title}`,
@@ -482,9 +490,9 @@ Complete this story. When done, the acceptance criteria should be met. Use Read,
total: totalStories,
title: story.title,
acceptance: story.acceptance,
+ diff: storyDiff || undefined,
},
commitHash: storyCommitHash,
- commitUrl: storyCommitUrl,
progress: progressLog.join('\n\n'),
usage,
})
@@ -515,7 +523,6 @@ Complete this story. When done, the acceptance criteria should be met. Use Read,
acceptance: story.acceptance,
},
commitHash: storyCommitHash,
- commitUrl: storyCommitUrl,
waitpoint: {
tokenId: token.id,
publicAccessToken: token.publicAccessToken,
diff --git a/background-ralph/src/trigger/streams.ts b/background-ralph/src/trigger/streams.ts
index 0a0bff3..c72d402 100644
--- a/background-ralph/src/trigger/streams.ts
+++ b/background-ralph/src/trigger/streams.ts
@@ -17,6 +17,9 @@ export type PrdStory = {
passes?: boolean
}
+// Alias for component usage
+export type Story = PrdStory
+
export type Prd = {
name: string
description: string
@@ -65,6 +68,7 @@ export type StatusUpdate = {
total: number
title: string
acceptance: string[]
+ diff?: string // Per-story git diff
}
commitHash?: string
commitUrl?: string
diff --git a/background-ralph/tailwind.config.ts b/background-ralph/tailwind.config.ts
index 168db8d..1a6a4b1 100644
--- a/background-ralph/tailwind.config.ts
+++ b/background-ralph/tailwind.config.ts
@@ -6,9 +6,14 @@ const config: Config = {
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
+ "./node_modules/streamdown/dist/**/*.js",
],
theme: {
extend: {
+ fontFamily: {
+ sans: ['var(--font-geist-sans)'],
+ mono: ['var(--font-geist-mono)'],
+ },
borderRadius: {
lg: 'var(--radius)',
md: 'calc(var(--radius) - 2px)',
@@ -58,6 +63,6 @@ const config: Config = {
}
}
},
- plugins: [require("tailwindcss-animate")],
+ plugins: [require("tailwindcss-animate"), require("@tailwindcss/typography")],
}
export default config
From 73dc5d599f935416856546e66de063003c7aed96 Mon Sep 17 00:00:00 2001
From: D-K-P <8297864+D-K-P@users.noreply.github.com>
Date: Tue, 13 Jan 2026 14:15:18 +0000
Subject: [PATCH 15/72] Full-width sidebar layout
---
background-ralph/src/app/page.tsx | 18 +-
.../src/components/mobile-warning.tsx | 12 ++
background-ralph/src/components/ralph-app.tsx | 168 ++++++++++--------
3 files changed, 115 insertions(+), 83 deletions(-)
create mode 100644 background-ralph/src/components/mobile-warning.tsx
diff --git a/background-ralph/src/app/page.tsx b/background-ralph/src/app/page.tsx
index 82ba8f2..c0d6655 100644
--- a/background-ralph/src/app/page.tsx
+++ b/background-ralph/src/app/page.tsx
@@ -1,17 +1,13 @@
import { RalphApp } from "@/components/ralph-app"
+import { MobileWarning } from "@/components/mobile-warning"
export default function Home() {
return (
-
-
-
- Background Ralph
-
-
- Autonomous Claude Code agent
-
-
-
-
+ <>
+
+
+
+
+ >
)
}
diff --git a/background-ralph/src/components/mobile-warning.tsx b/background-ralph/src/components/mobile-warning.tsx
new file mode 100644
index 0000000..1b8d3d8
--- /dev/null
+++ b/background-ralph/src/components/mobile-warning.tsx
@@ -0,0 +1,12 @@
+export function MobileWarning() {
+ return (
+
+
+
Desktop required
+
+ Background Ralph needs a larger screen. Please use a desktop browser.
+
+
+
+ )
+}
diff --git a/background-ralph/src/components/ralph-app.tsx b/background-ralph/src/components/ralph-app.tsx
index 44778f5..ef6606f 100644
--- a/background-ralph/src/components/ralph-app.tsx
+++ b/background-ralph/src/components/ralph-app.tsx
@@ -43,88 +43,112 @@ export function RalphApp() {
const isRunning = runState !== null
return (
-
- {/* Form section */}
-
-
-
Start a task
- {isRunning && (
-
- New task
-
- )}
-
-
-