@ekkos/cli 0.2.10 → 0.2.11
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/dist/agent/daemon.d.ts +86 -0
- package/dist/agent/daemon.js +297 -0
- package/dist/agent/pty-runner.d.ts +51 -0
- package/dist/agent/pty-runner.js +184 -0
- package/dist/commands/agent.d.ts +44 -0
- package/dist/commands/agent.js +300 -0
- package/dist/commands/doctor.js +27 -14
- package/dist/commands/run.d.ts +1 -0
- package/dist/commands/run.js +289 -65
- package/dist/commands/setup-remote.d.ts +20 -0
- package/dist/commands/setup-remote.js +467 -0
- package/dist/index.js +75 -1
- package/dist/utils/state.d.ts +2 -0
- package/package.json +1 -1
- package/templates/ekkos-manifest.json +1 -1
package/dist/commands/run.js
CHANGED
|
@@ -445,6 +445,72 @@ async function run(options) {
|
|
|
445
445
|
const config = getConfig(options);
|
|
446
446
|
setDebugLogPath(config.debugLogPath);
|
|
447
447
|
// ══════════════════════════════════════════════════════════════════════════
|
|
448
|
+
// EARLY SETUP: Resolve paths and prepare spawn BEFORE animation
|
|
449
|
+
// This lets us start Claude while animations run (perceived performance)
|
|
450
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
451
|
+
(0, state_1.ensureEkkosDir)();
|
|
452
|
+
(0, state_1.clearAutoClearFlag)();
|
|
453
|
+
const rawClaudePath = resolveClaudePath();
|
|
454
|
+
const isNpxMode = rawClaudePath.startsWith('npx:');
|
|
455
|
+
const pinnedVersion = isNpxMode ? rawClaudePath.split(':')[1] : null;
|
|
456
|
+
const claudePath = isNpxMode ? 'npx' : rawClaudePath;
|
|
457
|
+
// Build args early
|
|
458
|
+
const earlyArgs = [];
|
|
459
|
+
if (isNpxMode) {
|
|
460
|
+
earlyArgs.push(`@anthropic-ai/claude-code@${pinnedVersion}`);
|
|
461
|
+
}
|
|
462
|
+
if (bypass) {
|
|
463
|
+
earlyArgs.push('--dangerously-skip-permissions');
|
|
464
|
+
}
|
|
465
|
+
// Check PTY availability early
|
|
466
|
+
const usePty = pty !== null;
|
|
467
|
+
const monitorOnlyMode = noInject || (isWindows && !usePty);
|
|
468
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
469
|
+
// CONCURRENT STARTUP: Spawn Claude while animation runs
|
|
470
|
+
// Buffer output until animation completes, then flush
|
|
471
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
472
|
+
let earlySpawnedShell = null;
|
|
473
|
+
let bufferedOutput = [];
|
|
474
|
+
let animationComplete = false;
|
|
475
|
+
let shellReady = false;
|
|
476
|
+
let shellError = null;
|
|
477
|
+
// Handler reference for early spawn (allows replacing buffer handler with real handler)
|
|
478
|
+
let earlyDataHandler = null;
|
|
479
|
+
// Start spawning Claude NOW (before animation) if PTY available
|
|
480
|
+
if (usePty && pty && !isWindows) {
|
|
481
|
+
try {
|
|
482
|
+
earlySpawnedShell = pty.spawn(claudePath, earlyArgs, {
|
|
483
|
+
name: 'xterm-256color',
|
|
484
|
+
cols: process.stdout.columns || 80,
|
|
485
|
+
rows: process.stdout.rows || 24,
|
|
486
|
+
cwd: process.cwd(),
|
|
487
|
+
env: process.env
|
|
488
|
+
});
|
|
489
|
+
// Buffer output until animation completes using delegating handler
|
|
490
|
+
earlyDataHandler = (data) => {
|
|
491
|
+
bufferedOutput.push(data);
|
|
492
|
+
};
|
|
493
|
+
earlySpawnedShell.onData((data) => {
|
|
494
|
+
// Delegate to current handler (buffer during animation, real handler after)
|
|
495
|
+
if (earlyDataHandler) {
|
|
496
|
+
earlyDataHandler(data);
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
earlySpawnedShell.onExit(() => {
|
|
500
|
+
if (!animationComplete) {
|
|
501
|
+
// Claude exited during animation - will handle after
|
|
502
|
+
shellError = new Error('Claude exited during startup');
|
|
503
|
+
}
|
|
504
|
+
});
|
|
505
|
+
shellReady = true;
|
|
506
|
+
dlog('Claude spawned early (buffering output during animation)');
|
|
507
|
+
}
|
|
508
|
+
catch (err) {
|
|
509
|
+
dlog(`Early spawn failed: ${err.message}, will retry after animation`);
|
|
510
|
+
shellError = err;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
448
514
|
// STARTUP BANNER WITH COLOR PULSE ANIMATION
|
|
449
515
|
// ══════════════════════════════════════════════════════════════════════════
|
|
450
516
|
const logoLines = [
|
|
@@ -532,9 +598,87 @@ async function run(options) {
|
|
|
532
598
|
process.stdout.write('\x1B[6A');
|
|
533
599
|
logoLines.forEach(line => console.log(chalk_1.default.magenta(line)));
|
|
534
600
|
console.log('');
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
601
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
602
|
+
// ANIMATED TITLE: "Cognitive Continuity Engine" with orange/white shine
|
|
603
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
604
|
+
const titleText = 'Cognitive Continuity Engine';
|
|
605
|
+
const taglineText = 'Context is finite. Intelligence isn\'t.';
|
|
606
|
+
// Color palette for shine effect
|
|
607
|
+
const whiteShine = chalk_1.default.whiteBright;
|
|
608
|
+
// Phase 1: Typewriter effect for title
|
|
609
|
+
process.stdout.write(' ');
|
|
610
|
+
for (let i = 0; i < titleText.length; i++) {
|
|
611
|
+
const char = titleText[i];
|
|
612
|
+
// Flash white then settle to orange
|
|
613
|
+
process.stdout.write(whiteShine(char));
|
|
614
|
+
await sleep(25);
|
|
615
|
+
process.stdout.write('\b' + chalk_1.default.hex('#FF6B35').bold(char));
|
|
616
|
+
}
|
|
617
|
+
console.log('');
|
|
618
|
+
// Phase 2: Shine sweep across title (3 passes)
|
|
619
|
+
const SHINE_PASSES = 3;
|
|
620
|
+
const SHINE_WIDTH = 4;
|
|
621
|
+
for (let pass = 0; pass < SHINE_PASSES; pass++) {
|
|
622
|
+
for (let shinePos = -SHINE_WIDTH; shinePos <= titleText.length + SHINE_WIDTH; shinePos++) {
|
|
623
|
+
process.stdout.write('\x1B[1A'); // Move up one line
|
|
624
|
+
process.stdout.write('\r '); // Return to start
|
|
625
|
+
let output = '';
|
|
626
|
+
for (let i = 0; i < titleText.length; i++) {
|
|
627
|
+
const distFromShine = Math.abs(i - shinePos);
|
|
628
|
+
if (distFromShine === 0) {
|
|
629
|
+
output += whiteShine.bold(titleText[i]);
|
|
630
|
+
}
|
|
631
|
+
else if (distFromShine === 1) {
|
|
632
|
+
output += chalk_1.default.hex('#FFFFFF')(titleText[i]);
|
|
633
|
+
}
|
|
634
|
+
else if (distFromShine === 2) {
|
|
635
|
+
output += chalk_1.default.hex('#FFD700')(titleText[i]);
|
|
636
|
+
}
|
|
637
|
+
else if (distFromShine === 3) {
|
|
638
|
+
output += chalk_1.default.hex('#FFA500')(titleText[i]);
|
|
639
|
+
}
|
|
640
|
+
else {
|
|
641
|
+
output += chalk_1.default.hex('#FF6B35').bold(titleText[i]);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
process.stdout.write(output + '\n'); // Write and move down for next frame
|
|
645
|
+
await sleep(15);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
// Final title state
|
|
649
|
+
process.stdout.write('\x1B[1A\r');
|
|
650
|
+
console.log(' ' + chalk_1.default.hex('#FF6B35').bold(titleText));
|
|
651
|
+
// Phase 3: Tagline fade-in with shimmer
|
|
652
|
+
await sleep(100);
|
|
653
|
+
// Build up tagline with wave effect
|
|
654
|
+
const taglineColors = [
|
|
655
|
+
chalk_1.default.hex('#444444'),
|
|
656
|
+
chalk_1.default.hex('#666666'),
|
|
657
|
+
chalk_1.default.hex('#888888'),
|
|
658
|
+
chalk_1.default.hex('#AAAAAA'),
|
|
659
|
+
chalk_1.default.hex('#CCCCCC'),
|
|
660
|
+
chalk_1.default.hex('#EEEEEE'),
|
|
661
|
+
chalk_1.default.gray,
|
|
662
|
+
];
|
|
663
|
+
for (let wave = 0; wave < taglineColors.length; wave++) {
|
|
664
|
+
process.stdout.write('\r ');
|
|
665
|
+
process.stdout.write(taglineColors[wave](taglineText));
|
|
666
|
+
await sleep(40);
|
|
667
|
+
}
|
|
668
|
+
console.log('');
|
|
669
|
+
// Phase 4: Quick orange accent pulse on tagline
|
|
670
|
+
for (let pulse = 0; pulse < 2; pulse++) {
|
|
671
|
+
await sleep(80);
|
|
672
|
+
process.stdout.write('\x1B[1A\r');
|
|
673
|
+
console.log(' ' + chalk_1.default.hex('#FF8C00')(taglineText));
|
|
674
|
+
await sleep(80);
|
|
675
|
+
process.stdout.write('\x1B[1A\r');
|
|
676
|
+
console.log(' ' + chalk_1.default.gray(taglineText));
|
|
677
|
+
}
|
|
678
|
+
// Final tagline state with subtle orange tint
|
|
679
|
+
process.stdout.write('\x1B[1A\r');
|
|
680
|
+
console.log(' ' + chalk_1.default.hex('#B8860B')(taglineText));
|
|
681
|
+
console.log('');
|
|
538
682
|
if (bypass) {
|
|
539
683
|
console.log(chalk_1.default.yellow(' ⚡ Bypass permissions mode enabled'));
|
|
540
684
|
}
|
|
@@ -543,10 +687,18 @@ async function run(options) {
|
|
|
543
687
|
console.log(chalk_1.default.gray(` ⏱ Timing: clear=${config.clearWaitMs}ms, idleMax=${config.maxIdleWaitMs}ms (~${Math.round((config.clearWaitMs + config.maxIdleWaitMs * 2 + 1700) / 1000)}s total)`));
|
|
544
688
|
}
|
|
545
689
|
console.log('');
|
|
546
|
-
//
|
|
547
|
-
|
|
548
|
-
//
|
|
549
|
-
|
|
690
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
691
|
+
// ANIMATION COMPLETE: Mark ready and flush buffered Claude output
|
|
692
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
693
|
+
animationComplete = true;
|
|
694
|
+
dlog(`Animation complete. shellReady=${shellReady}, buffered=${bufferedOutput.length} chunks`);
|
|
695
|
+
// Show loading indicator if Claude is still initializing
|
|
696
|
+
if (shellReady && bufferedOutput.length === 0) {
|
|
697
|
+
process.stdout.write(chalk_1.default.gray(' Connecting to Claude...'));
|
|
698
|
+
// Brief wait for any buffered output
|
|
699
|
+
await sleep(100);
|
|
700
|
+
process.stdout.write('\r' + ' '.repeat(30) + '\r'); // Clear the line
|
|
701
|
+
}
|
|
550
702
|
// Track state
|
|
551
703
|
let currentSession = options.session || (0, state_1.getCurrentSessionName)();
|
|
552
704
|
// Write initial instance file
|
|
@@ -627,39 +779,13 @@ async function run(options) {
|
|
|
627
779
|
// Debounce tracking to prevent double triggers
|
|
628
780
|
let lastDetectionTime = 0;
|
|
629
781
|
const DETECTION_COOLDOWN = 30000; // 30 seconds cooldown
|
|
630
|
-
//
|
|
631
|
-
const
|
|
632
|
-
// Handle npx:VERSION format for pinned version
|
|
633
|
-
const isNpxMode = rawClaudePath.startsWith('npx:');
|
|
634
|
-
const pinnedVersion = isNpxMode ? rawClaudePath.split(':')[1] : null;
|
|
635
|
-
const claudePath = isNpxMode ? 'npx' : rawClaudePath;
|
|
636
|
-
if (verbose) {
|
|
637
|
-
if (isNpxMode) {
|
|
638
|
-
console.log(chalk_1.default.gray(` 🤖 Using claude-code@${pinnedVersion} via npx (pinned for better context)`));
|
|
639
|
-
}
|
|
640
|
-
else {
|
|
641
|
-
console.log(chalk_1.default.gray(` 🤖 Using claude at: ${claudePath}`));
|
|
642
|
-
}
|
|
643
|
-
if (currentSession) {
|
|
644
|
-
console.log(chalk_1.default.green(` 📍 Session: ${currentSession}`));
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
// Build args - prepend package name if using npx
|
|
648
|
-
const args = [];
|
|
649
|
-
if (isNpxMode) {
|
|
650
|
-
args.push(`@anthropic-ai/claude-code@${pinnedVersion}`);
|
|
651
|
-
}
|
|
652
|
-
if (bypass) {
|
|
653
|
-
args.push('--dangerously-skip-permissions');
|
|
654
|
-
}
|
|
655
|
-
// Determine which mode to use
|
|
656
|
-
const usePty = pty !== null;
|
|
782
|
+
// Use args from early setup
|
|
783
|
+
const args = earlyArgs;
|
|
657
784
|
// ══════════════════════════════════════════════════════════════════════════
|
|
658
785
|
// WINDOWS: MONITOR-ONLY MODE WITHOUT PTY (Per Spec v1.2 Addendum)
|
|
659
786
|
// Without node-pty/ConPTY, auto-continue cannot work on Windows.
|
|
660
787
|
// Instead of hard-failing, we enter monitor-only mode.
|
|
661
788
|
// ══════════════════════════════════════════════════════════════════════════
|
|
662
|
-
const monitorOnlyMode = noInject || (isWindows && !usePty);
|
|
663
789
|
if (isWindows && !usePty) {
|
|
664
790
|
console.log('');
|
|
665
791
|
console.log(chalk_1.default.yellow.bold('⚠️ Monitor-only mode (PTY not available)'));
|
|
@@ -679,46 +805,84 @@ async function run(options) {
|
|
|
679
805
|
console.log(chalk_1.default.yellow(' Monitor-only mode (--no-inject)'));
|
|
680
806
|
}
|
|
681
807
|
if (verbose) {
|
|
808
|
+
if (isNpxMode) {
|
|
809
|
+
console.log(chalk_1.default.gray(` 🤖 Using claude-code@${pinnedVersion} via npx (pinned for better context)`));
|
|
810
|
+
}
|
|
811
|
+
else {
|
|
812
|
+
console.log(chalk_1.default.gray(` 🤖 Using claude at: ${claudePath}`));
|
|
813
|
+
}
|
|
814
|
+
if (currentSession) {
|
|
815
|
+
console.log(chalk_1.default.green(` 📍 Session: ${currentSession}`));
|
|
816
|
+
}
|
|
682
817
|
console.log(chalk_1.default.gray(` 💻 PTY mode: ${usePty ? 'node-pty' : 'spawn+script (fallback)'}`));
|
|
683
818
|
console.log('');
|
|
684
819
|
}
|
|
685
820
|
let shell;
|
|
821
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
822
|
+
// USE EARLY-SPAWNED SHELL OR CREATE NEW ONE
|
|
823
|
+
// If we spawned Claude during animation, reuse it. Otherwise spawn now.
|
|
824
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
686
825
|
if (usePty && pty) {
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
name: 'xterm-256color',
|
|
691
|
-
cols: process.stdout.columns || 80,
|
|
692
|
-
rows: process.stdout.rows || 24,
|
|
693
|
-
cwd: process.cwd(),
|
|
694
|
-
env: process.env
|
|
695
|
-
});
|
|
826
|
+
if (earlySpawnedShell && shellReady && !shellError) {
|
|
827
|
+
// REUSE early-spawned shell - Claude loaded during animation!
|
|
828
|
+
dlog('Reusing early-spawned shell (Claude loaded during animation)');
|
|
696
829
|
shell = {
|
|
697
|
-
write: (data) =>
|
|
698
|
-
kill: () =>
|
|
699
|
-
resize: (cols, rows) =>
|
|
700
|
-
onData: (callback) =>
|
|
701
|
-
|
|
830
|
+
write: (data) => earlySpawnedShell.write(data),
|
|
831
|
+
kill: () => earlySpawnedShell.kill(),
|
|
832
|
+
resize: (cols, rows) => earlySpawnedShell.resize(cols, rows),
|
|
833
|
+
onData: (callback) => {
|
|
834
|
+
// Switch the delegating handler from buffer mode to real handler
|
|
835
|
+
// This replaces buffering with actual output processing
|
|
836
|
+
earlyDataHandler = callback;
|
|
837
|
+
},
|
|
838
|
+
onExit: (callback) => earlySpawnedShell.onExit(callback)
|
|
702
839
|
};
|
|
703
|
-
//
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
840
|
+
// Flush buffered output NOW (before switching handler)
|
|
841
|
+
if (bufferedOutput.length > 0) {
|
|
842
|
+
dlog(`Flushing ${bufferedOutput.length} buffered output chunks`);
|
|
843
|
+
for (const chunk of bufferedOutput) {
|
|
844
|
+
process.stdout.write(chunk);
|
|
845
|
+
// Also populate output buffer for pattern detection
|
|
846
|
+
outputBuffer += chunk;
|
|
847
|
+
}
|
|
848
|
+
bufferedOutput = [];
|
|
849
|
+
}
|
|
707
850
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
851
|
+
else {
|
|
852
|
+
// Spawn fresh (early spawn failed or wasn't attempted)
|
|
853
|
+
dlog('Spawning Claude fresh (early spawn not available)');
|
|
854
|
+
try {
|
|
855
|
+
const ptyShell = pty.spawn(claudePath, args, {
|
|
856
|
+
name: 'xterm-256color',
|
|
857
|
+
cols: process.stdout.columns || 80,
|
|
858
|
+
rows: process.stdout.rows || 24,
|
|
859
|
+
cwd: process.cwd(),
|
|
860
|
+
env: process.env
|
|
861
|
+
});
|
|
862
|
+
shell = {
|
|
863
|
+
write: (data) => ptyShell.write(data),
|
|
864
|
+
kill: () => ptyShell.kill(),
|
|
865
|
+
resize: (cols, rows) => ptyShell.resize(cols, rows),
|
|
866
|
+
onData: (callback) => ptyShell.onData(callback),
|
|
867
|
+
onExit: (callback) => ptyShell.onExit(callback)
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
catch (err) {
|
|
871
|
+
dlog(`node-pty spawn failed: ${err.message}`);
|
|
872
|
+
// Fall through to spawn mode
|
|
873
|
+
return runWithSpawn(claudePath, args, options, {
|
|
874
|
+
currentSession,
|
|
875
|
+
isAutoClearInProgress,
|
|
876
|
+
transcriptPath,
|
|
877
|
+
currentSessionId,
|
|
878
|
+
outputBuffer
|
|
879
|
+
});
|
|
712
880
|
}
|
|
713
|
-
// Fall through to spawn mode
|
|
714
|
-
return runWithSpawn(claudePath, args, options, {
|
|
715
|
-
currentSession,
|
|
716
|
-
isAutoClearInProgress,
|
|
717
|
-
transcriptPath,
|
|
718
|
-
currentSessionId,
|
|
719
|
-
outputBuffer
|
|
720
|
-
});
|
|
721
881
|
}
|
|
882
|
+
// Handle terminal resize
|
|
883
|
+
process.stdout.on('resize', () => {
|
|
884
|
+
shell.resize?.(process.stdout.columns || 80, process.stdout.rows || 24);
|
|
885
|
+
});
|
|
722
886
|
}
|
|
723
887
|
else {
|
|
724
888
|
// Fallback: use spawn+script for PTY emulation
|
|
@@ -1023,6 +1187,66 @@ async function run(options) {
|
|
|
1023
1187
|
}
|
|
1024
1188
|
}
|
|
1025
1189
|
});
|
|
1190
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
1191
|
+
// RESEARCH MODE: Auto-type research prompt after Claude is ready
|
|
1192
|
+
// Triggers: `ekkos run -r` or `ekkos run --research`
|
|
1193
|
+
// Works like /clear continue - waits for idle prompt, then injects text
|
|
1194
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
1195
|
+
if (options.research) {
|
|
1196
|
+
dlog('Research mode enabled - will auto-inject research prompt');
|
|
1197
|
+
// Research prompt - comprehensive autonomous research scanning
|
|
1198
|
+
const researchPrompt = `You are the ekkOS Research Scout agent. Your task:
|
|
1199
|
+
|
|
1200
|
+
1. **Scan arXiv** (cs.AI, cs.LG, cs.CL) for papers from the last 7 days
|
|
1201
|
+
2. **Filter for relevance** to ekkOS memory systems:
|
|
1202
|
+
- Memory-augmented neural networks
|
|
1203
|
+
- Retrieval-augmented generation (RAG)
|
|
1204
|
+
- Long-term memory for LLMs
|
|
1205
|
+
- Pattern learning and extraction
|
|
1206
|
+
- Cognitive architectures
|
|
1207
|
+
- Knowledge graphs
|
|
1208
|
+
- Episodic/semantic memory systems
|
|
1209
|
+
3. **Analyze each relevant paper**:
|
|
1210
|
+
- Core technique and novelty
|
|
1211
|
+
- Applicability to ekkOS 11-layer architecture
|
|
1212
|
+
- Implementation complexity (low/medium/high)
|
|
1213
|
+
- Potential impact (1-5 scale)
|
|
1214
|
+
4. **Update docs/EKKOS_RESEARCH_ROADMAP.md** with findings
|
|
1215
|
+
5. **Forge high-value insights as patterns** using ekkOS_Forge
|
|
1216
|
+
|
|
1217
|
+
Use Perplexity for deep research. Be thorough but efficient. Start now.`;
|
|
1218
|
+
// Start research injection after a delay to let Claude initialize
|
|
1219
|
+
setTimeout(async () => {
|
|
1220
|
+
dlog('Starting research prompt injection...');
|
|
1221
|
+
// Wait for idle prompt (same gate as /clear continue uses)
|
|
1222
|
+
const readiness = await waitForIdlePrompt(getOutputBuffer, config);
|
|
1223
|
+
if (!readiness.ready || readiness.interrupted) {
|
|
1224
|
+
dlog('Claude not ready for research prompt - aborting');
|
|
1225
|
+
return;
|
|
1226
|
+
}
|
|
1227
|
+
// PAUSE STDIN during injection to prevent user interference
|
|
1228
|
+
process.stdin.off('data', onStdinData);
|
|
1229
|
+
dlog('Stdin paused during research injection');
|
|
1230
|
+
try {
|
|
1231
|
+
// Clear any existing input
|
|
1232
|
+
shell.write('\x15'); // Ctrl+U
|
|
1233
|
+
await sleep(60);
|
|
1234
|
+
// Type the research prompt character by character (faster for long prompts)
|
|
1235
|
+
dlog('Typing research prompt...');
|
|
1236
|
+
const fastCharDelay = Math.min(config.charDelayMs, 10); // Faster typing for long prompt
|
|
1237
|
+
await typeSlowly(shell, researchPrompt, fastCharDelay);
|
|
1238
|
+
// Send Enter to execute
|
|
1239
|
+
await sleep(100);
|
|
1240
|
+
shell.write('\r');
|
|
1241
|
+
dlog('Research prompt sent');
|
|
1242
|
+
}
|
|
1243
|
+
finally {
|
|
1244
|
+
// RESUME STDIN
|
|
1245
|
+
process.stdin.on('data', onStdinData);
|
|
1246
|
+
dlog('Stdin resumed after research injection');
|
|
1247
|
+
}
|
|
1248
|
+
}, 4000); // Wait 4 seconds for Claude to fully initialize
|
|
1249
|
+
}
|
|
1026
1250
|
// Handle PTY exit
|
|
1027
1251
|
shell.onExit(({ exitCode }) => {
|
|
1028
1252
|
(0, state_1.clearAutoClearFlag)();
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ekkos setup-remote - One-command setup for remote terminal access
|
|
3
|
+
*
|
|
4
|
+
* This command does everything automatically:
|
|
5
|
+
* 1. Checks if user is logged in (prompts login if not)
|
|
6
|
+
* 2. Generates unique device ID and fingerprint
|
|
7
|
+
* 3. Opens browser for device pairing approval
|
|
8
|
+
* 4. Installs background agent as system service
|
|
9
|
+
* 5. Starts agent immediately
|
|
10
|
+
* 6. Verifies connection to cloud relay
|
|
11
|
+
*/
|
|
12
|
+
export interface SetupRemoteOptions {
|
|
13
|
+
force?: boolean;
|
|
14
|
+
skipService?: boolean;
|
|
15
|
+
verbose?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Main setup command
|
|
19
|
+
*/
|
|
20
|
+
export declare function setupRemote(options?: SetupRemoteOptions): Promise<void>;
|