@pellux/goodvibes-agent 0.1.117 → 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 +13 -4
- package/README.md +35 -14
- package/bin/goodvibes-agent.ts +16 -2
- package/dist/package/main.js +176073 -170980
- 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 +134 -68
- 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 +44 -36
- 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-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-runtime-profile-runtime.ts +45 -41
- package/src/input/commands/agent-skills-runtime.ts +83 -70
- 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 +56 -35
- 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 +45 -30
- 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 +59 -43
- 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 +21 -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
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type { CommandContext, CommandRegistry } from '../command-registry.ts';
|
|
2
|
+
import {
|
|
3
|
+
buildOperatorActionRequest,
|
|
4
|
+
formatOperatorActionFailure,
|
|
5
|
+
formatOperatorActionPreview,
|
|
6
|
+
formatOperatorActionSuccess,
|
|
7
|
+
postOperatorAction,
|
|
8
|
+
type OperatorActionId,
|
|
9
|
+
} from '../../agent/operator-actions.ts';
|
|
10
|
+
import { resolveAgentConnectedHostConnection } from '../../agent/routine-schedule-promotion.ts';
|
|
11
|
+
import { requireShellPaths } from './runtime-services.ts';
|
|
12
|
+
import { stripYesFlag } from './confirmation.ts';
|
|
13
|
+
|
|
14
|
+
interface OperatorActionOptionParse {
|
|
15
|
+
readonly note?: string;
|
|
16
|
+
readonly remember?: boolean;
|
|
17
|
+
readonly errors: readonly string[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function parseOperatorActionOptions(args: readonly string[]): OperatorActionOptionParse {
|
|
21
|
+
const errors: string[] = [];
|
|
22
|
+
let note: string | undefined;
|
|
23
|
+
let remember: boolean | undefined;
|
|
24
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
25
|
+
const token = args[index];
|
|
26
|
+
if (token === '--note') {
|
|
27
|
+
const value = args[index + 1];
|
|
28
|
+
if (!value) {
|
|
29
|
+
errors.push('--note requires text');
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
note = value;
|
|
33
|
+
index += 1;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (token === '--remember') {
|
|
37
|
+
remember = true;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (token === '--no-remember') {
|
|
41
|
+
remember = false;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
errors.push(`Unknown option ${token}`);
|
|
45
|
+
}
|
|
46
|
+
return { note, remember, errors };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export async function executeConfirmedOperatorAction(
|
|
50
|
+
ctx: CommandContext,
|
|
51
|
+
action: OperatorActionId,
|
|
52
|
+
targetField: 'approvalId' | 'jobId' | 'runId' | 'scheduleId',
|
|
53
|
+
targetId: string,
|
|
54
|
+
rawArgs: readonly string[],
|
|
55
|
+
usage: string,
|
|
56
|
+
): Promise<void> {
|
|
57
|
+
const parsed = stripYesFlag(rawArgs);
|
|
58
|
+
const options = parseOperatorActionOptions(parsed.rest);
|
|
59
|
+
if (options.errors.length > 0) {
|
|
60
|
+
ctx.print([`Usage: ${usage}`, ...options.errors.map((error) => ` ${error}`)].join('\n'));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const request = buildOperatorActionRequest({
|
|
64
|
+
action,
|
|
65
|
+
[targetField]: targetId,
|
|
66
|
+
note: options.note,
|
|
67
|
+
remember: options.remember,
|
|
68
|
+
});
|
|
69
|
+
if (!request.ok) {
|
|
70
|
+
ctx.print(request.error);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const requestSummary = `/${action} ${targetId}`;
|
|
74
|
+
if (!parsed.yes) {
|
|
75
|
+
ctx.print(`${formatOperatorActionPreview(request, requestSummary)}\nUsage: ${usage}`);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const shellPaths = requireShellPaths(ctx);
|
|
79
|
+
const connection = resolveAgentConnectedHostConnection(ctx.platform.configManager, shellPaths.homeDirectory);
|
|
80
|
+
const result = await postOperatorAction(connection, request);
|
|
81
|
+
ctx.print(result.ok ? formatOperatorActionSuccess(connection.baseUrl, result) : formatOperatorActionFailure(result));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function approvalActionFromSubcommand(sub: string): OperatorActionId | null {
|
|
85
|
+
if (sub === 'approve') return 'approvals.approve';
|
|
86
|
+
if (sub === 'deny') return 'approvals.deny';
|
|
87
|
+
if (sub === 'cancel') return 'approvals.cancel';
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function automationActionFromParts(scope: string, verb: string): {
|
|
92
|
+
readonly action: OperatorActionId;
|
|
93
|
+
readonly targetField: 'jobId' | 'runId' | 'scheduleId';
|
|
94
|
+
} | null {
|
|
95
|
+
if ((scope === 'job' || scope === 'jobs') && verb === 'run') return { action: 'automation.jobs.run', targetField: 'jobId' };
|
|
96
|
+
if ((scope === 'job' || scope === 'jobs') && verb === 'pause') return { action: 'automation.jobs.pause', targetField: 'jobId' };
|
|
97
|
+
if ((scope === 'job' || scope === 'jobs') && verb === 'resume') return { action: 'automation.jobs.resume', targetField: 'jobId' };
|
|
98
|
+
if ((scope === 'run' || scope === 'runs') && verb === 'cancel') return { action: 'automation.runs.cancel', targetField: 'runId' };
|
|
99
|
+
if ((scope === 'run' || scope === 'runs') && verb === 'retry') return { action: 'automation.runs.retry', targetField: 'runId' };
|
|
100
|
+
if ((scope === 'schedule' || scope === 'schedules') && verb === 'run') return { action: 'schedules.run', targetField: 'scheduleId' };
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export async function handleApprovalOperatorAction(args: readonly string[], ctx: CommandContext): Promise<boolean> {
|
|
105
|
+
const sub = (args[0] ?? '').toLowerCase();
|
|
106
|
+
const action = approvalActionFromSubcommand(sub);
|
|
107
|
+
if (!action) return false;
|
|
108
|
+
const approvalId = args[1] ?? '';
|
|
109
|
+
const usage = `/approval ${sub} <approval-id> [--note <text>] [--remember|--no-remember] --yes`;
|
|
110
|
+
if (!approvalId) {
|
|
111
|
+
ctx.print(`Usage: ${usage}`);
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
await executeConfirmedOperatorAction(ctx, action, 'approvalId', approvalId, args.slice(2), usage);
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function registerOperatorActionRuntimeCommands(registry: CommandRegistry): void {
|
|
119
|
+
registry.register({
|
|
120
|
+
name: 'automation',
|
|
121
|
+
aliases: ['auto'],
|
|
122
|
+
description: 'Run confirmed connected-host automation actions from the Agent TUI',
|
|
123
|
+
usage: 'job <run|pause|resume> <job-id> --yes | run <cancel|retry> <run-id> --yes | schedule run <schedule-id> --yes',
|
|
124
|
+
argsHint: 'job run <id> --yes | run cancel <id> --yes | schedule run <id> --yes',
|
|
125
|
+
async handler(args, ctx) {
|
|
126
|
+
const scope = (args[0] ?? '').toLowerCase();
|
|
127
|
+
const verb = (args[1] ?? '').toLowerCase();
|
|
128
|
+
const targetId = args[2] ?? '';
|
|
129
|
+
const mapping = automationActionFromParts(scope, verb);
|
|
130
|
+
const usage = '/automation job <run|pause|resume> <job-id> --yes | /automation run <cancel|retry> <run-id> --yes | /automation schedule run <schedule-id> --yes';
|
|
131
|
+
if (!mapping || !targetId) {
|
|
132
|
+
ctx.print(`Usage: ${usage}`);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
await executeConfirmedOperatorAction(ctx, mapping.action, mapping.targetField, targetId, args.slice(3), usage);
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
}
|
|
@@ -57,21 +57,6 @@ export function registerOperatorRuntimeCommands(registry: CommandRegistry): void
|
|
|
57
57
|
else ctx.scrollToLine?.(nextLine);
|
|
58
58
|
},
|
|
59
59
|
});
|
|
60
|
-
|
|
61
|
-
registry.register({
|
|
62
|
-
name: 'profiles',
|
|
63
|
-
aliases: ['profile'],
|
|
64
|
-
description: 'Blocked copied config-profile command; Agent uses isolated profile homes',
|
|
65
|
-
usage: 'disabled',
|
|
66
|
-
argsHint: 'disabled',
|
|
67
|
-
handler(_args, ctx) {
|
|
68
|
-
ctx.print([
|
|
69
|
-
'Copied config profiles are disabled in GoodVibes Agent.',
|
|
70
|
-
'Use /agent profiles or /agent-profile to create and manage isolated Agent profile homes.',
|
|
71
|
-
].join('\n'));
|
|
72
|
-
},
|
|
73
|
-
});
|
|
74
|
-
|
|
75
60
|
registry.register({
|
|
76
61
|
name: 'prev-error',
|
|
77
62
|
aliases: ['pe'],
|
|
@@ -153,7 +138,7 @@ export function registerOperatorRuntimeCommands(registry: CommandRegistry): void
|
|
|
153
138
|
return;
|
|
154
139
|
}
|
|
155
140
|
if (verbosity !== 'minimal' && verbosity !== 'normal' && verbosity !== 'verbose') {
|
|
156
|
-
ctx.print(`Invalid verbosity "${verbosity}". Valid values
|
|
141
|
+
ctx.print(`Invalid verbosity "${verbosity}". Valid values minimal, normal, verbose.`);
|
|
157
142
|
return;
|
|
158
143
|
}
|
|
159
144
|
if (!parsed.yes) {
|
|
@@ -161,7 +146,11 @@ export function registerOperatorRuntimeCommands(registry: CommandRegistry): void
|
|
|
161
146
|
return;
|
|
162
147
|
}
|
|
163
148
|
mgr.setDomainVerbosity(domain, verbosity as 'minimal' | 'normal' | 'verbose');
|
|
164
|
-
ctx.print(
|
|
149
|
+
ctx.print([
|
|
150
|
+
'Domain verbosity set',
|
|
151
|
+
` domain ${domain}`,
|
|
152
|
+
` verbosity ${verbosity}`,
|
|
153
|
+
].join('\n'));
|
|
165
154
|
return;
|
|
166
155
|
}
|
|
167
156
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { discoverPersonas, type DiscoveredPersonaRecord } from '../../agent/persona-discovery.ts';
|
|
2
2
|
import { AgentPersonaRegistry, type AgentPersonaRecord } from '../../agent/persona-registry.ts';
|
|
3
|
+
import { formatAgentRecordOrigin, formatAgentRecordReviewState } from '../../agent/record-labels.ts';
|
|
3
4
|
import type { CommandContext, CommandRegistry } from '../command-registry.ts';
|
|
4
5
|
import { requireShellPaths } from './runtime-services.ts';
|
|
5
6
|
|
|
@@ -44,21 +45,33 @@ function registryFromContext(ctx: CommandContext): AgentPersonaRegistry {
|
|
|
44
45
|
return AgentPersonaRegistry.fromShellPaths(requireShellPaths(ctx));
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
function formatPersonaReceipt(title: string, persona: Pick<AgentPersonaRecord, 'id' | 'name'>, extra: readonly string[] = []): string {
|
|
49
|
+
const activeSuffix = extra.some((line) => line.includes('active yes') || line.includes('active: yes')) ? ' (active)' : '';
|
|
50
|
+
const normalizedExtra = extra.map((line) => line.replace(/^ active /, ' active: '));
|
|
51
|
+
return [
|
|
52
|
+
`${title} ${persona.id}: ${persona.name}${activeSuffix}`,
|
|
53
|
+
` id ${persona.id}`,
|
|
54
|
+
` name ${persona.name}`,
|
|
55
|
+
...normalizedExtra,
|
|
56
|
+
].join('\n');
|
|
57
|
+
}
|
|
58
|
+
|
|
47
59
|
function summarizePersona(persona: AgentPersonaRecord, activePersonaId: string | null): string {
|
|
48
60
|
const active = persona.id === activePersonaId ? 'active' : 'inactive';
|
|
49
|
-
const
|
|
50
|
-
|
|
61
|
+
const review = formatAgentRecordReviewState(persona.reviewState);
|
|
62
|
+
const tags = persona.tags.length > 0 ? ` tags ${persona.tags.join(', ')}` : '';
|
|
63
|
+
return ` ${persona.id} ${active} ${review} ${persona.name} - ${persona.description}${tags}`;
|
|
51
64
|
}
|
|
52
65
|
|
|
53
66
|
function renderList(title: string, registry: AgentPersonaRegistry, personas: readonly AgentPersonaRecord[]): string {
|
|
54
67
|
const snapshot = registry.snapshot();
|
|
55
68
|
if (personas.length === 0) {
|
|
56
|
-
return `${title}\n No local Agent personas yet. Create one with /personas create --name <name> --description <summary> --body <instructions>.`;
|
|
69
|
+
return `${title}\n No local Agent personas yet.\n No Agent-local personas yet. Create one with /personas create --name <name> --description <summary> --body <instructions>.`;
|
|
57
70
|
}
|
|
58
71
|
return [
|
|
59
72
|
`${title} (${personas.length})`,
|
|
60
|
-
` store
|
|
61
|
-
` active
|
|
73
|
+
` store ${snapshot.path}`,
|
|
74
|
+
` active ${snapshot.activePersona?.name ?? '(none)'}`,
|
|
62
75
|
...personas.map((persona) => summarizePersona(persona, snapshot.activePersonaId)),
|
|
63
76
|
].join('\n');
|
|
64
77
|
}
|
|
@@ -66,11 +79,10 @@ function renderList(title: string, registry: AgentPersonaRegistry, personas: rea
|
|
|
66
79
|
function renderPersona(persona: AgentPersonaRecord, activePersonaId: string | null): string {
|
|
67
80
|
return [
|
|
68
81
|
`Persona ${persona.name}`,
|
|
69
|
-
` id
|
|
82
|
+
` id ${persona.id}`,
|
|
70
83
|
` active: ${persona.id === activePersonaId ? 'yes' : 'no'}`,
|
|
71
|
-
` review: ${persona.reviewState}`,
|
|
72
|
-
`
|
|
73
|
-
` provenance: ${persona.provenance}`,
|
|
84
|
+
` review: ${formatAgentRecordReviewState(persona.reviewState)}`,
|
|
85
|
+
` origin: ${formatAgentRecordOrigin(persona.source, persona.provenance)}`,
|
|
74
86
|
` tags: ${persona.tags.join(', ') || '(none)'}`,
|
|
75
87
|
` triggers: ${persona.triggers.join(', ') || '(none)'}`,
|
|
76
88
|
` created: ${persona.createdAt}`,
|
|
@@ -85,7 +97,7 @@ function renderPersona(persona: AgentPersonaRecord, activePersonaId: string | nu
|
|
|
85
97
|
|
|
86
98
|
function summarizeDiscoveredPersona(persona: DiscoveredPersonaRecord): string {
|
|
87
99
|
const description = persona.description ? ` - ${persona.description}` : '';
|
|
88
|
-
return ` ${persona.name} ${persona.origin}${description}\n path
|
|
100
|
+
return ` ${persona.name} ${persona.origin}${description}\n path ${persona.path}`;
|
|
89
101
|
}
|
|
90
102
|
|
|
91
103
|
function renderDiscoveredPersonas(personas: readonly DiscoveredPersonaRecord[]): string {
|
|
@@ -131,18 +143,18 @@ async function importDiscoveredPersona(args: readonly string[], ctx: CommandCont
|
|
|
131
143
|
}
|
|
132
144
|
const discovered = findDiscoveredPersona(await discoverPersonas(requireShellPaths(ctx)), name);
|
|
133
145
|
if (!discovered) {
|
|
134
|
-
ctx.print(`Unknown discovered Agent persona
|
|
146
|
+
ctx.print(`Unknown discovered Agent persona ${name}\nRun /personas discover to inspect available persona files.`);
|
|
135
147
|
return;
|
|
136
148
|
}
|
|
137
149
|
if (!parsed.yes) {
|
|
138
150
|
ctx.print([
|
|
139
151
|
'Agent persona import preview',
|
|
140
|
-
` name
|
|
141
|
-
` origin
|
|
142
|
-
` path
|
|
143
|
-
` description
|
|
144
|
-
` body characters
|
|
145
|
-
' next
|
|
152
|
+
` name ${discovered.name}`,
|
|
153
|
+
` origin ${discovered.origin}`,
|
|
154
|
+
` path ${discovered.path}`,
|
|
155
|
+
` description ${discovered.description || '(none)'}`,
|
|
156
|
+
` body characters ${discovered.body.length}`,
|
|
157
|
+
' next rerun with --yes to import into the Agent-local persona registry',
|
|
146
158
|
].join('\n'));
|
|
147
159
|
return;
|
|
148
160
|
}
|
|
@@ -153,10 +165,10 @@ async function importDiscoveredPersona(args: readonly string[], ctx: CommandCont
|
|
|
153
165
|
tags: frontmatterList(discovered, 'tags'),
|
|
154
166
|
triggers: frontmatterList(discovered, 'triggers'),
|
|
155
167
|
source: 'imported',
|
|
156
|
-
provenance: `
|
|
168
|
+
provenance: `Imported file (${discovered.origin}): ${discovered.path}`,
|
|
157
169
|
});
|
|
158
170
|
if (parsed.flags.get('use') === 'true') personaRegistry.setActive(persona.id);
|
|
159
|
-
ctx.print(
|
|
171
|
+
ctx.print(formatPersonaReceipt('Imported Agent persona', persona, [` active ${parsed.flags.get('use') === 'true' ? 'yes' : 'no'}`]));
|
|
160
172
|
}
|
|
161
173
|
|
|
162
174
|
function requiredFlag(flags: ReadonlyMap<string, string>, key: string): string {
|
|
@@ -166,14 +178,17 @@ function requiredFlag(flags: ReadonlyMap<string, string>, key: string): string {
|
|
|
166
178
|
}
|
|
167
179
|
|
|
168
180
|
function printError(ctx: CommandContext, error: unknown): void {
|
|
169
|
-
ctx.print(
|
|
181
|
+
ctx.print([
|
|
182
|
+
'Error',
|
|
183
|
+
` message ${error instanceof Error ? error.message : String(error)}`,
|
|
184
|
+
].join('\n'));
|
|
170
185
|
}
|
|
171
186
|
|
|
172
187
|
export function registerPersonasRuntimeCommands(registry: CommandRegistry): void {
|
|
173
188
|
registry.register({
|
|
174
189
|
name: 'personas',
|
|
175
190
|
aliases: ['persona'],
|
|
176
|
-
description: 'Manage local
|
|
191
|
+
description: 'Manage Agent-local personas',
|
|
177
192
|
usage: '[list|discover|import-discovered <name> --yes|search <query>|show <id>|create --name <name> --description <summary> --body <instructions>|update <id> [--name ...] [--description ...] [--body ...]|use <id>|active|clear|review <id>|stale <id> <reason...>|delete <id> --yes]',
|
|
178
193
|
async handler(args, ctx) {
|
|
179
194
|
const sub = (args[0] ?? 'list').toLowerCase();
|
|
@@ -204,7 +219,7 @@ export function registerPersonasRuntimeCommands(registry: CommandRegistry): void
|
|
|
204
219
|
}
|
|
205
220
|
const snapshot = registryStore.snapshot();
|
|
206
221
|
const persona = registryStore.get(id);
|
|
207
|
-
ctx.print(persona ? renderPersona(persona, snapshot.activePersonaId) : `Unknown persona
|
|
222
|
+
ctx.print(persona ? renderPersona(persona, snapshot.activePersonaId) : `Unknown Agent persona ${id}`);
|
|
208
223
|
return;
|
|
209
224
|
}
|
|
210
225
|
if (sub === 'create') {
|
|
@@ -217,9 +232,9 @@ export function registerPersonasRuntimeCommands(registry: CommandRegistry): void
|
|
|
217
232
|
tags: splitList(parsed.flags.get('tags')),
|
|
218
233
|
triggers: splitList(parsed.flags.get('triggers')),
|
|
219
234
|
source: 'user',
|
|
220
|
-
provenance: '
|
|
235
|
+
provenance: 'Command',
|
|
221
236
|
});
|
|
222
|
-
ctx.print(
|
|
237
|
+
ctx.print(formatPersonaReceipt('Created Agent persona', persona));
|
|
223
238
|
return;
|
|
224
239
|
}
|
|
225
240
|
if (sub === 'update') {
|
|
@@ -235,9 +250,9 @@ export function registerPersonasRuntimeCommands(registry: CommandRegistry): void
|
|
|
235
250
|
body: parsed.flags.get('body'),
|
|
236
251
|
tags: parsed.flags.has('tags') ? splitList(parsed.flags.get('tags')) : undefined,
|
|
237
252
|
triggers: parsed.flags.has('triggers') ? splitList(parsed.flags.get('triggers')) : undefined,
|
|
238
|
-
provenance: '
|
|
253
|
+
provenance: 'Command',
|
|
239
254
|
});
|
|
240
|
-
ctx.print(
|
|
255
|
+
ctx.print(formatPersonaReceipt('Updated Agent persona', updated));
|
|
241
256
|
return;
|
|
242
257
|
}
|
|
243
258
|
if (sub === 'use') {
|
|
@@ -247,7 +262,7 @@ export function registerPersonasRuntimeCommands(registry: CommandRegistry): void
|
|
|
247
262
|
return;
|
|
248
263
|
}
|
|
249
264
|
const persona = registryStore.setActive(id);
|
|
250
|
-
ctx.print(`Active Agent persona: ${persona.name}
|
|
265
|
+
ctx.print(`Active Agent persona: ${persona.name}\n${formatPersonaReceipt('Active Agent persona', persona)}`);
|
|
251
266
|
return;
|
|
252
267
|
}
|
|
253
268
|
if (sub === 'active') {
|
|
@@ -267,7 +282,7 @@ export function registerPersonasRuntimeCommands(registry: CommandRegistry): void
|
|
|
267
282
|
return;
|
|
268
283
|
}
|
|
269
284
|
const persona = registryStore.markReviewed(id);
|
|
270
|
-
ctx.print(
|
|
285
|
+
ctx.print(formatPersonaReceipt('Reviewed Agent persona', persona));
|
|
271
286
|
return;
|
|
272
287
|
}
|
|
273
288
|
if (sub === 'stale') {
|
|
@@ -277,7 +292,7 @@ export function registerPersonasRuntimeCommands(registry: CommandRegistry): void
|
|
|
277
292
|
return;
|
|
278
293
|
}
|
|
279
294
|
const persona = registryStore.markStale(id, args.slice(2).join(' '));
|
|
280
|
-
ctx.print(
|
|
295
|
+
ctx.print(formatPersonaReceipt('Marked Agent persona stale', persona));
|
|
281
296
|
return;
|
|
282
297
|
}
|
|
283
298
|
if (sub === 'delete' || sub === 'remove') {
|
|
@@ -292,7 +307,7 @@ export function registerPersonasRuntimeCommands(registry: CommandRegistry): void
|
|
|
292
307
|
return;
|
|
293
308
|
}
|
|
294
309
|
const removed = registryStore.deletePersona(id);
|
|
295
|
-
ctx.print(
|
|
310
|
+
ctx.print(formatPersonaReceipt('Deleted Agent persona', removed));
|
|
296
311
|
return;
|
|
297
312
|
}
|
|
298
313
|
ctx.print('Usage: /personas [list|discover|import-discovered|search <query>|show <id>|create|update|use|active|clear|review|stale|delete]');
|
|
@@ -111,7 +111,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
if (args[0] === 'panel') {
|
|
114
|
-
ctx.print('
|
|
114
|
+
ctx.print('Use /plan status or /plan list for compact command output. Open Agent Workspace -> Work -> Planning status or Saved plans for the workspace view.');
|
|
115
115
|
return;
|
|
116
116
|
}
|
|
117
117
|
|
|
@@ -3,6 +3,7 @@ import { dirname } from 'node:path';
|
|
|
3
3
|
import type { CommandRegistry } from '../command-registry.ts';
|
|
4
4
|
import { listBuiltinSubscriptionProviders } from '@pellux/goodvibes-sdk/platform/config';
|
|
5
5
|
import { buildAuthInspectionSnapshot, inspectProviderAuth } from '@/runtime/index.ts';
|
|
6
|
+
import { formatAgentRecordSource } from '../../agent/record-labels.ts';
|
|
6
7
|
import { requireSecretsManager, requireServiceRegistry, requireShellPaths, requireSubscriptionManager } from './runtime-services.ts';
|
|
7
8
|
import { requireYesFlag, stripYesFlag } from './confirmation.ts';
|
|
8
9
|
|
|
@@ -18,11 +19,11 @@ interface AuthReviewBundle {
|
|
|
18
19
|
function inspectAuthBundle(bundle: AuthReviewBundle): string {
|
|
19
20
|
return [
|
|
20
21
|
'Auth Review Bundle',
|
|
21
|
-
`
|
|
22
|
-
`
|
|
23
|
-
` stored secrets
|
|
24
|
-
` active subscriptions
|
|
25
|
-
` pending subscriptions
|
|
22
|
+
` exported at ${new Date(bundle.exportedAt).toISOString()}`,
|
|
23
|
+
` connected host auth ${bundle.externalRuntimeAuth}`,
|
|
24
|
+
` stored secrets ${bundle.secretKeys.length}`,
|
|
25
|
+
` active subscriptions ${bundle.activeSubscriptions.length}`,
|
|
26
|
+
` pending subscriptions ${bundle.pendingSubscriptions.length}`,
|
|
26
27
|
].join('\n');
|
|
27
28
|
}
|
|
28
29
|
|
|
@@ -66,12 +67,12 @@ export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry)
|
|
|
66
67
|
const builtinProviders = listBuiltinSubscriptionProviders().map((entry) => entry.provider);
|
|
67
68
|
ctx.print([
|
|
68
69
|
'Auth Review',
|
|
69
|
-
' connected
|
|
70
|
-
` stored secrets
|
|
71
|
-
` built-in providers
|
|
72
|
-
` active subscriptions
|
|
73
|
-
` pending subscriptions
|
|
74
|
-
...snapshot.providers.map((provider) => ` ${provider.provider}
|
|
70
|
+
' connected host auth managed outside goodvibes-agent',
|
|
71
|
+
` stored secrets ${snapshot.secretKeyCount}`,
|
|
72
|
+
` built-in providers ${builtinProviders.length}${builtinProviders.length > 0 ? ` (${builtinProviders.join(', ')})` : ''}`,
|
|
73
|
+
` active subscriptions ${snapshot.activeSubscriptions}${snapshot.activeSubscriptions > 0 ? ` (${snapshot.providers.filter((provider) => provider.activeSubscription).map((provider) => provider.provider).join(', ')})` : ''}`,
|
|
74
|
+
` pending subscriptions ${snapshot.pendingSubscriptions}${snapshot.pendingSubscriptions > 0 ? ` (${snapshot.providers.filter((provider) => provider.pendingLogin).map((provider) => provider.provider).join(', ')})` : ''}`,
|
|
75
|
+
...snapshot.providers.map((provider) => ` ${provider.provider} auth ${provider.freshness} finish manual configured ${provider.configured ? 'yes' : 'no'}`),
|
|
75
76
|
].join('\n'));
|
|
76
77
|
return;
|
|
77
78
|
}
|
|
@@ -89,19 +90,18 @@ export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry)
|
|
|
89
90
|
});
|
|
90
91
|
ctx.print([
|
|
91
92
|
`Auth Provider ${provider}`,
|
|
92
|
-
` configured
|
|
93
|
-
...(inspection.source ? [`
|
|
94
|
-
` freshness
|
|
95
|
-
|
|
96
|
-
...(inspection.redirectUri ? [`
|
|
97
|
-
|
|
98
|
-
`
|
|
99
|
-
`
|
|
100
|
-
`
|
|
101
|
-
...(inspection.
|
|
102
|
-
...
|
|
103
|
-
...inspection.
|
|
104
|
-
...inspection.nextActions.map((action) => ` next: ${action}`),
|
|
93
|
+
` configured ${inspection.configured ? 'yes' : 'no'}`,
|
|
94
|
+
...(inspection.source ? [` origin ${formatAgentRecordSource(inspection.source)}`] : []),
|
|
95
|
+
` freshness ${inspection.freshness}`,
|
|
96
|
+
' finish mode explicit manual',
|
|
97
|
+
...(inspection.redirectUri ? [` redirect URI ${inspection.redirectUri}`] : []),
|
|
98
|
+
` active subscription ${inspection.activeSubscription ? 'yes' : 'no'}`,
|
|
99
|
+
` pending login ${inspection.pendingLogin ? 'yes' : 'no'}`,
|
|
100
|
+
` ambient API key override ${inspection.overrideAmbientApiKeys ? 'yes' : 'no'}`,
|
|
101
|
+
...(inspection.tokenType ? [` token type ${inspection.tokenType}`] : []),
|
|
102
|
+
...(inspection.expiresAt ? [` expires at ${new Date(inspection.expiresAt).toISOString()}`] : []),
|
|
103
|
+
...inspection.issues.map((issue) => ` issue ${issue}`),
|
|
104
|
+
...inspection.nextActions.map((action) => ` next ${action}`),
|
|
105
105
|
].join('\n'));
|
|
106
106
|
return;
|
|
107
107
|
}
|
|
@@ -119,12 +119,12 @@ export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry)
|
|
|
119
119
|
});
|
|
120
120
|
ctx.print([
|
|
121
121
|
`Auth Repair ${provider}`,
|
|
122
|
-
` configured
|
|
123
|
-
` freshness
|
|
124
|
-
|
|
125
|
-
...inspection.issues.map((issue) => ` issue
|
|
122
|
+
` configured ${inspection.configured ? 'yes' : 'no'}`,
|
|
123
|
+
` freshness ${inspection.freshness}`,
|
|
124
|
+
' finish mode explicit manual',
|
|
125
|
+
...inspection.issues.map((issue) => ` issue ${issue}`),
|
|
126
126
|
...(inspection.nextActions.length > 0
|
|
127
|
-
? [' next
|
|
127
|
+
? [' next', ...inspection.nextActions.map((action) => ` ${action}`)]
|
|
128
128
|
: [' No active repair actions suggested.']),
|
|
129
129
|
].join('\n'));
|
|
130
130
|
return;
|
|
@@ -2,13 +2,34 @@ import type { CommandContext, CommandRegistry } from '../command-registry.ts';
|
|
|
2
2
|
import type {
|
|
3
3
|
ProviderAccountRecord,
|
|
4
4
|
ProviderAccountSnapshot,
|
|
5
|
-
|
|
5
|
+
ProviderAuthRoute,
|
|
6
|
+
ProviderRouteRecord,
|
|
7
|
+
} from '../../panels/provider-account-snapshot.ts';
|
|
8
|
+
import { buildProviderAccountSnapshot } from '../../panels/provider-account-snapshot.ts';
|
|
6
9
|
import {
|
|
7
|
-
|
|
10
|
+
requireProvider,
|
|
11
|
+
requireServiceRegistry,
|
|
12
|
+
requireSubscriptionManager,
|
|
8
13
|
} from './runtime-services.ts';
|
|
14
|
+
import { formatProviderAuthRouteId } from '../../provider-auth-route-display.ts';
|
|
15
|
+
|
|
16
|
+
function formatRouteList(routes: readonly ProviderAuthRoute[]): string {
|
|
17
|
+
return routes.map((route) => formatProviderAuthRouteId(route)).join(', ');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function formatRouteRecord(route: ProviderRouteRecord): string {
|
|
21
|
+
return `${formatProviderAuthRouteId(route.route)} ${route.usable ? 'usable' : 'blocked'} auth ${route.freshness} ${route.detail}`;
|
|
22
|
+
}
|
|
9
23
|
|
|
10
24
|
async function loadProviderAccountSnapshot(context: CommandContext): Promise<ProviderAccountSnapshot> {
|
|
11
|
-
return await
|
|
25
|
+
return await buildProviderAccountSnapshot({
|
|
26
|
+
providerModels: requireProvider(context).providerRegistry,
|
|
27
|
+
services: requireServiceRegistry(context),
|
|
28
|
+
subscriptions: requireSubscriptionManager(context),
|
|
29
|
+
environment: {
|
|
30
|
+
hasEnvironmentVariable: (name: string) => Boolean(process.env[name]),
|
|
31
|
+
},
|
|
32
|
+
});
|
|
12
33
|
}
|
|
13
34
|
|
|
14
35
|
function findProviderAccountRecord(
|
|
@@ -28,7 +49,7 @@ export function registerProviderAccountsRuntimeCommands(registry: CommandRegistr
|
|
|
28
49
|
async handler(args, ctx) {
|
|
29
50
|
const sub = (args[0] ?? 'review').toLowerCase();
|
|
30
51
|
if (sub === 'panel' || sub === 'open') {
|
|
31
|
-
ctx.print('
|
|
52
|
+
ctx.print('Open Agent Workspace -> Setup -> Provider accounts for the workspace view, or run /accounts review for compact command output.');
|
|
32
53
|
return;
|
|
33
54
|
}
|
|
34
55
|
const snapshot = await loadProviderAccountSnapshot(ctx);
|
|
@@ -36,16 +57,16 @@ export function registerProviderAccountsRuntimeCommands(registry: CommandRegistr
|
|
|
36
57
|
const providerId = args[1];
|
|
37
58
|
const record = findProviderAccountRecord(snapshot, providerId);
|
|
38
59
|
if (!record) {
|
|
39
|
-
ctx.print(providerId ? `Unknown provider account
|
|
60
|
+
ctx.print(providerId ? `Unknown provider account ${providerId}` : 'Usage: /accounts routes <provider>');
|
|
40
61
|
return;
|
|
41
62
|
}
|
|
42
63
|
ctx.print([
|
|
43
64
|
`Provider Routes ${record.providerId}`,
|
|
44
|
-
` preferred
|
|
45
|
-
` active
|
|
46
|
-
` reason
|
|
47
|
-
...record.routeRecords.map((route) => ` ${route
|
|
48
|
-
...record.routeRecords.flatMap((route) => route.issues.map((issue) => ` issue
|
|
65
|
+
` preferred route ${formatProviderAuthRouteId(record.preferredRoute)}`,
|
|
66
|
+
` active route ${formatProviderAuthRouteId(record.activeRoute)}`,
|
|
67
|
+
` reason ${record.activeRouteReason}`,
|
|
68
|
+
...record.routeRecords.map((route) => ` ${formatRouteRecord(route)}`),
|
|
69
|
+
...record.routeRecords.flatMap((route) => route.issues.map((issue) => ` issue ${issue}`)),
|
|
49
70
|
].join('\n'));
|
|
50
71
|
return;
|
|
51
72
|
}
|
|
@@ -53,17 +74,17 @@ export function registerProviderAccountsRuntimeCommands(registry: CommandRegistr
|
|
|
53
74
|
const providerId = args[1];
|
|
54
75
|
const record = findProviderAccountRecord(snapshot, providerId);
|
|
55
76
|
if (!record) {
|
|
56
|
-
ctx.print(providerId ? `Unknown provider account
|
|
77
|
+
ctx.print(providerId ? `Unknown provider account ${providerId}` : 'Usage: /accounts repair <provider>');
|
|
57
78
|
return;
|
|
58
79
|
}
|
|
59
80
|
ctx.print([
|
|
60
81
|
`Provider Account Repair ${record.providerId}`,
|
|
61
|
-
` active route
|
|
62
|
-
` preferred route
|
|
63
|
-
...(record.fallbackRisk ? [`
|
|
64
|
-
...(record.issues.map((issue) => ` issue
|
|
82
|
+
` active route ${formatProviderAuthRouteId(record.activeRoute)}`,
|
|
83
|
+
` preferred route ${formatProviderAuthRouteId(record.preferredRoute)}`,
|
|
84
|
+
...(record.fallbackRisk ? [` routing risk ${record.fallbackRisk}`] : []),
|
|
85
|
+
...(record.issues.map((issue) => ` issue ${issue}`)),
|
|
65
86
|
...(record.recommendedActions.length > 0
|
|
66
|
-
? [' next
|
|
87
|
+
? [' next', ...record.recommendedActions.map((action) => ` ${action}`)]
|
|
67
88
|
: [' No active repair actions suggested.']),
|
|
68
89
|
].join('\n'));
|
|
69
90
|
return;
|
|
@@ -72,39 +93,39 @@ export function registerProviderAccountsRuntimeCommands(registry: CommandRegistr
|
|
|
72
93
|
const providerId = args[1];
|
|
73
94
|
const record = findProviderAccountRecord(snapshot, providerId);
|
|
74
95
|
if (!record) {
|
|
75
|
-
ctx.print(providerId ? `Unknown provider account
|
|
96
|
+
ctx.print(providerId ? `Unknown provider account ${providerId}` : 'Usage: /accounts show <provider>');
|
|
76
97
|
return;
|
|
77
98
|
}
|
|
78
99
|
ctx.print([
|
|
79
100
|
`Provider Account ${record.providerId}`,
|
|
80
|
-
`
|
|
81
|
-
`
|
|
82
|
-
`
|
|
83
|
-
` configured
|
|
84
|
-
`
|
|
85
|
-
`
|
|
86
|
-
`
|
|
87
|
-
`
|
|
88
|
-
`
|
|
89
|
-
...(record.fallbackRoute ? [`
|
|
90
|
-
...(record.fallbackRisk ? [`
|
|
91
|
-
...(record.expiresAt ? [`
|
|
92
|
-
...record.routeRecords.map((route) => ` route ${route
|
|
93
|
-
...record.routeRecords.flatMap((route) => route.issues.map((issue) => ` issue
|
|
94
|
-
...record.usageWindows.map((entry) => ` window
|
|
95
|
-
...record.issues.map((issue) => ` issue
|
|
96
|
-
...record.notes.map((note) => ` note
|
|
97
|
-
...record.recommendedActions.map((action) => ` next
|
|
101
|
+
` preferred route ${formatProviderAuthRouteId(record.preferredRoute)}`,
|
|
102
|
+
` active route ${formatProviderAuthRouteId(record.activeRoute)}`,
|
|
103
|
+
` auth freshness ${record.authFreshness}`,
|
|
104
|
+
` configured ${record.configured ? 'yes' : 'no'}`,
|
|
105
|
+
` OAuth ready ${record.oauthReady ? 'yes' : 'no'}`,
|
|
106
|
+
` pending login ${record.pendingLogin ? 'yes' : 'no'}`,
|
|
107
|
+
` available routes ${formatRouteList(record.availableRoutes)}`,
|
|
108
|
+
` model count ${record.modelCount}`,
|
|
109
|
+
` route reason ${record.activeRouteReason}`,
|
|
110
|
+
...(record.fallbackRoute ? [` fallback route ${formatProviderAuthRouteId(record.fallbackRoute)}`] : []),
|
|
111
|
+
...(record.fallbackRisk ? [` routing risk ${record.fallbackRisk}`] : []),
|
|
112
|
+
...(record.expiresAt ? [` expires at ${new Date(record.expiresAt).toISOString()}`] : []),
|
|
113
|
+
...record.routeRecords.map((route) => ` route ${formatRouteRecord(route)}`),
|
|
114
|
+
...record.routeRecords.flatMap((route) => route.issues.map((issue) => ` issue ${issue}`)),
|
|
115
|
+
...record.usageWindows.map((entry) => ` window ${entry.label} — ${entry.detail}`),
|
|
116
|
+
...record.issues.map((issue) => ` issue ${issue}`),
|
|
117
|
+
...record.notes.map((note) => ` note ${note}`),
|
|
118
|
+
...record.recommendedActions.map((action) => ` next ${action}`),
|
|
98
119
|
].join('\n'));
|
|
99
120
|
return;
|
|
100
121
|
}
|
|
101
122
|
ctx.print([
|
|
102
123
|
'Provider Account Review',
|
|
103
|
-
` providers
|
|
104
|
-
` configured
|
|
105
|
-
` issues
|
|
124
|
+
` providers ${snapshot.providers.length}`,
|
|
125
|
+
` configured ${snapshot.configuredCount}`,
|
|
126
|
+
` issues ${snapshot.issueCount}`,
|
|
106
127
|
...snapshot.providers.map((record) => (
|
|
107
|
-
` ${record.providerId} active
|
|
128
|
+
` ${record.providerId} active route ${formatProviderAuthRouteId(record.activeRoute)} preferred route ${formatProviderAuthRouteId(record.preferredRoute)} auth ${record.authFreshness} models ${record.modelCount} issues ${record.issues.length}`
|
|
108
129
|
)),
|
|
109
130
|
].join('\n'));
|
|
110
131
|
},
|