Skip to content

Releases: TonyDua/dsh-web-search-exa

v0.2.3

Choose a tag to compare

@github-actions github-actions released this 14 Oct 19:58

Two changes make this release. The dsh 0.2.x line stops being declared
compatible and becomes verified: 0.2.3 was run on the current dsh release,
0.2.0-rc.2, and works there. And the plugin gets its configuration page back
on that line, live. Everything below that is incidental.

Added

  • The plugin is configurable from the Web UI again on dsh 0.2.0 and later,
    and a save applies to the next search with no restart.
    0.1.7-alpha.1
    replaced SettingsProvider.installSection with SettingsForms, whose page is
    derived from the Config schema the Loader already holds. From that release the
    plugin had no way to receive an edit — it kept the config it was mounted with,
    and only a remount picked up a change. On 0.2.0+ it was worse than that:
    dsh-settings builds a form with volatileForm(schema), and a schema with no
    volatile field yields undefined, at which point describe() drops the entry
    from Settings entirely and update() throws
    Plugin entry "web-search-exa" has no volatile fields. So 0.2.1 and 0.2.2
    installed cleanly on that line and then offered no page to edit.
    The release that removed the old API added its replacement: from 0.2.0-rc.1
    a Config field declared .volatile() in the schema (schemastery >= 3.18.4)
    reaches apply as a live reference, and the loader commits a saved edit into
    that reference in place. Every field of this plugin's Config — including
    mcpTool — is now declared volatile, so the page is generated and a save
    reaches the next search without restarting dsh web, including switching
    between the anonymous and keyed paths by adding or removing the key. The
    mechanism is the loader's; this package declares the fields and reads through
    the reference.
  • The read side stays version-proof. Fields are read through a structural
    probe (readConfigValue): a plain value passes through, a live reference is
    dereferenced. Older hosts, and direct library use, are unchanged, so one build
    still serves every supported dsh line.

Fixed

  • scripts/compat-matrix.sh could test a tarball from a previous run.
    npm_installs packed into a directory that survives across runs and then
    picked the tarball with ls | head -1, which sorts alphabetically — a
    0.1.6 tarball left over from an earlier run of a different plugin version
    sorted before 0.2.3 and was the one installed, failing strict install only
    beside the one host whose cordis requirement its stale peers could not
    satisfy (0.2.1-alpha.1). The failure read as a real incompatibility; it was
    leftover state. The pack directory is now wiped per call.
  • The REST user-agent no longer reports the wrong version. It stayed
    deepseek-harness-exa/0.1.5 through the 0.2.0–0.2.2 releases, because the
    string was a hand-written literal rather than derived from the package
    version. It is now bumped with every release.

Changed

  • devDependencies target dsh 0.2.0-rc.2 (cordis ~4.0.4), and
    @deepseek-ai/schemastery moved to ^3.18.4, the first version with
    .volatile(). Peer ranges and dsh.compatibility.dshReleases are unchanged
    from 0.2.2.
  • Documentation: the Web panel section is per dsh version, troubleshooting
    names the plugin upgrade that clears the 0.2.x skip warning, and the
    version-differences section describes the volatile mechanism.

Verified

All of it on this base, and on the runtime the release names:

  • On the current dsh release. 0.2.0-rc.2 is what npm tags latest. A real
    dsh 0.2.0-rc.2 process installed this tarball, composed the profile with no
    compatibility warning, and served a headless search through the anonymous
    structured MCP path with no EXA_API_KEY — 9 sources. A providerId set in
    cordis.patch.yml is what the booted process then serves, which is how the
    patch layer was checked; that path is boot-time, see Notes.
  • The 17-version compatibility matrix passes (0.1.2-alpha.2 through
    0.2.1-alpha.1): isolated install, tsc against each host's own
    declarations, the full 30-test suite, and a strict npm install of the real
    tarball beside every host — including 0.2.1-alpha.1, which only passes once
    the stale-tarball defect above is fixed.
  • A live edit on the real loader (cordis-plugin-loader 1.0.5): a
    volatile-only config change committed into the same fiber, with
    loader/volatile-update firing for exactly the changed path, no remount and
    no re-registration, and the next search carrying the new value. An ordinary
    change took the ordinary update path instead.

Notes

  • No peer range, compatibility declaration, or install-time behavior changed.
    This package installs and resolves exactly as 0.2.2 did. What changed is what
    it does once running on 0.2.0+.
  • "Live" means a save made in Settings → Plugins. dsh-config-editor.edit()
    writes the profile patch and reconciles the running loader in the same call,
    which is what carries the new value into the live reference. Editing
    cordis.patch.yml by hand is a separate path: dsh 0.2.0-rc.2 watches no
    patch file, so a hand edit still needs a restart.

v0.2.2

Choose a tag to compare

@github-actions github-actions released this 06 Oct 15:54

