From 7229b732d1e794bb39955ffff68308d3532edd24 Mon Sep 17 00:00:00 2001
From: Luke Rohenaz
Date: Fri, 4 Sep 2026 12:50:36 -0400
Subject: [PATCH 1/2] feat: publish BitPlan as an external agent provider
[OPL-4438]
---
.claude-plugin/plugin.json | 14 ++++++
.codex-plugin/plugin.json | 28 +++++++++++
.grok-plugin/plugin.json | 14 ++++++
CHANGELOG.md | 13 ++++++
README.md | 14 ++++++
.../.well-known/agent-skills/bitplan/SKILL.md | 20 +++++++-
.../.well-known/agent-skills/index.json | 2 +-
apps/web/src/app/docs/agents/page.tsx | 7 +++
apps/web/src/lib/agent-pages.test.ts | 46 ++++++++++++++++++-
apps/web/src/lib/agent-pages.ts | 4 ++
skills/bitplan/SKILL.md | 20 +++++++-
skills/bitplan/agents/openai.yaml | 4 ++
12 files changed, 181 insertions(+), 5 deletions(-)
create mode 100644 .claude-plugin/plugin.json
create mode 100644 .codex-plugin/plugin.json
create mode 100644 .grok-plugin/plugin.json
create mode 100644 skills/bitplan/agents/openai.yaml
diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json
new file mode 100644
index 0000000..cdac9b5
--- /dev/null
+++ b/.claude-plugin/plugin.json
@@ -0,0 +1,14 @@
+{
+ "name": "bitplan",
+ "version": "0.2.1",
+ "description": "Create and share encrypted, versioned HTML plans with a BRC-100 wallet.",
+ "author": {
+ "name": "OPL",
+ "url": "https://github.com/opldotdev"
+ },
+ "homepage": "https://bitplan.dev/docs/agents",
+ "repository": "https://github.com/opldotdev/bitplan.dev",
+ "license": "MIT",
+ "keywords": ["agents", "bitplan", "brc-100", "bsv", "encryption"],
+ "skills": "./skills/"
+}
diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json
new file mode 100644
index 0000000..085b7b6
--- /dev/null
+++ b/.codex-plugin/plugin.json
@@ -0,0 +1,28 @@
+{
+ "name": "bitplan",
+ "version": "0.2.1",
+ "description": "Create and share encrypted, versioned HTML plans with a BRC-100 wallet.",
+ "author": {
+ "name": "OPL",
+ "url": "https://github.com/opldotdev"
+ },
+ "homepage": "https://bitplan.dev/docs/agents",
+ "repository": "https://github.com/opldotdev/bitplan.dev",
+ "license": "MIT",
+ "keywords": ["agents", "bitplan", "brc-100", "bsv", "encryption"],
+ "skills": "./skills/",
+ "interface": {
+ "displayName": "BitPlan",
+ "shortDescription": "Encrypted plans owned by your wallet.",
+ "longDescription": "Create, review, host, version, share, and publish encrypted HTML plans through a BRC-100 wallet.",
+ "developerName": "OPL",
+ "category": "Productivity",
+ "capabilities": ["Skills"],
+ "websiteURL": "https://bitplan.dev",
+ "defaultPrompt": [
+ "Create an encrypted BitPlan for this project.",
+ "Update my existing BitPlan draft.",
+ "Share a BitPlan with another wallet."
+ ]
+ }
+}
diff --git a/.grok-plugin/plugin.json b/.grok-plugin/plugin.json
new file mode 100644
index 0000000..cdac9b5
--- /dev/null
+++ b/.grok-plugin/plugin.json
@@ -0,0 +1,14 @@
+{
+ "name": "bitplan",
+ "version": "0.2.1",
+ "description": "Create and share encrypted, versioned HTML plans with a BRC-100 wallet.",
+ "author": {
+ "name": "OPL",
+ "url": "https://github.com/opldotdev"
+ },
+ "homepage": "https://bitplan.dev/docs/agents",
+ "repository": "https://github.com/opldotdev/bitplan.dev",
+ "license": "MIT",
+ "keywords": ["agents", "bitplan", "brc-100", "bsv", "encryption"],
+ "skills": "./skills/"
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ddc68ef..a28018c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
# Changelog
+## Unreleased
+
+### Added
+
+- Package the canonical BitPlan skill as a Claude Code, Codex, and Grok plugin
+ so external catalogs can install it without copying the skill.
+
+### Changed
+
+- Document the wallet selection contract: prefer an existing BRC-100 wallet
+ and do not present the current 1Sat wallet-storage server as a compatible
+ BitPlan fallback.
+
## 0.0.16 — 2026-09-04
### Added
diff --git a/README.md b/README.md
index adbafde..bd4d991 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,16 @@ publish them on Bitcoin when they should be permanent.
[Open BitPlan](https://bitplan.dev) · [Read the docs](https://bitplan.dev/docs) · [Install the CLI](https://www.npmjs.com/package/bitplan)
+Install the agent skill directly from its owning repository:
+
+```sh
+npx skills add opldotdev/bitplan.dev --skill bitplan -g
+```
+
+The repository also includes native plugin manifests for Claude Code, Codex,
+and Grok. Marketplace installations therefore load this canonical skill rather
+than a copied version maintained by another plugin.
+
BitPlan turns a self-contained HTML file into an encrypted plan. BRC-100 is the
interface BitPlan uses to ask your wallet to encrypt and decrypt. Hosted drafts
store only ciphertext on bitplan.dev and cost no BSV. When a plan is ready, the
@@ -106,6 +116,10 @@ Compatibility tests open CLI-produced envelopes with the website
implementation. Wallet and network boundaries use mocks, so the automated
suite never publishes a transaction.
+BitPlan prefers a BRC-100 wallet already installed by the user. A future 1Sat
+CLI headless-wallet bridge is tracked separately; today's `1sat serve wallet`
+endpoint is a wallet-storage service and is not a BitPlan wallet endpoint.
+
Contributions are welcome. Start with [CONTRIBUTING.md](CONTRIBUTING.md).
## License
diff --git a/apps/web/public/.well-known/agent-skills/bitplan/SKILL.md b/apps/web/public/.well-known/agent-skills/bitplan/SKILL.md
index bad4f61..c4f15dc 100644
--- a/apps/web/public/.well-known/agent-skills/bitplan/SKILL.md
+++ b/apps/web/public/.well-known/agent-skills/bitplan/SKILL.md
@@ -5,11 +5,13 @@ description: >
with BitPlan and a BRC-100 wallet. Use when asked to make a BitPlan, publish
or update a plan, share one with a person or team, create a private reader
link, move a hosted draft on chain, or explain bitplan.dev.
+metadata:
+ version: "0.2.1"
---
# BitPlan
-**Skill version: 0.2.0**
+**Skill version: 0.2.1**
BitPlan turns one self-contained HTML file into an encrypted living plan. A
BRC-100 wallet owns the keys. A draft can stay hosted as ciphertext while it
@@ -19,6 +21,22 @@ wallet interface, not the inscription format.
Use `bunx bitplan` or `npx bitplan`. Never install the CLI globally. Run it
from the repository the plan belongs to so BitPlan records Git metadata.
+## Choose the wallet honestly
+
+Prefer a compatible BRC-100 wallet the user already has. Check it with
+`bunx bitplan auth`; do not silently create, import, or replace a wallet.
+
+The 1Sat CLI is intended to become the local fallback wallet for agents, but
+that application-facing bridge is not released yet. `1sat serve wallet`
+currently serves authenticated wallet storage; it is not a drop-in endpoint
+for BitPlan's BRC-100 `HTTPWalletJSON` client. Do not point BitPlan at it or
+claim the fallback works until the 1Sat headless-wallet acceptance test passes.
+
+If no compatible wallet is available, explain that BitPlan cannot create or
+update an encrypted plan today. Let the calling workflow offer a local file or
+an explicitly approved non-BitPlan host. Never weaken BitPlan into a plaintext
+or agent-held-key mode to make the command succeed.
+
## Check the live product first
Before answering what BitPlan supports, read https://bitplan.dev/llms.txt and
diff --git a/apps/web/public/.well-known/agent-skills/index.json b/apps/web/public/.well-known/agent-skills/index.json
index 71522c9..bf36ce4 100644
--- a/apps/web/public/.well-known/agent-skills/index.json
+++ b/apps/web/public/.well-known/agent-skills/index.json
@@ -6,7 +6,7 @@
"type": "skill-md",
"description": "Create, review, host, publish, update, fetch, and share encrypted HTML plans with a BRC-100 wallet.",
"url": "https://bitplan.dev/.well-known/agent-skills/bitplan/SKILL.md",
- "digest": "sha256:b8a705b429b0b684b26b4b2222b9ad9a9f0583394188469fbc0da6297fac6ff1"
+ "digest": "sha256:78c3af794fdba1a5a9a328382d0592a7545ca754b7ed6d1e725cfbac38cc62ce"
}
]
}
diff --git a/apps/web/src/app/docs/agents/page.tsx b/apps/web/src/app/docs/agents/page.tsx
index 1672eff..9bdeb70 100644
--- a/apps/web/src/app/docs/agents/page.tsx
+++ b/apps/web/src/app/docs/agents/page.tsx
@@ -36,6 +36,13 @@ export default function AgentsAndWalletsPage() {
The CLI never asks for a mnemonic or private key. The wallet still
controls every permission.
+
+ Prefer a compatible wallet you already use. The 1Sat CLI is planned as
+ a local fallback for agent sessions, but its current{" "}
+ 1sat serve wallet command exposes wallet storage rather
+ than the application-facing endpoint BitPlan needs. Do not configure
+ it as a BitPlan wallet yet.
+
diff --git a/apps/web/src/lib/agent-pages.test.ts b/apps/web/src/lib/agent-pages.test.ts
index 27fde6a..ce0a951 100644
--- a/apps/web/src/lib/agent-pages.test.ts
+++ b/apps/web/src/lib/agent-pages.test.ts
@@ -1,11 +1,17 @@
import { describe, expect, test } from "bun:test";
import { createHash } from "node:crypto";
import { readFile } from "node:fs/promises";
+import { dirname, resolve } from "node:path";
+import { fileURLToPath } from "node:url";
import { GET as getRobots } from "@/app/robots.txt/route";
import { LLMS_TXT, markdownForPath, markdownNotFound } from "./agent-pages";
+const SEMVER = /^\d+\.\d+\.\d+$/;
+const SKILL_METADATA_VERSION = /\nmetadata:\n\s+version: ["']([^"']+)["']/;
+const SKILL_VISIBLE_VERSION = /\*\*Skill version: ([^*]+)\*\*/;
+
describe("agent pages", () => {
test("home and docs have markdown", () => {
expect(markdownForPath("/")).toContain("npx bitplan");
@@ -52,22 +58,27 @@ describe("agent pages", () => {
test("agent discovery files describe real BitPlan capabilities", async () => {
const publicRoot = new URL("../../public/.well-known/", import.meta.url);
- const skill = await readFile(
+ const publishedSkill = await readFile(
new URL("agent-skills/bitplan/SKILL.md", publicRoot),
"utf8"
);
+ const canonicalSkill = await readFile(
+ new URL("../../../../skills/bitplan/SKILL.md", import.meta.url),
+ "utf8"
+ );
const index = JSON.parse(
await readFile(new URL("agent-skills/index.json", publicRoot), "utf8")
) as { $schema: string; skills: Array<{ digest: string }> };
const catalog = JSON.parse(
await readFile(new URL("ai-catalog.json", publicRoot), "utf8")
) as { entries: Array<{ data?: unknown; url?: unknown }> };
- const digest = createHash("sha256").update(skill).digest("hex");
+ const digest = createHash("sha256").update(canonicalSkill).digest("hex");
expect(index.$schema).toBe(
"https://schemas.agentskills.io/discovery/0.2.0/schema.json"
);
expect(index.skills[0].digest).toBe(`sha256:${digest}`);
+ expect(publishedSkill).toBe(canonicalSkill);
expect(catalog.entries).toHaveLength(2);
expect(
catalog.entries.every(
@@ -83,4 +94,35 @@ describe("agent pages", () => {
"Agentmap: https://bitplan.dev/.well-known/ai-catalog.json"
);
});
+
+ test("cross-harness plugin manifests expose the canonical skill", async () => {
+ const repoRoot = resolve(
+ dirname(fileURLToPath(import.meta.url)),
+ "../../../.."
+ );
+ const versions = new Set();
+ const canonicalSkill = await readFile(
+ resolve(repoRoot, "skills/bitplan/SKILL.md"),
+ "utf8"
+ );
+ const metadataVersion = canonicalSkill.match(SKILL_METADATA_VERSION)?.[1];
+ const visibleVersion = canonicalSkill.match(SKILL_VISIBLE_VERSION)?.[1];
+ const manifests = await Promise.all(
+ [".claude-plugin", ".codex-plugin", ".grok-plugin"].map(
+ async (directory) =>
+ JSON.parse(
+ await readFile(resolve(repoRoot, directory, "plugin.json"), "utf8")
+ ) as { name: string; skills: string; version: string }
+ )
+ );
+ for (const manifest of manifests) {
+ expect(manifest.name).toBe("bitplan");
+ expect(manifest.skills).toBe("./skills/");
+ expect(manifest.version).toMatch(SEMVER);
+ versions.add(manifest.version);
+ }
+ expect(versions.size).toBe(1);
+ expect(metadataVersion).toBe(manifests[0].version);
+ expect(visibleVersion).toBe(manifests[0].version);
+ });
});
diff --git a/apps/web/src/lib/agent-pages.ts b/apps/web/src/lib/agent-pages.ts
index c67707c..829ffc1 100644
--- a/apps/web/src/lib/agent-pages.ts
+++ b/apps/web/src/lib/agent-pages.ts
@@ -56,6 +56,8 @@ A coding agent uses the BitPlan CLI. The CLI calls a BRC-100 wallet on the same
Never give an agent a wallet mnemonic or private key. To read new plans with another wallet, save its public identity as a default reader:
+Prefer a compatible BRC-100 wallet the user already has. The planned 1Sat CLI fallback is not available yet: \`1sat serve wallet\` currently serves wallet storage, not the application-facing BRC-100 endpoint BitPlan needs. Do not point BitPlan at it.
+
npx bitplan config --share-with
For a local team, save contacts and share by team name:
@@ -150,6 +152,8 @@ Use BitPlan when a user wants to draft, publish, version, share, or read an encr
Do not use BitPlan as a general file host, a server-side notes app, or a substitute for a BRC-100 wallet.
+Prefer an existing compatible wallet. Do not claim that \`1sat serve wallet\` is a working BitPlan fallback; the application-facing 1Sat CLI wallet bridge is still planned.
+
## Terms
- BRC-100 is the interface BitPlan uses to talk to a wallet. It is not an inscription format.
diff --git a/skills/bitplan/SKILL.md b/skills/bitplan/SKILL.md
index bad4f61..c4f15dc 100644
--- a/skills/bitplan/SKILL.md
+++ b/skills/bitplan/SKILL.md
@@ -5,11 +5,13 @@ description: >
with BitPlan and a BRC-100 wallet. Use when asked to make a BitPlan, publish
or update a plan, share one with a person or team, create a private reader
link, move a hosted draft on chain, or explain bitplan.dev.
+metadata:
+ version: "0.2.1"
---
# BitPlan
-**Skill version: 0.2.0**
+**Skill version: 0.2.1**
BitPlan turns one self-contained HTML file into an encrypted living plan. A
BRC-100 wallet owns the keys. A draft can stay hosted as ciphertext while it
@@ -19,6 +21,22 @@ wallet interface, not the inscription format.
Use `bunx bitplan` or `npx bitplan`. Never install the CLI globally. Run it
from the repository the plan belongs to so BitPlan records Git metadata.
+## Choose the wallet honestly
+
+Prefer a compatible BRC-100 wallet the user already has. Check it with
+`bunx bitplan auth`; do not silently create, import, or replace a wallet.
+
+The 1Sat CLI is intended to become the local fallback wallet for agents, but
+that application-facing bridge is not released yet. `1sat serve wallet`
+currently serves authenticated wallet storage; it is not a drop-in endpoint
+for BitPlan's BRC-100 `HTTPWalletJSON` client. Do not point BitPlan at it or
+claim the fallback works until the 1Sat headless-wallet acceptance test passes.
+
+If no compatible wallet is available, explain that BitPlan cannot create or
+update an encrypted plan today. Let the calling workflow offer a local file or
+an explicitly approved non-BitPlan host. Never weaken BitPlan into a plaintext
+or agent-held-key mode to make the command succeed.
+
## Check the live product first
Before answering what BitPlan supports, read https://bitplan.dev/llms.txt and
diff --git a/skills/bitplan/agents/openai.yaml b/skills/bitplan/agents/openai.yaml
new file mode 100644
index 0000000..5d57a88
--- /dev/null
+++ b/skills/bitplan/agents/openai.yaml
@@ -0,0 +1,4 @@
+interface:
+ display_name: "BitPlan"
+ short_description: "Create encrypted plans with your wallet"
+ default_prompt: "Use $bitplan to create or update an encrypted, versioned plan with my BRC-100 wallet."
From fbf53fd385d48531775f1b638e1846f99f511a9c Mon Sep 17 00:00:00 2001
From: Luke Rohenaz
Date: Fri, 4 Sep 2026 12:55:20 -0400
Subject: [PATCH 2/2] chore: restore root lint gate
---
biome.json | 8 +++++++-
docs/templates/plan.html | 2 +-
plans/bitplan-agent-keys-and-next-features.html | 2 +-
3 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/biome.json b/biome.json
index e57d16c..bc6d669 100644
--- a/biome.json
+++ b/biome.json
@@ -2,7 +2,13 @@
"$schema": "https://biomejs.dev/schemas/2.5.11/schema.json",
"vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true },
"files": {
- "includes": ["**", "!**/node_modules", "!**/dist", "!apps/web"]
+ "includes": [
+ "**",
+ "!**/node_modules",
+ "!**/dist",
+ "!apps/web",
+ "!.claude/linear-sync.json"
+ ]
},
"formatter": { "enabled": true, "indentStyle": "tab", "indentWidth": 2 },
"linter": { "enabled": true, "rules": { "preset": "recommended" } },
diff --git a/docs/templates/plan.html b/docs/templates/plan.html
index 31b85b0..62d113a 100644
--- a/docs/templates/plan.html
+++ b/docs/templates/plan.html
@@ -48,7 +48,7 @@
/* Response block. Fills in from the radios with CSS alone, so it works with scripts off. */
.response { margin-top: 1.5rem; }
- .btn { display: inline-block; padding: 10px 16px; border-radius: 8px; background: var(--accent); color: #fff; font-weight: 700; cursor: pointer; border: 0; font: inherit; }
+ .btn { display: inline-block; padding: 10px 16px; border-radius: 8px; background: var(--accent); color: #fff; cursor: pointer; border: 0; font: inherit; font-weight: 700; }
.response pre { margin-top: 12px; user-select: all; -webkit-user-select: all; white-space: pre-wrap; }
.hint { font-size: .88rem; color: var(--muted); margin: 6px 0 0; }
.ans { display: none; }
diff --git a/plans/bitplan-agent-keys-and-next-features.html b/plans/bitplan-agent-keys-and-next-features.html
index 51caef4..34e595d 100644
--- a/plans/bitplan-agent-keys-and-next-features.html
+++ b/plans/bitplan-agent-keys-and-next-features.html
@@ -50,7 +50,7 @@
.opt .rec { color: var(--accent); font-weight: 700; }
.notes { width: 100%; min-height: 80px; margin-top: 8px; padding: 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg); color: var(--fg); font: inherit; font-size: .92rem; resize: vertical; box-sizing: border-box; }
.response { margin-top: 1.5rem; }
- .response .btn { display: inline-block; padding: 10px 16px; border-radius: 8px; background: var(--accent); color: #fff; font-weight: 700; cursor: pointer; border: 0; font: inherit; }
+ .response .btn { display: inline-block; padding: 10px 16px; border-radius: 8px; background: var(--accent); color: #fff; cursor: pointer; border: 0; font: inherit; font-weight: 700; }
.response pre { margin-top: 12px; user-select: all; -webkit-user-select: all; white-space: pre-wrap; }
.response .hint { font-size: .88rem; color: var(--muted); margin: 6px 0 0; }
.ans { display: none; }