@bilig/workbook 0.54.0 → 0.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,347 +1,194 @@
1
1
  # @bilig/workbook
2
2
 
3
- Agent-first workbook model API and transport-neutral workbook operation language for bilig.
3
+ Generic workbook intent for agents and runtimes.
4
4
 
5
5
  Build `@bilig/workbook` so an agent would love using it: simple, generic,
6
6
  predictable, inspectable, verifiable, and never dependent on hardcoded business
7
7
  models or human spreadsheet UI assumptions.
8
8
 
9
- Use this package when a consumer needs to describe workbook work without taking a
10
- dependency on the engine, app server, transport, or replica-state implementation.
11
-
12
- The public surface stays generic:
13
-
14
- - `defineModel`
15
- - `buildWorkbookActionPlan`
16
- - `planWorkbookAction`
17
- - `inspectModel`
18
- - `collectWorkbookRefs`
19
- - `findTable`, `findColumn`, `findRange`, `findName`, `findRows`
20
- - `find`
21
- - `check`
22
- - `describeModel`
23
- - `describeRef`
24
- - `describePlan`
25
- - `describePlanResult`
26
- - `describeRunResult`
27
- - `describeRuntimeRequirements`
28
- - `verifyPlan`
29
- - `verifyModel`
30
- - `runWorkbookPlan`
31
- - `runWorkbookAction`
32
- - `verifyWorkbookReadbacks`
33
- - `normalizeWorkbookActionInputDescription`
34
- - `workbookActionInputDescriptionKinds`
35
- - `isWorkbookActionInputDescriptionKind`
36
- - `isWorkbookActionInputDescription`
37
- - `isWorkbookActionInput`
38
- - `builtInWorkbookCheckKinds`
39
- - `isBuiltInWorkbookCheckKind`
40
- - `workbookRunErrorCodes`
41
- - `isWorkbookRunErrorCode`
42
- - `formula`
43
- - `workbook.addOp(op, { target?, message? })` inside model actions
44
- - `WorkbookModel`
45
- - `WorkbookAction`
46
- - `WorkbookActionConfig`
47
- - `WorkbookActionDefinition`
48
- - `WorkbookActionContext`
49
- - `WorkbookCheckContext`
50
- - `WorkbookFindWorkbook`
51
- - `WorkbookCheckWorkbook`
52
- - `WorkbookActionWorkbook`
53
- - `WorkbookModelWorkbook`
54
- - `WorkbookFindNamespace`
55
- - `WorkbookActionInput`
56
- - `WorkbookActionInputDescription`
57
- - `WorkbookActionInputDescriptionKind`
58
- - `WorkbookActionInspection`
59
- - `WorkbookAddOpOptions`
60
- - `WorkbookActionPlanResult`
61
- - `WorkbookModelDescription`
62
- - `WorkbookRefDescription`
63
- - `WorkbookActionPlanDescription`
64
- - `WorkbookActionPlanResultDescription`
65
- - `WorkbookRunResultDescription`
66
- - `WorkbookUndoRefDescription`
67
- - `WorkbookRuntimeRequirements`
68
- - `WorkbookRuntimeRequirement`
69
- - `WorkbookRuntimeCapability`
70
- - `WorkbookPlanVerification`
71
- - `WorkbookPlanIssue`
72
- - `WorkbookModelVerification`
73
- - `WorkbookModelActionVerification`
74
- - `WorkbookModelVerificationOptions`
75
- - `WorkbookRunAdapter`
76
- - `WorkbookRunApplyResult`
77
- - `WorkbookRunReadback`
78
- - `WorkbookReadbackVerification`
79
- - `WorkbookReadbackIssue`
80
- - `WorkbookReadbackIssueCode`
81
- - `WorkbookCheckExpectation`
82
- - `WorkbookCheckExpectationDescription`
83
- - `WorkbookBuiltInCheckKind`
84
- - `WorkbookCustomCheckOptions`
85
- - `WorkbookReadbackCheckOptions`
86
- - `WorkbookRawFormulaOptions`
87
- - `WorkbookRunResult`
88
- - `WorkbookRunError`
89
- - `WorkbookRunErrorCode`
90
- - `WorkbookCheckResult`
91
-
92
- The low-level operation language remains available:
93
-
94
- - `WorkbookOp`
95
- - `WorkbookTxn`
96
- - `EngineOp`
97
- - `EngineOpBatch`
98
- - `isEngineOpBatch`
99
-
100
- Formula helpers create portable formula expressions with `@bilig/formula`.
101
- Calculation and workbook execution stay in `@bilig/core` and the app runtime.
102
- Use `planWorkbookAction` when an action name comes from an agent or user input;
103
- it returns `planned` or structured `failed` results instead of requiring
104
- exception control flow.
105
- `defineModel` returns frozen, normalized model metadata. Model and action names
106
- must be non-empty and already trimmed, while descriptions and input metadata are
107
- trimmed and frozen so the manifest an agent inspected cannot be mutated later by
108
- the caller.
109
- Actions can also accept a JSON-safe input:
9
+ Use this package when a consumer wants to define their own workbook model and
10
+ hand a runtime a portable plan. The package does not import the engine, start a
11
+ server, calculate formulas, ship revenue/quote/forecast models, or depend on
12
+ `zod`, `effect`, `@bilig/core`, `@bilig/headless`, or `@bilig/agent-api`.
13
+
14
+ ```sh
15
+ pnpm add @bilig/workbook
16
+ ```
17
+
18
+ ## The Shape
110
19
 
