# Project export: Klio

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: OpenAI Build Week
- Tagline: A friendly AI assistant that tracks homeschool progress, gives feedback, and adjusts plans when life happens—so families can focus on learning together.
- Devpost: https://devpost.com/software/klio
- GitHub: https://github.com/btimofeyev/klio
- Demo: https://klio-olive.vercel.app/
- Video: https://www.youtube.com/embed/Gr4YJSg6lsk?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 1 GitHub contributor(s) — Ben Timofeyev (22 commits)

## Devpost submission (written by the team)

### Inspiration

I homeschool, and I have other family members who homeschool as well. A homeschooling parent is not only teaching. They are planning lessons, organizing curriculum, reviewing work, adjusting schedules, tracking progress, saving records, and deciding when a child needs more support. Most homeschool tools help store information, but they still leave the parent responsible for noticing every problem and manually coordinating every change. General-purpose AI chat can offer suggestions, but a parent must still transfer those suggestions into the family’s actual schedule and records. I've been thinking of a tool like Klio for my personal use case and 5.6-Sol was able to get very far with this prototype. I wanted to explore what it would look like if AI could understand the family’s curriculum, schedule, completed work, and learning evidence, and then safely help manage the work rather than simply talk about it.

### What it does

Klio brings a family’s homeschool operation into one connected workspace. Parents can use Klio to: Plan daily, weekly, and monthly schedules Organize courses, curriculum units, and sequenced lessons Coordinate assignments across multiple children Capture student work and supporting evidence Review submissions before they become trusted learning records Identify unfinished work, scheduling conflicts, pacing concerns, and learning gaps Generate focused practice from approved evidence Ask Klio to handle routine planning work in the background Review, approve, reject, or undo changes when appropriate Klio proactively notices issues instead of waiting for the parent to formulate the perfect prompt. For example, it may notice that lessons are out of sequence, several assignments remain unfinished, a day is overloaded, or a student needs more practice with a concept. The parent can choose “Ask Klio to handle this.” Klio then starts a background task directly from that notice. Routine, reversible schedule changes can be completed automatically with an Undo option. More consequential academic or curriculum decisions remain proposals until the parent approves them. The goal is not to replace the parent’s judgment. It is to reduce the coordination burden so the parent can spend more time teaching and supporting their children. How I built it I built Klio as a production-style application rather than a scripted demonstration. The interface uses Next.js and React and includes Today, Week, and Month views. The schedule is connected to curriculum, assignments, evidence, parent reviews, practice activities, and AI-generated notices. Supabase provides authentication, a hosted PostgreSQL database, access controls, and durable storage for families, learners, curriculum, assignments, evidence, reviews, proposals, audit events, and agent activity. The OpenAI-powered agent uses structured turns and bounded tools. When a parent hands Klio a task, the system: Records the request and the authority granted by the parent. Places the work in a durable background queue. Collects the relevant family, curriculum, schedule, and evidence context. Uses the model to determine the smallest useful next action. Calls only the tools permitted for that task. Records progress and tool results. Verifies the resulting application state. Returns a completed action, a reviewable proposal, or one necessary clarification. Because the work is durable, the parent can leave the page and return later without losing the task. Klio restores the task’s progress or completion receipt in the same place where it began. I also designed an autonomy system around the risk and reversibility of each action. Ordinary schedule adjustments can happen immediately and remain undoable. Grades, major curriculum decisions, and other significant academic changes continue to require explicit parental approval. Challenges I faced One of the hardest challenges was turning an AI conversation into dependable action. It is easy for a model to describe a good plan. It is much harder to safely apply that plan to real schedules and records without duplicating lessons, using stale information, or changing something the parent intended to preserve. Another challenge was background execution. Some AI tasks take longer than a normal web request, but the application still needs to feel responsive. I separated the user-facing application from the worker that processes agent tasks. Klio immediately confirms the handoff, displays durable progress, and continues the work independently. I also had to find the right balance between autonomy and parental control. Requiring approval for every minor schedule adjustment makes the agent feel like another inbox. Allowing every change automatically would be inappropriate for an educational system. Klio therefore distinguishes between safe, reversible operational changes and decisions that require human judgment. Keeping the data connected was another major challenge. A schedule change may affect curriculum order, workload, parent availability, evidence, and future recommendations. Stable identifiers, structured relationships, audit records, and post-action verification became essential parts of the system. What I learned AI needs real tools, not just good prompts. The agent became useful when it could safely inspect records, update schedules, create practice, and verify its work. Long-running tasks need durable state. Background work must survive navigation, refreshes, and temporary failures without losing progress. The interface must feel responsive even when the model is still working.*Immediate feedback, visible progress, and persistent results made the agent feel dependable.

