Skip to content

Releases: artfusion/ccgrapher

v0.5.0 — the picture becomes evidence

Choose a tag to compare

@artfusion artfusion released this 09 Sep 13:10
b42eca8

The graph has always been the argument. Up to now it only travelled as a fixed-size PNG — unreadable past a handful of nodes, and useless for showing the drift between what a spec declared and what a run actually did. This release closes both gaps.

Zoomable, everywhere the picture goes

ccg render examples/research-desk.yaml -o diagram.html

The same hand-drawn SVG, wrapped in a self-contained page: cursor-anchored wheel zoom, drag to pan, no CDN, no server. It opens as a chat attachment or a browser tab and stays legible at any size.

The audit learns the graph, not only the capabilities

ccg trace audit already held a run against the capabilities its spec declared. It now holds the run against the spec's nodes and edges too:

  • NODE_NEVER_RAN — a declared node with no evidence it ran in any matched run.
  • UNDECLARED_NODE — a node_started for an id the spec doesn't know.
  • ORDER_VIOLATION — a node started before its declared predecessor finished, though the spec says it should wait. The strongest of the four: it means the graph's core promise wasn't honoured.
  • OBSERVED_SERIALISATION — two nodes with no declared path between them that consistently never overlap across several runs. A candidate hidden edge, backed by evidence rather than a guess.

HIDDEN_EDGE stops missing cross-layer collisions

The rule used to compare nodes on the same layout rank only, on the assumption that rank meant "runs at the same time." True for ccg run and every codegen target, which both execute a rank behind a barrier — not true in general. It now compares every pair of nodes with no declared path between them, wherever they land.

Also in this release

  • render-excalidraw's README says how to open the file it produces (excalidraw.com, or the VS Code extension) and that edits made there don't write back to the spec.

@ccgrapher/web (private, unpublished) moves to 0.4.0 alongside this: a static export, a spec carried in the URL fragment, and a read-only viewer mode, now live at ccgrapher.artfusion.com/app.

apps/web v0.4.0 — the canvas gets a URL

Choose a tag to compare

@artfusion artfusion released this 09 Sep 13:11
b42eca8

