@pellux/goodvibes-agent 1.0.19 → 1.0.21

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.
@@ -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: () => uniq3,
731451
- stabilizeKnowledgeText: () => stableText2,
731452
- runKnowledgeSemanticSelfImprovement: () => runKnowledgeSemanticSelfImprovement2,
731508
+ uniqKnowledgeValues: () => uniq2,
731509
+ stabilizeKnowledgeText: () => stableText,
731510
+ runKnowledgeSemanticSelfImprovement: () => runKnowledgeSemanticSelfImprovement,
731453
731511
  resolveProjectPlanningSpace: () => resolveProjectPlanningSpace,
731454
- resolveKnowledgeDbPathFromControlPlaneDir: () => resolveKnowledgeDbPathFromControlPlaneDir2,
731512
+ resolveKnowledgeDbPathFromControlPlaneDir: () => resolveKnowledgeDbPathFromControlPlaneDir,
731455
731513
  renderPacket: () => renderPacket,
731456
731514
  renderKnowledgeSchemaSql: () => renderKnowledgeSchemaSql,
731457
731515
  renderKnowledgeMap: () => renderKnowledgeMap,
731458
731516
  readKnowledgeSearchText: () => readKnowledgeSearchText,
731459
- readBrowserKnowledgeProfile: () => readBrowserKnowledgeProfile2,
731517
+ readBrowserKnowledgeProfile: () => readBrowserKnowledgeProfile,
731460
731518
  projectPlanningSourceId: () => projectPlanningSourceId,
731461
731519
  projectPlanningProjectIdFromPath: () => projectPlanningProjectIdFromPath,
731462
731520
  projectPlanningCanonicalUri: () => projectPlanningCanonicalUri,
731463
731521
  projectKnowledgeSpaceId: () => projectKnowledgeSpaceId,
731464
- parseKnowledgeJsonValue: () => parseJsonValue2,
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: () => loadKnowledgeStoreSnapshot2,
731530
+ loadKnowledgeStoreSnapshot: () => loadKnowledgeStoreSnapshot,
731473
731531
  listGeneratedKnowledgePages: () => listGeneratedKnowledgePages,
731474
- listBrowserKinds: () => listBrowserKinds2,
731532
+ listBrowserKinds: () => listBrowserKinds,
731475
731533
  knowledgeSpaceMetadata: () => knowledgeSpaceMetadata,
731476
731534
  knowledgePageSourceWeight: () => knowledgePageSourceWeight,
731477
- knowledgeNowMs: () => nowMs2,
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: () => evaluateProjectPlanningReadiness2,
731498
- discoverBrowserKnowledgeProfiles: () => discoverBrowserKnowledgeProfiles2,
731555
+ evaluateProjectPlanningReadiness: () => evaluateProjectPlanningReadiness,
731556
+ discoverBrowserKnowledgeProfiles: () => discoverBrowserKnowledgeProfiles,
731499
731557
  createWebKnowledgeGapRepairer: () => createWebKnowledgeGapRepairer,
731500
731558
  createProviderBackedKnowledgeSemanticLlm: () => createProviderBackedKnowledgeSemanticLlm,
731501
731559
  createMemoryApi: () => createMemoryApi,
