{"_id":"@doikayt/update-markdown-uml","_rev":"7-cd1649270aaebc8f7aaccfbcceaf2a38","name":"@doikayt/update-markdown-uml","dist-tags":{"latest":"1.4.20"},"versions":{"1.4.15":{"name":"@doikayt/update-markdown-uml","version":"1.4.15","keywords":["uml","typescript","mermaid","documentation","class-diagram","component-diagram","ci","automation"],"license":"MIT","_id":"@doikayt/update-markdown-uml@1.4.15","maintainers":[{"name":"datalackey","email":"chris@buildlackey.com"}],"homepage":"https://github.com/doikayt/build-tools/tree/main/javascript/update-markdown-uml","bugs":{"url":"https://github.com/doikayt/build-tools/issues"},"bin":{"update-markdown-uml":"bin/update-markdown-uml.js"},"dist":{"shasum":"3b16dba2700c9ab285329227440e0e3b8ae8dd1f","tarball":"https://registry.npmjs.org/@doikayt/update-markdown-uml/-/update-markdown-uml-1.4.15.tgz","fileCount":33,"integrity":"sha512-rZx31Md6Q8vA2uDHgJRqUYiwDoopGW7DBT1RDlp9wtJnONCUEY0m2x5Bw2r4JR5qxUPLWoADJvZKLjswiaYuUw==","signatures":[{"sig":"MEQCIGkLqPs2FFiga4a1k4KmQOJiIq2W2KkqB4paEpfYYNKQAiB6OriYOBuxXkrJJAKbojYF4NUFxwXt8K+n72VGLSxD5g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50026},"type":"module","engines":{"node":">=22"},"gitHead":"2a67c16f87dbf3f5dc6f10fd9e7de0da0745e242","private":false,"scripts":{"prepack":"npx nx build @doikayt/update-markdown-uml 1>&2"},"_npmUser":{"name":"datalackey","email":"chris@buildlackey.com"},"repository":{"url":"git+https://github.com/doikayt/build-tools.git","type":"git","directory":"javascript/update-markdown-uml"},"_npmVersion":"10.9.8","description":"Generates and validates UML class and component diagrams for TypeScript source trees, injecting them into Markdown documentation files","directories":{},"_nodeVersion":"22.23.1","dependencies":{"ts-morph":"^24.0.0","micromatch":"^4.0.0","github-slugger":"^2.0.0","@doikayt/tooling-core":"^1.4.15"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.0.0","typescript":"^5.4.0","@types/node":"^18.16.0","@types/micromatch":"^4.0.9"},"_npmOperationalInternal":{"tmp":"tmp/update-markdown-uml_1.4.15_1783992553991_0.8344701877100626","host":"s3://npm-registry-packages-npm-production"}},"1.4.16":{"name":"@doikayt/update-markdown-uml","version":"1.4.16","keywords":["uml","typescript","mermaid","documentation","class-diagram","component-diagram","ci","automation"],"license":"MIT","_id":"@doikayt/update-markdown-uml@1.4.16","maintainers":[{"name":"datalackey","email":"chris@buildlackey.com"}],"homepage":"https://github.com/doikayt/build-tools/tree/main/javascript/update-markdown-uml","bugs":{"url":"https://github.com/doikayt/build-tools/issues"},"bin":{"update-markdown-uml":"bin/update-markdown-uml.js"},"dist":{"shasum":"8d2b19b73868c08d32fddf18df5aafbd071946dc","tarball":"https://registry.npmjs.org/@doikayt/update-markdown-uml/-/update-markdown-uml-1.4.16.tgz","fileCount":33,"integrity":"sha512-gc+ctXj74d8JmwrPQFVrsT87WgRdt0oOzzWW4lpLjz+NMQTPM7UbeOhSSIj2Y92xoijXC50+5Tv8JiA3CACojA==","signatures":[{"sig":"MEYCIQCS4OOLESmxcggirHEKpSHtBTSvMkAuoQMnKcMOy5RRGgIhANZycJnEY0fLTB/FwYVAFSiy/5VtMH9uyx+HMgaXHP3a","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50026},"type":"module","engines":{"node":">=22"},"gitHead":"d1cdb9d8727e1aecffdc4916e6766d9b50765e64","private":false,"scripts":{"prepack":"npx nx build @doikayt/update-markdown-uml 1>&2"},"_npmUser":{"name":"datalackey","email":"chris@buildlackey.com"},"repository":{"url":"git+https://github.com/doikayt/build-tools.git","type":"git","directory":"javascript/update-markdown-uml"},"_npmVersion":"10.9.8","description":"Generates and validates UML class and component diagrams for TypeScript source trees, injecting them into Markdown documentation files","directories":{},"_nodeVersion":"22.23.1","dependencies":{"ts-morph":"^24.0.0","micromatch":"^4.0.0","github-slugger":"^2.0.0","@doikayt/tooling-core":"^1.4.16"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.0.0","typescript":"^5.4.0","@types/node":"^18.16.0","@types/micromatch":"^4.0.9"},"_npmOperationalInternal":{"tmp":"tmp/update-markdown-uml_1.4.16_1783993667663_0.42781019674638543","host":"s3://npm-registry-packages-npm-production"}},"1.4.17":{"name":"@doikayt/update-markdown-uml","version":"1.4.17","keywords":["uml","typescript","mermaid","documentation","class-diagram","component-diagram","ci","automation"],"license":"MIT","_id":"@doikayt/update-markdown-uml@1.4.17","maintainers":[{"name":"datalackey","email":"chris@buildlackey.com"}],"homepage":"https://github.com/doikayt/build-tools/tree/main/javascript/update-markdown-uml","bugs":{"url":"https://github.com/doikayt/build-tools/issues"},"bin":{"update-markdown-uml":"bin/update-markdown-uml.js"},"dist":{"shasum":"b7ccab14b6e6b70d79acb32463243edc26d6b155","tarball":"https://registry.npmjs.org/@doikayt/update-markdown-uml/-/update-markdown-uml-1.4.17.tgz","fileCount":33,"integrity":"sha512-weDqYlyCLka0X5Doyt3KrXrC5TedE0f+gO7Wvdtb56JVbS8Y8Ldau4Jxioq6XOm8hIG7P0BfqHEPoS0KPhCT9A==","signatures":[{"sig":"MEUCIQD6IRbaFH0Kc+h7gIbmp8KaKjGYaz9mze6WLxyluqb5iwIgfSdujEHoDRfLNZR8NiTMoqYLjxWz4njwTVvjge9HZ8c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50026},"type":"module","engines":{"node":">=22"},"gitHead":"776931f4dfd9bbbc5a3e59c185ad157c2bba7b24","private":false,"scripts":{"prepack":"npx nx build @doikayt/update-markdown-uml 1>&2"},"_npmUser":{"name":"datalackey","email":"chris@buildlackey.com"},"repository":{"url":"git+https://github.com/doikayt/build-tools.git","type":"git","directory":"javascript/update-markdown-uml"},"_npmVersion":"10.9.8","description":"Generates and validates UML class and component diagrams for TypeScript source trees, injecting them into Markdown documentation files","directories":{},"_nodeVersion":"22.23.1","dependencies":{"ts-morph":"^24.0.0","micromatch":"^4.0.0","github-slugger":"^2.0.0","@doikayt/tooling-core":"^1.4.17"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.0.0","typescript":"^5.4.0","@types/node":"^18.16.0","@types/micromatch":"^4.0.9"},"_npmOperationalInternal":{"tmp":"tmp/update-markdown-uml_1.4.17_1783994513890_0.27801685422918454","host":"s3://npm-registry-packages-npm-production"}},"1.4.18":{"name":"@doikayt/update-markdown-uml","version":"1.4.18","keywords":["uml","typescript","mermaid","documentation","class-diagram","component-diagram","ci","automation"],"license":"MIT","_id":"@doikayt/update-markdown-uml@1.4.18","maintainers":[{"name":"datalackey","email":"chris@buildlackey.com"},{"name":"lastliet","email":"pranjalk.dev@outlook.com"}],"homepage":"https://github.com/doikayt/build-tools/tree/main/javascript/update-markdown-uml","bugs":{"url":"https://github.com/doikayt/build-tools/issues"},"bin":{"update-markdown-uml":"bin/update-markdown-uml.js"},"dist":{"shasum":"c1672ed6cdee46479571397285a09a80f938bf2e","tarball":"https://registry.npmjs.org/@doikayt/update-markdown-uml/-/update-markdown-uml-1.4.18.tgz","fileCount":33,"integrity":"sha512-eTiFMlQFwsXCoD9A79Ug6pzVy0WjR6AN660c1kGDTyD4wHlFi4dQW9Esubmi9o5BC5wXCOgxs7y4/BNv78lpqQ==","signatures":[{"sig":"MEUCIDVO97EoL4Fv4UwYA9jwj9FfoFXJEzFLaF5y/LtutkVuAiEA1ovbRMEDS6i2V9nILMhexrK1B0pg97Q18eVudyM3HHQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIFNgmy5EwQ/1rML4nJh8KfKbNP6YYyLEkn6M/0pL18fIAiBeikwNE0orNY1tnrB3W2VEXn40wp882GSI+NgKVPk+iw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50149},"type":"module","engines":{"node":">=22"},"gitHead":"2974899886f97c0ea44079338ff50f59a7c28718","private":false,"scripts":{"prepack":"npx nx build @doikayt/update-markdown-uml 1>&2"},"_npmUser":{"name":"datalackey","email":"chris@buildlackey.com"},"repository":{"url":"git+https://github.com/doikayt/build-tools.git","type":"git","directory":"javascript/update-markdown-uml"},"_npmVersion":"10.9.8","description":"Generates and validates UML class and component diagrams for TypeScript source trees, injecting them into Markdown documentation files","directories":{},"_nodeVersion":"22.23.2","dependencies":{"ts-morph":"^24.0.0","micromatch":"^4.0.0","github-slugger":"^2.0.0","@doikayt/tooling-core":"^1.4.18"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.0.0","typescript":"^5.4.0","@types/node":"^18.16.0","@types/micromatch":"^4.0.9"},"_npmOperationalInternal":{"tmp":"tmp/update-markdown-uml_1.4.18_1790823379250_0.5202862495472633","host":"s3://npm-registry-packages-npm-production"}},"1.4.19":{"name":"@doikayt/update-markdown-uml","version":"1.4.19","keywords":["uml","typescript","mermaid","documentation","class-diagram","component-diagram","ci","automation"],"license":"MIT","_id":"@doikayt/update-markdown-uml@1.4.19","maintainers":[{"name":"datalackey","email":"chris@buildlackey.com"},{"name":"lastliet","email":"pranjalk.dev@outlook.com"}],"homepage":"https://github.com/doikayt/build-tools/tree/main/javascript/update-markdown-uml","bugs":{"url":"https://github.com/doikayt/build-tools/issues"},"bin":{"update-markdown-uml":"bin/update-markdown-uml.js"},"dist":{"shasum":"1be4ebc3f5e40fc8fe880fc80e731fdc3a3cf049","tarball":"https://registry.npmjs.org/@doikayt/update-markdown-uml/-/update-markdown-uml-1.4.19.tgz","fileCount":33,"integrity":"sha512-bMPuy2anRgJxTAOdDG4ZPfwZSSo1CsuKYW1flWIecNiBafYtU7eqjYN3ic6IUkHIqDqelfLpasmkRwjLMn1ZPw==","signatures":[{"sig":"MEUCIELtPssCmUqrSzR+Q8PA9l0udCdsIRhfPVXicXgeLBYXAiEAjZtWFcFErglZPgbENf8EhLPnBrnXCzGyk0mwyJ2vniQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQC+JgVwbtn+5nJGMiD/M/Z3cIO2C0Ae/h/D7AwrOiD/tQIgQVaiH66UQpURxe2IfCpqnOKZD22Bpyh31iWFaD8xxyA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50149},"type":"module","engines":{"node":">=22"},"gitHead":"cbd192dc2455809281db2b19a5527a6260f33594","private":false,"scripts":{"prepack":"npx nx build @doikayt/update-markdown-uml 1>&2"},"_npmUser":{"name":"datalackey","email":"chris@buildlackey.com"},"repository":{"url":"git+https://github.com/doikayt/build-tools.git","type":"git","directory":"javascript/update-markdown-uml"},"_npmVersion":"10.9.9","description":"Generates and validates UML class and component diagrams for TypeScript source trees, injecting them into Markdown documentation files","directories":{},"_nodeVersion":"22.23.3","dependencies":{"ts-morph":"^24.0.0","micromatch":"^4.0.0","github-slugger":"^2.0.0","@doikayt/tooling-core":"^1.4.19"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.0.0","typescript":"^5.4.0","@types/node":"^18.16.0","@types/micromatch":"^4.0.9"},"_npmOperationalInternal":{"tmp":"tmp/update-markdown-uml_1.4.19_1790824039645_0.7772653235257223","host":"s3://npm-registry-packages-npm-production"}},"1.4.20":{"_id":"@doikayt/update-markdown-uml@1.4.20","bin":{"update-markdown-uml":"bin/update-markdown-uml.js"},"bugs":{"url":"https://github.com/doikayt/build-tools/issues"},"dist":{"shasum":"97cbc7a50cce692e7e22ec70ba849484e5f764f2","tarball":"https://registry.npmjs.org/@doikayt/update-markdown-uml/-/update-markdown-uml-1.4.20.tgz","fileCount":33,"integrity":"sha512-AIBCLLQFpfEUkr70FIe9J5w/3s3sWQMZmhrTNKm51+1iXCwtDDe8MASklUTpvoHEI9X0PP3r+UCI13IIjDlizw==","signatures":[{"sig":"MEQCIH5byEe/fPWSNAtWj5SSUDMfN6JY6oQqKB2Bwo0CuIwqAiAHp5deGfydVo4xqrtXV97IHxyaL18kgDdKoycgGl8cqA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD/6Zu/8xAl7QpSVjWPfylzbNsEouIlh9lyRCIAy6WNogIhAL1dJRJJeYMFlOWWsPvJIH1s3pOL1SPUaERwFBLy8N4i"}],"unpackedSize":50149},"name":"@doikayt/update-markdown-uml","type":"module","engines":{"node":">=22"},"gitHead":"711d730053d3e887dc94a1850139fffba699d816","license":"MIT","private":false,"scripts":{"prepack":"npx nx build @doikayt/update-markdown-uml 1>&2"},"version":"1.4.20","_npmUser":{"name":"datalackey","email":"chris@buildlackey.com"},"homepage":"https://github.com/doikayt/build-tools/tree/main/javascript/update-markdown-uml","keywords":["uml","typescript","mermaid","documentation","class-diagram","component-diagram","ci","automation"],"repository":{"url":"git+https://github.com/doikayt/build-tools.git","type":"git","directory":"javascript/update-markdown-uml"},"_npmVersion":"10.9.9","description":"Generates and validates UML class and component diagrams for TypeScript source trees, injecting them into Markdown documentation files","directories":{},"maintainers":[{"name":"datalackey","email":"chris@buildlackey.com"},{"name":"lastliet","email":"pranjalk.dev@outlook.com"}],"_nodeVersion":"22.23.3","dependencies":{"ts-morph":"^24.0.0","micromatch":"^4.0.0","github-slugger":"^2.0.0","@doikayt/tooling-core":"^1.4.20"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.0.0","typescript":"^5.4.0","@types/node":"^18.16.0","@types/micromatch":"^4.0.9"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/update-markdown-uml_1.4.20_1790824805589_0.07439755346735599"}}},"time":{"created":"2026-07-14T01:29:13.760Z","modified":"2026-10-01T03:20:05.841Z","1.4.15":"2026-07-14T01:29:14.136Z","1.4.16":"2026-07-14T01:47:47.811Z","1.4.17":"2026-07-14T02:01:54.029Z","1.4.18":"2026-10-01T02:56:19.334Z","1.4.19":"2026-10-01T03:07:19.731Z","1.4.20":"2026-10-01T03:20:05.682Z"},"bugs":{"url":"https://github.com/doikayt/build-tools/issues"},"license":"MIT","homepage":"https://github.com/doikayt/build-tools/tree/main/javascript/update-markdown-uml","keywords":["uml","typescript","mermaid","documentation","class-diagram","component-diagram","ci","automation"],"repository":{"url":"git+https://github.com/doikayt/build-tools.git","type":"git","directory":"javascript/update-markdown-uml"},"description":"Generates and validates UML class and component diagrams for TypeScript source trees, injecting them into Markdown documentation files","maintainers":[{"name":"datalackey","email":"chris@buildlackey.com"},{"name":"lastliet","email":"pranjalk.dev@outlook.com"}],"readme":"\n\n<!-- TOC:START -->\n- [@doikayt/update-markdown-uml](#doikaytupdate-markdown-uml)\n  - [Terminology](#terminology)\n  - [What It Does](#what-it-does)\n    - [Function-only components](#function-only-components)\n  - [Installation](#installation)\n  - [Usage](#usage)\n  - [Options](#options)\n  - [Example](#example)\n    - [Source tree](#source-tree)\n    - [Generated output](#generated-output)\n      - [cli](#cli)\n      - [math-engine](#math-engine)\n    - [Side Note on How to Correct Unknown Properties](#side-note-on-how-to-correct-unknown-properties)\n  - [Built With](#built-with)\n  - [Contributing and Releasing](#contributing-and-releasing)\n<!-- TOC:END -->\n\n# @doikayt/update-markdown-uml\n\nGenerates and validates UML class and component diagrams for TypeScript source\ntrees, injecting them into Markdown documentation files.\n\n---\n\n## Terminology\n\nThis tool uses **component** to denote a cohesive group of TypeScript source files\nthat live in a single directory under `src/`. This is the same concept Java\ndevelopers know as a *package* — a named namespace boundary that groups related\ntypes and controls visibility. The word \"package\" is avoided here because in a\nNode/npm workspace it already means something else (a publishable npm artifact),\nwhich would create ambiguity.\n\n## What It Does\n\nGiven a TypeScript project organised into components (one directory per\ncomponent under `src/`), this tool:\n\n- generates a **component relationship graph** showing cross-component\n  import dependencies\n- generates a **components table** with one row per component\n- generates **per-component class diagrams** showing classes, interfaces,\n  and type aliases\n\nAll three sections are injected into a single Markdown file between\nfixed marker pairs. Running the tool again is a no-op if nothing has\nchanged — output is fully deterministic.\n\n### Function-only components\n\nWhen a component directory contains no classes, interfaces, or type aliases,\nthe class diagram falls back to a four-column Markdown table of exported\nfunctions:\n\n| Function | Parameters | Returns | Description |\n|----------|------------|---------|-------------|\n| `matchFields` | `template: Template`<br>`fields: FormField[]` | `MatchResult` | Partitions discovered fields into three buckets. |\n| `isReactForm` | — | `boolean` | Returns `true` if any React signal is present. |\n\nDetails of the fallback format:\n\n- **Parameters cell** — each parameter is formatted as `name: Type`; multiple\n  parameters are stacked within the same cell using `<br>`. Zero-argument\n  functions show `—`.\n- **Description cell** — the first sentence of the function's JSDoc block\n  (text up to and including the first `.`, or up to the first newline,\n  whichever comes first). When no JSDoc description is present, `—` appears in\n  the cell and a warning is emitted to stderr:\n  ```\n  warn: [ComponentName] function `functionName` has no JSDoc description\n  ```\n- **Empty component** — if a component has no exported functions, classes,\n  interfaces, or types at all, the output is the single line\n  `_No exported types or functions._` and a warning is emitted:\n  ```\n  warn: [ComponentName] has no exported functions, classes, interfaces, or types\n  ```\n\nBoth warnings are suppressed when the CLI is run with `--quiet`.\n\n---\n\n## Installation\n\n```bash\nnpm install --save-dev @doikayt/update-markdown-uml\n```\n\n---\n\n## Usage\n\nPlace three marker pairs in the Markdown file where you want the diagrams\nto appear:\n\n&nbsp;&nbsp;&lt;!-- UML:components:START --&gt;<br>\n&nbsp;&nbsp;&lt;!-- UML:components:END --&gt;\n\n&nbsp;&nbsp;&lt;!-- UML:components-table:START --&gt;<br>\n&nbsp;&nbsp;&lt;!-- UML:components-table:END --&gt;\n\n&nbsp;&nbsp;&lt;!-- UML:component-details:START --&gt;<br>\n&nbsp;&nbsp;&lt;!-- UML:component-details:END --&gt;\n\nThen run:\n\n```bash\nnpx update-markdown-uml README.md\n```\n\nThe tool discovers `src/` automatically when it exists next to the target\nMarkdown file. Use `--source <path>` to override.\n\nFor CI drift detection, use `--check`:\n\n```bash\nnpx update-markdown-uml --check README.md\n```\n\n---\n\n## Options\n\n```\nupdate-markdown-uml [options] <file>\n\nOptions:\n  --source <path>                       Override source root discovery (default: src/)\n  --exclude-components <cmp1,cmp2>      Leaf directory names to exclude from all output\n  --test-patterns-to-skip <pat1,pat2>   Glob patterns for test files to skip during discovery\n  -t <pat1,pat2>                        Short form of --test-patterns-to-skip\n  --check                               Do not write; exit non-zero if content is stale\n  --verbose                             Print per-component type counts\n  --quiet                               Suppress all non-error output\n  --debug                               Print debug diagnostics to stderr\n  --help                                Show this help message and exit\n  --version                             Print version and exit\n```\n\nThis tool processes a single Markdown file per invocation. Recursive folder\ntraversal is not supported — each UML diagram is tied to a specific source\ntree, so the association must be declared explicitly. For workspace-wide runs\nuse [`autogen-markdown-doc`](../autogen-markdown-doc/README.md).\n\nFor full documentation of shared CLI behavior (`--check`, `--verbose`,\n`--quiet`, exit codes) see\n[Common CLI Behavior](../CLI-BEHAVIOR.md).\n\n---\n\n## Example\n\n[This folder](./tests/e2e/fixtures/math-cli) contains a sample project that demonstrates \nthe tool's output. \n\nRunning the sample and reproducing the output you see above by \nactually installing and running the tool is a good way to get a feel for how it works.\nCopy/paste the code below to clone the sample, install dependencies, and run the tool. \n\nTo view the rendered mermaid graph you could use VSCode's built-in markdown preview, or push \nit to github and view it in the browser.\n\n\n```bash\n\nrm -rf /tmp/run-sample \nmkdir /tmp/run-sample \ncp -r javascript/update-markdown-uml/tests/e2e/fixtures/math-cli/* /tmp/run-sample/  \ncd /tmp/run-sample/  \nnpm install\nnpx update-markdown-uml README.md\necho Load the README file into your favorite Markdown viewer. Enjoy the injected UML diagrams.\n\n```\n\n\n\n\n\n### Source tree\n\nA simple two-component project: a `cli` layer that delegates computation to\na `math-engine` layer.\n\n```\nsrc/\n  cli/\n    AddCommand.ts\n    ArgParser.ts\n    CliCommand.ts\n    CliRunner.ts\n    CommandRegistry.ts\n    ParsedArgs.ts\n    SubtractCommand.ts\n  math-engine/\n    MathEngine.ts\n    MathError.ts\n    MathResult.ts\n    Operation.ts\n```\n\n`cli` imports from `math-engine`. `math-engine` has no dependency on `cli`.\n\n### Generated output\n\n**Component overview** — one subgraph per component, arrows show import direction:\n\n```mermaid\nflowchart TB\n  subgraph cli[\"cli\"]\n  end\n  subgraph math-engine[\"math-engine\"]\n  end\n\n  cli --> math-engine\n```\n\n**Components table** — names link to the class diagram section below.\nDescriptions are read from an optional `_COMPONENT_INFO.md` file in each\ncomponent directory; `TBD` appears when the file is absent. The description\nis the first sentence of the file — text up to and including the first\nperiod (`.`); everything after that period is ignored.\n\n**Note:** if the file exists but contains no period, the description is\ntreated as missing (`TBD`) and a warning is printed identifying the file.\nTo suppress `TBD` without providing a description, create\n`_COMPONENT_INFO.md` with a blank first line (no period needed for an\nempty file).\n\n| Component | Description |\n|-----------|-------------|\n| [cli](#cli) | Command-line interface layer that parses arguments and dispatches math operations to the math-engine component |\n| [math-engine](#math-engine) | Code for System Backend -- which enables CLI front-end access to a suite of sophisticated math functions |\n\n**Class diagrams** — one per component, showing classes, interfaces, type\naliases, and relationships:\n\n#### cli\n\n```mermaid\nclassDiagram\n  direction TB\n  class AddCommand {\n    +name unknown\n    +description unknown\n    -engine MathEngine\n    +execute(args) void\n  }\n  class ArgParser {\n    +parse(argv) ParsedArgs\n  }\n  class CliCommand {\n    <<interface>>\n    +name string\n    +description string\n    +execute(args) void\n  }\n  class CliRunner {\n    -registry CommandRegistry\n    -parser ArgParser\n    +run(argv) void\n  }\n  class CommandRegistry {\n    -commands Map<string, CliCommand>\n    +register(command) void\n    +get(name) CliCommand | undefined\n    +listAll() CliCommand[]\n  }\n  class ParsedArgs {\n    <<interface>>\n    +command \"add\" | \"subtract\"\n    +a number\n    +b number\n  }\n  class SubtractCommand {\n    +name unknown\n    +description unknown\n    -engine MathEngine\n    +execute(args) void\n  }\n\n  AddCommand ..|> CliCommand\n  SubtractCommand ..|> CliCommand\n```\n\n#### math-engine\n\n```mermaid\nclassDiagram\n  direction TB\n  class MathEngine {\n    +add(a, b) MathResult\n    +subtract(a, b) MathResult\n    -validate(op, a, b) void\n  }\n  class MathError {\n    +operation Operation\n  }\n  class MathResult {\n    <<interface>>\n    +value number\n    +operation Operation\n    +operands [number, number]\n  }\n  class Operation {\n    <<type>>\n  }\n```\n\n\n\n\n\n### Side Note on How to Correct Unknown Properties \n\n\nProperties initialised with a\nliteral value and no explicit type annotation (e.g. `readonly name = \"add\"`)\nare rendered as `unknown` because the tool reads TypeScript source without\nfull type resolution. Adding an explicit annotation\n(`readonly name: string = \"add\"`) resolves this.\n\n---\n\n## Built With\n\n- [`@doikayt/tooling-core`](../tooling-core/README.md) — shared CLI framework and utilities\n- [`ts-morph`](https://ts-morph.com/) — TypeScript compiler API for class and import analysis\n\nFor the full workspace tech stack see: [TECH-STACK.md](../TECH-STACK.md)\n\n---\n\n## Contributing and Releasing\n\nFor code overview, development setup, build workflow, and release procedures (including how to\ntrigger a publish via Changesets), see\n[CONTRIBUTING.md](./docs/CONTRIBUTING.md).\n\n\n[![Remember the USS Liberty!](https://badge.techforpalestine.org/ceasefire-now)](https://techforpalestine.org/learn-more)\n","readmeFilename":"README.md"}