@pellux/goodvibes-agent 1.0.34 → 1.0.36

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.
Files changed (87) hide show
  1. package/CHANGELOG.md +28 -13
  2. package/README.md +11 -8
  3. package/dist/package/main.js +1592 -921
  4. package/docs/README.md +6 -5
  5. package/docs/channels-remote-and-api.md +3 -3
  6. package/docs/connected-host.md +3 -3
  7. package/docs/getting-started.md +20 -12
  8. package/docs/knowledge-artifacts-and-multimodal.md +9 -4
  9. package/docs/project-planning.md +3 -3
  10. package/docs/providers-and-routing.md +2 -2
  11. package/docs/release-and-publishing.md +8 -8
  12. package/docs/tools-and-commands.md +34 -17
  13. package/docs/voice-and-live-tts.md +1 -1
  14. package/package.json +1 -1
  15. package/release/live-verification/live-verification.json +15 -15
  16. package/release/live-verification/live-verification.md +19 -21
  17. package/release/release-notes.md +6 -6
  18. package/release/release-readiness.json +64 -64
  19. package/src/agent/harness-control.ts +35 -9
  20. package/src/agent/reminder-schedule-format.ts +2 -5
  21. package/src/agent/reminder-schedule.ts +4 -11
  22. package/src/agent/routine-schedule-format.ts +3 -6
  23. package/src/agent/routine-schedule-promotion.ts +5 -14
  24. package/src/agent/routine-schedule-receipts.ts +4 -9
  25. package/src/cli/agent-knowledge-command.ts +6 -11
  26. package/src/cli/agent-knowledge-format.ts +4 -9
  27. package/src/cli/agent-knowledge-runtime.ts +7 -14
  28. package/src/cli/external-runtime.ts +3 -46
  29. package/src/cli/help.ts +2 -2
  30. package/src/cli/status.ts +6 -7
  31. package/src/input/agent-workspace-categories.ts +23 -23
  32. package/src/input/agent-workspace-channels.ts +3 -3
  33. package/src/input/agent-workspace-operations-command-editors.ts +1 -1
  34. package/src/input/command-registry.ts +1 -1
  35. package/src/input/commands/compat-runtime.ts +1 -1
  36. package/src/input/commands/planning-runtime.ts +1 -1
  37. package/src/input/commands/runtime-services.ts +1 -1
  38. package/src/input/mcp-workspace.ts +1 -1
  39. package/src/input/submission-router.ts +1 -1
  40. package/src/panels/builtin/shared.ts +1 -1
  41. package/src/panels/project-planning-panel.ts +4 -4
  42. package/src/panels/qr-panel.ts +2 -2
  43. package/src/renderer/conversation-overlays.ts +1 -0
  44. package/src/runtime/bootstrap-command-parts.ts +1 -1
  45. package/src/runtime/bootstrap-core.ts +3 -1
  46. package/src/runtime/bootstrap-hook-bridge.ts +1 -1
  47. package/src/runtime/bootstrap-shell.ts +1 -1
  48. package/src/runtime/bootstrap.ts +7 -4
  49. package/src/runtime/context.ts +2 -2
  50. package/src/runtime/index.ts +88 -5
  51. package/src/runtime/store/state.ts +1 -1
  52. package/src/tools/agent-channel-send-tool.ts +1 -1
  53. package/src/tools/agent-harness-channel-metadata.ts +36 -25
  54. package/src/tools/agent-harness-cli-metadata.ts +19 -1
  55. package/src/tools/agent-harness-command-catalog.ts +15 -4
  56. package/src/tools/agent-harness-connected-host-status.ts +7 -6
  57. package/src/tools/agent-harness-delegation-posture.ts +15 -4
  58. package/src/tools/agent-harness-keybinding-metadata.ts +67 -16
  59. package/src/tools/agent-harness-mcp-metadata.ts +11 -3
  60. package/src/tools/agent-harness-media-posture.ts +25 -14
  61. package/src/tools/agent-harness-metadata.ts +140 -37
  62. package/src/tools/agent-harness-mode-catalog.ts +258 -0
  63. package/src/tools/agent-harness-model-routing.ts +18 -3
  64. package/src/tools/agent-harness-model-tool-catalog.ts +85 -7
  65. package/src/tools/agent-harness-notification-metadata.ts +30 -19
  66. package/src/tools/agent-harness-operator-methods.ts +15 -10
  67. package/src/tools/agent-harness-pairing-posture.ts +17 -5
  68. package/src/tools/agent-harness-panel-metadata.ts +10 -4
  69. package/src/tools/agent-harness-provider-account-metadata.ts +46 -35
  70. package/src/tools/agent-harness-release-evidence.ts +31 -3
  71. package/src/tools/agent-harness-release-readiness.ts +30 -0
  72. package/src/tools/agent-harness-security-posture.ts +18 -4
  73. package/src/tools/agent-harness-service-posture.ts +9 -2
  74. package/src/tools/agent-harness-session-metadata.ts +24 -8
  75. package/src/tools/agent-harness-setup-posture.ts +32 -21
  76. package/src/tools/agent-harness-text.ts +6 -0
  77. package/src/tools/agent-harness-tool-schema.ts +1 -1
  78. package/src/tools/agent-harness-tool.ts +38 -36
  79. package/src/tools/agent-harness-ui-surface-metadata.ts +105 -101
  80. package/src/tools/agent-harness-workspace-actions.ts +64 -3
  81. package/src/tools/agent-knowledge-ingest-tool.ts +1 -1
  82. package/src/tools/agent-knowledge-tool.ts +1 -1
  83. package/src/tools/agent-media-generate-tool.ts +2 -2
  84. package/src/tools/agent-notify-tool.ts +1 -1
  85. package/src/tools/agent-reminder-schedule-tool.ts +1 -1
  86. package/src/tools/tool-definition-compaction.ts +76 -0
  87. package/src/version.ts +2 -8
