@pellux/goodvibes-tui 1.19.2 → 1.19.4
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 +17 -0
- package/README.md +1 -1
- package/docs/foundation-artifacts/operator-contract.json +1 -1
- package/package.json +7 -8
- package/src/cli/tui-startup.ts +26 -0
- package/src/core/conversation-line-cache.ts +1 -1
- package/src/core/conversation-rendering.ts +68 -2
- package/src/main.ts +2 -2
- package/src/runtime/bootstrap.ts +6 -6
- package/src/runtime/context-accounting-source.ts +14 -0
- package/src/runtime/provider-fallback.ts +31 -0
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,23 @@ All notable changes to GoodVibes TUI.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [1.19.4] - 2026-07-17
|
|
8
|
+
|
|
9
|
+
### Changes
|
|
10
|
+
|
|
11
|
+
Fixed: selecting a custom-provider model no longer crashes the app at the next startup — boot now waits for custom providers to load before resolving the current model, and falls back to a selectable model (with a logged warning) if the configured provider's file was removed.
|
|
12
|
+
Fixed: startup failures now print a clear "goodvibes failed to start" message with the real error and exit, instead of hanging on a blank screen while the log recorded an empty error object.
|
|
13
|
+
Fixed: after an automatic context compaction, the transcript shows a compact expandable "compaction handoff" block instead of re-printing the entire re-injected instruction text every time.
|
|
14
|
+
Updated: @pellux/goodvibes-sdk and @pellux/goodvibes-terminal-shell to 1.11.3 (quieter startup when no hooks file exists; error summaries no longer mangle redacted paths).
|
|
15
|
+
|
|
16
|
+
## [1.19.3] - 2026-07-17
|
|
17
|
+
|
|
18
|
+
### Changes
|
|
19
|
+
|
|
20
|
+
- Adopt published SDK 1.11.2, which now carries `@pellux/goodvibes-toolchain` as a real dependency of its own — the toolchain devDependency pin is no longer needed here and has been dropped; it resolves transitively through the SDK.
|
|
21
|
+
- Adopt zero-touch releases: a green CI run on a push to main now tags the release commit and dispatches the release workflow automatically (`ci.yml`'s new `auto-release` job), instead of requiring a manual tag push. `release.yml` gains a `workflow_dispatch` `mode` input (`dry-run` default, `release`) so a release-mode dispatch runs the full publish topology that used to be push-only, while a plain dispatch still behaves as the existing dry-validation path.
|
|
22
|
+
- e1e4f446 deps: adopt published SDK 1.11.2 + zero-touch release adoption
|
|
23
|
+
|
|
7
24
|
## [1.19.2] - 2026-07-17
|
|
8
25
|
|
|
9
26
|
### Changes
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/mgd34msu/goodvibes-tui/actions/workflows/ci.yml)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
|
-
[](https://github.com/mgd34msu/goodvibes-tui)
|
|
6
6
|
|
|
7
7
|
A terminal-native AI coding, operations, automation, knowledge, and integration console with a typed runtime, omnichannel surfaces, structured memory/knowledge, and a raw ANSI renderer.
|
|
8
8
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-tui",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.4",
|
|
4
4
|
"description": "Terminal-native GoodVibes product for coding, operations, automation, knowledge, channels, and daemon-backed control-plane workflows.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/main.ts",
|
|
@@ -104,8 +104,8 @@
|
|
|
104
104
|
"@anthropic-ai/vertex-sdk": "^0.16.0",
|
|
105
105
|
"@ast-grep/napi": "^0.42.0",
|
|
106
106
|
"@aws/bedrock-token-generator": "^1.1.0",
|
|
107
|
-
"@pellux/goodvibes-sdk": "1.11.
|
|
108
|
-
"@pellux/goodvibes-terminal-shell": "1.11.
|
|
107
|
+
"@pellux/goodvibes-sdk": "1.11.3",
|
|
108
|
+
"@pellux/goodvibes-terminal-shell": "1.11.3",
|
|
109
109
|
"bash-language-server": "^5.6.0",
|
|
110
110
|
"fuse.js": "^7.1.0",
|
|
111
111
|
"graphql": "^16.13.2",
|
|
@@ -127,15 +127,14 @@
|
|
|
127
127
|
"zustand": "^5.0.12"
|
|
128
128
|
},
|
|
129
129
|
"devDependencies": {
|
|
130
|
-
"@pellux/goodvibes-toolchain": "1.11.1",
|
|
131
130
|
"@types/bun": "^1.3.10",
|
|
132
131
|
"typescript": "^5.9.3"
|
|
133
132
|
},
|
|
134
133
|
"optionalDependencies": {
|
|
135
|
-
"@pellux/goodvibes-tui-linux-x64": "1.19.
|
|
136
|
-
"@pellux/goodvibes-tui-linux-arm64": "1.19.
|
|
137
|
-
"@pellux/goodvibes-tui-darwin-x64": "1.19.
|
|
138
|
-
"@pellux/goodvibes-tui-darwin-arm64": "1.19.
|
|
134
|
+
"@pellux/goodvibes-tui-linux-x64": "1.19.4",
|
|
135
|
+
"@pellux/goodvibes-tui-linux-arm64": "1.19.4",
|
|
136
|
+
"@pellux/goodvibes-tui-darwin-x64": "1.19.4",
|
|
137
|
+
"@pellux/goodvibes-tui-darwin-arm64": "1.19.4"
|
|
139
138
|
},
|
|
140
139
|
"trustedDependencies": [],
|
|
141
140
|
"overrides": {
|
package/src/cli/tui-startup.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { WorkspaceRegistrationManager } from '../runtime/trust/workspace-re
|
|
|
5
5
|
import { hasResumableWizardProgress, readOnboardingCheckMarker, readWizardProgress } from '../runtime/onboarding/index.ts';
|
|
6
6
|
import { startOnboardingFastPath } from '../runtime/onboarding/fast-path.ts';
|
|
7
7
|
import { readLastSessionPointer } from '@/runtime/index.ts';
|
|
8
|
+
import { logger } from '@pellux/goodvibes-sdk/platform/utils';
|
|
8
9
|
import type { GoodVibesCliParseResult } from './types.ts';
|
|
9
10
|
|
|
10
11
|
export type TuiStartupShellPaths = Parameters<typeof readOnboardingCheckMarker>[0] & {
|
|
@@ -173,3 +174,28 @@ export function applyInitialTuiCliState(options: {
|
|
|
173
174
|
// request, not here — see main.ts's trustPromptRef wiring.
|
|
174
175
|
}
|
|
175
176
|
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* reportFatalStartupError — the main() catch handler. A bare Error
|
|
180
|
+
* JSON-serializes to {} in structured logs, and background timers keep the
|
|
181
|
+
* process alive after a boot failure — the historical result was a blank
|
|
182
|
+
* screen and a useless `Fatal error {"error": {}}` log line. Log real
|
|
183
|
+
* fields, tell the user what broke, and exit. Both writes are individually
|
|
184
|
+
* best-effort — a failing logger or torn-down stderr must never hide the
|
|
185
|
+
* original launch failure.
|
|
186
|
+
*/
|
|
187
|
+
export function reportFatalStartupError(err: unknown): void {
|
|
188
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
189
|
+
const stack = err instanceof Error ? err.stack : undefined;
|
|
190
|
+
try {
|
|
191
|
+
logger.error('Fatal error', { message, ...(stack ? { stack } : {}) });
|
|
192
|
+
} catch {
|
|
193
|
+
// Startup diagnostics must never hide the original launch failure.
|
|
194
|
+
}
|
|
195
|
+
try {
|
|
196
|
+
process.stderr.write(`goodvibes failed to start: ${message}\n${stack ? `${stack}\n` : ''}`);
|
|
197
|
+
} catch {
|
|
198
|
+
// Ignore secondary stderr failures during process teardown.
|
|
199
|
+
}
|
|
200
|
+
process.exit(1);
|
|
201
|
+
}
|
|
@@ -224,7 +224,7 @@ function renderOne(
|
|
|
224
224
|
cfg: RenderConfig,
|
|
225
225
|
): void {
|
|
226
226
|
if (message.role === 'user') {
|
|
227
|
-
renderConversationUserMessage(ctx, message, width);
|
|
227
|
+
renderConversationUserMessage(ctx, message, width, absoluteIdx);
|
|
228
228
|
} else if (message.role === 'assistant') {
|
|
229
229
|
renderConversationAssistantMessage(ctx, message, width, cfg.lineNumberMode, cfg.collapseThreshold, absoluteIdx);
|
|
230
230
|
} else if (message.role === 'system') {
|
|
@@ -17,7 +17,7 @@ import { GLYPHS } from '../renderer/ui-primitives.ts';
|
|
|
17
17
|
import type { BlockMeta } from './conversation-types.ts';
|
|
18
18
|
import type { ConversationMessageSnapshot } from '@pellux/goodvibes-sdk/platform/core';
|
|
19
19
|
import { parseDiffForApply } from '@pellux/goodvibes-sdk/platform/core';
|
|
20
|
-
import { extractUserDisplayText } from '@pellux/goodvibes-sdk/platform/core';
|
|
20
|
+
import { extractUserDisplayText, COMPACTION_HANDOFF_HEADER } from '@pellux/goodvibes-sdk/platform/core';
|
|
21
21
|
// SystemMessageKind imported from runtime directly to avoid cycle:
|
|
22
22
|
// conversation-rendering.ts → system-message-router.ts → conversation.ts → conversation-rendering.ts
|
|
23
23
|
import type { SystemMessageKind } from '@/runtime/index.ts';
|
|
@@ -88,6 +88,7 @@ export function renderConversationUserMessage(
|
|
|
88
88
|
context: ConversationRenderContext,
|
|
89
89
|
message: Extract<Message, { role: 'user' }>,
|
|
90
90
|
width: number,
|
|
91
|
+
msgIdx?: number,
|
|
91
92
|
): void {
|
|
92
93
|
const T = activeTheme();
|
|
93
94
|
const displayText = extractUserDisplayText(message.content);
|
|
@@ -95,9 +96,74 @@ export function renderConversationUserMessage(
|
|
|
95
96
|
context.history.addLines(UIFactory.createMessageBar(width, displayText, T.errorBarBg, '196', ' x ', true));
|
|
96
97
|
return;
|
|
97
98
|
}
|
|
99
|
+
// Compaction-continuation handoff: a user-ROLE message the compactor
|
|
100
|
+
// authored, not something the user typed. Rendered in full it repeats the
|
|
101
|
+
// entire re-injected instruction block after every automatic compaction —
|
|
102
|
+
// a multi-kilobyte wall in the transcript. Fold it like a tool result; the
|
|
103
|
+
// full payload stays reachable through the normal expand toggle.
|
|
104
|
+
if (msgIdx !== undefined && displayText.startsWith(COMPACTION_HANDOFF_HEADER)) {
|
|
105
|
+
renderCompactionContinuationMessage(context, displayText, width, msgIdx);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
98
108
|
context.history.addLines(UIFactory.createMessageBar(width, displayText));
|
|
99
109
|
}
|
|
100
110
|
|
|
111
|
+
/** Fold a compaction-continuation user message to one header + preview line. */
|
|
112
|
+
function renderCompactionContinuationMessage(
|
|
113
|
+
context: ConversationRenderContext,
|
|
114
|
+
content: string,
|
|
115
|
+
width: number,
|
|
116
|
+
msgIdx: number,
|
|
117
|
+
): void {
|
|
118
|
+
const T = activeTheme();
|
|
119
|
+
const collapseKey = `msg_${msgIdx}`;
|
|
120
|
+
const blockIdx = context.blockRegistry.length;
|
|
121
|
+
const startLine = context.history.getLineCount();
|
|
122
|
+
const lineCount = content.split('\n').length;
|
|
123
|
+
const isCollapsed = context.collapseState.has(collapseKey)
|
|
124
|
+
? context.collapseState.get(collapseKey)!
|
|
125
|
+
: true;
|
|
126
|
+
if (!context.collapseState.has(collapseKey)) {
|
|
127
|
+
context.collapseState.set(collapseKey, true);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
context.history.addLine(renderConversationEventLine(width, {
|
|
131
|
+
marker: GLYPHS.status.active,
|
|
132
|
+
markerFg: T.toolAccent,
|
|
133
|
+
label: 'compaction handoff',
|
|
134
|
+
labelFg: T.toolAccent,
|
|
135
|
+
detailFg: '244',
|
|
136
|
+
}, [
|
|
137
|
+
{ text: ` ${isCollapsed ? GLYPHS.navigation.collapsed : GLYPHS.navigation.expanded} ${lineCount} line${lineCount === 1 ? '' : 's'} `, fg: '244', dim: true },
|
|
138
|
+
]));
|
|
139
|
+
|
|
140
|
+
if (isCollapsed) {
|
|
141
|
+
const rendered = renderConversationCollapsedFragment(
|
|
142
|
+
'compacted-context handoff (re-injected instructions + session summary)',
|
|
143
|
+
width,
|
|
144
|
+
{
|
|
145
|
+
prefix: ` ${GLYPHS.navigation.collapsed} `,
|
|
146
|
+
prefixFg: T.toolAccent,
|
|
147
|
+
text: '244',
|
|
148
|
+
bodyBg: T.collapsedBodyBg,
|
|
149
|
+
dim: true,
|
|
150
|
+
},
|
|
151
|
+
);
|
|
152
|
+
context.history.addLines(rendered);
|
|
153
|
+
} else {
|
|
154
|
+
context.history.addLines(renderMarkdownTracked(content, width).lines);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
context.blockRegistry.push({
|
|
158
|
+
blockIndex: blockIdx,
|
|
159
|
+
collapseKey,
|
|
160
|
+
type: 'tool',
|
|
161
|
+
startLine,
|
|
162
|
+
lineCount: context.history.getLineCount() - startLine,
|
|
163
|
+
rawContent: content,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
101
167
|
export function renderConversationAssistantMessage(
|
|
102
168
|
context: ConversationRenderContext,
|
|
103
169
|
message: Extract<Message, { role: 'assistant' }>,
|
|
@@ -400,7 +466,7 @@ export function appendConversationMessages(
|
|
|
400
466
|
const absoluteIdx = msgIndexOffset + msgIdx;
|
|
401
467
|
messageLineRegistry[absoluteIdx] = renderContext.history.getLineCount();
|
|
402
468
|
if (message.role === 'user') {
|
|
403
|
-
renderConversationUserMessage(renderContext, message, width);
|
|
469
|
+
renderConversationUserMessage(renderContext, message, width, absoluteIdx);
|
|
404
470
|
} else if (message.role === 'assistant') {
|
|
405
471
|
renderConversationAssistantMessage(renderContext, message, width, lineNumberMode, collapseThreshold, absoluteIdx);
|
|
406
472
|
} else if (message.role === 'system') {
|
package/src/main.ts
CHANGED
|
@@ -45,7 +45,7 @@ import { deriveComposerState } from './core/composer-state.ts';
|
|
|
45
45
|
import { buildPersistedSessionContext, getReturnContextMode, maybeAssistReturnContextSummary } from '@/runtime/index.ts';
|
|
46
46
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
47
47
|
import { prepareShellCliRuntime } from './cli/entrypoint.ts';
|
|
48
|
-
import { applyInitialTuiCliState } from './cli/tui-startup.ts';
|
|
48
|
+
import { applyInitialTuiCliState, reportFatalStartupError } from './cli/tui-startup.ts';
|
|
49
49
|
import { applyConfiguredHitlMode, applyRuntimeConfigValue, applyTuiRuntimeConfigDefaults } from './cli/config-overrides.ts';
|
|
50
50
|
import { renderToolCallBlock } from './renderer/tool-call.ts';
|
|
51
51
|
import { wireSpokenTurnRuntime } from './audio/spoken-turn-wiring.ts';
|
|
@@ -797,4 +797,4 @@ async function main() {
|
|
|
797
797
|
|
|
798
798
|
}
|
|
799
799
|
|
|
800
|
-
main().catch(
|
|
800
|
+
main().catch(reportFatalStartupError);
|
package/src/runtime/bootstrap.ts
CHANGED
|
@@ -37,12 +37,13 @@ import { pruneStaleOperatorTokens } from '@pellux/goodvibes-sdk/platform/pairing
|
|
|
37
37
|
import { resolveDaemonCompanionToken, workspaceOperatorTokenCandidates } from './operator-token-cleanup.ts';
|
|
38
38
|
import type { UiRuntimeServices } from './ui-services.ts';
|
|
39
39
|
import { initializeBootstrapCore } from './bootstrap-core.ts';
|
|
40
|
+
import { ensureBootModelResolvable } from './provider-fallback.ts';
|
|
40
41
|
import { createBootstrapShell } from './bootstrap-shell.ts';
|
|
41
42
|
import { announceResumeState } from './resume-notice.ts';
|
|
42
43
|
import { announceInstallSelfCheck } from './install-self-check-startup.ts';
|
|
43
44
|
import { buildSharedOrchestratorCoreServices, refreshMemoryRecallSnapshot } from './orchestrator-core-services.ts';
|
|
44
45
|
import { consumeDaemonAttachNotices, consumeExternalDaemonAttachNotices } from './daemon-attach-notices.ts';
|
|
45
|
-
import {
|
|
46
|
+
import { wireContextAccountingSource } from './context-accounting-source.ts';
|
|
46
47
|
import { createEmbeddedServiceFactories } from './embedded-service-factories.ts';
|
|
47
48
|
import { buildRelayExternalServiceMethods } from './relay-reachability-bridge.ts';
|
|
48
49
|
import { startMcpConfigAutoReload } from '../mcp/runtime-reload.ts';
|
|
@@ -194,7 +195,8 @@ export async function bootstrapRuntime(
|
|
|
194
195
|
panelManager,
|
|
195
196
|
pluginManager,
|
|
196
197
|
} = services;
|
|
197
|
-
|
|
198
|
+
// A saved custom-provider model must never crash boot — see provider-fallback.ts.
|
|
199
|
+
await ensureBootModelResolvable(providerRegistry, configManager);
|
|
198
200
|
// A liveness flip is only PAINTED once something calls requestRender(); without
|
|
199
201
|
// this, the footer's spine segment sat correct-but-undrawn until incidental activity redrew it (minutes, during an idle stretch).
|
|
200
202
|
sessionUnionCache.setOnTransition(() => requestRender());
|
|
@@ -248,11 +250,9 @@ export async function bootstrapRuntime(
|
|
|
248
250
|
conversation.setSessionLineageTracker(services.sessionLineageTracker);
|
|
249
251
|
|
|
250
252
|
// Bind context_accounting's session source to the live Orchestrator (see context-accounting-source.ts).
|
|
251
|
-
|
|
253
|
+
wireContextAccountingSource({
|
|
252
254
|
orchestrator, providerRegistry, sessionLineageTracker: services.sessionLineageTracker, runtimeBus, sessionId: runtime.sessionId,
|
|
253
|
-
});
|
|
254
|
-
services.contextAccountingHolder.setSource(contextAccountingSourceHandle.source);
|
|
255
|
-
bootstrapUnsubs.push(contextAccountingSourceHandle.dispose);
|
|
255
|
+
}, services.contextAccountingHolder, bootstrapUnsubs);
|
|
256
256
|
|
|
257
257
|
const acpManager = new AcpManager({
|
|
258
258
|
requestPermission: (request) => permissionPromptRef.requestPermission(request),
|
|
@@ -101,3 +101,17 @@ export function createContextAccountingSource(deps: ContextAccountingSourceDeps)
|
|
|
101
101
|
dispose: () => { for (const unsub of unsubs) unsub(); },
|
|
102
102
|
};
|
|
103
103
|
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Create the source, install it on the holder, and register its dispose on
|
|
107
|
+
* the caller's unsubscribe list — the one-call bootstrap wiring.
|
|
108
|
+
*/
|
|
109
|
+
export function wireContextAccountingSource(
|
|
110
|
+
deps: ContextAccountingSourceDeps,
|
|
111
|
+
holder: { setSource: (source: ContextAccountingSourceHandle['source']) => void },
|
|
112
|
+
unsubs: Array<() => void>,
|
|
113
|
+
): void {
|
|
114
|
+
const handle = createContextAccountingSource(deps);
|
|
115
|
+
holder.setSource(handle.source);
|
|
116
|
+
unsubs.push(handle.dispose);
|
|
117
|
+
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { ConfigManager } from '@pellux/goodvibes-sdk/platform/config';
|
|
9
9
|
import { inferFallbackContextWindow, type ModelDefinition, type ProviderRegistry } from '@pellux/goodvibes-sdk/platform/providers';
|
|
10
|
+
import { logger } from '@pellux/goodvibes-sdk/platform/utils';
|
|
10
11
|
|
|
11
12
|
function buildFallbackModelDefinition(provider: string, modelId: string): ModelDefinition {
|
|
12
13
|
const providerLower = provider.toLowerCase();
|
|
@@ -53,3 +54,33 @@ export function ensureConfiguredModelIsRoutable(providerRegistry: ProviderRegist
|
|
|
53
54
|
models: [buildFallbackModelDefinition(providerId, modelId)],
|
|
54
55
|
});
|
|
55
56
|
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Boot-time custom-provider readiness. Custom providers register
|
|
60
|
+
* asynchronously (services.ts fires initCustomProviders() without awaiting),
|
|
61
|
+
* while the boot path resolves the current model synchronously — without
|
|
62
|
+
* waiting here, a saved provider.model that points at a custom provider
|
|
63
|
+
* throws "not in registry" before the first frame renders. The routability
|
|
64
|
+
* guard must re-run after ready(): its services-composition pass bails when
|
|
65
|
+
* the provider itself isn't registered yet, which is exactly the
|
|
66
|
+
* custom-provider case. As a last resort (the configured provider's file was
|
|
67
|
+
* deleted entirely), boot on a real selectable model with a warning instead
|
|
68
|
+
* of dying before the UI exists.
|
|
69
|
+
*/
|
|
70
|
+
export async function ensureBootModelResolvable(
|
|
71
|
+
providerRegistry: ProviderRegistry,
|
|
72
|
+
configManager: ConfigManager,
|
|
73
|
+
): Promise<void> {
|
|
74
|
+
await providerRegistry.ready();
|
|
75
|
+
ensureConfiguredModelIsRoutable(providerRegistry, configManager);
|
|
76
|
+
try {
|
|
77
|
+
providerRegistry.getCurrentModel();
|
|
78
|
+
} catch (err) {
|
|
79
|
+
const configured = String(configManager.get('provider.model') ?? '');
|
|
80
|
+
const replacement = providerRegistry.getSelectableModels()[0]?.registryKey;
|
|
81
|
+
if (!replacement) throw err;
|
|
82
|
+
providerRegistry.setCurrentModel(replacement);
|
|
83
|
+
configManager.set('provider.model', replacement);
|
|
84
|
+
logger.warn(`[bootstrap] Configured model '${configured}' is not resolvable (its provider is not registered); switched to '${replacement}'.`);
|
|
85
|
+
}
|
|
86
|
+
}
|
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 = '1.19.
|
|
9
|
+
let _version = '1.19.4';
|
|
10
10
|
try {
|
|
11
11
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8'));
|
|
12
12
|
// Only trust a version read from OUR OWN package.json. A Bun single-file
|