office-open-xml-viewer
AGENTS.md866 starsChanged 3 months agoMITView on GitHub
This file is the canonical workflow for AI coding agents working on this repository. Tool-specific files such as CLAUDE.md may add supplements, but they must not contradict this file. office-open-xml-viewer renders OOXML documents (docx, xlsx, pptx) to browser Canvas. The implementation is a Rust/WASM parser layer plus TypeScript Canvas renderers and viewers. Important directories: Use this flow for ordinary bug fixes and feature work: 1. Start from main and run git pull --ff-only. 2. If the checkout is dirty, preserve…
- Installs packages
- Commits and pushes
We split this AGENTS.md into the rules it gives an agent
69 rules. About 0 are common, 43 are distinctive, and 26 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈43
Distinctive · estimate
This author's own choices. Worth a look.
26
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Distinctive: line 25
Use this flow for ordinary bug fixes and feature work:
- Distinctive: line 27
Start from main and run git pull --ff-only.
- Very specific: line 28
If the checkout is dirty, preserve unrelated work before switching or pulling.
- Very specific: line 29
Prefer git stash push -u -m <clear-message> for work that appears to belong to another session.
- Very specific: line 31
Create a feature branch. Use codex/<topic> for Codex work when possible.
- Very specific: line 33
When creating or entering a Codex/Claude worktree, make the root checkout's ignored spec/ directory available from that worktree as a local …
- Very specific: line 41
If the worktree lives elsewhere, create spec as a symlink to the main local checkout's spec/ directory.
- Distinctive: line 45
add a focused failing test,
- Distinctive: line 48
Verify with the narrowest meaningful tests first, then broader checks when the touched surface warrants it.
- Very specific: line 50
Commit only the intended source/docs/test files.
- Distinctive: line 57
Never push directly to main.
- Distinctive: line 58
Use PRs for integration into main.
- Very specific: line 59
Do not squash merge. Use gh pr merge <number> --merge unless the user explicitly asks for another non-squash strategy.
- Distinctive: line 61
Before git push, set git config http.postBuffer 524288000 if large pushes are expected.
- Distinctive: line 63
Commit messages should match the repository style:
- Distinctive: line 69
do not include local absolute paths, usernames, home directories, machine names, or other personal environment details.
- Distinctive: line 71
do not quote or summarize the concrete contents of private or copyrighted samples.
- Distinctive: line 76
keep local-only sample filenames and visual details out of public PR text unless the user explicitly approves publishing that information.
- Distinctive: line 83
If Claude starts or delegates work to Codex, include both trailers in the resulting commit, including the model each agent actually used …
- Distinctive: line 90
Prefer focused verification tied to the change.
- Distinctive: line 112
If a check fails because ignored/generated WASM is stale, rebuild WASM before assuming the source change is broken.
- Very specific: line 115
Before running parser-backed integration tests, Storybook, or VRT, rebuild generated WASM (pnpm build:wasm or the per-package command) …
- Distinctive: line 126
Do not retain or add tests merely as a precaution, to preserve a test count, or to maintain a coverage percentage.
- Distinctive: line 129
Delete implementation copies, tests that only verify their own mocks or fixtures, and assertions that merely restate type-system or …
- Distinctive: line 135
Avoid asserting private fields, helper call order, source text, or exact internal object shape when an observable contract can express the …
- Distinctive: line 137
Do not replace behavior tests with snapshots of implementation details.
- Very specific: line 153
Before implementing OOXML behavior, consult the relevant documents under the local spec/ symlink.
- Distinctive: line 160
Prefer ECMA-376 / ISO-29500 behavior over sample-specific tuning.
- Distinctive: line 161
Do not add heuristics only to improve one VRT/sample number, such as arbitrary thresholds, empirical scaling constants, or special-casing a …
- Very specific: line 166
When behavior differs from Word/Excel/PowerPoint, first check whether the parser discarded necessary information during parsing, …
- Distinctive: line 168
If information is missing, extend the parser/model instead of guessing in the renderer.
- Distinctive: line 170
If Office behavior is not fully specified and requires reverse engineering, explain that explicitly and ask for user approval before adding …
- Distinctive: line 173
If a temporary heuristic is unavoidable, mark it clearly in code with the missing spec/implementation work and track it for removal.
- Distinctive: line 188
When an investigation settles a rule, incorporate it and its essential rationale into the responsible source before declaring the work …
- Distinctive: line 193
Create them in a task-owned temporary directory outside the checkout by default.
- Distinctive: line 200
Before cleanup, inspect contents, tracked status, symlinks, and active-task ownership.
- Distinctive: line 210
Treat one package's bug as a signal to inspect the sibling packages.
- Very specific: line 211
If the concept is shared, fix the shared layer (packages/ooxml-common or packages/core) where possible.
- Distinctive: line 213
Do not duplicate pure parsing predicates or common type definitions across packages unless the format truly diverges.
- Distinctive: line 215
Avoid false abstraction. Renderer logic that is tightly coupled to a package's layout model may stay local.
- Distinctive: line 222
Before declaring an OOXML feature or bug fix complete, perform an adversarial review of the final diff.
- Distinctive: line 227
Specification fidelity: Verify the implementation against the applicable ECMA-376 / ISO-29500 rule and Microsoft extension notes.
- Distinctive: line 232
No unexplained heuristics: Search for sample-specific branches, magic thresholds, empirical scale factors, path/name checks, and renderer …
- Distinctive: line 234
Remove them or justify them under the OOXML Implementation Policy.
- Distinctive: line 236
Bounded inference for implicit behavior: When Word, Excel, or PowerPoint behavior is not fully specified, base the inference on …
- Distinctive: line 259
Regression evidence: Run focused behavioral tests plus the broadest proportionate cross-package checks.
- Very specific: line 280
When using a Codex/Claude worktree, copy local private stories/samples from the main local checkout if needed.
- Distinctive: line 285
Before using Storybook for parser-backed samples, rebuild WASM from the current worktree source:
- Distinctive: line 306
Use those prefixes when fetching sample files.
- Very specific: line 326
demo: every file under packages/<fmt>/public/demo/ (tracked).
- Very specific: line 328
private: every file under packages/<fmt>/public/private/<fmt>/ (gitignored).
- Very specific: line 390
Run pnpm vrt:fidelity alongside the self-VRT for every renderer change, so main always passes its own ratchet.
- Distinctive: line 404
Only update references when the user explicitly asks:
- Very specific: line 410
Do not automatically update files under packages/*/tests/visual/references/.
- Very specific: line 428
use as Type assertions instead of postfix non-null assertions,
- Very specific: line 429
use canvas for canvas-backed viewers (DocxViewer, PptxViewer),
- Very specific: line 430
use container for container-backed viewers (XlsxViewer),
- Distinctive: line 431
avoid documenting private/local-only sample paths as public API.
- Distinctive: line 433
Keep announcements concise and user-facing:
- Distinctive: line 435
write first for readers who do not know the implementation: lead with the visible outcome and group low-level fixes by the user problem …
- Very specific: line 440
If a technical qualification is useful, put it in a final Technical note section after the outcome and migration guidance.
- Very specific: line 442
keep version-sensitive bundle measurements on the stable /bundle-size page, not in release announcements.
- Distinctive: line 444
do not link API reference details directly to release notes.
- Very specific: line 449
When the user asks for a release, prepare a dedicated PR named release/<version> and do all release changes there.
- Very specific: line 454
Update README screenshots in docs/images/{pptx,docx,xlsx}.png with pnpm screenshots:readme.
- Very specific: line 467
Add a new top CHANGELOG.md section: ## 0.x.0 — YYYY-MM-DD.
- Very specific: line 475
After bumping the root version, run pnpm sync:versions to synchronize packages/legacy-office/package.json (the public …
- Very specific: line 482
Run cargo check -p ooxml-mcp-server after bumping the MCP server so Cargo.lock follows.
- Distinctive: line 488
Create the GitHub Release with notes based on the changelog and a full changelog comparison link.
≈ “Common” is an estimate: at least 1 in 5 of the 36,368 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Agent Instructions
This file is the canonical workflow for AI coding agents working on this
repository. Tool-specific files such as CLAUDE.md may add supplements, but they
must not contradict this file.
Project
office-open-xml-viewer renders OOXML documents (docx, xlsx, pptx) to
browser Canvas. The implementation is a Rust/WASM parser layer plus TypeScript
Canvas renderers and viewers.
Important directories:
packages/core/— shared rendering primitives and shared TypeScript helpers.packages/ooxml-common/— shared Rust parsing/model helpers.packages/docx/— DOCX parser, renderer, viewer, and tests.packages/xlsx/— XLSX parser, renderer, viewer, and tests.packages/pptx/— PPTX parser, renderer, viewer, and tests.site/— public site..storybook/— unified Storybook config.
Standard Development Flow
Use this flow for ordinary bug fixes and feature work:
- Start from
mainand rungit pull --ff-only. - If the checkout is dirty, preserve unrelated work before switching or pulling.
Prefer
git stash push -u -m <clear-message>for work that appears to belong to another session. - Create a feature branch. Use
codex/<topic>for Codex work when possible; otherwise follow the repository's existing branch naming. When creating or entering a Codex/Claude worktree, make the root checkout's ignored
spec/directory available from that worktree as a local symlink. For the standard.claude/worktrees/<name>layout, run:ln -s ../../../spec specIf the worktree lives elsewhere, create
specas a symlink to the main local checkout'sspec/directory. Do not copy or commit the specification files.- Work with TDD for bug fixes:
- explore the failing sample or behavior,
- add a focused failing test,
- make it pass,
- refactor only where it reduces real complexity.
- Verify with the narrowest meaningful tests first, then broader checks when the touched surface warrants it.
- Commit only the intended source/docs/test files. Do not commit private samples or generated local artifacts.
- Push the feature branch, create a PR, wait for checks when practical, and merge with a merge commit. Do not squash.
Git and PR Rules
- Never push directly to
main. - Use PRs for integration into
main. - Do not squash merge. Use
gh pr merge <number> --mergeunless the user explicitly asks for another non-squash strategy. - Before
git push, setgit config http.postBuffer 524288000if large pushes are expected. - Commit messages should match the repository style:
- subject:
fix(scope): ...,test(scope): ...,refactor(scope): ..., etc. - body: explain the root cause, the fix, and verification.
- include specification sections or observed Office behavior when relevant.
- subject:
- PR titles, PR descriptions, commit messages, and public docs must be safe for
an OSS repository:
- do not include local absolute paths, usernames, home directories, machine names, or other personal environment details;
- do not quote or summarize the concrete contents of private or copyrighted samples;
- describe private-sample-driven work in terms of the implementation problem, the OOXML/Office behavior mismatch, the general class of affected documents, and the verification command or local-only comparison that was performed;
- keep local-only sample filenames and visual details out of public PR text unless the user explicitly approves publishing that information.
- Agent-authored commits should include a matching co-author trailer. Include
the actual model used for that task; do not hard-code a model name across
tasks. Examples:
- Codex:
Co-Authored-By: Codex <model-name> <noreply@openai.com> - Claude/Fable:
Co-Authored-By: Claude <model-name> <noreply@anthropic.com>
- Codex:
- If Claude starts or delegates work to Codex, include both trailers in the resulting commit, including the model each agent actually used for that task. This preserves the human-readable provenance of the orchestration layer and the implementation agent.
Verification
Prefer focused verification tied to the change. Common commands:
pnpm test
pnpm typecheck
pnpm build:wasm
pnpm storybook
pnpm build-storybookFor a narrow DOCX renderer fix, a good verification set is:
./node_modules/.bin/vitest run \
packages/docx/src/cell-border-conflict.test.ts \
packages/docx/src/cell-border-conflict-render.test.ts \
packages/docx/src/column-widths.test.ts
./node_modules/.bin/tsc --build --pretty false
git diff --checkIf a check fails because ignored/generated WASM is stale, rebuild WASM before assuming the source change is broken.
Before running parser-backed integration tests, Storybook, or VRT, rebuild
generated WASM (pnpm build:wasm or the per-package command) whenever parser
(Rust) source has changed or packages/*/src/wasm/ may be stale — stale
generated WASM can both hide real parser defects and fabricate failures.
Test value and consolidation
For every test, answer: What realistic defect would go undetected if this test were deleted? Compare that protection with execution cost, flakiness, fixture complexity, and the maintenance burden of legitimate refactoring.
- Do not retain or add tests merely as a precaution, to preserve a test count, or to maintain a coverage percentage. TDD means a focused regression for the actual defect; it does not require keeping every exploratory case.
- Delete implementation copies, tests that only verify their own mocks or fixtures, and assertions that merely restate type-system or dependency guarantees. Exercise production behavior with an independent expectation.
- Consolidate overlapping tests under the narrowest meaningful production boundary. Keep a distinct case only when it catches a distinct plausible failure: for example precedence, a real boundary, ownership, or a race.
- Avoid asserting private fields, helper call order, source text, or exact internal object shape when an observable contract can express the guarantee. Do not replace behavior tests with snapshots of implementation details.
- Reduce exploratory parameter matrices to representative cases and meaningful boundaries. Parameterizing the same redundant matrix does not reduce its execution cost or improve its value.
- Shared-helper coverage does not prove each format is wired correctly. Keep focused DOCX/XLSX/PPTX integration cases where their production paths differ; do not repeat the helper's entire input matrix in every format.
- In a test audit, identify the exact cases to remove or merge, the remaining test that supplies any claimed replacement, and the realistic protection lost. Distinguish unconditional deletion from removal that first requires a replacement. Do not report a static review as measured runtime savings.
OOXML Implementation Policy
Be specification-first.
- Before implementing OOXML behavior, consult the relevant documents under the
local
spec/symlink. Prefer ECMA-376 / ISO-29500 for normative behavior, and Microsoft extension notes such as[MS-DOCX],[MS-XLSX],[MS-PPTX], and[MS-ODRAWXML]when Office-specific behavior or extensions are involved. - Record the relevant specification section, schema element, or observed Office behavior beside the implementing source when it materially explains the implementation. A commit body alone is not a durable substitute.
- Prefer ECMA-376 / ISO-29500 behavior over sample-specific tuning.
- Do not add heuristics only to improve one VRT/sample number, such as arbitrary thresholds, empirical scaling constants, or special-casing a sample path.
- A user report like "this line is too long" or "this object is missing" is a hint that an OOXML rule is missing or mis-modeled. Identify the related section and implement the rule for the whole class of documents.
- When behavior differs from Word/Excel/PowerPoint, first check whether the parser discarded necessary information during parsing, inheritance, or style merging. If information is missing, extend the parser/model instead of guessing in the renderer.
- If Office behavior is not fully specified and requires reverse engineering, explain that explicitly and ask for user approval before adding a compatibility heuristic.
- If a temporary heuristic is unavoidable, mark it clearly in code with the missing spec/implementation work and track it for removal.
Source is the durable specification
Express every settled library behavior in production source. Put necessary decision rationale, tradeoffs, evidence boundaries, and intentionally unsupported behavior in concise comments next to the responsible implementation. Distinguish normative specification rules from observed Office behavior and library policy. For an observed rule, record the tested input classes and boundary/counterexample results needed to explain its scope, without private sample contents or paths.
- Code and these adjacent comments must remain understandable without local experiment files, handoff notes, chat history, PR descriptions, or a separate design document. Tests verify the contract; they must not be its only record.
- When an investigation settles a rule, incorporate it and its essential rationale into the responsible source before declaring the work complete or deleting the evidence. Do not copy an entire experiment log into comments.
- Parameter sweeps, generated Office samples/PDFs/images, probe scripts, logs,
comparison builds, and scratch notes are temporary investigation artifacts.
Create them in a task-owned temporary directory outside the checkout by
default. Remove owned artifacts once their conclusions are captured in source
and focused regression coverage. Do not accumulate permanent
output/oroutputs/directories as an alternative specification store. - Unresolved observations are not established compatibility rules. Record any implemented limitation beside its gate; preserve only the evidence still needed by an active investigation, with an owner and a cleanup point.
- Before cleanup, inspect contents, tracked status, symlinks, and active-task ownership. Do not delete another task's ongoing evidence, original private samples, specification documents, or maintained VRT references. Never follow scratch-directory symlinks into dependencies or other worktrees for deletion.
Cross-Package Integration
DOCX, XLSX, and PPTX share many ECMA-376 concepts: DrawingML images, srcRect,
text runs, paragraph properties, themes, fills, effects, and shape presets.
- Treat one package's bug as a signal to inspect the sibling packages.
- If the concept is shared, fix the shared layer (
packages/ooxml-commonorpackages/core) where possible. - Do not duplicate pure parsing predicates or common type definitions across packages unless the format truly diverges.
- Avoid false abstraction. Renderer logic that is tightly coupled to a package's layout model may stay local.
- Cross-package fixes may touch
core/ooxml-commonand multiple packages in one PR when that is the coherent unit of work.
Mandatory Adversarial Review
Before declaring an OOXML feature or bug fix complete, perform an adversarial review of the final diff. This review is required even when focused tests and VRT already pass. Record the conclusion and any material evidence in the task handoff or PR description; do not silently waive an unresolved item.
- Specification fidelity: Verify the implementation against the applicable ECMA-376 / ISO-29500 rule and Microsoft extension notes. Distinguish normative behavior, documented Office extensions, and implementation policy such as resource governance. Do not claim specification support from sample output alone.
- No unexplained heuristics: Search for sample-specific branches, magic thresholds, empirical scale factors, path/name checks, and renderer guesses. Remove them or justify them under the OOXML Implementation Policy. A passing VRT is not evidence that a heuristic is correct.
- Bounded inference for implicit behavior: When Word, Excel, or PowerPoint behavior is not fully specified, base the inference on sufficiently varied, Office-produced tests that exercise boundaries and counterexamples—not one private sample. State the observed behavior, the tested range, and the limits of the compatibility claim. Keep the implementation scope no broader than the evidence supports, and obtain user approval before adding a compatibility heuristic.
- Performance and resource safety: Review asymptotic work, allocation size, decoded and retained memory, cache ownership/eviction, concurrency, worker transfer cost, repeated parsing or decoding, hot paths, and failure cleanup. Reject unbounded fan-out or whole-document work when visible/page-local work is sufficient. Add budget, concurrency, cache, or stress tests where the risk is material.
- Module boundaries and single responsibility: Confirm that shared OOXML
concepts and pure rendering/resource primitives live in
ooxml-commonorcore, while DOCX, XLSX, and PPTX keep only format-specific parsing, layout, orchestration, and painting. Check for duplicated policy, false abstractions, package cycles, and classes/functions that mix unrelated responsibilities. - Cross-format wiring: For every shared capability, explicitly inspect DOCX, XLSX, and PPTX integration points. Verify the relevant parser/model, public options, viewer, renderer, cache/loader, worker protocol, error propagation, documentation, and tests for each applicable format. If one format is intentionally excluded, document the format-level reason.
- Regression evidence: Run focused behavioral tests plus the broadest proportionate cross-package checks. For renderer changes, use the previous renderer as the self-VRT oracle and keep Office-reference fidelity evaluation separate. Investigate every unexplained difference; do not weaken comparison thresholds merely to make the review pass.
Private Samples and Storybook
Private Office samples and local-only sample stories are gitignored and must not be committed.
Typical local-only paths:
packages/docx/public/private/docx/packages/xlsx/public/private/xlsx/packages/pptx/public/private/pptx/packages/*/src/*privateDemo.stories.ts
Generated build output such as packages/*/src/wasm/ is also git-ignored and
must not be committed; rebuild it instead of copying it between worktrees.
When using a Codex/Claude worktree, copy local private stories/samples from the
main local checkout if needed. Avoid copying .DS_Store, temporary Office lock
files, screenshots, VRT diffs, or private reference images unless the user
explicitly asks.
Before using Storybook for parser-backed samples, rebuild WASM from the current worktree source:
pnpm build:wasmor per package:
cd packages/docx/parser && wasm-pack build --target web --out-dir ../src/wasm && node ../../../scripts/append-wasm-reinit.mjs ../src/wasm/docx_parser.js
cd packages/xlsx/parser && wasm-pack build --target web --out-dir ../src/wasm && node ../../../scripts/append-wasm-reinit.mjs ../src/wasm/xlsx_parser.js
cd packages/pptx/parser && wasm-pack build --target web --out-dir ../src/wasm && node ../../../scripts/append-wasm-reinit.mjs ../src/wasm/pptx_parser.jsStorybook is unified at the repository root. Static prefixes are:
packages/docx/public/→/docx/packages/xlsx/public/→/xlsx/packages/pptx/public/→/pptx/
Use those prefixes when fetching sample files.
In sandboxed agent environments, Storybook's port detection may fail with
EPERM while probing 0.0.0.0. Running Storybook outside the sandbox for local
verification is acceptable when the user asks to view it.
Visual Regression Tests
VRT is local-only because private samples are not redistributable.
Regression detection must compare the changed renderer with images produced by the previous renderer. It must not use Word/Excel/PowerPoint or PDF reference images as the regression oracle. Keep Office-reference fidelity evaluation as a separate run.
Self-VRT (previous-renderer regression)
There are two self-VRT corpora per package. Both render every file completely and compare exact decoded pixels with the previous renderer's images:
- demo: every file under
packages/<fmt>/public/demo/(tracked). Captured bypnpm vrt:snapshotand checked bypnpm vrt. - private: every file under
packages/<fmt>/public/private/<fmt>/(gitignored). Captured bypnpm vrt:private:snapshotand checked bypnpm vrt:private.
pnpm vrt also runs the package's other visual specs (worker parity, overlays,
acceptance checks). Specs that need a private sample load it from
public/private/<fmt>/ and skip when it is absent.
Baselines are produced from a clean, detached worktree at the previous-renderer
revision, normally the full SHA of the latest origin/main. Snapshot mode
rejects a dirty tracked checkout and writes a manifest binding the baseline to
VRT_BASELINE_REVISION, the SHA-256 of each input and the exact
page/sheet/slide set. The candidate run verifies that manifest and reads the
images from the baseline worktree named by VRT_BASELINE_CHECKOUT. Use distinct
ports so a candidate server can never satisfy the baseline run:
base=$(git rev-parse origin/main)
git worktree add --detach /tmp/ooxml-vrt-baseline "$base"
cd /tmp/ooxml-vrt-baseline
pnpm install --frozen-lockfile && pnpm build:wasm
VRT_BASELINE_REVISION=$base VRT_PORT=5190 pnpm vrt:snapshot
VRT_BASELINE_REVISION=$base VRT_PORT=5190 pnpm vrt:private:snapshot
cd <candidate-worktree>
pnpm build:wasm
VRT_BASELINE_REVISION=$base VRT_BASELINE_CHECKOUT=/tmp/ooxml-vrt-baseline VRT_PORT=5191 pnpm vrt
VRT_BASELINE_REVISION=$base VRT_BASELINE_CHECKOUT=/tmp/ooxml-vrt-baseline VRT_PORT=5191 pnpm vrt:privateThe root scripts run every package without stopping at the first failing one,
and still exit non-zero if any package failed. Filter a single package with
pnpm --filter @silurus/ooxml-<fmt> vrt (and the matching snapshot script).
A comparison run requires VRT_BASELINE_CHECKOUT and fails closed unless it
names the root of a Git checkout whose HEAD is exactly VRT_BASELINE_REVISION
and whose renderer is unmodified: no tracked change, and no untracked file
outside dependencies and the private corpus. The checkout is re-verified
before every item is read, so a baseline that changes mid-run fails. Snapshot
manifests record the checkout's real path and each image's SHA-256; the
comparison requires both to match, and rejects any symlink below the baseline
checkout, so copied, replaced or redirected images are never accepted. The
harness runs Git with every GIT_* variable removed. A missing or mismatched
baseline fails the run; it is not a successful regression check. Remove the
baseline worktree when done.
For the one-time bootstrap of a harness change against a baseline revision that
predates it, copy only the allowlisted VRT harness files listed in
tests/visual/private-corpus.mjs into the baseline worktree and set
VRT_ALLOW_HARNESS_CHANGES=1 for both the snapshot and the comparison run;
renderer/parser changes remain forbidden.
Fidelity scores
pnpm vrt:fidelity compares each tracked demo file with its committed images
under packages/<fmt>/tests/visual/references/demo/ and applies the fidelity
ratchet: a page, sheet or slide fails when its match-% drops more than
RATCHET_DROP_PCT below the score recorded in scores.json beside the images.
The demo references are adopted renderer outputs, not Office exports, so the
ratchet detects drift from the adopted generation. Office PDFs remain the
fidelity ground truth.
Run pnpm vrt:fidelity alongside the self-VRT for every renderer change, so
main always passes its own ratchet. Record scores only from a clean checkout
of committed renderer code: the latest origin/main to resynchronize, or the
head of a renderer PR whose score drop has been adjudicated against the Office
PDF (recorded in that same PR). Never record from uncommitted work:
UPDATE_SCORES=1 pnpm vrt:fidelityThis rewrites only scores.json, never the reference images. Commit the
re-recorded scores as their own change that names the source revision. Never
loosen RATCHET_DROP_PCT or FAIL_ABOVE_PCT to make a run pass.
Only update references when the user explicitly asks:
UPDATE_REFS=1 pnpm vrt:fidelityDo not automatically update files under packages/*/tests/visual/references/.
An exact private self-VRT difference is a detected regression candidate, even when every changed document carries the setting being implemented. Enumerate every changed page, sheet, or slide and adjudicate each one against an Office-produced reference. A manual review counts only when it explicitly compares the candidate and previous renderers with that Office output, or when the user explicitly adjudicates the difference. Never approve a group of differences solely because the affected files share a feature flag or OOXML element. If neither an Office reference nor user adjudication is available, report that item as unadjudicated rather than calling the VRT successful.
Documentation and Public Examples
Public docs and commit messages should be written in English.
README, docs, and Storybook public-facing code examples should:
- use
as Typeassertions instead of postfix non-null assertions, - use
canvasfor canvas-backed viewers (DocxViewer,PptxViewer), - use
containerfor container-backed viewers (XlsxViewer), - avoid documenting private/local-only sample paths as public API.
Keep announcements concise and user-facing:
- write first for readers who do not know the implementation: lead with the visible outcome and group low-level fixes by the user problem they solve;
- state explicitly whether migration is required. When it is, give the minimum steps and name any changed default or behavior; when it is not, say so plainly;
- omit implementation detail that does not change a user's decision or action.
If a technical qualification is useful, put it in a final
Technical notesection after the outcome and migration guidance; - keep version-sensitive bundle measurements on the stable
/bundle-sizepage, not in release announcements; - do not link API reference details directly to release notes. Use a stable reference page when more detail is necessary.
Release Workflow
When the user asks for a release, prepare a dedicated PR named
release/<version> and do all release changes there.
Release checklist:
- Update README screenshots in
docs/images/{pptx,docx,xlsx}.pngwithpnpm screenshots:readme. - Review README against the current implementation:
- ESM-only package format,
- install/import examples,
- feature support table,
- bundle-size notes,
- deprecated API or stale version references.
- Sync public API documentation:
site/src/lib/api-reference.ts,site/src/components/Capabilities.astrowhen capabilities changed.site/src/pages/bundle-size.astrowith the latest production measurements. Measure withnode scripts/measure-bundle-size.mjsafterpnpm build:wasm && pnpm build.
- Add a new top
CHANGELOG.mdsection:## 0.x.0 — YYYY-MM-DD. Bump all versions consistently:
- root
package.json, packages/{core,pptx,xlsx,docx,markdown,node,vscode-extension}/package.json,site/package.json,packages/mcp-server/Cargo.toml.
After bumping the root version, run
pnpm sync:versionsto synchronizepackages/legacy-office/package.json(the public@silurus/ooxml-legacy-officepackage), its exact@silurus/ooxmlpeer pin, and the compiled companion runtime version. Runpnpm install --lockfile-onlyandpnpm check:versions; CI and publishing reject any mismatch. Both npm packages publish from the same tag, viewer first; retries skip exact versions already present on npm.- root
- Run
cargo check -p ooxml-mcp-serverafter bumping the MCP server soCargo.lockfollows. - Open PR
chore(release): 0.x.0. - Merge with
gh pr merge <number> --mergeor another non-squash strategy. - Pull main, create and push the annotated tag:
git tag -a v0.x.0 -m "v0.x.0"andgit push origin v0.x.0. - Create the GitHub Release with notes based on the changelog and a full changelog comparison link.
Reference images under tests/visual/references/ are outside the release
checklist unless the user explicitly asks to update them.
VS Code Extension Release
The VS Code extension version should match the npm library version. Pushing a
v* tag triggers .github/workflows/publish-vscode-extension.yml to publish the
extension. For manual packaging checks, use the workflow dispatch dry run.
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 28,693 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository2 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- docx-architecture-auditSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

