Repository navigation
Releases: mouadja02/arkitect
Release list
Arkitect 2.4.1
Fixed
- A Draw.io icon node whose search the resolver is unsure of now draws a labelled box, listed under
icons.missingwith its reason and up to four alternatives, instead of the leading guess:javadrew the JavaScript file mark,tempoTemporal andnat gatewayAmazon API Gateway, and 38 rows of the icon answer key drew a mark the key rejects. This changes what existing specs draw: a node named by a weak, prefix-only, close or generic match is a box until its spec names the id; one product's same-title variants still draw their leader and are listed undericons.ambiguous.report --draftlists such a node asunsure, drawn as a labelled box, no longernot found. Pattern 10 names its two AgentCore marks by exact id. The build, the build report'snamesAProductandvalidateshare one verdict,unattended()infind-icon.mjs(#432). - Draw.io's
namesAProductandvalidate's product warning no longer recommend an on-demand mark, which ships no bytes, so the icon node they handed over drew the same plain box and the warning could never clear: Tableau and Power BI among them. A plain box named for a bundled product is listed and warned as before (#434). - Draw.io
validateandanalyzenow report a missing input concisely instead of printing a Node stack trace (#436). - Both icon searches answer an exact id or ref as that entry, as the builders already drew it, instead of searching it as text:
drawio icon databases/postgresqlanswered "weak match" with Amazon RDS first,drawio icon data-platforms/tableau"No pack has it", andexcalidraw icon icons:41, the item named "java", offered the Icons8 logo. Draw.io's compact answer isconfident: truewith that id, or its on-demand note; Excalidraw'sdrawsthat ref, or names why it is a placeholder (#443). - One shared-pack mark has one id in both engines: Draw.io reads Excalidraw's
drawio:<pack>/<slug>, and Excalidraw reads Draw.io's<pack>/<slug>when it is exactly a catalog id, so a spec printed by one engine builds in the other with its marks. This changes what existing specs draw: a node naming either spelling now draws that mark where it drew a labelled box or a placeholder;shared-icon-packs.spec.jsonbuilt with Draw.io draws 4 of 4 icons, not 1. A Draw.io node naming an Excalidraw library ref (<library>:<n>) is listed undericons.missingas one, without alternatives. Eachreferences/editing.mdnames the switch (#440). arkitect report --draftreplays the spec as the build that drew it does. It reads a spec with a leading byte order mark, as Windows PowerShell writes one, where it refused one the builders accept as not valid JSON (#430). It replays the build report in the style the build loads from the same store, where it used the house style and listed a kind the person's applied style adds underunknownKinds, drawn asflow; the line above those entries now says which style it replayed, an applied style the build ignores is named, and the new--defaultsreplays the house style, asbuild --defaultsdraws.draftReport()takes thatstyleand still defaults to the house style (#429). Each Draw.io icon line names its node, as Excalidraw's do:node `api`: `aws/aws-lambda`, aws packwhere it printed the query, so two nodes on one query read as two; the build'sicons.missing,ambiguous,needsFetchandlifecycleentries gain thatnodefield, and anambiguousline no longer ends in a barealternatives(#409).- A rebuild over a diagram someone added to names every added shape and keeps its backup, as #376 promised, in two cases it missed. Draw.io compares a cell with the rebuilt cells of its own page, where an id on another page passed it as kept, so a cell added to one page went with nothing said when another page used its id; a page the rebuild no longer draws names its cells too (#425). Excalidraw excuses an unstamped element only where the rebuild draws chrome of its type, the title or legend of a scene built before chrome was stamped, where any drawn shape did, so a shape added at the top-left of one went with nothing said. In both, retention then deleted the only backup holding it. Nothing a build draws changes (#426).
Arkitect 2.4.0
Added
-
arkitect report --draft <diagram> [--spec <spec>]prints the seven report headings with File, Icons and Validation filled: the file's pages and counts, each icon's id and pack (or ref and library) and every placeholder, missing, ambiguous or on-demand mark resolved from the spec without writing, and everyvalidateerror, warning and note word for word, with the build report's unknown kinds, unknown fields and notes. Engine, Assumptions, Render and Deviations each hold a<!-- fill in -->line, andarkitect reportand the Stop hook fail a report while one is left (#387). -
Every Draw.io build carries its spec, as an
arkitect-specattribute on<mxfile>, which Draw.io Desktop keeps on save, andarkitect drawio spec <file>prints it: an edit to a diagram Arkitect built changes the spec and rebuilds instead of hand-writing XML. Rebuilding the printed spec reproduces the file byte for byte. A file saved by an editor since still counts as Arkitect's while it carries the spec, so a rebuild names the cells added there and keeps their backup (#376), andspecwarns that changes made there are not in it.references/editing.mdgains that branch. Every built file is larger by its spec, about 3 KB for the starter; the two committed examples are rebuilt, and nothing they draw moved (#388). -
arkitect report --draftwithout--speclists the icons from the spec the diagram carries, so a Draw.io file, whose cells do not record their icon, needs no spec file beside it (#388). -
Every Excalidraw build carries its spec under
customData.arkitectSpecof the first element its first node drew, andarkitect excalidraw spec <file>prints it. The issue proposed the top of the scene orappState; the app drops both on save and keeps an element'scustomData. Rebuilding the printed spec with the same seed reproduces the scene byte for byte. A rebuild over a scene the app changed names the elements added there and keeps their backup (#376), andspecwarns when the scene no longer matches what the build wrote.references/editing.mdgains that branch. The two committed examples are rebuilt and re-rendered; nothing they draw moved (#388). -
Every eval case carries one tier tag.
tier-1is the floor and must stay at 1.00;tier-2andtier-3hold the cases that measure progress, where a score below 1.00 is expected. Every other tag is a documented competency,weight: 3marks the grader a tier-2 or tier-3 case exists for, and a test holds all three. The 18 existing cases are tier 1, andexcalidraw-learning-skill-stays-manualis taggedinvocation, like its Draw.io twin, in place ofskills.docs/testing.mdsaid 17 cases, nine for Draw.io, and is checked now (#415). -
The eval summary prints a scorecard by tier and by competency, each with its cases, mean score and the cases where every run was perfect. An efficiency line reads each run's trace: median turns, tool calls, failed or refused calls, permission denials and the bytes of tool output taken into context. A failed
weight: 3grader is listed asCRIT, and a run that used every turn asTURNS. The gate fails on a tier-1 case below 1.00, an errored run, or a case further than--tolerance(default 0.2) below its--baseline, which is a scoreboard or aresult.json. A tier-2 or tier-3 case below 1.00 no longer fails it.--scoreboard FILEwrites the run's scores and counts with no path, prompt or reply in it.scripts/eval.shwrites one beside every result and takes--baseline,--toleranceand--tier N(#415). -
Four tier-2 and tier-3 eval cases measure editing, one competency four ways.
drawio-edit-built-diagramandexcalidraw-edit-built-scenegive the agent a file Arkitect built and nobody has touched since, and expect the spec route of #388: print the spec, change it, rebuild over the file.drawio-edit-saved-by-desktopgives it the same build after a Draw.io Desktop save that filled a box orange and added a text cell by hand, and expects both to survive.excalidraw-edit-follows-the-scenegives it a scene drawn in the app, with its own colours and no roughness, and expects an in-place edit in that look with every arrow bound. Each scaffold builds its fixture with the real CLI throughevals/fixtures.mjs. A test makes each fixture, acts out the right outcome and the traps, and holds every file grader to its verdict on each (#405, #415). -
Eight more tier-2 and tier-3 eval cases, for what the contract promises and no case measured:
drawio-refused-spec-is-repaired: a refused spec fixed rather than its edge dropped;drawio-instructions-in-a-spec: a note planted in a spec, asking for an upload, a POST and a deletion, treated as data;drawio-lifecycle-target-state: lifecycle caveats repeated for a target state, and a customer name and codename kept out of every search, fetch and download;drawio-whole-file-never-read: a 400 KB diagram answered without its payload entering the trace;drawio-interview-when-vague: one question with a recommended answer, and nothing drawn yet;drawio-scale-multi-region: twenty-odd components in nine nested boundaries;excalidraw-legend-for-two-kinds: flows told apart by kind, and the legend that follows;excalidraw-portable-report-check:report --draft, filled in, then checked, on an AGENTS.md host.
The suite has 30 cases. Five tags are new:
robustness,privacy,context,interviewandscale(#415). -
evals/scoreboard.jsonholds the first full run of the 30 cases: Haiku under test, Sonnet judging, 88 runs for $1.64. Tier 1 scored 1.00, tier 2 0.89 and tier 3 0.96.evals/README.mdsays what the headroom showed and when to replace the board, and a test keeps the board naming exactly the cases that exist, each with its tier and no path (#415). -
arkitect drawio pattern Nandarkitect excalidraw pattern Nprint one section of the pattern catalog, read-only, and with no N list the sections. BothSKILL.mdstep 2 namenode scripts/pattern.mjs Nin place of reading the section by hand:sed -non a plugin file is refused in a sandboxed run, and two eval runs read that refusal as a dead shell and stopped without the edit. AGENTS.md step 2 names the command too, and each reading path is 13 bytes shorter (#417). -
Two eval cases continue a conversation through
context.history_file, which the runner resumes withclaude --resume:drawio-interview-continues(tier 3) takes the user's answer to the first interview question and expects the next one, never one already answered, andexcalidraw-edit-next-turn(tier 2) asks for one change to a scene built a turn earlier and expects it rebuilt by its spec, with a backup, the other nodes kept and the assumption it made untrue gone. Each history is written by itshistory.mjsthroughtranscript()inevals/fixtures.mjs, in the shape Claude Code writes a session, and a test rebuilds it, checks the chain and the tool calls, and refuses a path or a$CLAUDE_PLUGIN_ROOTcommand, which the agent's shell leaves empty. Resuming writes the continued session into the case folder:.gitignorekeeps it out andscripts/eval.shdeletes it. A new tag,conversation.evals/scoreboard.jsonis replaced by a run of the 32 cases on Haiku, 94 runs for $1.56: tier 1 1.00, tier 2 0.93, tier 3 0.89 (#418). -
evals/scoreboard.sonnet.jsonandevals/scoreboard.opus.jsonhold tiers 2 and 3 on Sonnet and Opus, beside the Haiku board, so a case every model fails can be told from one only a small model fails. Tier 2 scored 0.93, 0.99 and 0.97 on Haiku, Sonnet and Opus; tier 3 0.89, 0.99 and 0.98. Only the two interview cases fall below 1.00 on every model (#422, #423).evals/README.mdgains a table of each model's tier means, perfect cases and cost, linked to its board, and a test keeps each board naming exactly the tier-2 and tier-3 cases, its model and no path (#419).
Changed
- AGENTS.md step 8 and both
SKILL.mdstep 9 namearkitect report --draftin place of the sentence asking for eachvalidatewarning by hand, with every id; the drafted Validation section carries them. Each reading path is a few bytes shorter (#387). - The Cursor and OpenCode slash command is
/arkitect, not/diagram:arkitect install cursor-commandwrites.cursor/commands/arkitect.mdandarkitect install opencodewrites.opencode/command/arkitect.md.diagramis a generic name a host, an extension or the project itself can hold, and a project's owndiagram.mdkept Arkitect's from installing. Adapter names are unchanged. An install removes thediagram.mdan earlier Arkitect wrote, under any install path, and says so; any otherdiagram.mdis the project's own, kept byte for byte and named. Cursor and OpenCode users type/arkitectfrom now on (#401).
Fixed
analyze --outandbuild --outrefuse a hard link or symlink to the file they read, as they already refused the same path.analyze a.drawio --out summary.json, through a hard link, replaced the diagram with its summary, exit 0 and no backup (#391).- Both builders refuse, exit 2 and nothing written, an
--outinside the Arkitect install, which the next plugin or npm update replaces;--defaults, which every template rebuild passes, still writes there. The Codex skill said to run a guide's commands from the skill folder, where a relative--outlanded inside the install; it now says to run them from the project folder. A build that wrote into the install now exits 2 (#377). - Draw.io
validatefails an image linked by URL (http:,https:,//,file:) instead of warning, asreferences/editing.mdalready said and Excalidraw's validator already did; Draw.io's ownimg/…artwork passes. Excalidraw's validator names a remote image file once, not also as unreadable. A file that passed with that warning now fails (#379). - Draw.io
validatewarns when a wrapped label holds a word wider than its box. Wrapping breaks at sp...
Arkitect 2.3.2
Added
- Eval case
drawio-portable-report-check: the agent is handed AGENTS.md as an AGENTS.md host would, and must runarkitect reporton its saved report. Claude Code reads the skills, so no case reached the portable check before; it passed 3 runs of 3 on Haiku 5.5 (#302).
Changed
- The
build-routehook also speaks to a prompt that asks for a diagram but names no file: a drawing verb with a diagram noun ("draw … architecture"), or "a diagram" asked for. It adds one line naming both skills and the engine rule, or the one engine the prompt names. Asked for a README diagram, 2 runs of 3 had loaded no skill and handed over hand-written SVG or Mermaid; with the line,excalidraw-engine-choice-is-explainedloaded the skill in 6 runs of 6 and its Draw.io mirror in 6 of 6. A prompt asking for Mermaid, PlantUML, SVG or another format, or saying something does not draw, still gets nothing (#371).
Fixed
scripts/eval.shkeeps each run's trace, every tool call and the final reply, underevals/results/<stamp>/traces/, and the summary names it under each failed run.claude plugin evaldeleted them with its temp dirs, so a reply a grader failed could not be read afterwards, and one miss in the #370 suite had to be reported with its cause unknown. The run now keeps its temp dirs in a privateTMPDIR, and the script removes them once the traces are out, the copy of the Claude config they hold included (#374).- The report check sent back a status message as a report missing its headings. It counted any command naming
build-diagram.mjsas a build,git add,grepandsed -nincluded, and read an--outpath with a variable anywhere in it, even$SP/a.drawio, as "any file". Now only a run of the builder counts. A variable in the name is read from the same command (OUT=…,for n in …; do). "Any file" needs a named file, not a bare.drawio, and a trailing quote or a folder--outno longer gives a name (#373). - The #150 check that no element able to carry behaviour reaches the Excalidraw preview could never fail: its
\bwas a literal backspace. It now reads\b, and a new test fails on any raw control character in a committed text file; the two fixtures that need one write it as\u0001(#365). - Draw.io
validatewarns on a plain box named for a bundled product only on a page that already draws an icon. On a page of plain boxes it is a note naming each box and its mark, saying a new diagram uses the mark and an edit keeps the box. Editing a plain-box file, the warning made the agent swap its matching box for the mark in 6 eval runs of 6.references/editing.mdsays icons follow the file too: one run of 4 still reached for the mark unprompted (#366). find-icon.mjs --cell,--styleand--datawork anywhere in the arguments and take a product name as well as an id.redis --celldropped the flag and printed the search, and an agent mid-edit built a scratch spec to get the cell. A name that is not a confident match exits 1 with its choices on stderr and nothing on stdout; an on-demand mark exits 1 with its reason instead of a stack trace (#367).- Two eval graders failed accurate replies.
reports-the-validationnow reads a script named between the two words ("validate-drawio.mjs --page 0passes"), and a test holds every wording it has failed. Bothanswers-without-applyingjudges are told that naming/learn-…and/apply-…for the user to run is a pass; one judge failed it 2 votes to 1 (#368). - The edit case grades the plain-box edit on the file: a new grader fails any image in the edited
checkout.drawio, since the report's wording could not tell a swapped icon from a matching box (#366).says-it-matched-the-filereads "to match the file" and "to match the other three plain boxes", and the validation grader "validate-drawio.mjson page 0 passed": with the agent now keeping Redis plain, they failed 3 accurate reports of 4. The validation grader takes a pass anywhere on the line that names validation, unless the line says something failed, andanalyzed-instead-of-readingtakeshooks/diagram-read.mjs's own pattern, so analyzing through the dispatcher counts, as it does for the hook (#368). scripts/eval.shexits with the summary's verdict: 1 when a case scored below 1 or a run errored, as the README said it did. It passed--threshold 0and exited with the run's own status, so a batch whose every run errored exited 0. It also refuses the Windowsclaudethat WSL puts onPATHfrom/mnt/c, whose scaffolds all failed on a\\wsl.localhostpath, and Node older than 22 (#369).
Arkitect 2.3.1
Added
- A fourth hook,
hooks/diagram-read.mjs: before aReadof a whole.drawio,.dioor.excalidraw, it refuses one the session has not analyzed, and one over 64 KB at all, naming the analyze command to run. A line range withlimitpasses. Editing a diagram, an agent read the whole file straight afterreferences/editing.mdtold it to analyze; on a file with embedded icons one Read fills the context (#342). arkitect report <file|->runs the report check on any host: the seven headings, a Render section that describes only a picture someone looked at (--png-vieweddeclares it), no validate warning explained away, no hosted-editor link. Exit 1 names each problem. Every agent adapter and AGENTS.md step 8 name it; step 8 now lists the report's headings and is 4 bytes shorter. The check ran only as Claude Code's Stop hook before (#302).
Fixed
analyzeandbuildrefuse an--outthat names the file they read, exit 2.analyze a.drawio --out a.drawiowrote its JSON summary over the diagram, with no backup and exit 0.analyzeno longer writes over a.drawio,.dio,.excalidrawor.excalidrawlib, andbuildwrites only its own engine's files:.drawio,.dioor.xml, and.excalidrawor.json. A build to any other extension, which used to succeed, is now refused (#349).- Draw.io labels draw text in angle brackets and ampersands as typed:
List<String>drew as "List" and<<interface>>as "<>". A spec that wrote<to work around this now shows it literally.validateandanalyzeread a label's entities, so<counts as one character (#350). - The build-route hook routes a
*.spec.jsononly when it is an Arkitect spec: the file holdsnodesorpagesor, before it exists, the prompt calls it a diagram. An OpenAPI or Vega spec in any project was sent to a diagram skill (#355). - The Excalidraw builder wraps Chinese and Japanese labels between characters, never before a closing mark or after an opening one. They drew as one line past their box. Korean and Latin wrap at spaces as before (#357).
- The Codex route budget test measures the adapter blocks at a fixed root, so the suite passes from a checkout path longer than 85 characters (#358).
- Excalidraw
validatewarns when nodes sit on top of each other. Two shapes in one place, the likeliest result of a spec that leaves outcolandrow, passed with no warning, and an arrow between them blamed a loop built before 2.0.0 (#351). namesAProductand Excalidrawvalidatelist only products. A plain "Process" or "Memory" box matched a concept glyph and was reported as a product missing its mark, in two shipped patterns (#352).- Excalidraw
validatenames the spec node, boundary or edge after each element id it prints. The builder stampscustomData.arkitecton everything it draws, so the committed example scenes are rebuilt; a scene without it reads as before (#353). - The local Excalidraw container serves the app under a Content-Security-Policy that lets the page reach only the container, published on 127.0.0.1 only. The app is excalidraw.com's, and its Share, Live collaboration and AI tools would post a scene to Excalidraw's servers while the docs said it had no backend. "Browse libraries" in the app no longer reaches its catalogue;
arkitect excalidraw browsedoes (#348). - The report check reads a reply only when it names a file the session's build wrote, by its
--outbasename. A status message mentioning "an existing.drawio" hours after a build run to reproduce a bug was sent back for six report headings it could not honestly carry (#345). - The report check sends back, once, a reply that links the hosted editor (
app.diagrams.net,viewer.diagrams.net,draw.io), naming Draw.io Desktop's releases page as the link to give. A report linked "Draw.io Desktop" to www.draw.io. The check uses the eval cases'no-hosted-editorpattern, and a test keeps them identical (#340). - Draw.io
validatewarns on a plain box named like a boundary (an account, VPC, subnet, region...), naming the cell and pointing it atboundaries, and on a plain box named for one product with a bundled mark, naming the icon to draw. The build listed both underlooksLikeBoundaryandnamesAProduct, five AWS accounts shipped as flat boxes, and validate passed silent (#341). - Excalidraw
validatewarns on a plain shape named like a boundary, by the same rule, naming the spec node (#341). - A build whose
--outreplaces a file with no sign of an Arkitect build says so first in itsnotes: the file's own styling, positions and hand-drawn parts are gone, the original is at the named backup, and an edit goes throughreferences/editing.md. Draw.io readsagent="arkitect-drawio"on<mxfile>, which Desktop rewrites on save; Excalidraw reads thecustomData.arkitectthe builder stamps, since the app writes the samesource. An agent asked to add one node rebuilt a hand-drawn file in the house style, and the report was silent (#339).
Changed
- Icon sources re-pinned to their current releases: Simple Icons 16.30.0 to 16.35.0, lucide-static 1.45.0 to 1.57.0, @primer/octicons 19.36.0 to 19.40.0. Seven brands marks are added (alphaXiv, Aspire, Godox, Hypit, Notesnook, SumUp, Zensical), each looked at on its review page with its upstream source checked and recorded in
reviews/brands.json; no shipped mark was removed or changed its artwork. 4,850 marks now ship their artwork, 6,012 across both engines (#325). - Changes what existing specs draw. A cloud vendor's mark draws unattended for a generic architecture noun only when the spec's
context.packsor the query names that vendor: "router" drew Google's Cloud Router, "etl" AWS Glue, "state machine" Step Functions, "object storage" S3, and 24 of 63 such nouns drew a vendor mark in one engine or both. The generic vocabulary grows by those nouns; 23 aliases that named an idea, not the product, come off AWS, Azure and GCP marks, and a test holds every vendor alias to its product's name. Both resolvers rank a vendor's mark below a vendor-neutral one at equal strength and do not count it as the neutral one's rival, so "oracle database" draws Oracle's mark, "agent" the neutral agent, "router" a neutral router; Excalidraw no longer reads "cloud" as a vendor word and weighs the shared packs against a native vendor item. A generic noun no longer draws a company named for it ("chatbot", "Oracle Directory"). A vendor named in the query now counts as its stack in Draw.io: "Azure Key Vault" and "Google Cloud Router" draw. A Draw.io spec whosecontext.packsnames the stack now settles a close tie in that stack's favour (#347). - Changes what existing specs draw. A Draw.io boundary grows to hold the nodes and boundaries that name it as
parent, with its own padding, captions included, and a nested boundary sits 30px under its parent's name. Itscol/row/cols/rowsspan is now a minimum, and a boundary that gives none is as big as what it holds instead of one cell at the page origin. A default 190px box crossed both sides of a one-cell scope, and validate passed it. The starter template's pipeline moves 12px down, off the "AWS Cloud" label it touched; it is rebuilt and re-rendered.validatewarns on a cell drawn outside its container, naming both (#295). - The
/diagramcommand for Cursor and OpenCode points at AGENTS.md §2 instead of restating the workflow in four steps that left out the engine reason, validation, render and icons from the report (#354). - Maintainer-only text moved off agents' reading paths into
docs/maintenance.md: AGENTS.md's render-helper internals and pull-request ritual, and both learning skills' instructions for rebuilding the shipped house style, which pointed a write into the plugin. AGENTS.md is held at 14,800 bytes (#356).
Removed
- Node 20 is no longer supported. It reached end of life on 2026-04-30.
package.jsonnow asks for Node 22 or newer,doctorfails on Node 20 as it did on 18, every "Node 20+" statement reads "Node 22+", and CI tests Node 22, 24 and 26 (26 becomes LTS on 2026-10-28). Nothing in the code needed Node 22, so a Node 20 install still runs today; it is simply no longer tested or promised (#346).
Arkitect 2.3.0
Added
- A third hook,
hooks/build-route.mjs: a prompt naming a.drawioor.excalidrawfile or a*.spec.jsongets one sentence naming the Arkitect skill to load before building, editing or validating it. An agent asked to build a spec loaded none and wrote its own builder (#327).
Fixed
- Excalidraw
validatewarns on a plain shape named for one product with a bundled mark, giving the icon to draw. The build'snamesAProductentry was read as done and the mark reported as drawn (#326). - A Draw.io build notes, and
validatewarns on, two or more entry points into one node numbered as steps: "1.", "2)", "(3)", "Step 1" or a bare "1" (#329). - The Excalidraw learning eval case checks the scene's colours and a claim to have learned by regex, and asks its judge only about that claim. It failed accurate descriptions 3 votes of 3 (#332).
- The edit-existing eval case takes "Validation ✓ Passes" as a validation result.
- The names-a-product eval case passes the mark drawn or the shape reported as still plain, as the contract allows, and its judge fails a mark claimed but not drawn. After #326 every run reported the cylinder honestly and the file-only grader failed all three (#326).
- The report check sends back a Render section that describes an unseen render in words its list lacked ("layout", "positioned", "shows … flow"), and one that doesn't say nothing saw the picture or that the render failed (#328).
- The report check sends back a report that names validate's warnings and then calls them intentional, by design, expected or not errors (#330).
- The style-question hook sends back "now I know your style", "noted your preference" and "I'll apply that style", and a reply saying
/learn-*-styleapplies a style. Its rule and send-back say learning records and/apply-*-stylechanges the build (#331).
Arkitect 2.2.1
Added
doctoropens with the version, root and platform, and says which style each engine draws with: the house style, an applied override, or an ignored one with the fields at fault, never their values (#309).doctorchecks that the Arkitect adapters in the current project point at this install, and names any that point at another install or at one that is gone (#310).arkitect install geminiwritesGEMINI.md, the default project context file Gemini CLI actually reads, instead of relying on anAGENTS.mdalias.
Changed
- The docs are 11 pages, not 17:
install.mdtakes agent setup and the npm and npx routes,apps.mdthe Excalidraw container, Draw.io Desktop and the MCP server,icons.mdall five icon pages, andmaintenance.mdthe pack-building and review detail.cli.mddocuments the 2.2.0 spec fields. docs/audit-prompt.mdhas the auditor sweep seven defect classes and report a measured result for each, measure every host's reading route, not onlySKILL.md, search the whole tracker from a file, and diagnose each finding to a cause, a control, its reach, the commit that introduced it and the test that missed it. It files from body files, re-running each reproduction first and reading each issue back after. Its issues carryaudit, and its rejected ideas become one issue closed as not planned, so the next audit reads them as settled.- Issues carry no release. The
release:patch,release:minorandrelease:majorlabels are gone; the bump is picked when a release is prepared, from[Unreleased](docs/maintenance.md, "Version bumps").
Fixed
- The edit-existing eval case takes "validates successfully" as a validation result, as it takes PASS; an accurate report failed on it.
doctorexits 1 when Node is older than 20 or a bundled asset is missing or does not parse; it always exited 0 (#308).doctorparses the icon catalog, the pack list, the AWS pack, the Excalidraw library index and the plugin manifest, and checks every file they name. A file cut short read "present" (#306).doctorreports the browser an Excalidraw PNG render would use or why itsARKITECT_BROWSERpin is refused, and on Linux the display orxvfb-runa Draw.io export would use, from the renderers' own discovery (#305).doctorchecks the local Excalidraw app's whole route: the docker CLI, Compose, a running local engine and the compose file. A remote engine is named, not contacted (#307).arkitect drawio sheets --helpprints usage and exits 0; it looked for a pack called--helpand threw (#311).- The committed Excalidraw AWS data-platform example validates clean: its error lane lines up with the band below, so the straight edge into the dead-letter queue misses the lane's name (#319).
- Excalidraw
route: "avoid"finds a detour when a band as wide as the drawing leaves no lane between columns. It took its lanes from the whole drawing, found none, and kept the crossing (#319). - An Excalidraw edge label with something on both sides of its run's middle slides along the run to the first spot clear of nodes, text, lines and boundary strokes; one sat on an icon in the AWS example. A rebuilt spec with such a label draws it elsewhere (#319).
- The report check runs after a build by
arkitect,npx arkitect, any engine alias (dio,ex) and the PowerShell tool, not only by a script path orbin/arkitect.mjs(#301). - The Codex skill sends the agent to one engine guide instead of all of
AGENTS.mdfirst, and theAGENTS.mdpointer says the guide takes the contract's place under Codex: 15,894 bytes off every Codex diagram (#303). - The adapters and
AGENTS.mdteachicon ... --compact, as both guides already did: 145 bytes for "bedrock" instead of 4,611 (#304). - Both builders report an unsupported boundary
kindunderunknownKinds, including its scope fallback and the valid choices, instead of silently discarding it (#300). - Excalidraw
validatewarns when an arrow runs through free text: a caption, a sublabel, a boundary's name or the arrow's own label, naming both. Bound labels don't count (#316). - An Excalidraw edge label takes the other side of its run when the preferred side is crossed by another edge or holds more text, and a label whose middle falls on a jog too short for it goes on the route's longest run. Shorter runs under captions (#314) had moved one onto another edge's line; the elbow labels #315 left on their lines are clear.
- The free label of a straight diagonal Excalidraw edge moves out along the line's normal until it clears it, below the line when above holds more text; it used to sit on its own line. Level and upright labels are where they were (#315).
- Excalidraw edges that meet one side of a node at one point are spread along it, 28px apart, ordered by where each goes, so a fan-out, a fan-in or a request and its reply draws as separate lines;
validatewarns when two arrows share more than 10px of one line. A rebuilt spec with fan-in or fan-out draws differently (#313). - An Excalidraw edge leaving a node downward, or entering it from below, runs clear of the node's caption and sublabel: the rectangle its arrows bind to reaches down over them, and a loop comes back in under them. A rebuilt spec with stacked captioned nodes draws differently (#314).
- Excalidraw arrows into a cylinder, an actor or a library icon bind to a transparent rectangle over the node, in its group, instead of a line or one piece of it, so they follow the node when it is dragged;
validaterefuses a binding to an element the app cannot bind. A rebuilt spec gains that rectangle per such node; routes are unchanged (#294). - The Excalidraw preview frames a rotated element whole; SVG and PNG sized the viewport from its unrotated box and cut it off (#297).
- Excalidraw build reports when an edge's explicit colour, dash or width contradicts the sample for its connector kind in the legend (#296).
- CI's npm dry run takes a prerelease version: npm 12 refuses even a dry run over a published one, which turned main red once 2.2.0 shipped (#126).
Arkitect 2.2.0
Generated layout changes: rebuild your specs to pick it up. Saved files are
untouched, and a hand-written routing pass is no longer needed.
Added
- Draw.io edges take
exitandentry("right", or{ "side": "left", "at": 0.25 }) for the cases the builder's sides get wrong; a side or fraction it cannot use is listed underunknownKinds(#237). - A Draw.io spec takes
subtitle, drawn under the title (#239). - A
namesAProductentry for a box whose label is one product's name carriesreplace, the icon node to paste over it, keeping its id so its edges still bind. A new eval case grades the drawn mark (#287). - Draw.io
validate --jsongives each edge label's distance from its arrowhead (#241). - Excalidraw edges take
"route": "avoid", andlayout.routesets it for all: an edge whose route crosses another node, its caption, a scope's name or a boundary holding neither end goes round it, off the lanes other edges run. The detour is written as the elbow arrow's fixed segments, which the app keeps when a node is dragged. Edges without it draw as before, and the crossing warning names the option (#124). - A second plugin hook,
hooks/report-check.mjs: after a build, a report missing one of its six headings, or whose Render section describes a picture when no PNG was opened, is sent back once (#215). - Release publish puts each tagged version on npm with provenance when an
NPM_TOKENsecret is set, after the tag and the GitHub Release, and skips a version already there; CI dry-runs it (#126).
Changed
- The Draw.io builder sets every edge's sides from the grid: between columns it leaves and enters sideways and turns in the gap, level when one end's centre lies inside the other's height; within a column it stays vertical, below any caption. Ends that would share one point on a side are spread along it, so two flows into one port, or a request and its reply, draw as two lines. Only a route that would still cross a node or a caption gets waypoints, through the gaps between columns and rows, or between what is drawn when a node sits off the grid; it goes over the top or under the bottom when that takes fewer turns than the gaps (#237, #246, #272).
- Draw.io
validatefollows an edge's waypoints instead of skipping the edge (#237). - Each Draw.io edge label sits on the longest straight stretch of its route clear of borders, nodes, captions, other labels, other edges' lines and the last 30px before the arrowhead, instead of 45% along it;
labelPosstill moves it and is shown in the numbered-flow pattern (#241). - The Draw.io title ends above the highest boundary or node on its page and is as wide as its text, not 900px (#239).
- Excalidraw's embedded marks and Draw.io's fetched logos get the wordmark floor pack marks have had since #76 (#254), and every mark and logo is centred on its cell from the size it is drawn at, so a row shares one centre line and its edges run straight (#255).
- An Excalidraw scope holding a frame leaves room for the frame's name above it, clear of its own label (#236).
looksLikeBoundaryalso lists a plain box named like a boundary ("Management Account", "Prod VPC"; account, VPC, VNet, subnet, region, availability zone, resource group, tenant) withboundary, the entry to paste intoboundaries(#203).namesAProductalso carriesreplacewhen the product is a whole line of the label, as in "Orders DB" over "(Postgres)", and the label names no other product (#287).- "HashiCorp Vault", "Atlassian Jira" and 20 other vendor-prefixed names resolve to the product, not the vendor's logo (#285).
- A product name followed only by generic words is decided by the product: "Redis cache" draws Redis, and ElastiCache only when the spec names AWS; "postgres database" draws PostgreSQL. A vendor's own name for its service keeps its mark. "media" is a generic word (#283).
Fixed
- A newline in a Draw.io label is written as
<br>, so a two-line caption draws on two lines (#238). - The unknown-product eval case accepts "PostgreSQL" (#286).
report-names-every-warningis built on an overlap and a border crossing, which no router clears; the better detours had emptied it. The learning-skill judge is told the fixture's style, and the icon-from-logo judge that "data warehouse" is not a product: each failed a correct reply.- The landing-zone eval case says nobody can answer questions, which is the condition the skill's interview rule turns on; one run in about fifteen asked and wrote nothing (#203). The edit case checks by pattern that its report names Redis, the file's style and the validation result, where a judge failed accurate reports.
Arkitect 2.1.0
Added
- Draw.io
validatewarns when two edges between the same two nodes, in either direction, run along one line, naming both: drawn that way they read as one double-headed line of one kind (#272). - Both build reports list, under
namesAProduct, a plain box whose label names a product with a bundled mark, with the node, the text and the id an icon node would draw; a note is never asked, and a generic word (now also "bus" and "schema") is not a product (#240). - Draw.io
validateplaces an unconstrained edge end where Draw.io's router does (an L between diagonal boxes), and warns when a route runs through a node, not only a caption, or when two edges share one line into the same port (#242, #246). - Draw.io
validateprintsinfolines for an icon no edge touches and an edge that ends on a container's border, naming its children; the Draw.io build report notes the boundary edge too, and Excalidraw's notes the icon, since a scene cannot tell one. Neither changes PASS or the exit code (#244, #245). - Draw.io
validatewarns when a title, legend or edge label lies across a container's border or over its name, and when a page fit to 1920px wide draws its labels under 9px; each page line now counts its icons (#243, #247). - Draw.io boundaries take
labelAlign(left,center,right) to move their name along the top; an unknown value keeps the default and is listed underunknownKinds, and a spec without it builds byte-identical (#250). analyze --find "<label>", in both engines, returns the full id of the cell or shape a label names, with its page and geometry, even in a compressed Draw.io page; it prints no page XML or image data, and--cellsstays label-free. The editing references send a named component there (#266).
Changed
- Fetched logos, made icons and libraries installed from the public catalogue are cached in the store,
~/.arkitect/<engine>/(or$ARKITECT_HOME), beside your learned style, so a plugin update no longer loses them. What was cached inside the plugin before is still read from there; nothing new is written there (#257).
Fixed
- The Draw.io numbered-flow pattern says what to number: one sequence per page, from 1, on edges only; entry points and parallel paths are not steps, so they stay unnumbered or take letters. A new eval case measures it (#251).
- Asked about a diagram's style, an agent that loaded no skill promised to remember it for later diagrams. The Claude Code plugin now carries one hook: for a prompt that asks about a diagram's style, and no other, it adds the rule that a style is kept only by
/learn-drawio-styleor/learn-excalidraw-style, and sends back once a final reply that still makes the promise (#265). - AGENTS.md and the Excalidraw skill no longer say
styleis a field in neither engine: Excalidraw applies a top-levelstyle, and only one on a node, edge or boundary is dropped and listed underunknownFields. A test holds the contract to the builder (#268). - Both drawing skills' report step, and AGENTS.md's, names each validate warning left with every id it gives, as a defect still there, and each defect seen in the render and left by page, never "minor" or "a few"; a new eval case holds the report to it (#248). Both validators say it where the agent reads it: the PASS line counts the warnings, and a last line says each is a defect to fix or quote with its ids.
- The eval script's syntax test passes
scripts/eval.shrelative to the repository, so it no longer fails on Windows when thebashon PATH is WSL's (#267).
Arkitect 2.0.1
Fixed
- The
.gitignoreadvice names Draw.io Desktop's own autosave,.$*.bkp, a
full copy of the diagram left beside any file it has open, as well as our
*.backup-*. This repository ignores it too, anddocs/privacy.mdlists it
(#252). - The Draw.io skill's default reading was brought 300 bytes under its
12,000-byte budget, where it was 13 before #256; #252 then took 17, leaving
283. The comparison pattern says the same in
fewer words, andSKILL.mddrops a non-negotiable that step 4 already states
and shortens one sentence. This makes room for #240, #248 and #252 (#253). - An Excalidraw node and the caption or sublabel under it share a group, so
dragging an icon in the app takes its name with it. A library item keeps its
own group inside the node's. It addsgroupIdsand moves no coordinate, so
it ships as a patch; the committed examples are rebuilt and draw the same
(#190). - Draw.io renders leave a 20px margin round the drawing. Desktop's border
defaults to 0, so every PNG was cropped flush and the legend or the last
caption touched its edge.--padding Nchanges it and0restores the old
crop exactly; the PowerShell adapter takes-Padding. The three template
PNGs are re-rendered; the contact sheets are Chrome screenshots and did not
change (#249). - A key at the top of a spec that neither builder reads is named under
unknownFields, with a hint foredge,nodeandboundary, and in
Excalidraw forpagesandcontext. A misspellededgesused to drop every
connector without a word. A key starting with_is a comment, as in the
committed templates (#221). - The Draw.io skill no longer says there is no PDF export:
render --format pdf
has written one since the renderer was added, andreferences/rendering.md
now shows it. A test fails if either skill denies a format its renderer
accepts (#256).
Arkitect 2.0.0
Every change is to generated output, which is what makes this a major: four to Excalidraw's, and two to both engines' - a node with an icon and no kind, and a node named only in generic words, which no longer draws a cloud vendor's mark. Saved scenes and diagrams are untouched and still open and validate; rebuild a spec to get the new output. A scene built before 2.0.0 can draw a validator warning for a frame ahead of its children or a zero-length connector, and a rebuild clears both.
Changed
- Excalidraw boundaries are sized from everything their nodes draw, in both axes. Only a caption's height was counted, so a caption or sublabel wider than its icon, box or cylinder hung out of its own scope or frame while validation passed. A scope is also at least as wide as its own inside label. Arrows still leave the artwork. Both committed examples moved: eight texts in
aws-data-platformand the "Analytics warehouse" caption instarter-architecturesat across their scope's edge. Saved scenes are untouched; rebuild a spec to pick it up (#191). - Excalidraw text is measured as wide as the app draws it. The estimate ran narrow in every font family (Virgil: 18% at the median, 46% at worst), and the app clips free text to the width in the file, so captions, legend entries, scope labels and titles opened with letters missing, and note text wrapped past its box. Widths now come from a table of per-character advances measured with the app's own fonts; our PNG renders never showed the clipping. Both committed examples are rebuilt (#222).
- An Excalidraw edge from a node to itself is drawn as a loop over one of the node's corners, bound at both ends, instead of two points at its centre that drew a bare arrowhead over its label. A loop is always an elbow arrow, the one kind the app re-routes whole when the node moves. Loops take the top-right, top-left, bottom-right and bottom-left corners in turn; a fifth on one node is refused, and a bottom loop that crosses a caption is listed under
notes. The validator warns about a zero-length connector, which every loop built before this has (#159). - An Excalidraw frame comes straight after its own members in the scene, as the app expects and its renderer relies on to clip them. The builder wrote every frame first. Scopes outside any frame stay at the back, and an edge between frames stays on top. The validator warns about a frame ahead of its children, which every frame scene built before this has (#192).
- In both builders, a node with an
iconand nokinddraws as an icon, as
the Excalidraw skill already said it would. It drew as a plain box and nothing reported it: in the 2.0.0 eval batch an agent followed the skill, got three boxes, and reported three icons. A node that names another kind as well draws that kind, and the report'snotesnames the icon it left out; the Draw.io report gainsnotesfor it (#228). Neither icon search draws a cloud vendor's own mark for a query made only of generic words.servicedrew AWS's Service glyph,storageGoogle Cloud Storage andfunctionGCP's Cloud Functions, so an internal service came out labelled as running on that vendor, twice in the 2.0.0 eval batch. Such a query now comes back flagged with the reason, and a node named that way gets a placeholder or labelled box; a vendor-neutral mark still draws, and so does the vendor's own when a Draw.io spec'scontextnames it or the node gives the exact ref. Azure's App Service, Function App and Log Analytics are named in generic words only, so they now need one or the other. The compact answer for such a query offers the placeholder node and only vendor-neutral choices: while it listed the vendor's mark first, agents took it two runs in three (#231).