731502
- createKnowledgeSchema: () => createSchema3,
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, nowMs3 = Date.now()) {
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 ? nowMs3 - Math.min(...queuedRuns.map((r5) => r5.queuedAt)) : null;
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.19";
816569
+ var _version = "1.0.21";
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"));
@@ -839370,7 +839428,7 @@ var WORK_PLAN_STATUSES = [
839370
839428
  "failed",
839371
839429
  "cancelled"
839372
839430
  ];
839373
- function nowMs3() {
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 = nowMs3();
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 = nowMs3();
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 = nowMs3();
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: nowMs3()
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 = nowMs3();
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 = nowMs3();
839672
+ const time4 = nowMs2();
839615
839673
  return {
839616
839674
  id: createPlanId(this.options.projectId, this.options.projectRoot),
839617
839675
  projectId: this.options.projectId,
@@ -880225,9 +880283,133 @@ function describeBinding(manager5, action2, combos, lookup) {
880225
880283
  labels: combos.map((combo) => manager5.formatCombo(combo)),
880226
880284
  defaultBindings: defaults3.map((combo) => describeCombo(manager5, combo)),
880227
880285
  customized,
880228
- source: customized ? "custom" : "default"
880286
+ source: customized ? "custom" : "default",
880287
+ modelOperation: keybindingOperationRoute(action2)
880229
880288
  };
880230
880289
  }
880290
+ function keybindingOperationRoute(action2) {
880291
+ switch (action2) {
880292
+ case "clear-cancel":
880293
+ return {
880294
+ supported: true,
880295
+ effect: "shell-action",
880296
+ preferredMode: "run_keybinding",
880297
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880298
+ note: "Routes the cancel-generation side of this shortcut through commandContext.cancelGeneration. Prompt clearing and double-press exit remain direct user interaction."
880299
+ };
880300
+ case "screen-clear":
880301
+ return {
880302
+ supported: true,
880303
+ effect: "shell-action",
880304
+ preferredMode: "run_keybinding",
880305
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880306
+ note: "Routes through commandContext.clearScreen."
880307
+ };
880308
+ case "panel-picker":
880309
+ return {
880310
+ supported: true,
880311
+ effect: "visible-ui-navigation",
880312
+ preferredMode: "run_keybinding",
880313
+ surfaceId: "agent-workspace",
880314
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880315
+ note: "Opens the same Agent workspace home route as the panel-picker shortcut."
880316
+ };
880317
+ case "panel-close":
880318
+ return {
880319
+ supported: true,
880320
+ effect: "visible-ui-navigation",
880321
+ preferredMode: "run_keybinding",
880322
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880323
+ note: "Closes the active legacy panel if present, then focuses the prompt when the shell bridge exposes focusPrompt."
880324
+ };
880325
+ case "panel-close-all":
880326
+ return {
880327
+ supported: true,
880328
+ effect: "visible-ui-navigation",
880329
+ preferredMode: "run_keybinding",
880330
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880331
+ note: "Closes all legacy panels if present, hides the panel manager, then focuses the prompt when the shell bridge exposes focusPrompt."
880332
+ };
880333
+ case "history-search":
880334
+ return {
880335
+ supported: true,
880336
+ effect: "visible-ui-navigation",
880337
+ preferredMode: "run_keybinding",
880338
+ surfaceId: "prompt-history-search",
880339
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880340
+ note: "Opens the visible prompt-history search overlay; optional search text may be supplied with value."
880341
+ };
880342
+ case "search":
880343
+ return {
880344
+ supported: true,
880345
+ effect: "visible-ui-navigation",
880346
+ preferredMode: "run_keybinding",
880347
+ surfaceId: "conversation-search",
880348
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880349
+ note: "Opens the visible conversation search overlay; optional search text may be supplied with value."
880350
+ };
880351
+ case "paste":
880352
+ return {
880353
+ supported: true,
880354
+ effect: "shell-action",
880355
+ preferredMode: "run_keybinding",
880356
+ command: "/paste",
880357
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880358
+ note: "Routes through commandContext.pasteFromClipboard and reports whether text, image, or nothing was pasted."
880359
+ };
880360
+ case "block-copy":
880361
+ case "bookmark":
880362
+ case "block-save":
880363
+ return {
880364
+ supported: true,
880365
+ effect: "visible-ui-interaction",
880366
+ preferredMode: "run_keybinding",
880367
+ surfaceId: "block-actions",
880368
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880369
+ note: "Opens the visible nearest-block actions surface. The exact block action remains an interactive visible-shell selection because it depends on cursor/scroll position."
880370
+ };
880371
+ case "panel-tab-next":
880372
+ case "panel-tab-prev":
880373
+ return {
880374
+ supported: false,
880375
+ effect: "visible-ui-navigation",
880376
+ preferredMode: "open_ui_surface",
880377
+ surfaceId: "agent-workspace",
880378
+ confirmation: "Use open_ui_surface with confirm:true and an explicit categoryId/target instead of cycling hidden UI state.",
880379
+ note: "Category cycling depends on the live workspace focus position. The model should open the intended Agent workspace category directly."
880380
+ };
880381
+ case "copy-selection":
880382
+ return {
880383
+ supported: false,
880384
+ effect: "clipboard-selection",
880385
+ preferredMode: "direct-user-interaction",
880386
+ confirmation: "No model operation is exposed.",
880387
+ note: "Terminal text selection is outside the Agent command context. Use transcript/session export or a content-specific model route when a concrete artifact is needed."
880388
+ };
880389
+ case "delete-word":
880390
+ case "line-start":
880391
+ case "next-error-line-end":
880392
+ case "kill-line":
880393
+ case "clear-prompt":
880394
+ case "undo":
880395
+ case "redo":
880396
+ return {
880397
+ supported: false,
880398
+ effect: "prompt-editor-state",
880399
+ preferredMode: "direct-user-interaction",
880400
+ confirmation: "No model operation is exposed.",
880401
+ note: "This shortcut mutates live prompt-buffer cursor/edit state that is not part of the model tool contract."
880402
+ };
880403
+ case "replay-panel":
880404
+ return {
880405
+ supported: false,
880406
+ effect: "reserved",
880407
+ preferredMode: "direct-user-interaction",
880408
+ confirmation: "No model operation is exposed.",
880409
+ note: "This shortcut is reserved and has no current Agent operation route."
880410
+ };
880411
+ }
880412
+ }
880231
880413
  function readOverrideFile(configPath) {
880232
880414
  if (!existsSync82(configPath))
880233
880415
  return {};
@@ -880259,7 +880441,7 @@ ${shortcut.description}`.toLowerCase().includes(query2)).slice(0, readLimit7(arg
880259
880441
  configurableKeybindings: keybindings.keybindings,
880260
880442
  returned: fixed.length + Number(keybindings.returned ?? 0),
880261
880443
  total: totalHarnessShortcuts(context),
880262
- policy: "Fixed shortcuts are runtime/editor controls. Configurable keybindings can be changed with set_keybinding/reset_keybinding."
880444
+ policy: "Fixed shortcuts are runtime/editor controls. Configurable keybindings can be inspected, supported shell-safe actions can be run with run_keybinding, and bindings can be changed with set_keybinding/reset_keybinding."
880263
880445
  };
880264
880446
  }
880265
880447
  function listHarnessKeybindings(context, args2) {
@@ -880271,7 +880453,7 @@ function listHarnessKeybindings(context, args2) {
880271
880453
  keybindings: entries,
880272
880454
  returned: entries.length,
880273
880455
  total: manager5.getAll().length,
880274
- 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."
880456
+ policy: "Reads the live resolved keybindings, including modelOperation route metadata. run_keybinding executes only supported shell-safe actions. set_keybinding/reset_keybinding write the same keybindings.json file the user can edit and reload the runtime manager."
880275
880457
  };
880276
880458
  }
880277
880459
  function describeHarnessKeybinding(context, args2) {
@@ -880287,6 +880469,143 @@ function describeHarnessKeybinding(context, args2) {
880287
880469
  ...describeBinding(manager5, entry.action, entry.combos, resolved.lookup)
880288
880470
  } : null;
880289
880471
  }
880472
+ function runUnavailable(action2, route, reason) {
880473
+ return {
880474
+ status: "keybinding_route_unavailable",
880475
+ action: action2,
880476
+ modelOperation: route,
880477
+ ...reason ? { reason } : {}
880478
+ };
880479
+ }
880480
+ function runHarnessKeybinding(context, args2) {
880481
+ const manager5 = requireKeybindingsManager2(context);
880482
+ const resolved = resolveHarnessKeybinding(context, args2);
880483
+ if (resolved?.status === "ambiguous")
880484
+ return { status: "ambiguous", input: resolved.input, candidates: resolved.candidates };
880485
+ if (!resolved)
880486
+ throw new Error("run_keybinding requires a valid keybinding action id, target, key, or query.");
880487
+ const entry = manager5.getAll().find((candidate) => candidate.action === resolved.action);
880488
+ if (!entry)
880489
+ throw new Error(`No live keybinding entry found for ${resolved.action}.`);
880490
+ const route = keybindingOperationRoute(resolved.action);
880491
+ const descriptor = {
880492
+ configPath: manager5.getConfigPath(),
880493
+ ...describeBinding(manager5, entry.action, entry.combos, resolved.lookup)
880494
+ };
880495
+ if (!route.supported) {
880496
+ return {
880497
+ status: "unsupported_keybinding_action",
880498
+ action: resolved.action,
880499
+ keybinding: descriptor,
880500
+ modelOperation: route
880501
+ };
880502
+ }
880503
+ switch (resolved.action) {
880504
+ case "clear-cancel":
880505
+ if (!context.cancelGeneration)
880506
+ return runUnavailable(resolved.action, route, "commandContext.cancelGeneration is unavailable.");
880507
+ context.cancelGeneration();
880508
+ return { status: "executed", action: resolved.action, effect: "cancel-generation", keybinding: descriptor };
880509
+ case "screen-clear":
880510
+ if (!context.clearScreen)
880511
+ return runUnavailable(resolved.action, route, "commandContext.clearScreen is unavailable.");
880512
+ context.clearScreen();
880513
+ return { status: "executed", action: resolved.action, effect: "screen-clear", keybinding: descriptor };
880514
+ case "panel-picker":
880515
+ if (context.openPanelPicker) {
880516
+ context.openPanelPicker();
880517
+ return { status: "executed", action: resolved.action, effect: "agent-workspace-opened", route: "openPanelPicker", keybinding: descriptor };
880518
+ }
880519
+ if (context.openAgentWorkspace) {
880520
+ context.openAgentWorkspace("home");
880521
+ return { status: "executed", action: resolved.action, effect: "agent-workspace-opened", route: "openAgentWorkspace", categoryId: "home", keybinding: descriptor };
880522
+ }
880523
+ return runUnavailable(resolved.action, route, "No panel picker or Agent workspace opener is available.");
880524
+ case "panel-close": {
880525
+ const active = context.workspace.panelManager?.getActivePanel() ?? null;
880526
+ if (active)
880527
+ context.workspace.panelManager?.close(active.id);
880528
+ if (!active && !context.focusPrompt)
880529
+ return runUnavailable(resolved.action, route, "No active legacy panel or prompt focus route is available.");
880530
+ if (context.focusPrompt)
880531
+ context.focusPrompt();
880532
+ context.renderRequest();
880533
+ return {
880534
+ status: "executed",
880535
+ action: resolved.action,
880536
+ effect: active ? "active-panel-closed" : "prompt-focused",
880537
+ ...active ? { panelId: active.id } : {},
880538
+ keybinding: descriptor
880539
+ };
880540
+ }
880541
+ case "panel-close-all": {
880542
+ const managerPanel = context.workspace.panelManager;
880543
+ const openPanels = managerPanel?.getAllOpen() ?? [];
880544
+ for (const panel of openPanels)
880545
+ managerPanel?.close(panel.id);
880546
+ managerPanel?.hide();
880547
+ if (openPanels.length === 0 && !context.focusPrompt)
880548
+ return runUnavailable(resolved.action, route, "No open legacy panels or prompt focus route is available.");
880549
+ if (context.focusPrompt)
880550
+ context.focusPrompt();
880551
+ context.renderRequest();
880552
+ return {
880553
+ status: "executed",
880554
+ action: resolved.action,
880555
+ effect: "all-panels-closed",
880556
+ closedPanels: openPanels.map((panel) => panel.id),
880557
+ keybinding: descriptor
880558
+ };
880559
+ }
880560
+ case "history-search": {
880561
+ if (!context.openPromptHistorySearch)
880562
+ return runUnavailable(resolved.action, route, "commandContext.openPromptHistorySearch is unavailable.");
880563
+ const query2 = readString52(args2.value);
880564
+ context.openPromptHistorySearch(query2 || undefined);
880565
+ return { status: "executed", action: resolved.action, effect: "prompt-history-search-opened", query: query2, keybinding: descriptor };
880566
+ }
880567
+ case "search": {
880568
+ if (!context.openConversationSearch)
880569
+ return runUnavailable(resolved.action, route, "commandContext.openConversationSearch is unavailable.");
880570
+ const query2 = readString52(args2.value);
880571
+ context.openConversationSearch(query2 || undefined);
880572
+ return { status: "executed", action: resolved.action, effect: "conversation-search-opened", query: query2, keybinding: descriptor };
880573
+ }
880574
+ case "paste": {
880575
+ if (!context.pasteFromClipboard)
880576
+ return runUnavailable(resolved.action, route, "commandContext.pasteFromClipboard is unavailable.");
880577
+ const pasted = context.pasteFromClipboard();
880578
+ return { status: "executed", action: resolved.action, effect: "paste-from-clipboard", pasted, keybinding: descriptor };
880579
+ }
880580
+ case "block-copy":
880581
+ case "bookmark":
880582
+ case "block-save": {
880583
+ if (!context.openBlockActions)
880584
+ return runUnavailable(resolved.action, route, "commandContext.openBlockActions is unavailable.");
880585
+ const opened = context.openBlockActions();
880586
+ return opened ? {
880587
+ status: "visible_interaction_required",
880588
+ action: resolved.action,
880589
+ effect: "block-actions-opened",
880590
+ keybinding: descriptor,
880591
+ note: "The block action surface is open. Selecting the exact nearest-block action remains visible interactive shell work."
880592
+ } : {
880593
+ status: "not_opened",
880594
+ action: resolved.action,
880595
+ effect: "block-actions",
880596
+ keybinding: descriptor,
880597
+ note: "The current shell did not have an empty prompt plus nearby block required for block actions."
880598
+ };
880599
+ }
880600
+ default:
880601
+ return {
880602
+ status: "unsupported_keybinding_action",
880603
+ action: resolved.action,
880604
+ keybinding: descriptor,
880605
+ modelOperation: route
880606
+ };
880607
+ }
880608
+ }
880290
880609
  function setHarnessKeybinding(context, args2) {
880291
880610
  const manager5 = requireKeybindingsManager2(context);
880292
880611
  const resolved = resolveHarnessKeybinding(context, args2);
@@ -881056,6 +881375,7 @@ var AGENT_HARNESS_MODES = [
881056
881375
  "shortcuts",
881057
881376
  "keybindings",
881058
881377
  "keybinding",
881378
+ "run_keybinding",
881059
881379
  "set_keybinding",
881060
881380
  "reset_keybinding",
881061
881381
  "commands",
@@ -881094,7 +881414,7 @@ var AGENT_HARNESS_PARAMETER_PROPERTIES = {
881094
881414
  },
881095
881415
  command: {
881096
881416
  type: "string",
881097
- description: 'Full slash command string for mode command, workspace_action lookup, or 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".'
881417
+ description: 'Full slash command string for mode command, workspace_action/run_workspace_action lookup, or 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".'
881098
881418
  },
881099
881419
  cliCommand: {
881100
881420
  type: "string",
@@ -881123,7 +881443,7 @@ var AGENT_HARNESS_PARAMETER_PROPERTIES = {
881123
881443
  },
881124
881444
  actionId: {
881125
881445
  type: "string",
881126
- description: "Agent workspace action id for workspace_action or run_workspace_action, or keybinding action id for keybinding/set_keybinding/reset_keybinding. target or query can also look up one keybinding action."
881446
+ description: "Agent workspace action id for workspace_action or run_workspace_action, or keybinding action id for keybinding/run_keybinding/set_keybinding/reset_keybinding. command, target, or query can also look up one workspace action; target or query can also look up one keybinding action."
881127
881447
  },
881128
881448
  fields: {
881129
881449
  type: "object",
@@ -881153,7 +881473,7 @@ var AGENT_HARNESS_PARAMETER_PROPERTIES = {
881153
881473
  { type: "number" },
881154
881474
  { type: "boolean" }
881155
881475
  ],
881156
- description: "Setting value for set_setting. Strings, booleans, numbers, and enum strings are accepted."
881476
+ description: "Setting value for set_setting. Strings, booleans, numbers, and enum strings are accepted. In run_keybinding, value can provide visible search text for search/history-search shortcut routes."
881157
881477
  },
881158
881478
  target: {
881159
881479
  type: "string",
@@ -881194,11 +881514,11 @@ var AGENT_HARNESS_PARAMETER_PROPERTIES = {
881194
881514
  },
881195
881515
  confirm: {
881196
881516
  type: "boolean",
881197
- description: "Required true for set_setting, reset_setting, run_command, open_panel, open_ui_surface, and mutating run_workspace_action calls after an explicit user request."
881517
+ description: "Required true for set_setting, reset_setting, run_keybinding, run_command, open_panel, open_ui_surface, and mutating run_workspace_action calls after an explicit user request."
881198
881518
  },
881199
881519
  explicitUserRequest: {
881200
881520
  type: "string",
881201
- description: "Exact user request or faithful short summary authorizing a setting mutation or harness UI/command invocation."
881521
+ description: "Exact user request or faithful short summary authorizing a setting mutation, keybinding action, or harness UI/command invocation."
881202
881522
  }
881203
881523
  };
881204
881524
 
@@ -881862,7 +882182,7 @@ var UI_SURFACES = [
881862
882182
  kind: "overlay",
881863
882183
  summary: "Keyboard shortcut reference overlay.",
881864
882184
  command: "/shortcuts",
881865
- preferredModelRoute: "Use shortcuts/keybindings modes for model-readable discovery and confirmed keybinding edits.",
882185
+ preferredModelRoute: "Use shortcuts/keybindings modes for model-readable discovery, run_keybinding for supported shell-safe actions, and confirmed keybinding edits for binding changes.",
881866
882186
  available: (context) => typeof context.openShortcutsOverlay === "function",
881867
882187
  open: (context) => {
881868
882188
  const surface = findSurfaceById("shortcuts-overlay");
@@ -882162,17 +882482,6 @@ function listWorkspaceActions(deps, args2) {
882162
882482
  const source = query2 ? searchAgentWorkspaceActions(AGENT_WORKSPACE_CATEGORIES, query2).map((result2) => ({ category: result2.category, action: result2.action })) : allWorkspaceActions();
882163
882483
  return source.filter((entry) => !categoryId || entry.category.id === categoryId).slice(0, limit3).map((entry) => describeWorkspaceAction(entry.category, entry.action, { includeEditor, editorContext }));
882164
882484
  }
882165
- function findWorkspaceAction(args2) {
882166
- const actionId = readString58(args2.actionId || args2.query);
882167
- const categoryId = readString58(args2.categoryId || args2.category);
882168
- if (!actionId)
882169
- return null;
882170
- return allWorkspaceActions().find((entry) => {
882171
- if (categoryId && entry.category.id !== categoryId)
882172
- return false;
882173
- return entry.action.id === actionId || entry.action.label.toLowerCase() === actionId.toLowerCase();
882174
- }) ?? null;
882175
- }
882176
882485
  function workspaceActionLookupFromArgs(args2) {
882177
882486
  const actionId = readString58(args2.actionId);
882178
882487
  if (actionId)
@@ -882380,10 +882689,12 @@ async function runWorkspaceEditorAction(deps, action2, editor, args2) {
882380
882689
  });
882381
882690
  }
882382
882691
  async function runWorkspaceAction(deps, args2) {
882383
- const found = findWorkspaceAction(args2);
882384
- if (!found)
882385
- return error52('run_workspace_action requires a valid actionId. Use mode:"workspace_actions" to inspect available actions.');
882386
- const { category, action: action2 } = found;
882692
+ const resolved = resolveWorkspaceActionDetail(args2);
882693
+ if (resolved?.status === "ambiguous")
882694
+ return error52(`Ambiguous Agent workspace action ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
882695
+ if (!resolved)
882696
+ return error52('run_workspace_action requires a valid actionId, command, target, or query. Use mode:"workspace_actions" to inspect available actions.');
882697
+ const { category, action: action2, lookup } = resolved;
882387
882698
  if (action2.safety === "blocked") {
882388
882699
  return error52(`Workspace action ${action2.id} is blocked in Agent: ${action2.detail}`);
882389
882700
  }
@@ -882391,14 +882702,14 @@ async function runWorkspaceAction(deps, args2) {
882391
882702
  const editorContext2 = buildWorkspaceEditorContext(deps.commandContext, args2);
882392
882703
  return output7({
882393
882704
  status: "guidance",
882394
- action: describeWorkspaceAction(category, action2, { includeEditor: true, editorContext: editorContext2 })
882705
+ action: describeWorkspaceAction(category, action2, { includeEditor: true, editorContext: editorContext2, lookup })
882395
882706
  });
882396
882707
  }
882397
882708
  if (action2.kind === "workspace" && action2.targetCategoryId) {
882398
882709
  const target = AGENT_WORKSPACE_CATEGORIES.find((entry) => entry.id === action2.targetCategoryId);
882399
882710
  return output7({
882400
882711
  status: "workspace_target",
882401
- action: describeWorkspaceAction(category, action2),
882712
+ action: describeWorkspaceAction(category, action2, { lookup }),
882402
882713
  targetCategory: target ? describeWorkspaceCategory(target) : action2.targetCategoryId,
882403
882714
  targetActions: target ? target.actions.map((entry) => describeWorkspaceAction(target, entry)).slice(0, 40) : []
882404
882715
  });
@@ -882407,7 +882718,7 @@ async function runWorkspaceAction(deps, args2) {
882407
882718
  if (/<[^>\s]+(?:\s+[^>]*)?>/.test(action2.command)) {
882408
882719
  return output7({
882409
882720
  status: "needs_concrete_command",
882410
- action: describeWorkspaceAction(category, action2),
882721
+ action: describeWorkspaceAction(category, action2, { lookup }),
882411
882722
  note: 'This workspace action is a command template. Provide concrete values with mode:"run_command" once the exact command is known.'
882412
882723
  });
882413
882724
  }
@@ -882425,7 +882736,7 @@ async function runWorkspaceAction(deps, args2) {
882425
882736
  const editorContext = buildWorkspaceEditorContext(deps.commandContext, args2);
882426
882737
  return output7({
882427
882738
  status: "no_direct_effect",
882428
- action: describeWorkspaceAction(category, action2, { includeEditor: true, editorContext })
882739
+ action: describeWorkspaceAction(category, action2, { includeEditor: true, editorContext, lookup })
882429
882740
  });
882430
882741
  }
882431
882742
  function createAgentHarnessTool(deps) {
@@ -882435,7 +882746,7 @@ function createAgentHarnessTool(deps) {
882435
882746
  description: [
882436
882747
  "Discover and operate the GoodVibes Agent harness from the main conversation.",
882437
882748
  "Use this tool to inspect Agent workspace actions, built-in panels, top-level CLI mirrors, UI surfaces, keybindings, slash commands with policy metadata, model tools or one model tool schema, connected-host capabilities or one connected-host capability detail, and Agent settings, or to invoke a workspace action/command through the same in-process command registry the user uses in the TUI.",
882438
- "Discovery modes are read-only. Setting/keybinding writes, resets, UI routing, slash command invocation, and workspace action invocation require confirm:true plus explicitUserRequest.",
882749
+ "Discovery modes are read-only. Setting/keybinding writes, resets, keybinding actions, UI routing, slash command invocation, and workspace action invocation require confirm:true plus explicitUserRequest.",
882439
882750
  "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."
882440
882751
  ].join(" "),
882441
882752
  parameters: {
@@ -882469,9 +882780,9 @@ function createAgentHarnessTool(deps) {
882469
882780
  cliCommands: 'Use mode:"cli_commands" to list and mode:"cli_command" with cliCommand, command, commandName, target, or query to inspect package CLI mirrors and their preferred in-process model routes. CLI modes are discovery-only.',
882470
882781
  panels: 'Use mode:"panels" to list and mode:"panel" with panelId, target, or query to inspect built-in panel catalog/open state; use mode:"open_panel" with confirm:true plus explicitUserRequest to route a visible panel/workspace change.',
882471
882782
  uiSurfaces: 'Use mode:"ui_surfaces" to list and mode:"ui_surface" with surfaceId, target, or query to inspect modal/overlay/picker/workspace surfaces; use mode:"open_ui_surface" with confirm:true plus explicitUserRequest to route visible UI navigation.',
882472
- shortcuts: 'Use mode:"shortcuts" to inspect fixed shortcuts plus configurable keybindings. Use mode:"keybinding" with actionId, target, key, or query; use mode:"set_keybinding" and mode:"reset_keybinding" with confirm:true plus explicitUserRequest to edit the same config file the user edits.',
882783
+ shortcuts: 'Use mode:"shortcuts" to inspect fixed shortcuts plus configurable keybindings. Use mode:"keybinding" with actionId, target, key, or query; use mode:"run_keybinding" for confirmation-gated shell-safe shortcut equivalents; use mode:"set_keybinding" and mode:"reset_keybinding" with confirm:true plus explicitUserRequest to edit the same config file the user edits.',
882473
882784
  slashCommands: 'Use mode:"commands" to list slash commands and mode:"command" with command, commandName, target, or query to inspect one command; use mode:"run_command" with confirm:true plus explicitUserRequest to execute.',
882474
- workspace: 'Use mode:"workspace_actions" to list and mode:"workspace_action" with actionId, command, target, or query for one action and editor schema; set includeParameters:true on workspace_actions to inline editor schemas.',
882785
+ workspace: 'Use mode:"workspace_actions" to list, mode:"workspace_action" with actionId, command, target, or query for one action and editor schema, and mode:"run_workspace_action" with the same lookup fields plus confirmation for executable actions; set includeParameters:true on workspace_actions to inline editor schemas.',
882475
882786
  settings: 'Use mode:"settings" to list and mode:"get_setting" with key, target, or query for one setting. Use mode:"set_setting" or mode:"reset_setting" with key, target, or query plus confirm:true and explicitUserRequest.',
882476
882787
  tools: 'Use mode:"tools" to list first-class model tools, or mode:"tool" with toolName, target, or query to inspect one schema.',
882477
882788
  connectedHost: 'Use mode:"connected_host" for the connected-host capability map and blocked boundaries. Use mode:"connected_host_capability" with capabilityId, target, or query for one allowed or blocked capability.',
@@ -882537,15 +882848,15 @@ function createAgentHarnessTool(deps) {
882537
882848
  }
882538
882849
  if (args2.mode === "set_keybinding") {
882539
882850
  const confirmationError2 = requireConfirmedAction(args2, "Keybinding mutation");
882540
- if (confirmationError2)
882541
- return error52(confirmationError2);
882542
- return output7(setHarnessKeybinding(deps.commandContext, args2));
882851
+ return confirmationError2 ? error52(confirmationError2) : output7(setHarnessKeybinding(deps.commandContext, args2));
882543
882852
  }
882544
882853
  if (args2.mode === "reset_keybinding") {
882545
882854
  const confirmationError2 = requireConfirmedAction(args2, "Keybinding reset");
882546
- if (confirmationError2)
882547
- return error52(confirmationError2);
882548
- return output7(resetHarnessKeybinding(deps.commandContext, args2));
882855
+ return confirmationError2 ? error52(confirmationError2) : output7(resetHarnessKeybinding(deps.commandContext, args2));
882856
+ }
882857
+ if (args2.mode === "run_keybinding") {
882858
+ const confirmationError2 = requireConfirmedAction(args2, "Keybinding action");
882859
+ return confirmationError2 ? error52(confirmationError2) : output7(runHarnessKeybinding(deps.commandContext, args2));
882549
882860
  }
882550
882861
  if (args2.mode === "commands") {
882551
882862
  const commands3 = listHarnessCommands(deps.commandRegistry, args2);