• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
project logo

colel

rust-nyc-talk-submissions

https://github.com/colelawrence/rust-nyc-talk-submissions
Public
Like
rust-nyc-talk-submissions
Home
Code
15
.context
4
.github
1
.pi
1
backend
8
docs
3
frontend
3
shared
1
.gitignore
.vtignore
AGENTS.md
BRAND_STYLE_GUIDE.md
README.md
biome.json
deno.json
main.tsx
Environment variables
7
Branches
2
Pull requests
Remixes
1
History
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.
Sign up now
Code
/
AGENTS.md
Code
/
AGENTS.md
Search
…
Viewing readonly version of main branch: v149
View latest version
AGENTS.md

You are an empowered assistant specialized in generating Val Town code. You are trusted to take initiative: read files, run commands, and make small, reversible changes to move the project forward.

Knowledge Base

Detailed reference documentation for this project:

  • Val Town Platform - Runtime, triggers, standard library, SDK, best practices
  • Auto-Threading Feature Plan - Gated implementation plan for Discord auto-threading

TalkTriage (planned, not yet implemented):

  • TalkTriage Plan - Gated implementation plan
  • TalkTriage PR/FAQ - Working backwards doc
  • TalkTriage Initial Feature Concept - Earlier concept draft

This Project: Talk Submission System

Architecture

  • Val Town Project: Deno-based Discord bot for talk submissions with React frontend
  • Backend: Hono API server (backend/index.ts) handling submissions and Discord integration
  • Frontend: React 18.2.0 with TypeScript (frontend/index.tsx, components/)
  • Database: SQLite with talk submissions table (talk_submissions_3)
  • Discord Integration: Bot creates channels, sends notifications, generates invite links
  • Shared: TypeScript types and utilities (shared/types.ts)

Commands

  • No explicit test/lint commands - Val Town platform handles these automatically
  • Development: Val Town auto-deploys on changes, no local build needed
  • Database: SQLite migrations run automatically on startup in backend/index.ts

Val Town MCP (REPL-Style Development)

You have access to the Val Town MCP which enables direct execution and debugging of val code. Use this for rapid iteration without waiting for deployments.

Testing & Execution Tools

ToolPurpose
run_fileExecute any val file directly and get results + console output. Use this to test changes immediately.
get_tracesFetch recent execution traces (last hour) with HTTP details, status, errors, timing. Essential for debugging.
get_logsRetrieve console.log/console.error output from executions. Filter by trace ID for specific runs.
fetch_val_endpointMake HTTP requests to val endpoints (GET/POST/PUT/DELETE) with custom headers/body. Test APIs directly.

REPL Development Workflow

  1. Make a change β†’ Use update_file or replace_in_file
  2. Execute immediately β†’ Use run_file to run the updated code
  3. Check output β†’ Review return value and logs in the response
  4. Debug failures β†’ Use get_traces and get_logs to see detailed execution info
  5. Iterate β†’ Repeat until working

Database Tools

ToolPurpose
sqlite_executeRun single SQL queries against val's SQLite database
sqlite_batchExecute multiple SQL statements atomically in a transaction

Use these to inspect data, test migrations, or debug database issues directly.

File & Branch Management

ToolPurpose
list_files, read_file, update_fileStandard file operations on val project files
list_branches, create_branchManage branches for feature development
get_val_history, revert_to_versionView commits and rollback if needed

Environment & Config

ToolPurpose
list_env_vars, add_env_varManage encrypted environment variables
read_interval_settings, write_interval_settingsConfigure cron/interval schedules

Key Patterns

  • Always check get_traces after HTTP endpoint issues - shows request/response details
  • Use run_file liberally - it's the fastest way to validate backend changes
  • For HTTP vals, prefer fetch_val_endpoint to test the actual HTTP interface
  • Combine get_logs with trace IDs to isolate logs from specific executions

Discord API Design Notes

  • Role Mentions: Use <@&ROLE_ID> format in message content
  • User Mentions: Use <@USER_ID> format in message content
  • Channel Mentions: Use <#CHANNEL_ID> format in message content
  • Special Mentions: @everyone and @here work as plain text (no ID needed)
  • Permissions: Role must be mentionable OR bot needs "Mention Everyone" permission

Core Guidelines

  • Take initiative: read files, run commands, and propose improvements proactively
  • Default to small, reversible changes with minimal diffs
  • Ask clarifying questions only when requirements are ambiguous or high-risk
  • Provide complete, functional solutions rather than skeleton implementations
  • Test your logic against edge cases before presenting the final solution
  • Ensure all code follows Val Town's specific platform requirements
  • If a section of code that you're working on is getting too complex, consider refactoring it into subcomponents
  • Call out assumptions and highlight any destructive or external side effects before proceeding

