Skip to content

feat(ui): GOAP plan implementation - tokens, overlay, responsive, chat polish#329

Merged
d-oit merged 5 commits into
mainfrom
feat/goap-plan-implementation-2026-06-19
Jun 19, 2026
Merged

feat(ui): GOAP plan implementation - tokens, overlay, responsive, chat polish#329
d-oit merged 5 commits into
mainfrom
feat/goap-plan-implementation-2026-06-19

Conversation

@d-oit

@d-oit d-oit commented Jun 19, 2026

Copy link
Copy Markdown
Owner

Summary

Implements tasks from GOAP plans 34-37 and 041:

PR #328 Fixes

  • Reduce cyclomatic complexity of by extracting helper
  • Fix operator usage → proper async handling
  • Remove inline styles from loading indicator

Plan 37: Security & Quality Hardening

  • ✅ API key encryption at rest (already implemented)
  • ✅ SSRF protection in URL resolution (already implemented)
  • ✅ Browser migrations bundled via import.meta.glob (already implemented)
  • ✅ Snapshot data validated with Zod (already implemented)
  • ✅ maskApiKey simplified (already implemented)

Plan 041 Wave 1: Foundation

  • Add missing CSS token aliases (--border-color, --surface-primary/secondary)
  • Add semantic token families: status, entity, graph, control-height, z-index, focus-ring
  • Add @media (prefers-reduced-motion: reduce) policy
  • Create <Overlay> primitive with focus trap, Escape, scroll lock
  • Create useScrollLock hook

Plan 041 Wave 2: Responsive + Modernize

  • Fix 100vh100dvh with fallback for mobile viewport
  • Add safe-area insets for notched devices
  • Add viewport-fit=cover for iOS
  • Fix touch targets (44px) for coarse pointers on filter-chips, close-buttons, layout-toggles
  • Fix graph/mindmap canvas height with clamp() instead of inline 600px

Plans 34-36 (Already Completed)

  • Repository split ✅
  • Search split ✅
  • GraphView split ✅
  • AIHarness split ✅

Quality Gates

  • pnpm run lint — 0 errors
  • pnpm run typecheck — clean
  • pnpm run build — successful
  • pnpm run test — 392 passed (1 pre-existing flaky benchmark test)

…at polish

- Fix PR #328 DeepSource issues: reduce cyclomatic complexity, fix void operator usage
- Add missing CSS token aliases (--border-color, --surface-primary/secondary)
- Add semantic token families (status, entity, graph, control-height, z-index, focus-ring)
- Add prefers-reduced-motion policy
- Create Overlay primitive with focus trap, Escape, scroll lock
- Create useScrollLock hook
- Fix 100vh → 100dvh with fallback for mobile viewport
- Add safe-area insets for notched devices
- Add viewport-fit=cover for iOS
- Fix touch targets (44px) for coarse pointers
- Fix graph/mindmap canvas height with clamp()
- Update plans/INDEX.md with new plan and ADR entries
@github-actions github-actions Bot added documentation Documentation improvements config labels Jun 19, 2026
@deepsource-io

deepsource-io Bot commented Jun 19, 2026

Copy link
Copy Markdown

DeepSource Code Review

We reviewed changes in 5172ee8...bd8fafc on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSource ↗

PR Report Card

Overall Grade   Security  

Reliability  

Complexity  

Hygiene  

Code Review Summary

Analyzer Status Updated (UTC) Details
JavaScript Jun 19, 2026 9:11a.m. Review ↗
Python Jun 19, 2026 9:11a.m. Review ↗
Shell Jun 19, 2026 9:11a.m. Review ↗
SQL Jun 19, 2026 9:11a.m. Review ↗

Important

AI Review is run only on demand for your team. We're only showing results of static analysis review right now. To trigger AI Review, comment @deepsourcebot review on this thread.

