@pellux/goodvibes-agent 0.1.107 → 0.1.109

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 (83) hide show
  1. package/CHANGELOG.md +42 -13
  2. package/README.md +27 -11
  3. package/docs/README.md +5 -5
  4. package/docs/{runtime-connection.md → connected-services.md} +8 -8
  5. package/docs/getting-started.md +28 -12
  6. package/docs/release-and-publishing.md +4 -4
  7. package/package.json +2 -12
  8. package/src/agent/memory-prompt.ts +35 -0
  9. package/src/agent/reminder-schedule-format.ts +75 -0
  10. package/src/agent/reminder-schedule.ts +494 -0
  11. package/src/agent/routine-schedule-format.ts +7 -7
  12. package/src/agent/routine-schedule-promotion.ts +1 -1
  13. package/src/agent/routine-schedule-receipts.ts +1 -1
  14. package/src/agent/skill-discovery.ts +2 -0
  15. package/src/cli/agent-knowledge-args.ts +93 -0
  16. package/src/cli/agent-knowledge-command.ts +200 -369
  17. package/src/cli/agent-knowledge-format.ts +58 -7
  18. package/src/cli/agent-knowledge-methods.ts +84 -0
  19. package/src/cli/agent-knowledge-runtime.ts +240 -0
  20. package/src/cli/completion.ts +0 -2
  21. package/src/cli/config-overrides.ts +2 -2
  22. package/src/cli/help.ts +34 -15
  23. package/src/cli/management-commands.ts +2 -2
  24. package/src/cli/management.ts +8 -8
  25. package/src/cli/package-verification.ts +7 -3
  26. package/src/cli/parser.ts +10 -4
  27. package/src/cli/service-posture.ts +6 -6
  28. package/src/cli/status.ts +32 -32
  29. package/src/input/agent-workspace-activation.ts +24 -13
  30. package/src/input/agent-workspace-basic-command-editors.ts +448 -0
  31. package/src/input/agent-workspace-categories.ts +42 -34
  32. package/src/input/agent-workspace-channels.ts +3 -3
  33. package/src/input/agent-workspace-command-editor.ts +65 -0
  34. package/src/input/agent-workspace-editors.ts +17 -2
  35. package/src/input/agent-workspace-knowledge-query-editor.ts +74 -0
  36. package/src/input/agent-workspace-knowledge-url-editor.ts +95 -0
  37. package/src/input/agent-workspace-reminder-schedule-editor.ts +125 -0
  38. package/src/input/agent-workspace-routine-schedule-editor.ts +127 -0
  39. package/src/input/agent-workspace-setup.ts +2 -2
  40. package/src/input/agent-workspace-snapshot.ts +5 -2
  41. package/src/input/agent-workspace-types.ts +21 -2
  42. package/src/input/agent-workspace-voice-media.ts +5 -5
  43. package/src/input/agent-workspace.ts +39 -2
  44. package/src/input/commands/agent-runtime-profile-runtime.ts +1 -1
  45. package/src/input/commands/agent-skills-runtime.ts +94 -2
  46. package/src/input/commands/brief-runtime.ts +126 -0
  47. package/src/input/commands/channels-runtime.ts +47 -0
  48. package/src/input/commands/health-runtime.ts +10 -10
  49. package/src/input/commands/knowledge.ts +176 -1
  50. package/src/input/commands/planning-runtime.ts +1 -1
  51. package/src/input/commands/platform-access-runtime.ts +10 -10
  52. package/src/input/commands/policy-dispatch.ts +1 -1
  53. package/src/input/commands/schedule-runtime.ts +42 -5
  54. package/src/input/commands/security-runtime.ts +1 -1
  55. package/src/input/commands/session-content.ts +1 -1
  56. package/src/input/commands/session-workflow.ts +1 -1
  57. package/src/input/commands/shell-core.ts +4 -2
  58. package/src/input/commands/tasks-runtime.ts +3 -3
  59. package/src/input/commands.ts +4 -0
  60. package/src/input/handler-onboarding.ts +4 -4
  61. package/src/input/handler.ts +3 -2
  62. package/src/input/onboarding/onboarding-wizard-helpers.ts +1 -1
  63. package/src/input/onboarding/onboarding-wizard-operator-steps.ts +13 -13
  64. package/src/input/onboarding/onboarding-wizard-steps.ts +8 -8
  65. package/src/input/settings-modal-agent-policy.ts +1 -1
  66. package/src/input/slash-command-parser.ts +60 -0
  67. package/src/panels/builtin/agent.ts +1 -1
  68. package/src/panels/builtin/operations.ts +2 -2
  69. package/src/panels/provider-account-snapshot.ts +1 -1
  70. package/src/panels/provider-health-domains.ts +6 -6
  71. package/src/panels/subscription-panel.ts +1 -1
  72. package/src/panels/tasks-panel.ts +3 -3
  73. package/src/renderer/agent-workspace.ts +44 -31
  74. package/src/renderer/help-overlay.ts +1 -1
  75. package/src/renderer/settings-modal.ts +13 -13
  76. package/src/runtime/bootstrap-core.ts +1 -1
  77. package/src/runtime/bootstrap-hook-bridge.ts +1 -1
  78. package/src/runtime/bootstrap.ts +11 -9
  79. package/src/runtime/index.ts +2 -2
  80. package/src/runtime/onboarding/derivation.ts +6 -6
  81. package/src/shell/service-settings-sync.ts +1 -1
  82. package/src/tools/agent-local-registry-tool.ts +208 -9
  83. package/src/version.ts +1 -1
@@ -8,15 +8,16 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
8
8
  summary: 'Main operator workspace for normal assistant work.',
