Skip to content

proompteng/bilig

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5,405 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

bilig

CI npm: @bilig/xlsx-formula-recalc npm weekly downloads CodeQL OpenSSF Scorecard License: MIT

Fix stale XLSX formula values after Node edits.

SheetJS, ExcelJS, and xlsx-populate are useful file libraries, but they do not turn your Node process into Excel. If your code edits an input cell, the formula cell can still carry the old cached value. Bilig recalculates the workbook in Node and lets you read back the cells your service actually depends on.

Run the smallest check without cloning this repo:

npm exec --package @bilig/xlsx-formula-recalc@latest -- xlsx-cache-doctor --demo --json

If you already have a workbook and do not know which formulas are stale, inspect it first:

npm exec --package @bilig/xlsx-formula-recalc@latest -- xlsx-cache-doctor pricing.xlsx --json

For pull requests, start with the GitHub Action and let it report before it blocks anything:

- uses: actions/setup-node@v6
  with:
    node-version: '22'
    package-manager-cache: false
- uses: proompteng/bilig@v1
  with:
    workbooks: '**/*.xlsx'
    changed-files-only: 'true'
    package-version: '0.130.5'
    fail-on-stale: 'false'

Marketplace listing: https://github.com/marketplace/actions/xlsx-cache-doctor

Live reviewer path: proompteng/xlsx-cache-doctor-demo#1

The demo pull request runs proompteng/bilig@v1, shows one workbook was inspected, finds one stale cached formula value, and uploads the JSON report. Production workflows should pin both the Action ref and package-version; the Action ref controls the wrapper, while package-version controls the npm runtime it executes.

Use @bilig/xlsx-formula-recalc when an .xlsx file is still the source of truth. Use @bilig/exceljs-formula-recalc when the workbook is already moving through ExcelJS. Keep the first proof at the file boundary before adopting a deeper workbook runtime.

For a direct before/after proof across SheetJS, xlsx-populate, and ExcelJS:

npm --prefix examples/recalc-bridge-workflows install
npm --prefix examples/recalc-bridge-workflows run smoke

The canonical guide is Fix stale XLSX formula values in Node.js.

Good fits: XLSX import validation, pricing or payout checks, CI fixtures, and formula models where stale readback is worse than a hard failure. Bad fits: manual spreadsheet editing, Office macros, desktop Excel automation, or one-off arithmetic where a workbook would be ceremony.

Project site: https://proompteng.github.io/bilig/

Start Here

Pick the path that matches the thing in your hands:

You have... Start with You should see
Pull requests or services can read .xlsx files with stale formula caches XLSX Cache Doctor evaluator A read-only formula-cache report with stale cells, cached values, recalculated values, suggested reads, and JSON.
An .xlsx file with stale formula results after editing inputs in Node XLSX recalculation evaluator A changed input, a recalculated output, recalculationCompleted: true, and demo expectedValueMatched: true.
A test runner or service needs the same stale-cache report from TypeScript inspectXlsxCache The same cacheStatusSummary, stale cells, and suggested reads as the CLI report, without a subprocess.

If you are not sure which one fits, use the file-level XLSX path when a real spreadsheet file is already the source of truth. Move to a deeper runtime later only when the calculation model belongs in code and JSON instead of an .xlsx file.

Each evaluator is deliberately small: one command, expected proof, what it proves, what it does not prove, and the limits to check before adoption.

The shortest no-project checks are:

npm exec --package @bilig/xlsx-formula-recalc@latest -- xlsx-cache-doctor --demo --json
npm exec --package @bilig/xlsx-formula-recalc@latest -- xlsx-recalc --demo --json

Those commands are intentionally small. If one matches your workflow, continue into the package matrix below; if none match, Bilig is probably not the first tool to evaluate.

If You Only Try One Thing

Most Excel libraries can edit cells and preserve formulas, but they do not refresh the cached formula results that backend jobs actually read. Run this without cloning the repo:

npm exec --package @bilig/xlsx-formula-recalc@latest -- xlsx-cache-doctor --demo --json

Expected shape:

{
  "schemaVersion": "xlsx-cache-doctor.v1",
  "formulaCellCount": 1,
  "inspectedFormulaCellCount": 1,
  "uninspectedFormulaCellCount": 0,
  "staleCachedFormulaCount": 1,
  "cacheStatusSummary": {
    "inspected": 1,
    "stale": 1,
    "fresh": 0,
    "missingCache": 0,
    "unsupportedRecalculation": 0
  },
  "suggestedReads": ["Summary!B2"],
  "formulas": [
    {
      "target": "Summary!B2",
      "cachedValue": 60000,
      "literalRecalculatedValue": 72000,
      "cacheStatus": "stale",
      "staleCachedValue": true
    }
  ],
  "commandSucceeded": true,
  "inspectionCompleted": true,
  "recalculationCompleted": true,
  "excelParity": "not_proven"
}

The JSON is deliberately clean for CI and agents: no star, release-watch, or discussion links are mixed into the machine-readable proof. Use the links in the surrounding docs after the recalculated value and warnings match your workflow.

staleCachedValue: null is not a hidden failure bucket. Use cacheStatusSummary and per-formula cacheStatus to separate missing cached values from formulas Bilig could not compare yet.

When the detector points at the cells you care about, run the recalculation check:

npm exec --package @bilig/xlsx-formula-recalc@latest -- xlsx-recalc --demo --json

Trust boundaries:

  • Runs locally in Node or in your GitHub Actions runner; no hosted workbook upload is required.
  • Does not claim Excel parity. Start with where Bilig is not Excel-compatible yet before using it for irreversible workflows.
  • The cache doctor is diagnostic by default. It only blocks pull requests when you opt into fail-on-stale.

For linked workbooks, use the external workbook recalculation proof. For the stale-cache detector, use Evaluate stale XLSX formula caches. For a narrower recalculation evaluator, use Evaluate XLSX formula recalculation.

If you already have the real workbook but do not know which formulas to read yet, inspect it first without writing an output file:

npm exec --package @bilig/xlsx-formula-recalc@latest -- xlsx-cache-doctor pricing.xlsx --json

That checks every formula by default, reports any skipped formulas as uninspectedFormulaCellCount, returns stale cached values, and suggests --read targets so the next command can prove the cells your service actually depends on.

If your service or test runner needs the same report without a subprocess, use the Node API:

import { readFile } from "node:fs/promises";
import { inspectXlsxCache } from "@bilig/xlsx-formula-recalc";

const report = inspectXlsxCache(await readFile("pricing.xlsx"), {
  fileName: "pricing.xlsx",
});

if (report.staleCachedFormulaCount > 0) {
  throw new Error(
    report.formulas
      .filter((formula) => formula.cacheStatus === "stale")
      .map((formula) => formula.target)
      .join(", "),
  );
}

To run that check in CI, install XLSX Cache Doctor from GitHub Marketplace, read the GitHub Action guide, or copy the runnable example at examples/xlsx-cache-doctor-ci. For a live reviewer path, inspect the demo pull request: it runs proompteng/bilig@v1, proves 60 formula cells were inspected, finds 1 stale cached formula value, and uploads the JSON report.

To generate the pull-request workflow instead of hand-writing YAML:

mkdir -p .github/workflows
npm exec --package @bilig/xlsx-formula-recalc@latest -- \
  xlsx-cache-doctor --print-github-action "**/*.xlsx" \
  > .github/workflows/xlsx-cache-doctor.yml

The generated workflow is read-only and report-only by default. Add --fail-on-stale true when you want stale cached values to block pull requests, or pass --inspect-limit, --json-output, or --markdown-output to match your CI artifact policy. The Action uploads machine-readable JSON and a human-readable Markdown report path, so reviewers can inspect the stale cells without giving the detector write permissions.

If your pipeline is specifically SheetJS / xlsx, run the sibling proof with the same shape:

npm exec --package @bilig/sheetjs-formula-recalc@latest -- sheetjs-recalc --demo --json

If the workbook is already in ExcelJS, keep that boundary and add @bilig/exceljs-formula-recalc:

npm install exceljs @bilig/exceljs-formula-recalc
npm exec --package @bilig/exceljs-formula-recalc@latest -- exceljs-recalc --demo --json

For one checkout proof across SheetJS/xlsx, xlsx-populate, and ExcelJS:

npm --prefix examples/recalc-bridge-workflows install
npm --prefix examples/recalc-bridge-workflows run smoke

That bridge proof is the fastest way to check whether Bilig solves the stale formula-value problem without asking you to adopt WorkPaper state first.

Which Path Should I Install?