@@ -3,10 +3,10 @@ import type { AgentWorkspaceCategory } from './agent-workspace-types.ts';
3
3
  export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
4
4
  {
5
5
  id: 'home',
6
- group: 'OPERATE',
6
+ group: 'HOME',
7
7
  label: 'Home',
8
8
  summary: 'Main operator workspace for normal assistant work.',
9
- detail: 'Use this as the Agent front door: chat in the main conversation, inspect state, choose model/provider, and open setup without switching modes.',
9
+ detail: 'Use this as the primary Agent workspace: chat in the main conversation, inspect state, choose model/provider, and open setup without switching modes.',
10
10
  actions: [
11
11
  { id: 'chat', label: 'Continue assistant chat', detail: 'Return to the main composer and type a normal message. Agent work stays serial in the main conversation.', kind: 'guidance', safety: 'safe' },
12
12
  { id: 'brief', label: 'Operator briefing', detail: 'Show a concise Agent status and next-actions briefing without mutating the connected host.', command: '/brief', kind: 'command', safety: 'read-only' },
@@ -29,13 +29,13 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
29
29
  { id: 'welcome', label: 'Welcome and setup guide', detail: 'Open the Agent setup guide from the workspace.', command: '/welcome', kind: 'command', safety: 'safe' },
30
30
  { id: 'health', label: 'Review health', detail: 'Show local health and connected-host status without starting or mutating anything.', command: '/health review', kind: 'command', safety: 'read-only' },
31
31
  { id: 'doctor', label: 'Doctor diagnostics', detail: 'Run the same Agent doctor diagnostics from the TUI home workspace instead of relying on the CLI.', command: '/doctor', kind: 'command', safety: 'read-only' },
32
- { id: 'compat', label: 'Host compatibility', detail: 'Inspect Agent SDK pin, connected-host version, and isolated Agent Knowledge route readiness from the TUI.', command: '/compat', kind: 'command', safety: 'read-only' },
32
+ { id: 'compat', label: 'Host compatibility', detail: 'Inspect connected-host compatibility and isolated Agent Knowledge route readiness from the TUI.', command: '/compat', kind: 'command', safety: 'read-only' },
33
33
  { id: 'quit', label: 'Quit Agent', detail: 'Exit the TUI and restore terminal state.', command: '/quit', kind: 'command', safety: 'safe' },
34
34
  ],
35
35
  },
36
36
  {
37
37
  id: 'setup',
38
- group: 'SETUP',
38
+ group: 'CONFIGURE',
39
39
  label: 'Setup',
40
40
  summary: 'Configuration, auth, provider, and onboarding workspaces.',
41
41
  detail: 'Use this to configure the assistant: provider/model, setup checklist, Agent Knowledge, local behavior, channels, and voice/media. Changes here stay Agent-owned.',
@@ -53,7 +53,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
53
53
  { id: 'setup-mode-show', label: 'Interaction mode', detail: 'Review current Agent interaction mode and domain verbosity.', command: '/mode show', kind: 'command', safety: 'read-only' },
54
54
  { id: 'setup-mode-preset', label: 'Set interaction mode', detail: 'Open a confirmed form for quiet, balanced, or operator interaction mode.', editorKind: 'mode-preset', kind: 'editor', safety: 'safe' },
55
55
  { id: 'setup-mode-domain', label: 'Set domain verbosity', detail: 'Open a confirmed form for one interaction-domain verbosity override.', editorKind: 'mode-domain', kind: 'editor', safety: 'safe' },
56
- { id: 'setup-compat', label: 'Compatibility', detail: 'Inspect Agent SDK pin, connected host version, and isolated Agent Knowledge route readiness.', command: '/compat', kind: 'command', safety: 'read-only' },
56
+ { id: 'setup-compat', label: 'Compatibility', detail: 'Inspect connected-host compatibility and isolated Agent Knowledge route readiness.', command: '/compat', kind: 'command', safety: 'read-only' },
57
57
  { id: 'setup-agent-knowledge', label: 'Agent Knowledge', detail: 'Open isolated Agent Knowledge status, ask/search, ingest, source review, and reindex actions.', targetCategoryId: 'knowledge', kind: 'workspace', safety: 'safe' },
58
58
  { id: 'setup-runtime-profiles', label: 'Agent profiles', detail: 'Open starter templates, isolated Agent homes, profile defaults, and profile import/export actions.', targetCategoryId: 'profiles', kind: 'workspace', safety: 'safe' },
59
59
  { id: 'setup-profile-from-discovered', label: 'Profile from discovered behavior', detail: 'Create an isolated Agent profile directly from reviewed local persona, skill, and routine files.', editorKind: 'profile-from-discovered', kind: 'editor', safety: 'safe' },
@@ -94,7 +94,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
94
94
  },
95
95
  {
96
96
  id: 'research',
97
- group: 'OPERATE',
97
+ group: 'RESEARCH',
98
98
  label: 'Research',
99
99
  summary: 'Read-only web research and source triage in the main conversation.',
100
100
  detail: 'Use this workspace to ask Agent to search, inspect URLs, compare sources, and decide what belongs in isolated Agent Knowledge. Research requests run in the normal conversation; source ingestion is explicit.',
@@ -113,7 +113,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
113
113
  },
