Skip to content

PR publish plugins#61

Merged
magmacomputing merged 6 commits into
mainfrom
release/plugins
Jul 17, 2026
Merged

PR publish plugins#61
magmacomputing merged 6 commits into
mainfrom
release/plugins

Conversation

@magmacomputing

@magmacomputing magmacomputing commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added IDE validation for Tempo.format() template tokens, including extensible plugin tokens.
    • Expanded the Functions package with calendar, business, scheduling, timezone, duration, and support utilities.
    • Plugin catalog cards now display available version numbers.
    • Added an interactive plugin REPL with discovered plugin globals.
  • Documentation

    • Added a premium plugin License Key Guide and refreshed ecosystem navigation.
    • Improved plugin documentation harvesting for multiple pages and links.
  • Bug Fixes

    • Improved timezone parsing, cron search limits, duration rounding, and documentation deployment.
  • Release

    • Updated Tempo, Library, and plugin tooling to version 3.9.1.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This release adds the functions utility package surface, compile-time Tempo.format() token validation, plugin REPL and build tooling updates, multi-file documentation harvesting, catalog version badges, expanded plugin guidance, reorganized CI jobs, and version 3.9.1 metadata.

Changes

Functions package

Layer / File(s) Summary
Utility APIs and exports
packages/functions/src/**
Adds business, calendar, support, timezone, duration, and scheduling utilities, with public barrel exports and runtime Temporal helpers.
Testing and packaging
packages/functions/test/**, packages/functions/package.json, packages/functions/vitest.config.ts, packages/functions/rollup.config.js
Adds Vitest setup and scenario tests, updates test configuration, and configures the Functions browser global bundle.
Documentation and branding
packages/functions/doc/**, packages/functions/README.md
Updates package naming, imports, branding, documentation navigation, and contribution guidance.

Plugin tooling

Layer / File(s) Summary
Plugin REPL bootstrap
package.json, packages/plugins/.bin/*
The plugin REPL preloads Temporal, discovers plugin exports, and injects them into an interactive Node REPL context.
Shared plugin test and build configuration
packages/plugins/*/package.json, packages/plugins/vitest.shared.ts, packages/plugins/tsup.shared.ts, packages/plugins/tsconfig.shared.json
Plugin tests use shared Vitest configuration; ESM builds externalize shared Tempo modules and license detection reads the package plan.

Format typing

Layer / File(s) Summary
Format token contracts and overloads
packages/tempo/src/tempo.type.ts, packages/tempo/src/module/module.format.ts, packages/tempo/src/tempo.class.ts, packages/tempo/test/instance/instance.format.test.ts
Adds augmentable format-token types, recursive literal validation, FormatOptions, narrowed return types, and updated format tests.

Documentation pipeline