9
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.',
10
10
  actions: [
11
- { id: 'chat', label: 'Continue assistant chat', detail: 'Close this workspace and type a normal message. Agent work stays serial in the main conversation.', kind: 'guidance', safety: 'safe' },
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
+ { id: 'brief', label: 'Operator briefing', detail: 'Show a concise Agent status and next-actions briefing without mutating connected services.', command: '/brief', kind: 'command', safety: 'read-only' },
12
13
  { id: 'model', label: 'Choose model', detail: 'Open the model/provider workspace for the Agent chat route.', command: '/model', kind: 'command', safety: 'safe' },
13
14
  { id: 'setup-home', label: 'Setup checklist', detail: 'Jump to the first-run checklist for provider, knowledge, personas, skills, routines, memory, channels, and voice/media.', targetCategoryId: 'setup', kind: 'workspace', safety: 'safe' },
14
15
  { id: 'knowledge-home', label: 'Agent Knowledge', detail: 'Jump to isolated Agent Knowledge status, ingest, search, and review flows.', targetCategoryId: 'knowledge', kind: 'workspace', safety: 'read-only' },
15
16
  { id: 'memory-home', label: 'Memory, skills, routines', detail: 'Jump to local memory, persona, skill, and routine setup. These are core Agent product features.', targetCategoryId: 'memory', kind: 'workspace', safety: 'safe' },
16
- { id: 'channels-home', label: 'Channels', detail: 'Jump to companion pairing and channel readiness without changing runtime connectivity.', targetCategoryId: 'channels', kind: 'workspace', safety: 'read-only' },
17
+ { id: 'channels-home', label: 'Channels', detail: 'Jump to companion pairing and channel readiness without changing connected-service routing.', targetCategoryId: 'channels', kind: 'workspace', safety: 'read-only' },
17
18
  { id: 'voice-home', label: 'Voice and media', detail: 'Jump to voice, TTS, image input, browser-tool, and media setup.', targetCategoryId: 'voice-media', kind: 'workspace', safety: 'safe' },
18
19
  { id: 'help', label: 'Browse commands', detail: 'Open registry-driven command help.', command: '/help', kind: 'command', safety: 'safe' },
19
- { id: 'health', label: 'Review health', detail: 'Show local health and runtime connection status without starting or mutating anything.', command: '/health review', kind: 'command', safety: 'read-only' },
20
+ { id: 'health', label: 'Review health', detail: 'Show local health and connected-service status without starting or mutating anything.', command: '/health review', kind: 'command', safety: 'read-only' },
20
21
  ],
21
22
  },
