@pellux/goodvibes-agent 0.1.28 → 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
@@ -2,6 +2,14 @@
2
2
 
3
3
  All notable changes to GoodVibes Agent will be recorded here.
4
4
 
5
+ ## 0.1.30 - 2026-05-31
6
+
7
+ - 6a1c818 Add channel readiness to Agent workspace
8
+
9
+ ## 0.1.29 - 2026-05-31
10
+
11
+ - 3fafcda Add Agent channel workspace guidance
12
+
5
13
  ## 0.1.28 - 2026-05-31
6
14
 
7
15
  - 77a9dc4 Add isolated Agent runtime profiles
@@ -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
- - Agent-first channel onboarding workspace for pairing, account visibility, delivery defaults, and channel safety.
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.28",
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
  }
@@ -192,6 +396,19 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
192
396
  { id: 'auth', label: 'Auth review', detail: 'Review authentication posture without printing token values.', command: '/auth review', kind: 'command', safety: 'read-only' },
193
397
  ],
194
398
  },
399
+ {
400
+ id: 'channels',
401
+ group: 'SETUP',
402
+ label: 'Channels',
403
+ summary: 'Companion pairing, channel posture, and delivery safety.',
404
+ detail: 'Agent uses externally owned daemon channel surfaces. Pairing, account inspection, and readiness checks are visible here; inbound delivery and public channel exposure stay policy-gated.',
405
+ actions: [
406
+ { id: 'pair', label: 'Pair companion', detail: 'Open the TUI-derived QR pairing surface for companion app setup.', command: '/pair', kind: 'command', safety: 'safe' },
407
+ { id: 'communication', label: 'Communication routes', detail: 'Inspect structured communication routes and recent activity.', command: '/communication', kind: 'command', safety: 'read-only' },
408
+ { id: 'setup-review', label: 'Channel setup review', detail: 'Review setup posture without starting listeners or mutating daemon surface state.', command: '/setup review', kind: 'command', safety: 'read-only' },
409
+ { id: 'channel-safety', label: 'Delivery safety', detail: 'External messages, channel DMs, and public delivery targets require explicit user action and daemon-side policy. Agent will not silently send or expose channels from this workspace.', kind: 'guidance', safety: 'blocked' },
410
+ ],
411
+ },
195
412
  {
196
413
  id: 'knowledge',
197
414
  group: 'KNOW',
@@ -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, and session surfaces while keeping side effects behind explicit user action.',
73
- configure: ['goodvibes-agent pair', 'goodvibes-agent qrcode', 'goodvibes-agent surfaces check'],
74
- use: ['/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'],
76
- next: ['Add Agent-first channel onboarding workspace that exposes connected accounts, delivery defaults, and pairing state without daemon ownership.'],
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.',
80
+ configure: ['goodvibes-agent pair', 'goodvibes-agent qrcode', 'goodvibes-agent surfaces check', '/agent → Channels'],
81
+ use: ['/agent → Channels', '/communication', '/pair'],
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',
@@ -88,6 +88,27 @@ function snapshotLines(category: AgentWorkspaceCategory, snapshot: AgentWorkspac
88
88
  { text: `Workspace: ${snapshot.workingDirectory}`, fg: PALETTE.muted },
89
89
  { text: `Home: ${snapshot.homeDirectory}`, fg: PALETTE.muted },
90
90
  );
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(', ');
96
+ base.push(
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 },
100
+ { text: 'Pairing: use /pair or /qrcode for companion setup.', fg: PALETTE.info },
101
+ { text: 'Channel posture: inspect via /communication and /setup review.', fg: PALETTE.muted },
102
+ { text: 'Safety: external delivery, unknown senders, and public exposure require explicit policy and user action.', fg: PALETTE.warn },
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
+ }
91
112
  } else if (category.id === 'knowledge') {
92
113
  base.push(
93
114
  { text: `Route family: ${snapshot.knowledgeRoute}/{status,ask,search}`, fg: PALETTE.info },
@@ -222,7 +243,8 @@ function footerText(workspace: AgentWorkspace): string {
222
243
  }
223
244
 
224
245
  export function renderAgentWorkspace(workspace: AgentWorkspace, width: number, height: number): Line[] {
225
- const metrics = getFullscreenWorkspaceMetrics({ width, height, leftWidth: width < 90 ? undefined : 30, contextRatio: 0.48, minContextRows: 8 });
246
+ const layoutOptions = { width, height, leftWidth: width < 90 ? undefined : 30, contextRatio: 0.62, minContextRows: 10 };
247
+ const metrics = getFullscreenWorkspaceMetrics(layoutOptions);
226
248
  const category = workspace.selectedCategory;
227
249
  const action = workspace.selectedAction;
228
250
 
@@ -237,5 +259,8 @@ export function renderAgentWorkspace(workspace: AgentWorkspace, width: number, h
237
259
  contextRows: buildContextRows(workspace, category, action, metrics.contextWidth),
238
260
  controlRows: buildActionRows(workspace, metrics.contextWidth, metrics.controlRows),
239
261
  footer: footerText(workspace),
262
+ leftWidth: layoutOptions.leftWidth,
263
+ contextRatio: layoutOptions.contextRatio,
264
+ minContextRows: layoutOptions.minContextRows,
240
265
  });
241
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.28';
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 {