@sheetxl/query 0.7.23-beta.1

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.
Files changed (82) hide show
  1. package/LICENSE.md +11 -0
  2. package/README.md +69 -0
  3. package/browser/cjs/index.cjs +26 -0
  4. package/browser/esm/index.mjs +1994 -0
  5. package/licenses/dependencies.txt +1 -0
  6. package/node/esm/index.mjs +2024 -0
  7. package/package.json +52 -0
  8. package/types/index.d.ts +2 -0
  9. package/types/src/Tool.d.ts +108 -0
  10. package/types/src/Tool.d.ts.map +1 -0
  11. package/types/src/encode/encodeCell.d.ts +149 -0
  12. package/types/src/encode/encodeCell.d.ts.map +1 -0
  13. package/types/src/encode/index.d.ts +2 -0
  14. package/types/src/encode/index.d.ts.map +1 -0
  15. package/types/src/grep/GrepTypes.d.ts +308 -0
  16. package/types/src/grep/GrepTypes.d.ts.map +1 -0
  17. package/types/src/grep/grep.d.ts +15 -0
  18. package/types/src/grep/grep.d.ts.map +1 -0
  19. package/types/src/grep/grepTool.d.ts +16 -0
  20. package/types/src/grep/grepTool.d.ts.map +1 -0
  21. package/types/src/grep/index.d.ts +5 -0
  22. package/types/src/grep/index.d.ts.map +1 -0
  23. package/types/src/grep/renderGrep.d.ts +19 -0
  24. package/types/src/grep/renderGrep.d.ts.map +1 -0
  25. package/types/src/index.d.ts +20 -0
  26. package/types/src/index.d.ts.map +1 -0
  27. package/types/src/markdown/MarkdownBuilder.d.ts +84 -0
  28. package/types/src/markdown/MarkdownBuilder.d.ts.map +1 -0
  29. package/types/src/markdown/appendSections.d.ts +364 -0
  30. package/types/src/markdown/appendSections.d.ts.map +1 -0
  31. package/types/src/markdown/caps.d.ts +24 -0
  32. package/types/src/markdown/caps.d.ts.map +1 -0
  33. package/types/src/markdown/describeRegionPayload.d.ts +46 -0
  34. package/types/src/markdown/describeRegionPayload.d.ts.map +1 -0
  35. package/types/src/markdown/describeRule.d.ts +66 -0
  36. package/types/src/markdown/describeRule.d.ts.map +1 -0
  37. package/types/src/markdown/describeStyle.d.ts +64 -0
  38. package/types/src/markdown/describeStyle.d.ts.map +1 -0
  39. package/types/src/markdown/index.d.ts +27 -0
  40. package/types/src/markdown/index.d.ts.map +1 -0
  41. package/types/src/markdown/parseRenderOptions.d.ts +16 -0
  42. package/types/src/markdown/parseRenderOptions.d.ts.map +1 -0
  43. package/types/src/markdown/profileRegion.d.ts +121 -0
  44. package/types/src/markdown/profileRegion.d.ts.map +1 -0
  45. package/types/src/markdown/registry.d.ts +96 -0
  46. package/types/src/markdown/registry.d.ts.map +1 -0
  47. package/types/src/markdown/renderCell.d.ts +23 -0
  48. package/types/src/markdown/renderCell.d.ts.map +1 -0
  49. package/types/src/markdown/renderCellRange.d.ts +61 -0
  50. package/types/src/markdown/renderCellRange.d.ts.map +1 -0
  51. package/types/src/markdown/renderConditionalFormat.d.ts +15 -0
  52. package/types/src/markdown/renderConditionalFormat.d.ts.map +1 -0
  53. package/types/src/markdown/renderCounts.d.ts +11 -0
  54. package/types/src/markdown/renderCounts.d.ts.map +1 -0
  55. package/types/src/markdown/renderDataValidation.d.ts +15 -0
  56. package/types/src/markdown/renderDataValidation.d.ts.map +1 -0
  57. package/types/src/markdown/renderFormula.d.ts +63 -0
  58. package/types/src/markdown/renderFormula.d.ts.map +1 -0
  59. package/types/src/markdown/renderMovable.d.ts +35 -0
  60. package/types/src/markdown/renderMovable.d.ts.map +1 -0
  61. package/types/src/markdown/renderNames.d.ts +32 -0
  62. package/types/src/markdown/renderNames.d.ts.map +1 -0
  63. package/types/src/markdown/renderRanges.d.ts +33 -0
  64. package/types/src/markdown/renderRanges.d.ts.map +1 -0
  65. package/types/src/markdown/renderRecords.d.ts +39 -0
  66. package/types/src/markdown/renderRecords.d.ts.map +1 -0
  67. package/types/src/markdown/renderRegions.d.ts +70 -0
  68. package/types/src/markdown/renderRegions.d.ts.map +1 -0
  69. package/types/src/markdown/renderResult.d.ts +35 -0
  70. package/types/src/markdown/renderResult.d.ts.map +1 -0
  71. package/types/src/markdown/renderSheet.d.ts +29 -0
  72. package/types/src/markdown/renderSheet.d.ts.map +1 -0
  73. package/types/src/markdown/renderStats.d.ts +18 -0
  74. package/types/src/markdown/renderStats.d.ts.map +1 -0
  75. package/types/src/markdown/renderStyle.d.ts +12 -0
  76. package/types/src/markdown/renderStyle.d.ts.map +1 -0
  77. package/types/src/markdown/renderTable.d.ts +12 -0
  78. package/types/src/markdown/renderTable.d.ts.map +1 -0
  79. package/types/src/markdown/renderValues.d.ts +28 -0
  80. package/types/src/markdown/renderValues.d.ts.map +1 -0
  81. package/types/src/markdown/renderWorkbook.d.ts +50 -0
  82. package/types/src/markdown/renderWorkbook.d.ts.map +1 -0
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@sheetxl/query",
3
+ "description": "SheetXL - Workbook read surface and renderers (grep, reports) — capabilities declared once, adapted by any host surface",
4
+ "version": "0.7.23-beta.1",
5
+ "license": "SEE LICENSE IN <LICENSE>",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./types/index.d.ts",
10
+ "browser": "./browser/esm/index.mjs",
11
+ "node": "./node/esm/index.mjs",
12
+ "import": "./browser/esm/index.mjs",
13
+ "require": "./browser/cjs/index.cjs"
14
+ }
15
+ },
16
+ "types": "./types/index.d.ts",
17
+ "module": "./browser/esm/index.mjs",
18
+ "main": "./browser/cjs/index.cjs",
19
+ "sideEffects": false,
20
+ "engines": {
21
+ "node": ">=20 <21 || >=22"
22
+ },
23
+ "engineStrict": true,
24
+ "homepage": "https://sheetxl.com",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "https://github.com/sheetxl/sheetxl.git"
28
+ },
29
+ "bugs": {
30
+ "url": "https://github.com/sheetxl/sheetxl/issues"
31
+ },
32
+ "keywords": [
33
+ "sheetxl",
34
+ "spreadsheet",
35
+ "javascript",
36
+ "typescript",
37
+ "excel",
38
+ "xlsx",
39
+ "agent",
40
+ "ai",
41
+ "mcp",
42
+ "grep",
43
+ "query"
44
+ ],
45
+ "dependencies": {
46
+ "@sheetxl/primitives": "^0.7.23-beta.1",
47
+ "@sheetxl/sdk": "^0.7.23-beta.1"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^26.1.2"
51
+ }
52
+ }
@@ -0,0 +1,2 @@
1
+ export * from './src/index'
2
+ export {}
@@ -0,0 +1,108 @@
1
+ import { IWorkbook } from '@sheetxl/sdk';
2
+ /**
3
+ * The read surface is defined once, here, and adapted mechanically by each host surface —
4
+ * no surface hand-writes a second copy of a capability.
5
+ *
6
+ * @remarks
7
+ * All text on a descriptor is **agent-facing and English**. It is read by a model, not by a
8
+ * person, so it is deliberately not routed through `t()`. Localized chrome (help headings,
9
+ * error framing) belongs to the surface that wraps this.
10
+ */
11
+ export declare namespace Tool {
12
+ /**
13
+ * The value kinds a parameter may take.
14
+ *
15
+ * @remarks
16
+ * Deliberately small. Every kind maps cleanly onto both a command-line option and a JSON
17
+ * Schema property; anything that does not is a sign the parameter wants to be its own tool.
18
+ */
19
+ type ParamType = 'string' | 'number' | 'boolean' | 'enum' | 'enum[]';
20
+ /**
21
+ * One argument of a tool, in the canonical (camelCase) form.
22
+ *
23
+ * @remarks
24
+ * Surfaces rename mechanically and never by hand: a flag surface kebab-cases (`ignoreCase`
25
+ * → `--ignore-case`), a schema surface passes the name through. A surface that needs a
26
+ * *different* name is declaring a divergence, and there is nowhere to put one.
27
+ */
28
+ interface Param {
29
+ /** Canonical camelCase name. */
30
+ readonly name: string;
31
+ readonly type: ParamType;
32
+ /** One line, agent-facing, English. */
33
+ readonly description: string;
34
+ readonly required?: boolean;
35
+ /**
36
+ * Applied by the tool, not by the adapter.
37
+ *
38
+ * @remarks
39
+ * Adapters must not inject defaults — if two surfaces default differently the capability has
40
+ * silently diverged, which is the whole failure this package exists to prevent.
41
+ */
42
+ readonly defaultValue?: unknown;
43
+ /** Allowed values for `enum` / `enum[]`. */
44
+ readonly values?: readonly string[];
45
+ /**
46
+ * The flag's value may be omitted (`--context` vs `--context table`).
47
+ *
48
+ * @remarks
49
+ * The bare form reaches the tool as `true`, and the tool — never the adapter — decides
50
+ * what `true` means, for the same reason adapters must not inject defaults. On a schema
51
+ * surface this is the union of `boolean` and the enum.
52
+ */
53
+ readonly valueOptional?: boolean;
54
+ /**
55
+ * Terminal affordance: register as a positional argument at this index rather than a flag.
56
+ *
57
+ * @remarks
58
+ * Schema surfaces ignore this — their arguments are all named. Positional order is a
59
+ * terminal convenience, not part of the capability.
60
+ */
61
+ readonly positional?: number;
62
+ /** Terminal affordance: single-character alias (`-i`). */
63
+ readonly alias?: string;
64
+ }
65
+ /**
66
+ * A read capability, plus its default rendering.
67
+ *
68
+ * @remarks
69
+ * `run` returns typed data and `render` turns it into the agent-facing text form. They are
70
+ * separate so a consumer that wants the data (a macro's caller, a UI, a test) is never forced
71
+ * through the string.
72
+ */
73
+ interface Descriptor<A = any, R = any> {
74
+ /** Tool name and subcommand — the same word on every surface. */
75
+ readonly name: string;
76
+ /** One or two lines, agent-facing, English. */
77
+ readonly description: string;
78
+ /**
79
+ * The SDK expression this tool wraps, e.g. `sheet.getRange(scope).find(pattern, {...})`.
80
+ *
81
+ * @remarks
82
+ * Rendered into every surface's description as one `SDK: …` line — the graduation path
83
+ * from tool call to macro. Generated from here so the mapping cannot drift from the tool
84
+ * it describes; it also makes tool↔SDK name divergence harmless where realigning an
85
+ * existing SDK method is cheaper than renaming it.
86
+ */
87
+ readonly sdk?: string;
88
+ readonly params: readonly Param[];
89
+ /**
90
+ * Execute against a live workbook.
91
+ *
92
+ * @remarks
93
+ * Takes an `IWorkbook`, never a path. A stateful host may hold a workbook with unsaved
94
+ * edits and no file behind it; a path-shaped entry point would either exclude it or make
95
+ * it read stale data. Loading is the caller's job.
96
+ */
97
+ run(workbook: IWorkbook, args: A): Promise<R>;
98
+ /**
99
+ * The default agent-facing rendering of a result.
100
+ *
101
+ * @remarks
102
+ * May be async — report renderers settle calculation before reading. Adapters `await` the
103
+ * result; a sync renderer (grep) is unaffected.
104
+ */
105
+ render(result: R): string | Promise<string>;
106
+ }
107
+ }
108
+ //# sourceMappingURL=Tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tool.d.ts","sourceRoot":"","sources":["../../../src/Tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C;;;;;;;;GAQG;AACH,yBAAiB,IAAI,CAAC;IACpB;;;;;;OAMG;IACH,KAAY,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IAE5E;;;;;;;OAOG;IACH,UAAiB,KAAK;QACpB,gCAAgC;QAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;QACzB,uCAAuC;QACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAC5B;;;;;;WAMG;QACH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;QAChC,4CAA4C;QAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QACpC;;;;;;;WAOG;QACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;QACjC;;;;;;WAMG;QACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAC7B,0DAA0D;QAC1D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;KACzB;IAED;;;;;;;OAOG;IACH,UAAiB,UAAU,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG;QAC1C,iEAAiE;QACjE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,+CAA+C;QAC/C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B;;;;;;;;WAQG;QACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;QAClC;;;;;;;WAOG;QACH,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAC9C;;;;;;WAMG;QACH,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;KAC7C;CACF"}
@@ -0,0 +1,149 @@
1
+ import { ICell, Scalar } from '@sheetxl/sdk';
2
+ /**
3
+ * The agent-facing value encoding.
4
+ *
5
+ * @remarks
6
+ * This is a **presentation contract, not an engine concern** — the SDK is code and has no need
7
+ * of it. Number formatting (turning `0.04` into `4%`) is legitimately the engine's job because
8
+ * the grid renders it; the encoding *on top* — the `'` prefix, `TRUE`/`FALSE`, error literals,
9
+ * blank elision — exists so a model reading a flat listing can infer types without a type
10
+ * column. That belongs here, above the SDK, beside the renderers that depend on it.
11
+ *
12
+ * Every read surface shares this module. `query_values`, `describe` and the markdown migration
13
+ * encode through it too, which is the property that makes {@link CellEncoding.Display | display}
14
+ * greppable: whatever text a read printed, grep can find, because one encoder produced both.
15
+ *
16
+ * ---
17
+ *
18
+ * **Quarantine note.** `ICell.getText()` is the only SDK call this module makes, and it is on its
19
+ * way out — its contract fuses formatting, localization, csv escaping and this encoding into one
20
+ * method with no clear answer for large values. It is isolated to this file deliberately: when
21
+ * the SDK splits pure number formatting away from the encoding, exactly one file changes and no
22
+ * renderer notices.
23
+ */
24
+ export declare namespace CellEncoding {
25
+ /**
26
+ * How much formatting to apply before encoding.
27
+ */
28
+ const Mode: {
29
+ /**
30
+ * The cell as displayed — number format applied.
31
+ *
32
+ * @remarks
33
+ * `4%`, `2024-01-01`, `$1,234.57`. What a human reading the grid sees, and what a values
34
+ * read prints.
35
+ */
36
+ readonly Display: "display";
37
+ /**
38
+ * The cell as the formula bar shows it — full precision, number formatting stripped.
39
+ *
40
+ * @remarks
41
+ * `1234.5678` where {@link Mode.Display | display} shows `$1,234.57`. Dates stay dates
42
+ * rather than decaying to serials, so the result is still searchable rather than merely
43
+ * lossless.
44
+ */
45
+ readonly Value: "value";
46
+ };
47
+ type Mode = typeof Mode[keyof typeof Mode];
48
+ /**
49
+ * A cell's text in the two forms a read surface needs.
50
+ *
51
+ * @remarks
52
+ * They differ only for strings, and only by the `'` prefix — but that one difference is why
53
+ * anchored patterns work while a rendered result still tells a string from a number.
54
+ */
55
+ interface Encoded {
56
+ /**
57
+ * Undecorated — what a pattern is tested against.
58
+ *
59
+ * @remarks
60
+ * The prefix is an *output* device, serving type inference by a reader. A pattern is input.
61
+ * Carrying the prefix into matching would make `^Acme` silently fail and `^42$` match the
62
+ * number but not the string — inconsistencies an agent has no way to diagnose.
63
+ */
64
+ match: string;
65
+ /**
66
+ * Encoded — what a result reports.
67
+ *
68
+ * @remarks
69
+ * Strings carry the leading `'`; numbers, booleans and errors do not. That asymmetry *is*
70
+ * the type inference.
71
+ */
72
+ display: string;
73
+ }
74
+ }
75
+ /**
76
+ * Encodes a bare number the way a spreadsheet displays one.
77
+ *
78
+ * @remarks
79
+ * **A display contract, not formatting.** Where a cell has a number format, that format decides
80
+ * the text and this never runs. Where there is none — a raw {@link Scalar}, a computed
81
+ * aggregate, anything off the value layer — something still has to choose how many digits to
82
+ * print, and JavaScript's default choice is the wrong one: `String(2398.7999999999997)` spends
83
+ * 17 digits publishing the binary residue of `0.1 + 0.2`-class arithmetic. The float is
84
+ * *correct*; the rendering is unusable, because an agent comparing it against an expected
85
+ * `2398.8` sees a mismatch that is not there.
86
+ *
87
+ * Excel caps display at **15 significant digits** for exactly this reason, and the cap is the
88
+ * whole rule — it is not rounding for readability, it is the point past which the extra digits
89
+ * describe IEEE-754 rather than the value. Rounding to 15 and re-stringifying lets JavaScript
90
+ * pick the shortest form that survives the round trip, so `2398.8` prints as `2398.8` and a
91
+ * genuinely long number keeps every digit it has earned.
92
+ *
93
+ * Non-finite values pass through: `NaN` and `Infinity` are not precision questions, and
94
+ * `toPrecision` would only hand back their own string anyway.
95
+ *
96
+ * The exponent is respelled Excel's way for the same reason the digits are capped Excel's way —
97
+ * see {@link excelExponent}.
98
+ */
99
+ export declare function encodeNumber(value: number): string;
100
+ /**
101
+ * Encodes a number that came off a range carrying a number format — an aggregate, a bound, a
102
+ * value with no cell of its own to ask.
103
+ *
104
+ * @remarks
105
+ * **This is what stops a date column from reporting itself as an ID column.** A profile that
106
+ * prints `45293 … 46234` for a date series is not merely ugly: it is the wrong *type*, and a
107
+ * reader acts on it. The same rule fixes currency (`$1.20`) and percent (`42.37%`) for free,
108
+ * because there is only one rule — a range's own format decides how its numbers print, exactly
109
+ * as {@link CellEncoding.Mode.Display} decides it for a cell.
110
+ *
111
+ * `General` (or no format) falls through to {@link encodeNumber}, which is the correct answer
112
+ * for a derived value: a mean carries no format of its own, and Excel's 15-digit display cap is
113
+ * the only thing standing between the reader and the float's binary residue.
114
+ *
115
+ * It goes through the SDK's own {@link NumberFormat.getEngine | format engine} rather than a
116
+ * format library directly, and that is not incidental: a range's format is frequently a **named**
117
+ * preset (`Short Date`, `[$-F800]`) whose expansion is locale-dependent, and a raw pattern
118
+ * formatter renders `Short Date` as literal characters — `00ort 1at2024` where the grid shows
119
+ * `1/1/2024`. The engine is the only thing that knows the workbook's answer.
120
+ *
121
+ * The result is trimmed: alignment formats pad with `_)` and a trailing space is a cell-width
122
+ * device with no meaning inside a sentence. A format the engine cannot render degrades to the
123
+ * unformatted number — a report must not fail because one column has a broken format string.
124
+ */
125
+ export declare function encodeFormattedNumber(value: number, numberFormat?: string | null): string;
126
+ /**
127
+ * Encodes one cell for agent consumption.
128
+ *
129
+ * @returns `null` for a blank cell — blanks are elided by every read surface rather than
130
+ * rendered as empty, so there is nothing to encode.
131
+ */
132
+ export declare function encodeCell(cell: ICell, mode: CellEncoding.Mode): CellEncoding.Encoded | null;
133
+ /**
134
+ * Encodes one bare {@link Scalar} — a value with no cell behind it.
135
+ *
136
+ * @remarks
137
+ * The counterpart to {@link encodeCell} for the stateless value layer (`IRange`, `Scalar[][]`),
138
+ * where there is no cell to ask for text and therefore **no number format to apply**. That is
139
+ * the whole difference: `0.04` encodes as `0.04` here and as `4%` through a cell that formats
140
+ * it. There is consequently no `mode` — the two modes differ only by how much formatting they
141
+ * apply, and here there is none to strip.
142
+ *
143
+ * Everything above formatting is identical, because it is the same contract: the `'` prefix on
144
+ * strings, `TRUE`/`FALSE`, error labels, blank elision.
145
+ *
146
+ * @returns `null` for a blank value, matching {@link encodeCell}.
147
+ */
148
+ export declare function encodeScalar(value: Scalar): CellEncoding.Encoded | null;
149
+ //# sourceMappingURL=encodeCell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encodeCell.d.ts","sourceRoot":"","sources":["../../../../src/encode/encodeCell.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,KAAK,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAEnF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,yBAAiB,YAAY,CAAC;IAC5B;;OAEG;IACI,MAAM,IAAI;QACf;;;;;;WAMG;;QAEH;;;;;;;WAOG;;KAEK,CAAC;IACX,KAAY,IAAI,GAAG,OAAO,IAAI,CAAC,MAAM,OAAO,IAAI,CAAC,CAAC;IAElD;;;;;;OAMG;IACH,UAAiB,OAAO;QACtB;;;;;;;WAOG;QACH,KAAK,EAAE,MAAM,CAAC;QACd;;;;;;WAMG;QACH,OAAO,EAAE,MAAM,CAAC;KACjB;CACF;AAOD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGlD;AAyBD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CASzF;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,GAAG,YAAY,CAAC,OAAO,GAAG,IAAI,CAK5F;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC,OAAO,GAAG,IAAI,CAkBvE"}
@@ -0,0 +1,2 @@
1
+ export * from './encodeCell';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/encode/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC"}
@@ -0,0 +1,308 @@
1
+ /**
2
+ * The cell layers `grep` can match against.
3
+ *
4
+ * @remarks
5
+ * These are *not* `ICell.Content`. That enum also carries `formats`, `tables`, `merges` and
6
+ * `warnings`, which have no text to match — selection by attribute is the regions read, not grep.
7
+ *
8
+ * The rule, which predicts any future member:
9
+ * **a grep field is a layer whose text was authored by a person or is read by one.**
10
+ *
11
+ * `display`, `value` and `raw` are read; `formula`, `hyperlink` and `numberFormat` are authored.
12
+ * A layer that fails the rule fails it because its payload has no canonical text — a fill's
13
+ * "red" may be stored as `FF0000`, a theme slot, or an indexed palette entry, so any pattern
14
+ * against it silently matches less than it claims: a confident wrong answer, which is worse
15
+ * than a missing feature. Color wants *nearness*, not matching — that is selection by
16
+ * attribute, and it belongs to the regions read.
17
+ *
18
+ * Two layers are deliberately absent for the same reason:
19
+ * - `note` — `ICell.Content.Notes` is marked NOT IMPLEMENTED.
20
+ * - `comment` — `IComment.Properties.content` is `any` pending `IRichText.JSON`, so any text
21
+ * extractor written against it today would quietly miss the shapes it did not anticipate.
22
+ *
23
+ * Both are additive once the SDK shapes settle.
24
+ */
25
+ export type GrepField =
26
+ /**
27
+ * The cell as displayed — number format applied.
28
+ *
29
+ * `4%`, `2024-01-01`, `$1,234.57`, `TRUE`, `#N/A`, `hello`.
30
+ *
31
+ * Not named `text`: that reads as "cells containing text", and there is no longer an SDK
32
+ * method of that name to be consistent with. `display` and {@link GrepField | value} name what
33
+ * they are and pair without explanation.
34
+ *
35
+ * Runs through the shared encoder, which is the point: whatever text a values read printed,
36
+ * grep finds, because one encoder produced both. A second display path would fail on exactly
37
+ * the strings an agent copied out of the previous tool call.
38
+ */
39
+ 'display'
40
+ /**
41
+ * The cell as the formula bar shows it — most formatting stripped, **category kept**.
42
+ *
43
+ * `1234.5678` where {@link GrepField | display} shows `$1,234.57` — but `40%` stays `40%`
44
+ * and dates stay dates, because the formula bar keeps minimal formatting for percents,
45
+ * dates and times (Excel's behavior, faithfully). This is *not* the underlying scalar:
46
+ * a percent cell storing `0.4` reads `40%` here. The stored scalar is
47
+ * {@link GrepField | raw}.
48
+ *
49
+ * Identical to `display` for every cell whose format only decorates (`General`, plain
50
+ * text) — the default search dedupes that case per cell rather than reporting both.
51
+ */
52
+ | 'value'
53
+ /**
54
+ * The stored scalar, encoded bare — what the stateless value layer prints.
55
+ *
56
+ * `0.4` where {@link GrepField | value} shows `40%`; dates as serial numbers. This is the
57
+ * layer `IRange` / stats reads print (they have no cell to format through), so it is the
58
+ * field that makes *those* printed values greppable — the round-trip that `display`
59
+ * provides for formatted reads. Not a default: serials and unrounded floats are noise
60
+ * until they are the question.
61
+ */
62
+ | 'raw'
63
+ /** Formula text, A1 style (`=SUM(A1:A10)`). Cells without a formula contribute nothing. */
64
+ | 'formula'
65
+ /** Hyperlink target — the address, not the display text (which is already `display`). */
66
+ | 'hyperlink'
67
+ /**
68
+ * The number format code — `0.00%`, `$#,##0.00`, `mm/dd/yyyy`.
69
+ *
70
+ * Authored text (it is literally what was typed into Format Cells), canonical, and regex
71
+ * is its native matcher. `--fields numberFormat "%"` is the well-posed form of "which
72
+ * cells are percentages" — the rendered `40%` is not. Matches cells with a *direct*
73
+ * format, including value-less ones (a formatted-but-empty column is a real finding).
74
+ */
75
+ | 'numberFormat';
76
+ export declare const GrepField: {
77
+ readonly Display: "display";
78
+ readonly Value: "value";
79
+ readonly Raw: "raw";
80
+ readonly Formula: "formula";
81
+ readonly Hyperlink: "hyperlink";
82
+ readonly NumberFormat: "numberFormat";
83
+ };
84
+ /** Every field, in the order they are searched and reported. */
85
+ export declare const GREP_FIELDS: readonly GrepField[];
86
+ /**
87
+ * The default field set.
88
+ *
89
+ * @remarks
90
+ * What you can see, what the formula bar shows, and what is structurally behind both.
91
+ * `value` is a default *because* the search dedupes it: for the majority of cells it is
92
+ * byte-identical to `display` and is suppressed per cell, so it only surfaces where it
93
+ * carries new information — `1234.5678` behind `$1,234.57`. A duplicate hit costs an agent
94
+ * a second look for no new information; a missing layer costs a silent zero-hit miss on
95
+ * full-precision searches, which is worse.
96
+ */
97
+ export declare const GREP_FIELDS_DEFAULT: readonly GrepField[];
98
+ /** What a grep result should carry. */
99
+ export type GrepOutput =
100
+ /** Address, field and the matched text. */
101
+ 'content'
102
+ /** Addresses only, one per matched cell. */
103
+ | 'addresses'
104
+ /** Counts only, reported per sheet — `rg -c`. */
105
+ | 'count'
106
+ /** Names of sheets with at least one match — `rg -l`. */
107
+ | 'sheets';
108
+ /**
109
+ * How {@link GrepArgs.context} resolves the block a match sits in.
110
+ */
111
+ export type GrepContext =
112
+ /**
113
+ * The uniform contentful block containing the match (Excel `CurrentRegion` semantics).
114
+ * When that block sits inside a table, the table's name is carried too — the name is the
115
+ * better answer and costs one lookup.
116
+ */
117
+ 'contentful'
118
+ /** The enclosing *table* only. Matches outside any table carry no context. */
119
+ | 'table';
120
+ /**
121
+ * Arguments to {@link grep}.
122
+ *
123
+ * @remarks
124
+ * Shaped after ripgrep rather than after anything novel — args, defaults and vocabulary are
125
+ * already pretrained, and every novel idiom is paid for in error loops.
126
+ */
127
+ export interface GrepArgs {
128
+ /**
129
+ * The pattern to search for — a regular expression, as in every grep.
130
+ *
131
+ * @remarks
132
+ * Full JS `RegExp` semantics (lookaround and backreferences work — more than rg's default
133
+ * engine). Literal search is {@link GrepArgs.fixedStrings}.
134
+ */
135
+ pattern: string;
136
+ /**
137
+ * Which cell layers to search.
138
+ *
139
+ * @defaultValue {@link GREP_FIELDS_DEFAULT} — `['display', 'value', 'formula']`
140
+ */
141
+ fields?: readonly GrepField[];
142
+ /**
143
+ * Treat `pattern` as a literal string — `rg -F`.
144
+ *
145
+ * @defaultValue false — **the pattern is a regex by default**, because that is what the name
146
+ * `grep` means everywhere an agent learned it (POSIX grep and rg both default to regex). A
147
+ * wildcard default was tried and rejected: agents type `\d+` by reflex, wildcards literalize
148
+ * it, and the result is a silent zero-hit miss. Excel's `?`/`*` wildcards live in the UI find
149
+ * dialog, where Excel users live.
150
+ */
151
+ fixedStrings?: boolean;
152
+ /**
153
+ * Case-insensitive matching.
154
+ *
155
+ * @defaultValue false — case-sensitive, as `rg` is. Note this inverts the SDK's `matchCase`.
156
+ */
157
+ ignoreCase?: boolean;
158
+ /**
159
+ * Require the match to fall on word boundaries.
160
+ *
161
+ * @remarks
162
+ * Boundaries are grep's, not `\b`'s: a pattern that starts or ends on a non-word character
163
+ * (`$1,234`, `4%`, `#N/A` — spreadsheet text is full of them) still matches at text edges,
164
+ * exactly as `rg -w` treats line edges. Implemented as `(?<!\w)…(?!\w)`, which coincides
165
+ * with `\b` for word-bounded patterns and stays correct for the rest.
166
+ */
167
+ word?: boolean;
168
+ /**
169
+ * Invert the match — report cells where **no** requested field matched (`rg -v`).
170
+ *
171
+ * @remarks
172
+ * Scoped to cells grep visits: a cell must have text in at least one requested field to be
173
+ * reported (an empty cell is not a finding, and "every blank cell" is not an answer).
174
+ * Reported rows carry the first requested field that has text, as the evidence line.
175
+ */
176
+ invert?: boolean;
177
+ /**
178
+ * Where to search: a sheet name (globs allowed — `Q*`), a sheet-qualified range
179
+ * (`Sheet1!A1:D9`), or a bare range applied to **every** sheet.
180
+ *
181
+ * @defaultValue every sheet's used range.
182
+ *
183
+ * @remarks
184
+ * Resolution order is fixed and documented rather than sniffed: a `!` splits sheet from
185
+ * range; otherwise an exact sheet-name match wins; otherwise a glob (`*`/`?`) matches sheet
186
+ * names; otherwise it is a range on **every sheet**. A bare range cannot resolve against an
187
+ * "active sheet" — a stateless invocation has none, and inventing one would make the same
188
+ * command mean different things in different surfaces.
189
+ *
190
+ * Naming a hidden sheet (exactly or via a glob-free match) searches it — an explicit name
191
+ * is an explicit request, the same way `rg` searches a hidden file you name.
192
+ */
193
+ scope?: string;
194
+ /**
195
+ * Search hidden rows, columns and hidden sheets — `rg --hidden`.
196
+ *
197
+ * @defaultValue false — hidden content is **excluded**, the `.gitignore` analogy: the user
198
+ * has already declared they are not looking at these. Exclusion is structural (hidden rows
199
+ * are never visited), never silent — the header's scope line reflects what was searched.
200
+ */
201
+ hidden?: boolean;
202
+ /**
203
+ * Stop after this many matching cells. Truncation is always reported, never silent.
204
+ *
205
+ * @defaultValue 200 — a grep result returns into a context window, not a terminal stream,
206
+ * so unbounded output is a cost the caller did not ask for. `0` removes the cap.
207
+ *
208
+ * @remarks
209
+ * Counts **cells**, not match rows — a cell matching in two fields is one unit of budget.
210
+ * The search looks one cell past the cap, so a result that ends exactly at `maxCount` is
211
+ * only reported truncated when a further match actually exists.
212
+ */
213
+ maxCount?: number;
214
+ /**
215
+ * Annotate each match with the block it sits in, and group the listing by block — the 2-D
216
+ * answer to `rg -C`.
217
+ *
218
+ * @remarks
219
+ * ±N lines is meaningless in a grid; the question context answers is "what is this thing
220
+ * part of?", and the honest unit for that is the uniform region containing the match — see
221
+ * {@link GrepContext}. `true` means `'contentful'`. A numeric value is rejected rather than
222
+ * reinterpreted: `-C 3` means something else in every other grep, and accepting it while
223
+ * meaning "enclosing block" would be a silent divergence.
224
+ */
225
+ context?: boolean | GrepContext;
226
+ /**
227
+ * @defaultValue 'content'
228
+ */
229
+ output?: GrepOutput;
230
+ }
231
+ /** The block a match sits in — present when {@link GrepArgs.context} was requested. */
232
+ export interface GrepMatchContext {
233
+ /** Sheet-qualified address of the enclosing block, e.g. `Sales!A1:D9`. */
234
+ range: string;
235
+ /** The enclosing table's name, when the match is inside one. */
236
+ table?: string;
237
+ }
238
+ /**
239
+ * One match. **Grep's unit is the cell** — one entry per matched `(cell, field)`, in reading
240
+ * order.
241
+ *
242
+ * @remarks
243
+ * Deliberately not coalesced into blocks: uniform runs of identical values are *regions* — a
244
+ * payload feature splits where the value changes, so the regions read already owns that shape,
245
+ * in 2-D and with the full partition to rank against. Grep answering cell-grain and regions
246
+ * answering block-grain is the family split (§6.1). {@link GrepArgs.context} does not move
247
+ * that line: the unit stays the cell; the region is carried as an annotation on it, and the
248
+ * renderer merely groups by it.
249
+ */
250
+ export interface GrepMatch {
251
+ /** Sheet name. */
252
+ sheet: string;
253
+ /** A1 cell address within the sheet. */
254
+ address: string;
255
+ /**
256
+ * Which layer matched.
257
+ *
258
+ * @remarks
259
+ * Load-bearing, not decoration. Searching several fields at once, a bare address is unusable —
260
+ * the agent cannot tell whether `2024` matched a date's display, a formula referencing row
261
+ * 2024, or a hyperlink. `rg` prints the matching line; this is the analog.
262
+ */
263
+ field: GrepField;
264
+ /** The full text of the matched layer. */
265
+ text: string;
266
+ /** The enclosing block, when {@link GrepArgs.context} was requested and one exists. */
267
+ context?: GrepMatchContext;
268
+ }
269
+ /** Per-sheet match accounting — the unit `rg -c` and `rg -l` report at. */
270
+ export interface GrepSheetMatches {
271
+ /** Sheet name. */
272
+ sheet: string;
273
+ /** Distinct cells that produced at least one match in this sheet. */
274
+ cells: number;
275
+ }
276
+ /** The result of a {@link grep}. */
277
+ export interface GrepResult {
278
+ /** Echoed back so a rendering carries its own scope. */
279
+ pattern: string;
280
+ fields: readonly GrepField[];
281
+ /** Resolved human-readable scope, e.g. `Sheet1!A1:D847` or `workbook`. */
282
+ scope: string;
283
+ matches: readonly GrepMatch[];
284
+ /** Distinct cells that produced at least one match. */
285
+ cellCount: number;
286
+ /** Per-sheet counts, in search order — only sheets with at least one match appear. */
287
+ sheets: readonly GrepSheetMatches[];
288
+ /**
289
+ * Sheets that were actually entered by the search.
290
+ *
291
+ * @remarks
292
+ * When {@link GrepArgs.maxCount} cuts the search short, sheets never entered are not
293
+ * counted — "searched" is a claim, and it is only made about work that happened.
294
+ */
295
+ sheetsSearched: number;
296
+ /** Sheets that produced at least one match. */
297
+ sheetsMatched: number;
298
+ /**
299
+ * True when {@link GrepArgs.maxCount} cut the search short — a further matching cell was
300
+ * actually found past the cap, never inferred from the count alone.
301
+ *
302
+ * @remarks
303
+ * Elision is explicit and never silent, so the renderer must surface this.
304
+ */
305
+ truncated: boolean;
306
+ output: GrepOutput;
307
+ }
308
+ //# sourceMappingURL=GrepTypes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GrepTypes.d.ts","sourceRoot":"","sources":["../../../../src/grep/GrepTypes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { IWorkbook } from '@sheetxl/sdk';
2
+ import { GrepArgs, GrepResult } from './GrepTypes';
3
+ /**
4
+ * Searches a workbook's cell contents by pattern.
5
+ *
6
+ * @remarks
7
+ * Deliberately shaped after ripgrep — args, defaults and vocabulary are pretrained, and every
8
+ * novel idiom is paid for in error loops.
9
+ *
10
+ * Hidden rows, columns and sheets are excluded by default (the `.gitignore` analogy — the user
11
+ * has already declared they are not looking at these); `hidden` includes them, and naming a
12
+ * hidden sheet in `scope` searches it.
13
+ */
14
+ export declare function grep(workbook: IWorkbook, args: GrepArgs): Promise<GrepResult>;
15
+ //# sourceMappingURL=grep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../../../src/grep/grep.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA6C,SAAS,EAAE,MAAM,cAAc,CAAC;AAIzF,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AA+PrB;;;;;;;;;;GAUG;AACH,wBAAsB,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CA+GnF"}