Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions vessel/src/app/api/raven-chat/__tests__/forecastIntent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,4 +341,15 @@ test('cross-year symbolic weather declarations include explicit years', () => {
});
assert.match(context.declaration, /2025/);
assert.match(context.declaration, /2026/);
});

test('parses tonight, this evening, this morning, and this afternoon as today', () => {
const now = new Date('2026-06-04T12:00:00Z');
const expected = { startDate: '2026-06-04', endDate: '2026-06-04' };

assert.deepEqual(parseSymbolicMomentDateRange('tell me about tonight', now), expected);
assert.deepEqual(parseSymbolicMomentDateRange('tell me about...tonight.', now), expected);
assert.deepEqual(parseSymbolicMomentDateRange('how is this evening looking?', now), expected);
assert.deepEqual(parseSymbolicMomentDateRange('what is active this morning?', now), expected);
assert.deepEqual(parseSymbolicMomentDateRange('read this afternoon', now), expected);
});
15 changes: 11 additions & 4 deletions vessel/src/app/api/raven-chat/dateUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@
probe.getUTCDate() === day;
return valid ? trimmed : null;
}

const SAME_DAY_PART_PATTERN = /\b(?:this\s+)?(?:tonight|evening|morning|afternoon)\b/i;

export function parseLooseDateToken(token: string, now: Date = new Date()): string | null {

Check failure on line 42 in vessel/src/app/api/raven-chat/dateUtils.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 18 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=DHCross_Shipyard&issues=AZ8RH6_YlDUuF1_pIAdR&open=AZ8RH6_YlDUuF1_pIAdR&pullRequest=886
const trimmed = token
.trim()
.replace(/[.?!]+$/g, '')
Expand All @@ -58,7 +61,11 @@
}
const normalized = trimmed.toLowerCase().replace(/,/g, ' ').replace(/\s+/g, ' ').trim();
const today = utcStartOfDay(now);
if (normalized === 'now' || normalized === 'today') {
if (
normalized === 'now'
|| normalized === 'today'
|| SAME_DAY_PART_PATTERN.test(normalized)
) {
Comment on lines +64 to +68

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep explicit future day parts from collapsing to today

When a captured phrase combines another date with a day part, this branch treats the whole phrase as same-day before extracting the explicit date. For example, parseLooseDateToken('tomorrow evening', new Date('2026-06-04T12:00:00Z')) now returns 2026-06-04, and ranged phrases like starting tomorrow morning build a window from today instead of June 5. That sends future timing reads to the current day's geometry whenever users add morning/evening/afternoon to a non-today date.

Useful? React with 👍 / 👎.

return toIsoDate(today);
}
if (normalized === 'tomorrow') {
Expand All @@ -84,7 +91,7 @@
...Array.from(phrase.matchAll(/\b\d{4}-\d{2}-\d{2}\b/g)).map((entry) => entry[0]),
...Array.from(phrase.matchAll(/\b(?:jan(?:uary)?|feb(?:ruary)?|mar(?:ch)?|apr(?:il)?|may|june?|july?|aug(?:ust)?|sep(?:t|tember)?|oct(?:ober)?|nov(?:ember)?|dec(?:ember)?)\s+\d{1,2}(?:st|nd|rd|th)?(?:,\s*\d{4}|\s+\d{4})?\b/ig)).map((entry) => entry[0]),
...Array.from(phrase.matchAll(/\b\d{1,2}[/-]\d{1,2}(?:[/-]\d{2,4})?\b/g)).map((entry) => entry[0]),
...Array.from(phrase.matchAll(/\b(?:now|today|tomorrow)\b/ig)).map((entry) => entry[0]),
...Array.from(phrase.matchAll(/\b(?:now|today|tonight|tomorrow|(?:this\s+)?(?:evening|morning|afternoon))\b/ig)).map((entry) => entry[0]),
];

for (const candidate of candidates) {
Expand Down Expand Up @@ -113,7 +120,7 @@
}

const DATE_PHRASE_PREFIX =
String.raw`(?:jan(?:uary)?|feb(?:ruary)?|mar(?:ch)?|apr(?:il)?|may|june?|july?|aug(?:ust)?|sep(?:t|tember)?|oct(?:ober)?|nov(?:ember)?|dec(?:ember)?)\s+\d{1,2}(?:st|nd|rd|th)?(?:,\s*\d{4}|\s+\d{4})?|\d{4}-\d{2}-\d{2}|\d{1,2}[/-]\d{1,2}(?:[/-]\d{2,4})?|today|tomorrow`;
String.raw`(?:jan(?:uary)?|feb(?:ruary)?|mar(?:ch)?|apr(?:il)?|may|june?|july?|aug(?:ust)?|sep(?:t|tember)?|oct(?:ober)?|nov(?:ember)?|dec(?:ember)?)\s+\d{1,2}(?:st|nd|rd|th)?(?:,\s*\d{4}|\s+\d{4})?|\d{4}-\d{2}-\d{2}|\d{1,2}[/-]\d{1,2}(?:[/-]\d{2,4})?|today|tonight|tomorrow|(?:this\s+)?(?:evening|morning|afternoon)`;

function daysBetweenIsoDates(startDate: string, endDate: string): number | null {
const start = parseIsoDate(startDate);
Expand Down Expand Up @@ -141,7 +148,7 @@
};
}

