AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻译准备中
astro-inkstone — the Astro wiki you can write in. Paper-and-ink typography for documentation sites, wikis and digital gardens, with in-place editing through astro-inkbrush. This demo is the package's
翻译准备中
开发工具TypeScript · JavaScriptGitHub @ventusff在线运营者未确认
试用过了吗? 点一下就好,无需登录。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证A tiny git-backed CMS for Astro — edit your static site in place: block-level editing with revision history, comments, AI assist and an Obsidian inbox. One integration, zero footprint in production builds.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
A tiny git-backed CMS for Astro — edit your static site in place. Inkbrush (笔 — the ink brush) adds an optional editing layer to any Astro site: hover a paragraph, click ✎, edit the Markdown source right there, save — the page hot-reloads, and with autocommit on the change is a git commit. No database, no admin panel, no separate authoring app. Your content files stay the single source of truth; git stays the history.查看完整 README ↗
Inkbrush (笔 — the ink brush) adds an optional editing layer to any Astro
site: hover a paragraph, click ✎, edit the Markdown source right there, save —
the page hot-reloads, and with autocommit on the change is a git commit. No
database, no admin panel, no separate authoring app. Your content files stay
the single source of truth; git stays the history.
It is the sibling of astro-inkstone
(砚 — the ink stone), a paper-and-ink design layer. Inkbrush styles only its
own editing chrome (through tokens it takes from your page) and ships no page
styling and no layout — bring your own site, or pair it with Inkstone for
the full look. See the editor in motion — formulas, tables, [[wikilinks]]
and the frontmatter edited in place, the guard refusing a broken save — in the
Inkstone README, and try it
yourself in the browser on the
Inkstone demo.
[[ autocompletion scoped to the note's language, optimistic
locking (a block changed by
someone else is refused, never overwritten), and a whole-file build gate —
the dialect, the content guard, your plugins, MDX compilation — before
anything is written. The frontmatter is a block too, edited as YAML from
the page head.claude CLI, streaming progress live. Every job runs in a throwaway
workspace holding only the note (and the companion files your config
names), with file tools confined to it, no shell or network tools and an
allowlisted environment; its result is validated like a manual save and
carried back only then — and only if nothing changed under the job
meanwhile: a concurrent manual edit wins..wiki/data/ beside your project; author emails
never leave the server.[[wikilink]] implementation shared by the page
pipeline, the editor preview and the importer: aliases, anchors, locale
mirrors, and dead-link spans instead of broken builds.*/_/~~, MDX
expressions swallowing your prose, single-line $$x$$, formulas KaTeX
can't render, and more — each reported with file:line:column and a caret.check-content.mjs (compile every source file with
the dialect, the guard and — given --config — your site's plugins;
given --frontmatter, hold every file's frontmatter to your
content-collection schema before the build does; in a repository whose
pages a translation service translates from an i18n.config.json, every
code fence names its language and a source page's code holds no Chinese,
since the service copies code into every language as written),
check-language.mjs (that last check alone; its findings are warnings
until the --config module exports codeLanguage: 'error'),
check-wikilinks.mjs (dead or ambiguous [[wikilinks]], dubious
anchors — with the library's own parser and resolution rules) and
check-dist.mjs (broken links, dangling anchors, locale doubling, nested
<a>, KaTeX error residue, and any CMS injection in built HTML).astro dev, and check-dist fails a build that carries any of its bytes.astro-inkbrush/playground) — an opt-in
surface for demo sites only: the same block editor on a static build,
saving to the visitor's own IndexedDB. Nothing leaves the browser;
consumer sites never mount it (the build that does declares itself with
check-dist --playground).readers → your static build (astro build) — nginx, Pages, object storage…
authors → the same repo running `WIKI=1 astro dev` on an editing domain
└─ saves → git commits (autocommit) → pushed (autopush) → CI rebuilds
The editor is Astro's dev server with this integration active: an
"edit-and-it's-live" surface needs a resident compiler, and the dev server
is exactly that. Sessions, a membership registry and cross-site request
checks make it fit for a real domain; the reader-facing site never runs any
of it. A two-service deployment skeleton (static reader + editing machine)
ships in deploy/.
The demo is the Inkstone garden: this engine's own manual lives there as the editing machine chapters (in 18 languages), and the browser playground on that site runs this very editor on a purely static build. To edit for real, run the garden in editing mode — it vendors this engine as a git submodule:
git clone --recurse-submodules https://github.com/ventusff/astro-inkstone
cd astro-inkstone && npm install
cd demo && npm install
npm run wiki # WIKI=1 astro dev → open the site, sign in (dev login), edit away
npm run build # reading mode — proof of the zero-footprint claim
Three touches, all gated on an env flag (vendor the repo as a git submodule
and declare it with pnpm workspace:* or npm file: — it isn't on npm,
by design):
// astro.config.ts
import { inkbrush, rehypeWikiBlocks } from 'astro-inkbrush';
import { markdownProcessor } from 'astro-inkbrush/markdown';
const WIKI_MODE = process.env.WIKI === '1' || process.env.WIKI === 'true';
const remarkPlugins = [/* yours */];
const rehypePlugins = [/* yours */];
export default defineConfig({
markdown: {
processor: markdownProcessor({
remarkPlugins,
rehypePlugins: [...rehypePlugins, ...(WIKI_MODE ? [rehypeWikiBlocks] : [])],
}),
},
// the same plugins go to the CMS, so its preview and its save-time
// validation render a note the way your pages do; urlFor is your
// note-id → URL rule — without it the engine assumes `/${id}/`;
// frontmatter is your content-collection schema, so a save is refused
// for the frontmatter the build would refuse
integrations: [...(WIKI_MODE ? [inkbrush({ markdown: { remarkPlugins, rehypePlugins, urlFor: (id) => `/notes/${id}/`, frontmatter: notesSchema } })] : [])],
});
<!-- on each note page: tell the CMS which note this is (routing stays yours) -->
<meta name="inkbrush-note" content={noteId} />
cp <path-to-inkbrush>/inkbrush.config.example.ts inkbrush.config.ts # optional, per machine
WIKI=1 astro dev
No config file is required — the default is dev-login-only with everything else off. See the manual for auth providers, the identity registry, the inbox, sharing, and every configuration key.
astro-inkbrush the brush — editing: block CMS, revisions, comments, AI,
inbox, Markdown dialect + content guard
astro-inkstone the stone — appearance: tokens, content styles, components,
pipeline preset (builds on this package's dialect)
your site the hand — identity: layout, routing, content, deployment
The one thing Inkbrush does define beyond the CMS is the Markdown dialect — because a block the editor accepts must render identically on the page, the parser rule set lives in one place and is consumed everywhere.
MIT © Jianfei Guo