114
114
  {
115
115
  id: 'artifacts',
116
- group: 'OPERATE',
116
+ group: 'ARTIFACTS',
117
117
  label: 'Artifacts',
118
118
  summary: 'Files, attachments, exports, source ingest, and generated media.',
119
119
  detail: 'Use this workspace to handle concrete user-visible artifacts: attach images, export conversations, ingest source files into Agent Knowledge, inspect source libraries, and generate media with explicit confirmation.',
@@ -136,7 +136,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
136
136
  },
137
137
  {
138
138
  id: 'conversation',
139
- group: 'OPERATE',
139
+ group: 'CONVERSATION',
140
140
  label: 'Conversation',
141
141
  summary: 'Transcript, prompt, context, and session controls.',
142
142
  detail: 'Use this workspace for the main TUI conversation: context review, compaction, prompt helpers, transcript navigation, session continuity, title, export, undo, redo, and retry.',
@@ -181,7 +181,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
181
181
  },
182
182
  {
183
183
  id: 'channels',
184
- group: 'SETUP',
184
+ group: 'CHANNELS',
185
185
  label: 'Channels',
186
186
  summary: 'Companion pairing, channel posture, and delivery safety.',
187
187
  detail: 'Agent uses connected channel accounts. Pairing, account inspection, and readiness checks are visible here; inbound delivery and public channel exposure stay policy-gated.',
@@ -209,7 +209,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
209
209
  },
210
210
  {
211
211
  id: 'tools',
212
- group: 'SETUP',
212
+ group: 'TOOLS',
213
213
  label: 'Tools & MCP',
214
214
  summary: 'MCP server setup, trust review, and tool inventory.',
215
215
  detail: 'Configure and inspect task tools from the Agent TUI. Adding or changing tools requires typed confirmation; normal chat still chooses tools serially in the main conversation.',
@@ -240,7 +240,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
240
240
  },
241
241
  {
242
242
  id: 'knowledge',
243
- group: 'KNOW',
243
+ group: 'KNOWLEDGE',
244
244
  label: 'Knowledge',
245
245
  summary: 'Agent Knowledge and source-backed lookup.',
246
246
  detail: 'Agent knowledge calls use the isolated Agent Knowledge route family only. Default knowledge and non-Agent knowledge segments are not the Agent knowledge environment.',
@@ -276,7 +276,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
276
276
  },
277
277
  {
278
278
  id: 'voice-media',
279
- group: 'SETUP',
279
+ group: 'VOICE & MEDIA',
280
280
  label: 'Voice & Media',
281
281
  summary: 'Voice, TTS, image input, browser tools, and media providers.',
282
282
  detail: 'Voice, media, browser tools, and image-capable flows are first-class Agent tools. Connected-host administration stays outside Agent and side effects stay explicit.',
@@ -302,7 +302,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
302
302
  },
303
303
  {
304
304
  id: 'profiles',
305
- group: 'SETUP',
305
+ group: 'PROFILES',
306
306
  label: 'Profiles',
307
307
  summary: 'Isolated Agent homes, starter templates, and setup bundles.',
308
308
  detail: 'Agent profiles isolate Agent state. Named homes and starter templates let one install behave like separate assistants for household, research, travel, operations, or personal workflows.',
@@ -325,7 +325,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
325
325
  },
326
326
  {
327
327
  id: 'memory',
328
- group: 'LEARN',
328
+ group: 'MEMORY',
329
329
  label: 'Memory & Skills',
330
330
  summary: 'Local assistant memory, notes, routines, skills, and reusable behavior.',
331
331
  detail: 'Memory, notes, routines, skills, and personas stay Agent-local until stable shared registry contracts exist. Secrets must not be stored as memory or notes.',
@@ -362,7 +362,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
362
362
  },
363
363
  {
364
364
  id: 'notes',
365
- group: 'LEARN',
365
+ group: 'NOTES',
366
366
  label: 'Notes',
367
367
  summary: 'Agent-local scratchpad for source triage and temporary context.',
368
368
  detail: 'Notes are local working context. They are useful for research notes, decisions in progress, and handoff notes, but they are not memory and are not Agent Knowledge.',
@@ -385,7 +385,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
385
385
  },
386
386
  {
387
387
  id: 'personas',
388
- group: 'LEARN',
388
+ group: 'PERSONAS',
389
389
  label: 'Personas',
390
390
  summary: 'Local behavior profiles for the main assistant.',
391
391
  detail: 'Personas shape the serial Agent in the main conversation. They are local behavior profiles, not separate Agent identities.',
@@ -408,7 +408,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
408
408
  },
409
409
  {
410
410
  id: 'skills',
411
- group: 'LEARN',
411
+ group: 'SKILLS',
412
412
  label: 'Skills',
413
413
  summary: 'Reusable local procedures with setup readiness.',
414
414
  detail: 'Skills are local, reviewable procedures with optional env/command requirements. Enabled skills inform the main conversation; secret-looking content is rejected.',
@@ -443,7 +443,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
443
443
  },
444
444
  {
445
445
  id: 'routines',
446
- group: 'LEARN',
446
+ group: 'ROUTINES',
447
447
  label: 'Routines',
448
448
  summary: 'Repeatable workflows with setup readiness.',
449
449
  detail: 'Routines run in the main conversation by default and can declare env/command requirements. Promotion to a connected schedule requires a real schedule command and --yes.',
@@ -473,7 +473,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
473
473
  },
