Desktop Companion for Hermes Agent
This report summarizes scanner evidence for fathah/hermes-desktop, a TypeScript project with 14,391 GitHub stars. SynthScan examined 212,579 lines of code across 911 source files, recording 606 pattern matches distributed across 13 syntactic categories. The legacy adjusted pattern signal is 5.9 (Moderate pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 345 finding(s).
Are imports declared and package/API names verified? 70 finding(s).
Are wrappers, guards, and repeated structures necessary? 463 finding(s).
Which changes need focused human review? 606 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 606 distinct pattern matches across 13 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | tests/installer-utils.test.ts | 38 | // ─── readLogs (test the logic, not the import) ───────── | COMMENT |
| MEDIUM | tests/installer-utils.test.ts | 71 | // ─── MCP server YAML parsing ─────────────────────────── | COMMENT |
| MEDIUM | tests/installer-utils.test.ts | 164 | // ─── Memory provider discovery logic ──────────────────── | COMMENT |
| MEDIUM | tests/installer-utils.test.ts | 237 | // ─── OAuth credential discovery ───────────────── | COMMENT |
| MEDIUM | tests/installer-utils.test.ts | 313 | // ─── OpenClaw detector ───────────────────────────────── | COMMENT |
| MEDIUM | tests/installer-utils.test.ts | 368 | // ─── Backward compatibility checks ───────────────────── | COMMENT |
| MEDIUM | tests/buildUserContent.test.ts | 63 | // ── helpers ────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/buildUserContent.test.ts | 112 | // ── tests ──────────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/constants.test.ts | 16 | // ─── PROVIDERS ────────────────────────────────────────── | COMMENT |
| MEDIUM | tests/constants.test.ts | 91 | // ─── GATEWAY_PLATFORMS ────────────────────────────────── | COMMENT |
| MEDIUM | tests/constants.test.ts | 148 | // ─── GATEWAY_SECTIONS ─────────────────────────────────── | COMMENT |
| MEDIUM | tests/constants.test.ts | 188 | // ─── SETTINGS_SECTIONS ────────────────────────────────── | COMMENT |
| MEDIUM | tests/constants.test.ts | 224 | // ─── Static constants ─────────────────────────────────── | COMMENT |
| MEDIUM | tests/constants.test.ts | 254 | // ─── providerRouteForEnvKey ───────────────────────────── | COMMENT |
| MEDIUM | tests/sse-parser.test.ts | 8 | // ─── parseSseBlock ────────────────────────────────────── | COMMENT |
| MEDIUM | tests/sse-parser.test.ts | 45 | // ─── processCustomEvent ───────────────────────────────── | COMMENT |
| MEDIUM | tests/sse-parser.test.ts | 163 | // ─── processSseData ───────────────────────────────────── | COMMENT |
| MEDIUM | tests/ipc-handlers.test.ts | 62 | // ─── New feature handlers registered ──────────────────── | COMMENT |
| MEDIUM | tests/ipc-handlers.test.ts | 91 | // ─── Legacy handlers still present ────────────────────── | COMMENT |
| MEDIUM | tests/validation.test.ts | 266 | // ── Nous Portal (issue #367) ───────────────────────────────── | COMMENT |
| MEDIUM | tests/validation.test.ts | 266 | // ── Nous Portal (issue #367) ───────────────────────────────── | COMMENT |
| MEDIUM | tests/preload-api-surface.test.ts | 66 | // ─── New APIs exist ───────────────────────────────────── | COMMENT |
| MEDIUM | tests/preload-api-surface.test.ts | 166 | // ─── Legacy APIs still present ────────────────────────── | COMMENT |
| MEDIUM | tests/preload-api-surface.test.ts | 269 | // ─── IPC channel consistency ──────────────────────────── | COMMENT |
| MEDIUM | scripts/verify-369-wsl-drift.js | 36 | // ── A. Run audit, look for drift issues ───────────────────── | COMMENT |
| MEDIUM | scripts/verify-369-wsl-drift.js | 61 | // ── B. Auto-fix the first autoFixable drift ──────────────── | COMMENT |
| MEDIUM | scripts/verify-369-wsl-drift.js | 86 | // ── C. Confirm Windows-side .env now has the value ────────── | COMMENT |
| MEDIUM | scripts/verify-369-wsl-drift.js | 97 | // ── D. Re-run audit — the same drift should be gone ──────── | COMMENT |
| MEDIUM | src/renderer/src/constants.ts | 1 | // ── Shared Types ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/constants.ts | 35 | // ── Providers ─────────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/constants.ts | 661 | // ── Theme ─────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/constants.ts | 710 | // ── Font ──────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/constants.ts | 740 | // ── Settings API Key Sections ─────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/constants.ts | 1016 | // ── Gateway Sections ──────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/constants.ts | 1352 | // ── Install ───────────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/attachmentUtils.test.ts | 19 | // ── helpers ────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/attachmentUtils.test.ts | 49 | // ── processFiles ───────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/attachmentUtils.test.ts | 202 | // ── filesFromClipboard ─────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/attachmentUtils.ts | 63 | // ───────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/attachmentUtils.ts | 65 | // ───────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/ModelPicker.test.tsx | 100 | // ── initial render ────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/ModelPicker.test.tsx | 114 | // ── open / close ──────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/ModelPicker.test.tsx | 162 | // ── model list rendering ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/ModelPicker.test.tsx | 210 | // ── model selection ───────────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/ModelPicker.test.tsx | 232 | // ── search / filtering ────────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/ModelPicker.test.tsx | 290 | // ── provider rail ─────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/ModelPicker.test.tsx | 306 | // ── configure providers/models footer ─────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/ModelPicker.test.tsx | 324 | // ── edge cases ────────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/MessageList.tsx | 129 | // ── Scroll-driven expansion (infinite history) ──────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/mediaUtils.test.ts | 26 | // ── Explicit MEDIA: tokens ───────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/mediaUtils.test.ts | 65 | // ── Whole-line bare paths ────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/mediaUtils.test.ts | 95 | // ── Inline bare paths (mid-sentence) ─────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/mediaUtils.test.ts | 239 | // ── False-positive guards ────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Chat/mediaUtils.test.ts | 362 | // ── Misc ─────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Office/office3d/trips.ts | 37 | // ── Tuning ───────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Office/office3d/layout.ts | 61 | // ── Partition between work area (west) and rest room (east) ──────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Office/office3d/layout.ts | 89 | // ── Desks (work area, west of the partition) ─────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Office/office3d/layout.ts | 98 | // ── CEO executive desk ───────────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Office/office3d/layout.ts | 113 | // ── CEO glass corner office (south-west of the work area) ────────────────── | COMMENT |
| MEDIUM | src/renderer/src/screens/Office/office3d/layout.ts | 291 | // ── Rest room (east of the partition) ────────────────────────────────────── | COMMENT |
| 107 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | tests/hermes-agent-compat-profiles.test.ts | 61 | print(json.dumps({ | CODE |
| HIGH | scripts/repro-session-proliferation.js | 48 | print(json.dumps({"total": total, "rows": rows})) | CODE |
| HIGH | scripts/repro-long-conversation.js | 42 | print(json.dumps({"total": total, "rows": rows})) | CODE |
| HIGH | scripts/repro-gateway-restart-midchat.js | 43 | print(json.dumps({"rows": rows})) | CODE |
| HIGH | scripts/repro-gateway-restart-v2.js | 32 | print(json.dumps({"rows": rows})) | CODE |
| HIGH⚡ | src/main/ssh-docker.ts | 170 | return False | CODE |
| HIGH⚡ | src/main/ssh-docker.ts | 177 | return True | CODE |
| HIGH⚡ | src/main/ssh-docker.ts | 178 | return False | CODE |
| HIGH | src/main/ssh-docker.ts | 139 | elif os.path.exists(home): | CODE |
| HIGH | src/main/ssh-docker.ts | 214 | print(json.dumps({ | CODE |
| HIGH | src/main/ssh-docker.ts | 313 | print(json.dumps({"ok": False, "error": msg})) | CODE |
| HIGH | src/main/ssh-docker.ts | 354 | print(json.dumps({"ok": True, "dataHome": data_home, "execUser": exec_user, "cliPath": cli_path})) | CODE |
| HIGH | src/main/ssh-docker.ts | 392 | print(json.dumps({"ok": False, "error": msg, "warnings": warnings})) | CODE |
| HIGH | src/main/ssh-docker.ts | 423 | elif os.path.isdir(home): | CODE |
| HIGH | src/main/ssh-docker.ts | 428 | elif os.path.exists(home): | CODE |
| HIGH | src/main/ssh-docker.ts | 485 | print(json.dumps({"ok": True, "version": version.stdout.strip(), "warnings": warnings})) | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 490 | print(json.dumps({"totalSessions": 0, "totalMessages": 0})) | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 496 | print(json.dumps({"totalSessions": s, "totalMessages": m})) | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 498 | print(json.dumps({"totalSessions": 0, "totalMessages": 0})) | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 1597 | print(json.dumps({"data_url": None})); sys.exit(0) | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 1602 | print(json.dumps({"data_url": None})); sys.exit(0) | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 1605 | print(json.dumps({"data_url": None})); sys.exit(0) | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 1609 | print(json.dumps({"data_url": None})); sys.exit(0) | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 1610 | print(json.dumps({"data_url": "data:%s;base64,%s" % (mime, base64.b64encode(data).decode("ascii"))})) | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 1612 | print(json.dumps({"data_url": None})) | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 1710 | print(json.dumps(result)) | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 1712 | print("[]") | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 1889 | if not os.path.exists(pid_file): return False | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 1900 | return True | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 1902 | return False | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 2285 | return None | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 2291 | return None | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 2299 | return None | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 2638 | print(response.status) | CODE |
| HIGH⚡ | src/main/ssh-remote.ts | 2640 | print(0) | CODE |
| HIGH | src/main/ssh-remote.ts | 182 | elif raw.startswith("$HOME/"): | CODE |
| HIGH | src/main/ssh-remote.ts | 192 | print(json.dumps(rows)) | CODE |
| HIGH | src/main/ssh-remote.ts | 297 | print(json.dumps(skills)) | CODE |
| HIGH | src/main/ssh-remote.ts | 1024 | return False | CODE |
| HIGH | src/main/ssh-remote.ts | 1044 | print(json.dumps(result)) | CODE |
| HIGH | src/main/ssh-remote.ts | 1393 | print("[]"); sys.exit(0) | CODE |
| HIGH | src/main/ssh-remote.ts | 1409 | print(json.dumps(result)) | CODE |
| HIGH | src/main/ssh-remote.ts | 1441 | print("[]"); sys.exit(0) | CODE |
| HIGH | src/main/ssh-remote.ts | 1545 | print(json.dumps(items)) | CODE |
| HIGH | src/main/ssh-remote.ts | 1687 | print("[]"); sys.exit(0) | CODE |
| HIGH | src/main/ssh-remote.ts | 1929 | print(json.dumps(profiles)) | CODE |
| HIGH | src/main/ssh-remote.ts | 2366 | print(current) | CODE |
| HIGH | src/main/ssh-remote.ts | 2370 | print(port) | CODE |
| HIGH | src/main/ssh-remote.ts | 2564 | print(sock.getsockname()[1]) | CODE |
| HIGH | src/main/ssh-remote.ts | 3419 | print(json.dumps(result)) | CODE |
| HIGH | src/main/ssh-env-update.ts | 46 | elif sys.platform.startswith("linux"): | CODE |
| HIGH | src/main/ssh-env-update.ts | 68 | elif operation not in ("ensure-dashboard", "ensure-api"): | CODE |
| HIGH | src/main/ssh-env-update.ts | 112 | elif operation == "ensure-dashboard": | CODE |
| HIGH | src/main/ssh-env-update.ts | 130 | elif key not in seen: | CODE |
| HIGH⚡ | src/main/ssh-env-update.ts | 160 | print(json.dumps(update_env(json.load(sys.stdin)))) | CODE |
| HIGH⚡ | src/main/ssh-env-update.ts | 162 | print("Could not safely update remote credentials: " + str(error), file=sys.stderr) | CODE |
| HIGH⚡ | src/main/hermes-agent-compat.ts | 145 | return None | CODE |
| HIGH⚡ | src/main/hermes-agent-compat.ts | 149 | return None | CODE |
| HIGH⚡ | src/main/hermes-agent-compat.ts | 195 | return None | CODE |
| HIGH⚡ | src/main/hermes-agent-compat.ts | 202 | return None | CODE |
| 5 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | AGENTS.md | 71 | def test_rejects_expired_tokens(): | CODE |
| LOW | AGENTS.md | 75 | def test_handles_missing_password(): | CODE |
| LOW | CLAUDE.md | 71 | def test_rejects_expired_tokens(): | CODE |
| LOW | CLAUDE.md | 75 | def test_handles_missing_password(): | CODE |
| LOW | tests/connection-config-security.test.ts | 10 | async function loadConnectionConfigModule(): Promise< | CODE |
| LOW | tests/remote-history.test.ts | 30 | function extractLocalRecoveryFunction(): string { | CODE |
| LOW | tests/remote-history.test.ts | 32 | "async function sendMessageViaBestApiWithLocalRecovery(", | CODE |
| LOW | tests/remote-history.test.ts | 148 | "async function sendMessageViaBestApiWithLocalRecovery(", | CODE |
| LOW | tests/ipc-handlers.test.ts | 29 | function extractPreloadInvokeChannels(src: string): string[] { | CODE |
| LOW | tests/hermes-agent-compat.test.ts | 35 | function normalizeWithInjectedPython(values: string[]): string[] { | CODE |
| LOW | tests/hermes-agent-compat.test.ts | 43 | const start = patched.indexOf("def _hermes_one_normalize_url_path(path):"); | CODE |
| LOW⚡ | tests/hermes-agent-compat.test.ts | 147 | "def _hermes_one_model_library_path(profile=None)", | CODE |
| LOW⚡ | tests/hermes-agent-compat.test.ts | 150 | "def _hermes_one_current_model_row(profile=None)", | CODE |
| LOW⚡ | tests/hermes-agent-compat.test.ts | 156 | "def hermes_one_get_model_library(profile: Optional[str] = None)", | CODE |
| LOW⚡ | tests/hermes-agent-compat.test.ts | 165 | "def hermes_one_add_model_library_row(body: Dict[str, Any], profile: Optional[str] = None)", | CODE |
| LOW⚡ | tests/hermes-agent-compat.test.ts | 168 | "def hermes_one_update_model_library_row(model_id: str, body: Dict[str, Any], profile: Optional[str] = None)", | CODE |
| LOW⚡ | tests/hermes-agent-compat.test.ts | 171 | "def hermes_one_delete_model_library_row(model_id: str, profile: Optional[str] = None)", | CODE |
| LOW | tests/hermes-agent-compat.test.ts | 265 | def hermes_one_get_model_library(): | CODE |
| LOW | .agents/skills/lat-md/SKILL.md | 141 | def test_rejects_expired_tokens(): | CODE |
| LOW | .claude/skills/lat-md/SKILL.md | 141 | def test_rejects_expired_tokens(): | CODE |
| LOW | scripts/drive-live-regression-suite.js | 77 | function assertNoDuplicateRenderedImages(state, label) { | CODE |
| LOW | src/renderer/src/App.tsx | 206 | function handleDismissVerifyWarning(): void { | CODE |
| LOW | src/renderer/src/utils/analytics.ts | 48 | function getOrCreateAnonymousId(): string { | CODE |
| LOW | src/renderer/src/screens/Settings/ConfigHealth.tsx | 45 | function publishConfigHealthReport(report: Report): void { | CODE |
| LOW | src/renderer/src/screens/Chat/mediaUtils.ts | 201 | function markdownDestinationRanges(content: string): Array<[number, number]> { | CODE |
| LOW | src/renderer/src/screens/Chat/chatNotifications.ts | 2 | export function shouldPlayCompletionSound( | CODE |
| LOW | src/renderer/src/screens/Chat/dashboardEventAdapter.ts | 29 | export function dashboardApprovalRequestId( | CODE |
| LOW | src/renderer/src/screens/Chat/dashboardEventAdapter.ts | 230 | function toolEventFromGatewayEvent(event: DashboardStreamEvent): ChatToolEvent { | CODE |
| LOW | src/renderer/src/screens/Chat/dashboardEventAdapter.ts | 606 | function hasReasoningSinceLastUser( | CODE |
| LOW | src/renderer/src/screens/Chat/dashboardEventAdapter.ts | 619 | function addCompletionReasoningFallback( | CODE |
| LOW | src/renderer/src/screens/Chat/dashboardEventAdapter.ts | 651 | function completeAssistantWithFinalText( | CODE |
| LOW | src/renderer/src/screens/Chat/dashboardEventAdapter.ts | 700 | export function applyDashboardStreamEvent( | CODE |
| LOW | src/renderer/src/screens/Chat/sessionHistory.ts | 149 | function normalizeBubbleContentForMatch(s: string): string { | CODE |
| LOW | src/renderer/src/screens/Chat/sessionHistory.ts | 159 | function buildDbAssistantSplitSequences( | CODE |
| LOW | src/renderer/src/screens/Chat/sessionHistory.ts | 248 | function isSyntheticLiveToolMessage(m: ChatMessage): boolean { | CODE |
| LOW | src/renderer/src/screens/Chat/sessionHistory.ts | 262 | function consumeCanonicalToolMatch( | CODE |
| LOW | src/renderer/src/screens/Chat/sessionHistory.ts | 282 | function mergeDbMetadataIntoStreamed( | CODE |
| LOW | src/renderer/src/screens/Chat/sessionHistory.ts | 338 | function compactOrphanDuplicateUserRuns( | CODE |
| LOW | src/renderer/src/screens/Chat/sessionHistory.ts | 398 | function anchorUnmatchedUsersBeforeConsumedTurnRows( | CODE |
| LOW | src/renderer/src/screens/Chat/sessionHistory.ts | 468 | function hasUniqueCurrentUserContent( | CODE |
| LOW | src/renderer/src/screens/Chat/sessionHistory.ts | 506 | function findNextOutputAnchorIndex( | CODE |
| LOW | src/renderer/src/screens/Chat/sessionHistory.ts | 522 | function hasEquivalentAssistantError( | CODE |
| LOW | src/renderer/src/screens/Chat/sessionHistory.ts | 552 | export function preserveLocalAssistantErrors( | CODE |
| LOW | src/renderer/src/screens/Chat/sessionHistory.ts | 639 | function firstDbIndexMatchingActiveTurnOutput( | CODE |
| LOW | src/renderer/src/screens/Chat/sessionHistory.ts | 660 | function findPreviousLocalErrorIndex( | CODE |
| LOW | src/renderer/src/screens/Chat/sessionHistory.ts | 910 | function dropLossyStreamedReasoning( | CODE |
| LOW | src/renderer/src/screens/Chat/sessionHistory.ts | 958 | function repositionInteractiveCards( | CODE |
| LOW | src/renderer/src/screens/Chat/dashboardGatewayClient.ts | 48 | export function normalizeDashboardNotification( | CODE |
| LOW | src/renderer/src/screens/Chat/liveToolEvents.ts | 7 | function toolProgressToNameAndPreview(progress: string): { | CODE |
| LOW | src/renderer/src/screens/Chat/liveToolEvents.ts | 28 | export function liveToolEventFromProgress(progress: string): ChatToolEvent { | CODE |
| LOW | src/renderer/src/screens/Chat/liveToolEvents.ts | 91 | function findLatestRunningSyntheticToolIndex( | CODE |
| LOW | src/renderer/src/screens/Chat/liveToolEvents.ts | 110 | function findLatestRunningSyntheticToolByNameIndex( | CODE |
| LOW | src/renderer/src/screens/Chat/liveToolEvents.ts | 167 | function upsertToolResultAfterCall( | CODE |
| LOW | …enderer/src/screens/Chat/slash/virtualSlashCommands.ts | 31 | export function createSlashCommandVirtualLayout( | CODE |
| LOW | …enderer/src/screens/Chat/slash/virtualSlashCommands.ts | 73 | export function getVisibleSlashCommandRows( | CODE |
| LOW | …er/src/screens/Chat/hooks/useDashboardChatTransport.ts | 164 | export function dashboardChatEnabledFromEnv( | CODE |
| LOW | …er/src/screens/Chat/hooks/useDashboardChatTransport.ts | 170 | export function dashboardChatEnabledForConnection( | CODE |
| LOW⚡ | …er/src/screens/Chat/hooks/useDashboardChatTransport.ts | 185 | export function dashboardShouldPersistLocalOverlays( | CODE |
| LOW⚡ | …er/src/screens/Chat/hooks/useDashboardChatTransport.ts | 191 | export function isDashboardSessionNotFoundError(err: unknown): boolean { | CODE |
| LOW⚡ | …er/src/screens/Chat/hooks/useDashboardChatTransport.ts | 196 | export function isDashboardSlashWorkerExitError(err: unknown): boolean { | CODE |
| 212 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | AGENTS.md | 36 | - **Section ids**: `lat.md/path/to/file#Heading#SubHeading` — full form uses project-root-relative path (e.g. `lat.md/te | CODE |
| MEDIUM | CLAUDE.md | 36 | - **Section ids**: `lat.md/path/to/file#Heading#SubHeading` — full form uses project-root-relative path (e.g. `lat.md/te | CODE |
| MEDIUM | lat.md/provider-setup.md | 176 | [[src/renderer/src/components/ProviderKeysSection.tsx#ProviderModelsManager]] renders below the key field in the config | CODE |
| MEDIUM | lat.md/model-context.md | 1 | # Model context window | COMMENT |
| MEDIUM | lat.md/model-context.md | 21 | For local connections, [[src/main/model-discovery.ts#getModelContextWindow]] consults [[src/main/config.ts#getModelConte | CODE |
| MEDIUM | tests/hermes-agent-compat-profiles.test.ts | 7 | // @lat: [[model-context#Model context window#Dashboard default profile isolation]] | COMMENT |
| MEDIUM | .agents/skills/lat-md/SKILL.md | 64 | Examples: `lat.md/tests/search#RAG Replay Tests`, `cli#init`, `parser#Wiki Links`. | CODE |
| MEDIUM | .agents/skills/hermes-agent/SKILL.md | 20 | - 5.2 [Tool Orchestration (model_tools.py)](#52-tool-orchestration-model_toolspy) | CODE |
| MEDIUM | .agents/skills/hermes-agent/SKILL.md | 164 | ├── model_tools.py # Tool orchestration, _discover_tools(), handle_function_call() | CODE |
| MEDIUM | .agents/skills/hermes-agent/SKILL.md | 1262 | ├── autonomous-ai-agents/ # Multi-agent orchestration | CODE |
| MEDIUM | .claude/skills/lat-md/SKILL.md | 64 | Examples: `lat.md/tests/search#RAG Replay Tests`, `cli#init`, `parser#Wiki Links`. | CODE |
| MEDIUM | .claude/skills/hermes-agent/SKILL.md | 20 | - 5.2 [Tool Orchestration (model_tools.py)](#52-tool-orchestration-model_toolspy) | CODE |
| MEDIUM | .claude/skills/hermes-agent/SKILL.md | 164 | ├── model_tools.py # Tool orchestration, _discover_tools(), handle_function_call() | CODE |
| MEDIUM | .claude/skills/hermes-agent/SKILL.md | 1262 | ├── autonomous-ai-agents/ # Multi-agent orchestration | CODE |
| MEDIUM | src/renderer/src/screens/Chat/MessageList.tsx | 278 | // rows — reasoning and tool rows would triple the number in agentic | COMMENT |
| MEDIUM | src/main/agent-config-providers.test.ts | 120 | // The agent's config scaffold writes `providers: {}` (inline empty dict). | COMMENT |
| MEDIUM | src/main/model-discovery.ts | 624 | // @lat: [[model-context#Model context window#Gauge resolution order]] | COMMENT |
| MEDIUM | src/main/config.ts | 1268 | // @lat: [[model-context#Model context window#Storage and propagation]] | COMMENT |
| MEDIUM | src/main/model-context.ts | 11 | // @lat: [[model-context#Model context window#Gauge resolution order]] | COMMENT |
| MEDIUM | src/main/agent-config-providers.ts | 219 | // The agent's config scaffold writes an inline empty dict (`providers: {}`), | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/install-gate-providers.test.ts | 101 | }); | COMMENT |
| LOW | tests/ssh-remote-paths.test.ts | 1 | import { describe, expect, it } from "vitest"; | COMMENT |
| LOW | tests/config-value-paths.test.ts | 1 | import { describe, it, expect, beforeEach, afterEach, vi } from "vitest"; | COMMENT |
| LOW | .agents/skills/typescript-expert/SKILL.md | 201 | COMMENT | |
| LOW | …ills/typescript-expert/references/tsconfig-strict.json | 41 | "baseUrl": ".", | COMMENT |
| LOW | src/renderer/src/constants.ts | 361 | // "Local / Others" — this chip covers both local servers and any remote | COMMENT |
| LOW | src/renderer/src/constants.ts | 521 | group: "remote", | COMMENT |
| LOW | src/renderer/src/screens/Chat/attachmentUtils.ts | 61 | } | COMMENT |
| LOW | src/renderer/src/screens/Chat/attachmentUtils.ts | 181 | const probeCtx = probeCanvas.getContext("2d"); | COMMENT |
| LOW | src/renderer/src/screens/Chat/attachmentUtils.ts | 221 | // Phase 1 — lossy formats: step quality down from 0.85 to 0.5 | COMMENT |
| LOW | src/renderer/src/screens/Chat/dashboardEventAdapter.ts | 521 | if (normStreamed.includes(normFinal)) return streamedContent; | COMMENT |
| LOW | src/renderer/src/screens/Chat/sessionHistory.ts | 801 | // `onChatError`). Preserve those tail-of-stream additions so the | COMMENT |
| LOW | src/renderer/src/screens/Chat/contextWindows.ts | 21 | // Mythos-class named models (claude-fable-5, …) — 1M context. Must come | COMMENT |
| LOW | src/renderer/src/screens/Office/RepInteractionPanel.tsx | 181 | // the panel can stay mounted while the tab is hidden and the user changes the | COMMENT |
| LOW | src/renderer/src/screens/Office/RepInteractionPanel.tsx | 241 | // The panel stays mounted while the Office selection changes (e.g. clicking | COMMENT |
| LOW | src/renderer/src/screens/Office/office3d/layout.ts | 101 | // grid which fills the rows to the north, with surrounding decor | COMMENT |
| LOW | src/renderer/src/screens/Office/office3d/Office3D.tsx | 241 | COMMENT | |
| LOW | …/renderer/src/screens/Office/office3d/core/cityPlan.ts | 21 | // ── Office entrance (south wall doorway) ────────────────────────────────── | COMMENT |
| LOW | src/renderer/src/screens/Providers/Providers.tsx | 241 | // blurring the API key input lost their typed key — config.yaml | COMMENT |
| LOW | src/renderer/src/screens/Providers/Providers.tsx | 301 | // typing in the Model field still feels responsive. | COMMENT |
| LOW | src/main/remote-skills.ts | 1 | import { getApiUrl, getRemoteAuthHeader } from "./hermes"; | COMMENT |
| LOW | src/main/validation.ts | 61 | // Nous Portal used to live here but was moved out because it supports | COMMENT |
| LOW | src/main/profiles.ts | 381 | }, | COMMENT |
| LOW | src/main/ssh-docker.ts | 21 | // remote file read/write (config, .env, sessions, logs, profiles) sees | COMMENT |
| LOW | src/main/yaml-path.ts | 1 | // Tiny indentation-aware YAML reader that resolves a dotted key path against | COMMENT |
| LOW | src/main/config-health.ts | 521 | } | COMMENT |
| LOW | src/main/ssh-remote.ts | 1081 | // | COMMENT |
| LOW | src/main/ssh-remote.ts | 2401 | key: string; | COMMENT |
| LOW | src/main/ssh-remote.ts | 2481 | // remote and tunnels to it for the model library, session list, and the chat | COMMENT |
| LOW | src/main/ssh-remote.ts | 3281 | messageCount: s.messageCount, | COMMENT |
| LOW | src/main/ssh-remote.ts | 3301 | // | COMMENT |
| LOW | src/main/default-models.ts | 61 | // qwen/qwen3-32b, qwen/qwen3-8b, Qwen/Qwen3-Coder, qwen/qwen3-coder-next, | COMMENT |
| LOW | src/main/installer.ts | 41 | // Resolve the Hermes data directory. Precedence: | COMMENT |
| LOW | src/main/installer.ts | 181 | // On Windows, use `pythonw.exe` (the GUI-subsystem interpreter that ships in | COMMENT |
| LOW | src/main/hermes.ts | 1481 | messages, | COMMENT |
| LOW | src/main/hermes.ts | 1501 | const headers = getJsonApiHeaders(profile, bodyBuf, conn); | COMMENT |
| LOW | src/main/hermes.ts | 2801 | // | COMMENT |
| LOW | src/main/hermes.ts | 3481 | // `API_SERVER_KEY=`, and config.yaml `api_server.token:` (each per-profile | COMMENT |
| LOW | src/main/gpu-fallback.ts | 21 | function shouldHonorPersistedGpuFlag(): boolean { | COMMENT |
| LOW | src/main/models.ts | 321 | try { | COMMENT |
| LOW | src/main/config.ts | 1281 | // custom/compatible endpoints). `undefined` leaves the key untouched | COMMENT |
| LOW | src/main/config.ts | 1301 | content = upsertBlockChild(content, "model", "default", model); | COMMENT |
| LOW | src/main/config.ts | 1761 | // platforms to start from env vars in .env; it doesn't look at a fictional | COMMENT |
| LOW | src/main/secrets/securityInvariants.test.ts | 101 | // INV-3: list() and get() AGREE on membership. If a key is enumerated by | COMMENT |
| LOW | src/main/secrets/index.ts | 201 | const provider = getSecretsProvider(profile); | COMMENT |
| LOW | src/main/secrets/commandProvider.ts | 81 | // env-shaped line falls through to the bare-value branch, because a bare | COMMENT |
| LOW | src/main/secrets/getSpawnFloor.test.ts | 1 | import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | …ents/skills/typescript-expert/scripts/ts_diagnostic.py | 18 | except Exception as e: | CODE |
| MEDIUM | src/main/ssh-docker.ts | 119 | def run(args, timeout=8): | CODE |
| LOW⚡ | src/main/ssh-docker.ts | 165 | except Exception: | CODE |
| LOW | src/main/ssh-docker.ts | 124 | except Exception: | CODE |
| LOW | src/main/ssh-docker.ts | 143 | except Exception: | CODE |
| LOW | src/main/ssh-docker.ts | 404 | except Exception: | CODE |
| LOW | src/main/ssh-docker.ts | 446 | except Exception: | CODE |
| LOW | src/main/ssh-docker.ts | 479 | except Exception as exc: | CODE |
| LOW⚡ | src/main/ssh-remote.ts | 1611 | except Exception: | CODE |
| LOW⚡ | src/main/ssh-remote.ts | 1711 | except Exception as e: | CODE |
| LOW⚡ | src/main/ssh-remote.ts | 1897 | except Exception: | CODE |
| LOW⚡ | src/main/ssh-remote.ts | 2639 | except Exception: | CODE |
| LOW | src/main/ssh-remote.ts | 390 | except Exception: | CODE |
| LOW | src/main/ssh-remote.ts | 1019 | except Exception: | CODE |
| LOW | src/main/ssh-remote.ts | 1455 | except Exception: | CODE |
| LOW | src/main/ssh-remote.ts | 1481 | except Exception: | CODE |
| LOW | src/main/ssh-remote.ts | 1498 | except Exception: | CODE |
| LOW | src/main/ssh-remote.ts | 1512 | except Exception: | CODE |
| LOW⚡ | src/main/ssh-env-update.ts | 161 | except Exception as error: | CODE |
| LOW⚡ | src/main/hermes-agent-compat.ts | 194 | except Exception: | CODE |
| LOW⚡ | src/main/hermes-agent-compat.ts | 201 | except Exception: | CODE |
| LOW | src/main/hermes-agent-compat.ts | 165 | except Exception: | CODE |
| LOW | src/main/hermes-agent-compat.ts | 556 | except Exception: | CODE |
| LOW | src/main/hermes-agent-compat.ts | 657 | except Exception: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | tests/ssh-env-update.test.ts | 345 | it.each(["", "short", "changeme", "API_SERVER_KEY", "your-api-key"])( | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/main/claw3d.ts | 706 | // Step 1: Clone (or pull if already cloned) | COMMENT |
| LOW | src/main/claw3d.ts | 775 | // Step 2: npm install | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/main/claw3d.ts | 706 | // Step 1: Clone (or pull if already cloned) | COMMENT |
| LOW | src/main/claw3d.ts | 775 | // Step 2: npm install | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | src/main/gpu-fallback.ts | 37 | // because the GPU process still attempts to initialize. The robust fix is to | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | …ents/skills/typescript-expert/scripts/ts_diagnostic.py | 8 | CODE | |
| LOW | …ents/skills/typescript-expert/scripts/ts_diagnostic.py | 9 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | scripts/probe-selectors.js | 21 | const placeholder = el.getAttribute("placeholder"); | CODE |
| LOW | scripts/repro-edit-model-emptykey.js | 61 | placeholder: el.getAttribute("placeholder"), | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | …ents/skills/typescript-expert/scripts/ts_diagnostic.py | 74 | CODE |