Fixed

  • The README was still advertising the old support range. The dsh badge
    hard-coded 0.1.2-alpha.2 – 0.1.7-alpha.1 and was not touched by the 0.2.x
    work, so the first thing a reader sees contradicted the package it describes.
    It now reads 0.1.2-alpha.2 – 0.2.1-alpha.1 and links to the compatibility
    section rather than to the harness repository.
  • The install section dated a claim it had outgrown. It said "v0.1.4 and
    later ship the dsh.bundle manifest", which invites a reader on an older
    release to wonder whether the documented command still applies to them. The
    manifest ships in every published version; the sentence no longer carries a
    version.

Changed

  • dsh.compatibility.dshReleases is now explained where the reader meets it,
    instead of only in a collapsed section. The text states what the key is and
    what it is not: catalog metadata that the dsh runtime never reads and that
    does not affect dependency resolution, present because registries such as DSH
    STORE require an exact per-version record. That distinction was worth making
    explicitly after a peer range that looked like a compatibility claim turned
    out to exclude the entire 0.2.x line.
  • The note separating a version that resolves from one that was tested was
    ambiguous about which number it was comparing; it now names the three
    releases (0.1.7-alpha.2, 0.1.7-rc.1, 0.1.7-rc.2) that account for the
    difference between 20 resolved and 17 tested.

Notes

  • Documentation only. No runtime behavior, manifest field, or peer range
    changed in this release; it exists because the READMEs are part of the
    published tarball, so a documentation fix only reaches dsh plugin add and
    npm users through a release.

v0.2.1

Choose a tag to compare

@github-actions github-actions released this 06 Oct 15:47