function parseSymbolicMomentDateRangeRaw(userMessage: string, now: Date = new Date()): SymbolicMomentDateRange | null {

Check failure on line 151 in vessel/src/app/api/raven-chat/dateUtils.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 66 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=DHCross_Shipyard&issues=AZ8RH6_ZlDUuF1_pIAdS&open=AZ8RH6_ZlDUuF1_pIAdS&pullRequest=886
if (isExternalReadoutCorrectionPaste(userMessage)) return null;

const normalized = userMessage.toLowerCase();
Expand Down Expand Up @@ -242,7 +249,7 @@
endDate: toIsoDate(utcAddDays(today, span - 1)),
};
}
if (/\btoday\b/.test(normalized)) {
if (/\btoday\b/.test(normalized) || SAME_DAY_PART_PATTERN.test(normalized)) {
const iso = toIsoDate(today);
return { startDate: iso, endDate: iso };
}
Expand Down
54 changes: 50 additions & 4 deletions vessel/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,30 @@
return 'Reading in flight…';
}

function WheelReadingResponseGlyph({
isVisible,
statusText,
}: {
isVisible: boolean;
statusText: string;
}) {

Check warning on line 572 in vessel/src/app/page.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Mark the props of the component as read-only.

See more on https://sonarcloud.io/project/issues?id=DHCross_Shipyard&issues=AZ8RH7AWlDUuF1_pIAdT&open=AZ8RH7AWlDUuF1_pIAdT&pullRequest=886
if (!isVisible) return null;

return (
<div className="pointer-events-none absolute right-3 top-3 z-30 flex items-center gap-2 rounded-full border border-emerald-300/35 bg-[#07110f]/80 px-3 py-2 shadow-[0_0_24px_rgba(16,185,129,0.24)] backdrop-blur-md">
<span className="relative flex h-7 w-7 items-center justify-center" aria-hidden="true">
<span className="absolute h-7 w-7 rounded-full border border-emerald-300/40 animate-ping" />
<span className="absolute h-5 w-5 rounded-full border border-cyan-300/40 animate-[spin_2.8s_linear_infinite] border-t-transparent" />
<span className="h-2 w-2 rounded-full bg-emerald-200 shadow-[0_0_16px_rgba(110,231,183,0.9)]" />
</span>
<span className="flex flex-col leading-none">
<span className="font-mono text-[8px] uppercase tracking-[0.22em] text-emerald-200">Read</span>
<span className="mt-1 max-w-[10rem] truncate text-[10px] text-slate-300">{statusText}</span>
</span>
</div>
);
}

