@pellux/goodvibes-agent 1.1.4 → 1.1.5
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 +6 -0
- package/dist/package/main.js +1273 -899
- 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-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
|
@@ -450372,23 +450372,6 @@ function createSchema2(db) {
|
|
|
450372
450372
|
`);
|
|
450373
450373
|
db.run(`CREATE INDEX IF NOT EXISTS idx_knowledge_schedules_job_id ON knowledge_schedules(job_id)`);
|
|
450374
450374
|
}
|
|
450375
|
-
function getKnowledgeSchemaStatements() {
|
|
450376
|
-
const statements = [];
|
|
450377
|
-
createSchema2({
|
|
450378
|
-
run(sql) {
|
|
450379
|
-
const normalized = sql.trim();
|
|
450380
|
-
if (normalized.length > 0)
|
|
450381
|
-
statements.push(normalized);
|
|
450382
|
-
}
|
|
450383
|
-
});
|
|
450384
|
-
return statements;
|
|
450385
|
-
}
|
|
450386
|
-
function renderKnowledgeSchemaSql() {
|
|
450387
|
-
return `${getKnowledgeSchemaStatements().map((statement) => statement.endsWith(";") ? statement : `${statement};`).join(`
|
|
450388
|
-
|
|
450389
|
-
`)}
|
|
450390
|
-
`;
|
|
450391
|
-
}
|
|
450392
450375
|
function rowObject(columns, values2) {
|
|
450393
450376
|
return Object.fromEntries(columns.map((column, index) => [column, values2[index]]));
|
|
450394
450377
|
}
|
|
@@ -763671,9 +763654,6 @@ var init_ingest = __esm(() => {
|
|
|
763671
763654
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/browser-history/index.js
|
|
763672
763655
|
var init_browser_history = __esm(() => {
|
|
763673
763656
|
init_ingest();
|
|
763674
|
-
init_discover();
|
|
763675
|
-
init_readers();
|
|
763676
|
-
init_paths2();
|
|
763677
763657
|
});
|
|
763678
763658
|
|
|
763679
763659
|
// node_modules/graphql/jsutils/devAssert.mjs
|
|
@@ -781313,7 +781293,6 @@ var init_semantic = __esm(() => {
|
|
|
781313
781293
|
init_llm();
|
|
781314
781294
|
init_gap_repair();
|
|
781315
781295
|
init_service4();
|
|
781316
|
-
init_self_improvement();
|
|
781317
781296
|
});
|
|
781318
781297
|
|
|
781319
781298
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/home-graph/helpers.js
|
|
@@ -785282,40 +785261,8 @@ var init_map_view = __esm(() => {
|
|
|
785282
785261
|
});
|
|
785283
785262
|
|
|
785284
785263
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/home-graph/types.js
|
|
785285
|
-
var
|
|
785264
|
+
var HOME_GRAPH_CAPABILITIES;
|
|
785286
785265
|
var init_types15 = __esm(() => {
|
|
785287
|
-
HOME_GRAPH_NODE_KINDS = [
|
|
785288
|
-
"ha_home",
|
|
785289
|
-
"ha_entity",
|
|
785290
|
-
"ha_device",
|
|
785291
|
-
"ha_area",
|
|
785292
|
-
"ha_automation",
|
|
785293
|
-
"ha_script",
|
|
785294
|
-
"ha_scene",
|
|
785295
|
-
"ha_label",
|
|
785296
|
-
"ha_integration",
|
|
785297
|
-
"ha_room",
|
|
785298
|
-
"ha_device_passport",
|
|
785299
|
-
"ha_maintenance_item",
|
|
785300
|
-
"ha_troubleshooting_case",
|
|
785301
|
-
"ha_purchase",
|
|
785302
|
-
"ha_network_node"
|
|
785303
|
-
];
|
|
785304
|
-
HOME_GRAPH_RELATIONS = [
|
|
785305
|
-
"controls",
|
|
785306
|
-
"located_in",
|
|
785307
|
-
"belongs_to_device",
|
|
785308
|
-
"has_manual",
|
|
785309
|
-
"has_receipt",
|
|
785310
|
-
"has_warranty",
|
|
785311
|
-
"has_issue",
|
|
785312
|
-
"fixed_by",
|
|
785313
|
-
"uses_battery",
|
|
785314
|
-
"connected_via",
|
|
785315
|
-
"part_of_network",
|
|
785316
|
-
"mentioned_by",
|
|
785317
|
-
"source_for"
|
|
785318
|
-
];
|
|
785319
785266
|
HOME_GRAPH_CAPABILITIES = [
|
|
785320
785267
|
"knowledge-space-isolation",
|
|
785321
785268
|
"snapshot-sync",
|
|
@@ -786722,7 +786669,6 @@ var init_service5 = __esm(() => {
|
|
|
786722
786669
|
var init_home_graph = __esm(() => {
|
|
786723
786670
|
init_service5();
|
|
786724
786671
|
init_extension();
|
|
786725
|
-
init_types15();
|
|
786726
786672
|
});
|
|
786727
786673
|
|
|
786728
786674
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/store-refinement.js
|
|
@@ -789050,14 +788996,10 @@ var init_service6 = __esm(() => {
|
|
|
789050
788996
|
var init_project_planning = __esm(() => {
|
|
789051
788997
|
init_service6();
|
|
789052
788998
|
init_helpers3();
|
|
789053
|
-
init_readiness();
|
|
789054
788999
|
});
|
|
789055
789000
|
|
|
789056
789001
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/persistence.js
|
|
789057
|
-
var init_persistence =
|
|
789058
|
-
init_store_schema();
|
|
789059
|
-
init_store_load();
|
|
789060
|
-
});
|
|
789002
|
+
var init_persistence = () => {};
|
|
789061
789003
|
|
|
789062
789004
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/projections.js
|
|
789063
789005
|
class KnowledgeProjectionService {
|
|
@@ -792565,21 +792507,21 @@ var init_service7 = __esm(() => {
|
|
|
792565
792507
|
var exports_knowledge = {};
|
|
792566
792508
|
__export(exports_knowledge, {
|
|
792567
792509
|
withKnowledgeSpace: () => withKnowledgeSpace,
|
|
792568
|
-
uniqKnowledgeValues: () =>
|
|
792569
|
-
stabilizeKnowledgeText: () =>
|
|
792570
|
-
runKnowledgeSemanticSelfImprovement: () =>
|
|
792510
|
+
uniqKnowledgeValues: () => uniq3,
|
|
792511
|
+
stabilizeKnowledgeText: () => stableText2,
|
|
792512
|
+
runKnowledgeSemanticSelfImprovement: () => runKnowledgeSemanticSelfImprovement2,
|
|
792571
792513
|
resolveProjectPlanningSpace: () => resolveProjectPlanningSpace,
|
|
792572
|
-
resolveKnowledgeDbPathFromControlPlaneDir: () =>
|
|
792514
|
+
resolveKnowledgeDbPathFromControlPlaneDir: () => resolveKnowledgeDbPathFromControlPlaneDir2,
|
|
792573
792515
|
renderPacket: () => renderPacket,
|
|
792574
792516
|
renderKnowledgeSchemaSql: () => renderKnowledgeSchemaSql,
|
|
792575
792517
|
renderKnowledgeMap: () => renderKnowledgeMap,
|
|
792576
792518
|
readKnowledgeSearchText: () => readKnowledgeSearchText,
|
|
792577
|
-
readBrowserKnowledgeProfile: () =>
|
|
792519
|
+
readBrowserKnowledgeProfile: () => readBrowserKnowledgeProfile2,
|
|
792578
792520
|
projectPlanningSourceId: () => projectPlanningSourceId,
|
|
792579
792521
|
projectPlanningProjectIdFromPath: () => projectPlanningProjectIdFromPath,
|
|
792580
792522
|
projectPlanningCanonicalUri: () => projectPlanningCanonicalUri,
|
|
792581
792523
|
projectKnowledgeSpaceId: () => projectKnowledgeSpaceId,
|
|
792582
|
-
parseKnowledgeJsonValue: () =>
|
|
792524
|
+
parseKnowledgeJsonValue: () => parseJsonValue2,
|
|
792583
792525
|
normalizeProjectId: () => normalizeProjectId,
|
|
792584
792526
|
normalizeKnowledgeSpaceId: () => normalizeKnowledgeSpaceId,
|
|
792585
792527
|
normalizeHomeAssistantInstallationId: () => normalizeHomeAssistantInstallationId,
|
|
@@ -792587,12 +792529,12 @@ __export(exports_knowledge, {
|
|
|
792587
792529
|
materializeGeneratedKnowledgeProjection: () => materializeGeneratedKnowledgeProjection,
|
|
792588
792530
|
looksLikeRawPdfPayload: () => looksLikeRawPdfPayload,
|
|
792589
792531
|
looksBinaryLikeText: () => looksBinaryLikeText,
|
|
792590
|
-
loadKnowledgeStoreSnapshot: () =>
|
|
792532
|
+
loadKnowledgeStoreSnapshot: () => loadKnowledgeStoreSnapshot2,
|
|
792591
792533
|
listGeneratedKnowledgePages: () => listGeneratedKnowledgePages,
|
|
792592
|
-
listBrowserKinds: () =>
|
|
792534
|
+
listBrowserKinds: () => listBrowserKinds2,
|
|
792593
792535
|
knowledgeSpaceMetadata: () => knowledgeSpaceMetadata,
|
|
792594
792536
|
knowledgePageSourceWeight: () => knowledgePageSourceWeight,
|
|
792595
|
-
knowledgeNowMs: () =>
|
|
792537
|
+
knowledgeNowMs: () => nowMs2,
|
|
792596
792538
|
knowledgeExtractionNeedsRefresh: () => knowledgeExtractionNeedsRefresh,
|
|
792597
792539
|
isUsefulKnowledgePageSourceCandidate: () => isUsefulKnowledgePageSourceCandidate,
|
|
792598
792540
|
isUsefulKnowledgePageSource: () => isUsefulKnowledgePageSource,
|
|
@@ -792612,12 +792554,12 @@ __export(exports_knowledge, {
|
|
|
792612
792554
|
generatedKnowledgeSourceId: () => generatedKnowledgeSourceId,
|
|
792613
792555
|
generatedKnowledgeCanonicalUri: () => generatedKnowledgeCanonicalUri,
|
|
792614
792556
|
extractKnowledgeArtifact: () => extractKnowledgeArtifact,
|
|
792615
|
-
evaluateProjectPlanningReadiness: () =>
|
|
792616
|
-
discoverBrowserKnowledgeProfiles: () =>
|
|
792557
|
+
evaluateProjectPlanningReadiness: () => evaluateProjectPlanningReadiness2,
|
|
792558
|
+
discoverBrowserKnowledgeProfiles: () => discoverBrowserKnowledgeProfiles2,
|
|
792617
792559
|
createWebKnowledgeGapRepairer: () => createWebKnowledgeGapRepairer,
|
|
792618
792560
|
createProviderBackedKnowledgeSemanticLlm: () => createProviderBackedKnowledgeSemanticLlm,
|
|
792619
792561
|
createMemoryApi: () => createMemoryApi,
|
|
792620
|
-
createKnowledgeSchema: () =>
|
|
792562
|
+
createKnowledgeSchema: () => createSchema3,
|
|
792621
792563
|
createKnowledgeApi: () => createKnowledgeApi,
|
|
792622
792564
|
createDefaultKnowledgeConnectorRegistry: () => createDefaultKnowledgeConnectorRegistry,
|
|
792623
792565
|
compareKnowledgePageSources: () => compareKnowledgePageSources,
|
|
@@ -795056,7 +794998,7 @@ var init_delivery_manager = __esm(() => {
|
|
|
795056
794998
|
});
|
|
795057
794999
|
|
|
795058
795000
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/automation/scheduler-capacity.js
|
|
795059
|
-
function computeSchedulerCapacity(slotsTotal, runs,
|
|
795001
|
+
function computeSchedulerCapacity(slotsTotal, runs, nowMs3 = Date.now()) {
|
|
795060
795002
|
let slotsInUse = 0;
|
|
795061
795003
|
const queuedRuns = [];
|
|
795062
795004
|
for (const run7 of runs) {
|
|
@@ -795066,7 +795008,7 @@ function computeSchedulerCapacity(slotsTotal, runs, nowMs2 = Date.now()) {
|
|
|
795066
795008
|
queuedRuns.push(run7);
|
|
795067
795009
|
}
|
|
795068
795010
|
const queueDepth = queuedRuns.length;
|
|
795069
|
-
const oldestQueuedAgeMs = queueDepth > 0 ?
|
|
795011
|
+
const oldestQueuedAgeMs = queueDepth > 0 ? nowMs3 - Math.min(...queuedRuns.map((r6) => r6.queuedAt)) : null;
|
|
795070
795012
|
return { slotsTotal, slotsInUse, queueDepth, oldestQueuedAgeMs };
|
|
795071
795013
|
}
|
|
795072
795014
|
|
|
@@ -817092,7 +817034,7 @@ var createStyledCell = (char, overrides = {}) => ({
|
|
|
817092
817034
|
// src/version.ts
|
|
817093
817035
|
import { readFileSync } from "fs";
|
|
817094
817036
|
import { join } from "path";
|
|
817095
|
-
var _version = "1.1.
|
|
817037
|
+
var _version = "1.1.5";
|
|
817096
817038
|
try {
|
|
817097
817039
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, "..", "package.json"), "utf-8"));
|
|
817098
817040
|
_version = typeof pkg.version === "string" ? pkg.version : _version;
|
|
@@ -839605,7 +839547,7 @@ var WORK_PLAN_STATUSES = [
|
|
|
839605
839547
|
"failed",
|
|
839606
839548
|
"cancelled"
|
|
839607
839549
|
];
|
|
839608
|
-
function
|
|
839550
|
+
function nowMs3() {
|
|
839609
839551
|
return Date.now();
|
|
839610
839552
|
}
|
|
839611
839553
|
function isObject4(value) {
|
|
@@ -839711,7 +839653,7 @@ class WorkPlanStore {
|
|
|
839711
839653
|
if (!normalizedTitle)
|
|
839712
839654
|
throw new Error("Work plan item title is required.");
|
|
839713
839655
|
const plan = this.readPlan();
|
|
839714
|
-
const time4 =
|
|
839656
|
+
const time4 = nowMs3();
|
|
839715
839657
|
const item = {
|
|
839716
839658
|
id: createItemId(),
|
|
839717
839659
|
title: normalizedTitle,
|
|
@@ -839735,7 +839677,7 @@ class WorkPlanStore {
|
|
|
839735
839677
|
updateItem(idOrPrefix, patch2) {
|
|
839736
839678
|
const plan = this.readPlan();
|
|
839737
839679
|
const item = this.resolveItem(plan, idOrPrefix);
|
|
839738
|
-
const time4 =
|
|
839680
|
+
const time4 = nowMs3();
|
|
839739
839681
|
const nextStatus = patch2.status ?? item.status;
|
|
839740
839682
|
const next = this.pruneItem({
|
|
839741
839683
|
...item,
|
|
@@ -839768,7 +839710,7 @@ class WorkPlanStore {
|
|
|
839768
839710
|
removeItem(idOrPrefix) {
|
|
839769
839711
|
const plan = this.readPlan();
|
|
839770
839712
|
const item = this.resolveItem(plan, idOrPrefix);
|
|
839771
|
-
const time4 =
|
|
839713
|
+
const time4 = nowMs3();
|
|
839772
839714
|
const remaining = plan.items.filter((candidate) => candidate.id !== item.id);
|
|
839773
839715
|
this.writePlan({
|
|
839774
839716
|
...plan,
|
|
@@ -839788,7 +839730,7 @@ class WorkPlanStore {
|
|
|
839788
839730
|
...plan,
|
|
839789
839731
|
items: remaining,
|
|
839790
839732
|
activeItemId: remaining[0]?.id,
|
|
839791
|
-
updatedAt:
|
|
839733
|
+
updatedAt: nowMs3()
|
|
839792
839734
|
});
|
|
839793
839735
|
return removed;
|
|
839794
839736
|
}
|
|
@@ -839827,7 +839769,7 @@ class WorkPlanStore {
|
|
|
839827
839769
|
const parsed = JSON.parse(raw);
|
|
839828
839770
|
if (!isObject4(parsed))
|
|
839829
839771
|
return this.createEmptyPlan();
|
|
839830
|
-
const time4 =
|
|
839772
|
+
const time4 = nowMs3();
|
|
839831
839773
|
const createdAt = typeof parsed.createdAt === "number" ? parsed.createdAt : time4;
|
|
839832
839774
|
const updatedAt = typeof parsed.updatedAt === "number" ? parsed.updatedAt : createdAt;
|
|
839833
839775
|
const items = Array.isArray(parsed.items) ? parsed.items.map((item) => normalizeItem(item, createdAt)).filter((item) => item !== null) : [];
|
|
@@ -839846,7 +839788,7 @@ class WorkPlanStore {
|
|
|
839846
839788
|
};
|
|
839847
839789
|
}
|
|
839848
839790
|
createEmptyPlan() {
|
|
839849
|
-
const time4 =
|
|
839791
|
+
const time4 = nowMs3();
|
|
839850
839792
|
return {
|
|
839851
839793
|
id: createPlanId(this.options.projectId, this.options.projectRoot),
|
|
839852
839794
|
projectId: this.options.projectId,
|
|
@@ -849851,13 +849793,13 @@ init_state3();
|
|
|
849851
849793
|
|
|
849852
849794
|
// src/input/commands/recall-shared.ts
|
|
849853
849795
|
var VALID_CLASSES = ["decision", "constraint", "incident", "pattern", "fact", "risk", "runbook", "architecture", "ownership"];
|
|
849854
|
-
var
|
|
849796
|
+
var VALID_SCOPES = ["session", "project", "team"];
|
|
849855
849797
|
var VALID_REVIEW_STATES = ["fresh", "reviewed", "stale", "contradicted"];
|
|
849856
849798
|
function isValidClass(s4) {
|
|
849857
849799
|
return VALID_CLASSES.includes(s4);
|
|
849858
849800
|
}
|
|
849859
849801
|
function isValidScope(s4) {
|
|
849860
|
-
return
|
|
849802
|
+
return VALID_SCOPES.includes(s4);
|
|
849861
849803
|
}
|
|
849862
849804
|
function isValidReviewState(s4) {
|
|
849863
849805
|
return VALID_REVIEW_STATES.includes(s4);
|
|
@@ -849900,7 +849842,7 @@ function handleRecallSearch(args2, context) {
|
|
|
849900
849842
|
if (isValidScope(scope))
|
|
849901
849843
|
filter.scope = scope;
|
|
849902
849844
|
else {
|
|
849903
|
-
context.print(`[memory] Unknown scope "${scope}". Valid values ${
|
|
849845
|
+
context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
849904
849846
|
return;
|
|
849905
849847
|
}
|
|
849906
849848
|
}
|
|
@@ -850075,7 +850017,7 @@ function handleRecallList(args2, context) {
|
|
|
850075
850017
|
if (scopeIdx !== -1 && args2[scopeIdx + 1]) {
|
|
850076
850018
|
const scope = args2[scopeIdx + 1];
|
|
850077
850019
|
if (!isValidScope(scope)) {
|
|
850078
|
-
context.print(`[memory] Unknown scope "${scope}". Valid values ${
|
|
850020
|
+
context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
850079
850021
|
return;
|
|
850080
850022
|
}
|
|
850081
850023
|
filter.scope = scope;
|
|
@@ -850125,7 +850067,7 @@ async function handleRecallAdd(args2, context) {
|
|
|
850125
850067
|
const tags = tagsRaw ? tagsRaw.split(",").map((token) => token.trim()).filter(Boolean) : [];
|
|
850126
850068
|
const scope = scopeRaw && isValidScope(scopeRaw) ? scopeRaw : "project";
|
|
850127
850069
|
if (scopeRaw && !isValidScope(scopeRaw)) {
|
|
850128
|
-
context.print(`[memory] Invalid scope "${scopeRaw}". Valid values ${
|
|
850070
|
+
context.print(`[memory] Invalid scope "${scopeRaw}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
850129
850071
|
return;
|
|
850130
850072
|
}
|
|
850131
850073
|
const provenance = [];
|
|
@@ -850259,7 +850201,7 @@ function handleRecallExport(args2, context) {
|
|
|
850259
850201
|
if (scopeIdx !== -1 && commandArgs[scopeIdx + 1]) {
|
|
850260
850202
|
const scope = commandArgs[scopeIdx + 1];
|
|
850261
850203
|
if (!isValidScope(scope)) {
|
|
850262
|
-
context.print(`[memory] Unknown scope "${scope}". Valid values ${
|
|
850204
|
+
context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
850263
850205
|
return;
|
|
850264
850206
|
}
|
|
850265
850207
|
filter.scope = scope;
|
|
@@ -850338,7 +850280,7 @@ function handleRecallHandoffExport(args2, context) {
|
|
|
850338
850280
|
const scopeIdx = commandArgs.indexOf("--scope");
|
|
850339
850281
|
const scopeRaw = scopeIdx !== -1 ? commandArgs[scopeIdx + 1] : "team";
|
|
850340
850282
|
if (!scopeRaw || !isValidScope(scopeRaw)) {
|
|
850341
|
-
context.print(`[memory] Unknown scope "${scopeRaw ?? ""}". Valid values ${
|
|
850283
|
+
context.print(`[memory] Unknown scope "${scopeRaw ?? ""}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
850342
850284
|
return;
|
|
850343
850285
|
}
|
|
850344
850286
|
const bundle = memory.exportBundle({ scope: scopeRaw });
|
|
@@ -850454,7 +850396,7 @@ function handleRecallPromote(args2, context) {
|
|
|
850454
850396
|
const id = parsed.rest[0];
|
|
850455
850397
|
const scope = parsed.rest[1];
|
|
850456
850398
|
if (!id || !scope || !isValidScope(scope)) {
|
|
850457
|
-
context.print(`[memory] Usage: /memory promote <id> <${
|
|
850399
|
+
context.print(`[memory] Usage: /memory promote <id> <${VALID_SCOPES.join("|")}> --yes`);
|
|
850458
850400
|
return;
|
|
850459
850401
|
}
|
|
850460
850402
|
if (!parsed.yes) {
|
|
@@ -858623,7 +858565,7 @@ var AGENT_WORKSPACE_CATEGORY_IDS = [
|
|
|
858623
858565
|
"onboarding-channels",
|
|
858624
858566
|
"onboarding-voice-media",
|
|
858625
858567
|
"onboarding-context",
|
|
858626
|
-
"onboarding-
|
|
858568
|
+
"onboarding-automation",
|
|
858627
858569
|
"research",
|
|
858628
858570
|
"artifacts",
|
|
858629
858571
|
"conversation",
|
|
@@ -862058,6 +862000,7 @@ Use /channels list to see available channel ids.`);
|
|
|
862058
862000
|
}
|
|
862059
862001
|
|
|
862060
862002
|
// src/input/agent-workspace-snapshot.ts
|
|
862003
|
+
init_config8();
|
|
862061
862004
|
import { basename as basename6, sep as sep3 } from "path";
|
|
862062
862005
|
|
|
862063
862006
|
// src/agent/behavior-discovery-summary.ts
|
|
@@ -862265,6 +862208,13 @@ function buildAgentWorkspaceSetupChecklist(input) {
|
|
|
862265
862208
|
detail: providerReady ? `Current chat route is ${input.provider} / ${input.model}.` : "Choose a provider and model before relying on assistant turns.",
|
|
862266
862209
|
command: "Setup -> Provider and model"
|
|
862267
862210
|
},
|
|
862211
|
+
{
|
|
862212
|
+
id: "subscriptions",
|
|
862213
|
+
label: "Provider subscriptions",
|
|
862214
|
+
status: input.activeSubscriptionCount > 0 ? "ready" : input.pendingSubscriptionCount > 0 ? "recommended" : input.availableSubscriptionProviderCount > 0 ? "recommended" : "optional",
|
|
862215
|
+
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.",
|
|
862216
|
+
command: "Start -> Start subscription login"
|
|
862217
|
+
},
|
|
862268
862218
|
{
|
|
862269
862219
|
id: "agent-knowledge",
|
|
862270
862220
|
label: "Agent Knowledge",
|
|
@@ -862833,6 +862783,41 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
|
|
|
862833
862783
|
const ttsVoice = readConfigString3(context, "tts.voice", "(voice default)");
|
|
862834
862784
|
const ttsLlmProvider = readConfigString3(context, "tts.llmProvider", "");
|
|
862835
862785
|
const ttsLlmModel = readConfigString3(context, "tts.llmModel", "");
|
|
862786
|
+
const embeddingProvider = readConfigString3(context, "provider.embeddingProvider", "(provider default)");
|
|
862787
|
+
const reasoningEffort = readConfigString3(context, "provider.reasoningEffort", "(default)");
|
|
862788
|
+
const helperEnabled = readConfigBoolean3(context, "helper.enabled", false);
|
|
862789
|
+
const toolLlmEnabled = readConfigBoolean3(context, "tools.llmEnabled", false);
|
|
862790
|
+
const providerFailureHints = readConfigBoolean3(context, "behavior.suggestAlternativeOnProviderFail", false);
|
|
862791
|
+
const cacheEnabled = readConfigBoolean3(context, "cache.enabled", true);
|
|
862792
|
+
const cacheStableTtl = readConfigString3(context, "cache.stableTtl", "(default)");
|
|
862793
|
+
const cacheMonitorHitRate = readConfigBoolean3(context, "cache.monitorHitRate", true);
|
|
862794
|
+
const cacheHitRateWarningThreshold = readConfigNumber(context, "cache.hitRateWarningThreshold", 0.3);
|
|
862795
|
+
const hitlMode = readConfigString3(context, "behavior.hitlMode", "(default)");
|
|
862796
|
+
const guidanceMode = readConfigString3(context, "behavior.guidanceMode", "(default)");
|
|
862797
|
+
const saveHistory2 = readConfigBoolean3(context, "behavior.saveHistory", true);
|
|
862798
|
+
const autoApprove = readConfigBoolean3(context, "behavior.autoApprove", false);
|
|
862799
|
+
const autoCompactThreshold = readConfigNumber(context, "behavior.autoCompactThreshold", 0);
|
|
862800
|
+
const staleContextWarnings = readConfigBoolean3(context, "behavior.staleContextWarnings", false);
|
|
862801
|
+
const showThinking = readConfigBoolean3(context, "display.showThinking", false);
|
|
862802
|
+
const showReasoningSummary = readConfigBoolean3(context, "display.showReasoningSummary", false);
|
|
862803
|
+
const theme = readConfigString3(context, "display.theme", "(default)");
|
|
862804
|
+
const stream6 = readConfigBoolean3(context, "display.stream", true);
|
|
862805
|
+
const lineNumbers = readConfigString3(context, "display.lineNumbers", "(default)");
|
|
862806
|
+
const operationalMessages = readConfigString3(context, "ui.operationalMessages", "(default)");
|
|
862807
|
+
const systemMessages = readConfigString3(context, "ui.systemMessages", "(default)");
|
|
862808
|
+
const releaseChannel = readConfigString3(context, "release.channel", "(default)");
|
|
862809
|
+
const permissionMode = readConfigString3(context, "permissions.mode", "(default)");
|
|
862810
|
+
const toolAutoHeal = readConfigBoolean3(context, "tools.autoHeal", false);
|
|
862811
|
+
const toolsDefaultTokenBudget = readConfigNumber(context, "tools.defaultTokenBudget", 5000);
|
|
862812
|
+
const artifactMaxBytes = readConfigNumber(context, "storage.artifacts.maxBytes", 512 * 1024 * 1024);
|
|
862813
|
+
const rawPromptTelemetry = readConfigBoolean3(context, "telemetry.includeRawPrompts", false);
|
|
862814
|
+
const automationEnabled = readConfigBoolean3(context, "automation.enabled", false);
|
|
862815
|
+
const automationMaxConcurrentRuns = readConfigNumber(context, "automation.maxConcurrentRuns", 4);
|
|
862816
|
+
const automationRunHistoryLimit = readConfigNumber(context, "automation.runHistoryLimit", 100);
|
|
862817
|
+
const automationDefaultTimeoutMs = readConfigNumber(context, "automation.defaultTimeoutMs", 15 * 60 * 1000);
|
|
862818
|
+
const automationCatchUpWindowMinutes = readConfigNumber(context, "automation.catchUpWindowMinutes", 30);
|
|
862819
|
+
const automationFailureCooldownMs = readConfigNumber(context, "automation.failureCooldownMs", 5 * 60 * 1000);
|
|
862820
|
+
const automationDeleteAfterRun = readConfigBoolean3(context, "automation.deleteAfterRun", false);
|
|
862836
862821
|
const runtimeBaseUrl = `http://${host}:${port}`;
|
|
862837
862822
|
const companionAccess = (() => {
|
|
862838
862823
|
const homeDirectory = context.workspace?.shellPaths?.homeDirectory ?? "";
|
|
@@ -862854,6 +862839,18 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
|
|
|
862854
862839
|
nextStep
|
|
862855
862840
|
};
|
|
862856
862841
|
})();
|
|
862842
|
+
const subscriptionSnapshot = (() => {
|
|
862843
|
+
try {
|
|
862844
|
+
const manager5 = context.platform?.subscriptionManager;
|
|
862845
|
+
const services = context.platform?.serviceRegistry;
|
|
862846
|
+
const active = manager5?.list?.().length ?? 0;
|
|
862847
|
+
const pending = manager5?.listPending?.().length ?? 0;
|
|
862848
|
+
const available = services ? listAvailableSubscriptionProviders(services.getAll()).length : 0;
|
|
862849
|
+
return { active, pending, available };
|
|
862850
|
+
} catch {
|
|
862851
|
+
return { active: 0, pending: 0, available: 0 };
|
|
862852
|
+
}
|
|
862853
|
+
})();
|
|
862857
862854
|
const channels = buildAgentWorkspaceChannels(context);
|
|
862858
862855
|
const voiceMediaReadiness = buildAgentWorkspaceVoiceMediaReadiness({
|
|
862859
862856
|
context,
|
|
@@ -862864,6 +862861,9 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
|
|
|
862864
862861
|
provider: provider5,
|
|
862865
862862
|
model,
|
|
862866
862863
|
runtimeBaseUrl,
|
|
862864
|
+
activeSubscriptionCount: subscriptionSnapshot.active,
|
|
862865
|
+
pendingSubscriptionCount: subscriptionSnapshot.pending,
|
|
862866
|
+
availableSubscriptionProviderCount: subscriptionSnapshot.available,
|
|
862867
862867
|
sessionMemoryCount,
|
|
862868
862868
|
localMemoryCount: memorySnapshot.count,
|
|
862869
862869
|
localMemoryReviewQueueCount: memorySnapshot.reviewQueueCount,
|
|
@@ -862891,11 +862891,49 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
|
|
|
862891
862891
|
provider: provider5,
|
|
862892
862892
|
model,
|
|
862893
862893
|
modelDisplayName: currentModel?.displayName ?? model,
|
|
862894
|
+
embeddingProvider,
|
|
862895
|
+
reasoningEffort,
|
|
862896
|
+
helperEnabled,
|
|
862897
|
+
toolLlmEnabled,
|
|
862898
|
+
providerFailureHints,
|
|
862899
|
+
cacheEnabled,
|
|
862900
|
+
cacheStableTtl,
|
|
862901
|
+
cacheMonitorHitRate,
|
|
862902
|
+
cacheHitRateWarningThreshold,
|
|
862903
|
+
hitlMode,
|
|
862904
|
+
guidanceMode,
|
|
862905
|
+
saveHistory: saveHistory2,
|
|
862906
|
+
autoApprove,
|
|
862907
|
+
autoCompactThreshold,
|
|
862908
|
+
staleContextWarnings,
|
|
862909
|
+
showThinking,
|
|
862910
|
+
showReasoningSummary,
|
|
862911
|
+
theme,
|
|
862912
|
+
stream: stream6,
|
|
862913
|
+
lineNumbers,
|
|
862914
|
+
operationalMessages,
|
|
862915
|
+
systemMessages,
|
|
862916
|
+
releaseChannel,
|
|
862917
|
+
permissionMode,
|
|
862918
|
+
toolAutoHeal,
|
|
862919
|
+
toolsDefaultTokenBudget,
|
|
862920
|
+
artifactMaxBytes,
|
|
862921
|
+
rawPromptTelemetry,
|
|
862922
|
+
automationEnabled,
|
|
862923
|
+
automationMaxConcurrentRuns,
|
|
862924
|
+
automationRunHistoryLimit,
|
|
862925
|
+
automationDefaultTimeoutMs,
|
|
862926
|
+
automationCatchUpWindowMinutes,
|
|
862927
|
+
automationFailureCooldownMs,
|
|
862928
|
+
automationDeleteAfterRun,
|
|
862894
862929
|
sessionId: context.session?.runtime?.sessionId ?? "unknown",
|
|
862895
862930
|
workingDirectory: context.workspace?.shellPaths?.workingDirectory ?? "unavailable",
|
|
862896
862931
|
homeDirectory: context.workspace?.shellPaths?.homeDirectory ?? "unavailable",
|
|
862897
862932
|
runtimeBaseUrl,
|
|
862898
862933
|
runtimeOwnership: "external",
|
|
862934
|
+
activeSubscriptionCount: subscriptionSnapshot.active,
|
|
862935
|
+
pendingSubscriptionCount: subscriptionSnapshot.pending,
|
|
862936
|
+
availableSubscriptionProviderCount: subscriptionSnapshot.available,
|
|
862899
862937
|
sessionMemoryCount,
|
|
862900
862938
|
localMemoryCount: memorySnapshot.count,
|
|
862901
862939
|
localMemoryReviewQueueCount: memorySnapshot.reviewQueueCount,
|
|
@@ -866599,7 +866637,7 @@ import { mkdirSync as mkdirSync66, readFileSync as readFileSync88, writeFileSync
|
|
|
866599
866637
|
import { dirname as dirname64, resolve as resolve39 } from "path";
|
|
866600
866638
|
init_state3();
|
|
866601
866639
|
var VALID_CLASSES2 = ["decision", "constraint", "incident", "pattern", "fact", "risk", "runbook", "architecture", "ownership"];
|
|
866602
|
-
var
|
|
866640
|
+
var VALID_SCOPES3 = ["session", "project", "team"];
|
|
866603
866641
|
var VALID_REVIEW_STATES3 = ["fresh", "reviewed", "stale", "contradicted"];
|
|
866604
866642
|
var VALID_PROVENANCE_KINDS = ["session", "turn", "task", "event", "file"];
|
|
866605
866643
|
var VALUE_OPTIONS = new Set([
|
|
@@ -866699,7 +866737,7 @@ function isMemoryClass2(value) {
|
|
|
866699
866737
|
return VALID_CLASSES2.includes(value);
|
|
866700
866738
|
}
|
|
866701
866739
|
function isMemoryScope2(value) {
|
|
866702
|
-
return
|
|
866740
|
+
return VALID_SCOPES3.includes(value);
|
|
866703
866741
|
}
|
|
866704
866742
|
function isReviewState(value) {
|
|
866705
866743
|
return VALID_REVIEW_STATES3.includes(value);
|
|
@@ -866714,7 +866752,7 @@ function requireClass(value) {
|
|
|
866714
866752
|
}
|
|
866715
866753
|
function requireScope(value) {
|
|
866716
866754
|
if (!value || !isMemoryScope2(value))
|
|
866717
|
-
throw new Error(`Invalid memory scope "${value ?? ""}". Valid values ${
|
|
866755
|
+
throw new Error(`Invalid memory scope "${value ?? ""}". Valid values ${VALID_SCOPES3.join(", ")}`);
|
|
866718
866756
|
return value;
|
|
866719
866757
|
}
|
|
866720
866758
|
function optionalScope(value) {
|
|
@@ -881486,7 +881524,7 @@ function createAgentWorkspaceBasicCommandEditor(kind2) {
|
|
|
881486
881524
|
selectedFieldIndex: 0,
|
|
881487
881525
|
message: "Inspect one provider subscription route without starting login or printing token values.",
|
|
881488
881526
|
fields: [
|
|
881489
|
-
{ id: "provider", label: "Provider", value: "openai", required: true, multiline: false, hint: "Subscription provider id
|
|
881527
|
+
{ id: "provider", label: "Provider", value: "openai", required: true, multiline: false, hint: "Subscription provider id, such as openai." }
|
|
881490
881528
|
]
|
|
881491
881529
|
};
|
|
881492
881530
|
}
|
|
@@ -881496,12 +881534,11 @@ function createAgentWorkspaceBasicCommandEditor(kind2) {
|
|
|
881496
881534
|
mode: "create",
|
|
881497
881535
|
title: "Start Provider Subscription Login",
|
|
881498
881536
|
selectedFieldIndex: 0,
|
|
881499
|
-
message: "Begin one provider subscription OAuth login
|
|
881537
|
+
message: "Begin one provider subscription OAuth login, save the pending session, and return here for completion.",
|
|
881500
881538
|
fields: [
|
|
881501
|
-
{ id: "provider", label: "Provider", value: "openai", required: true, multiline: false, hint: "Subscription provider id
|
|
881539
|
+
{ id: "provider", label: "Provider", value: "openai", required: true, multiline: false, hint: "Subscription provider id, such as openai." },
|
|
881502
881540
|
{ 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." }
|
|
881541
|
+
{ 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
881542
|
]
|
|
881506
881543
|
};
|
|
881507
881544
|
}
|
|
@@ -881511,11 +881548,11 @@ function createAgentWorkspaceBasicCommandEditor(kind2) {
|
|
|
881511
881548
|
mode: "update",
|
|
881512
881549
|
title: "Finish Provider Subscription Login",
|
|
881513
881550
|
selectedFieldIndex: 0,
|
|
881514
|
-
message: "Finish a pending provider subscription OAuth login from a code or redirected URL
|
|
881551
|
+
message: "Finish a pending provider subscription OAuth login from a code or redirected URL and save the subscription session.",
|
|
881515
881552
|
fields: [
|
|
881516
881553
|
{ id: "provider", label: "Provider", value: "openai", required: true, multiline: false, hint: "Provider id used when starting login." },
|
|
881517
881554
|
{ 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
|
|
881555
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to exchange the code and save the provider subscription session." }
|
|
881519
881556
|
]
|
|
881520
881557
|
};
|
|
881521
881558
|
}
|
|
@@ -881525,10 +881562,10 @@ function createAgentWorkspaceBasicCommandEditor(kind2) {
|
|
|
881525
881562
|
mode: "delete",
|
|
881526
881563
|
title: "Logout Provider Subscription",
|
|
881527
881564
|
selectedFieldIndex: 0,
|
|
881528
|
-
message: "Remove one
|
|
881565
|
+
message: "Remove one active or pending provider subscription session. Ambient API key resolution applies again if configured.",
|
|
881529
881566
|
fields: [
|
|
881530
881567
|
{ 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
|
|
881568
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to remove active or pending subscription state." }
|
|
881532
881569
|
]
|
|
881533
881570
|
};
|
|
881534
881571
|
}
|
|
@@ -890312,6 +890349,14 @@ function activateAgentWorkspaceSelection(workspace, requestRender) {
|
|
|
890312
890349
|
workspace.importTuiSettings(requestRender);
|
|
890313
890350
|
return;
|
|
890314
890351
|
}
|
|
890352
|
+
if (action2.kind === "model-picker") {
|
|
890353
|
+
workspace.openModelPickerAction(action2, requestRender);
|
|
890354
|
+
return;
|
|
890355
|
+
}
|
|
890356
|
+
if (action2.kind === "settings-modal") {
|
|
890357
|
+
workspace.openSettingsModalAction(action2, requestRender);
|
|
890358
|
+
return;
|
|
890359
|
+
}
|
|
890315
890360
|
if (action2.kind === "editor" && action2.editorKind) {
|
|
890316
890361
|
const editor = createAgentWorkspaceEditor(action2.editorKind, {
|
|
890317
890362
|
runtimeStarterTemplates: workspace.runtimeSnapshot?.runtimeStarterTemplates ?? [],
|
|
@@ -890481,6 +890526,63 @@ function settingAction(options) {
|
|
|
890481
890526
|
};
|
|
890482
890527
|
}
|
|
890483
890528
|
|
|
890529
|
+
// src/input/agent-workspace-host-category.ts
|
|
890530
|
+
var AGENT_WORKSPACE_HOST_CATEGORY = {
|
|
890531
|
+
id: "host",
|
|
890532
|
+
group: "OPERATIONS",
|
|
890533
|
+
label: "Connected Host",
|
|
890534
|
+
summary: "Connected-host health, tasks, sessions, channels, and automation.",
|
|
890535
|
+
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.",
|
|
890536
|
+
actions: [
|
|
890537
|
+
{ 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" },
|
|
890538
|
+
{ 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" },
|
|
890539
|
+
{ 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" },
|
|
890540
|
+
{ 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" },
|
|
890541
|
+
{ id: "host-maintenance", label: "Session maintenance", detail: "Review continuity, compaction, and current-session maintenance posture.", command: "/health maintenance", kind: "command", safety: "read-only" },
|
|
890542
|
+
{ 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" },
|
|
890543
|
+
{ 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" },
|
|
890544
|
+
{ 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" },
|
|
890545
|
+
{ 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" },
|
|
890546
|
+
{ 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" },
|
|
890547
|
+
{ 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" },
|
|
890548
|
+
{ 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" },
|
|
890549
|
+
{ 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" },
|
|
890550
|
+
{ 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" },
|
|
890551
|
+
{ id: "host-channel-policies", label: "Channel policies", detail: "Inspect channel delivery policy posture without changing routing.", command: "/channels policies", kind: "command", safety: "read-only" },
|
|
890552
|
+
{ id: "host-channels", label: "Open Channels", detail: "Jump to the channel setup and delivery workspace.", targetCategoryId: "channels", kind: "workspace", safety: "safe" },
|
|
890553
|
+
{ id: "host-automation", label: "Open Automation", detail: "Jump to connected schedules, reminders, receipts, and explicit run controls.", targetCategoryId: "automation", kind: "workspace", safety: "safe" },
|
|
890554
|
+
{ 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" },
|
|
890555
|
+
{ id: "host-schedule-reconcile", label: "Reconcile schedules", detail: "Compare local promotion receipts with live connected schedules.", command: "/schedule reconcile", kind: "command", safety: "read-only" },
|
|
890556
|
+
{ id: "host-knowledge", label: "Knowledge route", detail: "Inspect isolated Agent Knowledge route readiness and source counts.", command: "/knowledge status", kind: "command", safety: "read-only" },
|
|
890557
|
+
{ id: "host-knowledge-open", label: "Open Knowledge", detail: "Jump to Agent Knowledge source, graph, review, and ingest controls.", targetCategoryId: "knowledge", kind: "workspace", safety: "safe" },
|
|
890558
|
+
{ id: "host-media", label: "Media providers", detail: "Inspect configured media providers before generating media with confirmation.", command: "/media providers", kind: "command", safety: "read-only" },
|
|
890559
|
+
{ 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" },
|
|
890560
|
+
{ 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" },
|
|
890561
|
+
{ 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" },
|
|
890562
|
+
{ 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" },
|
|
890563
|
+
{ 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" },
|
|
890564
|
+
{ 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" },
|
|
890565
|
+
{ 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" },
|
|
890566
|
+
{ 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" },
|
|
890567
|
+
{ 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" },
|
|
890568
|
+
{ 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" },
|
|
890569
|
+
{ 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" },
|
|
890570
|
+
{ 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" },
|
|
890571
|
+
{ 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" },
|
|
890572
|
+
{ 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" },
|
|
890573
|
+
{ 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" },
|
|
890574
|
+
{ 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" },
|
|
890575
|
+
{ 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" },
|
|
890576
|
+
{ 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" },
|
|
890577
|
+
{ 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" },
|
|
890578
|
+
{ 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" },
|
|
890579
|
+
{ 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" },
|
|
890580
|
+
{ 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" },
|
|
890581
|
+
{ 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" },
|
|
890582
|
+
{ 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" }
|
|
890583
|
+
]
|
|
890584
|
+
};
|
|
890585
|
+
|
|
890484
890586
|
// src/input/agent-workspace-categories.ts
|
|
890485
890587
|
var AGENT_WORKSPACE_CATEGORIES = [
|
|
890486
890588
|
{
|
|
@@ -890493,6 +890595,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890493
890595
|
{ 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
890596
|
{ 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
890597
|
{ id: "model", label: "Choose model", detail: "Open the model/provider workspace for the Agent chat route.", command: "/model", kind: "command", safety: "safe" },
|
|
890598
|
+
{ 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
890599
|
{ 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
890600
|
{ 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
890601
|
{ 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 +890622,55 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890519
890622
|
id: "setup",
|
|
890520
890623
|
group: "ONBOARDING",
|
|
890521
890624
|
label: "Start",
|
|
890522
|
-
summary: "Import
|
|
890523
|
-
detail: "
|
|
890625
|
+
summary: "Import preferences, sign in, and choose the main model.",
|
|
890626
|
+
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
890627
|
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" },
|
|
890628
|
+
{ id: "import-goodvibes-tui-settings", label: "Import GoodVibes settings", detail: "Copy existing display, provider, behavior, permission, TTS, channel, helper, tool, release, and automation values into Agent-owned settings.", kind: "settings-import", safety: "safe" },
|
|
890629
|
+
{ 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" },
|
|
890630
|
+
{ 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" },
|
|
890631
|
+
{ 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" },
|
|
890632
|
+
settingAction({ id: "setup-reasoning-effort", label: "Reasoning effort", detail: "Cycle reasoning level when the selected model supports it.", key: "provider.reasoningEffort" }),
|
|
890633
|
+
{ 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
890634
|
{ 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
|
|
890635
|
+
{ 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" },
|
|
890636
|
+
settingAction({ id: "setup-secret-policy", label: "Secret storage", detail: "Choose how strongly Agent prefers secure secret storage.", key: "storage.secretPolicy" }),
|
|
890637
|
+
settingAction({ id: "setup-save-history", label: "Save history", detail: "Toggle local conversation history persistence.", key: "behavior.saveHistory" })
|
|
890538
890638
|
]
|
|
890539
890639
|
},
|
|
890540
890640
|
{
|
|
890541
890641
|
id: "account-model",
|
|
890542
890642
|
group: "ONBOARDING",
|
|
890543
|
-
label: "
|
|
890544
|
-
summary: "
|
|
890545
|
-
detail: "Use this after sign-in
|
|
890643
|
+
label: "Model Routing",
|
|
890644
|
+
summary: "Set chat, embedding, helper, tool, and spoken-turn routes.",
|
|
890645
|
+
detail: "Use this after sign-in. Routes are saved settings, so selections persist across launches.",
|
|
890546
890646
|
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" }),
|
|
890647
|
+
{ 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" },
|
|
890648
|
+
{ id: "provider-remove", label: "Remove custom provider", detail: "Remove one custom provider config after confirmation.", editorKind: "provider-remove", kind: "editor", safety: "safe" },
|
|
890649
|
+
{ 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" },
|
|
890650
|
+
settingAction({ id: "account-reasoning", label: "Reasoning effort", detail: "Cycle the reasoning effort used when supported.", key: "provider.reasoningEffort" }),
|
|
890651
|
+
settingAction({ id: "account-embedding", label: "Embedding provider", detail: "Set the embedding provider for memory and retrieval.", key: "provider.embeddingProvider" }),
|
|
890562
890652
|
settingAction({ id: "account-system-prompt", label: "System prompt file", detail: "Set an optional local system prompt file path.", key: "provider.systemPromptFile" }),
|
|
890563
890653
|
settingAction({ id: "account-helper-enabled", label: "Enable helper model", detail: "Toggle dedicated helper routing for background utility work.", key: "helper.enabled" }),
|
|
890564
|
-
|
|
890565
|
-
|
|
890654
|
+
{ 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" },
|
|
890655
|
+
{ 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
890656
|
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
|
-
|
|
890657
|
+
{ 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" },
|
|
890658
|
+
{ 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" },
|
|
890659
|
+
{ 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" },
|
|
890660
|
+
{ 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" },
|
|
890661
|
+
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" }),
|
|
890662
|
+
settingAction({ id: "account-cache-enabled", label: "Prompt cache", detail: "Toggle prompt caching for eligible providers.", key: "cache.enabled" }),
|
|
890663
|
+
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 }),
|
|
890664
|
+
settingAction({ id: "account-cache-monitor", label: "Cache hit-rate monitor", detail: "Toggle cache hit-rate monitoring.", key: "cache.monitorHitRate", visibleWhenKey: "cache.enabled", visibleWhenValue: true }),
|
|
890665
|
+
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
890666
|
]
|
|
890572
890667
|
},
|
|
890573
890668
|
{
|
|
890574
890669
|
id: "assistant-behavior",
|
|
890575
890670
|
group: "ONBOARDING",
|
|
890576
|
-
label: "
|
|
890577
|
-
summary: "
|
|
890578
|
-
detail: "Use this
|
|
890671
|
+
label: "Behavior",
|
|
890672
|
+
summary: "Set interaction style, context pressure behavior, and visible reasoning.",
|
|
890673
|
+
detail: "Use this to choose how chat feels during normal work and long-running tasks.",
|
|
890579
890674
|
actions: [
|
|
890580
890675
|
settingAction({ id: "behavior-hitl-mode", label: "Interaction mode", detail: "Cycle quiet, balanced, or operator interaction mode.", key: "behavior.hitlMode" }),
|
|
890581
890676
|
settingAction({ id: "behavior-guidance-mode", label: "Guidance mode", detail: "Cycle off, minimal, or guided operational guidance.", key: "behavior.guidanceMode" }),
|
|
@@ -890591,28 +890686,41 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890591
890686
|
id: "tools-permissions",
|
|
890592
890687
|
group: "ONBOARDING",
|
|
890593
890688
|
label: "Tools & Permissions",
|
|
890594
|
-
summary: "
|
|
890595
|
-
detail: "Use this
|
|
890689
|
+
summary: "Set approval policy, MCP entry points, and secret references.",
|
|
890690
|
+
detail: "Use this before enabling tool-heavy work. Permission rows write policy; MCP and secret rows open setup forms.",
|
|
890596
890691
|
actions: [
|
|
890597
890692
|
settingAction({ id: "permissions-mode", label: "Permission mode", detail: "Cycle prompt, allow-all, or custom permission mode.", key: "permissions.mode" }),
|
|
890693
|
+
settingAction({ id: "permissions-auto-approve", label: "Auto-approve tools", detail: "Toggle automatic approval for all tool permission requests.", key: "behavior.autoApprove" }),
|
|
890694
|
+
settingAction({ id: "permissions-read", label: "File reads", detail: "Cycle allow, prompt, or deny for file read operations.", key: "permissions.tools.read" }),
|
|
890695
|
+
settingAction({ id: "permissions-find", label: "File search", detail: "Cycle allow, prompt, or deny for file and directory search operations.", key: "permissions.tools.find" }),
|
|
890598
890696
|
settingAction({ id: "permissions-write", label: "File writes", detail: "Cycle allow, prompt, or deny for file write operations.", key: "permissions.tools.write" }),
|
|
890599
890697
|
settingAction({ id: "permissions-edit", label: "File edits", detail: "Cycle allow, prompt, or deny for edit and patch operations.", key: "permissions.tools.edit" }),
|
|
890600
890698
|
settingAction({ id: "permissions-exec", label: "Shell commands", detail: "Cycle allow, prompt, or deny for shell execution.", key: "permissions.tools.exec" }),
|
|
890601
890699
|
settingAction({ id: "permissions-fetch", label: "Network fetches", detail: "Cycle allow, prompt, or deny for outbound fetch requests.", key: "permissions.tools.fetch" }),
|
|
890700
|
+
settingAction({ id: "permissions-analyze", label: "Code analysis", detail: "Cycle allow, prompt, or deny for code and project analysis operations.", key: "permissions.tools.analyze" }),
|
|
890701
|
+
settingAction({ id: "permissions-inspect", label: "Runtime inspect", detail: "Cycle allow, prompt, or deny for runtime state inspection.", key: "permissions.tools.inspect" }),
|
|
890702
|
+
settingAction({ id: "permissions-state", label: "State reads", detail: "Cycle allow, prompt, or deny for reading runtime and session state.", key: "permissions.tools.state" }),
|
|
890703
|
+
settingAction({ id: "permissions-registry", label: "Registry reads", detail: "Cycle allow, prompt, or deny for tool and skill registry queries.", key: "permissions.tools.registry" }),
|
|
890602
890704
|
settingAction({ id: "permissions-mcp", label: "MCP tools", detail: "Cycle allow, prompt, or deny for external MCP tool calls.", key: "permissions.tools.mcp" }),
|
|
890603
890705
|
settingAction({ id: "permissions-agent", label: "Agent delegation", detail: "Cycle allow, prompt, or deny for subagent and delegation operations.", key: "permissions.tools.agent" }),
|
|
890604
890706
|
settingAction({ id: "permissions-workflow", label: "Workflow automation", detail: "Cycle allow, prompt, or deny for multi-step workflow automation.", key: "permissions.tools.workflow" }),
|
|
890707
|
+
settingAction({ id: "permissions-delegate", label: "Unknown tools", detail: "Cycle allow, prompt, or deny for unknown or unregistered tools.", key: "permissions.tools.delegate" }),
|
|
890605
890708
|
{ 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
890709
|
{ 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" }
|
|
890710
|
+
{ 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" },
|
|
890711
|
+
settingAction({ id: "tools-auto-heal", label: "Tool auto-heal", detail: "Toggle automatic syntax repair for precision write and edit operations.", key: "tools.autoHeal" }),
|
|
890712
|
+
settingAction({ id: "tools-token-budget", label: "Tool token budget", detail: "Set the default token budget for precision read operations.", key: "tools.defaultTokenBudget" }),
|
|
890713
|
+
settingAction({ id: "tools-hooks-file", label: "Hooks file", detail: "Set the hook configuration file name relative to host data.", key: "tools.hooksFile" }),
|
|
890714
|
+
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" }),
|
|
890715
|
+
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
890716
|
]
|
|
890609
890717
|
},
|
|
890610
890718
|
{
|
|
890611
890719
|
id: "onboarding-display",
|
|
890612
890720
|
group: "ONBOARDING",
|
|
890613
890721
|
label: "Interface",
|
|
890614
|
-
summary: "Display, streaming,
|
|
890615
|
-
detail: "Use this page to make the terminal readable for
|
|
890722
|
+
summary: "Display, streaming, message placement, and release channel.",
|
|
890723
|
+
detail: "Use this page to make the terminal readable for daily operation.",
|
|
890616
890724
|
actions: [
|
|
890617
890725
|
settingAction({ id: "display-stream", label: "Stream tokens", detail: "Toggle streaming assistant tokens as they arrive.", key: "display.stream" }),
|
|
890618
890726
|
settingAction({ id: "display-theme", label: "Theme", detail: "Set the color theme name.", key: "display.theme" }),
|
|
@@ -890629,18 +890737,20 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890629
890737
|
id: "onboarding-channels",
|
|
890630
890738
|
group: "ONBOARDING",
|
|
890631
890739
|
label: "Messaging",
|
|
890632
|
-
summary: "
|
|
890633
|
-
detail: "
|
|
890740
|
+
summary: "Choose remote channels, then fill only the fields for enabled channels.",
|
|
890741
|
+
detail: "Enable the channels you actually want. Channel credentials and default targets are saved as Agent settings or secret refs.",
|
|
890634
890742
|
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
890743
|
settingAction({ id: "channel-ntfy-enabled", label: "Use ntfy", detail: "Toggle ntfy notifications and chat routing.", key: "surfaces.ntfy.enabled" }),
|
|
890637
890744
|
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
890745
|
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
890746
|
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 }),
|
|
890747
|
+
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 }),
|
|
890748
|
+
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
890749
|
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
890750
|
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
890751
|
settingAction({ id: "channel-slack-enabled", label: "Use Slack", detail: "Toggle Slack adapter configuration.", key: "surfaces.slack.enabled" }),
|
|
890643
890752
|
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 }),
|
|
890753
|
+
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
890754
|
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
890755
|
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
890756
|
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 +890758,67 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890648
890758
|
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
890759
|
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
890760
|
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 }),
|
|
890761
|
+
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
890762
|
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
890763
|
settingAction({ id: "channel-webhook-enabled", label: "Use webhooks", detail: "Toggle generic webhook delivery.", key: "surfaces.webhook.enabled" }),
|
|
890653
890764
|
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
890765
|
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 }),
|
|
890766
|
+
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
890767
|
settingAction({ id: "channel-telegram-enabled", label: "Use Telegram", detail: "Toggle Telegram bot delivery.", key: "surfaces.telegram.enabled" }),
|
|
890656
890768
|
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 }),
|
|
890769
|
+
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
890770
|
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
890771
|
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 }),
|
|
890772
|
+
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
890773
|
settingAction({ id: "channel-googlechat-enabled", label: "Use Google Chat", detail: "Toggle Google Chat delivery.", key: "surfaces.googleChat.enabled" }),
|
|
890660
890774
|
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 }),
|
|
890775
|
+
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 }),
|
|
890776
|
+
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 }),
|
|
890777
|
+
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
890778
|
settingAction({ id: "channel-homeassistant-enabled", label: "Use home automation", detail: "Toggle home automation conversation and event delivery.", key: "surfaces.homeassistant.enabled" }),
|
|
890662
890779
|
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
890780
|
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 }),
|
|
890781
|
+
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 }),
|
|
890782
|
+
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 }),
|
|
890783
|
+
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 }),
|
|
890784
|
+
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 }),
|
|
890785
|
+
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 }),
|
|
890786
|
+
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
890787
|
settingAction({ id: "channel-signal-enabled", label: "Use Signal", detail: "Toggle Signal bridge delivery.", key: "surfaces.signal.enabled" }),
|
|
890665
890788
|
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 }),
|
|
890789
|
+
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 }),
|
|
890790
|
+
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
890791
|
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
890792
|
settingAction({ id: "channel-whatsapp-enabled", label: "Use WhatsApp", detail: "Toggle WhatsApp delivery.", key: "surfaces.whatsapp.enabled" }),
|
|
890668
890793
|
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
890794
|
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 }),
|
|
890795
|
+
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 }),
|
|
890796
|
+
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 }),
|
|
890797
|
+
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 }),
|
|
890798
|
+
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
890799
|
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
890800
|
settingAction({ id: "channel-imessage-enabled", label: "Use iMessage", detail: "Toggle iMessage bridge delivery.", key: "surfaces.imessage.enabled" }),
|
|
890672
890801
|
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: "
|
|
890802
|
+
settingAction({ id: "channel-imessage-account", label: "iMessage account", detail: "Set the iMessage account id.", key: "surfaces.imessage.account", visibleWhenKey: "surfaces.imessage.enabled", visibleWhenValue: true }),
|
|
890803
|
+
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 }),
|
|
890804
|
+
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
890805
|
]
|
|
890677
890806
|
},
|
|
890678
890807
|
{
|
|
890679
890808
|
id: "onboarding-voice-media",
|
|
890680
890809
|
group: "ONBOARDING",
|
|
890681
890810
|
label: "Voice & Phone",
|
|
890682
|
-
summary: "Configure
|
|
890683
|
-
detail: "Use this page for
|
|
890811
|
+
summary: "Configure voice controls, spoken output, and SMS or phone-call delivery.",
|
|
890812
|
+
detail: "Use this page for saved voice/TTS settings and telephony credentials. Generating media is available later from Voice & Media.",
|
|
890684
890813
|
actions: [
|
|
890685
890814
|
settingAction({ id: "voice-enabled", label: "Use voice controls", detail: "Toggle the optional local voice control surface.", key: "ui.voiceEnabled" }),
|
|
890686
890815
|
settingAction({ id: "voice-tts-provider", label: "TTS provider", detail: "Set the default text-to-speech provider id.", key: "tts.provider" }),
|
|
890687
890816
|
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
890817
|
settingAction({ id: "telephony-enabled", label: "Use telephony", detail: "Toggle SMS, voice call, or telephony bridge delivery.", key: "surfaces.telephony.enabled" }),
|
|
890692
890818
|
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
890819
|
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 }),
|
|
890820
|
+
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 }),
|
|
890821
|
+
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
890822
|
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
890823
|
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
890824
|
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 +890830,9 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890702
890830
|
{
|
|
890703
890831
|
id: "onboarding-context",
|
|
890704
890832
|
group: "ONBOARDING",
|
|
890705
|
-
label: "Context",
|
|
890706
|
-
summary: "
|
|
890707
|
-
detail: "Use this page to
|
|
890833
|
+
label: "Local Context",
|
|
890834
|
+
summary: "Create/import memory, personas, skills, routines, notes, and Knowledge.",
|
|
890835
|
+
detail: "Use this page to seed the assistant with durable local context. These forms create Agent-owned records or ingest reviewed sources.",
|
|
890708
890836
|
actions: [
|
|
890709
890837
|
{ 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
890838
|
{ 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 +890850,19 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890722
890850
|
]
|
|
890723
890851
|
},
|
|
890724
890852
|
{
|
|
890725
|
-
id: "onboarding-
|
|
890853
|
+
id: "onboarding-automation",
|
|
890726
890854
|
group: "ONBOARDING",
|
|
890727
|
-
label: "
|
|
890728
|
-
summary: "
|
|
890729
|
-
detail: "Use this page to
|
|
890855
|
+
label: "Automation Setup",
|
|
890856
|
+
summary: "Set scheduled work limits for reminders and routines.",
|
|
890857
|
+
detail: "Use this page to enable automation and set bounded run limits. Creating actual reminders and routines remains a separate confirmed action.",
|
|
890730
890858
|
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" }
|
|
890859
|
+
settingAction({ id: "automation-enabled", label: "Use automation", detail: "Toggle the automation subsystem for reminders and scheduled routines.", key: "automation.enabled" }),
|
|
890860
|
+
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 }),
|
|
890861
|
+
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 }),
|
|
890862
|
+
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 }),
|
|
890863
|
+
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 }),
|
|
890864
|
+
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 }),
|
|
890865
|
+
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
890866
|
]
|
|
890740
890867
|
},
|
|
890741
890868
|
{
|
|
@@ -891171,52 +891298,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
891171
891298
|
{ 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
891299
|
]
|
|
891173
891300
|
},
|
|
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
|
-
},
|
|
891301
|
+
AGENT_WORKSPACE_HOST_CATEGORY,
|
|
891220
891302
|
{
|
|
891221
891303
|
id: "automation",
|
|
891222
891304
|
group: "OPERATIONS",
|
|
@@ -891287,6 +891369,9 @@ function searchAgentWorkspaceActions(categories, query2) {
|
|
|
891287
891369
|
action2.command ?? "",
|
|
891288
891370
|
action2.editorKind ?? "",
|
|
891289
891371
|
action2.targetCategoryId ?? "",
|
|
891372
|
+
action2.modelPickerFlow ?? "",
|
|
891373
|
+
action2.modelPickerTarget ?? "",
|
|
891374
|
+
action2.settingsTarget ?? "",
|
|
891290
891375
|
action2.localOperation ?? "",
|
|
891291
891376
|
action2.safety
|
|
891292
891377
|
].join(" ").toLowerCase();
|
|
@@ -891317,6 +891402,9 @@ function scoreActionSearchResult(result2, exactQuery, terms) {
|
|
|
891317
891402
|
score += scoreField(action2.editorKind, terms, exactQuery, 85, 26);
|
|
891318
891403
|
score += scoreField(action2.command, terms, exactQuery, 75, 22);
|
|
891319
891404
|
score += scoreField(action2.label, terms, exactQuery, 65, 18);
|
|
891405
|
+
score += scoreField(action2.modelPickerTarget, terms, exactQuery, 58, 18);
|
|
891406
|
+
score += scoreField(action2.settingsTarget, terms, exactQuery, 58, 18);
|
|
891407
|
+
score += scoreField(action2.modelPickerFlow, terms, exactQuery, 54, 16);
|
|
891320
891408
|
score += scoreField(action2.localOperation, terms, exactQuery, 50, 16);
|
|
891321
891409
|
score += scoreField(action2.targetCategoryId, terms, exactQuery, 40, 12);
|
|
891322
891410
|
score += scoreField(action2.detail, terms, exactQuery, 24, 6);
|
|
@@ -895422,6 +895510,163 @@ function handleMcpWorkspaceToken(workspace, token, handleEscape2, requestRender)
|
|
|
895422
895510
|
return true;
|
|
895423
895511
|
}
|
|
895424
895512
|
|
|
895513
|
+
// src/input/agent-workspace-requirements.ts
|
|
895514
|
+
function buildAgentWorkspaceRequirements(readField) {
|
|
895515
|
+
return buildAgentSkillRequirements({
|
|
895516
|
+
env: splitList5(readField("requiresEnv")),
|
|
895517
|
+
commands: splitList5(readField("requiresCommands"))
|
|
895518
|
+
});
|
|
895519
|
+
}
|
|
895520
|
+
|
|
895521
|
+
// src/input/agent-workspace-local-editor-submission.ts
|
|
895522
|
+
function submitAgentWorkspaceLocalRegistryEditor(shellPaths3, editor, callbacks) {
|
|
895523
|
+
const field = callbacks.readField;
|
|
895524
|
+
if (editor.mode === "delete") {
|
|
895525
|
+
callbacks.submitDeleteEditor();
|
|
895526
|
+
return;
|
|
895527
|
+
}
|
|
895528
|
+
if (editor.kind === "learned-behavior") {
|
|
895529
|
+
const created = createAgentWorkspaceLearnedBehavior(shellPaths3, {
|
|
895530
|
+
target: callbacks.learnedBehaviorTarget(),
|
|
895531
|
+
name: field("name"),
|
|
895532
|
+
description: field("description"),
|
|
895533
|
+
notes: field("notes"),
|
|
895534
|
+
tags: splitList5(field("tags")),
|
|
895535
|
+
triggers: splitList5(field("triggers")),
|
|
895536
|
+
enable: isAffirmative15(field("enable"))
|
|
895537
|
+
});
|
|
895538
|
+
callbacks.finishLocalEditor(created.kind, created.id, created.name, "Created");
|
|
895539
|
+
} else if (editor.kind === "profile") {
|
|
895540
|
+
const template = field("template");
|
|
895541
|
+
const templateId = template && template.toLowerCase() !== "none" ? template : undefined;
|
|
895542
|
+
const profile5 = createAgentRuntimeProfile(shellPaths3.homeDirectory, field("name"), {
|
|
895543
|
+
...templateId ? { templateId } : {}
|
|
895544
|
+
});
|
|
895545
|
+
callbacks.finishProfileEditor(profile5);
|
|
895546
|
+
} else if (editor.kind === "note") {
|
|
895547
|
+
submitNoteEditor(shellPaths3, editor, field, callbacks.finishLocalEditor);
|
|
895548
|
+
} else if (editor.kind === "persona") {
|
|
895549
|
+
submitPersonaEditor(shellPaths3, editor, field, callbacks.finishLocalEditor);
|
|
895550
|
+
} else if (editor.kind === "skill") {
|
|
895551
|
+
submitSkillEditor(shellPaths3, editor, field, callbacks.finishLocalEditor);
|
|
895552
|
+
} else {
|
|
895553
|
+
submitRoutineEditor(shellPaths3, editor, field, callbacks.finishLocalEditor);
|
|
895554
|
+
}
|
|
895555
|
+
}
|
|
895556
|
+
function submitNoteEditor(shellPaths3, editor, field, finish) {
|
|
895557
|
+
const registry5 = AgentNoteRegistry.fromShellPaths(shellPaths3);
|
|
895558
|
+
if (editor.mode === "update" && editor.recordId) {
|
|
895559
|
+
const updated = registry5.update(editor.recordId, {
|
|
895560
|
+
title: field("title"),
|
|
895561
|
+
body: field("body"),
|
|
895562
|
+
sourceUrl: field("sourceUrl"),
|
|
895563
|
+
tags: splitList5(field("tags")),
|
|
895564
|
+
provenance: "Workspace"
|
|
895565
|
+
});
|
|
895566
|
+
finish("note", updated.id, updated.title, "Updated");
|
|
895567
|
+
return;
|
|
895568
|
+
}
|
|
895569
|
+
const created = registry5.create({
|
|
895570
|
+
title: field("title"),
|
|
895571
|
+
body: field("body"),
|
|
895572
|
+
sourceUrl: field("sourceUrl"),
|
|
895573
|
+
tags: splitList5(field("tags")),
|
|
895574
|
+
source: "user",
|
|
895575
|
+
provenance: "Workspace"
|
|
895576
|
+
});
|
|
895577
|
+
finish("note", created.id, created.title, "Created");
|
|
895578
|
+
}
|
|
895579
|
+
function submitPersonaEditor(shellPaths3, editor, field, finish) {
|
|
895580
|
+
const registry5 = AgentPersonaRegistry.fromShellPaths(shellPaths3);
|
|
895581
|
+
if (editor.mode === "update" && editor.recordId) {
|
|
895582
|
+
const wasActive = registry5.snapshot().activePersonaId === editor.recordId;
|
|
895583
|
+
const updated = registry5.update(editor.recordId, {
|
|
895584
|
+
name: field("name"),
|
|
895585
|
+
description: field("description"),
|
|
895586
|
+
body: field("body"),
|
|
895587
|
+
tags: splitList5(field("tags")),
|
|
895588
|
+
triggers: splitList5(field("triggers")),
|
|
895589
|
+
provenance: "Workspace"
|
|
895590
|
+
});
|
|
895591
|
+
if (isAffirmative15(field("activate")))
|
|
895592
|
+
registry5.setActive(updated.id);
|
|
895593
|
+
else if (wasActive)
|
|
895594
|
+
registry5.clearActive();
|
|
895595
|
+
finish("persona", updated.id, updated.name, "Updated");
|
|
895596
|
+
return;
|
|
895597
|
+
}
|
|
895598
|
+
const created = registry5.create({
|
|
895599
|
+
name: field("name"),
|
|
895600
|
+
description: field("description"),
|
|
895601
|
+
body: field("body"),
|
|
895602
|
+
tags: splitList5(field("tags")),
|
|
895603
|
+
triggers: splitList5(field("triggers")),
|
|
895604
|
+
source: "user",
|
|
895605
|
+
provenance: "Workspace"
|
|
895606
|
+
});
|
|
895607
|
+
if (isAffirmative15(field("activate")))
|
|
895608
|
+
registry5.setActive(created.id);
|
|
895609
|
+
finish("persona", created.id, created.name, "Created");
|
|
895610
|
+
}
|
|
895611
|
+
function submitSkillEditor(shellPaths3, editor, field, finish) {
|
|
895612
|
+
const registry5 = AgentSkillRegistry.fromShellPaths(shellPaths3);
|
|
895613
|
+
if (editor.mode === "update" && editor.recordId) {
|
|
895614
|
+
const updated = registry5.update(editor.recordId, {
|
|
895615
|
+
name: field("name"),
|
|
895616
|
+
description: field("description"),
|
|
895617
|
+
procedure: field("procedure"),
|
|
895618
|
+
triggers: splitList5(field("triggers")),
|
|
895619
|
+
tags: splitList5(field("tags")),
|
|
895620
|
+
requirements: buildAgentWorkspaceRequirements(field),
|
|
895621
|
+
provenance: "Workspace"
|
|
895622
|
+
});
|
|
895623
|
+
registry5.setEnabled(updated.id, isAffirmative15(field("enabled")));
|
|
895624
|
+
finish("skill", updated.id, updated.name, "Updated");
|
|
895625
|
+
return;
|
|
895626
|
+
}
|
|
895627
|
+
const created = registry5.create({
|
|
895628
|
+
name: field("name"),
|
|
895629
|
+
description: field("description"),
|
|
895630
|
+
procedure: field("procedure"),
|
|
895631
|
+
triggers: splitList5(field("triggers")),
|
|
895632
|
+
tags: splitList5(field("tags")),
|
|
895633
|
+
requirements: buildAgentWorkspaceRequirements(field),
|
|
895634
|
+
enabled: isAffirmative15(field("enabled")),
|
|
895635
|
+
source: "user",
|
|
895636
|
+
provenance: "Workspace"
|
|
895637
|
+
});
|
|
895638
|
+
finish("skill", created.id, created.name, "Created");
|
|
895639
|
+
}
|
|
895640
|
+
function submitRoutineEditor(shellPaths3, editor, field, finish) {
|
|
895641
|
+
const registry5 = AgentRoutineRegistry.fromShellPaths(shellPaths3);
|
|
895642
|
+
if (editor.mode === "update" && editor.recordId) {
|
|
895643
|
+
const updated = registry5.update(editor.recordId, {
|
|
895644
|
+
name: field("name"),
|
|
895645
|
+
description: field("description"),
|
|
895646
|
+
steps: field("steps"),
|
|
895647
|
+
triggers: splitList5(field("triggers")),
|
|
895648
|
+
tags: splitList5(field("tags")),
|
|
895649
|
+
requirements: buildAgentWorkspaceRequirements(field),
|
|
895650
|
+
provenance: "Workspace"
|
|
895651
|
+
});
|
|
895652
|
+
registry5.setEnabled(updated.id, isAffirmative15(field("enabled")));
|
|
895653
|
+
finish("routine", updated.id, updated.name, "Updated");
|
|
895654
|
+
return;
|
|
895655
|
+
}
|
|
895656
|
+
const created = registry5.create({
|
|
895657
|
+
name: field("name"),
|
|
895658
|
+
description: field("description"),
|
|
895659
|
+
steps: field("steps"),
|
|
895660
|
+
triggers: splitList5(field("triggers")),
|
|
895661
|
+
tags: splitList5(field("tags")),
|
|
895662
|
+
requirements: buildAgentWorkspaceRequirements(field),
|
|
895663
|
+
enabled: isAffirmative15(field("enabled")),
|
|
895664
|
+
source: "user",
|
|
895665
|
+
provenance: "Workspace"
|
|
895666
|
+
});
|
|
895667
|
+
finish("routine", created.id, created.name, "Created");
|
|
895668
|
+
}
|
|
895669
|
+
|
|
895425
895670
|
// src/input/agent-workspace-local-selection.ts
|
|
895426
895671
|
function agentWorkspaceLocalLibraryItems(snapshot2, kind2) {
|
|
895427
895672
|
if (kind2 === "memory")
|
|
@@ -895782,14 +896027,6 @@ function selectAgentWorkspaceCategory(host, categoryIdOrLabel) {
|
|
|
895782
896027
|
return true;
|
|
895783
896028
|
}
|
|
895784
896029
|
|
|
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
896030
|
// src/input/agent-workspace-settings.ts
|
|
895794
896031
|
import { existsSync as existsSync87, readFileSync as readFileSync94 } from "fs";
|
|
895795
896032
|
var GOODVIBES_TUI_SURFACE_ROOT = "tui";
|
|
@@ -896037,6 +896274,166 @@ function createSettingEditor(setting, currentValue, action2) {
|
|
|
896037
896274
|
]
|
|
896038
896275
|
};
|
|
896039
896276
|
}
|
|
896277
|
+
|
|
896278
|
+
// src/input/agent-workspace-subscription-editor.ts
|
|
896279
|
+
init_config8();
|
|
896280
|
+
async function submitAgentWorkspaceSubscriptionLoginStartEditor(host, editor, context, readField) {
|
|
896281
|
+
if (!isAffirmative15(readField("confirm"))) {
|
|
896282
|
+
host.localEditor = { ...editor, message: "Subscription login start not confirmed. Type yes, then press Enter." };
|
|
896283
|
+
host.status = "Subscription login start not confirmed.";
|
|
896284
|
+
return;
|
|
896285
|
+
}
|
|
896286
|
+
try {
|
|
896287
|
+
const provider5 = readField("provider") || "openai";
|
|
896288
|
+
const openBrowser2 = isAffirmative15(readField("openBrowser"));
|
|
896289
|
+
const { manager: manager5, services } = subscriptionServices(context);
|
|
896290
|
+
const resolved = getSubscriptionProviderConfig(provider5, services.get(provider5));
|
|
896291
|
+
if (!resolved) {
|
|
896292
|
+
throw new Error(`OAuth is not configured for ${provider5}. Add an OAuth provider service or choose a built-in subscription provider.`);
|
|
896293
|
+
}
|
|
896294
|
+
const started = provider5 === "openai" && resolved.source === "builtin" ? await beginOpenAICodexLogin() : null;
|
|
896295
|
+
const authorizationUrl = started ? started.authorizationUrl : (await manager5.beginOAuthLogin(provider5, resolveManualLoginConfig2(resolved.oauth))).authorizationUrl;
|
|
896296
|
+
if (started) {
|
|
896297
|
+
manager5.savePending({
|
|
896298
|
+
provider: provider5,
|
|
896299
|
+
state: started.state,
|
|
896300
|
+
verifier: started.verifier,
|
|
896301
|
+
redirectUri: started.redirectUri,
|
|
896302
|
+
createdAt: Date.now()
|
|
896303
|
+
});
|
|
896304
|
+
}
|
|
896305
|
+
const browserOpened = openBrowser2 ? await openExternalUrl(authorizationUrl) : false;
|
|
896306
|
+
host.localEditor = null;
|
|
896307
|
+
host.runtimeSnapshot = context ? buildAgentWorkspaceRuntimeSnapshot(context) : host.runtimeSnapshot;
|
|
896308
|
+
host.status = `Subscription login started for ${provider5}.`;
|
|
896309
|
+
host.lastActionResult = {
|
|
896310
|
+
kind: "refreshed",
|
|
896311
|
+
title: "Subscription login started",
|
|
896312
|
+
detail: [
|
|
896313
|
+
`Provider: ${provider5}.`,
|
|
896314
|
+
`Browser: ${openBrowser2 ? browserOpened ? "opened" : "open failed" : "skipped"}.`,
|
|
896315
|
+
"Use Finish subscription login with the callback code or redirect URL.",
|
|
896316
|
+
`Authorization URL: ${authorizationUrl}`
|
|
896317
|
+
].join(" "),
|
|
896318
|
+
safety: "safe"
|
|
896319
|
+
};
|
|
896320
|
+
host.clampSelection();
|
|
896321
|
+
} catch (error53) {
|
|
896322
|
+
const detail = error53 instanceof Error ? error53.message : String(error53);
|
|
896323
|
+
host.localEditor = { ...editor, message: detail };
|
|
896324
|
+
host.status = detail;
|
|
896325
|
+
host.lastActionResult = { kind: "error", title: "Subscription login start failed", detail, safety: "safe" };
|
|
896326
|
+
}
|
|
896327
|
+
}
|
|
896328
|
+
async function submitAgentWorkspaceSubscriptionLoginFinishEditor(host, editor, context, readField) {
|
|
896329
|
+
if (!isAffirmative15(readField("confirm"))) {
|
|
896330
|
+
host.localEditor = { ...editor, message: "Subscription login finish not confirmed. Type yes, then press Enter." };
|
|
896331
|
+
host.status = "Subscription login finish not confirmed.";
|
|
896332
|
+
return;
|
|
896333
|
+
}
|
|
896334
|
+
try {
|
|
896335
|
+
const provider5 = readField("provider") || "openai";
|
|
896336
|
+
const codeInput = readField("code");
|
|
896337
|
+
const code2 = extractAuthorizationCode3(codeInput) ?? codeInput;
|
|
896338
|
+
const { manager: manager5, services } = subscriptionServices(context);
|
|
896339
|
+
const resolved = getSubscriptionProviderConfig(provider5, services.get(provider5));
|
|
896340
|
+
if (!resolved) {
|
|
896341
|
+
throw new Error(`OAuth is not configured for ${provider5}. Start with a configured or built-in subscription provider.`);
|
|
896342
|
+
}
|
|
896343
|
+
const record2 = provider5 === "openai" && resolved.source === "builtin" ? (() => {
|
|
896344
|
+
const pending = manager5.getPending(provider5);
|
|
896345
|
+
if (!pending)
|
|
896346
|
+
throw new Error(`No pending OAuth login for ${provider5}. Start subscription login first.`);
|
|
896347
|
+
return exchangeOpenAICodexCode(code2, pending.verifier).then((token) => {
|
|
896348
|
+
const now5 = Date.now();
|
|
896349
|
+
return manager5.saveSubscription({
|
|
896350
|
+
provider: provider5,
|
|
896351
|
+
accessToken: token.accessToken,
|
|
896352
|
+
tokenType: token.tokenType,
|
|
896353
|
+
...typeof token.refreshToken === "string" && token.refreshToken.length > 0 ? { refreshToken: token.refreshToken } : {},
|
|
896354
|
+
...typeof token.expiresAt === "number" && Number.isFinite(token.expiresAt) ? { expiresAt: token.expiresAt } : {},
|
|
896355
|
+
...token.scopes ? { scopes: token.scopes } : {},
|
|
896356
|
+
authMode: "oauth",
|
|
896357
|
+
overrideAmbientApiKeys: false,
|
|
896358
|
+
createdAt: manager5.get(provider5)?.createdAt ?? now5,
|
|
896359
|
+
updatedAt: now5
|
|
896360
|
+
});
|
|
896361
|
+
});
|
|
896362
|
+
})() : manager5.completeOAuthLogin(provider5, resolveManualLoginConfig2(resolved.oauth), code2);
|
|
896363
|
+
const saved = await record2;
|
|
896364
|
+
host.localEditor = null;
|
|
896365
|
+
host.runtimeSnapshot = context ? buildAgentWorkspaceRuntimeSnapshot(context) : host.runtimeSnapshot;
|
|
896366
|
+
host.status = `Subscription session saved for ${provider5}.`;
|
|
896367
|
+
host.lastActionResult = {
|
|
896368
|
+
kind: "refreshed",
|
|
896369
|
+
title: "Subscription session saved",
|
|
896370
|
+
detail: [
|
|
896371
|
+
`Provider: ${provider5}.`,
|
|
896372
|
+
`Token type: ${saved.tokenType}.`,
|
|
896373
|
+
`Expires: ${saved.expiresAt ? new Date(saved.expiresAt).toISOString() : "n/a"}.`,
|
|
896374
|
+
describeSubscriptionPrecedence(saved)
|
|
896375
|
+
].join(" "),
|
|
896376
|
+
safety: "safe"
|
|
896377
|
+
};
|
|
896378
|
+
host.clampSelection();
|
|
896379
|
+
} catch (error53) {
|
|
896380
|
+
const detail = error53 instanceof Error ? error53.message : String(error53);
|
|
896381
|
+
host.localEditor = { ...editor, message: detail };
|
|
896382
|
+
host.status = detail;
|
|
896383
|
+
host.lastActionResult = { kind: "error", title: "Subscription login finish failed", detail, safety: "safe" };
|
|
896384
|
+
}
|
|
896385
|
+
}
|
|
896386
|
+
function submitAgentWorkspaceSubscriptionLogoutEditor(host, editor, context, readField) {
|
|
896387
|
+
if (!isAffirmative15(readField("confirm"))) {
|
|
896388
|
+
host.localEditor = { ...editor, message: "Subscription logout not confirmed. Type yes, then press Enter." };
|
|
896389
|
+
host.status = "Subscription logout not confirmed.";
|
|
896390
|
+
return;
|
|
896391
|
+
}
|
|
896392
|
+
try {
|
|
896393
|
+
const provider5 = readField("provider") || "openai";
|
|
896394
|
+
const { manager: manager5 } = subscriptionServices(context);
|
|
896395
|
+
const removed = manager5.logout(provider5);
|
|
896396
|
+
host.localEditor = null;
|
|
896397
|
+
host.runtimeSnapshot = context ? buildAgentWorkspaceRuntimeSnapshot(context) : host.runtimeSnapshot;
|
|
896398
|
+
host.status = removed ? `Logged out of ${provider5}.` : `No subscription session existed for ${provider5}.`;
|
|
896399
|
+
host.lastActionResult = {
|
|
896400
|
+
kind: removed ? "refreshed" : "guidance",
|
|
896401
|
+
title: removed ? "Subscription session removed" : "No subscription session found",
|
|
896402
|
+
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}.`,
|
|
896403
|
+
safety: "safe"
|
|
896404
|
+
};
|
|
896405
|
+
host.clampSelection();
|
|
896406
|
+
} catch (error53) {
|
|
896407
|
+
const detail = error53 instanceof Error ? error53.message : String(error53);
|
|
896408
|
+
host.localEditor = { ...editor, message: detail };
|
|
896409
|
+
host.status = detail;
|
|
896410
|
+
host.lastActionResult = { kind: "error", title: "Subscription logout failed", detail, safety: "safe" };
|
|
896411
|
+
}
|
|
896412
|
+
}
|
|
896413
|
+
function subscriptionServices(context) {
|
|
896414
|
+
const manager5 = context?.platform.subscriptionManager;
|
|
896415
|
+
const services = context?.platform.serviceRegistry;
|
|
896416
|
+
if (!manager5 || !services)
|
|
896417
|
+
throw new Error("Subscription services are unavailable in this runtime.");
|
|
896418
|
+
return { manager: manager5, services };
|
|
896419
|
+
}
|
|
896420
|
+
function extractAuthorizationCode3(input) {
|
|
896421
|
+
const trimmed2 = input.trim();
|
|
896422
|
+
if (!trimmed2)
|
|
896423
|
+
return null;
|
|
896424
|
+
try {
|
|
896425
|
+
const url2 = new URL(trimmed2);
|
|
896426
|
+
return url2.searchParams.get("code");
|
|
896427
|
+
} catch {
|
|
896428
|
+
return null;
|
|
896429
|
+
}
|
|
896430
|
+
}
|
|
896431
|
+
function resolveManualLoginConfig2(config6) {
|
|
896432
|
+
return config6.manualRedirectUri ? { ...config6, redirectUri: config6.manualRedirectUri } : config6;
|
|
896433
|
+
}
|
|
896434
|
+
function describeSubscriptionPrecedence(record2) {
|
|
896435
|
+
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.";
|
|
896436
|
+
}
|
|
896040
896437
|
// src/input/agent-workspace-token.ts
|
|
896041
896438
|
function handleAgentWorkspaceToken(workspace, token, handleEscape2, requestRender) {
|
|
896042
896439
|
if (!workspace.active)
|
|
@@ -896405,6 +896802,51 @@ class AgentWorkspace {
|
|
|
896405
896802
|
this.lastActionResult = { kind: "error", title: "Onboarding completion failed", detail, safety: "safe" };
|
|
896406
896803
|
}
|
|
896407
896804
|
}
|
|
896805
|
+
openModelPickerAction(action2, requestRender) {
|
|
896806
|
+
const target = action2.modelPickerTarget ?? "main";
|
|
896807
|
+
const opened2 = action2.modelPickerFlow === "model" ? this.context?.openModelPickerWithTarget?.(target) : this.context?.openProviderModelPickerWithTarget?.(target);
|
|
896808
|
+
if (!opened2) {
|
|
896809
|
+
this.status = "Model picker is unavailable.";
|
|
896810
|
+
this.lastActionResult = {
|
|
896811
|
+
kind: "error",
|
|
896812
|
+
title: "Model picker unavailable",
|
|
896813
|
+
detail: "This runtime cannot open the model picker from Agent workspace.",
|
|
896814
|
+
safety: action2.safety
|
|
896815
|
+
};
|
|
896816
|
+
requestRender?.();
|
|
896817
|
+
return;
|
|
896818
|
+
}
|
|
896819
|
+
this.status = `Opening ${action2.label}.`;
|
|
896820
|
+
this.lastActionResult = {
|
|
896821
|
+
kind: "dispatched",
|
|
896822
|
+
title: `Opening ${action2.label}`,
|
|
896823
|
+
detail: "Opened the shared provider/model picker for this setup target.",
|
|
896824
|
+
safety: action2.safety
|
|
896825
|
+
};
|
|
896826
|
+
requestRender?.();
|
|
896827
|
+
}
|
|
896828
|
+
openSettingsModalAction(action2, requestRender) {
|
|
896829
|
+
if (!this.context?.openSettingsModal) {
|
|
896830
|
+
this.status = "Settings are unavailable.";
|
|
896831
|
+
this.lastActionResult = {
|
|
896832
|
+
kind: "error",
|
|
896833
|
+
title: "Settings unavailable",
|
|
896834
|
+
detail: "This runtime cannot open settings from Agent workspace.",
|
|
896835
|
+
safety: action2.safety
|
|
896836
|
+
};
|
|
896837
|
+
requestRender?.();
|
|
896838
|
+
return;
|
|
896839
|
+
}
|
|
896840
|
+
this.context.openSettingsModal(action2.settingsTarget);
|
|
896841
|
+
this.status = `Opening ${action2.label}.`;
|
|
896842
|
+
this.lastActionResult = {
|
|
896843
|
+
kind: "dispatched",
|
|
896844
|
+
title: `Opening ${action2.label}`,
|
|
896845
|
+
detail: "Opened the shared settings surface for this setup area.",
|
|
896846
|
+
safety: action2.safety
|
|
896847
|
+
};
|
|
896848
|
+
requestRender?.();
|
|
896849
|
+
}
|
|
896408
896850
|
applySettingAction(action2, requestRender) {
|
|
896409
896851
|
const effect = buildAgentWorkspaceSettingActionEffect(this.context, action2);
|
|
896410
896852
|
if (effect.kind === "result") {
|
|
@@ -896515,6 +896957,19 @@ class AgentWorkspace {
|
|
|
896515
896957
|
this.status = `${missing.label} is required.`;
|
|
896516
896958
|
return;
|
|
896517
896959
|
}
|
|
896960
|
+
if (editor.kind === "subscription-login-start") {
|
|
896961
|
+
submitAgentWorkspaceSubscriptionLoginStartEditor(this, editor, this.context, (id) => this.editorField(id)).finally(() => requestRender?.());
|
|
896962
|
+
return;
|
|
896963
|
+
}
|
|
896964
|
+
if (editor.kind === "subscription-login-finish") {
|
|
896965
|
+
submitAgentWorkspaceSubscriptionLoginFinishEditor(this, editor, this.context, (id) => this.editorField(id)).finally(() => requestRender?.());
|
|
896966
|
+
return;
|
|
896967
|
+
}
|
|
896968
|
+
if (editor.kind === "subscription-logout") {
|
|
896969
|
+
submitAgentWorkspaceSubscriptionLogoutEditor(this, editor, this.context, (id) => this.editorField(id));
|
|
896970
|
+
requestRender?.();
|
|
896971
|
+
return;
|
|
896972
|
+
}
|
|
896518
896973
|
if (isAgentWorkspaceCommandEditorKind(editor.kind)) {
|
|
896519
896974
|
this.submitCommandEditor(editor);
|
|
896520
896975
|
requestRender?.();
|
|
@@ -896565,138 +897020,13 @@ class AgentWorkspace {
|
|
|
896565
897020
|
return;
|
|
896566
897021
|
}
|
|
896567
897022
|
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
|
-
}
|
|
897023
|
+
submitAgentWorkspaceLocalRegistryEditor(shellPaths3, editor, {
|
|
897024
|
+
readField: (id) => this.editorField(id),
|
|
897025
|
+
learnedBehaviorTarget: () => this.learnedBehaviorTarget(),
|
|
897026
|
+
submitDeleteEditor: () => this.submitLocalDeleteEditor(shellPaths3, editor),
|
|
897027
|
+
finishLocalEditor: (kind2, id, name51, verb) => this.finishLocalEditor(kind2, id, name51, verb),
|
|
897028
|
+
finishProfileEditor: (profile5) => this.finishProfileEditor(profile5)
|
|
897029
|
+
});
|
|
896700
897030
|
} catch (error53) {
|
|
896701
897031
|
const detail = error53 instanceof Error ? error53.message : String(error53);
|
|
896702
897032
|
this.localEditor = { ...editor, message: detail };
|
|
@@ -898540,6 +898870,17 @@ function handleModalTokenRoutes(state4, token) {
|
|
|
898540
898870
|
}, token)) {
|
|
898541
898871
|
return withState(state4, true);
|
|
898542
898872
|
}
|
|
898873
|
+
if (handleModelPickerToken({
|
|
898874
|
+
modelPicker: state4.modelPicker,
|
|
898875
|
+
modalStack: state4.modalStack,
|
|
898876
|
+
commandContext: state4.commandContext,
|
|
898877
|
+
getViewportHeight: state4.getViewportHeight,
|
|
898878
|
+
requestRender: state4.requestRender,
|
|
898879
|
+
handleEscape: state4.handleEscape,
|
|
898880
|
+
onModelPickerCommit: state4.onModelPickerCommit
|
|
898881
|
+
}, token)) {
|
|
898882
|
+
return withState(state4, true);
|
|
898883
|
+
}
|
|
898543
898884
|
if (handleSettingsModalToken({
|
|
898544
898885
|
settingsModal: state4.settingsModal,
|
|
898545
898886
|
commandContext: state4.commandContext,
|
|
@@ -898592,17 +898933,6 @@ function handleModalTokenRoutes(state4, token) {
|
|
|
898592
898933
|
if (handleHistorySearchToken(historyState, token)) {
|
|
898593
898934
|
return withState(state4, true, historyState);
|
|
898594
898935
|
}
|
|
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
898936
|
if (handleLiveTailToken({
|
|
898607
898937
|
liveTailModal: state4.liveTailModal,
|
|
898608
898938
|
processModal: state4.processModal,
|
|
@@ -899541,7 +899871,8 @@ class InputHandler {
|
|
|
899541
899871
|
handleCtrlCForHandler(this);
|
|
899542
899872
|
}
|
|
899543
899873
|
modalOpened(name51) {
|
|
899544
|
-
|
|
899874
|
+
const keepAgentWorkspaceUnderlay = name51 === "modelPicker" || name51 === "settings";
|
|
899875
|
+
if (name51 !== "agentWorkspace" && !keepAgentWorkspaceUnderlay && this.agentWorkspace.active) {
|
|
899545
899876
|
this.closeAgentWorkspaceModal();
|
|
899546
899877
|
}
|
|
899547
899878
|
modalOpenedForHandler(this, name51);
|
|
@@ -899904,232 +900235,6 @@ class PermissionPromptUI {
|
|
|
899904
900235
|
}
|
|
899905
900236
|
}
|
|
899906
900237
|
|
|
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
900238
|
// src/renderer/model-workspace.ts
|
|
900134
900239
|
var PALETTE = {
|
|
900135
900240
|
border: "#64748b",
|
|
@@ -900175,7 +900280,7 @@ var MODEL_WORKSPACE_CONTEXT_CAP_INPUT_HELP = "Type digits to set a cap. Enter co
|
|
|
900175
900280
|
var MODEL_WORKSPACE_FOOTER_SEARCH_ACTIVE = "Typing filters search; Esc clears search";
|
|
900176
900281
|
var MODEL_WORKSPACE_FOOTER_SEARCH_INACTIVE = "/ search";
|
|
900177
900282
|
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
|
|
900283
|
+
function clamp4(value, min2, max2) {
|
|
900179
900284
|
return Math.max(min2, Math.min(max2, value));
|
|
900180
900285
|
}
|
|
900181
900286
|
function fillRange2(line2, startX, endX, bg) {
|
|
@@ -900264,10 +900369,10 @@ function padDisplay2(text, width) {
|
|
|
900264
900369
|
function stableWindow2(total, selected, visible) {
|
|
900265
900370
|
if (total <= 0 || visible <= 0)
|
|
900266
900371
|
return { start: 0, end: 0 };
|
|
900267
|
-
const clamped =
|
|
900372
|
+
const clamped = clamp4(selected, 0, total - 1);
|
|
900268
900373
|
const half = Math.floor(visible / 2);
|
|
900269
900374
|
const maxStart = Math.max(0, total - visible);
|
|
900270
|
-
const start2 =
|
|
900375
|
+
const start2 = clamp4(clamped - half, 0, maxStart);
|
|
900271
900376
|
return { start: start2, end: Math.min(total, start2 + visible) };
|
|
900272
900377
|
}
|
|
900273
900378
|
function formatContext(value) {
|
|
@@ -900405,11 +900510,11 @@ function renderProviderRows(picker, lines, rows, startX, width) {
|
|
|
900405
900510
|
function renderModelRows(picker, lines, rows, startX, width) {
|
|
900406
900511
|
const models = picker.getFilteredModels();
|
|
900407
900512
|
const { start: start2, end } = stableWindow2(models.length, picker.selectedIndex, rows);
|
|
900408
|
-
const providerW =
|
|
900513
|
+
const providerW = clamp4(Math.floor(width * 0.14), 10, 18);
|
|
900409
900514
|
const ctxW = 8;
|
|
900410
900515
|
const tierW = 8;
|
|
900411
900516
|
const capsW = 14;
|
|
900412
|
-
const nameW =
|
|
900517
|
+
const nameW = clamp4(Math.floor(width * 0.28), 16, 36);
|
|
900413
900518
|
const keyW = Math.max(10, width - providerW - ctxW - tierW - capsW - nameW - 10);
|
|
900414
900519
|
for (let visibleRow = 0;visibleRow < rows; visibleRow += 1) {
|
|
900415
900520
|
const absolute = start2 + visibleRow;
|
|
@@ -900489,11 +900594,11 @@ function writeTableHeader(line2, picker, startX, width) {
|
|
|
900489
900594
|
writeText3(line2, startX + 1, width - 2, MODEL_WORKSPACE_TABLE_HEADERS.contextCap, style);
|
|
900490
900595
|
return;
|
|
900491
900596
|
}
|
|
900492
|
-
const providerW =
|
|
900597
|
+
const providerW = clamp4(Math.floor(width * 0.14), 10, 18);
|
|
900493
900598
|
const ctxW = 8;
|
|
900494
900599
|
const tierW = 8;
|
|
900495
900600
|
const capsW = 14;
|
|
900496
|
-
const nameW =
|
|
900601
|
+
const nameW = clamp4(Math.floor(width * 0.28), 16, 36);
|
|
900497
900602
|
const keyW = Math.max(10, width - providerW - ctxW - tierW - capsW - nameW - 10);
|
|
900498
900603
|
let x2 = startX + 3;
|
|
900499
900604
|
writeText3(line2, x2, keyW, padDisplay2(MODEL_WORKSPACE_TABLE_HEADERS.modelKey, keyW), style);
|
|
@@ -900516,7 +900621,7 @@ function renderModelWorkspace(picker, width, viewportHeight) {
|
|
|
900516
900621
|
const safeWidth = Math.max(20, width);
|
|
900517
900622
|
const safeHeight = Math.max(12, viewportHeight);
|
|
900518
900623
|
const lines = [];
|
|
900519
|
-
const targetW =
|
|
900624
|
+
const targetW = clamp4(Math.round(safeWidth * 0.18), 24, 34);
|
|
900520
900625
|
const contentX = targetW + 1;
|
|
900521
900626
|
const contentW = Math.max(1, safeWidth - contentX - 1);
|
|
900522
900627
|
const top = borderLine2(safeWidth, GLYPHS.frame.topLeft, GLYPHS.frame.horizontal, GLYPHS.frame.topRight);
|
|
@@ -900536,7 +900641,7 @@ function renderModelWorkspace(picker, width, viewportHeight) {
|
|
|
900536
900641
|
const bodyRows = safeHeight - 3 - footerRows;
|
|
900537
900642
|
const maxDetailRows = Math.max(3, bodyRows - 2);
|
|
900538
900643
|
const minDetailRows = Math.min(6, maxDetailRows);
|
|
900539
|
-
const detailRows =
|
|
900644
|
+
const detailRows = clamp4(Math.round(bodyRows * 0.32), minDetailRows, maxDetailRows);
|
|
900540
900645
|
const listRows = Math.max(1, bodyRows - detailRows - 1);
|
|
900541
900646
|
const details = detailLines(picker, contentW - 2).slice(0, detailRows);
|
|
900542
900647
|
for (let row = 0;row < bodyRows; row += 1) {
|
|
@@ -900644,292 +900749,6 @@ function keyForTargets(values2) {
|
|
|
900644
900749
|
].join("\x1D")).join("\x1F");
|
|
900645
900750
|
}
|
|
900646
900751
|
|
|
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
900752
|
// src/renderer/settings-modal-helpers.ts
|
|
900934
900753
|
function maskSecretValue(value) {
|
|
900935
900754
|
if (value.length === 0)
|
|
@@ -901604,6 +901423,518 @@ function renderSettingsModal(modal, width, viewportHeight = 24) {
|
|
|
901604
901423
|
});
|
|
901605
901424
|
}
|
|
901606
901425
|
|
|
901426
|
+
// src/renderer/layout-engine.ts
|
|
901427
|
+
function clamp5(value, min2, max2) {
|
|
901428
|
+
return Math.max(min2, Math.min(max2, value));
|
|
901429
|
+
}
|
|
901430
|
+
function createShellLayout(request2) {
|
|
901431
|
+
const width = Math.max(1, request2.width);
|
|
901432
|
+
const height = Math.max(1, request2.height);
|
|
901433
|
+
const headerHeight = clamp5(request2.headerHeight, 0, height);
|
|
901434
|
+
const footerHeight = clamp5(request2.footerHeight, 0, Math.max(0, height - headerHeight));
|
|
901435
|
+
const bodyHeight = Math.max(0, height - headerHeight - footerHeight);
|
|
901436
|
+
const hasPanel = typeof request2.panelWidth === "number" && request2.panelWidth > 0;
|
|
901437
|
+
const safePanelWidth = hasPanel ? clamp5(request2.panelWidth, 1, Math.max(1, width - 2)) : 0;
|
|
901438
|
+
const separatorWidth = hasPanel ? 1 : 0;
|
|
901439
|
+
const conversationWidth = hasPanel ? Math.max(1, width - safePanelWidth - separatorWidth) : width;
|
|
901440
|
+
return {
|
|
901441
|
+
screen: { x: 0, y: 0, width, height },
|
|
901442
|
+
header: { x: 0, y: 0, width, height: headerHeight },
|
|
901443
|
+
body: { x: 0, y: headerHeight, width, height: bodyHeight },
|
|
901444
|
+
footer: { x: 0, y: headerHeight + bodyHeight, width, height: footerHeight },
|
|
901445
|
+
conversation: { x: 0, y: headerHeight, width: conversationWidth, height: bodyHeight },
|
|
901446
|
+
panel: hasPanel ? {
|
|
901447
|
+
x: conversationWidth + separatorWidth,
|
|
901448
|
+
y: headerHeight,
|
|
901449
|
+
width: safePanelWidth,
|
|
901450
|
+
height: bodyHeight
|
|
901451
|
+
} : undefined,
|
|
901452
|
+
separatorX: hasPanel ? conversationWidth : undefined
|
|
901453
|
+
};
|
|
901454
|
+
}
|
|
901455
|
+
function createSplitPaneLayout(totalRows, ratio, options = {}) {
|
|
901456
|
+
const topTabRows = options.topTabRows ?? 1;
|
|
901457
|
+
const bottomTabRows = options.bottomTabRows ?? 1;
|
|
901458
|
+
const separatorRows = options.separatorRows ?? 1;
|
|
901459
|
+
const chromeRows = topTabRows + bottomTabRows + separatorRows;
|
|
901460
|
+
const contentRows = Math.max(0, totalRows - chromeRows);
|
|
901461
|
+
const normalizedRatio = clamp5(ratio, 0.2, 0.8);
|
|
901462
|
+
const topContentRows = contentRows <= 1 ? contentRows : Math.max(1, Math.floor(contentRows * normalizedRatio));
|
|
901463
|
+
const bottomContentRows = contentRows <= 1 ? 0 : Math.max(1, contentRows - topContentRows);
|
|
901464
|
+
return {
|
|
901465
|
+
totalRows,
|
|
901466
|
+
topTabRows,
|
|
901467
|
+
bottomTabRows,
|
|
901468
|
+
separatorRows,
|
|
901469
|
+
topContentRows,
|
|
901470
|
+
bottomContentRows
|
|
901471
|
+
};
|
|
901472
|
+
}
|
|
901473
|
+
|
|
901474
|
+
// src/renderer/process-indicator.ts
|
|
901475
|
+
function truncateToWidth2(text, maxWidth) {
|
|
901476
|
+
let width = 0;
|
|
901477
|
+
let i5 = 0;
|
|
901478
|
+
for (const char of text) {
|
|
901479
|
+
const cw = getDisplayWidth(char);
|
|
901480
|
+
if (width + cw > maxWidth)
|
|
901481
|
+
break;
|
|
901482
|
+
width += cw;
|
|
901483
|
+
i5 += char.length;
|
|
901484
|
+
}
|
|
901485
|
+
return text.slice(0, i5);
|
|
901486
|
+
}
|
|
901487
|
+
function renderProcessIndicator(width, agentCount, toolCount, focused = false, agentProgress) {
|
|
901488
|
+
const total = agentCount + toolCount;
|
|
901489
|
+
const delegationLabel = (count) => `${count} delegation${count !== 1 ? "s" : ""}`;
|
|
901490
|
+
const renderPlainStatus = (text, style) => [UIFactory.stringToLine(` ${text}`, width, style)];
|
|
901491
|
+
const renderFocusedStatus = (text) => {
|
|
901492
|
+
const bg = "#31506f";
|
|
901493
|
+
const fg = "#eefaff";
|
|
901494
|
+
const markerFg = "#7dd3fc";
|
|
901495
|
+
const line2 = UIFactory.stringToLine(" ".repeat(width), width, { fg: "238" });
|
|
901496
|
+
const prefix = `${GLYPHS.navigation.selected} `;
|
|
901497
|
+
const body2 = truncateToWidth2(text, Math.max(0, width - 8));
|
|
901498
|
+
const highlighted = ` ${prefix}${body2} `;
|
|
901499
|
+
const startX = 2;
|
|
901500
|
+
for (let i5 = 0;i5 < highlighted.length && startX + i5 < width - 2; i5++) {
|
|
901501
|
+
const ch = highlighted[i5];
|
|
901502
|
+
const isMarker = i5 < prefix.length + 1;
|
|
901503
|
+
line2[startX + i5].char = ch;
|
|
901504
|
+
line2[startX + i5].fg = isMarker ? markerFg : fg;
|
|
901505
|
+
line2[startX + i5].bg = bg;
|
|
901506
|
+
line2[startX + i5].bold = true;
|
|
901507
|
+
line2[startX + i5].dim = false;
|
|
901508
|
+
}
|
|
901509
|
+
return [line2];
|
|
901510
|
+
};
|
|
901511
|
+
if (focused) {
|
|
901512
|
+
const parts3 = [];
|
|
901513
|
+
if (agentCount > 0)
|
|
901514
|
+
parts3.push(delegationLabel(agentCount));
|
|
901515
|
+
if (toolCount > 0)
|
|
901516
|
+
parts3.push(`${toolCount} tool${toolCount !== 1 ? "s" : ""} running`);
|
|
901517
|
+
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`;
|
|
901518
|
+
return renderFocusedStatus(label2);
|
|
901519
|
+
}
|
|
901520
|
+
if (total === 0) {
|
|
901521
|
+
return renderPlainStatus("No runtime activity", { fg: "238", dim: true });
|
|
901522
|
+
}
|
|
901523
|
+
const parts2 = [];
|
|
901524
|
+
if (agentCount > 0) {
|
|
901525
|
+
parts2.push(delegationLabel(agentCount));
|
|
901526
|
+
}
|
|
901527
|
+
if (toolCount > 0) {
|
|
901528
|
+
parts2.push(`${toolCount} tool${toolCount !== 1 ? "s" : ""} running`);
|
|
901529
|
+
}
|
|
901530
|
+
const PROGRESS_RESERVED_CHARS = 43;
|
|
901531
|
+
const progressMaxLen = Math.max(0, width - PROGRESS_RESERVED_CHARS);
|
|
901532
|
+
const progressSuffix = agentProgress && progressMaxLen > 10 ? ` | ${agentProgress.length > progressMaxLen ? agentProgress.slice(0, Math.max(0, progressMaxLen - 3)) + "..." : agentProgress}` : "";
|
|
901533
|
+
const label = `${parts2.join(` ${GLYPHS.navigation.pipeSeparator} `)}${progressSuffix}`;
|
|
901534
|
+
const hint = ` ${GLYPHS.status.pending} Enter to view`;
|
|
901535
|
+
return renderPlainStatus(`${label}${hint}`, { fg: "#00ffff", bold: true });
|
|
901536
|
+
}
|
|
901537
|
+
|
|
901538
|
+
// src/renderer/shell-surface.ts
|
|
901539
|
+
var FOOTER_BASE_ROWS = 9;
|
|
901540
|
+
var CONTEXT_PROGRESS_ROWS = 2;
|
|
901541
|
+
var PROCESS_INDICATOR_ROWS = 1;
|
|
901542
|
+
function estimateShellFooterHeight(promptLineCount, contextWindow) {
|
|
901543
|
+
const safePromptLines = Math.max(1, promptLineCount);
|
|
901544
|
+
const progressRows = contextWindow && contextWindow > 0 ? CONTEXT_PROGRESS_ROWS : 0;
|
|
901545
|
+
return FOOTER_BASE_ROWS + safePromptLines + progressRows + PROCESS_INDICATOR_ROWS;
|
|
901546
|
+
}
|
|
901547
|
+
function buildShellFooter(options) {
|
|
901548
|
+
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);
|
|
901549
|
+
const processIndicator = renderProcessIndicator(options.width, options.runningAgentCount, options.runningProcessCount, options.indicatorFocused, options.runningAgentProgress);
|
|
901550
|
+
const inputBoxRows = Math.max(1, options.promptLineCount) + 2;
|
|
901551
|
+
lines.splice(inputBoxRows, 0, ...processIndicator);
|
|
901552
|
+
return { lines, height: lines.length };
|
|
901553
|
+
}
|
|
901554
|
+
|
|
901555
|
+
// src/renderer/conversation-layout.ts
|
|
901556
|
+
function buildConversationViewport(request2) {
|
|
901557
|
+
const overlayRows = request2.overlayRows ?? 0;
|
|
901558
|
+
const effectiveHeight = Math.max(0, request2.viewportHeight - overlayRows);
|
|
901559
|
+
const lineCount = request2.conversation.history.getLineCount();
|
|
901560
|
+
const maxScroll = Math.max(0, lineCount - effectiveHeight);
|
|
901561
|
+
const nextScrollTop = request2.scrollLocked ? maxScroll : Math.max(0, Math.min(request2.scrollTop, maxScroll));
|
|
901562
|
+
const viewport = request2.conversation.history.getSnapshot(nextScrollTop, effectiveHeight, request2.width);
|
|
901563
|
+
return {
|
|
901564
|
+
effectiveHeight,
|
|
901565
|
+
maxScroll,
|
|
901566
|
+
nextScrollTop,
|
|
901567
|
+
viewport
|
|
901568
|
+
};
|
|
901569
|
+
}
|
|
901570
|
+
function overlayViewportBottom(viewport, overlay, width, viewportHeight, bottomInset = 0) {
|
|
901571
|
+
if (overlay.length === 0)
|
|
901572
|
+
return [...viewport];
|
|
901573
|
+
const next = [...viewport];
|
|
901574
|
+
const targetStart = Math.max(0, viewportHeight - bottomInset - overlay.length);
|
|
901575
|
+
next.length = Math.min(next.length, targetStart);
|
|
901576
|
+
while (next.length < targetStart)
|
|
901577
|
+
next.push(createEmptyLine(width));
|
|
901578
|
+
next.push(...overlay);
|
|
901579
|
+
return next;
|
|
901580
|
+
}
|
|
901581
|
+
function replaceViewportWithOverlay(overlay, width, viewportHeight) {
|
|
901582
|
+
const next = [];
|
|
901583
|
+
const pad = Math.max(0, viewportHeight - overlay.length);
|
|
901584
|
+
for (let i5 = 0;i5 < pad; i5++)
|
|
901585
|
+
next.push(createEmptyLine(width));
|
|
901586
|
+
next.push(...overlay);
|
|
901587
|
+
return next;
|
|
901588
|
+
}
|
|
901589
|
+
|
|
901590
|
+
// src/renderer/file-picker-overlay.ts
|
|
901591
|
+
var FILE_PICKER_TITLE = "Select File";
|
|
901592
|
+
var FILE_PICKER_SEARCH_PREFIX = "@ ";
|
|
901593
|
+
var FILE_PICKER_EMPTY_MESSAGE = "No matching files";
|
|
901594
|
+
var FILE_PICKER_HINTS = "[Up/Down] Navigate [/] Search [Enter] Select [Esc] Cancel";
|
|
901595
|
+
function renderFilePickerOverlay(picker, width, viewportHeight = 24) {
|
|
901596
|
+
const lines = [];
|
|
901597
|
+
const metrics = getOverlaySurfaceMetrics(width, viewportHeight, {
|
|
901598
|
+
chromeRows: 4,
|
|
901599
|
+
maxWidth: 70,
|
|
901600
|
+
minContentRows: 6,
|
|
901601
|
+
maxContentRows: 10
|
|
901602
|
+
});
|
|
901603
|
+
const layout = createOverlayBoxLayout(width, metrics.margin, metrics.boxWidth);
|
|
901604
|
+
const contentW = layout.innerWidth;
|
|
901605
|
+
const borderFg = DEFAULT_OVERLAY_PALETTE.borderFg;
|
|
901606
|
+
const titleFg = DEFAULT_OVERLAY_PALETTE.titleFg;
|
|
901607
|
+
const bodyFg = DEFAULT_OVERLAY_PALETTE.bodyFg;
|
|
901608
|
+
const mutedFg = DEFAULT_OVERLAY_PALETTE.mutedFg;
|
|
901609
|
+
const selectedBg = DEFAULT_OVERLAY_PALETTE.selectedBg;
|
|
901610
|
+
const titleLine = createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.topLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.topRight, borderFg, DEFAULT_OVERLAY_PALETTE.titleBg);
|
|
901611
|
+
putOverlayText(titleLine, layout.margin + 2, layout.width - 4, FILE_PICKER_TITLE, { fg: titleFg, bold: true });
|
|
901612
|
+
lines.push(titleLine);
|
|
901613
|
+
const queryDisplay = picker.query || "";
|
|
901614
|
+
const searchLine = createOverlayContentLine(width, layout, borderFg, DEFAULT_OVERLAY_PALETTE.inputBg);
|
|
901615
|
+
const searchPrefix = FILE_PICKER_SEARCH_PREFIX;
|
|
901616
|
+
const queryText = fitDisplay(`${queryDisplay}${picker.searchFocused ? OVERLAY_GLYPHS.cursor : ""}`, Math.max(0, contentW - getDisplayWidth(searchPrefix)));
|
|
901617
|
+
putOverlayText(searchLine, layout.margin + 2, getDisplayWidth(searchPrefix), searchPrefix, { fg: picker.searchFocused ? bodyFg : mutedFg });
|
|
901618
|
+
putOverlayText(searchLine, layout.margin + 2 + getDisplayWidth(searchPrefix), contentW - getDisplayWidth(searchPrefix), queryText, { fg: picker.query.length > 0 || picker.searchFocused ? bodyFg : mutedFg });
|
|
901619
|
+
lines.push(searchLine);
|
|
901620
|
+
lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.teeLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.teeRight, borderFg, DEFAULT_OVERLAY_PALETTE.sectionBg));
|
|
901621
|
+
if (picker.results.length === 0) {
|
|
901622
|
+
const noResults = createOverlayContentLine(width, layout, borderFg, DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
901623
|
+
putOverlayText(noResults, layout.margin + 2, contentW, fitDisplay(FILE_PICKER_EMPTY_MESSAGE, contentW), { fg: "244", dim: true });
|
|
901624
|
+
lines.push(noResults);
|
|
901625
|
+
} else {
|
|
901626
|
+
const maxVisible = metrics.contentRows;
|
|
901627
|
+
let startIdx = 0;
|
|
901628
|
+
if (picker.results.length > maxVisible) {
|
|
901629
|
+
startIdx = Math.max(0, Math.min(picker.selectedIndex - Math.floor(maxVisible / 2), picker.results.length - maxVisible));
|
|
901630
|
+
}
|
|
901631
|
+
const endIdx = Math.min(startIdx + maxVisible, picker.results.length);
|
|
901632
|
+
for (let i5 = startIdx;i5 < endIdx; i5++) {
|
|
901633
|
+
const file2 = picker.results[i5];
|
|
901634
|
+
const isSelected = i5 === picker.selectedIndex;
|
|
901635
|
+
const indicator = isSelected ? `${OVERLAY_GLYPHS.selected} ` : " ";
|
|
901636
|
+
const displayFile = getDisplayWidth(file2) > contentW - 2 ? truncateDisplay(file2, contentW - 2) : file2;
|
|
901637
|
+
const line2 = createOverlayContentLine(width, layout, borderFg, isSelected ? selectedBg : DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
901638
|
+
putOverlayText(line2, layout.margin + 2, contentW, fitDisplay(indicator + fitDisplay(displayFile, contentW - 2), contentW), {
|
|
901639
|
+
fg: isSelected ? titleFg : file2.endsWith("/") ? titleFg : bodyFg,
|
|
901640
|
+
bg: isSelected ? selectedBg : DEFAULT_OVERLAY_PALETTE.bodyBg,
|
|
901641
|
+
bold: isSelected
|
|
901642
|
+
});
|
|
901643
|
+
lines.push(line2);
|
|
901644
|
+
}
|
|
901645
|
+
}
|
|
901646
|
+
const bottomLine = createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.bottomLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.bottomRight, borderFg, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
901647
|
+
putOverlayText(bottomLine, layout.margin + 2, layout.width - 4, truncateDisplay(FILE_PICKER_HINTS, layout.width - 4), { fg: mutedFg, dim: true });
|
|
901648
|
+
lines.push(bottomLine);
|
|
901649
|
+
return lines;
|
|
901650
|
+
}
|
|
901651
|
+
|
|
901652
|
+
// src/renderer/selection-modal-overlay.ts
|
|
901653
|
+
var BORDER_FG = DEFAULT_OVERLAY_PALETTE.borderFg;
|
|
901654
|
+
var TITLE_FG = DEFAULT_OVERLAY_PALETTE.titleFg;
|
|
901655
|
+
var BODY_FG = DEFAULT_OVERLAY_PALETTE.bodyFg;
|
|
901656
|
+
var MUTED_FG = DEFAULT_OVERLAY_PALETTE.mutedFg;
|
|
901657
|
+
var CATEGORY_FG = "#4488cc";
|
|
901658
|
+
var SELECTED_BG = DEFAULT_OVERLAY_PALETTE.selectedBg;
|
|
901659
|
+
var SELECTION_MODAL_SEARCH_LABEL = " Search";
|
|
901660
|
+
var SELECTION_MODAL_RESULTS_LABEL = " Results";
|
|
901661
|
+
var SELECTION_MODAL_NO_MATCHING_ITEMS = "No matching items";
|
|
901662
|
+
var SELECTION_MODAL_NO_ITEMS = "No items";
|
|
901663
|
+
var SELECTION_MODAL_NAVIGATION_HINT = "[Up/Down] Navigate";
|
|
901664
|
+
var SELECTION_MODAL_CLOSE_HINT = "[Esc] Close";
|
|
901665
|
+
var SELECTION_MODAL_SEARCH_HINT = "[/] Search";
|
|
901666
|
+
var SELECTION_MODAL_SPACE_TOGGLE_HINT = "[Space] Toggle";
|
|
901667
|
+
function putText(line2, startX, maxWidth, text, style) {
|
|
901668
|
+
putOverlayText(line2, startX, maxWidth, text, style);
|
|
901669
|
+
}
|
|
901670
|
+
function primaryVerbForAction(primaryAction) {
|
|
901671
|
+
return primaryAction === "toggle" ? "[Enter] Toggle" : primaryAction === "edit" ? "[Enter] Edit" : primaryAction === "delete" ? "[Enter] Delete" : "[Enter] Select";
|
|
901672
|
+
}
|
|
901673
|
+
function renderSelectionModalOverlay(modal, width, viewportHeight = 24) {
|
|
901674
|
+
const lines = [];
|
|
901675
|
+
const metrics = getOverlaySurfaceMetrics(width, viewportHeight, {
|
|
901676
|
+
margin: 4,
|
|
901677
|
+
maxWidth: 72,
|
|
901678
|
+
chromeRows: modal.allowSearch ? 5 : 4,
|
|
901679
|
+
minContentRows: 6,
|
|
901680
|
+
maxContentRows: 10
|
|
901681
|
+
});
|
|
901682
|
+
const layout = createOverlayBoxLayout(width, metrics.margin, metrics.boxWidth);
|
|
901683
|
+
lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.topLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.topRight, BORDER_FG, DEFAULT_OVERLAY_PALETTE.titleBg));
|
|
901684
|
+
const titleLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.titleBg);
|
|
901685
|
+
putText(titleLine, layout.margin + 2, layout.innerWidth, fitDisplay(truncateDisplay(modal.title, layout.innerWidth), layout.innerWidth), { fg: TITLE_FG, bold: true });
|
|
901686
|
+
lines.push(titleLine);
|
|
901687
|
+
if (modal.allowSearch) {
|
|
901688
|
+
const labelLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
901689
|
+
putText(labelLine, layout.margin + 2, layout.innerWidth, fitDisplay(SELECTION_MODAL_SEARCH_LABEL, layout.innerWidth), {
|
|
901690
|
+
fg: CATEGORY_FG,
|
|
901691
|
+
dim: true
|
|
901692
|
+
});
|
|
901693
|
+
lines.push(labelLine);
|
|
901694
|
+
const searchLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.inputBg);
|
|
901695
|
+
const prefix = "/ ";
|
|
901696
|
+
const queryAreaWidth = layout.innerWidth - getDisplayWidth(prefix);
|
|
901697
|
+
const queryValue = modal.query + (modal.searchFocused ? OVERLAY_GLYPHS.cursor : "");
|
|
901698
|
+
const queryText = fitDisplay(truncateDisplay(queryValue, queryAreaWidth), queryAreaWidth);
|
|
901699
|
+
putText(searchLine, layout.margin + 2, getDisplayWidth(prefix), prefix, { fg: modal.searchFocused ? BODY_FG : MUTED_FG });
|
|
901700
|
+
putText(searchLine, layout.margin + 2 + getDisplayWidth(prefix), queryAreaWidth, queryText, {
|
|
901701
|
+
fg: modal.query.length > 0 || modal.searchFocused ? BODY_FG : MUTED_FG
|
|
901702
|
+
});
|
|
901703
|
+
lines.push(searchLine);
|
|
901704
|
+
lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.teeLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.teeRight, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg));
|
|
901705
|
+
} else {
|
|
901706
|
+
lines.push(createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg));
|
|
901707
|
+
}
|
|
901708
|
+
const listTitle = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
901709
|
+
putText(listTitle, layout.margin + 2, layout.innerWidth, fitDisplay(SELECTION_MODAL_RESULTS_LABEL, layout.innerWidth), {
|
|
901710
|
+
fg: CATEGORY_FG,
|
|
901711
|
+
dim: true
|
|
901712
|
+
});
|
|
901713
|
+
lines.push(listTitle);
|
|
901714
|
+
const items = modal.filteredItems;
|
|
901715
|
+
if (items.length === 0) {
|
|
901716
|
+
const line2 = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
901717
|
+
const message = modal.query ? SELECTION_MODAL_NO_MATCHING_ITEMS : SELECTION_MODAL_NO_ITEMS;
|
|
901718
|
+
putText(line2, layout.margin + 2, layout.innerWidth, fitDisplay(message, layout.innerWidth), { fg: MUTED_FG, dim: true });
|
|
901719
|
+
lines.push(line2);
|
|
901720
|
+
} else {
|
|
901721
|
+
const maxVisible = metrics.contentRows;
|
|
901722
|
+
let startIdx = 0;
|
|
901723
|
+
if (items.length > maxVisible) {
|
|
901724
|
+
startIdx = Math.max(0, Math.min(modal.selectedIndex - Math.floor(maxVisible / 2), items.length - maxVisible));
|
|
901725
|
+
}
|
|
901726
|
+
const endIdx = Math.min(startIdx + maxVisible, items.length);
|
|
901727
|
+
let lastCategory;
|
|
901728
|
+
for (let i5 = startIdx;i5 < endIdx; i5++) {
|
|
901729
|
+
const item = items[i5];
|
|
901730
|
+
const isSelected = i5 === modal.selectedIndex;
|
|
901731
|
+
if (item.category && item.category !== lastCategory) {
|
|
901732
|
+
lastCategory = item.category;
|
|
901733
|
+
const categoryLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
901734
|
+
putText(categoryLine, layout.margin + 2, layout.innerWidth, fitDisplay(` ${item.category}`, layout.innerWidth), {
|
|
901735
|
+
fg: CATEGORY_FG,
|
|
901736
|
+
dim: true
|
|
901737
|
+
});
|
|
901738
|
+
lines.push(categoryLine);
|
|
901739
|
+
}
|
|
901740
|
+
const indicator = isSelected ? `${OVERLAY_GLYPHS.selected} ` : " ";
|
|
901741
|
+
const indicatorWidth = 2;
|
|
901742
|
+
const remaining = layout.innerWidth - indicatorWidth;
|
|
901743
|
+
const labelColor = isSelected ? TITLE_FG : item.fg ?? BODY_FG;
|
|
901744
|
+
const detailColor = isSelected ? BODY_FG : MUTED_FG;
|
|
901745
|
+
const labelWidth = item.detail ? fitLabelDetailColumns(item.label, item.detail, remaining).labelWidth : remaining;
|
|
901746
|
+
const labelLine = createOverlayContentLine(width, layout, BORDER_FG, isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
901747
|
+
putText(labelLine, layout.margin + 2, indicatorWidth, indicator, {
|
|
901748
|
+
fg: isSelected ? TITLE_FG : MUTED_FG,
|
|
901749
|
+
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg,
|
|
901750
|
+
bold: isSelected
|
|
901751
|
+
});
|
|
901752
|
+
putText(labelLine, layout.margin + 2 + indicatorWidth, labelWidth, fitDisplay(truncateDisplay(item.label, labelWidth), labelWidth), {
|
|
901753
|
+
fg: labelColor,
|
|
901754
|
+
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg,
|
|
901755
|
+
bold: isSelected
|
|
901756
|
+
});
|
|
901757
|
+
if (item.detail) {
|
|
901758
|
+
const detailWidth = fitLabelDetailColumns(item.label, item.detail, remaining).detailWidth;
|
|
901759
|
+
if (detailWidth >= 12) {
|
|
901760
|
+
putText(labelLine, layout.margin + 2 + indicatorWidth + labelWidth, 2, " ", {
|
|
901761
|
+
fg: BODY_FG,
|
|
901762
|
+
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg
|
|
901763
|
+
});
|
|
901764
|
+
putText(labelLine, layout.margin + 2 + indicatorWidth + labelWidth + 2, detailWidth, fitDisplay(truncateDisplay(item.detail, detailWidth), detailWidth), {
|
|
901765
|
+
fg: detailColor,
|
|
901766
|
+
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg
|
|
901767
|
+
});
|
|
901768
|
+
lines.push(labelLine);
|
|
901769
|
+
} else {
|
|
901770
|
+
lines.push(labelLine);
|
|
901771
|
+
const wrappedDetails = wrapWithHangingIndent(item.detail, Math.max(8, remaining), "", 2);
|
|
901772
|
+
for (const detailLineText of wrappedDetails) {
|
|
901773
|
+
const detailLine = createOverlayContentLine(width, layout, BORDER_FG, isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
901774
|
+
putText(detailLine, layout.margin + 2 + indicatorWidth, remaining, fitDisplay(truncateDisplay(detailLineText, remaining), remaining), {
|
|
901775
|
+
fg: detailColor,
|
|
901776
|
+
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg,
|
|
901777
|
+
dim: !isSelected
|
|
901778
|
+
});
|
|
901779
|
+
lines.push(detailLine);
|
|
901780
|
+
}
|
|
901781
|
+
}
|
|
901782
|
+
} else {
|
|
901783
|
+
lines.push(labelLine);
|
|
901784
|
+
}
|
|
901785
|
+
}
|
|
901786
|
+
if (items.length > maxVisible) {
|
|
901787
|
+
const above = startIdx;
|
|
901788
|
+
const below = items.length - endIdx;
|
|
901789
|
+
const scrollHint = above > 0 && below > 0 ? `(${above} above, ${below} below)` : below > 0 ? `(${below} below)` : `(${above} above)`;
|
|
901790
|
+
const hintLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
901791
|
+
putText(hintLine, layout.margin + 2, layout.innerWidth, fitDisplay(scrollHint, layout.innerWidth), { fg: MUTED_FG, dim: true });
|
|
901792
|
+
lines.push(hintLine);
|
|
901793
|
+
}
|
|
901794
|
+
}
|
|
901795
|
+
const footerLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
901796
|
+
const selectedItem = modal.getSelected();
|
|
901797
|
+
const primaryVerb = primaryVerbForAction(selectedItem?.primaryAction);
|
|
901798
|
+
let hints = `${SELECTION_MODAL_NAVIGATION_HINT} ${primaryVerb} ${SELECTION_MODAL_CLOSE_HINT}`;
|
|
901799
|
+
if (modal.allowSearch)
|
|
901800
|
+
hints += ` ${SELECTION_MODAL_SEARCH_HINT}`;
|
|
901801
|
+
if (selectedItem?.primaryAction === "toggle" && !selectedItem.actions)
|
|
901802
|
+
hints += ` ${SELECTION_MODAL_SPACE_TOGGLE_HINT}`;
|
|
901803
|
+
if (selectedItem?.actions)
|
|
901804
|
+
hints += ` ${selectedItem.actions}`;
|
|
901805
|
+
putText(footerLine, layout.margin + 2, layout.innerWidth, fitDisplay(truncateDisplay(hints, layout.innerWidth), layout.innerWidth), { fg: MUTED_FG, dim: true });
|
|
901806
|
+
lines.push(footerLine);
|
|
901807
|
+
lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.bottomLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.bottomRight, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg));
|
|
901808
|
+
return lines;
|
|
901809
|
+
}
|
|
901810
|
+
|
|
901811
|
+
// src/renderer/bottom-bar.ts
|
|
901812
|
+
function createBottomBarLine(width, style) {
|
|
901813
|
+
const line2 = createEmptyLine(width);
|
|
901814
|
+
for (let col = 0;col < width; col++) {
|
|
901815
|
+
line2[col] = createStyledCell(" ", {
|
|
901816
|
+
fg: style.fg,
|
|
901817
|
+
bg: style.bg,
|
|
901818
|
+
bold: style.bold ?? false,
|
|
901819
|
+
dim: style.dim ?? false,
|
|
901820
|
+
underline: style.underline ?? false
|
|
901821
|
+
});
|
|
901822
|
+
}
|
|
901823
|
+
return line2;
|
|
901824
|
+
}
|
|
901825
|
+
function writeBottomBarText(line2, startX, maxWidth, text, style) {
|
|
901826
|
+
let x2 = startX;
|
|
901827
|
+
let used = 0;
|
|
901828
|
+
for (const ch of text) {
|
|
901829
|
+
const cellWidth = getDisplayWidth(ch);
|
|
901830
|
+
if (cellWidth <= 0)
|
|
901831
|
+
continue;
|
|
901832
|
+
if (used + cellWidth > maxWidth || x2 >= line2.length)
|
|
901833
|
+
break;
|
|
901834
|
+
line2[x2] = createStyledCell(ch, {
|
|
901835
|
+
fg: style.fg,
|
|
901836
|
+
bg: style.bg,
|
|
901837
|
+
bold: style.bold ?? false,
|
|
901838
|
+
dim: style.dim ?? false,
|
|
901839
|
+
underline: style.underline ?? false
|
|
901840
|
+
});
|
|
901841
|
+
if (cellWidth > 1 && x2 + 1 < line2.length) {
|
|
901842
|
+
line2[x2 + 1] = createStyledCell(" ", {
|
|
901843
|
+
fg: style.fg,
|
|
901844
|
+
bg: style.bg,
|
|
901845
|
+
bold: style.bold ?? false,
|
|
901846
|
+
dim: style.dim ?? false,
|
|
901847
|
+
underline: style.underline ?? false
|
|
901848
|
+
});
|
|
901849
|
+
}
|
|
901850
|
+
x2 += cellWidth;
|
|
901851
|
+
used += cellWidth;
|
|
901852
|
+
}
|
|
901853
|
+
}
|
|
901854
|
+
|
|
901855
|
+
// src/renderer/search-overlay.ts
|
|
901856
|
+
var SEARCH_OVERLAY_LABEL = " Find: ";
|
|
901857
|
+
var SEARCH_OVERLAY_NO_MATCHES = "No matches";
|
|
901858
|
+
var SEARCH_OVERLAY_COUNT_SUFFIX = "up/down";
|
|
901859
|
+
var SEARCH_OVERLAY_LOCKED_HINTS = " [Up/Down] or [jk] navigate [Bksp] edit [Esc] close";
|
|
901860
|
+
var SEARCH_OVERLAY_UNLOCKED_HINTS = " [Enter/Tab] lock [Esc] close";
|
|
901861
|
+
function searchOverlayMatchCount(current, total) {
|
|
901862
|
+
return `${current}/${total} ${SEARCH_OVERLAY_COUNT_SUFFIX}`;
|
|
901863
|
+
}
|
|
901864
|
+
function renderSearchOverlay(manager5, width) {
|
|
901865
|
+
const matchCount = manager5.matches?.length > 0 ? searchOverlayMatchCount(manager5.currentMatch + 1, manager5.matches.length) : manager5.query.length > 0 ? SEARCH_OVERLAY_NO_MATCHES : "";
|
|
901866
|
+
const locked = manager5.locked;
|
|
901867
|
+
const cursor = locked ? "" : "\u2588";
|
|
901868
|
+
const queryDisplay = manager5.query + cursor;
|
|
901869
|
+
const hints = locked ? SEARCH_OVERLAY_LOCKED_HINTS : SEARCH_OVERLAY_UNLOCKED_HINTS;
|
|
901870
|
+
const label = SEARCH_OVERLAY_LABEL;
|
|
901871
|
+
const matchStr = matchCount ? ` ${matchCount}` : "";
|
|
901872
|
+
const leftPart = label + queryDisplay;
|
|
901873
|
+
const hintsW = getDisplayWidth(hints);
|
|
901874
|
+
const matchStrW = getDisplayWidth(matchStr);
|
|
901875
|
+
const leftWidth = width - hintsW - matchStrW - 2;
|
|
901876
|
+
const truncatedLeft = fitDisplay(getDisplayWidth(leftPart) > leftWidth ? truncateDisplay(leftPart, leftWidth) : leftPart, leftWidth);
|
|
901877
|
+
const fullLine = truncatedLeft + matchStr + hints + " ";
|
|
901878
|
+
const line2 = createBottomBarLine(width, { fg: "#000000", bg: "#00ffcc" });
|
|
901879
|
+
writeBottomBarText(line2, 0, width, fitDisplay(truncateDisplay(fullLine, width), width), { fg: "#000000", bg: "#00ffcc" });
|
|
901880
|
+
if (matchStr.length > 0) {
|
|
901881
|
+
const matchStart = getDisplayWidth(truncatedLeft);
|
|
901882
|
+
writeBottomBarText(line2, matchStart, matchStrW, matchStr, { fg: "#888888", bg: "#00ffcc", dim: true });
|
|
901883
|
+
}
|
|
901884
|
+
return [line2];
|
|
901885
|
+
}
|
|
901886
|
+
|
|
901887
|
+
// src/renderer/history-search-overlay.ts
|
|
901888
|
+
var HISTORY_SEARCH_PREFIX = "(reverse-i-search)`";
|
|
901889
|
+
var HISTORY_SEARCH_FAILED_PREFIX = "(failed reverse-i-search)`";
|
|
901890
|
+
var HISTORY_SEARCH_QUERY_SUFFIX = "': ";
|
|
901891
|
+
function historySearchLabel(prefix, query2) {
|
|
901892
|
+
return prefix + query2 + HISTORY_SEARCH_QUERY_SUFFIX;
|
|
901893
|
+
}
|
|
901894
|
+
function truncateToWidth3(text, maxWidth) {
|
|
901895
|
+
let usedWidth = 0;
|
|
901896
|
+
let result2 = "";
|
|
901897
|
+
let i5 = 0;
|
|
901898
|
+
while (i5 < text.length) {
|
|
901899
|
+
const code2 = text.codePointAt(i5);
|
|
901900
|
+
const charLen = code2 > 65535 ? 2 : 1;
|
|
901901
|
+
const charWidth = getDisplayWidth(text.slice(i5, i5 + charLen));
|
|
901902
|
+
if (usedWidth + charWidth > maxWidth)
|
|
901903
|
+
break;
|
|
901904
|
+
result2 += text.slice(i5, i5 + charLen);
|
|
901905
|
+
usedWidth += charWidth;
|
|
901906
|
+
i5 += charLen;
|
|
901907
|
+
}
|
|
901908
|
+
return result2 + " ".repeat(maxWidth - usedWidth);
|
|
901909
|
+
}
|
|
901910
|
+
function renderHistorySearchOverlay(historySearch, width) {
|
|
901911
|
+
if (width <= 0)
|
|
901912
|
+
return [];
|
|
901913
|
+
const match = historySearch.currentMatch;
|
|
901914
|
+
const hasMatch = match !== null && historySearch.query.length > 0;
|
|
901915
|
+
const noMatch = historySearch.query.length > 0 && !hasMatch;
|
|
901916
|
+
const prefix = noMatch ? HISTORY_SEARCH_FAILED_PREFIX : HISTORY_SEARCH_PREFIX;
|
|
901917
|
+
const matchText = hasMatch ? match?.entry ?? "" : "";
|
|
901918
|
+
const label = historySearchLabel(prefix, historySearch.query);
|
|
901919
|
+
const full = truncateToWidth3(label + matchText, width);
|
|
901920
|
+
const line2 = createBottomBarLine(width, { fg: "#000000", bg: "#00ffcc" });
|
|
901921
|
+
writeBottomBarText(line2, 0, width, full, { fg: "#000000", bg: "#00ffcc" });
|
|
901922
|
+
if (hasMatch && match) {
|
|
901923
|
+
const labelW = getDisplayWidth(label);
|
|
901924
|
+
const matchStartCol = labelW + match.matchStart;
|
|
901925
|
+
const matchEndCol = matchStartCol + match.matchLength;
|
|
901926
|
+
const highlightWidth = Math.max(0, matchEndCol - matchStartCol);
|
|
901927
|
+
const matchedSlice = truncateToWidth3(match.entry.slice(match.matchStart, match.matchStart + match.matchLength), highlightWidth);
|
|
901928
|
+
writeBottomBarText(line2, matchStartCol, highlightWidth, matchedSlice, {
|
|
901929
|
+
fg: "#000000",
|
|
901930
|
+
bg: "#00ffcc",
|
|
901931
|
+
bold: true,
|
|
901932
|
+
underline: true
|
|
901933
|
+
});
|
|
901934
|
+
}
|
|
901935
|
+
return [line2];
|
|
901936
|
+
}
|
|
901937
|
+
|
|
901607
901938
|
// src/renderer/mcp-workspace.ts
|
|
901608
901939
|
var MCP_WORKSPACE_TITLE = "MCP Workspace / Servers";
|
|
901609
901940
|
var MCP_WORKSPACE_LEFT_HEADER = "Servers";
|
|
@@ -902813,17 +903144,23 @@ function buildLeftRows2(workspace, height) {
|
|
|
902813
903144
|
}
|
|
902814
903145
|
function actionCommand(action2) {
|
|
902815
903146
|
if (action2.kind === "workspace")
|
|
902816
|
-
return
|
|
903147
|
+
return "open area";
|
|
902817
903148
|
if (action2.kind === "editor")
|
|
902818
|
-
return action2.editorKind ? `edit ${action2.editorKind}` : "
|
|
903149
|
+
return action2.editorKind ? `edit ${action2.editorKind}` : "edit form";
|
|
902819
903150
|
if (action2.kind === "setting")
|
|
902820
|
-
return action2.settingKey ? `
|
|
903151
|
+
return action2.settingKey ? `setting ${action2.settingKey}` : "setting";
|
|
902821
903152
|
if (action2.kind === "settings-import")
|
|
902822
903153
|
return "import GoodVibes settings";
|
|
903154
|
+
if (action2.kind === "model-picker")
|
|
903155
|
+
return action2.modelPickerFlow === "model" ? "model picker" : "provider/model picker";
|
|
903156
|
+
if (action2.kind === "settings-modal")
|
|
903157
|
+
return action2.settingsTarget ? `settings ${action2.settingsTarget}` : "settings";
|
|
902823
903158
|
if (action2.kind === "local-selection")
|
|
902824
903159
|
return action2.selectionDelta && action2.selectionDelta < 0 ? "select previous" : "select next";
|
|
902825
903160
|
if (action2.kind === "local-operation")
|
|
902826
903161
|
return action2.localOperation ?? "(local action)";
|
|
903162
|
+
if (action2.kind === "onboarding-complete")
|
|
903163
|
+
return "apply and close";
|
|
902827
903164
|
return action2.command ?? "(guidance)";
|
|
902828
903165
|
}
|
|
902829
903166
|
function setupCounts(snapshot2) {
|
|
@@ -902837,6 +903174,11 @@ function setupCounts(snapshot2) {
|
|
|
902837
903174
|
function setupStatusLabel(status) {
|
|
902838
903175
|
return status === "ready" ? "Ready" : status === "recommended" ? "Recommended" : status === "blocked" ? "Blocked" : "Optional";
|
|
902839
903176
|
}
|
|
903177
|
+
function formatMegabytes(bytes) {
|
|
903178
|
+
if (!Number.isFinite(bytes) || bytes <= 0)
|
|
903179
|
+
return "0 MB";
|
|
903180
|
+
return `${Math.round(bytes / (1024 * 1024))} MB`;
|
|
903181
|
+
}
|
|
902840
903182
|
function compactText3(text, maxWidth = 104) {
|
|
902841
903183
|
const normalized3 = text.replace(/\s+/g, " ").trim();
|
|
902842
903184
|
if (normalized3.length === 0)
|
|
@@ -903007,6 +903349,27 @@ function snapshotLines(workspace, category, snapshot2) {
|
|
|
903007
903349
|
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
903350
|
} else if (category.id === "setup") {
|
|
903009
903351
|
base2.push(...setupOverviewLines(snapshot2));
|
|
903352
|
+
} else if (category.id === "account-model") {
|
|
903353
|
+
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 });
|
|
903354
|
+
} else if (category.id === "assistant-behavior") {
|
|
903355
|
+
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 });
|
|
903356
|
+
} else if (category.id === "tools-permissions") {
|
|
903357
|
+
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 });
|
|
903358
|
+
} else if (category.id === "onboarding-display") {
|
|
903359
|
+
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 });
|
|
903360
|
+
} else if (category.id === "onboarding-channels") {
|
|
903361
|
+
const enabledCount = snapshot2.channels.filter((channel) => channel.enabled).length;
|
|
903362
|
+
const readyCount = snapshot2.channels.filter((channel) => channel.ready).length;
|
|
903363
|
+
const needsConfig = snapshot2.channels.filter((channel) => channel.setupState === "needs-config");
|
|
903364
|
+
const needsTarget = snapshot2.channels.filter((channel) => channel.setupState === "needs-target");
|
|
903365
|
+
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 });
|
|
903366
|
+
} else if (category.id === "onboarding-voice-media") {
|
|
903367
|
+
const readiness = snapshot2.voiceMediaReadiness;
|
|
903368
|
+
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 });
|
|
903369
|
+
} else if (category.id === "onboarding-context") {
|
|
903370
|
+
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 });
|
|
903371
|
+
} else if (category.id === "onboarding-automation") {
|
|
903372
|
+
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
903373
|
} else if (category.id === "artifacts") {
|
|
903011
903374
|
const mediaReady = snapshot2.voiceMediaReadiness.readyMediaProviderCount;
|
|
903012
903375
|
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 +903626,20 @@ function normalizeFullscreenViewport(lines, width, height) {
|
|
|
903263
903626
|
viewport.push(createEmptyLine(width));
|
|
903264
903627
|
return viewport;
|
|
903265
903628
|
}
|
|
903266
|
-
function
|
|
903629
|
+
function createFullscreenCompositeFromLines(lines, width, height) {
|
|
903267
903630
|
return {
|
|
903268
903631
|
width,
|
|
903269
903632
|
height,
|
|
903270
903633
|
header: [],
|
|
903271
|
-
viewport: normalizeFullscreenViewport(
|
|
903634
|
+
viewport: normalizeFullscreenViewport(lines, width, height),
|
|
903272
903635
|
footer: [],
|
|
903273
903636
|
forceFullRedraw: true,
|
|
903274
903637
|
panelWidth: 0
|
|
903275
903638
|
};
|
|
903276
903639
|
}
|
|
903640
|
+
function createAgentWorkspaceFullscreenComposite(workspace, width, height) {
|
|
903641
|
+
return createFullscreenCompositeFromLines(renderAgentWorkspace(workspace, width, height), width, height);
|
|
903642
|
+
}
|
|
903277
903643
|
|
|
903278
903644
|
// src/shell/service-settings-sync.ts
|
|
903279
903645
|
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 +906148,14 @@ async function main() {
|
|
|
905782
906148
|
input.setPanelMouseLayout(null);
|
|
905783
906149
|
activeConversationWidth = width;
|
|
905784
906150
|
conversation.setSplashSuppressed(true);
|
|
906151
|
+
if (input.modelPicker.active) {
|
|
906152
|
+
compositor.composite(createFullscreenCompositeFromLines(renderModelWorkspace(input.modelPicker, width, height), width, height));
|
|
906153
|
+
return;
|
|
906154
|
+
}
|
|
906155
|
+
if (input.settingsModal.active) {
|
|
906156
|
+
compositor.composite(createFullscreenCompositeFromLines(renderSettingsModal(input.settingsModal, width, height), width, height));
|
|
906157
|
+
return;
|
|
906158
|
+
}
|
|
905785
906159
|
compositor.composite(createAgentWorkspaceFullscreenComposite(input.agentWorkspace, width, height));
|
|
905786
906160
|
return;
|
|
905787
906161
|
}
|