Skip to content

Function metadata API: getAvailableFunctions / getFunctionDetails (HF-249)#1692

Open
marcin-kordas-hoc wants to merge 36 commits into
developfrom
feature/hf-249-function-metadata-api
Open

Function metadata API: getAvailableFunctions / getFunctionDetails (HF-249)#1692
marcin-kordas-hoc wants to merge 36 commits into
developfrom
feature/hf-249-function-metadata-api

Conversation

@marcin-kordas-hoc

@marcin-kordas-hoc marcin-kordas-hoc commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a two-tier public API for retrieving function metadata, intended for a Formula Builder / function picker:

  • HyperFormula.getAvailableFunctions(code) (static) / hfInstance.getAvailableFunctions() (instance) → FunctionListEntry[] — a short list sorted alphabetically by localized name: localizedName, canonicalName, category, shortDescription.
  • HyperFormula.getFunctionDetails(canonicalName, code) (static) / hfInstance.getFunctionDetails(canonicalName) (instance) → FunctionDetails | undefined — the same fields plus the ordered parameters list (each name, description, optional) and repeatLastArgs (how many trailing parameters repeat; 0 for a fixed arg list). No pre-rendered syntax string — the caller renders it from parameters + repeatLastArgs.

Built-in functions and their aliases are included. Custom (user-registered) functions are instance-scoped, so they are listed by the instance methods, not the static ones; a custom function has category: undefined, an empty shortDescription, and positional parameter names (Arg1, Arg2, …). A custom function that shadows a built-in id is reported as the custom function (never the built-in’s catalogue metadata).

Catalogue

The 363-function catalogue lives in src/interpreter/functionMetadata/categories/ (generated from docs/guide/built-in-functions.md by a dev-only script; not shipped — tsconfig include is ["src"]). Categories use the full-word names from the official Excel docs; Array manipulation, Matrix functions and Operator are HyperFormula-specific. Parameter names/optionality follow the implementation arity in implementedFunctions; a catalogue-vs-implementation arity mismatch drops the function from both list and details so they never disagree.

Tests

Paired tests PR: handsontable/hyperformula-tests#14 (branch feature/hf-249-function-metadata-api):

  • public API: static + instance, i18n, built-in aliases, custom functions (list + details, positional params, category: undefined), custom alias, instance-vs-static scoping
  • coverage parity: FUNCTION_DOCS keys == canonical set (both directions); FUNCTION_CATEGORIES shape
  • parameter consistency: count == arity, unique non-empty names, numeric repeatLastArgs (SUM=1, SUMIFS=2, SUMIF=0)
  • shadowed-built-in reported as custom (matching + mismatched arity); custom repeatLastArgs clamp
  • deterministic ordering: alphabetical by localizedName with canonicalName tiebreaker (locale-aware), non-Latin names

MVP scope

parameters[].description, documentationUrl, and examples are present but empty; authored in a later phase.

Notes

  • Sort order: alphabetical by localized name, canonicalName tiebreaker, via Intl.Collator from the language’s locale (deterministic across environments).
  • Empty language-pack translations fall back to the canonical id.

Note

Medium Risk
Large new public API surface and registry ownership logic, but changes are additive read-only metadata with guards for shadowed built-ins and catalogue drift rather than formula evaluation paths.

Overview
Adds a function metadata API for building function pickers and reference UIs: getAvailableFunctions() returns a localized, sorted short list; getFunctionDetails() returns full details including parameters, optionality, and repeatLastArgs (callers build syntax strings themselves). Both exist as static methods (built-ins + aliases, explicit language code) and instance methods (instance registry + configured language, including custom plugins).

Introduces a FUNCTION_DOCS catalogue under src/interpreter/functionMetadata/ (per-category files, mostly generated from docs/guide/built-in-functions.md via dev script scripts/hf249-migrate-function-docs.ts). FunctionRegistry gains built-in ownership tracking (captureBuiltinFunctionOwners, isBuiltinFunction, getListableFunctionIds) so custom plugins that shadow a built-in id are described as custom functions, not with stale built-in docs; catalogue arity drift omits a function from list and details.