474
474
  {
475
475
  id: 'work',
476
- group: 'TRACK',
476
+ group: 'WORK',
477
477
  label: 'Work & Approvals',
478
478
  summary: 'Visible task state, work plan, and approval posture.',
479
479
  detail: 'Use this workspace to inspect active operator state and update visible work-plan items from confirmed TUI forms.',
@@ -527,9 +527,9 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
527
527
  },
528
528
  {
529
529
  id: 'host',
530
- group: 'WATCH',
530
+ group: 'HOST',
531
531
  label: 'Connected Host',
532
- summary: 'Connected-host health, tasks, sessions, channels, automation, and control-plane posture.',
532
+ summary: 'Connected-host health, tasks, sessions, channels, and automation.',
533
533
  detail: 'Use this workspace to inspect the GoodVibes host surfaces that Agent can see: system health, remote routes, host tasks, sessions, channels, schedules, knowledge, media, MCP, provider auth, support bundles, and telemetry/config posture.',
534
534
  actions: [
535
535
  { id: 'host-overview', label: 'Host overview', detail: 'Review connected-host, provider, settings, continuity, and Agent health without starting or mutating host work.', command: '/health review', kind: 'command', safety: 'read-only' },
@@ -571,7 +571,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
571
571
  },
572
572
  {
573
573
  id: 'automation',
574
- group: 'WATCH',
574
+ group: 'AUTOMATION',
575
575
  label: 'Automation',
576
576
  summary: 'Reminders, schedule observability, and explicit routine promotion.',
577
577
  detail: 'Agent does not create hidden local automation jobs. Confirmed reminders, reviewed routine promotion, and explicit run/pause/resume controls go through the connected host with confirmation.',
@@ -598,7 +598,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
598
598
  },
599
599
  {
600
600
  id: 'delegate',
601
- group: 'BUILD',
601
+ group: 'DELEGATE',
602
602
  label: 'Build Delegation',
603
603
  summary: 'Explicit handoff to GoodVibes TUI for code work.',
604
604
  detail: 'Agent does not become the coding TUI. Build, implement, fix, patch, and review work must be handed to GoodVibes TUI with the full original ask and delegated review only when explicitly requested.',
@@ -88,7 +88,7 @@ const AGENT_WORKSPACE_CHANNEL_SPECS: readonly AgentWorkspaceChannelSpec[] = [
88
88
  requiredKeys: ['surfaces.signal.bridgeUrl', 'surfaces.signal.account'],
89
89
  defaultTargetKeys: ['surfaces.signal.defaultRecipient'],
90
90
  risk: 'bridge',
91
- riskLabel: 'private bridge delivery',
91
+ riskLabel: 'private routed delivery',
92
92
  },
93
93
  {
94
94
  id: 'whatsapp',
@@ -119,7 +119,7 @@ const AGENT_WORKSPACE_CHANNEL_SPECS: readonly AgentWorkspaceChannelSpec[] = [
119
119
  requiredKeys: ['surfaces.imessage.bridgeUrl', 'surfaces.imessage.account'],
120
120
  defaultTargetKeys: ['surfaces.imessage.defaultChatId'],
121
121
  risk: 'bridge',
122
- riskLabel: 'Apple bridge delivery',
122
+ riskLabel: 'Apple routed delivery',
123
123
  },
124
124
  {
125
125
  id: 'bluebubbles',
@@ -128,7 +128,7 @@ const AGENT_WORKSPACE_CHANNEL_SPECS: readonly AgentWorkspaceChannelSpec[] = [
128
128
  requiredKeys: ['surfaces.bluebubbles.serverUrl', 'surfaces.bluebubbles.password'],
129
129
  defaultTargetKeys: ['surfaces.bluebubbles.defaultChatGuid'],
130
130
  risk: 'bridge',
131
- riskLabel: 'iMessage bridge delivery',
131
+ riskLabel: 'iMessage routed delivery',
132
132
  },
133
133
  {
134
134
  id: 'msteams',
@@ -149,7 +149,7 @@ export function createAgentWorkspaceOperationsCommandEditor(kind: AgentWorkspace
149
149
  mode: 'update',
150
150
  title: 'Override Planning Strategy',
151
151
  selectedFieldIndex: 0,
152
- message: 'Override the planner strategy through the runtime bridge. This changes planner state and requires typed confirmation.',
152
+ message: 'Override the planner strategy through the runtime route. This changes planner state and requires typed confirmation.',
153
153
  fields: [
154
154
  { id: 'strategy', label: 'Strategy', value: 'serial', required: true, multiline: false, hint: 'Planner strategy, such as serial.' },
155
155
  { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /plan override with --yes.' },
@@ -153,7 +153,7 @@ export interface CommandProviderServices {
153
153
  }
154
154
 
155
155
  /**
156
- * Compose locally-owned command helpers with the narrower shell bridge-owned
156
+ * Compose locally-owned command helpers with the narrower runtime-owned
157
157
  * runtime surfaces exported from runtime/shell-command-services.ts.
158
158
  */
159
159
  export interface CommandWorkspaceUiServices {
@@ -8,7 +8,7 @@ export function registerCompatRuntimeCommands(registry: CommandRegistry): void {
8
8
  registry.register({
9
9
  name: 'compat',
10
10
  aliases: ['compatibility'],
11
- description: 'Inspect Agent SDK pin, connected host version, and Agent Knowledge route readiness',
11
+ description: 'Inspect connected-host compatibility and Agent Knowledge route readiness',
12
12
  usage: '[--json]',
13
13
  argsHint: '[--json]',
14
14
  async handler(args, ctx) {
@@ -67,7 +67,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
67
67
  }
68
68
  const result = ctx.ops.planRuntime
69
69
  ? ctx.ops.planRuntime(parsed.rest[0] ?? args[0], parsed.rest.slice(1))
70
- : { ok: false, output: 'Plan runtime bridge is not available in this runtime.' };
70
+ : { ok: false, output: 'Plan runtime route is not available in this runtime.' };
71
71
  ctx.print(result.output);
72
72
  return;
73
73
  }
@@ -31,7 +31,7 @@ import type {
31
31
 
32
32
  function requireContextValue<T>(value: T | null | undefined, name: string): T {
33
33
  if (value == null) {
34
- throw new Error(`commandContext.${name} is unavailable in this Agent runtime`);
34
+ throw new Error(`Required Agent runtime service "${name}" is unavailable in this runtime`);
35
35
  }
36
36
  return value;
37
37
  }
@@ -266,7 +266,7 @@ export class McpWorkspace {
266
266
  { type: 'action', id: 'add', label: 'Add or update server', detail: `Open a confirmed Agent workspace form to save an MCP server in ${this.form.scope} scope.` },
267
267
  { type: 'action', id: 'reload', label: 'Reload runtime', detail: 'Confirm an MCP runtime reload from this workspace after external config edits.' },
268
268
  { type: 'action', id: 'refresh-tools', label: 'Refresh tools', detail: 'Fetch the currently available MCP tool list from connected servers.' },
269
- { type: 'action', id: 'config', label: 'Config locations', detail: 'Show SDK-scanned config files and writable project/global paths.' },
269
+ { type: 'action', id: 'config', label: 'Config locations', detail: 'Show detected config files and writable project/global paths.' },
270
270
  ];
271
271
  }
272
272
 
@@ -43,7 +43,7 @@ export function routeSubmissionIntent(input: SubmissionRouterInput): SubmissionI
43
43
  return { kind: 'plan', label: 'plan', commandName, hasAttachments };
44
44
  }
45
45
  if (DELEGATION_COMMANDS.has(commandName)) {
46
- return { kind: 'delegation', label: 'TUI delegation', commandName, hasAttachments };
46
+ return { kind: 'delegation', label: 'delegation', commandName, hasAttachments };
47
47
  }
48
48
  if (PANEL_COMMANDS.has(commandName)) {
49
49
  return { kind: 'slash-command', label: 'Agent workspace', commandName, hasAttachments };
@@ -95,7 +95,7 @@ export interface BuiltinPanelDeps {
95
95
  planManager?: ExecutionPlanManager;
96
96
  /** Adaptive planner for ops strategy panels. */
97
97
  adaptivePlanner?: AdaptivePlanner;
98
- /** Passive SDK-backed project planning artifact service. */
98
+ /** Passive project planning artifact service. */
99
99
  projectPlanningService?: ProjectPlanningService;
100
100
  /** Stable workspace project id for project:<projectId> planning namespaces. */
101
101
  projectPlanningProjectId?: string;
@@ -192,7 +192,7 @@ export class ProjectPlanningPanel extends BasePanel {
192
192
  lines: buildEmptyState(
193
193
  width,
194
194
  'No project planning state has been saved for this workspace.',
195
- 'Describe the intended operator outcome in normal chat to let the Agent start the planning interview. The SDK stores and evaluates artifacts; it does not start execution.',
195
+ 'Describe the intended operator outcome in normal chat to let the Agent start the planning interview. The planning artifact service stores and evaluates artifacts; it does not start execution.',
196
196
  [],
197
197
  C,
198
198
  ),
@@ -234,7 +234,7 @@ export class ProjectPlanningPanel extends BasePanel {
234
234
 
235
235
  return buildPanelWorkspace(width, height, {
236
236
  title: this.loading ? 'Project Planning - loading' : 'Project Planning',
237
- intro: 'SDK-backed planning artifacts for the current Agent workspace. Conversation control stays in the main Agent turn.',
237
+ intro: 'Planning artifacts for the current Agent workspace. Conversation control stays in the main Agent turn.',
238
238
  sections: [{ ...scroll.section, lines: sectionLines }],
239
239
  footerLines: this.footerLines(width, footerSummary),
240
240
  palette: C,
@@ -557,8 +557,8 @@ export class ProjectPlanningPanel extends BasePanel {
557
557
  actions.push({
558
558
  id: 'scope-agent-first',
559
559
  label: 'Agent-first scope',
560
- detail: 'Fix Agent behavior here; report SDK blockers instead of patching around SDK-owned bugs.',
561
- answer: 'Scope is Agent-owned behavior first. If a blocker is SDK-owned, report the exact SDK contract/runtime issue instead of patching around it locally. Include runtime contracts only where Agent consumes public runtime routes.',
560
+ detail: 'Fix Agent behavior here; report public-runtime blockers instead of patching around external runtime bugs.',
561
+ answer: 'Scope is Agent-owned behavior first. If a blocker belongs to the public runtime, report the exact contract/runtime issue instead of patching around it locally. Include runtime contracts only where Agent consumes public runtime routes.',
562
562
  });
563
563
  }
564
564
  actions.push({
@@ -31,7 +31,7 @@ export interface QrPanelConnectionInfo {
31
31
  readonly username: string;
32
32
  /** Bootstrap password for companion authentication */
33
33
  readonly password?: string;
34
- /** SDK/surface version (defaults to '0.0.0' if omitted) */
34
+ /** Pairing payload version (defaults to '0.0.0' if omitted) */
35
35
  readonly version?: string;
36
36
  /** Surface identifier (defaults to GoodVibes Agent if omitted) */
37
37
  readonly surface?: string;
@@ -54,7 +54,7 @@ export type CopyToClipboardFn = (text: string) => void;
54
54
  * Shows connection URL, truncated token, and username above the QR code.
55
55
  * Supports `r` to regenerate the token and `c` to copy the token.
56
56
  *
57
- * QR matrix generation uses the SDK's `generateQrMatrix` via `encodeConnectionPayload`.
57
+ * QR matrix generation uses `generateQrMatrix` via `encodeConnectionPayload`.
58
58
  */
59
59
  export class QrPanel extends BasePanel {
60
60
  private connectionInfo: QrPanelConnectionInfo;
@@ -43,6 +43,7 @@ export function applyConversationOverlays(
43
43
  if (input.onboardingWizard.active) {
44
44
  const lines = renderOnboardingWizard(input.onboardingWizard, conversationWidth, viewportHeight);
45
45
  next = replaceViewportWithOverlay(lines, conversationWidth, viewportHeight);
46
+ if (!input.modelPicker.active) return next;
46
47
  }
47
48
 
48
49
  if (input.filePicker.active) {
@@ -133,7 +133,7 @@ export interface BootstrapCommandSectionOptions {
133
133
  }
134
134
 
135
135
  function unwiredShellAction(name: string): never {
136
- throw new Error(`commandContext.${name} was called before the shell bridge was attached in main.ts`);
136
+ throw new Error(`Agent runtime action "${name}" was called before the operator route was attached.`);
137
137
  }
138
138
 
139
139
  export function createBootstrapCommandActions(
@@ -39,6 +39,7 @@ import { registerAgentOperatorActionTool } from '../tools/agent-operator-action-
39
39
  import { registerAgentOperatorBriefingTool } from '../tools/agent-operator-briefing-tool.ts';
40
40
  import { registerAgentReminderScheduleTool } from '../tools/agent-reminder-schedule-tool.ts';
41
41
  import { registerAgentWorkPlanTool } from '../tools/agent-work-plan-tool.ts';
42
+ import { compactRegisteredToolDefinitions } from '../tools/tool-definition-compaction.ts';
42
43
  import { GOODVIBES_AGENT_SURFACE_ROOT } from '../config/surface.ts';
43
44
  import { registerAgentRuntimeEvents } from './agent-runtime-events.ts';
44
45
 
@@ -148,7 +149,7 @@ export async function initializeBootstrapCore(
148
149
  metadata: {
149
150
  product: 'goodvibes-agent',
150
151
  surfaceRoot: GOODVIBES_AGENT_SURFACE_ROOT,
151
- clientKindNote: 'SDK compatibility client kind; GoodVibes Agent remains an interactive operator TUI.',
152
+ clientKindNote: 'Connected-host client kind; GoodVibes Agent remains an interactive operator TUI.',
152
153
  },
153
154
  }, 'bootstrap.control-plane');
154
155
 
@@ -249,6 +250,7 @@ export async function initializeBootstrapCore(
249
250
  installAgentToolPolicyGuard(toolRegistry, {
250
251
  getLastUserMessage: () => conversation.getLastUserMessage(),
251
252
  });
253
+ compactRegisteredToolDefinitions(toolRegistry);
252
254
  services.agentOrchestrator.setDependencies({
253
255
  surfaceRoot: GOODVIBES_AGENT_SURFACE_ROOT,
254
256
  fileCache,
@@ -85,7 +85,7 @@ export function createResumeSessionHandler(options: ResumeSessionOptions): (sess
85
85
  sessionId: options.runtime.sessionId,
86
86
  timestamp: Date.now(),
87
87
  payload: { sessionId },
88
- }).catch((err: unknown) => logger.debug('Hook bridge fire error', {
88
+ }).catch((err: unknown) => logger.debug('Hook route fire error', {
89
89
  path: 'Lifecycle:session:load',
90
90
  error: summarizeError(err),
91
91
  }));
@@ -92,7 +92,7 @@ export function submitPlanningAnswerWithShellFallback(
92
92
  }
93
93
 
94
94
  options.addSystemMessage([
95
- '[Planning] Could not submit the selected answer because the prompt bridge is not ready.',
95
+ '[Planning] Could not submit the selected answer because the prompt route is not ready.',
96
96
  `Paste this answer into the prompt to continue planning: ${answer}`,
97
97
  ].join('\n'));
98
98
  options.requestRender();
@@ -43,12 +43,14 @@ import { buildEnabledSkillsPrompt } from '../agent/skill-registry.ts';
43
43
  import { buildEnabledRoutinesPrompt } from '../agent/routine-registry.ts';
44
44
  import { buildReviewedMemoryPrompt } from '../agent/memory-prompt.ts';
45
45
  import { registerAgentHarnessTool } from '../tools/agent-harness-tool.ts';
46
+ import { compactRegisteredToolDefinitions } from '../tools/tool-definition-compaction.ts';
46
47
 
47
48
  const GOODVIBES_AGENT_OPERATOR_POLICY = [
48
49
  '## GoodVibes Agent Operator Policy',
49
50
  '- Work serially in the main conversation by default: answer, inspect, summarize, remember useful non-secret facts, configure Agent-local state, and use safe read-only connected-host/operator routes.',
50
51
  '- Connected-host lifecycle is external. Do not start, stop, restart, install, expose, or mutate host listeners/network posture from Agent.',
51
52
  '- Read tools: `agent_operator_briefing` for connected work/approvals/automation/schedules, `agent_knowledge` for isolated Agent Knowledge, `agent_harness` for harness catalogs/settings/status.',
53
+ '- Harness access: use `agent_harness` modes `commands`/`run_command`, `workspace_actions`/`run_workspace_action`, and `settings`/`set_setting`/`reset_setting` to use the same surfaces the user can use.',
52
54
  '- State tools: `agent_work_plan` for visible local work items; `agent_local_registry` for Agent-local notes, memory, personas, skills, bundles, and routines. Keep records non-secret, sourced, and reviewable.',
53
55
  '- Confirmed tools: use `agent_operator_action`, `agent_knowledge_ingest`, `agent_media_generate`, `agent_notify`, `agent_channel_send`, and `agent_reminder_schedule` only for explicit user requests with confirm:true and explicitUserRequest.',
54
56
  '- Agent Knowledge must use only `/api/goodvibes-agent/knowledge/*` and fail closed. Do not use default knowledge or non-Agent knowledge spaces.',
@@ -88,9 +90,9 @@ export type BootstrapContext = RuntimeContext & {
88
90
  agentStatusIntervalRef: { value: ReturnType<typeof setInterval> | null };
89
91
  /** Mutable refs for viewport/scroll/render functions; main.ts patches these after constructing UI state. */
90
92
  orchestratorRefs: { getViewportHeight: () => number; scrollToEnd: (vHeight: number) => void; requestRender: () => void };
91
- /** Patch the bootstrap-owned render bridge after main.ts constructs the real render loop. */
93
+ /** Patch the bootstrap-owned render route after main.ts constructs the real render loop. */
92
94
  setRenderRequest: (fn: () => void) => void;
93
- /** Shell-owned permission prompt bridge that main.ts patches after UI setup. */
95
+ /** Shell-owned permission prompt route that main.ts patches after UI setup. */
94
96
  permissionPromptRef: { requestPermission: PermissionRequestHandler };
95
97
  /** Load the most recently saved conversation from disk. */
96
98
  loadLastConversation: () => { messages: Array<Record<string, unknown>> } | null;
@@ -129,7 +131,7 @@ export type BootstrapContext = RuntimeContext & {
129
131
  * 1. Config, caches, keybindings
130
132
  * 2. Runtime event bus, conversation, compositor, selection
131
133
  * 3. Tool registry + agent wiring
132
- * 4. Runtime bus subscriptions (delegation, subagent, hook bridge)
134
+ * 4. Runtime bus subscriptions (delegation, subagent, hook route)
133
135
  * 5. Providers, webhooks, PermissionManager, HookDispatcher
134
136
  * 6. Orchestrator and Agent-local task read models
135
137
  * 7. MCP auto-connect + workspace/panel manager
@@ -280,6 +282,7 @@ export async function bootstrapRuntime(
280
282
  const commandContext = shell.commandContext;
281
283
  const inputHistory = shell.inputHistory;
282
284
  registerAgentHarnessTool(toolRegistry, commandRegistry, commandContext);
285
+ compactRegisteredToolDefinitions(toolRegistry);
283
286
  const pluginCommandRegistry = {
284
287
  register(command: {
285
288
  readonly name: string;
@@ -545,7 +548,7 @@ export async function bootstrapRuntime(
545
548
  },
546
549
  };
547
550
 
548
- // Wire exit from options if provided; otherwise main.ts binds the shell bridge.
551
+ // Wire exit from options if provided; otherwise main.ts binds the operator route.
549
552
  if (options?.exit) {
550
553
  ctx.commandContext.exit = options.exit;
551
554
  }
@@ -35,8 +35,8 @@ export interface BootstrapOptions {
35
35
  configManager: import('@pellux/goodvibes-sdk/platform/config').ConfigManager;
36
36
  /**
37
37
  * Callback invoked when the app should exit.
38
- * If provided, commandContext.exit is wired during bootstrap.
39
- * Otherwise main.ts binds the shell-owned exit bridge immediately after bootstrap returns.
38
+ * If provided, the exit route is wired during bootstrap.
39
+ * Otherwise main.ts binds the app-owned exit route immediately after bootstrap returns.
40
40
  */
41
41
  exit?: () => void;
42
42
  }
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Runtime module barrel for GoodVibes Agent.
3
3
  *
4
- * SDK 0.33 intentionally removed private deep imports and the runtime root
5
- * god-barrel. This file keeps the Agent app on public SDK seams
4
+ * The shared runtime removed private deep imports and the runtime root
5
+ * god-barrel. This file keeps the Agent app on public runtime exports
6
6
  * while preserving the local import surface used by the shell.
7
7
  */
8
8
 
@@ -50,7 +50,7 @@ export function createFeatureFlagManager(): FeatureFlagManager {
50
50
  return manager;
51
51
  }
52
52
 
53
- // Public SDK runtime seams.
53
+ // Public runtime exports.
54
54
  export * from '@pellux/goodvibes-sdk/platform/runtime/state';
55
55
  export * from '@pellux/goodvibes-sdk/platform/runtime/store';
56
56
  export * from '@pellux/goodvibes-sdk/platform/runtime/ui';
@@ -491,8 +491,6 @@ export const canonicalize = security.canonicalize;
491
491
  export const classifyCommand = security.classifyCommand;
492
492
  export const classifySegment = security.classifySegment;
493
493
  export const collectCommandNodes = security.collectCommandNodes;
494
- export const evaluateCommandAST = security.evaluateCommandAST;
495
- export const evaluateSegmentNode = security.evaluateSegmentNode;
496
494
  export const higherPriority = security.higherPriority;
497
495
  export const parseAST = security.parseAST;
498
496
  export const parseCommandAST = security.parseCommandAST;
@@ -505,6 +503,91 @@ export const verifyBundle = security.verifyBundle;
505
503
  export const MAX_INPUT_LENGTH = security.MAX_INPUT_LENGTH;
506
504
  export const MAX_TOKEN_COUNT = security.MAX_TOKEN_COUNT;
507
505
 
506
+ type RuntimeSegmentVerdict = ReturnType<typeof security.evaluateSegmentNode>;
507
+ type RuntimeCompoundVerdict = ReturnType<typeof security.evaluateCommandAST>;
508
+ type RuntimeShellNode = Parameters<typeof security.evaluateCommandAST>[1];
509
+
510
+ const AGENT_OBFUSCATION_CHECKS: Array<{ description: string; test: (raw: string) => boolean }> = [
511
+ {
512
+ description: 'base64-encoded argument (possible command injection)',
513
+ test: (raw) =>
514
+ extractInspectableShellWords(raw).some((word) =>
515
+ /^[A-Za-z0-9+/]+={0,2}$/.test(word) && word.length >= 12 && word.length % 4 === 0,
516
+ ),
517
+ },
518
+ {
519
+ description: 'URL-encoded content in argument',
520
+ test: (raw) => /%[0-9a-fA-F]{2}/.test(raw),
521
+ },
522
+ ];
523
+
524
+ function extractInspectableShellWords(raw: string): string[] {
525
+ return (raw.match(/"[^"]*"|'[^']*'|`[^`]*`|\S+/g) ?? []).map((word) =>
526
+ word.replace(/^["'`]+|["'`;|&]+$/g, ''),
527
+ );
528
+ }
529
+
530
+ function agentObfuscationPatterns(raw: string, existing: readonly string[]): string[] {
531
+ const patterns = new Set(existing);
532
+ for (const check of AGENT_OBFUSCATION_CHECKS) {
533
+ if (check.test(raw)) {
534
+ patterns.add(check.description);
535
+ }
536
+ }
537
+ return [...patterns];
538
+ }
539
+
540
+ function enforceAgentObfuscationVerdict(verdict: RuntimeSegmentVerdict): RuntimeSegmentVerdict {
541
+ const obfuscationPatterns = agentObfuscationPatterns(verdict.raw, verdict.obfuscationPatterns);
542
+ if (obfuscationPatterns.length === verdict.obfuscationPatterns.length) {
543
+ return verdict;
544
+ }
545
+
546
+ return {
547
+ ...verdict,
548
+ allowed: false,
549
+ reason: `obfuscation detected: ${obfuscationPatterns.join('; ')}`,
550
+ hasObfuscation: true,
551
+ obfuscationPatterns,
552
+ };
553
+ }
554
+
555
+ export function evaluateSegmentNode(
556
+ node: Security.CommandNode,
557
+ allowedClasses?: ReadonlySet<Security.CommandClassification>,
558
+ ): RuntimeSegmentVerdict {
559
+ const verdict = allowedClasses === undefined
560
+ ? security.evaluateSegmentNode(node)
561
+ : security.evaluateSegmentNode(node, allowedClasses);
562
+ return enforceAgentObfuscationVerdict(verdict);
563
+ }
564
+
565
+ export function evaluateCommandAST(
566
+ original: string,
567
+ ast: RuntimeShellNode,
568
+ allowedClasses?: ReadonlySet<Security.CommandClassification>,
569
+ ): RuntimeCompoundVerdict {
570
+ const compound = allowedClasses === undefined
571
+ ? security.evaluateCommandAST(original, ast)
572
+ : security.evaluateCommandAST(original, ast, allowedClasses);
573
+ const segments = compound.segments.map(enforceAgentObfuscationVerdict);
574
+ const allowed = segments.every((segment) => segment.allowed);
575
+ const hasObfuscation = segments.some((segment) => segment.hasObfuscation);
576
+
577
+ const next: RuntimeCompoundVerdict = {
578
+ ...compound,
579
+ allowed,
580
+ segments,
581
+ hasObfuscation,
582
+ };
583
+ if (allowed) {
584
+ delete next.denialExplanation;
585
+ } else {
586
+ next.denialExplanation = security.buildDenialExplanation(original, segments);
587
+ }
588
+ return next;
589
+ }
590
+
508
591
  export type AuthInspectionSnapshot = Security.AuthInspectionSnapshot;
509
592
  export type ProviderAuthInspection = Security.ProviderAuthInspection;
510
593
  export type DivergenceDashboardSnapshot = Security.DivergenceDashboardSnapshot;
@@ -34,7 +34,7 @@ import type { DiscoveryDomainState } from '@/runtime/index.ts';
34
34
  import type { IntelligenceDomainState } from '@/runtime/index.ts';
35
35
  import type { UiPerfDomainState } from './domains/ui-perf.ts';
36
36
  // UiPerfDomainState is structurally identical to SDK's SurfacePerfDomainState.
37
- // Export as SurfacePerfDomainState alias for SDK compatibility.
37
+ // Export as SurfacePerfDomainState alias for shared runtime callers.
38
38
  export type { UiPerfDomainState };
39
39
 
40
40
  import { createInitialSessionState } from '@/runtime/index.ts';
@@ -75,7 +75,7 @@ export function createAgentChannelSendTool(
75
75
  },
76
76
  explicitUserRequest: {
77
77
  type: 'string',
78
- description: 'Short quote or summary of the user request that authorized this delivery.',
78
+ description: 'User request authorizing this delivery.',
79
79
  },
80
80
  },
81
81
  required: ['message', 'confirm', 'explicitUserRequest'],