Public
Like
48
Townie
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Viewing readonly version of ai-sdk-5 branch: v27View latest version
This is a full-stack application built on the Val Town platform that serves as an AI-powered development assistant for Val Town projects.
Townie helps developers work with Val Town by providing an intelligent assistant interface with chat-based interactions and AI agent capabilities.
This project uses the Val Town CLI for development workflow:
- Push changes:
vt push- Push local changes to Val Town- ⚠️ CRITICAL: NEVER push or watch to main branch without explicit user permission
- Watch for changes:
vt watch- Auto-sync changes with Val Town (includes WebSocket server for companion browser extension)- ⚠️ CRITICAL: NEVER push or watch to main branch without explicit user permission
- Manage branches:
vt branch- List all branchesvt branch -D <name>- Delete a branchvt checkout <branch>- Switch to existing branch
- Pull updates:
vt pull- Pull latest changes from Val Town - Check status:
vt status- Show working tree status - Browse:
vt browse- Open Val's main page in browser
- Testing: Run tests with
await runTests()in backend/database/queries_test.tsx - Linting: The project uses Deno's built-in linter configured in deno.json
- Database: Uses SQLite with schema migrations in backend/database/schema.tsx
backend/main.tsx- Main application entry pointbackend/routes/- API route handlersbackend/database/- Database schema and queries (SQLite)- Authentication via OAuth with Val Town
frontend/- React components and pages- Uses React 18.2.0 (pinned version)
- Custom hooks for API integration
- Local storage for user preferences
*.http.tsx- HTTP endpoint handlers*_test.tsx- Test files*Route.tsx- Route components- Database schema versioning (increment table names vs altering)
The application includes an AI agent system with various tools:
text-editor- File editing capabilitiesfetch- HTTP request handlingthink- Internal reasoningtraces- Execution tracingchange-val-type- Val type modifications
- Runtime: Deno
- Backend: Hono framework
- Frontend: React 18.2.0 (pinned)
- Database: SQLite
- Authentication: OAuth (Val Town)
- Styling: CSS modules and inline styles
- State Management: React hooks and context
- Testing: Custom test runner in queries_test.tsx
- Uses SQLite with custom schema management
- Schema versioning pattern: increment table names (_2, _3) instead of altering schemas
- Query functions organized in backend/database/queries.tsx
- Test suite in backend/database/queries_test.tsx
- React components organized by feature
- Custom hooks for API integration
- Local storage for user preferences
- Custom hooks for API integration
- Ask clarifying questions when requirements are ambiguous
- Provide complete, functional solutions rather than skeleton implementations
- Test your logic against edge cases before presenting the final solution
- Build incrementally and test as you go. Clean up after yourself and don't leave technical debt
- Only code if you're 100% certain - continue asking questions until aligned on what to build
- Generate code in TypeScript or TSX
- Add appropriate TypeScript types and interfaces for all data structures
- Prefer official SDKs or libraries rather than writing API calls directly
- Never bake secrets into code - always use environment variables with
Deno.env.get('keyname') - Include comments explaining complex logic (avoid commenting obvious operations)
- Follow modern ES6+ conventions and functional programming practices
- Read files from base directory
/directly, not/repo/ - Keep README.md up to date whenever making code changes (unless user asks not to)
- Use str_replace in smaller chunks wherever possible
- Directories are created implicitly when creating files within them
- Pin React to 18.2.0: Use
?deps=react@18.2.0,react-dom@18.2.0and include/** @jsxImportSource https://esm.sh/react@18.2.0 */ - Use Val Town utilities: Import from
https://esm.town/v/std/utils/index.tsforreadFile,serveFile, etc. - SQLite schema changes: Change table names (e.g.,
_2,_3) instead of altering schemas - Error handling: Include Hono error unwrapping:
app.onError((err) => Promise.reject(err)) - Static files: Use
serveFile()utility, NEVER use Hono'sserveStaticmiddleware - Imports: Use
https://esm.shfor npm packages to ensure browser/server compatibility
// Blob Storage
import { blob } from "https://esm.town/v/std/blob";
// SQLite
import { sqlite } from "https://esm.town/v/stevekrouse/sqlite";
// OpenAI
import { OpenAI } from "https://esm.town/v/std/openai";
// Email
import { email } from "https://esm.town/v/std/email";
- Redirects: Use
c.redirect()in Hono, ornew Response(null, { status: 302, headers: { Location: "/url" }}) - No binary files: Val Town only supports text files
- No Deno KV: Use SQLite or blob storage instead
- No browser APIs: Don't use
alert(),prompt(), orconfirm() - Error debugging: Add
<script src="https://esm.town/v/std/catch"></script>to HTML - CORS: Val Town automatically handles CORS - don't import cors middleware
- Use
fetchtool to debug HTTP vals by making requests and examining responses - Use
requeststool to debug all kinds of vals - shows logs, headers, status, runtime, errors - Default to smaller changes where possible to minimize code impact