dshmarket 1.66.43 → 1.66.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/client/client.js CHANGED
@@ -1993,8 +1993,9 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
1993
1993
  }
1994
1994
  /** Heuristic: plugins that target a terminal surface rather than the web UI. */
1995
1995
  function looksTerminal(plugin, lang) {
1996
+ if (/\b(tui|cli|tty|terminal)\b|终端|命令行/i.test(plugin.name)) return true;
1996
1997
  const positiveDesc = (plugin.description && (plugin.description[lang] || plugin.description.en) || "").replace(/\b(?:no|without)\b[^.!?;:,。!?;\n]{0,80}\b(?:tui|cli|tty|terminal)\b/gi, "").replace(/(?:无需|无须|不需要|不用)[^。!?;\n]{0,48}(?:tui|cli|tty|terminal|终端|命令行)/gi, "");
1997
- return /\b(tui|cli|tty|terminal)\b|终端|命令行/i.test(plugin.name + " " + positiveDesc);
1998
+ return /\b(?:terminal|cli)[ -]only\b|\btui (?:app|plugin|client)\b|\bterminal (?:ui|app|plugin|client)\b|\bcommand[- ]line (?:tool|interface|app|client|plugin)\b|命令行(?:工具|插件|应用|界面|客户端)|终端(?:工具|插件|应用|界面|客户端)|只在终端|仅在终端|需要(?:一个)?终端|在终端(?:里|中)运行/i.test(positiveDesc);
1998
1999
  }
1999
2000
  /** Days per TimeRange (`all` has no cutoff and is handled by the caller). */
2000
2001
  const TIME_RANGE_DAYS = {
package/lib/routes.js CHANGED
@@ -1855,6 +1855,12 @@ export function mountMarketRoutes(host, config, commandRuntime, agentsLookup, ho
1855
1855
  version,
1856
1856
  requirement: verdict.requirement,
1857
1857
  hostVersion: host?.version ?? null,
1858
+ // #923: the client's "find a compatible version" search is keyed by
1859
+ // the npm name, and the install branch could fall back to the catalog
1860
+ // entry's `npm` while the update branch had nothing. The value is
1861
+ // already here — it is this function's first argument and the key the
1862
+ // registry lookup above used — so publish it.
1863
+ npmName,
1858
1864
  },
1859
1865
  error: nothingWasInstalled
1860
1866
  ? `${displayName} ${version ?? ''} 要求的 DSH 版本是 ${verdict.requirement ?? '未知'},而当前运行的是 ${host?.version ?? '未知版本'},装上多半会直接报错。已停止,没有安装任何东西。 / ${displayName} ${version ?? ''} declares it needs DSH ${verdict.requirement ?? '(unknown)'}, and this host is ${host?.version ?? 'unknown'}; installing it would most likely break the plugin. Nothing was installed.`
@@ -4478,6 +4484,12 @@ export function mountMarketRoutes(host, config, commandRuntime, agentsLookup, ho
4478
4484
  if (pinnedForIdentification) {
4479
4485
  declareProfileDependency(config.profile, name, pinValue, activeProfileDir);
4480
4486
  }
4487
+ // #928: an update is remove-then-add, and a host killed between
4488
+ // the two leaves a package that is simply gone — with no record
4489
+ // of what was being attempted, because the completion log never
4490
+ // runs. Write the intent first, so the log can answer "where did
4491
+ // my plugin go" after the fact.
4492
+ logEvent('info', 'update-start', `${name} -> ${target} (profile ${config.profile})`);
4481
4493
  const result = await runPlugin(config.profile, addArgs);
4482
4494
  const cancelled = result.cancelled;
4483
4495
  // The pin above is the market's own write, so it is undone whenever
@@ -5745,6 +5757,10 @@ export function mountMarketRoutes(host, config, commandRuntime, agentsLookup, ho
5745
5757
  // it is meant to clean up after, and the rows outlive the package
5746
5758
  // as boot-time orphans (#799).
5747
5759
  const ownedRows = rowIdsForPackage(host, activeProfileDir, name);
5760
+ // #928: the same intent record as the update path — an uninstall
5761
+ // interrupted mid-remove leaves the same "where did it go" with no
5762
+ // entry saying what was running.
5763
+ logEvent('info', 'uninstall-start', `${name} (profile ${config.profile})`);
5748
5764
  const result = await runPlugin(config.profile, ['remove', name]);
5749
5765
  const cancelled = result.cancelled;
5750
5766
  const ok = result.exitCode === 0 && !result.timedOut && !cancelled;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dshmarket",
3
3
  "description": "Visual plugin market inside DeepSeek Harness — browse, search, and one-click install community plugins. · DSH 可视化插件市场:逛一逛,点一下,装好。",
4
- "version": "1.66.43",
4
+ "version": "1.66.44",
5
5
  "icon": "assets/logo.svg",
6
6
  "type": "module",
7
7
  "main": "lib/index.js",
@@ -430,15 +430,21 @@ export function readSession(key: string): any {
430
430
 
431
431
  /** Heuristic: plugins that target a terminal surface rather than the web UI. */
432
432
  export function looksTerminal(plugin: RegistryPlugin, lang: string): boolean {
433
+ // The package NAME is a claim about the package itself: `dsh-tui` is a
434
+ // terminal surface. Descriptions are not — they mention the terminal for
435
+ // many reasons, including a companion CLI that ships from the same
436
+ // repository (#931). A bare "CLI"/"terminal" mention in prose used to be
437
+ // enough to warn that a web plugin "may not work in the web app", and a
438
+ // warning that fires on ordinary plugins is one users learn to ignore.
439
+ if (/\b(tui|cli|tty|terminal)\b|终端|命令行/i.test(plugin.name)) return true
433
440
  const desc = (plugin.description && (plugin.description[lang] || plugin.description.en)) || ''
434
- // A description can mention a CLI only to say it is NOT required. Treating
435
- // that as positive evidence labels web plugins as terminal-only. Strip
436
- // bounded negated clauses before applying the deliberately broad heuristic;
437
- // the package name remains untouched and therefore stays strong evidence.
441
+ // A description can also mention a CLI only to say it is NOT required
442
+ // (#237). Strip bounded negated clauses first.
438
443
  const positiveDesc = desc
439
444
  .replace(/\b(?:no|without)\b[^.!?;:,。!?;\n]{0,80}\b(?:tui|cli|tty|terminal)\b/gi, '')
440
445
  .replace(/(?:无需|无须|不需要|不用)[^。!?;\n]{0,48}(?:tui|cli|tty|terminal|终端|命令行)/gi, '')
441
- return /\b(tui|cli|tty|terminal)\b|终端|命令行/i.test(plugin.name + ' ' + positiveDesc)
446
+ // Only phrases that assert THIS plugin's own surface count.
447
+ return /\b(?:terminal|cli)[ -]only\b|\btui (?:app|plugin|client)\b|\bterminal (?:ui|app|plugin|client)\b|\bcommand[- ]line (?:tool|interface|app|client|plugin)\b|命令行(?:工具|插件|应用|界面|客户端)|终端(?:工具|插件|应用|界面|客户端)|只在终端|仅在终端|需要(?:一个)?终端|在终端(?:里|中)运行/i.test(positiveDesc)
442
448
  }
443
449
 
444
450
  /** Sortable field for the Discover list. */
package/src/routes.ts CHANGED
@@ -2050,6 +2050,12 @@ export function mountMarketRoutes(
2050
2050
  version,
2051
2051
  requirement: verdict.requirement,
2052
2052
  hostVersion: host?.version ?? null,
2053
+ // #923: the client's "find a compatible version" search is keyed by
2054
+ // the npm name, and the install branch could fall back to the catalog
2055
+ // entry's `npm` while the update branch had nothing. The value is
2056
+ // already here — it is this function's first argument and the key the
2057
+ // registry lookup above used — so publish it.
2058
+ npmName,
2053
2059
  },
2054
2060
  error: nothingWasInstalled
2055
2061
  ? `${displayName} ${version ?? ''} 要求的 DSH 版本是 ${verdict.requirement ?? '未知'},而当前运行的是 ${host?.version ?? '未知版本'},装上多半会直接报错。已停止,没有安装任何东西。 / ${displayName} ${version ?? ''} declares it needs DSH ${verdict.requirement ?? '(unknown)'}, and this host is ${host?.version ?? 'unknown'}; installing it would most likely break the plugin. Nothing was installed.`
@@ -4688,6 +4694,12 @@ sendJson(response, 200, { updates })
4688
4694
  if (pinnedForIdentification) {
4689
4695
  declareProfileDependency(config.profile, name, pinValue, activeProfileDir)
4690
4696
  }
4697
+ // #928: an update is remove-then-add, and a host killed between
4698
+ // the two leaves a package that is simply gone — with no record
4699
+ // of what was being attempted, because the completion log never
4700
+ // runs. Write the intent first, so the log can answer "where did
4701
+ // my plugin go" after the fact.
4702
+ logEvent('info', 'update-start', `${name} -> ${target} (profile ${config.profile})`)
4691
4703
  const result = await runPlugin(config.profile, addArgs)
4692
4704
  const cancelled = result.cancelled
4693
4705
  // The pin above is the market's own write, so it is undone whenever
@@ -5979,6 +5991,10 @@ sendJson(response, 200, { updates })
5979
5991
  // it is meant to clean up after, and the rows outlive the package
5980
5992
  // as boot-time orphans (#799).
5981
5993
  const ownedRows = rowIdsForPackage(host, activeProfileDir, name)
5994
+ // #928: the same intent record as the update path — an uninstall
5995
+ // interrupted mid-remove leaves the same "where did it go" with no
5996
+ // entry saying what was running.
5997
+ logEvent('info', 'uninstall-start', `${name} (profile ${config.profile})`)
5982
5998
  const result = await runPlugin(config.profile, ['remove', name])
5983
5999
  const cancelled = result.cancelled
5984
6000
  const ok = result.exitCode === 0 && !result.timedOut && !cancelled