Docs/changelog updated; SUM / SUMIF carry sample rich metadata (examples, param descriptions) for Formula Builder testing.

Reviewed by Cursor Bugbot for commit 40b6468. Bugbot is set up for automated code reviews on this repo. Configure here.

…c API (HF-249)

Add static and instance getAvailableFunctions and getFunctionDetails to
HyperFormula, backed by the function metadata catalogue. Instance methods
delegate to the static ones using the configured language. Re-export the
public catalogue types from the package entry point.
Replace the seeded catalogue with all 363 canonical built-ins, generated from
docs/guide/built-in-functions.md by scripts/hf249-migrate-function-docs.ts (dev-only,
not shipped). Parameter names come from the Syntax column but their count and
optionality follow the implementation arity; repeating groups collapse and duplicate
names are disambiguated. Also fall back to the canonical id when a language pack leaves
a function name empty (e.g. SWITCH in several locales).
…-249)

Add a CHANGELOG entry for the new built-in function metadata API, and a
"Function metadata" section to the custom functions guide clarifying that the
catalogue covers built-ins only — custom functions are absent from
getAvailableFunctions() and getFunctionDetails() returns undefined for them.
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

Performance comparison of head (40b6468) vs base (e0e1261)

                                     testName |   base |   head | change
------------------------------------------------------------------------
                                      Sheet A | 498.75 | 500.61 | +0.37%
                                      Sheet B | 156.56 | 158.57 | +1.28%
                                      Sheet T | 143.49 | 140.49 | -2.09%
                                Column ranges | 471.89 | 470.16 | -0.37%
Sheet A:  change value, add/remove row/column |  16.17 |  15.35 | -5.07%
 Sheet B: change value, add/remove row/column | 133.76 | 131.37 | -1.79%
                   Column ranges - add column | 147.56 | 150.46 | +1.97%
                Column ranges - without batch | 443.91 | 458.57 | +3.30%
                        Column ranges - batch | 114.88 | 115.07 | +0.17%

@netlify

netlify Bot commented Jun 9, 2026

Copy link
Copy Markdown

Deploy Preview for hyperformula-dev-docs ready!

Name Link
🔨 Latest commit 40b6468
🔍 Latest deploy log https://app.netlify.com/projects/hyperformula-dev-docs/deploys/6a5764162e39a10008e74494
😎 Deploy Preview https://deploy-preview-1692--hyperformula-dev-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@marcin-kordas-hoc marcin-kordas-hoc force-pushed the feature/hf-249-function-metadata-api branch from 8983d26 to 3f8857b Compare June 10, 2026 03:21
marcinkordas

This comment was marked as resolved.

@marcin-kordas-hoc marcin-kordas-hoc marked this pull request as ready for review June 10, 2026 10:54
Comment thread src/HyperFormula.ts Outdated
…ith getFunctionDetails (HF-249)

getAvailableFunctions derived its id set from each plugin class's static implementedFunctions, so an unregistered built-in (or a registry mutation) could still appear in the list while getFunctionDetails returned undefined for it. Gate the list on FunctionRegistry.getFunctionPlugin(id) — the same resolution getFunctionDetails uses — so list and details never disagree. (Cursor Bugbot, #1692.)
Comment thread src/HyperFormula.ts Outdated
Comment thread src/HyperFormula.ts Outdated
…tFunctionDetails agree (HF-249)

getAvailableFunctions filtered on documented+registered but not the catalogue-vs-implementation arity check that getFunctionDetails applies, so a drifted function could appear in the list yet return undefined from details. Extract resolveListableMetadata (documented + registered + arity-consistent) and use it in both. (Cursor, #1692.)
@marcin-kordas-hoc marcin-kordas-hoc requested a review from sequba June 10, 2026 13:52
marcin-kordas-hoc and others added 2 commits June 23, 2026 07:45
…249)

Align parameter display names in the generated function-metadata catalogue
with their Title-Case siblings:
- financial.ts: CUMIPMT `type` -> `Type` (matches CUMPRINC); RATE `guess` -> `Guess`
- statistical.ts: BESSELI/J/K/Y `x`,`n` -> `X`,`N`