111
20
  ```ts
112
- import { defineModel } from '@bilig/workbook'
21
+ import {
22
+ defineModel,
23
+ describePlan,
24
+ describeRunResult,
25
+ describeRuntimeRequirements,
26
+ formula,
27
+ planWorkbookAction,
28
+ runWorkbookPlan,
29
+ verifyPlan,
30
+ } from "@bilig/workbook";
113
31
 
114
32
  export const model = defineModel({
115
- name: 'custom-writer',
33
+ name: "generic-row-calculator",
116
34
 
117
35
  find(workbook) {
36
+ const table = workbook.findTable({
37
+ headers: ["Item", "Quantity", "Rate", "Status", "Total"],
38
+ });
39
+ const rows = workbook.findRows({
40
+ table,
41
+ where: { column: "Status", op: "eq", value: "ready" },
42
+ });
43
+
118
44
  return {
119
- output: workbook.findRange({ sheetName: 'Sheet1', address: 'B2' }),
120
- }
45
+ table,
46
+ rows,
47
+ quantity: rows.column("Quantity"),
48
+ rate: rows.column("Rate"),
49
+ total: rows.column("Total"),
50
+ };
51
+ },
52
+
53
+ checks({ refs, workbook }) {
54
+ return [workbook.check.exists(refs.table), workbook.check.noFormulaErrors(refs.total)];
121
55
  },
122
56
 
123
57
  actions: {
124
- write({ refs, workbook, input }) {
125
- if (typeof input !== 'object' || input === null || Array.isArray(input)) {
126
- throw new Error('input object required')
127
- }
128
- const value = input.value
129
- if (typeof value !== 'number') {
130
- throw new Error('numeric value required')
131
- }
132
- workbook.writeValue(refs.output, value)
58
+ recompute({ refs, workbook }) {
59
+ const expected = formula.multiply(refs.quantity, refs.rate);
60
+ workbook.writeFormula(refs.total, expected);
61
+ workbook.check.formulaEquals(refs.total, expected);
133
62
  },
134
63
  },
135
- })
136
- ```
64
+ });
137
65
 