## README (from the GitHub repository)

# Klio

Klio is a bounded homeschool operating workspace for parents coordinating multiple learners. It turns everyday handoffs—notes, worksheets, scores, voice updates, unfinished lessons, and curriculum materials—into evidence-backed plans, reviews, practice, and reversible schedule changes without letting an AI silently become the educational authority.

Built for the **Education** track of [OpenAI Build Week](https://openai.devpost.com/).

- Live app: [klio-olive.vercel.app](https://klio-olive.vercel.app)
- Runtime model: [`gpt-5.6-terra`](https://developers.openai.com/api/docs/models/gpt-5.6-terra)
- Stack: Next.js 16, React 19, Supabase, OpenAI Codex SDK, OpenAI Responses API, Vercel Cron
- License: [MIT](./LICENSE)

## The problem

Homeschool planning tools usually track assignments, while general AI assistants produce suggestions. Neither one reliably manages the harder operating problem: a parent is one shared teaching resource across several learners, source work must stay connected to conclusions, grades need review, curriculum order matters, and schedule changes must remain understandable and reversible.

Klio combines those responsibilities in one persistent family workspace. It can do routine follow-through, but every action passes through a narrow domain tool, current family authorization, deterministic policy, and an audit trail.

## What Klio does

- Captures text, photos, PDFs, files, voice notes, explicit scores, books, and activities as preserved evidence.
- Maintains academic terms, learning days, curriculum scope, course order, learner capacity, and parent-attention constraints.
- Uses a persistent conversational agent to file work, organize days, create assignments and reminders, prepare reviews, and generate focused practice.
- Keeps inferred grades, learning interpretations, curriculum-direction changes, and major schedule changes behind parent review.
- Distinguishes provisional written-work feedback from parent-approved learning records.
- Generates structured, answer-safe practice grounded in approved evidence and renders it in a scored learner player.
- Produces weekly briefings, pacing signals, calendar-conflict warnings, and quiet no-op outcomes when nothing needs attention.
- Records undo information for eligible schedule mutations and refuses stale undo operations that would overwrite later work.

## Judge walkthrough

The hosted judge account contains synthetic data only: three learners, four completed weeks, current curriculum and schedule state, evidence history, reviews, attention items, and generated practice.

1. Open [the live app](https://klio-olive.vercel.app) and sign in with `test@klio.com`. The password is supplied in the Devpost testing instructions, never in this repository.
2. On **Home**, inspect the family schedule, weekly briefing, pacing cards, and parent-attention notices.
3. Open **Conversations**, select Jacob, and try:

   > Using Jacob's approved osmosis evidence, create a different six-item Science practice on causal explanations, schedule it for tomorrow, and do not change or invent a grade.

4. Watch the durable receipt move from queued work through evidence reading and practice creation. The Vercel worker runs the turn against hosted Supabase using GPT-5.6 Terra.
5. Open the generated practice to inspect the six-item progression and answer-safe learner view.
6. Open **Attention** to review any draft interpretation. Open the new schedule adjustment to undo it.

The production smoke test exercised the same path: web handoff → durable queue → Codex worker → bounded tools → parent review → generated practice → schedule → successful undo.

## Architecture

```mermaid
flowchart LR
  P[Parent or judge browser] --> W[Next.js web app on Vercel]
  W <--> S[Supabase Auth, Postgres, and Storage]
  W --> Q[Durable agent turn queue]
  Q --> S
  C[Vercel Cron every minute] --> R[Bounded worker batch]
  R <--> S
  R --> X[Codex SDK and GPT-5.6 Terra]
  X <--> M[Klio MCP tool gateway]
  M --> S
```

The web and worker share one codebase but not one request lifecycle. Web requests enqueue durable turns in Supabase. A secured Vercel Cron route claims work fairly across families, renews leases and heartbeats, bounds concurrency and retries, and records progress. The Codex SDK runs with a family-specific workspace and only the Klio MCP tools allowed for that turn.

Structured capture and curriculum-material analysis also use the OpenAI Responses API with Zod-validated outputs. The persistent operating agent uses the Codex SDK with `gpt-5.6-terra` and a signed, expiring capability for the local MCP gateway.

## Bounded authority

Klio's central product decision is that model intelligence and write authority are separate.

- The model receives a current, family-authorized snapshot; stale thread context is supplemental only.
- Capabilities are signed, expiring, turn-bound, requester-bound, family-bound, snapshot-versioned, and limited to named domain tools.
- The agent has no arbitrary SQL, shell, filesystem, browser, generic HTTP, generic record-update, or source-deletion tool.
- Every write revalidates ownership and snapshot state, uses an idempotency key, and records provenance.
- Submitted work and curriculum files are untrusted evidence, never executable instructions.
- Source evidence is preserved. Parent corrections remain available as negative examples rather than being silently overwritten.
- Supabase Row Level Security isolates every family; the browser receives only a publishable key.
- OpenAI, Supabase secret-key, Stripe, and cron credentials stay server-side.

The detailed contract is in [docs/bounded-agent-safety.md](./docs/bounded-agent-safety.md).

## How Codex and GPT-5.6 contributed

### Codex as the build collaborator

Codex accelerated repository exploration, implementation planning, schema and RLS work, Next.js API and UI changes, adversarial test coverage, deployment debugging, and live browser verification. It was especially useful for tracing behaviors across the queue, database policies, runtime tool gateway, receipts, and parent-facing UI instead of treating each layer independently.

The primary Codex `/feedback` Session ID is provided in the Devpost submission form. Dated commits and the submission-readiness plan provide additional evidence of work during the submission period.

### GPT-5.6 in the product

GPT-5.6 Terra interprets parent requests against the authorized family snapshot, chooses among the tools the host permits for that turn, and returns a schema-validated receipt describing what it understood, used, changed, and left for review. It does not receive blanket application authority.

The hosted smoke test used GPT-5.6 Terra to identify a specific osmosis explanation gap without inventing a grade, prepare a parent-reviewable evidence record, generate six grounded practice activities, schedule a follow-up, and then preserve an undo path.

### Key human decisions

| Decision | Why it remained human-owned |
| --- | --- |
| Separate intelligence from authority | A capable model should not imply permission to mutate every family record. |
| Treat the parent as one shared scheduling resource | Student capacity alone cannot prevent overlapping parent-led lessons across siblings. |
| Keep inferred grades and interpretations provisional | Written work and educational judgment require accountable parent review. |
| Prefer deterministic policy for capacity, order, leases, retries, and undo | These invariants must hold even when model output varies. |
| Deploy a real durable worker | The submitted product should behave like the demonstrated product, including background follow-through and recovery. |

## What was built during the submission period

Klio existed before the July 13, 2026 9:00 AM Pacific submission-period start. In accordance with the [official rules](https://openai.devpost.com/rules), only the meaningful extensions added during the submission period are presented as Buil

[README truncated for size]

## Detected evidence (automated analysis)

Indexed codebase: 974 recognized source files, 3747 KB.
- CSS (language) — detected in the code
- Next.js (technology) — detected in the code
- OpenAI (technology) — detected in the code
- React (technology) — detected in the code
- SQL (language) — detected in the code
- Supabase (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- JavaScript (language) — claimed on Devpost, not found in the code
- Node.js (technology) — claimed on Devpost, not found in the code
- Vercel (technology) — claimed on Devpost, not found in the code
- AI coding agent: Claude Code — evidence: config files committed to the repository
- AI coding agent: Codex — evidence: config files committed to the repository

## Codebase structure (from repository index)

### Files (120 of 1266)

```
.env.example
.gitignore
.vercelignore
AGENTS.md
CLAUDE.md
docs/bounded-agent-safety.md
e2e/academic-planning.spec.ts
e2e/autonomous-operations.spec.ts
e2e/calendar-conflicts.spec.ts
e2e/clarification-resume.spec.ts
e2e/first-week.spec.ts
e2e/learner-setup.spec.ts
e2e/open-handoff.spec.ts
e2e/operations.spec.ts
e2e/parent-attention.spec.ts
e2e/practice-overlay.spec.ts
e2e/prototype.spec.ts
e2e/receipt-honesty.spec.ts
e2e/review.spec.ts
e2e/seeded-family-week.spec.ts
e2e/students-records-dashboard.spec.ts
e2e/unfinished-attention.spec.ts
eslint.config.mjs
LICENSE
next.config.ts
package.json
playwright.config.ts
pnpm-workspace.yaml
postcss.config.mjs
proofs/capture-agent-phase0/.gitignore
proofs/capture-agent-phase0/config.toml
proofs/capture-agent-phase0/container/Dockerfile
proofs/capture-agent-phase0/container/entrypoint.sh
proofs/capture-agent-phase0/lib/app-server-client.mjs
proofs/capture-agent-phase0/lib/capability.mjs
proofs/capture-agent-phase0/lib/fixtures.mjs
proofs/capture-agent-phase0/lib/gateway.mjs
proofs/capture-agent-phase0/lib/preflight.mjs
proofs/capture-agent-phase0/lib/tool-definitions.mjs
proofs/capture-agent-phase0/live-proof-report.json
proofs/capture-agent-phase0/phase0-result.json
proofs/capture-agent-phase0/protocol-json/ApplyPatchApprovalParams.json
proofs/capture-agent-phase0/protocol-json/ApplyPatchApprovalResponse.json
proofs/capture-agent-phase0/protocol-json/AttestationGenerateParams.json
proofs/capture-agent-phase0/protocol-json/AttestationGenerateResponse.json
proofs/capture-agent-phase0/protocol-json/ChatgptAuthTokensRefreshParams.json
proofs/capture-agent-phase0/protocol-json/ChatgptAuthTokensRefreshResponse.json
proofs/capture-agent-phase0/protocol-json/ClientNotification.json
proofs/capture-agent-phase0/protocol-json/ClientRequest.json
proofs/capture-agent-phase0/protocol-json/codex_app_server_protocol.schemas.json
proofs/capture-agent-phase0/protocol-json/codex_app_server_protocol.v2.schemas.json
proofs/capture-agent-phase0/protocol-json/CommandExecutionRequestApprovalParams.json
proofs/capture-agent-phase0/protocol-json/CommandExecutionRequestApprovalResponse.json
proofs/capture-agent-phase0/protocol-json/DynamicToolCallParams.json
proofs/capture-agent-phase0/protocol-json/DynamicToolCallResponse.json
proofs/capture-agent-phase0/protocol-json/ExecCommandApprovalParams.json
proofs/capture-agent-phase0/protocol-json/ExecCommandApprovalResponse.json
proofs/capture-agent-phase0/protocol-json/FileChangeRequestApprovalParams.json
proofs/capture-agent-phase0/protocol-json/FileChangeRequestApprovalResponse.json
proofs/capture-agent-phase0/protocol-json/FuzzyFileSearchParams.json
proofs/capture-agent-phase0/protocol-json/FuzzyFileSearchResponse.json
proofs/capture-agent-phase0/protocol-json/FuzzyFileSearchSessionCompletedNotification.json
proofs/capture-agent-phase0/protocol-json/FuzzyFileSearchSessionUpdatedNotification.json
proofs/capture-agent-phase0/protocol-json/JSONRPCError.json
proofs/capture-agent-phase0/protocol-json/JSONRPCErrorError.json
proofs/capture-agent-phase0/protocol-json/JSONRPCMessage.json
proofs/capture-agent-phase0/protocol-json/JSONRPCNotification.json
proofs/capture-agent-phase0/protocol-json/JSONRPCRequest.json
proofs/capture-agent-phase0/protocol-json/JSONRPCResponse.json
proofs/capture-agent-phase0/protocol-json/McpServerElicitationRequestParams.json
proofs/capture-agent-phase0/protocol-json/McpServerElicitationRequestResponse.json
proofs/capture-agent-phase0/protocol-json/PermissionsRequestApprovalParams.json
proofs/capture-agent-phase0/protocol-json/PermissionsRequestApprovalResponse.json
proofs/capture-agent-phase0/protocol-json/RequestId.json
proofs/capture-agent-phase0/protocol-json/ServerNotification.json
proofs/capture-agent-phase0/protocol-json/ServerRequest.json
proofs/capture-agent-phase0/protocol-json/ToolRequestUserInputParams.json
proofs/capture-agent-phase0/protocol-json/ToolRequestUserInputResponse.json
proofs/capture-agent-phase0/protocol-json/v1/InitializeParams.json
proofs/capture-agent-phase0/protocol-json/v1/InitializeResponse.json
proofs/capture-agent-phase0/protocol-json/v2/AccountLoginCompletedNotification.json
proofs/capture-agent-phase0/protocol-json/v2/AccountRateLimitsUpdatedNotification.json
proofs/capture-agent-phase0/protocol-json/v2/AccountUpdatedNotification.json
proofs/capture-agent-phase0/protocol-json/v2/AgentMessageDeltaNotification.json
proofs/capture-agent-phase0/protocol-json/v2/AppListUpdatedNotification.json
proofs/capture-agent-phase0/protocol-json/v2/AppsListParams.json
proofs/capture-agent-phase0/protocol-json/v2/AppsListResponse.json
proofs/capture-agent-phase0/protocol-json/v2/CancelLoginAccountParams.json
proofs/capture-agent-phase0/protocol-json/v2/CancelLoginAccountResponse.json
proofs/capture-agent-phase0/protocol-json/v2/CommandExecOutputDeltaNotification.json
proofs/capture-agent-phase0/protocol-json/v2/CommandExecParams.json
proofs/capture-agent-phase0/protocol-json/v2/CommandExecResizeParams.json
proofs/capture-agent-phase0/protocol-json/v2/CommandExecResizeResponse.json
proofs/capture-agent-phase0/protocol-json/v2/CommandExecResponse.json
proofs/capture-agent-phase0/protocol-json/v2/CommandExecTerminateParams.json
proofs/capture-agent-phase0/protocol-json/v2/CommandExecTerminateResponse.json
proofs/capture-agent-phase0/protocol-json/v2/CommandExecutionOutputDeltaNotification.json
proofs/capture-agent-phase0/protocol-json/v2/CommandExecWriteParams.json
proofs/capture-agent-phase0/protocol-json/v2/CommandExecWriteResponse.json
proofs/capture-agent-phase0/protocol-json/v2/ConfigBatchWriteParams.json
proofs/capture-agent-phase0/protocol-json/v2/ConfigReadParams.json
proofs/capture-agent-phase0/protocol-json/v2/ConfigReadResponse.json
proofs/capture-agent-phase0/protocol-json/v2/ConfigRequirementsReadResponse.json
proofs/capture-agent-phase0/protocol-json/v2/ConfigValueWriteParams.json
proofs/capture-agent-phase0/protocol-json/v2/ConfigWarningNotification.json
proofs/capture-agent-phase0/protocol-json/v2/ConfigWriteResponse.json
proofs/capture-agent-phase0/protocol-json/v2/ConsumeAccountRateLimitResetCreditParams.json
proofs/capture-agent-phase0/protocol-json/v2/ConsumeAccountRateLimitResetCreditResponse.json
proofs/capture-agent-phase0/protocol-json/v2/ContextCompactedNotification.json
proofs/capture-agent-phase0/protocol-json/v2/DeprecationNoticeNotification.json
proofs/capture-agent-phase0/protocol-json/v2/ErrorNotification.json
proofs/capture-agent-phase0/protocol-json/v2/ExperimentalFeatureEnablementSetParams.json
proofs/capture-agent-phase0/protocol-json/v2/ExperimentalFeatureEnablementSetResponse.json
proofs/capture-agent-phase0/protocol-json/v2/ExperimentalFeatureListParams.json
proofs/capture-agent-phase0/protocol-json/v2/ExperimentalFeatureListResponse.json
proofs/capture-agent-phase0/protocol-json/v2/ExternalAgentConfigDetectParams.json
proofs/capture-agent-phase0/protocol-json/v2/ExternalAgentConfigDetectResponse.json
proofs/capture-agent-phase0/protocol-json/v2/ExternalAgentConfigImportCompletedNotification.json
proofs/capture-agent-phase0/protocol-json/v2/ExternalAgentConfigImportHistoriesReadResponse.json
proofs/capture-agent-phase0/protocol-json/v2/ExternalAgentConfigImportParams.json
[1146 more files omitted for size]
```

### Dependencies

- package.json: @hookform/resolvers@^5.4.0, @openai/codex-sdk@0.144.1, @playwright/test@^1.61.1, @supabase/ssr@^0.12.0, @supabase/supabase-js@^2.110.2, @tailwindcss/postcss@^4, @testing-library/jest-dom@^6.9.1, @testing-library/react@^16.3.2, @testing-library/user-event@^14.6.1, @types/node@^20, @types/nspell@^2.1.6, @types/papaparse@^5.5.2, @types/react@^19, @types/react-dom@^19, @vitejs/plugin-react@^6.0.3, class-variance-authority@^0.7.1, clsx@^2.1.1, date-fns@^4.4.0, dictionary-en@^4.0.0, dotenv@^17.4.2, eslint@^9, eslint-config-next@16.2.10, jsdom@^29.1.1, lucide-react@^1.24.0, motion@^12.42.2, music-metadata@^11.14.0, next@16.2.10, nspell@^2.1.5, openai@^6.46.0, papaparse@^5.5.4, react@19.2.4, react-dom@19.2.4, react-hook-form@^7.81.0, react-markdown@^10.1.0, remark-gfm@^4.0.1, server-only@^0.0.1, stripe@^22.3.1, tailwind-merge@^3.6.0, tailwindcss@^4, ts-ebml@^3.0.2, tsx@^4.23.0, typescript@^5, vitest@^4.1.10, zod@^4.4.3

### Recent commits (newest first)

- Restore completed assignment to planned status
- Hide practice-ready insights when practice cards are shown
- Ignore stale inbox conversation refreshes
- Center calendar conflict dialog in viewport
- Accept postgres UUIDs in assignment cursors
- Prevent weekly briefing card flicker
- Make assignment completion feedback immediate
- Restore briefing handoffs after reload
- Persist background briefing receipts on refresh
- Clear verified weekly briefing items
- Apply parent-authorized schedule fixes immediately
- Keep Today anchored to the current date
- Run weekly briefing handoffs in place
- Automatically repair preloaded curriculum sequences
- Cut agent startup latency
- Stream agent responses without cron delay
- Remove internal submission plans
- Complete submission readiness checklist
- Prepare Klio for OpenAI Build Week
- Add date-scoped workspace flows and calendar conflicts

## Key source files (fetched from GitHub, selected and truncated for size)

### CLAUDE.md

```markdown
@AGENTS.md

```

### AGENTS.md

```markdown
<!-- BEGIN:nextjs-agent-rules -->
# This is NOT the Next.js you know

This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
<!-- END:nextjs-agent-rules -->

```

### package.json

```
{
  "name": "klio",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "bash -c 'NODE_OPTIONS=--conditions=react-server tsx scripts/agent-worker.mts & worker=$!; next dev -H 0.0.0.0 -p 3100 & web=$!; trap \"kill $worker $web 2>/dev/null || true\" EXIT INT TERM; wait -n $worker $web'",
    "build": "next build",
    "start": "next start -H 0.0.0.0 -p 3100",
    "lint": "eslint .",
    "typecheck": "tsc --noEmit",
    "test": "vitest run",
    "test:watch": "vitest",
    "test:e2e": "playwright test",
    "test:e2e:web": "KLIO_NEXT_DIST_DIR=.next-e2e next dev -H 127.0.0.1 -p 3101",
    "db:start": "supabase start",
    "db:stop": "supabase stop",
    "db:reset": "supabase db reset --local",
    "db:types": "supabase gen types typescript --local > src/lib/supabase/database.types.ts",
    "agent:worker": "NODE_OPTIONS=--conditions=react-server tsx scripts/agent-worker.mts",
    "stripe:listen": "stripe listen --forward-to localhost:3100/api/stripe/webhook"
  },
  "dependencies": {
    "@hookform/resolvers": "^5.4.0",
    "@openai/codex-sdk": "0.144.1",
    "@supabase/ssr": "^0.12.0",
    "@supabase/supabase-js": "^2.110.2",
    "class-variance-authority": "^0.7.1",
    "clsx": "^2.1.1",
    "date-fns": "^4.4.0",
    "dictionary-en": "^4.0.0",
    "lucide-react": "^1.24.0",
    "motion": "^12.42.2",
    "music-metadata": "^11.14.0",
    "next": "16.2.10",
    "nspell": "^2.1.5",
    "openai": "^6.46.0",
    "papaparse": "^5.5.4",
    "react": "19.2.4",
    "react-dom": "19.2.4",
    "react-hook-form": "^7.81.0",
    "react-markdown": "^10.1.0",
    "remark-gfm": "^4.0.1",
    "server-only": "^0.0.1",
    "stripe": "^22.3.1",
    "tailwind-merge": "^3.6.0",
    "ts-ebml": "^3.0.2",
    "zod": "^4.4.3"
  },
  "devDependencies": {
    "@playwright/test": "^1.61.1",
    "@tailwindcss/postcss": "^4",
    "@testing-library/jest-dom": "^6.9.1",
    "@testing-library/react": "^16.3.2",
    "@testing-library/user-event": "^14.6.1",
    "@types/node": "^20",
    "@types/nspell": "^2.1.6",
    "@types/papaparse": "^5.5.2",
    "@types/react": "^19",
    "@types/react-dom": "^19",
    "@vitejs/plugin-react": "^6.0.3",
    "dotenv": "^17.4.2",
    "eslint": "^9",
    "eslint-config-next": "16.2.10",
    "jsdom": "^29.1.1",
    "tailwindcss": "^4",
    "tsx": "^4.23.0",
    "typescript": "^5",
    "vitest": "^4.1.10"
  }
}

```

### proofs/capture-agent-phase0/container/Dockerfile

```
FROM node:24-bookworm-slim

ARG CODEX_VERSION=0.144.1
RUN apt-get update \
  && apt-get install -y --no-install-recommends bubblewrap ca-certificates iproute2 iptables libcap2-bin \
  && rm -rf /var/lib/apt/lists/* \
  && npm install --global "@openai/codex@${CODEX_VERSION}"

WORKDIR /proof
COPY --chown=node:node . /proof
COPY container/entrypoint.sh /usr/local/bin/klio-phase0-entrypoint
RUN chmod 0755 /usr/local/bin/klio-phase0-entrypoint

ENV HOME=/home/node
ENTRYPOINT ["/usr/local/bin/klio-phase0-entrypoint"]
CMD ["node", "run-live-proof.mjs"]

```

### src/lib/agent/workspace/package.json

```
{
  "type": "module"
}

```

### src/app/layout.tsx

```typescript
import type { Metadata } from "next";
import { DM_Sans, Newsreader } from "next/font/google";
import "./globals.css";
import "./teacher-canvas.css";

const sans = DM_Sans({
  variable: "--font-sans",
  subsets: ["latin"],
});

const serif = Newsreader({
  variable: "--font-serif",
  subsets: ["latin"],
});

export const metadata: Metadata = {
  title: { default: "Klio", template: "%s · Klio" },
  description: "A capture-first homeschool agent workspace for families.",
  applicationName: "Klio",
};

export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
  return (
    <html lang="en" className={`${sans.variable} ${serif.variable}`}>
      <body>{children}</body>
    </html>
  );
}

```

### src/app/page.tsx

```typescript
import Link from "next/link";
import { ArrowRight, BookOpen, Camera, Mic, Sparkles } from "lucide-react";
import { getCurrentParent } from "@/lib/auth/require-parent";
import { redirect } from "next/navigation";
import { KlioWordmark } from "@/components/klio-wordmark";

export default async function HomePage() {
  const parent = await getCurrentParent();
  if (parent) redirect("/app");

  return (
    <main className="landing-shell">
      <nav className="landing-nav">
        <KlioWordmark />
        <Link className="text-link" href="/login">Sign in</Link>
      </nav>

      <section className="landing-hero">
        <div className="hero-copy">
          <p className="eyebrow">A working memory for your homeschool</p>
          <h1>Drop in the day.<br />Klio carries it forward.</h1>
          <p className="hero-lede">
            Notes, worksheets, voice clips, and grades become useful plans,
            lessons, and learning records—with you in control.
          </p>
          <Link className="primary-button" href="/login?mode=signup">
            Start your family workspace <ArrowRight size={17} />
          </Link>
        </div>

        <div className="hero-capture" aria-label="Example Klio capture surface">
          <div className="capture-paper">
            <div className="capture-line" />
            <p>We finished chapter four of The Wild Robot. Nora wondered why Roz chose to stay...</p>
            <div className="capture-tools">
              <span><Camera size={16} /> Photo</span>
              <span><Mic size={16} /> Voice</span>
              <span><BookOpen size={16} /> File</span>
              <span className="capture-send"><Sparkles size={15} /> Add to Klio</span>
            </div>
          </div>
          <div className="paper-shadow shadow-one" />
          <div className="paper-shadow shadow-two" />
        </div>
      </section>

      <section className="landing-proof">
        <p>One quiet place for the fragments that make up a real education.</p>
        <div className="proof-flow">
          <span>Capture</span><i />
          <span>Understand</span><i />
          <span>Create</span><i />
          <span>Approve</span>
        </div>
      </section>
    </main>
  );
}

```

### src/app/login/page.tsx

```typescript
import type { Metadata } from "next";
import { KlioWordmark } from "@/components/klio-wordmark";
import { AuthForm } from "./auth-form";

export const metadata: Metadata = { title: "Sign in" };

export default async function LoginPage({
  searchParams,
}: {
  searchParams: Promise<{ mode?: string }>;
}) {
  const mode = (await searchParams).mode === "signup" ? "signup" : "signin";

  return (
    <main className="auth-shell">
      <aside className="auth-aside">
        <KlioWordmark />
        <p className="auth-quote">The day is full of learning. Keep what matters.</p>
        <small>Private by default · Parent controlled</small>
      </aside>
      <section className="auth-main"><AuthForm mode={mode} /></section>
    </main>
  );
}

```

### src/lib/supabase/server.ts

```typescript
import "server-only";

import { createServerClient } from "@supabase/ssr";
import { cookies } from "next/headers";
import { serverEnv } from "@/lib/env";
import type { Database } from "./database.types";

export async function createClient() {
  const cookieStore = await cookies();

  return createServerClient<Database>(
    serverEnv.supabaseUrl,
    serverEnv.supabasePublishableKey,
    {
      cookies: {
        getAll: () => cookieStore.getAll(),
        setAll: (cookiesToSet) => {
          try {
            cookiesToSet.forEach(({ name, value, options }) =>
              cookieStore.set(name, value, options),
            );
          } catch {
            // Server Components cannot set cookies. src/proxy.ts refreshes them.
          }
        },
      },
    },
  );
}

```

### src/app/onboarding/page.tsx

```typescript
import { redirect } from "next/navigation";
import { KlioWordmark } from "@/components/klio-wordmark";
import { requireParent } from "@/lib/auth/require-parent";
import { createClient } from "@/lib/supabase/server";
import { OnboardingForm } from "./onboarding-form";
import { signOutAction } from "@/app/login/actions";

export default async function OnboardingPage() {
  const parent = await requireParent();
  const supabase = await createClient();
  const { data } = await supabase.from("family_members").select("family_id").eq("user_id", parent.id).limit(1).maybeSingle();
  if (data) redirect("/app");

  return <main className="onboarding-shell">
    <header className="onboarding-topbar">
      <KlioWordmark />
      <form action={signOutAction}><button type="submit">Sign out</button></form>
    </header>
    <OnboardingForm />
  </main>;
}

```

[956 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]