Not in the top 1,000 by GitHub stars
homespunapps/homespun
Homespun: apps your AI builds and hosts. Client CLI, MCP server, SDK core, agent skill and Claude plugin. MIT.
History
Review weekly changes to SKILL.md before updating. Dates mark the weeks in which we observed each version; checks apply to the recorded commits.
View weekly changes
skills/homespun/SKILL.md
Week of Nov 2, 2026 · +0 / −0 lines
Before Network or broad shell → After Network or broad shell
7044711ad213 → 7044711ad213
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Network or broad shell
First observation → 7044711ad213
No earlier version was observed for comparison.
Verified commit 7044711ad213e83ead58f313d764dabd7f883ac0
git clone --filter=blob:none --no-checkout https://github.com/homespunapps/homespun.git .hotskills/homespunapps-homespun && git -C .hotskills/homespunapps-homespun checkout --detach 7044711ad213e83ead58f313d764dabd7f883ac0
# Copy each selected skill directory from .hotskills/homespunapps-homespun into .claude/skills/<skill-name>/Heat
1.4- Star growth, last 7 daysNot available
- Star growth, last 24 hoursNot available
- Rank movement, last 7 daysNot available
- Commits, last 30 daysNot available
- Accounts asking about it through MCP, last 7 daysNot available
- Hot votes this weekNot available
Heat never changes the order by stars, and sponsorship never touches it. How heat works
Stars over time
30-day change not yet available: not enough history.
Individual skills in this repository
- homespun
skills/homespun
How it works
homespun
When your agent uses it
Deploy a real multi-user web app from this conversation, then keep operating it. You author an HTML page plus a manifest; `homespun deploy` puts it live on its own URL with magic-link sign-in, a shared realtime database, per-role read/write/delete permissions, email notifications and file uploads. Owners invite other people, who sign in and use it together. You keep read and write access to the app's data and its change feed afterwards, so you can query it, write to it, watch it and redeploy it in later conversations. Use when the work deserves a persistent app people can return to and share, rather than a reply. Drives the `homespun` CLI: deploy, read/write data, watch for changes.
What it loads into context
Frontmatter
173 tokensAlways available to the agent
SKILL.md
41,628 tokensWhen the skill is activated
Reference documents
101,850 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- When to use this
- Choosing how to invoke Homespun
- Setup
- The data model: collections and the change feed
- Keeping this skill up to date
- Discover the CLI with `--help`
- Authoring an app: the manifest
- Writing the HTML: `window.homespun`
- Serving and security: what an app's origin can and can't do
- Deploying and iterating
- Reading and writing data as the agent
- Common gotchas (before you ship)
- Reporting a problem with homespun itself
Files
../../.claude-plugin/marketplace.jsonasset623 bytes../../plugins/homespun/.claude-plugin/plugin.jsonasset664 bytes../../plugins/homespun/skills/homespun/MCP-INVOCATION.mddoc10,369 bytes../../plugins/homespun/skills/homespun/SKILL.mddoc166,596 bytes../../plugins/homespun/skills/homespun/references/agent-tasks.mddoc15,490 bytes../../plugins/homespun/skills/homespun/references/assets.mddoc7,928 bytes../../plugins/homespun/skills/homespun/references/attachments.mddoc13,184 bytes../../plugins/homespun/skills/homespun/references/community-templates.mddoc6,615 bytes../../plugins/homespun/skills/homespun/references/embedding.mddoc4,830 bytes../../plugins/homespun/skills/homespun/references/ingest.mddoc12,450 bytes../../plugins/homespun/skills/homespun/references/notify-targets.mddoc16,465 bytes../../plugins/homespun/skills/homespun/references/registering.mddoc5,836 bytes../../plugins/homespun/skills/homespun/references/webhooks.mddoc26,635 bytesMCP-INVOCATION.mddoc10,369 bytesSKILL.mdcore166,596 bytesSKILL.mdcore166,596 bytesSKILL.mdcore166,596 bytesSKILL.mdcore166,596 bytesSKILL.mdcore166,596 bytesSKILL.mdcore166,596 bytesSKILL.mdcore166,596 bytesSKILL.mdcore166,596 bytesSKILL.mdcore166,596 bytesSKILL.mdcore166,596 bytesSKILL.mdcore166,596 bytesSKILL.mdcore166,596 bytesSKILL.mdcore166,596 bytesSKILL.mdcore166,596 bytesSKILL.mdcore166,596 bytesSKILL.mdcore166,596 bytesSKILL.mdcore166,596 bytesSKILL.mdcore166,596 bytesreferences/agent-tasks.mddoc15,490 bytesreferences/assets.mddoc7,928 bytesreferences/attachments.mddoc13,184 bytesreferences/community-templates.mddoc6,615 bytesreferences/embedding.mddoc4,830 bytesreferences/ingest.mddoc12,450 bytesreferences/notify-targets.mddoc16,465 bytesreferences/registering.mddoc5,836 bytesreferences/webhooks.mddoc26,635 bytes
Read SKILL.md
<!-- homespun skill v1.6.99 -->
# homespun
`homespun` deploys real web apps for you and keeps you connected to them. You
author an HTML page plus a manifest (what data it stores, who may read and write
each part of it), `homespun deploy` puts it live on its own URL, and the relay
supplies the parts you would otherwise have to build: sign-in, a shared database
with a live change feed, per-role permissions, email notifications and file
uploads. The owner invites whoever should have access, and they use it together.
You stay a first-class participant afterwards. Through the exact same collection
API the page itself uses, you can read the app's data, write to it, watch its
feed, and redeploy a new version to the same URL in a later conversation. The appView the complete source on GitHubSkills included
- homespun
Repository facts
- License
- MIT
- Created
- Jul 22, 2026
- Last pushed
- Oct 20, 2026
- Forks
- 0
- Open issues
- 0
- Project activity
- Active
Before you install
Network or broad shellAutomated signals, not a guarantee
Checked Nov 6, 2026
Not fully analyzed: some files were too long, unreadable or missing. This never lowers the level.
Show 17 notes
skills/homespun/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/homespun/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/homespun/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/homespun/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/homespun/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/homespun/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/homespun/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/homespun/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/homespun/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/homespun/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/homespun/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/homespun/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/homespun/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/homespun/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/homespun/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/homespun/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/homespun/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzed
- No broad tool permissions
- No dangerous shell commands
- 153 network referencesin 12 files: plugins/homespun/skills/homespun/SKILL.md:78 homespun/SKILL.md:78 plugins/homespun/skills/homespun/references/webhooks.md:19 and 9 more
- No hidden or obfuscated text
- No instruction overrides
- No executable scripts
- 8 references to secretsin 2 files: plugins/homespun/skills/homespun/SKILL.md:82 homespun/SKILL.md:82
- No requests to vote in Hot
Show all 161 signals by file
.claude-plugin/marketplace.json
plugins/homespun/.claude-plugin/plugin.json
- Network accessline 5
"author": { "name": "aerolalit", "url": "https://github.com/aerolalit" - Network accessline 6
"name": "aerolalit", "url": "https://github.com/aerolalit" }, - Network accessline 7
"url": "https://github.com/aerolalit" - Network accessline 8
}, "homepage": "https://homespun.dev", "repository": "https://github.com/homespunapps/homespun", - Network accessline 9
"homepage": "https://homespun.dev", - Network accessline 10
"repository": "https://github.com/homespunapps/homespun",
plugins/homespun/skills/homespun/SKILL.md
- Network accessline 78
The hosted relay (`https://homespun.dev`) is the default: `homespun agent register` - Access to secretsline 82
[Credential-related source omitted] - Access to secretsline 84
[Credential-related source omitted] - Network accessline 620
{ "$schema": "https://json-schema.org/draft/2020-12/schema", - Network accessline 621
"$schema": "https://json-schema.org/draft/2020-12/schema", - Network accessline 659
} }, "externalHosts": ["https://api.example.com"], - Network accessline 660
}, "externalHosts": ["https://api.example.com"], "cdn": false - Network accessline 661
"externalHosts": ["https://api.example.com"], - Network accessline 722
no effect on `link`/`private` apps: their visibility is the access control and they are never indexable. - **`ogImage`**: an `https://` URL (≤2048 chars) used as the share-preview - Network accessline 723
control and they are never indexable. - **`ogImage`**: an `https://` URL (≤2048 chars) used as the share-preview image (`og:image`/`twitter:image`) instead of the generated card. The - Network accessline 724
- **`ogImage`**: an `https://` URL (≤2048 chars) used as the share-preview - Network accessline 995
rather than a flood of deletes. The author default, the owner's runtime override, and the full mechanics live at https://docs.homespun.dev/agents/collection-retention/; this is only the - Network accessline 996
override, and the full mechanics live at https://docs.homespun.dev/agents/collection-retention/; this is only the manifest shape. - Network accessline 997
https://docs.homespun.dev/agents/collection-retention/; this is only the - Network accessline 1096
- **`x-homespun-manifest.externalHosts`**: an array of `https://` origins (DNS name, optional single leftmost `*.` wildcard, no path/query/IP literal) the page's `fetch`/`XMLHttpRequest` is allowed to reach. This is - Network accessline 1101
- **`x-homespun-manifest.cdn`**: boolean, default `false`. Set `true` to allow `<script src>`/`<link rel=stylesheet>` from any `https:` origin (a CDN). It does **not** widen what the page can `fetch()`; that's `externalHosts` - Network accessline 1102
`<script src>`/`<link rel=stylesheet>` from any `https:` origin (a CDN). It does **not** widen what the page can `fetch()`; that's `externalHosts` only, kept separate on purpose so a page can load, say, a charting library - Network accessline 1103
It does **not** widen what the page can `fetch()`; that's `externalHosts` - Network accessline 1195
origin, not by these grants, so declaring them does not enable those buttons on a third-party embed (see `embeds` below). - **`x-homespun-manifest.embeds`**: optional array of `https://` origins - Network accessline 1196
on a third-party embed (see `embeds` below). - **`x-homespun-manifest.embeds`**: optional array of `https://` origins (same rules as `externalHosts`: DNS name, optional single leftmost `*.` - Network accessline 1197
- **`x-homespun-manifest.embeds`**: optional array of `https://` origins - Network accessline 1201
`connect-src` or `form-action`, so framing a site never lets the page send data to it. For a YouTube player use the privacy-preserving nocookie host: `"embeds": ["https://www.youtube-nocookie.com"]`. Declaring a non-empty - Network accessline 1202
data to it. For a YouTube player use the privacy-preserving nocookie host: `"embeds": ["https://www.youtube-nocookie.com"]`. Declaring a non-empty `embeds` list also relaxes the document's `Referrer-Policy` from `no-referrer` - Network accessline 1203
`"embeds": ["https://www.youtube-nocookie.com"]`. Declaring a non-empty - Network accessline 1215
<!-- manifest: {"x-homespun-manifest":{"embeds":["https://www.youtube-nocookie.com"]}} --> - Network accessline 1216
<iframe src="https://www.youtube-nocookie.com/embed/VIDEO_ID?rel=0" title="Video" - Network accessline 1217
src="https://www.youtube-nocookie.com/embed/VIDEO_ID?rel=0" - Network accessline 1238
The origin grammar is stricter than `embeds`: **exact origins only, no wildcard, ever.** `https://your-form-partner.example` is accepted; - Network accessline 1239
wildcard, ever.** `https://your-form-partner.example` is accepted; - Network accessline 1240
`https://*.example.com` is refused with a clear error, unlike `embeds` - Network accessline 1241
which does allow a single leftmost `*.`. The one exception is local development: `http://localhost:PORT` and `http://127.0.0.1:PORT` are accepted over plain `http`, and no other host may use `http`. - Network accessline 1242
development: `http://localhost:PORT` and `http://127.0.0.1:PORT` are - Network accessline 1243
accepted over plain `http`, and no other host may use `http`. `"embedAncestors": ["https://www.example-partner-site.com"]` is the whole declaration; no path, query, or userinfo is allowed. - Network accessline 1244
`"embedAncestors": ["https://www.example-partner-site.com"]` is the whole - Network accessline 1293
```html <script src="https://<main-domain>/embed.js" data-app="https://your-app.<usercontent-domain>/" - Network accessline 1294
<script src="https://<main-domain>/embed.js" data-app="https://your-app.<usercontent-domain>/" data-height="600" - Network accessline 1295
data-app="https://your-app.<usercontent-domain>/" - Network accessline 2343
body.append("file", file); // the field name is exactly "file" body.append("filename", file.name); // optional, display only const res = await fetch("/_hs/attachments?collection=photos", { method: "POST", body }); - Network accessline 2344
body.append("filename", file.name); // optional, display only const res = await fetch("/_hs/attachments?collection=photos", { method: "POST", body }); const ref = await res.json(); // 201 { attachment_id, mime, size, filename } - Network accessline 2345
const res = await fetch("/_hs/attachments?collection=photos", { method: "POST", body }); - Access to secretsline 2714
[Credential-related source omitted] - Access to secretsline 2715
[Credential-related source omitted]
plugins/homespun/skills/homespun/references/agent-tasks.md
- Network accessline 256
"writes": ["line_items"], "lease_expires_at": "2026-08-08T12:00:00.000Z", "api_base": "https://homespun.dev", - Network accessline 257
"lease_expires_at": "2026-08-08T12:00:00.000Z", "api_base": "https://homespun.dev", "credential": "hsc_..." - Network accessline 258
"api_base": "https://homespun.dev",
plugins/homespun/skills/homespun/references/attachments.md
- Network accessline 92
`{ put_url, attachment_id }`. 2. **PUT the bytes**: do an HTTP `PUT put_url` with the raw file bytes as the body (a plain `curl -T file "$put_url"` or `fetch(put_url, { method: 'PUT', - Network accessline 93
2. **PUT the bytes**: do an HTTP `PUT put_url` with the raw file bytes as the body (a plain `curl -T file "$put_url"` or `fetch(put_url, { method: 'PUT', body })`). This is the step that keeps the bytes out of the model context. - Network accessline 94
body (a plain `curl -T file "$put_url"` or `fetch(put_url, { method: 'PUT',
plugins/homespun/skills/homespun/references/registering.md
- Network accessline 39
{ "state": "pending_approval", "verification_uri_complete": "https://homespun.dev/device?code=ABCD-EFGH", - Network accessline 40
"state": "pending_approval", "verification_uri_complete": "https://homespun.dev/device?code=ABCD-EFGH", "user_code": "ABCD-EFGH", - Network accessline 41
"verification_uri_complete": "https://homespun.dev/device?code=ABCD-EFGH",
plugins/homespun/skills/homespun/references/webhooks.md
- Network accessline 19
"webhooks": [ { "on": "create", "collection": "orders", "url": "https://hooks.slack.com/services/T00/B00/xxxx" }, - Network accessline 20
{ "on": "create", "collection": "orders", "url": "https://hooks.slack.com/services/T00/B00/xxxx" }, - Network accessline 23
"collection": "orders", "when": { "field": "status", "changedTo": "shipped" }, "url": "https://api.example.com/hooks/orders" - Network accessline 24
"when": { "field": "status", "changedTo": "shipped" }, "url": "https://api.example.com/hooks/orders" } - Network accessline 25
"url": "https://api.example.com/hooks/orders" - Network accessline 35
`changedTo` edge form (`update` only), with the same pinned comparison semantics. Omit `when` to fire on every create/update. - **`url`** is required and must be a **public `https://` URL** with no - Network accessline 36
semantics. Omit `when` to fire on every create/update. - **`url`** is required and must be a **public `https://` URL** with no `user:pass@` userinfo and no IP-literal host (a DNS name only). A path and - Network accessline 37
- **`url`** is required and must be a **public `https://` URL** with no - Network accessline 57
"when": { "field": "status", "equals": "new" }, "machineAuthorKinds": ["hook", "service"], "url": "https://api.example.com/hooks/leads" - Network accessline 58
"machineAuthorKinds": ["hook", "service"], "url": "https://api.example.com/hooks/leads" } - Network accessline 59
"url": "https://api.example.com/hooks/leads" - Network accessline 224
"on": "create", "collection": "leads", "url": "https://api.hubapi.com/crm/v3/objects/contacts", - Network accessline 225
"collection": "leads", "url": "https://api.hubapi.com/crm/v3/objects/contacts", "connection": "hubspot", - Network accessline 226
"url": "https://api.hubapi.com/crm/v3/objects/contacts", - Network accessline 288
{ "name":"my-crm", "kind":"oauth2", "authorizeUrl":"https://accounts.example.com/oauth/authorize", - Network accessline 289
"authorizeUrl":"https://accounts.example.com/oauth/authorize", - Network accessline 290
"tokenEndpoint":"https://accounts.example.com/oauth/token", - Network accessline 377
`http://localhost:3000/hook` - or any other loopback, RFC1918, CGNAT, or - Network accessline 398
1. Start the receiver locally, e.g. listening on `http://localhost:3000`. - Network accessline 399
2. Start a tunnel to it and copy the `https://` URL it prints: - Network accessline 400
- **ngrok**: `ngrok http 3000` -> `https://<subdomain>.ngrok-free.app` - **cloudflared**: `cloudflared tunnel --url http://localhost:3000` -> `https://<subdomain>.trycloudflare.com` - Network accessline 401
- **cloudflared**: `cloudflared tunnel --url http://localhost:3000` -> - Network accessline 457
"offsetDays": 0, "when": { "field": "status", "equals": "live" }, "url": "https://api.example.com/hooks/expire" - Network accessline 458
"when": { "field": "status", "equals": "live" }, "url": "https://api.example.com/hooks/expire" } - Network accessline 459
"url": "https://api.example.com/hooks/expire"
skills/homespun/SKILL.md
- Network accessline 78
The hosted relay (`https://homespun.dev`) is the default: `homespun agent register` - Access to secretsline 82
[Credential-related source omitted] - Access to secretsline 84
[Credential-related source omitted] - Network accessline 620
{ "$schema": "https://json-schema.org/draft/2020-12/schema", - Network accessline 621
"$schema": "https://json-schema.org/draft/2020-12/schema", - Network accessline 659
} }, "externalHosts": ["https://api.example.com"], - Network accessline 660
}, "externalHosts": ["https://api.example.com"], "cdn": false - Network accessline 661
"externalHosts": ["https://api.example.com"], - Network accessline 722
no effect on `link`/`private` apps: their visibility is the access control and they are never indexable. - **`ogImage`**: an `https://` URL (≤2048 chars) used as the share-preview - Network accessline 723
control and they are never indexable. - **`ogImage`**: an `https://` URL (≤2048 chars) used as the share-preview image (`og:image`/`twitter:image`) instead of the generated card. The - Network accessline 724
- **`ogImage`**: an `https://` URL (≤2048 chars) used as the share-preview - Network accessline 995
rather than a flood of deletes. The author default, the owner's runtime override, and the full mechanics live at https://docs.homespun.dev/agents/collection-retention/; this is only the - Network accessline 996
override, and the full mechanics live at https://docs.homespun.dev/agents/collection-retention/; this is only the manifest shape. - Network accessline 997
https://docs.homespun.dev/agents/collection-retention/; this is only the - Network accessline 1096
- **`x-homespun-manifest.externalHosts`**: an array of `https://` origins (DNS name, optional single leftmost `*.` wildcard, no path/query/IP literal) the page's `fetch`/`XMLHttpRequest` is allowed to reach. This is - Network accessline 1101
- **`x-homespun-manifest.cdn`**: boolean, default `false`. Set `true` to allow `<script src>`/`<link rel=stylesheet>` from any `https:` origin (a CDN). It does **not** widen what the page can `fetch()`; that's `externalHosts` - Network accessline 1102
`<script src>`/`<link rel=stylesheet>` from any `https:` origin (a CDN). It does **not** widen what the page can `fetch()`; that's `externalHosts` only, kept separate on purpose so a page can load, say, a charting library - Network accessline 1103
It does **not** widen what the page can `fetch()`; that's `externalHosts` - Network accessline 1195
origin, not by these grants, so declaring them does not enable those buttons on a third-party embed (see `embeds` below). - **`x-homespun-manifest.embeds`**: optional array of `https://` origins - Network accessline 1196
on a third-party embed (see `embeds` below). - **`x-homespun-manifest.embeds`**: optional array of `https://` origins (same rules as `externalHosts`: DNS name, optional single leftmost `*.` - Network accessline 1197
- **`x-homespun-manifest.embeds`**: optional array of `https://` origins - Network accessline 1201
`connect-src` or `form-action`, so framing a site never lets the page send data to it. For a YouTube player use the privacy-preserving nocookie host: `"embeds": ["https://www.youtube-nocookie.com"]`. Declaring a non-empty - Network accessline 1202
data to it. For a YouTube player use the privacy-preserving nocookie host: `"embeds": ["https://www.youtube-nocookie.com"]`. Declaring a non-empty `embeds` list also relaxes the document's `Referrer-Policy` from `no-referrer` - Network accessline 1203
`"embeds": ["https://www.youtube-nocookie.com"]`. Declaring a non-empty - Network accessline 1215
<!-- manifest: {"x-homespun-manifest":{"embeds":["https://www.youtube-nocookie.com"]}} --> - Network accessline 1216
<iframe src="https://www.youtube-nocookie.com/embed/VIDEO_ID?rel=0" title="Video" - Network accessline 1217
src="https://www.youtube-nocookie.com/embed/VIDEO_ID?rel=0" - Network accessline 1238
The origin grammar is stricter than `embeds`: **exact origins only, no wildcard, ever.** `https://your-form-partner.example` is accepted; - Network accessline 1239
wildcard, ever.** `https://your-form-partner.example` is accepted; - Network accessline 1240
`https://*.example.com` is refused with a clear error, unlike `embeds` - Network accessline 1241
which does allow a single leftmost `*.`. The one exception is local development: `http://localhost:PORT` and `http://127.0.0.1:PORT` are accepted over plain `http`, and no other host may use `http`. - Network accessline 1242
development: `http://localhost:PORT` and `http://127.0.0.1:PORT` are - Network accessline 1243
accepted over plain `http`, and no other host may use `http`. `"embedAncestors": ["https://www.example-partner-site.com"]` is the whole declaration; no path, query, or userinfo is allowed. - Network accessline 1244
`"embedAncestors": ["https://www.example-partner-site.com"]` is the whole - Network accessline 1293
```html <script src="https://<main-domain>/embed.js" data-app="https://your-app.<usercontent-domain>/" - Network accessline 1294
<script src="https://<main-domain>/embed.js" data-app="https://your-app.<usercontent-domain>/" data-height="600" - Network accessline 1295
data-app="https://your-app.<usercontent-domain>/" - Network accessline 2343
body.append("file", file); // the field name is exactly "file" body.append("filename", file.name); // optional, display only const res = await fetch("/_hs/attachments?collection=photos", { method: "POST", body }); - Network accessline 2344
body.append("filename", file.name); // optional, display only const res = await fetch("/_hs/attachments?collection=photos", { method: "POST", body }); const ref = await res.json(); // 201 { attachment_id, mime, size, filename } - Network accessline 2345
const res = await fetch("/_hs/attachments?collection=photos", { method: "POST", body }); - Access to secretsline 2714
[Credential-related source omitted] - Access to secretsline 2715
[Credential-related source omitted]
skills/homespun/references/agent-tasks.md
- Network accessline 256
"writes": ["line_items"], "lease_expires_at": "2026-08-08T12:00:00.000Z", "api_base": "https://homespun.dev", - Network accessline 257
"lease_expires_at": "2026-08-08T12:00:00.000Z", "api_base": "https://homespun.dev", "credential": "hsc_..." - Network accessline 258
"api_base": "https://homespun.dev",
skills/homespun/references/attachments.md
- Network accessline 92
`{ put_url, attachment_id }`. 2. **PUT the bytes**: do an HTTP `PUT put_url` with the raw file bytes as the body (a plain `curl -T file "$put_url"` or `fetch(put_url, { method: 'PUT', - Network accessline 93
2. **PUT the bytes**: do an HTTP `PUT put_url` with the raw file bytes as the body (a plain `curl -T file "$put_url"` or `fetch(put_url, { method: 'PUT', body })`). This is the step that keeps the bytes out of the model context. - Network accessline 94
body (a plain `curl -T file "$put_url"` or `fetch(put_url, { method: 'PUT',
skills/homespun/references/registering.md
- Network accessline 39
{ "state": "pending_approval", "verification_uri_complete": "https://homespun.dev/device?code=ABCD-EFGH", - Network accessline 40
"state": "pending_approval", "verification_uri_complete": "https://homespun.dev/device?code=ABCD-EFGH", "user_code": "ABCD-EFGH", - Network accessline 41
"verification_uri_complete": "https://homespun.dev/device?code=ABCD-EFGH",
skills/homespun/references/webhooks.md
- Network accessline 19
"webhooks": [ { "on": "create", "collection": "orders", "url": "https://hooks.slack.com/services/T00/B00/xxxx" }, - Network accessline 20
{ "on": "create", "collection": "orders", "url": "https://hooks.slack.com/services/T00/B00/xxxx" }, - Network accessline 23
"collection": "orders", "when": { "field": "status", "changedTo": "shipped" }, "url": "https://api.example.com/hooks/orders" - Network accessline 24
"when": { "field": "status", "changedTo": "shipped" }, "url": "https://api.example.com/hooks/orders" } - Network accessline 25
"url": "https://api.example.com/hooks/orders" - Network accessline 35
`changedTo` edge form (`update` only), with the same pinned comparison semantics. Omit `when` to fire on every create/update. - **`url`** is required and must be a **public `https://` URL** with no - Network accessline 36
semantics. Omit `when` to fire on every create/update. - **`url`** is required and must be a **public `https://` URL** with no `user:pass@` userinfo and no IP-literal host (a DNS name only). A path and - Network accessline 37
- **`url`** is required and must be a **public `https://` URL** with no - Network accessline 57
"when": { "field": "status", "equals": "new" }, "machineAuthorKinds": ["hook", "service"], "url": "https://api.example.com/hooks/leads" - Network accessline 58
"machineAuthorKinds": ["hook", "service"], "url": "https://api.example.com/hooks/leads" } - Network accessline 59
"url": "https://api.example.com/hooks/leads" - Network accessline 224
"on": "create", "collection": "leads", "url": "https://api.hubapi.com/crm/v3/objects/contacts", - Network accessline 225
"collection": "leads", "url": "https://api.hubapi.com/crm/v3/objects/contacts", "connection": "hubspot", - Network accessline 226
"url": "https://api.hubapi.com/crm/v3/objects/contacts", - Network accessline 288
{ "name":"my-crm", "kind":"oauth2", "authorizeUrl":"https://accounts.example.com/oauth/authorize", - Network accessline 289
"authorizeUrl":"https://accounts.example.com/oauth/authorize", - Network accessline 290
"tokenEndpoint":"https://accounts.example.com/oauth/token", - Network accessline 377
`http://localhost:3000/hook` - or any other loopback, RFC1918, CGNAT, or - Network accessline 398
1. Start the receiver locally, e.g. listening on `http://localhost:3000`. - Network accessline 399
2. Start a tunnel to it and copy the `https://` URL it prints: - Network accessline 400
- **ngrok**: `ngrok http 3000` -> `https://<subdomain>.ngrok-free.app` - **cloudflared**: `cloudflared tunnel --url http://localhost:3000` -> `https://<subdomain>.trycloudflare.com` - Network accessline 401
- **cloudflared**: `cloudflared tunnel --url http://localhost:3000` -> - Network accessline 457
"offsetDays": 0, "when": { "field": "status", "equals": "live" }, "url": "https://api.example.com/hooks/expire" - Network accessline 458
"when": { "field": "status", "equals": "live" }, "url": "https://api.example.com/hooks/expire" } - Network accessline 459
"url": "https://api.example.com/hooks/expire"
How the signals fit together
Facts from a static read of the files at the pinned commit. They describe what the code does, not why.
Some files could not be read; the facts below still hold.
Signal confidence: 76 facts
- Network access in prose of the SKILL.mdhomespun/SKILL.md:78Low confidence
- Access to secrets in prose of the SKILL.mdhomespun/SKILL.md:82Low confidence
- Access to secrets in prose of the SKILL.mdhomespun/SKILL.md:84Low confidence
- Network access in code of the SKILL.mdhomespun/SKILL.md:620High confidence
- Network access in code of the SKILL.mdhomespun/SKILL.md:621High confidence
- Network access in code of the SKILL.mdhomespun/SKILL.md:659High confidence
- Network access in code of the SKILL.mdhomespun/SKILL.md:660High confidence
- Network access in code of the SKILL.mdhomespun/SKILL.md:661High confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:722Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:723Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:724Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:995Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:996Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:997Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1096Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1101Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1102Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1103Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1195Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1196Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1197Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1201Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1202Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1203Low confidence
- Network access in code of the SKILL.mdhomespun/SKILL.md:1215High confidence
- Network access in code of the SKILL.mdhomespun/SKILL.md:1216High confidence
- Network access in code of the SKILL.mdhomespun/SKILL.md:1217High confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1238Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1239Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1240Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1241Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1242Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1243Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1244Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1293Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1294Low confidence
- Network access in prose of the SKILL.mdhomespun/SKILL.md:1295Low confidence
- Network access in code of the SKILL.mdhomespun/SKILL.md:2343High confidence
- Network access in code of the SKILL.mdhomespun/SKILL.md:2344High confidence
- Network access in code of the SKILL.mdhomespun/SKILL.md:2345High confidence
- Access to secrets in prose of the SKILL.mdhomespun/SKILL.md:2714Low confidence
- Access to secrets in prose of the SKILL.mdhomespun/SKILL.md:2715Low confidence
- Network access in code of documentationhomespun/references/agent-tasks.md:256Low confidence
- Network access in code of documentationhomespun/references/agent-tasks.md:257Low confidence
- Network access in code of documentationhomespun/references/agent-tasks.md:258Low confidence
- Network access in prose of documentationhomespun/references/attachments.md:92Low confidence
- Network access in prose of documentationhomespun/references/attachments.md:93Low confidence
- Network access in prose of documentationhomespun/references/attachments.md:94Low confidence
- Network access in code of documentationhomespun/references/registering.md:39Low confidence
- Network access in code of documentationhomespun/references/registering.md:40Low confidence
and 26 more
Works with
| Agent | Status | Evidence | Install to |
|---|---|---|---|
| Claude Code | Native | Manifest .claude-plugin/marketplace.json | .claude/skills/<skill-name>/ |
| Codex | Compatible | Standard SKILL.md skills/homespun/SKILL.md | .agents/skills/<skill-name>/ |
| Cursor | Compatible | Standard SKILL.md skills/homespun/SKILL.md | .cursor/skills/<skill-name>/ |
| Gemini CLI | Compatible | Standard SKILL.md skills/homespun/SKILL.md | .gemini/skills/<skill-name>/ |
| GitHub Copilot | Compatible | Standard SKILL.md skills/homespun/SKILL.md | .github/skills/<skill-name>/ |
| OpenCode | Compatible | Standard SKILL.md skills/homespun/SKILL.md | .opencode/skills/<skill-name>/ |
- Native The repository ships a manifest, folder or frontmatter field for this agent.
- Compatible A standard SKILL.md that this agent can read.
- Unknown No evidence either way.
Derived automatically from paths, manifests and frontmatter. Not tested on each agent.