Layer / File(s) Summary
Plugin harvesting and catalog display
packages/tempo/bin/harvest-plugins.mjs, packages/tempo/.vitepress/config.ts, packages/tempo/.vitepress/theme/components/CatalogList.vue
Harvesting now supports multiple Markdown files with normalized IDs, collision detection, link rewriting, and catalog version badges.
Plugin setup and ecosystem documentation
packages/plugins/.setup/**, packages/plugins/ticker/doc/index.md, packages/tempo/doc/**, packages/tempo/README.md
Adds the License Key Guide and updates ecosystem, plugin, and premium-feature documentation.

CI and release metadata

Layer / File(s) Summary
Workspace CI pipeline
.github/workflows/ci.yml, .github/workflows/deploy-docs.yml
Splits CI into dependent library, Tempo, plugin, and functions jobs and updates documentation deployment paths.
Version and repository metadata
package.json, packages/library/package.json, packages/tempo/package.json, packages/tempo/src/tempo.version.ts, packages/tempo/CHANGELOG.md, .gitignore
Bumps version values to 3.9.1, updates side-effect entries and changelog data, and adds documentation ignore rules.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant package_json
  participant repl_mts
  participant plugin_packages
  participant repl_context
  package_json->>repl_mts: start REPL with Temporal preload
  repl_mts->>plugin_packages: scan compiled plugin entrypoints
  plugin_packages-->>repl_mts: return matching plugin exports
  repl_mts->>repl_context: inject Tempo, enums, and plugin globals
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is related to the changeset and points to the plugin publishing/release work, though it is broad and omits the wider functions and CI updates.
Docstring Coverage ✅ Passed Docstring coverage is 85.00% which is sufficient. The required threshold is 80.00%.
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
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release/plugins

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.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
packages/plugins/tsup.shared.ts (1)

111-114: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Update the comment to reflect the property rename.

The property checked is now plan, but the comment still refers to pricing tier.

📝 Proposed fix
-						// If the package explicitly declares the 'community' pricing tier, skip the license wrapper
+						// If the package explicitly declares the 'community' plan, skip the license wrapper
🤖 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 `@packages/plugins/tsup.shared.ts` around lines 111 - 114, Update the comment
above the plan === 'community' check to refer to the package’s explicitly
declared plan property rather than the pricing tier, keeping the existing
behavior unchanged.
🤖 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 `@package.json`:
- Line 26: Update the package.json repl:plugins script to invoke the actual
packages/plugins/.bin/repl.mts entrypoint with the tsx runner, matching the new
TypeScript REPL file and noEmit configuration.

In `@vitest.config.ts`:
- Around line 64-65: Update both alias entries in vitest.config.ts and
packages/plugins/vitest.shared.ts at the specified ranges: change the
`#tempo/plugins/`... patterns to the singular `#tempo/plugin/`... form and update
their replacement targets from packages/tempo/src/plugins/... to
packages/tempo/src/plugin/..., preserving the existing util/type and wildcard
mappings.

---

Nitpick comments:
In `@packages/plugins/tsup.shared.ts`:
- Around line 111-114: Update the comment above the plan === 'community' check
to refer to the package’s explicitly declared plan property rather than the
pricing tier, keeping the existing behavior unchanged.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 06b08e52-fddd-460a-843c-2e0d98e2410f

📥 Commits

Reviewing files that changed from the base of the PR and between ec6cd97 and 11ef412.

📒 Files selected for processing (15)
  • package.json
  • packages/plugins/.bin/README.md
  • packages/plugins/.bin/repl.mts
  • packages/plugins/.bin/temporal-polyfill.mts
  • packages/plugins/.bin/tsconfig.json
  • packages/plugins/astro/package.json
  • packages/plugins/batch/package.json
  • packages/plugins/finance/package.json
  • packages/plugins/snap/package.json
  • packages/plugins/sync/package.json
  • packages/plugins/tsup.shared.ts
  • packages/plugins/vitest.shared.ts
  • packages/tempo/.vitepress/theme/components/CatalogList.vue
  • packages/tempo/vitest.config.ts
  • vitest.config.ts

Comment thread package.json Outdated
Comment thread vitest.config.ts Outdated

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 10

🤖 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 @.github/workflows/ci.yml:
- Line 21: Disable checkout credential persistence for all four
actions/checkout@v4 steps by adding a with configuration with
persist-credentials set to false at .github/workflows/ci.yml lines 21, 37, 54,
and 71.
- Line 15: Add a top-level permissions block alongside the workflow’s top-level
configuration in ci.yml, explicitly restricting the default token to
least-privilege access, preferably disabling all permissions unless individual
jobs require specific scopes. Keep any required job-level permissions explicit
and unchanged.
- Around line 62-63: Update the CI test step in the packages/plugins
working-directory to target only the plugin workspaces explicitly, rather than
relying on npm workspace discovery from the repository root. Preserve the
existing optional-test behavior while excluding library, tempo, and functions
workspaces.

In `@packages/plugins/.app/doc/index.md`:
- Around line 46-77: Update all plugin references in the documentation examples
to use the exported TickerModule symbol consistently, replacing the truncated
TickerPlugi identifier in the import, plugins array, and Tempo.extend call.
Preserve the existing initialization examples and side-effect import behavior.
- Around line 121-126: The duplicated licensing guides incorrectly describe
revocation-check failures as console warnings. Update the documentation at
packages/plugins/.app/doc/index.md:121-126 and
packages/tempo/doc/9-plugins/.app.md:121-126 to state the implementation’s
actual debug-level logging, preserving the existing fail-open behavior.
- Around line 97-106: The frontend bundler documentation must ensure
TEMPO_LICENSE_KEY is set before Tempo initialization. Update the examples in
packages/plugins/.app/doc/index.md (lines 97-106) and
packages/tempo/doc/9-plugins/.app.md (lines 97-106) to use dynamic imports after
the globalThis.TEMPO_LICENSE_KEY assignment, or demonstrate Tempo.init({ license
}) instead of relying on static imports.

In `@packages/plugins/ticker/doc/index.md`:
- Around line 11-12: Update the License Key Guide link in the documentation text
to point to the shared, existing guide path rather than the nonexistent
ticker-relative path. Preserve the link label and surrounding content while
using the correct relative Tempo documentation destination.

In `@packages/plugins/tsup.shared.ts`:
- Around line 40-52: The resolver plugin ordering currently lets esm-external
short-circuit plugin imports before wrapper processing. Move the esm-external
plugin definition after the wrapper resolver plugin so the version-injection and
license-alias hooks run first, while preserving its existing IIFE exemption and
ESM externalization behavior.

In `@packages/tempo/src/module/module.format.ts`:
- Around line 26-34: Remove the catch-all `format(fmt?: any, options?: any):
any` overload from the `format` declarations so invalid format strings cannot
bypass `ValidateFormat<S>` and are rejected by TypeScript. If zero-argument
calls must remain supported, replace it with an explicit parameterless
`format(): string | number | bigint` overload while preserving the validated
generic overload.

In `@packages/tempo/src/tempo.class.ts`:
- Around line 1628-1636: Revert the implementation signature of the format
method to permissive parameter types that encompass the numeric and
Intl.DateTimeFormatOptions overloads declared by the module.format.ts interface.
Preserve the existing runtime delegation through `#resolve` and interpret, while
leaving strict format validation to the interface overloads.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8ca0ad03-b08f-41ab-8c3d-aae45e74c01b

📥 Commits

Reviewing files that changed from the base of the PR and between 11ef412 and 2133ef0.

📒 Files selected for processing (22)
  • .github/workflows/ci.yml
  • package.json
  • packages/plugins/.app/doc/index.md
  • packages/plugins/.bin/repl.mts
  • packages/plugins/.bin/temporal-polyfill.mts
  • packages/plugins/finance/package.json
  • packages/plugins/ticker/doc/index.md
  • packages/plugins/tsconfig.shared.json
  • packages/plugins/tsup.shared.ts
  • packages/plugins/vitest.shared.ts
  • packages/tempo/bin/harvest-plugins.mjs
  • packages/tempo/doc/3-extending-tempo/tempo.extension.md
  • packages/tempo/doc/8-project-and-support/commercial.md
  • packages/tempo/doc/9-plugins/.app.md
  • packages/tempo/doc/9-plugins/ticker.md
  • packages/tempo/package.json
  • packages/tempo/plan/refactor-path-terms.md
  • packages/tempo/plan/typescript-format-template.md
  • packages/tempo/src/module/module.format.ts
  • packages/tempo/src/tempo.class.ts
  • packages/tempo/src/tempo.type.ts
  • vitest.config.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/plugins/.bin/temporal-polyfill.mts
  • packages/plugins/finance/package.json
  • packages/plugins/vitest.shared.ts
  • vitest.config.ts

Comment thread .github/workflows/ci.yml
Comment thread .github/workflows/ci.yml
Comment thread .github/workflows/ci.yml Outdated
Comment thread packages/plugins/.app/doc/index.md Outdated
Comment thread packages/plugins/.app/doc/index.md Outdated
Comment thread packages/plugins/.app/doc/index.md Outdated
Comment thread packages/plugins/ticker/doc/index.md Outdated
Comment thread packages/plugins/tsup.shared.ts Outdated
Comment thread packages/tempo/src/module/module.format.ts Outdated
Comment thread packages/tempo/src/tempo.class.ts Outdated

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 6

🧹 Nitpick comments (8)
packages/tempo/test/instance/instance.format.test.ts (1)

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

Avoid bypassing the new Tempo.format contract in tests.

The any/string casts prevent these tests from checking whether supported Intl options and plugin tokens are accepted by the new overloads. Prefer properly typed fixtures, augment TempoFormatTokens for myDay, or add dedicated type-level assertions while keeping the runtime calls uncast.

Also applies to: 80-80, 96-97

🤖 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 `@packages/tempo/test/instance/instance.format.test.ts` at line 63, Update the
tests around the uncast runtime calls to use properly typed Arabic and option
fixtures that exercise the new Tempo.format overloads. Remove the any/string
casts, and augment TempoFormatTokens with the myDay token where needed or add
dedicated type-level assertions so supported Intl options and plugin tokens are
validated by the compiler.
packages/library/src/common/storage.library.ts (1)

15-15: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Restore trailing semicolons for variable declarations.

While automatic semicolon insertion (ASI) usually handles this, it is considered best practice (and often enforced by linters/formatters) to include trailing semicolons at the end of variable declarations assigning objects or arrow functions.

♻️ Proposed fixes

For mockStorage:

- }
+ };

For getSafeStorage:

- }
+ };

Also applies to: 24-24

🤖 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 `@packages/library/src/common/storage.library.ts` at line 15, Restore trailing
semicolons on the variable declarations for mockStorage and getSafeStorage,
including declarations assigning objects or arrow functions. Apply the same
formatting at both referenced locations without changing their behavior.
packages/functions/src/duration/normaliseFractionalDurations.ts (1)

15-24: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Intermediate Math.round drops precision that could cascade.

Rounding frac * factor at every level discards sub-unit remainder instead of letting it flow into the next smaller unit on the following iteration. For example { minutes: 1.51 } yields { minutes: 1, seconds: 31 } (round(30.6)), losing ~600ms that should have cascaded to milliseconds. Since each small unit is re-examined as the next big, adding the un-rounded contribution for non-terminal units (and rounding only the terminal nanoseconds) preserves accuracy.

🤖 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 `@packages/functions/src/duration/normaliseFractionalDurations.ts` around lines
15 - 24, Update the fractional conversion loop in the SCALE iteration to avoid
rounding payload[small] at intermediate units, allowing fractional remainders to
cascade into progressively smaller units. Preserve whole-unit handling, but
round only the contribution when converting into the terminal nanoseconds unit;
keep intermediate conversions unrounded so values such as fractional minutes
retain their precision.
packages/functions/src/scheduling/cron.ts (1)

89-89: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Iteration bound 5 * 366 doesn't guarantee a 5-year search window.

The loop advances by month, day, hour, or minute depending on which check fails, so 1830 iterations cover far less than 5 wall-clock years in the worst case (a match ~5 years out reached mainly via day-stepping already consumes ~1826 iterations, before any hour/minute steps). This can throw a spurious "could not find match" for a valid schedule. Bound the search by elapsed time (e.g. compare current against a +5 years limit) rather than a fixed iteration count.

  • packages/functions/src/scheduling/cron.ts#L89-L89: replace the fixed 5 * 366 iteration cap in nextCron with a time-based limit (stop when current exceeds start + 5 years).
  • packages/functions/src/scheduling/cron.ts#L124-L124: apply the mirrored fix in prevCron (stop when current falls below start - 5 years).
🤖 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 `@packages/functions/src/scheduling/cron.ts` at line 89, Replace the fixed
iteration caps in nextCron (packages/functions/src/scheduling/cron.ts, lines
89-89) and prevCron (packages/functions/src/scheduling/cron.ts, lines 124-124)
with elapsed-time bounds: stop nextCron when current exceeds start plus 5 years,
and stop prevCron when current falls below start minus 5 years. Preserve the
existing matching and failure behavior within those windows.
packages/functions/bin/sync-docs.mjs (1)

9-11: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Exclude internal directories from being synced to public docs.

The support directory is documented as internal, but this loop will inadvertently sync src/support/README.md to doc/functions/support/index.md. Since a separate doc/support.md file exists in the codebase, this may result in duplicate or unintended public documentation.

Consider filtering out support and any hidden directories to prevent internal docs from leaking into the generated function documentation site.

♻️ Proposed fix
 const categories = fs.readdirSync(srcDir, { withFileTypes: true })
-	.filter(dirent => dirent.isDirectory())
+	.filter(dirent => dirent.isDirectory() && dirent.name !== 'support' && !dirent.name.startsWith('.'))
 	.map(dirent => dirent.name);
🤖 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 `@packages/functions/bin/sync-docs.mjs` around lines 9 - 11, Update the
categories construction in the sync-docs flow to exclude the internal support
directory and hidden directories before mapping their names. Preserve syncing
for visible public category directories, while preventing support and any
directory whose name begins with “.” from reaching the documentation generation
loop.
packages/functions/doc/README.md (1)

5-8: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Update the logo alt text.

The alt text on the logo image still references the old Tempo-fns name. Consider updating it to match the new package name.

🔨 Proposed fix
-        <img src="../img/functions-logo.svg" width="90" height="90" alt="Tempo-fns Logo">
+        <img src="../img/functions-logo.svg" width="90" height="90" alt="Functions Logo">
       </td>
       <td valign="middle">
         <h1 style="border-bottom: none; margin-bottom: 0;"><code>`@magmacomputing/functions`</code></h1>
🤖 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 `@packages/functions/doc/README.md` around lines 5 - 8, Update the logo image’s
alt attribute in the README header to use the new `@magmacomputing/functions`
package name instead of the outdated Tempo-fns text; leave the image source and
surrounding markup unchanged.
packages/functions/README.md (1)

5-5: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Update the logo image's alt text.

The alt attribute still references the old name "Tempo-fns Logo".

🖼️ Proposed fix
-        <img src="../img/functions-logo.svg" width="90" height="90" alt="Tempo-fns Logo">
+        <img src="../img/functions-logo.svg" width="90" height="90" alt="Functions Logo">
🤖 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 `@packages/functions/README.md` at line 5, Update the alt attribute on the logo
img element in the README to use the current project name instead of the
outdated “Tempo-fns Logo” text, preserving the existing image source and
dimensions.
packages/functions/src/business/workingHoursUntil.ts (1)

42-42: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Update error message prefix to match the new package name.

The error message still uses the old [Tempo-Fns] prefix, whereas the warning log on line 104 was updated to [functions].

💡 Proposed fix
-		throw new Error('[Tempo-Fns] startHour must be strictly less than endHour');
+		throw new Error('[functions] startHour must be strictly less than endHour');
🤖 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 `@packages/functions/src/business/workingHoursUntil.ts` at line 42, Update the
error message in workingHoursUntil to use the new “[functions]” prefix instead
of “[Tempo-Fns]”, matching the existing warning log prefix while preserving the
rest of the validation message.
🤖 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 @.github/workflows/ci.yml:
- Around line 15-17: Update the workflow permissions used by the job running
actions/checkout@v4 so repository contents have read access instead of none,
ensuring checkout can fetch the code while preserving the minimal permission
scope.

In `@packages/functions/doc/preview.html`:
- Around line 15-16: Regenerate the embedded base64 payload assigned to markdown
in the preview HTML from the current rebranded functions README, replacing the
deprecated tempo-fns README content, logo paths, package references, and CDN
links while leaving the marked.parse rendering flow unchanged.

In `@packages/functions/rollup.config.js`:
- Around line 5-11: Update the Rollup output configuration to use the functions
branding: change the IIFE bundle filename from tempo-fns.global.js to
functions.global.js and expose it through the Functions global name instead of
TempoFns. Preserve the existing format and globals mapping.

In `@packages/functions/src/timezone/isDST.ts`:
- Around line 9-14: Update the string-handling fallback in the timezone
conversion flow to try TemporalAPI.PlainDateTime.from(date) and convert it with
the requested timeZone before falling back to TemporalAPI.PlainDate.from(date).
Preserve the existing Instant.from(date) path and ensure date-only strings still
use the PlainDate fallback.

In `@packages/functions/src/timezone/normalizeUtcOffset.ts`:
- Around line 15-16: Update the range validation condition in normalizeUtcOffset
so negative offsets at 12 hours are rejected when minutes are greater than zero,
enforcing the lower bound of -12:00 while preserving valid offsets through
-12:00 and the existing +14:00 checks.

In `@packages/tempo/bin/harvest-plugins.mjs`:
- Around line 45-49: Update the link-rewrite regexes in
packages/tempo/bin/harvest-plugins.mjs (lines 45-49) to optionally capture and
preserve trailing query strings or hash fragments for both local and
cross-plugin links. Also update the markdown-link rewrite logic in
packages/tempo/.vitepress/config.ts (lines 142-150) to capture the URL remainder
after .md and append it to the rewritten href, preserving hashes and queries.

---

Nitpick comments:
In `@packages/functions/bin/sync-docs.mjs`:
- Around line 9-11: Update the categories construction in the sync-docs flow to
exclude the internal support directory and hidden directories before mapping
their names. Preserve syncing for visible public category directories, while
preventing support and any directory whose name begins with “.” from reaching
the documentation generation loop.

In `@packages/functions/doc/README.md`:
- Around line 5-8: Update the logo image’s alt attribute in the README header to
use the new `@magmacomputing/functions` package name instead of the outdated
Tempo-fns text; leave the image source and surrounding markup unchanged.

In `@packages/functions/README.md`:
- Line 5: Update the alt attribute on the logo img element in the README to use
the current project name instead of the outdated “Tempo-fns Logo” text,
preserving the existing image source and dimensions.

In `@packages/functions/src/business/workingHoursUntil.ts`:
- Line 42: Update the error message in workingHoursUntil to use the new
“[functions]” prefix instead of “[Tempo-Fns]”, matching the existing warning log
prefix while preserving the rest of the validation message.

In `@packages/functions/src/duration/normaliseFractionalDurations.ts`:
- Around line 15-24: Update the fractional conversion loop in the SCALE
iteration to avoid rounding payload[small] at intermediate units, allowing
fractional remainders to cascade into progressively smaller units. Preserve
whole-unit handling, but round only the contribution when converting into the
terminal nanoseconds unit; keep intermediate conversions unrounded so values
such as fractional minutes retain their precision.

In `@packages/functions/src/scheduling/cron.ts`:
- Line 89: Replace the fixed iteration caps in nextCron
(packages/functions/src/scheduling/cron.ts, lines 89-89) and prevCron
(packages/functions/src/scheduling/cron.ts, lines 124-124) with elapsed-time
bounds: stop nextCron when current exceeds start plus 5 years, and stop prevCron
when current falls below start minus 5 years. Preserve the existing matching and
failure behavior within those windows.

In `@packages/library/src/common/storage.library.ts`:
- Line 15: Restore trailing semicolons on the variable declarations for
mockStorage and getSafeStorage, including declarations assigning objects or
arrow functions. Apply the same formatting at both referenced locations without
changing their behavior.

In `@packages/tempo/test/instance/instance.format.test.ts`:
- Line 63: Update the tests around the uncast runtime calls to use properly
typed Arabic and option fixtures that exercise the new Tempo.format overloads.
Remove the any/string casts, and augment TempoFormatTokens with the myDay token
where needed or add dedicated type-level assertions so supported Intl options
and plugin tokens are validated by the compiler.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9861a964-967b-495d-8860-92af29c03634

📥 Commits

Reviewing files that changed from the base of the PR and between 2133ef0 and 7e0e362.

⛔ Files ignored due to path filters (3)
  • package-lock.json is excluded by !**/package-lock.json
  • packages/functions/doc/public/img/functions-logo.svg is excluded by !**/*.svg
  • packages/functions/img/functions-logo.svg is excluded by !**/*.svg
