dsh-nextsteps 1.4.4 → 1.4.6
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.js +33 -25
- package/index.js +5 -1
- package/package.json +1 -1
package/client.js
CHANGED
|
@@ -369,6 +369,16 @@ window.__ModuleLoader__.load({
|
|
|
369
369
|
'zh-CN': {"header":"建议的后续操作","srFollowupSent":"后续操作已发送","sendFailed":"发送失败:","intro":"在每个智能体回合完成后的下方推荐下一步提示——单击即可发送。","setLanguage":"语言","setLanguageTip":"后续操作提示将以此语言生成。“自动”会跟随对话语言。","optAuto":"自动(跟随对话)","setModel":"模型","setModelTip":"生成建议的模型。自动会跟随对话所用的模型。","optModelAuto":"自动(与对话相同的模型)","modelUnavailable":"此安装没有可用的模型列表","setMax":"每回合提示数","setMaxTip":"模型应生成的建议提示数量(1-6)。","setHeader":"显示标题","setHeaderTip":"卡片上方的小标题“建议的后续操作”。","updates":"更新","current":"版本","checking":"检查中…","upToDate":"已是最新","available":"{v} 可用","manualCopy":"开发或重命名的副本——请手动更新。","installing":"正在安装 {v}…","restartMsg":"版本 {v} 已安装。请重启 dsh 以使用。","noReleases":"尚未发布任何版本","checkFailed":"检查更新失败({e})","updateNow":"立即更新","check":"检查更新","openRelease":"打开发布页","releaseNotes":"发布说明","repo":"GitHub 仓库","issues":"反馈问题"}
|
|
370
370
|
};
|
|
371
371
|
let pluginSettings = { lang: 'auto', maxFollowups: 3, showHeader: true };
|
|
372
|
+
let updateManager = undefined;
|
|
373
|
+
|
|
374
|
+
function compareVersions(a, b) {
|
|
375
|
+
const pa = String(a ?? '').replace(/^v/, '').split('.').map((part) => Number(part) || 0);
|
|
376
|
+
const pb = String(b ?? '').replace(/^v/, '').split('.').map((part) => Number(part) || 0);
|
|
377
|
+
for (let index = 0; index < Math.max(pa.length, pb.length); index += 1) {
|
|
378
|
+
if ((pa[index] ?? 0) !== (pb[index] ?? 0)) return (pa[index] ?? 0) < (pb[index] ?? 0) ? -1 : 1;
|
|
379
|
+
}
|
|
380
|
+
return 0;
|
|
381
|
+
}
|
|
372
382
|
let pluginVersion;
|
|
373
383
|
|
|
374
384
|
async function responseJson(response) {
|
|
@@ -555,45 +565,34 @@ window.__ModuleLoader__.load({
|
|
|
555
565
|
const response = await fetch(UPDATE_ROUTE, { cache: 'no-store' });
|
|
556
566
|
const info = await responseJson(response);
|
|
557
567
|
if (!response.ok || info === null || typeof info !== 'object' || info.error !== undefined) throw new Error(info?.error ?? 'HTTP ' + response.status);
|
|
558
|
-
|
|
568
|
+
const installedNewer = compareVersions(info.installed, info.current) > 0;
|
|
569
|
+
const status = installedNewer ? 'restart' : info.newer !== true ? 'current' : info.managed ? 'available' : 'manual';
|
|
570
|
+
setUpdate({ status, info });
|
|
559
571
|
} catch (error) {
|
|
560
572
|
setUpdate((previous) => previous.status === 'restart' ? previous : { status: 'error', info: previous.info, error: String(error?.message ?? error) });
|
|
561
573
|
}
|
|
562
574
|
};
|
|
563
575
|
const install = async () => {
|
|
564
576
|
const { info } = update;
|
|
565
|
-
|
|
566
|
-
try {
|
|
567
|
-
pluginManager = ctx.remote?.pluginManager ?? ctx.get?.('remote')?.pluginManager;
|
|
568
|
-
} catch { pluginManager = undefined; }
|
|
569
|
-
if (info === undefined) return;
|
|
570
|
-
if (pluginManager === undefined || typeof pluginManager.installBundle !== 'function') {
|
|
577
|
+
if (info === undefined || updateManager === undefined) {
|
|
571
578
|
setUpdate({ status: 'error', info, error: 'the plugin manager is not available in this install' });
|
|
572
579
|
return;
|
|
573
580
|
}
|
|
574
581
|
setUpdate({ status: 'installing', info });
|
|
575
582
|
try {
|
|
576
583
|
const requestId = NS + '-update-' + info.latest + '-' + Date.now();
|
|
577
|
-
const
|
|
578
|
-
const reply = await
|
|
579
|
-
if (reply
|
|
584
|
+
const installSpec = async (spec) => {
|
|
585
|
+
const reply = await updateManager.installBundle(spec, { requestId });
|
|
586
|
+
if (!reply?.ok) throw new Error(reply?.error?.message ?? 'plugin manager did not answer');
|
|
580
587
|
return reply.value;
|
|
581
588
|
};
|
|
582
|
-
let result;
|
|
583
|
-
if (
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
if (result !== null && typeof result === 'object' && result.error?.code === 'already-installed') result = await attempt('https://registry.npmjs.org/' + NPM_NAME + '/-/' + NPM_NAME + '-' + info.latest + '.tgz');
|
|
590
|
-
}
|
|
591
|
-
const applied = result !== null && typeof result === 'object' && (result.application === 'applied' || result.application === 'restart-required' || result.version === info.latest);
|
|
592
|
-
if (!applied) {
|
|
593
|
-
const diagnostic = typeof result?.error?.diagnostic === 'string' ? result.error.diagnostic.split('\n').find((entry) => entry.trim() !== '') : undefined;
|
|
594
|
-
throw new Error(diagnostic ?? result?.error?.code ?? 'install failed');
|
|
595
|
-
}
|
|
596
|
-
setUpdate(result.application === 'applied'
|
|
589
|
+
let result = await installSpec(NPM_NAME + '@' + info.latest);
|
|
590
|
+
if (result?.error?.code === 'already-installed') result = await installSpec('https://registry.npmjs.org/' + NPM_NAME + '/-/' + NPM_NAME + '-' + info.latest + '.tgz');
|
|
591
|
+
const firstLine = () => result?.error?.diagnostic?.split(String.fromCharCode(10)).find((line) => line.trim() !== '') ?? result?.error?.code ?? result?.application;
|
|
592
|
+
const live = result?.application === 'applied';
|
|
593
|
+
if (!live && result?.application !== 'restart-required' && result?.version !== info.latest) throw new Error(firstLine());
|
|
594
|
+
if (result?.application === 'failed') console.warn(`dsh-nextsteps: ${info.latest} is installed; dsh could not start it before a restart: ${firstLine()}`);
|
|
595
|
+
setUpdate(live
|
|
597
596
|
? { status: 'current', info: { ...info, current: info.latest, newer: false } }
|
|
598
597
|
: { status: 'restart', info });
|
|
599
598
|
} catch (error) {
|
|
@@ -652,6 +651,15 @@ window.__ModuleLoader__.load({
|
|
|
652
651
|
return {
|
|
653
652
|
inject: ['slots', 'locale', 'remote'],
|
|
654
653
|
apply(ctx) {
|
|
654
|
+
const injectScope = (deps, setup) => {
|
|
655
|
+
if (ctx.inject === undefined) return [];
|
|
656
|
+
const fiber = ctx.inject(deps, setup);
|
|
657
|
+
return [() => fiber.dispose()];
|
|
658
|
+
};
|
|
659
|
+
for (const off of injectScope(['remote.pluginManager'], (scope) => {
|
|
660
|
+
updateManager = scope.remote?.pluginManager;
|
|
661
|
+
scope.effect(() => () => { updateManager = undefined; }, 'dsh-nextsteps: update installer');
|
|
662
|
+
})) if (ctx.effect !== undefined) ctx.effect(() => off, 'dsh-nextsteps: update installer scope');
|
|
655
663
|
installStyles(ctx);
|
|
656
664
|
rehydrateCaptures();
|
|
657
665
|
refreshPluginSettings();
|
package/index.js
CHANGED
|
@@ -172,6 +172,10 @@ function nextstepsSectionText() {
|
|
|
172
172
|
].join('\n');
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
+
function onDiskVersion() {
|
|
176
|
+
try { return JSON.parse(readFileSync(new URL('./package.json', import.meta.url), 'utf8')).version ?? null; } catch { return null; }
|
|
177
|
+
}
|
|
178
|
+
|
|
175
179
|
const PLUGIN_REV = 'sf-2';
|
|
176
180
|
|
|
177
181
|
function toolSpec(settings = { lang: 'auto', maxFollowups: 3, model: '' }) {
|
|
@@ -449,7 +453,7 @@ async function apply(ctx) {
|
|
|
449
453
|
fetch: async (request) => {
|
|
450
454
|
try {
|
|
451
455
|
const info = await checkUpdate(fetch, PACKAGE, request.signal);
|
|
452
|
-
return json({ ...info, installed:
|
|
456
|
+
return json({ ...info, installed: onDiskVersion() });
|
|
453
457
|
} catch (error) {
|
|
454
458
|
return json({ error: String(error?.message ?? error) }, 502);
|
|
455
459
|
}
|