Problem you have right now Install or use First proof
Pull requests can commit XLSX fixtures with stale formula caches uses: proompteng/bilig@v1 XLSX Cache Doctor GitHub Action
Generic XLSX bytes changed in Node; formula outputs must refresh before returning npm install @bilig/xlsx-formula-recalc XLSX formula recalculation in Node.js
Formula workbook state belongs inside a Node service, route, queue, test, or tool npm install @bilig/workpaper Node service WorkPaper evaluator

Advanced adapters are still available when the boundary is already specific: SheetJS, ExcelJS, external workbooks, agent tools, @bilig/workbook when a runtime needs transport-neutral plan data and command receipts, and runtime provenance.

Agent And WorkPaper Proof

For agent adoption, use the Agent Adoption Kit: install the skill, run the no-key MCP proof, paste one workbook task into the agent, and require verified: true before trusting the result.

Coding agent? Do not start by driving Excel, LibreOffice, Google Sheets, or a browser grid. Use the headless WorkPaper proof instead: npm exec --package @bilig/workpaper@latest -- bilig-mcp-challenge --json. Then follow the agent MCP evaluator.

The published package also carries AGENTS.md and SKILL.md so coding agents inspecting node_modules/@bilig/workpaper can find the write/read/persist loop locally. Cloned checkouts expose the same workflow through .claude/skills/bilig-workpaper/SKILL.md, .claude/commands/bilig-workpaper-proof.md, .cursor/rules/bilig-workpaper.mdc, .windsurf/rules/bilig-workpaper.md, .clinerules/bilig-workpaper.md, and .continue/rules/bilig-workpaper.md. The public docs expose the same agent path through docs/.well-known/agent.json.

npx --yes skills@latest add https://bilig.proompteng.ai --list
npx --yes skills@latest add proompteng/bilig --skill bilig-workpaper --list
npm exec --package @bilig/workpaper@latest -- bilig-mcp-challenge --json

Integration Recipes After The Proof

Run one core proof above before wiring a platform-specific integration. These recipes are for teams that already know where the workbook tool needs to live.

Host or workflow runner Use Bilig when... Guide
Open WebUI A local or hosted tool server should expose workbook reads, writes, and formula readback. Open WebUI WorkPaper tool setup
LobeHub A LobeHub agent needs a Custom MCP server for workbook tools. LobeHub WorkPaper MCP setup
AnythingLLM Agent Skills should call hosted MCP or a private file-backed stdio server. AnythingLLM WorkPaper MCP setup
Sim An Agent block or MCP Tool block should read, write, recalculate, and export proof. Sim WorkPaper MCP setup
FastMCP Python A Python client should smoke-test hosted MCP before private agent wiring. FastMCP WorkPaper client
Hugging Face smolagents A Tool should return structured formula readback proof to a CodeAgent. smolagents WorkPaper tool
n8n, Dify, Flowise, Pipedream Workflow builders need formula readback without spreadsheet UI automation; use @bilig/n8n-nodes-workpaper, the upstream merged Dify plugin, or the reviewed Pipedream action. n8n, Dify, Flowise, Pipedream
Vercel AI SDK generateText() or streamText() tools need before/after/restore proof. Vercel AI SDK WorkPaper tools
LangGraph.js / LangChain MCP ToolNode state should carry WorkPaper proof, or MCP adapters should discover workbook tools. LangGraph, LangChain MCP example
Windmill, Trigger.dev Durable Formula Tasks, Inngest Durable workflow code should calculate fields from reviewable formulas. Windmill, Trigger.dev, Inngest
Airbyte, Meltano Post-sync or post-ELT validation should return formula-backed record/state proof. Airbyte, Meltano
Temporal, Airflow, Dagster Formula Assets, Kestra, Prefect Orchestrators should own retries/history while a Node step owns workbook proof. Temporal, Airflow, Dagster, Kestra, Prefect
Directus Persisted Calculated Fields A custom operation should persist calculated fields with formula proof. Directus WorkPaper Flow operation

Choose An Evaluation Path