22
23
  {
@@ -24,7 +25,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
24
25
  group: 'SETUP',
25
26
  label: 'Setup',
26
27
  summary: 'Configuration, auth, provider, and onboarding workspaces.',
27
- detail: 'Agent connects to an existing GoodVibes runtime and owns local assistant configuration only. Runtime lifecycle and connectivity posture remain external.',
28
+ detail: 'Use this to configure the assistant: provider/model, setup checklist, Agent Knowledge, local behavior, channels, and voice/media. Changes here stay Agent-owned.',
28
29
  actions: [
29
30
  { id: 'config', label: 'Open settings', detail: 'Open the fullscreen Agent settings workspace.', command: '/config', kind: 'command', safety: 'safe' },
30
31
  { id: 'setup', label: 'Run setup', detail: 'Review Agent settings in the fullscreen setup flow.', command: '/setup', kind: 'command', safety: 'safe' },
@@ -46,12 +47,13 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
46
47
  group: 'SETUP',
47
48
  label: 'Channels',
48
49
  summary: 'Companion pairing, channel posture, and delivery safety.',
49
- detail: 'Agent uses externally managed channels. Pairing, account inspection, and readiness checks are visible here; inbound delivery and public channel exposure stay policy-gated.',
50
+ detail: 'Agent uses connected channel accounts. Pairing, account inspection, and readiness checks are visible here; inbound delivery and public channel exposure stay policy-gated.',
50
51
  actions: [
51
52
  { id: 'pair', label: 'Pair companion', detail: 'Open the QR pairing view for companion app setup.', command: '/pair', kind: 'command', safety: 'safe' },
53
+ { id: 'channel-readiness', label: 'Channel readiness', detail: 'Show a read-only readiness matrix for configured messaging and notification channels.', command: '/channels', kind: 'command', safety: 'read-only' },
52
54
  { id: 'notification-routes', label: 'Notification routes', detail: 'Inspect configured webhook notification URLs without sending a test message.', command: '/notify list', kind: 'command', safety: 'read-only' },
53
- { id: 'setup-review', label: 'Health review', detail: 'Review setup posture without starting inbound endpoints or mutating channel state.', command: '/health review', kind: 'command', safety: 'read-only' },
54
- { id: 'channel-safety', label: 'Delivery safety', detail: 'External messages, channel DMs, and public delivery targets require explicit user action and runtime policy. Agent will not silently send or expose channels from this workspace.', kind: 'guidance', safety: 'blocked' },
55
+ { id: 'setup-review', label: 'Health review', detail: 'Review setup posture without changing inbound delivery or mutating channel state.', command: '/health review', kind: 'command', safety: 'read-only' },
56
+ { id: 'channel-safety', label: 'Delivery safety', detail: 'External messages, channel DMs, and public delivery targets require explicit user action and Agent policy. Agent will not silently send or expose channels from this workspace.', kind: 'guidance', safety: 'blocked' },
55
57
  ],
56
58
  },
57
59
  {
@@ -59,15 +61,18 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
59
61
  group: 'KNOW',
60
62
  label: 'Knowledge',
61
63
  summary: 'Agent Knowledge/Wiki and source-backed lookup.',
62
- detail: 'Agent knowledge calls must use the isolated /api/goodvibes-agent/knowledge routes. Default regular wiki and non-Agent knowledge segments are not the Agent knowledge environment.',
64
+ detail: 'Agent knowledge calls use the isolated Agent Knowledge route family only. Default regular wiki and non-Agent knowledge segments are not the Agent knowledge environment.',
63
65
  actions: [
64
66
  { id: 'knowledge-status', label: 'Knowledge status', detail: 'Inspect Agent knowledge readiness and counts.', command: '/knowledge status', kind: 'command', safety: 'read-only' },
65
- { id: 'knowledge-search', label: 'Search Agent knowledge', detail: 'Search the isolated Agent Knowledge index. Close this workspace and provide an actual query.', command: '/knowledge search <query>', kind: 'command', safety: 'read-only' },
66
- { id: 'knowledge-ingest-url', label: 'Ingest URL', detail: 'Ingest a URL into Agent Knowledge only. Requires an explicit --yes command with a real URL.', command: '/knowledge ingest-url <url> --yes', kind: 'command', safety: 'safe' },
67
- { id: 'knowledge-import-bookmarks', label: 'Import bookmarks', detail: 'Import a browser bookmark export into Agent Knowledge only. Requires an explicit --yes command with a real path.', command: '/knowledge import-bookmarks <path> --yes', kind: 'command', safety: 'safe' },
67
+ { id: 'knowledge-search', label: 'Search Agent knowledge', detail: 'Open an in-workspace search form for the isolated Agent Knowledge index.', editorKind: 'knowledge-search', kind: 'editor', safety: 'read-only' },
68
+ { id: 'knowledge-ingest-url', label: 'Ingest URL', detail: 'Open an in-workspace form that ingests a real URL into Agent Knowledge only after typed confirmation.', editorKind: 'knowledge-url', kind: 'editor', safety: 'safe' },
69
+ { id: 'knowledge-ingest-file', label: 'Ingest file', detail: 'Open an in-workspace form that imports a local file into Agent Knowledge only after typed confirmation.', editorKind: 'knowledge-file', kind: 'editor', safety: 'safe' },
70
+ { id: 'knowledge-import-bookmarks', label: 'Import bookmarks', detail: 'Open an in-workspace form that imports a browser bookmark export into Agent Knowledge after typed confirmation.', editorKind: 'knowledge-bookmarks', kind: 'editor', safety: 'safe' },
71
+ { id: 'knowledge-import-browser-history', label: 'Import browser history', detail: 'Open an in-workspace form that imports local browser history/bookmarks into Agent Knowledge after typed confirmation.', editorKind: 'knowledge-browser-history', kind: 'editor', safety: 'safe' },
72
+ { id: 'knowledge-ingest-connector', label: 'Ingest connector input', detail: 'Open an in-workspace form for explicit connector input after checking connector readiness.', editorKind: 'knowledge-connector-ingest', kind: 'editor', safety: 'safe' },
68
73
  { id: 'knowledge-review-queue', label: 'Review queue', detail: 'Inspect source, item, and issue review work before accepting, rejecting, or resolving anything.', command: '/knowledge queue', kind: 'command', safety: 'read-only' },
69
74
  { id: 'knowledge-sources', label: 'Source library', detail: 'List source-backed records already ingested into the isolated Agent Knowledge segment.', command: '/knowledge list --kind sources', kind: 'command', safety: 'read-only' },
70
- { id: 'knowledge-ask', label: 'Ask Agent knowledge', detail: 'Close this workspace and run /knowledge ask <question> or ask normally in chat.', kind: 'guidance', safety: 'read-only' },
75
+ { id: 'knowledge-ask', label: 'Ask Agent knowledge', detail: 'Open an in-workspace question form for isolated Agent Knowledge. Normal chat still uses the main conversation.', editorKind: 'knowledge-ask', kind: 'editor', safety: 'read-only' },
71
76
  ],
72
77
  },
73
78
  {
@@ -75,13 +80,13 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
75
80
  group: 'SETUP',
76
81
  label: 'Voice & Media',
77
82
  summary: 'Voice, TTS, image input, browser tools, and media providers.',
78
- detail: 'Voice, media, browser tools, and image-capable flows are first-class Agent tools. Runtime ownership stays external and side effects stay explicit.',
83
+ detail: 'Voice, media, browser tools, and image-capable flows are first-class Agent tools. Service management stays outside Agent and side effects stay explicit.',
79
84
  actions: [
80
85
  { id: 'tts-config', label: 'Configure live TTS', detail: 'Open the settings workspace at the TTS group.', command: '/config tts', kind: 'command', safety: 'safe' },
81
86
  { id: 'tts-provider', label: 'Choose TTS provider', detail: 'Open provider/model routing for spoken responses through the settings flow.', command: '/config tts.provider', kind: 'command', safety: 'safe' },
82
- { id: 'tts-speak', label: 'Speak a prompt', detail: 'Submit a normal assistant turn and play the reply through configured live TTS. Close this workspace and provide real prompt text.', command: '/tts <prompt>', kind: 'command', safety: 'safe' },
83
- { id: 'image-attach', label: 'Attach image input', detail: 'Attach an image to the next assistant turn. Close this workspace and provide a real path and prompt.', command: '/image <path> <prompt>', kind: 'command', safety: 'safe' },
84
- { id: 'browser-tools', label: 'Browser tools', detail: 'Inspect browser/tool server readiness without starting inbound endpoints or mutating runtime state.', command: '/mcp servers', kind: 'command', safety: 'read-only' },
87
+ { id: 'tts-speak', label: 'Speak a prompt', detail: 'Open an in-workspace prompt form for spoken assistant replies through configured live TTS.', editorKind: 'tts-prompt', kind: 'editor', safety: 'safe' },
88
+ { id: 'image-attach', label: 'Attach image input', detail: 'Open an in-workspace image form for attaching a real image path and optional prompt.', editorKind: 'image-input', kind: 'editor', safety: 'safe' },
89
+ { id: 'browser-tools', label: 'Browser tools', detail: 'Inspect browser/tool server readiness without starting inbound endpoints or mutating connected-service state.', command: '/mcp servers', kind: 'command', safety: 'read-only' },
85
90
  { id: 'mcp-tools', label: 'MCP tool inventory', detail: 'List available MCP tools, including browser and automation roles, without changing server trust or setup.', command: '/mcp tools', kind: 'command', safety: 'read-only' },
86
91
  ],
87
92
  },
@@ -90,17 +95,17 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
90
95
  group: 'SETUP',
91
96
  label: 'Profiles',
92
97
  summary: 'Isolated Agent homes, config profiles, and setup bundles.',
93
- detail: 'Profiles isolate Agent state. GoodVibes Agent exposes named homes, starter templates, and config profile pickers while keeping the shared runtime external.',
98
+ detail: 'Profiles isolate Agent state. Named homes and starter templates let one install behave like separate assistants for household, research, travel, operations, or personal workflows.',
94
99
  actions: [
95
100
  { id: 'profiles-open', label: 'Open config profiles', detail: 'Open the config profile picker for display/provider/behavior profile files.', command: '/profiles', kind: 'command', safety: 'safe' },
96
101
  { id: 'runtime-profile-guide', label: 'Starter authoring guide', detail: 'Open the Agent-local starter authoring flow inside the Agent TUI.', command: '/agent-profile guide', kind: 'command', safety: 'safe' },
97
102
  { id: 'runtime-profile-templates', label: 'Browse starter templates', detail: 'List built-in and local Agent starter templates with persona, skill, routine, and source details.', command: '/agent-profile templates', kind: 'command', safety: 'read-only' },
98
103
  { id: 'runtime-profile-list', label: 'List Agent profiles', detail: 'List isolated Agent profile homes under this Agent home.', command: '/agent-profile list', kind: 'command', safety: 'read-only' },
99
- { id: 'runtime-profile-template-export', label: 'Export starter template', detail: 'Export a starter template JSON file. Requires a real starter id, path, and explicit --yes.', command: '/agent-profile template export <id> <path> --yes', kind: 'command', safety: 'safe' },
100
- { id: 'runtime-profile-template-import', label: 'Import starter template', detail: 'Import a reviewed starter template JSON file into this Agent home. Requires a real path and explicit --yes.', command: '/agent-profile template import <path> --yes', kind: 'command', safety: 'safe' },
104
+ { id: 'runtime-profile-template-export', label: 'Export starter template', detail: 'Open an in-workspace form that exports a starter template JSON file for review and customization.', editorKind: 'profile-template-export', kind: 'editor', safety: 'safe' },
105
+ { id: 'runtime-profile-template-import', label: 'Import starter template', detail: 'Open an in-workspace form that imports a reviewed starter template JSON file into this Agent home.', editorKind: 'profile-template-import', kind: 'editor', safety: 'safe' },
101
106
  { id: 'runtime-profile-create', label: 'Create Agent profile', detail: 'Open an in-workspace form that creates an isolated Agent home from a built-in or local starter.', editorKind: 'profile', kind: 'editor', safety: 'safe' },
102
- { id: 'runtime-profile-template-edit', label: 'Customize starter', detail: 'Export a starter JSON file, edit it, import it as a local starter, then create a profile from it.', command: '/agent-profile template export <id> <path> --yes', kind: 'command', safety: 'safe' },
103
- { id: 'runtime-profile-switch', label: 'Switch Agent profile', detail: 'Launch goodvibes-agent --agent-profile <name> to use that isolated Agent home. This workspace cannot switch the current process home after startup.', kind: 'guidance', safety: 'safe' },
107
+ { id: 'runtime-profile-template-edit', label: 'Customize starter', detail: 'Open the starter export form, edit the JSON file, then import it as a local starter.', editorKind: 'profile-template-export', kind: 'editor', safety: 'safe' },
108
+ { id: 'runtime-profile-switch', label: 'Switch Agent profile', detail: 'Launch goodvibes-agent --agent-profile NAME to use that isolated Agent home. This workspace cannot switch the current process home after startup.', kind: 'guidance', safety: 'safe' },
104
109
  ],
105
110
  },
