kryptheon 0.1.5 → 0.1.6
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 +5 -3
- package/bin/kryptheon.js +51 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -123,9 +123,11 @@ Worth adding to `.gitignore`: `.env`, `kryptheon-baselines.json`,
|
|
|
123
123
|
|
|
124
124
|
## Requirements
|
|
125
125
|
|
|
126
|
-
Node 20.6 or later.
|
|
127
|
-
|
|
128
|
-
|
|
126
|
+
Node 20.6 or later. The first run downloads a browser (about 200MB, once).
|
|
127
|
+
|
|
128
|
+
Recording opens a browser window, so it needs a machine with a screen. It will
|
|
129
|
+
always try — if no window appears within 30 seconds it stops and says so,
|
|
130
|
+
rather than refusing up front.
|
|
129
131
|
|
|
130
132
|
## Licence
|
|
131
133
|
|
package/bin/kryptheon.js
CHANGED
|
@@ -479,23 +479,51 @@ async function nameRecording(relativeFile) {
|
|
|
479
479
|
// Recording needs a real browser window on someone's screen. Inside an AI
|
|
480
480
|
// coding assistant there is no desktop to draw it on, so codegen would sit
|
|
481
481
|
// there forever and the run would be killed before anything was tidied up.
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
482
|
+
// There is deliberately no up-front refusal here.
|
|
483
|
+
//
|
|
484
|
+
// This used to check process.stdout.isTTY and refuse before launching. That
|
|
485
|
+
// was wrong: isTTY is falsy in plenty of perfectly good terminals depending on
|
|
486
|
+
// how the process was started, and a real user in Command Prompt was told to
|
|
487
|
+
// go and run the command in Command Prompt. Refusing on a guess is far worse
|
|
488
|
+
// than trying and waiting - so we always launch, and the watchdog below
|
|
489
|
+
// reports only when a window genuinely never appears.
|
|
490
|
+
|
|
491
|
+
// Only ever shown after actually trying: the browser was launched and no
|
|
492
|
+
// window arrived. It must never tell someone to go and run the command they
|
|
493
|
+
// have plainly just run.
|
|
494
|
+
function noWindowLines(seconds) {
|
|
495
|
+
return [
|
|
496
|
+
'',
|
|
497
|
+
' No browser window appeared.',
|
|
498
|
+
'',
|
|
499
|
+
' The browser was started, but nothing showed up on screen within ' + seconds,
|
|
500
|
+
' seconds, so there was nowhere to record.',
|
|
501
|
+
'',
|
|
502
|
+
' The usual reasons:',
|
|
503
|
+
' - there is no desktop to draw on - a remote or SSH session, a',
|
|
504
|
+
' container, or an AI coding assistant running the command for you',
|
|
505
|
+
' - security software stopped the browser from opening',
|
|
506
|
+
' - the machine is slow and the browser had not finished starting',
|
|
507
|
+
'',
|
|
508
|
+
' If you are sitting at the screen, run the same command again - a slow',
|
|
509
|
+
' first start is the most common cause, and the second attempt usually',
|
|
510
|
+
' works.',
|
|
511
|
+
'',
|
|
512
|
+
' If you are connected to a different machine, run it on the machine',
|
|
513
|
+
' that has the screen.',
|
|
514
|
+
'',
|
|
515
|
+
' If the window really is open and this keeps happening, set',
|
|
516
|
+
' KRYPTHEON_FORCE_RECORD=1 to skip this check.',
|
|
517
|
+
'',
|
|
518
|
+
' Nothing was recorded.',
|
|
519
|
+
'',
|
|
520
|
+
];
|
|
485
521
|
}
|
|
486
522
|
|
|
487
|
-
function explainNoWindow(
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
console.error(' This terminal cannot show one - that is what happens inside an');
|
|
492
|
-
console.error(' AI coding assistant, or any window-less session.');
|
|
493
|
-
console.error('');
|
|
494
|
-
console.error(' Open Command Prompt (or PowerShell) yourself and run:');
|
|
495
|
-
console.error(' npx kryptheon record ' + url);
|
|
496
|
-
console.error('');
|
|
497
|
-
console.error(' Nothing was recorded.');
|
|
498
|
-
console.error('');
|
|
523
|
+
function explainNoWindow() {
|
|
524
|
+
for (const line of noWindowLines(Math.round(WINDOW_TIMEOUT_MS / 1000))) {
|
|
525
|
+
console.error(line);
|
|
526
|
+
}
|
|
499
527
|
}
|
|
500
528
|
|
|
501
529
|
// Is a Playwright-controlled browser actually showing a window?
|
|
@@ -693,7 +721,7 @@ async function finaliseRecording(outFile, context) {
|
|
|
693
721
|
}
|
|
694
722
|
|
|
695
723
|
if (ctx.reason === 'no-window') {
|
|
696
|
-
explainNoWindow(
|
|
724
|
+
explainNoWindow();
|
|
697
725
|
} else if (ctx.reason === 'signal') {
|
|
698
726
|
console.log('');
|
|
699
727
|
console.log(' Recording stopped before anything was saved.');
|
|
@@ -726,13 +754,6 @@ async function record(url) {
|
|
|
726
754
|
|
|
727
755
|
const target = normaliseRecordUrl(url);
|
|
728
756
|
|
|
729
|
-
// No desktop means no window means nothing to record. Say so now rather
|
|
730
|
-
// than hanging until something kills us.
|
|
731
|
-
if (looksLikeNoDesktop()) {
|
|
732
|
-
explainNoWindow(target);
|
|
733
|
-
return 1;
|
|
734
|
-
}
|
|
735
|
-
|
|
736
757
|
// Fail early and kindly rather than letting codegen throw a stack trace.
|
|
737
758
|
const reach = await reachability(target);
|
|
738
759
|
if (!reach.ok) {
|
|
@@ -793,8 +814,14 @@ async function record(url) {
|
|
|
793
814
|
|
|
794
815
|
return await new Promise((resolve) => {
|
|
795
816
|
// If no window ever appears, stop instead of waiting for someone to kill us.
|
|
817
|
+
// Someone whose window is real but undetectable can turn this off.
|
|
818
|
+
const watchdogOff = !!process.env.KRYPTHEON_FORCE_RECORD;
|
|
796
819
|
let waited = 0;
|
|
797
820
|
const watchdog = setInterval(() => {
|
|
821
|
+
if (watchdogOff) {
|
|
822
|
+
clearInterval(watchdog);
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
798
825
|
waited += WINDOW_POLL_MS;
|
|
799
826
|
if (browserWindowIsUp()) {
|
|
800
827
|
clearInterval(watchdog);
|
|
@@ -1299,7 +1326,7 @@ module.exports = {
|
|
|
1299
1326
|
takeOutSecrets: takeOutSecrets,
|
|
1300
1327
|
reportReplayRisks: reportReplayRisks,
|
|
1301
1328
|
offerToDropLogout: offerToDropLogout,
|
|
1302
|
-
|
|
1329
|
+
noWindowLines: noWindowLines,
|
|
1303
1330
|
classifyFetchError: classifyFetchError,
|
|
1304
1331
|
normaliseRecordUrl: normaliseRecordUrl,
|
|
1305
1332
|
isLocalAddress: isLocalAddress,
|