@pellux/goodvibes-agent 0.1.57 → 0.1.58
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 +4 -0
- package/package.json +1 -1
- package/src/cli/tui-startup.ts +23 -0
- package/src/main.ts +13 -12
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.58",
|
|
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",
|
package/src/cli/tui-startup.ts
CHANGED
|
@@ -3,6 +3,29 @@ import type { InputHandler } from '../input/handler.ts';
|
|
|
3
3
|
import { readOnboardingCheckMarker } from '../runtime/onboarding/index.ts';
|
|
4
4
|
import type { GoodVibesCliParseResult } from './types.ts';
|
|
5
5
|
|
|
6
|
+
export type InteractiveTerminalCheckInput = {
|
|
7
|
+
readonly binary: string;
|
|
8
|
+
readonly stdinIsTTY: boolean | undefined;
|
|
9
|
+
readonly stdoutIsTTY: boolean | undefined;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function getInteractiveTerminalLaunchError(input: InteractiveTerminalCheckInput): string | null {
|
|
13
|
+
const stdinReady = input.stdinIsTTY === true;
|
|
14
|
+
const stdoutReady = input.stdoutIsTTY === true;
|
|
15
|
+
if (stdinReady && stdoutReady) return null;
|
|
16
|
+
|
|
17
|
+
const missing = [
|
|
18
|
+
stdinReady ? null : 'stdin',
|
|
19
|
+
stdoutReady ? null : 'stdout',
|
|
20
|
+
].filter((entry): entry is string => entry !== null);
|
|
21
|
+
const missingLabel = missing.length === 1 ? `${missing[0]} is` : `${missing.join(' and ')} are`;
|
|
22
|
+
|
|
23
|
+
return [
|
|
24
|
+
`${input.binary} requires an interactive terminal for the TUI (${missingLabel} not a TTY).`,
|
|
25
|
+
`Run it from a terminal, or use non-interactive commands such as '${input.binary} --help', '${input.binary} status --json', or '${input.binary} run --print "<prompt>"'.`,
|
|
26
|
+
].join('\n');
|
|
27
|
+
}
|
|
28
|
+
|
|
6
29
|
export function applyInitialTuiCliState(options: {
|
|
7
30
|
readonly cli: GoodVibesCliParseResult;
|
|
8
31
|
readonly input: InputHandler;
|
package/src/main.ts
CHANGED
|
@@ -45,7 +45,7 @@ import { deriveComposerState } from './core/composer-state.ts';
|
|
|
45
45
|
import { buildPersistedSessionContext, formatReturnContextForDisplay, 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, getInteractiveTerminalLaunchError } from './cli/tui-startup.ts';
|
|
49
49
|
import { wireSpokenTurnRuntime } from './audio/spoken-turn-wiring.ts';
|
|
50
50
|
import { attachSpokenTurnModelRouting, createSpokenTurnInputOptions } from './audio/spoken-turn-model-routing.ts';
|
|
51
51
|
import { allowTerminalWrite, installTuiTerminalOutputGuard } from './runtime/terminal-output-guard.ts';
|
|
@@ -53,17 +53,8 @@ import { ProjectPlanningCoordinator } from './planning/project-planning-coordina
|
|
|
53
53
|
import { buildCommandArgsHint } from './input/command-args-hint.ts';
|
|
54
54
|
import { GOODVIBES_AGENT_PAIRING_SURFACE } from './config/surface.ts';
|
|
55
55
|
|
|
56
|
-
const ALT_SCREEN_ENTER = '\x1b[?1049h';
|
|
57
|
-
const
|
|
58
|
-
const MOUSE_ENABLE = '\x1b[?1000h\x1b[?1002h\x1b[?1006h';
|
|
59
|
-
const MOUSE_DISABLE = '\x1b[?1006l\x1b[?1002l\x1b[?1000l';
|
|
60
|
-
const CURSOR_HIDE = '\x1b[?25l';
|
|
61
|
-
const CURSOR_SHOW = '\x1b[?25h';
|
|
62
|
-
const CLEAR_SCREEN = '\x1b[2J\x1b[3J\x1b[H';
|
|
63
|
-
const KEYBOARD_EXT_ENABLE = '\x1b[>4;2m' + '\x1b[?1u';
|
|
64
|
-
const KEYBOARD_EXT_DISABLE = '\x1b[>4;0m' + '\x1b[?1l';
|
|
65
|
-
const PASTE_ENABLE = '\x1b[?2004h';
|
|
66
|
-
const PASTE_DISABLE = '\x1b[?2004l';
|
|
56
|
+
const ALT_SCREEN_ENTER = '\x1b[?1049h', ALT_SCREEN_EXIT = '\x1b[?1049l', MOUSE_ENABLE = '\x1b[?1000h\x1b[?1002h\x1b[?1006h', MOUSE_DISABLE = '\x1b[?1006l\x1b[?1002l\x1b[?1000l', CURSOR_HIDE = '\x1b[?25l', CURSOR_SHOW = '\x1b[?25h', CLEAR_SCREEN = '\x1b[2J\x1b[3J\x1b[H';
|
|
57
|
+
const KEYBOARD_EXT_ENABLE = '\x1b[>4;2m' + '\x1b[?1u', KEYBOARD_EXT_DISABLE = '\x1b[>4;0m' + '\x1b[?1l', PASTE_ENABLE = '\x1b[?2004h', PASTE_DISABLE = '\x1b[?2004l';
|
|
67
58
|
|
|
68
59
|
async function main() {
|
|
69
60
|
const stdout = process.stdout;
|
|
@@ -73,6 +64,16 @@ async function main() {
|
|
|
73
64
|
homeDirectory: process.env['GOODVIBES_AGENT_HOME'] ?? homedir(),
|
|
74
65
|
}, 'goodvibes-agent');
|
|
75
66
|
|
|
67
|
+
const terminalLaunchError = getInteractiveTerminalLaunchError({
|
|
68
|
+
binary: cli.binary,
|
|
69
|
+
stdinIsTTY: stdin.isTTY,
|
|
70
|
+
stdoutIsTTY: stdout.isTTY,
|
|
71
|
+
});
|
|
72
|
+
if (terminalLaunchError !== null) {
|
|
73
|
+
process.stderr.write(`${terminalLaunchError}\n`);
|
|
74
|
+
process.exit(2);
|
|
75
|
+
}
|
|
76
|
+
|
|
76
77
|
const ctx: BootstrapContext = await bootstrapRuntime(stdout, {
|
|
77
78
|
configManager,
|
|
78
79
|
workingDir: bootstrapWorkingDir,
|
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.58';
|
|
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 {
|