138
- `planWorkbookAction(model, "write", { value: 12 })` clones and canonicalizes
139
- that input into the plan so an agent can inspect exactly what was requested.
140
- Inputs must be plain JSON values: strings, finite numbers, booleans, `null`,
141
- arrays without holes, and plain objects. This package intentionally does not add
142
- schema dependencies; consumers own their own input validation inside actions.
143
- Use `verifyModel(model, { inputs: { write: { value: 12 } } })` when whole-model
144
- verification needs parameters for specific actions.
66
+ const planned = planWorkbookAction(model, "recompute");
67
+ if (planned.status === "failed") throw new Error(planned.errors[0]?.message);
145
68
 
146
- Actions can also be plain action objects when an agent needs a richer manifest
147
- without running workbook code:
69
+ const staticProof = verifyPlan(planned.plan);
70
+ const requirements = describeRuntimeRequirements(planned.plan);
71
+ const planForLogs = describePlan(planned.plan);
148
72
 
149
- ```ts
150
- actions: {
151
- write: {
152
- description: 'Write a consumer-provided value',
153
- input: {
154
- kind: 'object',
155
- fields: {
156
- value: { kind: 'number', required: true },
157
- },
158
- },
159
- run({ refs, workbook, input }) {
160
- if (typeof input !== 'object' || input === null || Array.isArray(input)) {
161
- throw new Error('input object required')
162
- }
163
- const value = input.value
164
- if (typeof value !== 'number') {
165
- throw new Error('numeric value required')
166
- }
167
- workbook.writeValue(refs.output, value)
168
- },
169
- },
170
- }
73
+ const result = await runWorkbookPlan(planned.plan, adapter);
74
+ const resultForLogs = describeRunResult(result);
171
75
  ```
172
76
 
