9- **File Browser**: Select specific files to include in the context window for more focused AI assistance
10- **Branch Management**: View, select, and create branches without leaving the app
11- **Cost Tracking**: See estimated API usage costs for each interaction
12- **Sound Notifications**: Get alerted when Claude finishes responding
13- **Mobile-Friendly**: Works on both desktop and mobile devices
14- **Usage Dashboard**: Monitor API usage and inference calls with detailed analytics
1516## How It Works
17181. **Login**: Authenticate with your Val Town API token and Anthropic API key
192. **Select a Project**: Choose which Val Town project you want to work on
203. **Select Files**: Browse your project files and select which ones to include in the context window
26### Prerequisites
2728- A Val Town account with API access
29- An Anthropic API key (Claude 3.7 Sonnet)
3031### Setup
32331. Visit the OpenTownie app
342. Enter your Val Town API token (with `projects:write` and `users:read` permissions)
353. Enter your Anthropic API key
364. Click "Login" to access your projects
3749- React frontend with TypeScript
50- React Router
51- Hono API server backend
52- Web Audio API for sound notifications
53- AI SDK for Claude integration
5455The application proxies requests to the Anthropic API and Val Town API, allowing Claude to view and edit your project files directly.
5657## Privacy & Security
5859- Your Val Town API token and Anthropic API key are stored locally in your browser
60- No data is stored on our servers
61- All communication with the APIs is done directly from your browser
62
1# Usage Dashboard
23A dashboard for monitoring API usage and inference calls.
45## Features
20index.ts # Main entry point and routing
21auth.ts # Authentication logic
22/api/
23index.ts # API request handler
24requests.ts # API endpoints for requests data
25inference-calls.ts # API endpoints for inference calls
26user-summary.ts # API endpoints for user summary data
27/views/
28layout.ts # Common layout template
54- Links back to the associated request
5556### API Endpoints
5758- `/api/requests` - Get paginated requests
59- `/api/requests?usage_id=123` - Get a specific request
60- `/api/inference-calls` - Get paginated inference calls
61- `/api/inference-calls?usage_id=123` - Get inference calls for a specific request
62- `/api/user-summary` - Get user summary data
6364## Debugging
Towniequeries.tsx5 matches
24user_id = ?
25AND timestamp > ?
26AND our_api_token = 1
27`,
28[userId, new Date().getTime() - 24 * 60 * 60 * 1000],
108branch_id,
109model,
110our_api_token,
111num_images,
112}: {
115branch_id: string;
116model: string;
117our_api_token: boolean;
118num_images: number;
119}) {
127branch_id,
128model,
129our_api_token,
130num_images
131) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
138branch_id,
139model,
140our_api_token ? 1 : 0,
141num_images,
142],
TowniePreview.tsx1 match
86value={customPath}
87onChange={handlePathChange}
88placeholder="Path (e.g., /api/data)"
89/>
90</div>
TownieLoginRoute.tsx9 matches
8const { isAuthenticated, authenticate, error } = useAuth();
9const [tokenValue, setTokenValue] = useState("");
10const [apiKey, setApiKey] = useState("");
11// const [invalid, setInvalid] = useState(""); // TODO
1213const handleSubmit = (e) => {
14e.preventDefault();
15authenticate(tokenValue, apiKey);
16};
1732<div>
33<label htmlFor="valtown-token" className="label">
34Val Town API Token
35</label>
36<div style={{ fontSize: "0.8em", color: "#666" }}>
37<p>
38<a
39href="https://www.val.town/settings/api/new"
40target="_blank"
41rel="noreferrer"
60</div>
61<div>
62<label htmlFor="anthropic-api-key" className="label">
63Anthropic API Key (optional)
64</label>
65<input
66type="password"
67id="anthropic-api-key"
68name="anthropic-key"
69value={apiKey}
70onChange={(e) => {
71setApiKey(e.target.value);
72}}
73/>
41);
4243// token middleware for API requests
44app.all("/api/*", async (c, next) => {
45const sessionCookie = getCookie(c, "_session");
46if (!sessionCookie) {
52});
5354app.route("/api", backend);
5556app.get("/frontend/*", (c) => {
1import { basicAuthMiddleware } from "./auth.ts";
2import { handleApiRequest } from "./api/index.ts";
3import { getRequests } from "./api/requests.ts";
4import { getUserSummary } from "./api/user-summary.ts";
5import { getInferenceCalls } from "./api/inference-calls.ts";
6import { renderDashboard } from "./views/dashboard.ts";
7import { renderRequests } from "./views/requests.ts";
22const path = url.pathname;
2324// Handle API requests
25if (path.startsWith("/api/")) {
26return handleApiRequest(req);
27}
28
45/**
6* Handle API requests
7*/
8export async function handleApiRequest(req: Request): Promise<Response> {
9const url = new URL(req.url);
10const path = url.pathname.replace("/api/", "");
11
12try {
13// Route to the appropriate API handler
14if (path === "requests") {
15const usageId = url.searchParams.get("usage_id");
59}
60} catch (error) {
61console.error("API error:", error);
62return new Response(JSON.stringify({ error: error.message }), {
63status: 500,
38<ol>
39<li>
40Login with your Val Town API token (with projects:read,
41projects:write, user:read permissions)
42</li>
77</div>
78<h3>Cost Tracking</h3>
79<p>See estimated API usage costs for each interaction</p>
80</div>
81</section>
86<ul>
87<li>React frontend with TypeScript</li>
88<li>Hono API server backend</li>
89<li>Web Audio API for sound notifications</li>
90<li>AI SDK for Claude integration</li>
91</ul>
92<p>
93The application proxies requests to the Anthropic API and Val Town
94API, allowing Claude to view and edit your project files directly.
95</p>
96<div>
Townie.cursorrules10 matches
13- Generate code in TypeScript or TSX
14- Add appropriate TypeScript types and interfaces for all data structures
15- Prefer official SDKs or libraries than writing API calls directly
16- Ask the user to supply API or library documentation if you are at all unsure about it
17- **Never bake in secrets into the code** - always use environment variables
18- Include comments explaining complex logic (avoid commenting obvious operations)
23### 1. HTTP Trigger
2425- Create web APIs and endpoints
26- Handle HTTP requests and responses
27- Example structure:
173However, it's *extremely importing* to note that `parseProject` and other Standard Library utilities ONLY RUN ON THE SERVER.
174If 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
175or by making an API request for it.
176177## Val Town Platform Specifics
181- **AI Image:** To inline generate an AI image use: `<img src="https://maxm-imggenurl.web.val.run/the-description-of-your-image" />`
182- **Storage:** DO NOT use the Deno KV module for storage
183- **Browser APIs:** DO NOT use the `alert()`, `prompt()`, or `confirm()` methods
184- **Weather Data:** Use open-meteo for weather data (doesn't require API keys) unless otherwise specified
185- **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
186- **Error Debugging:** Add `<script src="https://esm.town/v/std/catch"></script>` to HTML to capture client-side errors
187- **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
188- **Environment Variables:** Use `Deno.env.get('keyname')` when you need to, but generally prefer APIs that don't require keys
189- **Imports:** Use `https://esm.sh` for npm and Deno dependencies to ensure compatibility on server and browser
190- **Storage Strategy:** Only use backend storage if explicitly required; prefer simple static client-side sites
224### Backend (Hono) Best Practices
225226- Hono is the recommended API framework
227- Main entry point should be `backend/index.ts`
228- **Static asset serving:** Use the utility functions to read and serve project files:
248});
249```
250- Create RESTful API routes for CRUD operations
251- Always include this snippet at the top-level Hono app to re-throwing errors to see full stack traces:
252```ts
285- For files in the project, use `readFile` helpers
2862875. **API Design:**
288- `fetch` handler is the entry point for HTTP vals
289- Run the Hono app with `export default app.fetch // This is the entry point for HTTP vals`