Skip to content

Releases: ChanMeng666/archlang

v1.18.0

Choose a tag to compare

@github-actions github-actions released this 14 Jul 22:42
d419003

Two behaviour improvements to arch suggest (suggestTopology), requested by the downstream
ArchCanvas product, which persists a chosen candidate's insertText back into .arch source. Both
are unconditional — per ADR 0005 suggestions
are deterministic data, and the new behaviour is strictly more correct, so there is no opt-in flag.
The public Suggestion / SuggestionCandidate types are unchanged; only the string a candidate
carries (and, for one fault, candidate order) changes.

Changed

  • Candidates reference walls only by a STABLE ref. A candidate's insertText used to be able to
    name a wall by its positional auto-id (e.g. door on partition_3 at 50%), which re-indexes
    silently when a later edit inserts an earlier same-category wall — corrupting any persisted
    suggestion. Each candidate now composes its placement as the first available of: an author-declared
    wall id
    (on <id>), a unique wall category (on <category>, valid iff exactly one wall carries
    it), or absolute coordinates (at (x, y), which name no wall — the compiler's nearest-wall
    hosting binds the intended one). A positional auto-id is never emitted. Applies to all four
    builders (entrance, unreachable-room, bedroom-window, bath-via-bedroom).
  • A private unreachable room prefers reconnecting inward. For W_ROOM_UNREACHABLE on a private
    room (bedroom or wet room), interior candidates that reconnect to a space already reaching the
    entrance now rank above exterior (new-outside-door) candidates, regardless of run length; within
    each group the existing longest-free-run order is kept. Non-private rooms keep the pure geometric
    order. W_NO_ENTRANCE (exterior-first by design), W_BATH_VIA_BEDROOM (already interior-preferred),
    and W_BEDROOM_NO_WINDOW (windows are exterior-only) are unchanged.

Internal

  • RWall carries an internal _idAuthored marker (set in resolve from assignIds' knowledge of
    whether the id was author-declared; _-prefixed, never serialized into the Scene/exports), so
    suggestTopology can tell an authored id from an assigned positional one.

v1.17.0

Choose a tag to compare

@github-actions github-actions released this 14 Jul 06:09

Agent-CLI round: the arch CLI audited against the 7 Principles for Agent-Friendly
CLIs
rubric and hardened where it fell short.
The audit's good news is that the foundations already held — zero interactive prompts, zero ANSI
colour, --json almost everywhere, a documented 0/2/1/3 exit contract, a uniform stdin - seam,
and JSON diagnostics that already carry their own fixes. What it found was one blocker (a CLI an
agent literally could not ask for help), a parser that silently swallowed typo'd flags as
filenames
, a fix that clobbered your source with no preview and no recovery, and reads that
had no way to be narrowed. All four are closed here. The language is untouched; compile() stays
pure and its default output byte-identical.

Added

  • Per-command help — the blocker. arch <cmd> --help and arch help <cmd> now print help.
    Before this, --help after a verb fell through parseArgs into the positionals and was read as a
    filename (cannot read --help), so the standard two-hop probe an agent uses to learn a CLI —
    top-level help, then subcommand help — was broken at the second hop.
  • The manifest now carries worked examples[] per command (a required field), and a new
    src/cli/help.ts renders both the top-level and the per-command help from the manifest.
    The hand-maintained HELP string — a second, un-drift-tested source of truth for the command list
    — is gone, so help can no longer advertise a flag a command doesn't take.
  • arch --version.
  • arch fix --backup — saves the original bytes to <file>.bak before rewriting in place
    (opt-in, so no .bak litter by default), and fix now prints the unified diff it would write
    to stderr, --dry-run included. fix rewrites your source; it should be previewable and
    reversible.
  • Bounded reads (so one big plan can't blow an agent's context window):
    arch describe --select <keys> / --room <ids>, arch lint|validate --code <CODE> /
    --severity <sev>, and arch context --section <spec|workflow|cli|errors> — the error catalog
    alone drops the bundle from 60,187 → 13,161 bytes.
  • unifiedDiff moves from dataset/ into the pure core as src/unified-diff.ts (zero-dep,
    deterministic); dataset/diff.ts re-exports it.

