@pellux/goodvibes-tui 0.18.4 → 0.18.8
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 +154 -0
- package/README.md +2 -2
- package/bin/goodvibes +1 -1
- package/bin/goodvibes-daemon +66 -0
- package/docs/foundation-artifacts/operator-contract.json +1 -1
- package/package.json +14 -7
- package/scripts/postinstall.js +220 -0
- package/src/agents/orchestrator.ts +1 -1
- package/src/input/commands/discovery-runtime.ts +7 -1
- package/src/input/commands/local-setup-review.ts +1 -1
- package/src/input/commands/local-setup.ts +1 -1
- package/src/input/commands/platform-sandbox-qemu.ts +3 -3
- package/src/input/commands/platform-sandbox-runtime.ts +5 -5
- package/src/input/commands/platform-sandbox-session.ts +1 -1
- package/src/mcp/registry.ts +3 -5
- package/src/panels/builtin/shared.ts +1 -1
- package/src/panels/sandbox-panel.ts +2 -2
- package/src/panels/skills-panel.ts +28 -1
- package/src/runtime/bootstrap-background.ts +14 -4
- package/src/runtime/bootstrap-command-context.ts +1 -1
- package/src/runtime/bootstrap-command-parts.ts +1 -1
- package/src/runtime/context.ts +1 -1
- package/src/runtime/services.ts +7 -3
- package/src/runtime/shell-command-services.ts +1 -1
- package/src/runtime/shell-command-workspace.ts +1 -1
- package/src/tools/control/index.ts +1 -1
- package/src/tools/index.ts +7 -7
- package/src/version.ts +1 -1
- package/docs/README.md +0 -32
- package/scripts/postinstall.mjs +0 -203
- package/src/runtime/sandbox/backend.ts +0 -291
- package/src/runtime/sandbox/manager.ts +0 -364
- package/src/runtime/sandbox/provisioning.ts +0 -422
- package/src/runtime/sandbox/session-registry.ts +0 -289
- package/src/tools/repl/index.ts +0 -318
package/CHANGELOG.md
CHANGED
|
@@ -4,8 +4,156 @@ All notable changes to GoodVibes TUI.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [0.18.8] — 2026-04-15
|
|
8
|
+
|
|
9
|
+
### Canonical SDK Cutover Completion
|
|
10
|
+
|
|
11
|
+
- Switched the TUI to the canonical published SDK line at `@pellux/goodvibes-sdk@0.18.21`
|
|
12
|
+
- Removed the remaining local REPL and sandbox runtime implementations from the TUI and routed those flows through SDK-owned package imports instead
|
|
13
|
+
- Rewired command, MCP, panel, and runtime call sites that were still holding local platform copies so the TUI now consumes the shared SDK surface instead of carrying duplicate implementations
|
|
14
|
+
|
|
15
|
+
### TUI-Owned Configuration Boundary Fixes
|
|
16
|
+
|
|
17
|
+
- Kept product-owned storage and runtime identity at `.goodvibes/tui/...` by making the TUI pass explicit host configuration into SDK-owned services instead of inheriting SDK defaults
|
|
18
|
+
- Wired cross-session task graphs to the TUI-owned path under `.goodvibes/tui/sessions/task-graph.json`
|
|
19
|
+
- Instantiated the team and worklist tools with explicit `surfaceRoot: 'tui'` host configuration instead of relying on SDK defaults
|
|
20
|
+
- Aligned language-override and secret-store tests with the real TUI-owned configuration boundary
|
|
21
|
+
|
|
22
|
+
### Release-Path And Test Hardening
|
|
23
|
+
|
|
24
|
+
- Added per-file repo-local temp roots in `scripts/run-tests.ts` so the full TUI test suite no longer collides on shared temp filesystems
|
|
25
|
+
- Reworked tests that still wrote to `/tmp` or shared temp roots so they now use the active temp root or an explicit external directory when validating escape behavior
|
|
26
|
+
- Fixed the intelligence test helper to lazily initialize its runtime singletons, eliminating the module-init cycle that surfaced after the SDK cutover
|
|
27
|
+
- Improved the Skills panel detail path rendering so long skill origins keep the useful suffix visible instead of clipping away the selected file
|
|
28
|
+
|
|
29
|
+
### Verification
|
|
30
|
+
|
|
31
|
+
- Full typecheck passes: `bun x tsc --noEmit --pretty false`
|
|
32
|
+
- Full test runner passes locally: `bun run test`
|
|
33
|
+
- Architecture gate passes: `bun run architecture:check`
|
|
34
|
+
- Performance gate passes: `bun run perf:check`
|
|
35
|
+
- Eval gate passes: `bun run eval:gate`
|
|
36
|
+
- Foundation artifacts export passes: `bun run foundation:artifacts`
|
|
37
|
+
- Build passes: `bun run build`
|
|
38
|
+
- Publish packaging check passes: `bun run publish:check`
|
|
39
|
+
- Staged npm package rehearsal passes: `bun run publish:dry-run`
|
|
40
|
+
- Staged GitHub Packages rehearsal passes: `bun run publish:dry-run:github`
|
|
41
|
+
- Local package install smoke passes through `postinstall` with staged release artifacts
|
|
42
|
+
- Diff hygiene passes: `git diff --check`
|
|
43
|
+
|
|
44
|
+
## [0.18.7] — 2026-04-14
|
|
45
|
+
|
|
46
|
+
Superseded before successful public registry release. The release workflow got past the package-install fix, but the REPL tool and REPL test harness were still allocating temp state under constrained temp filesystems, which failed the test phase before publish. The corrected release shipped in `0.18.8`.
|
|
47
|
+
|
|
48
|
+
### Release Workflow Install Fix
|
|
49
|
+
|
|
50
|
+
- Fixed the TUI package postinstall path so source checkouts no longer try to download release binaries during `bun install`
|
|
51
|
+
- This unblocks CI and release validation jobs, which install repo dependencies before the GitHub Release assets exist
|
|
52
|
+
- Kept the actual packaged install behavior unchanged: published npm and GitHub Packages installs still download the matching TUI and standalone daemon binaries during `postinstall`
|
|
53
|
+
|
|
54
|
+
### Verification
|
|
55
|
+
|
|
56
|
+
- Full typecheck passes: `bun x tsc --noEmit --pretty false`
|
|
57
|
+
- Publish packaging check passes: `bun run publish:check`
|
|
58
|
+
- Staged npm package rehearsal passes: `bun run publish:dry-run`
|
|
59
|
+
- Staged GitHub Packages rehearsal passes: `bun run publish:dry-run:github`
|
|
60
|
+
- Local package install smoke passes through `postinstall` with staged release artifacts
|
|
61
|
+
- Diff hygiene passes: `git diff --check`
|
|
62
|
+
|
|
63
|
+
## [0.18.6] — 2026-04-14
|
|
64
|
+
|
|
65
|
+
Superseded before successful public registry release. The repo checkout still ran the binary-download `postinstall` during CI `bun install`, which blocked the tagged release before publish. The corrected release shipped in `0.18.7`.
|
|
66
|
+
|
|
67
|
+
### Public Package Delivery Fix
|
|
68
|
+
|
|
69
|
+
- Replaced the oversized bundled-binary npm package model with a smaller package that installs the matching TUI and standalone daemon binaries during `postinstall`
|
|
70
|
+
- Kept the package identities as `@pellux/goodvibes-tui` on npmjs and `@mgd34msu/goodvibes-tui` on GitHub Packages while keeping the installed CLI surface as `goodvibes` and `goodvibes-daemon`
|
|
71
|
+
- Kept the runtime fallback path so installs can still run from Bun + source if a platform binary is unavailable, but made the intended install path the version-matched release binaries
|
|
72
|
+
|
|
73
|
+
### Release Workflow Correction
|
|
74
|
+
|
|
75
|
+
- Reordered the release workflow so the GitHub Release and binary assets are created before npmjs and GitHub Packages publishing, ensuring package installs can fetch release assets immediately after publish
|
|
76
|
+
- Reworked install-smoke validation so the packed npm tarball is tested through the real `postinstall` path that installs both the TUI and daemon binaries for the current platform
|
|
77
|
+
- Hardened publish validation so registry tarballs fail if they accidentally include vendored binaries again or exceed the package-size guardrail
|
|
78
|
+
|
|
79
|
+
### Verification
|
|
80
|
+
|
|
81
|
+
- Full typecheck passes: `bun x tsc --noEmit --pretty false`
|
|
82
|
+
- Publish packaging check passes: `bun run publish:check`
|
|
83
|
+
- Staged npm package rehearsal passes: `bun run publish:dry-run`
|
|
84
|
+
- Staged GitHub Packages rehearsal passes: `bun run publish:dry-run:github`
|
|
85
|
+
- Local package install smoke passes through `postinstall` with staged release artifacts
|
|
86
|
+
- Diff hygiene passes: `git diff --check`
|
|
87
|
+
|
|
88
|
+
## [0.18.5] — 2026-04-14
|
|
89
|
+
|
|
90
|
+
Superseded before successful public registry release. The bundled-binary tarball for this version exceeded npmjs and GitHub Packages size limits, and the corrected public package model shipped in `0.18.6`.
|
|
91
|
+
|
|
92
|
+
### Public Package And Release Correction
|
|
93
|
+
|
|
94
|
+
- Corrected the public packaged release path after the initial `0.18.4` cutover so the shipped npm distribution now matches the actual intended install model
|
|
95
|
+
- Published the TUI on npm as `@pellux/goodvibes-tui` and mirrored the same release to GitHub Packages as `@mgd34msu/goodvibes-tui`
|
|
96
|
+
- Kept the installed CLI surface as `goodvibes` and `goodvibes-daemon` while moving the package identity to the scoped release names
|
|
97
|
+
- Added both launcher bins to the packaged distribution so global installs expose the interactive TUI and the standalone daemon directly on the user path
|
|
98
|
+
|
|
99
|
+
### Bundled Binary Delivery
|
|
100
|
+
|
|
101
|
+
- Bundled the compiled TUI binaries directly into the npm package for:
|
|
102
|
+
- Linux x64
|
|
103
|
+
- Linux arm64
|
|
104
|
+
- macOS x64
|
|
105
|
+
- macOS arm64
|
|
106
|
+
- Bundled the standalone daemon binaries directly into the npm package for:
|
|
107
|
+
- Linux x64
|
|
108
|
+
- Linux arm64
|
|
109
|
+
- macOS x64
|
|
110
|
+
- macOS arm64
|
|
111
|
+
- Removed the prior install-time binary download behavior so npm installs now use the packaged binaries already present in `vendor/`
|
|
112
|
+
- Added packaged release checksums through `vendor/SHA256SUMS.txt` and release-asset `SHA256SUMS.txt`
|
|
113
|
+
|
|
114
|
+
### Release Automation And Publish Path Hardening
|
|
115
|
+
|
|
116
|
+
- Added staged vendor-binary packaging so npm and GitHub Packages publishes are built from the same explicit bundled-binary package shape
|
|
117
|
+
- Added a dedicated publish-packaging path for registry release publishing instead of depending on raw repo copies during publish
|
|
118
|
+
- Added a GitHub Packages publish job alongside the npmjs publish job in the release workflow
|
|
119
|
+
- Fixed staged publish rehearsal so local dry-runs validate the real publishable package shape without tripping registry version conflicts or temporary-filesystem quota failures
|
|
120
|
+
- Extended release validation and install smoke coverage to require both launcher bins and both bundled binary families
|
|
121
|
+
|
|
122
|
+
### Verification
|
|
123
|
+
|
|
124
|
+
- Full typecheck passes: `bun x tsc --noEmit --pretty false`
|
|
125
|
+
- Architecture gate passes: `bun run architecture:check`
|
|
126
|
+
- Performance gate passes: `bun run perf:check`
|
|
127
|
+
- Eval gate passes: `bun run eval:gate`
|
|
128
|
+
- Full test runner passes: `bun run test`
|
|
129
|
+
- Build passes: `bun run build`
|
|
130
|
+
- Foundation artifact export passes: `bun run foundation:artifacts`
|
|
131
|
+
- Vendored binary staging passes: `bun run vendor:stage --clean`
|
|
132
|
+
- Publish packaging check passes: `bun run publish:check`
|
|
133
|
+
- Staged npm package rehearsal passes: `bun run publish:dry-run`
|
|
134
|
+
- Staged GitHub Packages rehearsal passes: `bun run publish:dry-run:github`
|
|
135
|
+
- Diff hygiene passes: `git diff --check`
|
|
136
|
+
|
|
7
137
|
## [0.18.4] — 2026-04-14
|
|
8
138
|
|
|
139
|
+
### First Public Distribution And Delivery
|
|
140
|
+
|
|
141
|
+
- Published the TUI under the Pellux scope as `@pellux/goodvibes-tui` while keeping the installed CLI commands as `goodvibes` and `goodvibes-daemon`
|
|
142
|
+
- Added a GitHub Packages mirror as `@mgd34msu/goodvibes-tui`
|
|
143
|
+
- Bundled the compiled TUI and standalone daemon binaries directly into the npm package instead of relying on install-time downloads
|
|
144
|
+
- Added both `goodvibes` and `goodvibes-daemon` launcher bins to the package so global npm installs expose both commands on the user path
|
|
145
|
+
- Expanded the release asset set to ship compiled binaries for:
|
|
146
|
+
- Linux x64
|
|
147
|
+
- Linux arm64
|
|
148
|
+
- macOS x64
|
|
149
|
+
- macOS arm64
|
|
150
|
+
- Expanded the release asset set to ship standalone daemon binaries for:
|
|
151
|
+
- Linux x64
|
|
152
|
+
- Linux arm64
|
|
153
|
+
- macOS x64
|
|
154
|
+
- macOS arm64
|
|
155
|
+
- Added `SHA256SUMS.txt` checksums for the published release binaries
|
|
156
|
+
|
|
9
157
|
### Canonical SDK Cutover
|
|
10
158
|
|
|
11
159
|
- Switched `goodvibes-tui` from the temporary beta line to the canonical `@pellux/goodvibes-sdk@0.18.14` package and rewired imports to the canonical SDK entrypoints
|
|
@@ -17,6 +165,9 @@ All notable changes to GoodVibes TUI.
|
|
|
17
165
|
- Fixed the TUI eval gate to use the SDK-backed eval baseline, formatting, and scorecard exports after the platform extraction removed the old local files
|
|
18
166
|
- Fixed the TUI performance gate to build CI snapshots against the SDK-backed `surfacePerf` domain shape instead of the pre-extraction local `uiPerf` shape
|
|
19
167
|
- Fixed the architecture check so it tolerates removed migration targets on clean checkouts instead of crashing when extracted directories no longer exist
|
|
168
|
+
- Fixed the package publish path so release packaging stages vendored binaries deterministically instead of depending on install-time binary download behavior
|
|
169
|
+
- Fixed the release workflow to publish both npmjs and GitHub Packages distributions from the same bundled-binary package shape
|
|
170
|
+
- Fixed the staged publish rehearsal so it packs the final publishable package locally without tripping registry version conflicts or `/tmp` quota issues
|
|
20
171
|
|
|
21
172
|
### Verification
|
|
22
173
|
|
|
@@ -27,7 +178,10 @@ All notable changes to GoodVibes TUI.
|
|
|
27
178
|
- Full test runner passes: `bun run test`
|
|
28
179
|
- Build passes: `bun run build`
|
|
29
180
|
- Foundation artifact export passes: `bun run foundation:artifacts`
|
|
181
|
+
- Vendored binary staging passes: `bun run vendor:stage --clean`
|
|
30
182
|
- Publish packaging check passes: `bun run publish:check`
|
|
183
|
+
- Staged npm package rehearsal passes: `bun run publish:dry-run`
|
|
184
|
+
- Staged GitHub Packages rehearsal passes: `bun run publish:dry-run:github`
|
|
31
185
|
- Diff hygiene passes: `git diff --check`
|
|
32
186
|
|
|
33
187
|
## [0.18.3] — 2026-04-14
|
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
|
|
|
@@ -39,7 +39,7 @@ Common entrypoints:
|
|
|
39
39
|
Release distribution:
|
|
40
40
|
|
|
41
41
|
- GitHub Releases are the primary distribution path for compiled binaries
|
|
42
|
-
- `npm install -g @pellux/goodvibes-tui` is supported on Linux, macOS, and WSL
|
|
42
|
+
- `npm install -g @pellux/goodvibes-tui` is supported on Linux, macOS, and WSL; the install script downloads the matching TUI and daemon binaries for the current platform
|
|
43
43
|
- native Windows is not supported; use WSL on Windows
|
|
44
44
|
|
|
45
45
|
Common paths:
|
package/bin/goodvibes
CHANGED
|
@@ -62,5 +62,5 @@ console.error(`platform: ${process.platform}-${process.arch}`);
|
|
|
62
62
|
console.error(`supported prebuilt targets: ${supported}`);
|
|
63
63
|
console.error('Either:');
|
|
64
64
|
console.error(' 1. install Bun and re-run the command, or');
|
|
65
|
-
console.error(' 2.
|
|
65
|
+
console.error(' 2. rerun the package postinstall step so the matching release binary is downloaded.');
|
|
66
66
|
process.exit(1);
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { accessSync, constants } from 'node:fs';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { spawnSync } from 'node:child_process';
|
|
6
|
+
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const packageRoot = join(__dirname, '..');
|
|
9
|
+
|
|
10
|
+
if (process.platform === 'win32') {
|
|
11
|
+
console.error('goodvibes-daemon: native Windows is not supported.');
|
|
12
|
+
console.error('Use WSL so the Linux release binary path applies.');
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function resolveArtifactName(platform, arch) {
|
|
17
|
+
if (platform === 'linux' && arch === 'x64') return 'goodvibes-daemon-linux-x64';
|
|
18
|
+
if (platform === 'linux' && arch === 'arm64') return 'goodvibes-daemon-linux-arm64';
|
|
19
|
+
if (platform === 'darwin' && arch === 'x64') return 'goodvibes-daemon-macos-x64';
|
|
20
|
+
if (platform === 'darwin' && arch === 'arm64') return 'goodvibes-daemon-macos-arm64';
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function isExecutable(path) {
|
|
25
|
+
try {
|
|
26
|
+
accessSync(path, constants.X_OK);
|
|
27
|
+
return true;
|
|
28
|
+
} catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function run(command, args) {
|
|
34
|
+
const child = spawnSync(command, args, { stdio: 'inherit' });
|
|
35
|
+
if (child.error) {
|
|
36
|
+
throw child.error;
|
|
37
|
+
}
|
|
38
|
+
process.exit(child.status ?? 1);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const artifactName = resolveArtifactName(process.platform, process.arch);
|
|
42
|
+
const vendoredBinary = artifactName ? join(packageRoot, 'vendor', artifactName) : null;
|
|
43
|
+
|
|
44
|
+
if (vendoredBinary && isExecutable(vendoredBinary)) {
|
|
45
|
+
run(vendoredBinary, process.argv.slice(2));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const bunProbe = spawnSync('bun', ['--version'], { stdio: 'ignore' });
|
|
49
|
+
if (bunProbe.status === 0) {
|
|
50
|
+
run('bun', [join(packageRoot, 'src', 'daemon', 'cli.ts'), ...process.argv.slice(2)]);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const supported = [
|
|
54
|
+
'linux-x64',
|
|
55
|
+
'linux-arm64',
|
|
56
|
+
'darwin-x64',
|
|
57
|
+
'darwin-arm64',
|
|
58
|
+
].join(', ');
|
|
59
|
+
|
|
60
|
+
console.error('goodvibes-daemon: no runnable binary is available.');
|
|
61
|
+
console.error(`platform: ${process.platform}-${process.arch}`);
|
|
62
|
+
console.error(`supported prebuilt targets: ${supported}`);
|
|
63
|
+
console.error('Either:');
|
|
64
|
+
console.error(' 1. install Bun and re-run the command, or');
|
|
65
|
+
console.error(' 2. rerun the package postinstall step so the matching daemon binary is downloaded.');
|
|
66
|
+
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-tui",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.8",
|
|
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",
|
|
7
7
|
"bin": {
|
|
8
|
-
"goodvibes": "
|
|
8
|
+
"goodvibes": "bin/goodvibes",
|
|
9
|
+
"goodvibes-daemon": "bin/goodvibes-daemon"
|
|
9
10
|
},
|
|
10
11
|
"files": [
|
|
11
12
|
"bin",
|
|
@@ -15,7 +16,7 @@
|
|
|
15
16
|
"src",
|
|
16
17
|
"!src/test",
|
|
17
18
|
"!src/**/*.test.ts",
|
|
18
|
-
"scripts/postinstall.
|
|
19
|
+
"scripts/postinstall.js",
|
|
19
20
|
"README.md",
|
|
20
21
|
"CHANGELOG.md",
|
|
21
22
|
"docs/foundation-artifacts"
|
|
@@ -30,15 +31,21 @@
|
|
|
30
31
|
"build:linux-arm64": "bun build src/main.ts --compile --target=bun-linux-arm64 --outfile dist/goodvibes-linux-arm64",
|
|
31
32
|
"build:macos-x64": "bun build src/main.ts --compile --target=bun-darwin-x64 --outfile dist/goodvibes-macos-x64",
|
|
32
33
|
"build:macos-arm64": "bun build src/main.ts --compile --target=bun-darwin-arm64 --outfile dist/goodvibes-macos-arm64",
|
|
34
|
+
"build:daemon:linux-x64": "bun build src/daemon/cli.ts --compile --target=bun-linux-x64 --outfile dist/goodvibes-daemon-linux-x64",
|
|
35
|
+
"build:daemon:linux-arm64": "bun build src/daemon/cli.ts --compile --target=bun-linux-arm64 --outfile dist/goodvibes-daemon-linux-arm64",
|
|
36
|
+
"build:daemon:macos-x64": "bun build src/daemon/cli.ts --compile --target=bun-darwin-x64 --outfile dist/goodvibes-daemon-macos-x64",
|
|
37
|
+
"build:daemon:macos-arm64": "bun build src/daemon/cli.ts --compile --target=bun-darwin-arm64 --outfile dist/goodvibes-daemon-macos-arm64",
|
|
33
38
|
"build:windows": "bun build src/main.ts --compile --target=bun-windows-x64 --outfile dist/goodvibes-windows.exe",
|
|
34
39
|
"build:all-shell": "bun run build:linux-x64 && bun run build:linux-arm64 && bun run build:macos-x64 && bun run build:macos-arm64 && bun run build:windows",
|
|
35
40
|
"test": "bun run scripts/run-tests.ts",
|
|
36
41
|
"version": "bun run scripts/prebuild.ts",
|
|
37
|
-
"postinstall": "node scripts/postinstall.
|
|
38
|
-
"postbuild": "node scripts/postinstall.
|
|
42
|
+
"postinstall": "node scripts/postinstall.js",
|
|
43
|
+
"postbuild": "node scripts/postinstall.js --no-download",
|
|
39
44
|
"release": "bun run scripts/release.ts",
|
|
40
45
|
"release:dry": "bun run scripts/release.ts --dry-run",
|
|
41
|
-
"publish:
|
|
46
|
+
"publish:package": "bun run scripts/publish-package.ts",
|
|
47
|
+
"publish:dry-run": "bun run scripts/publish-package.ts --dry-run",
|
|
48
|
+
"publish:dry-run:github": "GOODVIBES_PUBLIC_PACKAGE_NAME=@mgd34msu/goodvibes-tui GOODVIBES_PUBLISH_REGISTRY=https://npm.pkg.github.com bun run scripts/publish-package.ts --dry-run",
|
|
42
49
|
"publish:check": "bun run scripts/publish-check.ts",
|
|
43
50
|
"build:prod": "bun run scripts/build.ts",
|
|
44
51
|
"build:all": "bun run scripts/build.ts --all",
|
|
@@ -81,7 +88,7 @@
|
|
|
81
88
|
"@anthropic-ai/vertex-sdk": "^0.16.0",
|
|
82
89
|
"@ast-grep/napi": "^0.42.0",
|
|
83
90
|
"@aws/bedrock-token-generator": "^1.1.0",
|
|
84
|
-
"@pellux/goodvibes-sdk": "0.18.
|
|
91
|
+
"@pellux/goodvibes-sdk": "0.18.21",
|
|
85
92
|
"bash-language-server": "^5.6.0",
|
|
86
93
|
"fuse.js": "^7.1.0",
|
|
87
94
|
"graphql": "^16.13.2",
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { chmodSync, copyFileSync, cpSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
import { basename, dirname, join } from 'node:path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const projectRoot = join(__dirname, '..');
|
|
10
|
+
const home = homedir();
|
|
11
|
+
const pkg = JSON.parse(readFileSync(join(projectRoot, 'package.json'), 'utf8'));
|
|
12
|
+
const noDownload = process.argv.includes('--no-download') || process.env.GOODVIBES_SKIP_BINARY_DOWNLOAD === '1';
|
|
13
|
+
|
|
14
|
+
function isSourceCheckout() {
|
|
15
|
+
return existsSync(join(projectRoot, '.git')) || existsSync(join(projectRoot, 'bun.lock'));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function resolveArtifactNames(platform, arch) {
|
|
19
|
+
if (platform === 'linux' && arch === 'x64') {
|
|
20
|
+
return {
|
|
21
|
+
app: 'goodvibes-linux-x64',
|
|
22
|
+
daemon: 'goodvibes-daemon-linux-x64',
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
if (platform === 'linux' && arch === 'arm64') {
|
|
26
|
+
return {
|
|
27
|
+
app: 'goodvibes-linux-arm64',
|
|
28
|
+
daemon: 'goodvibes-daemon-linux-arm64',
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
if (platform === 'darwin' && arch === 'x64') {
|
|
32
|
+
return {
|
|
33
|
+
app: 'goodvibes-macos-x64',
|
|
34
|
+
daemon: 'goodvibes-daemon-macos-x64',
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (platform === 'darwin' && arch === 'arm64') {
|
|
38
|
+
return {
|
|
39
|
+
app: 'goodvibes-macos-arm64',
|
|
40
|
+
daemon: 'goodvibes-daemon-macos-arm64',
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function prepareBinary(path) {
|
|
47
|
+
if (process.platform !== 'win32') {
|
|
48
|
+
chmodSync(path, 0o755);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function sha256(buffer) {
|
|
53
|
+
return createHash('sha256').update(buffer).digest('hex');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function parseChecksumFile(contents) {
|
|
57
|
+
const checksums = new Map();
|
|
58
|
+
for (const rawLine of contents.split(/\r?\n/)) {
|
|
59
|
+
const line = rawLine.trim();
|
|
60
|
+
if (!line) continue;
|
|
61
|
+
const match = line.match(/^([a-f0-9]{64})\s+\*?(.+)$/i);
|
|
62
|
+
if (!match) continue;
|
|
63
|
+
checksums.set(match[2], match[1].toLowerCase());
|
|
64
|
+
}
|
|
65
|
+
return checksums;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function resolveRepositoryBaseUrl() {
|
|
69
|
+
const repositoryUrl = typeof pkg.repository?.url === 'string' ? pkg.repository.url : '';
|
|
70
|
+
const normalized = repositoryUrl
|
|
71
|
+
.replace(/^git\+/, '')
|
|
72
|
+
.replace(/\.git$/, '')
|
|
73
|
+
.replace(/^git@github\.com:/, 'https://github.com/');
|
|
74
|
+
if (!normalized.startsWith('https://github.com/')) {
|
|
75
|
+
throw new Error(`unsupported repository URL for binary downloads: ${repositoryUrl || '(missing)'}`);
|
|
76
|
+
}
|
|
77
|
+
return normalized;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function downloadFile(url, destination) {
|
|
81
|
+
const response = await fetch(url);
|
|
82
|
+
if (!response.ok) {
|
|
83
|
+
throw new Error(`download failed (${response.status}) for ${url}`);
|
|
84
|
+
}
|
|
85
|
+
writeFileSync(destination, Buffer.from(await response.arrayBuffer()));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function downloadText(url) {
|
|
89
|
+
const response = await fetch(url);
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
throw new Error(`download failed (${response.status}) for ${url}`);
|
|
92
|
+
}
|
|
93
|
+
return await response.text();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function installPlatformBinaries() {
|
|
97
|
+
const artifacts = resolveArtifactNames(process.platform, process.arch);
|
|
98
|
+
if (!artifacts) {
|
|
99
|
+
console.log(`postinstall: no prebuilt binaries for ${process.platform}-${process.arch}; skipping binary install`);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (noDownload) {
|
|
104
|
+
console.log('postinstall: skipping binary install (--no-download)');
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (isSourceCheckout()) {
|
|
109
|
+
console.log('postinstall: source checkout detected; skipping release-binary install');
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const vendorDir = join(projectRoot, 'vendor');
|
|
114
|
+
mkdirSync(vendorDir, { recursive: true });
|
|
115
|
+
|
|
116
|
+
const localSourceDir = process.env.GOODVIBES_ASSET_SOURCE_DIR?.trim();
|
|
117
|
+
if (localSourceDir) {
|
|
118
|
+
for (const artifactName of [artifacts.app, artifacts.daemon]) {
|
|
119
|
+
const sourcePath = join(localSourceDir, artifactName);
|
|
120
|
+
if (!existsSync(sourcePath)) {
|
|
121
|
+
throw new Error(`missing local release artifact for postinstall smoke: ${sourcePath}`);
|
|
122
|
+
}
|
|
123
|
+
const destination = join(vendorDir, artifactName);
|
|
124
|
+
copyFileSync(sourcePath, destination);
|
|
125
|
+
prepareBinary(destination);
|
|
126
|
+
}
|
|
127
|
+
console.log(`postinstall: installed local smoke-test binaries for ${process.platform}-${process.arch}`);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const releaseBaseUrl =
|
|
132
|
+
process.env.GOODVIBES_RELEASE_BASE_URL?.trim() ||
|
|
133
|
+
`${resolveRepositoryBaseUrl()}/releases/download/v${pkg.version}`;
|
|
134
|
+
|
|
135
|
+
const checksumUrl = `${releaseBaseUrl}/SHA256SUMS.txt`;
|
|
136
|
+
const checksumText = await downloadText(checksumUrl);
|
|
137
|
+
writeFileSync(join(vendorDir, 'SHA256SUMS.txt'), checksumText);
|
|
138
|
+
const checksums = parseChecksumFile(checksumText);
|
|
139
|
+
|
|
140
|
+
for (const artifactName of [artifacts.app, artifacts.daemon]) {
|
|
141
|
+
const destination = join(vendorDir, artifactName);
|
|
142
|
+
const tempDestination = `${destination}.download`;
|
|
143
|
+
rmSync(tempDestination, { force: true });
|
|
144
|
+
await downloadFile(`${releaseBaseUrl}/${artifactName}`, tempDestination);
|
|
145
|
+
const actual = sha256(readFileSync(tempDestination));
|
|
146
|
+
const expected = checksums.get(artifactName);
|
|
147
|
+
if (expected && expected !== actual) {
|
|
148
|
+
rmSync(tempDestination, { force: true });
|
|
149
|
+
throw new Error(`checksum mismatch for ${artifactName}: expected ${expected}, got ${actual}`);
|
|
150
|
+
}
|
|
151
|
+
rmSync(destination, { force: true });
|
|
152
|
+
copyFileSync(tempDestination, destination);
|
|
153
|
+
rmSync(tempDestination, { force: true });
|
|
154
|
+
prepareBinary(destination);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
console.log(`postinstall: installed release binaries for ${process.platform}-${process.arch}`);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function deployBundledFiles() {
|
|
161
|
+
const targets = [
|
|
162
|
+
{ src: join(projectRoot, '.goodvibes', 'skills'), dest: join(home, '.goodvibes', 'tui', 'skills') },
|
|
163
|
+
{ src: join(projectRoot, '.goodvibes', 'agents'), dest: join(home, '.goodvibes', 'tui', 'agents') },
|
|
164
|
+
];
|
|
165
|
+
|
|
166
|
+
let installed = 0;
|
|
167
|
+
let skipped = 0;
|
|
168
|
+
|
|
169
|
+
for (const { src, dest } of targets) {
|
|
170
|
+
if (!existsSync(src)) continue;
|
|
171
|
+
|
|
172
|
+
const entries = readdirSync(src, { withFileTypes: true });
|
|
173
|
+
|
|
174
|
+
for (const entry of entries) {
|
|
175
|
+
const srcPath = join(src, entry.name);
|
|
176
|
+
const destPath = join(dest, entry.name);
|
|
177
|
+
|
|
178
|
+
if (existsSync(destPath)) {
|
|
179
|
+
skipped++;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
mkdirSync(dest, { recursive: true });
|
|
184
|
+
|
|
185
|
+
if (entry.isDirectory()) {
|
|
186
|
+
cpSync(srcPath, destPath, { recursive: true });
|
|
187
|
+
console.log(` installed: ${entry.name}/`);
|
|
188
|
+
installed++;
|
|
189
|
+
} else if (entry.name.endsWith('.md')) {
|
|
190
|
+
cpSync(srcPath, destPath);
|
|
191
|
+
console.log(` installed: ${entry.name}`);
|
|
192
|
+
installed++;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const goodvibesSrc = join(projectRoot, '.goodvibes', 'GOODVIBES.md');
|
|
198
|
+
const goodvibesDest = join(home, '.goodvibes', 'GOODVIBES.md');
|
|
199
|
+
if (existsSync(goodvibesSrc) && !existsSync(goodvibesDest)) {
|
|
200
|
+
mkdirSync(join(home, '.goodvibes'), { recursive: true });
|
|
201
|
+
copyFileSync(goodvibesSrc, goodvibesDest);
|
|
202
|
+
console.log(` installed: ${basename(goodvibesDest)}`);
|
|
203
|
+
installed++;
|
|
204
|
+
} else if (existsSync(goodvibesDest)) {
|
|
205
|
+
skipped++;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (installed > 0 || skipped > 0) {
|
|
209
|
+
console.log(`postinstall: ${installed} installed, ${skipped} already exist (skipped)`);
|
|
210
|
+
} else {
|
|
211
|
+
console.log('postinstall: nothing to deploy');
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async function main() {
|
|
216
|
+
await installPlatformBinaries();
|
|
217
|
+
deployBundledFiles();
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
await main();
|
|
@@ -63,7 +63,7 @@ type AgentOrchestratorToolDeps = {
|
|
|
63
63
|
readonly serviceRegistry?: import('../config/service-registry.ts').ServiceRegistry;
|
|
64
64
|
readonly featureFlags?: Pick<FeatureFlagManager, 'isEnabled'> | null;
|
|
65
65
|
readonly overflowHandler?: import('@pellux/goodvibes-sdk/platform/tools/shared/overflow').OverflowHandler;
|
|
66
|
-
readonly sandboxSessionRegistry: import('
|
|
66
|
+
readonly sandboxSessionRegistry: import('@pellux/goodvibes-sdk/platform/runtime/sandbox/session-registry').SandboxSessionRegistry;
|
|
67
67
|
readonly workflowServices: ReturnType<typeof import('@pellux/goodvibes-sdk/platform/tools/workflow/index').createWorkflowServices>;
|
|
68
68
|
};
|
|
69
69
|
|
|
@@ -38,7 +38,13 @@ export function registerDiscoveryRuntimeCommands(registry: CommandRegistry): voi
|
|
|
38
38
|
ctx.print(`[Scan] Warning: failed to register some providers: ${summarizeError(err)}`);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
if (result.servers.length > 0)
|
|
41
|
+
if (result.servers.length > 0) {
|
|
42
|
+
const shellPaths = requireShellPaths(ctx);
|
|
43
|
+
persistProviders({
|
|
44
|
+
homeDirectory: shellPaths.homeDirectory,
|
|
45
|
+
surfaceRoot: 'tui',
|
|
46
|
+
}, result.servers);
|
|
47
|
+
}
|
|
42
48
|
ctx.renderRequest();
|
|
43
49
|
},
|
|
44
50
|
});
|
|
@@ -2,7 +2,7 @@ import { dirname, join, resolve } from 'node:path';
|
|
|
2
2
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import type { CommandContext } from '../command-registry.ts';
|
|
4
4
|
import { discoverSkills } from '../../panels/skills-panel.ts';
|
|
5
|
-
import { buildSandboxReview, isRunningInWsl } from '
|
|
5
|
+
import { buildSandboxReview, isRunningInWsl } from '@pellux/goodvibes-sdk/platform/runtime/sandbox/manager';
|
|
6
6
|
import { renderQemuWrapperTemplate } from '@pellux/goodvibes-sdk/platform/runtime/sandbox/qemu-wrapper-template';
|
|
7
7
|
import { getPluginDirectories } from '../../plugins/loader.ts';
|
|
8
8
|
import { listBuiltinSubscriptionProviders } from '../../config/subscription-providers.ts';
|
|
@@ -4,7 +4,7 @@ import type { CommandRegistry, CommandContext } from '../command-registry.ts';
|
|
|
4
4
|
import type { ConfigKey } from '../../config/index.ts';
|
|
5
5
|
import { CONFIG_SCHEMA } from '../../config/index.ts';
|
|
6
6
|
import { listHookPointContracts } from '../../hooks/index.ts';
|
|
7
|
-
import { isRunningInWsl } from '
|
|
7
|
+
import { isRunningInWsl } from '@pellux/goodvibes-sdk/platform/runtime/sandbox/manager';
|
|
8
8
|
import { renderQemuWrapperTemplate } from '@pellux/goodvibes-sdk/platform/runtime/sandbox/qemu-wrapper-template';
|
|
9
9
|
import type { SetupTransferBundle } from './local-setup-transfer.ts';
|
|
10
10
|
import {
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
inspectSandboxQemuSetupManifest,
|
|
9
9
|
loadSandboxQemuSetupManifest,
|
|
10
10
|
scaffoldSandboxQemuSetupBundle,
|
|
11
|
-
} from '
|
|
11
|
+
} from '@pellux/goodvibes-sdk/platform/runtime/sandbox/provisioning';
|
|
12
12
|
import { requireShellPaths } from './runtime-services.ts';
|
|
13
13
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils/error-display';
|
|
14
14
|
|
|
@@ -26,7 +26,7 @@ export async function handleSandboxQemuCommand(args: string[], ctx: CommandConte
|
|
|
26
26
|
ctx.print('Usage: /sandbox qemu setup <directory>');
|
|
27
27
|
return true;
|
|
28
28
|
}
|
|
29
|
-
const bundle = scaffoldSandboxQemuSetupBundle(ctx.platform.configManager, shellPaths.workingDirectory, dirArg);
|
|
29
|
+
const bundle = scaffoldSandboxQemuSetupBundle(ctx.platform.configManager, shellPaths.workingDirectory, dirArg, { surfaceRoot: 'tui' });
|
|
30
30
|
ctx.platform.configManager.setDynamic('sandbox.vmBackend', 'qemu');
|
|
31
31
|
ctx.platform.configManager.setDynamic('sandbox.qemuExecWrapper', bundle.wrapperPath);
|
|
32
32
|
ctx.platform.configManager.setDynamic('sandbox.qemuImagePath', bundle.imagePath);
|
|
@@ -61,7 +61,7 @@ export async function handleSandboxQemuCommand(args: string[], ctx: CommandConte
|
|
|
61
61
|
return true;
|
|
62
62
|
}
|
|
63
63
|
try {
|
|
64
|
-
const bundle = bootstrapSandboxQemuSetupBundle(ctx.platform.configManager, shellPaths.workingDirectory, dirArg, sizeGb);
|
|
64
|
+
const bundle = bootstrapSandboxQemuSetupBundle(ctx.platform.configManager, shellPaths.workingDirectory, dirArg, sizeGb, { surfaceRoot: 'tui' });
|
|
65
65
|
ctx.print([
|
|
66
66
|
`Bootstrapped QEMU sandbox in ${bundle.directory}`,
|
|
67
67
|
` wrapper: ${bundle.wrapperPath}`,
|