* feat(release): publish package source, declaration maps, and documentation Every release member publishes its TypeScript source and the declaration maps that resolve into it, and @deepseek-ai/dsh publishes the repository Markdown documentation staged from docs/ at prepack time. The ./src/* export most members already declared now resolves for an installed consumer, and a consumer editor follows a declaration to the implementation. Bundled JavaScript maps stay unpublished; the vendored family and the Desktop runtime file policy are unchanged. Rationale: .agents/notes/implemented/process/2026-10-08-published-source-and-docs.md * feat(release): publish JavaScript maps and compress bundles Every emitted JavaScript map ships beside the bundle it describes, and the workspace build and the client preset compress bundles without mangling identifiers. The documentation payload now mirrors the website publication manifest and is removed again by `postpack`; Desktop and the Python executable exclude the published source, documentation, and maps; `clean` removes a staged copy. Typert's publication contract gains the Remote declaration map. * fix(release): keep node bundles readable for the worker image The browser worker image lowers `yield*` only as a whole statement and rewrites `for await` loops by their source layout, so compressed node-side entries either fail that lowering or lower to unparseable code. Only the browser bundles keep compression, which removes about a third of their text. The bundle-purity assertion now matches the module-loader call regardless of the quote style compression picks, and the release-pack fixture exercises the installed package's new documentation requirement. * feat(release): publish the whole documentation tree `@deepseek-ai/dsh` copies `docs/` in full instead of the website's page set: the maintainer documents, the generated migration records, the translation guidelines, and the `*.i18n.yaml` consistency records ship with the installed package, so the documentation's own links resolve without a checkout. * feat(release): publish the upgrade guides with the documentation The staged documentation keeps the website's page set and adds every `docs/upgrade-guide/` document, which is what an installed reader consults when a released change breaks something. The rest of the maintainer tree stays out. * test(release): expect source and maps in master's new payload cases * feat(release): keep installed docs and source readable in Desktop Desktop keeps the published src/ and docs/ trees inside app.asar, and every model shell call receives DSH_INSTALL_DIR and DSH_NODE_EXECUTABLE so an agent can read them through Electron's Node mode. Staging also generates docs/upgrade-guide/README.md, an index of the upgrade guides grouped by the release they upgrade from. Minified client bundles print string literals with backticks: the worker image packer now recognizes those chunk requests, client license banners are prepended after minification so their text survives, and the affected artifact tests accept either quote. * test(desktop): read archived docs through the Windows PowerShell form Regenerate the config catalog for the shifted shell-env source line. * test(desktop): wait for the GUI-subsystem Electron process from PowerShell * build(release): publish source and maps from the message-quotes package * build(release): publish source and maps from packages new on master * build(release): publish source and maps from the tool-office package
description, kind
| description | kind |
|---|---|
| Register code host providers and poll change request status through one provider-neutral service. | package-reference |
@deepseek-ai/dsh-experimental-forge
English | 中文
Summary
Read and act on pull requests and merge requests without coupling consumers to one code host. A provider maps remote and change request URLs to provider-neutral references, finds change requests by head branch, reads their status in batches, reads their diffs and files, and marks drafts ready or merges on request. Watchers of one change request share a single polling loop whose cadence follows check, mergeability, and lifecycle state.
Table of Contents
- Use this package
- Understand the implementation
- Further Exploration
- Model Experience
- Known Limitations and Deferred Work
- Dev Note
Use this package
Mount the registry with at least one provider package, such as the GitHub provider.
- name: '@deepseek-ai/dsh-experimental-forge'
- name: '@deepseek-ai/dsh-experimental-forge-github'
ctx.forge.register(provider) is an effect on the calling fiber and returns an async disposer that cancels and drains that registration's calls. Results arriving after cancellation are discarded. One provider serves one forge family; registering a second provider for the same family throws. Registration changes announce forge/providers-changed; registering a provider polls its existing watches immediately. repositoryFromRemote(url) and changeRequestFromUrl(url) ask providers in registration order and return the first match. changeRequestUrl(ref), findByHead(repository, branch, signal), and readiness(repository, signal) delegate to the provider of the reference's forge and throw when none is registered; readiness reports whether the provider can reach the host with current credentials.
markReady(ref, signal) marks a draft ready for review, and merge(ref, { method, headSha }, signal) merges a change request only while its head is still headSha. Both delegate to the provider of the reference's forge, throw when none is registered, and resolve to undefined once the host accepted the change or to a ForgeActionFailure: unauthenticated, stale when the head moved past headSha, or failed with the host's reason. After either settles, a watched change request is polled at once. Snapshots carry mergeReady, whether the host would merge the change request now for the signed-in user, and mergeMethods, the methods the repository accepts with that user's usual one first.
diff(ref, signal) reads the change request's unified patch as the host computes it, with a/ and b/ path prefixes, and fileText(ref, commit, path, signal) reads one file of its repository at a commit. Both delegate to the provider of the reference's forge, throw when none is registered, and resolve to the text or to a ForgeFailure, which is too-large when the host or the provider refuses an answer over its size limit. fileUrl(ref, commit, path) returns the web page of that file at that commit.
fetchChecks(ref, signal) reads one change request’s complete checks on demand. It has its own fetchTimeoutMs deadline and does not occupy the polling batch or publish to its watchers. Failure leaves previously polled snapshots intact. A provider without fetchChecks returns unavailable. Caller cancellation and provider or service disposal abort the read; disposal waits for it to settle.
ctx.forge.watch(ref, listener) is also an effect. The first watcher of a change request polls it at once; latest(ref) returns the most recent result. Each forge has at most one polling fetch in flight, and that fetch includes every due change request of the forge. An open change request is polled every activeIntervalMs while checks are pending or mergeability is unknown, and every idleIntervalMs otherwise. Closed change requests use idleIntervalMs to detect reopening; merged requests stop automatic polling. refresh(ref) polls a watched change request at once, including after a terminal state; if a fetch is already in flight for its forge, another fetch starts immediately after it settles. A failed read repeats after activeIntervalMs doubled for each consecutive failure, up to maxBackoffMs, which must be at least activeIntervalMs. Unregistering a provider settles its watched change requests as unavailable. Polling stops when the last watcher leaves. The configuration catalog lists the defaults.
Reaching fetchTimeoutMs aborts the fetch signal with FORGE_FETCH_TIMEOUT. Providers must stop their work and settle when the signal aborts; rejected fetches become unavailable failures. A provider that ignores cancellation can stall polling and service disposal.
Providers may implement submitReview to publish a line comment or a completed review at an explicit head commit. The registry returns unsupported when that capability is absent and refreshes watched status after a submission. Successful writes return their web URL; failures distinguish changed heads, refusals, and unknown outcomes. Callers must reconcile unknown outcomes before another submission. Pending drafts belong to the consumer, not the polling registry.
Understand the implementation
Implementation internals — click to expand
One timer covers all watched change requests. When it fires, the service groups due change requests by forge and starts one batched provider fetch per idle forge. A listener that throws is logged and skipped. Disposing the service aborts in-flight fetches and waits for them to settle.
| Source | Responsibility |
|---|---|
src/index.ts |
Provider registration, URL mapping, watch lifetime, and batched polling |
src/schedule.ts |
Delay before the next poll of one change request |
src/keys.ts |
Case-insensitive canonical identity of a change request |
src/types.ts |
Repository, change request, status, and provider types |
Further Exploration
- Forge subsystem — provider contract, change request types, and service reference.
- GitHub provider — the provider for GitHub hosts.
- Session bindings — the consumer that binds change requests to Sessions.
- Binding decision — why bindings derive from shell results and status stays on the host.
Model Experience
None, as providers and watchers exchange code host status without contributing model context.
KV Cache effect
None. No model request contains data from this package.
Known Limitations and Deferred Work
- Polling only — status reaches watchers on the next scheduled poll or
refresh; there is no webhook intake. - Process-local results — latest results live in memory and are lost on restart; the next watcher polls again.
Dev Note
Working context for maintainers — click to expand
None.