Changed

  • An unrecognized flag or verb is now a usage error (exit 3), not a silently-swallowed filename.
    A FLAG_KEYS parse table replaces the old if/else chain and is bidirectionally drift-tested
    against the manifest
    , so the parser, the help, and the docs cannot disagree about what a command
    accepts. arch lint --jsn now exits 3 with did you mean \--json`?and ausage:echo;arch complesuggestscompile`.
  • Human-mode diagnostics print the catalog's = fix: line. JSON mode already carried it; a
    human (or an agent reading stderr) previously had to make a second call to arch explain <CODE>.
  • arch lint --profile <bogus> routes through usageError like every other bad-usage path (it used
    to return a bare 3 with an ad-hoc, prefix-less message).
  • arch md validates -f through the shared parseFormat instead of a hand-rolled check, so an
    unknown format gives the same error everywhere.
  • Bare arch prints its help to stderr (exit code 3, unchanged) rather than stdout — a missing
    command is a usage error, and its output shouldn't pollute a pipe.
  • Previously-ignored misplaced flags (e.g. arch describe --strict, on a command that takes no such
    flag) now exit 3 instead of being ignored.

Invariants pinned by tests

  • A display filter never changes gating. --code / --severity / --select / --room filter
    what is shown; the exit code and ok are computed from the unfiltered diagnostic set, so
    lint --code W_FOO on a plan failing for a different reason still fails.
  • The context --section splitter is welded to its generator by a test that regenerates
    llms-full.txt in memory and asserts the split — a format change breaks loudly instead of
    silently slicing garbage.

v1.16.0

Choose a tag to compare

@github-actions github-actions released this 13 Jul 23:00

Downstream-driven round: ArchCanvas's archlang-1.15 adoption surfaced two upstream gaps its own
ship gate + topology fixer had already filled locally, so those capabilities move upstream as
advisory data
and the generated agent docs are re-pointed to teach the v1.13 placement sugar
where models actually imitate it — the worked examples. Core stays zero runtime dependencies; the
default SVG output is byte-identical throughout.

Added

  • suggestTopology gains two connectivity-fault kindsSuggestion.code widens 2 → 4 to
    W_ROOM_UNREACHABLE | W_BEDROOM_NO_WINDOW | W_NO_ENTRANCE | W_BATH_VIA_BEDROOM. Both new builders
    are ported from capabilities proven in ArchCanvas's production topology fixer and each mirrors the
    semantics of the matching arch lint rule so a suggestion fires iff the lint fires:

    • W_NO_ENTRANCE — fires when the plan has an exterior wall but no entrance
      (access.hasEntrance === false). Emits door on <wall> at <pct>% width 900 candidates on the
      longest opening-free exterior run of an entrance-suitable room (not a bedroom, not a wet room),
      falling back to the remaining rooms only when no suitable room touches an exterior wall; the
      rationale names the room and that this creates the building's entrance.
    • W_BATH_VIA_BEDROOM — reuses the two-BFS pattern from the reachability lint (reach-all vs
      reach-excluding-bedrooms) to find a wet room reachable only through a bedroom, and suggests a
      door onto a neighbour that itself has a bedroom-free route (non-bedroom neighbours preferred over
      an exterior-wall fallback regardless of run length — reconnecting to circulation is the real fix).
      One suggestion per affected wet room.

    Both stay ADR 0005-compliant (facts and lint, not an architect):
    deterministic, closed-form, data-only, fail-open ([] on ambiguity or a resolve error), ordered by
    the existing free-run-length → wall-id → position tie-break, top 3 — never applied.

  • Furniture-aware door candidates. For door candidates only, the blocked-span computation now
    also subtracts wall runs where a furniture footprint intrudes into the door's approach corridor — the
    strip inside the target room along that wall, APPROACH_DEPTH = 900 mm deep — so a suggested door
    never opens straight onto a piece. Windows are exempt (furniture under a window is normal). The three
    door builders (W_NO_ENTRANCE, W_ROOM_UNREACHABLE, W_BATH_VIA_BEDROOM) feed the furniture-blocked
    runs into longestFreeRun; the window builder is unchanged. Fail-open — a furniture-free plan yields
    no blocked runs, so every pinned golden (all furniture-free fixtures) stays byte-identical.