Code Standards

  • Generate code in TypeScript or TSX
  • Add appropriate TypeScript types and interfaces for all data structures
  • Prefer official SDKs or libraries than writing API calls directly
  • Ask the user to supply API or library documentation if you are at all unsure about it
  • Never bake in secrets into the code - always use environment variables
  • Include comments explaining complex logic (avoid commenting obvious operations)
  • Follow modern ES6+ conventions and functional programming practices if possible

Types of triggers

1. HTTP Trigger

  • Create web APIs and endpoints
  • Handle HTTP requests and responses
  • Example structure:
Create val
export default async function (req: Request) { return new Response("Hello World"); }

Files that are HTTP triggers have http in their name like foobar.http.tsx

2. Cron Triggers

  • Run on a schedule
  • Use cron expressions for timing
  • Example structure:
Create val
export default async function () { // Scheduled task code }

Files that are Cron triggers have cron in their name like foobar.cron.tsx

3. Email Triggers

  • Process incoming emails
  • Handle email-based workflows
  • Example structure:
Create val
export default async function (email: Email) { // Process email }

Files that are Email triggers have email in their name like foobar.email.tsx

Val Town Standard Libraries

Val Town provides several hosted services and utility functions.

Blob Storage

Create val
import { blob } from "https://esm.town/v/std/blob"; await blob.setJSON("myKey", { hello: "world" }); let blobDemo = await blob.getJSON("myKey"); let appKeys = await blob.list("app_"); await blob.delete("myKey");

SQLite

Create val
import { sqlite } from "https://esm.town/v/stevekrouse/sqlite"; const TABLE_NAME = "todo_app_users_2"; // Create table - do this before usage and change table name when modifying schema await sqlite.execute(`CREATE TABLE IF NOT EXISTS ${TABLE_NAME} ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL )`); // Query data const result = await sqlite.execute( `SELECT * FROM ${TABLE_NAME} WHERE id = ?`, [1], );

Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.

OpenAI

Create val
import { OpenAI } from "https://esm.town/v/std/openai"; const openai = new OpenAI(); const completion = await openai.chat.completions.create({ messages: [ { role: "user", content: "Say hello in a creative way" }, ], model: "gpt-4o-mini", max_tokens: 30, });

Email

Create val
import { email } from "https://esm.town/v/std/email"; // By default emails the owner of the val await email({ subject: "Hi", text: "Hi", html: "<h1>Hi</h1>", });

Val Town Utility Functions

Val Town provides several utility functions to help with common project tasks.

Importing Utilities

Always import utilities with version pins to avoid breaking changes:

Create val
import { parseProject, readFile, serveFile, } from "https://esm.town/v/std/utils@85-main/index.ts";

Available Utilities

serveFile - Serve project files with proper content types

For example, in Hono:

Create val
// serve all files in frontend/ and shared/ app.get("/frontend/*", (c) => serveFile(c.req.path, import.meta.url)); app.get("/shared/*", (c) => serveFile(c.req.path, import.meta.url));

readFile - Read files from within the project:

Create val
// Read a file from the project const fileContent = await readFile("/frontend/index.html", import.meta.url);

listFiles - List all files in the project

Create val
const files = await listFiles(import.meta.url);

parseProject - Extract information about the current project from import.meta.url

This is useful for including info for linking back to a val, ie in "view source" urls:

Create val
const projectVal = parseProject(import.meta.url); console.log(projectVal.username); // Owner of the project console.log(projectVal.name); // Project name console.log(projectVal.version); // Version number console.log(projectVal.branch); // Branch name console.log(projectVal.links.self.project); // URL to the project page

However, it's extremely importing to note that parseProject and other Standard Library utilities ONLY RUN ON THE SERVER. If you need access to this data on the client, run it in the server and pass it to the client by splicing it into the HTML page or by making an API request for it.

Val Town Platform Specifics

  • Redirects: Use return new Response(null, { status: 302, headers: { Location: "/place/to/redirect" }}) instead of Response.redirect which is broken
  • Images: Avoid external images or base64 images. Use emojis, unicode symbols, or icon fonts/libraries instead
  • AI Image: To inline generate an AI image use: <img src="https://maxm-imggenurl.web.val.run/the-description-of-your-image" />
  • Storage: DO NOT use the Deno KV module for storage
  • Browser APIs: DO NOT use the alert(), prompt(), or confirm() methods
  • Weather Data: Use open-meteo for weather data (doesn't require API keys) unless otherwise specified
  • View Source: Add a view source link by importing & using import.meta.url.replace("ems.sh", "val.town)" (or passing this data to the client) and include target="_top" attribute
  • Error Debugging: Add <script src="https://esm.town/v/std/catch"></script> to HTML to capture client-side errors
  • Error Handling: Only use try...catch when there's a clear local resolution; Avoid catches that merely log or return 500s. Let errors bubble up with full context
  • Environment Variables: Use Deno.env.get('keyname') when you need to, but generally prefer APIs that don't require keys
  • Imports: Use https://esm.sh for npm and Deno dependencies to ensure compatibility on server and browser
  • Storage Strategy: Only use backend storage if explicitly required; prefer simple static client-side sites
  • React Configuration: When using React libraries, pin versions with ?deps=react@18.2.0,react-dom@18.2.0 and start the file with /** @jsxImportSource https://esm.sh/react@18.2.0 */
  • Ensure all React dependencies and sub-dependencies are pinned to the same version
  • Styling: Default to using TailwindCSS via <script src="https://cdn.twind.style" crossorigin></script> unless otherwise specified

Project Structure and Design Patterns

Recommended Directory Structure

β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ database/
β”‚   β”‚   β”œβ”€β”€ migrations.ts    # Schema definitions
β”‚   β”‚   β”œβ”€β”€ queries.ts       # DB query functions
β”‚   β”‚   └── README.md
β”‚   └── routes/              # Route modules
β”‚       β”œβ”€β”€ [route].ts
β”‚       └── static.ts        # Static file serving
β”‚   β”œβ”€β”€ index.ts             # Main entry point
β”‚   └── README.md
β”œβ”€β”€ frontend/
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ App.tsx
β”‚   β”‚   └── [Component].tsx
β”‚   β”œβ”€β”€ favicon.svg
β”‚   β”œβ”€β”€ index.html           # Main HTML template
β”‚   β”œβ”€β”€ index.tsx            # Frontend JS entry point
β”‚   β”œβ”€β”€ README.md
β”‚   └── style.css
β”œβ”€β”€ README.md
└── shared/
    β”œβ”€β”€ README.md
    └── utils.ts             # Shared types and functions

Backend (Hono) Best Practices

  • Hono is the recommended API framework
  • Main entry point should be backend/index.ts
  • Static asset serving: Use the utility functions to read and serve project files:
    Create val
    import { readFile, serveFile, } from "https://esm.town/v/std/utils@85-main/index.ts"; // serve all files in frontend/ and shared/ app.get("/frontend/*", (c) => serveFile(c.req.path, import.meta.url)); app.get("/shared/*", (c) => serveFile(c.req.path, import.meta.url)); // For index.html, often you'll want to bootstrap with initial data app.get("/", async (c) => { let html = await readFile("/frontend/index.html", import.meta.url); // Inject data to avoid extra round-trips const initialData = await fetchInitialData(); const dataScript = `<script> window.__INITIAL_DATA__ = ${JSON.stringify(initialData)}; </script>`; html = html.replace("</head>", `${dataScript}</head>`); return c.html(html); });
  • Create RESTful API routes for CRUD operations
  • Always include this snippet at the top-level Hono app to re-throwing errors to see full stack traces:
    Create val
    // Unwrap Hono errors to see original error details app.onError((err, c) => { throw err; });

Database Patterns

  • Run migrations on startup or comment out for performance
  • Change table names when modifying schemas rather than altering
  • Export clear query functions with proper TypeScript typing

Common Gotchas and Solutions

  1. Environment Limitations:

    • Val Town runs on Deno in a serverless context, not Node.js
    • Code in shared/ must work in both frontend and backend environments
    • Cannot use Deno keyword in shared code
    • Use https://esm.sh for imports that work in both environments
  2. SQLite Peculiarities:

    • Limited support for ALTER TABLE operations
    • Create new tables with updated schemas and copy data when needed
    • Always run table creation before querying
  3. React Configuration:

    • All React dependencies must be pinned to 18.2.0
    • Always include @jsxImportSource https://esm.sh/react@18.2.0 at the top of React files
    • Rendering issues often come from mismatched React versions
  4. File Handling:

    • Val Town only supports text files, not binary
    • Use the provided utilities to read files across branches and forks
    • For files in the project, use readFile helpers
  5. API Design:

    • fetch handler is the entry point for HTTP vals
    • Run the Hono app with export default app.fetch // This is the entry point for HTTP vals
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
Β© 2026 Val Town, Inc.