@pellux/goodvibes-agent 1.1.4 → 1.1.6
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/CHANGELOG.md +12 -0
- package/dist/package/main.js +1321 -825
- package/package.json +1 -1
- package/src/input/agent-workspace-activation.ts +10 -0
- package/src/input/agent-workspace-basic-command-editors.ts +8 -9
- package/src/input/agent-workspace-categories.ts +109 -117
- package/src/input/agent-workspace-host-category.ts +57 -0
- package/src/input/agent-workspace-local-editor-submission.ts +193 -0
- package/src/input/agent-workspace-search.ts +6 -0
- package/src/input/agent-workspace-settings.ts +94 -8
- package/src/input/agent-workspace-setup.ts +20 -0
- package/src/input/agent-workspace-snapshot.ts +89 -0
- package/src/input/agent-workspace-subscription-editor.ts +214 -0
- package/src/input/agent-workspace-types.ts +44 -2
- package/src/input/agent-workspace.ts +73 -133
- package/src/input/handler-modal-token-routes.ts +12 -12
- package/src/input/handler.ts +2 -1
- package/src/main.ts +11 -7
- package/src/renderer/agent-workspace.ts +68 -3
- package/src/shell/agent-workspace-fullscreen.ts +11 -3
- package/src/version.ts +1 -1
package/dist/package/main.js
CHANGED
|
@@ -817092,7 +817092,7 @@ var createStyledCell = (char, overrides = {}) => ({
|
|
|
817092
817092
|
// src/version.ts
|
|
817093
817093
|
import { readFileSync } from "fs";
|
|
817094
817094
|
import { join } from "path";
|
|
817095
|
-
var _version = "1.1.
|
|
817095
|
+
var _version = "1.1.6";
|
|
817096
817096
|
try {
|
|
817097
817097
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, "..", "package.json"), "utf-8"));
|
|
817098
817098
|
_version = typeof pkg.version === "string" ? pkg.version : _version;
|
|
@@ -849851,13 +849851,13 @@ init_state3();
|
|
|
849851
849851
|
|
|
849852
849852
|
// src/input/commands/recall-shared.ts
|
|
849853
849853
|
var VALID_CLASSES = ["decision", "constraint", "incident", "pattern", "fact", "risk", "runbook", "architecture", "ownership"];
|
|
849854
|
-
var
|
|
849854
|
+
var VALID_SCOPES = ["session", "project", "team"];
|
|
849855
849855
|
var VALID_REVIEW_STATES = ["fresh", "reviewed", "stale", "contradicted"];
|
|
849856
849856
|
function isValidClass(s4) {
|
|
849857
849857
|
return VALID_CLASSES.includes(s4);
|
|
849858
849858
|
}
|
|
849859
849859
|
function isValidScope(s4) {
|
|
849860
|
-
return
|
|
849860
|
+
return VALID_SCOPES.includes(s4);
|
|
849861
849861
|
}
|
|
849862
849862
|
function isValidReviewState(s4) {
|
|
849863
849863
|
return VALID_REVIEW_STATES.includes(s4);
|
|
@@ -849900,7 +849900,7 @@ function handleRecallSearch(args2, context) {
|
|
|
849900
849900
|
if (isValidScope(scope))
|
|
849901
849901
|
filter.scope = scope;
|
|
849902
849902
|
else {
|
|
849903
|
-
context.print(`[memory] Unknown scope "${scope}". Valid values ${
|
|
849903
|
+
context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
849904
849904
|
return;
|
|
849905
849905
|
}
|
|
849906
849906
|
}
|
|
@@ -850075,7 +850075,7 @@ function handleRecallList(args2, context) {
|
|
|
850075
850075
|
if (scopeIdx !== -1 && args2[scopeIdx + 1]) {
|
|
850076
850076
|
const scope = args2[scopeIdx + 1];
|
|
850077
850077
|
if (!isValidScope(scope)) {
|
|
850078
|
-
context.print(`[memory] Unknown scope "${scope}". Valid values ${
|
|
850078
|
+
context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
850079
850079
|
return;
|
|
850080
850080
|
}
|
|
850081
850081
|
filter.scope = scope;
|
|
@@ -850125,7 +850125,7 @@ async function handleRecallAdd(args2, context) {
|
|
|
850125
850125
|
const tags = tagsRaw ? tagsRaw.split(",").map((token) => token.trim()).filter(Boolean) : [];
|
|
850126
850126
|
const scope = scopeRaw && isValidScope(scopeRaw) ? scopeRaw : "project";
|
|
850127
850127
|
if (scopeRaw && !isValidScope(scopeRaw)) {
|
|
850128
|
-
context.print(`[memory] Invalid scope "${scopeRaw}". Valid values ${
|
|
850128
|
+
context.print(`[memory] Invalid scope "${scopeRaw}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
850129
850129
|
return;
|
|
850130
850130
|
}
|
|
850131
850131
|
const provenance = [];
|
|
@@ -850259,7 +850259,7 @@ function handleRecallExport(args2, context) {
|
|
|
850259
850259
|
if (scopeIdx !== -1 && commandArgs[scopeIdx + 1]) {
|
|
850260
850260
|
const scope = commandArgs[scopeIdx + 1];
|
|
850261
850261
|
if (!isValidScope(scope)) {
|
|
850262
|
-
context.print(`[memory] Unknown scope "${scope}". Valid values ${
|
|
850262
|
+
context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
850263
850263
|
return;
|
|
850264
850264
|
}
|
|
850265
850265
|
filter.scope = scope;
|
|
@@ -850338,7 +850338,7 @@ function handleRecallHandoffExport(args2, context) {
|
|
|
850338
850338
|
const scopeIdx = commandArgs.indexOf("--scope");
|
|
850339
850339
|
const scopeRaw = scopeIdx !== -1 ? commandArgs[scopeIdx + 1] : "team";
|
|
850340
850340
|
if (!scopeRaw || !isValidScope(scopeRaw)) {
|
|
850341
|
-
context.print(`[memory] Unknown scope "${scopeRaw ?? ""}". Valid values ${
|
|
850341
|
+
context.print(`[memory] Unknown scope "${scopeRaw ?? ""}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
850342
850342
|
return;
|
|
850343
850343
|
}
|
|
850344
850344
|
const bundle = memory.exportBundle({ scope: scopeRaw });
|
|
@@ -850454,7 +850454,7 @@ function handleRecallPromote(args2, context) {
|
|
|
850454
850454
|
const id = parsed.rest[0];
|
|
850455
850455
|
const scope = parsed.rest[1];
|
|
850456
850456
|
if (!id || !scope || !isValidScope(scope)) {
|
|
850457
|
-
context.print(`[memory] Usage: /memory promote <id> <${
|
|
850457
|
+
context.print(`[memory] Usage: /memory promote <id> <${VALID_SCOPES.join("|")}> --yes`);
|
|
850458
850458
|
return;
|
|
850459
850459
|
}
|
|
850460
850460
|
if (!parsed.yes) {
|
|
@@ -858623,7 +858623,7 @@ var AGENT_WORKSPACE_CATEGORY_IDS = [
|
|
|
858623
858623
|
"onboarding-channels",
|
|
858624
858624
|
"onboarding-voice-media",
|
|
858625
858625
|
"onboarding-context",
|
|
858626
|
-
"onboarding-
|
|
858626
|
+
"onboarding-automation",
|
|
858627
858627
|
"research",
|
|
858628
858628
|
"artifacts",
|
|
858629
858629
|
"conversation",
|
|
@@ -862058,6 +862058,7 @@ Use /channels list to see available channel ids.`);
|
|
|
862058
862058
|
}
|
|
862059
862059
|
|
|
862060
862060
|
// src/input/agent-workspace-snapshot.ts
|
|
862061
|
+
init_config8();
|
|
862061
862062
|
import { basename as basename6, sep as sep3 } from "path";
|
|
862062
862063
|
|
|
862063
862064
|
// src/agent/behavior-discovery-summary.ts
|
|
@@ -862265,6 +862266,13 @@ function buildAgentWorkspaceSetupChecklist(input) {
|
|
|
862265
862266
|
detail: providerReady ? `Current chat route is ${input.provider} / ${input.model}.` : "Choose a provider and model before relying on assistant turns.",
|
|
862266
862267
|
command: "Setup -> Provider and model"
|
|
862267
862268
|
},
|
|
862269
|
+
{
|
|
862270
|
+
id: "subscriptions",
|
|
862271
|
+
label: "Provider subscriptions",
|
|
862272
|
+
status: input.activeSubscriptionCount > 0 ? "ready" : input.pendingSubscriptionCount > 0 ? "recommended" : input.availableSubscriptionProviderCount > 0 ? "recommended" : "optional",
|
|
862273
|
+
detail: input.activeSubscriptionCount > 0 ? `${input.activeSubscriptionCount} provider subscription session(s) are active.` : input.pendingSubscriptionCount > 0 ? `${input.pendingSubscriptionCount} provider subscription login(s) are pending completion.` : input.availableSubscriptionProviderCount > 0 ? `${input.availableSubscriptionProviderCount} subscription-capable provider(s) are available. Start login if you want subscription routing.` : "No subscription-capable providers are available yet. Use API keys or add an OAuth provider service.",
|
|
862274
|
+
command: "Start -> Start subscription login"
|
|
862275
|
+
},
|
|
862268
862276
|
{
|
|
862269
862277
|
id: "agent-knowledge",
|
|
862270
862278
|
label: "Agent Knowledge",
|
|
@@ -862833,6 +862841,41 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
|
|
|
862833
862841
|
const ttsVoice = readConfigString3(context, "tts.voice", "(voice default)");
|
|
862834
862842
|
const ttsLlmProvider = readConfigString3(context, "tts.llmProvider", "");
|
|
862835
862843
|
const ttsLlmModel = readConfigString3(context, "tts.llmModel", "");
|
|
862844
|
+
const embeddingProvider = readConfigString3(context, "provider.embeddingProvider", "(provider default)");
|
|
862845
|
+
const reasoningEffort = readConfigString3(context, "provider.reasoningEffort", "(default)");
|
|
862846
|
+
const helperEnabled = readConfigBoolean3(context, "helper.enabled", false);
|
|
862847
|
+
const toolLlmEnabled = readConfigBoolean3(context, "tools.llmEnabled", false);
|
|
862848
|
+
const providerFailureHints = readConfigBoolean3(context, "behavior.suggestAlternativeOnProviderFail", false);
|
|
862849
|
+
const cacheEnabled = readConfigBoolean3(context, "cache.enabled", true);
|
|
862850
|
+
const cacheStableTtl = readConfigString3(context, "cache.stableTtl", "(default)");
|
|
862851
|
+
const cacheMonitorHitRate = readConfigBoolean3(context, "cache.monitorHitRate", true);
|
|
862852
|
+
const cacheHitRateWarningThreshold = readConfigNumber(context, "cache.hitRateWarningThreshold", 0.3);
|
|
862853
|
+
const hitlMode = readConfigString3(context, "behavior.hitlMode", "(default)");
|
|
862854
|
+
const guidanceMode = readConfigString3(context, "behavior.guidanceMode", "(default)");
|
|
862855
|
+
const saveHistory2 = readConfigBoolean3(context, "behavior.saveHistory", true);
|
|
862856
|
+
const autoApprove = readConfigBoolean3(context, "behavior.autoApprove", false);
|
|
862857
|
+
const autoCompactThreshold = readConfigNumber(context, "behavior.autoCompactThreshold", 0);
|
|
862858
|
+
const staleContextWarnings = readConfigBoolean3(context, "behavior.staleContextWarnings", false);
|
|
862859
|
+
const showThinking = readConfigBoolean3(context, "display.showThinking", false);
|
|
862860
|
+
const showReasoningSummary = readConfigBoolean3(context, "display.showReasoningSummary", false);
|
|
862861
|
+
const theme = readConfigString3(context, "display.theme", "(default)");
|
|
862862
|
+
const stream6 = readConfigBoolean3(context, "display.stream", true);
|
|
862863
|
+
const lineNumbers = readConfigString3(context, "display.lineNumbers", "(default)");
|
|
862864
|
+
const operationalMessages = readConfigString3(context, "ui.operationalMessages", "(default)");
|
|
862865
|
+
const systemMessages = readConfigString3(context, "ui.systemMessages", "(default)");
|
|
862866
|
+
const releaseChannel = readConfigString3(context, "release.channel", "(default)");
|
|
862867
|
+
const permissionMode = readConfigString3(context, "permissions.mode", "(default)");
|
|
862868
|
+
const toolAutoHeal = readConfigBoolean3(context, "tools.autoHeal", false);
|
|
862869
|
+
const toolsDefaultTokenBudget = readConfigNumber(context, "tools.defaultTokenBudget", 5000);
|
|
862870
|
+
const artifactMaxBytes = readConfigNumber(context, "storage.artifacts.maxBytes", 512 * 1024 * 1024);
|
|
862871
|
+
const rawPromptTelemetry = readConfigBoolean3(context, "telemetry.includeRawPrompts", false);
|
|
862872
|
+
const automationEnabled = readConfigBoolean3(context, "automation.enabled", false);
|
|
862873
|
+
const automationMaxConcurrentRuns = readConfigNumber(context, "automation.maxConcurrentRuns", 4);
|
|
862874
|
+
const automationRunHistoryLimit = readConfigNumber(context, "automation.runHistoryLimit", 100);
|
|
862875
|
+
const automationDefaultTimeoutMs = readConfigNumber(context, "automation.defaultTimeoutMs", 15 * 60 * 1000);
|
|
862876
|
+
const automationCatchUpWindowMinutes = readConfigNumber(context, "automation.catchUpWindowMinutes", 30);
|
|
862877
|
+
const automationFailureCooldownMs = readConfigNumber(context, "automation.failureCooldownMs", 5 * 60 * 1000);
|
|
862878
|
+
const automationDeleteAfterRun = readConfigBoolean3(context, "automation.deleteAfterRun", false);
|
|
862836
862879
|
const runtimeBaseUrl = `http://${host}:${port}`;
|
|
862837
862880
|
const companionAccess = (() => {
|
|
862838
862881
|
const homeDirectory = context.workspace?.shellPaths?.homeDirectory ?? "";
|
|
@@ -862854,6 +862897,18 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
|
|
|
862854
862897
|
nextStep
|
|
862855
862898
|
};
|
|
862856
862899
|
})();
|
|
862900
|
+
const subscriptionSnapshot = (() => {
|
|
862901
|
+
try {
|
|
862902
|
+
const manager5 = context.platform?.subscriptionManager;
|
|
862903
|
+
const services = context.platform?.serviceRegistry;
|
|
862904
|
+
const active = manager5?.list?.().length ?? 0;
|
|
862905
|
+
const pending = manager5?.listPending?.().length ?? 0;
|
|
862906
|
+
const available = services ? listAvailableSubscriptionProviders(services.getAll()).length : 0;
|
|
862907
|
+
return { active, pending, available };
|
|
862908
|
+
} catch {
|
|
862909
|
+
return { active: 0, pending: 0, available: 0 };
|
|
862910
|
+
}
|
|
862911
|
+
})();
|
|
862857
862912
|
const channels = buildAgentWorkspaceChannels(context);
|
|
862858
862913
|
const voiceMediaReadiness = buildAgentWorkspaceVoiceMediaReadiness({
|
|
862859
862914
|
context,
|
|
@@ -862864,6 +862919,9 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
|
|
|
862864
862919
|
provider: provider5,
|
|
862865
862920
|
model,
|
|
862866
862921
|
runtimeBaseUrl,
|
|
862922
|
+
activeSubscriptionCount: subscriptionSnapshot.active,
|
|
862923
|
+
pendingSubscriptionCount: subscriptionSnapshot.pending,
|
|
862924
|
+
availableSubscriptionProviderCount: subscriptionSnapshot.available,
|
|
862867
862925
|
sessionMemoryCount,
|
|
862868
862926
|
localMemoryCount: memorySnapshot.count,
|
|
862869
862927
|
localMemoryReviewQueueCount: memorySnapshot.reviewQueueCount,
|
|
@@ -862891,11 +862949,49 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
|
|
|
862891
862949
|
provider: provider5,
|
|
862892
862950
|
model,
|
|
862893
862951
|
modelDisplayName: currentModel?.displayName ?? model,
|
|
862952
|
+
embeddingProvider,
|
|
862953
|
+
reasoningEffort,
|
|
862954
|
+
helperEnabled,
|
|
862955
|
+
toolLlmEnabled,
|
|
862956
|
+
providerFailureHints,
|
|
862957
|
+
cacheEnabled,
|
|
862958
|
+
cacheStableTtl,
|
|
862959
|
+
cacheMonitorHitRate,
|
|
862960
|
+
cacheHitRateWarningThreshold,
|
|
862961
|
+
hitlMode,
|
|
862962
|
+
guidanceMode,
|
|
862963
|
+
saveHistory: saveHistory2,
|
|
862964
|
+
autoApprove,
|
|
862965
|
+
autoCompactThreshold,
|
|
862966
|
+
staleContextWarnings,
|
|
862967
|
+
showThinking,
|
|
862968
|
+
showReasoningSummary,
|
|
862969
|
+
theme,
|
|
862970
|
+
stream: stream6,
|
|
862971
|
+
lineNumbers,
|
|
862972
|
+
operationalMessages,
|
|
862973
|
+
systemMessages,
|
|
862974
|
+
releaseChannel,
|
|
862975
|
+
permissionMode,
|
|
862976
|
+
toolAutoHeal,
|
|
862977
|
+
toolsDefaultTokenBudget,
|
|
862978
|
+
artifactMaxBytes,
|
|
862979
|
+
rawPromptTelemetry,
|
|
862980
|
+
automationEnabled,
|
|
862981
|
+
automationMaxConcurrentRuns,
|
|
862982
|
+
automationRunHistoryLimit,
|
|
862983
|
+
automationDefaultTimeoutMs,
|
|
862984
|
+
automationCatchUpWindowMinutes,
|
|
862985
|
+
automationFailureCooldownMs,
|
|
862986
|
+
automationDeleteAfterRun,
|
|
862894
862987
|
sessionId: context.session?.runtime?.sessionId ?? "unknown",
|
|
862895
862988
|
workingDirectory: context.workspace?.shellPaths?.workingDirectory ?? "unavailable",
|
|
862896
862989
|
homeDirectory: context.workspace?.shellPaths?.homeDirectory ?? "unavailable",
|
|
862897
862990
|
runtimeBaseUrl,
|
|
862898
862991
|
runtimeOwnership: "external",
|
|
862992
|
+
activeSubscriptionCount: subscriptionSnapshot.active,
|
|
862993
|
+
pendingSubscriptionCount: subscriptionSnapshot.pending,
|
|
862994
|
+
availableSubscriptionProviderCount: subscriptionSnapshot.available,
|
|
862899
862995
|
sessionMemoryCount,
|
|
862900
862996
|
localMemoryCount: memorySnapshot.count,
|
|
862901
862997
|
localMemoryReviewQueueCount: memorySnapshot.reviewQueueCount,
|
|
@@ -866599,7 +866695,7 @@ import { mkdirSync as mkdirSync66, readFileSync as readFileSync88, writeFileSync
|
|
|
866599
866695
|
import { dirname as dirname64, resolve as resolve39 } from "path";
|
|
866600
866696
|
init_state3();
|
|
866601
866697
|
var VALID_CLASSES2 = ["decision", "constraint", "incident", "pattern", "fact", "risk", "runbook", "architecture", "ownership"];
|
|
866602
|
-
var
|
|
866698
|
+
var VALID_SCOPES3 = ["session", "project", "team"];
|
|
866603
866699
|
var VALID_REVIEW_STATES3 = ["fresh", "reviewed", "stale", "contradicted"];
|
|
866604
866700
|
var VALID_PROVENANCE_KINDS = ["session", "turn", "task", "event", "file"];
|
|
866605
866701
|
var VALUE_OPTIONS = new Set([
|
|
@@ -866699,7 +866795,7 @@ function isMemoryClass2(value) {
|
|
|
866699
866795
|
return VALID_CLASSES2.includes(value);
|
|
866700
866796
|
}
|
|
866701
866797
|
function isMemoryScope2(value) {
|
|
866702
|
-
return
|
|
866798
|
+
return VALID_SCOPES3.includes(value);
|
|
866703
866799
|
}
|
|
866704
866800
|
function isReviewState(value) {
|
|
866705
866801
|
return VALID_REVIEW_STATES3.includes(value);
|
|
@@ -866714,7 +866810,7 @@ function requireClass(value) {
|
|
|
866714
866810
|
}
|
|
866715
866811
|
function requireScope(value) {
|
|
866716
866812
|
if (!value || !isMemoryScope2(value))
|
|
866717
|
-
throw new Error(`Invalid memory scope "${value ?? ""}". Valid values ${
|
|
866813
|
+
throw new Error(`Invalid memory scope "${value ?? ""}". Valid values ${VALID_SCOPES3.join(", ")}`);
|
|
866718
866814
|
return value;
|
|
866719
866815
|
}
|
|
866720
866816
|
function optionalScope(value) {
|
|
@@ -881486,7 +881582,7 @@ function createAgentWorkspaceBasicCommandEditor(kind2) {
|
|
|
881486
881582
|
selectedFieldIndex: 0,
|
|
881487
881583
|
message: "Inspect one provider subscription route without starting login or printing token values.",
|
|
881488
881584
|
fields: [
|
|
881489
|
-
{ id: "provider", label: "Provider", value: "openai", required: true, multiline: false, hint: "Subscription provider id
|
|
881585
|
+
{ id: "provider", label: "Provider", value: "openai", required: true, multiline: false, hint: "Subscription provider id, such as openai." }
|
|
881490
881586
|
]
|
|
881491
881587
|
};
|
|
881492
881588
|
}
|
|
@@ -881496,12 +881592,11 @@ function createAgentWorkspaceBasicCommandEditor(kind2) {
|
|
|
881496
881592
|
mode: "create",
|
|
881497
881593
|
title: "Start Provider Subscription Login",
|
|
881498
881594
|
selectedFieldIndex: 0,
|
|
881499
|
-
message: "Begin one provider subscription OAuth login
|
|
881595
|
+
message: "Begin one provider subscription OAuth login, save the pending session, and return here for completion.",
|
|
881500
881596
|
fields: [
|
|
881501
|
-
{ id: "provider", label: "Provider", value: "openai", required: true, multiline: false, hint: "Subscription provider id
|
|
881597
|
+
{ id: "provider", label: "Provider", value: "openai", required: true, multiline: false, hint: "Subscription provider id, such as openai." },
|
|
881502
881598
|
{ id: "openBrowser", label: "Open browser", value: "yes", required: false, multiline: false, hint: "yes/no. Use no to print the authorization URL only." },
|
|
881503
|
-
{ id: "
|
|
881504
|
-
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /subscription login <provider> start with --yes." }
|
|
881599
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to save pending login state and open or show the authorization URL." }
|
|
881505
881600
|
]
|
|
881506
881601
|
};
|
|
881507
881602
|
}
|
|
@@ -881511,11 +881606,11 @@ function createAgentWorkspaceBasicCommandEditor(kind2) {
|
|
|
881511
881606
|
mode: "update",
|
|
881512
881607
|
title: "Finish Provider Subscription Login",
|
|
881513
881608
|
selectedFieldIndex: 0,
|
|
881514
|
-
message: "Finish a pending provider subscription OAuth login from a code or redirected URL
|
|
881609
|
+
message: "Finish a pending provider subscription OAuth login from a code or redirected URL and save the subscription session.",
|
|
881515
881610
|
fields: [
|
|
881516
881611
|
{ id: "provider", label: "Provider", value: "openai", required: true, multiline: false, hint: "Provider id used when starting login." },
|
|
881517
881612
|
{ id: "code", label: "Code or redirect URL", value: "", required: true, multiline: false, hint: "OAuth code or full redirect URL containing code=..." },
|
|
881518
|
-
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to
|
|
881613
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to exchange the code and save the provider subscription session." }
|
|
881519
881614
|
]
|
|
881520
881615
|
};
|
|
881521
881616
|
}
|
|
@@ -881525,10 +881620,10 @@ function createAgentWorkspaceBasicCommandEditor(kind2) {
|
|
|
881525
881620
|
mode: "delete",
|
|
881526
881621
|
title: "Logout Provider Subscription",
|
|
881527
881622
|
selectedFieldIndex: 0,
|
|
881528
|
-
message: "Remove one
|
|
881623
|
+
message: "Remove one active or pending provider subscription session. Ambient API key resolution applies again if configured.",
|
|
881529
881624
|
fields: [
|
|
881530
881625
|
{ id: "provider", label: "Provider", value: "openai", required: true, multiline: false, hint: "Stored subscription provider id." },
|
|
881531
|
-
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to
|
|
881626
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to remove active or pending subscription state." }
|
|
881532
881627
|
]
|
|
881533
881628
|
};
|
|
881534
881629
|
}
|
|
@@ -890312,6 +890407,14 @@ function activateAgentWorkspaceSelection(workspace, requestRender) {
|
|
|
890312
890407
|
workspace.importTuiSettings(requestRender);
|
|
890313
890408
|
return;
|
|
890314
890409
|
}
|
|
890410
|
+
if (action2.kind === "model-picker") {
|
|
890411
|
+
workspace.openModelPickerAction(action2, requestRender);
|
|
890412
|
+
return;
|
|
890413
|
+
}
|
|
890414
|
+
if (action2.kind === "settings-modal") {
|
|
890415
|
+
workspace.openSettingsModalAction(action2, requestRender);
|
|
890416
|
+
return;
|
|
890417
|
+
}
|
|
890315
890418
|
if (action2.kind === "editor" && action2.editorKind) {
|
|
890316
890419
|
const editor = createAgentWorkspaceEditor(action2.editorKind, {
|
|
890317
890420
|
runtimeStarterTemplates: workspace.runtimeSnapshot?.runtimeStarterTemplates ?? [],
|
|
@@ -890481,6 +890584,63 @@ function settingAction(options) {
|
|
|
890481
890584
|
};
|
|
890482
890585
|
}
|
|
890483
890586
|
|
|
890587
|
+
// src/input/agent-workspace-host-category.ts
|
|
890588
|
+
var AGENT_WORKSPACE_HOST_CATEGORY = {
|
|
890589
|
+
id: "host",
|
|
890590
|
+
group: "OPERATIONS",
|
|
890591
|
+
label: "Connected Host",
|
|
890592
|
+
summary: "Connected-host health, tasks, sessions, channels, and automation.",
|
|
890593
|
+
detail: "Use this workspace to inspect the GoodVibes host surfaces that Agent can see: system health, remote routes, host tasks, sessions, channels, schedules, knowledge, media, MCP, provider auth, support bundles, and telemetry/config posture.",
|
|
890594
|
+
actions: [
|
|
890595
|
+
{ id: "host-overview", label: "Host overview", detail: "Review connected-host, provider, settings, continuity, and Agent health without starting or mutating host work.", command: "/health review", kind: "command", safety: "read-only" },
|
|
890596
|
+
{ id: "host-services", label: "Host services", detail: "Inspect connected-host service readiness, credentials, and integration issues without changing them.", command: "/health host", kind: "command", safety: "read-only" },
|
|
890597
|
+
{ id: "host-setup", label: "Setup review", detail: "Inspect setup issues that affect connected-host and Agent runtime readiness.", command: "/health setup", kind: "command", safety: "read-only" },
|
|
890598
|
+
{ id: "host-remote", label: "Remote routes", detail: "Inspect remote build-host route health and recovery signals without starting build work.", command: "/health remote", kind: "command", safety: "read-only" },
|
|
890599
|
+
{ id: "host-maintenance", label: "Session maintenance", detail: "Review continuity, compaction, and current-session maintenance posture.", command: "/health maintenance", kind: "command", safety: "read-only" },
|
|
890600
|
+
{ id: "host-continuity", label: "Continuity", detail: "Inspect last-session pointer, recovery-file posture, and return-context state.", command: "/health continuity", kind: "command", safety: "read-only" },
|
|
890601
|
+
{ id: "host-tasks", label: "Host tasks", detail: "Inspect connected-host task state without creating, retrying, or mutating tasks.", command: "/tasks list", kind: "command", safety: "read-only" },
|
|
890602
|
+
{ id: "host-task-filter", label: "Filter host tasks", detail: "Open a status/type form for read-only connected-host task filtering.", editorKind: "task-list-filter", kind: "editor", safety: "read-only" },
|
|
890603
|
+
{ id: "host-task-show", label: "Inspect host task", detail: "Open a task-id form for read-only connected-host task metadata.", editorKind: "task-show", kind: "editor", safety: "read-only" },
|
|
890604
|
+
{ id: "host-task-output", label: "Show task output", detail: "Open a task-id form for read-only connected-host task output.", editorKind: "task-output", kind: "editor", safety: "read-only" },
|
|
890605
|
+
{ id: "host-sessions", label: "Host session routes", detail: "Browse saved Agent sessions and return-context posture exposed through the runtime session surface.", command: "/session list", kind: "command", safety: "read-only" },
|
|
890606
|
+
{ id: "host-session-graph", label: "Session graph", detail: "Open a read-only form for cross-session graph inspection; graph mutation remains blocked in Agent.", editorKind: "session-graph", kind: "editor", safety: "read-only" },
|
|
890607
|
+
{ id: "host-channels-status", label: "Channel status", detail: "Inspect connected channel runtime status from the host without mutating delivery state.", command: "/channels status", kind: "command", safety: "read-only" },
|
|
890608
|
+
{ id: "host-channel-accounts", label: "Channel accounts", detail: "Inspect connected channel accounts without printing secret values or sending messages.", command: "/channels accounts", kind: "command", safety: "read-only" },
|
|
890609
|
+
{ id: "host-channel-policies", label: "Channel policies", detail: "Inspect channel delivery policy posture without changing routing.", command: "/channels policies", kind: "command", safety: "read-only" },
|
|
890610
|
+
{ id: "host-channels", label: "Open Channels", detail: "Jump to the channel setup and delivery workspace.", targetCategoryId: "channels", kind: "workspace", safety: "safe" },
|
|
890611
|
+
{ id: "host-automation", label: "Open Automation", detail: "Jump to connected schedules, reminders, receipts, and explicit run controls.", targetCategoryId: "automation", kind: "workspace", safety: "safe" },
|
|
890612
|
+
{ id: "host-schedules", label: "Schedule status", detail: "Inspect schedules and run history without running or mutating them.", command: "/schedule list", kind: "command", safety: "read-only" },
|
|
890613
|
+
{ id: "host-schedule-reconcile", label: "Reconcile schedules", detail: "Compare local promotion receipts with live connected schedules.", command: "/schedule reconcile", kind: "command", safety: "read-only" },
|
|
890614
|
+
{ id: "host-knowledge", label: "Knowledge route", detail: "Inspect isolated Agent Knowledge route readiness and source counts.", command: "/knowledge status", kind: "command", safety: "read-only" },
|
|
890615
|
+
{ id: "host-knowledge-open", label: "Open Knowledge", detail: "Jump to Agent Knowledge source, graph, review, and ingest controls.", targetCategoryId: "knowledge", kind: "workspace", safety: "safe" },
|
|
890616
|
+
{ id: "host-media", label: "Media providers", detail: "Inspect configured media providers before generating media with confirmation.", command: "/media providers", kind: "command", safety: "read-only" },
|
|
890617
|
+
{ id: "host-media-open", label: "Open Voice and Media", detail: "Jump to voice, TTS, image input, media provider, and browser-tool setup actions.", targetCategoryId: "voice-media", kind: "workspace", safety: "safe" },
|
|
890618
|
+
{ id: "host-mcp-health", label: "MCP health", detail: "Inspect MCP lifecycle issues without changing trust posture or approving tool-definition review.", command: "/health mcp", kind: "command", safety: "read-only" },
|
|
890619
|
+
{ id: "host-mcp-review", label: "MCP review", detail: "Inspect MCP server connection, trust, role, and review posture.", command: "/mcp review", kind: "command", safety: "read-only" },
|
|
890620
|
+
{ id: "host-tools-open", label: "Open Tools and MCP", detail: "Jump to MCP server setup, tool inventory, secrets, and security review.", targetCategoryId: "tools", kind: "workspace", safety: "safe" },
|
|
890621
|
+
{ id: "host-provider-accounts", label: "Provider accounts", detail: "Review provider account routes, subscription windows, and billing-path safety.", command: "/accounts review", kind: "command", safety: "read-only" },
|
|
890622
|
+
{ id: "host-provider-detail", label: "Provider detail", detail: "Open a provider-id form for account and provider configuration review.", editorKind: "provider-inspect", kind: "editor", safety: "read-only" },
|
|
890623
|
+
{ id: "host-provider-routes", label: "Provider routes", detail: "Open a provider-id form for account, subscription, and route inspection.", editorKind: "provider-routes", kind: "editor", safety: "read-only" },
|
|
890624
|
+
{ id: "host-provider-repair", label: "Provider repair guidance", detail: "Open a provider-id form for read-only provider repair guidance.", editorKind: "provider-account-repair", kind: "editor", safety: "read-only" },
|
|
890625
|
+
{ id: "host-auth-owner", label: "Connected-host auth owner", detail: "Show that connected-host auth administration belongs to the owning GoodVibes host, not Agent.", command: "/auth local", kind: "command", safety: "read-only" },
|
|
890626
|
+
{ id: "host-auth-review", label: "Provider auth review", detail: "Review provider auth posture without printing token values.", command: "/auth review", kind: "command", safety: "read-only" },
|
|
890627
|
+
{ id: "host-auth-detail", label: "Provider auth detail", detail: "Open a provider-id form for read-only provider auth inspection.", editorKind: "auth-show", kind: "editor", safety: "read-only" },
|
|
890628
|
+
{ id: "host-auth-repair", label: "Provider auth repair", detail: "Open a provider-id form for provider auth repair guidance.", editorKind: "auth-repair", kind: "editor", safety: "read-only" },
|
|
890629
|
+
{ id: "host-auth-bundle-export", label: "Export auth bundle", detail: "Open a confirmed form that exports a redacted provider auth review bundle.", editorKind: "auth-bundle-export", kind: "editor", safety: "safe" },
|
|
890630
|
+
{ id: "host-auth-bundle-inspect", label: "Inspect auth bundle", detail: "Open a form that inspects a provider auth review bundle before sharing or import.", editorKind: "auth-bundle-inspect", kind: "editor", safety: "read-only" },
|
|
890631
|
+
{ id: "host-subscription-bundle-export", label: "Export subscription bundle", detail: "Open a confirmed form that exports redacted provider subscription state for review.", editorKind: "subscription-bundle-export", kind: "editor", safety: "safe" },
|
|
890632
|
+
{ id: "host-subscription-bundle-inspect", label: "Inspect subscription bundle", detail: "Open a form that inspects provider subscription state before sharing.", editorKind: "subscription-bundle-inspect", kind: "editor", safety: "read-only" },
|
|
890633
|
+
{ id: "host-security", label: "Security review", detail: "Inspect token posture, MCP attack paths, policy lint, plugin risk, and incident pressure.", command: "/security review", kind: "command", safety: "read-only" },
|
|
890634
|
+
{ id: "host-trust", label: "Trust review", detail: "Review permission, secret, plugin, and MCP trust posture without exporting bundles or changing trust.", command: "/trust review", kind: "command", safety: "read-only" },
|
|
890635
|
+
{ id: "host-support-bundle-export", label: "Export support bundle", detail: "Export a redacted Agent support bundle from the Host page.", editorKind: "support-bundle-export", kind: "editor", safety: "safe" },
|
|
890636
|
+
{ id: "host-support-bundle-inspect", label: "Inspect support bundle", detail: "Inspect a support bundle before import or sharing.", editorKind: "support-bundle-inspect", kind: "editor", safety: "read-only" },
|
|
890637
|
+
{ id: "host-support-bundle-import", label: "Import support bundle", detail: "Import reviewed, non-redacted config values from a support bundle.", editorKind: "support-bundle-import", kind: "editor", safety: "safe" },
|
|
890638
|
+
{ id: "host-telemetry", label: "Telemetry settings", detail: "Open telemetry payload policy settings for connected-host and Agent observability review.", command: "/config telemetry", kind: "command", safety: "safe" },
|
|
890639
|
+
{ id: "host-config", label: "Control-plane settings", detail: "Open configuration controls for service, channels, tools, automation, provider, and storage posture.", command: "/config", kind: "command", safety: "safe" },
|
|
890640
|
+
{ id: "host-safety", label: "Host mutation policy", detail: "Agent may inspect connected-host surfaces and run explicit confirmed actions, but does not silently create tasks, send channel messages, mutate auth, or start automation.", kind: "guidance", safety: "blocked" }
|
|
890641
|
+
]
|
|
890642
|
+
};
|
|
890643
|
+
|
|
890484
890644
|
// src/input/agent-workspace-categories.ts
|
|
890485
890645
|
var AGENT_WORKSPACE_CATEGORIES = [
|
|
890486
890646
|
{
|
|
@@ -890493,6 +890653,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890493
890653
|
{ id: "chat", label: "Continue assistant chat", detail: "Return to the main composer and type a normal message. Agent work stays serial in the main conversation.", kind: "guidance", safety: "safe" },
|
|
890494
890654
|
{ id: "brief", label: "Operator briefing", detail: "Show a concise Agent status and next-actions briefing without mutating the connected host.", command: "/brief", kind: "command", safety: "read-only" },
|
|
890495
890655
|
{ id: "model", label: "Choose model", detail: "Open the model/provider workspace for the Agent chat route.", command: "/model", kind: "command", safety: "safe" },
|
|
890656
|
+
{ id: "model-refresh", label: "Refresh model catalog", detail: "Refresh locally cached provider model lists without changing the selected route.", command: "/refresh-models", kind: "command", safety: "safe" },
|
|
890496
890657
|
{ id: "setup-home", label: "Onboarding", detail: "Jump to first-run configuration for account, model, tools, channels, voice, local context, and finish.", targetCategoryId: "setup", kind: "workspace", safety: "safe" },
|
|
890497
890658
|
{ id: "channels-home", label: "Channels", detail: "Jump to companion pairing and channel readiness without changing connected-host routing.", targetCategoryId: "channels", kind: "workspace", safety: "read-only" },
|
|
890498
890659
|
{ id: "mode-show", label: "Interaction mode", detail: "Review Agent interaction noise level and per-domain verbosity.", command: "/mode show", kind: "command", safety: "read-only" },
|
|
@@ -890519,63 +890680,55 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890519
890680
|
id: "setup",
|
|
890520
890681
|
group: "ONBOARDING",
|
|
890521
890682
|
label: "Start",
|
|
890522
|
-
summary: "Import
|
|
890523
|
-
detail: "
|
|
890683
|
+
summary: "Import preferences, sign in, and choose the main model.",
|
|
890684
|
+
detail: "Start here on a fresh install. Every row either saves state, opens the shared model picker, or opens a confirmed in-modal form.",
|
|
890524
890685
|
actions: [
|
|
890525
|
-
{ id: "import-goodvibes-tui-settings", label: "Import GoodVibes settings", detail: "Copy existing
|
|
890526
|
-
|
|
890527
|
-
|
|
890528
|
-
{ id: "
|
|
890529
|
-
{ id: "
|
|
890530
|
-
{ id: "subscription-logout", label: "Logout subscription", detail: "
|
|
890531
|
-
{ id: "subscription-inspect", label: "Inspect subscription route", detail: "Inspect one provider subscription OAuth route before starting or finishing login.", editorKind: "subscription-inspect", kind: "editor", safety: "read-only" },
|
|
890532
|
-
{ id: "subscription-bundle-export", label: "Export subscription bundle", detail: "Export a redacted provider subscription bundle for setup review.", editorKind: "subscription-bundle-export", kind: "editor", safety: "safe" },
|
|
890533
|
-
{ id: "subscription-bundle-inspect", label: "Inspect subscription bundle", detail: "Inspect a provider subscription bundle before setup review.", editorKind: "subscription-bundle-inspect", kind: "editor", safety: "read-only" },
|
|
890686
|
+
{ id: "import-goodvibes-tui-settings", label: "Import GoodVibes settings", detail: "Copy existing display, provider, subscription, behavior, permission, TTS, channel, helper, tool, release, and automation values into Agent-owned state.", kind: "settings-import", safety: "safe" },
|
|
890687
|
+
{ id: "subscription-login-start", label: "Start subscription login", detail: "Start one provider sign-in flow, save pending state, and return here.", editorKind: "subscription-login-start", kind: "editor", safety: "safe" },
|
|
890688
|
+
{ id: "subscription-login-finish", label: "Finish subscription login", detail: "Exchange a code or redirect URL and save the provider subscription session.", editorKind: "subscription-login-finish", kind: "editor", safety: "safe" },
|
|
890689
|
+
{ id: "setup-provider-model", label: "Choose main model", detail: "Open the shared provider/model picker for normal assistant turns.", kind: "model-picker", modelPickerFlow: "providerModel", modelPickerTarget: "main", safety: "safe" },
|
|
890690
|
+
settingAction({ id: "setup-reasoning-effort", label: "Reasoning effort", detail: "Cycle reasoning level when the selected model supports it.", key: "provider.reasoningEffort" }),
|
|
890691
|
+
{ id: "subscription-logout", label: "Logout subscription", detail: "Remove one stored or pending provider subscription session after confirmation.", editorKind: "subscription-logout", kind: "editor", safety: "safe" },
|
|
890534
890692
|
{ id: "provider-add", label: "Add custom provider", detail: "Add one OpenAI-compatible provider for Agent model routing.", editorKind: "provider-add", kind: "editor", safety: "safe" },
|
|
890535
|
-
{ id: "secret-set-provider", label: "Store
|
|
890536
|
-
settingAction({ id: "setup-secret-policy", label: "Secret storage
|
|
890537
|
-
settingAction({ id: "setup-save-history", label: "Save
|
|
890693
|
+
{ id: "secret-set-provider", label: "Store secret", detail: "Store a provider or channel credential through the Agent secret manager.", editorKind: "secret-set", kind: "editor", safety: "safe" },
|
|
890694
|
+
settingAction({ id: "setup-secret-policy", label: "Secret storage", detail: "Choose how strongly Agent prefers secure secret storage.", key: "storage.secretPolicy" }),
|
|
890695
|
+
settingAction({ id: "setup-save-history", label: "Save history", detail: "Toggle local conversation history persistence.", key: "behavior.saveHistory" })
|
|
890538
890696
|
]
|
|
890539
890697
|
},
|
|
890540
890698
|
{
|
|
890541
890699
|
id: "account-model",
|
|
890542
890700
|
group: "ONBOARDING",
|
|
890543
|
-
label: "
|
|
890544
|
-
summary: "
|
|
890545
|
-
detail: "Use this after sign-in
|
|
890701
|
+
label: "Model Routing",
|
|
890702
|
+
summary: "Set chat, embedding, helper, tool, and spoken-turn routes.",
|
|
890703
|
+
detail: "Use this after sign-in. Routes are saved settings, so selections persist across launches.",
|
|
890546
890704
|
actions: [
|
|
890547
|
-
{ id: "provider-use", label: "
|
|
890548
|
-
{ id: "provider-
|
|
890549
|
-
{ id: "
|
|
890550
|
-
{ id: "
|
|
890551
|
-
{ id: "
|
|
890552
|
-
{ id: "model-refresh", label: "Refresh model catalog", detail: "Refresh model catalog, benchmark, and token-limit metadata.", command: "/refresh-models", kind: "command", safety: "safe" },
|
|
890553
|
-
{ id: "model-pin", label: "Pin model", detail: "Pin one model registry key for quick reuse.", editorKind: "model-pin", kind: "editor", safety: "safe" },
|
|
890554
|
-
{ id: "model-unpin", label: "Unpin model", detail: "Remove one pinned model registry key.", editorKind: "model-unpin", kind: "editor", safety: "safe" },
|
|
890555
|
-
{ id: "auth-show", label: "Show provider auth", detail: "Inspect provider auth state without printing token values.", editorKind: "auth-show", kind: "editor", safety: "read-only" },
|
|
890556
|
-
{ id: "auth-repair", label: "Auth repair guidance", detail: "Show auth repair guidance without storing tokens or starting login.", editorKind: "auth-repair", kind: "editor", safety: "read-only" },
|
|
890557
|
-
{ id: "auth-bundle-export", label: "Export auth bundle", detail: "Export a redacted auth review bundle after confirmation.", editorKind: "auth-bundle-export", kind: "editor", safety: "safe" },
|
|
890558
|
-
{ id: "auth-bundle-inspect", label: "Inspect auth bundle", detail: "Inspect an auth review bundle before setup review.", editorKind: "auth-bundle-inspect", kind: "editor", safety: "read-only" },
|
|
890559
|
-
settingAction({ id: "account-main-model", label: "Main model", detail: "Edit the provider-qualified model registry key for normal assistant turns.", key: "provider.model" }),
|
|
890560
|
-
settingAction({ id: "account-reasoning", label: "Reasoning effort", detail: "Cycle instant, low, medium, or high reasoning effort.", key: "provider.reasoningEffort" }),
|
|
890561
|
-
settingAction({ id: "account-embedding", label: "Embedding provider", detail: "Set the embedding provider used by local memory and retrieval.", key: "provider.embeddingProvider" }),
|
|
890705
|
+
{ id: "provider-use", label: "Choose provider and model", detail: "Open the shared provider/model picker for the main chat route.", kind: "model-picker", modelPickerFlow: "providerModel", modelPickerTarget: "main", safety: "safe" },
|
|
890706
|
+
{ id: "provider-remove", label: "Remove custom provider", detail: "Remove one custom provider config after confirmation.", editorKind: "provider-remove", kind: "editor", safety: "safe" },
|
|
890707
|
+
{ id: "account-main-model", label: "Choose main model", detail: "Open the shared model picker for normal assistant turns.", kind: "model-picker", modelPickerFlow: "model", modelPickerTarget: "main", safety: "safe" },
|
|
890708
|
+
settingAction({ id: "account-reasoning", label: "Reasoning effort", detail: "Cycle the reasoning effort used when supported.", key: "provider.reasoningEffort" }),
|
|
890709
|
+
settingAction({ id: "account-embedding", label: "Embedding provider", detail: "Set the embedding provider for memory and retrieval.", key: "provider.embeddingProvider" }),
|
|
890562
890710
|
settingAction({ id: "account-system-prompt", label: "System prompt file", detail: "Set an optional local system prompt file path.", key: "provider.systemPromptFile" }),
|
|
890563
890711
|
settingAction({ id: "account-helper-enabled", label: "Enable helper model", detail: "Toggle dedicated helper routing for background utility work.", key: "helper.enabled" }),
|
|
890564
|
-
|
|
890565
|
-
|
|
890712
|
+
{ id: "account-helper-provider", label: "Choose helper provider/model", detail: "Open the shared provider/model picker for helper routing.", kind: "model-picker", modelPickerFlow: "providerModel", modelPickerTarget: "helper", visibleWhenSettingKey: "helper.enabled", visibleWhenSettingValue: true, safety: "safe" },
|
|
890713
|
+
{ id: "account-helper-model", label: "Choose helper model", detail: "Open the shared model picker for helper routing.", kind: "model-picker", modelPickerFlow: "model", modelPickerTarget: "helper", visibleWhenSettingKey: "helper.enabled", visibleWhenSettingValue: true, safety: "safe" },
|
|
890566
890714
|
settingAction({ id: "account-tool-llm-enabled", label: "Enable tool LLM", detail: "Toggle a dedicated tool LLM for internal operations.", key: "tools.llmEnabled" }),
|
|
890567
|
-
|
|
890568
|
-
|
|
890569
|
-
|
|
890570
|
-
|
|
890715
|
+
{ id: "account-tool-provider", label: "Choose tool provider/model", detail: "Open the shared provider/model picker for dedicated tool LLM calls.", kind: "model-picker", modelPickerFlow: "providerModel", modelPickerTarget: "tool", visibleWhenSettingKey: "tools.llmEnabled", visibleWhenSettingValue: true, safety: "safe" },
|
|
890716
|
+
{ id: "account-tool-model", label: "Choose tool model", detail: "Open the shared model picker for dedicated tool LLM calls.", kind: "model-picker", modelPickerFlow: "model", modelPickerTarget: "tool", visibleWhenSettingKey: "tools.llmEnabled", visibleWhenSettingValue: true, safety: "safe" },
|
|
890717
|
+
{ id: "account-tts-llm-provider", label: "Choose spoken-turn provider/model", detail: "Open the shared provider/model picker for spoken-response turns.", kind: "model-picker", modelPickerFlow: "providerModel", modelPickerTarget: "tts", safety: "safe" },
|
|
890718
|
+
{ id: "account-tts-llm-model", label: "Choose spoken-turn model", detail: "Open the shared model picker for spoken-response turns.", kind: "model-picker", modelPickerFlow: "model", modelPickerTarget: "tts", safety: "safe" },
|
|
890719
|
+
settingAction({ id: "account-provider-fallback-hint", label: "Provider failure hints", detail: "Toggle alternative model suggestions when the current provider fails non-transiently.", key: "behavior.suggestAlternativeOnProviderFail" }),
|
|
890720
|
+
settingAction({ id: "account-cache-enabled", label: "Prompt cache", detail: "Toggle prompt caching for eligible providers.", key: "cache.enabled" }),
|
|
890721
|
+
settingAction({ id: "account-cache-ttl", label: "Cache TTL", detail: "Cycle ephemeral or persistent cache TTL for stable content.", key: "cache.stableTtl", visibleWhenKey: "cache.enabled", visibleWhenValue: true }),
|
|
890722
|
+
settingAction({ id: "account-cache-monitor", label: "Cache hit-rate monitor", detail: "Toggle cache hit-rate monitoring.", key: "cache.monitorHitRate", visibleWhenKey: "cache.enabled", visibleWhenValue: true }),
|
|
890723
|
+
settingAction({ id: "account-cache-threshold", label: "Cache warning threshold", detail: "Set the cache hit-rate warning threshold.", key: "cache.hitRateWarningThreshold", visibleWhenKey: "cache.monitorHitRate", visibleWhenValue: true })
|
|
890571
890724
|
]
|
|
890572
890725
|
},
|
|
890573
890726
|
{
|
|
890574
890727
|
id: "assistant-behavior",
|
|
890575
890728
|
group: "ONBOARDING",
|
|
890576
|
-
label: "
|
|
890577
|
-
summary: "
|
|
890578
|
-
detail: "Use this
|
|
890729
|
+
label: "Behavior",
|
|
890730
|
+
summary: "Set interaction style, context pressure behavior, and visible reasoning.",
|
|
890731
|
+
detail: "Use this to choose how chat feels during normal work and long-running tasks.",
|
|
890579
890732
|
actions: [
|
|
890580
890733
|
settingAction({ id: "behavior-hitl-mode", label: "Interaction mode", detail: "Cycle quiet, balanced, or operator interaction mode.", key: "behavior.hitlMode" }),
|
|
890581
890734
|
settingAction({ id: "behavior-guidance-mode", label: "Guidance mode", detail: "Cycle off, minimal, or guided operational guidance.", key: "behavior.guidanceMode" }),
|
|
@@ -890591,28 +890744,41 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890591
890744
|
id: "tools-permissions",
|
|
890592
890745
|
group: "ONBOARDING",
|
|
890593
890746
|
label: "Tools & Permissions",
|
|
890594
|
-
summary: "
|
|
890595
|
-
detail: "Use this
|
|
890747
|
+
summary: "Set approval policy, MCP entry points, and secret references.",
|
|
890748
|
+
detail: "Use this before enabling tool-heavy work. Permission rows write policy; MCP and secret rows open setup forms.",
|
|
890596
890749
|
actions: [
|
|
890597
890750
|
settingAction({ id: "permissions-mode", label: "Permission mode", detail: "Cycle prompt, allow-all, or custom permission mode.", key: "permissions.mode" }),
|
|
890751
|
+
settingAction({ id: "permissions-auto-approve", label: "Auto-approve tools", detail: "Toggle automatic approval for all tool permission requests.", key: "behavior.autoApprove" }),
|
|
890752
|
+
settingAction({ id: "permissions-read", label: "File reads", detail: "Cycle allow, prompt, or deny for file read operations.", key: "permissions.tools.read" }),
|
|
890753
|
+
settingAction({ id: "permissions-find", label: "File search", detail: "Cycle allow, prompt, or deny for file and directory search operations.", key: "permissions.tools.find" }),
|
|
890598
890754
|
settingAction({ id: "permissions-write", label: "File writes", detail: "Cycle allow, prompt, or deny for file write operations.", key: "permissions.tools.write" }),
|
|
890599
890755
|
settingAction({ id: "permissions-edit", label: "File edits", detail: "Cycle allow, prompt, or deny for edit and patch operations.", key: "permissions.tools.edit" }),
|
|
890600
890756
|
settingAction({ id: "permissions-exec", label: "Shell commands", detail: "Cycle allow, prompt, or deny for shell execution.", key: "permissions.tools.exec" }),
|
|
890601
890757
|
settingAction({ id: "permissions-fetch", label: "Network fetches", detail: "Cycle allow, prompt, or deny for outbound fetch requests.", key: "permissions.tools.fetch" }),
|
|
890758
|
+
settingAction({ id: "permissions-analyze", label: "Code analysis", detail: "Cycle allow, prompt, or deny for code and project analysis operations.", key: "permissions.tools.analyze" }),
|
|
890759
|
+
settingAction({ id: "permissions-inspect", label: "Runtime inspect", detail: "Cycle allow, prompt, or deny for runtime state inspection.", key: "permissions.tools.inspect" }),
|
|
890760
|
+
settingAction({ id: "permissions-state", label: "State reads", detail: "Cycle allow, prompt, or deny for reading runtime and session state.", key: "permissions.tools.state" }),
|
|
890761
|
+
settingAction({ id: "permissions-registry", label: "Registry reads", detail: "Cycle allow, prompt, or deny for tool and skill registry queries.", key: "permissions.tools.registry" }),
|
|
890602
890762
|
settingAction({ id: "permissions-mcp", label: "MCP tools", detail: "Cycle allow, prompt, or deny for external MCP tool calls.", key: "permissions.tools.mcp" }),
|
|
890603
890763
|
settingAction({ id: "permissions-agent", label: "Agent delegation", detail: "Cycle allow, prompt, or deny for subagent and delegation operations.", key: "permissions.tools.agent" }),
|
|
890604
890764
|
settingAction({ id: "permissions-workflow", label: "Workflow automation", detail: "Cycle allow, prompt, or deny for multi-step workflow automation.", key: "permissions.tools.workflow" }),
|
|
890765
|
+
settingAction({ id: "permissions-delegate", label: "Unknown tools", detail: "Cycle allow, prompt, or deny for unknown or unregistered tools.", key: "permissions.tools.delegate" }),
|
|
890605
890766
|
{ id: "onboarding-mcp-server", label: "Add MCP server", detail: "Add or update one MCP server with command, args, role, trust, env refs, paths, and hosts.", editorKind: "mcp-server", kind: "editor", safety: "safe" },
|
|
890606
890767
|
{ id: "onboarding-secret-link", label: "Link secret reference", detail: "Link one config key to a goodvibes secret reference.", editorKind: "secret-link", kind: "editor", safety: "safe" },
|
|
890607
|
-
{ id: "onboarding-secret-test", label: "Test secret reference", detail: "Check one stored secret reference without printing the value.", editorKind: "secret-test", kind: "editor", safety: "safe" }
|
|
890768
|
+
{ id: "onboarding-secret-test", label: "Test secret reference", detail: "Check one stored secret reference without printing the value.", editorKind: "secret-test", kind: "editor", safety: "safe" },
|
|
890769
|
+
settingAction({ id: "tools-auto-heal", label: "Tool auto-heal", detail: "Toggle automatic syntax repair for precision write and edit operations.", key: "tools.autoHeal" }),
|
|
890770
|
+
settingAction({ id: "tools-token-budget", label: "Tool token budget", detail: "Set the default token budget for precision read operations.", key: "tools.defaultTokenBudget" }),
|
|
890771
|
+
settingAction({ id: "tools-hooks-file", label: "Hooks file", detail: "Set the hook configuration file name relative to host data.", key: "tools.hooksFile" }),
|
|
890772
|
+
settingAction({ id: "storage-artifact-limit", label: "Artifact storage limit", detail: "Set the maximum artifact size for file, URL, multipart, and raw upload ingest.", key: "storage.artifacts.maxBytes" }),
|
|
890773
|
+
settingAction({ id: "telemetry-raw-prompts", label: "Raw prompt telemetry", detail: "Toggle raw prompt and response telemetry; leave off unless debugging locally.", key: "telemetry.includeRawPrompts" })
|
|
890608
890774
|
]
|
|
890609
890775
|
},
|
|
890610
890776
|
{
|
|
890611
890777
|
id: "onboarding-display",
|
|
890612
890778
|
group: "ONBOARDING",
|
|
890613
890779
|
label: "Interface",
|
|
890614
|
-
summary: "Display, streaming,
|
|
890615
|
-
detail: "Use this page to make the terminal readable for
|
|
890780
|
+
summary: "Display, streaming, message placement, and release channel.",
|
|
890781
|
+
detail: "Use this page to make the terminal readable for daily operation.",
|
|
890616
890782
|
actions: [
|
|
890617
890783
|
settingAction({ id: "display-stream", label: "Stream tokens", detail: "Toggle streaming assistant tokens as they arrive.", key: "display.stream" }),
|
|
890618
890784
|
settingAction({ id: "display-theme", label: "Theme", detail: "Set the color theme name.", key: "display.theme" }),
|
|
@@ -890629,18 +890795,20 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890629
890795
|
id: "onboarding-channels",
|
|
890630
890796
|
group: "ONBOARDING",
|
|
890631
890797
|
label: "Messaging",
|
|
890632
|
-
summary: "
|
|
890633
|
-
detail: "
|
|
890798
|
+
summary: "Choose remote channels, then fill only the fields for enabled channels.",
|
|
890799
|
+
detail: "Enable the channels you actually want. Channel credentials and default targets are saved as Agent settings or secret refs.",
|
|
890634
890800
|
actions: [
|
|
890635
|
-
{ id: "onboarding-pair-companion", label: "Pair companion app", detail: "Open the QR pairing view for companion access.", command: "/pair", kind: "command", safety: "safe" },
|
|
890636
890801
|
settingAction({ id: "channel-ntfy-enabled", label: "Use ntfy", detail: "Toggle ntfy notifications and chat routing.", key: "surfaces.ntfy.enabled" }),
|
|
890637
890802
|
settingAction({ id: "channel-ntfy-base-url", label: "ntfy base URL", detail: "Set the ntfy server URL.", key: "surfaces.ntfy.baseUrl", visibleWhenKey: "surfaces.ntfy.enabled", visibleWhenValue: true }),
|
|
890638
890803
|
settingAction({ id: "channel-ntfy-chat-topic", label: "ntfy chat topic", detail: "Set the topic routed into active terminal chat.", key: "surfaces.ntfy.chatTopic", visibleWhenKey: "surfaces.ntfy.enabled", visibleWhenValue: true }),
|
|
890639
890804
|
settingAction({ id: "channel-ntfy-agent-topic", label: "ntfy agent topic", detail: "Set the topic routed to Agent work.", key: "surfaces.ntfy.agentTopic", visibleWhenKey: "surfaces.ntfy.enabled", visibleWhenValue: true }),
|
|
890805
|
+
settingAction({ id: "channel-ntfy-default-topic", label: "ntfy default topic", detail: "Set the default outbound notification topic.", key: "surfaces.ntfy.topic", visibleWhenKey: "surfaces.ntfy.enabled", visibleWhenValue: true }),
|
|
890806
|
+
settingAction({ id: "channel-ntfy-remote-topic", label: "ntfy remote topic", detail: "Set the daemon-owned remote chat topic.", key: "surfaces.ntfy.remoteTopic", visibleWhenKey: "surfaces.ntfy.enabled", visibleWhenValue: true }),
|
|
890640
890807
|
settingAction({ id: "channel-ntfy-token", label: "ntfy token", detail: "Store the ntfy access token or secret reference.", key: "surfaces.ntfy.token", visibleWhenKey: "surfaces.ntfy.enabled", visibleWhenValue: true }),
|
|
890641
890808
|
settingAction({ id: "channel-ntfy-priority", label: "ntfy priority", detail: "Set default ntfy priority from 1 to 5.", key: "surfaces.ntfy.defaultPriority", visibleWhenKey: "surfaces.ntfy.enabled", visibleWhenValue: true }),
|
|
890642
890809
|
settingAction({ id: "channel-slack-enabled", label: "Use Slack", detail: "Toggle Slack adapter configuration.", key: "surfaces.slack.enabled" }),
|
|
890643
890810
|
settingAction({ id: "channel-slack-bot-token", label: "Slack bot token", detail: "Store the Slack bot token or secret reference.", key: "surfaces.slack.botToken", visibleWhenKey: "surfaces.slack.enabled", visibleWhenValue: true }),
|
|
890811
|
+
settingAction({ id: "channel-slack-app-token", label: "Slack app token", detail: "Store the Slack app token or secret reference.", key: "surfaces.slack.appToken", visibleWhenKey: "surfaces.slack.enabled", visibleWhenValue: true }),
|
|
890644
890812
|
settingAction({ id: "channel-slack-signing-secret", label: "Slack signing secret", detail: "Store the Slack signing secret or secret reference.", key: "surfaces.slack.signingSecret", visibleWhenKey: "surfaces.slack.enabled", visibleWhenValue: true }),
|
|
890645
890813
|
settingAction({ id: "channel-slack-default-channel", label: "Slack default channel", detail: "Set the default Slack channel for notifications and replies.", key: "surfaces.slack.defaultChannel", visibleWhenKey: "surfaces.slack.enabled", visibleWhenValue: true }),
|
|
890646
890814
|
settingAction({ id: "channel-slack-workspace", label: "Slack workspace ID", detail: "Set the Slack workspace id for route binding.", key: "surfaces.slack.workspaceId", visibleWhenKey: "surfaces.slack.enabled", visibleWhenValue: true }),
|
|
@@ -890648,49 +890816,67 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890648
890816
|
settingAction({ id: "channel-discord-bot-token", label: "Discord bot token", detail: "Store the Discord bot token or secret reference.", key: "surfaces.discord.botToken", visibleWhenKey: "surfaces.discord.enabled", visibleWhenValue: true }),
|
|
890649
890817
|
settingAction({ id: "channel-discord-application", label: "Discord application ID", detail: "Set the Discord application id.", key: "surfaces.discord.applicationId", visibleWhenKey: "surfaces.discord.enabled", visibleWhenValue: true }),
|
|
890650
890818
|
settingAction({ id: "channel-discord-public-key", label: "Discord public key", detail: "Set the Discord application public key.", key: "surfaces.discord.publicKey", visibleWhenKey: "surfaces.discord.enabled", visibleWhenValue: true }),
|
|
890819
|
+
settingAction({ id: "channel-discord-guild", label: "Discord guild ID", detail: "Set the default Discord guild id.", key: "surfaces.discord.guildId", visibleWhenKey: "surfaces.discord.enabled", visibleWhenValue: true }),
|
|
890651
890820
|
settingAction({ id: "channel-discord-default-channel", label: "Discord default channel", detail: "Set the default Discord channel id.", key: "surfaces.discord.defaultChannelId", visibleWhenKey: "surfaces.discord.enabled", visibleWhenValue: true }),
|
|
890652
890821
|
settingAction({ id: "channel-webhook-enabled", label: "Use webhooks", detail: "Toggle generic webhook delivery.", key: "surfaces.webhook.enabled" }),
|
|
890653
890822
|
settingAction({ id: "channel-webhook-target", label: "Webhook target URL", detail: "Set the default outbound webhook target URL.", key: "surfaces.webhook.defaultTarget", visibleWhenKey: "surfaces.webhook.enabled", visibleWhenValue: true }),
|
|
890654
890823
|
settingAction({ id: "channel-webhook-secret", label: "Webhook secret", detail: "Store the shared webhook secret or secret reference.", key: "surfaces.webhook.secret", visibleWhenKey: "surfaces.webhook.enabled", visibleWhenValue: true }),
|
|
890824
|
+
settingAction({ id: "channel-webhook-timeout", label: "Webhook timeout", detail: "Set outbound webhook timeout in milliseconds.", key: "surfaces.webhook.timeoutMs", visibleWhenKey: "surfaces.webhook.enabled", visibleWhenValue: true }),
|
|
890655
890825
|
settingAction({ id: "channel-telegram-enabled", label: "Use Telegram", detail: "Toggle Telegram bot delivery.", key: "surfaces.telegram.enabled" }),
|
|
890656
890826
|
settingAction({ id: "channel-telegram-bot-token", label: "Telegram bot token", detail: "Store the Telegram bot token or secret reference.", key: "surfaces.telegram.botToken", visibleWhenKey: "surfaces.telegram.enabled", visibleWhenValue: true }),
|
|
890827
|
+
settingAction({ id: "channel-telegram-bot-username", label: "Telegram bot username", detail: "Set the Telegram bot username.", key: "surfaces.telegram.botUsername", visibleWhenKey: "surfaces.telegram.enabled", visibleWhenValue: true }),
|
|
890657
890828
|
settingAction({ id: "channel-telegram-chat", label: "Telegram chat ID", detail: "Set the default Telegram chat, group, or channel id.", key: "surfaces.telegram.defaultChatId", visibleWhenKey: "surfaces.telegram.enabled", visibleWhenValue: true }),
|
|
890658
890829
|
settingAction({ id: "channel-telegram-mode", label: "Telegram mode", detail: "Cycle webhook or polling ingress mode.", key: "surfaces.telegram.mode", visibleWhenKey: "surfaces.telegram.enabled", visibleWhenValue: true }),
|
|
890830
|
+
settingAction({ id: "channel-telegram-webhook-secret", label: "Telegram webhook secret", detail: "Store the Telegram webhook secret or secret reference.", key: "surfaces.telegram.webhookSecret", visibleWhenKey: "surfaces.telegram.enabled", visibleWhenValue: true }),
|
|
890659
890831
|
settingAction({ id: "channel-googlechat-enabled", label: "Use Google Chat", detail: "Toggle Google Chat delivery.", key: "surfaces.googleChat.enabled" }),
|
|
890660
890832
|
settingAction({ id: "channel-googlechat-webhook", label: "Google Chat webhook", detail: "Set the Google Chat webhook or app callback URL.", key: "surfaces.googleChat.webhookUrl", visibleWhenKey: "surfaces.googleChat.enabled", visibleWhenValue: true }),
|
|
890833
|
+
settingAction({ id: "channel-googlechat-space", label: "Google Chat space", detail: "Set the default Google Chat space id.", key: "surfaces.googleChat.spaceId", visibleWhenKey: "surfaces.googleChat.enabled", visibleWhenValue: true }),
|
|
890834
|
+
settingAction({ id: "channel-googlechat-app-id", label: "Google Chat app ID", detail: "Set the Google Chat app id.", key: "surfaces.googleChat.appId", visibleWhenKey: "surfaces.googleChat.enabled", visibleWhenValue: true }),
|
|
890835
|
+
settingAction({ id: "channel-googlechat-verification", label: "Google Chat verification", detail: "Store the Google Chat verification token or secret reference.", key: "surfaces.googleChat.verificationToken", visibleWhenKey: "surfaces.googleChat.enabled", visibleWhenValue: true }),
|
|
890661
890836
|
settingAction({ id: "channel-homeassistant-enabled", label: "Use home automation", detail: "Toggle home automation conversation and event delivery.", key: "surfaces.homeassistant.enabled" }),
|
|
890662
890837
|
settingAction({ id: "channel-homeassistant-url", label: "Home automation URL", detail: "Set the home automation instance URL.", key: "surfaces.homeassistant.instanceUrl", visibleWhenKey: "surfaces.homeassistant.enabled", visibleWhenValue: true }),
|
|
890663
890838
|
settingAction({ id: "channel-homeassistant-token", label: "Home automation token", detail: "Store the home automation access token or secret reference.", key: "surfaces.homeassistant.accessToken", visibleWhenKey: "surfaces.homeassistant.enabled", visibleWhenValue: true }),
|
|
890839
|
+
settingAction({ id: "channel-homeassistant-webhook-secret", label: "Home automation webhook secret", detail: "Store the shared secret used to verify inbound callbacks.", key: "surfaces.homeassistant.webhookSecret", visibleWhenKey: "surfaces.homeassistant.enabled", visibleWhenValue: true }),
|
|
890840
|
+
settingAction({ id: "channel-homeassistant-conversation", label: "Home automation conversation", detail: "Set the default conversation id.", key: "surfaces.homeassistant.defaultConversationId", visibleWhenKey: "surfaces.homeassistant.enabled", visibleWhenValue: true }),
|
|
890841
|
+
settingAction({ id: "channel-homeassistant-device-id", label: "Home automation device ID", detail: "Set the stable device id exposed to the home automation surface.", key: "surfaces.homeassistant.deviceId", visibleWhenKey: "surfaces.homeassistant.enabled", visibleWhenValue: true }),
|
|
890842
|
+
settingAction({ id: "channel-homeassistant-device-name", label: "Home automation device name", detail: "Set the device display name exposed to the home automation surface.", key: "surfaces.homeassistant.deviceName", visibleWhenKey: "surfaces.homeassistant.enabled", visibleWhenValue: true }),
|
|
890843
|
+
settingAction({ id: "channel-homeassistant-event-type", label: "Home automation event type", detail: "Set the event type used for daemon-to-home automation delivery.", key: "surfaces.homeassistant.eventType", visibleWhenKey: "surfaces.homeassistant.enabled", visibleWhenValue: true }),
|
|
890844
|
+
settingAction({ id: "channel-homeassistant-session-ttl", label: "Home automation session TTL", detail: "Set the idle TTL for remote home automation conversation sessions.", key: "surfaces.homeassistant.remoteSessionTtlMs", visibleWhenKey: "surfaces.homeassistant.enabled", visibleWhenValue: true }),
|
|
890664
890845
|
settingAction({ id: "channel-signal-enabled", label: "Use Signal", detail: "Toggle Signal bridge delivery.", key: "surfaces.signal.enabled" }),
|
|
890665
890846
|
settingAction({ id: "channel-signal-bridge", label: "Signal bridge URL", detail: "Set the Signal bridge base URL.", key: "surfaces.signal.bridgeUrl", visibleWhenKey: "surfaces.signal.enabled", visibleWhenValue: true }),
|
|
890847
|
+
settingAction({ id: "channel-signal-account", label: "Signal account", detail: "Set the Signal account id or phone number.", key: "surfaces.signal.account", visibleWhenKey: "surfaces.signal.enabled", visibleWhenValue: true }),
|
|
890848
|
+
settingAction({ id: "channel-signal-token", label: "Signal token", detail: "Store the Signal bridge token or secret reference.", key: "surfaces.signal.token", visibleWhenKey: "surfaces.signal.enabled", visibleWhenValue: true }),
|
|
890666
890849
|
settingAction({ id: "channel-signal-recipient", label: "Signal recipient", detail: "Set the default Signal recipient or group.", key: "surfaces.signal.defaultRecipient", visibleWhenKey: "surfaces.signal.enabled", visibleWhenValue: true }),
|
|
890667
890850
|
settingAction({ id: "channel-whatsapp-enabled", label: "Use WhatsApp", detail: "Toggle WhatsApp delivery.", key: "surfaces.whatsapp.enabled" }),
|
|
890668
890851
|
settingAction({ id: "channel-whatsapp-provider", label: "WhatsApp provider", detail: "Cycle Meta Cloud API or bridge provider mode.", key: "surfaces.whatsapp.provider", visibleWhenKey: "surfaces.whatsapp.enabled", visibleWhenValue: true }),
|
|
890669
890852
|
settingAction({ id: "channel-whatsapp-token", label: "WhatsApp access token", detail: "Store the WhatsApp provider access token or secret reference.", key: "surfaces.whatsapp.accessToken", visibleWhenKey: "surfaces.whatsapp.enabled", visibleWhenValue: true }),
|
|
890853
|
+
settingAction({ id: "channel-whatsapp-phone-id", label: "WhatsApp phone number ID", detail: "Set the WhatsApp phone number id.", key: "surfaces.whatsapp.phoneNumberId", visibleWhenKey: "surfaces.whatsapp.enabled", visibleWhenValue: true }),
|
|
890854
|
+
settingAction({ id: "channel-whatsapp-business-id", label: "WhatsApp business ID", detail: "Set the WhatsApp business account id.", key: "surfaces.whatsapp.businessAccountId", visibleWhenKey: "surfaces.whatsapp.enabled", visibleWhenValue: true }),
|
|
890855
|
+
settingAction({ id: "channel-whatsapp-verify", label: "WhatsApp verify token", detail: "Store the WhatsApp verify token or secret reference.", key: "surfaces.whatsapp.verifyToken", visibleWhenKey: "surfaces.whatsapp.enabled", visibleWhenValue: true }),
|
|
890856
|
+
settingAction({ id: "channel-whatsapp-signing", label: "WhatsApp signing secret", detail: "Store the WhatsApp signing secret or secret reference.", key: "surfaces.whatsapp.signingSecret", visibleWhenKey: "surfaces.whatsapp.enabled", visibleWhenValue: true }),
|
|
890670
890857
|
settingAction({ id: "channel-whatsapp-recipient", label: "WhatsApp recipient", detail: "Set the default WhatsApp recipient or chat id.", key: "surfaces.whatsapp.defaultRecipient", visibleWhenKey: "surfaces.whatsapp.enabled", visibleWhenValue: true }),
|
|
890671
890858
|
settingAction({ id: "channel-imessage-enabled", label: "Use iMessage", detail: "Toggle iMessage bridge delivery.", key: "surfaces.imessage.enabled" }),
|
|
890672
890859
|
settingAction({ id: "channel-imessage-bridge", label: "iMessage bridge URL", detail: "Set the iMessage bridge base URL.", key: "surfaces.imessage.bridgeUrl", visibleWhenKey: "surfaces.imessage.enabled", visibleWhenValue: true }),
|
|
890673
|
-
settingAction({ id: "channel-imessage-
|
|
890674
|
-
{ id: "
|
|
890675
|
-
{ id: "
|
|
890860
|
+
settingAction({ id: "channel-imessage-account", label: "iMessage account", detail: "Set the iMessage account id.", key: "surfaces.imessage.account", visibleWhenKey: "surfaces.imessage.enabled", visibleWhenValue: true }),
|
|
890861
|
+
settingAction({ id: "channel-imessage-token", label: "iMessage token", detail: "Store the iMessage bridge token or secret reference.", key: "surfaces.imessage.token", visibleWhenKey: "surfaces.imessage.enabled", visibleWhenValue: true }),
|
|
890862
|
+
settingAction({ id: "channel-imessage-chat", label: "iMessage chat ID", detail: "Set the default iMessage chat id.", key: "surfaces.imessage.defaultChatId", visibleWhenKey: "surfaces.imessage.enabled", visibleWhenValue: true })
|
|
890676
890863
|
]
|
|
890677
890864
|
},
|
|
890678
890865
|
{
|
|
890679
890866
|
id: "onboarding-voice-media",
|
|
890680
890867
|
group: "ONBOARDING",
|
|
890681
890868
|
label: "Voice & Phone",
|
|
890682
|
-
summary: "Configure
|
|
890683
|
-
detail: "Use this page for
|
|
890869
|
+
summary: "Configure voice controls, spoken output, and SMS or phone-call delivery.",
|
|
890870
|
+
detail: "Use this page for saved voice/TTS settings and telephony credentials. Generating media is available later from Voice & Media.",
|
|
890684
890871
|
actions: [
|
|
890685
890872
|
settingAction({ id: "voice-enabled", label: "Use voice controls", detail: "Toggle the optional local voice control surface.", key: "ui.voiceEnabled" }),
|
|
890686
890873
|
settingAction({ id: "voice-tts-provider", label: "TTS provider", detail: "Set the default text-to-speech provider id.", key: "tts.provider" }),
|
|
890687
890874
|
settingAction({ id: "voice-tts-voice", label: "TTS voice", detail: "Set the default text-to-speech voice id.", key: "tts.voice" }),
|
|
890688
|
-
{ id: "voice-speak-prompt", label: "Try spoken prompt", detail: "Open a prompt form for a spoken assistant reply through configured TTS.", editorKind: "tts-prompt", kind: "editor", safety: "safe" },
|
|
890689
|
-
{ id: "media-attach-image", label: "Attach image", detail: "Attach a local image path and optional prompt to the next assistant turn.", editorKind: "image-input", kind: "editor", safety: "safe" },
|
|
890690
|
-
{ id: "onboarding-media-generate", label: "Generate media", detail: "Generate image or video artifacts through a configured media provider after confirmation.", editorKind: "media-generate", kind: "editor", safety: "safe" },
|
|
890691
890875
|
settingAction({ id: "telephony-enabled", label: "Use telephony", detail: "Toggle SMS, voice call, or telephony bridge delivery.", key: "surfaces.telephony.enabled" }),
|
|
890692
890876
|
settingAction({ id: "telephony-provider", label: "Telephony provider", detail: "Cycle direct provider or bridge mode.", key: "surfaces.telephony.provider", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true }),
|
|
890693
890877
|
settingAction({ id: "telephony-mode", label: "Telephony mode", detail: "Cycle SMS, voice call, or bridge delivery mode.", key: "surfaces.telephony.mode", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true }),
|
|
890878
|
+
settingAction({ id: "telephony-bridge-url", label: "Telephony bridge URL", detail: "Set the telephony bridge base URL.", key: "surfaces.telephony.bridgeUrl", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true }),
|
|
890879
|
+
settingAction({ id: "telephony-token", label: "Telephony bridge token", detail: "Store the telephony bridge token or secret reference.", key: "surfaces.telephony.token", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true }),
|
|
890694
890880
|
settingAction({ id: "telephony-account-sid", label: "Twilio account SID", detail: "Set the Twilio account SID for provider-direct delivery.", key: "surfaces.telephony.accountSid", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true }),
|
|
890695
890881
|
settingAction({ id: "telephony-auth-token", label: "Twilio auth token", detail: "Store the Twilio auth token or secret reference.", key: "surfaces.telephony.authToken", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true }),
|
|
890696
890882
|
settingAction({ id: "telephony-from", label: "Sender phone number", detail: "Set the default caller or sender phone number.", key: "surfaces.telephony.fromNumber", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true }),
|
|
@@ -890702,9 +890888,9 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890702
890888
|
{
|
|
890703
890889
|
id: "onboarding-context",
|
|
890704
890890
|
group: "ONBOARDING",
|
|
890705
|
-
label: "Context",
|
|
890706
|
-
summary: "
|
|
890707
|
-
detail: "Use this page to
|
|
890891
|
+
label: "Local Context",
|
|
890892
|
+
summary: "Create/import memory, personas, skills, routines, notes, and Knowledge.",
|
|
890893
|
+
detail: "Use this page to seed the assistant with durable local context. These forms create Agent-owned records or ingest reviewed sources.",
|
|
890708
890894
|
actions: [
|
|
890709
890895
|
{ id: "context-profile-from-discovered", label: "Profile from discovered files", detail: "Create an isolated Agent profile from reviewed local persona, skill, and routine files.", editorKind: "profile-from-discovered", kind: "editor", safety: "safe" },
|
|
890710
890896
|
{ id: "context-persona-discovery", label: "Import persona files", detail: "Import discovered persona files into the Agent persona registry.", editorKind: "persona-discovery-import", kind: "editor", safety: "safe" },
|
|
@@ -890722,20 +890908,19 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890722
890908
|
]
|
|
890723
890909
|
},
|
|
890724
890910
|
{
|
|
890725
|
-
id: "onboarding-
|
|
890911
|
+
id: "onboarding-automation",
|
|
890726
890912
|
group: "ONBOARDING",
|
|
890727
|
-
label: "
|
|
890728
|
-
summary: "
|
|
890729
|
-
detail: "Use this page to
|
|
890913
|
+
label: "Automation Setup",
|
|
890914
|
+
summary: "Set scheduled work limits for reminders and routines.",
|
|
890915
|
+
detail: "Use this page to enable automation and set bounded run limits. Creating actual reminders and routines remains a separate confirmed action.",
|
|
890730
890916
|
actions: [
|
|
890731
|
-
{ id: "
|
|
890732
|
-
{ id: "
|
|
890733
|
-
{ id: "
|
|
890734
|
-
{ id: "
|
|
890735
|
-
{ id: "
|
|
890736
|
-
{ id: "
|
|
890737
|
-
{ id: "
|
|
890738
|
-
{ id: "verify-knowledge", label: "Knowledge status", detail: "Inspect isolated Agent Knowledge readiness and counts.", command: "/knowledge status", kind: "command", safety: "read-only" }
|
|
890917
|
+
settingAction({ id: "automation-enabled", label: "Use automation", detail: "Toggle the automation subsystem for reminders and scheduled routines.", key: "automation.enabled" }),
|
|
890918
|
+
settingAction({ id: "automation-max-concurrent", label: "Concurrent runs", detail: "Set the maximum automation runs that can execute concurrently.", key: "automation.maxConcurrentRuns", visibleWhenKey: "automation.enabled", visibleWhenValue: true }),
|
|
890919
|
+
settingAction({ id: "automation-history-limit", label: "Run history limit", detail: "Set the number of run history entries retained per automation job.", key: "automation.runHistoryLimit", visibleWhenKey: "automation.enabled", visibleWhenValue: true }),
|
|
890920
|
+
settingAction({ id: "automation-default-timeout", label: "Default timeout", detail: "Set the default automation run timeout in milliseconds.", key: "automation.defaultTimeoutMs", visibleWhenKey: "automation.enabled", visibleWhenValue: true }),
|
|
890921
|
+
settingAction({ id: "automation-catch-up", label: "Catch-up window", detail: "Set how long startup should catch up missed automation runs.", key: "automation.catchUpWindowMinutes", visibleWhenKey: "automation.enabled", visibleWhenValue: true }),
|
|
890922
|
+
settingAction({ id: "automation-failure-cooldown", label: "Failure cooldown", detail: "Set the cooldown after a failed automation run.", key: "automation.failureCooldownMs", visibleWhenKey: "automation.enabled", visibleWhenValue: true }),
|
|
890923
|
+
settingAction({ id: "automation-delete-after-run", label: "Delete one-shot jobs", detail: "Toggle deleting one-shot automation jobs after their first successful run.", key: "automation.deleteAfterRun", visibleWhenKey: "automation.enabled", visibleWhenValue: true })
|
|
890739
890924
|
]
|
|
890740
890925
|
},
|
|
890741
890926
|
{
|
|
@@ -891171,52 +891356,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
891171
891356
|
{ id: "approval-cancel", label: "Cancel request", detail: "Open a confirmed form for cancelling one pending connected-host approval request by id.", editorKind: "approval-cancel", kind: "editor", safety: "safe" }
|
|
891172
891357
|
]
|
|
891173
891358
|
},
|
|
891174
|
-
|
|
891175
|
-
id: "host",
|
|
891176
|
-
group: "OPERATIONS",
|
|
891177
|
-
label: "Connected Host",
|
|
891178
|
-
summary: "Connected-host health, tasks, sessions, channels, and automation.",
|
|
891179
|
-
detail: "Use this workspace to inspect the GoodVibes host surfaces that Agent can see: system health, remote routes, host tasks, sessions, channels, schedules, knowledge, media, MCP, provider auth, support bundles, and telemetry/config posture.",
|
|
891180
|
-
actions: [
|
|
891181
|
-
{ id: "host-overview", label: "Host overview", detail: "Review connected-host, provider, settings, continuity, and Agent health without starting or mutating host work.", command: "/health review", kind: "command", safety: "read-only" },
|
|
891182
|
-
{ id: "host-services", label: "Host services", detail: "Inspect connected-host service readiness, credentials, and integration issues without changing them.", command: "/health host", kind: "command", safety: "read-only" },
|
|
891183
|
-
{ id: "host-setup", label: "Setup review", detail: "Inspect setup issues that affect connected-host and Agent runtime readiness.", command: "/health setup", kind: "command", safety: "read-only" },
|
|
891184
|
-
{ id: "host-remote", label: "Remote routes", detail: "Inspect remote build-host route health and recovery signals without starting build work.", command: "/health remote", kind: "command", safety: "read-only" },
|
|
891185
|
-
{ id: "host-maintenance", label: "Session maintenance", detail: "Review continuity, compaction, and current-session maintenance posture.", command: "/health maintenance", kind: "command", safety: "read-only" },
|
|
891186
|
-
{ id: "host-continuity", label: "Continuity", detail: "Inspect last-session pointer, recovery-file posture, and return-context state.", command: "/health continuity", kind: "command", safety: "read-only" },
|
|
891187
|
-
{ id: "host-tasks", label: "Host tasks", detail: "Inspect connected-host task state without creating, retrying, or mutating tasks.", command: "/tasks list", kind: "command", safety: "read-only" },
|
|
891188
|
-
{ id: "host-task-filter", label: "Filter host tasks", detail: "Open a status/type form for read-only connected-host task filtering.", editorKind: "task-list-filter", kind: "editor", safety: "read-only" },
|
|
891189
|
-
{ id: "host-task-show", label: "Inspect host task", detail: "Open a task-id form for read-only connected-host task metadata.", editorKind: "task-show", kind: "editor", safety: "read-only" },
|
|
891190
|
-
{ id: "host-task-output", label: "Show task output", detail: "Open a task-id form for read-only connected-host task output.", editorKind: "task-output", kind: "editor", safety: "read-only" },
|
|
891191
|
-
{ id: "host-sessions", label: "Host session routes", detail: "Browse saved Agent sessions and return-context posture exposed through the runtime session surface.", command: "/session list", kind: "command", safety: "read-only" },
|
|
891192
|
-
{ id: "host-session-graph", label: "Session graph", detail: "Open a read-only form for cross-session graph inspection; graph mutation remains blocked in Agent.", editorKind: "session-graph", kind: "editor", safety: "read-only" },
|
|
891193
|
-
{ id: "host-channels-status", label: "Channel status", detail: "Inspect connected channel runtime status from the host without mutating delivery state.", command: "/channels status", kind: "command", safety: "read-only" },
|
|
891194
|
-
{ id: "host-channel-accounts", label: "Channel accounts", detail: "Inspect connected channel accounts without printing secret values or sending messages.", command: "/channels accounts", kind: "command", safety: "read-only" },
|
|
891195
|
-
{ id: "host-channel-policies", label: "Channel policies", detail: "Inspect channel delivery policy posture without changing routing.", command: "/channels policies", kind: "command", safety: "read-only" },
|
|
891196
|
-
{ id: "host-channels", label: "Open Channels", detail: "Jump to the channel setup and delivery workspace.", targetCategoryId: "channels", kind: "workspace", safety: "safe" },
|
|
891197
|
-
{ id: "host-automation", label: "Open Automation", detail: "Jump to connected schedules, reminders, receipts, and explicit run controls.", targetCategoryId: "automation", kind: "workspace", safety: "safe" },
|
|
891198
|
-
{ id: "host-schedules", label: "Schedule status", detail: "Inspect schedules and run history without running or mutating them.", command: "/schedule list", kind: "command", safety: "read-only" },
|
|
891199
|
-
{ id: "host-schedule-reconcile", label: "Reconcile schedules", detail: "Compare local promotion receipts with live connected schedules.", command: "/schedule reconcile", kind: "command", safety: "read-only" },
|
|
891200
|
-
{ id: "host-knowledge", label: "Knowledge route", detail: "Inspect isolated Agent Knowledge route readiness and source counts.", command: "/knowledge status", kind: "command", safety: "read-only" },
|
|
891201
|
-
{ id: "host-knowledge-open", label: "Open Knowledge", detail: "Jump to Agent Knowledge source, graph, review, and ingest controls.", targetCategoryId: "knowledge", kind: "workspace", safety: "safe" },
|
|
891202
|
-
{ id: "host-media", label: "Media providers", detail: "Inspect configured media providers before generating media with confirmation.", command: "/media providers", kind: "command", safety: "read-only" },
|
|
891203
|
-
{ id: "host-media-open", label: "Open Voice and Media", detail: "Jump to voice, TTS, image input, media provider, and browser-tool setup actions.", targetCategoryId: "voice-media", kind: "workspace", safety: "safe" },
|
|
891204
|
-
{ id: "host-mcp-health", label: "MCP health", detail: "Inspect MCP lifecycle issues without changing trust posture or approving tool-definition review.", command: "/health mcp", kind: "command", safety: "read-only" },
|
|
891205
|
-
{ id: "host-mcp-review", label: "MCP review", detail: "Inspect MCP server connection, trust, role, and review posture.", command: "/mcp review", kind: "command", safety: "read-only" },
|
|
891206
|
-
{ id: "host-tools-open", label: "Open Tools and MCP", detail: "Jump to MCP server setup, tool inventory, secrets, and security review.", targetCategoryId: "tools", kind: "workspace", safety: "safe" },
|
|
891207
|
-
{ id: "host-provider-accounts", label: "Provider accounts", detail: "Review provider account routes, subscription windows, and billing-path safety.", command: "/accounts review", kind: "command", safety: "read-only" },
|
|
891208
|
-
{ id: "host-auth-owner", label: "Connected-host auth owner", detail: "Show that connected-host auth administration belongs to the owning GoodVibes host, not Agent.", command: "/auth local", kind: "command", safety: "read-only" },
|
|
891209
|
-
{ id: "host-auth-review", label: "Provider auth review", detail: "Review provider auth posture without printing token values.", command: "/auth review", kind: "command", safety: "read-only" },
|
|
891210
|
-
{ id: "host-security", label: "Security review", detail: "Inspect token posture, MCP attack paths, policy lint, plugin risk, and incident pressure.", command: "/security review", kind: "command", safety: "read-only" },
|
|
891211
|
-
{ id: "host-trust", label: "Trust review", detail: "Review permission, secret, plugin, and MCP trust posture without exporting bundles or changing trust.", command: "/trust review", kind: "command", safety: "read-only" },
|
|
891212
|
-
{ id: "host-support-bundle-export", label: "Export support bundle", detail: "Export a redacted Agent support bundle from the Host page.", editorKind: "support-bundle-export", kind: "editor", safety: "safe" },
|
|
891213
|
-
{ id: "host-support-bundle-inspect", label: "Inspect support bundle", detail: "Inspect a support bundle before import or sharing.", editorKind: "support-bundle-inspect", kind: "editor", safety: "read-only" },
|
|
891214
|
-
{ id: "host-support-bundle-import", label: "Import support bundle", detail: "Import reviewed, non-redacted config values from a support bundle.", editorKind: "support-bundle-import", kind: "editor", safety: "safe" },
|
|
891215
|
-
{ id: "host-telemetry", label: "Telemetry settings", detail: "Open telemetry payload policy settings for connected-host and Agent observability review.", command: "/config telemetry", kind: "command", safety: "safe" },
|
|
891216
|
-
{ id: "host-config", label: "Control-plane settings", detail: "Open configuration controls for service, channels, tools, automation, provider, and storage posture.", command: "/config", kind: "command", safety: "safe" },
|
|
891217
|
-
{ id: "host-safety", label: "Host mutation policy", detail: "Agent may inspect connected-host surfaces and run explicit confirmed actions, but does not silently create tasks, send channel messages, mutate auth, or start automation.", kind: "guidance", safety: "blocked" }
|
|
891218
|
-
]
|
|
891219
|
-
},
|
|
891359
|
+
AGENT_WORKSPACE_HOST_CATEGORY,
|
|
891220
891360
|
{
|
|
891221
891361
|
id: "automation",
|
|
891222
891362
|
group: "OPERATIONS",
|
|
@@ -891287,6 +891427,9 @@ function searchAgentWorkspaceActions(categories, query2) {
|
|
|
891287
891427
|
action2.command ?? "",
|
|
891288
891428
|
action2.editorKind ?? "",
|
|
891289
891429
|
action2.targetCategoryId ?? "",
|
|
891430
|
+
action2.modelPickerFlow ?? "",
|
|
891431
|
+
action2.modelPickerTarget ?? "",
|
|
891432
|
+
action2.settingsTarget ?? "",
|
|
891290
891433
|
action2.localOperation ?? "",
|
|
891291
891434
|
action2.safety
|
|
891292
891435
|
].join(" ").toLowerCase();
|
|
@@ -891317,6 +891460,9 @@ function scoreActionSearchResult(result2, exactQuery, terms) {
|
|
|
891317
891460
|
score += scoreField(action2.editorKind, terms, exactQuery, 85, 26);
|
|
891318
891461
|
score += scoreField(action2.command, terms, exactQuery, 75, 22);
|
|
891319
891462
|
score += scoreField(action2.label, terms, exactQuery, 65, 18);
|
|
891463
|
+
score += scoreField(action2.modelPickerTarget, terms, exactQuery, 58, 18);
|
|
891464
|
+
score += scoreField(action2.settingsTarget, terms, exactQuery, 58, 18);
|
|
891465
|
+
score += scoreField(action2.modelPickerFlow, terms, exactQuery, 54, 16);
|
|
891320
891466
|
score += scoreField(action2.localOperation, terms, exactQuery, 50, 16);
|
|
891321
891467
|
score += scoreField(action2.targetCategoryId, terms, exactQuery, 40, 12);
|
|
891322
891468
|
score += scoreField(action2.detail, terms, exactQuery, 24, 6);
|
|
@@ -895422,6 +895568,163 @@ function handleMcpWorkspaceToken(workspace, token, handleEscape2, requestRender)
|
|
|
895422
895568
|
return true;
|
|
895423
895569
|
}
|
|
895424
895570
|
|
|
895571
|
+
// src/input/agent-workspace-requirements.ts
|
|
895572
|
+
function buildAgentWorkspaceRequirements(readField) {
|
|
895573
|
+
return buildAgentSkillRequirements({
|
|
895574
|
+
env: splitList5(readField("requiresEnv")),
|
|
895575
|
+
commands: splitList5(readField("requiresCommands"))
|
|
895576
|
+
});
|
|
895577
|
+
}
|
|
895578
|
+
|
|
895579
|
+
// src/input/agent-workspace-local-editor-submission.ts
|
|
895580
|
+
function submitAgentWorkspaceLocalRegistryEditor(shellPaths3, editor, callbacks) {
|
|
895581
|
+
const field = callbacks.readField;
|
|
895582
|
+
if (editor.mode === "delete") {
|
|
895583
|
+
callbacks.submitDeleteEditor();
|
|
895584
|
+
return;
|
|
895585
|
+
}
|
|
895586
|
+
if (editor.kind === "learned-behavior") {
|
|
895587
|
+
const created = createAgentWorkspaceLearnedBehavior(shellPaths3, {
|
|
895588
|
+
target: callbacks.learnedBehaviorTarget(),
|
|
895589
|
+
name: field("name"),
|
|
895590
|
+
description: field("description"),
|
|
895591
|
+
notes: field("notes"),
|
|
895592
|
+
tags: splitList5(field("tags")),
|
|
895593
|
+
triggers: splitList5(field("triggers")),
|
|
895594
|
+
enable: isAffirmative15(field("enable"))
|
|
895595
|
+
});
|
|
895596
|
+
callbacks.finishLocalEditor(created.kind, created.id, created.name, "Created");
|
|
895597
|
+
} else if (editor.kind === "profile") {
|
|
895598
|
+
const template = field("template");
|
|
895599
|
+
const templateId = template && template.toLowerCase() !== "none" ? template : undefined;
|
|
895600
|
+
const profile5 = createAgentRuntimeProfile(shellPaths3.homeDirectory, field("name"), {
|
|
895601
|
+
...templateId ? { templateId } : {}
|
|
895602
|
+
});
|
|
895603
|
+
callbacks.finishProfileEditor(profile5);
|
|
895604
|
+
} else if (editor.kind === "note") {
|
|
895605
|
+
submitNoteEditor(shellPaths3, editor, field, callbacks.finishLocalEditor);
|
|
895606
|
+
} else if (editor.kind === "persona") {
|
|
895607
|
+
submitPersonaEditor(shellPaths3, editor, field, callbacks.finishLocalEditor);
|
|
895608
|
+
} else if (editor.kind === "skill") {
|
|
895609
|
+
submitSkillEditor(shellPaths3, editor, field, callbacks.finishLocalEditor);
|
|
895610
|
+
} else {
|
|
895611
|
+
submitRoutineEditor(shellPaths3, editor, field, callbacks.finishLocalEditor);
|
|
895612
|
+
}
|
|
895613
|
+
}
|
|
895614
|
+
function submitNoteEditor(shellPaths3, editor, field, finish) {
|
|
895615
|
+
const registry5 = AgentNoteRegistry.fromShellPaths(shellPaths3);
|
|
895616
|
+
if (editor.mode === "update" && editor.recordId) {
|
|
895617
|
+
const updated = registry5.update(editor.recordId, {
|
|
895618
|
+
title: field("title"),
|
|
895619
|
+
body: field("body"),
|
|
895620
|
+
sourceUrl: field("sourceUrl"),
|
|
895621
|
+
tags: splitList5(field("tags")),
|
|
895622
|
+
provenance: "Workspace"
|
|
895623
|
+
});
|
|
895624
|
+
finish("note", updated.id, updated.title, "Updated");
|
|
895625
|
+
return;
|
|
895626
|
+
}
|
|
895627
|
+
const created = registry5.create({
|
|
895628
|
+
title: field("title"),
|
|
895629
|
+
body: field("body"),
|
|
895630
|
+
sourceUrl: field("sourceUrl"),
|
|
895631
|
+
tags: splitList5(field("tags")),
|
|
895632
|
+
source: "user",
|
|
895633
|
+
provenance: "Workspace"
|
|
895634
|
+
});
|
|
895635
|
+
finish("note", created.id, created.title, "Created");
|
|
895636
|
+
}
|
|
895637
|
+
function submitPersonaEditor(shellPaths3, editor, field, finish) {
|
|
895638
|
+
const registry5 = AgentPersonaRegistry.fromShellPaths(shellPaths3);
|
|
895639
|
+
if (editor.mode === "update" && editor.recordId) {
|
|
895640
|
+
const wasActive = registry5.snapshot().activePersonaId === editor.recordId;
|
|
895641
|
+
const updated = registry5.update(editor.recordId, {
|
|
895642
|
+
name: field("name"),
|
|
895643
|
+
description: field("description"),
|
|
895644
|
+
body: field("body"),
|
|
895645
|
+
tags: splitList5(field("tags")),
|
|
895646
|
+
triggers: splitList5(field("triggers")),
|
|
895647
|
+
provenance: "Workspace"
|
|
895648
|
+
});
|
|
895649
|
+
if (isAffirmative15(field("activate")))
|
|
895650
|
+
registry5.setActive(updated.id);
|
|
895651
|
+
else if (wasActive)
|
|
895652
|
+
registry5.clearActive();
|
|
895653
|
+
finish("persona", updated.id, updated.name, "Updated");
|
|
895654
|
+
return;
|
|
895655
|
+
}
|
|
895656
|
+
const created = registry5.create({
|
|
895657
|
+
name: field("name"),
|
|
895658
|
+
description: field("description"),
|
|
895659
|
+
body: field("body"),
|
|
895660
|
+
tags: splitList5(field("tags")),
|
|
895661
|
+
triggers: splitList5(field("triggers")),
|
|
895662
|
+
source: "user",
|
|
895663
|
+
provenance: "Workspace"
|
|
895664
|
+
});
|
|
895665
|
+
if (isAffirmative15(field("activate")))
|
|
895666
|
+
registry5.setActive(created.id);
|
|
895667
|
+
finish("persona", created.id, created.name, "Created");
|
|
895668
|
+
}
|
|
895669
|
+
function submitSkillEditor(shellPaths3, editor, field, finish) {
|
|
895670
|
+
const registry5 = AgentSkillRegistry.fromShellPaths(shellPaths3);
|
|
895671
|
+
if (editor.mode === "update" && editor.recordId) {
|
|
895672
|
+
const updated = registry5.update(editor.recordId, {
|
|
895673
|
+
name: field("name"),
|
|
895674
|
+
description: field("description"),
|
|
895675
|
+
procedure: field("procedure"),
|
|
895676
|
+
triggers: splitList5(field("triggers")),
|
|
895677
|
+
tags: splitList5(field("tags")),
|
|
895678
|
+
requirements: buildAgentWorkspaceRequirements(field),
|
|
895679
|
+
provenance: "Workspace"
|
|
895680
|
+
});
|
|
895681
|
+
registry5.setEnabled(updated.id, isAffirmative15(field("enabled")));
|
|
895682
|
+
finish("skill", updated.id, updated.name, "Updated");
|
|
895683
|
+
return;
|
|
895684
|
+
}
|
|
895685
|
+
const created = registry5.create({
|
|
895686
|
+
name: field("name"),
|
|
895687
|
+
description: field("description"),
|
|
895688
|
+
procedure: field("procedure"),
|
|
895689
|
+
triggers: splitList5(field("triggers")),
|
|
895690
|
+
tags: splitList5(field("tags")),
|
|
895691
|
+
requirements: buildAgentWorkspaceRequirements(field),
|
|
895692
|
+
enabled: isAffirmative15(field("enabled")),
|
|
895693
|
+
source: "user",
|
|
895694
|
+
provenance: "Workspace"
|
|
895695
|
+
});
|
|
895696
|
+
finish("skill", created.id, created.name, "Created");
|
|
895697
|
+
}
|
|
895698
|
+
function submitRoutineEditor(shellPaths3, editor, field, finish) {
|
|
895699
|
+
const registry5 = AgentRoutineRegistry.fromShellPaths(shellPaths3);
|
|
895700
|
+
if (editor.mode === "update" && editor.recordId) {
|
|
895701
|
+
const updated = registry5.update(editor.recordId, {
|
|
895702
|
+
name: field("name"),
|
|
895703
|
+
description: field("description"),
|
|
895704
|
+
steps: field("steps"),
|
|
895705
|
+
triggers: splitList5(field("triggers")),
|
|
895706
|
+
tags: splitList5(field("tags")),
|
|
895707
|
+
requirements: buildAgentWorkspaceRequirements(field),
|
|
895708
|
+
provenance: "Workspace"
|
|
895709
|
+
});
|
|
895710
|
+
registry5.setEnabled(updated.id, isAffirmative15(field("enabled")));
|
|
895711
|
+
finish("routine", updated.id, updated.name, "Updated");
|
|
895712
|
+
return;
|
|
895713
|
+
}
|
|
895714
|
+
const created = registry5.create({
|
|
895715
|
+
name: field("name"),
|
|
895716
|
+
description: field("description"),
|
|
895717
|
+
steps: field("steps"),
|
|
895718
|
+
triggers: splitList5(field("triggers")),
|
|
895719
|
+
tags: splitList5(field("tags")),
|
|
895720
|
+
requirements: buildAgentWorkspaceRequirements(field),
|
|
895721
|
+
enabled: isAffirmative15(field("enabled")),
|
|
895722
|
+
source: "user",
|
|
895723
|
+
provenance: "Workspace"
|
|
895724
|
+
});
|
|
895725
|
+
finish("routine", created.id, created.name, "Created");
|
|
895726
|
+
}
|
|
895727
|
+
|
|
895425
895728
|
// src/input/agent-workspace-local-selection.ts
|
|
895426
895729
|
function agentWorkspaceLocalLibraryItems(snapshot2, kind2) {
|
|
895427
895730
|
if (kind2 === "memory")
|
|
@@ -895782,14 +896085,6 @@ function selectAgentWorkspaceCategory(host, categoryIdOrLabel) {
|
|
|
895782
896085
|
return true;
|
|
895783
896086
|
}
|
|
895784
896087
|
|
|
895785
|
-
// src/input/agent-workspace-requirements.ts
|
|
895786
|
-
function buildAgentWorkspaceRequirements(readField) {
|
|
895787
|
-
return buildAgentSkillRequirements({
|
|
895788
|
-
env: splitList5(readField("requiresEnv")),
|
|
895789
|
-
commands: splitList5(readField("requiresCommands"))
|
|
895790
|
-
});
|
|
895791
|
-
}
|
|
895792
|
-
|
|
895793
896088
|
// src/input/agent-workspace-settings.ts
|
|
895794
896089
|
import { existsSync as existsSync87, readFileSync as readFileSync94 } from "fs";
|
|
895795
896090
|
var GOODVIBES_TUI_SURFACE_ROOT = "tui";
|
|
@@ -895831,6 +896126,62 @@ function canImportTuiSetting(key) {
|
|
|
895831
896126
|
function valuesMatch(left, right) {
|
|
895832
896127
|
return JSON.stringify(left) === JSON.stringify(right);
|
|
895833
896128
|
}
|
|
896129
|
+
function readRecordMap(record2, key) {
|
|
896130
|
+
const value = record2[key];
|
|
896131
|
+
return isRecord45(value) ? Object.values(value) : [];
|
|
896132
|
+
}
|
|
896133
|
+
function isProviderSubscription(value) {
|
|
896134
|
+
return isRecord45(value) && typeof value.provider === "string" && typeof value.accessToken === "string" && typeof value.tokenType === "string" && value.authMode === "oauth" && typeof value.overrideAmbientApiKeys === "boolean" && typeof value.createdAt === "number" && typeof value.updatedAt === "number";
|
|
896135
|
+
}
|
|
896136
|
+
function isPendingSubscriptionLogin(value) {
|
|
896137
|
+
return isRecord45(value) && typeof value.provider === "string" && typeof value.state === "string" && typeof value.verifier === "string" && typeof value.redirectUri === "string" && typeof value.createdAt === "number";
|
|
896138
|
+
}
|
|
896139
|
+
function importTuiSubscriptions(context, parseErrors) {
|
|
896140
|
+
const shellPaths3 = context.workspace.shellPaths;
|
|
896141
|
+
const manager5 = context.platform.subscriptionManager;
|
|
896142
|
+
const result2 = {
|
|
896143
|
+
importedActive: [],
|
|
896144
|
+
importedPending: [],
|
|
896145
|
+
unchangedActive: [],
|
|
896146
|
+
unchangedPending: [],
|
|
896147
|
+
skipped: []
|
|
896148
|
+
};
|
|
896149
|
+
if (!shellPaths3 || !manager5)
|
|
896150
|
+
return result2;
|
|
896151
|
+
const sourcePath = shellPaths3.resolveUserPath(GOODVIBES_TUI_SURFACE_ROOT, "subscriptions.json");
|
|
896152
|
+
try {
|
|
896153
|
+
const store2 = readJsonRecord(sourcePath);
|
|
896154
|
+
if (!store2)
|
|
896155
|
+
return result2;
|
|
896156
|
+
for (const entry of readRecordMap(store2, "subscriptions")) {
|
|
896157
|
+
if (!isProviderSubscription(entry)) {
|
|
896158
|
+
result2.skipped.push("active subscription with invalid shape");
|
|
896159
|
+
continue;
|
|
896160
|
+
}
|
|
896161
|
+
if (valuesMatch(manager5.get(entry.provider), entry)) {
|
|
896162
|
+
result2.unchangedActive.push(entry.provider);
|
|
896163
|
+
continue;
|
|
896164
|
+
}
|
|
896165
|
+
manager5.saveSubscription(entry);
|
|
896166
|
+
result2.importedActive.push(entry.provider);
|
|
896167
|
+
}
|
|
896168
|
+
for (const entry of readRecordMap(store2, "pending")) {
|
|
896169
|
+
if (!isPendingSubscriptionLogin(entry)) {
|
|
896170
|
+
result2.skipped.push("pending subscription with invalid shape");
|
|
896171
|
+
continue;
|
|
896172
|
+
}
|
|
896173
|
+
if (valuesMatch(manager5.getPending(entry.provider), entry)) {
|
|
896174
|
+
result2.unchangedPending.push(entry.provider);
|
|
896175
|
+
continue;
|
|
896176
|
+
}
|
|
896177
|
+
manager5.savePending(entry);
|
|
896178
|
+
result2.importedPending.push(entry.provider);
|
|
896179
|
+
}
|
|
896180
|
+
} catch (error53) {
|
|
896181
|
+
parseErrors.push(`subscriptions: ${error53 instanceof Error ? error53.message : String(error53)}`);
|
|
896182
|
+
}
|
|
896183
|
+
return result2;
|
|
896184
|
+
}
|
|
895834
896185
|
function agentWorkspaceSettingSchema(context, key) {
|
|
895835
896186
|
return context?.platform?.configManager?.getSchema().find((setting) => setting.key === key) ?? null;
|
|
895836
896187
|
}
|
|
@@ -895934,7 +896285,7 @@ async function applyAgentWorkspaceSettingValue(context, setting, value) {
|
|
|
895934
896285
|
async function importAgentWorkspaceTuiSettings(context) {
|
|
895935
896286
|
const shellPaths3 = context?.workspace?.shellPaths;
|
|
895936
896287
|
const configManager = context?.platform?.configManager;
|
|
895937
|
-
if (!shellPaths3 || !configManager) {
|
|
896288
|
+
if (!context || !shellPaths3 || !configManager) {
|
|
895938
896289
|
return {
|
|
895939
896290
|
status: "GoodVibes TUI settings import is unavailable in this runtime.",
|
|
895940
896291
|
runtimeSnapshot: null,
|
|
@@ -895968,8 +896319,11 @@ async function importAgentWorkspaceTuiSettings(context) {
|
|
|
895968
896319
|
parseErrors.push(`${source.label}: ${error53 instanceof Error ? error53.message : String(error53)}`);
|
|
895969
896320
|
}
|
|
895970
896321
|
}
|
|
895971
|
-
|
|
895972
|
-
|
|
896322
|
+
const subscriptions = importTuiSubscriptions(context, parseErrors);
|
|
896323
|
+
const subscriptionImports = subscriptions.importedActive.length + subscriptions.importedPending.length;
|
|
896324
|
+
const subscriptionUnchanged = subscriptions.unchangedActive.length + subscriptions.unchangedPending.length;
|
|
896325
|
+
if (values2.size === 0 && subscriptionImports === 0 && subscriptionUnchanged === 0 && subscriptions.skipped.length === 0) {
|
|
896326
|
+
const detail = parseErrors.length > 0 ? `No importable settings or subscriptions found. ${parseErrors.join("; ")}` : "No GoodVibes TUI settings or subscription store with importable Agent-owned state was found.";
|
|
895973
896327
|
return {
|
|
895974
896328
|
status: "No GoodVibes TUI settings imported.",
|
|
895975
896329
|
runtimeSnapshot: null,
|
|
@@ -895999,15 +896353,20 @@ async function importAgentWorkspaceTuiSettings(context) {
|
|
|
895999
896353
|
skipped.push(`${setting.key}: ${error53 instanceof Error ? error53.message : String(error53)}`);
|
|
896000
896354
|
}
|
|
896001
896355
|
}
|
|
896356
|
+
skipped.push(...subscriptions.skipped);
|
|
896357
|
+
const changedCount = imported.length + subscriptionImports;
|
|
896358
|
+
const unchangedCount = unchanged.length + subscriptionUnchanged;
|
|
896002
896359
|
return {
|
|
896003
|
-
status:
|
|
896360
|
+
status: changedCount > 0 ? `Imported ${changedCount} GoodVibes TUI item(s).` : "No GoodVibes TUI settings changed.",
|
|
896004
896361
|
runtimeSnapshot: context ? buildAgentWorkspaceRuntimeSnapshot(context) : null,
|
|
896005
896362
|
result: {
|
|
896006
|
-
kind: skipped.length > 0 &&
|
|
896007
|
-
title:
|
|
896363
|
+
kind: skipped.length > 0 && changedCount === 0 ? "error" : changedCount > 0 ? "refreshed" : "guidance",
|
|
896364
|
+
title: changedCount > 0 ? "GoodVibes TUI settings imported" : "No settings changed",
|
|
896008
896365
|
detail: [
|
|
896009
896366
|
imported.length > 0 ? `Imported: ${imported.slice(0, 10).join(", ")}${imported.length > 10 ? `, +${imported.length - 10} more` : ""}.` : "",
|
|
896010
|
-
|
|
896367
|
+
subscriptions.importedActive.length > 0 ? `Imported active subscription(s): ${subscriptions.importedActive.join(", ")}.` : "",
|
|
896368
|
+
subscriptions.importedPending.length > 0 ? `Imported pending subscription(s): ${subscriptions.importedPending.join(", ")}.` : "",
|
|
896369
|
+
unchangedCount > 0 ? `${unchangedCount} item(s) already matched.` : "",
|
|
896011
896370
|
skipped.length > 0 ? `Skipped: ${skipped.slice(0, 5).join("; ")}${skipped.length > 5 ? `; +${skipped.length - 5} more` : ""}.` : "",
|
|
896012
896371
|
parseErrors.length > 0 ? `Parse issues: ${parseErrors.join("; ")}.` : ""
|
|
896013
896372
|
].filter((line2) => line2.length > 0).join(" "),
|
|
@@ -896037,6 +896396,166 @@ function createSettingEditor(setting, currentValue, action2) {
|
|
|
896037
896396
|
]
|
|
896038
896397
|
};
|
|
896039
896398
|
}
|
|
896399
|
+
|
|
896400
|
+
// src/input/agent-workspace-subscription-editor.ts
|
|
896401
|
+
init_config8();
|
|
896402
|
+
async function submitAgentWorkspaceSubscriptionLoginStartEditor(host, editor, context, readField) {
|
|
896403
|
+
if (!isAffirmative15(readField("confirm"))) {
|
|
896404
|
+
host.localEditor = { ...editor, message: "Subscription login start not confirmed. Type yes, then press Enter." };
|
|
896405
|
+
host.status = "Subscription login start not confirmed.";
|
|
896406
|
+
return;
|
|
896407
|
+
}
|
|
896408
|
+
try {
|
|
896409
|
+
const provider5 = readField("provider") || "openai";
|
|
896410
|
+
const openBrowser2 = isAffirmative15(readField("openBrowser"));
|
|
896411
|
+
const { manager: manager5, services } = subscriptionServices(context);
|
|
896412
|
+
const resolved = getSubscriptionProviderConfig(provider5, services.get(provider5));
|
|
896413
|
+
if (!resolved) {
|
|
896414
|
+
throw new Error(`OAuth is not configured for ${provider5}. Add an OAuth provider service or choose a built-in subscription provider.`);
|
|
896415
|
+
}
|
|
896416
|
+
const started = provider5 === "openai" && resolved.source === "builtin" ? await beginOpenAICodexLogin() : null;
|
|
896417
|
+
const authorizationUrl = started ? started.authorizationUrl : (await manager5.beginOAuthLogin(provider5, resolveManualLoginConfig2(resolved.oauth))).authorizationUrl;
|
|
896418
|
+
if (started) {
|
|
896419
|
+
manager5.savePending({
|
|
896420
|
+
provider: provider5,
|
|
896421
|
+
state: started.state,
|
|
896422
|
+
verifier: started.verifier,
|
|
896423
|
+
redirectUri: started.redirectUri,
|
|
896424
|
+
createdAt: Date.now()
|
|
896425
|
+
});
|
|
896426
|
+
}
|
|
896427
|
+
const browserOpened = openBrowser2 ? await openExternalUrl(authorizationUrl) : false;
|
|
896428
|
+
host.localEditor = null;
|
|
896429
|
+
host.runtimeSnapshot = context ? buildAgentWorkspaceRuntimeSnapshot(context) : host.runtimeSnapshot;
|
|
896430
|
+
host.status = `Subscription login started for ${provider5}.`;
|
|
896431
|
+
host.lastActionResult = {
|
|
896432
|
+
kind: "refreshed",
|
|
896433
|
+
title: "Subscription login started",
|
|
896434
|
+
detail: [
|
|
896435
|
+
`Provider: ${provider5}.`,
|
|
896436
|
+
`Browser: ${openBrowser2 ? browserOpened ? "opened" : "open failed" : "skipped"}.`,
|
|
896437
|
+
"Use Finish subscription login with the callback code or redirect URL.",
|
|
896438
|
+
`Authorization URL: ${authorizationUrl}`
|
|
896439
|
+
].join(" "),
|
|
896440
|
+
safety: "safe"
|
|
896441
|
+
};
|
|
896442
|
+
host.clampSelection();
|
|
896443
|
+
} catch (error53) {
|
|
896444
|
+
const detail = error53 instanceof Error ? error53.message : String(error53);
|
|
896445
|
+
host.localEditor = { ...editor, message: detail };
|
|
896446
|
+
host.status = detail;
|
|
896447
|
+
host.lastActionResult = { kind: "error", title: "Subscription login start failed", detail, safety: "safe" };
|
|
896448
|
+
}
|
|
896449
|
+
}
|
|
896450
|
+
async function submitAgentWorkspaceSubscriptionLoginFinishEditor(host, editor, context, readField) {
|
|
896451
|
+
if (!isAffirmative15(readField("confirm"))) {
|
|
896452
|
+
host.localEditor = { ...editor, message: "Subscription login finish not confirmed. Type yes, then press Enter." };
|
|
896453
|
+
host.status = "Subscription login finish not confirmed.";
|
|
896454
|
+
return;
|
|
896455
|
+
}
|
|
896456
|
+
try {
|
|
896457
|
+
const provider5 = readField("provider") || "openai";
|
|
896458
|
+
const codeInput = readField("code");
|
|
896459
|
+
const code2 = extractAuthorizationCode3(codeInput) ?? codeInput;
|
|
896460
|
+
const { manager: manager5, services } = subscriptionServices(context);
|
|
896461
|
+
const resolved = getSubscriptionProviderConfig(provider5, services.get(provider5));
|
|
896462
|
+
if (!resolved) {
|
|
896463
|
+
throw new Error(`OAuth is not configured for ${provider5}. Start with a configured or built-in subscription provider.`);
|
|
896464
|
+
}
|
|
896465
|
+
const record2 = provider5 === "openai" && resolved.source === "builtin" ? (() => {
|
|
896466
|
+
const pending = manager5.getPending(provider5);
|
|
896467
|
+
if (!pending)
|
|
896468
|
+
throw new Error(`No pending OAuth login for ${provider5}. Start subscription login first.`);
|
|
896469
|
+
return exchangeOpenAICodexCode(code2, pending.verifier).then((token) => {
|
|
896470
|
+
const now5 = Date.now();
|
|
896471
|
+
return manager5.saveSubscription({
|
|
896472
|
+
provider: provider5,
|
|
896473
|
+
accessToken: token.accessToken,
|
|
896474
|
+
tokenType: token.tokenType,
|
|
896475
|
+
...typeof token.refreshToken === "string" && token.refreshToken.length > 0 ? { refreshToken: token.refreshToken } : {},
|
|
896476
|
+
...typeof token.expiresAt === "number" && Number.isFinite(token.expiresAt) ? { expiresAt: token.expiresAt } : {},
|
|
896477
|
+
...token.scopes ? { scopes: token.scopes } : {},
|
|
896478
|
+
authMode: "oauth",
|
|
896479
|
+
overrideAmbientApiKeys: false,
|
|
896480
|
+
createdAt: manager5.get(provider5)?.createdAt ?? now5,
|
|
896481
|
+
updatedAt: now5
|
|
896482
|
+
});
|
|
896483
|
+
});
|
|
896484
|
+
})() : manager5.completeOAuthLogin(provider5, resolveManualLoginConfig2(resolved.oauth), code2);
|
|
896485
|
+
const saved = await record2;
|
|
896486
|
+
host.localEditor = null;
|
|
896487
|
+
host.runtimeSnapshot = context ? buildAgentWorkspaceRuntimeSnapshot(context) : host.runtimeSnapshot;
|
|
896488
|
+
host.status = `Subscription session saved for ${provider5}.`;
|
|
896489
|
+
host.lastActionResult = {
|
|
896490
|
+
kind: "refreshed",
|
|
896491
|
+
title: "Subscription session saved",
|
|
896492
|
+
detail: [
|
|
896493
|
+
`Provider: ${provider5}.`,
|
|
896494
|
+
`Token type: ${saved.tokenType}.`,
|
|
896495
|
+
`Expires: ${saved.expiresAt ? new Date(saved.expiresAt).toISOString() : "n/a"}.`,
|
|
896496
|
+
describeSubscriptionPrecedence(saved)
|
|
896497
|
+
].join(" "),
|
|
896498
|
+
safety: "safe"
|
|
896499
|
+
};
|
|
896500
|
+
host.clampSelection();
|
|
896501
|
+
} catch (error53) {
|
|
896502
|
+
const detail = error53 instanceof Error ? error53.message : String(error53);
|
|
896503
|
+
host.localEditor = { ...editor, message: detail };
|
|
896504
|
+
host.status = detail;
|
|
896505
|
+
host.lastActionResult = { kind: "error", title: "Subscription login finish failed", detail, safety: "safe" };
|
|
896506
|
+
}
|
|
896507
|
+
}
|
|
896508
|
+
function submitAgentWorkspaceSubscriptionLogoutEditor(host, editor, context, readField) {
|
|
896509
|
+
if (!isAffirmative15(readField("confirm"))) {
|
|
896510
|
+
host.localEditor = { ...editor, message: "Subscription logout not confirmed. Type yes, then press Enter." };
|
|
896511
|
+
host.status = "Subscription logout not confirmed.";
|
|
896512
|
+
return;
|
|
896513
|
+
}
|
|
896514
|
+
try {
|
|
896515
|
+
const provider5 = readField("provider") || "openai";
|
|
896516
|
+
const { manager: manager5 } = subscriptionServices(context);
|
|
896517
|
+
const removed = manager5.logout(provider5);
|
|
896518
|
+
host.localEditor = null;
|
|
896519
|
+
host.runtimeSnapshot = context ? buildAgentWorkspaceRuntimeSnapshot(context) : host.runtimeSnapshot;
|
|
896520
|
+
host.status = removed ? `Logged out of ${provider5}.` : `No subscription session existed for ${provider5}.`;
|
|
896521
|
+
host.lastActionResult = {
|
|
896522
|
+
kind: removed ? "refreshed" : "guidance",
|
|
896523
|
+
title: removed ? "Subscription session removed" : "No subscription session found",
|
|
896524
|
+
detail: removed ? `Removed active or pending subscription state for ${provider5}. Ambient API key resolution applies if configured.` : `No active or pending subscription state existed for ${provider5}.`,
|
|
896525
|
+
safety: "safe"
|
|
896526
|
+
};
|
|
896527
|
+
host.clampSelection();
|
|
896528
|
+
} catch (error53) {
|
|
896529
|
+
const detail = error53 instanceof Error ? error53.message : String(error53);
|
|
896530
|
+
host.localEditor = { ...editor, message: detail };
|
|
896531
|
+
host.status = detail;
|
|
896532
|
+
host.lastActionResult = { kind: "error", title: "Subscription logout failed", detail, safety: "safe" };
|
|
896533
|
+
}
|
|
896534
|
+
}
|
|
896535
|
+
function subscriptionServices(context) {
|
|
896536
|
+
const manager5 = context?.platform.subscriptionManager;
|
|
896537
|
+
const services = context?.platform.serviceRegistry;
|
|
896538
|
+
if (!manager5 || !services)
|
|
896539
|
+
throw new Error("Subscription services are unavailable in this runtime.");
|
|
896540
|
+
return { manager: manager5, services };
|
|
896541
|
+
}
|
|
896542
|
+
function extractAuthorizationCode3(input) {
|
|
896543
|
+
const trimmed2 = input.trim();
|
|
896544
|
+
if (!trimmed2)
|
|
896545
|
+
return null;
|
|
896546
|
+
try {
|
|
896547
|
+
const url2 = new URL(trimmed2);
|
|
896548
|
+
return url2.searchParams.get("code");
|
|
896549
|
+
} catch {
|
|
896550
|
+
return null;
|
|
896551
|
+
}
|
|
896552
|
+
}
|
|
896553
|
+
function resolveManualLoginConfig2(config6) {
|
|
896554
|
+
return config6.manualRedirectUri ? { ...config6, redirectUri: config6.manualRedirectUri } : config6;
|
|
896555
|
+
}
|
|
896556
|
+
function describeSubscriptionPrecedence(record2) {
|
|
896557
|
+
return record2.overrideAmbientApiKeys ? "Subscription routing now overrides ambient API keys for this provider." : "Subscription session is stored for subscription-backed flows; ambient API keys are unchanged.";
|
|
896558
|
+
}
|
|
896040
896559
|
// src/input/agent-workspace-token.ts
|
|
896041
896560
|
function handleAgentWorkspaceToken(workspace, token, handleEscape2, requestRender) {
|
|
896042
896561
|
if (!workspace.active)
|
|
@@ -896405,6 +896924,51 @@ class AgentWorkspace {
|
|
|
896405
896924
|
this.lastActionResult = { kind: "error", title: "Onboarding completion failed", detail, safety: "safe" };
|
|
896406
896925
|
}
|
|
896407
896926
|
}
|
|
896927
|
+
openModelPickerAction(action2, requestRender) {
|
|
896928
|
+
const target = action2.modelPickerTarget ?? "main";
|
|
896929
|
+
const opened2 = action2.modelPickerFlow === "model" ? this.context?.openModelPickerWithTarget?.(target) : this.context?.openProviderModelPickerWithTarget?.(target);
|
|
896930
|
+
if (!opened2) {
|
|
896931
|
+
this.status = "Model picker is unavailable.";
|
|
896932
|
+
this.lastActionResult = {
|
|
896933
|
+
kind: "error",
|
|
896934
|
+
title: "Model picker unavailable",
|
|
896935
|
+
detail: "This runtime cannot open the model picker from Agent workspace.",
|
|
896936
|
+
safety: action2.safety
|
|
896937
|
+
};
|
|
896938
|
+
requestRender?.();
|
|
896939
|
+
return;
|
|
896940
|
+
}
|
|
896941
|
+
this.status = `Opening ${action2.label}.`;
|
|
896942
|
+
this.lastActionResult = {
|
|
896943
|
+
kind: "dispatched",
|
|
896944
|
+
title: `Opening ${action2.label}`,
|
|
896945
|
+
detail: "Opened the shared provider/model picker for this setup target.",
|
|
896946
|
+
safety: action2.safety
|
|
896947
|
+
};
|
|
896948
|
+
requestRender?.();
|
|
896949
|
+
}
|
|
896950
|
+
openSettingsModalAction(action2, requestRender) {
|
|
896951
|
+
if (!this.context?.openSettingsModal) {
|
|
896952
|
+
this.status = "Settings are unavailable.";
|
|
896953
|
+
this.lastActionResult = {
|
|
896954
|
+
kind: "error",
|
|
896955
|
+
title: "Settings unavailable",
|
|
896956
|
+
detail: "This runtime cannot open settings from Agent workspace.",
|
|
896957
|
+
safety: action2.safety
|
|
896958
|
+
};
|
|
896959
|
+
requestRender?.();
|
|
896960
|
+
return;
|
|
896961
|
+
}
|
|
896962
|
+
this.context.openSettingsModal(action2.settingsTarget);
|
|
896963
|
+
this.status = `Opening ${action2.label}.`;
|
|
896964
|
+
this.lastActionResult = {
|
|
896965
|
+
kind: "dispatched",
|
|
896966
|
+
title: `Opening ${action2.label}`,
|
|
896967
|
+
detail: "Opened the shared settings surface for this setup area.",
|
|
896968
|
+
safety: action2.safety
|
|
896969
|
+
};
|
|
896970
|
+
requestRender?.();
|
|
896971
|
+
}
|
|
896408
896972
|
applySettingAction(action2, requestRender) {
|
|
896409
896973
|
const effect = buildAgentWorkspaceSettingActionEffect(this.context, action2);
|
|
896410
896974
|
if (effect.kind === "result") {
|
|
@@ -896515,6 +897079,19 @@ class AgentWorkspace {
|
|
|
896515
897079
|
this.status = `${missing.label} is required.`;
|
|
896516
897080
|
return;
|
|
896517
897081
|
}
|
|
897082
|
+
if (editor.kind === "subscription-login-start") {
|
|
897083
|
+
submitAgentWorkspaceSubscriptionLoginStartEditor(this, editor, this.context, (id) => this.editorField(id)).finally(() => requestRender?.());
|
|
897084
|
+
return;
|
|
897085
|
+
}
|
|
897086
|
+
if (editor.kind === "subscription-login-finish") {
|
|
897087
|
+
submitAgentWorkspaceSubscriptionLoginFinishEditor(this, editor, this.context, (id) => this.editorField(id)).finally(() => requestRender?.());
|
|
897088
|
+
return;
|
|
897089
|
+
}
|
|
897090
|
+
if (editor.kind === "subscription-logout") {
|
|
897091
|
+
submitAgentWorkspaceSubscriptionLogoutEditor(this, editor, this.context, (id) => this.editorField(id));
|
|
897092
|
+
requestRender?.();
|
|
897093
|
+
return;
|
|
897094
|
+
}
|
|
896518
897095
|
if (isAgentWorkspaceCommandEditorKind(editor.kind)) {
|
|
896519
897096
|
this.submitCommandEditor(editor);
|
|
896520
897097
|
requestRender?.();
|
|
@@ -896565,138 +897142,13 @@ class AgentWorkspace {
|
|
|
896565
897142
|
return;
|
|
896566
897143
|
}
|
|
896567
897144
|
try {
|
|
896568
|
-
|
|
896569
|
-
this.
|
|
896570
|
-
|
|
896571
|
-
|
|
896572
|
-
|
|
896573
|
-
|
|
896574
|
-
|
|
896575
|
-
name: this.editorField("name"),
|
|
896576
|
-
description: this.editorField("description"),
|
|
896577
|
-
notes: this.editorField("notes"),
|
|
896578
|
-
tags: splitList5(this.editorField("tags")),
|
|
896579
|
-
triggers: splitList5(this.editorField("triggers")),
|
|
896580
|
-
enable: isAffirmative15(this.editorField("enable"))
|
|
896581
|
-
});
|
|
896582
|
-
this.finishLocalEditor(created.kind, created.id, created.name, "Created");
|
|
896583
|
-
} else if (editor.kind === "profile") {
|
|
896584
|
-
const template = this.editorField("template");
|
|
896585
|
-
const templateId = template && template.toLowerCase() !== "none" ? template : undefined;
|
|
896586
|
-
const profile5 = createAgentRuntimeProfile(shellPaths3.homeDirectory, this.editorField("name"), {
|
|
896587
|
-
...templateId ? { templateId } : {}
|
|
896588
|
-
});
|
|
896589
|
-
this.finishProfileEditor(profile5);
|
|
896590
|
-
} else if (editor.kind === "note") {
|
|
896591
|
-
const registry5 = AgentNoteRegistry.fromShellPaths(shellPaths3);
|
|
896592
|
-
if (editor.mode === "update" && editor.recordId) {
|
|
896593
|
-
const updated = registry5.update(editor.recordId, {
|
|
896594
|
-
title: this.editorField("title"),
|
|
896595
|
-
body: this.editorField("body"),
|
|
896596
|
-
sourceUrl: this.editorField("sourceUrl"),
|
|
896597
|
-
tags: splitList5(this.editorField("tags")),
|
|
896598
|
-
provenance: "Workspace"
|
|
896599
|
-
});
|
|
896600
|
-
this.finishLocalEditor(editor.kind, updated.id, updated.title, "Updated");
|
|
896601
|
-
return;
|
|
896602
|
-
}
|
|
896603
|
-
const created = registry5.create({
|
|
896604
|
-
title: this.editorField("title"),
|
|
896605
|
-
body: this.editorField("body"),
|
|
896606
|
-
sourceUrl: this.editorField("sourceUrl"),
|
|
896607
|
-
tags: splitList5(this.editorField("tags")),
|
|
896608
|
-
source: "user",
|
|
896609
|
-
provenance: "Workspace"
|
|
896610
|
-
});
|
|
896611
|
-
this.finishLocalEditor(editor.kind, created.id, created.title, "Created");
|
|
896612
|
-
} else if (editor.kind === "persona") {
|
|
896613
|
-
const registry5 = AgentPersonaRegistry.fromShellPaths(shellPaths3);
|
|
896614
|
-
if (editor.mode === "update" && editor.recordId) {
|
|
896615
|
-
const wasActive = registry5.snapshot().activePersonaId === editor.recordId;
|
|
896616
|
-
const updated = registry5.update(editor.recordId, {
|
|
896617
|
-
name: this.editorField("name"),
|
|
896618
|
-
description: this.editorField("description"),
|
|
896619
|
-
body: this.editorField("body"),
|
|
896620
|
-
tags: splitList5(this.editorField("tags")),
|
|
896621
|
-
triggers: splitList5(this.editorField("triggers")),
|
|
896622
|
-
provenance: "Workspace"
|
|
896623
|
-
});
|
|
896624
|
-
if (isAffirmative15(this.editorField("activate")))
|
|
896625
|
-
registry5.setActive(updated.id);
|
|
896626
|
-
else if (wasActive)
|
|
896627
|
-
registry5.clearActive();
|
|
896628
|
-
this.finishLocalEditor(editor.kind, updated.id, updated.name, "Updated");
|
|
896629
|
-
return;
|
|
896630
|
-
}
|
|
896631
|
-
const created = registry5.create({
|
|
896632
|
-
name: this.editorField("name"),
|
|
896633
|
-
description: this.editorField("description"),
|
|
896634
|
-
body: this.editorField("body"),
|
|
896635
|
-
tags: splitList5(this.editorField("tags")),
|
|
896636
|
-
triggers: splitList5(this.editorField("triggers")),
|
|
896637
|
-
source: "user",
|
|
896638
|
-
provenance: "Workspace"
|
|
896639
|
-
});
|
|
896640
|
-
if (isAffirmative15(this.editorField("activate")))
|
|
896641
|
-
registry5.setActive(created.id);
|
|
896642
|
-
this.finishLocalEditor(editor.kind, created.id, created.name, "Created");
|
|
896643
|
-
} else if (editor.kind === "skill") {
|
|
896644
|
-
const registry5 = AgentSkillRegistry.fromShellPaths(shellPaths3);
|
|
896645
|
-
if (editor.mode === "update" && editor.recordId) {
|
|
896646
|
-
const updated = registry5.update(editor.recordId, {
|
|
896647
|
-
name: this.editorField("name"),
|
|
896648
|
-
description: this.editorField("description"),
|
|
896649
|
-
procedure: this.editorField("procedure"),
|
|
896650
|
-
triggers: splitList5(this.editorField("triggers")),
|
|
896651
|
-
tags: splitList5(this.editorField("tags")),
|
|
896652
|
-
requirements: buildAgentWorkspaceRequirements((id) => this.editorField(id)),
|
|
896653
|
-
provenance: "Workspace"
|
|
896654
|
-
});
|
|
896655
|
-
registry5.setEnabled(updated.id, isAffirmative15(this.editorField("enabled")));
|
|
896656
|
-
this.finishLocalEditor(editor.kind, updated.id, updated.name, "Updated");
|
|
896657
|
-
return;
|
|
896658
|
-
}
|
|
896659
|
-
const created = registry5.create({
|
|
896660
|
-
name: this.editorField("name"),
|
|
896661
|
-
description: this.editorField("description"),
|
|
896662
|
-
procedure: this.editorField("procedure"),
|
|
896663
|
-
triggers: splitList5(this.editorField("triggers")),
|
|
896664
|
-
tags: splitList5(this.editorField("tags")),
|
|
896665
|
-
requirements: buildAgentWorkspaceRequirements((id) => this.editorField(id)),
|
|
896666
|
-
enabled: isAffirmative15(this.editorField("enabled")),
|
|
896667
|
-
source: "user",
|
|
896668
|
-
provenance: "Workspace"
|
|
896669
|
-
});
|
|
896670
|
-
this.finishLocalEditor(editor.kind, created.id, created.name, "Created");
|
|
896671
|
-
} else {
|
|
896672
|
-
const registry5 = AgentRoutineRegistry.fromShellPaths(shellPaths3);
|
|
896673
|
-
if (editor.mode === "update" && editor.recordId) {
|
|
896674
|
-
const updated = registry5.update(editor.recordId, {
|
|
896675
|
-
name: this.editorField("name"),
|
|
896676
|
-
description: this.editorField("description"),
|
|
896677
|
-
steps: this.editorField("steps"),
|
|
896678
|
-
triggers: splitList5(this.editorField("triggers")),
|
|
896679
|
-
tags: splitList5(this.editorField("tags")),
|
|
896680
|
-
requirements: buildAgentWorkspaceRequirements((id) => this.editorField(id)),
|
|
896681
|
-
provenance: "Workspace"
|
|
896682
|
-
});
|
|
896683
|
-
registry5.setEnabled(updated.id, isAffirmative15(this.editorField("enabled")));
|
|
896684
|
-
this.finishLocalEditor(editor.kind, updated.id, updated.name, "Updated");
|
|
896685
|
-
return;
|
|
896686
|
-
}
|
|
896687
|
-
const created = registry5.create({
|
|
896688
|
-
name: this.editorField("name"),
|
|
896689
|
-
description: this.editorField("description"),
|
|
896690
|
-
steps: this.editorField("steps"),
|
|
896691
|
-
triggers: splitList5(this.editorField("triggers")),
|
|
896692
|
-
tags: splitList5(this.editorField("tags")),
|
|
896693
|
-
requirements: buildAgentWorkspaceRequirements((id) => this.editorField(id)),
|
|
896694
|
-
enabled: isAffirmative15(this.editorField("enabled")),
|
|
896695
|
-
source: "user",
|
|
896696
|
-
provenance: "Workspace"
|
|
896697
|
-
});
|
|
896698
|
-
this.finishLocalEditor(editor.kind, created.id, created.name, "Created");
|
|
896699
|
-
}
|
|
897145
|
+
submitAgentWorkspaceLocalRegistryEditor(shellPaths3, editor, {
|
|
897146
|
+
readField: (id) => this.editorField(id),
|
|
897147
|
+
learnedBehaviorTarget: () => this.learnedBehaviorTarget(),
|
|
897148
|
+
submitDeleteEditor: () => this.submitLocalDeleteEditor(shellPaths3, editor),
|
|
897149
|
+
finishLocalEditor: (kind2, id, name51, verb) => this.finishLocalEditor(kind2, id, name51, verb),
|
|
897150
|
+
finishProfileEditor: (profile5) => this.finishProfileEditor(profile5)
|
|
897151
|
+
});
|
|
896700
897152
|
} catch (error53) {
|
|
896701
897153
|
const detail = error53 instanceof Error ? error53.message : String(error53);
|
|
896702
897154
|
this.localEditor = { ...editor, message: detail };
|
|
@@ -898540,6 +898992,17 @@ function handleModalTokenRoutes(state4, token) {
|
|
|
898540
898992
|
}, token)) {
|
|
898541
898993
|
return withState(state4, true);
|
|
898542
898994
|
}
|
|
898995
|
+
if (handleModelPickerToken({
|
|
898996
|
+
modelPicker: state4.modelPicker,
|
|
898997
|
+
modalStack: state4.modalStack,
|
|
898998
|
+
commandContext: state4.commandContext,
|
|
898999
|
+
getViewportHeight: state4.getViewportHeight,
|
|
899000
|
+
requestRender: state4.requestRender,
|
|
899001
|
+
handleEscape: state4.handleEscape,
|
|
899002
|
+
onModelPickerCommit: state4.onModelPickerCommit
|
|
899003
|
+
}, token)) {
|
|
899004
|
+
return withState(state4, true);
|
|
899005
|
+
}
|
|
898543
899006
|
if (handleSettingsModalToken({
|
|
898544
899007
|
settingsModal: state4.settingsModal,
|
|
898545
899008
|
commandContext: state4.commandContext,
|
|
@@ -898592,17 +899055,6 @@ function handleModalTokenRoutes(state4, token) {
|
|
|
898592
899055
|
if (handleHistorySearchToken(historyState, token)) {
|
|
898593
899056
|
return withState(state4, true, historyState);
|
|
898594
899057
|
}
|
|
898595
|
-
if (handleModelPickerToken({
|
|
898596
|
-
modelPicker: state4.modelPicker,
|
|
898597
|
-
modalStack: state4.modalStack,
|
|
898598
|
-
commandContext: state4.commandContext,
|
|
898599
|
-
getViewportHeight: state4.getViewportHeight,
|
|
898600
|
-
requestRender: state4.requestRender,
|
|
898601
|
-
handleEscape: state4.handleEscape,
|
|
898602
|
-
onModelPickerCommit: state4.onModelPickerCommit
|
|
898603
|
-
}, token)) {
|
|
898604
|
-
return withState(state4, true);
|
|
898605
|
-
}
|
|
898606
899058
|
if (handleLiveTailToken({
|
|
898607
899059
|
liveTailModal: state4.liveTailModal,
|
|
898608
899060
|
processModal: state4.processModal,
|
|
@@ -899541,7 +899993,8 @@ class InputHandler {
|
|
|
899541
899993
|
handleCtrlCForHandler(this);
|
|
899542
899994
|
}
|
|
899543
899995
|
modalOpened(name51) {
|
|
899544
|
-
|
|
899996
|
+
const keepAgentWorkspaceUnderlay = name51 === "modelPicker" || name51 === "settings";
|
|
899997
|
+
if (name51 !== "agentWorkspace" && !keepAgentWorkspaceUnderlay && this.agentWorkspace.active) {
|
|
899545
899998
|
this.closeAgentWorkspaceModal();
|
|
899546
899999
|
}
|
|
899547
900000
|
modalOpenedForHandler(this, name51);
|
|
@@ -899904,232 +900357,6 @@ class PermissionPromptUI {
|
|
|
899904
900357
|
}
|
|
899905
900358
|
}
|
|
899906
900359
|
|
|
899907
|
-
// src/renderer/layout-engine.ts
|
|
899908
|
-
function clamp4(value, min2, max2) {
|
|
899909
|
-
return Math.max(min2, Math.min(max2, value));
|
|
899910
|
-
}
|
|
899911
|
-
function createShellLayout(request2) {
|
|
899912
|
-
const width = Math.max(1, request2.width);
|
|
899913
|
-
const height = Math.max(1, request2.height);
|
|
899914
|
-
const headerHeight = clamp4(request2.headerHeight, 0, height);
|
|
899915
|
-
const footerHeight = clamp4(request2.footerHeight, 0, Math.max(0, height - headerHeight));
|
|
899916
|
-
const bodyHeight = Math.max(0, height - headerHeight - footerHeight);
|
|
899917
|
-
const hasPanel = typeof request2.panelWidth === "number" && request2.panelWidth > 0;
|
|
899918
|
-
const safePanelWidth = hasPanel ? clamp4(request2.panelWidth, 1, Math.max(1, width - 2)) : 0;
|
|
899919
|
-
const separatorWidth = hasPanel ? 1 : 0;
|
|
899920
|
-
const conversationWidth = hasPanel ? Math.max(1, width - safePanelWidth - separatorWidth) : width;
|
|
899921
|
-
return {
|
|
899922
|
-
screen: { x: 0, y: 0, width, height },
|
|
899923
|
-
header: { x: 0, y: 0, width, height: headerHeight },
|
|
899924
|
-
body: { x: 0, y: headerHeight, width, height: bodyHeight },
|
|
899925
|
-
footer: { x: 0, y: headerHeight + bodyHeight, width, height: footerHeight },
|
|
899926
|
-
conversation: { x: 0, y: headerHeight, width: conversationWidth, height: bodyHeight },
|
|
899927
|
-
panel: hasPanel ? {
|
|
899928
|
-
x: conversationWidth + separatorWidth,
|
|
899929
|
-
y: headerHeight,
|
|
899930
|
-
width: safePanelWidth,
|
|
899931
|
-
height: bodyHeight
|
|
899932
|
-
} : undefined,
|
|
899933
|
-
separatorX: hasPanel ? conversationWidth : undefined
|
|
899934
|
-
};
|
|
899935
|
-
}
|
|
899936
|
-
function createSplitPaneLayout(totalRows, ratio, options = {}) {
|
|
899937
|
-
const topTabRows = options.topTabRows ?? 1;
|
|
899938
|
-
const bottomTabRows = options.bottomTabRows ?? 1;
|
|
899939
|
-
const separatorRows = options.separatorRows ?? 1;
|
|
899940
|
-
const chromeRows = topTabRows + bottomTabRows + separatorRows;
|
|
899941
|
-
const contentRows = Math.max(0, totalRows - chromeRows);
|
|
899942
|
-
const normalizedRatio = clamp4(ratio, 0.2, 0.8);
|
|
899943
|
-
const topContentRows = contentRows <= 1 ? contentRows : Math.max(1, Math.floor(contentRows * normalizedRatio));
|
|
899944
|
-
const bottomContentRows = contentRows <= 1 ? 0 : Math.max(1, contentRows - topContentRows);
|
|
899945
|
-
return {
|
|
899946
|
-
totalRows,
|
|
899947
|
-
topTabRows,
|
|
899948
|
-
bottomTabRows,
|
|
899949
|
-
separatorRows,
|
|
899950
|
-
topContentRows,
|
|
899951
|
-
bottomContentRows
|
|
899952
|
-
};
|
|
899953
|
-
}
|
|
899954
|
-
|
|
899955
|
-
// src/renderer/process-indicator.ts
|
|
899956
|
-
function truncateToWidth2(text, maxWidth) {
|
|
899957
|
-
let width = 0;
|
|
899958
|
-
let i5 = 0;
|
|
899959
|
-
for (const char of text) {
|
|
899960
|
-
const cw = getDisplayWidth(char);
|
|
899961
|
-
if (width + cw > maxWidth)
|
|
899962
|
-
break;
|
|
899963
|
-
width += cw;
|
|
899964
|
-
i5 += char.length;
|
|
899965
|
-
}
|
|
899966
|
-
return text.slice(0, i5);
|
|
899967
|
-
}
|
|
899968
|
-
function renderProcessIndicator(width, agentCount, toolCount, focused = false, agentProgress) {
|
|
899969
|
-
const total = agentCount + toolCount;
|
|
899970
|
-
const delegationLabel = (count) => `${count} delegation${count !== 1 ? "s" : ""}`;
|
|
899971
|
-
const renderPlainStatus = (text, style) => [UIFactory.stringToLine(` ${text}`, width, style)];
|
|
899972
|
-
const renderFocusedStatus = (text) => {
|
|
899973
|
-
const bg = "#31506f";
|
|
899974
|
-
const fg = "#eefaff";
|
|
899975
|
-
const markerFg = "#7dd3fc";
|
|
899976
|
-
const line2 = UIFactory.stringToLine(" ".repeat(width), width, { fg: "238" });
|
|
899977
|
-
const prefix = `${GLYPHS.navigation.selected} `;
|
|
899978
|
-
const body2 = truncateToWidth2(text, Math.max(0, width - 8));
|
|
899979
|
-
const highlighted = ` ${prefix}${body2} `;
|
|
899980
|
-
const startX = 2;
|
|
899981
|
-
for (let i5 = 0;i5 < highlighted.length && startX + i5 < width - 2; i5++) {
|
|
899982
|
-
const ch = highlighted[i5];
|
|
899983
|
-
const isMarker = i5 < prefix.length + 1;
|
|
899984
|
-
line2[startX + i5].char = ch;
|
|
899985
|
-
line2[startX + i5].fg = isMarker ? markerFg : fg;
|
|
899986
|
-
line2[startX + i5].bg = bg;
|
|
899987
|
-
line2[startX + i5].bold = true;
|
|
899988
|
-
line2[startX + i5].dim = false;
|
|
899989
|
-
}
|
|
899990
|
-
return [line2];
|
|
899991
|
-
};
|
|
899992
|
-
if (focused) {
|
|
899993
|
-
const parts3 = [];
|
|
899994
|
-
if (agentCount > 0)
|
|
899995
|
-
parts3.push(delegationLabel(agentCount));
|
|
899996
|
-
if (toolCount > 0)
|
|
899997
|
-
parts3.push(`${toolCount} tool${toolCount !== 1 ? "s" : ""} running`);
|
|
899998
|
-
const label2 = total === 0 ? `No runtime activity ${GLYPHS.status.pending} back to input` : `${parts3.join(` ${GLYPHS.navigation.pipeSeparator} `)} ${GLYPHS.status.pending} Enter to open ${GLYPHS.status.pending} back to input`;
|
|
899999
|
-
return renderFocusedStatus(label2);
|
|
900000
|
-
}
|
|
900001
|
-
if (total === 0) {
|
|
900002
|
-
return renderPlainStatus("No runtime activity", { fg: "238", dim: true });
|
|
900003
|
-
}
|
|
900004
|
-
const parts2 = [];
|
|
900005
|
-
if (agentCount > 0) {
|
|
900006
|
-
parts2.push(delegationLabel(agentCount));
|
|
900007
|
-
}
|
|
900008
|
-
if (toolCount > 0) {
|
|
900009
|
-
parts2.push(`${toolCount} tool${toolCount !== 1 ? "s" : ""} running`);
|
|
900010
|
-
}
|
|
900011
|
-
const PROGRESS_RESERVED_CHARS = 43;
|
|
900012
|
-
const progressMaxLen = Math.max(0, width - PROGRESS_RESERVED_CHARS);
|
|
900013
|
-
const progressSuffix = agentProgress && progressMaxLen > 10 ? ` | ${agentProgress.length > progressMaxLen ? agentProgress.slice(0, Math.max(0, progressMaxLen - 3)) + "..." : agentProgress}` : "";
|
|
900014
|
-
const label = `${parts2.join(` ${GLYPHS.navigation.pipeSeparator} `)}${progressSuffix}`;
|
|
900015
|
-
const hint = ` ${GLYPHS.status.pending} Enter to view`;
|
|
900016
|
-
return renderPlainStatus(`${label}${hint}`, { fg: "#00ffff", bold: true });
|
|
900017
|
-
}
|
|
900018
|
-
|
|
900019
|
-
// src/renderer/shell-surface.ts
|
|
900020
|
-
var FOOTER_BASE_ROWS = 9;
|
|
900021
|
-
var CONTEXT_PROGRESS_ROWS = 2;
|
|
900022
|
-
var PROCESS_INDICATOR_ROWS = 1;
|
|
900023
|
-
function estimateShellFooterHeight(promptLineCount, contextWindow) {
|
|
900024
|
-
const safePromptLines = Math.max(1, promptLineCount);
|
|
900025
|
-
const progressRows = contextWindow && contextWindow > 0 ? CONTEXT_PROGRESS_ROWS : 0;
|
|
900026
|
-
return FOOTER_BASE_ROWS + safePromptLines + progressRows + PROCESS_INDICATOR_ROWS;
|
|
900027
|
-
}
|
|
900028
|
-
function buildShellFooter(options) {
|
|
900029
|
-
const lines = UIFactory.createFooter(options.width, options.promptText, options.usage, options.showExitNotice, options.lastCopyTime, options.model, options.toolCount, options.promptCursorPos, options.workingDir, options.provider, options.contextWindow, options.compactThreshold, options.dangerMode, options.lastInputTokens, options.commandArgsHint, options.hitlMode, options.promptFocused ?? !options.indicatorFocused, options.composerMode, options.composerStatus, options.composerFlags, options.composerPendingRisk);
|
|
900030
|
-
const processIndicator = renderProcessIndicator(options.width, options.runningAgentCount, options.runningProcessCount, options.indicatorFocused, options.runningAgentProgress);
|
|
900031
|
-
const inputBoxRows = Math.max(1, options.promptLineCount) + 2;
|
|
900032
|
-
lines.splice(inputBoxRows, 0, ...processIndicator);
|
|
900033
|
-
return { lines, height: lines.length };
|
|
900034
|
-
}
|
|
900035
|
-
|
|
900036
|
-
// src/renderer/conversation-layout.ts
|
|
900037
|
-
function buildConversationViewport(request2) {
|
|
900038
|
-
const overlayRows = request2.overlayRows ?? 0;
|
|
900039
|
-
const effectiveHeight = Math.max(0, request2.viewportHeight - overlayRows);
|
|
900040
|
-
const lineCount = request2.conversation.history.getLineCount();
|
|
900041
|
-
const maxScroll = Math.max(0, lineCount - effectiveHeight);
|
|
900042
|
-
const nextScrollTop = request2.scrollLocked ? maxScroll : Math.max(0, Math.min(request2.scrollTop, maxScroll));
|
|
900043
|
-
const viewport = request2.conversation.history.getSnapshot(nextScrollTop, effectiveHeight, request2.width);
|
|
900044
|
-
return {
|
|
900045
|
-
effectiveHeight,
|
|
900046
|
-
maxScroll,
|
|
900047
|
-
nextScrollTop,
|
|
900048
|
-
viewport
|
|
900049
|
-
};
|
|
900050
|
-
}
|
|
900051
|
-
function overlayViewportBottom(viewport, overlay, width, viewportHeight, bottomInset = 0) {
|
|
900052
|
-
if (overlay.length === 0)
|
|
900053
|
-
return [...viewport];
|
|
900054
|
-
const next = [...viewport];
|
|
900055
|
-
const targetStart = Math.max(0, viewportHeight - bottomInset - overlay.length);
|
|
900056
|
-
next.length = Math.min(next.length, targetStart);
|
|
900057
|
-
while (next.length < targetStart)
|
|
900058
|
-
next.push(createEmptyLine(width));
|
|
900059
|
-
next.push(...overlay);
|
|
900060
|
-
return next;
|
|
900061
|
-
}
|
|
900062
|
-
function replaceViewportWithOverlay(overlay, width, viewportHeight) {
|
|
900063
|
-
const next = [];
|
|
900064
|
-
const pad = Math.max(0, viewportHeight - overlay.length);
|
|
900065
|
-
for (let i5 = 0;i5 < pad; i5++)
|
|
900066
|
-
next.push(createEmptyLine(width));
|
|
900067
|
-
next.push(...overlay);
|
|
900068
|
-
return next;
|
|
900069
|
-
}
|
|
900070
|
-
|
|
900071
|
-
// src/renderer/file-picker-overlay.ts
|
|
900072
|
-
var FILE_PICKER_TITLE = "Select File";
|
|
900073
|
-
var FILE_PICKER_SEARCH_PREFIX = "@ ";
|
|
900074
|
-
var FILE_PICKER_EMPTY_MESSAGE = "No matching files";
|
|
900075
|
-
var FILE_PICKER_HINTS = "[Up/Down] Navigate [/] Search [Enter] Select [Esc] Cancel";
|
|
900076
|
-
function renderFilePickerOverlay(picker, width, viewportHeight = 24) {
|
|
900077
|
-
const lines = [];
|
|
900078
|
-
const metrics = getOverlaySurfaceMetrics(width, viewportHeight, {
|
|
900079
|
-
chromeRows: 4,
|
|
900080
|
-
maxWidth: 70,
|
|
900081
|
-
minContentRows: 6,
|
|
900082
|
-
maxContentRows: 10
|
|
900083
|
-
});
|
|
900084
|
-
const layout = createOverlayBoxLayout(width, metrics.margin, metrics.boxWidth);
|
|
900085
|
-
const contentW = layout.innerWidth;
|
|
900086
|
-
const borderFg = DEFAULT_OVERLAY_PALETTE.borderFg;
|
|
900087
|
-
const titleFg = DEFAULT_OVERLAY_PALETTE.titleFg;
|
|
900088
|
-
const bodyFg = DEFAULT_OVERLAY_PALETTE.bodyFg;
|
|
900089
|
-
const mutedFg = DEFAULT_OVERLAY_PALETTE.mutedFg;
|
|
900090
|
-
const selectedBg = DEFAULT_OVERLAY_PALETTE.selectedBg;
|
|
900091
|
-
const titleLine = createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.topLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.topRight, borderFg, DEFAULT_OVERLAY_PALETTE.titleBg);
|
|
900092
|
-
putOverlayText(titleLine, layout.margin + 2, layout.width - 4, FILE_PICKER_TITLE, { fg: titleFg, bold: true });
|
|
900093
|
-
lines.push(titleLine);
|
|
900094
|
-
const queryDisplay = picker.query || "";
|
|
900095
|
-
const searchLine = createOverlayContentLine(width, layout, borderFg, DEFAULT_OVERLAY_PALETTE.inputBg);
|
|
900096
|
-
const searchPrefix = FILE_PICKER_SEARCH_PREFIX;
|
|
900097
|
-
const queryText = fitDisplay(`${queryDisplay}${picker.searchFocused ? OVERLAY_GLYPHS.cursor : ""}`, Math.max(0, contentW - getDisplayWidth(searchPrefix)));
|
|
900098
|
-
putOverlayText(searchLine, layout.margin + 2, getDisplayWidth(searchPrefix), searchPrefix, { fg: picker.searchFocused ? bodyFg : mutedFg });
|
|
900099
|
-
putOverlayText(searchLine, layout.margin + 2 + getDisplayWidth(searchPrefix), contentW - getDisplayWidth(searchPrefix), queryText, { fg: picker.query.length > 0 || picker.searchFocused ? bodyFg : mutedFg });
|
|
900100
|
-
lines.push(searchLine);
|
|
900101
|
-
lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.teeLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.teeRight, borderFg, DEFAULT_OVERLAY_PALETTE.sectionBg));
|
|
900102
|
-
if (picker.results.length === 0) {
|
|
900103
|
-
const noResults = createOverlayContentLine(width, layout, borderFg, DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
900104
|
-
putOverlayText(noResults, layout.margin + 2, contentW, fitDisplay(FILE_PICKER_EMPTY_MESSAGE, contentW), { fg: "244", dim: true });
|
|
900105
|
-
lines.push(noResults);
|
|
900106
|
-
} else {
|
|
900107
|
-
const maxVisible = metrics.contentRows;
|
|
900108
|
-
let startIdx = 0;
|
|
900109
|
-
if (picker.results.length > maxVisible) {
|
|
900110
|
-
startIdx = Math.max(0, Math.min(picker.selectedIndex - Math.floor(maxVisible / 2), picker.results.length - maxVisible));
|
|
900111
|
-
}
|
|
900112
|
-
const endIdx = Math.min(startIdx + maxVisible, picker.results.length);
|
|
900113
|
-
for (let i5 = startIdx;i5 < endIdx; i5++) {
|
|
900114
|
-
const file2 = picker.results[i5];
|
|
900115
|
-
const isSelected = i5 === picker.selectedIndex;
|
|
900116
|
-
const indicator = isSelected ? `${OVERLAY_GLYPHS.selected} ` : " ";
|
|
900117
|
-
const displayFile = getDisplayWidth(file2) > contentW - 2 ? truncateDisplay(file2, contentW - 2) : file2;
|
|
900118
|
-
const line2 = createOverlayContentLine(width, layout, borderFg, isSelected ? selectedBg : DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
900119
|
-
putOverlayText(line2, layout.margin + 2, contentW, fitDisplay(indicator + fitDisplay(displayFile, contentW - 2), contentW), {
|
|
900120
|
-
fg: isSelected ? titleFg : file2.endsWith("/") ? titleFg : bodyFg,
|
|
900121
|
-
bg: isSelected ? selectedBg : DEFAULT_OVERLAY_PALETTE.bodyBg,
|
|
900122
|
-
bold: isSelected
|
|
900123
|
-
});
|
|
900124
|
-
lines.push(line2);
|
|
900125
|
-
}
|
|
900126
|
-
}
|
|
900127
|
-
const bottomLine = createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.bottomLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.bottomRight, borderFg, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
900128
|
-
putOverlayText(bottomLine, layout.margin + 2, layout.width - 4, truncateDisplay(FILE_PICKER_HINTS, layout.width - 4), { fg: mutedFg, dim: true });
|
|
900129
|
-
lines.push(bottomLine);
|
|
900130
|
-
return lines;
|
|
900131
|
-
}
|
|
900132
|
-
|
|
900133
900360
|
// src/renderer/model-workspace.ts
|
|
900134
900361
|
var PALETTE = {
|
|
900135
900362
|
border: "#64748b",
|
|
@@ -900175,7 +900402,7 @@ var MODEL_WORKSPACE_CONTEXT_CAP_INPUT_HELP = "Type digits to set a cap. Enter co
|
|
|
900175
900402
|
var MODEL_WORKSPACE_FOOTER_SEARCH_ACTIVE = "Typing filters search; Esc clears search";
|
|
900176
900403
|
var MODEL_WORKSPACE_FOOTER_SEARCH_INACTIVE = "/ search";
|
|
900177
900404
|
var MODEL_WORKSPACE_FOOTER_CONTROLS = "Up/Down navigate \u2022 Left/Right pane \u2022 Enter select \u2022 <search> \u2022 Tab price \u2022 C caps \u2022 A available \u2022 B benchmark \u2022 G group \u2022 Esc close";
|
|
900178
|
-
function
|
|
900405
|
+
function clamp4(value, min2, max2) {
|
|
900179
900406
|
return Math.max(min2, Math.min(max2, value));
|
|
900180
900407
|
}
|
|
900181
900408
|
function fillRange2(line2, startX, endX, bg) {
|
|
@@ -900264,10 +900491,10 @@ function padDisplay2(text, width) {
|
|
|
900264
900491
|
function stableWindow2(total, selected, visible) {
|
|
900265
900492
|
if (total <= 0 || visible <= 0)
|
|
900266
900493
|
return { start: 0, end: 0 };
|
|
900267
|
-
const clamped =
|
|
900494
|
+
const clamped = clamp4(selected, 0, total - 1);
|
|
900268
900495
|
const half = Math.floor(visible / 2);
|
|
900269
900496
|
const maxStart = Math.max(0, total - visible);
|
|
900270
|
-
const start2 =
|
|
900497
|
+
const start2 = clamp4(clamped - half, 0, maxStart);
|
|
900271
900498
|
return { start: start2, end: Math.min(total, start2 + visible) };
|
|
900272
900499
|
}
|
|
900273
900500
|
function formatContext(value) {
|
|
@@ -900405,11 +900632,11 @@ function renderProviderRows(picker, lines, rows, startX, width) {
|
|
|
900405
900632
|
function renderModelRows(picker, lines, rows, startX, width) {
|
|
900406
900633
|
const models = picker.getFilteredModels();
|
|
900407
900634
|
const { start: start2, end } = stableWindow2(models.length, picker.selectedIndex, rows);
|
|
900408
|
-
const providerW =
|
|
900635
|
+
const providerW = clamp4(Math.floor(width * 0.14), 10, 18);
|
|
900409
900636
|
const ctxW = 8;
|
|
900410
900637
|
const tierW = 8;
|
|
900411
900638
|
const capsW = 14;
|
|
900412
|
-
const nameW =
|
|
900639
|
+
const nameW = clamp4(Math.floor(width * 0.28), 16, 36);
|
|
900413
900640
|
const keyW = Math.max(10, width - providerW - ctxW - tierW - capsW - nameW - 10);
|
|
900414
900641
|
for (let visibleRow = 0;visibleRow < rows; visibleRow += 1) {
|
|
900415
900642
|
const absolute = start2 + visibleRow;
|
|
@@ -900489,11 +900716,11 @@ function writeTableHeader(line2, picker, startX, width) {
|
|
|
900489
900716
|
writeText3(line2, startX + 1, width - 2, MODEL_WORKSPACE_TABLE_HEADERS.contextCap, style);
|
|
900490
900717
|
return;
|
|
900491
900718
|
}
|
|
900492
|
-
const providerW =
|
|
900719
|
+
const providerW = clamp4(Math.floor(width * 0.14), 10, 18);
|
|
900493
900720
|
const ctxW = 8;
|
|
900494
900721
|
const tierW = 8;
|
|
900495
900722
|
const capsW = 14;
|
|
900496
|
-
const nameW =
|
|
900723
|
+
const nameW = clamp4(Math.floor(width * 0.28), 16, 36);
|
|
900497
900724
|
const keyW = Math.max(10, width - providerW - ctxW - tierW - capsW - nameW - 10);
|
|
900498
900725
|
let x2 = startX + 3;
|
|
900499
900726
|
writeText3(line2, x2, keyW, padDisplay2(MODEL_WORKSPACE_TABLE_HEADERS.modelKey, keyW), style);
|
|
@@ -900516,7 +900743,7 @@ function renderModelWorkspace(picker, width, viewportHeight) {
|
|
|
900516
900743
|
const safeWidth = Math.max(20, width);
|
|
900517
900744
|
const safeHeight = Math.max(12, viewportHeight);
|
|
900518
900745
|
const lines = [];
|
|
900519
|
-
const targetW =
|
|
900746
|
+
const targetW = clamp4(Math.round(safeWidth * 0.18), 24, 34);
|
|
900520
900747
|
const contentX = targetW + 1;
|
|
900521
900748
|
const contentW = Math.max(1, safeWidth - contentX - 1);
|
|
900522
900749
|
const top = borderLine2(safeWidth, GLYPHS.frame.topLeft, GLYPHS.frame.horizontal, GLYPHS.frame.topRight);
|
|
@@ -900536,7 +900763,7 @@ function renderModelWorkspace(picker, width, viewportHeight) {
|
|
|
900536
900763
|
const bodyRows = safeHeight - 3 - footerRows;
|
|
900537
900764
|
const maxDetailRows = Math.max(3, bodyRows - 2);
|
|
900538
900765
|
const minDetailRows = Math.min(6, maxDetailRows);
|
|
900539
|
-
const detailRows =
|
|
900766
|
+
const detailRows = clamp4(Math.round(bodyRows * 0.32), minDetailRows, maxDetailRows);
|
|
900540
900767
|
const listRows = Math.max(1, bodyRows - detailRows - 1);
|
|
900541
900768
|
const details = detailLines(picker, contentW - 2).slice(0, detailRows);
|
|
900542
900769
|
for (let row = 0;row < bodyRows; row += 1) {
|
|
@@ -900644,292 +900871,6 @@ function keyForTargets(values2) {
|
|
|
900644
900871
|
].join("\x1D")).join("\x1F");
|
|
900645
900872
|
}
|
|
900646
900873
|
|
|
900647
|
-
// src/renderer/selection-modal-overlay.ts
|
|
900648
|
-
var BORDER_FG = DEFAULT_OVERLAY_PALETTE.borderFg;
|
|
900649
|
-
var TITLE_FG = DEFAULT_OVERLAY_PALETTE.titleFg;
|
|
900650
|
-
var BODY_FG = DEFAULT_OVERLAY_PALETTE.bodyFg;
|
|
900651
|
-
var MUTED_FG = DEFAULT_OVERLAY_PALETTE.mutedFg;
|
|
900652
|
-
var CATEGORY_FG = "#4488cc";
|
|
900653
|
-
var SELECTED_BG = DEFAULT_OVERLAY_PALETTE.selectedBg;
|
|
900654
|
-
var SELECTION_MODAL_SEARCH_LABEL = " Search";
|
|
900655
|
-
var SELECTION_MODAL_RESULTS_LABEL = " Results";
|
|
900656
|
-
var SELECTION_MODAL_NO_MATCHING_ITEMS = "No matching items";
|
|
900657
|
-
var SELECTION_MODAL_NO_ITEMS = "No items";
|
|
900658
|
-
var SELECTION_MODAL_NAVIGATION_HINT = "[Up/Down] Navigate";
|
|
900659
|
-
var SELECTION_MODAL_CLOSE_HINT = "[Esc] Close";
|
|
900660
|
-
var SELECTION_MODAL_SEARCH_HINT = "[/] Search";
|
|
900661
|
-
var SELECTION_MODAL_SPACE_TOGGLE_HINT = "[Space] Toggle";
|
|
900662
|
-
function putText(line2, startX, maxWidth, text, style) {
|
|
900663
|
-
putOverlayText(line2, startX, maxWidth, text, style);
|
|
900664
|
-
}
|
|
900665
|
-
function primaryVerbForAction(primaryAction) {
|
|
900666
|
-
return primaryAction === "toggle" ? "[Enter] Toggle" : primaryAction === "edit" ? "[Enter] Edit" : primaryAction === "delete" ? "[Enter] Delete" : "[Enter] Select";
|
|
900667
|
-
}
|
|
900668
|
-
function renderSelectionModalOverlay(modal, width, viewportHeight = 24) {
|
|
900669
|
-
const lines = [];
|
|
900670
|
-
const metrics = getOverlaySurfaceMetrics(width, viewportHeight, {
|
|
900671
|
-
margin: 4,
|
|
900672
|
-
maxWidth: 72,
|
|
900673
|
-
chromeRows: modal.allowSearch ? 5 : 4,
|
|
900674
|
-
minContentRows: 6,
|
|
900675
|
-
maxContentRows: 10
|
|
900676
|
-
});
|
|
900677
|
-
const layout = createOverlayBoxLayout(width, metrics.margin, metrics.boxWidth);
|
|
900678
|
-
lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.topLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.topRight, BORDER_FG, DEFAULT_OVERLAY_PALETTE.titleBg));
|
|
900679
|
-
const titleLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.titleBg);
|
|
900680
|
-
putText(titleLine, layout.margin + 2, layout.innerWidth, fitDisplay(truncateDisplay(modal.title, layout.innerWidth), layout.innerWidth), { fg: TITLE_FG, bold: true });
|
|
900681
|
-
lines.push(titleLine);
|
|
900682
|
-
if (modal.allowSearch) {
|
|
900683
|
-
const labelLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
900684
|
-
putText(labelLine, layout.margin + 2, layout.innerWidth, fitDisplay(SELECTION_MODAL_SEARCH_LABEL, layout.innerWidth), {
|
|
900685
|
-
fg: CATEGORY_FG,
|
|
900686
|
-
dim: true
|
|
900687
|
-
});
|
|
900688
|
-
lines.push(labelLine);
|
|
900689
|
-
const searchLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.inputBg);
|
|
900690
|
-
const prefix = "/ ";
|
|
900691
|
-
const queryAreaWidth = layout.innerWidth - getDisplayWidth(prefix);
|
|
900692
|
-
const queryValue = modal.query + (modal.searchFocused ? OVERLAY_GLYPHS.cursor : "");
|
|
900693
|
-
const queryText = fitDisplay(truncateDisplay(queryValue, queryAreaWidth), queryAreaWidth);
|
|
900694
|
-
putText(searchLine, layout.margin + 2, getDisplayWidth(prefix), prefix, { fg: modal.searchFocused ? BODY_FG : MUTED_FG });
|
|
900695
|
-
putText(searchLine, layout.margin + 2 + getDisplayWidth(prefix), queryAreaWidth, queryText, {
|
|
900696
|
-
fg: modal.query.length > 0 || modal.searchFocused ? BODY_FG : MUTED_FG
|
|
900697
|
-
});
|
|
900698
|
-
lines.push(searchLine);
|
|
900699
|
-
lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.teeLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.teeRight, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg));
|
|
900700
|
-
} else {
|
|
900701
|
-
lines.push(createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg));
|
|
900702
|
-
}
|
|
900703
|
-
const listTitle = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
900704
|
-
putText(listTitle, layout.margin + 2, layout.innerWidth, fitDisplay(SELECTION_MODAL_RESULTS_LABEL, layout.innerWidth), {
|
|
900705
|
-
fg: CATEGORY_FG,
|
|
900706
|
-
dim: true
|
|
900707
|
-
});
|
|
900708
|
-
lines.push(listTitle);
|
|
900709
|
-
const items = modal.filteredItems;
|
|
900710
|
-
if (items.length === 0) {
|
|
900711
|
-
const line2 = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
900712
|
-
const message = modal.query ? SELECTION_MODAL_NO_MATCHING_ITEMS : SELECTION_MODAL_NO_ITEMS;
|
|
900713
|
-
putText(line2, layout.margin + 2, layout.innerWidth, fitDisplay(message, layout.innerWidth), { fg: MUTED_FG, dim: true });
|
|
900714
|
-
lines.push(line2);
|
|
900715
|
-
} else {
|
|
900716
|
-
const maxVisible = metrics.contentRows;
|
|
900717
|
-
let startIdx = 0;
|
|
900718
|
-
if (items.length > maxVisible) {
|
|
900719
|
-
startIdx = Math.max(0, Math.min(modal.selectedIndex - Math.floor(maxVisible / 2), items.length - maxVisible));
|
|
900720
|
-
}
|
|
900721
|
-
const endIdx = Math.min(startIdx + maxVisible, items.length);
|
|
900722
|
-
let lastCategory;
|
|
900723
|
-
for (let i5 = startIdx;i5 < endIdx; i5++) {
|
|
900724
|
-
const item = items[i5];
|
|
900725
|
-
const isSelected = i5 === modal.selectedIndex;
|
|
900726
|
-
if (item.category && item.category !== lastCategory) {
|
|
900727
|
-
lastCategory = item.category;
|
|
900728
|
-
const categoryLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
900729
|
-
putText(categoryLine, layout.margin + 2, layout.innerWidth, fitDisplay(` ${item.category}`, layout.innerWidth), {
|
|
900730
|
-
fg: CATEGORY_FG,
|
|
900731
|
-
dim: true
|
|
900732
|
-
});
|
|
900733
|
-
lines.push(categoryLine);
|
|
900734
|
-
}
|
|
900735
|
-
const indicator = isSelected ? `${OVERLAY_GLYPHS.selected} ` : " ";
|
|
900736
|
-
const indicatorWidth = 2;
|
|
900737
|
-
const remaining = layout.innerWidth - indicatorWidth;
|
|
900738
|
-
const labelColor = isSelected ? TITLE_FG : item.fg ?? BODY_FG;
|
|
900739
|
-
const detailColor = isSelected ? BODY_FG : MUTED_FG;
|
|
900740
|
-
const labelWidth = item.detail ? fitLabelDetailColumns(item.label, item.detail, remaining).labelWidth : remaining;
|
|
900741
|
-
const labelLine = createOverlayContentLine(width, layout, BORDER_FG, isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
900742
|
-
putText(labelLine, layout.margin + 2, indicatorWidth, indicator, {
|
|
900743
|
-
fg: isSelected ? TITLE_FG : MUTED_FG,
|
|
900744
|
-
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg,
|
|
900745
|
-
bold: isSelected
|
|
900746
|
-
});
|
|
900747
|
-
putText(labelLine, layout.margin + 2 + indicatorWidth, labelWidth, fitDisplay(truncateDisplay(item.label, labelWidth), labelWidth), {
|
|
900748
|
-
fg: labelColor,
|
|
900749
|
-
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg,
|
|
900750
|
-
bold: isSelected
|
|
900751
|
-
});
|
|
900752
|
-
if (item.detail) {
|
|
900753
|
-
const detailWidth = fitLabelDetailColumns(item.label, item.detail, remaining).detailWidth;
|
|
900754
|
-
if (detailWidth >= 12) {
|
|
900755
|
-
putText(labelLine, layout.margin + 2 + indicatorWidth + labelWidth, 2, " ", {
|
|
900756
|
-
fg: BODY_FG,
|
|
900757
|
-
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg
|
|
900758
|
-
});
|
|
900759
|
-
putText(labelLine, layout.margin + 2 + indicatorWidth + labelWidth + 2, detailWidth, fitDisplay(truncateDisplay(item.detail, detailWidth), detailWidth), {
|
|
900760
|
-
fg: detailColor,
|
|
900761
|
-
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg
|
|
900762
|
-
});
|
|
900763
|
-
lines.push(labelLine);
|
|
900764
|
-
} else {
|
|
900765
|
-
lines.push(labelLine);
|
|
900766
|
-
const wrappedDetails = wrapWithHangingIndent(item.detail, Math.max(8, remaining), "", 2);
|
|
900767
|
-
for (const detailLineText of wrappedDetails) {
|
|
900768
|
-
const detailLine = createOverlayContentLine(width, layout, BORDER_FG, isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
900769
|
-
putText(detailLine, layout.margin + 2 + indicatorWidth, remaining, fitDisplay(truncateDisplay(detailLineText, remaining), remaining), {
|
|
900770
|
-
fg: detailColor,
|
|
900771
|
-
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg,
|
|
900772
|
-
dim: !isSelected
|
|
900773
|
-
});
|
|
900774
|
-
lines.push(detailLine);
|
|
900775
|
-
}
|
|
900776
|
-
}
|
|
900777
|
-
} else {
|
|
900778
|
-
lines.push(labelLine);
|
|
900779
|
-
}
|
|
900780
|
-
}
|
|
900781
|
-
if (items.length > maxVisible) {
|
|
900782
|
-
const above = startIdx;
|
|
900783
|
-
const below = items.length - endIdx;
|
|
900784
|
-
const scrollHint = above > 0 && below > 0 ? `(${above} above, ${below} below)` : below > 0 ? `(${below} below)` : `(${above} above)`;
|
|
900785
|
-
const hintLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
900786
|
-
putText(hintLine, layout.margin + 2, layout.innerWidth, fitDisplay(scrollHint, layout.innerWidth), { fg: MUTED_FG, dim: true });
|
|
900787
|
-
lines.push(hintLine);
|
|
900788
|
-
}
|
|
900789
|
-
}
|
|
900790
|
-
const footerLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
900791
|
-
const selectedItem = modal.getSelected();
|
|
900792
|
-
const primaryVerb = primaryVerbForAction(selectedItem?.primaryAction);
|
|
900793
|
-
let hints = `${SELECTION_MODAL_NAVIGATION_HINT} ${primaryVerb} ${SELECTION_MODAL_CLOSE_HINT}`;
|
|
900794
|
-
if (modal.allowSearch)
|
|
900795
|
-
hints += ` ${SELECTION_MODAL_SEARCH_HINT}`;
|
|
900796
|
-
if (selectedItem?.primaryAction === "toggle" && !selectedItem.actions)
|
|
900797
|
-
hints += ` ${SELECTION_MODAL_SPACE_TOGGLE_HINT}`;
|
|
900798
|
-
if (selectedItem?.actions)
|
|
900799
|
-
hints += ` ${selectedItem.actions}`;
|
|
900800
|
-
putText(footerLine, layout.margin + 2, layout.innerWidth, fitDisplay(truncateDisplay(hints, layout.innerWidth), layout.innerWidth), { fg: MUTED_FG, dim: true });
|
|
900801
|
-
lines.push(footerLine);
|
|
900802
|
-
lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.bottomLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.bottomRight, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg));
|
|
900803
|
-
return lines;
|
|
900804
|
-
}
|
|
900805
|
-
|
|
900806
|
-
// src/renderer/bottom-bar.ts
|
|
900807
|
-
function createBottomBarLine(width, style) {
|
|
900808
|
-
const line2 = createEmptyLine(width);
|
|
900809
|
-
for (let col = 0;col < width; col++) {
|
|
900810
|
-
line2[col] = createStyledCell(" ", {
|
|
900811
|
-
fg: style.fg,
|
|
900812
|
-
bg: style.bg,
|
|
900813
|
-
bold: style.bold ?? false,
|
|
900814
|
-
dim: style.dim ?? false,
|
|
900815
|
-
underline: style.underline ?? false
|
|
900816
|
-
});
|
|
900817
|
-
}
|
|
900818
|
-
return line2;
|
|
900819
|
-
}
|
|
900820
|
-
function writeBottomBarText(line2, startX, maxWidth, text, style) {
|
|
900821
|
-
let x2 = startX;
|
|
900822
|
-
let used = 0;
|
|
900823
|
-
for (const ch of text) {
|
|
900824
|
-
const cellWidth = getDisplayWidth(ch);
|
|
900825
|
-
if (cellWidth <= 0)
|
|
900826
|
-
continue;
|
|
900827
|
-
if (used + cellWidth > maxWidth || x2 >= line2.length)
|
|
900828
|
-
break;
|
|
900829
|
-
line2[x2] = createStyledCell(ch, {
|
|
900830
|
-
fg: style.fg,
|
|
900831
|
-
bg: style.bg,
|
|
900832
|
-
bold: style.bold ?? false,
|
|
900833
|
-
dim: style.dim ?? false,
|
|
900834
|
-
underline: style.underline ?? false
|
|
900835
|
-
});
|
|
900836
|
-
if (cellWidth > 1 && x2 + 1 < line2.length) {
|
|
900837
|
-
line2[x2 + 1] = createStyledCell(" ", {
|
|
900838
|
-
fg: style.fg,
|
|
900839
|
-
bg: style.bg,
|
|
900840
|
-
bold: style.bold ?? false,
|
|
900841
|
-
dim: style.dim ?? false,
|
|
900842
|
-
underline: style.underline ?? false
|
|
900843
|
-
});
|
|
900844
|
-
}
|
|
900845
|
-
x2 += cellWidth;
|
|
900846
|
-
used += cellWidth;
|
|
900847
|
-
}
|
|
900848
|
-
}
|
|
900849
|
-
|
|
900850
|
-
// src/renderer/search-overlay.ts
|
|
900851
|
-
var SEARCH_OVERLAY_LABEL = " Find: ";
|
|
900852
|
-
var SEARCH_OVERLAY_NO_MATCHES = "No matches";
|
|
900853
|
-
var SEARCH_OVERLAY_COUNT_SUFFIX = "up/down";
|
|
900854
|
-
var SEARCH_OVERLAY_LOCKED_HINTS = " [Up/Down] or [jk] navigate [Bksp] edit [Esc] close";
|
|
900855
|
-
var SEARCH_OVERLAY_UNLOCKED_HINTS = " [Enter/Tab] lock [Esc] close";
|
|
900856
|
-
function searchOverlayMatchCount(current, total) {
|
|
900857
|
-
return `${current}/${total} ${SEARCH_OVERLAY_COUNT_SUFFIX}`;
|
|
900858
|
-
}
|
|
900859
|
-
function renderSearchOverlay(manager5, width) {
|
|
900860
|
-
const matchCount = manager5.matches?.length > 0 ? searchOverlayMatchCount(manager5.currentMatch + 1, manager5.matches.length) : manager5.query.length > 0 ? SEARCH_OVERLAY_NO_MATCHES : "";
|
|
900861
|
-
const locked = manager5.locked;
|
|
900862
|
-
const cursor = locked ? "" : "\u2588";
|
|
900863
|
-
const queryDisplay = manager5.query + cursor;
|
|
900864
|
-
const hints = locked ? SEARCH_OVERLAY_LOCKED_HINTS : SEARCH_OVERLAY_UNLOCKED_HINTS;
|
|
900865
|
-
const label = SEARCH_OVERLAY_LABEL;
|
|
900866
|
-
const matchStr = matchCount ? ` ${matchCount}` : "";
|
|
900867
|
-
const leftPart = label + queryDisplay;
|
|
900868
|
-
const hintsW = getDisplayWidth(hints);
|
|
900869
|
-
const matchStrW = getDisplayWidth(matchStr);
|
|
900870
|
-
const leftWidth = width - hintsW - matchStrW - 2;
|
|
900871
|
-
const truncatedLeft = fitDisplay(getDisplayWidth(leftPart) > leftWidth ? truncateDisplay(leftPart, leftWidth) : leftPart, leftWidth);
|
|
900872
|
-
const fullLine = truncatedLeft + matchStr + hints + " ";
|
|
900873
|
-
const line2 = createBottomBarLine(width, { fg: "#000000", bg: "#00ffcc" });
|
|
900874
|
-
writeBottomBarText(line2, 0, width, fitDisplay(truncateDisplay(fullLine, width), width), { fg: "#000000", bg: "#00ffcc" });
|
|
900875
|
-
if (matchStr.length > 0) {
|
|
900876
|
-
const matchStart = getDisplayWidth(truncatedLeft);
|
|
900877
|
-
writeBottomBarText(line2, matchStart, matchStrW, matchStr, { fg: "#888888", bg: "#00ffcc", dim: true });
|
|
900878
|
-
}
|
|
900879
|
-
return [line2];
|
|
900880
|
-
}
|
|
900881
|
-
|
|
900882
|
-
// src/renderer/history-search-overlay.ts
|
|
900883
|
-
var HISTORY_SEARCH_PREFIX = "(reverse-i-search)`";
|
|
900884
|
-
var HISTORY_SEARCH_FAILED_PREFIX = "(failed reverse-i-search)`";
|
|
900885
|
-
var HISTORY_SEARCH_QUERY_SUFFIX = "': ";
|
|
900886
|
-
function historySearchLabel(prefix, query2) {
|
|
900887
|
-
return prefix + query2 + HISTORY_SEARCH_QUERY_SUFFIX;
|
|
900888
|
-
}
|
|
900889
|
-
function truncateToWidth3(text, maxWidth) {
|
|
900890
|
-
let usedWidth = 0;
|
|
900891
|
-
let result2 = "";
|
|
900892
|
-
let i5 = 0;
|
|
900893
|
-
while (i5 < text.length) {
|
|
900894
|
-
const code2 = text.codePointAt(i5);
|
|
900895
|
-
const charLen = code2 > 65535 ? 2 : 1;
|
|
900896
|
-
const charWidth = getDisplayWidth(text.slice(i5, i5 + charLen));
|
|
900897
|
-
if (usedWidth + charWidth > maxWidth)
|
|
900898
|
-
break;
|
|
900899
|
-
result2 += text.slice(i5, i5 + charLen);
|
|
900900
|
-
usedWidth += charWidth;
|
|
900901
|
-
i5 += charLen;
|
|
900902
|
-
}
|
|
900903
|
-
return result2 + " ".repeat(maxWidth - usedWidth);
|
|
900904
|
-
}
|
|
900905
|
-
function renderHistorySearchOverlay(historySearch, width) {
|
|
900906
|
-
if (width <= 0)
|
|
900907
|
-
return [];
|
|
900908
|
-
const match = historySearch.currentMatch;
|
|
900909
|
-
const hasMatch = match !== null && historySearch.query.length > 0;
|
|
900910
|
-
const noMatch = historySearch.query.length > 0 && !hasMatch;
|
|
900911
|
-
const prefix = noMatch ? HISTORY_SEARCH_FAILED_PREFIX : HISTORY_SEARCH_PREFIX;
|
|
900912
|
-
const matchText = hasMatch ? match?.entry ?? "" : "";
|
|
900913
|
-
const label = historySearchLabel(prefix, historySearch.query);
|
|
900914
|
-
const full = truncateToWidth3(label + matchText, width);
|
|
900915
|
-
const line2 = createBottomBarLine(width, { fg: "#000000", bg: "#00ffcc" });
|
|
900916
|
-
writeBottomBarText(line2, 0, width, full, { fg: "#000000", bg: "#00ffcc" });
|
|
900917
|
-
if (hasMatch && match) {
|
|
900918
|
-
const labelW = getDisplayWidth(label);
|
|
900919
|
-
const matchStartCol = labelW + match.matchStart;
|
|
900920
|
-
const matchEndCol = matchStartCol + match.matchLength;
|
|
900921
|
-
const highlightWidth = Math.max(0, matchEndCol - matchStartCol);
|
|
900922
|
-
const matchedSlice = truncateToWidth3(match.entry.slice(match.matchStart, match.matchStart + match.matchLength), highlightWidth);
|
|
900923
|
-
writeBottomBarText(line2, matchStartCol, highlightWidth, matchedSlice, {
|
|
900924
|
-
fg: "#000000",
|
|
900925
|
-
bg: "#00ffcc",
|
|
900926
|
-
bold: true,
|
|
900927
|
-
underline: true
|
|
900928
|
-
});
|
|
900929
|
-
}
|
|
900930
|
-
return [line2];
|
|
900931
|
-
}
|
|
900932
|
-
|
|
900933
900874
|
// src/renderer/settings-modal-helpers.ts
|
|
900934
900875
|
function maskSecretValue(value) {
|
|
900935
900876
|
if (value.length === 0)
|
|
@@ -901604,6 +901545,518 @@ function renderSettingsModal(modal, width, viewportHeight = 24) {
|
|
|
901604
901545
|
});
|
|
901605
901546
|
}
|
|
901606
901547
|
|
|
901548
|
+
// src/renderer/layout-engine.ts
|
|
901549
|
+
function clamp5(value, min2, max2) {
|
|
901550
|
+
return Math.max(min2, Math.min(max2, value));
|
|
901551
|
+
}
|
|
901552
|
+
function createShellLayout(request2) {
|
|
901553
|
+
const width = Math.max(1, request2.width);
|
|
901554
|
+
const height = Math.max(1, request2.height);
|
|
901555
|
+
const headerHeight = clamp5(request2.headerHeight, 0, height);
|
|
901556
|
+
const footerHeight = clamp5(request2.footerHeight, 0, Math.max(0, height - headerHeight));
|
|
901557
|
+
const bodyHeight = Math.max(0, height - headerHeight - footerHeight);
|
|
901558
|
+
const hasPanel = typeof request2.panelWidth === "number" && request2.panelWidth > 0;
|
|
901559
|
+
const safePanelWidth = hasPanel ? clamp5(request2.panelWidth, 1, Math.max(1, width - 2)) : 0;
|
|
901560
|
+
const separatorWidth = hasPanel ? 1 : 0;
|
|
901561
|
+
const conversationWidth = hasPanel ? Math.max(1, width - safePanelWidth - separatorWidth) : width;
|
|
901562
|
+
return {
|
|
901563
|
+
screen: { x: 0, y: 0, width, height },
|
|
901564
|
+
header: { x: 0, y: 0, width, height: headerHeight },
|
|
901565
|
+
body: { x: 0, y: headerHeight, width, height: bodyHeight },
|
|
901566
|
+
footer: { x: 0, y: headerHeight + bodyHeight, width, height: footerHeight },
|
|
901567
|
+
conversation: { x: 0, y: headerHeight, width: conversationWidth, height: bodyHeight },
|
|
901568
|
+
panel: hasPanel ? {
|
|
901569
|
+
x: conversationWidth + separatorWidth,
|
|
901570
|
+
y: headerHeight,
|
|
901571
|
+
width: safePanelWidth,
|
|
901572
|
+
height: bodyHeight
|
|
901573
|
+
} : undefined,
|
|
901574
|
+
separatorX: hasPanel ? conversationWidth : undefined
|
|
901575
|
+
};
|
|
901576
|
+
}
|
|
901577
|
+
function createSplitPaneLayout(totalRows, ratio, options = {}) {
|
|
901578
|
+
const topTabRows = options.topTabRows ?? 1;
|
|
901579
|
+
const bottomTabRows = options.bottomTabRows ?? 1;
|
|
901580
|
+
const separatorRows = options.separatorRows ?? 1;
|
|
901581
|
+
const chromeRows = topTabRows + bottomTabRows + separatorRows;
|
|
901582
|
+
const contentRows = Math.max(0, totalRows - chromeRows);
|
|
901583
|
+
const normalizedRatio = clamp5(ratio, 0.2, 0.8);
|
|
901584
|
+
const topContentRows = contentRows <= 1 ? contentRows : Math.max(1, Math.floor(contentRows * normalizedRatio));
|
|
901585
|
+
const bottomContentRows = contentRows <= 1 ? 0 : Math.max(1, contentRows - topContentRows);
|
|
901586
|
+
return {
|
|
901587
|
+
totalRows,
|
|
901588
|
+
topTabRows,
|
|
901589
|
+
bottomTabRows,
|
|
901590
|
+
separatorRows,
|
|
901591
|
+
topContentRows,
|
|
901592
|
+
bottomContentRows
|
|
901593
|
+
};
|
|
901594
|
+
}
|
|
901595
|
+
|
|
901596
|
+
// src/renderer/process-indicator.ts
|
|
901597
|
+
function truncateToWidth2(text, maxWidth) {
|
|
901598
|
+
let width = 0;
|
|
901599
|
+
let i5 = 0;
|
|
901600
|
+
for (const char of text) {
|
|
901601
|
+
const cw = getDisplayWidth(char);
|
|
901602
|
+
if (width + cw > maxWidth)
|
|
901603
|
+
break;
|
|
901604
|
+
width += cw;
|
|
901605
|
+
i5 += char.length;
|
|
901606
|
+
}
|
|
901607
|
+
return text.slice(0, i5);
|
|
901608
|
+
}
|
|
901609
|
+
function renderProcessIndicator(width, agentCount, toolCount, focused = false, agentProgress) {
|
|
901610
|
+
const total = agentCount + toolCount;
|
|
901611
|
+
const delegationLabel = (count) => `${count} delegation${count !== 1 ? "s" : ""}`;
|
|
901612
|
+
const renderPlainStatus = (text, style) => [UIFactory.stringToLine(` ${text}`, width, style)];
|
|
901613
|
+
const renderFocusedStatus = (text) => {
|
|
901614
|
+
const bg = "#31506f";
|
|
901615
|
+
const fg = "#eefaff";
|
|
901616
|
+
const markerFg = "#7dd3fc";
|
|
901617
|
+
const line2 = UIFactory.stringToLine(" ".repeat(width), width, { fg: "238" });
|
|
901618
|
+
const prefix = `${GLYPHS.navigation.selected} `;
|
|
901619
|
+
const body2 = truncateToWidth2(text, Math.max(0, width - 8));
|
|
901620
|
+
const highlighted = ` ${prefix}${body2} `;
|
|
901621
|
+
const startX = 2;
|
|
901622
|
+
for (let i5 = 0;i5 < highlighted.length && startX + i5 < width - 2; i5++) {
|
|
901623
|
+
const ch = highlighted[i5];
|
|
901624
|
+
const isMarker = i5 < prefix.length + 1;
|
|
901625
|
+
line2[startX + i5].char = ch;
|
|
901626
|
+
line2[startX + i5].fg = isMarker ? markerFg : fg;
|
|
901627
|
+
line2[startX + i5].bg = bg;
|
|
901628
|
+
line2[startX + i5].bold = true;
|
|
901629
|
+
line2[startX + i5].dim = false;
|
|
901630
|
+
}
|
|
901631
|
+
return [line2];
|
|
901632
|
+
};
|
|
901633
|
+
if (focused) {
|
|
901634
|
+
const parts3 = [];
|
|
901635
|
+
if (agentCount > 0)
|
|
901636
|
+
parts3.push(delegationLabel(agentCount));
|
|
901637
|
+
if (toolCount > 0)
|
|
901638
|
+
parts3.push(`${toolCount} tool${toolCount !== 1 ? "s" : ""} running`);
|
|
901639
|
+
const label2 = total === 0 ? `No runtime activity ${GLYPHS.status.pending} back to input` : `${parts3.join(` ${GLYPHS.navigation.pipeSeparator} `)} ${GLYPHS.status.pending} Enter to open ${GLYPHS.status.pending} back to input`;
|
|
901640
|
+
return renderFocusedStatus(label2);
|
|
901641
|
+
}
|
|
901642
|
+
if (total === 0) {
|
|
901643
|
+
return renderPlainStatus("No runtime activity", { fg: "238", dim: true });
|
|
901644
|
+
}
|
|
901645
|
+
const parts2 = [];
|
|
901646
|
+
if (agentCount > 0) {
|
|
901647
|
+
parts2.push(delegationLabel(agentCount));
|
|
901648
|
+
}
|
|
901649
|
+
if (toolCount > 0) {
|
|
901650
|
+
parts2.push(`${toolCount} tool${toolCount !== 1 ? "s" : ""} running`);
|
|
901651
|
+
}
|
|
901652
|
+
const PROGRESS_RESERVED_CHARS = 43;
|
|
901653
|
+
const progressMaxLen = Math.max(0, width - PROGRESS_RESERVED_CHARS);
|
|
901654
|
+
const progressSuffix = agentProgress && progressMaxLen > 10 ? ` | ${agentProgress.length > progressMaxLen ? agentProgress.slice(0, Math.max(0, progressMaxLen - 3)) + "..." : agentProgress}` : "";
|
|
901655
|
+
const label = `${parts2.join(` ${GLYPHS.navigation.pipeSeparator} `)}${progressSuffix}`;
|
|
901656
|
+
const hint = ` ${GLYPHS.status.pending} Enter to view`;
|
|
901657
|
+
return renderPlainStatus(`${label}${hint}`, { fg: "#00ffff", bold: true });
|
|
901658
|
+
}
|
|
901659
|
+
|
|
901660
|
+
// src/renderer/shell-surface.ts
|
|
901661
|
+
var FOOTER_BASE_ROWS = 9;
|
|
901662
|
+
var CONTEXT_PROGRESS_ROWS = 2;
|
|
901663
|
+
var PROCESS_INDICATOR_ROWS = 1;
|
|
901664
|
+
function estimateShellFooterHeight(promptLineCount, contextWindow) {
|
|
901665
|
+
const safePromptLines = Math.max(1, promptLineCount);
|
|
901666
|
+
const progressRows = contextWindow && contextWindow > 0 ? CONTEXT_PROGRESS_ROWS : 0;
|
|
901667
|
+
return FOOTER_BASE_ROWS + safePromptLines + progressRows + PROCESS_INDICATOR_ROWS;
|
|
901668
|
+
}
|
|
901669
|
+
function buildShellFooter(options) {
|
|
901670
|
+
const lines = UIFactory.createFooter(options.width, options.promptText, options.usage, options.showExitNotice, options.lastCopyTime, options.model, options.toolCount, options.promptCursorPos, options.workingDir, options.provider, options.contextWindow, options.compactThreshold, options.dangerMode, options.lastInputTokens, options.commandArgsHint, options.hitlMode, options.promptFocused ?? !options.indicatorFocused, options.composerMode, options.composerStatus, options.composerFlags, options.composerPendingRisk);
|
|
901671
|
+
const processIndicator = renderProcessIndicator(options.width, options.runningAgentCount, options.runningProcessCount, options.indicatorFocused, options.runningAgentProgress);
|
|
901672
|
+
const inputBoxRows = Math.max(1, options.promptLineCount) + 2;
|
|
901673
|
+
lines.splice(inputBoxRows, 0, ...processIndicator);
|
|
901674
|
+
return { lines, height: lines.length };
|
|
901675
|
+
}
|
|
901676
|
+
|
|
901677
|
+
// src/renderer/conversation-layout.ts
|
|
901678
|
+
function buildConversationViewport(request2) {
|
|
901679
|
+
const overlayRows = request2.overlayRows ?? 0;
|
|
901680
|
+
const effectiveHeight = Math.max(0, request2.viewportHeight - overlayRows);
|
|
901681
|
+
const lineCount = request2.conversation.history.getLineCount();
|
|
901682
|
+
const maxScroll = Math.max(0, lineCount - effectiveHeight);
|
|
901683
|
+
const nextScrollTop = request2.scrollLocked ? maxScroll : Math.max(0, Math.min(request2.scrollTop, maxScroll));
|
|
901684
|
+
const viewport = request2.conversation.history.getSnapshot(nextScrollTop, effectiveHeight, request2.width);
|
|
901685
|
+
return {
|
|
901686
|
+
effectiveHeight,
|
|
901687
|
+
maxScroll,
|
|
901688
|
+
nextScrollTop,
|
|
901689
|
+
viewport
|
|
901690
|
+
};
|
|
901691
|
+
}
|
|
901692
|
+
function overlayViewportBottom(viewport, overlay, width, viewportHeight, bottomInset = 0) {
|
|
901693
|
+
if (overlay.length === 0)
|
|
901694
|
+
return [...viewport];
|
|
901695
|
+
const next = [...viewport];
|
|
901696
|
+
const targetStart = Math.max(0, viewportHeight - bottomInset - overlay.length);
|
|
901697
|
+
next.length = Math.min(next.length, targetStart);
|
|
901698
|
+
while (next.length < targetStart)
|
|
901699
|
+
next.push(createEmptyLine(width));
|
|
901700
|
+
next.push(...overlay);
|
|
901701
|
+
return next;
|
|
901702
|
+
}
|
|
901703
|
+
function replaceViewportWithOverlay(overlay, width, viewportHeight) {
|
|
901704
|
+
const next = [];
|
|
901705
|
+
const pad = Math.max(0, viewportHeight - overlay.length);
|
|
901706
|
+
for (let i5 = 0;i5 < pad; i5++)
|
|
901707
|
+
next.push(createEmptyLine(width));
|
|
901708
|
+
next.push(...overlay);
|
|
901709
|
+
return next;
|
|
901710
|
+
}
|
|
901711
|
+
|
|
901712
|
+
// src/renderer/file-picker-overlay.ts
|
|
901713
|
+
var FILE_PICKER_TITLE = "Select File";
|
|
901714
|
+
var FILE_PICKER_SEARCH_PREFIX = "@ ";
|
|
901715
|
+
var FILE_PICKER_EMPTY_MESSAGE = "No matching files";
|
|
901716
|
+
var FILE_PICKER_HINTS = "[Up/Down] Navigate [/] Search [Enter] Select [Esc] Cancel";
|
|
901717
|
+
function renderFilePickerOverlay(picker, width, viewportHeight = 24) {
|
|
901718
|
+
const lines = [];
|
|
901719
|
+
const metrics = getOverlaySurfaceMetrics(width, viewportHeight, {
|
|
901720
|
+
chromeRows: 4,
|
|
901721
|
+
maxWidth: 70,
|
|
901722
|
+
minContentRows: 6,
|
|
901723
|
+
maxContentRows: 10
|
|
901724
|
+
});
|
|
901725
|
+
const layout = createOverlayBoxLayout(width, metrics.margin, metrics.boxWidth);
|
|
901726
|
+
const contentW = layout.innerWidth;
|
|
901727
|
+
const borderFg = DEFAULT_OVERLAY_PALETTE.borderFg;
|
|
901728
|
+
const titleFg = DEFAULT_OVERLAY_PALETTE.titleFg;
|
|
901729
|
+
const bodyFg = DEFAULT_OVERLAY_PALETTE.bodyFg;
|
|
901730
|
+
const mutedFg = DEFAULT_OVERLAY_PALETTE.mutedFg;
|
|
901731
|
+
const selectedBg = DEFAULT_OVERLAY_PALETTE.selectedBg;
|
|
901732
|
+
const titleLine = createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.topLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.topRight, borderFg, DEFAULT_OVERLAY_PALETTE.titleBg);
|
|
901733
|
+
putOverlayText(titleLine, layout.margin + 2, layout.width - 4, FILE_PICKER_TITLE, { fg: titleFg, bold: true });
|
|
901734
|
+
lines.push(titleLine);
|
|
901735
|
+
const queryDisplay = picker.query || "";
|
|
901736
|
+
const searchLine = createOverlayContentLine(width, layout, borderFg, DEFAULT_OVERLAY_PALETTE.inputBg);
|
|
901737
|
+
const searchPrefix = FILE_PICKER_SEARCH_PREFIX;
|
|
901738
|
+
const queryText = fitDisplay(`${queryDisplay}${picker.searchFocused ? OVERLAY_GLYPHS.cursor : ""}`, Math.max(0, contentW - getDisplayWidth(searchPrefix)));
|
|
901739
|
+
putOverlayText(searchLine, layout.margin + 2, getDisplayWidth(searchPrefix), searchPrefix, { fg: picker.searchFocused ? bodyFg : mutedFg });
|
|
901740
|
+
putOverlayText(searchLine, layout.margin + 2 + getDisplayWidth(searchPrefix), contentW - getDisplayWidth(searchPrefix), queryText, { fg: picker.query.length > 0 || picker.searchFocused ? bodyFg : mutedFg });
|
|
901741
|
+
lines.push(searchLine);
|
|
901742
|
+
lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.teeLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.teeRight, borderFg, DEFAULT_OVERLAY_PALETTE.sectionBg));
|
|
901743
|
+
if (picker.results.length === 0) {
|
|
901744
|
+
const noResults = createOverlayContentLine(width, layout, borderFg, DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
901745
|
+
putOverlayText(noResults, layout.margin + 2, contentW, fitDisplay(FILE_PICKER_EMPTY_MESSAGE, contentW), { fg: "244", dim: true });
|
|
901746
|
+
lines.push(noResults);
|
|
901747
|
+
} else {
|
|
901748
|
+
const maxVisible = metrics.contentRows;
|
|
901749
|
+
let startIdx = 0;
|
|
901750
|
+
if (picker.results.length > maxVisible) {
|
|
901751
|
+
startIdx = Math.max(0, Math.min(picker.selectedIndex - Math.floor(maxVisible / 2), picker.results.length - maxVisible));
|
|
901752
|
+
}
|
|
901753
|
+
const endIdx = Math.min(startIdx + maxVisible, picker.results.length);
|
|
901754
|
+
for (let i5 = startIdx;i5 < endIdx; i5++) {
|
|
901755
|
+
const file2 = picker.results[i5];
|
|
901756
|
+
const isSelected = i5 === picker.selectedIndex;
|
|
901757
|
+
const indicator = isSelected ? `${OVERLAY_GLYPHS.selected} ` : " ";
|
|
901758
|
+
const displayFile = getDisplayWidth(file2) > contentW - 2 ? truncateDisplay(file2, contentW - 2) : file2;
|
|
901759
|
+
const line2 = createOverlayContentLine(width, layout, borderFg, isSelected ? selectedBg : DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
901760
|
+
putOverlayText(line2, layout.margin + 2, contentW, fitDisplay(indicator + fitDisplay(displayFile, contentW - 2), contentW), {
|
|
901761
|
+
fg: isSelected ? titleFg : file2.endsWith("/") ? titleFg : bodyFg,
|
|
901762
|
+
bg: isSelected ? selectedBg : DEFAULT_OVERLAY_PALETTE.bodyBg,
|
|
901763
|
+
bold: isSelected
|
|
901764
|
+
});
|
|
901765
|
+
lines.push(line2);
|
|
901766
|
+
}
|
|
901767
|
+
}
|
|
901768
|
+
const bottomLine = createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.bottomLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.bottomRight, borderFg, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
901769
|
+
putOverlayText(bottomLine, layout.margin + 2, layout.width - 4, truncateDisplay(FILE_PICKER_HINTS, layout.width - 4), { fg: mutedFg, dim: true });
|
|
901770
|
+
lines.push(bottomLine);
|
|
901771
|
+
return lines;
|
|
901772
|
+
}
|
|
901773
|
+
|
|
901774
|
+
// src/renderer/selection-modal-overlay.ts
|
|
901775
|
+
var BORDER_FG = DEFAULT_OVERLAY_PALETTE.borderFg;
|
|
901776
|
+
var TITLE_FG = DEFAULT_OVERLAY_PALETTE.titleFg;
|
|
901777
|
+
var BODY_FG = DEFAULT_OVERLAY_PALETTE.bodyFg;
|
|
901778
|
+
var MUTED_FG = DEFAULT_OVERLAY_PALETTE.mutedFg;
|
|
901779
|
+
var CATEGORY_FG = "#4488cc";
|
|
901780
|
+
var SELECTED_BG = DEFAULT_OVERLAY_PALETTE.selectedBg;
|
|
901781
|
+
var SELECTION_MODAL_SEARCH_LABEL = " Search";
|
|
901782
|
+
var SELECTION_MODAL_RESULTS_LABEL = " Results";
|
|
901783
|
+
var SELECTION_MODAL_NO_MATCHING_ITEMS = "No matching items";
|
|
901784
|
+
var SELECTION_MODAL_NO_ITEMS = "No items";
|
|
901785
|
+
var SELECTION_MODAL_NAVIGATION_HINT = "[Up/Down] Navigate";
|
|
901786
|
+
var SELECTION_MODAL_CLOSE_HINT = "[Esc] Close";
|
|
901787
|
+
var SELECTION_MODAL_SEARCH_HINT = "[/] Search";
|
|
901788
|
+
var SELECTION_MODAL_SPACE_TOGGLE_HINT = "[Space] Toggle";
|
|
901789
|
+
function putText(line2, startX, maxWidth, text, style) {
|
|
901790
|
+
putOverlayText(line2, startX, maxWidth, text, style);
|
|
901791
|
+
}
|
|
901792
|
+
function primaryVerbForAction(primaryAction) {
|
|
901793
|
+
return primaryAction === "toggle" ? "[Enter] Toggle" : primaryAction === "edit" ? "[Enter] Edit" : primaryAction === "delete" ? "[Enter] Delete" : "[Enter] Select";
|
|
901794
|
+
}
|
|
901795
|
+
function renderSelectionModalOverlay(modal, width, viewportHeight = 24) {
|
|
901796
|
+
const lines = [];
|
|
901797
|
+
const metrics = getOverlaySurfaceMetrics(width, viewportHeight, {
|
|
901798
|
+
margin: 4,
|
|
901799
|
+
maxWidth: 72,
|
|
901800
|
+
chromeRows: modal.allowSearch ? 5 : 4,
|
|
901801
|
+
minContentRows: 6,
|
|
901802
|
+
maxContentRows: 10
|
|
901803
|
+
});
|
|
901804
|
+
const layout = createOverlayBoxLayout(width, metrics.margin, metrics.boxWidth);
|
|
901805
|
+
lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.topLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.topRight, BORDER_FG, DEFAULT_OVERLAY_PALETTE.titleBg));
|
|
901806
|
+
const titleLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.titleBg);
|
|
901807
|
+
putText(titleLine, layout.margin + 2, layout.innerWidth, fitDisplay(truncateDisplay(modal.title, layout.innerWidth), layout.innerWidth), { fg: TITLE_FG, bold: true });
|
|
901808
|
+
lines.push(titleLine);
|
|
901809
|
+
if (modal.allowSearch) {
|
|
901810
|
+
const labelLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
901811
|
+
putText(labelLine, layout.margin + 2, layout.innerWidth, fitDisplay(SELECTION_MODAL_SEARCH_LABEL, layout.innerWidth), {
|
|
901812
|
+
fg: CATEGORY_FG,
|
|
901813
|
+
dim: true
|
|
901814
|
+
});
|
|
901815
|
+
lines.push(labelLine);
|
|
901816
|
+
const searchLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.inputBg);
|
|
901817
|
+
const prefix = "/ ";
|
|
901818
|
+
const queryAreaWidth = layout.innerWidth - getDisplayWidth(prefix);
|
|
901819
|
+
const queryValue = modal.query + (modal.searchFocused ? OVERLAY_GLYPHS.cursor : "");
|
|
901820
|
+
const queryText = fitDisplay(truncateDisplay(queryValue, queryAreaWidth), queryAreaWidth);
|
|
901821
|
+
putText(searchLine, layout.margin + 2, getDisplayWidth(prefix), prefix, { fg: modal.searchFocused ? BODY_FG : MUTED_FG });
|
|
901822
|
+
putText(searchLine, layout.margin + 2 + getDisplayWidth(prefix), queryAreaWidth, queryText, {
|
|
901823
|
+
fg: modal.query.length > 0 || modal.searchFocused ? BODY_FG : MUTED_FG
|
|
901824
|
+
});
|
|
901825
|
+
lines.push(searchLine);
|
|
901826
|
+
lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.teeLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.teeRight, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg));
|
|
901827
|
+
} else {
|
|
901828
|
+
lines.push(createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg));
|
|
901829
|
+
}
|
|
901830
|
+
const listTitle = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
901831
|
+
putText(listTitle, layout.margin + 2, layout.innerWidth, fitDisplay(SELECTION_MODAL_RESULTS_LABEL, layout.innerWidth), {
|
|
901832
|
+
fg: CATEGORY_FG,
|
|
901833
|
+
dim: true
|
|
901834
|
+
});
|
|
901835
|
+
lines.push(listTitle);
|
|
901836
|
+
const items = modal.filteredItems;
|
|
901837
|
+
if (items.length === 0) {
|
|
901838
|
+
const line2 = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
901839
|
+
const message = modal.query ? SELECTION_MODAL_NO_MATCHING_ITEMS : SELECTION_MODAL_NO_ITEMS;
|
|
901840
|
+
putText(line2, layout.margin + 2, layout.innerWidth, fitDisplay(message, layout.innerWidth), { fg: MUTED_FG, dim: true });
|
|
901841
|
+
lines.push(line2);
|
|
901842
|
+
} else {
|
|
901843
|
+
const maxVisible = metrics.contentRows;
|
|
901844
|
+
let startIdx = 0;
|
|
901845
|
+
if (items.length > maxVisible) {
|
|
901846
|
+
startIdx = Math.max(0, Math.min(modal.selectedIndex - Math.floor(maxVisible / 2), items.length - maxVisible));
|
|
901847
|
+
}
|
|
901848
|
+
const endIdx = Math.min(startIdx + maxVisible, items.length);
|
|
901849
|
+
let lastCategory;
|
|
901850
|
+
for (let i5 = startIdx;i5 < endIdx; i5++) {
|
|
901851
|
+
const item = items[i5];
|
|
901852
|
+
const isSelected = i5 === modal.selectedIndex;
|
|
901853
|
+
if (item.category && item.category !== lastCategory) {
|
|
901854
|
+
lastCategory = item.category;
|
|
901855
|
+
const categoryLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
901856
|
+
putText(categoryLine, layout.margin + 2, layout.innerWidth, fitDisplay(` ${item.category}`, layout.innerWidth), {
|
|
901857
|
+
fg: CATEGORY_FG,
|
|
901858
|
+
dim: true
|
|
901859
|
+
});
|
|
901860
|
+
lines.push(categoryLine);
|
|
901861
|
+
}
|
|
901862
|
+
const indicator = isSelected ? `${OVERLAY_GLYPHS.selected} ` : " ";
|
|
901863
|
+
const indicatorWidth = 2;
|
|
901864
|
+
const remaining = layout.innerWidth - indicatorWidth;
|
|
901865
|
+
const labelColor = isSelected ? TITLE_FG : item.fg ?? BODY_FG;
|
|
901866
|
+
const detailColor = isSelected ? BODY_FG : MUTED_FG;
|
|
901867
|
+
const labelWidth = item.detail ? fitLabelDetailColumns(item.label, item.detail, remaining).labelWidth : remaining;
|
|
901868
|
+
const labelLine = createOverlayContentLine(width, layout, BORDER_FG, isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
901869
|
+
putText(labelLine, layout.margin + 2, indicatorWidth, indicator, {
|
|
901870
|
+
fg: isSelected ? TITLE_FG : MUTED_FG,
|
|
901871
|
+
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg,
|
|
901872
|
+
bold: isSelected
|
|
901873
|
+
});
|
|
901874
|
+
putText(labelLine, layout.margin + 2 + indicatorWidth, labelWidth, fitDisplay(truncateDisplay(item.label, labelWidth), labelWidth), {
|
|
901875
|
+
fg: labelColor,
|
|
901876
|
+
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg,
|
|
901877
|
+
bold: isSelected
|
|
901878
|
+
});
|
|
901879
|
+
if (item.detail) {
|
|
901880
|
+
const detailWidth = fitLabelDetailColumns(item.label, item.detail, remaining).detailWidth;
|
|
901881
|
+
if (detailWidth >= 12) {
|
|
901882
|
+
putText(labelLine, layout.margin + 2 + indicatorWidth + labelWidth, 2, " ", {
|
|
901883
|
+
fg: BODY_FG,
|
|
901884
|
+
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg
|
|
901885
|
+
});
|
|
901886
|
+
putText(labelLine, layout.margin + 2 + indicatorWidth + labelWidth + 2, detailWidth, fitDisplay(truncateDisplay(item.detail, detailWidth), detailWidth), {
|
|
901887
|
+
fg: detailColor,
|
|
901888
|
+
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg
|
|
901889
|
+
});
|
|
901890
|
+
lines.push(labelLine);
|
|
901891
|
+
} else {
|
|
901892
|
+
lines.push(labelLine);
|
|
901893
|
+
const wrappedDetails = wrapWithHangingIndent(item.detail, Math.max(8, remaining), "", 2);
|
|
901894
|
+
for (const detailLineText of wrappedDetails) {
|
|
901895
|
+
const detailLine = createOverlayContentLine(width, layout, BORDER_FG, isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
901896
|
+
putText(detailLine, layout.margin + 2 + indicatorWidth, remaining, fitDisplay(truncateDisplay(detailLineText, remaining), remaining), {
|
|
901897
|
+
fg: detailColor,
|
|
901898
|
+
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg,
|
|
901899
|
+
dim: !isSelected
|
|
901900
|
+
});
|
|
901901
|
+
lines.push(detailLine);
|
|
901902
|
+
}
|
|
901903
|
+
}
|
|
901904
|
+
} else {
|
|
901905
|
+
lines.push(labelLine);
|
|
901906
|
+
}
|
|
901907
|
+
}
|
|
901908
|
+
if (items.length > maxVisible) {
|
|
901909
|
+
const above = startIdx;
|
|
901910
|
+
const below = items.length - endIdx;
|
|
901911
|
+
const scrollHint = above > 0 && below > 0 ? `(${above} above, ${below} below)` : below > 0 ? `(${below} below)` : `(${above} above)`;
|
|
901912
|
+
const hintLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
901913
|
+
putText(hintLine, layout.margin + 2, layout.innerWidth, fitDisplay(scrollHint, layout.innerWidth), { fg: MUTED_FG, dim: true });
|
|
901914
|
+
lines.push(hintLine);
|
|
901915
|
+
}
|
|
901916
|
+
}
|
|
901917
|
+
const footerLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
901918
|
+
const selectedItem = modal.getSelected();
|
|
901919
|
+
const primaryVerb = primaryVerbForAction(selectedItem?.primaryAction);
|
|
901920
|
+
let hints = `${SELECTION_MODAL_NAVIGATION_HINT} ${primaryVerb} ${SELECTION_MODAL_CLOSE_HINT}`;
|
|
901921
|
+
if (modal.allowSearch)
|
|
901922
|
+
hints += ` ${SELECTION_MODAL_SEARCH_HINT}`;
|
|
901923
|
+
if (selectedItem?.primaryAction === "toggle" && !selectedItem.actions)
|
|
901924
|
+
hints += ` ${SELECTION_MODAL_SPACE_TOGGLE_HINT}`;
|
|
901925
|
+
if (selectedItem?.actions)
|
|
901926
|
+
hints += ` ${selectedItem.actions}`;
|
|
901927
|
+
putText(footerLine, layout.margin + 2, layout.innerWidth, fitDisplay(truncateDisplay(hints, layout.innerWidth), layout.innerWidth), { fg: MUTED_FG, dim: true });
|
|
901928
|
+
lines.push(footerLine);
|
|
901929
|
+
lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.bottomLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.bottomRight, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg));
|
|
901930
|
+
return lines;
|
|
901931
|
+
}
|
|
901932
|
+
|
|
901933
|
+
// src/renderer/bottom-bar.ts
|
|
901934
|
+
function createBottomBarLine(width, style) {
|
|
901935
|
+
const line2 = createEmptyLine(width);
|
|
901936
|
+
for (let col = 0;col < width; col++) {
|
|
901937
|
+
line2[col] = createStyledCell(" ", {
|
|
901938
|
+
fg: style.fg,
|
|
901939
|
+
bg: style.bg,
|
|
901940
|
+
bold: style.bold ?? false,
|
|
901941
|
+
dim: style.dim ?? false,
|
|
901942
|
+
underline: style.underline ?? false
|
|
901943
|
+
});
|
|
901944
|
+
}
|
|
901945
|
+
return line2;
|
|
901946
|
+
}
|
|
901947
|
+
function writeBottomBarText(line2, startX, maxWidth, text, style) {
|
|
901948
|
+
let x2 = startX;
|
|
901949
|
+
let used = 0;
|
|
901950
|
+
for (const ch of text) {
|
|
901951
|
+
const cellWidth = getDisplayWidth(ch);
|
|
901952
|
+
if (cellWidth <= 0)
|
|
901953
|
+
continue;
|
|
901954
|
+
if (used + cellWidth > maxWidth || x2 >= line2.length)
|
|
901955
|
+
break;
|
|
901956
|
+
line2[x2] = createStyledCell(ch, {
|
|
901957
|
+
fg: style.fg,
|
|
901958
|
+
bg: style.bg,
|
|
901959
|
+
bold: style.bold ?? false,
|
|
901960
|
+
dim: style.dim ?? false,
|
|
901961
|
+
underline: style.underline ?? false
|
|
901962
|
+
});
|
|
901963
|
+
if (cellWidth > 1 && x2 + 1 < line2.length) {
|
|
901964
|
+
line2[x2 + 1] = createStyledCell(" ", {
|
|
901965
|
+
fg: style.fg,
|
|
901966
|
+
bg: style.bg,
|
|
901967
|
+
bold: style.bold ?? false,
|
|
901968
|
+
dim: style.dim ?? false,
|
|
901969
|
+
underline: style.underline ?? false
|
|
901970
|
+
});
|
|
901971
|
+
}
|
|
901972
|
+
x2 += cellWidth;
|
|
901973
|
+
used += cellWidth;
|
|
901974
|
+
}
|
|
901975
|
+
}
|
|
901976
|
+
|
|
901977
|
+
// src/renderer/search-overlay.ts
|
|
901978
|
+
var SEARCH_OVERLAY_LABEL = " Find: ";
|
|
901979
|
+
var SEARCH_OVERLAY_NO_MATCHES = "No matches";
|
|
901980
|
+
var SEARCH_OVERLAY_COUNT_SUFFIX = "up/down";
|
|
901981
|
+
var SEARCH_OVERLAY_LOCKED_HINTS = " [Up/Down] or [jk] navigate [Bksp] edit [Esc] close";
|
|
901982
|
+
var SEARCH_OVERLAY_UNLOCKED_HINTS = " [Enter/Tab] lock [Esc] close";
|
|
901983
|
+
function searchOverlayMatchCount(current, total) {
|
|
901984
|
+
return `${current}/${total} ${SEARCH_OVERLAY_COUNT_SUFFIX}`;
|
|
901985
|
+
}
|
|
901986
|
+
function renderSearchOverlay(manager5, width) {
|
|
901987
|
+
const matchCount = manager5.matches?.length > 0 ? searchOverlayMatchCount(manager5.currentMatch + 1, manager5.matches.length) : manager5.query.length > 0 ? SEARCH_OVERLAY_NO_MATCHES : "";
|
|
901988
|
+
const locked = manager5.locked;
|
|
901989
|
+
const cursor = locked ? "" : "\u2588";
|
|
901990
|
+
const queryDisplay = manager5.query + cursor;
|
|
901991
|
+
const hints = locked ? SEARCH_OVERLAY_LOCKED_HINTS : SEARCH_OVERLAY_UNLOCKED_HINTS;
|
|
901992
|
+
const label = SEARCH_OVERLAY_LABEL;
|
|
901993
|
+
const matchStr = matchCount ? ` ${matchCount}` : "";
|
|
901994
|
+
const leftPart = label + queryDisplay;
|
|
901995
|
+
const hintsW = getDisplayWidth(hints);
|
|
901996
|
+
const matchStrW = getDisplayWidth(matchStr);
|
|
901997
|
+
const leftWidth = width - hintsW - matchStrW - 2;
|
|
901998
|
+
const truncatedLeft = fitDisplay(getDisplayWidth(leftPart) > leftWidth ? truncateDisplay(leftPart, leftWidth) : leftPart, leftWidth);
|
|
901999
|
+
const fullLine = truncatedLeft + matchStr + hints + " ";
|
|
902000
|
+
const line2 = createBottomBarLine(width, { fg: "#000000", bg: "#00ffcc" });
|
|
902001
|
+
writeBottomBarText(line2, 0, width, fitDisplay(truncateDisplay(fullLine, width), width), { fg: "#000000", bg: "#00ffcc" });
|
|
902002
|
+
if (matchStr.length > 0) {
|
|
902003
|
+
const matchStart = getDisplayWidth(truncatedLeft);
|
|
902004
|
+
writeBottomBarText(line2, matchStart, matchStrW, matchStr, { fg: "#888888", bg: "#00ffcc", dim: true });
|
|
902005
|
+
}
|
|
902006
|
+
return [line2];
|
|
902007
|
+
}
|
|
902008
|
+
|
|
902009
|
+
// src/renderer/history-search-overlay.ts
|
|
902010
|
+
var HISTORY_SEARCH_PREFIX = "(reverse-i-search)`";
|
|
902011
|
+
var HISTORY_SEARCH_FAILED_PREFIX = "(failed reverse-i-search)`";
|
|
902012
|
+
var HISTORY_SEARCH_QUERY_SUFFIX = "': ";
|
|
902013
|
+
function historySearchLabel(prefix, query2) {
|
|
902014
|
+
return prefix + query2 + HISTORY_SEARCH_QUERY_SUFFIX;
|
|
902015
|
+
}
|
|
902016
|
+
function truncateToWidth3(text, maxWidth) {
|
|
902017
|
+
let usedWidth = 0;
|
|
902018
|
+
let result2 = "";
|
|
902019
|
+
let i5 = 0;
|
|
902020
|
+
while (i5 < text.length) {
|
|
902021
|
+
const code2 = text.codePointAt(i5);
|
|
902022
|
+
const charLen = code2 > 65535 ? 2 : 1;
|
|
902023
|
+
const charWidth = getDisplayWidth(text.slice(i5, i5 + charLen));
|
|
902024
|
+
if (usedWidth + charWidth > maxWidth)
|
|
902025
|
+
break;
|
|
902026
|
+
result2 += text.slice(i5, i5 + charLen);
|
|
902027
|
+
usedWidth += charWidth;
|
|
902028
|
+
i5 += charLen;
|
|
902029
|
+
}
|
|
902030
|
+
return result2 + " ".repeat(maxWidth - usedWidth);
|
|
902031
|
+
}
|
|
902032
|
+
function renderHistorySearchOverlay(historySearch, width) {
|
|
902033
|
+
if (width <= 0)
|
|
902034
|
+
return [];
|
|
902035
|
+
const match = historySearch.currentMatch;
|
|
902036
|
+
const hasMatch = match !== null && historySearch.query.length > 0;
|
|
902037
|
+
const noMatch = historySearch.query.length > 0 && !hasMatch;
|
|
902038
|
+
const prefix = noMatch ? HISTORY_SEARCH_FAILED_PREFIX : HISTORY_SEARCH_PREFIX;
|
|
902039
|
+
const matchText = hasMatch ? match?.entry ?? "" : "";
|
|
902040
|
+
const label = historySearchLabel(prefix, historySearch.query);
|
|
902041
|
+
const full = truncateToWidth3(label + matchText, width);
|
|
902042
|
+
const line2 = createBottomBarLine(width, { fg: "#000000", bg: "#00ffcc" });
|
|
902043
|
+
writeBottomBarText(line2, 0, width, full, { fg: "#000000", bg: "#00ffcc" });
|
|
902044
|
+
if (hasMatch && match) {
|
|
902045
|
+
const labelW = getDisplayWidth(label);
|
|
902046
|
+
const matchStartCol = labelW + match.matchStart;
|
|
902047
|
+
const matchEndCol = matchStartCol + match.matchLength;
|
|
902048
|
+
const highlightWidth = Math.max(0, matchEndCol - matchStartCol);
|
|
902049
|
+
const matchedSlice = truncateToWidth3(match.entry.slice(match.matchStart, match.matchStart + match.matchLength), highlightWidth);
|
|
902050
|
+
writeBottomBarText(line2, matchStartCol, highlightWidth, matchedSlice, {
|
|
902051
|
+
fg: "#000000",
|
|
902052
|
+
bg: "#00ffcc",
|
|
902053
|
+
bold: true,
|
|
902054
|
+
underline: true
|
|
902055
|
+
});
|
|
902056
|
+
}
|
|
902057
|
+
return [line2];
|
|
902058
|
+
}
|
|
902059
|
+
|
|
901607
902060
|
// src/renderer/mcp-workspace.ts
|
|
901608
902061
|
var MCP_WORKSPACE_TITLE = "MCP Workspace / Servers";
|
|
901609
902062
|
var MCP_WORKSPACE_LEFT_HEADER = "Servers";
|
|
@@ -902813,17 +903266,23 @@ function buildLeftRows2(workspace, height) {
|
|
|
902813
903266
|
}
|
|
902814
903267
|
function actionCommand(action2) {
|
|
902815
903268
|
if (action2.kind === "workspace")
|
|
902816
|
-
return
|
|
903269
|
+
return "open area";
|
|
902817
903270
|
if (action2.kind === "editor")
|
|
902818
|
-
return action2.editorKind ? `edit ${action2.editorKind}` : "
|
|
903271
|
+
return action2.editorKind ? `edit ${action2.editorKind}` : "edit form";
|
|
902819
903272
|
if (action2.kind === "setting")
|
|
902820
|
-
return action2.settingKey ? `
|
|
903273
|
+
return action2.settingKey ? `setting ${action2.settingKey}` : "setting";
|
|
902821
903274
|
if (action2.kind === "settings-import")
|
|
902822
903275
|
return "import GoodVibes settings";
|
|
903276
|
+
if (action2.kind === "model-picker")
|
|
903277
|
+
return action2.modelPickerFlow === "model" ? "model picker" : "provider/model picker";
|
|
903278
|
+
if (action2.kind === "settings-modal")
|
|
903279
|
+
return action2.settingsTarget ? `settings ${action2.settingsTarget}` : "settings";
|
|
902823
903280
|
if (action2.kind === "local-selection")
|
|
902824
903281
|
return action2.selectionDelta && action2.selectionDelta < 0 ? "select previous" : "select next";
|
|
902825
903282
|
if (action2.kind === "local-operation")
|
|
902826
903283
|
return action2.localOperation ?? "(local action)";
|
|
903284
|
+
if (action2.kind === "onboarding-complete")
|
|
903285
|
+
return "apply and close";
|
|
902827
903286
|
return action2.command ?? "(guidance)";
|
|
902828
903287
|
}
|
|
902829
903288
|
function setupCounts(snapshot2) {
|
|
@@ -902837,6 +903296,11 @@ function setupCounts(snapshot2) {
|
|
|
902837
903296
|
function setupStatusLabel(status) {
|
|
902838
903297
|
return status === "ready" ? "Ready" : status === "recommended" ? "Recommended" : status === "blocked" ? "Blocked" : "Optional";
|
|
902839
903298
|
}
|
|
903299
|
+
function formatMegabytes(bytes) {
|
|
903300
|
+
if (!Number.isFinite(bytes) || bytes <= 0)
|
|
903301
|
+
return "0 MB";
|
|
903302
|
+
return `${Math.round(bytes / (1024 * 1024))} MB`;
|
|
903303
|
+
}
|
|
902840
903304
|
function compactText3(text, maxWidth = 104) {
|
|
902841
903305
|
const normalized3 = text.replace(/\s+/g, " ").trim();
|
|
902842
903306
|
if (normalized3.length === 0)
|
|
@@ -903007,6 +903471,27 @@ function snapshotLines(workspace, category, snapshot2) {
|
|
|
903007
903471
|
base2.push({ text: `Chat route: ${snapshot2.provider} / ${snapshot2.modelDisplayName}`, fg: FULLSCREEN_PALETTE.info }, { text: `Session: ${snapshot2.sessionId}`, fg: FULLSCREEN_PALETTE.muted }, { text: `Policy: ${snapshot2.executionPolicy}; delegated review ${snapshot2.delegatedReviewPolicy}`, fg: FULLSCREEN_PALETTE.good }, conciseSetupLine(snapshot2), ...homeNextActionLines(snapshot2));
|
|
903008
903472
|
} else if (category.id === "setup") {
|
|
903009
903473
|
base2.push(...setupOverviewLines(snapshot2));
|
|
903474
|
+
} else if (category.id === "account-model") {
|
|
903475
|
+
base2.push({ text: `Chat route: ${snapshot2.provider} / ${snapshot2.modelDisplayName}`, fg: FULLSCREEN_PALETTE.info }, { text: `Subscriptions: ${snapshot2.activeSubscriptionCount} active; ${snapshot2.pendingSubscriptionCount} pending; ${snapshot2.availableSubscriptionProviderCount} available.`, fg: snapshot2.activeSubscriptionCount > 0 ? FULLSCREEN_PALETTE.good : snapshot2.pendingSubscriptionCount > 0 ? FULLSCREEN_PALETTE.warn : FULLSCREEN_PALETTE.muted }, { text: `Embedding: ${snapshot2.embeddingProvider}; reasoning ${snapshot2.reasoningEffort}.`, fg: FULLSCREEN_PALETTE.info }, { text: `Helper: ${snapshot2.helperEnabled ? "enabled" : "disabled"}; Tool LLM: ${snapshot2.toolLlmEnabled ? "enabled" : "disabled"}.`, fg: snapshot2.helperEnabled || snapshot2.toolLlmEnabled ? FULLSCREEN_PALETTE.good : FULLSCREEN_PALETTE.muted }, { text: `Cache: ${snapshot2.cacheEnabled ? snapshot2.cacheStableTtl : "off"}; monitor ${snapshot2.cacheMonitorHitRate ? snapshot2.cacheHitRateWarningThreshold : "off"}; failure hints ${snapshot2.providerFailureHints ? "on" : "off"}.`, fg: snapshot2.cacheEnabled ? FULLSCREEN_PALETTE.info : FULLSCREEN_PALETTE.muted });
|
|
903476
|
+
} else if (category.id === "assistant-behavior") {
|
|
903477
|
+
base2.push({ text: `Interaction: ${snapshot2.hitlMode}; guidance ${snapshot2.guidanceMode}; history ${snapshot2.saveHistory ? "saved" : "off"}.`, fg: FULLSCREEN_PALETTE.info }, { text: `Context: compact at ${snapshot2.autoCompactThreshold}; stale warnings ${snapshot2.staleContextWarnings ? "on" : "off"}.`, fg: FULLSCREEN_PALETTE.info }, { text: `Reasoning display: thinking ${snapshot2.showThinking ? "on" : "off"}; summaries ${snapshot2.showReasoningSummary ? "on" : "off"}.`, fg: FULLSCREEN_PALETTE.muted });
|
|
903478
|
+
} else if (category.id === "tools-permissions") {
|
|
903479
|
+
base2.push({ text: `Permission mode: ${snapshot2.permissionMode}.`, fg: snapshot2.permissionMode === "allow-all" ? FULLSCREEN_PALETTE.warn : FULLSCREEN_PALETTE.info }, { text: `Auto-approve ${snapshot2.autoApprove ? "on" : "off"}; tool auto-heal ${snapshot2.toolAutoHeal ? "on" : "off"}; token budget ${snapshot2.toolsDefaultTokenBudget}.`, fg: snapshot2.autoApprove ? FULLSCREEN_PALETTE.warn : FULLSCREEN_PALETTE.info }, { text: `Artifact limit ${formatMegabytes(snapshot2.artifactMaxBytes)}; raw prompt telemetry ${snapshot2.rawPromptTelemetry ? "on" : "off"}.`, fg: snapshot2.rawPromptTelemetry ? FULLSCREEN_PALETTE.warn : FULLSCREEN_PALETTE.muted }, { text: `MCP servers: ${snapshot2.mcpConnectedServerCount}/${snapshot2.mcpServerCount} connected; quarantined ${snapshot2.mcpQuarantinedServerCount}.`, fg: snapshot2.mcpQuarantinedServerCount > 0 ? FULLSCREEN_PALETTE.warn : FULLSCREEN_PALETTE.info }, { text: "MCP and secret setup use forms; selecting a row does not run arbitrary tools.", fg: FULLSCREEN_PALETTE.good });
|
|
903480
|
+
} else if (category.id === "onboarding-display") {
|
|
903481
|
+
base2.push({ text: `Theme: ${snapshot2.theme}; streaming ${snapshot2.stream ? "on" : "off"}; line numbers ${snapshot2.lineNumbers}.`, fg: FULLSCREEN_PALETTE.info }, { text: `Messages: operational ${snapshot2.operationalMessages}; system ${snapshot2.systemMessages}.`, fg: FULLSCREEN_PALETTE.info }, { text: `Release channel: ${snapshot2.releaseChannel}.`, fg: FULLSCREEN_PALETTE.muted });
|
|
903482
|
+
} else if (category.id === "onboarding-channels") {
|
|
903483
|
+
const enabledCount = snapshot2.channels.filter((channel) => channel.enabled).length;
|
|
903484
|
+
const readyCount = snapshot2.channels.filter((channel) => channel.ready).length;
|
|
903485
|
+
const needsConfig = snapshot2.channels.filter((channel) => channel.setupState === "needs-config");
|
|
903486
|
+
const needsTarget = snapshot2.channels.filter((channel) => channel.setupState === "needs-target");
|
|
903487
|
+
base2.push({ text: `Channels: ${readyCount}/${snapshot2.channels.length} ready; ${enabledCount} enabled.`, fg: enabledCount > 0 ? FULLSCREEN_PALETTE.info : FULLSCREEN_PALETTE.muted }, { text: `Needs config: ${needsConfig.length}; needs target: ${needsTarget.length}.`, fg: needsConfig.length > 0 || needsTarget.length > 0 ? FULLSCREEN_PALETTE.warn : FULLSCREEN_PALETTE.good }, { text: "Enable only the channels you want; hidden channel fields appear after the channel is enabled.", fg: FULLSCREEN_PALETTE.good });
|
|
903488
|
+
} else if (category.id === "onboarding-voice-media") {
|
|
903489
|
+
const readiness = snapshot2.voiceMediaReadiness;
|
|
903490
|
+
base2.push({ text: `Voice: ${snapshot2.voiceSurfaceEnabled ? "enabled" : "disabled"}; TTS ${snapshot2.ttsProvider}; voice ${snapshot2.ttsVoice}.`, fg: snapshot2.voiceSurfaceEnabled ? FULLSCREEN_PALETTE.good : FULLSCREEN_PALETTE.info }, { text: `Media readiness: ${readiness.readyMediaProviderCount}/${snapshot2.mediaProviderCount}; generation providers ${snapshot2.mediaGenerationProviderCount}.`, fg: readiness.readyMediaProviderCount > 0 ? FULLSCREEN_PALETTE.good : FULLSCREEN_PALETTE.muted }, { text: `Telephony channel: ${snapshot2.channels.find((channel) => channel.id === "telephony")?.setupState ?? "disabled"}.`, fg: FULLSCREEN_PALETTE.info });
|
|
903491
|
+
} else if (category.id === "onboarding-context") {
|
|
903492
|
+
base2.push({ text: `Local context: ${snapshot2.localMemoryCount} memories, ${snapshot2.localNoteCount} notes, ${snapshot2.localPersonaCount} personas.`, fg: FULLSCREEN_PALETTE.info }, { text: `Skills: ${snapshot2.enabledSkillCount}/${snapshot2.localSkillCount} enabled; routines ${snapshot2.enabledRoutineCount}/${snapshot2.localRoutineCount} enabled.`, fg: FULLSCREEN_PALETTE.info }, { text: `Discovered files: personas ${snapshot2.discoveredBehavior.personas.count}, skills ${snapshot2.discoveredBehavior.skills.count}, routines ${snapshot2.discoveredBehavior.routines.count}.`, fg: FULLSCREEN_PALETTE.muted });
|
|
903493
|
+
} else if (category.id === "onboarding-automation") {
|
|
903494
|
+
base2.push({ text: `Automation: ${snapshot2.automationEnabled ? "enabled" : "disabled"}; max ${snapshot2.automationMaxConcurrentRuns} concurrent; history ${snapshot2.automationRunHistoryLimit}.`, fg: snapshot2.automationEnabled ? FULLSCREEN_PALETTE.good : FULLSCREEN_PALETTE.muted }, { text: `Timeout ${snapshot2.automationDefaultTimeoutMs} ms; catch-up ${snapshot2.automationCatchUpWindowMinutes} min; cooldown ${snapshot2.automationFailureCooldownMs} ms.`, fg: FULLSCREEN_PALETTE.info }, { text: `Delete one-shot jobs after success: ${snapshot2.automationDeleteAfterRun ? "yes" : "no"}.`, fg: snapshot2.automationDeleteAfterRun ? FULLSCREEN_PALETTE.info : FULLSCREEN_PALETTE.muted });
|
|
903010
903495
|
} else if (category.id === "artifacts") {
|
|
903011
903496
|
const mediaReady = snapshot2.voiceMediaReadiness.readyMediaProviderCount;
|
|
903012
903497
|
base2.push({ text: `Chat: ${snapshot2.provider} / ${snapshot2.modelDisplayName}; Knowledge: ${snapshot2.knowledgeRoute}`, fg: FULLSCREEN_PALETTE.info }, { text: `Media: ${mediaReady}/${snapshot2.mediaProviderCount} ready; generation ${snapshot2.mediaGenerationProviderCount}.`, fg: mediaReady > 0 ? FULLSCREEN_PALETTE.good : FULLSCREEN_PALETTE.warn }, { text: "Files: attach, export, inspect, ingest reviewed sources, or generate media.", fg: FULLSCREEN_PALETTE.good }, { text: "Knowledge ingest and media generation require explicit actions.", fg: FULLSCREEN_PALETTE.warn });
|
|
@@ -903263,17 +903748,20 @@ function normalizeFullscreenViewport(lines, width, height) {
|
|
|
903263
903748
|
viewport.push(createEmptyLine(width));
|
|
903264
903749
|
return viewport;
|
|
903265
903750
|
}
|
|
903266
|
-
function
|
|
903751
|
+
function createFullscreenCompositeFromLines(lines, width, height) {
|
|
903267
903752
|
return {
|
|
903268
903753
|
width,
|
|
903269
903754
|
height,
|
|
903270
903755
|
header: [],
|
|
903271
|
-
viewport: normalizeFullscreenViewport(
|
|
903756
|
+
viewport: normalizeFullscreenViewport(lines, width, height),
|
|
903272
903757
|
footer: [],
|
|
903273
903758
|
forceFullRedraw: true,
|
|
903274
903759
|
panelWidth: 0
|
|
903275
903760
|
};
|
|
903276
903761
|
}
|
|
903762
|
+
function createAgentWorkspaceFullscreenComposite(workspace, width, height) {
|
|
903763
|
+
return createFullscreenCompositeFromLines(renderAgentWorkspace(workspace, width, height), width, height);
|
|
903764
|
+
}
|
|
903277
903765
|
|
|
903278
903766
|
// src/shell/service-settings-sync.ts
|
|
903279
903767
|
var AGENT_EXTERNAL_HOST_SERVICE_MESSAGE = "GoodVibes Agent uses a connected GoodVibes host and does not install, start, stop, restart, or uninstall it. Manage host lifecycle outside Agent.";
|
|
@@ -905782,6 +906270,14 @@ async function main() {
|
|
|
905782
906270
|
input.setPanelMouseLayout(null);
|
|
905783
906271
|
activeConversationWidth = width;
|
|
905784
906272
|
conversation.setSplashSuppressed(true);
|
|
906273
|
+
if (input.modelPicker.active) {
|
|
906274
|
+
compositor.composite(createFullscreenCompositeFromLines(renderModelWorkspace(input.modelPicker, width, height), width, height));
|
|
906275
|
+
return;
|
|
906276
|
+
}
|
|
906277
|
+
if (input.settingsModal.active) {
|
|
906278
|
+
compositor.composite(createFullscreenCompositeFromLines(renderSettingsModal(input.settingsModal, width, height), width, height));
|
|
906279
|
+
return;
|
|
906280
|
+
}
|
|
905785
906281
|
compositor.composite(createAgentWorkspaceFullscreenComposite(input.agentWorkspace, width, height));
|
|
905786
906282
|
return;
|
|
905787
906283
|
}
|