@pellux/goodvibes-tui 0.19.50 → 0.19.51
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 +11 -0
- package/README.md +1 -1
- package/docs/foundation-artifacts/operator-contract.json +1 -1
- package/package.json +2 -2
- package/src/daemon/cli.ts +8 -1
- package/src/daemon/safe-serve.ts +61 -0
- package/src/runtime/bootstrap.ts +23 -2
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@ All notable changes to GoodVibes TUI.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [0.19.51] — 2026-04-28
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- Updated `@pellux/goodvibes-sdk` to `0.26.6`.
|
|
11
|
+
- Embedded and standalone daemon hosts now wrap Bun request handlers so unexpected daemon/listener route exceptions return bounded JSON errors and are logged instead of printing raw stack/source output into the TUI terminal.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
- Picked up SDK Home Assistant Home Graph snapshot sync fixes for Home Assistant-native snake_case registry fields, incomplete registry objects, and JSON error responses from Home Graph admin routes.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
7
18
|
## [0.19.50] — 2026-04-28
|
|
8
19
|
|
|
9
20
|
### Changed
|
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": "0.19.
|
|
3
|
+
"version": "0.19.51",
|
|
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",
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"@anthropic-ai/vertex-sdk": "^0.16.0",
|
|
92
92
|
"@ast-grep/napi": "^0.42.0",
|
|
93
93
|
"@aws/bedrock-token-generator": "^1.1.0",
|
|
94
|
-
"@pellux/goodvibes-sdk": "0.26.
|
|
94
|
+
"@pellux/goodvibes-sdk": "0.26.6",
|
|
95
95
|
"bash-language-server": "^5.6.0",
|
|
96
96
|
"fuse.js": "^7.1.0",
|
|
97
97
|
"graphql": "^16.13.2",
|
package/src/daemon/cli.ts
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
loadPersistedProviders,
|
|
27
27
|
persistProviders,
|
|
28
28
|
} from '@pellux/goodvibes-sdk/platform/discovery/index';
|
|
29
|
+
import { createSafeHostServeFactory } from './safe-serve.ts';
|
|
29
30
|
|
|
30
31
|
import {
|
|
31
32
|
parseGoodVibesCli,
|
|
@@ -195,11 +196,17 @@ async function main(): Promise<void> {
|
|
|
195
196
|
});
|
|
196
197
|
|
|
197
198
|
const userAuth = runtimeServices.localUserAuthManager;
|
|
198
|
-
const daemon = new DaemonServer({
|
|
199
|
+
const daemon = new DaemonServer({
|
|
200
|
+
runtimeBus,
|
|
201
|
+
userAuth,
|
|
202
|
+
runtimeServices,
|
|
203
|
+
serveFactory: createSafeHostServeFactory('Standalone daemon'),
|
|
204
|
+
});
|
|
199
205
|
const listener = new HttpListener({
|
|
200
206
|
hookDispatcher: runtimeServices.hookDispatcher,
|
|
201
207
|
userAuth,
|
|
202
208
|
configManager: config,
|
|
209
|
+
serveFactory: createSafeHostServeFactory('Standalone HTTP listener'),
|
|
203
210
|
});
|
|
204
211
|
const { daemonToken, httpToken } = readDaemonCliTokens(process.env);
|
|
205
212
|
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { logger } from '@pellux/goodvibes-sdk/platform/utils/logger';
|
|
2
|
+
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils/error-display';
|
|
3
|
+
|
|
4
|
+
type HostServeFetch = (
|
|
5
|
+
request: Request,
|
|
6
|
+
server: unknown,
|
|
7
|
+
) => Response | undefined | Promise<Response | undefined>;
|
|
8
|
+
|
|
9
|
+
type HostServeOptions = Parameters<typeof Bun.serve>[0] & {
|
|
10
|
+
fetch?: HostServeFetch;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
function requestPath(request: Request): string {
|
|
14
|
+
try {
|
|
15
|
+
return new URL(request.url).pathname;
|
|
16
|
+
} catch {
|
|
17
|
+
return request.url;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function createHostRequestFailureResponse(
|
|
22
|
+
surface: string,
|
|
23
|
+
request: Request,
|
|
24
|
+
error: unknown,
|
|
25
|
+
): Response {
|
|
26
|
+
const message = summarizeError(error);
|
|
27
|
+
logger.error(`${surface}: request handler failed`, {
|
|
28
|
+
method: request.method,
|
|
29
|
+
path: requestPath(request),
|
|
30
|
+
error: message,
|
|
31
|
+
});
|
|
32
|
+
return Response.json({
|
|
33
|
+
error: message,
|
|
34
|
+
code: 'HOST_REQUEST_HANDLER_FAILED',
|
|
35
|
+
}, { status: 500 });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function createSafeHostServeFactory(
|
|
39
|
+
surface: string,
|
|
40
|
+
baseServeFactory: typeof Bun.serve = Bun.serve,
|
|
41
|
+
): typeof Bun.serve {
|
|
42
|
+
return ((options: HostServeOptions) => {
|
|
43
|
+
const originalFetch = options.fetch;
|
|
44
|
+
if (typeof originalFetch !== 'function') {
|
|
45
|
+
return baseServeFactory(options as Parameters<typeof Bun.serve>[0]);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const wrappedFetch: HostServeFetch = async (request, server) => {
|
|
49
|
+
try {
|
|
50
|
+
return await originalFetch(request, server);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
return createHostRequestFailureResponse(surface, request, error);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return baseServeFactory({
|
|
57
|
+
...options,
|
|
58
|
+
fetch: wrappedFetch,
|
|
59
|
+
} as Parameters<typeof Bun.serve>[0]);
|
|
60
|
+
}) as typeof Bun.serve;
|
|
61
|
+
}
|
package/src/runtime/bootstrap.ts
CHANGED
|
@@ -43,6 +43,11 @@ import { createDeferredStartupCoordinator } from '@pellux/goodvibes-sdk/platform
|
|
|
43
43
|
import { initializeBootstrapCore } from './bootstrap-core.ts';
|
|
44
44
|
import { createBootstrapShell } from './bootstrap-shell.ts';
|
|
45
45
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils/error-display';
|
|
46
|
+
import { DaemonServer } from '@pellux/goodvibes-sdk/platform/daemon/server';
|
|
47
|
+
import { HttpListener } from '@pellux/goodvibes-sdk/platform/daemon/http-listener';
|
|
48
|
+
import { createSafeHostServeFactory } from '../daemon/safe-serve.ts';
|
|
49
|
+
|
|
50
|
+
type ExternalServiceFactories = NonNullable<Parameters<typeof startExternalServices>[3]>;
|
|
46
51
|
|
|
47
52
|
// ── Bootstrap context type ──────────────────────────────────────────────────
|
|
48
53
|
|
|
@@ -350,6 +355,22 @@ export async function bootstrapRuntime(
|
|
|
350
355
|
]);
|
|
351
356
|
};
|
|
352
357
|
|
|
358
|
+
const createExternalServiceFactories = (sharedDaemonToken: string): ExternalServiceFactories => ({
|
|
359
|
+
sharedDaemonToken,
|
|
360
|
+
createDaemonServer: (bus, userAuth, runtimeServices) => new DaemonServer({
|
|
361
|
+
runtimeBus: bus,
|
|
362
|
+
userAuth,
|
|
363
|
+
runtimeServices,
|
|
364
|
+
serveFactory: createSafeHostServeFactory('Embedded daemon'),
|
|
365
|
+
}),
|
|
366
|
+
createHttpListener: (dispatcher, userAuth, configManager) => new HttpListener({
|
|
367
|
+
hookDispatcher: dispatcher,
|
|
368
|
+
userAuth,
|
|
369
|
+
configManager,
|
|
370
|
+
serveFactory: createSafeHostServeFactory('Embedded HTTP listener'),
|
|
371
|
+
}),
|
|
372
|
+
});
|
|
373
|
+
|
|
353
374
|
let externalServices: ExternalServicesHandle = {
|
|
354
375
|
daemonServer: null,
|
|
355
376
|
httpListener: null,
|
|
@@ -380,7 +401,7 @@ export async function bootstrapRuntime(
|
|
|
380
401
|
configManager,
|
|
381
402
|
runtimeBus,
|
|
382
403
|
hookDispatcher,
|
|
383
|
-
|
|
404
|
+
createExternalServiceFactories(companionTokenRecord.token),
|
|
384
405
|
services,
|
|
385
406
|
);
|
|
386
407
|
externalServices = await externalServicesPromise;
|
|
@@ -443,7 +464,7 @@ export async function bootstrapRuntime(
|
|
|
443
464
|
configManager,
|
|
444
465
|
runtimeBus,
|
|
445
466
|
hookDispatcher,
|
|
446
|
-
|
|
467
|
+
createExternalServiceFactories(companionTokenRecord.token),
|
|
447
468
|
services,
|
|
448
469
|
);
|
|
449
470
|
externalServices = await externalServicesPromise;
|
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.19.
|
|
9
|
+
let _version = '0.19.51';
|
|
10
10
|
try {
|
|
11
11
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8'));
|
|
12
12
|
_version = pkg.version ?? _version;
|