Changed

  • The generated agent spec now teaches attachment-first through its worked example.
    scripts/gen-llm-spec.ts's SPEC_EXAMPLES swaps the coordinate-math studio.arch for the
    attachment/strip/anchor attached.arch as the flagship worked example (parametric.arch stays second
    as the sanctioned computed-at idiom); neither examples/*.arch file changed. The ## Common mistakes table is rewritten from coordinate fixes to attachment-first guidance (off-wall opening →
    on <wall> at <pos>, hosted by construction; hand-summed room offsets → strip; a guessed furniture
    atin <room> anchor <9-point>), keeping the genuinely universal rows (mm units, +y down, unique
    ids). The fix-topology prose now names all four suggest kinds and leads with arch suggest --json.
    spec.llm.md regenerated (~15.9 → ~14.8 KB; llms-full.txt regenerated in the same chain).
  • SKILL.md anchor grammar corrected. The stale anchor <corner|edge> placeholder becomes the real
    nine-point token list (top-left, top, top-right, left, center, right, bottom-left, bottom, bottom-right),
    and the topology section names all four suggest faults and notes the candidates are furniture-aware.
  • CLI / MCP prose lists all four suggest kinds. The arch suggest usage line (src/cli.ts), the
    cmdSuggest doc comment (src/cli/commands-author.ts), and the MCP suggest tool description
    (packages/mcp/src/server.ts) now name unreachable / no-entrance / bath-via-bedroom / windowless-bedroom
    and note the attachment form + furniture-awareness. No wiring change — the raw Suggestion[] passes
    through untouched. The MCP shim republishes as @chanmeng666/archlang-mcp@0.2.1 (version-bump-only
    release so the refreshed tool description actually reaches npm and the MCP registry — the release
    workflow's idempotency guard would have skipped an unbumped 0.2.0).
  • suggestTopology's pre-existing W_ROOM_UNREACHABLE builder is now gated on the plan having an
    entrance.
    An entrance-less plan previously produced per-room W_ROOM_UNREACHABLE suggestions; it now
    yields the single W_NO_ENTRANCE suggestion instead, matching the lint's own suppression behavior (the
    reachability rule reports no-entrance, not per-room unreachability, when there is no way in). No pinned
    golden is affected — the existing faulty fixture has an entrance.
  • Note (eval baseline): spec.llm.md is the eval's author prompt, and this change replaces a worked
    example in it, so it now differs from the prompt behind the calibrated live baseline. No scoring/judge/fixture
    code changed; re-running the paid live baseline under the new prompt stays a separate, owner-approved action
    (default: not run).

v1.15.0

Choose a tag to compare

@ChanMeng666 ChanMeng666 released this 13 Jul 06:22

Roadmap Tranche 6 resolved (2026-07-12): Gate G2 closed with residual area failures = 0/8
on the calibrated baseline (docs/research/2026-07-g2-verdict.md) — the T6 area-syntax sugar
is parked behind frozen reversal triggers, and only the tranche's unconditional Track B
items ship below.

Added

  • matchVocabulary — one shared closed-vocabulary matcher, and the advisory W_ALIAS_MATCH.
    The token-bounded matcher core (normalizeLabel/synonymMatchesLabel) moved from
    src/intent-concepts.ts into new src/vocabulary.ts, and the scattered room-label regexes in
    analyze.ts/analyze/circulation.ts are re-expressed as its data-driven USE_VOCABULARY
    (canonical vs alias words per use kind). One matcher core, two vocabularies at two layers — the
    brief-level CONCEPTS table and SYNONYMS_VERSION are untouched (judge fixture byte-green; no
    second concept table). New advisory W_ALIAS_MATCH fires when a room with no authored
    uses classifies only via an indirect alias ("Powder" → WC, "Foyer" → entry), carrying a
    machine-applicable fix that inserts the explicit uses …; corpus classification is pinned
    byte-identical by test/vocabulary-equivalence.test.ts over every example and eval golden.
  • rankFixes — deterministic cost ordering for a diagnostic's fix alternatives (exported).
    Orders the mutually-exclusive fixes on one diagnostic by applicability rank → total edit
    magnitude (smallest change wins) → earliest offset → stable index. arch fix now applies only
    the top-ranked alternative per diagnostic; LSP code actions present alternatives in the same
    canonical order. Identity on today's singleton arrays, so existing behavior is byte-identical.
  • describe().freedom — a degrees-of-freedom placement report (append-only). Per placed
    element, whether its position was authored absolutely or derived by the resolver — rooms
    absolute/relational/strip, openings attached/absolute, furniture
    anchored/against-wall/absolute — as per-family counts plus one elements row each.
    Facts only (ADR 0005); the internal marker never reaches the Scene, so rendered output is
    unchanged.
  • Optional metric unit suffixes on numeric literals (roadmap Tranche 6 Track B). A number may
    carry a mm/cm/m suffix, folded to millimetres at lex time: 3m3000, 3.5m3500,
    3cm30, 3mm3 (an explicit no-op). Bare numbers still mean millimetres, so every
    existing plan's output is byte-identical
    (a determinism/byte-equality test compiles a suffixed
    plan and its bare-mm twin and asserts equal SVG). The conversion is exact — decimal-point
    shifting on the digit string, never a floating-point multiply — so 3.333m is exactly 3333 and
    0.0005m is exactly 0.5 mm. The suffix must sit immediately after the digits (no space) and
    does not fire when a letter follows (3meters = number 3 + ident meters); each component of a
    WxH literal may carry its own suffix (3mx4m, 3.5mx4200). Deliberately no area unit
    () — that belongs to the parked T6 area syntax (Gate G2 closed; see
    docs/research/2026-07-g2-verdict.md). The formatter normalises a suffixed literal to its mm
    value (3.5m3500). Folded in the lexer (src/lexer.ts); the grammar source of truth
    (src/grammar/tokens.ts) and every generated artifact — editor grammars, grammars/archlang.gbnf,
    spec.llm.md, llms-full.txt — carry the optional suffix.
  • Note (eval baseline): spec.llm.md is the eval's author prompt, and this change adds a line
    to it, so it now differs from the prompt behind the 2026-07-11/12 calibrated live baseline. No
    scoring/judge/fixture code changed; re-running the paid live baseline under the new prompt stays a
    separate, owner-approved action (default: not run).

Changed

  • arch fix now collects fixes from lint diagnostics too (previously compile-stage
    diagnostics only). W_ALIAS_MATCH is the first lint rule to carry a fix; the L1 gate's
    l1Pipeline remains the compile-stage-fix + repair reference pipeline and is unaffected.
  • A room labelled with a WC-only alias (e.g. "Powder") now classifies as a WC. The word was
    dead in the old regex cascade (WC_RE was only consulted after WET_RE, which never matched
    it); the vocabulary form resolves it, flagged by W_ALIAS_MATCH. The one deliberate
    reclassification — every other label classifies exactly as before (pinned by test).

v1.14.0

Choose a tag to compare

@ChanMeng666 ChanMeng666 released this 13 Jul 06:22

v1.14 Tranches 1–2 + 4 — the measurement foundation, then the intent channel it licensed
(roadmap docs/research/2026-07-roadmap-proposal.md). Tranches 1–2 were repo-internal (eval/ and
CI only; the one core exception is the repair() purity fix under Fixed): fix the ruler before
measuring capability
. Gate G1's PASS then cleared Tranche 4, which DOES extend the published
surface — the intent channel below.

Added — Tranche 4: the intent channel (2026-07-12; core + CLI, zero new runtime deps)

  • src/intent.ts — the judge-v2 scoring core, lifted into the core package. A brief's
    checkable expectations as data (Intent), lowered to the shallow predicate kinds
    (room-count / room-exists / room-area / total-area / adjacent / reachable, plus a
    new gating room-windows), checked against describe() facts.
    validateIntent(source, intent){ ok, satisfied, total, violations, subscores, assertions, diagnostics } with typed, catalogued violations and Nickel-style spanless blame
    messages (intent /roomsInclude/1: no room matching concept "bathroom" …);
    intentFromJson (zero-dep pathed shape walker); feedbackForResult (deterministic
    per-violation correction prompts — advisory data, ADR 0005, never auto-applied).
  • src/intent-concepts.ts — the concept vocabulary, now production name resolution. Byte-
    mirrors the eval's table; a known concept resolves exactly as the eval judges (label →
    room_typeuses, token-bounded), an unknown one falls back to a literal
    id → label → uses → room_type match.
  • Eight catalogued codes: E_INTENT_ROOM_MISSING / _ROOM_COUNT / _ROOM_AREA /
    _TOTAL_AREA / _NO_WINDOW gate; E_INTENT_NOT_ADJACENT / _NO_DOOR / _UNREACHABLE are
    advisory (gate: false — scored, never failing ok; reachable blames by cause: no entrance
    NO_DOOR, cut-off rooms → UNREACHABLE). Promoting adjacency/reachability to gating stays
    parked on T3's still-open loop-vs-resampling question.
  • schemas/intent.schema.json (npm run gen:intent-schema, drift-tested, served by the docs
    site). Its field docs make Gate G1's two lessons normative: the area band conventions
    ("about/~/bare N m²" → ±10%; "at least N" → min only; qualitative words → no assertion) and
    the count discipline ("assert a room count only when the brief enumerates it").
  • CLI: arch validate --intent <intent.json> (the gate — exit 2 on a gating violation;
    composes with --graph/--strict; --feedback appends the correction prompts) and
    arch score <file> --brief <intent.json> (the continuous meter — satisfied/total +
    subscores, exit 0 on any successful measurement).
  • describe() windows gain facing: "N"|"S"|"E"|"W" (append-only; the outward normal of the
    window's host wall), and intent windows assertions take an optional facing.
  • The eval now consumes the same implementation (eval/assertions.ts/synonyms.ts are thin
    re-export shims; run.ts's Expect is the production Intent) — one judge, zero eval↔prod
    skew. JUDGE_VERSION stays "2", proven by a pinned fixture (eval/judge-fixture.json +
    test/eval-fixture.test.ts) that every corpus per-assertion judgment is byte-identical across
    the lift; the fixture is regenerated only to record an approved bump, never to green a red suite.

Added — release engineering: tokenless OIDC publishing (npm + MCP registry)

  • .github/workflows/release.yml — a v* tag push (or manual dispatch) publishes the core,
    then the MCP shim, to npm via OIDC trusted publishing with provenance (no npm token exists
    anywhere; each package carries a one-time Trusted Publisher registration on npmjs.com pointing
    at this workflow), then syncs the MCP registry with mcp-publisher login github-oidc
    also tokenless. Every step is idempotent (versions already on a registry are skipped, and the
    registry sync is guarded by the registry's own state), so partial failures re-run safely.
    Replaces the local granular-token publish flow that npm is deprecating through 2026–2027.
  • MCP shim 0.2.0 (@chanmeng666/archlang-mcp, registry entry updated): the validate tool
    takes an optional intent (gating assertions fail it; advisory ones score), a new score
    tool is the continuous satisfaction meter, and intent.schema.json ships as the
    intent-schema resource — the same intentFromJson/validateIntent/feedbackForResult path
    the CLI uses.
  • Provenance gotcha, recorded: npm E422-rejects a publish whose package.json
    repository.url casing differs from the OIDC-attested repo (ChanMeng666, not
    chanmeng666) — fixed in both package.json files + server.json.

Added — Gate G1 verdict + the L2 experiment harness (2026-07-12; still repo-internal)

  • Gate G1: PASS (eval/g1/ — generator harness, generated intents, double-blind scores,
    report). NL→intent-JSON per-assertion faithfulness on all 26 briefs: 154/157 (98.1%) vs
    93.4% per-assertion accuracy of direct .arch generation (one-tailed z = 2.08, p = .019;
    valid-only sensitivity variant below resolution — recorded). The intent channel (roadmap T4:
    src/intent.ts, arch validate --intent, intent.schema.json) is cleared for a future
    release. The generation prompt is oracle-isolated and test/g1.test.ts enforces it.
  • T3 harness: the L2 tier (eval/l2.ts + eval/l2-run.ts + .github/workflows/eval-l2.yml,
    npm run eval:l2). Diagnostic feedback loop (≤2 rounds, fed only compile/lint diagnostics +
    fix --dry-run previews + trimmed describe() — oracle-isolated) against an equal-token-budget
    i.i.d. resampling control
    (Olausson accounting, round-up favours the control), per-metric
    best-of, mean±σ across trials, pass@n/pass^n, retrying author + per-brief error isolation.
    Offline-tested (14 tests). The live experiment has not been run (cost declined) — the
    loop-vs-resampling question remains open and no loop-gain claim is made.

Added — judge v2: brief-grounded intent scoring

  • Intent-assertion scoring core (eval/assertions.ts, JUDGE_VERSION = "2"). scoreSource no
    longer greps the goldens for label substrings and golden-derived area bands; it lowers each brief
    to a small intent-assertion data structure — the shallow five kinds room-count /
    room-exists / room-area / total-area / adjacent / reachable — and checks the model's
    plan against those. The five-kind boundary is deliberately the one a future src/intent.ts can
    lift wholesale (Tranche 4 hook). Score gains append-only subscores / assertions /
    judgeVersion fields.
  • Oracle-isolated synonym table (eval/synonyms.ts, SYNONYMS_VERSION = 1). Room-label matching
    runs through a versioned, never-shown-to-the-model concept table with token-bounded,
    one-room-one-concept greedy assignment — so "wc"/"toilet"/"bath" resolve to one concept without
    leaking the answer into the prompt.
  • Brief-grounded area checks. Area is verified only where the brief states a number, in a
    ±10–15% band around the brief's number; all 20 golden-derived bands were deleted. Qualitative
    size words ("compact", "generous") carry no cap yet (a documented tier-b hook, added the day a
    real "oversized compact" instance appears).
  • Frozen corpus-review rubric (eval/rubric.md). Blind-drafted by an isolated agent, then frozen
    with the approver's decisions: room-count policy B (a ±1 surplus passes the gate only when the
    extra room is pure circulation, operationalized as planCirc >= expectedCirc + 1); one-room-one-concept
    greedy assignment; qualitative size words carry no cap. Adjacency and reachability score as
    subscores only, never a gate (Tranche 4 hook).
  • Corpus 22 → 26. Three prompts amended so every room count is brief-derivable
    (two-bath-flat, against-wall-bath, accessible-bath), plus a new per-room-area slice
    (sized-kitchen-flat, sized-bedrooms, sized-wet-room, sized-office-mix) so the area dimension
    is no longer total-only (H5) — every band carries the brief-source quote it came from.
  • L1 deterministic-tool gate (eval/faults/, eval/l1.ts, test/fault-injection.test.ts, in CI
    via npm test). Six single-defect fixtures (off-wall door/window/opening, furniture-through-wall,
    blocked-doorway, and a combined case) prove the l1Pipeline — a bounded machine-applicable-fix
    fixpoint (mirroring arch fix) followed by repair(), in the ADR 0011 → ADR 0006 order — heals
    every defect class deterministically and idempotently
    , and is a byte no-op on a clean golden.
  • --l1 live overlay (eval/run.ts, live runs only). Reports the deterministic dividend
    ΔL0→L1 (what fix+repair recover for free, zero extra API calls) with a per-row heal column;
    the committed baseline delta stays L0-only so cross-run comparisons don't silently fold the tool
    tier into a model score.
  • eval-live workflow inputs (.github/workflows/eval-live.yml): a --l1 toggle (default on) and
    the corpus-covering max default of 26.

Changed — live-harness integrity

  • Token budget & determinism. Anthropic max_tokens 2048 → 16384 (reasoning models spend
    thinking tokens out of the completion cap — the 2048 ceiling truncated output into false
    invalidity) with temperature: 0 and ephemeral prompt caching; the OpenAI path pins
    seed = 20260711 and records system_fingerprint (temperature deliberately not sent).
  • --budget <n>tok|<n>usd circuit breaker — a pre-call estimate halts the run before it
    overspends; skipped briefs are excluded from the denominators (over-estimating direction, verified
    price map).
  • Cross-judge guard. Baseline now carries a judge field and renderDelta flags any delta
    taken across a judge-version change as non-comparable — a judge change is never a capabilit...
Read more

v1.13.0 — AI-native authoring

Choose a tag to compare

@ChanMeng666 ChanMeng666 released this 10 Jul 21:28

The AI-first release: agents write plans without doing coordinate arithmetic, and fix them mechanically.

  • Placement sugardoor|window|opening on <wall> at <pos> attachment, swing into <room>, hinge near start|end, furniture in <room> centered | anchor <corner> [inset N], and strip room rows. Attached openings cannot be off-wall by construction.
  • Machine-applicable fixesDiagnostic.fixes (rustc-style 4-tier applicability), arch fix (piece-table applier, bounded self-checking fixpoint), arch suggest (candidate doors/windows for unreachable rooms as data, never auto-applied), LSP quick-fixes in the VS Code extension.
  • Structured I/O — Plan JSON in/out (compile --from-json, arch ast) aligned to the academic LLM floor-plan schema, validate --graph intent checking, arch complete, generated schemas/plan.schema.json.
  • Constrained decoding — generated grammars/archlang.gbnf so llama.cpp / vLLM-class stacks can hard-guarantee valid .arch.
  • Zero-dep perceptionarch compile -f txt / preview --ascii renders a box-drawing floor plan any sandboxed agent can read.
  • Eval — live authorability eval (OpenAI provider, cost-guarded), corpus 18→22, recorded baseline + delta reporting.
  • MCP — new optional @chanmeng666/archlang-mcp stdio shim (ADR 0012); the CLI stays the primary agent interface and the core stays zero-dependency.

See CHANGELOG.md for the full tranche-by-tranche detail.

v1.12.1

Choose a tag to compare

@ChanMeng666 ChanMeng666 released this 13 Jul 06:22

Fixed

  • The PNG backend's lazy import("node:fs") / import("node:url") (font lookup) now carry
    /* webpackIgnore: true */ /* @vite-ignore */ like every other Node-only lazy import, so a
    webpack/Next.js consumer importing the core client-side no longer fails its build trying to
    resolve fs for the browser (the code path never runs in a browser; same class of bug as the
    1.0.0 → 1.0.1 fix). Found by ArchCanvas's first in-browser use of the core.