Also add an instance-method example to the "Function metadata" section of
docs/guide/custom-functions.md so the "available both as static and instance
methods" claim is backed by a snippet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@qunabu

qunabu commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Comment thread src/interpreter/functionMetadata/FunctionDescription.ts Outdated
Comment thread src/interpreter/functionMetadata/FunctionDescription.ts Outdated
Comment thread src/interpreter/functionMetadata/FunctionDescription.ts
Comment thread src/interpreter/functionMetadata/FunctionDescription.ts Outdated
Comment thread src/interpreter/functionMetadata/FunctionDescription.ts Outdated
Comment thread docs/guide/custom-functions.md Outdated
Comment thread CHANGELOG.md Outdated
…-249)

buildFunctionDescriptions eagerly imported the plugin barrel to detect
built-in ownership; since HyperFormula loads the metadata builders early,
that created a module-load-order cycle crashing the bundled build
('Class extends value undefined' in the perf benchmark). Move the
built-in owner snapshot to FunctionRegistry (captured in index.ts, which
already imports the barrel to register built-ins) and expose
isBuiltinFunction; the builders no longer import the barrel. Shadow-vs-
built-in behavior is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@marcin-kordas-hoc marcin-kordas-hoc requested a review from sequba June 24, 2026 11:12
Comment thread docs/guide/custom-functions.md Outdated
…adata (HF-249)

Per review: the metadata guide need not describe what the API does NOT return.
Keep only the repeatLastArgs explanation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@marcin-kordas-hoc marcin-kordas-hoc requested a review from sequba June 24, 2026 18:28
marcin-kordas-hoc and others added 2 commits June 25, 2026 09:26
…/examples on FunctionDoc (HF-249)

Add optional documentationUrl/examples to FunctionDoc and surface them in
getFunctionDetails (falling back to ''/[] when absent). Author SUM and SUMIF
as reference functions with real parameter descriptions, examples and a
documentation link so the Formula Builder team can test rendering of populated
metadata. The migration generator does not emit these fields; a comment guards
the two entries against regeneration.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ails (HF-249)

