@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,101 @@
|
|
|
1
|
+
import type { AgentWorkspaceActionResult, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
|
|
2
|
+
import type { AgentWorkspaceSkillBundleCommandEditorKind } from './agent-workspace-skill-bundle-command-editors.ts';
|
|
3
|
+
import { isAgentWorkspaceSkillBundleCommandEditorKind } from './agent-workspace-skill-bundle-command-editors.ts';
|
|
4
|
+
import { quoteSlashCommandArg } from './slash-command-parser.ts';
|
|
5
|
+
|
|
6
|
+
type AgentWorkspaceFieldReader = (fieldId: string) => string;
|
|
7
|
+
|
|
8
|
+
export type AgentWorkspaceSkillBundleCommandEditorSubmission =
|
|
9
|
+
| {
|
|
10
|
+
readonly kind: 'editor';
|
|
11
|
+
readonly editor: AgentWorkspaceLocalEditor;
|
|
12
|
+
readonly status: string;
|
|
13
|
+
readonly actionResult?: AgentWorkspaceActionResult;
|
|
14
|
+
}
|
|
15
|
+
| {
|
|
16
|
+
readonly kind: 'dispatch';
|
|
17
|
+
readonly command: string;
|
|
18
|
+
readonly status: string;
|
|
19
|
+
readonly actionResult: AgentWorkspaceActionResult;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export function isAgentWorkspaceSkillBundleCommandSubmissionKind(kind: string): kind is AgentWorkspaceSkillBundleCommandEditorKind {
|
|
23
|
+
return isAgentWorkspaceSkillBundleCommandEditorKind(kind as AgentWorkspaceSkillBundleCommandEditorKind);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function isAffirmative(value: string): boolean {
|
|
27
|
+
return /^(y|yes|true)$/i.test(value.trim());
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function unconfirmed(editor: AgentWorkspaceLocalEditor, message: string): AgentWorkspaceSkillBundleCommandEditorSubmission {
|
|
31
|
+
return {
|
|
32
|
+
kind: 'editor',
|
|
33
|
+
editor: { ...editor, message },
|
|
34
|
+
status: message,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function dispatch(command: string, title: string, detail: string, safety: AgentWorkspaceActionResult['safety']): AgentWorkspaceSkillBundleCommandEditorSubmission {
|
|
39
|
+
return {
|
|
40
|
+
kind: 'dispatch',
|
|
41
|
+
command,
|
|
42
|
+
status: `${title}.`,
|
|
43
|
+
actionResult: { kind: 'dispatched', title, detail, command, safety },
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function buildAgentWorkspaceSkillBundleCommandEditorSubmission(
|
|
48
|
+
editor: AgentWorkspaceLocalEditor,
|
|
49
|
+
readField: AgentWorkspaceFieldReader,
|
|
50
|
+
): AgentWorkspaceSkillBundleCommandEditorSubmission {
|
|
51
|
+
if (editor.kind === 'skill-bundle-search') {
|
|
52
|
+
const query = readField('query').trim();
|
|
53
|
+
const command = query.length > 0 ? `/skills bundle search ${quoteSlashCommandArg(query)}` : '/skills bundle search';
|
|
54
|
+
return dispatch(command, 'Opening skill bundle search', 'The workspace handed a read-only skill bundle search command to the shell-owned command router.', 'read-only');
|
|
55
|
+
}
|
|
56
|
+
if (editor.kind === 'skill-bundle-show') {
|
|
57
|
+
return dispatch(
|
|
58
|
+
`/skills bundle show ${quoteSlashCommandArg(readField('id'))}`,
|
|
59
|
+
'Opening skill bundle detail',
|
|
60
|
+
'The workspace handed a read-only skill bundle detail command to the shell-owned command router.',
|
|
61
|
+
'read-only',
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
if (editor.kind === 'skill-bundle-update') {
|
|
65
|
+
if (!isAffirmative(readField('confirm'))) return unconfirmed(editor, 'Skill bundle update not confirmed. Type yes, then press Enter.');
|
|
66
|
+
const parts = ['/skills', 'bundle', 'update', quoteSlashCommandArg(readField('id'))];
|
|
67
|
+
const name = readField('name');
|
|
68
|
+
const description = readField('description');
|
|
69
|
+
const skills = readField('skills');
|
|
70
|
+
if (name.length > 0) parts.push('--name', quoteSlashCommandArg(name));
|
|
71
|
+
if (description.length > 0) parts.push('--description', quoteSlashCommandArg(description));
|
|
72
|
+
if (skills.length > 0) parts.push('--skills', quoteSlashCommandArg(skills));
|
|
73
|
+
return dispatch(parts.join(' '), 'Opening skill bundle update', 'The workspace handed a confirmed skill bundle update command to the shell-owned command router.', 'safe');
|
|
74
|
+
}
|
|
75
|
+
if (editor.kind === 'skill-bundle-enable' || editor.kind === 'skill-bundle-disable' || editor.kind === 'skill-bundle-review') {
|
|
76
|
+
if (!isAffirmative(readField('confirm'))) return unconfirmed(editor, 'Skill bundle action not confirmed. Type yes, then press Enter.');
|
|
77
|
+
const verb = editor.kind.replace('skill-bundle-', '');
|
|
78
|
+
return dispatch(
|
|
79
|
+
`/skills bundle ${verb} ${quoteSlashCommandArg(readField('id'))}`,
|
|
80
|
+
`Opening skill bundle ${verb}`,
|
|
81
|
+
`The workspace handed a confirmed skill bundle ${verb} command to the shell-owned command router.`,
|
|
82
|
+
'safe',
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
if (editor.kind === 'skill-bundle-stale') {
|
|
86
|
+
if (!isAffirmative(readField('confirm'))) return unconfirmed(editor, 'Skill bundle stale action not confirmed. Type yes, then press Enter.');
|
|
87
|
+
return dispatch(
|
|
88
|
+
`/skills bundle stale ${quoteSlashCommandArg(readField('id'))} ${quoteSlashCommandArg(readField('reason'))}`,
|
|
89
|
+
'Opening skill bundle stale review',
|
|
90
|
+
'The workspace handed a confirmed skill bundle stale command to the shell-owned command router.',
|
|
91
|
+
'safe',
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
if (!isAffirmative(readField('confirm'))) return unconfirmed(editor, 'Skill bundle delete not confirmed. Type yes, then press Enter.');
|
|
95
|
+
return dispatch(
|
|
96
|
+
`/skills bundle delete ${quoteSlashCommandArg(readField('id'))} --yes`,
|
|
97
|
+
'Opening skill bundle delete',
|
|
98
|
+
'The workspace handed a confirmed skill bundle delete command to the shell-owned command router.',
|
|
99
|
+
'safe',
|
|
100
|
+
);
|
|
101
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
|
|
2
|
+
|
|
3
|
+
export type AgentWorkspaceSkillBundleCommandEditorKind = Extract<
|
|
4
|
+
AgentWorkspaceEditorKind,
|
|
5
|
+
| 'skill-bundle-search'
|
|
6
|
+
| 'skill-bundle-show'
|
|
7
|
+
| 'skill-bundle-update'
|
|
8
|
+
| 'skill-bundle-enable'
|
|
9
|
+
| 'skill-bundle-disable'
|
|
10
|
+
| 'skill-bundle-review'
|
|
11
|
+
| 'skill-bundle-stale'
|
|
12
|
+
| 'skill-bundle-delete'
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
export function isAgentWorkspaceSkillBundleCommandEditorKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceSkillBundleCommandEditorKind {
|
|
16
|
+
return kind === 'skill-bundle-search'
|
|
17
|
+
|| kind === 'skill-bundle-show'
|
|
18
|
+
|| kind === 'skill-bundle-update'
|
|
19
|
+
|| kind === 'skill-bundle-enable'
|
|
20
|
+
|| kind === 'skill-bundle-disable'
|
|
21
|
+
|| kind === 'skill-bundle-review'
|
|
22
|
+
|| kind === 'skill-bundle-stale'
|
|
23
|
+
|| kind === 'skill-bundle-delete';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function createAgentWorkspaceSkillBundleCommandEditor(kind: AgentWorkspaceSkillBundleCommandEditorKind): AgentWorkspaceLocalEditor {
|
|
27
|
+
if (kind === 'skill-bundle-search') {
|
|
28
|
+
return {
|
|
29
|
+
kind,
|
|
30
|
+
mode: 'create',
|
|
31
|
+
title: 'Search Skill Bundles',
|
|
32
|
+
selectedFieldIndex: 0,
|
|
33
|
+
message: 'Search Agent-local skill bundles by name, description, or member skill.',
|
|
34
|
+
fields: [
|
|
35
|
+
{ id: 'query', label: 'Search query', value: '', required: false, multiline: false, hint: 'Optional text query. Blank lists every bundle.' },
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (kind === 'skill-bundle-show') {
|
|
40
|
+
return {
|
|
41
|
+
kind,
|
|
42
|
+
mode: 'create',
|
|
43
|
+
title: 'Show Skill Bundle',
|
|
44
|
+
selectedFieldIndex: 0,
|
|
45
|
+
message: 'Show one Agent-local skill bundle with readiness and member skills.',
|
|
46
|
+
fields: [
|
|
47
|
+
{ id: 'id', label: 'Bundle id', value: '', required: true, multiline: false, hint: 'Existing local skill bundle id.' },
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
if (kind === 'skill-bundle-update') {
|
|
52
|
+
return {
|
|
53
|
+
kind,
|
|
54
|
+
mode: 'update',
|
|
55
|
+
title: 'Update Skill Bundle',
|
|
56
|
+
selectedFieldIndex: 0,
|
|
57
|
+
message: 'Update one Agent-local skill bundle. Type yes on the final field to confirm.',
|
|
58
|
+
fields: [
|
|
59
|
+
{ id: 'id', label: 'Bundle id', value: '', required: true, multiline: false, hint: 'Existing local skill bundle id.' },
|
|
60
|
+
{ id: 'name', label: 'Name', value: '', required: false, multiline: false, hint: 'Optional replacement name.' },
|
|
61
|
+
{ id: 'description', label: 'Description', value: '', required: false, multiline: false, hint: 'Optional replacement one-line description.' },
|
|
62
|
+
{ id: 'skills', label: 'Skill ids', value: '', required: false, multiline: false, hint: 'Optional replacement comma-separated local skill ids.' },
|
|
63
|
+
{ id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /skills bundle update.' },
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (kind === 'skill-bundle-stale') {
|
|
68
|
+
return {
|
|
69
|
+
kind,
|
|
70
|
+
mode: 'update',
|
|
71
|
+
title: 'Mark Skill Bundle Stale',
|
|
72
|
+
selectedFieldIndex: 0,
|
|
73
|
+
message: 'Mark one Agent-local skill bundle stale with a review reason. Type yes on the final field to confirm.',
|
|
74
|
+
fields: [
|
|
75
|
+
{ id: 'id', label: 'Bundle id', value: '', required: true, multiline: false, hint: 'Existing local skill bundle id.' },
|
|
76
|
+
{ id: 'reason', label: 'Reason', value: '', required: true, multiline: true, hint: 'Why this bundle needs review. Ctrl-J inserts a new line.' },
|
|
77
|
+
{ id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /skills bundle stale.' },
|
|
78
|
+
],
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (kind === 'skill-bundle-delete') {
|
|
82
|
+
return {
|
|
83
|
+
kind,
|
|
84
|
+
mode: 'delete',
|
|
85
|
+
title: 'Delete Skill Bundle',
|
|
86
|
+
selectedFieldIndex: 0,
|
|
87
|
+
message: 'Delete one Agent-local skill bundle. This does not delete member skills. Type yes to confirm.',
|
|
88
|
+
fields: [
|
|
89
|
+
{ id: 'id', label: 'Bundle id', value: '', required: true, multiline: false, hint: 'Existing local skill bundle id.' },
|
|
90
|
+
{ id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /skills bundle delete with --yes.' },
|
|
91
|
+
],
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
const verb = kind === 'skill-bundle-enable'
|
|
95
|
+
? 'Enable'
|
|
96
|
+
: kind === 'skill-bundle-disable'
|
|
97
|
+
? 'Disable'
|
|
98
|
+
: 'Review';
|
|
99
|
+
return {
|
|
100
|
+
kind,
|
|
101
|
+
mode: 'update',
|
|
102
|
+
title: `${verb} Skill Bundle`,
|
|
103
|
+
selectedFieldIndex: 0,
|
|
104
|
+
message: `${verb} one Agent-local skill bundle. Type yes on the final field to confirm.`,
|
|
105
|
+
fields: [
|
|
106
|
+
{ id: 'id', label: 'Bundle id', value: '', required: true, multiline: false, hint: 'Existing local skill bundle id.' },
|
|
107
|
+
{ id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: `Type yes to run /skills bundle ${verb.toLowerCase()}.` },
|
|
108
|
+
],
|
|
109
|
+
};
|
|
110
|
+
}
|
|
@@ -1,29 +1,39 @@
|
|
|
1
1
|
import { basename, sep } from 'node:path';
|
|
2
2
|
import type { MemoryRecord } from '@pellux/goodvibes-sdk/platform/state';
|
|
3
3
|
import type { CommandContext } from './command-registry.ts';
|
|
4
|
+
import { AgentNoteRegistry, type AgentNoteRecord } from '../agent/note-registry.ts';
|
|
4
5
|
import { AgentPersonaRegistry, type AgentPersonaRecord } from '../agent/persona-registry.ts';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
6
|
+
import { formatAgentRecordOrigin } from '../agent/record-labels.ts';
|
|
7
|
+
import { AgentRoutineRegistry, evaluateAgentRoutineReadiness, type AgentRoutineRecord } from '../agent/routine-registry.ts';
|
|
8
|
+
import {
|
|
9
|
+
AgentSkillRegistry,
|
|
10
|
+
evaluateAgentSkillBundleReadiness,
|
|
11
|
+
evaluateAgentSkillReadiness,
|
|
12
|
+
formatAgentSkillRequirement,
|
|
13
|
+
type AgentSkillBundleRecord,
|
|
14
|
+
type AgentSkillRecord,
|
|
15
|
+
} from '../agent/skill-registry.ts';
|
|
7
16
|
import { summarizeAgentBehaviorDiscovery } from '../agent/behavior-discovery-summary.ts';
|
|
8
17
|
import { isPromptActiveMemory } from '../agent/memory-prompt.ts';
|
|
9
|
-
import { getAgentRuntimeProfilesRoot, listAgentRuntimeProfiles, listAgentRuntimeProfileTemplates } from '../agent/runtime-profile.ts';
|
|
18
|
+
import { getAgentRuntimeProfilesRoot, listAgentRuntimeProfiles, listAgentRuntimeProfileTemplates, readAgentRuntimeProfileSelection } from '../agent/runtime-profile.ts';
|
|
19
|
+
import { RoutineScheduleReceiptStore } from '../agent/routine-schedule-receipts.ts';
|
|
20
|
+
import { GOODVIBES_AGENT_PAIRING_SURFACE } from '../config/surface.ts';
|
|
21
|
+
import { connectedHostOperatorTokenFingerprint, readConnectedHostOperatorToken, type ConnectedHostOperatorToken } from '../runtime/connected-host-auth.ts';
|
|
10
22
|
import { buildAgentWorkspaceChannels } from './agent-workspace-channels.ts';
|
|
23
|
+
import { getAgentWorkspaceConfigReader } from './agent-workspace-config-reader.ts';
|
|
11
24
|
import { buildAgentWorkspaceSetupChecklist } from './agent-workspace-setup.ts';
|
|
12
25
|
import { buildAgentWorkspaceVoiceMediaReadiness, type AgentWorkspaceVoiceMediaProviderDescriptor } from './agent-workspace-voice-media.ts';
|
|
13
26
|
import type {
|
|
14
27
|
AgentWorkspaceLocalLibraryItem,
|
|
28
|
+
AgentWorkspaceRoutineScheduleReceiptSummary,
|
|
15
29
|
AgentWorkspaceRuntimeProfileItem,
|
|
16
30
|
AgentWorkspaceRuntimeSnapshot,
|
|
17
31
|
AgentWorkspaceRuntimeStarterTemplateItem,
|
|
18
32
|
} from './agent-workspace-types.ts';
|
|
19
33
|
|
|
20
|
-
type AgentWorkspaceConfigReader = {
|
|
21
|
-
get(key: string): unknown;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
34
|
function readConfigString(context: CommandContext, key: string, fallback: string): string {
|
|
25
35
|
try {
|
|
26
|
-
const configManager = context
|
|
36
|
+
const configManager = getAgentWorkspaceConfigReader(context);
|
|
27
37
|
const value = configManager?.get(key);
|
|
28
38
|
return typeof value === 'string' && value.trim().length > 0 ? value.trim() : fallback;
|
|
29
39
|
} catch {
|
|
@@ -33,7 +43,7 @@ function readConfigString(context: CommandContext, key: string, fallback: string
|
|
|
33
43
|
|
|
34
44
|
function readConfigNumber(context: CommandContext, key: string, fallback: number): number {
|
|
35
45
|
try {
|
|
36
|
-
const configManager = context
|
|
46
|
+
const configManager = getAgentWorkspaceConfigReader(context);
|
|
37
47
|
const value = configManager?.get(key);
|
|
38
48
|
const numberValue = typeof value === 'number' ? value : Number(value);
|
|
39
49
|
return Number.isFinite(numberValue) ? numberValue : fallback;
|
|
@@ -44,7 +54,7 @@ function readConfigNumber(context: CommandContext, key: string, fallback: number
|
|
|
44
54
|
|
|
45
55
|
function readConfigBoolean(context: CommandContext, key: string, fallback: boolean): boolean {
|
|
46
56
|
try {
|
|
47
|
-
const configManager = context
|
|
57
|
+
const configManager = getAgentWorkspaceConfigReader(context);
|
|
48
58
|
const value = configManager?.get(key);
|
|
49
59
|
if (typeof value === 'boolean') return value;
|
|
50
60
|
if (typeof value === 'string') {
|
|
@@ -63,13 +73,19 @@ function inferActiveRuntimeProfile(homeDirectory: string): string {
|
|
|
63
73
|
return homeDirectory.includes(marker) ? basename(homeDirectory) : '(default home)';
|
|
64
74
|
}
|
|
65
75
|
|
|
76
|
+
function inferRuntimeProfileBaseHome(homeDirectory: string): string {
|
|
77
|
+
const marker = `${sep}.goodvibes${sep}agent${sep}profile-homes${sep}`;
|
|
78
|
+
const markerIndex = homeDirectory.indexOf(marker);
|
|
79
|
+
return markerIndex >= 0 ? homeDirectory.slice(0, markerIndex) : homeDirectory;
|
|
80
|
+
}
|
|
81
|
+
|
|
66
82
|
function summarizePersonaItem(persona: AgentPersonaRecord, activePersonaId: string | null): AgentWorkspaceLocalLibraryItem {
|
|
67
83
|
return {
|
|
68
84
|
id: persona.id,
|
|
69
85
|
name: persona.name,
|
|
70
86
|
description: persona.description,
|
|
71
87
|
reviewState: persona.reviewState,
|
|
72
|
-
source: persona.source,
|
|
88
|
+
source: formatAgentRecordOrigin(persona.source, persona.provenance),
|
|
73
89
|
tags: persona.tags,
|
|
74
90
|
triggers: persona.triggers,
|
|
75
91
|
active: persona.id === activePersonaId,
|
|
@@ -77,45 +93,76 @@ function summarizePersonaItem(persona: AgentPersonaRecord, activePersonaId: stri
|
|
|
77
93
|
}
|
|
78
94
|
|
|
79
95
|
function summarizeSkillItem(skill: AgentSkillRecord): AgentWorkspaceLocalLibraryItem {
|
|
96
|
+
const readiness = evaluateAgentSkillReadiness(skill);
|
|
80
97
|
return {
|
|
81
98
|
id: skill.id,
|
|
82
99
|
name: skill.name,
|
|
83
100
|
description: skill.description,
|
|
84
101
|
reviewState: skill.reviewState,
|
|
85
|
-
source: skill.source,
|
|
102
|
+
source: formatAgentRecordOrigin(skill.source, skill.provenance),
|
|
86
103
|
tags: skill.tags,
|
|
87
104
|
triggers: skill.triggers,
|
|
88
105
|
enabled: skill.enabled,
|
|
106
|
+
requirementCount: skill.requirements.length,
|
|
107
|
+
missingRequirementCount: readiness.missing.length,
|
|
108
|
+
missingRequirements: readiness.missing.map(formatAgentSkillRequirement),
|
|
89
109
|
};
|
|
90
110
|
}
|
|
91
111
|
|
|
92
|
-
function summarizeSkillBundleItem(bundle: AgentSkillBundleRecord): AgentWorkspaceLocalLibraryItem {
|
|
112
|
+
function summarizeSkillBundleItem(bundle: AgentSkillBundleRecord, skills: readonly AgentSkillRecord[]): AgentWorkspaceLocalLibraryItem {
|
|
113
|
+
const readiness = evaluateAgentSkillBundleReadiness(bundle, skills);
|
|
114
|
+
const missing = [
|
|
115
|
+
...readiness.missingRequirements.map(formatAgentSkillRequirement),
|
|
116
|
+
...readiness.missingSkillIds.map((skillId) => `skill:${skillId}`),
|
|
117
|
+
];
|
|
93
118
|
return {
|
|
94
119
|
id: bundle.id,
|
|
95
120
|
name: bundle.name,
|
|
96
121
|
description: `${bundle.description} Skills: ${bundle.skillIds.join(', ')}`,
|
|
97
122
|
reviewState: bundle.reviewState,
|
|
98
|
-
source: bundle.source,
|
|
123
|
+
source: formatAgentRecordOrigin(bundle.source, bundle.provenance),
|
|
99
124
|
tags: bundle.skillIds,
|
|
100
125
|
triggers: [],
|
|
101
126
|
enabled: bundle.enabled,
|
|
127
|
+
requirementCount: readiness.includedSkills.reduce((total, skill) => total + skill.requirements.length, 0) + readiness.missingSkillIds.length,
|
|
128
|
+
missingRequirementCount: missing.length,
|
|
129
|
+
missingRequirements: missing,
|
|
102
130
|
};
|
|
103
131
|
}
|
|
104
132
|
|
|
105
133
|
function summarizeRoutineItem(routine: AgentRoutineRecord): AgentWorkspaceLocalLibraryItem {
|
|
134
|
+
const readiness = evaluateAgentRoutineReadiness(routine);
|
|
106
135
|
return {
|
|
107
136
|
id: routine.id,
|
|
108
137
|
name: routine.name,
|
|
109
138
|
description: routine.description,
|
|
110
139
|
reviewState: routine.reviewState,
|
|
111
|
-
source: routine.source,
|
|
140
|
+
source: formatAgentRecordOrigin(routine.source, routine.provenance),
|
|
112
141
|
tags: routine.tags,
|
|
113
142
|
triggers: routine.triggers,
|
|
114
143
|
enabled: routine.enabled,
|
|
144
|
+
requirementCount: routine.requirements.length,
|
|
145
|
+
missingRequirementCount: readiness.missing.length,
|
|
146
|
+
missingRequirements: readiness.missing.map(formatAgentSkillRequirement),
|
|
115
147
|
startCount: routine.startCount,
|
|
116
148
|
};
|
|
117
149
|
}
|
|
118
150
|
|
|
151
|
+
function summarizeRoutineScheduleReceipt(
|
|
152
|
+
receipt: ReturnType<RoutineScheduleReceiptStore['snapshot']>['receipts'][number],
|
|
153
|
+
): AgentWorkspaceRoutineScheduleReceiptSummary {
|
|
154
|
+
return {
|
|
155
|
+
id: receipt.id,
|
|
156
|
+
status: receipt.status,
|
|
157
|
+
routineId: receipt.routineId,
|
|
158
|
+
routineName: receipt.routineName,
|
|
159
|
+
scheduleName: receipt.scheduleName,
|
|
160
|
+
scheduleKind: receipt.scheduleKind,
|
|
161
|
+
scheduleValue: receipt.scheduleValue,
|
|
162
|
+
createdAt: receipt.createdAt,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
119
166
|
function summarizeMemoryItem(record: MemoryRecord): AgentWorkspaceLocalLibraryItem {
|
|
120
167
|
const detail = record.detail?.trim();
|
|
121
168
|
return {
|
|
@@ -123,7 +170,7 @@ function summarizeMemoryItem(record: MemoryRecord): AgentWorkspaceLocalLibraryIt
|
|
|
123
170
|
name: record.summary,
|
|
124
171
|
description: detail && detail.length > 0 ? detail : `${record.scope}/${record.cls}`,
|
|
125
172
|
reviewState: record.reviewState,
|
|
126
|
-
source: '
|
|
173
|
+
source: 'Agent memory',
|
|
127
174
|
tags: record.tags,
|
|
128
175
|
triggers: [],
|
|
129
176
|
scope: record.scope,
|
|
@@ -132,6 +179,22 @@ function summarizeMemoryItem(record: MemoryRecord): AgentWorkspaceLocalLibraryIt
|
|
|
132
179
|
};
|
|
133
180
|
}
|
|
134
181
|
|
|
182
|
+
function summarizeNoteItem(note: AgentNoteRecord): AgentWorkspaceLocalLibraryItem {
|
|
183
|
+
const preview = note.body.replace(/\s+/g, ' ').trim();
|
|
184
|
+
const description = note.sourceUrl
|
|
185
|
+
? `${preview.slice(0, 160)}${preview.length > 160 ? '...' : ''} Origin URL ${note.sourceUrl}`
|
|
186
|
+
: preview;
|
|
187
|
+
return {
|
|
188
|
+
id: note.id,
|
|
189
|
+
name: note.title,
|
|
190
|
+
description,
|
|
191
|
+
reviewState: note.reviewState,
|
|
192
|
+
source: formatAgentRecordOrigin(note.source, note.provenance),
|
|
193
|
+
tags: note.tags,
|
|
194
|
+
triggers: [],
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
135
198
|
function summarizeRuntimeProfile(profile: ReturnType<typeof listAgentRuntimeProfiles>[number]): AgentWorkspaceRuntimeProfileItem {
|
|
136
199
|
return {
|
|
137
200
|
id: profile.id,
|
|
@@ -202,6 +265,20 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
202
265
|
return { count: 0, activeName: '(unavailable)', items: [] };
|
|
203
266
|
}
|
|
204
267
|
})();
|
|
268
|
+
const noteSnapshot = (() => {
|
|
269
|
+
try {
|
|
270
|
+
const shellPaths = context.workspace?.shellPaths;
|
|
271
|
+
if (!shellPaths) return { count: 0, reviewQueueCount: 0, items: [] };
|
|
272
|
+
const snapshot = AgentNoteRegistry.fromShellPaths(shellPaths).snapshot();
|
|
273
|
+
return {
|
|
274
|
+
count: snapshot.notes.length,
|
|
275
|
+
reviewQueueCount: snapshot.reviewQueue.length,
|
|
276
|
+
items: snapshot.notes.map(summarizeNoteItem),
|
|
277
|
+
};
|
|
278
|
+
} catch {
|
|
279
|
+
return { count: 0, reviewQueueCount: 0, items: [] };
|
|
280
|
+
}
|
|
281
|
+
})();
|
|
205
282
|
const skillSnapshot = (() => {
|
|
206
283
|
try {
|
|
207
284
|
const shellPaths = context.workspace?.shellPaths;
|
|
@@ -214,7 +291,7 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
214
291
|
bundleCount: snapshot.bundles.length,
|
|
215
292
|
enabledBundleCount: snapshot.enabledBundles.length,
|
|
216
293
|
items: snapshot.skills.map(summarizeSkillItem),
|
|
217
|
-
bundleItems: snapshot.bundles.map(summarizeSkillBundleItem),
|
|
294
|
+
bundleItems: snapshot.bundles.map((bundle) => summarizeSkillBundleItem(bundle, snapshot.skills)),
|
|
218
295
|
};
|
|
219
296
|
} catch {
|
|
220
297
|
return { count: 0, enabled: 0, active: 0, bundleCount: 0, enabledBundleCount: 0, items: [], bundleItems: [] };
|
|
@@ -234,21 +311,44 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
234
311
|
return { count: 0, enabled: 0, items: [] };
|
|
235
312
|
}
|
|
236
313
|
})();
|
|
314
|
+
const routineScheduleReceipts = (() => {
|
|
315
|
+
try {
|
|
316
|
+
const shellPaths = context.workspace?.shellPaths;
|
|
317
|
+
if (!shellPaths) return { count: 0, successful: 0, failed: 0, latest: null };
|
|
318
|
+
const receipts = RoutineScheduleReceiptStore.fromShellPaths(shellPaths).snapshot().receipts;
|
|
319
|
+
return {
|
|
320
|
+
count: receipts.length,
|
|
321
|
+
successful: receipts.filter((receipt) => receipt.status === 'created').length,
|
|
322
|
+
failed: receipts.filter((receipt) => receipt.status === 'failed').length,
|
|
323
|
+
latest: receipts[0] ? summarizeRoutineScheduleReceipt(receipts[0]) : null,
|
|
324
|
+
};
|
|
325
|
+
} catch {
|
|
326
|
+
return { count: 0, successful: 0, failed: 0, latest: null };
|
|
327
|
+
}
|
|
328
|
+
})();
|
|
237
329
|
const discoveredBehavior = summarizeAgentBehaviorDiscovery(context.workspace?.shellPaths);
|
|
330
|
+
const profileBaseHome = inferRuntimeProfileBaseHome(context.workspace?.shellPaths?.homeDirectory ?? '');
|
|
238
331
|
const runtimeProfiles = (() => {
|
|
239
332
|
try {
|
|
240
|
-
return listAgentRuntimeProfiles(
|
|
333
|
+
return listAgentRuntimeProfiles(profileBaseHome);
|
|
241
334
|
} catch {
|
|
242
335
|
return [];
|
|
243
336
|
}
|
|
244
337
|
})();
|
|
245
338
|
const runtimeStarterTemplates = (() => {
|
|
246
339
|
try {
|
|
247
|
-
return listAgentRuntimeProfileTemplates(
|
|
340
|
+
return listAgentRuntimeProfileTemplates(profileBaseHome);
|
|
248
341
|
} catch {
|
|
249
342
|
return [];
|
|
250
343
|
}
|
|
251
344
|
})();
|
|
345
|
+
const selectedRuntimeProfile = (() => {
|
|
346
|
+
try {
|
|
347
|
+
return readAgentRuntimeProfileSelection(profileBaseHome);
|
|
348
|
+
} catch {
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
})();
|
|
252
352
|
const voiceProviders = (() => {
|
|
253
353
|
try {
|
|
254
354
|
return context.platform?.voiceProviderRegistry?.list?.() ?? [];
|
|
@@ -299,6 +399,32 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
299
399
|
const ttsLlmProvider = readConfigString(context, 'tts.llmProvider', '');
|
|
300
400
|
const ttsLlmModel = readConfigString(context, 'tts.llmModel', '');
|
|
301
401
|
const runtimeBaseUrl = `http://${host}:${port}`;
|
|
402
|
+
const companionAccess = (() => {
|
|
403
|
+
const homeDirectory = context.workspace?.shellPaths?.homeDirectory ?? '';
|
|
404
|
+
const tokenRecord: ConnectedHostOperatorToken = homeDirectory.length > 0
|
|
405
|
+
? readConnectedHostOperatorToken(homeDirectory)
|
|
406
|
+
: { path: '(Agent home unavailable)', present: false, token: null };
|
|
407
|
+
const tokenFingerprint = tokenRecord.token ? connectedHostOperatorTokenFingerprint(tokenRecord.token) : null;
|
|
408
|
+
const pairingReady = Boolean(tokenRecord.token);
|
|
409
|
+
const nextStep = tokenRecord.error
|
|
410
|
+
? 'Repair the connected-host operator token file through the owning GoodVibes host, then rerun /pair.'
|
|
411
|
+
: pairingReady
|
|
412
|
+
? 'Use /pair to scan the QR code. Manual token display stays hidden unless /pair --show-token --yes is used.'
|
|
413
|
+
: 'Pair or provision connected-host access through the owning GoodVibes host, then rerun /pair.';
|
|
414
|
+
return {
|
|
415
|
+
surface: GOODVIBES_AGENT_PAIRING_SURFACE,
|
|
416
|
+
hostUrl: runtimeBaseUrl,
|
|
417
|
+
tokenPath: tokenRecord.path,
|
|
418
|
+
tokenPresent: tokenRecord.present,
|
|
419
|
+
tokenReadable: Boolean(tokenRecord.token),
|
|
420
|
+
tokenFingerprint,
|
|
421
|
+
tokenError: tokenRecord.error ?? null,
|
|
422
|
+
pairingReady,
|
|
423
|
+
qrCommand: '/pair',
|
|
424
|
+
manualTokenCommand: '/pair --show-token --yes',
|
|
425
|
+
nextStep,
|
|
426
|
+
} as const;
|
|
427
|
+
})();
|
|
302
428
|
const channels = buildAgentWorkspaceChannels(context);
|
|
303
429
|
const voiceMediaReadiness = buildAgentWorkspaceVoiceMediaReadiness({
|
|
304
430
|
context,
|
|
@@ -312,12 +438,16 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
312
438
|
sessionMemoryCount,
|
|
313
439
|
localMemoryCount: memorySnapshot.count,
|
|
314
440
|
localMemoryReviewQueueCount: memorySnapshot.reviewQueueCount,
|
|
441
|
+
localNoteCount: noteSnapshot.count,
|
|
442
|
+
localNoteReviewQueueCount: noteSnapshot.reviewQueueCount,
|
|
315
443
|
routineCount: routineSnapshot.count,
|
|
316
444
|
enabledRoutineCount: routineSnapshot.enabled,
|
|
445
|
+
missingRoutineRequirementCount: routineSnapshot.items.reduce((total, item) => total + (item.missingRequirementCount ?? 0), 0),
|
|
317
446
|
skillCount: skillSnapshot.count,
|
|
318
447
|
enabledSkillCount: skillSnapshot.enabled,
|
|
319
448
|
skillBundleCount: skillSnapshot.bundleCount,
|
|
320
449
|
enabledSkillBundleCount: skillSnapshot.enabledBundleCount,
|
|
450
|
+
missingSkillRequirementCount: skillSnapshot.items.reduce((total, item) => total + (item.missingRequirementCount ?? 0), 0),
|
|
321
451
|
activePersonaName: personaSnapshot.activeName,
|
|
322
452
|
discoveredPersonas: discoveredBehavior.personas,
|
|
323
453
|
discoveredSkills: discoveredBehavior.skills,
|
|
@@ -343,9 +473,16 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
343
473
|
localMemoryReviewQueueCount: memorySnapshot.reviewQueueCount,
|
|
344
474
|
localMemoryPromptActiveCount: memorySnapshot.promptActiveCount,
|
|
345
475
|
localMemories: memorySnapshot.items,
|
|
476
|
+
localNoteCount: noteSnapshot.count,
|
|
477
|
+
localNoteReviewQueueCount: noteSnapshot.reviewQueueCount,
|
|
478
|
+
localNotes: noteSnapshot.items,
|
|
346
479
|
localRoutineCount: routineSnapshot.count,
|
|
347
480
|
enabledRoutineCount: routineSnapshot.enabled,
|
|
348
481
|
localRoutines: routineSnapshot.items,
|
|
482
|
+
routineScheduleReceiptCount: routineScheduleReceipts.count,
|
|
483
|
+
successfulRoutineScheduleReceiptCount: routineScheduleReceipts.successful,
|
|
484
|
+
failedRoutineScheduleReceiptCount: routineScheduleReceipts.failed,
|
|
485
|
+
latestRoutineScheduleReceipt: routineScheduleReceipts.latest,
|
|
349
486
|
localSkillCount: skillSnapshot.count,
|
|
350
487
|
enabledSkillCount: skillSnapshot.enabled,
|
|
351
488
|
localSkillBundleCount: skillSnapshot.bundleCount,
|
|
@@ -360,7 +497,8 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
360
497
|
knowledgeRoute: '/api/goodvibes-agent/knowledge',
|
|
361
498
|
knowledgeIsolation: 'agent-only',
|
|
362
499
|
executionPolicy: 'serial-proactive',
|
|
363
|
-
|
|
500
|
+
delegatedReviewPolicy: 'explicit-build-delegation-only',
|
|
501
|
+
companionAccess,
|
|
364
502
|
channels,
|
|
365
503
|
voiceProviderCount: voiceProviders.length,
|
|
366
504
|
voiceStreamingProviderCount: voiceProviders.filter((entry) => entry.capabilities.includes('tts-stream')).length,
|
|
@@ -381,9 +519,12 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
381
519
|
browserToolExposureEnabled: readConfigBoolean(context, 'web.enabled', false),
|
|
382
520
|
browserToolPublicBaseUrl: readConfigString(context, 'web.publicBaseUrl', '(not configured)'),
|
|
383
521
|
activeRuntimeProfile: inferActiveRuntimeProfile(context.workspace?.shellPaths?.homeDirectory ?? ''),
|
|
522
|
+
selectedRuntimeProfile: selectedRuntimeProfile?.id ?? null,
|
|
523
|
+
selectedRuntimeProfileExists: selectedRuntimeProfile?.exists ?? false,
|
|
524
|
+
selectedRuntimeProfileSelectedAt: selectedRuntimeProfile?.selectedAt ?? null,
|
|
384
525
|
runtimeProfileCount: runtimeProfiles.length,
|
|
385
526
|
runtimeProfiles: runtimeProfiles.map(summarizeRuntimeProfile),
|
|
386
|
-
runtimeProfileRoot: getAgentRuntimeProfilesRoot(
|
|
527
|
+
runtimeProfileRoot: getAgentRuntimeProfilesRoot(profileBaseHome),
|
|
387
528
|
runtimeStarterTemplateCount: runtimeStarterTemplates.length,
|
|
388
529
|
localStarterTemplateCount: runtimeStarterTemplates.filter((template) => template.source === 'local').length,
|
|
389
530
|
runtimeStarterTemplates: runtimeStarterTemplates.map(summarizeStarterTemplate),
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { AgentWorkspaceActionResult, AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
|
|
2
|
+
import type { AgentWorkspaceTaskCommandEditorKind } from './agent-workspace-task-command-editors.ts';
|
|
3
|
+
import { isAgentWorkspaceTaskCommandEditorKind } from './agent-workspace-task-command-editors.ts';
|
|
4
|
+
import { quoteSlashCommandArg } from './slash-command-parser.ts';
|
|
5
|
+
|
|
6
|
+
type AgentWorkspaceFieldReader = (fieldId: string) => string;
|
|
7
|
+
|
|
8
|
+
export type AgentWorkspaceTaskCommandEditorSubmission =
|
|
9
|
+
| {
|
|
10
|
+
readonly kind: 'editor';
|
|
11
|
+
readonly editor: AgentWorkspaceLocalEditor;
|
|
12
|
+
readonly status: string;
|
|
13
|
+
readonly actionResult?: AgentWorkspaceActionResult;
|
|
14
|
+
}
|
|
15
|
+
| {
|
|
16
|
+
readonly kind: 'dispatch';
|
|
17
|
+
readonly command: string;
|
|
18
|
+
readonly status: string;
|
|
19
|
+
readonly actionResult: AgentWorkspaceActionResult;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export function isAgentWorkspaceTaskCommandSubmissionKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceTaskCommandEditorKind {
|
|
23
|
+
return isAgentWorkspaceTaskCommandEditorKind(kind);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function buildAgentWorkspaceTaskCommandEditorSubmission(
|
|
27
|
+
editor: AgentWorkspaceLocalEditor,
|
|
28
|
+
readField: AgentWorkspaceFieldReader,
|
|
29
|
+
): AgentWorkspaceTaskCommandEditorSubmission {
|
|
30
|
+
if (editor.kind === 'task-list-filter') {
|
|
31
|
+
const filter = readField('filter');
|
|
32
|
+
const command = filter.length > 0 ? `/tasks list ${quoteSlashCommandArg(filter)}` : '/tasks list';
|
|
33
|
+
return {
|
|
34
|
+
kind: 'dispatch',
|
|
35
|
+
command,
|
|
36
|
+
status: 'Opening filtered task list.',
|
|
37
|
+
actionResult: {
|
|
38
|
+
kind: 'dispatched',
|
|
39
|
+
title: 'Opening filtered task list',
|
|
40
|
+
detail: 'The workspace handed read-only connected-host task listing to the shell-owned command router.',
|
|
41
|
+
command,
|
|
42
|
+
safety: 'read-only',
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const subcommand = editor.kind === 'task-output' ? 'output' : 'show';
|
|
47
|
+
const command = `/tasks ${subcommand} ${quoteSlashCommandArg(readField('taskId'))}`;
|
|
48
|
+
const title = editor.kind === 'task-output' ? 'Opening task output' : 'Opening task inspection';
|
|
49
|
+
return {
|
|
50
|
+
kind: 'dispatch',
|
|
51
|
+
command,
|
|
52
|
+
status: `${title}.`,
|
|
53
|
+
actionResult: {
|
|
54
|
+
kind: 'dispatched',
|
|
55
|
+
title,
|
|
56
|
+
detail: 'The workspace handed read-only connected-host task inspection to the shell-owned command router.',
|
|
57
|
+
command,
|
|
58
|
+
safety: 'read-only',
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|