adelpro/writing-flow
v0.10.0MIT
Portable voice-writing pipeline. Drafts in a profile's voice, runs the Arabic, anti-AI and provenance passes, and gates the result deterministically.
Changelog
All notable changes to this package. Versioning follows Semantic Versioning.
0.10.0
- Added: an options surface on the installer.
--agents,--all-agents,--no-agents,--no-claude,--no-opencode,--skills-only,--no-deps,--offline,--no-python-check,--prune,--uninstall,--keep,--profile/--default-profile/--generate-profile/--no-profile,--store,--json,--check,--yes,--help— plus an interactive wizard when it is run in a terminal without--yes. Flags never imply a write:--apply, or the wizard's confirmation, is required. Naming--agentsscopes every surface, not just the skills. - Added: a profile store, searched before the default.
~/.agents/writing-flow/profilesis checked before falling back to the bundledvoice-default, and a profile found there is rendered into the harness roots. Generating a profile is offered, never automatic. - Added:
--skip-style, the symmetric escape to--skip-marks, reported asPASS skipped (--skip-style)so it can never be read as a check that ran. - Dropped: the MCP-only surface. A client with no skills system — a plain chat UI — gets the
profile tools and the prompts, but cannot load the skill the prompt depends on, and
run_gatetakes a file path, so the flow degrades into an improvised order and an ungated result. Thewriteprompt now stops and says so instead of improvising, and the README and ROADMAP record it as a non-goal. The server keeps its role as the profile-tool component of the supported surfaces. - Fixed: the dependencies only reached OpenCode. They were installed with
-a opencode, so~/.agents/skillsgot them and every other harness root did not — Claude Code would receive writing-flow from the plugin and none of the four skills its stages call. They now install for every detected agent,claude-codeincluded; there is no duplication risk, because no plugin ships them. - Added: install-time warnings instead of silent gaps. A missing Python — or the Microsoft
Store stub, which is on
PATHbut does not run — is named at install time rather than discovered later as a bare exit 2, and the message carries the--skip-marksescape. A dependency directory that exists but cannot run (an umbrella repository cloned into the skill root, so the gate script sits a level deeper) is warned about with the fix, because the installer deliberately never rewrites an existing dependency. probePythonnow verifies the candidate runs (python --version) instead of trustingwhere/which, so the Store stub is reported as "does not run" rather than as a working Python that fails every gate.- Fixed: the suite was not hermetic.
tests/install.test.mjscalled the installer with the real dependency list and no dry run, so every test run performed a livegit clone. - Changed: every harness is now installed through its own native mechanism.
bin/install.mjsno longer copies what a harness can fetch itself. Claude Code gets the marketplace plugin (extraKnownMarketplaces+enabledPluginsin~/.claude/settings.json); OpenCode gets the package plugin (@adelpro/writing-flowin thepluginsarray); every other detected agent gets the two skills through the skills CLI. The hand-assembled~/.claude/plugins/writing-flowbundle, the~/.config/opencode/commands/copies, the mergedmcp.writing-flowentry and the generatedshims/opencode/mcp.opencode.jsonfragment are all gone. - Fixed: the Claude bundle's MCP server could never start. It pointed at
${CLAUDE_PLUGIN_ROOT}/skills/writing-flow/scripts/mcp-server.mjsfrom a bundle that deliberately ships noskills/. The marketplace route resolves that path inside the plugin clone, so the fix was to stop hand-assembling the bundle. - Packaged as an OpenCode plugin package:
package.jsongainsmainandexportspointing atopencode/index.mjs, so the package can be named inpluginsrather than path-referenced. - Fixed: the OpenCode plugin could register a skill twice. It now adds a skill only when
OpenCode has not already discovered it in
~/.agents/skills. - Fixed (Windows):
tests/opencode.test.mjscompared a backslash-joined path against command text that used forward slashes, so the suite failed onwindows-latest. Both sides are now compared with a single separator. - Hardened: the installer's direct-invocation guard matched any path ending in
install.mjs; it now compares the basename. A byte-order mark at the start of a settings file no longer makes the merge skip silently. - Added: an OpenCode plugin (
opencode/index.mjs). It registers thewriting-flowandvoice-defaultskills, the MCP server, and the/flow-writingand/flow-doctorcommands through OpenCode's plugin API, so OpenCode no longer needs the installer's copy steps. Covered bytests/opencode.test.mjs, which runs against a fake plugin context rather than a live OpenCode. - Packaging: the repository is now an npm package.
package.jsonadds awriting-flowbin,npm test/npm run build/npm run doctorscripts, anengines: node >=22floor, and afilesallowlist that ships sources only. The installer moved tobin/and now regenerates the client shims in memory, so an npm tarball needs no dotfiles andnpx -y @adelpro/writing-flow --applyinstalls without a clone. Docs were reorganised:ROADMAP.mdmoved underdocs/, planning documents are no longer tracked (docs/superpowers/is gitignored), the unused vendored schemas were dropped, andAGENTS.mdmaps source versus generated. Three tests were added (version parity,filescoverage, and shim regeneration from a dotfile-less package). - Fixed:
generate_profileleft a freshly written profile failing its own doctor. The generatedvoice-card.mdwas written with a trailing newline the card checker does not expect, sodoctorreportedstale cardon a profile the tool itself had just created. The card is now written exactly asrenderVoiceCardproduces it - the same bytesrender_profilewrites - and a test pins the two together. - Fixed: doctor passed a profile whose files disagreed with each other. A profile's own
voice-card.mdwas never compared with itsSKILL.md, and theversion:inSKILL.mdwas never compared withwriting-profile.json, so a hand-edited profile reportedOKwhile its portable card still carried the old rules. Doctor now reports a stale card (with therender.mjs card --writecommand that fixes it) and a version mismatch. Doctor also warns, without failing the check, when lines ofSKILL.mdwould be dropped bygenerate_profileas pipeline instruction. Covered by four new tests.
0.9.1
- Reverted the Gemini CLI extension. 0.9.0 added
gemini-extension.json,GEMINI.mdand two.tomlcommands; all of it is removed. - The surface no longer exists: Gemini CLI stopped serving free, Google AI Pro and Google AI Ultra users on 18 June 2026, replaced by Antigravity CLI. What remains is enterprise licences and paid API keys.
- And Antigravity needs nothing from us: it reads Agent Plugins packages -
plugin.json+skills/+mcp.json- which is what this repository has shipped all along. The extension was supporting a retired product with a format already covered, at the cost of a hand-maintained context file and two command files. - Recorded as a revert rather than rewritten out of history, and the version moves forward so nobody sees it go backwards.
0.8.3
- Fixed: gate 5 could never work on a fresh install.
remove-ai-markskeeps its skill and its Python machinery in separate trees of the same repository -skills/remove-ai-marks/holds only SKILL.md and references, and every script lives underservice/scripts.npx skills addtherefore installed instructions with nothing to execute, so a new user gotexit 2from the gate forever. The installer now fetches the declared machinery too. Found by CI, and exactly the gap the roadmap predicted in 'never run on a machine without the dependencies'. - CI now installs through the package's own installer, so it exercises the path a user takes rather than a parallel reimplementation, and asserts both gate entry points exist before running the suite.
0.8.2
- CI went red on its first run, and it was right to. The integration job installed the dependency skills through the skills CLI, the suite passed, and the guard step failed - which means the tools had not resolved and the gate tests had silently skipped. A green run that tests nothing is the exact failure CI exists to catch. The job now installs the tools by cloning, which does not depend on the CLI detecting an installed agent, and asserts the two entry scripts exist before running anything.
0.8.1
- Documented the skills-CLI install route, verified rather than assumed: the CLI finds both skills in this repository, -a opencode installs to
~/.agents/skills, and-stakes one skill per flag. It is also now stated plainly that this installs skills and nothing else - no command, no MCP server, nopaths.json.
0.8.0
- CI. GitHub Actions: a fast hermetic job across ubuntu node 22/24 and windows node 22, plus an integration job that installs the four dependency skills so the gate is exercised against the real upstream tools. That job asserts the gate tests did not silently skip - the suite passes vacuously without the tools, which is exactly the failure a green badge would hide.
- Claude marketplace source pinned to the repository. Was
source: ./- permitted but undocumented. Now a github source derived from plugin.json's repository, so it cannot drift from the manifest. - Node floor raised to 22: 18 and 20 are end-of-life.
- README gains per-harness instructions, including the honest note that the skills are the piece to take if a client can only take one.
0.7.0
- Two gaps closed that would have made the profile advisory rather than applied. The pipeline skill never told the agent to read the resolved profile - it said which one won and left it there, so a profile could be resolved and then ignored. It now instructs reading the profiles SKILL.md and applying it.
- Learned preferences were write-only.
learn_preferenceappended tolearned-preferences.jsonand nothing ever read it.get_profilenow returnslearnedPreferences, and the skill instructs applying them and never re-litigating a recorded one. - Added ROADMAP.md: the memory plan, the release process, the known gaps in priority order, and the parked hosted-service decisions.
- README and the internal plan sanitised of machine-specific paths.
0.6.1
- The README's install section is now agent-executable, because pasting the repo link and asking an agent to install it is a primary path. It states the prerequisites (Node 18+, network, Python 3), the dry run, and — the step that was missing — the harness reload, without which the MCP server is registered but invisible.
- It also records what the installer deliberately does not do: create a profile, touch a harness it cannot find, or remove anything. The last one matters: the installer copies but never prunes, so a renamed command leaves a stale copy behind.
0.6.0
- Commands renamed:
/write→/flow-writing,/doctor→/flow-doctor. The filename is the command name, and in OpenCode's flat namespace a bare/doctorcollides with unrelated tooling (thereact-doctorskill already claims that trigger). Theflow-prefix is what keeps the pair unambiguous. - In Claude Code the plugin name is prefixed, so they read
/writing-flow:flow-writingand/writing-flow:flow-doctor— redundant there, correct in a flat namespace. - The MCP prompts keep their unprefixed names (
write,doctor): clients namespace prompts themselves, so a prefix there would double.
0.5.0
commands/doctor.md. The diagnostic entry point now exists as a native command alongsidewrite, mirroring the MCPdoctorprompt for clients that do not surface prompts.- The installer copies every file in
commands/rather than a hardcodedwrite.md, to both~/.config/opencode/commands/and the Claude plugin bundle. Adding a command no longer needs an installer edit. - The README now documents which clients read
commands/(Claude Code and Cursor do; OpenCode does not) and gives the exact steps to install the OpenCode commands by hand. It also records that the same files are/writein OpenCode and/writing-flow:writein Claude Code.
0.4.0
- MCP prompts:
writeanddoctor. The server now declares thepromptscapability and answersprompts/listandprompts/get. A prompt is user-invoked, which is the MCP counterpart of a slash command and the only portable one —commands/*.mdreaches Claude Code and Cursor, a prompt reaches any client that surfaces prompts. writetakes a requiredrequest, and unlike a static file it is computed: it names the profile active at the moment it is served, with the voice path, house-style path, languages and required skills, plus the gate command and exit contract.doctorasks for the setup to be diagnosed in plain language, with the exact fixing command.- An unknown prompt or a missing required argument is
-32602, not a crash.
0.3.0
- The repository is now a Claude Code plugin as well as an Agent Plugins 1.0.0 package.
.claude-plugin/plugin.json,.claude-plugin/marketplace.jsonand.mcp.jsonmoved to the repository root, andcommands/write.mdmoved out of the copyable bundle. Claude Code looks for its manifest at the plugin root, so the previous layout could only ever be a bundle to copy. The files stay generated frommcp.jsonandplugin.json. - Conformant Agent Plugins clients are unaffected: extra top-level directories are not
component types and must be ignored, and
.mcp.jsonis not the fixedmcp.jsonpath. - No Cursor manifest is shipped, deliberately. Cursor reads the Agent Plugins manifest
already, and
.cursor-plugin/marketplace.jsonis for multi-plugin repositories. - The installed Claude plugin bundle carries no skills — they already live in
~/.claude/skills, and a namespaced plugin copy would duplicate them.
0.2.1
- The pipeline skill now suggests a profile: when the active profile is the bundled default it
says so once and moves on, and it names
generate_profile(with the CLI fallback) as the way to create or import a voice. Bounded on purpose — a suggestion that repeats becomes nagging, and one that blocks stops the writing. Pinned by a test.
0.2.0
generate_profile: build a profile in the standard format from existing writing — aSKILL.md, a markdown file, or a directory containing one. Reports every line it would drop as pipeline instruction, previews by default, and requiresconfirm: trueto write.includeAllkeeps every line. Exposed as a seventh MCP tool and as a CLI (node skills/writing-flow/scripts/generate.mjs <source> --name <n> --out <dir>).
0.1.0
Initial release.
- Agent Plugins 1.0.0 package:
plugin.json,skills/,mcp.json. writing-flowskill: the six-stage pipeline contract, the bounded loop between the Arabic passes, the gate exit contract, and the profile resolution rule. Carries no voice and no style rules.voice-defaultskill: a neutral fallback profile, markedisDefaultso it never competes with a real profile for resolution.gate.mjs: gates 4 and 5 in Node, replacingwrite-gate.ps1. Exit contract preserved —0clean,1violation,2tool error, with a missing tool always2.profile.mjs: profile manifest parsing and three-tier resolution, with same-tier ambiguity reported rather than silently resolved.render.mjs: renders a profile from the store into a harness skill root, generates a portablevoice-card.md, and detects drift between the store and every rendered copy.resolve-paths.mjs: locates the third-party gate tools without hardcoding a path.doctor.mjs: one call reporting the effective profile, resolved tools, missing skills and drift.mcp-server.mjs: bundled local stdio MCP server exposingget_profile,manage_profile,learn_preference,run_gate,doctorandrender_profile.shims.mjs: generates the Claude Code and OpenCode client configs from the single portablemcp.json.install.mjsplusinstall.ps1/install.shshims: renders the skills into each harness root, records resolved tool paths, pulls declared dependencies with targeted installs only, and wires the MCP server and/writecommand into an existing OpenCode config.