@pellux/goodvibes-agent 1.5.5 → 1.5.6

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 (165) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +1 -1
  3. package/dist/package/main.js +94130 -79335
  4. package/docs/tools-and-commands.md +2 -1
  5. package/package.json +6 -3
  6. package/src/agent/autonomy-schedule-format.ts +1 -1
  7. package/src/agent/autonomy-schedule.ts +3 -3
  8. package/src/agent/calendar/calendar-oauth-service.ts +324 -0
  9. package/src/agent/calendar-subscription-registry.ts +497 -0
  10. package/src/agent/email/email-service.ts +57 -0
  11. package/src/agent/email/smtp-client.ts +30 -10
  12. package/src/agent/memory-prompt.ts +143 -12
  13. package/src/agent/operator-actions.ts +26 -22
  14. package/src/agent/prompt-context-receipts.ts +45 -18
  15. package/src/agent/reminder-schedule-format.ts +1 -1
  16. package/src/agent/reminder-schedule.ts +3 -3
  17. package/src/agent/routine-schedule-format.ts +2 -2
  18. package/src/agent/routine-schedule-promotion.ts +5 -5
  19. package/src/agent/routine-schedule-receipts.ts +2 -2
  20. package/src/agent/schedule-edit-format.ts +1 -1
  21. package/src/agent/schedule-edit.ts +5 -5
  22. package/src/agent/session-registration.ts +281 -0
  23. package/src/agent/vibe-file.ts +50 -0
  24. package/src/cli/local-library-command-shared.ts +146 -0
  25. package/src/cli/management.ts +2 -1
  26. package/src/cli/personas-command.ts +252 -0
  27. package/src/cli/resume-relaunch-notice.ts +151 -0
  28. package/src/cli/routines-command.ts +25 -2
  29. package/src/cli/service-posture.ts +3 -2
  30. package/src/cli/skill-bundle-command.ts +175 -0
  31. package/src/cli/skills-command.ts +309 -0
  32. package/src/cli/status.ts +43 -7
  33. package/src/cli/tui-startup.ts +24 -1
  34. package/src/config/agent-settings-policy.ts +0 -1
  35. package/src/config/secret-config.ts +4 -0
  36. package/src/core/conversation-rendering.ts +20 -11
  37. package/src/core/focus-tracker.ts +41 -0
  38. package/src/core/system-message-noise.ts +108 -0
  39. package/src/core/system-message-router.ts +54 -1
  40. package/src/core/thinking-overlay.ts +83 -0
  41. package/src/input/agent-workspace-access-command-editor-submission.ts +75 -108
  42. package/src/input/agent-workspace-access-command-editors.ts +108 -128
  43. package/src/input/agent-workspace-activation.ts +15 -0
  44. package/src/input/agent-workspace-basic-command-editor-submission.ts +292 -513
  45. package/src/input/agent-workspace-basic-command-editors.ts +433 -564
  46. package/src/input/agent-workspace-calendar-connect-editor.ts +116 -0
  47. package/src/input/agent-workspace-calendar-oauth-editor.ts +152 -0
  48. package/src/input/agent-workspace-calendar-subscribe-editor.ts +128 -0
  49. package/src/input/agent-workspace-categories.ts +7 -2
  50. package/src/input/agent-workspace-channel-command-editor-submission.ts +38 -52
  51. package/src/input/agent-workspace-channel-command-editors.ts +42 -46
  52. package/src/input/agent-workspace-command-editor-engine.ts +133 -0
  53. package/src/input/agent-workspace-command-editor.ts +4 -0
  54. package/src/input/agent-workspace-direct-editor-submission.ts +59 -0
  55. package/src/input/agent-workspace-email-connect-editor.ts +162 -0
  56. package/src/input/agent-workspace-knowledge-command-editor-submission.ts +52 -81
  57. package/src/input/agent-workspace-knowledge-command-editors.ts +71 -71
  58. package/src/input/agent-workspace-library-command-editor-submission.ts +10 -28
  59. package/src/input/agent-workspace-library-command-editors.ts +16 -2
  60. package/src/input/agent-workspace-live-counters.ts +55 -0
  61. package/src/input/agent-workspace-mcp-command-editor-submission.ts +60 -82
  62. package/src/input/agent-workspace-mcp-command-editors.ts +52 -0
  63. package/src/input/agent-workspace-media-command-editor-submission.ts +12 -39
  64. package/src/input/agent-workspace-media-command-editors.ts +10 -8
  65. package/src/input/agent-workspace-memory-command-editor-submission.ts +76 -151
  66. package/src/input/agent-workspace-memory-command-editors.ts +116 -141
  67. package/src/input/agent-workspace-operations-command-editor-submission.ts +131 -184
  68. package/src/input/agent-workspace-operations-command-editors.ts +150 -162
  69. package/src/input/agent-workspace-provider-command-editor-submission.ts +60 -106
  70. package/src/input/agent-workspace-provider-command-editors.ts +58 -68
  71. package/src/input/agent-workspace-search.ts +8 -1
  72. package/src/input/agent-workspace-session-command-editor-submission.ts +104 -132
  73. package/src/input/agent-workspace-session-command-editors.ts +160 -195
  74. package/src/input/agent-workspace-settings.ts +40 -1
  75. package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +55 -71
  76. package/src/input/agent-workspace-skill-bundle-command-editors.ts +65 -69
  77. package/src/input/agent-workspace-snapshot-builders.ts +431 -0
  78. package/src/input/agent-workspace-snapshot-config.ts +43 -0
  79. package/src/input/agent-workspace-snapshot.ts +198 -432
  80. package/src/input/agent-workspace-task-command-editor-submission.ts +34 -44
  81. package/src/input/agent-workspace-task-command-editors.ts +27 -28
  82. package/src/input/agent-workspace-types.ts +35 -1
  83. package/src/input/agent-workspace.ts +5 -14
  84. package/src/input/command-registry.ts +23 -1
  85. package/src/input/commands/calendar-connect-runtime.ts +226 -0
  86. package/src/input/commands/calendar-runtime.ts +110 -7
  87. package/src/input/commands/calendar-subscription-runtime.ts +225 -0
  88. package/src/input/commands/email-runtime.ts +100 -40
  89. package/src/input/commands/knowledge.ts +1 -1
  90. package/src/input/commands/network-scan-runtime.ts +75 -0
  91. package/src/input/commands/operator-actions-runtime.ts +9 -6
  92. package/src/input/commands/personas-runtime.ts +1 -1
  93. package/src/input/commands/schedule-runtime.ts +4 -4
  94. package/src/input/commands/session-content.ts +13 -1
  95. package/src/input/commands/session-workflow.ts +15 -20
  96. package/src/input/commands/session.ts +3 -1
  97. package/src/input/commands/shell-core.ts +20 -6
  98. package/src/input/commands.ts +2 -2
  99. package/src/input/delete-key-policy.ts +46 -0
  100. package/src/input/feed-context-factory.ts +10 -0
  101. package/src/input/handler-feed.ts +87 -0
  102. package/src/input/handler-modal-routes.ts +6 -1
  103. package/src/input/handler.ts +5 -0
  104. package/src/input/panel-paste-flood-guard.ts +94 -0
  105. package/src/input/settings-modal-types.ts +5 -3
  106. package/src/input/settings-modal.ts +21 -0
  107. package/src/main.ts +36 -36
  108. package/src/permissions/approval-posture.ts +141 -0
  109. package/src/renderer/agent-workspace-context-lines.ts +10 -2
  110. package/src/renderer/compositor.ts +27 -4
  111. package/src/renderer/diff.ts +61 -18
  112. package/src/renderer/fullscreen-primitives.ts +37 -18
  113. package/src/renderer/markdown.ts +20 -10
  114. package/src/renderer/modal-factory.ts +25 -15
  115. package/src/renderer/overlay-box.ts +23 -12
  116. package/src/renderer/process-indicator.ts +8 -3
  117. package/src/renderer/prompt-content-width.ts +16 -0
  118. package/src/renderer/settings-modal-helpers.ts +2 -0
  119. package/src/renderer/settings-modal.ts +2 -0
  120. package/src/renderer/startup-theme-probe.ts +35 -0
  121. package/src/renderer/status-glyphs.ts +11 -15
  122. package/src/renderer/system-message.ts +17 -2
  123. package/src/renderer/term-caps.ts +318 -0
  124. package/src/renderer/terminal-bg-probe.ts +373 -0
  125. package/src/renderer/terminal-escapes.ts +24 -0
  126. package/src/renderer/theme-mode-config.ts +87 -0
  127. package/src/renderer/theme.ts +241 -0
  128. package/src/renderer/thinking.ts +12 -3
  129. package/src/renderer/tool-call.ts +7 -3
  130. package/src/renderer/ui-factory.ts +92 -36
  131. package/src/renderer/ui-primitives.ts +33 -93
  132. package/src/runtime/bootstrap-core.ts +15 -0
  133. package/src/runtime/bootstrap-hook-bridge.ts +6 -0
  134. package/src/runtime/bootstrap-shell.ts +2 -0
  135. package/src/runtime/bootstrap.ts +68 -5
  136. package/src/runtime/calendar-boot-refresh.ts +105 -0
  137. package/src/runtime/lan-scan-consent.ts +253 -0
  138. package/src/runtime/services.ts +127 -2
  139. package/src/runtime/session-spine-rest-transport.ts +160 -0
  140. package/src/runtime/terminal-output-guard.ts +6 -1
  141. package/src/runtime/ui-services.ts +3 -0
  142. package/src/shell/agent-workspace-fullscreen.ts +5 -0
  143. package/src/shell/terminal-focus-mode.ts +120 -0
  144. package/src/shell/ui-openers.ts +13 -4
  145. package/src/tools/agent-harness-autonomy-intake.ts +5 -5
  146. package/src/tools/agent-harness-autonomy-queue.ts +1 -1
  147. package/src/tools/agent-harness-background-processes.ts +2 -1
  148. package/src/tools/agent-harness-metadata.ts +16 -8
  149. package/src/tools/agent-harness-operator-methods.ts +44 -8
  150. package/src/tools/agent-harness-personal-ops-discovery.ts +57 -10
  151. package/src/tools/agent-harness-personal-ops-lanes.ts +17 -5
  152. package/src/tools/agent-harness-personal-ops-operations.ts +7 -7
  153. package/src/tools/agent-harness-personal-ops-types.ts +6 -0
  154. package/src/tools/agent-harness-prompt-context.ts +26 -12
  155. package/src/tools/agent-harness-workspace-actions.ts +4 -0
  156. package/src/tools/agent-local-registry-args.ts +117 -0
  157. package/src/tools/agent-local-registry-memory.ts +227 -0
  158. package/src/tools/agent-local-registry-tool.ts +19 -237
  159. package/src/tools/agent-operator-briefing-tool.ts +2 -2
  160. package/src/tools/agent-operator-method-tool.ts +13 -0
  161. package/src/tools/agent-policy-explanation.ts +39 -4
  162. package/src/tools/agent-schedule-tool.ts +5 -5
  163. package/src/utils/terminal-width.ts +98 -1
  164. package/src/version.ts +1 -1
  165. package/src/cli/local-library-command.ts +0 -825