106
111
  {
@@ -134,7 +139,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
134
139
  { id: 'personas-active', label: 'Show active persona', detail: 'Inspect the active local persona applied to new turns.', command: '/personas active', kind: 'command', safety: 'read-only' },
135
140
  { id: 'personas-prev', label: 'Previous persona', detail: 'Move the local persona selection up without changing active state.', localKind: 'persona', selectionDelta: -1, kind: 'local-selection', safety: 'safe' },
136
141
  { id: 'personas-next', label: 'Next persona', detail: 'Move the local persona selection down without changing active state.', localKind: 'persona', selectionDelta: 1, kind: 'local-selection', safety: 'safe' },
137
- { id: 'personas-create', label: 'Create persona', detail: 'Open an in-workspace form for a local persona. No placeholder command is dispatched.', editorKind: 'persona', kind: 'editor', safety: 'safe' },
142
+ { id: 'personas-create', label: 'Create persona', detail: 'Open an in-workspace form for a local persona that writes Agent-local state only.', editorKind: 'persona', kind: 'editor', safety: 'safe' },
138
143
  { id: 'personas-edit', label: 'Edit selected', detail: 'Open the selected local persona in an in-workspace editor.', localKind: 'persona', localOperation: 'persona-edit', kind: 'local-operation', safety: 'safe' },
139
144
  { id: 'personas-use', label: 'Use selected', detail: 'Activate the selected local persona for future main-conversation turns.', localKind: 'persona', localOperation: 'persona-use', kind: 'local-operation', safety: 'safe' },
140
145
  { id: 'personas-review', label: 'Review selected', detail: 'Mark the selected local persona reviewed after inspecting it.', localKind: 'persona', localOperation: 'persona-review', kind: 'local-operation', safety: 'safe' },
@@ -151,11 +156,13 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
151
156
  actions: [
152
157
  { id: 'skills-list', label: 'List skills', detail: 'Print the full local Agent skill library.', command: '/agent-skills list', kind: 'command', safety: 'read-only' },
153
158
  { id: 'skills-enabled', label: 'Enabled skills', detail: 'Show only skills currently injected into Agent guidance.', command: '/agent-skills enabled', kind: 'command', safety: 'read-only' },
159
+ { id: 'skills-discover', label: 'Discover skill files', detail: 'Scan project and global Agent skill folders for SKILL.md or .md skills without importing them.', command: '/agent-skills discover', kind: 'command', safety: 'read-only' },
160
+ { id: 'skills-import-discovered', label: 'Import discovered skill', detail: 'Open an in-workspace form that imports one reviewed discovered skill file into the Agent-local skill registry after typed confirmation.', editorKind: 'skill-discovery-import', kind: 'editor', safety: 'safe' },
154
161
  { id: 'skills-bundles', label: 'Skill bundles', detail: 'List reviewable groups of local skills that can be enabled together.', command: '/agent-skills bundle list', kind: 'command', safety: 'read-only' },
155
- { id: 'skills-create-bundle', label: 'Create bundle', detail: 'Create a named skill bundle from existing skill ids with an explicit command.', command: '/agent-skills bundle create --name <name> --description <summary> --skills <id,id>', kind: 'command', safety: 'safe' },
162
+ { id: 'skills-create-bundle', label: 'Create bundle', detail: 'Open an in-workspace form that creates a named skill bundle from existing local skill ids.', editorKind: 'skill-bundle', kind: 'editor', safety: 'safe' },
156
163
  { id: 'skills-prev', label: 'Previous skill', detail: 'Move the local skill selection up without changing enabled state.', localKind: 'skill', selectionDelta: -1, kind: 'local-selection', safety: 'safe' },
157
164
  { id: 'skills-next', label: 'Next skill', detail: 'Move the local skill selection down without changing enabled state.', localKind: 'skill', selectionDelta: 1, kind: 'local-selection', safety: 'safe' },
158
- { id: 'skills-create', label: 'Create skill', detail: 'Open an in-workspace form for a reusable local procedure. No placeholder command is dispatched.', editorKind: 'skill', kind: 'editor', safety: 'safe' },
165
+ { id: 'skills-create', label: 'Create skill', detail: 'Open an in-workspace form for a reusable local procedure that writes Agent-local state only.', editorKind: 'skill', kind: 'editor', safety: 'safe' },
159
166
  { id: 'skills-edit', label: 'Edit selected', detail: 'Open the selected local Agent skill in an in-workspace editor.', localKind: 'skill', localOperation: 'skill-edit', kind: 'local-operation', safety: 'safe' },
160
167
  { id: 'skills-enable', label: 'Enable selected', detail: 'Enable the selected local Agent skill for future main-conversation guidance.', localKind: 'skill', localOperation: 'skill-enable', kind: 'local-operation', safety: 'safe' },
161
168
  { id: 'skills-disable', label: 'Disable selected', detail: 'Disable the selected local Agent skill without deleting it.', localKind: 'skill', localOperation: 'skill-disable', kind: 'local-operation', safety: 'safe' },
@@ -168,20 +175,20 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
168
175
  group: 'LEARN',
169
176
  label: 'Routines',
170
177
  summary: 'Repeatable workflows for the main conversation.',
171
- detail: 'Routines run in the main conversation by default. Promotion to an external schedule requires a real schedule command and --yes.',
178
+ detail: 'Routines run in the main conversation by default. Promotion to a connected schedule requires a real schedule command and --yes.',
172
179
  actions: [
173
180
  { id: 'routines-list', label: 'List routines', detail: 'Print the full local Agent routine library.', command: '/routines list', kind: 'command', safety: 'read-only' },
174
181
  { id: 'routines-enabled', label: 'Enabled routines', detail: 'Show routines available for direct use.', command: '/routines enabled', kind: 'command', safety: 'read-only' },
175
182
  { id: 'routines-prev', label: 'Previous routine', detail: 'Move the local routine selection up without changing enabled state.', localKind: 'routine', selectionDelta: -1, kind: 'local-selection', safety: 'safe' },
176
183
  { id: 'routines-next', label: 'Next routine', detail: 'Move the local routine selection down without changing enabled state.', localKind: 'routine', selectionDelta: 1, kind: 'local-selection', safety: 'safe' },
177
- { id: 'routines-create', label: 'Create routine', detail: 'Open an in-workspace form for a repeatable local workflow. No placeholder command is dispatched.', editorKind: 'routine', kind: 'editor', safety: 'safe' },
184
+ { id: 'routines-create', label: 'Create routine', detail: 'Open an in-workspace form for a repeatable local workflow that writes Agent-local state only.', editorKind: 'routine', kind: 'editor', safety: 'safe' },
178
185
  { id: 'routines-edit', label: 'Edit selected', detail: 'Open the selected local Agent routine in an in-workspace editor.', localKind: 'routine', localOperation: 'routine-edit', kind: 'local-operation', safety: 'safe' },
179
186
  { id: 'routines-start', label: 'Start selected', detail: 'Mark the selected routine started and show it as a main-conversation workflow. This creates no hidden job.', localKind: 'routine', localOperation: 'routine-start', kind: 'local-operation', safety: 'safe' },
180
187
  { id: 'routines-enable', label: 'Enable selected', detail: 'Enable the selected routine for future main-conversation guidance.', localKind: 'routine', localOperation: 'routine-enable', kind: 'local-operation', safety: 'safe' },
181
188
  { id: 'routines-disable', label: 'Disable selected', detail: 'Disable the selected routine without deleting it.', localKind: 'routine', localOperation: 'routine-disable', kind: 'local-operation', safety: 'safe' },
182
189
  { id: 'routines-review', label: 'Review selected', detail: 'Mark the selected local routine reviewed after inspecting it.', localKind: 'routine', localOperation: 'routine-review', kind: 'local-operation', safety: 'safe' },
183
190
  { id: 'routines-delete', label: 'Delete selected', detail: 'Open a confirmation form before deleting the selected local Agent routine.', localKind: 'routine', localOperation: 'routine-delete', kind: 'local-operation', safety: 'safe' },
184
- { id: 'routines-promote', label: 'Promote to schedule', detail: 'Create an external schedule from a reviewed routine only with real timing and --yes.', command: '/routines promote <id> --cron <expr> --yes', kind: 'command', safety: 'safe' },
191
+ { id: 'routines-promote', label: 'Promote to schedule', detail: 'Open an in-workspace form that creates one connected schedule from the selected routine with real timing and confirmation.', editorKind: 'routine-schedule', kind: 'editor', safety: 'safe' },
185
192
  { id: 'routines-receipts', label: 'Promotion receipts', detail: 'Inspect local redacted routine schedule promotion receipts.', command: '/routines receipts', kind: 'command', safety: 'read-only' },
186
193
  ],
187
194
  },
@@ -201,15 +208,16 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
201
208
  id: 'automation',
202
209
  group: 'WATCH',
203
210
  label: 'Automation',
204
- summary: 'Automation and schedule observability with explicit routine promotion.',
205
- detail: 'Agent does not create local automation jobs or hidden scheduler spawns. Reviewed local routines can be promoted into external schedules only through an explicit schedules.create command with --yes, optional delivery targets, and a redacted local receipt.',
211
+ summary: 'Reminders, schedule observability, and explicit routine promotion.',
212
+ detail: 'Agent does not create local automation jobs or hidden scheduler spawns. Confirmed reminders and reviewed local routines can create connected schedules through explicit schedules.create commands with --yes.',
206
213
  actions: [
214
+ { id: 'schedule-reminder', label: 'Create reminder', detail: 'Open an in-workspace form that creates one connected reminder schedule with real timing, optional delivery target, and explicit confirmation.', editorKind: 'reminder-schedule', kind: 'editor', safety: 'safe' },
207
215
  { id: 'schedule-list', label: 'List schedules', detail: 'Inspect configured jobs and history without running or mutating them.', command: '/schedule list', kind: 'command', safety: 'read-only' },
208
- { id: 'schedule-promote-routine', label: 'Promote routine', detail: 'Create an external schedule from a local Agent routine. Requires a real routine id, schedule expression, optional delivery target, and explicit --yes.', command: '/schedule promote-routine <routine-id> --cron <expr> [--delivery-channel slack] --yes', kind: 'command', safety: 'safe' },
216
+ { id: 'schedule-promote-routine', label: 'Promote routine', detail: 'Open an in-workspace form that creates one connected schedule from a local Agent routine with real timing, optional delivery target, and explicit confirmation.', editorKind: 'routine-schedule', kind: 'editor', safety: 'safe' },
209
217
  { id: 'schedule-receipts', label: 'Promotion receipts', detail: 'Review local redacted receipt history for routine-to-schedule promotion attempts.', command: '/schedule receipts', kind: 'command', safety: 'read-only' },
210
- { id: 'schedule-reconcile', label: 'Reconcile schedules', detail: 'Compare local promotion receipts with live external schedules using schedules.list.', command: '/schedule reconcile', kind: 'command', safety: 'read-only' },
211
- { id: 'schedule-policy', label: 'Local scheduler blocked', detail: 'Local schedule add/run/remove/enable/disable remain blocked; only explicit external schedule promotion is allowed here.', kind: 'guidance', safety: 'blocked' },
212
- { id: 'health-services', label: 'Runtime status', detail: 'Inspect runtime readiness without starting, stopping, or restarting anything.', command: '/health review', kind: 'command', safety: 'read-only' },
218
+ { id: 'schedule-reconcile', label: 'Reconcile schedules', detail: 'Compare local promotion receipts with live connected schedules using schedules.list.', command: '/schedule reconcile', kind: 'command', safety: 'read-only' },
219
+ { id: 'schedule-policy', label: 'Local scheduler blocked', detail: 'Local schedule add/run/remove/enable/disable remain blocked; confirmed reminders and routine promotion use connected schedules only.', kind: 'guidance', safety: 'blocked' },
220
+ { id: 'health-services', label: 'Service status', detail: 'Inspect connected-service readiness without starting, stopping, or restarting anything.', command: '/health review', kind: 'command', safety: 'read-only' },
213
221
  ],
214
222
  },
