Feature/registry support#37
Conversation
|
Warning Review limit reached
More reviews will be available in 1 minute and 16 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the 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 include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughMonorepo v3 release: replace Logify with Logger/Diagnostic Engine, extract Ticker to premium, add crypto/webtoken modules, Intl/duration/token API changes, add BenchmarkModule, and migrate tests/docs/tooling to SWC and new logging contracts. ChangesTempo & Library v3 Cutover
Estimated code review effort Possibly related PRs
✨ Finishing Touches🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 15
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
packages/tempo/src/tempo.class.ts (2)
638-711:⚠️ Potential issue | 🟠 Major | ⚡ Quick winRe-apply the logger level after the final config merge.
setLogLevel()runs before store/discovery/options are merged intostate.config, so adebuglevel loaded from storage or discovery never reaches the new logger stack. After init,Tempo.config.debugcan say one thing whilelogTempois still running atInfo.Suggested fix
try { setLogLevel(options.debug ?? Default?.debug ?? LOG.Info); @@ this[$setConfig](state, { calendar, timeZone, locale, discovery: normalizedDiscovery, formats: config.formats ?? enumify(STATE.FORMAT, false), scope: 'global', catch: options.catch ?? config.catch ?? false }, { store: storeKey, discovery: normalizedDiscovery, scope: 'global' }, this.readStore(storeKey), this[$setDiscovery](state, rt.pluginsDb as any), this[$setDiscovery](state, userDiscovery), options, ) + setLogLevel(state.config.debug as any);🤖 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 638 - 711, The logger level is set early with setLogLevel(options.debug ?? Default?.debug ?? LOG.Info) before this[$setConfig](...) merges store/discovery values into state.config, so persisted or discovered debug settings are ignored; after the unified merge call this[$setConfig](...) completes, re-apply the effective level by calling setLogLevel with the merged value (e.g. setLogLevel(state.config.debug ?? options.debug ?? Default?.debug ?? LOG.Info) or simply setLogLevel(state.config.debug ?? LOG.Info) so the logger reflects the final state.config); update immediately after the this[$setConfig](...) invocation.
346-377:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftKeep sandbox discovery out of the shared registries.
Tempo.create()now routes sandbox discovery through this method, but theseregistryUpdate(...)calls still mutate the shared registry state. A sandbox that definesformats,timeZones,numbers, ormonthDaydata will leak those additions back into baseTempoand other sandboxes.Also applies to: 387-390
🤖 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 346 - 377, The discovery processing is mutating shared registries via registryUpdate for formats, timeZones, numbers and MONTH_DAY; when discovery is from a sandbox this leaks into global state. Fix by detecting sandbox discovery (e.g., a boolean flag on the discovery object or a parameter passed into the method) and: if sandbox, do not call registryUpdate for the entries processed in the blocks handling discovery.timeZones, discovery.numbers, discovery.monthDay (and the formats block) — instead merge those values into a local opts/registry object returned or used only by the instance; if not sandbox, continue to call registryUpdate as before. Ensure the same guard is applied for the later registryUpdate calls related to MONTH_DAY and intl so sandbox data never mutates the shared registry.packages/tempo/bench/bench.parse.prefilter.e2e.ts (1)
14-18:⚠️ Potential issue | 🟡 MinorFix extensionless corpus path to avoid always using the fallback dataset
bench.parse.prefilter.e2e.tsreadsfs.readFileSync(new URL('./bench.parse.prefilter', import.meta.url), ...), which resolves topackages/tempo/bench/bench.parse.prefilter(no extension). That extensionless file doesn’t exist in the repo (onlybench.parse.prefilter.tsis present), so the benchmark will hit the fallback and produce misleading e2e numbers.🤖 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/bench/bench.parse.prefilter.e2e.ts` around lines 14 - 18, The path passed to fs.readFileSync is missing the file extension so new URL('./bench.parse.prefilter', import.meta.url) resolves to a non-existent extensionless file and triggers the fallback dataset; update the URL to point to the actual file (e.g. use './bench.parse.prefilter.ts') in the call that builds corpus so the code in bench.parse.prefilter.e2e.ts reads the real corpus file instead of falling back.packages/tempo/test/plugins/licensing.full.test.ts (2)
196-234:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winDuplicate await statement.
Line 223 has a duplicate
await rt.license.jws;that appears immediately after the same statement on line 222. This is functionally harmless (awaiting an already-resolved promise is a no-op), but it's unnecessary and may indicate a copy-paste error.🧹 Proposed cleanup
const rt = getRuntime(); await rt.license.jws; - await rt.license.jws; await vi.waitFor(() => expect(rt.license.status).toBe(LICENSE.Revoked));🤖 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/plugins/licensing.full.test.ts` around lines 196 - 234, Remove the duplicate await call to rt.license.jws (the second await on the same promise immediately after the first) in the test 'Eager Discovery Guard: blocks premium plugins when license is revoked' so only a single await rt.license.jws remains before checking rt.license.status; this cleans up the redundant no-op await and prevents confusion about a possible copy/paste error.
101-113:⚠️ Potential issue | 🔴 Critical | ⚡ Quick winRace condition causes test failure.
The test expects
LICENSE.Pendingbut the pipeline shows it receives'active'. After callingTempo.init({ license: mockToken }), the license verification may complete immediately because the mock resolves synchronously. The test shouldawait rt.license.jwsbefore asserting the status, or explicitly check the pre-resolution state in a deterministic way.The pipeline error confirms this: "expected 'active' to be 'pending'".
🔧 Proposed fix
Add a guard to ensure the test checks the status before verification completes:
test('License state is global and persists across local instances', () => { const payload = { permissions: { global: {} } }; const mockToken = `a.${base64Encode(JSON.stringify(payload))}.c`; Tempo.init({ license: mockToken }); + const rt = getRuntime(); // Create a local instance const local = new Tempo(); // Local instance should reflect the global license state via its runtime bridge - expect(Tempo.license.status).toBe(LICENSE.Pending); + // Note: The mock verification may complete immediately, so we check the runtime directly + // If you want to test Pending state, add a longer async mock or check before init completes + expect(rt.license.status).toMatch(/pending|active/i); expect((Tempo.license as any).key).toBeUndefined(); });Or if you specifically need to test the Pending state, you need to prevent the mock from resolving immediately.
🤖 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/plugins/licensing.full.test.ts` around lines 101 - 113, The test is racy: after calling Tempo.init({ license: mockToken }) the license verification may resolve synchronously, so assertions against Tempo.license.status can be nondeterministic; fix by awaiting the runtime bridge license promise before asserting (e.g. await rt.license.jws or the equivalent promise exposed by the runtime bridge created by new Tempo()) and then assert the resolved state, or if you intend to assert the Pending state, modify the mock verification to delay resolution (make the verification promise async/delayed) and then assert Tempo.license.status === LICENSE.Pending immediately after Tempo.init; reference Tempo.init, new Tempo(), Tempo.license and rt.license.jws to locate where to await or where to stub the verifier.
🧹 Nitpick comments (5)
packages/library/src/browser/mapper.library.ts (1)
130-131: ⚡ Quick winConsider migrating remaining console calls to Logger for consistency.
The module now uses
Loggerfor some logging (lines 71, 87-88), but still uses rawconsole.*calls at lines 130, 147, 163, 176, and 203. For a cleaner diagnostic strategy, consider migrating these remainingconsolecalls to theloginstance.♻️ Example migration for line 130-131
- if (opts.debug) - console.log('mapQuery: cache'); + log.debug(opts, 'mapQuery: cache');Also applies to: 147-148, 163-164, 176-177, 203-204
🤖 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/browser/mapper.library.ts` around lines 130 - 131, Replace remaining raw console calls in packages/library/src/browser/mapper.library.ts (inside the mapQuery flow) with the module Logger instance (log) for consistency: change console.log('mapQuery: cache') and the other console.* usages at the equivalent spots (the calls around the cache path, fallback/path checks, and error/info messages—previously at lines similar to 130,147,163,176,203) to use log.debug or log.info/log.warn/log.error as appropriate, keeping the same message text and honoring the existing opts.debug guard by using log.debug when opts.debug is checked; ensure you import/use the existing log instance used on lines 71 and 87-88 and remove direct console.* usage.packages/library/src/common/cipher.class.ts (1)
95-100: ⚡ Quick winNon-null assertions on keypair properties assume successful generation.
The
!operators on lines 95 and 100 assume thatprivateKeyandpublicKeywill always exist on the generated keypair. While this should be true for RSASSA-PKCS1-v1_5 with the specified usages, these assertions could throw if the key generation returns an unexpected structure.🛡️ Safer alternative without assertions
static sign = async (doc: any) => - subtle.sign(keys.SignKey, (await _asymmetricKey).privateKey!, Cipher.encodeBuffer(doc)) + subtle.sign(keys.SignKey, (await _asymmetricKey).privateKey, Cipher.encodeBuffer(doc)) .then(result => new Uint8Array(result)) .then(Cipher.decodeBuffer); static verify = async (signature: Promise<ArrayBuffer>, doc: any) => - subtle.verify(keys.SignKey, (await _asymmetricKey).publicKey!, await signature, Cipher.encodeBuffer(doc)); + subtle.verify(keys.SignKey, (await _asymmetricKey).publicKey, await signature, Cipher.encodeBuffer(doc));🤖 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/cipher.class.ts` around lines 95 - 100, The code currently uses non-null assertions on (await _asymmetricKey).privateKey and .publicKey when calling subtle.sign and subtle.verify; replace these assertions with explicit runtime checks: await _asymmetricKey once, verify that keypair.privateKey (for the sign flow) or keypair.publicKey (for verify) exist and throw a descriptive error (or return a rejected Promise) if missing, then pass the validated key to subtle.sign/subtle.verify together with Cipher.encodeBuffer/Cipher.decodeBuffer; reference the _asymmetricKey promise, subtle.sign/subtle.verify calls, and the Cipher.encodeBuffer/Cipher.decodeBuffer helpers when making the change.packages/tempo/doc/architecture.md (1)
33-33: ⚡ Quick winClarify the documentation phrasing for
$LogConfig.The sentence "Note that
$LogConfigis already a Symbol created viaSymbol.for('$LibraryLogConfig')" is somewhat awkward. Consider rephrasing for clarity.📝 Suggested rephrasing
-- **Symbol-Gated**: Diagnostic metadata is attached via the symbol variable directly (e.g., `config[sym.$LogConfig]`), making it invisible to standard iteration (`Object.keys`) and serialization (`JSON.stringify`). Note that `$LogConfig` is already a Symbol created via `Symbol.for('$LibraryLogConfig')`. +- **Symbol-Gated**: Diagnostic metadata is attached via `config[sym.$LogConfig]` (where `$LogConfig` is defined as `Symbol.for('$LibraryLogConfig')`), making it invisible to standard iteration (`Object.keys`) and serialization (`JSON.stringify`).🤖 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/doc/architecture.md` at line 33, Reword the awkward sentence about $LogConfig for clarity: replace "Note that `$LogConfig` is already a Symbol created via `Symbol.for('$LibraryLogConfig')`" with a clearer phrasing such as "The $LogConfig identifier is a Symbol (created with Symbol.for('$LibraryLogConfig'))" or "Note: $LogConfig is a Symbol created using Symbol.for('$LibraryLogConfig')". Update the line referencing sym.$LogConfig and Symbol.for('$LibraryLogConfig') in the architecture.md paragraph so it reads smoothly and unambiguously.packages/library/src/common/logger.class.ts (1)
96-96: 💤 Low valueConsider the semantic difference between
traceanddebugconsole methods.Mapping
Method.Tracetoconsole.debug(line 96) works functionally, butconsole.trace()is a standard method that prints the call stack. Users might expect.trace()to produce stack traces rather than debug-level output. If stack traces are not needed, consider renaming the method or documenting this design choice more explicitly.🤖 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/logger.class.ts` at line 96, The current mapping maps Method.Trace to console.debug which hides the semantic behavior of console.trace; update the mapping in logger.class (the assignment that sets consoleMethod for Method.Trace) to use 'trace' so calls to Method.Trace invoke console.trace and produce a stack trace, or if stack traces are intentionally undesired, rename the enum value Method.Trace to Method.Debug (and update all callers) and add a clear comment in logger.class explaining the chosen behavior.packages/tempo/test/module/module.benchmark.test.ts (1)
23-23: ⚡ Quick winUse a more robust assertion for success rate.
The exact string match
toBe('50.0%')is fragile and will break if formatting changes (e.g., to'50%'or'50.00%'). Consider using a regex or checking the numeric value instead.♻️ Proposed fix
- expect(native.successRate).toBe('50.0%'); + expect(native.successRate).toMatch(/50(\.0)?%/);🤖 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/module/module.benchmark.test.ts` at line 23, Replace the fragile exact string assertion for native.successRate in the test (module.benchmark.test.ts) with a tolerant check: either parse the numeric percentage from native.successRate and assert the numeric value equals 50 (or within a small delta), or assert the string matches a regex like /^50(\.0+)?%$/; update the expectation that currently uses expect(native.successRate).toBe('50.0%') to one of these more robust forms to avoid formatting brittleness.
🤖 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 `@CHANGELOG.md`:
- Line 8: Update the release date in the CHANGELOG.md entry header "## [3.0.0] -
2026-06-01" to the correct publication date (e.g., change "2026-06-01" to
"2026-06-05" or the intended date) so the release heading accurately reflects
the actual release/PR date.
In `@packages/library/src/common/boundary.library.ts`:
- Line 32: Replace the call that logs only error.message with a call that passes
the full Error object to the logger (i.e., use context.logger.error with the
Error instance rather than error.message) so the stack and metadata are
preserved; update any surrounding error handling in the function where
context.logger.error is called to accept an Error object if necessary (refer to
the symbol context.logger.error in boundary.library.ts).
In `@packages/library/src/common/cipher.class.ts`:
- Around line 16-22: The module-level promises _cryptoKey and _asymmetricKey are
created without error handling which can cause unhandled rejections before first
use; update the initialization to handle failures by creating a safe init
routine (e.g., an async initKeys or lazy factory) that wraps subtle.generateKey
calls in try/catch (or attaches .catch) and stores either the resolved
CryptoKey/CryptoKeyPair or a captured error; then have Cipher.encrypt,
Cipher.decrypt, Cipher.sign and Cipher.verify await the initialized result and
rethrow the captured error with a clear message if key generation failed so
errors surface deterministically instead of producing unhandled rejections.
In `@packages/library/src/common/international.library.ts`:
- Around line 24-27: getDF currently constructs new (Intl as
any).DurationFormat(...) with no protection; wrap that construction in a
try/catch and return a safe fallback object when construction throws or returns
a partial implementation. Specifically, inside getDF (the memoized factory) try
to construct (Intl as any).DurationFormat(locale, options) and verify it has a
callable format method; on any error or missing format, return an object with
format: (duration) => String(duration) (or a sensible fallback string) so
callers like formatDuration can safely call .format without crashing.
In `@packages/library/src/common/logger.class.ts`:
- Around line 32-36: parseLogLevel currently accepts any numeric DebugLevel and
returns it as LOG without bounds checking; update the isNumber branch in
parseLogLevel to validate that the numeric value is within the valid LOG enum
range (e.g., 0–5) and return fallback if it's out of range (or clamp to the
nearest valid value), so invalid numbers like 999 won't be treated as a valid
LOG; reference the parseLogLevel function and the LOG enum (and use Level/Method
branches unchanged) when adding this numeric validation.
In `@packages/library/test/common/boundary.library.test.ts`:
- Line 23: Update the test assertion in boundary.library.test.ts so it expects
an Error object instead of the literal message string: change the assertion
referencing mockLogger.error to verify that mockLogger.error was called with an
Error instance (or with a new Error('Test Exception')) so it matches the
implementation that passes the full Error object.
In `@packages/tempo/bench/benchmark-results.json`:
- Around line 1-42: The committed autogenerated benchmark file is causing churn;
update the test runner that calls fs.writeFileSync('benchmark-results.json',
...) (in runner.test.ts) to write outputs to an untracked path (e.g., a tmp or
bench-output directory) or to a timestamped/versioned filename, and add a
.gitignore rule to ignore bench JSON outputs (e.g., ignore
benchmark-results.json or *.bench/*.json or packages/tempo/bench/*.json) so
CI/local runs don’t change tracked files; alternatively, if you intend to keep a
snapshot, make the runner produce explicit snapshot files and document that
behavior in tempo.benchmarks.md.
In `@packages/tempo/bin/push-docs.sh`:
- Line 36: Quote the branch variable when invoking git to avoid word-splitting
or special-character issues: replace uses of git checkout $CURRENT_BRANCH with
git checkout "$CURRENT_BRANCH" (apply at the other occurrence as well) — locate
the git checkout calls that reference the CURRENT_BRANCH variable and wrap the
variable in double quotes.
- Line 30: Update the git checkout invocation in push-docs.sh to quote the
branch variable but leave the paths unquoted: ensure the CURRENT_BRANCH
reference is quoted (to prevent globbing/word-splitting) while DOC_PATHS remains
unquoted so it can expand to multiple arguments; modify the line using git
checkout with "$CURRENT_BRANCH" -- $DOC_PATHS to fix the issue in the script.
In `@packages/tempo/src/support/support.init.ts`:
- Around line 167-174: The current assignment to runtime.license.status can end
up as null/undefined when res.status is unexpected; update the logic that builds
desc and uses statusMap so the final value always falls back to LICENSE.Invalid
(use LICENSE.Invalid instead of res.status when no mapping found). Specifically,
ensure desc handles null/undefined safely (so desc is not the string
'null'/'undefined') and change the lookup to use statusMap[desc] ??
LICENSE.Invalid; update references in this block (desc, statusMap,
runtime.license.status, LICENSE.Invalid) accordingly.
In `@packages/tempo/src/support/support.license.ts`:
- Around line 29-37: definePremiumPlugin currently only replaces object hook
properties but leaves function-style plugins (passed to Tempo.extend) untouched;
detect when the provided plugin is a function (typeof plugin === 'function') and
replace it with a wrapper function that immediately throws the same license
Error (use the existing throwLicense message) so function plugins cannot execute
in community builds, while keeping the existing behavior for object plugins
(replace install/define/resolve). Keep the logWarn and return type semantics
(return the replaced wrapper or modified object) and ensure references to
definePremiumPlugin and Tempo.extend behavior are considered.
In `@packages/tempo/src/support/support.util.ts`:
- Around line 52-56: The code duplicates appended text because when err is a
string the branch using isString(err) builds new Error(`${err} ${text}`) and
then the subsequent isError/isString check appends text again; fix by making the
isString(err) branch create new Error(err) (omit `${text}`) and let the existing
block that checks isError(err) and appends text handle adding concatMsg(msg), or
alternatively add a guard so the second append only runs when the original err
was not a string; update the logic around concatMsg(msg), isString(err),
isError(err) and err.message accordingly.
In `@packages/tempo/src/tsconfig.repl.json`:
- Around line 29-32: The tsconfig REPL path mapping for the alias
"`#tempo/license`" contains a dead first target "../premium/src/index.ts" which
does not exist in the repo and is always bypassed in favor of
"./support/support.license.ts"; remove the non-existent
"../premium/src/index.ts" entry from the "`#tempo/license`" array, or if it is
intentionally scaffolding add a one-line comment/TODO next to the alias
explaining that the top-level premium package will be added later so reviewers
know it’s intentional, keeping the alias array only with the valid
"./support/support.license.ts" entry otherwise.
In `@packages/tempo/test/module/module.benchmark.test.ts`:
- Line 35: Remove the leftover debug console.log call that prints the benchmark
results: locate the console.log('BENCHMARK RESULTS:', results) in the
module.benchmark.test.ts test and delete it (or replace it with an appropriate
assertion or test-runner logger if you need to persist output), ensuring only
test assertions remain and no debug stdout is emitted during CI runs.
---
Outside diff comments:
In `@packages/tempo/bench/bench.parse.prefilter.e2e.ts`:
- Around line 14-18: The path passed to fs.readFileSync is missing the file
extension so new URL('./bench.parse.prefilter', import.meta.url) resolves to a
non-existent extensionless file and triggers the fallback dataset; update the
URL to point to the actual file (e.g. use './bench.parse.prefilter.ts') in the
call that builds corpus so the code in bench.parse.prefilter.e2e.ts reads the
real corpus file instead of falling back.
In `@packages/tempo/src/tempo.class.ts`:
- Around line 638-711: The logger level is set early with
setLogLevel(options.debug ?? Default?.debug ?? LOG.Info) before
this[$setConfig](...) merges store/discovery values into state.config, so
persisted or discovered debug settings are ignored; after the unified merge call
this[$setConfig](...) completes, re-apply the effective level by calling
setLogLevel with the merged value (e.g. setLogLevel(state.config.debug ??
options.debug ?? Default?.debug ?? LOG.Info) or simply
setLogLevel(state.config.debug ?? LOG.Info) so the logger reflects the final
state.config); update immediately after the this[$setConfig](...) invocation.
- Around line 346-377: The discovery processing is mutating shared registries
via registryUpdate for formats, timeZones, numbers and MONTH_DAY; when discovery
is from a sandbox this leaks into global state. Fix by detecting sandbox
discovery (e.g., a boolean flag on the discovery object or a parameter passed
into the method) and: if sandbox, do not call registryUpdate for the entries
processed in the blocks handling discovery.timeZones, discovery.numbers,
discovery.monthDay (and the formats block) — instead merge those values into a
local opts/registry object returned or used only by the instance; if not
sandbox, continue to call registryUpdate as before. Ensure the same guard is
applied for the later registryUpdate calls related to MONTH_DAY and intl so
sandbox data never mutates the shared registry.
In `@packages/tempo/test/plugins/licensing.full.test.ts`:
- Around line 196-234: Remove the duplicate await call to rt.license.jws (the
second await on the same promise immediately after the first) in the test 'Eager
Discovery Guard: blocks premium plugins when license is revoked' so only a
single await rt.license.jws remains before checking rt.license.status; this
cleans up the redundant no-op await and prevents confusion about a possible
copy/paste error.
- Around line 101-113: The test is racy: after calling Tempo.init({ license:
mockToken }) the license verification may resolve synchronously, so assertions
against Tempo.license.status can be nondeterministic; fix by awaiting the
runtime bridge license promise before asserting (e.g. await rt.license.jws or
the equivalent promise exposed by the runtime bridge created by new Tempo()) and
then assert the resolved state, or if you intend to assert the Pending state,
modify the mock verification to delay resolution (make the verification promise
async/delayed) and then assert Tempo.license.status === LICENSE.Pending
immediately after Tempo.init; reference Tempo.init, new Tempo(), Tempo.license
and rt.license.jws to locate where to await or where to stub the verifier.
---
Nitpick comments:
In `@packages/library/src/browser/mapper.library.ts`:
- Around line 130-131: Replace remaining raw console calls in
packages/library/src/browser/mapper.library.ts (inside the mapQuery flow) with
the module Logger instance (log) for consistency: change console.log('mapQuery:
cache') and the other console.* usages at the equivalent spots (the calls around
the cache path, fallback/path checks, and error/info messages—previously at
lines similar to 130,147,163,176,203) to use log.debug or
log.info/log.warn/log.error as appropriate, keeping the same message text and
honoring the existing opts.debug guard by using log.debug when opts.debug is
checked; ensure you import/use the existing log instance used on lines 71 and
87-88 and remove direct console.* usage.
In `@packages/library/src/common/cipher.class.ts`:
- Around line 95-100: The code currently uses non-null assertions on (await
_asymmetricKey).privateKey and .publicKey when calling subtle.sign and
subtle.verify; replace these assertions with explicit runtime checks: await
_asymmetricKey once, verify that keypair.privateKey (for the sign flow) or
keypair.publicKey (for verify) exist and throw a descriptive error (or return a
rejected Promise) if missing, then pass the validated key to
subtle.sign/subtle.verify together with Cipher.encodeBuffer/Cipher.decodeBuffer;
reference the _asymmetricKey promise, subtle.sign/subtle.verify calls, and the
Cipher.encodeBuffer/Cipher.decodeBuffer helpers when making the change.
In `@packages/library/src/common/logger.class.ts`:
- Line 96: The current mapping maps Method.Trace to console.debug which hides
the semantic behavior of console.trace; update the mapping in logger.class (the
assignment that sets consoleMethod for Method.Trace) to use 'trace' so calls to
Method.Trace invoke console.trace and produce a stack trace, or if stack traces
are intentionally undesired, rename the enum value Method.Trace to Method.Debug
(and update all callers) and add a clear comment in logger.class explaining the
chosen behavior.
In `@packages/tempo/doc/architecture.md`:
- Line 33: Reword the awkward sentence about $LogConfig for clarity: replace
"Note that `$LogConfig` is already a Symbol created via
`Symbol.for('$LibraryLogConfig')`" with a clearer phrasing such as "The
$LogConfig identifier is a Symbol (created with
Symbol.for('$LibraryLogConfig'))" or "Note: $LogConfig is a Symbol created using
Symbol.for('$LibraryLogConfig')". Update the line referencing sym.$LogConfig and
Symbol.for('$LibraryLogConfig') in the architecture.md paragraph so it reads
smoothly and unambiguously.
In `@packages/tempo/test/module/module.benchmark.test.ts`:
- Line 23: Replace the fragile exact string assertion for native.successRate in
the test (module.benchmark.test.ts) with a tolerant check: either parse the
numeric percentage from native.successRate and assert the numeric value equals
50 (or within a small delta), or assert the string matches a regex like
/^50(\.0+)?%$/; update the expectation that currently uses
expect(native.successRate).toBe('50.0%') to one of these more robust forms to
avoid formatting brittleness.
🪄 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: 26169a30-33b5-46a4-89d9-a46d8e23a663
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (128)
.gitignoreCHANGELOG.mdpackage.jsonpackages/library/doc/browser/types.mdpackages/library/package.jsonpackages/library/src/browser/mapper.library.tspackages/library/src/browser/webstore.class.tspackages/library/src/common.index.tspackages/library/src/common/array.library.tspackages/library/src/common/assertion.library.tspackages/library/src/common/boundary.library.tspackages/library/src/common/cipher.class.tspackages/library/src/common/class.library.tspackages/library/src/common/function.library.tspackages/library/src/common/international.library.tspackages/library/src/common/logger.class.tspackages/library/src/common/logify.class.tspackages/library/src/common/number.library.tspackages/library/src/common/object.library.tspackages/library/src/common/pledge.class.tspackages/library/src/common/reflection.library.tspackages/library/src/common/symbol.library.tspackages/library/src/common/type.library.tspackages/library/src/server/file.library.tspackages/library/test/common/boundary.library.test.tspackages/library/test/common/logger.class.test.tspackages/library/test/common/logify.class.test.tspackages/library/test/common/pledge.class.test.tspackages/library/vitest.config.tspackages/tempo/.vitepress/config.tspackages/tempo/CHANGELOG.mdpackages/tempo/CONTRIBUTING.mdpackages/tempo/bench/bench.parse.prefilter.e2e.tspackages/tempo/bench/bench.parse.prefilter.tspackages/tempo/bench/benchmark-results.jsonpackages/tempo/bench/runner.test.tspackages/tempo/bench/test-benchmark-output.tspackages/tempo/bench/test-pizza.test.tspackages/tempo/bench/test-pizza.tspackages/tempo/bench/tsconfig.jsonpackages/tempo/bin/push-docs.shpackages/tempo/bin/repl.tspackages/tempo/bin/tsconfig.jsonpackages/tempo/doc/architecture.mdpackages/tempo/doc/commercial.mdpackages/tempo/doc/migration-guide.mdpackages/tempo/doc/release-notes-v3.0.0.mdpackages/tempo/doc/releases/v2.x.mdpackages/tempo/doc/sandbox-factory.mdpackages/tempo/doc/soft_freeze_strategy.mdpackages/tempo/doc/tempo.benchmarks.mdpackages/tempo/doc/tempo.config.mdpackages/tempo/doc/tempo.cookbook.mdpackages/tempo/doc/tempo.debugging.mdpackages/tempo/doc/tempo.duration.mdpackages/tempo/doc/tempo.extension.mdpackages/tempo/doc/tempo.format.mdpackages/tempo/doc/tempo.layout.mdpackages/tempo/doc/tempo.month-day.mdpackages/tempo/doc/tempo.pledge.mdpackages/tempo/doc/tempo.plugin.mdpackages/tempo/doc/tempo.term.mdpackages/tempo/doc/tempo.ticker.mdpackages/tempo/importmap.jsonpackages/tempo/index.mdpackages/tempo/package.jsonpackages/tempo/rollup.config.jspackages/tempo/src/engine/engine.alias.tspackages/tempo/src/engine/engine.composer.tspackages/tempo/src/engine/engine.guard.tspackages/tempo/src/engine/engine.lexer.tspackages/tempo/src/engine/engine.normalizer.tspackages/tempo/src/engine/engine.pattern.tspackages/tempo/src/engine/engine.planner.tspackages/tempo/src/engine/engine.term.tspackages/tempo/src/library.index.tspackages/tempo/src/module/module.benchmark.tspackages/tempo/src/module/module.duration.tspackages/tempo/src/module/module.format.tspackages/tempo/src/module/module.mutate.tspackages/tempo/src/module/module.parse.tspackages/tempo/src/plugin/plugin.index.tspackages/tempo/src/plugin/plugin.util.tspackages/tempo/src/support/support.default.tspackages/tempo/src/support/support.enum.tspackages/tempo/src/support/support.error.tspackages/tempo/src/support/support.index.tspackages/tempo/src/support/support.init.tspackages/tempo/src/support/support.intl.tspackages/tempo/src/support/support.license.tspackages/tempo/src/support/support.register.tspackages/tempo/src/support/support.symbol.tspackages/tempo/src/support/support.util.tspackages/tempo/src/tempo.class.tspackages/tempo/src/tempo.type.tspackages/tempo/src/tsconfig.jsonpackages/tempo/src/tsconfig.repl.jsonpackages/tempo/test/core/alias-engine-protochain.test.tspackages/tempo/test/core/alias-engine.test.tspackages/tempo/test/core/dispose.core.test.tspackages/tempo/test/core/sandbox-factory.test.tspackages/tempo/test/engine/parse.prefilter.flag.test.tspackages/tempo/test/instance/instance.since.rtf.test.tspackages/tempo/test/issues/issue-fixes.test.tspackages/tempo/test/module/module.benchmark.test.tspackages/tempo/test/plugins/duration.balance.test.tspackages/tempo/test/plugins/licensing.full.test.tspackages/tempo/test/plugins/plugin_registration.test.tspackages/tempo/test/plugins/slick.verification.test.tspackages/tempo/test/plugins/ticker.active.test.tspackages/tempo/test/plugins/ticker.hang.test.tspackages/tempo/test/plugins/ticker.options.test.tspackages/tempo/test/plugins/ticker.patterns.test.tspackages/tempo/test/plugins/ticker.pulse.test.tspackages/tempo/test/plugins/ticker.stop.test.tspackages/tempo/test/plugins/ticker.term.core.test.tspackages/tempo/test/plugins/ticker_cold_start.test.tspackages/tempo/test/support/error-handling.test.tspackages/tempo/test/support/library-import.test.tspackages/tempo/test/support/proof.test.tspackages/tempo/test/support/symbol-import.test.tspackages/tempo/test/tsconfig.jsonpackages/tempo/tsconfig.build.jsonpackages/tempo/tsconfig.jsonpackages/tempo/vitest.config.tspackages/tempo/vitest.workspace.tsvitest.config.tsvitest.workspace.ts
💤 Files with no reviewable changes (18)
- packages/tempo/test/plugins/ticker.pulse.test.ts
- vitest.workspace.ts
- packages/tempo/vitest.workspace.ts
- packages/tempo/test/plugins/ticker.hang.test.ts
- packages/tempo/test/plugins/ticker_cold_start.test.ts
- packages/tempo/test/support/error-handling.test.ts
- packages/tempo/test/support/library-import.test.ts
- packages/tempo/test/tsconfig.json
- packages/tempo/test/plugins/ticker.stop.test.ts
- packages/tempo/test/plugins/ticker.options.test.ts
- packages/library/test/common/logify.class.test.ts
- packages/tempo/importmap.json
- packages/library/src/common/logify.class.ts
- packages/tempo/bin/tsconfig.json
- packages/tempo/test/plugins/ticker.term.core.test.ts
- packages/tempo/test/plugins/ticker.patterns.test.ts
- packages/tempo/test/plugins/ticker.active.test.ts
- packages/tempo/test/plugins/slick.verification.test.ts
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/tempo/bin/push-docs.sh (1)
7-7:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse an array for doc paths to avoid path-splitting bugs.
Line 7 + Line 30 rely on word-splitting. If the repo path contains spaces, checkout arguments break. Use a Bash array and expand with
"${DOC_PATHS[@]}".Proposed fix
-DOC_PATHS="$TEMPO_ROOT/doc/ $TEMPO_ROOT/img/ $TEMPO_ROOT/index.md $TEMPO_ROOT/typedoc.json $TEMPO_ROOT/.vitepress/" +DOC_PATHS=( + "$TEMPO_ROOT/doc/" + "$TEMPO_ROOT/img/" + "$TEMPO_ROOT/index.md" + "$TEMPO_ROOT/typedoc.json" + "$TEMPO_ROOT/.vitepress/" +) @@ -git checkout "$CURRENT_BRANCH" -- $DOC_PATHS +git checkout "$CURRENT_BRANCH" -- "${DOC_PATHS[@]}"Also applies to: 30-30
🤖 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/push-docs.sh` at line 7, Replace the space-delimited DOC_PATHS string with a Bash array named DOC_PATHS (e.g., DOC_PATHS=( ... )) and update any usage sites (the checkout/rsync/git commands referencing DOC_PATHS, noted around the current startLine 30) to expand the paths as "${DOC_PATHS[@]}", so paths containing spaces are preserved; ensure quotes are used when expanding and that any loops or commands that previously relied on word-splitting now iterate over the array elements.Source: Linters/SAST tools
♻️ Duplicate comments (1)
packages/tempo/src/support/support.init.ts (1)
166-173:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUnexpected status values may bypass
LICENSE.Invalidfallback.The fallback chain
statusMap[desc] ?? res.status ?? LICENSE.Invalidallows unexpected status values (like'pending'or other strings) to pass through asres.statusinstead of defaulting toLICENSE.Invalid. This contradicts the intent of the statusMap normalization.🛡️ Suggested fix to ensure strict mapping
-runtime.license.status = statusMap[desc] ?? res.status ?? LICENSE.Invalid; +runtime.license.status = statusMap[desc] ?? LICENSE.Invalid;🤖 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/support/support.init.ts` around lines 166 - 173, The code lets unexpected res.status values bypass normalization because it falls back to res.status; change the assignment so only mapped values are accepted and anything else becomes LICENSE.Invalid. Specifically, update the logic around desc, statusMap, and runtime.license.status (currently using statusMap[desc] ?? res.status ?? LICENSE.Invalid) to use only statusMap[desc] ?? LICENSE.Invalid, ensuring runtime.license.status is set to a member of LICENSE or LICENSE.Invalid for unrecognized statuses.
🧹 Nitpick comments (2)
packages/tempo/src/support/support.init.ts (1)
185-193: 💤 Low valueSilent catch in revocationPromise handler.
The
.catch(() => { /* silent fail-safe */ })swallows all errors including unexpected runtime exceptions. While this prevents unhandled rejections, consider logging at debug/trace level for diagnostics.🤖 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/support/support.init.ts` around lines 185 - 193, The catch block on the revocationPromise silently swallows errors; update the handler for res.revocationPromise in support.init.ts to log caught errors (at debug/trace level) instead of leaving the catch empty — preserve the fail-safe behavior but call an existing logger (e.g., logDebug or logTrace) with the error and context (include initialJti, initialKey, and runtime.license.jti/key) so you still set runtime.license.status = LICENSE.Revoked and runtime.license.error when appropriate; reference the res.revocationPromise.then(...) chain, runtime.license, LICENSE.Revoked, logWarn, and state.config to locate where to add the debug-level logging in the .catch.packages/tempo/src/support/support.license.ts (1)
15-24: 💤 Low valueUnused
claimsvariable in community Validator.verify().The
decodeJWT(this.key)result is assigned toclaimsbut never used. This appears intentional for the no-op community build, but the unused variable could be removed for clarity.🧹 Remove unused variable
async verify() { // Decodes but DOES NOT verify the signature. // Cannot safely unlock Premium Plugins without cryptographic proof. - const claims = decodeJWT(this.key); + decodeJWT(this.key); // No-op: decodes but cannot verify without crypto engine return { status: 'invalid' as const, scopes: {},🤖 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/support/support.license.ts` around lines 15 - 24, The verify() method assigns decodeJWT(this.key) to an unused variable claims; remove the unused variable by either deleting the call entirely if there are no side-effects, or invoking decodeJWT(this.key) without assignment (i.e., call it for side-effects only) inside the async verify() method. Update the function body in support.license.ts (the async verify() method) to eliminate the unused claims variable while keeping behavior consistent.
🤖 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/buffer.library.ts`:
- Around line 14-15: The code directly references the global identifier Buffer
inside isDefined(Buffer), which throws a ReferenceError in environments without
Buffer; replace those checks with a safe existence test like typeof Buffer !==
'undefined' or using globalThis?.Buffer before calling
Buffer.from(...).toString('base64') (apply the same change where Buffer is
checked/used at the other location), so the btoa/atob fallback is reachable
without errors.
In `@packages/library/src/common/cipher.library.ts`:
- Around line 56-61: encrypt accepts any but passes data to encodeBuffer which
only handles strings, causing silent corruption for non-strings; update the
encrypt function (encrypt) to either restrict its input type to string or
explicitly serialize non-string inputs (e.g., JSON.stringify) before calling
encodeBuffer(data), and ensure callers reflect the chosen contract; locate
references to encodeBuffer and _cryptoKey in encrypt to implement the change and
add a short validation/serialization step so only valid string bytes are
encrypted.
- Around line 83-91: The sign function currently decodes signature bytes to
UTF‑8 via decodeBuffer causing lossy signatures and mismatch with verify; update
sign (and ensure verify) to return and accept raw binary (ArrayBuffer or
Uint8Array) directly from subtle.sign/subtle.verify without calling decodeBuffer
so the signature remains reversible (refer to sign, verify, decodeBuffer,
_asymmetricKey, subtle.sign, subtle.verify); also fix encrypt to either enforce
a string input or explicitly serialize/coerce non-string data (e.g.
JSON.stringify) before passing to encodeBuffer to avoid silent corruption (refer
to encrypt and encodeBuffer) so encoding is deterministic and lossless.
In `@packages/library/src/common/webtoken.library.ts`:
- Around line 13-23: The decodeJWT function currently uses atob(...) or
Buffer.from(...).toString() which yields raw binary strings and corrupts
non-ASCII UTF‑8 JSON payloads; change decodeJWT to convert the base64url payload
into a Buffer via the shared helper base64ToBuffer and then decode the UTF‑8
bytes using decodeBuffer before JSON.parse (use base64url→base64 normalization
first). Also update verifyJWS to ensure you add proper '=' padding when
converting base64url to base64 before calling base64ToBuffer (so the atob
fallback gets correctly padded input), keeping the existing normalization logic
but appending padding as needed.
---
Outside diff comments:
In `@packages/tempo/bin/push-docs.sh`:
- Line 7: Replace the space-delimited DOC_PATHS string with a Bash array named
DOC_PATHS (e.g., DOC_PATHS=( ... )) and update any usage sites (the
checkout/rsync/git commands referencing DOC_PATHS, noted around the current
startLine 30) to expand the paths as "${DOC_PATHS[@]}", so paths containing
spaces are preserved; ensure quotes are used when expanding and that any loops
or commands that previously relied on word-splitting now iterate over the array
elements.
---
Duplicate comments:
In `@packages/tempo/src/support/support.init.ts`:
- Around line 166-173: The code lets unexpected res.status values bypass
normalization because it falls back to res.status; change the assignment so only
mapped values are accepted and anything else becomes LICENSE.Invalid.
Specifically, update the logic around desc, statusMap, and
runtime.license.status (currently using statusMap[desc] ?? res.status ??
LICENSE.Invalid) to use only statusMap[desc] ?? LICENSE.Invalid, ensuring
runtime.license.status is set to a member of LICENSE or LICENSE.Invalid for
unrecognized statuses.
---
Nitpick comments:
In `@packages/tempo/src/support/support.init.ts`:
- Around line 185-193: The catch block on the revocationPromise silently
swallows errors; update the handler for res.revocationPromise in support.init.ts
to log caught errors (at debug/trace level) instead of leaving the catch empty —
preserve the fail-safe behavior but call an existing logger (e.g., logDebug or
logTrace) with the error and context (include initialJti, initialKey, and
runtime.license.jti/key) so you still set runtime.license.status =
LICENSE.Revoked and runtime.license.error when appropriate; reference the
res.revocationPromise.then(...) chain, runtime.license, LICENSE.Revoked,
logWarn, and state.config to locate where to add the debug-level logging in the
.catch.
In `@packages/tempo/src/support/support.license.ts`:
- Around line 15-24: The verify() method assigns decodeJWT(this.key) to an
unused variable claims; remove the unused variable by either deleting the call
entirely if there are no side-effects, or invoking decodeJWT(this.key) without
assignment (i.e., call it for side-effects only) inside the async verify()
method. Update the function body in support.license.ts (the async verify()
method) to eliminate the unused claims variable while keeping behavior
consistent.
🪄 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: cd99dddf-6db5-43f2-95c8-4c66fcd674cb
📒 Files selected for processing (42)
.gitignoreCHANGELOG.mdpackages/library/CHANGELOG.mdpackages/library/src/browser/mapper.library.tspackages/library/src/common.index.tspackages/library/src/common/boundary.library.tspackages/library/src/common/buffer.library.tspackages/library/src/common/cipher.class.tspackages/library/src/common/cipher.library.tspackages/library/src/common/coercion.library.tspackages/library/src/common/international.library.tspackages/library/src/common/logger.class.tspackages/library/src/common/utility.library.tspackages/library/src/common/webtoken.library.tspackages/library/src/server.index.tspackages/library/src/server/auth.library.tspackages/library/src/server/buffer.library.tspackages/library/test/common/boundary.library.test.tspackages/tempo/CHANGELOG.mdpackages/tempo/bench/bench.parse.prefilter.e2e.tspackages/tempo/bin/push-docs.shpackages/tempo/doc/architecture.mdpackages/tempo/doc/migration-guide.mdpackages/tempo/doc/sandbox-factory.mdpackages/tempo/doc/tempo.config.mdpackages/tempo/doc/tempo.debugging.mdpackages/tempo/package.jsonpackages/tempo/src/engine/engine.composer.tspackages/tempo/src/engine/engine.lexer.tspackages/tempo/src/engine/engine.normalizer.tspackages/tempo/src/library.index.tspackages/tempo/src/module/module.parse.tspackages/tempo/src/plugin/extend/extend.ticker.tspackages/tempo/src/support/support.init.tspackages/tempo/src/support/support.license.tspackages/tempo/src/support/support.runtime.tspackages/tempo/src/support/support.util.tspackages/tempo/src/tempo.class.tspackages/tempo/src/tempo.type.tspackages/tempo/src/tsconfig.repl.jsonpackages/tempo/test/module/module.benchmark.test.tspackages/tempo/test/plugins/licensing.full.test.ts
💤 Files with no reviewable changes (4)
- packages/tempo/src/tsconfig.repl.json
- packages/library/src/server/buffer.library.ts
- packages/library/src/server.index.ts
- packages/library/src/common/cipher.class.ts
✅ Files skipped from review due to trivial changes (6)
- packages/library/CHANGELOG.md
- packages/tempo/doc/architecture.md
- CHANGELOG.md
- packages/tempo/doc/tempo.debugging.md
- packages/tempo/doc/migration-guide.md
- packages/tempo/CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (11)
- packages/tempo/doc/sandbox-factory.md
- packages/library/test/common/boundary.library.test.ts
- packages/library/src/common.index.ts
- packages/library/src/common/boundary.library.ts
- packages/tempo/src/engine/engine.normalizer.ts
- .gitignore
- packages/tempo/test/module/module.benchmark.test.ts
- packages/library/src/common/logger.class.ts
- packages/tempo/doc/tempo.config.md
- packages/tempo/src/engine/engine.composer.ts
- packages/tempo/src/support/support.util.ts
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/tempo/src/support/support.init.ts`:
- Around line 166-167: The code assigns verifier output directly to
runtime.license.status and runtime.license.scopes; validate both before
applying: check res.status against the allowed LICENSE enum members (accept only
known values like LICENSE.Valid / LICENSE.Invalid / LICENSE.Blocked, otherwise
set runtime.license.status = LICENSE.Invalid) and ensure res.scopes is an
object/expected shape (if typeof res.scopes !== 'object' || res.scopes === null
use an empty object or the existing runtime.license.scopes fallback). Update the
assignment site (where runtime.license.status and runtime.license.scopes are
set) to perform these guards so unexpected values cannot bypass blocked-status
checks or poison downstream state.
In `@packages/tempo/src/support/support.util.ts`:
- Around line 221-223: The function resolveDisplayStatus currently maps any
unrecognized status to LICENSE.Active; change it so unknown inputs are mapped to
a safe "unknown" value instead of Active: update resolveDisplayStatus to check
String(status) against LICENSE.values() and return that value if present,
otherwise return LICENSE.Unknown (or a dedicated safe constant on the LICENSE
enum/object) so unexpected statuses do not present as Active; ensure references
to LICENSE.values() and LICENSE.Unknown are used consistently.
🪄 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: 091100ba-d369-4d3c-8984-f97805d24d3b
📒 Files selected for processing (13)
packages/library/src/common/buffer.library.tspackages/library/src/common/cipher.library.tspackages/library/src/common/coercion.library.tspackages/library/src/common/temporal.polyfill.tspackages/library/src/common/webtoken.library.tspackages/tempo/bin/push-docs.shpackages/tempo/doc/tempo.plugin.mdpackages/tempo/src/plugin/term/term.util.tspackages/tempo/src/support/support.enum.tspackages/tempo/src/support/support.init.tspackages/tempo/src/support/support.license.tspackages/tempo/src/support/support.util.tspackages/tempo/src/tempo.class.ts
🚧 Files skipped from review as they are similar to previous changes (5)
- packages/tempo/src/support/support.enum.ts
- packages/tempo/bin/push-docs.sh
- packages/library/src/common/webtoken.library.ts
- packages/library/src/common/buffer.library.ts
- packages/tempo/src/support/support.license.ts
Breaking Changes
Ticker moved to a standalone premium plugin (separate install/registration required).
Config keys renamed: relativeTime → relativeTimeFormat; debug now accepts numeric or string levels.
UTC ISO output now uses higher-precision Temporal formatting.
New Features
New compact date/time tokens and uppercase ordinal tokens.
Duration formatting supports Intl.DurationFormat with multi-unit output.
Improvements
Centralized diagnostic/logging with numeric verbosity.
Package versions bumped to v3.0.0.
Documentation
Migration guide, release notes, and examples updated.
Tests
Legacy ticker tests removed; logging and new boundary/logger tests added.
Summary by CodeRabbit
Breaking Changes
New Features
Bug Fixes
Documentation