If you are evaluating... Start here What should be true before you adopt
Existing XLSX files XLSX recalculation evaluator A command edits inputs, reads recalculated values, writes XLSX, and returns recalculationCompleted: true.
Node service formulas Node service WorkPaper evaluator A starter writes one input, recalculates, persists JSON, restores, and prints verified: true.
Agent MCP contract Agent MCP workbook evaluator MCP tool discovery, input edit, formula readback, persistence, and restart proof all pass.
Agent intent/runtime adapters Workbook agent intent API and workbook-agent-model example A model prepares transport-neutral plan data, strict runtime proof, command receipts, and check evidence.
Basic fit Why use Bilig? The problem is workbook-shaped business logic that needs API readback and persistence.
Published npm package 90-second Node quickstart @bilig/workpaper edits one input, recalculates, persists JSON, restores, and prints verified: true.
XLSX or ExcelJS recalculation XLSX formula recalculation and ExcelJS formula recalculation The package updates inputs, reads recalculated values, and exports or mutates the workbook boundary.
Backend service shape Quote approval WorkPaper API A realistic route-style workflow returns formula readback and restoredMatchesAfter: true.
Agent or MCP tools Headless WorkPaper agent handbook, MCP spreadsheet tool server, Gemini CLI extension, and Claude Desktop MCPB bundle The agent installs a tool path, gets a copy-paste handoff prompt, then proves write/readback/persist.
Agent-owned XLSX files Agent XLSX recalculation without LibreOffice A tool can edit XLSX inputs, recalculate, export, reimport, and return verified: true.
Public technical review Show HN maintainer note One shareable page has the npm check, benchmark caveat, known limits, and feedback ask.
Trust and performance npm provenance and benchmark evidence npm shows SLSA provenance, and benchmark claims match the checked artifact.
Almost a fit adoption blocker form Name the formula, import/export, persistence, framework, MCP, package, or benchmark gap.
Formula or XLSX bug formula bug clinic Share a reduced public case that can become a test, example, corpus fixture, or docs proof.
Real workbook blocked submit a workbook fixture Use the structured form when a reduced workbook is ready.

Reduced workbook already in hand? Generate the paste-ready fixture report in one command:

npm exec --package @bilig/workpaper -- bilig-formula-clinic ./reduced.xlsx --cells "Summary!B7,Inputs!B2"

Handing a spreadsheet task to another coding agent? Start with the agent handoff prompt before opening Excel, LibreOffice, Google Sheets, or a screenshot UI. To prove the package-owned agent loop without cloning the repo or downloading a TypeScript file:

npm exec --package @bilig/workpaper@latest -- bilig-agent-challenge --json
npm exec --package @bilig/workpaper@latest -- bilig-mcp-challenge --json

Agent tools that support skill manifests can start from skill.md or the well-known index at docs/.well-known/agent-skills/index.json. Claude Code reads the project skill from .claude/skills/bilig-workpaper/SKILL.md when the repo is cloned locally, and can invoke the explicit proof prompt from .claude/commands/bilig-workpaper-proof.md. Cursor and Windsurf/Cascade read the same proof loop from .cursor/rules/bilig-workpaper.mdc and .windsurf/rules/bilig-workpaper.md. Cline and Continue read the workspace rules from .clinerules/bilig-workpaper.md and .continue/rules/bilig-workpaper.md. GitHub Copilot and VS Code agent mode read the repository instructions, prompt, and MCP servers from .github/copilot-instructions.md, .github/prompts/bilig-workpaper-proof.prompt.md, and .vscode/mcp.json. Gemini CLI users can install Bilig as an extension:

gemini extensions install https://github.com/proompteng/bilig --ref main

Claude Desktop users can also install the released MCPB bundle directly: https://github.com/proompteng/bilig/releases/latest/download/bilig-workpaper.mcpb. If you need a copy-paste eval for another tool host, use the agent workbook challenge: one input edit, one dependent formula readback, one serialized restore, and a verified: true proof object.

bilig headless workbook runtime for formulas in TypeScript

Try It In 90 Seconds

This uses the published npm package. It builds a workbook, changes one input, reads the calculated value, saves JSON, restores the workbook, and prints the same value again.

npm create @bilig/workpaper@latest pricing-workpaper
cd pricing-workpaper
npm install
npm run smoke

Expected output includes this proof shape:

{
  "before": {
    "summary": {
      "decision": "review"
    },
    "inputCells": {
      "units": "Inputs!B2",
      "listPrice": "Inputs!B3"
    }
  },
  "edit": {
    "before": {
      "decision": "review"
    },
    "after": {
      "decision": "approved"
    },
    "restored": {
      "decision": "approved"
    },
    "checks": {
      "decisionChanged": true,
      "formulasPersisted": true,
      "restoredMatchesAfter": true,
      "serializedBytes": 1242
    }
  },
  "verified": true
}