173
- Input descriptions are intentionally descriptive metadata, not a schema engine.
174
- They support boring JSON kinds: `json`, `object`, `array`, `string`, `number`,
175
- `boolean`, and `null`. `object` descriptions may list sorted `fields`; `array`
176
- descriptions may list `items`. `normalizeWorkbookActionInputDescription` trims
177
- text, rejects malformed metadata, returns frozen data, and keeps the package
178
- free of `zod`, `effect`, or model-specific validators.
179
- `workbookActionInputDescriptionKinds`, `isWorkbookActionInputDescriptionKind`,
180
- `isWorkbookActionInputDescription`, and `isWorkbookActionInput` expose the same
181
- contract as stable data so generic tool builders can validate model metadata and
182
- JSON-safe payloads without ad hoc string matching.
183
-
184
- Formula expressions also keep their workbook inputs separate from their formula
185
- text. A planned `writeFormula` command includes both the parseable formula
186
- string and the generic model refs it used, so an agent can inspect what the
187
- action depends on without reverse-parsing placeholder names.
188
- For formulas outside the small helper set, use
189
- `formula.raw(source, { inputs })`; the source stays parseable while the
190
- declared refs remain inspectable and verifiable. These inputs are a declared
191
- dependency contract for agents, not parser-discovered proof that every formula
192
- reference has been mapped to a model ref.
193
- Formula operands intentionally do not accept bare strings. Use `formula.raw`
194
- for formula source and `formula.text` for spreadsheet string literals, so an
195
- agent cannot confuse a label, cell address, named range, or user-provided string
196
- with executable formula text.
197
-
198
- Known single-cell `workbook.format(ref, { numberFormat })` actions compile to
199
- concrete `setCellFormat` ops. Use `numberFormat: null` to plan an explicit
200
- format clear. Style patches remain high-level intent until the runtime resolves
201
- style ids.
202
- Use `workbook.addOp(op, { target?, message? })` inside model actions when a
203
- consumer needs the existing low-level workbook operation language directly. The
204
- op is runtime-guarded with `isWorkbookOp`, cloned into `plan.ops`, and kept in
205
- the command log so agents can inspect it without depending on `@bilig/core`.
206
- When a `target` is supplied for an address or range op, `verifyPlan` checks that
207
- the op touches the same range. For op kinds without an inferable range, `target`
208
- is still useful for logs and approvals but cannot prove the affected cells by
209
- itself.
210
-
211
- Action plans expose `refsUsed`, a flat deduped list of workbook refs found in
212
- the consumer-defined `refs` object. Use `collectWorkbookRefs` directly when an
213
- agent needs to inspect refs from any nested consumer shape.
214
- Use `findTable`, `findColumn`, `findRange`, `findName`, and `findRows` directly
215
- when an agent or test needs the same generic refs outside a model callback. The
216
- same helpers are also available as a frozen `find` namespace with short aliases
217
- such as `find.table(...)`, `find.range(...)`, and `find.rows(...)`.
218
- Selector helpers trim text, canonicalize cell addresses, and reject empty table
219
- names, column names, named ranges, headers, invalid range addresses, invalid row
220
- operators, and non-finite row predicate values before a plan reaches runtime.
221
- `findRows` refs include the predicate value in their stable id so two
222
- consumer-defined row selectors do not collapse during dedupe, while labels stay
223
- human-readable for agent logs.
224
- Refs are frozen data objects. Ergonomic helpers like `table.column()` and
225
- `rows.column()` remain available, but they are non-enumerable so JSON
226
- inspection, object keys, and plan descriptions stay data-first.
227
- For table-backed rows, use `rows.column("Amount")` to target only that column in
228
- the matching rows. Runtime adapters can materialize row-filtered columns into
229
- the exact cells to read, write, format, clear, or use as row-wise formula inputs
230
- without hardcoding a business model.
231
- Use `check.exists(ref)` and `check.noFormulaErrors(ref)` directly when an agent
232
- or test needs the same generic planned checks outside a model callback.
233
- Use `check.valueEquals(ref, value)` and `check.formulaEquals(ref, formula)` when
234
- an action should carry machine-readable readback expectations for runtime
235
- verification. `formulaEquals` stores normalized formula text plus explicit model
236
- refs used by that formula, so an agent can inspect the post-action proof target
237
- without depending on a rendered spreadsheet UI.
238
- Use `check.custom({ kind, message, target, refs })` for consumer-defined
239
- invariants; the package does not need to know what the model means. `target`
240
- names the main ref, and `refs` names any supporting refs the invariant depends
241
- on so agents can describe and verify the full check contract.
242
- Custom check kinds cannot reuse built-in names. Use the frozen
243
- `builtInWorkbookCheckKinds` list or `isBuiltInWorkbookCheckKind` guard when a
244
- consumer-facing tool needs to validate check kinds before planning.
245
-
246
- Model callback phases are deliberately scoped. `find(workbook)` receives only
247
- the find API; `checks({ workbook })` receives find helpers plus `workbook.check`;
248
- actions receive find helpers, checks, and mutation planning methods. That keeps
249
- discovery and proof declaration separate from workbook mutation intent.
250
-
251
- Use `describeModel` when an agent needs a JSON-safe manifest of model name,
252
- model description, sorted action names, per-action descriptions, optional input
253
- descriptions, and whether model-level checks exist without running `find`,
254
- checks, or actions.
255
- Use `describeRef` and `describePlan` when an agent needs JSON-safe intent for
256
- logs, comparisons, approvals, or runtime handoff. Descriptions keep the same
257
- generic action input, refs, commands, checks, changes, and ops, but omit
258
- consumer-private `refs` object shape and helper functions such as
259
- `table.column()`.
260
- Use `describePlanResult` when the same JSON-safe handoff is needed for either
261
- planned or failed action planning.
262
- Use `describeRunResult` after execution when an agent needs the same JSON-safe
263
- shape for `done` or `failed` run results. It preserves changed summaries,
264
- checks, errors, and undo ops, but describes workbook refs without helper
265
- functions such as `table.column()` or `rows.column()`.
266
- Run errors use a stable `WorkbookRunErrorCode` union rather than arbitrary
267
- strings. Use the frozen `workbookRunErrorCodes` list and `isWorkbookRunErrorCode`
268
- guard when an adapter, logger, or approval layer needs to branch on known
269
- failure classes. Runtime adapters should use `apply_failed` for apply
270
- exceptions and `runtime_rejected` for intentional runtime refusal with a
271
- specific message instead of inventing new public codes.
272
- Use `describeRuntimeRequirements(plan)` before runtime handoff when an agent
273
- needs to inspect what the adapter must do. It returns a JSON-safe list of
274
- generic `apply`, `read`, and `verify` requirements with boring capabilities
275
- such as `writeFormula`, `writeValue`, `format`, `clear`, `applyOp`, `read`, and
276
- `verifyCheck`. Command-derived concrete single-cell ops are not repeated as
277
- extra `applyOp` requirements, while explicit or manually assembled ops still
278
- appear as `applyOp`. It does not execute anything and it does not import the
279
- engine.
280
-
281
- Use `verifyPlan` before runtime handoff when an agent needs to prove a planned
282
- action is internally consistent. It checks for non-JSON-safe action input,
283
- unresolved refs, unparsable formulas, duplicate resolved refs, and missing
284
- concrete ops for write, clear, and number-format commands that already target a
285
- known single cell. Custom check targets and supporting refs must also resolve
286
- through the model's `refsUsed` contract. Formula readback expectation inputs
287
- must also resolve through `refsUsed`, and expectation formulas must be parseable.
288
- Checks must start as `planned`; consumer code cannot mark a check passed or
289
- failed before runtime proof.
290
- Low-level `addOp` commands must contain valid `WorkbookOp` values, must still
291
- appear in `plan.ops`, and must match their declared `target` when the op exposes
292
- a concrete address or range.
293
- Use `verifyModel` to plan and verify every action in a consumer-defined model
294
- with one JSON-safe result. Pass `inputs` when specific actions require
295
- parameters. Each successfully planned action also includes its runtime
296
- requirements, so an agent can inspect the action manifest, planned intent,
297
- static verification result, and adapter handoff checklist from the same object.
298
-
299
- Use `runWorkbookPlan(plan, adapter)` or
300
- `runWorkbookAction(model, actionName, adapter, input)` when an agent needs a
301
- generic apply-and-prove loop. The adapter owns runtime execution and semantic
302
- readback:
77
+ That is the core flow:
78
+
79
+ 1. `defineModel` freezes a consumer-defined model.
80
+ 2. `find` returns generic refs.
81
+ 3. `checks` declares facts the runtime must prove.
82
+ 4. An action builds workbook intent.
83
+ 5. `verifyPlan` checks the plan without running an engine.
84
+ 6. `describeRuntimeRequirements` tells an adapter what it must apply, read, and prove.
85
+ 7. `runWorkbookPlan` applies the plan through a runtime-owned adapter and returns a boring result.
86
+
87
+ ## Public Contract
88
+
89
+ The main API is intentionally small:
90
+
91
+ - model: `defineModel`, `inspectModel`, `planWorkbookAction`, `buildWorkbookActionPlan`
92
+ - selectors: `findTable`, `findColumn`, `findRange`, `findName`, `findRows`, `find`
93
+ - checks: `check.exists`, `check.noFormulaErrors`, `check.valueEquals`, `check.formulaEquals`, `check.custom`
94
+ - formulas: `formula.add`, `formula.subtract`, `formula.multiply`, `formula.divide`, `formula.sum`, `formula.call`, `formula.raw`, `formula.text`
95
+ - proof: `verifyPlan`, `verifyModel`, `verifyWorkbookReadbacks`
96
+ - descriptions: `describeModel`, `describeRef`, `describePlan`, `describePlanResult`, `describeRuntimeRequirements`, `describeRunResult`
97
+ - runtime handoff: `runWorkbookPlan`, `runWorkbookAction`, `WorkbookRunAdapter`
98
+ - low-level language: `WorkbookOp`, `WorkbookTxn`, `EngineOp`, `EngineOpBatch`, `isEngineOpBatch`
99
+
100
+ Stable data helpers are exported for generic tool builders:
101
+
102
+ - `workbookRefKinds`, `isWorkbookRefKind`, `isWorkbookRef`
103
+ - `workbookRowOperators`, `workbookRowOperatorValueTypes`, `isWorkbookRowOperator`, `isWorkbookRowValueCompatible`
104
+ - `builtInWorkbookCheckKinds`, `isBuiltInWorkbookCheckKind`
105
+ - `workbookActionInputDescriptionKinds`, `isWorkbookActionInputDescriptionKind`, `isWorkbookActionInputDescription`, `isWorkbookActionInput`
106
+ - `workbookRunErrorCodes`, `isWorkbookRunErrorCode`
107
+
108
+ ## Selectors
109
+
110
+ Selectors are not a human spreadsheet UI. They are stable intent for runtimes and
111
+ agents.
112
+
113
+ - `findTable({ headers })` means "find a table with all these headers." Header
114
+ order is normalized, duplicate headers are rejected, and matching is
115
+ case-sensitive after trimming.
116
+ - `findRows({ table, where })` means "find rows in this table matching this
117
+ predicate." `eq` and `neq` accept any JSON literal; `contains` and
118
+ `startsWith` accept strings; ordered comparisons accept numbers or strings.
119
+ - `findRange` is the escape hatch for an explicit range when the consumer really
120
+ has one. It validates and canonicalizes addresses before runtime handoff.
121
+
122
+ Refs are frozen data. Helpers such as `table.column("Total")` and
123
+ `rows.column("Total")` are non-enumerable, so JSON descriptions stay data-first.
124
+
125
+ ## Formulas
126
+
127
+ `@bilig/workbook` creates formula expressions. `@bilig/formula` parses and
128
+ normalizes formula text. `@bilig/core` or an app runtime calculates it.
129
+
130
+ Formula helpers keep formula text and workbook dependencies separate. A planned
131
+ formula write includes both the formula string and the refs used to build it.
132
+ For custom formula text, use `formula.raw(source, { inputs })`. For spreadsheet
133
+ string literals, use `formula.text(value)`. Bare strings are not formula
134
+ operands because agents should not guess whether a string is code, a label, a
135
+ named range, or user text.
136
+
137
+ ## Runtime Adapter
138
+
139
+ `@bilig/workbook` does not execute plans. A runtime owns that:
303
140
 
