mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-01 04:59:41 +02:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5adf044399 | ||
|
|
d95b4c597c |
@@ -1,5 +1,15 @@
|
||||
# aicodeman
|
||||
|
||||
## 0.9.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Self-updater: show live progress during the slow steps so an update no longer looks frozen.
|
||||
- The detached update runner (`scripts/self-update.sh`) now emits a heartbeat every few seconds during `npm install` and `npm run build`, refreshing the update status with the latest output line (full output is still written to the update log).
|
||||
- App Settings → Updates now shows the live status message plus a ticking elapsed-time counter during non-terminal phases, instead of only a static phase label.
|
||||
|
||||
This takes effect when updating _from_ a build that includes it — the detached runner script and the polling UI are both the from-version's copies.
|
||||
|
||||
## 0.9.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -56,7 +56,7 @@ When user says "COM":
|
||||
|
||||
CI runs `npm run check:lockfile` on every push/PR, so lockfile drift fails the build even if the `version-packages` script is bypassed.
|
||||
|
||||
**Version**: 0.9.5 (must match `package.json`)
|
||||
**Version**: 0.9.6 (must match `package.json`)
|
||||
|
||||
## Project Overview
|
||||
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "aicodeman",
|
||||
"version": "0.9.5",
|
||||
"version": "0.9.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "aicodeman",
|
||||
"version": "0.9.5",
|
||||
"version": "0.9.6",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "aicodeman",
|
||||
"version": "0.9.5",
|
||||
"version": "0.9.6",
|
||||
"description": "The missing control plane for AI coding agents - run 20 autonomous agents with real-time monitoring and session persistence",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
|
||||
+33
-5
@@ -93,6 +93,35 @@ write_status() {
|
||||
' || echo "[self-update] WARN: status write failed ($phase)"
|
||||
}
|
||||
|
||||
# Run a slow step with a heartbeat so the status file (and the UI polling it) keeps
|
||||
# moving instead of looking frozen during npm install / build. Every few seconds it
|
||||
# refreshes the status with the latest output line, and mirrors full output to the
|
||||
# log. Returns the wrapped command's exit code.
|
||||
run_step() {
|
||||
local phase="$1" base="$2"; shift 2
|
||||
local step_log; step_log="$(mktemp "${TMPDIR:-/tmp}/codeman-update.XXXXXX" 2>/dev/null || echo "/tmp/codeman-update.$$")"
|
||||
write_status "$phase" "$base…"
|
||||
echo "[self-update] $phase: $* (output below)"
|
||||
"$@" >"$step_log" 2>&1 &
|
||||
local pid=$! start=$SECONDS last_line=""
|
||||
while kill -0 "$pid" 2>/dev/null; do
|
||||
sleep 3
|
||||
local line
|
||||
line="$(tr -d '\r' <"$step_log" 2>/dev/null | grep -aE '[^[:space:]]' | tail -n 1 | cut -c1-100)"
|
||||
[[ -n "$line" && "$line" != "$last_line" ]] && last_line="$line"
|
||||
if [[ -n "$last_line" ]]; then
|
||||
write_status "$phase" "$base… · $last_line"
|
||||
else
|
||||
write_status "$phase" "$base… (working)"
|
||||
fi
|
||||
done
|
||||
wait "$pid"; local rc=$?
|
||||
echo "[self-update] $phase finished in $((SECONDS - start))s (rc=$rc)"
|
||||
cat "$step_log" >>"$LOG" 2>/dev/null || true
|
||||
rm -f "$step_log" 2>/dev/null || true
|
||||
return $rc
|
||||
}
|
||||
|
||||
fail() {
|
||||
local msg="$1" err="${2:-}"
|
||||
echo "[self-update] FAILED: $msg ($err)"
|
||||
@@ -138,13 +167,12 @@ git fetch --tags --force origin "refs/tags/$TAG:refs/tags/$TAG" 2>/dev/null \
|
||||
write_status "checkout" "Checking out $TAG…"
|
||||
git -c advice.detachedHead=false checkout --force "$TAG" || rollback_and_fail "Could not check out $TAG"
|
||||
|
||||
# 4) Install dependencies.
|
||||
write_status "installing" "Installing dependencies…"
|
||||
npm install --no-fund --no-audit || rollback_and_fail "Dependency install failed"
|
||||
# 4) Install dependencies (heartbeat keeps the UI live during this slow step).
|
||||
run_step "installing" "Installing dependencies" npm install --no-fund --no-audit \
|
||||
|| rollback_and_fail "Dependency install failed"
|
||||
|
||||
# 5) Build (gate the restart on success — never restart into a torn dist/).
|
||||
write_status "building" "Building…"
|
||||
npm run build || rollback_and_fail "Build failed"
|
||||
run_step "building" "Building" npm run build || rollback_and_fail "Build failed"
|
||||
|
||||
# 6) Restart the service so the new code loads. Write the terminal pre-restart
|
||||
# marker FIRST so the freshly-booted server can reconcile it deterministically.
|
||||
|
||||
@@ -606,7 +606,17 @@ Object.assign(CodemanApp.prototype, {
|
||||
return;
|
||||
}
|
||||
if (!terminal.has(data.phase)) {
|
||||
this._setUpdateProgress(`↻ ${escapeHtml(this._updatePhaseText(data.phase))}`);
|
||||
// Prefer the live status message — the updater's heartbeat enriches it with
|
||||
// the latest npm/build output line so a slow step doesn't look frozen — and
|
||||
// fall back to the static phase label. Append total elapsed so the counter
|
||||
// keeps ticking between heartbeats: a clear "still working" signal.
|
||||
const label = (data.message && data.message.trim()) ? data.message.trim() : this._updatePhaseText(data.phase);
|
||||
let elapsed = '';
|
||||
if (data.startedAt) {
|
||||
const secs = Math.max(0, Math.round((Date.now() - data.startedAt) / 1000));
|
||||
elapsed = ` <span style="color:var(--text-secondary)">· ${secs}s</span>`;
|
||||
}
|
||||
this._setUpdateProgress(`<span class="tunnel-spinner"></span> ${escapeHtml(label)}${elapsed}`);
|
||||
return;
|
||||
}
|
||||
this._stopUpdatePolling();
|
||||
|
||||
Reference in New Issue
Block a user