@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,83 @@
|
|
|
1
|
+
import type { AgentWorkspaceActionResult, AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
|
|
2
|
+
import type { AgentWorkspaceChannelCommandEditorKind } from './agent-workspace-channel-command-editors.ts';
|
|
3
|
+
import { isAgentWorkspaceChannelCommandEditorKind } from './agent-workspace-channel-command-editors.ts';
|
|
4
|
+
import { quoteSlashCommandArg } from './slash-command-parser.ts';
|
|
5
|
+
|
|
6
|
+
type AgentWorkspaceFieldReader = (fieldId: string) => string;
|
|
7
|
+
|
|
8
|
+
export type AgentWorkspaceChannelCommandEditorSubmission =
|
|
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 isAgentWorkspaceChannelCommandSubmissionKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceChannelCommandEditorKind {
|
|
23
|
+
return isAgentWorkspaceChannelCommandEditorKind(kind);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function buildAgentWorkspaceChannelCommandEditorSubmission(
|
|
27
|
+
editor: AgentWorkspaceLocalEditor,
|
|
28
|
+
readField: AgentWorkspaceFieldReader,
|
|
29
|
+
): AgentWorkspaceChannelCommandEditorSubmission {
|
|
30
|
+
if (editor.kind === 'channel-send') {
|
|
31
|
+
if (!/^(y|yes|true)$/i.test(readField('confirm').trim())) {
|
|
32
|
+
return {
|
|
33
|
+
kind: 'editor',
|
|
34
|
+
editor: { ...editor, message: 'Channel delivery not confirmed. Type yes, then press Enter.' },
|
|
35
|
+
status: 'Channel delivery not confirmed.',
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const parts = ['/channels', 'send'];
|
|
39
|
+
const title = readField('title');
|
|
40
|
+
const channel = readField('channel');
|
|
41
|
+
const route = readField('route');
|
|
42
|
+
const webhook = readField('webhook');
|
|
43
|
+
const link = readField('link');
|
|
44
|
+
if (title) parts.push('--title', quoteSlashCommandArg(title));
|
|
45
|
+
if (channel) parts.push('--channel', quoteSlashCommandArg(channel));
|
|
46
|
+
if (route) parts.push('--route', quoteSlashCommandArg(route));
|
|
47
|
+
if (webhook) parts.push('--webhook', quoteSlashCommandArg(webhook));
|
|
48
|
+
if (link) parts.push('--link', quoteSlashCommandArg(link));
|
|
49
|
+
parts.push('--message', quoteSlashCommandArg(readField('message')), '--yes');
|
|
50
|
+
const command = parts.join(' ');
|
|
51
|
+
return {
|
|
52
|
+
kind: 'dispatch',
|
|
53
|
+
command,
|
|
54
|
+
status: 'Opening channel delivery.',
|
|
55
|
+
actionResult: {
|
|
56
|
+
kind: 'dispatched',
|
|
57
|
+
title: 'Opening channel delivery',
|
|
58
|
+
detail: 'The workspace handed a confirmed channel delivery command to the shell-owned command router.',
|
|
59
|
+
command,
|
|
60
|
+
safety: 'safe',
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const subcommand = editor.kind === 'channel-doctor' ? 'doctor' : editor.kind === 'channel-setup' ? 'setup' : 'show';
|
|
65
|
+
const command = `/channels ${subcommand} ${quoteSlashCommandArg(readField('channel'))}`;
|
|
66
|
+
const title = editor.kind === 'channel-doctor'
|
|
67
|
+
? 'Opening channel doctor'
|
|
68
|
+
: editor.kind === 'channel-setup'
|
|
69
|
+
? 'Opening channel setup guidance'
|
|
70
|
+
: 'Opening channel detail';
|
|
71
|
+
return {
|
|
72
|
+
kind: 'dispatch',
|
|
73
|
+
command,
|
|
74
|
+
status: `${title}.`,
|
|
75
|
+
actionResult: {
|
|
76
|
+
kind: 'dispatched',
|
|
77
|
+
title,
|
|
78
|
+
detail: 'The workspace handed read-only channel inspection to the shell-owned command router.',
|
|
79
|
+
command,
|
|
80
|
+
safety: 'read-only',
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
|
|
2
|
+
|
|
3
|
+
export type AgentWorkspaceChannelCommandEditorKind = Extract<
|
|
4
|
+
AgentWorkspaceEditorKind,
|
|
5
|
+
'channel-show' | 'channel-doctor' | 'channel-setup' | 'channel-send'
|
|
6
|
+
>;
|
|
7
|
+
|
|
8
|
+
export function isAgentWorkspaceChannelCommandEditorKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceChannelCommandEditorKind {
|
|
9
|
+
return kind === 'channel-show' || kind === 'channel-doctor' || kind === 'channel-setup' || kind === 'channel-send';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function createAgentWorkspaceChannelCommandEditor(kind: AgentWorkspaceChannelCommandEditorKind): AgentWorkspaceLocalEditor {
|
|
13
|
+
if (kind === 'channel-send') {
|
|
14
|
+
return {
|
|
15
|
+
kind,
|
|
16
|
+
mode: 'create',
|
|
17
|
+
title: 'Send Channel Message',
|
|
18
|
+
selectedFieldIndex: 0,
|
|
19
|
+
message: 'Send one message through a configured delivery target. Fill exactly one target field and type yes to confirm.',
|
|
20
|
+
fields: [
|
|
21
|
+
{ id: 'message', label: 'Message', value: '', required: true, multiline: true, hint: 'Plain-text message. Ctrl-J inserts a new line.' },
|
|
22
|
+
{ id: 'title', label: 'Title', value: '', required: false, multiline: false, hint: 'Optional delivery title. Blank uses the Agent default.' },
|
|
23
|
+
{ id: 'channel', label: 'Channel target', value: '', required: false, multiline: false, hint: 'Optional surface[:route[:label]], such as slack:ops:Ops or telephony:+15551234567.' },
|
|
24
|
+
{ id: 'route', label: 'Route target', value: '', required: false, multiline: false, hint: 'Optional route id or route:label.' },
|
|
25
|
+
{ id: 'webhook', label: 'Webhook URL', value: '', required: false, multiline: false, hint: 'Optional http(s) webhook target.' },
|
|
26
|
+
{ id: 'link', label: 'Link target', value: '', required: false, multiline: false, hint: 'Optional link delivery target.' },
|
|
27
|
+
{ id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /channels send with --yes.' },
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
if (kind === 'channel-doctor') {
|
|
32
|
+
return {
|
|
33
|
+
kind,
|
|
34
|
+
mode: 'create',
|
|
35
|
+
title: 'Run Channel Doctor',
|
|
36
|
+
selectedFieldIndex: 0,
|
|
37
|
+
message: 'Inspect one connected channel route without sending messages or changing delivery state.',
|
|
38
|
+
fields: [
|
|
39
|
+
{ id: 'channel', label: 'Channel id', value: '', required: true, multiline: false, hint: 'Channel id, such as slack, telegram, discord, ntfy, signal, whatsapp, or telephony.' },
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (kind === 'channel-setup') {
|
|
44
|
+
return {
|
|
45
|
+
kind,
|
|
46
|
+
mode: 'create',
|
|
47
|
+
title: 'Show Channel Setup',
|
|
48
|
+
selectedFieldIndex: 0,
|
|
49
|
+
message: 'Show read-only setup guidance for one channel. This does not pair, enable, or send through the channel.',
|
|
50
|
+
fields: [
|
|
51
|
+
{ id: 'channel', label: 'Channel id', value: '', required: true, multiline: false, hint: 'Channel id, such as slack, telegram, discord, ntfy, signal, whatsapp, or telephony.' },
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
kind,
|
|
57
|
+
mode: 'create',
|
|
58
|
+
title: 'Show Channel Detail',
|
|
59
|
+
selectedFieldIndex: 0,
|
|
60
|
+
message: 'Show one channel readiness record from the Agent workspace without changing channel state.',
|
|
61
|
+
fields: [
|
|
62
|
+
{ id: 'channel', label: 'Channel id', value: '', required: true, multiline: false, hint: 'Channel id, such as slack, telegram, discord, ntfy, signal, whatsapp, or telephony.' },
|
|
63
|
+
],
|
|
64
|
+
};
|
|
65
|
+
}
|
|
@@ -29,6 +29,7 @@ interface AgentWorkspaceChannelSpec {
|
|
|
29
29
|
readonly label: string;
|
|
30
30
|
readonly enabledKey: string;
|
|
31
31
|
readonly requiredKeys: readonly string[];
|
|
32
|
+
readonly requiredKeyGroups?: readonly (readonly string[])[];
|
|
32
33
|
readonly defaultTargetKeys: readonly string[];
|
|
33
34
|
readonly risk: AgentWorkspaceChannelRisk;
|
|
34
35
|
readonly riskLabel: string;
|
|
@@ -98,6 +99,19 @@ const AGENT_WORKSPACE_CHANNEL_SPECS: readonly AgentWorkspaceChannelSpec[] = [
|
|
|
98
99
|
risk: 'dm',
|
|
99
100
|
riskLabel: 'phone-number delivery',
|
|
100
101
|
},
|
|
102
|
+
{
|
|
103
|
+
id: 'telephony',
|
|
104
|
+
label: 'Telephony',
|
|
105
|
+
enabledKey: 'surfaces.telephony.enabled',
|
|
106
|
+
requiredKeys: [],
|
|
107
|
+
requiredKeyGroups: [
|
|
108
|
+
['surfaces.telephony.bridgeUrl'],
|
|
109
|
+
['surfaces.telephony.accountSid', 'surfaces.telephony.authToken', 'surfaces.telephony.fromNumber'],
|
|
110
|
+
],
|
|
111
|
+
defaultTargetKeys: ['surfaces.telephony.defaultRecipient'],
|
|
112
|
+
risk: 'dm',
|
|
113
|
+
riskLabel: 'SMS/voice phone-number delivery',
|
|
114
|
+
},
|
|
101
115
|
{
|
|
102
116
|
id: 'imessage',
|
|
103
117
|
label: 'iMessage',
|
|
@@ -186,9 +200,28 @@ function hasConfigValue(context: CommandContext, key: string): boolean {
|
|
|
186
200
|
}
|
|
187
201
|
}
|
|
188
202
|
|
|
203
|
+
function uniqueStrings(values: readonly string[]): readonly string[] {
|
|
204
|
+
return [...new Set(values)];
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function missingKeysForBestRequiredGroup(context: CommandContext, groups: readonly (readonly string[])[]): readonly string[] {
|
|
208
|
+
if (groups.length === 0) return [];
|
|
209
|
+
const missingByGroup = groups.map((group) => group.filter((key) => !hasConfigValue(context, key)));
|
|
210
|
+
if (missingByGroup.some((missing) => missing.length === 0)) return [];
|
|
211
|
+
return missingByGroup.reduce((best, missing) => missing.length < best.length ? missing : best, missingByGroup[0] ?? []);
|
|
212
|
+
}
|
|
213
|
+
|
|
189
214
|
function buildChannelStatus(context: CommandContext, spec: AgentWorkspaceChannelSpec): AgentWorkspaceChannelStatus {
|
|
190
215
|
const enabled = readConfigBoolean(context, spec.enabledKey, false);
|
|
191
|
-
const
|
|
216
|
+
const requiredKeyGroups = spec.requiredKeyGroups ?? [];
|
|
217
|
+
const requiredKeys = uniqueStrings([
|
|
218
|
+
...spec.requiredKeys,
|
|
219
|
+
...requiredKeyGroups.flat(),
|
|
220
|
+
]);
|
|
221
|
+
const missingRequiredKeys = [
|
|
222
|
+
...spec.requiredKeys.filter((key) => !hasConfigValue(context, key)),
|
|
223
|
+
...missingKeysForBestRequiredGroup(context, requiredKeyGroups),
|
|
224
|
+
];
|
|
192
225
|
const configuredDefaultTargetKeys = spec.defaultTargetKeys.filter((key) => hasConfigValue(context, key));
|
|
193
226
|
const missingConfigCount = missingRequiredKeys.length;
|
|
194
227
|
const defaultTarget = spec.defaultTargetKeys.length === 0
|
|
@@ -223,7 +256,7 @@ function buildChannelStatus(context: CommandContext, spec: AgentWorkspaceChannel
|
|
|
223
256
|
label: spec.label,
|
|
224
257
|
enabled,
|
|
225
258
|
ready,
|
|
226
|
-
requiredKeys
|
|
259
|
+
requiredKeys,
|
|
227
260
|
missingRequiredKeys,
|
|
228
261
|
missingConfigCount,
|
|
229
262
|
defaultTargetKeys: spec.defaultTargetKeys,
|
|
@@ -1,23 +1,35 @@
|
|
|
1
|
+
import type { AgentWorkspaceBasicCommandEditorKind } from './agent-workspace-basic-command-editors.ts';
|
|
1
2
|
import { buildAgentWorkspaceBasicCommandEditorSubmission, isAgentWorkspaceBasicCommandEditorKind } from './agent-workspace-basic-command-editors.ts';
|
|
2
3
|
import { buildAgentKnowledgeUrlEditorSubmission } from './agent-workspace-knowledge-url-editor.ts';
|
|
3
4
|
import { buildAgentKnowledgeQueryEditorSubmission } from './agent-workspace-knowledge-query-editor.ts';
|
|
4
5
|
import { buildAgentReminderScheduleEditorSubmission } from './agent-workspace-reminder-schedule-editor.ts';
|
|
5
6
|
import { buildAgentRoutineScheduleEditorSubmission } from './agent-workspace-routine-schedule-editor.ts';
|
|
7
|
+
import { buildAgentWorkspaceWebResearchSubmission } from './agent-workspace-web-research-editor.ts';
|
|
6
8
|
import type { AgentWorkspaceActionResult, AgentWorkspaceEditorKind, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
|
|
7
9
|
|
|
8
10
|
type AgentWorkspaceFieldReader = (fieldId: string) => string;
|
|
9
|
-
type AgentWorkspaceCommandEditorKind = Extract<
|
|
11
|
+
type AgentWorkspaceCommandEditorKind = AgentWorkspaceBasicCommandEditorKind | Extract<
|
|
10
12
|
AgentWorkspaceEditorKind,
|
|
11
|
-
'
|
|
13
|
+
'web-research'
|
|
14
|
+
| 'web-fetch'
|
|
15
|
+
| 'knowledge-url'
|
|
16
|
+
| 'knowledge-urls'
|
|
12
17
|
| 'knowledge-file'
|
|
13
18
|
| 'knowledge-browser-history'
|
|
14
19
|
| 'knowledge-connector-ingest'
|
|
20
|
+
| 'knowledge-reindex'
|
|
15
21
|
| 'knowledge-search'
|
|
16
22
|
| 'knowledge-ask'
|
|
17
23
|
| 'mcp-server'
|
|
18
24
|
| 'notify-webhook'
|
|
19
25
|
| 'notify-webhook-remove'
|
|
26
|
+
| 'notify-webhook-clear'
|
|
20
27
|
| 'notify-webhook-test'
|
|
28
|
+
| 'notify-send'
|
|
29
|
+
| 'secret-set'
|
|
30
|
+
| 'secret-link'
|
|
31
|
+
| 'secret-test'
|
|
32
|
+
| 'secret-delete'
|
|
21
33
|
| 'routine-schedule'
|
|
22
34
|
| 'reminder-schedule'
|
|
23
35
|
| 'knowledge-bookmarks'
|
|
@@ -31,6 +43,20 @@ type AgentWorkspaceCommandEditorKind = Extract<
|
|
|
31
43
|
| 'profile-template-import'
|
|
32
44
|
| 'profile-template-from-discovered'
|
|
33
45
|
| 'profile-from-discovered'
|
|
46
|
+
| 'profile-default'
|
|
47
|
+
| 'profile-default-clear'
|
|
48
|
+
| 'support-bundle-export'
|
|
49
|
+
| 'support-bundle-inspect'
|
|
50
|
+
| 'support-bundle-import'
|
|
51
|
+
| 'subscription-inspect'
|
|
52
|
+
| 'subscription-login-start'
|
|
53
|
+
| 'subscription-login-finish'
|
|
54
|
+
| 'subscription-logout'
|
|
55
|
+
| 'delegate-task'
|
|
56
|
+
| 'workplan-add'
|
|
57
|
+
| 'workplan-status'
|
|
58
|
+
| 'workplan-delete'
|
|
59
|
+
| 'workplan-clear-completed'
|
|
34
60
|
>;
|
|
35
61
|
|
|
36
62
|
type AgentWorkspaceCommandEditorSubmission =
|
|
@@ -45,10 +71,18 @@ type AgentWorkspaceCommandEditorSubmission =
|
|
|
45
71
|
readonly command: string;
|
|
46
72
|
readonly status: string;
|
|
47
73
|
readonly actionResult: AgentWorkspaceActionResult;
|
|
74
|
+
}
|
|
75
|
+
| {
|
|
76
|
+
readonly kind: 'prompt';
|
|
77
|
+
readonly prompt: string;
|
|
78
|
+
readonly status: string;
|
|
79
|
+
readonly actionResult: AgentWorkspaceActionResult;
|
|
48
80
|
};
|
|
49
81
|
|
|
50
82
|
export function isAgentWorkspaceCommandEditorKind(kind: AgentWorkspaceEditorKind): kind is AgentWorkspaceCommandEditorKind {
|
|
51
|
-
return kind === '
|
|
83
|
+
return kind === 'web-research'
|
|
84
|
+
|| kind === 'web-fetch'
|
|
85
|
+
|| kind === 'knowledge-url'
|
|
52
86
|
|| kind === 'knowledge-search'
|
|
53
87
|
|| kind === 'knowledge-ask'
|
|
54
88
|
|| kind === 'routine-schedule'
|
|
@@ -60,7 +94,11 @@ export function buildAgentWorkspaceCommandEditorSubmission(
|
|
|
60
94
|
editor: AgentWorkspaceLocalEditor,
|
|
61
95
|
readField: AgentWorkspaceFieldReader,
|
|
62
96
|
commandDispatchAvailable: boolean,
|
|
97
|
+
promptDispatchAvailable: boolean,
|
|
63
98
|
): AgentWorkspaceCommandEditorSubmission {
|
|
99
|
+
if (editor.kind === 'web-research' || editor.kind === 'web-fetch') {
|
|
100
|
+
return buildAgentWorkspaceWebResearchSubmission(editor, readField, promptDispatchAvailable);
|
|
101
|
+
}
|
|
64
102
|
if (editor.kind === 'knowledge-url') return buildAgentKnowledgeUrlEditorSubmission(editor, readField, commandDispatchAvailable);
|
|
65
103
|
if (editor.kind === 'knowledge-search' || editor.kind === 'knowledge-ask') {
|
|
66
104
|
return buildAgentKnowledgeQueryEditorSubmission(editor, readField, commandDispatchAvailable);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CommandContext } from './command-registry.ts';
|
|
2
|
+
|
|
3
|
+
export interface AgentWorkspaceConfigReader {
|
|
4
|
+
get(key: string): unknown;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function getAgentWorkspaceConfigReader(context: CommandContext): AgentWorkspaceConfigReader | null {
|
|
8
|
+
const configManager: object = context.platform.configManager;
|
|
9
|
+
const get = Reflect.get(configManager, 'get');
|
|
10
|
+
if (typeof get !== 'function') return null;
|
|
11
|
+
return {
|
|
12
|
+
get(key: string): unknown {
|
|
13
|
+
return Reflect.apply(get, configManager, [key]);
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { AgentWorkspaceActionResult, AgentWorkspaceLocalEditor } from './agent-workspace-types.ts';
|
|
2
|
+
import { quoteSlashCommandArg } from './slash-command-parser.ts';
|
|
3
|
+
|
|
4
|
+
type AgentWorkspaceFieldReader = (fieldId: string) => string;
|
|
5
|
+
|
|
6
|
+
export type AgentWorkspaceDelegationEditorSubmission =
|
|
7
|
+
| {
|
|
8
|
+
readonly kind: 'editor';
|
|
9
|
+
readonly editor: AgentWorkspaceLocalEditor;
|
|
10
|
+
readonly status: string;
|
|
11
|
+
readonly actionResult?: AgentWorkspaceActionResult;
|
|
12
|
+
}
|
|
13
|
+
| {
|
|
14
|
+
readonly kind: 'dispatch';
|
|
15
|
+
readonly command: string;
|
|
16
|
+
readonly status: string;
|
|
17
|
+
readonly actionResult: AgentWorkspaceActionResult;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
function isAffirmative(value: string): boolean {
|
|
21
|
+
return /^(y|yes|true)$/i.test(value.trim());
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function isAgentWorkspaceDelegationEditorKind(kind: string): kind is 'delegate-task' {
|
|
25
|
+
return kind === 'delegate-task';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function buildAgentWorkspaceDelegationEditorSubmission(
|
|
29
|
+
editor: AgentWorkspaceLocalEditor,
|
|
30
|
+
readField: AgentWorkspaceFieldReader,
|
|
31
|
+
): AgentWorkspaceDelegationEditorSubmission {
|
|
32
|
+
if (!isAffirmative(readField('confirm'))) {
|
|
33
|
+
return {
|
|
34
|
+
kind: 'editor',
|
|
35
|
+
editor: { ...editor, message: 'Build delegation not confirmed. Type yes, then press Enter.' },
|
|
36
|
+
status: 'Build delegation not confirmed.',
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const parts = ['/delegate'];
|
|
40
|
+
if (isAffirmative(readField('review')) || isAffirmative(readField('wrfc'))) parts.push('--review');
|
|
41
|
+
parts.push(quoteSlashCommandArg(readField('task')));
|
|
42
|
+
const command = parts.join(' ');
|
|
43
|
+
return {
|
|
44
|
+
kind: 'dispatch',
|
|
45
|
+
command,
|
|
46
|
+
status: 'Opening explicit build delegation.',
|
|
47
|
+
actionResult: {
|
|
48
|
+
kind: 'dispatched',
|
|
49
|
+
title: 'Opening explicit build delegation',
|
|
50
|
+
detail: 'The workspace handed a confirmed build/fix/review task to the shell-owned command router.',
|
|
51
|
+
command,
|
|
52
|
+
safety: 'delegates',
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AgentPersonaRecord } from '../agent/persona-registry.ts';
|
|
2
2
|
import type { AgentRoutineRecord } from '../agent/routine-registry.ts';
|
|
3
3
|
import type { AgentSkillRecord } from '../agent/skill-registry.ts';
|
|
4
|
+
import type { AgentNoteRecord } from '../agent/note-registry.ts';
|
|
4
5
|
import type { MemoryRecord } from '@pellux/goodvibes-sdk/platform/state';
|
|
5
6
|
import type {
|
|
6
7
|
AgentWorkspaceLocalEditor,
|
|
@@ -30,6 +31,25 @@ export function createProfileEditor(templates: readonly AgentWorkspaceRuntimeSta
|
|
|
30
31
|
};
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
export function createLearnedBehaviorEditor(): AgentWorkspaceLocalEditor {
|
|
35
|
+
return {
|
|
36
|
+
kind: 'learned-behavior',
|
|
37
|
+
mode: 'create',
|
|
38
|
+
title: 'Capture Learned Behavior',
|
|
39
|
+
selectedFieldIndex: 0,
|
|
40
|
+
message: 'Turn a reviewed workflow or lesson into Agent-local behavior. This writes only to Agent-local personas, skills, or routines.',
|
|
41
|
+
fields: [
|
|
42
|
+
{ id: 'target', label: 'Behavior type', value: 'skill', required: true, multiline: false, hint: 'skill, routine, or persona.' },
|
|
43
|
+
{ id: 'name', label: 'Name', value: '', required: true, multiline: false, hint: 'Short name for the learned behavior.' },
|
|
44
|
+
{ id: 'description', label: 'Description', value: '', required: true, multiline: false, hint: 'One-line summary of when to use it.' },
|
|
45
|
+
{ id: 'notes', label: 'Lesson or workflow', value: '', required: true, multiline: true, hint: 'Paste the procedure, persona guidance, or repeatable workflow. Ctrl-J inserts a new line.' },
|
|
46
|
+
{ id: 'triggers', label: 'Triggers', value: '', required: false, multiline: false, hint: 'Comma-separated words that suggest this behavior.' },
|
|
47
|
+
{ id: 'tags', label: 'Tags', value: 'learned', required: false, multiline: false, hint: 'Comma-separated optional tags.' },
|
|
48
|
+
{ id: 'enable', label: 'Enable or activate', value: 'yes', required: false, multiline: false, hint: 'yes/no. Skills and routines enable; personas activate.' },
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
33
53
|
export function createLocalEditor(kind: AgentWorkspaceLocalEditorKind | 'knowledge-url'): AgentWorkspaceLocalEditor {
|
|
34
54
|
if (kind === 'profile') return createProfileEditor([]);
|
|
35
55
|
if (kind === 'knowledge-url') {
|
|
@@ -53,7 +73,7 @@ export function createLocalEditor(kind: AgentWorkspaceLocalEditorKind | 'knowled
|
|
|
53
73
|
mode: 'create',
|
|
54
74
|
title: 'Create Memory',
|
|
55
75
|
selectedFieldIndex: 0,
|
|
56
|
-
message: 'Record a durable, non-secret Agent memory. This stays in the Agent-owned memory store and never writes to default
|
|
76
|
+
message: 'Record a durable, non-secret Agent memory. This stays in the Agent-owned memory store and never writes to default knowledge.',
|
|
57
77
|
fields: [
|
|
58
78
|
{ id: 'cls', label: 'Class', value: 'fact', required: true, multiline: false, hint: 'fact, decision, constraint, incident, pattern, risk, runbook, architecture, or ownership.' },
|
|
59
79
|
{ id: 'scope', label: 'Scope', value: 'project', required: true, multiline: false, hint: 'session, project, or team.' },
|
|
@@ -64,6 +84,21 @@ export function createLocalEditor(kind: AgentWorkspaceLocalEditorKind | 'knowled
|
|
|
64
84
|
],
|
|
65
85
|
};
|
|
66
86
|
}
|
|
87
|
+
if (kind === 'note') {
|
|
88
|
+
return {
|
|
89
|
+
kind,
|
|
90
|
+
mode: 'create',
|
|
91
|
+
title: 'Create Note',
|
|
92
|
+
selectedFieldIndex: 0,
|
|
93
|
+
message: 'Capture a local working note or source-triage note. Notes stay in the Agent-local scratchpad and are not memory or Agent Knowledge.',
|
|
94
|
+
fields: [
|
|
95
|
+
{ id: 'title', label: 'Title', value: '', required: true, multiline: false, hint: 'Short note title.' },
|
|
96
|
+
{ id: 'body', label: 'Note', value: '', required: true, multiline: true, hint: 'Working note, source triage, or temporary decision. Ctrl-J inserts a new line.' },
|
|
97
|
+
{ id: 'sourceUrl', label: 'Source URL', value: '', required: false, multiline: false, hint: 'Optional reviewed URL. This does not ingest the URL into Agent Knowledge.' },
|
|
98
|
+
{ id: 'tags', label: 'Tags', value: 'scratchpad', required: false, multiline: false, hint: 'Comma-separated optional tags.' },
|
|
99
|
+
],
|
|
100
|
+
};
|
|
101
|
+
}
|
|
67
102
|
if (kind === 'persona') {
|
|
68
103
|
return {
|
|
69
104
|
kind,
|
|
@@ -94,6 +129,8 @@ export function createLocalEditor(kind: AgentWorkspaceLocalEditorKind | 'knowled
|
|
|
94
129
|
{ id: 'procedure', label: 'Procedure', value: '', required: true, multiline: true, hint: 'Reusable steps. Ctrl-J inserts a new line.' },
|
|
95
130
|
{ id: 'triggers', label: 'Triggers', value: '', required: false, multiline: false, hint: 'Comma-separated words that suggest this skill.' },
|
|
96
131
|
{ id: 'tags', label: 'Tags', value: '', required: false, multiline: false, hint: 'Comma-separated optional tags.' },
|
|
132
|
+
{ id: 'requiresEnv', label: 'Required env vars', value: '', required: false, multiline: false, hint: 'Comma-separated env var names. Values are never stored.' },
|
|
133
|
+
{ id: 'requiresCommands', label: 'Required commands', value: '', required: false, multiline: false, hint: 'Comma-separated binaries that must be on PATH.' },
|
|
97
134
|
{ id: 'enabled', label: 'Enable now', value: 'yes', required: false, multiline: false, hint: 'yes/no.' },
|
|
98
135
|
],
|
|
99
136
|
};
|
|
@@ -110,6 +147,8 @@ export function createLocalEditor(kind: AgentWorkspaceLocalEditorKind | 'knowled
|
|
|
110
147
|
{ id: 'steps', label: 'Steps', value: '', required: true, multiline: true, hint: 'Workflow steps. Ctrl-J inserts a new line.' },
|
|
111
148
|
{ id: 'triggers', label: 'Triggers', value: '', required: false, multiline: false, hint: 'Comma-separated words that suggest this routine.' },
|
|
112
149
|
{ id: 'tags', label: 'Tags', value: '', required: false, multiline: false, hint: 'Comma-separated optional tags.' },
|
|
150
|
+
{ id: 'requiresEnv', label: 'Required env vars', value: '', required: false, multiline: false, hint: 'Comma-separated env var names. Values are never stored.' },
|
|
151
|
+
{ id: 'requiresCommands', label: 'Required commands', value: '', required: false, multiline: false, hint: 'Comma-separated binaries that must be on PATH.' },
|
|
113
152
|
{ id: 'enabled', label: 'Enable now', value: 'yes', required: false, multiline: false, hint: 'yes/no.' },
|
|
114
153
|
],
|
|
115
154
|
};
|
|
@@ -132,6 +171,127 @@ export function createMemoryUpdateEditor(record: MemoryRecord): AgentWorkspaceLo
|
|
|
132
171
|
};
|
|
133
172
|
}
|
|
134
173
|
|
|
174
|
+
function noteDescription(note: AgentNoteRecord): string {
|
|
175
|
+
const compact = note.body.replace(/\s+/g, ' ').trim();
|
|
176
|
+
const firstSentence = compact.split(/(?<=[.!?])\s+/)[0]?.trim() ?? compact;
|
|
177
|
+
const base = firstSentence.length > 160 ? `${firstSentence.slice(0, 157)}...` : firstSentence;
|
|
178
|
+
return base || note.title;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function noteTags(note: AgentNoteRecord, extraTag: string): string {
|
|
182
|
+
return [...new Set([...note.tags, extraTag])].join(', ');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function createMemoryEditorFromNote(note: AgentNoteRecord): AgentWorkspaceLocalEditor {
|
|
186
|
+
const sourceLine = note.sourceUrl ? `\n\nOrigin URL: ${note.sourceUrl}` : '';
|
|
187
|
+
return {
|
|
188
|
+
kind: 'memory',
|
|
189
|
+
mode: 'create',
|
|
190
|
+
title: 'Create Memory From Note',
|
|
191
|
+
selectedFieldIndex: 0,
|
|
192
|
+
message: `Promote ${note.title} into durable Agent memory. Saving writes memory only; the note remains in the scratchpad.`,
|
|
193
|
+
fields: [
|
|
194
|
+
{ id: 'cls', label: 'Class', value: 'fact', required: true, multiline: false, hint: 'fact, decision, constraint, incident, pattern, risk, runbook, architecture, or ownership.' },
|
|
195
|
+
{ id: 'scope', label: 'Scope', value: 'project', required: true, multiline: false, hint: 'session, project, or team.' },
|
|
196
|
+
{ id: 'summary', label: 'Summary', value: note.title, required: true, multiline: false, hint: 'One durable sentence. Do not store secrets.' },
|
|
197
|
+
{ id: 'detail', label: 'Detail', value: `${note.body}${sourceLine}`, required: false, multiline: true, hint: 'Optional supporting detail. Ctrl-J inserts a new line.' },
|
|
198
|
+
{ id: 'tags', label: 'Tags', value: noteTags(note, 'from-note'), required: false, multiline: false, hint: 'Comma-separated optional tags.' },
|
|
199
|
+
{ id: 'confidence', label: 'Confidence', value: note.reviewState === 'reviewed' ? '85' : '65', required: false, multiline: false, hint: '0-100 confidence score.' },
|
|
200
|
+
],
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export function createPersonaEditorFromNote(note: AgentNoteRecord): AgentWorkspaceLocalEditor {
|
|
205
|
+
return {
|
|
206
|
+
kind: 'persona',
|
|
207
|
+
mode: 'create',
|
|
208
|
+
title: 'Create Persona From Note',
|
|
209
|
+
selectedFieldIndex: 0,
|
|
210
|
+
message: `Use ${note.title} as the starting point for a local persona. Saving creates a persona only; the note remains in the scratchpad.`,
|
|
211
|
+
fields: [
|
|
212
|
+
{ id: 'name', label: 'Name', value: note.title, required: true, multiline: false, hint: 'Short persona name.' },
|
|
213
|
+
{ id: 'description', label: 'Description', value: noteDescription(note), required: true, multiline: false, hint: 'One-line summary of when to use it.' },
|
|
214
|
+
{ id: 'body', label: 'Instructions', value: note.body, required: true, multiline: true, hint: 'Operating guidance. Ctrl-J inserts a new line.' },
|
|
215
|
+
{ id: 'tags', label: 'Tags', value: noteTags(note, 'from-note'), required: false, multiline: false, hint: 'Comma-separated optional tags.' },
|
|
216
|
+
{ id: 'triggers', label: 'Triggers', value: '', required: false, multiline: false, hint: 'Comma-separated words that suggest this persona.' },
|
|
217
|
+
{ id: 'activate', label: 'Activate now', value: 'no', required: false, multiline: false, hint: 'yes/no.' },
|
|
218
|
+
],
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export function createSkillEditorFromNote(note: AgentNoteRecord): AgentWorkspaceLocalEditor {
|
|
223
|
+
return {
|
|
224
|
+
kind: 'skill',
|
|
225
|
+
mode: 'create',
|
|
226
|
+
title: 'Create Skill From Note',
|
|
227
|
+
selectedFieldIndex: 0,
|
|
228
|
+
message: `Use ${note.title} as the starting point for a reusable local skill. Saving creates a skill only; the note remains in the scratchpad.`,
|
|
229
|
+
fields: [
|
|
230
|
+
{ id: 'name', label: 'Name', value: note.title, required: true, multiline: false, hint: 'Short skill name.' },
|
|
231
|
+
{ id: 'description', label: 'Description', value: noteDescription(note), required: true, multiline: false, hint: 'One-line summary of the procedure.' },
|
|
232
|
+
{ id: 'procedure', label: 'Procedure', value: note.body, required: true, multiline: true, hint: 'Reusable steps. Ctrl-J inserts a new line.' },
|
|
233
|
+
{ id: 'triggers', label: 'Triggers', value: '', required: false, multiline: false, hint: 'Comma-separated words that suggest this skill.' },
|
|
234
|
+
{ id: 'tags', label: 'Tags', value: noteTags(note, 'from-note'), required: false, multiline: false, hint: 'Comma-separated optional tags.' },
|
|
235
|
+
{ id: 'requiresEnv', label: 'Required env vars', value: '', required: false, multiline: false, hint: 'Comma-separated env var names. Values are never stored.' },
|
|
236
|
+
{ id: 'requiresCommands', label: 'Required commands', value: '', required: false, multiline: false, hint: 'Comma-separated binaries that must be on PATH.' },
|
|
237
|
+
{ id: 'enabled', label: 'Enable now', value: 'yes', required: false, multiline: false, hint: 'yes/no.' },
|
|
238
|
+
],
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export function createRoutineEditorFromNote(note: AgentNoteRecord): AgentWorkspaceLocalEditor {
|
|
243
|
+
return {
|
|
244
|
+
kind: 'routine',
|
|
245
|
+
mode: 'create',
|
|
246
|
+
title: 'Create Routine From Note',
|
|
247
|
+
selectedFieldIndex: 0,
|
|
248
|
+
message: `Use ${note.title} as the starting point for a repeatable local routine. Saving creates a routine only; the note remains in the scratchpad.`,
|
|
249
|
+
fields: [
|
|
250
|
+
{ id: 'name', label: 'Name', value: note.title, required: true, multiline: false, hint: 'Short routine name.' },
|
|
251
|
+
{ id: 'description', label: 'Description', value: noteDescription(note), required: true, multiline: false, hint: 'One-line summary of the workflow.' },
|
|
252
|
+
{ id: 'steps', label: 'Steps', value: note.body, required: true, multiline: true, hint: 'Workflow steps. Ctrl-J inserts a new line.' },
|
|
253
|
+
{ id: 'triggers', label: 'Triggers', value: '', required: false, multiline: false, hint: 'Comma-separated words that suggest this routine.' },
|
|
254
|
+
{ id: 'tags', label: 'Tags', value: noteTags(note, 'from-note'), required: false, multiline: false, hint: 'Comma-separated optional tags.' },
|
|
255
|
+
{ id: 'requiresEnv', label: 'Required env vars', value: '', required: false, multiline: false, hint: 'Comma-separated env var names. Values are never stored.' },
|
|
256
|
+
{ id: 'requiresCommands', label: 'Required commands', value: '', required: false, multiline: false, hint: 'Comma-separated binaries that must be on PATH.' },
|
|
257
|
+
{ id: 'enabled', label: 'Enable now', value: 'yes', required: false, multiline: false, hint: 'yes/no.' },
|
|
258
|
+
],
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export function createKnowledgeUrlEditorFromNote(note: AgentNoteRecord): AgentWorkspaceLocalEditor {
|
|
263
|
+
return {
|
|
264
|
+
kind: 'knowledge-url',
|
|
265
|
+
mode: 'create',
|
|
266
|
+
title: 'Ingest Note Source Into Agent Knowledge',
|
|
267
|
+
selectedFieldIndex: 3,
|
|
268
|
+
message: `Review the source URL from ${note.title}, then type yes to ingest it into isolated Agent Knowledge. The scratchpad note remains unchanged.`,
|
|
269
|
+
fields: [
|
|
270
|
+
{ id: 'url', label: 'URL', value: note.sourceUrl ?? '', required: true, multiline: false, hint: 'HTTP or HTTPS URL to ingest into Agent Knowledge only.' },
|
|
271
|
+
{ id: 'tags', label: 'Tags', value: noteTags(note, 'from-note'), required: false, multiline: false, hint: 'Comma-separated optional tags. Spaces are not needed.' },
|
|
272
|
+
{ id: 'folder', label: 'Folder', value: 'notes', required: false, multiline: false, hint: 'Optional Agent Knowledge folder path.' },
|
|
273
|
+
{ id: 'confirm', label: 'Confirm', value: '', required: true, multiline: false, hint: 'Type yes to run /knowledge ingest-url with --yes.' },
|
|
274
|
+
],
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export function createNoteUpdateEditor(record: AgentNoteRecord): AgentWorkspaceLocalEditor {
|
|
279
|
+
return {
|
|
280
|
+
kind: 'note',
|
|
281
|
+
mode: 'update',
|
|
282
|
+
recordId: record.id,
|
|
283
|
+
title: 'Edit Note',
|
|
284
|
+
selectedFieldIndex: 0,
|
|
285
|
+
message: `Editing ${record.title}. Saving keeps it in the Agent-local scratchpad only.`,
|
|
286
|
+
fields: [
|
|
287
|
+
{ id: 'title', label: 'Title', value: record.title, required: true, multiline: false, hint: 'Short note title.' },
|
|
288
|
+
{ id: 'body', label: 'Note', value: record.body, required: true, multiline: true, hint: 'Working note, source triage, or temporary decision. Ctrl-J inserts a new line.' },
|
|
289
|
+
{ id: 'sourceUrl', label: 'Source URL', value: record.sourceUrl ?? '', required: false, multiline: false, hint: 'Optional reviewed URL. This does not ingest the URL into Agent Knowledge.' },
|
|
290
|
+
{ id: 'tags', label: 'Tags', value: record.tags.join(', '), required: false, multiline: false, hint: 'Comma-separated optional tags.' },
|
|
291
|
+
],
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
|
|
135
295
|
export function createPersonaUpdateEditor(record: AgentPersonaRecord, active: boolean): AgentWorkspaceLocalEditor {
|
|
136
296
|
return {
|
|
137
297
|
kind: 'persona',
|
|
@@ -165,6 +325,8 @@ export function createSkillUpdateEditor(record: AgentSkillRecord): AgentWorkspac
|
|
|
165
325
|
{ id: 'procedure', label: 'Procedure', value: record.procedure, required: true, multiline: true, hint: 'Reusable steps. Ctrl-J inserts a new line.' },
|
|
166
326
|
{ id: 'triggers', label: 'Triggers', value: record.triggers.join(', '), required: false, multiline: false, hint: 'Comma-separated words that suggest this skill.' },
|
|
167
327
|
{ id: 'tags', label: 'Tags', value: record.tags.join(', '), required: false, multiline: false, hint: 'Comma-separated optional tags.' },
|
|
328
|
+
{ id: 'requiresEnv', label: 'Required env vars', value: record.requirements.filter((requirement) => requirement.kind === 'env').map((requirement) => requirement.name).join(', '), required: false, multiline: false, hint: 'Comma-separated env var names. Values are never stored.' },
|
|
329
|
+
{ id: 'requiresCommands', label: 'Required commands', value: record.requirements.filter((requirement) => requirement.kind === 'command').map((requirement) => requirement.name).join(', '), required: false, multiline: false, hint: 'Comma-separated binaries that must be on PATH.' },
|
|
168
330
|
{ id: 'enabled', label: 'Enabled', value: record.enabled ? 'yes' : 'no', required: false, multiline: false, hint: 'yes/no.' },
|
|
169
331
|
],
|
|
170
332
|
};
|
|
@@ -184,6 +346,8 @@ export function createRoutineUpdateEditor(record: AgentRoutineRecord): AgentWork
|
|
|
184
346
|
{ id: 'steps', label: 'Steps', value: record.steps, required: true, multiline: true, hint: 'Workflow steps. Ctrl-J inserts a new line.' },
|
|
185
347
|
{ id: 'triggers', label: 'Triggers', value: record.triggers.join(', '), required: false, multiline: false, hint: 'Comma-separated words that suggest this routine.' },
|
|
186
348
|
{ id: 'tags', label: 'Tags', value: record.tags.join(', '), required: false, multiline: false, hint: 'Comma-separated optional tags.' },
|
|
349
|
+
{ id: 'requiresEnv', label: 'Required env vars', value: record.requirements.filter((requirement) => requirement.kind === 'env').map((requirement) => requirement.name).join(', '), required: false, multiline: false, hint: 'Comma-separated env var names. Values are never stored.' },
|
|
350
|
+
{ id: 'requiresCommands', label: 'Required commands', value: record.requirements.filter((requirement) => requirement.kind === 'command').map((requirement) => requirement.name).join(', '), required: false, multiline: false, hint: 'Comma-separated binaries that must be on PATH.' },
|
|
187
351
|
{ id: 'enabled', label: 'Enabled', value: record.enabled ? 'yes' : 'no', required: false, multiline: false, hint: 'yes/no.' },
|
|
188
352
|
],
|
|
189
353
|
};
|
|
@@ -215,6 +379,7 @@ export function isAffirmative(value: string): boolean {
|
|
|
215
379
|
|
|
216
380
|
export function editorCategoryId(kind: AgentWorkspaceLocalEditorKind): string {
|
|
217
381
|
if (kind === 'memory') return 'memory';
|
|
382
|
+
if (kind === 'note') return 'notes';
|
|
218
383
|
if (kind === 'profile') return 'profiles';
|
|
219
384
|
if (kind === 'persona') return 'personas';
|
|
220
385
|
if (kind === 'skill') return 'skills';
|