Commit graph

5 commits

Author SHA1 Message Date
wujunchen
5f36b1218b feat: provider/lifecycle robustness, onboarding nudge, CI coverage gate
Assessment-driven batch of 10 verified, low-risk improvements. All gates green
(typecheck, biome, obsidian lint + strict review, 28 test files, branch
coverage 100%, e2e gate).

Correctness:
- provider-request: decide structured-output fallback on HTTP status via a new
  ProviderApiError (status+body) instead of pattern-matching the i18n-translated
  message — previously only en/zh matched, so fr/de/es/ja/ko users hit silent
  permanent failures when a provider rejected json_schema.
- streaming: surface in-stream provider error payloads ({type:'error'} /
  {error:{}}) by throwing, instead of swallowing them and later misreporting a
  transient overload/quota error as "non-JSON LLM output". Note: detection runs
  outside the JSON.parse try/catch so the throw is not swallowed.
- main: throwIfCancelled before cacheManager.put so a cancelled job cannot
  poison the cache.
- generation-job-manager: add cancelAll(); onunload now cancels in-flight jobs
  (aborting streaming HTTP + SIGKILL-ing CLI children), not just queued waiters.

Onboarding / UX:
- settings: DEFAULT_SETTINGS.promptLanguage 'zh' -> 'auto' so new non-Chinese
  users get source-language summaries by default (existing users unaffected).
- view/main/types: first-run "Set up AI provider" CTA in the empty state when no
  credential is configured (PluginHost.openSettings + isCredentialConfigured).
- error-ui/generation-job-manager/types: new 'network' ErrorKind with an
  actionable notice + Retry for offline/connection failures.
- i18n-strings: 4 new keys across all 7 locales (parity test enforced).

CI / docs:
- .c8rc.json + package.json: branch-coverage gate (check-coverage, branches=100,
  degenerate metrics disabled) and preserve c8's exit code in the coverage script.
- ci.yml: run coverage gate and strict obsidian review in CI.
- README: fix Obsidian version badge 1.4.0 -> 1.8.7 (matches manifest).
- e2e product-shell DOM shim: add createSpan (was missing; real Obsidian has it).

Tests: cover the status-based fallback (incl. non-English locale), in-stream
error throwing, cancelAll, and network classification.

Change-Id: Ic619098aa7cdf3dc1c444be4bb8a445550eadf55
2026-06-16 09:37:59 +08:00
wujunchen
de66de5b5c refactor: remove dead code and over-broad exports
- Delete unused CacheFile interface (src/types.ts)
- Demote internal-only symbols from export to module scope:
  PROMPT_VERSION, DEFAULT_CLI_TIMEOUT_MS, MIN_STREAMING_TIMEOUT_MS,
  MIN_CLI_TIMEOUT_MS (settings.ts), CliFailureReason (cli.ts),
  GenerationErrorContext (error-ui.ts), AnthropicMessagesBody/
  OpenAiChatBody/OpenAiResponsesBody/GeminiBody (provider-bodies.ts),
  BackendTestDeps (backend-test.ts)

Verified: tsc, esbuild prod build, biome, all 28 test files pass.
Change-Id: I0fc597ee51ec67d509a7f33db39fabcbdb301797
2026-05-16 00:15:10 +08:00
wujunchen
04428950de chore: prepare 1.0.19 release
Change-Id: I86c01c3d6a2c13a193636ac08ba562d54a2e9a20
2026-05-09 10:48:36 +08:00
wujunchen
07faeddab5 fix Obsidian plugin review scan
Change-Id: I43416145eca8ee04468522c350fdcebeb772ab6e
2026-05-08 22:57:31 +08:00
fancivez
d738fc120a feat(error-ui): structured CliProcessError + ErrorKind-driven UI dispatch
Replaces the single long-Notice failure UX with a kind-aware dispatcher
so users get actionable buttons instead of a wall of text.

- CliProcessError extends Error with a typed CliErrorDetails payload
  (reason / pid / elapsed / idle / bytes / tails / exitCode / signal /
  timeoutMs / idleTimeoutMs). All five runCli failure paths now throw
  the typed error; message format is preserved so existing classifier
  regex and tests still match.
- classifyGenerationError short-circuits on details.reason for the
  deterministic cases (wall/idle-timeout → timeout, spawn/startup →
  config, streams-unavailable → unknown). exit-nonzero falls through
  so stderr-derived auth/rate-limit hints still classify correctly.
  Duck-typed check avoids cli ↔ generation-job-manager circular import.
- New error-ui.ts dispatches by ErrorKind:
    timeout (with details) → TimeoutDiagnosticsModal showing cmd, pid,
      elapsed, idle, bytes, redacted stderr/stdout tail, plus copy /
      open-settings / close buttons.
    timeout (no details, e.g. API streaming) → actionable Notice.
    auth/config → Notice + "Open Settings" CTA.
    rate-limit → Notice + "Copy details".
    schema → Notice + "Copy raw output" CTA.
    unknown → unchanged legacy short Notice.
- main.ts handleGenerationError delegates to dispatcher; new
  openPluginSettings() helper uses Obsidian's app.setting.openTabById.
- 21 i18n strings (zh + en) for all new UI labels and the modal copy.
- styles.css adds error notice + diagnostics modal styling.
- 7 new test assertions cover typed details on every failure path and
  classifyGenerationError respecting structured reasons.

Change-Id: I8af46d375d92ba26d14180ffbeb6c3a6dedd89f5
2026-05-05 20:19:57 +08:00