mixdog 0.9.27 → 0.9.29

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.
@@ -156,7 +156,7 @@ var require_mixdog_debug = __commonJS({
156
156
  // src/tui/index.jsx
157
157
  import React21 from "react";
158
158
  import { render } from "../../../vendor/ink/build/index.js";
159
- import { closeSync as closeSync2, constants as fsConstants, createWriteStream, mkdirSync as mkdirSync6, openSync as openSync2, readSync } from "node:fs";
159
+ import { closeSync as closeSync2, constants as fsConstants, createWriteStream, mkdirSync as mkdirSync7, openSync as openSync2, readSync } from "node:fs";
160
160
  import { tmpdir as tmpdir2 } from "node:os";
161
161
  import { dirname as dirname9, join as join10 } from "node:path";
162
162
  import { performance as performance3 } from "node:perf_hooks";
@@ -3099,6 +3099,74 @@ function formatAggregateDetail(summaries) {
3099
3099
  return order.map((item) => item.type === "metric" ? metrics.get(item.key)?.render(metrics.get(item.key)) : item.text).filter(Boolean).join(", ");
3100
3100
  }
3101
3101
 
3102
+ // src/runtime/shared/update-checker.mjs
3103
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3104
+ import { dirname as dirname2, join as join2 } from "node:path";
3105
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
3106
+
3107
+ // src/runtime/shared/plugin-paths.mjs
3108
+ import { homedir } from "os";
3109
+ import { dirname, join } from "path";
3110
+ import { fileURLToPath } from "url";
3111
+ var DEFAULT_ROOT = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
3112
+ function mixdogHome() {
3113
+ return process.env.MIXDOG_HOME || join(homedir(), ".mixdog");
3114
+ }
3115
+ function resolvePluginData() {
3116
+ return process.env.MIXDOG_DATA_DIR || join(mixdogHome(), "data");
3117
+ }
3118
+
3119
+ // src/runtime/shared/spawn-flags.mjs
3120
+ var isWin = process.platform === "win32";
3121
+ var detachedSpawnOpts = Object.freeze({
3122
+ windowsHide: true,
3123
+ ...isWin ? {} : { detached: true }
3124
+ });
3125
+ var hiddenSpawnOpts = Object.freeze({
3126
+ windowsHide: true
3127
+ });
3128
+
3129
+ // src/runtime/shared/update-checker.mjs
3130
+ var PACKAGE_NAME = "mixdog";
3131
+ var REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
3132
+ var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
3133
+ var _MODULE_DIR = dirname2(fileURLToPath2(import.meta.url));
3134
+ var _PACKAGE_JSON_PATH = join2(_MODULE_DIR, "..", "..", "..", "package.json");
3135
+ var _PACKAGE_ROOT = dirname2(_PACKAGE_JSON_PATH);
3136
+ var _localVersionCache = null;
3137
+ function localPackageVersion() {
3138
+ if (_localVersionCache) return _localVersionCache;
3139
+ try {
3140
+ const raw = JSON.parse(readFileSync(_PACKAGE_JSON_PATH, "utf8"));
3141
+ _localVersionCache = String(raw?.version || "0.0.0");
3142
+ } catch {
3143
+ _localVersionCache = "0.0.0";
3144
+ }
3145
+ return _localVersionCache;
3146
+ }
3147
+ function parseSemver(value) {
3148
+ const text = String(value || "").trim().replace(/^v/i, "");
3149
+ const [core, ...preParts] = text.split("-");
3150
+ const parts = core.split(".").map((n) => {
3151
+ const num2 = Number.parseInt(n, 10);
3152
+ return Number.isFinite(num2) ? num2 : 0;
3153
+ });
3154
+ while (parts.length < 3) parts.push(0);
3155
+ return { parts, prerelease: preParts.join("-") };
3156
+ }
3157
+ function compareSemver(a, b) {
3158
+ const pa = parseSemver(a);
3159
+ const pb = parseSemver(b);
3160
+ for (let i = 0; i < 3; i++) {
3161
+ const diff = (pa.parts[i] || 0) - (pb.parts[i] || 0);
3162
+ if (diff !== 0) return diff;
3163
+ }
3164
+ if (pa.prerelease && !pb.prerelease) return -1;
3165
+ if (!pa.prerelease && pb.prerelease) return 1;
3166
+ if (pa.prerelease !== pb.prerelease) return pa.prerelease < pb.prerelease ? -1 : 1;
3167
+ return 0;
3168
+ }
3169
+
3102
3170
  // src/tui/components/Spinner.jsx
3103
3171
  import React, { useRef as useRef2 } from "react";
3104
3172
  import { Box, Text } from "../../../vendor/ink/build/index.js";
@@ -4258,10 +4326,10 @@ ${grafted}` : cachedL1;
4258
4326
  const workflowLabel = workflowModeLabel(workflow, remoteEnabled);
4259
4327
  return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", width: "100%", height: 3, overflow: "hidden", justifyContent: "flex-start", paddingLeft: 2, backgroundColor: surfaceBackground(), children: [
4260
4328
  /* @__PURE__ */ jsxs2(Box2, { flexDirection: "row", width: "100%", overflow: "hidden", children: [
4261
- /* @__PURE__ */ jsx2(Box2, { flexGrow: 1, flexShrink: 1, overflow: "hidden", children: /* @__PURE__ */ jsx2(Text2, { wrap: "truncate", children: lines[0] || " " }) }),
4329
+ /* @__PURE__ */ jsx2(Box2, { flexGrow: 1, flexShrink: 1, flexBasis: 0, overflow: "hidden", children: /* @__PURE__ */ jsx2(Text2, { wrap: "truncate", children: lines[0] || " " }) }),
4262
4330
  /* @__PURE__ */ jsx2(Box2, { flexShrink: 0, marginLeft: 1, marginRight: 1, children: /* @__PURE__ */ jsx2(Text2, { color: theme.statusText, wrap: "truncate", children: workflowLabel }) })
4263
4331
  ] }),
4264
- /* @__PURE__ */ jsx2(Box2, { flexDirection: "row", width: "100%", overflow: "hidden", children: /* @__PURE__ */ jsx2(Box2, { flexGrow: 1, flexShrink: 1, overflow: "hidden", children: /* @__PURE__ */ jsx2(Text2, { wrap: "truncate", children: lines[1] || " " }) }) })
4332
+ /* @__PURE__ */ jsx2(Box2, { flexDirection: "row", width: "100%", overflow: "hidden", children: /* @__PURE__ */ jsx2(Box2, { flexGrow: 1, flexShrink: 1, flexBasis: 0, overflow: "hidden", children: /* @__PURE__ */ jsx2(Text2, { wrap: "truncate", children: lines[1] || " " }) }) })
4265
4333
  ] });
4266
4334
  }
4267
4335
  var StatusLine = React2.memo(StatusLineView);
@@ -4274,7 +4342,7 @@ import { Box as Box3, Text as Text3, useInput, usePaste, useStdin } from "../../
4274
4342
  import stringWidth from "string-width";
4275
4343
  var graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
4276
4344
  function isProblemCodePoint(cp) {
4277
- return cp >= 9312 && cp <= 9471 || cp >= 8596 && cp <= 8703;
4345
+ return cp >= 9312 && cp <= 9471 || cp >= 8596 && cp <= 8703 && cp !== 8635;
4278
4346
  }
4279
4347
  var PROBLEM_RE = /[\u2194-\u21ff\u2460-\u24ff]/;
4280
4348
  function resolveAmbiguousWidePolicy(env = process.env, platform = process.platform) {
@@ -6931,7 +6999,7 @@ function TextEntryPanel({
6931
6999
  import { execFile } from "node:child_process";
6932
7000
  import { Buffer as Buffer2 } from "node:buffer";
6933
7001
  import { randomBytes } from "node:crypto";
6934
- import { existsSync, unlinkSync } from "node:fs";
7002
+ import { existsSync as existsSync2, unlinkSync } from "node:fs";
6935
7003
  import { readFile as readFileAsync, stat as statAsync } from "node:fs/promises";
6936
7004
  import { tmpdir } from "node:os";
6937
7005
  import { basename, extname, isAbsolute, resolve } from "node:path";
@@ -7213,7 +7281,7 @@ async function readClipboardImageToTempFile() {
7213
7281
  const r = await execFileBuffer("powershell.exe", ["-NoLogo", "-NoProfile", "-NonInteractive", "-Command", ps], {
7214
7282
  env: { ...process.env, MIXDOG_CLIPBOARD_IMAGE_PATH: out }
7215
7283
  });
7216
- return r.ok && existsSync(out) ? out : null;
7284
+ return r.ok && existsSync2(out) ? out : null;
7217
7285
  }
7218
7286
  if (process.platform === "darwin") {
7219
7287
  const script = `set png_data to (the clipboard as \xABclass PNGf\xBB)
@@ -7221,7 +7289,7 @@ set fp to open for access POSIX file "${out.replace(/"/g, '\\"')}" with write pe
7221
7289
  write png_data to fp
