Skip to content

Document complex API boundaries - #6

Merged
thannous merged 1 commit into
mainfrom
agent/document-api-boundaries
Aug 1, 2026
Merged

Document complex API boundaries#6
thannous merged 1 commit into
mainfrom
agent/document-api-boundaries

Conversation

@thannous

@thannous thannous commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Summary

  • add formal JSDoc contracts to HID framing, device sessions, and lighting payload APIs
  • document AppSense/profile transformation invariants and session navigation targets
  • document the GUI profile workflow boundary
  • raise the selected boundary modules from 5 to 77 JSDoc blocks
  • guard all 68 exported API-surface symbols (36 callables and 32 constants), plus public HID session methods
  • document the maintenance contract in both contributor guides

Validation

  • node --test tests/api-docs.test.mjs — 10/10 passed
  • npm run validate — profile, presets, and 46 Markdown files validated
  • npm run check — 109 root tests passed; 73.40% lines, 75.48% branches, 73.99% functions
  • GUI production build passed
  • prototype coverage — 33 tests passed; 98.80% lines, 92.82% branches, 97.83% functions

Impact

Documentation and maintainability guard only; no runtime behavior changes.

Summary by CodeRabbit

  • Documentation

    • Expanded API documentation for hardware, profile, session, lighting, input, and status-related features.
    • Added guidance for documenting complex exported APIs in English and French contributor documentation.
  • Tests

    • Added automated checks to verify that public APIs include required JSDoc details and documented contracts.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The pull request adds adjacent JSDoc contracts to exported APIs across profile, HID, lighting, session, and input-profile modules. It also adds contribution guidance and automated tests that verify the documented API surface.

Changes

API documentation coverage

Layer / File(s) Summary
Documentation rules and automated enforcement
CONTRIBUTING*.md, tests/api-docs.test.mjs
Contribution guides define required JSDoc contracts. Tests inspect runtime exports, prototype exports, classes, and public methods.
Profile workflow API contracts
prototype/src/profile-workflow.js
Profile workflow functions document parameters, return values, hashing behavior, errors, and preservation rules.
HID transport API contracts
scripts/lib/hid-device.mjs, scripts/lib/hid-frame.mjs
HID device and frame APIs document constants, session behavior, RPC calls, framing, decoding, and close semantics.
Session and lighting API contracts
scripts/lib/hid-lighting.mjs, scripts/lib/thread-slots.mjs, shared/thread-status-palette.mjs
Lighting, session-slot, navigation, and palette contracts now describe data shapes, validation, state behavior, and preservation rules.
Input profile API contracts
shared/input-profile.mjs
Input-profile APIs document key restrictions, mappings, wheel modes, joystick geometry, profile inspection, synthesis, derivation, and generation.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 61.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the pull request’s main change: documenting complex API boundaries with formal JSDoc contracts.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/document-api-boundaries

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@thannous
thannous marked this pull request as ready for review August 1, 2026 09:39

