dsh-context 0.49.2 → 0.49.4
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/lib/client.js +99 -16
- package/lib/index.js +105 -29
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -67,6 +67,10 @@ window.__ModuleLoader__.load({
|
|
|
67
67
|
"gran.turn": "轮次",
|
|
68
68
|
"settings.title": "上下文",
|
|
69
69
|
"settings.desc": "dsh-context 插件中上下文面板的偏好设置",
|
|
70
|
+
"settings.placement": "入口位置",
|
|
71
|
+
"placement.tab": "标签页",
|
|
72
|
+
"placement.sidebar": "侧边栏",
|
|
73
|
+
"placement.all": "全部",
|
|
70
74
|
"settings.gran": "趋势图 · 默认粒度",
|
|
71
75
|
"settings.mode": "趋势图 · 默认展示方式",
|
|
72
76
|
"settings.fileSort": "文件活动 · 默认排序",
|
|
@@ -358,6 +362,10 @@ window.__ModuleLoader__.load({
|
|
|
358
362
|
"gran.turn": "Turn",
|
|
359
363
|
"settings.title": "Context",
|
|
360
364
|
"settings.desc": "Preferences for Context panel in dsh-context plugin",
|
|
365
|
+
"settings.placement": "Entry Options",
|
|
366
|
+
"placement.tab": "Tab",
|
|
367
|
+
"placement.sidebar": "Sidebar",
|
|
368
|
+
"placement.all": "All",
|
|
361
369
|
"settings.gran": "Trend Chart · Default granularity",
|
|
362
370
|
"settings.mode": "Trend Chart · Default display",
|
|
363
371
|
"settings.fileSort": "File Activity · Default sort",
|
|
@@ -4426,6 +4434,28 @@ window.__ModuleLoader__.load({
|
|
|
4426
4434
|
role: "status",
|
|
4427
4435
|
children: t("settings.readOnly")
|
|
4428
4436
|
}) : null,
|
|
4437
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PrefRow, {
|
|
4438
|
+
label: t("settings.placement"),
|
|
4439
|
+
value: state.placement,
|
|
4440
|
+
disabled,
|
|
4441
|
+
options: [
|
|
4442
|
+
{
|
|
4443
|
+
id: "all",
|
|
4444
|
+
label: t("placement.all")
|
|
4445
|
+
},
|
|
4446
|
+
{
|
|
4447
|
+
id: "tab",
|
|
4448
|
+
label: t("placement.tab")
|
|
4449
|
+
},
|
|
4450
|
+
{
|
|
4451
|
+
id: "sidebar",
|
|
4452
|
+
label: t("placement.sidebar")
|
|
4453
|
+
}
|
|
4454
|
+
],
|
|
4455
|
+
onPick: (id) => {
|
|
4456
|
+
props.set?.("defaultPlacement", id);
|
|
4457
|
+
}
|
|
4458
|
+
}),
|
|
4429
4459
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PrefRow, {
|
|
4430
4460
|
label: t("settings.gran"),
|
|
4431
4461
|
value: state.granularity,
|
|
@@ -4489,6 +4519,7 @@ window.__ModuleLoader__.load({
|
|
|
4489
4519
|
if (value === null || typeof value !== "object") return {};
|
|
4490
4520
|
const v = value;
|
|
4491
4521
|
return {
|
|
4522
|
+
...v.defaultPlacement === "all" || v.defaultPlacement === "tab" || v.defaultPlacement === "sidebar" ? { placement: v.defaultPlacement } : {},
|
|
4492
4523
|
...v.defaultGranularity === "step" || v.defaultGranularity === "turn" ? { granularity: v.defaultGranularity } : {},
|
|
4493
4524
|
...v.defaultTrendMode === "total" || v.defaultTrendMode === "delta" ? { mode: v.defaultTrendMode } : {},
|
|
4494
4525
|
...v.defaultFileSort === "count" || v.defaultFileSort === "latest" || v.defaultFileSort === "path" ? { fileSort: v.defaultFileSort } : {}
|
|
@@ -4497,6 +4528,7 @@ window.__ModuleLoader__.load({
|
|
|
4497
4528
|
function createContextSettings() {
|
|
4498
4529
|
let state = {
|
|
4499
4530
|
status: "loading",
|
|
4531
|
+
placement: "all",
|
|
4500
4532
|
granularity: "step",
|
|
4501
4533
|
mode: "total",
|
|
4502
4534
|
fileSort: "count",
|
|
@@ -4505,20 +4537,23 @@ window.__ModuleLoader__.load({
|
|
|
4505
4537
|
let scope;
|
|
4506
4538
|
const listeners = /* @__PURE__ */ new Set();
|
|
4507
4539
|
const publish = (next) => {
|
|
4508
|
-
if (next.status === state.status && next.granularity === state.granularity && next.mode === state.mode && next.fileSort === state.fileSort && next.writable === state.writable) return;
|
|
4540
|
+
if (next.status === state.status && next.placement === state.placement && next.granularity === state.granularity && next.mode === state.mode && next.fileSort === state.fileSort && next.writable === state.writable) return;
|
|
4509
4541
|
state = next;
|
|
4510
4542
|
for (const listener of listeners) listener();
|
|
4511
4543
|
};
|
|
4512
4544
|
const sync = (bound) => {
|
|
4513
4545
|
const snap = bound.getSnapshot();
|
|
4514
4546
|
const prefs = prefsOf(snap.value);
|
|
4547
|
+
const rawPlacement = snap.value !== null && typeof snap.value === "object" ? snap.value.defaultPlacement : void 0;
|
|
4515
4548
|
publish({
|
|
4516
4549
|
status: snap.status === "ready" || snap.status === "unavailable" ? snap.status : "loading",
|
|
4550
|
+
placement: prefs.placement ?? (rawPlacement === void 0 ? state.placement : "all"),
|
|
4517
4551
|
granularity: prefs.granularity ?? state.granularity,
|
|
4518
4552
|
mode: prefs.mode ?? state.mode,
|
|
4519
4553
|
fileSort: prefs.fileSort ?? state.fileSort,
|
|
4520
4554
|
writable: snap.writable
|
|
4521
4555
|
});
|
|
4556
|
+
return prefs.placement;
|
|
4522
4557
|
};
|
|
4523
4558
|
return {
|
|
4524
4559
|
store: {
|
|
@@ -4530,6 +4565,7 @@ window.__ModuleLoader__.load({
|
|
|
4530
4565
|
},
|
|
4531
4566
|
getSnapshot: () => state
|
|
4532
4567
|
},
|
|
4568
|
+
defaultPlacement: () => state.placement,
|
|
4533
4569
|
defaultGranularity: () => state.granularity,
|
|
4534
4570
|
defaultTrendMode: () => state.mode,
|
|
4535
4571
|
defaultFileSort: () => state.fileSort,
|
|
@@ -4548,7 +4584,11 @@ window.__ModuleLoader__.load({
|
|
|
4548
4584
|
const bound = scope;
|
|
4549
4585
|
if (bound === void 0) return;
|
|
4550
4586
|
bound.set(field, value).catch(() => {
|
|
4551
|
-
sync(bound);
|
|
4587
|
+
const truth = sync(bound);
|
|
4588
|
+
if (field === "defaultPlacement" && truth === void 0) publish({
|
|
4589
|
+
...state,
|
|
4590
|
+
placement: "all"
|
|
4591
|
+
});
|
|
4552
4592
|
});
|
|
4553
4593
|
}
|
|
4554
4594
|
};
|
|
@@ -6640,7 +6680,7 @@ window.__ModuleLoader__.load({
|
|
|
6640
6680
|
return function PluginInfo() {
|
|
6641
6681
|
const [latest, setLatest] = (0, react.useState)(null);
|
|
6642
6682
|
(0, react.useEffect)(() => {
|
|
6643
|
-
if ("0.49.
|
|
6683
|
+
if ("0.49.4".includes("-dev")) return;
|
|
6644
6684
|
let on = true;
|
|
6645
6685
|
fetchLatestVersion().then((v) => {
|
|
6646
6686
|
if (on && v) setLatest(v);
|
|
@@ -6649,8 +6689,8 @@ window.__ModuleLoader__.load({
|
|
|
6649
6689
|
on = false;
|
|
6650
6690
|
};
|
|
6651
6691
|
}, []);
|
|
6652
|
-
const update = latest !== null && isNewerVersion(latest, "0.49.
|
|
6653
|
-
const nameText = "dsh-context (v0.49.
|
|
6692
|
+
const update = latest !== null && isNewerVersion(latest, "0.49.4") ? latest : null;
|
|
6693
|
+
const nameText = "dsh-context (v0.49.4)";
|
|
6654
6694
|
const nameValue = [nameText];
|
|
6655
6695
|
if (update) nameValue.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6656
6696
|
className: "lc-pi-update",
|
|
@@ -8756,6 +8796,42 @@ window.__ModuleLoader__.load({
|
|
|
8756
8796
|
};
|
|
8757
8797
|
}
|
|
8758
8798
|
//#endregion
|
|
8799
|
+
//#region src/client/placement.ts
|
|
8800
|
+
/**
|
|
8801
|
+
* Mount per the current preference and keep the registrations glued to it
|
|
8802
|
+
* until the returned disposer runs.
|
|
8803
|
+
*/
|
|
8804
|
+
function watchPlacement(settings, mounts) {
|
|
8805
|
+
let tab;
|
|
8806
|
+
let sidebar;
|
|
8807
|
+
const own = (result) => typeof result === "function" ? result : void 0;
|
|
8808
|
+
const mount = (placement) => {
|
|
8809
|
+
const wantTab = placement !== "sidebar";
|
|
8810
|
+
const wantSidebar = placement !== "tab";
|
|
8811
|
+
if (wantTab && tab === void 0) tab = own(mounts.tab());
|
|
8812
|
+
if (!wantTab && tab !== void 0) {
|
|
8813
|
+
tab();
|
|
8814
|
+
tab = void 0;
|
|
8815
|
+
}
|
|
8816
|
+
if (wantSidebar && sidebar === void 0) sidebar = own(mounts.sidebar());
|
|
8817
|
+
if (!wantSidebar && sidebar !== void 0) {
|
|
8818
|
+
sidebar();
|
|
8819
|
+
sidebar = void 0;
|
|
8820
|
+
}
|
|
8821
|
+
};
|
|
8822
|
+
mount(settings.defaultPlacement());
|
|
8823
|
+
const unsubscribe = settings.store.subscribe(() => {
|
|
8824
|
+
mount(settings.defaultPlacement());
|
|
8825
|
+
});
|
|
8826
|
+
return () => {
|
|
8827
|
+
unsubscribe();
|
|
8828
|
+
tab?.();
|
|
8829
|
+
sidebar?.();
|
|
8830
|
+
tab = void 0;
|
|
8831
|
+
sidebar = void 0;
|
|
8832
|
+
};
|
|
8833
|
+
}
|
|
8834
|
+
//#endregion
|
|
8759
8835
|
//#region src/client/icon.tsx
|
|
8760
8836
|
/** The sheet's strokes, in paint order, as `[path, fill]` pairs. */
|
|
8761
8837
|
const SHEET_PATHS = [
|
|
@@ -8853,9 +8929,11 @@ window.__ModuleLoader__.load({
|
|
|
8853
8929
|
* locale at call time, so a language switch relabels the guide entry.
|
|
8854
8930
|
* @param ns - the plugin's locale namespace, put on the body registration so
|
|
8855
8931
|
* the framework synthesizes the `t` seat for the panel too.
|
|
8932
|
+
* @returns the deferred inject's disposer (placement toggling calls it to
|
|
8933
|
+
* take the mount down; a no-op on faces that return no handle).
|
|
8856
8934
|
*/
|
|
8857
8935
|
function watchSidebarContextTab(ctx, view, t, ns) {
|
|
8858
|
-
ctx.inject(["sidebarRightTabs"], (raw) => {
|
|
8936
|
+
const handle = ctx.inject(["sidebarRightTabs"], (raw) => {
|
|
8859
8937
|
const injected = raw;
|
|
8860
8938
|
const disposers = [];
|
|
8861
8939
|
const own = (result) => {
|
|
@@ -8895,6 +8973,9 @@ window.__ModuleLoader__.load({
|
|
|
8895
8973
|
for (const dispose of disposers) dispose();
|
|
8896
8974
|
};
|
|
8897
8975
|
});
|
|
8976
|
+
return () => {
|
|
8977
|
+
handle?.dispose?.();
|
|
8978
|
+
};
|
|
8898
8979
|
}
|
|
8899
8980
|
//#endregion
|
|
8900
8981
|
//#region src/client/viewkit.ts
|
|
@@ -9103,16 +9184,18 @@ window.__ModuleLoader__.load({
|
|
|
9103
9184
|
watchHistoryFaces(ctx);
|
|
9104
9185
|
const settings = createContextSettings();
|
|
9105
9186
|
const ContextView = makeContextView(ctx, kit, settings);
|
|
9106
|
-
ctx.
|
|
9107
|
-
|
|
9108
|
-
|
|
9109
|
-
|
|
9110
|
-
|
|
9111
|
-
|
|
9112
|
-
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
9187
|
+
ctx.effect(() => watchPlacement(settings, {
|
|
9188
|
+
tab: () => ctx.slots.inject("conversation.view", () => {
|
|
9189
|
+
return ctx.slots.register({
|
|
9190
|
+
name: "conversation.view",
|
|
9191
|
+
id: "context",
|
|
9192
|
+
order: 20,
|
|
9193
|
+
locale: NS,
|
|
9194
|
+
label: () => t("tab")
|
|
9195
|
+
}, (props) => (0, react.createElement)(ContextView, props));
|
|
9196
|
+
}),
|
|
9197
|
+
sidebar: () => watchSidebarContextTab(ctx, ContextView, t, NS)
|
|
9198
|
+
}), "dsh-context: placement");
|
|
9116
9199
|
const ContextJump = makeContextJumpButton(kit);
|
|
9117
9200
|
ctx.slots.inject("conversation.chat.assistant-actions", () => {
|
|
9118
9201
|
return ctx.slots.register({
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
-
import { dirname, join, normalize } from "node:path";
|
|
3
|
+
import { dirname, join, normalize, relative } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { deriveEventMessage } from "@deepseek-ai/dsh-session";
|
|
@@ -2009,7 +2009,7 @@ function watchDetailChannel(ctx, bounds) {
|
|
|
2009
2009
|
* host probes and gates; the client displays what the wire record carries),
|
|
2010
2010
|
* so this module must stay dependency-free.
|
|
2011
2011
|
*
|
|
2012
|
-
* The baseline mirrors the support matrix (
|
|
2012
|
+
* The baseline mirrors the support matrix (docs/compatibility.md and the
|
|
2013
2013
|
* package's `dsh.compatibility.dshReleases` declaration): the oldest dsh
|
|
2014
2014
|
* release this plugin works on. A harness BELOW it gets the fallback units
|
|
2015
2015
|
* (host/fallback.ts) instead of the real folds.
|
|
@@ -2607,6 +2607,11 @@ function createFallbackHeadersDefinition() {
|
|
|
2607
2607
|
const SETTINGS_NAMESPACE = "dsh-context";
|
|
2608
2608
|
/** Section schema: also the wire envelope the browser scope validates against. */
|
|
2609
2609
|
const SettingsSchema = z$1.object({
|
|
2610
|
+
defaultPlacement: z$1.union([
|
|
2611
|
+
"all",
|
|
2612
|
+
"tab",
|
|
2613
|
+
"sidebar"
|
|
2614
|
+
]).default("all").loose(),
|
|
2610
2615
|
defaultGranularity: z$1.union(["step", "turn"]).default("step"),
|
|
2611
2616
|
defaultTrendMode: z$1.union(["total", "delta"]).default("total").loose(),
|
|
2612
2617
|
defaultFileSort: z$1.union([
|
|
@@ -2707,35 +2712,72 @@ function watchStepIdentity(ctx) {
|
|
|
2707
2712
|
* The probe never imports a harness package for its version; it reads
|
|
2708
2713
|
* manifests through Node resolution from two anchors, in order:
|
|
2709
2714
|
*
|
|
2710
|
-
* 1.
|
|
2711
|
-
*
|
|
2712
|
-
*
|
|
2713
|
-
*
|
|
2714
|
-
*
|
|
2715
|
-
*
|
|
2716
|
-
*
|
|
2717
|
-
*
|
|
2715
|
+
* 1. This module's own ESM resolution of the library packages the Host half
|
|
2716
|
+
* imports at runtime. That is the very pipeline the process resolves those
|
|
2717
|
+
* imports through, so an embedding shell that redirects plugin imports —
|
|
2718
|
+
* the packaged Desktop's ASAR resolver bridge does exactly this — redirects
|
|
2719
|
+
* the probe identically, and the answer names the module instances the
|
|
2720
|
+
* harness is actually running. A witness that lands inside this package's
|
|
2721
|
+
* own tree is the plugin's dependency closure (a `link:`-installed dev
|
|
2722
|
+
* checkout's pinned devDependencies), never the harness, so it is discarded
|
|
2723
|
+
* for the home anchor.
|
|
2724
|
+
* 2. The harness home's healed `profiles/node_modules` mirror (located via
|
|
2725
|
+
* the app-boot `dshHomePath` service). It names the installation that last
|
|
2726
|
+
* healed it: authoritative for a dev checkout, whose own tree holds pinned
|
|
2727
|
+
* devDependencies, but only as fresh as the last CLI profile boot. A
|
|
2728
|
+
* packaged Desktop never heals it, so a stale global-CLI mirror can outlive
|
|
2729
|
+
* the CLI and misname the running harness — that is why it answers only
|
|
2730
|
+
* when the running anchor has nothing it can trust.
|
|
2718
2731
|
*
|
|
2719
2732
|
* The `@deepseek-ai/dsh` CLI package is probed ONLY through the home anchor:
|
|
2720
|
-
* the plugin never
|
|
2721
|
-
*
|
|
2733
|
+
* the plugin never imports it, so a hit from the running anchor can only be an
|
|
2734
|
+
* ambient install above the plugin's tree (e.g. a global copy under
|
|
2722
2735
|
* ~/node_modules) — not necessarily the RUNNING harness.
|
|
2723
2736
|
*
|
|
2724
2737
|
* Every step is guarded: any failure (absent service, unresolvable package,
|
|
2725
|
-
* unreadable/invalid manifest, non-string version) degrades to
|
|
2726
|
-
* and the gate treats an unknown version as SATISFIED — a probe
|
|
2727
|
-
* never blank a working deployment.
|
|
2738
|
+
* non-file URL, unreadable/invalid manifest, non-string version) degrades to
|
|
2739
|
+
* `undefined`, and the gate treats an unknown version as SATISFIED — a probe
|
|
2740
|
+
* misfire must never blank a working deployment.
|
|
2728
2741
|
*/
|
|
2729
2742
|
/**
|
|
2730
|
-
* Library packages whose manifest version IS the harness release version
|
|
2731
|
-
*
|
|
2732
|
-
*
|
|
2733
|
-
*
|
|
2734
|
-
* to probe from either anchor.
|
|
2743
|
+
* Library packages whose manifest version IS the harness release version (the
|
|
2744
|
+
* dsh monorepo versions every package in lockstep). The home anchor probes
|
|
2745
|
+
* them after the CLI package; the running anchor probes the two first- and
|
|
2746
|
+
* second-ordered.
|
|
2735
2747
|
*/
|
|
2736
2748
|
const LIBRARY_PROBE_PACKAGES = ["@deepseek-ai/dsh-session-projection", "@deepseek-ai/dsh-session"];
|
|
2749
|
+
/**
|
|
2750
|
+
* Running-anchor probe order: the package the Host half genuinely imports at
|
|
2751
|
+
* runtime first (host/fold.ts imports it, so it MUST resolve whenever this
|
|
2752
|
+
* plugin runs), then its co-versioned sibling.
|
|
2753
|
+
*/
|
|
2754
|
+
const RUNNING_PROBE_PACKAGES = ["@deepseek-ai/dsh-session", "@deepseek-ai/dsh-session-projection"];
|
|
2737
2755
|
/** Home-anchor probe order: the user-facing CLI version first, then the libraries. */
|
|
2738
2756
|
const HOME_PROBE_PACKAGES = ["@deepseek-ai/dsh", ...LIBRARY_PROBE_PACKAGES];
|
|
2757
|
+
/**
|
|
2758
|
+
* This package's root. A running-anchor witness under it belongs to the
|
|
2759
|
+
* plugin's own dependency closure, not to the harness.
|
|
2760
|
+
*
|
|
2761
|
+
* Located through the package's own `./package.json` self-reference: Node
|
|
2762
|
+
* resolves that against the nearest package.json, so the answer is the package
|
|
2763
|
+
* root in the source tree and in the bundled profile install alike — a fixed
|
|
2764
|
+
* number of `..` steps cannot be, since `src/host/` and `lib/` differ by a
|
|
2765
|
+
* level. A loader that cannot self-resolve (an exotic loader, or a fork renamed
|
|
2766
|
+
* without a matching `exports`) falls back to this module's own directory: the
|
|
2767
|
+
* guard then covers less of the package, but it still can never mistake the
|
|
2768
|
+
* plugin's own `node_modules` for the harness.
|
|
2769
|
+
*/
|
|
2770
|
+
function ownPackageRoot() {
|
|
2771
|
+
try {
|
|
2772
|
+
return dirname(fileURLToPath(import.meta.resolve("dsh-context/package.json")));
|
|
2773
|
+
} catch {
|
|
2774
|
+
/* v8 ignore next -- a loader that cannot resolve one of its own package's
|
|
2775
|
+
published subpaths is out of the suite's reach; the fallback keeps one
|
|
2776
|
+
probe path (an unanswered probe fails open either way). */
|
|
2777
|
+
return dirname(fileURLToPath(import.meta.url));
|
|
2778
|
+
}
|
|
2779
|
+
}
|
|
2780
|
+
const PLUGIN_ROOT = ownPackageRoot();
|
|
2739
2781
|
/** One manifest's `version`, or undefined on any read/shape failure. */
|
|
2740
2782
|
function versionOfManifest(manifestPath, expectedName) {
|
|
2741
2783
|
try {
|
|
@@ -2785,11 +2827,51 @@ function probeAnchor(resolve, packageNames) {
|
|
|
2785
2827
|
}
|
|
2786
2828
|
}
|
|
2787
2829
|
/**
|
|
2830
|
+
* Whether `candidate` lies inside `root`'s tree. A `..`-prefixed relative path
|
|
2831
|
+
* escapes it; a sibling such as `dsh-context-extra` is reached through `..` too,
|
|
2832
|
+
* so it never counts as a child. A pathological child literally named `..foo`
|
|
2833
|
+
* would degrade to the home anchor, which is the safe direction.
|
|
2834
|
+
*/
|
|
2835
|
+
function isInside(root, candidate) {
|
|
2836
|
+
return !relative(root, candidate).startsWith("..");
|
|
2837
|
+
}
|
|
2838
|
+
/**
|
|
2839
|
+
* The running module tree's answer, or undefined when it cannot be trusted.
|
|
2840
|
+
* Each probe package is checked on its own: a witness inside the plugin's own
|
|
2841
|
+
* closure is the plugin's dependency, not the harness, and a trusted witness
|
|
2842
|
+
* whose manifest cannot be read is no answer either — the next package may
|
|
2843
|
+
* still resolve to one.
|
|
2844
|
+
*/
|
|
2845
|
+
function probeRunningTree(resolve, pluginRoot) {
|
|
2846
|
+
for (const packageName of RUNNING_PROBE_PACKAGES) {
|
|
2847
|
+
let witness;
|
|
2848
|
+
try {
|
|
2849
|
+
witness = resolve(packageName);
|
|
2850
|
+
} catch {
|
|
2851
|
+
continue;
|
|
2852
|
+
}
|
|
2853
|
+
if (isInside(pluginRoot, witness)) continue;
|
|
2854
|
+
const version = versionViaManifest(resolve, packageName) ?? versionViaEntry(resolve, packageName);
|
|
2855
|
+
if (version !== void 0) return version;
|
|
2856
|
+
}
|
|
2857
|
+
}
|
|
2858
|
+
/** The default running anchor: this module's own ESM resolution. */
|
|
2859
|
+
function resolveRunningModule(specifier) {
|
|
2860
|
+
return import.meta.resolve(specifier);
|
|
2861
|
+
}
|
|
2862
|
+
/**
|
|
2788
2863
|
* The running harness's version string, or undefined when nothing answers
|
|
2789
2864
|
* (the gate fails open on it — see the header note).
|
|
2790
|
-
* @param
|
|
2791
|
-
|
|
2792
|
-
|
|
2865
|
+
* @param resolveUrl - the running anchor's URL resolver (injectable for hermetic tests).
|
|
2866
|
+
* @param pluginRoot - this package's root for the own-closure check (injectable for hermetic tests).
|
|
2867
|
+
*/
|
|
2868
|
+
function detectHarnessVersion(ctx, resolveUrl = resolveRunningModule, pluginRoot = PLUGIN_ROOT) {
|
|
2869
|
+
const running = probeRunningTree((specifier) => {
|
|
2870
|
+
const url = resolveUrl(specifier);
|
|
2871
|
+
if (!url.startsWith("file:")) throw new Error(`dsh-context: non-file module URL for ${specifier}`);
|
|
2872
|
+
return fileURLToPath(url);
|
|
2873
|
+
}, pluginRoot);
|
|
2874
|
+
if (running !== void 0) return running;
|
|
2793
2875
|
try {
|
|
2794
2876
|
const homePath = ctx.get("dshHomePath");
|
|
2795
2877
|
if (typeof homePath === "function") {
|
|
@@ -2798,12 +2880,6 @@ function detectHarnessVersion(ctx, selfUrl = import.meta.url) {
|
|
|
2798
2880
|
if (home !== void 0) return home;
|
|
2799
2881
|
}
|
|
2800
2882
|
} catch {}
|
|
2801
|
-
try {
|
|
2802
|
-
const req = createRequire(selfUrl);
|
|
2803
|
-
return probeAnchor((specifier) => req.resolve(specifier), LIBRARY_PROBE_PACKAGES);
|
|
2804
|
-
} catch {
|
|
2805
|
-
return;
|
|
2806
|
-
}
|
|
2807
2883
|
}
|
|
2808
2884
|
//#endregion
|
|
2809
2885
|
//#region src/host/index.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-context",
|
|
3
|
-
"version": "0.49.
|
|
3
|
+
"version": "0.49.4",
|
|
4
4
|
"description": "A DeepSeek Harness plugin for context insight and management, with context dashboard and context command, for understanding how the context is made of, and how it evolves.",
|
|
5
5
|
"author": "bowenliang123",
|
|
6
6
|
"repository": {
|