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.
- package/package.json +6 -2
- package/src/app.mjs +14 -0
- package/src/rules/lead/lead-tool.md +1 -2
- package/src/rules/shared/01-tool.md +13 -11
- package/src/runtime/channels/backends/discord-access.mjs +1 -3
- package/src/runtime/channels/backends/telegram.mjs +1 -1
- package/src/runtime/channels/lib/config.mjs +5 -29
- package/src/runtime/memory/tool-defs.mjs +1 -1
- package/src/runtime/shared/config.mjs +1 -6
- package/src/runtime/shared/schedules-db.mjs +2 -120
- package/src/runtime/shared/webhooks-db.mjs +3 -138
- package/src/session-runtime/runtime-core.mjs +32 -10
- package/src/standalone/agent-tool/tool-def.mjs +1 -1
- package/src/standalone/channel-admin.mjs +6 -27
- package/src/tui/App.jsx +2 -1
- package/src/tui/components/StatusLine.jsx +2 -2
- package/src/tui/components/ToolExecution.jsx +10 -1
- package/src/tui/display-width.mjs +4 -1
- package/src/tui/dist/index.mjs +173 -157
- package/src/tui/engine/notification-plan.mjs +5 -1
- package/src/tui/index.jsx +2 -1
- package/src/workflows/default/WORKFLOW.md +15 -11
- package/vendor/ink/build/display-width.js +3 -1
package/src/tui/dist/index.mjs
CHANGED
|
@@ -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
|
|
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 &&
|
|
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 &&
|
|
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
|
|
7276
|
-
import { basename as basename2, dirname, isAbsolute as isAbsolute2, join, resolve as resolve2 } from "node:path";
|
|
7277
|
-
var MIXDOG_HOME = process.env.MIXDOG_HOME ||
|
|
7278
|
-
var PROJECTS_FILE =
|
|
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 (!
|
|
7291
|
-
const raw =
|
|
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
|
-
|
|
7376
|
+
mkdirSync2(dirname3(PROJECTS_FILE), { recursive: true });
|
|
7309
7377
|
const tmp = `${PROJECTS_FILE}.${process.pid}.tmp`;
|
|
7310
|
-
|
|
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 =
|
|
7325
|
-
if (
|
|
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 =
|
|
7329
|
-
|
|
7396
|
+
const markerDir = join3(absPath, ".mixdog");
|
|
7397
|
+
mkdirSync2(markerDir, { recursive: true });
|
|
7330
7398
|
const tmp = `${markerPath}.${process.pid}.tmp`;
|
|
7331
|
-
|
|
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 &&
|
|
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
|
-
|
|
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
|
|
14166
|
-
import { join as
|
|
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
|
|
14240
|
+
existsSync as existsSync4,
|
|
14185
14241
|
fsyncSync,
|
|
14186
14242
|
linkSync,
|
|
14187
|
-
mkdirSync as
|
|
14243
|
+
mkdirSync as mkdirSync3,
|
|
14188
14244
|
openSync,
|
|
14189
|
-
readFileSync as
|
|
14245
|
+
readFileSync as readFileSync3,
|
|
14190
14246
|
renameSync as renameSync2,
|
|
14191
14247
|
statSync as statSync2,
|
|
14192
14248
|
unlinkSync as unlinkSync2,
|
|
14193
|
-
writeFileSync as
|
|
14249
|
+
writeFileSync as writeFileSync3
|
|
14194
14250
|
} from "fs";
|
|
14195
|
-
import { dirname as
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
14549
|
-
if (
|
|
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 =
|
|
14578
|
-
if (!
|
|
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 =
|
|
14605
|
-
if (
|
|
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 =
|
|
14630
|
-
if (!
|
|
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 =
|
|
14650
|
-
|
|
14651
|
-
const 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
|
-
|
|
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 =
|
|
14691
|
-
|
|
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 (
|
|
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(
|
|
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
|
|
14755
|
-
mkdirSync as
|
|
14810
|
+
existsSync as existsSync5,
|
|
14811
|
+
mkdirSync as mkdirSync4,
|
|
14756
14812
|
readdirSync,
|
|
14757
|
-
readFileSync as
|
|
14813
|
+
readFileSync as readFileSync4,
|
|
14758
14814
|
rmSync,
|
|
14759
14815
|
statSync as statSync3,
|
|
14760
|
-
writeFileSync as
|
|
14816
|
+
writeFileSync as writeFileSync4
|
|
14761
14817
|
} from "fs";
|
|
14762
|
-
import { dirname as
|
|
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 ||
|
|
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 ||
|
|
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
|
|
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
|
|
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 =
|
|
14814
|
-
if (!
|
|
14869
|
+
const cfgPath = join5(root, name, "mixdog-config.json");
|
|
14870
|
+
if (!existsSync5(cfgPath)) continue;
|
|
14815
14871
|
try {
|
|
14816
|
-
const parsed = JSON.parse(
|
|
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(
|
|
14884
|
+
copyTree(join5(src, name), join5(dst, name), copied);
|
|
14829
14885
|
}
|
|
14830
14886
|
return;
|
|
14831
14887
|
}
|
|
14832
14888
|
if (!st.isFile()) return;
|
|
14833
|
-
|
|
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(
|
|
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
|
-
|
|
14854
|
-
|
|
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 || !
|
|
14866
|
-
const backupDir =
|
|
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 =
|
|
14870
|
-
if (
|
|
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 =
|
|
14874
|
-
if (
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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 (
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
17769
|
+
return join7(resolvePluginData(), "tui-prompt-history", `${digest}.json`);
|
|
17714
17770
|
}
|
|
17715
17771
|
function readEntries(filePath) {
|
|
17716
|
-
if (!filePath || !
|
|
17772
|
+
if (!filePath || !existsSync7(filePath)) return [];
|
|
17717
17773
|
try {
|
|
17718
|
-
const parsed = JSON.parse(
|
|
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
|
-
|
|
17788
|
+
mkdirSync6(dirname7(filePath), { recursive: true, mode: 448 });
|
|
17733
17789
|
const tmp = `${filePath}.${process.pid}.tmp`;
|
|
17734
|
-
|
|
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(
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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);
|