The generated starter uses the same maintained WorkPaper proof shape as the public mirror at https://proompteng.github.io/bilig/npm-eval.ts and examples/headless-workpaper/npm-eval.ts. The exact byte count can change between package versions; verified: true, decisionChanged, formulasPersisted, and restoredMatchesAfter are the checks.

For a route-shaped quote approval API today, run the maintained example:

git clone --depth 1 https://github.com/proompteng/bilig.git
cd bilig
pnpm --dir examples/serverless-workpaper-api install --ignore-workspace
pnpm --dir examples/serverless-workpaper-api run smoke

For a generated project from a blank directory, run npm create @bilig/workpaper@latest pricing-workpaper through the @bilig/create-workpaper package. The package source lives in packages/create-workpaper, and the publish gate is documented in create a Bilig WorkPaper starter. For an agent-ready project with AGENTS.md, CLAUDE.md, GEMINI.md, Copilot / Cursor / Cline / Continue / Windsurf rules, MCP client configs, and an agent:verify script, run npm create @bilig/workpaper@latest pricing-agent -- --agent.

If that proof almost matches a service or agent workflow you maintain, the useful next step is concrete feedback: open or answer one adoption blocker in Discussions: formula coverage, stale XLSX cached values, persistence shape, MCP/agent writeback, or benchmark coverage.

TypeScript API Shape

Most integrations are just this: build a workbook, write an input, read the calculated value, and save the workbook state.

import { WorkPaper, exportWorkPaperDocument, serializeWorkPaperDocument } from '@bilig/workpaper'

const workbook = WorkPaper.buildFromSheets({
  Inputs: [
    ['Metric', 'Value'],
    ['Customers', 20],
    ['Average revenue', 1200],
  ],
  Summary: [
    ['Metric', 'Value'],
    ['Revenue', '=Inputs!B2*Inputs!B3'],
  ],
})

const inputs = workbook.getSheetId('Inputs')
const summary = workbook.getSheetId('Summary')
if (inputs === undefined || summary === undefined) {
  throw new Error('Workbook is missing required sheets')
}

workbook.setCellContents({ sheet: inputs, row: 1, col: 1 }, 32)

const revenue = workbook.getCellDisplayValue({ sheet: summary, row: 1, col: 1 })
const saved = serializeWorkPaperDocument(exportWorkPaperDocument(workbook, { includeConfig: true }))

console.log({ revenue, savedBytes: saved.length })

When To Reach For It

Use @bilig/workpaper when:

  • a Node service owns a workbook-shaped calculation;
  • an agent needs tools such as readRange and setInputCell, with computed before/after values instead of screenshots;
  • tests need deterministic spreadsheet state and formula readback;
  • a workflow needs to save the edited workbook as JSON and restore it later.

Use something else when you need a visual spreadsheet grid, Office macros, desktop Excel automation, or a one-off arithmetic helper. Do not treat embedded XLSX cached formula values as truth; use the Excel oracle workflow when accuracy matters.

Package Boundary

Current checked npm footprint for @bilig/headless@0.130.5:

  • Pack dry run: 820 kB tarball, 5.03 MB unpacked, 800 package entries.
  • Boundary: the main import is the WorkPaper formula/JSON runtime; XLSX import/export stays behind the @bilig/headless/xlsx subpath; MCP is the bilig-workpaper-mcp binary wrapper; reduced workbook reports use the bilig-formula-clinic binary.
  • Cold-start gate: Node imports the main entrypoint, builds a two-sheet WorkPaper, and reads 24000 under 1000 ms without importing the XLSX subpath.
  • Runtime: Node >=22.0.0; Node 22 compatibility is covered by the runtime package workflow.

Published Package Trust

@bilig/headless is published with npm registry signatures and SLSA provenance attestations. Verify the package version you are about to adopt:

npm view @bilig/headless version dist.attestations dist.signatures --json

After installing, npm can verify the current dependency tree:

npm audit signatures

The current package trust path is documented in npm provenance and package trust. Repository security posture is tracked by OpenSSF Scorecard and uploaded to GitHub code scanning on every main update.