The canvas has had cursor-anchored zoom and live lint since the JointJS move — the one thing it never had was a URL. This release gets it one, without a new subdomain or a server.

  • next build now produces a static export. Nothing about how the app runs changed; it has always been client-only.
  • A spec carried in the URL fragment (#spec=<base64>) loads directly and switches the page into a read-only viewer: the example dropdown, file picker, and YAML textarea hide, and the repair toggle and live-run bar stay. A fragment never reaches a server log, and needs no CORS.
  • Deployed at ccgrapher.artfusion.com/app — a subdirectory of the existing marketing site, basePath: "/app" doing the rewriting. A two-level subdomain turned out not to be provisionable on the current host; this reuses infrastructure already proven to work.

No published @ccgrapher/* package changed — this app stays private and unpublished.

apps/web v0.3.0 — the canvas learns to move under you

Choose a tag to compare

@artfusion artfusion released this 31 Aug 13:03
f82b769

Not a package release. Nothing under packages/* changed since v0.4.0 beyond
test files, so the npm train stays at 0.4.0 and this tag, like apps-web-v0.2.0
before it, sits outside it. It marks what the canvas gained since the JointJS
migration.

What's new

Mouse-wheel zoom and drag-to-pan. The canvas stopped being a fixed window.
Scroll to zoom around the pointer, drag empty space to pan. Nodes still cannot
be moved by hand, and that is not an omission: the picture remains a consequence
of the in:/out: declarations.

Open a spec file directly into the canvas. Point the editor at a spec on
disk and it loads straight in, rather than starting from the built-in example
and pasting over it.

Also

jsdom smoke tests for the editor, and direct coverage for the graph model, so
the two bugs the JointJS migration surfaced now have the kind of tests that
would have caught them.

Upgrading

Nothing to change for the CLI or any published package; none of them moved.

pnpm --filter @ccgrapher/web dev

There is now a CHANGELOG
covering every release to date.

apps/web v0.2.0 — the canvas moves to JointJS

Choose a tag to compare

@artfusion artfusion released this 10 Aug 08:58
091ed62

Not a package release — nothing under packages/* changed, and apps/web stays private and
unpublished, so this tag sits outside the npm-publishable vX.Y.Z train. It marks a real
milestone for the canvas on its own.

What moved

The web canvas was React Flow. It's JointJS now — same picture, same overlays (run state, heat,
capability), same lint findings. core, lint and layout haven't changed, so nothing here
touches what the CLI computes or reports.

What's new

Every node's declared in:/out: fields are real ports now, not one anonymous handle per node.
Drag a link from one port to another and the edge lints as you draw — the field it carries is
written straight back into the YAML pane, and a spec problem it creates (a fan-in with no
expects guard, say) shows up in the findings list immediately, the same way editing the YAML
directly always has.

Dragging a node does nothing to the spec. The picture is a consequence of the in:/out:
declarations, never something a human moved — only a connection is a real edit.

Two bugs the migration surfaced, not two features

Both were caught live, with a real drag, not by a type checker:

  • A brand-new link's source/target are set at construction, which JointJS/Backbone doesn't
    treat as a "change" — so the first pass at wiring this up watched for change events and never
    saw a new connection land. Fixed by also watching for the link itself being added.
  • Watching that event synchronously turned up a second bug: the canvas seeds its graph one
    cell at a time on load, and reading the link list from inside the very first add event in
    that burst caught the graph mid-seed — briefly wiping edges: in the YAML pane on every fresh
    load. Fixed by batching the read to run once the seed has actually settled.

Upgrading

Nothing to change if you're using the CLI, or any of the published packages — this release
doesn't touch them.

pnpm --filter @ccgrapher/web dev

v0.4.0 — the runtime stops being opaque

Choose a tag to compare

@artfusion artfusion released this 07 Aug 19:52
6cc6518

A workflow spec has always said what each step reads and writes. It has never said what the step needed to exist around it — an MCP server, a skill, a plugin, another agent. When one of those is missing, a run does not stop. It quietly does something worse and reports success.

This release makes that auditable.

Declaring

A node can say what it depends on:

- id: research
  kind: worker
  uses: ["mcp:search/query", "skill:house-style"]

Opaque, namespaced ids. What counts as a capability belongs to the runtime, not to the schema.

Reporting

Three new trace events, additive within v: 1. capability_available and capability_lost are run-scoped, because whether a thing exists is a fact about the environment rather than about any one step. capability_invoked carries an optional node: a runner knows which node called, an adapter watching a live session knows only that a tool was used, and a contract demanding a node id would have excluded the second while calling itself general.

ccg run emits them natively. @ccgrapher/adapter-claude-code is new, and turns a Claude Code session into the same trace through its hooks, so the tools an agent actually reached for become a run you can serve, read and audit like any other.

Auditing

ccg trace audit runs/my-run.jsonl --spec spec.yaml

CAPABILITY_GAP when a node ran while something it declares was reported gone. UNUSED_CAPABILITY when a node ran and never reached for what it declares. UNDECLARED_CAPABILITY when something was used that was never declared. Exit 0 clean or warnings, 1 on an error, 2 on bad usage. The six lint rules stay six: an audit finding needs a run as well as a spec.

What it refuses to say

Two rules run through all of it, and they are the point rather than a detail.

A capability nothing reported on is unknown, never missing. A gap needs positive evidence that something went away. And UNUSED_CAPABILITY stays quiet unless the run reported at least one invocation somewhere, because a producer that never reports them has not told you a declaration went unused, it has told you nothing.

An audit is only honest about the run it was given. A trace records which spec it came from. One naming a different spec is left out and reported; a file where every run names a different spec is bad usage rather than a report. Two unrelated workflows need only share a node name to appear to disagree, and that finding would be confident, specific and false. A run that recorded no spec at all is audited anyway: it made no claim to contradict, and refusing it would be the same error pointed the other way.

Also

The SSE transport now forwards event types it has never heard of, with their sequence numbers intact, so they survive a reconnect. The contract promised additive-only within v: 1 and the transport quietly broke that promise one layer below where it was made.

Upgrading

Nothing to change. uses: is optional, the events are additive, and a spec carrying capabilities still parses under older tools, which strip the field. An older reader folds the new events as no update.

npx @ccgrapher/cli lint <spec.yaml>

v0.3.1 — a mistyped flag stops looking like a failing check

Choose a tag to compare

@artfusion artfusion released this 07 Aug 10:31
251ba3e

A patch release with one fix in it, worth shipping on its own.

Fixed

An unknown flag printed a Node stack trace and exited 1. Exit 1 is the code that means the workflow has lint errors, so a typo in a flag was indistinguishable from a failing check to anything reading exit codes, which is precisely what CI does. The unknown-command path exited 2 correctly all along, so the two halves of the same documented contract disagreed with each other.

$ ccg lint plan.yaml --nope
ccg lint: unknown option '--nope'
Run `ccg --help` for usage.

Exit 2, matching the README, and no stack trace. Every command parses through the same wrapper now, so all of them agree rather than one of them being fixed.

--help after a subcommand prints usage and exits 0 instead of being rejected. Asking for help is never bad usage.

Upgrading

Nothing to change. Same API, same flags, same output on every path that already worked.

npx @ccgrapher/cli lint <spec.yaml>

v0.3.0 — retro, dataflow edge recovery, and the trace contract

Choose a tag to compare

@artfusion artfusion released this 02 Aug 13:17
1a2f755

Eleven packages move together. @ccgrapher/web stays private and unpublished.

What is new

ccg retro <owner/repo> rebuilds the as-merged workflow from a repository pull request history, with edges only where two changes touched the same files. Point it at a repository and it draws what the work actually was, without anyone writing a spec. The first live run on this repository went from fifteen layers to five.

@ccgrapher/trace is a new package: a versioned JSONL event contract and the reducer that folds it back into state. It is additive-only within v: 1, and treated as a compatibility surface rather than an internal detail.

@ccgrapher/runner executes a graph. ccg run walks a spec and writes a trace, and ccg serve streams that trace over SSE in a way that survives a dropped connection.

Ingest now recovers edges from dataflow rather than variable names, which is the difference between a round-trip validator for our own output and something you can point at a stranger's code. It also warns when nodes parse but no dependency does, instead of quietly drawing an edgeless graph.

One expects rule across three runtimes. There were three implementations and two different comparisons. The guard is now a floor everywhere.

Fixed

A release path that would have shipped ten of eleven packages without saying so. tools/publish.sh kept a hand-maintained list, and a new package missing from it published nothing, printed a success, and surfaced later as an install that could not resolve. The script now refuses to run while any non-private workspace package is absent from the list.

Install

npx @ccgrapher/cli lint <spec.yaml>
npx @ccgrapher/cli retro your-org/your-repo --lint

Known issue

--help after a subcommand, as in ccg retro --help, exits 1 with a Node stack trace instead of printing usage. Use ccg --help for now.

v0.2.0 — plan, and a Claude Code skill

Choose a tag to compare

@artfusion artfusion released this 30 Jul 21:20

First public release. A linter for agent workflows, and a Claude Code skill that
makes an agent apply it to its own plans before executing them.

The skill

git clone https://github.com/artfusion/ccgrapher.git
ln -s "$PWD/ccgrapher/skills/parallel-plan" ~/.claude/skills/parallel-plan

Before executing a plan of five steps or more, the agent checks which steps
actually depend on each other and runs the independent ones concurrently.

ccg plan

lint says what is wrong with a workflow; plan says how to run it.

wave 1               scope
wave 2  ×6 together  pr_hotfix, pr_landing, pr_new_site, pr_pricing, pr_byok, pr_compare
wave 3  ×3 together  pr_credits, pr_copy, pr_links
wave 4               ci
wave 5               release

5 waves for 12 steps — 7 fewer than doing them one at a time

Without --fix it reports the shape as written and says how much of that is
fake, so the number is never quietly flattering. --json for tooling.

Also in this release

  • Six lint rules with a two-pass repair pipeline — repairs repoint to the
    nearest supplier rather than deleting, which would leave a step starting
    before its real dependency.
  • Four render targets: hand-drawn SVG, Mermaid, Excalidraw, plus the web canvas.
  • Codegen for Claude Code workflows, plain TypeScript and LangGraph.
  • ingest — ts-morph reads existing orchestration code back into a spec.
    Round-trip is lossless and asserted for every fixture.
  • examples/release-session.yaml — nine pull requests shipped one after
    another. Six were never waiting on anything.

Install

npx @ccgrapher/cli lint your-workflow.yaml

250 tests, CI on Node 22 and 24. Apache-2.0.

Note: 0.1.0 on npm is deprecated and broken — it shipped with the
workspace: protocol unresolved. Use 0.2.0.