Skip to content

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 --agents scopes every surface, not just the skills.
  • Added: a profile store, searched before the default. ~/.agents/writing-flow/profiles is checked before falling back to the bundled voice-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 as PASS 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_gate takes a file path, so the flow degrades into an improvised order and an ungated result. The write prompt 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/skills got 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-code included; 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 PATH but does not run — is named at install time rather than discovered later as a bare exit 2, and the message carries the --skip-marks escape. 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.
  • probePython now verifies the candidate runs (python --version) instead of trusting where/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.mjs called the installer with the real dependency list and no dry run, so every test run performed a live git clone.
  • Changed: every harness is now installed through its own native mechanism. bin/install.mjs no longer copies what a harness can fetch itself. Claude Code gets the marketplace plugin (extraKnownMarketplaces + enabledPlugins in ~/.claude/settings.json); OpenCode gets the package plugin (@adelpro/writing-flow in the plugins array); every other detected agent gets the two skills through the skills CLI. The hand-assembled ~/.claude/plugins/writing-flow bundle, the ~/.config/opencode/commands/ copies, the merged mcp.writing-flow entry and the generated shims/opencode/mcp.opencode.json fragment 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.mjs from a bundle that deliberately ships no skills/. 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.json gains main and exports pointing at opencode/index.mjs, so the package can be named in plugins rather 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.mjs compared a backslash-joined path against command text that used forward slashes, so the suite failed on windows-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 the writing-flow and voice-default skills, the MCP server, and the /flow-writing and /flow-doctor commands through OpenCode's plugin API, so OpenCode no longer needs the installer's copy steps. Covered by tests/opencode.test.mjs, which runs against a fake plugin context rather than a live OpenCode.
  • Packaging: the repository is now an npm package. package.json adds a writing-flow bin, npm test / npm run build / npm run doctor scripts, an engines: node >=22 floor, and a files allowlist that ships sources only. The installer moved to bin/ and now regenerates the client shims in memory, so an npm tarball needs no dotfiles and npx -y @adelpro/writing-flow --apply installs without a clone. Docs were reorganised: ROADMAP.md moved under docs/, planning documents are no longer tracked (docs/superpowers/ is gitignored), the unused vendored schemas were dropped, and AGENTS.md maps source versus generated. Three tests were added (version parity, files coverage, and shim regeneration from a dotfile-less package).
  • Fixed: generate_profile left a freshly written profile failing its own doctor. The generated voice-card.md was written with a trailing newline the card checker does not expect, so doctor reported stale card on a profile the tool itself had just created. The card is now written exactly as renderVoiceCard produces it - the same bytes render_profile writes - and a test pins the two together.
  • Fixed: doctor passed a profile whose files disagreed with each other. A profile's own voice-card.md was never compared with its SKILL.md, and the version: in SKILL.md was never compared with writing-profile.json, so a hand-edited profile reported OK while its portable card still carried the old rules. Doctor now reports a stale card (with the render.mjs card --write command that fixes it) and a version mismatch. Doctor also warns, without failing the check, when lines of SKILL.md would be dropped by generate_profile as pipeline instruction. Covered by four new tests.

0.9.1

  • Reverted the Gemini CLI extension. 0.9.0 added gemini-extension.json, GEMINI.md and two .toml commands; 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-marks keeps 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 under service/scripts. npx skills add therefore installed instructions with nothing to execute, so a new user got exit 2 from 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 -s takes one skill per flag. It is also now stated plainly that this installs skills and nothing else - no command, no MCP server, no paths.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_preference appended to learned-preferences.json and nothing ever read it. get_profile now returns learnedPreferences, 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 /doctor collides with unrelated tooling (the react-doctor skill already claims that trigger). The flow- prefix is what keeps the pair unambiguous.
  • In Claude Code the plugin name is prefixed, so they read /writing-flow:flow-writing and /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 alongside write, mirroring the MCP doctor prompt for clients that do not surface prompts.
  • The installer copies every file in commands/ rather than a hardcoded write.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 /write in OpenCode and /writing-flow:write in Claude Code.

0.4.0

  • MCP prompts: write and doctor. The server now declares the prompts capability and answers prompts/list and prompts/get. A prompt is user-invoked, which is the MCP counterpart of a slash command and the only portable one — commands/*.md reaches Claude Code and Cursor, a prompt reaches any client that surfaces prompts.
  • write takes a required request, 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.
  • doctor asks 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.json and .mcp.json moved to the repository root, and commands/write.md moved 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 from mcp.json and plugin.json.
  • Conformant Agent Plugins clients are unaffected: extra top-level directories are not component types and must be ignored, and .mcp.json is not the fixed mcp.json path.
  • No Cursor manifest is shipped, deliberately. Cursor reads the Agent Plugins manifest already, and .cursor-plugin/marketplace.json is 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 — a SKILL.md, a markdown file, or a directory containing one. Reports every line it would drop as pipeline instruction, previews by default, and requires confirm: true to write. includeAll keeps 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-flow skill: 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-default skill: a neutral fallback profile, marked isDefault so it never competes with a real profile for resolution.
  • gate.mjs: gates 4 and 5 in Node, replacing write-gate.ps1. Exit contract preserved — 0 clean, 1 violation, 2 tool error, with a missing tool always 2.
  • 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 portable voice-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 exposing get_profile, manage_profile, learn_preference, run_gate, doctor and render_profile.
  • shims.mjs: generates the Claude Code and OpenCode client configs from the single portable mcp.json.
  • install.mjs plus install.ps1 / install.sh shims: renders the skills into each harness root, records resolved tool paths, pulls declared dependencies with targeted installs only, and wires the MCP server and /write command into an existing OpenCode config.