@pellux/goodvibes-agent 1.0.19 → 1.0.20

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 CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  Product-facing release notes for GoodVibes Agent.
4
4
 
5
+ ## 1.0.20 - 2026-06-03
6
+
7
+ - Add agent_harness run_keybinding for confirmation-gated shell-safe shortcut equivalents such as search, prompt-history search, paste, clear screen, cancel generation, panel focus/close routes, and visible block-action routing.
8
+ - Add modelOperation route metadata to every configurable keybinding so the model can distinguish supported shell routes from prompt-editor-only or direct-interaction shortcuts.
9
+ - Refresh package-facing docs and focused harness coverage for keybinding operation parity.
10
+
5
11
  ## 1.0.19 - 2026-06-03
6
12
 
7
13
  - Add agent_harness cli_command lookup by cliCommand, command, commandName, target, or query while preserving parsed metadata for concrete invocations.
package/README.md CHANGED
@@ -7,7 +7,7 @@ GoodVibes Agent is the personal operator assistant TUI for GoodVibes. It is buil
7
7
 
8
8
  The Agent product connects to a GoodVibes host owned outside this package. It does not install, start, stop, restart, or own that host.
9
9
 
10
- Most work happens in the interactive TUI. The installed CLI exists to launch that TUI and provide scriptable mirrors for workflows that are already reachable from the workspace. The main Agent model can inspect the same harness surface through Agent-owned tools: workspace actions and single-action lookup, built-in panels and single-panel lookup, modal/overlay/picker UI surfaces and single-surface lookup, named operator surfaces, top-level CLI mirrors and single-mirror lookup, fixed shortcuts, configurable keybindings and single-keybinding lookup, slash commands, single-command lookup with policy metadata, settings and single-setting lookup, model tools and individual model tool schemas, local registries, connected-host capability boundaries, and live connected-host readiness are all discoverable from the conversation without exposing connected-host lifecycle control.
10
+ Most work happens in the interactive TUI. The installed CLI exists to launch that TUI and provide scriptable mirrors for workflows that are already reachable from the workspace. The main Agent model can inspect the same harness surface through Agent-owned tools: workspace actions and single-action lookup, built-in panels and single-panel lookup, modal/overlay/picker UI surfaces and single-surface lookup, named operator surfaces, top-level CLI mirrors and single-mirror lookup, fixed shortcuts, configurable keybindings, single-keybinding lookup, shell-safe keybinding execution, slash commands, single-command lookup with policy metadata, settings and single-setting lookup, model tools and individual model tool schemas, local registries, connected-host capability boundaries, and live connected-host readiness are all discoverable from the conversation without exposing connected-host lifecycle control.
11
11
 
12
12
  ## Install
13
13
 
@@ -66,7 +66,7 @@ Use the workspace as the primary product surface:
66
66
 
67
67
  Inside the Agent workspace, press `/` to search every workspace action by name, category, command, or detail. This is the primary discovery path for product actions; slash commands and CLI subcommands remain power-user/scriptable mirrors.
68
68
 
69
- The model has the same harness map through `agent_harness`: it can list Agent workspace actions, inspect one workspace action by `actionId`, `command`, `target`, or `query`, list built-in panels and inspect one panel by `panelId`, `target`, or `query`, inspect modal/overlay/picker UI surfaces by `surfaceId`, `target`, or `query`, list top-level CLI mirrors and inspect one mirror by `cliCommand`, `command`, `commandName`, `target`, or `query`, inspect fixed shortcuts and configurable keybindings by `actionId`, `target`, `key`, or `query`, list slash commands, inspect one slash command by `command`, `commandName`, `target`, or `query` with parsed arguments and policy metadata, inspect model tool definitions or one model tool schema, inspect or change Agent settings by `key`, `target`, or `query` with confirmation, run concrete workspace or slash-command mirrors with confirmation, and report connected-host capability and live readiness posture. CLI mirror modes are read-only catalog and parser inspection; inside the main conversation, the model uses the returned preferred model tool, workspace action, setting mode, or confirmed slash-command mirror instead of launching hidden nested CLI processes. Panel modes expose catalog/open state and route visible panel/workspace changes through the current Agent shell bridge with confirmation. UI surface modes expose help, shortcuts, command browser, conversation search, prompt-history search, slash-command mode, file picker, block actions, context, runtime activity, live process output, bookmarks, model/provider/reasoning-effort pickers, TTS provider/voice pickers, session/profile pickers, the panel-picker compatibility route, security/knowledge/subscription operator surfaces, settings, MCP workspace, onboarding, and Agent workspace entrypoints; `open_ui_surface` is confirmation-gated and only performs visible shell navigation. Shortcut modes expose fixed runtime/editor controls plus the live resolved keybinding table; `set_keybinding` and `reset_keybinding` write the same `keybindings.json` file the user edits and require confirmation. Workspace action discovery can inline editor field schemas with `includeParameters:true`; single-action lookup uses the same user-facing search fields and returns lookup metadata plus editor schema; CLI mirror, panel, UI surface, keybinding, and setting lookup use their catalog search fields and refuse ambiguous route or mutation requests with candidates; profile editors use the current starter-template inventory, and routine schedule editors can prefill a selected local routine from `recordId`. Selection-based local workspace actions accept a local `recordId` so the model can use the same note promotion and local registry flows as the TUI. Direct local create editors for memory, notes, personas, skills, and routines can execute from submitted fields through `run_workspace_action` and `agent_local_registry` with confirmation. The `connected_host` report includes route families, allowed capabilities, blocked lifecycle/non-Agent surfaces, and availability for the first-class Agent tools; `connected_host_capability` inspects one allowed or blocked capability by id, target, or query with its route families and boundary. The `connected_host_status` report performs a read-only live check of the connected-host status route and the isolated Agent Knowledge status route, reports SDK compatibility, token posture, endpoint bindings, route readiness, and actionable findings, and still refuses connected-host lifecycle control. The model uses those first-class tools for product workflows where they exist, such as Agent Knowledge, local memory/notes/personas/skills/routines, channel sends, notifications, reminders, media generation, work plans, and connected-host operator actions.
69
+ The model has the same harness map through `agent_harness`: it can list Agent workspace actions, inspect one workspace action by `actionId`, `command`, `target`, or `query`, list built-in panels and inspect one panel by `panelId`, `target`, or `query`, inspect modal/overlay/picker UI surfaces by `surfaceId`, `target`, or `query`, list top-level CLI mirrors and inspect one mirror by `cliCommand`, `command`, `commandName`, `target`, or `query`, inspect fixed shortcuts and configurable keybindings by `actionId`, `target`, `key`, or `query`, run shell-safe keybinding equivalents with confirmation, list slash commands, inspect one slash command by `command`, `commandName`, `target`, or `query` with parsed arguments and policy metadata, inspect model tool definitions or one model tool schema, inspect or change Agent settings by `key`, `target`, or `query` with confirmation, run concrete workspace or slash-command mirrors with confirmation, and report connected-host capability and live readiness posture. CLI mirror modes are read-only catalog and parser inspection; inside the main conversation, the model uses the returned preferred model tool, workspace action, setting mode, or confirmed slash-command mirror instead of launching hidden nested CLI processes. Panel modes expose catalog/open state and route visible panel/workspace changes through the current Agent shell bridge with confirmation. UI surface modes expose help, shortcuts, command browser, conversation search, prompt-history search, slash-command mode, file picker, block actions, context, runtime activity, live process output, bookmarks, model/provider/reasoning-effort pickers, TTS provider/voice pickers, session/profile pickers, the panel-picker compatibility route, security/knowledge/subscription operator surfaces, settings, MCP workspace, onboarding, and Agent workspace entrypoints; `open_ui_surface` is confirmation-gated and only performs visible shell navigation. Shortcut modes expose fixed runtime/editor controls plus the live resolved keybinding table; each keybinding descriptor reports its model operation route, `run_keybinding` executes only supported shell-safe equivalents with confirmation, and prompt-editor-only or terminal-selection shortcuts remain explicit direct user interaction. `set_keybinding` and `reset_keybinding` write the same `keybindings.json` file the user edits and require confirmation. Workspace action discovery can inline editor field schemas with `includeParameters:true`; single-action lookup uses the same user-facing search fields and returns lookup metadata plus editor schema; CLI mirror, panel, UI surface, keybinding, and setting lookup use their catalog search fields and refuse ambiguous route or mutation requests with candidates; profile editors use the current starter-template inventory, and routine schedule editors can prefill a selected local routine from `recordId`. Selection-based local workspace actions accept a local `recordId` so the model can use the same note promotion and local registry flows as the TUI. Direct local create editors for memory, notes, personas, skills, and routines can execute from submitted fields through `run_workspace_action` and `agent_local_registry` with confirmation. The `connected_host` report includes route families, allowed capabilities, blocked lifecycle/non-Agent surfaces, and availability for the first-class Agent tools; `connected_host_capability` inspects one allowed or blocked capability by id, target, or query with its route families and boundary. The `connected_host_status` report performs a read-only live check of the connected-host status route and the isolated Agent Knowledge status route, reports SDK compatibility, token posture, endpoint bindings, route readiness, and actionable findings, and still refuses connected-host lifecycle control. The model uses those first-class tools for product workflows where they exist, such as Agent Knowledge, local memory/notes/personas/skills/routines, channel sends, notifications, reminders, media generation, work plans, and connected-host operator actions.
70
70
 
71
71
  The setup workspace surfaces discovered Agent-local persona, skill, and routine markdown files so day-one setup can import useful behavior instead of starting from blank records. It can also create one initial scratchpad note, local persona, skill, and routine directly during first-run setup; those records stay in Agent-local registries and never write to default knowledge or non-Agent segments.
72
72
 
@@ -816508,7 +816508,7 @@ var createStyledCell = (char, overrides = {}) => ({
816508
816508
  // src/version.ts
816509
816509
  import { readFileSync } from "fs";
816510
816510
  import { join } from "path";
816511
- var _version = "1.0.19";
816511
+ var _version = "1.0.20";
816512
816512
  var _sdkVersion = "0.33.35";
816513
816513
  try {
816514
816514
  const pkg = JSON.parse(readFileSync(join(import.meta.dir, "..", "package.json"), "utf-8"));
@@ -880225,9 +880225,133 @@ function describeBinding(manager5, action2, combos, lookup) {
880225
880225
  labels: combos.map((combo) => manager5.formatCombo(combo)),
880226
880226
  defaultBindings: defaults3.map((combo) => describeCombo(manager5, combo)),
880227
880227
  customized,
880228
- source: customized ? "custom" : "default"
880228
+ source: customized ? "custom" : "default",
880229
+ modelOperation: keybindingOperationRoute(action2)
880229
880230
  };
880230
880231
  }
880232
+ function keybindingOperationRoute(action2) {
880233
+ switch (action2) {
880234
+ case "clear-cancel":
880235
+ return {
880236
+ supported: true,
880237
+ effect: "shell-action",
880238
+ preferredMode: "run_keybinding",
880239
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880240
+ note: "Routes the cancel-generation side of this shortcut through commandContext.cancelGeneration. Prompt clearing and double-press exit remain direct user interaction."
880241
+ };
880242
+ case "screen-clear":
880243
+ return {
880244
+ supported: true,
880245
+ effect: "shell-action",
880246
+ preferredMode: "run_keybinding",
880247
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880248
+ note: "Routes through commandContext.clearScreen."
880249
+ };
880250
+ case "panel-picker":
880251
+ return {
880252
+ supported: true,
880253
+ effect: "visible-ui-navigation",
880254
+ preferredMode: "run_keybinding",
880255
+ surfaceId: "agent-workspace",
880256
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880257
+ note: "Opens the same Agent workspace home route as the panel-picker shortcut."
880258
+ };
880259
+ case "panel-close":
880260
+ return {
880261
+ supported: true,
880262
+ effect: "visible-ui-navigation",
880263
+ preferredMode: "run_keybinding",
880264
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880265
+ note: "Closes the active legacy panel if present, then focuses the prompt when the shell bridge exposes focusPrompt."
880266
+ };
880267
+ case "panel-close-all":
880268
+ return {
880269
+ supported: true,
880270
+ effect: "visible-ui-navigation",
880271
+ preferredMode: "run_keybinding",
880272
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880273
+ note: "Closes all legacy panels if present, hides the panel manager, then focuses the prompt when the shell bridge exposes focusPrompt."
880274
+ };
880275
+ case "history-search":
880276
+ return {
880277
+ supported: true,
880278
+ effect: "visible-ui-navigation",
880279
+ preferredMode: "run_keybinding",
880280
+ surfaceId: "prompt-history-search",
880281
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880282
+ note: "Opens the visible prompt-history search overlay; optional search text may be supplied with value."
880283
+ };
880284
+ case "search":
880285
+ return {
880286
+ supported: true,
880287
+ effect: "visible-ui-navigation",
880288
+ preferredMode: "run_keybinding",
880289
+ surfaceId: "conversation-search",
880290
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880291
+ note: "Opens the visible conversation search overlay; optional search text may be supplied with value."
880292
+ };
880293
+ case "paste":
880294
+ return {
880295
+ supported: true,
880296
+ effect: "shell-action",
880297
+ preferredMode: "run_keybinding",
880298
+ command: "/paste",
880299
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880300
+ note: "Routes through commandContext.pasteFromClipboard and reports whether text, image, or nothing was pasted."
880301
+ };
880302
+ case "block-copy":
880303
+ case "bookmark":
880304
+ case "block-save":
880305
+ return {
880306
+ supported: true,
880307
+ effect: "visible-ui-interaction",
880308
+ preferredMode: "run_keybinding",
880309
+ surfaceId: "block-actions",
880310
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
880311
+ 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."
880312
+ };
880313
+ case "panel-tab-next":
880314
+ case "panel-tab-prev":
880315
+ return {
880316
+ supported: false,
880317
+ effect: "visible-ui-navigation",
880318
+ preferredMode: "open_ui_surface",
880319
+ surfaceId: "agent-workspace",
880320
+ confirmation: "Use open_ui_surface with confirm:true and an explicit categoryId/target instead of cycling hidden UI state.",
880321
+ note: "Category cycling depends on the live workspace focus position. The model should open the intended Agent workspace category directly."
880322
+ };
880323
+ case "copy-selection":
880324
+ return {
880325
+ supported: false,
880326
+ effect: "clipboard-selection",
880327
+ preferredMode: "direct-user-interaction",
880328
+ confirmation: "No model operation is exposed.",
880329
+ 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."
880330
+ };
880331
+ case "delete-word":
880332
+ case "line-start":
880333
+ case "next-error-line-end":
880334
+ case "kill-line":
880335
+ case "clear-prompt":
880336
+ case "undo":
880337
+ case "redo":
880338
+ return {
880339
+ supported: false,
880340
+ effect: "prompt-editor-state",
880341
+ preferredMode: "direct-user-interaction",
880342
+ confirmation: "No model operation is exposed.",
880343
+ note: "This shortcut mutates live prompt-buffer cursor/edit state that is not part of the model tool contract."
880344
+ };
880345
+ case "replay-panel":
880346
+ return {
880347
+ supported: false,
880348
+ effect: "reserved",
880349
+ preferredMode: "direct-user-interaction",
880350
+ confirmation: "No model operation is exposed.",
880351
+ note: "This shortcut is reserved and has no current Agent operation route."
880352
+ };
880353
+ }
880354
+ }
880231
880355
  function readOverrideFile(configPath) {
880232
880356
  if (!existsSync82(configPath))
880233
880357
  return {};
@@ -880259,7 +880383,7 @@ ${shortcut.description}`.toLowerCase().includes(query2)).slice(0, readLimit7(arg
880259
880383
  configurableKeybindings: keybindings.keybindings,
880260
880384
  returned: fixed.length + Number(keybindings.returned ?? 0),
880261
880385
  total: totalHarnessShortcuts(context),
880262
- policy: "Fixed shortcuts are runtime/editor controls. Configurable keybindings can be changed with set_keybinding/reset_keybinding."
880386
+ 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
880387
  };
880264
880388
  }
880265
880389
  function listHarnessKeybindings(context, args2) {
@@ -880271,7 +880395,7 @@ function listHarnessKeybindings(context, args2) {
880271
880395
  keybindings: entries,
880272
880396
  returned: entries.length,
880273
880397
  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."
880398
+ 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
880399
  };
880276
880400
  }
880277
880401
  function describeHarnessKeybinding(context, args2) {
@@ -880287,6 +880411,143 @@ function describeHarnessKeybinding(context, args2) {
880287
880411
  ...describeBinding(manager5, entry.action, entry.combos, resolved.lookup)
880288
880412
  } : null;
880289
880413
  }
880414
+ function runUnavailable(action2, route, reason) {
880415
+ return {
880416
+ status: "keybinding_route_unavailable",
880417
+ action: action2,
880418
+ modelOperation: route,
880419
+ ...reason ? { reason } : {}
880420
+ };
880421
+ }
880422
+ function runHarnessKeybinding(context, args2) {
880423
+ const manager5 = requireKeybindingsManager2(context);
880424
+ const resolved = resolveHarnessKeybinding(context, args2);
880425
+ if (resolved?.status === "ambiguous")
880426
+ return { status: "ambiguous", input: resolved.input, candidates: resolved.candidates };
880427
+ if (!resolved)
880428
+ throw new Error("run_keybinding requires a valid keybinding action id, target, key, or query.");
880429
+ const entry = manager5.getAll().find((candidate) => candidate.action === resolved.action);
880430
+ if (!entry)
880431
+ throw new Error(`No live keybinding entry found for ${resolved.action}.`);
880432
+ const route = keybindingOperationRoute(resolved.action);
880433
+ const descriptor = {
880434
+ configPath: manager5.getConfigPath(),
880435
+ ...describeBinding(manager5, entry.action, entry.combos, resolved.lookup)
880436
+ };
880437
+ if (!route.supported) {
880438
+ return {
880439
+ status: "unsupported_keybinding_action",
880440
+ action: resolved.action,
880441
+ keybinding: descriptor,
880442
+ modelOperation: route
880443
+ };
880444
+ }
880445
+ switch (resolved.action) {
880446
+ case "clear-cancel":
880447
+ if (!context.cancelGeneration)
880448
+ return runUnavailable(resolved.action, route, "commandContext.cancelGeneration is unavailable.");
880449
+ context.cancelGeneration();
880450
+ return { status: "executed", action: resolved.action, effect: "cancel-generation", keybinding: descriptor };
880451
+ case "screen-clear":
880452
+ if (!context.clearScreen)
880453
+ return runUnavailable(resolved.action, route, "commandContext.clearScreen is unavailable.");
880454
+ context.clearScreen();
880455
+ return { status: "executed", action: resolved.action, effect: "screen-clear", keybinding: descriptor };
880456
+ case "panel-picker":
880457
+ if (context.openPanelPicker) {
880458
+ context.openPanelPicker();
880459
+ return { status: "executed", action: resolved.action, effect: "agent-workspace-opened", route: "openPanelPicker", keybinding: descriptor };
880460
+ }
880461
+ if (context.openAgentWorkspace) {
880462
+ context.openAgentWorkspace("home");
880463
+ return { status: "executed", action: resolved.action, effect: "agent-workspace-opened", route: "openAgentWorkspace", categoryId: "home", keybinding: descriptor };
880464
+ }
880465
+ return runUnavailable(resolved.action, route, "No panel picker or Agent workspace opener is available.");
880466
+ case "panel-close": {
880467
+ const active = context.workspace.panelManager?.getActivePanel() ?? null;
880468
+ if (active)
880469
+ context.workspace.panelManager?.close(active.id);
880470
+ if (!active && !context.focusPrompt)
880471
+ return runUnavailable(resolved.action, route, "No active legacy panel or prompt focus route is available.");
880472
+ if (context.focusPrompt)
880473
+ context.focusPrompt();
880474
+ context.renderRequest();
880475
+ return {
880476
+ status: "executed",
880477
+ action: resolved.action,
880478
+ effect: active ? "active-panel-closed" : "prompt-focused",
880479
+ ...active ? { panelId: active.id } : {},
880480
+ keybinding: descriptor
880481
+ };
880482
+ }
880483
+ case "panel-close-all": {
880484
+ const managerPanel = context.workspace.panelManager;
880485
+ const openPanels = managerPanel?.getAllOpen() ?? [];
880486
+ for (const panel of openPanels)
880487
+ managerPanel?.close(panel.id);
880488
+ managerPanel?.hide();
880489
+ if (openPanels.length === 0 && !context.focusPrompt)
880490
+ return runUnavailable(resolved.action, route, "No open legacy panels or prompt focus route is available.");
880491
+ if (context.focusPrompt)
880492
+ context.focusPrompt();
880493
+ context.renderRequest();
880494
+ return {
880495
+ status: "executed",
880496
+ action: resolved.action,
880497
+ effect: "all-panels-closed",
880498
+ closedPanels: openPanels.map((panel) => panel.id),
880499
+ keybinding: descriptor
880500
+ };
880501
+ }
880502
+ case "history-search": {
880503
+ if (!context.openPromptHistorySearch)
880504
+ return runUnavailable(resolved.action, route, "commandContext.openPromptHistorySearch is unavailable.");
880505
+ const query2 = readString52(args2.value);
880506
+ context.openPromptHistorySearch(query2 || undefined);
880507
+ return { status: "executed", action: resolved.action, effect: "prompt-history-search-opened", query: query2, keybinding: descriptor };
880508
+ }
880509
+ case "search": {
880510
+ if (!context.openConversationSearch)
880511
+ return runUnavailable(resolved.action, route, "commandContext.openConversationSearch is unavailable.");
880512
+ const query2 = readString52(args2.value);
880513
+ context.openConversationSearch(query2 || undefined);
880514
+ return { status: "executed", action: resolved.action, effect: "conversation-search-opened", query: query2, keybinding: descriptor };
880515
+ }
880516
+ case "paste": {
880517
+ if (!context.pasteFromClipboard)
880518
+ return runUnavailable(resolved.action, route, "commandContext.pasteFromClipboard is unavailable.");
880519
+ const pasted = context.pasteFromClipboard();
880520
+ return { status: "executed", action: resolved.action, effect: "paste-from-clipboard", pasted, keybinding: descriptor };
880521
+ }
880522
+ case "block-copy":
880523
+ case "bookmark":
880524
+ case "block-save": {
880525
+ if (!context.openBlockActions)
880526
+ return runUnavailable(resolved.action, route, "commandContext.openBlockActions is unavailable.");
880527
+ const opened = context.openBlockActions();
880528
+ return opened ? {
880529
+ status: "visible_interaction_required",
880530
+ action: resolved.action,
880531
+ effect: "block-actions-opened",
880532
+ keybinding: descriptor,
880533
+ note: "The block action surface is open. Selecting the exact nearest-block action remains visible interactive shell work."
880534
+ } : {
880535
+ status: "not_opened",
880536
+ action: resolved.action,
880537
+ effect: "block-actions",
880538
+ keybinding: descriptor,
880539
+ note: "The current shell did not have an empty prompt plus nearby block required for block actions."
880540
+ };
880541
+ }
880542
+ default:
880543
+ return {
880544
+ status: "unsupported_keybinding_action",
880545
+ action: resolved.action,
880546
+ keybinding: descriptor,
880547
+ modelOperation: route
880548
+ };
880549
+ }
880550
+ }
880290
880551
  function setHarnessKeybinding(context, args2) {
880291
880552
  const manager5 = requireKeybindingsManager2(context);
880292
880553
  const resolved = resolveHarnessKeybinding(context, args2);
@@ -881056,6 +881317,7 @@ var AGENT_HARNESS_MODES = [
881056
881317
  "shortcuts",
881057
881318
  "keybindings",
881058
881319
  "keybinding",
881320
+ "run_keybinding",
881059
881321
  "set_keybinding",
881060
881322
  "reset_keybinding",
881061
881323
  "commands",
@@ -881123,7 +881385,7 @@ var AGENT_HARNESS_PARAMETER_PROPERTIES = {
881123
881385
  },
881124
881386
  actionId: {
881125
881387
  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."
881388
+ description: "Agent workspace action id for workspace_action or run_workspace_action, or keybinding action id for keybinding/run_keybinding/set_keybinding/reset_keybinding. target or query can also look up one keybinding action."
881127
881389
  },
881128
881390
  fields: {
881129
881391
  type: "object",
@@ -881153,7 +881415,7 @@ var AGENT_HARNESS_PARAMETER_PROPERTIES = {
881153
881415
  { type: "number" },
881154
881416
  { type: "boolean" }
881155
881417
  ],
881156
- description: "Setting value for set_setting. Strings, booleans, numbers, and enum strings are accepted."
881418
+ 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
881419
  },
881158
881420
  target: {
881159
881421
  type: "string",
@@ -881194,11 +881456,11 @@ var AGENT_HARNESS_PARAMETER_PROPERTIES = {
881194
881456
  },
881195
881457
  confirm: {
881196
881458
  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."
881459
+ 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
881460
  },
881199
881461
  explicitUserRequest: {
881200
881462
  type: "string",
881201
- description: "Exact user request or faithful short summary authorizing a setting mutation or harness UI/command invocation."
881463
+ description: "Exact user request or faithful short summary authorizing a setting mutation, keybinding action, or harness UI/command invocation."
881202
881464
  }
881203
881465
  };
881204
881466
 
@@ -881862,7 +882124,7 @@ var UI_SURFACES = [
881862
882124
  kind: "overlay",
881863
882125
  summary: "Keyboard shortcut reference overlay.",
881864
882126
  command: "/shortcuts",
881865
- preferredModelRoute: "Use shortcuts/keybindings modes for model-readable discovery and confirmed keybinding edits.",
882127
+ preferredModelRoute: "Use shortcuts/keybindings modes for model-readable discovery, run_keybinding for supported shell-safe actions, and confirmed keybinding edits for binding changes.",
881866
882128
  available: (context) => typeof context.openShortcutsOverlay === "function",
881867
882129
  open: (context) => {
881868
882130
  const surface = findSurfaceById("shortcuts-overlay");
@@ -882435,7 +882697,7 @@ function createAgentHarnessTool(deps) {
882435
882697
  description: [
882436
882698
  "Discover and operate the GoodVibes Agent harness from the main conversation.",
882437
882699
  "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.",
882700
+ "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
882701
  "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
882702
  ].join(" "),
882441
882703
  parameters: {
@@ -882469,7 +882731,7 @@ function createAgentHarnessTool(deps) {
882469
882731
  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
882732
  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
882733
  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.',
882734
+ 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
882735
  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
882736
  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.',
882475
882737
  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.',
@@ -882537,15 +882799,15 @@ function createAgentHarnessTool(deps) {
882537
882799
  }
882538
882800
  if (args2.mode === "set_keybinding") {
882539
882801
  const confirmationError2 = requireConfirmedAction(args2, "Keybinding mutation");
882540
- if (confirmationError2)
882541
- return error52(confirmationError2);
882542
- return output7(setHarnessKeybinding(deps.commandContext, args2));
882802
+ return confirmationError2 ? error52(confirmationError2) : output7(setHarnessKeybinding(deps.commandContext, args2));
882543
882803
  }
882544
882804
  if (args2.mode === "reset_keybinding") {
882545
882805
  const confirmationError2 = requireConfirmedAction(args2, "Keybinding reset");
882546
- if (confirmationError2)
882547
- return error52(confirmationError2);
882548
- return output7(resetHarnessKeybinding(deps.commandContext, args2));
882806
+ return confirmationError2 ? error52(confirmationError2) : output7(resetHarnessKeybinding(deps.commandContext, args2));
882807
+ }
882808
+ if (args2.mode === "run_keybinding") {
882809
+ const confirmationError2 = requireConfirmedAction(args2, "Keybinding action");
882810
+ return confirmationError2 ? error52(confirmationError2) : output7(runHarnessKeybinding(deps.commandContext, args2));
882549
882811
  }
882550
882812
  if (args2.mode === "commands") {
882551
882813
  const commands3 = listHarnessCommands(deps.commandRegistry, args2);
package/docs/README.md CHANGED
@@ -22,7 +22,7 @@ Important baseline constraints:
22
22
  - Agent depends on `@pellux/goodvibes-sdk@0.33.35`.
23
23
  - Agent connects to a GoodVibes host owned outside this product.
24
24
  - Agent does not start, stop, restart, install, uninstall, or own the connected GoodVibes host.
25
- - User-facing Agent workspace actions, single workspace-action lookup, built-in panels and single-panel lookup, modal/overlay/picker UI surfaces and single-surface lookup, named operator surfaces, top-level CLI mirrors and single-mirror lookup, fixed shortcuts, configurable keybindings and single-keybinding lookup, slash commands, single-command lookup with policy metadata, model tools and individual model tool schemas, settings and single-setting lookup, local registries, connected-host capability boundaries, single connected-host capability inspection, and live connected-host readiness are model-visible through Agent-owned tools. Visible UI routing includes the command browser, reasoning-effort picker, live process output, runtime activity, settings, workspaces, and pickers the user can open. Local memory, note, persona, skill, and routine create editors can also run through confirmed workspace actions. Mutations and visible UI routing remain explicit and confirmation-gated, and ambiguous lookup matches are refused with candidates instead of guessed.
25
+ - User-facing Agent workspace actions, single workspace-action lookup, built-in panels and single-panel lookup, modal/overlay/picker UI surfaces and single-surface lookup, named operator surfaces, top-level CLI mirrors and single-mirror lookup, fixed shortcuts, configurable keybindings, single-keybinding lookup, shell-safe keybinding execution, slash commands, single-command lookup with policy metadata, model tools and individual model tool schemas, settings and single-setting lookup, local registries, connected-host capability boundaries, single connected-host capability inspection, and live connected-host readiness are model-visible through Agent-owned tools. Visible UI routing includes the command browser, reasoning-effort picker, live process output, runtime activity, settings, workspaces, and pickers the user can open. Local memory, note, persona, skill, and routine create editors can also run through confirmed workspace actions. Mutations, visible UI routing, and keybinding execution remain explicit and confirmation-gated; prompt-editor-only shortcuts stay direct user interaction; and ambiguous lookup matches are refused with candidates instead of guessed.
26
26
  - Agent Knowledge uses only `/api/goodvibes-agent/knowledge/*`; there is no default knowledge or non-Agent product fallback.
27
27
  - Agent supports isolated Agent homes with `GOODVIBES_AGENT_HOME=<path>` and named profile homes with `goodvibes-agent profiles create <name> --template <starter> --yes` plus `--agent-profile <name>`.
28
28
  - Agent supports connected-host URL overrides with `--runtime-url http://host:port` or `GOODVIBES_AGENT_RUNTIME_URL=http://host:port`; these only change the Agent connection target.
@@ -44,7 +44,7 @@ After setup has been applied once, the TUI opens directly into the Agent operato
44
44
 
45
45
  Press `/` inside the Agent workspace to search every workspace action by name, category, command, or detail. Use that finder before reaching for shell commands; CLI subcommands are scriptable mirrors of these TUI workflows.
46
46
 
47
- The model can inspect and use the same harness surface through Agent-owned tools. `agent_harness` exposes workspace action discovery, single workspace-action inspection by action id, command, or lookup text, built-in panel discovery/routing by panel id or lookup text, modal/overlay/picker UI surface discovery/routing by surface id or lookup text, top-level CLI mirror discovery and single-mirror lookup by command string, command token, or lookup text, fixed shortcut and configurable keybinding discovery, keybinding inspection/mutation by action id or lookup text, slash-command discovery, single slash-command inspection by typed command or lookup text, command policy metadata, command execution with confirmation, model tool discovery and single-tool schema inspection, settings inspection/mutation by key or lookup text, connected-host capability inventory, single connected-host capability inspection, and live connected-host readiness posture. CLI mirror modes are read-only catalog/parser inspection and point the model to the matching in-process tool, workspace action, setting mode, or slash-command mirror. Panel modes expose catalog/open state and route visible panel/workspace changes through the current Agent shell bridge with confirmation. UI surface modes expose help, shortcuts, command browser, conversation search, prompt-history search, slash-command mode, file picker, block actions, context, runtime activity, live process output, bookmarks, model/provider/reasoning-effort pickers, TTS provider/voice pickers, session/profile pickers, the panel-picker compatibility route, security/knowledge/subscription operator surfaces, settings, MCP workspace, onboarding, and Agent workspace entrypoints; `open_ui_surface` is confirmation-gated and only performs visible shell navigation. Shortcut modes expose the fixed runtime/editor shortcuts and the live keybindings table; confirmed keybinding edits write the same `keybindings.json` file the user edits and reload the runtime manager. Workspace action discovery can include editor field schemas with `includeParameters:true`, including starter-template defaults for profile creation and selected-routine defaults for routine schedule promotion when `recordId` is supplied; single-action lookup uses the same user-facing search fields and returns lookup metadata plus the editor schema; single-CLI-mirror, single-panel, single-surface, single-keybinding, and single-setting lookup use their catalog search fields, return lookup metadata, and refuse ambiguous route or mutation requests with candidates. Selection-based local workspace actions accept a local `recordId`, so the model can use the same note promotion and local registry flows as the TUI. Direct local create editors for memory, notes, personas, skills, and routines can execute from submitted fields through `run_workspace_action` and `agent_local_registry` with confirmation. First-class model tools cover the main product workflows directly: Agent Knowledge, Agent Knowledge ingest, Agent-local memory/notes/personas/skills/routines, operator actions, notifications, channel sends, reminders, generated media, and work plans.
47
+ The model can inspect and use the same harness surface through Agent-owned tools. `agent_harness` exposes workspace action discovery, single workspace-action inspection by action id, command, or lookup text, built-in panel discovery/routing by panel id or lookup text, modal/overlay/picker UI surface discovery/routing by surface id or lookup text, top-level CLI mirror discovery and single-mirror lookup by command string, command token, or lookup text, fixed shortcut and configurable keybinding discovery, keybinding inspection/mutation by action id or lookup text, confirmation-gated shell-safe keybinding execution, slash-command discovery, single slash-command inspection by typed command or lookup text, command policy metadata, command execution with confirmation, model tool discovery and single-tool schema inspection, settings inspection/mutation by key or lookup text, connected-host capability inventory, single connected-host capability inspection, and live connected-host readiness posture. CLI mirror modes are read-only catalog/parser inspection and point the model to the matching in-process tool, workspace action, setting mode, or slash-command mirror. Panel modes expose catalog/open state and route visible panel/workspace changes through the current Agent shell bridge with confirmation. UI surface modes expose help, shortcuts, command browser, conversation search, prompt-history search, slash-command mode, file picker, block actions, context, runtime activity, live process output, bookmarks, model/provider/reasoning-effort pickers, TTS provider/voice pickers, session/profile pickers, the panel-picker compatibility route, security/knowledge/subscription operator surfaces, settings, MCP workspace, onboarding, and Agent workspace entrypoints; `open_ui_surface` is confirmation-gated and only performs visible shell navigation. Shortcut modes expose the fixed runtime/editor shortcuts and the live keybindings table; keybinding descriptors include a model operation route, `run_keybinding` executes supported shell-safe equivalents only with confirmation, prompt-editor-only or terminal-selection shortcuts remain direct user interaction, and confirmed keybinding edits write the same `keybindings.json` file the user edits and reload the runtime manager. Workspace action discovery can include editor field schemas with `includeParameters:true`, including starter-template defaults for profile creation and selected-routine defaults for routine schedule promotion when `recordId` is supplied; single-action lookup uses the same user-facing search fields and returns lookup metadata plus the editor schema; single-CLI-mirror, single-panel, single-surface, single-keybinding, and single-setting lookup use their catalog search fields, return lookup metadata, and refuse ambiguous route or mutation requests with candidates. Selection-based local workspace actions accept a local `recordId`, so the model can use the same note promotion and local registry flows as the TUI. Direct local create editors for memory, notes, personas, skills, and routines can execute from submitted fields through `run_workspace_action` and `agent_local_registry` with confirmation. First-class model tools cover the main product workflows directly: Agent Knowledge, Agent Knowledge ingest, Agent-local memory/notes/personas/skills/routines, operator actions, notifications, channel sends, reminders, generated media, and work plans.
48
48
 
49
49
  Use the Artifacts area for concrete files and generated output: attach images to prompts, export conversations or saved sessions, ingest local source files and URL lists into Agent Knowledge, import bookmarks or browser history, inspect source records, and generate media artifacts from confirmed prompts.
50
50
 
@@ -122,7 +122,7 @@ Use `/channels` inside the TUI for channel readiness and exact confirmed sends.
122
122
 
123
123
  The main assistant conversation can perform narrow confirmed operator actions when the user explicitly asks for a specific target: approve/deny/cancel one approval, run/pause/resume one automation job, cancel/retry one automation run, or run one schedule. Those calls use only public connected-host routes, require confirmation, and do not create, edit, or delete automation definitions.
124
124
 
125
- When the main assistant conversation needs to change Agent settings, change Agent keybindings, open a visible UI surface, or run a user-facing harness action, it should use `agent_harness` rather than generic SDK context/settings tools. Panel, UI surface, keybinding, and setting descriptors report lookup metadata when resolved from `target` or `query`; ambiguous route or mutation requests return candidates instead of guessing. Setting descriptors also report writability, workspace visibility, and lock reasons. Keybinding descriptors report fixed shortcuts, resolved bindings, defaults, custom state, and config path; UI surface descriptors report the visible shell opener, preferred model route, and confirmation policy; secret-backed settings store raw values through the secret manager; connected-host lifecycle settings stay read-only in Agent; and destructive local record deletion requires explicit confirmation.
125
+ When the main assistant conversation needs to change Agent settings, inspect/change/run supported Agent keybindings, open a visible UI surface, or run a user-facing harness action, it should use `agent_harness` rather than generic SDK context/settings tools. Panel, UI surface, keybinding, and setting descriptors report lookup metadata when resolved from `target` or `query`; ambiguous route or mutation requests return candidates instead of guessing. Setting descriptors also report writability, workspace visibility, and lock reasons. Keybinding descriptors report fixed shortcuts, resolved bindings, defaults, custom state, config path, and model-operation route; unsupported prompt-editor-only shortcuts stay direct user interaction instead of hidden model operations. UI surface descriptors report the visible shell opener, preferred model route, and confirmation policy; secret-backed settings store raw values through the secret manager; connected-host lifecycle settings stay read-only in Agent; and destructive local record deletion requires explicit confirmation.
126
126
 
127
127
  ## Connected GoodVibes Host
128
128
 
@@ -43,26 +43,26 @@ Host-management and coding-first commands that would imply connected-host lifecy
43
43
 
44
44
  The main Agent model has an Agent-owned harness bridge rather than generic SDK settings/context control. Use these model tools as the supported parity layer:
45
45
 
46
- - `agent_harness`: inspect workspace categories/actions and one workspace action by action id, command, or lookup text, inspect built-in panels and one panel by id or lookup text, inspect modal/overlay/picker UI surfaces and named operator surfaces by id or lookup text, inspect top-level CLI mirrors and one mirror by command string, command token, or lookup text, inspect fixed shortcuts and configurable keybindings, inspect or change one keybinding by action id or lookup text, inspect slash commands and one slash command by typed command or lookup text with policy metadata, run concrete workspace or slash-command mirrors with confirmation, inspect model tools or one model tool schema, inspect or change Agent settings by exact key or lookup text, inspect connected-host capability boundaries or one connected-host capability, and inspect live connected-host readiness.
46
+ - `agent_harness`: inspect workspace categories/actions and one workspace action by action id, command, or lookup text, inspect built-in panels and one panel by id or lookup text, inspect modal/overlay/picker UI surfaces and named operator surfaces by id or lookup text, inspect top-level CLI mirrors and one mirror by command string, command token, or lookup text, inspect fixed shortcuts and configurable keybindings, inspect/change/run one keybinding by action id or lookup text where a shell-safe model route exists, inspect slash commands and one slash command by typed command or lookup text with policy metadata, run concrete workspace or slash-command mirrors with confirmation, inspect model tools or one model tool schema, inspect or change Agent settings by exact key or lookup text, inspect connected-host capability boundaries or one connected-host capability, and inspect live connected-host readiness.
47
47
  - `agent_local_registry`: inspect and maintain Agent-local memory, notes, personas, skills, skill bundles, and routines. Deleting local records requires `confirm:true` and `explicitUserRequest`.
48
48
  - `agent_knowledge` and `agent_knowledge_ingest`: ask/search and ingest into the isolated Agent Knowledge segment.
49
49
  - `agent_operator_briefing` and `agent_operator_action`: inspect connected work/approval/automation posture, or run exact confirmed approval/automation actions.
50
50
  - `agent_work_plan`: keep the visible Agent-local work plan current from the conversation.
51
51
  - `agent_channel_send`, `agent_notify`, `agent_reminder_schedule`, and `agent_media_generate`: perform confirmed external delivery, notification, reminder, or media actions when the user explicitly asks.
52
52
 
53
- `agent_harness` discovery modes are read-only. `summary` reports the model access map; `panels` lists the built-in panel catalog, and `panel` resolves one panel by `panelId`, `target`, or `query` with current open/focused state plus its matching Agent workspace route; `ui_surfaces` lists modal, overlay, picker, and workspace entrypoints, and `ui_surface` resolves one by `surfaceId`, `target`, or `query` with shell-opener availability and preferred model routes; `cli_commands` lists top-level package CLI mirror metadata, and `cli_command` resolves one mirror by `cliCommand`, `command`, `commandName`, `target`, or `query`, returning parser output for concrete invocations, blocked command tokens, lookup metadata, and preferred in-process model routes; `shortcuts` returns fixed runtime/editor shortcuts plus configurable keybindings; `keybindings` lists the live resolved keybinding table, and `keybinding`, `set_keybinding`, and `reset_keybinding` resolve one action by `actionId`, `target`, `key`, or `query` with default bindings, custom state, config path, and lookup metadata; `commands` lists slash-command descriptions; `command` returns one slash-command detail by `command`, `commandName`, `target`, or `query`, including parsed arguments plus effect/confirmation/preferred-tool/boundary policy metadata; `workspace_actions` lists Agent workspace actions and can inline editor field schemas with `includeParameters:true`; `workspace_action` returns one action by `actionId`, `command`, `target`, or `query`, using the same user-facing action-search fields and returning lookup metadata plus its editor schema; `tools` lists model tool definitions and can inline JSON schemas with `includeParameters:true`; `tool` returns one model tool schema by `toolName`, `target`, or `query`; `settings` returns setting descriptors plus setting policy; `get_setting`, `set_setting`, and `reset_setting` resolve one setting by `key`, `target`, or `query`, return lookup metadata on success, and refuse ambiguous matches with candidate settings; `connected_host` returns the connected-host route families, allowed capabilities, blocked capabilities, and first-class tool availability; `connected_host_capability` returns one allowed or blocked connected-host capability by `capabilityId`, `target`, or `query` with related route families and boundary text; and `connected_host_status` performs a live read-only check of the connected-host status and Agent Knowledge status routes and reports endpoint bindings, token posture, SDK compatibility, route readiness, and findings without printing token values.
53
+ `agent_harness` discovery modes are read-only. `summary` reports the model access map; `panels` lists the built-in panel catalog, and `panel` resolves one panel by `panelId`, `target`, or `query` with current open/focused state plus its matching Agent workspace route; `ui_surfaces` lists modal, overlay, picker, and workspace entrypoints, and `ui_surface` resolves one by `surfaceId`, `target`, or `query` with shell-opener availability and preferred model routes; `cli_commands` lists top-level package CLI mirror metadata, and `cli_command` resolves one mirror by `cliCommand`, `command`, `commandName`, `target`, or `query`, returning parser output for concrete invocations, blocked command tokens, lookup metadata, and preferred in-process model routes; `shortcuts` returns fixed runtime/editor shortcuts plus configurable keybindings; `keybindings` lists the live resolved keybinding table, and `keybinding`, `run_keybinding`, `set_keybinding`, and `reset_keybinding` resolve one action by `actionId`, `target`, `key`, or `query` with default bindings, custom state, config path, lookup metadata, and model-operation route metadata; `commands` lists slash-command descriptions; `command` returns one slash-command detail by `command`, `commandName`, `target`, or `query`, including parsed arguments plus effect/confirmation/preferred-tool/boundary policy metadata; `workspace_actions` lists Agent workspace actions and can inline editor field schemas with `includeParameters:true`; `workspace_action` returns one action by `actionId`, `command`, `target`, or `query`, using the same user-facing action-search fields and returning lookup metadata plus its editor schema; `tools` lists model tool definitions and can inline JSON schemas with `includeParameters:true`; `tool` returns one model tool schema by `toolName`, `target`, or `query`; `settings` returns setting descriptors plus setting policy; `get_setting`, `set_setting`, and `reset_setting` resolve one setting by `key`, `target`, or `query`, return lookup metadata on success, and refuse ambiguous matches with candidate settings; `connected_host` returns the connected-host route families, allowed capabilities, blocked capabilities, and first-class tool availability; `connected_host_capability` returns one allowed or blocked connected-host capability by `capabilityId`, `target`, or `query` with related route families and boundary text; and `connected_host_status` performs a live read-only check of the connected-host status and Agent Knowledge status routes and reports endpoint bindings, token posture, SDK compatibility, route readiness, and findings without printing token values.
54
54
 
55
55
  `open_ui_surface` is a confirmation-gated visible navigation mode for the same shell surfaces the user can open: Agent workspace, settings, MCP workspace, model/provider/reasoning-effort pickers, TTS provider/voice pickers, session/profile pickers, the panel-picker compatibility route, security/knowledge/subscription operator surfaces, conversation search, prompt-history search, slash-command mode, command browser, file picker, block actions, bookmarks, context inspector, runtime activity monitor, live process output, help, shortcuts, and onboarding. It does not perform hidden operations; use first-class model tools, settings modes, workspace actions, or confirmed slash-command mirrors for actual state changes. Ambiguous UI surface lookup text is refused with candidate surfaces instead of routed.
56
56
 
57
57
  `cli_command` is a read-only inspection mode. Concrete CLI strings are parsed with redacted config overrides; descriptive lookup text searches the same `cli_commands` catalog and returns one match or candidate mirrors when broad.
58
58
 
59
- `set_keybinding` and `reset_keybinding` are confirmation-gated control modes. They write the same Agent `keybindings.json` file exposed by `/keybindings`, reload the runtime keybinding manager, and leave fixed runtime/editor shortcuts read-only. Ambiguous keybinding lookup text is refused with candidate actions instead of guessed.
59
+ `run_keybinding`, `set_keybinding`, and `reset_keybinding` are confirmation-gated control modes. `run_keybinding` executes only keybinding actions with a faithful current-shell route, such as cancel generation, clear screen, open/focus/dismiss visible panel workspace routes, open conversation or prompt-history search, paste through the existing clipboard handler, or open the visible block-action surface. Prompt-editor-only controls, terminal text selection, category cycling, and reserved shortcuts stay visible in descriptors but return unsupported/direct-interaction metadata instead of pretending a hidden model operation exists. `set_keybinding` and `reset_keybinding` write the same Agent `keybindings.json` file exposed by `/keybindings`, reload the runtime keybinding manager, and leave fixed runtime/editor shortcuts read-only. Ambiguous keybinding lookup text is refused with candidate actions instead of guessed.
60
60
 
61
61
  `open_panel` is a confirmation-gated UI routing mode. It hands a visible panel/workspace route to the current Agent shell bridge and does not mutate connected-host lifecycle, listener posture, or external accounts. Ambiguous panel lookup text is refused with candidate panels instead of routed.
62
62
 
63
63
  CLI mirror modes are catalog and parser inspection only. When the user asks the model to operate from inside the main conversation, use the returned first-class model tool, workspace action, setting mode, or confirmed slash-command mirror instead of launching a hidden nested `goodvibes-agent` process.
64
64
 
65
- Setting writes, setting resets, keybinding writes/resets, UI surface routing, slash-command invocation, workspace-action invocation, local record deletion, channel sends, notifications, reminders, media generation, and connected-host operator mutations require explicit user request and confirmation. Secret-backed settings are stored through the secret manager, and connected-host lifecycle/listener settings remain read-only in Agent.
65
+ Setting writes, setting resets, supported keybinding actions, keybinding writes/resets, UI surface routing, slash-command invocation, workspace-action invocation, local record deletion, channel sends, notifications, reminders, media generation, and connected-host operator mutations require explicit user request and confirmation. Secret-backed settings are stored through the secret manager, and connected-host lifecycle/listener settings remain read-only in Agent.
66
66
 
67
67
  Selection-based local workspace actions use the same bridge. `agent_harness` reports the required model tool for each local action; for actions that depend on the TUI selection, call `run_workspace_action` with the selected local `recordId`. Direct local create editors for memory, notes, personas, skills, and routines can execute from submitted `fields` through `run_workspace_action`; the harness validates required fields, requires `confirm:true` and `explicitUserRequest`, and dispatches through `agent_local_registry`. Note promotion actions can prefill and create memory, personas, skills, routines, or isolated Agent Knowledge URL ingests through the matching first-class model tool. Profile creation schemas include the current runtime starter-template inventory, and routine schedule schemas prefill the selected routine when `recordId` or a `routineId` field matches a local routine.
68
68
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-agent",
3
- "version": "1.0.19",
3
+ "version": "1.0.20",
4
4
  "private": false,
5
5
  "description": "GoodVibes personal operator assistant TUI with a proactive Agent product brain, isolated Agent Knowledge, local profiles, routines, skills, personas, and explicit build delegation.",
6
6
  "type": "module",
@@ -32,6 +32,25 @@ interface HarnessKeybindingArgs {
32
32
  readonly limit?: unknown;
33
33
  }
34
34
 
35
+ type KeybindingOperationEffect =
36
+ | 'shell-action'
37
+ | 'visible-ui-navigation'
38
+ | 'visible-ui-interaction'
39
+ | 'prompt-editor-state'
40
+ | 'clipboard-selection'
41
+ | 'reserved'
42
+ | 'disabled';
43
+
44
+ interface KeybindingOperationRoute {
45
+ readonly supported: boolean;
46
+ readonly effect: KeybindingOperationEffect;
47
+ readonly confirmation: string;
48
+ readonly preferredMode?: 'run_keybinding' | 'open_ui_surface' | 'run_command' | 'direct-user-interaction';
49
+ readonly surfaceId?: string;
50
+ readonly command?: string;
51
+ readonly note: string;
52
+ }
53
+
35
54
  type KeybindingsOverrideFile = Record<string, unknown>;
36
55
 
37
56
  interface KeybindingLookup {
@@ -214,9 +233,134 @@ function describeBinding(manager: KeybindingsManager, action: KeyAction, combos:
214
233
  defaultBindings: defaults.map((combo) => describeCombo(manager, combo)),
215
234
  customized,
216
235
  source: customized ? 'custom' : 'default',
236
+ modelOperation: keybindingOperationRoute(action),
217
237
  };
218
238
  }
219
239
 
240
+ function keybindingOperationRoute(action: KeyAction): KeybindingOperationRoute {
241
+ switch (action) {
242
+ case 'clear-cancel':
243
+ return {
244
+ supported: true,
245
+ effect: 'shell-action',
246
+ preferredMode: 'run_keybinding',
247
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
248
+ note: 'Routes the cancel-generation side of this shortcut through commandContext.cancelGeneration. Prompt clearing and double-press exit remain direct user interaction.',
249
+ };
250
+ case 'screen-clear':
251
+ return {
252
+ supported: true,
253
+ effect: 'shell-action',
254
+ preferredMode: 'run_keybinding',
255
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
256
+ note: 'Routes through commandContext.clearScreen.',
257
+ };
258
+ case 'panel-picker':
259
+ return {
260
+ supported: true,
261
+ effect: 'visible-ui-navigation',
262
+ preferredMode: 'run_keybinding',
263
+ surfaceId: 'agent-workspace',
264
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
265
+ note: 'Opens the same Agent workspace home route as the panel-picker shortcut.',
266
+ };
267
+ case 'panel-close':
268
+ return {
269
+ supported: true,
270
+ effect: 'visible-ui-navigation',
271
+ preferredMode: 'run_keybinding',
272
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
273
+ note: 'Closes the active legacy panel if present, then focuses the prompt when the shell bridge exposes focusPrompt.',
274
+ };
275
+ case 'panel-close-all':
276
+ return {
277
+ supported: true,
278
+ effect: 'visible-ui-navigation',
279
+ preferredMode: 'run_keybinding',
280
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
281
+ note: 'Closes all legacy panels if present, hides the panel manager, then focuses the prompt when the shell bridge exposes focusPrompt.',
282
+ };
283
+ case 'history-search':
284
+ return {
285
+ supported: true,
286
+ effect: 'visible-ui-navigation',
287
+ preferredMode: 'run_keybinding',
288
+ surfaceId: 'prompt-history-search',
289
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
290
+ note: 'Opens the visible prompt-history search overlay; optional search text may be supplied with value.',
291
+ };
292
+ case 'search':
293
+ return {
294
+ supported: true,
295
+ effect: 'visible-ui-navigation',
296
+ preferredMode: 'run_keybinding',
297
+ surfaceId: 'conversation-search',
298
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
299
+ note: 'Opens the visible conversation search overlay; optional search text may be supplied with value.',
300
+ };
301
+ case 'paste':
302
+ return {
303
+ supported: true,
304
+ effect: 'shell-action',
305
+ preferredMode: 'run_keybinding',
306
+ command: '/paste',
307
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
308
+ note: 'Routes through commandContext.pasteFromClipboard and reports whether text, image, or nothing was pasted.',
309
+ };
310
+ case 'block-copy':
311
+ case 'bookmark':
312
+ case 'block-save':
313
+ return {
314
+ supported: true,
315
+ effect: 'visible-ui-interaction',
316
+ preferredMode: 'run_keybinding',
317
+ surfaceId: 'block-actions',
318
+ confirmation: 'agent_harness mode:"run_keybinding" requires confirm:true and explicitUserRequest.',
319
+ 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.',
320
+ };
321
+ case 'panel-tab-next':
322
+ case 'panel-tab-prev':
323
+ return {
324
+ supported: false,
325
+ effect: 'visible-ui-navigation',
326
+ preferredMode: 'open_ui_surface',
327
+ surfaceId: 'agent-workspace',
328
+ confirmation: 'Use open_ui_surface with confirm:true and an explicit categoryId/target instead of cycling hidden UI state.',
329
+ note: 'Category cycling depends on the live workspace focus position. The model should open the intended Agent workspace category directly.',
330
+ };
331
+ case 'copy-selection':
332
+ return {
333
+ supported: false,
334
+ effect: 'clipboard-selection',
335
+ preferredMode: 'direct-user-interaction',
336
+ confirmation: 'No model operation is exposed.',
337
+ 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.',
338
+ };
339
+ case 'delete-word':
340
+ case 'line-start':
341
+ case 'next-error-line-end':
342
+ case 'kill-line':
343
+ case 'clear-prompt':
344
+ case 'undo':
345
+ case 'redo':
346
+ return {
347
+ supported: false,
348
+ effect: 'prompt-editor-state',
349
+ preferredMode: 'direct-user-interaction',
350
+ confirmation: 'No model operation is exposed.',
351
+ note: 'This shortcut mutates live prompt-buffer cursor/edit state that is not part of the model tool contract.',
352
+ };
353
+ case 'replay-panel':
354
+ return {
355
+ supported: false,
356
+ effect: 'reserved',
357
+ preferredMode: 'direct-user-interaction',
358
+ confirmation: 'No model operation is exposed.',
359
+ note: 'This shortcut is reserved and has no current Agent operation route.',
360
+ };
361
+ }
362
+ }
363
+
220
364
  function readOverrideFile(configPath: string): KeybindingsOverrideFile {
221
365
  if (!existsSync(configPath)) return {};
222
366
  const parsed = JSON.parse(readFileSync(configPath, 'utf-8')) as unknown;
@@ -252,7 +396,7 @@ export function listHarnessShortcuts(context: CommandContext, args: HarnessKeybi
252
396
  configurableKeybindings: keybindings.keybindings,
253
397
  returned: fixed.length + Number(keybindings.returned ?? 0),
254
398
  total: totalHarnessShortcuts(context),
255
- policy: 'Fixed shortcuts are runtime/editor controls. Configurable keybindings can be changed with set_keybinding/reset_keybinding.',
399
+ 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.',
256
400
  };
257
401
  }
258
402
 
@@ -268,7 +412,7 @@ export function listHarnessKeybindings(context: CommandContext, args: HarnessKey
268
412
  keybindings: entries,
269
413
  returned: entries.length,
270
414
  total: manager.getAll().length,
271
- 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.',
415
+ 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.',
272
416
  };
273
417
  }
274
418
 
@@ -284,6 +428,133 @@ export function describeHarnessKeybinding(context: CommandContext, args: Harness
284
428
  } : null;
285
429
  }
286
430
 
431
+ function runUnavailable(action: KeyAction, route: KeybindingOperationRoute, reason?: string): Record<string, unknown> {
432
+ return {
433
+ status: 'keybinding_route_unavailable',
434
+ action,
435
+ modelOperation: route,
436
+ ...(reason ? { reason } : {}),
437
+ };
438
+ }
439
+
440
+ export function runHarnessKeybinding(context: CommandContext, args: HarnessKeybindingArgs): Record<string, unknown> {
441
+ const manager = requireKeybindingsManager(context);
442
+ const resolved = resolveHarnessKeybinding(context, args);
443
+ if (resolved?.status === 'ambiguous') return { status: 'ambiguous', input: resolved.input, candidates: resolved.candidates };
444
+ if (!resolved) throw new Error('run_keybinding requires a valid keybinding action id, target, key, or query.');
445
+ const entry = manager.getAll().find((candidate) => candidate.action === resolved.action);
446
+ if (!entry) throw new Error(`No live keybinding entry found for ${resolved.action}.`);
447
+ const route = keybindingOperationRoute(resolved.action);
448
+ const descriptor = {
449
+ configPath: manager.getConfigPath(),
450
+ ...describeBinding(manager, entry.action, entry.combos, resolved.lookup),
451
+ };
452
+ if (!route.supported) {
453
+ return {
454
+ status: 'unsupported_keybinding_action',
455
+ action: resolved.action,
456
+ keybinding: descriptor,
457
+ modelOperation: route,
458
+ };
459
+ }
460
+
461
+ switch (resolved.action) {
462
+ case 'clear-cancel':
463
+ if (!context.cancelGeneration) return runUnavailable(resolved.action, route, 'commandContext.cancelGeneration is unavailable.');
464
+ context.cancelGeneration();
465
+ return { status: 'executed', action: resolved.action, effect: 'cancel-generation', keybinding: descriptor };
466
+ case 'screen-clear':
467
+ if (!context.clearScreen) return runUnavailable(resolved.action, route, 'commandContext.clearScreen is unavailable.');
468
+ context.clearScreen();
469
+ return { status: 'executed', action: resolved.action, effect: 'screen-clear', keybinding: descriptor };
470
+ case 'panel-picker':
471
+ if (context.openPanelPicker) {
472
+ context.openPanelPicker();
473
+ return { status: 'executed', action: resolved.action, effect: 'agent-workspace-opened', route: 'openPanelPicker', keybinding: descriptor };
474
+ }
475
+ if (context.openAgentWorkspace) {
476
+ context.openAgentWorkspace('home');
477
+ return { status: 'executed', action: resolved.action, effect: 'agent-workspace-opened', route: 'openAgentWorkspace', categoryId: 'home', keybinding: descriptor };
478
+ }
479
+ return runUnavailable(resolved.action, route, 'No panel picker or Agent workspace opener is available.');
480
+ case 'panel-close': {
481
+ const active = context.workspace.panelManager?.getActivePanel() ?? null;
482
+ if (active) context.workspace.panelManager?.close(active.id);
483
+ if (!active && !context.focusPrompt) return runUnavailable(resolved.action, route, 'No active legacy panel or prompt focus route is available.');
484
+ if (context.focusPrompt) context.focusPrompt();
485
+ context.renderRequest();
486
+ return {
487
+ status: 'executed',
488
+ action: resolved.action,
489
+ effect: active ? 'active-panel-closed' : 'prompt-focused',
490
+ ...(active ? { panelId: active.id } : {}),
491
+ keybinding: descriptor,
492
+ };
493
+ }
494
+ case 'panel-close-all': {
495
+ const managerPanel = context.workspace.panelManager;
496
+ const openPanels = managerPanel?.getAllOpen() ?? [];
497
+ for (const panel of openPanels) managerPanel?.close(panel.id);
498
+ managerPanel?.hide();
499
+ if (openPanels.length === 0 && !context.focusPrompt) return runUnavailable(resolved.action, route, 'No open legacy panels or prompt focus route is available.');
500
+ if (context.focusPrompt) context.focusPrompt();
501
+ context.renderRequest();
502
+ return {
503
+ status: 'executed',
504
+ action: resolved.action,
505
+ effect: 'all-panels-closed',
506
+ closedPanels: openPanels.map((panel) => panel.id),
507
+ keybinding: descriptor,
508
+ };
509
+ }
510
+ case 'history-search': {
511
+ if (!context.openPromptHistorySearch) return runUnavailable(resolved.action, route, 'commandContext.openPromptHistorySearch is unavailable.');
512
+ const query = readString(args.value);
513
+ context.openPromptHistorySearch(query || undefined);
514
+ return { status: 'executed', action: resolved.action, effect: 'prompt-history-search-opened', query, keybinding: descriptor };
515
+ }
516
+ case 'search': {
517
+ if (!context.openConversationSearch) return runUnavailable(resolved.action, route, 'commandContext.openConversationSearch is unavailable.');
518
+ const query = readString(args.value);
519
+ context.openConversationSearch(query || undefined);
520
+ return { status: 'executed', action: resolved.action, effect: 'conversation-search-opened', query, keybinding: descriptor };
521
+ }
522
+ case 'paste': {
523
+ if (!context.pasteFromClipboard) return runUnavailable(resolved.action, route, 'commandContext.pasteFromClipboard is unavailable.');
524
+ const pasted = context.pasteFromClipboard();
525
+ return { status: 'executed', action: resolved.action, effect: 'paste-from-clipboard', pasted, keybinding: descriptor };
526
+ }
527
+ case 'block-copy':
528
+ case 'bookmark':
529
+ case 'block-save': {
530
+ if (!context.openBlockActions) return runUnavailable(resolved.action, route, 'commandContext.openBlockActions is unavailable.');
531
+ const opened = context.openBlockActions();
532
+ return opened
533
+ ? {
534
+ status: 'visible_interaction_required',
535
+ action: resolved.action,
536
+ effect: 'block-actions-opened',
537
+ keybinding: descriptor,
538
+ note: 'The block action surface is open. Selecting the exact nearest-block action remains visible interactive shell work.',
539
+ }
540
+ : {
541
+ status: 'not_opened',
542
+ action: resolved.action,
543
+ effect: 'block-actions',
544
+ keybinding: descriptor,
545
+ note: 'The current shell did not have an empty prompt plus nearby block required for block actions.',
546
+ };
547
+ }
548
+ default:
549
+ return {
550
+ status: 'unsupported_keybinding_action',
551
+ action: resolved.action,
552
+ keybinding: descriptor,
553
+ modelOperation: route,
554
+ };
555
+ }
556
+ }
557
+
287
558
  export function setHarnessKeybinding(context: CommandContext, args: HarnessKeybindingArgs): Record<string, unknown> {
288
559
  const manager = requireKeybindingsManager(context);
289
560
  const resolved = resolveHarnessKeybinding(context, args);
@@ -1,7 +1,7 @@
1
1
  export const AGENT_HARNESS_MODES = [
2
2
  'summary', 'cli_commands', 'cli_command', 'panels', 'panel', 'open_panel',
3
3
  'ui_surfaces', 'ui_surface', 'open_ui_surface',
4
- 'shortcuts', 'keybindings', 'keybinding', 'set_keybinding', 'reset_keybinding',
4
+ 'shortcuts', 'keybindings', 'keybinding', 'run_keybinding', 'set_keybinding', 'reset_keybinding',
5
5
  'commands', 'command', 'run_command', 'settings', 'get_setting', 'set_setting',
6
6
  'reset_setting', 'workspace', 'workspace_categories', 'workspace_actions',
7
7
  'workspace_action', 'run_workspace_action', 'tools', 'tool', 'connected_host', 'connected_host_status',
@@ -56,7 +56,7 @@ export const AGENT_HARNESS_PARAMETER_PROPERTIES = {
56
56
  },
57
57
  actionId: {
58
58
  type: 'string',
59
- 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.',
59
+ description: 'Agent workspace action id for workspace_action or run_workspace_action, or keybinding action id for keybinding/run_keybinding/set_keybinding/reset_keybinding. target or query can also look up one keybinding action.',
60
60
  },
61
61
  fields: {
62
62
  type: 'object',
@@ -86,7 +86,7 @@ export const AGENT_HARNESS_PARAMETER_PROPERTIES = {
86
86
  { type: 'number' },
87
87
  { type: 'boolean' },
88
88
  ],
89
- description: 'Setting value for set_setting. Strings, booleans, numbers, and enum strings are accepted.',
89
+ 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.',
90
90
  },
91
91
  target: {
92
92
  type: 'string',
@@ -127,10 +127,10 @@ export const AGENT_HARNESS_PARAMETER_PROPERTIES = {
127
127
  },
128
128
  confirm: {
129
129
  type: 'boolean',
130
- 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.',
130
+ 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.',
131
131
  },
132
132
  explicitUserRequest: {
133
133
  type: 'string',
134
- description: 'Exact user request or faithful short summary authorizing a setting mutation or harness UI/command invocation.',
134
+ description: 'Exact user request or faithful short summary authorizing a setting mutation, keybinding action, or harness UI/command invocation.',
135
135
  },
136
136
  } as const;
@@ -19,7 +19,7 @@ import type {
19
19
  import { parseSlashCommand } from '../input/slash-command-parser.ts';
20
20
  import { blockedHarnessCliCommandTokens, describeHarnessCliCommand, listHarnessCliCommands, totalHarnessCliCommands } from './agent-harness-cli-metadata.ts';
21
21
  import { describeHarnessCommand, listHarnessCommands } from './agent-harness-command-catalog.ts';
22
- import { describeHarnessKeybinding, listHarnessKeybindings, listHarnessShortcuts, resetHarnessKeybinding, setHarnessKeybinding, totalHarnessKeybindings, totalHarnessShortcuts } from './agent-harness-keybinding-metadata.ts';
22
+ import { describeHarnessKeybinding, listHarnessKeybindings, listHarnessShortcuts, resetHarnessKeybinding, runHarnessKeybinding, setHarnessKeybinding, totalHarnessKeybindings, totalHarnessShortcuts } from './agent-harness-keybinding-metadata.ts';
23
23
  import { describeHarnessPanel, listHarnessPanels, openHarnessPanel, totalHarnessPanels } from './agent-harness-panel-metadata.ts';
24
24
  import { connectedHostStatusSummary } from './agent-harness-connected-host-status.ts';
25
25
  import { describeLocalWorkspaceModelExecution, runLocalWorkspaceAction, runLocalWorkspaceEditorAction } from './agent-harness-local-operations.ts';
@@ -564,7 +564,7 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
564
564
  description: [
565
565
  'Discover and operate the GoodVibes Agent harness from the main conversation.',
566
566
  '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.',
567
- 'Discovery modes are read-only. Setting/keybinding writes, resets, UI routing, slash command invocation, and workspace action invocation require confirm:true plus explicitUserRequest.',
567
+ '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.',
568
568
  '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.',
569
569
  ].join(' '),
570
570
  parameters: {
@@ -597,7 +597,7 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
597
597
  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.',
598
598
  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.',
599
599
  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.',
600
- 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.',
600
+ 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.',
601
601
  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.',
602
602
  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.',
603
603
  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.',
@@ -661,13 +661,15 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
661
661
  }
662
662
  if (args.mode === 'set_keybinding') {
663
663
  const confirmationError = requireConfirmedAction(args, 'Keybinding mutation');
664
- if (confirmationError) return error(confirmationError);
665
- return output(setHarnessKeybinding(deps.commandContext, args));
664
+ return confirmationError ? error(confirmationError) : output(setHarnessKeybinding(deps.commandContext, args));
666
665
  }
667
666
  if (args.mode === 'reset_keybinding') {
668
667
  const confirmationError = requireConfirmedAction(args, 'Keybinding reset');
669
- if (confirmationError) return error(confirmationError);
670
- return output(resetHarnessKeybinding(deps.commandContext, args));
668
+ return confirmationError ? error(confirmationError) : output(resetHarnessKeybinding(deps.commandContext, args));
669
+ }
670
+ if (args.mode === 'run_keybinding') {
671
+ const confirmationError = requireConfirmedAction(args, 'Keybinding action');
672
+ return confirmationError ? error(confirmationError) : output(runHarnessKeybinding(deps.commandContext, args));
671
673
  }
672
674
  if (args.mode === 'commands') {
673
675
  const commands = listHarnessCommands(deps.commandRegistry, args);
@@ -642,7 +642,7 @@ const UI_SURFACES: readonly UiSurfaceDefinition[] = [
642
642
  kind: 'overlay',
643
643
  summary: 'Keyboard shortcut reference overlay.',
644
644
  command: '/shortcuts',
645
- preferredModelRoute: 'Use shortcuts/keybindings modes for model-readable discovery and confirmed keybinding edits.',
645
+ preferredModelRoute: 'Use shortcuts/keybindings modes for model-readable discovery, run_keybinding for supported shell-safe actions, and confirmed keybinding edits for binding changes.',
646
646
  available: (context) => typeof context.openShortcutsOverlay === 'function',
647
647
  open: (context) => {
648
648
  const surface = findSurfaceById('shortcuts-overlay')!;
package/src/version.ts CHANGED
@@ -6,7 +6,7 @@ import { join } from 'node:path';
6
6
  // The prebuild script updates the fallback value before compilation.
7
7
  // Uses import.meta.dir (Bun) to locate package.json relative to this file,
8
8
  // which is correct regardless of the process working directory.
9
- let _version = '1.0.19';
9
+ let _version = '1.0.20';
10
10
  let _sdkVersion = '0.33.35';
11
11
  try {
12
12
  const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8')) as {