Fixed

  • The plugin could not be installed beside any dsh 0.2.x release. The peer
    ranges ended at >=0.1.8, and because a prerelease only satisfies a range
    that carries a prerelease comparator on the same major.minor.patch triple,
    that enumeration excluded the entire 0.2.x line. npm install of the
    published tarball beside 0.2.0-rc.2 failed with ERESOLVE — which is what
    took this package off the DSH STORE listing
    (AI-Scarlett/DSH-Store#1016),
    since the catalog requires an installable result for at least one of the
    official latest three releases. The ranges now end with
    || >=0.2.0-rc.1 || >=0.2.1-alpha.1.
  • @deepseek-ai/cordis had the same defect one line down. >=4.0.2
    excludes 4.0.5-alpha.1, which is what a 0.2.1-alpha.1 host peers, so that
    version failed strict installation even after the dsh ranges were fixed. The
    range is now >=4.0.2 || >=4.0.5-alpha.1.
  • scripts/compat-matrix.sh pinned cordis wrongly, in a way that hid the
    real problem.
    It hard-coded 4.0.3 for the whole 0.2.* line, which is
    wrong for 0.2.0-rc.2 (~4.0.4) and wrong again for 0.2.1-alpha.1
    (~4.0.5-alpha.1); the resulting npm conflict came from the harness's own
    graph but surfaced as an install failure next to this plugin, reading like our
    bug. The range is now read from each version's published manifest and its
    floor pinned as a concrete version. Pinning the range itself — the obvious
    first fix — is broken, which is how that mistake was caught: on the 0.1.5
    line ^4.0.2 resolves to 4.0.4, the plugin then fails to install strictly,
    and four versions went red. Passing cordis through nowhere at all fails the
    other way, because tsc needs it resolvable at the top level while the
    harness's own tree nests it. The 0.2.x line is in the version list now, so
    the gap that caused this cannot silently reopen.

Added

  • dsh.compatibility.dshReleases in package.json, declaring
    0.2.0-rc.1, 0.2.0-rc.2, and 0.2.1-alpha.1 as compatible. A catalog
    requires a precise per-version record; a peer range is not installable
    evidence. Each declared version was verified by installing the real tarball
    with npm under strict peer resolution beside that host and then running a live
    keyless search through the registered provider.

Notes

  • The || in these ranges picks the highest lower bound rather than widening
    the range, because every comparator is open-ended >=. Appending
    || >=0.2.0-rc.1 to a range ending in >=0.1.8 silently drops 0.1.8
    through 0.2.0-rc.1. Both READMEs now say so, with the measured numbers: the
    shipped enumeration resolves on all 20 published releases from
    0.1.2-alpha.2 to 0.2.1-alpha.1.
  • No runtime behavior changed in this release.

v0.1.5

Choose a tag to compare

@github-actions github-actions released this 23 Sep 07:21

Fixed

  • The peer range now actually installs on every claimed version. The earlier
    >=0.1.2-rc.1 was verified with pnpm, where it works, and assumed to work
    everywhere. Measured with npm against the real tarball it installs on 1 of
    14
    versions and fails the other 13 with ERESOLVE. The cause is the
    pre-release rule: a prerelease satisfies a range only when some comparator
    carries a prerelease on the same major.minor.patch tuple, so
    >=0.1.2-rc.1 excludes 0.1.5-rc.2. Each 0.1.x line that shipped a
    prerelease now gets its own comparator, ending with >=0.1.8 to carry future
    stable releases. Result: 14/14 under both npm and pnpm. A future 0.1.9
    prerelease line needs one added entry.
  • Runs on dsh 0.1.7+. 0.1.7-alpha.1 removed
    SettingsProvider.installSection and replaced the service with
    SettingsForms, which derives a page from the Config schema the Loader
    already holds. The old unconditional call threw a TypeError there — the
    plugin loaded but failed. installSettingsSection() now describes the service
    structurally, calls installSection only when it is a function, and
    otherwise returns false; provider registration was already outside that
    branch and stays unconditional.
  • id no longer freezes at construction. It was assigned once in the
    constructor, so a live Settings change to providerId left the provider
    reporting a stale id. It is now read per access.
  • The keyless channel now reports its own health. A new
    ExaAvailabilityBreaker opens after 3 consecutive transient failures
    (5xx/429/network/parse) for a 5-minute cooldown, during which
    available() returns false — previously it returned true unconditionally, so
    a throttled public endpoint produced a hard error on every search with no way
    for the seam to route around it. One successful search closes the breaker.
    A 4xx other than 429 deliberately does not trip it: that failure would repeat
    forever, and hiding it behind a cooldown only delays the same error.
  • 429 is no longer indistinguishable from a network failure. The anonymous
    path throws ExaRateLimitError with code WEB_RATE_LIMITED and a message
    naming EXA_API_KEY, instead of a generic WEB_PROVIDER_ERROR, so the model
    can tell throttling from breakage. The keyed REST path is unaffected by the
    breaker — a paid endpoint's failure is the caller's to see.

Added

  • TypeScript source tree (src/) — the implementation is now real source
    rather than only a committed compile artifact: constants.ts, types.ts,
    provider.ts, and index.ts, carrying the JSDoc the bundle used to hold.
  • Build toolchain matching the harness's own packages: tsdown bundles
    src/index.ts to lib/index.js and rolls the declarations into
    lib/index.d.ts; tsc --noEmit gates types.
  • pnpm run build, pnpm run typecheck, pnpm run test:only, and a
    prepublishOnly build hook so the tarball cannot ship stale artifacts.
  • 6 regression tests covering the three fixes above (the frozen-id test was
    confirmed to fail against the previous build).
  • Cross-version compatibility matrix (scripts/compat-matrix.sh, pnpm run compat): installs every published dsh version in isolation and typechecks +
    tests the plugin against each one's own declarations. Wired into CI as a
    separate job. This is the evidence behind the README's compatibility table
    rather than a hand-written claim.
  • 3 regression tests pinning the settings-generation behaviour: the 0.1.7 shape
    is tolerated, apply still registers the provider on it, and the older API
    still adopts live Settings edits.

Audit findings (no code change needed)

  • The ctx.web seam is byte-stable across all 14 published versions:
    WebError is exported from dsh-web and extends HarnessError in every one,
    launchEnvironmentOf is always present, and ctx.settings is always mounted.
  • 0.1.7-alpha.1 peers @deepseek-ai/cordis ^4.0.3 while the cordis latest
    dist-tag still points at 4.0.2; 4.0.3 is published and resolves it.

Changed

  • Peer ranges are no longer pinned to a single prerelease. @deepseek-ai/cordis
    is >=4.0.2, and each dsh package now enumerates one comparator per released
    line (>=0.1.2-alpha.2 || >=0.1.3-alpha.2 || … || >=0.1.8) because semver
    excludes pre-release versions from ordinary ranges: ^0.1.2-rc.1 did not
    match 0.1.5-rc.2, so every install on the 0.1.5 line reported missing peers
    even though the plugin worked. 0.1.2-alpha.2 remains the oldest tested
    baseline.
  • @deepseek-ai/dsh-settings is now declared an optional peer
    (peerDependenciesMeta): the provider registers whether or not a settings
    service is mounted, so a keyless profile without the Settings UI is supported.
  • engines.node raised to >=22.19.0, matching the harness.
  • Declarations are generated, not hand-written. The former
    lib/types/index.d.ts was maintained by hand next to the bundle and could
    drift from it; types now come from src/ and land in lib/index.d.ts.
  • README gains a supported-version matrix, the profile peerDependencyRules
    recipe that silences host-provided peer warnings, and source-build steps.

Verified

  • 14/14 node:test cases pass against the rebuilt artifact on dsh 0.1.5-rc.2.
  • End-to-end: dsh --profile headless searched through the anonymous MCP path
    with no API key in the environment, both before and after the rebuild.

Known limitation

  • The plugin can now report that it is degraded, but the harness seam has no
    provider priority chain: it selects exactly one usable provider and errors
    (WEB_PROVIDER_AMBIGUOUS) when several are usable. So this makes failover
    possible, not automatic — see the README note on unpinning searchProvider.