📒 Files selected for processing (81)
  • .github/workflows/ci.yml
  • .github/workflows/deploy-docs.yml
  • .gitignore
  • package.json
  • packages/functions/CHANGELOG.md
  • packages/functions/LICENSE
  • packages/functions/README.md
  • packages/functions/bin/sync-docs.mjs
  • packages/functions/doc/.vitepress/config.mts
  • packages/functions/doc/CONTRIBUTING.md
  • packages/functions/doc/README.md
  • packages/functions/doc/functions/business/index.md
  • packages/functions/doc/functions/calendar/index.md
  • packages/functions/doc/functions/duration/index.md
  • packages/functions/doc/functions/index.md
  • packages/functions/doc/functions/scheduling/Interval.md
  • packages/functions/doc/functions/scheduling/cron.md
  • packages/functions/doc/functions/scheduling/index.md
  • packages/functions/doc/functions/timezone/index.md
  • packages/functions/doc/index.md
  • packages/functions/doc/preview.html
  • packages/functions/doc/support.md
  • packages/functions/package.json
  • packages/functions/rollup.config.js
  • packages/functions/src/business/README.md
  • packages/functions/src/business/isSameFiscalQuarter.ts
  • packages/functions/src/business/workingHoursUntil.ts
  • packages/functions/src/calendar/README.md
  • packages/functions/src/calendar/getISOWeekOfYear.ts
  • packages/functions/src/calendar/getPublicHolidays.ts
  • packages/functions/src/calendar/isFirstDayOfMonth.ts
  • packages/functions/src/duration/README.md
  • packages/functions/src/duration/normaliseFractionalDurations.ts
  • packages/functions/src/index.ts
  • packages/functions/src/scheduling/README.md
  • packages/functions/src/scheduling/cron.ts
  • packages/functions/src/support/README.md
  • packages/functions/src/support/assert.ts
  • packages/functions/src/support/fetch.ts
  • packages/functions/src/support/index.ts
  • packages/functions/src/support/intl.ts
  • packages/functions/src/support/temporal.ts
  • packages/functions/src/timezone/README.md
  • packages/functions/src/timezone/getHemisphere.ts
  • packages/functions/src/timezone/getOffsets.ts
  • packages/functions/src/timezone/isDST.ts
  • packages/functions/src/timezone/normalizeUtcOffset.ts
  • packages/functions/test/business/isSameFiscalQuarter.test.ts
  • packages/functions/test/business/workingHoursUntil.test.ts
  • packages/functions/test/calendar/isFirstDayOfMonth.test.ts
  • packages/functions/test/scheduling/cron.test.ts
  • packages/functions/test/setup.ts
  • packages/functions/test/tsconfig.json
  • packages/functions/tsconfig.json
  • packages/functions/vitest.config.ts
  • packages/library/package.json
  • packages/library/src/common/storage.library.ts
  • packages/plugins/.setup/README.md
  • packages/plugins/.setup/doc/index.md
  • packages/plugins/ticker/doc/index.md
  • packages/plugins/tsup.shared.ts
  • packages/tempo/.vitepress/config.ts
  • packages/tempo/CHANGELOG.md
  • packages/tempo/README.md
  • packages/tempo/bin/harvest-plugins.mjs
  • packages/tempo/doc/1-getting-started/tempo.cookbook.md
  • packages/tempo/doc/3-extending-tempo/tempo.plugin.md
  • packages/tempo/doc/8-project-and-support/commercial.md
  • packages/tempo/doc/9-plugins/astro.md
  • packages/tempo/doc/9-plugins/batch.md
  • packages/tempo/doc/9-plugins/finance.md
  • packages/tempo/doc/9-plugins/snap.md
  • packages/tempo/doc/9-plugins/sync.md
  • packages/tempo/doc/9-plugins/ticker.md
  • packages/tempo/package.json
  • packages/tempo/plan/refactor-path-terms.md
  • packages/tempo/src/module/module.format.ts
  • packages/tempo/src/tempo.class.ts
  • packages/tempo/src/tempo.type.ts
  • packages/tempo/src/tempo.version.ts
  • packages/tempo/test/instance/instance.format.test.ts