Deeper Evaluation Paths

After the first proof in Start Here, use the deeper guide that matches the next job.

  1. Run the 90-second npm eval in a blank project.
  2. Run the flagship serverless WorkPaper API example: npm run quote-approval-api.
  3. If the workflow starts with an XLSX file, run the XLSX formula recalculation in Node: npm start.
  4. If an agent needs workbook tools, start with the headless WorkPaper agent handbook, then use the MCP server guide when the caller is an MCP client.
  5. If a real workbook almost works, start with the formula bug clinic. Then submit a reduced public fixture so the blocker can become a test, example, or corpus case instead of private feedback. Form: https://github.com/proompteng/bilig/issues/new?template=workbook_fixture.yml. Discussion: #414.

The rest of the docs are an index, not a prerequisite.

For comparison and integration details, use the plain-language fit guide, screenshot automation boundary, Google Sheets API boundary, workbook automation examples, the formula workbooks proof page, the Node spreadsheet formula engine guide, server-side spreadsheet automation, framework adapters, formula bug clinic, workbook fixture submissions, OpenAI Agents SDK tools, AI SDK and LangChain tools, CrewAI adapter, the headless WorkPaper agent handbook, the MCP server guide, spreadsheet MCP server comparison, MCP directory status, MCP client setup, Gemini CLI extension, FastMCP Python client, Claude Desktop MCPB bundle, npm provenance and package trust, JavaScript library comparison, headless spreadsheet engine for Node services and agents, XLSX formula recalculation in Node.js, agent XLSX formula recalculation without LibreOffice, Excel file as a Node calculation engine, stale XLSX formula cache in Node.js, SheetJS formula result not updating in Node.js, Microsoft Graph Excel recalculation in Node.js, xlsx-calc alternative for Node workbook recalculation, ExcelJS formula recalculation in Node.js, ExcelJS shared formulas in Node.js, SheetJS/ExcelJS boundary, and headless engine comparison.

Useful deeper examples: invoice totals, budget variance alerts, fulfillment capacity plan, quote approval threshold, subscription MRR forecast, agent framework adapters, MCP tool server shape, XLSX formula recalculation in Node, and serverless quote approval. Run npm run quote-approval-api, npm run agent:openai-agents-sdk, npm run agent:framework-adapters, npm run agent:mcp-tools, npm run agent:mcp-transcript, npm run agent:mcp-file-transcript, npm run agent:mcp-stdio, or npm exec --package @bilig/workpaper -- bilig-workpaper-mcp when that is the path you are evaluating.

The serverless example also includes npm run next-route-handler, npm run next-server-action, npm run next-server-action-formdata, npm run framework-adapters, and npm run persistence-adapters for framework-specific boundary checks.

The MCP server is also listed in the official registry: https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.proompteng%2Fbilig-workpaper. Clients that support Streamable HTTP MCP can also smoke-test the stateless hosted endpoint at https://bilig.proompteng.ai/mcp; use the local stdio server when the agent needs to persist a project WorkPaper JSON file.

Examples You Can Run

The runnable examples are TypeScript files. Some source imports end in .js because Node ESM resolves compiled package output that way; the files you edit and run are still .ts.

From a cloned checkout:

pnpm --dir examples/headless-workpaper install --ignore-workspace
pnpm --dir examples/headless-workpaper run start
pnpm --dir examples/headless-workpaper run json-records
pnpm --dir examples/headless-workpaper run csv-shaped
pnpm --dir examples/headless-workpaper run invoice-totals
pnpm --dir examples/headless-workpaper run budget-variance
pnpm --dir examples/headless-workpaper run fulfillment-capacity
pnpm --dir examples/headless-workpaper run quote-approval
pnpm --dir examples/headless-workpaper run subscription-mrr
pnpm --dir examples/headless-workpaper run persistence

The most useful entry points:

For agent tools:

pnpm --dir examples/headless-workpaper run agent:verify
pnpm --dir examples/headless-workpaper run agent:tool-call
pnpm --dir examples/headless-workpaper run agent:openai-agents-sdk
pnpm --dir examples/headless-workpaper run agent:openai-agents-sdk-mcp
pnpm --dir examples/headless-workpaper run agent:openai-responses
pnpm --dir examples/headless-workpaper run agent:ai-sdk-generate-text
pnpm --dir examples/headless-workpaper run agent:ai-sdk-stream-text
pnpm --dir examples/headless-workpaper run agent:framework-adapters
pnpm --dir examples/langgraph-workpaper-tool-state run smoke
pnpm --dir examples/langchain-mcp-workpaper-toolnode run smoke
pnpm --dir examples/headless-workpaper run agent:mcp-tools
pnpm --dir examples/headless-workpaper run agent:mcp-file-transcript
pnpm --dir examples/headless-workpaper run agent:mcp-stdio