The custom-functions guide listed the getFunctionDetails return shape but omitted
the documentationUrl and examples fields; add them so the documented shape matches
FunctionDetails.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread src/HyperFormula.ts
Comment thread docs/guide/custom-functions.md Outdated
```
:::

## Function metadata

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to describe getAvailableFunctions and getFunctionDetails functions in the built-in-functions page instead of custom-functions

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cursor fix it

@cursor cursor Bot Jul 14, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect! I've successfully fixed both issues:

Changes Made

1. Added Missing Catalogue Entries (commit c65115b)

  • Added XIRR to src/interpreter/functionMetadata/categories/financial.ts
  • Added VSTACK and HSTACK to src/interpreter/functionMetadata/categories/array-manipulation.ts
  • Moved Function metadata API documentation from custom-functions.md to built-in-functions.md

2. Fixed Static API to Exclude Custom Plugins (commit 86ab411)

  • Modified FunctionRegistry.getListableFunctionIds() to filter out globally-registered custom plugins, returning only built-in functions and aliases
  • Modified HyperFormula.getFunctionDetails() static method to return undefined for custom plugins instead of partial metadata
  • Both changes use the existing isBuiltinFunction() check to properly distinguish built-ins from custom plugins

Verification

✅ Linter passes (0 errors, only pre-existing warnings)
✅ Jest smoke tests pass (4/4 tests)
✅ Built-in functions like XIRR, VSTACK, HSTACK are correctly included in static API
✅ Static methods now properly exclude globally-registered custom plugins per documentation

The static metadata API now correctly returns only built-in functions and their aliases, while instance methods continue to include custom plugins as intended.

Open in Web Open in Cursor 

@sequba

sequba commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

@cursor fix the review comment

@cursor

cursor Bot commented Jul 14, 2026

Copy link
Copy Markdown

Taking a look!

Open in Web Open in Cursor 

- Add XIRR to Financial category with Values, Dates, Guess parameters
- Add VSTACK and HSTACK to Array manipulation category with Array1 parameter
- Move Function metadata section from custom-functions.md to built-in-functions.md
- Fixes Bugbot review: Missing catalogue mislabels builtins

Co-authored-by: Kuba Sekowski <sequba@users.noreply.github.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c65115b. Configure here.

Comment thread src/HyperFormula.ts
cursoragent and others added 5 commits July 14, 2026 11:44
Static getAvailableFunctions and getFunctionDetails now filter out
custom plugins registered via HyperFormula.registerFunctionPlugin,
returning only built-in functions and their aliases as documented.

Co-authored-by: Kuba Sekowski <sequba@users.noreply.github.com>
Add note to custom-functions.md explaining that globally-registered
custom plugins (via registerFunctionPlugin) are available in all
instances but don't appear in static metadata API methods.

Co-authored-by: Kuba Sekowski <sequba@users.noreply.github.com>
…dsontable/hyperformula into feature/hf-249-function-metadata-api
sequba and others added 2 commits July 14, 2026 15:36
…(HF-249) (#1709)

<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
### Context

Addresses a code-review finding on #1692: the function-metadata
catalogue mixed several parameter-name conventions, which surface
directly in a function-picker UI. Even closely-related functions
disagreed — `SUMIF` used `Range, Criteria, Sumrange`, `SUMIFS` used
`Sum_Range, Criterion_range1, Criterion1`, `AVERAGEIF` used `Range,
Criterion, Average_Range` — mixing Title-case, `snake_Case`, and run-on
tokens.

This normalizes **every** `FunctionDoc` parameter name to `snake_case`
so the catalogue is internally consistent.

**What changed**

- All 172 unique parameter names across the 13 `categories/*.ts` files
are now `snake_case` (lowercase words joined by `_`, camelCase/acronym
boundaries split, separators unified, trailing digits kept attached:
`Number1`/`Number_1` → `number1`).
- Run-on tokens the docs left unsplit are segmented so siblings agree:
`Sumrange` → `sum_range` (matches `SUMIFS`), `Searchcriterion` →
`search_criterion` (matches `VLOOKUP`/`HLOOKUP`), plus `logical_value`,
`date_string`, `time_string`, `start_date`, `minimum_length`,
`lower_bound`, `upper_bound`, `number_x`, `number_y`.
- The migration generator (`scripts/hf249-migrate-function-docs.ts`) now
emits `snake_case` via a shared, exported `toSnakeCase` helper (+ a
small segmentation table), so a future regeneration stays consistent.
Its `main()` is guarded with `require.main === module` so the helper can
be imported without side effects.
- **Not touched:** parameter `description`s, `examples`,
`documentationUrl`, categories, short descriptions, ordering.
Custom-function positional names (`Arg1`, `Arg2`, …) are unchanged —
they are a documented, self-consistent placeholder for user functions
that ship no metadata (see open question below).

### How did you test your changes?

- `tsc --noEmit` — clean.
- `eslint` on the changed files — 0 errors.
- `test/smoke.spec.ts` — 4/4 pass.
- Ad-hoc runtime checks against the built API:
- every catalogue **and** `getFunctionDetails` parameter name matches
`^[a-z][a-z0-9]*(_[a-z0-9]+)*$`;
- names are unique within each function (no collisions introduced by the
transform);
- `getAvailableFunctions`/`getFunctionDetails` list↔details parity still
holds;
- `SUMIF` & `SUMIFS` both expose `sum_range`; `MATCH` & `VLOOKUP` both
expose `search_criterion`;
  - custom-function details still report `Arg1`, `Arg2`.
- Ran the generator to confirm it produces identical parameter names to
this hand-applied transform (the only regen deltas are unrelated
pre-existing drift — alphabetical re-sorting of manually-added
`HSTACK`/`XIRR`, the hand-authored `SUM`/`SUMIF` fields, and a stale
`TEXT` description — so the regen output was discarded).

### Types of changes

- [ ] Breaking change (a fix or a feature because of which an existing
functionality doesn't work as expected anymore)
- [x] New feature or improvement (a non-breaking change that adds
functionality)
- [ ] Bug fix (a non-breaking change that fixes an issue)
- [ ] Additional language file, or a change to an existing language file
(translations)
- [ ] Change to the documentation

### Related issues:

1. Follow-up to #1692 (HF-249); targets that branch.

### Notes for reviewers

- **Paired tests:** the private test suite (`hyperformula-tests#14`)
asserts specific parameter names (e.g. `SUMIF` params); those
expectations need updating to the new `snake_case` names.
- **Open question — custom functions:** the request was "snake_case for
all param names". I scoped this to the catalogue and left the runtime
custom-function placeholders as the documented `Arg1`/`Arg2`. If you'd
also like those lowercased (`arg1`/`arg2`), it's a 1-line change in
`buildCustomFunctionDetails` plus a `custom-functions.md` wording update
— say the word.
- **Segmentation calls** (`sumrange`→`sum_range`, etc.) are the only
editorial decisions here; everything else is mechanical.

<!-- CURSOR_AGENT_PR_BODY_END -->

<div><a
href="https://cursor.com/agents/bc-51ff732c-3307-42ef-aa24-7fb0dc332ce9"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/background-agent?bcId=bc-51ff732c-3307-42ef-aa24-7fb0dc332ce9"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;</div>

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Kuba Sekowski <sequba@users.noreply.github.com>
…es (HF-249) (#1710)

<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
### Context

Addresses a code-review finding on #1692: `getAvailableFunctions` can
throw a `RangeError` for a caller-registered, malformed language code.

`buildAvailableFunctions` built its sort collator with `new
Intl.Collator(toBcp47Locale(code))`. `toBcp47Locale` only hyphenates the
canonical `<ll><RR>` shape and passes any other string through
unchanged, and `registerLanguage` performs **no** shape validation on
the code. `Intl.Collator` throws a `RangeError` on a *structurally
invalid* language tag (it does **not** silently fall back to the default
locale). So a caller who registers an underscore-style code such as
`'pt_BR'` (or `'en_US'`, `'x'`, `'12'`) and then calls
`getAvailableFunctions` (static **or** instance) crashes.

Built-in language codes are all safe, so this only affects
consumer-registered malformed codes → important, not critical.

The `toBcp47Locale` JSDoc was also wrong: it claimed unrecognized tags
"fall back to the default locale," which `Intl.Collator` does not do for
invalid tags.

### Fix

- Extract `createLocaleCollator(languageCode)` which wraps the
`Intl.Collator` construction in a `try/catch` and falls back to the
environment-default collator (`new Intl.Collator()`) on `RangeError`, so
listing functions never crashes on a non-BCP-47 code.
- Use it in `buildAvailableFunctions`.
- Correct the `toBcp47Locale` JSDoc to describe the real behavior
(invalid tags throw; the throw is handled by `createLocaleCollator`).

`getFunctionDetails` is unaffected — it does not sort and never
constructs a collator.

### How did you test your changes?

- Reproduced the crash before the fix: registering `'pt_BR'` then
calling `getAvailableFunctions('pt_BR')` threw `RangeError: Incorrect
locale information provided`.
- After the fix, `'pt_BR'`, `'en_US'`, `'x'`, and `'12'` each return the
full, alphabetically-sorted 419-entry list; well-formed `'enGB'` is
unchanged.
- Confirmed via Node that `new Intl.Collator('pt_BR'|'en_US'|'x'|'12')`
throw while `'zz-ZZ'`/`'qqq'` do not.
- `tsc --noEmit` clean; `eslint src/HyperFormula.ts` 0 errors;
`test/smoke.spec.ts` 4/4.

### Types of changes

- [ ] Breaking change (a fix or a feature because of which an existing
functionality doesn't work as expected anymore)
- [ ] New feature or improvement (a non-breaking change that adds
functionality)
- [x] Bug fix (a non-breaking change that fixes an issue)
- [ ] Additional language file, or a change to an existing language file
(translations)
- [ ] Change to the documentation

### Related issues:

1. Follow-up to #1692 (HF-249); targets that branch.

### Notes for reviewers

- Behavior on a malformed code is now "sort using the default collator"
rather than throwing. The alternative (validating codes in
`registerLanguage`) would be a broader, potentially breaking change, so
it's intentionally out of scope here.
- A unit test for this belongs in the paired private suite
(`hyperformula-tests`): register a `'pt_BR'`-style code and assert
`getAvailableFunctions` returns a sorted list instead of throwing.

<!-- CURSOR_AGENT_PR_BODY_END -->

<div><a
href="https://cursor.com/agents/bc-51ff732c-3307-42ef-aa24-7fb0dc332ce9"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/background-agent?bcId=bc-51ff732c-3307-42ef-aa24-7fb0dc332ce9"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;</div>

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Kuba Sekowski <sequba@users.noreply.github.com>
marcin-kordas-hoc added a commit that referenced this pull request Jul 15, 2026
…param backticks (HF-300)

- BETA.DIST second example switched from the PDF-with-bounds form
  (=BETA.DIST(2,2,3,FALSE(),0,4) → HF 1.5 vs Excel 0.375, a known engine
  PDF-scaling bug) to the cumulative bounded form (=BETA.DIST(2,2,3,TRUE(),0,4)
  → 0.6875, matches Excel). Still exercises the optional A/B bounds args, but
  no longer ships an example whose output is wrong.
- Removed backticks from six date-and-time PARAMETER descriptions
  (nullDate/dateFormats/timeFormats). The metadata field is plain text and
  every other parameter description in the catalogue is plain prose; backticks
  rendered literally for API consumers. shortDescription markdown links are
  migrated (#1692) content and left untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Source: https://app.clickup.com/t/86caprtgj
ADR: adr/2026-07-13-hf300-function-metadata-enrichment.md
sequba and others added 2 commits July 15, 2026 08:50
A traceability audit (run during HF-300) found migrated shortDescriptions that
either misstate behavior or leak markup into the plain-text metadata API. Per
Kuba's call (Slack #hyperformula-dev, 2026-07-15) they belong on the parent
HF-249 branch, since the catalogue is becoming the single source of truth
(docs/guide generated from it at build):

- XNPV: was verbatim identical to NPV; now conveys its non-periodic/date-based nature.
- MIRR: "modified internal value" -> "modified internal rate of return".
- SPLIT/TEXT: dropped <br> + markdown (rendered literally through the API); TEXT
  now also mentions the stringifyCurrency option.
- SECH: "given angle (in radians)" -> "given value" (the argument is a plain number).
- BASE: "positive integer" -> "non-negative integer" (0 is accepted by the impl).
- typos: MROUND "neares"/"multiplicity", Fischer->Fisher, densitity->density,
  skeweness->skewness (x2).

Catalogue-only; docs/guide regenerates from these once #1699 lands.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.43%. Comparing base (e0e1261) to head (40b6468).

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #1692      +/-   ##
===========================================
- Coverage    97.16%   96.43%   -0.73%     
===========================================
  Files          176      192      +16     
  Lines        15450    15589     +139     
  Branches      3417     3447      +30     
===========================================
+ Hits         15012    15034      +22     
- Misses         438      555     +117     
Files with missing lines Coverage Δ
src/HyperFormula.ts 99.75% <100.00%> (+0.02%) ⬆️
src/index.ts 100.00% <100.00%> (ø)
src/interpreter/FunctionRegistry.ts 99.43% <100.00%> (+0.05%) ⬆️
...nterpreter/functionMetadata/FunctionDescription.ts 100.00% <100.00%> (ø)
...eter/functionMetadata/buildFunctionDescriptions.ts 100.00% <100.00%> (ø)
.../functionMetadata/categories/array-manipulation.ts 100.00% <100.00%> (ø)
...nterpreter/functionMetadata/categories/database.ts 100.00% <100.00%> (ø)
...reter/functionMetadata/categories/date-and-time.ts 100.00% <100.00%> (ø)
...rpreter/functionMetadata/categories/engineering.ts 100.00% <100.00%> (ø)
...terpreter/functionMetadata/categories/financial.ts 100.00% <100.00%> (ø)
... and 9 more

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants