@steipete/oracle 0.5.2 → 0.5.3
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/README.md +1 -1
- package/dist/bin/oracle-cli.js +11 -9
- package/dist/src/cli/tui/index.js +40 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -38,7 +38,7 @@ npx @steipete/oracle status --hours 72
|
|
|
38
38
|
npx @steipete/oracle session <id> --render
|
|
39
39
|
|
|
40
40
|
# TUI (interactive, only for humans)
|
|
41
|
-
npx @steipete/oracle
|
|
41
|
+
npx @steipete/oracle tui
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
Engine auto-picks API when `OPENAI_API_KEY` is set, otherwise browser; browser is stable on macOS and works on Linux and Windows. On Linux pass `--browser-chrome-path/--browser-cookie-path` if detection fails; on Windows prefer `--browser-manual-login` or inline cookies if decryption is blocked.
|
package/dist/bin/oracle-cli.js
CHANGED
|
@@ -49,7 +49,6 @@ const CLI_ENTRYPOINT = fileURLToPath(import.meta.url);
|
|
|
49
49
|
const rawCliArgs = process.argv.slice(2);
|
|
50
50
|
const userCliArgs = rawCliArgs[0] === CLI_ENTRYPOINT ? rawCliArgs.slice(1) : rawCliArgs;
|
|
51
51
|
const isTty = process.stdout.isTTY;
|
|
52
|
-
const tuiEnabled = () => isTty && process.env.ORACLE_NO_TUI !== '1';
|
|
53
52
|
const program = new Command();
|
|
54
53
|
let introPrinted = false;
|
|
55
54
|
program.hook('preAction', () => {
|
|
@@ -66,8 +65,8 @@ program.hook('preAction', (thisCommand) => {
|
|
|
66
65
|
if (userCliArgs.some((arg) => arg === '--help' || arg === '-h')) {
|
|
67
66
|
return;
|
|
68
67
|
}
|
|
69
|
-
if (userCliArgs.length === 0
|
|
70
|
-
//
|
|
68
|
+
if (userCliArgs.length === 0) {
|
|
69
|
+
// Let the root action handle zero-arg entry (help + hint to `oracle tui`).
|
|
71
70
|
return;
|
|
72
71
|
}
|
|
73
72
|
const opts = thisCommand.optsWithGlobals();
|
|
@@ -212,6 +211,13 @@ program
|
|
|
212
211
|
token: commandOptions.token,
|
|
213
212
|
});
|
|
214
213
|
});
|
|
214
|
+
program
|
|
215
|
+
.command('tui')
|
|
216
|
+
.description('Launch the interactive terminal UI for humans (no automation).')
|
|
217
|
+
.action(async () => {
|
|
218
|
+
await sessionStore.ensureStorage();
|
|
219
|
+
await launchTui({ version: VERSION, printIntro: false });
|
|
220
|
+
});
|
|
215
221
|
const sessionCommand = program
|
|
216
222
|
.command('session [id]')
|
|
217
223
|
.description('Attach to a stored session or list recent sessions when no ID is provided.')
|
|
@@ -422,12 +428,8 @@ async function runRootCommand(options) {
|
|
|
422
428
|
console.log(chalk.dim(`Remote browser host detected: ${remoteHost}`));
|
|
423
429
|
}
|
|
424
430
|
if (userCliArgs.length === 0) {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
return;
|
|
428
|
-
}
|
|
429
|
-
console.log(chalk.yellow('No prompt or subcommand supplied. See `oracle --help` for usage.'));
|
|
430
|
-
program.help({ error: false });
|
|
431
|
+
console.log(chalk.yellow('No prompt or subcommand supplied. Run `oracle --help` or `oracle tui` for the TUI.'));
|
|
432
|
+
program.outputHelp();
|
|
431
433
|
return;
|
|
432
434
|
}
|
|
433
435
|
const retentionHours = typeof options.retainHours === 'number' ? options.retainHours : undefined;
|
|
@@ -21,6 +21,8 @@ const PAGE_SIZE = 10;
|
|
|
21
21
|
export async function launchTui({ version, printIntro = true }) {
|
|
22
22
|
const userConfig = (await loadUserConfig()).config;
|
|
23
23
|
const rich = isTty();
|
|
24
|
+
let pagingFailures = 0;
|
|
25
|
+
let exitMessageShown = false;
|
|
24
26
|
if (printIntro) {
|
|
25
27
|
if (rich) {
|
|
26
28
|
console.log(chalk.bold('🧿 oracle'), `${version}`, dim('— Whispering your tokens to the silicon sage'));
|
|
@@ -76,15 +78,31 @@ export async function launchTui({ version, printIntro = true }) {
|
|
|
76
78
|
prompt
|
|
77
79
|
.then(({ selection: answer }) => resolve(answer))
|
|
78
80
|
.catch((error) => {
|
|
79
|
-
|
|
81
|
+
pagingFailures += 1;
|
|
82
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
83
|
+
if (message.includes('SIGINT') || message.includes('force closed the prompt')) {
|
|
84
|
+
console.log(chalk.green('🧿 Closing the book. See you next prompt.'));
|
|
85
|
+
exitMessageShown = true;
|
|
86
|
+
resolve('__exit__');
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
console.error(chalk.red('Paging failed; returning to recent list.'), message);
|
|
90
|
+
if (message.includes('setRawMode') || message.includes('EIO') || pagingFailures >= 3) {
|
|
91
|
+
console.error(chalk.red('Terminal input unavailable; exiting TUI.'), dim('Try `stty sane` then rerun oracle, or use `oracle recent`.'));
|
|
92
|
+
resolve('__exit__');
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
80
95
|
resolve('__reset__');
|
|
81
96
|
});
|
|
82
97
|
});
|
|
83
98
|
if (process.env.ORACLE_DEBUG_TUI === '1') {
|
|
84
99
|
console.error(`[tui] selection=${JSON.stringify(selection)}`);
|
|
85
100
|
}
|
|
101
|
+
pagingFailures = 0;
|
|
86
102
|
if (selection === '__exit__') {
|
|
87
|
-
|
|
103
|
+
if (!exitMessageShown) {
|
|
104
|
+
console.log(chalk.green('🧿 Closing the book. See you next prompt.'));
|
|
105
|
+
}
|
|
88
106
|
return;
|
|
89
107
|
}
|
|
90
108
|
if (selection === '__ask__') {
|
|
@@ -156,14 +174,26 @@ async function showSessionDetail(sessionId) {
|
|
|
156
174
|
...(isRunning ? [{ name: 'Refresh', value: 'refresh' }] : []),
|
|
157
175
|
{ name: 'Back', value: 'back' },
|
|
158
176
|
];
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
177
|
+
let next;
|
|
178
|
+
try {
|
|
179
|
+
({ next } = await inquirer.prompt([
|
|
180
|
+
{
|
|
181
|
+
name: 'next',
|
|
182
|
+
type: 'select',
|
|
183
|
+
message: 'Actions',
|
|
184
|
+
choices: actions,
|
|
185
|
+
},
|
|
186
|
+
]));
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
190
|
+
if (message.includes('SIGINT') || message.includes('force closed the prompt')) {
|
|
191
|
+
console.log(chalk.green('🧿 Closing the book. See you next prompt.'));
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
console.error(chalk.red('Paging failed; returning to session list.'), message);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
167
197
|
if (next === 'back') {
|
|
168
198
|
return;
|
|
169
199
|
}
|
package/package.json
CHANGED