@pellux/goodvibes-agent 0.1.117 → 1.0.1
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 +20 -4
- package/README.md +35 -14
- package/bin/goodvibes-agent.ts +16 -2
- package/dist/package/main.js +176093 -171065
- package/docs/README.md +11 -5
- package/docs/channels-remote-and-api.md +50 -0
- package/docs/connected-host.md +3 -3
- package/docs/getting-started.md +29 -15
- 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 +44 -9
- package/docs/tools-and-commands.md +123 -0
- package/docs/voice-and-live-tts.md +51 -0
- package/package.json +2 -5
- 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-registry.ts +15 -14
- package/src/agent/record-labels.ts +107 -0
- package/src/agent/reminder-schedule-format.ts +33 -24
- package/src/agent/reminder-schedule.ts +26 -25
- package/src/agent/routine-registry.ts +13 -12
- 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 +34 -32
- package/src/agent/routine-schedule-receipts.ts +28 -26
- package/src/agent/runtime-profile-starters.ts +2 -2
- package/src/agent/runtime-profile.ts +18 -17
- package/src/agent/skill-registry.ts +25 -24
- package/src/cli/agent-knowledge-args.ts +5 -1
- package/src/cli/agent-knowledge-command.ts +39 -33
- 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 +13 -8
- package/src/cli/config-overrides.ts +37 -36
- package/src/cli/external-runtime.ts +10 -4
- package/src/cli/help.ts +29 -11
- package/src/cli/local-library-command.ts +159 -73
- package/src/cli/management-commands.ts +98 -62
- package/src/cli/management.ts +52 -26
- package/src/cli/memory-command.ts +66 -32
- package/src/cli/parser.ts +37 -24
- package/src/cli/profiles-command.ts +52 -35
- package/src/cli/provider-auth-routes.ts +2 -1
- package/src/cli/routines-command.ts +59 -39
- package/src/cli/service-posture.ts +6 -6
- package/src/cli/status.ts +46 -121
- package/src/core/conversation-message-snapshot.ts +131 -0
- package/src/input/agent-workspace-activation.ts +33 -7
- package/src/input/agent-workspace-basic-command-editor-submission.ts +7 -3
- package/src/input/agent-workspace-basic-command-editors.ts +30 -10
- package/src/input/agent-workspace-categories.ts +276 -64
- package/src/input/agent-workspace-channel-command-editor-submission.ts +34 -0
- package/src/input/agent-workspace-channel-command-editors.ts +23 -5
- package/src/input/agent-workspace-channels.ts +35 -2
- package/src/input/agent-workspace-command-editor.ts +18 -2
- package/src/input/agent-workspace-config-reader.ts +16 -0
- package/src/input/agent-workspace-delegation-editor-submission.ts +1 -1
- package/src/input/agent-workspace-editors.ts +140 -2
- package/src/input/agent-workspace-knowledge-query-editor.ts +1 -1
- package/src/input/agent-workspace-knowledge-url-editor.ts +4 -11
- package/src/input/agent-workspace-learned-behavior.ts +2 -2
- package/src/input/agent-workspace-library-command-editor-submission.ts +1 -1
- package/src/input/agent-workspace-library-command-editors.ts +2 -2
- 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-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-editors.ts +1 -1
- package/src/input/agent-workspace-memory-editor.ts +2 -2
- package/src/input/agent-workspace-navigation.ts +38 -2
- package/src/input/agent-workspace-notify-editor-submission.ts +16 -2
- package/src/input/agent-workspace-operations-command-editor-submission.ts +63 -1
- package/src/input/agent-workspace-operations-command-editors.ts +80 -3
- package/src/input/agent-workspace-panel-route.ts +43 -0
- package/src/input/agent-workspace-reminder-schedule-editor.ts +1 -1
- 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-setup.ts +22 -11
- package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +6 -6
- package/src/input/agent-workspace-skill-bundle-command-editors.ts +10 -10
- package/src/input/agent-workspace-snapshot.ts +112 -13
- package/src/input/agent-workspace-task-command-editors.ts +4 -4
- package/src/input/agent-workspace-token.ts +18 -2
- package/src/input/agent-workspace-types.ts +92 -4
- package/src/input/agent-workspace-voice-media.ts +3 -6
- package/src/input/agent-workspace-web-research-editor.ts +104 -0
- package/src/input/agent-workspace.ts +136 -208
- package/src/input/command-registry.ts +4 -1
- package/src/input/commands/agent-local-library-args.ts +52 -0
- package/src/input/commands/agent-runtime-profile-runtime.ts +45 -41
- package/src/input/commands/agent-skills-runtime.ts +87 -99
- package/src/input/commands/agent-workspace-runtime.ts +23 -7
- package/src/input/commands/brief-runtime.ts +25 -24
- package/src/input/commands/channels-runtime.ts +145 -31
- 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 +140 -115
- package/src/input/commands/knowledge.ts +57 -56
- package/src/input/commands/local-provider-runtime.ts +36 -18
- package/src/input/commands/local-runtime.ts +138 -16
- package/src/input/commands/local-setup-review.ts +7 -7
- package/src/input/commands/mcp-runtime.ts +118 -50
- 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 -17
- package/src/input/commands/personas-runtime.ts +49 -59
- package/src/input/commands/planning-runtime.ts +1 -1
- package/src/input/commands/platform-access-runtime.ts +29 -29
- package/src/input/commands/provider-accounts-runtime.ts +60 -39
- package/src/input/commands/qrcode-runtime.ts +45 -6
- 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 +63 -72
- package/src/input/commands/schedule-runtime.ts +33 -20
- package/src/input/commands/security-runtime.ts +4 -4
- package/src/input/commands/session-content.ts +80 -78
- package/src/input/commands/session-workflow.ts +132 -93
- package/src/input/commands/session.ts +3 -174
- package/src/input/commands/shell-core.ts +32 -17
- package/src/input/commands/subscription-runtime.ts +53 -179
- package/src/input/commands/tasks-runtime.ts +20 -20
- package/src/input/commands/work-plan-runtime.ts +33 -8
- package/src/input/commands.ts +2 -2
- package/src/input/feed-context-factory.ts +2 -1
- 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 -1
- package/src/input/handler-feed-routes.ts +19 -12
- package/src/input/handler-feed.ts +6 -3
- package/src/input/handler-interactions.ts +7 -5
- package/src/input/handler-modal-stack.ts +3 -3
- package/src/input/handler-onboarding.ts +24 -80
- package/src/input/handler-shortcuts.ts +15 -4
- package/src/input/handler.ts +47 -17
- package/src/input/input-history.ts +5 -6
- package/src/input/keybindings.ts +22 -11
- package/src/input/onboarding/onboarding-wizard-apply.ts +13 -0
- package/src/input/onboarding/onboarding-wizard-constants.ts +1 -0
- package/src/input/onboarding/onboarding-wizard-operator-steps.ts +147 -57
- package/src/input/onboarding/onboarding-wizard-steps.ts +46 -29
- package/src/input/onboarding/onboarding-wizard-types.ts +3 -1
- package/src/input/onboarding/onboarding-wizard.ts +68 -0
- package/src/input/profile-picker-modal.ts +31 -12
- package/src/input/session-picker-modal.ts +22 -4
- 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 +6 -52
- package/src/input/submission-intent.ts +0 -1
- package/src/input/submission-router.ts +3 -3
- package/src/main.ts +18 -8
- package/src/panels/approval-panel.ts +8 -8
- package/src/panels/automation-control-panel.ts +2 -2
- package/src/panels/base-panel.ts +1 -1
- package/src/panels/builtin/agent.ts +1 -1
- package/src/panels/builtin/operations.ts +1 -10
- package/src/panels/builtin/session.ts +9 -9
- package/src/panels/builtin/shared.ts +2 -2
- 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 +18 -11
- 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 +45 -4
- package/src/panels/provider-health-panel.ts +5 -4
- package/src/panels/qr-panel.ts +1 -1
- 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 +3 -3
- package/src/panels/system-messages-panel.ts +1 -1
- package/src/panels/tasks-panel.ts +20 -13
- 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 +1 -1
- package/src/provider-auth-route-display.ts +9 -0
- package/src/renderer/agent-workspace-style.ts +34 -0
- package/src/renderer/agent-workspace.ts +228 -52
- package/src/renderer/autocomplete-overlay.ts +25 -6
- 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 +106 -33
- package/src/renderer/history-search-overlay.ts +19 -4
- package/src/renderer/live-tail-modal.ts +27 -5
- package/src/renderer/mcp-workspace.ts +164 -50
- package/src/renderer/model-picker-overlay.ts +58 -2
- package/src/renderer/model-workspace.ts +104 -20
- package/src/renderer/process-modal.ts +27 -6
- package/src/renderer/profile-picker-modal.ts +20 -4
- 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 +83 -50
- package/src/renderer/tool-call.ts +20 -11
- package/src/runtime/agent-runtime-events.ts +6 -6
- package/src/runtime/bootstrap-command-context.ts +7 -1
- package/src/runtime/bootstrap-command-parts.ts +9 -7
- package/src/runtime/bootstrap-core.ts +19 -1
- package/src/runtime/bootstrap-hook-bridge.ts +7 -18
- package/src/runtime/bootstrap-shell.ts +4 -4
- package/src/runtime/bootstrap.ts +31 -22
- package/src/runtime/connected-host-auth.ts +7 -2
- package/src/runtime/diagnostics/panels/index.ts +2 -2
- package/src/runtime/diagnostics/panels/policy.ts +7 -7
- package/src/runtime/index.ts +2 -1
- package/src/runtime/onboarding/apply-file-helpers.ts +66 -0
- package/src/runtime/onboarding/apply.ts +80 -79
- package/src/runtime/onboarding/derivation.ts +5 -8
- package/src/runtime/onboarding/snapshot.ts +0 -15
- package/src/runtime/onboarding/types.ts +8 -19
- package/src/runtime/onboarding/verify.ts +32 -10
- package/src/runtime/operator-token-cleanup.ts +1 -1
- package/src/runtime/services.ts +91 -22
- 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/ui-openers.ts +3 -13
- 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 +269 -69
- 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 +8 -8
- package/src/tools/agent-work-plan-tool.ts +256 -0
- package/src/version.ts +1 -1
- package/src/input/commands/policy-dispatch.ts +0 -339
- package/src/input/commands/policy.ts +0 -13
- 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
|
@@ -8,39 +8,15 @@ import {
|
|
|
8
8
|
type AgentSkillRecord,
|
|
9
9
|
} from '../../agent/skill-registry.ts';
|
|
10
10
|
import { discoverSkills, type SkillRecord } from '../../agent/skill-discovery.ts';
|
|
11
|
+
import { formatAgentRecordOrigin, formatAgentRecordReviewState } from '../../agent/record-labels.ts';
|
|
11
12
|
import type { CommandContext, CommandRegistry } from '../command-registry.ts';
|
|
13
|
+
import { parseAgentLocalLibraryArgs, type ParsedAgentLocalLibraryArgs } from './agent-local-library-args.ts';
|
|
12
14
|
import { requireShellPaths } from './runtime-services.ts';
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
readonly rest: readonly string[];
|
|
16
|
-
readonly flags: ReadonlyMap<string, string>;
|
|
17
|
-
readonly yes: boolean;
|
|
18
|
-
}
|
|
16
|
+
const SKILL_VALUE_FLAGS = ['name', 'description', 'procedure', 'tags', 'triggers', 'requires-env', 'requires-command', 'requires-commands', 'skills'] as const;
|
|
19
17
|
|
|
20
|
-
function parseSkillArgs(args: readonly string[]):
|
|
21
|
-
|
|
22
|
-
const rest: string[] = [];
|
|
23
|
-
let yes = false;
|
|
24
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
25
|
-
const token = args[index] ?? '';
|
|
26
|
-
if (token === '--yes') {
|
|
27
|
-
yes = true;
|
|
28
|
-
continue;
|
|
29
|
-
}
|
|
30
|
-
if (token.startsWith('--')) {
|
|
31
|
-
const key = token.slice(2);
|
|
32
|
-
const next = args[index + 1];
|
|
33
|
-
if (next !== undefined && !next.startsWith('--')) {
|
|
34
|
-
flags.set(key, next);
|
|
35
|
-
index += 1;
|
|
36
|
-
} else {
|
|
37
|
-
flags.set(key, 'true');
|
|
38
|
-
}
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
rest.push(token);
|
|
42
|
-
}
|
|
43
|
-
return { rest, flags, yes };
|
|
18
|
+
function parseSkillArgs(args: readonly string[]): ParsedAgentLocalLibraryArgs {
|
|
19
|
+
return parseAgentLocalLibraryArgs(args, { valueFlags: SKILL_VALUE_FLAGS });
|
|
44
20
|
}
|
|
45
21
|
|
|
46
22
|
function splitList(value: string | undefined): readonly string[] {
|
|
@@ -58,23 +34,34 @@ function requiredFlag(flags: ReadonlyMap<string, string>, key: string): string {
|
|
|
58
34
|
return value;
|
|
59
35
|
}
|
|
60
36
|
|
|
37
|
+
function formatSkillReceipt(title: string, record: { readonly id: string; readonly name: string }, extra: readonly string[] = []): string {
|
|
38
|
+
return [
|
|
39
|
+
`${title} ${record.id}`,
|
|
40
|
+
` id ${record.id}`,
|
|
41
|
+
` name ${record.name}`,
|
|
42
|
+
...extra,
|
|
43
|
+
].join('\n');
|
|
44
|
+
}
|
|
45
|
+
|
|
61
46
|
function summarizeSkill(skill: AgentSkillRecord): string {
|
|
62
47
|
const enabled = skill.enabled ? 'enabled' : 'disabled';
|
|
63
|
-
const tags = skill.tags.length > 0 ? ` tags
|
|
48
|
+
const tags = skill.tags.length > 0 ? ` tags ${skill.tags.join(', ')}` : '';
|
|
64
49
|
const readiness = evaluateAgentSkillReadiness(skill);
|
|
50
|
+
const review = formatAgentRecordReviewState(skill.reviewState);
|
|
65
51
|
const ready = readiness.ready ? 'ready' : `needs ${readiness.missing.map(formatAgentSkillRequirement).join(',')}`;
|
|
66
|
-
return ` ${skill.id} ${enabled} ${
|
|
52
|
+
return ` ${skill.id} ${enabled} ${review} ${ready} ${skill.name} - ${skill.description}${tags}`;
|
|
67
53
|
}
|
|
68
54
|
|
|
69
55
|
function summarizeBundle(bundle: AgentSkillBundleRecord, skills: readonly AgentSkillRecord[]): string {
|
|
70
56
|
const enabled = bundle.enabled ? 'enabled' : 'disabled';
|
|
71
57
|
const readiness = evaluateAgentSkillBundleReadiness(bundle, skills);
|
|
58
|
+
const review = formatAgentRecordReviewState(bundle.reviewState);
|
|
72
59
|
const missing = [
|
|
73
60
|
...readiness.missingRequirements.map(formatAgentSkillRequirement),
|
|
74
|
-
...readiness.missingSkillIds.map((skillId) => `skill
|
|
61
|
+
...readiness.missingSkillIds.map((skillId) => `skill ${skillId}`),
|
|
75
62
|
];
|
|
76
63
|
const ready = readiness.ready ? 'ready' : `needs ${missing.join(',')}`;
|
|
77
|
-
return ` ${bundle.id} ${enabled} ${
|
|
64
|
+
return ` ${bundle.id} ${enabled} ${review} ${ready} ${bundle.name} - ${bundle.description} skills ${bundle.skillIds.join(', ')}`;
|
|
78
65
|
}
|
|
79
66
|
|
|
80
67
|
function renderList(title: string, registry: AgentSkillRegistry, skills: readonly AgentSkillRecord[], emptyMessage?: string): string {
|
|
@@ -82,21 +69,21 @@ function renderList(title: string, registry: AgentSkillRegistry, skills: readonl
|
|
|
82
69
|
if (skills.length === 0) {
|
|
83
70
|
return emptyMessage
|
|
84
71
|
? `${title}\n ${emptyMessage}`
|
|
85
|
-
: `${title}\n No local
|
|
72
|
+
: `${title}\n No Agent-local skills yet. Create one with /skills create --name <name> --description <summary> --procedure <steps>.`;
|
|
86
73
|
}
|
|
87
74
|
return [
|
|
88
75
|
`${title} (${skills.length})`,
|
|
89
|
-
` store
|
|
90
|
-
` enabled
|
|
76
|
+
` store ${snapshot.path}`,
|
|
77
|
+
` enabled ${snapshot.enabledSkills.length}`,
|
|
91
78
|
...skills.map(summarizeSkill),
|
|
92
79
|
].join('\n');
|
|
93
80
|
}
|
|
94
81
|
|
|
95
82
|
function summarizeDiscoveredSkill(skill: SkillRecord): string {
|
|
96
83
|
const description = skill.description ? ` - ${skill.description}` : '';
|
|
97
|
-
const dependencies = skill.dependencies.length > 0 ? ` deps
|
|
98
|
-
const includes = skill.includes.length > 0 ? ` includes
|
|
99
|
-
return ` ${skill.name} ${skill.origin}${description}${dependencies}${includes}\n path
|
|
84
|
+
const dependencies = skill.dependencies.length > 0 ? ` deps ${skill.dependencies.join(', ')}` : '';
|
|
85
|
+
const includes = skill.includes.length > 0 ? ` includes ${skill.includes.join(', ')}` : '';
|
|
86
|
+
return ` ${skill.name} ${skill.origin}${description}${dependencies}${includes}\n path ${skill.path}`;
|
|
100
87
|
}
|
|
101
88
|
|
|
102
89
|
function renderDiscoveredSkills(skills: readonly SkillRecord[]): string {
|
|
@@ -111,7 +98,7 @@ function renderDiscoveredSkills(skills: readonly SkillRecord[]): string {
|
|
|
111
98
|
`Discovered Agent skill files (${skills.length})`,
|
|
112
99
|
...skills.map(summarizeDiscoveredSkill),
|
|
113
100
|
'',
|
|
114
|
-
'Import one with: /
|
|
101
|
+
'Import one with: /skills import-discovered <name> --yes',
|
|
115
102
|
].join('\n');
|
|
116
103
|
}
|
|
117
104
|
|
|
@@ -150,23 +137,23 @@ async function importDiscoveredSkill(args: readonly string[], ctx: CommandContex
|
|
|
150
137
|
const parsed = parseSkillArgs(args);
|
|
151
138
|
const name = parsed.rest.join(' ').trim();
|
|
152
139
|
if (!name) {
|
|
153
|
-
ctx.print('Usage: /
|
|
140
|
+
ctx.print('Usage: /skills import-discovered <name> [--enabled] --yes');
|
|
154
141
|
return;
|
|
155
142
|
}
|
|
156
143
|
const discovered = findDiscoveredSkill(await discoverSkills(requireShellPaths(ctx)), name);
|
|
157
144
|
if (!discovered) {
|
|
158
|
-
ctx.print(`Unknown discovered Agent skill
|
|
145
|
+
ctx.print(`Unknown discovered Agent skill ${name}\nRun /skills discover to inspect available skill files.`);
|
|
159
146
|
return;
|
|
160
147
|
}
|
|
161
148
|
if (!parsed.yes) {
|
|
162
149
|
ctx.print([
|
|
163
150
|
'Agent skill import preview',
|
|
164
|
-
` name
|
|
165
|
-
` origin
|
|
166
|
-
` path
|
|
167
|
-
` description
|
|
168
|
-
` procedure characters
|
|
169
|
-
' next
|
|
151
|
+
` name ${discovered.name}`,
|
|
152
|
+
` origin ${discovered.origin}`,
|
|
153
|
+
` path ${discovered.path}`,
|
|
154
|
+
` description ${discovered.description || '(none)'}`,
|
|
155
|
+
` procedure characters ${discovered.body.length}`,
|
|
156
|
+
' next rerun with --yes to import into the Agent-local skill registry',
|
|
170
157
|
].join('\n'));
|
|
171
158
|
return;
|
|
172
159
|
}
|
|
@@ -182,9 +169,9 @@ async function importDiscoveredSkill(args: readonly string[], ctx: CommandContex
|
|
|
182
169
|
}),
|
|
183
170
|
enabled: parsed.flags.get('enabled') === 'true',
|
|
184
171
|
source: 'imported',
|
|
185
|
-
provenance: `
|
|
172
|
+
provenance: `Imported file (${discovered.origin}): ${discovered.path}`,
|
|
186
173
|
});
|
|
187
|
-
ctx.print(
|
|
174
|
+
ctx.print(formatSkillReceipt('Imported Agent skill', skill, [` enabled ${skill.enabled ? 'yes' : 'no'}`]));
|
|
188
175
|
}
|
|
189
176
|
|
|
190
177
|
function renderBundleList(title: string, registry: AgentSkillRegistry, bundles: readonly AgentSkillBundleRecord[], emptyMessage?: string): string {
|
|
@@ -192,11 +179,11 @@ function renderBundleList(title: string, registry: AgentSkillRegistry, bundles:
|
|
|
192
179
|
if (bundles.length === 0) {
|
|
193
180
|
return emptyMessage
|
|
194
181
|
? `${title}\n ${emptyMessage}`
|
|
195
|
-
: `${title}\n No local
|
|
182
|
+
: `${title}\n No Agent-local skill bundles yet. Create one with /skills bundle create --name <name> --description <summary> --skills <id,id>.`;
|
|
196
183
|
}
|
|
197
184
|
return [
|
|
198
185
|
`${title} (${bundles.length})`,
|
|
199
|
-
` store
|
|
186
|
+
` store ${snapshot.path}`,
|
|
200
187
|
` enabled bundles: ${snapshot.enabledBundles.length}`,
|
|
201
188
|
` active skills: ${snapshot.activeSkills.length}`,
|
|
202
189
|
...bundles.map((bundle) => summarizeBundle(bundle, snapshot.skills)),
|
|
@@ -207,14 +194,13 @@ function renderSkill(skill: AgentSkillRecord): string {
|
|
|
207
194
|
const readiness = evaluateAgentSkillReadiness(skill);
|
|
208
195
|
return [
|
|
209
196
|
`Skill ${skill.name}`,
|
|
210
|
-
` id
|
|
197
|
+
` id ${skill.id}`,
|
|
211
198
|
` enabled: ${skill.enabled ? 'yes' : 'no'}`,
|
|
212
199
|
` readiness: ${readiness.ready ? 'ready' : 'needs setup'}`,
|
|
213
200
|
` requirements: ${skill.requirements.map(formatAgentSkillRequirement).join(', ') || '(none)'}`,
|
|
214
201
|
readiness.missing.length > 0 ? ` missing: ${readiness.missing.map(formatAgentSkillRequirement).join(', ')}` : '',
|
|
215
|
-
` review: ${skill.reviewState}`,
|
|
216
|
-
`
|
|
217
|
-
` provenance: ${skill.provenance}`,
|
|
202
|
+
` review: ${formatAgentRecordReviewState(skill.reviewState)}`,
|
|
203
|
+
` origin: ${formatAgentRecordOrigin(skill.source, skill.provenance)}`,
|
|
218
204
|
` tags: ${skill.tags.join(', ') || '(none)'}`,
|
|
219
205
|
` triggers: ${skill.triggers.join(', ') || '(manual)'}`,
|
|
220
206
|
` created: ${skill.createdAt}`,
|
|
@@ -234,17 +220,16 @@ function renderBundle(bundle: AgentSkillBundleRecord, registry: AgentSkillRegist
|
|
|
234
220
|
const readiness = evaluateAgentSkillBundleReadiness(bundle, registry.snapshot().skills);
|
|
235
221
|
const missing = [
|
|
236
222
|
...readiness.missingRequirements.map(formatAgentSkillRequirement),
|
|
237
|
-
...readiness.missingSkillIds.map((skillId) => `skill
|
|
223
|
+
...readiness.missingSkillIds.map((skillId) => `skill ${skillId}`),
|
|
238
224
|
];
|
|
239
225
|
return [
|
|
240
226
|
`Skill Bundle ${bundle.name}`,
|
|
241
|
-
` id
|
|
227
|
+
` id ${bundle.id}`,
|
|
242
228
|
` enabled: ${bundle.enabled ? 'yes' : 'no'}`,
|
|
243
229
|
` readiness: ${readiness.ready ? 'ready' : 'needs setup'}`,
|
|
244
230
|
missing.length > 0 ? ` missing: ${missing.join(', ')}` : '',
|
|
245
|
-
` review: ${bundle.reviewState}`,
|
|
246
|
-
`
|
|
247
|
-
` provenance: ${bundle.provenance}`,
|
|
231
|
+
` review: ${formatAgentRecordReviewState(bundle.reviewState)}`,
|
|
232
|
+
` origin: ${formatAgentRecordOrigin(bundle.source, bundle.provenance)}`,
|
|
248
233
|
` skills: ${bundle.skillIds.join(', ')}`,
|
|
249
234
|
` created: ${bundle.createdAt}`,
|
|
250
235
|
` updated: ${bundle.updatedAt}`,
|
|
@@ -257,7 +242,10 @@ function renderBundle(bundle: AgentSkillBundleRecord, registry: AgentSkillRegist
|
|
|
257
242
|
}
|
|
258
243
|
|
|
259
244
|
function printError(ctx: CommandContext, error: unknown): void {
|
|
260
|
-
ctx.print(
|
|
245
|
+
ctx.print([
|
|
246
|
+
'Error',
|
|
247
|
+
` message ${error instanceof Error ? error.message : String(error)}`,
|
|
248
|
+
].join('\n'));
|
|
261
249
|
}
|
|
262
250
|
|
|
263
251
|
function runBundleCommand(args: readonly string[], ctx: CommandContext, skillRegistry: AgentSkillRegistry): void {
|
|
@@ -274,7 +262,7 @@ function runBundleCommand(args: readonly string[], ctx: CommandContext, skillReg
|
|
|
274
262
|
if (sub === 'attention' || sub === 'needs-setup') {
|
|
275
263
|
const snapshot = skillRegistry.snapshot();
|
|
276
264
|
const bundles = snapshot.bundles.filter((bundle) => !evaluateAgentSkillBundleReadiness(bundle, snapshot.skills).ready);
|
|
277
|
-
ctx.print(renderBundleList('Agent Skill Bundles needing setup', skillRegistry, bundles, 'No local
|
|
265
|
+
ctx.print(renderBundleList('Agent Skill Bundles needing setup', skillRegistry, bundles, 'No Agent-local skill bundles need setup.'));
|
|
278
266
|
return;
|
|
279
267
|
}
|
|
280
268
|
if (sub === 'search') {
|
|
@@ -285,11 +273,11 @@ function runBundleCommand(args: readonly string[], ctx: CommandContext, skillReg
|
|
|
285
273
|
if (sub === 'show') {
|
|
286
274
|
const id = args[1];
|
|
287
275
|
if (!id) {
|
|
288
|
-
ctx.print('Usage: /
|
|
276
|
+
ctx.print('Usage: /skills bundle show <id>');
|
|
289
277
|
return;
|
|
290
278
|
}
|
|
291
279
|
const bundle = skillRegistry.getBundle(id);
|
|
292
|
-
ctx.print(bundle ? renderBundle(bundle, skillRegistry) : `Unknown Agent skill bundle
|
|
280
|
+
ctx.print(bundle ? renderBundle(bundle, skillRegistry) : `Unknown Agent skill bundle ${id}`);
|
|
293
281
|
return;
|
|
294
282
|
}
|
|
295
283
|
if (sub === 'create') {
|
|
@@ -300,15 +288,15 @@ function runBundleCommand(args: readonly string[], ctx: CommandContext, skillReg
|
|
|
300
288
|
skillIds: splitList(requiredFlag(parsed.flags, 'skills')),
|
|
301
289
|
enabled: parsed.flags.get('enabled') === 'true',
|
|
302
290
|
source: 'user',
|
|
303
|
-
provenance: '
|
|
291
|
+
provenance: 'Command',
|
|
304
292
|
});
|
|
305
|
-
ctx.print(
|
|
293
|
+
ctx.print(formatSkillReceipt('Created Agent skill bundle', bundle));
|
|
306
294
|
return;
|
|
307
295
|
}
|
|
308
296
|
if (sub === 'update') {
|
|
309
297
|
const id = args[1];
|
|
310
298
|
if (!id) {
|
|
311
|
-
ctx.print('Usage: /
|
|
299
|
+
ctx.print('Usage: /skills bundle update <id> [--name ...] [--description ...] [--skills id,id]');
|
|
312
300
|
return;
|
|
313
301
|
}
|
|
314
302
|
const parsed = parseSkillArgs(args.slice(2));
|
|
@@ -316,46 +304,46 @@ function runBundleCommand(args: readonly string[], ctx: CommandContext, skillReg
|
|
|
316
304
|
name: parsed.flags.get('name'),
|
|
317
305
|
description: parsed.flags.get('description'),
|
|
318
306
|
skillIds: parsed.flags.has('skills') ? splitList(parsed.flags.get('skills')) : undefined,
|
|
319
|
-
provenance: '
|
|
307
|
+
provenance: 'Command',
|
|
320
308
|
});
|
|
321
|
-
ctx.print(
|
|
309
|
+
ctx.print(formatSkillReceipt('Updated Agent skill bundle', updated));
|
|
322
310
|
return;
|
|
323
311
|
}
|
|
324
312
|
if (sub === 'enable' || sub === 'disable') {
|
|
325
313
|
const id = args[1];
|
|
326
314
|
if (!id) {
|
|
327
|
-
ctx.print(`Usage: /
|
|
315
|
+
ctx.print(`Usage: /skills bundle ${sub} <id>`);
|
|
328
316
|
return;
|
|
329
317
|
}
|
|
330
318
|
const bundle = skillRegistry.setBundleEnabled(id, sub === 'enable');
|
|
331
|
-
ctx.print(`${sub === 'enable' ? 'Enabled' : 'Disabled'} Agent skill bundle
|
|
319
|
+
ctx.print(formatSkillReceipt(`${sub === 'enable' ? 'Enabled' : 'Disabled'} Agent skill bundle`, bundle));
|
|
332
320
|
return;
|
|
333
321
|
}
|
|
334
322
|
if (sub === 'review') {
|
|
335
323
|
const id = args[1];
|
|
336
324
|
if (!id) {
|
|
337
|
-
ctx.print('Usage: /
|
|
325
|
+
ctx.print('Usage: /skills bundle review <id>');
|
|
338
326
|
return;
|
|
339
327
|
}
|
|
340
328
|
const bundle = skillRegistry.markBundleReviewed(id);
|
|
341
|
-
ctx.print(
|
|
329
|
+
ctx.print(formatSkillReceipt('Reviewed Agent skill bundle', bundle));
|
|
342
330
|
return;
|
|
343
331
|
}
|
|
344
332
|
if (sub === 'stale') {
|
|
345
333
|
const id = args[1];
|
|
346
334
|
if (!id) {
|
|
347
|
-
ctx.print('Usage: /
|
|
335
|
+
ctx.print('Usage: /skills bundle stale <id> <reason...>');
|
|
348
336
|
return;
|
|
349
337
|
}
|
|
350
338
|
const bundle = skillRegistry.markBundleStale(id, args.slice(2).join(' '));
|
|
351
|
-
ctx.print(
|
|
339
|
+
ctx.print(formatSkillReceipt('Marked Agent skill bundle stale', bundle));
|
|
352
340
|
return;
|
|
353
341
|
}
|
|
354
342
|
if (sub === 'delete' || sub === 'remove') {
|
|
355
343
|
const parsed = parseSkillArgs(args.slice(1));
|
|
356
344
|
const id = parsed.rest[0];
|
|
357
345
|
if (!id) {
|
|
358
|
-
ctx.print('Usage: /
|
|
346
|
+
ctx.print('Usage: /skills bundle delete <id> --yes');
|
|
359
347
|
return;
|
|
360
348
|
}
|
|
361
349
|
if (!parsed.yes) {
|
|
@@ -363,10 +351,10 @@ function runBundleCommand(args: readonly string[], ctx: CommandContext, skillReg
|
|
|
363
351
|
return;
|
|
364
352
|
}
|
|
365
353
|
const removed = skillRegistry.deleteBundle(id);
|
|
366
|
-
ctx.print(
|
|
354
|
+
ctx.print(formatSkillReceipt('Deleted Agent skill bundle', removed));
|
|
367
355
|
return;
|
|
368
356
|
}
|
|
369
|
-
ctx.print('Usage: /
|
|
357
|
+
ctx.print('Usage: /skills bundle [list|enabled|attention|search|show|create|update|enable|disable|review|stale|delete]');
|
|
370
358
|
}
|
|
371
359
|
|
|
372
360
|
export async function runAgentSkillsRuntimeCommand(args: readonly string[], ctx: CommandContext): Promise<void> {
|
|
@@ -400,7 +388,7 @@ export async function runAgentSkillsRuntimeCommand(args: readonly string[], ctx:
|
|
|
400
388
|
}
|
|
401
389
|
if (sub === 'attention' || sub === 'needs-setup') {
|
|
402
390
|
const skills = skillRegistry.list().filter((skill) => !evaluateAgentSkillReadiness(skill).ready);
|
|
403
|
-
ctx.print(renderList('Agent Skills needing setup', skillRegistry, skills, 'No local
|
|
391
|
+
ctx.print(renderList('Agent Skills needing setup', skillRegistry, skills, 'No Agent-local skills need setup.'));
|
|
404
392
|
return;
|
|
405
393
|
}
|
|
406
394
|
if (sub === 'search') {
|
|
@@ -411,11 +399,11 @@ export async function runAgentSkillsRuntimeCommand(args: readonly string[], ctx:
|
|
|
411
399
|
if (sub === 'show') {
|
|
412
400
|
const id = args[1];
|
|
413
401
|
if (!id) {
|
|
414
|
-
ctx.print('Usage: /
|
|
402
|
+
ctx.print('Usage: /skills show <id>');
|
|
415
403
|
return;
|
|
416
404
|
}
|
|
417
405
|
const skill = skillRegistry.get(id);
|
|
418
|
-
ctx.print(skill ? renderSkill(skill) : `Unknown Agent skill
|
|
406
|
+
ctx.print(skill ? renderSkill(skill) : `Unknown Agent skill ${id}`);
|
|
419
407
|
return;
|
|
420
408
|
}
|
|
421
409
|
if (sub === 'create') {
|
|
@@ -433,15 +421,15 @@ export async function runAgentSkillsRuntimeCommand(args: readonly string[], ctx:
|
|
|
433
421
|
}),
|
|
434
422
|
enabled: parsed.flags.get('enabled') === 'true',
|
|
435
423
|
source: 'user',
|
|
436
|
-
provenance: '
|
|
424
|
+
provenance: 'Command',
|
|
437
425
|
});
|
|
438
|
-
ctx.print(
|
|
426
|
+
ctx.print(formatSkillReceipt('Created Agent skill', skill));
|
|
439
427
|
return;
|
|
440
428
|
}
|
|
441
429
|
if (sub === 'update') {
|
|
442
430
|
const id = args[1];
|
|
443
431
|
if (!id) {
|
|
444
|
-
ctx.print('Usage: /
|
|
432
|
+
ctx.print('Usage: /skills update <id> [--name ...] [--description ...] [--procedure ...]');
|
|
445
433
|
return;
|
|
446
434
|
}
|
|
447
435
|
const parsed = parseSkillArgs(args.slice(2));
|
|
@@ -457,46 +445,46 @@ export async function runAgentSkillsRuntimeCommand(args: readonly string[], ctx:
|
|
|
457
445
|
commands: splitList(parsed.flags.get('requires-command') ?? parsed.flags.get('requires-commands')),
|
|
458
446
|
})
|
|
459
447
|
: undefined,
|
|
460
|
-
provenance: '
|
|
448
|
+
provenance: 'Command',
|
|
461
449
|
});
|
|
462
|
-
ctx.print(
|
|
450
|
+
ctx.print(formatSkillReceipt('Updated Agent skill', updated));
|
|
463
451
|
return;
|
|
464
452
|
}
|
|
465
453
|
if (sub === 'enable' || sub === 'disable') {
|
|
466
454
|
const id = args[1];
|
|
467
455
|
if (!id) {
|
|
468
|
-
ctx.print(`Usage: /
|
|
456
|
+
ctx.print(`Usage: /skills ${sub} <id>`);
|
|
469
457
|
return;
|
|
470
458
|
}
|
|
471
459
|
const skill = skillRegistry.setEnabled(id, sub === 'enable');
|
|
472
|
-
ctx.print(`${sub === 'enable' ? 'Enabled' : 'Disabled'} Agent skill
|
|
460
|
+
ctx.print(formatSkillReceipt(`${sub === 'enable' ? 'Enabled' : 'Disabled'} Agent skill`, skill));
|
|
473
461
|
return;
|
|
474
462
|
}
|
|
475
463
|
if (sub === 'review') {
|
|
476
464
|
const id = args[1];
|
|
477
465
|
if (!id) {
|
|
478
|
-
ctx.print('Usage: /
|
|
466
|
+
ctx.print('Usage: /skills review <id>');
|
|
479
467
|
return;
|
|
480
468
|
}
|
|
481
469
|
const skill = skillRegistry.markReviewed(id);
|
|
482
|
-
ctx.print(
|
|
470
|
+
ctx.print(formatSkillReceipt('Reviewed Agent skill', skill));
|
|
483
471
|
return;
|
|
484
472
|
}
|
|
485
473
|
if (sub === 'stale') {
|
|
486
474
|
const id = args[1];
|
|
487
475
|
if (!id) {
|
|
488
|
-
ctx.print('Usage: /
|
|
476
|
+
ctx.print('Usage: /skills stale <id> <reason...>');
|
|
489
477
|
return;
|
|
490
478
|
}
|
|
491
479
|
const skill = skillRegistry.markStale(id, args.slice(2).join(' '));
|
|
492
|
-
ctx.print(
|
|
480
|
+
ctx.print(formatSkillReceipt('Marked Agent skill stale', skill));
|
|
493
481
|
return;
|
|
494
482
|
}
|
|
495
483
|
if (sub === 'delete' || sub === 'remove') {
|
|
496
484
|
const parsed = parseSkillArgs(args.slice(1));
|
|
497
485
|
const id = parsed.rest[0];
|
|
498
486
|
if (!id) {
|
|
499
|
-
ctx.print('Usage: /
|
|
487
|
+
ctx.print('Usage: /skills delete <id> --yes');
|
|
500
488
|
return;
|
|
501
489
|
}
|
|
502
490
|
if (!parsed.yes) {
|
|
@@ -504,10 +492,10 @@ export async function runAgentSkillsRuntimeCommand(args: readonly string[], ctx:
|
|
|
504
492
|
return;
|
|
505
493
|
}
|
|
506
494
|
const removed = skillRegistry.deleteSkill(id);
|
|
507
|
-
ctx.print(
|
|
495
|
+
ctx.print(formatSkillReceipt('Deleted Agent skill', removed));
|
|
508
496
|
return;
|
|
509
497
|
}
|
|
510
|
-
ctx.print('Usage: /
|
|
498
|
+
ctx.print('Usage: /skills [list|enabled|attention|discover|import-discovered|search|show|create|update|enable|disable|review|stale|delete|bundle]');
|
|
511
499
|
} catch (error) {
|
|
512
500
|
printError(ctx, error);
|
|
513
501
|
}
|
|
@@ -515,9 +503,9 @@ export async function runAgentSkillsRuntimeCommand(args: readonly string[], ctx:
|
|
|
515
503
|
|
|
516
504
|
export function registerAgentSkillsRuntimeCommands(registry: CommandRegistry): void {
|
|
517
505
|
registry.register({
|
|
518
|
-
name: '
|
|
519
|
-
aliases: ['
|
|
520
|
-
description: 'Manage local
|
|
506
|
+
name: 'skills',
|
|
507
|
+
aliases: ['skill', 'agent-skills', 'askills', 'local-skills'],
|
|
508
|
+
description: 'Manage Agent-local skills',
|
|
521
509
|
usage: '[list|enabled|attention|discover|import-discovered <name> --yes|search <query>|show <id>|create --name <name> --description <summary> --procedure <steps> [--requires-env A,B] [--requires-command gh,jq]|update <id> [--name ...] [--description ...] [--procedure ...]|enable <id>|disable <id>|review <id>|stale <id> <reason...>|delete <id> --yes|bundle ...]',
|
|
522
510
|
handler: runAgentSkillsRuntimeCommand,
|
|
523
511
|
});
|
|
@@ -1,18 +1,34 @@
|
|
|
1
|
-
import type { CommandRegistry } from '../command-registry.ts';
|
|
1
|
+
import type { CommandContext, CommandRegistry } from '../command-registry.ts';
|
|
2
|
+
import { AGENT_WORKSPACE_CATEGORY_IDS } from '../agent-workspace-types.ts';
|
|
3
|
+
|
|
4
|
+
const AGENT_WORKSPACE_ARGS_HINT = `${AGENT_WORKSPACE_CATEGORY_IDS.join('|')}|connected-host`;
|
|
2
5
|
|
|
3
6
|
export function registerAgentWorkspaceRuntimeCommands(registry: CommandRegistry): void {
|
|
7
|
+
function openAgentWorkspace(ctx: CommandContext, categoryId: string | undefined): void {
|
|
8
|
+
if (!ctx.openAgentWorkspace) {
|
|
9
|
+
ctx.print('Agent operator workspace is not available in this runtime.');
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
ctx.openAgentWorkspace(categoryId);
|
|
13
|
+
}
|
|
14
|
+
|
|
4
15
|
registry.register({
|
|
5
16
|
name: 'agent',
|
|
6
17
|
aliases: ['home', 'operator'],
|
|
7
18
|
description: 'Open the GoodVibes Agent operator workspace',
|
|
8
19
|
usage: '[category]',
|
|
9
|
-
argsHint:
|
|
20
|
+
argsHint: AGENT_WORKSPACE_ARGS_HINT,
|
|
10
21
|
handler(args, ctx) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
22
|
+
openAgentWorkspace(ctx, args[0]);
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
registry.register({
|
|
26
|
+
name: 'notes',
|
|
27
|
+
aliases: ['scratchpad'],
|
|
28
|
+
description: 'Open Agent-local scratchpad notes in the operator workspace',
|
|
29
|
+
usage: '',
|
|
30
|
+
handler(_args, ctx) {
|
|
31
|
+
openAgentWorkspace(ctx, 'notes');
|
|
16
32
|
},
|
|
17
33
|
});
|
|
18
34
|
}
|
|
@@ -39,7 +39,7 @@ function countSetupGaps(items: readonly { readonly missingRequirementCount?: num
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
function formatWorkPlanLine(total: number, counts: StatusCounts): string {
|
|
42
|
-
if (total === 0) return ' work plan
|
|
42
|
+
if (total === 0) return ' work plan empty';
|
|
43
43
|
const active = counts.pending + counts.in_progress + counts.blocked;
|
|
44
44
|
return [
|
|
45
45
|
` work plan: ${plural(total, 'item')}`,
|
|
@@ -52,8 +52,8 @@ function formatWorkPlanLine(total: number, counts: StatusCounts): string {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
function formatWarnings(warnings: readonly string[]): readonly string[] {
|
|
55
|
-
if (warnings.length === 0) return [' warnings
|
|
56
|
-
return [' warnings
|
|
55
|
+
if (warnings.length === 0) return [' warnings none'];
|
|
56
|
+
return [' warnings', ...warnings.slice(0, 4).map((warning) => ` - ${warning}`)];
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
export function formatAgentOperatorBriefing(ctx: CommandContext): string {
|
|
@@ -76,63 +76,64 @@ export function formatAgentOperatorBriefing(ctx: CommandContext): string {
|
|
|
76
76
|
|
|
77
77
|
const nextActions = [
|
|
78
78
|
snapshot.provider === 'unknown' || snapshot.model === 'unknown'
|
|
79
|
-
? 'Choose the assistant model
|
|
79
|
+
? 'Choose the assistant model from Agent Workspace -> Home -> Choose model.'
|
|
80
80
|
: '',
|
|
81
81
|
snapshot.localMemoryCount === 0
|
|
82
|
-
? 'Store durable non-secret facts
|
|
82
|
+
? 'Store durable non-secret facts from Agent Workspace -> Memory -> Add memory.'
|
|
83
83
|
: snapshot.localMemoryReviewQueueCount > 0
|
|
84
|
-
? `Review ${plural(snapshot.localMemoryReviewQueueCount, 'memory record')}
|
|
84
|
+
? `Review ${plural(snapshot.localMemoryReviewQueueCount, 'memory record')} from Agent Workspace -> Memory -> Review queue.`
|
|
85
85
|
: '',
|
|
86
86
|
!hasLocalSkillBehavior
|
|
87
|
-
? 'Create reusable procedures
|
|
87
|
+
? 'Create reusable procedures from Agent Workspace -> Skills or import reviewed skill files.'
|
|
88
88
|
: '',
|
|
89
89
|
skillSetupGaps > 0
|
|
90
|
-
? `Resolve ${plural(skillSetupGaps, 'skill')} with setup gaps from
|
|
90
|
+
? `Resolve ${plural(skillSetupGaps, 'skill')} with setup gaps from Agent Workspace -> Skills.`
|
|
91
91
|
: '',
|
|
92
92
|
skillBundleSetupGaps > 0
|
|
93
|
-
? `Resolve ${plural(skillBundleSetupGaps, 'skill bundle')} with setup gaps from
|
|
93
|
+
? `Resolve ${plural(skillBundleSetupGaps, 'skill bundle')} with setup gaps from Agent Workspace -> Skills.`
|
|
94
94
|
: '',
|
|
95
95
|
hasLocalSkillBehavior && skillSetupGaps === 0 && skillBundleSetupGaps === 0 && snapshot.activeSkillCount === 0
|
|
96
|
-
? 'Enable reviewed skills or bundles
|
|
96
|
+
? 'Enable reviewed skills or bundles from Agent Workspace -> Skills.'
|
|
97
97
|
: '',
|
|
98
98
|
snapshot.localRoutineCount === 0
|
|
99
|
-
? 'Create repeatable workflows
|
|
99
|
+
? 'Create repeatable workflows from Agent Workspace -> Routines; promote schedules only with explicit confirmation.'
|
|
100
100
|
: routineSetupGaps > 0
|
|
101
|
-
? `Resolve ${plural(routineSetupGaps, 'routine')} with setup gaps from
|
|
101
|
+
? `Resolve ${plural(routineSetupGaps, 'routine')} with setup gaps from Agent Workspace -> Routines.`
|
|
102
102
|
: snapshot.enabledRoutineCount === 0
|
|
103
|
-
? 'Enable reviewed routines
|
|
103
|
+
? 'Enable reviewed routines from Agent Workspace -> Routines.'
|
|
104
104
|
: '',
|
|
105
105
|
channelSetupGaps > 0
|
|
106
|
-
? `Review ${plural(channelSetupGaps, 'enabled channel')} needing setup from
|
|
106
|
+
? `Review ${plural(channelSetupGaps, 'enabled channel')} needing setup from Agent Workspace -> Channels.`
|
|
107
107
|
: '',
|
|
108
108
|
voiceSetupNeedsReview
|
|
109
|
-
? 'Review voice setup
|
|
109
|
+
? 'Review voice setup from Agent Workspace -> Voice & Media before relying on spoken replies.'
|
|
110
110
|
: '',
|
|
111
111
|
mediaSetupNeedsReview
|
|
112
|
-
? 'Review media provider setup
|
|
112
|
+
? 'Review media provider setup from Agent Workspace -> Voice & Media before relying on image or media workflows.'
|
|
113
113
|
: '',
|
|
114
|
-
'Use
|
|
115
|
-
'Use
|
|
114
|
+
'Use Agent Workspace -> Knowledge for Agent Knowledge status, search, and explicit ingest forms.',
|
|
115
|
+
'Use Agent Workspace -> Build Delegation only for explicit build, fix, implementation, or review handoff to GoodVibes TUI.',
|
|
116
116
|
].filter((line): line is string => line.length > 0);
|
|
117
117
|
|
|
118
118
|
return [
|
|
119
119
|
'Agent Briefing',
|
|
120
120
|
` chat route: ${snapshot.provider} / ${snapshot.modelDisplayName}`,
|
|
121
|
-
` session
|
|
122
|
-
` profile
|
|
123
|
-
` policy
|
|
124
|
-
` knowledge
|
|
121
|
+
` session ${snapshot.sessionId}`,
|
|
122
|
+
` profile ${snapshot.activeRuntimeProfile}`,
|
|
123
|
+
` policy ${snapshot.executionPolicy}; delegated review ${snapshot.delegatedReviewPolicy}`,
|
|
124
|
+
` knowledge ${snapshot.knowledgeRoute} (${snapshot.knowledgeIsolation}; no fallback)`,
|
|
125
125
|
'',
|
|
126
126
|
'Readiness',
|
|
127
|
-
` setup
|
|
127
|
+
` setup ${setupReady}/${snapshot.setupChecklist.length} ready; ${setupRecommended} recommended; ${setupBlocked} blocked`,
|
|
128
128
|
` local memory: ${plural(snapshot.localMemoryCount, 'record')}; prompt-active ${snapshot.localMemoryPromptActiveCount}; review queue ${snapshot.localMemoryReviewQueueCount}`,
|
|
129
|
+
` scratchpad notes: ${plural(snapshot.localNoteCount, 'note')}; review queue ${snapshot.localNoteReviewQueueCount}`,
|
|
129
130
|
` personas: ${plural(snapshot.localPersonaCount, 'persona')}; active ${snapshot.activePersonaName}`,
|
|
130
131
|
` skills: ${snapshot.enabledSkillCount}/${snapshot.localSkillCount} enabled; bundles ${snapshot.enabledSkillBundleCount}/${snapshot.localSkillBundleCount}; active ${snapshot.activeSkillCount}; setup gaps ${skillSetupGaps} skill, ${skillBundleSetupGaps} bundle`,
|
|
131
132
|
` routines: ${snapshot.enabledRoutineCount}/${snapshot.localRoutineCount} enabled; setup gaps ${routineSetupGaps}`,
|
|
132
133
|
` channels: ${readyChannels}/${snapshot.channels.length} ready; ${enabledChannels} enabled; setup gaps ${channelSetupGaps}`,
|
|
133
134
|
` voice/media: ${snapshot.voiceProviderCount} voice, ${snapshot.mediaProviderCount} media; browser tools ${snapshot.voiceMediaReadiness.browserToolState}`,
|
|
134
135
|
formatWorkPlanLine(workPlan.total, workPlan.counts),
|
|
135
|
-
` schedules
|
|
136
|
+
` schedules ${enabledJobs}/${jobs.length} visible jobs enabled`,
|
|
136
137
|
'',
|
|
137
138
|
'Next Actions',
|
|
138
139
|
...nextActions.map((line) => ` - ${line}`),
|