fix(automations): don't flag valid-but-wrong-trigger {{ }} tokens as typos (#3653)#3739
Conversation
…typos (#3653) The token highlighter scoped validity to the current trigger only, so a real token used under a different trigger (e.g. {{ trigger.from }} on a System or Schedule automation — `from` only exists for message triggers) was flagged red, identical to a genuine typo. Reported as "it flags all expansions as invalid". Now three tiers: valid-for-this-trigger = blue (ok); a real token belonging to a DIFFERENT trigger = amber (foreign) with a soft "not available for this trigger — renders blank" note (NOT a typo); unrecognized everywhere = red with the typo warning. classifyToken() drives all of it; unknownTokens() lists only true typos. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VBLhGGNh35oMwTL53va1Y5
|
Claude finished @Yeraze's task —— View job PR Review: fix(automations): don't flag valid-but-wrong-trigger {{ }} tokens as typos
SummaryThis PR correctly addresses the false-positive typo detection for cross-trigger tokens. The three-tier classification ( tokenHints.tsModule-level mutable cache ( let anyCache: Set<string> | null = null;
export function anyTriggerTokenSet(): Set<string> {
if (anyCache) return anyCache;
...
anyCache = set;
return set;
}
const ANY_TRIGGER_TOKEN_SET: Set<string> = (() => {
const set = new Set<string>();
for (const toks of Object.values(TRIGGER_TOKENS)) for (const [k] of toks) set.add(`trigger.${k}`);
for (const [k] of UNIVERSAL_TOKENS) set.add(`trigger.${k}`);
return set;
})();This also removes the need to export
if (path.length === 0 || valid.has(path)) return 'ok';Returning TokenTextField.tsxFour separate const valid = useMemo(() => validTokenSet(triggerType, variableNames), [...]);
const segs = useMemo(() => tokenize(value, valid), [value, valid]);
const unknown = useMemo(() => unknownTokens(value, valid), [value, valid]);
const foreign = useMemo(() => foreignTokens(value, valid), [value, valid]);
Doc comment is stale — The JSDoc says "blue when recognized, red+wavy when not" but no longer mentions amber/foreign. Minor, but worth updating to match the three-tier model described in the PR. CSS
.ae-tokenfield-backdrop .ae-token-foreign {
background: color-mix(in srgb, var(--ctp-yellow) 26%, transparent);
color: var(--ctp-text); border-radius: 3px; text-decoration: underline dotted var(--ctp-yellow);
}Looks correct and consistent with the Tests
The module-level Coverage is good — the three Missing edge case: Minor
VerdictApprove with suggestions. The core fix is correct and well-tested. The main actionable items are:
None of these are blocking. |
…3653) Replaces the two summary notes with a dynamic bar that lists each problematic token on its own line with a type-specific message: - {{ var.asfd }} → "does not exist" (no such variable) - {{ trigger.from }} on a non-message trigger → "is undefined for this trigger" (warn) - {{ trigger.asfd }} → "is not a recognized trigger field" - {{ foo }} → "is not a recognized token" Errors render red (✕), the cross-trigger warning amber (⚠). diagnoseTokens() is the single source; valid tokens produce nothing (bar hidden when clean). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VBLhGGNh35oMwTL53va1Y5
|
Claude finished @Yeraze's task —— View job PR Review: fix(automations): don't flag valid-but-wrong-trigger {{ }} tokens as typos
SummaryThe PR correctly addresses the false-positive typo flagging. The three-tier classification ( tokenHints.ts
Mutable module-level cache — let anyCache: Set<string> | null = null;
export function anyTriggerTokenSet(): Set<string> {
if (anyCache) return anyCache;
...Since const ANY_TRIGGER_TOKEN_SET: Set<string> = (() => {
const set = new Set<string>();
for (const toks of Object.values(TRIGGER_TOKENS)) for (const [k] of toks) set.add(`trigger.${k}`);
for (const [k] of UNIVERSAL_TOKENS) set.add(`trigger.${k}`);
return set;
})();This is not a blocking issue —
if (path.length === 0 || valid.has(path)) return 'ok';Returning TokenTextField.tsxStale JSDoc — The doc comment still says "blue when recognized, red+wavy when not". It should mention the three tiers now (blue/amber/red) to match reality. Minor, but the comment actively misleads anyone reading it.
CSS
TestsCoverage is solid for the happy paths: One missing edge case — there's no test asserting it('var.* tokens are never foreign, only bad', () => {
const sys = validTokenSet('trigger.system', []);
expect(classifyToken('var.nope', sys)).toBe('bad'); // not 'foreign'
});
VerdictApprove. The core fix is correct and well-tested. Two actionable items, neither blocking:
|
…3653) The bar lived inside .ae-tokenfield, so the container grew to include it and the backdrop (position:absolute inset:0, opaque bg) painted over the bar — visible as an empty box below the field, with the diagnostics hidden. Move the bar to a sibling outside the overlay box (wrap both in a fragment) so the backdrop only covers the input. (This also un-hides what was the amber note.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VBLhGGNh35oMwTL53va1Y5
|
Claude finished @Yeraze's task —— View job PR Review: fix(automations): don't flag valid-but-wrong-trigger {{ }} tokens as typos
SummaryThis PR correctly fixes the false-positive typo detection bug. The three-tier classification ( tokenHints.tsMutable module-level cache — let anyCache: Set<string> | null = null;
export function anyTriggerTokenSet(): Set<string> {
if (anyCache) return anyCache;
...
anyCache = set;
return set;
}Since const ANY_TRIGGER_TOKEN_SET: Set<string> = (() => {
const set = new Set<string>();
for (const toks of Object.values(TRIGGER_TOKENS)) for (const [k] of toks) set.add(`trigger.${k}`);
for (const [k] of UNIVERSAL_TOKENS) set.add(`trigger.${k}`);
return set;
})();This is not blocking —
if (path.length === 0 || valid.has(path)) return 'ok';Returning TokenTextField.tsxStale JSDoc — * tokens colored — blue when recognized, red+wavy when not — while a transparentThis still describes only two tiers. Should mention the three tiers: blue (ok), amber/dotted (foreign), red+wavy (bad). The comment actively misleads maintainers.
No key stability concern — CSS
Tests —
|
Follow-up fix to the token highlighter (#3727).
Bug
Highlighting scoped token validity to the current trigger only. A real token referenced under a different trigger — e.g.
{{ trigger.from }}on a System/Schedule automation (fromonly exists fortrigger.message) — was flagged red, identical to a genuine typo. Reported as "it flags all expansions as invalid" (tested withHi {{trigger.from}} welcome to {{ trigger.asfd }}on a non-message trigger).Fix — three tiers
var.*/NOW).classifyToken()drives the tiers;unknownTokens()lists only true typos,foreignTokens()the cross-trigger ones. So{{ trigger.from }}is never called a typo; only{{ trigger.asfd }}is.Tests
tokenHints.test.tscoversclassifyToken(ok/foreign/bad), and thatunknownTokensflags only genuine typos whileforeignTokenscatches cross-trigger ones. Full suite 7524 passed, 0 failures; tsc + build clean.🤖 Generated with Claude Code