💤 Files with no reviewable changes (6)
  • packages/tempo/doc/9-plugins/astro.md
  • packages/tempo/doc/9-plugins/snap.md
  • packages/tempo/doc/9-plugins/sync.md
  • packages/tempo/doc/9-plugins/batch.md
  • packages/tempo/doc/9-plugins/finance.md
  • packages/tempo/doc/9-plugins/ticker.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/plugins/ticker/doc/index.md
  • packages/tempo/src/module/module.format.ts
  • packages/plugins/tsup.shared.ts
  • packages/tempo/src/tempo.type.ts

@coderabbitai coderabbitai Bot left a comment

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.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 6

🧹 Nitpick comments (8)
packages/tempo/test/instance/instance.format.test.ts (1)

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

Avoid bypassing the new Tempo.format contract in tests.

The any/string casts prevent these tests from checking whether supported Intl options and plugin tokens are accepted by the new overloads. Prefer properly typed fixtures, augment TempoFormatTokens for myDay, or add dedicated type-level assertions while keeping the runtime calls uncast.

Also applies to: 80-80, 96-97

🤖 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 `@packages/tempo/test/instance/instance.format.test.ts` at line 63, Update the
tests around the uncast runtime calls to use properly typed Arabic and option
fixtures that exercise the new Tempo.format overloads. Remove the any/string
casts, and augment TempoFormatTokens with the myDay token where needed or add
dedicated type-level assertions so supported Intl options and plugin tokens are
validated by the compiler.
packages/library/src/common/storage.library.ts (1)

15-15: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Restore trailing semicolons for variable declarations.

While automatic semicolon insertion (ASI) usually handles this, it is considered best practice (and often enforced by linters/formatters) to include trailing semicolons at the end of variable declarations assigning objects or arrow functions.

♻️ Proposed fixes

For mockStorage:

- }
+ };

For getSafeStorage:

- }
+ };

Also applies to: 24-24

🤖 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 `@packages/library/src/common/storage.library.ts` at line 15, Restore trailing
semicolons on the variable declarations for mockStorage and getSafeStorage,
including declarations assigning objects or arrow functions. Apply the same
formatting at both referenced locations without changing their behavior.
packages/functions/src/duration/normaliseFractionalDurations.ts (1)

15-24: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Intermediate Math.round drops precision that could cascade.

Rounding frac * factor at every level discards sub-unit remainder instead of letting it flow into the next smaller unit on the following iteration. For example { minutes: 1.51 } yields { minutes: 1, seconds: 31 } (round(30.6)), losing ~600ms that should have cascaded to milliseconds. Since each small unit is re-examined as the next big, adding the un-rounded contribution for non-terminal units (and rounding only the terminal nanoseconds) preserves accuracy.

