Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "papervizagent",
"version": "0.3.0",
"version": "0.4.0",
"description": "Scientific figures with upstream PaperVizAgent, separate roles, configurable model providers and Codex subscription fallback. Host-native defaults where tools are available.",
"author": {
"name": "GoatInAHat"
Expand Down Expand Up @@ -57,7 +57,7 @@
"command": "uvx",
"args": [
"--from",
"papervizagent==0.3.0",
"papervizagent==0.4.0",
"papervizagent",
"mcp"
],
Expand Down
2 changes: 1 addition & 1 deletion .codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "papervizagent",
"version": "0.3.0",
"version": "0.4.0",
"description": "Scientific figures with upstream PaperVizAgent, separate roles, configurable model providers and Codex subscription fallback. Host-native defaults where tools are available.",
"author": {
"name": "GoatInAHat"
Expand Down
2 changes: 1 addition & 1 deletion .cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "papervizagent",
"version": "0.3.0",
"version": "0.4.0",
"description": "Scientific figures with upstream PaperVizAgent, separate roles, configurable model providers and Codex subscription fallback. Host-native defaults where tools are available.",
"author": {
"name": "GoatInAHat"
Expand Down
21 changes: 21 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,24 @@ dist
web/dist
.env
.env.*

# tf:dockerignore
.git/
.env
.env.*
!.env.example
node_modules/
**/node_modules/
.venv/
**/.venv/
dist/
coverage/
test-results/
playwright-report/
.pytest_cache/
.mypy_cache/
.ruff_cache/
__pycache__/
**/__pycache__/
.vscode-test/
# /tf:dockerignore
8 changes: 5 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ permissions:
jobs:
test:
runs-on: ubuntu-latest
env:
TOOLFACTORY_SYSTEM_NATIVE_JOBS: "true"
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
Expand Down Expand Up @@ -42,15 +44,15 @@ jobs:
- name: Install core into Hermes
run: uv pip install --python "$HOME/.hermes/hermes-agent/venv/bin/python" --editable .
- name: toolfactory check
run: npx --yes toolfactory@0.1.2 check
run: npx --yes toolfactory@0.2.1 check
- name: toolfactory build (output files)
run: npx --yes toolfactory@0.1.2 build
run: npx --yes toolfactory@0.2.1 build
- name: Install Claude Code CLI
run: npm i -g @anthropic-ai/claude-code
- name: Install Chromium dependencies
run: npx --yes playwright install-deps chromium
- name: toolfactory validate
run: npx --yes toolfactory@0.1.2 validate
run: npx --yes toolfactory@0.2.1 validate
- name: author tests
run: uv run --with pytest pytest -q
- name: openclaw end-to-end (scripted model, no LLM key)
Expand Down
59 changes: 34 additions & 25 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Adopted from ToolFactory 0.1.2 for workflow permissions and container inputs.
# Adopted from ToolFactory 0.2.1 for workflow permissions and container inputs.
# `gate` decides once which registries this tag can publish to (a job-level `if` cannot read
# secrets) and every leg obeys its output, so a tag with no secrets is still green: gate,
# package, the Release, and whatever else applies. After adding a secret, re-run with
Expand Down Expand Up @@ -93,15 +93,15 @@ jobs:
- name: Install core into Hermes
run: uv pip install --python "$HOME/.hermes/hermes-agent/venv/bin/python" --editable .
- name: toolfactory check
run: npx --yes toolfactory@0.1.2 check
run: npx --yes toolfactory@0.2.1 check
- name: toolfactory build (output files)
run: npx --yes toolfactory@0.1.2 build
run: npx --yes toolfactory@0.2.1 build
- name: Install Claude Code CLI
run: npm i -g @anthropic-ai/claude-code
- name: Install Chromium dependencies
run: npx --yes playwright install-deps chromium
- name: toolfactory validate
run: npx --yes toolfactory@0.1.2 validate
run: npx --yes toolfactory@0.2.1 validate
- name: author tests
run: uv run --with pytest pytest -q
- name: openclaw end-to-end (scripted model, no LLM key)
Expand Down Expand Up @@ -158,7 +158,7 @@ jobs:
- name: install
run: uv sync
- name: toolfactory build (output files)
run: npx --yes toolfactory@0.1.2 build
run: npx --yes toolfactory@0.2.1 build
- name: web build
run: npm -C web ci && npm -C web run build
env:
Expand All @@ -178,11 +178,20 @@ jobs:
- name: web tarball
run: tar -czf dist/release/papervizagent-web.tar.gz -C web/dist .
- name: browser extension zips
run: npm --prefix hosts/browser install && npm --prefix hosts/browser exec --no -- wxt zip hosts/browser -b chrome && npm --prefix hosts/browser exec --no -- wxt zip hosts/browser -b firefox && npm --prefix hosts/browser exec --no -- wxt zip hosts/browser -b edge && cp hosts/browser/.output/papervizagent-0.3.0-chrome.zip dist/release/ && cp hosts/browser/.output/papervizagent-0.3.0-firefox.zip dist/release/ && cp hosts/browser/.output/papervizagent-0.3.0-edge.zip dist/release/ && cp hosts/browser/.output/papervizagent-0.3.0-sources.zip dist/release/
working-directory: hosts/browser
run: |-
npm install
npm exec --no -- wxt zip -b chrome
npm exec --no -- wxt zip -b firefox
npm exec --no -- wxt zip -b edge
cp .output/papervizagent-0.4.0-{chrome,firefox,edge,sources}.zip ../../dist/release/
cd ../..
git archive --format=zip --output=dist/release/papervizagent-0.4.0-sources.zip HEAD
zip -q dist/release/papervizagent-0.4.0-sources.zip web/src/ops.json
- name: Firefox signed xpi (only when FIREFOX_JWT_ISSUER/FIREFOX_JWT_SECRET are set)
run: if [ -n "$FIREFOX_JWT_ISSUER" ] && [ -n "$FIREFOX_JWT_SECRET" ]; then npm --prefix hosts/browser exec --no -- web-ext sign --channel=unlisted --api-key="$FIREFOX_JWT_ISSUER" --api-secret="$FIREFOX_JWT_SECRET" --source-dir hosts/browser/.output/firefox-mv2 --artifacts-dir dist/release; fi
- name: coverage report
run: cp COVERAGE.md dist/release/ && npx --yes toolfactory@0.1.2 coverage > dist/release/coverage.json
run: cp COVERAGE.md dist/release/ && npx --yes toolfactory@0.2.1 coverage > dist/release/coverage.json
- uses: actions/upload-artifact@v7
with:
name: release-assets
Expand Down Expand Up @@ -213,7 +222,7 @@ jobs:
- name: npm publish
env:
NPM_TOKEN: ${{ vars.NPM_TRUSTED_PUBLISHER != 'true' && secrets.NPM_TOKEN || '' }}
run: 'if npm view papervizagent@0.3.0 version >/dev/null 2>&1; then echo "::notice::npm: papervizagent@0.3.0 already published; skipping immutable version."; elif [ "$NPM_TRUSTED_PUBLISHER" = true ]; then npm publish ./release-assets/papervizagent-0.3.0.tgz --access public; else NODE_AUTH_TOKEN="$NPM_TOKEN" npm publish ./release-assets/papervizagent-0.3.0.tgz --access public; fi'
run: 'if npm view papervizagent@0.4.0 version >/dev/null 2>&1; then echo "::notice::npm: papervizagent@0.4.0 already published; skipping immutable version."; elif [ "$NPM_TRUSTED_PUBLISHER" = true ]; then npm publish ./release-assets/papervizagent-0.4.0.tgz --access public; else NODE_AUTH_TOKEN="$NPM_TOKEN" npm publish ./release-assets/papervizagent-0.4.0.tgz --access public; fi'
publish-pypi:
needs:
- gate
Expand Down Expand Up @@ -254,7 +263,7 @@ jobs:
- name: install
run: uv sync --frozen
- name: generate container build inputs
run: npx --yes toolfactory@0.1.2 build
run: npx --yes toolfactory@0.2.1 build
- uses: docker/login-action@v4
with:
registry: ghcr.io
Expand Down Expand Up @@ -312,7 +321,7 @@ jobs:
uses: openclaw/clawhub/.github/workflows/package-publish.yml@main
with:
package_artifact_name: release-assets
package_artifact_path: openclaw-plugin-papervizagent-0.3.0.tgz
package_artifact_path: openclaw-plugin-papervizagent-0.4.0.tgz
dry_run: false
wait_for_publication: true
secrets:
Expand Down Expand Up @@ -366,20 +375,20 @@ jobs:
path: release-assets
- name: wxt submit --dry-run (zips, plus a live credential read for Chrome and Firefox)
run: |-
flags=""
if [ -n "$CHROME_EXTENSION_ID" ] && [ -n "$CHROME_PUBLISHER_ID" ] && [ -n "$CHROME_SERVICE_ACCOUNT_CLIENT_EMAIL" ] && [ -n "$CHROME_SERVICE_ACCOUNT_PRIVATE_KEY" ]; then flags="$flags --chrome-zip release-assets/papervizagent-0.3.0-chrome.zip"; fi
if [ -n "$FIREFOX_EXTENSION_ID" ] && [ -n "$FIREFOX_JWT_ISSUER" ] && [ -n "$FIREFOX_JWT_SECRET" ]; then flags="$flags --firefox-zip release-assets/papervizagent-0.3.0-firefox.zip --firefox-sources-zip release-assets/papervizagent-0.3.0-sources.zip"; fi
if [ -n "$EDGE_PRODUCT_ID" ] && [ -n "$EDGE_CLIENT_ID" ] && [ -n "$EDGE_API_KEY" ]; then flags="$flags --edge-zip release-assets/papervizagent-0.3.0-edge.zip"; fi
if [ -z "$flags" ]; then echo "No browser store credentials configured; skipping wxt submit."; exit 0; fi
npm --prefix hosts/browser exec --no -- wxt submit --dry-run $flags
flags=()
if [ -n "$CHROME_EXTENSION_ID" ] && [ -n "$CHROME_PUBLISHER_ID" ] && [ -n "$CHROME_SERVICE_ACCOUNT_CLIENT_EMAIL" ] && [ -n "$CHROME_SERVICE_ACCOUNT_PRIVATE_KEY" ]; then flags+=(--chrome-zip release-assets/papervizagent-0.4.0-chrome.zip); fi
if [ -n "$FIREFOX_EXTENSION_ID" ] && [ -n "$FIREFOX_JWT_ISSUER" ] && [ -n "$FIREFOX_JWT_SECRET" ]; then flags+=(--firefox-zip release-assets/papervizagent-0.4.0-firefox.zip --firefox-sources-zip release-assets/papervizagent-0.4.0-sources.zip); fi
if [ -n "$EDGE_PRODUCT_ID" ] && [ -n "$EDGE_CLIENT_ID" ] && [ -n "$EDGE_API_KEY" ]; then flags+=(--edge-zip release-assets/papervizagent-0.4.0-edge.zip); fi
if [ "${#flags[@]}" -eq 0 ]; then echo "No browser store credentials configured; skipping wxt submit."; exit 0; fi
npm --prefix hosts/browser exec --no -- wxt submit --dry-run "${flags[@]}"
- name: wxt submit
run: |-
flags=""
if [ -n "$CHROME_EXTENSION_ID" ] && [ -n "$CHROME_PUBLISHER_ID" ] && [ -n "$CHROME_SERVICE_ACCOUNT_CLIENT_EMAIL" ] && [ -n "$CHROME_SERVICE_ACCOUNT_PRIVATE_KEY" ]; then flags="$flags --chrome-zip release-assets/papervizagent-0.3.0-chrome.zip"; fi
if [ -n "$FIREFOX_EXTENSION_ID" ] && [ -n "$FIREFOX_JWT_ISSUER" ] && [ -n "$FIREFOX_JWT_SECRET" ]; then flags="$flags --firefox-zip release-assets/papervizagent-0.3.0-firefox.zip --firefox-sources-zip release-assets/papervizagent-0.3.0-sources.zip"; fi
if [ -n "$EDGE_PRODUCT_ID" ] && [ -n "$EDGE_CLIENT_ID" ] && [ -n "$EDGE_API_KEY" ]; then flags="$flags --edge-zip release-assets/papervizagent-0.3.0-edge.zip"; fi
if [ -z "$flags" ]; then echo "No browser store credentials configured; skipping wxt submit."; exit 0; fi
npm --prefix hosts/browser exec --no -- wxt submit $flags
flags=()
if [ -n "$CHROME_EXTENSION_ID" ] && [ -n "$CHROME_PUBLISHER_ID" ] && [ -n "$CHROME_SERVICE_ACCOUNT_CLIENT_EMAIL" ] && [ -n "$CHROME_SERVICE_ACCOUNT_PRIVATE_KEY" ]; then flags+=(--chrome-zip release-assets/papervizagent-0.4.0-chrome.zip); fi
if [ -n "$FIREFOX_EXTENSION_ID" ] && [ -n "$FIREFOX_JWT_ISSUER" ] && [ -n "$FIREFOX_JWT_SECRET" ]; then flags+=(--firefox-zip release-assets/papervizagent-0.4.0-firefox.zip --firefox-sources-zip release-assets/papervizagent-0.4.0-sources.zip); fi
if [ -n "$EDGE_PRODUCT_ID" ] && [ -n "$EDGE_CLIENT_ID" ] && [ -n "$EDGE_API_KEY" ]; then flags+=(--edge-zip release-assets/papervizagent-0.4.0-edge.zip); fi
if [ "${#flags[@]}" -eq 0 ]; then echo "No browser store credentials configured; skipping wxt submit."; exit 0; fi
npm --prefix hosts/browser exec --no -- wxt submit "${flags[@]}"
release:
needs:
- gate
Expand Down Expand Up @@ -414,7 +423,7 @@ jobs:
- name: install
run: uv sync
- name: unpublish dropped registries
run: npx --yes toolfactory@0.1.2 unpublish
run: npx --yes toolfactory@0.2.1 unpublish
env:
GH_TOKEN: ${{ github.token }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
Expand Down Expand Up @@ -464,14 +473,14 @@ jobs:
- name: install
run: uv sync
- name: toolfactory build (output files)
run: npx --yes toolfactory@0.1.2 build
run: npx --yes toolfactory@0.2.1 build
- uses: actions/configure-pages@v5
- name: web build
env:
PAGES_BASE: /${{ github.event.repository.name }}/
run: npm -C web ci && npm -C web run build
- name: publish the schema and the coverage report alongside the app
run: cp dev.toolfactory/tool.schema.json COVERAGE.md web/dist/ && npx --yes toolfactory@0.1.2 coverage > web/dist/coverage.json
run: cp dev.toolfactory/tool.schema.json COVERAGE.md web/dist/ && npx --yes toolfactory@0.2.1 coverage > web/dist/coverage.json
- uses: actions/upload-pages-artifact@v3
with:
path: web/dist
Expand Down
10 changes: 6 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Development

Install Node.js 24, npm, Python 3.11+ and uv. ToolFactory 0.1.2 is pinned by the
Makefile and generated workflows. `uv sync` installs the runtime dependencies.
Install Node.js 24, npm, Python 3.11+ and uv. ToolFactory 0.2.1 is pinned by the
Makefile and workflows. `uv sync` installs the runtime dependencies.

```sh
make build
Expand All @@ -17,11 +17,13 @@ backends. Local live tests use the normal signed-in Codex account and are not CI
## Ownership

Edit `plugin.json` for identity/version, `dev.toolfactory/tool.json` for surfaces,
`src/papervizagent/{config,backends,ops}.py` for runtime behavior, and skill
`src/papervizagent/{config,backends,events,ops}.py` for runtime behavior, and skill
bodies/reference adapters for native behavior. ToolFactory owns generated
kernels, host adapters, manifests, skill frontmatter, README installation regions
and the lock. Never edit generated regions; adopt first when necessary.
`AGENTS.md` is adopted; CI and release workflows are generated again in v0.3.
`AGENTS.md` and the release workflow are adopted. CI remains generated; the
release workflow preserves repository-specific permissions, container inputs
and complete Firefox source archives.

Reuse upstream source in `src/papervizagent/upstream`. Keep original prompt
constants unchanged and retain source hashes and modified-file notices. The
Expand Down
2 changes: 1 addition & 1 deletion COVERAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ Generated by `toolfactory build`. Verdicts per operation and surface: `native` (
| `status` | bridged (agent-mediated) | native | native | degraded (loader-unverified) | degraded (loader-unverified) | native | native | native | native | native | native | native | degraded (out-of-process) | native | native | native | native | native |
| `web` | bridged (agent-mediated) | native | native | degraded (loader-unverified) | degraded (loader-unverified) | native | native | native | native | native | native | native | degraded (out-of-process) | native | native | native | native | native |

4 of 99 managed files adopted as manual (4%): `.github/workflows/agent-config.yml`, `.github/workflows/release.yml`, `AGENTS.md`, `Dockerfile`.
4 of 100 managed files adopted as manual (4%): `.github/workflows/agent-config.yml`, `.github/workflows/release.yml`, `AGENTS.md`, `Dockerfile`.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FACTORY ?= npx --yes toolfactory@0.1.2
FACTORY ?= npx --yes toolfactory@0.2.1

.PHONY: build check validate package test
build:
Expand Down
23 changes: 19 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The Python processor, seven agent implementations and complete style guides are
**Release status:** GitHub/source installation is available; the PyPI, npm, ClawHub and browser-store commands below require the publisher setup described in [RELEASING.md](RELEASING.md). Until PyPI is published, run the runtime from the release source:

```sh
uvx --from git+https://github.com/GoatInAHat/PaperVizAgent@v0.3.0 papervizagent mcp
uvx --from git+https://github.com/GoatInAHat/PaperVizAgent@v0.4.0 papervizagent mcp
```

<!-- tf:install -->
Expand All @@ -23,18 +23,18 @@ uvx --from git+https://github.com/GoatInAHat/PaperVizAgent@v0.3.0 papervizagent
- **Gemini CLI extension** — `gemini extensions install https://github.com/GoatInAHat/PaperVizAgent`
- **OpenClaw plugin** — `openclaw plugins install --link hosts/openclaw` from a checkout; published: `openclaw plugins install clawhub:openclaw-plugin-papervizagent`
- **Hermes plugin** — `hermes plugins install https://github.com/GoatInAHat/PaperVizAgent#hosts/hermes/papervizagent_hermes`
- **DSH plugin** (experimental) — `dsh plugin --profile <profile> add ./hosts/dsh` from a checkout, or the release tarball `papervizagent-dsh-0.3.0.tgz`
- **DSH plugin** (experimental) — `dsh plugin --profile <profile> add ./hosts/dsh` from a checkout, or the release tarball `papervizagent-dsh-0.4.0.tgz`
- **Browser extension** — from a checkout: `npm --prefix hosts/browser install && npm --prefix hosts/browser exec --no -- wxt build`,
then `chrome://extensions` → developer mode → Load unpacked → `hosts/browser/.output/chrome-mv3`
(Firefox: `npm --prefix hosts/browser exec --no -- web-ext run`). Each GitHub Release attaches the
store uploads `papervizagent-0.3.0-chrome.zip`, `papervizagent-0.3.0-firefox.zip`, `papervizagent-0.3.0-edge.zip`. When Firefox signing credentials are configured, it also attaches a
store uploads `papervizagent-0.4.0-chrome.zip`, `papervizagent-0.4.0-firefox.zip`, `papervizagent-0.4.0-edge.zip`. When Firefox signing credentials are configured, it also attaches a
Mozilla-signed `.xpi`; the Chrome Web Store, Firefox Add-ons and Edge Add-ons listings appear once the release's
submit step has each store's credentials. Then pair it: `uvx papervizagent mcp --http --pair`
prints the `<url>#<token>` the extension's options page accepts.
- **Web app** — `uvx papervizagent mcp --http --open` serves the operations page beside the
MCP endpoint on one port and opens it; over MCP or a skill, the `web` operation does the same and
returns the URL.
- **npm package** — `npm install papervizagent`; requires `uv`, and `papervizagent` delegates to `uvx --from papervizagent==0.3.0 papervizagent`
- **npm package** — `npm install papervizagent`; requires `uv`, and `papervizagent` delegates to `uvx --from papervizagent==0.4.0 papervizagent`
- **PyPI package** — `uv add papervizagent`

<!-- /tf:install -->
Expand Down Expand Up @@ -76,6 +76,21 @@ Both diagrams and Matplotlib plots support vanilla, planner, planner+stylist, pl

Original prompt constants and style guides remain unchanged. Each native role has a fresh subagent; each runtime role makes an isolated provider request or Codex thread. Critic revisions produce fresh renders; polish is a separate editing workflow. Plot execution runs generated Python in a temporary child process with a configurable timeout and 300 DPI output. This isolates plotting state and hangs; it is **not an OS security sandbox**. Use the host’s execution sandbox for untrusted inputs.

## Background execution

In hosts with background completion notifications, the skill dispatches one
coordinator to own generation, isolated roles, critique and review. The main
conversation receives the completion or failure event. It does not schedule
check-ins or repeatedly poll files for progress.

Runtime integrations keep one awaited CLI process or MCP request. Embedded
Python hosts can use `papervizagent.ops.generate_events` for run, candidate and
role lifecycle events, or supply an async `on_event` callback to `generate`.
The host owns the background task and delivers the result when it completes;
there is no additional daemon or scheduler. Hosts without a background completion
channel use one awaited call. See [completion events](skills/papervizagent/references/completion.md)
for the event contract and cancellation behavior.

## Development and fidelity

```sh
Expand Down
Loading
Loading