@pellux/goodvibes-agent 0.1.29 → 0.1.30
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
|
@@ -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,7 +50,7 @@ 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
|
|
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 |
|
|
47
54
|
| Knowledge/memory | Durable memory, semantic search, wiki/claim layers | Isolated Agent Knowledge routes 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 |
|
|
@@ -66,7 +73,7 @@ GoodVibes Agent should exceed OpenClaw/Hermes by making these properties true fr
|
|
|
66
73
|
|
|
67
74
|
## Current Gaps To Close
|
|
68
75
|
|
|
69
|
-
-
|
|
76
|
+
- Live daemon account health and last delivery errors in the Channels workspace once a stable read-only route is available.
|
|
70
77
|
- Richer Agent Knowledge ingest/review workspace for URLs, bookmarks, artifacts, issue queues, and consolidation.
|
|
71
78
|
- Profile-aware onboarding summaries and profile export/import shortcuts from the Agent workspace.
|
|
72
79
|
- Voice/media/browser/node setup workspaces.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.30",
|
|
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
|
}
|
|
@@ -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',
|
|
@@ -89,12 +89,26 @@ 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 },
|
|
@@ -229,7 +243,8 @@ function footerText(workspace: AgentWorkspace): string {
|
|
|
229
243
|
}
|
|
230
244
|
|
|
231
245
|
export function renderAgentWorkspace(workspace: AgentWorkspace, width: number, height: number): Line[] {
|
|
232
|
-
const
|
|
246
|
+
const layoutOptions = { width, height, leftWidth: width < 90 ? undefined : 30, contextRatio: 0.62, minContextRows: 10 };
|
|
247
|
+
const metrics = getFullscreenWorkspaceMetrics(layoutOptions);
|
|
233
248
|
const category = workspace.selectedCategory;
|
|
234
249
|
const action = workspace.selectedAction;
|
|
235
250
|
|
|
@@ -244,5 +259,8 @@ export function renderAgentWorkspace(workspace: AgentWorkspace, width: number, h
|
|
|
244
259
|
contextRows: buildContextRows(workspace, category, action, metrics.contextWidth),
|
|
245
260
|
controlRows: buildActionRows(workspace, metrics.contextWidth, metrics.controlRows),
|
|
246
261
|
footer: footerText(workspace),
|
|
262
|
+
leftWidth: layoutOptions.leftWidth,
|
|
263
|
+
contextRatio: layoutOptions.contextRatio,
|
|
264
|
+
minContextRows: layoutOptions.minContextRows,
|
|
247
265
|
});
|
|
248
266
|
}
|
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.30';
|
|
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 {
|