215
223
  {
@@ -220,7 +228,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
220
228
  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 WRFC only when explicitly requested.',
221
229
  actions: [
222
230
  { id: 'delegate-guidance', label: 'Delegation rule', detail: 'For build/fix/review work, delegate one request to GoodVibes TUI instead of spawning local Engineer/Reviewer/Tester roots.', kind: 'guidance', safety: 'delegates' },
223
- { id: 'review-command', label: 'Review delegation command', detail: 'Use /delegate --wrfc <task> only when the user explicitly asks for code review/build execution. Close this workspace and include the actual task text.', kind: 'guidance', safety: 'delegates' },
231
+ { id: 'review-command', label: 'Review delegation command', detail: 'Use /delegate --wrfc TASK only when the user explicitly asks for code review/build execution. Return to the composer and include the actual task text.', kind: 'guidance', safety: 'delegates' },
224
232
  { id: 'delegation-status', label: 'Delegation status', detail: 'Inspect build-delegation receipts and shared-session status without starting coding work.', command: '/delegate status', kind: 'command', safety: 'read-only' },
225
233
  ],
226
234
  },
@@ -212,12 +212,12 @@ function buildChannelStatus(context: CommandContext, spec: AgentWorkspaceChannel
212
212
  ? 'needs-target'
213
213
  : 'ready';
214
214
  const nextStep = setupState === 'disabled'
215
- ? `Enable ${spec.label} in the owning GoodVibes runtime before Agent can use it.`
215
+ ? `Enable ${spec.label} in the owning GoodVibes host before Agent can use it.`
216
216
  : setupState === 'needs-config'
217
- ? `Configure ${missingRequiredKeys.join(', ')} in the owning runtime or secret manager.`
217
+ ? `Configure ${missingRequiredKeys.join(', ')} in the owning GoodVibes host or secret manager.`
218
218
  : setupState === 'needs-target'
219
219
  ? `Provide an explicit delivery target per send, or configure one of ${spec.defaultTargetKeys.join(', ')}.`
220
- : `Use explicit user action or runtime policy to send through ${spec.label}.`;
220
+ : `Use explicit user action or Agent policy to send through ${spec.label}.`;
221
221
  return {
222
222
  id: spec.id,
223
223
  label: spec.label,
@@ -0,0 +1,65 @@
1
+ import { buildAgentWorkspaceBasicCommandEditorSubmission, isAgentWorkspaceBasicCommandEditorKind } from './agent-workspace-basic-command-editors.ts';
2
+ import { buildAgentKnowledgeUrlEditorSubmission } from './agent-workspace-knowledge-url-editor.ts';
3
+ import { buildAgentKnowledgeQueryEditorSubmission } from './agent-workspace-knowledge-query-editor.ts';
4
+ import { buildAgentReminderScheduleEditorSubmission } from './agent-workspace-reminder-schedule-editor.ts';
5
+ import { buildAgentRoutineScheduleEditorSubmission } from './agent-workspace-routine-schedule-editor.ts';
6
+ import type { AgentWorkspaceActionResult, AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
7
+
8
+ type AgentWorkspaceFieldReader = (fieldId: string) => string;
9
+ type AgentWorkspaceCommandEditorKind = Extract<
10
+ AgentWorkspaceEditorKind,
11
+ 'knowledge-url'
12
+ | 'knowledge-file'
13
+ | 'knowledge-browser-history'
14
+ | 'knowledge-connector-ingest'
15
+ | 'knowledge-search'
16
+ | 'knowledge-ask'
17
+ | 'routine-schedule'
18
+ | 'reminder-schedule'
19
+ | 'knowledge-bookmarks'
20
+ | 'tts-prompt'
21
+ | 'image-input'
22
+ | 'skill-bundle'
23
+ | 'skill-discovery-import'
24
+ | 'profile-template-export'
25
+ | 'profile-template-import'
26
+ >;
27
+
28
+ type AgentWorkspaceCommandEditorSubmission =
29
+ | {
30
+ readonly kind: 'editor';
31
+ readonly editor: AgentWorkspaceLocalEditor;
32
+ readonly status: string;
33
+ readonly actionResult?: AgentWorkspaceActionResult;
34
+ }
35
+ | {
36
+ readonly kind: 'dispatch';
37
+ readonly command: string;
38
+ readonly status: string;
39
+ readonly actionResult: AgentWorkspaceActionResult;
40
+ };
41
+
42
+ export function isAgentWorkspaceCommandEditorKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceCommandEditorKind {
43
+ return kind === 'knowledge-url'
44
+ || kind === 'knowledge-search'
45
+ || kind === 'knowledge-ask'
46
+ || kind === 'routine-schedule'
47
+ || kind === 'reminder-schedule'
48
+ || isAgentWorkspaceBasicCommandEditorKind(kind);
49
+ }
50
+
51
+ export function buildAgentWorkspaceCommandEditorSubmission(
52
+ editor: AgentWorkspaceLocalEditor,
53
+ readField: AgentWorkspaceFieldReader,
54
+ commandDispatchAvailable: boolean,
55
+ ): AgentWorkspaceCommandEditorSubmission {
56
+ if (editor.kind === 'knowledge-url') return buildAgentKnowledgeUrlEditorSubmission(editor, readField, commandDispatchAvailable);
57
+ if (editor.kind === 'knowledge-search' || editor.kind === 'knowledge-ask') {
58
+ return buildAgentKnowledgeQueryEditorSubmission(editor, readField, commandDispatchAvailable);
59
+ }
60
+ if (isAgentWorkspaceBasicCommandEditorKind(editor.kind)) {
61
+ return buildAgentWorkspaceBasicCommandEditorSubmission(editor, readField, commandDispatchAvailable);
62
+ }
63
+ if (editor.kind === 'reminder-schedule') return buildAgentReminderScheduleEditorSubmission(editor, readField, commandDispatchAvailable);
64
+ return buildAgentRoutineScheduleEditorSubmission(editor, readField, commandDispatchAvailable);
65
+ }
@@ -30,8 +30,23 @@ export function createProfileEditor(templates: readonly AgentWorkspaceRuntimeSta
30
30
  };
31
31
  }
32
32
 
33
- export function createLocalEditor(kind: AgentWorkspaceLocalEditorKind): AgentWorkspaceLocalEditor {
33
+ export function createLocalEditor(kind: AgentWorkspaceLocalEditorKind | 'knowledge-url'): AgentWorkspaceLocalEditor {
34
34
  if (kind === 'profile') return createProfileEditor([]);
35
+ if (kind === 'knowledge-url') {
36
+ return {
37
+ kind,
38
+ mode: 'create',
39
+ title: 'Ingest Agent Knowledge URL',
40
+ selectedFieldIndex: 0,
41
+ message: 'Add a source-backed URL to the isolated Agent Knowledge segment. Type yes on the final field to confirm.',
42
+ fields: [
43
+ { id: 'url', label: 'URL', value: '', required: true, multiline: false, hint: 'HTTP or HTTPS URL to ingest into Agent Knowledge only.' },
44
+ { id: 'tags', label: 'Tags', value: '', required: false, multiline: false, hint: 'Comma-separated optional tags. Spaces are not needed.' },
45
+ { id: 'folder', label: 'Folder', value: '', required: false, multiline: false, hint: 'Optional Agent Knowledge folder path.' },
46
+ { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /knowledge ingest-url with --yes.' },
47
+ ],
48
+ };
49
+ }
35
50
  if (kind === 'memory') {
36
51
  return {
37
52
  kind,
@@ -88,7 +103,7 @@ export function createLocalEditor(kind: AgentWorkspaceLocalEditorKind): AgentWor
88
103
  mode: 'create',
89
104
  title: 'Create Routine',
90
105
  selectedFieldIndex: 0,
91
- message: 'Enter a repeatable workflow. It runs in the main conversation unless explicitly promoted to an external schedule.',
106
+ message: 'Enter a repeatable workflow. It runs in the main conversation unless explicitly promoted to a connected schedule.',
92
107
  fields: [
93
108
  { id: 'name', label: 'Name', value: '', required: true, multiline: false, hint: 'Short routine name.' },
94
109
  { id: 'description', label: 'Description', value: '', required: true, multiline: false, hint: 'One-line summary of the workflow.' },
@@ -0,0 +1,74 @@
1
+ import type { AgentWorkspaceActionResult, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
2
+ import { quoteSlashCommandArg } from './slash-command-parser.ts';
3
+
4
+ type AgentWorkspaceFieldReader = (fieldId: string) => string;
5
+ export type AgentKnowledgeQueryMode = 'ask' | 'search';
6
+
7
+ export type AgentKnowledgeQueryEditorSubmission =
8
+ | {
9
+ readonly kind: 'editor';
10
+ readonly editor: AgentWorkspaceLocalEditor;
11
+ readonly status: string;
12
+ readonly actionResult?: AgentWorkspaceActionResult;
13
+ }
14
+ | {
15
+ readonly kind: 'dispatch';
16
+ readonly command: string;
17
+ readonly status: string;
18
+ readonly actionResult: AgentWorkspaceActionResult;
19
+ };
20
+
21
+ export function createAgentKnowledgeQueryEditor(mode: AgentKnowledgeQueryMode): AgentWorkspaceLocalEditor {
22
+ return {
23
+ kind: mode === 'ask' ? 'knowledge-ask' : 'knowledge-search',
24
+ mode: 'create',
25
+ title: mode === 'ask' ? 'Ask Agent Knowledge' : 'Search Agent Knowledge',
26
+ selectedFieldIndex: 0,
27
+ message: mode === 'ask'
28
+ ? 'Ask the isolated Agent Knowledge segment. If it has no answer, it fails closed instead of using another wiki.'
29
+ : 'Search the isolated Agent Knowledge segment. Results come from Agent-owned sources only.',
30
+ fields: [
31
+ {
32
+ id: 'query',
33
+ label: mode === 'ask' ? 'Question' : 'Search query',
34
+ value: '',
35
+ required: true,
36
+ multiline: false,
37
+ hint: 'Plain-language query. Spaces are allowed.',
38
+ },
39
+ ],
40
+ };
41
+ }
42
+
43
+ export function buildAgentKnowledgeQueryEditorSubmission(
44
+ editor: AgentWorkspaceLocalEditor,
45
+ readField: AgentWorkspaceFieldReader,
46
+ commandDispatchAvailable: boolean,
47
+ ): AgentKnowledgeQueryEditorSubmission {
48
+ if (!commandDispatchAvailable) {
49
+ return {
50
+ kind: 'editor',
51
+ editor: { ...editor, message: 'Command dispatch is unavailable; cannot query Agent Knowledge from this workspace.' },
52
+ status: 'Command dispatch unavailable.',
53
+ actionResult: {
54
+ kind: 'error',
55
+ title: 'Command dispatch unavailable',
56
+ detail: 'The Agent Knowledge query command cannot be opened from this runtime.',
57
+ },
58
+ };
59
+ }
60
+ const mode: AgentKnowledgeQueryMode = editor.kind === 'knowledge-ask' ? 'ask' : 'search';
61
+ const command = `/knowledge ${mode} ${quoteSlashCommandArg(readField('query'))}`;
62
+ return {
63
+ kind: 'dispatch',
64
+ command,
65
+ status: `Opening Agent Knowledge ${mode}.`,
66
+ actionResult: {
67
+ kind: 'dispatched',
68
+ title: `Opening Agent Knowledge ${mode}`,
69
+ detail: 'The workspace handed a read-only Agent Knowledge query to the shell-owned command router.',
70
+ command,
71
+ safety: 'read-only',
72
+ },
73
+ };
74
+ }
@@ -0,0 +1,95 @@
1
+ import type { AgentWorkspaceActionResult, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
2
+ import { isAffirmative, splitList } from './agent-workspace-editors.ts';
3
+
4
+ type AgentWorkspaceFieldReader = (fieldId: string) => string;
5
+
6
+ export type AgentKnowledgeUrlEditorSubmission =
7
+ | {
8
+ readonly kind: 'editor';
9
+ readonly editor: AgentWorkspaceLocalEditor;
10
+ readonly status: string;
11
+ readonly actionResult?: AgentWorkspaceActionResult;
12
+ }
13
+ | {
14
+ readonly kind: 'dispatch';
15
+ readonly command: string;
16
+ readonly status: string;
17
+ readonly actionResult: AgentWorkspaceActionResult;
18
+ };
19
+
20
+ export function buildAgentKnowledgeUrlEditorSubmission(
21
+ editor: AgentWorkspaceLocalEditor,
22
+ readField: AgentWorkspaceFieldReader,
23
+ commandDispatchAvailable: boolean,
24
+ ): AgentKnowledgeUrlEditorSubmission {
25
+ const url = readField('url');
26
+ const confirm = readField('confirm');
27
+ if (!isAffirmative(confirm)) {
28
+ return {
29
+ kind: 'editor',
30
+ editor: { ...editor, message: 'Type yes to confirm Agent Knowledge URL ingest.' },
31
+ status: 'Agent Knowledge ingest not confirmed.',
32
+ };
33
+ }
34
+
35
+ try {
36
+ const parsed = new URL(url);
37
+ if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
38
+ throw new Error('Agent Knowledge URL ingest requires an http(s) URL.');
39
+ }
40
+ } catch (error) {
41
+ const detail = error instanceof Error ? error.message : String(error);
42
+ return {
43
+ kind: 'editor',
44
+ editor: { ...editor, message: detail },
45
+ status: detail,
46
+ actionResult: {
47
+ kind: 'error',
48
+ title: 'Agent Knowledge ingest URL invalid',
49
+ detail,
50
+ },
51
+ };
52
+ }
53
+
54
+ if (!commandDispatchAvailable) {
55
+ return {
56
+ kind: 'editor',
57
+ editor: { ...editor, message: 'Command dispatch is unavailable; cannot run Agent Knowledge ingest from this workspace.' },
58
+ status: 'Command dispatch unavailable.',
59
+ actionResult: {
60
+ kind: 'error',
61
+ title: 'Command dispatch unavailable',
62
+ detail: 'The Agent Knowledge ingest command cannot be opened from this runtime.',
63
+ },
64
+ };
65
+ }
66
+
67
+ const folder = readField('folder');
68
+ if (/\s/.test(folder)) {
69
+ return {
70
+ kind: 'editor',
71
+ editor: { ...editor, message: 'Folder paths with spaces are not supported from this compact workspace form.' },
72
+ status: 'Folder path contains spaces.',
73
+ };
74
+ }
75
+
76
+ const tags = splitList(readField('tags'));
77
+ const parts = ['/knowledge', 'ingest-url', url];
78
+ if (tags.length > 0) parts.push('--tags', tags.join(','));
79
+ if (folder.length > 0) parts.push('--folder', folder);
80
+ parts.push('--yes');
81
+ const command = parts.join(' ');
82
+
83
+ return {
84
+ kind: 'dispatch',
85
+ command,
86
+ status: 'Opening Agent Knowledge URL ingest.',
87
+ actionResult: {
88
+ kind: 'dispatched',
89
+ title: 'Opening Agent Knowledge URL ingest',
90
+ detail: 'The workspace handed a confirmed Agent Knowledge URL ingest command to the shell-owned command router.',
91
+ command,
92
+ safety: 'safe',
93
+ },
94
+ };
95
+ }