@pellux/goodvibes-agent 0.1.116 → 1.0.0
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.
- package/CHANGELOG.md +48 -661
- package/README.md +64 -57
- package/bin/goodvibes-agent.ts +16 -2
- package/dist/package/main.js +199180 -192185
- package/docs/README.md +15 -8
- package/docs/channels-remote-and-api.md +50 -0
- package/docs/connected-host.md +59 -0
- package/docs/getting-started.md +61 -50
- package/docs/knowledge-artifacts-and-multimodal.md +91 -0
- package/docs/project-planning.md +79 -0
- package/docs/providers-and-routing.md +46 -0
- package/docs/release-and-publishing.md +48 -11
- package/docs/tools-and-commands.md +123 -0
- package/docs/voice-and-live-tts.md +51 -0
- package/package.json +3 -6
- package/src/agent/behavior-discovery-summary.ts +1 -3
- package/src/agent/channel-delivery.ts +201 -0
- package/src/agent/media-generation.ts +159 -0
- package/src/agent/memory-prompt.ts +0 -1
- package/src/agent/note-registry.ts +329 -0
- package/src/agent/operator-actions.ts +343 -0
- package/src/agent/persona-discovery.ts +1 -3
- package/src/agent/persona-registry.ts +19 -16
- package/src/agent/record-labels.ts +107 -0
- package/src/agent/reminder-schedule-format.ts +33 -24
- package/src/agent/reminder-schedule.ts +27 -26
- package/src/agent/routine-registry.ts +54 -14
- package/src/agent/routine-schedule-args.ts +2 -1
- package/src/agent/routine-schedule-format.ts +77 -53
- package/src/agent/routine-schedule-promotion.ts +35 -33
- package/src/agent/routine-schedule-receipts.ts +29 -27
- package/src/agent/runtime-profile-starters.ts +5 -5
- package/src/agent/runtime-profile.ts +91 -12
- package/src/agent/skill-registry.ts +210 -32
- package/src/cli/agent-knowledge-args.ts +5 -1
- package/src/cli/agent-knowledge-command.ts +40 -34
- package/src/cli/agent-knowledge-format.ts +80 -67
- package/src/cli/agent-knowledge-methods.ts +1 -1
- package/src/cli/agent-knowledge-runtime.ts +32 -26
- package/src/cli/bundle-command.ts +14 -9
- package/src/cli/config-overrides.ts +37 -36
- package/src/cli/entrypoint.ts +16 -7
- package/src/cli/external-runtime.ts +10 -4
- package/src/cli/help.ts +54 -29
- package/src/cli/local-library-command.ts +203 -83
- package/src/cli/management-commands.ts +105 -68
- package/src/cli/management.ts +55 -74
- package/src/cli/memory-command.ts +66 -32
- package/src/cli/parser.ts +37 -3
- package/src/cli/profiles-command.ts +166 -31
- package/src/cli/provider-auth-routes.ts +2 -1
- package/src/cli/routines-command.ts +176 -40
- package/src/cli/service-posture.ts +16 -16
- package/src/cli/status.ts +56 -135
- package/src/core/conversation-message-snapshot.ts +131 -0
- package/src/input/agent-workspace-access-command-editor-submission.ts +149 -0
- package/src/input/agent-workspace-access-command-editors.ts +170 -0
- package/src/input/agent-workspace-activation.ts +35 -8
- package/src/input/agent-workspace-basic-command-editor-submission.ts +351 -94
- package/src/input/agent-workspace-basic-command-editors.ts +502 -9
- package/src/input/agent-workspace-categories.ts +423 -51
- package/src/input/agent-workspace-channel-command-editor-submission.ts +83 -0
- package/src/input/agent-workspace-channel-command-editors.ts +65 -0
- package/src/input/agent-workspace-channels.ts +35 -2
- package/src/input/agent-workspace-command-editor.ts +41 -3
- package/src/input/agent-workspace-config-reader.ts +16 -0
- package/src/input/agent-workspace-delegation-editor-submission.ts +55 -0
- package/src/input/agent-workspace-editors.ts +166 -1
- package/src/input/agent-workspace-knowledge-command-editor-submission.ts +132 -0
- package/src/input/agent-workspace-knowledge-command-editors.ts +110 -0
- package/src/input/agent-workspace-knowledge-query-editor.ts +1 -1
- package/src/input/agent-workspace-learned-behavior.ts +67 -0
- package/src/input/agent-workspace-library-command-editor-submission.ts +50 -0
- package/src/input/agent-workspace-library-command-editors.ts +35 -0
- package/src/input/agent-workspace-local-operations.ts +218 -0
- package/src/input/agent-workspace-local-selection.ts +75 -0
- package/src/input/agent-workspace-mcp-command-editor-submission.ts +95 -0
- package/src/input/agent-workspace-media-command-editor-submission.ts +62 -0
- package/src/input/agent-workspace-media-command-editors.ts +27 -0
- package/src/input/agent-workspace-memory-command-editor-submission.ts +232 -0
- package/src/input/agent-workspace-memory-command-editors.ts +180 -0
- package/src/input/agent-workspace-memory-editor.ts +2 -2
- package/src/input/agent-workspace-navigation.ts +81 -0
- package/src/input/agent-workspace-notify-editor-submission.ts +121 -0
- package/src/input/agent-workspace-operations-command-editor-submission.ts +208 -0
- package/src/input/agent-workspace-operations-command-editors.ts +196 -0
- package/src/input/agent-workspace-panel-route.ts +43 -0
- package/src/input/agent-workspace-provider-command-editor-submission.ts +155 -0
- package/src/input/agent-workspace-provider-command-editors.ts +93 -0
- package/src/input/agent-workspace-reminder-schedule-editor.ts +1 -1
- package/src/input/agent-workspace-requirements.ts +11 -0
- package/src/input/agent-workspace-routine-schedule-editor.ts +2 -2
- package/src/input/agent-workspace-search.ts +169 -0
- package/src/input/agent-workspace-secret-editor-submission.ts +153 -0
- package/src/input/agent-workspace-session-command-editor-submission.ts +199 -0
- package/src/input/agent-workspace-session-command-editors.ts +249 -0
- package/src/input/agent-workspace-setup.ts +37 -16
- package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +101 -0
- package/src/input/agent-workspace-skill-bundle-command-editors.ts +110 -0
- package/src/input/agent-workspace-snapshot.ts +162 -21
- package/src/input/agent-workspace-task-command-editor-submission.ts +61 -0
- package/src/input/agent-workspace-task-command-editors.ts +47 -0
- package/src/input/agent-workspace-token.ts +18 -2
- package/src/input/agent-workspace-types.ts +212 -4
- package/src/input/agent-workspace-voice-media.ts +4 -7
- package/src/input/agent-workspace-web-research-editor.ts +104 -0
- package/src/input/agent-workspace-workplan-editor-submission.ts +153 -0
- package/src/input/agent-workspace.ts +178 -240
- package/src/input/command-registry.ts +5 -2
- package/src/input/commands/agent-runtime-profile-runtime.ts +126 -37
- package/src/input/commands/agent-skills-runtime.ts +149 -72
- package/src/input/commands/agent-workspace-runtime.ts +23 -6
- package/src/input/commands/brief-runtime.ts +55 -25
- package/src/input/commands/channels-runtime.ts +147 -33
- package/src/input/commands/compat-runtime.ts +32 -0
- package/src/input/commands/delegation-runtime.ts +29 -23
- package/src/input/commands/experience-runtime.ts +6 -4
- package/src/input/commands/guidance-runtime.ts +4 -4
- package/src/input/commands/health-runtime.ts +149 -126
- package/src/input/commands/knowledge.ts +82 -60
- package/src/input/commands/local-provider-runtime.ts +43 -21
- package/src/input/commands/local-runtime.ts +138 -16
- package/src/input/commands/local-setup-review.ts +10 -20
- package/src/input/commands/mcp-runtime.ts +63 -46
- package/src/input/commands/notify-runtime.ts +38 -9
- package/src/input/commands/operator-actions-runtime.ts +138 -0
- package/src/input/commands/operator-runtime.ts +6 -76
- package/src/input/commands/personas-runtime.ts +46 -31
- package/src/input/commands/planning-runtime.ts +1 -1
- package/src/input/commands/platform-access-runtime.ts +35 -98
- package/src/input/commands/product-runtime.ts +2 -2
- package/src/input/commands/provider-accounts-runtime.ts +60 -39
- package/src/input/commands/qrcode-runtime.ts +50 -9
- package/src/input/commands/recall-bundle.ts +11 -11
- package/src/input/commands/recall-capture.ts +13 -11
- package/src/input/commands/recall-query.ts +29 -21
- package/src/input/commands/recall-review.ts +2 -1
- package/src/input/commands/routines-runtime.ts +99 -45
- package/src/input/commands/runtime-services.ts +1 -14
- package/src/input/commands/schedule-runtime.ts +33 -20
- package/src/input/commands/security-runtime.ts +6 -11
- package/src/input/commands/session-content.ts +80 -78
- package/src/input/commands/session-workflow.ts +134 -104
- package/src/input/commands/session.ts +3 -174
- package/src/input/commands/shell-core.ts +38 -17
- package/src/input/commands/subscription-runtime.ts +54 -185
- package/src/input/commands/support-bundle-runtime.ts +53 -0
- package/src/input/commands/tasks-runtime.ts +21 -21
- package/src/input/commands/work-plan-runtime.ts +33 -8
- package/src/input/commands.ts +6 -2
- package/src/input/feed-context-factory.ts +2 -2
- package/src/input/file-picker.ts +3 -2
- package/src/input/handler-command-route.ts +4 -7
- package/src/input/handler-content-actions.ts +89 -26
- package/src/input/handler-feed-routes.ts +19 -12
- package/src/input/handler-feed.ts +6 -5
- package/src/input/handler-interactions.ts +9 -36
- package/src/input/handler-modal-stack.ts +3 -3
- package/src/input/handler-onboarding.ts +52 -91
- package/src/input/handler-shortcuts.ts +16 -7
- package/src/input/handler.ts +50 -23
- package/src/input/input-history.ts +5 -6
- package/src/input/keybindings.ts +27 -16
- package/src/input/mcp-workspace.ts +90 -26
- package/src/input/onboarding/handler-onboarding-routes.ts +3 -1
- package/src/input/onboarding/onboarding-wizard-apply.ts +62 -0
- package/src/input/onboarding/onboarding-wizard-constants.ts +1 -0
- package/src/input/onboarding/onboarding-wizard-helpers.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-operator-steps.ts +223 -55
- package/src/input/onboarding/onboarding-wizard-steps.ts +59 -35
- package/src/input/onboarding/onboarding-wizard-types.ts +4 -1
- package/src/input/onboarding/onboarding-wizard.ts +87 -2
- package/src/input/profile-picker-modal.ts +31 -12
- package/src/input/session-picker-modal.ts +21 -4
- package/src/input/settings-modal-agent-policy.ts +6 -6
- package/src/input/settings-modal-behavior.ts +0 -3
- package/src/input/settings-modal-subscriptions.ts +3 -3
- package/src/input/settings-modal-types.ts +2 -13
- package/src/input/settings-modal.ts +20 -66
- package/src/input/submission-intent.ts +0 -1
- package/src/input/submission-router.ts +3 -3
- package/src/main.ts +18 -10
- package/src/panels/approval-panel.ts +8 -8
- package/src/panels/automation-control-panel.ts +4 -4
- package/src/panels/base-panel.ts +1 -1
- package/src/panels/builtin/agent.ts +1 -1
- package/src/panels/builtin/operations.ts +3 -12
- package/src/panels/builtin/session.ts +32 -24
- package/src/panels/builtin/shared.ts +7 -7
- package/src/panels/cost-tracker-panel.ts +1 -1
- package/src/panels/docs-panel.ts +5 -3
- package/src/panels/index.ts +0 -1
- package/src/panels/knowledge-panel.ts +6 -5
- package/src/panels/memory-panel.ts +7 -6
- package/src/panels/panel-list-panel.ts +36 -80
- package/src/panels/project-planning-panel.ts +19 -12
- package/src/panels/provider-account-snapshot.ts +51 -25
- package/src/panels/provider-accounts-panel.ts +33 -18
- package/src/panels/provider-health-domains.ts +48 -7
- package/src/panels/provider-health-panel.ts +5 -4
- package/src/panels/qr-panel.ts +44 -20
- package/src/panels/schedule-panel.ts +9 -17
- package/src/panels/security-panel.ts +8 -8
- package/src/panels/session-browser-panel.ts +10 -10
- package/src/panels/subscription-panel.ts +6 -6
- package/src/panels/system-messages-panel.ts +3 -3
- package/src/panels/tasks-panel.ts +21 -14
- package/src/panels/tool-inspector-panel.ts +19 -12
- package/src/panels/work-plan-panel.ts +5 -5
- package/src/planning/project-planning-coordinator.ts +3 -3
- package/src/provider-auth-route-display.ts +9 -0
- package/src/renderer/agent-workspace-style.ts +34 -0
- package/src/renderer/agent-workspace.ts +254 -57
- package/src/renderer/autocomplete-overlay.ts +25 -6
- package/src/renderer/block-actions.ts +1 -3
- package/src/renderer/bookmark-modal.ts +19 -4
- package/src/renderer/buffer.ts +4 -2
- package/src/renderer/context-inspector.ts +50 -13
- package/src/renderer/diff.ts +1 -1
- package/src/renderer/file-picker-overlay.ts +19 -6
- package/src/renderer/help-overlay.ts +112 -34
- package/src/renderer/history-search-overlay.ts +19 -4
- package/src/renderer/live-tail-modal.ts +27 -5
- package/src/renderer/mcp-workspace.ts +176 -43
- package/src/renderer/model-picker-overlay.ts +58 -3
- package/src/renderer/model-workspace.ts +104 -22
- package/src/renderer/onboarding/onboarding-wizard.ts +20 -4
- package/src/renderer/process-modal.ts +27 -6
- package/src/renderer/profile-picker-modal.ts +21 -5
- package/src/renderer/search-overlay.ts +25 -5
- package/src/renderer/selection-modal-overlay.ts +46 -14
- package/src/renderer/session-picker-modal.ts +18 -1
- package/src/renderer/settings-modal-helpers.ts +2 -40
- package/src/renderer/settings-modal.ts +88 -55
- package/src/renderer/system-message.ts +1 -1
- package/src/renderer/tool-call.ts +20 -11
- package/src/runtime/agent-runtime-events.ts +129 -0
- package/src/runtime/bootstrap-command-context.ts +7 -1
- package/src/runtime/bootstrap-command-parts.ts +11 -8
- package/src/runtime/bootstrap-core.ts +23 -65
- package/src/runtime/bootstrap-hook-bridge.ts +7 -18
- package/src/runtime/bootstrap-shell.ts +46 -8
- package/src/runtime/bootstrap.ts +36 -46
- package/src/runtime/connected-host-auth.ts +47 -0
- package/src/runtime/diagnostics/panels/index.ts +2 -2
- package/src/runtime/diagnostics/panels/panel-resources.ts +1 -1
- package/src/runtime/diagnostics/panels/policy.ts +7 -7
- package/src/runtime/index.ts +2 -5
- package/src/runtime/onboarding/apply-file-helpers.ts +66 -0
- package/src/runtime/onboarding/apply.ts +288 -74
- package/src/runtime/onboarding/derivation.ts +10 -13
- package/src/runtime/onboarding/snapshot.ts +2 -17
- package/src/runtime/onboarding/types.ts +34 -20
- package/src/runtime/onboarding/verify.ts +105 -4
- package/src/runtime/operator-token-cleanup.ts +3 -3
- package/src/runtime/services.ts +95 -11
- package/src/runtime/store/selectors/index.ts +3 -3
- package/src/runtime/store/state.ts +1 -4
- package/src/runtime/surface-feature-flags.ts +41 -6
- package/src/runtime/ui-read-models.ts +3 -4
- package/src/runtime/ui-services.ts +6 -6
- package/src/shell/blocking-input.ts +2 -1
- package/src/shell/service-settings-sync.ts +7 -7
- package/src/shell/ui-openers.ts +17 -38
- package/src/tools/agent-analysis-registry-policy.ts +0 -1
- package/src/tools/agent-channel-send-tool.ts +133 -0
- package/src/tools/agent-context-policy.ts +1 -1
- package/src/tools/agent-knowledge-ingest-tool.ts +405 -0
- package/src/tools/agent-knowledge-tool.ts +170 -0
- package/src/tools/agent-local-registry-tool.ts +279 -73
- package/src/tools/agent-media-generate-tool.ts +133 -0
- package/src/tools/agent-notify-tool.ts +143 -0
- package/src/tools/agent-operator-action-tool.ts +137 -0
- package/src/tools/agent-operator-briefing-tool.ts +217 -0
- package/src/tools/agent-reminder-schedule-tool.ts +237 -0
- package/src/tools/agent-tool-policy-guard.ts +13 -15
- package/src/tools/agent-work-plan-tool.ts +256 -0
- package/src/version.ts +1 -1
- package/docs/connected-services.md +0 -51
- package/src/cli/package-verification.ts +0 -274
- package/src/input/commands/policy-dispatch.ts +0 -339
- package/src/input/commands/policy.ts +0 -17
- package/src/panels/panel-picker.ts +0 -105
- package/src/panels/policy-panel.ts +0 -308
- package/src/renderer/panel-picker-overlay.ts +0 -202
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { CommandContext } from '../command-registry.ts';
|
|
2
2
|
import type { MemoryApi } from '@pellux/goodvibes-sdk/platform/knowledge';
|
|
3
3
|
import type { MemorySearchFilter } from '@pellux/goodvibes-sdk/platform/state';
|
|
4
|
+
import { formatAgentRecordReference, formatAgentRecordReferences } from '../../agent/record-labels.ts';
|
|
4
5
|
import { VALID_CLASSES, VALID_SCOPES, isValidClass, isValidScope } from './recall-shared.ts';
|
|
5
6
|
import { requireYesFlag, stripYesFlag } from './confirmation.ts';
|
|
6
7
|
|
|
@@ -8,7 +9,7 @@ export function getMemoryApi(context: CommandContext): MemoryApi | null {
|
|
|
8
9
|
const memoryApi = context.clients?.agentKnowledgeApi?.memory;
|
|
9
10
|
if (!memoryApi) {
|
|
10
11
|
context.print('[memory] Agent Memory API is not available in this runtime.');
|
|
11
|
-
context.print('[memory] Refusing to use default
|
|
12
|
+
context.print('[memory] Refusing to use default knowledge or non-Agent knowledge fallback.');
|
|
12
13
|
return null;
|
|
13
14
|
}
|
|
14
15
|
return memoryApi;
|
|
@@ -29,7 +30,7 @@ export function handleRecallSearch(args: string[], context: CommandContext): voi
|
|
|
29
30
|
const cls = args[clsIdx + 1];
|
|
30
31
|
if (isValidClass(cls)) filter.cls = cls;
|
|
31
32
|
else {
|
|
32
|
-
context.print(`[memory] Unknown class "${cls}". Valid
|
|
33
|
+
context.print(`[memory] Unknown class "${cls}". Valid values ${VALID_CLASSES.join(', ')}.`);
|
|
33
34
|
return;
|
|
34
35
|
}
|
|
35
36
|
}
|
|
@@ -39,7 +40,7 @@ export function handleRecallSearch(args: string[], context: CommandContext): voi
|
|
|
39
40
|
const scope = args[scopeIdx + 1];
|
|
40
41
|
if (isValidScope(scope)) filter.scope = scope;
|
|
41
42
|
else {
|
|
42
|
-
context.print(`[memory] Unknown scope "${scope}". Valid
|
|
43
|
+
context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(', ')}.`);
|
|
43
44
|
return;
|
|
44
45
|
}
|
|
45
46
|
}
|
|
@@ -63,7 +64,7 @@ export function handleRecallSearch(args: string[], context: CommandContext): voi
|
|
|
63
64
|
return;
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
context.print(`[memory] ${results.length} ${semantic ? 'semantic ' : ''}record(s)
|
|
67
|
+
context.print(`[memory] ${results.length} ${semantic ? 'semantic ' : ''}record(s)`);
|
|
67
68
|
for (const record of results) {
|
|
68
69
|
const semanticEntry = semanticResults.find((entry) => entry.record.id === record.id);
|
|
69
70
|
const ts = new Date(record.createdAt).toISOString().slice(0, 16).replace('T', ' ');
|
|
@@ -72,7 +73,7 @@ export function handleRecallSearch(args: string[], context: CommandContext): voi
|
|
|
72
73
|
context.print(` ${record.id} [${record.cls}]${tagStr} ${ts}${scoreStr}`);
|
|
73
74
|
context.print(` ${record.summary}`);
|
|
74
75
|
if (record.provenance.length) {
|
|
75
|
-
context.print(`
|
|
76
|
+
context.print(` origin ${formatAgentRecordReferences(record.provenance)}`);
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
79
|
}
|
|
@@ -124,29 +125,28 @@ export function handleRecallGet(args: string[], context: CommandContext): void {
|
|
|
124
125
|
}
|
|
125
126
|
const record = memory.get(id);
|
|
126
127
|
if (!record) {
|
|
127
|
-
context.print(`[memory] Record not found
|
|
128
|
+
context.print(`[memory] Record not found ${id}`);
|
|
128
129
|
return;
|
|
129
130
|
}
|
|
130
131
|
const ts = new Date(record.createdAt).toISOString().slice(0, 19).replace('T', ' ');
|
|
131
132
|
context.print(`[memory] ${record.id}`);
|
|
132
|
-
context.print(`
|
|
133
|
-
context.print(`
|
|
134
|
-
context.print(`
|
|
135
|
-
if (record.detail) context.print(`
|
|
136
|
-
if (record.tags.length) context.print(`
|
|
137
|
-
context.print(`
|
|
133
|
+
context.print(` scope ${record.scope}`);
|
|
134
|
+
context.print(` class ${record.cls}`);
|
|
135
|
+
context.print(` summary ${record.summary}`);
|
|
136
|
+
if (record.detail) context.print(` detail ${record.detail}`);
|
|
137
|
+
if (record.tags.length) context.print(` tags ${record.tags.join(', ')}`);
|
|
138
|
+
context.print(` created ${ts}`);
|
|
138
139
|
|
|
139
140
|
if (record.provenance.length) {
|
|
140
|
-
context.print('
|
|
141
|
+
context.print(' origin');
|
|
141
142
|
for (const provenance of record.provenance) {
|
|
142
|
-
|
|
143
|
-
context.print(` ${provenance.kind}: ${provenance.ref}${label}`);
|
|
143
|
+
context.print(` ${formatAgentRecordReference(provenance)}`);
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
const links = memory.linksFor(id);
|
|
148
148
|
if (links.length) {
|
|
149
|
-
context.print('
|
|
149
|
+
context.print(' links');
|
|
150
150
|
for (const link of links) {
|
|
151
151
|
const dir = link.fromId === id ? '->' : '<-';
|
|
152
152
|
const other = link.fromId === id ? link.toId : link.fromId;
|
|
@@ -175,7 +175,12 @@ export async function handleRecallLink(args: string[], context: CommandContext):
|
|
|
175
175
|
context.print('[memory] Link failed — check that both IDs exist.');
|
|
176
176
|
return;
|
|
177
177
|
}
|
|
178
|
-
context.print(
|
|
178
|
+
context.print([
|
|
179
|
+
'[memory] Linked',
|
|
180
|
+
` from ${fromId}`,
|
|
181
|
+
` to ${toId}`,
|
|
182
|
+
` relation ${relation}`,
|
|
183
|
+
].join('\n'));
|
|
179
184
|
}
|
|
180
185
|
|
|
181
186
|
export function handleRecallRemove(args: string[], context: CommandContext): void {
|
|
@@ -195,10 +200,13 @@ export function handleRecallRemove(args: string[], context: CommandContext): voi
|
|
|
195
200
|
}
|
|
196
201
|
const removed = memory.delete(id);
|
|
197
202
|
if (!removed) {
|
|
198
|
-
context.print(`[memory] Record not found
|
|
203
|
+
context.print(`[memory] Record not found ${id}`);
|
|
199
204
|
return;
|
|
200
205
|
}
|
|
201
|
-
context.print(
|
|
206
|
+
context.print([
|
|
207
|
+
'[memory] Deleted',
|
|
208
|
+
` id ${id}`,
|
|
209
|
+
].join('\n'));
|
|
202
210
|
}
|
|
203
211
|
|
|
204
212
|
export function handleRecallList(args: string[], context: CommandContext): void {
|
|
@@ -213,7 +221,7 @@ export function handleRecallList(args: string[], context: CommandContext): void
|
|
|
213
221
|
if (scopeIdx !== -1 && args[scopeIdx + 1]) {
|
|
214
222
|
const scope = args[scopeIdx + 1];
|
|
215
223
|
if (!isValidScope(scope)) {
|
|
216
|
-
context.print(`[memory] Unknown scope "${scope}". Valid
|
|
224
|
+
context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(', ')}.`);
|
|
217
225
|
return;
|
|
218
226
|
}
|
|
219
227
|
filter.scope = scope;
|
|
@@ -232,7 +240,7 @@ export function handleRecallList(args: string[], context: CommandContext): void
|
|
|
232
240
|
}
|
|
233
241
|
|
|
234
242
|
for (const [clsName, group] of Object.entries(grouped)) {
|
|
235
|
-
context.print(`\n[memory] ${clsName.toUpperCase()} (${group.length})
|
|
243
|
+
context.print(`\n[memory] ${clsName.toUpperCase()} (${group.length})`);
|
|
236
244
|
for (const record of group) {
|
|
237
245
|
const tagStr = record.tags.length ? ` [${record.tags.join(', ')}]` : '';
|
|
238
246
|
context.print(` ${record.id} [${record.scope}]${tagStr} ${record.summary}`);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CommandContext } from '../command-registry.ts';
|
|
2
|
+
import { formatAgentRecordReviewState } from '../../agent/record-labels.ts';
|
|
2
3
|
import { VALID_REVIEW_STATES, VALID_SCOPES, isValidReviewState, isValidScope } from './recall-shared.ts';
|
|
3
4
|
import { getMemoryApi } from './recall-query.ts';
|
|
4
5
|
import { requireYesFlag, stripYesFlag } from './confirmation.ts';
|
|
@@ -17,7 +18,7 @@ export function handleRecallQueue(args: string[], context: CommandContext): void
|
|
|
17
18
|
context.print(`[memory] Review queue (${queue.length}):`);
|
|
18
19
|
for (const record of queue) {
|
|
19
20
|
const reason = record.staleReason ? ` — ${record.staleReason}` : '';
|
|
20
|
-
context.print(` ${record.id} [${record.scope}/${record.cls}] ${record.reviewState} ${record.confidence}% ${record.summary}${reason}`);
|
|
21
|
+
context.print(` ${record.id} [${record.scope}/${record.cls}] ${formatAgentRecordReviewState(record.reviewState)} ${record.confidence}% ${record.summary}${reason}`);
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { discoverRoutines, type DiscoveredRoutineRecord } from '../../agent/routine-discovery.ts';
|
|
2
|
-
import { AgentRoutineRegistry, type AgentRoutineRecord } from '../../agent/routine-registry.ts';
|
|
2
|
+
import { AgentRoutineRegistry, evaluateAgentRoutineReadiness, type AgentRoutineRecord } from '../../agent/routine-registry.ts';
|
|
3
|
+
import { formatAgentRecordOrigin, formatAgentRecordReviewState } from '../../agent/record-labels.ts';
|
|
4
|
+
import { buildAgentSkillRequirements, formatAgentSkillRequirement } from '../../agent/skill-registry.ts';
|
|
3
5
|
import {
|
|
4
6
|
buildRoutineSchedulePreview,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
promoteRoutineToConnectedSchedule,
|
|
8
|
+
resolveAgentConnectedHostConnection,
|
|
7
9
|
} from '../../agent/routine-schedule-promotion.ts';
|
|
8
10
|
import { parseRoutineSchedulePromotionArgs } from '../../agent/routine-schedule-args.ts';
|
|
9
11
|
import {
|
|
@@ -72,39 +74,57 @@ function requiredFlag(flags: ReadonlyMap<string, string>, key: string): string {
|
|
|
72
74
|
return value;
|
|
73
75
|
}
|
|
74
76
|
|
|
77
|
+
function formatRoutineReceipt(title: string, routine: Pick<AgentRoutineRecord, 'id' | 'name'>, extra: readonly string[] = []): string {
|
|
78
|
+
const enabled = extra.some((line) => line.trim() === 'enabled yes');
|
|
79
|
+
return [
|
|
80
|
+
`${title} ${routine.id}: ${routine.name}${enabled ? ' (enabled)' : ''}`,
|
|
81
|
+
` id ${routine.id}`,
|
|
82
|
+
` name ${routine.name}`,
|
|
83
|
+
...extra,
|
|
84
|
+
].join('\n');
|
|
85
|
+
}
|
|
86
|
+
|
|
75
87
|
function summarizeRoutine(routine: AgentRoutineRecord): string {
|
|
76
88
|
const enabled = routine.enabled ? 'enabled' : 'disabled';
|
|
77
|
-
const tags = routine.tags.length > 0 ? ` tags
|
|
78
|
-
|
|
89
|
+
const tags = routine.tags.length > 0 ? ` tags ${routine.tags.join(', ')}` : '';
|
|
90
|
+
const readiness = evaluateAgentRoutineReadiness(routine);
|
|
91
|
+
const review = formatAgentRecordReviewState(routine.reviewState);
|
|
92
|
+
const ready = readiness.ready ? 'ready' : `needs ${readiness.missing.map(formatAgentSkillRequirement).join(',')}`;
|
|
93
|
+
return ` ${routine.id} ${enabled} ${review} ${ready} starts ${routine.startCount} ${routine.name} - ${routine.description}${tags}`;
|
|
79
94
|
}
|
|
80
95
|
|
|
81
|
-
function renderList(title: string, registry: AgentRoutineRegistry, routines: readonly AgentRoutineRecord[]): string {
|
|
96
|
+
function renderList(title: string, registry: AgentRoutineRegistry, routines: readonly AgentRoutineRecord[], emptyMessage?: string): string {
|
|
82
97
|
const snapshot = registry.snapshot();
|
|
83
98
|
if (routines.length === 0) {
|
|
84
|
-
return
|
|
99
|
+
return emptyMessage
|
|
100
|
+
? `${title}\n ${emptyMessage}`
|
|
101
|
+
: `${title}\n No local Agent routines yet.\n No Agent-local routines yet. Create one with /routines create --name <name> --description <summary> --steps <steps>.`;
|
|
85
102
|
}
|
|
86
103
|
return [
|
|
87
104
|
`${title} (${routines.length})`,
|
|
88
|
-
` store
|
|
89
|
-
` enabled
|
|
105
|
+
` store ${snapshot.path}`,
|
|
106
|
+
` enabled ${snapshot.enabledRoutines.length}`,
|
|
90
107
|
...routines.map(summarizeRoutine),
|
|
91
108
|
].join('\n');
|
|
92
109
|
}
|
|
93
110
|
|
|
94
111
|
function renderRoutine(routine: AgentRoutineRecord): string {
|
|
112
|
+
const readiness = evaluateAgentRoutineReadiness(routine);
|
|
95
113
|
return [
|
|
96
114
|
`Routine ${routine.name}`,
|
|
97
|
-
` id
|
|
98
|
-
` enabled
|
|
99
|
-
`
|
|
100
|
-
`
|
|
101
|
-
`
|
|
115
|
+
` id ${routine.id}`,
|
|
116
|
+
` enabled ${routine.enabled ? 'yes' : 'no'}`,
|
|
117
|
+
` readiness: ${readiness.ready ? 'ready' : 'needs setup'}`,
|
|
118
|
+
` requirements ${routine.requirements.map(formatAgentSkillRequirement).join(', ') || '(none)'}`,
|
|
119
|
+
readiness.missing.length > 0 ? ` missing: ${readiness.missing.map(formatAgentSkillRequirement).join(', ')}` : '',
|
|
120
|
+
` review ${formatAgentRecordReviewState(routine.reviewState)}`,
|
|
121
|
+
` origin ${formatAgentRecordOrigin(routine.source, routine.provenance)}`,
|
|
102
122
|
` tags: ${routine.tags.join(', ') || '(none)'}`,
|
|
103
123
|
` triggers: ${routine.triggers.join(', ') || '(manual)'}`,
|
|
104
|
-
` started
|
|
105
|
-
` created
|
|
106
|
-
` updated
|
|
107
|
-
routine.staleReason ? ` stale reason
|
|
124
|
+
` started ${routine.startCount}${routine.lastStartedAt ? `; last ${routine.lastStartedAt}` : ''}`,
|
|
125
|
+
` created ${routine.createdAt}`,
|
|
126
|
+
` updated ${routine.updatedAt}`,
|
|
127
|
+
routine.staleReason ? ` stale reason ${routine.staleReason}` : '',
|
|
108
128
|
'',
|
|
109
129
|
routine.description,
|
|
110
130
|
'',
|
|
@@ -114,7 +134,7 @@ function renderRoutine(routine: AgentRoutineRecord): string {
|
|
|
114
134
|
|
|
115
135
|
function summarizeDiscoveredRoutine(routine: DiscoveredRoutineRecord): string {
|
|
116
136
|
const description = routine.description ? ` - ${routine.description}` : '';
|
|
117
|
-
return ` ${routine.name} ${routine.origin}${description}\n path
|
|
137
|
+
return ` ${routine.name} ${routine.origin}${description}\n path ${routine.path}`;
|
|
118
138
|
}
|
|
119
139
|
|
|
120
140
|
function renderDiscoveredRoutines(routines: readonly DiscoveredRoutineRecord[]): string {
|
|
@@ -151,8 +171,19 @@ function frontmatterList(routine: DiscoveredRoutineRecord, key: string): readonl
|
|
|
151
171
|
return splitList(value);
|
|
152
172
|
}
|
|
153
173
|
|
|
174
|
+
function frontmatterAnyList(routine: DiscoveredRoutineRecord, keys: readonly string[]): readonly string[] {
|
|
175
|
+
for (const key of keys) {
|
|
176
|
+
const values = frontmatterList(routine, key);
|
|
177
|
+
if (values.length > 0) return values;
|
|
178
|
+
}
|
|
179
|
+
return [];
|
|
180
|
+
}
|
|
181
|
+
|
|
154
182
|
function printError(ctx: CommandContext, error: unknown): void {
|
|
155
|
-
ctx.print(
|
|
183
|
+
ctx.print([
|
|
184
|
+
'Error',
|
|
185
|
+
` message ${error instanceof Error ? error.message : String(error)}`,
|
|
186
|
+
].join('\n'));
|
|
156
187
|
}
|
|
157
188
|
|
|
158
189
|
async function importDiscoveredRoutine(args: readonly string[], ctx: CommandContext, routineRegistry: AgentRoutineRegistry): Promise<void> {
|
|
@@ -164,18 +195,18 @@ async function importDiscoveredRoutine(args: readonly string[], ctx: CommandCont
|
|
|
164
195
|
}
|
|
165
196
|
const discovered = findDiscoveredRoutine(await discoverRoutines(requireShellPaths(ctx)), name);
|
|
166
197
|
if (!discovered) {
|
|
167
|
-
ctx.print(`Unknown discovered Agent routine
|
|
198
|
+
ctx.print(`Unknown discovered Agent routine ${name}\nRun /routines discover to inspect available routine files.`);
|
|
168
199
|
return;
|
|
169
200
|
}
|
|
170
201
|
if (!parsed.yes) {
|
|
171
202
|
ctx.print([
|
|
172
203
|
'Agent routine import preview',
|
|
173
|
-
` name
|
|
174
|
-
` origin
|
|
175
|
-
` path
|
|
176
|
-
` description
|
|
177
|
-
` steps characters
|
|
178
|
-
' next
|
|
204
|
+
` name ${discovered.name}`,
|
|
205
|
+
` origin ${discovered.origin}`,
|
|
206
|
+
` path ${discovered.path}`,
|
|
207
|
+
` description ${discovered.description || '(none)'}`,
|
|
208
|
+
` steps characters ${discovered.steps.length}`,
|
|
209
|
+
' next rerun with --yes to import into the Agent-local routine registry',
|
|
179
210
|
].join('\n'));
|
|
180
211
|
return;
|
|
181
212
|
}
|
|
@@ -185,11 +216,15 @@ async function importDiscoveredRoutine(args: readonly string[], ctx: CommandCont
|
|
|
185
216
|
steps: discovered.steps,
|
|
186
217
|
tags: frontmatterList(discovered, 'tags'),
|
|
187
218
|
triggers: frontmatterList(discovered, 'triggers'),
|
|
219
|
+
requirements: buildAgentSkillRequirements({
|
|
220
|
+
env: frontmatterAnyList(discovered, ['requiresEnv', 'requires-env', 'requires_env']),
|
|
221
|
+
commands: frontmatterAnyList(discovered, ['requiresCommands', 'requires-commands', 'requires_commands', 'commands']),
|
|
222
|
+
}),
|
|
188
223
|
enabled: parsed.flags.get('enabled') === 'true',
|
|
189
224
|
source: 'imported',
|
|
190
225
|
provenance: `discovered:${discovered.origin}:${discovered.path}`,
|
|
191
226
|
});
|
|
192
|
-
ctx.print(
|
|
227
|
+
ctx.print(formatRoutineReceipt('Imported Agent routine', routine, [` enabled ${routine.enabled ? 'yes' : 'no'}`]));
|
|
193
228
|
}
|
|
194
229
|
|
|
195
230
|
async function promoteRoutine(args: readonly string[], routineRegistry: AgentRoutineRegistry, ctx: CommandContext): Promise<void> {
|
|
@@ -212,8 +247,8 @@ async function promoteRoutine(args: readonly string[], routineRegistry: AgentRou
|
|
|
212
247
|
return;
|
|
213
248
|
}
|
|
214
249
|
const shellPaths = requireShellPaths(ctx);
|
|
215
|
-
const connection =
|
|
216
|
-
const result = await
|
|
250
|
+
const connection = resolveAgentConnectedHostConnection(ctx.platform.configManager, shellPaths.homeDirectory);
|
|
251
|
+
const result = await promoteRoutineToConnectedSchedule(connection, preview);
|
|
217
252
|
const receipt = receiptStoreFromContext(ctx).append(connection, preview, result);
|
|
218
253
|
ctx.print(result.ok ? `${formatRoutineScheduleSuccess(result)}\n receipt: ${receipt.id}` : `${formatRoutineScheduleFailure(result)}\n receipt: ${receipt.id}`);
|
|
219
254
|
}
|
|
@@ -231,6 +266,11 @@ export async function runRoutinesRuntimeCommand(args: readonly string[], ctx: Co
|
|
|
231
266
|
ctx.print(renderList('Enabled Agent Routines', routineRegistry, snapshot.enabledRoutines));
|
|
232
267
|
return;
|
|
233
268
|
}
|
|
269
|
+
if (sub === 'attention' || sub === 'needs-setup') {
|
|
270
|
+
const routines = routineRegistry.list().filter((routine) => !evaluateAgentRoutineReadiness(routine).ready);
|
|
271
|
+
ctx.print(renderList('Agent Routines needing setup', routineRegistry, routines, 'No Agent-local routines need setup.'));
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
234
274
|
if (sub === 'discover' || sub === 'discovered') {
|
|
235
275
|
ctx.print(renderDiscoveredRoutines(await discoverRoutines(requireShellPaths(ctx))));
|
|
236
276
|
return;
|
|
@@ -260,7 +300,7 @@ export async function runRoutinesRuntimeCommand(args: readonly string[], ctx: Co
|
|
|
260
300
|
}
|
|
261
301
|
if (sub === 'reconcile' || sub === 'sync' || sub === 'status') {
|
|
262
302
|
const shellPaths = requireShellPaths(ctx);
|
|
263
|
-
const connection =
|
|
303
|
+
const connection = resolveAgentConnectedHostConnection(ctx.platform.configManager, shellPaths.homeDirectory);
|
|
264
304
|
const result = await reconcileRoutineScheduleReceipts(connection, receiptStoreFromContext(ctx).snapshot());
|
|
265
305
|
ctx.print(formatRoutineScheduleCorrelation(result));
|
|
266
306
|
return;
|
|
@@ -272,7 +312,7 @@ export async function runRoutinesRuntimeCommand(args: readonly string[], ctx: Co
|
|
|
272
312
|
return;
|
|
273
313
|
}
|
|
274
314
|
const receipt = receiptStoreFromContext(ctx).get(id);
|
|
275
|
-
ctx.print(receipt ? formatRoutineScheduleReceipt(receipt) : `Unknown routine schedule receipt
|
|
315
|
+
ctx.print(receipt ? formatRoutineScheduleReceipt(receipt) : `Unknown routine schedule receipt ${id}`);
|
|
276
316
|
return;
|
|
277
317
|
}
|
|
278
318
|
if (sub === 'create') {
|
|
@@ -284,11 +324,15 @@ export async function runRoutinesRuntimeCommand(args: readonly string[], ctx: Co
|
|
|
284
324
|
steps,
|
|
285
325
|
triggers: splitList(parsed.flags.get('triggers')),
|
|
286
326
|
tags: splitList(parsed.flags.get('tags')),
|
|
327
|
+
requirements: buildAgentSkillRequirements({
|
|
328
|
+
env: splitList(parsed.flags.get('requires-env')),
|
|
329
|
+
commands: splitList(parsed.flags.get('requires-command') ?? parsed.flags.get('requires-commands')),
|
|
330
|
+
}),
|
|
287
331
|
enabled: parsed.flags.get('enabled') === 'true',
|
|
288
332
|
source: 'user',
|
|
289
|
-
provenance: '
|
|
333
|
+
provenance: 'Command',
|
|
290
334
|
});
|
|
291
|
-
ctx.print(
|
|
335
|
+
ctx.print(formatRoutineReceipt('Created Agent routine', routine));
|
|
292
336
|
return;
|
|
293
337
|
}
|
|
294
338
|
if (sub === 'update') {
|
|
@@ -304,9 +348,15 @@ export async function runRoutinesRuntimeCommand(args: readonly string[], ctx: Co
|
|
|
304
348
|
steps: parsed.flags.get('steps'),
|
|
305
349
|
triggers: parsed.flags.has('triggers') ? splitList(parsed.flags.get('triggers')) : undefined,
|
|
306
350
|
tags: parsed.flags.has('tags') ? splitList(parsed.flags.get('tags')) : undefined,
|
|
307
|
-
|
|
351
|
+
requirements: parsed.flags.has('requires-env') || parsed.flags.has('requires-command') || parsed.flags.has('requires-commands')
|
|
352
|
+
? buildAgentSkillRequirements({
|
|
353
|
+
env: splitList(parsed.flags.get('requires-env')),
|
|
354
|
+
commands: splitList(parsed.flags.get('requires-command') ?? parsed.flags.get('requires-commands')),
|
|
355
|
+
})
|
|
356
|
+
: undefined,
|
|
357
|
+
provenance: 'Command',
|
|
308
358
|
});
|
|
309
|
-
ctx.print(
|
|
359
|
+
ctx.print(formatRoutineReceipt('Updated Agent routine', updated));
|
|
310
360
|
return;
|
|
311
361
|
}
|
|
312
362
|
if (sub === 'enable' || sub === 'disable') {
|
|
@@ -316,7 +366,7 @@ export async function runRoutinesRuntimeCommand(args: readonly string[], ctx: Co
|
|
|
316
366
|
return;
|
|
317
367
|
}
|
|
318
368
|
const routine = routineRegistry.setEnabled(id, sub === 'enable');
|
|
319
|
-
ctx.print(`${sub === 'enable' ? 'Enabled' : 'Disabled'} Agent routine
|
|
369
|
+
ctx.print(formatRoutineReceipt(`${sub === 'enable' ? 'Enabled' : 'Disabled'} Agent routine`, routine));
|
|
320
370
|
return;
|
|
321
371
|
}
|
|
322
372
|
if (sub === 'start' || sub === 'run') {
|
|
@@ -326,9 +376,13 @@ export async function runRoutinesRuntimeCommand(args: readonly string[], ctx: Co
|
|
|
326
376
|
return;
|
|
327
377
|
}
|
|
328
378
|
const routine = routineRegistry.markStarted(id);
|
|
379
|
+
const readiness = evaluateAgentRoutineReadiness(routine);
|
|
329
380
|
ctx.print([
|
|
330
|
-
`Started Agent routine ${routine.id}
|
|
331
|
-
|
|
381
|
+
`Started Agent routine ${routine.id}`,
|
|
382
|
+
` id ${routine.id}`,
|
|
383
|
+
` name ${routine.name}`,
|
|
384
|
+
` readiness: ${readiness.ready ? 'ready' : `needs setup (${readiness.missing.map(formatAgentSkillRequirement).join(', ')})`}`,
|
|
385
|
+
' policy same main conversation; no hidden job, runtime mutation, or external side effect was started',
|
|
332
386
|
'',
|
|
333
387
|
routine.steps,
|
|
334
388
|
].join('\n'));
|
|
@@ -341,7 +395,7 @@ export async function runRoutinesRuntimeCommand(args: readonly string[], ctx: Co
|
|
|
341
395
|
return;
|
|
342
396
|
}
|
|
343
397
|
const routine = routineRegistry.markReviewed(id);
|
|
344
|
-
ctx.print(
|
|
398
|
+
ctx.print(formatRoutineReceipt('Reviewed Agent routine', routine));
|
|
345
399
|
return;
|
|
346
400
|
}
|
|
347
401
|
if (sub === 'stale') {
|
|
@@ -351,7 +405,7 @@ export async function runRoutinesRuntimeCommand(args: readonly string[], ctx: Co
|
|
|
351
405
|
return;
|
|
352
406
|
}
|
|
353
407
|
const routine = routineRegistry.markStale(id, args.slice(2).join(' '));
|
|
354
|
-
ctx.print(
|
|
408
|
+
ctx.print(formatRoutineReceipt('Marked Agent routine stale', routine));
|
|
355
409
|
return;
|
|
356
410
|
}
|
|
357
411
|
if (sub === 'promote' || sub === 'schedule' || sub === 'promote-schedule') {
|
|
@@ -370,10 +424,10 @@ export async function runRoutinesRuntimeCommand(args: readonly string[], ctx: Co
|
|
|
370
424
|
return;
|
|
371
425
|
}
|
|
372
426
|
const removed = routineRegistry.deleteRoutine(id);
|
|
373
|
-
ctx.print(
|
|
427
|
+
ctx.print(formatRoutineReceipt('Deleted Agent routine', removed));
|
|
374
428
|
return;
|
|
375
429
|
}
|
|
376
|
-
ctx.print('Usage: /routines [list|enabled|discover|import-discovered|search|show|receipts|reconcile|receipt|create|update|enable|disable|start|review|stale|promote|delete]');
|
|
430
|
+
ctx.print('Usage: /routines [list|enabled|attention|discover|import-discovered|search|show|receipts|reconcile|receipt|create|update|enable|disable|start|review|stale|promote|delete]');
|
|
377
431
|
} catch (error) {
|
|
378
432
|
printError(ctx, error);
|
|
379
433
|
}
|
|
@@ -383,8 +437,8 @@ export function registerRoutinesRuntimeCommands(registry: CommandRegistry): void
|
|
|
383
437
|
registry.register({
|
|
384
438
|
name: 'routines',
|
|
385
439
|
aliases: ['routine'],
|
|
386
|
-
description: 'Manage local
|
|
387
|
-
usage: '[list|enabled|discover|import-discovered <name> --yes|search <query>|show <id>|receipts|reconcile|receipt <id>|create --name <name> --description <summary> --steps <steps
|
|
440
|
+
description: 'Manage Agent-local routines',
|
|
441
|
+
usage: '[list|enabled|attention|discover|import-discovered <name> --yes|search <query>|show <id>|receipts|reconcile|receipt <id>|create --name <name> --description <summary> --steps <steps> [--requires-env A,B] [--requires-command gh,jq]|update <id> [--name ...] [--description ...] [--steps ...]|enable <id>|disable <id>|start <id>|review <id>|stale <id> <reason...>|promote <id> --cron <expr> [--delivery-channel slack] --yes|delete <id> --yes]',
|
|
388
442
|
handler: runRoutinesRuntimeCommand,
|
|
389
443
|
});
|
|
390
444
|
}
|
|
@@ -22,7 +22,6 @@ import { GOODVIBES_AGENT_SURFACE_ROOT } from '../../config/surface.ts';
|
|
|
22
22
|
import type { ProviderApi } from '@pellux/goodvibes-sdk/platform/providers';
|
|
23
23
|
import type {
|
|
24
24
|
ShellAgentManagerService,
|
|
25
|
-
ShellAcpManagerService,
|
|
26
25
|
ShellAutomationManagerService,
|
|
27
26
|
ShellAutomationManagerRuntimeService,
|
|
28
27
|
ShellModeManagerService,
|
|
@@ -32,7 +31,7 @@ import type {
|
|
|
32
31
|
|
|
33
32
|
function requireContextValue<T>(value: T | null | undefined, name: string): T {
|
|
34
33
|
if (value == null) {
|
|
35
|
-
throw new Error(`commandContext.${name} is
|
|
34
|
+
throw new Error(`commandContext.${name} is unavailable in this Agent runtime`);
|
|
36
35
|
}
|
|
37
36
|
return value;
|
|
38
37
|
}
|
|
@@ -274,10 +273,6 @@ export function requireAgentManager(context: CommandContext): ShellAgentManagerS
|
|
|
274
273
|
return requireContextValue(context.ops.agentManager, 'ops.agentManager') as ShellAgentManagerService;
|
|
275
274
|
}
|
|
276
275
|
|
|
277
|
-
export function requireAcpManager(context: CommandContext): ShellAcpManagerService {
|
|
278
|
-
return requireContextValue(context.ops.acpManager, 'ops.acpManager') as ShellAcpManagerService;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
276
|
export function requireModeManager(context: CommandContext): ShellModeManagerService {
|
|
282
277
|
return requireContextValue(context.ops.modeManager, 'ops.modeManager') as ShellModeManagerService;
|
|
283
278
|
}
|
|
@@ -285,11 +280,3 @@ export function requireModeManager(context: CommandContext): ShellModeManagerSer
|
|
|
285
280
|
export function requireAutomationManager(context: CommandContext): ShellAutomationManagerRuntimeService {
|
|
286
281
|
return requireContextValue(context.ops.automationManager, 'ops.automationManager') as ShellAutomationManagerRuntimeService;
|
|
287
282
|
}
|
|
288
|
-
|
|
289
|
-
export function requireSandboxSessionRegistry(context: CommandContext) {
|
|
290
|
-
return requireContextValue(context.workspace.sandboxSessionRegistry, 'workspace.sandboxSessionRegistry');
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
export function requireWorktreeRegistry(context: CommandContext) {
|
|
294
|
-
return requireContextValue(context.workspace.worktreeRegistry, 'workspace.worktreeRegistry');
|
|
295
|
-
}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
buildReminderSchedulePreview,
|
|
9
9
|
createReminderSchedule,
|
|
10
10
|
parseReminderScheduleArgs,
|
|
11
|
-
|
|
11
|
+
resolveReminderConnectedHostConnection,
|
|
12
12
|
} from '../../agent/reminder-schedule.ts';
|
|
13
13
|
import {
|
|
14
14
|
formatReminderScheduleFailure,
|
|
@@ -18,8 +18,8 @@ import {
|
|
|
18
18
|
import { AgentRoutineRegistry } from '../../agent/routine-registry.ts';
|
|
19
19
|
import {
|
|
20
20
|
buildRoutineSchedulePreview,
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
promoteRoutineToConnectedSchedule,
|
|
22
|
+
resolveAgentConnectedHostConnection,
|
|
23
23
|
} from '../../agent/routine-schedule-promotion.ts';
|
|
24
24
|
import { parseRoutineSchedulePromotionArgs } from '../../agent/routine-schedule-args.ts';
|
|
25
25
|
import {
|
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
} from '../../agent/routine-schedule-receipts.ts';
|
|
37
37
|
import type { CommandContext } from '../command-registry.ts';
|
|
38
38
|
import { requireShellPaths } from './runtime-services.ts';
|
|
39
|
+
import { executeConfirmedOperatorAction } from './operator-actions-runtime.ts';
|
|
39
40
|
|
|
40
41
|
function formatSchedule(schedule: AutomationScheduleDefinition): string {
|
|
41
42
|
switch (schedule.kind) {
|
|
@@ -64,10 +65,11 @@ function formatPrompt(job: AutomationJob): string {
|
|
|
64
65
|
function printReadOnlyScheduleBoundary(print: (text: string) => void, requestedAction: string): void {
|
|
65
66
|
print([
|
|
66
67
|
'GoodVibes Agent local schedule commands are read-only in this runtime.',
|
|
67
|
-
` requested
|
|
68
|
-
' policy
|
|
69
|
-
' use
|
|
70
|
-
'
|
|
68
|
+
` requested ${requestedAction}`,
|
|
69
|
+
' policy no hidden local Agent automation jobs or immediate automation runs',
|
|
70
|
+
' use /schedule list',
|
|
71
|
+
' connected run route /automation schedule run <schedule-id> --yes',
|
|
72
|
+
' schedule route use /schedule promote-routine <routine> --cron <expr> --yes to create a connected schedule explicitly',
|
|
71
73
|
].join('\n'));
|
|
72
74
|
}
|
|
73
75
|
|
|
@@ -83,7 +85,7 @@ async function promoteRoutineSchedule(args: readonly string[], ctx: CommandConte
|
|
|
83
85
|
const shellPaths = requireShellPaths(ctx);
|
|
84
86
|
const routine = AgentRoutineRegistry.fromShellPaths(shellPaths).get(parsed.routineId ?? '');
|
|
85
87
|
if (!routine) {
|
|
86
|
-
ctx.print(`Unknown Agent routine
|
|
88
|
+
ctx.print(`Unknown Agent routine ${parsed.routineId ?? ''}`);
|
|
87
89
|
return;
|
|
88
90
|
}
|
|
89
91
|
const preview = buildRoutineSchedulePreview(routine, parsed);
|
|
@@ -91,8 +93,8 @@ async function promoteRoutineSchedule(args: readonly string[], ctx: CommandConte
|
|
|
91
93
|
ctx.print(formatRoutineSchedulePreview(preview));
|
|
92
94
|
return;
|
|
93
95
|
}
|
|
94
|
-
const connection =
|
|
95
|
-
const result = await
|
|
96
|
+
const connection = resolveAgentConnectedHostConnection(ctx.platform.configManager, shellPaths.homeDirectory);
|
|
97
|
+
const result = await promoteRoutineToConnectedSchedule(connection, preview);
|
|
96
98
|
const receipt = RoutineScheduleReceiptStore.fromShellPaths(shellPaths).append(connection, preview, result);
|
|
97
99
|
ctx.print(result.ok ? `${formatRoutineScheduleSuccess(result)}\n receipt: ${receipt.id}` : `${formatRoutineScheduleFailure(result)}\n receipt: ${receipt.id}`);
|
|
98
100
|
}
|
|
@@ -112,7 +114,7 @@ async function createReminder(args: readonly string[], ctx: CommandContext): Pro
|
|
|
112
114
|
return;
|
|
113
115
|
}
|
|
114
116
|
const shellPaths = requireShellPaths(ctx);
|
|
115
|
-
const connection =
|
|
117
|
+
const connection = resolveReminderConnectedHostConnection(ctx.platform.configManager, shellPaths.homeDirectory);
|
|
116
118
|
const result = await createReminderSchedule(connection, preview);
|
|
117
119
|
ctx.print(result.ok ? formatReminderScheduleSuccess(result) : formatReminderScheduleFailure(result));
|
|
118
120
|
}
|
|
@@ -121,7 +123,7 @@ export function registerScheduleRuntimeCommands(registry: CommandRegistry): void
|
|
|
121
123
|
registry.register({
|
|
122
124
|
name: 'schedule',
|
|
123
125
|
aliases: ['sched'],
|
|
124
|
-
description: 'Inspect schedules, create confirmed reminders, and explicitly promote local
|
|
126
|
+
description: 'Inspect schedules, create confirmed reminders, and explicitly promote Agent-local routines to connected schedules',
|
|
125
127
|
usage: 'list | remind --at <iso> --message <text> --yes | receipts | reconcile | receipt <id> | promote-routine <routine-id> --cron <expr> [--delivery-channel slack] --yes',
|
|
126
128
|
argsHint: 'list | remind --at <iso> --message <text> --yes | receipts | reconcile | receipt <id> | promote-routine <routine-id> --cron <expr> [--delivery-channel slack] --yes',
|
|
127
129
|
async handler(args, ctx) {
|
|
@@ -144,7 +146,7 @@ export function registerScheduleRuntimeCommands(registry: CommandRegistry): void
|
|
|
144
146
|
|
|
145
147
|
if (sub === 'reconcile' || sub === 'sync' || sub === 'status') {
|
|
146
148
|
const shellPaths = requireShellPaths(ctx);
|
|
147
|
-
const connection =
|
|
149
|
+
const connection = resolveAgentConnectedHostConnection(ctx.platform.configManager, shellPaths.homeDirectory);
|
|
148
150
|
const result = await reconcileRoutineScheduleReceipts(connection, RoutineScheduleReceiptStore.fromShellPaths(shellPaths).snapshot());
|
|
149
151
|
ctx.print(formatRoutineScheduleCorrelation(result));
|
|
150
152
|
return;
|
|
@@ -157,7 +159,7 @@ export function registerScheduleRuntimeCommands(registry: CommandRegistry): void
|
|
|
157
159
|
return;
|
|
158
160
|
}
|
|
159
161
|
const receipt = RoutineScheduleReceiptStore.fromShellPaths(requireShellPaths(ctx)).get(id);
|
|
160
|
-
ctx.print(receipt ? formatRoutineScheduleReceipt(receipt) : `Unknown routine schedule receipt
|
|
162
|
+
ctx.print(receipt ? formatRoutineScheduleReceipt(receipt) : `Unknown routine schedule receipt ${id}`);
|
|
161
163
|
return;
|
|
162
164
|
}
|
|
163
165
|
|
|
@@ -176,20 +178,30 @@ export function registerScheduleRuntimeCommands(registry: CommandRegistry): void
|
|
|
176
178
|
);
|
|
177
179
|
return;
|
|
178
180
|
}
|
|
179
|
-
const lines = ['Automation jobs
|
|
181
|
+
const lines = ['Automation jobs', ''];
|
|
180
182
|
for (const job of jobs) {
|
|
181
183
|
const status = job.enabled ? '● enabled ' : '○ paused ';
|
|
182
184
|
const next = formatNextRun(job.nextRunAt);
|
|
183
185
|
const last = job.lastRunAt ? new Date(job.lastRunAt).toLocaleString() : 'never';
|
|
184
|
-
lines.push(` ${job.id.slice(0, 12)} ${status} runs
|
|
185
|
-
lines.push(` name
|
|
186
|
-
lines.push(` prompt
|
|
186
|
+
lines.push(` ${job.id.slice(0, 12)} ${status} runs ${job.runCount} next ${next} last ${last}`);
|
|
187
|
+
lines.push(` name ${job.name} schedule ${formatSchedule(job.schedule)}`);
|
|
188
|
+
lines.push(` prompt ${formatPrompt(job)}`);
|
|
187
189
|
}
|
|
188
190
|
ctx.print(lines.join('\n'));
|
|
189
191
|
return;
|
|
190
192
|
}
|
|
191
193
|
|
|
192
|
-
if (sub === '
|
|
194
|
+
if (sub === 'run') {
|
|
195
|
+
const scheduleId = args[1] ?? '';
|
|
196
|
+
if (!scheduleId) {
|
|
197
|
+
ctx.print('Usage: /schedule run <schedule-id> --yes');
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
await executeConfirmedOperatorAction(ctx, 'schedules.run', 'scheduleId', scheduleId, args.slice(2), '/schedule run <schedule-id> --yes');
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (sub === 'add' || sub === 'remove' || sub === 'enable' || sub === 'disable') {
|
|
193
205
|
printReadOnlyScheduleBoundary(ctx.print, `/schedule ${args.join(' ')}`.trim());
|
|
194
206
|
return;
|
|
195
207
|
}
|
|
@@ -200,9 +212,10 @@ export function registerScheduleRuntimeCommands(registry: CommandRegistry): void
|
|
|
200
212
|
+ ' /schedule receipts\n'
|
|
201
213
|
+ ' /schedule reconcile\n'
|
|
202
214
|
+ ' /schedule receipt <receipt-id>\n'
|
|
215
|
+
+ ' /schedule run <schedule-id> --yes\n'
|
|
203
216
|
+ ' /schedule remind (--cron <expr>|--every <interval>|--at <iso-time>) (--message <text>|<text...>) [--delivery-channel <channel>|--delivery-route <route>|--delivery-webhook <url>] --yes\n'
|
|
204
217
|
+ ' /schedule promote-routine <routine-id> (--cron <expr>|--every <interval>|--at <iso-time>) [--delivery-channel <channel>|--delivery-route <route>|--delivery-webhook <url>] --yes\n'
|
|
205
|
-
+ ' Local schedule mutations
|
|
218
|
+
+ ' Local schedule mutations remain blocked; schedule run is a confirmed connected-host action.'
|
|
206
219
|
);
|
|
207
220
|
},
|
|
208
221
|
});
|