Skip to content

Feature/tempo pattern compiler#28

Merged
magmacomputing merged 17 commits intomainfrom
feature/tempo-pattern-compiler
May 8, 2026
Merged

Feature/tempo pattern compiler#28
magmacomputing merged 17 commits intomainfrom
feature/tempo-pattern-compiler

Conversation

@magmacomputing
Copy link
Copy Markdown
Owner

@magmacomputing magmacomputing commented May 7, 2026

Guard Builder isolation

Summary by CodeRabbit

Release v2.9.2

  • New Features

    • Improved Temporal handling (broader input support, safer zone/calendar detection)
    • Added Regex prototyping docs for layout previews
  • Bug Fixes

    • Hardening of parsing and alias/term resolution to avoid leakage and shadowing
    • Fixes for prototype-shadowing and symbol mapping issues
  • Improvements

    • Performance and robustness gains via dedicated guard and normalizer components
    • Theme-aware UI color update
  • Documentation

    • Expanded installation, architecture, and main-branch protection guidance

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

Review Change Stack

Warning

Rate limit exceeded

@magmacomputing has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 45 minutes and 48 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b1a9d4e6-f5ba-4366-8672-5ddc0730edd4

📥 Commits

Reviewing files that changed from the base of the PR and between cc57f60 and 4f4e4af.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • package.json
  • packages/tempo/.vitepress/config.ts
  • packages/tempo/doc/releases/v2.x.md
  • packages/tempo/package.json
📝 Walkthrough

Walkthrough

This PR consolidates Tempo's internal module structure (renaming tempo.* to support.*), extracts the Master Guard and Parse Result Normalizer into dedicated engine modules, introduces a spec-resilient getTemporalIds helper for timezone/calendar extraction, migrates parse/format from discrete to module structure, generifies plugin types, and expands documentation for Node.js Temporal support and parse configuration.

Changes

Core Engine, Temporal Resilience & Type Refactoring

