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
|
||
|---|---|---|
| .. | ||
| cases | ||
| scripts | ||
| config.yaml | ||
| gate.sh | ||
| hook.sh | ||
| README.md | ||
| run.sh | ||
E2E Contract
This repository uses .e2e/run.sh as the project-local runtime entry point.
The runner clears stale artifacts, executes the release-grade test pipeline
(build → typecheck → unit/component/contract category suites → headless
product-shell smoke → optional live smoke), records logs under
.e2e/results/, and writes .e2e/artifact.json in CTRF format with one entry
per real evidence source.
Run the host-neutral gate with:
npm run e2e
The gate is self-contained in this repository. It does not depend on local agent skills or an external validator checkout.
Generated artifacts under .e2e/artifact.json and .e2e/results/ are runtime
evidence and are intentionally ignored by git.
Test Categories
The source of truth for ordinary test classification is tests/catalog.json.
unit: pure logic tests with no Obsidian runtime, filesystem, process, or provider boundary.component: plugin components exercised with controlled adapters, job managers, or Obsidian shims.contract: provider protocols, CLI command shapes, exported test surfaces, and architecture invariants.e2e: default project-local product-shell smoke. It installs the built plugin package into a disposable Vault filesystem and boots the packagedmain.jsagainst a recording Obsidian API shim. This checks package/install/lifecycle boundaries, but it is not a full Obsidian GUI run.live: opt-in check against a real local Vault install. It verifies plugin files under.obsidian/plugins/parallel-reader/and does not launch Obsidian, call a provider, or run GUI interactions. Run withTEST_LIVE=1and setOBSIDIAN_VAULT_PATHwhen the default iCloud Vault path is not the target.
Useful commands:
npm run e2e
npm run test:unit
npm run test:component
npm run test:contract
npm run test:e2e
TEST_LIVE=1 npm run test:live
The .e2e gate emits one CTRF entry per real evidence source so risk-tag
coverage maps to actual runs:
| Entry | Risk tags |
|---|---|
build and typecheck |
boundary_io, wiring, regression |
unit category |
regression |
component category |
data_integrity, wiring, resource_lifecycle, regression |
contract category |
contract, wiring, regression |
headless product-shell e2e smoke |
boundary_io, wiring, resource_lifecycle, regression |
live Vault install smoke (skipped unless TEST_LIVE=1) |
boundary_io, contract, regression |
npm test remains a developer-facing convenience that runs the same build,
typecheck, and category suites without the e2e/live legs.