@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
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import type { Tool } from '@pellux/goodvibes-sdk/platform/types';
|
|
2
|
+
import type { ToolRegistry } from '@pellux/goodvibes-sdk/platform/tools';
|
|
3
|
+
import type { ShellPathService } from '@/runtime/index.ts';
|
|
4
|
+
import {
|
|
5
|
+
buildReminderSchedulePreview,
|
|
6
|
+
createReminderSchedule,
|
|
7
|
+
parseReminderScheduleArgs,
|
|
8
|
+
resolveReminderConnectedHostConnection,
|
|
9
|
+
type ReminderScheduleResult,
|
|
10
|
+
} from '../agent/reminder-schedule.ts';
|
|
11
|
+
import {
|
|
12
|
+
formatReminderScheduleFailure,
|
|
13
|
+
formatReminderSchedulePreview,
|
|
14
|
+
formatReminderScheduleSuccess,
|
|
15
|
+
} from '../agent/reminder-schedule-format.ts';
|
|
16
|
+
import type { AgentConnectedHostConfigReader } from '../agent/routine-schedule-promotion.ts';
|
|
17
|
+
|
|
18
|
+
type ReminderScheduleKind = 'at' | 'every' | 'cron';
|
|
19
|
+
|
|
20
|
+
export interface AgentReminderScheduleToolArgs {
|
|
21
|
+
readonly message?: unknown;
|
|
22
|
+
readonly scheduleKind?: unknown;
|
|
23
|
+
readonly scheduleValue?: unknown;
|
|
24
|
+
readonly timezone?: unknown;
|
|
25
|
+
readonly name?: unknown;
|
|
26
|
+
readonly provider?: unknown;
|
|
27
|
+
readonly model?: unknown;
|
|
28
|
+
readonly deliveryChannel?: unknown;
|
|
29
|
+
readonly deliveryRoute?: unknown;
|
|
30
|
+
readonly deliveryWebhook?: unknown;
|
|
31
|
+
readonly deliveryLink?: unknown;
|
|
32
|
+
readonly disabled?: unknown;
|
|
33
|
+
readonly confirm?: unknown;
|
|
34
|
+
readonly explicitUserRequest?: unknown;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const SCHEDULE_KINDS: readonly ReminderScheduleKind[] = ['at', 'every', 'cron'];
|
|
38
|
+
|
|
39
|
+
function isScheduleKind(value: unknown): value is ReminderScheduleKind {
|
|
40
|
+
return typeof value === 'string' && SCHEDULE_KINDS.includes(value as ReminderScheduleKind);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function readString(value: unknown): string {
|
|
44
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function readOptionalString(value: unknown): string | null {
|
|
48
|
+
const text = readString(value);
|
|
49
|
+
return text ? text : null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function readBoolean(value: unknown): boolean {
|
|
53
|
+
return value === true || value === 'true' || value === 'yes';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function addOptionalArg(args: string[], flag: string, value: unknown): void {
|
|
57
|
+
const text = readOptionalString(value);
|
|
58
|
+
if (!text) return;
|
|
59
|
+
args.push(flag, text);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function scheduleFlag(kind: ReminderScheduleKind): string {
|
|
63
|
+
if (kind === 'cron') return '--cron';
|
|
64
|
+
if (kind === 'every') return '--every';
|
|
65
|
+
return '--at';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function buildReminderScheduleArgs(rawArgs: AgentReminderScheduleToolArgs): readonly string[] {
|
|
69
|
+
const message = readOptionalString(rawArgs.message);
|
|
70
|
+
const scheduleValue = readOptionalString(rawArgs.scheduleValue);
|
|
71
|
+
if (!message) throw new Error('message is required.');
|
|
72
|
+
if (!isScheduleKind(rawArgs.scheduleKind)) throw new Error('scheduleKind must be one of: at, every, cron.');
|
|
73
|
+
if (!scheduleValue) throw new Error('scheduleValue is required.');
|
|
74
|
+
|
|
75
|
+
const args = [
|
|
76
|
+
scheduleFlag(rawArgs.scheduleKind),
|
|
77
|
+
scheduleValue,
|
|
78
|
+
'--message',
|
|
79
|
+
message,
|
|
80
|
+
];
|
|
81
|
+
addOptionalArg(args, '--timezone', rawArgs.timezone);
|
|
82
|
+
addOptionalArg(args, '--name', rawArgs.name);
|
|
83
|
+
addOptionalArg(args, '--provider', rawArgs.provider);
|
|
84
|
+
addOptionalArg(args, '--model', rawArgs.model);
|
|
85
|
+
addOptionalArg(args, '--delivery-channel', rawArgs.deliveryChannel);
|
|
86
|
+
addOptionalArg(args, '--delivery-route', rawArgs.deliveryRoute);
|
|
87
|
+
addOptionalArg(args, '--delivery-webhook', rawArgs.deliveryWebhook);
|
|
88
|
+
addOptionalArg(args, '--delivery-link', rawArgs.deliveryLink);
|
|
89
|
+
if (readBoolean(rawArgs.disabled)) args.push('--disabled');
|
|
90
|
+
if (readBoolean(rawArgs.confirm)) args.push('--yes');
|
|
91
|
+
return args;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function outputForResult(result: ReminderScheduleResult): { readonly success: boolean; readonly output?: string; readonly error?: string } {
|
|
95
|
+
if (result.ok) {
|
|
96
|
+
return {
|
|
97
|
+
success: true,
|
|
98
|
+
output: formatReminderScheduleSuccess(result),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
success: false,
|
|
103
|
+
error: formatReminderScheduleFailure(result),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function confirmationError(preview: ReturnType<typeof buildReminderSchedulePreview>): string {
|
|
108
|
+
return [
|
|
109
|
+
formatReminderSchedulePreview(preview),
|
|
110
|
+
'',
|
|
111
|
+
'Model tool confirmation required. Call this tool with confirm:true only when the user explicitly asked GoodVibes Agent to create this reminder or schedule.',
|
|
112
|
+
'Do not create reminders from vague suggestions, brainstorming, routine startup, or inferred follow-up work.',
|
|
113
|
+
].join('\n');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function createAgentReminderScheduleTool(
|
|
117
|
+
shellPaths: ShellPathService,
|
|
118
|
+
configManager: AgentConnectedHostConfigReader,
|
|
119
|
+
): Tool {
|
|
120
|
+
return {
|
|
121
|
+
definition: {
|
|
122
|
+
name: 'agent_reminder_schedule',
|
|
123
|
+
description: [
|
|
124
|
+
'Create one connected GoodVibes Agent reminder schedule from the main conversation.',
|
|
125
|
+
'Use only when the user explicitly asks to be reminded or asks Agent to schedule a reminder.',
|
|
126
|
+
'This calls the public schedules.create route on the connected GoodVibes host; it does not manage connected-host hosting, create a local scheduler, create separate Agent jobs, use delegated review, or write to default knowledge or non-Agent knowledge segments.',
|
|
127
|
+
'Set confirm:true only for an explicit user request. Otherwise return the preview/confirmation error.',
|
|
128
|
+
].join(' '),
|
|
129
|
+
parameters: {
|
|
130
|
+
type: 'object',
|
|
131
|
+
properties: {
|
|
132
|
+
message: {
|
|
133
|
+
type: 'string',
|
|
134
|
+
description: 'Reminder text to deliver when the schedule fires.',
|
|
135
|
+
},
|
|
136
|
+
scheduleKind: {
|
|
137
|
+
type: 'string',
|
|
138
|
+
enum: [...SCHEDULE_KINDS],
|
|
139
|
+
description: 'Schedule selector: at for one timestamp, every for an interval, cron for a cron expression.',
|
|
140
|
+
},
|
|
141
|
+
scheduleValue: {
|
|
142
|
+
type: 'string',
|
|
143
|
+
description: 'ISO timestamp, interval, or cron expression matching scheduleKind.',
|
|
144
|
+
},
|
|
145
|
+
timezone: {
|
|
146
|
+
type: 'string',
|
|
147
|
+
description: 'Optional IANA timezone for cron/at schedules.',
|
|
148
|
+
},
|
|
149
|
+
name: {
|
|
150
|
+
type: 'string',
|
|
151
|
+
description: 'Optional connected schedule display name.',
|
|
152
|
+
},
|
|
153
|
+
provider: {
|
|
154
|
+
type: 'string',
|
|
155
|
+
description: 'Optional provider row id for reminder execution.',
|
|
156
|
+
},
|
|
157
|
+
model: {
|
|
158
|
+
type: 'string',
|
|
159
|
+
description: 'Optional model id for reminder execution.',
|
|
160
|
+
},
|
|
161
|
+
deliveryChannel: {
|
|
162
|
+
type: 'string',
|
|
163
|
+
description: 'Optional delivery channel target: surfaceKind:routeId:label, for example slack:ops:Ops.',
|
|
164
|
+
},
|
|
165
|
+
deliveryRoute: {
|
|
166
|
+
type: 'string',
|
|
167
|
+
description: 'Optional connected route target: routeId:label.',
|
|
168
|
+
},
|
|
169
|
+
deliveryWebhook: {
|
|
170
|
+
type: 'string',
|
|
171
|
+
description: 'Optional http(s) webhook target.',
|
|
172
|
+
},
|
|
173
|
+
deliveryLink: {
|
|
174
|
+
type: 'string',
|
|
175
|
+
description: 'Optional link delivery target.',
|
|
176
|
+
},
|
|
177
|
+
disabled: {
|
|
178
|
+
type: 'boolean',
|
|
179
|
+
description: 'Create the schedule disabled.',
|
|
180
|
+
},
|
|
181
|
+
confirm: {
|
|
182
|
+
type: 'boolean',
|
|
183
|
+
description: 'Required true only when the user explicitly asked to create this reminder.',
|
|
184
|
+
},
|
|
185
|
+
explicitUserRequest: {
|
|
186
|
+
type: 'string',
|
|
187
|
+
description: 'Short quote or summary of the user request that authorized this reminder creation.',
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
required: ['message', 'scheduleKind', 'scheduleValue', 'confirm', 'explicitUserRequest'],
|
|
191
|
+
additionalProperties: false,
|
|
192
|
+
},
|
|
193
|
+
sideEffects: ['network', 'state'],
|
|
194
|
+
},
|
|
195
|
+
execute: async (rawArgs: unknown) => {
|
|
196
|
+
try {
|
|
197
|
+
const args = rawArgs as AgentReminderScheduleToolArgs;
|
|
198
|
+
const explicitUserRequest = readOptionalString(args.explicitUserRequest);
|
|
199
|
+
if (!explicitUserRequest) {
|
|
200
|
+
return {
|
|
201
|
+
success: false,
|
|
202
|
+
error: 'explicitUserRequest is required so reminder creation stays tied to a direct user request.',
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
const parsed = parseReminderScheduleArgs(buildReminderScheduleArgs(args));
|
|
206
|
+
if (parsed.errors.length > 0) {
|
|
207
|
+
return {
|
|
208
|
+
success: false,
|
|
209
|
+
error: parsed.errors.join('\n'),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
const preview = buildReminderSchedulePreview(parsed);
|
|
213
|
+
if (!parsed.yes) {
|
|
214
|
+
return {
|
|
215
|
+
success: false,
|
|
216
|
+
error: confirmationError(preview),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
const connection = resolveReminderConnectedHostConnection(configManager, shellPaths.homeDirectory);
|
|
220
|
+
return outputForResult(await createReminderSchedule(connection, preview));
|
|
221
|
+
} catch (error) {
|
|
222
|
+
return {
|
|
223
|
+
success: false,
|
|
224
|
+
error: error instanceof Error ? error.message : String(error),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export function registerAgentReminderScheduleTool(
|
|
232
|
+
registry: ToolRegistry,
|
|
233
|
+
shellPaths: ShellPathService,
|
|
234
|
+
configManager: AgentConnectedHostConfigReader,
|
|
235
|
+
): void {
|
|
236
|
+
registry.register(createAgentReminderScheduleTool(shellPaths, configManager));
|
|
237
|
+
}
|
|
@@ -83,8 +83,6 @@ const READ_ONLY_AGENT_TOOL_MODES = [
|
|
|
83
83
|
'templates',
|
|
84
84
|
'get',
|
|
85
85
|
'budget',
|
|
86
|
-
'wrfc-chains',
|
|
87
|
-
'wrfc-history',
|
|
88
86
|
'cohort-status',
|
|
89
87
|
'cohort-report',
|
|
90
88
|
] as const;
|
|
@@ -124,13 +122,13 @@ const READ_ONLY_QUERY_TOOL_MODE_SET = new Set<string>(READ_ONLY_QUERY_TOOL_MODES
|
|
|
124
122
|
const READ_ONLY_CONTROL_TOOL_MODE_SET = new Set<string>(READ_ONLY_CONTROL_TOOL_MODES);
|
|
125
123
|
|
|
126
124
|
const LOCAL_AGENT_DENIAL = [
|
|
127
|
-
'GoodVibes Agent does not
|
|
125
|
+
'GoodVibes Agent does not create coding-role Agent jobs or run local delegated review chains.',
|
|
128
126
|
'Keep ordinary assistant work serial in the main conversation.',
|
|
129
127
|
'For explicit build/fix/review work, delegate one request to GoodVibes TUI through the public shared-session/build-delegation contract with the full original user ask.',
|
|
130
128
|
].join(' ');
|
|
131
129
|
|
|
132
130
|
const LOCAL_CODING_TOOL_DENIAL = [
|
|
133
|
-
'GoodVibes Agent does not perform direct local file mutation, local
|
|
131
|
+
'GoodVibes Agent does not perform direct local file mutation, local delegated review workflow execution, or local execution-isolation work from the main conversation.',
|
|
134
132
|
'For explicit build/fix/review/code execution work, delegate one request to GoodVibes TUI through the public shared-session/build-delegation contract with the full original user ask.',
|
|
135
133
|
'For durable Agent memory, skills, personas, routines, and knowledge, use the Agent-owned commands and isolated Agent Knowledge routes.',
|
|
136
134
|
].join(' ');
|
|
@@ -142,9 +140,9 @@ const BACKGROUND_EXEC_DENIAL = [
|
|
|
142
140
|
].join(' ');
|
|
143
141
|
|
|
144
142
|
const REMOTE_MUTATION_DENIAL = [
|
|
145
|
-
'GoodVibes Agent only inspects remote
|
|
143
|
+
'GoodVibes Agent only inspects remote build-host pools, contracts, artifacts, and review summaries from the main conversation.',
|
|
146
144
|
'Remote pool creation, assignment, unassignment, and artifact import are disabled here.',
|
|
147
|
-
'Use explicit GoodVibes TUI delegation
|
|
145
|
+
'Use explicit GoodVibes TUI delegation for build/fix/review execution changes.',
|
|
148
146
|
].join(' ');
|
|
149
147
|
|
|
150
148
|
const CHANNEL_ACTION_DENIAL = [
|
|
@@ -174,7 +172,7 @@ const STATE_MUTATION_DENIAL = [
|
|
|
174
172
|
const SETTINGS_MUTATION_DENIAL = [
|
|
175
173
|
'GoodVibes Agent does not mutate configuration through model tools in the main conversation.',
|
|
176
174
|
'Use explicit Agent CLI/slash settings commands for intentional config changes.',
|
|
177
|
-
'Secrets, tokens, passwords,
|
|
175
|
+
'Secrets, tokens, passwords, connected-host lifecycle settings, and connected-host exposure settings require explicit user action outside the model tool surface.',
|
|
178
176
|
].join(' ');
|
|
179
177
|
|
|
180
178
|
const INSPECT_WRITE_DENIAL = [
|
|
@@ -191,8 +189,8 @@ const DURABLE_WORKFLOW_MUTATION_DENIAL = [
|
|
|
191
189
|
|
|
192
190
|
const CONTROL_MUTATION_DENIAL = [
|
|
193
191
|
'GoodVibes Agent only inspects runtime-owned product-control surfaces from the main conversation.',
|
|
194
|
-
'Product-control mutation,
|
|
195
|
-
'Use explicit Agent CLI/slash commands for Agent-owned changes, and keep
|
|
192
|
+
'Product-control mutation, connected-host lifecycle, and connected-host posture changes are disabled here.',
|
|
193
|
+
'Use explicit Agent CLI/slash commands for Agent-owned changes, and keep connected-host lifecycle external.',
|
|
196
194
|
].join(' ');
|
|
197
195
|
|
|
198
196
|
export function installAgentToolPolicyGuard(registry: ToolRegistry, options: AgentToolPolicyGuardOptions = {}): void {
|
|
@@ -209,8 +207,8 @@ export function installAgentToolPolicyGuard(registry: ToolRegistry, options: Age
|
|
|
209
207
|
allowedModes: READ_ONLY_REMOTE_TOOL_MODES,
|
|
210
208
|
modeSet: READ_ONLY_REMOTE_TOOL_MODE_SET,
|
|
211
209
|
description: [
|
|
212
|
-
'Read-only remote
|
|
213
|
-
'Pool creation,
|
|
210
|
+
'Read-only remote build-host inspection for GoodVibes Agent.',
|
|
211
|
+
'Pool creation, host assignment, unassignment, and artifact import are disabled in the main conversation.',
|
|
214
212
|
].join(' '),
|
|
215
213
|
denial: REMOTE_MUTATION_DENIAL,
|
|
216
214
|
});
|
|
@@ -250,7 +248,7 @@ export function installAgentToolPolicyGuard(registry: ToolRegistry, options: Age
|
|
|
250
248
|
modeSet: READ_ONLY_CONTROL_TOOL_MODE_SET,
|
|
251
249
|
description: [
|
|
252
250
|
'Read-only product-control inspection for GoodVibes Agent.',
|
|
253
|
-
'Command, panel, and subscription catalogs can be inspected, but product-control mutation and
|
|
251
|
+
'Command, panel, and subscription catalogs can be inspected, but product-control mutation and connected-host lifecycle are external.',
|
|
254
252
|
].join(' '),
|
|
255
253
|
denial: CONTROL_MUTATION_DENIAL,
|
|
256
254
|
});
|
|
@@ -363,7 +361,7 @@ export function wrapBlockedSettingsToolForAgentPolicy(tool: Tool): void {
|
|
|
363
361
|
tool.definition.description = [
|
|
364
362
|
'Blocked in GoodVibes Agent main conversation: configuration mutation.',
|
|
365
363
|
'Use explicit Agent CLI/slash settings commands for intentional config changes.',
|
|
366
|
-
'
|
|
364
|
+
'Connected-host lifecycle and service exposure remain externally managed outside GoodVibes Agent.',
|
|
367
365
|
].join(' ');
|
|
368
366
|
tool.definition.sideEffects = [];
|
|
369
367
|
tool.definition.parameters = {
|
|
@@ -616,7 +614,7 @@ function isPresent(value: unknown): boolean {
|
|
|
616
614
|
function narrowAgentToolDefinitionForAgentPolicy(tool: Tool): void {
|
|
617
615
|
tool.definition.description = [
|
|
618
616
|
'Read-only local Agent inspection for GoodVibes Agent.',
|
|
619
|
-
'This product does not
|
|
617
|
+
'This product does not create separate Agent jobs or run local delegated review chains.',
|
|
620
618
|
'For build/fix/review work, delegate to GoodVibes TUI through the explicit build-delegation path instead.',
|
|
621
619
|
].join(' ');
|
|
622
620
|
tool.definition.sideEffects = [];
|
|
@@ -626,7 +624,7 @@ function narrowAgentToolDefinitionForAgentPolicy(tool: Tool): void {
|
|
|
626
624
|
const modeProperty = properties.mode;
|
|
627
625
|
if (!isRecord(modeProperty)) return;
|
|
628
626
|
modeProperty.enum = [...READ_ONLY_AGENT_TOOL_MODES];
|
|
629
|
-
modeProperty.description = 'Read-only Agent inspection mode.
|
|
627
|
+
modeProperty.description = 'Read-only Agent inspection mode. Separate Agent job creation, batch creation, cancel, message, wait, and plan modes are disabled in GoodVibes Agent.';
|
|
630
628
|
}
|
|
631
629
|
|
|
632
630
|
function narrowExecToolDefinitionForAgentPolicy(tool: Tool): void {
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import type { Tool } from '@pellux/goodvibes-sdk/platform/types';
|
|
2
|
+
import type { ToolRegistry } from '@pellux/goodvibes-sdk/platform/tools';
|
|
3
|
+
import {
|
|
4
|
+
WORK_PLAN_STATUSES,
|
|
5
|
+
type WorkPlanItem,
|
|
6
|
+
type WorkPlanItemStatus,
|
|
7
|
+
type WorkPlanStore,
|
|
8
|
+
} from '../work-plans/work-plan-store.ts';
|
|
9
|
+
|
|
10
|
+
export type AgentWorkPlanAction =
|
|
11
|
+
| 'list'
|
|
12
|
+
| 'get'
|
|
13
|
+
| 'create'
|
|
14
|
+
| 'update'
|
|
15
|
+
| 'set_status'
|
|
16
|
+
| 'remove'
|
|
17
|
+
| 'clear_completed';
|
|
18
|
+
|
|
19
|
+
export interface AgentWorkPlanToolArgs {
|
|
20
|
+
readonly action?: unknown;
|
|
21
|
+
readonly id?: unknown;
|
|
22
|
+
readonly title?: unknown;
|
|
23
|
+
readonly status?: unknown;
|
|
24
|
+
readonly owner?: unknown;
|
|
25
|
+
readonly source?: unknown;
|
|
26
|
+
readonly notes?: unknown;
|
|
27
|
+
readonly confirm?: unknown;
|
|
28
|
+
readonly explicitUserRequest?: unknown;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const ACTIONS: readonly AgentWorkPlanAction[] = [
|
|
32
|
+
'list',
|
|
33
|
+
'get',
|
|
34
|
+
'create',
|
|
35
|
+
'update',
|
|
36
|
+
'set_status',
|
|
37
|
+
'remove',
|
|
38
|
+
'clear_completed',
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
function isAction(value: unknown): value is AgentWorkPlanAction {
|
|
42
|
+
return typeof value === 'string' && ACTIONS.includes(value as AgentWorkPlanAction);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function isStatus(value: unknown): value is WorkPlanItemStatus {
|
|
46
|
+
return typeof value === 'string' && WORK_PLAN_STATUSES.includes(value as WorkPlanItemStatus);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function readString(value: unknown): string {
|
|
50
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function readBoolean(value: unknown): boolean {
|
|
54
|
+
return value === true || value === 'true' || value === 'yes';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function failure(error: string): { readonly success: false; readonly error: string } {
|
|
58
|
+
return { success: false, error };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function output(text: string): { readonly success: true; readonly output: string } {
|
|
62
|
+
return { success: true, output: text };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function requireId(args: AgentWorkPlanToolArgs): string {
|
|
66
|
+
const id = readString(args.id);
|
|
67
|
+
if (!id) throw new Error('id is required.');
|
|
68
|
+
return id;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function requireTitle(args: AgentWorkPlanToolArgs): string {
|
|
72
|
+
const title = readString(args.title);
|
|
73
|
+
if (!title) throw new Error('title is required.');
|
|
74
|
+
return title;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function readOptionalStatus(value: unknown): WorkPlanItemStatus | undefined {
|
|
78
|
+
if (value === undefined || value === null || readString(value) === '') return undefined;
|
|
79
|
+
if (!isStatus(value)) throw new Error(`Invalid status. Valid values ${WORK_PLAN_STATUSES.join(', ')}.`);
|
|
80
|
+
return value;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function formatStatus(status: WorkPlanItemStatus): string {
|
|
84
|
+
return status.replace(/_/g, ' ');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function formatItem(item: WorkPlanItem): string {
|
|
88
|
+
const owner = item.owner ? ` owner ${item.owner}` : '';
|
|
89
|
+
const source = item.source ? ` source=${item.source}` : '';
|
|
90
|
+
const completed = item.completedAt ? ` completed ${new Date(item.completedAt).toISOString()}` : '';
|
|
91
|
+
return `${item.id} ${formatStatus(item.status)}${owner}${source}${completed} ${item.title}`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function formatItemDetail(item: WorkPlanItem): string {
|
|
95
|
+
return [
|
|
96
|
+
formatItem(item),
|
|
97
|
+
`created ${new Date(item.createdAt).toISOString()}`,
|
|
98
|
+
`updated ${new Date(item.updatedAt).toISOString()}`,
|
|
99
|
+
item.linked
|
|
100
|
+
? `linked ${Object.entries(item.linked).map(([key, value]) => `${key} ${String(value)}`).join(', ')}`
|
|
101
|
+
: 'linked (none)',
|
|
102
|
+
'',
|
|
103
|
+
item.notes || '(no notes)',
|
|
104
|
+
].join('\n');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function resolveItem(store: WorkPlanStore, idOrPrefix: string): WorkPlanItem {
|
|
108
|
+
const needle = idOrPrefix.trim();
|
|
109
|
+
if (!needle) throw new Error('id is required.');
|
|
110
|
+
const items = store.listItems();
|
|
111
|
+
const exact = items.find((item) => item.id === needle);
|
|
112
|
+
if (exact) return exact;
|
|
113
|
+
const matches = items.filter((item) => item.id.startsWith(needle));
|
|
114
|
+
if (matches.length === 1) return matches[0]!;
|
|
115
|
+
if (matches.length > 1) {
|
|
116
|
+
throw new Error(`Work plan item id "${needle}" is ambiguous. Matches ${matches.map((item) => item.id).join(', ')}`);
|
|
117
|
+
}
|
|
118
|
+
throw new Error(`Work plan item not found ${needle}`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function listOutput(store: WorkPlanStore): string {
|
|
122
|
+
const plan = store.getActivePlan();
|
|
123
|
+
const counts = new Map<WorkPlanItemStatus, number>(WORK_PLAN_STATUSES.map((status) => [status, 0]));
|
|
124
|
+
for (const item of plan.items) counts.set(item.status, (counts.get(item.status) ?? 0) + 1);
|
|
125
|
+
const lines = [
|
|
126
|
+
'Agent local work plan',
|
|
127
|
+
` plan ${plan.id}`,
|
|
128
|
+
` project ${plan.projectRoot}`,
|
|
129
|
+
` items ${plan.items.length}; pending ${counts.get('pending') ?? 0}; active ${counts.get('in_progress') ?? 0}; blocked ${counts.get('blocked') ?? 0}; done ${counts.get('done') ?? 0}`,
|
|
130
|
+
];
|
|
131
|
+
if (plan.items.length === 0) {
|
|
132
|
+
lines.push('', 'No local work plan items.');
|
|
133
|
+
return lines.join('\n');
|
|
134
|
+
}
|
|
135
|
+
lines.push('', ...plan.items.slice(0, 20).map(formatItem));
|
|
136
|
+
if (plan.items.length > 20) lines.push(`${plan.items.length - 20} more item(s) omitted.`);
|
|
137
|
+
return lines.join('\n');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function requireDestructiveConfirmation(args: AgentWorkPlanToolArgs, action: string): string | null {
|
|
141
|
+
const explicitUserRequest = readString(args.explicitUserRequest);
|
|
142
|
+
if (!explicitUserRequest) return `explicitUserRequest is required before ${action}.`;
|
|
143
|
+
if (!readBoolean(args.confirm)) {
|
|
144
|
+
return [
|
|
145
|
+
`Agent work plan ${action} preview`,
|
|
146
|
+
' policy destructive local work-plan changes require confirm:true and an explicit user request',
|
|
147
|
+
` request ${explicitUserRequest}`,
|
|
148
|
+
].join('\n');
|
|
149
|
+
}
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function updatePatch(args: AgentWorkPlanToolArgs): Parameters<WorkPlanStore['updateItem']>[1] {
|
|
154
|
+
const status = readOptionalStatus(args.status);
|
|
155
|
+
return {
|
|
156
|
+
...(args.title !== undefined ? { title: requireTitle(args) } : {}),
|
|
157
|
+
...(status !== undefined ? { status } : {}),
|
|
158
|
+
...(args.owner !== undefined ? { owner: readString(args.owner) || null } : {}),
|
|
159
|
+
...(args.source !== undefined ? { source: readString(args.source) || null } : {}),
|
|
160
|
+
...(args.notes !== undefined ? { notes: readString(args.notes) || null } : {}),
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export function createAgentWorkPlanTool(store: WorkPlanStore): Tool {
|
|
165
|
+
return {
|
|
166
|
+
definition: {
|
|
167
|
+
name: 'agent_work_plan',
|
|
168
|
+
description: [
|
|
169
|
+
'Inspect and maintain the visible GoodVibes Agent local work plan from the main conversation.',
|
|
170
|
+
'Use this to track concrete tasks the assistant is doing or has agreed to do, so the work is visible in the Agent TUI workspace.',
|
|
171
|
+
'This uses only Agent-local persisted work-plan state; it does not call connected-host mutation routes, start background jobs, create separate Agent jobs, use delegated review, write default knowledge, or use non-Agent knowledge segments.',
|
|
172
|
+
'Create, update, and set_status are safe local state actions. remove and clear_completed require confirm:true plus explicitUserRequest.',
|
|
173
|
+
].join(' '),
|
|
174
|
+
parameters: {
|
|
175
|
+
type: 'object',
|
|
176
|
+
properties: {
|
|
177
|
+
action: { type: 'string', enum: [...ACTIONS] },
|
|
178
|
+
id: { type: 'string', description: 'Work plan item id or unique id prefix for get/update/set_status/remove.' },
|
|
179
|
+
title: { type: 'string', description: 'Work plan item title for create/update.' },
|
|
180
|
+
status: { type: 'string', enum: [...WORK_PLAN_STATUSES], description: 'Work plan item status.' },
|
|
181
|
+
owner: { type: 'string', description: 'Optional owner label.' },
|
|
182
|
+
source: { type: 'string', description: 'Optional source/provenance label.' },
|
|
183
|
+
notes: { type: 'string', description: 'Optional work-plan notes.' },
|
|
184
|
+
confirm: { type: 'boolean', description: 'Required true for remove and clear_completed.' },
|
|
185
|
+
explicitUserRequest: { type: 'string', description: 'Required for destructive remove and clear_completed actions.' },
|
|
186
|
+
},
|
|
187
|
+
required: ['action'],
|
|
188
|
+
additionalProperties: false,
|
|
189
|
+
},
|
|
190
|
+
sideEffects: ['state'],
|
|
191
|
+
},
|
|
192
|
+
execute: async (rawArgs: unknown) => {
|
|
193
|
+
try {
|
|
194
|
+
const args = rawArgs as AgentWorkPlanToolArgs;
|
|
195
|
+
if (!isAction(args.action)) return failure(`Unknown Agent work plan action. Valid values ${ACTIONS.join(', ')}.`);
|
|
196
|
+
if (args.action === 'list') return output(listOutput(store));
|
|
197
|
+
if (args.action === 'get') return output(formatItemDetail(resolveItem(store, requireId(args))));
|
|
198
|
+
if (args.action === 'create') {
|
|
199
|
+
const item = store.addItem(requireTitle(args), {
|
|
200
|
+
status: readOptionalStatus(args.status) ?? 'pending',
|
|
201
|
+
owner: readString(args.owner) || 'agent',
|
|
202
|
+
source: readString(args.source) || 'main-conversation',
|
|
203
|
+
notes: readString(args.notes) || undefined,
|
|
204
|
+
});
|
|
205
|
+
return output([
|
|
206
|
+
'Created Agent work plan item',
|
|
207
|
+
` id ${item.id}`,
|
|
208
|
+
` title ${item.title}`,
|
|
209
|
+
].join('\n'));
|
|
210
|
+
}
|
|
211
|
+
if (args.action === 'update') {
|
|
212
|
+
const item = store.updateItem(requireId(args), updatePatch(args));
|
|
213
|
+
return output([
|
|
214
|
+
'Updated Agent work plan item',
|
|
215
|
+
` id ${item.id}`,
|
|
216
|
+
` title ${item.title}`,
|
|
217
|
+
].join('\n'));
|
|
218
|
+
}
|
|
219
|
+
if (args.action === 'set_status') {
|
|
220
|
+
const status = readOptionalStatus(args.status);
|
|
221
|
+
if (!status) throw new Error('status is required.');
|
|
222
|
+
const item = store.setItemStatus(requireId(args), status);
|
|
223
|
+
return output([
|
|
224
|
+
'Set Agent work plan item status',
|
|
225
|
+
` id ${item.id}`,
|
|
226
|
+
` status ${formatStatus(item.status)}`,
|
|
227
|
+
` title ${item.title}`,
|
|
228
|
+
].join('\n'));
|
|
229
|
+
}
|
|
230
|
+
if (args.action === 'remove') {
|
|
231
|
+
const denied = requireDestructiveConfirmation(args, `remove ${readString(args.id) || '(missing id)'}`);
|
|
232
|
+
if (denied) return failure(denied);
|
|
233
|
+
const item = store.removeItem(requireId(args));
|
|
234
|
+
return output([
|
|
235
|
+
'Removed Agent work plan item',
|
|
236
|
+
` id ${item.id}`,
|
|
237
|
+
` title ${item.title}`,
|
|
238
|
+
].join('\n'));
|
|
239
|
+
}
|
|
240
|
+
const denied = requireDestructiveConfirmation(args, 'clear completed');
|
|
241
|
+
if (denied) return failure(denied);
|
|
242
|
+
const count = store.clearCompleted();
|
|
243
|
+
return output([
|
|
244
|
+
`Cleared ${count} completed/cancelled Agent work plan items`,
|
|
245
|
+
` count ${count}`,
|
|
246
|
+
].join('\n'));
|
|
247
|
+
} catch (error) {
|
|
248
|
+
return failure(error instanceof Error ? error.message : String(error));
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export function registerAgentWorkPlanTool(registry: ToolRegistry, store: WorkPlanStore): void {
|
|
255
|
+
registry.register(createAgentWorkPlanTool(store));
|
|
256
|
+
}
|
package/src/version.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { join } from 'node:path';
|
|
|
6
6
|
// The prebuild script updates the fallback value before compilation.
|
|
7
7
|
// Uses import.meta.dir (Bun) to locate package.json relative to this file,
|
|
8
8
|
// which is correct regardless of the process working directory.
|
|
9
|
-
let _version = '0.
|
|
9
|
+
let _version = '1.0.0';
|
|
10
10
|
let _sdkVersion = '0.33.35';
|
|
11
11
|
try {
|
|
12
12
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8')) as {
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# Connected Services
|
|
2
|
-
|
|
3
|
-
GoodVibes Agent is a TUI client for connected GoodVibes services owned outside this package. The package exposes one executable:
|
|
4
|
-
|
|
5
|
-
```sh
|
|
6
|
-
goodvibes-agent
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
The installed command is backed by TypeScript-authored source with a Bun shebang. Package install smoke must verify:
|
|
10
|
-
|
|
11
|
-
- `goodvibes-agent --help`
|
|
12
|
-
- `goodvibes-agent --version`
|
|
13
|
-
- `goodvibes-agent status --json`
|
|
14
|
-
- `goodvibes-agent` launches the TUI in a real PTY
|
|
15
|
-
|
|
16
|
-
## Service Prerequisite
|
|
17
|
-
|
|
18
|
-
Start connected GoodVibes services from GoodVibes TUI or the owning host before launching Agent. Agent expects those services to expose public operator routes and the isolated Agent Knowledge routes:
|
|
19
|
-
|
|
20
|
-
```text
|
|
21
|
-
http://127.0.0.1:3421
|
|
22
|
-
/api/goodvibes-agent/knowledge/status
|
|
23
|
-
/api/goodvibes-agent/knowledge/ask
|
|
24
|
-
/api/goodvibes-agent/knowledge/search
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
If the GoodVibes API is on a different host or port, use a one-off override:
|
|
28
|
-
|
|
29
|
-
```sh
|
|
30
|
-
goodvibes-agent --runtime-url http://127.0.0.1:3421 status
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
For a persistent shell/session override, set:
|
|
34
|
-
|
|
35
|
-
```sh
|
|
36
|
-
export GOODVIBES_AGENT_RUNTIME_URL=http://127.0.0.1:3421
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
`GOODVIBES_AGENT_BASE_URL` is accepted as a legacy alias. These values only select the connected GoodVibes API root; they do not make Agent own services.
|
|
40
|
-
|
|
41
|
-
If connected GoodVibes services are unavailable, unauthenticated, or on an incompatible SDK version, Agent commands report actionable diagnostics without printing token values.
|
|
42
|
-
|
|
43
|
-
## Product Boundary
|
|
44
|
-
|
|
45
|
-
Agent owns the operator assistant TUI, local profiles, local memory/routines/skills/personas, isolated Agent Knowledge calls, companion chat, approvals/automation visibility, and explicit build delegation.
|
|
46
|
-
|
|
47
|
-
Agent does not own connected-service lifecycle. It does not provide commands to install, expose, start, stop, restart, or mutate connected GoodVibes services.
|
|
48
|
-
|
|
49
|
-
Agent Knowledge/Wiki is its own product segment. Agent uses `/api/goodvibes-agent/knowledge/*` only and must not fall back to default Knowledge/Wiki or other product-specific knowledge routes.
|
|
50
|
-
|
|
51
|
-
Normal assistant chat uses companion chat. Build/fix/review work is delegated explicitly to GoodVibes TUI through public runtime/session contracts, and WRFC is requested only when explicitly asked for delegated build/fix/review work.
|