v1.12.0

Choose a tag to compare

@ChanMeng666 ChanMeng666 released this 13 Jul 06:22

AI-first release (Mermaid-inspired): make ArchLang maximally discoverable, self-describing and
distributable for AI agents. Default SVG output stays byte-identical throughout; every new output
behavior is opt-in (ADR 0007 discipline).

Added — agent context & diagnostics

  • llms-full.txt (generated, drift-tested via npm run gen:llms / scripts/gen-llms-full.ts):
    the full language spec, the SKILL.md agent workflow, a manifest-derived CLI reference and the
    complete diagnostic catalog bundled into one system-prompt-ready document (~40 KB). Ships in the
    npm package; the docs site now serves /llms.txt and /llms-full.txt at its root
    (copied into docs-site/public/ by sync-docs.mjs, per llmstxt.org convention).
  • arch context: prints the bundle — one command gives a cold-start agent everything
    (arch spec remains the language-only view).
  • diagnosticToJson(source, d) + DiagnosticJson (new src/diagnostic-json.ts, exported):
    the CLI's agent-facing diagnostic projection (line/col from byte spans + catalogued fix) is now
    public API for SDK/playground/LSP consumers. CLI JSON output is byte-identical.

Added — always-visible errors & eval spine

  • Opt-in error-card SVG: compile(src, { onError: "svg" }) / --error-svg on
    compile/preview/md — a plan that fails to compile still renders a deterministic,
    self-describing SVG card (severity, code chip, line:col, message, catalogued fix; new
    src/backends/error-svg.ts, exported renderErrorSvg). Errors/diagnostics/exit codes are
    unchanged; without the opt-in, a broken plan still produces no bytes. arch md --error-svg
    renders failing fenced blocks as error cards instead of skipping them. Also exported:
    renderPngFromSvg (raster core extracted from the PNG backend).
  • Authorability eval hardened: corpus grown 3 → 18 briefs with hand-verified goldens
    (relational placement, dims auto, against wall, multi-bath topology, open-plan opening,
    accessibility briefs, scripting, an intentional-warning shell, 30–126 m²); offline golden
    regression gate wired into CI (npm run eval:ci, no API key); default live-eval model id
    updated.

