@pellux/goodvibes-agent 0.1.114 → 0.1.117

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 (168) hide show
  1. package/CHANGELOG.md +41 -650
  2. package/README.md +40 -50
  3. package/dist/package/main.js +38224 -35673
  4. package/docs/README.md +5 -4
  5. package/docs/{connected-services.md → connected-host.md} +18 -10
  6. package/docs/getting-started.md +43 -42
  7. package/docs/release-and-publishing.md +6 -4
  8. package/package.json +3 -3
  9. package/src/agent/behavior-discovery-summary.ts +165 -0
  10. package/src/agent/persona-discovery.ts +1 -3
  11. package/src/agent/persona-registry.ts +5 -3
  12. package/src/agent/reminder-schedule-format.ts +6 -6
  13. package/src/agent/reminder-schedule.ts +1 -1
  14. package/src/agent/routine-registry.ts +43 -4
  15. package/src/agent/routine-schedule-format.ts +6 -6
  16. package/src/agent/routine-schedule-promotion.ts +1 -1
  17. package/src/agent/routine-schedule-receipts.ts +1 -1
  18. package/src/agent/runtime-profile-starters.ts +331 -0
  19. package/src/agent/runtime-profile.ts +228 -330
  20. package/src/agent/skill-registry.ts +190 -13
  21. package/src/cli/agent-knowledge-command.ts +2 -2
  22. package/src/cli/agent-knowledge-format.ts +2 -2
  23. package/src/cli/agent-knowledge-runtime.ts +1 -1
  24. package/src/cli/bundle-command.ts +1 -1
  25. package/src/cli/entrypoint.ts +16 -7
  26. package/src/cli/help.ts +26 -19
  27. package/src/cli/local-library-command.ts +75 -21
  28. package/src/cli/management-commands.ts +7 -6
  29. package/src/cli/management.ts +6 -51
  30. package/src/cli/parser.ts +23 -2
  31. package/src/cli/profiles-command.ts +247 -1
  32. package/src/cli/routines-command.ts +139 -11
  33. package/src/cli/service-posture.ts +11 -11
  34. package/src/cli/status.ts +21 -25
  35. package/src/input/agent-workspace-access-command-editor-submission.ts +149 -0
  36. package/src/input/agent-workspace-access-command-editors.ts +170 -0
  37. package/src/input/agent-workspace-activation.ts +2 -1
  38. package/src/input/agent-workspace-basic-command-editor-submission.ts +787 -0
  39. package/src/input/agent-workspace-basic-command-editors.ts +524 -459
  40. package/src/input/agent-workspace-categories.ts +177 -14
  41. package/src/input/agent-workspace-channel-command-editor-submission.ts +49 -0
  42. package/src/input/agent-workspace-channel-command-editors.ts +47 -0
  43. package/src/input/agent-workspace-command-editor.ts +25 -1
  44. package/src/input/agent-workspace-delegation-editor-submission.ts +55 -0
  45. package/src/input/agent-workspace-editors.ts +27 -0
  46. package/src/input/agent-workspace-knowledge-command-editor-submission.ts +132 -0
  47. package/src/input/agent-workspace-knowledge-command-editors.ts +110 -0
  48. package/src/input/agent-workspace-learned-behavior.ts +67 -0
  49. package/src/input/agent-workspace-library-command-editor-submission.ts +50 -0
  50. package/src/input/agent-workspace-library-command-editors.ts +35 -0
  51. package/src/input/agent-workspace-mcp-command-editor-submission.ts +95 -0
  52. package/src/input/agent-workspace-memory-command-editor-submission.ts +232 -0
  53. package/src/input/agent-workspace-memory-command-editors.ts +180 -0
  54. package/src/input/agent-workspace-navigation.ts +45 -0
  55. package/src/input/agent-workspace-notify-editor-submission.ts +107 -0
  56. package/src/input/agent-workspace-operations-command-editor-submission.ts +146 -0
  57. package/src/input/agent-workspace-operations-command-editors.ts +119 -0
  58. package/src/input/agent-workspace-provider-command-editor-submission.ts +155 -0
  59. package/src/input/agent-workspace-provider-command-editors.ts +93 -0
  60. package/src/input/agent-workspace-requirements.ts +11 -0
  61. package/src/input/agent-workspace-secret-editor-submission.ts +153 -0
  62. package/src/input/agent-workspace-session-command-editor-submission.ts +199 -0
  63. package/src/input/agent-workspace-session-command-editors.ts +249 -0
  64. package/src/input/agent-workspace-setup.ts +49 -19
  65. package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +101 -0
  66. package/src/input/agent-workspace-skill-bundle-command-editors.ts +110 -0
  67. package/src/input/agent-workspace-snapshot.ts +56 -8
  68. package/src/input/agent-workspace-task-command-editor-submission.ts +61 -0
  69. package/src/input/agent-workspace-task-command-editors.ts +47 -0
  70. package/src/input/agent-workspace-types.ts +124 -0
  71. package/src/input/agent-workspace-voice-media.ts +1 -1
  72. package/src/input/agent-workspace-workplan-editor-submission.ts +153 -0
  73. package/src/input/agent-workspace.ts +47 -37
  74. package/src/input/command-registry.ts +1 -1
  75. package/src/input/commands/agent-runtime-profile-runtime.ts +160 -6
  76. package/src/input/commands/agent-skills-runtime.ts +76 -12
  77. package/src/input/commands/agent-workspace-runtime.ts +4 -3
  78. package/src/input/commands/brief-runtime.ts +38 -9
  79. package/src/input/commands/channels-runtime.ts +3 -3
  80. package/src/input/commands/compat-runtime.ts +32 -0
  81. package/src/input/commands/health-runtime.ts +22 -24
  82. package/src/input/commands/knowledge.ts +26 -5
  83. package/src/input/commands/local-provider-runtime.ts +7 -3
  84. package/src/input/commands/local-setup-review.ts +4 -14
  85. package/src/input/commands/mcp-runtime.ts +8 -12
  86. package/src/input/commands/operator-runtime.ts +8 -67
  87. package/src/input/commands/personas-runtime.ts +1 -1
  88. package/src/input/commands/platform-access-runtime.ts +7 -70
  89. package/src/input/commands/policy-dispatch.ts +1 -1
  90. package/src/input/commands/policy.ts +1 -5
  91. package/src/input/commands/product-runtime.ts +2 -2
  92. package/src/input/commands/qrcode-runtime.ts +6 -4
  93. package/src/input/commands/routines-runtime.ts +44 -6
  94. package/src/input/commands/runtime-services.ts +1 -14
  95. package/src/input/commands/security-runtime.ts +3 -8
  96. package/src/input/commands/session-content.ts +1 -1
  97. package/src/input/commands/session-workflow.ts +5 -14
  98. package/src/input/commands/shell-core.ts +8 -2
  99. package/src/input/commands/subscription-runtime.ts +1 -6
  100. package/src/input/commands/support-bundle-runtime.ts +53 -0
  101. package/src/input/commands/tasks-runtime.ts +2 -2
  102. package/src/input/commands.ts +4 -0
  103. package/src/input/feed-context-factory.ts +0 -1
  104. package/src/input/handler-content-actions.ts +0 -25
  105. package/src/input/handler-feed.ts +0 -2
  106. package/src/input/handler-interactions.ts +2 -31
  107. package/src/input/handler-onboarding.ts +29 -12
  108. package/src/input/handler-shortcuts.ts +1 -3
  109. package/src/input/handler.ts +4 -7
  110. package/src/input/keybindings.ts +9 -9
  111. package/src/input/mcp-workspace.ts +90 -26
  112. package/src/input/onboarding/handler-onboarding-routes.ts +3 -1
  113. package/src/input/onboarding/onboarding-wizard-apply.ts +49 -0
  114. package/src/input/onboarding/onboarding-wizard-helpers.ts +1 -1
  115. package/src/input/onboarding/onboarding-wizard-operator-steps.ts +126 -11
  116. package/src/input/onboarding/onboarding-wizard-steps.ts +15 -8
  117. package/src/input/onboarding/onboarding-wizard-types.ts +1 -0
  118. package/src/input/onboarding/onboarding-wizard.ts +19 -2
  119. package/src/input/profile-picker-modal.ts +2 -2
  120. package/src/input/settings-modal-agent-policy.ts +6 -6
  121. package/src/input/settings-modal-subscriptions.ts +3 -3
  122. package/src/input/settings-modal.ts +14 -14
  123. package/src/main.ts +0 -2
  124. package/src/panels/automation-control-panel.ts +3 -3
  125. package/src/panels/builtin/agent.ts +1 -1
  126. package/src/panels/builtin/operations.ts +2 -2
  127. package/src/panels/builtin/session.ts +26 -18
  128. package/src/panels/builtin/shared.ts +6 -6
  129. package/src/panels/project-planning-panel.ts +1 -1
  130. package/src/panels/provider-health-domains.ts +3 -3
  131. package/src/panels/qr-panel.ts +44 -20
  132. package/src/panels/subscription-panel.ts +3 -3
  133. package/src/panels/system-messages-panel.ts +2 -2
  134. package/src/panels/tasks-panel.ts +4 -4
  135. package/src/planning/project-planning-coordinator.ts +2 -2
  136. package/src/renderer/agent-workspace.ts +52 -5
  137. package/src/renderer/block-actions.ts +1 -3
  138. package/src/renderer/help-overlay.ts +13 -8
  139. package/src/renderer/mcp-workspace.ts +32 -13
  140. package/src/renderer/model-picker-overlay.ts +0 -1
  141. package/src/renderer/model-workspace.ts +0 -2
  142. package/src/renderer/onboarding/onboarding-wizard.ts +20 -4
  143. package/src/renderer/panel-picker-overlay.ts +1 -1
  144. package/src/renderer/profile-picker-modal.ts +2 -2
  145. package/src/renderer/settings-modal-helpers.ts +23 -23
  146. package/src/renderer/settings-modal.ts +18 -18
  147. package/src/renderer/system-message.ts +1 -1
  148. package/src/runtime/agent-runtime-events.ts +129 -0
  149. package/src/runtime/bootstrap-command-parts.ts +3 -2
  150. package/src/runtime/bootstrap-core.ts +4 -64
  151. package/src/runtime/bootstrap-shell.ts +42 -4
  152. package/src/runtime/bootstrap.ts +8 -27
  153. package/src/runtime/connected-host-auth.ts +42 -0
  154. package/src/runtime/diagnostics/panels/panel-resources.ts +1 -1
  155. package/src/runtime/index.ts +1 -5
  156. package/src/runtime/onboarding/apply.ts +213 -0
  157. package/src/runtime/onboarding/derivation.ts +25 -6
  158. package/src/runtime/onboarding/snapshot.ts +4 -2
  159. package/src/runtime/onboarding/types.ts +28 -1
  160. package/src/runtime/onboarding/verify.ts +81 -2
  161. package/src/runtime/operator-token-cleanup.ts +2 -2
  162. package/src/runtime/services.ts +27 -12
  163. package/src/shell/service-settings-sync.ts +7 -7
  164. package/src/shell/ui-openers.ts +27 -38
  165. package/src/tools/agent-local-registry-tool.ts +10 -4
  166. package/src/tools/agent-tool-policy-guard.ts +5 -7
  167. package/src/version.ts +1 -1
  168. package/src/cli/package-verification.ts +0 -274
