@pellux/goodvibes-agent 0.1.111 → 0.1.113
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 +22 -0
- package/README.md +3 -3
- package/dist/package/main.js +9921 -9868
- package/docs/getting-started.md +3 -3
- package/package.json +1 -1
- package/src/cli/help.ts +4 -1
- package/src/cli/local-library-command.ts +90 -1
- package/src/cli/parser.ts +0 -8
- package/src/cli/service-posture.ts +1 -8
- package/src/cli/status.ts +1 -30
- package/src/cli/types.ts +0 -1
- package/src/input/agent-workspace-categories.ts +5 -7
- package/src/input/agent-workspace-snapshot.ts +2 -10
- package/src/input/agent-workspace-types.ts +2 -3
- package/src/input/commands/brief-runtime.ts +1 -1
- package/src/input/commands/channels-runtime.ts +397 -35
- package/src/input/commands/experience-runtime.ts +4 -9
- package/src/input/commands/health-runtime.ts +26 -6
- package/src/input/commands/mcp-runtime.ts +51 -26
- package/src/input/commands/memory.ts +10 -10
- package/src/input/commands/planning-runtime.ts +4 -9
- package/src/input/commands/provider-accounts-runtime.ts +2 -3
- package/src/input/commands/qrcode-runtime.ts +48 -9
- package/src/input/commands/recall-bundle.ts +16 -16
- package/src/input/commands/recall-capture.ts +18 -18
- package/src/input/commands/recall-query.ts +22 -22
- package/src/input/commands/recall-review.ts +12 -12
- package/src/input/commands/tasks-runtime.ts +9 -15
- package/src/input/commands/work-plan-runtime.ts +5 -19
- package/src/input/commands.ts +2 -7
- package/src/renderer/agent-workspace.ts +1 -2
- package/src/renderer/ui-factory.ts +1 -1
- package/src/runtime/onboarding/derivation.ts +6 -67
- package/src/version.ts +1 -1
package/docs/getting-started.md
CHANGED
|
@@ -96,9 +96,9 @@ Memory, personas, routines, and reusable Agent skills are local to GoodVibes Age
|
|
|
96
96
|
/channels
|
|
97
97
|
/agent-skills create --name "Morning Brief" --description "Daily briefing flow" --procedure "Check tasks, approvals, calendar, and unread state before summarizing." --enabled true
|
|
98
98
|
/agent-skills enabled
|
|
99
|
-
/skills
|
|
100
|
-
/
|
|
101
|
-
/
|
|
99
|
+
/skills list
|
|
100
|
+
/memory add fact "Prefers concise morning briefings" --scope project --tags preference
|
|
101
|
+
/memory search morning
|
|
102
102
|
```
|
|
103
103
|
|
|
104
104
|
The active persona plus enabled Agent routines, reviewed memory, and skills are injected into the main serial assistant conversation. Starting a routine records local usage and prints its steps; it does not spawn background agents or automation jobs. Promoting a routine to a schedule is an explicit `schedules.create` call, requires `--yes`, writes a local redacted promotion receipt, and preserves the rule that Agent Knowledge never falls back to default Knowledge/Wiki or non-Agent knowledge segments.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.113",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "GoodVibes personal operator assistant TUI with a proactive Agent product brain, isolated Agent Knowledge, local profiles, routines, skills, personas, and explicit build delegation.",
|
|
6
6
|
"type": "module",
|
package/src/cli/help.ts
CHANGED
|
@@ -188,6 +188,8 @@ const COMMAND_HELP: Record<string, CommandHelp> = {
|
|
|
188
188
|
'skills list',
|
|
189
189
|
'skills enabled',
|
|
190
190
|
'skills active',
|
|
191
|
+
'skills discover',
|
|
192
|
+
'skills import-discovered <name> [--enabled] --yes',
|
|
191
193
|
'skills search <query>',
|
|
192
194
|
'skills show <id>',
|
|
193
195
|
'skills create --name <name> --description <summary> --procedure <steps> [--tags a,b] [--triggers a,b] [--enabled]',
|
|
@@ -202,6 +204,8 @@ const COMMAND_HELP: Record<string, CommandHelp> = {
|
|
|
202
204
|
summary: 'Manage reusable Agent-local procedures and skill bundles for the main conversation.',
|
|
203
205
|
examples: [
|
|
204
206
|
'skills list',
|
|
207
|
+
'skills discover',
|
|
208
|
+
'skills import-discovered "Daily Brief" --enabled --yes',
|
|
205
209
|
'skills create --name "Daily Brief" --description "Summarize operator state" --procedure "Review Agent Knowledge, work plans, approvals, and routines" --enabled',
|
|
206
210
|
'skills bundle create --name "Ops Pack" --description "Daily operations bundle" --skills daily-brief --enabled',
|
|
207
211
|
'skills delete daily-brief --yes',
|
|
@@ -366,7 +370,6 @@ const HELP_ALIASES: Record<string, string> = {
|
|
|
366
370
|
skill: 'skills',
|
|
367
371
|
'agent-skills': 'skills',
|
|
368
372
|
memories: 'memory',
|
|
369
|
-
recall: 'memory',
|
|
370
373
|
subscriptions: 'subscription',
|
|
371
374
|
secret: 'secrets',
|
|
372
375
|
session: 'sessions',
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createShellPathService } from '@/runtime/index.ts';
|
|
2
2
|
import { AgentPersonaRegistry, type AgentPersonaRecord } from '../agent/persona-registry.ts';
|
|
3
|
+
import { discoverSkills, type SkillRecord } from '../agent/skill-discovery.ts';
|
|
3
4
|
import {
|
|
4
5
|
AgentSkillRegistry,
|
|
5
6
|
type AgentSkillBundleRecord,
|
|
@@ -107,6 +108,13 @@ function skillRegistry(runtime: CliCommandRuntime): AgentSkillRegistry {
|
|
|
107
108
|
}));
|
|
108
109
|
}
|
|
109
110
|
|
|
111
|
+
function shellPaths(runtime: CliCommandRuntime): ReturnType<typeof createShellPathService> {
|
|
112
|
+
return createShellPathService({
|
|
113
|
+
workingDirectory: runtime.workingDirectory,
|
|
114
|
+
homeDirectory: runtime.homeDirectory,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
110
118
|
function summarizePersona(persona: AgentPersonaRecord, activePersonaId: string | null): string {
|
|
111
119
|
const active = persona.id === activePersonaId ? 'active' : 'available';
|
|
112
120
|
const tags = persona.tags.length > 0 ? ` tags=${persona.tags.join(',')}` : '';
|
|
@@ -174,6 +182,52 @@ function renderSkillList(title: string, path: string, skills: readonly AgentSkil
|
|
|
174
182
|
].join('\n');
|
|
175
183
|
}
|
|
176
184
|
|
|
185
|
+
function summarizeDiscoveredSkill(skill: SkillRecord): string {
|
|
186
|
+
const description = skill.description ? ` - ${skill.description}` : '';
|
|
187
|
+
const dependencies = skill.dependencies.length > 0 ? ` deps=${skill.dependencies.join(',')}` : '';
|
|
188
|
+
const includes = skill.includes.length > 0 ? ` includes=${skill.includes.join(',')}` : '';
|
|
189
|
+
return [
|
|
190
|
+
` ${skill.name} ${skill.origin}${description}${dependencies}${includes}`,
|
|
191
|
+
` path: ${skill.path}`,
|
|
192
|
+
].join('\n');
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function renderDiscoveredSkillList(skills: readonly SkillRecord[]): string {
|
|
196
|
+
if (skills.length === 0) {
|
|
197
|
+
return [
|
|
198
|
+
'Discovered Agent skill files',
|
|
199
|
+
' No SKILL.md or .md skill files found in Agent skill folders.',
|
|
200
|
+
' Search roots: .goodvibes/skills, .goodvibes/agent/skills, ~/.goodvibes/skills, ~/.goodvibes/agent/skills',
|
|
201
|
+
].join('\n');
|
|
202
|
+
}
|
|
203
|
+
return [
|
|
204
|
+
`Discovered Agent skill files (${skills.length})`,
|
|
205
|
+
...skills.map(summarizeDiscoveredSkill),
|
|
206
|
+
'',
|
|
207
|
+
'Import one with: goodvibes-agent skills import-discovered <name> --yes',
|
|
208
|
+
].join('\n');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function discoveredSkillLookupValues(skill: SkillRecord): readonly string[] {
|
|
212
|
+
const slug = skill.name.trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
|
213
|
+
const basename = skill.path.split(/[\\/]/).pop()?.replace(/\.md$/i, '') ?? '';
|
|
214
|
+
return [skill.name, slug, skill.path, basename]
|
|
215
|
+
.map((value) => value.trim().toLowerCase())
|
|
216
|
+
.filter(Boolean);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function findDiscoveredSkill(skills: readonly SkillRecord[], idOrName: string): SkillRecord | null {
|
|
220
|
+
const lookup = idOrName.trim().toLowerCase();
|
|
221
|
+
if (!lookup) return null;
|
|
222
|
+
return skills.find((skill) => discoveredSkillLookupValues(skill).includes(lookup)) ?? null;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function discoveredFrontmatterList(skill: SkillRecord, key: string): readonly string[] {
|
|
226
|
+
const value = skill.frontmatter[key];
|
|
227
|
+
if (!value) return [];
|
|
228
|
+
return value.split(',').map((entry) => entry.trim()).filter(Boolean);
|
|
229
|
+
}
|
|
230
|
+
|
|
177
231
|
function renderBundleList(title: string, path: string, bundles: readonly AgentSkillBundleRecord[]): string {
|
|
178
232
|
if (bundles.length === 0) {
|
|
179
233
|
return [
|
|
@@ -231,7 +285,7 @@ function usagePersonas(): string {
|
|
|
231
285
|
}
|
|
232
286
|
|
|
233
287
|
function usageSkills(): string {
|
|
234
|
-
return 'Usage: goodvibes-agent skills [list|enabled|active|search <query>|show <id>|create|update <id>|enable <id>|disable <id>|review <id>|stale <id> <reason>|delete <id> --yes|bundle ...]';
|
|
288
|
+
return 'Usage: goodvibes-agent skills [list|enabled|active|discover|import-discovered <name> --yes|search <query>|show <id>|create|update <id>|enable <id>|disable <id>|review <id>|stale <id> <reason>|delete <id> --yes|bundle ...]';
|
|
235
289
|
}
|
|
236
290
|
|
|
237
291
|
function usageBundles(): string {
|
|
@@ -453,6 +507,41 @@ export async function handleSkillsCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
453
507
|
snapshot.enabledBundles.length > 0 ? renderBundleList('Enabled Agent skill bundles', snapshot.path, snapshot.enabledBundles) : '',
|
|
454
508
|
].filter(Boolean).join('\n\n'));
|
|
455
509
|
}
|
|
510
|
+
if (normalized === 'discover') {
|
|
511
|
+
const discovered = await discoverSkills(shellPaths(runtime));
|
|
512
|
+
return success(runtime, 'agent.skills.discover', { skills: discovered }, renderDiscoveredSkillList(discovered));
|
|
513
|
+
}
|
|
514
|
+
if (normalized === 'import-discovered' || normalized === 'import-skill') {
|
|
515
|
+
const options = parseOptions(rest);
|
|
516
|
+
const name = options.positionals.join(' ').trim();
|
|
517
|
+
if (!name) return failure(runtime, 'invalid_skill_command', 'Usage: goodvibes-agent skills import-discovered <name> [--enabled] --yes', 2);
|
|
518
|
+
const discovered = findDiscoveredSkill(await discoverSkills(shellPaths(runtime)), name);
|
|
519
|
+
if (!discovered) {
|
|
520
|
+
return failure(runtime, 'skill_discovery_not_found', `Unknown discovered Agent skill: ${name}\nRun goodvibes-agent skills discover to inspect available skill files.`, 1);
|
|
521
|
+
}
|
|
522
|
+
if (!hasFlag(options, 'yes')) {
|
|
523
|
+
return success(runtime, 'agent.skills.import_discovered.preview', { skill: discovered }, [
|
|
524
|
+
'Agent skill import preview',
|
|
525
|
+
` name: ${discovered.name}`,
|
|
526
|
+
` origin: ${discovered.origin}`,
|
|
527
|
+
` path: ${discovered.path}`,
|
|
528
|
+
` description: ${discovered.description || '(none)'}`,
|
|
529
|
+
` procedure characters: ${discovered.body.length}`,
|
|
530
|
+
' next: rerun with --yes to import into the Agent-local skill registry',
|
|
531
|
+
].join('\n'));
|
|
532
|
+
}
|
|
533
|
+
const skill = registry.create({
|
|
534
|
+
name: discovered.name,
|
|
535
|
+
description: discovered.description || `Imported skill from ${discovered.origin} skill file.`,
|
|
536
|
+
procedure: discovered.body,
|
|
537
|
+
tags: discoveredFrontmatterList(discovered, 'tags'),
|
|
538
|
+
triggers: discoveredFrontmatterList(discovered, 'triggers'),
|
|
539
|
+
enabled: hasFlag(options, 'enabled'),
|
|
540
|
+
source: 'imported',
|
|
541
|
+
provenance: `discovered:${discovered.origin}:${discovered.path}`,
|
|
542
|
+
});
|
|
543
|
+
return success(runtime, 'agent.skills.import_discovered', skill, `Imported Agent skill ${skill.id}: ${skill.name}${skill.enabled ? ' (enabled)' : ''}`);
|
|
544
|
+
}
|
|
456
545
|
if (normalized === 'search' || normalized === 'find') {
|
|
457
546
|
const query = rest.join(' ').trim();
|
|
458
547
|
const results = registry.search(query);
|
package/src/cli/parser.ts
CHANGED
|
@@ -26,7 +26,6 @@ const COMMAND_ALIASES: Readonly<Record<string, GoodVibesCliCommand>> = {
|
|
|
26
26
|
'agent-skills': 'skills',
|
|
27
27
|
memory: 'memory',
|
|
28
28
|
memories: 'memory',
|
|
29
|
-
recall: 'memory',
|
|
30
29
|
routines: 'routines',
|
|
31
30
|
routine: 'routines',
|
|
32
31
|
auth: 'auth',
|
|
@@ -66,7 +65,6 @@ function createDefaultFlags(): GoodVibesCliFlags {
|
|
|
66
65
|
provider: undefined,
|
|
67
66
|
model: undefined,
|
|
68
67
|
agentProfile: undefined,
|
|
69
|
-
daemonHome: undefined,
|
|
70
68
|
runtimeUrl: undefined,
|
|
71
69
|
workingDir: undefined,
|
|
72
70
|
help: false,
|
|
@@ -286,12 +284,6 @@ export function parseGoodVibesCli(
|
|
|
286
284
|
if (consumed.value !== undefined) flags = withFlag(flags, 'agentProfile', consumed.value);
|
|
287
285
|
continue;
|
|
288
286
|
}
|
|
289
|
-
if (name === '--daemon-home') {
|
|
290
|
-
const consumed = getValue(argv, index, inlineValue, name, errors);
|
|
291
|
-
index = consumed.nextIndex;
|
|
292
|
-
if (consumed.value !== undefined) flags = withFlag(flags, 'daemonHome', consumed.value);
|
|
293
|
-
continue;
|
|
294
|
-
}
|
|
295
287
|
if (name === '--runtime-url' || name === '--runtime') {
|
|
296
288
|
const consumed = getValue(argv, index, inlineValue, name, errors);
|
|
297
289
|
index = consumed.nextIndex;
|
|
@@ -186,12 +186,6 @@ export async function buildCliServicePosture(
|
|
|
186
186
|
if (serverBackedEnabled && !config.enabled) {
|
|
187
187
|
issues.push('Connected-service settings are present, but Agent service ownership is disabled by design.');
|
|
188
188
|
}
|
|
189
|
-
if (config.enabled && !config.autostart) {
|
|
190
|
-
issues.push('Connected-service autostart is off.');
|
|
191
|
-
}
|
|
192
|
-
if (config.enabled && !config.restartOnFailure) {
|
|
193
|
-
issues.push('Connected-service restart-on-failure is off.');
|
|
194
|
-
}
|
|
195
189
|
for (const endpoint of endpoints) {
|
|
196
190
|
if (endpoint.enabled && options.probe && endpoint.reachable === false) {
|
|
197
191
|
issues.push(`${endpoint.label} is enabled but not reachable on ${endpoint.binding.host}:${endpoint.binding.port}.`);
|
|
@@ -233,8 +227,7 @@ export function formatCliServicePosture(posture: CliServicePosture, json = false
|
|
|
233
227
|
' ownership: managed outside goodvibes-agent',
|
|
234
228
|
' Agent owns lifecycle: no',
|
|
235
229
|
` external host config present: ${yesNo(posture.config.enabled)}`,
|
|
236
|
-
|
|
237
|
-
` external host restart config: ${yesNo(posture.config.restartOnFailure)}`,
|
|
230
|
+
' external host lifecycle config: ignored by Agent',
|
|
238
231
|
` legacy host switch present: ${yesNo(posture.config.daemonEnabled)}`,
|
|
239
232
|
` log: ${posture.log.path ?? 'n/a'} (${posture.log.exists ? 'present' : 'missing'})`,
|
|
240
233
|
...(posture.log.readError ? [` log read error: ${posture.log.readError}`] : []),
|
package/src/cli/status.ts
CHANGED
|
@@ -99,8 +99,6 @@ function bindLine(label: string, enabled: unknown, binding: { readonly hostMode:
|
|
|
99
99
|
export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliDoctorFinding[] {
|
|
100
100
|
const config = options.configManager;
|
|
101
101
|
const serviceEnabled = config.get('service.enabled') === true;
|
|
102
|
-
const serviceAutostart = config.get('service.autostart') === true;
|
|
103
|
-
const restartOnFailure = config.get('service.restartOnFailure') === true;
|
|
104
102
|
const daemonEnabled = config.get('danger.daemon') === true;
|
|
105
103
|
const listenerEnabled = config.get('danger.httpListener') === true;
|
|
106
104
|
const webEnabled = config.get('web.enabled') === true;
|
|
@@ -180,30 +178,6 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
|
|
|
180
178
|
});
|
|
181
179
|
}
|
|
182
180
|
|
|
183
|
-
if (serviceEnabled && !serviceAutostart) {
|
|
184
|
-
findings.push({
|
|
185
|
-
id: 'runtime-autostart-disabled',
|
|
186
|
-
area: 'runtime',
|
|
187
|
-
severity: 'warning',
|
|
188
|
-
summary: 'Connected-service autostart is off.',
|
|
189
|
-
cause: 'service.enabled is true and service.autostart is false.',
|
|
190
|
-
impact: 'Connected GoodVibes services may not be available after login or reboot even though host-managed startup is selected.',
|
|
191
|
-
action: 'Configure autostart from GoodVibes TUI or the owning host; Agent will not mutate this setting.',
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
if (serviceEnabled && !restartOnFailure) {
|
|
196
|
-
findings.push({
|
|
197
|
-
id: 'runtime-restart-disabled',
|
|
198
|
-
area: 'runtime',
|
|
199
|
-
severity: 'warning',
|
|
200
|
-
summary: 'Connected-service restart-on-failure is off.',
|
|
201
|
-
cause: 'service.enabled is true and service.restartOnFailure is false.',
|
|
202
|
-
impact: 'A crashed connected service or listener may stay down until manually restarted.',
|
|
203
|
-
action: 'Configure restart-on-failure from GoodVibes TUI or the owning host; Agent will not mutate this setting.',
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
|
|
207
181
|
if (options.service) {
|
|
208
182
|
for (const issue of options.service.issues) {
|
|
209
183
|
if (findings.some((finding) => finding.summary === issue)) continue;
|
|
@@ -342,8 +316,6 @@ export function renderCliStatus(options: CliStatusOptions): string {
|
|
|
342
316
|
const config = options.configManager;
|
|
343
317
|
const snapshot = buildCliStatusSnapshot(options);
|
|
344
318
|
const serviceEnabled = snapshot.runtimeConnection.enabled;
|
|
345
|
-
const serviceAutostart = snapshot.runtimeConnection.autostart;
|
|
346
|
-
const restartOnFailure = snapshot.runtimeConnection.restartOnFailure;
|
|
347
319
|
const controlPlaneEnabled = snapshot.runtimeEndpoints.controlPlane.enabled;
|
|
348
320
|
const listenerEnabled = snapshot.runtimeEndpoints.httpListener.enabled;
|
|
349
321
|
const webEnabled = snapshot.runtimeEndpoints.web.enabled;
|
|
@@ -414,8 +386,7 @@ export function renderCliStatus(options: CliStatusOptions): string {
|
|
|
414
386
|
'',
|
|
415
387
|
'Connected-Service Config Signals:',
|
|
416
388
|
` host config present: ${yesNo(serviceEnabled)}`,
|
|
417
|
-
|
|
418
|
-
` host restart policy: ${yesNo(restartOnFailure)}`,
|
|
389
|
+
' lifecycle config: external to Agent',
|
|
419
390
|
'',
|
|
420
391
|
'Endpoint Diagnostics:',
|
|
421
392
|
bindLine('runtimeApi', controlPlaneEnabled, controlPlaneBinding),
|
package/src/cli/types.ts
CHANGED
|
@@ -39,7 +39,6 @@ export interface GoodVibesCliFlags {
|
|
|
39
39
|
readonly provider: string | undefined;
|
|
40
40
|
readonly model: string | undefined;
|
|
41
41
|
readonly agentProfile: string | undefined;
|
|
42
|
-
readonly daemonHome: string | undefined;
|
|
43
42
|
readonly runtimeUrl: string | undefined;
|
|
44
43
|
readonly workingDir: string | undefined;
|
|
45
44
|
readonly help: boolean;
|
|
@@ -52,7 +52,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
|
|
|
52
52
|
detail: 'Agent uses connected channel accounts. Pairing, account inspection, and readiness checks are visible here; inbound delivery and public channel exposure stay policy-gated.',
|
|
53
53
|
actions: [
|
|
54
54
|
{ id: 'pair', label: 'Pair companion', detail: 'Open the QR pairing view for companion app setup.', command: '/pair', kind: 'command', safety: 'safe' },
|
|
55
|
-
{ id: 'channel-readiness', label: 'Channel readiness', detail: 'Show
|
|
55
|
+
{ id: 'channel-readiness', label: 'Channel readiness', detail: 'Show the read-only readiness matrix, then use /channels attention or /channels show <id> for setup detail.', command: '/channels', kind: 'command', safety: 'read-only' },
|
|
56
56
|
{ id: 'notification-routes', label: 'Notification routes', detail: 'Inspect configured webhook notification URLs without sending a test message.', command: '/notify list', kind: 'command', safety: 'read-only' },
|
|
57
57
|
{ id: 'notification-add-webhook', label: 'Add webhook target', detail: 'Open a confirmed form that adds one webhook notification target for explicit reminder and routine delivery.', editorKind: 'notify-webhook', kind: 'editor', safety: 'safe' },
|
|
58
58
|
{ id: 'notification-remove-webhook', label: 'Remove webhook target', detail: 'Open a confirmed form that removes one exact webhook notification target from Agent delivery.', editorKind: 'notify-webhook-remove', kind: 'editor', safety: 'safe' },
|
|
@@ -116,10 +116,9 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
|
|
|
116
116
|
id: 'profiles',
|
|
117
117
|
group: 'SETUP',
|
|
118
118
|
label: 'Profiles',
|
|
119
|
-
summary: 'Isolated Agent homes,
|
|
120
|
-
detail: '
|
|
119
|
+
summary: 'Isolated Agent homes, starter templates, and setup bundles.',
|
|
120
|
+
detail: 'Agent profiles isolate Agent state. Named homes and starter templates let one install behave like separate assistants for household, research, travel, operations, or personal workflows.',
|
|
121
121
|
actions: [
|
|
122
|
-
{ id: 'profiles-open', label: 'Open config profiles', detail: 'Open the config profile picker for display/provider/behavior profile files.', command: '/profiles', kind: 'command', safety: 'safe' },
|
|
123
122
|
{ id: 'runtime-profile-guide', label: 'Starter authoring guide', detail: 'Open the Agent-local starter authoring flow inside the Agent TUI.', command: '/agent-profile guide', kind: 'command', safety: 'safe' },
|
|
124
123
|
{ id: 'runtime-profile-templates', label: 'Browse starter templates', detail: 'List built-in and local Agent starter templates with persona, skill, routine, and source details.', command: '/agent-profile templates', kind: 'command', safety: 'read-only' },
|
|
125
124
|
{ id: 'runtime-profile-list', label: 'List Agent profiles', detail: 'List isolated Agent profile homes under this Agent home.', command: '/agent-profile list', kind: 'command', safety: 'read-only' },
|
|
@@ -221,9 +220,8 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
|
|
|
221
220
|
summary: 'Visible task state, work plan, and approval posture.',
|
|
222
221
|
detail: 'Use this workspace to inspect active operator state. Side-effecting approval decisions require explicit commands and confirmation outside this workspace.',
|
|
223
222
|
actions: [
|
|
224
|
-
{ id: 'workplan', label: '
|
|
225
|
-
{ id: '
|
|
226
|
-
{ id: 'approvals', label: 'Review approvals', detail: 'Open/read approval posture. This workspace does not approve or deny requests.', command: '/approval open', kind: 'command', safety: 'read-only' },
|
|
223
|
+
{ id: 'workplan', label: 'Review work plan', detail: 'Print a concise work plan summary in the main Agent transcript.', command: '/workplan list', kind: 'command', safety: 'read-only' },
|
|
224
|
+
{ id: 'approvals', label: 'Review approvals', detail: 'Print the approval matrix without approving or denying requests.', command: '/approval matrix', kind: 'command', safety: 'read-only' },
|
|
227
225
|
],
|
|
228
226
|
},
|
|
229
227
|
{
|
|
@@ -240,13 +240,6 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
240
240
|
return [];
|
|
241
241
|
}
|
|
242
242
|
})();
|
|
243
|
-
const configProfileCount = (() => {
|
|
244
|
-
try {
|
|
245
|
-
return context.workspace?.profileManager?.list?.().length ?? 0;
|
|
246
|
-
} catch {
|
|
247
|
-
return 0;
|
|
248
|
-
}
|
|
249
|
-
})();
|
|
250
243
|
const runtimeStarterTemplates = (() => {
|
|
251
244
|
try {
|
|
252
245
|
return listAgentRuntimeProfileTemplates(context.workspace?.shellPaths?.homeDirectory ?? '');
|
|
@@ -379,8 +372,8 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
379
372
|
mcpConnectedServerCount: mcpSnapshot.connectedCount,
|
|
380
373
|
mcpQuarantinedServerCount: mcpSnapshot.quarantinedCount,
|
|
381
374
|
mcpAllowAllServerCount: mcpSnapshot.allowAllCount,
|
|
382
|
-
|
|
383
|
-
|
|
375
|
+
browserToolExposureEnabled: readConfigBoolean(context, 'web.enabled', false),
|
|
376
|
+
browserToolPublicBaseUrl: readConfigString(context, 'web.publicBaseUrl', '(not configured)'),
|
|
384
377
|
activeRuntimeProfile: inferActiveRuntimeProfile(context.workspace?.shellPaths?.homeDirectory ?? ''),
|
|
385
378
|
runtimeProfileCount: runtimeProfiles.length,
|
|
386
379
|
runtimeProfiles: runtimeProfiles.map(summarizeRuntimeProfile),
|
|
@@ -388,7 +381,6 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
388
381
|
runtimeStarterTemplateCount: runtimeStarterTemplates.length,
|
|
389
382
|
localStarterTemplateCount: runtimeStarterTemplates.filter((template) => template.source === 'local').length,
|
|
390
383
|
runtimeStarterTemplates: runtimeStarterTemplates.map(summarizeStarterTemplate),
|
|
391
|
-
configProfileCount,
|
|
392
384
|
setupChecklist,
|
|
393
385
|
warnings,
|
|
394
386
|
};
|
|
@@ -190,8 +190,8 @@ export interface AgentWorkspaceRuntimeSnapshot {
|
|
|
190
190
|
readonly mcpConnectedServerCount: number;
|
|
191
191
|
readonly mcpQuarantinedServerCount: number;
|
|
192
192
|
readonly mcpAllowAllServerCount: number;
|
|
193
|
-
readonly
|
|
194
|
-
readonly
|
|
193
|
+
readonly browserToolExposureEnabled: boolean;
|
|
194
|
+
readonly browserToolPublicBaseUrl: string;
|
|
195
195
|
readonly activeRuntimeProfile: string;
|
|
196
196
|
readonly runtimeProfileCount: number;
|
|
197
197
|
readonly runtimeProfiles: readonly AgentWorkspaceRuntimeProfileItem[];
|
|
@@ -199,7 +199,6 @@ export interface AgentWorkspaceRuntimeSnapshot {
|
|
|
199
199
|
readonly runtimeStarterTemplateCount: number;
|
|
200
200
|
readonly localStarterTemplateCount: number;
|
|
201
201
|
readonly runtimeStarterTemplates: readonly AgentWorkspaceRuntimeStarterTemplateItem[];
|
|
202
|
-
readonly configProfileCount: number;
|
|
203
202
|
readonly setupChecklist: readonly AgentWorkspaceSetupChecklistItem[];
|
|
204
203
|
readonly warnings: readonly string[];
|
|
205
204
|
}
|
|
@@ -101,7 +101,7 @@ export function formatAgentOperatorBriefing(ctx: CommandContext): string {
|
|
|
101
101
|
` skills: ${snapshot.enabledSkillCount}/${snapshot.localSkillCount} enabled; bundles ${snapshot.enabledSkillBundleCount}/${snapshot.localSkillBundleCount}; active ${snapshot.activeSkillCount}`,
|
|
102
102
|
` routines: ${snapshot.enabledRoutineCount}/${snapshot.localRoutineCount} enabled`,
|
|
103
103
|
` channels: ${readyChannels}/${snapshot.channels.length} ready; ${enabledChannels} enabled`,
|
|
104
|
-
` voice/media: ${snapshot.voiceProviderCount} voice, ${snapshot.mediaProviderCount} media; browser
|
|
104
|
+
` voice/media: ${snapshot.voiceProviderCount} voice, ${snapshot.mediaProviderCount} media; browser tools ${snapshot.voiceMediaReadiness.browserToolState}`,
|
|
105
105
|
formatWorkPlanLine(workPlan.total, workPlan.counts),
|
|
106
106
|
` schedules: ${enabledJobs}/${jobs.length} visible jobs enabled`,
|
|
107
107
|
'',
|