function BlindMirrorPanel({
blindMirror,
disabled = false,
Expand Down Expand Up @@ -1068,7 +1092,7 @@
const layer = HOUSE_NAME_LAYERS.find(l => l.houseNumber === chamberNumber);
if (!layer) return null;

const module = blueprint?.modules?.find((m: any) => m.id === chamberNumber);

Check failure on line 1095 in vessel/src/app/page.tsx

View workflow job for this annotation

GitHub Actions / Advisory Lint Check

Do not assign to the variable `module`. See: https://nextjs.org/docs/messages/no-assign-module-variable
const operationalEngine = blueprint ? resolveChamberOperationalEngine(blueprint, chamberNumber) : null;
const audit: ChamberAudit | null = blueprint ? getChamberAudit(blueprint, chamberNumber) : null;

Expand Down Expand Up @@ -8614,10 +8638,13 @@
);

// Guided Chat
const renderGuidedView = () => {

Check failure on line 8641 in vessel/src/app/page.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 117 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=DHCross_Shipyard&issues=AZ8RH7AWlDUuF1_pIAdU&open=AZ8RH7AWlDUuF1_pIAdU&pullRequest=886
const showGuidedMobileWheel = isCompactViewport && !sessionActive && !selectedChamber;
const showGuidedMobileCard = isCompactViewport && !sessionActive && selectedChamber;
const showGuidedMobileChat = isCompactViewport && sessionActive;
const guidedReadTabResponding = sessionActive && isLoading;
const guidedReadTabActive = guidedChatFocused || guidedReadTabResponding;
const wheelReadingStatusText = ravenThinkingStatusText || 'Raven is responding.';

const activeTimingConnections = (() => {
const drivers = latestAssistantCorridorSnapshotForDisplay?.transitDrivers?.subjectA?.drivers || [];
Expand Down Expand Up @@ -8756,7 +8783,11 @@
✕ Close
</button>
</div>
<div className="flex-grow flex items-center justify-center">
<div className="relative flex-grow flex items-center justify-center">
<WheelReadingResponseGlyph
isVisible={guidedReadTabResponding}
statusText={wheelReadingStatusText}
/>
<WovenMapWheel
blueprint={displayedWheelBlueprint}
activeChamber={theaterActiveChamber || null}
Expand Down Expand Up @@ -8941,7 +8972,11 @@
✕ Close
</button>
</div>
<div className="flex-grow flex items-center justify-center">
<div className="relative flex-grow flex items-center justify-center">
<WheelReadingResponseGlyph
isVisible={guidedReadTabResponding}
statusText={wheelReadingStatusText}
/>
<WovenMapWheel
blueprint={displayedWheelBlueprint}
activeChamber={selectedChamber?.name || theaterActiveChamber || null}
Expand Down Expand Up @@ -9552,118 +9587,121 @@
) : null}
</div>
</>
) : guidedActiveMapPane ? (
<div
data-guided-active-map-toolbar="true"
className="flex w-full flex-col items-center gap-1 rounded-xl bg-[#050608]/80 backdrop-blur-sm px-3 py-1.5"
>
<div className="flex flex-wrap items-center justify-center gap-1.5">
<button
onClick={() => setGuidedChatFocused(false)}
className="inline-flex items-center gap-1 rounded-lg border border-white/[0.12] bg-white/[0.06] px-2.5 py-1 text-[9px] font-mono uppercase tracking-wider text-slate-200 transition-all duration-300"
>
<Compass className="w-3 h-3" strokeWidth={1.25} />
Map
</button>
<button
onClick={() => {
setGuidedChatFocused(true);
setReadingTabGlow(false);
window.requestAnimationFrame(() => focusGuidedComposer());
}}
className={`inline-flex items-center gap-1 rounded-lg border border-transparent px-2.5 py-1 text-[9px] font-mono uppercase tracking-wider text-slate-500 transition-all duration-300 hover:bg-white/[0.03] hover:text-slate-300 ${readingTabGlow ? 'animate-pulse shadow-[0_0_12px_rgba(52,211,153,0.3)] border-emerald-500/30 text-emerald-300' : ''}`}
>
<MessageSquare className="w-3 h-3" strokeWidth={1.25} />
Reading
</button>
{renderGuidedResonanceHubButton()}
<SessionInstrumentChrome
modeLabel={headerModeLabel}
activeMode={activeMode}
structuredReadingOptIn={structuredReadingOptIn}
structuredReadLocked={structuredReadLocked}
voiceExpression={creatorModeActive ? null : activeVoiceExpression}
semanticDepth={pendingSemanticDepth}
aperture={latestAssistantCorridorSnapshot?.aperture ?? null}
onModeSelect={handleHeaderModeSelect}
onVoiceSelect={handleVoiceExpressionSelect}
className=""
/>
</div>
{inProgressReadingPreview ? (
<button
type="button"
onClick={handleReturnToReading}
data-guided-active-map-reading-chip="true"
className="inline-flex max-w-full items-center gap-1.5 rounded-full border border-emerald-500/20 bg-emerald-500/[0.08] px-2.5 py-1 text-left transition-colors hover:border-emerald-400/35 hover:bg-emerald-500/12"
>
<span className="shrink-0 font-mono text-[8px] uppercase tracking-[0.16em] text-emerald-300">
Reading open
</span>
<span className="truncate text-[10px] text-slate-300">
{inProgressReadingPreview}
</span>
</button>
) : null}
</div>
) : (
<>
<h1 className="text-2xl font-serif text-white tracking-wide font-semibold">
{selectedChamber
? formatChamberHeader(selectedChamber.name).domain
: "Your Woven Map"}
</h1>
<span className="text-[10px] font-mono text-emerald-400 uppercase tracking-[0.22em] mt-0.5">
{selectedChamber
? formatChamberHeader(selectedChamber.name).wovenName
: "The map behind today's reading"}
</span>
{sessionActive && (
<SessionInstrumentChrome
modeLabel={headerModeLabel}
activeMode={activeMode}
structuredReadingOptIn={structuredReadingOptIn}
structuredReadLocked={structuredReadLocked}
voiceExpression={creatorModeActive ? null : activeVoiceExpression}
semanticDepth={pendingSemanticDepth}
aperture={latestAssistantCorridorSnapshot?.aperture ?? null}
onModeSelect={handleHeaderModeSelect}
onVoiceSelect={handleVoiceExpressionSelect}
className="mt-2"
/>
)}
{sessionActive && (
<div className="mt-2 flex flex-wrap items-center justify-center gap-2">
<button
onClick={() => setGuidedChatFocused(false)}
className={`inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-[10px] font-mono uppercase tracking-wider transition-all duration-300 ${
!guidedChatFocused
? 'bg-white/[0.06] border border-white/[0.12] text-slate-200'
: 'border border-transparent text-slate-500 hover:text-slate-300 hover:bg-white/[0.03]'
}`}
>
<Compass className="w-3.5 h-3.5" strokeWidth={1.25} />
Map
</button>
<button
onClick={() => {
setGuidedChatFocused(true);
window.requestAnimationFrame(() => focusGuidedComposer());
}}
className={`inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-[10px] font-mono uppercase tracking-wider transition-all duration-300 ${
guidedChatFocused
? 'bg-white/[0.06] border border-white/[0.12] text-slate-200'
guidedReadTabActive
? cn(
'bg-white/[0.06] border border-white/[0.12] text-slate-200',
guidedReadTabResponding && 'border-emerald-300/45 bg-emerald-500/10 text-emerald-100 shadow-[0_0_22px_rgba(16,185,129,0.22)] animate-pulse',
)
: 'border border-transparent text-slate-500 hover:text-slate-300 hover:bg-white/[0.03]'
}`}
>
<MessageSquare className="w-3.5 h-3.5" strokeWidth={1.25} />
Reading
</button>
{renderGuidedResonanceHubButton()}
</div>
)}
</>
)}

