chore: v2.8.21 — update progress steps, clone in background, extra SSH keys inline, today's spend

- Plugin update reports its running step (plugin-update-progress.json →
  plugin_update_progress); a hidden update or clone leaves a progress chip.
- Clone here can run in the background.
- Git identity: extra SSH keys are added inline per host (no More keys tab).
- Users: spend today (viewer's local day, ?tz_offset=).
- Prettier on the files touched since v2.8.20.
This commit is contained in:
2026-10-23 10:44:11 +07:00
parent 62b4520507
commit 9dd97a369c
33 changed files with 906 additions and 393 deletions
+12 -3
View File
@@ -36,7 +36,7 @@
const fs = require("fs");
const path = require("path");
const { execFile } = require("child_process");
const { readLastPluginUpdate } = require("./plugin-update");
const { readLastPluginUpdate, readPluginUpdateProgress } = require("./plugin-update");
const { getClaudeHome } = require("./claude-home");
const DEFAULT_ROOT = path.join(__dirname, "..", "..");
@@ -115,10 +115,16 @@ function execNpm(cwd, args, opts = {}) {
if (!err) return resolve(String(stdout).trim());
if (err.killed) {
return reject(
new Error(`${step} did not finish within ${Math.round(timeout / 60_000)} min and was stopped`)
new Error(
`${step} did not finish within ${Math.round(timeout / 60_000)} min and was stopped`
)
);
}
const tail = String(stderr || err.message || err).trim().split(/\r?\n/).slice(-15).join("\n");
const tail = String(stderr || err.message || err)
.trim()
.split(/\r?\n/)
.slice(-15)
.join("\n");
reject(new Error(`${step} failed:\n${tail}`));
}
);
@@ -491,6 +497,7 @@ async function pluginStatus(root, pluginInstall, options = {}) {
plugin_marketplace: pluginInstall.marketplace,
plugin_name: pluginInstall.plugin,
last_plugin_update: readLastPluginUpdate(),
plugin_update_progress: readPluginUpdateProgress(),
local_version: localVersion,
// Not a clone, so there is nothing to be shallow about and no distances to
@@ -785,6 +792,8 @@ async function getUpdatesStatus(gitRoot = DEFAULT_ROOT, options = {}) {
// every consumer (route, WS broadcast, CLI) gets it from one place — and so
// a chain that died is visible instead of looking like a slow restart.
last_plugin_update: pluginInstall ? readLastPluginUpdate() : null,
// The step a running chain is on, while it runs.
plugin_update_progress: pluginInstall ? readPluginUpdateProgress() : null,
local_version: localVersion,
// True when commit distances are unusable and version strings are the only
// signal — the UI must not render an "N commits" badge in that case.