🤖 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 `@packages/functions/src/duration/normaliseFractionalDurations.ts` around lines
15 - 24, Update the fractional conversion loop in the SCALE iteration to avoid
rounding payload[small] at intermediate units, allowing fractional remainders to
cascade into progressively smaller units. Preserve whole-unit handling, but
round only the contribution when converting into the terminal nanoseconds unit;
keep intermediate conversions unrounded so values such as fractional minutes
retain their precision.
packages/functions/src/scheduling/cron.ts (1)

89-89: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Iteration bound 5 * 366 doesn't guarantee a 5-year search window.

The loop advances by month, day, hour, or minute depending on which check fails, so 1830 iterations cover far less than 5 wall-clock years in the worst case (a match ~5 years out reached mainly via day-stepping already consumes ~1826 iterations, before any hour/minute steps). This can throw a spurious "could not find match" for a valid schedule. Bound the search by elapsed time (e.g. compare current against a +5 years limit) rather than a fixed iteration count.

  • packages/functions/src/scheduling/cron.ts#L89-L89: replace the fixed 5 * 366 iteration cap in nextCron with a time-based limit (stop when current exceeds start + 5 years).
  • packages/functions/src/scheduling/cron.ts#L124-L124: apply the mirrored fix in prevCron (stop when current falls below start - 5 years).
🤖 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 `@packages/functions/src/scheduling/cron.ts` at line 89, Replace the fixed
iteration caps in nextCron (packages/functions/src/scheduling/cron.ts, lines
89-89) and prevCron (packages/functions/src/scheduling/cron.ts, lines 124-124)
with elapsed-time bounds: stop nextCron when current exceeds start plus 5 years,
and stop prevCron when current falls below start minus 5 years. Preserve the
existing matching and failure behavior within those windows.
packages/functions/bin/sync-docs.mjs (1)

9-11: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Exclude internal directories from being synced to public docs.

The support directory is documented as internal, but this loop will inadvertently sync src/support/README.md to doc/functions/support/index.md. Since a separate doc/support.md file exists in the codebase, this may result in duplicate or unintended public documentation.

Consider filtering out support and any hidden directories to prevent internal docs from leaking into the generated function documentation site.

♻️ Proposed fix
 const categories = fs.readdirSync(srcDir, { withFileTypes: true })
-	.filter(dirent => dirent.isDirectory())
+	.filter(dirent => dirent.isDirectory() && dirent.name !== 'support' && !dirent.name.startsWith('.'))
 	.map(dirent => dirent.name);
🤖 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 `@packages/functions/bin/sync-docs.mjs` around lines 9 - 11, Update the
categories construction in the sync-docs flow to exclude the internal support
directory and hidden directories before mapping their names. Preserve syncing
for visible public category directories, while preventing support and any
directory whose name begins with “.” from reaching the documentation generation
loop.
packages/functions/doc/README.md (1)

5-8: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Update the logo alt text.

The alt text on the logo image still references the old Tempo-fns name. Consider updating it to match the new package name.

🔨 Proposed fix
-        <img src="../img/functions-logo.svg" width="90" height="90" alt="Tempo-fns Logo">
+        <img src="../img/functions-logo.svg" width="90" height="90" alt="Functions Logo">
       </td>
       <td valign="middle">
         <h1 style="border-bottom: none; margin-bottom: 0;"><code>`@magmacomputing/functions`</code></h1>
🤖 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 `@packages/functions/doc/README.md` around lines 5 - 8, Update the logo image’s
alt attribute in the README header to use the new `@magmacomputing/functions`
package name instead of the outdated Tempo-fns text; leave the image source and
surrounding markup unchanged.
packages/functions/README.md (1)

5-5: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Update the logo image's alt text.

The alt attribute still references the old name "Tempo-fns Logo".

🖼️ Proposed fix
-        <img src="../img/functions-logo.svg" width="90" height="90" alt="Tempo-fns Logo">
+        <img src="../img/functions-logo.svg" width="90" height="90" alt="Functions Logo">
🤖 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 `@packages/functions/README.md` at line 5, Update the alt attribute on the logo
img element in the README to use the current project name instead of the
outdated “Tempo-fns Logo” text, preserving the existing image source and
dimensions.
packages/functions/src/business/workingHoursUntil.ts (1)

42-42: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Update error message prefix to match the new package name.

The error message still uses the old [Tempo-Fns] prefix, whereas the warning log on line 104 was updated to [functions].

💡 Proposed fix
-		throw new Error('[Tempo-Fns] startHour must be strictly less than endHour');
+		throw new Error('[functions] startHour must be strictly less than endHour');
🤖 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 `@packages/functions/src/business/workingHoursUntil.ts` at line 42, Update the
error message in workingHoursUntil to use the new “[functions]” prefix instead
of “[Tempo-Fns]”, matching the existing warning log prefix while preserving the
rest of the validation message.
🤖 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 @.github/workflows/ci.yml:
- Around line 15-17: Update the workflow permissions used by the job running
actions/checkout@v4 so repository contents have read access instead of none,
ensuring checkout can fetch the code while preserving the minimal permission
scope.

In `@packages/functions/doc/preview.html`:
- Around line 15-16: Regenerate the embedded base64 payload assigned to markdown
in the preview HTML from the current rebranded functions README, replacing the
deprecated tempo-fns README content, logo paths, package references, and CDN
links while leaving the marked.parse rendering flow unchanged.

In `@packages/functions/rollup.config.js`:
- Around line 5-11: Update the Rollup output configuration to use the functions
branding: change the IIFE bundle filename from tempo-fns.global.js to
functions.global.js and expose it through the Functions global name instead of
TempoFns. Preserve the existing format and globals mapping.

In `@packages/functions/src/timezone/isDST.ts`:
- Around line 9-14: Update the string-handling fallback in the timezone
conversion flow to try TemporalAPI.PlainDateTime.from(date) and convert it with
the requested timeZone before falling back to TemporalAPI.PlainDate.from(date).
Preserve the existing Instant.from(date) path and ensure date-only strings still
use the PlainDate fallback.

In `@packages/functions/src/timezone/normalizeUtcOffset.ts`:
- Around line 15-16: Update the range validation condition in normalizeUtcOffset
so negative offsets at 12 hours are rejected when minutes are greater than zero,
enforcing the lower bound of -12:00 while preserving valid offsets through
-12:00 and the existing +14:00 checks.

In `@packages/tempo/bin/harvest-plugins.mjs`:
- Around line 45-49: Update the link-rewrite regexes in
packages/tempo/bin/harvest-plugins.mjs (lines 45-49) to optionally capture and
preserve trailing query strings or hash fragments for both local and
cross-plugin links. Also update the markdown-link rewrite logic in
packages/tempo/.vitepress/config.ts (lines 142-150) to capture the URL remainder
after .md and append it to the rewritten href, preserving hashes and queries.

---

Nitpick comments:
In `@packages/functions/bin/sync-docs.mjs`:
- Around line 9-11: Update the categories construction in the sync-docs flow to
exclude the internal support directory and hidden directories before mapping
their names. Preserve syncing for visible public category directories, while
preventing support and any directory whose name begins with “.” from reaching
the documentation generation loop.

In `@packages/functions/doc/README.md`:
- Around line 5-8: Update the logo image’s alt attribute in the README header to
use the new `@magmacomputing/functions` package name instead of the outdated
Tempo-fns text; leave the image source and surrounding markup unchanged.

In `@packages/functions/README.md`:
- Line 5: Update the alt attribute on the logo img element in the README to use
the current project name instead of the outdated “Tempo-fns Logo” text,
preserving the existing image source and dimensions.