thannous commented Aug 1, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e199f0b37e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/api-docs.test.mjs
Comment on lines +56 to +59
function exportedFunctionNames(source) {
return [...source.matchAll(/export\s+(?:async\s+)?function\s+([A-Za-z_$][\w$]*)/g)]
.map((match) => match[1])
.sort();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Enumerate every source-only export form

Extend this surface check beyond direct export function declarations. If the workflow adds a callable as export const helper = () => ..., a class, or a separately declared symbol exposed with export { helper }, exportedFunctionNames() ignores it, so the equality assertion still passes and no JSDoc contract is checked for the new public API.

Useful? React with 👍 / 👎.

Comment thread tests/api-docs.test.mjs
Comment on lines +168 to +169
for (const member of ["constructor", "open", "onNotification", "call", "close"]) {
assertDocumentedMember(source, file, "DeviceSession", member);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Discover public HID methods instead of hard-coding them

Derive the public DeviceSession member list from the class source, or assert that this allowlist matches it. As written, adding any new public method without updating this array makes the documentation test pass without examining that method, defeating the regression guard precisely when the session API expands.

Useful? React with 👍 / 👎.

Comment on lines +137 to +141
* Sanitizes persisted data into the current snapshot shape and slot count.
* Invalid snapshots fail closed to {@link emptySnapshot}; extra slots vanish.
*
* @param {unknown} value Deserialized snapshot candidate.
* @returns {SlotSnapshot} Defensive copy safe for reducer operations.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Validate slot fields before promising a sanitized snapshot

Do not return the documented SlotSnapshot contract for arbitrary persisted entries without validating their state. For example, {slots: [{sessionId: "x", state: "bogus"}]} is copied verbatim by this function, and slotView() subsequently emits an undefined color even though SessionSlot.state is documented as a known shared state and the result is described as safe for reducer operations; validate state and pending values or narrow the contract.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai 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.

Actionable comments posted: 8

🧹 Nitpick comments (1)
prototype/src/profile-workflow.js (1)

66-77: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the preservation report shape.

report is declared as object, but prototype/tests/profile-session.test.mjs:84-110 reads review.report.nativeLayerPreserved. Define the report fields and types, preferably with a shared typedef, so consumers can rely on this boundary contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@prototype/src/profile-workflow.js` around lines 66 - 77, Document the
preservation report contract used by the profile-building function, preferably
via a shared typedef referenced by its return annotation. Define the report
shape to include the boolean nativeLayerPreserved field consumed by
profile-session tests, along with the other fields returned by the transformer,
so consumers have explicit field types.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@prototype/src/profile-workflow.js`:
- Around line 43-50: Update the sha256Hex JSDoc parameter declaration to match
its supported inputs: allow null and the minimal injectable object exposing
subtle.digest, while preserving the existing failure behavior for unavailable or
rejected Web Crypto.

In `@scripts/lib/hid-device.mjs`:
- Around line 123-129: Update the onForeignWrite contract in the handle/session
JSDoc declarations and the `#resolve`() callback invocation consistently: either
await and catch rejected promises with defined failure behavior, or remove
Promise<void> from both callback types and keep them synchronous. Ensure the
constructor and DeviceSession.open declarations match the behavior implemented
by `#resolve`().
- Around line 178-187: Preserve validation errors from buildRequest in
DeviceSession.call instead of wrapping them as WRITE_FAILED in `#run`. Validate
the method and request id before queueing, or identify and rethrow the dedicated
validation error separately from HID write failures; document this behavior in
the call method’s JSDoc.

In `@scripts/lib/hid-lighting.mjs`:
- Around line 111-116: Update the exported JSDoc blocks for
threadsLightingParams and rgbConfigParams to declare that they may throw Error
propagated from threadEntry and zoneSide respectively, without changing runtime
behavior.

In `@scripts/lib/thread-slots.mjs`:
- Around line 19-31: Complete the SessionSlot typedef by declaring the kind and
startedAt properties with the types returned by claude agents --json, matching
the fields applyRoster persists. Keep the existing applyRoster behavior
unchanged rather than removing those values.
- Around line 39-40: Clarify the JSDoc for SlotSnapshot.overflow to state that
applyRoster accumulates the number of sessions unable to claim a slot across
reconciliations, rather than representing the current live-session count; do not
change the reconciliation logic.
- Around line 84-90: Update the JSDoc for stateFromHookEvent to explicitly
document that idle_prompt is an exception to the non-blocking notification rule
and returns STATES.idle; retain the existing null behavior description for other
non-blocking or unrecognized events.

In `@tests/api-docs.test.mjs`:
- Around line 56-60: Update exportedFunctionNames and the related
export-contract checks to enumerate every supported source export declaration,
including exported const bindings and classes in addition to function
declarations. Preserve the declaration kind for each match so callable exports
and constant/class exports receive their appropriate JSDoc contract validation,
ensuring newly added exports cannot bypass the equality check.

---

Nitpick comments:
In `@prototype/src/profile-workflow.js`:
- Around line 66-77: Document the preservation report contract used by the
profile-building function, preferably via a shared typedef referenced by its
return annotation. Define the report shape to include the boolean
nativeLayerPreserved field consumed by profile-session tests, along with the
other fields returned by the transformer, so consumers have explicit field
types.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b269e342-ccc5-4fee-990f-1d768b579a9a

📥 Commits

Reviewing files that changed from the base of the PR and between 86a1a37 and e199f0b.

📒 Files selected for processing (10)
  • CONTRIBUTING.fr.md
  • CONTRIBUTING.md
  • prototype/src/profile-workflow.js
  • scripts/lib/hid-device.mjs
  • scripts/lib/hid-frame.mjs
  • scripts/lib/hid-lighting.mjs
  • scripts/lib/thread-slots.mjs
  • shared/input-profile.mjs
  • shared/thread-status-palette.mjs
  • tests/api-docs.test.mjs

Comment on lines +43 to +50
/**
* Computes a browser-compatible SHA-256 digest without making hashing a hard
* requirement. Unavailable or rejected Web Crypto returns an empty string.
*
* @param {string} text UTF-8 text to hash.
* @param {Crypto} [crypto] Injectable Web Crypto implementation.
* @returns {Promise<string>} Lowercase hexadecimal digest, or `""` on failure.
*/

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 4 '\bsha256Hex\s*\(' prototype --glob '*.js' --glob '*.mjs'

Repository: thannous/claude-codex-micro

Length of output: 2471


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== profile-workflow sha256Hex implementation =="
sed -n '35,65p' prototype/src/profile-workflow.js

echo
echo "== sha256Hex call sites with crypto argument =="
rg -n -C 3 '\bsha256Hex\s*\(\s*[^,\n]+,\s*([^,\n]+)' prototype/src prototype/tests --glob '*.js' --glob '*.mjs'

Repository: thannous/claude-codex-micro

Length of output: 2835


Normalize the crypto parameter type to match supported inputs.

sha256Hex is called with null and a minimal { subtle: { digest } } object. Update the JSDoc type to reflect nullable and minimal injectable inputs, or narrow the runtime contract and change the tests.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@prototype/src/profile-workflow.js` around lines 43 - 50, Update the sha256Hex
JSDoc parameter declaration to match its supported inputs: allow null and the
minimal injectable object exposing subtle.digest, while preserving the existing
failure behavior for unavailable or rejected Web Crypto.

Comment on lines +123 to +129
/**
* @param {{on: Function, write: Function, close: Function}} handle Open HID handle.
* @param {object} [options] Session callbacks.
* @param {(method: string, response: unknown) => void|Promise<void>} [options.onForeignWrite]
* Called for orphan responses to known lighting methods.
* @param {(line: string) => void} [options.onDebugLine] Called for firmware debug lines.
*/

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Handle rejected onForeignWrite promises or remove Promise<void> from the contract.

The constructor and DeviceSession.open contracts accept an asynchronous callback. #resolve() invokes this callback at Line [278] without awaiting or catching the returned promise. A rejected callback promise becomes unhandled. Either handle the promise and define its failure behavior, or restrict both JSDoc types to void.

Also applies to: 142-151

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/lib/hid-device.mjs` around lines 123 - 129, Update the onForeignWrite
contract in the handle/session JSDoc declarations and the `#resolve`() callback
invocation consistently: either await and catch rejected promises with defined
failure behavior, or remove Promise<void> from both callback types and keep them
synchronous. Ensure the constructor and DeviceSession.open declarations match
the behavior implemented by `#resolve`().

Comment on lines +178 to +187
/**
* Queues one RPC call and resolves only its correlated response. Calls run
* sequentially with {@link CALL_SPACING_MS} between start times.
*
* @param {string} method Firmware method name.
* @param {unknown} [params] Method parameters; `null` when omitted.
* @param {number} [id] Explicit request id, primarily for deterministic tests.
* @returns {Promise<object>} Parsed firmware response envelope.
* @throws {DeviceError} Via rejection on timeout, write, RPC, or disconnect failure.
*/

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Preserve request-validation errors in DeviceSession.call().

buildRequest() in scripts/lib/hid-frame.mjs rejects empty methods and identifiers outside [0, 999). #run() catches those errors in the same block as HID write failures and wraps them as WRITE_FAILED at Lines [228]-[237]. Callers cannot distinguish invalid input from a transport failure. Validate before queueing or preserve a dedicated validation error, then document the behavior here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/lib/hid-device.mjs` around lines 178 - 187, Preserve validation
errors from buildRequest in DeviceSession.call instead of wrapping them as
WRITE_FAILED in `#run`. Validate the method and request id before queueing, or
identify and rethrow the dedicated validation error separately from HID write
failures; document this behavior in the call method’s JSDoc.

Comment on lines +111 to +116
/**
* Builds the parameter array for `v.oai.thstatus`.
*
* @param {ThreadLightingInput[]} entries Repository-facing slot updates.
* @returns {Array<object>} Firmware-facing entries in the original order.
*/

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Document propagated validation errors on the exported wrappers.

threadsLightingParams calls threadEntry for each entry. rgbConfigParams calls zoneSide for both zones. Both helpers can throw Error, but these exported JSDoc blocks do not declare @throws.

Proposed documentation update
  * `@param` {ThreadLightingInput[]} entries Repository-facing slot updates.
  * `@returns` {Array<object>} Firmware-facing entries in the original order.
+ * `@throws` {Error} When an entry fails `threadEntry` validation.
  */
 export function threadsLightingParams(entries) {

  * `@param` {{ambient: ZoneLightingInput, keys: ZoneLightingInput}} input Zone inputs.
  * `@returns` {{ambient: object, keys: object}} Firmware-facing complete configuration.
+ * `@throws` {Error} When a zone fails `zoneSide` validation.
  */
 export function rgbConfigParams({ ambient, keys }) {

Also applies to: 139-144

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/lib/hid-lighting.mjs` around lines 111 - 116, Update the exported
JSDoc blocks for threadsLightingParams and rgbConfigParams to declare that they
may throw Error propagated from threadEntry and zoneSide respectively, without
changing runtime behavior.

Comment on lines +19 to +31
/**
* @typedef {object} SessionSlot
* @property {string} sessionId Claude Code session identifier.
* @property {string} state One of the shared `STATES` values.
* @property {number} [updatedAt] Timestamp of the last state transition.
* @property {string} [name] Display name from the official roster.
* @property {string} [cwd] Session working directory.
* @property {number} [pid] Session process identifier.
* @property {string} [tty] Terminal identifier reported by `ps`.
* @property {string} [terminalApp] Supported terminal application name.
* @property {string} [entrypoint] Claude Code host entrypoint.
* @property {string} [hostSessionId] Host grouping id, not a navigation target.
*/

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Complete the SessionSlot typedef.

applyRoster copies kind and startedAt into session entries at Lines 268-270, but SessionSlot does not declare either property. Add both fields with the types emitted by claude agents --json, or stop persisting them.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/lib/thread-slots.mjs` around lines 19 - 31, Complete the SessionSlot
typedef by declaring the kind and startedAt properties with the types returned
by claude agents --json, matching the fields applyRoster persists. Keep the
existing applyRoster behavior unchanged rather than removing those values.

Comment on lines +39 to +40
* @property {number} overflow Live sessions that could not claim a slot.
*/

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Clarify the lifecycle of SlotSnapshot.overflow.

applyRoster increments next.overflow for each session that cannot claim a slot. The current text reads as a current live-session count. Document that the value is cumulative, or reset it before reconciliation if a current count is intended.

Proposed documentation update
- * `@property` {number} overflow Live sessions that could not claim a slot.
+ * `@property` {number} overflow Cumulative count of roster sessions that could not claim a slot.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* @property {number} overflow Live sessions that could not claim a slot.
*/
* `@property` {number} overflow Cumulative count of roster sessions that could not claim a slot.
*/
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/lib/thread-slots.mjs` around lines 39 - 40, Clarify the JSDoc for
SlotSnapshot.overflow to state that applyRoster accumulates the number of
sessions unable to claim a slot across reconciliations, rather than representing
the current live-session count; do not change the reconciliation logic.

Comment on lines +84 to +90
/**
* Converts one Claude hook payload into a lighting state transition.
* Non-blocking notifications and unrecognized events deliberately return null.
*
* @param {object|null|undefined} event Normalized hook event.
* @returns {string|null} A shared `STATES` value, or null for no transition.
*/

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Document the idle_prompt exception.

The comment states that non-blocking notifications return null, but stateFromHookEvent returns STATES.idle for idle_prompt at Lines 97-100. List this exception in the contract.

Proposed documentation update
- * Non-blocking notifications and unrecognized events deliberately return null.
+ * Unrecognized events return null. Blocking notifications return `STATES.blocked`;
+ * `idle_prompt` returns `STATES.idle`; other non-blocking notifications return null.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* Converts one Claude hook payload into a lighting state transition.
* Non-blocking notifications and unrecognized events deliberately return null.
*
* @param {object|null|undefined} event Normalized hook event.
* @returns {string|null} A shared `STATES` value, or null for no transition.
*/
/**
* Converts one Claude hook payload into a lighting state transition.
* Unrecognized events return null. Blocking notifications return `STATES.blocked`;
* `idle_prompt` returns `STATES.idle`; other non-blocking notifications return null.
*
* `@param` {object|null|undefined} event Normalized hook event.
* `@returns` {string|null} A shared `STATES` value, or null for no transition.
*/
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/lib/thread-slots.mjs` around lines 84 - 90, Update the JSDoc for
stateFromHookEvent to explicitly document that idle_prompt is an exception to
the non-blocking notification rule and returns STATES.idle; retain the existing
null behavior description for other non-blocking or unrecognized events.

Comment thread tests/api-docs.test.mjs
Comment on lines +56 to +60
function exportedFunctionNames(source) {
return [...source.matchAll(/export\s+(?:async\s+)?function\s+([A-Za-z_$][\w$]*)/g)]
.map((match) => match[1])
.sort();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Enumerate all source-only exports.

exportedFunctionNames only matches export function declarations. If prototype/src/profile-workflow.js adds export const createThing = () => {} or an exported class, the equality check remains unchanged and no JSDoc contract is required.

Collect all supported export declaration kinds. Apply the callable or constant contract check by declaration kind.

Also applies to: 153-158

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/api-docs.test.mjs` around lines 56 - 60, Update exportedFunctionNames
and the related export-contract checks to enumerate every supported source
export declaration, including exported const bindings and classes in addition to
function declarations. Preserve the declaration kind for each match so callable
exports and constant/class exports receive their appropriate JSDoc contract
validation, ensuring newly added exports cannot bypass the equality check.

@thannous
thannous merged commit 603b653 into main Aug 1, 2026
2 checks passed
@thannous
thannous deleted the agent/document-api-boundaries branch August 6, 2026 10:34
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.

1 participant