@pellux/goodvibes-agent 0.1.29 → 0.1.31
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
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to GoodVibes Agent will be recorded here.
|
|
4
4
|
|
|
5
|
+
## 0.1.31 - 2026-05-31
|
|
6
|
+
|
|
7
|
+
- 2bc4887 Expand Agent Knowledge workspace flows
|
|
8
|
+
|
|
9
|
+
## 0.1.30 - 2026-05-31
|
|
10
|
+
|
|
11
|
+
- 6a1c818 Add channel readiness to Agent workspace
|
|
12
|
+
|
|
5
13
|
## 0.1.29 - 2026-05-31
|
|
6
14
|
|
|
7
15
|
- 3fafcda Add Agent channel workspace guidance
|
|
@@ -30,11 +30,18 @@ Inside the TUI:
|
|
|
30
30
|
Primary sources used for the benchmark:
|
|
31
31
|
|
|
32
32
|
- OpenClaw README: https://github.com/openclaw/openclaw/blob/main/README.md
|
|
33
|
+
- OpenClaw Docs: https://docs.openclaw.ai/
|
|
34
|
+
- OpenClaw Features: https://docs.openclaw.ai/concepts/features
|
|
33
35
|
- OpenClaw FAQ: https://docs.openclaw.ai/help/faq
|
|
34
36
|
- OpenClaw Memory: https://docs.openclaw.ai/concepts/memory
|
|
35
37
|
- Hermes README: https://github.com/NousResearch/hermes-agent
|
|
38
|
+
- Hermes Features Overview: https://hermes-agent.nousresearch.com/docs/user-guide/features/overview/
|
|
36
39
|
- Hermes Tools: https://hermes-agent.nousresearch.com/docs/user-guide/features/tools/
|
|
40
|
+
- Hermes Skills: https://hermes-agent.nousresearch.com/docs/user-guide/features/skills/
|
|
37
41
|
- Hermes Cron: https://hermes-agent.nousresearch.com/docs/user-guide/features/cron/
|
|
42
|
+
- Hermes MCP: https://hermes-agent.nousresearch.com/docs/user-guide/features/mcp/
|
|
43
|
+
- Hermes Voice: https://hermes-agent.nousresearch.com/docs/user-guide/features/voice-mode/
|
|
44
|
+
- Hermes API Server: https://hermes-agent.nousresearch.com/docs/user-guide/features/api-server/
|
|
38
45
|
- Hermes Profiles: https://hermes-agent.nousresearch.com/docs/user-guide/profiles/
|
|
39
46
|
|
|
40
47
|
## Capability Targets
|
|
@@ -43,8 +50,8 @@ Primary sources used for the benchmark:
|
|
|
43
50
|
| --- | --- | --- |
|
|
44
51
|
| Terminal operator UI | Interactive CLI/TUI, commands, sessions | Near-fork GoodVibes TUI compositor/input/fullscreen foundation |
|
|
45
52
|
| Always-on gateway | Gateway/service owns channels, sessions, tools, events | External GoodVibes daemon, never Agent-owned lifecycle |
|
|
46
|
-
| Channels | WhatsApp, Telegram, Slack, Discord, Signal, iMessage, web chat | GoodVibes daemon channel and companion surfaces with Agent-side policy
|
|
47
|
-
| Knowledge/memory | Durable memory, semantic search, wiki/claim layers | Isolated Agent Knowledge routes plus local memory/skills/personas/routines |
|
|
53
|
+
| Channels | WhatsApp, Telegram, Slack, Discord, Signal, iMessage, web chat | GoodVibes daemon channel and companion surfaces with Agent-side policy, a Channels operator workspace, and per-channel readiness/risk labels |
|
|
54
|
+
| Knowledge/memory | Durable memory, semantic search, wiki/claim layers | Isolated Agent Knowledge routes with workspace ask/search/ingest/review flows plus local memory/skills/personas/routines |
|
|
48
55
|
| Skills/procedural memory | Skills directories, registries, skill lifecycle | Local Agent skills with review/stale/source/provenance fields |
|
|
49
56
|
| Scheduling | Natural-language cron, run/pause/resume/edit/remove, delivery | Guarded automation/schedule routes plus local routines; hidden model scheduling blocked |
|
|
50
57
|
| Tools/MCP | Broad toolsets, MCP, browser, media, terminal, files | GoodVibes SDK tools with Agent policy guards and MCP/provider integrations |
|
|
@@ -66,8 +73,8 @@ GoodVibes Agent should exceed OpenClaw/Hermes by making these properties true fr
|
|
|
66
73
|
|
|
67
74
|
## Current Gaps To Close
|
|
68
75
|
|
|
69
|
-
-
|
|
70
|
-
-
|
|
76
|
+
- Live daemon account health and last delivery errors in the Channels workspace once a stable read-only route is available.
|
|
77
|
+
- Artifact and multimodal Agent Knowledge ingest affordances once Agent-specific routes are stable.
|
|
71
78
|
- Profile-aware onboarding summaries and profile export/import shortcuts from the Agent workspace.
|
|
72
79
|
- Voice/media/browser/node setup workspaces.
|
|
73
80
|
- Delegation receipts and artifact review inside the operator workspace.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.31",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Near-fork GoodVibes operator assistant with the GoodVibes TUI shell, renderer, input, fullscreen workspace, and daemon-connected Agent product brain.",
|
|
6
6
|
"type": "module",
|
|
@@ -30,6 +30,20 @@ export interface AgentWorkspaceCategory {
|
|
|
30
30
|
|
|
31
31
|
export type AgentWorkspaceCommandDispatcher = (command: string) => void;
|
|
32
32
|
|
|
33
|
+
export type AgentWorkspaceChannelRisk = 'dm' | 'group' | 'public' | 'webhook' | 'bridge';
|
|
34
|
+
|
|
35
|
+
export interface AgentWorkspaceChannelStatus {
|
|
36
|
+
readonly id: string;
|
|
37
|
+
readonly label: string;
|
|
38
|
+
readonly enabled: boolean;
|
|
39
|
+
readonly ready: boolean;
|
|
40
|
+
readonly missingConfigCount: number;
|
|
41
|
+
readonly defaultTarget: 'configured' | 'missing' | 'not-required';
|
|
42
|
+
readonly delivery: 'disabled' | 'blocked' | 'explicit-target' | 'default-ready';
|
|
43
|
+
readonly risk: AgentWorkspaceChannelRisk;
|
|
44
|
+
readonly riskLabel: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
33
47
|
export type AgentWorkspaceActionResultKind = 'guidance' | 'blocked' | 'dispatched' | 'refreshed' | 'error';
|
|
34
48
|
|
|
35
49
|
export interface AgentWorkspaceActionResult {
|
|
@@ -64,9 +78,140 @@ export interface AgentWorkspaceRuntimeSnapshot {
|
|
|
64
78
|
readonly knowledgeIsolation: 'agent-only';
|
|
65
79
|
readonly executionPolicy: 'serial-proactive';
|
|
66
80
|
readonly wrfcPolicy: 'explicit-build-delegation-only';
|
|
81
|
+
readonly channels: readonly AgentWorkspaceChannelStatus[];
|
|
67
82
|
readonly warnings: readonly string[];
|
|
68
83
|
}
|
|
69
84
|
|
|
85
|
+
interface AgentWorkspaceChannelSpec {
|
|
86
|
+
readonly id: string;
|
|
87
|
+
readonly label: string;
|
|
88
|
+
readonly enabledKey: string;
|
|
89
|
+
readonly requiredKeys: readonly string[];
|
|
90
|
+
readonly defaultTargetKeys: readonly string[];
|
|
91
|
+
readonly risk: AgentWorkspaceChannelRisk;
|
|
92
|
+
readonly riskLabel: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const AGENT_WORKSPACE_CHANNEL_SPECS: readonly AgentWorkspaceChannelSpec[] = [
|
|
96
|
+
{
|
|
97
|
+
id: 'slack',
|
|
98
|
+
label: 'Slack',
|
|
99
|
+
enabledKey: 'surfaces.slack.enabled',
|
|
100
|
+
requiredKeys: ['surfaces.slack.botToken', 'surfaces.slack.signingSecret'],
|
|
101
|
+
defaultTargetKeys: ['surfaces.slack.defaultChannel'],
|
|
102
|
+
risk: 'group',
|
|
103
|
+
riskLabel: 'workspace/group channel',
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: 'discord',
|
|
107
|
+
label: 'Discord',
|
|
108
|
+
enabledKey: 'surfaces.discord.enabled',
|
|
109
|
+
requiredKeys: ['surfaces.discord.botToken', 'surfaces.discord.publicKey', 'surfaces.discord.applicationId'],
|
|
110
|
+
defaultTargetKeys: ['surfaces.discord.defaultChannelId'],
|
|
111
|
+
risk: 'group',
|
|
112
|
+
riskLabel: 'server/channel delivery',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
id: 'telegram',
|
|
116
|
+
label: 'Telegram',
|
|
117
|
+
enabledKey: 'surfaces.telegram.enabled',
|
|
118
|
+
requiredKeys: ['surfaces.telegram.botToken'],
|
|
119
|
+
defaultTargetKeys: ['surfaces.telegram.defaultChatId'],
|
|
120
|
+
risk: 'dm',
|
|
121
|
+
riskLabel: 'bot DM/group delivery',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
id: 'ntfy',
|
|
125
|
+
label: 'ntfy',
|
|
126
|
+
enabledKey: 'surfaces.ntfy.enabled',
|
|
127
|
+
requiredKeys: ['surfaces.ntfy.baseUrl', 'surfaces.ntfy.chatTopic', 'surfaces.ntfy.agentTopic'],
|
|
128
|
+
defaultTargetKeys: ['surfaces.ntfy.topic'],
|
|
129
|
+
risk: 'public',
|
|
130
|
+
riskLabel: 'topic-based public/private feed',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
id: 'googleChat',
|
|
134
|
+
label: 'Google Chat',
|
|
135
|
+
enabledKey: 'surfaces.googleChat.enabled',
|
|
136
|
+
requiredKeys: ['surfaces.googleChat.webhookUrl', 'surfaces.googleChat.verificationToken'],
|
|
137
|
+
defaultTargetKeys: ['surfaces.googleChat.spaceId'],
|
|
138
|
+
risk: 'group',
|
|
139
|
+
riskLabel: 'space delivery',
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
id: 'signal',
|
|
143
|
+
label: 'Signal',
|
|
144
|
+
enabledKey: 'surfaces.signal.enabled',
|
|
145
|
+
requiredKeys: ['surfaces.signal.bridgeUrl', 'surfaces.signal.account'],
|
|
146
|
+
defaultTargetKeys: ['surfaces.signal.defaultRecipient'],
|
|
147
|
+
risk: 'bridge',
|
|
148
|
+
riskLabel: 'private bridge delivery',
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
id: 'whatsapp',
|
|
152
|
+
label: 'WhatsApp',
|
|
153
|
+
enabledKey: 'surfaces.whatsapp.enabled',
|
|
154
|
+
requiredKeys: ['surfaces.whatsapp.accessToken', 'surfaces.whatsapp.verifyToken', 'surfaces.whatsapp.phoneNumberId'],
|
|
155
|
+
defaultTargetKeys: ['surfaces.whatsapp.defaultRecipient'],
|
|
156
|
+
risk: 'dm',
|
|
157
|
+
riskLabel: 'phone-number delivery',
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
id: 'imessage',
|
|
161
|
+
label: 'iMessage',
|
|
162
|
+
enabledKey: 'surfaces.imessage.enabled',
|
|
163
|
+
requiredKeys: ['surfaces.imessage.bridgeUrl', 'surfaces.imessage.account'],
|
|
164
|
+
defaultTargetKeys: ['surfaces.imessage.defaultChatId'],
|
|
165
|
+
risk: 'bridge',
|
|
166
|
+
riskLabel: 'Apple bridge delivery',
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
id: 'bluebubbles',
|
|
170
|
+
label: 'BlueBubbles',
|
|
171
|
+
enabledKey: 'surfaces.bluebubbles.enabled',
|
|
172
|
+
requiredKeys: ['surfaces.bluebubbles.serverUrl', 'surfaces.bluebubbles.password'],
|
|
173
|
+
defaultTargetKeys: ['surfaces.bluebubbles.defaultChatGuid'],
|
|
174
|
+
risk: 'bridge',
|
|
175
|
+
riskLabel: 'iMessage bridge delivery',
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
id: 'msteams',
|
|
179
|
+
label: 'Microsoft Teams',
|
|
180
|
+
enabledKey: 'surfaces.msteams.enabled',
|
|
181
|
+
requiredKeys: ['surfaces.msteams.appId', 'surfaces.msteams.appPassword'],
|
|
182
|
+
defaultTargetKeys: ['surfaces.msteams.defaultConversationId', 'surfaces.msteams.defaultChannelId'],
|
|
183
|
+
risk: 'group',
|
|
184
|
+
riskLabel: 'tenant/channel delivery',
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
id: 'mattermost',
|
|
188
|
+
label: 'Mattermost',
|
|
189
|
+
enabledKey: 'surfaces.mattermost.enabled',
|
|
190
|
+
requiredKeys: ['surfaces.mattermost.baseUrl', 'surfaces.mattermost.botToken'],
|
|
191
|
+
defaultTargetKeys: ['surfaces.mattermost.defaultChannelId'],
|
|
192
|
+
risk: 'group',
|
|
193
|
+
riskLabel: 'team/channel delivery',
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
id: 'matrix',
|
|
197
|
+
label: 'Matrix',
|
|
198
|
+
enabledKey: 'surfaces.matrix.enabled',
|
|
199
|
+
requiredKeys: ['surfaces.matrix.homeserverUrl', 'surfaces.matrix.accessToken'],
|
|
200
|
+
defaultTargetKeys: ['surfaces.matrix.defaultRoomId'],
|
|
201
|
+
risk: 'group',
|
|
202
|
+
riskLabel: 'room delivery',
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
id: 'webhook',
|
|
206
|
+
label: 'Webhook',
|
|
207
|
+
enabledKey: 'surfaces.webhook.enabled',
|
|
208
|
+
requiredKeys: ['surfaces.webhook.defaultTarget'],
|
|
209
|
+
defaultTargetKeys: ['surfaces.webhook.defaultTarget'],
|
|
210
|
+
risk: 'webhook',
|
|
211
|
+
riskLabel: 'external HTTP delivery',
|
|
212
|
+
},
|
|
213
|
+
];
|
|
214
|
+
|
|
70
215
|
function readConfigString(context: CommandContext, key: string, fallback: string): string {
|
|
71
216
|
try {
|
|
72
217
|
const configManager = context.platform?.configManager as unknown as AgentWorkspaceConfigReader | undefined;
|
|
@@ -88,6 +233,64 @@ function readConfigNumber(context: CommandContext, key: string, fallback: number
|
|
|
88
233
|
}
|
|
89
234
|
}
|
|
90
235
|
|
|
236
|
+
function readConfigBoolean(context: CommandContext, key: string, fallback: boolean): boolean {
|
|
237
|
+
try {
|
|
238
|
+
const configManager = context.platform?.configManager as unknown as AgentWorkspaceConfigReader | undefined;
|
|
239
|
+
const value = configManager?.get(key);
|
|
240
|
+
if (typeof value === 'boolean') return value;
|
|
241
|
+
if (typeof value === 'string') {
|
|
242
|
+
const normalized = value.trim().toLowerCase();
|
|
243
|
+
if (normalized === 'true') return true;
|
|
244
|
+
if (normalized === 'false') return false;
|
|
245
|
+
}
|
|
246
|
+
return fallback;
|
|
247
|
+
} catch {
|
|
248
|
+
return fallback;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function hasConfigValue(context: CommandContext, key: string): boolean {
|
|
253
|
+
try {
|
|
254
|
+
const configManager = context.platform?.configManager as unknown as AgentWorkspaceConfigReader | undefined;
|
|
255
|
+
const value = configManager?.get(key);
|
|
256
|
+
if (typeof value === 'string') return value.trim().length > 0;
|
|
257
|
+
if (typeof value === 'number') return Number.isFinite(value);
|
|
258
|
+
if (typeof value === 'boolean') return value;
|
|
259
|
+
return value !== null && value !== undefined;
|
|
260
|
+
} catch {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function buildChannelStatus(context: CommandContext, spec: AgentWorkspaceChannelSpec): AgentWorkspaceChannelStatus {
|
|
266
|
+
const enabled = readConfigBoolean(context, spec.enabledKey, false);
|
|
267
|
+
const missingConfigCount = spec.requiredKeys.filter((key) => !hasConfigValue(context, key)).length;
|
|
268
|
+
const defaultTarget = spec.defaultTargetKeys.length === 0
|
|
269
|
+
? 'not-required'
|
|
270
|
+
: spec.defaultTargetKeys.some((key) => hasConfigValue(context, key))
|
|
271
|
+
? 'configured'
|
|
272
|
+
: 'missing';
|
|
273
|
+
const ready = enabled && missingConfigCount === 0;
|
|
274
|
+
const delivery = !enabled
|
|
275
|
+
? 'disabled'
|
|
276
|
+
: !ready
|
|
277
|
+
? 'blocked'
|
|
278
|
+
: defaultTarget === 'configured'
|
|
279
|
+
? 'default-ready'
|
|
280
|
+
: 'explicit-target';
|
|
281
|
+
return {
|
|
282
|
+
id: spec.id,
|
|
283
|
+
label: spec.label,
|
|
284
|
+
enabled,
|
|
285
|
+
ready,
|
|
286
|
+
missingConfigCount,
|
|
287
|
+
defaultTarget,
|
|
288
|
+
delivery,
|
|
289
|
+
risk: spec.risk,
|
|
290
|
+
riskLabel: spec.riskLabel,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
|
|
91
294
|
export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): AgentWorkspaceRuntimeSnapshot {
|
|
92
295
|
const host = readConfigString(context, 'controlPlane.host', '127.0.0.1');
|
|
93
296
|
const port = readConfigNumber(context, 'controlPlane.port', 3421);
|
|
@@ -161,6 +364,7 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
161
364
|
knowledgeIsolation: 'agent-only',
|
|
162
365
|
executionPolicy: 'serial-proactive',
|
|
163
366
|
wrfcPolicy: 'explicit-build-delegation-only',
|
|
367
|
+
channels: AGENT_WORKSPACE_CHANNEL_SPECS.map((spec) => buildChannelStatus(context, spec)),
|
|
164
368
|
warnings,
|
|
165
369
|
};
|
|
166
370
|
}
|
|
@@ -213,7 +417,11 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
|
|
|
213
417
|
detail: 'Agent knowledge calls must use the isolated /api/goodvibes-agent/knowledge routes. Default regular wiki and HomeGraph are not the Agent knowledge environment.',
|
|
214
418
|
actions: [
|
|
215
419
|
{ id: 'knowledge-status', label: 'Knowledge status', detail: 'Inspect Agent knowledge readiness and counts.', command: '/knowledge status', kind: 'command', safety: 'read-only' },
|
|
216
|
-
{ id: 'knowledge-
|
|
420
|
+
{ id: 'knowledge-search', label: 'Search Agent knowledge', detail: 'Search the isolated Agent Knowledge index. Close this workspace and provide an actual query.', command: '/knowledge search <query>', kind: 'command', safety: 'read-only' },
|
|
421
|
+
{ id: 'knowledge-ingest-url', label: 'Ingest URL', detail: 'Ingest a URL into Agent Knowledge only. Requires an explicit --yes command with a real URL.', command: '/knowledge ingest-url <url> --yes', kind: 'command', safety: 'safe' },
|
|
422
|
+
{ id: 'knowledge-import-bookmarks', label: 'Import bookmarks', detail: 'Import a browser bookmark export into Agent Knowledge only. Requires an explicit --yes command with a real path.', command: '/knowledge import-bookmarks <path> --yes', kind: 'command', safety: 'safe' },
|
|
423
|
+
{ id: 'knowledge-review-queue', label: 'Review queue', detail: 'Inspect source/node/issue review work before accepting, rejecting, or resolving anything.', command: '/knowledge queue', kind: 'command', safety: 'read-only' },
|
|
424
|
+
{ id: 'knowledge-consolidation', label: 'Consolidation review', detail: 'Inspect consolidation candidates and reports before running Agent Knowledge mutations.', command: '/knowledge candidates', kind: 'command', safety: 'read-only' },
|
|
217
425
|
{ id: 'knowledge-ask', label: 'Ask Agent knowledge', detail: 'Close this workspace and run /knowledge ask <question> or ask normally in chat.', kind: 'guidance', safety: 'read-only' },
|
|
218
426
|
],
|
|
219
427
|
},
|
|
@@ -30,11 +30,18 @@ export interface OperatorCapabilityBenchmarkReport {
|
|
|
30
30
|
|
|
31
31
|
export const OPERATOR_CAPABILITY_BENCHMARK_SOURCES = [
|
|
32
32
|
'https://github.com/openclaw/openclaw/blob/main/README.md',
|
|
33
|
+
'https://docs.openclaw.ai/',
|
|
34
|
+
'https://docs.openclaw.ai/concepts/features',
|
|
33
35
|
'https://docs.openclaw.ai/help/faq',
|
|
34
36
|
'https://docs.openclaw.ai/concepts/memory',
|
|
35
37
|
'https://github.com/NousResearch/hermes-agent',
|
|
38
|
+
'https://hermes-agent.nousresearch.com/docs/user-guide/features/overview/',
|
|
36
39
|
'https://hermes-agent.nousresearch.com/docs/user-guide/features/tools/',
|
|
40
|
+
'https://hermes-agent.nousresearch.com/docs/user-guide/features/skills/',
|
|
37
41
|
'https://hermes-agent.nousresearch.com/docs/user-guide/features/cron/',
|
|
42
|
+
'https://hermes-agent.nousresearch.com/docs/user-guide/features/mcp/',
|
|
43
|
+
'https://hermes-agent.nousresearch.com/docs/user-guide/features/voice-mode/',
|
|
44
|
+
'https://hermes-agent.nousresearch.com/docs/user-guide/features/api-server/',
|
|
38
45
|
'https://hermes-agent.nousresearch.com/docs/user-guide/profiles/',
|
|
39
46
|
] as const;
|
|
40
47
|
|
|
@@ -69,11 +76,11 @@ export const OPERATOR_CAPABILITY_BENCHMARKS: readonly OperatorCapabilityBenchmar
|
|
|
69
76
|
posture: 'configurable',
|
|
70
77
|
competitors: ['openclaw', 'hermes'],
|
|
71
78
|
competitorBaseline: 'Messaging gateway for WhatsApp, Telegram, Slack, Discord, Signal, iMessage, web chat, and related platforms.',
|
|
72
|
-
goodvibesAgent: 'Uses GoodVibes daemon channel, companion, pairing, QR, communication, and session surfaces while keeping side effects behind explicit user action. The Agent workspace exposes channel setup and
|
|
79
|
+
goodvibesAgent: 'Uses GoodVibes daemon channel, companion, pairing, QR, communication, and session surfaces while keeping side effects behind explicit user action. The Agent workspace exposes channel setup, per-channel readiness, default-target posture, and risk labels as a first-class operator area.',
|
|
73
80
|
configure: ['goodvibes-agent pair', 'goodvibes-agent qrcode', 'goodvibes-agent surfaces check', '/agent → Channels'],
|
|
74
81
|
use: ['/agent → Channels', '/communication', '/pair'],
|
|
75
|
-
exceedsBy: ['Agent-owned safety policy over shared channel routes', 'read-only inspection by default', 'explicit approval path for external side effects', 'channel setup discoverable from the fullscreen operator workspace'],
|
|
76
|
-
next: ['
|
|
82
|
+
exceedsBy: ['Agent-owned safety policy over shared channel routes', 'read-only inspection by default', 'explicit approval path for external side effects', 'channel setup discoverable from the fullscreen operator workspace', 'per-channel readiness and delivery defaults shown without leaking token values'],
|
|
83
|
+
next: ['Pull live daemon account health and last delivery errors into the Channels workspace when a stable read-only route is available.'],
|
|
77
84
|
},
|
|
78
85
|
{
|
|
79
86
|
id: 'isolated-knowledge-wiki',
|
|
@@ -81,11 +88,11 @@ export const OPERATOR_CAPABILITY_BENCHMARKS: readonly OperatorCapabilityBenchmar
|
|
|
81
88
|
posture: 'ready',
|
|
82
89
|
competitors: ['openclaw', 'hermes'],
|
|
83
90
|
competitorBaseline: 'Persistent memory and knowledge/wiki layers with search, recall, provenance, and freshness checks.',
|
|
84
|
-
goodvibesAgent: 'Uses only /api/goodvibes-agent/knowledge/*; never falls back to default Knowledge/Wiki, HomeGraph, or Home Assistant routes.',
|
|
85
|
-
configure: ['goodvibes-agent compat', 'goodvibes-agent knowledge status'],
|
|
86
|
-
use: ['goodvibes-agent ask <question>', 'goodvibes-agent search <query>', '/knowledge ask <question>', '/knowledge ingest-url <url> --yes'],
|
|
87
|
-
exceedsBy: ['Dedicated product segment for Agent knowledge', 'route-level isolation', 'package gates that reject default wiki/HomeGraph fallback'],
|
|
88
|
-
next: ['Add
|
|
91
|
+
goodvibesAgent: 'Uses only /api/goodvibes-agent/knowledge/*; never falls back to default Knowledge/Wiki, HomeGraph, or Home Assistant routes. The Agent workspace exposes isolated ask/search/status, URL/bookmark ingestion, review queue, and consolidation workflows.',
|
|
92
|
+
configure: ['goodvibes-agent compat', 'goodvibes-agent knowledge status', '/agent → Knowledge'],
|
|
93
|
+
use: ['goodvibes-agent ask <question>', 'goodvibes-agent search <query>', '/knowledge ask <question>', '/knowledge ingest-url <url> --yes', '/knowledge queue'],
|
|
94
|
+
exceedsBy: ['Dedicated product segment for Agent knowledge', 'route-level isolation', 'package gates that reject default wiki/HomeGraph fallback', 'fullscreen review/ingest workflow that keeps writes explicit'],
|
|
95
|
+
next: ['Add artifact and multimodal Agent Knowledge ingest affordances once the Agent-specific route is stable.'],
|
|
89
96
|
},
|
|
90
97
|
{
|
|
91
98
|
id: 'local-memory-skills-personas',
|
|
@@ -89,16 +89,32 @@ function snapshotLines(category: AgentWorkspaceCategory, snapshot: AgentWorkspac
|
|
|
89
89
|
{ text: `Home: ${snapshot.homeDirectory}`, fg: PALETTE.muted },
|
|
90
90
|
);
|
|
91
91
|
} else if (category.id === 'channels') {
|
|
92
|
+
const enabledCount = snapshot.channels.filter((channel) => channel.enabled).length;
|
|
93
|
+
const readyCount = snapshot.channels.filter((channel) => channel.ready).length;
|
|
94
|
+
const configuredDefaults = snapshot.channels.filter((channel) => channel.defaultTarget === 'configured').length;
|
|
95
|
+
const disabledChannels = snapshot.channels.filter((channel) => !channel.enabled).map((channel) => channel.label).join(', ');
|
|
92
96
|
base.push(
|
|
93
97
|
{ text: `External daemon: ${snapshot.daemonBaseUrl}`, fg: PALETTE.info },
|
|
98
|
+
{ text: `Readiness: ${readyCount}/${snapshot.channels.length} ready; ${enabledCount} enabled; ${configuredDefaults} default target(s) configured.`, fg: PALETTE.info },
|
|
99
|
+
{ text: `Disabled channels: ${disabledChannels || 'none'}.`, fg: PALETTE.dim },
|
|
94
100
|
{ text: 'Pairing: use /pair or /qrcode for companion setup.', fg: PALETTE.info },
|
|
95
101
|
{ text: 'Channel posture: inspect via /communication and /setup review.', fg: PALETTE.muted },
|
|
96
102
|
{ text: 'Safety: external delivery, unknown senders, and public exposure require explicit policy and user action.', fg: PALETTE.warn },
|
|
97
103
|
);
|
|
104
|
+
for (const channel of snapshot.channels) {
|
|
105
|
+
const enabled = channel.enabled ? 'enabled' : 'disabled';
|
|
106
|
+
const ready = channel.ready ? 'ready' : `${channel.missingConfigCount} missing`;
|
|
107
|
+
base.push({
|
|
108
|
+
text: `${channel.label}: ${enabled}; ${ready}; default ${channel.defaultTarget}; delivery ${channel.delivery}; risk ${channel.riskLabel}.`,
|
|
109
|
+
fg: channel.ready ? PALETTE.good : channel.enabled ? PALETTE.warn : PALETTE.dim,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
98
112
|
} else if (category.id === 'knowledge') {
|
|
99
113
|
base.push(
|
|
100
114
|
{ text: `Route family: ${snapshot.knowledgeRoute}/{status,ask,search}`, fg: PALETTE.info },
|
|
101
115
|
{ text: `Isolation: ${snapshot.knowledgeIsolation}; no default Knowledge/Wiki or HomeGraph fallback`, fg: PALETTE.good },
|
|
116
|
+
{ text: 'Ingest: URL, URL-list, and bookmark imports require explicit --yes and write only to Agent Knowledge.', fg: PALETTE.info },
|
|
117
|
+
{ text: 'Review: queue, issues, candidates, reports, reindex, and consolidation stay inside the Agent segment.', fg: PALETTE.muted },
|
|
102
118
|
{ text: 'Agent-owned content appears here only after explicit Agent knowledge ingestion.', fg: PALETTE.muted },
|
|
103
119
|
);
|
|
104
120
|
} else if (category.id === 'memory') {
|
|
@@ -229,7 +245,8 @@ function footerText(workspace: AgentWorkspace): string {
|
|
|
229
245
|
}
|
|
230
246
|
|
|
231
247
|
export function renderAgentWorkspace(workspace: AgentWorkspace, width: number, height: number): Line[] {
|
|
232
|
-
const
|
|
248
|
+
const layoutOptions = { width, height, leftWidth: width < 90 ? undefined : 30, contextRatio: 0.62, minContextRows: 10 };
|
|
249
|
+
const metrics = getFullscreenWorkspaceMetrics(layoutOptions);
|
|
233
250
|
const category = workspace.selectedCategory;
|
|
234
251
|
const action = workspace.selectedAction;
|
|
235
252
|
|
|
@@ -244,5 +261,8 @@ export function renderAgentWorkspace(workspace: AgentWorkspace, width: number, h
|
|
|
244
261
|
contextRows: buildContextRows(workspace, category, action, metrics.contextWidth),
|
|
245
262
|
controlRows: buildActionRows(workspace, metrics.contextWidth, metrics.controlRows),
|
|
246
263
|
footer: footerText(workspace),
|
|
264
|
+
leftWidth: layoutOptions.leftWidth,
|
|
265
|
+
contextRatio: layoutOptions.contextRatio,
|
|
266
|
+
minContextRows: layoutOptions.minContextRows,
|
|
247
267
|
});
|
|
248
268
|
}
|
package/src/version.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { join } from 'node:path';
|
|
|
6
6
|
// The prebuild script updates the fallback value before compilation.
|
|
7
7
|
// Uses import.meta.dir (Bun) to locate package.json relative to this file,
|
|
8
8
|
// which is correct regardless of the process working directory.
|
|
9
|
-
let _version = '0.1.
|
|
9
|
+
let _version = '0.1.31';
|
|
10
10
|
let _sdkVersion = '0.33.35';
|
|
11
11
|
try {
|
|
12
12
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8')) as {
|