In `@packages/functions/src/business/workingHoursUntil.ts`:
- Line 42: Update the error message in workingHoursUntil to use the new
“[functions]” prefix instead of “[Tempo-Fns]”, matching the existing warning log
prefix while preserving the rest of the validation message.

In `@packages/functions/src/duration/normaliseFractionalDurations.ts`:
- Around line 15-24: Update the fractional conversion loop in the SCALE
iteration to avoid rounding payload[small] at intermediate units, allowing
fractional remainders to cascade into progressively smaller units. Preserve
whole-unit handling, but round only the contribution when converting into the
terminal nanoseconds unit; keep intermediate conversions unrounded so values
such as fractional minutes retain their precision.

In `@packages/functions/src/scheduling/cron.ts`:
- Line 89: Replace the fixed iteration caps in nextCron
(packages/functions/src/scheduling/cron.ts, lines 89-89) and prevCron
(packages/functions/src/scheduling/cron.ts, lines 124-124) with elapsed-time
bounds: stop nextCron when current exceeds start plus 5 years, and stop prevCron
when current falls below start minus 5 years. Preserve the existing matching and
failure behavior within those windows.

In `@packages/library/src/common/storage.library.ts`:
- Line 15: Restore trailing semicolons on the variable declarations for
mockStorage and getSafeStorage, including declarations assigning objects or
arrow functions. Apply the same formatting at both referenced locations without
changing their behavior.

In `@packages/tempo/test/instance/instance.format.test.ts`:
- Line 63: Update the tests around the uncast runtime calls to use properly
typed Arabic and option fixtures that exercise the new Tempo.format overloads.
Remove the any/string casts, and augment TempoFormatTokens with the myDay token
where needed or add dedicated type-level assertions so supported Intl options
and plugin tokens are validated by the compiler.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9861a964-967b-495d-8860-92af29c03634

📥 Commits

Reviewing files that changed from the base of the PR and between 2133ef0 and 7e0e362.

⛔ Files ignored due to path filters (3)
  • package-lock.json is excluded by !**/package-lock.json
  • packages/functions/doc/public/img/functions-logo.svg is excluded by !**/*.svg
  • packages/functions/img/functions-logo.svg is excluded by !**/*.svg
📒 Files selected for processing (81)
  • .github/workflows/ci.yml
  • .github/workflows/deploy-docs.yml
  • .gitignore
  • package.json
  • packages/functions/CHANGELOG.md
  • packages/functions/LICENSE
  • packages/functions/README.md
  • packages/functions/bin/sync-docs.mjs
  • packages/functions/doc/.vitepress/config.mts
  • packages/functions/doc/CONTRIBUTING.md
  • packages/functions/doc/README.md
  • packages/functions/doc/functions/business/index.md
  • packages/functions/doc/functions/calendar/index.md
  • packages/functions/doc/functions/duration/index.md
  • packages/functions/doc/functions/index.md
  • packages/functions/doc/functions/scheduling/Interval.md
  • packages/functions/doc/functions/scheduling/cron.md
  • packages/functions/doc/functions/scheduling/index.md
  • packages/functions/doc/functions/timezone/index.md
  • packages/functions/doc/index.md
  • packages/functions/doc/preview.html
  • packages/functions/doc/support.md
  • packages/functions/package.json
  • packages/functions/rollup.config.js
  • packages/functions/src/business/README.md
  • packages/functions/src/business/isSameFiscalQuarter.ts
  • packages/functions/src/business/workingHoursUntil.ts
  • packages/functions/src/calendar/README.md
  • packages/functions/src/calendar/getISOWeekOfYear.ts
  • packages/functions/src/calendar/getPublicHolidays.ts
  • packages/functions/src/calendar/isFirstDayOfMonth.ts
  • packages/functions/src/duration/README.md
  • packages/functions/src/duration/normaliseFractionalDurations.ts
  • packages/functions/src/index.ts
  • packages/functions/src/scheduling/README.md
  • packages/functions/src/scheduling/cron.ts
  • packages/functions/src/support/README.md
  • packages/functions/src/support/assert.ts
  • packages/functions/src/support/fetch.ts
  • packages/functions/src/support/index.ts
  • packages/functions/src/support/intl.ts
  • packages/functions/src/support/temporal.ts
  • packages/functions/src/timezone/README.md
  • packages/functions/src/timezone/getHemisphere.ts
  • packages/functions/src/timezone/getOffsets.ts
  • packages/functions/src/timezone/isDST.ts
  • packages/functions/src/timezone/normalizeUtcOffset.ts
  • packages/functions/test/business/isSameFiscalQuarter.test.ts
  • packages/functions/test/business/workingHoursUntil.test.ts
  • packages/functions/test/calendar/isFirstDayOfMonth.test.ts
  • packages/functions/test/scheduling/cron.test.ts
  • packages/functions/test/setup.ts
  • packages/functions/test/tsconfig.json
  • packages/functions/tsconfig.json
  • packages/functions/vitest.config.ts
  • packages/library/package.json
  • packages/library/src/common/storage.library.ts
  • packages/plugins/.setup/README.md
  • packages/plugins/.setup/doc/index.md
  • packages/plugins/ticker/doc/index.md
  • packages/plugins/tsup.shared.ts
  • packages/tempo/.vitepress/config.ts
  • packages/tempo/CHANGELOG.md
  • packages/tempo/README.md
  • packages/tempo/bin/harvest-plugins.mjs
  • packages/tempo/doc/1-getting-started/tempo.cookbook.md
  • packages/tempo/doc/3-extending-tempo/tempo.plugin.md
  • packages/tempo/doc/8-project-and-support/commercial.md
  • packages/tempo/doc/9-plugins/astro.md
  • packages/tempo/doc/9-plugins/batch.md
  • packages/tempo/doc/9-plugins/finance.md
  • packages/tempo/doc/9-plugins/snap.md
  • packages/tempo/doc/9-plugins/sync.md
  • packages/tempo/doc/9-plugins/ticker.md
  • packages/tempo/package.json
  • packages/tempo/plan/refactor-path-terms.md
  • packages/tempo/src/module/module.format.ts
  • packages/tempo/src/tempo.class.ts
  • packages/tempo/src/tempo.type.ts
  • packages/tempo/src/tempo.version.ts
  • packages/tempo/test/instance/instance.format.test.ts
💤 Files with no reviewable changes (6)
  • packages/tempo/doc/9-plugins/astro.md
  • packages/tempo/doc/9-plugins/snap.md
  • packages/tempo/doc/9-plugins/sync.md
  • packages/tempo/doc/9-plugins/batch.md
  • packages/tempo/doc/9-plugins/finance.md
  • packages/tempo/doc/9-plugins/ticker.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/plugins/ticker/doc/index.md
  • packages/tempo/src/module/module.format.ts
  • packages/plugins/tsup.shared.ts
  • packages/tempo/src/tempo.type.ts
🛑 Comments failed to post (6)
.github/workflows/ci.yml (1)

15-17: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Update permissions to allow repository checkout.

Setting contents: none at the top level without overriding it at the job level will cause actions/checkout@v4 to fail with a 403 Forbidden error, as it requires contents: read permission to fetch the repository code.

🛠️ Proposed fix
 permissions:
-  contents: none
+  contents: read
🤖 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 @.github/workflows/ci.yml around lines 15 - 17, Update the workflow
permissions used by the job running actions/checkout@v4 so repository contents
have read access instead of none, ensuring checkout can fetch the code while
preserving the minimal permission scope.
packages/functions/doc/preview.html (1)

15-16: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Update the base64 payload to reflect the rebranded functions content.

The embedded base64 markdown string decodes to the older, deprecated tempo-fns README content (including the old logo paths, package name, and CDN links).