@@ -0,0 +1,199 @@
1
+ import type { AgentWorkspaceActionResult, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
2
+ import type { AgentWorkspaceSessionCommandEditorKind } from './agent-workspace-session-command-editors.ts';
3
+ import { isAgentWorkspaceSessionCommandEditorKind } from './agent-workspace-session-command-editors.ts';
4
+ import { quoteSlashCommandArg } from './slash-command-parser.ts';
5
+
6
+ type AgentWorkspaceFieldReader = (fieldId: string) => string;
7
+
8
+ export type AgentWorkspaceSessionCommandEditorSubmission =
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
+ export function isAgentWorkspaceSessionCommandSubmissionKind(kind: string): kind is AgentWorkspaceSessionCommandEditorKind {
23
+ return isAgentWorkspaceSessionCommandEditorKind(kind as AgentWorkspaceSessionCommandEditorKind);
24
+ }
25
+
26
+ function isAffirmative(value: string): boolean {
27
+ return /^(y|yes|true)$/i.test(value.trim());
28
+ }
29
+
30
+ function unconfirmed(editor: AgentWorkspaceLocalEditor, message: string): AgentWorkspaceSessionCommandEditorSubmission {
31
+ return {
32
+ kind: 'editor',
33
+ editor: { ...editor, message },
34
+ status: message,
35
+ };
36
+ }
37
+
38
+ function dispatch(command: string, title: string, detail: string, safety: AgentWorkspaceActionResult['safety']): AgentWorkspaceSessionCommandEditorSubmission {
39
+ return {
40
+ kind: 'dispatch',
41
+ command,
42
+ status: `${title}.`,
43
+ actionResult: { kind: 'dispatched', title, detail, command, safety },
44
+ };
45
+ }
46
+
47
+ export function buildAgentWorkspaceSessionCommandEditorSubmission(
48
+ editor: AgentWorkspaceLocalEditor,
49
+ readField: AgentWorkspaceFieldReader,
50
+ ): AgentWorkspaceSessionCommandEditorSubmission {
51
+ if (editor.kind === 'conversation-export') {
52
+ if (!isAffirmative(readField('confirm'))) return unconfirmed(editor, 'Conversation export not confirmed. Type yes, then press Enter.');
53
+ return dispatch(
54
+ `/export ${quoteSlashCommandArg(readField('format'))} ${quoteSlashCommandArg(readField('path'))} --yes`,
55
+ 'Opening conversation export',
56
+ 'The workspace handed a confirmed conversation export command to the shell-owned command router.',
57
+ 'safe',
58
+ );
59
+ }
60
+ if (editor.kind === 'conversation-events' || editor.kind === 'conversation-groups') {
61
+ const subcommand = editor.kind === 'conversation-groups' ? 'groups' : 'events';
62
+ const eventKind = readField('kind');
63
+ const command = eventKind.length > 0
64
+ ? `/conversation ${subcommand} ${quoteSlashCommandArg(eventKind)}`
65
+ : `/conversation ${subcommand}`;
66
+ return dispatch(
67
+ command,
68
+ editor.kind === 'conversation-groups' ? 'Opening transcript groups' : 'Opening transcript events',
69
+ 'The workspace handed read-only transcript structure inspection to the shell-owned command router.',
70
+ 'read-only',
71
+ );
72
+ }
73
+ if (editor.kind === 'conversation-find') {
74
+ const kind = readField('kind');
75
+ const command = kind.length > 0
76
+ ? `/conversation find ${quoteSlashCommandArg(readField('query'))} ${quoteSlashCommandArg(kind)}`
77
+ : `/conversation find ${quoteSlashCommandArg(readField('query'))}`;
78
+ return dispatch(
79
+ command,
80
+ 'Opening transcript search',
81
+ 'The workspace handed read-only transcript search to the shell-owned command router.',
82
+ 'read-only',
83
+ );
84
+ }
85
+ if (editor.kind === 'effort-level') {
86
+ return dispatch(
87
+ `/effort ${quoteSlashCommandArg(readField('level'))}`,
88
+ 'Opening reasoning effort change',
89
+ 'The workspace handed reasoning effort selection to the shell-owned command router.',
90
+ 'safe',
91
+ );
92
+ }
93
+ if (editor.kind === 'session-save') {
94
+ if (!isAffirmative(readField('confirm'))) return unconfirmed(editor, 'Session save not confirmed. Type yes, then press Enter.');
95
+ return dispatch(
96
+ `/save ${quoteSlashCommandArg(readField('name'))}`,
97
+ 'Opening session save',
98
+ 'The workspace handed a confirmed session save command to the shell-owned command router.',
99
+ 'safe',
100
+ );
101
+ }
102
+ if (editor.kind === 'session-load') {
103
+ if (!isAffirmative(readField('confirm'))) return unconfirmed(editor, 'Session load not confirmed. Type yes, then press Enter.');
104
+ return dispatch(
105
+ `/load ${quoteSlashCommandArg(readField('name'))}`,
106
+ 'Opening session load',
107
+ 'The workspace handed a confirmed session load command to the shell-owned command router.',
108
+ 'safe',
109
+ );
110
+ }
111
+ if (editor.kind === 'session-rename') {
112
+ return dispatch(
113
+ `/session rename ${quoteSlashCommandArg(readField('name'))}`,
114
+ 'Opening session rename',
115
+ 'The workspace handed current-session rename to the shell-owned command router.',
116
+ 'safe',
117
+ );
118
+ }
119
+ if (editor.kind === 'session-resume') {
120
+ return dispatch(
121
+ `/session resume ${quoteSlashCommandArg(readField('target'))}`,
122
+ 'Opening session resume',
123
+ 'The workspace handed saved-session resume to the shell-owned command router.',
124
+ 'safe',
125
+ );
126
+ }
127
+ if (editor.kind === 'session-info') {
128
+ return dispatch(
129
+ `/session info ${quoteSlashCommandArg(readField('target'))}`,
130
+ 'Opening session inspection',
131
+ 'The workspace handed read-only saved-session inspection to the shell-owned command router.',
132
+ 'read-only',
133
+ );
134
+ }
135
+ if (editor.kind === 'session-export-saved') {
136
+ return dispatch(
137
+ `/session export ${quoteSlashCommandArg(readField('target'))} ${quoteSlashCommandArg(readField('format'))}`,
138
+ 'Opening saved-session export',
139
+ 'The workspace handed saved-session transcript export to the shell-owned command router.',
140
+ 'read-only',
141
+ );
142
+ }
143
+ if (editor.kind === 'session-search') {
144
+ return dispatch(
145
+ `/session search ${quoteSlashCommandArg(readField('query'))}`,
146
+ 'Opening saved-session search',
147
+ 'The workspace handed saved-session search to the shell-owned command router.',
148
+ 'read-only',
149
+ );
150
+ }
151
+ if (editor.kind === 'session-delete') {
152
+ if (!isAffirmative(readField('confirm'))) return unconfirmed(editor, 'Session delete not confirmed. Type yes, then press Enter.');
153
+ return dispatch(
154
+ `/session delete ${quoteSlashCommandArg(readField('target'))} --yes`,
155
+ 'Opening saved-session delete',
156
+ 'The workspace handed confirmed saved-session deletion to the shell-owned command router.',
157
+ 'safe',
158
+ );
159
+ }
160
+ if (editor.kind === 'session-fork') {
161
+ const name = readField('name');
162
+ return dispatch(
163
+ name.length > 0 ? `/session fork ${quoteSlashCommandArg(name)}` : '/session fork',
164
+ 'Opening session fork',
165
+ 'The workspace handed current-session fork to the shell-owned command router.',
166
+ 'safe',
167
+ );
168
+ }
169
+ if (editor.kind === 'session-graph') {
170
+ const sessionId = readField('sessionId');
171
+ const format = readField('format');
172
+ const parts = ['/session', 'graph'];
173
+ if (sessionId.length > 0) parts.push('--session', quoteSlashCommandArg(sessionId));
174
+ if (format.length > 0) parts.push('--format', quoteSlashCommandArg(format));
175
+ const command = parts.join(' ');
176
+ return dispatch(
177
+ command,
178
+ 'Opening session graph',
179
+ 'The workspace handed read-only session graph inspection to the shell-owned command router.',
180
+ 'read-only',
181
+ );
182
+ }
183
+ if (editor.kind === 'mode-preset') {
184
+ if (!isAffirmative(readField('confirm'))) return unconfirmed(editor, 'Interaction mode change not confirmed. Type yes, then press Enter.');
185
+ return dispatch(
186
+ `/mode ${quoteSlashCommandArg(readField('preset'))} --yes`,
187
+ 'Opening interaction mode change',
188
+ 'The workspace handed a confirmed interaction mode command to the shell-owned command router.',
189
+ 'safe',
190
+ );
191
+ }
192
+ if (!isAffirmative(readField('confirm'))) return unconfirmed(editor, 'Domain verbosity change not confirmed. Type yes, then press Enter.');
193
+ return dispatch(
194
+ `/mode set-domain ${quoteSlashCommandArg(readField('domain'))} ${quoteSlashCommandArg(readField('verbosity'))} --yes`,
195
+ 'Opening domain verbosity change',
196
+ 'The workspace handed a confirmed domain verbosity command to the shell-owned command router.',
197
+ 'safe',
198
+ );
199
+ }
@@ -0,0 +1,249 @@
1
+ import type { AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
2
+
3
+ export type AgentWorkspaceSessionCommandEditorKind = Extract<
4
+ AgentWorkspaceEditorKind,
5
+ | 'conversation-export'
6
+ | 'conversation-events'
7
+ | 'conversation-groups'
8
+ | 'conversation-find'
9
+ | 'effort-level'
10
+ | 'session-save'
11
+ | 'session-load'
12
+ | 'session-rename'
13
+ | 'session-resume'
14
+ | 'session-info'
15
+ | 'session-export-saved'
16
+ | 'session-search'
17
+ | 'session-delete'
18
+ | 'session-fork'
19
+ | 'session-graph'
20
+ | 'mode-preset'
21
+ | 'mode-domain'
22
+ >;
23
+
24
+ export function isAgentWorkspaceSessionCommandEditorKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceSessionCommandEditorKind {
25
+ return kind === 'conversation-export'
26
+ || kind === 'conversation-events'
27
+ || kind === 'conversation-groups'
28
+ || kind === 'conversation-find'
29
+ || kind === 'effort-level'
30
+ || kind === 'session-save'
31
+ || kind === 'session-load'
32
+ || kind === 'session-rename'
33
+ || kind === 'session-resume'
34
+ || kind === 'session-info'
35
+ || kind === 'session-export-saved'
36
+ || kind === 'session-search'
37
+ || kind === 'session-delete'
38
+ || kind === 'session-fork'
39
+ || kind === 'session-graph'
40
+ || kind === 'mode-preset'
41
+ || kind === 'mode-domain';
42
+ }
43
+
44
+ export function createAgentWorkspaceSessionCommandEditor(kind: AgentWorkspaceSessionCommandEditorKind): AgentWorkspaceLocalEditor {
45
+ if (kind === 'conversation-export') {
46
+ return {
47
+ kind,
48
+ mode: 'create',
49
+ title: 'Export Conversation',
50
+ selectedFieldIndex: 0,
51
+ message: 'Export the current conversation to a workspace file. Type yes on the final field to confirm.',
52
+ fields: [
53
+ { id: 'format', label: 'Format', value: 'markdown', required: true, multiline: false, hint: 'markdown or text.' },
54
+ { id: 'path', label: 'Output path', value: './conversation.md', required: true, multiline: false, hint: 'Workspace-relative output path.' },
55
+ { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /export with --yes.' },
56
+ ],
57
+ };
58
+ }
59
+ if (kind === 'conversation-events' || kind === 'conversation-groups') {
60
+ const groups = kind === 'conversation-groups';
61
+ return {
62
+ kind,
63
+ mode: 'create',
64
+ title: groups ? 'Show Transcript Groups' : 'Show Transcript Events',
65
+ selectedFieldIndex: 0,
66
+ message: groups
67
+ ? 'Inspect grouped transcript structure from the Agent workspace.'
68
+ : 'Inspect transcript events from the Agent workspace.',
69
+ fields: [
70
+ { id: 'kind', label: 'Event kind', value: '', required: false, multiline: false, hint: 'Optional transcript event kind. Blank shows all.' },
71
+ ],
72
+ };
73
+ }
74
+ if (kind === 'conversation-find') {
75
+ return {
76
+ kind,
77
+ mode: 'create',
78
+ title: 'Find Transcript Text',
79
+ selectedFieldIndex: 0,
80
+ message: 'Search the current Agent transcript from the workspace.',
81
+ fields: [
82
+ { id: 'query', label: 'Search query', value: '', required: true, multiline: false, hint: 'Text to find in the current transcript.' },
83
+ { id: 'kind', label: 'Event kind', value: '', required: false, multiline: false, hint: 'Optional transcript event kind.' },
84
+ ],
85
+ };
86
+ }
87
+ if (kind === 'effort-level') {
88
+ return {
89
+ kind,
90
+ mode: 'update',
91
+ title: 'Set Reasoning Effort',
92
+ selectedFieldIndex: 0,
93
+ message: 'Set the reasoning effort used by normal Agent chat turns when the selected model supports it.',
94
+ fields: [
95
+ { id: 'level', label: 'Effort level', value: 'medium', required: true, multiline: false, hint: 'instant, low, medium, or high.' },
96
+ ],
97
+ };
98
+ }
99
+ if (kind === 'session-save') {
100
+ return {
101
+ kind,
102
+ mode: 'create',
103
+ title: 'Save Session',
104
+ selectedFieldIndex: 0,
105
+ message: 'Save the current Agent session under a reviewable name. Type yes on the final field to confirm.',
106
+ fields: [
107
+ { id: 'name', label: 'Session name', value: '', required: true, multiline: false, hint: 'Local saved-session name.' },
108
+ { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /save.' },
109
+ ],
110
+ };
111
+ }
112
+ if (kind === 'session-load') {
113
+ return {
114
+ kind,
115
+ mode: 'update',
116
+ title: 'Load Session',
117
+ selectedFieldIndex: 0,
118
+ message: 'Load a saved Agent session into the current conversation. Type yes on the final field to confirm.',
119
+ fields: [
120
+ { id: 'name', label: 'Session name', value: '', required: true, multiline: false, hint: 'Existing saved-session name from /sessions.' },
121
+ { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /load.' },
122
+ ],
123
+ };
124
+ }
125
+ if (kind === 'session-rename') {
126
+ return {
127
+ kind,
128
+ mode: 'update',
129
+ title: 'Rename Current Session',
130
+ selectedFieldIndex: 0,
131
+ message: 'Rename the active Agent session from the workspace.',
132
+ fields: [
133
+ { id: 'name', label: 'New session name', value: '', required: true, multiline: false, hint: 'New reviewable name for the current session.' },
134
+ ],
135
+ };
136
+ }
137
+ if (kind === 'session-resume') {
138
+ return {
139
+ kind,
140
+ mode: 'update',
141
+ title: 'Resume Saved Session',
142
+ selectedFieldIndex: 0,
143
+ message: 'Resume one saved Agent session by id, prefix, or title.',
144
+ fields: [
145
+ { id: 'target', label: 'Session id or name', value: '', required: true, multiline: false, hint: 'Use /session list or the Saved sessions action to find ids.' },
146
+ ],
147
+ };
148
+ }
149
+ if (kind === 'session-info') {
150
+ return {
151
+ kind,
152
+ mode: 'create',
153
+ title: 'Inspect Saved Session',
154
+ selectedFieldIndex: 0,
155
+ message: 'Inspect saved session metadata without changing the current conversation.',
156
+ fields: [
157
+ { id: 'target', label: 'Session id or name', value: '', required: true, multiline: false, hint: 'Saved session id, prefix, or name.' },
158
+ ],
159
+ };
160
+ }
161
+ if (kind === 'session-export-saved') {
162
+ return {
163
+ kind,
164
+ mode: 'create',
165
+ title: 'Export Saved Session',
166
+ selectedFieldIndex: 0,
167
+ message: 'Print one saved session transcript as markdown or text.',
168
+ fields: [
169
+ { id: 'target', label: 'Session id or name', value: '', required: true, multiline: false, hint: 'Use . for the current session, or a saved session id/name.' },
170
+ { id: 'format', label: 'Format', value: 'markdown', required: true, multiline: false, hint: 'markdown or text.' },
171
+ ],
172
+ };
173
+ }
174
+ if (kind === 'session-search') {
175
+ return {
176
+ kind,
177
+ mode: 'create',
178
+ title: 'Search Saved Sessions',
179
+ selectedFieldIndex: 0,
180
+ message: 'Search saved Agent sessions from the workspace.',
181
+ fields: [
182
+ { id: 'query', label: 'Search query', value: '', required: true, multiline: false, hint: 'Keyword or phrase to find in saved sessions.' },
183
+ ],
184
+ };
185
+ }
186
+ if (kind === 'session-delete') {
187
+ return {
188
+ kind,
189
+ mode: 'delete',
190
+ title: 'Delete Saved Session',
191
+ selectedFieldIndex: 0,
192
+ message: 'Delete one saved Agent session. Type yes on the final field to confirm.',
193
+ fields: [
194
+ { id: 'target', label: 'Session id or name', value: '', required: true, multiline: false, hint: 'Saved session id or prefix. The active session cannot be deleted.' },
195
+ { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /session delete with --yes.' },
196
+ ],
197
+ };
198
+ }
199
+ if (kind === 'session-fork') {
200
+ return {
201
+ kind,
202
+ mode: 'create',
203
+ title: 'Fork Current Session',
204
+ selectedFieldIndex: 0,
205
+ message: 'Fork the current Agent session into a new local saved session.',
206
+ fields: [
207
+ { id: 'name', label: 'Fork name', value: '', required: false, multiline: false, hint: 'Optional new session name. Blank uses the default fork name.' },
208
+ ],
209
+ };
210
+ }
211
+ if (kind === 'session-graph') {
212
+ return {
213
+ kind,
214
+ mode: 'create',
215
+ title: 'Inspect Session Graph',
216
+ selectedFieldIndex: 0,
217
+ message: 'Inspect the read-only cross-session graph. Mutating graph actions remain blocked in Agent.',
218
+ fields: [
219
+ { id: 'sessionId', label: 'Session id', value: '', required: false, multiline: false, hint: 'Optional session id filter.' },
220
+ { id: 'format', label: 'Format', value: 'text', required: false, multiline: false, hint: 'text or json.' },
221
+ ],
222
+ };
223
+ }
224
+ if (kind === 'mode-preset') {
225
+ return {
226
+ kind,
227
+ mode: 'update',
228
+ title: 'Set Interaction Mode',
229
+ selectedFieldIndex: 0,
230
+ message: 'Set the Agent interaction noise level. Type yes on the final field to confirm.',
231
+ fields: [
232
+ { id: 'preset', label: 'Preset', value: 'balanced', required: true, multiline: false, hint: 'quiet, balanced, or operator.' },
233
+ { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /mode <preset> with --yes.' },
234
+ ],
235
+ };
236
+ }
237
+ return {
238
+ kind,
239
+ mode: 'update',
240
+ title: 'Set Domain Verbosity',
241
+ selectedFieldIndex: 0,
242
+ message: 'Set interaction verbosity for one notification domain. Type yes on the final field to confirm.',
243
+ fields: [
244
+ { id: 'domain', label: 'Domain', value: '', required: true, multiline: false, hint: 'Domain name from mode output.' },
245
+ { id: 'verbosity', label: 'Verbosity', value: 'normal', required: true, multiline: false, hint: 'minimal, normal, or verbose.' },
246
+ { id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /mode set-domain.' },
247
+ ],
248
+ };
249
+ }
@@ -1,3 +1,5 @@
1
+ import type { AgentBehaviorDiscoverySummary } from '../agent/behavior-discovery-summary.ts';
2
+
1
3
  export type AgentWorkspaceSetupStatus = 'ready' | 'recommended' | 'optional' | 'blocked';
2
4
 
3
5
  export interface AgentWorkspaceSetupChecklistItem {
@@ -17,11 +19,16 @@ export interface AgentWorkspaceSetupChecklistInput {
17
19
  readonly localMemoryReviewQueueCount: number;
18
20
  readonly routineCount: number;
19
21
  readonly enabledRoutineCount: number;
22
+ readonly missingRoutineRequirementCount: number;
20
23
  readonly skillCount: number;
21
24
  readonly enabledSkillCount: number;
22
25
  readonly skillBundleCount: number;
23
26
  readonly enabledSkillBundleCount: number;
27
+ readonly missingSkillRequirementCount: number;
24
28
  readonly activePersonaName: string;
29
+ readonly discoveredPersonas: AgentBehaviorDiscoverySummary;
30
+ readonly discoveredSkills: AgentBehaviorDiscoverySummary;
31
+ readonly discoveredRoutines: AgentBehaviorDiscoverySummary;
25
32
  readonly readyChannelCount: number;
26
33
  readonly voiceProviderCount: number;
27
34
  readonly mediaProviderCount: number;
@@ -33,13 +40,20 @@ function setupStatusForCount(count: number, ready: AgentWorkspaceSetupStatus, em
33
40
  return count > 0 ? ready : empty;
34
41
  }
35
42
 
43
+ function sampleNames(summary: AgentBehaviorDiscoverySummary): string {
44
+ if (summary.names.length === 0) return '';
45
+ const suffix = summary.count > summary.names.length ? `, +${summary.count - summary.names.length} more` : '';
46
+ return ` Found: ${summary.names.join(', ')}${suffix}.`;
47
+ }
48
+
36
49
  export function buildAgentWorkspaceSetupChecklist(input: AgentWorkspaceSetupChecklistInput): readonly AgentWorkspaceSetupChecklistItem[] {
37
50
  const providerReady = input.provider !== 'unknown' && input.model !== 'unknown';
38
51
  const hasActivePersona = input.activePersonaName !== '(none)' && input.activePersonaName !== '(unavailable)';
52
+ const discoveredBehaviorCount = input.discoveredPersonas.count + input.discoveredSkills.count + input.discoveredRoutines.count;
39
53
  return [
40
54
  {
41
55
  id: 'runtime',
42
- label: 'Connected services',
56
+ label: 'Connected host',
43
57
  status: 'ready',
44
58
  detail: `Agent will connect to ${input.runtimeBaseUrl}; service ownership stays outside this product.`,
45
59
  command: '/health',
@@ -51,50 +65,66 @@ export function buildAgentWorkspaceSetupChecklist(input: AgentWorkspaceSetupChec
51
65
  detail: providerReady
52
66
  ? `Current chat route is ${input.provider} / ${input.model}.`
53
67
  : 'Choose a provider and model before relying on assistant turns.',
54
- command: '/model',
68
+ command: '/agent setup',
55
69
  },
56
70
  {
57
71
  id: 'agent-knowledge',
58
72
  label: 'Agent Knowledge',
59
73
  status: 'recommended',
60
74
  detail: 'Check isolated Agent Knowledge status, then ingest source-backed material into the Agent segment only.',
61
- command: '/knowledge status',
75
+ command: '/agent knowledge',
62
76
  },
63
77
  {
64
78
  id: 'profile',
65
79
  label: 'Agent profile',
66
- status: setupStatusForCount(input.runtimeProfileCount, 'ready', 'optional'),
80
+ status: input.runtimeProfileCount > 0 ? 'ready' : discoveredBehaviorCount > 0 ? 'recommended' : 'optional',
67
81
  detail: input.runtimeProfileCount > 0
68
82
  ? `${input.runtimeProfileCount} isolated Agent profile(s) are available.`
83
+ : discoveredBehaviorCount > 0
84
+ ? `${discoveredBehaviorCount} discovered behavior file(s) can seed an isolated Agent profile from the Profiles workspace.`
69
85
  : `${input.runtimeStarterTemplateCount} starter template(s) are available if this machine needs separate operator identities.`,
70
- command: '/agent-profile templates',
86
+ command: '/agent profiles',
71
87
  },
72
88
  {
73
89
  id: 'persona',
74
90
  label: 'Persona',
75
91
  status: hasActivePersona ? 'ready' : 'recommended',
76
92
  detail: hasActivePersona
77
- ? `Active persona: ${input.activePersonaName}.`
78
- : 'Create or choose a persona to make the assistant voice and policy explicit.',
79
- command: '/personas',
93
+ ? `Active persona: ${input.activePersonaName}.${input.discoveredPersonas.count > 0 ? ` ${input.discoveredPersonas.count} discovered persona file(s) are still available to import.` : ''}`
94
+ : input.discoveredPersonas.count > 0
95
+ ? `${input.discoveredPersonas.count} discovered persona file(s) can be imported into the Agent-local registry.${sampleNames(input.discoveredPersonas)}`
96
+ : 'Create or choose a persona to make the assistant voice and policy explicit.',
97
+ command: '/agent personas',
80
98
  },
81
99
  {
82
100
  id: 'skills',
83
101
  label: 'Skills',
84
- status: input.enabledSkillCount > 0 || input.enabledSkillBundleCount > 0 ? 'ready' : input.skillCount > 0 || input.skillBundleCount > 0 ? 'recommended' : 'optional',
102
+ status: input.missingSkillRequirementCount > 0
103
+ ? 'recommended'
104
+ : input.enabledSkillCount > 0 || input.enabledSkillBundleCount > 0
105
+ ? 'ready'
106
+ : input.skillCount > 0 || input.skillBundleCount > 0 || input.discoveredSkills.count > 0
107
+ ? 'recommended'
108
+ : 'optional',
85
109
  detail: input.skillCount > 0 || input.skillBundleCount > 0
86
- ? `${input.enabledSkillCount}/${input.skillCount} local skill(s) enabled; ${input.enabledSkillBundleCount}/${input.skillBundleCount} bundle(s) enabled.`
87
- : 'Create reusable local skills and bundles for repeated workflows.',
88
- command: '/agent-skills',
110
+ ? `${input.enabledSkillCount}/${input.skillCount} local skill(s) enabled; ${input.enabledSkillBundleCount}/${input.skillBundleCount} bundle(s) enabled.${input.missingSkillRequirementCount > 0 ? ` ${input.missingSkillRequirementCount} missing setup requirement(s).` : ''}${input.discoveredSkills.count > 0 ? ` ${input.discoveredSkills.count} discovered skill file(s) are still available to import.` : ''}`
111
+ : input.discoveredSkills.count > 0
112
+ ? `${input.discoveredSkills.count} discovered skill file(s) can be imported as local reusable procedures.${sampleNames(input.discoveredSkills)}`
113
+ : 'Create reusable local skills and bundles for repeated workflows.',
114
+ command: '/agent skills',
89
115
  },
90
116
  {
91
117
  id: 'routines',
92
118
  label: 'Routines',
93
- status: setupStatusForCount(input.enabledRoutineCount, 'ready', input.routineCount > 0 ? 'recommended' : 'optional'),
119
+ status: input.missingRoutineRequirementCount > 0
120
+ ? 'recommended'
121
+ : setupStatusForCount(input.enabledRoutineCount, 'ready', input.routineCount > 0 || input.discoveredRoutines.count > 0 ? 'recommended' : 'optional'),
94
122
  detail: input.routineCount > 0
95
- ? `${input.enabledRoutineCount}/${input.routineCount} local routine(s) enabled.`
96
- : 'Create local routines first; promote schedules only with explicit confirmation.',
97
- command: '/routines',
123
+ ? `${input.enabledRoutineCount}/${input.routineCount} local routine(s) enabled.${input.missingRoutineRequirementCount > 0 ? ` ${input.missingRoutineRequirementCount} missing setup requirement(s).` : ''}${input.discoveredRoutines.count > 0 ? ` ${input.discoveredRoutines.count} discovered routine file(s) are still available to import.` : ''}`
124
+ : input.discoveredRoutines.count > 0
125
+ ? `${input.discoveredRoutines.count} discovered routine file(s) can be imported as main-conversation workflows.${sampleNames(input.discoveredRoutines)}`
126
+ : 'Create local routines first; promote schedules only with explicit confirmation.',
127
+ command: '/agent routines',
98
128
  },
99
129
  {
100
130
  id: 'memory',
@@ -103,7 +133,7 @@ export function buildAgentWorkspaceSetupChecklist(input: AgentWorkspaceSetupChec
103
133
  detail: input.localMemoryCount > 0
104
134
  ? `${input.localMemoryCount} Agent memory record(s) are available; ${input.localMemoryReviewQueueCount} need review.`
105
135
  : 'Memory starts empty; durable facts should be stored deliberately and never include secrets.',
106
- command: '/memory',
136
+ command: '/agent memory',
107
137
  },
108
138
  {
109
139
  id: 'channels',
@@ -112,14 +142,14 @@ export function buildAgentWorkspaceSetupChecklist(input: AgentWorkspaceSetupChec
112
142
  detail: input.readyChannelCount > 0
113
143
  ? `${input.readyChannelCount} external channel(s) are ready.`
114
144
  : 'Pair or review channels only when you want the assistant reachable outside this terminal.',
115
- command: '/pair',
145
+ command: '/agent channels',
116
146
  },
117
147
  {
118
148
  id: 'voice-media',
119
149
  label: 'Voice and media',
120
150
  status: input.voiceProviderCount > 0 || input.mediaProviderCount > 0 ? 'ready' : 'optional',
121
151
  detail: `${input.voiceProviderCount} voice provider(s), ${input.mediaProviderCount} media provider(s). Configure these only when useful.`,
122
- command: '/config tts',
152
+ command: '/agent voice-media',
123
153
  },
124
154
  ];
125
155
  }