@pellux/goodvibes-agent 1.0.2 → 1.0.4
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/README.md +2 -2
- package/dist/package/main.js +1139 -390
- package/docs/README.md +2 -2
- package/docs/getting-started.md +2 -2
- package/docs/tools-and-commands.md +9 -3
- package/package.json +1 -1
- package/src/cli/help.ts +26 -0
- package/src/tools/agent-harness-cli-metadata.ts +152 -0
- package/src/tools/agent-harness-keybinding-metadata.ts +262 -0
- package/src/tools/agent-harness-metadata.ts +108 -0
- package/src/tools/agent-harness-model-tool-catalog.ts +36 -0
- package/src/tools/agent-harness-panel-metadata.ts +121 -0
- package/src/tools/agent-harness-tool.ts +112 -87
- package/src/version.ts +1 -1
package/dist/package/main.js
CHANGED
|
@@ -389257,6 +389257,23 @@ function createSchema2(db) {
|
|
|
389257
389257
|
`);
|
|
389258
389258
|
db.run(`CREATE INDEX IF NOT EXISTS idx_knowledge_schedules_job_id ON knowledge_schedules(job_id)`);
|
|
389259
389259
|
}
|
|
389260
|
+
function getKnowledgeSchemaStatements() {
|
|
389261
|
+
const statements = [];
|
|
389262
|
+
createSchema2({
|
|
389263
|
+
run(sql) {
|
|
389264
|
+
const normalized = sql.trim();
|
|
389265
|
+
if (normalized.length > 0)
|
|
389266
|
+
statements.push(normalized);
|
|
389267
|
+
}
|
|
389268
|
+
});
|
|
389269
|
+
return statements;
|
|
389270
|
+
}
|
|
389271
|
+
function renderKnowledgeSchemaSql() {
|
|
389272
|
+
return `${getKnowledgeSchemaStatements().map((statement) => statement.endsWith(";") ? statement : `${statement};`).join(`
|
|
389273
|
+
|
|
389274
|
+
`)}
|
|
389275
|
+
`;
|
|
389276
|
+
}
|
|
389260
389277
|
function rowObject(columns, values2) {
|
|
389261
389278
|
return Object.fromEntries(columns.map((column, index) => [column, values2[index]]));
|
|
389262
389279
|
}
|
|
@@ -702594,6 +702611,9 @@ var init_ingest = __esm(() => {
|
|
|
702594
702611
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/browser-history/index.js
|
|
702595
702612
|
var init_browser_history = __esm(() => {
|
|
702596
702613
|
init_ingest();
|
|
702614
|
+
init_discover();
|
|
702615
|
+
init_readers();
|
|
702616
|
+
init_paths2();
|
|
702597
702617
|
});
|
|
702598
702618
|
|
|
702599
702619
|
// node_modules/graphql/jsutils/devAssert.mjs
|
|
@@ -720233,6 +720253,7 @@ var init_semantic = __esm(() => {
|
|
|
720233
720253
|
init_llm();
|
|
720234
720254
|
init_gap_repair();
|
|
720235
720255
|
init_service4();
|
|
720256
|
+
init_self_improvement();
|
|
720236
720257
|
});
|
|
720237
720258
|
|
|
720238
720259
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/home-graph/helpers.js
|
|
@@ -724201,8 +724222,40 @@ var init_map_view = __esm(() => {
|
|
|
724201
724222
|
});
|
|
724202
724223
|
|
|
724203
724224
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/home-graph/types.js
|
|
724204
|
-
var HOME_GRAPH_CAPABILITIES;
|
|
724225
|
+
var HOME_GRAPH_NODE_KINDS, HOME_GRAPH_RELATIONS, HOME_GRAPH_CAPABILITIES;
|
|
724205
724226
|
var init_types6 = __esm(() => {
|
|
724227
|
+
HOME_GRAPH_NODE_KINDS = [
|
|
724228
|
+
"ha_home",
|
|
724229
|
+
"ha_entity",
|
|
724230
|
+
"ha_device",
|
|
724231
|
+
"ha_area",
|
|
724232
|
+
"ha_automation",
|
|
724233
|
+
"ha_script",
|
|
724234
|
+
"ha_scene",
|
|
724235
|
+
"ha_label",
|
|
724236
|
+
"ha_integration",
|
|
724237
|
+
"ha_room",
|
|
724238
|
+
"ha_device_passport",
|
|
724239
|
+
"ha_maintenance_item",
|
|
724240
|
+
"ha_troubleshooting_case",
|
|
724241
|
+
"ha_purchase",
|
|
724242
|
+
"ha_network_node"
|
|
724243
|
+
];
|
|
724244
|
+
HOME_GRAPH_RELATIONS = [
|
|
724245
|
+
"controls",
|
|
724246
|
+
"located_in",
|
|
724247
|
+
"belongs_to_device",
|
|
724248
|
+
"has_manual",
|
|
724249
|
+
"has_receipt",
|
|
724250
|
+
"has_warranty",
|
|
724251
|
+
"has_issue",
|
|
724252
|
+
"fixed_by",
|
|
724253
|
+
"uses_battery",
|
|
724254
|
+
"connected_via",
|
|
724255
|
+
"part_of_network",
|
|
724256
|
+
"mentioned_by",
|
|
724257
|
+
"source_for"
|
|
724258
|
+
];
|
|
724206
724259
|
HOME_GRAPH_CAPABILITIES = [
|
|
724207
724260
|
"knowledge-space-isolation",
|
|
724208
724261
|
"snapshot-sync",
|
|
@@ -725609,6 +725662,7 @@ var init_service5 = __esm(() => {
|
|
|
725609
725662
|
var init_home_graph = __esm(() => {
|
|
725610
725663
|
init_service5();
|
|
725611
725664
|
init_extension();
|
|
725665
|
+
init_types6();
|
|
725612
725666
|
});
|
|
725613
725667
|
|
|
725614
725668
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/store-refinement.js
|
|
@@ -727936,10 +727990,14 @@ var init_service6 = __esm(() => {
|
|
|
727936
727990
|
var init_project_planning = __esm(() => {
|
|
727937
727991
|
init_service6();
|
|
727938
727992
|
init_helpers3();
|
|
727993
|
+
init_readiness();
|
|
727939
727994
|
});
|
|
727940
727995
|
|
|
727941
727996
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/persistence.js
|
|
727942
|
-
var init_persistence = () => {
|
|
727997
|
+
var init_persistence = __esm(() => {
|
|
727998
|
+
init_store_schema();
|
|
727999
|
+
init_store_load();
|
|
728000
|
+
});
|
|
727943
728001
|
|
|
727944
728002
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/projections.js
|
|
727945
728003
|
class KnowledgeProjectionService {
|
|
@@ -731447,21 +731505,21 @@ var init_service7 = __esm(() => {
|
|
|
731447
731505
|
var exports_knowledge = {};
|
|
731448
731506
|
__export(exports_knowledge, {
|
|
731449
731507
|
withKnowledgeSpace: () => withKnowledgeSpace,
|
|
731450
|
-
uniqKnowledgeValues: () =>
|
|
731451
|
-
stabilizeKnowledgeText: () =>
|
|
731452
|
-
runKnowledgeSemanticSelfImprovement: () =>
|
|
731508
|
+
uniqKnowledgeValues: () => uniq2,
|
|
731509
|
+
stabilizeKnowledgeText: () => stableText,
|
|
731510
|
+
runKnowledgeSemanticSelfImprovement: () => runKnowledgeSemanticSelfImprovement,
|
|
731453
731511
|
resolveProjectPlanningSpace: () => resolveProjectPlanningSpace,
|
|
731454
|
-
resolveKnowledgeDbPathFromControlPlaneDir: () =>
|
|
731512
|
+
resolveKnowledgeDbPathFromControlPlaneDir: () => resolveKnowledgeDbPathFromControlPlaneDir,
|
|
731455
731513
|
renderPacket: () => renderPacket,
|
|
731456
731514
|
renderKnowledgeSchemaSql: () => renderKnowledgeSchemaSql,
|
|
731457
731515
|
renderKnowledgeMap: () => renderKnowledgeMap,
|
|
731458
731516
|
readKnowledgeSearchText: () => readKnowledgeSearchText,
|
|
731459
|
-
readBrowserKnowledgeProfile: () =>
|
|
731517
|
+
readBrowserKnowledgeProfile: () => readBrowserKnowledgeProfile,
|
|
731460
731518
|
projectPlanningSourceId: () => projectPlanningSourceId,
|
|
731461
731519
|
projectPlanningProjectIdFromPath: () => projectPlanningProjectIdFromPath,
|
|
731462
731520
|
projectPlanningCanonicalUri: () => projectPlanningCanonicalUri,
|
|
731463
731521
|
projectKnowledgeSpaceId: () => projectKnowledgeSpaceId,
|
|
731464
|
-
parseKnowledgeJsonValue: () =>
|
|
731522
|
+
parseKnowledgeJsonValue: () => parseJsonValue,
|
|
731465
731523
|
normalizeProjectId: () => normalizeProjectId,
|
|
731466
731524
|
normalizeKnowledgeSpaceId: () => normalizeKnowledgeSpaceId,
|
|
731467
731525
|
normalizeHomeAssistantInstallationId: () => normalizeHomeAssistantInstallationId,
|
|
@@ -731469,12 +731527,12 @@ __export(exports_knowledge, {
|
|
|
731469
731527
|
materializeGeneratedKnowledgeProjection: () => materializeGeneratedKnowledgeProjection,
|
|
731470
731528
|
looksLikeRawPdfPayload: () => looksLikeRawPdfPayload,
|
|
731471
731529
|
looksBinaryLikeText: () => looksBinaryLikeText,
|
|
731472
|
-
loadKnowledgeStoreSnapshot: () =>
|
|
731530
|
+
loadKnowledgeStoreSnapshot: () => loadKnowledgeStoreSnapshot,
|
|
731473
731531
|
listGeneratedKnowledgePages: () => listGeneratedKnowledgePages,
|
|
731474
|
-
listBrowserKinds: () =>
|
|
731532
|
+
listBrowserKinds: () => listBrowserKinds,
|
|
731475
731533
|
knowledgeSpaceMetadata: () => knowledgeSpaceMetadata,
|
|
731476
731534
|
knowledgePageSourceWeight: () => knowledgePageSourceWeight,
|
|
731477
|
-
knowledgeNowMs: () =>
|
|
731535
|
+
knowledgeNowMs: () => nowMs,
|
|
731478
731536
|
knowledgeExtractionNeedsRefresh: () => knowledgeExtractionNeedsRefresh,
|
|
731479
731537
|
isUsefulKnowledgePageSourceCandidate: () => isUsefulKnowledgePageSourceCandidate,
|
|
731480
731538
|
isUsefulKnowledgePageSource: () => isUsefulKnowledgePageSource,
|
|
@@ -731494,12 +731552,12 @@ __export(exports_knowledge, {
|
|
|
731494
731552
|
generatedKnowledgeSourceId: () => generatedKnowledgeSourceId,
|
|
731495
731553
|
generatedKnowledgeCanonicalUri: () => generatedKnowledgeCanonicalUri,
|
|
731496
731554
|
extractKnowledgeArtifact: () => extractKnowledgeArtifact,
|
|
731497
|
-
evaluateProjectPlanningReadiness: () =>
|
|
731498
|
-
discoverBrowserKnowledgeProfiles: () =>
|
|
731555
|
+
evaluateProjectPlanningReadiness: () => evaluateProjectPlanningReadiness,
|
|
731556
|
+
discoverBrowserKnowledgeProfiles: () => discoverBrowserKnowledgeProfiles,
|
|
731499
731557
|
createWebKnowledgeGapRepairer: () => createWebKnowledgeGapRepairer,
|
|
731500
731558
|
createProviderBackedKnowledgeSemanticLlm: () => createProviderBackedKnowledgeSemanticLlm,
|
|
731501
731559
|
createMemoryApi: () => createMemoryApi,
|
|
731502
|
-
createKnowledgeSchema: () =>
|
|
731560
|
+
createKnowledgeSchema: () => createSchema2,
|
|
731503
731561
|
createKnowledgeApi: () => createKnowledgeApi,
|
|
731504
731562
|
createDefaultKnowledgeConnectorRegistry: () => createDefaultKnowledgeConnectorRegistry,
|
|
731505
731563
|
compareKnowledgePageSources: () => compareKnowledgePageSources,
|
|
@@ -733937,7 +733995,7 @@ var init_delivery_manager = __esm(() => {
|
|
|
733937
733995
|
});
|
|
733938
733996
|
|
|
733939
733997
|
// node_modules/@pellux/goodvibes-sdk/dist/platform/automation/scheduler-capacity.js
|
|
733940
|
-
function computeSchedulerCapacity(slotsTotal, runs,
|
|
733998
|
+
function computeSchedulerCapacity(slotsTotal, runs, nowMs2 = Date.now()) {
|
|
733941
733999
|
let slotsInUse = 0;
|
|
733942
734000
|
const queuedRuns = [];
|
|
733943
734001
|
for (const run7 of runs) {
|
|
@@ -733947,7 +734005,7 @@ function computeSchedulerCapacity(slotsTotal, runs, nowMs3 = Date.now()) {
|
|
|
733947
734005
|
queuedRuns.push(run7);
|
|
733948
734006
|
}
|
|
733949
734007
|
const queueDepth = queuedRuns.length;
|
|
733950
|
-
const oldestQueuedAgeMs = queueDepth > 0 ?
|
|
734008
|
+
const oldestQueuedAgeMs = queueDepth > 0 ? nowMs2 - Math.min(...queuedRuns.map((r5) => r5.queuedAt)) : null;
|
|
733951
734009
|
return { slotsTotal, slotsInUse, queueDepth, oldestQueuedAgeMs };
|
|
733952
734010
|
}
|
|
733953
734011
|
|
|
@@ -816508,7 +816566,7 @@ var createStyledCell = (char, overrides = {}) => ({
|
|
|
816508
816566
|
// src/version.ts
|
|
816509
816567
|
import { readFileSync } from "fs";
|
|
816510
816568
|
import { join } from "path";
|
|
816511
|
-
var _version = "1.0.
|
|
816569
|
+
var _version = "1.0.4";
|
|
816512
816570
|
var _sdkVersion = "0.33.35";
|
|
816513
816571
|
try {
|
|
816514
816572
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, "..", "package.json"), "utf-8"));
|
|
@@ -821139,7 +821197,7 @@ var INBOUND_EVENT_SURFACE_KINDS = new Set([
|
|
|
821139
821197
|
]);
|
|
821140
821198
|
// src/runtime/onboarding/apply.ts
|
|
821141
821199
|
init_config8();
|
|
821142
|
-
import { existsSync as
|
|
821200
|
+
import { existsSync as existsSync85, readFileSync as readFileSync91, rmSync as rmSync10 } from "fs";
|
|
821143
821201
|
|
|
821144
821202
|
// src/agent/runtime-profile.ts
|
|
821145
821203
|
import { existsSync as existsSync43, mkdirSync as mkdirSync32, readFileSync as readFileSync48, readdirSync as readdirSync15, rmSync as rmSync5, statSync as statSync13, writeFileSync as writeFileSync29 } from "fs";
|
|
@@ -839370,7 +839428,7 @@ var WORK_PLAN_STATUSES = [
|
|
|
839370
839428
|
"failed",
|
|
839371
839429
|
"cancelled"
|
|
839372
839430
|
];
|
|
839373
|
-
function
|
|
839431
|
+
function nowMs2() {
|
|
839374
839432
|
return Date.now();
|
|
839375
839433
|
}
|
|
839376
839434
|
function isObject5(value) {
|
|
@@ -839476,7 +839534,7 @@ class WorkPlanStore {
|
|
|
839476
839534
|
if (!normalizedTitle)
|
|
839477
839535
|
throw new Error("Work plan item title is required.");
|
|
839478
839536
|
const plan = this.readPlan();
|
|
839479
|
-
const time4 =
|
|
839537
|
+
const time4 = nowMs2();
|
|
839480
839538
|
const item = {
|
|
839481
839539
|
id: createItemId(),
|
|
839482
839540
|
title: normalizedTitle,
|
|
@@ -839500,7 +839558,7 @@ class WorkPlanStore {
|
|
|
839500
839558
|
updateItem(idOrPrefix, patch2) {
|
|
839501
839559
|
const plan = this.readPlan();
|
|
839502
839560
|
const item = this.resolveItem(plan, idOrPrefix);
|
|
839503
|
-
const time4 =
|
|
839561
|
+
const time4 = nowMs2();
|
|
839504
839562
|
const nextStatus = patch2.status ?? item.status;
|
|
839505
839563
|
const next = this.pruneItem({
|
|
839506
839564
|
...item,
|
|
@@ -839533,7 +839591,7 @@ class WorkPlanStore {
|
|
|
839533
839591
|
removeItem(idOrPrefix) {
|
|
839534
839592
|
const plan = this.readPlan();
|
|
839535
839593
|
const item = this.resolveItem(plan, idOrPrefix);
|
|
839536
|
-
const time4 =
|
|
839594
|
+
const time4 = nowMs2();
|
|
839537
839595
|
const remaining = plan.items.filter((candidate) => candidate.id !== item.id);
|
|
839538
839596
|
this.writePlan({
|
|
839539
839597
|
...plan,
|
|
@@ -839553,7 +839611,7 @@ class WorkPlanStore {
|
|
|
839553
839611
|
...plan,
|
|
839554
839612
|
items: remaining,
|
|
839555
839613
|
activeItemId: remaining[0]?.id,
|
|
839556
|
-
updatedAt:
|
|
839614
|
+
updatedAt: nowMs2()
|
|
839557
839615
|
});
|
|
839558
839616
|
return removed;
|
|
839559
839617
|
}
|
|
@@ -839592,7 +839650,7 @@ class WorkPlanStore {
|
|
|
839592
839650
|
const parsed = JSON.parse(raw);
|
|
839593
839651
|
if (!isObject5(parsed))
|
|
839594
839652
|
return this.createEmptyPlan();
|
|
839595
|
-
const time4 =
|
|
839653
|
+
const time4 = nowMs2();
|
|
839596
839654
|
const createdAt = typeof parsed.createdAt === "number" ? parsed.createdAt : time4;
|
|
839597
839655
|
const updatedAt = typeof parsed.updatedAt === "number" ? parsed.updatedAt : createdAt;
|
|
839598
839656
|
const items = Array.isArray(parsed.items) ? parsed.items.map((item) => normalizeItem(item, createdAt)).filter((item) => item !== null) : [];
|
|
@@ -839611,7 +839669,7 @@ class WorkPlanStore {
|
|
|
839611
839669
|
};
|
|
839612
839670
|
}
|
|
839613
839671
|
createEmptyPlan() {
|
|
839614
|
-
const time4 =
|
|
839672
|
+
const time4 = nowMs2();
|
|
839615
839673
|
return {
|
|
839616
839674
|
id: createPlanId(this.options.projectId, this.options.projectRoot),
|
|
839617
839675
|
projectId: this.options.projectId,
|
|
@@ -847717,13 +847775,13 @@ init_state3();
|
|
|
847717
847775
|
|
|
847718
847776
|
// src/input/commands/recall-shared.ts
|
|
847719
847777
|
var VALID_CLASSES = ["decision", "constraint", "incident", "pattern", "fact", "risk", "runbook", "architecture", "ownership"];
|
|
847720
|
-
var
|
|
847778
|
+
var VALID_SCOPES = ["session", "project", "team"];
|
|
847721
847779
|
var VALID_REVIEW_STATES = ["fresh", "reviewed", "stale", "contradicted"];
|
|
847722
847780
|
function isValidClass(s4) {
|
|
847723
847781
|
return VALID_CLASSES.includes(s4);
|
|
847724
847782
|
}
|
|
847725
847783
|
function isValidScope(s4) {
|
|
847726
|
-
return
|
|
847784
|
+
return VALID_SCOPES.includes(s4);
|
|
847727
847785
|
}
|
|
847728
847786
|
function isValidReviewState(s4) {
|
|
847729
847787
|
return VALID_REVIEW_STATES.includes(s4);
|
|
@@ -847766,7 +847824,7 @@ function handleRecallSearch(args2, context) {
|
|
|
847766
847824
|
if (isValidScope(scope))
|
|
847767
847825
|
filter.scope = scope;
|
|
847768
847826
|
else {
|
|
847769
|
-
context.print(`[memory] Unknown scope "${scope}". Valid values ${
|
|
847827
|
+
context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
847770
847828
|
return;
|
|
847771
847829
|
}
|
|
847772
847830
|
}
|
|
@@ -847941,7 +847999,7 @@ function handleRecallList(args2, context) {
|
|
|
847941
847999
|
if (scopeIdx !== -1 && args2[scopeIdx + 1]) {
|
|
847942
848000
|
const scope = args2[scopeIdx + 1];
|
|
847943
848001
|
if (!isValidScope(scope)) {
|
|
847944
|
-
context.print(`[memory] Unknown scope "${scope}". Valid values ${
|
|
848002
|
+
context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
847945
848003
|
return;
|
|
847946
848004
|
}
|
|
847947
848005
|
filter.scope = scope;
|
|
@@ -847991,7 +848049,7 @@ async function handleRecallAdd(args2, context) {
|
|
|
847991
848049
|
const tags = tagsRaw ? tagsRaw.split(",").map((token) => token.trim()).filter(Boolean) : [];
|
|
847992
848050
|
const scope = scopeRaw && isValidScope(scopeRaw) ? scopeRaw : "project";
|
|
847993
848051
|
if (scopeRaw && !isValidScope(scopeRaw)) {
|
|
847994
|
-
context.print(`[memory] Invalid scope "${scopeRaw}". Valid values ${
|
|
848052
|
+
context.print(`[memory] Invalid scope "${scopeRaw}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
847995
848053
|
return;
|
|
847996
848054
|
}
|
|
847997
848055
|
const provenance = [];
|
|
@@ -848125,7 +848183,7 @@ function handleRecallExport(args2, context) {
|
|
|
848125
848183
|
if (scopeIdx !== -1 && commandArgs[scopeIdx + 1]) {
|
|
848126
848184
|
const scope = commandArgs[scopeIdx + 1];
|
|
848127
848185
|
if (!isValidScope(scope)) {
|
|
848128
|
-
context.print(`[memory] Unknown scope "${scope}". Valid values ${
|
|
848186
|
+
context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
848129
848187
|
return;
|
|
848130
848188
|
}
|
|
848131
848189
|
filter.scope = scope;
|
|
@@ -848204,7 +848262,7 @@ function handleRecallHandoffExport(args2, context) {
|
|
|
848204
848262
|
const scopeIdx = commandArgs.indexOf("--scope");
|
|
848205
848263
|
const scopeRaw = scopeIdx !== -1 ? commandArgs[scopeIdx + 1] : "team";
|
|
848206
848264
|
if (!scopeRaw || !isValidScope(scopeRaw)) {
|
|
848207
|
-
context.print(`[memory] Unknown scope "${scopeRaw ?? ""}". Valid values ${
|
|
848265
|
+
context.print(`[memory] Unknown scope "${scopeRaw ?? ""}". Valid values ${VALID_SCOPES.join(", ")}.`);
|
|
848208
848266
|
return;
|
|
848209
848267
|
}
|
|
848210
848268
|
const bundle = memory.exportBundle({ scope: scopeRaw });
|
|
@@ -848320,7 +848378,7 @@ function handleRecallPromote(args2, context) {
|
|
|
848320
848378
|
const id = parsed.rest[0];
|
|
848321
848379
|
const scope = parsed.rest[1];
|
|
848322
848380
|
if (!id || !scope || !isValidScope(scope)) {
|
|
848323
|
-
context.print(`[memory] Usage: /memory promote <id> <${
|
|
848381
|
+
context.print(`[memory] Usage: /memory promote <id> <${VALID_SCOPES.join("|")}> --yes`);
|
|
848324
848382
|
return;
|
|
848325
848383
|
}
|
|
848326
848384
|
if (!parsed.yes) {
|
|
@@ -859718,6 +859776,20 @@ function normalizeHelpTopic(topic) {
|
|
|
859718
859776
|
const normalized = topic.trim().toLowerCase();
|
|
859719
859777
|
return HELP_ALIASES[normalized] ?? normalized;
|
|
859720
859778
|
}
|
|
859779
|
+
function describeGoodVibesCommandHelp(topic) {
|
|
859780
|
+
const normalized = normalizeHelpTopic(topic);
|
|
859781
|
+
const help = COMMAND_HELP[normalized];
|
|
859782
|
+
if (!help)
|
|
859783
|
+
return null;
|
|
859784
|
+
return {
|
|
859785
|
+
command: normalized,
|
|
859786
|
+
aliases: Object.entries(HELP_ALIASES).filter(([, target]) => target === normalized).map(([alias]) => alias).sort(),
|
|
859787
|
+
summary: help.summary,
|
|
859788
|
+
usage: help.usage,
|
|
859789
|
+
subcommands: help.subcommands ?? [],
|
|
859790
|
+
examples: help.examples ?? []
|
|
859791
|
+
};
|
|
859792
|
+
}
|
|
859721
859793
|
function renderGoodVibesCommandHelp(topic, binary2 = "goodvibes-agent") {
|
|
859722
859794
|
const normalized = normalizeHelpTopic(topic);
|
|
859723
859795
|
const help = COMMAND_HELP[normalized];
|
|
@@ -860388,6 +860460,15 @@ var BLOCKED_PRODUCT_COMMAND_HINTS = {
|
|
|
860388
860460
|
web: () => "Unsupported command: web. GoodVibes Agent does not start web servers or expose browser routes.",
|
|
860389
860461
|
webhook: () => "Unsupported command: webhook. GoodVibes Agent can send explicit channel messages, but it does not create webhook listeners."
|
|
860390
860462
|
};
|
|
860463
|
+
function listGoodVibesCliCommandTokens() {
|
|
860464
|
+
return Object.keys(COMMAND_ALIASES).sort();
|
|
860465
|
+
}
|
|
860466
|
+
function listGoodVibesCliCommands() {
|
|
860467
|
+
return [...new Set(["tui", ...Object.values(COMMAND_ALIASES)])].sort();
|
|
860468
|
+
}
|
|
860469
|
+
function listBlockedGoodVibesCliCommandTokens() {
|
|
860470
|
+
return Object.keys(BLOCKED_PRODUCT_COMMAND_HINTS).sort();
|
|
860471
|
+
}
|
|
860391
860472
|
function createDefaultFlags() {
|
|
860392
860473
|
return {
|
|
860393
860474
|
provider: undefined,
|
|
@@ -862073,7 +862154,7 @@ import { mkdirSync as mkdirSync64, readFileSync as readFileSync86, writeFileSync
|
|
|
862073
862154
|
import { dirname as dirname63, resolve as resolve39 } from "path";
|
|
862074
862155
|
init_state3();
|
|
862075
862156
|
var VALID_CLASSES2 = ["decision", "constraint", "incident", "pattern", "fact", "risk", "runbook", "architecture", "ownership"];
|
|
862076
|
-
var
|
|
862157
|
+
var VALID_SCOPES3 = ["session", "project", "team"];
|
|
862077
862158
|
var VALID_REVIEW_STATES3 = ["fresh", "reviewed", "stale", "contradicted"];
|
|
862078
862159
|
var VALID_PROVENANCE_KINDS = ["session", "turn", "task", "event", "file"];
|
|
862079
862160
|
var VALUE_OPTIONS = new Set([
|
|
@@ -862173,7 +862254,7 @@ function isMemoryClass2(value) {
|
|
|
862173
862254
|
return VALID_CLASSES2.includes(value);
|
|
862174
862255
|
}
|
|
862175
862256
|
function isMemoryScope2(value) {
|
|
862176
|
-
return
|
|
862257
|
+
return VALID_SCOPES3.includes(value);
|
|
862177
862258
|
}
|
|
862178
862259
|
function isReviewState(value) {
|
|
862179
862260
|
return VALID_REVIEW_STATES3.includes(value);
|
|
@@ -862188,7 +862269,7 @@ function requireClass(value) {
|
|
|
862188
862269
|
}
|
|
862189
862270
|
function requireScope(value) {
|
|
862190
862271
|
if (!value || !isMemoryScope2(value))
|
|
862191
|
-
throw new Error(`Invalid memory scope "${value ?? ""}". Valid values ${
|
|
862272
|
+
throw new Error(`Invalid memory scope "${value ?? ""}". Valid values ${VALID_SCOPES3.join(", ")}`);
|
|
862192
862273
|
return value;
|
|
862193
862274
|
}
|
|
862194
862275
|
function optionalScope(value) {
|
|
@@ -879137,224 +879218,6 @@ function actionSearchStatus(host) {
|
|
|
879137
879218
|
return count === 0 ? `No Agent workspace actions match "${host.actionSearchQuery}".` : `Found ${count} Agent workspace action(s) for "${host.actionSearchQuery}".`;
|
|
879138
879219
|
}
|
|
879139
879220
|
|
|
879140
|
-
// src/tools/agent-harness-local-operations.ts
|
|
879141
|
-
function output6(value) {
|
|
879142
|
-
return { success: true, output: typeof value === "string" ? value : JSON.stringify(value, null, 2) };
|
|
879143
|
-
}
|
|
879144
|
-
function error51(message) {
|
|
879145
|
-
return { success: false, error: message };
|
|
879146
|
-
}
|
|
879147
|
-
function readString50(value) {
|
|
879148
|
-
return typeof value === "string" ? value.trim() : "";
|
|
879149
|
-
}
|
|
879150
|
-
function readFieldMap(value) {
|
|
879151
|
-
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
879152
|
-
return {};
|
|
879153
|
-
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, typeof entry === "string" ? entry : String(entry)]));
|
|
879154
|
-
}
|
|
879155
|
-
function describeEditor(editor) {
|
|
879156
|
-
return {
|
|
879157
|
-
kind: editor.kind,
|
|
879158
|
-
mode: editor.mode,
|
|
879159
|
-
recordId: editor.recordId,
|
|
879160
|
-
title: editor.title,
|
|
879161
|
-
message: editor.message,
|
|
879162
|
-
fields: editor.fields.map((field) => ({
|
|
879163
|
-
id: field.id,
|
|
879164
|
-
label: field.label,
|
|
879165
|
-
required: field.required,
|
|
879166
|
-
multiline: field.multiline,
|
|
879167
|
-
hint: field.hint,
|
|
879168
|
-
default: field.redact ? "<redacted>" : field.value
|
|
879169
|
-
}))
|
|
879170
|
-
};
|
|
879171
|
-
}
|
|
879172
|
-
function readRecordId(args2) {
|
|
879173
|
-
const fields = readFieldMap(args2.fields);
|
|
879174
|
-
return readString50(args2.recordId ?? args2.id ?? fields.recordId ?? fields.id);
|
|
879175
|
-
}
|
|
879176
|
-
function requireConfirmed(args2, label) {
|
|
879177
|
-
if (!readString50(args2.explicitUserRequest))
|
|
879178
|
-
return `${label} requires explicitUserRequest with the user's exact request or a short faithful summary.`;
|
|
879179
|
-
if (args2.confirm !== true)
|
|
879180
|
-
return `${label} requires confirm:true after an explicit user request.`;
|
|
879181
|
-
return null;
|
|
879182
|
-
}
|
|
879183
|
-
function fieldReader(editor, fields) {
|
|
879184
|
-
return (id) => fields[id] ?? editor.fields.find((field) => field.id === id)?.value ?? "";
|
|
879185
|
-
}
|
|
879186
|
-
function hasExecutionFields(args2) {
|
|
879187
|
-
return Object.keys(readFieldMap(args2.fields)).some((key) => key !== "id" && key !== "recordId");
|
|
879188
|
-
}
|
|
879189
|
-
function missingRequiredFields(editor, fields) {
|
|
879190
|
-
const read = fieldReader(editor, fields);
|
|
879191
|
-
return editor.fields.filter((field) => field.required && !read(field.id).trim()).map((field) => field.id);
|
|
879192
|
-
}
|
|
879193
|
-
function registryTarget(operation) {
|
|
879194
|
-
if (operation === "memory-edit")
|
|
879195
|
-
return { domain: "memory", action: "update", requiresRecordId: true };
|
|
879196
|
-
if (operation === "memory-review")
|
|
879197
|
-
return { domain: "memory", action: "review", requiresRecordId: true };
|
|
879198
|
-
if (operation === "memory-stale")
|
|
879199
|
-
return { domain: "memory", action: "stale", requiresRecordId: true };
|
|
879200
|
-
if (operation === "memory-delete")
|
|
879201
|
-
return { domain: "memory", action: "delete", requiresRecordId: true };
|
|
879202
|
-
if (operation === "note-edit")
|
|
879203
|
-
return { domain: "note", action: "update", requiresRecordId: true };
|
|
879204
|
-
if (operation === "note-review")
|
|
879205
|
-
return { domain: "note", action: "review", requiresRecordId: true };
|
|
879206
|
-
if (operation === "note-stale")
|
|
879207
|
-
return { domain: "note", action: "stale", requiresRecordId: true };
|
|
879208
|
-
if (operation === "note-delete")
|
|
879209
|
-
return { domain: "note", action: "delete", requiresRecordId: true };
|
|
879210
|
-
if (operation === "persona-edit")
|
|
879211
|
-
return { domain: "persona", action: "update", requiresRecordId: true };
|
|
879212
|
-
if (operation === "persona-use")
|
|
879213
|
-
return { domain: "persona", action: "use", requiresRecordId: true };
|
|
879214
|
-
if (operation === "persona-review")
|
|
879215
|
-
return { domain: "persona", action: "review", requiresRecordId: true };
|
|
879216
|
-
if (operation === "persona-clear")
|
|
879217
|
-
return { domain: "persona", action: "clear_active", requiresRecordId: false };
|
|
879218
|
-
if (operation === "persona-delete")
|
|
879219
|
-
return { domain: "persona", action: "delete", requiresRecordId: true };
|
|
879220
|
-
if (operation === "skill-edit")
|
|
879221
|
-
return { domain: "skill", action: "update", requiresRecordId: true };
|
|
879222
|
-
if (operation === "skill-enable")
|
|
879223
|
-
return { domain: "skill", action: "enable", requiresRecordId: true };
|
|
879224
|
-
if (operation === "skill-disable")
|
|
879225
|
-
return { domain: "skill", action: "disable", requiresRecordId: true };
|
|
879226
|
-
if (operation === "skill-review")
|
|
879227
|
-
return { domain: "skill", action: "review", requiresRecordId: true };
|
|
879228
|
-
if (operation === "skill-delete")
|
|
879229
|
-
return { domain: "skill", action: "delete", requiresRecordId: true };
|
|
879230
|
-
if (operation === "routine-edit")
|
|
879231
|
-
return { domain: "routine", action: "update", requiresRecordId: true };
|
|
879232
|
-
if (operation === "routine-start")
|
|
879233
|
-
return { domain: "routine", action: "start", requiresRecordId: true };
|
|
879234
|
-
if (operation === "routine-enable")
|
|
879235
|
-
return { domain: "routine", action: "enable", requiresRecordId: true };
|
|
879236
|
-
if (operation === "routine-disable")
|
|
879237
|
-
return { domain: "routine", action: "disable", requiresRecordId: true };
|
|
879238
|
-
if (operation === "routine-review")
|
|
879239
|
-
return { domain: "routine", action: "review", requiresRecordId: true };
|
|
879240
|
-
if (operation === "routine-delete")
|
|
879241
|
-
return { domain: "routine", action: "delete", requiresRecordId: true };
|
|
879242
|
-
return null;
|
|
879243
|
-
}
|
|
879244
|
-
function editorForOperation(context, operation, recordId) {
|
|
879245
|
-
const shellPaths3 = context.workspace.shellPaths;
|
|
879246
|
-
if (operation === "memory-edit") {
|
|
879247
|
-
const record2 = context.clients?.agentKnowledgeApi?.memory?.get(recordId);
|
|
879248
|
-
return record2 ? createMemoryUpdateEditor(record2) : null;
|
|
879249
|
-
}
|
|
879250
|
-
if (!shellPaths3)
|
|
879251
|
-
return null;
|
|
879252
|
-
if (operation === "note-edit") {
|
|
879253
|
-
const note = AgentNoteRegistry.fromShellPaths(shellPaths3).get(recordId);
|
|
879254
|
-
return note ? createNoteUpdateEditor(note) : null;
|
|
879255
|
-
}
|
|
879256
|
-
if (operation === "note-promote-memory" || operation === "note-promote-persona" || operation === "note-promote-skill" || operation === "note-promote-routine" || operation === "note-promote-knowledge-url") {
|
|
879257
|
-
const note = AgentNoteRegistry.fromShellPaths(shellPaths3).get(recordId);
|
|
879258
|
-
if (!note)
|
|
879259
|
-
return null;
|
|
879260
|
-
if (operation === "note-promote-memory")
|
|
879261
|
-
return createMemoryEditorFromNote(note);
|
|
879262
|
-
if (operation === "note-promote-persona")
|
|
879263
|
-
return createPersonaEditorFromNote(note);
|
|
879264
|
-
if (operation === "note-promote-skill")
|
|
879265
|
-
return createSkillEditorFromNote(note);
|
|
879266
|
-
if (operation === "note-promote-routine")
|
|
879267
|
-
return createRoutineEditorFromNote(note);
|
|
879268
|
-
return note.sourceUrl ? createKnowledgeUrlEditorFromNote(note) : null;
|
|
879269
|
-
}
|
|
879270
|
-
if (operation === "persona-edit") {
|
|
879271
|
-
const registry5 = AgentPersonaRegistry.fromShellPaths(shellPaths3);
|
|
879272
|
-
const persona = registry5.get(recordId);
|
|
879273
|
-
return persona ? createPersonaUpdateEditor(persona, registry5.snapshot().activePersonaId === persona.id) : null;
|
|
879274
|
-
}
|
|
879275
|
-
if (operation === "skill-edit") {
|
|
879276
|
-
const skill = AgentSkillRegistry.fromShellPaths(shellPaths3).get(recordId);
|
|
879277
|
-
return skill ? createSkillUpdateEditor(skill) : null;
|
|
879278
|
-
}
|
|
879279
|
-
if (operation === "routine-edit") {
|
|
879280
|
-
const routine = AgentRoutineRegistry.fromShellPaths(shellPaths3).get(recordId);
|
|
879281
|
-
return routine ? createRoutineUpdateEditor(routine) : null;
|
|
879282
|
-
}
|
|
879283
|
-
return null;
|
|
879284
|
-
}
|
|
879285
|
-
function localRegistryArgsFromEditor(editor, fields, id) {
|
|
879286
|
-
const read = fieldReader(editor, fields);
|
|
879287
|
-
if (editor.kind === "memory")
|
|
879288
|
-
return { domain: "memory", action: editor.mode === "update" ? "update" : "create", id, cls: read("cls"), scope: read("scope"), summary: read("summary"), detail: read("detail"), tags: splitList5(read("tags")), confidence: read("confidence"), provenance: editor.recordId ? "agent-harness-local-operation" : "agent-harness-note-promotion" };
|
|
879289
|
-
if (editor.kind === "note")
|
|
879290
|
-
return { domain: "note", action: "update", id, title: read("title"), body: read("body"), sourceUrl: read("sourceUrl"), tags: splitList5(read("tags")), provenance: "agent-harness-local-operation" };
|
|
879291
|
-
if (editor.kind === "persona")
|
|
879292
|
-
return { domain: "persona", action: editor.mode === "update" ? "update" : "create", id, name: read("name"), description: read("description"), body: read("body"), tags: splitList5(read("tags")), triggers: splitList5(read("triggers")), activate: read("activate"), provenance: editor.recordId ? "agent-harness-local-operation" : "agent-harness-note-promotion" };
|
|
879293
|
-
if (editor.kind === "skill")
|
|
879294
|
-
return { domain: "skill", action: editor.mode === "update" ? "update" : "create", id, name: read("name"), description: read("description"), procedure: read("procedure"), tags: splitList5(read("tags")), triggers: splitList5(read("triggers")), requiresEnv: splitList5(read("requiresEnv")), requiresCommands: splitList5(read("requiresCommands")), enabled: isAffirmative15(read("enabled")), provenance: editor.recordId ? "agent-harness-local-operation" : "agent-harness-note-promotion" };
|
|
879295
|
-
return { domain: "routine", action: editor.mode === "update" ? "update" : "create", id, name: read("name"), description: read("description"), steps: read("steps"), tags: splitList5(read("tags")), triggers: splitList5(read("triggers")), requiresEnv: splitList5(read("requiresEnv")), requiresCommands: splitList5(read("requiresCommands")), enabled: isAffirmative15(read("enabled")), provenance: editor.recordId ? "agent-harness-local-operation" : "agent-harness-note-promotion" };
|
|
879296
|
-
}
|
|
879297
|
-
function localRegistryArgsForTarget(target, args2, recordId) {
|
|
879298
|
-
const fields = readFieldMap(args2.fields);
|
|
879299
|
-
const base2 = { domain: target.domain, action: target.action, ...recordId ? { id: recordId } : {} };
|
|
879300
|
-
const edit = target.action === "update" ? localRegistryArgsFromEditor({ kind: target.domain, mode: "update", recordId, title: "", selectedFieldIndex: 0, message: "", fields: [] }, fields, recordId) : {};
|
|
879301
|
-
return {
|
|
879302
|
-
...base2,
|
|
879303
|
-
...edit,
|
|
879304
|
-
...target.action === "stale" && fields.reason ? { reason: fields.reason } : {},
|
|
879305
|
-
...target.action === "delete" ? { confirm: args2.confirm, explicitUserRequest: readString50(args2.explicitUserRequest) } : {}
|
|
879306
|
-
};
|
|
879307
|
-
}
|
|
879308
|
-
async function executeTool(toolRegistry, name51, toolArgs) {
|
|
879309
|
-
if (!toolRegistry.has(name51))
|
|
879310
|
-
return output6({ status: "model_tool_required", modelExecution: { tool: name51, args: toolArgs } });
|
|
879311
|
-
const result2 = await toolRegistry.execute(`agent-harness-${name51}-${Date.now()}`, name51, toolArgs);
|
|
879312
|
-
if (!result2.success)
|
|
879313
|
-
return error51(result2.error ?? `${name51} failed.`);
|
|
879314
|
-
return output6({ status: "executed_model_tool", tool: name51, output: result2.output ?? "" });
|
|
879315
|
-
}
|
|
879316
|
-
function describeLocalWorkspaceModelExecution(action2) {
|
|
879317
|
-
if (action2.kind === "local-selection")
|
|
879318
|
-
return { tool: "agent_local_registry", domain: action2.localKind, actions: ["list", "search", "get"], note: "TUI selection maps to recordId for model-run local-operation actions." };
|
|
879319
|
-
if (!action2.localOperation)
|
|
879320
|
-
return null;
|
|
879321
|
-
const target = registryTarget(action2.localOperation);
|
|
879322
|
-
if (target)
|
|
879323
|
-
return { tool: "agent_local_registry", domain: target.domain, action: target.action, requiresRecordId: target.requiresRecordId };
|
|
879324
|
-
if (action2.localOperation === "note-promote-knowledge-url")
|
|
879325
|
-
return { tool: "agent_knowledge_ingest", sourceKind: "url", requiresRecordId: true, selectedRecordDomain: "note" };
|
|
879326
|
-
return { tool: "agent_local_registry", selectedRecordDomain: "note", action: "create", requiresRecordId: true };
|
|
879327
|
-
}
|
|
879328
|
-
async function runLocalWorkspaceAction(deps, action2, args2) {
|
|
879329
|
-
if (action2.kind === "local-selection")
|
|
879330
|
-
return output6({ status: "local_selection", action: action2.id, modelExecution: describeLocalWorkspaceModelExecution(action2) });
|
|
879331
|
-
const operation = action2.localOperation;
|
|
879332
|
-
if (!operation)
|
|
879333
|
-
return output6({ status: "local_registry_action", action: action2.id, modelExecution: describeLocalWorkspaceModelExecution(action2) });
|
|
879334
|
-
const target = registryTarget(operation);
|
|
879335
|
-
const recordId = readRecordId(args2);
|
|
879336
|
-
if (target?.requiresRecordId && !recordId)
|
|
879337
|
-
return output6({ status: "needs_record_id", action: action2.id, modelExecution: describeLocalWorkspaceModelExecution(action2) });
|
|
879338
|
-
const editor = recordId ? editorForOperation(deps.commandContext, operation, recordId) : null;
|
|
879339
|
-
if (editor && !hasExecutionFields(args2) && args2.confirm !== true)
|
|
879340
|
-
return output6({ status: "editor", action: action2.id, editor: describeEditor(editor), modelExecution: describeLocalWorkspaceModelExecution(action2) });
|
|
879341
|
-
const confirmationError2 = requireConfirmed(args2, "Workspace local registry action");
|
|
879342
|
-
if (confirmationError2)
|
|
879343
|
-
return error51(confirmationError2);
|
|
879344
|
-
if (editor) {
|
|
879345
|
-
const fields = readFieldMap(args2.fields);
|
|
879346
|
-
const missing = missingRequiredFields(editor, fields);
|
|
879347
|
-
if (missing.length > 0)
|
|
879348
|
-
return output6({ status: "missing_required_fields", missing, action: action2.id, editor: describeEditor(editor) });
|
|
879349
|
-
if (editor.kind === "knowledge-url")
|
|
879350
|
-
return executeTool(deps.toolRegistry, "agent_knowledge_ingest", { sourceKind: "url", url: fieldReader(editor, fields)("url"), tags: splitList5(fieldReader(editor, fields)("tags")), folderPath: fieldReader(editor, fields)("folder"), confirm: args2.confirm, explicitUserRequest: readString50(args2.explicitUserRequest) });
|
|
879351
|
-
return executeTool(deps.toolRegistry, "agent_local_registry", localRegistryArgsFromEditor(editor, fields, recordId));
|
|
879352
|
-
}
|
|
879353
|
-
if (!target)
|
|
879354
|
-
return output6({ status: "local_registry_action", action: action2.id, modelExecution: describeLocalWorkspaceModelExecution(action2) });
|
|
879355
|
-
return executeTool(deps.toolRegistry, "agent_local_registry", localRegistryArgsForTarget(target, args2, recordId));
|
|
879356
|
-
}
|
|
879357
|
-
|
|
879358
879221
|
// src/tools/agent-harness-metadata.ts
|
|
879359
879222
|
function describeCommandPolicy(commandName) {
|
|
879360
879223
|
const root = commandName.replace(/^\//, "").trim().toLowerCase();
|
|
@@ -879458,6 +879321,95 @@ function describeCommandPolicy(commandName) {
|
|
|
879458
879321
|
boundary: "Inspect the command description, usage, and workspace action metadata before invoking through run_command."
|
|
879459
879322
|
};
|
|
879460
879323
|
}
|
|
879324
|
+
function describeCliCommandPolicy(commandName) {
|
|
879325
|
+
const root = commandName.trim().toLowerCase();
|
|
879326
|
+
const confirmation = "agent_harness CLI command modes are discovery-only. Use first-class model tools, workspace actions, slash-command mirrors, or an explicit external shell request to execute equivalent CLI workflows.";
|
|
879327
|
+
if ([
|
|
879328
|
+
"app",
|
|
879329
|
+
"bridge",
|
|
879330
|
+
"control-plane",
|
|
879331
|
+
"controlplane",
|
|
879332
|
+
"cp",
|
|
879333
|
+
"daemon",
|
|
879334
|
+
"http-listener",
|
|
879335
|
+
"launch",
|
|
879336
|
+
"listener",
|
|
879337
|
+
"remote",
|
|
879338
|
+
"serve",
|
|
879339
|
+
"server",
|
|
879340
|
+
"service",
|
|
879341
|
+
"services",
|
|
879342
|
+
"start",
|
|
879343
|
+
"surface",
|
|
879344
|
+
"surfaces",
|
|
879345
|
+
"web",
|
|
879346
|
+
"webhook"
|
|
879347
|
+
].includes(root)) {
|
|
879348
|
+
return {
|
|
879349
|
+
effect: "unknown",
|
|
879350
|
+
confirmation,
|
|
879351
|
+
boundary: "Blocked package CLI token. Agent can launch its own TUI and use public connected-host routes, but it does not manage connected-host lifecycle, listeners, servers, bridges, remotes, web surfaces, or webhook listeners."
|
|
879352
|
+
};
|
|
879353
|
+
}
|
|
879354
|
+
if (root === "tui" || root === "onboarding" || root === "help" || root === "version" || root === "completion") {
|
|
879355
|
+
return {
|
|
879356
|
+
effect: root === "tui" || root === "onboarding" ? "ui-navigation" : "read-only",
|
|
879357
|
+
confirmation,
|
|
879358
|
+
preferredModelTool: root === "onboarding" || root === "tui" ? "agent_harness workspace/workspace_actions" : "agent_harness cli_commands/cli_command",
|
|
879359
|
+
boundary: "Top-level CLI launch, setup, help, version, and completion commands are package entrypoint surfaces; use in-process workspace and slash-command bridges from the model when operating inside the TUI."
|
|
879360
|
+
};
|
|
879361
|
+
}
|
|
879362
|
+
if (root === "run") {
|
|
879363
|
+
return {
|
|
879364
|
+
effect: "mixed",
|
|
879365
|
+
confirmation,
|
|
879366
|
+
boundary: "The CLI run command starts a non-interactive Agent turn from a process entrypoint. Do not create hidden nested turns from agent_harness; answer the user directly in the current conversation."
|
|
879367
|
+
};
|
|
879368
|
+
}
|
|
879369
|
+
if (root === "status" || root === "doctor" || root === "auth" || root === "compat" || root === "models" || root === "providers" || root === "tasks") {
|
|
879370
|
+
return {
|
|
879371
|
+
effect: "read-only",
|
|
879372
|
+
confirmation,
|
|
879373
|
+
preferredModelTool: root === "tasks" ? "agent_operator_briefing" : "agent_harness connected_host/settings/tools",
|
|
879374
|
+
boundary: "Diagnostics and posture commands are readable from Agent-owned settings, provider, model, and connected-host capability surfaces without taking connected-host lifecycle ownership."
|
|
879375
|
+
};
|
|
879376
|
+
}
|
|
879377
|
+
if (root === "profiles" || root === "personas" || root === "skills" || root === "memory" || root === "routines" || root === "sessions" || root === "bundle") {
|
|
879378
|
+
return {
|
|
879379
|
+
effect: "local-state",
|
|
879380
|
+
confirmation,
|
|
879381
|
+
preferredModelTool: root === "profiles" ? "agent_harness workspace_actions/run_workspace_action" : "agent_local_registry",
|
|
879382
|
+
boundary: "Local library/profile/session/bundle CLI commands operate on Agent-local data. Mutations require explicit user intent and should use first-class Agent-local tools where available."
|
|
879383
|
+
};
|
|
879384
|
+
}
|
|
879385
|
+
if (root === "knowledge" || root === "ask" || root === "search") {
|
|
879386
|
+
return {
|
|
879387
|
+
effect: "mixed",
|
|
879388
|
+
confirmation,
|
|
879389
|
+
preferredModelTool: root === "knowledge" ? "agent_knowledge or agent_knowledge_ingest" : "agent_knowledge",
|
|
879390
|
+
boundary: "Agent Knowledge CLI commands must stay on isolated Agent Knowledge routes and never fall back to default or non-Agent knowledge spaces."
|
|
879391
|
+
};
|
|
879392
|
+
}
|
|
879393
|
+
if (root === "delegate") {
|
|
879394
|
+
return {
|
|
879395
|
+
effect: "delegated-work",
|
|
879396
|
+
confirmation,
|
|
879397
|
+
boundary: "Delegation is explicit user-directed work only; no hidden background review or separate Agent job should be created implicitly."
|
|
879398
|
+
};
|
|
879399
|
+
}
|
|
879400
|
+
if (root === "subscription" || root === "secrets" || root === "pair") {
|
|
879401
|
+
return {
|
|
879402
|
+
effect: root === "pair" ? "external-network" : "mixed",
|
|
879403
|
+
confirmation,
|
|
879404
|
+
boundary: "Provider subscription, secret, and pairing flows can expose credentials or external account state. Use only explicit user-directed flows and prefer secret refs over raw values."
|
|
879405
|
+
};
|
|
879406
|
+
}
|
|
879407
|
+
return {
|
|
879408
|
+
effect: "unknown",
|
|
879409
|
+
confirmation,
|
|
879410
|
+
boundary: "Inspect the CLI help, parser result, and preferred model routes before using an equivalent command path."
|
|
879411
|
+
};
|
|
879412
|
+
}
|
|
879461
879413
|
function toolIsAvailable(toolRegistry, toolName) {
|
|
879462
879414
|
return toolRegistry.getToolDefinitions().some((tool2) => tool2.name === toolName);
|
|
879463
879415
|
}
|
|
@@ -879587,6 +879539,21 @@ function connectedHostRouteFamilies() {
|
|
|
879587
879539
|
}
|
|
879588
879540
|
];
|
|
879589
879541
|
}
|
|
879542
|
+
function connectedHostSummary(context, toolRegistry) {
|
|
879543
|
+
const shellPaths3 = context.workspace.shellPaths;
|
|
879544
|
+
const homeDirectory = shellPaths3?.homeDirectory ?? context.platform.configManager.getHomeDirectory() ?? "";
|
|
879545
|
+
const connection5 = resolveAgentConnectedHostConnection(context.platform.configManager, homeDirectory);
|
|
879546
|
+
return {
|
|
879547
|
+
baseUrl: connection5.baseUrl,
|
|
879548
|
+
operatorToken: connection5.token ? "configured" : "missing",
|
|
879549
|
+
tokenPath: connection5.tokenPath,
|
|
879550
|
+
ownership: "external-connected-host",
|
|
879551
|
+
lifecycle: "GoodVibes Agent can use public connected-host operator routes, but does not start, stop, restart, install, expose, or mutate the host listener.",
|
|
879552
|
+
routeFamilies: connectedHostRouteFamilies(),
|
|
879553
|
+
capabilities: connectedHostCapabilityMap(toolRegistry),
|
|
879554
|
+
blockedCapabilities: blockedConnectedHostCapabilities()
|
|
879555
|
+
};
|
|
879556
|
+
}
|
|
879590
879557
|
function blockedConnectedHostCapabilities() {
|
|
879591
879558
|
return [
|
|
879592
879559
|
{
|
|
@@ -879621,9 +879588,737 @@ function settingsPolicySummary() {
|
|
|
879621
879588
|
};
|
|
879622
879589
|
}
|
|
879623
879590
|
|
|
879591
|
+
// src/tools/agent-harness-cli-metadata.ts
|
|
879592
|
+
function readString50(value) {
|
|
879593
|
+
return typeof value === "string" ? value.trim() : "";
|
|
879594
|
+
}
|
|
879595
|
+
function readLimit5(value, fallback) {
|
|
879596
|
+
const parsed = typeof value === "string" && value.trim() ? Number(value) : value;
|
|
879597
|
+
if (typeof parsed !== "number" || !Number.isFinite(parsed))
|
|
879598
|
+
return fallback;
|
|
879599
|
+
return Math.max(1, Math.min(500, Math.trunc(parsed)));
|
|
879600
|
+
}
|
|
879601
|
+
function cliCommandTokens(command8) {
|
|
879602
|
+
if (command8 === "unknown")
|
|
879603
|
+
return [];
|
|
879604
|
+
if (command8 === "tui")
|
|
879605
|
+
return ["(no command)"];
|
|
879606
|
+
return listGoodVibesCliCommandTokens().filter((token) => parseGoodVibesCli([token]).command === command8).sort();
|
|
879607
|
+
}
|
|
879608
|
+
function fallbackCliSummary(command8) {
|
|
879609
|
+
if (command8 === "tui")
|
|
879610
|
+
return "Launch the interactive Agent TUI.";
|
|
879611
|
+
if (command8 === "help")
|
|
879612
|
+
return "Print top-level or command-specific help.";
|
|
879613
|
+
if (command8 === "version")
|
|
879614
|
+
return "Print the installed Agent package version.";
|
|
879615
|
+
return "Inspect the CLI help for this Agent package command.";
|
|
879616
|
+
}
|
|
879617
|
+
function describeCliCommand(command8) {
|
|
879618
|
+
const help = describeGoodVibesCommandHelp(command8);
|
|
879619
|
+
const tokens = cliCommandTokens(command8);
|
|
879620
|
+
return {
|
|
879621
|
+
name: command8,
|
|
879622
|
+
tokens,
|
|
879623
|
+
invocation: command8 === "tui" ? "goodvibes-agent" : `goodvibes-agent ${tokens[0] ?? command8}`,
|
|
879624
|
+
helpTopic: help?.command ?? command8,
|
|
879625
|
+
summary: help?.summary ?? fallbackCliSummary(command8),
|
|
879626
|
+
usage: help?.usage ?? (command8 === "tui" ? ["goodvibes-agent [OPTIONS]"] : [`goodvibes-agent ${command8} [ARGS]`]),
|
|
879627
|
+
aliases: help?.aliases ?? tokens.filter((token) => token !== command8),
|
|
879628
|
+
subcommands: help?.subcommands ?? [],
|
|
879629
|
+
examples: help?.examples ?? [],
|
|
879630
|
+
policy: describeCliCommandPolicy(command8)
|
|
879631
|
+
};
|
|
879632
|
+
}
|
|
879633
|
+
function cliCommandMatches(command8, query2) {
|
|
879634
|
+
if (!query2)
|
|
879635
|
+
return true;
|
|
879636
|
+
return [
|
|
879637
|
+
command8.name,
|
|
879638
|
+
command8.tokens,
|
|
879639
|
+
command8.summary,
|
|
879640
|
+
command8.usage,
|
|
879641
|
+
command8.aliases,
|
|
879642
|
+
command8.subcommands,
|
|
879643
|
+
command8.examples,
|
|
879644
|
+
command8.policy
|
|
879645
|
+
].map((value) => JSON.stringify(value)).join(`
|
|
879646
|
+
`).toLowerCase().includes(query2.toLowerCase());
|
|
879647
|
+
}
|
|
879648
|
+
function totalHarnessCliCommands() {
|
|
879649
|
+
return listGoodVibesCliCommands().filter((command8) => command8 !== "unknown").length;
|
|
879650
|
+
}
|
|
879651
|
+
function blockedHarnessCliCommandTokens() {
|
|
879652
|
+
return listBlockedGoodVibesCliCommandTokens();
|
|
879653
|
+
}
|
|
879654
|
+
function listHarnessCliCommands(args2) {
|
|
879655
|
+
const query2 = readString50(args2.query);
|
|
879656
|
+
const limit3 = readLimit5(args2.limit, 200);
|
|
879657
|
+
return listGoodVibesCliCommands().filter((command8) => command8 !== "unknown").map(describeCliCommand).filter((command8) => cliCommandMatches(command8, query2)).sort((a4, b3) => String(a4.name).localeCompare(String(b3.name))).slice(0, limit3);
|
|
879658
|
+
}
|
|
879659
|
+
function cliTokensFromArgs(args2) {
|
|
879660
|
+
const raw = readString50(args2.cliCommand) || readString50(args2.command) || readString50(args2.commandName) || readString50(args2.query);
|
|
879661
|
+
if (!raw)
|
|
879662
|
+
return [];
|
|
879663
|
+
const tokens = raw.split(/\s+/).filter((token) => token.length > 0);
|
|
879664
|
+
if (tokens[0] === "goodvibes-agent" || tokens[0]?.endsWith("/goodvibes-agent"))
|
|
879665
|
+
return tokens.slice(1);
|
|
879666
|
+
return tokens;
|
|
879667
|
+
}
|
|
879668
|
+
function describeHarnessCliCommand(args2) {
|
|
879669
|
+
const tokens = cliTokensFromArgs(args2);
|
|
879670
|
+
if (tokens.length === 0)
|
|
879671
|
+
return describeCliCommand("tui");
|
|
879672
|
+
const parsed = parseGoodVibesCli(tokens);
|
|
879673
|
+
if (parsed.command === "unknown") {
|
|
879674
|
+
return {
|
|
879675
|
+
supported: false,
|
|
879676
|
+
token: parsed.rawCommand ?? tokens[0],
|
|
879677
|
+
errors: parsed.errors,
|
|
879678
|
+
blockedTokens: blockedHarnessCliCommandTokens(),
|
|
879679
|
+
policy: describeCliCommandPolicy(parsed.rawCommand ?? tokens[0] ?? "unknown")
|
|
879680
|
+
};
|
|
879681
|
+
}
|
|
879682
|
+
return {
|
|
879683
|
+
...describeCliCommand(parsed.command),
|
|
879684
|
+
parsed: {
|
|
879685
|
+
command: parsed.command,
|
|
879686
|
+
rawCommand: parsed.rawCommand,
|
|
879687
|
+
commandArgs: parsed.commandArgs,
|
|
879688
|
+
positionals: parsed.positionals,
|
|
879689
|
+
flags: {
|
|
879690
|
+
provider: parsed.flags.provider,
|
|
879691
|
+
model: parsed.flags.model,
|
|
879692
|
+
agentProfile: parsed.flags.agentProfile,
|
|
879693
|
+
runtimeUrl: parsed.flags.runtimeUrl,
|
|
879694
|
+
workingDir: parsed.flags.workingDir,
|
|
879695
|
+
help: parsed.flags.help,
|
|
879696
|
+
version: parsed.flags.version,
|
|
879697
|
+
print: parsed.flags.print,
|
|
879698
|
+
outputFormat: parsed.flags.outputFormat,
|
|
879699
|
+
configOverrides: parsed.flags.configOverrides.map((override) => {
|
|
879700
|
+
const index = override.indexOf("=");
|
|
879701
|
+
return index < 0 ? override : `${override.slice(0, index)}=<redacted>`;
|
|
879702
|
+
}),
|
|
879703
|
+
enableFeatures: parsed.flags.enableFeatures,
|
|
879704
|
+
disableFeatures: parsed.flags.disableFeatures,
|
|
879705
|
+
noAltScreen: parsed.flags.noAltScreen,
|
|
879706
|
+
port: parsed.flags.port,
|
|
879707
|
+
hostname: parsed.flags.hostname,
|
|
879708
|
+
open: parsed.flags.open,
|
|
879709
|
+
continueLast: parsed.flags.continueLast,
|
|
879710
|
+
resume: parsed.flags.resume,
|
|
879711
|
+
session: parsed.flags.session,
|
|
879712
|
+
fork: parsed.flags.fork,
|
|
879713
|
+
rawOutput: parsed.flags.rawOutput,
|
|
879714
|
+
acceptRawOutputRisk: parsed.flags.acceptRawOutputRisk
|
|
879715
|
+
},
|
|
879716
|
+
errors: parsed.errors
|
|
879717
|
+
}
|
|
879718
|
+
};
|
|
879719
|
+
}
|
|
879720
|
+
|
|
879721
|
+
// src/tools/agent-harness-keybinding-metadata.ts
|
|
879722
|
+
import { existsSync as existsSync82, mkdirSync as mkdirSync67, readFileSync as readFileSync89, writeFileSync as writeFileSync58 } from "fs";
|
|
879723
|
+
import { dirname as dirname66 } from "path";
|
|
879724
|
+
var FIXED_SHORTCUTS = [
|
|
879725
|
+
{ key: "Enter", description: "Send prompt" },
|
|
879726
|
+
{ key: "Shift+Enter / Ctrl+J", description: "Insert newline" },
|
|
879727
|
+
{ key: "Up / Down", description: "Navigate input history, lists, and scrollable overlays" },
|
|
879728
|
+
{ key: "Tab", description: "Autocomplete slash command or file mention" },
|
|
879729
|
+
{ key: "Esc", description: "Close overlays, pickers, and transient input modes" },
|
|
879730
|
+
{ key: "? / F1", description: "Toggle help overlay" },
|
|
879731
|
+
{ key: "F2 / /shortcuts", description: "Open keyboard shortcut reference" },
|
|
879732
|
+
{ key: "/keybindings", description: "List configurable keybindings and config path" }
|
|
879733
|
+
];
|
|
879734
|
+
function readString51(value) {
|
|
879735
|
+
return typeof value === "string" ? value.trim() : "";
|
|
879736
|
+
}
|
|
879737
|
+
function readLimit6(value, fallback) {
|
|
879738
|
+
const parsed = typeof value === "string" && value.trim() ? Number(value) : value;
|
|
879739
|
+
if (typeof parsed !== "number" || !Number.isFinite(parsed))
|
|
879740
|
+
return fallback;
|
|
879741
|
+
return Math.max(1, Math.min(500, Math.trunc(parsed)));
|
|
879742
|
+
}
|
|
879743
|
+
function readFieldMap(value) {
|
|
879744
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
879745
|
+
return {};
|
|
879746
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, typeof entry === "string" ? entry : String(entry)]));
|
|
879747
|
+
}
|
|
879748
|
+
function requireKeybindingsManager2(context) {
|
|
879749
|
+
const manager5 = context.workspace.keybindingsManager;
|
|
879750
|
+
if (!manager5)
|
|
879751
|
+
throw new Error("workspace.keybindingsManager is unavailable in this Agent runtime");
|
|
879752
|
+
return manager5;
|
|
879753
|
+
}
|
|
879754
|
+
function isKeyAction2(action2) {
|
|
879755
|
+
return Object.hasOwn(ACTION_DESCRIPTIONS, action2);
|
|
879756
|
+
}
|
|
879757
|
+
function actionFromArgs(args2) {
|
|
879758
|
+
const action2 = readString51(args2.actionId || args2.key || args2.query);
|
|
879759
|
+
return action2 && isKeyAction2(action2) ? action2 : null;
|
|
879760
|
+
}
|
|
879761
|
+
function readBoolean15(value) {
|
|
879762
|
+
if (typeof value === "boolean")
|
|
879763
|
+
return value;
|
|
879764
|
+
if (typeof value !== "string")
|
|
879765
|
+
return;
|
|
879766
|
+
const normalized = value.trim().toLowerCase();
|
|
879767
|
+
if (["true", "yes", "y", "1", "on"].includes(normalized))
|
|
879768
|
+
return true;
|
|
879769
|
+
if (["false", "no", "n", "0", "off"].includes(normalized))
|
|
879770
|
+
return false;
|
|
879771
|
+
return;
|
|
879772
|
+
}
|
|
879773
|
+
function normalizeCombo(value) {
|
|
879774
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
879775
|
+
return null;
|
|
879776
|
+
const raw = value;
|
|
879777
|
+
const key = readString51(raw.key);
|
|
879778
|
+
if (!key)
|
|
879779
|
+
return null;
|
|
879780
|
+
const combo = { key };
|
|
879781
|
+
const ctrl = readBoolean15(raw.ctrl);
|
|
879782
|
+
const shift = readBoolean15(raw.shift);
|
|
879783
|
+
const alt = readBoolean15(raw.alt);
|
|
879784
|
+
if (ctrl !== undefined)
|
|
879785
|
+
combo.ctrl = ctrl;
|
|
879786
|
+
if (shift !== undefined)
|
|
879787
|
+
combo.shift = shift;
|
|
879788
|
+
if (alt !== undefined)
|
|
879789
|
+
combo.alt = alt;
|
|
879790
|
+
return combo;
|
|
879791
|
+
}
|
|
879792
|
+
function parseComboLabel(value) {
|
|
879793
|
+
const parts2 = value.split("+").map((part) => part.trim()).filter(Boolean);
|
|
879794
|
+
if (parts2.length === 0)
|
|
879795
|
+
return null;
|
|
879796
|
+
const key = parts2.at(-1);
|
|
879797
|
+
if (!key)
|
|
879798
|
+
return null;
|
|
879799
|
+
const combo = { key: key.length === 1 ? key.toLowerCase() : key.toLowerCase() };
|
|
879800
|
+
for (const part of parts2.slice(0, -1)) {
|
|
879801
|
+
const normalized = part.toLowerCase();
|
|
879802
|
+
if (normalized === "ctrl" || normalized === "control")
|
|
879803
|
+
combo.ctrl = true;
|
|
879804
|
+
else if (normalized === "shift")
|
|
879805
|
+
combo.shift = true;
|
|
879806
|
+
else if (normalized === "alt" || normalized === "option")
|
|
879807
|
+
combo.alt = true;
|
|
879808
|
+
else
|
|
879809
|
+
return null;
|
|
879810
|
+
}
|
|
879811
|
+
return combo;
|
|
879812
|
+
}
|
|
879813
|
+
function combosFromArgs(args2) {
|
|
879814
|
+
if (Array.isArray(args2.combos)) {
|
|
879815
|
+
const combos = args2.combos.map(normalizeCombo);
|
|
879816
|
+
if (combos.every((combo2) => combo2 !== null))
|
|
879817
|
+
return combos;
|
|
879818
|
+
throw new Error("set_keybinding combos must be objects with key and optional boolean ctrl/shift/alt fields.");
|
|
879819
|
+
}
|
|
879820
|
+
const combo = normalizeCombo(args2.combo);
|
|
879821
|
+
if (combo)
|
|
879822
|
+
return [combo];
|
|
879823
|
+
const fields = readFieldMap(args2.fields);
|
|
879824
|
+
const fieldCombo = normalizeCombo(fields);
|
|
879825
|
+
if (fieldCombo)
|
|
879826
|
+
return [fieldCombo];
|
|
879827
|
+
const labelCombo = parseComboLabel(readString51(args2.value));
|
|
879828
|
+
if (labelCombo)
|
|
879829
|
+
return [labelCombo];
|
|
879830
|
+
throw new Error('set_keybinding requires combo, combos, fields.key, or a value such as "Ctrl+G".');
|
|
879831
|
+
}
|
|
879832
|
+
function comboFingerprint(combo) {
|
|
879833
|
+
return `${combo.key}:${combo.ctrl ? 1 : 0}:${combo.shift ? 1 : 0}:${combo.alt ? 1 : 0}`;
|
|
879834
|
+
}
|
|
879835
|
+
function combosEqual(left, right) {
|
|
879836
|
+
if (left.length !== right.length)
|
|
879837
|
+
return false;
|
|
879838
|
+
return left.every((combo, index) => comboFingerprint(combo) === comboFingerprint(right[index]));
|
|
879839
|
+
}
|
|
879840
|
+
function describeCombo(manager5, combo) {
|
|
879841
|
+
return {
|
|
879842
|
+
key: combo.key,
|
|
879843
|
+
ctrl: combo.ctrl === true,
|
|
879844
|
+
shift: combo.shift === true,
|
|
879845
|
+
alt: combo.alt === true,
|
|
879846
|
+
label: manager5.formatCombo(combo)
|
|
879847
|
+
};
|
|
879848
|
+
}
|
|
879849
|
+
function bindingMatches(entry, query2) {
|
|
879850
|
+
if (!query2)
|
|
879851
|
+
return true;
|
|
879852
|
+
const haystack = [
|
|
879853
|
+
entry.action,
|
|
879854
|
+
entry.description,
|
|
879855
|
+
...entry.combos.map((combo) => comboFingerprint(combo))
|
|
879856
|
+
].join(`
|
|
879857
|
+
`).toLowerCase();
|
|
879858
|
+
return haystack.includes(query2.toLowerCase());
|
|
879859
|
+
}
|
|
879860
|
+
function describeBinding(manager5, action2, combos) {
|
|
879861
|
+
const defaults3 = DEFAULT_KEYBINDINGS[action2];
|
|
879862
|
+
const customized = !combosEqual(combos, defaults3);
|
|
879863
|
+
return {
|
|
879864
|
+
action: action2,
|
|
879865
|
+
description: ACTION_DESCRIPTIONS[action2],
|
|
879866
|
+
bindings: combos.map((combo) => describeCombo(manager5, combo)),
|
|
879867
|
+
labels: combos.map((combo) => manager5.formatCombo(combo)),
|
|
879868
|
+
defaultBindings: defaults3.map((combo) => describeCombo(manager5, combo)),
|
|
879869
|
+
customized,
|
|
879870
|
+
source: customized ? "custom" : "default"
|
|
879871
|
+
};
|
|
879872
|
+
}
|
|
879873
|
+
function readOverrideFile(configPath) {
|
|
879874
|
+
if (!existsSync82(configPath))
|
|
879875
|
+
return {};
|
|
879876
|
+
const parsed = JSON.parse(readFileSync89(configPath, "utf-8"));
|
|
879877
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
879878
|
+
throw new Error(`Keybindings config ${configPath} must contain a JSON object.`);
|
|
879879
|
+
}
|
|
879880
|
+
return parsed;
|
|
879881
|
+
}
|
|
879882
|
+
function writeOverrideFile(configPath, overrides) {
|
|
879883
|
+
mkdirSync67(dirname66(configPath), { recursive: true });
|
|
879884
|
+
writeFileSync58(configPath, `${JSON.stringify(overrides, null, 2)}
|
|
879885
|
+
`, "utf-8");
|
|
879886
|
+
}
|
|
879887
|
+
function totalHarnessKeybindings(context) {
|
|
879888
|
+
return context.workspace.keybindingsManager?.getAll().length ?? 0;
|
|
879889
|
+
}
|
|
879890
|
+
function totalHarnessShortcuts(context) {
|
|
879891
|
+
return totalHarnessKeybindings(context) + FIXED_SHORTCUTS.length;
|
|
879892
|
+
}
|
|
879893
|
+
function listHarnessShortcuts(context, args2) {
|
|
879894
|
+
const keybindings = listHarnessKeybindings(context, args2);
|
|
879895
|
+
const query2 = readString51(args2.query).toLowerCase();
|
|
879896
|
+
const fixed = FIXED_SHORTCUTS.filter((shortcut) => !query2 || `${shortcut.key}
|
|
879897
|
+
${shortcut.description}`.toLowerCase().includes(query2)).slice(0, readLimit6(args2.limit, 200)).map((shortcut) => ({ ...shortcut, source: "fixed", userEditable: false }));
|
|
879898
|
+
return {
|
|
879899
|
+
configPath: keybindings.configPath,
|
|
879900
|
+
fixedShortcuts: fixed,
|
|
879901
|
+
configurableKeybindings: keybindings.keybindings,
|
|
879902
|
+
returned: fixed.length + Number(keybindings.returned ?? 0),
|
|
879903
|
+
total: totalHarnessShortcuts(context),
|
|
879904
|
+
policy: "Fixed shortcuts are runtime/editor controls. Configurable keybindings can be changed with set_keybinding/reset_keybinding."
|
|
879905
|
+
};
|
|
879906
|
+
}
|
|
879907
|
+
function listHarnessKeybindings(context, args2) {
|
|
879908
|
+
const manager5 = requireKeybindingsManager2(context);
|
|
879909
|
+
const query2 = readString51(args2.query);
|
|
879910
|
+
const entries = manager5.getAll().filter((entry) => bindingMatches(entry, query2)).slice(0, readLimit6(args2.limit, 200)).map((entry) => describeBinding(manager5, entry.action, entry.combos));
|
|
879911
|
+
return {
|
|
879912
|
+
configPath: manager5.getConfigPath(),
|
|
879913
|
+
keybindings: entries,
|
|
879914
|
+
returned: entries.length,
|
|
879915
|
+
total: manager5.getAll().length,
|
|
879916
|
+
policy: "Reads the live resolved keybindings. set_keybinding/reset_keybinding write the same keybindings.json file the user can edit and reload the runtime manager."
|
|
879917
|
+
};
|
|
879918
|
+
}
|
|
879919
|
+
function describeHarnessKeybinding(context, args2) {
|
|
879920
|
+
const manager5 = requireKeybindingsManager2(context);
|
|
879921
|
+
const action2 = actionFromArgs(args2);
|
|
879922
|
+
if (!action2)
|
|
879923
|
+
return null;
|
|
879924
|
+
const entry = manager5.getAll().find((candidate) => candidate.action === action2);
|
|
879925
|
+
return entry ? {
|
|
879926
|
+
configPath: manager5.getConfigPath(),
|
|
879927
|
+
...describeBinding(manager5, entry.action, entry.combos)
|
|
879928
|
+
} : null;
|
|
879929
|
+
}
|
|
879930
|
+
function setHarnessKeybinding(context, args2) {
|
|
879931
|
+
const manager5 = requireKeybindingsManager2(context);
|
|
879932
|
+
const action2 = actionFromArgs(args2);
|
|
879933
|
+
if (!action2)
|
|
879934
|
+
throw new Error("set_keybinding requires a valid keybinding action id.");
|
|
879935
|
+
const combos = combosFromArgs(args2);
|
|
879936
|
+
const configPath = manager5.getConfigPath();
|
|
879937
|
+
const overrides = readOverrideFile(configPath);
|
|
879938
|
+
overrides[action2] = combos.length === 1 ? combos[0] : combos;
|
|
879939
|
+
writeOverrideFile(configPath, overrides);
|
|
879940
|
+
manager5.loadFromDisk();
|
|
879941
|
+
return {
|
|
879942
|
+
status: "updated",
|
|
879943
|
+
configPath,
|
|
879944
|
+
keybinding: describeHarnessKeybinding(context, { actionId: action2 })
|
|
879945
|
+
};
|
|
879946
|
+
}
|
|
879947
|
+
function resetHarnessKeybinding(context, args2) {
|
|
879948
|
+
const manager5 = requireKeybindingsManager2(context);
|
|
879949
|
+
const action2 = actionFromArgs(args2);
|
|
879950
|
+
if (!action2)
|
|
879951
|
+
throw new Error("reset_keybinding requires a valid keybinding action id.");
|
|
879952
|
+
const configPath = manager5.getConfigPath();
|
|
879953
|
+
const overrides = readOverrideFile(configPath);
|
|
879954
|
+
delete overrides[action2];
|
|
879955
|
+
writeOverrideFile(configPath, overrides);
|
|
879956
|
+
manager5.loadFromDisk();
|
|
879957
|
+
return {
|
|
879958
|
+
status: "reset",
|
|
879959
|
+
configPath,
|
|
879960
|
+
keybinding: describeHarnessKeybinding(context, { actionId: action2 })
|
|
879961
|
+
};
|
|
879962
|
+
}
|
|
879963
|
+
|
|
879964
|
+
// src/tools/agent-harness-panel-metadata.ts
|
|
879965
|
+
function readString52(value) {
|
|
879966
|
+
return typeof value === "string" ? value.trim() : "";
|
|
879967
|
+
}
|
|
879968
|
+
function readLimit7(value, fallback) {
|
|
879969
|
+
const parsed = typeof value === "string" && value.trim() ? Number(value) : value;
|
|
879970
|
+
if (typeof parsed !== "number" || !Number.isFinite(parsed))
|
|
879971
|
+
return fallback;
|
|
879972
|
+
return Math.max(1, Math.min(500, Math.trunc(parsed)));
|
|
879973
|
+
}
|
|
879974
|
+
function panelManager(context) {
|
|
879975
|
+
return context.workspace.panelManager ?? null;
|
|
879976
|
+
}
|
|
879977
|
+
function panelMatches(panel, query2) {
|
|
879978
|
+
if (!query2)
|
|
879979
|
+
return true;
|
|
879980
|
+
return [
|
|
879981
|
+
panel.id,
|
|
879982
|
+
panel.name,
|
|
879983
|
+
panel.category,
|
|
879984
|
+
panel.description,
|
|
879985
|
+
panel.workspaceRoute
|
|
879986
|
+
].map((value) => String(value ?? "")).join(`
|
|
879987
|
+
`).toLowerCase().includes(query2.toLowerCase());
|
|
879988
|
+
}
|
|
879989
|
+
function describePanelRegistration(context, registration) {
|
|
879990
|
+
const manager5 = panelManager(context);
|
|
879991
|
+
const openPanel = manager5?.getPanel(registration.id) ?? null;
|
|
879992
|
+
const pane = manager5?.getPaneOf(registration.id) ?? null;
|
|
879993
|
+
const activePanel = manager5?.getActivePanel() ?? null;
|
|
879994
|
+
return {
|
|
879995
|
+
id: registration.id,
|
|
879996
|
+
name: registration.name,
|
|
879997
|
+
icon: registration.icon,
|
|
879998
|
+
category: registration.category,
|
|
879999
|
+
description: registration.description,
|
|
880000
|
+
preload: registration.preload === true,
|
|
880001
|
+
open: openPanel !== null,
|
|
880002
|
+
pane,
|
|
880003
|
+
active: activePanel?.id === registration.id,
|
|
880004
|
+
focused: activePanel?.id === registration.id,
|
|
880005
|
+
workspaceRoute: {
|
|
880006
|
+
categoryId: agentWorkspaceCategoryForPanel(registration.id),
|
|
880007
|
+
command: agentWorkspaceCommandForPanel(registration.id)
|
|
880008
|
+
},
|
|
880009
|
+
policy: {
|
|
880010
|
+
effect: "ui-navigation",
|
|
880011
|
+
confirmation: 'agent_harness mode:"open_panel" requires confirm:true and explicitUserRequest.',
|
|
880012
|
+
boundary: "Panels are Agent/TUI operator views. The model can inspect panel catalog/open state; panel routing uses the existing Agent workspace bridge and does not mutate connected-host lifecycle."
|
|
880013
|
+
}
|
|
880014
|
+
};
|
|
880015
|
+
}
|
|
880016
|
+
function totalHarnessPanels(context) {
|
|
880017
|
+
return panelManager(context)?.getRegisteredTypes().length ?? 0;
|
|
880018
|
+
}
|
|
880019
|
+
function listHarnessPanels(context, args2) {
|
|
880020
|
+
const manager5 = panelManager(context);
|
|
880021
|
+
if (!manager5)
|
|
880022
|
+
return [];
|
|
880023
|
+
const query2 = readString52(args2.query);
|
|
880024
|
+
const category = readString52(args2.category);
|
|
880025
|
+
const limit3 = readLimit7(args2.limit, 200);
|
|
880026
|
+
return manager5.getRegisteredTypes().map((registration) => describePanelRegistration(context, registration)).filter((panel) => !category || panel.category === category).filter((panel) => panelMatches(panel, query2)).sort((a4, b3) => String(a4.id).localeCompare(String(b3.id))).slice(0, limit3);
|
|
880027
|
+
}
|
|
880028
|
+
function describeHarnessPanel(context, args2) {
|
|
880029
|
+
const manager5 = panelManager(context);
|
|
880030
|
+
if (!manager5)
|
|
880031
|
+
return null;
|
|
880032
|
+
const panelId = readString52(args2.panelId || args2.query);
|
|
880033
|
+
if (!panelId)
|
|
880034
|
+
return null;
|
|
880035
|
+
const registration = manager5.getRegisteredTypes().find((panel) => panel.id === panelId || panel.name.toLowerCase() === panelId.toLowerCase());
|
|
880036
|
+
return registration ? describePanelRegistration(context, registration) : null;
|
|
880037
|
+
}
|
|
880038
|
+
function openHarnessPanel(context, args2) {
|
|
880039
|
+
const panel = describeHarnessPanel(context, args2);
|
|
880040
|
+
if (!panel) {
|
|
880041
|
+
return {
|
|
880042
|
+
status: "unknown_panel",
|
|
880043
|
+
panelId: readString52(args2.panelId || args2.query) || "<missing>",
|
|
880044
|
+
availablePanels: listHarnessPanels(context, { limit: 50 }).map((entry) => entry.id)
|
|
880045
|
+
};
|
|
880046
|
+
}
|
|
880047
|
+
const requestedPane = readString52(args2.pane);
|
|
880048
|
+
const pane = requestedPane === "bottom" || requestedPane === "top" ? requestedPane : undefined;
|
|
880049
|
+
if (!context.showPanel) {
|
|
880050
|
+
return {
|
|
880051
|
+
status: "route_unavailable",
|
|
880052
|
+
panel,
|
|
880053
|
+
note: "The current runtime did not provide showPanel. Use the returned workspaceRoute from the TUI."
|
|
880054
|
+
};
|
|
880055
|
+
}
|
|
880056
|
+
context.showPanel(String(panel.id), pane);
|
|
880057
|
+
return {
|
|
880058
|
+
status: "routed",
|
|
880059
|
+
panel,
|
|
880060
|
+
pane: pane ?? "default",
|
|
880061
|
+
note: "Panel routing was handed to the current Agent shell bridge."
|
|
880062
|
+
};
|
|
880063
|
+
}
|
|
880064
|
+
|
|
880065
|
+
// src/tools/agent-harness-local-operations.ts
|
|
880066
|
+
function output6(value) {
|
|
880067
|
+
return { success: true, output: typeof value === "string" ? value : JSON.stringify(value, null, 2) };
|
|
880068
|
+
}
|
|
880069
|
+
function error51(message) {
|
|
880070
|
+
return { success: false, error: message };
|
|
880071
|
+
}
|
|
880072
|
+
function readString53(value) {
|
|
880073
|
+
return typeof value === "string" ? value.trim() : "";
|
|
880074
|
+
}
|
|
880075
|
+
function readFieldMap2(value) {
|
|
880076
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
880077
|
+
return {};
|
|
880078
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, typeof entry === "string" ? entry : String(entry)]));
|
|
880079
|
+
}
|
|
880080
|
+
function describeEditor(editor) {
|
|
880081
|
+
return {
|
|
880082
|
+
kind: editor.kind,
|
|
880083
|
+
mode: editor.mode,
|
|
880084
|
+
recordId: editor.recordId,
|
|
880085
|
+
title: editor.title,
|
|
880086
|
+
message: editor.message,
|
|
880087
|
+
fields: editor.fields.map((field) => ({
|
|
880088
|
+
id: field.id,
|
|
880089
|
+
label: field.label,
|
|
880090
|
+
required: field.required,
|
|
880091
|
+
multiline: field.multiline,
|
|
880092
|
+
hint: field.hint,
|
|
880093
|
+
default: field.redact ? "<redacted>" : field.value
|
|
880094
|
+
}))
|
|
880095
|
+
};
|
|
880096
|
+
}
|
|
880097
|
+
function readRecordId(args2) {
|
|
880098
|
+
const fields = readFieldMap2(args2.fields);
|
|
880099
|
+
return readString53(args2.recordId ?? args2.id ?? fields.recordId ?? fields.id);
|
|
880100
|
+
}
|
|
880101
|
+
function requireConfirmed(args2, label) {
|
|
880102
|
+
if (!readString53(args2.explicitUserRequest))
|
|
880103
|
+
return `${label} requires explicitUserRequest with the user's exact request or a short faithful summary.`;
|
|
880104
|
+
if (args2.confirm !== true)
|
|
880105
|
+
return `${label} requires confirm:true after an explicit user request.`;
|
|
880106
|
+
return null;
|
|
880107
|
+
}
|
|
880108
|
+
function fieldReader(editor, fields) {
|
|
880109
|
+
return (id) => fields[id] ?? editor.fields.find((field) => field.id === id)?.value ?? "";
|
|
880110
|
+
}
|
|
880111
|
+
function hasExecutionFields(args2) {
|
|
880112
|
+
return Object.keys(readFieldMap2(args2.fields)).some((key) => key !== "id" && key !== "recordId");
|
|
880113
|
+
}
|
|
880114
|
+
function missingRequiredFields(editor, fields) {
|
|
880115
|
+
const read = fieldReader(editor, fields);
|
|
880116
|
+
return editor.fields.filter((field) => field.required && !read(field.id).trim()).map((field) => field.id);
|
|
880117
|
+
}
|
|
880118
|
+
function registryTarget(operation) {
|
|
880119
|
+
if (operation === "memory-edit")
|
|
880120
|
+
return { domain: "memory", action: "update", requiresRecordId: true };
|
|
880121
|
+
if (operation === "memory-review")
|
|
880122
|
+
return { domain: "memory", action: "review", requiresRecordId: true };
|
|
880123
|
+
if (operation === "memory-stale")
|
|
880124
|
+
return { domain: "memory", action: "stale", requiresRecordId: true };
|
|
880125
|
+
if (operation === "memory-delete")
|
|
880126
|
+
return { domain: "memory", action: "delete", requiresRecordId: true };
|
|
880127
|
+
if (operation === "note-edit")
|
|
880128
|
+
return { domain: "note", action: "update", requiresRecordId: true };
|
|
880129
|
+
if (operation === "note-review")
|
|
880130
|
+
return { domain: "note", action: "review", requiresRecordId: true };
|
|
880131
|
+
if (operation === "note-stale")
|
|
880132
|
+
return { domain: "note", action: "stale", requiresRecordId: true };
|
|
880133
|
+
if (operation === "note-delete")
|
|
880134
|
+
return { domain: "note", action: "delete", requiresRecordId: true };
|
|
880135
|
+
if (operation === "persona-edit")
|
|
880136
|
+
return { domain: "persona", action: "update", requiresRecordId: true };
|
|
880137
|
+
if (operation === "persona-use")
|
|
880138
|
+
return { domain: "persona", action: "use", requiresRecordId: true };
|
|
880139
|
+
if (operation === "persona-review")
|
|
880140
|
+
return { domain: "persona", action: "review", requiresRecordId: true };
|
|
880141
|
+
if (operation === "persona-clear")
|
|
880142
|
+
return { domain: "persona", action: "clear_active", requiresRecordId: false };
|
|
880143
|
+
if (operation === "persona-delete")
|
|
880144
|
+
return { domain: "persona", action: "delete", requiresRecordId: true };
|
|
880145
|
+
if (operation === "skill-edit")
|
|
880146
|
+
return { domain: "skill", action: "update", requiresRecordId: true };
|
|
880147
|
+
if (operation === "skill-enable")
|
|
880148
|
+
return { domain: "skill", action: "enable", requiresRecordId: true };
|
|
880149
|
+
if (operation === "skill-disable")
|
|
880150
|
+
return { domain: "skill", action: "disable", requiresRecordId: true };
|
|
880151
|
+
if (operation === "skill-review")
|
|
880152
|
+
return { domain: "skill", action: "review", requiresRecordId: true };
|
|
880153
|
+
if (operation === "skill-delete")
|
|
880154
|
+
return { domain: "skill", action: "delete", requiresRecordId: true };
|
|
880155
|
+
if (operation === "routine-edit")
|
|
880156
|
+
return { domain: "routine", action: "update", requiresRecordId: true };
|
|
880157
|
+
if (operation === "routine-start")
|
|
880158
|
+
return { domain: "routine", action: "start", requiresRecordId: true };
|
|
880159
|
+
if (operation === "routine-enable")
|
|
880160
|
+
return { domain: "routine", action: "enable", requiresRecordId: true };
|
|
880161
|
+
if (operation === "routine-disable")
|
|
880162
|
+
return { domain: "routine", action: "disable", requiresRecordId: true };
|
|
880163
|
+
if (operation === "routine-review")
|
|
880164
|
+
return { domain: "routine", action: "review", requiresRecordId: true };
|
|
880165
|
+
if (operation === "routine-delete")
|
|
880166
|
+
return { domain: "routine", action: "delete", requiresRecordId: true };
|
|
880167
|
+
return null;
|
|
880168
|
+
}
|
|
880169
|
+
function editorForOperation(context, operation, recordId) {
|
|
880170
|
+
const shellPaths3 = context.workspace.shellPaths;
|
|
880171
|
+
if (operation === "memory-edit") {
|
|
880172
|
+
const record2 = context.clients?.agentKnowledgeApi?.memory?.get(recordId);
|
|
880173
|
+
return record2 ? createMemoryUpdateEditor(record2) : null;
|
|
880174
|
+
}
|
|
880175
|
+
if (!shellPaths3)
|
|
880176
|
+
return null;
|
|
880177
|
+
if (operation === "note-edit") {
|
|
880178
|
+
const note = AgentNoteRegistry.fromShellPaths(shellPaths3).get(recordId);
|
|
880179
|
+
return note ? createNoteUpdateEditor(note) : null;
|
|
880180
|
+
}
|
|
880181
|
+
if (operation === "note-promote-memory" || operation === "note-promote-persona" || operation === "note-promote-skill" || operation === "note-promote-routine" || operation === "note-promote-knowledge-url") {
|
|
880182
|
+
const note = AgentNoteRegistry.fromShellPaths(shellPaths3).get(recordId);
|
|
880183
|
+
if (!note)
|
|
880184
|
+
return null;
|
|
880185
|
+
if (operation === "note-promote-memory")
|
|
880186
|
+
return createMemoryEditorFromNote(note);
|
|
880187
|
+
if (operation === "note-promote-persona")
|
|
880188
|
+
return createPersonaEditorFromNote(note);
|
|
880189
|
+
if (operation === "note-promote-skill")
|
|
880190
|
+
return createSkillEditorFromNote(note);
|
|
880191
|
+
if (operation === "note-promote-routine")
|
|
880192
|
+
return createRoutineEditorFromNote(note);
|
|
880193
|
+
return note.sourceUrl ? createKnowledgeUrlEditorFromNote(note) : null;
|
|
880194
|
+
}
|
|
880195
|
+
if (operation === "persona-edit") {
|
|
880196
|
+
const registry5 = AgentPersonaRegistry.fromShellPaths(shellPaths3);
|
|
880197
|
+
const persona = registry5.get(recordId);
|
|
880198
|
+
return persona ? createPersonaUpdateEditor(persona, registry5.snapshot().activePersonaId === persona.id) : null;
|
|
880199
|
+
}
|
|
880200
|
+
if (operation === "skill-edit") {
|
|
880201
|
+
const skill = AgentSkillRegistry.fromShellPaths(shellPaths3).get(recordId);
|
|
880202
|
+
return skill ? createSkillUpdateEditor(skill) : null;
|
|
880203
|
+
}
|
|
880204
|
+
if (operation === "routine-edit") {
|
|
880205
|
+
const routine = AgentRoutineRegistry.fromShellPaths(shellPaths3).get(recordId);
|
|
880206
|
+
return routine ? createRoutineUpdateEditor(routine) : null;
|
|
880207
|
+
}
|
|
880208
|
+
return null;
|
|
880209
|
+
}
|
|
880210
|
+
function localRegistryArgsFromEditor(editor, fields, id) {
|
|
880211
|
+
const read = fieldReader(editor, fields);
|
|
880212
|
+
if (editor.kind === "memory")
|
|
880213
|
+
return { domain: "memory", action: editor.mode === "update" ? "update" : "create", id, cls: read("cls"), scope: read("scope"), summary: read("summary"), detail: read("detail"), tags: splitList5(read("tags")), confidence: read("confidence"), provenance: editor.recordId ? "agent-harness-local-operation" : "agent-harness-note-promotion" };
|
|
880214
|
+
if (editor.kind === "note")
|
|
880215
|
+
return { domain: "note", action: "update", id, title: read("title"), body: read("body"), sourceUrl: read("sourceUrl"), tags: splitList5(read("tags")), provenance: "agent-harness-local-operation" };
|
|
880216
|
+
if (editor.kind === "persona")
|
|
880217
|
+
return { domain: "persona", action: editor.mode === "update" ? "update" : "create", id, name: read("name"), description: read("description"), body: read("body"), tags: splitList5(read("tags")), triggers: splitList5(read("triggers")), activate: read("activate"), provenance: editor.recordId ? "agent-harness-local-operation" : "agent-harness-note-promotion" };
|
|
880218
|
+
if (editor.kind === "skill")
|
|
880219
|
+
return { domain: "skill", action: editor.mode === "update" ? "update" : "create", id, name: read("name"), description: read("description"), procedure: read("procedure"), tags: splitList5(read("tags")), triggers: splitList5(read("triggers")), requiresEnv: splitList5(read("requiresEnv")), requiresCommands: splitList5(read("requiresCommands")), enabled: isAffirmative15(read("enabled")), provenance: editor.recordId ? "agent-harness-local-operation" : "agent-harness-note-promotion" };
|
|
880220
|
+
return { domain: "routine", action: editor.mode === "update" ? "update" : "create", id, name: read("name"), description: read("description"), steps: read("steps"), tags: splitList5(read("tags")), triggers: splitList5(read("triggers")), requiresEnv: splitList5(read("requiresEnv")), requiresCommands: splitList5(read("requiresCommands")), enabled: isAffirmative15(read("enabled")), provenance: editor.recordId ? "agent-harness-local-operation" : "agent-harness-note-promotion" };
|
|
880221
|
+
}
|
|
880222
|
+
function localRegistryArgsForTarget(target, args2, recordId) {
|
|
880223
|
+
const fields = readFieldMap2(args2.fields);
|
|
880224
|
+
const base2 = { domain: target.domain, action: target.action, ...recordId ? { id: recordId } : {} };
|
|
880225
|
+
const edit = target.action === "update" ? localRegistryArgsFromEditor({ kind: target.domain, mode: "update", recordId, title: "", selectedFieldIndex: 0, message: "", fields: [] }, fields, recordId) : {};
|
|
880226
|
+
return {
|
|
880227
|
+
...base2,
|
|
880228
|
+
...edit,
|
|
880229
|
+
...target.action === "stale" && fields.reason ? { reason: fields.reason } : {},
|
|
880230
|
+
...target.action === "delete" ? { confirm: args2.confirm, explicitUserRequest: readString53(args2.explicitUserRequest) } : {}
|
|
880231
|
+
};
|
|
880232
|
+
}
|
|
880233
|
+
async function executeTool(toolRegistry, name51, toolArgs) {
|
|
880234
|
+
if (!toolRegistry.has(name51))
|
|
880235
|
+
return output6({ status: "model_tool_required", modelExecution: { tool: name51, args: toolArgs } });
|
|
880236
|
+
const result2 = await toolRegistry.execute(`agent-harness-${name51}-${Date.now()}`, name51, toolArgs);
|
|
880237
|
+
if (!result2.success)
|
|
880238
|
+
return error51(result2.error ?? `${name51} failed.`);
|
|
880239
|
+
return output6({ status: "executed_model_tool", tool: name51, output: result2.output ?? "" });
|
|
880240
|
+
}
|
|
880241
|
+
function describeLocalWorkspaceModelExecution(action2) {
|
|
880242
|
+
if (action2.kind === "local-selection")
|
|
880243
|
+
return { tool: "agent_local_registry", domain: action2.localKind, actions: ["list", "search", "get"], note: "TUI selection maps to recordId for model-run local-operation actions." };
|
|
880244
|
+
if (!action2.localOperation)
|
|
880245
|
+
return null;
|
|
880246
|
+
const target = registryTarget(action2.localOperation);
|
|
880247
|
+
if (target)
|
|
880248
|
+
return { tool: "agent_local_registry", domain: target.domain, action: target.action, requiresRecordId: target.requiresRecordId };
|
|
880249
|
+
if (action2.localOperation === "note-promote-knowledge-url")
|
|
880250
|
+
return { tool: "agent_knowledge_ingest", sourceKind: "url", requiresRecordId: true, selectedRecordDomain: "note" };
|
|
880251
|
+
return { tool: "agent_local_registry", selectedRecordDomain: "note", action: "create", requiresRecordId: true };
|
|
880252
|
+
}
|
|
880253
|
+
async function runLocalWorkspaceAction(deps, action2, args2) {
|
|
880254
|
+
if (action2.kind === "local-selection")
|
|
880255
|
+
return output6({ status: "local_selection", action: action2.id, modelExecution: describeLocalWorkspaceModelExecution(action2) });
|
|
880256
|
+
const operation = action2.localOperation;
|
|
880257
|
+
if (!operation)
|
|
880258
|
+
return output6({ status: "local_registry_action", action: action2.id, modelExecution: describeLocalWorkspaceModelExecution(action2) });
|
|
880259
|
+
const target = registryTarget(operation);
|
|
880260
|
+
const recordId = readRecordId(args2);
|
|
880261
|
+
if (target?.requiresRecordId && !recordId)
|
|
880262
|
+
return output6({ status: "needs_record_id", action: action2.id, modelExecution: describeLocalWorkspaceModelExecution(action2) });
|
|
880263
|
+
const editor = recordId ? editorForOperation(deps.commandContext, operation, recordId) : null;
|
|
880264
|
+
if (editor && !hasExecutionFields(args2) && args2.confirm !== true)
|
|
880265
|
+
return output6({ status: "editor", action: action2.id, editor: describeEditor(editor), modelExecution: describeLocalWorkspaceModelExecution(action2) });
|
|
880266
|
+
const confirmationError2 = requireConfirmed(args2, "Workspace local registry action");
|
|
880267
|
+
if (confirmationError2)
|
|
880268
|
+
return error51(confirmationError2);
|
|
880269
|
+
if (editor) {
|
|
880270
|
+
const fields = readFieldMap2(args2.fields);
|
|
880271
|
+
const missing = missingRequiredFields(editor, fields);
|
|
880272
|
+
if (missing.length > 0)
|
|
880273
|
+
return output6({ status: "missing_required_fields", missing, action: action2.id, editor: describeEditor(editor) });
|
|
880274
|
+
if (editor.kind === "knowledge-url")
|
|
880275
|
+
return executeTool(deps.toolRegistry, "agent_knowledge_ingest", { sourceKind: "url", url: fieldReader(editor, fields)("url"), tags: splitList5(fieldReader(editor, fields)("tags")), folderPath: fieldReader(editor, fields)("folder"), confirm: args2.confirm, explicitUserRequest: readString53(args2.explicitUserRequest) });
|
|
880276
|
+
return executeTool(deps.toolRegistry, "agent_local_registry", localRegistryArgsFromEditor(editor, fields, recordId));
|
|
880277
|
+
}
|
|
880278
|
+
if (!target)
|
|
880279
|
+
return output6({ status: "local_registry_action", action: action2.id, modelExecution: describeLocalWorkspaceModelExecution(action2) });
|
|
880280
|
+
return executeTool(deps.toolRegistry, "agent_local_registry", localRegistryArgsForTarget(target, args2, recordId));
|
|
880281
|
+
}
|
|
880282
|
+
|
|
880283
|
+
// src/tools/agent-harness-model-tool-catalog.ts
|
|
880284
|
+
function readString54(value) {
|
|
880285
|
+
return typeof value === "string" ? value.trim() : "";
|
|
880286
|
+
}
|
|
880287
|
+
function readLimit8(value, fallback) {
|
|
880288
|
+
const parsed = typeof value === "string" && value.trim() ? Number(value) : value;
|
|
880289
|
+
if (typeof parsed !== "number" || !Number.isFinite(parsed))
|
|
880290
|
+
return fallback;
|
|
880291
|
+
return Math.max(1, Math.min(500, Math.trunc(parsed)));
|
|
880292
|
+
}
|
|
880293
|
+
function listHarnessModelTools(toolRegistry, args2) {
|
|
880294
|
+
const query2 = readString54(args2.query).toLowerCase();
|
|
880295
|
+
const includeParameters = args2.includeParameters === true;
|
|
880296
|
+
const limit3 = readLimit8(args2.limit, 200);
|
|
880297
|
+
return toolRegistry.getToolDefinitions().filter((tool2) => !query2 || [tool2.name, tool2.description, ...tool2.sideEffects ?? []].join(`
|
|
880298
|
+
`).toLowerCase().includes(query2)).sort((a4, b3) => a4.name.localeCompare(b3.name)).slice(0, limit3).map((tool2) => ({
|
|
880299
|
+
name: tool2.name,
|
|
880300
|
+
description: tool2.description,
|
|
880301
|
+
sideEffects: tool2.sideEffects ?? [],
|
|
880302
|
+
concurrency: tool2.concurrency ?? "parallel",
|
|
880303
|
+
supportsProgress: tool2.supportsProgress ?? false,
|
|
880304
|
+
supportsStreamingOutput: tool2.supportsStreamingOutput ?? false,
|
|
880305
|
+
...includeParameters ? { parameters: tool2.parameters } : {}
|
|
880306
|
+
}));
|
|
880307
|
+
}
|
|
880308
|
+
|
|
879624
880309
|
// src/tools/agent-harness-tool.ts
|
|
879625
880310
|
var MODES = [
|
|
879626
880311
|
"summary",
|
|
880312
|
+
"cli_commands",
|
|
880313
|
+
"cli_command",
|
|
880314
|
+
"panels",
|
|
880315
|
+
"panel",
|
|
880316
|
+
"open_panel",
|
|
880317
|
+
"shortcuts",
|
|
880318
|
+
"keybindings",
|
|
880319
|
+
"keybinding",
|
|
880320
|
+
"set_keybinding",
|
|
880321
|
+
"reset_keybinding",
|
|
879627
880322
|
"commands",
|
|
879628
880323
|
"command",
|
|
879629
880324
|
"run_command",
|
|
@@ -879642,10 +880337,10 @@ var MODES = [
|
|
|
879642
880337
|
function isMode(value) {
|
|
879643
880338
|
return typeof value === "string" && MODES.includes(value);
|
|
879644
880339
|
}
|
|
879645
|
-
function
|
|
880340
|
+
function readString55(value) {
|
|
879646
880341
|
return typeof value === "string" ? value.trim() : "";
|
|
879647
880342
|
}
|
|
879648
|
-
function
|
|
880343
|
+
function readLimit9(value, fallback) {
|
|
879649
880344
|
const parsed = typeof value === "string" && value.trim() ? Number(value) : value;
|
|
879650
880345
|
if (typeof parsed !== "number" || !Number.isFinite(parsed))
|
|
879651
880346
|
return fallback;
|
|
@@ -879656,7 +880351,7 @@ function readStringArray12(value) {
|
|
|
879656
880351
|
return [];
|
|
879657
880352
|
return value.map((entry) => typeof entry === "string" ? entry : String(entry));
|
|
879658
880353
|
}
|
|
879659
|
-
function
|
|
880354
|
+
function readFieldMap3(value) {
|
|
879660
880355
|
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
879661
880356
|
return {};
|
|
879662
880357
|
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, typeof entry === "string" ? entry : String(entry)]));
|
|
@@ -879670,6 +880365,12 @@ function output7(value) {
|
|
|
879670
880365
|
function error52(message) {
|
|
879671
880366
|
return { success: false, error: message };
|
|
879672
880367
|
}
|
|
880368
|
+
var KEY_COMBO_PARAMETER_SCHEMA = {
|
|
880369
|
+
type: "object",
|
|
880370
|
+
properties: { key: { type: "string" }, ctrl: { type: "boolean" }, shift: { type: "boolean" }, alt: { type: "boolean" } },
|
|
880371
|
+
required: ["key"],
|
|
880372
|
+
additionalProperties: false
|
|
880373
|
+
};
|
|
879673
880374
|
function commandMatches(command8, query2) {
|
|
879674
880375
|
if (!query2)
|
|
879675
880376
|
return true;
|
|
@@ -879725,8 +880426,8 @@ function describeWorkspaceEditor(editor) {
|
|
|
879725
880426
|
};
|
|
879726
880427
|
}
|
|
879727
880428
|
function selectedRoutineFromArgs(snapshot, args2) {
|
|
879728
|
-
const fields =
|
|
879729
|
-
const routineId =
|
|
880429
|
+
const fields = readFieldMap3(args2.fields);
|
|
880430
|
+
const routineId = readString55(args2.recordId) || readString55(fields.routineId) || readString55(fields.id);
|
|
879730
880431
|
if (!routineId)
|
|
879731
880432
|
return null;
|
|
879732
880433
|
return snapshot.localRoutines.find((routine) => routine.id === routineId || routine.name.toLowerCase() === routineId.toLowerCase()) ?? null;
|
|
@@ -879794,17 +880495,17 @@ function localEditorModelExecution(editorKind) {
|
|
|
879794
880495
|
return "Use the command field, editor schema, or a first-class Agent model tool when available.";
|
|
879795
880496
|
}
|
|
879796
880497
|
function listWorkspaceActions(deps, args2) {
|
|
879797
|
-
const query2 =
|
|
879798
|
-
const categoryId =
|
|
879799
|
-
const limit3 =
|
|
880498
|
+
const query2 = readString55(args2.query);
|
|
880499
|
+
const categoryId = readString55(args2.categoryId || args2.category);
|
|
880500
|
+
const limit3 = readLimit9(args2.limit, 200);
|
|
879800
880501
|
const includeEditor = args2.includeParameters === true;
|
|
879801
880502
|
const editorContext = includeEditor ? buildWorkspaceEditorContext(deps.commandContext, args2) : null;
|
|
879802
880503
|
const source = query2 ? searchAgentWorkspaceActions(AGENT_WORKSPACE_CATEGORIES, query2).map((result2) => ({ category: result2.category, action: result2.action })) : allWorkspaceActions();
|
|
879803
880504
|
return source.filter((entry) => !categoryId || entry.category.id === categoryId).slice(0, limit3).map((entry) => describeWorkspaceAction(entry.category, entry.action, { includeEditor, editorContext }));
|
|
879804
880505
|
}
|
|
879805
880506
|
function findWorkspaceAction(args2) {
|
|
879806
|
-
const actionId =
|
|
879807
|
-
const categoryId =
|
|
880507
|
+
const actionId = readString55(args2.actionId || args2.query);
|
|
880508
|
+
const categoryId = readString55(args2.categoryId || args2.category);
|
|
879808
880509
|
if (!actionId)
|
|
879809
880510
|
return null;
|
|
879810
880511
|
return allWorkspaceActions().find((entry) => {
|
|
@@ -879814,31 +880515,12 @@ function findWorkspaceAction(args2) {
|
|
|
879814
880515
|
}) ?? null;
|
|
879815
880516
|
}
|
|
879816
880517
|
function listCommands(commandRegistry, args2) {
|
|
879817
|
-
const query2 =
|
|
879818
|
-
const limit3 =
|
|
880518
|
+
const query2 = readString55(args2.query);
|
|
880519
|
+
const limit3 = readLimit9(args2.limit, 200);
|
|
879819
880520
|
return commandRegistry.list().filter((command8) => commandMatches(command8, query2)).sort((a4, b3) => a4.name.localeCompare(b3.name)).slice(0, limit3).map(describeCommand);
|
|
879820
880521
|
}
|
|
879821
|
-
function listTools(toolRegistry, args2) {
|
|
879822
|
-
const query2 = readString51(args2.query).toLowerCase();
|
|
879823
|
-
const includeParameters = args2.includeParameters === true;
|
|
879824
|
-
const limit3 = readLimit5(args2.limit, 200);
|
|
879825
|
-
return toolRegistry.getToolDefinitions().filter((tool2) => {
|
|
879826
|
-
if (!query2)
|
|
879827
|
-
return true;
|
|
879828
|
-
return [tool2.name, tool2.description, ...tool2.sideEffects ?? []].join(`
|
|
879829
|
-
`).toLowerCase().includes(query2);
|
|
879830
|
-
}).sort((a4, b3) => a4.name.localeCompare(b3.name)).slice(0, limit3).map((tool2) => ({
|
|
879831
|
-
name: tool2.name,
|
|
879832
|
-
description: tool2.description,
|
|
879833
|
-
sideEffects: tool2.sideEffects ?? [],
|
|
879834
|
-
concurrency: tool2.concurrency ?? "parallel",
|
|
879835
|
-
supportsProgress: tool2.supportsProgress ?? false,
|
|
879836
|
-
supportsStreamingOutput: tool2.supportsStreamingOutput ?? false,
|
|
879837
|
-
...includeParameters ? { parameters: tool2.parameters } : {}
|
|
879838
|
-
}));
|
|
879839
|
-
}
|
|
879840
880522
|
function requireConfirmedAction(args2, action2) {
|
|
879841
|
-
const explicitUserRequest =
|
|
880523
|
+
const explicitUserRequest = readString55(args2.explicitUserRequest);
|
|
879842
880524
|
if (!explicitUserRequest)
|
|
879843
880525
|
return `${action2} requires explicitUserRequest with the user's exact request or a short faithful summary.`;
|
|
879844
880526
|
if (args2.confirm !== true)
|
|
@@ -879846,7 +880528,7 @@ function requireConfirmedAction(args2, action2) {
|
|
|
879846
880528
|
return null;
|
|
879847
880529
|
}
|
|
879848
880530
|
function commandFromArgs(args2) {
|
|
879849
|
-
const rawCommand =
|
|
880531
|
+
const rawCommand = readString55(args2.command);
|
|
879850
880532
|
if (rawCommand) {
|
|
879851
880533
|
const parsed = parseSlashCommand(rawCommand);
|
|
879852
880534
|
if (!parsed.name)
|
|
@@ -879856,7 +880538,7 @@ function commandFromArgs(args2) {
|
|
|
879856
880538
|
args: parsed.args
|
|
879857
880539
|
};
|
|
879858
880540
|
}
|
|
879859
|
-
const commandName =
|
|
880541
|
+
const commandName = readString55(args2.commandName).replace(/^\//, "");
|
|
879860
880542
|
if (!commandName)
|
|
879861
880543
|
return null;
|
|
879862
880544
|
const commandArgs = readStringArray12(args2.args);
|
|
@@ -879906,7 +880588,7 @@ function missingRequiredEditorFields(editor, fields) {
|
|
|
879906
880588
|
return editor.fields.filter((field) => field.required && !readField(field.id).trim()).map((field) => field.id);
|
|
879907
880589
|
}
|
|
879908
880590
|
async function runWorkspaceEditorAction(deps, action2, editor, args2) {
|
|
879909
|
-
const fields =
|
|
880591
|
+
const fields = readFieldMap3(args2.fields);
|
|
879910
880592
|
const missing = missingRequiredEditorFields(editor, fields);
|
|
879911
880593
|
if (missing.length > 0) {
|
|
879912
880594
|
return output7({
|
|
@@ -880038,29 +880720,14 @@ async function runWorkspaceAction(deps, args2) {
|
|
|
880038
880720
|
action: describeWorkspaceAction(category, action2, { includeEditor: true, editorContext })
|
|
880039
880721
|
});
|
|
880040
880722
|
}
|
|
880041
|
-
function connectedHostSummary(context, toolRegistry) {
|
|
880042
|
-
const shellPaths3 = context.workspace.shellPaths;
|
|
880043
|
-
const homeDirectory = shellPaths3?.homeDirectory ?? context.platform.configManager.getHomeDirectory() ?? "";
|
|
880044
|
-
const connection5 = resolveAgentConnectedHostConnection(context.platform.configManager, homeDirectory);
|
|
880045
|
-
return {
|
|
880046
|
-
baseUrl: connection5.baseUrl,
|
|
880047
|
-
operatorToken: connection5.token ? "configured" : "missing",
|
|
880048
|
-
tokenPath: connection5.tokenPath,
|
|
880049
|
-
ownership: "external-connected-host",
|
|
880050
|
-
lifecycle: "GoodVibes Agent can use public connected-host operator routes, but does not start, stop, restart, install, expose, or mutate the host listener.",
|
|
880051
|
-
routeFamilies: connectedHostRouteFamilies(),
|
|
880052
|
-
capabilities: connectedHostCapabilityMap(toolRegistry),
|
|
880053
|
-
blockedCapabilities: blockedConnectedHostCapabilities()
|
|
880054
|
-
};
|
|
880055
|
-
}
|
|
880056
880723
|
function createAgentHarnessTool(deps) {
|
|
880057
880724
|
return {
|
|
880058
880725
|
definition: {
|
|
880059
880726
|
name: "agent_harness",
|
|
880060
880727
|
description: [
|
|
880061
880728
|
"Discover and operate the GoodVibes Agent harness from the main conversation.",
|
|
880062
|
-
"Use this tool to inspect Agent workspace actions, slash commands with policy metadata, model tools, connected-host capabilities, and Agent settings, or to invoke a workspace action/command through the same in-process command registry the user uses in the TUI.",
|
|
880063
|
-
"Discovery modes are read-only. Setting writes, resets, slash command invocation, and workspace action invocation require confirm:true plus explicitUserRequest.",
|
|
880729
|
+
"Use this tool to inspect Agent workspace actions, built-in panels, top-level CLI mirrors, keybindings, slash commands with policy metadata, model tools, connected-host capabilities, and Agent settings, or to invoke a workspace action/command through the same in-process command registry the user uses in the TUI.",
|
|
880730
|
+
"Discovery modes are read-only. Setting/keybinding writes, resets, slash command invocation, and workspace action invocation require confirm:true plus explicitUserRequest.",
|
|
880064
880731
|
"This tool preserves Agent product boundaries: connected-host lifecycle and listener posture stay externally owned, connected-host mode reports allowed and blocked route families, and secret-backed settings store raw values through the secret manager while config receives only a secret reference."
|
|
880065
880732
|
].join(" "),
|
|
880066
880733
|
parameters: {
|
|
@@ -880077,11 +880744,15 @@ function createAgentHarnessTool(deps) {
|
|
|
880077
880744
|
},
|
|
880078
880745
|
command: {
|
|
880079
880746
|
type: "string",
|
|
880080
|
-
description: 'Full slash command string for mode run_command, for example "/settings get provider.model".'
|
|
880747
|
+
description: 'Full slash command string for mode run_command, for example "/settings get provider.model". In cli_command mode this may also hold a top-level CLI string such as "goodvibes-agent status --json".'
|
|
880748
|
+
},
|
|
880749
|
+
cliCommand: {
|
|
880750
|
+
type: "string",
|
|
880751
|
+
description: 'Top-level CLI command string for mode cli_command, for example "goodvibes-agent status --json" or "profiles list". This mode is read-only metadata/parse inspection.'
|
|
880081
880752
|
},
|
|
880082
880753
|
commandName: {
|
|
880083
880754
|
type: "string",
|
|
880084
|
-
description: "Slash command root without the leading slash for mode command or run_command."
|
|
880755
|
+
description: "Slash command root without the leading slash for mode command or run_command, or a top-level CLI command token for cli_command."
|
|
880085
880756
|
},
|
|
880086
880757
|
args: {
|
|
880087
880758
|
type: "array",
|
|
@@ -880092,15 +880763,28 @@ function createAgentHarnessTool(deps) {
|
|
|
880092
880763
|
type: "string",
|
|
880093
880764
|
description: "Agent workspace category id for workspace action filtering."
|
|
880094
880765
|
},
|
|
880766
|
+
panelId: {
|
|
880767
|
+
type: "string",
|
|
880768
|
+
description: "Built-in panel id for panel or open_panel modes."
|
|
880769
|
+
},
|
|
880095
880770
|
actionId: {
|
|
880096
880771
|
type: "string",
|
|
880097
|
-
description: "Agent workspace action id for workspace_action or run_workspace_action."
|
|
880772
|
+
description: "Agent workspace action id for workspace_action or run_workspace_action, or keybinding action id for keybinding/set_keybinding/reset_keybinding."
|
|
880098
880773
|
},
|
|
880099
880774
|
fields: {
|
|
880100
880775
|
type: "object",
|
|
880101
880776
|
additionalProperties: { type: "string" },
|
|
880102
880777
|
description: "Field values for run_workspace_action when the workspace action opens an editor form."
|
|
880103
880778
|
},
|
|
880779
|
+
combo: {
|
|
880780
|
+
...KEY_COMBO_PARAMETER_SCHEMA,
|
|
880781
|
+
description: 'Single key combo for set_keybinding, for example { "key": "g", "ctrl": true }.'
|
|
880782
|
+
},
|
|
880783
|
+
combos: {
|
|
880784
|
+
type: "array",
|
|
880785
|
+
items: KEY_COMBO_PARAMETER_SCHEMA,
|
|
880786
|
+
description: "Multiple key combos for set_keybinding."
|
|
880787
|
+
},
|
|
880104
880788
|
recordId: {
|
|
880105
880789
|
type: "string",
|
|
880106
880790
|
description: "Selected Agent-local record id for selection-based local workspace operations."
|
|
@@ -880137,9 +880821,14 @@ function createAgentHarnessTool(deps) {
|
|
|
880137
880821
|
type: "number",
|
|
880138
880822
|
description: "Maximum catalog entries to return."
|
|
880139
880823
|
},
|
|
880824
|
+
pane: {
|
|
880825
|
+
type: "string",
|
|
880826
|
+
enum: ["top", "bottom"],
|
|
880827
|
+
description: "Preferred panel pane for open_panel when the current shell supports panel routing."
|
|
880828
|
+
},
|
|
880140
880829
|
confirm: {
|
|
880141
880830
|
type: "boolean",
|
|
880142
|
-
description: "Required true for set_setting, reset_setting, run_command, and mutating run_workspace_action calls after an explicit user request."
|
|
880831
|
+
description: "Required true for set_setting, reset_setting, run_command, open_panel, and mutating run_workspace_action calls after an explicit user request."
|
|
880143
880832
|
},
|
|
880144
880833
|
explicitUserRequest: {
|
|
880145
880834
|
type: "string",
|
|
@@ -880159,12 +880848,20 @@ function createAgentHarnessTool(deps) {
|
|
|
880159
880848
|
try {
|
|
880160
880849
|
if (args2.mode === "summary") {
|
|
880161
880850
|
return output7({
|
|
880851
|
+
cliCommands: totalHarnessCliCommands(),
|
|
880852
|
+
blockedCliCommandTokens: blockedHarnessCliCommandTokens(),
|
|
880853
|
+
panels: totalHarnessPanels(deps.commandContext),
|
|
880854
|
+
shortcuts: totalHarnessShortcuts(deps.commandContext),
|
|
880855
|
+
keybindings: totalHarnessKeybindings(deps.commandContext),
|
|
880162
880856
|
commands: deps.commandRegistry.list().length,
|
|
880163
880857
|
settings: deps.commandContext.platform.configManager.getSchema().length,
|
|
880164
880858
|
workspaceCategories: AGENT_WORKSPACE_CATEGORIES.length,
|
|
880165
880859
|
workspaceActions: allWorkspaceActions().length,
|
|
880166
880860
|
tools: deps.toolRegistry.getToolDefinitions().length,
|
|
880167
880861
|
modelAccess: {
|
|
880862
|
+
cliCommands: 'Use mode:"cli_commands" and mode:"cli_command" to inspect package CLI mirrors and their preferred in-process model routes. CLI modes are discovery-only.',
|
|
880863
|
+
panels: 'Use mode:"panels" and mode:"panel" to inspect built-in panel catalog/open state; use mode:"open_panel" with confirm:true plus explicitUserRequest to route a visible panel/workspace change.',
|
|
880864
|
+
shortcuts: 'Use mode:"shortcuts" to inspect fixed shortcuts plus configurable keybindings. Use mode:"set_keybinding" and mode:"reset_keybinding" with confirm:true plus explicitUserRequest to edit the same config file the user edits.',
|
|
880168
880865
|
slashCommands: 'Use mode:"commands" and mode:"command" to inspect; use mode:"run_command" with confirm:true plus explicitUserRequest to execute.',
|
|
880169
880866
|
workspace: 'Use mode:"workspace_actions" to list and mode:"workspace_action" for editor schemas; set includeParameters:true on workspace_actions to inline editor schemas.',
|
|
880170
880867
|
settings: 'Use mode:"settings", mode:"get_setting", mode:"set_setting", and mode:"reset_setting".',
|
|
@@ -880175,12 +880872,64 @@ function createAgentHarnessTool(deps) {
|
|
|
880175
880872
|
connectedHost: connectedHostSummary(deps.commandContext, deps.toolRegistry)
|
|
880176
880873
|
});
|
|
880177
880874
|
}
|
|
880875
|
+
if (args2.mode === "cli_commands") {
|
|
880876
|
+
const commands3 = listHarnessCliCommands(args2);
|
|
880877
|
+
return output7({
|
|
880878
|
+
commands: commands3,
|
|
880879
|
+
returned: commands3.length,
|
|
880880
|
+
total: totalHarnessCliCommands(),
|
|
880881
|
+
blockedTokens: blockedHarnessCliCommandTokens(),
|
|
880882
|
+
policy: "CLI modes are read-only discovery. Use first-class model tools, workspace actions, settings modes, or confirmed slash-command mirrors for in-process operation."
|
|
880883
|
+
});
|
|
880884
|
+
}
|
|
880885
|
+
if (args2.mode === "cli_command") {
|
|
880886
|
+
return output7(describeHarnessCliCommand(args2));
|
|
880887
|
+
}
|
|
880888
|
+
if (args2.mode === "panels") {
|
|
880889
|
+
const panels = listHarnessPanels(deps.commandContext, args2);
|
|
880890
|
+
return output7({
|
|
880891
|
+
panels,
|
|
880892
|
+
returned: panels.length,
|
|
880893
|
+
total: totalHarnessPanels(deps.commandContext),
|
|
880894
|
+
policy: "Panel modes expose Agent/TUI operator view catalog and open state. open_panel is confirmation-gated and routes through the current Agent shell bridge."
|
|
880895
|
+
});
|
|
880896
|
+
}
|
|
880897
|
+
if (args2.mode === "panel") {
|
|
880898
|
+
const panel = describeHarnessPanel(deps.commandContext, args2);
|
|
880899
|
+
return panel ? output7(panel) : error52(`Unknown panel ${readString55(args2.panelId || args2.query) || "<missing>"}.`);
|
|
880900
|
+
}
|
|
880901
|
+
if (args2.mode === "open_panel") {
|
|
880902
|
+
const confirmationError2 = requireConfirmedAction(args2, "Panel routing");
|
|
880903
|
+
if (confirmationError2)
|
|
880904
|
+
return error52(confirmationError2);
|
|
880905
|
+
return output7(openHarnessPanel(deps.commandContext, args2));
|
|
880906
|
+
}
|
|
880907
|
+
if (args2.mode === "shortcuts")
|
|
880908
|
+
return output7(listHarnessShortcuts(deps.commandContext, args2));
|
|
880909
|
+
if (args2.mode === "keybindings")
|
|
880910
|
+
return output7(listHarnessKeybindings(deps.commandContext, args2));
|
|
880911
|
+
if (args2.mode === "keybinding") {
|
|
880912
|
+
const binding = describeHarnessKeybinding(deps.commandContext, args2);
|
|
880913
|
+
return binding ? output7(binding) : error52(`Unknown keybinding action ${readString55(args2.actionId || args2.key || args2.query) || "<missing>"}.`);
|
|
880914
|
+
}
|
|
880915
|
+
if (args2.mode === "set_keybinding") {
|
|
880916
|
+
const confirmationError2 = requireConfirmedAction(args2, "Keybinding mutation");
|
|
880917
|
+
if (confirmationError2)
|
|
880918
|
+
return error52(confirmationError2);
|
|
880919
|
+
return output7(setHarnessKeybinding(deps.commandContext, args2));
|
|
880920
|
+
}
|
|
880921
|
+
if (args2.mode === "reset_keybinding") {
|
|
880922
|
+
const confirmationError2 = requireConfirmedAction(args2, "Keybinding reset");
|
|
880923
|
+
if (confirmationError2)
|
|
880924
|
+
return error52(confirmationError2);
|
|
880925
|
+
return output7(resetHarnessKeybinding(deps.commandContext, args2));
|
|
880926
|
+
}
|
|
880178
880927
|
if (args2.mode === "commands") {
|
|
880179
880928
|
const commands3 = listCommands(deps.commandRegistry, args2);
|
|
880180
880929
|
return output7({ commands: commands3, returned: commands3.length, total: deps.commandRegistry.list().length });
|
|
880181
880930
|
}
|
|
880182
880931
|
if (args2.mode === "command") {
|
|
880183
|
-
const name51 =
|
|
880932
|
+
const name51 = readString55(args2.commandName).replace(/^\//, "");
|
|
880184
880933
|
const command8 = name51 ? deps.commandRegistry.get(name51) : null;
|
|
880185
880934
|
return command8 ? output7(describeCommand(command8)) : error52(`Unknown slash command /${name51 || "<missing>"}.`);
|
|
880186
880935
|
}
|
|
@@ -880188,16 +880937,16 @@ function createAgentHarnessTool(deps) {
|
|
|
880188
880937
|
return runCommand2(deps, args2);
|
|
880189
880938
|
if (args2.mode === "settings") {
|
|
880190
880939
|
const settings = listHarnessSettings(deps.commandContext.platform.configManager, {
|
|
880191
|
-
category:
|
|
880192
|
-
prefix:
|
|
880193
|
-
query:
|
|
880940
|
+
category: readString55(args2.category) || undefined,
|
|
880941
|
+
prefix: readString55(args2.prefix) || undefined,
|
|
880942
|
+
query: readString55(args2.query) || undefined,
|
|
880194
880943
|
includeHidden: args2.includeHidden === true,
|
|
880195
|
-
limit:
|
|
880944
|
+
limit: readLimit9(args2.limit, 100)
|
|
880196
880945
|
});
|
|
880197
880946
|
return output7({ settings, returned: settings.length, policy: settingsPolicySummary() });
|
|
880198
880947
|
}
|
|
880199
880948
|
if (args2.mode === "get_setting") {
|
|
880200
|
-
const key =
|
|
880949
|
+
const key = readString55(args2.key);
|
|
880201
880950
|
const setting = getHarnessSetting(deps.commandContext.platform.configManager, key);
|
|
880202
880951
|
return setting ? output7(setting) : error52(`Unknown setting ${key || "<missing>"}.`);
|
|
880203
880952
|
}
|
|
@@ -880207,7 +880956,7 @@ function createAgentHarnessTool(deps) {
|
|
|
880207
880956
|
return error52(confirmationError2);
|
|
880208
880957
|
if (args2.value === undefined)
|
|
880209
880958
|
return error52("set_setting requires value.");
|
|
880210
|
-
const key =
|
|
880959
|
+
const key = readString55(args2.key);
|
|
880211
880960
|
const result2 = await setHarnessSetting(deps.commandContext.platform.configManager, deps.commandContext.platform.secretsManager, key, args2.value);
|
|
880212
880961
|
return output7(result2);
|
|
880213
880962
|
}
|
|
@@ -880215,7 +880964,7 @@ function createAgentHarnessTool(deps) {
|
|
|
880215
880964
|
const confirmationError2 = requireConfirmedAction(args2, "Setting reset");
|
|
880216
880965
|
if (confirmationError2)
|
|
880217
880966
|
return error52(confirmationError2);
|
|
880218
|
-
const key =
|
|
880967
|
+
const key = readString55(args2.key);
|
|
880219
880968
|
const result2 = await resetHarnessSetting(deps.commandContext.platform.configManager, deps.commandContext.platform.secretsManager, key);
|
|
880220
880969
|
return output7(result2);
|
|
880221
880970
|
}
|
|
@@ -880232,12 +880981,12 @@ function createAgentHarnessTool(deps) {
|
|
|
880232
880981
|
if (args2.mode === "workspace_action") {
|
|
880233
880982
|
const found = findWorkspaceAction(args2);
|
|
880234
880983
|
const editorContext = buildWorkspaceEditorContext(deps.commandContext, args2);
|
|
880235
|
-
return found ? output7(describeWorkspaceAction(found.category, found.action, { includeEditor: true, editorContext })) : error52(`Unknown Agent workspace action ${
|
|
880984
|
+
return found ? output7(describeWorkspaceAction(found.category, found.action, { includeEditor: true, editorContext })) : error52(`Unknown Agent workspace action ${readString55(args2.actionId || args2.query) || "<missing>"}.`);
|
|
880236
880985
|
}
|
|
880237
880986
|
if (args2.mode === "run_workspace_action")
|
|
880238
880987
|
return runWorkspaceAction(deps, args2);
|
|
880239
880988
|
if (args2.mode === "tools") {
|
|
880240
|
-
const tools3 =
|
|
880989
|
+
const tools3 = listHarnessModelTools(deps.toolRegistry, args2);
|
|
880241
880990
|
return output7({ tools: tools3, returned: tools3.length, total: deps.toolRegistry.getToolDefinitions().length });
|
|
880242
880991
|
}
|
|
880243
880992
|
if (args2.mode === "connected_host")
|
|
@@ -880322,7 +881071,7 @@ async function bootstrapRuntime(stdout, options) {
|
|
|
880322
881071
|
const {
|
|
880323
881072
|
automationManager,
|
|
880324
881073
|
hookDispatcher,
|
|
880325
|
-
panelManager,
|
|
881074
|
+
panelManager: panelManager2,
|
|
880326
881075
|
pluginManager
|
|
880327
881076
|
} = services;
|
|
880328
881077
|
const orchestratorRefs = {
|
|
@@ -882055,7 +882804,7 @@ function mergeFeatureFlagConfigValue(config6, key, value) {
|
|
|
882055
882804
|
|
|
882056
882805
|
// src/runtime/onboarding/verify.ts
|
|
882057
882806
|
init_config8();
|
|
882058
|
-
import { existsSync as
|
|
882807
|
+
import { existsSync as existsSync83 } from "fs";
|
|
882059
882808
|
import { join as join98 } from "path";
|
|
882060
882809
|
function getNow(deps) {
|
|
882061
882810
|
return deps.clock?.() ?? Date.now();
|
|
@@ -882137,7 +882886,7 @@ function verifyAuthOperation(_deps, operation) {
|
|
|
882137
882886
|
}
|
|
882138
882887
|
function verifyCreateAgentProfileOperation(deps, operation) {
|
|
882139
882888
|
const resolution2 = resolveAgentRuntimeProfileHome(deps.shellPaths.homeDirectory, operation.name);
|
|
882140
|
-
const ok3 =
|
|
882889
|
+
const ok3 = existsSync83(join98(resolution2.homeDirectory, "profile.json"));
|
|
882141
882890
|
return {
|
|
882142
882891
|
id: `agent-profile:${resolution2.id}`,
|
|
882143
882892
|
status: ok3 ? "pass" : "fail",
|
|
@@ -882235,22 +882984,22 @@ async function verifyOnboardingRequest(deps, request2) {
|
|
|
882235
882984
|
}
|
|
882236
882985
|
|
|
882237
882986
|
// src/runtime/onboarding/apply-file-helpers.ts
|
|
882238
|
-
import { existsSync as
|
|
882239
|
-
import { dirname as
|
|
882987
|
+
import { existsSync as existsSync84, mkdirSync as mkdirSync68, readFileSync as readFileSync90, unlinkSync as unlinkSync11, writeFileSync as writeFileSync59 } from "fs";
|
|
882988
|
+
import { dirname as dirname67 } from "path";
|
|
882240
882989
|
function isPlainObject3(value) {
|
|
882241
882990
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
882242
882991
|
}
|
|
882243
882992
|
function readJsonObject(path7) {
|
|
882244
|
-
if (!
|
|
882993
|
+
if (!existsSync84(path7))
|
|
882245
882994
|
return {};
|
|
882246
|
-
const parsed = JSON.parse(
|
|
882995
|
+
const parsed = JSON.parse(readFileSync90(path7, "utf-8"));
|
|
882247
882996
|
if (!isPlainObject3(parsed))
|
|
882248
882997
|
throw new Error(`Expected an object JSON payload at ${path7}.`);
|
|
882249
882998
|
return parsed;
|
|
882250
882999
|
}
|
|
882251
883000
|
function writeJsonObject(path7, payload) {
|
|
882252
|
-
|
|
882253
|
-
|
|
883001
|
+
mkdirSync68(dirname67(path7), { recursive: true });
|
|
883002
|
+
writeFileSync59(path7, `${JSON.stringify(payload, null, 2)}
|
|
882254
883003
|
`, "utf-8");
|
|
882255
883004
|
}
|
|
882256
883005
|
function setNestedValue(root, key, value) {
|
|
@@ -882271,16 +883020,16 @@ function setNestedValue(root, key, value) {
|
|
|
882271
883020
|
}
|
|
882272
883021
|
function restoreFile(path7, previous, reload) {
|
|
882273
883022
|
if (previous === null) {
|
|
882274
|
-
if (
|
|
883023
|
+
if (existsSync84(path7))
|
|
882275
883024
|
unlinkSync11(path7);
|
|
882276
883025
|
} else {
|
|
882277
|
-
|
|
882278
|
-
|
|
883026
|
+
mkdirSync68(dirname67(path7), { recursive: true });
|
|
883027
|
+
writeFileSync59(path7, previous, "utf-8");
|
|
882279
883028
|
}
|
|
882280
883029
|
reload?.();
|
|
882281
883030
|
}
|
|
882282
883031
|
function snapshotFileRollback(path7, reload) {
|
|
882283
|
-
const previous =
|
|
883032
|
+
const previous = existsSync84(path7) ? readFileSync90(path7, "utf-8") : null;
|
|
882284
883033
|
return () => restoreFile(path7, previous, reload);
|
|
882285
883034
|
}
|
|
882286
883035
|
async function runRollbacks(rollbacks) {
|
|
@@ -882399,7 +883148,7 @@ function validateCreateAgentProfileOperation(deps, operation) {
|
|
|
882399
883148
|
if (name51.length === 0)
|
|
882400
883149
|
throw new Error("Agent profile name is required.");
|
|
882401
883150
|
const resolution2 = resolveAgentRuntimeProfileHome(deps.shellPaths.homeDirectory, name51);
|
|
882402
|
-
if (
|
|
883151
|
+
if (existsSync85(resolution2.homeDirectory)) {
|
|
882403
883152
|
throw new Error(`Agent profile already exists: ${resolution2.id}`);
|
|
882404
883153
|
}
|
|
882405
883154
|
const templateId = operation.templateId?.trim();
|
|
@@ -882411,7 +883160,7 @@ function validateSelectAgentProfileOperation(deps, operation) {
|
|
|
882411
883160
|
if (name51.length === 0)
|
|
882412
883161
|
throw new Error("Agent profile name is required.");
|
|
882413
883162
|
const resolution2 = resolveAgentRuntimeProfileHome(deps.shellPaths.homeDirectory, name51);
|
|
882414
|
-
if (!
|
|
883163
|
+
if (!existsSync85(resolution2.homeDirectory)) {
|
|
882415
883164
|
throw new Error(`Agent profile does not exist: ${resolution2.id}`);
|
|
882416
883165
|
}
|
|
882417
883166
|
}
|
|
@@ -882519,7 +883268,7 @@ async function buildSecretRollbackAction(deps, operation) {
|
|
|
882519
883268
|
throw new Error(`Secret storage locations for ${scope} scope are unavailable.`);
|
|
882520
883269
|
const snapshots = locations.map((location) => ({
|
|
882521
883270
|
path: location.path,
|
|
882522
|
-
previous:
|
|
883271
|
+
previous: existsSync85(location.path) ? readFileSync91(location.path, "utf-8") : null
|
|
882523
883272
|
}));
|
|
882524
883273
|
return () => {
|
|
882525
883274
|
for (const snapshot of snapshots)
|
|
@@ -882553,7 +883302,7 @@ async function buildRollbackAction(deps, operation) {
|
|
|
882553
883302
|
if (operation.kind === "create-agent-profile") {
|
|
882554
883303
|
const resolution2 = resolveAgentRuntimeProfileHome(deps.shellPaths.homeDirectory, operation.name);
|
|
882555
883304
|
return () => {
|
|
882556
|
-
if (
|
|
883305
|
+
if (existsSync85(resolution2.homeDirectory))
|
|
882557
883306
|
rmSync10(resolution2.homeDirectory, { recursive: true, force: true });
|
|
882558
883307
|
};
|
|
882559
883308
|
}
|
|
@@ -882889,8 +883638,8 @@ async function applyOnboardingRequest(deps, request2) {
|
|
|
882889
883638
|
};
|
|
882890
883639
|
}
|
|
882891
883640
|
// src/runtime/onboarding/markers.ts
|
|
882892
|
-
import { existsSync as
|
|
882893
|
-
import { dirname as
|
|
883641
|
+
import { existsSync as existsSync86, mkdirSync as mkdirSync69, readFileSync as readFileSync92, writeFileSync as writeFileSync60 } from "fs";
|
|
883642
|
+
import { dirname as dirname68 } from "path";
|
|
882894
883643
|
var ONBOARDING_CHECK_MARKER_FILE = "onboarding-checked.json";
|
|
882895
883644
|
function resolveMarkerPath(shellPaths3, scope) {
|
|
882896
883645
|
return scope === "project" ? shellPaths3.resolveProjectPath(GOODVIBES_AGENT_SURFACE_ROOT, ONBOARDING_CHECK_MARKER_FILE) : shellPaths3.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, ONBOARDING_CHECK_MARKER_FILE);
|
|
@@ -882933,10 +883682,10 @@ function getOnboardingCheckMarkerPath(shellPaths3, scope = "user") {
|
|
|
882933
883682
|
}
|
|
882934
883683
|
function readOnboardingCheckMarker(shellPaths3, scope = "user") {
|
|
882935
883684
|
const path7 = resolveMarkerPath(shellPaths3, scope);
|
|
882936
|
-
if (!
|
|
883685
|
+
if (!existsSync86(path7))
|
|
882937
883686
|
return buildMissingMarkerState(scope, path7);
|
|
882938
883687
|
try {
|
|
882939
|
-
const parsed = JSON.parse(
|
|
883688
|
+
const parsed = JSON.parse(readFileSync92(path7, "utf-8"));
|
|
882940
883689
|
if (!isCheckMarkerPayload(parsed)) {
|
|
882941
883690
|
return buildParseErrorState(scope, path7, "Invalid onboarding check marker payload.");
|
|
882942
883691
|
}
|
|
@@ -882972,13 +883721,13 @@ function writeOnboardingCheckMarker(shellPaths3, options = {}) {
|
|
|
882972
883721
|
...options.mode ? { mode: options.mode } : {},
|
|
882973
883722
|
...options.workspaceRoot ? { workspaceRoot: options.workspaceRoot } : {}
|
|
882974
883723
|
};
|
|
882975
|
-
|
|
882976
|
-
|
|
883724
|
+
mkdirSync69(dirname68(path7), { recursive: true });
|
|
883725
|
+
writeFileSync60(path7, `${JSON.stringify(payload, null, 2)}
|
|
882977
883726
|
`, "utf-8");
|
|
882978
883727
|
return readOnboardingCheckMarker(shellPaths3, scope);
|
|
882979
883728
|
}
|
|
882980
883729
|
// src/input/handler-content-actions.ts
|
|
882981
|
-
import { existsSync as
|
|
883730
|
+
import { existsSync as existsSync87, lstatSync as lstatSync3, readFileSync as readFileSync93, readdirSync as readdirSync22 } from "fs";
|
|
882982
883731
|
import { basename as basename6, relative as relative15 } from "path";
|
|
882983
883732
|
var MARKER_REGEX = /\[(TEXT|IMAGE): [^\]]+\]/g;
|
|
882984
883733
|
var IMAGE_PREFIXES = [
|
|
@@ -883038,7 +883787,7 @@ function readContextFileBlock(reference, projectRoot) {
|
|
|
883038
883787
|
logger.debug("expandPrompt: context reference rejected", { reference, error: summarizeError(error53) });
|
|
883039
883788
|
return null;
|
|
883040
883789
|
}
|
|
883041
|
-
if (!
|
|
883790
|
+
if (!existsSync87(resolvedPath3))
|
|
883042
883791
|
return null;
|
|
883043
883792
|
const stat6 = lstatSync3(resolvedPath3);
|
|
883044
883793
|
const label = escapeContextAttribute(relative15(projectRoot, resolvedPath3) || basename6(resolvedPath3));
|
|
@@ -883057,14 +883806,14 @@ function readContextFileBlock(reference, projectRoot) {
|
|
|
883057
883806
|
if (stat6.size > MAX_CONTEXT_FILE_BYTES) {
|
|
883058
883807
|
return [
|
|
883059
883808
|
`<context-file path="${label}" truncated="true" bytes="${stat6.size}">`,
|
|
883060
|
-
|
|
883809
|
+
readFileSync93(resolvedPath3, "utf-8").slice(0, MAX_CONTEXT_FILE_BYTES),
|
|
883061
883810
|
"</context-file>"
|
|
883062
883811
|
].join(`
|
|
883063
883812
|
`);
|
|
883064
883813
|
}
|
|
883065
883814
|
return [
|
|
883066
883815
|
`<context-file path="${label}" bytes="${stat6.size}">`,
|
|
883067
|
-
|
|
883816
|
+
readFileSync93(resolvedPath3, "utf-8"),
|
|
883068
883817
|
"</context-file>"
|
|
883069
883818
|
].join(`
|
|
883070
883819
|
`);
|
|
@@ -883121,8 +883870,8 @@ function registerPaste(state4, content, projectRoot) {
|
|
|
883121
883870
|
if (IMAGE_EXTENSIONS2.some((ext) => trimmed2.toLowerCase().endsWith(ext))) {
|
|
883122
883871
|
try {
|
|
883123
883872
|
const resolvedPath3 = resolveAndValidatePath(trimmed2, projectRoot);
|
|
883124
|
-
if (
|
|
883125
|
-
const data =
|
|
883873
|
+
if (existsSync87(resolvedPath3)) {
|
|
883874
|
+
const data = readFileSync93(resolvedPath3);
|
|
883126
883875
|
const base644 = data.toString("base64");
|
|
883127
883876
|
const ext = trimmed2.slice(trimmed2.lastIndexOf("."));
|
|
883128
883877
|
const mediaType = mediaTypeFromExt(ext);
|
|
@@ -883172,7 +883921,7 @@ function expandPrompt(pasteRegistry, imageRegistry, text, projectRoot) {
|
|
|
883172
883921
|
const filePath = injectMatch[1];
|
|
883173
883922
|
try {
|
|
883174
883923
|
const resolvedPath3 = resolveAndValidatePath(filePath, projectRoot);
|
|
883175
|
-
const content =
|
|
883924
|
+
const content = readFileSync93(resolvedPath3, "utf-8");
|
|
883176
883925
|
expanded = expanded.slice(0, injectMatch.index) + content + expanded.slice(injectMatch.index + injectMatch[0].length);
|
|
883177
883926
|
injectRegex.lastIndex = injectMatch.index + content.length;
|
|
883178
883927
|
} catch (err2) {
|
|
@@ -891829,23 +892578,23 @@ function handlePromptKeyToken(state4, token) {
|
|
|
891829
892578
|
function clampRatio(value) {
|
|
891830
892579
|
return Math.max(0.2, Math.min(0.8, value));
|
|
891831
892580
|
}
|
|
891832
|
-
function getActivePanelInPane(
|
|
891833
|
-
const target = pane === "top" ?
|
|
892581
|
+
function getActivePanelInPane(panelManager2, pane) {
|
|
892582
|
+
const target = pane === "top" ? panelManager2.getTopPane() : panelManager2.getBottomPane();
|
|
891834
892583
|
return target.panels[target.activeIndex] ?? null;
|
|
891835
892584
|
}
|
|
891836
|
-
function getPanelUnderMouse(
|
|
891837
|
-
if (layout === null || !
|
|
892585
|
+
function getPanelUnderMouse(panelManager2, layout, row, col) {
|
|
892586
|
+
if (layout === null || !panelManager2.isVisible() || panelManager2.getAllOpen().length === 0 || col < layout.x || col >= layout.x + layout.width || row < layout.y || row >= layout.y + layout.height) {
|
|
891838
892587
|
return null;
|
|
891839
892588
|
}
|
|
891840
892589
|
const panelRow = row - layout.y;
|
|
891841
892590
|
if (!layout.hasBottomPane) {
|
|
891842
|
-
return getActivePanelInPane(
|
|
892591
|
+
return getActivePanelInPane(panelManager2, "top");
|
|
891843
892592
|
}
|
|
891844
892593
|
const panelAreaRows = Math.max(0, layout.height - 1);
|
|
891845
892594
|
const contentRows = Math.max(0, panelAreaRows - 3);
|
|
891846
892595
|
const topContentRows = contentRows <= 1 ? contentRows : Math.max(1, Math.floor(contentRows * clampRatio(layout.verticalSplitRatio)));
|
|
891847
892596
|
const topLastRow = 2 + topContentRows;
|
|
891848
|
-
return panelRow <= topLastRow ? getActivePanelInPane(
|
|
892597
|
+
return panelRow <= topLastRow ? getActivePanelInPane(panelManager2, "top") : getActivePanelInPane(panelManager2, "bottom");
|
|
891849
892598
|
}
|
|
891850
892599
|
function scrollPanelUnderMouse(state4, token, deltaRows) {
|
|
891851
892600
|
const panel = getPanelUnderMouse(state4.panelManager, state4.panelMouseLayout, token.row, token.col);
|
|
@@ -892445,7 +893194,7 @@ function handleProfilePickerToken(state4, token) {
|
|
|
892445
893194
|
}
|
|
892446
893195
|
|
|
892447
893196
|
// src/input/handler-picker-routes.ts
|
|
892448
|
-
import { readFileSync as
|
|
893197
|
+
import { readFileSync as readFileSync94 } from "fs";
|
|
892449
893198
|
|
|
892450
893199
|
// src/renderer/model-picker-overlay.ts
|
|
892451
893200
|
var MODEL_PICKER_CHROME_LINES = 7;
|
|
@@ -892737,7 +893486,7 @@ function handleFilePickerToken(state4, token) {
|
|
|
892737
893486
|
throw new Error("working directory is unavailable");
|
|
892738
893487
|
}
|
|
892739
893488
|
const resolvedPath3 = resolveAndValidatePath(selected, projectRoot);
|
|
892740
|
-
const data =
|
|
893489
|
+
const data = readFileSync94(resolvedPath3);
|
|
892741
893490
|
const base644 = data.toString("base64");
|
|
892742
893491
|
const mediaType = state4.mediaTypeFromExt(ext);
|
|
892743
893492
|
const filename = selected.split("/").pop() ?? selected;
|
|
@@ -893293,7 +894042,7 @@ function handleGlobalShortcutToken(state4, token, viewportHeight) {
|
|
|
893293
894042
|
}
|
|
893294
894043
|
|
|
893295
894044
|
// src/input/panel-integration-actions.ts
|
|
893296
|
-
function handlePanelIntegrationAction(
|
|
894045
|
+
function handlePanelIntegrationAction(panelManager2, activePanel, key, commandContext) {
|
|
893297
894046
|
if (!activePanel)
|
|
893298
894047
|
return false;
|
|
893299
894048
|
if ((key === "enter" || key === "return") && activePanel instanceof ApprovalPanel) {
|
|
@@ -898078,16 +898827,16 @@ function renderPanel(panel, width, height) {
|
|
|
898078
898827
|
panelRenderCache.set(panel, { lines, width, height });
|
|
898079
898828
|
return lines;
|
|
898080
898829
|
}
|
|
898081
|
-
function buildPanelCompositeData(
|
|
898082
|
-
if (!
|
|
898830
|
+
function buildPanelCompositeData(panelManager2, input, panelWidth, panelHeight) {
|
|
898831
|
+
if (!panelManager2.isVisible() || panelManager2.getAllOpen().length === 0 || panelWidth <= 0) {
|
|
898083
898832
|
return {};
|
|
898084
898833
|
}
|
|
898085
|
-
const topPane =
|
|
898086
|
-
const bottomPane =
|
|
898087
|
-
const focusedPane =
|
|
898088
|
-
const workspaceTabs =
|
|
898089
|
-
const verticalSplitRatio =
|
|
898090
|
-
const hasBottom =
|
|
898834
|
+
const topPane = panelManager2.getTopPane();
|
|
898835
|
+
const bottomPane = panelManager2.getBottomPane();
|
|
898836
|
+
const focusedPane = panelManager2.getFocusedPane();
|
|
898837
|
+
const workspaceTabs = panelManager2.getWorkspaceTabs();
|
|
898838
|
+
const verticalSplitRatio = panelManager2.getVerticalSplitRatio();
|
|
898839
|
+
const hasBottom = panelManager2.isBottomPaneVisible() && bottomPane.panels.length > 0;
|
|
898091
898840
|
const workspaceBar = renderPanelWorkspaceBar(workspaceTabs, panelWidth, input.panelFocused);
|
|
898092
898841
|
let topContent;
|
|
898093
898842
|
let topTabBar;
|
|
@@ -898230,7 +898979,7 @@ function wireShellUiOpeners(options) {
|
|
|
898230
898979
|
const {
|
|
898231
898980
|
commandContext,
|
|
898232
898981
|
input,
|
|
898233
|
-
panelManager,
|
|
898982
|
+
panelManager: panelManager2,
|
|
898234
898983
|
conversation,
|
|
898235
898984
|
configManager,
|
|
898236
898985
|
providerRegistry,
|
|
@@ -898421,7 +899170,7 @@ function wireShellUiOpeners(options) {
|
|
|
898421
899170
|
render();
|
|
898422
899171
|
};
|
|
898423
899172
|
commandContext.openPanelPicker = () => {
|
|
898424
|
-
|
|
899173
|
+
panelManager2.hide();
|
|
898425
899174
|
input.panelFocused = false;
|
|
898426
899175
|
conversation.setSplashSuppressed(false);
|
|
898427
899176
|
conversation.log("Panel picker is handled through Agent Workspace. Use /agent for current operator controls.", { fg: "214" });
|
|
@@ -898440,7 +899189,7 @@ function wireShellUiOpeners(options) {
|
|
|
898440
899189
|
render();
|
|
898441
899190
|
};
|
|
898442
899191
|
commandContext.showPanel = (panelId, pane) => {
|
|
898443
|
-
|
|
899192
|
+
panelManager2.hide();
|
|
898444
899193
|
input.panelFocused = false;
|
|
898445
899194
|
conversation.setSplashSuppressed(false);
|
|
898446
899195
|
conversation.log(`Panel route "${panelId}" is handled through Agent Workspace. Opening the matching operator area.`, { fg: "214" });
|
|
@@ -898451,7 +899200,7 @@ function wireShellUiOpeners(options) {
|
|
|
898451
899200
|
}
|
|
898452
899201
|
|
|
898453
899202
|
// src/cli/entrypoint.ts
|
|
898454
|
-
import { existsSync as
|
|
899203
|
+
import { existsSync as existsSync89 } from "fs";
|
|
898455
899204
|
import { join as join101 } from "path";
|
|
898456
899205
|
// src/cli/status.ts
|
|
898457
899206
|
function yesNo3(value) {
|
|
@@ -898697,12 +899446,12 @@ function renderOnboardingCliStatus(options) {
|
|
|
898697
899446
|
`);
|
|
898698
899447
|
}
|
|
898699
899448
|
// src/cli/external-runtime.ts
|
|
898700
|
-
import { existsSync as
|
|
899449
|
+
import { existsSync as existsSync88, readFileSync as readFileSync95 } from "fs";
|
|
898701
899450
|
import { join as join100 } from "path";
|
|
898702
899451
|
function isRecord43(value) {
|
|
898703
899452
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
898704
899453
|
}
|
|
898705
|
-
function
|
|
899454
|
+
function readString56(record2, key) {
|
|
898706
899455
|
const value = record2?.[key];
|
|
898707
899456
|
return typeof value === "string" ? value : null;
|
|
898708
899457
|
}
|
|
@@ -898713,10 +899462,10 @@ function resolveBaseUrl2(configManager) {
|
|
|
898713
899462
|
}
|
|
898714
899463
|
function readOperatorToken2(homeDirectory) {
|
|
898715
899464
|
const path7 = join100(homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
|
|
898716
|
-
if (!
|
|
899465
|
+
if (!existsSync88(path7))
|
|
898717
899466
|
return { token: null, path: path7 };
|
|
898718
899467
|
try {
|
|
898719
|
-
const parsed = JSON.parse(
|
|
899468
|
+
const parsed = JSON.parse(readFileSync95(path7, "utf-8"));
|
|
898720
899469
|
const token = isRecord43(parsed) && typeof parsed.token === "string" ? parsed.token : null;
|
|
898721
899470
|
return { token, path: path7 };
|
|
898722
899471
|
} catch {
|
|
@@ -898753,7 +899502,7 @@ async function inspectCliExternalRuntime(options) {
|
|
|
898753
899502
|
try {
|
|
898754
899503
|
const status = await fetchJson2(`${baseUrl}/status`, token.token, timeoutMs);
|
|
898755
899504
|
const statusRecord = isRecord43(status.body) ? status.body : {};
|
|
898756
|
-
const version6 =
|
|
899505
|
+
const version6 = readString56(statusRecord, "version") ?? "unknown";
|
|
898757
899506
|
const compatible = status.ok && version6 === SDK_VERSION;
|
|
898758
899507
|
if (!status.ok) {
|
|
898759
899508
|
return {
|
|
@@ -899208,11 +899957,11 @@ async function prepareShellCliRuntime(argv, roots, binary2 = "goodvibes-agent")
|
|
|
899208
899957
|
onboardingMarkers,
|
|
899209
899958
|
auth: {
|
|
899210
899959
|
userStorePath,
|
|
899211
|
-
userStorePresent:
|
|
899960
|
+
userStorePresent: existsSync89(userStorePath),
|
|
899212
899961
|
bootstrapCredentialPath,
|
|
899213
|
-
bootstrapCredentialPresent:
|
|
899962
|
+
bootstrapCredentialPresent: existsSync89(bootstrapCredentialPath),
|
|
899214
899963
|
operatorTokenPath,
|
|
899215
|
-
operatorTokenPresent:
|
|
899964
|
+
operatorTokenPresent: existsSync89(operatorTokenPath)
|
|
899216
899965
|
},
|
|
899217
899966
|
service,
|
|
899218
899967
|
externalRuntime,
|
|
@@ -900390,7 +901139,7 @@ async function main() {
|
|
|
900390
901139
|
modeManager.setHITLMode(hitlMode);
|
|
900391
901140
|
}
|
|
900392
901141
|
}
|
|
900393
|
-
const
|
|
901142
|
+
const panelManager2 = ctx.services.panelManager;
|
|
900394
901143
|
const buildSessionContinuityHints = () => {
|
|
900395
901144
|
const sessionSnapshot = uiServices.readModels.session.getSnapshot();
|
|
900396
901145
|
const tasksSnapshot = uiServices.readModels.tasks.getSnapshot();
|
|
@@ -900401,7 +901150,7 @@ async function main() {
|
|
|
900401
901150
|
blockedTasks: tasksSnapshot.tasks.filter((task) => task.status === "blocked").length,
|
|
900402
901151
|
remoteContracts: remoteSnapshot.contracts.length,
|
|
900403
901152
|
remoteRunners: remoteSnapshot.contracts.slice(0, 4).map((contract) => contract.runnerId),
|
|
900404
|
-
openPanels:
|
|
901153
|
+
openPanels: panelManager2.getAllOpen().map((panel) => panel.id)
|
|
900405
901154
|
};
|
|
900406
901155
|
};
|
|
900407
901156
|
const buildCurrentSessionSnapshot = () => {
|
|
@@ -900537,8 +901286,8 @@ async function main() {
|
|
|
900537
901286
|
render();
|
|
900538
901287
|
},
|
|
900539
901288
|
openPanel: () => {
|
|
900540
|
-
|
|
900541
|
-
|
|
901289
|
+
panelManager2.open("project-planning");
|
|
901290
|
+
panelManager2.show();
|
|
900542
901291
|
render();
|
|
900543
901292
|
}
|
|
900544
901293
|
});
|
|
@@ -900682,7 +901431,7 @@ async function main() {
|
|
|
900682
901431
|
shell: {
|
|
900683
901432
|
bookmarkManager: ctx.services.bookmarkManager,
|
|
900684
901433
|
keybindingsManager: ctx.services.keybindingsManager,
|
|
900685
|
-
panelManager,
|
|
901434
|
+
panelManager: panelManager2,
|
|
900686
901435
|
processManager,
|
|
900687
901436
|
profileManager: ctx.services.profileManager
|
|
900688
901437
|
},
|
|
@@ -900775,7 +901524,7 @@ async function main() {
|
|
|
900775
901524
|
const onboardingOwnsScreen = input.onboardingWizard.active;
|
|
900776
901525
|
const shellHeaderLines = onboardingOwnsScreen ? [] : headerLines;
|
|
900777
901526
|
const shellFooterLines = onboardingOwnsScreen ? [] : footerLines;
|
|
900778
|
-
const panelWidth = !onboardingOwnsScreen &&
|
|
901527
|
+
const panelWidth = !onboardingOwnsScreen && panelManager2.isVisible() && panelManager2.getAllOpen().length > 0 ? panelManager2.getRightWidth(width) : 0;
|
|
900779
901528
|
const shellLayout = createShellLayout({
|
|
900780
901529
|
width,
|
|
900781
901530
|
height,
|
|
@@ -900788,13 +901537,13 @@ async function main() {
|
|
|
900788
901537
|
y: shellLayout.panel.y,
|
|
900789
901538
|
width: shellLayout.panel.width,
|
|
900790
901539
|
height: shellLayout.panel.height,
|
|
900791
|
-
hasBottomPane:
|
|
900792
|
-
verticalSplitRatio:
|
|
901540
|
+
hasBottomPane: panelManager2.isBottomPaneVisible() && panelManager2.getBottomPane().panels.length > 0,
|
|
901541
|
+
verticalSplitRatio: panelManager2.getVerticalSplitRatio()
|
|
900793
901542
|
} : null);
|
|
900794
901543
|
const vHeight = shellLayout.body.height;
|
|
900795
901544
|
const conversationWidth = shellLayout.conversation.width;
|
|
900796
901545
|
activeConversationWidth = conversationWidth;
|
|
900797
|
-
const hasPanelWorkspace = !onboardingOwnsScreen &&
|
|
901546
|
+
const hasPanelWorkspace = !onboardingOwnsScreen && panelManager2.isVisible() && panelManager2.getAllOpen().length > 0;
|
|
900798
901547
|
conversation.setSplashSuppressed(hasPanelWorkspace);
|
|
900799
901548
|
conversation.getDisplayBlocks();
|
|
900800
901549
|
let overlayRows = 0;
|
|
@@ -900838,7 +901587,7 @@ async function main() {
|
|
|
900838
901587
|
viewportHeight: vHeight,
|
|
900839
901588
|
contextWindow: currentModel.contextWindow
|
|
900840
901589
|
});
|
|
900841
|
-
const panelComposite = onboardingOwnsScreen ? { panelData: undefined, panelWidth: 0 } : buildPanelCompositeData(
|
|
901590
|
+
const panelComposite = onboardingOwnsScreen ? { panelData: undefined, panelWidth: 0 } : buildPanelCompositeData(panelManager2, input, shellLayout.panel?.width ?? 0, shellLayout.panel?.height ?? vHeight);
|
|
900842
901591
|
compositor.composite({
|
|
900843
901592
|
width,
|
|
900844
901593
|
height,
|
|
@@ -900869,7 +901618,7 @@ async function main() {
|
|
|
900869
901618
|
wireShellUiOpeners({
|
|
900870
901619
|
commandContext,
|
|
900871
901620
|
input,
|
|
900872
|
-
panelManager,
|
|
901621
|
+
panelManager: panelManager2,
|
|
900873
901622
|
conversation,
|
|
900874
901623
|
configManager,
|
|
900875
901624
|
providerRegistry,
|