To keep the local preview accurate, please regenerate and replace the base64 string with the contents of the newly rebranded functions README.

🧰 Tools
🪛 ast-grep (0.44.1)

[warning] 15-15: Avoid assigning untrusted data to innerHTML/outerHTML or document.write
Context: document.getElementById('content').innerHTML = marked.parse(markdown)
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting').

(inner-outer-html)

🤖 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 `@packages/functions/doc/preview.html` around lines 15 - 16, Regenerate the
embedded base64 payload assigned to markdown in the preview HTML from the
current rebranded functions README, replacing the deprecated tempo-fns README
content, logo paths, package references, and CDN links while leaving the
marked.parse rendering flow unchanged.
packages/functions/rollup.config.js (1)

5-11: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Align IIFE bundle name and filename with the new functions branding.

The Rollup configuration still outputs the bundle as dist/tempo-fns.global.js with the global variable name TempoFns. However, the documentation and README.md expect the file to be dist/functions.global.js and expose a Functions global object.

🔧 Proposed fix
 	output: {
-		file: 'dist/tempo-fns.global.js',
+		file: 'dist/functions.global.js',
 		format: 'iife',
-		name: 'TempoFns',
+		name: 'Functions',
 		globals: {
📝 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.

	output: {
		file: 'dist/functions.global.js',
		format: 'iife',
		name: 'Functions',
		globals: {
			'`@magmacomputing/tempo`': 'Tempo'
		}
🤖 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 `@packages/functions/rollup.config.js` around lines 5 - 11, Update the Rollup
output configuration to use the functions branding: change the IIFE bundle
filename from tempo-fns.global.js to functions.global.js and expose it through
the Functions global name instead of TempoFns. Preserve the existing format and
globals mapping.
packages/functions/src/timezone/isDST.ts (1)

9-14: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
node -e '
try {
  const { Temporal } = require("`@js-temporal/polyfill`");
  const str = "2024-03-10T12:00:00";
  
  const pd = Temporal.PlainDate.from(str).toZonedDateTime("America/New_York");
  console.log("PlainDate evaluated at:", pd.toString()); // Incorrectly evaluates at midnight
  
  const pdt = Temporal.PlainDateTime.from(str).toZonedDateTime("America/New_York");
  console.log("PlainDateTime evaluated at:", pdt.toString()); // Preserves 12:00
} catch (e) {
  console.log("Polyfill not in sandbox, but the spec behaves as described.");
}
'

Repository: magmacomputing/magma

Length of output: 298


Preserve time components for string inputs without an offset. Temporal.PlainDate.from(date) drops the time portion, so 2024-03-10T12:00:00 is evaluated at midnight. On DST transition days that can return the wrong result; try Temporal.PlainDateTime.from(date) first, then fall back to PlainDate.

🤖 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 `@packages/functions/src/timezone/isDST.ts` around lines 9 - 14, Update the
string-handling fallback in the timezone conversion flow to try
TemporalAPI.PlainDateTime.from(date) and convert it with the requested timeZone
before falling back to TemporalAPI.PlainDate.from(date). Preserve the existing
Instant.from(date) path and ensure date-only strings still use the PlainDate
fallback.
packages/functions/src/timezone/normalizeUtcOffset.ts (1)

15-16: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Enforce the stated lower bound of -12:00.

The comment specifies a valid range of -12:00 .. +14:00. However, the current check (sign === '-' && h > 12) erroneously permits offsets like -12:30 (since h = 12 is not strictly greater than 12), which bypasses the -12:00 bound.

Update the condition to reject minutes greater than 0 when sign is '-' and hours is 12.

🐛 Proposed fix
 	// Temporal-valid range: -12:00 .. +14:00, minutes 0..59
-	if (h > 14 || m > 59 || (sign === '+' && h === 14 && m !== 0) || (sign === '-' && h > 12)) return zone;
+	if (h > 14 || m > 59 || (sign === '+' && h === 14 && m !== 0) || (sign === '-' && (h > 12 || (h === 12 && m !== 0)))) return zone;
📝 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.

	// Temporal-valid range: -12:00 .. +14:00, minutes 0..59
	if (h > 14 || m > 59 || (sign === '+' && h === 14 && m !== 0) || (sign === '-' && (h > 12 || (h === 12 && m !== 0)))) return zone;
🤖 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 `@packages/functions/src/timezone/normalizeUtcOffset.ts` around lines 15 - 16,
Update the range validation condition in normalizeUtcOffset so negative offsets
at 12 hours are rejected when minutes are greater than zero, enforcing the lower
bound of -12:00 while preserving valid offsets through -12:00 and the existing
+14:00 checks.
packages/tempo/bin/harvest-plugins.mjs (1)

45-49: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Preserve URL hashes and query parameters in markdown links.

Both the documentation harvest script and the VitePress markdown config rewrite plugin documentation links, but their regular expressions fail to account for #hash or ?query suffixes.

  • In harvest-plugins.mjs, links like [text](./other.md#section) will not match the regex (which strictly requires \.md\)), leaving them un-rewritten and causing broken links in VitePress.

  • In config.ts, the regex matches up to .md but ignores the suffix, meaning section anchors are stripped from the final generated link.

  • packages/tempo/bin/harvest-plugins.mjs#L45-L49: Update the regexes to optionally match and preserve trailing hashes/queries.

  • packages/tempo/.vitepress/config.ts#L142-L150: Update the regex to capture the remainder of the URL and append it to the rewritten href.

🛠️ Proposed fixes for both files

For packages/tempo/bin/harvest-plugins.mjs:

-    content = content.replace(/\]\(\.\/([^/]+)\.md\)/g, `](./${pluginId}.$1.md)`);
+    content = content.replace(/\]\(\.\/([^/#?)]+)\.md([#?][^)]*)?\)/g, (_m, f, suffix) => `](./${pluginId}.${f}.md${suffix || ''})`);

     // Rewrite cross-plugin relative links so they work in VitePress
     // Maps: ../../[plugin-dir]/doc/[filename].md -> ./[normalised-pluginId].[filename].md
-    content = content.replace(/\]\(\.\.\/\.\.\/([^/]+)\/doc\/([^/]+)\.md\)/g, (_m, p, f) => `](./${p.replace(/^\./, '_')}.${f}.md)`);
+    content = content.replace(/\]\(\.\.\/\.\.\/([^/]+)\/doc\/([^/#?)]+)\.md([#?][^)]*)?\)/g, (_m, p, f, suffix) => `](./${p.replace(/^\./, '_')}.${f}.md${suffix || ''})`);

For packages/tempo/.vitepress/config.ts:

-          const match = href.match(/(?:\.\.\/)+plugins\/([^\/]+)\/doc\/([^/]+)\.md/);
+          const match = href.match(/(?:\.\.\/)+plugins\/([^\/]+)\/doc\/([^/#?]+)\.md(.*)/);
           if (match) {
             // Normalise: replace leading dot with underscore (mirrors harvest-plugins.mjs)
             // e.g. '.setup' -> '_setup', 'ticker' -> 'ticker'
             // Using '_' (not stripping) avoids silent collision between '.setup/' and 'setup/'.
             const pluginId = match[1].replace(/^\./, '_');
             // Rewrite the href to point to the absolute harvested VitePress path
-            hrefAttr[1] = `/doc/9-plugins/${pluginId}.${match[2]}.md`;
+            hrefAttr[1] = `/doc/9-plugins/${pluginId}.${match[2]}.md${match[3] || ''}`;
           }
📝 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.

    content = content.replace(/\]\(\.\/([^/#?)]+)\.md([#?][^)]*)?\)/g, (_m, f, suffix) => `](./${pluginId}.${f}.md${suffix || ''})`);

    // Rewrite cross-plugin relative links so they work in VitePress
    // Maps: ../../[plugin-dir]/doc/[filename].md -> ./[normalised-pluginId].[filename].md
    content = content.replace(/\]\(\.\.\/\.\.\/([^/]+)\/doc\/([^/#?)]+)\.md([#?][^)]*)?\)/g, (_m, p, f, suffix) => `](./${p.replace(/^\./, '_')}.${f}.md${suffix || ''})`);
📍 Affects 2 files
  • packages/tempo/bin/harvest-plugins.mjs#L45-L49 (this comment)
  • packages/tempo/.vitepress/config.ts#L142-L150
🤖 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 `@packages/tempo/bin/harvest-plugins.mjs` around lines 45 - 49, Update the
link-rewrite regexes in packages/tempo/bin/harvest-plugins.mjs (lines 45-49) to
optionally capture and preserve trailing query strings or hash fragments for
both local and cross-plugin links. Also update the markdown-link rewrite logic
in packages/tempo/.vitepress/config.ts (lines 142-150) to capture the URL
remainder after .md and append it to the rewritten href, preserving hashes and
queries.

@coderabbitai coderabbitai Bot left a comment

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
.github/workflows/deploy-docs.yml (1)

54-60: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Build the functions workspace before copying its docs.

The workflow still runs docs:build for @magmacomputing/tempo-fns, while the merge step reads from packages/functions/doc/.vitepress/dist. This can fail because the old workspace no longer exists, or produce a missing/empty functions output. Rename the step and target the functions workspace instead.

Proposed fix
-      - name: Build Tempo-Fns Docs
-        run: npm run docs:build --workspace=`@magmacomputing/tempo-fns`
+      - name: Build Functions Docs
+        run: npm run docs:build --workspace=`@magmacomputing/functions`
🤖 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 @.github/workflows/deploy-docs.yml around lines 54 - 60, Update the
documentation build step currently named “Build Tempo-Fns Docs” to build the
functions workspace that produces packages/functions/doc/.vitepress/dist, and
rename the step to reflect that workspace. Keep the subsequent “Merge
Documentation Sites” copy source unchanged.
packages/functions/doc/CONTRIBUTING.md (1)

57-57: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the obsolete CI disclaimer.

This says automated CI is unavailable, but this PR adds CI jobs that run the functions tests. Update the contributor instructions to describe the current CI workflow.

Proposed wording
-Once your files are structured correctly, submit a PR to the `magma` monorepo! Please ensure you run the tests and linter locally before submitting, as our automated CI pipeline is not yet available for this initial release.
+Once your files are structured correctly, submit a PR to the `magma` monorepo. Please run the tests and linter locally; CI will also validate the relevant workspace jobs.
🤖 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 `@packages/functions/doc/CONTRIBUTING.md` at line 57, Update the contributor
instructions in CONTRIBUTING.md to remove the obsolete statement that automated
CI is unavailable. Revise the submission guidance to reflect that CI now runs
the functions tests, while retaining the instruction to run tests and lint
locally if still applicable.
packages/functions/doc/functions/scheduling/cron.md (1)

42-42: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Export parseCron from the package root or fix this import.

packages/functions/src/index.ts exports nextCron and prevCron, but not parseCron; this example will fail when copied. Use a supported subpath or add parseCron to the root barrel.

🤖 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 `@packages/functions/doc/functions/scheduling/cron.md` at line 42, Fix the cron
documentation example’s parseCron import by either switching it to a supported
package subpath or exporting parseCron from the package root barrel alongside
nextCron and prevCron in packages/functions/src/index.ts; ensure the copied
example resolves successfully.
🤖 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.

Outside diff comments:
In @.github/workflows/deploy-docs.yml:
- Around line 54-60: Update the documentation build step currently named “Build
Tempo-Fns Docs” to build the functions workspace that produces
packages/functions/doc/.vitepress/dist, and rename the step to reflect that
workspace. Keep the subsequent “Merge Documentation Sites” copy source
unchanged.

In `@packages/functions/doc/CONTRIBUTING.md`:
- Line 57: Update the contributor instructions in CONTRIBUTING.md to remove the
obsolete statement that automated CI is unavailable. Revise the submission
guidance to reflect that CI now runs the functions tests, while retaining the
instruction to run tests and lint locally if still applicable.

In `@packages/functions/doc/functions/scheduling/cron.md`:
- Line 42: Fix the cron documentation example’s parseCron import by either
switching it to a supported package subpath or exporting parseCron from the
package root barrel alongside nextCron and prevCron in
packages/functions/src/index.ts; ensure the copied example resolves
successfully.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d6cdcbe3-1878-451f-a1fc-84b63a14d893

📥 Commits

Reviewing files that changed from the base of the PR and between 7e0e362 and 395df43.

📒 Files selected for processing (37)
  • .github/workflows/ci.yml
  • .github/workflows/deploy-docs.yml
  • packages/functions/CHANGELOG.md
  • packages/functions/README.md
  • packages/functions/bin/sync-docs.mjs
  • packages/functions/doc/.vitepress/config.mts
  • packages/functions/doc/CONTRIBUTING.md
  • packages/functions/doc/README.md
  • packages/functions/doc/functions/business/index.md
  • packages/functions/doc/functions/calendar/index.md
  • packages/functions/doc/functions/duration/index.md
  • packages/functions/doc/functions/index.md
  • packages/functions/doc/functions/scheduling/Interval.md
  • packages/functions/doc/functions/scheduling/cron.md
  • packages/functions/doc/functions/scheduling/index.md
  • packages/functions/doc/functions/timezone/index.md
  • packages/functions/doc/index.md
  • packages/functions/doc/support.md
  • packages/functions/rollup.config.js
  • packages/functions/src/business/README.md
  • packages/functions/src/business/workingHoursUntil.ts
  • packages/functions/src/calendar/README.md
  • packages/functions/src/duration/README.md
  • packages/functions/src/duration/normaliseFractionalDurations.ts
  • packages/functions/src/scheduling/README.md
  • packages/functions/src/scheduling/cron.ts
  • packages/functions/src/timezone/README.md
  • packages/functions/src/timezone/isDST.ts
  • packages/functions/src/timezone/normalizeUtcOffset.ts
  • packages/plugins/finance/src/index.ts
  • packages/plugins/snap/src/index.ts
  • packages/tempo/.vitepress/config.ts
  • packages/tempo/bin/harvest-plugins.mjs
  • packages/tempo/src/module/module.format.ts
  • packages/tempo/src/tempo.class.ts
  • packages/tempo/src/tempo.type.ts
  • packages/tempo/test/instance/instance.format.test.ts
🚧 Files skipped from review as they are similar to previous changes (14)
  • packages/functions/rollup.config.js
  • packages/functions/doc/.vitepress/config.mts
  • packages/functions/src/timezone/README.md
  • packages/functions/src/timezone/isDST.ts
  • packages/tempo/.vitepress/config.ts
  • packages/functions/bin/sync-docs.mjs
  • packages/functions/src/duration/normaliseFractionalDurations.ts
  • packages/functions/src/timezone/normalizeUtcOffset.ts
  • packages/tempo/src/tempo.type.ts
  • packages/tempo/src/module/module.format.ts
  • packages/functions/doc/functions/scheduling/Interval.md
  • .github/workflows/ci.yml
  • packages/functions/src/scheduling/cron.ts
  • packages/tempo/bin/harvest-plugins.mjs

@magmacomputing
magmacomputing merged commit 0ef012e into main Jul 17, 2026
5 checks passed
@magmacomputing
magmacomputing deleted the release/plugins branch July 17, 2026 07:17
@coderabbitai coderabbitai Bot mentioned this pull request Jul 20, 2026
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