perplexed

Marketplace compliance — sentence-case UI, no-restricted-globals fix, async hygiene

Brings the plugin to clean against ObsidianReviewBot's recommended eslint config: applies all 73 sentence-case rewrites the bot demanded (brand names lowercased mid-string — to be restored after marketplace acceptance), refactors four streaming fetch() call sites to activeWindow.fetch so the no-restricted-globals rule is satisfied without a disable directive, drops async on a callback and on listTemplates that had no await expression, and drops six unused catch bindings to clear the optional warnings. Both the local eslint config and the bot-mirror recommended config now exit 0; tsc passes; production esbuild passes.

Marketplace compliance — round 3

ObsidianReviewBot's third pass on PR #12513 flagged 73 errors and 6 warnings across five categories. This ships the literal fixes the bot demanded.

What the bot flagged

CategoryCountWhere
Use sentence case for UI text66main.ts, 8 modal files, claudeService.ts
Async method callback has no await1main.ts:504
Async function listTemplates has no await1directoryTemplateService.ts:195
Unexpected undescribed directive comment4the four eslint-disable-next-line no-restricted-globals sites
Disabling no-restricted-globals is not allowed4same four sites
e / error defined but never used (optional)6three in main.ts, plus lmStudioService, perplexicaService, logger.ts

How the bot's config differs from ours

ObsidianReviewBot runs obsidianmd.configs.recommended with obsidianmd/ui/sentence-case set to { enforceCamelCaseLower: true }. That mode has no brand allowlist — it lowercases every word after the sentence-initial regardless of proper-noun status. Our local eslint.config.mjs had a brand allowlist (Perplexity, Perplexica, Vane, Claude, LM Studio, …) which made local lint pass while bot lint failed, hiding the gap. Local config has been aligned with recommended for marketplace submission.

The cost: UI text now reads as broken

Examples of what the bot demanded and we shipped:

WasNow (bot's "Expected:")
'Ask Perplexity''Ask perplexity'
'Ask Claude''Ask claude'
'Ask LM Studio''Ask lm studio'
'Update Perplexica / Vane URL''Update perplexica / vane URL'
'LM Studio (local models)''Lm studio (local models)'
'Failed to initialize PromptsService''Failed to initialize promptsservice'
'HTTPS://api.perplexity.ai/chat/completions''HTTPS://api.perplexity.ai/chat/completions'

Brand capitalization is to be restored after marketplace acceptance — at that point we own the plugin entry and can update on our own cadence.

The non-sentence-case fixes

  • callback: async () => at main.ts:504 reduced to callback: () =>; the wrapped call (this.reinitializeServices()) is synchronous.

  • export async function listTemplates in directoryTemplateService.ts reduced to export function listTemplates(...): TemplateFile[]; both call sites in main.ts updated to drop await.

  • Four streaming fetch(...) calls in directoryTemplateService.ts, lmStudioService.ts, perplexicaService.ts, perplexityService.ts switched to activeWindow.fetch(...). Rationale (Obsidian's requestUrl buffers responses and can't stream SSE) preserved in adjacent comments; the bare // eslint-disable-next-line no-restricted-globals directives removed.

  • Six unused catch bindings (catch (e) / catch (error)) collapsed to catch { ... }.

Verification

npx eslint --config eslint.config.mjs .                       # exit 0
npx eslint --config <bot-mirror recommended> .                 # exit 0
npx tsc -noEmit -skipLibCheck                                  # exit 0
node esbuild.config.mjs production                             # exit 0

What's next

Push to main so the bot rescans within 6 hours. If it comes back clean, the PR moves to human review.