@@ -1,4 +1,6 @@
1
1
  import type { AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
2
+ import type { AgentWorkspaceEditorSpec, AgentWorkspaceEditorSpecEntry } from './agent-workspace-command-editor-engine.ts';
3
+ import { createAgentWorkspaceEditorFromTable } from './agent-workspace-command-editor-engine.ts';
2
4
 
3
5
  export type AgentWorkspaceOperationsCommandEditorKind = Extract<
4
6
  AgentWorkspaceEditorKind,
@@ -45,168 +47,150 @@ export function isAgentWorkspaceOperationsCommandEditorKind(kind: AgentWorkspace
45
47
  || kind === 'schedule-receipt';
46
48
  }
47
49
 
48
- export function createAgentWorkspaceOperationsCommandEditor(kind: AgentWorkspaceOperationsCommandEditorKind): AgentWorkspaceLocalEditor {
49
- if (kind === 'plan-seed') {
50
- return {
51
- kind,
52
- mode: 'create',
53
- title: 'Seed Planning Goal',
54
- selectedFieldIndex: 0,
55
- message: 'Seed Agent planning state from a concrete goal. This stays in the main Agent planning flow and does not create coding-role Agent jobs.',
56
- fields: [
57
- { id: 'goal', label: 'Planning goal', value: '', required: true, multiline: true, hint: 'Describe the goal or operating plan to evaluate. Ctrl-J inserts a new line.' },
58
- ],
59
- };
60
- }
61
- if (kind === 'health-repair') {
62
- return {
63
- kind,
64
- mode: 'create',
65
- title: 'Show Health Repair Guidance',
66
- selectedFieldIndex: 0,
67
- message: 'Show health repair guidance for one domain. Agent does not manage connected-host hosting or mutate connected-host lifecycle.',
68
- fields: [
69
- { id: 'domain', label: 'Domain', value: 'settings', required: true, multiline: false, hint: 'settings, auth, accounts, host, remote, mcp, continuity, or maintenance.' },
70
- ],
71
- };
72
- }
73
- if (kind === 'approval-review') {
74
- return {
75
- kind,
76
- mode: 'create',
77
- title: 'Review Approval Class',
78
- selectedFieldIndex: 0,
79
- message: 'Review one approval class without approving, denying, or mutating pending requests.',
80
- fields: [
81
- { id: 'kind', label: 'Approval kind', value: 'shell', required: true, multiline: false, hint: 'shell, file, network, delegate, mcp, remote, hook, or plugin.' },
82
- ],
83
- };
84
- }
85
- if (kind === 'approval-approve' || kind === 'approval-deny' || kind === 'approval-cancel') {
86
- const verb = kind === 'approval-approve' ? 'Approve' : kind === 'approval-deny' ? 'Deny' : 'Cancel';
87
- return {
88
- kind,
89
- mode: 'update',
90
- title: `${verb} Approval`,
91
- selectedFieldIndex: 0,
92
- message: `${verb} one pending connected-host approval request. This is an explicit operator action and requires typed confirmation.`,
93
- fields: [
94
- { id: 'approvalId', label: 'Approval id', value: '', required: true, multiline: false, hint: 'Approval request id from the approval list.' },
95
- { id: 'note', label: 'Note', value: '', required: false, multiline: true, hint: 'Optional approval note. Ctrl-J inserts a new line.' },
96
- { id: 'remember', label: 'Remember', value: '', required: false, multiline: false, hint: 'yes/no when you explicitly want to set the connected-host remember flag; blank leaves it unset.' },
97
- { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: `Type yes to run /approval ${kind.replace('approval-', '')} with --yes.` },
98
- ],
99
- };
100
- }
101
- if (
102
- kind === 'automation-job-run'
103
- || kind === 'automation-job-pause'
104
- || kind === 'automation-job-resume'
105
- || kind === 'automation-run-cancel'
106
- || kind === 'automation-run-retry'
107
- || kind === 'schedule-run'
108
- ) {
109
- const job = kind.startsWith('automation-job-');
110
- const run = kind.startsWith('automation-run-');
111
- const label = job ? 'Job id' : run ? 'Run id' : 'Schedule id';
112
- const field = job ? 'jobId' : run ? 'runId' : 'scheduleId';
113
- const action = kind === 'automation-job-run'
114
- ? 'Run Automation Job'
115
- : kind === 'automation-job-pause'
116
- ? 'Pause Automation Job'
117
- : kind === 'automation-job-resume'
118
- ? 'Resume Automation Job'
119
- : kind === 'automation-run-cancel'
120
- ? 'Cancel Automation Run'
121
- : kind === 'automation-run-retry'
122
- ? 'Retry Automation Run'
123
- : 'Run Schedule';
124
- return {
125
- kind,
126
- mode: 'update',
127
- title: action,
128
- selectedFieldIndex: 0,
129
- message: `${action} through the connected host. This is never automatic and requires typed confirmation.`,
130
- fields: [
131
- { id: field, label, value: '', required: true, multiline: false, hint: `${label} from the Automation workspace list.` },
132
- { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run the confirmed connected-host action with --yes.' },
133
- ],
134
- };
135
- }
136
- if (kind === 'schedule-edit') {
137
- return {
138
- kind,
139
- mode: 'update',
140
- title: 'Edit Schedule',
141
- selectedFieldIndex: 0,
142
- message: 'Edit one connected-host schedule name, cadence, or prompt. This requires typed confirmation and never creates a hidden local job.',
143
- fields: [
144
- { id: 'scheduleId', label: 'Schedule id', value: '', required: true, multiline: false, hint: 'Schedule id from List schedules or the autonomy queue.' },
145
- { id: 'scheduleKind', label: 'Schedule type', value: '', required: false, multiline: false, hint: 'Optional. at, every, or cron. Leave blank to keep cadence.' },
146
- { id: 'scheduleValue', label: 'Schedule value', value: '', required: false, multiline: false, hint: 'Required with Schedule type. Examples: 0 9 * * *, 7d, or an ISO timestamp.' },
147
- { id: 'timezone', label: 'Timezone', value: '', required: false, multiline: false, hint: 'Optional IANA timezone for cron schedules, for example America/Chicago.' },
148
- { id: 'scheduleName', label: 'Schedule name', value: '', required: false, multiline: false, hint: 'Optional replacement display name.' },
149
- { id: 'task', label: 'Task', value: '', required: false, multiline: true, hint: 'Optional replacement autonomous task. Ctrl-J inserts a new line.' },
150
- { id: 'successCriteria', label: 'Success criteria', value: '', required: false, multiline: true, hint: 'Required with Task so scheduled runs know what success means.' },
151
- { id: 'prompt', label: 'Exact prompt', value: '', required: false, multiline: true, hint: 'Optional exact prompt replacement. Do not combine with Task.' },
152
- { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /schedule edit with --yes.' },
153
- ],
154
- };
155
- }
156
- if (kind === 'plan-approve') {
157
- return {
158
- kind,
159
- mode: 'update',
160
- title: 'Approve Planning State',
161
- selectedFieldIndex: 0,
162
- message: 'Approve the current Agent planning state for execution. This changes planning state and requires typed confirmation.',
163
- fields: [
164
- { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /plan approve with --yes.' },
165
- ],
166
- };
167
- }
168
- if (kind === 'plan-override') {
169
- return {
170
- kind,
171
- mode: 'update',
172
- title: 'Override Planning Strategy',
173
- selectedFieldIndex: 0,
174
- message: 'Override the planner strategy through the runtime route. This changes planner state and requires typed confirmation.',
175
- fields: [
176
- { id: 'strategy', label: 'Strategy', value: 'serial', required: true, multiline: false, hint: 'Planner strategy, such as serial.' },
177
- { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /plan override with --yes.' },
178
- ],
179
- };
180
- }
181
- if (kind === 'plan-clear') {
182
- return {
183
- kind,
184
- mode: 'delete',
185
- title: 'Clear Planning State',
186
- selectedFieldIndex: 0,
187
- message: 'Clear planner state. This is destructive and requires typed confirmation.',
188
- fields: [
189
- { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /plan clear with --yes.' },
190
- ],
191
- };
192
- }
193
- if (kind === 'routine-receipt' || kind === 'schedule-receipt') {
194
- const routine = kind === 'routine-receipt';
195
- return {
196
- kind,
197
- mode: 'create',
198
- title: routine ? 'Show Routine Promotion Receipt' : 'Show Schedule Receipt',
199
- selectedFieldIndex: 0,
200
- message: routine
201
- ? 'Show one local routine schedule-promotion receipt without reconciling or mutating connected schedules.'
202
- : 'Show one local schedule receipt without reconciling or mutating connected schedules.',
203
- fields: [
204
- { id: 'receiptId', label: 'Receipt id', value: '', required: true, multiline: false, hint: 'Receipt id from Promotion receipts.' },
205
- ],
206
- };
207
- }
50
+ function approvalActionSpec(kind: AgentWorkspaceOperationsCommandEditorKind): AgentWorkspaceEditorSpec {
51
+ const verb = kind === 'approval-approve' ? 'Approve' : kind === 'approval-deny' ? 'Deny' : 'Cancel';
52
+ return {
53
+ mode: 'update',
54
+ title: `${verb} Approval`,
55
+ selectedFieldIndex: 0,
56
+ message: `${verb} one pending connected-host approval request. This is an explicit operator action and requires typed confirmation.`,
57
+ fields: [
58
+ { id: 'approvalId', label: 'Approval id', value: '', required: true, multiline: false, hint: 'Approval request id from the approval list.' },
59
+ { id: 'note', label: 'Note', value: '', required: false, multiline: true, hint: 'Optional approval note. Ctrl-J inserts a new line.' },
60
+ { id: 'remember', label: 'Remember', value: '', required: false, multiline: false, hint: 'yes/no when you explicitly want to set the connected-host remember flag; blank leaves it unset.' },
61
+ { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: `Type yes to run /approval ${kind.replace('approval-', '')} with --yes.` },
62
+ ],
63
+ };
64
+ }
65
+
66
+ function automationActionSpec(kind: AgentWorkspaceOperationsCommandEditorKind): AgentWorkspaceEditorSpec {
67
+ const job = kind.startsWith('automation-job-');
68
+ const run = kind.startsWith('automation-run-');
69
+ const label = job ? 'Job id' : run ? 'Run id' : 'Schedule id';
70
+ const field = job ? 'jobId' : run ? 'runId' : 'scheduleId';
71
+ const action = kind === 'automation-job-run'
72
+ ? 'Run Automation Job'
73
+ : kind === 'automation-job-pause'
74
+ ? 'Pause Automation Job'
75
+ : kind === 'automation-job-resume'
76
+ ? 'Resume Automation Job'
77
+ : kind === 'automation-run-cancel'
78
+ ? 'Cancel Automation Run'
79
+ : kind === 'automation-run-retry'
80
+ ? 'Retry Automation Run'
81
+ : 'Run Schedule';
208
82
  return {
209
- kind,
83
+ mode: 'update',
84
+ title: action,
85
+ selectedFieldIndex: 0,
86
+ message: `${action} through the connected host. This is never automatic and requires typed confirmation.`,
87
+ fields: [
88
+ { id: field, label, value: '', required: true, multiline: false, hint: `${label} from the Automation workspace list.` },
89
+ { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run the confirmed connected-host action with --yes.' },
90
+ ],
91
+ };
92
+ }
93
+
94
+ function receiptSpec(kind: AgentWorkspaceOperationsCommandEditorKind): AgentWorkspaceEditorSpec {
95
+ const routine = kind === 'routine-receipt';
96
+ return {
97
+ mode: 'create',
98
+ title: routine ? 'Show Routine Promotion Receipt' : 'Show Schedule Receipt',
99
+ selectedFieldIndex: 0,
100
+ message: routine
101
+ ? 'Show one local routine schedule-promotion receipt without reconciling or mutating connected schedules.'
102
+ : 'Show one local schedule receipt without reconciling or mutating connected schedules.',
103
+ fields: [
104
+ { id: 'receiptId', label: 'Receipt id', value: '', required: true, multiline: false, hint: 'Receipt id from Promotion receipts.' },
105
+ ],
106
+ };
107
+ }
108
+
109
+ const OPERATIONS_COMMAND_EDITOR_SPECS: Readonly<Record<AgentWorkspaceOperationsCommandEditorKind, AgentWorkspaceEditorSpecEntry<AgentWorkspaceOperationsCommandEditorKind>>> = {
110
+ 'plan-seed': {
111
+ mode: 'create',
112
+ title: 'Seed Planning Goal',
113
+ selectedFieldIndex: 0,
114
+ message: 'Seed Agent planning state from a concrete goal. This stays in the main Agent planning flow and does not create coding-role Agent jobs.',
115
+ fields: [
116
+ { id: 'goal', label: 'Planning goal', value: '', required: true, multiline: true, hint: 'Describe the goal or operating plan to evaluate. Ctrl-J inserts a new line.' },
117
+ ],
118
+ },
119
+ 'health-repair': {
120
+ mode: 'create',
121
+ title: 'Show Health Repair Guidance',
122
+ selectedFieldIndex: 0,
123
+ message: 'Show health repair guidance for one domain. Agent does not manage connected-host hosting or mutate connected-host lifecycle.',
124
+ fields: [
125
+ { id: 'domain', label: 'Domain', value: 'settings', required: true, multiline: false, hint: 'settings, auth, accounts, host, remote, mcp, continuity, or maintenance.' },
126
+ ],
127
+ },
128
+ 'approval-review': {
129
+ mode: 'create',
130
+ title: 'Review Approval Class',
131
+ selectedFieldIndex: 0,
132
+ message: 'Review one approval class without approving, denying, or mutating pending requests.',
133
+ fields: [
134
+ { id: 'kind', label: 'Approval kind', value: 'shell', required: true, multiline: false, hint: 'shell, file, network, delegate, mcp, remote, hook, or plugin.' },
135
+ ],
136
+ },
137
+ 'approval-approve': approvalActionSpec,
138
+ 'approval-deny': approvalActionSpec,
139
+ 'approval-cancel': approvalActionSpec,
140
+ 'automation-job-run': automationActionSpec,
141
+ 'automation-job-pause': automationActionSpec,
142
+ 'automation-job-resume': automationActionSpec,
143
+ 'automation-run-cancel': automationActionSpec,
144
+ 'automation-run-retry': automationActionSpec,
145
+ 'schedule-run': automationActionSpec,
146
+ 'schedule-edit': {
147
+ mode: 'update',
148
+ title: 'Edit Schedule',
149
+ selectedFieldIndex: 0,
150
+ message: 'Edit one connected-host schedule name, cadence, or prompt. This requires typed confirmation and never creates a hidden local job.',
151
+ fields: [
152
+ { id: 'scheduleId', label: 'Schedule id', value: '', required: true, multiline: false, hint: 'Schedule id from List schedules or the autonomy queue.' },
153
+ { id: 'scheduleKind', label: 'Schedule type', value: '', required: false, multiline: false, hint: 'Optional. at, every, or cron. Leave blank to keep cadence.' },
154
+ { id: 'scheduleValue', label: 'Schedule value', value: '', required: false, multiline: false, hint: 'Required with Schedule type. Examples: 0 9 * * *, 7d, or an ISO timestamp.' },
155
+ { id: 'timezone', label: 'Timezone', value: '', required: false, multiline: false, hint: 'Optional IANA timezone for cron schedules, for example America/Chicago.' },
156
+ { id: 'scheduleName', label: 'Schedule name', value: '', required: false, multiline: false, hint: 'Optional replacement display name.' },
157
+ { id: 'task', label: 'Task', value: '', required: false, multiline: true, hint: 'Optional replacement autonomous task. Ctrl-J inserts a new line.' },
158
+ { id: 'successCriteria', label: 'Success criteria', value: '', required: false, multiline: true, hint: 'Required with Task so scheduled runs know what success means.' },
159
+ { id: 'prompt', label: 'Exact prompt', value: '', required: false, multiline: true, hint: 'Optional exact prompt replacement. Do not combine with Task.' },
160
+ { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /schedule edit with --yes.' },
161
+ ],
162
+ },
163
+ 'plan-approve': {
164
+ mode: 'update',
165
+ title: 'Approve Planning State',
166
+ selectedFieldIndex: 0,
167
+ message: 'Approve the current Agent planning state for execution. This changes planning state and requires typed confirmation.',
168
+ fields: [
169
+ { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /plan approve with --yes.' },
170
+ ],
171
+ },
172
+ 'plan-override': {
173
+ mode: 'update',
174
+ title: 'Override Planning Strategy',
175
+ selectedFieldIndex: 0,
176
+ message: 'Override the planner strategy through the runtime route. This changes planner state and requires typed confirmation.',
177
+ fields: [
178
+ { id: 'strategy', label: 'Strategy', value: 'serial', required: true, multiline: false, hint: 'Planner strategy, such as serial.' },
179
+ { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /plan override with --yes.' },
180
+ ],
181
+ },
182
+ 'plan-clear': {
183
+ mode: 'delete',
184
+ title: 'Clear Planning State',
185
+ selectedFieldIndex: 0,
186
+ message: 'Clear planner state. This is destructive and requires typed confirmation.',
187
+ fields: [
188
+ { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /plan clear with --yes.' },
189
+ ],
190
+ },
191
+ 'routine-receipt': receiptSpec,
192
+ 'schedule-receipt': receiptSpec,
193
+ 'plan-show': {
210
194
  mode: 'create',
211
195
  title: 'Show Saved Plan',
212
196
  selectedFieldIndex: 0,
@@ -214,5 +198,9 @@ export function createAgentWorkspaceOperationsCommandEditor(kind: AgentWorkspace
214
198
  fields: [
215
199
  { id: 'planId', label: 'Plan id', value: '', required: true, multiline: false, hint: 'Plan id or unique prefix from Saved plans.' },
216
200
  ],
217
- };
201
+ },
202
+ };
203
+
204
+ export function createAgentWorkspaceOperationsCommandEditor(kind: AgentWorkspaceOperationsCommandEditorKind): AgentWorkspaceLocalEditor {
205
+ return createAgentWorkspaceEditorFromTable(kind, OPERATIONS_COMMAND_EDITOR_SPECS);
218
206
  }
@@ -1,110 +1,54 @@
1
- import type { AgentWorkspaceActionResult, AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
1
+ import type { AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
2
2
  import type { AgentWorkspaceProviderCommandEditorKind } from './agent-workspace-provider-command-editors.ts';
3
3
  import { isAgentWorkspaceProviderCommandEditorKind } from './agent-workspace-provider-command-editors.ts';
4
4
  import { quoteSlashCommandArg } from './slash-command-parser.ts';
5
+ import type { AgentWorkspaceCommandEditorSubmission, AgentWorkspaceCommandSubmissionHandler, AgentWorkspaceFieldReader } from './agent-workspace-command-editor-engine.ts';
6
+ import { buildCommandEditorSubmissionFromTable, dispatchCommandEditorSubmission, editorMessageSubmission, isAffirmative } from './agent-workspace-command-editor-engine.ts';
5
7
 
6
- type AgentWorkspaceFieldReader = (fieldId: string) => string;
8
+ export type AgentWorkspaceProviderCommandEditorSubmission = AgentWorkspaceCommandEditorSubmission;
7
9
 
8
- export type AgentWorkspaceProviderCommandEditorSubmission =
9
- | {
10
- readonly kind: 'editor';
11
- readonly editor: AgentWorkspaceLocalEditor;
12
- readonly status: string;
13
- readonly actionResult?: AgentWorkspaceActionResult;
14
- }
15
- | {
16
- readonly kind: 'dispatch';
17
- readonly command: string;
18
- readonly status: string;
19
- readonly actionResult: AgentWorkspaceActionResult;
20
- };
21
-
22
- function isAffirmative(value: string): boolean {
23
- return /^(y|yes|true)$/i.test(value.trim());
24
- }
25
-
26
- function unconfirmed(editor: AgentWorkspaceLocalEditor, label: string): AgentWorkspaceProviderCommandEditorSubmission {
27
- return {
28
- kind: 'editor',
29
- editor: { ...editor, message: `${label} not confirmed. Type yes, then press Enter.` },
30
- status: `${label} not confirmed.`,
31
- };
10
+ function unconfirmed(editor: AgentWorkspaceLocalEditor, label: string): AgentWorkspaceCommandEditorSubmission {
11
+ return editorMessageSubmission(editor, `${label} not confirmed. Type yes, then press Enter.`, `${label} not confirmed.`);
32
12
  }
33
13
 
34
14
  export function isAgentWorkspaceProviderCommandSubmissionKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceProviderCommandEditorKind {
35
15
  return isAgentWorkspaceProviderCommandEditorKind(kind);
36
16
  }
37
17
 
38
- export function buildAgentWorkspaceProviderCommandEditorSubmission(
39
- editor: AgentWorkspaceLocalEditor,
40
- readField: AgentWorkspaceFieldReader,
41
- ): AgentWorkspaceProviderCommandEditorSubmission {
42
- if (editor.kind === 'provider-use') {
18
+ const PROVIDER_COMMAND_SUBMISSION_HANDLERS: Readonly<Record<AgentWorkspaceProviderCommandEditorKind, AgentWorkspaceCommandSubmissionHandler>> = {
19
+ 'provider-use': (_editor, readField) => {
43
20
  const model = readField('model');
44
21
  const command = [
45
22
  '/provider',
46
23
  quoteSlashCommandArg(readField('provider')),
47
24
  ...(model.length > 0 ? [quoteSlashCommandArg(model)] : []),
48
25
  ].join(' ');
49
- return {
50
- kind: 'dispatch',
51
- command,
52
- status: 'Opening provider selection.',
53
- actionResult: {
54
- kind: 'dispatched',
55
- title: 'Opening provider selection',
56
- detail: 'The workspace handed provider selection to the shell-owned command router.',
57
- command,
58
- safety: 'safe',
59
- },
60
- };
61
- }
62
- if (editor.kind === 'provider-inspect') {
63
- const command = `/accounts show ${quoteSlashCommandArg(readField('provider'))}`;
64
- return {
65
- kind: 'dispatch',
66
- command,
67
- status: 'Opening provider inspection.',
68
- actionResult: {
69
- kind: 'dispatched',
70
- title: 'Opening provider inspection',
71
- detail: 'The workspace handed read-only provider inspection to the shell-owned command router.',
72
- command,
73
- safety: 'read-only',
74
- },
75
- };
76
- }
77
- if (editor.kind === 'provider-routes') {
78
- const command = `/accounts routes ${quoteSlashCommandArg(readField('provider'))}`;
79
- return {
80
- kind: 'dispatch',
81
- command,
82
- status: 'Opening provider route inspection.',
83
- actionResult: {
84
- kind: 'dispatched',
85
- title: 'Opening provider route inspection',
86
- detail: 'The workspace handed read-only provider route inspection to the shell-owned command router.',
87
- command,
88
- safety: 'read-only',
89
- },
90
- };
91
- }
92
- if (editor.kind === 'provider-account-repair') {
93
- const command = `/accounts repair ${quoteSlashCommandArg(readField('provider'))}`;
94
- return {
95
- kind: 'dispatch',
26
+ return dispatchCommandEditorSubmission(
96
27
  command,
97
- status: 'Opening provider account repair review.',
98
- actionResult: {
99
- kind: 'dispatched',
100
- title: 'Opening provider account repair review',
101
- detail: 'The workspace handed read-only provider account repair guidance to the shell-owned command router.',
102
- command,
103
- safety: 'read-only',
104
- },
105
- };
106
- }
107
- if (editor.kind === 'provider-add') {
28
+ 'Opening provider selection',
29
+ 'The workspace handed provider selection to the shell-owned command router.',
30
+ 'safe',
31
+ );
32
+ },
33
+ 'provider-inspect': (_editor, readField) => dispatchCommandEditorSubmission(
34
+ `/accounts show ${quoteSlashCommandArg(readField('provider'))}`,
35
+ 'Opening provider inspection',
36
+ 'The workspace handed read-only provider inspection to the shell-owned command router.',
37
+ 'read-only',
38
+ ),
39
+ 'provider-routes': (_editor, readField) => dispatchCommandEditorSubmission(
40
+ `/accounts routes ${quoteSlashCommandArg(readField('provider'))}`,
41
+ 'Opening provider route inspection',
42
+ 'The workspace handed read-only provider route inspection to the shell-owned command router.',
43
+ 'read-only',
44
+ ),
45
+ 'provider-account-repair': (_editor, readField) => dispatchCommandEditorSubmission(
46
+ `/accounts repair ${quoteSlashCommandArg(readField('provider'))}`,
47
+ 'Opening provider account repair review',
48
+ 'The workspace handed read-only provider account repair guidance to the shell-owned command router.',
49
+ 'read-only',
50
+ ),
51
+ 'provider-add': (editor, readField) => {
108
52
  if (!isAffirmative(readField('confirm'))) {
109
53
  return unconfirmed(editor, 'Custom provider add');
110
54
  }
@@ -122,6 +66,10 @@ export function buildAgentWorkspaceProviderCommandEditorSubmission(
122
66
  }
123
67
  parts.push('--yes');
124
68
  redactedParts.push('--yes');
69
+ // The dispatched command carries the real key; the actionResult.command shown
70
+ // in the transcript is redacted. This is the one submission in this domain that
71
+ // cannot use dispatchCommandEditorSubmission, whose actionResult.command always
72
+ // matches the dispatched command.
125
73
  return {
126
74
  kind: 'dispatch',
127
75
  command: parts.join(' '),
@@ -134,22 +82,28 @@ export function buildAgentWorkspaceProviderCommandEditorSubmission(
134
82
  safety: 'safe',
135
83
  },
136
84
  };
137
- }
85
+ },
86
+ 'provider-remove': (editor, readField) => {
87
+ if (!isAffirmative(readField('confirm'))) {
88
+ return unconfirmed(editor, 'Custom provider removal');
89
+ }
90
+ return dispatchCommandEditorSubmission(
91
+ `/provider remove ${quoteSlashCommandArg(readField('name'))} --yes`,
92
+ 'Opening custom provider removal',
93
+ 'The workspace handed a confirmed custom provider removal command to the shell-owned command router.',
94
+ 'safe',
95
+ );
96
+ },
97
+ };
138
98
 
139
- if (!isAffirmative(readField('confirm'))) {
140
- return unconfirmed(editor, 'Custom provider removal');
141
- }
142
- const command = `/provider remove ${quoteSlashCommandArg(readField('name'))} --yes`;
143
- return {
144
- kind: 'dispatch',
145
- command,
146
- status: 'Opening custom provider removal.',
147
- actionResult: {
148
- kind: 'dispatched',
149
- title: 'Opening custom provider removal',
150
- detail: 'The workspace handed a confirmed custom provider removal command to the shell-owned command router.',
151
- command,
152
- safety: 'safe',
153
- },
154
- };
99
+ export function buildAgentWorkspaceProviderCommandEditorSubmission(
100
+ editor: AgentWorkspaceLocalEditor,
101
+ readField: AgentWorkspaceFieldReader,
102
+ ): AgentWorkspaceCommandEditorSubmission {
103
+ return buildCommandEditorSubmissionFromTable(
104
+ editor.kind as AgentWorkspaceProviderCommandEditorKind,
105
+ editor,
106
+ readField,
107
+ PROVIDER_COMMAND_SUBMISSION_HANDLERS,
108
+ );
155
109
  }