Added — distribution

  • Docs site: plain ```arch fences in any docs page now render as live, editable
    <ArchLive> widgets (markdown-it fence transform; SSR/no-JS keeps the highlighted block;
    ```arch static opts out). Explicit <ArchLive> usage is untouched.
  • GitHub Action .github/actions/arch-render (composite, in-repo): render every fenced
    ```arch block in a repo's Markdown via arch md — inputs files/format/out-dir/
    error-svg/version, with a self-test workflow. With error-svg: true (default) broken blocks
    become error-card images and the job stays green.
  • Playground: Copy-for-LLM button (current source + describe() facts + diagnostics with
    fixes + spec pointer as one paste-ready prompt; pure buildLlmPrompt helper) and diagnostics
    now show their catalogued fix inline (full cause/example still behind the disclosure).

Added — accessibility as a language feature

  • compile(src, { accessible: true }) / arch compile --accessible: the SVG carries
    <title> (plan name), <desc> (a derived one-sentence caption) and role="img" +
    aria-labelledby. The caption is also exposed as describe().caption (same sentence,
    guaranteed identical). Default output byte-identical without the flag.
  • accTitle / accDescr plan-level keywords (the release's one language-surface change):
    explicit accessible metadata overriding the derived title/caption. Duplicate → new
    W_DUP_ACC_METADATA (last wins); misplaced → new E_ACC_PLACEMENT. Grammar/spec/editor
    artifacts regenerated; new examples/accessible.arch; arch fmt prints and preserves both.
    VS Code extension repack required (it bundles the core).

v1.11.0

Choose a tag to compare

@ChanMeng666 ChanMeng666 released this 13 Jul 06:22

Added

  • Annotate mode now stamps data-arch-id / data-arch-kind on element primitives.
    data-arch-kind is stamped for every element kind except wall — currently room,
    door, window, opening, furniture, dim, and column (the non-wall members of
    ElementKind; the set is open-ended and grows as kinds are added). Walls are excluded —
    their SVG is unioned geometry stitched across many statements, so per-element attribution
    is ambiguous. Default (non-annotate) output remains byte-identical.
  • diffPlans(sourceA, sourceB, opts?): deterministic semantic diff of two plans built on
    describe() — room/opening/furniture changes, per-room bbox edge deltas, circulation deltas,
    and human-readable summary sentences.

v1.10.0 — human circulation + foundation refactor

Choose a tag to compare

@ChanMeng666 ChanMeng666 released this 02 Jul 11:46

Human circulation (ADR 0008)

Circulation analysis grows from "is every room reachable?" to "how far, how wide, how direct is the walk?" — strictly facts + advisory + explicit transform (no generative layout; default SVG output byte-identical, pinned by tests):

  • Factsdescribe().circulation: per-room walk distance, bottleneck clear width, and detour ratio from the entrance, plus key routes (kitchen↔living/dining, bedroom↔bath), on a clearance-eroded navigation grid.
  • LintW_PATH_TOO_NARROW (default 700 mm; accessibility-advisory profile: 900 mm) and W_CIRCUITOUS_PATH (>3.0× straight-line).
  • Overlayarch compile --overlay circulation / compile(src, { overlays: ["circulation"] }) draws the walks, key routes, and bottleneck markers; the playground gains an off-by-default Paths toggle.
  • Repair guardarch repair declines any furniture move that would newly pinch a walk below the lint threshold and reports it in unresolved.

Foundation refactor (default output byte-identical)

  • Wall-union rewritten: opening-heavy toScene ~19.5 → ~2.6 ms (full compile ~42 → ~24 ms); validate/lint no longer render the SVG they discard.
  • lint() restructured to one module per rule over a shared context; shared rect geometry (geometry/rect.ts) and one deterministic number formatter (num-format.ts).
  • Drift tests pin the element-keyword↔registry, fixture-classifier, completion-kind, and export-format joints; new core exports COMPLETION_KINDS, EXPORT_FORMATS, optional Scene.chrome.
  • Tooling: Biome (CI-gated), noUncheckedIndexedAccess on, Node 18/20/22 CI matrix, honest per-stage benchmarks; the playground app is now TypeScript with its own tests.

Sites

Embeddable playground viewer (embed.html + Embed button), IDE-parity actions (Format / Repair panel / clickable diagnostics), live editable <ArchLive> docs examples.

Suite: 535 tests · typecheck/Biome/gen-drift clean · all default artifacts byte-identical to v1.9.0.