This report summarizes scanner evidence for vastsa/PI-Desktop. SynthScan examined 703,339 lines of code across 2709 source files, recording 774 pattern matches distributed across 14 syntactic categories. The legacy adjusted pattern signal is 1.3 (Low 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.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 714 finding(s).
Are imports declared and package/API names verified? 24 finding(s).
Are wrappers, guards, and repeated structures necessary? 613 finding(s).
Which changes need focused human review? 774 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 774 distinct pattern matches across 14 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 |
|---|---|---|---|---|
| LOW | scripts/e2e/transcript-long-history.tsx | 116 | export async function transcriptLongHistoryProbe() { | CODE |
| LOW | scripts/e2e/settings-scroll.jsx | 230 | async function exerciseBrazilianPortuguese() { | CODE |
| LOW | scripts/e2e/settings-scroll.jsx | 265 | async function exerciseProxyDraftRestoration() { | CODE |
| LOW | scripts/e2e/scroll-input-ownership.ts | 6 | export function probeScrollInputOwnership(scroller: HTMLElement) { | CODE |
| LOW | scripts/e2e/transcript-render.tsx | 50 | async function markdownLinkInteractionProbe( | CODE |
| LOW | scripts/e2e/transcript-render.tsx | 138 | async function contextMenuSubmenuInteractionProbe() { | CODE |
| LOW | scripts/e2e/browser-pane-lifecycle.ts | 8 | export async function checkBrowserPaneLifecycle( | CODE |
| LOW | scripts/e2e/transcript-auto-collapse.tsx | 17 | export async function transcriptAutoCollapseProbe() { | CODE |
| LOW | scripts/e2e/work-panel-tab-close.tsx | 177 | async function runTabContextMenuUserPath(): Promise<TabContextMenuPathResult> { | CODE |
| LOW | scripts/e2e/work-panel-tab-close.tsx | 280 | async function runPluginViewMenuLayerPath(): Promise<PluginViewMenuLayerResult> { | CODE |
| LOW | scripts/e2e/transcript-minimap-jump.tsx | 86 | export async function transcriptMinimapJumpProbe() { | CODE |
| LOW | packages/host-runtime/src/chat-ref-resolve.ts | 217 | async function canonicalPathOrMissingTail(path: string): Promise<string | null> { | CODE |
| LOW | packages/host-runtime/src/turn-persistence.ts | 27 | function isDuplicateMessageIdError(error: unknown): boolean { | CODE |
| LOW | packages/host-runtime/src/session-message-input.ts | 24 | export async function resolveSessionMessageInput( | CODE |
| LOW | packages/host-runtime/src/workspace-files.ts | 182 | export async function resolveRealPathWithinRoot( | CODE |
| LOW | packages/host-runtime/src/workspace-files.ts | 205 | export async function resolveRealPathForCreateWithinRoot( | CODE |
| LOW | packages/host-runtime/src/launch-resolver.ts | 122 | export function createHeadlessLaunchResolver(options: HeadlessLaunchResolverOptions): LaunchResolver { | CODE |
| LOW | packages/host-runtime/src/launch-resolver.ts | 143 | async function activeUserSubagentDocuments(projectPath: string | undefined): Promise<UserSubagentDocument[]> { | CODE |
| LOW | packages/host-runtime/src/launch-resolver.ts | 175 | async function resolveEffectiveCommandShell(): Promise<CommandShellCatalog> { | CODE |
| LOW | packages/host-runtime/src/plan-execution.ts | 68 | export function executionListFromResponse(value: unknown): PlanExecution[] { | CODE |
| LOW | packages/host-runtime/src/live-work/context.ts | 13 | export function buildLiveWorkClassifierInput(input: { | CODE |
| LOW | packages/host-runtime/src/live-work/coordinator.ts | 10 | export function liveWorkUnselectedSessionId(callId: string): string { | CODE |
| LOW | packages/host-runtime/src/live-work/coordinator.ts | 1088 | function isKnownAdmissionRejection(code: string | undefined): boolean { | CODE |
| LOW | packages/plugin-sdk/src/theme-css.ts | 234 | export function findThemeCssUrlReferences(masked: string): ThemeCssUrlReference[] { | CODE |
| LOW | packages/plugin-sdk/src/theme-css.ts | 286 | function rewriteThemeAssetReferences( | CODE |
| LOW⚡ | packages/plugin-sdk/src/theme-variables.ts | 15 | export function isPluginThemeVariableName(value: unknown): value is string { | CODE |
| LOW⚡ | packages/plugin-sdk/src/theme-variables.ts | 19 | export function validatePluginThemeVariableDeclaration(value: unknown): value is PluginThemeVariableContrib { | CODE |
| LOW⚡ | packages/plugin-sdk/src/theme-variables.ts | 29 | export function validatePluginThemeVariables(declarations: readonly PluginThemeVariableContrib[], values: unknown): Plug | CODE |
| LOW | packages/plugin-sdk/src/theme-variables.ts | 51 | export function normalizePluginThemeVariableValues(declarations: readonly PluginThemeVariableContrib[], values: unknown) | CODE |
| LOW | packages/plugin-sdk/src/theme-variables.ts | 57 | export function formatPluginThemeVariables(themeId: string, declarations: readonly PluginThemeVariableContrib[], values: | CODE |
| LOW | packages/plugin-sdk/src/net-policy.ts | 189 | export function isNetSocketUrlAllowedWithGrant( | CODE |
| LOW | packages/plugin-sdk/src/index.ts | 491 | export function resolvePluginLocalizedString( | CODE |
| LOW | packages/shared/src/racp.ts | 279 | export function eventEnvelopeSequencingIsValid(envelope: RacpEventEnvelope): boolean { | CODE |
| LOW | packages/shared/src/racp.ts | 344 | export function allowedDecisionsAreCoherent(request: RacpApprovalRequest): boolean { | CODE |
| LOW | packages/shared/src/racp.ts | 564 | export function protocolVersionsCompatible(server: string, client: string): boolean { | CODE |
| LOW | packages/shared/src/racp.ts | 832 | export function effectiveRemotePermissionMode(input: RacpCeilingInput): RacpPermissionMode { | CODE |
| LOW | packages/shared/src/composer-trigger.ts | 34 | export function normalizeLargePasteThreshold(value: unknown): number { | CODE |
| LOW | packages/shared/src/composer-trigger.ts | 60 | export function rewriteIdeographicCommaTrigger(value: string): string { | CODE |
| LOW | packages/shared/src/composer-trigger.ts | 183 | export function serializeComposerFileReferences( | CODE |
| LOW | packages/shared/src/composer-trigger.ts | 205 | export function serializeInlineComposerFileReferences( | CODE |
| LOW | packages/shared/src/composer-trigger.ts | 235 | export function stripInlineComposerFileReferenceTokens( | CODE |
| LOW | packages/shared/src/composer-trigger.ts | 253 | export function restoreInlineComposerFileReferenceTokens( | CODE |
| LOW | packages/shared/src/network-policy.ts | 116 | export function allowInsecureUserEndpoints(settings: unknown): boolean { | CODE |
| LOW | packages/shared/src/network-policy.ts | 121 | export function needsInsecureEndpointNotice(settings: unknown): boolean { | CODE |
| LOW | packages/shared/src/transcript-truncation.ts | 15 | export function resolveTranscriptTruncation( | CODE |
| LOW | packages/shared/src/provider-endpoint.ts | 111 | export function discoveryStyleForApiStyle(apiStyle?: string | null): DiscoveryStyle { | CODE |
| LOW | packages/shared/src/provider-endpoint.ts | 176 | export function providerEndpointDefinitionsForHost(host: string): readonly ProviderEndpointDefinition[] { | CODE |
| LOW | packages/shared/src/provider-endpoint.ts | 185 | export function providerEndpointDefinitionForUrl( | CODE |
| LOW | packages/shared/src/changelog-runtime.ts | 4 | export function normalizeChangelogVersion( | CODE |
| LOW | packages/shared/src/certificate-errors.ts | 21 | export function isCertificateVerificationError(code: unknown): boolean { | CODE |
| LOW | packages/shared/src/github-feedback.ts | 28 | export function formatFeedbackEnvironment(info: FeedbackIssueContext): string { | CODE |
| LOW | packages/shared/src/public-network.ts | 236 | export function isAcceptableUserEndpointAddress( | CODE |
| LOW | packages/shared/src/public-network.ts | 387 | export function isAcceptableResolvedAddress( | CODE |
| LOW | packages/shared/src/public-network.ts | 404 | export function isPublicNetworkPolicyFailure(error: unknown): boolean { | CODE |
| LOW | packages/shared/src/public-network.ts | 432 | export function publicNetworkRefusalReason(error: unknown): PublicNetworkRefusalReason | undefined { | CODE |
| LOW | packages/shared/src/public-network.ts | 511 | export function publicNetworkRefusalDetail(error: unknown): PublicNetworkRefusalDetail | undefined { | CODE |
| LOW | packages/shared/src/network-proxy.ts | 240 | export function settingsForInactiveProxyMode( | CODE |
| LOW | packages/shared/src/provider-presets.ts | 404 | export function addressesPublishedVendorHost(baseUrl: string | undefined): boolean { | CODE |
| LOW | packages/shared/src/provider-presets.ts | 497 | export function isDeepSeekReasoningReplay(input: { | CODE |
| LOW | packages/shared/src/provider-presets.ts | 510 | export function isOfficialDeepSeekEndpoint(input: { baseUrl?: string }): boolean { | CODE |
| 517 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | scripts/macos-signing-diagnostics.sh | 60 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | scripts/macos-signing-diagnostics.sh | 62 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | scripts/macos-signing-diagnostics.sh | 128 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | scripts/macos-signing-diagnostics.sh | 130 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | scripts/macos-signing-diagnostics.sh | 137 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | scripts/macos-signing-diagnostics.sh | 139 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | scripts/macos-signing-diagnostics.sh | 150 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | scripts/macos-signing-diagnostics.sh | 153 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | scripts/macos-signing-diagnostics.sh | 168 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | scripts/macos-signing-diagnostics.sh | 170 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | scripts/macos-signing-diagnostics.sh | 176 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | scripts/macos-signing-diagnostics.sh | 178 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | scripts/macos-signing-diagnostics.sh | 184 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | scripts/macos-signing-diagnostics.sh | 189 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | scripts/macos-signing-diagnostics.sh | 203 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | scripts/macos-signing-diagnostics.sh | 205 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 45 | // ── 上限 ──────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 100 | // ── 敏感路径黑名单(读与写都拒绝) ────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 123 | // ── 模块状态 ──────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 155 | // ── 错误 ──────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 171 | // ── 路径安全 ──────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 411 | // ── 项目组与基点(0.5.0) ──────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 561 | // ── 忽略规则(.gitignore / .ignore 语义子集) ──────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 676 | // ── 审计 ──────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 691 | // ── git 状态(0.7.0) ─────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 1308 | // ── 文件监听(0.8.0) ─────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 1521 | // ── 编辑器探测与「通过…打开」(0.9.0) ───────────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 2240 | // ── 读 ────────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 2430 | // ── 写 ────────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 2517 | // ── 新建 / 重命名 / 移动 / 删除 ──────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 2653 | // ── 搜索(分页 + 会话游标) ───────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 2760 | // ── SQLite(只读浏览 + 查询) ─────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 3256 | // ── 偏好 ──────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 3338 | // ── 通道路由 ──────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/desktop/resources/plugins/pi.file-manager/main.js | 3380 | // ── 生命周期 ──────────────────────────────────────────────────────────────── | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | crates/host-core/src/scratch.rs | 1 | //! Per-session scratch directories (D114). | COMMENT |
| LOW | crates/host-core/src/user_subagents.rs | 41 | /// never see their handles. That scan also `prune`s state for records it no | COMMENT |
| LOW | crates/host-core/src/background_tasks.rs | 1 | //! Background command tasks: long-lived processes started from a chat turn | COMMENT |
| LOW | crates/host-core/src/background_tasks.rs | 21 | use tokio::sync::{watch, Mutex}; | COMMENT |
| LOW | crates/host-core/src/todos.rs | 1 | //! Session checklist: validation, storage, and the single write path. | COMMENT |
| LOW | crates/host-core/src/todos.rs | 281 | COMMENT | |
| LOW | crates/host-core/src/transcripts.rs | 1 | //! Per-session transcript files (D119). | COMMENT |
| LOW | crates/host-core/src/transcripts.rs | 121 | #[derive(Debug, Clone, Serialize, Deserialize)] | COMMENT |
| LOW | crates/host-core/src/transcripts.rs | 141 | /// turn, and because the suffix grows with every turn the file grew | COMMENT |
| LOW | crates/host-core/src/transcripts.rs | 481 | } | COMMENT |
| LOW | crates/host-core/src/transcripts.rs | 1301 | Ok(()) | COMMENT |
| LOW | crates/host-core/src/transcripts.rs | 1321 | /// | COMMENT |
| LOW | crates/host-core/src/transcripts.rs | 1481 | data_dir: &Path, | COMMENT |
| LOW | crates/host-core/src/transcripts.rs | 1601 | /// The file is streamed once to record where its matching lines are, and only | COMMENT |
| LOW | crates/host-core/src/sessions.rs | 141 | /// True when this session is the transcript owned by a scheduled-task run. | COMMENT |
| LOW | crates/host-core/src/sessions.rs | 181 | #[serde(skip_serializing_if = "Option::is_none")] | COMMENT |
| LOW | crates/host-core/src/sessions.rs | 201 | /// Original text for a slash template or Skill invocation. | COMMENT |
| LOW | crates/host-core/src/sessions.rs | 221 | #[serde(skip_serializing_if = "Option::is_none")] | COMMENT |
| LOW | crates/host-core/src/sessions.rs | 241 | /// For user messages that own regenerate history: total revision count. | COMMENT |
| LOW | crates/host-core/src/sessions.rs | 261 | #[serde(skip_serializing_if = "Option::is_none")] | COMMENT |
| LOW | crates/host-core/src/sessions.rs | 301 | #[serde(skip_serializing_if = "Vec::is_empty")] | COMMENT |
| LOW | crates/host-core/src/sessions.rs | 2461 | /// row. | COMMENT |
| LOW | crates/host-core/src/sessions.rs | 2801 | } | COMMENT |
| LOW | crates/host-core/src/sessions.rs | 3521 | /// The user root as it now stands on disk, for the renderer's pager. | COMMENT |
| LOW | crates/host-core/src/sessions.rs | 4061 | COMMENT | |
| LOW | crates/host-core/src/keyboard.rs | 1 | //! Windows-only global keyboard fallback for shortcuts reserved by the shell. | COMMENT |
| LOW | crates/host-core/src/state.rs | 41 | /// Subagent definitions the user owns, alongside the builtin and per-project | COMMENT |
| LOW | crates/host-core/src/state.rs | 61 | pub plugin_import_rates: HashMap<String, Vec<Instant>>, | COMMENT |
| LOW | crates/host-core/src/state.rs | 81 | /// Abort can race ahead of tools.execute because host RPC requests run in | COMMENT |
| LOW | crates/host-core/src/workspace.rs | 201 | root == candidate | COMMENT |
| LOW | crates/host-core/src/network_policy.rs | 1 | //! Trust policy for the endpoints the user enters themselves, as host-core | COMMENT |
| LOW | crates/host-core/src/permissions.rs | 141 | /// read/inspect core plus Bash; only their submit tool differs, and that one | COMMENT |
| LOW | crates/host-core/src/permissions.rs | 201 | declared_risk, | COMMENT |
| LOW | crates/host-core/src/session_search.rs | 61 | } | COMMENT |
| LOW | crates/host-core/src/user_skills.rs | 61 | pub level: Option<String>, | COMMENT |
| LOW | crates/host-core/src/user_skills.rs | 281 | /// | COMMENT |
| LOW | crates/host-core/src/user_skills.rs | 401 | directory.join(stem).join("SKILL.md") | COMMENT |
| LOW | crates/host-core/src/agent_capabilities.rs | 341 | _ => self.level == CapabilityLevel::Global, | COMMENT |
| LOW | crates/host-core/src/agent_capabilities.rs | 381 | /// | COMMENT |
| LOW | crates/host-core/src/activation.rs | 1 | use serde::{Deserialize, Serialize}; | COMMENT |
| LOW | crates/host-core/src/tools/shell.rs | 461 | .ok_or_else(|| "Command Prompt (cmd.exe) was not found".into()) | COMMENT |
| LOW | crates/host-core/src/tools/shell.rs | 601 | } | COMMENT |
| LOW | crates/host-core/src/tools/ignore_rules.rs | 1 | //! Workspace ignore rules (spec 03-runtime/15, D032). | COMMENT |
| LOW | crates/host-core/src/tools/mod.rs | 41 | /// per-result budgets (`BUDGET_SHELL` and friends). The retained copy is what | COMMENT |
| LOW | crates/host-core/src/tools/mod.rs | 561 | } | COMMENT |
| LOW | crates/host-core/src/tools/mod.rs | 601 | direction: Direction::Tail, | COMMENT |
| LOW | crates/host-core/src/tools/mod.rs | 661 | /// permission mode. `inherit` and absent behave identically. | COMMENT |
| LOW | crates/host-core/src/tools/mod.rs | 1081 | /// How long host-core waits for Electron main to answer an approved | COMMENT |
| LOW | crates/host-core/src/plugins/renderer.rs | 1 | //! Renderer-slot declarations: `manifest.renderer` and its two whitelists. | COMMENT |
| LOW | crates/host-core/src/plugins/registry.rs | 21 | /// | COMMENT |
| LOW | crates/host-core/src/plugins/registry.rs | 61 | let _ = mgr.reload_from_disk(); | COMMENT |
| LOW | crates/host-core/src/plugins/device.rs | 1 | //! Stable device identity for the plugin center's download interface. | COMMENT |
| LOW | crates/host-core/src/plugins/resolve.rs | 1 | //! The plugin center's download interface. | COMMENT |
| LOW | crates/host-core/src/plugins/manifest.rs | 21 | #[serde(default, rename = "rendererCallMethods")] | COMMENT |
| LOW | crates/host-core/src/plugins/reviews.rs | 1 | //! Anonymous plugin reviews read from the plugin center. | COMMENT |
| LOW | crates/host-core/src/plugins/progress.rs | 1 | //! Progress an install reports while it runs, and the way a user cancels one. | COMMENT |
| LOW | crates/host-core/src/plugins/install.rs | 701 | )) | COMMENT |
| LOW | crates/host-core/src/plugins/marketplace.rs | 281 | "sourceUrl": self.market_source_url(), | COMMENT |
| LOW | crates/host-core/src/plugins/marketplace.rs | 641 | } | COMMENT |
| LOW | crates/host-core/src/plugins/providers.rs | 521 | }) | COMMENT |
| 60 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | docs/spec/08-meta/decisions-log.md | 2579 | ## 2026-08-24 — Subagents use event-driven idle and duration timeouts | COMMENT |
| MEDIUM | docs/spec/02-architecture/03-repo-structure.md | 43 | │ └── plugin-devkit/ # pi-plugin CLI: scaffold, check, pack, publish | CODE |
| MEDIUM | docs/zh-CN/spec/02-architecture/03-repo-structure.md | 44 | │ └── plugin-devkit/ # pi-plugin CLI:scaffold、check、pack、publish | CODE |
| MEDIUM | examples/plugins/roundtable/main.js | 24 | `## Roundtable orchestration plan`, | CODE |
| MEDIUM | examples/plugins/roundtable/skills/roundtable.md | 71 | ## How the parent agent orchestrates | COMMENT |
| MEDIUM | apps/desktop/electron/main/runtime/sidecar.ts | 658 | // Plugin authoring (D171): scaffold, validate and package a plugin without | COMMENT |
| MEDIUM | apps/desktop/electron/main/ipc/plugin-ipc.ts | 283 | // scaffold only writes files; loading waits for the same review as a folder | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | crates/host-core/src/sessions.rs | 7339 | let filler = "lorem ipsum dolor sit amet ".repeat(60); | CODE |
| LOW | crates/host-core/src/sessions.rs | 7339 | let filler = "lorem ipsum dolor sit amet ".repeat(60); | CODE |
| LOW | packages/i18n/src/locales/de/index.ts | 48 | "placeholder": "pnpm install", | CODE |
| LOW | packages/i18n/src/locales/de/index.ts | 148 | "placeholder": "Plugins nach Name oder Pinyin durchsuchen", | CODE |
| LOW | packages/i18n/src/locales/de/index.ts | 348 | "placeholder": "Bitten Sie PI-Desktop um Hilfe bei allem", | CODE |
| LOW | packages/i18n/src/locales/de/index.ts | 2240 | "placeholder": "Wert eingeben", | CODE |
| LOW | packages/i18n/src/locales/fr/index.ts | 48 | "placeholder": "pnpm install", | CODE |
| LOW | packages/i18n/src/locales/fr/index.ts | 148 | "placeholder": "Rechercher des plugins par nom ou pinyin", | CODE |
| LOW | packages/i18n/src/locales/fr/index.ts | 348 | "placeholder": "Demandez à PI-Desktop de vous aider pour tout", | CODE |
| LOW | packages/i18n/src/locales/fr/index.ts | 2240 | "placeholder": "Saisissez une valeur", | CODE |
| LOW | packages/i18n/src/locales/es/index.ts | 48 | "placeholder": "pnpm install", | CODE |
| LOW | packages/i18n/src/locales/es/index.ts | 148 | "placeholder": "Buscar complementos por nombre o pinyin", | CODE |
| LOW | packages/i18n/src/locales/es/index.ts | 348 | "placeholder": "Pídale ayuda a PI-Desktop con cualquier cosa", | CODE |
| LOW | packages/i18n/src/locales/es/index.ts | 2240 | "placeholder": "Escribe un valor", | CODE |
| LOW | …esktop/resources/plugins/pi.browser/views/browser.html | 207 | input.placeholder = t("placeholder"); | CODE |
| LOW | apps/desktop/electron/main/oauth.ts | 275 | placeholder: "placeholder" in prompt ? prompt.placeholder : undefined, | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | docs/adr/0179-import-model-configuration.md | 65 | Placeholder values (`YOUR_API_KEY`, `${VAR}`) are treated as missing. | CODE |
| HIGH | packages/shared/src/model-config-import.test.ts | 119 | options: { apiKey: "YOUR_API_KEY" }, | CODE |
| HIGH | packages/shared/src/model-config-import.test.ts | 446 | expect(publicModelConfigCandidate(drafts("YOUR_API_KEY")[0]).hasSecret).toBe(false); | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | …sktop/electron/main/remote/pi-host-bootstrap-script.ts | 127 | elif command -v shasum >/dev/null 2>&1; then | CODE |
| HIGH | …sktop/electron/main/remote/pi-host-bootstrap-script.ts | 152 | elif command -v wget >/dev/null 2>&1; then | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | docs/spec/04-ux/07-ui-design-system.md | 35 | ### 3.1 AI-generated page copy | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | crates/host-core/src/plugins/install.rs | 740 | // Prefer curl for robust HTTPS support on developer and CI machines. | COMMENT |
| MEDIUM | apps/desktop/electron/main/bootstrap/window.ts | 1863 | // Destination + theme captures (robust via __PI_DESKTOP__ hooks). | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | apps/desktop/electron/main/mcp-oauth.ts | 221 | // Step 1: Probe endpoint to check for 401 with WWW-Authenticate | COMMENT |
| LOW | apps/desktop/electron/main/mcp-oauth.ts | 256 | // Step 2: Fallback to standard RFC 9728 paths if not in WWW-Authenticate | COMMENT |
| LOW | apps/desktop/electron/main/mcp-oauth.ts | 291 | // Step 3: Fetch Authorization Server Metadata (RFC 8414) | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | apps/desktop/electron/main/mcp-oauth.ts | 221 | // Step 1: Probe endpoint to check for 401 with WWW-Authenticate | COMMENT |
| LOW | apps/desktop/electron/main/mcp-oauth.ts | 256 | // Step 2: Fallback to standard RFC 9728 paths if not in WWW-Authenticate | COMMENT |
| LOW | apps/desktop/electron/main/mcp-oauth.ts | 291 | // Step 3: Fetch Authorization Server Metadata (RFC 8414) | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | scripts/publish-screenshots.py | 20 | CODE | |
| LOW | scripts/make-icon.py | 16 | CODE | |
| LOW | scripts/make-dmg-background.py | 11 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | packages/plugin-devkit/src/templates.ts | 466 | ## How to use | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | scripts/e2e/config-sync-s3-admin.py | 101 | except Exception as error: | CODE |