Comment thread src/components/Overlay.tsx Outdated
useEffect(() => {
if (!isOpen) return;
document.addEventListener('keydown', handleKeyDown);
return () => document.removeEventListener('keydown', handleKeyDown);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Arrow function expected no return value


Any code paths that do not have explicit returns will return undefined. It is recommended to replace any implicit dead-ends that return undefined with a return null statement.

Comment thread src/features/chat/Chat.tsx Outdated
Comment on lines +18 to +23
function buildResponse(input: string, results: RankedResult[]): string {
if (results.length > 0) {
return `Based on your local records, here's what I found about "${input}". I've cited the most relevant items below.`;
}
return `I couldn't find any direct matches in your local library for "${input}". You might want to try different keywords or add more context to your entities.`;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Unexpected function declaration in the global scope, wrap in an IIFE for a local variable, assign as global property for a global variable


It is considered a best practice to avoid 'polluting' the global scope with variables that are intended to be local to the script. Global variables created from a script can produce name collisions with global variables created from another script, which will usually lead to runtime errors or unexpected behavior. It is mostly useful for browser scripts.

Comment thread src/features/chat/Chat.tsx Outdated
<div className="suggested-actions">
<button onClick={() => setInput('Summarize my recent projects')}>Summarize recent projects</button>
<button onClick={() => setInput('Who are the key people?')}>Key people</button>
<button onClick={() => { void handleSend(undefined, 'Summarize my recent projects'); }}>Summarize recent projects</button>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Expected 'undefined' and instead saw 'void'


The void operator takes an operand and returns undefined. It can be used to ignore the value produced by an expression. However, this can lead to code that is difficult to understand and maintain. Historically, the void operator was used to get a "pure" undefined value, as the undefined variable was mutable prior to ES5.

Comment thread src/features/chat/Chat.tsx Outdated
<button onClick={() => setInput('Summarize my recent projects')}>Summarize recent projects</button>
<button onClick={() => setInput('Who are the key people?')}>Key people</button>
<button onClick={() => { void handleSend(undefined, 'Summarize my recent projects'); }}>Summarize recent projects</button>
<button onClick={() => { void handleSend(undefined, 'Who are the key people?'); }}>Key people</button>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Expected 'undefined' and instead saw 'void'


The void operator takes an operand and returns undefined. It can be used to ignore the value produced by an expression. However, this can lead to code that is difficult to understand and maintain. Historically, the void operator was used to get a "pure" undefined value, as the undefined variable was mutable prior to ES5.

Comment thread src/features/chat/Chat.tsx Outdated

<form className="ask-composer" onSubmit={e => void handleSend(e)}>
<div className="input-container">
<form className="chat-controls" onSubmit={e => { void handleSend(e); }}>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Expected 'undefined' and instead saw 'void'


The void operator takes an operand and returns undefined. It can be used to ignore the value produced by an expression. However, this can lead to code that is difficult to understand and maintain. Historically, the void operator was used to get a "pure" undefined value, as the undefined variable was mutable prior to ES5.

Comment thread src/hooks/useScrollLock.ts Outdated
Comment on lines +7 to +31
export function useScrollLock(active: boolean): void {
useEffect(() => {
if (!active) return;

const scrollY = window.scrollY;
const body = document.body;
const originalOverflow = body.style.overflow;
const originalPosition = body.style.position;
const originalTop = body.style.top;
const originalWidth = body.style.width;

body.style.overflow = 'hidden';
body.style.position = 'fixed';
body.style.top = `-${scrollY}px`;
body.style.width = '100%';

return () => {
body.style.overflow = originalOverflow;
body.style.position = originalPosition;
body.style.top = originalTop;
body.style.width = originalWidth;
window.scrollTo(0, scrollY);
};
}, [active]);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Unexpected function declaration in the global scope, wrap in an IIFE for a local variable, assign as global property for a global variable


It is considered a best practice to avoid 'polluting' the global scope with variables that are intended to be local to the script. Global variables created from a script can produce name collisions with global variables created from another script, which will usually lead to runtime errors or unexpected behavior. It is mostly useful for browser scripts.

Comment on lines +23 to +29
return () => {
body.style.overflow = originalOverflow;
body.style.position = originalPosition;
body.style.top = originalTop;
body.style.width = originalWidth;
window.scrollTo(0, scrollY);
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Arrow function expected no return value


Any code paths that do not have explicit returns will return undefined. It is recommended to replace any implicit dead-ends that return undefined with a return null statement.

@codacy-production

codacy-production Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 12 complexity · 2 duplication

Metric Results
Complexity 12
Duplication 2

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

useEffect(() => {
if (!isOpen) return;
document.addEventListener('keydown', handleKeyDown);
return () => { document.removeEventListener('keydown', handleKeyDown); };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Arrow function expected no return value


Any code paths that do not have explicit returns will return undefined. It is recommended to replace any implicit dead-ends that return undefined with a return null statement.


const handleSend = async (e?: React.FormEvent) => {
/* biome-ignore lint/correctness/useQwikValidLexicalScope: false positive - standard React async function */
const handleSend = async (e?: React.FormEvent, query?: string) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

`handleSend` has a cyclomatic complexity of 6 with "medium" risk


A function with high cyclomatic complexity can be hard to understand and
maintain. Cyclomatic complexity is a software metric that measures the number of
independent paths through a function. A higher cyclomatic complexity indicates
that the function has more decision points and is more complex.

@d-oit d-oit enabled auto-merge (squash) June 19, 2026 08:56
@github-actions github-actions Bot added the tests Related to automated/manual tests label Jun 19, 2026
@d-oit d-oit merged commit 5608449 into main Jun 19, 2026
23 of 24 checks passed
@d-oit d-oit deleted the feat/goap-plan-implementation-2026-06-19 branch June 19, 2026 09:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

config documentation Documentation improvements tests Related to automated/manual tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants