dsh-mnemon 0.5.21 → 0.5.22
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 +151 -15
- package/lib/index.js +321 -50
- package/lib/types/src/client/locales.d.ts +5 -0
- package/lib/types/src/host/protocol.d.ts +21 -0
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -1854,7 +1854,7 @@ window.__ModuleLoader__.load({
|
|
|
1854
1854
|
"versions.packagesOutdated": "{count} 个有新版本",
|
|
1855
1855
|
"versions.packagesDetail": "展开查看维护方式",
|
|
1856
1856
|
"versions.packagesHide": "收起子包详情",
|
|
1857
|
-
"versions.packagesHint": "默认组合随主包更新;在当前 Profile 中独立安装的子包可单独更新。更新后重启
|
|
1857
|
+
"versions.packagesHint": "默认组合随主包更新;在当前 Profile 中独立安装的子包可单独更新。更新后重启 DSH。",
|
|
1858
1858
|
"versions.managedStarter": "随主包维护",
|
|
1859
1859
|
"versions.managedProfile": "Profile 独立维护",
|
|
1860
1860
|
"versions.starterVersion": "主包指定",
|
|
@@ -1880,7 +1880,11 @@ window.__ModuleLoader__.load({
|
|
|
1880
1880
|
"versions.updating": "更新中…",
|
|
1881
1881
|
"versions.updated": "{name} 已更新",
|
|
1882
1882
|
"versions.alreadyCurrent": "当前已经是最新版本",
|
|
1883
|
-
"versions.restartRequired": "请重启
|
|
1883
|
+
"versions.restartRequired": "请重启 DSH 以加载新的 dsh-mnemon 插件代码;桌面版请完全退出后重新打开。",
|
|
1884
|
+
"versions.pendingInstalledTitle": "dsh-mnemon {version} 已安装",
|
|
1885
|
+
"versions.pendingInstalledDetail": "当前运行的仍是 {running};重启 DSH 后生效,桌面版请完全退出后重新打开。",
|
|
1886
|
+
"versions.pendingPackagesTitle": "{names} 已更新",
|
|
1887
|
+
"versions.pendingPackagesDetail": "重启 DSH 后生效,桌面版请完全退出后重新打开。",
|
|
1884
1888
|
"versions.checkedAt": "检查于 {time}",
|
|
1885
1889
|
"versions.latestUnavailable": "暂时无法读取远程最新版本;请检查网络后重试。",
|
|
1886
1890
|
"versions.modeHomebrew": "Homebrew",
|
|
@@ -1892,8 +1896,9 @@ window.__ModuleLoader__.load({
|
|
|
1892
1896
|
"versions.hintHomebrew": "由 Homebrew 管理;发现新版本时可在此安全更新。",
|
|
1893
1897
|
"versions.hintBrewMissing": "检测到 Homebrew 安装,但当前找不到 brew 命令。",
|
|
1894
1898
|
"versions.hintGo": "由 go install 管理;发现新版本时可在此安全更新。",
|
|
1895
|
-
"versions.
|
|
1896
|
-
"versions.
|
|
1899
|
+
"versions.hintDsh": "由当前 DSH Profile 管理;用 DSH 自己的插件安装方式更新,完成后重启 DSH。",
|
|
1900
|
+
"versions.hintPnpm": "由当前 DSH Profile 管理;更新后需要重启 DSH。",
|
|
1901
|
+
"versions.hintPnpmMissing": "检测到 DSH Profile 安装,但宿主找不到 pnpm 命令;安装 pnpm 并重启 DSH 后即可在此更新。",
|
|
1897
1902
|
"versions.hintLink": "当前为本地 Link 开发版本;请在源码目录拉取并构建,避免覆盖本地修改。",
|
|
1898
1903
|
"versions.hintInstall": "未安装 Mnemon CLI。只有 Mnemon Native 需要它;需要时安装并确保 mnemon 位于 PATH,或设置 MNEMON_CLI_PATH / mnemon.cliPath。",
|
|
1899
1904
|
"versions.hintManual": "无法安全识别安装来源;请沿用原安装方式手工更新。",
|
|
@@ -2445,7 +2450,7 @@ window.__ModuleLoader__.load({
|
|
|
2445
2450
|
"versions.packagesOutdated": "{count} updates available",
|
|
2446
2451
|
"versions.packagesDetail": "Expand for maintenance options",
|
|
2447
2452
|
"versions.packagesHide": "Collapse package details",
|
|
2448
|
-
"versions.packagesHint": "Default packages update with the Starter. Packages installed independently in this Profile can update individually. Restart
|
|
2453
|
+
"versions.packagesHint": "Default packages update with the Starter. Packages installed independently in this Profile can update individually. Restart DSH afterward.",
|
|
2449
2454
|
"versions.managedStarter": "Maintained with Starter",
|
|
2450
2455
|
"versions.managedProfile": "Managed by Profile",
|
|
2451
2456
|
"versions.starterVersion": "Starter pin",
|
|
@@ -2471,7 +2476,11 @@ window.__ModuleLoader__.load({
|
|
|
2471
2476
|
"versions.updating": "Updating…",
|
|
2472
2477
|
"versions.updated": "{name} updated",
|
|
2473
2478
|
"versions.alreadyCurrent": "Already on the latest version",
|
|
2474
|
-
"versions.restartRequired": "Restart
|
|
2479
|
+
"versions.restartRequired": "Restart DSH to load the new dsh-mnemon plugin code; in the desktop app, quit and reopen it.",
|
|
2480
|
+
"versions.pendingInstalledTitle": "dsh-mnemon {version} is installed",
|
|
2481
|
+
"versions.pendingInstalledDetail": "This Host still runs {running}. Restart DSH to load it; in the desktop app, quit and reopen it.",
|
|
2482
|
+
"versions.pendingPackagesTitle": "{names} updated",
|
|
2483
|
+
"versions.pendingPackagesDetail": "Restart DSH to load the update; in the desktop app, quit and reopen it.",
|
|
2475
2484
|
"versions.checkedAt": "Checked at {time}",
|
|
2476
2485
|
"versions.latestUnavailable": "The remote latest version is unavailable. Check the network and try again.",
|
|
2477
2486
|
"versions.modeHomebrew": "Homebrew",
|
|
@@ -2483,8 +2492,9 @@ window.__ModuleLoader__.load({
|
|
|
2483
2492
|
"versions.hintHomebrew": "Managed by Homebrew; an available release can be safely updated here.",
|
|
2484
2493
|
"versions.hintBrewMissing": "A Homebrew installation was detected, but the brew command is unavailable.",
|
|
2485
2494
|
"versions.hintGo": "Managed by go install; an available release can be safely updated here.",
|
|
2486
|
-
"versions.
|
|
2487
|
-
"versions.
|
|
2495
|
+
"versions.hintDsh": "Managed by the current DSH Profile. Updates use DSH's own plugin installer; restart DSH afterwards.",
|
|
2496
|
+
"versions.hintPnpm": "Managed by the current DSH Profile; restart DSH after updating.",
|
|
2497
|
+
"versions.hintPnpmMissing": "A DSH Profile installation was detected, but the Host cannot find the pnpm command. Install pnpm and restart DSH to update here.",
|
|
2488
2498
|
"versions.hintLink": "This is a local linked development build. Pull and build in the source directory to preserve local changes.",
|
|
2489
2499
|
"versions.hintInstall": "Mnemon CLI is not installed. Only Mnemon Native needs it; to use Native, install it and place mnemon on PATH, or set MNEMON_CLI_PATH / mnemon.cliPath.",
|
|
2490
2500
|
"versions.hintManual": "The installation source cannot be identified safely. Update it using the original installation method.",
|
|
@@ -8938,6 +8948,74 @@ window.__ModuleLoader__.load({
|
|
|
8938
8948
|
}
|
|
8939
8949
|
};
|
|
8940
8950
|
//#endregion
|
|
8951
|
+
//#region src/client/starter-update.ts
|
|
8952
|
+
const STORAGE_KEY = "dsh-mnemon.starter-update";
|
|
8953
|
+
/** An older record belongs to an earlier visit, not to an update this page just ran. */
|
|
8954
|
+
const FRESH_MS = 6e5;
|
|
8955
|
+
function sessionStore() {
|
|
8956
|
+
try {
|
|
8957
|
+
return typeof window === "undefined" ? void 0 : window.sessionStorage;
|
|
8958
|
+
} catch {
|
|
8959
|
+
return;
|
|
8960
|
+
}
|
|
8961
|
+
}
|
|
8962
|
+
function recordStarterUpdate(update, now = Date.now()) {
|
|
8963
|
+
const record = {
|
|
8964
|
+
at: now,
|
|
8965
|
+
...update.from === void 0 ? {} : { from: update.from },
|
|
8966
|
+
...update.to === void 0 ? {} : { to: update.to }
|
|
8967
|
+
};
|
|
8968
|
+
try {
|
|
8969
|
+
sessionStore()?.setItem(STORAGE_KEY, JSON.stringify(record));
|
|
8970
|
+
} catch {}
|
|
8971
|
+
}
|
|
8972
|
+
function clearStarterUpdate() {
|
|
8973
|
+
try {
|
|
8974
|
+
sessionStore()?.removeItem(STORAGE_KEY);
|
|
8975
|
+
} catch {}
|
|
8976
|
+
}
|
|
8977
|
+
function pendingStarterUpdate(now = Date.now()) {
|
|
8978
|
+
let raw;
|
|
8979
|
+
try {
|
|
8980
|
+
raw = sessionStore()?.getItem(STORAGE_KEY);
|
|
8981
|
+
} catch {
|
|
8982
|
+
return;
|
|
8983
|
+
}
|
|
8984
|
+
if (raw === null || raw === void 0) return void 0;
|
|
8985
|
+
let value;
|
|
8986
|
+
try {
|
|
8987
|
+
value = JSON.parse(raw);
|
|
8988
|
+
} catch {
|
|
8989
|
+
value = void 0;
|
|
8990
|
+
}
|
|
8991
|
+
if (!isRecord(value) || typeof value.at !== "number" || now - value.at > FRESH_MS || value.at > now + 6e4) {
|
|
8992
|
+
clearStarterUpdate();
|
|
8993
|
+
return;
|
|
8994
|
+
}
|
|
8995
|
+
return {
|
|
8996
|
+
at: value.at,
|
|
8997
|
+
...typeof value.from === "string" ? { from: value.from } : {},
|
|
8998
|
+
...typeof value.to === "string" ? { to: value.to } : {}
|
|
8999
|
+
};
|
|
9000
|
+
}
|
|
9001
|
+
/** Open the Memory System once it can open, when this page just started a Starter update. */
|
|
9002
|
+
function reopenAfterStarterUpdate(workspace) {
|
|
9003
|
+
if (pendingStarterUpdate() === void 0) return () => {};
|
|
9004
|
+
let unsubscribe;
|
|
9005
|
+
const attempt = () => {
|
|
9006
|
+
const open = workspace.getSnapshot();
|
|
9007
|
+
if (open === void 0) return;
|
|
9008
|
+
unsubscribe?.();
|
|
9009
|
+
unsubscribe = void 0;
|
|
9010
|
+
if (pendingStarterUpdate() !== void 0) open();
|
|
9011
|
+
};
|
|
9012
|
+
unsubscribe = workspace.subscribe(attempt);
|
|
9013
|
+
attempt();
|
|
9014
|
+
return () => {
|
|
9015
|
+
unsubscribe?.();
|
|
9016
|
+
};
|
|
9017
|
+
}
|
|
9018
|
+
//#endregion
|
|
8941
9019
|
//#region src/client/change-signal.ts
|
|
8942
9020
|
/**
|
|
8943
9021
|
* A revision other surfaces bump when something they cannot observe directly
|
|
@@ -9233,6 +9311,7 @@ window.__ModuleLoader__.load({
|
|
|
9233
9311
|
if (component.updateHint === "brew") return t("versions.hintHomebrew");
|
|
9234
9312
|
if (component.updateHint === "brew-missing") return t("versions.hintBrewMissing");
|
|
9235
9313
|
if (component.updateHint === "go") return t("versions.hintGo");
|
|
9314
|
+
if (component.updateHint === "dsh") return t("versions.hintDsh");
|
|
9236
9315
|
if (component.updateHint === "pnpm") return t("versions.hintPnpm");
|
|
9237
9316
|
if (component.updateHint === "pnpm-missing") return t("versions.hintPnpmMissing");
|
|
9238
9317
|
if (component.updateHint === "link") return t("versions.hintLink");
|
|
@@ -9353,20 +9432,41 @@ window.__ModuleLoader__.load({
|
|
|
9353
9432
|
setUpdating(component.id);
|
|
9354
9433
|
setError(null);
|
|
9355
9434
|
setResult(null);
|
|
9435
|
+
if (component.id === "dsh-mnemon") recordStarterUpdate({
|
|
9436
|
+
from: component.current,
|
|
9437
|
+
to: component.latest
|
|
9438
|
+
});
|
|
9356
9439
|
try {
|
|
9357
9440
|
const next = await props.client.updateVersion(component.id);
|
|
9358
9441
|
setResult(next);
|
|
9359
9442
|
await check();
|
|
9360
9443
|
props.onRefreshStatus();
|
|
9361
9444
|
} catch (reason) {
|
|
9445
|
+
if (component.id === "dsh-mnemon") clearStarterUpdate();
|
|
9362
9446
|
setError(message(reason));
|
|
9363
9447
|
} finally {
|
|
9364
9448
|
setUpdating(null);
|
|
9365
9449
|
updateInFlight.current = false;
|
|
9366
9450
|
}
|
|
9367
9451
|
};
|
|
9452
|
+
const close = () => {
|
|
9453
|
+
clearStarterUpdate();
|
|
9454
|
+
props.onClose();
|
|
9455
|
+
};
|
|
9368
9456
|
const updatingBusy = updating !== null;
|
|
9369
9457
|
const controlsBusy = checking || updatingBusy;
|
|
9458
|
+
const resumed = props.resumedUpdate;
|
|
9459
|
+
const starter = snapshot?.components.find((component) => component.id === "dsh-mnemon");
|
|
9460
|
+
const outcome = result === null && error === null && resumed !== void 0 && snapshot?.lastUpdate?.component === "dsh-mnemon" && Date.parse(snapshot.lastUpdate.at) >= resumed.at - 6e4 ? snapshot.lastUpdate : void 0;
|
|
9461
|
+
const resumedResult = outcome !== void 0 ? outcome.result ?? null : result === null && resumed !== void 0 && snapshot?.lastUpdate === void 0 && starter?.restartRequired === true && (resumed.to === void 0 || starter.current === resumed.to) ? {
|
|
9462
|
+
component: "dsh-mnemon",
|
|
9463
|
+
updated: true,
|
|
9464
|
+
restartRequired: true,
|
|
9465
|
+
...resumed.from === void 0 ? {} : { previousVersion: resumed.from },
|
|
9466
|
+
...starter.current === void 0 ? {} : { currentVersion: starter.current }
|
|
9467
|
+
} : null;
|
|
9468
|
+
const shownResult = result ?? resumedResult;
|
|
9469
|
+
const shownError = error ?? outcome?.error ?? null;
|
|
9370
9470
|
const updateButton = (component) => props.writeEnabled && component.outdated && component.updateSupported && component.checkError === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
9371
9471
|
type: "button",
|
|
9372
9472
|
className: MnemonView_module_css_default.primaryButton,
|
|
@@ -9419,7 +9519,7 @@ window.__ModuleLoader__.load({
|
|
|
9419
9519
|
description: t("versions.description"),
|
|
9420
9520
|
busy: updatingBusy,
|
|
9421
9521
|
contentReady: !checking,
|
|
9422
|
-
onClose:
|
|
9522
|
+
onClose: close,
|
|
9423
9523
|
footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
9424
9524
|
className: MnemonView_module_css_default.modalFooterMeta,
|
|
9425
9525
|
children: snapshot === null ? "" : t("versions.checkedAt", { time: new Date(snapshot.checkedAt).toLocaleTimeString() })
|
|
@@ -9437,7 +9537,7 @@ window.__ModuleLoader__.load({
|
|
|
9437
9537
|
"data-dialog-close": true,
|
|
9438
9538
|
className: MnemonView_module_css_default.secondaryButton,
|
|
9439
9539
|
disabled: updatingBusy,
|
|
9440
|
-
onClick:
|
|
9540
|
+
onClick: close,
|
|
9441
9541
|
children: t("common.close")
|
|
9442
9542
|
})]
|
|
9443
9543
|
})] }),
|
|
@@ -9449,19 +9549,19 @@ window.__ModuleLoader__.load({
|
|
|
9449
9549
|
role: "status",
|
|
9450
9550
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {}), t("versions.checking")]
|
|
9451
9551
|
}),
|
|
9452
|
-
|
|
9552
|
+
shownError !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9453
9553
|
className: MnemonView_module_css_default.versionError,
|
|
9454
9554
|
role: "alert",
|
|
9455
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("versions.failed") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children:
|
|
9555
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("versions.failed") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: shownError })]
|
|
9456
9556
|
}),
|
|
9457
9557
|
!props.writeEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
9458
9558
|
className: MnemonView_module_css_default.versionNotice,
|
|
9459
9559
|
children: t("versions.readOnly")
|
|
9460
9560
|
}),
|
|
9461
|
-
|
|
9561
|
+
shownResult !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9462
9562
|
className: MnemonView_module_css_default.versionResult,
|
|
9463
9563
|
role: "status",
|
|
9464
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children:
|
|
9564
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: shownResult.updated ? t("versions.updated", { name: shownResult.component === "mnemon" ? "Mnemon CLI" : shownResult.component }) : t("versions.alreadyCurrent") }), shownResult.restartRequired && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("versions.restartRequired") })]
|
|
9465
9565
|
}),
|
|
9466
9566
|
snapshot !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9467
9567
|
className: MnemonView_module_css_default.versionList,
|
|
@@ -9987,8 +10087,19 @@ window.__ModuleLoader__.load({
|
|
|
9987
10087
|
}
|
|
9988
10088
|
function StatusPage(props) {
|
|
9989
10089
|
const t = useT();
|
|
10090
|
+
const [resumedUpdate, setResumedUpdate] = (0, react.useState)(() => pendingStarterUpdate());
|
|
9990
10091
|
const [versionsOpen, setVersionsOpen] = (0, react.useState)(false);
|
|
9991
10092
|
const status = props.status;
|
|
10093
|
+
const answered = status !== null || !props.loading;
|
|
10094
|
+
(0, react.useEffect)(() => {
|
|
10095
|
+
if (resumedUpdate === void 0 || !answered) return;
|
|
10096
|
+
if (status !== null && status.restartPending === void 0 && resumedUpdate.to !== void 0 && status.dshMnemonVersion === resumedUpdate.to) {
|
|
10097
|
+
clearStarterUpdate();
|
|
10098
|
+
setResumedUpdate(void 0);
|
|
10099
|
+
return;
|
|
10100
|
+
}
|
|
10101
|
+
setVersionsOpen(true);
|
|
10102
|
+
}, [answered]);
|
|
9992
10103
|
const reviewError = status?.lifecycle?.current?.lastError;
|
|
9993
10104
|
const storage = status?.storage;
|
|
9994
10105
|
const selectedScopeKind = storage?.activeKind ?? "global";
|
|
@@ -10056,12 +10167,32 @@ window.__ModuleLoader__.load({
|
|
|
10056
10167
|
versionsOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(VersionDialog, {
|
|
10057
10168
|
client: props.client,
|
|
10058
10169
|
writeEnabled: props.writeEnabled,
|
|
10059
|
-
|
|
10170
|
+
resumedUpdate,
|
|
10171
|
+
onClose: () => {
|
|
10172
|
+
setResumedUpdate(void 0);
|
|
10173
|
+
setVersionsOpen(false);
|
|
10174
|
+
},
|
|
10060
10175
|
onRefreshStatus: props.onRefresh
|
|
10061
10176
|
})
|
|
10062
10177
|
]
|
|
10063
10178
|
});
|
|
10064
10179
|
}
|
|
10180
|
+
/**
|
|
10181
|
+
* An installed update waits for DSH to restart: the Host keeps the code it loaded, while DSH has
|
|
10182
|
+
* already swapped in this page. Every Memory System page says so until the restart.
|
|
10183
|
+
*/
|
|
10184
|
+
function RestartReminder({ pending }) {
|
|
10185
|
+
const t = useT();
|
|
10186
|
+
return pending.installed !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Callout, {
|
|
10187
|
+
tone: "warning",
|
|
10188
|
+
title: t("versions.pendingInstalledTitle", { version: pending.installed }),
|
|
10189
|
+
children: t("versions.pendingInstalledDetail", { running: pending.running })
|
|
10190
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Callout, {
|
|
10191
|
+
tone: "warning",
|
|
10192
|
+
title: t("versions.pendingPackagesTitle", { names: (pending.packages ?? []).join(t("config.listSeparator")) }),
|
|
10193
|
+
children: t("versions.pendingPackagesDetail")
|
|
10194
|
+
});
|
|
10195
|
+
}
|
|
10065
10196
|
/** Mnemon Native is one Provider among peers: it has a health card once its CLI is installed or a space uses it. */
|
|
10066
10197
|
function nativeInUse(status) {
|
|
10067
10198
|
return status.commandFound || (status.memoryBodies ?? []).some((body) => body.provider.origin === "native");
|
|
@@ -10901,6 +11032,10 @@ window.__ModuleLoader__.load({
|
|
|
10901
11032
|
children: notice.detail
|
|
10902
11033
|
})
|
|
10903
11034
|
}),
|
|
11035
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Reveal, {
|
|
11036
|
+
className: MnemonView_module_css_default.notice,
|
|
11037
|
+
children: status?.restartPending !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RestartReminder, { pending: status.restartPending })
|
|
11038
|
+
}),
|
|
10904
11039
|
workspaceToast.element,
|
|
10905
11040
|
remoteReadOnly && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
10906
11041
|
className: MnemonView_module_css_default.alert,
|
|
@@ -12055,6 +12190,7 @@ window.__ModuleLoader__.load({
|
|
|
12055
12190
|
activeMemoryWorkspace = void 0;
|
|
12056
12191
|
};
|
|
12057
12192
|
}, "dsh-mnemon: memory workspace entry");
|
|
12193
|
+
ctx.effect(() => reopenAfterStarterUpdate(seats.workspace), "dsh-mnemon: reopen after a Starter update");
|
|
12058
12194
|
const componentSettingsDirectory = createComponentSettingsDirectory(ctx);
|
|
12059
12195
|
const configurationServices = () => ({
|
|
12060
12196
|
componentSettingsDirectory,
|
package/lib/index.js
CHANGED
|
@@ -2376,10 +2376,10 @@ var LiveMnemonRuntime = class {
|
|
|
2376
2376
|
route(request) {
|
|
2377
2377
|
this.assertOpen();
|
|
2378
2378
|
const effectiveAgent = this.agent(request.sessionId);
|
|
2379
|
-
const effectiveWorkspace = effectiveAgent === void 0 ?
|
|
2379
|
+
const effectiveWorkspace = effectiveAgent === void 0 ? this.workspaceForSession(request.sessionId) : this.workspaceForPath(effectiveAgent.session.header?.cwd);
|
|
2380
2380
|
const selectedWorkspace = request.workspaceId === void 0 || request.workspaceId.trim() === "" ? effectiveWorkspace : this.requireWorkspace(request.workspaceId);
|
|
2381
|
-
const
|
|
2382
|
-
const
|
|
2381
|
+
const effectiveGraph = effectiveAgent !== void 0 ? this.forAgent(effectiveAgent) : effectiveWorkspace !== void 0 && isWorkspaceStorageScope(this.current.config.storageScope) ? this.forWorkspacePath(effectiveWorkspace.path) : this.current;
|
|
2382
|
+
const graph = selectedWorkspace === void 0 ? effectiveGraph : isWorkspaceStorageScope(this.current.config.storageScope) ? this.forWorkspacePath(selectedWorkspace.path) : this.current;
|
|
2383
2383
|
const selectedRoot = resolve(graph.directory);
|
|
2384
2384
|
const effectiveRoot = resolve(effectiveGraph.directory);
|
|
2385
2385
|
return {
|
|
@@ -2388,7 +2388,8 @@ var LiveMnemonRuntime = class {
|
|
|
2388
2388
|
...effectiveWorkspace === void 0 ? {} : { effectiveWorkspace },
|
|
2389
2389
|
selectedRoot,
|
|
2390
2390
|
effectiveRoot,
|
|
2391
|
-
aligned: selectedRoot === effectiveRoot
|
|
2391
|
+
aligned: selectedRoot === effectiveRoot,
|
|
2392
|
+
liveSession: effectiveAgent !== void 0
|
|
2392
2393
|
};
|
|
2393
2394
|
}
|
|
2394
2395
|
forWorkspacePath(workspaceRoot) {
|
|
@@ -2424,6 +2425,11 @@ var LiveMnemonRuntime = class {
|
|
|
2424
2425
|
if (workspace === void 0) throw new Error("selected DSH workspace is unavailable");
|
|
2425
2426
|
return workspace;
|
|
2426
2427
|
}
|
|
2428
|
+
workspaceForSession(sessionId) {
|
|
2429
|
+
const normalized = sessionId?.trim();
|
|
2430
|
+
if (normalized === void 0 || normalized === "") return void 0;
|
|
2431
|
+
return this.workspaceRegistry?.list().find((workspace) => workspace.sessionIds?.includes(normalized) === true);
|
|
2432
|
+
}
|
|
2427
2433
|
workspaceForPath(path) {
|
|
2428
2434
|
const normalized = path?.trim();
|
|
2429
2435
|
if (normalized === void 0 || normalized === "") return void 0;
|
|
@@ -2836,6 +2842,112 @@ function reviewCheckpoint(session, maxChars) {
|
|
|
2836
2842
|
return header + (selected.reverse().join("") || "(no eligible text; skip)");
|
|
2837
2843
|
}
|
|
2838
2844
|
//#endregion
|
|
2845
|
+
//#region src/host/plugin-message.ts
|
|
2846
|
+
const MNEMON_PLUGIN_SOURCE = "dsh-mnemon";
|
|
2847
|
+
/** A user-role message this plugin adds to a step, marked with its own source. */
|
|
2848
|
+
function createPluginMessage(text, form) {
|
|
2849
|
+
return structuredClone({
|
|
2850
|
+
id: randomUUID(),
|
|
2851
|
+
role: "user",
|
|
2852
|
+
content: [{
|
|
2853
|
+
type: "text",
|
|
2854
|
+
text
|
|
2855
|
+
}],
|
|
2856
|
+
source: {
|
|
2857
|
+
kind: MNEMON_PLUGIN_SOURCE,
|
|
2858
|
+
form
|
|
2859
|
+
}
|
|
2860
|
+
});
|
|
2861
|
+
}
|
|
2862
|
+
//#endregion
|
|
2863
|
+
//#region src/host/continuation-turn.ts
|
|
2864
|
+
/** The user turn that ends a refused delegated child's tool continuations. */
|
|
2865
|
+
const CONTINUATION_TEXT = "Continue from the tool results above.";
|
|
2866
|
+
/** How a server reports a chat template that found no user query (Ollama, vLLM and others). */
|
|
2867
|
+
const NO_USER_QUERY = /no user query found in messages/iu;
|
|
2868
|
+
const startingChild = new AsyncLocalStorage();
|
|
2869
|
+
function hasUserText(message) {
|
|
2870
|
+
return message.role === "user" && message.content.some((block) => block.type === "text" && typeof block.text === "string" && block.text.trim() !== "");
|
|
2871
|
+
}
|
|
2872
|
+
/**
|
|
2873
|
+
* Some chat templates refuse a request without a user query: Ollama 0.33
|
|
2874
|
+
* serving Qwen3.x answers 500 "no user query found in messages" (#327). A
|
|
2875
|
+
* delegated child's only user turn is its prompt. Once tool results fill the
|
|
2876
|
+
* model's context window, Ollama truncates from the front and drops that
|
|
2877
|
+
* prompt while keeping the tool messages after it.
|
|
2878
|
+
*
|
|
2879
|
+
* Nothing changes until a server refuses a request that way. The refused step
|
|
2880
|
+
* then ends with a short user turn and runs again at once (the server ran no
|
|
2881
|
+
* inference), and each later tool continuation of the same child ends the
|
|
2882
|
+
* same way, since the server always keeps the last message. A route that never
|
|
2883
|
+
* refuses keeps its requests as they are, so a template that shows reasoning
|
|
2884
|
+
* only after the last user query keeps the earlier steps' reasoning.
|
|
2885
|
+
*/
|
|
2886
|
+
function continueAfterRefusal(agent) {
|
|
2887
|
+
if (typeof agent.ctx?.on !== "function") return [];
|
|
2888
|
+
let refused = false;
|
|
2889
|
+
const retried = /* @__PURE__ */ new Set();
|
|
2890
|
+
const turn = () => createPluginMessage(CONTINUATION_TEXT, "instructions");
|
|
2891
|
+
return [agent.ctx.on("agent/request-error", (async (payload, next) => {
|
|
2892
|
+
const step = `${payload.turn}:${payload.step}`;
|
|
2893
|
+
const session = agent.session;
|
|
2894
|
+
if (payload.signal.aborted || payload.step < 2 || retried.has(step) || typeof session.append !== "function" || !NO_USER_QUERY.test(payload.failure?.message ?? "")) return next();
|
|
2895
|
+
retried.add(step);
|
|
2896
|
+
refused = true;
|
|
2897
|
+
session.append("user/message", turn(), { surfaceOp: "append" });
|
|
2898
|
+
return { kind: "retry" };
|
|
2899
|
+
}), { prepend: true }), agent.ctx.on("agent/pre-step", (async (payload, next) => {
|
|
2900
|
+
const decision = await next();
|
|
2901
|
+
if (!refused || payload.step === 1 || payload.signal.aborted || decision.kind !== "enter") return decision;
|
|
2902
|
+
if (payload.messages.length > 0 && decision.messages.length === 0) return decision;
|
|
2903
|
+
if (decision.messages.some(hasUserText)) return decision;
|
|
2904
|
+
return {
|
|
2905
|
+
...decision,
|
|
2906
|
+
messages: [...decision.messages, turn()]
|
|
2907
|
+
};
|
|
2908
|
+
}), { prepend: true })];
|
|
2909
|
+
}
|
|
2910
|
+
/**
|
|
2911
|
+
* Start one delegated child and attach the refusal recovery while DSH
|
|
2912
|
+
* publishes it, before its first step. Async context attributes concurrent
|
|
2913
|
+
* starts, and DSH's ownership check confirms the parent where it exists. A host
|
|
2914
|
+
* that does not report creation leaves the child as it was.
|
|
2915
|
+
*/
|
|
2916
|
+
async function startWithContinuationTurns(host, parent, start) {
|
|
2917
|
+
const pending = Symbol("Mnemon delegated start");
|
|
2918
|
+
const stops = [];
|
|
2919
|
+
const listener = host.on("agent/created", (({ agent }) => {
|
|
2920
|
+
if (startingChild.getStore() !== pending) return;
|
|
2921
|
+
if (typeof host.agents?.isOwnedBy === "function" && !host.agents.isOwnedBy(agent.id, parent)) return;
|
|
2922
|
+
for (const stop of continueAfterRefusal(agent)) if (typeof stop === "function") stops.push(stop);
|
|
2923
|
+
}));
|
|
2924
|
+
const release = async () => {
|
|
2925
|
+
for (const stop of stops.splice(0)) await stop();
|
|
2926
|
+
};
|
|
2927
|
+
let run;
|
|
2928
|
+
try {
|
|
2929
|
+
run = await startingChild.run(pending, start);
|
|
2930
|
+
} catch (error) {
|
|
2931
|
+
await release();
|
|
2932
|
+
throw error;
|
|
2933
|
+
} finally {
|
|
2934
|
+
if (typeof listener === "function") await listener();
|
|
2935
|
+
}
|
|
2936
|
+
const active = run;
|
|
2937
|
+
return {
|
|
2938
|
+
id: active.id,
|
|
2939
|
+
...active.localAgent === void 0 ? {} : { localAgent: active.localAgent },
|
|
2940
|
+
result: active.result,
|
|
2941
|
+
async dispose() {
|
|
2942
|
+
try {
|
|
2943
|
+
await active.dispose();
|
|
2944
|
+
} finally {
|
|
2945
|
+
await release();
|
|
2946
|
+
}
|
|
2947
|
+
}
|
|
2948
|
+
};
|
|
2949
|
+
}
|
|
2950
|
+
//#endregion
|
|
2839
2951
|
//#region src/host/subagent.ts
|
|
2840
2952
|
function evidenceInsights(evidence) {
|
|
2841
2953
|
return evidence.items.map((item) => {
|
|
@@ -4572,7 +4684,8 @@ This is the only completion channel for this run. Do not finish with a plain-tex
|
|
|
4572
4684
|
provider: fixed.provider,
|
|
4573
4685
|
model: fixed.model
|
|
4574
4686
|
};
|
|
4575
|
-
const
|
|
4687
|
+
const host = this.resultRuntime;
|
|
4688
|
+
const start = () => startWithContinuationTurns(host, parent, () => this.subagents.start(provider, {
|
|
4576
4689
|
label,
|
|
4577
4690
|
prompt: [{
|
|
4578
4691
|
type: "text",
|
|
@@ -4584,7 +4697,7 @@ This is the only completion channel for this run. Do not finish with a plain-tex
|
|
|
4584
4697
|
maxDepth: 1,
|
|
4585
4698
|
toolFilter: { allow: [...tools, resultToolName] },
|
|
4586
4699
|
persona: completionPersona
|
|
4587
|
-
});
|
|
4700
|
+
}));
|
|
4588
4701
|
run = operation === "review" ? await startGuardedReview(this.resultRuntime, parent, [...tools, resultToolName], start, (child) => {
|
|
4589
4702
|
reviewChildId = child.id;
|
|
4590
4703
|
}, reviewLayerPolicy()) : await start();
|
|
@@ -5251,21 +5364,6 @@ function llmService(value) {
|
|
|
5251
5364
|
if (typeof value !== "object" || value === null || !("listProviders" in value) || typeof value.listProviders !== "function" || !("listModels" in value) || typeof value.listModels !== "function") return void 0;
|
|
5252
5365
|
return value;
|
|
5253
5366
|
}
|
|
5254
|
-
const MNEMON_PLUGIN_SOURCE = "dsh-mnemon";
|
|
5255
|
-
function createPluginMessage(text, form) {
|
|
5256
|
-
return structuredClone({
|
|
5257
|
-
id: crypto.randomUUID(),
|
|
5258
|
-
role: "user",
|
|
5259
|
-
content: [{
|
|
5260
|
-
type: "text",
|
|
5261
|
-
text
|
|
5262
|
-
}],
|
|
5263
|
-
source: {
|
|
5264
|
-
kind: MNEMON_PLUGIN_SOURCE,
|
|
5265
|
-
form
|
|
5266
|
-
}
|
|
5267
|
-
});
|
|
5268
|
-
}
|
|
5269
5367
|
function isMnemonMessageSource(source) {
|
|
5270
5368
|
if (typeof source !== "object" || source === null) return false;
|
|
5271
5369
|
const { kind, plugin } = source;
|
|
@@ -5891,6 +5989,16 @@ var MnemonLifecycle = class {
|
|
|
5891
5989
|
mutateDocument(sessionId, request, signal = new AbortController().signal) {
|
|
5892
5990
|
return this.coordinator.document(this.liveAgent(sessionId), request, signal);
|
|
5893
5991
|
}
|
|
5992
|
+
/**
|
|
5993
|
+
* The same Document write under a fresh task Agent, for a conversation whose
|
|
5994
|
+
* Agent is not loaded: it archives the least recently used Document to make
|
|
5995
|
+
* room, as the conversation's Agent would.
|
|
5996
|
+
*/
|
|
5997
|
+
mutateDocumentTask(sessionId, request, workspaceRoot, signal = new AbortController().signal) {
|
|
5998
|
+
const root = workspaceRoot?.trim() || this.workspaceRoot(sessionId);
|
|
5999
|
+
if (root === void 0 || root.trim() === "") throw new Error("a selected DSH workspace is required to write a Mnemon Document");
|
|
6000
|
+
return this.runTaskAgent(sessionId, root, signal, (agent) => this.coordinator.document(agent, request, signal));
|
|
6001
|
+
}
|
|
5894
6002
|
archiveDocument(sessionId, id, workspaceRoot, signal = new AbortController().signal) {
|
|
5895
6003
|
const root = workspaceRoot?.trim() || this.workspaceRoot(sessionId);
|
|
5896
6004
|
if (root === void 0 || root.trim() === "") throw new Error("a selected DSH workspace is required to archive a Mnemon Document");
|
|
@@ -5902,6 +6010,11 @@ var MnemonLifecycle = class {
|
|
|
5902
6010
|
placeProvider(sessionId, body, prepared, signal = new AbortController().signal) {
|
|
5903
6011
|
return this.coordinator.placeProvider(this.liveAgent(sessionId), body, prepared, signal);
|
|
5904
6012
|
}
|
|
6013
|
+
/** Choose a new Memory Space's Provider under a fresh task Agent, as Ask Agent does without a loaded conversation Agent. */
|
|
6014
|
+
placeProviderTask(sessionId, body, prepared, workspaceRoot, signal = new AbortController().signal) {
|
|
6015
|
+
const root = workspaceRoot?.trim() || this.workspaceRoot(sessionId);
|
|
6016
|
+
return this.runTaskAgent(sessionId, root, signal, (agent) => this.coordinator.placeProvider(agent, body, prepared, signal));
|
|
6017
|
+
}
|
|
5905
6018
|
maintainMetadata(sessionId, memoryBodyIds, workspaceRoot, signal = new AbortController().signal) {
|
|
5906
6019
|
const root = workspaceRoot?.trim() || this.workspaceRoot(sessionId);
|
|
5907
6020
|
return this.runTaskAgent(sessionId, root, signal, (agent) => this.coordinator.maintainMetadata(agent, memoryBodyIds, signal));
|
|
@@ -6233,8 +6346,15 @@ function isVersionComponentId(value) {
|
|
|
6233
6346
|
}
|
|
6234
6347
|
const MNEMON_MODULE = "github.com/mnemon-dev/mnemon";
|
|
6235
6348
|
const PACKAGE_MANIFEST_PATH = [new URL("../package.json", import.meta.url), new URL("../../package.json", import.meta.url)].map((url) => fileURLToPath(url)).find((path) => manifest$1(path)?.name === DSH_MNEMON_PACKAGE) ?? fileURLToPath(new URL("../package.json", import.meta.url));
|
|
6349
|
+
/**
|
|
6350
|
+
* The version this process loaded. Profiles install with a hoisted layout, so an update rewrites
|
|
6351
|
+
* these same files while the loaded modules stay in memory until DSH restarts.
|
|
6352
|
+
*/
|
|
6353
|
+
const LOADED_VERSION = manifest$1(PACKAGE_MANIFEST_PATH)?.version;
|
|
6236
6354
|
const CHECK_TIMEOUT_MS = 1e4;
|
|
6237
6355
|
const UPDATE_TIMEOUT_MS = 6e5;
|
|
6356
|
+
/** A check waits this long for an update that is finishing, within the browser's 15 s check deadline. */
|
|
6357
|
+
const IN_FLIGHT_WAIT_MS = 3e3;
|
|
6238
6358
|
const MAX_UPDATE_OUTPUT_BYTES = 16384;
|
|
6239
6359
|
async function settledWithin(promise, fallback, timeoutMs = 11e3) {
|
|
6240
6360
|
let timer;
|
|
@@ -6353,6 +6473,10 @@ async function fetchNpmLatest(name, tag = "latest") {
|
|
|
6353
6473
|
function dependencySpec(profile, name = DSH_MNEMON_PACKAGE) {
|
|
6354
6474
|
return profile?.dependencies?.[name] ?? profile?.devDependencies?.[name];
|
|
6355
6475
|
}
|
|
6476
|
+
/** A dependency the Profile records at one exact version, as DSH's installer writes it. */
|
|
6477
|
+
function exactVersion(spec) {
|
|
6478
|
+
return spec !== void 0 && /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(spec) ? spec : void 0;
|
|
6479
|
+
}
|
|
6356
6480
|
function isLinkSpec(spec) {
|
|
6357
6481
|
return spec !== void 0 && /^(?:link|file|workspace):|^\.{1,2}(?:[/\\]|$)/.test(spec);
|
|
6358
6482
|
}
|
|
@@ -6427,6 +6551,22 @@ async function resultOrThrow(runner, command, args, timeoutMs, options = {}) {
|
|
|
6427
6551
|
}
|
|
6428
6552
|
return result;
|
|
6429
6553
|
}
|
|
6554
|
+
/** DSH's failure code with the DSH a release needs, or with the first line of its diagnostic. */
|
|
6555
|
+
function dshFailure(change) {
|
|
6556
|
+
const reason = change.error?.code ?? change.application;
|
|
6557
|
+
const incompatible = change.error?.incompatible ?? [];
|
|
6558
|
+
const peers = incompatible.flatMap((plugin) => Object.entries(plugin.peers ?? {}).map(([name, range]) => `${name} ${range}`));
|
|
6559
|
+
if (peers.length > 0) {
|
|
6560
|
+
const runtime = incompatible.find((plugin) => plugin.runtimeVersion !== void 0)?.runtimeVersion;
|
|
6561
|
+
return `${reason} (requires ${peers.join(", ")}${runtime === void 0 ? "" : `; this DSH is ${runtime}`})`;
|
|
6562
|
+
}
|
|
6563
|
+
const lines = (change.error?.diagnostic ?? change.packageResult?.output ?? "").split("\n").map((line) => line.trim()).filter((line) => line !== "");
|
|
6564
|
+
const line = lines.findLast((line) => /ERR_PNPM_[A-Z_]+/.test(line)) ?? lines.findLast((line) => /^(?:\[?error\]?\b|ERROR\b)|\brejected\b/i.test(line)) ?? lines.at(-1);
|
|
6565
|
+
const kind = change.packageResult?.kind;
|
|
6566
|
+
const detail = [kind === void 0 || kind === "unknown" || line?.includes(kind) === true ? void 0 : kind, line?.slice(0, 300)].filter(Boolean).join(": ");
|
|
6567
|
+
const log = change.packageResult?.logPath;
|
|
6568
|
+
return `${reason}${detail === "" ? "" : ` (${detail})`}${log === void 0 || log === "" ? "" : `; log: ${log}`}`;
|
|
6569
|
+
}
|
|
6430
6570
|
function updateOutput(result) {
|
|
6431
6571
|
const output = [result.stdout.trim(), result.stderr.trim()].filter(Boolean).join("\n").trim();
|
|
6432
6572
|
return output === "" ? void 0 : output.slice(-4e3);
|
|
@@ -6449,6 +6589,9 @@ function samePath(left, right) {
|
|
|
6449
6589
|
}
|
|
6450
6590
|
}
|
|
6451
6591
|
var VersionUpdateManager = class {
|
|
6592
|
+
/** The version this Host runs; an update changes what is installed, not what is loaded. */
|
|
6593
|
+
runningVersion;
|
|
6594
|
+
/** The Starter the last update installed, read only while the files on disk cannot be. */
|
|
6452
6595
|
dshMnemonVersion;
|
|
6453
6596
|
packageManifestPath;
|
|
6454
6597
|
dshHome;
|
|
@@ -6457,20 +6600,73 @@ var VersionUpdateManager = class {
|
|
|
6457
6600
|
executable;
|
|
6458
6601
|
fetchNpmLatest;
|
|
6459
6602
|
fetchMnemonLatest;
|
|
6460
|
-
|
|
6461
|
-
|
|
6603
|
+
bundleInstallerOf;
|
|
6604
|
+
runningProfile;
|
|
6605
|
+
/** What Check versions updated while this Host runs, each with the version it replaced. */
|
|
6606
|
+
pendingRestart = /* @__PURE__ */ new Map();
|
|
6607
|
+
inFlight;
|
|
6608
|
+
lastUpdate;
|
|
6462
6609
|
constructor(dependencies = {}) {
|
|
6463
6610
|
this.packageManifestPath = dependencies.packageManifestPath ?? PACKAGE_MANIFEST_PATH;
|
|
6464
|
-
this.
|
|
6611
|
+
this.runningVersion = (dependencies.packageManifestPath === void 0 ? LOADED_VERSION : void 0) ?? manifest$1(this.packageManifestPath)?.version ?? "0.0.0";
|
|
6612
|
+
this.dshMnemonVersion = this.runningVersion;
|
|
6465
6613
|
this.dshHome = dependencies.dshHome ?? (process.env.DSH_HOME?.trim() || join(homedir(), ".dsh"));
|
|
6466
6614
|
this.mnemonCliPath = dependencies.mnemonCliPath ?? (() => findMnemonCommand({}));
|
|
6467
6615
|
this.processRunner = dependencies.processRunner ?? runProcess;
|
|
6468
6616
|
this.executable = dependencies.resolveExecutable ?? resolveExecutable;
|
|
6469
6617
|
this.fetchNpmLatest = dependencies.fetchNpmLatest ?? fetchNpmLatest;
|
|
6470
6618
|
this.fetchMnemonLatest = dependencies.fetchMnemonLatest ?? (() => this.fetchNpmLatest(MNEMON_NPM_PACKAGE));
|
|
6619
|
+
this.bundleInstallerOf = dependencies.bundleInstaller ?? (() => void 0);
|
|
6620
|
+
this.runningProfile = dependencies.runningProfile ?? (() => void 0);
|
|
6471
6621
|
}
|
|
6622
|
+
/**
|
|
6623
|
+
* DSH's own installer, only for the profile this Host runs in, so it never writes another
|
|
6624
|
+
* profile, and only while DSH has a package manager to run.
|
|
6625
|
+
*/
|
|
6626
|
+
bundleInstaller(install) {
|
|
6627
|
+
if (install.mode !== "npm" || install.profileDir === void 0) return void 0;
|
|
6628
|
+
const installer = this.bundleInstallerOf();
|
|
6629
|
+
if (typeof installer?.installBundle !== "function" || typeof installer.listBundles !== "function") return void 0;
|
|
6630
|
+
const running = this.runningProfile();
|
|
6631
|
+
if (running === void 0 || !running.packageManager && this.executable("pnpm") === void 0) return void 0;
|
|
6632
|
+
try {
|
|
6633
|
+
return realpathSync(running.dir) === realpathSync(install.profileDir) ? installer : void 0;
|
|
6634
|
+
} catch {
|
|
6635
|
+
return;
|
|
6636
|
+
}
|
|
6637
|
+
}
|
|
6638
|
+
/** The Starter installed now, which DSH loads at its next start, however it was installed. */
|
|
6472
6639
|
get currentDshMnemonVersion() {
|
|
6473
|
-
return this.
|
|
6640
|
+
return this.installedVersion(inspectDshInstall(this.packageManifestPath, this.dshHome));
|
|
6641
|
+
}
|
|
6642
|
+
installedVersion(install) {
|
|
6643
|
+
const recorded = install.mode === "npm" && install.profileDir !== void 0 ? exactVersion(dependencySpec(manifest$1(join(install.profileDir, "package.json")))) : void 0;
|
|
6644
|
+
if (recorded !== void 0) return recorded;
|
|
6645
|
+
return manifest$1(install.mode === "npm" && install.profileDir !== void 0 ? packageAt(install.profileDir, DSH_MNEMON_PACKAGE) ?? this.packageManifestPath : this.packageManifestPath)?.version ?? this.dshMnemonVersion;
|
|
6646
|
+
}
|
|
6647
|
+
/** A package Check versions updated, and still not the version it replaced. */
|
|
6648
|
+
replaced(id, current) {
|
|
6649
|
+
return this.pendingRestart.has(id) && current !== this.pendingRestart.get(id);
|
|
6650
|
+
}
|
|
6651
|
+
remember(id, previousVersion) {
|
|
6652
|
+
if (!this.pendingRestart.has(id)) this.pendingRestart.set(id, previousVersion);
|
|
6653
|
+
}
|
|
6654
|
+
/**
|
|
6655
|
+
* What waits for a DSH restart: a Starter on disk other than the one this Host runs, however it
|
|
6656
|
+
* was installed, and the packages Check versions updated on their own.
|
|
6657
|
+
*/
|
|
6658
|
+
restartStatus() {
|
|
6659
|
+
const install = inspectDshInstall(this.packageManifestPath, this.dshHome);
|
|
6660
|
+
const installed = this.installedVersion(install);
|
|
6661
|
+
const pending = [...this.pendingRestart.keys()].filter((id) => id !== DSH_MNEMON_PACKAGE);
|
|
6662
|
+
const rows = pending.length === 0 ? [] : this.subpackages(install).map((row) => row.status);
|
|
6663
|
+
const packages = pending.filter((id) => this.replaced(id, rows.find((row) => row.id === id)?.current)).sort();
|
|
6664
|
+
if (installed === this.runningVersion && packages.length === 0) return void 0;
|
|
6665
|
+
return {
|
|
6666
|
+
running: this.runningVersion,
|
|
6667
|
+
...installed === this.runningVersion ? {} : { installed },
|
|
6668
|
+
...packages.length === 0 ? {} : { packages }
|
|
6669
|
+
};
|
|
6474
6670
|
}
|
|
6475
6671
|
async latestPackageVersion(name, current) {
|
|
6476
6672
|
const channel = current === void 0 ? void 0 : parseSemver(current)?.prerelease[0];
|
|
@@ -6634,19 +6830,24 @@ var VersionUpdateManager = class {
|
|
|
6634
6830
|
subpackages(install) {
|
|
6635
6831
|
const starterPath = install.mode === "npm" && install.profileDir !== void 0 ? packageAt(install.profileDir, DSH_MNEMON_PACKAGE) ?? this.packageManifestPath : this.packageManifestPath;
|
|
6636
6832
|
const starter = manifest$1(starterPath);
|
|
6833
|
+
const starterReplaced = this.installedVersion(install) !== this.runningVersion;
|
|
6637
6834
|
const profile = install.profileDir === void 0 ? void 0 : manifest$1(join(install.profileDir, "package.json"));
|
|
6638
|
-
|
|
6835
|
+
const names = [.../* @__PURE__ */ new Set([
|
|
6639
6836
|
...Object.keys(starter?.dependencies ?? {}),
|
|
6640
6837
|
...Object.keys(profile?.dependencies ?? {}),
|
|
6641
6838
|
...Object.keys(profile?.devDependencies ?? {})
|
|
6642
|
-
])].filter((name) => SUBPACKAGE.test(name)).sort()
|
|
6839
|
+
])].filter((name) => SUBPACKAGE.test(name)).sort();
|
|
6840
|
+
const installer = this.bundleInstaller(install);
|
|
6841
|
+
return names.map((name) => {
|
|
6643
6842
|
const directSpec = dependencySpec(profile, name);
|
|
6644
6843
|
const managedBy = directSpec === void 0 ? "starter" : "profile";
|
|
6645
6844
|
const path = packageAt(directSpec === void 0 ? dirname(starterPath) : install.profileDir, name);
|
|
6646
6845
|
const value = path === void 0 ? void 0 : manifest$1(path);
|
|
6846
|
+
const current = (managedBy === "profile" ? exactVersion(directSpec) : void 0) ?? value?.version;
|
|
6647
6847
|
const linked = isLinkSpec(directSpec ?? starter?.dependencies?.[name]) || install.mode === "link" || path !== void 0 && !realpathSync(dirname(path)).replaceAll("\\", "/").includes("/node_modules/");
|
|
6648
6848
|
const mode = linked ? "link" : path === void 0 ? "missing" : install.mode === "npm" ? "npm" : "manual";
|
|
6649
|
-
const
|
|
6849
|
+
const throughDsh = managedBy === "profile" && mode === "npm" && installer !== void 0 && value?.dsh?.bundle !== void 0;
|
|
6850
|
+
const supported = managedBy === "profile" && mode === "npm" && (throughDsh || this.executable("pnpm") !== void 0);
|
|
6650
6851
|
return {
|
|
6651
6852
|
...path === void 0 ? {} : { manifestPath: path },
|
|
6652
6853
|
status: {
|
|
@@ -6655,19 +6856,20 @@ var VersionUpdateManager = class {
|
|
|
6655
6856
|
kind: SUBPACKAGE.exec(name)[1],
|
|
6656
6857
|
managedBy,
|
|
6657
6858
|
...starter?.dependencies?.[name] === void 0 ? {} : { expectedVersion: starter.dependencies[name] },
|
|
6658
|
-
...
|
|
6859
|
+
...current === void 0 ? {} : { current },
|
|
6659
6860
|
...path === void 0 ? {} : { installPath: realpathSync(dirname(path)) },
|
|
6660
6861
|
...install.profileName === void 0 ? {} : { installProfile: install.profileName },
|
|
6661
6862
|
installMode: mode,
|
|
6662
6863
|
outdated: false,
|
|
6663
6864
|
updateSupported: supported,
|
|
6664
|
-
updateHint: linked ? "link" : managedBy === "starter" ? "starter" : supported ? "pnpm" : mode === "npm" ? "pnpm-missing" : "manual",
|
|
6665
|
-
restartRequired: this.
|
|
6865
|
+
updateHint: linked ? "link" : managedBy === "starter" ? "starter" : throughDsh ? "dsh" : supported ? "pnpm" : mode === "npm" ? "pnpm-missing" : "manual",
|
|
6866
|
+
restartRequired: this.replaced(name, current) || starterReplaced
|
|
6666
6867
|
}
|
|
6667
6868
|
};
|
|
6668
6869
|
});
|
|
6669
6870
|
}
|
|
6670
6871
|
async check() {
|
|
6872
|
+
if (this.inFlight !== void 0) await settledWithin(this.inFlight, void 0, IN_FLIGHT_WAIT_MS);
|
|
6671
6873
|
const dshInstall = inspectDshInstall(this.packageManifestPath, this.dshHome);
|
|
6672
6874
|
const [mnemonLocal, mnemonLatest, dshLatest, packages] = await Promise.all([
|
|
6673
6875
|
settledWithin(this.inspectMnemon(), { install: {
|
|
@@ -6686,25 +6888,28 @@ var VersionUpdateManager = class {
|
|
|
6686
6888
|
}))
|
|
6687
6889
|
]);
|
|
6688
6890
|
const pnpm = this.executable("pnpm");
|
|
6891
|
+
const installer = this.bundleInstaller(dshInstall);
|
|
6689
6892
|
const mnemonOutdated = mnemonLocal.current !== void 0 && mnemonLatest !== void 0 && compareVersions(mnemonLocal.current, mnemonLatest) < 0;
|
|
6690
|
-
const
|
|
6893
|
+
const installed = this.installedVersion(dshInstall);
|
|
6894
|
+
const dshOutdated = dshLatest !== void 0 && compareVersions(installed, dshLatest) < 0;
|
|
6691
6895
|
const mnemonSupported = mnemonLocal.install.updateCommand !== void 0;
|
|
6692
|
-
const dshSupported = dshInstall.mode === "npm" && dshInstall.profileDir !== void 0 && pnpm !== void 0;
|
|
6896
|
+
const dshSupported = dshInstall.mode === "npm" && dshInstall.profileDir !== void 0 && (installer !== void 0 || pnpm !== void 0);
|
|
6693
6897
|
return {
|
|
6694
6898
|
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6899
|
+
...this.lastUpdate === void 0 ? {} : { lastUpdate: this.lastUpdate },
|
|
6695
6900
|
components: [{
|
|
6696
6901
|
id: "dsh-mnemon",
|
|
6697
6902
|
name: "dsh-mnemon",
|
|
6698
6903
|
...dshInstall.profileName === void 0 ? {} : { installProfile: dshInstall.profileName },
|
|
6699
6904
|
installPath: dshInstall.locationDir,
|
|
6700
|
-
current:
|
|
6905
|
+
current: installed,
|
|
6701
6906
|
...dshLatest === void 0 ? {} : { latest: dshLatest },
|
|
6702
6907
|
outdated: dshOutdated,
|
|
6703
6908
|
installMode: dshInstall.mode,
|
|
6704
6909
|
updateSupported: dshSupported,
|
|
6705
6910
|
packages,
|
|
6706
|
-
restartRequired: this.
|
|
6707
|
-
updateHint: dshInstall.mode === "npm" ? dshSupported ? "pnpm" : "pnpm-missing" : dshInstall.mode === "link" ? "link" : "manual",
|
|
6911
|
+
restartRequired: this.restartStatus() !== void 0,
|
|
6912
|
+
updateHint: dshInstall.mode === "npm" ? installer !== void 0 ? "dsh" : dshSupported ? "pnpm" : "pnpm-missing" : dshInstall.mode === "link" ? "link" : "manual",
|
|
6708
6913
|
...dshLatest === void 0 ? { checkError: "latest-unavailable" } : {}
|
|
6709
6914
|
}, {
|
|
6710
6915
|
id: "mnemon",
|
|
@@ -6721,12 +6926,26 @@ var VersionUpdateManager = class {
|
|
|
6721
6926
|
};
|
|
6722
6927
|
}
|
|
6723
6928
|
async update(component) {
|
|
6724
|
-
if (this.
|
|
6725
|
-
|
|
6929
|
+
if (this.inFlight !== void 0) throw new Error("A version update is already in progress");
|
|
6930
|
+
const run = this.performUpdate(component);
|
|
6931
|
+
this.inFlight = run;
|
|
6726
6932
|
try {
|
|
6727
|
-
|
|
6933
|
+
const result = await run;
|
|
6934
|
+
this.lastUpdate = {
|
|
6935
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6936
|
+
component,
|
|
6937
|
+
result
|
|
6938
|
+
};
|
|
6939
|
+
return result;
|
|
6940
|
+
} catch (error) {
|
|
6941
|
+
this.lastUpdate = {
|
|
6942
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6943
|
+
component,
|
|
6944
|
+
error: error instanceof Error ? error.message : String(error)
|
|
6945
|
+
};
|
|
6946
|
+
throw error;
|
|
6728
6947
|
} finally {
|
|
6729
|
-
this.
|
|
6948
|
+
this.inFlight = void 0;
|
|
6730
6949
|
}
|
|
6731
6950
|
}
|
|
6732
6951
|
async performUpdate(component) {
|
|
@@ -6768,8 +6987,10 @@ var VersionUpdateManager = class {
|
|
|
6768
6987
|
previousVersion,
|
|
6769
6988
|
currentVersion: previousVersion,
|
|
6770
6989
|
updated: false,
|
|
6771
|
-
restartRequired: this.
|
|
6990
|
+
restartRequired: component === DSH_MNEMON_PACKAGE ? previousVersion !== this.runningVersion : this.replaced(component, previousVersion)
|
|
6772
6991
|
};
|
|
6992
|
+
const installer = child === void 0 || child.updateHint === "dsh" ? this.bundleInstaller(install) : void 0;
|
|
6993
|
+
if (installer !== void 0) return this.updateThroughDsh(installer, component, previousVersion, latest);
|
|
6773
6994
|
const pnpm = this.executable("pnpm");
|
|
6774
6995
|
if (install.mode !== "npm" || install.profileDir === void 0 || pnpm === void 0) throw new Error("This dsh-mnemon installation cannot be updated automatically");
|
|
6775
6996
|
const output = await resultOrThrow(this.processRunner, pnpm, [
|
|
@@ -6781,7 +7002,7 @@ var VersionUpdateManager = class {
|
|
|
6781
7002
|
if (installedVersion !== latest) throw new Error(`${component} update did not install the requested version ${latest}; found ${installedVersion ?? "no package"}`);
|
|
6782
7003
|
const outputText = updateOutput(output);
|
|
6783
7004
|
if (component === DSH_MNEMON_PACKAGE) this.dshMnemonVersion = installedVersion;
|
|
6784
|
-
this.
|
|
7005
|
+
this.remember(component, previousVersion);
|
|
6785
7006
|
return {
|
|
6786
7007
|
component,
|
|
6787
7008
|
previousVersion,
|
|
@@ -6791,6 +7012,33 @@ var VersionUpdateManager = class {
|
|
|
6791
7012
|
...outputText === void 0 ? {} : { output: outputText }
|
|
6792
7013
|
};
|
|
6793
7014
|
}
|
|
7015
|
+
/**
|
|
7016
|
+
* An exact version installs at once, outside pnpm's release-age window, and for the Starter pins
|
|
7017
|
+
* its tested components. The update replaces the package only; which bundles run stays as it was.
|
|
7018
|
+
*/
|
|
7019
|
+
async updateThroughDsh(installer, component, previousVersion, latest) {
|
|
7020
|
+
const spec = `${component}@${latest}`;
|
|
7021
|
+
let change;
|
|
7022
|
+
try {
|
|
7023
|
+
change = await installer.installBundle(spec, { enabled: false });
|
|
7024
|
+
} catch (error) {
|
|
7025
|
+
throw new Error(`DSH could not install ${spec}: ${error instanceof Error ? error.message : String(error)}`);
|
|
7026
|
+
}
|
|
7027
|
+
const output = change.packageResult?.output?.trim();
|
|
7028
|
+
if (change.application === "failed" || change.application === "cancelled") throw new Error(`DSH could not install ${spec}: ${dshFailure(change)}`);
|
|
7029
|
+
const installedVersion = (await installer.listBundles()).find((bundle) => bundle.name === component)?.version;
|
|
7030
|
+
if (installedVersion !== latest) throw new Error(`${component} update did not install the requested version ${latest}; found ${installedVersion ?? "no package"}`);
|
|
7031
|
+
if (component === DSH_MNEMON_PACKAGE) this.dshMnemonVersion = installedVersion;
|
|
7032
|
+
this.remember(component, previousVersion);
|
|
7033
|
+
return {
|
|
7034
|
+
component,
|
|
7035
|
+
previousVersion,
|
|
7036
|
+
currentVersion: installedVersion,
|
|
7037
|
+
updated: true,
|
|
7038
|
+
restartRequired: true,
|
|
7039
|
+
...output === void 0 || output === "" ? {} : { output: output.slice(-4e3) }
|
|
7040
|
+
};
|
|
7041
|
+
}
|
|
6794
7042
|
};
|
|
6795
7043
|
//#endregion
|
|
6796
7044
|
//#region src/host/rpc.ts
|
|
@@ -6970,7 +7218,13 @@ async function assisted(runtime, lifecycle, typeId, operation, input, signal, ta
|
|
|
6970
7218
|
if (operation === "mutate") {
|
|
6971
7219
|
requireCapability(runtime, typeId, "write");
|
|
6972
7220
|
const request = input;
|
|
6973
|
-
|
|
7221
|
+
if (runtime.aligned && runtime.liveSession && sessionId !== "") return lifecycle.mutateDocument(sessionId, request, signal);
|
|
7222
|
+
try {
|
|
7223
|
+
return await runtime.source(typeId).mutate("mutate", request, signal);
|
|
7224
|
+
} catch (error) {
|
|
7225
|
+
if (!runtime.aligned || sessionId === "" || !sourceFailure(error, "document-capacity")) throw error;
|
|
7226
|
+
return lifecycle.mutateDocumentTask(sessionId, request, workspaceRoot, signal);
|
|
7227
|
+
}
|
|
6974
7228
|
}
|
|
6975
7229
|
}
|
|
6976
7230
|
if (typeId !== "memory-spaces") throw new Error("unsupported Source assistance operation");
|
|
@@ -6994,10 +7248,11 @@ async function assisted(runtime, lifecycle, typeId, operation, input, signal, ta
|
|
|
6994
7248
|
if (request.placement === void 0) return source.mutate("body-create", request, signal);
|
|
6995
7249
|
requireAligned(runtime);
|
|
6996
7250
|
const prepared = await source.read("prepare-body-placement", request, signal);
|
|
6997
|
-
const
|
|
7251
|
+
const body = {
|
|
6998
7252
|
name: request.name,
|
|
6999
7253
|
description: request.description
|
|
7000
|
-
}
|
|
7254
|
+
};
|
|
7255
|
+
const placementDecision = runtime.liveSession ? await lifecycle.placeProvider(sessionId, body, prepared, signal) : await lifecycle.placeProviderTask(sessionId, body, prepared, workspaceRoot, signal);
|
|
7001
7256
|
return source.mutate("body-create", {
|
|
7002
7257
|
request,
|
|
7003
7258
|
placementDecision
|
|
@@ -7082,6 +7337,10 @@ function createReadHandler(input, lifecycle, versions) {
|
|
|
7082
7337
|
documents = await runtime.source("documents").read("snapshot", null, signal);
|
|
7083
7338
|
} catch {}
|
|
7084
7339
|
const composition = await compositionStatus(runtime);
|
|
7340
|
+
let restartPending;
|
|
7341
|
+
try {
|
|
7342
|
+
restartPending = versions?.restartStatus();
|
|
7343
|
+
} catch {}
|
|
7085
7344
|
return success$1({
|
|
7086
7345
|
...composition.sources.some((source) => source.sourceTypeId === "memory-spaces") ? await runtime.source("memory-spaces").read(endpoint, payload, signal) : {
|
|
7087
7346
|
healthy: composition.evaluation.state === "ready",
|
|
@@ -7093,7 +7352,8 @@ function createReadHandler(input, lifecycle, versions) {
|
|
|
7093
7352
|
writeEnabled: runtime.graph.config.writeEnabled,
|
|
7094
7353
|
defaultRecallLimit: runtime.graph.config.defaultRecallLimit
|
|
7095
7354
|
},
|
|
7096
|
-
...versions === void 0 ? {} : { dshMnemonVersion: versions.
|
|
7355
|
+
...versions === void 0 ? {} : { dshMnemonVersion: versions.runningVersion },
|
|
7356
|
+
...restartPending === void 0 ? {} : { restartPending },
|
|
7097
7357
|
...lifecycle === void 0 ? {} : { lifecycle: lifecycle.snapshot(runtime.scope.sessionId, isWorkspaceStorageScope(runtime.graph.config.storageScope) ? runtime.scope.workspaceId : void 0) },
|
|
7098
7358
|
...documents === void 0 ? {} : { documents },
|
|
7099
7359
|
memorySystem: composition,
|
|
@@ -7248,7 +7508,7 @@ function createWriteHandler(input, lifecycle, versions) {
|
|
|
7248
7508
|
}
|
|
7249
7509
|
if (Object.hasOwn(SPACE_WRITE_CAPABILITIES, endpoint)) {
|
|
7250
7510
|
requireCapability(runtime, "memory-spaces", SPACE_WRITE_CAPABILITIES[endpoint]);
|
|
7251
|
-
if (endpoint === "remember" && lifecycle !== void 0 && runtime.aligned && runtime.scope.sessionId) return success$1(await lifecycle.remember(runtime.scope.sessionId, {
|
|
7511
|
+
if (endpoint === "remember" && lifecycle !== void 0 && runtime.aligned && runtime.liveSession && runtime.scope.sessionId) return success$1(await lifecycle.remember(runtime.scope.sessionId, {
|
|
7252
7512
|
...payload,
|
|
7253
7513
|
source: "user"
|
|
7254
7514
|
}, signal));
|
|
@@ -9156,8 +9416,8 @@ function createViewHandler(runtime, engine, management, access, lifecycle, insta
|
|
|
9156
9416
|
...sessionId === void 0 ? {} : { sessionId },
|
|
9157
9417
|
...selectedWorkspaceId === void 0 ? {} : { workspaceId: selectedWorkspaceId }
|
|
9158
9418
|
});
|
|
9159
|
-
const
|
|
9160
|
-
const
|
|
9419
|
+
const sessionWorkspace = lifecycle?.workspaceRoot(sessionId) ?? route.effectiveWorkspace?.path;
|
|
9420
|
+
const workspaceId = route.selectedWorkspace?.path ?? sessionWorkspace;
|
|
9161
9421
|
const aligned = route.aligned && (route.selectedWorkspace === void 0 || sessionId === void 0 || sessionWorkspace !== void 0 && resolve(route.selectedWorkspace.path) === resolve(sessionWorkspace));
|
|
9162
9422
|
const config = management.resolveConfig(runtime.config);
|
|
9163
9423
|
const scope = {
|
|
@@ -10276,7 +10536,18 @@ function apply(rawContext, rawConfig = {}) {
|
|
|
10276
10536
|
ctx.inject(["connection", "webServer"], (webContext) => {
|
|
10277
10537
|
const connection = Context.is(webContext) ? webContext.extend({ webServer: webContext.get("webServer") }).connection : webContext.connection;
|
|
10278
10538
|
if (connection === void 0) return;
|
|
10279
|
-
const
|
|
10539
|
+
const versions = new VersionUpdateManager({
|
|
10540
|
+
mnemonCliPath: () => runtime.config.cliPath,
|
|
10541
|
+
bundleInstaller: () => ctx.get("pluginManager"),
|
|
10542
|
+
runningProfile: () => {
|
|
10543
|
+
const profile = ctx.get("profileContext");
|
|
10544
|
+
return typeof profile?.dir === "string" ? {
|
|
10545
|
+
dir: profile.dir,
|
|
10546
|
+
packageManager: profile.packageManager !== void 0
|
|
10547
|
+
} : void 0;
|
|
10548
|
+
}
|
|
10549
|
+
});
|
|
10550
|
+
const rpc = registerRpc(connection, runtime, lifecycle, versions);
|
|
10280
10551
|
const settings = registerSettingsRpc(connection, hostSettings);
|
|
10281
10552
|
const view = registerViewRpc(connection, runtime, extensions, memoryPlugins, lifecycle, pluginInstallation);
|
|
10282
10553
|
if (Context.is(webContext)) new MnemonRemoteService(webContext, {
|
|
@@ -268,6 +268,10 @@ export declare const zh: {
|
|
|
268
268
|
'versions.updated': string;
|
|
269
269
|
'versions.alreadyCurrent': string;
|
|
270
270
|
'versions.restartRequired': string;
|
|
271
|
+
'versions.pendingInstalledTitle': string;
|
|
272
|
+
'versions.pendingInstalledDetail': string;
|
|
273
|
+
'versions.pendingPackagesTitle': string;
|
|
274
|
+
'versions.pendingPackagesDetail': string;
|
|
271
275
|
'versions.checkedAt': string;
|
|
272
276
|
'versions.latestUnavailable': string;
|
|
273
277
|
'versions.modeHomebrew': string;
|
|
@@ -279,6 +283,7 @@ export declare const zh: {
|
|
|
279
283
|
'versions.hintHomebrew': string;
|
|
280
284
|
'versions.hintBrewMissing': string;
|
|
281
285
|
'versions.hintGo': string;
|
|
286
|
+
'versions.hintDsh': string;
|
|
282
287
|
'versions.hintPnpm': string;
|
|
283
288
|
'versions.hintPnpmMissing': string;
|
|
284
289
|
'versions.hintLink': string;
|
|
@@ -486,7 +486,10 @@ export interface StatusView {
|
|
|
486
486
|
healthy: boolean;
|
|
487
487
|
error?: string;
|
|
488
488
|
version?: string;
|
|
489
|
+
/** The dsh-mnemon version this Host runs, which an installed update replaces only when DSH restarts. */
|
|
489
490
|
dshMnemonVersion?: string;
|
|
491
|
+
/** Updates installed while this Host runs; they load when DSH restarts. */
|
|
492
|
+
restartPending?: VersionRestartStatus;
|
|
490
493
|
cliPath: string;
|
|
491
494
|
commandFound: boolean;
|
|
492
495
|
dataDir: string;
|
|
@@ -606,6 +609,24 @@ export interface VersionPackageStatus extends VersionComponentStatus {
|
|
|
606
609
|
export interface VersionStatus {
|
|
607
610
|
checkedAt: string;
|
|
608
611
|
components: VersionComponentStatus[];
|
|
612
|
+
/** How the last update this Host ran from Check versions ended, for a page DSH swapped in meanwhile. */
|
|
613
|
+
lastUpdate?: VersionUpdateOutcome;
|
|
614
|
+
}
|
|
615
|
+
export interface VersionUpdateOutcome {
|
|
616
|
+
at: string;
|
|
617
|
+
component: VersionComponentId;
|
|
618
|
+
/** The update's reply, when it ended without an error. */
|
|
619
|
+
result?: VersionUpdateResult;
|
|
620
|
+
/** Why it failed, when it did. */
|
|
621
|
+
error?: string;
|
|
622
|
+
}
|
|
623
|
+
export interface VersionRestartStatus {
|
|
624
|
+
/** The dsh-mnemon version this Host runs. */
|
|
625
|
+
running: string;
|
|
626
|
+
/** The dsh-mnemon version now installed, when it differs, however it was installed: Check versions or `dsh plugin`, for example. */
|
|
627
|
+
installed?: string;
|
|
628
|
+
/** Packages Check versions updated on their own. */
|
|
629
|
+
packages?: VersionPackageId[];
|
|
609
630
|
}
|
|
610
631
|
export interface VersionUpdateResult {
|
|
611
632
|
component: VersionComponentId;
|
package/package.json
CHANGED