304
141
  ```ts
305
- const result = await runWorkbookAction(model, 'write', {
142
+ const adapter = {
306
143
  apply(plan) {
307
- return runtime.apply(plan.ops)
144
+ return { status: "applied", undo: { id: "undo-1" } };
308
145
  },
309
- read(targets) {
310
- return runtime.read(targets)
146
+ read(targets, plan) {
147
+ return targets.map((target) => ({ target, value: 12 }));
311
148
  },
312
- })
149
+ verifyChecks(checks, plan) {
150
+ return checks.map((entry) => ({ ...entry, status: "passed" }));
151
+ },
152
+ };
313
153
  ```
314
154
 
315
- `runWorkbookAction` plans the action, runs `verifyPlan`, calls
316
- `adapter.apply(plan)`, then evaluates `valueEquals` and `formulaEquals` checks
317
- against `adapter.read(targets, plan)`. It never imports the engine, headless
318
- runtime, app server, or UI. If static verification fails, the apply adapter is
319
- not called. If a readback expectation is missing or mismatched, the returned
320
- `WorkbookRunResult` is `failed` with deterministic error codes such as
321
- `readback_missing`, `value_mismatch`, or `formula_mismatch`. `adapter.read`
322
- must return exactly the requested targets; extra readbacks fail with
323
- `readback_unexpected` because an agent should not accept proof for cells it did
324
- not ask the runtime to inspect.
325
- Formula readbacks are exact: adapters should return formula text in the same
326
- normalized no-leading-`=` form produced by `formula.source`.
327
- `adapter.apply` only applies the plan and may return an undo ref; it cannot
328
- drop, replace, or prove checks. An apply result with `status: "applied"` and
329
- non-empty `errors` is rejected as `runtime_rejected`.
330
- Adapters provide `verifyChecks(checks, plan)` to prove non-readback checks such
331
- as `exists`, `noFormulaErrors`, and consumer-defined `custom` invariants. The
332
- verifier must return the same checks in the same order and may only change
333
- `status` or add JSON-safe `proof`. Changing `kind`, `target`, `refs`,
334
- `expectation`, or `message` fails the run as `invalid_check_verification`.
335
- Unsupported verifier fields are stripped from accepted results. If any verified
336
- check is `failed`, the run returns `failed` with `check_failed`. If any check
337
- remains `planned` after readback and adapter verification, the run returns
338
- `failed` with `check_not_verified`; `status: "done"` means every planned check
339
- has proof.
340
-
341
- When running against Bilig's engine, use `createWorkbookRunAdapter(engine)` from
342
- `@bilig/core`. The adapter materializes generic `plan.commands` into engine
343
- operations, falls back to explicit `plan.ops` for low-level plans, reads
344
- single-cell expectation targets, and verifies generic `exists` and
345
- `noFormulaErrors` checks without adding workbook-specific business models to
346
- this package. If the engine captures undo, the run result includes `undo.ops` in
347
- the same portable operation language.
155
+ `runWorkbookPlan` refuses to call `apply` if static plan verification fails.
156
+ Readback checks attach proof to passed checks, such as
157
+ `{ source: "readback", value: 12 }` or
158
+ `{ source: "readback", formula: "(Table[Quantity])*(Table[Rate])" }`.
159
+ Generic check verifiers may only change `status` or add JSON-safe `proof`; they
160
+ cannot rewrite the check contract.
161
+
162
+ The result is deliberately plain:
163
+
164
+ ```ts
165
+ type WorkbookRunResult =
166
+ | {
167
+ status: "done";
168
+ changed: WorkbookChangeSummary[];
169
+ checks: WorkbookCheckResult[];
170
+ undo?: WorkbookUndoRef;
171
+ }
172
+ | {
173
+ status: "failed";
174
+ errors: WorkbookRunError[];
175
+ checks: WorkbookCheckResult[];
176
+ };
177
+ ```
178
+
179
+ ## Low-Level Ops
180
+
181
+ Most models should use the small action API: `writeFormula`, `writeValue`,
182
+ `format`, `clear`, and checks. If a consumer needs the existing workbook
183
+ operation language directly, call `workbook.addOp(op, { target, message })`
184
+ inside an action.
185
+
186
+ The op is guarded with `isWorkbookOp`, cloned into `plan.ops`, and kept in the
187
+ command log. If a target is supplied and the op exposes a concrete range,
188
+ `verifyPlan` checks that the target and op agree.
189
+
190
+ ## Example
191
+
192
+ See [examples/workbook-agent-model](../../examples/workbook-agent-model) for a
193
+ generic model that plans, verifies, describes, runs, and prints proof without
194
+ depending on a hardcoded business model.
package/dist/check.js CHANGED
@@ -46,14 +46,22 @@ function uniqueRefs(refs) {
46
46
  }