7222
7290
  close access fp`;
7223
7291
  const r = await execFileBuffer("osascript", ["-e", script]);
7224
- return r.ok && existsSync(out) ? out : null;
7292
+ return r.ok && existsSync2(out) ? out : null;
7225
7293
  }
7226
7294
  return null;
7227
7295
  }
@@ -7271,11 +7339,11 @@ async function readClipboardText() {
7271
7339
  }
7272
7340
 
7273
7341
  // src/standalone/projects.mjs
7274
- import { homedir } from "node:os";
7275
- import { existsSync as existsSync2, mkdirSync, readFileSync, renameSync, statSync, writeFileSync } from "node:fs";
7276
- import { basename as basename2, dirname, isAbsolute as isAbsolute2, join, resolve as resolve2 } from "node:path";
7277
- var MIXDOG_HOME = process.env.MIXDOG_HOME || join(homedir(), ".mixdog");
7278
- var PROJECTS_FILE = join(MIXDOG_HOME, "projects.json");
7342
+ import { homedir as homedir2 } from "node:os";
7343
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync, statSync, writeFileSync as writeFileSync2 } from "node:fs";
7344
+ import { basename as basename2, dirname as dirname3, isAbsolute as isAbsolute2, join as join3, resolve as resolve2 } from "node:path";
7345
+ var MIXDOG_HOME = process.env.MIXDOG_HOME || join3(homedir2(), ".mixdog");
7346
+ var PROJECTS_FILE = join3(MIXDOG_HOME, "projects.json");
7279
7347
  function toAbsolute(rawPath) {
7280
7348
  const text = String(rawPath || "").trim();
7281
7349
  if (!text) return "";
@@ -7287,8 +7355,8 @@ function normalizeKey(absPath) {
7287
7355
  }
7288
7356
  function readStore() {
7289
7357
  try {
7290
- if (!existsSync2(PROJECTS_FILE)) return { projects: [] };
7291
- const raw = readFileSync(PROJECTS_FILE, "utf8");
7358
+ if (!existsSync3(PROJECTS_FILE)) return { projects: [] };
7359
+ const raw = readFileSync2(PROJECTS_FILE, "utf8");
7292
7360
  const parsed = JSON.parse(raw);
7293
7361
  const projects = Array.isArray(parsed?.projects) ? parsed.projects : [];
7294
7362
  return {
@@ -7305,9 +7373,9 @@ function readStore() {
7305
7373
  }
7306
7374
  function writeStore(store) {
7307
7375
  try {
7308
- mkdirSync(dirname(PROJECTS_FILE), { recursive: true });
7376
+ mkdirSync2(dirname3(PROJECTS_FILE), { recursive: true });
7309
7377
  const tmp = `${PROJECTS_FILE}.${process.pid}.tmp`;
7310
- writeFileSync(tmp, `${JSON.stringify(store, null, 2)}
7378
+ writeFileSync2(tmp, `${JSON.stringify(store, null, 2)}
7311
7379
  `, "utf8");
7312
7380
  renameSync(tmp, PROJECTS_FILE);
7313
7381
  } catch {
@@ -7321,14 +7389,14 @@ function ensureProjectIdMarker(absPath, name) {
7321
7389
  } catch {
7322
7390
  return;
7323
7391
  }
7324
- const markerPath = join(absPath, ".mixdog", "project.id");
7325
- if (existsSync2(markerPath)) return;
7392
+ const markerPath = join3(absPath, ".mixdog", "project.id");
7393
+ if (existsSync3(markerPath)) return;
7326
7394
  const value = String(name || basename2(absPath) || "").trim();
7327
7395
  if (!value || value.toLowerCase() === "common") return;
7328
- const markerDir = join(absPath, ".mixdog");
7329
- mkdirSync(markerDir, { recursive: true });
7396
+ const markerDir = join3(absPath, ".mixdog");
7397
+ mkdirSync2(markerDir, { recursive: true });
7330
7398
  const tmp = `${markerPath}.${process.pid}.tmp`;
7331
- writeFileSync(tmp, `${value}
7399
+ writeFileSync2(tmp, `${value}
7332
7400
  `, "utf8");
7333
7401
  renameSync(tmp, markerPath);
7334
7402
  } catch {
@@ -7396,7 +7464,7 @@ function renameProject(rawPath, nextName) {
7396
7464
  }
7397
7465
  function pathExists(rawPath) {
7398
7466
  const absPath = toAbsolute(rawPath);
7399
- return !!absPath && existsSync2(absPath);
7467
+ return !!absPath && existsSync3(absPath);
7400
7468
  }
7401
7469
  function isDirectory(rawPath) {
7402
7470
  const absPath = toAbsolute(rawPath);
@@ -7411,7 +7479,7 @@ function ensureDir(rawPath) {
7411
7479
  const absPath = toAbsolute(rawPath);
7412
7480
  if (!absPath) return "";
7413
7481
  try {
7414
- mkdirSync(absPath, { recursive: true });
7482
+ mkdirSync2(absPath, { recursive: true });
7415
7483
  return absPath;
7416
7484
  } catch {
7417
7485
  return "";
@@ -14162,37 +14230,25 @@ function createOnboardingSteps({
14162
14230
  }
14163
14231
 
14164
14232
  // src/runtime/shared/config.mjs
14165
- import { readFileSync as readFileSync4, mkdirSync as mkdirSync4, existsSync as existsSync5 } from "fs";
14166
- import { join as join5, dirname as dirname5 } from "path";
14233
+ import { readFileSync as readFileSync5, mkdirSync as mkdirSync5, existsSync as existsSync6 } from "fs";
14234
+ import { join as join6, dirname as dirname6 } from "path";
14167
14235
  import { createRequire as createRequire2 } from "module";
14168
14236
 
14169
- // src/runtime/shared/plugin-paths.mjs
14170
- import { homedir as homedir2 } from "os";
14171
- import { dirname as dirname2, join as join2 } from "path";
14172
- import { fileURLToPath } from "url";
14173
- var DEFAULT_ROOT = join2(dirname2(fileURLToPath(import.meta.url)), "..", "..");
14174
- function mixdogHome() {
14175
- return process.env.MIXDOG_HOME || join2(homedir2(), ".mixdog");
14176
- }
14177
- function resolvePluginData() {
14178
- return process.env.MIXDOG_DATA_DIR || join2(mixdogHome(), "data");
14179
- }
14180
-
14181
14237
  // src/runtime/shared/atomic-file.mjs
14182
14238
  import {
14183
14239
  closeSync,
14184
- existsSync as existsSync3,
14240
+ existsSync as existsSync4,
14185
14241
  fsyncSync,
14186
14242
  linkSync,
14187
- mkdirSync as mkdirSync2,
14243
+ mkdirSync as mkdirSync3,
14188
14244
  openSync,
14189
- readFileSync as readFileSync2,
14245
+ readFileSync as readFileSync3,
14190
14246
  renameSync as renameSync2,
14191
14247
  statSync as statSync2,
14192
14248
  unlinkSync as unlinkSync2,
14193
- writeFileSync as writeFileSync2
14249
+ writeFileSync as writeFileSync3
14194
14250
  } from "fs";
14195
- import { dirname as dirname3, basename as basename3, join as join3 } from "path";
14251
+ import { dirname as dirname4, basename as basename3, join as join4 } from "path";
14196
14252
  import { randomBytes as randomBytes2 } from "crypto";
14197
14253
  import { execFile as execFile2, execFileSync } from "child_process";
14198
14254
  import { promisify } from "util";
@@ -14244,7 +14300,7 @@ function withFileLockSync(lockPath, fn, opts = {}) {
14244
14300
  const timeoutMs = Number.isFinite(opts.timeoutMs) ? opts.timeoutMs : DEFAULT_LOCK_TIMEOUT_MS;
14245
14301
  const staleMs = Number.isFinite(opts.staleMs) ? opts.staleMs : 3e4;
14246
14302
  const deadline = Date.now() + timeoutMs;
14247
- mkdirSync2(dirname3(lockPath), { recursive: true });
14303
+ mkdirSync3(dirname4(lockPath), { recursive: true });
14248
14304
  let attempt = 0;
14249
14305
  let lastErr = null;
14250
14306
  while (true) {
@@ -14272,7 +14328,7 @@ function withFileLockSync(lockPath, fn, opts = {}) {
14272
14328
  continue;
14273
14329
  }
14274
14330
  try {
14275
- writeFileSync2(fd, `${process.pid} ${Date.now()} ${_OWNER_TOKEN}
14331
+ writeFileSync3(fd, `${process.pid} ${Date.now()} ${_OWNER_TOKEN}
14276
14332
  `, "utf8");
14277
14333
  } catch {
14278
14334
  }
@@ -14297,7 +14353,7 @@ function withFileLockSync(lockPath, fn, opts = {}) {
14297
14353
  }
14298
14354
  function _readLockOwnerPid(lockPath) {
14299
14355
  try {
14300
- const raw = readFileSync2(lockPath, "utf8");
14356
+ const raw = readFileSync3(lockPath, "utf8");
14301
14357
  const tok = String(raw).trim().split(/\s+/)[0];
14302
14358
  const pid = Number.parseInt(tok, 10);
14303
14359
  return Number.isFinite(pid) && pid > 0 ? pid : null;
@@ -14317,7 +14373,7 @@ function _pidIsDead(pid) {
14317
14373
  }
14318
14374
  function _readLockOwner(lockPath) {
14319
14375
  try {
14320
- const raw = readFileSync2(lockPath, "utf8");
14376
+ const raw = readFileSync3(lockPath, "utf8");
14321
14377
  const parts = String(raw).trim().split(/\s+/);
14322
14378
  const pid = Number.parseInt(parts[0], 10);
14323
14379
  return {
@@ -14398,14 +14454,14 @@ function _reclaimGuardIsUnreadableAndStale(guardPath, staleMs) {
14398
14454
  }
14399
14455
  function _reclaimGuardMatchesToken(guardPath, token) {
14400
14456
  try {
14401
- return readFileSync2(guardPath, "utf8") === token;
14457
+ return readFileSync3(guardPath, "utf8") === token;
14402
14458
  } catch {
14403
14459
  return false;
14404
14460
  }
14405
14461
  }
14406
14462
  function _readGuardContent(guardPath) {
14407
14463
  try {
14408
- return readFileSync2(guardPath, "utf8");
14464
+ return readFileSync3(guardPath, "utf8");
14409
14465
  } catch {
14410
14466
  return null;
14411
14467
  }
@@ -14457,7 +14513,7 @@ function _tryAcquireReclaimGuard(lockPath, staleMs) {
14457
14513
  const token = `${process.pid} ${Date.now()} ${randomBytes2(8).toString("hex")}
14458
14514
  `;
14459
14515
  try {
14460
- writeFileSync2(fd, token, "utf8");
14516
+ writeFileSync3(fd, token, "utf8");
14461
14517
  } catch {
14462
14518
  }
14463
14519
  return { fd, guardPath, token };
@@ -14490,7 +14546,7 @@ async function withFileLock(lockPath, fn, opts = {}) {
14490
14546
  const timeoutMs = Number.isFinite(opts.timeoutMs) ? opts.timeoutMs : DEFAULT_LOCK_TIMEOUT_MS;
14491
14547
  const staleMs = Number.isFinite(opts.staleMs) ? opts.staleMs : 3e4;
14492
14548
  const deadline = Date.now() + timeoutMs;
14493
- mkdirSync2(dirname3(lockPath), { recursive: true });
14549
+ mkdirSync3(dirname4(lockPath), { recursive: true });
14494
14550
  let attempt = 0;
14495
14551
  let lastErr = null;
14496
14552
  while (true) {
@@ -14518,7 +14574,7 @@ async function withFileLock(lockPath, fn, opts = {}) {
14518
14574
  continue;
14519
14575
  }
14520
14576
  try {
14521
- writeFileSync2(fd, `${process.pid} ${Date.now()} ${_OWNER_TOKEN}
14577
+ writeFileSync3(fd, `${process.pid} ${Date.now()} ${_OWNER_TOKEN}
14522
14578
  `, "utf8");
14523
14579
  } catch {
14524
14580
  }
@@ -14545,8 +14601,8 @@ var _cachedUserSid = null;
14545
14601
  function _resolveCurrentUserPrincipal() {
14546
14602
  const systemRoot = process.env.SystemRoot || process.env.windir;
14547
14603
  if (systemRoot) {
14548
- const whoami = join3(systemRoot, "System32", "whoami.exe");
14549
- if (existsSync3(whoami)) {
14604
+ const whoami = join4(systemRoot, "System32", "whoami.exe");
14605
+ if (existsSync4(whoami)) {
14550
14606
  try {
14551
14607
  const out = execFileSync(whoami, ["/user", "/fo", "csv", "/nh"], {
14552
14608
  encoding: "utf8",
@@ -14574,8 +14630,8 @@ function _enforceOwnerOnlyAclWin32(targetPath) {
14574
14630
  err.code = "EACLNOROOT";
14575
14631
  throw err;
14576
14632
  }
14577
- const icacls = join3(systemRoot, "System32", "icacls.exe");
14578
- if (!existsSync3(icacls)) {
14633
+ const icacls = join4(systemRoot, "System32", "icacls.exe");
14634
+ if (!existsSync4(icacls)) {
14579
14635
  const err = new Error(`icacls.exe not found at ${icacls}; refusing to leave secret world-readable`);
14580
14636
  err.code = "EACLNOICACLS";
14581
14637
  throw err;
@@ -14601,8 +14657,8 @@ function _enforceOwnerOnlyAclWin32(targetPath) {
14601
14657
  async function _resolveCurrentUserPrincipalAsync() {
14602
14658
  const systemRoot = process.env.SystemRoot || process.env.windir;
14603
14659
  if (systemRoot) {
14604
- const whoami = join3(systemRoot, "System32", "whoami.exe");
14605
- if (existsSync3(whoami)) {
14660
+ const whoami = join4(systemRoot, "System32", "whoami.exe");
14661
+ if (existsSync4(whoami)) {
14606
14662
  try {
14607
14663
  const { stdout } = await _execFileAsync(whoami, ["/user", "/fo", "csv", "/nh"], {
14608
14664
  encoding: "utf8",
@@ -14626,8 +14682,8 @@ async function _enforceOwnerOnlyAclWin32Async(targetPath) {
14626
14682
  err.code = "EACLNOROOT";
14627
14683
  throw err;
14628
14684
  }
14629
- const icacls = join3(systemRoot, "System32", "icacls.exe");
14630
- if (!existsSync3(icacls)) {
14685
+ const icacls = join4(systemRoot, "System32", "icacls.exe");
14686
+ if (!existsSync4(icacls)) {
14631
14687
  const err = new Error(`icacls.exe not found at ${icacls}; refusing to leave secret world-readable`);
14632
14688
  err.code = "EACLNOICACLS";
14633
14689
  throw err;
@@ -14646,12 +14702,12 @@ async function _enforceOwnerOnlyAclWin32Async(targetPath) {
14646
14702
  }
14647
14703
  function writeFileAtomicSync(filePath, data, opts = {}) {
14648
14704
  const run = () => {
14649
- const dir = dirname3(filePath);
14650
- mkdirSync2(dir, { recursive: true });
14651
- const tmp = join3(dir, `.${basename3(filePath)}.${randomBytes2(12).toString("hex")}.tmp`);
14705
+ const dir = dirname4(filePath);
14706
+ mkdirSync3(dir, { recursive: true });
14707
+ const tmp = join4(dir, `.${basename3(filePath)}.${randomBytes2(12).toString("hex")}.tmp`);
14652
14708
  try {
14653
14709
  const writeOpts = { encoding: opts.encoding || "utf8", flag: "wx", mode: opts.mode !== void 0 ? opts.mode : 384 };
14654
- writeFileSync2(tmp, data, writeOpts);
14710
+ writeFileSync3(tmp, data, writeOpts);
14655
14711
  if (opts.secret === true) _enforceOwnerOnlyAclWin32(tmp);
14656
14712
  if (opts.fsync !== false) {
14657
14713
  let fd = null;
@@ -14687,8 +14743,8 @@ function writeFileAtomicSync(filePath, data, opts = {}) {
14687
14743
  renameWithRetrySync(tmp, filePath, opts);
14688
14744
  } catch (err) {
14689
14745
  if (opts.renameFallback === "truncate" && opts.secret !== true && process.platform === "win32" && RETRY_CODES.has(err?.code)) {
14690
- const data2 = readFileSync2(tmp);
14691
- writeFileSync2(filePath, data2, { mode: opts.mode !== void 0 ? opts.mode : 384 });
14746
+ const data2 = readFileSync3(tmp);
14747
+ writeFileSync3(filePath, data2, { mode: opts.mode !== void 0 ? opts.mode : 384 });
14692
14748
  try {
14693
14749
  unlinkSync2(tmp);
14694
14750
  } catch {
@@ -14718,7 +14774,7 @@ function writeFileAtomicSync(filePath, data, opts = {}) {
14718
14774
  return true;
14719
14775
  } catch (err) {
14720
14776
  try {
14721
- if (existsSync3(tmp)) unlinkSync2(tmp);
14777
+ if (existsSync4(tmp)) unlinkSync2(tmp);
14722
14778
  } catch {
14723
14779
  }
14724
14780
  throw err;
@@ -14737,7 +14793,7 @@ async function updateJsonAtomic(filePath, mutator, opts = {}) {
14737
14793
  return withFileLock(`${filePath}.lock`, () => {
14738
14794
  let cur = null;
14739
14795
  try {
14740
- cur = JSON.parse(readFileSync2(filePath, "utf8"));
14796
+ cur = JSON.parse(readFileSync3(filePath, "utf8"));
14741
14797
  } catch {
14742
14798
  cur = null;
14743
14799
  }
@@ -14751,22 +14807,22 @@ async function updateJsonAtomic(filePath, mutator, opts = {}) {
14751
14807
  // src/runtime/shared/user-data-guard.mjs
14752
14808
  import {
14753
14809
  copyFileSync,
14754
- existsSync as existsSync4,
14755
- mkdirSync as mkdirSync3,
14810
+ existsSync as existsSync5,
14811
+ mkdirSync as mkdirSync4,
14756
14812
  readdirSync,
14757
- readFileSync as readFileSync3,
14813
+ readFileSync as readFileSync4,
14758
14814
  rmSync,
14759
14815
  statSync as statSync3,
14760
- writeFileSync as writeFileSync3
14816
+ writeFileSync as writeFileSync4
14761
14817
  } from "fs";
14762
- import { dirname as dirname4, join as join4, resolve as resolve3 } from "path";
14818
+ import { dirname as dirname5, join as join5, resolve as resolve3 } from "path";
14763
14819
  import { homedir as homedir3 } from "os";
14764
14820
  import { createHash } from "crypto";
14765
14821
  function mixdogConfigBaseDir() {
14766
- return process.env.MIXDOG_CONFIG_DIR || join4(homedir3(), ".mixdog");
14822
+ return process.env.MIXDOG_CONFIG_DIR || join5(homedir3(), ".mixdog");
14767
14823
  }
14768
14824
  function getBackupRoot() {
14769
- return process.env.MIXDOG_USER_DATA_BACKUP_ROOT || join4(mixdogConfigBaseDir(), "backups", "user-data");
14825
+ return process.env.MIXDOG_USER_DATA_BACKUP_ROOT || join5(mixdogConfigBaseDir(), "backups", "user-data");
14770
14826
  }
14771
14827
  var USER_DATA_FILES = [
14772
14828
  "mixdog-config.json",
@@ -14787,13 +14843,13 @@ function safeReason(reason) {
14787
14843
  }
14788
14844
  function initMarkerPath(dataDir) {
14789
14845
  const id = createHash("sha256").update(String(dataDir || "unknown")).digest("hex").slice(0, 16);
14790
- return join4(getBackupRoot(), `.initialized-${id}.json`);
14846
+ return join5(getBackupRoot(), `.initialized-${id}.json`);
14791
14847
  }
14792
14848
  function isPlainObject(value) {
14793
14849
  return !!value && typeof value === "object" && !Array.isArray(value);
14794
14850
  }
14795
14851
  function hasUserDataInitMarker(dataDir) {
14796
- return existsSync4(initMarkerPath(dataDir));
14852
+ return existsSync5(initMarkerPath(dataDir));
14797
14853
  }
14798
14854
  function isStructurallyCompleteMixdogConfigBackup(parsed) {
14799
14855
  if (!isPlainObject(parsed)) return false;
@@ -14810,10 +14866,10 @@ function loadLatestMixdogConfigFromBackup(_dataDir) {
14810
14866
  return null;
14811
14867
  }
14812
14868
  for (const name of entries) {
14813
- const cfgPath = join4(root, name, "mixdog-config.json");
14814
- if (!existsSync4(cfgPath)) continue;
14869
+ const cfgPath = join5(root, name, "mixdog-config.json");
14870
+ if (!existsSync5(cfgPath)) continue;
14815
14871
  try {
14816
- const parsed = JSON.parse(readFileSync3(cfgPath, "utf8"));
14872
+ const parsed = JSON.parse(readFileSync4(cfgPath, "utf8"));
14817
14873
  if (isStructurallyCompleteMixdogConfigBackup(parsed)) return parsed;
14818
14874
  } catch {
14819
14875
  continue;
@@ -14825,12 +14881,12 @@ function copyTree(src, dst, copied) {
14825
14881
  const st = statSync3(src);
14826
14882
  if (st.isDirectory()) {
14827
14883
  for (const name of readdirSync(src)) {
14828
- copyTree(join4(src, name), join4(dst, name), copied);
14884
+ copyTree(join5(src, name), join5(dst, name), copied);
14829
14885
  }
14830
14886
  return;
14831
14887
  }
14832
14888
  if (!st.isFile()) return;
14833
- mkdirSync3(dirname4(dst), { recursive: true });
14889
+ mkdirSync4(dirname5(dst), { recursive: true });
14834
14890
  copyFileSync(src, dst);
14835
14891
  copied.push(dst);
14836
14892
  }
@@ -14843,15 +14899,15 @@ function pruneBackups(keep = 40) {
14843
14899
  }
14844
14900
  for (const name of entries.slice(keep)) {
14845
14901
  try {
14846
- rmSync(join4(getBackupRoot(), name), { recursive: true, force: true });
14902
+ rmSync(join5(getBackupRoot(), name), { recursive: true, force: true });
14847
14903
  } catch {
14848
14904
  }
14849
14905
  }
14850
14906
  }
14851
14907
  function markUserDataInitialized(dataDir) {
14852
14908
  try {
14853
- mkdirSync3(getBackupRoot(), { recursive: true });
14854
- writeFileSync3(initMarkerPath(dataDir), JSON.stringify({
14909
+ mkdirSync4(getBackupRoot(), { recursive: true });
14910
+ writeFileSync4(initMarkerPath(dataDir), JSON.stringify({
14855
14911
  dataDir,
14856
14912
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
14857
14913
  }, null, 2) + "\n", "utf8");
@@ -14862,16 +14918,16 @@ function backupUserData(dataDir, reason = "snapshot") {
14862
14918
  if (process.env.MIXDOG_SKIP_USER_DATA_BACKUP === "1" || process.env.MIXDOG_SKIP_USER_DATA_BACKUP === "true") {
14863
14919
  return { dir: null, copied: [] };
14864
14920
  }
14865
- if (!dataDir || !existsSync4(dataDir)) return { dir: null, copied: [] };
14866
- const backupDir = join4(getBackupRoot(), `${stamp()}-${safeReason(reason)}`);
14921
+ if (!dataDir || !existsSync5(dataDir)) return { dir: null, copied: [] };
14922
+ const backupDir = join5(getBackupRoot(), `${stamp()}-${safeReason(reason)}`);
14867
14923
  const copied = [];
14868
14924
  for (const rel of USER_DATA_FILES) {
14869
- const src = join4(dataDir, rel);
14870
- if (existsSync4(src)) copyTree(src, join4(backupDir, rel), copied);
14925
+ const src = join5(dataDir, rel);
14926
+ if (existsSync5(src)) copyTree(src, join5(backupDir, rel), copied);
14871
14927
  }
14872
14928
  for (const rel of USER_DATA_DIRS) {
14873
- const src = join4(dataDir, rel);
14874
- if (existsSync4(src)) copyTree(src, join4(backupDir, rel), copied);
14929
+ const src = join5(dataDir, rel);
14930
+ if (existsSync5(src)) copyTree(src, join5(backupDir, rel), copied);
14875
14931
  }
14876
14932
  if (copied.length > 0) {
14877
14933
  markUserDataInitialized(dataDir);
@@ -14889,7 +14945,7 @@ var CASE_INSENSITIVE = process.platform === "win32";
14889
14945
  var _require = createRequire2(import.meta.url);
14890
14946
  var { getSecret: _getSecret, setSecret: _setSecret, deleteSecret: _deleteSecret, hasSecret: _hasSecret } = _require("../../lib/keychain-cjs.cjs");
14891
14947
  var DATA_DIR = resolvePluginData();
14892
- var CONFIG_PATH = join5(DATA_DIR, "mixdog-config.json");
14948
+ var CONFIG_PATH = join6(DATA_DIR, "mixdog-config.json");
14893
14949
  var GENERATED_KEY = "_generated";
14894
14950
  function isPlainObject2(value) {
14895
14951
  return !!value && typeof value === "object" && !Array.isArray(value);
@@ -14902,7 +14958,7 @@ function stripGeneratedMarker(data) {
14902
14958
  function readJsonFile(path2) {
14903
14959
  let raw;
14904
14960
  try {
14905
- raw = readFileSync4(path2, "utf8");
14961
+ raw = readFileSync5(path2, "utf8");
14906
14962
  } catch (err) {
14907
14963
  if (err.code === "ENOENT") return null;
14908
14964
  process.stderr.write(`[config] readJsonFile: unexpected read error for ${path2}: ${err.message}
@@ -14925,7 +14981,7 @@ function readJsonFile(path2) {
14925
14981
  }
14926
14982
  }
14927
14983
  function writeJsonFile(path2, data) {
14928
- mkdirSync4(dirname5(path2), { recursive: true, mode: 448 });
14984
+ mkdirSync5(dirname6(path2), { recursive: true, mode: 448 });
14929
14985
  if (path2 === CONFIG_PATH) {
14930
14986
  try {
14931
14987
  backupUserData(DATA_DIR, "pre-config-write");
@@ -14959,7 +15015,7 @@ function readAll() {
14959
15015
  function quarantineMalformedConfig(parseErr) {
14960
15016
  const corrupt = `${CONFIG_PATH}.corrupt-${Date.now()}`;
14961
15017
  try {
14962
- if (existsSync5(CONFIG_PATH)) renameWithRetrySync(CONFIG_PATH, corrupt);
15018
+ if (existsSync6(CONFIG_PATH)) renameWithRetrySync(CONFIG_PATH, corrupt);
14963
15019
  } catch {
14964
15020
  }
14965
15021
  process.stderr.write(
@@ -14981,7 +15037,7 @@ function restoreAllForRmWOrThrow(reason) {
14981
15037
  function readAllForRmW() {
14982
15038
  let raw;
14983
15039
  try {
14984
- raw = readFileSync4(CONFIG_PATH, "utf8");
15040
+ raw = readFileSync5(CONFIG_PATH, "utf8");
14985
15041
  } catch (err) {
14986
15042
  if (err.code === "ENOENT") {
14987
15043
  if (hasUserDataInitMarker(DATA_DIR)) {
@@ -17693,9 +17749,9 @@ import { useCallback as useCallback5 } from "react";
17693
17749
 
17694
17750
  // src/tui/prompt-history-store.mjs
17695
17751
  import { createHash as createHash2 } from "node:crypto";
17696
- import { chmodSync, existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync5, renameSync as renameSync3, writeFileSync as writeFileSync4 } from "node:fs";
17752
+ import { chmodSync, existsSync as existsSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync6, renameSync as renameSync3, writeFileSync as writeFileSync5 } from "node:fs";
17697
17753
  import { chmod, mkdir, rename, writeFile } from "node:fs/promises";
17698
- import { dirname as dirname6, join as join6, resolve as resolve4 } from "node:path";
17754
+ import { dirname as dirname7, join as join7, resolve as resolve4 } from "node:path";
17699
17755
  var PROMPT_HISTORY_LIMIT2 = 50;
17700
17756
  function promptHistoryKey2(value) {
17701
17757
  return String(value || "").trim().replace(/\s+/g, " ");
@@ -17710,12 +17766,12 @@ function historyFilePath(cwd) {
17710
17766
  const key = promptHistoryCwdKey(cwd);
17711
17767
  if (!key) return "";
17712
17768
  const digest = createHash2("sha256").update(key, "utf8").digest("hex").slice(0, 32);
17713
- return join6(resolvePluginData(), "tui-prompt-history", `${digest}.json`);
17769
+ return join7(resolvePluginData(), "tui-prompt-history", `${digest}.json`);
17714
17770
  }
17715
17771
  function readEntries(filePath) {
17716
- if (!filePath || !existsSync6(filePath)) return [];
17772
+ if (!filePath || !existsSync7(filePath)) return [];
17717
17773
  try {
17718
- const parsed = JSON.parse(readFileSync5(filePath, "utf8"));
17774
+ const parsed = JSON.parse(readFileSync6(filePath, "utf8"));
17719
17775
  const entries = Array.isArray(parsed?.entries) ? parsed.entries : [];
17720
17776
  return entries.map((entry) => String(entry || "").trim()).filter((entry) => promptHistoryKey2(entry));
17721
17777
  } catch {
@@ -17729,9 +17785,9 @@ function buildPayload(entries) {
17729
17785
  function writeEntriesSync(filePath, entries) {
17730
17786
  if (!filePath) return false;
17731
17787
  try {
17732
- mkdirSync5(dirname6(filePath), { recursive: true, mode: 448 });
17788
+ mkdirSync6(dirname7(filePath), { recursive: true, mode: 448 });
17733
17789
  const tmp = `${filePath}.${process.pid}.tmp`;
17734
- writeFileSync4(tmp, buildPayload(entries), { encoding: "utf8", mode: 384 });
17790
+ writeFileSync5(tmp, buildPayload(entries), { encoding: "utf8", mode: 384 });
17735
17791
  renameSync3(tmp, filePath);
17736
17792
  try {
17737
17793
  chmodSync(filePath, 384);
@@ -17745,7 +17801,7 @@ function writeEntriesSync(filePath, entries) {
17745
17801
  async function writeEntriesAsync(filePath, entries) {
17746
17802
  if (!filePath) return false;
17747
17803
  try {
17748
- await mkdir(dirname6(filePath), { recursive: true, mode: 448 });
17804
+ await mkdir(dirname7(filePath), { recursive: true, mode: 448 });
17749
17805
  const tmp = `${filePath}.${process.pid}.tmp`;
17750
17806
  await writeFile(tmp, buildPayload(entries), { encoding: "utf8", mode: 384 });
17751
17807
  await rename(tmp, filePath);
@@ -18945,7 +19001,9 @@ function ToolExecution({ name, args, result, rawResult, isError, errorCount, exp
18945
19001
  const finalStatusColor = toolStatusColor({ pending, groupCount, failedCount, terminalStatus });
18946
19002
  const dotColor = finalStatusColor;
18947
19003
  const markerGlyph = isAgentResponse ? AGENT_RESPONSE_MARKER : isAgentSurfaceCard ? AGENT_CALL_MARKER : TURN_MARKER;
18948
- const dotText = pending && !blinkExpired && !blinkOn ? " " : markerGlyph;
19004
+ const isDirectionalMarker = isAgentResponse || isAgentSurfaceCard;
19005
+ const markerText = isDirectionalMarker ? `${markerGlyph} ` : markerGlyph;
19006
+ const dotText = pending && !blinkExpired && !blinkOn ? " " : markerText;
18949
19007
  let labelText;
18950
19008
  if (isAgentResponse) labelText = agentResponseTitle(parsedArgs);
18951
19009
  else if (isBackgroundResponse) labelText = backgroundTaskResultTitle(normalizedName, backgroundMeta || parsedArgs);
@@ -21348,7 +21406,7 @@ function App({ store, initialStatusLine = "", forceOnboarding = false }) {
21348
21406
  /* @__PURE__ */ jsx20(Text20, { color: theme.logo ?? theme.claude, bold: true, children: centerLine("\u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551", frameColumns) }),
21349
21407
  /* @__PURE__ */ jsx20(Text20, { color: theme.logo ?? theme.claude, bold: true, children: centerLine("\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2554\u255D \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D", frameColumns) }),
21350
21408
  /* @__PURE__ */ jsx20(Box18, { height: 1, flexShrink: 0 }),
21351
- /* @__PURE__ */ jsx20(Text20, { color: theme.inactive, children: centerLine(`mixdog coding agent \xB7 ${state.cwd}`, frameColumns, 4) })
21409
+ /* @__PURE__ */ jsx20(Text20, { color: theme.inactive, children: centerLine(`mixdog coding agent \xB7 v${localPackageVersion()} \xB7 ${state.cwd}`, frameColumns, 4) })
21352
21410
  ] }) : null,
21353
21411
  /* @__PURE__ */ jsxs16(
21354
21412
  Box18,
@@ -22574,7 +22632,9 @@ function resolveTuiRuntimeNotificationDelivery(event, text) {
22574
22632
  const parsed = parseAgentJob(trimmed);
22575
22633
  const meta = event?.meta && typeof event.meta === "object" ? event.meta : {};
22576
22634
  if (meta.kind === "update-notice") {
22577
- return { action: "notice", displayText: trimmed, tone: meta.tone === "warn" ? "warn" : "info" };
22635
+ const ver = String(meta.version || "").trim();
22636
+ const displayText = ver ? `mixdog v${ver} ready \u2014 restart to apply.` : trimmed;
22637
+ return { action: "notice", displayText, tone: meta.tone === "warn" ? "warn" : "info" };
22578
22638
  }
22579
22639
  if (!isExecutionNotification(event, trimmed, parsed)) {
22580
22640
  return { action: "enqueue", displayText: trimmed, modelContent: trimmed };
@@ -23115,7 +23175,7 @@ function createAgentJobFeed({
23115
23175
 
23116
23176
  // src/tui/engine/tui-steering-persist.mjs
23117
23177
  import { randomBytes as randomBytes3 } from "crypto";
23118
- import { join as join7 } from "path";
23178
+ import { join as join8 } from "path";
23119
23179
  var PENDING_MESSAGES_FILE = "session-pending-messages.json";
23120
23180
  var PENDING_MESSAGES_MODE = 384;
23121
23181
  var _persistChain = Promise.resolve();
@@ -23126,7 +23186,7 @@ function _serialize(task) {
23126
23186
  return run;
23127
23187
  }
23128
23188
  function pendingMessagesPath() {
23129
- return join7(resolvePluginData(), PENDING_MESSAGES_FILE);
23189
+ return join8(resolvePluginData(), PENDING_MESSAGES_FILE);
23130
23190
  }
23131
23191
  function tuiSteeringSessionKey(leadSessionId) {
23132
23192
  if (typeof leadSessionId !== "string" || !/^[A-Za-z0-9_-]+$/.test(leadSessionId)) return null;
@@ -25156,52 +25216,8 @@ function createEngineApiB(bag) {
25156
25216
  };
25157
25217
  }
25158
25218
 
25159
- // src/runtime/shared/update-checker.mjs
25160
- import { dirname as dirname7, join as join8 } from "node:path";
25161
- import { fileURLToPath as fileURLToPath2 } from "node:url";
25162
-
25163
- // src/runtime/shared/spawn-flags.mjs
25164
- var isWin = process.platform === "win32";
25165
- var detachedSpawnOpts = Object.freeze({
25166
- windowsHide: true,
25167
- ...isWin ? {} : { detached: true }
25168
- });
25169
- var hiddenSpawnOpts = Object.freeze({
25170
- windowsHide: true
25171
- });
25172
-
25173
- // src/runtime/shared/update-checker.mjs
25174
- var PACKAGE_NAME = "mixdog";
25175
- var REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
25176
- var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
25177
- var _MODULE_DIR = dirname7(fileURLToPath2(import.meta.url));
25178
- var _PACKAGE_JSON_PATH = join8(_MODULE_DIR, "..", "..", "..", "package.json");
25179
- var _PACKAGE_ROOT = dirname7(_PACKAGE_JSON_PATH);
25180
- function parseSemver(value) {
25181
- const text = String(value || "").trim().replace(/^v/i, "");
25182
- const [core, ...preParts] = text.split("-");
25183
- const parts = core.split(".").map((n) => {
25184
- const num2 = Number.parseInt(n, 10);
25185
- return Number.isFinite(num2) ? num2 : 0;
25186
- });
25187
- while (parts.length < 3) parts.push(0);
25188
- return { parts, prerelease: preParts.join("-") };
25189
- }
25190
- function compareSemver(a, b) {
25191
- const pa = parseSemver(a);
25192
- const pb = parseSemver(b);
25193
- for (let i = 0; i < 3; i++) {
25194
- const diff = (pa.parts[i] || 0) - (pb.parts[i] || 0);
25195
- if (diff !== 0) return diff;
25196
- }
25197
- if (pa.prerelease && !pb.prerelease) return -1;
25198
- if (!pa.prerelease && pb.prerelease) return 1;
25199
- if (pa.prerelease !== pb.prerelease) return pa.prerelease < pb.prerelease ? -1 : 1;
25200
- return 0;
25201
- }
25202
-
25203
25219
  // src/tui/app/doctor.mjs
25204
- import { readFileSync as readFileSync6 } from "node:fs";
25220
+ import { readFileSync as readFileSync7 } from "node:fs";
25205
25221
  import { dirname as dirname8, join as join9 } from "node:path";
25206
25222
  import { fileURLToPath as fileURLToPath3 } from "node:url";
25207
25223
  var GLYPH = { ok: "\u2713", warn: "\u26A0", fail: "\u2717" };
@@ -25228,7 +25244,7 @@ function median(nums) {
25228
25244
  function readPackageJson() {
25229
25245
  try {
25230
25246
  const dir = dirname8(fileURLToPath3(import.meta.url));
25231
- const raw = JSON.parse(readFileSync6(join9(dir, "..", "..", "..", "package.json"), "utf8"));
25247
+ const raw = JSON.parse(readFileSync7(join9(dir, "..", "..", "..", "package.json"), "utf8"));
25232
25248
  return raw && typeof raw === "object" ? raw : null;
25233
25249
  } catch {
25234
25250
  return null;
@@ -25364,7 +25380,7 @@ async function buildDoctorReport(runtime = {}, getState = () => ({})) {
25364
25380
  const pgdata = join9(dataDir, "pgdata");
25365
25381
  let writes;
25366
25382
  try {
25367
- writes = parseCheckpointWriteSeconds(readFileSync6(join9(dataDir, "pg.log"), "utf8"));
25383
+ writes = parseCheckpointWriteSeconds(readFileSync7(join9(dataDir, "pg.log"), "utf8"));
25368
25384
  } catch {
25369
25385
  row("ok", "pg.log unavailable \xB7 check skipped");
25370
25386
  return;
@@ -26732,7 +26748,7 @@ function paintBootSplash() {
26732
26748
  `;
26733
26749
  }
26734
26750
  out += "\r\n";
26735
- out += `${subtleFg}${center(`mixdog coding agent \xB7 ${process.cwd()}`)}${reset}`;
26751
+ out += `${subtleFg}${center(`mixdog coding agent \xB7 v${localPackageVersion()} \xB7 ${process.cwd()}`)}${reset}`;
26736
26752
  out += "\x1B[H";
26737
26753
  process.stdout.write(out);
26738
26754
  return { stop: () => {
@@ -26782,7 +26798,7 @@ function installTuiStderrGuard() {
26782
26798
  const originalWrite = process.stderr.write.bind(process.stderr);
26783
26799
  const logPath = resolveTuiStderrLogPath();
26784
26800
  try {
26785
- mkdirSync6(dirname9(logPath), { recursive: true });
26801
+ mkdirSync7(dirname9(logPath), { recursive: true });
26786
26802
  } catch {
26787
26803
  }
26788
26804
  (0, import_mixdog_debug.rotateBoundedLog)(logPath, import_mixdog_debug.PLUGIN_LOG_MAX_BYTES, import_mixdog_debug.PLUGIN_LOG_KEEP_BYTES);