@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
@@ -0,0 +1,52 @@
1
+ import type { AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
2
+ import type { AgentWorkspaceEditorSpecEntry } from './agent-workspace-command-editor-engine.ts';
3
+ import { createAgentWorkspaceEditorFromTable } from './agent-workspace-command-editor-engine.ts';
4
+
5
+ export type AgentWorkspaceMcpCommandEditorKind = Extract<AgentWorkspaceEditorKind, 'mcp-server' | 'mcp-tools-server' | 'mcp-repair'>;
6
+
7
+ export function isAgentWorkspaceMcpCommandEditorKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceMcpCommandEditorKind {
8
+ return kind === 'mcp-server' || kind === 'mcp-tools-server' || kind === 'mcp-repair';
9
+ }
10
+
11
+ const MCP_COMMAND_EDITOR_SPECS: Readonly<Record<AgentWorkspaceMcpCommandEditorKind, AgentWorkspaceEditorSpecEntry<AgentWorkspaceMcpCommandEditorKind>>> = {
12
+ 'mcp-server': {
13
+ mode: 'create',
14
+ title: 'Add MCP Server',
15
+ selectedFieldIndex: 0,
16
+ message: 'Add or update one MCP server from the Agent workspace. Type yes on the final field to confirm.',
17
+ fields: [
18
+ { id: 'name', label: 'Server name', value: '', required: true, multiline: false, hint: 'Letters, numbers, dot, underscore, and dash only.' },
19
+ { id: 'command', label: 'Command', value: '', required: true, multiline: false, hint: 'Executable command, such as bunx, npx, uvx, or a full local binary path.' },
20
+ { id: 'args', label: 'Arguments', value: '', required: false, multiline: false, hint: 'Optional command arguments. Quotes are supported.' },
21
+ { id: 'scope', label: 'Scope', value: '', required: false, multiline: false, hint: 'Optional. Defaults to project. Use project or global.' },
22
+ { id: 'role', label: 'Role', value: '', required: false, multiline: false, hint: 'Optional. general, docs, filesystem, git, database, browser, automation, ops, or remote.' },
23
+ { id: 'trust', label: 'Trust mode', value: '', required: false, multiline: false, hint: 'Optional. Defaults to constrained. Use constrained, ask-on-risk, or blocked. Use settings for allow-all.' },
24
+ { id: 'env', label: 'Env refs', value: '', required: false, multiline: false, hint: 'Comma-separated KEY=VALUE entries. Prefer secret refs, not raw secrets.' },
25
+ { id: 'paths', label: 'Allowed paths', value: '', required: false, multiline: false, hint: 'Comma-separated path allowlist entries.' },
26
+ { id: 'hosts', label: 'Allowed hosts', value: '', required: false, multiline: false, hint: 'Comma-separated host allowlist entries.' },
27
+ { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to save the MCP server through the TUI command router.' },
28
+ ],
29
+ },
30
+ 'mcp-tools-server': {
31
+ mode: 'create',
32
+ title: 'Show MCP Server Tools',
33
+ selectedFieldIndex: 0,
34
+ message: 'List tools exposed by one MCP server without changing server trust, role, or config.',
35
+ fields: [
36
+ { id: 'server', label: 'Server name', value: '', required: true, multiline: false, hint: 'MCP server name from MCP Review or the fullscreen MCP workspace.' },
37
+ ],
38
+ },
39
+ 'mcp-repair': {
40
+ mode: 'create',
41
+ title: 'Show MCP Repair Guidance',
42
+ selectedFieldIndex: 0,
43
+ message: 'Show read-only repair guidance for one MCP server. This does not approve quarantine, change trust, or reload the runtime.',
44
+ fields: [
45
+ { id: 'server', label: 'Server name', value: '', required: true, multiline: false, hint: 'MCP server name from MCP Review or Auth review.' },
46
+ ],
47
+ },
48
+ };
49
+
50
+ export function createAgentWorkspaceMcpCommandEditor(kind: AgentWorkspaceMcpCommandEditorKind): AgentWorkspaceLocalEditor {
51
+ return createAgentWorkspaceEditorFromTable(kind, MCP_COMMAND_EDITOR_SPECS);
52
+ }
@@ -1,42 +1,22 @@
1
- import type { AgentWorkspaceActionResult, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
1
+ import type { AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
2
2
  import type { AgentWorkspaceMediaCommandEditorKind } from './agent-workspace-media-command-editors.ts';
3
3
  import { isAgentWorkspaceMediaCommandEditorKind } from './agent-workspace-media-command-editors.ts';
4
4
  import { quoteSlashCommandArg } from './slash-command-parser.ts';
5
+ import type { AgentWorkspaceCommandEditorSubmission, AgentWorkspaceFieldReader } from './agent-workspace-command-editor-engine.ts';
6
+ import { dispatchCommandEditorSubmission, editorMessageSubmission, isAffirmative } from './agent-workspace-command-editor-engine.ts';
5
7
 
6
- type AgentWorkspaceFieldReader = (fieldId: string) => string;
7
-
8
- export type AgentWorkspaceMediaCommandEditorSubmission =
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
- };
8
+ export type AgentWorkspaceMediaCommandEditorSubmission = AgentWorkspaceCommandEditorSubmission;
21
9
 
22
10
  export function isAgentWorkspaceMediaCommandSubmissionKind(kind: string): kind is AgentWorkspaceMediaCommandEditorKind {
23
11
  return isAgentWorkspaceMediaCommandEditorKind(kind as AgentWorkspaceMediaCommandEditorKind);
24
12
  }
25
13
 
26
- function isAffirmative(value: string): boolean {
27
- return /^(y|yes|true)$/i.test(value.trim());
28
- }
29
-
30
14
  export function buildAgentWorkspaceMediaCommandEditorSubmission(
31
15
  editor: AgentWorkspaceLocalEditor,
32
16
  readField: AgentWorkspaceFieldReader,
33
- ): AgentWorkspaceMediaCommandEditorSubmission {
17
+ ): AgentWorkspaceCommandEditorSubmission {
34
18
  if (!isAffirmative(readField('confirm'))) {
35
- return {
36
- kind: 'editor',
37
- editor: { ...editor, message: 'Media generation not confirmed. Type yes, then press Enter.' },
38
- status: 'Agent media generation not confirmed.',
39
- };
19
+ return editorMessageSubmission(editor, 'Media generation not confirmed. Type yes, then press Enter.', 'Agent media generation not confirmed.');
40
20
  }
41
21
  const parts = ['/media', 'generate'];
42
22
  const provider = readField('provider');
@@ -46,17 +26,10 @@ export function buildAgentWorkspaceMediaCommandEditorSubmission(
46
26
  if (model) parts.push('--model', quoteSlashCommandArg(model));
47
27
  if (mime) parts.push('--mime', quoteSlashCommandArg(mime));
48
28
  parts.push(quoteSlashCommandArg(readField('prompt')), '--yes');
49
- const command = parts.join(' ');
50
- return {
51
- kind: 'dispatch',
52
- command,
53
- status: 'Opening media generation.',
54
- actionResult: {
55
- kind: 'dispatched',
56
- title: 'Opening media generation',
57
- detail: 'The workspace handed confirmed media generation to the shell-owned command router.',
58
- command,
59
- safety: 'safe',
60
- },
61
- };
29
+ return dispatchCommandEditorSubmission(
30
+ parts.join(' '),
31
+ 'Opening media generation',
32
+ 'The workspace handed confirmed media generation to the shell-owned command router.',
33
+ 'safe',
34
+ );
62
35
  }
@@ -1,17 +1,15 @@
1
1
  import type { AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
2
+ import type { AgentWorkspaceEditorSpecEntry } from './agent-workspace-command-editor-engine.ts';
3
+ import { createAgentWorkspaceEditorFromTable } from './agent-workspace-command-editor-engine.ts';
2
4
 
3
- export type AgentWorkspaceMediaCommandEditorKind = Extract<
4
- AgentWorkspaceEditorKind,
5
- 'media-generate'
6
- >;
5
+ export type AgentWorkspaceMediaCommandEditorKind = Extract<AgentWorkspaceEditorKind, 'media-generate'>;
7
6
 
8
7
  export function isAgentWorkspaceMediaCommandEditorKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceMediaCommandEditorKind {
9
8
  return kind === 'media-generate';
10
9
  }
11
10
 
12
- export function createAgentWorkspaceMediaCommandEditor(kind: AgentWorkspaceMediaCommandEditorKind): AgentWorkspaceLocalEditor {
13
- return {
14
- kind,
11
+ const MEDIA_COMMAND_EDITOR_SPECS: Readonly<Record<AgentWorkspaceMediaCommandEditorKind, AgentWorkspaceEditorSpecEntry<AgentWorkspaceMediaCommandEditorKind>>> = {
12
+ 'media-generate': {
15
13
  mode: 'create',
16
14
  title: 'Generate Media',
17
15
  selectedFieldIndex: 0,
@@ -23,5 +21,9 @@ export function createAgentWorkspaceMediaCommandEditor(kind: AgentWorkspaceMedia
23
21
  { id: 'mime', label: 'Output MIME', value: '', required: false, multiline: false, hint: 'Optional output type, such as image/png or video/mp4.' },
24
22
  { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /media generate with --yes.' },
25
23
  ],
26
- };
24
+ },
25
+ };
26
+
27
+ export function createAgentWorkspaceMediaCommandEditor(kind: AgentWorkspaceMediaCommandEditorKind): AgentWorkspaceLocalEditor {
28
+ return createAgentWorkspaceEditorFromTable(kind, MEDIA_COMMAND_EDITOR_SPECS);
27
29
  }
@@ -1,74 +1,21 @@
1
- import type { AgentWorkspaceAction, AgentWorkspaceActionResult, AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
1
+ import type { AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
2
2
  import { quoteSlashCommandArg } from './slash-command-parser.ts';
3
3
  import type { AgentWorkspaceMemoryCommandEditorKind } from './agent-workspace-memory-command-editors.ts';
4
4
  import { isAgentWorkspaceMemoryCommandEditorKind } from './agent-workspace-memory-command-editors.ts';
5
+ import type { AgentWorkspaceCommandEditorSubmission, AgentWorkspaceCommandSubmissionHandler, AgentWorkspaceFieldReader } from './agent-workspace-command-editor-engine.ts';
6
+ import { appendOptionalArg, buildCommandEditorSubmissionFromTable, dispatchCommandEditorSubmission, editorMessageSubmission, isAffirmative, splitCommaList } from './agent-workspace-command-editor-engine.ts';
5
7
 
6
- type AgentWorkspaceFieldReader = (fieldId: string) => string;
8
+ export type AgentWorkspaceMemoryCommandEditorSubmission = AgentWorkspaceCommandEditorSubmission;
7
9
 
8
- export type AgentWorkspaceMemoryCommandEditorSubmission =
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
- type MemoryDispatchSafety = AgentWorkspaceAction['safety'];
23
-
24
- function isAffirmative(value: string): boolean {
25
- return /^(y|yes|true)$/i.test(value.trim());
26
- }
27
-
28
- function splitCommaList(value: string): readonly string[] {
29
- return value.split(',').map((entry) => entry.trim()).filter(Boolean);
30
- }
31
-
32
- function unconfirmed(editor: AgentWorkspaceLocalEditor, label: string): AgentWorkspaceMemoryCommandEditorSubmission {
33
- return {
34
- kind: 'editor',
35
- editor: { ...editor, message: `${label} not confirmed. Type yes, then press Enter.` },
36
- status: `${label} not confirmed.`,
37
- };
38
- }
39
-
40
- function dispatch(
41
- command: string,
42
- title: string,
43
- status: string,
44
- detail: string,
45
- safety: MemoryDispatchSafety,
46
- ): AgentWorkspaceMemoryCommandEditorSubmission {
47
- return {
48
- kind: 'dispatch',
49
- command,
50
- status,
51
- actionResult: {
52
- kind: 'dispatched',
53
- title,
54
- detail,
55
- command,
56
- safety,
57
- },
58
- };
59
- }
60
-
61
- function appendOptional(parts: string[], flag: string, value: string): void {
62
- if (value.trim().length > 0) {
63
- parts.push(flag, quoteSlashCommandArg(value));
64
- }
10
+ function unconfirmed(editor: AgentWorkspaceLocalEditor, label: string): AgentWorkspaceCommandEditorSubmission {
11
+ return editorMessageSubmission(editor, `${label} not confirmed. Type yes, then press Enter.`, `${label} not confirmed.`);
65
12
  }
66
13
 
67
14
  function requireConfirmation(
68
15
  editor: AgentWorkspaceLocalEditor,
69
16
  readField: AgentWorkspaceFieldReader,
70
17
  label: string,
71
- ): AgentWorkspaceMemoryCommandEditorSubmission | null {
18
+ ): AgentWorkspaceCommandEditorSubmission | null {
72
19
  return isAffirmative(readField('confirm')) ? null : unconfirmed(editor, label);
73
20
  }
74
21
 
@@ -76,157 +23,135 @@ export function isAgentWorkspaceMemoryCommandSubmissionKind(kind: AgentWorkspace
76
23
  return isAgentWorkspaceMemoryCommandEditorKind(kind);
77
24
  }
78
25
 
79
- export function buildAgentWorkspaceMemoryCommandEditorSubmission(
80
- editor: AgentWorkspaceLocalEditor,
81
- readField: AgentWorkspaceFieldReader,
82
- ): AgentWorkspaceMemoryCommandEditorSubmission {
83
- if (editor.kind === 'memory-search') {
26
+ const MEMORY_COMMAND_SUBMISSION_HANDLERS: Readonly<Record<AgentWorkspaceMemoryCommandEditorKind, AgentWorkspaceCommandSubmissionHandler>> = {
27
+ 'memory-search': (_editor, readField) => {
84
28
  const parts = ['/memory', 'search'];
85
29
  const query = readField('query');
86
30
  if (query.length > 0) parts.push(quoteSlashCommandArg(query));
87
- appendOptional(parts, '--scope', readField('scope'));
88
- appendOptional(parts, '--cls', readField('class'));
89
- appendOptional(parts, '--limit', readField('limit'));
31
+ appendOptionalArg(parts, '--scope', readField('scope'));
32
+ appendOptionalArg(parts, '--cls', readField('class'));
33
+ appendOptionalArg(parts, '--limit', readField('limit'));
90
34
  if (isAffirmative(readField('semantic'))) parts.push('--semantic');
91
- const command = parts.join(' ');
92
- return dispatch(
93
- command,
35
+ return dispatchCommandEditorSubmission(
36
+ parts.join(' '),
94
37
  'Opening Agent memory search',
95
- 'Opening Agent memory search.',
96
38
  'The workspace handed an Agent-local memory search command to the shell-owned command router.',
97
39
  'read-only',
98
40
  );
99
- }
100
-
101
- if (editor.kind === 'memory-get') {
102
- const command = `/memory get ${quoteSlashCommandArg(readField('id'))}`;
103
- return dispatch(
104
- command,
105
- 'Opening Agent memory record',
106
- 'Opening Agent memory record.',
107
- 'The workspace handed an Agent-local memory lookup command to the shell-owned command router.',
108
- 'read-only',
109
- );
110
- }
111
-
112
- if (editor.kind === 'memory-explain') {
41
+ },
42
+ 'memory-get': (_editor, readField) => dispatchCommandEditorSubmission(
43
+ `/memory get ${quoteSlashCommandArg(readField('id'))}`,
44
+ 'Opening Agent memory record',
45
+ 'The workspace handed an Agent-local memory lookup command to the shell-owned command router.',
46
+ 'read-only',
47
+ ),
48
+ 'memory-explain': (_editor, readField) => {
113
49
  const parts = ['/memory', 'explain', quoteSlashCommandArg(readField('task'))];
114
50
  const scopes = splitCommaList(readField('scopes'));
115
51
  if (scopes.length > 0) {
116
52
  parts.push('--scope');
117
53
  for (const scope of scopes) parts.push(quoteSlashCommandArg(scope));
118
54
  }
119
- const command = parts.join(' ');
120
- return dispatch(
121
- command,
55
+ return dispatchCommandEditorSubmission(
56
+ parts.join(' '),
122
57
  'Opening Agent memory explanation',
123
- 'Opening Agent memory explanation.',
124
58
  'The workspace handed an Agent-local memory explanation command to the shell-owned command router.',
125
59
  'read-only',
126
60
  );
127
- }
128
-
129
- if (editor.kind === 'memory-promote') {
61
+ },
62
+ 'memory-promote': (editor, readField) => {
130
63
  const confirmation = requireConfirmation(editor, readField, 'Memory promotion');
131
64
  if (confirmation) return confirmation;
132
- const command = `/memory promote ${quoteSlashCommandArg(readField('id'))} ${quoteSlashCommandArg(readField('scope'))} --yes`;
133
- return dispatch(
134
- command,
65
+ return dispatchCommandEditorSubmission(
66
+ `/memory promote ${quoteSlashCommandArg(readField('id'))} ${quoteSlashCommandArg(readField('scope'))} --yes`,
135
67
  'Opening Agent memory promotion',
136
- 'Opening Agent memory promotion.',
137
68
  'The workspace handed a confirmed Agent-local memory promotion command to the shell-owned command router.',
138
69
  'safe',
139
70
  );
140
- }
141
-
142
- if (editor.kind === 'memory-link') {
71
+ },
72
+ 'memory-link': (editor, readField) => {
143
73
  const confirmation = requireConfirmation(editor, readField, 'Memory link');
144
74
  if (confirmation) return confirmation;
145
- const command = `/memory link ${quoteSlashCommandArg(readField('fromId'))} ${quoteSlashCommandArg(readField('toId'))} ${quoteSlashCommandArg(readField('relation'))} --yes`;
146
- return dispatch(
147
- command,
75
+ return dispatchCommandEditorSubmission(
76
+ `/memory link ${quoteSlashCommandArg(readField('fromId'))} ${quoteSlashCommandArg(readField('toId'))} ${quoteSlashCommandArg(readField('relation'))} --yes`,
148
77
  'Opening Agent memory link',
149
- 'Opening Agent memory link.',
150
78
  'The workspace handed a confirmed Agent-local memory link command to the shell-owned command router.',
151
79
  'safe',
152
80
  );
153
- }
154
-
155
- if (editor.kind === 'memory-export') {
81
+ },
82
+ 'memory-export': (editor, readField) => {
156
83
  const confirmation = requireConfirmation(editor, readField, 'Memory bundle export');
157
84
  if (confirmation) return confirmation;
158
85
  const parts = ['/memory', 'export', quoteSlashCommandArg(readField('path'))];
159
- appendOptional(parts, '--scope', readField('scope'));
160
- appendOptional(parts, '--cls', readField('class'));
86
+ appendOptionalArg(parts, '--scope', readField('scope'));
87
+ appendOptionalArg(parts, '--cls', readField('class'));
161
88
  parts.push('--yes');
162
- return dispatch(
89
+ return dispatchCommandEditorSubmission(
163
90
  parts.join(' '),
164
91
  'Opening Agent memory bundle export',
165
- 'Opening Agent memory bundle export.',
166
92
  'The workspace handed a confirmed Agent-local memory export command to the shell-owned command router.',
167
93
  'safe',
168
94
  );
169
- }
170
-
171
- if (editor.kind === 'memory-import') {
95
+ },
96
+ 'memory-import': (editor, readField) => {
172
97
  const confirmation = requireConfirmation(editor, readField, 'Memory bundle import');
173
98
  if (confirmation) return confirmation;
174
- const command = `/memory import ${quoteSlashCommandArg(readField('path'))} --yes`;
175
- return dispatch(
176
- command,
99
+ return dispatchCommandEditorSubmission(
100
+ `/memory import ${quoteSlashCommandArg(readField('path'))} --yes`,
177
101
  'Opening Agent memory bundle import',
178
- 'Opening Agent memory bundle import.',
179
102
  'The workspace handed a confirmed Agent-local memory import command to the shell-owned command router.',
180
103
  'safe',
181
104
  );
182
- }
183
-
184
- if (editor.kind === 'memory-handoff-export') {
105
+ },
106
+ 'memory-handoff-export': (editor, readField) => {
185
107
  const confirmation = requireConfirmation(editor, readField, 'Memory handoff export');
186
108
  if (confirmation) return confirmation;
187
109
  const parts = ['/memory', 'handoff-export', quoteSlashCommandArg(readField('path'))];
188
- appendOptional(parts, '--scope', readField('scope'));
110
+ appendOptionalArg(parts, '--scope', readField('scope'));
189
111
  parts.push('--yes');
190
- return dispatch(
112
+ return dispatchCommandEditorSubmission(
191
113
  parts.join(' '),
192
114
  'Opening Agent memory handoff export',
193
- 'Opening Agent memory handoff export.',
194
115
  'The workspace handed a confirmed Agent-local memory handoff export command to the shell-owned command router.',
195
116
  'safe',
196
117
  );
197
- }
198
-
199
- if (editor.kind === 'memory-handoff-inspect') {
200
- const command = `/memory handoff-inspect ${quoteSlashCommandArg(readField('path'))}`;
201
- return dispatch(
202
- command,
203
- 'Opening Agent memory handoff inspection',
204
- 'Opening Agent memory handoff inspection.',
205
- 'The workspace handed an Agent-local memory handoff inspection command to the shell-owned command router.',
206
- 'read-only',
207
- );
208
- }
209
-
210
- if (editor.kind === 'memory-handoff-import') {
118
+ },
119
+ 'memory-handoff-inspect': (_editor, readField) => dispatchCommandEditorSubmission(
120
+ `/memory handoff-inspect ${quoteSlashCommandArg(readField('path'))}`,
121
+ 'Opening Agent memory handoff inspection',
122
+ 'The workspace handed an Agent-local memory handoff inspection command to the shell-owned command router.',
123
+ 'read-only',
124
+ ),
125
+ 'memory-handoff-import': (editor, readField) => {
211
126
  const confirmation = requireConfirmation(editor, readField, 'Memory handoff import');
212
127
  if (confirmation) return confirmation;
213
- const command = `/memory handoff-import ${quoteSlashCommandArg(readField('path'))} --yes`;
214
- return dispatch(
215
- command,
128
+ return dispatchCommandEditorSubmission(
129
+ `/memory handoff-import ${quoteSlashCommandArg(readField('path'))} --yes`,
216
130
  'Opening Agent memory handoff import',
217
- 'Opening Agent memory handoff import.',
218
131
  'The workspace handed a confirmed Agent-local memory handoff import command to the shell-owned command router.',
219
132
  'safe',
220
133
  );
221
- }
134
+ },
135
+ 'memory-vector-rebuild': (editor, readField) => {
136
+ const confirmation = requireConfirmation(editor, readField, 'Memory vector rebuild');
137
+ if (confirmation) return confirmation;
138
+ return dispatchCommandEditorSubmission(
139
+ '/memory vector rebuild',
140
+ 'Opening Agent memory vector rebuild',
141
+ 'The workspace handed a confirmed Agent-local memory vector rebuild command to the shell-owned command router.',
142
+ 'safe',
143
+ );
144
+ },
145
+ };
222
146
 
223
- const confirmation = requireConfirmation(editor, readField, 'Memory vector rebuild');
224
- if (confirmation) return confirmation;
225
- return dispatch(
226
- '/memory vector rebuild',
227
- 'Opening Agent memory vector rebuild',
228
- 'Opening Agent memory vector rebuild.',
229
- 'The workspace handed a confirmed Agent-local memory vector rebuild command to the shell-owned command router.',
230
- 'safe',
147
+ export function buildAgentWorkspaceMemoryCommandEditorSubmission(
148
+ editor: AgentWorkspaceLocalEditor,
149
+ readField: AgentWorkspaceFieldReader,
150
+ ): AgentWorkspaceCommandEditorSubmission {
151
+ return buildCommandEditorSubmissionFromTable(
152
+ editor.kind as AgentWorkspaceMemoryCommandEditorKind,
153
+ editor,
154
+ readField,
155
+ MEMORY_COMMAND_SUBMISSION_HANDLERS,
231
156
  );
232
157
  }