47
47
  function createWorkbookCheck(options) {
48
48
  const refs = uniqueRefs(options.refs);
49
- return {
49
+ const expectation = options.expectation === undefined
50
+ ? undefined
51
+ : options.expectation.kind === 'formulaEquals'
52
+ ? Object.freeze({
53
+ ...options.expectation,
54
+ inputs: Object.freeze([...options.expectation.inputs]),
55
+ })
56
+ : Object.freeze({ ...options.expectation });
57
+ return Object.freeze({
50
58
  status: 'planned',
51
59
  kind: requiredText(options.kind, 'kind'),
52
60
  ...(options.target !== undefined ? { target: options.target } : {}),
53
- ...(refs !== undefined ? { refs } : {}),
61
+ ...(refs !== undefined ? { refs: Object.freeze([...refs]) } : {}),
54
62
  message: requiredText(options.message, 'message'),
55
- ...(options.expectation !== undefined ? { expectation: options.expectation } : {}),
56
- };
63
+ ...(expectation !== undefined ? { expectation } : {}),
64
+ });
57
65
  }
58
66
  export function createWorkbookCustomCheck(options) {
59
67
  const kind = requiredText(options.kind, 'kind');
package/dist/check.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"check.js","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"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"}
package/dist/find.d.ts CHANGED
@@ -27,6 +27,18 @@ export interface WorkbookColumnRef extends WorkbookBaseRef {
27
27
  readonly name: string;
28
28
  }
29
29
  export type WorkbookRowOperator = 'eq' | 'neq' | 'contains' | 'startsWith' | 'gt' | 'gte' | 'lt' | 'lte';
30
+ export type WorkbookRowValueType = 'number' | 'string' | 'boolean' | 'null';
31
+ export declare const workbookRowOperators: readonly ["eq", "neq", "contains", "startsWith", "gt", "gte", "lt", "lte"];
32
+ export declare const workbookRowOperatorValueTypes: Readonly<{
33
+ readonly eq: readonly ("string" | "number" | "boolean" | "null")[];
34
+ readonly neq: readonly ("string" | "number" | "boolean" | "null")[];
35
+ readonly contains: readonly "string"[];
36
+ readonly startsWith: readonly "string"[];
37
+ readonly gt: readonly ("string" | "number")[];
38
+ readonly gte: readonly ("string" | "number")[];
39
+ readonly lt: readonly ("string" | "number")[];
40
+ readonly lte: readonly ("string" | "number")[];
41
+ }>;
30
42
  export interface WorkbookRowsRef extends WorkbookBaseRef {
31
43
  readonly kind: 'rows';
32
44
  readonly sheetName?: string;
@@ -39,6 +51,8 @@ export interface WorkbookRowsRef extends WorkbookBaseRef {
39
51
  readonly column: (name: string) => WorkbookColumnRef;
40
52
  }
41
53
  export type WorkbookRef = WorkbookRangeRef | WorkbookNameRef | WorkbookTableRef | WorkbookColumnRef | WorkbookRowsRef;
54
+ export declare const workbookRefKinds: readonly ["range", "name", "table", "column", "rows"];
55
+ export declare function isWorkbookRefKind(value: unknown): value is WorkbookRefKind;
42
56
  export declare function isWorkbookRef(value: unknown): value is WorkbookRef;
43
57
  export declare function collectWorkbookRefs(value: unknown): readonly WorkbookRef[];
44
58
  export interface FindTableOptions {
@@ -84,6 +98,8 @@ export interface WorkbookFindNamespace extends WorkbookFindApi {
84
98
  readonly name: (name: string) => WorkbookNameRef;
85
99
  readonly rows: (options: FindRowsOptions) => WorkbookRowsRef;
86
100
  }
101
+ export declare function isWorkbookRowOperator(value: unknown): value is WorkbookRowOperator;
102
+ export declare function isWorkbookRowValueCompatible(op: WorkbookRowOperator, value: LiteralInput): boolean;
87
103
  export declare function normalizeRangeRef(input: FindRangeInput): CellRangeRef;
88
104
  export declare function createWorkbookTableRef(options: FindTableOptions): WorkbookTableRef;
89
105
  export declare function createWorkbookColumnRef(options: FindColumnOptions): WorkbookColumnRef;