原始 JSON 报告 机器可读
{
"data": {
"repo": {
"topics": [
"animation",
"circuits",
"cli",
"diagrams",
"graphics",
"gsap",
"kernighan",
"pdf",
"pic",
"pikchr",
"png",
"rust",
"schematics",
"svg",
"vector-graphics",
"wasm"
],
"is_fork": false,
"size_kb": 2668,
"has_wiki": true,
"homepage": "https://rpic.dev",
"languages": {
"C": 1606,
"CSS": 2680,
"MDX": 112744,
"HTML": 3394,
"Roff": 52047,
"Ruby": 1110,
"Rust": 720844,
"Astro": 78968,
"Shell": 5846,
"Python": 6114,
"JavaScript": 60182,
"TypeScript": 15817
},
"pushed_at": "2026-07-20T11:14:01Z",
"created_at": "2026-06-29T13:14:38Z",
"owner_type": "User",
"updated_at": "2026-07-19T16:19:57Z",
"description": "A modern reimplementation of the pic graphics language in Rust — SVG/PNG/PDF output, GSAP animation, and an 79-element circuit library. Bindings for Python, R and JS/TS.",
"is_archived": false,
"is_disabled": false,
"license_spdx": "BSD-2-Clause",
"default_branch": "main",
"license_spdx_raw": "BSD-2-Clause",
"primary_language": "Rust",
"significant_languages": [
"Rust",
"MDX"
]
},
"owner": {
"blog": "https://castlab.org",
"name": "Andre Leite Wanderley",
"type": "User",
"login": "milkway",
"company": "UFPE",
"location": "Brazil",
"followers": 24,
"avatar_url": "https://avatars.githubusercontent.com/u/7375849?v=4",
"created_at": "2014-04-22T17:43:11Z",
"is_verified": null,
"public_repos": 36,
"account_age_days": 4476
},
"license": {
"state": "standard",
"spdx_id": "BSD-2-Clause",
"raw_spdx": "BSD-2-Clause",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v0.11.1",
"kind": "patch",
"published_at": "2026-07-19T03:53:58Z"
},
{
"tag": "v0.11.0",
"kind": "minor",
"published_at": "2026-07-11T11:08:47Z"
},
{
"tag": "v0.10.0",
"kind": "minor",
"published_at": "2026-07-10T14:26:24Z"
},
{
"tag": "v0.9.0",
"kind": "minor",
"published_at": "2026-07-09T15:13:09Z"
},
{
"tag": "v0.8.1",
"kind": "patch",
"published_at": "2026-07-07T01:58:42Z"
},
{
"tag": "v0.8.0",
"kind": "minor",
"published_at": "2026-07-07T00:03:59Z"
},
{
"tag": "v0.7.1",
"kind": "patch",
"published_at": "2026-07-06T00:44:33Z"
},
{
"tag": "v0.7.0",
"kind": "minor",
"published_at": "2026-07-05T19:57:28Z"
},
{
"tag": "v0.6.2",
"kind": "patch",
"published_at": "2026-07-04T19:21:16Z"
},
{
"tag": "v0.6.1",
"kind": "patch",
"published_at": "2026-07-04T02:01:06Z"
},
{
"tag": "v0.6.0",
"kind": "minor",
"published_at": "2026-07-04T01:20:04Z"
},
{
"tag": "v0.5.0",
"kind": "minor",
"published_at": "2026-07-03T09:39:15Z"
},
{
"tag": "v0.4.1",
"kind": "patch",
"published_at": "2026-07-03T00:09:28Z"
},
{
"tag": "v0.4.0",
"kind": "minor",
"published_at": "2026-07-02T18:32:43Z"
},
{
"tag": "v0.3.0",
"kind": "minor",
"published_at": "2026-07-02T12:50:57Z"
},
{
"tag": "v0.2.0",
"kind": "minor",
"published_at": "2026-07-01T14:00:17Z"
},
{
"tag": "v0.1.1",
"kind": "patch",
"published_at": "2026-06-30T11:59:20Z"
},
{
"tag": "v0.1.0",
"kind": "minor",
"published_at": "2026-06-30T02:37:47Z"
},
{
"tag": "v0.0.2",
"kind": "patch",
"published_at": "2026-06-29T16:17:12Z"
},
{
"tag": "v0.0.1",
"kind": "patch",
"published_at": "2026-06-29T14:06:29Z"
}
],
"recent_commits": [
{
"oid": "162041209aae604661ac3e0f32fab8d2a55b35d8",
"body": "…fact (#378)\n\nSTATUS.md said dpic -v itself fails on 3d/EscherCube.pic. It does not:\ndpic resolves copy \"libdp3D.pic\" relative to the cwd, so the file\ncompiles cleanly when dpic runs from 3d/, and run that way it matches\nrpic on the parity metric (element counts + stroke-dasharray: 11\npolylines + 45\n[…]\nsupport library.\n\nFound while auditing the companion papers, which now carry the\ncorrected accounting; this brings the repo's own story in line.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(status): EscherCube's dpic 'failure' is a working-directory arti…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-19T16:19:53Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3a3aebbdfd53442cc282d26ad2d7a71cde8d02b9",
"body": "The archive description claimed R bindings among the in-tree\ndeliverables; the R package is maintained in the companion repository.\nReworded and linked so archive readers (and OSP reviewers) are not sent\nlooking for an R crate that is not here.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(zenodo): R bindings live in milkway/rpic-r, not in-tree (#377)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-19T16:19:50Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "5b7f2e8730b953ab11b3a7a485995b772d1818fd",
"body": "…8-#371) (#376)\n\nOne coherent bump of all nine ratex crates (parser/layout/svg/types +\nfive transitive) across the three workspaces (root, bindings/python,\ncrates/wasm) — dependabot's four PRs each moved one crate in the root\nlock only. Upstream 0.1.13 changes are react-native/iOS only; verified\ninert here: corpus 124/124 byte-identical under -c -t --svg and --json,\n367 tests pass.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(deps): ratex family 0.1.12 -> 0.1.13 (supersedes dependabot #36…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-19T10:29:08Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "1ad3aaacd249d8b5e125c9b9c2d07ddec2cfed7e",
"body": "…#375)\n\nPatch release carrying #374: macro argument frames are now built once\nper substitution and shared via Arc, taking man36.pic from 4.4 s to\n~6 ms with the corpus byte-identical. Version bumped in the workspace,\ninter-crate dep refs, wasm, python and js bindings; CHANGELOG and\nCITATION.cff updated.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "release: v0.11.1 — fix exponential recursive macro expansion (#373) (…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-19T03:51:56Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "e7c7eaee225ec0d7123dfaa3b69772cdc424cb1d",
"body": "… exponential (#373) (#374)\n\nsubstitute() stamped every emitted token with its own deep copy of the\ncall's argument token lists (args.to_vec() per token). Argument tokens\nalready carry the frames of the enclosing call, so per-token size grew\nroughly |args|^recursion-depth: man36.pic (tree(4,1000)) t\n[…]\nary over all 124 corpus\nfiles, -c -t --svg AND --json, all identical. New regression test\ncompiles a depth-6 tree (hangs visibly on regression).\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(parser): share macro arg frames via Arc — recursive expansion was…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-19T03:30:18Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2ada4db1b993b47f3cea4417bb49dbbfbdbe8a54",
"body": "…aper/) (#372)\n\n* docs: JOSS submission prerequisites — CONTRIBUTING, CODE_OF_CONDUCT, paper/\n\nAdds the three items the JOSS reviewer checklist requires that the repo\nlacked: contribution guidelines (build/test/corpus rules, PR flow),\nContributor Covenant 2.1, and the JOSS paper draft (paper/paper.m\n[…]\n community files\n(CONTRIBUTING, CODE_OF_CONDUCT) the JOSS checklist requires.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: JOSS submission prerequisites (CONTRIBUTING, CODE_OF_CONDUCT, p…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-19T01:37:27Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8fa14f961cefcf4f97d74ca978126a306f541b0b",
"body": "…r) (#367)\n\nVersion bump across every manifest (workspace + inter-crate dep refs +\nwasm/python standalone workspaces with their lockfiles + npm package),\nCITATION.cff version/date, CHANGELOG [Unreleased]→[0.11.0] with compare\nlinks, and the site banner.\n\nRelease-time doc flips (deferred until the fi\n[…]\nself-contained\nanimated pages, the standalone npm player module, corpus regeneration\nwith a CI drift guard, and the plain-HTML quick-start docs.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "release: v0.11.0 — animation anywhere (link, --html, standalone playe…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-11T11:06:54Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "35b1f669957ee78ea793fd9a363e47466a3c3a93",
"body": "One command, one file: `rpic --html -o fig.html fig.pic` writes a page\nwith the SVG, the animation/interaction manifests and the GSAP player\ninlined, plus pinned gsap@3.13.0 CDN <script> tags (SRI + crossorigin) —\nand ONLY the plugins the used effects require (move→MotionPath,\nmorph→MorphSVG, scramb\n[…]\nry pulled global succeeded).\n\nDocs: README Outputs section, animate.mdx quick start now leads with the\nzero-effort path; CHANGELOG.\n\nCloses #357\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(cli): --html — self-contained animated page (#357) (#366)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-11T10:55:32Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "39ef84a64d87fc71feb5a3671e1c7398e3238668",
"body": "…364) (#365)\n\nIntentional byte-moving changes (#274 standalone-label ink, #278\nxcolor→hex) regenerated only part of the corpus: 36 committed renders\n(1 dpic/doc, 12 dpic/manual, 23 figuras) no longer matched what main\nemits. Regenerated all 36 with `-c --svg` (the committed convention) and\nQA'd on 4\n[…]\nwithout a sibling stay svg-less on purpose: 3 are copied\nshims/libraries, 15 are root-level demos that never had committed\nrenders.\n\nCloses #364\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(corpus): regenerate 36 stale committed svgs + CI drift guard (#…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-11T02:25:45Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d79b4920227dced25898d9b6c6704b34894cfd23",
"body": "On rpic.dev the linked objects' labels rendered underlined/emerald: the\n`link` extension emitted a classless `<a>`, which the common\n`a:not([class])` prose pattern (`.docs-prose a:not([class])` here) matches,\ncascading text-decoration/colour/weight into the inline SVG's <text>.\n\nTwo complementary fi\n[…]\nted-svg comparison surfaced that examples/dpic/**.svg have\nbeen stale vs main since #274 (pre-existing, unrelated — flagged apart).\n\nCloses #362\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(link): shield object labels from host prose CSS (#362) (#363)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-11T02:06:14Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "abc97d1dfe4f76bf11620a1504cca4dc47b88cd1",
"body": "…wasm glue (#356) (#361)\n\nThe GSAP player (animate/interactive + all private helpers) moves verbatim\nfrom index.js to player.js, a ZERO-import module: importing it (bundler\nsubpath `@strategicprojects/rpic/player`, or `…/player.js` straight from a\nCDN) fetches nothing wasm-related. index.js re-expor\n[…]\nick start gains a note — the snippet itself flips to\nplayer.js at the next release, when the file exists on the CDN.\n\nUnblocks #357. Closes #356\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(js): standalone player module — animate/interactive without the …",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-11T01:47:36Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ff0782f6e0c91e2fb88b7623ff722c449639260f",
"body": "* chore(python): sync standalone Cargo.lock to 0.10.0\n\nSame lag the wasm workspace had (#355): the release bump touched\nCargo.toml but the standalone lock kept 0.9.0.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n* feat: `link \"<url>\"` — clickable hyperlinks on objects (#358)\n\nA contextua\n[…]\nguard); docs: extensions.md section, site page\n+ nav, CHANGELOG.\n\nCloses #358\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: `link \"<url>\"` — clickable hyperlinks on objects (#360)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-11T01:30:59Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f3b9947accfa2398229b74a4dcc9afa7563c0632",
"body": "…AP player (#359)\n\nThe animate page and the npm README only showed the npm+bundler path; anyone\nwith a CLI-rendered SVG had no recipe for a static page. Adds a \"Quick start —\nplain HTML, no build step\" section with two browser-verified variants:\ncompile-in-the-page (wasm from the CDN) and pre-render\n[…]\nRI-pinned) importing only the player.\n\nFollow-ups filed: #356 (standalone player module), #357 (rpic --html),\n#358 (clickable links on objects).\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(animate): plain-HTML quick start — CDN header recipes for the GS…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-11T00:46:01Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2b5f9b484f71b4f5b609d5929866eb40baf2cbb2",
"body": "The wasm crate is a standalone workspace outside the root members, so its own\nCargo.lock wasn't touched by the release bump; regenerate it to 0.10.0 for\nrpic-core/render/wasm. Generated-lock-only, no source change.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(wasm): sync standalone Cargo.lock to 0.10.0 (#355)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-10T14:51:23Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "2bd04d445fac885c3d2e2b6cf9b50b32691683a1",
"body": "… 24's npm (#354)\n\nThe `npm install -g npm@latest` step upgraded npm in place, which drops npm's\nbundled `sigstore` module; `npm publish --provenance` then died with `Cannot\nfind module 'sigstore'`, forcing a manual console publish every release (0.8.0\nthrough 0.10.0). Node 24 already bundles npm 11\n[…]\nhich supports OIDC Trusted\nPublishing and provenance with sigstore intact — so bump setup-node to 24 and\nremove the self-upgrade step entirely.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "ci(npm): fix provenance publish — drop the npm self-upgrade, use Node…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-10T14:44:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "af3698c8112f84e8a78c0d7d78166af61a0c89b4",
"body": "…rtial draw) (#353)\n\nBump the workspace and every binding to 0.10.0 (minor: all changes since 0.9.0\nare opt-in, byte-inert additions). Promote the CHANGELOG [Unreleased] section to\n[0.10.0], fix the compare links (0.9.0 was missing), refresh CITATION.cff\nversion/date and the home-page banner.\n\nSince\n[…]\ndraggable` (interactive drag), and partial `draw from/to` (reveal a stroke\n sub-segment).\n- `invalid_color` warning now carries a source span.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "release: v0.10.0 — richer animation (type, scramble, wiggle, drag, pa…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-10T14:24:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a177245c7b4406c54658b440c938581c92d400fa",
"body": "Match the home-page demo: draw the arc twice — a faint grey full-length track,\nthen the live stroke that reveals only its middle third on top — so the whole\npath stays visible behind the highlighted window instead of the unrevealed part\nvanishing. Note the track idiom in the prose.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(animate): partial-draw example gains a ghost track (#352)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-10T13:54:36Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "e1b1d60cc19d0312b97025b051c7b0fa3d07a5b4",
"body": "…351)\n\nMatch GreenSock's original: draw the spline twice — a faint grey full track,\nthen the live emerald stroke on top that the reveal window uncovers. Before,\nthe unrevealed part vanished; now the whole path stays visible behind the\nhighlighted slice, exactly like the DrawSVG demo's template + path pair. The\nwindow applies only to the live stroke (the last <path>).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(site): draw-values demo — show the full wave as a ghost track (#…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-10T13:43:46Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "d3823f14e10240286bf345a75f679e500ffaaa36",
"body": "…built (#350)\n\nA homage to GreenSock's DrawSVGPlugin-values pen (bNdLyR), rebuilt on the new\npartial `draw`: the wave is a single spline drawn by rpic, and a \"Next value\"\nbutton sweeps a reveal window through the CodePen's value list — expressed the\nrpic way as stroke *fractions* (`draw from 40% to \n[…]\nrray` sweep rpic's `draw from/to` player emits,\ntweened here between values with GSAP; no plugin. Credits GSAP and links the\npartial-draw docs.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(site): home \"Draw any segment\" — GSAP DrawSVG-values demo, rpic-…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-10T13:28:48Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c90d3c44d983f1106758a82383132d787263b736",
"body": "…343) (#349)\n\n`draw` gains two optional clauses, `from <p>` and `to <p>`, that narrow the\ntrace to any window of the stroke, given as a fraction (`60%` or the bare\n`0.6`); absent ends default to 0 and 1. Out-of-range values clamp to [0,1].\n\n- parser: for a literal `\"draw\"` effect, `from`/`to` read a\n[…]\n CHANGELOG) get a \"Partial draw\" section noting fractions, not pixel ranges.\n\nTests at parser/eval/manifest layers + a player smoke assertion.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(animate): partial `draw` — reveal a stroke sub-segment (closes #…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-10T13:13:21Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "fe285efb18a35f504e18e90a97a62c7ce2a89d01",
"body": "Move the generating pic source under the curve (was a right-hand column)\nand highlight it with the same Shiki grammar + rpic-forest themes the\nrest of the site uses — each combo is pre-highlighted at build and its\nHTML swapped in as the selectors change, reusing the site's `.astro-code`\nstyling (padding, border, dark-mode CSS-var switch). Copy still grabs the\nraw source.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(site): put the ease pic below the graph, Shiki-highlighted (#348)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-10T12:47:58Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9c701de5ab4c7abdc52369a10ed3490e375291eb",
"body": "…#347)\n\nThe ease explorer now renders the exact pic that produced the current\n(family, variant) panel in a code block next to the curve, with a Copy\nbutton — so a reader can grab it and render the animation themselves.\nEach build-time bundle carries its `src`; `show()` swaps it in as the\nselectors change.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(site): show the generating pic source beside the selected ease (…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-10T12:36:10Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "d3354e4f06eed49b958df062d7b957347ef6141e",
"body": "* fix(docs): ease marker climbs once and stops at the top\n\nThe value marker in the ease explorer looped forever (`repeat -1 yoyo`); it now\nplays a single pass — tracing the curve's value up the axis and settling at the\ntop (value 1) — with ▶ Replay to run it again. Dropped `repeat -1 yoyo` from the\n\n[…]\nits label),\nso the three controls are the same height and align on one row.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(docs): ease marker climbs once and stops at the top (#346)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-10T12:21:39Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e8e391169a22dcec98c88a5a448bfceda98f9807",
"body": "* docs: interactive ease explorer with family + variant selectors\n\nAdds an `EaseVisualizer` component to the animate page: two selectors (ease\nfamily + in/out/inOut) that plot the curve and preview it as motion with a live\nprogress/value readout — the graph view of GSAP's visualiser, for the names y\n[…]\n).\n\nAll 31 curves verified against the known ease shapes; site build green.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: pic-driven ease explorer (rpic plots every curve) (#345)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-10T02:32:16Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b3712641e8ffc6c5e75953f7de97a2683f3f2c29",
"body": "…ue marker) (#342)\n\nReproduces the \"graph\" view of GSAP's ease visualiser in pic: the ease curve's\nsegments are a block revealed by `draw` + `stagger` (drawing itself left to\nright), while a value marker rides `move` up the right axis with the same ease,\nso its height traces the curve's value as it's drawn. The one part pic can't do\nis GSAP's live numeric `value:` readout (no animated counter).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: add the animated graph-view ease visualiser (curve reveal + val…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-10T01:39:43Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "d89c8380c9ccce12314f7a47bc09e2a7ea22fc94",
"body": "The animate page already reproduces GSAP's ease visualiser two ways — the static\n`ease-gallery.pic` curve grid and a live motion race. Broaden the race from 3 to\n6 eases (none, power2.out, expo.out, back, elastic, bounce), each a dot riding\n`move` along its track with `repeat -1 yoyo`, so they loop and compare side by\nside — a fuller live counterpart to https://gsap.com/docs/v3/Eases/.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: expand the animated ease visualiser to six eases (#341)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-10T01:29:03Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "78de1f6bf9bb67199056b4658641475a4c60bf65",
"body": "The `type` showcase placed the title with `at (1.4,1.2)`, which moved the\ncurrent position there — so the first unpositioned `box \"parse\"` drew on the\nsame spot, putting \"rpic animates\" on top of the boxes. Draw the row first and\nanchor the title above the middle box (`at B.n + (0, 0.55)`), so it clears the\nrow (SVG y 15..25 vs the boxes at 73..95) and centres over it.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(docs): showcase title no longer overlaps the boxes (#340)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-10T01:08:11Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "4e4aae58972ee9c25cc1f50e50b1ce86719da293",
"body": "- README: the animation effect palette is now a table including `type`,\n `scramble` and `wiggle`, with a two-line example and a note on the `draggable`\n directive + `interactions` manifest.\n- Homepage intro lists the new effects (typewriter, scramble, wiggle & drag).\n- animate page: a combined sto\n[…]\nple upgraded to a two-node graph you can\n throw around inside its frame.\n\nSite build green (all live examples render with the release binary).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(readme,site): showcase the new animate effects and draggable (#339)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-10T00:46:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5cebe893a55584a893b9ddbbdbbc459ba51c23a4",
"body": "…#333) (#338)\n\nThe `invalid_color` warning was emitted position-less, so `line`/`col`/`end_col`\ncame out null and editors (rpic studio) couldn't jump to or underline the\noffending colour token. The colour attributes now carry their token span\n(`Attr::Color`/`HatchColor`/`Gradient` gain an `Option<Sp\n[…]\n(corpus 124/124\nbyte-identical); the animate `to <colour>` warning stays position-less (no\nper-colour span is threaded through that directive).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(diag): attach a source span to the invalid_color warning (closes …",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-10T00:34:08Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0b5370abb01b98bda801a3ece1c62b4fde35efa4",
"body": "…s #331) (#337)\n\n`draggable <place> [inertia] [bounds <place>] [x|y]` marks an object grabbable\nin the browser. It is a new *interaction* axis, not a timeline effect, so it is\nits own directive (contextual like `class`, so `draggable` stays a usable\nvariable) with its own output stream — not folded \n[…]\nighlight keywords;\n CHANGELOG.\n\ncargo test 335 pass, clippy/fmt clean, corpus 124/124 byte-identical, highlight\n+ JS smoke + site build green.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(draggable): interactive drag directive via GSAP Draggable (close…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-10T00:19:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "cc3c76e302a2575573465438ce09ba33591ea6ac",
"body": "…es #330) (#336)\n\n`wiggle` gives an object a quick oscillating shake that returns to rest — the\n\"look here\" nudge that draws the eye without moving it. `wiggles <n>` sets the\noscillation count (default 6).\n\n- ast/parser: contextual `wiggles <n>` clause (stays a usable variable name).\n- eval: `wiggle\n[…]\nSAP callout, extensions.md, CHANGELOG.\n\ncargo test 334 pass, clippy/fmt clean, corpus 124/124 byte-identical, JS smoke\ntest + site build green.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(animate): `wiggle` attention shake + document bounce eases (clos…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T23:53:37Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2e29ff9e8f87faf4c604f152aebf6526d88a6f78",
"body": "…329) (#335)\n\nA label's glyphs cycle through random characters and resolve into the real\ntext. It drives the `<text>` element directly through GSAP's ScrambleTextPlugin\n(which, unlike SplitText, works on SVG `<text>`), so there is zero cost on the\nSVG side — the static render and the whole corpus st\n[…]\n green. (Runtime GSAP behaviour of the reveal to be confirmed\nin a browser, per the issue's open question — the SVG/manifest side is verified.)\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(animate): `scramble` effect — decode-style text reveal (closes #…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T23:34:26Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "29606d8119c2fcaad7233479e227276f153102bd",
"body": "…#334)\n\nReveal a label one character (or `by word`) at a time, staggered over the\neffect's duration. The split is native — GSAP's SplitText doesn't support SVG\n`<text>` — so the SVG backend wraps each unit of a `type` target in a\n`<tspan class=\"rpic-ch\">` and the browser player staggers their opacit\n[…]\nive example, extensions.md, CHANGELOG.\n\ncargo test 332 pass, clippy/fmt clean, corpus 124/124 byte-identical, JS smoke\ntest + site build green.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(animate): `type` effect — typewriter text reveal (closes #328) (…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T18:32:44Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "234356d178c009823ca5e65d53cbbbf35c159064",
"body": "Re-ran tools/bench (Apple M2 Pro, hyperfine, all six tools) and updated the\nperformance page's PerfBench/PerfDistribution data + prose to the new medians:\nrpic ~5.3 ms at 120 nodes (still the C class next to pikchr 3.0 / dpic 3.7),\ngraphviz 84 ms, d2 449 ms, mermaid 713 ms; the 50-diagram pipeline i\n[…]\n→~140×, and a new \"Safe on untrusted input\" bullet covering the bounded\nrecursion / loop-shape budgets / escaped output / C ABI panic boundary.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(site,readme): refresh v0.9.0 benchmark + feature messaging (#332)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T17:37:48Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "88baeb8056a25ccd947fbae506b3d0368edeff92",
"body": "Bump workspace + wasm/python/js versions and inter-crate deps to 0.9.0,\nregenerate the three lockfiles, date the CHANGELOG and CITATION.cff.\n\nHighlights since 0.8.1:\n- Extensions: `thin` keyword, dvips/xcolor→RGB, colour-name validation,\n colours from variables/expressions, full C ABI options via `\n[…]\nfamily XML escaping (#317).\n- Quality: escapers named by context to prevent the #317 class (#324),\n eval.rs split into an eval/ module (#323).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "release: v0.9.0 (#327)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T15:11:19Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "91dfa195748782ad09588cfa5ce65915b51a454e",
"body": "…ses #323) (#326)\n\neval.rs was by far the largest file in the crate. Split it, along its existing\nseams, into files that each read at the same altitude as the rest of the crate:\n\n- eval.rs — State, entry points, statement/animation dispatch (~1.9k)\n- eval/build.rs — primitive construction (c\n[…]\ne\nreorganization — no logic, signature, or public-API change. cargo test 328\npass, clippy 1.97 clean, fmt clean, corpus 124/124 byte-identical.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor(core): split the 7.6k-line eval.rs into an eval/ module (clo…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T14:58:55Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e1375d15bace8fac74f06b2888920ddfa8cc59de",
"body": "… (closes #324) (#325)\n\nThe two near-identical escapers `escape`/`attr` let a text escaper be used for\nan attribute value silently (#317). Rename to `escape_text` / `escape_attr` so\nevery call site states its context — a text escaper in an attribute now reads\nwrong — with doc comments spelling out t\n[…]\ntext through each\nattribute kind and asserts the `\"` can't break out, plus drops three needless\n`stroke` clones. Corpus 124/124 byte-identical.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor(svg): name escapers by context so the #317 class can't recur…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T14:51:11Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b27b6491299dbffd6c7c00e202868224d4e55d84",
"body": "Every `extern \"C\"` entry point delegated straight to its `_impl` with no\n`catch_unwind`, so a Rust panic would unwind across the FFI boundary and abort\nthe C/C++/R host process. Wrap the shared `_impl` bodies in a `guard_ptr`\nhelper that converts a panic into the crate's null-pointer failure convent\n[…]\n internal invariant break). Python is\nalready panic-safe via PyO3; wasm traps cleanly. Test asserts a panicking body\nyields null, not an abort.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(capi): catch panics at the C ABI boundary (closes #319) (#322)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T14:18:21Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b18e653011d168b61e1064b1eed7bdb42f2e1183",
"body": "…es #318) (#321)\n\n#306/#314 capped flat numeric operator chains but four sibling constructs still\naborted the process by overflowing the stack — a hard, uncatchable crash for\nevery embedding (Python/JS/R/C), the exact untrusted-input threat model:\n\n- brace-group `{{{…}}}` — parse_element→parse_elem\n[…]\nor (\"nested too deeply\" /\n\"too many chained operators\"). Regression test added; corpus 124/124\nbyte-identical (deepest committed nesting is 4).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(parser): bound four recursion/AST-depth vectors #306 missed (clos…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T14:00:36Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1a3066112bb3f0adab0de628e635224455317493",
"body": "The per-string font family was emitted into the `font-family=\"…\"` attribute\nwith `escape()` (text-content: only `&<>`), not `attr()` (`\"`→`"`), so a\ndouble quote closed the attribute early — malformed SVG plus attribute/event-\nhandler injection into the `<text>` element (XSS when the SVG is inl\n[…]\n). Switch to `attr()`, matching every other attribute site. Add a\nregression test; corpus 124/124 byte-identical (no figure uses a `font \"…\"`).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(svg): XML-escape `font \"…\"` family names (closes #317) (#320)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T13:57:27Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0352e0af7b18aa192891e6c56ee875d4fb938516",
"body": "…(#316)\n\n* fix: add eval budgets for loop expansion\n\n* style(svg): drop redundant `text: _` binds flagged by clippy 1.97\n\nRust 1.97.0 (stable, 2026-07-07) tightened the unused-pattern lint: a\n`text: _,` field bind followed by `..` is now an error under\n`-D warnings`. Four match arms in `shape_svg_bo\n[…]\ncks CI lint;\nbehavior is unchanged (corpus 124/124 byte-identical vs main).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: configurable budgets for large for-loop expansion (closes #309) …",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T13:20:21Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c1c0d1def13bba935d4f6611fb151eb2b3f28f3a",
"body": null,
"is_bot": false,
"headline": "fix: guard png raster allocations (#315)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T12:02:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d80b4d3b52c094a83762c7ed59495de19aab9451",
"body": "Closes #306.\n\nAdd an explicit parser budget for flat expression operator chains and evaluate left-deep binary chains iteratively so malformed-but-valid input returns a normal error instead of overflowing the evaluator stack.\n\nValidated with local cargo fmt/test/clippy/build, CLI repro, and GitHub CI.",
"is_bot": false,
"headline": "fix: cap flat expression chains (#314)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T11:42:18Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "76e874fccf687663e594f1a2a0f73f39f9617d92",
"body": "Closes #308.\n\nReject SVG/CSS paint server values such as url(...) before color strings reach the renderer. CSS variables and unsupported CSS functions now error, while plain unknown color names keep the existing advisory warning behavior.\n\nValidated with local cargo fmt/test/clippy/build and GitHub CI.",
"is_bot": false,
"headline": "fix: reject unsafe SVG color functions (#313)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T10:58:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "61bb279c474405a6d8f127748fcf40d742e51e1c",
"body": "Adds host-configurable animation caps plus PIC-level maxanimrepeat/maxrepeats/maxanimseconds variables that can only lower the host ceiling.",
"is_bot": false,
"headline": "feat: make animation limits configurable (#312)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T01:11:56Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "64c8342460ea75242d3ed0ed552cf673939674b2",
"body": "Closes #310.",
"is_bot": false,
"headline": "fix: validate animation timing values (#311)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T00:53:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b1f0543122f2b35e120ce6e1f61681145aab7a13",
"body": "…after, splice spacing) (#305)\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(changelog): note the second-audit fixes (rotated label, stagger-…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T00:12:16Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "c4388c09a95894a6dba978ccd4d01d7e8ecc9f95",
"body": "…>` waits (audit) (#304)\n\n`animate <block> … stagger` recorded the end of the last staggered child under\nthe first *visible* child's shape index, but `after <block>` resolves to the\nblock's *own* shape index — which line 863 had seeded with a single-iteration\nend. When the block leads with an invisi\n[…]\nuded) byte-identical across the corpus (124/124 —\nno figure `after`s a staggered invisible-spine block). Test added; 313 pass,\nclippy/fmt clean.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(animate): record whole-stagger end on the block, so `after <block…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T00:08:25Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5ae48d3e1ec5c5875472bfc89fafc9dde1ecf97e",
"body": "…ntre (audit) (#303)\n\nA `rotated` label that is also justified could render entirely outside the\nviewBox and vanish. The SVG backend rotates a label about its text anchor —\nthe left edge for `ljust`, the right for `rjust` — but the bounds helper\n`add_rect_rotated` spun the cover about the rect *cent\n[…]\nrame (verified visually + a test\nasserting the anchor stays within the viewBox for all three justifications).\n\n313 tests pass; clippy/fmt clean.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(bbox): rotate label bounds about the text anchor, not the rect ce…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-09T00:08:22Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5c15ac7ce096bd9dcd371c0f6898f75a078910d0",
"body": "…der invariant (#302)\n\nSecond-audit follow-ups.\n\ntokens_to_text (the `\"$n\"` splice serializer from #282) computed the source gap\nbetween tokens from the *rendered* length of the previous piece, not the\ntoken's real `end_col`. When a token renders shorter/longer than its source\nspan — a normalized fl\n[…]\nould be a silent failure the module exists to prevent. All\n68 pass today; the test locks it in.\n\n311 tests + color suite pass; clippy/fmt clean.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(macro): use real source span for splice spacing; guard xcolor ren…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T23:54:54Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e3f3149ebad0f681a2cd22944f9f4416e86bb21a",
"body": "…ory (closes #157) (#301)\n\nManual curation pass over the full corpus (contact sheets of all 123 files,\n5 sheets reviewed). The new set reads as a narrative: Kernighan classics →\nprogrammability → TeX labels → the circuit library → 3D projection.\n\nIn (new): man29 compiler structure, man36 binary heap\n[…]\n on the 2-col grid; verified visually in the\nbuilt site (dark mode) — no clipping, Studio buttons present exactly on the\nself-contained sources.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(site): curate the Gallery — 14 figures telling the language's st…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T23:21:54Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9be39b196f5f3e62622bfe43f7022f44658295ea",
"body": "… (#300)\n\nThe label sizing constants (11 pt em, 0.6 advance ratio, 1.2 line height,\n0.66 x-height ratio) and the per-line ink-width estimator were implemented\ntwice — eval.rs (layout/canvas bbox) and svg.rs (rendered ink bounds) — and\nagreed only because both hard-coded the same numbers. Any future \n[…]\ne-identical across the corpus (124/124 vs main). 311\ntests pass; clippy/fmt clean. Closes the remaining item of #291 (items 1-2\nlanded in #295).\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor(core): single source of truth for text metrics (closes #291)…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T23:21:50Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d04e086879626b5ac2ba5ab1ea8b2c5b221dbef5",
"body": "…yer (closes #287) (#299)\n\nThe two GSAP players had drifted and the shipped TypeScript types under-described\nthe manifest.\n\n- index.d.ts: `Anim` now declares the optional keys the player consumes\n (repeat/yoyo/ease/path/color/out/from/morph) and documents the effect names;\n `Bundle` gains `scroll?\n[…]\nes types\nand brings the docs player in line with it. Site builds; types are additive\ndeclarations (CI's wasm smoke test exercises the npm side).\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(js): complete animation types; align docs player with the npm pla…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T19:52:59Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "df21f5bed223e47808662e1c2cf1fc5781082f00",
"body": "…enies includes (closes #286) (#298)\n\nTwo related option/policy gaps in the non-Rust entry points.\n\nC ABI: the four render functions took only `circuits`, so C/R embedders (the\ncapi is \"the foundation for non-Rust bindings\") couldn't enable texlabels as a\nflag, set an include base, or sandbox `copy \n[…]\n` texlabels flag, Deny policy, and NULL-options\ndefaults. 311 core + 3 capi tests pass; clippy (all-targets + wasm\nmanifest-path) and fmt clean.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(bindings): expose full compile options in C ABI; wasm compile() d…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T19:43:51Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d078ebbae768055e115e0acf500cfe77e10981d8",
"body": "… (closes #290) (#297)\n\n- Fix a 404: the animate page linked the traveller dot to\n /docs/extensions/junction-dots; the page is /docs/extensions/dot.\n- spec.mdx colour surface was pre-0.7.0: the prose and the grammar `color ::=`\n rule listed only \"CSS name, quoted or bare\". Updated to include rgb()\n[…]\nk-reference\n definitions (the file follows Keep a Changelog).\n\nDocs-only; site builds and the new spec→rotated colour-literals anchor resolves.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: consistency pass — broken link, colour grammar, extensions list…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T19:43:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2db26fc6ba1c283afbecd4eb8f5b48707ebfdb65",
"body": "…296)\n\nThe TextMate grammar (Shiki on rpic.dev + the VS Code extension) had drifted\nfrom the language. Verified against crates/core/src/lexer.rs and the contextual\nName-matches in parser.rs.\n\nAdded ~25 keywords the engine recognises but the grammar didn't highlight:\n- animate clauses: along, into, s\n[…]\n the phantoms are NOT highlighted as keywords — so this can't\nsilently drift again. Grammar JSON validates; all scope + corpus-smoke tests\npass.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(highlight): sync grammar keywords with the lexer (closes #289) (#…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T19:29:12Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4c8a9a4e46437671d5be7bbb3402c339bf369648",
"body": "… #291) (#295)\n\nTwo small robustness/UX fixes from the audit bundle:\n\n- A non-positive `dashed`/`dotted` pitch (`line dashed 0-0.1`) emitted an\n invalid negative `stroke-dasharray` that renderers reject (dashing silently\n dropped to solid). A non-finite/≤0 pitch now falls back to the default\n spa\n[…]\n/fmt clean. The third #291 item (deduplicating the text-metric math\nacross eval.rs/svg.rs) is a larger structural refactor left for a follow-up.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: guard non-positive dash pitch; suggest xcolor names too (part of…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T19:27:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "280ca844de70a9baf71c3a29ca908638a40f7629",
"body": "…294)\n\nThe bold/italic/bold-italic/mono/mono-bold faces and the mono family lacked the\n`#[cfg(feature = \"raster\")]` gate that the base font and family carry, even\nthough every one is used only inside the raster-gated `load_embedded_fonts`. So\nthe documented math-only wasm build (`rpic-render` with\n`\n[…]\ns math` compiles clean\n(no unused-const warnings, fonts no longer embedded) and the default `raster`\nbuild is unchanged; workspace clippy clean.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(render): gate all embedded fonts behind `raster` (closes #288) (#…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T19:10:49Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b54362532c689ce192fd9335a52a25e0ff49ca47",
"body": "`fill_opacity_attr` emitted `fill-opacity` only when `fill` or `hatch` was set,\nso `box gradient \"gold\" \"red\" opacity 0.3` rendered fully opaque while solid,\nhatch, and gradient+hatch fills all honoured the opacity. A gradient is a fill\ntoo — add `style.gradient.is_some()` to the predicate (matching\n[…]\nh already counts gradient).\n\nByte-inert across the corpus (124/124 — nothing combines gradient+opacity).\nTest added; 308 pass, clippy/fmt clean.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(svg): gradient-only fill honours opacity (closes #285) (#293)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T19:04:59Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "07e63bd5871875f48bf5b9ea12f95a8c356fb68a",
"body": "… #283, #284) (#292)\n\nTwo unbounded paths let adversarial `.pic` source abort the process — an\nuncatchable stack overflow / OOM, unlike every other error which returns Err.\nBoth are reachable from the CLI and the wasm binding (the docs site / Studio\ncompile pasted source), so this is a crash/DoS sur\n[…]\nzed test build than the harness's default thread (a\nnon-issue for release/wasm, which the limit is tuned for). 310 tests pass,\nclippy/fmt clean.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(parser,eval): bound recursion depth and sprintf precision (closes…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T19:00:16Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c84807c65ab77a0fd0be9638a06a4decb9e765b8",
"body": "…ing (closes #280) (#282)\n\ntokens_to_text — the serializer behind `\"$n\"` splices inside string literals\n(the static-exec dispatch idiom, shim labels) — glued all tokens without\nseparators, silently DROPPED keywords (its `_ => {}` arm swallowed Kw and\nevery operator), and stripped string quotes. A st\n[…]\njust\" is gone). Corpus stays\n100% warning-clean. 308 tests (3 new: exec splice, kw preservation, span\nspacing + idiom guards); clippy/fmt clean.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(macro): argument splices reproduce source text — spans drive spac…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T18:19:00Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2b266b9c83bb6adb0f5db69521ab65d359b442ed",
"body": "…oses #273) (#281)\n\nWhen gradient and hatch combined, the gradient was embedded as the pattern\ntile's background with gradientUnits=\"objectBoundingBox\" — the bbox of the\n7.68px tile rect, so the full ramp rendered inside EVERY hatch cell and tiled\nacross the shape (a \"quilted\" look) instead of spann\n[…]\nest now asserts the underlay\nordering and that the tile embeds no gradient. Docs wording updated\n(gradient.mdx + docs/extensions.md); CHANGELOG.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(svg): paint gradient+hatch as an underlay spanning the object (cl…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T17:48:58Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "266dfb7f9d11a6543c0cac368af8b66a45286cc4",
"body": "…closes #276) (#279)\n\nTwo intertwined bugs broke the dpic suite's `DefineRGBColor(name,r,g,b)`\nmachinery (a `case(dpicopt, …)` that exec-dispatches into a nested define of\nthe colour macro):\n\n1. `parse_exec_source` expanded exec'd text against a CLONE of the macro\n table, so a `define` inside an e\n[…]\ns pass, including new\nones for exec-define persistence, the full DefineRGBColor machinery, and the\noracle-checked opt* values; clippy/fmt clean.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(exec): persist defines from exec'd text; one-based dpicopt/opt* (…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T17:23:48Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c1f29a8d4fa0f929915066f4fdb501efda6e6f2a",
"body": "…278)\n\nThe 30 dvips names no browser understands (Dandelion, BurntOrange,\nPeriwinkle, …) now emit their dvipsnam.def RGB (Dandelion → #ffb529) instead\nof passing through as an SVG-invalid keyword that painted nothing. Values are\nderived from TeX's dvipsnam.def cmyk table (channel = 1 − min(1, c+k));\n[…]\n test keeps its verbatim-passthrough\nassertion via a truly unknown name and gains the Dandelion mapping check.\n304 tests pass; clippy/fmt clean.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(color): resolve dvips/xcolor names to their RGB (closes #275) (#…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T17:12:42Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "598d2f9fcc1a7f3f870253bf3b765783c1e45002",
"body": "…277)\n\nrpic passed any colour string straight to the SVG backend, so a typo\n(`\"crimsom\"`), a mis-cased keyword, or a malformed hex (`\"#12g456\"`) silently\nrendered blank. Add colour-name validation: a new `color` module classifies a\nresolved colour string (the 148 CSS named colours, `#rgb`/`#rgba`/`#\n[…]\ny.\n\nTests: color module unit tests + an eval integration test; 301 pass, clippy/fmt\nclean. Docs (rotated & colour literals) + CHANGELOG updated.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(color): warn on unknown colour names (part of #269 follow-up) (#…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T16:40:42Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "805ac18df95cf79f8aad0d03d5e25510d2ba8a7f",
"body": "… (closes #270) (#274)\n\nA standalone `\"text\" at P` label contributed no glyph width to the drawing\nbounds — the SVG backend's `standalone_text_bounds` used the (zero) `textwid`\nbox, ignoring the ink and the ljust/rjust justification. So a wide or\nedge-anchored label ran off the page. `attached_text_\n[…]\nivergence;\na new `standalone_label_ink_is_bounded_not_clipped` test guards it. CHANGELOG\nupdated. Tests 297 pass; clippy/fmt clean; site builds.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(bbox): bound standalone-label glyph ink so edge labels don't clip…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T15:06:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0de67b24f69bb2790f70a0be2e801602e1c52bd5",
"body": "Add `thin` as a bare line-thickness attribute — `line thin`, `box thin`, no\nvalue — a pikchr-flavoured convenience for a lighter stroke. It sets the\nobject's thickness to two-thirds of the current `linethick` (matching pikchr's\n`thin` ratio), so it tracks the global line width and complements the ex\n[…]\n unit test added.\n\nByte-inert: no corpus source uses `thin` as an identifier, so all 124 examples\nrender byte-identically to main under `-c -t`.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(attr): `thin` line-thickness keyword (closes #268) (#272)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T14:00:06Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0134cc18a41abd329d281302cc118097ea287b47",
"body": "…lise 0x strings (#269) (#271)\n\nColours can now be held in a variable or computed. In colour position\n(`outlined`, `shaded`, `color`, `hatchcolor`, `gradient`, `animate … to`):\n\n- a bareword that names a variable resolves to its value as a 0xRRGGBB colour\n (`accent = 0x2f855a; … outlined accent`) —\n[…]\nry.pic refactored to a colour palette (`acc`/`grid`) as a\ndogfood — its render is unchanged to the byte. Tests + docs (rotated.mdx) +\nCHANGELOG.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(color): evaluate variables/expressions in colour position; norma…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T13:30:11Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7cd141bab020cd2ee9868f2ee9a20eec0375f4b7",
"body": "…ion demo) (#267)\n\nAnswer \"can we build the GSAP ease visualiser in pic?\" — yes. Add\nexamples/ease-gallery.pic: a 3×3 small-multiples gallery that plots each ease\nfamily's .out curve by sampling the GSAP formula in a `for` loop (sin/exp/\nsqrt/^, if/else for the piecewise bounce), with a linear-refer\n[…]\nshowing the same eases as *motion*\n(three dots covering one track in equal time under none/power2.out/bounce.out).\n\nDocs-only; no engine change.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(animate): an ease visualiser drawn in rpic (static gallery + mot…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T12:50:37Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "612a9cdb567fd852fe12b7818242760123720ec2",
"body": "The `ease` clause is an opaque passthrough — rpic never parses it, GSAP\nresolves the string at play time — so any GSAP ease works but none were\nenumerated. Add an \"Easing reference\" section under Looping and easing: the\n`<family>.<variant>[(args)]` naming pattern, a variant table (.in/.out/.inOut),\n\n[…]\npower1–4, sine, expo, circ, back, elastic,\nbounce, steps), and a note that typos fall back to GSAP's default. Cross-link\nfrom the `ease` bullet.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(animate): add an easing reference (family/variant catalogue) (#266)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-08T12:07:10Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "fe1abc13c403c36b183dff7a19ec8f605c59121e",
"body": "…in note (#265)\n\nAdd a small toolbar to every code example on rpic.dev:\n- Copy button (client-side clipboard with execCommand fallback + \"Copied!\"\n confirmation), source escaped into a data-code attribute.\n- Open in Studio link, built at build time via a shared studioUrl() helper\n (studio.rpic.dev\n[…]\n, and that GSAP >= 3.13 is required (since 3.13 the whole toolset,\nMorphSVGPlugin included, is free; older versions loaded a watermarked trial).\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(site): Copy + Open in Studio buttons on every example; GSAP plug…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-07T18:51:39Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "37109bf6f5af766c1c486b3c583737d8d1b865a6",
"body": "Latest published release is v0.8.1 (the npm move/morph player fix). Bump the\nlanding banner number; the \"a complete animation subsystem\" tagline stands.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: homepage banner → v0.8.1 (#264)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-07T02:28:29Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "b4f5592b4b4cf255c57a37f3f15324fd75c0bdd0",
"body": "macOS GitHub-hosted runners are billed even for public repos, and ci.yml ran a\n`test (macos-latest)` job on every PR and every push to main — 100+ macOS runs\nthis month, the bulk of the repo's Actions bill. Remove macOS from the test\nmatrix (Linux + Windows remain). macOS is still validated at relea\n[…]\nded PR/branch runs stop\ninstead of finishing — no required status check references the macOS job, so\nneither change stalls merges.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "ci: drop macOS from routine CI (keep it at release time only) (#263)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-07T02:23:12Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3b0d31226205d315378612bea1cd31ad7224f6fc",
"body": "Patch release. Bump the workspace + inter-crate dep refs, the standalone wasm\nand python workspaces, the JS package, and CITATION.cff to 0.8.1; refresh the\nthree Cargo.lock files; add the CHANGELOG entry.\n\nThe one substantive change since v0.8.0 is a **JS-player fix**: the npm package\n`@strategicpro\n[…]\no those channels re-publish an aligned no-op version bump.\nAlso folds in the stronger `highlight` (thicker outline + scale pulse).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "release: v0.8.1 (#262)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-07T01:55:25Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "fae338f88f09fe75cfdc88d7d942ae016e473794",
"body": "The docs sidebar is `hidden lg:block`, so below 1024px the entire page\nnavigation vanished and there was no alternative — phone/tablet users could\nonly reach Home/Docs/GitHub from the header, never the individual docs pages\n(installation, spec, extensions/*, …).\n\nAdd a hamburger toggle (lg:hidden) t\n[…]\n\nGitHub text links collapse (`hidden sm:inline`) so the bar doesn't crowd.\nDesktop is unchanged (hamburger hidden, sidebar shown).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(site): add a mobile navigation menu (#261)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-07T01:21:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d7b0f90ae40788acef9416e8628a9525ad82353c",
"body": "…260)\n\n* fix(animate): convert primitives to <path> for move/morph players\n\nThe `move` and `morph` effects crashed at runtime — the console filled with\n\"Expecting a <path> element or an SVG path data string\" and\n\"TypeError: undefined is not an object (evaluating 'e[0]')\", looping every frame\nunder `\n[…]\nto match; the repeat option is still documented).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(animate): move/morph player + pic-family table + bench harness (#…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-07T01:12:42Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "76c004b7e80abc498d3800139c6fd0f145ef69c4",
"body": "v0.8.0 is published; update the landing banner from the v0.7.0 tagline to\n\"v0.8.0 — a complete animation subsystem\", matching the release headline and\nthe new \"Watch it build\" showcase.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: homepage banner → v0.8.0 (animation subsystem) (#259)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-07T00:27:15Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "cb17e526239142d7298aa455b783aee39561a484",
"body": "Bump the workspace + inter-crate dep refs, the standalone wasm and python\nworkspaces, the JS package, and CITATION.cff to 0.8.0; refresh the three\nCargo.lock files. Add CHANGELOG.md (new) and link it from the README.\n\nSince v0.7.1: a complete **animation subsystem** (#246–#256). `animate` grew\nfrom \n[…]\nints a new version DOI under the same concept DOI; the\nconcept DOI (10.5281/zenodo.21209915, in CITATION.cff/README) is unchanged.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "release: v0.8.0 (#258)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-06T23:57:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "69a2c347a8907be37aff60412c08f8b4bd30547b",
"body": "The animation layer grew from three effects to a full storytelling toolkit\n(#246-#256), so bring the front-facing docs up to date.\n\n- README: expand the feature blurb and the \"Animation (GSAP)\" section to cover\n the whole palette — fade/pop/draw/slide/move/highlight/morph effects, the\n `out` exit \n[…]\nns.md,\nDESIGN.md) were already updated by each feature PR. Version banner left at\nv0.7.0 — the animate work is unreleased in main.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: reflect the expanded animate subsystem in README + homepage (#257)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-06T23:44:50Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ff10c646486316dff86649db9bcd05772456f699",
"body": "…G) (#256)\n\nThe last of the Tier 3 animate ideas from #250 (previously deferred): a `morph`\neffect that tweens an object's outline into another shape's geometry — a box\nbecoming a circle, one symbol flowing into the next.\n\n```\nanimate A with \"morph\" into B [for <dur>] [repeat…] [ease…]\n```\n\nStructur\n[…]\n the Tier 3 animate set (#250 was already closed by the slide/out/scroll\nwork; this finishes the one item that had been deferred).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: animate `morph` effect — morph into another shape (GSAP MorphSV…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-06T23:37:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1f2ef7d8a78aa686fd0d889b298197efc8b4646e",
"body": "The last of the Tier 3 animate ideas we picked up (after slide/out in #254):\na `animate scroll` directive that hints the host should scrub the timeline by\nscroll position instead of autoplaying.\n\nUnlike the effect clauses this is a whole-timeline decision, so it's a bare\ndirective (not attached to a\n[…]\n#250. (MorphSVG, the remaining Tier 3 idea, is deliberately deferred —\nniche and heavier; file a fresh issue if it's ever wanted.)\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: animate scroll — timeline-level scroll-scrub hint (#250) (#255)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-06T23:21:10Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a83704093790cb176aac0c05785e7f90629aa57d",
"body": "Two of the Tier 3 animate ideas from #250:\n\n- **`slide` effect** — enter by translating in from a compass direction:\n `animate X with \"slide\" from up|down|left|right`. The player offsets the\n object by its own extent so it clears its slot. `slide` needs a `from`\n direction (omitting it errors); `\n[…]\nate.mdx, plus docs/extensions.md and DESIGN.md.\n\nPart of #250 (Tier 3); ScrollTrigger scrub follows separately, MorphSVG deferred.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: animate `slide` effect + `out` exit modifier (#250) (#254)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-06T23:08:32Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0f33fdbb70d64e71446af207a3089d66cda7d5f3",
"body": "…49) (#253)\n\nPoint `animate` at a `[ … ]` block and add `stagger <d>` to fan the effect\nacross the block's children — each child starts `d` seconds after the previous,\nso a row or grid assembles itself one piece at a time.\n\n```\nanimate <block> with \"<effect>\" stagger <d> [for <dur>] [timing…] [repea\n[…]\n \"Staggering a\ngroup\" section with a live self-assembling row in animate.mdx, plus\ndocs/extensions.md and DESIGN.md.\n\nCloses #249.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: animate `stagger` — fan an effect across a block's children (#2…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-06T22:43:18Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3ecaaf55c1414d088acf9fecb941e25b87e5296e",
"body": "A new `animate` effect that draws the eye to an already-drawn object — the\n\"now look here\" beat of a step-by-step explanation.\n\n```\nanimate <obj> with \"highlight\" [to <colour>] [for <dur>] [timing…] [repeat…]\n```\n\n- `to <colour>` (any rpic colour form — name, `rgb()`, `0xRRGGBB`, resolved via\n the \n[…]\ntion. Docs: an \"Emphasis\" section\nwith a live pulsing example in animate.mdx, plus docs/extensions.md and DESIGN.md.\n\nCloses #248.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: animate `highlight` effect — emphasis colour tween (#248) (#252)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-06T22:28:41Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2b017c27826d1bbe8baf4aedf527d44c7d49c293",
"body": "…#247) (#251)\n\nA new `animate` effect that sends its target travelling along another\nobject's geometry — a token down a wire, a packet along an arrow, current\naround a loop.\n\n```\nanimate <obj> with \"move\" along <path> [for <dur>] [timing…] [repeat…]\n```\n\n- `along <path>` names a drawn line/arrow/spl\n[…]\n along a\npath\" section with a live flowing example in animate.mdx, plus updates to\ndocs/extensions.md and DESIGN.md.\n\nCloses #247.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: animate `move` effect — travel along a path (GSAP MotionPath) (…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-06T22:13:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f4a80bdb3c4f5f7b262fd6fd754d3b06c184776a",
"body": "Extend the `animate` extension with three GSAP-tween passthroughs and\nfill out the (previously thin) animate documentation.\n\nNew optional clauses on `animate <place> with \"<effect>\" …`:\n- `repeat <n>` — replay count (`-1` loops forever, `0`/absent plays once)\n- `yoyo` — reverse each pass; warns `yoy\n[…]\nes, four-mode timing model, a live looping example) and added a\n\"Declarative Animation\" section to docs/extensions.md + DESIGN.md.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: animate repeat/yoyo/ease + dedicated animate docs page (#246)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-06T19:36:02Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "447bfd19763cde5fd93fcc44947d5ac09e5be129",
"body": "Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 4 to 5.\n- [Release notes](https://github.com/actions/deploy-pages/releases)\n- [Commits](https://github.com/actions/deploy-pages/compare/v4...v5)\n\n---\nupdated-dependencies:\n- dependency-name: actions/deploy-pages\n dependency-\n[…]\nirect:production\n update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump actions/deploy-pages from 4 to 5 (#243)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-06T14:08:39Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8868e2aff877f7a9a3e35b1ce238bf6aff1e1b94",
"body": "Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 4 to 5.\n- [Release notes](https://github.com/actions/upload-pages-artifact/releases)\n- [Commits](https://github.com/actions/upload-pages-artifact/compare/v4...v5)\n\n---\nupdated-dependencies:\n- dependency-name\n[…]\nirect:production\n update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump actions/upload-pages-artifact from 4 to 5 (#245)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-06T14:08:35Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "cb91d4c5e1c2fbd5a1b4c2c64ef30e08afc1c006",
"body": "Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.\n- [Release notes](https://github.com/actions/setup-node/releases)\n- [Commits](https://github.com/actions/setup-node/compare/v4...v6)\n\n---\nupdated-dependencies:\n- dependency-name: actions/setup-node\n dependency-version: '\n[…]\nirect:production\n update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump actions/setup-node from 4 to 6 (#244)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-06T14:08:28Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "14dc11e402f30ecee18f01951dd0dfb8df940c73",
"body": "Bump the workspace + inter-crate dep refs, the standalone wasm and python\nworkspaces, the JS package, and CITATION.cff to 0.7.1.\n\nSince v0.7.0: #240 pikchr-compat — `.start`/`.end` as `with` anchors on\nclosed objects, `previous` synonym for `last`, `aligned` text (rotate a\nlabel to its segment's ang\n[…]\npt DOI (10.5281/zenodo.21209915, in CITATION.cff/README) is unchanged.\n\n\nClaude-Session: https://claude.ai/code/session_014mdqiuyHrn4zYM2zi5sHPJ\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "release: v0.7.1 (#242)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-06T00:42:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1fa72c6ed5053101ce7b7fe176e5b05bd97fccba",
"body": "…g/small (#240) (#241)\n\nFour pikchr conveniences, all opt-in and corpus 121/121 byte-identical:\n\n1. `.start`/`.end` as `with` anchors on closed objects. rpic already reads\n `box.start`/`.end` (entry/exit edge for the current direction) but the\n `with`-placement path silently centred them. Now `B\n[…]\nges (aligned on rotated, big/small\non font), README list.\n\nCloses #240\n\n\nClaude-Session: https://claude.ai/code/session_014mdqiuyHrn4zYM2zi5sHPJ\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: pikchr-compat — .start/.end with-anchors, previous, aligned, bi…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-06T00:12:02Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "65ba54d9c05c214c55dfd1749eb09371f9dd27b6",
"body": "…#239)\n\nMove it from a hover-revealed figure overlay into the card footer, below\nthe caption. Always visible (better for touch), and out of the figure so\nit never overlaps drawing content (the sorting-network / compass / mini-\ncomputer figures all had top-right content the overlay covered).\n\n\nClaude-Session: https://claude.ai/code/session_014mdqiuyHrn4zYM2zi5sHPJ\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(site): make the gallery \"Open in Studio\" button always visible (…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-05T22:09:17Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "3ddd080b334d6e96f7818fa9fbe2f8e29c3e8f9b",
"body": "…#238)\n\n- DocsLayout: a Home link at the top of the left sidebar (home icon,\n active on the landing page), above \"Getting started\".\n- Gallery: each self-contained figure gets an \"Open in Studio\" button\n (hover-revealed, top-right) that opens it live in studio.rpic.dev.\n\nThe Studio shares source in\n[…]\nsource.\n\nAdds lz-string ^1.5.0 (matches the Studio's encoder version).\n\n\nClaude-Session: https://claude.ai/code/session_014mdqiuyHrn4zYM2zi5sHPJ\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(site): sidebar Home link + \"Open in Studio\" on gallery figures (…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-05T22:01:14Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d577afb40200182f7a6dda5f037956d45b2d8348",
"body": "The 4-column layout squeezed each card so titles wrapped mid-word\n(\"Kernighan-\\nfirst\"). Rework into a roomier 2×2 grid, and give each card\nan emerald-tinted icon tile (compass / layers / blocks / cursor), softer\nrounding, a subtle surface fill and an emerald hover border.\n\nScreenshot-verified in light and dark.\n\n\nClaude-Session: https://claude.ai/code/session_014mdqiuyHrn4zYM2zi5sHPJ\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: redesign homepage feature cards as a styled 2×2 grid (#237)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-05T21:27:19Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "6b85398fc8369220983a598d703cdf84580ea843",
"body": "…236)\n\nThe homepage was frozen at \"v0.4.0 — the styling & typography release\" and\nits feature list predated three releases' worth of work.\n\nHomepage (index.astro):\n- version banner → \"v0.7.0 — typography, colour & editor geometry\"\n- hero copy now names the current capabilities: real typography\n (bo\n[…]\nd \"Built for editors\" bullets surfacing the\n #225/#227/#226/#228 work\n\n\nClaude-Session: https://claude.ai/code/session_014mdqiuyHrn4zYM2zi5sHPJ\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: refresh homepage + README to highlight the v0.5–0.7 advances (#…",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-05T21:07:00Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3dd1f37a1696600759489cbbc0e5d67667ce51d3",
"body": "The v0.7.0 tag minted the concept DOI (10.5281/zenodo.21209915) and the\nv0.7.0 version DOI (…916). Surface it now:\n\n- README: DOI badge + a \"How to cite\" section with BibTeX (concept DOI)\n- CITATION.cff: `doi:` field + an identifiers block (concept + version DOI)\n- rpic.dev homepage: a \"How to cite\" note\n\nThe concept DOI always resolves to the latest release.\n\n\nClaude-Session: https://claude.ai/code/session_014mdqiuyHrn4zYM2zi5sHPJ\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: wire up the Zenodo DOI (badge, CITATION.cff, how-to-cite) (#235)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-05T20:10:22Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9fe33744303a36a0e463a8609596b899b91adb13",
"body": "Bump the workspace and every inter-crate dep ref, the standalone wasm and\npython workspaces, the JS package, and CITATION.cff to 0.7.0.\n\nSince v0.6.2 (all opt-in, corpus byte-identical):\n- #227 per-object geometry export (`objects` in the compile bundle)\n- #226 `canvas from … to …` fixed page / stab\n[…]\nolour literals\n\nThis is the release that mints the Zenodo concept DOI.\n\n\nClaude-Session: https://claude.ai/code/session_014mdqiuyHrn4zYM2zi5sHPJ\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "release: v0.7.0 (#234)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-05T19:55:25Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3ea9d3fcfba2ce50cb7762aa1922c607be6a61c2",
"body": "Re-ran the benchmark on the current binary (the #225 fonts add 841 KB;\nsame-session new-vs-old confirms cold-start is unchanged — the faces are\nmmap'd lazily off the hot path). Refreshed all numbers to one coherent\n6-tool session and enriched the story with statistics:\n\n- table now reports medians (\n[…]\ne for the generated diagrams/results\n\nBoth themes screenshot-verified.\n\n\nClaude-Session: https://claude.ai/code/session_014mdqiuyHrn4zYM2zi5sHPJ\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: re-evaluate performance + add a distribution box plot (#233)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-05T19:41:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "065ea84eefca3cef9abcfbbd6a9822e5eacf86d7",
"body": "Two figure conveniences (both oracle-checked: dpic rejects the words).\n\nrotated <degrees> — per-string text attribute binding like ljust; CCW\n(pic convention), pivoting on the text anchor (SVG rotate(-a x y)).\nfit and standalone-text bounds cover the rotated extent via a padded\naxis-aligned cover (B\n[…]\nions,\nREADME list. Corpus 121/121 byte-identical vs main.\n\nCloses #228\n\n\nClaude-Session: https://claude.ai/code/session_014mdqiuyHrn4zYM2zi5sHPJ\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: rotated labels + native rgb()/0xRRGGBB colour literals (#232)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-05T18:57:27Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f3ad7b1fd027aebe70eedee0c39bbaca0040ebe8",
"body": "New rpic extension (inspired by Pikchr): five text attributes style each\nstring individually, binding like ljust/rjust — to the string they\nfollow, or (written before any string) to the next one.\n\n box \"Heading\" bold \"subtitle\" italic fontsize 9\n box \"code\" mono fit\n \"caption\" font \"Georgia\"\n\n- T\n[…]\nd Maybe → Adopted\n\nCorpus 121/121 byte-identical vs main.\n\nCloses #225\n\n\nClaude-Session: https://claude.ai/code/session_014mdqiuyHrn4zYM2zi5sHPJ\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: per-string font attributes — bold/italic/mono/font/fontsize (#231)",
"author_name": "Andre Leite Wanderley",
"author_login": "milkway",
"committed_at": "2026-07-05T18:33:32Z",
"body_truncated": true,
"is_coding_agent": true
}
],
"releases_count": 20,
"commits_last_year": 264,
"latest_release_at": "2026-07-19T03:53:58Z",
"latest_release_tag": "v0.11.1",
"releases_from_tags": false,
"days_since_last_push": 4,
"active_weeks_last_year": 4,
"days_since_latest_release": 5,
"mean_days_between_releases": 1.7
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": true,
"health_percentage": 71,
"has_issue_template": false,
"has_code_of_conduct": true,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "rpic-cli",
"exists": true,
"license": "BSD-2-Clause",
"keywords": [
"cli",
"diagram",
"graphics",
"pic",
"svg",
"command-line-utilities",
"graphics"
],
"ecosystem": "crates",
"matches_repo": true,
"registry_url": "https://crates.io/crates/rpic-cli",
"is_deprecated": false,
"latest_version": "0.11.1",
"repository_url": "https://github.com/milkway/rpic-lang",
"versions_count": 20,
"total_downloads": 375,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": 125,
"first_published_at": "2026-06-29T16:03:00.718452Z",
"latest_published_at": "2026-07-19T03:53:17.177208Z",
"latest_version_yanked": false,
"days_since_latest_publish": 5
},
{
"name": "rpic-capi",
"exists": true,
"license": "BSD-2-Clause",
"keywords": [
"c-api",
"ffi",
"graphics",
"pic",
"svg",
"external-ffi-bindings",
"graphics"
],
"ecosystem": "crates",
"matches_repo": true,
"registry_url": "https://crates.io/crates/rpic-capi",
"is_deprecated": false,
"latest_version": "0.11.1",
"repository_url": "https://github.com/milkway/rpic-lang",
"versions_count": 20,
"total_downloads": 362,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": 121,
"first_published_at": "2026-06-29T16:02:56.898717Z",
"latest_published_at": "2026-07-19T03:53:13.885581Z",
"latest_version_yanked": false,
"days_since_latest_publish": 5
},
{
"name": "rpic-core",
"exists": true,
"license": "BSD-2-Clause",
"keywords": [
"diagram",
"drawing",
"graphics",
"pic",
"svg",
"graphics",
"parser-implementations"
],
"ecosystem": "crates",
"matches_repo": true,
"registry_url": "https://crates.io/crates/rpic-core",
"is_deprecated": false,
"latest_version": "0.11.1",
"repository_url": "https://github.com/milkway/rpic-lang",
"versions_count": 20,
"total_downloads": 653,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": 218,
"first_published_at": "2026-06-29T16:02:12.084344Z",
"latest_published_at": "2026-07-19T03:52:26.514162Z",
"latest_version_yanked": false,
"days_since_latest_publish": 5
},
{
"name": "@strategicprojects/rpic",
"exists": true,
"license": "BSD-2-Clause",
"keywords": [
"pic",
"svg",
"diagram",
"graphics",
"wasm",
"gsap",
"animation",
"circuits"
],
"ecosystem": "npm",
"matches_repo": true,
"registry_url": "https://www.npmjs.com/package/@strategicprojects/rpic",
"is_deprecated": false,
"latest_version": "0.11.1",
"repository_url": "https://github.com/milkway/rpic-lang",
"versions_count": 18,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": 1,
"monthly_downloads": 3178,
"first_published_at": "2026-06-30T11:27:24.379000Z",
"latest_published_at": "2026-07-19T03:53:26.379000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 5
},
{
"name": "rpic-render",
"exists": true,
"license": "BSD-2-Clause",
"keywords": [
"pdf",
"png",
"rasterize",
"render",
"svg",
"graphics",
"rendering"
],
"ecosystem": "crates",
"matches_repo": true,
"registry_url": "https://crates.io/crates/rpic-render",
"is_deprecated": false,
"latest_version": "0.11.1",
"repository_url": "https://github.com/milkway/rpic-lang",
"versions_count": 20,
"total_downloads": 611,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": 204,
"first_published_at": "2026-06-29T16:02:30.104387Z",
"latest_published_at": "2026-07-19T03:53:09.504748Z",
"latest_version_yanked": false,
"days_since_latest_publish": 5
},
{
"name": "rpiclang",
"exists": true,
"license": "BSD-2-Clause",
"keywords": [
"License :: OSI Approved :: BSD License",
"Programming Language :: Python :: 3",
"Programming Language :: Rust",
"Topic :: Multimedia :: Graphics"
],
"ecosystem": "pypi",
"matches_repo": true,
"registry_url": "https://pypi.org/project/rpiclang/",
"is_deprecated": false,
"latest_version": "0.11.1",
"repository_url": "https://github.com/milkway/rpic-lang",
"versions_count": 19,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": null,
"first_published_at": "2026-06-29T16:20:44.845960Z",
"latest_published_at": "2026-07-19T03:57:12.994881Z",
"latest_version_yanked": null,
"days_since_latest_publish": 5
}
]
},
"popularity": {
"forks": 0,
"stars": 2,
"watchers": 0,
"fork_history": {
"days": [],
"complete": true,
"collected": 0,
"total_forks": 0
},
"star_history": null,
"open_issues_and_prs": 1
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [
"examples"
],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": false,
"bootstrap_files": [],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [],
"toolchain_manifests": [
"Cargo.toml",
"bindings/python/Cargo.toml",
"crates/capi/Cargo.toml",
"crates/cli/Cargo.toml",
"crates/core/Cargo.toml",
"crates/render/Cargo.toml",
"crates/wasm/Cargo.toml"
],
"largest_source_bytes": 142387,
"source_files_sampled": 45,
"oversized_source_files": 4,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"dependencies": {
"manifests": [
"Cargo.toml",
"site/package.json"
],
"advisories": {
"error": null,
"scope": null,
"source": null,
"findings": [],
"collected": false,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 0,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 0,
"direct_affected_count": 0
},
"ecosystems": [
"crates",
"npm"
],
"dependencies": [
{
"name": "@astrojs/mdx",
"manifest": "site/package.json",
"ecosystem": "npm",
"version_constraint": "^7.0.2"
},
{
"name": "@tailwindcss/vite",
"manifest": "site/package.json",
"ecosystem": "npm",
"version_constraint": "^4.3.2"
},
{
"name": "astro",
"manifest": "site/package.json",
"ecosystem": "npm",
"version_constraint": "^7.0.6"
},
{
"name": "gsap",
"manifest": "site/package.json",
"ecosystem": "npm",
"version_constraint": "^3.15.0"
},
{
"name": "lz-string",
"manifest": "site/package.json",
"ecosystem": "npm",
"version_constraint": "^1.5.0"
},
{
"name": "tailwindcss",
"manifest": "site/package.json",
"ecosystem": "npm",
"version_constraint": "^4.3.2"
},
{
"name": "rpic-core",
"manifest": "bindings/python/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "rpic-render",
"manifest": "bindings/python/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "pyo3",
"manifest": "bindings/python/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.29"
},
{
"name": "rpic-core",
"manifest": "crates/capi/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.11.1"
},
{
"name": "rpic-render",
"manifest": "crates/capi/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.11.1"
},
{
"name": "rpic-core",
"manifest": "crates/cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.11.1"
},
{
"name": "rpic-render",
"manifest": "crates/cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.11.1"
},
{
"name": "resvg",
"manifest": "crates/render/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.47.0"
},
{
"name": "svg2pdf",
"manifest": "crates/render/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.13.0"
},
{
"name": "rpic-core",
"manifest": "crates/render/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.11.1"
},
{
"name": "ratex-parser",
"manifest": "crates/render/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.1.13"
},
{
"name": "ratex-layout",
"manifest": "crates/render/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.1.13"
},
{
"name": "ratex-svg",
"manifest": "crates/render/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.1.13"
},
{
"name": "ratex-types",
"manifest": "crates/render/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.1.13"
},
{
"name": "rpic-core",
"manifest": "crates/wasm/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "rpic-render",
"manifest": "crates/wasm/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "wasm-bindgen",
"manifest": "crates/wasm/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.2"
}
],
"all_dependencies": {
"error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
"source": null,
"packages": [],
"collected": false,
"truncated": false,
"total_count": null,
"direct_count": null,
"indirect_count": null
}
},
"maintainership": {
"issues": {
"open_prs": 1,
"merged_prs": 233,
"open_issues": 0,
"closed_ratio": 1,
"closed_issues": 134,
"closed_unmerged_prs": 11
},
"bus_factor": 1,
"bot_contributors": 1,
"top_contributors": [
{
"type": "User",
"login": "milkway",
"commits": 261,
"avatar_url": "https://avatars.githubusercontent.com/u/7375849?v=4"
}
],
"contributors_sampled": 1,
"top_contributor_share": 1
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"ci.yml",
"crates-io.yml",
"docs.yml",
"npm.yml",
"python.yml",
"release.yml",
"winget.yml"
],
"has_docs_dir": true,
"linter_configs": [],
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [
"Cargo.lock",
"package-lock.json"
],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 10,
"reason": "no binaries found in the repo",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": 0,
"reason": "branch protection not enabled on development/release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": 10,
"reason": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 0,
"reason": "Found 0/30 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 3,
"reason": "project has 1 contributing companies or organizations -- score normalized to 3",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 10,
"reason": "update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 10,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 0,
"reason": "project was created within the last 90 days. Please review its contents carefully",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": 10,
"reason": "packaging workflow detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": 1,
"reason": "dependency not pinned by hash detected -- score normalized to 1",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "SAST tool is not run on all commits -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 0,
"reason": "security policy file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": 0,
"reason": "Project has not signed or included provenance with any releases.",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 0,
"reason": "detected GitHub workflow tokens with excessive permissions",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 5,
"reason": "5 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "162041209aae604661ac3e0f32fab8d2a55b35d8",
"ran_at": "2026-07-25T01:30:04Z",
"aggregate_score": 3.8,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": true
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-20T11:14:03Z",
"oldest_open_prs": [
{
"number": 379,
"created_at": "2026-07-20T11:14:02Z",
"last_comment_at": null,
"last_comment_author": null
}
],
"last_merged_pr_at": "2026-07-19T16:19:53Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": []
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/milkway/rpic-lang",
"host": "github.com",
"name": "rpic-lang",
"owner": "milkway"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 60,
"inputs": {
"security": 38,
"vitality": 70,
"community": 45,
"governance": 58,
"engineering": 81
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "good",
"name": "Vitality",
"value": 70,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "moderate",
"name": "Development activity",
"note": null,
"notes": [],
"value": 57,
"inputs": {
"commits_last_year": 264,
"human_commit_share": 0.97,
"days_since_last_push": 4,
"active_weeks_last_year": 4
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 4 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 4
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "4/52 weeks with commits",
"points": 2.8,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 4
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "264 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 264
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "project was created within the last 90 days. Please review its contents carefully",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": null,
"notes": [],
"value": 90,
"inputs": {
"releases_count": 20,
"latest_release_tag": "v0.11.1",
"releases_from_tags": false,
"days_since_latest_release": 5,
"mean_days_between_releases": 1.7
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "20 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 20
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 5 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 5
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~1.7 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 1.7
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "Project has not signed or included provenance with any releases.",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "unverified",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": "repository_too_young",
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": null,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "maintenance record not established from the collected data",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_unverified",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "at_risk",
"name": "Community & Adoption",
"value": 45,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "critical",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 1,
"inputs": {
"forks": 0,
"stars": 2,
"watchers": 0,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "2 stars",
"points": 0,
"status": "missed",
"details": [
{
"code": "stars",
"params": {
"count": 2
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "0 forks",
"points": 0,
"status": "missed",
"details": [
{
"code": "forks",
"params": {
"count": 0
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "0 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 0
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "excellent",
"name": "Community health",
"note": null,
"notes": [],
"value": 85,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": true,
"has_issue_template": false,
"has_code_of_conduct": true,
"has_pull_request_template": false
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (BSD-2-Clause)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "BSD-2-Clause"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 18,
"status": "met",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 13.5,
"status": "met",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
},
{
"key": "ecosystem_adoption",
"band": "moderate",
"name": "Ecosystem adoption (downloads)",
"note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"registry_dependents"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 60,
"inputs": {
"packages": [
"rpic-cli",
"rpic-capi",
"rpic-core",
"@strategicprojects/rpic",
"rpic-render",
"rpiclang"
],
"dependents": null,
"ecosystems": "crates, npm, pypi",
"total_downloads": 2001,
"monthly_downloads": 3846
},
"components": [
{
"key": "monthly_downloads",
"name": "Monthly downloads",
"detail": "3,846 downloads/month across crates, npm, pypi",
"points": 47.8,
"status": "partial",
"details": [
{
"code": "downloads_monthly",
"params": {
"count": 3846,
"ecosystems": "crates, npm, pypi"
}
}
],
"max_points": 80
},
{
"key": "registry_dependents",
"name": "Registry dependents",
"detail": "not reported by this ecosystem",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_reported_by_this_ecosystem",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 58,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 13,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 1,
"top_contributor_share": 1
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "1 contributor(s) cover half of all commits",
"points": 9,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 1
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 100% of commits",
"points": 0,
"status": "missed",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 100
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "1 contributors",
"points": 1.4,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 1
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 1 contributing companies or organizations -- score normalized to 3",
"points": 3,
"status": "partial",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "good",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 83,
"inputs": {
"merged_prs": 233,
"open_issues": 0,
"closed_issues": 134,
"issue_closed_ratio": 1,
"closed_unmerged_prs": 11
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "100% of issues closed",
"points": 46.8,
"status": "met",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 100
}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "233/244 decided PRs merged",
"points": 36.5,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 233,
"decided": 244
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "moderate",
"name": "Ownership & stewardship",
"note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"verified_domain"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 54,
"inputs": {
"followers": 24,
"owner_type": "User",
"is_verified": null,
"owner_login": "milkway",
"public_repos": 36,
"account_age_days": 4476
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "personal (user) account",
"points": 10,
"status": "partial",
"details": [
{
"code": "owner_personal",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": "not applicable to user accounts",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_applicable_to_user_accounts",
"params": {}
}
],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "24 followers of milkway",
"points": 10.1,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 24,
"login": "milkway"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "36 public repos, account ~12 yr old",
"points": 23.4,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 36
}
},
{
"code": "account_age_years",
"params": {
"years": 12
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"rpic-cli",
"rpic-capi",
"rpic-core",
"@strategicprojects/rpic",
"rpic-render",
"rpiclang"
],
"ecosystems": "crates, npm, pypi",
"any_deprecated": false,
"min_days_since_publish": 5
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "6 package(s) on crates, npm, pypi",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 6,
"ecosystems": "crates, npm, pypi"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 5 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 5
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "20 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 20
}
}
],
"max_points": 20
},
{
"key": "not_deprecated",
"name": "Not deprecated",
"detail": "active, not deprecated or yanked",
"points": 20,
"status": "met",
"details": [
{
"code": "package_not_deprecated",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "good",
"name": "Engineering Quality",
"value": 81,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "moderate",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 68,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "7 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 7
}
}
],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 24,
"status": "met",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10",
"points": 20,
"status": "met",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "excellent",
"name": "Documentation",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"topics": [
"animation",
"circuits",
"cli",
"diagrams",
"graphics",
"gsap",
"kernighan",
"pdf",
"pic",
"pikchr",
"png",
"rust",
"schematics",
"svg",
"vector-graphics",
"wasm"
],
"has_wiki": true,
"homepage": "https://rpic.dev",
"has_readme": true,
"has_docs_dir": true,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 25,
"status": "met",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": "https://rpic.dev",
"points": 15,
"status": "met",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": "16 topics",
"points": 10,
"status": "met",
"details": [
{
"code": "topics_count",
"params": {
"count": 16
}
}
],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "at_risk",
"name": "Security",
"value": 38,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "at_risk",
"name": "Security posture",
"note": null,
"notes": [],
"value": 38,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 18,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 0,
"scorecard_aggregate": 3.8
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "no binaries found in the repo",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "branch protection not enabled on development/release branches",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 1 contributing companies or organizations -- score normalized to 3",
"points": 0.8,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "update tool detected",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "project was created within the last 90 days. Please review its contents carefully",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow detected",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 1",
"points": 0.5,
"status": "partial",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "SAST tool is not run on all commits -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "Project has not signed or included provenance with any releases.",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "detected GitHub workflow tokens with excessive permissions",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "5 existing vulnerabilities detected",
"points": 3.8,
"status": "partial",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "excellent",
"name": "High-Risk Jurisdiction Exposure",
"note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
"notes": [
{
"code": "jurisdiction_evidence_limits",
"params": {}
}
],
"value": 100,
"inputs": {
"meaning": "self-published location evidence; not nationality or citizenship",
"red_flag": false,
"exposures": [],
"policy_countries": [
"Russia",
"Iran",
"North Korea"
],
"review_only_matches": 0,
"assessed_self_published_locations": 2
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "moderate",
"name": "AI Readiness",
"value": 62,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "at_risk",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 1,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "no CLAUDE.md / AGENTS.md / editor rules",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_instructions",
"params": {}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "97 of 97 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 97,
"sampled": 97
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "good",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 75,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [
"Cargo.lock",
"package-lock.json"
],
"has_dockerfile": false,
"typed_language": true,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [],
"agent_commit_share": 0.92,
"toolchain_manifests": [
"Cargo.toml",
"bindings/python/Cargo.toml",
"crates/capi/Cargo.toml",
"crates/cli/Cargo.toml",
"crates/core/Cargo.toml",
"crates/render/Cargo.toml",
"crates/wasm/Cargo.toml"
],
"dependency_bot_commit_share": 0.03
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "Cargo.toml, bindings/python/Cargo.toml, crates/capi/Cargo.toml (toolchain convention, no task runner)",
"points": 12.6,
"status": "partial",
"details": [
{
"code": "toolchain_convention",
"params": {
"files": "Cargo.toml, bindings/python/Cargo.toml, crates/capi/Cargo.toml"
}
}
],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "Rust (statically typed)",
"points": 11,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Rust"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "lockfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "lockfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "92 of the last 100 commits agent-authored or agent-credited",
"points": 10,
"status": "met",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 92,
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "3 of the last 100 commits are automated dependency updates",
"points": 8,
"status": "met",
"details": [
{
"code": "dependency_bot_commits",
"params": {
"count": 3,
"sampled": 100
}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 1",
"points": 1,
"status": "partial",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "excellent",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 95,
"inputs": {
"primary_language": "Rust",
"largest_source_bytes": 142387,
"source_files_sampled": 45,
"oversized_source_files": 4
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "Rust (statically typed)",
"points": 45,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Rust"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "4/45 source files over 60KB",
"points": 50.1,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 45,
"oversized": 4
}
}
],
"max_points": 55
}
]
},
{
"key": "ai_interfaces",
"band": "at_risk",
"name": "Machine-readable interfaces",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"example_dirs": [
"examples"
],
"has_mcp_signal": false,
"api_schema_files": []
},
"components": [
{
"key": "api_schema_openapi_graphql_proto",
"name": "API schema (OpenAPI/GraphQL/proto)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 40
},
{
"key": "mcp_server",
"name": "MCP server",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "runnable_examples",
"name": "Runnable examples",
"detail": "examples",
"points": 40,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "examples"
}
}
],
"max_points": 40
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
"Could not fetch crates package 'rpic-wasm' from its registry",
"Could not fetch crates package 'rpic-python' from its registry",
"GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
],
"report_type": "repository",
"generated_at": "2026-07-25T01:30:20.605328Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/m/milkway/rpic-lang.svg",
"full_name": "milkway/rpic-lang",
"license_state": "standard",
"license_spdx": "BSD-2-Clause"
}