@pellux/goodvibes-agent 1.1.3 → 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 +13 -0
- package/dist/package/main.js +1780 -939
- package/package.json +1 -1
- package/src/input/agent-workspace-activation.ts +21 -1
- package/src/input/agent-workspace-basic-command-editors.ts +8 -9
- package/src/input/agent-workspace-categories.ts +263 -115
- package/src/input/agent-workspace-category-actions.ts +25 -0
- package/src/input/agent-workspace-host-category.ts +57 -0
- package/src/input/agent-workspace-local-editor-submission.ts +193 -0
- package/src/input/agent-workspace-search.ts +6 -0
- package/src/input/agent-workspace-settings.ts +314 -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 +56 -1
- package/src/input/agent-workspace.ts +139 -164
- 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 +80 -14
- package/src/shell/agent-workspace-fullscreen.ts +11 -3
- package/src/tools/agent-harness-ui-surface-metadata.ts +1 -1
- package/src/tools/agent-harness-workspace-actions.ts +2 -2
- 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) {
|
|
@@ -858616,6 +858558,14 @@ function registerWorkPlanRuntimeCommands(registry5) {
|
|
|
858616
858558
|
var AGENT_WORKSPACE_CATEGORY_IDS = [
|
|
858617
858559
|
"home",
|
|
858618
858560
|
"setup",
|
|
858561
|
+
"account-model",
|
|
858562
|
+
"assistant-behavior",
|
|
858563
|
+
"tools-permissions",
|
|
858564
|
+
"onboarding-display",
|
|
858565
|
+
"onboarding-channels",
|
|
858566
|
+
"onboarding-voice-media",
|
|
858567
|
+
"onboarding-context",
|
|
858568
|
+
"onboarding-automation",
|
|
858619
858569
|
"research",
|
|
858620
858570
|
"artifacts",
|
|
858621
858571
|
"conversation",
|
|
@@ -862050,6 +862000,7 @@ Use /channels list to see available channel ids.`);
|
|
|
862050
862000
|
}
|
|
862051
862001
|
|
|
862052
862002
|
// src/input/agent-workspace-snapshot.ts
|
|
862003
|
+
init_config8();
|
|
862053
862004
|
import { basename as basename6, sep as sep3 } from "path";
|
|
862054
862005
|
|
|
862055
862006
|
// src/agent/behavior-discovery-summary.ts
|
|
@@ -862257,6 +862208,13 @@ function buildAgentWorkspaceSetupChecklist(input) {
|
|
|
862257
862208
|
detail: providerReady ? `Current chat route is ${input.provider} / ${input.model}.` : "Choose a provider and model before relying on assistant turns.",
|
|
862258
862209
|
command: "Setup -> Provider and model"
|
|
862259
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
|
+
},
|
|
862260
862218
|
{
|
|
862261
862219
|
id: "agent-knowledge",
|
|
862262
862220
|
label: "Agent Knowledge",
|
|
@@ -862825,6 +862783,41 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
|
|
|
862825
862783
|
const ttsVoice = readConfigString3(context, "tts.voice", "(voice default)");
|
|
862826
862784
|
const ttsLlmProvider = readConfigString3(context, "tts.llmProvider", "");
|
|
862827
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);
|
|
862828
862821
|
const runtimeBaseUrl = `http://${host}:${port}`;
|
|
862829
862822
|
const companionAccess = (() => {
|
|
862830
862823
|
const homeDirectory = context.workspace?.shellPaths?.homeDirectory ?? "";
|
|
@@ -862846,6 +862839,18 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
|
|
|
862846
862839
|
nextStep
|
|
862847
862840
|
};
|
|
862848
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
|
+
})();
|
|
862849
862854
|
const channels = buildAgentWorkspaceChannels(context);
|
|
862850
862855
|
const voiceMediaReadiness = buildAgentWorkspaceVoiceMediaReadiness({
|
|
862851
862856
|
context,
|
|
@@ -862856,6 +862861,9 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
|
|
|
862856
862861
|
provider: provider5,
|
|
862857
862862
|
model,
|
|
862858
862863
|
runtimeBaseUrl,
|
|
862864
|
+
activeSubscriptionCount: subscriptionSnapshot.active,
|
|
862865
|
+
pendingSubscriptionCount: subscriptionSnapshot.pending,
|
|
862866
|
+
availableSubscriptionProviderCount: subscriptionSnapshot.available,
|
|
862859
862867
|
sessionMemoryCount,
|
|
862860
862868
|
localMemoryCount: memorySnapshot.count,
|
|
862861
862869
|
localMemoryReviewQueueCount: memorySnapshot.reviewQueueCount,
|
|
@@ -862883,11 +862891,49 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
|
|
|
862883
862891
|
provider: provider5,
|
|
862884
862892
|
model,
|
|
862885
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,
|
|
862886
862929
|
sessionId: context.session?.runtime?.sessionId ?? "unknown",
|
|
862887
862930
|
workingDirectory: context.workspace?.shellPaths?.workingDirectory ?? "unavailable",
|
|
862888
862931
|
homeDirectory: context.workspace?.shellPaths?.homeDirectory ?? "unavailable",
|
|
862889
862932
|
runtimeBaseUrl,
|
|
862890
862933
|
runtimeOwnership: "external",
|
|
862934
|
+
activeSubscriptionCount: subscriptionSnapshot.active,
|
|
862935
|
+
pendingSubscriptionCount: subscriptionSnapshot.pending,
|
|
862936
|
+
availableSubscriptionProviderCount: subscriptionSnapshot.available,
|
|
862891
862937
|
sessionMemoryCount,
|
|
862892
862938
|
localMemoryCount: memorySnapshot.count,
|
|
862893
862939
|
localMemoryReviewQueueCount: memorySnapshot.reviewQueueCount,
|
|
@@ -866591,7 +866637,7 @@ import { mkdirSync as mkdirSync66, readFileSync as readFileSync88, writeFileSync
|
|
|
866591
866637
|
import { dirname as dirname64, resolve as resolve39 } from "path";
|
|
866592
866638
|
init_state3();
|
|
866593
866639
|
var VALID_CLASSES2 = ["decision", "constraint", "incident", "pattern", "fact", "risk", "runbook", "architecture", "ownership"];
|
|
866594
|
-
var
|
|
866640
|
+
var VALID_SCOPES3 = ["session", "project", "team"];
|
|
866595
866641
|
var VALID_REVIEW_STATES3 = ["fresh", "reviewed", "stale", "contradicted"];
|
|
866596
866642
|
var VALID_PROVENANCE_KINDS = ["session", "turn", "task", "event", "file"];
|
|
866597
866643
|
var VALUE_OPTIONS = new Set([
|
|
@@ -866691,7 +866737,7 @@ function isMemoryClass2(value) {
|
|
|
866691
866737
|
return VALID_CLASSES2.includes(value);
|
|
866692
866738
|
}
|
|
866693
866739
|
function isMemoryScope2(value) {
|
|
866694
|
-
return
|
|
866740
|
+
return VALID_SCOPES3.includes(value);
|
|
866695
866741
|
}
|
|
866696
866742
|
function isReviewState(value) {
|
|
866697
866743
|
return VALID_REVIEW_STATES3.includes(value);
|
|
@@ -866706,7 +866752,7 @@ function requireClass(value) {
|
|
|
866706
866752
|
}
|
|
866707
866753
|
function requireScope(value) {
|
|
866708
866754
|
if (!value || !isMemoryScope2(value))
|
|
866709
|
-
throw new Error(`Invalid memory scope "${value ?? ""}". Valid values ${
|
|
866755
|
+
throw new Error(`Invalid memory scope "${value ?? ""}". Valid values ${VALID_SCOPES3.join(", ")}`);
|
|
866710
866756
|
return value;
|
|
866711
866757
|
}
|
|
866712
866758
|
function optionalScope(value) {
|
|
@@ -881478,7 +881524,7 @@ function createAgentWorkspaceBasicCommandEditor(kind2) {
|
|
|
881478
881524
|
selectedFieldIndex: 0,
|
|
881479
881525
|
message: "Inspect one provider subscription route without starting login or printing token values.",
|
|
881480
881526
|
fields: [
|
|
881481
|
-
{ 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." }
|
|
881482
881528
|
]
|
|
881483
881529
|
};
|
|
881484
881530
|
}
|
|
@@ -881488,12 +881534,11 @@ function createAgentWorkspaceBasicCommandEditor(kind2) {
|
|
|
881488
881534
|
mode: "create",
|
|
881489
881535
|
title: "Start Provider Subscription Login",
|
|
881490
881536
|
selectedFieldIndex: 0,
|
|
881491
|
-
message: "Begin one provider subscription OAuth login
|
|
881537
|
+
message: "Begin one provider subscription OAuth login, save the pending session, and return here for completion.",
|
|
881492
881538
|
fields: [
|
|
881493
|
-
{ 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." },
|
|
881494
881540
|
{ id: "openBrowser", label: "Open browser", value: "yes", required: false, multiline: false, hint: "yes/no. Use no to print the authorization URL only." },
|
|
881495
|
-
{ id: "
|
|
881496
|
-
{ 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." }
|
|
881497
881542
|
]
|
|
881498
881543
|
};
|
|
881499
881544
|
}
|
|
@@ -881503,11 +881548,11 @@ function createAgentWorkspaceBasicCommandEditor(kind2) {
|
|
|
881503
881548
|
mode: "update",
|
|
881504
881549
|
title: "Finish Provider Subscription Login",
|
|
881505
881550
|
selectedFieldIndex: 0,
|
|
881506
|
-
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.",
|
|
881507
881552
|
fields: [
|
|
881508
881553
|
{ id: "provider", label: "Provider", value: "openai", required: true, multiline: false, hint: "Provider id used when starting login." },
|
|
881509
881554
|
{ id: "code", label: "Code or redirect URL", value: "", required: true, multiline: false, hint: "OAuth code or full redirect URL containing code=..." },
|
|
881510
|
-
{ 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." }
|
|
881511
881556
|
]
|
|
881512
881557
|
};
|
|
881513
881558
|
}
|
|
@@ -881517,10 +881562,10 @@ function createAgentWorkspaceBasicCommandEditor(kind2) {
|
|
|
881517
881562
|
mode: "delete",
|
|
881518
881563
|
title: "Logout Provider Subscription",
|
|
881519
881564
|
selectedFieldIndex: 0,
|
|
881520
|
-
message: "Remove one
|
|
881565
|
+
message: "Remove one active or pending provider subscription session. Ambient API key resolution applies again if configured.",
|
|
881521
881566
|
fields: [
|
|
881522
881567
|
{ id: "provider", label: "Provider", value: "openai", required: true, multiline: false, hint: "Stored subscription provider id." },
|
|
881523
|
-
{ 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." }
|
|
881524
881569
|
]
|
|
881525
881570
|
};
|
|
881526
881571
|
}
|
|
@@ -889824,7 +889869,7 @@ var UI_SURFACES = [
|
|
|
889824
889869
|
kind: "picker",
|
|
889825
889870
|
summary: "Reasoning-effort selector for models that expose effort levels.",
|
|
889826
889871
|
command: "/effort",
|
|
889827
|
-
preferredModelRoute: `Use ${agentHarnessModes2("settings", "get_setting", "set_setting")} for provider.reasoningEffort when a concrete level is known, or mode:"run_workspace_action" setup-effort with confirmation.`,
|
|
889872
|
+
preferredModelRoute: `Use ${agentHarnessModes2("settings", "get_setting", "set_setting")} for provider.reasoningEffort when a concrete level is known, or mode:"run_workspace_action" setup-reasoning-effort with confirmation.`,
|
|
889828
889873
|
available: (context) => typeof context.openReasoningEffortPicker === "function",
|
|
889829
889874
|
open: (context) => {
|
|
889830
889875
|
const surface = findSurfaceById("reasoning-effort-picker");
|
|
@@ -890296,6 +890341,22 @@ function activateAgentWorkspaceSelection(workspace, requestRender) {
|
|
|
890296
890341
|
const action2 = workspace.selectedAction;
|
|
890297
890342
|
if (!action2)
|
|
890298
890343
|
return;
|
|
890344
|
+
if (action2.kind === "setting") {
|
|
890345
|
+
workspace.applySettingAction(action2, requestRender);
|
|
890346
|
+
return;
|
|
890347
|
+
}
|
|
890348
|
+
if (action2.kind === "settings-import") {
|
|
890349
|
+
workspace.importTuiSettings(requestRender);
|
|
890350
|
+
return;
|
|
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
|
+
}
|
|
890299
890360
|
if (action2.kind === "editor" && action2.editorKind) {
|
|
890300
890361
|
const editor = createAgentWorkspaceEditor(action2.editorKind, {
|
|
890301
890362
|
runtimeStarterTemplates: workspace.runtimeSnapshot?.runtimeStarterTemplates ?? [],
|
|
@@ -890385,7 +890446,7 @@ function activateAgentWorkspaceSelection(workspace, requestRender) {
|
|
|
890385
890446
|
workspace.lastActionResult = {
|
|
890386
890447
|
kind: "dispatched",
|
|
890387
890448
|
title: `Opening ${action2.label}`,
|
|
890388
|
-
detail: "The workspace handed this
|
|
890449
|
+
detail: "The workspace handed this command to the shell-owned command router.",
|
|
890389
890450
|
command: action2.command,
|
|
890390
890451
|
safety: action2.safety
|
|
890391
890452
|
};
|
|
@@ -890450,6 +890511,78 @@ function handleGuidanceOrWorkspaceAction(workspace, action2) {
|
|
|
890450
890511
|
};
|
|
890451
890512
|
}
|
|
890452
890513
|
|
|
890514
|
+
// src/input/agent-workspace-category-actions.ts
|
|
890515
|
+
function settingAction(options) {
|
|
890516
|
+
return {
|
|
890517
|
+
id: options.id,
|
|
890518
|
+
label: options.label,
|
|
890519
|
+
detail: options.detail,
|
|
890520
|
+
kind: "setting",
|
|
890521
|
+
safety: "safe",
|
|
890522
|
+
settingKey: options.key,
|
|
890523
|
+
...options.value !== undefined ? { settingValueHint: options.value } : {},
|
|
890524
|
+
...options.visibleWhenKey !== undefined ? { visibleWhenSettingKey: options.visibleWhenKey } : {},
|
|
890525
|
+
...options.visibleWhenValue !== undefined ? { visibleWhenSettingValue: options.visibleWhenValue } : {}
|
|
890526
|
+
};
|
|
890527
|
+
}
|
|
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
|
+
|
|
890453
890586
|
// src/input/agent-workspace-categories.ts
|
|
890454
890587
|
var AGENT_WORKSPACE_CATEGORIES = [
|
|
890455
890588
|
{
|
|
@@ -890462,7 +890595,8 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890462
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" },
|
|
890463
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" },
|
|
890464
890597
|
{ id: "model", label: "Choose model", detail: "Open the model/provider workspace for the Agent chat route.", command: "/model", kind: "command", safety: "safe" },
|
|
890465
|
-
{ id: "
|
|
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" },
|
|
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" },
|
|
890466
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" },
|
|
890467
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" },
|
|
890468
890602
|
{ id: "mode-preset", label: "Set interaction mode", detail: "Open a confirmed form for quiet, balanced, or operator interaction mode.", editorKind: "mode-preset", kind: "editor", safety: "safe" },
|
|
@@ -890486,61 +890620,249 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890486
890620
|
},
|
|
890487
890621
|
{
|
|
890488
890622
|
id: "setup",
|
|
890489
|
-
group: "
|
|
890490
|
-
label: "
|
|
890491
|
-
summary: "
|
|
890492
|
-
detail: "
|
|
890623
|
+
group: "ONBOARDING",
|
|
890624
|
+
label: "Start",
|
|
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.",
|
|
890627
|
+
actions: [
|
|
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" },
|
|
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" },
|
|
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" })
|
|
890638
|
+
]
|
|
890639
|
+
},
|
|
890640
|
+
{
|
|
890641
|
+
id: "account-model",
|
|
890642
|
+
group: "ONBOARDING",
|
|
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.",
|
|
890646
|
+
actions: [
|
|
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" }),
|
|
890652
|
+
settingAction({ id: "account-system-prompt", label: "System prompt file", detail: "Set an optional local system prompt file path.", key: "provider.systemPromptFile" }),
|
|
890653
|
+
settingAction({ id: "account-helper-enabled", label: "Enable helper model", detail: "Toggle dedicated helper routing for background utility work.", key: "helper.enabled" }),
|
|
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" },
|
|
890656
|
+
settingAction({ id: "account-tool-llm-enabled", label: "Enable tool LLM", detail: "Toggle a dedicated tool LLM for internal operations.", key: "tools.llmEnabled" }),
|
|
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 })
|
|
890666
|
+
]
|
|
890667
|
+
},
|
|
890668
|
+
{
|
|
890669
|
+
id: "assistant-behavior",
|
|
890670
|
+
group: "ONBOARDING",
|
|
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.",
|
|
890674
|
+
actions: [
|
|
890675
|
+
settingAction({ id: "behavior-hitl-mode", label: "Interaction mode", detail: "Cycle quiet, balanced, or operator interaction mode.", key: "behavior.hitlMode" }),
|
|
890676
|
+
settingAction({ id: "behavior-guidance-mode", label: "Guidance mode", detail: "Cycle off, minimal, or guided operational guidance.", key: "behavior.guidanceMode" }),
|
|
890677
|
+
settingAction({ id: "behavior-auto-compact", label: "Auto-compact threshold", detail: "Set the context percentage that triggers automatic compaction.", key: "behavior.autoCompactThreshold" }),
|
|
890678
|
+
settingAction({ id: "behavior-stale-context", label: "Context warnings", detail: "Toggle proactive warnings before compaction is required.", key: "behavior.staleContextWarnings" }),
|
|
890679
|
+
settingAction({ id: "behavior-notify-complete", label: "Notify on long turns", detail: "Toggle terminal and desktop notification when a long turn completes.", key: "behavior.notifyOnComplete" }),
|
|
890680
|
+
settingAction({ id: "behavior-return-context", label: "Resume summary mode", detail: "Cycle off, local, or assisted resume summaries.", key: "behavior.returnContextMode" }),
|
|
890681
|
+
settingAction({ id: "behavior-show-thinking", label: "Show thinking blocks", detail: "Toggle visible reasoning/thinking content when the provider returns it.", key: "display.showThinking" }),
|
|
890682
|
+
settingAction({ id: "behavior-show-reasoning-summary", label: "Show reasoning summary", detail: "Toggle visible reasoning summaries when supported.", key: "display.showReasoningSummary" })
|
|
890683
|
+
]
|
|
890684
|
+
},
|
|
890685
|
+
{
|
|
890686
|
+
id: "tools-permissions",
|
|
890687
|
+
group: "ONBOARDING",
|
|
890688
|
+
label: "Tools & Permissions",
|
|
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.",
|
|
890691
|
+
actions: [
|
|
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" }),
|
|
890696
|
+
settingAction({ id: "permissions-write", label: "File writes", detail: "Cycle allow, prompt, or deny for file write operations.", key: "permissions.tools.write" }),
|
|
890697
|
+
settingAction({ id: "permissions-edit", label: "File edits", detail: "Cycle allow, prompt, or deny for edit and patch operations.", key: "permissions.tools.edit" }),
|
|
890698
|
+
settingAction({ id: "permissions-exec", label: "Shell commands", detail: "Cycle allow, prompt, or deny for shell execution.", key: "permissions.tools.exec" }),
|
|
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" }),
|
|
890704
|
+
settingAction({ id: "permissions-mcp", label: "MCP tools", detail: "Cycle allow, prompt, or deny for external MCP tool calls.", key: "permissions.tools.mcp" }),
|
|
890705
|
+
settingAction({ id: "permissions-agent", label: "Agent delegation", detail: "Cycle allow, prompt, or deny for subagent and delegation operations.", key: "permissions.tools.agent" }),
|
|
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" }),
|
|
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" },
|
|
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" },
|
|
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" })
|
|
890716
|
+
]
|
|
890717
|
+
},
|
|
890718
|
+
{
|
|
890719
|
+
id: "onboarding-display",
|
|
890720
|
+
group: "ONBOARDING",
|
|
890721
|
+
label: "Interface",
|
|
890722
|
+
summary: "Display, streaming, message placement, and release channel.",
|
|
890723
|
+
detail: "Use this page to make the terminal readable for daily operation.",
|
|
890724
|
+
actions: [
|
|
890725
|
+
settingAction({ id: "display-stream", label: "Stream tokens", detail: "Toggle streaming assistant tokens as they arrive.", key: "display.stream" }),
|
|
890726
|
+
settingAction({ id: "display-theme", label: "Theme", detail: "Set the color theme name.", key: "display.theme" }),
|
|
890727
|
+
settingAction({ id: "display-line-numbers", label: "Line numbers", detail: "Cycle all, code-only, or off for assistant output line numbers.", key: "display.lineNumbers" }),
|
|
890728
|
+
settingAction({ id: "display-collapse-threshold", label: "Collapse threshold", detail: "Set the line count threshold for collapsed tool output.", key: "display.collapseThreshold" }),
|
|
890729
|
+
settingAction({ id: "display-token-speed", label: "Token speed counter", detail: "Toggle tokens-per-second while generating.", key: "display.showTokenSpeed" }),
|
|
890730
|
+
settingAction({ id: "display-tool-preview", label: "Tool call preview", detail: "Toggle partial tool-call preview while streaming.", key: "display.showToolPreview" }),
|
|
890731
|
+
settingAction({ id: "display-operational-messages", label: "Operational messages", detail: "Cycle panel, conversation, or both for tool and runtime messages.", key: "ui.operationalMessages" }),
|
|
890732
|
+
settingAction({ id: "display-system-messages", label: "System messages", detail: "Cycle panel, conversation, or both for system messages.", key: "ui.systemMessages" }),
|
|
890733
|
+
settingAction({ id: "display-release-channel", label: "Release channel", detail: "Cycle stable or preview for update flows.", key: "release.channel" })
|
|
890734
|
+
]
|
|
890735
|
+
},
|
|
890736
|
+
{
|
|
890737
|
+
id: "onboarding-channels",
|
|
890738
|
+
group: "ONBOARDING",
|
|
890739
|
+
label: "Messaging",
|
|
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.",
|
|
890742
|
+
actions: [
|
|
890743
|
+
settingAction({ id: "channel-ntfy-enabled", label: "Use ntfy", detail: "Toggle ntfy notifications and chat routing.", key: "surfaces.ntfy.enabled" }),
|
|
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 }),
|
|
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 }),
|
|
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 }),
|
|
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 }),
|
|
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 }),
|
|
890751
|
+
settingAction({ id: "channel-slack-enabled", label: "Use Slack", detail: "Toggle Slack adapter configuration.", key: "surfaces.slack.enabled" }),
|
|
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 }),
|
|
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 }),
|
|
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 }),
|
|
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 }),
|
|
890757
|
+
settingAction({ id: "channel-discord-enabled", label: "Use Discord", detail: "Toggle Discord adapter configuration.", key: "surfaces.discord.enabled" }),
|
|
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 }),
|
|
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 }),
|
|
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 }),
|
|
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 }),
|
|
890763
|
+
settingAction({ id: "channel-webhook-enabled", label: "Use webhooks", detail: "Toggle generic webhook delivery.", key: "surfaces.webhook.enabled" }),
|
|
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 }),
|
|
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 }),
|
|
890767
|
+
settingAction({ id: "channel-telegram-enabled", label: "Use Telegram", detail: "Toggle Telegram bot delivery.", key: "surfaces.telegram.enabled" }),
|
|
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 }),
|
|
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 }),
|
|
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 }),
|
|
890773
|
+
settingAction({ id: "channel-googlechat-enabled", label: "Use Google Chat", detail: "Toggle Google Chat delivery.", key: "surfaces.googleChat.enabled" }),
|
|
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 }),
|
|
890778
|
+
settingAction({ id: "channel-homeassistant-enabled", label: "Use home automation", detail: "Toggle home automation conversation and event delivery.", key: "surfaces.homeassistant.enabled" }),
|
|
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 }),
|
|
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 }),
|
|
890787
|
+
settingAction({ id: "channel-signal-enabled", label: "Use Signal", detail: "Toggle Signal bridge delivery.", key: "surfaces.signal.enabled" }),
|
|
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 }),
|
|
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 }),
|
|
890792
|
+
settingAction({ id: "channel-whatsapp-enabled", label: "Use WhatsApp", detail: "Toggle WhatsApp delivery.", key: "surfaces.whatsapp.enabled" }),
|
|
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 }),
|
|
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 }),
|
|
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 }),
|
|
890800
|
+
settingAction({ id: "channel-imessage-enabled", label: "Use iMessage", detail: "Toggle iMessage bridge delivery.", key: "surfaces.imessage.enabled" }),
|
|
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 }),
|
|
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 })
|
|
890805
|
+
]
|
|
890806
|
+
},
|
|
890807
|
+
{
|
|
890808
|
+
id: "onboarding-voice-media",
|
|
890809
|
+
group: "ONBOARDING",
|
|
890810
|
+
label: "Voice & Phone",
|
|
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.",
|
|
890493
890813
|
actions: [
|
|
890494
|
-
{ id: "
|
|
890495
|
-
{ id: "
|
|
890496
|
-
{ id: "
|
|
890497
|
-
{ id: "
|
|
890498
|
-
{ id: "
|
|
890499
|
-
{ id: "
|
|
890500
|
-
{ id: "
|
|
890501
|
-
{ id: "
|
|
890502
|
-
{ id: "
|
|
890503
|
-
{ id: "
|
|
890504
|
-
{ id: "
|
|
890505
|
-
{ id: "
|
|
890506
|
-
{ id: "
|
|
890507
|
-
{ id: "
|
|
890508
|
-
|
|
890509
|
-
|
|
890510
|
-
|
|
890511
|
-
|
|
890512
|
-
|
|
890513
|
-
|
|
890514
|
-
|
|
890515
|
-
|
|
890516
|
-
|
|
890517
|
-
{ id: "
|
|
890518
|
-
{ id: "
|
|
890519
|
-
{ id: "
|
|
890520
|
-
{ id: "
|
|
890521
|
-
{ id: "
|
|
890522
|
-
{ id: "
|
|
890523
|
-
{ id: "
|
|
890524
|
-
{ id: "
|
|
890525
|
-
{ id: "
|
|
890526
|
-
{ id: "
|
|
890527
|
-
{ id: "
|
|
890528
|
-
{ id: "
|
|
890529
|
-
{ id: "
|
|
890530
|
-
|
|
890531
|
-
|
|
890532
|
-
|
|
890533
|
-
|
|
890534
|
-
|
|
890535
|
-
|
|
890536
|
-
|
|
890537
|
-
|
|
890538
|
-
|
|
890539
|
-
{ id: "
|
|
890540
|
-
{ id: "
|
|
890541
|
-
{ id: "
|
|
890542
|
-
{ id: "
|
|
890543
|
-
{ id: "
|
|
890814
|
+
settingAction({ id: "voice-enabled", label: "Use voice controls", detail: "Toggle the optional local voice control surface.", key: "ui.voiceEnabled" }),
|
|
890815
|
+
settingAction({ id: "voice-tts-provider", label: "TTS provider", detail: "Set the default text-to-speech provider id.", key: "tts.provider" }),
|
|
890816
|
+
settingAction({ id: "voice-tts-voice", label: "TTS voice", detail: "Set the default text-to-speech voice id.", key: "tts.voice" }),
|
|
890817
|
+
settingAction({ id: "telephony-enabled", label: "Use telephony", detail: "Toggle SMS, voice call, or telephony bridge delivery.", key: "surfaces.telephony.enabled" }),
|
|
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 }),
|
|
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 }),
|
|
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 }),
|
|
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 }),
|
|
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 }),
|
|
890825
|
+
settingAction({ id: "telephony-recipient", label: "Recipient phone number", detail: "Set the default telephony recipient number.", key: "surfaces.telephony.defaultRecipient", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true }),
|
|
890826
|
+
settingAction({ id: "telephony-webhook-secret", label: "Telephony webhook secret", detail: "Store the shared telephony webhook secret or secret reference.", key: "surfaces.telephony.webhookSecret", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true }),
|
|
890827
|
+
settingAction({ id: "telephony-voice-language", label: "Voice language", detail: "Set the BCP-47 language code for voice-call text-to-speech.", key: "surfaces.telephony.voiceLanguage", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true })
|
|
890828
|
+
]
|
|
890829
|
+
},
|
|
890830
|
+
{
|
|
890831
|
+
id: "onboarding-context",
|
|
890832
|
+
group: "ONBOARDING",
|
|
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.",
|
|
890836
|
+
actions: [
|
|
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" },
|
|
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" },
|
|
890839
|
+
{ id: "context-skill-discovery", label: "Import skill files", detail: "Import discovered skill files into the Agent skill registry.", editorKind: "skill-discovery-import", kind: "editor", safety: "safe" },
|
|
890840
|
+
{ id: "context-routine-discovery", label: "Import routine files", detail: "Import discovered routine files into the Agent routine registry.", editorKind: "routine-discovery-import", kind: "editor", safety: "safe" },
|
|
890841
|
+
{ id: "context-create-persona", label: "Create persona", detail: "Create and optionally activate an Agent-local persona.", editorKind: "persona", kind: "editor", safety: "safe" },
|
|
890842
|
+
{ id: "context-create-memory", label: "Create starter memory", detail: "Create one durable local memory record.", editorKind: "memory", kind: "editor", safety: "safe" },
|
|
890843
|
+
{ id: "context-create-skill", label: "Create skill", detail: "Create one reusable Agent-local skill.", editorKind: "skill", kind: "editor", safety: "safe" },
|
|
890844
|
+
{ id: "context-create-routine", label: "Create routine", detail: "Create one reusable Agent-local routine.", editorKind: "routine", kind: "editor", safety: "safe" },
|
|
890845
|
+
{ id: "context-create-note", label: "Create note", detail: "Create one Agent-local scratchpad note.", editorKind: "note", kind: "editor", safety: "safe" },
|
|
890846
|
+
{ id: "context-knowledge-url", label: "Ingest URL", detail: "Ingest a reviewed URL into isolated Agent Knowledge after confirmation.", editorKind: "knowledge-url", kind: "editor", safety: "safe" },
|
|
890847
|
+
{ id: "context-knowledge-file", label: "Ingest file", detail: "Ingest a local file into isolated Agent Knowledge after confirmation.", editorKind: "knowledge-file", kind: "editor", safety: "safe" },
|
|
890848
|
+
{ id: "context-knowledge-bookmarks", label: "Import bookmarks", detail: "Import a browser bookmark export into isolated Agent Knowledge.", editorKind: "knowledge-bookmarks", kind: "editor", safety: "safe" },
|
|
890849
|
+
{ id: "context-knowledge-browser-history", label: "Import browser history", detail: "Import local browser history or bookmarks into isolated Agent Knowledge.", editorKind: "knowledge-browser-history", kind: "editor", safety: "safe" }
|
|
890850
|
+
]
|
|
890851
|
+
},
|
|
890852
|
+
{
|
|
890853
|
+
id: "onboarding-automation",
|
|
890854
|
+
group: "ONBOARDING",
|
|
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.",
|
|
890858
|
+
actions: [
|
|
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 })
|
|
890544
890866
|
]
|
|
890545
890867
|
},
|
|
890546
890868
|
{
|
|
@@ -890976,50 +891298,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
890976
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" }
|
|
890977
891299
|
]
|
|
890978
891300
|
},
|
|
890979
|
-
|
|
890980
|
-
id: "host",
|
|
890981
|
-
group: "OPERATIONS",
|
|
890982
|
-
label: "Connected Host",
|
|
890983
|
-
summary: "Connected-host health, tasks, sessions, channels, and automation.",
|
|
890984
|
-
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.",
|
|
890985
|
-
actions: [
|
|
890986
|
-
{ 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" },
|
|
890987
|
-
{ 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" },
|
|
890988
|
-
{ 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" },
|
|
890989
|
-
{ 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" },
|
|
890990
|
-
{ id: "host-maintenance", label: "Session maintenance", detail: "Review continuity, compaction, and current-session maintenance posture.", command: "/health maintenance", kind: "command", safety: "read-only" },
|
|
890991
|
-
{ 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" },
|
|
890992
|
-
{ 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" },
|
|
890993
|
-
{ 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" },
|
|
890994
|
-
{ 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" },
|
|
890995
|
-
{ 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" },
|
|
890996
|
-
{ 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" },
|
|
890997
|
-
{ 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" },
|
|
890998
|
-
{ 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" },
|
|
890999
|
-
{ 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" },
|
|
891000
|
-
{ id: "host-channel-policies", label: "Channel policies", detail: "Inspect channel delivery policy posture without changing routing.", command: "/channels policies", kind: "command", safety: "read-only" },
|
|
891001
|
-
{ id: "host-channels", label: "Open Channels", detail: "Jump to the channel setup and delivery workspace.", targetCategoryId: "channels", kind: "workspace", safety: "safe" },
|
|
891002
|
-
{ id: "host-automation", label: "Open Automation", detail: "Jump to connected schedules, reminders, receipts, and explicit run controls.", targetCategoryId: "automation", kind: "workspace", safety: "safe" },
|
|
891003
|
-
{ 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" },
|
|
891004
|
-
{ id: "host-schedule-reconcile", label: "Reconcile schedules", detail: "Compare local promotion receipts with live connected schedules.", command: "/schedule reconcile", kind: "command", safety: "read-only" },
|
|
891005
|
-
{ id: "host-knowledge", label: "Knowledge route", detail: "Inspect isolated Agent Knowledge route readiness and source counts.", command: "/knowledge status", kind: "command", safety: "read-only" },
|
|
891006
|
-
{ id: "host-knowledge-open", label: "Open Knowledge", detail: "Jump to Agent Knowledge source, graph, review, and ingest controls.", targetCategoryId: "knowledge", kind: "workspace", safety: "safe" },
|
|
891007
|
-
{ id: "host-media", label: "Media providers", detail: "Inspect configured media providers before generating media with confirmation.", command: "/media providers", kind: "command", safety: "read-only" },
|
|
891008
|
-
{ 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" },
|
|
891009
|
-
{ 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" },
|
|
891010
|
-
{ 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" },
|
|
891011
|
-
{ 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" },
|
|
891012
|
-
{ 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" },
|
|
891013
|
-
{ 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" },
|
|
891014
|
-
{ 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" },
|
|
891015
|
-
{ 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" },
|
|
891016
|
-
{ 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" },
|
|
891017
|
-
{ id: "host-support-bundle", label: "Support bundle", detail: "Open support bundle export, inspect, and import actions for host-facing setup review.", targetCategoryId: "setup", kind: "workspace", safety: "safe" },
|
|
891018
|
-
{ 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" },
|
|
891019
|
-
{ 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" },
|
|
891020
|
-
{ 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" }
|
|
891021
|
-
]
|
|
891022
|
-
},
|
|
891301
|
+
AGENT_WORKSPACE_HOST_CATEGORY,
|
|
891023
891302
|
{
|
|
891024
891303
|
id: "automation",
|
|
891025
891304
|
group: "OPERATIONS",
|
|
@@ -891066,9 +891345,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
891066
891345
|
label: "Finish",
|
|
891067
891346
|
summary: "Acknowledge setup and close onboarding.",
|
|
891068
891347
|
detail: "Use this final step after reviewing setup. Apply & close writes the user onboarding completion marker so normal future launches start in the main conversation.",
|
|
891069
|
-
actions: [
|
|
891070
|
-
{ id: "onboarding-apply-close", label: "Apply & close", detail: "Acknowledge onboarding as finished, persist the user completion marker, and close the fullscreen Agent workspace.", kind: "onboarding-complete", safety: "safe" }
|
|
891071
|
-
]
|
|
891348
|
+
actions: [{ id: "onboarding-apply-close", label: "Apply & close", detail: "Acknowledge onboarding as finished, persist the user completion marker, and close the fullscreen Agent workspace.", kind: "onboarding-complete", safety: "safe" }]
|
|
891072
891349
|
}
|
|
891073
891350
|
];
|
|
891074
891351
|
|
|
@@ -891092,6 +891369,9 @@ function searchAgentWorkspaceActions(categories, query2) {
|
|
|
891092
891369
|
action2.command ?? "",
|
|
891093
891370
|
action2.editorKind ?? "",
|
|
891094
891371
|
action2.targetCategoryId ?? "",
|
|
891372
|
+
action2.modelPickerFlow ?? "",
|
|
891373
|
+
action2.modelPickerTarget ?? "",
|
|
891374
|
+
action2.settingsTarget ?? "",
|
|
891095
891375
|
action2.localOperation ?? "",
|
|
891096
891376
|
action2.safety
|
|
891097
891377
|
].join(" ").toLowerCase();
|
|
@@ -891122,6 +891402,9 @@ function scoreActionSearchResult(result2, exactQuery, terms) {
|
|
|
891122
891402
|
score += scoreField(action2.editorKind, terms, exactQuery, 85, 26);
|
|
891123
891403
|
score += scoreField(action2.command, terms, exactQuery, 75, 22);
|
|
891124
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);
|
|
891125
891408
|
score += scoreField(action2.localOperation, terms, exactQuery, 50, 16);
|
|
891126
891409
|
score += scoreField(action2.targetCategoryId, terms, exactQuery, 40, 12);
|
|
891127
891410
|
score += scoreField(action2.detail, terms, exactQuery, 24, 6);
|
|
@@ -891280,7 +891563,7 @@ function readLimit26(value, fallback) {
|
|
|
891280
891563
|
const parsed = typeof value === "string" && value.trim() ? Number(value) : value;
|
|
891281
891564
|
if (typeof parsed !== "number" || !Number.isFinite(parsed))
|
|
891282
891565
|
return fallback;
|
|
891283
|
-
return Math.max(1, Math.min(
|
|
891566
|
+
return Math.max(1, Math.min(1000, Math.trunc(parsed)));
|
|
891284
891567
|
}
|
|
891285
891568
|
function readFieldMap3(value) {
|
|
891286
891569
|
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
@@ -891444,7 +891727,7 @@ function describeWorkspaceActionSummary(category, action2) {
|
|
|
891444
891727
|
function listWorkspaceActions(context, args2) {
|
|
891445
891728
|
const query2 = readString72(args2.query);
|
|
891446
891729
|
const categoryId = readString72(args2.categoryId || args2.category);
|
|
891447
|
-
const limit3 = readLimit26(args2.limit,
|
|
891730
|
+
const limit3 = readLimit26(args2.limit, 1000);
|
|
891448
891731
|
const includeEditor = args2.includeParameters === true;
|
|
891449
891732
|
const editorContext = includeEditor ? buildWorkspaceEditorContext(context, args2) : null;
|
|
891450
891733
|
const source = query2 ? searchAgentWorkspaceActions(AGENT_WORKSPACE_CATEGORIES, query2).map((result2) => ({ category: result2.category, action: result2.action })) : allWorkspaceActions();
|
|
@@ -895227,6 +895510,163 @@ function handleMcpWorkspaceToken(workspace, token, handleEscape2, requestRender)
|
|
|
895227
895510
|
return true;
|
|
895228
895511
|
}
|
|
895229
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
|
+
|
|
895230
895670
|
// src/input/agent-workspace-local-selection.ts
|
|
895231
895671
|
function agentWorkspaceLocalLibraryItems(snapshot2, kind2) {
|
|
895232
895672
|
if (kind2 === "memory")
|
|
@@ -895587,12 +896027,412 @@ function selectAgentWorkspaceCategory(host, categoryIdOrLabel) {
|
|
|
895587
896027
|
return true;
|
|
895588
896028
|
}
|
|
895589
896029
|
|
|
895590
|
-
// src/input/agent-workspace-
|
|
895591
|
-
|
|
895592
|
-
|
|
895593
|
-
|
|
895594
|
-
|
|
895595
|
-
|
|
896030
|
+
// src/input/agent-workspace-settings.ts
|
|
896031
|
+
import { existsSync as existsSync87, readFileSync as readFileSync94 } from "fs";
|
|
896032
|
+
var GOODVIBES_TUI_SURFACE_ROOT = "tui";
|
|
896033
|
+
var TUI_IMPORTABLE_SETTING_PREFIXES = [
|
|
896034
|
+
"display.",
|
|
896035
|
+
"provider.",
|
|
896036
|
+
"behavior.",
|
|
896037
|
+
"storage.",
|
|
896038
|
+
"permissions.",
|
|
896039
|
+
"ui.",
|
|
896040
|
+
"tts.",
|
|
896041
|
+
"surfaces.",
|
|
896042
|
+
"helper.",
|
|
896043
|
+
"tools.",
|
|
896044
|
+
"release.",
|
|
896045
|
+
"automation."
|
|
896046
|
+
];
|
|
896047
|
+
function isRecord45(value) {
|
|
896048
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
896049
|
+
}
|
|
896050
|
+
function readJsonRecord(path7) {
|
|
896051
|
+
if (!existsSync87(path7))
|
|
896052
|
+
return null;
|
|
896053
|
+
const parsed = JSON.parse(readFileSync94(path7, "utf-8"));
|
|
896054
|
+
return isRecord45(parsed) ? parsed : null;
|
|
896055
|
+
}
|
|
896056
|
+
function readNestedSettingValue(record2, key) {
|
|
896057
|
+
let cursor = record2;
|
|
896058
|
+
for (const part of key.split(".")) {
|
|
896059
|
+
if (!isRecord45(cursor) || !(part in cursor))
|
|
896060
|
+
return;
|
|
896061
|
+
cursor = cursor[part];
|
|
896062
|
+
}
|
|
896063
|
+
return cursor;
|
|
896064
|
+
}
|
|
896065
|
+
function canImportTuiSetting(key) {
|
|
896066
|
+
return !isExternalHostOwnedSettingKey(key) && TUI_IMPORTABLE_SETTING_PREFIXES.some((prefix) => key.startsWith(prefix));
|
|
896067
|
+
}
|
|
896068
|
+
function valuesMatch(left, right) {
|
|
896069
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
896070
|
+
}
|
|
896071
|
+
function agentWorkspaceSettingSchema(context, key) {
|
|
896072
|
+
return context?.platform?.configManager?.getSchema().find((setting) => setting.key === key) ?? null;
|
|
896073
|
+
}
|
|
896074
|
+
function isAgentWorkspaceActionVisible(context, action2) {
|
|
896075
|
+
const key = action2.visibleWhenSettingKey?.trim();
|
|
896076
|
+
if (!key)
|
|
896077
|
+
return true;
|
|
896078
|
+
const configManager = context?.platform?.configManager;
|
|
896079
|
+
if (!configManager)
|
|
896080
|
+
return false;
|
|
896081
|
+
return configManager.get(key) === action2.visibleWhenSettingValue;
|
|
896082
|
+
}
|
|
896083
|
+
function buildAgentWorkspaceSettingActionEffect(context, action2) {
|
|
896084
|
+
const settingKey = action2.settingKey?.trim();
|
|
896085
|
+
const configManager = context?.platform?.configManager;
|
|
896086
|
+
if (!settingKey || !configManager) {
|
|
896087
|
+
return {
|
|
896088
|
+
kind: "result",
|
|
896089
|
+
status: "Setting is unavailable in this runtime.",
|
|
896090
|
+
result: {
|
|
896091
|
+
kind: "error",
|
|
896092
|
+
title: "Setting unavailable",
|
|
896093
|
+
detail: action2.detail,
|
|
896094
|
+
safety: action2.safety
|
|
896095
|
+
}
|
|
896096
|
+
};
|
|
896097
|
+
}
|
|
896098
|
+
const setting = agentWorkspaceSettingSchema(context, settingKey);
|
|
896099
|
+
if (!setting) {
|
|
896100
|
+
return {
|
|
896101
|
+
kind: "result",
|
|
896102
|
+
status: `Unknown setting: ${settingKey}`,
|
|
896103
|
+
result: {
|
|
896104
|
+
kind: "error",
|
|
896105
|
+
title: "Unknown setting",
|
|
896106
|
+
detail: `No Agent setting exists for ${settingKey}.`,
|
|
896107
|
+
safety: action2.safety
|
|
896108
|
+
}
|
|
896109
|
+
};
|
|
896110
|
+
}
|
|
896111
|
+
if (action2.settingValueHint !== undefined) {
|
|
896112
|
+
return { kind: "apply", setting, value: action2.settingValueHint };
|
|
896113
|
+
}
|
|
896114
|
+
const currentValue = configManager.get(setting.key);
|
|
896115
|
+
if (setting.type === "boolean") {
|
|
896116
|
+
return { kind: "apply", setting, value: !Boolean(currentValue) };
|
|
896117
|
+
}
|
|
896118
|
+
if (setting.type === "enum" && setting.enumValues && setting.enumValues.length > 0) {
|
|
896119
|
+
const currentIndex = Math.max(0, setting.enumValues.indexOf(String(currentValue)));
|
|
896120
|
+
return { kind: "apply", setting, value: setting.enumValues[(currentIndex + 1) % setting.enumValues.length] };
|
|
896121
|
+
}
|
|
896122
|
+
return {
|
|
896123
|
+
kind: "editor",
|
|
896124
|
+
editor: createSettingEditor(setting, String(currentValue ?? ""), action2),
|
|
896125
|
+
status: `Editing ${setting.key}.`,
|
|
896126
|
+
result: {
|
|
896127
|
+
kind: "guidance",
|
|
896128
|
+
title: `Edit ${setting.key}`,
|
|
896129
|
+
detail: setting.description,
|
|
896130
|
+
safety: action2.safety
|
|
896131
|
+
}
|
|
896132
|
+
};
|
|
896133
|
+
}
|
|
896134
|
+
async function applyAgentWorkspaceSettingValue(context, setting, value) {
|
|
896135
|
+
const configManager = context?.platform?.configManager;
|
|
896136
|
+
if (!configManager) {
|
|
896137
|
+
return {
|
|
896138
|
+
status: "Setting is unavailable in this runtime.",
|
|
896139
|
+
result: {
|
|
896140
|
+
kind: "error",
|
|
896141
|
+
title: `${setting.key} update failed`,
|
|
896142
|
+
detail: "The Agent workspace has no config manager for this runtime.",
|
|
896143
|
+
safety: "safe"
|
|
896144
|
+
}
|
|
896145
|
+
};
|
|
896146
|
+
}
|
|
896147
|
+
try {
|
|
896148
|
+
const result2 = await setHarnessSetting(configManager, context?.platform?.secretsManager, setting.key, value);
|
|
896149
|
+
return {
|
|
896150
|
+
status: `${result2.key} set.`,
|
|
896151
|
+
result: {
|
|
896152
|
+
kind: "refreshed",
|
|
896153
|
+
title: `${result2.key} updated`,
|
|
896154
|
+
detail: `Current value: ${String(result2.current)}`,
|
|
896155
|
+
safety: "safe"
|
|
896156
|
+
}
|
|
896157
|
+
};
|
|
896158
|
+
} catch (error53) {
|
|
896159
|
+
const detail = error53 instanceof Error ? error53.message : String(error53);
|
|
896160
|
+
return {
|
|
896161
|
+
status: detail,
|
|
896162
|
+
result: {
|
|
896163
|
+
kind: "error",
|
|
896164
|
+
title: `${setting.key} update failed`,
|
|
896165
|
+
detail,
|
|
896166
|
+
safety: "safe"
|
|
896167
|
+
}
|
|
896168
|
+
};
|
|
896169
|
+
}
|
|
896170
|
+
}
|
|
896171
|
+
async function importAgentWorkspaceTuiSettings(context) {
|
|
896172
|
+
const shellPaths3 = context?.workspace?.shellPaths;
|
|
896173
|
+
const configManager = context?.platform?.configManager;
|
|
896174
|
+
if (!shellPaths3 || !configManager) {
|
|
896175
|
+
return {
|
|
896176
|
+
status: "GoodVibes TUI settings import is unavailable in this runtime.",
|
|
896177
|
+
runtimeSnapshot: null,
|
|
896178
|
+
result: {
|
|
896179
|
+
kind: "error",
|
|
896180
|
+
title: "Import unavailable",
|
|
896181
|
+
detail: "The workspace cannot locate shell paths or the Agent config manager.",
|
|
896182
|
+
safety: "safe"
|
|
896183
|
+
}
|
|
896184
|
+
};
|
|
896185
|
+
}
|
|
896186
|
+
const sources = [
|
|
896187
|
+
{ label: "user", path: shellPaths3.resolveUserPath(GOODVIBES_TUI_SURFACE_ROOT, "settings.json") },
|
|
896188
|
+
{ label: "project", path: shellPaths3.resolveProjectPath(GOODVIBES_TUI_SURFACE_ROOT, "settings.json") }
|
|
896189
|
+
];
|
|
896190
|
+
const values2 = new Map;
|
|
896191
|
+
const parseErrors = [];
|
|
896192
|
+
for (const source of sources) {
|
|
896193
|
+
try {
|
|
896194
|
+
const record2 = readJsonRecord(source.path);
|
|
896195
|
+
if (!record2)
|
|
896196
|
+
continue;
|
|
896197
|
+
for (const setting of configManager.getSchema()) {
|
|
896198
|
+
if (!canImportTuiSetting(setting.key))
|
|
896199
|
+
continue;
|
|
896200
|
+
const value = readNestedSettingValue(record2, setting.key);
|
|
896201
|
+
if (value !== undefined)
|
|
896202
|
+
values2.set(setting.key, { value, source: source.label });
|
|
896203
|
+
}
|
|
896204
|
+
} catch (error53) {
|
|
896205
|
+
parseErrors.push(`${source.label}: ${error53 instanceof Error ? error53.message : String(error53)}`);
|
|
896206
|
+
}
|
|
896207
|
+
}
|
|
896208
|
+
if (values2.size === 0) {
|
|
896209
|
+
const detail = parseErrors.length > 0 ? `No importable settings found. ${parseErrors.join("; ")}` : "No GoodVibes TUI settings file with importable Agent-owned settings was found.";
|
|
896210
|
+
return {
|
|
896211
|
+
status: "No GoodVibes TUI settings imported.",
|
|
896212
|
+
runtimeSnapshot: null,
|
|
896213
|
+
result: {
|
|
896214
|
+
kind: parseErrors.length > 0 ? "error" : "guidance",
|
|
896215
|
+
title: "Nothing imported",
|
|
896216
|
+
detail,
|
|
896217
|
+
safety: "safe"
|
|
896218
|
+
}
|
|
896219
|
+
};
|
|
896220
|
+
}
|
|
896221
|
+
const imported = [];
|
|
896222
|
+
const unchanged = [];
|
|
896223
|
+
const skipped = [];
|
|
896224
|
+
for (const [key, entry] of values2) {
|
|
896225
|
+
const setting = agentWorkspaceSettingSchema(context, key);
|
|
896226
|
+
if (!setting)
|
|
896227
|
+
continue;
|
|
896228
|
+
if (valuesMatch(configManager.get(setting.key), entry.value)) {
|
|
896229
|
+
unchanged.push(setting.key);
|
|
896230
|
+
continue;
|
|
896231
|
+
}
|
|
896232
|
+
try {
|
|
896233
|
+
await setHarnessSetting(configManager, context?.platform?.secretsManager, setting.key, entry.value);
|
|
896234
|
+
imported.push(`${setting.key} (${entry.source})`);
|
|
896235
|
+
} catch (error53) {
|
|
896236
|
+
skipped.push(`${setting.key}: ${error53 instanceof Error ? error53.message : String(error53)}`);
|
|
896237
|
+
}
|
|
896238
|
+
}
|
|
896239
|
+
return {
|
|
896240
|
+
status: imported.length > 0 ? `Imported ${imported.length} GoodVibes TUI setting(s).` : "No GoodVibes TUI settings changed.",
|
|
896241
|
+
runtimeSnapshot: context ? buildAgentWorkspaceRuntimeSnapshot(context) : null,
|
|
896242
|
+
result: {
|
|
896243
|
+
kind: skipped.length > 0 && imported.length === 0 ? "error" : imported.length > 0 ? "refreshed" : "guidance",
|
|
896244
|
+
title: imported.length > 0 ? "GoodVibes TUI settings imported" : "No settings changed",
|
|
896245
|
+
detail: [
|
|
896246
|
+
imported.length > 0 ? `Imported: ${imported.slice(0, 10).join(", ")}${imported.length > 10 ? `, +${imported.length - 10} more` : ""}.` : "",
|
|
896247
|
+
unchanged.length > 0 ? `${unchanged.length} setting(s) already matched.` : "",
|
|
896248
|
+
skipped.length > 0 ? `Skipped: ${skipped.slice(0, 5).join("; ")}${skipped.length > 5 ? `; +${skipped.length - 5} more` : ""}.` : "",
|
|
896249
|
+
parseErrors.length > 0 ? `Parse issues: ${parseErrors.join("; ")}.` : ""
|
|
896250
|
+
].filter((line2) => line2.length > 0).join(" "),
|
|
896251
|
+
safety: "safe"
|
|
896252
|
+
}
|
|
896253
|
+
};
|
|
896254
|
+
}
|
|
896255
|
+
function createSettingEditor(setting, currentValue, action2) {
|
|
896256
|
+
const valueHint = setting.type === "number" ? "Enter a number." : setting.type === "string" ? "Enter a value. Leave empty to clear it." : setting.enumValues ? `Allowed values: ${setting.enumValues.join(", ")}.` : action2.detail;
|
|
896257
|
+
return {
|
|
896258
|
+
kind: "setting-set",
|
|
896259
|
+
mode: "update",
|
|
896260
|
+
recordId: setting.key,
|
|
896261
|
+
title: `Set ${setting.key}`,
|
|
896262
|
+
selectedFieldIndex: 0,
|
|
896263
|
+
message: action2.detail,
|
|
896264
|
+
fields: [
|
|
896265
|
+
{
|
|
896266
|
+
id: "value",
|
|
896267
|
+
label: setting.key,
|
|
896268
|
+
value: currentValue,
|
|
896269
|
+
required: false,
|
|
896270
|
+
multiline: false,
|
|
896271
|
+
hint: action2.settingValueHint ?? valueHint,
|
|
896272
|
+
redact: /(?:secret|token|password|api[-_.]?key|signing)/i.test(setting.key)
|
|
896273
|
+
}
|
|
896274
|
+
]
|
|
896275
|
+
};
|
|
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.";
|
|
895596
896436
|
}
|
|
895597
896437
|
// src/input/agent-workspace-token.ts
|
|
895598
896438
|
function handleAgentWorkspaceToken(workspace, token, handleEscape2, requestRender) {
|
|
@@ -895697,14 +896537,7 @@ class AgentWorkspace {
|
|
|
895697
896537
|
localEditor = null;
|
|
895698
896538
|
actionSearchActive = false;
|
|
895699
896539
|
actionSearchQuery = "";
|
|
895700
|
-
selectedLibraryItemIndexes = {
|
|
895701
|
-
memory: 0,
|
|
895702
|
-
note: 0,
|
|
895703
|
-
persona: 0,
|
|
895704
|
-
skill: 0,
|
|
895705
|
-
routine: 0,
|
|
895706
|
-
profile: 0
|
|
895707
|
-
};
|
|
896540
|
+
selectedLibraryItemIndexes = { memory: 0, note: 0, persona: 0, skill: 0, routine: 0, profile: 0 };
|
|
895708
896541
|
context = null;
|
|
895709
896542
|
dispatchCommand = null;
|
|
895710
896543
|
dispatchPrompt = null;
|
|
@@ -895720,7 +896553,10 @@ class AgentWorkspace {
|
|
|
895720
896553
|
this.localEditor = null;
|
|
895721
896554
|
this.actionSearchActive = false;
|
|
895722
896555
|
this.actionSearchQuery = "";
|
|
895723
|
-
if (
|
|
896556
|
+
if (!categoryId) {
|
|
896557
|
+
this.selectedCategoryIndex = 0;
|
|
896558
|
+
this.selectedActionIndex = 0;
|
|
896559
|
+
} else if (!this.selectCategory(categoryId)) {
|
|
895724
896560
|
const normalized3 = categoryId.trim();
|
|
895725
896561
|
this.status = `Unknown Agent workspace area: ${normalized3}`;
|
|
895726
896562
|
this.lastActionResult = {
|
|
@@ -895751,7 +896587,7 @@ class AgentWorkspace {
|
|
|
895751
896587
|
get actions() {
|
|
895752
896588
|
if (this.actionSearchActive)
|
|
895753
896589
|
return this.actionSearchResults.map((result2) => result2.action);
|
|
895754
|
-
return this.selectedCategory.actions;
|
|
896590
|
+
return this.selectedCategory.actions.filter((action2) => isAgentWorkspaceActionVisible(this.context, action2));
|
|
895755
896591
|
}
|
|
895756
896592
|
get selectedAction() {
|
|
895757
896593
|
return this.actions[this.selectedActionIndex] ?? null;
|
|
@@ -895762,7 +896598,13 @@ class AgentWorkspace {
|
|
|
895762
896598
|
return this.selectedCategory;
|
|
895763
896599
|
}
|
|
895764
896600
|
get actionSearchResults() {
|
|
895765
|
-
|
|
896601
|
+
if (!this.actionSearchActive)
|
|
896602
|
+
return [];
|
|
896603
|
+
const categories = this.categories.map((category) => ({
|
|
896604
|
+
...category,
|
|
896605
|
+
actions: category.actions.filter((action2) => isAgentWorkspaceActionVisible(this.context, action2))
|
|
896606
|
+
}));
|
|
896607
|
+
return searchAgentWorkspaceActions(categories, this.actionSearchQuery);
|
|
895766
896608
|
}
|
|
895767
896609
|
get selectedActionSearchResult() {
|
|
895768
896610
|
if (!this.actionSearchActive)
|
|
@@ -895819,11 +896661,7 @@ class AgentWorkspace {
|
|
|
895819
896661
|
}
|
|
895820
896662
|
this.runtimeSnapshot = buildAgentWorkspaceRuntimeSnapshot(this.context);
|
|
895821
896663
|
this.status = "Runtime context refreshed.";
|
|
895822
|
-
this.lastActionResult = {
|
|
895823
|
-
kind: "refreshed",
|
|
895824
|
-
title: "Runtime context refreshed",
|
|
895825
|
-
detail: "Provider, model, session, local memory, runtime endpoint, and Agent knowledge route posture were re-read from the live command context."
|
|
895826
|
-
};
|
|
896664
|
+
this.lastActionResult = { kind: "refreshed", title: "Runtime context refreshed", detail: "Provider, model, session, local memory, runtime endpoint, and Agent knowledge route posture were re-read from the live command context." };
|
|
895827
896665
|
}
|
|
895828
896666
|
cancelLocalEditor() {
|
|
895829
896667
|
if (!this.localEditor)
|
|
@@ -895951,33 +896789,81 @@ class AgentWorkspace {
|
|
|
895951
896789
|
return;
|
|
895952
896790
|
}
|
|
895953
896791
|
try {
|
|
895954
|
-
const marker = {
|
|
895955
|
-
scope: "user",
|
|
895956
|
-
source: "wizard",
|
|
895957
|
-
mode: "new",
|
|
895958
|
-
workspaceRoot: shellPaths3.workingDirectory
|
|
895959
|
-
};
|
|
896792
|
+
const marker = { scope: "user", source: "wizard", mode: "new", workspaceRoot: shellPaths3.workingDirectory };
|
|
895960
896793
|
writeOnboardingCheckMarker(shellPaths3, marker);
|
|
895961
896794
|
writeOnboardingCompletionMarker(shellPaths3, marker);
|
|
895962
896795
|
this.status = "Onboarding applied and closed.";
|
|
895963
|
-
this.lastActionResult = {
|
|
895964
|
-
kind: "refreshed",
|
|
895965
|
-
title: "Onboarding complete",
|
|
895966
|
-
detail: "Saved the user onboarding completion marker. Future normal launches start in the main conversation.",
|
|
895967
|
-
safety: "safe"
|
|
895968
|
-
};
|
|
896796
|
+
this.lastActionResult = { kind: "refreshed", title: "Onboarding complete", detail: "Saved the user onboarding completion marker. Future normal launches start in the main conversation.", safety: "safe" };
|
|
895969
896797
|
if (!this.context?.dismissAgentWorkspace?.())
|
|
895970
896798
|
this.close();
|
|
895971
896799
|
} catch (error53) {
|
|
895972
896800
|
const detail = error53 instanceof Error ? error53.message : String(error53);
|
|
895973
896801
|
this.status = "Onboarding completion failed.";
|
|
896802
|
+
this.lastActionResult = { kind: "error", title: "Onboarding completion failed", detail, safety: "safe" };
|
|
896803
|
+
}
|
|
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.";
|
|
895974
896810
|
this.lastActionResult = {
|
|
895975
896811
|
kind: "error",
|
|
895976
|
-
title: "
|
|
895977
|
-
detail,
|
|
895978
|
-
safety:
|
|
896812
|
+
title: "Model picker unavailable",
|
|
896813
|
+
detail: "This runtime cannot open the model picker from Agent workspace.",
|
|
896814
|
+
safety: action2.safety
|
|
895979
896815
|
};
|
|
896816
|
+
requestRender?.();
|
|
896817
|
+
return;
|
|
895980
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
|
+
}
|
|
896850
|
+
applySettingAction(action2, requestRender) {
|
|
896851
|
+
const effect = buildAgentWorkspaceSettingActionEffect(this.context, action2);
|
|
896852
|
+
if (effect.kind === "result") {
|
|
896853
|
+
this.status = effect.status;
|
|
896854
|
+
this.lastActionResult = effect.result;
|
|
896855
|
+
return;
|
|
896856
|
+
}
|
|
896857
|
+
if (effect.kind === "editor") {
|
|
896858
|
+
this.localEditor = effect.editor;
|
|
896859
|
+
this.status = effect.status;
|
|
896860
|
+
this.lastActionResult = effect.result;
|
|
896861
|
+
return;
|
|
896862
|
+
}
|
|
896863
|
+
this.applySettingValue(effect.setting, effect.value, requestRender);
|
|
896864
|
+
}
|
|
896865
|
+
importTuiSettings(requestRender) {
|
|
896866
|
+
this.importTuiSettingsAsync(requestRender);
|
|
895981
896867
|
}
|
|
895982
896868
|
selectedItemForOperation(operation) {
|
|
895983
896869
|
if (operation.startsWith("memory-"))
|
|
@@ -895990,6 +896876,22 @@ class AgentWorkspace {
|
|
|
895990
896876
|
return this.selectedLocalLibraryItem("skill");
|
|
895991
896877
|
return this.selectedLocalLibraryItem("routine");
|
|
895992
896878
|
}
|
|
896879
|
+
async applySettingValue(setting, value, requestRender) {
|
|
896880
|
+
const outcome = await applyAgentWorkspaceSettingValue(this.context, setting, value);
|
|
896881
|
+
this.runtimeSnapshot = this.context ? buildAgentWorkspaceRuntimeSnapshot(this.context) : this.runtimeSnapshot;
|
|
896882
|
+
this.clampSelection();
|
|
896883
|
+
this.status = outcome.status;
|
|
896884
|
+
this.lastActionResult = outcome.result;
|
|
896885
|
+
requestRender?.();
|
|
896886
|
+
}
|
|
896887
|
+
async importTuiSettingsAsync(requestRender) {
|
|
896888
|
+
const outcome = await importAgentWorkspaceTuiSettings(this.context);
|
|
896889
|
+
this.runtimeSnapshot = outcome.runtimeSnapshot ?? this.runtimeSnapshot;
|
|
896890
|
+
this.clampSelection();
|
|
896891
|
+
this.status = outcome.status;
|
|
896892
|
+
this.lastActionResult = outcome.result;
|
|
896893
|
+
requestRender?.();
|
|
896894
|
+
}
|
|
895993
896895
|
memoryApi() {
|
|
895994
896896
|
const memory = this.context?.clients?.agentKnowledgeApi?.memory;
|
|
895995
896897
|
if (!memory)
|
|
@@ -896055,11 +896957,37 @@ class AgentWorkspace {
|
|
|
896055
896957
|
this.status = `${missing.label} is required.`;
|
|
896056
896958
|
return;
|
|
896057
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
|
+
}
|
|
896058
896973
|
if (isAgentWorkspaceCommandEditorKind(editor.kind)) {
|
|
896059
896974
|
this.submitCommandEditor(editor);
|
|
896060
896975
|
requestRender?.();
|
|
896061
896976
|
return;
|
|
896062
896977
|
}
|
|
896978
|
+
if (editor.kind === "setting-set") {
|
|
896979
|
+
const setting = editor.recordId ? agentWorkspaceSettingSchema(this.context, editor.recordId) : null;
|
|
896980
|
+
if (!setting) {
|
|
896981
|
+
this.localEditor = { ...editor, message: "Unknown setting; cannot save." };
|
|
896982
|
+
this.status = "Unknown setting; cannot save.";
|
|
896983
|
+
requestRender?.();
|
|
896984
|
+
return;
|
|
896985
|
+
}
|
|
896986
|
+
const value = this.editorField("value");
|
|
896987
|
+
this.localEditor = null;
|
|
896988
|
+
this.applySettingValue(setting, value, requestRender);
|
|
896989
|
+
return;
|
|
896990
|
+
}
|
|
896063
896991
|
if (editor.kind === "memory") {
|
|
896064
896992
|
if (editor.mode === "delete") {
|
|
896065
896993
|
try {
|
|
@@ -896092,138 +897020,13 @@ class AgentWorkspace {
|
|
|
896092
897020
|
return;
|
|
896093
897021
|
}
|
|
896094
897022
|
try {
|
|
896095
|
-
|
|
896096
|
-
this.
|
|
896097
|
-
|
|
896098
|
-
|
|
896099
|
-
|
|
896100
|
-
|
|
896101
|
-
|
|
896102
|
-
name: this.editorField("name"),
|
|
896103
|
-
description: this.editorField("description"),
|
|
896104
|
-
notes: this.editorField("notes"),
|
|
896105
|
-
tags: splitList5(this.editorField("tags")),
|
|
896106
|
-
triggers: splitList5(this.editorField("triggers")),
|
|
896107
|
-
enable: isAffirmative15(this.editorField("enable"))
|
|
896108
|
-
});
|
|
896109
|
-
this.finishLocalEditor(created.kind, created.id, created.name, "Created");
|
|
896110
|
-
} else if (editor.kind === "profile") {
|
|
896111
|
-
const template = this.editorField("template");
|
|
896112
|
-
const templateId = template && template.toLowerCase() !== "none" ? template : undefined;
|
|
896113
|
-
const profile5 = createAgentRuntimeProfile(shellPaths3.homeDirectory, this.editorField("name"), {
|
|
896114
|
-
...templateId ? { templateId } : {}
|
|
896115
|
-
});
|
|
896116
|
-
this.finishProfileEditor(profile5);
|
|
896117
|
-
} else if (editor.kind === "note") {
|
|
896118
|
-
const registry5 = AgentNoteRegistry.fromShellPaths(shellPaths3);
|
|
896119
|
-
if (editor.mode === "update" && editor.recordId) {
|
|
896120
|
-
const updated = registry5.update(editor.recordId, {
|
|
896121
|
-
title: this.editorField("title"),
|
|
896122
|
-
body: this.editorField("body"),
|
|
896123
|
-
sourceUrl: this.editorField("sourceUrl"),
|
|
896124
|
-
tags: splitList5(this.editorField("tags")),
|
|
896125
|
-
provenance: "Workspace"
|
|
896126
|
-
});
|
|
896127
|
-
this.finishLocalEditor(editor.kind, updated.id, updated.title, "Updated");
|
|
896128
|
-
return;
|
|
896129
|
-
}
|
|
896130
|
-
const created = registry5.create({
|
|
896131
|
-
title: this.editorField("title"),
|
|
896132
|
-
body: this.editorField("body"),
|
|
896133
|
-
sourceUrl: this.editorField("sourceUrl"),
|
|
896134
|
-
tags: splitList5(this.editorField("tags")),
|
|
896135
|
-
source: "user",
|
|
896136
|
-
provenance: "Workspace"
|
|
896137
|
-
});
|
|
896138
|
-
this.finishLocalEditor(editor.kind, created.id, created.title, "Created");
|
|
896139
|
-
} else if (editor.kind === "persona") {
|
|
896140
|
-
const registry5 = AgentPersonaRegistry.fromShellPaths(shellPaths3);
|
|
896141
|
-
if (editor.mode === "update" && editor.recordId) {
|
|
896142
|
-
const wasActive = registry5.snapshot().activePersonaId === editor.recordId;
|
|
896143
|
-
const updated = registry5.update(editor.recordId, {
|
|
896144
|
-
name: this.editorField("name"),
|
|
896145
|
-
description: this.editorField("description"),
|
|
896146
|
-
body: this.editorField("body"),
|
|
896147
|
-
tags: splitList5(this.editorField("tags")),
|
|
896148
|
-
triggers: splitList5(this.editorField("triggers")),
|
|
896149
|
-
provenance: "Workspace"
|
|
896150
|
-
});
|
|
896151
|
-
if (isAffirmative15(this.editorField("activate")))
|
|
896152
|
-
registry5.setActive(updated.id);
|
|
896153
|
-
else if (wasActive)
|
|
896154
|
-
registry5.clearActive();
|
|
896155
|
-
this.finishLocalEditor(editor.kind, updated.id, updated.name, "Updated");
|
|
896156
|
-
return;
|
|
896157
|
-
}
|
|
896158
|
-
const created = registry5.create({
|
|
896159
|
-
name: this.editorField("name"),
|
|
896160
|
-
description: this.editorField("description"),
|
|
896161
|
-
body: this.editorField("body"),
|
|
896162
|
-
tags: splitList5(this.editorField("tags")),
|
|
896163
|
-
triggers: splitList5(this.editorField("triggers")),
|
|
896164
|
-
source: "user",
|
|
896165
|
-
provenance: "Workspace"
|
|
896166
|
-
});
|
|
896167
|
-
if (isAffirmative15(this.editorField("activate")))
|
|
896168
|
-
registry5.setActive(created.id);
|
|
896169
|
-
this.finishLocalEditor(editor.kind, created.id, created.name, "Created");
|
|
896170
|
-
} else if (editor.kind === "skill") {
|
|
896171
|
-
const registry5 = AgentSkillRegistry.fromShellPaths(shellPaths3);
|
|
896172
|
-
if (editor.mode === "update" && editor.recordId) {
|
|
896173
|
-
const updated = registry5.update(editor.recordId, {
|
|
896174
|
-
name: this.editorField("name"),
|
|
896175
|
-
description: this.editorField("description"),
|
|
896176
|
-
procedure: this.editorField("procedure"),
|
|
896177
|
-
triggers: splitList5(this.editorField("triggers")),
|
|
896178
|
-
tags: splitList5(this.editorField("tags")),
|
|
896179
|
-
requirements: buildAgentWorkspaceRequirements((id) => this.editorField(id)),
|
|
896180
|
-
provenance: "Workspace"
|
|
896181
|
-
});
|
|
896182
|
-
registry5.setEnabled(updated.id, isAffirmative15(this.editorField("enabled")));
|
|
896183
|
-
this.finishLocalEditor(editor.kind, updated.id, updated.name, "Updated");
|
|
896184
|
-
return;
|
|
896185
|
-
}
|
|
896186
|
-
const created = registry5.create({
|
|
896187
|
-
name: this.editorField("name"),
|
|
896188
|
-
description: this.editorField("description"),
|
|
896189
|
-
procedure: this.editorField("procedure"),
|
|
896190
|
-
triggers: splitList5(this.editorField("triggers")),
|
|
896191
|
-
tags: splitList5(this.editorField("tags")),
|
|
896192
|
-
requirements: buildAgentWorkspaceRequirements((id) => this.editorField(id)),
|
|
896193
|
-
enabled: isAffirmative15(this.editorField("enabled")),
|
|
896194
|
-
source: "user",
|
|
896195
|
-
provenance: "Workspace"
|
|
896196
|
-
});
|
|
896197
|
-
this.finishLocalEditor(editor.kind, created.id, created.name, "Created");
|
|
896198
|
-
} else {
|
|
896199
|
-
const registry5 = AgentRoutineRegistry.fromShellPaths(shellPaths3);
|
|
896200
|
-
if (editor.mode === "update" && editor.recordId) {
|
|
896201
|
-
const updated = registry5.update(editor.recordId, {
|
|
896202
|
-
name: this.editorField("name"),
|
|
896203
|
-
description: this.editorField("description"),
|
|
896204
|
-
steps: this.editorField("steps"),
|
|
896205
|
-
triggers: splitList5(this.editorField("triggers")),
|
|
896206
|
-
tags: splitList5(this.editorField("tags")),
|
|
896207
|
-
requirements: buildAgentWorkspaceRequirements((id) => this.editorField(id)),
|
|
896208
|
-
provenance: "Workspace"
|
|
896209
|
-
});
|
|
896210
|
-
registry5.setEnabled(updated.id, isAffirmative15(this.editorField("enabled")));
|
|
896211
|
-
this.finishLocalEditor(editor.kind, updated.id, updated.name, "Updated");
|
|
896212
|
-
return;
|
|
896213
|
-
}
|
|
896214
|
-
const created = registry5.create({
|
|
896215
|
-
name: this.editorField("name"),
|
|
896216
|
-
description: this.editorField("description"),
|
|
896217
|
-
steps: this.editorField("steps"),
|
|
896218
|
-
triggers: splitList5(this.editorField("triggers")),
|
|
896219
|
-
tags: splitList5(this.editorField("tags")),
|
|
896220
|
-
requirements: buildAgentWorkspaceRequirements((id) => this.editorField(id)),
|
|
896221
|
-
enabled: isAffirmative15(this.editorField("enabled")),
|
|
896222
|
-
source: "user",
|
|
896223
|
-
provenance: "Workspace"
|
|
896224
|
-
});
|
|
896225
|
-
this.finishLocalEditor(editor.kind, created.id, created.name, "Created");
|
|
896226
|
-
}
|
|
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
|
+
});
|
|
896227
897030
|
} catch (error53) {
|
|
896228
897031
|
const detail = error53 instanceof Error ? error53.message : String(error53);
|
|
896229
897032
|
this.localEditor = { ...editor, message: detail };
|
|
@@ -897658,7 +898461,7 @@ function handleProfilePickerToken(state4, token) {
|
|
|
897658
898461
|
}
|
|
897659
898462
|
|
|
897660
898463
|
// src/input/handler-picker-routes.ts
|
|
897661
|
-
import { readFileSync as
|
|
898464
|
+
import { readFileSync as readFileSync95 } from "fs";
|
|
897662
898465
|
|
|
897663
898466
|
// src/renderer/model-picker-overlay.ts
|
|
897664
898467
|
var MODEL_PICKER_CHROME_LINES = 7;
|
|
@@ -897950,7 +898753,7 @@ function handleFilePickerToken(state4, token) {
|
|
|
897950
898753
|
throw new Error("working directory is unavailable");
|
|
897951
898754
|
}
|
|
897952
898755
|
const resolvedPath3 = resolveAndValidatePath(selected, projectRoot);
|
|
897953
|
-
const data =
|
|
898756
|
+
const data = readFileSync95(resolvedPath3);
|
|
897954
898757
|
const base644 = data.toString("base64");
|
|
897955
898758
|
const mediaType = state4.mediaTypeFromExt(ext);
|
|
897956
898759
|
const filename = selected.split("/").pop() ?? selected;
|
|
@@ -898067,6 +898870,17 @@ function handleModalTokenRoutes(state4, token) {
|
|
|
898067
898870
|
}, token)) {
|
|
898068
898871
|
return withState(state4, true);
|
|
898069
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
|
+
}
|
|
898070
898884
|
if (handleSettingsModalToken({
|
|
898071
898885
|
settingsModal: state4.settingsModal,
|
|
898072
898886
|
commandContext: state4.commandContext,
|
|
@@ -898119,17 +898933,6 @@ function handleModalTokenRoutes(state4, token) {
|
|
|
898119
898933
|
if (handleHistorySearchToken(historyState, token)) {
|
|
898120
898934
|
return withState(state4, true, historyState);
|
|
898121
898935
|
}
|
|
898122
|
-
if (handleModelPickerToken({
|
|
898123
|
-
modelPicker: state4.modelPicker,
|
|
898124
|
-
modalStack: state4.modalStack,
|
|
898125
|
-
commandContext: state4.commandContext,
|
|
898126
|
-
getViewportHeight: state4.getViewportHeight,
|
|
898127
|
-
requestRender: state4.requestRender,
|
|
898128
|
-
handleEscape: state4.handleEscape,
|
|
898129
|
-
onModelPickerCommit: state4.onModelPickerCommit
|
|
898130
|
-
}, token)) {
|
|
898131
|
-
return withState(state4, true);
|
|
898132
|
-
}
|
|
898133
898936
|
if (handleLiveTailToken({
|
|
898134
898937
|
liveTailModal: state4.liveTailModal,
|
|
898135
898938
|
processModal: state4.processModal,
|
|
@@ -899068,7 +899871,8 @@ class InputHandler {
|
|
|
899068
899871
|
handleCtrlCForHandler(this);
|
|
899069
899872
|
}
|
|
899070
899873
|
modalOpened(name51) {
|
|
899071
|
-
|
|
899874
|
+
const keepAgentWorkspaceUnderlay = name51 === "modelPicker" || name51 === "settings";
|
|
899875
|
+
if (name51 !== "agentWorkspace" && !keepAgentWorkspaceUnderlay && this.agentWorkspace.active) {
|
|
899072
899876
|
this.closeAgentWorkspaceModal();
|
|
899073
899877
|
}
|
|
899074
899878
|
modalOpenedForHandler(this, name51);
|
|
@@ -899431,232 +900235,6 @@ class PermissionPromptUI {
|
|
|
899431
900235
|
}
|
|
899432
900236
|
}
|
|
899433
900237
|
|
|
899434
|
-
// src/renderer/layout-engine.ts
|
|
899435
|
-
function clamp4(value, min2, max2) {
|
|
899436
|
-
return Math.max(min2, Math.min(max2, value));
|
|
899437
|
-
}
|
|
899438
|
-
function createShellLayout(request2) {
|
|
899439
|
-
const width = Math.max(1, request2.width);
|
|
899440
|
-
const height = Math.max(1, request2.height);
|
|
899441
|
-
const headerHeight = clamp4(request2.headerHeight, 0, height);
|
|
899442
|
-
const footerHeight = clamp4(request2.footerHeight, 0, Math.max(0, height - headerHeight));
|
|
899443
|
-
const bodyHeight = Math.max(0, height - headerHeight - footerHeight);
|
|
899444
|
-
const hasPanel = typeof request2.panelWidth === "number" && request2.panelWidth > 0;
|
|
899445
|
-
const safePanelWidth = hasPanel ? clamp4(request2.panelWidth, 1, Math.max(1, width - 2)) : 0;
|
|
899446
|
-
const separatorWidth = hasPanel ? 1 : 0;
|
|
899447
|
-
const conversationWidth = hasPanel ? Math.max(1, width - safePanelWidth - separatorWidth) : width;
|
|
899448
|
-
return {
|
|
899449
|
-
screen: { x: 0, y: 0, width, height },
|
|
899450
|
-
header: { x: 0, y: 0, width, height: headerHeight },
|
|
899451
|
-
body: { x: 0, y: headerHeight, width, height: bodyHeight },
|
|
899452
|
-
footer: { x: 0, y: headerHeight + bodyHeight, width, height: footerHeight },
|
|
899453
|
-
conversation: { x: 0, y: headerHeight, width: conversationWidth, height: bodyHeight },
|
|
899454
|
-
panel: hasPanel ? {
|
|
899455
|
-
x: conversationWidth + separatorWidth,
|
|
899456
|
-
y: headerHeight,
|
|
899457
|
-
width: safePanelWidth,
|
|
899458
|
-
height: bodyHeight
|
|
899459
|
-
} : undefined,
|
|
899460
|
-
separatorX: hasPanel ? conversationWidth : undefined
|
|
899461
|
-
};
|
|
899462
|
-
}
|
|
899463
|
-
function createSplitPaneLayout(totalRows, ratio, options = {}) {
|
|
899464
|
-
const topTabRows = options.topTabRows ?? 1;
|
|
899465
|
-
const bottomTabRows = options.bottomTabRows ?? 1;
|
|
899466
|
-
const separatorRows = options.separatorRows ?? 1;
|
|
899467
|
-
const chromeRows = topTabRows + bottomTabRows + separatorRows;
|
|
899468
|
-
const contentRows = Math.max(0, totalRows - chromeRows);
|
|
899469
|
-
const normalizedRatio = clamp4(ratio, 0.2, 0.8);
|
|
899470
|
-
const topContentRows = contentRows <= 1 ? contentRows : Math.max(1, Math.floor(contentRows * normalizedRatio));
|
|
899471
|
-
const bottomContentRows = contentRows <= 1 ? 0 : Math.max(1, contentRows - topContentRows);
|
|
899472
|
-
return {
|
|
899473
|
-
totalRows,
|
|
899474
|
-
topTabRows,
|
|
899475
|
-
bottomTabRows,
|
|
899476
|
-
separatorRows,
|
|
899477
|
-
topContentRows,
|
|
899478
|
-
bottomContentRows
|
|
899479
|
-
};
|
|
899480
|
-
}
|
|
899481
|
-
|
|
899482
|
-
// src/renderer/process-indicator.ts
|
|
899483
|
-
function truncateToWidth2(text, maxWidth) {
|
|
899484
|
-
let width = 0;
|
|
899485
|
-
let i5 = 0;
|
|
899486
|
-
for (const char of text) {
|
|
899487
|
-
const cw = getDisplayWidth(char);
|
|
899488
|
-
if (width + cw > maxWidth)
|
|
899489
|
-
break;
|
|
899490
|
-
width += cw;
|
|
899491
|
-
i5 += char.length;
|
|
899492
|
-
}
|
|
899493
|
-
return text.slice(0, i5);
|
|
899494
|
-
}
|
|
899495
|
-
function renderProcessIndicator(width, agentCount, toolCount, focused = false, agentProgress) {
|
|
899496
|
-
const total = agentCount + toolCount;
|
|
899497
|
-
const delegationLabel = (count) => `${count} delegation${count !== 1 ? "s" : ""}`;
|
|
899498
|
-
const renderPlainStatus = (text, style) => [UIFactory.stringToLine(` ${text}`, width, style)];
|
|
899499
|
-
const renderFocusedStatus = (text) => {
|
|
899500
|
-
const bg = "#31506f";
|
|
899501
|
-
const fg = "#eefaff";
|
|
899502
|
-
const markerFg = "#7dd3fc";
|
|
899503
|
-
const line2 = UIFactory.stringToLine(" ".repeat(width), width, { fg: "238" });
|
|
899504
|
-
const prefix = `${GLYPHS.navigation.selected} `;
|
|
899505
|
-
const body2 = truncateToWidth2(text, Math.max(0, width - 8));
|
|
899506
|
-
const highlighted = ` ${prefix}${body2} `;
|
|
899507
|
-
const startX = 2;
|
|
899508
|
-
for (let i5 = 0;i5 < highlighted.length && startX + i5 < width - 2; i5++) {
|
|
899509
|
-
const ch = highlighted[i5];
|
|
899510
|
-
const isMarker = i5 < prefix.length + 1;
|
|
899511
|
-
line2[startX + i5].char = ch;
|
|
899512
|
-
line2[startX + i5].fg = isMarker ? markerFg : fg;
|
|
899513
|
-
line2[startX + i5].bg = bg;
|
|
899514
|
-
line2[startX + i5].bold = true;
|
|
899515
|
-
line2[startX + i5].dim = false;
|
|
899516
|
-
}
|
|
899517
|
-
return [line2];
|
|
899518
|
-
};
|
|
899519
|
-
if (focused) {
|
|
899520
|
-
const parts3 = [];
|
|
899521
|
-
if (agentCount > 0)
|
|
899522
|
-
parts3.push(delegationLabel(agentCount));
|
|
899523
|
-
if (toolCount > 0)
|
|
899524
|
-
parts3.push(`${toolCount} tool${toolCount !== 1 ? "s" : ""} running`);
|
|
899525
|
-
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`;
|
|
899526
|
-
return renderFocusedStatus(label2);
|
|
899527
|
-
}
|
|
899528
|
-
if (total === 0) {
|
|
899529
|
-
return renderPlainStatus("No runtime activity", { fg: "238", dim: true });
|
|
899530
|
-
}
|
|
899531
|
-
const parts2 = [];
|
|
899532
|
-
if (agentCount > 0) {
|
|
899533
|
-
parts2.push(delegationLabel(agentCount));
|
|
899534
|
-
}
|
|
899535
|
-
if (toolCount > 0) {
|
|
899536
|
-
parts2.push(`${toolCount} tool${toolCount !== 1 ? "s" : ""} running`);
|
|
899537
|
-
}
|
|
899538
|
-
const PROGRESS_RESERVED_CHARS = 43;
|
|
899539
|
-
const progressMaxLen = Math.max(0, width - PROGRESS_RESERVED_CHARS);
|
|
899540
|
-
const progressSuffix = agentProgress && progressMaxLen > 10 ? ` | ${agentProgress.length > progressMaxLen ? agentProgress.slice(0, Math.max(0, progressMaxLen - 3)) + "..." : agentProgress}` : "";
|
|
899541
|
-
const label = `${parts2.join(` ${GLYPHS.navigation.pipeSeparator} `)}${progressSuffix}`;
|
|
899542
|
-
const hint = ` ${GLYPHS.status.pending} Enter to view`;
|
|
899543
|
-
return renderPlainStatus(`${label}${hint}`, { fg: "#00ffff", bold: true });
|
|
899544
|
-
}
|
|
899545
|
-
|
|
899546
|
-
// src/renderer/shell-surface.ts
|
|
899547
|
-
var FOOTER_BASE_ROWS = 9;
|
|
899548
|
-
var CONTEXT_PROGRESS_ROWS = 2;
|
|
899549
|
-
var PROCESS_INDICATOR_ROWS = 1;
|
|
899550
|
-
function estimateShellFooterHeight(promptLineCount, contextWindow) {
|
|
899551
|
-
const safePromptLines = Math.max(1, promptLineCount);
|
|
899552
|
-
const progressRows = contextWindow && contextWindow > 0 ? CONTEXT_PROGRESS_ROWS : 0;
|
|
899553
|
-
return FOOTER_BASE_ROWS + safePromptLines + progressRows + PROCESS_INDICATOR_ROWS;
|
|
899554
|
-
}
|
|
899555
|
-
function buildShellFooter(options) {
|
|
899556
|
-
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);
|
|
899557
|
-
const processIndicator = renderProcessIndicator(options.width, options.runningAgentCount, options.runningProcessCount, options.indicatorFocused, options.runningAgentProgress);
|
|
899558
|
-
const inputBoxRows = Math.max(1, options.promptLineCount) + 2;
|
|
899559
|
-
lines.splice(inputBoxRows, 0, ...processIndicator);
|
|
899560
|
-
return { lines, height: lines.length };
|
|
899561
|
-
}
|
|
899562
|
-
|
|
899563
|
-
// src/renderer/conversation-layout.ts
|
|
899564
|
-
function buildConversationViewport(request2) {
|
|
899565
|
-
const overlayRows = request2.overlayRows ?? 0;
|
|
899566
|
-
const effectiveHeight = Math.max(0, request2.viewportHeight - overlayRows);
|
|
899567
|
-
const lineCount = request2.conversation.history.getLineCount();
|
|
899568
|
-
const maxScroll = Math.max(0, lineCount - effectiveHeight);
|
|
899569
|
-
const nextScrollTop = request2.scrollLocked ? maxScroll : Math.max(0, Math.min(request2.scrollTop, maxScroll));
|
|
899570
|
-
const viewport = request2.conversation.history.getSnapshot(nextScrollTop, effectiveHeight, request2.width);
|
|
899571
|
-
return {
|
|
899572
|
-
effectiveHeight,
|
|
899573
|
-
maxScroll,
|
|
899574
|
-
nextScrollTop,
|
|
899575
|
-
viewport
|
|
899576
|
-
};
|
|
899577
|
-
}
|
|
899578
|
-
function overlayViewportBottom(viewport, overlay, width, viewportHeight, bottomInset = 0) {
|
|
899579
|
-
if (overlay.length === 0)
|
|
899580
|
-
return [...viewport];
|
|
899581
|
-
const next = [...viewport];
|
|
899582
|
-
const targetStart = Math.max(0, viewportHeight - bottomInset - overlay.length);
|
|
899583
|
-
next.length = Math.min(next.length, targetStart);
|
|
899584
|
-
while (next.length < targetStart)
|
|
899585
|
-
next.push(createEmptyLine(width));
|
|
899586
|
-
next.push(...overlay);
|
|
899587
|
-
return next;
|
|
899588
|
-
}
|
|
899589
|
-
function replaceViewportWithOverlay(overlay, width, viewportHeight) {
|
|
899590
|
-
const next = [];
|
|
899591
|
-
const pad = Math.max(0, viewportHeight - overlay.length);
|
|
899592
|
-
for (let i5 = 0;i5 < pad; i5++)
|
|
899593
|
-
next.push(createEmptyLine(width));
|
|
899594
|
-
next.push(...overlay);
|
|
899595
|
-
return next;
|
|
899596
|
-
}
|
|
899597
|
-
|
|
899598
|
-
// src/renderer/file-picker-overlay.ts
|
|
899599
|
-
var FILE_PICKER_TITLE = "Select File";
|
|
899600
|
-
var FILE_PICKER_SEARCH_PREFIX = "@ ";
|
|
899601
|
-
var FILE_PICKER_EMPTY_MESSAGE = "No matching files";
|
|
899602
|
-
var FILE_PICKER_HINTS = "[Up/Down] Navigate [/] Search [Enter] Select [Esc] Cancel";
|
|
899603
|
-
function renderFilePickerOverlay(picker, width, viewportHeight = 24) {
|
|
899604
|
-
const lines = [];
|
|
899605
|
-
const metrics = getOverlaySurfaceMetrics(width, viewportHeight, {
|
|
899606
|
-
chromeRows: 4,
|
|
899607
|
-
maxWidth: 70,
|
|
899608
|
-
minContentRows: 6,
|
|
899609
|
-
maxContentRows: 10
|
|
899610
|
-
});
|
|
899611
|
-
const layout = createOverlayBoxLayout(width, metrics.margin, metrics.boxWidth);
|
|
899612
|
-
const contentW = layout.innerWidth;
|
|
899613
|
-
const borderFg = DEFAULT_OVERLAY_PALETTE.borderFg;
|
|
899614
|
-
const titleFg = DEFAULT_OVERLAY_PALETTE.titleFg;
|
|
899615
|
-
const bodyFg = DEFAULT_OVERLAY_PALETTE.bodyFg;
|
|
899616
|
-
const mutedFg = DEFAULT_OVERLAY_PALETTE.mutedFg;
|
|
899617
|
-
const selectedBg = DEFAULT_OVERLAY_PALETTE.selectedBg;
|
|
899618
|
-
const titleLine = createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.topLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.topRight, borderFg, DEFAULT_OVERLAY_PALETTE.titleBg);
|
|
899619
|
-
putOverlayText(titleLine, layout.margin + 2, layout.width - 4, FILE_PICKER_TITLE, { fg: titleFg, bold: true });
|
|
899620
|
-
lines.push(titleLine);
|
|
899621
|
-
const queryDisplay = picker.query || "";
|
|
899622
|
-
const searchLine = createOverlayContentLine(width, layout, borderFg, DEFAULT_OVERLAY_PALETTE.inputBg);
|
|
899623
|
-
const searchPrefix = FILE_PICKER_SEARCH_PREFIX;
|
|
899624
|
-
const queryText = fitDisplay(`${queryDisplay}${picker.searchFocused ? OVERLAY_GLYPHS.cursor : ""}`, Math.max(0, contentW - getDisplayWidth(searchPrefix)));
|
|
899625
|
-
putOverlayText(searchLine, layout.margin + 2, getDisplayWidth(searchPrefix), searchPrefix, { fg: picker.searchFocused ? bodyFg : mutedFg });
|
|
899626
|
-
putOverlayText(searchLine, layout.margin + 2 + getDisplayWidth(searchPrefix), contentW - getDisplayWidth(searchPrefix), queryText, { fg: picker.query.length > 0 || picker.searchFocused ? bodyFg : mutedFg });
|
|
899627
|
-
lines.push(searchLine);
|
|
899628
|
-
lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.teeLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.teeRight, borderFg, DEFAULT_OVERLAY_PALETTE.sectionBg));
|
|
899629
|
-
if (picker.results.length === 0) {
|
|
899630
|
-
const noResults = createOverlayContentLine(width, layout, borderFg, DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
899631
|
-
putOverlayText(noResults, layout.margin + 2, contentW, fitDisplay(FILE_PICKER_EMPTY_MESSAGE, contentW), { fg: "244", dim: true });
|
|
899632
|
-
lines.push(noResults);
|
|
899633
|
-
} else {
|
|
899634
|
-
const maxVisible = metrics.contentRows;
|
|
899635
|
-
let startIdx = 0;
|
|
899636
|
-
if (picker.results.length > maxVisible) {
|
|
899637
|
-
startIdx = Math.max(0, Math.min(picker.selectedIndex - Math.floor(maxVisible / 2), picker.results.length - maxVisible));
|
|
899638
|
-
}
|
|
899639
|
-
const endIdx = Math.min(startIdx + maxVisible, picker.results.length);
|
|
899640
|
-
for (let i5 = startIdx;i5 < endIdx; i5++) {
|
|
899641
|
-
const file2 = picker.results[i5];
|
|
899642
|
-
const isSelected = i5 === picker.selectedIndex;
|
|
899643
|
-
const indicator = isSelected ? `${OVERLAY_GLYPHS.selected} ` : " ";
|
|
899644
|
-
const displayFile = getDisplayWidth(file2) > contentW - 2 ? truncateDisplay(file2, contentW - 2) : file2;
|
|
899645
|
-
const line2 = createOverlayContentLine(width, layout, borderFg, isSelected ? selectedBg : DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
899646
|
-
putOverlayText(line2, layout.margin + 2, contentW, fitDisplay(indicator + fitDisplay(displayFile, contentW - 2), contentW), {
|
|
899647
|
-
fg: isSelected ? titleFg : file2.endsWith("/") ? titleFg : bodyFg,
|
|
899648
|
-
bg: isSelected ? selectedBg : DEFAULT_OVERLAY_PALETTE.bodyBg,
|
|
899649
|
-
bold: isSelected
|
|
899650
|
-
});
|
|
899651
|
-
lines.push(line2);
|
|
899652
|
-
}
|
|
899653
|
-
}
|
|
899654
|
-
const bottomLine = createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.bottomLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.bottomRight, borderFg, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
899655
|
-
putOverlayText(bottomLine, layout.margin + 2, layout.width - 4, truncateDisplay(FILE_PICKER_HINTS, layout.width - 4), { fg: mutedFg, dim: true });
|
|
899656
|
-
lines.push(bottomLine);
|
|
899657
|
-
return lines;
|
|
899658
|
-
}
|
|
899659
|
-
|
|
899660
900238
|
// src/renderer/model-workspace.ts
|
|
899661
900239
|
var PALETTE = {
|
|
899662
900240
|
border: "#64748b",
|
|
@@ -899702,7 +900280,7 @@ var MODEL_WORKSPACE_CONTEXT_CAP_INPUT_HELP = "Type digits to set a cap. Enter co
|
|
|
899702
900280
|
var MODEL_WORKSPACE_FOOTER_SEARCH_ACTIVE = "Typing filters search; Esc clears search";
|
|
899703
900281
|
var MODEL_WORKSPACE_FOOTER_SEARCH_INACTIVE = "/ search";
|
|
899704
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";
|
|
899705
|
-
function
|
|
900283
|
+
function clamp4(value, min2, max2) {
|
|
899706
900284
|
return Math.max(min2, Math.min(max2, value));
|
|
899707
900285
|
}
|
|
899708
900286
|
function fillRange2(line2, startX, endX, bg) {
|
|
@@ -899791,10 +900369,10 @@ function padDisplay2(text, width) {
|
|
|
899791
900369
|
function stableWindow2(total, selected, visible) {
|
|
899792
900370
|
if (total <= 0 || visible <= 0)
|
|
899793
900371
|
return { start: 0, end: 0 };
|
|
899794
|
-
const clamped =
|
|
900372
|
+
const clamped = clamp4(selected, 0, total - 1);
|
|
899795
900373
|
const half = Math.floor(visible / 2);
|
|
899796
900374
|
const maxStart = Math.max(0, total - visible);
|
|
899797
|
-
const start2 =
|
|
900375
|
+
const start2 = clamp4(clamped - half, 0, maxStart);
|
|
899798
900376
|
return { start: start2, end: Math.min(total, start2 + visible) };
|
|
899799
900377
|
}
|
|
899800
900378
|
function formatContext(value) {
|
|
@@ -899932,11 +900510,11 @@ function renderProviderRows(picker, lines, rows, startX, width) {
|
|
|
899932
900510
|
function renderModelRows(picker, lines, rows, startX, width) {
|
|
899933
900511
|
const models = picker.getFilteredModels();
|
|
899934
900512
|
const { start: start2, end } = stableWindow2(models.length, picker.selectedIndex, rows);
|
|
899935
|
-
const providerW =
|
|
900513
|
+
const providerW = clamp4(Math.floor(width * 0.14), 10, 18);
|
|
899936
900514
|
const ctxW = 8;
|
|
899937
900515
|
const tierW = 8;
|
|
899938
900516
|
const capsW = 14;
|
|
899939
|
-
const nameW =
|
|
900517
|
+
const nameW = clamp4(Math.floor(width * 0.28), 16, 36);
|
|
899940
900518
|
const keyW = Math.max(10, width - providerW - ctxW - tierW - capsW - nameW - 10);
|
|
899941
900519
|
for (let visibleRow = 0;visibleRow < rows; visibleRow += 1) {
|
|
899942
900520
|
const absolute = start2 + visibleRow;
|
|
@@ -900016,11 +900594,11 @@ function writeTableHeader(line2, picker, startX, width) {
|
|
|
900016
900594
|
writeText3(line2, startX + 1, width - 2, MODEL_WORKSPACE_TABLE_HEADERS.contextCap, style);
|
|
900017
900595
|
return;
|
|
900018
900596
|
}
|
|
900019
|
-
const providerW =
|
|
900597
|
+
const providerW = clamp4(Math.floor(width * 0.14), 10, 18);
|
|
900020
900598
|
const ctxW = 8;
|
|
900021
900599
|
const tierW = 8;
|
|
900022
900600
|
const capsW = 14;
|
|
900023
|
-
const nameW =
|
|
900601
|
+
const nameW = clamp4(Math.floor(width * 0.28), 16, 36);
|
|
900024
900602
|
const keyW = Math.max(10, width - providerW - ctxW - tierW - capsW - nameW - 10);
|
|
900025
900603
|
let x2 = startX + 3;
|
|
900026
900604
|
writeText3(line2, x2, keyW, padDisplay2(MODEL_WORKSPACE_TABLE_HEADERS.modelKey, keyW), style);
|
|
@@ -900043,7 +900621,7 @@ function renderModelWorkspace(picker, width, viewportHeight) {
|
|
|
900043
900621
|
const safeWidth = Math.max(20, width);
|
|
900044
900622
|
const safeHeight = Math.max(12, viewportHeight);
|
|
900045
900623
|
const lines = [];
|
|
900046
|
-
const targetW =
|
|
900624
|
+
const targetW = clamp4(Math.round(safeWidth * 0.18), 24, 34);
|
|
900047
900625
|
const contentX = targetW + 1;
|
|
900048
900626
|
const contentW = Math.max(1, safeWidth - contentX - 1);
|
|
900049
900627
|
const top = borderLine2(safeWidth, GLYPHS.frame.topLeft, GLYPHS.frame.horizontal, GLYPHS.frame.topRight);
|
|
@@ -900063,7 +900641,7 @@ function renderModelWorkspace(picker, width, viewportHeight) {
|
|
|
900063
900641
|
const bodyRows = safeHeight - 3 - footerRows;
|
|
900064
900642
|
const maxDetailRows = Math.max(3, bodyRows - 2);
|
|
900065
900643
|
const minDetailRows = Math.min(6, maxDetailRows);
|
|
900066
|
-
const detailRows =
|
|
900644
|
+
const detailRows = clamp4(Math.round(bodyRows * 0.32), minDetailRows, maxDetailRows);
|
|
900067
900645
|
const listRows = Math.max(1, bodyRows - detailRows - 1);
|
|
900068
900646
|
const details = detailLines(picker, contentW - 2).slice(0, detailRows);
|
|
900069
900647
|
for (let row = 0;row < bodyRows; row += 1) {
|
|
@@ -900171,292 +900749,6 @@ function keyForTargets(values2) {
|
|
|
900171
900749
|
].join("\x1D")).join("\x1F");
|
|
900172
900750
|
}
|
|
900173
900751
|
|
|
900174
|
-
// src/renderer/selection-modal-overlay.ts
|
|
900175
|
-
var BORDER_FG = DEFAULT_OVERLAY_PALETTE.borderFg;
|
|
900176
|
-
var TITLE_FG = DEFAULT_OVERLAY_PALETTE.titleFg;
|
|
900177
|
-
var BODY_FG = DEFAULT_OVERLAY_PALETTE.bodyFg;
|
|
900178
|
-
var MUTED_FG = DEFAULT_OVERLAY_PALETTE.mutedFg;
|
|
900179
|
-
var CATEGORY_FG = "#4488cc";
|
|
900180
|
-
var SELECTED_BG = DEFAULT_OVERLAY_PALETTE.selectedBg;
|
|
900181
|
-
var SELECTION_MODAL_SEARCH_LABEL = " Search";
|
|
900182
|
-
var SELECTION_MODAL_RESULTS_LABEL = " Results";
|
|
900183
|
-
var SELECTION_MODAL_NO_MATCHING_ITEMS = "No matching items";
|
|
900184
|
-
var SELECTION_MODAL_NO_ITEMS = "No items";
|
|
900185
|
-
var SELECTION_MODAL_NAVIGATION_HINT = "[Up/Down] Navigate";
|
|
900186
|
-
var SELECTION_MODAL_CLOSE_HINT = "[Esc] Close";
|
|
900187
|
-
var SELECTION_MODAL_SEARCH_HINT = "[/] Search";
|
|
900188
|
-
var SELECTION_MODAL_SPACE_TOGGLE_HINT = "[Space] Toggle";
|
|
900189
|
-
function putText(line2, startX, maxWidth, text, style) {
|
|
900190
|
-
putOverlayText(line2, startX, maxWidth, text, style);
|
|
900191
|
-
}
|
|
900192
|
-
function primaryVerbForAction(primaryAction) {
|
|
900193
|
-
return primaryAction === "toggle" ? "[Enter] Toggle" : primaryAction === "edit" ? "[Enter] Edit" : primaryAction === "delete" ? "[Enter] Delete" : "[Enter] Select";
|
|
900194
|
-
}
|
|
900195
|
-
function renderSelectionModalOverlay(modal, width, viewportHeight = 24) {
|
|
900196
|
-
const lines = [];
|
|
900197
|
-
const metrics = getOverlaySurfaceMetrics(width, viewportHeight, {
|
|
900198
|
-
margin: 4,
|
|
900199
|
-
maxWidth: 72,
|
|
900200
|
-
chromeRows: modal.allowSearch ? 5 : 4,
|
|
900201
|
-
minContentRows: 6,
|
|
900202
|
-
maxContentRows: 10
|
|
900203
|
-
});
|
|
900204
|
-
const layout = createOverlayBoxLayout(width, metrics.margin, metrics.boxWidth);
|
|
900205
|
-
lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.topLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.topRight, BORDER_FG, DEFAULT_OVERLAY_PALETTE.titleBg));
|
|
900206
|
-
const titleLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.titleBg);
|
|
900207
|
-
putText(titleLine, layout.margin + 2, layout.innerWidth, fitDisplay(truncateDisplay(modal.title, layout.innerWidth), layout.innerWidth), { fg: TITLE_FG, bold: true });
|
|
900208
|
-
lines.push(titleLine);
|
|
900209
|
-
if (modal.allowSearch) {
|
|
900210
|
-
const labelLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
900211
|
-
putText(labelLine, layout.margin + 2, layout.innerWidth, fitDisplay(SELECTION_MODAL_SEARCH_LABEL, layout.innerWidth), {
|
|
900212
|
-
fg: CATEGORY_FG,
|
|
900213
|
-
dim: true
|
|
900214
|
-
});
|
|
900215
|
-
lines.push(labelLine);
|
|
900216
|
-
const searchLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.inputBg);
|
|
900217
|
-
const prefix = "/ ";
|
|
900218
|
-
const queryAreaWidth = layout.innerWidth - getDisplayWidth(prefix);
|
|
900219
|
-
const queryValue = modal.query + (modal.searchFocused ? OVERLAY_GLYPHS.cursor : "");
|
|
900220
|
-
const queryText = fitDisplay(truncateDisplay(queryValue, queryAreaWidth), queryAreaWidth);
|
|
900221
|
-
putText(searchLine, layout.margin + 2, getDisplayWidth(prefix), prefix, { fg: modal.searchFocused ? BODY_FG : MUTED_FG });
|
|
900222
|
-
putText(searchLine, layout.margin + 2 + getDisplayWidth(prefix), queryAreaWidth, queryText, {
|
|
900223
|
-
fg: modal.query.length > 0 || modal.searchFocused ? BODY_FG : MUTED_FG
|
|
900224
|
-
});
|
|
900225
|
-
lines.push(searchLine);
|
|
900226
|
-
lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.teeLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.teeRight, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg));
|
|
900227
|
-
} else {
|
|
900228
|
-
lines.push(createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg));
|
|
900229
|
-
}
|
|
900230
|
-
const listTitle = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
900231
|
-
putText(listTitle, layout.margin + 2, layout.innerWidth, fitDisplay(SELECTION_MODAL_RESULTS_LABEL, layout.innerWidth), {
|
|
900232
|
-
fg: CATEGORY_FG,
|
|
900233
|
-
dim: true
|
|
900234
|
-
});
|
|
900235
|
-
lines.push(listTitle);
|
|
900236
|
-
const items = modal.filteredItems;
|
|
900237
|
-
if (items.length === 0) {
|
|
900238
|
-
const line2 = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
900239
|
-
const message = modal.query ? SELECTION_MODAL_NO_MATCHING_ITEMS : SELECTION_MODAL_NO_ITEMS;
|
|
900240
|
-
putText(line2, layout.margin + 2, layout.innerWidth, fitDisplay(message, layout.innerWidth), { fg: MUTED_FG, dim: true });
|
|
900241
|
-
lines.push(line2);
|
|
900242
|
-
} else {
|
|
900243
|
-
const maxVisible = metrics.contentRows;
|
|
900244
|
-
let startIdx = 0;
|
|
900245
|
-
if (items.length > maxVisible) {
|
|
900246
|
-
startIdx = Math.max(0, Math.min(modal.selectedIndex - Math.floor(maxVisible / 2), items.length - maxVisible));
|
|
900247
|
-
}
|
|
900248
|
-
const endIdx = Math.min(startIdx + maxVisible, items.length);
|
|
900249
|
-
let lastCategory;
|
|
900250
|
-
for (let i5 = startIdx;i5 < endIdx; i5++) {
|
|
900251
|
-
const item = items[i5];
|
|
900252
|
-
const isSelected = i5 === modal.selectedIndex;
|
|
900253
|
-
if (item.category && item.category !== lastCategory) {
|
|
900254
|
-
lastCategory = item.category;
|
|
900255
|
-
const categoryLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
900256
|
-
putText(categoryLine, layout.margin + 2, layout.innerWidth, fitDisplay(` ${item.category}`, layout.innerWidth), {
|
|
900257
|
-
fg: CATEGORY_FG,
|
|
900258
|
-
dim: true
|
|
900259
|
-
});
|
|
900260
|
-
lines.push(categoryLine);
|
|
900261
|
-
}
|
|
900262
|
-
const indicator = isSelected ? `${OVERLAY_GLYPHS.selected} ` : " ";
|
|
900263
|
-
const indicatorWidth = 2;
|
|
900264
|
-
const remaining = layout.innerWidth - indicatorWidth;
|
|
900265
|
-
const labelColor = isSelected ? TITLE_FG : item.fg ?? BODY_FG;
|
|
900266
|
-
const detailColor = isSelected ? BODY_FG : MUTED_FG;
|
|
900267
|
-
const labelWidth = item.detail ? fitLabelDetailColumns(item.label, item.detail, remaining).labelWidth : remaining;
|
|
900268
|
-
const labelLine = createOverlayContentLine(width, layout, BORDER_FG, isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
900269
|
-
putText(labelLine, layout.margin + 2, indicatorWidth, indicator, {
|
|
900270
|
-
fg: isSelected ? TITLE_FG : MUTED_FG,
|
|
900271
|
-
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg,
|
|
900272
|
-
bold: isSelected
|
|
900273
|
-
});
|
|
900274
|
-
putText(labelLine, layout.margin + 2 + indicatorWidth, labelWidth, fitDisplay(truncateDisplay(item.label, labelWidth), labelWidth), {
|
|
900275
|
-
fg: labelColor,
|
|
900276
|
-
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg,
|
|
900277
|
-
bold: isSelected
|
|
900278
|
-
});
|
|
900279
|
-
if (item.detail) {
|
|
900280
|
-
const detailWidth = fitLabelDetailColumns(item.label, item.detail, remaining).detailWidth;
|
|
900281
|
-
if (detailWidth >= 12) {
|
|
900282
|
-
putText(labelLine, layout.margin + 2 + indicatorWidth + labelWidth, 2, " ", {
|
|
900283
|
-
fg: BODY_FG,
|
|
900284
|
-
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg
|
|
900285
|
-
});
|
|
900286
|
-
putText(labelLine, layout.margin + 2 + indicatorWidth + labelWidth + 2, detailWidth, fitDisplay(truncateDisplay(item.detail, detailWidth), detailWidth), {
|
|
900287
|
-
fg: detailColor,
|
|
900288
|
-
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg
|
|
900289
|
-
});
|
|
900290
|
-
lines.push(labelLine);
|
|
900291
|
-
} else {
|
|
900292
|
-
lines.push(labelLine);
|
|
900293
|
-
const wrappedDetails = wrapWithHangingIndent(item.detail, Math.max(8, remaining), "", 2);
|
|
900294
|
-
for (const detailLineText of wrappedDetails) {
|
|
900295
|
-
const detailLine = createOverlayContentLine(width, layout, BORDER_FG, isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg);
|
|
900296
|
-
putText(detailLine, layout.margin + 2 + indicatorWidth, remaining, fitDisplay(truncateDisplay(detailLineText, remaining), remaining), {
|
|
900297
|
-
fg: detailColor,
|
|
900298
|
-
bg: isSelected ? SELECTED_BG : DEFAULT_OVERLAY_PALETTE.bodyBg,
|
|
900299
|
-
dim: !isSelected
|
|
900300
|
-
});
|
|
900301
|
-
lines.push(detailLine);
|
|
900302
|
-
}
|
|
900303
|
-
}
|
|
900304
|
-
} else {
|
|
900305
|
-
lines.push(labelLine);
|
|
900306
|
-
}
|
|
900307
|
-
}
|
|
900308
|
-
if (items.length > maxVisible) {
|
|
900309
|
-
const above = startIdx;
|
|
900310
|
-
const below = items.length - endIdx;
|
|
900311
|
-
const scrollHint = above > 0 && below > 0 ? `(${above} above, ${below} below)` : below > 0 ? `(${below} below)` : `(${above} above)`;
|
|
900312
|
-
const hintLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
900313
|
-
putText(hintLine, layout.margin + 2, layout.innerWidth, fitDisplay(scrollHint, layout.innerWidth), { fg: MUTED_FG, dim: true });
|
|
900314
|
-
lines.push(hintLine);
|
|
900315
|
-
}
|
|
900316
|
-
}
|
|
900317
|
-
const footerLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
|
|
900318
|
-
const selectedItem = modal.getSelected();
|
|
900319
|
-
const primaryVerb = primaryVerbForAction(selectedItem?.primaryAction);
|
|
900320
|
-
let hints = `${SELECTION_MODAL_NAVIGATION_HINT} ${primaryVerb} ${SELECTION_MODAL_CLOSE_HINT}`;
|
|
900321
|
-
if (modal.allowSearch)
|
|
900322
|
-
hints += ` ${SELECTION_MODAL_SEARCH_HINT}`;
|
|
900323
|
-
if (selectedItem?.primaryAction === "toggle" && !selectedItem.actions)
|
|
900324
|
-
hints += ` ${SELECTION_MODAL_SPACE_TOGGLE_HINT}`;
|
|
900325
|
-
if (selectedItem?.actions)
|
|
900326
|
-
hints += ` ${selectedItem.actions}`;
|
|
900327
|
-
putText(footerLine, layout.margin + 2, layout.innerWidth, fitDisplay(truncateDisplay(hints, layout.innerWidth), layout.innerWidth), { fg: MUTED_FG, dim: true });
|
|
900328
|
-
lines.push(footerLine);
|
|
900329
|
-
lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.bottomLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.bottomRight, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg));
|
|
900330
|
-
return lines;
|
|
900331
|
-
}
|
|
900332
|
-
|
|
900333
|
-
// src/renderer/bottom-bar.ts
|
|
900334
|
-
function createBottomBarLine(width, style) {
|
|
900335
|
-
const line2 = createEmptyLine(width);
|
|
900336
|
-
for (let col = 0;col < width; col++) {
|
|
900337
|
-
line2[col] = createStyledCell(" ", {
|
|
900338
|
-
fg: style.fg,
|
|
900339
|
-
bg: style.bg,
|
|
900340
|
-
bold: style.bold ?? false,
|
|
900341
|
-
dim: style.dim ?? false,
|
|
900342
|
-
underline: style.underline ?? false
|
|
900343
|
-
});
|
|
900344
|
-
}
|
|
900345
|
-
return line2;
|
|
900346
|
-
}
|
|
900347
|
-
function writeBottomBarText(line2, startX, maxWidth, text, style) {
|
|
900348
|
-
let x2 = startX;
|
|
900349
|
-
let used = 0;
|
|
900350
|
-
for (const ch of text) {
|
|
900351
|
-
const cellWidth = getDisplayWidth(ch);
|
|
900352
|
-
if (cellWidth <= 0)
|
|
900353
|
-
continue;
|
|
900354
|
-
if (used + cellWidth > maxWidth || x2 >= line2.length)
|
|
900355
|
-
break;
|
|
900356
|
-
line2[x2] = createStyledCell(ch, {
|
|
900357
|
-
fg: style.fg,
|
|
900358
|
-
bg: style.bg,
|
|
900359
|
-
bold: style.bold ?? false,
|
|
900360
|
-
dim: style.dim ?? false,
|
|
900361
|
-
underline: style.underline ?? false
|
|
900362
|
-
});
|
|
900363
|
-
if (cellWidth > 1 && x2 + 1 < line2.length) {
|
|
900364
|
-
line2[x2 + 1] = createStyledCell(" ", {
|
|
900365
|
-
fg: style.fg,
|
|
900366
|
-
bg: style.bg,
|
|
900367
|
-
bold: style.bold ?? false,
|
|
900368
|
-
dim: style.dim ?? false,
|
|
900369
|
-
underline: style.underline ?? false
|
|
900370
|
-
});
|
|
900371
|
-
}
|
|
900372
|
-
x2 += cellWidth;
|
|
900373
|
-
used += cellWidth;
|
|
900374
|
-
}
|
|
900375
|
-
}
|
|
900376
|
-
|
|
900377
|
-
// src/renderer/search-overlay.ts
|
|
900378
|
-
var SEARCH_OVERLAY_LABEL = " Find: ";
|
|
900379
|
-
var SEARCH_OVERLAY_NO_MATCHES = "No matches";
|
|
900380
|
-
var SEARCH_OVERLAY_COUNT_SUFFIX = "up/down";
|
|
900381
|
-
var SEARCH_OVERLAY_LOCKED_HINTS = " [Up/Down] or [jk] navigate [Bksp] edit [Esc] close";
|
|
900382
|
-
var SEARCH_OVERLAY_UNLOCKED_HINTS = " [Enter/Tab] lock [Esc] close";
|
|
900383
|
-
function searchOverlayMatchCount(current, total) {
|
|
900384
|
-
return `${current}/${total} ${SEARCH_OVERLAY_COUNT_SUFFIX}`;
|
|
900385
|
-
}
|
|
900386
|
-
function renderSearchOverlay(manager5, width) {
|
|
900387
|
-
const matchCount = manager5.matches?.length > 0 ? searchOverlayMatchCount(manager5.currentMatch + 1, manager5.matches.length) : manager5.query.length > 0 ? SEARCH_OVERLAY_NO_MATCHES : "";
|
|
900388
|
-
const locked = manager5.locked;
|
|
900389
|
-
const cursor = locked ? "" : "\u2588";
|
|
900390
|
-
const queryDisplay = manager5.query + cursor;
|
|
900391
|
-
const hints = locked ? SEARCH_OVERLAY_LOCKED_HINTS : SEARCH_OVERLAY_UNLOCKED_HINTS;
|
|
900392
|
-
const label = SEARCH_OVERLAY_LABEL;
|
|
900393
|
-
const matchStr = matchCount ? ` ${matchCount}` : "";
|
|
900394
|
-
const leftPart = label + queryDisplay;
|
|
900395
|
-
const hintsW = getDisplayWidth(hints);
|
|
900396
|
-
const matchStrW = getDisplayWidth(matchStr);
|
|
900397
|
-
const leftWidth = width - hintsW - matchStrW - 2;
|
|
900398
|
-
const truncatedLeft = fitDisplay(getDisplayWidth(leftPart) > leftWidth ? truncateDisplay(leftPart, leftWidth) : leftPart, leftWidth);
|
|
900399
|
-
const fullLine = truncatedLeft + matchStr + hints + " ";
|
|
900400
|
-
const line2 = createBottomBarLine(width, { fg: "#000000", bg: "#00ffcc" });
|
|
900401
|
-
writeBottomBarText(line2, 0, width, fitDisplay(truncateDisplay(fullLine, width), width), { fg: "#000000", bg: "#00ffcc" });
|
|
900402
|
-
if (matchStr.length > 0) {
|
|
900403
|
-
const matchStart = getDisplayWidth(truncatedLeft);
|
|
900404
|
-
writeBottomBarText(line2, matchStart, matchStrW, matchStr, { fg: "#888888", bg: "#00ffcc", dim: true });
|
|
900405
|
-
}
|
|
900406
|
-
return [line2];
|
|
900407
|
-
}
|
|
900408
|
-
|
|
900409
|
-
// src/renderer/history-search-overlay.ts
|
|
900410
|
-
var HISTORY_SEARCH_PREFIX = "(reverse-i-search)`";
|
|
900411
|
-
var HISTORY_SEARCH_FAILED_PREFIX = "(failed reverse-i-search)`";
|
|
900412
|
-
var HISTORY_SEARCH_QUERY_SUFFIX = "': ";
|
|
900413
|
-
function historySearchLabel(prefix, query2) {
|
|
900414
|
-
return prefix + query2 + HISTORY_SEARCH_QUERY_SUFFIX;
|
|
900415
|
-
}
|
|
900416
|
-
function truncateToWidth3(text, maxWidth) {
|
|
900417
|
-
let usedWidth = 0;
|
|
900418
|
-
let result2 = "";
|
|
900419
|
-
let i5 = 0;
|
|
900420
|
-
while (i5 < text.length) {
|
|
900421
|
-
const code2 = text.codePointAt(i5);
|
|
900422
|
-
const charLen = code2 > 65535 ? 2 : 1;
|
|
900423
|
-
const charWidth = getDisplayWidth(text.slice(i5, i5 + charLen));
|
|
900424
|
-
if (usedWidth + charWidth > maxWidth)
|
|
900425
|
-
break;
|
|
900426
|
-
result2 += text.slice(i5, i5 + charLen);
|
|
900427
|
-
usedWidth += charWidth;
|
|
900428
|
-
i5 += charLen;
|
|
900429
|
-
}
|
|
900430
|
-
return result2 + " ".repeat(maxWidth - usedWidth);
|
|
900431
|
-
}
|
|
900432
|
-
function renderHistorySearchOverlay(historySearch, width) {
|
|
900433
|
-
if (width <= 0)
|
|
900434
|
-
return [];
|
|
900435
|
-
const match = historySearch.currentMatch;
|
|
900436
|
-
const hasMatch = match !== null && historySearch.query.length > 0;
|
|
900437
|
-
const noMatch = historySearch.query.length > 0 && !hasMatch;
|
|
900438
|
-
const prefix = noMatch ? HISTORY_SEARCH_FAILED_PREFIX : HISTORY_SEARCH_PREFIX;
|
|
900439
|
-
const matchText = hasMatch ? match?.entry ?? "" : "";
|
|
900440
|
-
const label = historySearchLabel(prefix, historySearch.query);
|
|
900441
|
-
const full = truncateToWidth3(label + matchText, width);
|
|
900442
|
-
const line2 = createBottomBarLine(width, { fg: "#000000", bg: "#00ffcc" });
|
|
900443
|
-
writeBottomBarText(line2, 0, width, full, { fg: "#000000", bg: "#00ffcc" });
|
|
900444
|
-
if (hasMatch && match) {
|
|
900445
|
-
const labelW = getDisplayWidth(label);
|
|
900446
|
-
const matchStartCol = labelW + match.matchStart;
|
|
900447
|
-
const matchEndCol = matchStartCol + match.matchLength;
|
|
900448
|
-
const highlightWidth = Math.max(0, matchEndCol - matchStartCol);
|
|
900449
|
-
const matchedSlice = truncateToWidth3(match.entry.slice(match.matchStart, match.matchStart + match.matchLength), highlightWidth);
|
|
900450
|
-
writeBottomBarText(line2, matchStartCol, highlightWidth, matchedSlice, {
|
|
900451
|
-
fg: "#000000",
|
|
900452
|
-
bg: "#00ffcc",
|
|
900453
|
-
bold: true,
|
|
900454
|
-
underline: true
|
|
900455
|
-
});
|
|
900456
|
-
}
|
|
900457
|
-
return [line2];
|
|
900458
|
-
}
|
|
900459
|
-
|
|
900460
900752
|
// src/renderer/settings-modal-helpers.ts
|
|
900461
900753
|
function maskSecretValue(value) {
|
|
900462
900754
|
if (value.length === 0)
|
|
@@ -901131,6 +901423,518 @@ function renderSettingsModal(modal, width, viewportHeight = 24) {
|
|
|
901131
901423
|
});
|
|
901132
901424
|
}
|
|
901133
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
|
+
|
|
901134
901938
|
// src/renderer/mcp-workspace.ts
|
|
901135
901939
|
var MCP_WORKSPACE_TITLE = "MCP Workspace / Servers";
|
|
901136
901940
|
var MCP_WORKSPACE_LEFT_HEADER = "Servers";
|
|
@@ -902284,15 +903088,6 @@ function handleBlockingShellInput(options) {
|
|
|
902284
903088
|
}
|
|
902285
903089
|
|
|
902286
903090
|
// src/renderer/agent-workspace-style.ts
|
|
902287
|
-
function safetyColor(action2) {
|
|
902288
|
-
if (action2.safety === "safe")
|
|
902289
|
-
return FULLSCREEN_PALETTE.good;
|
|
902290
|
-
if (action2.safety === "read-only")
|
|
902291
|
-
return FULLSCREEN_PALETTE.info;
|
|
902292
|
-
if (action2.safety === "delegates")
|
|
902293
|
-
return FULLSCREEN_PALETTE.warn;
|
|
902294
|
-
return FULLSCREEN_PALETTE.bad;
|
|
902295
|
-
}
|
|
902296
903091
|
function actionResultColor(result2) {
|
|
902297
903092
|
if (result2.kind === "blocked" || result2.kind === "error")
|
|
902298
903093
|
return FULLSCREEN_PALETTE.bad;
|
|
@@ -902349,13 +903144,23 @@ function buildLeftRows2(workspace, height) {
|
|
|
902349
903144
|
}
|
|
902350
903145
|
function actionCommand(action2) {
|
|
902351
903146
|
if (action2.kind === "workspace")
|
|
902352
|
-
return
|
|
903147
|
+
return "open area";
|
|
902353
903148
|
if (action2.kind === "editor")
|
|
902354
|
-
return action2.editorKind ? `edit ${action2.editorKind}` : "
|
|
903149
|
+
return action2.editorKind ? `edit ${action2.editorKind}` : "edit form";
|
|
903150
|
+
if (action2.kind === "setting")
|
|
903151
|
+
return action2.settingKey ? `setting ${action2.settingKey}` : "setting";
|
|
903152
|
+
if (action2.kind === "settings-import")
|
|
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";
|
|
902355
903158
|
if (action2.kind === "local-selection")
|
|
902356
903159
|
return action2.selectionDelta && action2.selectionDelta < 0 ? "select previous" : "select next";
|
|
902357
903160
|
if (action2.kind === "local-operation")
|
|
902358
903161
|
return action2.localOperation ?? "(local action)";
|
|
903162
|
+
if (action2.kind === "onboarding-complete")
|
|
903163
|
+
return "apply and close";
|
|
902359
903164
|
return action2.command ?? "(guidance)";
|
|
902360
903165
|
}
|
|
902361
903166
|
function setupCounts(snapshot2) {
|
|
@@ -902369,6 +903174,11 @@ function setupCounts(snapshot2) {
|
|
|
902369
903174
|
function setupStatusLabel(status) {
|
|
902370
903175
|
return status === "ready" ? "Ready" : status === "recommended" ? "Recommended" : status === "blocked" ? "Blocked" : "Optional";
|
|
902371
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
|
+
}
|
|
902372
903182
|
function compactText3(text, maxWidth = 104) {
|
|
902373
903183
|
const normalized3 = text.replace(/\s+/g, " ").trim();
|
|
902374
903184
|
if (normalized3.length === 0)
|
|
@@ -902379,8 +903189,8 @@ function compactText3(text, maxWidth = 104) {
|
|
|
902379
903189
|
}
|
|
902380
903190
|
function actionMetaLine(action2) {
|
|
902381
903191
|
return {
|
|
902382
|
-
text:
|
|
902383
|
-
fg: action2.kind === "command" ? FULLSCREEN_PALETTE.info :
|
|
903192
|
+
text: `Does: ${actionCommand(action2)}`,
|
|
903193
|
+
fg: action2.safety === "blocked" ? FULLSCREEN_PALETTE.warn : action2.kind === "command" ? FULLSCREEN_PALETTE.info : FULLSCREEN_PALETTE.muted
|
|
902384
903194
|
};
|
|
902385
903195
|
}
|
|
902386
903196
|
function setupAttentionItems(snapshot2, limit3) {
|
|
@@ -902401,7 +903211,7 @@ function setupOverviewLines(snapshot2) {
|
|
|
902401
903211
|
const counts = setupCounts(snapshot2);
|
|
902402
903212
|
const nextItems = setupAttentionItems(snapshot2, 3);
|
|
902403
903213
|
const lines = [
|
|
902404
|
-
{ text: "
|
|
903214
|
+
{ text: "Onboarding", fg: FULLSCREEN_PALETTE.title, bold: true },
|
|
902405
903215
|
{ text: `${counts.ready}/${snapshot2.setupChecklist.length} ready; ${counts.recommended} recommended; ${counts.optional} optional; ${counts.blocked} blocked.`, fg: counts.blocked > 0 ? FULLSCREEN_PALETTE.warn : FULLSCREEN_PALETTE.info },
|
|
902406
903216
|
{ text: `Chat: ${snapshot2.provider} / ${snapshot2.modelDisplayName}.`, fg: FULLSCREEN_PALETTE.info },
|
|
902407
903217
|
{ text: `Local: ${snapshot2.localPersonaCount} personas, ${snapshot2.localSkillCount} skills, ${snapshot2.localRoutineCount} routines, ${snapshot2.localMemoryCount} memories.`, fg: FULLSCREEN_PALETTE.info }
|
|
@@ -902539,6 +903349,27 @@ function snapshotLines(workspace, category, snapshot2) {
|
|
|
902539
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));
|
|
902540
903350
|
} else if (category.id === "setup") {
|
|
902541
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 });
|
|
902542
903373
|
} else if (category.id === "artifacts") {
|
|
902543
903374
|
const mediaReady = snapshot2.voiceMediaReadiness.readyMediaProviderCount;
|
|
902544
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 });
|
|
@@ -902549,7 +903380,7 @@ function snapshotLines(workspace, category, snapshot2) {
|
|
|
902549
903380
|
const needsTarget = snapshot2.channels.filter((channel) => channel.setupState === "needs-target");
|
|
902550
903381
|
const needsConfig = snapshot2.channels.filter((channel) => channel.setupState === "needs-config");
|
|
902551
903382
|
const nextAttentionChannel = needsConfig[0] ?? needsTarget[0] ?? snapshot2.channels.find((channel) => !channel.enabled);
|
|
902552
|
-
base2.push({ text: `API: ${snapshot2.runtimeBaseUrl}`, fg: FULLSCREEN_PALETTE.info }, companionAccessLine(snapshot2), { text: `Channels: ${readyCount}/${snapshot2.channels.length} ready; ${enabledCount} enabled; ${configuredDefaults} target(s).`, fg: FULLSCREEN_PALETTE.info }, { text: `Next: ${nextAttentionChannel ? `${nextAttentionChannel.label} - ${compactText3(nextAttentionChannel.nextStep)}` : "All enabled channels ready."}`, fg: nextAttentionChannel ? FULLSCREEN_PALETTE.warn : FULLSCREEN_PALETTE.good }, { text: "
|
|
903383
|
+
base2.push({ text: `API: ${snapshot2.runtimeBaseUrl}`, fg: FULLSCREEN_PALETTE.info }, companionAccessLine(snapshot2), { text: `Channels: ${readyCount}/${snapshot2.channels.length} ready; ${enabledCount} enabled; ${configuredDefaults} target(s).`, fg: FULLSCREEN_PALETTE.info }, { text: `Next: ${nextAttentionChannel ? `${nextAttentionChannel.label} - ${compactText3(nextAttentionChannel.nextStep)}` : "All enabled channels ready."}`, fg: nextAttentionChannel ? FULLSCREEN_PALETTE.warn : FULLSCREEN_PALETTE.good }, { text: "Secrets hidden; sends require explicit action.", fg: FULLSCREEN_PALETTE.warn });
|
|
902553
903384
|
} else if (category.id === "knowledge") {
|
|
902554
903385
|
base2.push({ text: `Route: ${snapshot2.knowledgeRoute}; isolation ${snapshot2.knowledgeIsolation}.`, fg: FULLSCREEN_PALETTE.info }, { text: "Ask/search, ingest, review, reindex, and reports stay Agent-owned.", fg: FULLSCREEN_PALETTE.good }, { text: "Ingest requires explicit confirmation.", fg: FULLSCREEN_PALETTE.warn });
|
|
902555
903386
|
} else if (category.id === "research") {
|
|
@@ -902692,9 +903523,8 @@ function buildActionRows(workspace, width, height) {
|
|
|
902692
903523
|
if (workspace.localEditor)
|
|
902693
903524
|
return buildEditorRows(workspace.localEditor, width, height);
|
|
902694
903525
|
const rows = [];
|
|
902695
|
-
const labelWidth = Math.min(
|
|
902696
|
-
const
|
|
902697
|
-
const commandWidth = Math.max(10, width - labelWidth - safetyWidth - 9);
|
|
903526
|
+
const labelWidth = Math.min(34, Math.max(18, Math.floor(width * 0.38)));
|
|
903527
|
+
const commandWidth = Math.max(10, width - labelWidth - 6);
|
|
902698
903528
|
if (workspace.actionSearchActive) {
|
|
902699
903529
|
rows.push({
|
|
902700
903530
|
text: ` Search: ${workspace.actionSearchQuery || "(type to filter actions)"}`,
|
|
@@ -902703,7 +903533,7 @@ function buildActionRows(workspace, width, height) {
|
|
|
902703
903533
|
});
|
|
902704
903534
|
}
|
|
902705
903535
|
rows.push({
|
|
902706
|
-
text: ` ${padDisplay(workspace.actionSearchActive ? "Result" : "Action", labelWidth)} ${padDisplay("
|
|
903536
|
+
text: ` ${padDisplay(workspace.actionSearchActive ? "Result" : "Action", labelWidth)} ${padDisplay("Does", commandWidth)}`,
|
|
902707
903537
|
fg: FULLSCREEN_PALETTE.muted,
|
|
902708
903538
|
bold: true
|
|
902709
903539
|
});
|
|
@@ -902719,9 +903549,9 @@ function buildActionRows(workspace, width, height) {
|
|
|
902719
903549
|
const label = searchResult ? `${searchResult.category.label} / ${action2.label}` : action2.label;
|
|
902720
903550
|
const marker = selected ? GLYPHS.navigation.selected : " ";
|
|
902721
903551
|
rows.push({
|
|
902722
|
-
text: `${marker} ${padDisplay(label, labelWidth)} ${padDisplay(
|
|
903552
|
+
text: `${marker} ${padDisplay(label, labelWidth)} ${padDisplay(actionCommand(action2), commandWidth)}`,
|
|
902723
903553
|
selected: selected && workspace.focusPane === "actions",
|
|
902724
|
-
fg:
|
|
903554
|
+
fg: action2.safety === "blocked" ? FULLSCREEN_PALETTE.warn : selected ? FULLSCREEN_PALETTE.text : FULLSCREEN_PALETTE.info,
|
|
902725
903555
|
bold: selected
|
|
902726
903556
|
});
|
|
902727
903557
|
}
|
|
@@ -902770,7 +903600,7 @@ function renderAgentWorkspace(workspace, width, height) {
|
|
|
902770
903600
|
title: "GoodVibes Agent / Operator Workspace",
|
|
902771
903601
|
stateLabel: workspace.localEditor ? "Editor" : workspace.actionSearchActive ? "Search" : workspace.focusPane === "categories" ? "Categories" : "Actions",
|
|
902772
903602
|
leftHeader: "Operator Areas",
|
|
902773
|
-
mainHeader: workspace.actionSearchActive ? `Search actions \xB7 ${workspace.actions.length} result(s)` : `${category.label} \xB7 ${
|
|
903603
|
+
mainHeader: workspace.actionSearchActive ? `Search actions \xB7 ${workspace.actions.length} result(s)` : `${category.label} \xB7 ${workspace.actions.length} action(s)`,
|
|
902774
903604
|
leftRows: buildLeftRows2(workspace, metrics.bodyRows),
|
|
902775
903605
|
contextRows: buildContextRows(workspace, category, action2, metrics.contextWidth),
|
|
902776
903606
|
controlRows: buildActionRows(workspace, metrics.contextWidth, metrics.controlRows),
|
|
@@ -902796,17 +903626,20 @@ function normalizeFullscreenViewport(lines, width, height) {
|
|
|
902796
903626
|
viewport.push(createEmptyLine(width));
|
|
902797
903627
|
return viewport;
|
|
902798
903628
|
}
|
|
902799
|
-
function
|
|
903629
|
+
function createFullscreenCompositeFromLines(lines, width, height) {
|
|
902800
903630
|
return {
|
|
902801
903631
|
width,
|
|
902802
903632
|
height,
|
|
902803
903633
|
header: [],
|
|
902804
|
-
viewport: normalizeFullscreenViewport(
|
|
903634
|
+
viewport: normalizeFullscreenViewport(lines, width, height),
|
|
902805
903635
|
footer: [],
|
|
902806
903636
|
forceFullRedraw: true,
|
|
902807
903637
|
panelWidth: 0
|
|
902808
903638
|
};
|
|
902809
903639
|
}
|
|
903640
|
+
function createAgentWorkspaceFullscreenComposite(workspace, width, height) {
|
|
903641
|
+
return createFullscreenCompositeFromLines(renderAgentWorkspace(workspace, width, height), width, height);
|
|
903642
|
+
}
|
|
902810
903643
|
|
|
902811
903644
|
// src/shell/service-settings-sync.ts
|
|
902812
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.";
|
|
@@ -903197,7 +904030,7 @@ function wireShellUiOpeners(options) {
|
|
|
903197
904030
|
}
|
|
903198
904031
|
|
|
903199
904032
|
// src/cli/entrypoint.ts
|
|
903200
|
-
import { existsSync as
|
|
904033
|
+
import { existsSync as existsSync88 } from "fs";
|
|
903201
904034
|
import { join as join98 } from "path";
|
|
903202
904035
|
// src/cli/status.ts
|
|
903203
904036
|
function yesNo3(value) {
|
|
@@ -903805,9 +904638,9 @@ async function prepareShellCliRuntime(argv, roots, binary2 = "goodvibes-agent")
|
|
|
903805
904638
|
onboardingMarkers,
|
|
903806
904639
|
auth: {
|
|
903807
904640
|
userStorePath,
|
|
903808
|
-
userStorePresent:
|
|
904641
|
+
userStorePresent: existsSync88(userStorePath),
|
|
903809
904642
|
bootstrapCredentialPath,
|
|
903810
|
-
bootstrapCredentialPresent:
|
|
904643
|
+
bootstrapCredentialPresent: existsSync88(bootstrapCredentialPath),
|
|
903811
904644
|
operatorTokenPath: effectiveOperatorTokenPath,
|
|
903812
904645
|
operatorTokenPresent: externalRuntime.operatorToken.present
|
|
903813
904646
|
},
|
|
@@ -905315,6 +906148,14 @@ async function main() {
|
|
|
905315
906148
|
input.setPanelMouseLayout(null);
|
|
905316
906149
|
activeConversationWidth = width;
|
|
905317
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
|
+
}
|
|
905318
906159
|
compositor.composite(createAgentWorkspaceFullscreenComposite(input.agentWorkspace, width, height));
|
|
905319
906160
|
return;
|
|
905320
906161
|
}
|