Master unifies every live agent with its exact SessionId and moves declarative startup failures to agent-loop/config-start-failed. Keeping the branch’s AgentId label binding would let the TUI target the wrong lifecycle after reload and would miss asynchronous resume failures.
Resolve that contract migration by giving the selected terminal front door the same generated or resumed SessionId as agent-core, mounting the front door first, and entering fullscreen only after the matching root appears. Refresh the source-derived catalogs and keyless terminal goldens so Code Mode, workflow, Cordis-tool, and transient UI scenarios all exercise the merged identity model.
Regenerate docs/config-catalog.md for the telemetry package, unwrap the
design doc's multi-line blockquote paragraphs, and stop exporting the
create-sdk headless spec internals that have no external consumer.
Wrap runDshSdkCommand so each command times itself and, in a finally block,
resolves consent (option A) and sends one best-effort, fire-and-forget telemetry
event (redacted cordis.yml + package.json content; never reads .env). Never
affects the command's exit code. Adds dsh-scripts -> dsh-telemetry dependency.
Default-on via absent consent entry; opt-out by a disabled telemetry entry.
The config/create wizard opt-out toggle is deferred (see design doc).
External-plugin creation will add a package-manager-native dependency
(github:owner/repo#ref or pkg@version) plus a cordis mount instead of fetching
tarballs into a temp dir, so the giget/pacote fetch package is no longer needed.
Add @deepseek-ai/dsh-telemetry, a launcher-side (non-plugin) library for the
ConsentResolver (parses cordis.yml consent + DO_NOT_TRACK/CI), buildTelemetryPayload
(redacted cordis.yml + package.json full content, never .env), getOrCreateAnonymousId
(random UUID in a per-machine global config file), and TelemetryReporter
(fire-and-forget, never blocks or crashes the command).
Endpoint is a fixed .invalid placeholder pending the real endpoint. Launcher
dispatch wiring and the helper feature-catalog entry are intentionally out of
scope. Registers the package in tsconfig references, the module graph, and the
README model-experience audit map. Per-file 100% coverage.
Greenfield #2 "建插件" modules for the forthcoming `dsh-sdk create <source>`
command, in a new foundation-independent package so it touches none of the
dsh-scripts / dsh-helper / create-sdk hotspots the foundation refactor edits.
- `resolvePluginSource(spec)` parses `owner/repo[/subdir]#ref` (github) or
`pkg@version` (npm) into a `PluginSource` discriminated union, failing loud on
an ambiguous or malformed spec.
- `PluginFetcher<S>` seam + `fetchPlugin` tag dispatch returning a common
`FetchedPlugin` (temp dir + immutable provenance).
- `GigetFetcher` (github) over @bluwy/giget-core: resolve `#ref` to a commit SHA
first, download that SHA; provenance pins the SHA. Chosen over unjs/giget for
its single runtime dep and absent install/action surface.
- `PacoteFetcher` (npm) over pacote: resolve the manifest, then extract the
tarball verified against its registry integrity. Registry-only is enforced by
the source resolver; extract runs no lifecycle scripts.
- Branded `CommitSha`/`Integrity`; network + temp-dir boundaries are injected so
the logic is unit-tested at 100% per-file coverage without network.
Wiring (package.json pin, cordis.yml via ProjectEditSession with a confirmed
diff, install --ignore-scripts) and the launcher command registration land
later with the foundation.