Repository Analysis

Nagi-ovo/gemini-voyager

An all-in-one enhancement suite for Google Gemini & AI Studio - timeline navigation, folder management, prompt library, and chat export in one powerful extension. / Google Gemini & AI Studio 全能增强插件:集成时间轴导航、文件夹管理、提示词库及聊天导出等众多功能。

2.3 Likely human-written View on GitHub
2.3
Adjusted Score
2.3
Raw Score
100%
Time Factor
2026-05-30
Last Push
18,438
Stars
TypeScript
Language
168,097
Lines of Code
881
Files
308
Pattern Hits
2026-05-31
Scan Date

Score History

Severity Breakdown

CRITICAL 0HIGH 3MEDIUM 24LOW 281

Pattern Findings

308 matches across 7 categories. Click a row to expand file-level details.

Hyper-Verbose Identifiers247 hits · 254 pts
SeverityFileLineSnippet
LOWpublic/response-complete-observer.js34 function isGeminiGenerationRequest(url, bodyText) {
LOWsrc/core/utils/conversationIdentity.ts33export function extractConversationIdFromUrl(input: string): string | null {
LOWsrc/core/utils/conversationIdentity.ts64export function buildRouteConversationIdFromUrl(input: string): string {
LOWsrc/core/utils/conversationIdentity.ts73export function buildConversationIdFromUrl(input: string): string {
LOWsrc/core/utils/conversationIdentity.ts82export function buildLegacyConversationIdFromUrl(input: string): string {
LOWsrc/core/utils/updateReminder.ts12export function shouldShowUpdateReminderForCurrentVersion({
LOWsrc/core/utils/browser.ts39export function shouldShowSafariUpdateReminder(): boolean {
LOWsrc/core/utils/browser.ts100export function supportsOptionalHostPermissions(): boolean {
LOWsrc/core/utils/browser.ts112export function supportsExtensionNotifications(): boolean {
LOWsrc/core/utils/selectors.ts31export function getAssistantTurnSelectors(): string[] {
LOWsrc/core/utils/selectors.ts60export function getConversationLinkSelectors(): string[] {
LOWsrc/core/utils/gemini.ts29export function hasGeminiEnterpriseDomHints(doc: Document): boolean {
LOWsrc/core/utils/gemini.ts46export function isGeminiEnterpriseEnvironment(parts: UrlParts, doc?: Document): boolean {
LOWsrc/core/utils/extensionContext.ts13export function isExtensionContextInvalidatedError(error: unknown): boolean {
LOWsrc/core/services/AccountIsolationService.ts63export function detectAccountPlatformFromUrl(pageUrl: string | null | undefined): AccountPlatform {
LOWsrc/core/services/AccountIsolationService.ts69export function getAccountIsolationStorageKey(platform: AccountPlatform): string {
LOWsrc/core/services/AccountIsolationService.ts141export function extractRouteUserIdFromPath(pathname: string): string | null {
LOWsrc/core/services/AccountIsolationService.ts146export function extractRouteUserIdFromUrl(url: string): string | null {
LOWsrc/core/services/AccountIsolationService.ts205export function detectAccountContextFromDocument(pageUrl: string, doc: Document): AccountContext {
LOWsrc/core/services/AccountIsolationService.ts251export function buildScopedFolderStorageKey(accountKey: string): string {
LOWsrc/core/services/SettingsBackupService.ts120export function filterBackupableSyncSettings(value: unknown): BackupableSyncSettings {
LOWsrc/core/services/SettingsBackupService.ts134export async function loadBackupableSyncSettings(
LOWsrc/core/services/SettingsBackupService.ts142export async function exportBackupableSyncSettings(
LOWsrc/core/services/SettingsBackupService.ts153export async function restoreBackupableSyncSettings(
LOW…ore/services/__tests__/KeyboardShortcutService.test.ts11function createCustomSingleLetterConfig(): KeyboardShortcutConfig {
LOWsrc/features/plugins/manifest/validate.ts89function normalizeLocalizedSetting(raw: unknown): LocalizedSettingField | undefined {
LOWsrc/features/plugins/manifest/validate.ts102function normalizeLocalizedSettings(
LOWsrc/features/plugins/runtime/siteRegistration.ts59export async function registerContentScriptsForOrigins(
LOWsrc/features/export/ui/ExportToast.ts11function getOrCreateToast(): HTMLDivElement {
LOWsrc/features/export/ui/ExportErrorMessage.ts3export function resolveExportErrorMessage(
LOWsrc/features/export/types/errors.ts3export function isEventLikeImageRenderError(error: unknown): boolean {
LOWsrc/features/export/types/export.ts56export function normalizeImageExportWidth(value: unknown): ImageExportWidth {
LOWsrc/features/export/services/ImageRenderService.ts35export function isImageResourceRenderError(error: unknown): boolean {
LOWsrc/features/export/services/ImageRenderService.ts98async function renderUsingSanitizedClone(target: HTMLElement, selector: string): Promise<Blob> {
LOWsrc/pages/background/index.ts81function normalizeNotificationText(value: unknown, maxLength: number): string {
LOWsrc/pages/background/index.ts88async function showResponseCompleteNotification(
LOWsrc/pages/background/index.ts181async function resolveAccountScopeForMessage(
LOWsrc/pages/background/index.ts205function filterStarredByRouteScope(
LOWsrc/pages/background/index.ts224function filterForkNodesByRouteScope(
LOWsrc/pages/background/index.ts298async function unregisterResponseCompleteObserver(): Promise<void> {
LOWsrc/pages/background/index.ts310async function syncResponseCompleteObserverRegistration(): Promise<void> {
LOWsrc/pages/background/index.ts411function extractDomainsFromOrigins(origins?: string[]): string[] {
LOWsrc/pages/background/index.ts528async function injectPluginScriptIntoOpenTabs(
LOWsrc/pages/popup/Popup.tsx159function formatFolderStructurePrompt(
LOWsrc/pages/popup/utils/brandTheme.ts20export function createPopupBrandThemeStyle(brand: string): PopupBrandThemeStyle {
LOWsrc/pages/popup/utils/latestVersion.ts15export function extractLatestReleaseVersion(data: unknown): string | null {
LOWsrc/pages/content/sidebarCollapseNudge.ts37export function removeSidebarCollapseNudge(): void {
LOWsrc/pages/content/sidebarCollapseNudge.ts41function mountSidebarCollapseNudge(anchor: HTMLElement): void {
LOWsrc/pages/content/sidebarCollapseNudge.ts83export async function showSidebarCollapseNudgeOnce(anchor: HTMLElement): Promise<void> {
LOWsrc/pages/content/fork/featureFlag.ts1export function isForkFeatureEnabledValue(value: unknown): boolean {
LOWsrc/pages/content/fork/chatPairs.ts109function pickAssistantExportElement(assistantHost: HTMLElement): HTMLElement {
LOWsrc/pages/content/fork/index.ts337function extractConversationIdFromUrl(): string | null {
LOWsrc/pages/content/fork/index.ts344function getNewConversationUrlForCurrentAccount(): string {
LOWsrc/pages/content/fork/index.ts371function buildForkMarkdownFilename(title: string): string {
LOWsrc/pages/content/fork/index.ts430function extractConversationIdFromHref(href: string): string | null {
LOWsrc/pages/content/fork/index.ts442function findSidebarConversationLinkById(conversationId: string): HTMLAnchorElement | null {
LOWsrc/pages/content/fork/index.ts460function navigateToForkConversation(node: ForkNode): void {
LOWsrc/pages/content/fork/index.ts477function collectSidebarConversationIds(): Set<string> {
LOWsrc/pages/content/fork/index.ts551async function pruneDeletedNodesFromGroup(
LOWsrc/pages/content/fork/index.ts576function clearInjectedForkIndicators(): void {
187 more matches not shown…
Decorative Section Separators22 hits · 66 pts
SeverityFileLineSnippet
MEDIUM.github/workflows/release.yml11# -------------------------
MEDIUMsrc/pages/popup/Popup.tsx1498 // ── Section reorder helpers ──────────────────────────────────
MEDIUMsrc/pages/content/folder/manager.ts708 // ─── DOM recovery (resize / print) ─────────────────────────────────────
MEDIUMsrc/pages/content/folder/manager.ts5839 // ── Overlay ───────────────────────────────────────────────────────────
MEDIUMsrc/pages/content/folder/manager.ts5850 // ── Title ─────────────────────────────────────────────────────────────
MEDIUMsrc/pages/content/folder/manager.ts5859 // ── Instructions textarea ─────────────────────────────────────────────
MEDIUMsrc/pages/content/folder/manager.ts5875 // ── Actions ──────────────────────────────────────────────────────────
MEDIUMsrc/pages/content/folder/manager.ts5901 // ── Assembly ──────────────────────────────────────────────────────────
MEDIUMsrc/pages/content/sidebarAutoHide/index.ts110// ─── Transition CSS (shared) ───────────────────────────────────────────
MEDIUMsrc/pages/content/sidebarAutoHide/index.ts137// ─── Full-Hide CSS ─────────────────────────────────────────────────────
MEDIUMsrc/pages/content/sidebarAutoHide/index.ts166// ─── Edge Trigger (full-hide) ──────────────────────────────────────────
MEDIUMsrc/pages/content/sidebarAutoHide/index.ts226// ─── Sidebar State Detection ───────────────────────────────────────────
MEDIUMsrc/pages/content/sidebarAutoHide/index.ts381// ─── Menu Click Handling ───────────────────────────────────────────────
MEDIUMsrc/pages/content/sidebarAutoHide/index.ts425// ─── Sidebar Toggle ────────────────────────────────────────────────────
MEDIUMsrc/pages/content/sidebarAutoHide/index.ts468// ─── Predictive Aiming ────────────────────────────────────────────────
MEDIUMsrc/pages/content/sidebarAutoHide/index.ts552// ─── Mouse Event Handlers ──────────────────────────────────────────────
MEDIUMsrc/pages/content/sidebarAutoHide/index.ts592// ─── DOM Management ────────────────────────────────────────────────────
MEDIUMsrc/pages/content/sidebarAutoHide/index.ts681// ─── Shared Infrastructure ─────────────────────────────────────────────
MEDIUMsrc/pages/content/sidebarAutoHide/index.ts733// ─── Auto-Hide Feature ────────────────────────────────────────────────
MEDIUMsrc/pages/content/sidebarAutoHide/index.ts792// ─── Full-Hide Feature ─────────────────────────────────────────────────
MEDIUMsrc/pages/content/sidebarAutoHide/index.ts854// ─── Entry Point ───────────────────────────────────────────────────────
MEDIUMsrc/pages/content/export/index.ts2359 // ─── DOM recovery (resize / print) ─────────────────────────────────────
Verbosity Indicators14 hits · 23 pts
SeverityFileLineSnippet
LOWpublic/fetchInterceptor.js219 // Step 2: Processing
LOWscripts/build-safari.sh10# Step 1: Build the extension using Vite
LOWscripts/build-safari.sh14# Step 2: Check if dist_safari exists
LOWscripts/build-safari.sh22# Step 3: Convert to Safari App Extension (requires macOS)
LOWsrc/pages/content/folder/aistudio.ts2476 // Step 1: Try to restore from localStorage backups (primary, emergency, beforeUnload)
LOWsrc/pages/content/folder/aistudio.ts2487 // Step 2: Keep existing in-memory data if it exists and is valid
LOWsrc/pages/content/folder/aistudio.ts2494 // Step 3: Last resort - initialize empty data and notify user
LOWsrc/pages/content/folder/manager.ts4320 // Step 1: Find the conversation element in the sidebar.
LOWsrc/pages/content/folder/manager.ts6979 // Step 1: Try to restore from localStorage backups (primary, emergency, beforeUnload)
LOWsrc/pages/content/folder/manager.ts6991 // Step 2: If current this.data already has valid structure, keep it
LOWsrc/pages/content/folder/manager.ts6998 // Step 3: Last resort - initialize empty data and log critical error
LOWsrc/pages/content/watermarkRemover/index.ts627 // Step 1: Downloading original image
LOWsrc/pages/content/watermarkRemover/index.ts660 // Step 2: Processing watermark
LOWsrc/pages/content/watermarkRemover/index.ts674 // Step 3: Done, auto-dismiss after 2s
Synthetic Comment Markers3 hits · 15 pts
SeverityFileLineSnippet
HIGHdocs/pt/guide/nanobanana.md11Images generated by Gemini™ come with a visible watermark by default. While this is intended for safety, there are creat
HIGHdocs/ar/guide/nanobanana.md11Images generated by Gemini™ come with a visible watermark by default. While this is intended for safety, there are creat
HIGHdocs/en/guide/nanobanana.md11Images generated by Gemini™ come with a visible watermark by default. While this is intended for safety, there are creat
Over-Commented Block13 hits · 13 pts
SeverityFileLineSnippet
LOWpublic/fetchInterceptor.js141 // Store original fetch
LOWsafari/App/SafariWebExtensionHandler.swift1//
LOWsafari/Models/SafariMessage.swift1//
LOW.github/workflows/release.yml1name: Release
LOW.github/workflows/release.yml21# 4. Creates git tag "vX.Y.Z".
LOWsrc/core/types/common.ts141 FOLDERS_HIDDEN: 'gvFoldersHidden',
LOWsrc/core/types/common.ts201 // Popup section order
LOWsrc/pages/content/index.tsx501
LOWsrc/pages/content/folder/manager.ts1161 this.changeFolderColor(folderId, color);
LOWsrc/pages/content/sidebarAutoHide/index.ts21// `findToggleButton` because the 2026 layout keeps an invisible 0×0 sibling
LOWsrc/pages/content/export/responseActionImageButton.ts141 // this, clicks on the SVG's painted area (the icon glyph) hit the SVG/icon
LOWsrc/pages/content/sidebarWidth/index.ts321 // applyWidth(currentWidthValue);
LOWsrc/pages/content/quoteReply/index.ts361 focusChatInput(input);
Fake / Example Data7 hits · 7 pts
SeverityFileLineSnippet
LOW…ore/services/__tests__/AccountIsolationService.test.ts89 email: 'user@example.com',
LOW…ore/services/__tests__/AccountIsolationService.test.ts118 email: 'user@example.com',
LOW…atures/backup/services/__tests__/BackupService.test.ts26 [getTimelineHierarchyStorageKey(`email:${hashString('user@example.com')}`)]: {
LOW…/popup/components/__tests__/CloudSyncSettings.test.tsx441 email: 'user@example.com',
LOW…/popup/components/__tests__/CloudSyncSettings.test.tsx451 accountKey: `email:${hashString('user@example.com')}`,
LOW…/popup/components/__tests__/CloudSyncSettings.test.tsx482 `email:${hashString('user@example.com')}`,
LOWsrc/pages/content/prompt/__tests__/localBackup.test.ts53 email: 'user@example.com',
AI Slop Vocabulary2 hits · 6 pts
SeverityFileLineSnippet
MEDIUMsrc/pages/content/folder/manager.ts5924 // observer. This mirrors the proven, robust export-button observer: it
MEDIUMsrc/pages/content/timeline/manager.ts1744 // Use index lookup if available for robust handling of duplicate content