The AI SDK example uses ai-sdk-generate-text-tool-smoke.ts. The OpenAI Agents SDK guide is docs/openai-agents-sdk-workpaper-tool.md. It includes both direct tool() wrapping and MCPServerStdio discovery through the same WorkPaper MCP tool loop. The OpenAI Responses guide is docs/openai-responses-workpaper-tool-call.md. The agent framework guide is docs/vercel-ai-sdk-langchain-spreadsheet-tool.md. The LangGraph.js ToolNode proof is docs/langgraph-workpaper-toolnode-spreadsheet.md. It includes a no-key @langchain/mcp-adapters smoke that discovers the published WorkPaper MCP stdio tools and executes them through ToolNode.

The package also ships the MCP stdio binary:

npm exec --package @bilig/workpaper@latest -- bilig-agent-challenge --json
npm exec --package @bilig/workpaper@latest -- bilig-formula-clinic ./reduced.xlsx --cells "Summary!B7,Inputs!B2"
npm exec --package @bilig/workpaper@latest -- bilig-mcp-challenge --json
npm exec --package @bilig/workpaper@latest -- bilig-workpaper-mcp
npm exec --package @bilig/workpaper@latest -- bilig-workpaper-mcp --workpaper ./pricing.workpaper.json --init-demo-workpaper --writable
npm exec --package @bilig/headless@latest -- bilig-workpaper-mcp
docker build --target bilig-workpaper-mcp -t bilig-workpaper-mcp:local .

bilig-agent-challenge prints the same edit, formula readback, WorkPaper JSON export, restore, and verified: true proof object used by the agent workbook challenge page.

bilig-mcp-challenge proves the file-backed MCP path end to end: initialize JSON-RPC, list tools/resources/prompts, edit Inputs!B3, read recalculated Summary!B3, export the WorkPaper JSON, restart from disk, and return verified: true.

bilig-formula-clinic imports a reduced XLSX locally, samples formulas, reads requested cells through WorkPaper, and prints a Markdown issue body. It does not upload workbook contents.

Without --workpaper, the binary starts the built-in demo workbook. With --workpaper, it loads your persisted WorkPaper JSON and exposes list_sheets, read_range, read_cell, set_cell_contents, set_cell_contents_and_readback, get_cell_display_value, export_workpaper_document, and validate_formula; --writable persists set_cell_contents or set_cell_contents_and_readback edits back to the same file. It also exposes MCP resources and prompts for bilig://workpaper/agent-handoff, bilig://workpaper/current-document, edit_and_verify_workpaper, and debug_workpaper_formula, so capable clients can discover the workflow before calling tools. The Docker target is for MCP directory scanners: it seeds a demo WorkPaper JSON inside the image and starts the file-backed --writable tool surface so tools/list, resources/list, and prompts/list return the general WorkPaper agent surface without cloning this monorepo. For remote MCP clients, the app runtime exposes https://bilig.proompteng.ai/mcp as a stateless JSON-only Streamable HTTP endpoint for tool discovery and write/readback smoke tests.

It is published in the official MCP Registry as io.github.proompteng/bilig-workpaper: https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.proompteng%2Fbilig-workpaper. It is also live on Glama with Try in Browser, A-grade tool pages, and the file-backed WorkPaper tools: https://glama.ai/mcp/servers/proompteng/bilig.

Proof You Can Reproduce

If you are evaluating Bilig runtime packages for production and want release notifications, watch releases: https://github.com/proompteng/bilig/subscription.

XLSX Accuracy Policy

Cached formula values embedded in .xlsx files are cache diagnostics, not an accuracy verdict. A Bilig correctness bug should only be claimed when the expected value came from a fresh Excel recalculation oracle.

OUT=.cache/excel-oracle-evaluation
pnpm workpaper:xlsx-oracle -- prepare-oracle /path/to/xlsx-corpus "$OUT"
pnpm workpaper:xlsx-oracle -- evaluate-cache /path/to/xlsx-corpus "$OUT"
pnpm workpaper:xlsx-oracle -- evaluate-oracle /path/to/xlsx-corpus "$OUT/recalculated" "$OUT"
pnpm workpaper:xlsx-oracle -- summarize "$OUT"

evaluate-cache writes cache-diagnostic.json and stays non-authoritative. evaluate-oracle writes excel-oracle-report.json, and summarize writes summary.md. If Excel automation is unavailable, cells are classified as missing_excel_oracle instead of being promoted to bugs.

What Is In This Repo

  • packages/headless: WorkPaper runtime and npm package.
  • packages/excel-import: XLSX import/export boundary. Install both packages with pnpm add @bilig/headless @bilig/excel-import when you need file import and export.
  • packages/formula: formula parser, binder, compiler, and evaluator.
  • packages/core: workbook engine, snapshots, mutation flow, and scheduler.
  • packages/grid and apps/web: browser spreadsheet shell.
  • apps/bilig: fullstack monolith runtime, API surface, and static asset server.
  • packages/renderer: React workbook renderer.
  • packages/protocol, packages/binary-protocol, packages/agent-api, and packages/worker-transport: protocol and integration boundaries.
  • packages/wasm-kernel: AssemblyScript/WASM numeric fast path.
  • packages/benchmarks: benchmark harness and performance contracts.

For XLSX import/export from TypeScript:

import { WorkPaper } from '@bilig/headless'
import { exportXlsx, importXlsx } from '@bilig/excel-import'

Use WorkPaper.buildFromSnapshot(imported.snapshot) after import and workbook.exportSnapshot() before exportXlsx().

Local Development

Use Node 24+, Bun, and pnpm@10.32.1.

pnpm install
pnpm dev:web
pnpm dev:web-local
pnpm dev:sync

For a full local preflight:

pnpm lint
pnpm typecheck
pnpm test
pnpm test:browser
pnpm run ci

Generated sources and public evidence are checked:

pnpm protocol:check
pnpm formula-inventory:check
pnpm workspace-resolution:check
pnpm workpaper:bench:competitive:check
pnpm docs:discovery:check

For Coding Agents

Start with the public package boundary unless the task is explicitly engine work.

  1. Read packages/workpaper/README.md before touching public WorkPaper behavior.
  2. Read docs/AGENTS.md, docs/skill.md, or docs/llms-full.txt when building an agent-facing integration from outside the repo.
  3. Use public exports from @bilig/workpaper; do not reach into src/ or dist/ when writing consumer examples.
  4. Keep examples TypeScript-first.
  5. Do not call stale XLSX cached formula values an accuracy oracle.
  6. Add focused tests before changing formulas, persistence, range bounds, config rebuilds, events, row/column moves, or sheet lifecycle.
  7. Run the focused package tests first, then broaden to pnpm run ci.

Contributing

Read CONTRIBUTING.md before opening a PR. If this is your first patch, start with the new contributor guide and then claim a scoped starter issue.

Good first patches usually fit one of these shapes:

  • formula fixtures with clear expected behavior;
  • small WorkPaper examples that prove a real service or agent workflow;
  • focused correctness fixes with regression tests;
  • grid accessibility and keyboard-behavior improvements;
  • docs that turn an existing architecture note into a runnable command.

The shortest public on-ramp is the starter issues queue. It keeps code/test picks, example tasks, adapters, and focused docs work in one current list, with small acceptance commands for first patches.

If this is your first contribution to bilig, use the first-timers-only filter.

Security And Support

Read SECURITY.md before sharing vulnerability details, private workbook data, tokens, credentials, or exploit reproductions. Security reports should use GitHub private vulnerability reporting when available, or security@proompteng.ai when the private flow is not visible.

Use SUPPORT.md for the fastest public support path. Good reports include the package version, Node version, OS, exact formula or workbook input, expected value, actual value, and the smallest command or script that reproduces the issue.

CI

Forgejo Actions is the primary CI surface via .forgejo/workflows/forgejo-ci.yml. GitHub Actions mirrors the verification contract in .github/workflows/ci.yml.

The strict gate includes frozen lockfile install, full pnpm run ci, artifact budget checks, browser smoke, and tracked-file cleanliness checks.

License

MIT.