fix(host): address ds-review-bot v7 on the adaptive picker chooser

- resolve.ts: gate the display branch on linux (the native backend drives
  exactly darwin/win32/linux) and require a zenity/kdialog binary on PATH,
  probed once at boot (new probe.ts, injected predicate for tests); type
  bindHost as the webserver schema's closed union.
- index.ts: the disposer now joins the removed entry's fiber teardown so
  unloading the chooser settles only after the backend quiesced; export
  BACKEND_PACKAGES as the runtime-string source of truth.
- verify-cordis-config: a composition mounting -auto must declare both
  backends as dependencies (negative-tested), since keyless Linux CI only
  ever resolves browse and would hide a dropped -native dep.
- apps/web scaffold: pin -browse via disable+insert (goldens are
  interaction-specific); fix the stale workspace-flow comment.
- docs/module-graph.md regenerated; README + Agent Note document the
  ssh -L shape, the PATH-only probe, and the new gate (zh pairs re-paired).
- composition spec: assert teardown quiescence without a loader await,
  cover external entry removal, and await the loader's self-dispose
  disabled-persist so it cannot race temp-dir teardown.
This commit is contained in:
creatixchu
2026-07-29 21:09:02 +08:00
parent 8cec74748b
commit f0f897ef02
15 changed files with 253 additions and 53 deletions

View File

@@ -30,6 +30,20 @@ interface PluginReference {
const root = resolve(import.meta.dirname, '..')
const metadataFields = ['id', 'name', 'group', 'disabled', 'inject', 'intercept', 'isolate'] as const
/** The adaptive directory-picker chooser package (mounts a backend row at boot). */
const CHOOSER_PACKAGE = '@deepseek-ai/dsh-host-directory-picker-auto'
/**
* The backends the chooser mounts by runtime string (mirror of its exported
* `BACKEND_PACKAGES`), invisible to yml-row scanning: a composition mounting
* the chooser must resolve both, or keyless Linux CI (which only ever
* resolves `browse`) hides a dropped `-native` dependency until a macOS boot.
*/
const CHOOSER_BACKEND_PACKAGES = [
'@deepseek-ai/dsh-host-directory-picker-native',
'@deepseek-ai/dsh-host-directory-picker-browse',
]
const jsExprType = new yaml.Type('tag:yaml.org,2002:js', {
kind: 'scalar',
resolve: data => typeof data === 'string',
@@ -134,12 +148,18 @@ function missingPluginDependencies(
manifestPath: string,
): string[] {
const requiredPackages = new Map<string, Set<string>>()
const require = (packageName: string, file: string): void => {
const locations = requiredPackages.get(packageName) ?? new Set<string>()
locations.add(file)
requiredPackages.set(packageName, locations)
}
for (const reference of references) {
const packageName = packageNameFromSpecifier(reference.name)
if (packageName === undefined) continue
const locations = requiredPackages.get(packageName) ?? new Set<string>()
locations.add(reference.file)
requiredPackages.set(packageName, locations)
require(packageName, reference.file)
if (packageName === CHOOSER_PACKAGE) {
for (const backend of CHOOSER_BACKEND_PACKAGES) require(backend, reference.file)
}
}
return [...requiredPackages].flatMap(([packageName, locations]) => packageName in dependencies
? []