Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
3e6151e
Align version to 0.7.0 across package.json and CHANGELOG
theclaymethod Jul 7, 2026
581f385
Fix marketplace manifest attribution and repository routing
theclaymethod Jul 7, 2026
6e6992c
Reword machine-specific notes in verify spec/contract as design intent
theclaymethod Jul 7, 2026
4749ba5
Add contributor scaffolding: CONTRIBUTING, SECURITY, issue/PR templates
theclaymethod Jul 7, 2026
ed4f5c4
integrity: replace Function()-eval with a safe literal parser
theclaymethod Jul 7, 2026
5949b8e
Patch vite advisory via npm audit fix
theclaymethod Jul 7, 2026
cda3a0a
SKILL: make the installed skill self-locating for the export pipeline
theclaymethod Jul 7, 2026
e218212
verify: make Chromium fallback path portable across platforms
theclaymethod Jul 7, 2026
572e97b
integrity: add malicious-literal regression fixtures with a canary
theclaymethod Jul 7, 2026
e6154ec
plan 009 step 1: re-route MDX flows off legacy-html.md
theclaymethod Jul 7, 2026
c30c23e
matrix: strip OPENROUTER_API_KEY from all spawned child processes
theclaymethod Jul 7, 2026
cd8f930
plan 009 step 2: add scope statement to legacy-html.md
theclaymethod Jul 7, 2026
191dd53
export/matrix: clean up temp dirs on every exit path
theclaymethod Jul 7, 2026
bb55e1b
plan 009 step 3: de-duplicate mono-industrial spec
theclaymethod Jul 7, 2026
de3c8c5
ve:check: exercise export-static.mjs and assert rendered content is n…
theclaymethod Jul 7, 2026
59ee9dd
evals: assert catalog/fixture parity for deterministic checks
theclaymethod Jul 7, 2026
2ff5dc3
scripts: add manifest version/repository consistency check
theclaymethod Jul 7, 2026
dc9c71d
package: declare Node >=22 engines requirement, add .nvmrc
theclaymethod Jul 7, 2026
8934faf
plan 009 step 4: template status ledger
theclaymethod Jul 7, 2026
7580420
ci: add GitHub Actions workflow (static + evals jobs)
theclaymethod Jul 7, 2026
bc33d61
evals: add clean-rich-page fixture (DiagramCanvas+DiffBlock+JsonTree+…
theclaymethod Jul 7, 2026
05eca8b
Merge branch 'advisor/002-safe-literal-parse' into worktree-agent-af4…
theclaymethod Jul 7, 2026
7eaa9d0
plan 007 step 1-2: design note — execution-path map + stub-judge reco…
theclaymethod Jul 7, 2026
72c0fe4
security: network-isolate verifier/PDF-exporter Chromium and harden g…
theclaymethod Jul 7, 2026
96f6be0
plan 007 step 3: rubric fixture runner for the first 6-check slice
theclaymethod Jul 7, 2026
a1ce1a5
plan 007 step 5: track the remaining 24 uncovered llm-pass/transcript…
theclaymethod Jul 7, 2026
6f02ccf
Extract diagram layout engine into diagram-layout.ts
theclaymethod Jul 7, 2026
a3b25cd
Add node:test unit tests for the extracted diagram layout engine
theclaymethod Jul 7, 2026
dce456c
ve:check: assert the 17-component roster stays in sync across sources
theclaymethod Jul 7, 2026
2ce6b8c
verify: gate split-bleed check on authoring markup, not raw bundle text
theclaymethod Jul 7, 2026
d6501c8
slides: implement a real autofit floor and reconcile the check with r…
theclaymethod Jul 7, 2026
14883cf
slides: fix light/accent-tone contrast at the token layer
theclaymethod Jul 7, 2026
1349eaf
evals: land clean-rich-slides fixture proving the slides path verifie…
theclaymethod Jul 7, 2026
558a887
verify: reconcile split-bleed applies_when text with the fixed gate
theclaymethod Jul 7, 2026
5909163
Merge branch 'advisor/005-network-isolation' into advisor/integration
theclaymethod Jul 7, 2026
a2e17ad
Merge branch 'advisor/007-rubric-fixtures' into advisor/integration
theclaymethod Jul 7, 2026
2e83ed7
Merge branch 'advisor/009-legacy-quarantine' into advisor/integration
theclaymethod Jul 7, 2026
a1d96b0
integration: allowlist the pinned Mermaid runtime in network isolation
theclaymethod Jul 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
"description": "Generate beautiful HTML pages for diagrams, diff reviews, plan reviews, slides, and data tables",
"version": "0.7.0",
"author": {
"name": "nicobailon"
"name": "Clayton Kim"
},
"repository": "https://github.com/nicobailon/visual-explainer",
"repository": "https://github.com/theclaymethod/artifacture",
"license": "MIT",
"keywords": [
"diagrams",
Expand Down
33 changes: 33 additions & 0 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Bug report
description: Report a problem with Artifacture
labels: ["bug"]
body:
- type: textarea
id: what-happened
attributes:
label: What happened
description: What did you expect, and what did you get instead?
validations:
required: true
- type: input
id: command
attributes:
label: Exact command
description: The exact command you ran (e.g. `npm run ve:export -- ...`).
placeholder: npm run ve:export -- src/diagram.mdx --out out.html
validations:
required: true
- type: checkboxes
id: attachment
attributes:
label: Attachment
options:
- label: I attached the generated artifact and/or MDX/TSX source that reproduces this.
- type: textarea
id: envinfo
attributes:
label: Environment
description: Output of `npx envinfo --system --binaries --npmPackages artifacture`.
render: shell
validations:
required: true
10 changes: 10 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## Checklist

- [ ] `npm run ve:check` passes.
- [ ] `npm run ve:eval` passes.
- [ ] If this PR adds a check, I added a seeded violation fixture and an
`evals/expectations.json` entry for it.
- [ ] If this PR adds a component, I updated `SKILL.md` and the
`sharedComponents` set in `scripts/ve-mdx/integrity.mjs`.

## What does this change and why?
36 changes: 36 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: CI

on:
push:
branches: [main]
pull_request:

jobs:
static:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: npm
- run: npm ci
- run: npm run ve:check-integrity
# Plan 004 (release hygiene) landed before this workflow was written,
# so all manifest version sources already agree — this job is
# blocking rather than continue-on-error, per that plan's guidance to
# flip it once versions are consistent. See plan 003 NOTES.
- run: npm run check:manifests
- run: npm run ve:check

evals:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: npm
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npm run ve:eval
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## [0.7.0] - 2026-07-04

### Changed
- Renamed to Artifacture; published as a standalone repo (github.com/theclaymethod/artifacture).
- MDX/React source-first pipeline with 17 shared components and build-time Shiki.
- ve-verify: 207-check deterministic design gate with seeded-violation eval suite.
- Multi-model eval harness (evals/model-matrix) with blind acuity judging.
- Tiered agent docs: SKILL.md + per-flow cards.

## [0.6.3] - 2026-03-09

### Documentation
Expand Down
50 changes: 50 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Contributing

## Dev setup

- Node >= 22.
- `npm ci`
- `npx playwright install chromium`. The verifier's browser stage uses
`playwright-core`, which never downloads browsers itself.
- `npm run ve:eval`. If it exits green, your environment is working.

## Adding a check

`ve-verify` is a deterministic design-quality gate driven by
`plugins/visual-explainer/scripts/verify/checks.json` (a list of check
objects with `id`, `family`, `severity`, `spec`, etc.). To add one:

1. Add an entry to `checks.json` with a unique `id`.
2. Implement the check logic wherever the matching stage/family lives in
`plugins/visual-explainer/scripts/verify/`.
3. Add a seeded violation fixture at
`evals/fixtures/violations/<check-id>.html` that trips the new check and
nothing else.
4. Add the fixture's expected result to `evals/expectations.json`.
5. Run `npm run ve:eval` and confirm the new fixture is caught.

## Adding a shared component

1. Export the component from `visual-explainer-mdx/components.tsx`.
2. Add its name to the `sharedComponents` set in
`scripts/ve-mdx/integrity.mjs:4-22` (strict-export integrity checks
against this list).
3. Add it to the component list in `plugins/visual-explainer/SKILL.md`.
4. Run `npm run ve:check` to confirm export integrity holds.

## Adding a preset

Presets are semantic-token layers in `visual-explainer-mdx/global.css`,
selected via `data-ve-preset="<name>"` on the root. Add a new
`[data-ve-preset="<name>"] { ... }` block that sets the same semantic
tokens the existing presets set (mono-industrial, nothing, blueprint,
editorial, paper-ink, terminal, custom) — don't introduce new token names.

## Before you open a PR

- `npm run ve:check` must pass.
- `npm run ve:eval` must pass.
- If you touched or generated an HTML artifact, run the verifier on it
(`node plugins/visual-explainer/scripts/verify/ve-verify.mjs <artifact.html>`)
and fix any error-severity failures.
- Follow the checklist in the PR template.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ Any agent with skills support (Claude Code, Codex, Cursor, and others), via the
npx skills add theclaymethod/artifacture
```

First generation clones the render pipeline to `~/.artifacture` (one-time,
Node >= 22); full-clone installs use the repo in place.

**Claude Code, as a plugin:**

```bash
Expand Down
14 changes: 14 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Security Policy

## Reporting a vulnerability

Report vulnerabilities privately through GitHub Security Advisories on
[theclaymethod/artifacture](https://github.com/theclaymethod/artifacture/security/advisories/new).
Do not open a public issue for security reports.

Include what you found, how to reproduce it, and the affected version.

## What to expect

There is no bounty program. We ask for a 90-day disclosure courtesy window
before any public write-up, so a fix can ship first.
25 changes: 25 additions & 0 deletions evals/fixtures/clean/clean-rich-page.html

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions evals/fixtures/clean/clean-rich-slides.html

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions evals/fixtures/rubrics/deck-content-completeness/clean.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"context": "Every source section, decision card, and table row has a corresponding slide; two short bullets were legitimately consolidated into one.",
"judge_response": {
"pass": true,
"findings": []
}
}
13 changes: 13 additions & 0 deletions evals/fixtures/rubrics/deck-content-completeness/fire.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"context": "Source document has 7 decision cards; the deck's extracted text only covers 4 of them.",
"judge_response": {
"pass": false,
"findings": [
{
"check_id": "deck-content-completeness",
"evidence": "source table rows 'Rollback policy', 'On-call rotation', and 'Data retention window' have no corresponding slide heading, bullet, or card text anywhere in the extracted deck text",
"fix": "Add slides (or fold into existing slides with explicit callouts) for the 3 missing decision items, or note the intentional exclusion."
}
]
}
}
7 changes: 7 additions & 0 deletions evals/fixtures/rubrics/diagram-type-coherent/clean.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"context": "Figure screenshot is a single hand-authored flow diagram, one shape vocabulary throughout.",
"judge_response": {
"pass": true,
"findings": []
}
}
13 changes: 13 additions & 0 deletions evals/fixtures/rubrics/diagram-type-coherent/fire.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"context": "Figure screenshot mixes swimlane lanes with a nested-containment metaphor in one canvas.",
"judge_response": {
"pass": false,
"findings": [
{
"check_id": "diagram-type-coherent",
"evidence": "figure 1 screenshot: left half draws horizontal swimlanes, right half draws nested containment boxes for the same data — reads as two diagram types glued together",
"fix": "Pick one diagram type (swimlane or nested-containment) for the whole figure and redraw the other half to match."
}
]
}
}
7 changes: 7 additions & 0 deletions evals/fixtures/rubrics/fixed-ui-obscures-content/clean.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"context": "390x844 screenshot shows the fixed theme toggle in a corner with no overlap onto readable or clickable content.",
"judge_response": {
"pass": true,
"findings": []
}
}
13 changes: 13 additions & 0 deletions evals/fixtures/rubrics/fixed-ui-obscures-content/fire.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"context": "390x844 screenshot shows a floating theme toggle covering the page title.",
"judge_response": {
"pass": false,
"findings": [
{
"check_id": "fixed-ui-obscures-content",
"evidence": "390-light screenshot: fixed theme-toggle button overlaps the top third of the h1 title text, making it unreadable",
"fix": "Reposition the fixed toggle away from primary content, or add safe-area padding to the title block."
}
]
}
}
7 changes: 7 additions & 0 deletions evals/fixtures/rubrics/preset-both-mode-visual/clean.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"context": "Paired light and dark full-page screenshots both invert cleanly with no leftover wrong-mode fills.",
"judge_response": {
"pass": true,
"findings": []
}
}
13 changes: 13 additions & 0 deletions evals/fixtures/rubrics/preset-both-mode-visual/fire.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"context": "A Mono page where one section's background stays dark in light mode because its fill was hard-coded.",
"judge_response": {
"pass": false,
"findings": [
{
"check_id": "preset-both-mode-visual",
"evidence": "light screenshot: the 'Status' card panel keeps a #0b0d10 dark background while the rest of the page is on the light token set, reading as a broken invert",
"fix": "Replace the hard-coded background with the theme token so it participates in the light/dark swap."
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"segments": [
{ "start": 0.0, "end": 2.2, "text": "Our engine cuts p99 latency in half." }
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"words": [
{ "text": "Our", "start": 0.0, "end": 0.2 },
{ "text": "engine", "start": 0.2, "end": 0.6 },
{ "text": "cuts", "start": 0.6, "end": 0.9 },
{ "text": "p99", "start": 0.9, "end": 1.2 },
{ "text": "latency", "start": 1.2, "end": 1.7 },
{ "text": "in", "start": 1.7, "end": 1.8 },
{ "text": "half", "start": 1.8, "end": 2.2 }
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"segments": [
{ "start": 0.0, "end": 2.2, "text": "We speed up queries" }
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"words": [
{ "text": "Our", "start": 0.0, "end": 0.2 },
{ "text": "engine", "start": 0.2, "end": 0.6 },
{ "text": "cuts", "start": 0.6, "end": 0.9 },
{ "text": "p99", "start": 0.9, "end": 1.2 },
{ "text": "latency", "start": 1.2, "end": 1.7 },
{ "text": "in", "start": 1.7, "end": 1.8 },
{ "text": "half", "start": 1.8, "end": 2.2 }
]
}
7 changes: 7 additions & 0 deletions evals/fixtures/rubrics/text-visibly-clipped/clean.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"context": "390x844 light/dark screenshots show all headings and body text fully visible with normal line wrapping.",
"judge_response": {
"pass": true,
"findings": []
}
}
13 changes: 13 additions & 0 deletions evals/fixtures/rubrics/text-visibly-clipped/fire.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"context": "390x844 light/dark screenshots show a mobile heading losing its final word at the right edge with no ellipsis.",
"judge_response": {
"pass": false,
"findings": [
{
"check_id": "text-visibly-clipped",
"evidence": "390-light screenshot: heading 'Architect...' chopped mid-word by the hero container's overflow:hidden edge, no ellipsis present",
"fix": "Add text-overflow: ellipsis or increase container width/line-height so the heading is not chopped mid-character."
}
]
}
}
3 changes: 2 additions & 1 deletion evals/model-matrix/gallery.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ function escapeHtml(value) {
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('"', '&quot;');
.replaceAll('"', '&quot;')
.replaceAll("'", '&#39;');
}

if (import.meta.url === `file://${process.argv[1]}`) {
Expand Down
Loading
Loading