mixdog 0.9.147 → 0.9.148
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 +23 -3
- package/scripts/build-voice-runtime-unix.sh +101 -0
- package/scripts/embedding-quality-probe.mjs +96 -0
- package/scripts/generate-voice-runtime-manifest.mjs +300 -0
- package/scripts/generate-voice-runtime-manifest.test.mjs +135 -0
- package/scripts/native-binary-arch.mjs +30 -13
- package/scripts/native-binary-arch.test.mjs +40 -4
- package/scripts/plan-voice-runtime-release.mjs +73 -0
- package/scripts/prepare-native-assets.mjs +50 -9
- package/scripts/prune-embedding-runtime.mjs +3 -3
- package/scripts/sync-voice-runtime-manifest.mjs +46 -0
- package/scripts/verify-release-assets.mjs +106 -6
- package/scripts/verify-voice-runtime-release.mjs +89 -0
- package/scripts/voice-runtime-config.json +52 -0
- package/src/app.mjs +42 -5
- package/src/headless-exec.mjs +58 -32
- package/src/headless-exec.test.mjs +74 -13
- package/src/rules/lead/01-general.md +2 -0
- package/src/rules/shared/10-tool-workflow.md +7 -4
- package/src/rules/shared/30-exploration.md +2 -1
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +28 -9
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +6 -1
- package/src/runtime/agent/orchestrator/config.mjs +53 -18
- package/src/runtime/agent/orchestrator/mcp/cancellation.test.mjs +139 -0
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +34 -5
- package/src/runtime/agent/orchestrator/mcp/client.mjs +94 -10
- package/src/runtime/agent/orchestrator/providers/anthropic-betas.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.mjs +98 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.test.mjs +90 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-leaked-toolcall.mjs +67 -16
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +4 -82
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +0 -5
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +62 -121
- package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.mjs +48 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.test.mjs +215 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +44 -48
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +54 -31
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +56 -2
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +34 -2
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +61 -1
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +6 -1
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +61 -15
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +120 -1
- package/src/runtime/agent/orchestrator/providers/lib/env-utils.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/lib/stream-outcome.mjs +0 -3
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +187 -84
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +36 -36
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +16 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +50 -213
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +135 -126
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +17 -11
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +20 -7
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +11 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +132 -42
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +28 -10
- package/src/runtime/agent/orchestrator/providers/registry.mjs +122 -95
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +58 -3
- package/src/runtime/agent/orchestrator/providers/tool-stream-state.mjs +4 -22
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +7 -14
- package/src/runtime/agent/orchestrator/session/compact-policy.test.mjs +128 -0
- package/src/runtime/agent/orchestrator/session/context-compaction-policy.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +27 -48
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +19 -14
- package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +9 -43
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +15 -2
- package/src/runtime/agent/orchestrator/session/manager/pending-messages-persistence.test.mjs +325 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +599 -195
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +22 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +9 -2
- package/src/runtime/agent/orchestrator/session/manager.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +26 -16
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +23 -11
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +118 -3
- package/src/runtime/agent/orchestrator/session/store-summary-reader.test.mjs +332 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +38 -1
- package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +27 -6
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +12 -20
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +291 -128
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +45 -8
- package/src/runtime/agent/orchestrator/tools/builtin/edit-encoding-eol.test.mjs +224 -0
- package/src/runtime/agent/orchestrator/tools/builtin/edit-sequential-occupation.test.mjs +53 -3
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +255 -25
- package/src/runtime/agent/orchestrator/tools/builtin/find-search-budget.test.mjs +87 -0
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-policy.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +132 -9
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.test.mjs +10 -0
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-pattern-fanout.mjs +29 -3
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +178 -29
- package/src/runtime/agent/orchestrator/tools/builtin/local-search-telemetry.mjs +4 -1
- package/src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs +32 -5
- package/src/runtime/agent/orchestrator/tools/builtin/native-search-health.test.mjs +5 -2
- package/src/runtime/agent/orchestrator/tools/builtin/native-search-runner.mjs +10 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-batch.mjs +38 -10
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +12 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +31 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +11 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-windows.mjs +22 -4
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +6 -8
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +25 -24
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +152 -133
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +114 -42
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +129 -15
- package/src/runtime/agent/orchestrator/tools/code-graph/loose-file-target.test.mjs +72 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/project-root.mjs +7 -8
- package/src/runtime/agent/orchestrator/tools/code-graph/search-references.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +201 -19
- package/src/runtime/agent/orchestrator/tools/code-graph/span.mjs +26 -3
- package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +10 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/symbol-search-scope.test.mjs +55 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/text-mask.mjs +115 -25
- package/src/runtime/agent/orchestrator/tools/code-graph/text-span-mask.test.mjs +268 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +296 -46
- package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.test.mjs +104 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +136 -0
- package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +127 -38
- package/src/runtime/agent/orchestrator/tools/patch/engine-contract-gate.test.mjs +661 -0
- package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +350 -9
- package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +418 -44
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +27 -3
- package/src/runtime/agent/orchestrator/tools/patch/patch-codec-eol.test.mjs +552 -0
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +65 -15
- package/src/runtime/agent/orchestrator/tools/patch-manifest.json +11 -11
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +284 -109
- package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +51 -21
- package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +44 -27
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +11 -11
- package/src/runtime/attachments/store.mjs +11 -3
- package/src/runtime/channels/data/voice-runtime-manifest.json +46 -70
- package/src/runtime/channels/lib/event-queue.mjs +51 -41
- package/src/runtime/channels/lib/scheduler.mjs +23 -28
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +6 -17
- package/src/runtime/channels/lib/voice-runtime-fetcher.test.mjs +17 -0
- package/src/runtime/channels/lib/webhook.mjs +39 -20
- package/src/runtime/channels/lib/whisper-server.mjs +46 -1
- package/src/runtime/channels/lib/worker-main.mjs +3 -1
- package/src/runtime/media/adapters/gemini-video.mjs +20 -4
- package/src/runtime/media/jobs.mjs +13 -0
- package/src/runtime/media/renditions.mjs +7 -1
- package/src/runtime/media/store.mjs +42 -22
- package/src/runtime/memory/index.mjs +4 -9
- package/src/runtime/memory/lib/agent-ipc.mjs +1 -6
- package/src/runtime/memory/lib/archive-security.test.mjs +21 -1
- package/src/runtime/memory/lib/core-memory-store.mjs +28 -50
- package/src/runtime/memory/lib/embedding-model-config.mjs +37 -1
- package/src/runtime/memory/lib/embedding-model-config.test.mjs +33 -0
- package/src/runtime/memory/lib/embedding-provider.mjs +34 -12
- package/src/runtime/memory/lib/embedding-worker.mjs +37 -5
- package/src/runtime/memory/lib/ko-morph.mjs +46 -15
- package/src/runtime/memory/lib/memory-action-handlers.mjs +18 -1
- package/src/runtime/memory/lib/memory-cycle1.mjs +1 -18
- package/src/runtime/memory/lib/memory-cycle2-gate.mjs +1 -18
- package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +98 -45
- package/src/runtime/memory/lib/memory-cycle2-shared.mjs +71 -0
- package/src/runtime/memory/lib/memory-cycle2-shared.test.mjs +78 -0
- package/src/runtime/memory/lib/memory-cycle2.mjs +37 -3
- package/src/runtime/memory/lib/memory-cycle3.mjs +1 -1
- package/src/runtime/memory/lib/memory-embedding-migration.test.mjs +50 -0
- package/src/runtime/memory/lib/memory-recall-store.mjs +9 -24
- package/src/runtime/memory/lib/memory.mjs +50 -12
- package/src/runtime/memory/lib/pg/process.mjs +1 -10
- package/src/runtime/memory/lib/pg/supervisor.mjs +1 -9
- package/src/runtime/memory/lib/query-handlers.mjs +2 -4
- package/src/runtime/memory/lib/session-ingest-runtime.mjs +2 -2
- package/src/runtime/shared/background-tasks.mjs +15 -0
- package/src/runtime/shared/background-tasks.test.mjs +78 -0
- package/src/runtime/shared/child-guardian.mjs +2 -10
- package/src/runtime/shared/pid-liveness.mjs +27 -0
- package/src/runtime/shared/runtime-root.mjs +1 -11
- package/src/runtime/shared/service-discovery.mjs +1 -17
- package/src/runtime/shared/singleton-owner.mjs +1 -11
- package/src/runtime/shared/staged-update.mjs +2 -12
- package/src/runtime/shared/tool-status.mjs +5 -1
- package/src/runtime/shared/tool-surface.mjs +15 -7
- package/src/runtime/shared/turn-snapshot-store.mjs +168 -0
- package/src/runtime/shared/turn-snapshot.mjs +137 -13
- package/src/runtime/shared/turn-worktree-snapshot.mjs +110 -18
- package/src/runtime/shared/webhook-session-run.mjs +16 -2
- package/src/runtime/web-search/lib/http-fetch.mjs +34 -4
- package/src/runtime/web-search/lib/state.mjs +15 -15
- package/src/runtime/web-search/lib/web-tools.mjs +46 -5
- package/src/session-runtime/context-status.mjs +4 -12
- package/src/session-runtime/runtime-core.mjs +20 -1
- package/src/standalone/agent-dispatch-broker.mjs +33 -2
- package/src/standalone/agent-tool/job-task-reconcile.mjs +78 -0
- package/src/standalone/agent-tool/notify.mjs +3 -1
- package/src/standalone/agent-tool/spawn-flow.mjs +48 -66
- package/src/standalone/agent-tool/tag-registry.mjs +116 -33
- package/src/standalone/agent-tool/tool-def.mjs +2 -2
- package/src/standalone/agent-tool/worker-index.mjs +8 -11
- package/src/standalone/agent-tool/worker-rows.mjs +4 -1
- package/src/standalone/agent-tool.mjs +20 -55
- package/src/standalone/agent-watchdog-registry.mjs +28 -4
- package/src/standalone/channel-client.mjs +47 -15
- package/src/standalone/channel-transport.mjs +44 -25
- package/src/standalone/daemon.mjs +31 -2
- package/src/standalone/hook-bus/config.mjs +25 -9
- package/src/standalone/hook-bus/handlers.mjs +16 -52
- package/src/standalone/hook-bus.mjs +29 -23
- package/src/standalone/memory-runtime-proxy.mjs +1 -16
- package/src/standalone/session-client.mjs +86 -23
- package/src/standalone/session-protocol.mjs +0 -2
- package/src/standalone/session-runtime-host-health.test.mjs +5 -4
- package/src/standalone/session-runtime-host.mjs +101 -6
- package/src/standalone/session-runtime-record.mjs +1 -5
- package/src/standalone/session-runtime-worker.mjs +52 -57
- package/src/standalone/session-service.mjs +4 -1
- package/src/standalone/session-transport.mjs +56 -25
- package/src/tui/App.jsx +40 -49
- package/src/tui/app/app-view.jsx +14 -21
- package/src/tui/app/core-memory-picker.mjs +29 -16
- package/src/tui/app/create-app-pickers.mjs +15 -36
- package/src/tui/app/extension-pickers.mjs +60 -49
- package/src/tui/app/maintenance-pickers.mjs +100 -57
- package/src/tui/app/message-selector.mjs +6 -5
- package/src/tui/app/model-picker.mjs +30 -13
- package/src/tui/app/onboarding-steps.mjs +21 -12
- package/src/tui/app/panel-epoch.mjs +56 -0
- package/src/tui/app/panel-epoch.test.mjs +1009 -0
- package/src/tui/app/panel-surface.mjs +98 -0
- package/src/tui/app/project-picker.mjs +30 -29
- package/src/tui/app/prompt-submit.mjs +192 -97
- package/src/tui/app/prompt-submit.test.mjs +206 -0
- package/src/tui/app/provider-setup-picker.mjs +74 -43
- package/src/tui/app/resume-picker.mjs +11 -8
- package/src/tui/app/route-pickers.mjs +45 -28
- package/src/tui/app/settings-picker.mjs +69 -18
- package/src/tui/app/shell-layout.mjs +1 -3
- package/src/tui/app/slash-commands.mjs +0 -2
- package/src/tui/app/slash-dispatch.mjs +4 -2
- package/src/tui/app/text-entry-policy.mjs +25 -0
- package/src/tui/app/theme-effort-pickers.mjs +11 -16
- package/src/tui/app/usage-context-panels.mjs +21 -25
- package/src/tui/app/use-global-key-input.mjs +3 -2
- package/src/tui/app/use-prompt-draft-flow.mjs +6 -18
- package/src/tui/app/use-prompt-handlers.mjs +3 -2
- package/src/tui/app/use-welcome-prompt-hint.mjs +17 -3
- package/src/tui/components/Picker.jsx +1 -1
- package/src/tui/components/TextEntryPanel.jsx +7 -2
- package/src/tui/dist/index.mjs +652 -561
- package/src/tui/lib/voice-setup.mjs +1 -2
- package/src/tui/session/agent-job-feed.mjs +73 -11
- package/src/tui/session/session-api-ext.mjs +5 -6
- package/src/tui/session/session-api.mjs +1 -0
- package/src/tui/session/tool-approval.mjs +15 -5
- package/src/tui/session/tui-steering-persist.mjs +33 -19
- package/src/tui/session/tui-steering-persist.test.mjs +104 -0
- package/src/tui/session-local.mjs +0 -22
- package/scripts/.tmp-coverage-report.mjs +0 -96
- package/src/runtime/agent/orchestrator/tools/builtin/shell-monitor.mjs +0 -57
- package/src/runtime/agent/orchestrator/tools/builtin/shell-monitor.test.mjs +0 -57
package/src/tui/dist/index.mjs
CHANGED
|
@@ -4086,8 +4086,6 @@ var CATEGORY_ORDER = [
|
|
|
4086
4086
|
"Shell",
|
|
4087
4087
|
"Agent",
|
|
4088
4088
|
"Task",
|
|
4089
|
-
"Schedule",
|
|
4090
|
-
"Channel",
|
|
4091
4089
|
"Setup",
|
|
4092
4090
|
"Other"
|
|
4093
4091
|
];
|
|
@@ -4163,8 +4161,6 @@ var CATEGORY_COPY = /* @__PURE__ */ new Map([
|
|
|
4163
4161
|
["Shell", { active: "Running", done: "Ran", noun: "command" }],
|
|
4164
4162
|
["Agent", { active: "Calling", done: "Called", noun: "agent" }],
|
|
4165
4163
|
["Task", { active: "Checking", done: "Checked", noun: "task" }],
|
|
4166
|
-
["Schedule", { active: "Running", done: "Ran", noun: "schedule" }],
|
|
4167
|
-
["Channel", { active: "Sending", done: "Sent", noun: "message" }],
|
|
4168
4164
|
["Setup", { active: "Setting up", done: "Set up", noun: "item" }],
|
|
4169
4165
|
["Other", { active: "Calling", done: "Called", noun: "tool" }]
|
|
4170
4166
|
]);
|
|
@@ -4283,8 +4279,11 @@ function toolWorkUnit(name, args = {}, category = "") {
|
|
|
4283
4279
|
case "job_wait":
|
|
4284
4280
|
return unitDescriptor("Shell", { count: queryCount(a, "command", "commands", "cmd") || 1, noun: "command" });
|
|
4285
4281
|
case "git":
|
|
4286
|
-
case "git_stage":
|
|
4287
4282
|
return unitDescriptor("Git", { count: queryCount(a, "command", "commands") || 1, noun: "Git command" });
|
|
4283
|
+
// Staging is not "running a Git command": it selects change_ids out of an
|
|
4284
|
+
// existing diff. Its own work unit keeps the two apart on the activity row.
|
|
4285
|
+
case "git_stage":
|
|
4286
|
+
return unitDescriptor("Git", { count: queryCount(a, "change_ids", "change_id") || 1, active: "Staging", done: "Staged", noun: "change" });
|
|
4288
4287
|
case "agent":
|
|
4289
4288
|
case "bridge": {
|
|
4290
4289
|
const type = String(a.type || a.action || "").toLowerCase();
|
|
@@ -4303,8 +4302,11 @@ function toolWorkUnit(name, args = {}, category = "") {
|
|
|
4303
4302
|
}
|
|
4304
4303
|
case "task": {
|
|
4305
4304
|
const action = String(a.action || "").toLowerCase();
|
|
4306
|
-
|
|
4307
|
-
return unitDescriptor("Task", { count:
|
|
4305
|
+
const taskCount = queryCount(a, "task_id", "task_ids", "id", "ids") || 1;
|
|
4306
|
+
if (action === "cancel") return unitDescriptor("Task", { count: taskCount, active: "Cancelling", done: "Cancelled", noun: "task" });
|
|
4307
|
+
if (action === "wait") return unitDescriptor("Task", { count: taskCount, active: "Waiting for", done: "Waited for", noun: "task" });
|
|
4308
|
+
if (action === "list") return unitDescriptor("Task", { count: taskCount, active: "Listing", done: "Listed", noun: "task" });
|
|
4309
|
+
return unitDescriptor("Task", { count: taskCount, noun: "task" });
|
|
4308
4310
|
}
|
|
4309
4311
|
case "skill":
|
|
4310
4312
|
case "skill_execute":
|
|
@@ -4319,7 +4321,9 @@ function toolWorkUnit(name, args = {}, category = "") {
|
|
|
4319
4321
|
count: queryCount(a, "symbols", "symbol", "query", "file", "path") || 1,
|
|
4320
4322
|
active: searching ? "Mapping" : "Reading",
|
|
4321
4323
|
done: searching ? "Mapped" : "Read",
|
|
4322
|
-
|
|
4324
|
+
// "code map", not "file": an overview/imports/impact pass reads
|
|
4325
|
+
// structure, and sharing the plain read unit hid it behind file reads.
|
|
4326
|
+
noun: searching ? "symbol" : "code map"
|
|
4323
4327
|
});
|
|
4324
4328
|
}
|
|
4325
4329
|
case "request_user_input":
|
|
@@ -5268,6 +5272,13 @@ init_config();
|
|
|
5268
5272
|
// src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs
|
|
5269
5273
|
init_plugin_paths();
|
|
5270
5274
|
import { join as join6 } from "node:path";
|
|
5275
|
+
|
|
5276
|
+
// src/runtime/agent/orchestrator/providers/cursor-auth.mjs
|
|
5277
|
+
init_plugin_paths();
|
|
5278
|
+
init_atomic_file();
|
|
5279
|
+
var REFRESH_SKEW_MS = 5 * 6e4;
|
|
5280
|
+
|
|
5281
|
+
// src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs
|
|
5271
5282
|
var ANTHROPIC_DEFAULT_CREDENTIALS_PATH = join6(resolvePluginData(), "anthropic-oauth-credentials.json");
|
|
5272
5283
|
|
|
5273
5284
|
// src/runtime/agent/orchestrator/config.mjs
|
|
@@ -8512,6 +8523,21 @@ function textEntryReservedRows(value, width, maxRows) {
|
|
|
8512
8523
|
return Math.min(wrappedTextRows(`${String(value ?? "")} `, w), cap);
|
|
8513
8524
|
}
|
|
8514
8525
|
|
|
8526
|
+
// src/tui/app/text-entry-policy.mjs
|
|
8527
|
+
var CLEAR_BY_EMPTY_TEXT_ENTRY_KINDS = Object.freeze([
|
|
8528
|
+
"system-shell",
|
|
8529
|
+
"autoclear-provider",
|
|
8530
|
+
"profile-title"
|
|
8531
|
+
]);
|
|
8532
|
+
var CLEAR_BY_EMPTY_KIND_SET = new Set(CLEAR_BY_EMPTY_TEXT_ENTRY_KINDS);
|
|
8533
|
+
function textEntryClearsByEmpty(kind) {
|
|
8534
|
+
return CLEAR_BY_EMPTY_KIND_SET.has(String(kind || ""));
|
|
8535
|
+
}
|
|
8536
|
+
function canSubmitTextEntry(value, allowEmpty = false) {
|
|
8537
|
+
if (allowEmpty === true) return true;
|
|
8538
|
+
return String(value ?? "").trim().length > 0;
|
|
8539
|
+
}
|
|
8540
|
+
|
|
8515
8541
|
// src/tui/components/TextEntryPanel.jsx
|
|
8516
8542
|
import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
8517
8543
|
function insertText2(draft, input) {
|
|
@@ -8625,6 +8651,10 @@ function TextEntryPanel({
|
|
|
8625
8651
|
hint = "",
|
|
8626
8652
|
detail = "",
|
|
8627
8653
|
initialValue = "",
|
|
8654
|
+
// Blank submit = the documented reset/clear action for some prompt kinds
|
|
8655
|
+
// (system shell → auto, provider auto-clear → built-in, profile title →
|
|
8656
|
+
// cleared). Off by default: every other prompt still requires a value.
|
|
8657
|
+
allowEmpty = false,
|
|
8628
8658
|
mask = false,
|
|
8629
8659
|
multiline = false,
|
|
8630
8660
|
maxContentRows = 8,
|
|
@@ -8694,7 +8724,7 @@ function TextEntryPanel({
|
|
|
8694
8724
|
}, [multiline, draft.value, mask, contentCells, maxContentRows, onContentRowsChange]);
|
|
8695
8725
|
const submit = () => {
|
|
8696
8726
|
if (submitGateRef.current) return;
|
|
8697
|
-
if (!
|
|
8727
|
+
if (!canSubmitTextEntry(draftRef.current.value, allowEmpty)) return;
|
|
8698
8728
|
submitGateRef.current = true;
|
|
8699
8729
|
const accepted = onSubmit?.(draftRef.current.value) !== false;
|
|
8700
8730
|
if (accepted) {
|
|
@@ -8710,7 +8740,7 @@ function TextEntryPanel({
|
|
|
8710
8740
|
if (submitGateRef.current) return;
|
|
8711
8741
|
const current = draftRef.current;
|
|
8712
8742
|
const next = prefix ? insertText2(current, prefix) : current;
|
|
8713
|
-
if (!
|
|
8743
|
+
if (!canSubmitTextEntry(next.value, allowEmpty)) return;
|
|
8714
8744
|
submitGateRef.current = true;
|
|
8715
8745
|
const accepted = onSubmit?.(next.value) !== false;
|
|
8716
8746
|
if (accepted) {
|
|
@@ -9376,7 +9406,7 @@ function compareSlashCommands(a, b) {
|
|
|
9376
9406
|
return String(a?.name || "").localeCompare(String(b?.name || ""), "en", { sensitivity: "base" });
|
|
9377
9407
|
}
|
|
9378
9408
|
function overlayBlocksGlobalTranscriptScroll(owner = {}) {
|
|
9379
|
-
return !!(owner.slashPaletteOpen || owner.picker || owner.toolApproval || owner.contextPanel || owner.usagePanel || owner.providerPrompt || owner.
|
|
9409
|
+
return !!(owner.slashPaletteOpen || owner.picker || owner.toolApproval || owner.contextPanel || owner.usagePanel || owner.providerPrompt || owner.settingsPrompt);
|
|
9380
9410
|
}
|
|
9381
9411
|
function normalizeSlashCommandName(cmd) {
|
|
9382
9412
|
const name = String(cmd || "").toLowerCase();
|
|
@@ -9427,31 +9457,6 @@ function isLiveSpinnerMetaVisible({
|
|
|
9427
9457
|
}
|
|
9428
9458
|
|
|
9429
9459
|
// src/tui/app/input-parsers.mjs
|
|
9430
|
-
function parseHookRuleInput(text) {
|
|
9431
|
-
const parts = String(text || "").split("|").map((part) => part.trim());
|
|
9432
|
-
const [tool, actionRaw, match, reason, patchText] = parts;
|
|
9433
|
-
const action = String(actionRaw || "").toLowerCase();
|
|
9434
|
-
if (!tool || !action) return { error: "usage: tool | allow|deny|modify | match(optional) | reason(optional) | json patch(optional)" };
|
|
9435
|
-
if (!["allow", "deny", "block", "modify", "rewrite"].includes(action)) {
|
|
9436
|
-
return { error: "hook action must be allow, deny, block, modify, or rewrite" };
|
|
9437
|
-
}
|
|
9438
|
-
const rule = { tool, action };
|
|
9439
|
-
if (match) rule.match = match;
|
|
9440
|
-
if (reason) rule.reason = reason;
|
|
9441
|
-
if (patchText) {
|
|
9442
|
-
try {
|
|
9443
|
-
const patch = JSON.parse(patchText);
|
|
9444
|
-
if (!patch || typeof patch !== "object" || Array.isArray(patch)) return { error: "json patch must be an object" };
|
|
9445
|
-
rule.patch = patch;
|
|
9446
|
-
} catch (e) {
|
|
9447
|
-
return { error: `invalid json patch: ${e?.message || e}` };
|
|
9448
|
-
}
|
|
9449
|
-
}
|
|
9450
|
-
if ((action === "modify" || action === "rewrite") && !rule.patch) {
|
|
9451
|
-
return { error: "modify/rewrite needs a json patch object in the last field" };
|
|
9452
|
-
}
|
|
9453
|
-
return { rule };
|
|
9454
|
-
}
|
|
9455
9460
|
function parseMcpServerInput(text) {
|
|
9456
9461
|
const parts = String(text || "").split("|").map((part) => part.trim());
|
|
9457
9462
|
const [name, commandOrUrl, argsText = "", cwd = ""] = parts;
|
|
@@ -9608,6 +9613,90 @@ function copyToClipboard(text) {
|
|
|
9608
9613
|
});
|
|
9609
9614
|
}
|
|
9610
9615
|
|
|
9616
|
+
// src/tui/app/panel-epoch.mjs
|
|
9617
|
+
var panelEpoch = 0;
|
|
9618
|
+
function currentPanelEpoch() {
|
|
9619
|
+
return panelEpoch;
|
|
9620
|
+
}
|
|
9621
|
+
function supersedePanelEpoch() {
|
|
9622
|
+
panelEpoch += 1;
|
|
9623
|
+
return panelEpoch;
|
|
9624
|
+
}
|
|
9625
|
+
function isPanelEpochCurrent(token) {
|
|
9626
|
+
return token === panelEpoch;
|
|
9627
|
+
}
|
|
9628
|
+
function panelIdentity(panel) {
|
|
9629
|
+
if (!panel || typeof panel !== "object") return null;
|
|
9630
|
+
return panel._kind || panel.title || null;
|
|
9631
|
+
}
|
|
9632
|
+
function shouldSupersedePanelEpoch(previous, next) {
|
|
9633
|
+
if (!previous || typeof previous !== "object") return false;
|
|
9634
|
+
if (!next || typeof next !== "object") return true;
|
|
9635
|
+
if (previous === next) return false;
|
|
9636
|
+
return panelIdentity(previous) !== panelIdentity(next);
|
|
9637
|
+
}
|
|
9638
|
+
|
|
9639
|
+
// src/tui/app/panel-surface.mjs
|
|
9640
|
+
function createPanelSurface({ setPicker, setContextPanel, setUsagePanel } = {}) {
|
|
9641
|
+
let usageGeneration = 0;
|
|
9642
|
+
const claim = () => {
|
|
9643
|
+
let token = currentPanelEpoch();
|
|
9644
|
+
let released = false;
|
|
9645
|
+
const owns = () => !released && isPanelEpochCurrent(token);
|
|
9646
|
+
const write = (sink, value) => {
|
|
9647
|
+
if (!owns()) return false;
|
|
9648
|
+
sink?.(value);
|
|
9649
|
+
token = currentPanelEpoch();
|
|
9650
|
+
return true;
|
|
9651
|
+
};
|
|
9652
|
+
return {
|
|
9653
|
+
owns,
|
|
9654
|
+
paint: (panel) => write(setPicker, panel),
|
|
9655
|
+
// Clearing the context panel hands the surface back exactly as closing a
|
|
9656
|
+
// picker does. setPicker's caller supersedes the epoch on a close (see
|
|
9657
|
+
// shouldSupersedePanelEpoch); this sink has no such step, so a context
|
|
9658
|
+
// open still in flight stayed valid and repainted "Context Usage" after
|
|
9659
|
+
// the user had already pressed Esc. Superseding here is what makes the
|
|
9660
|
+
// dismissal final, and re-reading the token keeps THIS flow (Esc inside a
|
|
9661
|
+
// settings picker, which clears context and carries on) working.
|
|
9662
|
+
context: (panel) => {
|
|
9663
|
+
if (!owns()) return false;
|
|
9664
|
+
setContextPanel?.(panel);
|
|
9665
|
+
if (panel == null) supersedePanelEpoch();
|
|
9666
|
+
token = currentPanelEpoch();
|
|
9667
|
+
return true;
|
|
9668
|
+
},
|
|
9669
|
+
close: () => {
|
|
9670
|
+
if (!owns()) return false;
|
|
9671
|
+
setPicker?.(null);
|
|
9672
|
+
released = true;
|
|
9673
|
+
return true;
|
|
9674
|
+
},
|
|
9675
|
+
defer: (run) => {
|
|
9676
|
+
const deferredToken = token;
|
|
9677
|
+
return (...args) => !released && isPanelEpochCurrent(deferredToken) ? run(...args) : void 0;
|
|
9678
|
+
}
|
|
9679
|
+
};
|
|
9680
|
+
};
|
|
9681
|
+
const claimUsage = () => {
|
|
9682
|
+
const generation = usageGeneration += 1;
|
|
9683
|
+
const owns = () => generation === usageGeneration;
|
|
9684
|
+
return {
|
|
9685
|
+
owns,
|
|
9686
|
+
paint: (dashboard) => {
|
|
9687
|
+
if (!owns()) return false;
|
|
9688
|
+
setUsagePanel?.(dashboard);
|
|
9689
|
+
return true;
|
|
9690
|
+
}
|
|
9691
|
+
};
|
|
9692
|
+
};
|
|
9693
|
+
const closeUsage = () => {
|
|
9694
|
+
usageGeneration += 1;
|
|
9695
|
+
setUsagePanel?.(null);
|
|
9696
|
+
};
|
|
9697
|
+
return { claim, claimUsage, closeUsage };
|
|
9698
|
+
}
|
|
9699
|
+
|
|
9611
9700
|
// src/tui/App.jsx
|
|
9612
9701
|
import stringWidth11 from "string-width";
|
|
9613
9702
|
|
|
@@ -11959,7 +12048,7 @@ function normalizeToolTerminalStatus(value) {
|
|
|
11959
12048
|
if (/^(running|pending|queued|in_progress|in-progress)$/.test(raw)) return "running";
|
|
11960
12049
|
if (/^(completed|complete|done|success|succeeded|ok)$/.test(raw)) return "completed";
|
|
11961
12050
|
if (/^(failed|fail|error|errored|timeout|timed_out|killed)$/.test(raw)) return "failed";
|
|
11962
|
-
if (/^(cancelled|canceled|cancel)$/.test(raw)) return "cancelled";
|
|
12051
|
+
if (/^(cancelled|canceled|cancel|cancel[-_ ]unconfirmed|cancel[-_ ]pending|cancelling|canceling)$/.test(raw)) return "cancelled";
|
|
11963
12052
|
if (/^(denied|deny|refused|rejected)$/.test(raw)) return "denied";
|
|
11964
12053
|
return "";
|
|
11965
12054
|
}
|
|
@@ -14844,12 +14933,20 @@ function useWelcomePromptHint({ store, state, toastErrorSignature }) {
|
|
|
14844
14933
|
}
|
|
14845
14934
|
}
|
|
14846
14935
|
}
|
|
14847
|
-
|
|
14936
|
+
let activeWorkflow = null;
|
|
14937
|
+
try {
|
|
14938
|
+
activeWorkflow = await activeWorkflowSummaryForStore(store, state.workflow || {});
|
|
14939
|
+
} catch {
|
|
14940
|
+
}
|
|
14848
14941
|
if (!next && String(activeWorkflow?.id || state.workflow?.id || "").toLowerCase() === "solo") {
|
|
14849
14942
|
next = CONDITIONAL_WELCOME_PROMPT_HINTS.soloWorkflow;
|
|
14850
14943
|
}
|
|
14851
14944
|
if (!next) {
|
|
14852
|
-
|
|
14945
|
+
let webSearchRoute = null;
|
|
14946
|
+
try {
|
|
14947
|
+
webSearchRoute = await store.getWebSearchRoute?.() || null;
|
|
14948
|
+
} catch {
|
|
14949
|
+
}
|
|
14853
14950
|
const webSearchProvider = String(webSearchRoute?.provider || "").trim();
|
|
14854
14951
|
const webSearchModel = String(webSearchRoute?.model || "").trim();
|
|
14855
14952
|
const defaultWebSearchRoute = webSearchProvider.toLowerCase() === "default" && webSearchModel.toLowerCase() === "default";
|
|
@@ -14869,7 +14966,8 @@ function useWelcomePromptHint({ store, state, toastErrorSignature }) {
|
|
|
14869
14966
|
}
|
|
14870
14967
|
if (alive) setConditionalWelcomePromptHint((prev) => prev === next ? prev : next);
|
|
14871
14968
|
};
|
|
14872
|
-
void refreshConditionalWelcomeHint()
|
|
14969
|
+
void refreshConditionalWelcomeHint().catch(() => {
|
|
14970
|
+
});
|
|
14873
14971
|
return () => {
|
|
14874
14972
|
alive = false;
|
|
14875
14973
|
};
|
|
@@ -14919,27 +15017,20 @@ function useCopySelection({
|
|
|
14919
15017
|
function createUsageContextPanels({
|
|
14920
15018
|
store,
|
|
14921
15019
|
state,
|
|
14922
|
-
|
|
14923
|
-
setPicker,
|
|
15020
|
+
surface,
|
|
14924
15021
|
setProviderPrompt,
|
|
14925
|
-
setChannelPrompt,
|
|
14926
|
-
setHookPrompt,
|
|
14927
15022
|
setSettingsPrompt,
|
|
14928
|
-
setContextPanel,
|
|
14929
|
-
setUsagePanel,
|
|
14930
15023
|
closeUsagePanel
|
|
14931
15024
|
}) {
|
|
14932
15025
|
const openUsagePanel = (arg = "") => {
|
|
14933
15026
|
const refresh = /(?:^|\s)(?:refresh|--refresh|-r|true)(?:\s|$)/i.test(String(arg || ""));
|
|
14934
|
-
const
|
|
14935
|
-
|
|
15027
|
+
const own = surface.claim();
|
|
15028
|
+
const dashboardOwn = surface.claimUsage();
|
|
14936
15029
|
setProviderPrompt(null);
|
|
14937
|
-
setChannelPrompt(null);
|
|
14938
|
-
setHookPrompt(null);
|
|
14939
15030
|
setSettingsPrompt(null);
|
|
14940
|
-
|
|
14941
|
-
|
|
14942
|
-
|
|
15031
|
+
own.paint(null);
|
|
15032
|
+
own.context(null);
|
|
15033
|
+
dashboardOwn.paint({
|
|
14943
15034
|
title: "Provider Quotas",
|
|
14944
15035
|
subtitle: "Statusline-style provider quota windows.",
|
|
14945
15036
|
checking: true,
|
|
@@ -14948,30 +15039,29 @@ function createUsageContextPanels({
|
|
|
14948
15039
|
total: null
|
|
14949
15040
|
});
|
|
14950
15041
|
setTimeout(() => {
|
|
14951
|
-
if (
|
|
15042
|
+
if (!dashboardOwn.owns()) return;
|
|
14952
15043
|
void store.getUsageDashboard?.({
|
|
14953
15044
|
refresh,
|
|
14954
15045
|
onUpdate: (dashboard) => {
|
|
14955
|
-
if (
|
|
14956
|
-
if (!dashboard) return;
|
|
14957
|
-
setUsagePanel(dashboard);
|
|
15046
|
+
if (dashboard) dashboardOwn.paint(dashboard);
|
|
14958
15047
|
}
|
|
14959
15048
|
}).then((dashboard) => {
|
|
14960
|
-
if (
|
|
15049
|
+
if (!dashboardOwn.owns()) return;
|
|
14961
15050
|
if (!dashboard) {
|
|
14962
15051
|
closeUsagePanel();
|
|
14963
15052
|
store.pushNotice("usage dashboard unavailable", "warn");
|
|
14964
15053
|
return;
|
|
14965
15054
|
}
|
|
14966
|
-
|
|
15055
|
+
dashboardOwn.paint(dashboard);
|
|
14967
15056
|
}).catch((e) => {
|
|
14968
|
-
if (
|
|
15057
|
+
if (!dashboardOwn.owns()) return;
|
|
14969
15058
|
closeUsagePanel();
|
|
14970
15059
|
store.pushNotice(`usage failed: ${e?.message || e}`, "error");
|
|
14971
15060
|
});
|
|
14972
15061
|
}, 0);
|
|
14973
15062
|
};
|
|
14974
15063
|
const openContextPicker = async () => {
|
|
15064
|
+
const own = surface.claim();
|
|
14975
15065
|
const [toolsStatus, mcpStatus, skillsStatus, pluginsStatus, contextStatusValue] = await Promise.all([
|
|
14976
15066
|
Promise.resolve(store.toolsStatus?.()).catch(() => null),
|
|
14977
15067
|
Promise.resolve(store.mcpStatus?.()).catch(() => null),
|
|
@@ -15109,12 +15199,11 @@ function createUsageContextPanels({
|
|
|
15109
15199
|
_action: "extensions"
|
|
15110
15200
|
}
|
|
15111
15201
|
];
|
|
15202
|
+
if (!own.owns()) return;
|
|
15112
15203
|
setProviderPrompt(null);
|
|
15113
|
-
setChannelPrompt(null);
|
|
15114
|
-
setHookPrompt(null);
|
|
15115
15204
|
setSettingsPrompt(null);
|
|
15116
|
-
|
|
15117
|
-
|
|
15205
|
+
own.paint(null);
|
|
15206
|
+
own.context({
|
|
15118
15207
|
kind: "context",
|
|
15119
15208
|
title: "Context Usage",
|
|
15120
15209
|
detail: {
|
|
@@ -15194,21 +15283,20 @@ function createUsageContextPanels({
|
|
|
15194
15283
|
|
|
15195
15284
|
// src/tui/app/prompt-submit.mjs
|
|
15196
15285
|
init_paste_attachments();
|
|
15286
|
+
var providerWriteToken = 0;
|
|
15287
|
+
var settingsWriteToken = 0;
|
|
15288
|
+
var providerWriteInFlight = () => providerWriteToken > 0 && isPanelEpochCurrent(providerWriteToken);
|
|
15289
|
+
var settingsWriteInFlight = () => settingsWriteToken > 0 && isPanelEpochCurrent(settingsWriteToken);
|
|
15197
15290
|
function createPromptSubmit({
|
|
15198
15291
|
store,
|
|
15199
15292
|
state,
|
|
15200
15293
|
providerPrompt,
|
|
15201
|
-
channelPrompt,
|
|
15202
|
-
hookPrompt,
|
|
15203
15294
|
settingsPrompt,
|
|
15204
15295
|
setProviderPrompt,
|
|
15205
|
-
setChannelPrompt,
|
|
15206
|
-
setHookPrompt,
|
|
15207
15296
|
setSettingsPrompt,
|
|
15208
15297
|
oauthSubmitRef,
|
|
15209
15298
|
clearModelCaches,
|
|
15210
15299
|
openProviderSetupPicker,
|
|
15211
|
-
openHooksPicker,
|
|
15212
15300
|
openSettingsPicker,
|
|
15213
15301
|
openProjectPicker,
|
|
15214
15302
|
openAutoClearPicker,
|
|
@@ -15232,6 +15320,12 @@ function createPromptSubmit({
|
|
|
15232
15320
|
}
|
|
15233
15321
|
return Promise.resolve(target.apply(store, args));
|
|
15234
15322
|
};
|
|
15323
|
+
const openPanel = (open, ...args) => {
|
|
15324
|
+
if (typeof open !== "function") return;
|
|
15325
|
+
void Promise.resolve(open(...args)).catch((error) => {
|
|
15326
|
+
store.pushNotice(`panel failed to open: ${error?.message || error}`, "error");
|
|
15327
|
+
});
|
|
15328
|
+
};
|
|
15235
15329
|
const submitPrompt = (prompt, options) => {
|
|
15236
15330
|
if (typeof store.submitAsync !== "function") return store.submit(prompt, options);
|
|
15237
15331
|
void Promise.resolve(store.submitAsync(prompt, options)).then((accepted) => {
|
|
@@ -15241,6 +15335,14 @@ function createPromptSubmit({
|
|
|
15241
15335
|
});
|
|
15242
15336
|
return true;
|
|
15243
15337
|
};
|
|
15338
|
+
const restoreSettingsPrompt = (target, value) => {
|
|
15339
|
+
setSettingsPrompt({
|
|
15340
|
+
...target,
|
|
15341
|
+
submitting: false,
|
|
15342
|
+
initialValue: value,
|
|
15343
|
+
restoreEpoch: (Number(target.restoreEpoch) || 0) + 1
|
|
15344
|
+
});
|
|
15345
|
+
};
|
|
15244
15346
|
const onSubmit = (raw) => {
|
|
15245
15347
|
const text = String(raw ?? "");
|
|
15246
15348
|
const commandText = text.trim();
|
|
@@ -15249,57 +15351,80 @@ function createPromptSubmit({
|
|
|
15249
15351
|
store.pushNotice("wait for the current command to finish", "warn");
|
|
15250
15352
|
return false;
|
|
15251
15353
|
}
|
|
15354
|
+
const beginProviderSave = (target) => {
|
|
15355
|
+
const token = supersedePanelEpoch();
|
|
15356
|
+
providerWriteToken = token;
|
|
15357
|
+
setProviderPrompt((prompt) => prompt === target ? { ...prompt, submitting: true } : prompt);
|
|
15358
|
+
return token;
|
|
15359
|
+
};
|
|
15360
|
+
const endProviderSave = (token) => {
|
|
15361
|
+
if (providerWriteToken === token) providerWriteToken = 0;
|
|
15362
|
+
};
|
|
15363
|
+
const finishProviderSave = (target, token) => {
|
|
15364
|
+
endProviderSave(token);
|
|
15365
|
+
if (!isPanelEpochCurrent(token)) return;
|
|
15366
|
+
setProviderPrompt(null);
|
|
15367
|
+
if (target.afterSave) target.afterSave();
|
|
15368
|
+
else openPanel(openProviderSetupPicker);
|
|
15369
|
+
};
|
|
15370
|
+
const failProviderSave = (target, value, message, token) => {
|
|
15371
|
+
endProviderSave(token);
|
|
15372
|
+
store.pushNotice(message, "error");
|
|
15373
|
+
if (!isPanelEpochCurrent(token)) return;
|
|
15374
|
+
supersedePanelEpoch();
|
|
15375
|
+
setProviderPrompt({
|
|
15376
|
+
...target,
|
|
15377
|
+
submitting: false,
|
|
15378
|
+
initialValue: value,
|
|
15379
|
+
restoreEpoch: (Number(target.restoreEpoch) || 0) + 1
|
|
15380
|
+
});
|
|
15381
|
+
};
|
|
15252
15382
|
if (providerPrompt.kind === "api-key") {
|
|
15253
15383
|
if (!commandText) {
|
|
15254
15384
|
store.pushNotice(`API key is required for ${providerPrompt.providerId}`, "warn");
|
|
15255
15385
|
return false;
|
|
15256
15386
|
}
|
|
15257
|
-
|
|
15258
|
-
store.
|
|
15259
|
-
clearModelCaches("all");
|
|
15260
|
-
const afterSave = providerPrompt.afterSave;
|
|
15261
|
-
setProviderPrompt(null);
|
|
15262
|
-
if (afterSave) afterSave();
|
|
15263
|
-
else void openProviderSetupPicker();
|
|
15264
|
-
return true;
|
|
15265
|
-
} catch (e) {
|
|
15266
|
-
store.pushNotice(`api key save failed: ${e?.message || e}`, "error");
|
|
15387
|
+
if (providerWriteInFlight()) {
|
|
15388
|
+
store.pushNotice("API key is already being saved", "warn");
|
|
15267
15389
|
return false;
|
|
15268
15390
|
}
|
|
15391
|
+
const target = providerPrompt;
|
|
15392
|
+
const token = beginProviderSave(target);
|
|
15393
|
+
void serviceCall("saveProviderApiKey", target.providerId, commandText).then(() => {
|
|
15394
|
+
clearModelCaches("all");
|
|
15395
|
+
finishProviderSave(target, token);
|
|
15396
|
+
}).catch((error) => failProviderSave(target, commandText, `api key save failed: ${error?.message || error}`, token));
|
|
15397
|
+
return true;
|
|
15269
15398
|
}
|
|
15270
15399
|
if (providerPrompt.kind === "openai-usage-session") {
|
|
15271
15400
|
if (!commandText) {
|
|
15272
15401
|
store.pushNotice("OpenAI usage session key is required for credit lookup", "warn");
|
|
15273
15402
|
return false;
|
|
15274
15403
|
}
|
|
15275
|
-
|
|
15276
|
-
store.
|
|
15277
|
-
const afterSave = providerPrompt.afterSave;
|
|
15278
|
-
setProviderPrompt(null);
|
|
15279
|
-
if (afterSave) afterSave();
|
|
15280
|
-
else void openProviderSetupPicker();
|
|
15281
|
-
return true;
|
|
15282
|
-
} catch (e) {
|
|
15283
|
-
store.pushNotice(`OpenAI usage auth save failed: ${e?.message || e}`, "error");
|
|
15404
|
+
if (providerWriteInFlight()) {
|
|
15405
|
+
store.pushNotice("OpenAI usage session key is already being saved", "warn");
|
|
15284
15406
|
return false;
|
|
15285
15407
|
}
|
|
15408
|
+
const target = providerPrompt;
|
|
15409
|
+
const token = beginProviderSave(target);
|
|
15410
|
+
void serviceCall("saveOpenAIUsageSessionKey", commandText).then(() => finishProviderSave(target, token)).catch((error) => failProviderSave(target, commandText, `OpenAI usage auth save failed: ${error?.message || error}`, token));
|
|
15411
|
+
return true;
|
|
15286
15412
|
}
|
|
15287
15413
|
if (providerPrompt.kind === "local-url") {
|
|
15288
|
-
|
|
15289
|
-
store.
|
|
15290
|
-
enabled: true,
|
|
15291
|
-
baseURL: commandText || providerPrompt.defaultURL
|
|
15292
|
-
});
|
|
15293
|
-
clearModelCaches("all");
|
|
15294
|
-
const afterSave = providerPrompt.afterSave;
|
|
15295
|
-
setProviderPrompt(null);
|
|
15296
|
-
if (afterSave) afterSave();
|
|
15297
|
-
else void openProviderSetupPicker();
|
|
15298
|
-
return true;
|
|
15299
|
-
} catch (e) {
|
|
15300
|
-
store.pushNotice(`local provider update failed: ${e?.message || e}`, "error");
|
|
15414
|
+
if (providerWriteInFlight()) {
|
|
15415
|
+
store.pushNotice("local provider update is already running", "warn");
|
|
15301
15416
|
return false;
|
|
15302
15417
|
}
|
|
15418
|
+
const target = providerPrompt;
|
|
15419
|
+
const token = beginProviderSave(target);
|
|
15420
|
+
void serviceCall("setLocalProvider", target.providerId, {
|
|
15421
|
+
enabled: true,
|
|
15422
|
+
baseURL: commandText || target.defaultURL
|
|
15423
|
+
}).then(() => {
|
|
15424
|
+
clearModelCaches("all");
|
|
15425
|
+
finishProviderSave(target, token);
|
|
15426
|
+
}).catch((error) => failProviderSave(target, commandText, `local provider update failed: ${error?.message || error}`, token));
|
|
15427
|
+
return true;
|
|
15303
15428
|
}
|
|
15304
15429
|
if (providerPrompt.kind === "oauth-code") {
|
|
15305
15430
|
if (!commandText) {
|
|
@@ -15321,7 +15446,7 @@ function createPromptSubmit({
|
|
|
15321
15446
|
store.pushNotice(`${providerPrompt.providerName || "OAuth"} login complete`, "info");
|
|
15322
15447
|
if (successReturn) successReturn();
|
|
15323
15448
|
else if (afterSave) afterSave();
|
|
15324
|
-
else
|
|
15449
|
+
else openPanel(openProviderSetupPicker);
|
|
15325
15450
|
}).catch((e) => {
|
|
15326
15451
|
oauthSubmitRef.current = false;
|
|
15327
15452
|
store.pushNotice(`oauth code failed: ${e?.message || e}`, "error");
|
|
@@ -15331,46 +15456,51 @@ function createPromptSubmit({
|
|
|
15331
15456
|
return true;
|
|
15332
15457
|
}
|
|
15333
15458
|
}
|
|
15334
|
-
if (
|
|
15459
|
+
if (settingsPrompt) {
|
|
15335
15460
|
if (state.commandBusy) {
|
|
15336
15461
|
store.pushNotice("wait for the current command to finish", "warn");
|
|
15337
15462
|
return false;
|
|
15338
15463
|
}
|
|
15339
|
-
|
|
15340
|
-
|
|
15341
|
-
const parsed = parseHookRuleInput(commandText);
|
|
15342
|
-
if (parsed.error) {
|
|
15343
|
-
store.pushNotice(parsed.error, "warn");
|
|
15344
|
-
return false;
|
|
15345
|
-
}
|
|
15346
|
-
store.addHookRule?.(parsed.rule);
|
|
15347
|
-
setHookPrompt(null);
|
|
15348
|
-
void openHooksPicker();
|
|
15349
|
-
return true;
|
|
15350
|
-
}
|
|
15351
|
-
} catch (e) {
|
|
15352
|
-
store.pushNotice(`hook update failed: ${e?.message || e}`, "error");
|
|
15353
|
-
return false;
|
|
15354
|
-
}
|
|
15355
|
-
}
|
|
15356
|
-
if (settingsPrompt) {
|
|
15357
|
-
if (state.commandBusy) {
|
|
15358
|
-
store.pushNotice("wait for the current command to finish", "warn");
|
|
15464
|
+
if (settingsWriteInFlight()) {
|
|
15465
|
+
store.pushNotice("wait for the current settings change to finish", "warn");
|
|
15359
15466
|
return false;
|
|
15360
15467
|
}
|
|
15468
|
+
const beginSettingsSave = (target) => {
|
|
15469
|
+
const token = supersedePanelEpoch();
|
|
15470
|
+
settingsWriteToken = token;
|
|
15471
|
+
setSettingsPrompt((prompt) => prompt === target ? { ...prompt, submitting: true } : prompt);
|
|
15472
|
+
return token;
|
|
15473
|
+
};
|
|
15474
|
+
const endSettingsSave = (token) => {
|
|
15475
|
+
if (settingsWriteToken === token) settingsWriteToken = 0;
|
|
15476
|
+
};
|
|
15477
|
+
const finishSettingsSave = (token, after) => {
|
|
15478
|
+
endSettingsSave(token);
|
|
15479
|
+
if (!isPanelEpochCurrent(token)) return;
|
|
15480
|
+
setSettingsPrompt(null);
|
|
15481
|
+
after?.();
|
|
15482
|
+
};
|
|
15483
|
+
const failSettingsSave = (target, value, message, token, tone = "error") => {
|
|
15484
|
+
endSettingsSave(token);
|
|
15485
|
+
store.pushNotice(message, tone);
|
|
15486
|
+
if (!isPanelEpochCurrent(token)) return;
|
|
15487
|
+
supersedePanelEpoch();
|
|
15488
|
+
restoreSettingsPrompt(target, value);
|
|
15489
|
+
};
|
|
15361
15490
|
try {
|
|
15362
15491
|
if (settingsPrompt.kind === "cwd") {
|
|
15363
15492
|
if (!commandText) {
|
|
15364
15493
|
store.pushNotice("working directory path is required", "warn");
|
|
15365
15494
|
return false;
|
|
15366
15495
|
}
|
|
15496
|
+
const target = settingsPrompt;
|
|
15497
|
+
const token = beginSettingsSave(target);
|
|
15367
15498
|
void serviceCall("setCwd", commandText, {
|
|
15368
15499
|
message: `Project set: ${projectNameFromPath(commandText)}`
|
|
15369
15500
|
}).then(() => {
|
|
15370
|
-
|
|
15371
|
-
void openSettingsPicker();
|
|
15501
|
+
finishSettingsSave(token, () => openPanel(openSettingsPicker));
|
|
15372
15502
|
}).catch((error) => {
|
|
15373
|
-
|
|
15503
|
+
failSettingsSave(target, commandText, `project switch failed: ${error?.message || error}`, token);
|
|
15374
15504
|
});
|
|
15375
15505
|
return true;
|
|
15376
15506
|
}
|
|
@@ -15379,17 +15509,21 @@ function createPromptSubmit({
|
|
|
15379
15509
|
store.pushNotice("project path is required", "warn");
|
|
15380
15510
|
return false;
|
|
15381
15511
|
}
|
|
15512
|
+
const target = settingsPrompt;
|
|
15513
|
+
const token = beginSettingsSave(target);
|
|
15382
15514
|
void serviceCall("inspectProjectPath", commandText).then((result) => {
|
|
15383
15515
|
const path2 = String(result?.path || commandText);
|
|
15384
15516
|
if (result?.directory === true) {
|
|
15385
|
-
|
|
15386
|
-
void registerProject(path2);
|
|
15517
|
+
finishSettingsSave(token, () => openPanel(registerProject, path2));
|
|
15387
15518
|
return;
|
|
15388
15519
|
}
|
|
15389
15520
|
if (result?.exists === true) {
|
|
15390
|
-
|
|
15521
|
+
failSettingsSave(target, commandText, `${path2} is not a directory`, token, "warn");
|
|
15391
15522
|
return;
|
|
15392
15523
|
}
|
|
15524
|
+
endSettingsSave(token);
|
|
15525
|
+
if (!isPanelEpochCurrent(token)) return;
|
|
15526
|
+
supersedePanelEpoch();
|
|
15393
15527
|
setSettingsPrompt({
|
|
15394
15528
|
kind: "project-create-confirm",
|
|
15395
15529
|
label: "New project \xB7 Create folder?",
|
|
@@ -15397,7 +15531,7 @@ function createPromptSubmit({
|
|
|
15397
15531
|
pendingPath: path2
|
|
15398
15532
|
});
|
|
15399
15533
|
}).catch((error) => {
|
|
15400
|
-
|
|
15534
|
+
failSettingsSave(target, commandText, `project path check failed: ${error?.message || error}`, token);
|
|
15401
15535
|
});
|
|
15402
15536
|
return true;
|
|
15403
15537
|
}
|
|
@@ -15405,12 +15539,14 @@ function createPromptSubmit({
|
|
|
15405
15539
|
const pendingPath = String(settingsPrompt.pendingPath || "");
|
|
15406
15540
|
const answer = String(commandText || "").trim().toLowerCase();
|
|
15407
15541
|
if (answer === "y" || answer === "yes") {
|
|
15542
|
+
const target = settingsPrompt;
|
|
15543
|
+
const token = beginSettingsSave(target);
|
|
15408
15544
|
void serviceCall("ensureProjectDirectory", pendingPath).then((created) => {
|
|
15409
|
-
|
|
15410
|
-
void registerProject(created || pendingPath);
|
|
15545
|
+
finishSettingsSave(token, () => openPanel(registerProject, created || pendingPath));
|
|
15411
15546
|
}).catch((error) => {
|
|
15547
|
+
endSettingsSave(token);
|
|
15412
15548
|
store.pushNotice(`could not create folder: ${error?.message || error}`, "error");
|
|
15413
|
-
setSettingsPrompt(null);
|
|
15549
|
+
if (isPanelEpochCurrent(token)) setSettingsPrompt(null);
|
|
15414
15550
|
});
|
|
15415
15551
|
return true;
|
|
15416
15552
|
}
|
|
@@ -15420,21 +15556,26 @@ function createPromptSubmit({
|
|
|
15420
15556
|
}
|
|
15421
15557
|
if (settingsPrompt.kind === "project-rename") {
|
|
15422
15558
|
const targetPath = String(settingsPrompt.projectPath || "");
|
|
15559
|
+
const target = settingsPrompt;
|
|
15560
|
+
const token = beginSettingsSave(target);
|
|
15423
15561
|
void serviceCall("renameProject", targetPath, commandText).then((updated) => {
|
|
15424
15562
|
if (updated) {
|
|
15425
15563
|
store.pushNotice(`project renamed to "${updated.name}"`, "info");
|
|
15426
15564
|
}
|
|
15427
|
-
|
|
15428
|
-
void openProjectPicker();
|
|
15565
|
+
finishSettingsSave(token, () => openPanel(openProjectPicker));
|
|
15429
15566
|
}).catch((error) => {
|
|
15430
|
-
|
|
15567
|
+
failSettingsSave(target, commandText, `rename failed: ${error?.message || error}`, token);
|
|
15431
15568
|
});
|
|
15432
15569
|
return true;
|
|
15433
15570
|
}
|
|
15434
15571
|
if (settingsPrompt.kind === "system-shell") {
|
|
15435
|
-
|
|
15436
|
-
|
|
15437
|
-
void
|
|
15572
|
+
const target = settingsPrompt;
|
|
15573
|
+
const token = beginSettingsSave(target);
|
|
15574
|
+
void serviceCall("setSystemShell", commandText).then(() => {
|
|
15575
|
+
finishSettingsSave(token, () => openPanel(openSettingsPicker));
|
|
15576
|
+
}).catch((error) => {
|
|
15577
|
+
failSettingsSave(target, commandText, `system shell update failed: ${error?.message || error}`, token);
|
|
15578
|
+
});
|
|
15438
15579
|
return true;
|
|
15439
15580
|
}
|
|
15440
15581
|
if (settingsPrompt.kind === "autoclear-provider") {
|
|
@@ -15443,28 +15584,26 @@ function createPromptSubmit({
|
|
|
15443
15584
|
store.pushNotice("auto-clear provider is missing", "warn");
|
|
15444
15585
|
return false;
|
|
15445
15586
|
}
|
|
15446
|
-
const
|
|
15447
|
-
|
|
15448
|
-
|
|
15449
|
-
|
|
15450
|
-
store.pushNotice(
|
|
15451
|
-
|
|
15452
|
-
|
|
15453
|
-
|
|
15454
|
-
}
|
|
15455
|
-
setSettingsPrompt(null);
|
|
15456
|
-
openAutoClearPicker({ advanced: true, returnTo: settingsPrompt.returnTo });
|
|
15587
|
+
const duration = String(commandText || "").trim();
|
|
15588
|
+
const target = settingsPrompt;
|
|
15589
|
+
const token = beginSettingsSave(target);
|
|
15590
|
+
void serviceCall("setAutoClear", duration ? { provider, duration } : { provider, resetProvider: true }).then(() => {
|
|
15591
|
+
store.pushNotice(duration ? `Auto-clear ${provider} default set to ${duration}` : `Auto-clear ${provider} default reset`, "info");
|
|
15592
|
+
finishSettingsSave(token, () => openPanel(openAutoClearPicker, { advanced: true, returnTo: target.returnTo }));
|
|
15593
|
+
}).catch((error) => {
|
|
15594
|
+
failSettingsSave(target, duration, `autoclear failed: ${error?.message || error}`, token);
|
|
15595
|
+
});
|
|
15457
15596
|
return true;
|
|
15458
15597
|
}
|
|
15459
15598
|
if (settingsPrompt.kind === "profile-title") {
|
|
15460
|
-
|
|
15461
|
-
|
|
15599
|
+
const target = settingsPrompt;
|
|
15600
|
+
const token = beginSettingsSave(target);
|
|
15601
|
+
void serviceCall("setProfile", { title: commandText }).then(() => {
|
|
15462
15602
|
store.pushNotice(commandText ? `Title set to "${commandText.trim()}"` : "Title cleared", "info");
|
|
15463
|
-
|
|
15464
|
-
|
|
15465
|
-
|
|
15466
|
-
|
|
15467
|
-
openProfilePicker();
|
|
15603
|
+
finishSettingsSave(token, () => openPanel(openProfilePicker));
|
|
15604
|
+
}).catch((error) => {
|
|
15605
|
+
failSettingsSave(target, commandText, `profile update failed: ${error?.message || error}`, token);
|
|
15606
|
+
});
|
|
15468
15607
|
return true;
|
|
15469
15608
|
}
|
|
15470
15609
|
if (settingsPrompt.kind === "plugin-add") {
|
|
@@ -15616,8 +15755,6 @@ function createPromptSubmit({
|
|
|
15616
15755
|
// src/tui/app/shell-layout.mjs
|
|
15617
15756
|
function computeShellLayout({
|
|
15618
15757
|
providerPrompt,
|
|
15619
|
-
channelPrompt,
|
|
15620
|
-
hookPrompt,
|
|
15621
15758
|
settingsPrompt,
|
|
15622
15759
|
panelTransitionEpoch,
|
|
15623
15760
|
panelInkMaskEpoch,
|
|
@@ -15653,7 +15790,7 @@ function computeShellLayout({
|
|
|
15653
15790
|
isInstantPanelCloseTransition: isInstantPanelCloseTransition2,
|
|
15654
15791
|
PANEL_LAYOUT_SIG: PANEL_LAYOUT_SIG2
|
|
15655
15792
|
}) {
|
|
15656
|
-
const textEntryPrompt = providerPrompt ||
|
|
15793
|
+
const textEntryPrompt = providerPrompt || settingsPrompt;
|
|
15657
15794
|
const hasTextEntryPrompt = !!textEntryPrompt;
|
|
15658
15795
|
const hasFloatingPanel = !!(toolApproval || picker || contextPanel || usagePanel || slashPaletteOpen || hasTextEntryPrompt);
|
|
15659
15796
|
const expandedOptionPanel = !!(toolApproval || picker || contextPanel || usagePanel || hasTextEntryPrompt);
|
|
@@ -15909,7 +16046,7 @@ function useGlobalKeyInput({
|
|
|
15909
16046
|
picker,
|
|
15910
16047
|
usagePanel,
|
|
15911
16048
|
contextPanel,
|
|
15912
|
-
|
|
16049
|
+
surface,
|
|
15913
16050
|
closeUsagePanel,
|
|
15914
16051
|
isRawModeSupported,
|
|
15915
16052
|
resizeState,
|
|
@@ -15987,7 +16124,7 @@ function useGlobalKeyInput({
|
|
|
15987
16124
|
return;
|
|
15988
16125
|
}
|
|
15989
16126
|
if (key.escape && contextPanel && !picker) {
|
|
15990
|
-
|
|
16127
|
+
surface.claim().context(null);
|
|
15991
16128
|
return;
|
|
15992
16129
|
}
|
|
15993
16130
|
if (key.pageUp) {
|
|
@@ -16781,7 +16918,7 @@ var Item = React19.memo(function Item2({ item, prevKind, columns, toolOutputExpa
|
|
|
16781
16918
|
// src/tui/app/app-view.jsx
|
|
16782
16919
|
import { Fragment as Fragment6, jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
16783
16920
|
function renderAppView(ctx) {
|
|
16784
|
-
const { PANEL_MAX_VISIBLE, acceptSlashPalette, activeSlashQuery, activeTools, agentRevision,
|
|
16921
|
+
const { PANEL_MAX_VISIBLE, acceptSlashPalette, activeSlashQuery, activeTools, agentRevision, cancelProviderPrompt, cancelSettingsPrompt, cancelSlashPalette, clearPromptHint, completeSlashPalette, contextPanel, cycleWorkflowFromPrompt, exiting, expandedOptionPanel, floatingPanelRows, frameColumns, gridSelectionActiveRef, guardHintWidth, handlePromptEscape, handlePromptHistoryNavigate, handlePromptInterrupt, handlePromptPaste, hasUserMessages, initialStatusLine, inputBoxHidden, inputHint, inputHintTone, liveSpinner, onPromptDraftChange, onSubmit, overlayHintAttachItemIndex, overlayHintBandRows, overlayHintFallbackRow, overlayHintOnLastItem, panelCloseMaskRows, panelInkMaskEpoch, panelTransitionClearRows, panelTransitionEpoch, picker, pickerOpenedFromEnterRef, pickerOpenedFromEnterTimerRef, pickerVisibleRows, promptBoxRectRef, promptBoxRows, promptDraft, promptDraftOverride, promptMetaVisible, promptMouseSelectionRef, promptSelectionRef, promptSpinnerColumns, promptValueRef, providerPrompt, queuedCompact, queuedVisible, renderedTranscriptItems, resizeEpoch, resizeState, restoreQueuedToPrompt, setSlashIndex, setTextEntryLayoutRows, settingsPrompt, showWelcomeBanner, slashCommands, slashIndex, slashPaletteOpen, state, statuslineStats, store, surface, toolApproval, toolOutputExpanded, transcriptContentHeight, transcriptGuardRows, transcriptMeasureRef, transcriptTailPinned, transcriptWindow, transientStatusWidth, tuiReady, usagePanel, viewportHeight, welcomePromptHintRows, welcomePromptHintText } = ctx;
|
|
16785
16922
|
const promptInputControl = /* @__PURE__ */ jsx20(
|
|
16786
16923
|
PromptInput,
|
|
16787
16924
|
{
|
|
@@ -16967,7 +17104,7 @@ function renderAppView(ctx) {
|
|
|
16967
17104
|
onCancel: () => {
|
|
16968
17105
|
if (picker.onCancel) picker.onCancel();
|
|
16969
17106
|
else {
|
|
16970
|
-
|
|
17107
|
+
surface.claim().close();
|
|
16971
17108
|
clearPromptHint();
|
|
16972
17109
|
}
|
|
16973
17110
|
},
|
|
@@ -17030,32 +17167,13 @@ function renderAppView(ctx) {
|
|
|
17030
17167
|
detail: providerPrompt.detail || "",
|
|
17031
17168
|
mask: providerPrompt.kind === "api-key" || providerPrompt.kind === "openai-usage-session",
|
|
17032
17169
|
columns: frameColumns,
|
|
17170
|
+
initialValue: providerPrompt.initialValue || "",
|
|
17033
17171
|
actionLabel: providerPrompt.kind === "oauth-code" ? "continue" : "save",
|
|
17034
17172
|
promptLabel: providerPrompt.kind === "api-key" ? "API key > " : providerPrompt.kind === "oauth-code" ? "Paste code here if prompted > " : providerPrompt.kind === "openai-usage-session" ? "Session key > " : "Base URL > ",
|
|
17035
17173
|
onSubmit,
|
|
17036
17174
|
onCancel: cancelProviderPrompt
|
|
17037
|
-
}
|
|
17038
|
-
|
|
17039
|
-
TextEntryPanel,
|
|
17040
|
-
{
|
|
17041
|
-
title: channelPrompt.label,
|
|
17042
|
-
hint: channelPrompt.hint || "Save channel setting.",
|
|
17043
|
-
mask: channelPrompt.kind === "webhook-token",
|
|
17044
|
-
columns: frameColumns,
|
|
17045
|
-
promptLabel: "Value > ",
|
|
17046
|
-
onSubmit,
|
|
17047
|
-
onCancel: cancelChannelPrompt
|
|
17048
|
-
}
|
|
17049
|
-
) : hookPrompt ? /* @__PURE__ */ jsx20(
|
|
17050
|
-
TextEntryPanel,
|
|
17051
|
-
{
|
|
17052
|
-
title: hookPrompt.label,
|
|
17053
|
-
hint: hookPrompt.hint || "Save hook setting.",
|
|
17054
|
-
columns: frameColumns,
|
|
17055
|
-
promptLabel: "Value > ",
|
|
17056
|
-
onSubmit,
|
|
17057
|
-
onCancel: cancelHookPrompt
|
|
17058
|
-
}
|
|
17175
|
+
},
|
|
17176
|
+
`provider-prompt:${providerPrompt.restoreEpoch || 0}`
|
|
17059
17177
|
) : settingsPrompt ? /* @__PURE__ */ jsx20(
|
|
17060
17178
|
TextEntryPanel,
|
|
17061
17179
|
{
|
|
@@ -17063,6 +17181,7 @@ function renderAppView(ctx) {
|
|
|
17063
17181
|
hint: settingsPrompt.hint || "Save setting.",
|
|
17064
17182
|
columns: frameColumns,
|
|
17065
17183
|
initialValue: settingsPrompt.initialValue || "",
|
|
17184
|
+
allowEmpty: textEntryClearsByEmpty(settingsPrompt.kind),
|
|
17066
17185
|
multiline: settingsPrompt.kind === "core-add" || settingsPrompt.kind === "core-edit",
|
|
17067
17186
|
maxContentRows: PANEL_MAX_VISIBLE,
|
|
17068
17187
|
onContentRowsChange: setTextEntryLayoutRows,
|
|
@@ -17070,7 +17189,8 @@ function renderAppView(ctx) {
|
|
|
17070
17189
|
promptLabel: settingsPrompt.kind === "skill-use" ? "Command > " : settingsPrompt.kind === "autoclear-provider" ? "Duration > " : settingsPrompt.kind === "project-new" ? "Path > " : settingsPrompt.kind === "project-create-confirm" ? "Create? (y/n) > " : settingsPrompt.kind === "project-rename" ? "Name > " : settingsPrompt.kind === "core-add" ? "Sentence > " : settingsPrompt.kind === "core-edit" ? "Sentence > " : settingsPrompt.kind === "core-delete-confirm" ? "Delete? (y/n) > " : "Value > ",
|
|
17071
17190
|
onSubmit,
|
|
17072
17191
|
onCancel: cancelSettingsPrompt
|
|
17073
|
-
}
|
|
17192
|
+
},
|
|
17193
|
+
`settings-prompt:${settingsPrompt.kind}:${settingsPrompt.restoreEpoch || 0}`
|
|
17074
17194
|
) : null }) : null,
|
|
17075
17195
|
!inputBoxHidden ? /* @__PURE__ */ jsxs16(Fragment6, { children: [
|
|
17076
17196
|
promptMetaVisible ? /* @__PURE__ */ jsxs16(Fragment6, { children: [
|
|
@@ -17172,12 +17292,8 @@ function usePromptDraftFlow({
|
|
|
17172
17292
|
slashDismissedFor,
|
|
17173
17293
|
setSlashDismissedFor,
|
|
17174
17294
|
providerPrompt,
|
|
17175
|
-
channelPrompt,
|
|
17176
|
-
hookPrompt,
|
|
17177
17295
|
settingsPrompt,
|
|
17178
17296
|
setProviderPrompt,
|
|
17179
|
-
setChannelPrompt,
|
|
17180
|
-
setHookPrompt,
|
|
17181
17297
|
setSettingsPrompt,
|
|
17182
17298
|
oauthSubmitRef,
|
|
17183
17299
|
openProjectPicker,
|
|
@@ -17216,6 +17332,7 @@ function usePromptDraftFlow({
|
|
|
17216
17332
|
}
|
|
17217
17333
|
}, [clearPromptHint, dismissWelcomePromptHint, resetPromptHistoryNav, showPromptHint, slashDismissedFor, syncPromptLayoutRows]);
|
|
17218
17334
|
const cancelProviderPrompt = useCallback8(() => {
|
|
17335
|
+
supersedePanelEpoch();
|
|
17219
17336
|
try {
|
|
17220
17337
|
providerPrompt?.login?.cancel?.();
|
|
17221
17338
|
} catch {
|
|
@@ -17227,17 +17344,8 @@ function usePromptDraftFlow({
|
|
|
17227
17344
|
if (onCancel) onCancel();
|
|
17228
17345
|
else if (afterSave) afterSave();
|
|
17229
17346
|
}, [providerPrompt, showPromptHint]);
|
|
17230
|
-
const cancelChannelPrompt = useCallback8(() => {
|
|
17231
|
-
const onCancel = channelPrompt?.onCancel;
|
|
17232
|
-
const afterSave = channelPrompt?.afterSave;
|
|
17233
|
-
setChannelPrompt(null);
|
|
17234
|
-
if (typeof onCancel === "function") onCancel();
|
|
17235
|
-
else if (typeof afterSave === "function") afterSave();
|
|
17236
|
-
}, [channelPrompt, showPromptHint]);
|
|
17237
|
-
const cancelHookPrompt = useCallback8(() => {
|
|
17238
|
-
setHookPrompt(null);
|
|
17239
|
-
}, [showPromptHint]);
|
|
17240
17347
|
const cancelSettingsPrompt = useCallback8(() => {
|
|
17348
|
+
supersedePanelEpoch();
|
|
17241
17349
|
const kind = settingsPrompt?.kind;
|
|
17242
17350
|
setSettingsPrompt(null);
|
|
17243
17351
|
if (kind === "project-new" || kind === "project-create-confirm" || kind === "project-rename") {
|
|
@@ -17277,8 +17385,6 @@ function usePromptDraftFlow({
|
|
|
17277
17385
|
return {
|
|
17278
17386
|
onPromptDraftChange,
|
|
17279
17387
|
cancelProviderPrompt,
|
|
17280
|
-
cancelChannelPrompt,
|
|
17281
|
-
cancelHookPrompt,
|
|
17282
17388
|
cancelSettingsPrompt,
|
|
17283
17389
|
acceptSlashPalette,
|
|
17284
17390
|
completeSlashPalette,
|
|
@@ -17387,18 +17493,16 @@ var themeNotice = (applied) => `Theme set to ${applied?.label || applied?.id ||
|
|
|
17387
17493
|
function createThemeEffortPickers({
|
|
17388
17494
|
state,
|
|
17389
17495
|
store,
|
|
17390
|
-
|
|
17496
|
+
surface,
|
|
17391
17497
|
setProviderPrompt,
|
|
17392
|
-
setChannelPrompt,
|
|
17393
|
-
setHookPrompt,
|
|
17394
17498
|
setSettingsPrompt,
|
|
17395
|
-
setContextPanel,
|
|
17396
17499
|
closeUsagePanel,
|
|
17397
17500
|
clean: clean2
|
|
17398
17501
|
}) {
|
|
17399
17502
|
const openThemePicker = (options = {}) => {
|
|
17400
17503
|
const returnTo = typeof options.returnTo === "function" ? options.returnTo : null;
|
|
17401
17504
|
const onboarding = options.onboarding || null;
|
|
17505
|
+
const own = surface.claim();
|
|
17402
17506
|
let themes = [];
|
|
17403
17507
|
try {
|
|
17404
17508
|
themes = store.listThemes?.() || [];
|
|
@@ -17420,10 +17524,8 @@ function createThemeEffortPickers({
|
|
|
17420
17524
|
_theme: entry
|
|
17421
17525
|
}));
|
|
17422
17526
|
setProviderPrompt(null);
|
|
17423
|
-
setChannelPrompt(null);
|
|
17424
|
-
setHookPrompt(null);
|
|
17425
17527
|
setSettingsPrompt(null);
|
|
17426
|
-
|
|
17528
|
+
own.context(null);
|
|
17427
17529
|
closeUsagePanel();
|
|
17428
17530
|
const applyTheme = (id, { persist = true } = {}) => {
|
|
17429
17531
|
try {
|
|
@@ -17434,13 +17536,13 @@ function createThemeEffortPickers({
|
|
|
17434
17536
|
}
|
|
17435
17537
|
};
|
|
17436
17538
|
const saveTheme = (id, { advance = false } = {}) => {
|
|
17437
|
-
|
|
17539
|
+
own.close();
|
|
17438
17540
|
const applied = applyTheme(id, { persist: true });
|
|
17439
17541
|
store.pushNotice(themeNotice(applied || { id }), "info");
|
|
17440
17542
|
if (advance && onboarding) onboarding.onAdvance?.();
|
|
17441
17543
|
else if (returnTo) returnTo();
|
|
17442
17544
|
};
|
|
17443
|
-
|
|
17545
|
+
own.paint({
|
|
17444
17546
|
title: "Theme",
|
|
17445
17547
|
description: "Choose the color theme that looks best with your terminal.",
|
|
17446
17548
|
help: onboarding ? void 0 : returnTo ? "\u2191/\u2193 Preview \xB7 Enter Choose \xB7 Esc Settings" : "\u2191/\u2193 Preview \xB7 Enter Choose \xB7 Esc Back",
|
|
@@ -17475,7 +17577,7 @@ function createThemeEffortPickers({
|
|
|
17475
17577
|
saveTheme(entry.id, { advance: Boolean(onboarding) });
|
|
17476
17578
|
},
|
|
17477
17579
|
onCancel: () => {
|
|
17478
|
-
|
|
17580
|
+
own.close();
|
|
17479
17581
|
if (currentId) applyTheme(currentId, { persist: false });
|
|
17480
17582
|
if (onboarding) onboarding.onCancel?.();
|
|
17481
17583
|
else if (returnTo) returnTo();
|
|
@@ -17483,9 +17585,8 @@ function createThemeEffortPickers({
|
|
|
17483
17585
|
});
|
|
17484
17586
|
};
|
|
17485
17587
|
const openEffortPicker = () => {
|
|
17588
|
+
const own = surface.claim();
|
|
17486
17589
|
setProviderPrompt(null);
|
|
17487
|
-
setChannelPrompt(null);
|
|
17488
|
-
setHookPrompt(null);
|
|
17489
17590
|
setSettingsPrompt(null);
|
|
17490
17591
|
const items = Array.isArray(state.effortOptions) && state.effortOptions.length > 0 ? state.effortOptions : [];
|
|
17491
17592
|
if (!items.length) {
|
|
@@ -17499,17 +17600,17 @@ function createThemeEffortPickers({
|
|
|
17499
17600
|
markerColor: theme.success,
|
|
17500
17601
|
description: clean2(item?.description).toLowerCase() === "current" ? "" : item?.description
|
|
17501
17602
|
}));
|
|
17502
|
-
|
|
17603
|
+
own.paint({
|
|
17503
17604
|
title: "Effort",
|
|
17504
17605
|
description: "Reasoning effort for the current model.",
|
|
17505
17606
|
items: pickerItems,
|
|
17506
17607
|
onSelect: (value) => {
|
|
17507
|
-
|
|
17608
|
+
own.close();
|
|
17508
17609
|
const pendingTurn = state.busy ? " (applies from the next turn)" : "";
|
|
17509
17610
|
void store.setEffort(value).then((result) => store.pushNotice(result ? `Effort set to ${result}${pendingTurn}` : "Effort switch is already running.", result ? "info" : "warn")).catch((e) => store.pushNotice(`Couldn\u2019t switch effort: ${e?.message || e}`, "error"));
|
|
17510
17611
|
},
|
|
17511
17612
|
onCancel: () => {
|
|
17512
|
-
|
|
17613
|
+
own.close();
|
|
17513
17614
|
}
|
|
17514
17615
|
});
|
|
17515
17616
|
};
|
|
@@ -17519,11 +17620,12 @@ function createThemeEffortPickers({
|
|
|
17519
17620
|
// src/tui/app/resume-picker.mjs
|
|
17520
17621
|
function createResumePicker({
|
|
17521
17622
|
store,
|
|
17522
|
-
|
|
17623
|
+
surface,
|
|
17523
17624
|
formatSessionUpdatedAt: formatSessionUpdatedAt2,
|
|
17524
17625
|
formatSessionMessageCount: formatSessionMessageCount2
|
|
17525
17626
|
}) {
|
|
17526
17627
|
const openResumePicker = async () => {
|
|
17628
|
+
const own = surface.claim();
|
|
17527
17629
|
let sessions;
|
|
17528
17630
|
try {
|
|
17529
17631
|
sessions = await store.listSessions({ refreshFromStorage: true });
|
|
@@ -17545,19 +17647,19 @@ function createResumePicker({
|
|
|
17545
17647
|
description: title || preview || "(no message)"
|
|
17546
17648
|
};
|
|
17547
17649
|
});
|
|
17548
|
-
|
|
17650
|
+
own.paint({
|
|
17549
17651
|
title: "Resume",
|
|
17550
17652
|
description: "Restore a saved chat session.",
|
|
17551
17653
|
items,
|
|
17552
17654
|
labelWidth: 21,
|
|
17553
17655
|
onSelect: (value) => {
|
|
17554
|
-
|
|
17656
|
+
own.close();
|
|
17555
17657
|
const selected = sessions.find((session) => session.id === value);
|
|
17556
17658
|
const resumedName = String(selected?.title || selected?.preview || value).replace(/\s+/g, " ").trim();
|
|
17557
17659
|
void store.resume(value).then((ok) => store.pushNotice(ok ? `Resumed ${resumedName || value}` : "Couldn\u2019t resume chat.", ok ? "info" : "warn")).catch((e) => store.pushNotice(`Couldn\u2019t resume chat: ${e?.message || e}`, "error"));
|
|
17558
17660
|
},
|
|
17559
17661
|
onCancel: () => {
|
|
17560
|
-
|
|
17662
|
+
own.close();
|
|
17561
17663
|
}
|
|
17562
17664
|
});
|
|
17563
17665
|
};
|
|
@@ -17567,20 +17669,22 @@ function createResumePicker({
|
|
|
17567
17669
|
// src/tui/app/core-memory-picker.mjs
|
|
17568
17670
|
function createCoreMemoryPicker({
|
|
17569
17671
|
store,
|
|
17570
|
-
|
|
17672
|
+
surface,
|
|
17571
17673
|
setSettingsPrompt,
|
|
17572
17674
|
parseMemoryCoreRows: parseMemoryCoreRows2
|
|
17573
17675
|
}) {
|
|
17574
17676
|
let escReturnTo = null;
|
|
17575
17677
|
const closeMemoryCorePicker = () => {
|
|
17576
17678
|
if (escReturnTo) escReturnTo();
|
|
17577
|
-
else
|
|
17679
|
+
else surface.claim().close();
|
|
17578
17680
|
};
|
|
17579
17681
|
const openMemoryCorePicker = (options = {}) => {
|
|
17580
17682
|
if (options && Object.prototype.hasOwnProperty.call(options, "returnTo")) {
|
|
17581
17683
|
escReturnTo = typeof options.returnTo === "function" ? options.returnTo : null;
|
|
17582
17684
|
}
|
|
17583
|
-
|
|
17685
|
+
const own = surface.claim();
|
|
17686
|
+
const paintPanel = (panel) => own.paint(panel);
|
|
17687
|
+
paintPanel({
|
|
17584
17688
|
title: "Memory",
|
|
17585
17689
|
// Loading state lives in the header description row, not as a fake
|
|
17586
17690
|
// selectable menu item.
|
|
@@ -17603,7 +17707,7 @@ function createCoreMemoryPicker({
|
|
|
17603
17707
|
_rows: coreRows
|
|
17604
17708
|
}
|
|
17605
17709
|
];
|
|
17606
|
-
|
|
17710
|
+
paintPanel({
|
|
17607
17711
|
title: "Memory",
|
|
17608
17712
|
description: "User-curated core memories across projects.",
|
|
17609
17713
|
items: rows.length ? rows : [{ value: "empty", label: "Memory", description: "empty" }],
|
|
@@ -17620,13 +17724,15 @@ function createCoreMemoryPicker({
|
|
|
17620
17724
|
onCancel: closeMemoryCorePicker
|
|
17621
17725
|
});
|
|
17622
17726
|
}).catch((e) => {
|
|
17623
|
-
|
|
17727
|
+
own.close();
|
|
17624
17728
|
store.pushNotice(`core memory failed: ${e?.message || e}`, "error");
|
|
17625
17729
|
});
|
|
17626
17730
|
};
|
|
17627
17731
|
const openCoreMemoryListPicker = (rows = null) => {
|
|
17732
|
+
const own = surface.claim();
|
|
17733
|
+
const paintPanel = (panel) => own.paint(panel);
|
|
17628
17734
|
const renderList = (coreRows) => {
|
|
17629
|
-
|
|
17735
|
+
paintPanel({
|
|
17630
17736
|
title: "Memory \xB7 List",
|
|
17631
17737
|
description: coreRows.length ? "Select a memory to edit or delete." : "No stored memories yet.",
|
|
17632
17738
|
items: coreRows.length ? coreRows : [{ value: "empty", label: "Memory", description: "empty" }],
|
|
@@ -17643,7 +17749,7 @@ function createCoreMemoryPicker({
|
|
|
17643
17749
|
renderList(rows);
|
|
17644
17750
|
return;
|
|
17645
17751
|
}
|
|
17646
|
-
|
|
17752
|
+
paintPanel({
|
|
17647
17753
|
title: "Memory \xB7 List",
|
|
17648
17754
|
description: "Loading memories\u2026",
|
|
17649
17755
|
items: [],
|
|
@@ -17651,13 +17757,16 @@ function createCoreMemoryPicker({
|
|
|
17651
17757
|
},
|
|
17652
17758
|
onCancel: () => openMemoryCorePicker()
|
|
17653
17759
|
});
|
|
17654
|
-
void store.memoryControl?.({ action: "core", op: "list", project_id: "*" }, { silent: true }).then((result) =>
|
|
17655
|
-
|
|
17760
|
+
void store.memoryControl?.({ action: "core", op: "list", project_id: "*" }, { silent: true }).then((result) => {
|
|
17761
|
+
renderList(parseMemoryCoreRows2(result));
|
|
17762
|
+
}).catch((e) => {
|
|
17763
|
+
own.close();
|
|
17656
17764
|
store.pushNotice(`core memory failed: ${e?.message || e}`, "error");
|
|
17657
17765
|
});
|
|
17658
17766
|
};
|
|
17659
17767
|
const openCoreEntryActionsPicker = (entryItem) => {
|
|
17660
|
-
|
|
17768
|
+
const own = surface.claim();
|
|
17769
|
+
own.paint({
|
|
17661
17770
|
title: `Memory \xB7 #${entryItem._id}`,
|
|
17662
17771
|
description: entryItem._summary || entryItem._element || "",
|
|
17663
17772
|
items: [
|
|
@@ -17672,7 +17781,7 @@ function createCoreMemoryPicker({
|
|
|
17672
17781
|
});
|
|
17673
17782
|
};
|
|
17674
17783
|
const beginAddCoreMemory = () => {
|
|
17675
|
-
|
|
17784
|
+
surface.claim().close();
|
|
17676
17785
|
setSettingsPrompt({
|
|
17677
17786
|
kind: "core-add",
|
|
17678
17787
|
label: "Add memory",
|
|
@@ -17680,7 +17789,7 @@ function createCoreMemoryPicker({
|
|
|
17680
17789
|
});
|
|
17681
17790
|
};
|
|
17682
17791
|
const beginEditCoreMemory = (entryItem) => {
|
|
17683
|
-
|
|
17792
|
+
surface.claim().close();
|
|
17684
17793
|
setSettingsPrompt({
|
|
17685
17794
|
kind: "core-edit",
|
|
17686
17795
|
label: `Memory \xB7 Edit #${entryItem._id}`,
|
|
@@ -17695,7 +17804,7 @@ function createCoreMemoryPicker({
|
|
|
17695
17804
|
});
|
|
17696
17805
|
};
|
|
17697
17806
|
const beginDeleteCoreMemory = (entryItem) => {
|
|
17698
|
-
|
|
17807
|
+
surface.claim().close();
|
|
17699
17808
|
setSettingsPrompt({
|
|
17700
17809
|
kind: "core-delete-confirm",
|
|
17701
17810
|
label: `Memory \xB7 Delete #${entryItem._id}?`,
|
|
@@ -17719,11 +17828,9 @@ function createExtensionPickers({
|
|
|
17719
17828
|
theme: theme2,
|
|
17720
17829
|
clean: clean2,
|
|
17721
17830
|
copyToClipboard: copyToClipboard2,
|
|
17722
|
-
|
|
17831
|
+
surface,
|
|
17723
17832
|
getPicker,
|
|
17724
17833
|
setProviderPrompt,
|
|
17725
|
-
setChannelPrompt,
|
|
17726
|
-
setHookPrompt,
|
|
17727
17834
|
setSettingsPrompt,
|
|
17728
17835
|
getDisabledSkills,
|
|
17729
17836
|
setDisabledSkills
|
|
@@ -17741,6 +17848,7 @@ function createExtensionPickers({
|
|
|
17741
17848
|
return { ...status, servers: status.servers || [] };
|
|
17742
17849
|
};
|
|
17743
17850
|
const openMcpServersPicker = async (options = {}) => {
|
|
17851
|
+
const own = surface.claim();
|
|
17744
17852
|
const status = await mcpStatus();
|
|
17745
17853
|
if (!status) return;
|
|
17746
17854
|
const servers = status.servers || [];
|
|
@@ -17768,9 +17876,8 @@ function createExtensionPickers({
|
|
|
17768
17876
|
_enabled: enabled
|
|
17769
17877
|
});
|
|
17770
17878
|
}
|
|
17879
|
+
if (!own.owns()) return;
|
|
17771
17880
|
setProviderPrompt(null);
|
|
17772
|
-
setChannelPrompt(null);
|
|
17773
|
-
setHookPrompt(null);
|
|
17774
17881
|
setSettingsPrompt(null);
|
|
17775
17882
|
const toggleServer = (item) => {
|
|
17776
17883
|
if (item._action !== "server" || !item._server?.name) return;
|
|
@@ -17790,7 +17897,7 @@ function createExtensionPickers({
|
|
|
17790
17897
|
settle(() => openMcpServersPicker({ highlightValue }));
|
|
17791
17898
|
});
|
|
17792
17899
|
};
|
|
17793
|
-
|
|
17900
|
+
own.paint({
|
|
17794
17901
|
_kind: "mcp-servers",
|
|
17795
17902
|
title: "MCP servers",
|
|
17796
17903
|
description: "Enable or disable configured MCP servers.",
|
|
@@ -17802,7 +17909,7 @@ function createExtensionPickers({
|
|
|
17802
17909
|
onCancel: () => {
|
|
17803
17910
|
mcpActive = false;
|
|
17804
17911
|
mcpEpoch++;
|
|
17805
|
-
|
|
17912
|
+
own.close();
|
|
17806
17913
|
}
|
|
17807
17914
|
});
|
|
17808
17915
|
mcpActive = true;
|
|
@@ -17821,6 +17928,7 @@ function createExtensionPickers({
|
|
|
17821
17928
|
return { ...status, skills: status.skills || [] };
|
|
17822
17929
|
};
|
|
17823
17930
|
const openProjectSkillsPicker = async () => {
|
|
17931
|
+
const own = surface.claim();
|
|
17824
17932
|
const status = await skillsStatus();
|
|
17825
17933
|
if (!status) return;
|
|
17826
17934
|
const skills = status.skills || [];
|
|
@@ -17842,26 +17950,26 @@ function createExtensionPickers({
|
|
|
17842
17950
|
_skill: skill
|
|
17843
17951
|
});
|
|
17844
17952
|
}
|
|
17953
|
+
if (!own.owns()) return;
|
|
17845
17954
|
setProviderPrompt(null);
|
|
17846
|
-
setChannelPrompt(null);
|
|
17847
|
-
setHookPrompt(null);
|
|
17848
17955
|
setSettingsPrompt(null);
|
|
17849
|
-
|
|
17956
|
+
own.paint({
|
|
17850
17957
|
title: "Project skills",
|
|
17851
17958
|
description: "Skills bundled with this project.",
|
|
17852
17959
|
items,
|
|
17853
17960
|
onSelect: (_value, item) => {
|
|
17854
|
-
|
|
17961
|
+
own.close();
|
|
17855
17962
|
if (item._action !== "view") return;
|
|
17856
17963
|
openSkillDetailPicker(item._skill);
|
|
17857
17964
|
},
|
|
17858
17965
|
onCancel: () => {
|
|
17859
|
-
|
|
17966
|
+
own.close();
|
|
17860
17967
|
void openSkillsPicker();
|
|
17861
17968
|
}
|
|
17862
17969
|
});
|
|
17863
17970
|
};
|
|
17864
17971
|
const openSkillsPicker = async (options = {}) => {
|
|
17972
|
+
const own = surface.claim();
|
|
17865
17973
|
let skills;
|
|
17866
17974
|
if (Array.isArray(options.skills)) {
|
|
17867
17975
|
skills = options.skills;
|
|
@@ -17893,9 +18001,8 @@ function createExtensionPickers({
|
|
|
17893
18001
|
_enabled: enabled
|
|
17894
18002
|
});
|
|
17895
18003
|
}
|
|
18004
|
+
if (!own.owns()) return;
|
|
17896
18005
|
setProviderPrompt(null);
|
|
17897
|
-
setChannelPrompt(null);
|
|
17898
|
-
setHookPrompt(null);
|
|
17899
18006
|
setSettingsPrompt(null);
|
|
17900
18007
|
const toggleSkill = (item) => {
|
|
17901
18008
|
if (item._action !== "skill" || !item._skill?.name) return;
|
|
@@ -17910,7 +18017,7 @@ function createExtensionPickers({
|
|
|
17910
18017
|
);
|
|
17911
18018
|
openSkillsPicker({ highlightValue: name, disabledOverride: next, skills });
|
|
17912
18019
|
};
|
|
17913
|
-
|
|
18020
|
+
own.paint({
|
|
17914
18021
|
_kind: "skills",
|
|
17915
18022
|
title: "Skills",
|
|
17916
18023
|
description: "Enable or disable project skills.",
|
|
@@ -17920,13 +18027,14 @@ function createExtensionPickers({
|
|
|
17920
18027
|
onLeft: (item) => toggleSkill(item),
|
|
17921
18028
|
onRight: (item) => toggleSkill(item),
|
|
17922
18029
|
onCancel: () => {
|
|
17923
|
-
|
|
18030
|
+
own.close();
|
|
17924
18031
|
}
|
|
17925
18032
|
});
|
|
17926
18033
|
};
|
|
17927
18034
|
const openSkillDetailPicker = (skill) => {
|
|
18035
|
+
const own = surface.claim();
|
|
17928
18036
|
const disabled = getDisabledSkills().has(skill.name);
|
|
17929
|
-
|
|
18037
|
+
own.paint({
|
|
17930
18038
|
title: `Skill \xB7 ${skill.name}`,
|
|
17931
18039
|
description: clean2(skill.description) || "Enable, disable, or run this skill.",
|
|
17932
18040
|
items: [
|
|
@@ -17944,7 +18052,7 @@ function createExtensionPickers({
|
|
|
17944
18052
|
}
|
|
17945
18053
|
],
|
|
17946
18054
|
onSelect: (_value, item) => {
|
|
17947
|
-
|
|
18055
|
+
own.close();
|
|
17948
18056
|
if (item._action === "enable") {
|
|
17949
18057
|
setDisabledSkills((current) => {
|
|
17950
18058
|
const next = new Set(current);
|
|
@@ -17976,7 +18084,7 @@ function createExtensionPickers({
|
|
|
17976
18084
|
}
|
|
17977
18085
|
},
|
|
17978
18086
|
onCancel: () => {
|
|
17979
|
-
|
|
18087
|
+
own.close();
|
|
17980
18088
|
void openSkillsPicker();
|
|
17981
18089
|
}
|
|
17982
18090
|
});
|
|
@@ -17992,11 +18100,12 @@ function createExtensionPickers({
|
|
|
17992
18100
|
return { ...status, plugins: status.plugins || [] };
|
|
17993
18101
|
};
|
|
17994
18102
|
const beginAddPlugin = () => {
|
|
17995
|
-
|
|
18103
|
+
surface.claim().close();
|
|
17996
18104
|
setSettingsPrompt({ kind: "plugin-add", label: "Plugin URL", hint: "Git URL, owner/repo, or local path" });
|
|
17997
18105
|
};
|
|
17998
18106
|
const openPluginDetailPicker = (p) => {
|
|
17999
|
-
|
|
18107
|
+
const own = surface.claim();
|
|
18108
|
+
own.paint({
|
|
18000
18109
|
title: p.title || p.name,
|
|
18001
18110
|
description: clean2(p.description) || "Update, MCP, or uninstall this plugin.",
|
|
18002
18111
|
items: [
|
|
@@ -18038,7 +18147,7 @@ function createExtensionPickers({
|
|
|
18038
18147
|
}
|
|
18039
18148
|
],
|
|
18040
18149
|
onSelect: (_detailValue, detail) => {
|
|
18041
|
-
|
|
18150
|
+
own.paint(null);
|
|
18042
18151
|
if (detail._action === "info") {
|
|
18043
18152
|
store.pushNotice([
|
|
18044
18153
|
`${p.title || p.name}${p.version ? ` ${p.version}` : ""}`,
|
|
@@ -18052,11 +18161,11 @@ ${p.description}` : ""
|
|
|
18052
18161
|
return;
|
|
18053
18162
|
}
|
|
18054
18163
|
if (detail._action === "update") {
|
|
18055
|
-
void store.updatePlugin?.(p).then(() => openInstalledPluginsPicker()).catch((e) => store.pushNotice(`plugin update failed: ${e?.message || e}`, "error"));
|
|
18164
|
+
void store.updatePlugin?.(p).then(own.defer(() => openInstalledPluginsPicker())).catch((e) => store.pushNotice(`plugin update failed: ${e?.message || e}`, "error"));
|
|
18056
18165
|
return;
|
|
18057
18166
|
}
|
|
18058
18167
|
if (detail._action === "enable-mcp") {
|
|
18059
|
-
void store.enablePluginMcp?.(p).then(() => openMcpPicker()).catch((e) => store.pushNotice(`plugin MCP enable failed: ${e?.message || e}`, "error"));
|
|
18168
|
+
void store.enablePluginMcp?.(p).then(own.defer(() => openMcpPicker())).catch((e) => store.pushNotice(`plugin MCP enable failed: ${e?.message || e}`, "error"));
|
|
18060
18169
|
return;
|
|
18061
18170
|
}
|
|
18062
18171
|
if (detail._action === "copy-root") {
|
|
@@ -18068,16 +18177,17 @@ ${p.description}` : ""
|
|
|
18068
18177
|
return;
|
|
18069
18178
|
}
|
|
18070
18179
|
if (detail._action === "uninstall") {
|
|
18071
|
-
void store.removePlugin?.(p).then(() => openInstalledPluginsPicker()).catch((e) => store.pushNotice(`plugin uninstall failed: ${e?.message || e}`, "error"));
|
|
18180
|
+
void store.removePlugin?.(p).then(own.defer(() => openInstalledPluginsPicker())).catch((e) => store.pushNotice(`plugin uninstall failed: ${e?.message || e}`, "error"));
|
|
18072
18181
|
}
|
|
18073
18182
|
},
|
|
18074
18183
|
onCancel: () => {
|
|
18075
|
-
|
|
18184
|
+
own.close();
|
|
18076
18185
|
void openInstalledPluginsPicker();
|
|
18077
18186
|
}
|
|
18078
18187
|
});
|
|
18079
18188
|
};
|
|
18080
18189
|
const openInstalledPluginsPicker = async () => {
|
|
18190
|
+
const own = surface.claim();
|
|
18081
18191
|
const status = await pluginStatus();
|
|
18082
18192
|
if (!status) return;
|
|
18083
18193
|
const plugins = status.plugins || [];
|
|
@@ -18099,33 +18209,32 @@ ${p.description}` : ""
|
|
|
18099
18209
|
_plugin: plugin
|
|
18100
18210
|
});
|
|
18101
18211
|
}
|
|
18212
|
+
if (!own.owns()) return;
|
|
18102
18213
|
setProviderPrompt(null);
|
|
18103
|
-
setChannelPrompt(null);
|
|
18104
|
-
setHookPrompt(null);
|
|
18105
18214
|
setSettingsPrompt(null);
|
|
18106
|
-
|
|
18215
|
+
own.paint({
|
|
18107
18216
|
title: "Installed plugins",
|
|
18108
18217
|
description: "Open an installed plugin to manage it.",
|
|
18109
18218
|
items,
|
|
18110
18219
|
onSelect: (_value, item) => {
|
|
18111
|
-
|
|
18220
|
+
own.close();
|
|
18112
18221
|
if (item._action !== "plugin") return;
|
|
18113
18222
|
openPluginDetailPicker(item._plugin);
|
|
18114
18223
|
},
|
|
18115
18224
|
onCancel: () => {
|
|
18116
|
-
|
|
18225
|
+
own.close();
|
|
18117
18226
|
void openPluginsPicker();
|
|
18118
18227
|
}
|
|
18119
18228
|
});
|
|
18120
18229
|
};
|
|
18121
18230
|
const openPluginsPicker = async () => {
|
|
18231
|
+
const own = surface.claim();
|
|
18122
18232
|
const status = await pluginStatus();
|
|
18123
18233
|
if (!status) return;
|
|
18234
|
+
if (!own.owns()) return;
|
|
18124
18235
|
setProviderPrompt(null);
|
|
18125
|
-
setChannelPrompt(null);
|
|
18126
|
-
setHookPrompt(null);
|
|
18127
18236
|
setSettingsPrompt(null);
|
|
18128
|
-
|
|
18237
|
+
own.paint({
|
|
18129
18238
|
title: "Plugins",
|
|
18130
18239
|
description: "Add or manage local plugin integrations.",
|
|
18131
18240
|
items: [
|
|
@@ -18143,7 +18252,7 @@ ${p.description}` : ""
|
|
|
18143
18252
|
}
|
|
18144
18253
|
],
|
|
18145
18254
|
onSelect: (_value, item) => {
|
|
18146
|
-
|
|
18255
|
+
own.close();
|
|
18147
18256
|
if (item._action === "installed") {
|
|
18148
18257
|
openInstalledPluginsPicker();
|
|
18149
18258
|
return;
|
|
@@ -18151,11 +18260,12 @@ ${p.description}` : ""
|
|
|
18151
18260
|
if (item._action === "add") beginAddPlugin();
|
|
18152
18261
|
},
|
|
18153
18262
|
onCancel: () => {
|
|
18154
|
-
|
|
18263
|
+
own.close();
|
|
18155
18264
|
}
|
|
18156
18265
|
});
|
|
18157
18266
|
};
|
|
18158
18267
|
const openHooksPicker = async () => {
|
|
18268
|
+
const own = surface.claim();
|
|
18159
18269
|
let status;
|
|
18160
18270
|
try {
|
|
18161
18271
|
status = await store.hooksStatus?.() || { events: [], recent: [] };
|
|
@@ -18180,20 +18290,14 @@ ${p.description}` : ""
|
|
|
18180
18290
|
_action: "noop"
|
|
18181
18291
|
}]
|
|
18182
18292
|
];
|
|
18293
|
+
if (!own.owns()) return;
|
|
18183
18294
|
setProviderPrompt(null);
|
|
18184
|
-
setChannelPrompt(null);
|
|
18185
|
-
setHookPrompt(null);
|
|
18186
18295
|
setSettingsPrompt(null);
|
|
18187
18296
|
const toggleRule = (item) => {
|
|
18188
18297
|
if (item._action !== "rule") return;
|
|
18189
|
-
|
|
18190
|
-
store.setHookRuleEnabled?.(item._rule.index, !item._rule.enabled);
|
|
18191
|
-
void openHooksPicker();
|
|
18192
|
-
} catch (e) {
|
|
18193
|
-
store.pushNotice(`hook toggle failed: ${e?.message || e}`, "error");
|
|
18194
|
-
}
|
|
18298
|
+
void Promise.resolve(store.setHookRuleEnabled?.(item._rule.index, !item._rule.enabled)).then(own.defer(() => openHooksPicker())).catch((e) => store.pushNotice(`hook toggle failed: ${e?.message || e}`, "error"));
|
|
18195
18299
|
};
|
|
18196
|
-
|
|
18300
|
+
own.paint({
|
|
18197
18301
|
_kind: "hooks",
|
|
18198
18302
|
title: "Hooks",
|
|
18199
18303
|
description: "Before-tool hook rules; Enter toggles a rule.",
|
|
@@ -18202,7 +18306,7 @@ ${p.description}` : ""
|
|
|
18202
18306
|
onLeft: (item) => toggleRule(item),
|
|
18203
18307
|
onRight: (item) => toggleRule(item),
|
|
18204
18308
|
onCancel: () => {
|
|
18205
|
-
|
|
18309
|
+
own.close();
|
|
18206
18310
|
}
|
|
18207
18311
|
});
|
|
18208
18312
|
};
|
|
@@ -18225,16 +18329,20 @@ function createMaintenancePickers({
|
|
|
18225
18329
|
store,
|
|
18226
18330
|
theme: theme2,
|
|
18227
18331
|
formatDuration: formatDuration2,
|
|
18228
|
-
|
|
18332
|
+
surface,
|
|
18229
18333
|
setProviderPrompt,
|
|
18230
|
-
setChannelPrompt,
|
|
18231
|
-
setHookPrompt,
|
|
18232
18334
|
setSettingsPrompt,
|
|
18233
|
-
setContextPanel,
|
|
18234
18335
|
closeUsagePanel
|
|
18235
18336
|
}) {
|
|
18236
18337
|
const openUpdatePicker = (options = {}) => {
|
|
18237
18338
|
const returnTo = typeof options.returnTo === "function" ? options.returnTo : null;
|
|
18339
|
+
const own = surface.claim();
|
|
18340
|
+
const paintPanel = (panel) => {
|
|
18341
|
+
if (!own.owns()) return false;
|
|
18342
|
+
setProviderPrompt(null);
|
|
18343
|
+
setSettingsPrompt(null);
|
|
18344
|
+
return own.paint(panel);
|
|
18345
|
+
};
|
|
18238
18346
|
const readSettings = async () => {
|
|
18239
18347
|
try {
|
|
18240
18348
|
return await store.getUpdateSettings?.() || {};
|
|
@@ -18277,11 +18385,7 @@ function createMaintenancePickers({
|
|
|
18277
18385
|
_action: "auto-update"
|
|
18278
18386
|
}
|
|
18279
18387
|
];
|
|
18280
|
-
|
|
18281
|
-
setChannelPrompt(null);
|
|
18282
|
-
setHookPrompt(null);
|
|
18283
|
-
setSettingsPrompt(null);
|
|
18284
|
-
setPicker({
|
|
18388
|
+
return paintPanel({
|
|
18285
18389
|
title: "Update",
|
|
18286
18390
|
description: "Check version and update mixdog.",
|
|
18287
18391
|
help: "\u2191/\u2193 Select \xB7 Enter Open/Toggle \xB7 Esc Close",
|
|
@@ -18308,46 +18412,54 @@ function createMaintenancePickers({
|
|
|
18308
18412
|
}
|
|
18309
18413
|
},
|
|
18310
18414
|
onCancel: () => {
|
|
18311
|
-
|
|
18415
|
+
own.close();
|
|
18312
18416
|
if (returnTo) returnTo();
|
|
18313
18417
|
}
|
|
18314
18418
|
});
|
|
18315
18419
|
};
|
|
18420
|
+
const rerender = (opts = {}) => {
|
|
18421
|
+
void Promise.resolve(render2(opts)).catch((e) => store.pushNotice(`update panel failed: ${e?.message || e}`, "error"));
|
|
18422
|
+
};
|
|
18423
|
+
const deferredRerender = (opts = {}) => own.defer(() => rerender(opts));
|
|
18316
18424
|
const toggleAutoUpdate = (enabled) => {
|
|
18317
|
-
|
|
18318
|
-
void Promise.resolve(store.setAutoUpdate?.(enabled)).finally(() => render2());
|
|
18319
|
-
store.pushNotice(`Auto-update ${enabled ? "on" : "off"}`, "info");
|
|
18320
|
-
} catch (e) {
|
|
18321
|
-
store.pushNotice(`auto-update failed: ${e?.message || e}`, "error");
|
|
18322
|
-
}
|
|
18323
|
-
render2();
|
|
18425
|
+
void Promise.resolve(store.setAutoUpdate?.(enabled)).then(() => store.pushNotice(`Auto-update ${enabled ? "on" : "off"}`, "info")).catch((e) => store.pushNotice(`auto-update failed: ${e?.message || e}`, "error")).finally(deferredRerender());
|
|
18324
18426
|
};
|
|
18325
18427
|
const recheck = () => {
|
|
18326
|
-
|
|
18327
|
-
|
|
18428
|
+
rerender({ checking: true });
|
|
18429
|
+
const settled = deferredRerender();
|
|
18430
|
+
void Promise.resolve(store.checkForUpdate?.({ force: true })).then(() => settled()).catch((e) => {
|
|
18328
18431
|
store.pushNotice(`update check failed: ${e?.message || e}`, "error");
|
|
18329
|
-
|
|
18432
|
+
settled();
|
|
18330
18433
|
});
|
|
18331
18434
|
};
|
|
18332
18435
|
const runUpdate = () => {
|
|
18333
18436
|
store.pushNotice("Updating\u2026", "info");
|
|
18437
|
+
const settled = deferredRerender();
|
|
18334
18438
|
void Promise.resolve(store.runUpdateNow?.()).then((result) => {
|
|
18335
18439
|
if (result?.ok) {
|
|
18336
18440
|
store.pushNotice(`v${result.version} installed \u2014 restart to apply`, "warn");
|
|
18337
18441
|
} else {
|
|
18338
18442
|
store.pushNotice(`Update failed: ${result?.error || "unknown error"}`, "error");
|
|
18339
18443
|
}
|
|
18340
|
-
|
|
18444
|
+
settled();
|
|
18341
18445
|
}).catch((e) => {
|
|
18342
18446
|
store.pushNotice(`Update failed: ${e?.message || e}`, "error");
|
|
18343
|
-
|
|
18447
|
+
settled();
|
|
18344
18448
|
});
|
|
18345
18449
|
};
|
|
18346
|
-
render2({ checking: true })
|
|
18347
|
-
|
|
18450
|
+
void Promise.resolve(render2({ checking: true })).catch((e) => {
|
|
18451
|
+
store.pushNotice(`update panel failed: ${e?.message || e}`, "error");
|
|
18452
|
+
return false;
|
|
18453
|
+
}).then((painted) => {
|
|
18454
|
+
if (!painted) return;
|
|
18455
|
+
const initialChecked = deferredRerender();
|
|
18456
|
+
void Promise.resolve(store.checkForUpdate?.({})).then(() => initialChecked()).catch(() => initialChecked());
|
|
18457
|
+
});
|
|
18348
18458
|
};
|
|
18349
18459
|
const openAutoClearPicker = (options = {}) => {
|
|
18350
18460
|
const returnTo = typeof options.returnTo === "function" ? options.returnTo : null;
|
|
18461
|
+
const own = surface.claim();
|
|
18462
|
+
const paintPanel = (panel) => own.paint(panel);
|
|
18351
18463
|
const HOUR_MS = 60 * 60 * 1e3;
|
|
18352
18464
|
const formatDurationInput = (ms) => {
|
|
18353
18465
|
const value = Math.max(0, Math.round(Number(ms) || 0));
|
|
@@ -18364,19 +18476,20 @@ function createMaintenancePickers({
|
|
|
18364
18476
|
}
|
|
18365
18477
|
};
|
|
18366
18478
|
const applyAutoClear = (patch = {}) => {
|
|
18479
|
+
const settled = own.defer(() => {
|
|
18480
|
+
void Promise.resolve(render2()).catch((e) => store.pushNotice(`auto-clear panel failed: ${e?.message || e}`, "error"));
|
|
18481
|
+
});
|
|
18367
18482
|
void Promise.resolve(store.setAutoClear?.(patch)).then((next) => {
|
|
18368
18483
|
if (!next) {
|
|
18369
18484
|
store.pushNotice("autoclear unavailable", "warn");
|
|
18370
18485
|
return;
|
|
18371
18486
|
}
|
|
18372
18487
|
store.pushNotice(next.enabled ? `autoclear on \xB7 idle ${formatDuration2(next.idleMs)}` : "autoclear off", "info");
|
|
18373
|
-
}).catch((e) => store.pushNotice(`autoclear failed: ${e?.message || e}`, "error")).finally(
|
|
18374
|
-
void render2();
|
|
18375
|
-
});
|
|
18488
|
+
}).catch((e) => store.pushNotice(`autoclear failed: ${e?.message || e}`, "error")).finally(settled);
|
|
18376
18489
|
};
|
|
18377
18490
|
const openProviderDurationEditor = (entry) => {
|
|
18378
18491
|
if (!entry?.provider) return;
|
|
18379
|
-
|
|
18492
|
+
own.close();
|
|
18380
18493
|
setSettingsPrompt({
|
|
18381
18494
|
kind: "autoclear-provider",
|
|
18382
18495
|
label: `Auto-clear \xB7 ${entry.provider}`,
|
|
@@ -18401,7 +18514,7 @@ function createMaintenancePickers({
|
|
|
18401
18514
|
_action: "provider-default",
|
|
18402
18515
|
_entry: entry
|
|
18403
18516
|
}));
|
|
18404
|
-
|
|
18517
|
+
paintPanel({
|
|
18405
18518
|
title: "Auto-clear \xB7 Advanced",
|
|
18406
18519
|
description: "Provider default idle windows. Enter edits the duration text.",
|
|
18407
18520
|
help: "\u2191/\u2193 Select \xB7 Enter Edit \xB7 Esc Back",
|
|
@@ -18437,7 +18550,7 @@ function createMaintenancePickers({
|
|
|
18437
18550
|
_action: "advanced"
|
|
18438
18551
|
}
|
|
18439
18552
|
];
|
|
18440
|
-
|
|
18553
|
+
paintPanel({
|
|
18441
18554
|
title: "Auto-clear",
|
|
18442
18555
|
description: `Clear idle context after ${enabled ? formatDuration2(idleMs) : "never"} \xB7 lead cache TTL ${cacheTtlLabel}.`,
|
|
18443
18556
|
help: "\u2191/\u2193 Select \xB7 \u2190/\u2192 Toggle On/Off \xB7 Enter Open/Toggle \xB7 Esc Close",
|
|
@@ -18458,22 +18571,21 @@ function createMaintenancePickers({
|
|
|
18458
18571
|
}
|
|
18459
18572
|
},
|
|
18460
18573
|
onCancel: () => {
|
|
18461
|
-
|
|
18574
|
+
own.close();
|
|
18462
18575
|
if (returnTo) returnTo();
|
|
18463
18576
|
}
|
|
18464
18577
|
});
|
|
18465
18578
|
};
|
|
18466
18579
|
setProviderPrompt(null);
|
|
18467
|
-
setChannelPrompt(null);
|
|
18468
|
-
setHookPrompt(null);
|
|
18469
18580
|
setSettingsPrompt(null);
|
|
18470
|
-
|
|
18581
|
+
own.context(null);
|
|
18471
18582
|
closeUsagePanel();
|
|
18472
18583
|
if (options.advanced === true) renderAdvanced();
|
|
18473
18584
|
else render2();
|
|
18474
18585
|
};
|
|
18475
18586
|
const openProfilePicker = async (options = {}) => {
|
|
18476
18587
|
const returnTo = typeof options.returnTo === "function" ? options.returnTo : null;
|
|
18588
|
+
const own = surface.claim();
|
|
18477
18589
|
let profile = null;
|
|
18478
18590
|
try {
|
|
18479
18591
|
profile = await store.getProfile?.() || null;
|
|
@@ -18492,36 +18604,26 @@ function createMaintenancePickers({
|
|
|
18492
18604
|
const currentExperienceLevelId = profile?.experienceLevel || "";
|
|
18493
18605
|
const currentExperienceLevel = experienceLevels.find((level) => level.id === currentExperienceLevelId) || null;
|
|
18494
18606
|
const titleValue = String(profile?.title || "").trim();
|
|
18607
|
+
const reopenProfile = () => own.defer(() => {
|
|
18608
|
+
void Promise.resolve(openProfilePicker({ returnTo })).catch((e) => store.pushNotice(`profile panel failed: ${e?.message || e}`, "error"));
|
|
18609
|
+
});
|
|
18495
18610
|
const cycleLanguage = (direction = 1) => {
|
|
18496
18611
|
const idx = Math.max(0, languages.findIndex((lang) => lang.id === currentLangId));
|
|
18497
18612
|
const next = languages[(idx + direction + languages.length) % languages.length];
|
|
18498
|
-
|
|
18499
|
-
store.setProfile?.({ language: next.id });
|
|
18500
|
-
store.pushNotice(`Language set to ${next.label}`, "info");
|
|
18501
|
-
} catch (e) {
|
|
18502
|
-
store.pushNotice(`profile update failed: ${e?.message || e}`, "error");
|
|
18503
|
-
}
|
|
18504
|
-
openProfilePicker({ returnTo });
|
|
18613
|
+
void Promise.resolve(store.setProfile?.({ language: next.id })).then(() => store.pushNotice(`Language set to ${next.label}`, "info")).catch((e) => store.pushNotice(`profile update failed: ${e?.message || e}`, "error")).finally(reopenProfile());
|
|
18505
18614
|
};
|
|
18506
18615
|
const cycleExperienceLevel = (direction = 1) => {
|
|
18507
18616
|
const idx = experienceLevels.findIndex((level) => level.id === currentExperienceLevelId);
|
|
18508
18617
|
const nextIdx = idx < 0 ? direction < 0 ? experienceLevels.length - 1 : 0 : (idx + direction + experienceLevels.length) % experienceLevels.length;
|
|
18509
18618
|
const next = experienceLevels[nextIdx];
|
|
18510
|
-
|
|
18511
|
-
store.setProfile?.({ experienceLevel: next.id });
|
|
18512
|
-
store.pushNotice(`Experience level set to ${next.label}`, "info");
|
|
18513
|
-
} catch (e) {
|
|
18514
|
-
store.pushNotice(`profile update failed: ${e?.message || e}`, "error");
|
|
18515
|
-
}
|
|
18516
|
-
openProfilePicker({ returnTo });
|
|
18619
|
+
void Promise.resolve(store.setProfile?.({ experienceLevel: next.id })).then(() => store.pushNotice(`Experience level set to ${next.label}`, "info")).catch((e) => store.pushNotice(`profile update failed: ${e?.message || e}`, "error")).finally(reopenProfile());
|
|
18517
18620
|
};
|
|
18621
|
+
if (!own.owns()) return;
|
|
18518
18622
|
setProviderPrompt(null);
|
|
18519
|
-
setChannelPrompt(null);
|
|
18520
|
-
setHookPrompt(null);
|
|
18521
18623
|
setSettingsPrompt(null);
|
|
18522
|
-
|
|
18624
|
+
own.context(null);
|
|
18523
18625
|
closeUsagePanel();
|
|
18524
|
-
|
|
18626
|
+
own.paint({
|
|
18525
18627
|
title: "Profile",
|
|
18526
18628
|
description: "How the assistant addresses you, adapts terminology, and chooses its response language.",
|
|
18527
18629
|
help: "\u2191/\u2193 Select \xB7 \u2190/\u2192 Change \xB7 Enter Edit \xB7 Esc Close",
|
|
@@ -18561,7 +18663,7 @@ function createMaintenancePickers({
|
|
|
18561
18663
|
},
|
|
18562
18664
|
onSelect: (_value, item) => {
|
|
18563
18665
|
if (item?._action === "title") {
|
|
18564
|
-
|
|
18666
|
+
own.close();
|
|
18565
18667
|
setSettingsPrompt({
|
|
18566
18668
|
kind: "profile-title",
|
|
18567
18669
|
label: "Profile \xB7 Title",
|
|
@@ -18574,7 +18676,7 @@ function createMaintenancePickers({
|
|
|
18574
18676
|
}
|
|
18575
18677
|
},
|
|
18576
18678
|
onCancel: () => {
|
|
18577
|
-
|
|
18679
|
+
own.close();
|
|
18578
18680
|
if (returnTo) returnTo();
|
|
18579
18681
|
}
|
|
18580
18682
|
});
|
|
@@ -18857,10 +18959,8 @@ var routeFromModel = (model, effort = null) => ({
|
|
|
18857
18959
|
// src/tui/app/onboarding-steps.mjs
|
|
18858
18960
|
function createOnboardingSteps({
|
|
18859
18961
|
store,
|
|
18860
|
-
|
|
18962
|
+
surface,
|
|
18861
18963
|
setProviderPrompt,
|
|
18862
|
-
setChannelPrompt,
|
|
18863
|
-
setHookPrompt,
|
|
18864
18964
|
setSettingsPrompt,
|
|
18865
18965
|
setOnboardingActive,
|
|
18866
18966
|
onboardingRef,
|
|
@@ -18899,11 +18999,13 @@ function createOnboardingSteps({
|
|
|
18899
18999
|
};
|
|
18900
19000
|
const openOnboardingAuthStep = async () => {
|
|
18901
19001
|
prefetchOnboardingStep2();
|
|
19002
|
+
const own = surface.claim();
|
|
18902
19003
|
let preloadedSetup = null;
|
|
18903
19004
|
try {
|
|
18904
19005
|
preloadedSetup = await store.getProviderSetup?.();
|
|
18905
19006
|
} catch {
|
|
18906
19007
|
}
|
|
19008
|
+
if (!own.owns()) return;
|
|
18907
19009
|
void openProviderSetupPicker({
|
|
18908
19010
|
title: "First Run \xB7 Step 1/4 \xB7 Provider Auth",
|
|
18909
19011
|
returnTo: () => openOnboardingAuthStep(),
|
|
@@ -18943,7 +19045,7 @@ function createOnboardingSteps({
|
|
|
18943
19045
|
const webSearchRoute = onboardingRef.current.webSearchRoute || null;
|
|
18944
19046
|
const overrides = onboardingRef.current.agentRoutes || {};
|
|
18945
19047
|
const hasOverrides = Object.keys(overrides).length > 0;
|
|
18946
|
-
|
|
19048
|
+
surface.claim().close();
|
|
18947
19049
|
setOnboardingActive(false);
|
|
18948
19050
|
const done = () => store.pushNotice("First-run setup complete.", "info");
|
|
18949
19051
|
const failed = (e) => store.pushNotice(`Couldn\u2019t save setup: ${e?.message || e}`, "error");
|
|
@@ -18965,6 +19067,7 @@ function createOnboardingSteps({
|
|
|
18965
19067
|
void Promise.resolve().then(() => store.skipOnboarding?.()).then(done, failed);
|
|
18966
19068
|
};
|
|
18967
19069
|
const openOnboardingRoleModelPicker = async (target) => {
|
|
19070
|
+
const own = surface.claim();
|
|
18968
19071
|
const isLead = target === "lead";
|
|
18969
19072
|
const isWebSearch = target === "webSearch";
|
|
18970
19073
|
let models;
|
|
@@ -18978,14 +19081,14 @@ function createOnboardingSteps({
|
|
|
18978
19081
|
models = normalizeModelOptions(webSearchModels || []);
|
|
18979
19082
|
if (models.length === 0) {
|
|
18980
19083
|
store.pushNotice("no native web-search models available; connect OpenAI, Grok, Gemini, or Anthropic", "warn");
|
|
18981
|
-
void openOnboardingWorkflowStep();
|
|
19084
|
+
if (own.owns()) void openOnboardingWorkflowStep();
|
|
18982
19085
|
return;
|
|
18983
19086
|
}
|
|
18984
19087
|
} else {
|
|
18985
19088
|
models = normalizeModelOptions(onboardingRef.current.providerModels || []);
|
|
18986
19089
|
if (models.length === 0) {
|
|
18987
19090
|
store.pushNotice("no provider models available; open /providers to sign in", "warn");
|
|
18988
|
-
openOnboardingAuthStep();
|
|
19091
|
+
if (own.owns()) openOnboardingAuthStep();
|
|
18989
19092
|
return;
|
|
18990
19093
|
}
|
|
18991
19094
|
}
|
|
@@ -19016,7 +19119,8 @@ function createOnboardingSteps({
|
|
|
19016
19119
|
const matchIdx = models.findIndex((m) => routeMatchesModel(currentRoute, m));
|
|
19017
19120
|
const initialIndex = isLead ? Math.max(0, matchIdx) : isUnset || matchIdx < 0 ? 0 : matchIdx + 1;
|
|
19018
19121
|
const label = isLead ? "Main" : isWebSearch ? "Web Search" : (onboardingRef.current.agents || []).find((a) => a.id === target)?.label || target;
|
|
19019
|
-
|
|
19122
|
+
if (!own.owns()) return;
|
|
19123
|
+
own.paint({
|
|
19020
19124
|
title: `First Run \xB7 ${label}`,
|
|
19021
19125
|
description: isLead ? "Pick the main model. Agents inherit this unless individually changed." : isWebSearch ? "Pick the native web-search model, or Default to follow the Main Model." : `Pick the model for ${label}, or Default to follow the Main Model.`,
|
|
19022
19126
|
initialIndex,
|
|
@@ -19057,6 +19161,7 @@ function createOnboardingSteps({
|
|
|
19057
19161
|
});
|
|
19058
19162
|
};
|
|
19059
19163
|
const openOnboardingWorkflowStep = async () => {
|
|
19164
|
+
const own = surface.claim();
|
|
19060
19165
|
if (!Array.isArray(onboardingRef.current.providerModels) || onboardingRef.current.providerModels.length === 0) {
|
|
19061
19166
|
try {
|
|
19062
19167
|
onboardingRef.current.providerModels = await store.listProviderModels();
|
|
@@ -19071,7 +19176,7 @@ function createOnboardingSteps({
|
|
|
19071
19176
|
onboardingRef.current.defaultRoute = null;
|
|
19072
19177
|
onboardingRef.current.agentRoutes = {};
|
|
19073
19178
|
store.pushNotice("no provider models available; open /providers to sign in", "warn");
|
|
19074
|
-
openOnboardingAuthStep();
|
|
19179
|
+
if (own.owns()) openOnboardingAuthStep();
|
|
19075
19180
|
return;
|
|
19076
19181
|
}
|
|
19077
19182
|
if (!Array.isArray(onboardingRef.current.agents) || onboardingRef.current.agents.length === 0) {
|
|
@@ -19086,11 +19191,10 @@ function createOnboardingSteps({
|
|
|
19086
19191
|
const webSearchRoute = onboardingRef.current.webSearchRoute || null;
|
|
19087
19192
|
const overrides = onboardingRef.current.agentRoutes || {};
|
|
19088
19193
|
const agents = onboardingRef.current.agents || [];
|
|
19194
|
+
if (!own.owns()) return;
|
|
19089
19195
|
setProviderPrompt(null);
|
|
19090
|
-
setChannelPrompt(null);
|
|
19091
|
-
setHookPrompt(null);
|
|
19092
19196
|
setSettingsPrompt(null);
|
|
19093
|
-
|
|
19197
|
+
own.paint({
|
|
19094
19198
|
title: "First Run \xB7 Step 2/4 \xB7 Models",
|
|
19095
19199
|
description: "Set the Main Model; each agent inherits it unless changed.",
|
|
19096
19200
|
indexMode: "always",
|
|
@@ -19139,7 +19243,7 @@ function createOnboardingSteps({
|
|
|
19139
19243
|
}
|
|
19140
19244
|
},
|
|
19141
19245
|
onCancel: () => {
|
|
19142
|
-
|
|
19246
|
+
own.close();
|
|
19143
19247
|
onboardingWarnReopen();
|
|
19144
19248
|
}
|
|
19145
19249
|
});
|
|
@@ -19159,12 +19263,9 @@ function createOnboardingSteps({
|
|
|
19159
19263
|
// src/tui/app/provider-setup-picker.mjs
|
|
19160
19264
|
function createProviderSetupPicker({
|
|
19161
19265
|
store,
|
|
19162
|
-
|
|
19266
|
+
surface,
|
|
19163
19267
|
setProviderPrompt,
|
|
19164
|
-
setChannelPrompt,
|
|
19165
|
-
setHookPrompt,
|
|
19166
19268
|
setSettingsPrompt,
|
|
19167
|
-
setContextPanel,
|
|
19168
19269
|
closeUsagePanel,
|
|
19169
19270
|
oauthSubmitRef,
|
|
19170
19271
|
clearModelCaches
|
|
@@ -19173,16 +19274,18 @@ function createProviderSetupPicker({
|
|
|
19173
19274
|
const returnTo = typeof options.returnTo === "function" ? options.returnTo : null;
|
|
19174
19275
|
const onContinue = typeof options.onContinue === "function" ? options.onContinue : returnTo;
|
|
19175
19276
|
const onCancel = typeof options.onCancel === "function" ? options.onCancel : null;
|
|
19277
|
+
const own = surface.claim();
|
|
19176
19278
|
setProviderPrompt(null);
|
|
19177
|
-
setChannelPrompt(null);
|
|
19178
|
-
setHookPrompt(null);
|
|
19179
19279
|
setSettingsPrompt(null);
|
|
19180
|
-
|
|
19280
|
+
own.context(null);
|
|
19181
19281
|
closeUsagePanel();
|
|
19282
|
+
const ownsSurface = () => own.owns();
|
|
19283
|
+
const paintProviders = (panel) => own.paint(panel);
|
|
19284
|
+
const releaseSurface = () => own.paint(null);
|
|
19182
19285
|
let setup = options.preloadedSetup && typeof options.preloadedSetup === "object" ? options.preloadedSetup : null;
|
|
19183
19286
|
options.preloadedSetup = null;
|
|
19184
19287
|
if (!setup) {
|
|
19185
|
-
|
|
19288
|
+
paintProviders({
|
|
19186
19289
|
title: options.title || "Providers",
|
|
19187
19290
|
description: options.description || "Choose a provider to configure.",
|
|
19188
19291
|
labelWidth: 18,
|
|
@@ -19199,7 +19302,7 @@ function createProviderSetupPicker({
|
|
|
19199
19302
|
onSelect: () => {
|
|
19200
19303
|
},
|
|
19201
19304
|
onCancel: () => {
|
|
19202
|
-
|
|
19305
|
+
own.close();
|
|
19203
19306
|
if (onCancel) onCancel();
|
|
19204
19307
|
}
|
|
19205
19308
|
});
|
|
@@ -19292,7 +19395,8 @@ function createProviderSetupPicker({
|
|
|
19292
19395
|
return idx >= 0 ? idx : 0;
|
|
19293
19396
|
};
|
|
19294
19397
|
const reopenProviders = () => {
|
|
19295
|
-
|
|
19398
|
+
if (!ownsSurface()) return;
|
|
19399
|
+
void Promise.resolve(openProviderSetupPicker(options)).catch((e) => store.pushNotice(`providers failed: ${e?.message || e}`, "error"));
|
|
19296
19400
|
};
|
|
19297
19401
|
const providerActionFooter = (provider) => provider ? [{
|
|
19298
19402
|
glyph: providerIsActive(provider) ? "\u25CF" : "\u25CB",
|
|
@@ -19300,6 +19404,7 @@ function createProviderSetupPicker({
|
|
|
19300
19404
|
text: [providerKindLabel(provider), providerStatusLabel(provider), providerDetailText(provider)].filter(Boolean).join(" \xB7 ")
|
|
19301
19405
|
}] : "";
|
|
19302
19406
|
const setApiKeyPrompt = (providerItem) => {
|
|
19407
|
+
if (!ownsSurface()) return;
|
|
19303
19408
|
setProviderPrompt({
|
|
19304
19409
|
kind: "api-key",
|
|
19305
19410
|
providerId: providerItem._providerId,
|
|
@@ -19311,6 +19416,7 @@ function createProviderSetupPicker({
|
|
|
19311
19416
|
});
|
|
19312
19417
|
};
|
|
19313
19418
|
const openApiProviderActions = (providerItem) => {
|
|
19419
|
+
if (!ownsSurface()) return;
|
|
19314
19420
|
rememberProviderSelection(providerItem);
|
|
19315
19421
|
const provider = providerItem._provider || {};
|
|
19316
19422
|
const hasAuth = providerItem._authenticated || provider.authenticated;
|
|
@@ -19338,7 +19444,7 @@ function createProviderSetupPicker({
|
|
|
19338
19444
|
_action: "usage-login-browser"
|
|
19339
19445
|
});
|
|
19340
19446
|
}
|
|
19341
|
-
|
|
19447
|
+
paintProviders({
|
|
19342
19448
|
title: `Provider \xB7 ${providerItem._providerName}`,
|
|
19343
19449
|
description: "Choose an API-key action.",
|
|
19344
19450
|
footer: () => providerActionFooter(provider),
|
|
@@ -19349,19 +19455,19 @@ function createProviderSetupPicker({
|
|
|
19349
19455
|
initialIndex: 0,
|
|
19350
19456
|
items: apiActions,
|
|
19351
19457
|
onSelect: (_detailValue, detail) => {
|
|
19352
|
-
|
|
19458
|
+
releaseSurface();
|
|
19353
19459
|
if (detail._action === "set-key") {
|
|
19354
19460
|
setApiKeyPrompt(providerItem);
|
|
19355
19461
|
return;
|
|
19356
19462
|
}
|
|
19357
19463
|
if (detail._action === "forget-key") {
|
|
19358
|
-
|
|
19359
|
-
store.forgetProviderAuth(providerItem._providerId);
|
|
19464
|
+
void Promise.resolve(store.forgetProviderAuth?.(providerItem._providerId)).then(() => {
|
|
19360
19465
|
clearModelCaches("all");
|
|
19361
19466
|
reopenProviders();
|
|
19362
|
-
}
|
|
19467
|
+
}).catch((e) => {
|
|
19363
19468
|
store.pushNotice(`auth-forget failed: ${e?.message || e}`, "error");
|
|
19364
|
-
|
|
19469
|
+
openApiProviderActions(providerItem);
|
|
19470
|
+
});
|
|
19365
19471
|
}
|
|
19366
19472
|
if (detail._action === "usage-login-browser") {
|
|
19367
19473
|
let backedOut = false;
|
|
@@ -19381,7 +19487,7 @@ function createProviderSetupPicker({
|
|
|
19381
19487
|
_action: "back"
|
|
19382
19488
|
}
|
|
19383
19489
|
];
|
|
19384
|
-
|
|
19490
|
+
paintProviders({
|
|
19385
19491
|
title: `Provider \xB7 ${providerItem._providerName}`,
|
|
19386
19492
|
description: "Opening browser. Sign in at opencode.ai/auth; the auth cookie is captured automatically.",
|
|
19387
19493
|
footer: () => providerActionFooter(provider),
|
|
@@ -19436,7 +19542,7 @@ function createProviderSetupPicker({
|
|
|
19436
19542
|
_action: "back"
|
|
19437
19543
|
}
|
|
19438
19544
|
];
|
|
19439
|
-
|
|
19545
|
+
paintProviders({
|
|
19440
19546
|
title: `Provider \xB7 ${providerItem._providerName}`,
|
|
19441
19547
|
description: message,
|
|
19442
19548
|
footer: () => providerActionFooter(provider),
|
|
@@ -19455,7 +19561,7 @@ function createProviderSetupPicker({
|
|
|
19455
19561
|
};
|
|
19456
19562
|
const showOAuthResult = (ok, message = "") => {
|
|
19457
19563
|
setProviderPrompt(null);
|
|
19458
|
-
|
|
19564
|
+
paintProviders({
|
|
19459
19565
|
title: `Provider \xB7 ${providerItem._providerName}`,
|
|
19460
19566
|
description: message || (ok ? "Login complete." : "Login did not complete."),
|
|
19461
19567
|
footer: () => providerActionFooter(provider),
|
|
@@ -19504,7 +19610,8 @@ function createProviderSetupPicker({
|
|
|
19504
19610
|
};
|
|
19505
19611
|
void store.beginOAuthProviderLogin(providerItem._providerId).then((login) => {
|
|
19506
19612
|
if (typeof login?.completeCode === "function") {
|
|
19507
|
-
|
|
19613
|
+
if (!ownsSurface()) return;
|
|
19614
|
+
releaseSurface();
|
|
19508
19615
|
const manualUrl = login?.manualUrl || "";
|
|
19509
19616
|
setProviderPrompt({
|
|
19510
19617
|
kind: "oauth-code",
|
|
@@ -19556,6 +19663,7 @@ function createProviderSetupPicker({
|
|
|
19556
19663
|
});
|
|
19557
19664
|
};
|
|
19558
19665
|
const openOAuthProviderActions = (providerItem) => {
|
|
19666
|
+
if (!ownsSurface()) return;
|
|
19559
19667
|
rememberProviderSelection(providerItem);
|
|
19560
19668
|
const provider = providerItem._provider || {};
|
|
19561
19669
|
const hasAuth = providerItem._authenticated || provider.authenticated || provider.reauthRequired === true;
|
|
@@ -19574,7 +19682,7 @@ function createProviderSetupPicker({
|
|
|
19574
19682
|
_action: "forget-oauth"
|
|
19575
19683
|
});
|
|
19576
19684
|
}
|
|
19577
|
-
|
|
19685
|
+
paintProviders({
|
|
19578
19686
|
title: `Provider \xB7 ${providerItem._providerName}`,
|
|
19579
19687
|
description: "Choose an OAuth login action.",
|
|
19580
19688
|
footer: () => providerActionFooter(provider),
|
|
@@ -19590,19 +19698,20 @@ function createProviderSetupPicker({
|
|
|
19590
19698
|
return;
|
|
19591
19699
|
}
|
|
19592
19700
|
if (detail._action === "forget-oauth") {
|
|
19593
|
-
|
|
19594
|
-
store.forgetProviderAuth(providerItem._providerId);
|
|
19701
|
+
void Promise.resolve(store.forgetProviderAuth?.(providerItem._providerId)).then(() => {
|
|
19595
19702
|
clearModelCaches("all");
|
|
19596
19703
|
reopenProviders();
|
|
19597
|
-
}
|
|
19704
|
+
}).catch((e) => {
|
|
19598
19705
|
store.pushNotice(`auth-forget failed: ${e?.message || e}`, "error");
|
|
19599
|
-
|
|
19706
|
+
openOAuthProviderActions(providerItem);
|
|
19707
|
+
});
|
|
19600
19708
|
}
|
|
19601
19709
|
},
|
|
19602
19710
|
onCancel: reopenProviders
|
|
19603
19711
|
});
|
|
19604
19712
|
};
|
|
19605
19713
|
const openLocalProviderActions = (providerItem) => {
|
|
19714
|
+
if (!ownsSurface()) return;
|
|
19606
19715
|
rememberProviderSelection(providerItem);
|
|
19607
19716
|
const provider = providerItem._provider || {};
|
|
19608
19717
|
const localActions = [
|
|
@@ -19621,7 +19730,7 @@ function createProviderSetupPicker({
|
|
|
19621
19730
|
_action: "disable-local"
|
|
19622
19731
|
});
|
|
19623
19732
|
}
|
|
19624
|
-
|
|
19733
|
+
paintProviders({
|
|
19625
19734
|
title: `Provider \xB7 ${providerItem._providerName}`,
|
|
19626
19735
|
description: "Choose a local endpoint action.",
|
|
19627
19736
|
footer: () => providerActionFooter(provider),
|
|
@@ -19632,7 +19741,7 @@ function createProviderSetupPicker({
|
|
|
19632
19741
|
initialIndex: 0,
|
|
19633
19742
|
items: localActions,
|
|
19634
19743
|
onSelect: (_detailValue, detail) => {
|
|
19635
|
-
|
|
19744
|
+
releaseSurface();
|
|
19636
19745
|
if (detail._action === "set-local-url") {
|
|
19637
19746
|
setProviderPrompt({
|
|
19638
19747
|
kind: "local-url",
|
|
@@ -19644,19 +19753,19 @@ function createProviderSetupPicker({
|
|
|
19644
19753
|
return;
|
|
19645
19754
|
}
|
|
19646
19755
|
if (detail._action === "disable-local") {
|
|
19647
|
-
|
|
19648
|
-
store.setLocalProvider(providerItem._providerId, { enabled: false, baseURL: providerItem._baseURL });
|
|
19756
|
+
void Promise.resolve(store.setLocalProvider?.(providerItem._providerId, { enabled: false, baseURL: providerItem._baseURL })).then(() => {
|
|
19649
19757
|
clearModelCaches("all");
|
|
19650
19758
|
reopenProviders();
|
|
19651
|
-
}
|
|
19759
|
+
}).catch((e) => {
|
|
19652
19760
|
store.pushNotice(`local provider update failed: ${e?.message || e}`, "error");
|
|
19653
|
-
|
|
19761
|
+
openLocalProviderActions(providerItem);
|
|
19762
|
+
});
|
|
19654
19763
|
}
|
|
19655
19764
|
},
|
|
19656
19765
|
onCancel: reopenProviders
|
|
19657
19766
|
});
|
|
19658
19767
|
};
|
|
19659
|
-
|
|
19768
|
+
paintProviders({
|
|
19660
19769
|
title: options.title || "Providers",
|
|
19661
19770
|
description: options.description || "Choose a provider. Enter opens provider actions.",
|
|
19662
19771
|
footer: providerFooter,
|
|
@@ -19673,7 +19782,7 @@ function createProviderSetupPicker({
|
|
|
19673
19782
|
if (item?._providerId) rememberProviderSelection(item);
|
|
19674
19783
|
},
|
|
19675
19784
|
onSelect: (_value, item) => {
|
|
19676
|
-
|
|
19785
|
+
releaseSurface();
|
|
19677
19786
|
if (item._type === "continue") {
|
|
19678
19787
|
onContinue?.();
|
|
19679
19788
|
return;
|
|
@@ -19691,7 +19800,7 @@ function createProviderSetupPicker({
|
|
|
19691
19800
|
}
|
|
19692
19801
|
},
|
|
19693
19802
|
onCancel: () => {
|
|
19694
|
-
|
|
19803
|
+
own.close();
|
|
19695
19804
|
if (onCancel) onCancel();
|
|
19696
19805
|
else if (returnTo) returnTo();
|
|
19697
19806
|
}
|
|
@@ -19705,10 +19814,8 @@ var MODEL_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
|
19705
19814
|
function createModelPicker({
|
|
19706
19815
|
store,
|
|
19707
19816
|
getState,
|
|
19708
|
-
|
|
19817
|
+
surface,
|
|
19709
19818
|
setProviderPrompt,
|
|
19710
|
-
setChannelPrompt,
|
|
19711
|
-
setHookPrompt,
|
|
19712
19819
|
setSettingsPrompt,
|
|
19713
19820
|
providerModelsCacheRef,
|
|
19714
19821
|
webSearchModelsCacheRef,
|
|
@@ -19720,9 +19827,8 @@ function createModelPicker({
|
|
|
19720
19827
|
let providerModelsTtlRefreshPromise = null;
|
|
19721
19828
|
const openModelPicker = async (options = {}) => {
|
|
19722
19829
|
const state = getState();
|
|
19830
|
+
const own = surface.claim();
|
|
19723
19831
|
setProviderPrompt(null);
|
|
19724
|
-
setChannelPrompt(null);
|
|
19725
|
-
setHookPrompt(null);
|
|
19726
19832
|
setSettingsPrompt(null);
|
|
19727
19833
|
modelPickerRequestRef.current += 1;
|
|
19728
19834
|
let modelPickerClosed = false;
|
|
@@ -19733,15 +19839,16 @@ function createModelPicker({
|
|
|
19733
19839
|
const cancelModelPicker = () => {
|
|
19734
19840
|
modelPickerClosed = true;
|
|
19735
19841
|
if (returnTo) returnTo();
|
|
19736
|
-
else
|
|
19842
|
+
else own.close();
|
|
19737
19843
|
};
|
|
19844
|
+
const paintModelPicker = (panel) => own.paint(panel);
|
|
19738
19845
|
const cacheRef = options.cacheRef === "webSearch" ? webSearchModelsCacheRef : providerModelsCacheRef;
|
|
19739
19846
|
const loadModels = typeof options.loadModels === "function" ? options.loadModels : store.listProviderModels;
|
|
19740
19847
|
let providerModels = Array.isArray(cacheRef.current.models) ? cacheRef.current.models : [];
|
|
19741
19848
|
let refreshModelsPromise = null;
|
|
19742
19849
|
let renderedQuickModels = false;
|
|
19743
19850
|
if (!providerModels.length || options.refreshModels === true) {
|
|
19744
|
-
|
|
19851
|
+
paintModelPicker({
|
|
19745
19852
|
title: options.title || "Model",
|
|
19746
19853
|
description: options.loadingDescription || "Loading models...",
|
|
19747
19854
|
help: returnTo ? `\u2191/\u2193 Select \xB7 Enter Open \xB7 Esc ${returnLabel}` : "\u2191/\u2193 Select \xB7 Enter Open \xB7 Esc Back",
|
|
@@ -19770,6 +19877,7 @@ function createModelPicker({
|
|
|
19770
19877
|
const cacheIsStale = providerModels.length > 0 && options.refreshModels !== true && options.cacheRef !== "webSearch" && !refreshModelsPromise && Date.now() - cacheAt > MODEL_CACHE_TTL_MS;
|
|
19771
19878
|
if (!providerModels || providerModels.length === 0) {
|
|
19772
19879
|
store.pushNotice(options.emptyNotice || "no provider models available; open /providers to sign in", "warn");
|
|
19880
|
+
if (!own.owns()) return;
|
|
19773
19881
|
void openProviderSetupPicker({
|
|
19774
19882
|
title: "Providers",
|
|
19775
19883
|
continueLabel: "Back to model setup",
|
|
@@ -20013,23 +20121,29 @@ ${model?.id || ""}`;
|
|
|
20013
20121
|
if (typeof options.onImmediateSelect === "function") {
|
|
20014
20122
|
options.onImmediateSelect(routeInput, selected, effort);
|
|
20015
20123
|
} else {
|
|
20016
|
-
|
|
20124
|
+
own.paint(null);
|
|
20017
20125
|
}
|
|
20126
|
+
const afterSelect2 = own.defer(() => {
|
|
20127
|
+
if (typeof options.onAfterSelect === "function") options.onAfterSelect();
|
|
20128
|
+
});
|
|
20018
20129
|
void savePromise.then((result) => {
|
|
20019
20130
|
if (result) clearModelCaches("all");
|
|
20020
|
-
|
|
20131
|
+
afterSelect2();
|
|
20021
20132
|
return result;
|
|
20022
20133
|
}).catch((e) => store.pushNotice(`Couldn\u2019t save model: ${e?.message || e}`, "error"));
|
|
20023
20134
|
return;
|
|
20024
20135
|
}
|
|
20025
|
-
|
|
20136
|
+
own.paint(null);
|
|
20137
|
+
const afterSelect = own.defer(() => {
|
|
20138
|
+
if (typeof options.onAfterSelect === "function") options.onAfterSelect();
|
|
20139
|
+
});
|
|
20026
20140
|
void store.setRoute(routeInput).then((ok) => {
|
|
20027
20141
|
if (ok) clearModelCaches("provider");
|
|
20028
20142
|
store.pushNotice(
|
|
20029
20143
|
ok ? modelSwitchNotice2() : "Model switch is already running",
|
|
20030
20144
|
ok ? "info" : "warn"
|
|
20031
20145
|
);
|
|
20032
|
-
if (ok
|
|
20146
|
+
if (ok) afterSelect();
|
|
20033
20147
|
}).catch((e) => store.pushNotice(`Couldn\u2019t switch model: ${e?.message || e}`, "error"));
|
|
20034
20148
|
};
|
|
20035
20149
|
const renderProviderModels = () => {
|
|
@@ -20040,7 +20154,7 @@ ${model?.id || ""}`;
|
|
|
20040
20154
|
(item) => item._provider === activeRoute?.provider && item._modelId === activeRoute?.model
|
|
20041
20155
|
)
|
|
20042
20156
|
);
|
|
20043
|
-
|
|
20157
|
+
paintModelPicker({
|
|
20044
20158
|
title: providerDisplayName(provider),
|
|
20045
20159
|
description: options.modelDescription || "Select a model. Adjust Effort with \u2190/\u2192.",
|
|
20046
20160
|
footer: (item) => modelFooter(item?._model),
|
|
@@ -20090,7 +20204,7 @@ ${model?.id || ""}`;
|
|
|
20090
20204
|
0,
|
|
20091
20205
|
providerItems.findIndex((item) => item._provider === providerHighlight)
|
|
20092
20206
|
);
|
|
20093
|
-
|
|
20207
|
+
paintModelPicker({
|
|
20094
20208
|
title: options.title || "Model",
|
|
20095
20209
|
description: options.providerDescription || "Choose a provider.",
|
|
20096
20210
|
help: returnTo ? `\u2191/\u2193 Select \xB7 Enter Open \xB7 Esc ${returnLabel}` : "\u2191/\u2193 Select \xB7 Enter Open \xB7 Esc Back",
|
|
@@ -20141,12 +20255,9 @@ var outputStyleNotice = (result) => {
|
|
|
20141
20255
|
function createRoutePickers({
|
|
20142
20256
|
store,
|
|
20143
20257
|
state,
|
|
20144
|
-
|
|
20258
|
+
surface,
|
|
20145
20259
|
setProviderPrompt,
|
|
20146
|
-
setChannelPrompt,
|
|
20147
|
-
setHookPrompt,
|
|
20148
20260
|
setSettingsPrompt,
|
|
20149
|
-
setContextPanel,
|
|
20150
20261
|
closeUsagePanel,
|
|
20151
20262
|
clean: clean2,
|
|
20152
20263
|
routeLabel: routeLabel2,
|
|
@@ -20158,7 +20269,9 @@ function createRoutePickers({
|
|
|
20158
20269
|
const openWebSearchPicker = async (options = {}) => {
|
|
20159
20270
|
const routeOverride = options.routeOverride || null;
|
|
20160
20271
|
const returnTo = typeof options.returnTo === "function" ? options.returnTo : null;
|
|
20272
|
+
const own = surface.claim();
|
|
20161
20273
|
const currentWebSearchRoute = routeOverride || await store.getWebSearchRoute?.() || null;
|
|
20274
|
+
if (!own.owns()) return;
|
|
20162
20275
|
void openModelPicker({
|
|
20163
20276
|
title: "Web Search Model",
|
|
20164
20277
|
loadingDescription: "Loading web-search-capable models...",
|
|
@@ -20173,7 +20286,7 @@ function createRoutePickers({
|
|
|
20173
20286
|
returnOnNestedCancel: options.returnOnNestedCancel === true,
|
|
20174
20287
|
onImmediateSelect: () => {
|
|
20175
20288
|
if (returnTo) returnTo();
|
|
20176
|
-
else
|
|
20289
|
+
else surface.claim().close();
|
|
20177
20290
|
},
|
|
20178
20291
|
onSelectRoute: async (routeInput) => {
|
|
20179
20292
|
const result = await store.setWebSearchRoute?.(routeInput);
|
|
@@ -20188,6 +20301,7 @@ function createRoutePickers({
|
|
|
20188
20301
|
});
|
|
20189
20302
|
};
|
|
20190
20303
|
const openAgentsPicker = async (options = {}) => {
|
|
20304
|
+
const own = surface.claim();
|
|
20191
20305
|
let agents = [];
|
|
20192
20306
|
try {
|
|
20193
20307
|
agents = await store.listAgents?.() || [];
|
|
@@ -20205,13 +20319,12 @@ function createRoutePickers({
|
|
|
20205
20319
|
description: agent.description || agent.definition?.description || "",
|
|
20206
20320
|
_agent: agent
|
|
20207
20321
|
}));
|
|
20322
|
+
if (!own.owns()) return;
|
|
20208
20323
|
setProviderPrompt(null);
|
|
20209
|
-
setChannelPrompt(null);
|
|
20210
|
-
setHookPrompt(null);
|
|
20211
20324
|
setSettingsPrompt(null);
|
|
20212
|
-
|
|
20325
|
+
own.context(null);
|
|
20213
20326
|
closeUsagePanel();
|
|
20214
|
-
|
|
20327
|
+
own.paint({
|
|
20215
20328
|
title: "Agents",
|
|
20216
20329
|
description: "Workflow agents available for agent tasks.",
|
|
20217
20330
|
help: "\u2191/\u2193 Select \xB7 Enter Set Model \xB7 Esc Back",
|
|
@@ -20241,7 +20354,7 @@ function createRoutePickers({
|
|
|
20241
20354
|
store.pushNotice(`${agent.label} model set to ${agentModelProfile2(result)}`, "info");
|
|
20242
20355
|
}
|
|
20243
20356
|
});
|
|
20244
|
-
|
|
20357
|
+
own.paint({
|
|
20245
20358
|
title: agent.label,
|
|
20246
20359
|
description: "Pick a model for this agent, or turn it off.",
|
|
20247
20360
|
help: "\u2191/\u2193 Select \xB7 Enter Choose \xB7 Esc Back",
|
|
@@ -20267,6 +20380,9 @@ function createRoutePickers({
|
|
|
20267
20380
|
openAgentModelPicker();
|
|
20268
20381
|
return;
|
|
20269
20382
|
}
|
|
20383
|
+
const reopenAgents = own.defer(() => {
|
|
20384
|
+
void openAgentsPicker();
|
|
20385
|
+
});
|
|
20270
20386
|
try {
|
|
20271
20387
|
const result = await store.setAgentRoute?.(agent.id, { disabled: true });
|
|
20272
20388
|
if (!result) {
|
|
@@ -20277,7 +20393,7 @@ function createRoutePickers({
|
|
|
20277
20393
|
} catch (e) {
|
|
20278
20394
|
store.pushNotice(`could not turn off ${agent.label}: ${e?.message || e}`, "error");
|
|
20279
20395
|
}
|
|
20280
|
-
|
|
20396
|
+
reopenAgents();
|
|
20281
20397
|
},
|
|
20282
20398
|
onCancel: () => {
|
|
20283
20399
|
void openAgentsPicker();
|
|
@@ -20285,12 +20401,13 @@ function createRoutePickers({
|
|
|
20285
20401
|
});
|
|
20286
20402
|
},
|
|
20287
20403
|
onCancel: () => {
|
|
20288
|
-
|
|
20404
|
+
own.close();
|
|
20289
20405
|
}
|
|
20290
20406
|
});
|
|
20291
20407
|
};
|
|
20292
20408
|
const openWorkflowPicker = async (options = {}) => {
|
|
20293
20409
|
const returnTo = typeof options.returnTo === "function" ? options.returnTo : null;
|
|
20410
|
+
const own = surface.claim();
|
|
20294
20411
|
let workflows = [];
|
|
20295
20412
|
try {
|
|
20296
20413
|
workflows = await store.listWorkflows?.() || [];
|
|
@@ -20310,13 +20427,12 @@ function createRoutePickers({
|
|
|
20310
20427
|
description: workflow.description || `${workflow.source || "workflow"} workflow`,
|
|
20311
20428
|
_workflow: workflow
|
|
20312
20429
|
}));
|
|
20430
|
+
if (!own.owns()) return;
|
|
20313
20431
|
setProviderPrompt(null);
|
|
20314
|
-
setChannelPrompt(null);
|
|
20315
|
-
setHookPrompt(null);
|
|
20316
20432
|
setSettingsPrompt(null);
|
|
20317
|
-
|
|
20433
|
+
own.context(null);
|
|
20318
20434
|
closeUsagePanel();
|
|
20319
|
-
|
|
20435
|
+
own.paint({
|
|
20320
20436
|
title: "Workflow",
|
|
20321
20437
|
description: "Select active workflow.",
|
|
20322
20438
|
help: returnTo ? "\u2191/\u2193 Select \xB7 Enter Choose \xB7 Esc Settings" : "\u2191/\u2193 Select \xB7 Enter Choose \xB7 Esc Back",
|
|
@@ -20325,18 +20441,21 @@ function createRoutePickers({
|
|
|
20325
20441
|
onSelect: (_value, item) => {
|
|
20326
20442
|
const workflow = item?._workflow;
|
|
20327
20443
|
if (!workflow) return;
|
|
20328
|
-
|
|
20444
|
+
own.paint(null);
|
|
20445
|
+
const returnAfterSwitch = own.defer(() => {
|
|
20446
|
+
if (returnTo) returnTo();
|
|
20447
|
+
});
|
|
20329
20448
|
void store.setWorkflow?.(workflow.id).then((result) => {
|
|
20330
20449
|
if (!result) {
|
|
20331
20450
|
store.pushNotice("Workflow switch is already running.", "warn");
|
|
20332
20451
|
return;
|
|
20333
20452
|
}
|
|
20334
20453
|
store.pushNotice(workflowSwitchNotice2(result), "info");
|
|
20335
|
-
|
|
20454
|
+
returnAfterSwitch();
|
|
20336
20455
|
}).catch((e) => store.pushNotice(`Couldn\u2019t switch workflow: ${e?.message || e}`, "error"));
|
|
20337
20456
|
},
|
|
20338
20457
|
onCancel: () => {
|
|
20339
|
-
|
|
20458
|
+
own.close();
|
|
20340
20459
|
if (returnTo) returnTo();
|
|
20341
20460
|
}
|
|
20342
20461
|
});
|
|
@@ -20344,6 +20463,7 @@ function createRoutePickers({
|
|
|
20344
20463
|
const openOutputStylePicker = async (options = {}) => {
|
|
20345
20464
|
const returnTo = typeof options.returnTo === "function" ? options.returnTo : null;
|
|
20346
20465
|
const onboarding = options.onboarding || null;
|
|
20466
|
+
const own = surface.claim();
|
|
20347
20467
|
let status = null;
|
|
20348
20468
|
try {
|
|
20349
20469
|
status = await store.listOutputStyles?.() || null;
|
|
@@ -20366,26 +20486,28 @@ function createRoutePickers({
|
|
|
20366
20486
|
description: style.description || style.source || "output style",
|
|
20367
20487
|
_style: style
|
|
20368
20488
|
}));
|
|
20489
|
+
if (!own.owns()) return;
|
|
20369
20490
|
setProviderPrompt(null);
|
|
20370
|
-
setChannelPrompt(null);
|
|
20371
|
-
setHookPrompt(null);
|
|
20372
20491
|
setSettingsPrompt(null);
|
|
20373
|
-
|
|
20492
|
+
own.context(null);
|
|
20374
20493
|
closeUsagePanel();
|
|
20375
20494
|
const saveStyle = (styleId, { advance = false } = {}) => {
|
|
20376
20495
|
if (!styleId) return;
|
|
20377
|
-
if (!(advance && onboarding))
|
|
20496
|
+
if (!(advance && onboarding)) own.paint(null);
|
|
20497
|
+
const advanceAfterSave = own.defer(() => {
|
|
20498
|
+
if (advance && onboarding) onboarding.onAdvance?.();
|
|
20499
|
+
else if (returnTo) returnTo();
|
|
20500
|
+
});
|
|
20378
20501
|
void store.setOutputStyle?.(styleId).then((result) => {
|
|
20379
20502
|
if (!result) {
|
|
20380
20503
|
store.pushNotice("Output style switch is already running.", "warn");
|
|
20381
20504
|
} else {
|
|
20382
20505
|
store.pushNotice(outputStyleNotice(result), "info");
|
|
20383
20506
|
}
|
|
20384
|
-
|
|
20385
|
-
else if (returnTo) returnTo();
|
|
20507
|
+
advanceAfterSave();
|
|
20386
20508
|
}).catch((e) => store.pushNotice(`Couldn\u2019t switch output style: ${e?.message || e}`, "error"));
|
|
20387
20509
|
};
|
|
20388
|
-
|
|
20510
|
+
own.paint({
|
|
20389
20511
|
title: "Output Style",
|
|
20390
20512
|
description: "Select response style.",
|
|
20391
20513
|
// Onboarding uses a ConfirmBar (←/→ = Back/Next); let the Picker supply
|
|
@@ -20400,7 +20522,7 @@ function createRoutePickers({
|
|
|
20400
20522
|
],
|
|
20401
20523
|
onConfirm: (button) => {
|
|
20402
20524
|
if (button.value === "back") {
|
|
20403
|
-
|
|
20525
|
+
own.close();
|
|
20404
20526
|
onboarding.onBack?.();
|
|
20405
20527
|
return;
|
|
20406
20528
|
}
|
|
@@ -20416,7 +20538,7 @@ function createRoutePickers({
|
|
|
20416
20538
|
saveStyle(style.id, { advance: Boolean(onboarding) });
|
|
20417
20539
|
},
|
|
20418
20540
|
onCancel: () => {
|
|
20419
|
-
|
|
20541
|
+
own.close();
|
|
20420
20542
|
if (onboarding) onboarding.onCancel?.();
|
|
20421
20543
|
else if (returnTo) returnTo();
|
|
20422
20544
|
}
|
|
@@ -20541,12 +20663,11 @@ async function toggleVoice({ pushNotice, setProgressHint } = {}) {
|
|
|
20541
20663
|
function createSettingsPicker({
|
|
20542
20664
|
store,
|
|
20543
20665
|
state,
|
|
20544
|
-
|
|
20666
|
+
surface,
|
|
20545
20667
|
setProviderPrompt,
|
|
20546
|
-
setChannelPrompt,
|
|
20547
|
-
setHookPrompt,
|
|
20548
20668
|
setSettingsPrompt,
|
|
20549
20669
|
settingsHeavyCacheRef,
|
|
20670
|
+
settingsRequestRef,
|
|
20550
20671
|
formatDuration: formatDuration2,
|
|
20551
20672
|
displayModelName: displayModelName3,
|
|
20552
20673
|
routeModelLabel: routeModelLabel2,
|
|
@@ -20569,7 +20690,14 @@ function createSettingsPicker({
|
|
|
20569
20690
|
openMemoryCorePicker,
|
|
20570
20691
|
openUpdatePicker
|
|
20571
20692
|
}) {
|
|
20572
|
-
const
|
|
20693
|
+
const nextSettingsRequest = () => {
|
|
20694
|
+
if (!settingsRequestRef) return 0;
|
|
20695
|
+
settingsRequestRef.current = (Number(settingsRequestRef.current) || 0) + 1;
|
|
20696
|
+
return settingsRequestRef.current;
|
|
20697
|
+
};
|
|
20698
|
+
const isCurrentSettingsRequest = (requestId) => !settingsRequestRef || settingsRequestRef.current === requestId;
|
|
20699
|
+
const buildSettingsPicker = async (opts = {}, requestId = 0) => {
|
|
20700
|
+
const own = surface.claim();
|
|
20573
20701
|
const light = opts.light === true;
|
|
20574
20702
|
const overrides = opts.overrides || null;
|
|
20575
20703
|
const heavyCache = light ? settingsHeavyCacheRef.current : null;
|
|
@@ -20593,13 +20721,12 @@ function createSettingsPicker({
|
|
|
20593
20721
|
const workflowLabel = workflowDisplayName2(workflow);
|
|
20594
20722
|
const boolLabel = (enabled) => enabled ? "On" : "Off";
|
|
20595
20723
|
const compactTypeDescription = "Uses Memory recall to rebuild context faster on large histories.";
|
|
20724
|
+
const deferredSettingsRefresh = () => own.defer(() => refreshSettings());
|
|
20596
20725
|
const applyAutoClear = (patch = {}) => {
|
|
20597
20726
|
void Promise.resolve(store.setAutoClear?.(patch)).then((next) => {
|
|
20598
20727
|
if (!next) store.pushNotice("autoclear unavailable", "warn");
|
|
20599
20728
|
else store.pushNotice(next.enabled ? `Auto-clear on \xB7 idle ${formatDuration2(next.idleMs)}` : "Auto-clear off", "info");
|
|
20600
|
-
}).catch((e) => store.pushNotice(`autoclear failed: ${e?.message || e}`, "error")).finally(()
|
|
20601
|
-
void openSettingsPicker({ light: true });
|
|
20602
|
-
});
|
|
20729
|
+
}).catch((e) => store.pushNotice(`autoclear failed: ${e?.message || e}`, "error")).finally(deferredSettingsRefresh());
|
|
20603
20730
|
};
|
|
20604
20731
|
const autoClearEnabled = autoClear.enabled !== false;
|
|
20605
20732
|
const toggleAutoClear = () => applyAutoClear({ enabled: !autoClearEnabled });
|
|
@@ -20610,22 +20737,20 @@ function createSettingsPicker({
|
|
|
20610
20737
|
return;
|
|
20611
20738
|
}
|
|
20612
20739
|
store.pushNotice(`Compaction ${next.auto !== false ? "auto on" : "auto off"} \xB7 ${next.compactType === "recall-fasttrack" ? "Fast-track" : "Default"}`, "info");
|
|
20613
|
-
}).catch((e) => store.pushNotice(`compaction failed: ${e?.message || e}`, "error")).finally(()
|
|
20740
|
+
}).catch((e) => store.pushNotice(`compaction failed: ${e?.message || e}`, "error")).finally(deferredSettingsRefresh());
|
|
20614
20741
|
};
|
|
20615
20742
|
const applyVoice = () => {
|
|
20616
20743
|
if (isVoiceInstallBusy()) {
|
|
20617
20744
|
store.pushNotice("Voice install is already running", "warn");
|
|
20618
20745
|
return;
|
|
20619
20746
|
}
|
|
20620
|
-
void Promise.resolve(toggleVoice({ pushNotice: store.pushNotice, setProgressHint: store.setProgressHint })).
|
|
20621
|
-
void openSettingsPicker({ light: true });
|
|
20622
|
-
});
|
|
20747
|
+
void Promise.resolve(toggleVoice({ pushNotice: store.pushNotice, setProgressHint: store.setProgressHint })).catch((e) => store.pushNotice(`voice setup failed: ${e?.message || e}`, "error")).finally(deferredSettingsRefresh());
|
|
20623
20748
|
};
|
|
20624
20749
|
const applyToolModule = (label, setter, enabled) => {
|
|
20625
20750
|
void Promise.resolve(setter?.(enabled)).then((next) => {
|
|
20626
20751
|
if (!next) store.pushNotice(`${label} setting is busy`, "warn");
|
|
20627
20752
|
else store.pushNotice(`${label} ${enabled ? "on" : "off"} \xB7 new sessions`, "info");
|
|
20628
|
-
}).catch((e) => store.pushNotice(`${label} setting failed: ${e?.message || e}`, "error")).finally(()
|
|
20753
|
+
}).catch((e) => store.pushNotice(`${label} setting failed: ${e?.message || e}`, "error")).finally(deferredSettingsRefresh());
|
|
20629
20754
|
};
|
|
20630
20755
|
const toggleWebSearch = () => applyToolModule("Web search", store.setWebSearchEnabled, !webSearchOn);
|
|
20631
20756
|
const toggleMemory = () => applyToolModule("Memory", store.setMemoryToolsEnabled, !memoryToolsOn);
|
|
@@ -20634,9 +20759,10 @@ function createSettingsPicker({
|
|
|
20634
20759
|
void Promise.resolve(store.setRecapEnabled?.(enabled)).then((next) => {
|
|
20635
20760
|
if (!next) store.pushNotice("Memory cycles setting is busy", "warn");
|
|
20636
20761
|
else store.pushNotice(`Memory cycles ${enabled ? "on" : "off"}`, "info");
|
|
20637
|
-
}).catch((e) => store.pushNotice(`Memory cycles setting failed: ${e?.message || e}`, "error")).finally(()
|
|
20762
|
+
}).catch((e) => store.pushNotice(`Memory cycles setting failed: ${e?.message || e}`, "error")).finally(deferredSettingsRefresh());
|
|
20638
20763
|
};
|
|
20639
20764
|
const cycleOutputStyle = async (direction = 1) => {
|
|
20765
|
+
const settled = deferredSettingsRefresh();
|
|
20640
20766
|
let status = null;
|
|
20641
20767
|
try {
|
|
20642
20768
|
status = await store.listOutputStyles?.() || null;
|
|
@@ -20658,9 +20784,10 @@ function createSettingsPicker({
|
|
|
20658
20784
|
return;
|
|
20659
20785
|
}
|
|
20660
20786
|
store.pushNotice(outputStyleNotice(result), "info");
|
|
20661
|
-
}).catch((e) => store.pushNotice(`Couldn\u2019t switch output style: ${e?.message || e}`, "error")).finally(
|
|
20787
|
+
}).catch((e) => store.pushNotice(`Couldn\u2019t switch output style: ${e?.message || e}`, "error")).finally(settled);
|
|
20662
20788
|
};
|
|
20663
20789
|
const cycleWorkflow = async (direction = 1) => {
|
|
20790
|
+
const settled = deferredSettingsRefresh();
|
|
20664
20791
|
let workflows = [];
|
|
20665
20792
|
try {
|
|
20666
20793
|
workflows = await store.listWorkflows?.() || [];
|
|
@@ -20681,7 +20808,7 @@ function createSettingsPicker({
|
|
|
20681
20808
|
return;
|
|
20682
20809
|
}
|
|
20683
20810
|
store.pushNotice(workflowSwitchNotice2(result), "info");
|
|
20684
|
-
}).catch((e) => store.pushNotice(`Couldn\u2019t switch workflow: ${e?.message || e}`, "error")).finally(
|
|
20811
|
+
}).catch((e) => store.pushNotice(`Couldn\u2019t switch workflow: ${e?.message || e}`, "error")).finally(settled);
|
|
20685
20812
|
};
|
|
20686
20813
|
const cycleTheme = (direction = 1) => {
|
|
20687
20814
|
let themes = [];
|
|
@@ -20704,7 +20831,7 @@ function createSettingsPicker({
|
|
|
20704
20831
|
} catch (e) {
|
|
20705
20832
|
store.pushNotice(`Couldn\u2019t set theme: ${e?.message || e}`, "error");
|
|
20706
20833
|
}
|
|
20707
|
-
|
|
20834
|
+
refreshSettings();
|
|
20708
20835
|
};
|
|
20709
20836
|
const items = [
|
|
20710
20837
|
{
|
|
@@ -20717,7 +20844,10 @@ function createSettingsPicker({
|
|
|
20717
20844
|
{
|
|
20718
20845
|
value: "websearch",
|
|
20719
20846
|
label: "Web search model",
|
|
20720
|
-
|
|
20847
|
+
// From the one-shot snapshot: a direct getWebSearchRoute() here is an
|
|
20848
|
+
// unresolved promise on a daemon-backed store, so the row rendered
|
|
20849
|
+
// its "(unset)" default for every configured route.
|
|
20850
|
+
meta: routeModelLabel2(snapshot.webSearchRoute || null),
|
|
20721
20851
|
description: "Native web-search model.",
|
|
20722
20852
|
_action: "websearch"
|
|
20723
20853
|
},
|
|
@@ -20868,11 +20998,11 @@ function createSettingsPicker({
|
|
|
20868
20998
|
_action: "update"
|
|
20869
20999
|
}
|
|
20870
21000
|
];
|
|
21001
|
+
if (!isCurrentSettingsRequest(requestId)) return;
|
|
21002
|
+
if (!own.owns()) return;
|
|
20871
21003
|
setProviderPrompt(null);
|
|
20872
|
-
setChannelPrompt(null);
|
|
20873
|
-
setHookPrompt(null);
|
|
20874
21004
|
setSettingsPrompt(null);
|
|
20875
|
-
|
|
21005
|
+
own.paint({
|
|
20876
21006
|
title: "Settings",
|
|
20877
21007
|
description: "Runtime, model, tools, and integrations.",
|
|
20878
21008
|
help: "\u2191/\u2193 Select \xB7 \u2190/\u2192 Change \xB7 Enter Open/Toggle \xB7 Esc Close",
|
|
@@ -20937,7 +21067,7 @@ function createSettingsPicker({
|
|
|
20937
21067
|
else if (item._action === "skills") openSkillsPicker();
|
|
20938
21068
|
else if (item._action === "memory") openMemoryCorePicker({ returnTo: openSettingsPicker });
|
|
20939
21069
|
else if (item._action === "system-shell") {
|
|
20940
|
-
|
|
21070
|
+
own.close();
|
|
20941
21071
|
setSettingsPrompt({
|
|
20942
21072
|
kind: "system-shell",
|
|
20943
21073
|
label: "System shell",
|
|
@@ -20947,10 +21077,22 @@ function createSettingsPicker({
|
|
|
20947
21077
|
} else if (item._action === "update") openUpdatePicker({ returnTo: openSettingsPicker });
|
|
20948
21078
|
},
|
|
20949
21079
|
onCancel: () => {
|
|
20950
|
-
|
|
21080
|
+
nextSettingsRequest();
|
|
21081
|
+
own.close();
|
|
20951
21082
|
}
|
|
20952
21083
|
});
|
|
20953
21084
|
};
|
|
21085
|
+
const openSettingsPicker = async (opts = {}) => {
|
|
21086
|
+
const requestId = nextSettingsRequest();
|
|
21087
|
+
try {
|
|
21088
|
+
await buildSettingsPicker(opts, requestId);
|
|
21089
|
+
} catch (error) {
|
|
21090
|
+
store.pushNotice(`settings unavailable: ${error?.message || error}`, "error");
|
|
21091
|
+
}
|
|
21092
|
+
};
|
|
21093
|
+
const refreshSettings = () => {
|
|
21094
|
+
void openSettingsPicker({ light: true });
|
|
21095
|
+
};
|
|
20954
21096
|
return { openSettingsPicker };
|
|
20955
21097
|
}
|
|
20956
21098
|
|
|
@@ -20965,7 +21107,7 @@ function createSlashDispatch({
|
|
|
20965
21107
|
state,
|
|
20966
21108
|
store,
|
|
20967
21109
|
normalizeSlashCommandName: normalizeSlashCommandName2,
|
|
20968
|
-
|
|
21110
|
+
surface,
|
|
20969
21111
|
closeUsagePanel,
|
|
20970
21112
|
openModelPicker,
|
|
20971
21113
|
modelSwitchNotice: modelSwitchNotice2,
|
|
@@ -21001,7 +21143,7 @@ function createSlashDispatch({
|
|
|
21001
21143
|
const runSlashCommand = (cmd, arg = "") => {
|
|
21002
21144
|
const rawName = String(cmd || "").toLowerCase();
|
|
21003
21145
|
cmd = normalizeSlashCommandName2(cmd);
|
|
21004
|
-
if (cmd !== "context")
|
|
21146
|
+
if (cmd !== "context") surface.claim().context(null);
|
|
21005
21147
|
if (cmd !== "usage") closeUsagePanel();
|
|
21006
21148
|
switch (cmd) {
|
|
21007
21149
|
case "clear":
|
|
@@ -21286,12 +21428,9 @@ function createSlashDispatch({
|
|
|
21286
21428
|
function createAppPickers({
|
|
21287
21429
|
state,
|
|
21288
21430
|
store,
|
|
21289
|
-
|
|
21431
|
+
surface,
|
|
21290
21432
|
setProviderPrompt,
|
|
21291
|
-
setChannelPrompt,
|
|
21292
|
-
setHookPrompt,
|
|
21293
21433
|
setSettingsPrompt,
|
|
21294
|
-
setContextPanel,
|
|
21295
21434
|
setOnboardingActive,
|
|
21296
21435
|
closeUsagePanel,
|
|
21297
21436
|
oauthSubmitRef,
|
|
@@ -21302,6 +21441,7 @@ function createAppPickers({
|
|
|
21302
21441
|
modelPickerRequestRef,
|
|
21303
21442
|
onboardingPrefetchSeqRef,
|
|
21304
21443
|
settingsHeavyCacheRef,
|
|
21444
|
+
settingsRequestRef,
|
|
21305
21445
|
livePickerRef,
|
|
21306
21446
|
disabledSkills,
|
|
21307
21447
|
setDisabledSkills,
|
|
@@ -21314,24 +21454,21 @@ function createAppPickers({
|
|
|
21314
21454
|
const { openThemePicker, openEffortPicker } = createThemeEffortPickers({
|
|
21315
21455
|
state,
|
|
21316
21456
|
store,
|
|
21317
|
-
|
|
21457
|
+
surface,
|
|
21318
21458
|
setProviderPrompt,
|
|
21319
|
-
setChannelPrompt,
|
|
21320
|
-
setHookPrompt,
|
|
21321
21459
|
setSettingsPrompt,
|
|
21322
|
-
setContextPanel,
|
|
21323
21460
|
closeUsagePanel,
|
|
21324
21461
|
clean
|
|
21325
21462
|
});
|
|
21326
21463
|
const { openResumePicker } = createResumePicker({
|
|
21327
21464
|
store,
|
|
21328
|
-
|
|
21465
|
+
surface,
|
|
21329
21466
|
formatSessionUpdatedAt,
|
|
21330
21467
|
formatSessionMessageCount
|
|
21331
21468
|
});
|
|
21332
21469
|
const { openMemoryCorePicker } = createCoreMemoryPicker({
|
|
21333
21470
|
store,
|
|
21334
|
-
|
|
21471
|
+
surface,
|
|
21335
21472
|
setSettingsPrompt,
|
|
21336
21473
|
parseMemoryCoreRows
|
|
21337
21474
|
});
|
|
@@ -21351,11 +21488,9 @@ function createAppPickers({
|
|
|
21351
21488
|
theme,
|
|
21352
21489
|
clean,
|
|
21353
21490
|
copyToClipboard,
|
|
21354
|
-
|
|
21491
|
+
surface,
|
|
21355
21492
|
getPicker: () => livePickerRef.current,
|
|
21356
21493
|
setProviderPrompt,
|
|
21357
|
-
setChannelPrompt,
|
|
21358
|
-
setHookPrompt,
|
|
21359
21494
|
setSettingsPrompt,
|
|
21360
21495
|
getDisabledSkills: () => disabledSkills,
|
|
21361
21496
|
setDisabledSkills
|
|
@@ -21368,20 +21503,15 @@ function createAppPickers({
|
|
|
21368
21503
|
store,
|
|
21369
21504
|
theme,
|
|
21370
21505
|
formatDuration,
|
|
21371
|
-
|
|
21506
|
+
surface,
|
|
21372
21507
|
setProviderPrompt,
|
|
21373
|
-
setChannelPrompt,
|
|
21374
|
-
setHookPrompt,
|
|
21375
21508
|
setSettingsPrompt,
|
|
21376
|
-
setContextPanel,
|
|
21377
21509
|
closeUsagePanel
|
|
21378
21510
|
});
|
|
21379
21511
|
const { onboardingWarnReopen, openOnboardingAuthStep } = createOnboardingSteps({
|
|
21380
21512
|
store,
|
|
21381
|
-
|
|
21513
|
+
surface,
|
|
21382
21514
|
setProviderPrompt,
|
|
21383
|
-
setChannelPrompt,
|
|
21384
|
-
setHookPrompt,
|
|
21385
21515
|
setSettingsPrompt,
|
|
21386
21516
|
setOnboardingActive,
|
|
21387
21517
|
onboardingRef,
|
|
@@ -21393,12 +21523,9 @@ function createAppPickers({
|
|
|
21393
21523
|
});
|
|
21394
21524
|
const { openProviderSetupPicker } = createProviderSetupPicker({
|
|
21395
21525
|
store,
|
|
21396
|
-
|
|
21526
|
+
surface,
|
|
21397
21527
|
setProviderPrompt,
|
|
21398
|
-
setChannelPrompt,
|
|
21399
|
-
setHookPrompt,
|
|
21400
21528
|
setSettingsPrompt,
|
|
21401
|
-
setContextPanel,
|
|
21402
21529
|
closeUsagePanel,
|
|
21403
21530
|
oauthSubmitRef,
|
|
21404
21531
|
clearModelCaches
|
|
@@ -21406,10 +21533,8 @@ function createAppPickers({
|
|
|
21406
21533
|
const { openModelPicker } = createModelPicker({
|
|
21407
21534
|
store,
|
|
21408
21535
|
getState: () => state,
|
|
21409
|
-
|
|
21536
|
+
surface,
|
|
21410
21537
|
setProviderPrompt,
|
|
21411
|
-
setChannelPrompt,
|
|
21412
|
-
setHookPrompt,
|
|
21413
21538
|
setSettingsPrompt,
|
|
21414
21539
|
providerModelsCacheRef,
|
|
21415
21540
|
webSearchModelsCacheRef,
|
|
@@ -21426,12 +21551,9 @@ function createAppPickers({
|
|
|
21426
21551
|
} = createRoutePickers({
|
|
21427
21552
|
store,
|
|
21428
21553
|
state,
|
|
21429
|
-
|
|
21554
|
+
surface,
|
|
21430
21555
|
setProviderPrompt,
|
|
21431
|
-
setChannelPrompt,
|
|
21432
|
-
setHookPrompt,
|
|
21433
21556
|
setSettingsPrompt,
|
|
21434
|
-
setContextPanel,
|
|
21435
21557
|
closeUsagePanel,
|
|
21436
21558
|
clean,
|
|
21437
21559
|
routeLabel,
|
|
@@ -21443,12 +21565,11 @@ function createAppPickers({
|
|
|
21443
21565
|
const { openSettingsPicker } = createSettingsPicker({
|
|
21444
21566
|
store,
|
|
21445
21567
|
state,
|
|
21446
|
-
|
|
21568
|
+
surface,
|
|
21447
21569
|
setProviderPrompt,
|
|
21448
|
-
setChannelPrompt,
|
|
21449
|
-
setHookPrompt,
|
|
21450
21570
|
setSettingsPrompt,
|
|
21451
21571
|
settingsHeavyCacheRef,
|
|
21572
|
+
settingsRequestRef,
|
|
21452
21573
|
formatDuration,
|
|
21453
21574
|
displayModelName,
|
|
21454
21575
|
routeModelLabel,
|
|
@@ -21475,7 +21596,7 @@ function createAppPickers({
|
|
|
21475
21596
|
state,
|
|
21476
21597
|
store,
|
|
21477
21598
|
normalizeSlashCommandName,
|
|
21478
|
-
|
|
21599
|
+
surface,
|
|
21479
21600
|
closeUsagePanel,
|
|
21480
21601
|
openModelPicker: (...a) => openModelPicker(...a),
|
|
21481
21602
|
modelSwitchNotice,
|
|
@@ -21712,7 +21833,7 @@ function messageSelectorLabel(text, width = 56) {
|
|
|
21712
21833
|
function useMessageSelector({
|
|
21713
21834
|
store,
|
|
21714
21835
|
state,
|
|
21715
|
-
|
|
21836
|
+
surface,
|
|
21716
21837
|
setPromptDraftOverride,
|
|
21717
21838
|
syncPromptLayoutRows,
|
|
21718
21839
|
showPromptHint,
|
|
@@ -21742,14 +21863,15 @@ function useMessageSelector({
|
|
|
21742
21863
|
showPromptHint("No message to jump back to.", "info");
|
|
21743
21864
|
return false;
|
|
21744
21865
|
}
|
|
21745
|
-
|
|
21866
|
+
const own = surface.claim();
|
|
21867
|
+
own.paint({
|
|
21746
21868
|
_kind: "message-selector",
|
|
21747
21869
|
title: "Jump back to a message",
|
|
21748
21870
|
description: "Rewind the conversation to a previous prompt and edit it.",
|
|
21749
21871
|
initialIndex: rows.length - 1,
|
|
21750
21872
|
items: rows.map((row) => ({ value: row.id, label: messageSelectorLabel(row.text) })),
|
|
21751
21873
|
onSelect: (value) => {
|
|
21752
|
-
|
|
21874
|
+
own.close();
|
|
21753
21875
|
let restored;
|
|
21754
21876
|
try {
|
|
21755
21877
|
restored = store.rewindToItem?.(value);
|
|
@@ -21763,10 +21885,10 @@ function useMessageSelector({
|
|
|
21763
21885
|
}
|
|
21764
21886
|
applyRewind(restored);
|
|
21765
21887
|
},
|
|
21766
|
-
onCancel: () =>
|
|
21888
|
+
onCancel: () => own.close()
|
|
21767
21889
|
});
|
|
21768
21890
|
return true;
|
|
21769
|
-
}, [store, state.items,
|
|
21891
|
+
}, [store, state.items, surface, applyRewind, showPromptHint]);
|
|
21770
21892
|
return { hasUserMessages, openMessageSelector };
|
|
21771
21893
|
}
|
|
21772
21894
|
|
|
@@ -22367,12 +22489,9 @@ function useTranscriptWindow({
|
|
|
22367
22489
|
function createProjectPicker({
|
|
22368
22490
|
state,
|
|
22369
22491
|
store,
|
|
22370
|
-
|
|
22492
|
+
surface,
|
|
22371
22493
|
setProviderPrompt,
|
|
22372
|
-
setChannelPrompt,
|
|
22373
|
-
setHookPrompt,
|
|
22374
22494
|
setSettingsPrompt,
|
|
22375
|
-
setContextPanel,
|
|
22376
22495
|
closeUsagePanel,
|
|
22377
22496
|
projectNameFromPath: projectNameFromPath3,
|
|
22378
22497
|
pickFolder: pickFolder2
|
|
@@ -22443,16 +22562,15 @@ function createProjectPicker({
|
|
|
22443
22562
|
}
|
|
22444
22563
|
},
|
|
22445
22564
|
onCancel: () => {
|
|
22446
|
-
|
|
22565
|
+
surface.claim().close();
|
|
22447
22566
|
}
|
|
22448
22567
|
};
|
|
22449
22568
|
};
|
|
22450
22569
|
const beginNewProjectManual = () => {
|
|
22451
|
-
|
|
22570
|
+
const own = surface.claim();
|
|
22571
|
+
own.context(null);
|
|
22572
|
+
own.close();
|
|
22452
22573
|
setProviderPrompt(null);
|
|
22453
|
-
setChannelPrompt(null);
|
|
22454
|
-
setHookPrompt(null);
|
|
22455
|
-
setContextPanel(null);
|
|
22456
22574
|
closeUsagePanel();
|
|
22457
22575
|
setSettingsPrompt({
|
|
22458
22576
|
kind: "project-new",
|
|
@@ -22461,12 +22579,11 @@ function createProjectPicker({
|
|
|
22461
22579
|
});
|
|
22462
22580
|
};
|
|
22463
22581
|
const beginNewProject = () => {
|
|
22582
|
+
const own = surface.claim();
|
|
22464
22583
|
setProviderPrompt(null);
|
|
22465
|
-
|
|
22466
|
-
setHookPrompt(null);
|
|
22467
|
-
setContextPanel(null);
|
|
22584
|
+
own.context(null);
|
|
22468
22585
|
closeUsagePanel();
|
|
22469
|
-
|
|
22586
|
+
own.paint({
|
|
22470
22587
|
kind: "project",
|
|
22471
22588
|
title: "Project",
|
|
22472
22589
|
description: "Opening folder picker\u2026 choose a folder in the dialog window.",
|
|
@@ -22482,6 +22599,7 @@ function createProjectPicker({
|
|
|
22482
22599
|
title: "Select a project folder",
|
|
22483
22600
|
initialPath: String(state.cwd || process.cwd() || "")
|
|
22484
22601
|
}).then((result) => {
|
|
22602
|
+
if (!own.owns()) return;
|
|
22485
22603
|
if (!result || result.available === false) {
|
|
22486
22604
|
beginNewProjectManual();
|
|
22487
22605
|
return;
|
|
@@ -22492,7 +22610,7 @@ function createProjectPicker({
|
|
|
22492
22610
|
}
|
|
22493
22611
|
void registerProject(result.path);
|
|
22494
22612
|
}).catch(() => {
|
|
22495
|
-
beginNewProjectManual();
|
|
22613
|
+
if (own.owns()) beginNewProjectManual();
|
|
22496
22614
|
});
|
|
22497
22615
|
};
|
|
22498
22616
|
const registerProject = async (rawPath) => {
|
|
@@ -22501,9 +22619,11 @@ function createProjectPicker({
|
|
|
22501
22619
|
store.pushNotice("project path is required", "warn");
|
|
22502
22620
|
return false;
|
|
22503
22621
|
}
|
|
22622
|
+
const own = surface.claim();
|
|
22504
22623
|
try {
|
|
22505
22624
|
const project = await serviceCall("addProject", path2);
|
|
22506
22625
|
if (project?.name) store.pushNotice(`project added: ${project.name}`, "info");
|
|
22626
|
+
if (!own.owns()) return true;
|
|
22507
22627
|
await openProjectPicker();
|
|
22508
22628
|
return true;
|
|
22509
22629
|
} catch (e) {
|
|
@@ -22517,7 +22637,7 @@ function createProjectPicker({
|
|
|
22517
22637
|
store.pushNotice("project path is required", "warn");
|
|
22518
22638
|
return false;
|
|
22519
22639
|
}
|
|
22520
|
-
|
|
22640
|
+
surface.claim().close();
|
|
22521
22641
|
try {
|
|
22522
22642
|
const resolved = await serviceCall("setCwd", path2, {
|
|
22523
22643
|
notice: options?.notice !== false,
|
|
@@ -22532,11 +22652,10 @@ function createProjectPicker({
|
|
|
22532
22652
|
};
|
|
22533
22653
|
const beginRenameProject = (project) => {
|
|
22534
22654
|
if (!project?.path) return;
|
|
22535
|
-
|
|
22655
|
+
const own = surface.claim();
|
|
22656
|
+
own.context(null);
|
|
22657
|
+
own.close();
|
|
22536
22658
|
setProviderPrompt(null);
|
|
22537
|
-
setChannelPrompt(null);
|
|
22538
|
-
setHookPrompt(null);
|
|
22539
|
-
setContextPanel(null);
|
|
22540
22659
|
closeUsagePanel();
|
|
22541
22660
|
setSettingsPrompt({
|
|
22542
22661
|
kind: "project-rename",
|
|
@@ -22547,28 +22666,27 @@ function createProjectPicker({
|
|
|
22547
22666
|
});
|
|
22548
22667
|
};
|
|
22549
22668
|
const openProjectPicker = async ({ initialEntry = false } = {}) => {
|
|
22669
|
+
const own = surface.claim();
|
|
22550
22670
|
setProviderPrompt(null);
|
|
22551
|
-
setChannelPrompt(null);
|
|
22552
|
-
setHookPrompt(null);
|
|
22553
22671
|
setSettingsPrompt(null);
|
|
22554
|
-
|
|
22672
|
+
own.context(null);
|
|
22555
22673
|
closeUsagePanel();
|
|
22556
22674
|
const requestId = /* @__PURE__ */ Symbol("project-picker-request");
|
|
22557
|
-
|
|
22675
|
+
own.paint(buildProjectPickerState({
|
|
22558
22676
|
initialEntry,
|
|
22559
22677
|
loading: true,
|
|
22560
22678
|
requestId
|
|
22561
22679
|
}));
|
|
22562
22680
|
try {
|
|
22563
22681
|
const projects = await serviceCall("listProjects");
|
|
22564
|
-
|
|
22682
|
+
own.paint((current) => current?._projectRequestId === requestId ? buildProjectPickerState({
|
|
22565
22683
|
initialEntry,
|
|
22566
22684
|
projects: Array.isArray(projects) ? projects : [],
|
|
22567
22685
|
requestId
|
|
22568
22686
|
}) : current);
|
|
22569
22687
|
return projects;
|
|
22570
22688
|
} catch (error) {
|
|
22571
|
-
|
|
22689
|
+
own.paint((current) => current?._projectRequestId === requestId ? buildProjectPickerState({ initialEntry, projects: [], requestId }) : current);
|
|
22572
22690
|
store.pushNotice(`project list failed: ${error?.message || error}`, "error");
|
|
22573
22691
|
return [];
|
|
22574
22692
|
}
|
|
@@ -22681,7 +22799,7 @@ function usePromptHandlers({
|
|
|
22681
22799
|
setPastedImages,
|
|
22682
22800
|
setPastedTexts,
|
|
22683
22801
|
setPromptDraftOverride,
|
|
22684
|
-
|
|
22802
|
+
surface,
|
|
22685
22803
|
// derived / helper values + callbacks
|
|
22686
22804
|
syncPromptLayoutRows,
|
|
22687
22805
|
showPromptHint,
|
|
@@ -22822,7 +22940,7 @@ function usePromptHandlers({
|
|
|
22822
22940
|
return true;
|
|
22823
22941
|
}
|
|
22824
22942
|
if (contextPanel) {
|
|
22825
|
-
|
|
22943
|
+
surface.claim().context(null);
|
|
22826
22944
|
return true;
|
|
22827
22945
|
}
|
|
22828
22946
|
if (meta.phase === "clear-arm") {
|
|
@@ -22996,7 +23114,9 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
22996
23114
|
const [picker, setPickerState] = useState11(null);
|
|
22997
23115
|
const livePickerRef = useRef15(null);
|
|
22998
23116
|
const setPicker = useCallback13((next) => {
|
|
22999
|
-
|
|
23117
|
+
const previousPicker = livePickerRef.current;
|
|
23118
|
+
livePickerRef.current = typeof next === "function" ? next(previousPicker) : next;
|
|
23119
|
+
if (shouldSupersedePanelEpoch(previousPicker, livePickerRef.current)) supersedePanelEpoch();
|
|
23000
23120
|
setPickerState((prev) => {
|
|
23001
23121
|
const resolved = typeof next === "function" ? next(prev) : next;
|
|
23002
23122
|
if (resolved && typeof resolved === "object" && pickerOpenedFromEnterRef.current) {
|
|
@@ -23016,26 +23136,23 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23016
23136
|
livePickerRef.current = picker;
|
|
23017
23137
|
const [contextPanel, setContextPanel] = useState11(null);
|
|
23018
23138
|
const [usagePanel, setUsagePanel] = useState11(null);
|
|
23019
|
-
const
|
|
23139
|
+
const surfaceRef = useRef15(null);
|
|
23140
|
+
if (!surfaceRef.current) {
|
|
23141
|
+
surfaceRef.current = createPanelSurface({ setPicker, setContextPanel, setUsagePanel });
|
|
23142
|
+
}
|
|
23143
|
+
const surface = surfaceRef.current;
|
|
23020
23144
|
const settingsHeavyCacheRef = useRef15(null);
|
|
23021
|
-
const
|
|
23022
|
-
|
|
23023
|
-
setUsagePanel(null);
|
|
23024
|
-
}, []);
|
|
23145
|
+
const settingsRequestRef = useRef15(0);
|
|
23146
|
+
const closeUsagePanel = useCallback13(() => surface.closeUsage(), [surface]);
|
|
23025
23147
|
const [providerPrompt, setProviderPrompt] = useState11(null);
|
|
23026
23148
|
const oauthSubmitRef = useRef15(false);
|
|
23027
|
-
const [channelPrompt, setChannelPrompt] = useState11(null);
|
|
23028
|
-
const [hookPrompt, setHookPrompt] = useState11(null);
|
|
23029
23149
|
const [settingsPrompt, setSettingsPrompt] = useState11(null);
|
|
23030
23150
|
const projectPicker = createProjectPicker({
|
|
23031
23151
|
state,
|
|
23032
23152
|
store,
|
|
23033
|
-
|
|
23153
|
+
surface,
|
|
23034
23154
|
setProviderPrompt,
|
|
23035
|
-
setChannelPrompt,
|
|
23036
|
-
setHookPrompt,
|
|
23037
23155
|
setSettingsPrompt,
|
|
23038
|
-
setContextPanel,
|
|
23039
23156
|
closeUsagePanel,
|
|
23040
23157
|
projectNameFromPath,
|
|
23041
23158
|
pickFolder
|
|
@@ -23206,12 +23323,9 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23206
23323
|
} = createAppPickers({
|
|
23207
23324
|
state,
|
|
23208
23325
|
store,
|
|
23209
|
-
|
|
23326
|
+
surface,
|
|
23210
23327
|
setProviderPrompt,
|
|
23211
|
-
setChannelPrompt,
|
|
23212
|
-
setHookPrompt,
|
|
23213
23328
|
setSettingsPrompt,
|
|
23214
|
-
setContextPanel,
|
|
23215
23329
|
setOnboardingActive,
|
|
23216
23330
|
closeUsagePanel,
|
|
23217
23331
|
oauthSubmitRef,
|
|
@@ -23222,6 +23336,7 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23222
23336
|
modelPickerRequestRef,
|
|
23223
23337
|
onboardingPrefetchSeqRef,
|
|
23224
23338
|
settingsHeavyCacheRef,
|
|
23339
|
+
settingsRequestRef,
|
|
23225
23340
|
livePickerRef,
|
|
23226
23341
|
disabledSkills,
|
|
23227
23342
|
setDisabledSkills,
|
|
@@ -23373,7 +23488,7 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23373
23488
|
const { hasUserMessages, openMessageSelector } = useMessageSelector({
|
|
23374
23489
|
store,
|
|
23375
23490
|
state,
|
|
23376
|
-
|
|
23491
|
+
surface,
|
|
23377
23492
|
setPromptDraftOverride,
|
|
23378
23493
|
syncPromptLayoutRows,
|
|
23379
23494
|
showPromptHint,
|
|
@@ -23397,7 +23512,7 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23397
23512
|
setPastedImages,
|
|
23398
23513
|
setPastedTexts,
|
|
23399
23514
|
setPromptDraftOverride,
|
|
23400
|
-
|
|
23515
|
+
surface,
|
|
23401
23516
|
syncPromptLayoutRows,
|
|
23402
23517
|
showPromptHint,
|
|
23403
23518
|
clearPromptHint,
|
|
@@ -23425,7 +23540,7 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23425
23540
|
picker,
|
|
23426
23541
|
usagePanel,
|
|
23427
23542
|
contextPanel,
|
|
23428
|
-
|
|
23543
|
+
surface,
|
|
23429
23544
|
closeUsagePanel,
|
|
23430
23545
|
isRawModeSupported,
|
|
23431
23546
|
resizeState,
|
|
@@ -23445,14 +23560,9 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23445
23560
|
const { openUsagePanel, openContextPicker } = createUsageContextPanels({
|
|
23446
23561
|
store,
|
|
23447
23562
|
state,
|
|
23448
|
-
|
|
23449
|
-
setPicker,
|
|
23563
|
+
surface,
|
|
23450
23564
|
setProviderPrompt,
|
|
23451
|
-
setChannelPrompt,
|
|
23452
|
-
setHookPrompt,
|
|
23453
23565
|
setSettingsPrompt,
|
|
23454
|
-
setContextPanel,
|
|
23455
|
-
setUsagePanel,
|
|
23456
23566
|
closeUsagePanel
|
|
23457
23567
|
});
|
|
23458
23568
|
useEffect14(() => {
|
|
@@ -23493,17 +23603,12 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23493
23603
|
store,
|
|
23494
23604
|
state,
|
|
23495
23605
|
providerPrompt,
|
|
23496
|
-
channelPrompt,
|
|
23497
|
-
hookPrompt,
|
|
23498
23606
|
settingsPrompt,
|
|
23499
23607
|
setProviderPrompt,
|
|
23500
|
-
setChannelPrompt,
|
|
23501
|
-
setHookPrompt,
|
|
23502
23608
|
setSettingsPrompt,
|
|
23503
23609
|
oauthSubmitRef,
|
|
23504
23610
|
clearModelCaches,
|
|
23505
23611
|
openProviderSetupPicker,
|
|
23506
|
-
openHooksPicker,
|
|
23507
23612
|
openSettingsPicker,
|
|
23508
23613
|
openProjectPicker,
|
|
23509
23614
|
openAutoClearPicker,
|
|
@@ -23520,7 +23625,7 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23520
23625
|
pastedImagesRef,
|
|
23521
23626
|
pastedTextsRef
|
|
23522
23627
|
});
|
|
23523
|
-
const activeSlashQuery = providerPrompt ||
|
|
23628
|
+
const activeSlashQuery = providerPrompt || settingsPrompt || toolApproval || contextPanel || usagePanel ? null : slashQuery(promptDraft);
|
|
23524
23629
|
const slashModeLive = activeSlashQuery !== null && !picker && !toolApproval && !contextPanel && !usagePanel && !exiting && !state.commandBusy;
|
|
23525
23630
|
const slashCommands = !slashModeLive ? [] : SLASH_COMMANDS.filter((command) => slashCommandMatches(command, activeSlashQuery)).sort(compareSlashCommands);
|
|
23526
23631
|
const slashPaletteOpen = slashModeLive && slashDismissedFor !== promptDraft;
|
|
@@ -23532,8 +23637,6 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23532
23637
|
contextPanel: !!contextPanel,
|
|
23533
23638
|
usagePanel: !!usagePanel,
|
|
23534
23639
|
providerPrompt: !!providerPrompt,
|
|
23535
|
-
channelPrompt: !!channelPrompt,
|
|
23536
|
-
hookPrompt: !!hookPrompt,
|
|
23537
23640
|
settingsPrompt: !!settingsPrompt
|
|
23538
23641
|
};
|
|
23539
23642
|
useEffect14(() => {
|
|
@@ -23542,8 +23645,6 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23542
23645
|
const {
|
|
23543
23646
|
onPromptDraftChange,
|
|
23544
23647
|
cancelProviderPrompt,
|
|
23545
|
-
cancelChannelPrompt,
|
|
23546
|
-
cancelHookPrompt,
|
|
23547
23648
|
cancelSettingsPrompt,
|
|
23548
23649
|
acceptSlashPalette,
|
|
23549
23650
|
completeSlashPalette,
|
|
@@ -23563,12 +23664,8 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23563
23664
|
slashDismissedFor,
|
|
23564
23665
|
setSlashDismissedFor,
|
|
23565
23666
|
providerPrompt,
|
|
23566
|
-
channelPrompt,
|
|
23567
|
-
hookPrompt,
|
|
23568
23667
|
settingsPrompt,
|
|
23569
23668
|
setProviderPrompt,
|
|
23570
|
-
setChannelPrompt,
|
|
23571
|
-
setHookPrompt,
|
|
23572
23669
|
setSettingsPrompt,
|
|
23573
23670
|
oauthSubmitRef,
|
|
23574
23671
|
openProjectPicker,
|
|
@@ -23584,8 +23681,6 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23584
23681
|
const { agentRevision, activeToolsSignature, activeTools, statuslineStats } = useTranscriptActivity({ state });
|
|
23585
23682
|
const layout = computeShellLayout({
|
|
23586
23683
|
providerPrompt,
|
|
23587
|
-
channelPrompt,
|
|
23588
|
-
hookPrompt,
|
|
23589
23684
|
settingsPrompt,
|
|
23590
23685
|
panelTransitionEpoch,
|
|
23591
23686
|
panelInkMaskEpoch,
|
|
@@ -23701,7 +23796,7 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23701
23796
|
setMeasuredRowsVersion
|
|
23702
23797
|
});
|
|
23703
23798
|
const cycleWorkflowFromPrompt = useCallback13(() => {
|
|
23704
|
-
if (slashPaletteOpen || toolApproval || picker || settingsPrompt || providerPrompt ||
|
|
23799
|
+
if (slashPaletteOpen || toolApproval || picker || settingsPrompt || providerPrompt || contextPanel || usagePanel) return true;
|
|
23705
23800
|
const repeatGuardMs = 300;
|
|
23706
23801
|
const cycleGuard = workflowTabCycleRef.current;
|
|
23707
23802
|
const now = Date.now();
|
|
@@ -23736,19 +23831,16 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23736
23831
|
cycleGuard.lastAt = Date.now();
|
|
23737
23832
|
});
|
|
23738
23833
|
return true;
|
|
23739
|
-
}, [slashPaletteOpen, toolApproval, picker, settingsPrompt, providerPrompt,
|
|
23834
|
+
}, [slashPaletteOpen, toolApproval, picker, settingsPrompt, providerPrompt, contextPanel, usagePanel, state.commandBusy, state.workflow, store]);
|
|
23740
23835
|
return renderAppView({
|
|
23741
23836
|
...layout,
|
|
23742
23837
|
acceptSlashPalette,
|
|
23743
23838
|
activeSlashQuery,
|
|
23744
23839
|
activeTools,
|
|
23745
23840
|
agentRevision,
|
|
23746
|
-
cancelChannelPrompt,
|
|
23747
|
-
cancelHookPrompt,
|
|
23748
23841
|
cancelProviderPrompt,
|
|
23749
23842
|
cancelSettingsPrompt,
|
|
23750
23843
|
cancelSlashPalette,
|
|
23751
|
-
channelPrompt,
|
|
23752
23844
|
clearPromptHint,
|
|
23753
23845
|
completeSlashPalette,
|
|
23754
23846
|
contextPanel,
|
|
@@ -23761,7 +23853,6 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23761
23853
|
handlePromptInterrupt,
|
|
23762
23854
|
handlePromptPaste,
|
|
23763
23855
|
hasUserMessages,
|
|
23764
|
-
hookPrompt,
|
|
23765
23856
|
initialStatusLine,
|
|
23766
23857
|
onPromptDraftChange,
|
|
23767
23858
|
onSubmit,
|
|
@@ -23784,7 +23875,6 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23784
23875
|
resizeEpoch,
|
|
23785
23876
|
resizeState,
|
|
23786
23877
|
restoreQueuedToPrompt,
|
|
23787
|
-
setPicker,
|
|
23788
23878
|
setSlashIndex,
|
|
23789
23879
|
setTextEntryLayoutRows,
|
|
23790
23880
|
settingsPrompt,
|
|
@@ -23794,6 +23884,7 @@ function App({ store, initialStatusLine = "", forceOnboarding = false, onboardin
|
|
|
23794
23884
|
state,
|
|
23795
23885
|
statuslineStats,
|
|
23796
23886
|
store,
|
|
23887
|
+
surface,
|
|
23797
23888
|
toolApproval,
|
|
23798
23889
|
toolOutputExpanded,
|
|
23799
23890
|
transcriptMeasureRef,
|