Check warning on line 9704 in vessel/src/app/page.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract this nested ternary operation into an independent statement.

See more on https://sonarcloud.io/project/issues?id=DHCross_Shipyard&issues=AZ8RH7AWlDUuF1_pIAdV&open=AZ8RH7AWlDUuF1_pIAdV&pullRequest=886
</div>
)}

Expand All @@ -9688,114 +9726,122 @@
})()}
{renderGuidedActiveSessionConversation({ includeCorridor: false })}
</div>
) : !sessionActive ? (
<div className={cn("flex min-h-0 w-full flex-1 flex-col", guidedDesktopComposerDock && "pb-56")}>
<OrientationHome
userName={activeProfile?.name}
showLoggedInGlimpse={Boolean(activeProfile?.name)}
pressureChamberName={theaterActiveChamber || selectedChamber?.name || 'The Path'}
scopePresentation={orientationScopePresentation}
onReadPrimary={handleStartPrimaryOrientationRead}
onReadSecondary={orientationScopePresentation.secondaryAction ? handleStartSecondaryOrientationRead : undefined}
onShowMap={scrollToGuidedMap}
onViewBlueprint={() => handleStartGuidedReading("Read my whole Blueprint.")}
onExploreRelationship={() => {
setFreeformChatActivated(true);
setGuidedChatFocused(true);
handleGuidedEntry(
GUIDED_ENTRY_LABELS.MAP_US,
'Read my relationship patterns and encounter dynamics.',
);
}}
scrollContainerRef={guidedMapSectionRef}
mapSection={(
<div className="w-full flex flex-col items-center gap-3">
<WovenMapWheelGateBanner
profile={activeProfile}
frameResolved={primaryWheelFrameResolved}
/>
{displayedWheelBlueprint && primaryWheelFrameResolved && (
<FrameStatusBlock frame={displayedWheelBlueprint.frame ?? null} />
)}
<div className="chart-scroll-pass-through relative flex min-h-[390px] w-full items-center justify-center py-1">
<WheelReadingResponseGlyph
isVisible={guidedReadTabResponding}
statusText={wheelReadingStatusText}
/>
{shouldShowSunStartPanel && sunWheelPlacement && (
<SunWheelStartPanel
placement={sunWheelPlacement}
onDismiss={dismissSunStartPanel}
/>
)}
{primaryWheelFrameResolved ? (
<WovenMapWheel
blueprint={displayedWheelBlueprint}
activeChamber={selectedChamber?.name || theaterActiveChamber || null}
onChamberClick={(chamber) => {
setSelectedChamber(chamber);
setShowFullCardInActiveSession(false);
}}
onCenterClick={() => {
setSelectedChamber(null);
setShowFullCardInActiveSession(false);
}}
size={420}
activePlanets={activePlanetsList}
corridorSnapshot={activeSnapshot}
isStreaming={isLoading}
sunOnboardingMode={sunStartModeActive}
sunPlacement={sunWheelPlacement}
/>
) : (
<div className="flex min-h-[320px] w-full max-w-md items-center justify-center rounded-3xl border border-amber-500/20 bg-amber-500/[0.04] px-6 py-8 text-center">
<p className="text-sm leading-7 text-slate-300">
The chamber wheel stays closed until birth time is determined or you accept a guided provisional frame.
</p>
</div>
)}
</div>
</div>
)}
/>
</div>
) : guidedActiveMapPane ? (
<div
ref={guidedMapSectionRef}
data-guided-active-map-pane="true"
data-testid="guided-map-scroll"
className="guided-map-active flex min-h-0 w-full max-w-[46rem] flex-1 flex-col overflow-hidden"
>
<div className="chart-scroll-pass-through relative flex min-h-0 w-full flex-1 items-center justify-center px-2">
<WheelReadingResponseGlyph
isVisible={guidedReadTabResponding}
statusText={wheelReadingStatusText}
/>
{soloScopedProfile && soloScopedProfile.id !== activeProfile?.id && (
<div className="absolute top-2 left-1/2 z-10 -translate-x-1/2 text-[10px] font-mono uppercase tracking-widest text-amber-400/80">
{soloScopedProfile.name} · Solo Mirror
</div>
)}
<WovenMapWheel
blueprint={displayedWheelBlueprint}
activeChamber={selectedChamber?.name || theaterActiveChamber || null}
onChamberClick={(chamber) => {
setSelectedChamber(chamber);
setShowFullCardInActiveSession(false);
}}
onCenterClick={() => {
setSelectedChamber(null);
setShowFullCardInActiveSession(false);
}}
size={480}
activePlanets={activePlanetsList}
corridorSnapshot={activeSnapshot}
isStreaming={isLoading}
sunOnboardingMode={false}
sunPlacement={sunWheelPlacement}
/>
</div>
<div className="shrink-0 px-2 pb-2">
<CelestialTheatreStrip
corridorSnapshot={celestialSnapshotForTheater}
activeChamber={theaterActiveChamber}
quietMode={isQuietMode}
/>
</div>
</div>
) : null}

