@pellux/goodvibes-agent 0.1.114 → 0.1.117
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 +41 -650
- package/README.md +40 -50
- package/dist/package/main.js +38224 -35673
- package/docs/README.md +5 -4
- package/docs/{connected-services.md → connected-host.md} +18 -10
- package/docs/getting-started.md +43 -42
- package/docs/release-and-publishing.md +6 -4
- package/package.json +3 -3
- package/src/agent/behavior-discovery-summary.ts +165 -0
- package/src/agent/persona-discovery.ts +1 -3
- package/src/agent/persona-registry.ts +5 -3
- package/src/agent/reminder-schedule-format.ts +6 -6
- package/src/agent/reminder-schedule.ts +1 -1
- package/src/agent/routine-registry.ts +43 -4
- package/src/agent/routine-schedule-format.ts +6 -6
- package/src/agent/routine-schedule-promotion.ts +1 -1
- package/src/agent/routine-schedule-receipts.ts +1 -1
- package/src/agent/runtime-profile-starters.ts +331 -0
- package/src/agent/runtime-profile.ts +228 -330
- package/src/agent/skill-registry.ts +190 -13
- package/src/cli/agent-knowledge-command.ts +2 -2
- package/src/cli/agent-knowledge-format.ts +2 -2
- package/src/cli/agent-knowledge-runtime.ts +1 -1
- package/src/cli/bundle-command.ts +1 -1
- package/src/cli/entrypoint.ts +16 -7
- package/src/cli/help.ts +26 -19
- package/src/cli/local-library-command.ts +75 -21
- package/src/cli/management-commands.ts +7 -6
- package/src/cli/management.ts +6 -51
- package/src/cli/parser.ts +23 -2
- package/src/cli/profiles-command.ts +247 -1
- package/src/cli/routines-command.ts +139 -11
- package/src/cli/service-posture.ts +11 -11
- package/src/cli/status.ts +21 -25
- 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 +2 -1
- package/src/input/agent-workspace-basic-command-editor-submission.ts +787 -0
- package/src/input/agent-workspace-basic-command-editors.ts +524 -459
- package/src/input/agent-workspace-categories.ts +177 -14
- package/src/input/agent-workspace-channel-command-editor-submission.ts +49 -0
- package/src/input/agent-workspace-channel-command-editors.ts +47 -0
- package/src/input/agent-workspace-command-editor.ts +25 -1
- package/src/input/agent-workspace-delegation-editor-submission.ts +55 -0
- package/src/input/agent-workspace-editors.ts +27 -0
- 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-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-mcp-command-editor-submission.ts +95 -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-navigation.ts +45 -0
- package/src/input/agent-workspace-notify-editor-submission.ts +107 -0
- package/src/input/agent-workspace-operations-command-editor-submission.ts +146 -0
- package/src/input/agent-workspace-operations-command-editors.ts +119 -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-requirements.ts +11 -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 +49 -19
- 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 +56 -8
- 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-types.ts +124 -0
- package/src/input/agent-workspace-voice-media.ts +1 -1
- package/src/input/agent-workspace-workplan-editor-submission.ts +153 -0
- package/src/input/agent-workspace.ts +47 -37
- package/src/input/command-registry.ts +1 -1
- package/src/input/commands/agent-runtime-profile-runtime.ts +160 -6
- package/src/input/commands/agent-skills-runtime.ts +76 -12
- package/src/input/commands/agent-workspace-runtime.ts +4 -3
- package/src/input/commands/brief-runtime.ts +38 -9
- package/src/input/commands/channels-runtime.ts +3 -3
- package/src/input/commands/compat-runtime.ts +32 -0
- package/src/input/commands/health-runtime.ts +22 -24
- package/src/input/commands/knowledge.ts +26 -5
- package/src/input/commands/local-provider-runtime.ts +7 -3
- package/src/input/commands/local-setup-review.ts +4 -14
- package/src/input/commands/mcp-runtime.ts +8 -12
- package/src/input/commands/operator-runtime.ts +8 -67
- package/src/input/commands/personas-runtime.ts +1 -1
- package/src/input/commands/platform-access-runtime.ts +7 -70
- package/src/input/commands/policy-dispatch.ts +1 -1
- package/src/input/commands/policy.ts +1 -5
- package/src/input/commands/product-runtime.ts +2 -2
- package/src/input/commands/qrcode-runtime.ts +6 -4
- package/src/input/commands/routines-runtime.ts +44 -6
- package/src/input/commands/runtime-services.ts +1 -14
- package/src/input/commands/security-runtime.ts +3 -8
- package/src/input/commands/session-content.ts +1 -1
- package/src/input/commands/session-workflow.ts +5 -14
- package/src/input/commands/shell-core.ts +8 -2
- package/src/input/commands/subscription-runtime.ts +1 -6
- package/src/input/commands/support-bundle-runtime.ts +53 -0
- package/src/input/commands/tasks-runtime.ts +2 -2
- package/src/input/commands.ts +4 -0
- package/src/input/feed-context-factory.ts +0 -1
- package/src/input/handler-content-actions.ts +0 -25
- package/src/input/handler-feed.ts +0 -2
- package/src/input/handler-interactions.ts +2 -31
- package/src/input/handler-onboarding.ts +29 -12
- package/src/input/handler-shortcuts.ts +1 -3
- package/src/input/handler.ts +4 -7
- package/src/input/keybindings.ts +9 -9
- 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 +49 -0
- package/src/input/onboarding/onboarding-wizard-helpers.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-operator-steps.ts +126 -11
- package/src/input/onboarding/onboarding-wizard-steps.ts +15 -8
- package/src/input/onboarding/onboarding-wizard-types.ts +1 -0
- package/src/input/onboarding/onboarding-wizard.ts +19 -2
- package/src/input/profile-picker-modal.ts +2 -2
- package/src/input/settings-modal-agent-policy.ts +6 -6
- package/src/input/settings-modal-subscriptions.ts +3 -3
- package/src/input/settings-modal.ts +14 -14
- package/src/main.ts +0 -2
- package/src/panels/automation-control-panel.ts +3 -3
- package/src/panels/builtin/agent.ts +1 -1
- package/src/panels/builtin/operations.ts +2 -2
- package/src/panels/builtin/session.ts +26 -18
- package/src/panels/builtin/shared.ts +6 -6
- package/src/panels/project-planning-panel.ts +1 -1
- package/src/panels/provider-health-domains.ts +3 -3
- package/src/panels/qr-panel.ts +44 -20
- package/src/panels/subscription-panel.ts +3 -3
- package/src/panels/system-messages-panel.ts +2 -2
- package/src/panels/tasks-panel.ts +4 -4
- package/src/planning/project-planning-coordinator.ts +2 -2
- package/src/renderer/agent-workspace.ts +52 -5
- package/src/renderer/block-actions.ts +1 -3
- package/src/renderer/help-overlay.ts +13 -8
- package/src/renderer/mcp-workspace.ts +32 -13
- package/src/renderer/model-picker-overlay.ts +0 -1
- package/src/renderer/model-workspace.ts +0 -2
- package/src/renderer/onboarding/onboarding-wizard.ts +20 -4
- package/src/renderer/panel-picker-overlay.ts +1 -1
- package/src/renderer/profile-picker-modal.ts +2 -2
- package/src/renderer/settings-modal-helpers.ts +23 -23
- package/src/renderer/settings-modal.ts +18 -18
- package/src/renderer/system-message.ts +1 -1
- package/src/runtime/agent-runtime-events.ts +129 -0
- package/src/runtime/bootstrap-command-parts.ts +3 -2
- package/src/runtime/bootstrap-core.ts +4 -64
- package/src/runtime/bootstrap-shell.ts +42 -4
- package/src/runtime/bootstrap.ts +8 -27
- package/src/runtime/connected-host-auth.ts +42 -0
- package/src/runtime/diagnostics/panels/panel-resources.ts +1 -1
- package/src/runtime/index.ts +1 -5
- package/src/runtime/onboarding/apply.ts +213 -0
- package/src/runtime/onboarding/derivation.ts +25 -6
- package/src/runtime/onboarding/snapshot.ts +4 -2
- package/src/runtime/onboarding/types.ts +28 -1
- package/src/runtime/onboarding/verify.ts +81 -2
- package/src/runtime/operator-token-cleanup.ts +2 -2
- package/src/runtime/services.ts +27 -12
- package/src/shell/service-settings-sync.ts +7 -7
- package/src/shell/ui-openers.ts +27 -38
- package/src/tools/agent-local-registry-tool.ts +10 -4
- package/src/tools/agent-tool-policy-guard.ts +5 -7
- package/src/version.ts +1 -1
- package/src/cli/package-verification.ts +0 -274
|
@@ -174,8 +174,7 @@ export function registerMcpRuntimeCommands(registry: CommandRegistry): void {
|
|
|
174
174
|
+ ' ~/.config/claude/claude_desktop_config.json (Claude Desktop)\n'
|
|
175
175
|
+ ' .mcp/mcp.json (project-local)\n'
|
|
176
176
|
+ ' .goodvibes/mcp.json (goodvibes project)\n'
|
|
177
|
-
+ '\
|
|
178
|
-
+ ' /mcp add filesystem npx -y @modelcontextprotocol/server-filesystem . --scope project --role filesystem --yes'
|
|
177
|
+
+ '\nOpen /mcp and choose Add or update server, or use Agent Workspace -> Tools & MCP -> Add MCP server.'
|
|
179
178
|
);
|
|
180
179
|
return;
|
|
181
180
|
}
|
|
@@ -265,7 +264,7 @@ export function registerMcpRuntimeCommands(registry: CommandRegistry): void {
|
|
|
265
264
|
const mode = commandArgs[2] as 'constrained' | 'ask-on-risk' | 'allow-all' | 'blocked' | undefined;
|
|
266
265
|
if (serverName && mode) {
|
|
267
266
|
if (mode === 'allow-all') {
|
|
268
|
-
ctx.print(`Use /settings → MCP to explicitly enable allow-all for ${serverName}. Direct
|
|
267
|
+
ctx.print(`Use /settings → MCP to explicitly enable allow-all for ${serverName}. Direct command escalation is blocked.`);
|
|
269
268
|
ctx.openSettingsModal?.();
|
|
270
269
|
return;
|
|
271
270
|
}
|
|
@@ -399,9 +398,9 @@ export function registerMcpRuntimeCommands(registry: CommandRegistry): void {
|
|
|
399
398
|
}),
|
|
400
399
|
'',
|
|
401
400
|
'Add or update from inside Agent with explicit confirmation:',
|
|
401
|
+
' Open /mcp and choose Add or update server, or use Agent Workspace -> Tools & MCP -> Add MCP server.',
|
|
402
|
+
'Automation equivalent:',
|
|
402
403
|
' /mcp add <name> <command> [args...] [--scope project|global] [--role <role>] [--trust <mode>] --yes',
|
|
403
|
-
'Example:',
|
|
404
|
-
' /mcp add filesystem npx -y @modelcontextprotocol/server-filesystem . --scope project --role filesystem --trust constrained --yes',
|
|
405
404
|
].join('\n'));
|
|
406
405
|
} catch (error) {
|
|
407
406
|
ctx.print(`MCP config read failed: ${summarizeError(error)}`);
|
|
@@ -446,8 +445,7 @@ export function registerMcpRuntimeCommands(registry: CommandRegistry): void {
|
|
|
446
445
|
+ ' ~/.config/claude/claude_desktop_config.json (Claude Desktop)\n'
|
|
447
446
|
+ ' .mcp/mcp.json (project-local)\n'
|
|
448
447
|
+ ' .goodvibes/mcp.json (goodvibes project)\n'
|
|
449
|
-
+ '\
|
|
450
|
-
+ ' /mcp add filesystem npx -y @modelcontextprotocol/server-filesystem . --scope project --role filesystem --yes\n'
|
|
448
|
+
+ '\nOpen /mcp and choose Add or update server, or use Agent Workspace -> Tools & MCP -> Add MCP server.\n'
|
|
451
449
|
+ '\nFormat: { "servers": [{ "name": "my-server", "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"] }] }'
|
|
452
450
|
);
|
|
453
451
|
return;
|
|
@@ -473,11 +471,9 @@ function formatMcpServerList(servers: readonly McpSecurityServer[]): string {
|
|
|
473
471
|
}
|
|
474
472
|
if (connected.length > 0) {
|
|
475
473
|
lines.push('');
|
|
476
|
-
lines.push('
|
|
477
|
-
lines.push('
|
|
478
|
-
lines.push('
|
|
479
|
-
lines.push('Run "/mcp trust <server> <mode> --yes" to change trust mode, or "/mcp role <server> <role> --yes" to change its coherence role.');
|
|
480
|
-
lines.push('Run "/mcp quarantine <server> [detail] --yes" to block a server, or "/mcp quarantine <server> approve [operatorId] --yes" to approve a temporary override.');
|
|
474
|
+
lines.push('Open "/mcp" for the fullscreen MCP workspace with server status, tools, config paths, and confirmed add/remove/reload actions.');
|
|
475
|
+
lines.push('Use "/mcp tools" for a compact tool list, or "/mcp tools <server>" for one server.');
|
|
476
|
+
lines.push('Use Settings -> MCP for allow-all decisions; trust, role, and quarantine command actions still require explicit --yes confirmation.');
|
|
481
477
|
lines.push('Use /settings -> MCP to explicitly enable allow-all for a server.');
|
|
482
478
|
}
|
|
483
479
|
if (disconnected.length > 0) {
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { CommandRegistry } from '../command-registry.ts';
|
|
2
|
-
import type { ProfileData } from '@pellux/goodvibes-sdk/platform/profiles';
|
|
3
2
|
import { logger } from '@pellux/goodvibes-sdk/platform/utils';
|
|
4
|
-
import { requireProfileManager } from './runtime-services.ts';
|
|
5
3
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
6
4
|
import { requireYesFlag, stripYesFlag } from './confirmation.ts';
|
|
7
5
|
|
|
@@ -63,71 +61,14 @@ export function registerOperatorRuntimeCommands(registry: CommandRegistry): void
|
|
|
63
61
|
registry.register({
|
|
64
62
|
name: 'profiles',
|
|
65
63
|
aliases: ['profile'],
|
|
66
|
-
description: '
|
|
67
|
-
usage: '
|
|
68
|
-
argsHint: '
|
|
69
|
-
handler(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (ctx.openProfilePicker) {
|
|
75
|
-
ctx.openProfilePicker();
|
|
76
|
-
} else {
|
|
77
|
-
const profiles = profileManager.list();
|
|
78
|
-
if (profiles.length === 0) ctx.print('No profiles saved. Use /profiles save <name> --yes to save the current settings as a profile.');
|
|
79
|
-
else ctx.print(['Saved profiles:', ...profiles.map(p => ` ${p.name}`)].join('\n'));
|
|
80
|
-
}
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
if (sub === 'list') {
|
|
84
|
-
const profiles = profileManager.list();
|
|
85
|
-
if (profiles.length === 0) ctx.print('No profiles saved. Use /profiles save <name> --yes to save the current settings as a profile.');
|
|
86
|
-
else ctx.print(['Saved profiles:', ...profiles.map(p => ` ${p.name}`)].join('\n'));
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
if (sub === 'save') {
|
|
90
|
-
const name = parsed.rest[1];
|
|
91
|
-
if (!name) {
|
|
92
|
-
ctx.print('Usage: /profiles save <name> --yes');
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
if (!parsed.yes) {
|
|
96
|
-
requireYesFlag(ctx, `save config profile ${name}`, '/profiles save <name> --yes');
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
const all = ctx.platform.configManager.getAll();
|
|
100
|
-
const data: ProfileData = {
|
|
101
|
-
display: { ...all.display },
|
|
102
|
-
provider: {
|
|
103
|
-
model: all.provider.model,
|
|
104
|
-
reasoningEffort: all.provider.reasoningEffort,
|
|
105
|
-
},
|
|
106
|
-
behavior: { ...all.behavior },
|
|
107
|
-
};
|
|
108
|
-
profileManager.save(name, data);
|
|
109
|
-
ctx.print(`Profile saved: ${name}`);
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
if (sub === 'delete' || sub === 'remove') {
|
|
113
|
-
const name = parsed.rest[1];
|
|
114
|
-
if (!name) {
|
|
115
|
-
ctx.print('Usage: /profiles delete <name> --yes');
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
if (!parsed.yes) {
|
|
119
|
-
requireYesFlag(ctx, `delete config profile ${name}`, '/profiles delete <name> --yes');
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
const deleted = profileManager.delete(name);
|
|
123
|
-
ctx.print(deleted ? `Profile deleted: ${name}` : `Profile not found: ${name}`);
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
if (args.length === 0 && ctx.openProfilePicker) {
|
|
127
|
-
ctx.openProfilePicker();
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
ctx.print('Usage: /profiles [list|open|save <name> --yes|delete <name> --yes]');
|
|
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'));
|
|
131
72
|
},
|
|
132
73
|
});
|
|
133
74
|
|
|
@@ -93,7 +93,7 @@ function renderDiscoveredPersonas(personas: readonly DiscoveredPersonaRecord[]):
|
|
|
93
93
|
return [
|
|
94
94
|
'Discovered Agent persona files',
|
|
95
95
|
' No persona markdown files found in project/global Agent persona folders.',
|
|
96
|
-
' Search roots: .goodvibes/personas, .goodvibes/agent/personas,
|
|
96
|
+
' Search roots: .goodvibes/personas, .goodvibes/agent/personas, ~/.goodvibes/personas, ~/.goodvibes/agent/personas',
|
|
97
97
|
].join('\n');
|
|
98
98
|
}
|
|
99
99
|
return [
|
|
@@ -27,69 +27,6 @@ function inspectAuthBundle(bundle: AuthReviewBundle): string {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry): void {
|
|
30
|
-
registry.register({
|
|
31
|
-
name: 'login',
|
|
32
|
-
description: 'Front-door login flow for provider subscriptions',
|
|
33
|
-
usage: 'provider <name> start|finish <code> --yes',
|
|
34
|
-
async handler(args, ctx) {
|
|
35
|
-
const parsed = stripYesFlag(args);
|
|
36
|
-
const commandArgs = [...parsed.rest];
|
|
37
|
-
const target = (commandArgs[0] ?? '').toLowerCase();
|
|
38
|
-
if (target === 'provider') {
|
|
39
|
-
const provider = commandArgs[1];
|
|
40
|
-
const mode = commandArgs[2]?.toLowerCase();
|
|
41
|
-
if (!provider || !mode) {
|
|
42
|
-
ctx.print('Usage: /login provider <name> start|finish <code> --yes');
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
if (!parsed.yes) {
|
|
46
|
-
requireYesFlag(ctx, `${mode} provider subscription login for ${provider}`, '/login provider <name> start|finish <code> --yes');
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
if (ctx.executeCommand) {
|
|
50
|
-
await ctx.executeCommand('subscription', ['login', provider, mode, ...commandArgs.slice(3), '--yes']);
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
ctx.print(`Use /subscription login ${provider} ${mode}${commandArgs[3] ? ` ${commandArgs[3]}` : ''} --yes`);
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
if (target === 'service' || target === 'runtime' || target === 'listener' || target === 'daemon') {
|
|
57
|
-
ctx.print([
|
|
58
|
-
'Connected-service login is outside GoodVibes Agent.',
|
|
59
|
-
'Agent does not create, exchange, store, rotate, revoke, or clear connected-service sessions.',
|
|
60
|
-
'Use the owning GoodVibes host for connected-service auth administration.',
|
|
61
|
-
'Agent login supports provider subscriptions only: /login provider <name> start|finish <code> --yes.',
|
|
62
|
-
].join('\n'));
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
ctx.print('Usage: /login provider <name> start|finish <code> --yes');
|
|
66
|
-
},
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
registry.register({
|
|
70
|
-
name: 'logout',
|
|
71
|
-
description: 'Front-door logout flow for provider subscription sessions and supported overrides',
|
|
72
|
-
usage: 'provider <name> --yes',
|
|
73
|
-
async handler(args, ctx) {
|
|
74
|
-
const parsed = stripYesFlag(args);
|
|
75
|
-
const commandArgs = [...parsed.rest];
|
|
76
|
-
const target = (commandArgs[0] ?? '').toLowerCase();
|
|
77
|
-
if (target !== 'provider' || !commandArgs[1]) {
|
|
78
|
-
ctx.print('Usage: /logout provider <name> --yes');
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
if (!parsed.yes) {
|
|
82
|
-
requireYesFlag(ctx, `log out provider subscription ${commandArgs[1]}`, '/logout provider <name> --yes');
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
if (ctx.executeCommand) {
|
|
86
|
-
await ctx.executeCommand('subscription', ['logout', commandArgs[1], '--yes']);
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
ctx.print(`Use /subscription logout ${commandArgs[1]} --yes`);
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
|
|
93
30
|
registry.register({
|
|
94
31
|
name: 'auth',
|
|
95
32
|
description: 'Review provider auth posture and export redacted auth review bundles',
|
|
@@ -100,18 +37,18 @@ export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry)
|
|
|
100
37
|
const sub = commandArgs[0] ?? 'review';
|
|
101
38
|
if (sub === 'local') {
|
|
102
39
|
ctx.print([
|
|
103
|
-
'Connected-
|
|
104
|
-
'Agent connects to GoodVibes
|
|
105
|
-
'Use the owning GoodVibes host for connected-
|
|
40
|
+
'Connected-host auth management is outside GoodVibes Agent.',
|
|
41
|
+
'Agent connects to a GoodVibes host owned outside this package and does not create, delete, rotate, revoke, or clear connected-host auth users, sessions, or bootstrap credentials.',
|
|
42
|
+
'Use the owning GoodVibes host for connected-host auth administration.',
|
|
106
43
|
'Agent auth commands available here: /auth review, /auth show <provider>, /auth repair <provider>, /auth bundle export <path> --yes, /auth bundle inspect <path>.',
|
|
107
44
|
].join('\n'));
|
|
108
45
|
return;
|
|
109
46
|
}
|
|
110
47
|
if (sub === 'login') {
|
|
111
48
|
ctx.print([
|
|
112
|
-
'Connected-
|
|
113
|
-
'Agent does not create, exchange, store, rotate, revoke, or clear connected-
|
|
114
|
-
'Use the owning GoodVibes host for connected-
|
|
49
|
+
'Connected-host login is outside GoodVibes Agent.',
|
|
50
|
+
'Agent does not create, exchange, store, rotate, revoke, or clear connected-host sessions.',
|
|
51
|
+
'Use the owning GoodVibes host for connected-host auth administration.',
|
|
115
52
|
].join('\n'));
|
|
116
53
|
return;
|
|
117
54
|
}
|
|
@@ -129,7 +66,7 @@ export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry)
|
|
|
129
66
|
const builtinProviders = listBuiltinSubscriptionProviders().map((entry) => entry.provider);
|
|
130
67
|
ctx.print([
|
|
131
68
|
'Auth Review',
|
|
132
|
-
' connected-
|
|
69
|
+
' connected-host auth: managed outside goodvibes-agent',
|
|
133
70
|
` stored secrets: ${snapshot.secretKeyCount}`,
|
|
134
71
|
` built-in providers: ${builtinProviders.length}${builtinProviders.length > 0 ? ` (${builtinProviders.join(', ')})` : ''}`,
|
|
135
72
|
` active subscriptions: ${snapshot.activeSubscriptions}${snapshot.activeSubscriptions > 0 ? ` (${snapshot.providers.filter((provider) => provider.activeSubscription).map((provider) => provider.provider).join(', ')})` : ''}`,
|
|
@@ -289,7 +289,7 @@ async function handleStatus(_args: string[], context: CommandContext): Promise<v
|
|
|
289
289
|
export function renderPolicyUsage(): string {
|
|
290
290
|
return [
|
|
291
291
|
'Usage: /policy <subcommand>',
|
|
292
|
-
' /policy
|
|
292
|
+
' /policy status — show current policy state',
|
|
293
293
|
' load <bundle-id> [rule-count] — Load a candidate bundle',
|
|
294
294
|
' simulate [mode] — Run simulation (silent|warn|enforce)',
|
|
295
295
|
' diff — Show rule diff (current vs candidate)',
|
|
@@ -4,14 +4,10 @@ import { dispatchPolicyCommand } from './policy-dispatch.ts';
|
|
|
4
4
|
export const policyCommand: SlashCommand = {
|
|
5
5
|
name: 'policy',
|
|
6
6
|
aliases: ['pol'],
|
|
7
|
-
description: '
|
|
7
|
+
description: 'Review or manage versioned policy bundles (load, simulate, diff, promote, rollback).',
|
|
8
8
|
usage: '<subcommand> [args]',
|
|
9
9
|
argsHint: 'load|simulate|diff|lint|preflight|promote|rollback|status',
|
|
10
10
|
handler: async (args: string[], context: CommandContext): Promise<void> => {
|
|
11
|
-
if (args.length === 0 && context.openPolicyPanel) {
|
|
12
|
-
context.openPolicyPanel();
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
11
|
await dispatchPolicyCommand(args, context);
|
|
16
12
|
},
|
|
17
13
|
};
|
|
@@ -68,7 +68,7 @@ function formatTrustReview(bundle: TrustReviewBundle): string {
|
|
|
68
68
|
'Trust Review',
|
|
69
69
|
` permission mode: ${bundle.permissionMode}`,
|
|
70
70
|
` secrets stored: ${bundle.secretKeys.length}`,
|
|
71
|
-
` configured
|
|
71
|
+
` configured integrations: ${bundle.serviceNames.length}`,
|
|
72
72
|
` plugins: ${bundle.pluginSummary.total} (trusted ${bundle.pluginSummary.trusted}, limited ${bundle.pluginSummary.limited}, untrusted ${bundle.pluginSummary.untrusted}, quarantined ${bundle.pluginSummary.quarantined})`,
|
|
73
73
|
` MCP servers: ${bundle.mcpSummary.total} (constrained ${bundle.mcpSummary.constrained}, ask-on-risk ${bundle.mcpSummary.askOnRisk}, allow-all ${bundle.mcpSummary.allowAll}, blocked ${bundle.mcpSummary.blocked}, quarantined ${bundle.mcpSummary.quarantined})`,
|
|
74
74
|
].join('\n');
|
|
@@ -81,7 +81,7 @@ function inspectTrustBundle(path: string): string {
|
|
|
81
81
|
` captured: ${new Date(parsed.capturedAt).toISOString()}`,
|
|
82
82
|
` permission mode: ${parsed.permissionMode}`,
|
|
83
83
|
` secrets stored: ${parsed.secretKeys.length}`,
|
|
84
|
-
` configured
|
|
84
|
+
` configured integrations: ${parsed.serviceNames.length}`,
|
|
85
85
|
` plugins: ${parsed.pluginSummary.total}`,
|
|
86
86
|
` MCP servers: ${parsed.mcpSummary.total}`,
|
|
87
87
|
].join('\n');
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import type { CommandRegistry } from '../command-registry.ts';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
2
|
import { networkInterfaces } from 'node:os';
|
|
4
3
|
import {
|
|
5
4
|
buildCompanionConnectionInfo,
|
|
6
5
|
encodeConnectionPayload,
|
|
7
6
|
formatConnectionBlock,
|
|
8
7
|
generateQrMatrix,
|
|
9
|
-
getOrCreateCompanionToken,
|
|
10
8
|
renderQrToString,
|
|
11
9
|
} from '@pellux/goodvibes-sdk/platform/pairing';
|
|
12
10
|
import { GOODVIBES_AGENT_PAIRING_SURFACE } from '../../config/surface.ts';
|
|
13
11
|
import { resolveRuntimeEndpointBinding } from '../../cli/endpoints.ts';
|
|
12
|
+
import { connectedHostTokenRequiredMessage, readConnectedHostOperatorToken } from '../../runtime/connected-host-auth.ts';
|
|
14
13
|
import { requirePlatform, requireShellPaths } from './runtime-services.ts';
|
|
15
14
|
|
|
16
15
|
function getLocalNetworkIp(): string {
|
|
@@ -41,8 +40,11 @@ export function registerQrcodeRuntimeCommands(registry: CommandRegistry): void {
|
|
|
41
40
|
handler(_args, ctx) {
|
|
42
41
|
const shellPaths = requireShellPaths(ctx);
|
|
43
42
|
const configManager = requirePlatform(ctx).configManager;
|
|
44
|
-
const
|
|
45
|
-
|
|
43
|
+
const tokenRecord = readConnectedHostOperatorToken(shellPaths.homeDirectory);
|
|
44
|
+
if (!tokenRecord.token) {
|
|
45
|
+
ctx.print(connectedHostTokenRequiredMessage(tokenRecord.path));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
46
48
|
const binding = resolveRuntimeEndpointBinding(configManager, 'controlPlane');
|
|
47
49
|
const daemonUrl = `http://${urlHostForBindHost(binding.host)}:${binding.port}`;
|
|
48
50
|
const info = buildCompanionConnectionInfo({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { discoverRoutines, type DiscoveredRoutineRecord } from '../../agent/routine-discovery.ts';
|
|
2
|
-
import { AgentRoutineRegistry, type AgentRoutineRecord } from '../../agent/routine-registry.ts';
|
|
2
|
+
import { AgentRoutineRegistry, evaluateAgentRoutineReadiness, type AgentRoutineRecord } from '../../agent/routine-registry.ts';
|
|
3
|
+
import { buildAgentSkillRequirements, formatAgentSkillRequirement } from '../../agent/skill-registry.ts';
|
|
3
4
|
import {
|
|
4
5
|
buildRoutineSchedulePreview,
|
|
5
6
|
promoteRoutineToDaemonSchedule,
|
|
@@ -75,13 +76,17 @@ function requiredFlag(flags: ReadonlyMap<string, string>, key: string): string {
|
|
|
75
76
|
function summarizeRoutine(routine: AgentRoutineRecord): string {
|
|
76
77
|
const enabled = routine.enabled ? 'enabled' : 'disabled';
|
|
77
78
|
const tags = routine.tags.length > 0 ? ` tags=${routine.tags.join(',')}` : '';
|
|
78
|
-
|
|
79
|
+
const readiness = evaluateAgentRoutineReadiness(routine);
|
|
80
|
+
const ready = readiness.ready ? 'ready' : `needs ${readiness.missing.map(formatAgentSkillRequirement).join(',')}`;
|
|
81
|
+
return ` ${routine.id} ${enabled} ${routine.reviewState} ${ready} starts=${routine.startCount} ${routine.name} - ${routine.description}${tags}`;
|
|
79
82
|
}
|
|
80
83
|
|
|
81
|
-
function renderList(title: string, registry: AgentRoutineRegistry, routines: readonly AgentRoutineRecord[]): string {
|
|
84
|
+
function renderList(title: string, registry: AgentRoutineRegistry, routines: readonly AgentRoutineRecord[], emptyMessage?: string): string {
|
|
82
85
|
const snapshot = registry.snapshot();
|
|
83
86
|
if (routines.length === 0) {
|
|
84
|
-
return
|
|
87
|
+
return emptyMessage
|
|
88
|
+
? `${title}\n ${emptyMessage}`
|
|
89
|
+
: `${title}\n No local Agent routines yet. Create one with /routines create --name <name> --description <summary> --steps <steps>.`;
|
|
85
90
|
}
|
|
86
91
|
return [
|
|
87
92
|
`${title} (${routines.length})`,
|
|
@@ -92,10 +97,14 @@ function renderList(title: string, registry: AgentRoutineRegistry, routines: rea
|
|
|
92
97
|
}
|
|
93
98
|
|
|
94
99
|
function renderRoutine(routine: AgentRoutineRecord): string {
|
|
100
|
+
const readiness = evaluateAgentRoutineReadiness(routine);
|
|
95
101
|
return [
|
|
96
102
|
`Routine ${routine.name}`,
|
|
97
103
|
` id: ${routine.id}`,
|
|
98
104
|
` enabled: ${routine.enabled ? 'yes' : 'no'}`,
|
|
105
|
+
` readiness: ${readiness.ready ? 'ready' : 'needs setup'}`,
|
|
106
|
+
` requirements: ${routine.requirements.map(formatAgentSkillRequirement).join(', ') || '(none)'}`,
|
|
107
|
+
readiness.missing.length > 0 ? ` missing: ${readiness.missing.map(formatAgentSkillRequirement).join(', ')}` : '',
|
|
99
108
|
` review: ${routine.reviewState}`,
|
|
100
109
|
` source: ${routine.source}`,
|
|
101
110
|
` provenance: ${routine.provenance}`,
|
|
@@ -151,6 +160,14 @@ function frontmatterList(routine: DiscoveredRoutineRecord, key: string): readonl
|
|
|
151
160
|
return splitList(value);
|
|
152
161
|
}
|
|
153
162
|
|
|
163
|
+
function frontmatterAnyList(routine: DiscoveredRoutineRecord, keys: readonly string[]): readonly string[] {
|
|
164
|
+
for (const key of keys) {
|
|
165
|
+
const values = frontmatterList(routine, key);
|
|
166
|
+
if (values.length > 0) return values;
|
|
167
|
+
}
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
|
|
154
171
|
function printError(ctx: CommandContext, error: unknown): void {
|
|
155
172
|
ctx.print(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
156
173
|
}
|
|
@@ -185,6 +202,10 @@ async function importDiscoveredRoutine(args: readonly string[], ctx: CommandCont
|
|
|
185
202
|
steps: discovered.steps,
|
|
186
203
|
tags: frontmatterList(discovered, 'tags'),
|
|
187
204
|
triggers: frontmatterList(discovered, 'triggers'),
|
|
205
|
+
requirements: buildAgentSkillRequirements({
|
|
206
|
+
env: frontmatterAnyList(discovered, ['requiresEnv', 'requires-env', 'requires_env']),
|
|
207
|
+
commands: frontmatterAnyList(discovered, ['requiresCommands', 'requires-commands', 'requires_commands', 'commands']),
|
|
208
|
+
}),
|
|
188
209
|
enabled: parsed.flags.get('enabled') === 'true',
|
|
189
210
|
source: 'imported',
|
|
190
211
|
provenance: `discovered:${discovered.origin}:${discovered.path}`,
|
|
@@ -231,6 +252,11 @@ export async function runRoutinesRuntimeCommand(args: readonly string[], ctx: Co
|
|
|
231
252
|
ctx.print(renderList('Enabled Agent Routines', routineRegistry, snapshot.enabledRoutines));
|
|
232
253
|
return;
|
|
233
254
|
}
|
|
255
|
+
if (sub === 'attention' || sub === 'needs-setup') {
|
|
256
|
+
const routines = routineRegistry.list().filter((routine) => !evaluateAgentRoutineReadiness(routine).ready);
|
|
257
|
+
ctx.print(renderList('Agent Routines needing setup', routineRegistry, routines, 'No local Agent routines need setup.'));
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
234
260
|
if (sub === 'discover' || sub === 'discovered') {
|
|
235
261
|
ctx.print(renderDiscoveredRoutines(await discoverRoutines(requireShellPaths(ctx))));
|
|
236
262
|
return;
|
|
@@ -284,6 +310,10 @@ export async function runRoutinesRuntimeCommand(args: readonly string[], ctx: Co
|
|
|
284
310
|
steps,
|
|
285
311
|
triggers: splitList(parsed.flags.get('triggers')),
|
|
286
312
|
tags: splitList(parsed.flags.get('tags')),
|
|
313
|
+
requirements: buildAgentSkillRequirements({
|
|
314
|
+
env: splitList(parsed.flags.get('requires-env')),
|
|
315
|
+
commands: splitList(parsed.flags.get('requires-command') ?? parsed.flags.get('requires-commands')),
|
|
316
|
+
}),
|
|
287
317
|
enabled: parsed.flags.get('enabled') === 'true',
|
|
288
318
|
source: 'user',
|
|
289
319
|
provenance: 'slash-command',
|
|
@@ -304,6 +334,12 @@ export async function runRoutinesRuntimeCommand(args: readonly string[], ctx: Co
|
|
|
304
334
|
steps: parsed.flags.get('steps'),
|
|
305
335
|
triggers: parsed.flags.has('triggers') ? splitList(parsed.flags.get('triggers')) : undefined,
|
|
306
336
|
tags: parsed.flags.has('tags') ? splitList(parsed.flags.get('tags')) : undefined,
|
|
337
|
+
requirements: parsed.flags.has('requires-env') || parsed.flags.has('requires-command') || parsed.flags.has('requires-commands')
|
|
338
|
+
? buildAgentSkillRequirements({
|
|
339
|
+
env: splitList(parsed.flags.get('requires-env')),
|
|
340
|
+
commands: splitList(parsed.flags.get('requires-command') ?? parsed.flags.get('requires-commands')),
|
|
341
|
+
})
|
|
342
|
+
: undefined,
|
|
307
343
|
provenance: 'slash-command',
|
|
308
344
|
});
|
|
309
345
|
ctx.print(`Updated Agent routine ${updated.id}: ${updated.name}`);
|
|
@@ -326,8 +362,10 @@ export async function runRoutinesRuntimeCommand(args: readonly string[], ctx: Co
|
|
|
326
362
|
return;
|
|
327
363
|
}
|
|
328
364
|
const routine = routineRegistry.markStarted(id);
|
|
365
|
+
const readiness = evaluateAgentRoutineReadiness(routine);
|
|
329
366
|
ctx.print([
|
|
330
367
|
`Started Agent routine ${routine.id}: ${routine.name}`,
|
|
368
|
+
` readiness: ${readiness.ready ? 'ready' : `needs setup (${readiness.missing.map(formatAgentSkillRequirement).join(', ')})`}`,
|
|
331
369
|
' policy: same main conversation; no hidden job, runtime mutation, or external side effect was started',
|
|
332
370
|
'',
|
|
333
371
|
routine.steps,
|
|
@@ -373,7 +411,7 @@ export async function runRoutinesRuntimeCommand(args: readonly string[], ctx: Co
|
|
|
373
411
|
ctx.print(`Deleted Agent routine ${removed.id}: ${removed.name}`);
|
|
374
412
|
return;
|
|
375
413
|
}
|
|
376
|
-
ctx.print('Usage: /routines [list|enabled|discover|import-discovered|search|show|receipts|reconcile|receipt|create|update|enable|disable|start|review|stale|promote|delete]');
|
|
414
|
+
ctx.print('Usage: /routines [list|enabled|attention|discover|import-discovered|search|show|receipts|reconcile|receipt|create|update|enable|disable|start|review|stale|promote|delete]');
|
|
377
415
|
} catch (error) {
|
|
378
416
|
printError(ctx, error);
|
|
379
417
|
}
|
|
@@ -384,7 +422,7 @@ export function registerRoutinesRuntimeCommands(registry: CommandRegistry): void
|
|
|
384
422
|
name: 'routines',
|
|
385
423
|
aliases: ['routine'],
|
|
386
424
|
description: 'Manage local GoodVibes Agent routines',
|
|
387
|
-
usage: '[list|enabled|discover|import-discovered <name> --yes|search <query>|show <id>|receipts|reconcile|receipt <id>|create --name <name> --description <summary> --steps <steps
|
|
425
|
+
usage: '[list|enabled|attention|discover|import-discovered <name> --yes|search <query>|show <id>|receipts|reconcile|receipt <id>|create --name <name> --description <summary> --steps <steps> [--requires-env A,B] [--requires-command gh,jq]|update <id> [--name ...] [--description ...] [--steps ...]|enable <id>|disable <id>|start <id>|review <id>|stale <id> <reason...>|promote <id> --cron <expr> [--delivery-channel slack] --yes|delete <id> --yes]',
|
|
388
426
|
handler: runRoutinesRuntimeCommand,
|
|
389
427
|
});
|
|
390
428
|
}
|
|
@@ -22,7 +22,6 @@ import { GOODVIBES_AGENT_SURFACE_ROOT } from '../../config/surface.ts';
|
|
|
22
22
|
import type { ProviderApi } from '@pellux/goodvibes-sdk/platform/providers';
|
|
23
23
|
import type {
|
|
24
24
|
ShellAgentManagerService,
|
|
25
|
-
ShellAcpManagerService,
|
|
26
25
|
ShellAutomationManagerService,
|
|
27
26
|
ShellAutomationManagerRuntimeService,
|
|
28
27
|
ShellModeManagerService,
|
|
@@ -32,7 +31,7 @@ import type {
|
|
|
32
31
|
|
|
33
32
|
function requireContextValue<T>(value: T | null | undefined, name: string): T {
|
|
34
33
|
if (value == null) {
|
|
35
|
-
throw new Error(`commandContext.${name} is
|
|
34
|
+
throw new Error(`commandContext.${name} is unavailable in this Agent runtime`);
|
|
36
35
|
}
|
|
37
36
|
return value;
|
|
38
37
|
}
|
|
@@ -274,10 +273,6 @@ export function requireAgentManager(context: CommandContext): ShellAgentManagerS
|
|
|
274
273
|
return requireContextValue(context.ops.agentManager, 'ops.agentManager') as ShellAgentManagerService;
|
|
275
274
|
}
|
|
276
275
|
|
|
277
|
-
export function requireAcpManager(context: CommandContext): ShellAcpManagerService {
|
|
278
|
-
return requireContextValue(context.ops.acpManager, 'ops.acpManager') as ShellAcpManagerService;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
276
|
export function requireModeManager(context: CommandContext): ShellModeManagerService {
|
|
282
277
|
return requireContextValue(context.ops.modeManager, 'ops.modeManager') as ShellModeManagerService;
|
|
283
278
|
}
|
|
@@ -285,11 +280,3 @@ export function requireModeManager(context: CommandContext): ShellModeManagerSer
|
|
|
285
280
|
export function requireAutomationManager(context: CommandContext): ShellAutomationManagerRuntimeService {
|
|
286
281
|
return requireContextValue(context.ops.automationManager, 'ops.automationManager') as ShellAutomationManagerRuntimeService;
|
|
287
282
|
}
|
|
288
|
-
|
|
289
|
-
export function requireSandboxSessionRegistry(context: CommandContext) {
|
|
290
|
-
return requireContextValue(context.workspace.sandboxSessionRegistry, 'workspace.sandboxSessionRegistry');
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
export function requireWorktreeRegistry(context: CommandContext) {
|
|
294
|
-
return requireContextValue(context.workspace.worktreeRegistry, 'workspace.worktreeRegistry');
|
|
295
|
-
}
|
|
@@ -10,16 +10,11 @@ export function registerSecurityRuntimeCommands(registry: CommandRegistry): void
|
|
|
10
10
|
description: 'Inspect security posture, attack paths, and review state',
|
|
11
11
|
usage: '[review | attack-paths | tokens]',
|
|
12
12
|
handler(args, ctx) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
ctx.print('Security panel is not available in this runtime.');
|
|
13
|
+
const subcommand = args[0]?.toLowerCase() ?? 'review';
|
|
14
|
+
if (subcommand === 'open' || subcommand === 'panel') {
|
|
15
|
+
ctx.print('Security panels are not part of the Agent workspace. Use /security review.');
|
|
19
16
|
return;
|
|
20
17
|
}
|
|
21
|
-
|
|
22
|
-
const subcommand = args[0]?.toLowerCase() ?? 'review';
|
|
23
18
|
const audit = requireTokenAuditor(ctx).auditAll(Date.now());
|
|
24
19
|
const securitySnapshot = requireReadModels(ctx).security.getSnapshot();
|
|
25
20
|
const policySnapshot = ctx.extensions.policyRuntimeState?.getSnapshot();
|
|
@@ -144,7 +144,7 @@ export function registerSessionContentCommands(registry: CommandRegistry): void
|
|
|
144
144
|
if (meta.title) ctx.session.conversationManager.title = meta.title;
|
|
145
145
|
ctx.session.conversationManager.rebuildHistory();
|
|
146
146
|
ctx.renderRequest();
|
|
147
|
-
ctx.print(`Session loaded: ${args[0]} (${messages.length} messages)${agentRecords.length > 0 ? ` [ignored ${agentRecords.length}
|
|
147
|
+
ctx.print(`Session loaded: ${args[0]} (${messages.length} messages)${agentRecords.length > 0 ? ` [ignored ${agentRecords.length} host-owned local agent record${agentRecords.length !== 1 ? 's' : ''}]` : ''}`);
|
|
148
148
|
} catch (e) {
|
|
149
149
|
ctx.print(`Failed to load session: ${summarizeError(e)}`);
|
|
150
150
|
}
|
|
@@ -6,7 +6,7 @@ import type { TranscriptEventKind } from '@pellux/goodvibes-sdk/platform/core';
|
|
|
6
6
|
import type { ConversationTitleSource } from '../../core/conversation';
|
|
7
7
|
import type { SessionReturnContextSummary } from '@/runtime/index.ts';
|
|
8
8
|
import { formatReturnContextForDisplay, getReturnContextMode, maybeAssistReturnContextSummary } from '@/runtime/index.ts';
|
|
9
|
-
import {
|
|
9
|
+
import { requireProviderApi, requireSessionManager } from './runtime-services.ts';
|
|
10
10
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
11
11
|
import { requireYesFlag, stripYesFlag } from './confirmation.ts';
|
|
12
12
|
|
|
@@ -81,18 +81,8 @@ function buildTranscriptReviewLines(
|
|
|
81
81
|
|
|
82
82
|
function reopenPanelsFromReturnContext(ctx: CommandContext, summary: SessionReturnContextSummary | undefined): string[] {
|
|
83
83
|
if (!summary?.openPanels || summary.openPanels.length === 0) return [];
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
for (const panelId of summary.openPanels.slice(0, 4)) {
|
|
87
|
-
try {
|
|
88
|
-
panelManager.open(panelId);
|
|
89
|
-
reopened.push(panelId);
|
|
90
|
-
} catch {
|
|
91
|
-
// Ignore unknown or currently unavailable panel ids during resume.
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
if (reopened.length > 0) panelManager.show();
|
|
95
|
-
return reopened;
|
|
84
|
+
ctx.print(` Saved panel state ignored: ${summary.openPanels.slice(0, 4).join(', ')}. Use /agent for the Agent operator workspace.`);
|
|
85
|
+
return [];
|
|
96
86
|
}
|
|
97
87
|
|
|
98
88
|
function printSessionExport(
|
|
@@ -182,7 +172,7 @@ export async function handleSessionWorkflowCommand(args: string[], ctx: CommandC
|
|
|
182
172
|
session.returnContext.activeTasks ? `active=${session.returnContext.activeTasks}` : null,
|
|
183
173
|
session.returnContext.blockedTasks ? `blocked=${session.returnContext.blockedTasks}` : null,
|
|
184
174
|
session.returnContext.pendingApprovals ? `approvals=${session.returnContext.pendingApprovals}` : null,
|
|
185
|
-
session.returnContext.openPanels?.length ? `
|
|
175
|
+
session.returnContext.openPanels?.length ? `saved-panel-state-ignored=${session.returnContext.openPanels.slice(0, 3).join(',')}` : null,
|
|
186
176
|
].filter(Boolean).join(' ');
|
|
187
177
|
if (posture) lines.push(` posture: ${posture}`);
|
|
188
178
|
}
|
|
@@ -258,6 +248,7 @@ export async function handleSessionWorkflowCommand(args: string[], ctx: CommandC
|
|
|
258
248
|
const returnContextMode = getReturnContextMode(ctx.platform.configManager);
|
|
259
249
|
if (returnContextMode !== 'off' && meta.returnContext) {
|
|
260
250
|
for (const line of formatReturnContextForDisplay(meta.returnContext)) {
|
|
251
|
+
if (line.startsWith('Open panels:')) continue;
|
|
261
252
|
ctx.print(` ${line}`);
|
|
262
253
|
}
|
|
263
254
|
if (reopenedPanels.length > 0) {
|
|
@@ -115,6 +115,10 @@ export function registerShellCoreCommands(registry: CommandRegistry): void {
|
|
|
115
115
|
if (ctx.openSelection) {
|
|
116
116
|
const items: SelectionItem[] = [
|
|
117
117
|
{ id: '/agent', label: '/agent', detail: 'Open the Agent operator workspace', category: 'Agent Operator' },
|
|
118
|
+
{ id: '/agent setup', label: '/agent setup', detail: 'Open the Agent setup workspace', category: 'Agent Operator' },
|
|
119
|
+
{ id: '/agent channels', label: '/agent channels', detail: 'Open channel readiness and delivery safety', category: 'Agent Operator' },
|
|
120
|
+
{ id: '/agent knowledge', label: '/agent knowledge', detail: 'Open isolated Agent Knowledge workflows', category: 'Agent Operator' },
|
|
121
|
+
{ id: '/agent voice-media', label: '/agent voice-media', detail: 'Open voice, TTS, image, browser, and media setup', category: 'Agent Operator' },
|
|
118
122
|
{ id: '/home', label: '/home', detail: 'Alias for the Agent operator workspace', category: 'Agent Operator' },
|
|
119
123
|
{ id: '/brief', label: '/brief', detail: 'Show a concise Agent operator briefing and next actions', category: 'Agent Operator' },
|
|
120
124
|
{ id: '/knowledge', label: '/knowledge', detail: 'Inspect isolated Agent Knowledge status, ask/search, and ingest flows', category: 'Agent Operator' },
|
|
@@ -124,7 +128,7 @@ export function registerShellCoreCommands(registry: CommandRegistry): void {
|
|
|
124
128
|
{ id: '/routines', label: '/routines', detail: 'Create, review, start, and promote Agent routines explicitly', category: 'Agent Operator' },
|
|
125
129
|
{ id: '/delegate', label: '/delegate [task]', detail: 'Explicit build/fix/review handoff to GoodVibes TUI', category: 'Agent Operator' },
|
|
126
130
|
{ id: '/channels', label: '/channels', detail: 'Inspect messaging-channel readiness without sending messages', category: 'Agent Operator' },
|
|
127
|
-
{ id: '/pair', label: '/pair', detail: 'Pair companion clients through connected GoodVibes
|
|
131
|
+
{ id: '/pair', label: '/pair', detail: 'Pair companion clients through connected GoodVibes host', category: 'Agent Operator' },
|
|
128
132
|
{ id: '/model', label: '/model [id]', detail: 'Select LLM model', category: 'Model & Provider' },
|
|
129
133
|
{ id: '/provider', label: '/provider [name]', detail: 'Switch provider', category: 'Model & Provider' },
|
|
130
134
|
{ id: '/effort', label: '/effort [level]', detail: 'Reasoning effort (instant/low/medium/high)', category: 'Model & Provider' },
|
|
@@ -156,7 +160,9 @@ export function registerShellCoreCommands(registry: CommandRegistry): void {
|
|
|
156
160
|
{ id: '/paste', label: '/paste', detail: 'Insert clipboard text or image into the prompt', category: 'Tools & System' },
|
|
157
161
|
{ id: '/shortcuts', label: '/shortcuts', detail: 'View keyboard shortcuts reference', category: 'Tools & System' },
|
|
158
162
|
{ id: '/commands', label: '/commands', detail: 'Browse all commands in a scrollable list', category: 'Tools & System' },
|
|
163
|
+
{ id: '/compat', label: '/compat', detail: 'Inspect connected-host and Agent Knowledge compatibility', category: 'Tools & System' },
|
|
159
164
|
{ id: '/secrets', label: '/secrets set|link|get|test|list|delete', detail: 'Manage encrypted and provider-backed secrets', category: 'Tools & System' },
|
|
165
|
+
{ id: '/bundle', label: '/bundle export|inspect|import', detail: 'Manage redacted Agent support bundles', category: 'Tools & System' },
|
|
160
166
|
{ id: '/help', label: '/help', detail: 'This help', category: 'Tools & System' },
|
|
161
167
|
{ id: '/quit', label: '/quit', detail: 'Exit', category: 'Tools & System' },
|
|
162
168
|
];
|
|
@@ -172,7 +178,7 @@ export function registerShellCoreCommands(registry: CommandRegistry): void {
|
|
|
172
178
|
});
|
|
173
179
|
return;
|
|
174
180
|
}
|
|
175
|
-
ctx.print('Use /help to open the help modal. Commands: /agent, /brief, /knowledge, /memory, /personas, /agent-skills, /routines, /channels, /delegate, /model, /provider, /config, /paste, /sessions, /bookmarks, /save, /load, /undo, /redo, /retry, /clear, /reset, /compact, /export, /title, /effort, /expand, /collapse, /quit');
|
|
181
|
+
ctx.print('Use /help to open the help modal. Commands: /agent, /brief, /knowledge, /memory, /personas, /agent-skills, /routines, /channels, /delegate, /model, /provider, /config, /compat, /bundle, /paste, /sessions, /bookmarks, /save, /load, /undo, /redo, /retry, /clear, /reset, /compact, /export, /title, /effort, /expand, /collapse, /quit');
|
|
176
182
|
},
|
|
177
183
|
});
|
|
178
184
|
|