From 5d44457918aa16211069b0b0051e86bc60294963 Mon Sep 17 00:00:00 2001 From: Pete Millspaugh Date: Wed, 1 Jul 2026 15:05:50 -0400 Subject: [PATCH 1/3] note what data travels when transferring vals between orgs --- plugin/skills/blob-storage/SKILL.md | 23 +++++++++-- plugin/skills/http-endpoints/SKILL.md | 22 ++++++++++- plugin/skills/sqlite-storage/SKILL.md | 9 ++++- .../skills/third-party-integrations/SKILL.md | 39 ++++++++++++++++++- 4 files changed, 86 insertions(+), 7 deletions(-) diff --git a/plugin/skills/blob-storage/SKILL.md b/plugin/skills/blob-storage/SKILL.md index 05e5e73..cbd7cf4 100644 --- a/plugin/skills/blob-storage/SKILL.md +++ b/plugin/skills/blob-storage/SKILL.md @@ -1,7 +1,21 @@ --- name: blob-storage description: Use when a val needs simple key/value persistence — JSON documents, cached responses, uploaded files, or binary assets. Covers the std/blob API, listing and deleting keys, account-global or val scoping, and storage limits. -triggers: [blob, storage, kv, key-value, persistence, cache, store, upload, file, json, asset, binary] +triggers: + [ + blob, + storage, + kv, + key-value, + persistence, + cache, + store, + upload, + file, + json, + asset, + binary, + ] --- # Blob Storage @@ -81,12 +95,11 @@ for (const { key } of entries) { } await blob.copy("config", "config.bak"); // duplicate under a new key -await blob.move("draft", "published"); // rename / relocate +await blob.move("draft", "published"); // rename / relocate ``` `list(prefix?)` returns an array of `{ key: string; size: number; lastModified: string }` — objects, not bare key strings. - ## Limits - **Key length:** up to 512 characters. @@ -103,6 +116,10 @@ When using the `storeBlob`, `readBlob`, `listBlobs`, or `deleteBlob` tools again - `getJSON` returns `undefined` for missing keys; `get` throws `ValTownBlobNotFoundError`. Handle the absent case accordingly. - Don't store secrets in blobs — use environment variables for credentials. +## Transfer between orgs + +Blob storage scoped to a val will automatically transfer when transferring the val to a different org. + ## Reference Full API docs: https://docs.val.town/std/blob/ diff --git a/plugin/skills/http-endpoints/SKILL.md b/plugin/skills/http-endpoints/SKILL.md index 1604503..7df799c 100644 --- a/plugin/skills/http-endpoints/SKILL.md +++ b/plugin/skills/http-endpoints/SKILL.md @@ -1,7 +1,21 @@ --- name: http-endpoints description: Use when building an HTTP val — a web endpoint, API route, webhook receiver, or any val that responds to HTTP requests. Covers the handler signature, Hono usage, the endpoint URL, CORS behavior, redirects, and Val Town-specific limitations. -triggers: [http, endpoint, webhook, api, request, response, hono, web, route, fetch, cors, redirect] +triggers: + [ + http, + endpoint, + webhook, + api, + request, + response, + hono, + web, + route, + fetch, + cors, + redirect, + ] --- # HTTP Endpoints @@ -47,7 +61,7 @@ Hono's `serveStatic` does **not** work on Val Town. Use `serveFile` / `staticHTT ## CORS -Val Town adds permissive CORS headers by default (`Access-Control-Allow-Origin: *`), so in 99% of cases, you should never need to do anything with CORS. Using Hono's `cors` middleware is almost always unnecessary. +Val Town adds permissive CORS headers by default (`Access-Control-Allow-Origin: *`), so in 99% of cases, you should never need to do anything with CORS. Using Hono's `cors` middleware is almost always unnecessary. If you set **any** CORS header yourself, Val Town stops adding **all** default headers — so either handle CORS completely yourself or don't touch it at all. @@ -77,3 +91,7 @@ For HTML responses, add this script tag to send browser errors back to val logs ## Verifying changes After editing an HTTP val, fetch it to confirm it returns the expected HTTP response. Do not report a change as done without this step. + +## Transfer between orgs + +HTTP endpoints will continue working/unchanged when transferring a val to a different org. diff --git a/plugin/skills/sqlite-storage/SKILL.md b/plugin/skills/sqlite-storage/SKILL.md index 1b457cf..d495ba8 100644 --- a/plugin/skills/sqlite-storage/SKILL.md +++ b/plugin/skills/sqlite-storage/SKILL.md @@ -34,7 +34,10 @@ Use `sqlite.batch` for atomic multi-statement transactions — all succeed or al ```ts await sqlite.batch([ - { sql: "INSERT INTO users (name, email) VALUES (?, ?)", args: ["Bob", "bob@example.com"] }, + { + sql: "INSERT INTO users (name, email) VALUES (?, ?)", + args: ["Bob", "bob@example.com"], + }, { sql: "UPDATE users SET name = ? WHERE id = ?", args: ["Robert", 2] }, ]); ``` @@ -58,6 +61,10 @@ When using the `sqlite_execute` or `sqlite_batch` tools to query a val owned by - Use `CREATE TABLE IF NOT EXISTS` so schema setup is idempotent across val restarts. - Schema migrations: add new columns with `ALTER TABLE ... ADD COLUMN`. Wrap in `try/catch` if the migration may run against an already-updated table. +## Transfer between orgs + +SQLite data scoped to a val will automatically transfer when transferring the val to a different org. + ## Reference Full API docs: https://docs.val.town/reference/std/sqlite/usage/ diff --git a/plugin/skills/third-party-integrations/SKILL.md b/plugin/skills/third-party-integrations/SKILL.md index 7cae461..5aef3e4 100644 --- a/plugin/skills/third-party-integrations/SKILL.md +++ b/plugin/skills/third-party-integrations/SKILL.md @@ -1,7 +1,40 @@ --- name: third-party-integrations description: Use when a val talks to an external service — Slack, Discord, Telegram, Stripe, GitHub, Gmail, Google Sheets, Postgres/Supabase/Upstash/Neon, browser automation (Playwright, Browserbase, Kernel, Steel), web scraping, PDF generation, push notifications, RSS, or any other third-party API. Covers the required workflow (fetch the Val Town guide, get credentials, test, store secrets) and the catalog of available guides. -triggers: [integration, third-party, external, service, api, slack, discord, telegram, stripe, github, gmail, sheets, google, neon, postgres, supabase, upstash, database, playwright, browser, browserbase, kernel, steel, browserless, scraping, scrape, pdf, rss, push, notification, webhook] +triggers: + [ + integration, + third-party, + external, + service, + api, + slack, + discord, + telegram, + stripe, + github, + gmail, + sheets, + google, + neon, + postgres, + supabase, + upstash, + database, + playwright, + browser, + browserbase, + kernel, + steel, + browserless, + scraping, + scrape, + pdf, + rss, + push, + notification, + webhook, + ] --- # Third-Party Integrations @@ -33,3 +66,7 @@ Services with dedicated guides today — not exhaustive, so use the sitemap from ## Why this matters Integration code is the most common place models hallucinate. APIs change, auth flows get reworked, and platform constraints (no filesystem, no subprocess) break naive approaches. The Val Town guide is the source of truth for what currently works on the platform. + +## Transferring secrets between orgs + +Note that environment variables scoped to a val will automatically transfer when transferring the val to a different org. Environment groups will _not_ transfer, nor will (deprecated) account-based environment variables. From b7de4833f4168f224220d41db02b0e6d8fd769ba Mon Sep 17 00:00:00 2001 From: Pete Millspaugh Date: Wed, 1 Jul 2026 15:08:40 -0400 Subject: [PATCH 2/3] generate changeset --- .changeset/tender-memes-burn.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/tender-memes-burn.md diff --git a/.changeset/tender-memes-burn.md b/.changeset/tender-memes-burn.md new file mode 100644 index 0000000..bd5cce9 --- /dev/null +++ b/.changeset/tender-memes-burn.md @@ -0,0 +1,5 @@ +--- +"@valtown/skills": minor +--- + +New skill for creating custom user skills; information on transferring vals between orgs From 27a555825e1f4d87f043656730e59ac593a862d9 Mon Sep 17 00:00:00 2001 From: Pete Millspaugh Date: Wed, 1 Jul 2026 15:12:04 -0400 Subject: [PATCH 3/3] undo formatting changes --- plugin/skills/blob-storage/SKILL.md | 19 ++-------- plugin/skills/http-endpoints/SKILL.md | 18 ++-------- plugin/skills/sqlite-storage/SKILL.md | 5 +-- .../skills/third-party-integrations/SKILL.md | 35 +------------------ 4 files changed, 7 insertions(+), 70 deletions(-) diff --git a/plugin/skills/blob-storage/SKILL.md b/plugin/skills/blob-storage/SKILL.md index cbd7cf4..67d2746 100644 --- a/plugin/skills/blob-storage/SKILL.md +++ b/plugin/skills/blob-storage/SKILL.md @@ -1,21 +1,7 @@ --- name: blob-storage description: Use when a val needs simple key/value persistence — JSON documents, cached responses, uploaded files, or binary assets. Covers the std/blob API, listing and deleting keys, account-global or val scoping, and storage limits. -triggers: - [ - blob, - storage, - kv, - key-value, - persistence, - cache, - store, - upload, - file, - json, - asset, - binary, - ] +triggers: [blob, storage, kv, key-value, persistence, cache, store, upload, file, json, asset, binary] --- # Blob Storage @@ -95,11 +81,12 @@ for (const { key } of entries) { } await blob.copy("config", "config.bak"); // duplicate under a new key -await blob.move("draft", "published"); // rename / relocate +await blob.move("draft", "published"); // rename / relocate ``` `list(prefix?)` returns an array of `{ key: string; size: number; lastModified: string }` — objects, not bare key strings. + ## Limits - **Key length:** up to 512 characters. diff --git a/plugin/skills/http-endpoints/SKILL.md b/plugin/skills/http-endpoints/SKILL.md index 7df799c..017171d 100644 --- a/plugin/skills/http-endpoints/SKILL.md +++ b/plugin/skills/http-endpoints/SKILL.md @@ -1,21 +1,7 @@ --- name: http-endpoints description: Use when building an HTTP val — a web endpoint, API route, webhook receiver, or any val that responds to HTTP requests. Covers the handler signature, Hono usage, the endpoint URL, CORS behavior, redirects, and Val Town-specific limitations. -triggers: - [ - http, - endpoint, - webhook, - api, - request, - response, - hono, - web, - route, - fetch, - cors, - redirect, - ] +triggers: [http, endpoint, webhook, api, request, response, hono, web, route, fetch, cors, redirect] --- # HTTP Endpoints @@ -61,7 +47,7 @@ Hono's `serveStatic` does **not** work on Val Town. Use `serveFile` / `staticHTT ## CORS -Val Town adds permissive CORS headers by default (`Access-Control-Allow-Origin: *`), so in 99% of cases, you should never need to do anything with CORS. Using Hono's `cors` middleware is almost always unnecessary. +Val Town adds permissive CORS headers by default (`Access-Control-Allow-Origin: *`), so in 99% of cases, you should never need to do anything with CORS. Using Hono's `cors` middleware is almost always unnecessary. If you set **any** CORS header yourself, Val Town stops adding **all** default headers — so either handle CORS completely yourself or don't touch it at all. diff --git a/plugin/skills/sqlite-storage/SKILL.md b/plugin/skills/sqlite-storage/SKILL.md index d495ba8..a7615f1 100644 --- a/plugin/skills/sqlite-storage/SKILL.md +++ b/plugin/skills/sqlite-storage/SKILL.md @@ -34,10 +34,7 @@ Use `sqlite.batch` for atomic multi-statement transactions — all succeed or al ```ts await sqlite.batch([ - { - sql: "INSERT INTO users (name, email) VALUES (?, ?)", - args: ["Bob", "bob@example.com"], - }, + { sql: "INSERT INTO users (name, email) VALUES (?, ?)", args: ["Bob", "bob@example.com"] }, { sql: "UPDATE users SET name = ? WHERE id = ?", args: ["Robert", 2] }, ]); ``` diff --git a/plugin/skills/third-party-integrations/SKILL.md b/plugin/skills/third-party-integrations/SKILL.md index 5aef3e4..8ad10ba 100644 --- a/plugin/skills/third-party-integrations/SKILL.md +++ b/plugin/skills/third-party-integrations/SKILL.md @@ -1,40 +1,7 @@ --- name: third-party-integrations description: Use when a val talks to an external service — Slack, Discord, Telegram, Stripe, GitHub, Gmail, Google Sheets, Postgres/Supabase/Upstash/Neon, browser automation (Playwright, Browserbase, Kernel, Steel), web scraping, PDF generation, push notifications, RSS, or any other third-party API. Covers the required workflow (fetch the Val Town guide, get credentials, test, store secrets) and the catalog of available guides. -triggers: - [ - integration, - third-party, - external, - service, - api, - slack, - discord, - telegram, - stripe, - github, - gmail, - sheets, - google, - neon, - postgres, - supabase, - upstash, - database, - playwright, - browser, - browserbase, - kernel, - steel, - browserless, - scraping, - scrape, - pdf, - rss, - push, - notification, - webhook, - ] +triggers: [integration, third-party, external, service, api, slack, discord, telegram, stripe, github, gmail, sheets, google, neon, postgres, supabase, upstash, database, playwright, browser, browserbase, kernel, steel, browserless, scraping, scrape, pdf, rss, push, notification, webhook] --- # Third-Party Integrations