Check warning on line 9844 in vessel/src/app/page.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract this nested ternary operation into an independent statement.

See more on https://sonarcloud.io/project/issues?id=DHCross_Shipyard&issues=AZ8RH7AWlDUuF1_pIAdW&open=AZ8RH7AWlDUuF1_pIAdW&pullRequest=886

Check warning on line 9844 in vessel/src/app/page.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract this nested ternary operation into an independent statement.

See more on https://sonarcloud.io/project/issues?id=DHCross_Shipyard&issues=AZ8RH7AWlDUuF1_pIAdX&open=AZ8RH7AWlDUuF1_pIAdX&pullRequest=886
</div>

{/* 3. Right Column: Ask Raven / Raven Card (Column 3) — or Reading Summary Card if chat is focused */}
Expand Down
6 changes: 6 additions & 0 deletions vessel/src/lib/raven/__tests__/symbolicMomentIntent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,10 @@ test('detects timing-window planner scan phrases', () => {
'What is the high-valence date coming up?',
'When is the next positive bias window?',
'When does the next high valence window open?',
'tell me about...tonight.',
'how is this evening looking?',
'what is active this morning?',
'read this afternoon',
];
for (const msg of timingWindowQuestions) {
assert.equal(
Expand All @@ -444,6 +448,8 @@ test('does not flag ordinary timing follow-ups as timing-window planner scans',
'Will it get lighter tomorrow?',
'When will this pressure ease?',
'How soon does this settle?',
'I am exhausted tonight.',
'Maybe I should stop pushing tonight?',
];
for (const msg of nonTimingWindow) {
assert.equal(
Expand Down
5 changes: 4 additions & 1 deletion vessel/src/lib/raven/symbolicMomentIntent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@
/\bhigh[\s-]?valence\s+date\b/i,
/\bwhen\s+is\s+my\s+next\s+(?:high[\s-]?valence|positive\s+bias)\b/i,
/\bwhen\s+(?:is|does)\s+(?:the\s+)?(?:next|best)\s+(?:high[\s-]?valence|positive\s+bias|expansion)\b/i,
/\b(?:tell\s+me\s+about|read|show|check|pull|fetch|run)\b[\s.?!,;:…-]{0,20}\b(?:tonight|(?:this\s+)?(?:evening|morning|afternoon))\b/i,

Check warning on line 101 in vessel/src/lib/raven/symbolicMomentIntent.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Simplify this regular expression to reduce its complexity from 21 to the 20 allowed.

See more on https://sonarcloud.io/project/issues?id=DHCross_Shipyard&issues=AZ8RH69DlDUuF1_pIAdN&open=AZ8RH69DlDUuF1_pIAdN&pullRequest=886

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Anchor day-part read verbs to explicit requests

Because this new timing-window regex is not anchored to the start of the utterance or another request context, any sentence containing verbs like read, run, or check near tonight is classified as NEW_SYMBOLIC_READ before follow-up handling runs. For example, classifySymbolicMomentTurn('I need to check tonight before deciding') now triggers a fresh symbolic read, so ordinary testimony/decision chat can be promoted into the exact new-read path this change is trying to avoid.

Useful? React with 👍 / 👎.

/\b(?:what(?:s| is)|how(?:s| is))\b[\s.?!,;:…-]{0,80}\b(?:active|looking|running|happening|pressing|live|the\s+(?:field|sky|pressure|moment))\b[\s.?!,;:…-]{0,40}\b(?:tonight|(?:this\s+)?(?:evening|morning|afternoon))\b/i,

Check warning on line 102 in vessel/src/lib/raven/symbolicMomentIntent.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Simplify this regular expression to reduce its complexity from 30 to the 20 allowed.

See more on https://sonarcloud.io/project/issues?id=DHCross_Shipyard&issues=AZ8RH69DlDUuF1_pIAdO&open=AZ8RH69DlDUuF1_pIAdO&pullRequest=886
/\bhow(?:s| is)\b[\s.?!,;:…-]{0,20}\b(?:tonight|(?:this\s+)?(?:evening|morning|afternoon))\b[\s.?!,;:…-]{0,40}\b(?:looking|running|happening|landing|feeling)\b/i,
] as const;

const NEW_SYMBOLIC_READ_PATTERNS = [
Expand Down Expand Up @@ -415,7 +418,7 @@
return hasWindowOpener && hasWindowMarker && hasWindowTarget;
}

export function isSymbolicMomentsIntent(

Check failure on line 421 in vessel/src/lib/raven/symbolicMomentIntent.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 29 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=DHCross_Shipyard&issues=AZ8RH69DlDUuF1_pIAdP&open=AZ8RH69DlDUuF1_pIAdP&pullRequest=886
userMessage: string,
hasWindowCue: boolean,
context?: {
Expand Down Expand Up @@ -445,7 +448,7 @@
if (/\b(?:how\s+is)\s+(?:the\s+)?(?:sky|field|symbolic\s+moment|pressure)\b/i.test(normalized)) return true;
if (/\b(?:what(?:s|'s| is))\s+(?:going\s+on|doing\s+on|happening)\s+(?:in\s+(?:the\s+)?(?:sky|field|chart|transits)|right\s+now|today|this\s+week|astrologically)\b/i.test(normalized)) return true;
if (/\b(?:what(?:s|'s| is))\s+(?:doing|going)\s+on\s+right\s+now\b/i.test(normalized)) return true;
if (/\b(?:ask\s+about|tell\s+me\s+about)\s+(?:today|this\s+week|right\s+now|the\s+current\s+(?:sky|moment|field|pressure|symbolic\s+moment))\b/i.test(normalized)) return true;
if (/\b(?:ask\s+about|tell\s+me\s+about)\s+(?:today|tonight|this\s+(?:morning|afternoon|evening|week)|right\s+now|the\s+current\s+(?:sky|moment|field|pressure|symbolic\s+moment))\b/i.test(normalized)) return true;

Check warning on line 451 in vessel/src/lib/raven/symbolicMomentIntent.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Simplify this regular expression to reduce its complexity from 32 to the 20 allowed.

See more on https://sonarcloud.io/project/issues?id=DHCross_Shipyard&issues=AZ8RH69DlDUuF1_pIAdQ&open=AZ8RH69DlDUuF1_pIAdQ&pullRequest=886

if (/\b(?:what(?:'s|s|\s+is)\s+(?:just\s+)?loud|just\s+what\s+(?:is|it)\s+loud|read\s+(?:what(?:'s|s|\s+is)\s+)?loud)\b/i.test(normalized)) return true;

Expand Down
Loading