-
Notifications
You must be signed in to change notification settings - Fork 106
Add Silicon Signal cookbook project #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add Silicon Signal cookbook project #29
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the
📝 WalkthroughWalkthroughAdds a new silicon-signal Next.js application and related infrastructure: frontend app with landing, dashboard, and UI components; a POST /api/scan server route implementing multi-source browser- and fetch-based part scanning, signal extraction, merging, and risk scoring; types and a lightweight history store with sample history data; build/config files (tsconfig, next.config, ESLint, PostCSS, package.json); global styles and assets. Exports include the scan POST handler, several React components, types, and history-store functions. Sequence Diagram(s)sequenceDiagram
participant Client
participant API as /api/scan
participant Cache
participant History as History Store
participant Browser as Headless Browser
participant Dist1 as DigiKey
participant Dist2 as Mouser
participant Dist3 as Other Vendors
participant Risk as Risk Analyzer
Client->>API: POST /api/scan (part_number, manufacturer)
API->>API: Validate input
API->>Cache: Check cache for part
alt Cache Hit
Cache-->>API: Cached result
API-->>Client: Return cached result
else Cache Miss
API->>History: Load historical snapshots
History-->>API: Return history
API->>Browser: Launch headless browser (fallback: fetch)
Browser->>Dist1: Navigate & fetch page
Dist1-->>Browser: Page content / JSON-LD
Browser->>Browser: Parse DOM & JSON-LD -> extract signals
Browser->>Dist2: Navigate & fetch page
Dist2-->>Browser: Page content / JSON-LD
Browser->>Browser: Parse DOM & JSON-LD -> extract signals
Browser->>Dist3: Navigate & fetch page
Dist3-->>Browser: Page content / JSON-LD
Browser->>Browser: Parse DOM & JSON-LD -> extract signals
Browser-->>API: Source signals & agent logs
API->>API: Merge signals across sources
API->>Risk: Compute consolidated risk & confidence
Risk->>History: Compare with historical trends
History-->>Risk: Historical context
Risk-->>API: Risk analysis
API->>History: Save new snapshot
History-->>API: Snapshot stored
API->>Cache: Store result with TTL
Cache-->>API: Cached
API-->>Client: Return ScanResult (signals, risk, evidence, timing)
end
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 10
🤖 Fix all issues with AI agents
In `@README.md`:
- Line 41: Fix the typo in the README table row for the project labeled
"[summer-school-finder]": replace the incorrect text "sch`ool" in the
description string "Discover and compare summer sch`ool programs from
universities around the world" with the correct "school" so the description
reads "Discover and compare summer school programs from universities around the
world".
In `@silicon-signal/README.md`:
- Line 3: Replace the bare URL on the README's "Live link:" line with a Markdown
link so it uses proper link syntax; for example, change the text that currently
reads "Live link: https://silicon-signal.vercel.app/" to use bracketed link text
and parentheses (e.g., "Live link: [Silicon
Signal](https://silicon-signal.vercel.app/)") so markdownlint MD034 is
satisfied.
- Around line 26-28: The fenced code block containing the environment variable
example (the block with "MINO_API_KEY=your_tinyfish_key") lacks a language tag
and triggers MD040; add the language identifier "dotenv" to the opening fence
(i.e., change the triple-backtick that precedes the MINO_API_KEY line to include
"dotenv") so the snippet is fenced as a dotenv code block.
In `@silicon-signal/src/app/api/scan/route.ts`:
- Around line 551-553: The regex used to validate part_number currently allows a
backslash due to the sequence "\\", which is unintended; update the validation
to disallow backslashes by removing the backslash from the character class and
ensure the hyphen is placed at the end (e.g., use a character class like
[A-Za-z0-9._/+ -] with the hyphen last) in the check that tests part_number so
invalid backslashes are rejected while preserving the intended allowed
characters.
- Around line 6-62: Remove the duplicated interface declarations (RiskAnalysis,
ScanResult, SourceSignal, SignalSummary, ConfidenceInfo) from route.ts and
replace them with a single import of those types from the shared types module;
specifically, delete the interface blocks shown in the diff and add an import
type statement that brings in RiskAnalysis, ScanResult, SourceSignal,
SignalSummary and ConfidenceInfo from the shared types module so the file uses
the canonical definitions instead of duplicating them.
In `@silicon-signal/src/components/Header.tsx`:
- Around line 3-11: The Header component uses client-only APIs (the onClick
handler that sets window.location.href) so either mark the component as a client
component by adding the directive 'use client' at the top of the Header file
(Header component) or make it server-safe by replacing the clickable div (the
element with onClick and the window.location.href usage) with a native anchor
element (<a href="/">) that preserves the same children and styles and removes
the onClick/window reference; update any related imports/props if needed.
In `@silicon-signal/src/components/ScanForm.tsx`:
- Around line 3-25: The handleSubmit function in ScanForm uses the identifier
React.FormEvent but React is not imported (with "jsx":"react-jsx" there is no
default React binding); fix by importing the event type from React and updating
the signature: add an import like "import type { FormEvent } from 'react'" (or
import React as needed) and change handleSubmit's parameter to use FormEvent (or
the imported type) so the TypeScript reference to React.FormEvent is resolved;
ensure this import sits with the other React imports at the top of ScanForm.tsx.
In `@silicon-signal/src/components/SignalOverview.tsx`:
- Around line 13-18: In the SignalOverview component JSX there is an invalid
nesting: a <div> placed inside the inline <span> that renders the live status;
replace that inner <div> with a <span> (preserving the clsx class string "w-1.5
h-1.5 rounded-full" and conditional classes "bg-accent"/"bg-border") so the
status indicator is valid inline HTML; update the JSX where the outer span uses
clsx(...) and the nested element created for the dot indicator to be a span
instead of div.
In `@silicon-signal/src/components/SiliconWafer.tsx`:
- Around line 1-2: This file is missing the Next.js client boundary directive
required for framer-motion; add the literal string 'use client' as the very
first line in SiliconWafer.tsx (before any imports) so the component and its use
of motion from 'framer-motion' run as a client component; ensure the directive
appears above the import of motion and any other imports in the file.
In `@silicon-signal/src/lib/store.ts`:
- Around line 27-79: saveSnapshot performs a read-modify-write (via attemptSave
and currentHistoryFile) without any locking, which can cause lost updates under
concurrent writes; fix by making writes atomic: when writing inside attemptSave,
write the JSON to a temporary file (e.g., same dir + unique suffix) and then
atomically rename/replace the target file (fs.renameSync) to avoid
partial/overwritten data, and optionally add a short retry/backoff or simple
lock-file mechanism around attemptSave to reduce race windows; if you choose not
to implement concurrency control, add a clear comment/docstring on saveSnapshot
explaining the race condition limitation and recommending atomic rename or
external locking for production.
🧹 Nitpick comments (10)
silicon-signal/src/components/HistoricalTrend.tsx (1)
6-12: Clamp history scores before plotting to avoid out-of-range rendering.If a score is outside 0–100, the path can render off-canvas. Clamping keeps the chart stable without changing data semantics elsewhere.
♻️ Suggested change
- const points = history.length > 1 ? history.map((h, i) => { - const x = (i / (history.length - 1)) * 240 + 20; - const y = 90 - (h.score / 100) * 80; - return { x, y }; - }) : []; + const clampScore = (score: number) => Math.min(100, Math.max(0, score)); + const points = history.length > 1 ? history.map((h, i) => { + const x = (i / (history.length - 1)) * 240 + 20; + const y = 90 - (clampScore(h.score) / 100) * 80; + return { x, y }; + }) : [];silicon-signal/src/components/ScanResultCard.tsx (2)
4-4: Unused import:CalendarThe
Calendaricon is imported but never used in the component.🧹 Remove unused import
-import { ExternalLink, AlertTriangle, Calendar, CheckCircle, Activity, DollarSign, Globe } from 'lucide-react'; +import { ExternalLink, AlertTriangle, CheckCircle, Activity, DollarSign, Globe } from 'lucide-react';
23-23: Set explicit value foraria-hiddenThe
aria-hiddenattribute should have an explicit boolean or string value for clarity.🧹 Suggested fix
- <div className="absolute -top-20 -right-20 w-64 h-64 bg-cyan-500/10 rounded-full blur-3xl group-hover:bg-cyan-500/20 transition-all duration-1000" aria-hidden /> + <div className="absolute -top-20 -right-20 w-64 h-64 bg-cyan-500/10 rounded-full blur-3xl group-hover:bg-cyan-500/20 transition-all duration-1000" aria-hidden="true" />silicon-signal/src/components/PlatformView.tsx (1)
34-37: Consider checking response status before parsing JSONThe current flow parses JSON before checking
res.ok. If the server returns a non-JSON error (e.g., 502 Bad Gateway with HTML),res.json()will throw, and the error message will be a parse error rather than the actual HTTP error.🛡️ Suggested improvement for robustness
- const data = await res.json(); - if (!res.ok) { - throw new Error(data?.error || 'Scan failed'); - } - setResult(data); + if (!res.ok) { + const data = await res.json().catch(() => ({})); + throw new Error(data?.error || `Scan failed (${res.status})`); + } + const data = await res.json(); + setResult(data);silicon-signal/src/lib/store.ts (1)
81-94: Fallback behavior may skip valid data in other files
getHistorystops at the first successfully parsed file, even if that file doesn't contain the requestedpartNumber. If the part's history exists only in a later file (e.g.,data/history.json), it won't be found.This is likely acceptable for the demo's use case but worth noting.
silicon-signal/src/types.ts (1)
1-5: Consider using a union type forlevelUsing a union type for
levelwould provide better type safety and autocompletion:🧹 Suggested improvement
+export type RiskLevel = 'LOW' | 'MEDIUM' | 'HIGH'; + export interface RiskAnalysis { score: number; - level: string; + level: RiskLevel; reasoning: string; }silicon-signal/src/app/api/scan/route.ts (4)
616-627: Multiple@ts-ignorecomments for Chromium typesThe type mismatches between
puppeteer-coreand@sparticuz/chromiumare common. Consider using type assertions withas unknown as Xfor slightly safer typing, or adding a brief comment explaining why these ignores are necessary.
786-799: Browser cleanup could use finally blockThe browser cleanup is split between the happy path (line 786) and error handling (lines 792-798). Using a
finallyblock would ensure cleanup happens regardless of which path is taken.🧹 Consider wrapping browser operations in try-finally
let browser: Browser | undefined; try { browser = await launchBrowser(); // ... browser operations } finally { if (browser) { try { await browser.close(); } catch { // ignore close errors } } }
1076-1089: Cache eviction removes oldest by insertion, not by TTLThe eviction logic removes entries in insertion order, not by expiration time. This means a recently used entry that was inserted early could be evicted before an expired entry inserted later. For a demo this is fine, but worth noting if caching is enabled in production.
534-1111: POST handler is quite long (~580 lines)The handler orchestrates many concerns: validation, browser management, data fetching, signal parsing, risk calculation, caching, and history. For a cookbook demo this is acceptable, but consider extracting logical sections into helper functions for maintainability:
launchBrowser()- browser initialization logicfetchSignalsWithBrowser()- browser-based data collectioncomputeRiskAnalysis()- risk scoring logicbuildScanResult()- result assembly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@silicon-signal/src/components/SignalOverview.tsx`:
- Around line 5-9: The "Data Confidence" metric in the metrics array is
hardcoded to 95; update the Data Confidence value to use the actual scan result
confidence (use result.confidence?.score or result?.confidence?.score ??
<fallback>) instead of 95, e.g. replace the numeric literal in the Data
Confidence entry inside the metrics constant so it reads the ScanResult
confidence score and preserves existing status/color logic.
🧹 Nitpick comments (2)
silicon-signal/src/app/api/scan/route.ts (2)
554-571: Consider adding type declarations or explicit typing for chromium integration.Multiple
@ts-ignorecomments suppress TypeScript errors for the@sparticuz/chromiumintegration. While this is a common workaround, it reduces type safety. Consider:
- Adding a local type declaration file for the chromium module
- Using explicit type assertions with comments explaining the expected types
- Checking if newer versions of
@sparticuz/chromiumhave improved type definitions♻️ Example type declaration approach
Create
silicon-signal/src/types/chromium.d.ts:declare module '@sparticuz/chromium' { const chromium: { executablePath(): Promise<string>; args: string[]; defaultViewport: { width: number; height: number }; headless: boolean | 'new'; }; export default chromium; }
621-665: Consider logging suppressed errors to agent logs for observability.Multiple empty catch blocks silently swallow errors during DOM extraction and page navigation. While graceful degradation is appropriate here, logging these failures to
agentLogswould aid debugging without affecting control flow.♻️ Example improvement for one catch block
} catch { - // optional + agentLogs.push(`${logPrefix} DOM extraction from search page skipped.`); }
TinyFish - SiliconSignal
SiliconSignal is a high-precision monitoring platform designed to detect logistics risks, lead-time shifts, and lifecycle transitions in real-time. By leveraging the Tinyfish web agent (Mino), it extracts live signals directly from foundry bulletins and primary distributor channels.
Deployment:- https://silicon-signal.vercel.app