mixdog 1.1.0 → 1.1.2
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/README.md +13 -6
- package/package.json +1 -2
- package/scripts/latest-guard.mjs +63 -0
- package/scripts/lib/run-node-tests.mjs +103 -27
- package/scripts/lib/test-failure-summary.mjs +7 -2
- package/scripts/merge-mac-update-feed.mjs +107 -0
- package/scripts/mobile-release.mjs +210 -0
- package/scripts/post-release-check.mjs +353 -0
- package/scripts/publish-asset-release.mjs +43 -0
- package/scripts/release-guard.mjs +63 -0
- package/scripts/release-paths.mjs +39 -2
- package/scripts/test.mjs +29 -7
- package/src/defaults/shipped-history.json +2 -0
- package/src/defaults/skills/computer-use/SKILL.md +1 -1
- package/src/defaults/skills/setup/references/actions.md +1 -0
- package/src/headless-role.mjs +2 -2
- package/src/lib/keychain-cjs.cjs +582 -17
- package/src/lib/rules-builder.cjs +0 -23
- package/src/rules/lead/LEAD.md +2 -2
- package/src/runtime/agent/orchestrator/config-storage.mjs +32 -4
- package/src/runtime/agent/orchestrator/config.mjs +18 -0
- package/src/runtime/agent/orchestrator/context/instruction-files.mjs +130 -0
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +11 -0
- package/src/runtime/agent/orchestrator/providers/lib/open-login-url.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-login.mjs +254 -0
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +218 -0
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-tokens.mjs +239 -0
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +233 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth-login.mjs +247 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth-tokens.mjs +225 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +542 -0
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +25 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/openai-codex-model.mjs +13 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +14 -6
- package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog-store.mjs +99 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog.mjs +4 -8
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +2 -7
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +8 -0
- package/src/runtime/agent/orchestrator/providers/registry.mjs +4 -0
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +2 -0
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +15 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +1 -5
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +12 -14
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +11 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-call-ids.mjs +90 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +19 -11
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +28 -0
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +1 -5
- package/src/runtime/agent/orchestrator/session/read-dedup.mjs +0 -1
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/turn-effort.mjs +18 -0
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +11 -8
- package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +9 -4
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/bashism-rewrite.mjs +245 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +13 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +49 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +9 -7
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +61 -8
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +28 -3
- package/src/runtime/agent/orchestrator/tools/builtin/path-utils.mjs +73 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-guards.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +17 -6
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +23 -5
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +93 -43
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +32 -6
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +9 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +12 -15
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +124 -91
- package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +19 -4
- package/src/runtime/channels/index.mjs +1 -5
- package/src/runtime/channels/lib/runtime-paths.mjs +8 -23
- package/src/runtime/channels/lib/tool-dispatch.mjs +1 -13
- package/src/runtime/channels/lib/worker-ipc.mjs +2 -2
- package/src/runtime/channels/lib/worker-main.mjs +4 -34
- package/src/runtime/computer-bridge/client.mjs +25 -1
- package/src/runtime/computer-bridge/linux-action-capabilities.mjs +84 -0
- package/src/runtime/computer-bridge/linux-readiness.d.mts +52 -0
- package/src/runtime/computer-bridge/linux-readiness.mjs +411 -0
- package/src/runtime/computer-bridge/test-linux-display.mjs +5 -0
- package/src/runtime/effort-judge/compact-tokenizer.mjs +13 -8
- package/src/runtime/effort-judge/judge-input.mjs +5 -2
- package/src/runtime/effort-judge/model-install.mjs +9 -3
- package/src/runtime/effort-judge/model-manifest.json +7 -7
- package/src/runtime/memory/lib/embedding-worker.mjs +9 -3
- package/src/runtime/memory/lib/pg/supervisor.mjs +3 -0
- package/src/runtime/shared/config.mjs +50 -2
- package/src/runtime/shared/developer-options.mjs +7 -0
- package/src/runtime/shared/instruction-files-mode.mjs +9 -0
- package/src/runtime/shared/llm/model-catalog.mjs +2 -1
- package/src/runtime/shared/llm/openai-daybreak.mjs +79 -0
- package/src/runtime/shared/pristine-execution-contract.json +9 -0
- package/src/runtime/shared/pristine-execution.mjs +1 -1
- package/src/runtime/shared/provider-accounts.mjs +2 -0
- package/src/runtime/shared/resource-admission.mjs +10 -3
- package/src/runtime/shared/schedule-model-ref.mjs +11 -0
- package/src/runtime/shared/semver.d.mts +1 -0
- package/src/runtime/shared/semver.mjs +57 -0
- package/src/runtime/shared/session-approval-wait.mjs +35 -0
- package/src/runtime/shared/shell-display.mjs +4 -2
- package/src/runtime/shared/tool-surface.mjs +2 -2
- package/src/runtime/shared/turn-worktree-snapshot.mjs +11 -10
- package/src/runtime/shared/update-checker.mjs +2 -31
- package/src/session-runtime/boot/apis.mjs +5 -0
- package/src/session-runtime/boot/begin.mjs +0 -2
- package/src/session-runtime/boot/tools.mjs +5 -4
- package/src/session-runtime/model-recency.mjs +3 -0
- package/src/session-runtime/provider-auth/login.mjs +10 -10
- package/src/session-runtime/provider-auth/setup.mjs +22 -2
- package/src/session-runtime/provider-models/row-hydration.mjs +12 -4
- package/src/session-runtime/provider-readiness.mjs +4 -0
- package/src/session-runtime/resource-mcp-api.mjs +7 -3
- package/src/session-runtime/runtime-bootstrap.mjs +0 -4
- package/src/session-runtime/runtime-facade.mjs +5 -0
- package/src/session-runtime/runtime-paths.mjs +0 -1
- package/src/session-runtime/schedule-session-run.mjs +3 -1
- package/src/session-runtime/services/agent-tool/index-write-queue.mjs +55 -14
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +15 -3
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +2 -0
- package/src/session-runtime/services/agent-tool/worker-index/approval-wait.mjs +97 -0
- package/src/session-runtime/services/agent-tool/worker-index/mutation-batch.mjs +4 -2
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +8 -2
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +3 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +58 -2
- package/src/session-runtime/services/agent-tool/worker-index.mjs +69 -15
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +2 -0
- package/src/session-runtime/services/channel-admin.mjs +4 -2
- package/src/session-runtime/services/channel-worker.mjs +1 -1
- package/src/session-runtime/services/provider-admin.mjs +80 -17
- package/src/session-runtime/services/seeds.mjs +7 -10
- package/src/session-runtime/services/usage-dashboard-model.mjs +6 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +15 -0
- package/src/session-runtime/settings-profile-api.mjs +27 -2
- package/src/session-runtime/setup-tool/executor.mjs +5 -0
- package/src/session-runtime/setup-tool/tool-defs.mjs +8 -0
- package/src/session-runtime/starter-guide-state.mjs +62 -0
- package/src/session-runtime/tool-policy-refresh.mjs +3 -0
- package/src/session-runtime/webhook-session-run.mjs +3 -1
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -2
- package/src/standalone/channel-binding.mjs +1 -2
- package/src/standalone/channel-transport/call-dispatch.mjs +4 -10
- package/src/standalone/daemon-channels-loader.mjs +2 -3
- package/src/standalone/local-session-runtime.mjs +2 -78
- package/src/standalone/session-protocol.mjs +2 -0
- package/src/tui/app/model-options.mjs +13 -1
- package/src/tui/app/model-picker/route-selection/fast-parameters.mjs +10 -4
- package/src/tui/app/provider-setup/oauth-actions.mjs +5 -0
- package/src/tui/dist/index.mjs +84 -34
- package/src/tui/session/context-state.mjs +2 -0
- package/src/tui/session/live-share/owner.mjs +17 -0
- package/src/tui/session/oauth-flows.mjs +2 -0
- package/src/tui/session/session-api/extensions.mjs +12 -8
- package/src/tui/session/session-api/integrations.mjs +9 -8
- package/src/tui/session/session-api/routes.mjs +2 -2
- package/src/tui/session/session-api/settings.mjs +1 -0
- package/src/tui/session/session-api/shared.mjs +10 -6
- package/src/tui/session/tool-card-results/grouped-result.mjs +11 -2
- package/src/tui/session/transcript-spill/spill-dir.mjs +22 -6
- package/src/tui/spinner-meta.mjs +26 -10
- package/src/runtime/channels/tool-defs.mjs +0 -17
package/src/tui/dist/index.mjs
CHANGED
|
@@ -41514,7 +41514,7 @@ function describeError(value) {
|
|
|
41514
41514
|
const { raw, message, status, code } = unwrap(value);
|
|
41515
41515
|
const rejected429 = isRejected429(value);
|
|
41516
41516
|
const details = safeErrorDetails(raw);
|
|
41517
|
-
const
|
|
41517
|
+
const clean3 = safeErrorDetails(message).replace(/^(?:Error invoking remote method ['"][^'"]+['"]:\s*)?(?:Error:\s*)?/i, "").trim();
|
|
41518
41518
|
let kind = "unknown";
|
|
41519
41519
|
let summary = "";
|
|
41520
41520
|
let recovery = "";
|
|
@@ -41523,21 +41523,21 @@ function describeError(value) {
|
|
|
41523
41523
|
kind = "reauth";
|
|
41524
41524
|
summary = "Sign-in expired.";
|
|
41525
41525
|
recovery = "Sign in again from Providers.";
|
|
41526
|
-
} else if (status === 401 || status === 403 || /\b(?:invalid|expired)\s+(?:api[ _-]?key|access token|credentials?)\b|Provider authentication failed/i.test(
|
|
41526
|
+
} else if (status === 401 || status === 403 || /\b(?:invalid|expired)\s+(?:api[ _-]?key|access token|credentials?)\b|Provider authentication failed/i.test(clean3)) {
|
|
41527
41527
|
kind = "authentication";
|
|
41528
41528
|
summary = "Provider authentication failed";
|
|
41529
41529
|
recovery = "Check your sign-in or API key, then try again.";
|
|
41530
41530
|
} else if (/image.*dimensions.*exceed|image.*(?:too large|maximum.*(?:size|dimension))|many-image requests|An attached image exceeds the provider limit/i.test(
|
|
41531
|
-
|
|
41531
|
+
clean3
|
|
41532
41532
|
)) {
|
|
41533
41533
|
kind = "image-size";
|
|
41534
41534
|
summary = "An attached image exceeds the provider limit.";
|
|
41535
41535
|
recovery = "Reduce the image dimensions or number of images, then try again.";
|
|
41536
|
-
} else if (status === 413 || /payload too large|request (?:body )?too large|The request exceeds the size limit/i.test(
|
|
41536
|
+
} else if (status === 413 || /payload too large|request (?:body )?too large|The request exceeds the size limit/i.test(clean3)) {
|
|
41537
41537
|
kind = "payload-size";
|
|
41538
41538
|
summary = "The request exceeds the size limit.";
|
|
41539
41539
|
recovery = "Reduce the attachments or request size, then try again.";
|
|
41540
|
-
} else if (!rejected429 && (status === 429 || /rate[_ -]?limit|quota.*(?:hit|exceed)|too many requests|The provider usage limit was reached/i.test(
|
|
41540
|
+
} else if (!rejected429 && (status === 429 || /rate[_ -]?limit|quota.*(?:hit|exceed)|too many requests|The provider usage limit was reached/i.test(clean3))) {
|
|
41541
41541
|
kind = "rate-limit";
|
|
41542
41542
|
summary = "The provider usage limit was reached.";
|
|
41543
41543
|
recovery = "Wait for the limit to reset or choose another account.";
|
|
@@ -41545,12 +41545,12 @@ function describeError(value) {
|
|
|
41545
41545
|
kind = "connection";
|
|
41546
41546
|
summary = transport.replace(/\.$/, "");
|
|
41547
41547
|
recovery = "Check the connection, then try again.";
|
|
41548
|
-
} else if (rejected429 || status === 400 || status === 422 || code === "invalid_request_error" ||
|
|
41548
|
+
} else if (rejected429 || status === 400 || status === 422 || code === "invalid_request_error" || clean3 === "The provider rejected this request.") {
|
|
41549
41549
|
kind = "request";
|
|
41550
41550
|
summary = "The provider rejected this request.";
|
|
41551
41551
|
recovery = "Review the request details before trying again.";
|
|
41552
41552
|
} else {
|
|
41553
|
-
const lines =
|
|
41553
|
+
const lines = clean3.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
41554
41554
|
const first = lines.find((line) => !/^at\s|^\{|^<!doctype|^<html/i.test(line)) || "";
|
|
41555
41555
|
summary = first && !/^[{[]|^<|(?:API|HTTP)\s+[45]\d\d.*[<{]/i.test(first) ? first : "Something went wrong.";
|
|
41556
41556
|
}
|
|
@@ -48421,16 +48421,22 @@ function formatSpinnerTokens(value) {
|
|
|
48421
48421
|
if (tokens >= 1e3) return compactNumberFormatter.format(tokens).toLowerCase();
|
|
48422
48422
|
return String(Math.round(tokens));
|
|
48423
48423
|
}
|
|
48424
|
-
function
|
|
48424
|
+
function effortLevel(effort) {
|
|
48425
48425
|
const level = String(effort || "").trim().toLowerCase();
|
|
48426
48426
|
if (!level || level === "auto" || level === "default" || level === "off" || level === "none") return "";
|
|
48427
|
-
return
|
|
48427
|
+
return level;
|
|
48428
48428
|
}
|
|
48429
|
-
function
|
|
48430
|
-
if (thinking || Number(thinkingSince) > 0) return
|
|
48429
|
+
function spinnerThinkingParts({ thinking = false, thinkingSince = 0, thinkingMs = 0, effort = "" } = {}) {
|
|
48430
|
+
if (thinking || Number(thinkingSince) > 0) return { kind: "thinking", effort: effortLevel(effort) };
|
|
48431
48431
|
const ms = Math.max(0, Number(thinkingMs) || 0);
|
|
48432
|
-
if (ms >= 1e3) return
|
|
48433
|
-
return
|
|
48432
|
+
if (ms >= 1e3) return { kind: "thought", seconds: Math.max(1, Math.round(ms / 1e3)) };
|
|
48433
|
+
return null;
|
|
48434
|
+
}
|
|
48435
|
+
function spinnerThinkingLabel(options = {}) {
|
|
48436
|
+
const parts = spinnerThinkingParts(options);
|
|
48437
|
+
if (!parts) return "";
|
|
48438
|
+
if (parts.kind === "thinking") return `thinking${parts.effort ? ` (${parts.effort})` : ""}`;
|
|
48439
|
+
return `thought for ${parts.seconds}s`;
|
|
48434
48440
|
}
|
|
48435
48441
|
function buildSpinnerMeta({
|
|
48436
48442
|
elapsedMs: _elapsedMs = 0,
|
|
@@ -48442,8 +48448,12 @@ function buildSpinnerMeta({
|
|
|
48442
48448
|
verbose: _verbose = false
|
|
48443
48449
|
} = {}) {
|
|
48444
48450
|
const tokens = Math.max(0, Number(outputTokens) || 0);
|
|
48451
|
+
const thinkingParts = spinnerThinkingParts({ thinking, thinkingSince, thinkingMs, effort });
|
|
48445
48452
|
const thinkingText = spinnerThinkingLabel({ thinking, thinkingSince, thinkingMs, effort });
|
|
48446
48453
|
return {
|
|
48454
|
+
// Structured twins of tokensText / thinkingText for surfaces that translate them.
|
|
48455
|
+
tokensCount: tokens > 0 ? formatSpinnerTokens(tokens) : "",
|
|
48456
|
+
thinkingParts,
|
|
48447
48457
|
tokensText: tokens > 0 ? `${formatSpinnerTokens(tokens)} tokens` : "",
|
|
48448
48458
|
// The count appears with the FIRST token (user: 30초가 아니라 바로).
|
|
48449
48459
|
// Elapsed was never gated, so the byline used to grow a second field
|
|
@@ -55140,7 +55150,7 @@ function createThemeEffortPickers({
|
|
|
55140
55150
|
setProviderPrompt,
|
|
55141
55151
|
setSettingsPrompt,
|
|
55142
55152
|
closeUsagePanel,
|
|
55143
|
-
clean:
|
|
55153
|
+
clean: clean3
|
|
55144
55154
|
}) {
|
|
55145
55155
|
const openThemePicker = (options = {}) => {
|
|
55146
55156
|
const returnTo = typeof options.returnTo === "function" ? options.returnTo : null;
|
|
@@ -55247,7 +55257,7 @@ function createThemeEffortPickers({
|
|
|
55247
55257
|
...item,
|
|
55248
55258
|
marker: item?.value === current ? "\u2713" : "",
|
|
55249
55259
|
markerColor: theme.success,
|
|
55250
|
-
description:
|
|
55260
|
+
description: clean3(item?.description).toLowerCase() === "current" ? "" : item?.description
|
|
55251
55261
|
}));
|
|
55252
55262
|
own.paint({
|
|
55253
55263
|
title: "Effort",
|
|
@@ -55696,7 +55706,7 @@ var pluginDetailItems = (p) => [
|
|
|
55696
55706
|
];
|
|
55697
55707
|
function createPluginsPickers({
|
|
55698
55708
|
store,
|
|
55699
|
-
clean:
|
|
55709
|
+
clean: clean3,
|
|
55700
55710
|
copyToClipboard: copyToClipboard2,
|
|
55701
55711
|
surface,
|
|
55702
55712
|
setProviderPrompt,
|
|
@@ -55712,7 +55722,7 @@ function createPluginsPickers({
|
|
|
55712
55722
|
const own = surface.claim();
|
|
55713
55723
|
own.paint({
|
|
55714
55724
|
title: p.title || p.name,
|
|
55715
|
-
description:
|
|
55725
|
+
description: clean3(p.description) || "Update, MCP, or uninstall this plugin.",
|
|
55716
55726
|
items: pluginDetailItems(p),
|
|
55717
55727
|
onSelect: (_detailValue, detail) => {
|
|
55718
55728
|
own.paint(null);
|
|
@@ -55899,7 +55909,7 @@ function createProjectSkillsPicker({
|
|
|
55899
55909
|
// src/tui/app/extension-pickers/skills-pickers/skill-detail.mjs
|
|
55900
55910
|
function createSkillDetailPickers({
|
|
55901
55911
|
store,
|
|
55902
|
-
clean:
|
|
55912
|
+
clean: clean3,
|
|
55903
55913
|
surface,
|
|
55904
55914
|
setSettingsPrompt,
|
|
55905
55915
|
getDisabledSkills,
|
|
@@ -55922,7 +55932,7 @@ function createSkillDetailPickers({
|
|
|
55922
55932
|
const openSkillDetailPicker = (skill) => {
|
|
55923
55933
|
const own = surface.claim();
|
|
55924
55934
|
const disabled = getDisabledSkills().has(skill.name);
|
|
55925
|
-
const summary = [
|
|
55935
|
+
const summary = [clean3(skill.description), clean3(skill.whenToUse)].filter(Boolean).join(" \u2014 ");
|
|
55926
55936
|
own.paint({
|
|
55927
55937
|
title: `Skill \xB7 ${skill.name}`,
|
|
55928
55938
|
description: summary || "Enable, disable, or run this skill.",
|
|
@@ -55972,7 +55982,7 @@ function createSkillDetailPickers({
|
|
|
55972
55982
|
function createSkillsPickers({
|
|
55973
55983
|
store,
|
|
55974
55984
|
theme: theme2,
|
|
55975
|
-
clean:
|
|
55985
|
+
clean: clean3,
|
|
55976
55986
|
surface,
|
|
55977
55987
|
setProviderPrompt,
|
|
55978
55988
|
setSettingsPrompt,
|
|
@@ -56029,7 +56039,7 @@ function createSkillsPickers({
|
|
|
56029
56039
|
};
|
|
56030
56040
|
const { openSkillDetailPicker } = createSkillDetailPickers({
|
|
56031
56041
|
store,
|
|
56032
|
-
clean:
|
|
56042
|
+
clean: clean3,
|
|
56033
56043
|
surface,
|
|
56034
56044
|
setSettingsPrompt,
|
|
56035
56045
|
getDisabledSkills,
|
|
@@ -56051,7 +56061,7 @@ function createSkillsPickers({
|
|
|
56051
56061
|
function createExtensionPickers({
|
|
56052
56062
|
store,
|
|
56053
56063
|
theme: theme2,
|
|
56054
|
-
clean:
|
|
56064
|
+
clean: clean3,
|
|
56055
56065
|
copyToClipboard: copyToClipboard2,
|
|
56056
56066
|
surface,
|
|
56057
56067
|
getPicker,
|
|
@@ -56064,7 +56074,7 @@ function createExtensionPickers({
|
|
|
56064
56074
|
const skills = createSkillsPickers({
|
|
56065
56075
|
store,
|
|
56066
56076
|
theme: theme2,
|
|
56067
|
-
clean:
|
|
56077
|
+
clean: clean3,
|
|
56068
56078
|
surface,
|
|
56069
56079
|
setProviderPrompt,
|
|
56070
56080
|
setSettingsPrompt,
|
|
@@ -56073,7 +56083,7 @@ function createExtensionPickers({
|
|
|
56073
56083
|
});
|
|
56074
56084
|
const plugins = createPluginsPickers({
|
|
56075
56085
|
store,
|
|
56076
|
-
clean:
|
|
56086
|
+
clean: clean3,
|
|
56077
56087
|
copyToClipboard: copyToClipboard2,
|
|
56078
56088
|
surface,
|
|
56079
56089
|
setProviderPrompt,
|
|
@@ -56667,6 +56677,25 @@ function isRollingModelAlias(id) {
|
|
|
56667
56677
|
return /-latest$/i.test(String(id || "").trim());
|
|
56668
56678
|
}
|
|
56669
56679
|
|
|
56680
|
+
// src/runtime/shared/llm/openai-daybreak.mjs
|
|
56681
|
+
var DAYBREAK_PROVIDER = "openai-oauth";
|
|
56682
|
+
var DAYBREAK_PARAMETER_ID = "daybreak";
|
|
56683
|
+
var DAYBREAK_ON = "on";
|
|
56684
|
+
var DAYBREAK_OFF = "off";
|
|
56685
|
+
var DAYBREAK_PARAMETER_OPTION = Object.freeze({
|
|
56686
|
+
id: DAYBREAK_PARAMETER_ID,
|
|
56687
|
+
label: "Daybreak Blue",
|
|
56688
|
+
kind: "boolean",
|
|
56689
|
+
options: Object.freeze([
|
|
56690
|
+
Object.freeze({ value: DAYBREAK_OFF, label: "Off" }),
|
|
56691
|
+
Object.freeze({ value: DAYBREAK_ON, label: "On" })
|
|
56692
|
+
])
|
|
56693
|
+
});
|
|
56694
|
+
var clean2 = (value) => String(value ?? "").trim();
|
|
56695
|
+
function daybreakBlueOn(modelParameters) {
|
|
56696
|
+
return clean2(modelParameters?.[DAYBREAK_PARAMETER_ID]).toLowerCase() === DAYBREAK_ON;
|
|
56697
|
+
}
|
|
56698
|
+
|
|
56670
56699
|
// src/tui/app/model-options.mjs
|
|
56671
56700
|
var parsedModelVersion = (id) => {
|
|
56672
56701
|
const text = String(id || "").toLowerCase();
|
|
@@ -56799,6 +56828,8 @@ var PROVIDER_DISPLAY_NAMES = /* @__PURE__ */ new Map([
|
|
|
56799
56828
|
["openai-oauth", "OpenAI OAuth"],
|
|
56800
56829
|
["anthropic-oauth", "Anthropic OAuth"],
|
|
56801
56830
|
["grok-oauth", "Grok OAuth"],
|
|
56831
|
+
["muse-code-oauth", "Muse Code"],
|
|
56832
|
+
["mimo-oauth", "MiMo"],
|
|
56802
56833
|
["cursor-oauth", "Cursor OAuth"],
|
|
56803
56834
|
["antigravity-oauth", "Antigravity OAuth"],
|
|
56804
56835
|
["openai", "OpenAI API"],
|
|
@@ -56822,6 +56853,8 @@ var PROVIDER_DISPLAY_RANKS = {
|
|
|
56822
56853
|
"openai-oauth": 10,
|
|
56823
56854
|
"anthropic-oauth": 20,
|
|
56824
56855
|
"grok-oauth": 30,
|
|
56856
|
+
"muse-code-oauth": 33,
|
|
56857
|
+
"mimo-oauth": 34,
|
|
56825
56858
|
"antigravity-oauth": 31,
|
|
56826
56859
|
"cursor-oauth": 32,
|
|
56827
56860
|
"opencode-go": 35,
|
|
@@ -56850,7 +56883,10 @@ var effortDisplayLabel = (value) => {
|
|
|
56850
56883
|
var fastDisplayLabel = (enabled = true) => `Fast ${enabled ? "On" : "Off"}`;
|
|
56851
56884
|
var modelDescription = (m) => [String(m?.description || "").trim(), m.fastCapable ? "Fast Available" : ""].filter(Boolean).join(" \xB7 ");
|
|
56852
56885
|
var modelRecordDisplayName = (model) => displayModelName(model?.id, model?.provider, model?.display || model?.name);
|
|
56853
|
-
var routeModelDisplayName = (route) =>
|
|
56886
|
+
var routeModelDisplayName = (route) => [
|
|
56887
|
+
displayModelName(route?.model, route?.provider, route?.modelDisplay || ""),
|
|
56888
|
+
route?.provider === DAYBREAK_PROVIDER && daybreakBlueOn(route?.modelParameters) ? "Blue" : ""
|
|
56889
|
+
].filter(Boolean).join(" ");
|
|
56854
56890
|
var groupModelsByProvider = (models) => {
|
|
56855
56891
|
const providers = /* @__PURE__ */ new Map();
|
|
56856
56892
|
for (const model of models) {
|
|
@@ -57612,6 +57648,11 @@ function beginInteractiveOAuthLogin(flow, providerItem, login) {
|
|
|
57612
57648
|
`browser opened for ${providerName}; paste code/redirect here if callback does not finish`,
|
|
57613
57649
|
"info"
|
|
57614
57650
|
);
|
|
57651
|
+
} else if (started?.userCode) {
|
|
57652
|
+
flow.store.pushNotice(
|
|
57653
|
+
`${providerName}: enter code ${started.userCode} in the browser to finish signing in`,
|
|
57654
|
+
"info"
|
|
57655
|
+
);
|
|
57615
57656
|
} else {
|
|
57616
57657
|
flow.store.pushNotice(`browser opened for ${providerName}; finish signing in there`, "info");
|
|
57617
57658
|
}
|
|
@@ -58074,6 +58115,7 @@ function createContextSelection({ state, currentRoute, isCurrentRoute, isStateRo
|
|
|
58074
58115
|
}
|
|
58075
58116
|
|
|
58076
58117
|
// src/tui/app/model-picker/route-selection/fast-parameters.mjs
|
|
58118
|
+
var TOGGLE_PARAMETER_IDS = /* @__PURE__ */ new Set(["thinking", DAYBREAK_PARAMETER_ID]);
|
|
58077
58119
|
function createFastParameterSelection({ state, currentRoute, isCurrentRoute, isStateRoute, getSelectedEffort }) {
|
|
58078
58120
|
const selectedFast = /* @__PURE__ */ new Map();
|
|
58079
58121
|
const selectedModelParameters = /* @__PURE__ */ new Map();
|
|
@@ -58138,9 +58180,11 @@ function createFastParameterSelection({ state, currentRoute, isCurrentRoute, isS
|
|
|
58138
58180
|
return true;
|
|
58139
58181
|
};
|
|
58140
58182
|
const cycleThinking = (model) => {
|
|
58141
|
-
const
|
|
58142
|
-
|
|
58183
|
+
const definition = (model.modelParameterOptions || []).find(
|
|
58184
|
+
(parameter) => TOGGLE_PARAMETER_IDS.has(parameter.id)
|
|
58185
|
+
);
|
|
58143
58186
|
if (!definition?.options?.length) return false;
|
|
58187
|
+
const wanted = definition.id;
|
|
58144
58188
|
const parameters = modelParametersFor(model);
|
|
58145
58189
|
const current = Math.max(
|
|
58146
58190
|
0,
|
|
@@ -58431,7 +58475,7 @@ function createAgentsPicker({
|
|
|
58431
58475
|
setProviderPrompt,
|
|
58432
58476
|
setSettingsPrompt,
|
|
58433
58477
|
closeUsagePanel,
|
|
58434
|
-
clean:
|
|
58478
|
+
clean: clean3,
|
|
58435
58479
|
agentModelParts: agentModelParts2,
|
|
58436
58480
|
agentModelProfile: agentModelProfile2,
|
|
58437
58481
|
openModelPicker
|
|
@@ -58515,7 +58559,7 @@ function createAgentsPicker({
|
|
|
58515
58559
|
}
|
|
58516
58560
|
const refreshModels = options.refreshModels === true;
|
|
58517
58561
|
const routeOverrides = options.routeOverrides && typeof options.routeOverrides === "object" ? options.routeOverrides : {};
|
|
58518
|
-
const initialAgentId =
|
|
58562
|
+
const initialAgentId = clean3(options.initialAgentId || "");
|
|
58519
58563
|
const items = agents.map((agent) => ({
|
|
58520
58564
|
value: agent.id,
|
|
58521
58565
|
label: agent.label,
|
|
@@ -58729,7 +58773,7 @@ function createRoutePickers({
|
|
|
58729
58773
|
setProviderPrompt,
|
|
58730
58774
|
setSettingsPrompt,
|
|
58731
58775
|
closeUsagePanel,
|
|
58732
|
-
clean:
|
|
58776
|
+
clean: clean3,
|
|
58733
58777
|
routeLabel: routeLabel2,
|
|
58734
58778
|
agentModelParts: agentModelParts2,
|
|
58735
58779
|
agentModelProfile: agentModelProfile2,
|
|
@@ -58773,7 +58817,7 @@ function createRoutePickers({
|
|
|
58773
58817
|
const panelDeps = { store, surface, setProviderPrompt, setSettingsPrompt, closeUsagePanel };
|
|
58774
58818
|
return {
|
|
58775
58819
|
openWebSearchPicker,
|
|
58776
|
-
...createAgentsPicker({ ...panelDeps, clean:
|
|
58820
|
+
...createAgentsPicker({ ...panelDeps, clean: clean3, agentModelParts: agentModelParts2, agentModelProfile: agentModelProfile2, openModelPicker }),
|
|
58777
58821
|
...createWorkflowPicker({ ...panelDeps, workflowSwitchNotice: workflowSwitchNotice2 }),
|
|
58778
58822
|
...createOutputStylePicker(panelDeps)
|
|
58779
58823
|
};
|
|
@@ -59017,7 +59061,13 @@ var {
|
|
|
59017
59061
|
getSecret: _getSecret,
|
|
59018
59062
|
setSecret: _setSecret,
|
|
59019
59063
|
deleteSecret: _deleteSecret,
|
|
59020
|
-
hasSecret: _hasSecret
|
|
59064
|
+
hasSecret: _hasSecret,
|
|
59065
|
+
setSecretAsync: _setSecretAsyncImpl,
|
|
59066
|
+
deleteSecretAsync: _deleteSecretAsyncImpl,
|
|
59067
|
+
keychainStatus: _keychainStatus,
|
|
59068
|
+
retryKeychain: _retryKeychain,
|
|
59069
|
+
refreshKeychainStatus: _refreshKeychainStatus,
|
|
59070
|
+
onKeychainRecovered: _onKeychainRecovered
|
|
59021
59071
|
} = _require("../../lib/keychain-cjs.cjs");
|
|
59022
59072
|
function configPath() {
|
|
59023
59073
|
return join11(resolvePluginData(), "mixdog-config.json");
|
|
@@ -60869,13 +60919,13 @@ function useTerminalChrome({ stdout: stdout2, isRawModeSupported, setResizeState
|
|
|
60869
60919
|
import { useCallback as useCallback21, useEffect as useEffect25, useLayoutEffect as useLayoutEffect8 } from "react";
|
|
60870
60920
|
|
|
60871
60921
|
// src/tui/session/transcript-spill.mjs
|
|
60872
|
-
import { readFileSync as
|
|
60922
|
+
import { readFileSync as readFileSync15 } from "node:fs";
|
|
60873
60923
|
import { join as join15 } from "node:path";
|
|
60874
60924
|
import { Worker } from "node:worker_threads";
|
|
60875
60925
|
|
|
60876
60926
|
// src/tui/session/transcript-spill/spill-dir.mjs
|
|
60877
60927
|
import { randomUUID } from "node:crypto";
|
|
60878
|
-
import { mkdtempSync, readdirSync as readdirSync5, rmSync as rmSync5, statSync as statSync5, writeFileSync as writeFileSync6 } from "node:fs";
|
|
60928
|
+
import { mkdtempSync, readdirSync as readdirSync5, readFileSync as readFileSync14, rmSync as rmSync5, statSync as statSync5, writeFileSync as writeFileSync6 } from "node:fs";
|
|
60879
60929
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
60880
60930
|
import { join as join14 } from "node:path";
|
|
60881
60931
|
var STALE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -56,6 +56,8 @@ export function createContextState({
|
|
|
56
56
|
sessionProvider: runtime.sessionProvider ?? null,
|
|
57
57
|
sessionModel: runtime.sessionModel ?? null,
|
|
58
58
|
effort: runtime.effort,
|
|
59
|
+
// Resolved per-turn/per-step effort (Auto judge); null when none recorded.
|
|
60
|
+
turnEffort: runtime.turnEffort ?? null,
|
|
59
61
|
effortOptions: runtime.effortOptions,
|
|
60
62
|
fast: runtime.fast,
|
|
61
63
|
fastCapable: runtime.fastCapable,
|
|
@@ -27,6 +27,21 @@ function unlinkQuietly(path) {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
// Sockets this process still serves. A process that exits without closing its
|
|
31
|
+
// sessions (daemon shutdown, tray Quit) must not leave them behind in /tmp.
|
|
32
|
+
const servedSocketPaths = new Set();
|
|
33
|
+
let exitCleanupInstalled = false;
|
|
34
|
+
function serveSocketPath(path) {
|
|
35
|
+
if (process.platform === 'win32' || !path) return;
|
|
36
|
+
servedSocketPaths.add(path);
|
|
37
|
+
if (exitCleanupInstalled) return;
|
|
38
|
+
exitCleanupInstalled = true;
|
|
39
|
+
process.once('exit', () => {
|
|
40
|
+
for (const served of servedSocketPaths) unlinkQuietly(served);
|
|
41
|
+
servedSocketPaths.clear();
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
30
45
|
export function createOwnerLeg({
|
|
31
46
|
ownerSessionId,
|
|
32
47
|
socketPathFor,
|
|
@@ -181,6 +196,7 @@ export function createOwnerLeg({
|
|
|
181
196
|
/* already closed */
|
|
182
197
|
}
|
|
183
198
|
unlinkQuietly(serverPath);
|
|
199
|
+
servedSocketPaths.delete(serverPath);
|
|
184
200
|
serverId = '';
|
|
185
201
|
serverPath = '';
|
|
186
202
|
};
|
|
@@ -216,6 +232,7 @@ export function createOwnerLeg({
|
|
|
216
232
|
server = next;
|
|
217
233
|
serverId = id;
|
|
218
234
|
serverPath = path;
|
|
235
|
+
serveSocketPath(path);
|
|
219
236
|
try {
|
|
220
237
|
next.listen(path);
|
|
221
238
|
} catch {
|
|
@@ -9,6 +9,7 @@ function oauthFlowStatus(flow) {
|
|
|
9
9
|
provider: flow.provider,
|
|
10
10
|
url: flow.url,
|
|
11
11
|
manualUrl: flow.manualUrl,
|
|
12
|
+
userCode: flow.userCode,
|
|
12
13
|
state: flow.state,
|
|
13
14
|
completed: flow.state === 'complete',
|
|
14
15
|
error: flow.error,
|
|
@@ -77,6 +78,7 @@ export function createSessionOAuthFlowRegistry({ ttlMs = DEFAULT_FLOW_TTL_MS } =
|
|
|
77
78
|
provider,
|
|
78
79
|
url: typeof started.url === 'string' ? started.url : null,
|
|
79
80
|
manualUrl: typeof started.manualUrl === 'string' ? started.manualUrl : null,
|
|
81
|
+
userCode: typeof started.userCode === 'string' ? started.userCode : null,
|
|
80
82
|
state: 'pending',
|
|
81
83
|
result: null,
|
|
82
84
|
error: null,
|
|
@@ -14,15 +14,19 @@ export function createSessionExtensionsApi(bag) {
|
|
|
14
14
|
resetStatsAndSyncContext,
|
|
15
15
|
routeState,
|
|
16
16
|
});
|
|
17
|
-
// One locked runtime mutation, then republish and announce it.
|
|
17
|
+
// One locked runtime mutation, then republish and announce it. A refused
|
|
18
|
+
// change throws so a caller never reports a skipped write as saved.
|
|
18
19
|
const lockedChange = (call, notice) =>
|
|
19
|
-
withCommandLock(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
withCommandLock(
|
|
21
|
+
async (...args) => {
|
|
22
|
+
const result = await call(...args);
|
|
23
|
+
refreshRouteStats();
|
|
24
|
+
const [text, level = 'info'] = notice(result, ...args);
|
|
25
|
+
pushNotice(text, level);
|
|
26
|
+
return result;
|
|
27
|
+
},
|
|
28
|
+
{ busyError: 'Another command is still running; try again when it finishes.' }
|
|
29
|
+
);
|
|
26
30
|
const pluginLabel = (result, plugin) => result?.plugin?.title || result?.plugin?.name || plugin?.name || plugin;
|
|
27
31
|
|
|
28
32
|
return {
|
|
@@ -68,6 +68,7 @@ export function createSessionIntegrationsApi(bag, { oauthFlows }) {
|
|
|
68
68
|
// Completed-marking only; no route/agent/provider writes.
|
|
69
69
|
return runtime.skipOnboarding?.() || null;
|
|
70
70
|
},
|
|
71
|
+
saveStarterGuideState: (state) => runtime.saveStarterGuideState?.(state) || null,
|
|
71
72
|
completeOnboarding: withCommandLock(async (payload = {}) => {
|
|
72
73
|
const result = await runtime.completeOnboarding?.(payload);
|
|
73
74
|
refreshRouteStats();
|
|
@@ -98,8 +99,8 @@ export function createSessionIntegrationsApi(bag, { oauthFlows }) {
|
|
|
98
99
|
getOAuthProviderLoginStatus: (flowId) => oauthFlows.status(flowId),
|
|
99
100
|
completeOAuthProviderLogin: async (flowId, code) => oauthFlows.complete(flowId, code),
|
|
100
101
|
cancelOAuthProviderLogin: async (flowId) => oauthFlows.cancel(flowId),
|
|
101
|
-
saveProviderApiKey: (provider, secret) => {
|
|
102
|
-
const result = runtime.saveProviderApiKey(provider, secret);
|
|
102
|
+
saveProviderApiKey: async (provider, secret) => {
|
|
103
|
+
const result = await runtime.saveProviderApiKey(provider, secret);
|
|
103
104
|
pushNotice(`provider api key saved: ${result.provider}`, 'info');
|
|
104
105
|
return true;
|
|
105
106
|
},
|
|
@@ -116,13 +117,13 @@ export function createSessionIntegrationsApi(bag, { oauthFlows }) {
|
|
|
116
117
|
},
|
|
117
118
|
testCustomProvider: (input) => runtime.testCustomProvider(input),
|
|
118
119
|
discoverCustomProviderModels: (input) => runtime.discoverCustomProviderModels(input),
|
|
119
|
-
saveOpenCodeGoUsageAuth: (opts) => {
|
|
120
|
-
runtime.saveOpenCodeGoUsageAuth(opts);
|
|
120
|
+
saveOpenCodeGoUsageAuth: async (opts) => {
|
|
121
|
+
await runtime.saveOpenCodeGoUsageAuth(opts);
|
|
121
122
|
pushNotice('OpenCode Go usage auth saved', 'info');
|
|
122
123
|
return true;
|
|
123
124
|
},
|
|
124
|
-
saveOpenAIUsageSessionKey: (secret) => {
|
|
125
|
-
runtime.saveOpenAIUsageSessionKey(secret);
|
|
125
|
+
saveOpenAIUsageSessionKey: async (secret) => {
|
|
126
|
+
await runtime.saveOpenAIUsageSessionKey(secret);
|
|
126
127
|
pushNotice('OpenAI usage auth saved', 'info');
|
|
127
128
|
return true;
|
|
128
129
|
},
|
|
@@ -134,8 +135,8 @@ export function createSessionIntegrationsApi(bag, { oauthFlows }) {
|
|
|
134
135
|
},
|
|
135
136
|
{ busyResult: false }
|
|
136
137
|
),
|
|
137
|
-
forgetProviderAuth: (provider, accountId) => {
|
|
138
|
-
const result = runtime.forgetProviderAuth(provider, accountId);
|
|
138
|
+
forgetProviderAuth: async (provider, accountId) => {
|
|
139
|
+
const result = await runtime.forgetProviderAuth(provider, accountId);
|
|
139
140
|
pushNotice(`provider auth forgotten: ${result.provider}`, 'info');
|
|
140
141
|
return true;
|
|
141
142
|
},
|
|
@@ -148,8 +148,8 @@ export function createSessionRouteApi(bag) {
|
|
|
148
148
|
listProviders: () => {
|
|
149
149
|
return runtime.listProviders();
|
|
150
150
|
},
|
|
151
|
-
getProviderSetup: () => {
|
|
152
|
-
return runtime.getProviderSetup();
|
|
151
|
+
getProviderSetup: (options = {}) => {
|
|
152
|
+
return runtime.getProviderSetup(options);
|
|
153
153
|
},
|
|
154
154
|
setRoute,
|
|
155
155
|
setAgentRoute: async (agentId, opts) => {
|
|
@@ -130,6 +130,7 @@ export function createSessionSettingsApi(bag) {
|
|
|
130
130
|
getDeveloperSettings: () => runtime.getDeveloperSettings?.(),
|
|
131
131
|
setDeveloperOption: lockedRuntimeCall((id, enabled) => runtime.setDeveloperOption?.(id, enabled)),
|
|
132
132
|
setWebSearchEnabled: lockedRuntimeCall((enabled) => runtime.setWebSearchEnabled?.(enabled)),
|
|
133
|
+
setInstructionFiles: lockedRuntimeCall((mode) => runtime.setInstructionFiles?.(mode)),
|
|
133
134
|
setMemoryToolsEnabled: lockedRuntimeCall((enabled) => runtime.setMemoryToolsEnabled?.(enabled)),
|
|
134
135
|
setBuiltinToolEnabled: lockedRuntimeCall((name, enabled) => runtime.setBuiltinToolEnabled?.(name, enabled)),
|
|
135
136
|
installBuiltinFeature: lockedRuntimeCall((name) => runtime.installBuiltinFeature?.(name)),
|
|
@@ -5,15 +5,19 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export function createApiHelpers({ getState, set, resetStatsAndSyncContext, routeState, syncContextStats }) {
|
|
7
7
|
/**
|
|
8
|
-
* Wrap a runtime call in the command lock: refused (→ `busyResult
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* Wrap a runtime call in the command lock: refused (→ `busyResult`, or a
|
|
9
|
+
* thrown `busyError` for callers that must not read a refusal as success)
|
|
10
|
+
* while another command holds commandBusy, otherwise held for the call's
|
|
11
|
+
* duration. `onRelease` runs after the lock drops (RPC replies read the
|
|
12
|
+
* published snapshot, not the mutable draft, so some callers flush there).
|
|
12
13
|
*/
|
|
13
14
|
const withCommandLock =
|
|
14
|
-
(run, { busyResult = null, onRelease = null } = {}) =>
|
|
15
|
+
(run, { busyResult = null, busyError = '', onRelease = null } = {}) =>
|
|
15
16
|
async (...args) => {
|
|
16
|
-
if (getState().commandBusy)
|
|
17
|
+
if (getState().commandBusy) {
|
|
18
|
+
if (busyError) throw new Error(busyError);
|
|
19
|
+
return busyResult;
|
|
20
|
+
}
|
|
17
21
|
set({ commandBusy: true });
|
|
18
22
|
try {
|
|
19
23
|
return await run(...args);
|
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { toolGroupedDisplayFallback } from '../tool-result-text.mjs';
|
|
7
7
|
import { parseAgentJob } from '../agent-envelope.mjs';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
groupedToolResultText,
|
|
10
|
+
toolMetaPatchFromMessage,
|
|
11
|
+
uiDiffPatchFromMessage,
|
|
12
|
+
withCancelledResultMarker,
|
|
13
|
+
} from '../tool-result-status.mjs';
|
|
9
14
|
import { closeCard } from './item-patch.mjs';
|
|
10
15
|
|
|
11
16
|
/**
|
|
@@ -69,7 +74,11 @@ export function applyGroupedResult(ctx, card, callId, outcome, message, rawText,
|
|
|
69
74
|
if (group.errors > 0 && !String(displayResult || '').trim()) {
|
|
70
75
|
displayResult = finalizedErrorFallbackBody(displayResult, text, exitCode);
|
|
71
76
|
}
|
|
72
|
-
const patch = {
|
|
77
|
+
const patch = {
|
|
78
|
+
...settledPatch(group, displayResult),
|
|
79
|
+
...uiDiffPatchFromMessage(message),
|
|
80
|
+
...toolMetaPatchFromMessage(message),
|
|
81
|
+
};
|
|
73
82
|
if (group.count <= 1) {
|
|
74
83
|
applyAgentJobFields(ctx, patch, { itemId: card.itemId, group, text, rawText, isError, exitCode });
|
|
75
84
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// proves the owner is still running, and the sweep that reclaims directories
|
|
6
6
|
// of dead or long-silent owners.
|
|
7
7
|
import { randomUUID } from 'node:crypto';
|
|
8
|
-
import { mkdtempSync, readdirSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
8
|
+
import { mkdtempSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
9
9
|
import { tmpdir } from 'node:os';
|
|
10
10
|
import { join } from 'node:path';
|
|
11
11
|
|
|
@@ -62,11 +62,27 @@ export function cleanupStaleTranscriptSpillDirs({ root = tmpdir(), now = Date.no
|
|
|
62
62
|
* from the live registry and cannot be mistaken for this process. Throws on
|
|
63
63
|
* write failure; callers decide whether that is fatal. */
|
|
64
64
|
export function writeOwnerRegistry(root = tmpdir()) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
const file = join(root, `mixdog-transcript-owner-${process.pid}.json`);
|
|
66
|
+
writeFileSync(file, JSON.stringify({ pid: process.pid, nonce: PROCESS_NONCE }), 'utf8');
|
|
67
|
+
ownerRegistryFiles.add(file);
|
|
68
|
+
installOwnerRegistryCleanup();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// The registry only has to outlive this process's spill directories. Remove it
|
|
72
|
+
// when the process exits (daemon shutdown, tray Quit) — but only a file that is
|
|
73
|
+
// still this run's: a PID-reuse successor may have rewritten it meanwhile.
|
|
74
|
+
const ownerRegistryFiles = new Set();
|
|
75
|
+
let ownerRegistryCleanupInstalled = false;
|
|
76
|
+
function installOwnerRegistryCleanup() {
|
|
77
|
+
if (ownerRegistryCleanupInstalled) return;
|
|
78
|
+
ownerRegistryCleanupInstalled = true;
|
|
79
|
+
process.once('exit', () => {
|
|
80
|
+
for (const file of ownerRegistryFiles) {
|
|
81
|
+
try {
|
|
82
|
+
if (JSON.parse(readFileSync(file, 'utf8'))?.nonce === PROCESS_NONCE) rmSync(file, { force: true });
|
|
83
|
+
} catch {}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
70
86
|
}
|
|
71
87
|
|
|
72
88
|
export function createSpillDirectories() {
|