Layer / File(s) Summary
Plugin Type Generification
packages/tempo/src/plugin/plugin.type.ts, packages/tempo/src/plugin/plugin.index.ts, packages/tempo/src/plugin/term/term.type.ts, packages/tempo/src/plugin/term/term.util.ts
Plugin, Module, Extension types become generic Plugin<T = any> with polymorphic install(this: T, t: T) signature; term-related types (TermPlugin, TempoTermType, Range, ResolvedRange, Terms) extracted into dedicated term.type.ts module.
Support Module Consolidation
packages/tempo/src/support/support.default.ts, packages/tempo/src/support/support.runtime.ts, packages/tempo/src/plugin/term/*.ts, packages/tempo/src/plugin/plugin.util.ts
Internal imports switched from tempo.* to support.* modules (enums, symbols, utilities) across engine/plugin/runtime modules to reduce fragmentation.
Temporal ID Extraction & Type Detection
packages/library/src/common/assertion.library.ts, packages/library/src/common/temporal.library.ts, packages/library/src/common/temporal.polyfill.ts, packages/library/test/common/temporal_library.test.ts
Type guards updated with optional chaining; toZonedDateTime accepts ISO strings with zone auto-append; getTemporalIds extracts timezone/calendar from multiple Temporal object shapes with fallback defaults; polyfill adds sane-implementation runtime check.
Master Guard Extraction
packages/tempo/src/engine/engine.guard.ts, packages/tempo/test/engine/engine.guard.test.ts
Dedicated MasterGuard interface and createMasterGuard(words) factory implement greedy longest-token matching with bracket-expression and single-character fallback; comprehensive test suite validates allow-list acceptance, rejection, and edge cases.
Parse Result Normalizer Extraction
packages/tempo/src/engine/engine.normalizer.ts
New module exports NormalizerContext, getResolutionContext, normalizeMatch, resolveAliases, and accumulateResult to isolate match normalization, alias resolution with recursion safety, and diagnostic result tracking.
Engine Hardening
packages/tempo/src/engine/engine.alias.ts, packages/tempo/src/engine/engine.pattern.ts, packages/tempo/src/engine/engine.term.ts, packages/tempo/src/engine/engine.composer.ts, packages/tempo/src/module/module.duration.ts
Alias engine logs errors instead of throwing for invalid parents; pattern compiler sanitizes regex group names via character-whitelisting; term/duration/composer modules updated to derive temporal IDs via getTemporalIds for spec resilience.

Parse/Format Module Refactoring & Integration

Layer / File(s) Summary
Module Entry Points
packages/tempo/src/module/module.index.ts, packages/tempo/src/discrete/discrete.index.ts, packages/tempo/src/tempo.index.ts
module.index.ts re-exports parse/format; discrete.index.ts exports removed; tempo.index.ts re-exports from #tempo/module instead of discrete.
Parse Engine Refactoring
packages/tempo/src/module/module.parse.ts
Integrates normalizeMatch and accumulateResult for match processing; updates basis/anchor computation via getTemporalIds; refactors conform flow for timezone/calendar application and Tempo instance temporal ID derivation.
Module Utilities Update
packages/tempo/src/module/module.mutate.ts, packages/tempo/src/module/module.duration.ts
Import paths updated to local term.util; duration module derives timezone/calendar via getTemporalIds for zone comparison; mutate initializes depth and updates unit key construction.
Tempo Class Refactoring
packages/tempo/src/tempo.class.ts
Replaces inline Master Guard with createMasterGuard(wordsList) factory; strengthens Tempo.regexp(...) with lazy per-state PatternCompiler rebinding; adds memoized #temporalIds() helper; tz/cal getters and toNow() derive IDs via getTemporalIds(...) for spec-compliant handling.
Tempo Type & Configuration
packages/tempo/src/tempo.type.ts, packages/tempo/src/plugin/plugin.util.ts, packages/tempo/src/plugin/extend/extend.ticker.ts, packages/tempo/src/plugin/term/term.index.ts
BaseOptions/Discovery plugins updated to TempoPlugin type; Internal.State adds optional patternCompiler; plugin util and extensions updated to use generic Plugin<TempoType> constraints; term index updated for module path alignment.

Tests, Documentation, Configuration & Release

Layer / File(s) Summary
Test Suite Additions
packages/tempo/test/core/tempo_guard.test.ts, packages/tempo/test/support/setup.console-spy.ts, packages/library/test/common/temporal_library.test.ts, packages/tempo/test/engine/engine.guard.test.ts
Adds numeric input bypass verification; console-spy setup formatting consistency; adds Temporal helper tests; guard test suite for master guard behavior.
Build Configuration
packages/tempo/src/tsconfig.json, packages/tempo/test/tsconfig.json, packages/tempo/vitest.config.ts
Path aliases for #tempo/parse, #tempo/format, #tempo/module redirected from discrete/* to module/* in both isDist and source modes; new aliases added for engine/plugin subpaths.
Documentation
packages/tempo/doc/installation.md, packages/tempo/doc/architecture.md, packages/tempo/doc/tempo.layout.md, packages/tempo/doc/tempo.config.md, doc/main_branch_protection.md
Installation guide expands with Node.js --harmony-temporal flag and native-implementation warnings; architecture docs update Master Guard extraction; new Tempo.regexp() section; config docs add layoutOrder/preFilter/planner options; branch protection doc added/expanded.
Release & Package Management
packages/tempo/CHANGELOG.md, packages/tempo/plan/RELEASE-D.md, package.json, packages/library/package.json, packages/tempo/package.json
CHANGELOG adds v2.9.2 entry; RELEASE-D marks guard/normalizer/pattern compiler extraction complete; versions bumped to 2.9.2; root cross-env updated to ^10.1.0; tempo exports rewired; safe npm script added.
UI & Miscellaneous
packages/tempo/index.md, packages/tempo/test/README.md, packages/tempo/test/engine/parse.prefilter.numeric-safety.test.ts, packages/tempo/plan/, doc/main_branch_protection.md
Tempo-btn-brand uses VitePress CSS variables; test README updates for module structure; numeric-safety test comment updated for module path; outdated planning documents cleared; branch protection documentation enhanced.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐰 A master guard now hops with care,

Normalizer sorts each match with flair,
Temporal IDs find their path anew,
Modules consolidated—v2.9.2!

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/tempo-pattern-compiler

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

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

⚠️ Outside diff range comments (1)
packages/tempo/src/engine/engine.alias.ts (1)

83-103: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Invalid parent is logged but still retained — downstream methods will crash.

The constructor sets this.#parent = options.parent ?? null before the instanceof AliasEngine check, and the new else branch only logs when parent is truthy but not an AliasEngine. The invalid reference is still kept on this.#parent, so later code that gates on if (this.#parent) { this.#parent.getPatterns(...) } (line 172–175), this.#parent?.getVersion() (line 181), this.#parent?.getAlias(key) (line 219), and (this.#parent as any).#words (line 247) will throw TypeErrors the next time aliases are registered/resolved. Previously this surfaced as an explicit TypeError at construction; now it only surfaces deep inside parsing.

Either restore the strict throw or null out the parent in the invalid branch so root semantics are actually root semantics.

🛡️ Proposed fix — null out invalid parent so root paths stay root
 		if (this.#parent instanceof AliasEngine) {
 			this.#depth = this.#parent.#depth + 1;
 			this.#state = Object.create(this.#parent.#state);			// create a new state object that inherits from the parent engine's state
 			this.#words = Object.create(this.#parent.#words);			// create a new words object that inherits from the parent engine's words for collision detection
 		} else {
-			if (this.#parent)
-				this.#logger?.error(this.#config, "Parent engine must be an instance of AliasEngine");
-
+			if (this.#parent) {
+				this.#logger?.error(this.#config, "Parent engine must be an instance of AliasEngine");
+				this.#parent = null;	// avoid retaining an invalid reference that downstream methods would dereference
+			}
 			this.#depth = 0;
 			this.#state = Object.create(null);										// initialize an empty state for the root engine (no parent)
 			this.#words = Object.create(null);										// initialize an empty words object for the root engine (no parent)
 		}
🤖 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/src/engine/engine.alias.ts` around lines 83 - 103, In the
AliasEngine constructor, don't keep an invalid options.parent on this.#parent;
instead test options.parent first and only assign when it's an instance of
AliasEngine, otherwise log the error and set this.#parent = null so downstream
checks (e.g. calls to getPatterns, getVersion, getAlias or accessing `#words`)
behave like a root engine; reposition the instanceof AliasEngine check to
control assignment to this.#parent and then initialize this.#depth, this.#state
and this.#words accordingly (root vs child) so invalid parents are nulled rather
than retained.
🧹 Nitpick comments (1)
packages/tempo/test/engine/engine.guard.test.ts (1)

1-62: ⚡ Quick win

LGTM — test suite covers the primary guard behaviors well.

One coverage gap worth noting: there is no test for a whitespace-only input (e.g. guard.test(' ')). The current implementation would return true for such input (the loop exits cleanly after consuming only spaces), which may not be the intended contract. A test asserting false would either catch this or explicitly document the intended behavior.

🤖 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/engine/engine.guard.test.ts` around lines 1 - 62, Add a
test asserting that a string consisting only of whitespace is treated as
invalid: call createMasterGuard(...) to produce a guard and add an expectation
like expect(guard.test('   ')).toBe(false) (or add a new it block alongside the
existing "should fail on empty or non-string input" case) to ensure guard.test
handles whitespace-only input; locate usage of createMasterGuard and guard.test
in engine.guard.test.ts to insert the new assertion.
🤖 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 `@doc/main_branch_protection.md`:
- Around line 127-129: The docs currently recommend using "git commit -am" which
omits new/untracked files; update the recovery flow to stage all changes first
by advising to run "git add ." or "git add -A" before the commit step (replace
or augment the "git commit -am" guidance), and mention the rationale briefly so
users know new files will be included; reference the git commit -am step and the
new recommended git add commands so readers can locate and apply the change.
- Around line 139-143: Update the README step before the destructive command
"git reset --hard origin/main" to add an explicit safety check: instruct users
to verify their working tree is clean (for example by running a status/porcelain
check or confirming there are no uncommitted changes) and to stash or commit any
work before proceeding; include a short warning sentence explaining that the
reset will discard local changes and recommend alternatives (stash/commit) if
the check fails so users don't lose work.

In `@packages/tempo/doc/tempo.layout.md`:
- Around line 88-94: The illustrative console output currently shows sequential
duplicate named groups for the `{sep}` token which is invalid; update the
example output produced by Tempo.regexp('{dd}{sep}{mm}{sep}{yy}') to reflect
Tempo's actual behavior (e.g., deduplicating or renaming groups so names are
unique within the same branch such as `(?<sep>...)(?<sep1>...)` or showing how
Tempo merges repeated tokens) and ensure the comment no longer displays
`(?<sep>...)(?<sep>...)`; reference the Tempo.regexp usage and the format string
'{dd}{sep}{mm}{sep}{yy}' when updating the illustrative output.

In `@packages/tempo/index.md`:
- Around line 558-565: The .tempo-btn-brand and .tempo-btn-brand:hover rules
hardcode light blue colors that fail WCAG contrast; replace them with either (a)
a darker background color that yields at least 4.5:1 contrast against white
(update the values in .tempo-btn-brand and .tempo-btn-brand:hover) or (b) revert
to using the existing theme variables like .tempo-btn-alt does so styling is
consistent and accessible; ensure the new colors are tested to meet 4.5:1 and
keep .tempo-btn-alt’s variable-based approach as the reference for consistency.

In `@packages/tempo/src/engine/engine.guard.ts`:
- Around line 30-31: The test(input: string): boolean in engine.guard.ts
currently returns true for inputs that are only whitespace because it only
checks !input and then advances over spaces; fix by adding a boolean flag (e.g.,
sawNonWhitespace or matchedToken) inside test to track whether any
non-whitespace/token character was actually consumed/matched before returning
true, set it when any token-accepting branch runs (not when skipping spaces),
and use that flag in the final return so pure-whitespace inputs return false;
apply the same change to the other test occurrence referenced (the second test
method around the other guard).
- Around line 18-21: The map step building wordsList can crash when a Symbol has
no description because (isSymbol(w) ? w.description : ... ) may be undefined
before .toLowerCase() — update the logic in the wordsList creation (the chain
around isSymbol, isString, and .map) to guard against undefined descriptions:
either filter out symbols with no description before mapping or coerce undefined
to an empty string/default (e.g., skip or return ''), and then call
.toLowerCase(); specifically change the sequence around wordsList (the
filter(...).map(...) chain) so that any Symbol without a description is excluded
or handled before calling .toLowerCase() to avoid the TypeError.

In `@packages/tempo/src/tempo.class.ts`:
- Around line 829-833: The current use of the nullish-assignment on
state.patternCompiler may reuse a PatternCompiler instance from a
prototype/parent state; change the logic in the accessor where you obtain state
via (this as any)[$Internal]() so that you either always construct a new
PatternCompiler bound to this state or recreate it when an existing
state.patternCompiler is present but its bound state !== state; ensure the
stored field (state.patternCompiler) is set to new PatternCompiler({ state }) in
that case and then call state.patternCompiler.compileRegExp(layout, snippet) so
PatternCompiler ownership and cache remain isolated per-state.

---

Outside diff comments:
In `@packages/tempo/src/engine/engine.alias.ts`:
- Around line 83-103: In the AliasEngine constructor, don't keep an invalid
options.parent on this.#parent; instead test options.parent first and only
assign when it's an instance of AliasEngine, otherwise log the error and set
this.#parent = null so downstream checks (e.g. calls to getPatterns, getVersion,
getAlias or accessing `#words`) behave like a root engine; reposition the
instanceof AliasEngine check to control assignment to this.#parent and then
initialize this.#depth, this.#state and this.#words accordingly (root vs child)
so invalid parents are nulled rather than retained.

---

Nitpick comments:
In `@packages/tempo/test/engine/engine.guard.test.ts`:
- Around line 1-62: Add a test asserting that a string consisting only of
whitespace is treated as invalid: call createMasterGuard(...) to produce a guard
and add an expectation like expect(guard.test('   ')).toBe(false) (or add a new
it block alongside the existing "should fail on empty or non-string input" case)
to ensure guard.test handles whitespace-only input; locate usage of
createMasterGuard and guard.test in engine.guard.test.ts to insert the new
assertion.
🪄 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: 3508f842-c96f-4325-aa34-907a59a46647

📥 Commits

Reviewing files that changed from the base of the PR and between e66d9aa and f2f2a86.

📒 Files selected for processing (40)
  • .agent/workflows/interactive-testing.md
  • .github/workflows/ci.yml
  • doc/main_branch_protection.md
  • package.json
  • packages/library/package.json
  • packages/tempo/CHANGELOG.md
  • packages/tempo/doc/architecture.md
  • packages/tempo/doc/installation.md
  • packages/tempo/doc/tempo.layout.md
  • packages/tempo/index.md
  • packages/tempo/package.json
  • packages/tempo/plan/RELEASE-D.md
  • packages/tempo/src/discrete/discrete.parse.ts
  • packages/tempo/src/engine/engine.alias.ts
  • packages/tempo/src/engine/engine.guard.ts
  • packages/tempo/src/engine/engine.layout.ts
  • packages/tempo/src/engine/engine.pattern.ts
  • packages/tempo/src/engine/engine.resolver.ts
  • packages/tempo/src/parse/parse.layout.ts
  • packages/tempo/src/parse/parse.resolver.ts
  • packages/tempo/src/plugin/plugin.util.ts
  • packages/tempo/src/plugin/term/term.quarter.ts
  • packages/tempo/src/plugin/term/term.season.ts
  • packages/tempo/src/support/support.default.ts
  • packages/tempo/src/support/support.enum.ts
  • packages/tempo/src/support/support.index.ts
  • packages/tempo/src/support/support.init.ts
  • packages/tempo/src/support/support.intl.ts
  • packages/tempo/src/support/support.register.ts
  • packages/tempo/src/support/support.runtime.ts
  • packages/tempo/src/support/support.symbol.ts
  • packages/tempo/src/support/support.util.ts
  • packages/tempo/src/tempo.class.ts
  • packages/tempo/src/tempo.type.ts
  • packages/tempo/src/tsconfig.json
  • packages/tempo/test/engine/engine.guard.test.ts
  • packages/tempo/test/engine/parse.layout.test.ts
  • packages/tempo/test/engine/pattern_compiler_optimization.test.ts
  • packages/tempo/test/plugins/plugin_registration.test.ts
  • packages/tempo/vitest.config.ts
💤 Files with no reviewable changes (5)
  • packages/tempo/src/parse/parse.layout.ts
  • packages/tempo/src/tsconfig.json
  • packages/tempo/src/parse/parse.resolver.ts
  • packages/tempo/vitest.config.ts
  • .github/workflows/ci.yml

Comment thread doc/main_branch_protection.md
Comment thread doc/main_branch_protection.md
Comment thread packages/tempo/doc/tempo.layout.md
Comment thread packages/tempo/index.md
Comment thread packages/tempo/src/engine/engine.guard.ts
Comment thread packages/tempo/src/engine/engine.guard.ts
Comment thread packages/tempo/src/tempo.class.ts
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (8)
packages/tempo/src/tempo.class.ts (1)

1287-1288: 💤 Low value

Minor: tz and cal getters duplicate work.

Each getter independently calls this.toDateTime() and getTemporalIds(...). When both are read in succession (a common pattern, e.g. in toNow or duration paths), this resolves the ZonedDateTime twice and re-extracts ids twice. If the call sites are hot, consider memoizing per-instance or exposing a single #ids() helper. Low priority — toDateTime() is already memoized via #resolve, so the cost is just the ID extraction.

🤖 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/src/tempo.class.ts` around lines 1287 - 1288, tz and cal both
call this.toDateTime() and getTemporalIds(...) causing duplicated work; add a
single private helper (e.g., a method named `#ids`() or a lazy memoized pair like
this.#tz and this.#cal) that calls getTemporalIds(this.toDateTime()) once and
returns the tuple, then change the getters tz and cal to return the first and
second elements from that helper; ensure the helper is private to the Tempo
class and lazily computes/stores the ids so subsequent tz/cal accesses reuse the
result.
packages/tempo/src/engine/engine.composer.ts (1)

24-24: 💤 Low value

Defensive dateTime ?? today fallback is now unreachable — consider tightening typing/intent.

With let dateTime: Temporal.ZonedDateTime = today; on Line 24 and every default branch returning early (Lines 152, and Line 46 for the string failure path), dateTime is always assigned by the time control reaches Line 156, so dateTime ?? today is dead. Either drop the ?? (since the type is now non-optional) or remove the explicit today initializer to keep the fallback meaningful — the current pairing is contradictory.

Suggested cleanup
-	return { dateTime: dateTime ?? today, timeZone };
+	return { dateTime, timeZone };

Also applies to: 156-156

🤖 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/src/engine/engine.composer.ts` at line 24, The variable
dateTime is declared as a non-optional ZonedDateTime and initialized to today,
making the later defensive "dateTime ?? today" check unreachable; either remove
the initializer (let dateTime: Temporal.ZonedDateTime | undefined) so the
nullish fallback remains meaningful, or keep the non-optional type and
initializer and remove the "?? today" at the use site. Locate the declaration of
dateTime (let dateTime: Temporal.ZonedDateTime = today;) and the later usage
with "dateTime ?? today" and change one of them so the type and fallback
behavior are consistent (adjust the type to allow undefined or drop the nullish
operator).
packages/tempo/plan/RELEASE-D.md (1)

129-173: 💤 Low value

Detailed Outlines for Guard Builder/Normalizer still read as "Assessment Outline" despite checklist showing completed extraction.

The checklist (Lines 24-35) marks both Guard Builder Extraction and Parse Result Normalizer Extraction as completed (with concrete extractions to engine.guard.ts and engine.normalizer.ts), but the corresponding detailed outlines below (Lines 129-173) are still phrased as evaluation/assessment of feasibility ("Evaluate the value and feasibility...", "Assessment Steps", "If justified, outline module boundaries..."). Worth updating these sections to reflect the realized design (modules, exported APIs like createMasterGuard, normalizeMatch, accumulateResult) so the plan stays consistent with the implemented state.

🤖 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/plan/RELEASE-D.md` around lines 129 - 173, Update the "Guard
Builder Extraction" and "Parse Result Normalizer Extraction" sections to reflect
that extraction is complete: replace assessment language with concrete design
and migration details, mention the new modules (engine.guard.ts and
engine.normalizer.ts) and their exported APIs such as createMasterGuard,
normalizeMatch, and accumulateResult, describe how they integrate with
tempo.class.ts's parse pipeline and pattern system, and remove/replace
"Assessment Steps" with brief notes on module responsibilities, public function
signatures, and any migration/usage examples so the document matches the
implemented state.
packages/tempo/src/engine/engine.normalizer.ts (3)

88-178: 💤 Low value

prevAnchor is shadowed inside the alias loop — high risk of future regressions.

Line 88 captures the caller's anchor; line 91 overwrites state.anchor to the current dateTime. Inside the alias-resolution branch, line 158 re-declares const prevAnchor: any = state.anchor; to snapshot the current anchor before subParse, then line 161 restores it. The outer finally at line 172 then restores the original outer prevAnchor. Functionally correct today because they are in separate scopes, but the identical name across nested scopes is a maintenance hazard — a stray edit promoting either declaration (or fusing the blocks) silently destroys the save/restore protocol.

Rename the inner one (e.g. innerPrevAnchor or subAnchor) to make the layered restore explicit.

♻️ Disambiguate
-					const prevAnchor: any = state.anchor;
-					state.anchor = dateTime;
-					const resMatch = subParse(res.value, dateTime, resolving);
-					state.anchor = prevAnchor;
+					const subPrevAnchor: any = state.anchor;
+					state.anchor = dateTime;
+					const resMatch = subParse(res.value, dateTime, resolving);
+					state.anchor = subPrevAnchor;
🤖 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/src/engine/engine.normalizer.ts` around lines 88 - 178, The
inner snapshot of state.anchor inside the alias-resolution branch shadows the
outer prevAnchor; rename the inner const prevAnchor (the one declared before
calling subParse) to a distinct identifier like innerPrevAnchor or subAnchor and
update its corresponding restore (state.anchor = innerPrevAnchor) so the outer
prevAnchor used in the outer finally block (and the outer save/restore logic
around state.anchor/state.zdt) remains untouched; locate the declaration and
restore around subParse in the alias handling code path (the block that sets
state.anchor = dateTime, calls subParse, then restores state.anchor) and rename
the local variable consistently.

127-133: 💤 Low value

Magic recursion limit > 50.

The hard-coded 50 mirrors no other constant in this file and is unrelated to the depth limit (> 10) used inside PatternCompiler.matcher. Hoist it to a named constant and document why this ceiling was chosen, so future tuning (or test injection) doesn't have to grep for 50.

🤖 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/src/engine/engine.normalizer.ts` around lines 127 - 133,
Replace the magic number 50 used in the recursion guard inside the normalization
loop with a well-named constant (e.g., MAX_TEMPO_RESOLVE_DEPTH) declared at the
top of the module and add a short comment explaining why this ceiling was chosen
and how it relates to the PatternCompiler.matcher depth limit (~10); update the
check from "resolvingKeys.size > 50" to use that constant, leaving the rest of
the logic (setting state.errored, calling (TempoClass as any)[sym.$logError],
deleting groups[key], and continue) unchanged so behavior is identical but the
limit is discoverable and configurable.

40-41: 💤 Low value

Redundant getTemporalIds evaluations in tz/cal getters.

Each property access recomputes the full normalization. cal even passes state.config.timeZone only to discard [0]. Trivial to consolidate with toNow above.

♻️ Compute once
-		toNow: () => {
-			const [tz, cal] = getTemporalIds(state.config.timeZone, state.config.calendar);
-			return instant().toZonedDateTimeISO(tz).withCalendar(cal);
-		},
-		get tz() { return getTemporalIds(state.config.timeZone)[0] },
-		get cal() { return getTemporalIds(state.config.timeZone, state.config.calendar)[1] },
+		toNow: () => {
+			const [tz, cal] = getTemporalIds(state.config.timeZone, state.config.calendar);
+			return instant().toZonedDateTimeISO(tz).withCalendar(cal);
+		},
+		get tz() { return getTemporalIds(state.config.timeZone, state.config.calendar)[0] },
+		get cal() { return getTemporalIds(state.config.timeZone, state.config.calendar)[1] },
🤖 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/src/engine/engine.normalizer.ts` around lines 40 - 41, The tz
and cal getters call getTemporalIds separately (and cal calls it with only
timeZone), causing duplicate work; compute getTemporalIds once (e.g., call
getTemporalIds(state.config.timeZone, state.config.calendar) once above or
alongside toNow and store the tuple/values) and have the tz getter return the
first element and cal return the second, removing the redundant per-getter calls
and the incorrect single-argument call in cal.
packages/library/src/common/temporal.library.ts (1)

86-89: ⚡ Quick win

toZonedDateTime has a design flaw with string inputs that should be fixed to prevent future issues.

The function accepts ISO strings in its signature but blindly appends [${tz}] without checking if the input already contains a zone designator. Passing '2024-01-01T00:00:00-05:00[America/New_York]' would create '2024-01-01T00:00:00-05:00[America/New_York][UTC]' (invalid per Temporal spec), and '2024-01-01T00:00Z' with a different tz parameter would produce '2024-01-01T00:00Z[UTC]' (which silently succeeds only if the tz matches Z).

Current code avoids this by passing property bags only (not strings), but since this is a reachable public API, adding a guard is sensible to prevent misuse:

Suggested fix
 export function toZonedDateTime(bag: Temporal.ZonedDateTimeLike | string, tz: Temporal.TimeZoneLike = 'UTC'): Temporal.ZonedDateTime {
-	if (isString(bag)) return Temporal.ZonedDateTime.from(`${bag}[${tz}]`);
+	if (isString(bag)) {
+		const hasZoneBracket = /\[[^\]]+\]\s*$/.test(bag);
+		return Temporal.ZonedDateTime.from(hasZoneBracket ? bag : `${bag}[${String(tz)}]`);
+	}
 	return Temporal.ZonedDateTime.from(bag);
 }
🤖 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/temporal.library.ts` around lines 86 - 89, The
toZonedDateTime function currently appends `[${tz}]` to any string input which
can produce invalid double-zone strings; update toZonedDateTime to first detect
whether the string already includes a zone designator (either an offset like
±HH:MM or a bracketed IANA zone like [...]) and only append `[${tz}]` when no
zone is present, otherwise pass the original string through to
Temporal.ZonedDateTime.from; keep the existing behavior for non-string bags. Use
a simple regex test on the string input inside toZonedDateTime to decide which
branch to call Temporal.ZonedDateTime.from on.
packages/tempo/src/engine/engine.pattern.ts (1)

79-83: 💤 Low value

Add defensive placeholder name sanitization to prevent invalid named-capture identifiers.

The current code at lines 79-83 only escapes dots (name.replace(/\./g, '_')), but JS named capture groups require identifiers matching [A-Za-z_$][A-Za-z0-9_$]*. If a placeholder name starts with a digit (e.g., {123ext}) or contains other special characters, new RegExp() will throw at line 93—but the error is silently caught and falls back to escaped literal matching, masking the real layout/snippet authoring bug.

🛡️ Defensive sanitization
-			if (res && name.includes('.')) {										// wrap dotted extensions for identification
-				const safeName = name.replace(/\./g, '_');
-				if (!res.startsWith(`(?<${safeName}>`))
-					res = `(?<${safeName}>${res})`;
-			}
+			if (res && name.includes('.')) {										// wrap dotted extensions for identification
+				const safeName = name.replace(/[^A-Za-z0-9_$]/g, '_');
+				if (/^[A-Za-z_$]/.test(safeName) && !res.startsWith(`(?<${safeName}>`))
+					res = `(?<${safeName}>${res})`;
+			}
🤖 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/src/engine/engine.pattern.ts` around lines 79 - 83, The
placeholder sanitization only replaces dots but must produce a valid JS
named-capture identifier; update the logic that builds safeName (the code that
currently does const safeName = name.replace(/\./g, '_')) to: trim/ensure
non-empty, replace any character not in [A-Za-z0-9_$] with '_', and if the first
character is not [A-Za-z_$] prefix an underscore (or replace it) so the final
safeName matches [A-Za-z_$][A-Za-z0-9_$]* before it is interpolated into the
group `(?<${safeName}>${res})`; keep the existing fallback behavior for RegExp
construction (the code that calls new RegExp on res) but ensure we generate a
valid safeName to avoid throwing there and to surface real template issues
instead of silently falling back.
🤖 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 `@doc/main_branch_protection.md`:
- Around line 98-101: Remove or relocate the premature "Stage all changes" and
"Commit your work" steps in the introductory section that currently advise
running `git add .` / `git add -A` and `git commit -m "Your descriptive
message"` before creating a branch; these instructions conflict with the
pre-commit hook described in the scenario and already appear correctly in the
branch-first workflows below—either delete those two steps or move them into the
method sections that instruct creating a new branch first so staging/commit
guidance appears only after branch creation.

In `@packages/library/src/common/temporal.library.ts`:
- Around line 115-139: The guard in getTemporalIds wrongfully treats a
ZonedDateTime as a timeZone-like object when a Calendar is passed as the second
argument; add explicit TypeScript overloads for getTemporalIds to support
(tzOrZdt: ZonedDateTime, cal?: Calendar), (tzOrZdt: TimeZoneLike, cal?:
Calendar) and the general fallback to improve type safety, then change the
runtime guard in getTemporalIds (currently using isZonedDateTime(tzOrZdt) &&
isUndefined(cal)) to detect ZonedDateTime regardless of whether a calendar arg
was supplied (e.g., if isZonedDateTime(tzOrZdt) then use its
timeZoneId/calendarId and, if cal is provided, treat that as the explicit
calendar override), and ensure engine.normalizer.ts callers (tz and cal getters)
rely on the typed overloads so swapped-argument mistakes are caught by the
compiler.

In `@packages/tempo/src/engine/engine.normalizer.ts`:
- Around line 192-205: accumulateResult currently builds a fresh match object
each call so the res.includes(match) check is a no-op; either remove that check
to always append, or implement real deduping by comparing stable identity
fields. Update the function accumulateResult to compute a stable identity (e.g.
combine match.match and match.source or compare match.match, match.source,
match.anchor as appropriate) and replace res.includes(match) with a lookup like
res.some(existing => existing.match === match.match && existing.source ===
match.source [&& existing.anchor === match.anchor if needed]) before pushing, or
simply delete the includes branch if deduplication is not required; refer to
symbols: accumulateResult, match, state.parse.result, and state.parse.anchor.

---

Nitpick comments:
In `@packages/library/src/common/temporal.library.ts`:
- Around line 86-89: The toZonedDateTime function currently appends `[${tz}]` to
any string input which can produce invalid double-zone strings; update
toZonedDateTime to first detect whether the string already includes a zone
designator (either an offset like ±HH:MM or a bracketed IANA zone like [...])
and only append `[${tz}]` when no zone is present, otherwise pass the original
string through to Temporal.ZonedDateTime.from; keep the existing behavior for
non-string bags. Use a simple regex test on the string input inside
toZonedDateTime to decide which branch to call Temporal.ZonedDateTime.from on.

In `@packages/tempo/plan/RELEASE-D.md`:
- Around line 129-173: Update the "Guard Builder Extraction" and "Parse Result
Normalizer Extraction" sections to reflect that extraction is complete: replace
assessment language with concrete design and migration details, mention the new
modules (engine.guard.ts and engine.normalizer.ts) and their exported APIs such
as createMasterGuard, normalizeMatch, and accumulateResult, describe how they
integrate with tempo.class.ts's parse pipeline and pattern system, and
remove/replace "Assessment Steps" with brief notes on module responsibilities,
public function signatures, and any migration/usage examples so the document
matches the implemented state.

In `@packages/tempo/src/engine/engine.composer.ts`:
- Line 24: The variable dateTime is declared as a non-optional ZonedDateTime and
initialized to today, making the later defensive "dateTime ?? today" check
unreachable; either remove the initializer (let dateTime: Temporal.ZonedDateTime
| undefined) so the nullish fallback remains meaningful, or keep the
non-optional type and initializer and remove the "?? today" at the use site.
Locate the declaration of dateTime (let dateTime: Temporal.ZonedDateTime =
today;) and the later usage with "dateTime ?? today" and change one of them so
the type and fallback behavior are consistent (adjust the type to allow
undefined or drop the nullish operator).

In `@packages/tempo/src/engine/engine.normalizer.ts`:
- Around line 88-178: The inner snapshot of state.anchor inside the
alias-resolution branch shadows the outer prevAnchor; rename the inner const
prevAnchor (the one declared before calling subParse) to a distinct identifier
like innerPrevAnchor or subAnchor and update its corresponding restore
(state.anchor = innerPrevAnchor) so the outer prevAnchor used in the outer
finally block (and the outer save/restore logic around state.anchor/state.zdt)
remains untouched; locate the declaration and restore around subParse in the
alias handling code path (the block that sets state.anchor = dateTime, calls
subParse, then restores state.anchor) and rename the local variable
consistently.
- Around line 127-133: Replace the magic number 50 used in the recursion guard
inside the normalization loop with a well-named constant (e.g.,
MAX_TEMPO_RESOLVE_DEPTH) declared at the top of the module and add a short
comment explaining why this ceiling was chosen and how it relates to the
PatternCompiler.matcher depth limit (~10); update the check from
"resolvingKeys.size > 50" to use that constant, leaving the rest of the logic
(setting state.errored, calling (TempoClass as any)[sym.$logError], deleting
groups[key], and continue) unchanged so behavior is identical but the limit is
discoverable and configurable.
- Around line 40-41: The tz and cal getters call getTemporalIds separately (and
cal calls it with only timeZone), causing duplicate work; compute getTemporalIds
once (e.g., call getTemporalIds(state.config.timeZone, state.config.calendar)
once above or alongside toNow and store the tuple/values) and have the tz getter
return the first element and cal return the second, removing the redundant
per-getter calls and the incorrect single-argument call in cal.

In `@packages/tempo/src/engine/engine.pattern.ts`:
- Around line 79-83: The placeholder sanitization only replaces dots but must
produce a valid JS named-capture identifier; update the logic that builds
safeName (the code that currently does const safeName = name.replace(/\./g,
'_')) to: trim/ensure non-empty, replace any character not in [A-Za-z0-9_$] with
'_', and if the first character is not [A-Za-z_$] prefix an underscore (or
replace it) so the final safeName matches [A-Za-z_$][A-Za-z0-9_$]* before it is
interpolated into the group `(?<${safeName}>${res})`; keep the existing fallback
behavior for RegExp construction (the code that calls new RegExp on res) but
ensure we generate a valid safeName to avoid throwing there and to surface real
template issues instead of silently falling back.

In `@packages/tempo/src/tempo.class.ts`:
- Around line 1287-1288: tz and cal both call this.toDateTime() and
getTemporalIds(...) causing duplicated work; add a single private helper (e.g.,
a method named `#ids`() or a lazy memoized pair like this.#tz and this.#cal) that
calls getTemporalIds(this.toDateTime()) once and returns the tuple, then change
the getters tz and cal to return the first and second elements from that helper;
ensure the helper is private to the Tempo class and lazily computes/stores the
ids so subsequent tz/cal accesses reuse the result.
🪄 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: 2ee03d44-ceda-475e-9e94-2bfc6af60d77

📥 Commits

Reviewing files that changed from the base of the PR and between f2f2a86 and 8099d82.

📒 Files selected for processing (19)
  • doc/main_branch_protection.md
  • packages/library/src/common/assertion.library.ts
  • packages/library/src/common/temporal.library.ts
  • packages/tempo/doc/tempo.layout.md
  • packages/tempo/index.md
  • packages/tempo/plan/RELEASE-D.md
  • packages/tempo/src/discrete/discrete.parse.ts
  • packages/tempo/src/engine/engine.alias.ts
  • packages/tempo/src/engine/engine.composer.ts
  • packages/tempo/src/engine/engine.guard.ts
  • packages/tempo/src/engine/engine.normalizer.ts
  • packages/tempo/src/engine/engine.pattern.ts
  • packages/tempo/src/engine/engine.term.ts
  • packages/tempo/src/module/module.duration.ts
  • packages/tempo/src/support/support.default.ts
  • packages/tempo/src/tempo.class.ts
  • packages/tempo/test/core/tempo_guard.test.ts
  • packages/tempo/test/engine/engine.guard.test.ts
  • packages/tempo/test/support/setup.console-spy.ts
✅ Files skipped from review due to trivial changes (4)
  • packages/tempo/src/engine/engine.term.ts
  • packages/tempo/test/support/setup.console-spy.ts
  • packages/tempo/src/engine/engine.guard.ts
  • packages/tempo/src/support/support.default.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/tempo/index.md
  • packages/tempo/test/engine/engine.guard.test.ts
  • packages/tempo/src/engine/engine.alias.ts

Comment thread doc/main_branch_protection.md Outdated
Comment thread packages/library/src/common/temporal.library.ts
Comment thread packages/tempo/src/engine/engine.normalizer.ts
@magmacomputing
Copy link
Copy Markdown
Owner Author

@coderabbitai full review please

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

Tip

For best results, initiate chat on the files or code changes.

@magmacomputing Sure! I'll kick off a full review of this PR right away. 🐇

[full_review]

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 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 `@packages/library/src/common/temporal.polyfill.ts`:
- Around line 28-30: The catch in temporal.polyfill.ts currently swallows all
exceptions and discards the caught err; update that catch (the block that logs
"Tempo: Native Temporal implementation appears incomplete...") to include the
error object in the console.warn so diagnostics are preserved, and only suppress
the error when it matches the expected "incomplete implementation" signal (e.g.,
inspect err.name or err.message or use a specific Error subclass); for any other
errors rethrow them so unrelated failures (timezone DB issues, runtime errors)
are not masked.

In `@packages/library/test/common/temporal_library.test.ts`:
- Around line 24-31: The test uses a try/catch around toZonedDateTime(bag,
'Australia/Sydney') which causes a silent-pass if no exception is thrown; update
the test to assert the expected throw explicitly by replacing the try/catch with
Jest's expect(() => toZonedDateTime(bag, 'Australia/Sydney')).toThrow(/requires
a time zone ID in brackets/) or, if you prefer keeping the try/catch style, add
expect.assertions(1) before the call and keep the expect inside the catch to
guarantee the catch branch runs; target the test referencing toZonedDateTime and
the local variable bag.

In `@packages/tempo/src/engine/engine.normalizer.ts`:
- Around line 142-176: The code currently adds aliasKey to resolvingKeys but
never removes it, causing sibling resolutions to see it as "in progress"; ensure
aliasKey is removed from resolvingKeys in all paths (both when !res causes the
continue and after the try/finally block) so the set is released after each
alias resolution attempt; modify the logic around resolvingKeys.add(aliasKey)
and the branch that handles (!res) and the try/finally that uses subParse/state
to call resolvingKeys.delete(aliasKey) (or equivalent) so resolvingKeys is
always cleaned up even on early returns or errors, referencing resolvingKeys,
aliasKey, getResolutionContext, aliasEngine.resolveAlias, subParse, state and
groups to locate the change.

In `@packages/tempo/src/module/module.parse.ts`:
- Around line 173-177: The code applies wall-clock mutations via
zdt.with(options) before changing zone/calendar, which shifts the instant and
yields the wrong local wall time; to fix, first call zdt =
zdt.withTimeZone(timeZone) (if timeZone) and zdt = zdt.withCalendar(calendar)
(if calendar) and only then apply zdt = zdt.with(options as
Temporal.ZonedDateTimeLikeObject) so the wall-clock fields are interpreted in
the target time zone/calendar before calling accumulateResult with the final
zdt.

In `@packages/tempo/src/tempo.type.ts`:
- Around line 15-20: The PluginContainer type currently extends the unimported
global DOM Plugin identifier; update the declaration of PluginContainer to
extend the imported TempoPlugin type (use TempoPlugin instead of Plugin) so it
conforms to Tempo's plugin contract, and remove any bare usage of Plugin in this
file to avoid the DOM interface collision; refer to the PluginContainer type
declaration and the existing imported TempoPlugin symbol when making the change.
🪄 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: 13f6622d-fea6-4d70-b379-23b4622e0fce

📥 Commits

Reviewing files that changed from the base of the PR and between 8099d82 and ed0ae00.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (48)
  • doc/main_branch_protection.md
  • doc/release-process.md
  • package.json
  • packages/library/src/common/temporal.library.ts
  • packages/library/src/common/temporal.polyfill.ts
  • packages/library/test/common/temporal_library.test.ts
  • packages/tempo/CHANGELOG.md
  • packages/tempo/doc/installation.md
  • packages/tempo/doc/tempo.config.md
  • packages/tempo/index.md
  • packages/tempo/package.json
  • packages/tempo/plan/.WISHLIST.md
  • packages/tempo/plan/RELEASE-D.md
  • packages/tempo/plan/alias-migration-phase2.md
  • packages/tempo/plan/alias-precedence-strategy.md
  • packages/tempo/plan/alias.registration.md
  • packages/tempo/plan/configuration.md
  • packages/tempo/plan/release-c-prefilter-summary.md
  • packages/tempo/src/discrete/discrete.index.ts
  • packages/tempo/src/engine/engine.composer.ts
  • packages/tempo/src/engine/engine.normalizer.ts
  • packages/tempo/src/engine/engine.pattern.ts
  • packages/tempo/src/engine/engine.term.ts
  • packages/tempo/src/module/module.duration.ts
  • packages/tempo/src/module/module.format.ts
  • packages/tempo/src/module/module.index.ts
  • packages/tempo/src/module/module.mutate.ts
  • packages/tempo/src/module/module.parse.ts
  • packages/tempo/src/plugin/extend/extend.ticker.ts
  • packages/tempo/src/plugin/plugin.index.ts
  • packages/tempo/src/plugin/plugin.type.ts
  • packages/tempo/src/plugin/plugin.util.ts
  • packages/tempo/src/plugin/term/term.index.ts
  • packages/tempo/src/plugin/term/term.quarter.ts
  • packages/tempo/src/plugin/term/term.season.ts
  • packages/tempo/src/plugin/term/term.timeline.ts
  • packages/tempo/src/plugin/term/term.type.ts
  • packages/tempo/src/plugin/term/term.util.ts
  • packages/tempo/src/plugin/term/term.zodiac.ts
  • packages/tempo/src/support/support.runtime.ts
  • packages/tempo/src/tempo.class.ts
  • packages/tempo/src/tempo.index.ts
  • packages/tempo/src/tempo.type.ts
  • packages/tempo/src/tsconfig.json
  • packages/tempo/test/README.md
  • packages/tempo/test/engine/parse.prefilter.numeric-safety.test.ts
  • packages/tempo/test/tsconfig.json
  • packages/tempo/vitest.config.ts
💤 Files with no reviewable changes (8)
  • packages/tempo/plan/alias.registration.md
  • packages/tempo/plan/release-c-prefilter-summary.md
  • packages/tempo/src/discrete/discrete.index.ts
  • packages/tempo/plan/.WISHLIST.md
  • packages/tempo/plan/alias-precedence-strategy.md
  • packages/tempo/plan/alias-migration-phase2.md
  • packages/tempo/plan/configuration.md
  • packages/tempo/plan/RELEASE-D.md
✅ Files skipped from review due to trivial changes (14)
  • packages/tempo/test/README.md
  • packages/tempo/src/plugin/plugin.index.ts
  • packages/tempo/src/plugin/term/term.quarter.ts
  • packages/tempo/test/engine/parse.prefilter.numeric-safety.test.ts
  • packages/tempo/src/plugin/term/term.timeline.ts
  • packages/tempo/src/module/module.index.ts
  • packages/tempo/src/tempo.index.ts
  • packages/tempo/src/plugin/term/term.season.ts
  • packages/tempo/src/plugin/term/term.zodiac.ts
  • packages/tempo/index.md
  • packages/tempo/src/plugin/term/term.util.ts
  • packages/tempo/src/plugin/extend/extend.ticker.ts
  • packages/tempo/src/plugin/term/term.type.ts
  • packages/tempo/doc/installation.md
🚧 Files skipped from review as they are similar to previous changes (13)
  • package.json
  • packages/tempo/src/engine/engine.composer.ts
  • packages/tempo/src/module/module.duration.ts
  • packages/tempo/src/plugin/plugin.util.ts
  • packages/tempo/src/tsconfig.json
  • packages/tempo/src/engine/engine.term.ts
  • packages/tempo/src/engine/engine.pattern.ts
  • packages/tempo/package.json
  • packages/tempo/src/support/support.runtime.ts
  • doc/main_branch_protection.md
  • packages/library/src/common/temporal.library.ts
  • packages/tempo/src/tempo.class.ts
  • packages/tempo/vitest.config.ts

Comment thread packages/library/src/common/temporal.polyfill.ts Outdated
Comment thread packages/library/test/common/temporal_library.test.ts
Comment thread packages/tempo/src/engine/engine.normalizer.ts
Comment thread packages/tempo/src/module/module.parse.ts Outdated
Comment thread packages/tempo/src/tempo.type.ts
@magmacomputing magmacomputing merged commit 55b3058 into main May 8, 2026
2 checks passed
@magmacomputing magmacomputing deleted the feature/tempo-pattern-compiler branch May 8, 2026 02:19
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