@pellux/goodvibes-agent 1.1.6 → 1.2.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 +176 -0
- package/README.md +46 -30
- package/dist/package/{ast-grep-napi.linux-x64-gnu-mkk8xwww.node → ast-grep-napi.linux-x64-gnu-swtppvy9.node} +0 -0
- package/dist/package/{ast-grep-napi.linux-x64-musl-ryqtgdv6.node → ast-grep-napi.linux-x64-musl-ttfcdtap.node} +0 -0
- package/dist/package/main.js +132662 -91399
- package/docs/README.md +14 -7
- package/docs/channels-remote-and-api.md +8 -5
- package/docs/connected-host.md +14 -12
- package/docs/getting-started.md +56 -30
- package/docs/knowledge-artifacts-and-multimodal.md +7 -5
- package/docs/project-planning.md +2 -2
- package/docs/providers-and-routing.md +11 -3
- package/docs/tools-and-commands.md +114 -45
- package/docs/voice-and-live-tts.md +3 -1
- package/package.json +3 -2
- package/release/release-notes.md +130 -5
- package/release/release-readiness.json +120 -90
- package/src/agent/assistant-cockpit.ts +247 -0
- package/src/agent/autonomy-schedule-format.ts +96 -0
- package/src/agent/autonomy-schedule.ts +514 -0
- package/src/agent/channel-delivery-receipts.ts +292 -0
- package/src/agent/competitive-feature-inventory.ts +296 -0
- package/src/agent/document-registry-types.ts +106 -0
- package/src/agent/document-registry.ts +734 -0
- package/src/agent/harness-control.ts +2 -2
- package/src/agent/memory-prompt.ts +2 -2
- package/src/agent/operator-actions.ts +50 -6
- package/src/agent/persona-registry.ts +8 -0
- package/src/agent/project-context-files.ts +273 -0
- package/src/agent/prompt-context-receipts.ts +502 -0
- package/src/agent/reminder-schedule-format.ts +16 -2
- package/src/agent/research-run-registry.ts +582 -0
- package/src/agent/research-source-registry.ts +441 -0
- package/src/agent/routine-registry.ts +19 -3
- package/src/agent/routine-schedule-format.ts +27 -2
- package/src/agent/runtime-profile-starters.ts +7 -0
- package/src/agent/runtime-profile.ts +106 -4
- package/src/agent/schedule-edit-format.ts +129 -0
- package/src/agent/schedule-edit.ts +496 -0
- package/src/agent/schedule-next-routes.ts +42 -0
- package/src/agent/setup-wizard-checkpoint.ts +140 -0
- package/src/agent/setup-wizard.ts +447 -0
- package/src/agent/skill-registry-types.ts +102 -0
- package/src/agent/skill-registry.ts +81 -107
- package/src/agent/vibe-confirmation-routes.ts +62 -0
- package/src/agent/vibe-file.ts +285 -0
- package/src/cli/agent-knowledge-command.ts +45 -2
- package/src/cli/help.ts +3 -0
- package/src/cli/profiles-command.ts +25 -11
- package/src/config/agent-settings-policy.ts +1 -18
- package/src/input/agent-workspace-activation.ts +53 -0
- package/src/input/agent-workspace-artifact-browser-editor.ts +494 -0
- package/src/input/agent-workspace-artifact-metadata.ts +17 -0
- package/src/input/agent-workspace-basic-command-editors.ts +5 -1
- package/src/input/agent-workspace-categories.ts +153 -155
- package/src/input/agent-workspace-channel-triage.ts +481 -0
- package/src/input/agent-workspace-channels.ts +263 -0
- package/src/input/agent-workspace-command-editor.ts +152 -0
- package/src/input/agent-workspace-context-snapshot.ts +349 -0
- package/src/input/agent-workspace-delegation-editor-submission.ts +8 -0
- package/src/input/agent-workspace-document-editor.ts +502 -0
- package/src/input/agent-workspace-document-ops-editor.ts +523 -0
- package/src/input/agent-workspace-host-category.ts +1 -1
- package/src/input/agent-workspace-local-library-snapshot.ts +167 -0
- package/src/input/agent-workspace-model-compare-editor.ts +376 -0
- package/src/input/agent-workspace-model-compare-prompt-submission.ts +552 -0
- package/src/input/agent-workspace-model-compare-types.ts +82 -0
- package/src/input/agent-workspace-model-compare-utils.ts +35 -0
- package/src/input/agent-workspace-onboarding-categories.ts +141 -0
- package/src/input/agent-workspace-operations-command-editor-submission.ts +53 -0
- package/src/input/agent-workspace-operations-command-editors.ts +22 -0
- package/src/input/agent-workspace-research-report-editor.ts +212 -0
- package/src/input/agent-workspace-research-run-editor.ts +144 -0
- package/src/input/agent-workspace-research-source-editor.ts +167 -0
- package/src/input/agent-workspace-review-packet-snapshot.ts +593 -0
- package/src/input/agent-workspace-review-packet-utils.ts +265 -0
- package/src/input/agent-workspace-settings.ts +262 -30
- package/src/input/agent-workspace-setup-checkpoint-action.ts +127 -0
- package/src/input/agent-workspace-setup-snapshot.ts +198 -0
- package/src/input/agent-workspace-setup.ts +34 -1
- package/src/input/agent-workspace-snapshot.ts +162 -147
- package/src/input/agent-workspace-types.ts +287 -2
- package/src/input/agent-workspace.ts +18 -0
- package/src/input/command-registry.ts +9 -2
- package/src/input/commands/agent-runtime-profile-runtime.ts +28 -13
- package/src/input/commands/channels-runtime.ts +102 -114
- package/src/input/commands/delegation-runtime.ts +87 -24
- package/src/input/commands/knowledge-browser-flags.ts +12 -0
- package/src/input/commands/knowledge.ts +28 -14
- package/src/input/commands/operator-actions-runtime.ts +6 -3
- package/src/input/commands/schedule-runtime.ts +71 -14
- package/src/input/commands/session-content.ts +2 -2
- package/src/input/commands/shell-core.ts +2 -0
- package/src/input/commands/vibe-runtime.ts +140 -0
- package/src/input/commands.ts +2 -0
- package/src/input/connected-host-routes.ts +123 -0
- package/src/input/settings-modal-types.ts +14 -0
- package/src/main.ts +15 -15
- package/src/panels/qr-panel.ts +2 -2
- package/src/renderer/agent-workspace-context-lines.ts +686 -0
- package/src/renderer/agent-workspace.ts +30 -419
- package/src/renderer/settings-modal-helpers.ts +12 -0
- package/src/renderer/settings-modal.ts +12 -0
- package/src/runtime/bootstrap-command-context.ts +11 -1
- package/src/runtime/bootstrap-command-parts.ts +14 -3
- package/src/runtime/bootstrap-core.ts +43 -1
- package/src/runtime/bootstrap-shell.ts +6 -0
- package/src/runtime/bootstrap.ts +113 -30
- package/src/runtime/connected-host-auth.ts +3 -2
- package/src/runtime/execution-ledger.ts +231 -0
- package/src/runtime/services.ts +88 -10
- package/src/runtime/tool-permission-safety.ts +287 -0
- package/src/shell/session-continuity-hints.ts +39 -0
- package/src/tools/agent-artifacts-tool.ts +606 -0
- package/src/tools/agent-audit-tool.ts +155 -0
- package/src/tools/agent-autonomy-schedule-tool.ts +238 -0
- package/src/tools/agent-autonomy-tool.ts +140 -0
- package/src/tools/agent-channel-send-tool.ts +24 -2
- package/src/tools/agent-channels-tool.ts +140 -0
- package/src/tools/agent-computer-tool.ts +168 -0
- package/src/tools/agent-context-policy.ts +267 -10
- package/src/tools/agent-context-tool.ts +143 -0
- package/src/tools/agent-delegation-tool.ts +128 -0
- package/src/tools/agent-device-tool.ts +240 -0
- package/src/tools/agent-documents-tool.ts +684 -0
- package/src/tools/agent-execution-tool.ts +230 -0
- package/src/tools/agent-harness-agent-orchestration.ts +703 -0
- package/src/tools/agent-harness-autonomy-intake.ts +785 -0
- package/src/tools/agent-harness-autonomy-live-records.ts +588 -0
- package/src/tools/agent-harness-autonomy-queue-types.ts +88 -0
- package/src/tools/agent-harness-autonomy-queue.ts +560 -0
- package/src/tools/agent-harness-background-processes-types.ts +35 -0
- package/src/tools/agent-harness-background-processes.ts +794 -0
- package/src/tools/agent-harness-browser-cockpit-route.ts +219 -0
- package/src/tools/agent-harness-browser-control.ts +338 -0
- package/src/tools/agent-harness-channel-metadata.ts +168 -10
- package/src/tools/agent-harness-cli-command-policy.ts +110 -0
- package/src/tools/agent-harness-command-catalog.ts +4 -2
- package/src/tools/agent-harness-command-runner.ts +42 -0
- package/src/tools/agent-harness-connected-host-status.ts +7 -4
- package/src/tools/agent-harness-delegation-posture.ts +234 -19
- package/src/tools/agent-harness-document-ops-reviewer-readiness.ts +234 -0
- package/src/tools/agent-harness-document-ops-types.ts +72 -0
- package/src/tools/agent-harness-document-ops.ts +671 -0
- package/src/tools/agent-harness-execution-history.ts +489 -0
- package/src/tools/agent-harness-execution-posture.ts +382 -0
- package/src/tools/agent-harness-file-recovery.ts +135 -0
- package/src/tools/agent-harness-keybinding-metadata.ts +16 -12
- package/src/tools/agent-harness-learning-curator-common.ts +102 -0
- package/src/tools/agent-harness-learning-curator-consolidation.ts +295 -0
- package/src/tools/agent-harness-learning-curator-proposals.ts +606 -0
- package/src/tools/agent-harness-learning-curator-types.ts +151 -0
- package/src/tools/agent-harness-learning-curator.ts +417 -0
- package/src/tools/agent-harness-local-model-benchmarks.ts +199 -0
- package/src/tools/agent-harness-local-model-cookbook.ts +238 -0
- package/src/tools/agent-harness-local-model-endpoints.ts +673 -0
- package/src/tools/agent-harness-media-posture.ts +208 -2
- package/src/tools/agent-harness-memory-posture.ts +556 -0
- package/src/tools/agent-harness-metadata.ts +100 -168
- package/src/tools/agent-harness-mode-catalog.ts +84 -33
- package/src/tools/agent-harness-model-catalog.ts +162 -0
- package/src/tools/agent-harness-model-provider-health.ts +186 -0
- package/src/tools/agent-harness-model-readiness.ts +406 -0
- package/src/tools/agent-harness-model-routing-types.ts +266 -0
- package/src/tools/agent-harness-model-routing-utils.ts +30 -0
- package/src/tools/agent-harness-model-routing.ts +137 -190
- package/src/tools/agent-harness-operator-methods.ts +115 -133
- package/src/tools/agent-harness-pairing-posture.ts +431 -18
- package/src/tools/agent-harness-personal-ops-discovery.ts +533 -0
- package/src/tools/agent-harness-personal-ops-intake.ts +385 -0
- package/src/tools/agent-harness-personal-ops-lanes.ts +204 -0
- package/src/tools/agent-harness-personal-ops-records.ts +732 -0
- package/src/tools/agent-harness-personal-ops-runner.ts +637 -0
- package/src/tools/agent-harness-personal-ops-types.ts +222 -0
- package/src/tools/agent-harness-personal-ops.ts +606 -0
- package/src/tools/agent-harness-project-context.ts +144 -0
- package/src/tools/agent-harness-prompt-context.ts +589 -0
- package/src/tools/agent-harness-provider-account-metadata.ts +2 -2
- package/src/tools/agent-harness-release-evidence.ts +9 -7
- package/src/tools/agent-harness-release-readiness.ts +9 -7
- package/src/tools/agent-harness-research-briefing.ts +427 -0
- package/src/tools/agent-harness-research-queue.ts +250 -0
- package/src/tools/agent-harness-research-runs.ts +295 -0
- package/src/tools/agent-harness-research-workflow.ts +322 -0
- package/src/tools/agent-harness-security-posture.ts +2 -2
- package/src/tools/agent-harness-service-posture.ts +9 -9
- package/src/tools/agent-harness-session-metadata.ts +3 -3
- package/src/tools/agent-harness-setup-connected-host.ts +501 -0
- package/src/tools/agent-harness-setup-describe.ts +557 -0
- package/src/tools/agent-harness-setup-handoffs.ts +502 -0
- package/src/tools/agent-harness-setup-model-helpers.ts +101 -0
- package/src/tools/agent-harness-setup-plan.ts +253 -0
- package/src/tools/agent-harness-setup-posture-types.ts +218 -0
- package/src/tools/agent-harness-setup-posture-utils.ts +173 -0
- package/src/tools/agent-harness-setup-posture.ts +449 -221
- package/src/tools/agent-harness-setup-smoke.ts +508 -0
- package/src/tools/agent-harness-sudo-posture.ts +114 -0
- package/src/tools/agent-harness-tool-schema.ts +120 -7
- package/src/tools/agent-harness-tool-types.ts +78 -0
- package/src/tools/agent-harness-tool-utils.ts +43 -0
- package/src/tools/agent-harness-tool.ts +311 -370
- package/src/tools/agent-harness-ui-surface-metadata.ts +76 -69
- package/src/tools/agent-harness-ui-surface-types.ts +46 -0
- package/src/tools/agent-harness-vibe-health.ts +105 -0
- package/src/tools/agent-harness-workspace-action-runner.ts +149 -0
- package/src/tools/agent-harness-workspace-actions.ts +114 -8
- package/src/tools/agent-harness-workspace-editor-execution.ts +214 -0
- package/src/tools/agent-harness-workspace-editor-runner.ts +755 -0
- package/src/tools/agent-host-tool.ts +159 -0
- package/src/tools/agent-knowledge-ingest-tool.ts +34 -1
- package/src/tools/agent-learning-consolidation-core.ts +327 -0
- package/src/tools/agent-learning-consolidation-tool.ts +758 -0
- package/src/tools/agent-memory-tool.ts +214 -0
- package/src/tools/agent-model-compare-export.ts +315 -0
- package/src/tools/agent-model-compare-handoff.ts +592 -0
- package/src/tools/agent-model-compare-judgment.ts +633 -0
- package/src/tools/agent-model-compare-run.ts +722 -0
- package/src/tools/agent-model-compare-tool.ts +698 -0
- package/src/tools/agent-model-compare-types.ts +191 -0
- package/src/tools/agent-model-compare-utils.ts +93 -0
- package/src/tools/agent-models-tool.ts +208 -0
- package/src/tools/agent-operator-action-tool.ts +1 -1
- package/src/tools/agent-operator-method-tool.ts +643 -0
- package/src/tools/agent-personal-ops-tool.ts +197 -0
- package/src/tools/agent-policy-explanation.ts +415 -0
- package/src/tools/agent-research-report-tool.ts +608 -0
- package/src/tools/agent-research-runs-tool.ts +434 -0
- package/src/tools/agent-research-sources-tool.ts +443 -0
- package/src/tools/agent-research-tool.ts +687 -0
- package/src/tools/agent-review-packet-presets-core.ts +757 -0
- package/src/tools/agent-review-packet-presets-tool.ts +466 -0
- package/src/tools/agent-review-packet-share-tool.ts +305 -0
- package/src/tools/agent-route-planner-candidates-setup.ts +411 -0
- package/src/tools/agent-route-planner-candidates-surfaces.ts +432 -0
- package/src/tools/agent-route-planner-candidates-work.ts +251 -0
- package/src/tools/agent-route-planner-helpers.ts +667 -0
- package/src/tools/agent-route-planner.ts +185 -0
- package/src/tools/agent-route-tool.ts +105 -0
- package/src/tools/agent-schedule-edit-tool.ts +210 -0
- package/src/tools/agent-schedule-tool.ts +282 -0
- package/src/tools/agent-security-tool.ts +145 -0
- package/src/tools/agent-sessions-tool.ts +122 -0
- package/src/tools/agent-settings-import-tool.ts +104 -0
- package/src/tools/agent-settings-tool.ts +176 -0
- package/src/tools/agent-setup-tool.ts +226 -0
- package/src/tools/agent-support-tool.ts +122 -0
- package/src/tools/agent-terminal-process-tools.ts +167 -0
- package/src/tools/agent-tool-policy-guard-types.ts +77 -0
- package/src/tools/agent-tool-policy-guard.ts +110 -89
- package/src/tools/agent-vibe-tool.ts +297 -0
- package/src/tools/agent-work-plan-tool.ts +265 -6
- package/src/tools/agent-workspace-tool.ts +305 -0
- package/src/tools/artifact-archive.ts +169 -0
- package/src/tools/tool-definition-compaction.ts +36 -0
- package/src/tools/tool-execution-safety.ts +41 -0
- package/src/version.ts +1 -1
|
@@ -0,0 +1,282 @@
|
|
|
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 type { AgentConnectedHostConfigReader } from '../agent/routine-schedule-promotion.ts';
|
|
5
|
+
import { createAgentAutonomyScheduleTool } from './agent-autonomy-schedule-tool.ts';
|
|
6
|
+
import { createAgentOperatorActionTool } from './agent-operator-action-tool.ts';
|
|
7
|
+
import { createAgentOperatorMethodTool } from './agent-operator-method-tool.ts';
|
|
8
|
+
import { createAgentReminderScheduleTool } from './agent-reminder-schedule-tool.ts';
|
|
9
|
+
import { createAgentScheduleEditTool } from './agent-schedule-edit-tool.ts';
|
|
10
|
+
|
|
11
|
+
type ScheduleAction =
|
|
12
|
+
| 'list'
|
|
13
|
+
| 'create'
|
|
14
|
+
| 'reminder'
|
|
15
|
+
| 'edit'
|
|
16
|
+
| 'run'
|
|
17
|
+
| 'pause'
|
|
18
|
+
| 'resume'
|
|
19
|
+
| 'delete';
|
|
20
|
+
|
|
21
|
+
interface AgentScheduleToolArgs {
|
|
22
|
+
readonly action?: unknown;
|
|
23
|
+
readonly mode?: unknown;
|
|
24
|
+
readonly scheduleId?: unknown;
|
|
25
|
+
readonly jobId?: unknown;
|
|
26
|
+
readonly targetId?: unknown;
|
|
27
|
+
readonly task?: unknown;
|
|
28
|
+
readonly message?: unknown;
|
|
29
|
+
readonly successCriteria?: unknown;
|
|
30
|
+
readonly scheduleKind?: unknown;
|
|
31
|
+
readonly kind?: unknown;
|
|
32
|
+
readonly scheduleValue?: unknown;
|
|
33
|
+
readonly value?: unknown;
|
|
34
|
+
readonly at?: unknown;
|
|
35
|
+
readonly every?: unknown;
|
|
36
|
+
readonly cron?: unknown;
|
|
37
|
+
readonly timezone?: unknown;
|
|
38
|
+
readonly staggerMs?: unknown;
|
|
39
|
+
readonly name?: unknown;
|
|
40
|
+
readonly prompt?: unknown;
|
|
41
|
+
readonly provider?: unknown;
|
|
42
|
+
readonly model?: unknown;
|
|
43
|
+
readonly deliveryChannel?: unknown;
|
|
44
|
+
readonly deliveryRoute?: unknown;
|
|
45
|
+
readonly deliveryWebhook?: unknown;
|
|
46
|
+
readonly deliveryLink?: unknown;
|
|
47
|
+
readonly disabled?: unknown;
|
|
48
|
+
readonly confirm?: unknown;
|
|
49
|
+
readonly explicitUserRequest?: unknown;
|
|
50
|
+
readonly query?: unknown;
|
|
51
|
+
readonly limit?: unknown;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const LIFECYCLE_ACTIONS: Readonly<Record<'run' | 'pause' | 'resume' | 'delete', string>> = {
|
|
55
|
+
run: 'schedules.run',
|
|
56
|
+
pause: 'schedules.disable',
|
|
57
|
+
resume: 'schedules.enable',
|
|
58
|
+
delete: 'schedules.delete',
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
function readString(value: unknown): string {
|
|
62
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function readBoolean(value: unknown): boolean {
|
|
66
|
+
return value === true || value === 'true' || value === 'yes';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function readScheduleId(args: AgentScheduleToolArgs): string {
|
|
70
|
+
return readString(args.scheduleId) || readString(args.jobId) || readString(args.targetId);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function normalizeAction(value: unknown): ScheduleAction | null {
|
|
74
|
+
const action = readString(value).toLowerCase();
|
|
75
|
+
if (!action) return null;
|
|
76
|
+
if (action === 'autonomous' || action === 'schedule' || action === 'create_task' || action === 'create-task') return 'create';
|
|
77
|
+
if (action === 'remind' || action === 'reminder' || action === 'create_reminder' || action === 'create-reminder') return 'reminder';
|
|
78
|
+
if (action === 'update' || action === 'patch') return 'edit';
|
|
79
|
+
if (action === 'disable' || action === 'stop' || action === 'cancel') return 'pause';
|
|
80
|
+
if (action === 'enable' || action === 'start') return 'resume';
|
|
81
|
+
if (action === 'remove') return 'delete';
|
|
82
|
+
if (action === 'ls' || action === 'status' || action === 'show') return 'list';
|
|
83
|
+
if (action === 'list' || action === 'create' || action === 'edit' || action === 'run' || action === 'pause' || action === 'resume' || action === 'delete') return action;
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function hasEditFields(args: AgentScheduleToolArgs): boolean {
|
|
88
|
+
return Boolean(
|
|
89
|
+
readString(args.scheduleKind)
|
|
90
|
+
|| readString(args.kind)
|
|
91
|
+
|| readString(args.scheduleValue)
|
|
92
|
+
|| readString(args.value)
|
|
93
|
+
|| readString(args.at)
|
|
94
|
+
|| readString(args.every)
|
|
95
|
+
|| readString(args.cron)
|
|
96
|
+
|| readString(args.name)
|
|
97
|
+
|| readString(args.prompt)
|
|
98
|
+
|| readString(args.task)
|
|
99
|
+
|| readString(args.successCriteria)
|
|
100
|
+
|| args.staggerMs !== undefined,
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function readAction(args: AgentScheduleToolArgs): ScheduleAction {
|
|
105
|
+
const explicit = normalizeAction(args.action) ?? normalizeAction(args.mode);
|
|
106
|
+
if (explicit) return explicit;
|
|
107
|
+
if (readString(args.message)) return 'reminder';
|
|
108
|
+
if (readString(args.task)) return readScheduleId(args) && hasEditFields(args) ? 'edit' : 'create';
|
|
109
|
+
if (readScheduleId(args) && hasEditFields(args)) return 'edit';
|
|
110
|
+
return 'list';
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function scheduleKind(args: AgentScheduleToolArgs): string {
|
|
114
|
+
const direct = readString(args.scheduleKind) || readString(args.kind);
|
|
115
|
+
if (direct) return direct.toLowerCase();
|
|
116
|
+
if (readString(args.at)) return 'at';
|
|
117
|
+
if (readString(args.every)) return 'every';
|
|
118
|
+
if (readString(args.cron)) return 'cron';
|
|
119
|
+
return '';
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function scheduleValue(args: AgentScheduleToolArgs, kind: string): string {
|
|
123
|
+
const direct = readString(args.scheduleValue) || readString(args.value);
|
|
124
|
+
if (direct) return direct;
|
|
125
|
+
if (kind === 'at') return readString(args.at);
|
|
126
|
+
if (kind === 'every') return readString(args.every);
|
|
127
|
+
if (kind === 'cron') return readString(args.cron);
|
|
128
|
+
return readString(args.at) || readString(args.every) || readString(args.cron);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function sharedCreateArgs(args: AgentScheduleToolArgs): Record<string, unknown> {
|
|
132
|
+
const kind = scheduleKind(args);
|
|
133
|
+
return {
|
|
134
|
+
scheduleKind: kind,
|
|
135
|
+
scheduleValue: scheduleValue(args, kind),
|
|
136
|
+
timezone: args.timezone,
|
|
137
|
+
name: args.name,
|
|
138
|
+
provider: args.provider,
|
|
139
|
+
model: args.model,
|
|
140
|
+
deliveryChannel: args.deliveryChannel,
|
|
141
|
+
deliveryRoute: args.deliveryRoute,
|
|
142
|
+
deliveryWebhook: args.deliveryWebhook,
|
|
143
|
+
deliveryLink: args.deliveryLink,
|
|
144
|
+
disabled: args.disabled,
|
|
145
|
+
confirm: args.confirm,
|
|
146
|
+
explicitUserRequest: args.explicitUserRequest,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function autonomyArgs(args: AgentScheduleToolArgs): Record<string, unknown> {
|
|
151
|
+
return {
|
|
152
|
+
task: args.task,
|
|
153
|
+
successCriteria: args.successCriteria,
|
|
154
|
+
...sharedCreateArgs(args),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function reminderArgs(args: AgentScheduleToolArgs): Record<string, unknown> {
|
|
159
|
+
return {
|
|
160
|
+
message: args.message,
|
|
161
|
+
...sharedCreateArgs(args),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function editArgs(args: AgentScheduleToolArgs): Record<string, unknown> {
|
|
166
|
+
const kind = scheduleKind(args);
|
|
167
|
+
return {
|
|
168
|
+
scheduleId: readScheduleId(args),
|
|
169
|
+
scheduleKind: kind || undefined,
|
|
170
|
+
scheduleValue: kind ? scheduleValue(args, kind) : undefined,
|
|
171
|
+
timezone: args.timezone,
|
|
172
|
+
staggerMs: args.staggerMs,
|
|
173
|
+
name: args.name,
|
|
174
|
+
prompt: args.prompt,
|
|
175
|
+
task: args.task,
|
|
176
|
+
successCriteria: args.successCriteria,
|
|
177
|
+
confirm: args.confirm,
|
|
178
|
+
explicitUserRequest: args.explicitUserRequest,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function listInput(args: AgentScheduleToolArgs): Record<string, unknown> {
|
|
183
|
+
const input: Record<string, unknown> = {};
|
|
184
|
+
const query = readString(args.query) || readScheduleId(args);
|
|
185
|
+
if (query) input.query = query;
|
|
186
|
+
if (typeof args.limit === 'number' && Number.isFinite(args.limit)) input.limit = args.limit;
|
|
187
|
+
return input;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export function createAgentScheduleTool(
|
|
191
|
+
shellPaths: ShellPathService,
|
|
192
|
+
configManager: AgentConnectedHostConfigReader,
|
|
193
|
+
): Tool {
|
|
194
|
+
const autonomyTool = createAgentAutonomyScheduleTool(shellPaths, configManager);
|
|
195
|
+
const reminderTool = createAgentReminderScheduleTool(shellPaths, configManager);
|
|
196
|
+
const editTool = createAgentScheduleEditTool(shellPaths, configManager);
|
|
197
|
+
const operatorActionTool = createAgentOperatorActionTool(shellPaths, configManager);
|
|
198
|
+
const operatorMethodTool = createAgentOperatorMethodTool(shellPaths, configManager);
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
definition: {
|
|
202
|
+
name: 'schedule',
|
|
203
|
+
description: 'List, create, edit, run, pause, resume schedules.',
|
|
204
|
+
parameters: {
|
|
205
|
+
type: 'object',
|
|
206
|
+
properties: {
|
|
207
|
+
action: {
|
|
208
|
+
type: 'string',
|
|
209
|
+
enum: ['list', 'create', 'autonomous', 'remind', 'reminder', 'edit', 'run', 'pause', 'resume', 'enable', 'disable', 'delete'],
|
|
210
|
+
description: 'Schedule action; list is read-only, others confirm.',
|
|
211
|
+
},
|
|
212
|
+
scheduleId: { type: 'string', description: 'Connected schedule id for edit/run/pause/resume/delete.' },
|
|
213
|
+
jobId: { type: 'string', description: 'Alias for scheduleId.' },
|
|
214
|
+
targetId: { type: 'string', description: 'Alias for scheduleId.' },
|
|
215
|
+
task: { type: 'string', description: 'Autonomous task for action:create, or replacement task for action:edit.' },
|
|
216
|
+
message: { type: 'string', description: 'Reminder text for action:reminder.' },
|
|
217
|
+
successCriteria: { type: 'string', description: 'Required for autonomous scheduled tasks.' },
|
|
218
|
+
scheduleKind: { type: 'string', enum: ['at', 'every', 'cron'], description: 'Schedule kind.' },
|
|
219
|
+
kind: { type: 'string', enum: ['at', 'every', 'cron'], description: 'Alias for scheduleKind.' },
|
|
220
|
+
scheduleValue: { type: 'string', description: 'ISO timestamp, interval, or cron expression.' },
|
|
221
|
+
value: { type: 'string', description: 'Alias for scheduleValue.' },
|
|
222
|
+
at: { type: 'string', description: 'ISO timestamp shortcut.' },
|
|
223
|
+
every: { type: 'string', description: 'Interval shortcut such as 1d or 30m.' },
|
|
224
|
+
cron: { type: 'string', description: 'Cron expression shortcut.' },
|
|
225
|
+
timezone: { type: 'string', description: 'Optional IANA timezone.' },
|
|
226
|
+
staggerMs: { type: 'number', description: 'Optional cron stagger in milliseconds for edits.' },
|
|
227
|
+
name: { type: 'string', description: 'Connected schedule display name.' },
|
|
228
|
+
prompt: { type: 'string', description: 'Exact replacement prompt for action:edit.' },
|
|
229
|
+
provider: { type: 'string', description: 'Optional provider row id for scheduled execution.' },
|
|
230
|
+
model: { type: 'string', description: 'Optional model id for scheduled execution.' },
|
|
231
|
+
deliveryChannel: { type: 'string', description: 'Optional delivery channel target.' },
|
|
232
|
+
deliveryRoute: { type: 'string', description: 'Optional connected route target.' },
|
|
233
|
+
deliveryWebhook: { type: 'string', description: 'Optional webhook target.' },
|
|
234
|
+
deliveryLink: { type: 'string', description: 'Optional link delivery target.' },
|
|
235
|
+
disabled: { type: 'boolean', description: 'Create schedule disabled.' },
|
|
236
|
+
query: { type: 'string', description: 'Optional list query or schedule lookup text.' },
|
|
237
|
+
limit: { type: 'number', description: 'Optional list limit when supported by the connected host.' },
|
|
238
|
+
confirm: { type: 'boolean', description: 'Required true for create/edit/run/pause/resume/delete.' },
|
|
239
|
+
explicitUserRequest: { type: 'string', description: 'User request authorizing side-effecting schedule actions.' },
|
|
240
|
+
},
|
|
241
|
+
additionalProperties: false,
|
|
242
|
+
},
|
|
243
|
+
sideEffects: ['network', 'state'],
|
|
244
|
+
concurrency: 'serial',
|
|
245
|
+
},
|
|
246
|
+
execute: async (rawArgs: unknown) => {
|
|
247
|
+
const args = (rawArgs && typeof rawArgs === 'object' && !Array.isArray(rawArgs) ? rawArgs : {}) as AgentScheduleToolArgs;
|
|
248
|
+
const action = readAction(args);
|
|
249
|
+
if (action === 'list') {
|
|
250
|
+
return operatorMethodTool.execute({
|
|
251
|
+
methodId: 'schedules.list',
|
|
252
|
+
input: listInput(args),
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
if (action === 'create') return autonomyTool.execute(autonomyArgs(args));
|
|
256
|
+
if (action === 'reminder') return reminderTool.execute(reminderArgs(args));
|
|
257
|
+
if (action === 'edit') return editTool.execute(editArgs(args));
|
|
258
|
+
|
|
259
|
+
const scheduleId = readScheduleId(args);
|
|
260
|
+
if (!scheduleId) {
|
|
261
|
+
return {
|
|
262
|
+
success: false,
|
|
263
|
+
error: `scheduleId is required for schedule action:${action}.`,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
return operatorActionTool.execute({
|
|
267
|
+
action: LIFECYCLE_ACTIONS[action],
|
|
268
|
+
scheduleId,
|
|
269
|
+
confirm: readBoolean(args.confirm),
|
|
270
|
+
explicitUserRequest: args.explicitUserRequest,
|
|
271
|
+
});
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export function registerAgentScheduleTool(
|
|
277
|
+
registry: ToolRegistry,
|
|
278
|
+
shellPaths: ShellPathService,
|
|
279
|
+
configManager: AgentConnectedHostConfigReader,
|
|
280
|
+
): void {
|
|
281
|
+
if (!registry.has('schedule')) registry.register(createAgentScheduleTool(shellPaths, configManager));
|
|
282
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import type { Tool } from '@pellux/goodvibes-sdk/platform/types';
|
|
2
|
+
import type { ToolRegistry } from '@pellux/goodvibes-sdk/platform/tools';
|
|
3
|
+
import type { CommandContext, CommandRegistry } from '../input/command-registry.ts';
|
|
4
|
+
import { createAgentHarnessTool } from './agent-harness-tool.ts';
|
|
5
|
+
import { explainAgentPolicyDecision } from './agent-policy-explanation.ts';
|
|
6
|
+
|
|
7
|
+
type AgentSecurityAction = 'status' | 'finding' | 'explain';
|
|
8
|
+
|
|
9
|
+
interface AgentSecurityToolArgs {
|
|
10
|
+
readonly action?: unknown;
|
|
11
|
+
readonly mode?: unknown;
|
|
12
|
+
readonly id?: unknown;
|
|
13
|
+
readonly findingId?: unknown;
|
|
14
|
+
readonly toolName?: unknown;
|
|
15
|
+
readonly tool?: unknown;
|
|
16
|
+
readonly toolArgs?: unknown;
|
|
17
|
+
readonly args?: unknown;
|
|
18
|
+
readonly target?: unknown;
|
|
19
|
+
readonly query?: unknown;
|
|
20
|
+
readonly includeParameters?: unknown;
|
|
21
|
+
readonly limit?: unknown;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface AgentSecurityToolDeps {
|
|
25
|
+
readonly commandRegistry: CommandRegistry;
|
|
26
|
+
readonly commandContext: CommandContext;
|
|
27
|
+
readonly toolRegistry: ToolRegistry;
|
|
28
|
+
readonly harnessTool?: Tool;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function error(message: string): { readonly success: false; readonly error: string } {
|
|
32
|
+
return { success: false, error: message };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function output(value: unknown): { readonly success: true; readonly output: string } {
|
|
36
|
+
return { success: true, output: JSON.stringify(value, null, 2) };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function readString(value: unknown): string {
|
|
40
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function normalizeSecurityAction(value: unknown): AgentSecurityAction | null {
|
|
44
|
+
const action = readString(value).toLowerCase().replace(/-/g, '_');
|
|
45
|
+
if (!action) return null;
|
|
46
|
+
if (action === 'status' || action === 'summary' || action === 'review' || action === 'posture') return 'status';
|
|
47
|
+
if (action === 'finding' || action === 'show' || action === 'inspect' || action === 'security_finding') return 'finding';
|
|
48
|
+
if (action === 'explain' || action === 'policy' || action === 'policy_explain' || action === 'why') return 'explain';
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function readAction(args: AgentSecurityToolArgs): AgentSecurityAction | null {
|
|
53
|
+
const explicit = readString(args.action) || readString(args.mode);
|
|
54
|
+
if (explicit) return normalizeSecurityAction(explicit);
|
|
55
|
+
if (readString(args.toolName) || readString(args.tool)) return 'explain';
|
|
56
|
+
if (readString(args.findingId) || readString(args.id)) return 'finding';
|
|
57
|
+
return 'status';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function compactArgs(entries: Record<string, unknown>): Record<string, unknown> {
|
|
61
|
+
return Object.fromEntries(Object.entries(entries).filter(([, value]) => value !== undefined && value !== ''));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function statusArgs(args: AgentSecurityToolArgs): Record<string, unknown> {
|
|
65
|
+
return compactArgs({
|
|
66
|
+
mode: 'security_posture',
|
|
67
|
+
query: args.query ?? args.target,
|
|
68
|
+
includeParameters: args.includeParameters,
|
|
69
|
+
limit: args.limit,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function findingArgs(args: AgentSecurityToolArgs): Record<string, unknown> {
|
|
74
|
+
const findingId = readString(args.findingId) || readString(args.id);
|
|
75
|
+
return compactArgs({
|
|
76
|
+
mode: 'security_finding',
|
|
77
|
+
findingId,
|
|
78
|
+
target: findingId ? undefined : args.target,
|
|
79
|
+
query: findingId ? undefined : args.query,
|
|
80
|
+
includeParameters: args.includeParameters,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function createAgentSecurityTool(deps: AgentSecurityToolDeps): Tool {
|
|
85
|
+
const harnessTool = deps.harnessTool ?? createAgentHarnessTool({
|
|
86
|
+
commandRegistry: deps.commandRegistry,
|
|
87
|
+
commandContext: deps.commandContext,
|
|
88
|
+
toolRegistry: deps.toolRegistry,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
definition: {
|
|
93
|
+
name: 'security',
|
|
94
|
+
description: 'Read security posture, findings, and policy explanations.',
|
|
95
|
+
parameters: {
|
|
96
|
+
type: 'object',
|
|
97
|
+
properties: {
|
|
98
|
+
action: {
|
|
99
|
+
type: 'string',
|
|
100
|
+
enum: ['status', 'finding', 'explain'],
|
|
101
|
+
description: 'Read posture, finding detail, or action policy.',
|
|
102
|
+
},
|
|
103
|
+
mode: { type: 'string', description: 'Alias for action.' },
|
|
104
|
+
id: { type: 'string', description: 'Generic finding id.' },
|
|
105
|
+
findingId: { type: 'string', description: 'Security finding id.' },
|
|
106
|
+
toolName: { type: 'string', description: 'Model tool name for action:explain.' },
|
|
107
|
+
tool: { type: 'string', description: 'Alias for toolName.' },
|
|
108
|
+
toolArgs: { type: 'object', description: 'Arguments for policy explanation.' },
|
|
109
|
+
args: { type: 'object', description: 'Alias for toolArgs.' },
|
|
110
|
+
target: { type: 'string', description: 'Lookup target or search text.' },
|
|
111
|
+
query: { type: 'string', description: 'Search text.' },
|
|
112
|
+
includeParameters: { type: 'boolean', description: 'Include detailed evidence and tool metadata.' },
|
|
113
|
+
limit: { type: 'number', description: 'Maximum findings returned.' },
|
|
114
|
+
},
|
|
115
|
+
additionalProperties: false,
|
|
116
|
+
},
|
|
117
|
+
sideEffects: [],
|
|
118
|
+
concurrency: 'parallel',
|
|
119
|
+
},
|
|
120
|
+
execute: async (rawArgs: unknown) => {
|
|
121
|
+
const args = (rawArgs && typeof rawArgs === 'object' && !Array.isArray(rawArgs) ? rawArgs : {}) as AgentSecurityToolArgs;
|
|
122
|
+
const action = readAction(args);
|
|
123
|
+
if (!action) return error('Unknown security action. Use action:"status" or action:"explain".');
|
|
124
|
+
|
|
125
|
+
if (action === 'status') return harnessTool.execute(statusArgs(args));
|
|
126
|
+
if (action === 'finding') return harnessTool.execute(findingArgs(args));
|
|
127
|
+
if (action === 'explain') {
|
|
128
|
+
const resolved = explainAgentPolicyDecision(deps.commandContext, deps.toolRegistry, args);
|
|
129
|
+
if (resolved.status === 'found') return output(resolved.explanation);
|
|
130
|
+
if (resolved.status === 'ambiguous') return error(`Ambiguous security policy target ${resolved.input}. Candidates: ${JSON.stringify(resolved.candidates)}`);
|
|
131
|
+
return error(resolved.usage);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return error('Unknown security action. Use action:"status" or action:"explain".');
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export function registerAgentSecurityTool(
|
|
140
|
+
registry: ToolRegistry,
|
|
141
|
+
commandRegistry: CommandRegistry,
|
|
142
|
+
commandContext: CommandContext,
|
|
143
|
+
): void {
|
|
144
|
+
if (!registry.has('security')) registry.register(createAgentSecurityTool({ commandRegistry, commandContext, toolRegistry: registry }));
|
|
145
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { Tool } from '@pellux/goodvibes-sdk/platform/types';
|
|
2
|
+
import type { ToolRegistry } from '@pellux/goodvibes-sdk/platform/tools';
|
|
3
|
+
import type { CommandContext, CommandRegistry } from '../input/command-registry.ts';
|
|
4
|
+
import { createAgentHarnessTool } from './agent-harness-tool.ts';
|
|
5
|
+
|
|
6
|
+
type AgentSessionsAction = 'list' | 'get';
|
|
7
|
+
|
|
8
|
+
interface AgentSessionsToolArgs {
|
|
9
|
+
readonly action?: unknown;
|
|
10
|
+
readonly mode?: unknown;
|
|
11
|
+
readonly id?: unknown;
|
|
12
|
+
readonly sessionId?: unknown;
|
|
13
|
+
readonly target?: unknown;
|
|
14
|
+
readonly query?: unknown;
|
|
15
|
+
readonly includeParameters?: unknown;
|
|
16
|
+
readonly limit?: unknown;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface AgentSessionsToolDeps {
|
|
20
|
+
readonly commandRegistry: CommandRegistry;
|
|
21
|
+
readonly commandContext: CommandContext;
|
|
22
|
+
readonly toolRegistry: ToolRegistry;
|
|
23
|
+
readonly harnessTool?: Tool;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function error(message: string): { readonly success: false; readonly error: string } {
|
|
27
|
+
return { success: false, error: message };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function readString(value: unknown): string {
|
|
31
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function normalizeSessionsAction(value: unknown): AgentSessionsAction | null {
|
|
35
|
+
const action = readString(value).toLowerCase().replace(/-/g, '_');
|
|
36
|
+
if (!action) return null;
|
|
37
|
+
if (['list', 'search', 'status', 'summary', 'catalog', 'sessions', 'bookmarks'].includes(action)) return 'list';
|
|
38
|
+
if (['get', 'show', 'inspect', 'session'].includes(action)) return 'get';
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function readAction(args: AgentSessionsToolArgs): AgentSessionsAction | null {
|
|
43
|
+
const explicit = normalizeSessionsAction(args.action) ?? normalizeSessionsAction(args.mode);
|
|
44
|
+
if (explicit) return explicit;
|
|
45
|
+
if (readString(args.sessionId) || readString(args.id)) return 'get';
|
|
46
|
+
return 'list';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function compactArgs(entries: Record<string, unknown>): Record<string, unknown> {
|
|
50
|
+
return Object.fromEntries(Object.entries(entries).filter(([, value]) => value !== undefined && value !== ''));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function listArgs(args: AgentSessionsToolArgs): Record<string, unknown> {
|
|
54
|
+
return compactArgs({
|
|
55
|
+
mode: 'sessions',
|
|
56
|
+
query: args.query ?? args.target,
|
|
57
|
+
includeParameters: args.includeParameters,
|
|
58
|
+
limit: args.limit,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function getArgs(args: AgentSessionsToolArgs): Record<string, unknown> {
|
|
63
|
+
const sessionId = readString(args.sessionId) || readString(args.id);
|
|
64
|
+
return compactArgs({
|
|
65
|
+
mode: 'session',
|
|
66
|
+
sessionId,
|
|
67
|
+
target: sessionId ? undefined : args.target,
|
|
68
|
+
query: sessionId ? undefined : args.query,
|
|
69
|
+
includeParameters: args.includeParameters,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function createAgentSessionsTool(deps: AgentSessionsToolDeps): Tool {
|
|
74
|
+
const harnessTool = deps.harnessTool ?? createAgentHarnessTool({
|
|
75
|
+
commandRegistry: deps.commandRegistry,
|
|
76
|
+
commandContext: deps.commandContext,
|
|
77
|
+
toolRegistry: deps.toolRegistry,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
definition: {
|
|
82
|
+
name: 'sessions',
|
|
83
|
+
description: 'Read saved sessions, bookmarks, and transcript continuity.',
|
|
84
|
+
parameters: {
|
|
85
|
+
type: 'object',
|
|
86
|
+
properties: {
|
|
87
|
+
action: {
|
|
88
|
+
type: 'string',
|
|
89
|
+
enum: ['list', 'search', 'status', 'get'],
|
|
90
|
+
description: 'List/search sessions or inspect one saved session.',
|
|
91
|
+
},
|
|
92
|
+
mode: { type: 'string', description: 'Alias for action.' },
|
|
93
|
+
id: { type: 'string', description: 'Alias for sessionId.' },
|
|
94
|
+
sessionId: { type: 'string', description: 'Saved session id.' },
|
|
95
|
+
target: { type: 'string', description: 'Lookup target or search text.' },
|
|
96
|
+
query: { type: 'string', description: 'Search text.' },
|
|
97
|
+
includeParameters: { type: 'boolean', description: 'Include detail, snippets, and route metadata.' },
|
|
98
|
+
limit: { type: 'number', description: 'Maximum sessions returned.' },
|
|
99
|
+
},
|
|
100
|
+
additionalProperties: false,
|
|
101
|
+
},
|
|
102
|
+
sideEffects: [],
|
|
103
|
+
concurrency: 'parallel',
|
|
104
|
+
},
|
|
105
|
+
execute: async (rawArgs: unknown) => {
|
|
106
|
+
const args = (rawArgs && typeof rawArgs === 'object' && !Array.isArray(rawArgs) ? rawArgs : {}) as AgentSessionsToolArgs;
|
|
107
|
+
const action = readAction(args);
|
|
108
|
+
if (!action) return error('Unknown sessions action. Use action:"list" or action:"get".');
|
|
109
|
+
if (action === 'list') return harnessTool.execute(listArgs(args));
|
|
110
|
+
if (action === 'get') return harnessTool.execute(getArgs(args));
|
|
111
|
+
return error('Unknown sessions action. Use action:"list" or action:"get".');
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function registerAgentSessionsTool(
|
|
117
|
+
registry: ToolRegistry,
|
|
118
|
+
commandRegistry: CommandRegistry,
|
|
119
|
+
commandContext: CommandContext,
|
|
120
|
+
): void {
|
|
121
|
+
if (!registry.has('sessions')) registry.register(createAgentSessionsTool({ commandRegistry, commandContext, toolRegistry: registry }));
|
|
122
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { Tool } from '@pellux/goodvibes-sdk/platform/types';
|
|
2
|
+
import type { ToolRegistry } from '@pellux/goodvibes-sdk/platform/tools';
|
|
3
|
+
import type { CommandContext } from '../input/command-registry.ts';
|
|
4
|
+
import {
|
|
5
|
+
importAgentWorkspaceTuiSettings,
|
|
6
|
+
previewAgentWorkspaceTuiSettingsImport,
|
|
7
|
+
} from '../input/agent-workspace-settings.ts';
|
|
8
|
+
|
|
9
|
+
type SettingsImportAction = 'preview' | 'apply';
|
|
10
|
+
|
|
11
|
+
interface AgentSettingsImportArgs {
|
|
12
|
+
readonly action?: unknown;
|
|
13
|
+
readonly mode?: unknown;
|
|
14
|
+
readonly confirm?: unknown;
|
|
15
|
+
readonly explicitUserRequest?: unknown;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function output(value: unknown): { readonly success: true; readonly output: string } {
|
|
19
|
+
return {
|
|
20
|
+
success: true,
|
|
21
|
+
output: typeof value === 'string' ? value : JSON.stringify(value, null, 2),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function error(message: string): { readonly success: false; readonly error: string } {
|
|
26
|
+
return { success: false, error: message };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function readString(value: unknown): string {
|
|
30
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function readBoolean(value: unknown): boolean {
|
|
34
|
+
return value === true || (typeof value === 'string' && ['true', 'yes', 'apply', 'import'].includes(value.trim().toLowerCase()));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function readAction(args: AgentSettingsImportArgs): SettingsImportAction {
|
|
38
|
+
const raw = (readString(args.action) || readString(args.mode)).toLowerCase();
|
|
39
|
+
if (raw === 'apply' || raw === 'confirm') return 'apply';
|
|
40
|
+
if (raw === 'import') return readBoolean(args.confirm) ? 'apply' : 'preview';
|
|
41
|
+
return 'preview';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function createAgentSettingsImportTool(commandContext: CommandContext): Tool {
|
|
45
|
+
return {
|
|
46
|
+
definition: {
|
|
47
|
+
name: 'import_goodvibes_settings',
|
|
48
|
+
description: 'Preview or apply shared GoodVibes settings import.',
|
|
49
|
+
parameters: {
|
|
50
|
+
type: 'object',
|
|
51
|
+
properties: {
|
|
52
|
+
action: {
|
|
53
|
+
type: 'string',
|
|
54
|
+
enum: ['preview', 'import', 'apply'],
|
|
55
|
+
description: 'preview is read-only; apply/import with confirm mutates Agent settings.',
|
|
56
|
+
},
|
|
57
|
+
mode: { type: 'string', description: 'Alias for action.' },
|
|
58
|
+
confirm: { type: 'boolean', description: 'Required true for action:apply.' },
|
|
59
|
+
explicitUserRequest: { type: 'string', description: 'User request authorizing confirmed import.' },
|
|
60
|
+
},
|
|
61
|
+
additionalProperties: false,
|
|
62
|
+
},
|
|
63
|
+
sideEffects: ['state'],
|
|
64
|
+
concurrency: 'serial',
|
|
65
|
+
},
|
|
66
|
+
execute: async (rawArgs: unknown) => {
|
|
67
|
+
const args = (rawArgs && typeof rawArgs === 'object' && !Array.isArray(rawArgs) ? rawArgs : {}) as AgentSettingsImportArgs;
|
|
68
|
+
const preview = previewAgentWorkspaceTuiSettingsImport(commandContext);
|
|
69
|
+
if (!preview) return error('GoodVibes settings import is unavailable in this runtime.');
|
|
70
|
+
const action = readAction(args);
|
|
71
|
+
|
|
72
|
+
if (action === 'preview' || !readBoolean(args.confirm)) {
|
|
73
|
+
return output({
|
|
74
|
+
status: 'confirmation_required',
|
|
75
|
+
action: 'import_goodvibes_settings',
|
|
76
|
+
preview,
|
|
77
|
+
next: 'Run action:"apply" with confirm:true and explicitUserRequest after the user asks to import these settings.',
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const explicitUserRequest = readString(args.explicitUserRequest);
|
|
82
|
+
if (!explicitUserRequest) return error('GoodVibes settings import requires explicitUserRequest when confirm is true.');
|
|
83
|
+
|
|
84
|
+
const outcome = await importAgentWorkspaceTuiSettings(commandContext);
|
|
85
|
+
return output({
|
|
86
|
+
status: outcome.status,
|
|
87
|
+
action: 'import_goodvibes_settings',
|
|
88
|
+
preview,
|
|
89
|
+
actionResult: outcome.result,
|
|
90
|
+
runtimeSnapshot: outcome.runtimeSnapshot,
|
|
91
|
+
policy: {
|
|
92
|
+
effect: 'state',
|
|
93
|
+
confirmation: 'confirmed',
|
|
94
|
+
explicitUserRequest,
|
|
95
|
+
boundary: 'Applied only Agent-owned settings and subscription state from published GoodVibes platform sources; source package stores were not mutated.',
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function registerAgentSettingsImportTool(registry: ToolRegistry, commandContext: CommandContext): void {
|
|
103
|
+
if (!registry.has('import_goodvibes_settings')) registry.register(createAgentSettingsImportTool(commandContext));
|
|
104
|
+
}
|