@matheos/cli 0.0.0-stage → 0.2.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.
package/README.md CHANGED
@@ -1,3 +1,22 @@
1
- # Temporary Holding Version
1
+ # @matheos/cli
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Command line for [Matheos](https://matheos.fly.dev) `.mth` calculation documents: check them,
4
+ render them to HTML or PDF, print the authoring guide for an agent.
5
+
6
+ ```sh
7
+ npm install -g @matheos/cli
8
+
9
+ matheos check beam.mth # errors, failed checks, exit code 0/1/2/3
10
+ matheos check --json beam.mth # the same as JSON, for agents
11
+ matheos render beam.mth # beam.pdf next to it (needs a Chrome; see below)
12
+ matheos render beam.mth -o out/ # HTML or PDF by the -o extension, a folder for many files
13
+ matheos guide # SKILL.md: the grammar, units, checks, the mistakes to avoid
14
+ matheos calc "q = 25 kN/m" "L = 6 m" "M = q L^2 / 8 to kNm" # quick sums; no arguments: a prompt
15
+ ```
16
+
17
+ Rendering uses an installed Chrome or Edge, the `MATHEOS_CHROME` path, or a Chromium that
18
+ `matheos install-chrome` downloads once into the puppeteer cache.
19
+
20
+ How to work on `.mth` files with Claude or another agent:
21
+ [Working on .mth calculations with Claude](https://github.com/Suharevillya/matheos-issues/blob/main/USING-CLAUDE.md).
22
+ Bugs and feature requests: <https://github.com/Suharevillya/matheos-issues/issues>.
package/SKILL.md ADDED
@@ -0,0 +1,165 @@
1
+ ---
2
+ name: matheos-authoring
3
+ description: Write and verify Matheos `.mth` calculation documents (Markdown prose + unit-aware math blocks for structural engineering checks). Use when asked to produce a calculation, a Eurocode check, or a report in Matheos format, or to fix a `.mth` file that `matheos check` rejects.
4
+ ---
5
+
6
+ # Writing Matheos documents
7
+
8
+ A `.mth` file is CommonMark with YAML front matter and fenced `math` blocks. CommonMark is the
9
+ standard flavour of Markdown: `#` headings, paragraphs, lists, GFM tables, and fenced code
10
+ blocks between lines of three backticks; a fence tagged `math` is a calculation block. YAML front
11
+ matter is the block between two `---` lines at the top, one `key: value` per line, holding the
12
+ title, author and other metadata of the report. Statements run top to bottom; every derived statement prints formula, substituted values and result; every `check`
13
+ prints a verdict and the utilization η. Start from the closest file in
14
+ `examples/` (https://github.com/Suharevillya/matheos/tree/main/examples); `steel-beam.mth` is
15
+ the canonical template.
16
+
17
+ ## 1. Front matter
18
+
19
+ ```yaml
20
+ ---
21
+ title: Simply supported floor beam
22
+ project: Example building, axis B
23
+ author: Name
24
+ date: 2026-10-15
25
+ revision: A
26
+ code: EN 1993-1-1 + Finnish NA
27
+ ---
28
+ ```
29
+
30
+ Optional: `logo: file.png`, `logo_width: 40` (mm), `digits: 4`.
31
+
32
+ ## 2. Statements, one per line inside ```` ```math ```` fences
33
+
34
+ | Form | Example | Prints |
35
+ |---|---|---|
36
+ | input | `L = 6.0 m # span` | `L = 6.0 m` + caption |
37
+ | derived | `M_Ed = q_Ed * L^2 / 8` | formula = substituted = result |
38
+ | bare expression | `c_f / t_f` | the three stages, no name |
39
+ | check | `check M_Ed <= M_c_Rd` | both sides with values, ✓/✗, η |
40
+ | conditional | `if c_f / t_f <= 9 eps` … `else if` … `else` … `end` | taken branch only, after its condition |
41
+ | comment | `# own line` or trailing `# caption` | nothing / right-aligned caption |
42
+ | parameter | `L = 6.0 m ?`, `curve = "b" ? ["a", "b", "c"]` | as an input; a form field (text, or radio buttons for the choices) in the editor |
43
+
44
+ An input is a literal number with an optional unit. Anything else is derived. `check` needs the
45
+ keyword; a bare comparison is just a boolean. Rebinding a name is allowed; last wins.
46
+
47
+ ## 3. Identifiers
48
+
49
+ `[A-Za-z_][A-Za-z0-9_]*`. First `_` opens a subscript, later `_` become commas:
50
+ `W_pl_y` → W_{pl,y}, `M_c_Rd` → M_{c,Rd}. Spelled Greek renders as the letter:
51
+ `gamma_M0`, `alpha_cc`, `eps`, `lambda`, `eta`, `phi`, `delta`, `sigma`. Trailing `'` is a prime.
52
+ An accent right after a Greek base decorates it: `lambda_bar_y` → λ̄_y (`_bar`, `_hat`,
53
+ `_tilde`); a Latin `d_bar` keeps "bar" as its subscript.
54
+
55
+ ## 4. Units
56
+
57
+ Write the unit after the number: `25 kN/m`, `355 MPa`, `8356e4 mm^4`, `60 kNm/m`. Available:
58
+ `mm cm m km`, `g kg t`, `s`, `N kN MN`, `Nm kNm MNm`, `Pa kPa MPa GPa`, `rad deg`, `K`,
59
+ `J kJ W kW`, and compounds with `^`, `*`, `/` (`kN/m^2`, `N/mm^2`). Units combine through
60
+ arithmetic; a result prints in a sensible default (mm, kN, kN·m, kN/m, MPa) unless you end the
61
+ statement with `to <unit>`: `M_c_Rd = W_pl_y * f_y / gamma_M0 to kNm`. `to` never changes the
62
+ stored value. A bound name wins over a unit of the same spelling (`t = 10 mm` makes `t` a
63
+ variable from then on). Adding a number to a quantity, or comparing them, is an error.
64
+
65
+ Engineering guidance: SI inputs with a unit on every literal. `to` on every resistance so the
66
+ report reads in kN and kN·m. A `check` for every demand/capacity pair. Captions carry clause
67
+ numbers (`# (6.13)`). Prose explains; math computes.
68
+
69
+ Multiplication style: implicit is the norm (`q L^2 / 8`, `W_pl_y f_y`). Write `*` when the next
70
+ factor is a bracket or a call after `/`: `a / b * (c + d)`, `M / W * f(x)`, because `a / b (c + d)`
71
+ is a/(b·(c + d)) (implicit multiplication binds tighter than `/`; the checker warns). A bound
72
+ name before a bracket multiplies (`a (b + c)`); inside `simplify`, `derivative`, `integrate`
73
+ and `solve` the free variable does too (`x (L - x)`).
74
+
75
+ ## 5. Checks and η
76
+
77
+ `check <expr> <op> <expr>` with `<=`, `>=`, `<`, `>`, `==`, `!=`. η = left / right (right / left for
78
+ `>=` and `>`). Text values compare as text: `curve = "b"`, `alpha = curve == "b" ? 0.34 : 0.49`,
79
+ `check curve == "b"` (verdict, no η). `not a` negates a boolean. Write one check per demand/capacity pair. `check a <= b warn 80%` keeps the
80
+ fail line at 100 % but flags a pass above 80 % with a yellow badge. A range is one line:
81
+ `check 0.25 <= beta <= 1`. A ternary may sit inside a check when bracketed. In prose,
82
+ `{U to %}` shows a value in a display unit. `check a <= b if cond` applies only when `cond`
83
+ holds (n/a badge otherwise). A failure mode that does not apply is `na`: `N_ps = beta <= 0.85
84
+ ? … : na`; `min(…)` skips it and a check against it reads n/a. `solve(expr, x, lo, hi)` finds
85
+ the root of `expr = 0` by bisection (units carried) where a spreadsheet would goal-seek. A
86
+ moment per length shows with `to kNm/m`.
87
+
88
+ ## 6. Conditionals
89
+
90
+ ```
91
+ if c_f / t_f <= 9 eps
92
+ cls = 1
93
+ else if c_f / t_f <= 10 eps
94
+ cls = 2
95
+ else
96
+ cls = 3
97
+ end
98
+ ```
99
+
100
+ Conditions are comparisons, optionally joined with `and`, `or`, `not`. Only inside math blocks.
101
+
102
+ ## 7. Inline values in prose
103
+
104
+ `{cls}` prints the value, `{M_Ed / M_c_Rd}` a computed ratio, `{F_v_Ed =}` prints `F_v,Ed = 50 kN`.
105
+
106
+ ## 8. Modifiers and block options
107
+
108
+ Trailing `;` evaluates silently, trailing `:` prints the result line only. Fence options:
109
+ ```` ```math hide ```` (evaluate, print nothing), ```` ```math results ```` (result lines only).
110
+
111
+ ## 9. Vectors, tables, drawings, plots
112
+
113
+ - Vectors: `lx = [5400, 5400, 200] mm`, element-wise `.*` `./` `.^`, `lx[2]`, slices
114
+ `x[2:5]`, `sum`, `max`, `mean`, `median`, `std`, `dot`, `lusolve(K, F)` (returns a column: `z[3, 1]`). Keep a matrix
115
+ homogeneous: `[0 kN, 0 kN, P]`. `sqrt`, `abs`, `exp`, `log`, `sin`/`cos`/`tan`/`sinh`/`cosh`/`tanh` (of `deg` quantities too), `min`, `max`, `pi` exist; the one-argument ones map over vectors. `pi (d - t)` is a product.
116
+ - `a (b + c)` multiplies when `a` is a variable; `f(x)` calls a function.
117
+ - `cond ? a : b` prints as cases; `U = N_Ed / N_Rd to %` shows a percentage.
118
+ - Tables: GFM Markdown tables with `{expr}` in cells. Images: `![alt](file.svg)` next to the
119
+ document. Raw `<svg>` in prose passes through, with `{(x[1] - lx[1]/2) / s}` substituted as a
120
+ plain number (divide by `1 mm` for a bare number).
121
+ - Plots: a ```` ```plot ```` fence with `title:`, `x = 0 .. 2` (or `0 m .. 6 m`), `xlabel:`,
122
+ `ylabel:`, one expression in `x` per line (`M(x)`, `2 - 2 x`), `(1, 0.5)` points; the
123
+ trailing `#` comment is the legend entry.
124
+ - Includes: front matter `include: helpers.mth` (or a list) binds another document's variables
125
+ and functions before the first block, printing nothing. Resolved next to the document (CLI),
126
+ by document name in the web library, or through `resolve` when embedded.
127
+ - Catalogues: front matter `catalogs: { IPE: { file: IPE-props_EC3UK.json, units: { H: mm,
128
+ Wply: cm^3 } } }`, then `sec = IPE["IPE 300"]` and `W_pl_y = sec.Wply`. Do not name the row
129
+ variable `s`, `m` or another unit. The file sits next to the document (CLI); the web app
130
+ bundles the IPE and HE tables.
131
+ - `integrate(q x, x, 0 m, L)` (numeric, units carried), `derivative(q x L/2 - q x^2/2, x)` and
132
+ `simplify(expr)` (symbolic, print only).
133
+
134
+ ![integrate with units, derivative and simplify printed symbolically](img/calculus.png)
135
+
136
+ - Conditional prose: ```` ```if U > 0.8 ```` … ```` ``` ```` shows the Markdown inside only
137
+ when true; write a second fence for the other case.
138
+ - A parameter is an input ending in `?`: `L = 6.0 m ?`; a catalogue pick may carry it too
139
+ (`sec = SHS["180X180X6"] ?`). The editor lists these as a form. A list after the `?` gives
140
+ the choices, shown as radio buttons; the value before the `?` is the current one, and the
141
+ document reads it like any other value:
142
+
143
+ ```
144
+ reinf = "none" ? ["multiple", "single", "none"] # shear reinforcement
145
+ n_b = 2 ? [1, 2, 3] # bars per layer
146
+ k_reinf = reinf == "none" ? 1.0 : 1.5
147
+ ```
148
+
149
+ Choices are literals: quoted text, numbers, or quantities (`t = 6 mm ? [5 mm, 6 mm, 8 mm]`).
150
+ Use a choice wherever a spreadsheet would have a drop-down: buckling curve, exposure class,
151
+ bolt grade, "yes"/"no" switches that an `if` or a ternary then reads.
152
+ - Loops in math: `for e = 1 : n_E` … `end`, nestable, `K[i, j] = K[i, j] + k` updates one
153
+ element; end body lines with `;` to print only what matters. Loops in prose: a
154
+ ```````for i = 1 : n```` fence right after a table header line gives one row per `i`
155
+ (`| {i} | {F[i]} |`); inside `<svg>` it gives one element per `i`. The variable is
156
+ substituted only inside `{…}`.
157
+
158
+ ![A table with one row per wall from a for fence](img/table.png)
159
+
160
+ ![An SVG plan drawn from the vectors, one element per wall](img/drawing.png)
161
+
162
+ ![A plot fence: the bending moment of a beam](img/plot.png)
163
+ - A long matrix may continue on the next lines while a bracket is open; the result prints
164
+ after the last line. A vector with one unit prints it once: `[5.6 0.0066] kN/mm`. Lines wider than the page
165
+ shrink to fit; keep huge matrices silent (`K = zeros(15, 15);`) and show them as tables.
@@ -0,0 +1,2 @@
1
+ /** `<style>` markup with KaTeX, Figtree 400/600/700 and JetBrains Mono 400/600 embedded. */
2
+ export declare function inlineHead(): string;
package/dist/assets.js ADDED
@@ -0,0 +1,34 @@
1
+ // Inlined KaTeX CSS and fonts for a self-contained report, docs/spec/cli.md (HTML).
2
+ import { readFileSync } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
4
+ import { createRequire } from 'node:module';
5
+ const require = createRequire(import.meta.url);
6
+ const pkgDir = (name) => dirname(require.resolve(`${name}/package.json`));
7
+ /** Rewrite `url(...)` references in a CSS file to data URIs; keep woff2 only. */
8
+ function inlineCss(cssPath) {
9
+ const base = dirname(cssPath);
10
+ const css = readFileSync(cssPath, 'utf8');
11
+ return css
12
+ .replace(/src:\s*([^;]+);/g, (_, srcs) => {
13
+ const woff2 = srcs.split(',').map((s) => s.trim()).find((s) => s.includes('.woff2'));
14
+ return `src: ${woff2 ?? srcs};`;
15
+ })
16
+ .replace(/url\((['"]?)([^'")]+\.woff2)\1\)/g, (_, _q, rel) => {
17
+ const data = readFileSync(join(base, rel)).toString('base64');
18
+ return `url(data:font/woff2;base64,${data})`;
19
+ });
20
+ }
21
+ let cached;
22
+ /** `<style>` markup with KaTeX, Figtree 400/600/700 and JetBrains Mono 400/600 embedded. */
23
+ export function inlineHead() {
24
+ if (cached)
25
+ return cached;
26
+ const parts = [
27
+ inlineCss(join(pkgDir('katex'), 'dist', 'katex.min.css')),
28
+ ...['400', '600', '700'].map((w) => inlineCss(join(pkgDir('@fontsource/figtree'), `${w}.css`))),
29
+ ...['400', '600'].map((w) => inlineCss(join(pkgDir('@fontsource/jetbrains-mono'), `${w}.css`))),
30
+ ];
31
+ cached = `<style>${parts.join('\n')}</style>`;
32
+ return cached;
33
+ }
34
+ //# sourceMappingURL=assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.js","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,eAAe,CAAC,CAAC,CAAC;AAElF,iFAAiF;AACjF,SAAS,SAAS,CAAC,OAAe;IAChC,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1C,OAAO,GAAG;SACP,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC,EAAE,IAAY,EAAE,EAAE;QAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QACrF,OAAO,QAAQ,KAAK,IAAI,IAAI,GAAG,CAAC;IAClC,CAAC,CAAC;SACD,OAAO,CAAC,mCAAmC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,GAAW,EAAE,EAAE;QACnE,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC9D,OAAO,8BAA8B,IAAI,GAAG,CAAC;IAC/C,CAAC,CAAC,CAAC;AACP,CAAC;AAED,IAAI,MAA0B,CAAC;AAE/B,4FAA4F;AAC5F,MAAM,UAAU,UAAU;IACxB,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,KAAK,GAAG;QACZ,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;QACzD,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/F,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,4BAA4B,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;KAChG,CAAC;IACF,MAAM,GAAG,UAAU,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;IAC9C,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,10 @@
1
+ export declare const CACHE_DIR: string;
2
+ export interface Chrome {
3
+ path: string;
4
+ shell: boolean;
5
+ source: 'flag' | 'env' | 'cache' | 'system';
6
+ }
7
+ /** Order: --chrome flag, MATHEOS_CHROME, the matheos cache, a system Chrome or Edge. */
8
+ export declare function findChrome(flag?: string): Chrome | undefined;
9
+ /** Download chrome-headless-shell (stable) into the cache; returns its path. */
10
+ export declare function installChrome(log?: (s: string) => void): Promise<Chrome>;
package/dist/chrome.js ADDED
@@ -0,0 +1,47 @@
1
+ // Chromium lookup and download, docs/spec/cli.md (Chromium).
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { Browser, computeExecutablePath, detectBrowserPlatform, install, resolveBuildId } from '@puppeteer/browsers';
6
+ export const CACHE_DIR = join(homedir(), '.cache', 'matheos');
7
+ const STAMP = join(CACHE_DIR, 'chrome-headless-shell.json');
8
+ const SYSTEM = process.platform === 'win32'
9
+ ? [
10
+ 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
11
+ 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
12
+ join(process.env.LOCALAPPDATA ?? '', 'Google\\Chrome\\Application\\chrome.exe'),
13
+ 'C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe',
14
+ 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
15
+ ]
16
+ : process.platform === 'darwin'
17
+ ? ['/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge']
18
+ : ['/usr/bin/google-chrome', '/usr/bin/google-chrome-stable', '/usr/bin/chromium', '/usr/bin/chromium-browser', '/usr/bin/microsoft-edge'];
19
+ /** Order: --chrome flag, MATHEOS_CHROME, the matheos cache, a system Chrome or Edge. */
20
+ export function findChrome(flag) {
21
+ if (flag)
22
+ return { path: flag, shell: /headless-shell/i.test(flag), source: 'flag' };
23
+ const env = process.env.MATHEOS_CHROME;
24
+ if (env)
25
+ return { path: env, shell: /headless-shell/i.test(env), source: 'env' };
26
+ if (existsSync(STAMP)) {
27
+ const { buildId } = JSON.parse(readFileSync(STAMP, 'utf8'));
28
+ const path = computeExecutablePath({ browser: Browser.CHROMEHEADLESSSHELL, buildId, cacheDir: CACHE_DIR });
29
+ if (existsSync(path))
30
+ return { path, shell: true, source: 'cache' };
31
+ }
32
+ const sys = SYSTEM.find((p) => p && existsSync(p));
33
+ return sys ? { path: sys, shell: false, source: 'system' } : undefined;
34
+ }
35
+ /** Download chrome-headless-shell (stable) into the cache; returns its path. */
36
+ export async function installChrome(log = () => { }) {
37
+ const platform = detectBrowserPlatform();
38
+ if (!platform)
39
+ throw new Error('unsupported platform for chrome-headless-shell');
40
+ const buildId = await resolveBuildId(Browser.CHROMEHEADLESSSHELL, platform, 'stable');
41
+ log(`downloading chrome-headless-shell ${buildId} to ${CACHE_DIR} (about 100 MB, once)`);
42
+ mkdirSync(CACHE_DIR, { recursive: true });
43
+ const installed = await install({ browser: Browser.CHROMEHEADLESSSHELL, buildId, cacheDir: CACHE_DIR });
44
+ writeFileSync(STAMP, JSON.stringify({ buildId }));
45
+ return { path: installed.executablePath, shell: true, source: 'cache' };
46
+ }
47
+ //# sourceMappingURL=chrome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chrome.js","sourceRoot":"","sources":["../src/chrome.ts"],"names":[],"mappings":"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"}
package/dist/main.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ export declare const EXIT: {
3
+ readonly ok: 0;
4
+ readonly errors: 1;
5
+ readonly failed: 2;
6
+ readonly usage: 3;
7
+ };
package/dist/main.js ADDED
@@ -0,0 +1,196 @@
1
+ #!/usr/bin/env node
2
+ // matheos CLI, docs/spec/cli.md. Commands: check, render, calc, install-chrome, guide.
3
+ import { readFileSync, writeFileSync, existsSync, statSync } from 'node:fs';
4
+ import { createInterface } from 'node:readline';
5
+ import { basename, dirname, extname, join, resolve } from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+ import { parse, evaluate, toHtml, plainText, statements } from '@matheos/core';
8
+ import { inlineHead } from './assets.js';
9
+ import { findChrome, installChrome } from './chrome.js';
10
+ import { renderPdf } from './pdf.js';
11
+ const USAGE = `usage:
12
+ matheos check <file.mth>... [--json]
13
+ matheos render <file.mth>... [-o <out.pdf|out.html|dir>] [--chrome <path>]
14
+ matheos calc [statement]... one statement per argument or stdin line; no arguments on a terminal: a prompt
15
+ matheos install-chrome
16
+ matheos guide`;
17
+ export const EXIT = { ok: 0, errors: 1, failed: 2, usage: 3 };
18
+ function load(file) {
19
+ // catalogue tables and included documents resolve next to the document, then in a `catalogs/` folder beside it or
20
+ // one level up (the template library's layout); `.mth` comes back as text, anything else parsed as JSON
21
+ const resolveFile = (p) => {
22
+ for (const dir of ['.', 'catalogs', join('..', 'catalogs')]) {
23
+ try {
24
+ const t = readFileSync(resolve(dirname(file), dir, p), 'utf8');
25
+ return p.endsWith('.mth') ? t : JSON.parse(t);
26
+ }
27
+ catch { /* next */ }
28
+ }
29
+ return undefined;
30
+ };
31
+ return evaluate(parse(readFileSync(file, 'utf8')), { resolve: resolveFile });
32
+ }
33
+ function findings(file, r) {
34
+ const checks = statements(r).filter((i) => i.kind === 'check');
35
+ const values = {};
36
+ for (const [k, v] of r.scope)
37
+ values[k] = typeof v === 'object' && v !== null && 'toString' in v ? String(v) : v;
38
+ return {
39
+ file,
40
+ errors: r.errors.map((e) => ({ message: e.message, line: e.pos.start.line, column: e.pos.start.column })),
41
+ checks: checks.map((c) => ({ line: c.pos.start.line, latex: c.latex, verdict: c.verdict ?? false, eta: Number(c.eta), ...(c.na && { na: true }) })),
42
+ warnings: statements(r).filter((i) => i.warning).map((i) => ({ line: i.pos.start.line, message: i.warning })),
43
+ values,
44
+ };
45
+ }
46
+ const codeOf = (r) => {
47
+ if (r.errors.length)
48
+ return EXIT.errors;
49
+ const failed = statements(r).some((i) => i.kind === 'check' && !i.verdict);
50
+ return failed ? EXIT.failed : EXIT.ok;
51
+ };
52
+ function check(files, json) {
53
+ let code = EXIT.ok;
54
+ const out = [];
55
+ for (const file of files) {
56
+ if (!existsSync(file)) {
57
+ console.error(`${file}: not found`);
58
+ return EXIT.usage;
59
+ }
60
+ const r = load(file);
61
+ const f = findings(file, r);
62
+ out.push(f);
63
+ code = Math.max(code, codeOf(r));
64
+ if (json)
65
+ continue;
66
+ const failed = f.checks.filter((c) => !c.verdict);
67
+ for (const e of f.errors)
68
+ console.log(`${file}:${e.line}:${e.column} error: ${e.message}`);
69
+ for (const w of statements(r).filter((i) => i.warning))
70
+ console.log(`${file}:${w.pos.start.line} warning: ${w.warning}`);
71
+ for (const c of failed)
72
+ console.log(`${file}:${c.line} check failed: ${plain(c.latex)}${Number.isFinite(c.eta) ? ` η = ${c.eta.toFixed(2)}` : ""}`);
73
+ console.log(`${file}: ${f.checks.length} checks, ${failed.length} failed, ${f.errors.length} error${f.errors.length === 1 ? '' : 's'}`);
74
+ }
75
+ if (json)
76
+ console.log(JSON.stringify(out.length === 1 ? out[0] : out, null, 2));
77
+ return code;
78
+ }
79
+ const plain = plainText;
80
+ async function render(files, out, chromeFlag) {
81
+ let code = EXIT.ok;
82
+ const outIsDir = out !== undefined && existsSync(out) && statSync(out).isDirectory();
83
+ if (out && files.length > 1 && !outIsDir) {
84
+ console.error('-o must be a directory when rendering several files');
85
+ return EXIT.usage;
86
+ }
87
+ for (const file of files) {
88
+ if (!existsSync(file)) {
89
+ console.error(`${file}: not found`);
90
+ return EXIT.usage;
91
+ }
92
+ const target = out && !outIsDir ? out : join(out ?? dirname(file), basename(file, extname(file)) + '.pdf');
93
+ const r = load(file);
94
+ const assets = (p) => {
95
+ const f = resolve(dirname(file), p);
96
+ if (!existsSync(f))
97
+ return undefined;
98
+ const ext = extname(f).slice(1).toLowerCase();
99
+ const mime = ext === 'svg' ? 'image/svg+xml' : ext === 'jpg' ? 'image/jpeg' : `image/${ext}`;
100
+ return `data:${mime};base64,${readFileSync(f).toString('base64')}`;
101
+ };
102
+ const html = toHtml(r, { head: inlineHead(), assets });
103
+ if (extname(target).toLowerCase() === '.html') {
104
+ writeFileSync(target, html);
105
+ }
106
+ else {
107
+ let chrome = findChrome(chromeFlag);
108
+ if (!chrome) {
109
+ if (process.env.MATHEOS_OFFLINE) {
110
+ console.error('no Chromium found; run `matheos install-chrome` or set MATHEOS_CHROME');
111
+ return EXIT.usage;
112
+ }
113
+ try {
114
+ chrome = await installChrome((s) => console.error(s));
115
+ }
116
+ catch (e) {
117
+ console.error(`no Chromium found and the download failed (${e.message}); set MATHEOS_CHROME or --chrome`);
118
+ return EXIT.usage;
119
+ }
120
+ }
121
+ await renderPdf(html, target, chrome);
122
+ }
123
+ code = Math.max(code, codeOf(r));
124
+ const failed = statements(r).filter((i) => i.kind === 'check' && !i.verdict).length;
125
+ console.log(`${file} -> ${target}${r.errors.length ? ` (${r.errors.length} errors)` : ''}${failed ? ` (${failed} checks failed)` : ''}`);
126
+ }
127
+ return code;
128
+ }
129
+ function guide() {
130
+ const here = dirname(fileURLToPath(import.meta.url));
131
+ for (const p of [join(here, '..', 'SKILL.md'), join(here, '..', '..', 'skills', 'matheos-authoring', 'SKILL.md')]) {
132
+ if (existsSync(p)) {
133
+ process.stdout.write(readFileSync(p, 'utf8'));
134
+ return EXIT.ok;
135
+ }
136
+ }
137
+ console.error('SKILL.md not packaged yet; see docs/spec/agent-guide.md in the repository.');
138
+ return EXIT.usage;
139
+ }
140
+ /** Quick sums in the terminal: each statement is a line of one growing math block, its result printed as plain text. */
141
+ async function calc(args) {
142
+ // ponytail: the session is re-evaluated from its first line on every statement (sessions are short); reusing the scope is the upgrade
143
+ const kept = [];
144
+ const show = (ln) => {
145
+ const r = evaluate(parse('```math\n' + [...kept, ln].join('\n') + '\n```\n'));
146
+ const st = statements(r).pop(), err = r.errors[0]?.message ?? st?.error;
147
+ if (err) {
148
+ console.error('✗ ' + err);
149
+ return;
150
+ }
151
+ if (st)
152
+ console.log(plainText(st.latex) + (st.kind === 'check' ? (st.na ? ' n/a' : st.verdict ? ' ✓ OK' : ' ✗ FAIL') + (st.eta ? ' η = ' + st.eta : '') : ''));
153
+ kept.push(ln);
154
+ };
155
+ const lines = args.flatMap((a) => a.split(';')).map((l) => l.trim()).filter(Boolean);
156
+ if (lines.length) {
157
+ lines.forEach(show);
158
+ return EXIT.ok;
159
+ }
160
+ if (!process.stdin.isTTY) {
161
+ readFileSync(0, 'utf8').split(/\r?\n/).map((l) => l.trim()).filter(Boolean).forEach(show);
162
+ return EXIT.ok;
163
+ }
164
+ console.log('matheos calc: one statement per line, e.g. q = 25 kN/m · M = q L^2 / 8 to kNm · check M <= 100 kNm (Ctrl+C ends)');
165
+ const rl = createInterface({ input: process.stdin, output: process.stdout, prompt: '> ' });
166
+ rl.prompt();
167
+ for await (const ln of rl) {
168
+ if (ln.trim())
169
+ show(ln.trim());
170
+ rl.prompt();
171
+ }
172
+ return EXIT.ok;
173
+ }
174
+ async function main(argv) {
175
+ const [cmd, ...rest] = argv;
176
+ const flags = new Set(rest.filter((a) => a.startsWith('--') && !a.startsWith('--chrome')));
177
+ const valueOf = (name) => { const i = rest.indexOf(name); return i >= 0 ? rest[i + 1] : undefined; };
178
+ const skip = new Set(['-o', '--chrome'].flatMap((n) => { const i = rest.indexOf(n); return i >= 0 ? [i, i + 1] : []; }));
179
+ const files = rest.filter((a, i) => !a.startsWith('-') && !skip.has(i)).map((f) => resolve(f));
180
+ switch (cmd) {
181
+ case 'check': return files.length ? check(files, flags.has('--json')) : (console.error(USAGE), EXIT.usage);
182
+ case 'render': return files.length ? render(files, valueOf('-o'), valueOf('--chrome')) : (console.error(USAGE), EXIT.usage);
183
+ case 'install-chrome': {
184
+ const c = await installChrome((s) => console.error(s));
185
+ console.log(c.path);
186
+ return EXIT.ok;
187
+ }
188
+ case 'guide': return guide();
189
+ case 'calc': return calc(rest);
190
+ default:
191
+ console.error(USAGE);
192
+ return EXIT.usage;
193
+ }
194
+ }
195
+ main(process.argv.slice(2)).then((code) => process.exit(code), (e) => { console.error(String(e instanceof Error ? e.message : e)); process.exit(EXIT.usage); });
196
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
package/dist/pdf.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import type { Chrome } from './chrome.js';
2
+ export declare function renderPdf(html: string, out: string, chrome: Chrome): Promise<void>;
package/dist/pdf.js ADDED
@@ -0,0 +1,24 @@
1
+ // HTML -> PDF through headless Chromium, docs/spec/cli.md and docs/adr/0002.
2
+ import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { pathToFileURL } from 'node:url';
6
+ import puppeteer from 'puppeteer-core';
7
+ export async function renderPdf(html, out, chrome) {
8
+ const dir = mkdtempSync(join(tmpdir(), 'matheos-'));
9
+ const page = join(dir, 'report.html');
10
+ writeFileSync(page, html);
11
+ const browser = await puppeteer.launch({ executablePath: chrome.path, headless: chrome.shell ? 'shell' : true, args: ['--no-sandbox'] });
12
+ try {
13
+ const tab = await browser.newPage();
14
+ await tab.goto(pathToFileURL(page).href, { waitUntil: 'load' });
15
+ await tab.evaluate('document.fonts.ready.then(() => window.fitWidth && window.fitWidth())'); // wide lines shrink after the fonts settle
16
+ await tab.evaluate('document.fonts.ready');
17
+ await tab.pdf({ path: out, preferCSSPageSize: true, printBackground: true });
18
+ }
19
+ finally {
20
+ await browser.close();
21
+ rmSync(dir, { recursive: true, force: true });
22
+ }
23
+ }
24
+ //# sourceMappingURL=pdf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf.js","sourceRoot":"","sources":["../src/pdf.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,SAAS,MAAM,gBAAgB,CAAC;AAGvC,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY,EAAE,GAAW,EAAE,MAAc;IACvE,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IACtC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC1B,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;IACzI,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QACpC,MAAM,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;QAChE,MAAM,GAAG,CAAC,QAAQ,CAAC,uEAAuE,CAAC,CAAC,CAAG,2CAA2C;QAC1I,MAAM,GAAG,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC;QAC3C,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/E,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,52 @@
1
1
  {
2
2
  "name": "@matheos/cli",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.1",
4
+ "description": "Matheos command line: check and render .mth documents.",
5
+ "license": "MIT",
6
+ "homepage": "https://matheos.fly.dev",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/Suharevillya/matheos.git",
10
+ "directory": "cli"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/Suharevillya/matheos-issues/issues"
14
+ },
15
+ "keywords": [
16
+ "structural-engineering",
17
+ "calculation",
18
+ "units",
19
+ "markdown",
20
+ "eurocode",
21
+ "cli"
22
+ ],
23
+ "type": "module",
24
+ "bin": {
25
+ "matheos": "./dist/main.js"
26
+ },
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "scripts": {
31
+ "build": "tsc && node -e \"require('fs').copyFileSync('../skills/matheos-authoring/SKILL.md','SKILL.md')\"",
32
+ "typecheck": "tsc --noEmit",
33
+ "test": "vitest run",
34
+ "prepack": "npm run build"
35
+ },
36
+ "dependencies": {
37
+ "@fontsource/figtree": "^5.3.0",
38
+ "@fontsource/jetbrains-mono": "^5.3.0",
39
+ "@matheos/core": "^0.2.0",
40
+ "@puppeteer/browsers": "^3.2.5",
41
+ "katex": "^0.16.47",
42
+ "puppeteer-core": "^25.14.0"
43
+ },
44
+ "devDependencies": {
45
+ "pdf-parse": "^1.1.1"
46
+ },
47
+ "files": [
48
+ "dist",
49
+ "SKILL.md",
50
+ "README.md"
51
+ ]
52
+ }