vibelet 1.2.210 → 1.2.215
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/index.cjs +1 -1
- package/dist/inventory-scan-worker.cjs +1 -1
- package/dist/runtime-version.cjs +1 -1
- package/dist/tailcat/vibelet-tailcat-darwin-amd64 +0 -0
- package/dist/tailcat/vibelet-tailcat-darwin-arm64 +0 -0
- package/dist/tailcat/vibelet-tailcat-linux-amd64 +0 -0
- package/dist/tailcat/vibelet-tailcat-linux-arm64 +0 -0
- package/dist/tailcat/vibelet-tailcat-win32-amd64.exe +0 -0
- package/dist/tailcat/vibelet-tailcat-win32-arm64.exe +0 -0
- package/dist/vibelet.mjs +621 -519
- package/package.json +1 -1
package/dist/vibelet.mjs
CHANGED
|
@@ -11340,7 +11340,7 @@ module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("zlib");
|
|
|
11340
11340
|
|
|
11341
11341
|
/***/ }),
|
|
11342
11342
|
|
|
11343
|
-
/***/
|
|
11343
|
+
/***/ 1484:
|
|
11344
11344
|
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __nccwpck_require__) => {
|
|
11345
11345
|
|
|
11346
11346
|
|
|
@@ -11362,218 +11362,16 @@ var external_node_fs_ = __nccwpck_require__(3024);
|
|
|
11362
11362
|
var external_node_module_ = __nccwpck_require__(8995);
|
|
11363
11363
|
// EXTERNAL MODULE: external "node:path"
|
|
11364
11364
|
var external_node_path_ = __nccwpck_require__(6760);
|
|
11365
|
-
|
|
11366
|
-
var promises_ = __nccwpck_require__(1455);
|
|
11367
|
-
// EXTERNAL MODULE: external "node:util"
|
|
11368
|
-
var external_node_util_ = __nccwpck_require__(7975);
|
|
11369
|
-
;// CONCATENATED MODULE: ../../packages/cloudflared-tunnel/managed-binary.mjs
|
|
11370
|
-
|
|
11371
|
-
|
|
11372
|
-
|
|
11373
|
-
|
|
11374
|
-
|
|
11375
|
-
|
|
11376
|
-
const execFileAsync = (0,external_node_util_.promisify)(external_node_child_process_.execFile);
|
|
11377
|
-
const DEFAULT_UPDATE_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
11378
|
-
const DEFAULT_UPDATE_TIMEOUT_MS = 30_000;
|
|
11379
|
-
|
|
11380
|
-
function parseCloudflaredVersion(output) {
|
|
11381
|
-
return String(output || '').match(/cloudflared version\s+([0-9]+(?:\.[0-9]+){1,2})/i)?.[1] ?? null;
|
|
11382
|
-
}
|
|
11383
|
-
|
|
11384
|
-
async function readUpdateState(updateStatePath) {
|
|
11385
|
-
try {
|
|
11386
|
-
const state = JSON.parse(await (0,promises_.readFile)(updateStatePath, 'utf8'));
|
|
11387
|
-
return state && typeof state === 'object' ? state : null;
|
|
11388
|
-
} catch {
|
|
11389
|
-
return null;
|
|
11390
|
-
}
|
|
11391
|
-
}
|
|
11392
|
-
|
|
11393
|
-
async function writeUpdateState(updateStatePath, state) {
|
|
11394
|
-
await (0,promises_.mkdir)((0,external_node_path_.dirname)(updateStatePath), { recursive: true });
|
|
11395
|
-
const temporaryPath = `${updateStatePath}.tmp-${process.pid}-${Date.now()}`;
|
|
11396
|
-
await (0,promises_.writeFile)(temporaryPath, `${JSON.stringify(state, null, 2)}\n`, 'utf8');
|
|
11397
|
-
await (0,promises_.rename)(temporaryPath, updateStatePath);
|
|
11398
|
-
}
|
|
11399
|
-
|
|
11400
|
-
async function runVersion(binaryPath, timeoutMs, runCommand) {
|
|
11401
|
-
if (!binaryPath || !(0,external_node_fs_.existsSync)(binaryPath)) return null;
|
|
11402
|
-
try {
|
|
11403
|
-
const { stdout, stderr } = await runCommand(binaryPath, ['--version'], {
|
|
11404
|
-
encoding: 'utf8',
|
|
11405
|
-
timeout: timeoutMs,
|
|
11406
|
-
maxBuffer: 1024 * 1024,
|
|
11407
|
-
});
|
|
11408
|
-
return parseCloudflaredVersion(`${stdout || ''}\n${stderr || ''}`);
|
|
11409
|
-
} catch {
|
|
11410
|
-
return null;
|
|
11411
|
-
}
|
|
11412
|
-
}
|
|
11413
|
-
|
|
11414
|
-
async function probeCloudflaredLaunchSpecVersion(
|
|
11415
|
-
launchSpec,
|
|
11416
|
-
{ timeoutMs = 5_000, runCommand = execFileAsync } = {},
|
|
11417
|
-
) {
|
|
11418
|
-
try {
|
|
11419
|
-
const { stdout, stderr } = await runCommand(launchSpec.command, [...launchSpec.args, '--version'], {
|
|
11420
|
-
encoding: 'utf8',
|
|
11421
|
-
timeout: timeoutMs,
|
|
11422
|
-
maxBuffer: 1024 * 1024,
|
|
11423
|
-
...(launchSpec.shell ? { shell: true } : {}),
|
|
11424
|
-
});
|
|
11425
|
-
return parseCloudflaredVersion(`${stdout || ''}\n${stderr || ''}`);
|
|
11426
|
-
} catch {
|
|
11427
|
-
return null;
|
|
11428
|
-
}
|
|
11429
|
-
}
|
|
11430
|
-
|
|
11431
|
-
async function installLatestToTemporaryPath({ launchSpec, binaryPath, timeoutMs, platform, runCommand }) {
|
|
11432
|
-
const temporaryDir = (0,external_node_path_.join)((0,external_node_path_.dirname)(binaryPath), `.cloudflared-update-${process.pid}-${Date.now()}`);
|
|
11433
|
-
const temporaryBinaryPath = (0,external_node_path_.join)(temporaryDir, (0,external_node_path_.basename)(binaryPath));
|
|
11434
|
-
await (0,promises_.mkdir)(temporaryDir, { recursive: true });
|
|
11435
|
-
try {
|
|
11436
|
-
await runCommand(launchSpec.command, [...launchSpec.args, 'bin', 'install', 'latest'], {
|
|
11437
|
-
encoding: 'utf8',
|
|
11438
|
-
timeout: timeoutMs,
|
|
11439
|
-
maxBuffer: 4 * 1024 * 1024,
|
|
11440
|
-
env: { ...process.env, CLOUDFLARED_BIN: temporaryBinaryPath },
|
|
11441
|
-
...(launchSpec.shell ? { shell: true } : {}),
|
|
11442
|
-
});
|
|
11443
|
-
const version = await runVersion(temporaryBinaryPath, timeoutMs, runCommand);
|
|
11444
|
-
if (!version) throw new Error('downloaded cloudflared did not report a valid version');
|
|
11445
|
-
|
|
11446
|
-
if (platform === 'win32' && (0,external_node_fs_.existsSync)(binaryPath)) {
|
|
11447
|
-
const backupPath = `${binaryPath}.previous-${process.pid}`;
|
|
11448
|
-
await (0,promises_.rename)(binaryPath, backupPath);
|
|
11449
|
-
try {
|
|
11450
|
-
await (0,promises_.rename)(temporaryBinaryPath, binaryPath);
|
|
11451
|
-
await (0,promises_.rm)(backupPath, { force: true });
|
|
11452
|
-
} catch (error) {
|
|
11453
|
-
await (0,promises_.rename)(backupPath, binaryPath).catch(() => undefined);
|
|
11454
|
-
throw error;
|
|
11455
|
-
}
|
|
11456
|
-
} else {
|
|
11457
|
-
await (0,promises_.rename)(temporaryBinaryPath, binaryPath);
|
|
11458
|
-
}
|
|
11459
|
-
return version;
|
|
11460
|
-
} finally {
|
|
11461
|
-
await (0,promises_.rm)(temporaryDir, { recursive: true, force: true });
|
|
11462
|
-
}
|
|
11463
|
-
}
|
|
11464
|
-
|
|
11465
|
-
async function resolveManagedCloudflared({
|
|
11466
|
-
launchSpec,
|
|
11467
|
-
updateStatePath,
|
|
11468
|
-
now = Date.now(),
|
|
11469
|
-
updateIntervalMs = DEFAULT_UPDATE_INTERVAL_MS,
|
|
11470
|
-
timeoutMs = DEFAULT_UPDATE_TIMEOUT_MS,
|
|
11471
|
-
platform = process.platform,
|
|
11472
|
-
runCommand = execFileAsync,
|
|
11473
|
-
}) {
|
|
11474
|
-
const state = await readUpdateState(updateStatePath);
|
|
11475
|
-
const lastAttemptAt = Date.parse(state?.lastAttemptAt || '');
|
|
11476
|
-
const recentlyAttempted = Number.isFinite(lastAttemptAt) && now - lastAttemptAt < updateIntervalMs;
|
|
11477
|
-
if (recentlyAttempted) {
|
|
11478
|
-
return {
|
|
11479
|
-
launchSpec,
|
|
11480
|
-
version: state?.installedVersion ?? null,
|
|
11481
|
-
update: 'skipped',
|
|
11482
|
-
};
|
|
11483
|
-
}
|
|
11484
|
-
|
|
11485
|
-
const attemptedAt = new Date(now).toISOString();
|
|
11486
|
-
const binaryPath = launchSpec.managedBinaryPath;
|
|
11487
|
-
if (launchSpec.source !== 'dependency' || !binaryPath) {
|
|
11488
|
-
const version = state?.installedVersion ?? null;
|
|
11489
|
-
let stateWarning = '';
|
|
11490
|
-
try {
|
|
11491
|
-
await writeUpdateState(updateStatePath, {
|
|
11492
|
-
...state,
|
|
11493
|
-
lastAttemptAt: attemptedAt,
|
|
11494
|
-
installedVersion: version,
|
|
11495
|
-
});
|
|
11496
|
-
} catch (error) {
|
|
11497
|
-
stateWarning = ` Update state could not be saved: ${error instanceof Error ? error.message : String(error)}`;
|
|
11498
|
-
}
|
|
11499
|
-
return {
|
|
11500
|
-
launchSpec,
|
|
11501
|
-
version,
|
|
11502
|
-
update: 'skipped',
|
|
11503
|
-
warning: `Skipping cloudflared self-update for unmanaged ${launchSpec.source} executable: ${launchSpec.description}.${stateWarning}`,
|
|
11504
|
-
};
|
|
11505
|
-
}
|
|
11506
|
-
|
|
11507
|
-
const previousVersion = await runVersion(binaryPath, timeoutMs, runCommand);
|
|
11508
|
-
try {
|
|
11509
|
-
const installedVersion = await installLatestToTemporaryPath({
|
|
11510
|
-
launchSpec,
|
|
11511
|
-
binaryPath,
|
|
11512
|
-
timeoutMs,
|
|
11513
|
-
platform,
|
|
11514
|
-
runCommand,
|
|
11515
|
-
});
|
|
11516
|
-
await writeUpdateState(updateStatePath, {
|
|
11517
|
-
lastAttemptAt: attemptedAt,
|
|
11518
|
-
lastSuccessAt: attemptedAt,
|
|
11519
|
-
installedVersion,
|
|
11520
|
-
});
|
|
11521
|
-
return {
|
|
11522
|
-
launchSpec,
|
|
11523
|
-
version: installedVersion,
|
|
11524
|
-
update: previousVersion ? 'updated' : 'fresh',
|
|
11525
|
-
};
|
|
11526
|
-
} catch (error) {
|
|
11527
|
-
const fallbackVersion = previousVersion || (await runVersion(binaryPath, timeoutMs, runCommand));
|
|
11528
|
-
await writeUpdateState(updateStatePath, {
|
|
11529
|
-
...state,
|
|
11530
|
-
lastAttemptAt: attemptedAt,
|
|
11531
|
-
installedVersion: fallbackVersion,
|
|
11532
|
-
}).catch(() => undefined);
|
|
11533
|
-
return {
|
|
11534
|
-
launchSpec,
|
|
11535
|
-
version: fallbackVersion,
|
|
11536
|
-
update: 'failed',
|
|
11537
|
-
warning: `cloudflared update failed; continuing with ${fallbackVersion || 'the existing launcher'}: ${error instanceof Error ? error.message : String(error)}`,
|
|
11538
|
-
};
|
|
11539
|
-
}
|
|
11540
|
-
}
|
|
11541
|
-
|
|
11542
|
-
;// CONCATENATED MODULE: ../../packages/cloudflared-tunnel/index.mjs
|
|
11543
|
-
|
|
11544
|
-
|
|
11545
|
-
|
|
11365
|
+
;// CONCATENATED MODULE: ../../packages/cloudflared-tunnel/launch-spec.mjs
|
|
11546
11366
|
|
|
11547
11367
|
|
|
11548
11368
|
|
|
11549
11369
|
|
|
11550
11370
|
|
|
11551
|
-
const QUICK_TUNNEL_URL_PATTERN = /https:\/\/[a-z0-9-]+\.trycloudflare\.com(?=$|[\s"',)\]])/g;
|
|
11552
11371
|
const npmFallbackArgs = ['--yes', '--package=cloudflared', 'cloudflared'];
|
|
11553
11372
|
const npmFallbackDescription = `npx ${npmFallbackArgs.join(' ')}`;
|
|
11554
11373
|
const defaultUrlTimeoutMs = 90_000;
|
|
11555
11374
|
|
|
11556
|
-
function supportsFastAutoProtocolFallback(version) {
|
|
11557
|
-
if (!version) return false;
|
|
11558
|
-
const parts = version.split('.').map(Number);
|
|
11559
|
-
const threshold = [2026, 5, 2];
|
|
11560
|
-
for (let index = 0; index < threshold.length; index += 1) {
|
|
11561
|
-
const value = parts[index] || 0;
|
|
11562
|
-
if (value !== threshold[index]) return value > threshold[index];
|
|
11563
|
-
}
|
|
11564
|
-
return true;
|
|
11565
|
-
}
|
|
11566
|
-
|
|
11567
|
-
function extractQuickTunnelUrl(logContent) {
|
|
11568
|
-
if (typeof logContent !== 'string' || logContent.length === 0) {
|
|
11569
|
-
return null;
|
|
11570
|
-
}
|
|
11571
|
-
|
|
11572
|
-
const match = QUICK_TUNNEL_URL_PATTERN.exec(logContent);
|
|
11573
|
-
QUICK_TUNNEL_URL_PATTERN.lastIndex = 0;
|
|
11574
|
-
return match?.[0] ?? null;
|
|
11575
|
-
}
|
|
11576
|
-
|
|
11577
11375
|
function isQuickTunnelUrl(url) {
|
|
11578
11376
|
if (typeof url !== 'string' || !url.trim()) return false;
|
|
11579
11377
|
try {
|
|
@@ -11657,55 +11455,6 @@ function readProcessCommandLine(pid, { platform = process.platform, spawnSyncImp
|
|
|
11657
11455
|
return result.status === 0 ? String(result.stdout || '').trim() : '';
|
|
11658
11456
|
}
|
|
11659
11457
|
|
|
11660
|
-
function extractCloudflaredMetricsBaseUrl(logContent) {
|
|
11661
|
-
if (typeof logContent !== 'string' || logContent.length === 0) {
|
|
11662
|
-
return null;
|
|
11663
|
-
}
|
|
11664
|
-
const match = logContent.match(
|
|
11665
|
-
/Starting metrics server on (?:https?:\/\/)?(127\.0\.0\.1|localhost|\[::1\]):(\d+)\/metrics\b/iu,
|
|
11666
|
-
);
|
|
11667
|
-
if (!match) return null;
|
|
11668
|
-
return `http://${match[1]}:${match[2]}`;
|
|
11669
|
-
}
|
|
11670
|
-
|
|
11671
|
-
async function probeCloudflaredReadiness(logContent, { fetchFn = globalThis.fetch, timeoutMs = 1000 } = {}) {
|
|
11672
|
-
const metricsBaseUrl = extractCloudflaredMetricsBaseUrl(logContent);
|
|
11673
|
-
if (!metricsBaseUrl || typeof fetchFn !== 'function') return false;
|
|
11674
|
-
|
|
11675
|
-
const controller = new AbortController();
|
|
11676
|
-
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
11677
|
-
try {
|
|
11678
|
-
const response = await fetchFn(`${metricsBaseUrl}/ready`, { signal: controller.signal });
|
|
11679
|
-
return response.ok;
|
|
11680
|
-
} catch {
|
|
11681
|
-
return false;
|
|
11682
|
-
} finally {
|
|
11683
|
-
clearTimeout(timeout);
|
|
11684
|
-
}
|
|
11685
|
-
}
|
|
11686
|
-
|
|
11687
|
-
async function probeQuickTunnelPublicHealth(state, { fetchFn = globalThis.fetch, timeoutMs = 1_500 } = {}) {
|
|
11688
|
-
if (!isQuickTunnelUrl(state?.url) || typeof fetchFn !== 'function') return false;
|
|
11689
|
-
|
|
11690
|
-
const controller = new AbortController();
|
|
11691
|
-
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
11692
|
-
try {
|
|
11693
|
-
const healthUrl = new URL('/health', state.url);
|
|
11694
|
-
healthUrl.searchParams.set('_vibelet_reuse_probe', String(Date.now()));
|
|
11695
|
-
const response = await fetchFn(healthUrl, {
|
|
11696
|
-
headers: { 'cache-control': 'no-cache' },
|
|
11697
|
-
signal: controller.signal,
|
|
11698
|
-
});
|
|
11699
|
-
if (!response.ok) return false;
|
|
11700
|
-
const payload = await response.json().catch(() => null);
|
|
11701
|
-
return payload?.status === 'ok';
|
|
11702
|
-
} catch {
|
|
11703
|
-
return false;
|
|
11704
|
-
} finally {
|
|
11705
|
-
clearTimeout(timeout);
|
|
11706
|
-
}
|
|
11707
|
-
}
|
|
11708
|
-
|
|
11709
11458
|
function getNpmFallbackCommand(platform = process.platform) {
|
|
11710
11459
|
return platform === 'win32' ? 'npx.cmd' : 'npx';
|
|
11711
11460
|
}
|
|
@@ -11803,79 +11552,389 @@ function resolveInstalledCloudflaredCliPath({
|
|
|
11803
11552
|
return null;
|
|
11804
11553
|
}
|
|
11805
11554
|
|
|
11806
|
-
let packageJson;
|
|
11807
|
-
try {
|
|
11808
|
-
packageJson = JSON.parse((0,external_node_fs_.readFileSync)(packageJsonPath, 'utf8'));
|
|
11809
|
-
} catch {
|
|
11810
|
-
return null;
|
|
11811
|
-
}
|
|
11555
|
+
let packageJson;
|
|
11556
|
+
try {
|
|
11557
|
+
packageJson = JSON.parse((0,external_node_fs_.readFileSync)(packageJsonPath, 'utf8'));
|
|
11558
|
+
} catch {
|
|
11559
|
+
return null;
|
|
11560
|
+
}
|
|
11561
|
+
|
|
11562
|
+
const relativeBinPath = typeof packageJson.bin === 'string' ? packageJson.bin : packageJson.bin?.cloudflared;
|
|
11563
|
+
|
|
11564
|
+
if (typeof relativeBinPath !== 'string' || !relativeBinPath) {
|
|
11565
|
+
return null;
|
|
11566
|
+
}
|
|
11567
|
+
|
|
11568
|
+
const cliPath = (0,external_node_path_.isAbsolute)(relativeBinPath) ? relativeBinPath : (0,external_node_path_.resolve)((0,external_node_path_.dirname)(packageJsonPath), relativeBinPath);
|
|
11569
|
+
|
|
11570
|
+
return (0,external_node_fs_.existsSync)(cliPath) ? cliPath : null;
|
|
11571
|
+
}
|
|
11572
|
+
|
|
11573
|
+
function createDependencyLaunchSpec(dependencyCliPath, platform = process.platform) {
|
|
11574
|
+
return {
|
|
11575
|
+
command: process.execPath,
|
|
11576
|
+
args: [dependencyCliPath],
|
|
11577
|
+
source: 'dependency',
|
|
11578
|
+
description: dependencyCliPath,
|
|
11579
|
+
managedBinaryPath: (0,external_node_path_.join)(
|
|
11580
|
+
(0,external_node_path_.dirname)((0,external_node_path_.dirname)(dependencyCliPath)),
|
|
11581
|
+
'bin',
|
|
11582
|
+
platform === 'win32' ? 'cloudflared.exe' : 'cloudflared',
|
|
11583
|
+
),
|
|
11584
|
+
urlTimeoutMs: defaultUrlTimeoutMs,
|
|
11585
|
+
};
|
|
11586
|
+
}
|
|
11587
|
+
|
|
11588
|
+
function resolveCloudflaredLaunchSpec({
|
|
11589
|
+
pathValue = process.env.PATH ?? '',
|
|
11590
|
+
pathExtValue = process.env.PATHEXT ?? '',
|
|
11591
|
+
platform = process.platform,
|
|
11592
|
+
resolvePackageJsonPath,
|
|
11593
|
+
} = {}) {
|
|
11594
|
+
const directPathCandidates = findExecutablesInPath('cloudflared', { pathValue, pathExtValue, platform });
|
|
11595
|
+
const directPath =
|
|
11596
|
+
directPathCandidates.find((candidatePath) => !isNodeModulesBinPath(candidatePath)) ??
|
|
11597
|
+
directPathCandidates[0] ??
|
|
11598
|
+
null;
|
|
11599
|
+
if (directPath) {
|
|
11600
|
+
return {
|
|
11601
|
+
command: directPath,
|
|
11602
|
+
args: [],
|
|
11603
|
+
source: 'path',
|
|
11604
|
+
description: directPath,
|
|
11605
|
+
...(isWindowsCommandScript(directPath, platform) ? { shell: true } : {}),
|
|
11606
|
+
urlTimeoutMs: defaultUrlTimeoutMs,
|
|
11607
|
+
};
|
|
11608
|
+
}
|
|
11609
|
+
|
|
11610
|
+
const dependencyCliPath = resolveInstalledCloudflaredCliPath({ resolvePackageJsonPath });
|
|
11611
|
+
if (dependencyCliPath) {
|
|
11612
|
+
return createDependencyLaunchSpec(dependencyCliPath, platform);
|
|
11613
|
+
}
|
|
11614
|
+
|
|
11615
|
+
return {
|
|
11616
|
+
command: getNpmFallbackCommand(platform),
|
|
11617
|
+
args: [...npmFallbackArgs],
|
|
11618
|
+
source: 'npm',
|
|
11619
|
+
description: npmFallbackDescription,
|
|
11620
|
+
...(platform === 'win32' ? { shell: true } : {}),
|
|
11621
|
+
urlTimeoutMs: defaultUrlTimeoutMs,
|
|
11622
|
+
};
|
|
11623
|
+
}
|
|
11624
|
+
|
|
11625
|
+
function resolvePreferredCloudflaredLaunchSpec() {
|
|
11626
|
+
const dependencyCliPath = resolveInstalledCloudflaredCliPath();
|
|
11627
|
+
return dependencyCliPath ? createDependencyLaunchSpec(dependencyCliPath) : resolveCloudflaredLaunchSpec();
|
|
11628
|
+
}
|
|
11629
|
+
|
|
11630
|
+
function cloudflaredChildEnv(launchSpec, env = process.env, versions = process.versions) {
|
|
11631
|
+
// Electron must run the npm CLI as Node; app mode can exit while its child
|
|
11632
|
+
// tunnel is still starting, losing ownership of the process.
|
|
11633
|
+
return launchSpec.source === 'dependency' && versions.electron ? { ...env, ELECTRON_RUN_AS_NODE: '1' } : env;
|
|
11634
|
+
}
|
|
11635
|
+
|
|
11636
|
+
;// CONCATENATED MODULE: external "node:http"
|
|
11637
|
+
const external_node_http_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:http");
|
|
11638
|
+
;// CONCATENATED MODULE: external "node:https"
|
|
11639
|
+
const external_node_https_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:https");
|
|
11640
|
+
;// CONCATENATED MODULE: ../../packages/cloudflared-tunnel/health-fetch.mjs
|
|
11641
|
+
|
|
11642
|
+
|
|
11643
|
+
|
|
11644
|
+
// This package runs in Node and Electron plugin hosts. Renderer fetch applies
|
|
11645
|
+
// browser CORS to cloudflared's local metrics endpoint, which has no CORS headers.
|
|
11646
|
+
function fetchTunnelHealth(input, { signal, headers } = {}) {
|
|
11647
|
+
const url = new URL(input);
|
|
11648
|
+
const request = url.protocol === 'https:' ? external_node_https_namespaceObject.request : url.protocol === 'http:' ? external_node_http_namespaceObject.request : null;
|
|
11649
|
+
if (!request) return Promise.reject(new Error('Unsupported tunnel health protocol'));
|
|
11650
|
+
return new Promise((resolve, reject) => {
|
|
11651
|
+
const req = request(url, { signal, headers, method: 'GET' }, (res) => {
|
|
11652
|
+
const chunks = [];
|
|
11653
|
+
let size = 0;
|
|
11654
|
+
res.on('data', (chunk) => {
|
|
11655
|
+
size += chunk.length;
|
|
11656
|
+
if (size > 64 * 1024) {
|
|
11657
|
+
res.destroy(new Error('Tunnel health response is too large'));
|
|
11658
|
+
return;
|
|
11659
|
+
}
|
|
11660
|
+
chunks.push(chunk);
|
|
11661
|
+
});
|
|
11662
|
+
res.on('error', reject);
|
|
11663
|
+
res.on('end', () => {
|
|
11664
|
+
const body = Buffer.concat(chunks).toString('utf8');
|
|
11665
|
+
resolve({
|
|
11666
|
+
ok: res.statusCode >= 200 && res.statusCode < 300,
|
|
11667
|
+
json: async () => JSON.parse(body),
|
|
11668
|
+
});
|
|
11669
|
+
});
|
|
11670
|
+
});
|
|
11671
|
+
req.on('error', reject);
|
|
11672
|
+
req.end();
|
|
11673
|
+
});
|
|
11674
|
+
}
|
|
11675
|
+
|
|
11676
|
+
// EXTERNAL MODULE: external "node:fs/promises"
|
|
11677
|
+
var promises_ = __nccwpck_require__(1455);
|
|
11678
|
+
// EXTERNAL MODULE: external "node:util"
|
|
11679
|
+
var external_node_util_ = __nccwpck_require__(7975);
|
|
11680
|
+
;// CONCATENATED MODULE: ../../packages/cloudflared-tunnel/managed-binary.mjs
|
|
11681
|
+
|
|
11682
|
+
|
|
11683
|
+
|
|
11684
|
+
|
|
11685
|
+
|
|
11686
|
+
|
|
11687
|
+
|
|
11688
|
+
const execFileAsync = (0,external_node_util_.promisify)(external_node_child_process_.execFile);
|
|
11689
|
+
const DEFAULT_UPDATE_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
11690
|
+
const DEFAULT_UPDATE_TIMEOUT_MS = 30_000;
|
|
11691
|
+
|
|
11692
|
+
function parseCloudflaredVersion(output) {
|
|
11693
|
+
return String(output || '').match(/cloudflared version\s+([0-9]+(?:\.[0-9]+){1,2})/i)?.[1] ?? null;
|
|
11694
|
+
}
|
|
11695
|
+
|
|
11696
|
+
async function readUpdateState(updateStatePath) {
|
|
11697
|
+
try {
|
|
11698
|
+
const state = JSON.parse(await (0,promises_.readFile)(updateStatePath, 'utf8'));
|
|
11699
|
+
return state && typeof state === 'object' ? state : null;
|
|
11700
|
+
} catch {
|
|
11701
|
+
return null;
|
|
11702
|
+
}
|
|
11703
|
+
}
|
|
11704
|
+
|
|
11705
|
+
async function writeUpdateState(updateStatePath, state) {
|
|
11706
|
+
await (0,promises_.mkdir)((0,external_node_path_.dirname)(updateStatePath), { recursive: true });
|
|
11707
|
+
const temporaryPath = `${updateStatePath}.tmp-${process.pid}-${Date.now()}`;
|
|
11708
|
+
await (0,promises_.writeFile)(temporaryPath, `${JSON.stringify(state, null, 2)}\n`, 'utf8');
|
|
11709
|
+
await (0,promises_.rename)(temporaryPath, updateStatePath);
|
|
11710
|
+
}
|
|
11711
|
+
|
|
11712
|
+
async function runVersion(binaryPath, timeoutMs, runCommand) {
|
|
11713
|
+
if (!binaryPath || !(0,external_node_fs_.existsSync)(binaryPath)) return null;
|
|
11714
|
+
try {
|
|
11715
|
+
const { stdout, stderr } = await runCommand(binaryPath, ['--version'], {
|
|
11716
|
+
encoding: 'utf8',
|
|
11717
|
+
timeout: timeoutMs,
|
|
11718
|
+
maxBuffer: 1024 * 1024,
|
|
11719
|
+
});
|
|
11720
|
+
return parseCloudflaredVersion(`${stdout || ''}\n${stderr || ''}`);
|
|
11721
|
+
} catch {
|
|
11722
|
+
return null;
|
|
11723
|
+
}
|
|
11724
|
+
}
|
|
11725
|
+
|
|
11726
|
+
async function probeCloudflaredLaunchSpecVersion(
|
|
11727
|
+
launchSpec,
|
|
11728
|
+
{ timeoutMs = 5_000, runCommand = execFileAsync } = {},
|
|
11729
|
+
) {
|
|
11730
|
+
try {
|
|
11731
|
+
const { stdout, stderr } = await runCommand(launchSpec.command, [...launchSpec.args, '--version'], {
|
|
11732
|
+
encoding: 'utf8',
|
|
11733
|
+
timeout: timeoutMs,
|
|
11734
|
+
maxBuffer: 1024 * 1024,
|
|
11735
|
+
env: cloudflaredChildEnv(launchSpec),
|
|
11736
|
+
...(launchSpec.shell ? { shell: true } : {}),
|
|
11737
|
+
});
|
|
11738
|
+
return parseCloudflaredVersion(`${stdout || ''}\n${stderr || ''}`);
|
|
11739
|
+
} catch {
|
|
11740
|
+
return null;
|
|
11741
|
+
}
|
|
11742
|
+
}
|
|
11743
|
+
|
|
11744
|
+
async function installLatestToTemporaryPath({ launchSpec, binaryPath, timeoutMs, platform, runCommand }) {
|
|
11745
|
+
const temporaryDir = (0,external_node_path_.join)((0,external_node_path_.dirname)(binaryPath), `.cloudflared-update-${process.pid}-${Date.now()}`);
|
|
11746
|
+
const temporaryBinaryPath = (0,external_node_path_.join)(temporaryDir, (0,external_node_path_.basename)(binaryPath));
|
|
11747
|
+
await (0,promises_.mkdir)(temporaryDir, { recursive: true });
|
|
11748
|
+
try {
|
|
11749
|
+
await runCommand(launchSpec.command, [...launchSpec.args, 'bin', 'install', 'latest'], {
|
|
11750
|
+
encoding: 'utf8',
|
|
11751
|
+
timeout: timeoutMs,
|
|
11752
|
+
maxBuffer: 4 * 1024 * 1024,
|
|
11753
|
+
env: cloudflaredChildEnv(launchSpec, { ...process.env, CLOUDFLARED_BIN: temporaryBinaryPath }),
|
|
11754
|
+
...(launchSpec.shell ? { shell: true } : {}),
|
|
11755
|
+
});
|
|
11756
|
+
const version = await runVersion(temporaryBinaryPath, timeoutMs, runCommand);
|
|
11757
|
+
if (!version) throw new Error('downloaded cloudflared did not report a valid version');
|
|
11758
|
+
|
|
11759
|
+
if (platform === 'win32' && (0,external_node_fs_.existsSync)(binaryPath)) {
|
|
11760
|
+
const backupPath = `${binaryPath}.previous-${process.pid}`;
|
|
11761
|
+
await (0,promises_.rename)(binaryPath, backupPath);
|
|
11762
|
+
try {
|
|
11763
|
+
await (0,promises_.rename)(temporaryBinaryPath, binaryPath);
|
|
11764
|
+
await (0,promises_.rm)(backupPath, { force: true });
|
|
11765
|
+
} catch (error) {
|
|
11766
|
+
await (0,promises_.rename)(backupPath, binaryPath).catch(() => undefined);
|
|
11767
|
+
throw error;
|
|
11768
|
+
}
|
|
11769
|
+
} else {
|
|
11770
|
+
await (0,promises_.rename)(temporaryBinaryPath, binaryPath);
|
|
11771
|
+
}
|
|
11772
|
+
return version;
|
|
11773
|
+
} finally {
|
|
11774
|
+
await (0,promises_.rm)(temporaryDir, { recursive: true, force: true });
|
|
11775
|
+
}
|
|
11776
|
+
}
|
|
11777
|
+
|
|
11778
|
+
async function resolveManagedCloudflared({
|
|
11779
|
+
launchSpec,
|
|
11780
|
+
updateStatePath,
|
|
11781
|
+
now = Date.now(),
|
|
11782
|
+
updateIntervalMs = DEFAULT_UPDATE_INTERVAL_MS,
|
|
11783
|
+
timeoutMs = DEFAULT_UPDATE_TIMEOUT_MS,
|
|
11784
|
+
platform = process.platform,
|
|
11785
|
+
runCommand = execFileAsync,
|
|
11786
|
+
}) {
|
|
11787
|
+
const state = await readUpdateState(updateStatePath);
|
|
11788
|
+
const lastAttemptAt = Date.parse(state?.lastAttemptAt || '');
|
|
11789
|
+
const recentlyAttempted = Number.isFinite(lastAttemptAt) && now - lastAttemptAt < updateIntervalMs;
|
|
11790
|
+
if (recentlyAttempted) {
|
|
11791
|
+
return {
|
|
11792
|
+
launchSpec,
|
|
11793
|
+
version: state?.installedVersion ?? null,
|
|
11794
|
+
update: 'skipped',
|
|
11795
|
+
};
|
|
11796
|
+
}
|
|
11797
|
+
|
|
11798
|
+
const attemptedAt = new Date(now).toISOString();
|
|
11799
|
+
const binaryPath = launchSpec.managedBinaryPath;
|
|
11800
|
+
if (launchSpec.source !== 'dependency' || !binaryPath) {
|
|
11801
|
+
const version = state?.installedVersion ?? null;
|
|
11802
|
+
let stateWarning = '';
|
|
11803
|
+
try {
|
|
11804
|
+
await writeUpdateState(updateStatePath, {
|
|
11805
|
+
...state,
|
|
11806
|
+
lastAttemptAt: attemptedAt,
|
|
11807
|
+
installedVersion: version,
|
|
11808
|
+
});
|
|
11809
|
+
} catch (error) {
|
|
11810
|
+
stateWarning = ` Update state could not be saved: ${error instanceof Error ? error.message : String(error)}`;
|
|
11811
|
+
}
|
|
11812
|
+
return {
|
|
11813
|
+
launchSpec,
|
|
11814
|
+
version,
|
|
11815
|
+
update: 'skipped',
|
|
11816
|
+
warning: `Skipping cloudflared self-update for unmanaged ${launchSpec.source} executable: ${launchSpec.description}.${stateWarning}`,
|
|
11817
|
+
};
|
|
11818
|
+
}
|
|
11819
|
+
|
|
11820
|
+
const previousVersion = await runVersion(binaryPath, timeoutMs, runCommand);
|
|
11821
|
+
try {
|
|
11822
|
+
const installedVersion = await installLatestToTemporaryPath({
|
|
11823
|
+
launchSpec,
|
|
11824
|
+
binaryPath,
|
|
11825
|
+
timeoutMs,
|
|
11826
|
+
platform,
|
|
11827
|
+
runCommand,
|
|
11828
|
+
});
|
|
11829
|
+
await writeUpdateState(updateStatePath, {
|
|
11830
|
+
lastAttemptAt: attemptedAt,
|
|
11831
|
+
lastSuccessAt: attemptedAt,
|
|
11832
|
+
installedVersion,
|
|
11833
|
+
});
|
|
11834
|
+
return {
|
|
11835
|
+
launchSpec,
|
|
11836
|
+
version: installedVersion,
|
|
11837
|
+
update: previousVersion ? 'updated' : 'fresh',
|
|
11838
|
+
};
|
|
11839
|
+
} catch (error) {
|
|
11840
|
+
const fallbackVersion = previousVersion || (await runVersion(binaryPath, timeoutMs, runCommand));
|
|
11841
|
+
await writeUpdateState(updateStatePath, {
|
|
11842
|
+
...state,
|
|
11843
|
+
lastAttemptAt: attemptedAt,
|
|
11844
|
+
installedVersion: fallbackVersion,
|
|
11845
|
+
}).catch(() => undefined);
|
|
11846
|
+
return {
|
|
11847
|
+
launchSpec,
|
|
11848
|
+
version: fallbackVersion,
|
|
11849
|
+
update: 'failed',
|
|
11850
|
+
warning: `cloudflared update failed; continuing with ${fallbackVersion || 'the existing launcher'}: ${error instanceof Error ? error.message : String(error)}`,
|
|
11851
|
+
};
|
|
11852
|
+
}
|
|
11853
|
+
}
|
|
11854
|
+
|
|
11855
|
+
;// CONCATENATED MODULE: ../../packages/cloudflared-tunnel/index.mjs
|
|
11856
|
+
|
|
11857
|
+
|
|
11858
|
+
|
|
11859
|
+
|
|
11860
|
+
|
|
11861
|
+
|
|
11862
|
+
|
|
11863
|
+
|
|
11864
|
+
|
|
11812
11865
|
|
|
11813
|
-
const relativeBinPath = typeof packageJson.bin === 'string' ? packageJson.bin : packageJson.bin?.cloudflared;
|
|
11814
11866
|
|
|
11815
|
-
if (typeof relativeBinPath !== 'string' || !relativeBinPath) {
|
|
11816
|
-
return null;
|
|
11817
|
-
}
|
|
11818
11867
|
|
|
11819
|
-
|
|
11868
|
+
const QUICK_TUNNEL_URL_PATTERN = /https:\/\/[a-z0-9-]+\.trycloudflare\.com(?=$|[\s"',)\]])/g;
|
|
11820
11869
|
|
|
11821
|
-
|
|
11870
|
+
function supportsFastAutoProtocolFallback(version) {
|
|
11871
|
+
if (!version) return false;
|
|
11872
|
+
const parts = version.split('.').map(Number);
|
|
11873
|
+
const threshold = [2026, 5, 2];
|
|
11874
|
+
for (let index = 0; index < threshold.length; index += 1) {
|
|
11875
|
+
const value = parts[index] || 0;
|
|
11876
|
+
if (value !== threshold[index]) return value > threshold[index];
|
|
11877
|
+
}
|
|
11878
|
+
return true;
|
|
11822
11879
|
}
|
|
11823
11880
|
|
|
11824
|
-
function
|
|
11825
|
-
|
|
11826
|
-
|
|
11827
|
-
|
|
11828
|
-
|
|
11829
|
-
|
|
11830
|
-
|
|
11831
|
-
|
|
11832
|
-
'bin',
|
|
11833
|
-
platform === 'win32' ? 'cloudflared.exe' : 'cloudflared',
|
|
11834
|
-
),
|
|
11835
|
-
urlTimeoutMs: defaultUrlTimeoutMs,
|
|
11836
|
-
};
|
|
11881
|
+
function extractQuickTunnelUrl(logContent) {
|
|
11882
|
+
if (typeof logContent !== 'string' || logContent.length === 0) {
|
|
11883
|
+
return null;
|
|
11884
|
+
}
|
|
11885
|
+
|
|
11886
|
+
const match = QUICK_TUNNEL_URL_PATTERN.exec(logContent);
|
|
11887
|
+
QUICK_TUNNEL_URL_PATTERN.lastIndex = 0;
|
|
11888
|
+
return match?.[0] ?? null;
|
|
11837
11889
|
}
|
|
11838
11890
|
|
|
11839
|
-
function
|
|
11840
|
-
|
|
11841
|
-
|
|
11842
|
-
platform = process.platform,
|
|
11843
|
-
resolvePackageJsonPath,
|
|
11844
|
-
} = {}) {
|
|
11845
|
-
const directPathCandidates = findExecutablesInPath('cloudflared', { pathValue, pathExtValue, platform });
|
|
11846
|
-
const directPath =
|
|
11847
|
-
directPathCandidates.find((candidatePath) => !isNodeModulesBinPath(candidatePath)) ??
|
|
11848
|
-
directPathCandidates[0] ??
|
|
11849
|
-
null;
|
|
11850
|
-
if (directPath) {
|
|
11851
|
-
return {
|
|
11852
|
-
command: directPath,
|
|
11853
|
-
args: [],
|
|
11854
|
-
source: 'path',
|
|
11855
|
-
description: directPath,
|
|
11856
|
-
...(isWindowsCommandScript(directPath, platform) ? { shell: true } : {}),
|
|
11857
|
-
urlTimeoutMs: defaultUrlTimeoutMs,
|
|
11858
|
-
};
|
|
11891
|
+
function extractCloudflaredMetricsBaseUrl(logContent) {
|
|
11892
|
+
if (typeof logContent !== 'string' || logContent.length === 0) {
|
|
11893
|
+
return null;
|
|
11859
11894
|
}
|
|
11895
|
+
const match = logContent.match(
|
|
11896
|
+
/Starting metrics server on (?:https?:\/\/)?(127\.0\.0\.1|localhost|\[::1\]):(\d+)\/metrics\b/iu,
|
|
11897
|
+
);
|
|
11898
|
+
if (!match) return null;
|
|
11899
|
+
return `http://${match[1]}:${match[2]}`;
|
|
11900
|
+
}
|
|
11860
11901
|
|
|
11861
|
-
|
|
11862
|
-
|
|
11863
|
-
|
|
11864
|
-
}
|
|
11902
|
+
async function probeCloudflaredReadiness(logContent, { fetchFn = fetchTunnelHealth, timeoutMs = 1000 } = {}) {
|
|
11903
|
+
const metricsBaseUrl = extractCloudflaredMetricsBaseUrl(logContent);
|
|
11904
|
+
if (!metricsBaseUrl || typeof fetchFn !== 'function') return false;
|
|
11865
11905
|
|
|
11866
|
-
|
|
11867
|
-
|
|
11868
|
-
|
|
11869
|
-
|
|
11870
|
-
|
|
11871
|
-
|
|
11872
|
-
|
|
11873
|
-
}
|
|
11906
|
+
const controller = new AbortController();
|
|
11907
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
11908
|
+
try {
|
|
11909
|
+
const response = await fetchFn(`${metricsBaseUrl}/ready`, { signal: controller.signal });
|
|
11910
|
+
return response.ok;
|
|
11911
|
+
} catch {
|
|
11912
|
+
return false;
|
|
11913
|
+
} finally {
|
|
11914
|
+
clearTimeout(timeout);
|
|
11915
|
+
}
|
|
11874
11916
|
}
|
|
11875
11917
|
|
|
11876
|
-
function
|
|
11877
|
-
|
|
11878
|
-
|
|
11918
|
+
async function probeQuickTunnelPublicHealth(state, { fetchFn = fetchTunnelHealth, timeoutMs = 1_500 } = {}) {
|
|
11919
|
+
if (!isQuickTunnelUrl(state?.url) || typeof fetchFn !== 'function') return false;
|
|
11920
|
+
|
|
11921
|
+
const controller = new AbortController();
|
|
11922
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
11923
|
+
try {
|
|
11924
|
+
const healthUrl = new URL('/health', state.url);
|
|
11925
|
+
healthUrl.searchParams.set('_vibelet_reuse_probe', String(Date.now()));
|
|
11926
|
+
const response = await fetchFn(healthUrl, {
|
|
11927
|
+
headers: { 'cache-control': 'no-cache' },
|
|
11928
|
+
signal: controller.signal,
|
|
11929
|
+
});
|
|
11930
|
+
if (!response.ok) return false;
|
|
11931
|
+
const payload = await response.json().catch(() => null);
|
|
11932
|
+
return payload?.status === 'ok';
|
|
11933
|
+
} catch {
|
|
11934
|
+
return false;
|
|
11935
|
+
} finally {
|
|
11936
|
+
clearTimeout(timeout);
|
|
11937
|
+
}
|
|
11879
11938
|
}
|
|
11880
11939
|
|
|
11881
11940
|
function summarizeCloudflaredLog(logContent, { maxLines = 8, maxChars = 1200 } = {}) {
|
|
@@ -12187,6 +12246,7 @@ async function startTunnel({
|
|
|
12187
12246
|
[...launchSpec.args, 'tunnel', '--no-autoupdate', '--protocol', effectiveProtocol, '--url', originUrl],
|
|
12188
12247
|
{
|
|
12189
12248
|
detached: true,
|
|
12249
|
+
env: cloudflaredChildEnv(launchSpec),
|
|
12190
12250
|
stdio: ['ignore', stdoutLogFd, stderrLogFd],
|
|
12191
12251
|
windowsHide: true,
|
|
12192
12252
|
...(launchSpec.shell ? { shell: true } : {}),
|
|
@@ -12382,7 +12442,7 @@ function canUseSystemdUserManager({ spawnSyncImpl = node_child_process__WEBPACK_
|
|
|
12382
12442
|
|
|
12383
12443
|
/***/ }),
|
|
12384
12444
|
|
|
12385
|
-
/***/
|
|
12445
|
+
/***/ 5028:
|
|
12386
12446
|
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __nccwpck_require__) => {
|
|
12387
12447
|
|
|
12388
12448
|
|
|
@@ -12711,9 +12771,196 @@ var websocket_server = __nccwpck_require__(3261);
|
|
|
12711
12771
|
|
|
12712
12772
|
|
|
12713
12773
|
|
|
12714
|
-
/* harmony default export */ const wrapper = (websocket);
|
|
12774
|
+
/* harmony default export */ const wrapper = (websocket);
|
|
12775
|
+
|
|
12776
|
+
;// CONCATENATED MODULE: ./bin/terminal-screen.mjs
|
|
12777
|
+
const ANSI_CLEAR_SCREEN = '\x1b[2J\x1b[H';
|
|
12778
|
+
const ANSI_HIDE_CURSOR = '\x1b[?25l';
|
|
12779
|
+
const terminal_screen_ANSI_RESET = '\x1b[0m';
|
|
12780
|
+
const ANSI_BOLD = '\x1b[1m';
|
|
12781
|
+
const ANSI_CYAN = '\x1b[36m';
|
|
12782
|
+
const ANSI_GREEN = '\x1b[32m';
|
|
12783
|
+
const ANSI_YELLOW = '\x1b[33m';
|
|
12784
|
+
const ANSI_RED = '\x1b[31m';
|
|
12785
|
+
const ANSI_BG_BLUE = '\x1b[44m';
|
|
12786
|
+
const ANSI_WHITE = '\x1b[97m';
|
|
12787
|
+
|
|
12788
|
+
function truncateMiddle(value, maxLength) {
|
|
12789
|
+
const text = String(value ?? '');
|
|
12790
|
+
if (text.length <= maxLength) return text;
|
|
12791
|
+
if (maxLength <= 5) return text.slice(0, maxLength);
|
|
12792
|
+
const headLength = Math.ceil((maxLength - 3) / 2);
|
|
12793
|
+
const tailLength = Math.floor((maxLength - 3) / 2);
|
|
12794
|
+
return `${text.slice(0, headLength)}...${text.slice(text.length - tailLength)}`;
|
|
12795
|
+
}
|
|
12796
|
+
|
|
12797
|
+
function truncateEnd(value, maxLength) {
|
|
12798
|
+
const text = String(value ?? '');
|
|
12799
|
+
if (text.length <= maxLength) return text;
|
|
12800
|
+
if (maxLength <= 5) return text.slice(0, maxLength);
|
|
12801
|
+
return `${text.slice(0, maxLength - 3)}...`;
|
|
12802
|
+
}
|
|
12803
|
+
|
|
12804
|
+
function wrapText(text, width) {
|
|
12805
|
+
const words = String(text).split(/\s+/).filter(Boolean);
|
|
12806
|
+
if (words.length === 0) return [''];
|
|
12807
|
+
const lines = [];
|
|
12808
|
+
let current = '';
|
|
12809
|
+
for (const word of words) {
|
|
12810
|
+
if (word.length > width) {
|
|
12811
|
+
if (current) {
|
|
12812
|
+
lines.push(current);
|
|
12813
|
+
current = '';
|
|
12814
|
+
}
|
|
12815
|
+
for (let index = 0; index < word.length; index += width) {
|
|
12816
|
+
lines.push(word.slice(index, index + width));
|
|
12817
|
+
}
|
|
12818
|
+
continue;
|
|
12819
|
+
}
|
|
12820
|
+
const next = current ? `${current} ${word}` : word;
|
|
12821
|
+
if (next.length > width) {
|
|
12822
|
+
lines.push(current);
|
|
12823
|
+
current = word;
|
|
12824
|
+
} else {
|
|
12825
|
+
current = next;
|
|
12826
|
+
}
|
|
12827
|
+
}
|
|
12828
|
+
if (current) lines.push(current);
|
|
12829
|
+
return lines;
|
|
12830
|
+
}
|
|
12831
|
+
|
|
12832
|
+
function padRight(text, width) {
|
|
12833
|
+
const value = String(text);
|
|
12834
|
+
if (value.length >= width) return value.slice(0, width);
|
|
12835
|
+
return `${value}${' '.repeat(width - value.length)}`;
|
|
12836
|
+
}
|
|
12837
|
+
|
|
12838
|
+
function colorize(enabled, style, text) {
|
|
12839
|
+
if (!enabled || !style) return text;
|
|
12840
|
+
return `${style}${text}${terminal_screen_ANSI_RESET}`;
|
|
12841
|
+
}
|
|
12842
|
+
|
|
12843
|
+
function getTerminalControlScreenTone(title) {
|
|
12844
|
+
if (/\bFAILED\b|\bBLOCKED\b/i.test(title)) return 'danger';
|
|
12845
|
+
if (/\bRESTORING\b|\bSTARTING\b/i.test(title)) return 'restore';
|
|
12846
|
+
return 'takeover';
|
|
12847
|
+
}
|
|
12848
|
+
|
|
12849
|
+
function getTerminalControlScreenPalette(tone) {
|
|
12850
|
+
if (tone === 'danger') {
|
|
12851
|
+
return {
|
|
12852
|
+
title: `${ANSI_BOLD}${ANSI_RED}`,
|
|
12853
|
+
subtitle: ANSI_RED,
|
|
12854
|
+
separator: ANSI_RED,
|
|
12855
|
+
label: ANSI_YELLOW,
|
|
12856
|
+
body: '',
|
|
12857
|
+
footer: `${ANSI_BOLD}${ANSI_YELLOW}`,
|
|
12858
|
+
};
|
|
12859
|
+
}
|
|
12860
|
+
if (tone === 'restore') {
|
|
12861
|
+
return {
|
|
12862
|
+
title: `${ANSI_BOLD}${ANSI_CYAN}`,
|
|
12863
|
+
subtitle: ANSI_CYAN,
|
|
12864
|
+
separator: ANSI_CYAN,
|
|
12865
|
+
label: ANSI_CYAN,
|
|
12866
|
+
body: '',
|
|
12867
|
+
footer: `${ANSI_BOLD}${ANSI_GREEN}`,
|
|
12868
|
+
};
|
|
12869
|
+
}
|
|
12870
|
+
return {
|
|
12871
|
+
title: `${ANSI_BOLD}${ANSI_BG_BLUE}${ANSI_WHITE}`,
|
|
12872
|
+
subtitle: ANSI_GREEN,
|
|
12873
|
+
separator: ANSI_GREEN,
|
|
12874
|
+
label: ANSI_CYAN,
|
|
12875
|
+
body: '',
|
|
12876
|
+
footer: `${ANSI_BOLD}${ANSI_YELLOW}`,
|
|
12877
|
+
};
|
|
12878
|
+
}
|
|
12879
|
+
|
|
12880
|
+
function formatTerminalFieldParts(label, value, width, { truncate = 'middle' } = {}) {
|
|
12881
|
+
const prefix = `${label}: `;
|
|
12882
|
+
const maxValueLength = Math.max(8, width - prefix.length);
|
|
12883
|
+
return {
|
|
12884
|
+
label: prefix,
|
|
12885
|
+
value: truncate === 'end' ? truncateEnd(value, maxValueLength) : truncateMiddle(value, maxValueLength),
|
|
12886
|
+
};
|
|
12887
|
+
}
|
|
12888
|
+
|
|
12889
|
+
function formatTerminalControlScreen({
|
|
12890
|
+
title,
|
|
12891
|
+
subtitle,
|
|
12892
|
+
agent,
|
|
12893
|
+
cwd,
|
|
12894
|
+
sessionId,
|
|
12895
|
+
task,
|
|
12896
|
+
bodyLines = [],
|
|
12897
|
+
footerLines = [],
|
|
12898
|
+
columns = 80,
|
|
12899
|
+
rows = 24,
|
|
12900
|
+
color = false,
|
|
12901
|
+
}) {
|
|
12902
|
+
const screenWidth = Math.max(20, Number(columns) || 80);
|
|
12903
|
+
const width = screenWidth < 60 ? screenWidth : Math.min(100, screenWidth);
|
|
12904
|
+
const height = Math.max(20, Number(rows) || 24);
|
|
12905
|
+
const innerWidth = width - 8;
|
|
12906
|
+
const separator = '='.repeat(width);
|
|
12907
|
+
const tone = getTerminalControlScreenTone(title);
|
|
12908
|
+
const palette = getTerminalControlScreenPalette(tone);
|
|
12909
|
+
const fieldLines = [
|
|
12910
|
+
{ label: 'Agent', value: agent || 'unknown' },
|
|
12911
|
+
{ label: 'Session', value: sessionId || 'pending' },
|
|
12912
|
+
...(task ? [{ label: 'Task', value: task, truncate: 'end' }] : []),
|
|
12913
|
+
{ label: 'Directory', value: cwd || process.cwd() },
|
|
12914
|
+
].map(({ label, value, truncate }) => {
|
|
12915
|
+
const parts = formatTerminalFieldParts(label, value, innerWidth, { truncate });
|
|
12916
|
+
return `${colorize(color, palette.label, parts.label)}${parts.value}`;
|
|
12917
|
+
});
|
|
12918
|
+
const block = [
|
|
12919
|
+
colorize(color, palette.separator, separator),
|
|
12920
|
+
colorize(color, palette.title, padRight(title, width)),
|
|
12921
|
+
subtitle ? colorize(color, palette.subtitle, padRight(subtitle, width)) : '',
|
|
12922
|
+
colorize(color, palette.separator, separator),
|
|
12923
|
+
'',
|
|
12924
|
+
...fieldLines,
|
|
12925
|
+
'',
|
|
12926
|
+
];
|
|
12927
|
+
|
|
12928
|
+
for (const line of bodyLines) {
|
|
12929
|
+
for (const wrapped of wrapText(line, innerWidth)) {
|
|
12930
|
+
block.push(colorize(color, palette.body, padRight(wrapped, width)));
|
|
12931
|
+
}
|
|
12932
|
+
}
|
|
12933
|
+
|
|
12934
|
+
block.push('');
|
|
12935
|
+
for (const line of footerLines) {
|
|
12936
|
+
for (const wrapped of wrapText(line, innerWidth)) {
|
|
12937
|
+
block.push(colorize(color, palette.footer, padRight(wrapped, width)));
|
|
12938
|
+
}
|
|
12939
|
+
}
|
|
12940
|
+
block.push(colorize(color, palette.separator, separator));
|
|
12941
|
+
|
|
12942
|
+
const verticalPadding = Math.max(0, Math.floor((height - block.length) / 3));
|
|
12943
|
+
return `${'\n'.repeat(verticalPadding)}${block.join('\n')}\n`;
|
|
12944
|
+
}
|
|
12945
|
+
|
|
12946
|
+
function normalizeTerminalScreenForTty(screen) {
|
|
12947
|
+
return `\r${String(screen).replace(/\r?\n/g, '\r\n')}`;
|
|
12948
|
+
}
|
|
12949
|
+
|
|
12950
|
+
function renderTerminalControlScreen(stream, options) {
|
|
12951
|
+
const columns = Number(stream?.columns) || 80;
|
|
12952
|
+
const rows = Number(stream?.rows) || 24;
|
|
12953
|
+
const screen = formatTerminalControlScreen({ ...options, columns, rows, color: Boolean(stream?.isTTY) });
|
|
12954
|
+
if (stream?.isTTY) {
|
|
12955
|
+
stream.write(`${ANSI_CLEAR_SCREEN}${ANSI_HIDE_CURSOR}${normalizeTerminalScreenForTty(screen)}`);
|
|
12956
|
+
return;
|
|
12957
|
+
}
|
|
12958
|
+
stream.write(`\n${screen}`);
|
|
12959
|
+
}
|
|
12960
|
+
|
|
12961
|
+
;// CONCATENATED MODULE: ./bin/terminal-wrapper.mjs
|
|
12962
|
+
|
|
12715
12963
|
|
|
12716
|
-
;// CONCATENATED MODULE: ./bin/terminal-wrapper.mjs
|
|
12717
12964
|
|
|
12718
12965
|
|
|
12719
12966
|
|
|
@@ -12736,21 +12983,25 @@ const SWITCHBACK_RESTORE_NOTICE_MS = 1200;
|
|
|
12736
12983
|
const SWITCHBACK_BUSY_RETRY_DELAY_MS = 750;
|
|
12737
12984
|
const TERMINAL_CONTROL_RECONNECT_DELAY_MS = 1000;
|
|
12738
12985
|
const CLAUDE_HOOK_SECRET_HEADER = 'x-vibelet-claude-hook-secret';
|
|
12739
|
-
const ANSI_CLEAR_SCREEN = '\x1b[2J\x1b[H';
|
|
12740
|
-
const ANSI_HIDE_CURSOR = '\x1b[?25l';
|
|
12741
|
-
const terminal_wrapper_ANSI_RESET = '\x1b[0m';
|
|
12742
|
-
const ANSI_BOLD = '\x1b[1m';
|
|
12743
|
-
const ANSI_CYAN = '\x1b[36m';
|
|
12744
|
-
const ANSI_GREEN = '\x1b[32m';
|
|
12745
|
-
const ANSI_YELLOW = '\x1b[33m';
|
|
12746
|
-
const ANSI_RED = '\x1b[31m';
|
|
12747
|
-
const ANSI_BG_BLUE = '\x1b[44m';
|
|
12748
|
-
const ANSI_WHITE = '\x1b[97m';
|
|
12749
|
-
|
|
12750
12986
|
function isTerminalAgentCommand(command) {
|
|
12751
12987
|
return command === 'claude' || command === 'codex';
|
|
12752
12988
|
}
|
|
12753
12989
|
|
|
12990
|
+
async function waitForTakeoverResponseSent(control, timeoutMs = 5000) {
|
|
12991
|
+
if (!control) return false;
|
|
12992
|
+
let timer;
|
|
12993
|
+
try {
|
|
12994
|
+
return await Promise.race([
|
|
12995
|
+
control.takeoverResponseSent,
|
|
12996
|
+
new Promise((resolve) => {
|
|
12997
|
+
timer = setTimeout(() => resolve(false), timeoutMs);
|
|
12998
|
+
}),
|
|
12999
|
+
]);
|
|
13000
|
+
} finally {
|
|
13001
|
+
clearTimeout(timer);
|
|
13002
|
+
}
|
|
13003
|
+
}
|
|
13004
|
+
|
|
12754
13005
|
function resolveNativeAgentCommand(agent, env = process.env) {
|
|
12755
13006
|
if (agent === 'claude') return env.CLAUDE_PATH || 'claude';
|
|
12756
13007
|
if (agent === 'codex') return env.CODEX_PATH || 'codex';
|
|
@@ -13103,179 +13354,6 @@ function createTerminalModeState(initialMode = 'localNative') {
|
|
|
13103
13354
|
};
|
|
13104
13355
|
}
|
|
13105
13356
|
|
|
13106
|
-
function truncateMiddle(value, maxLength) {
|
|
13107
|
-
const text = String(value ?? '');
|
|
13108
|
-
if (text.length <= maxLength) return text;
|
|
13109
|
-
if (maxLength <= 5) return text.slice(0, maxLength);
|
|
13110
|
-
const headLength = Math.ceil((maxLength - 3) / 2);
|
|
13111
|
-
const tailLength = Math.floor((maxLength - 3) / 2);
|
|
13112
|
-
return `${text.slice(0, headLength)}...${text.slice(text.length - tailLength)}`;
|
|
13113
|
-
}
|
|
13114
|
-
|
|
13115
|
-
function truncateEnd(value, maxLength) {
|
|
13116
|
-
const text = String(value ?? '');
|
|
13117
|
-
if (text.length <= maxLength) return text;
|
|
13118
|
-
if (maxLength <= 5) return text.slice(0, maxLength);
|
|
13119
|
-
return `${text.slice(0, maxLength - 3)}...`;
|
|
13120
|
-
}
|
|
13121
|
-
|
|
13122
|
-
function wrapText(text, width) {
|
|
13123
|
-
const words = String(text).split(/\s+/).filter(Boolean);
|
|
13124
|
-
if (words.length === 0) return [''];
|
|
13125
|
-
const lines = [];
|
|
13126
|
-
let current = '';
|
|
13127
|
-
for (const word of words) {
|
|
13128
|
-
if (word.length > width) {
|
|
13129
|
-
if (current) {
|
|
13130
|
-
lines.push(current);
|
|
13131
|
-
current = '';
|
|
13132
|
-
}
|
|
13133
|
-
for (let index = 0; index < word.length; index += width) {
|
|
13134
|
-
lines.push(word.slice(index, index + width));
|
|
13135
|
-
}
|
|
13136
|
-
continue;
|
|
13137
|
-
}
|
|
13138
|
-
const next = current ? `${current} ${word}` : word;
|
|
13139
|
-
if (next.length > width) {
|
|
13140
|
-
lines.push(current);
|
|
13141
|
-
current = word;
|
|
13142
|
-
} else {
|
|
13143
|
-
current = next;
|
|
13144
|
-
}
|
|
13145
|
-
}
|
|
13146
|
-
if (current) lines.push(current);
|
|
13147
|
-
return lines;
|
|
13148
|
-
}
|
|
13149
|
-
|
|
13150
|
-
function padRight(text, width) {
|
|
13151
|
-
const value = String(text);
|
|
13152
|
-
if (value.length >= width) return value.slice(0, width);
|
|
13153
|
-
return `${value}${' '.repeat(width - value.length)}`;
|
|
13154
|
-
}
|
|
13155
|
-
|
|
13156
|
-
function colorize(enabled, style, text) {
|
|
13157
|
-
if (!enabled || !style) return text;
|
|
13158
|
-
return `${style}${text}${terminal_wrapper_ANSI_RESET}`;
|
|
13159
|
-
}
|
|
13160
|
-
|
|
13161
|
-
function getTerminalControlScreenTone(title) {
|
|
13162
|
-
if (/\bFAILED\b|\bBLOCKED\b/i.test(title)) return 'danger';
|
|
13163
|
-
if (/\bRESTORING\b|\bSTARTING\b/i.test(title)) return 'restore';
|
|
13164
|
-
return 'takeover';
|
|
13165
|
-
}
|
|
13166
|
-
|
|
13167
|
-
function getTerminalControlScreenPalette(tone) {
|
|
13168
|
-
if (tone === 'danger') {
|
|
13169
|
-
return {
|
|
13170
|
-
title: `${ANSI_BOLD}${ANSI_RED}`,
|
|
13171
|
-
subtitle: ANSI_RED,
|
|
13172
|
-
separator: ANSI_RED,
|
|
13173
|
-
label: ANSI_YELLOW,
|
|
13174
|
-
body: '',
|
|
13175
|
-
footer: `${ANSI_BOLD}${ANSI_YELLOW}`,
|
|
13176
|
-
};
|
|
13177
|
-
}
|
|
13178
|
-
if (tone === 'restore') {
|
|
13179
|
-
return {
|
|
13180
|
-
title: `${ANSI_BOLD}${ANSI_CYAN}`,
|
|
13181
|
-
subtitle: ANSI_CYAN,
|
|
13182
|
-
separator: ANSI_CYAN,
|
|
13183
|
-
label: ANSI_CYAN,
|
|
13184
|
-
body: '',
|
|
13185
|
-
footer: `${ANSI_BOLD}${ANSI_GREEN}`,
|
|
13186
|
-
};
|
|
13187
|
-
}
|
|
13188
|
-
return {
|
|
13189
|
-
title: `${ANSI_BOLD}${ANSI_BG_BLUE}${ANSI_WHITE}`,
|
|
13190
|
-
subtitle: ANSI_GREEN,
|
|
13191
|
-
separator: ANSI_GREEN,
|
|
13192
|
-
label: ANSI_CYAN,
|
|
13193
|
-
body: '',
|
|
13194
|
-
footer: `${ANSI_BOLD}${ANSI_YELLOW}`,
|
|
13195
|
-
};
|
|
13196
|
-
}
|
|
13197
|
-
|
|
13198
|
-
function formatTerminalFieldParts(label, value, width, { truncate = 'middle' } = {}) {
|
|
13199
|
-
const prefix = `${label}: `;
|
|
13200
|
-
const maxValueLength = Math.max(8, width - prefix.length);
|
|
13201
|
-
return {
|
|
13202
|
-
label: prefix,
|
|
13203
|
-
value: truncate === 'end' ? truncateEnd(value, maxValueLength) : truncateMiddle(value, maxValueLength),
|
|
13204
|
-
};
|
|
13205
|
-
}
|
|
13206
|
-
|
|
13207
|
-
function formatTerminalControlScreen({
|
|
13208
|
-
title,
|
|
13209
|
-
subtitle,
|
|
13210
|
-
agent,
|
|
13211
|
-
cwd,
|
|
13212
|
-
sessionId,
|
|
13213
|
-
task,
|
|
13214
|
-
bodyLines = [],
|
|
13215
|
-
footerLines = [],
|
|
13216
|
-
columns = 80,
|
|
13217
|
-
rows = 24,
|
|
13218
|
-
color = false,
|
|
13219
|
-
}) {
|
|
13220
|
-
const screenWidth = Math.max(20, Number(columns) || 80);
|
|
13221
|
-
const width = screenWidth < 60 ? screenWidth : Math.min(100, screenWidth);
|
|
13222
|
-
const height = Math.max(20, Number(rows) || 24);
|
|
13223
|
-
const innerWidth = width - 8;
|
|
13224
|
-
const separator = '='.repeat(width);
|
|
13225
|
-
const tone = getTerminalControlScreenTone(title);
|
|
13226
|
-
const palette = getTerminalControlScreenPalette(tone);
|
|
13227
|
-
const fieldLines = [
|
|
13228
|
-
{ label: 'Agent', value: agent || 'unknown' },
|
|
13229
|
-
{ label: 'Session', value: sessionId || 'pending' },
|
|
13230
|
-
...(task ? [{ label: 'Task', value: task, truncate: 'end' }] : []),
|
|
13231
|
-
{ label: 'Directory', value: cwd || process.cwd() },
|
|
13232
|
-
].map(({ label, value, truncate }) => {
|
|
13233
|
-
const parts = formatTerminalFieldParts(label, value, innerWidth, { truncate });
|
|
13234
|
-
return `${colorize(color, palette.label, parts.label)}${parts.value}`;
|
|
13235
|
-
});
|
|
13236
|
-
const block = [
|
|
13237
|
-
colorize(color, palette.separator, separator),
|
|
13238
|
-
colorize(color, palette.title, padRight(title, width)),
|
|
13239
|
-
subtitle ? colorize(color, palette.subtitle, padRight(subtitle, width)) : '',
|
|
13240
|
-
colorize(color, palette.separator, separator),
|
|
13241
|
-
'',
|
|
13242
|
-
...fieldLines,
|
|
13243
|
-
'',
|
|
13244
|
-
];
|
|
13245
|
-
|
|
13246
|
-
for (const line of bodyLines) {
|
|
13247
|
-
for (const wrapped of wrapText(line, innerWidth)) {
|
|
13248
|
-
block.push(colorize(color, palette.body, padRight(wrapped, width)));
|
|
13249
|
-
}
|
|
13250
|
-
}
|
|
13251
|
-
|
|
13252
|
-
block.push('');
|
|
13253
|
-
for (const line of footerLines) {
|
|
13254
|
-
for (const wrapped of wrapText(line, innerWidth)) {
|
|
13255
|
-
block.push(colorize(color, palette.footer, padRight(wrapped, width)));
|
|
13256
|
-
}
|
|
13257
|
-
}
|
|
13258
|
-
block.push(colorize(color, palette.separator, separator));
|
|
13259
|
-
|
|
13260
|
-
const verticalPadding = Math.max(0, Math.floor((height - block.length) / 3));
|
|
13261
|
-
return `${'\n'.repeat(verticalPadding)}${block.join('\n')}\n`;
|
|
13262
|
-
}
|
|
13263
|
-
|
|
13264
|
-
function normalizeTerminalScreenForTty(screen) {
|
|
13265
|
-
return `\r${String(screen).replace(/\r?\n/g, '\r\n')}`;
|
|
13266
|
-
}
|
|
13267
|
-
|
|
13268
|
-
function renderTerminalControlScreen(stream, options) {
|
|
13269
|
-
const columns = Number(stream?.columns) || 80;
|
|
13270
|
-
const rows = Number(stream?.rows) || 24;
|
|
13271
|
-
const screen = formatTerminalControlScreen({ ...options, columns, rows, color: Boolean(stream?.isTTY) });
|
|
13272
|
-
if (stream?.isTTY) {
|
|
13273
|
-
stream.write(`${ANSI_CLEAR_SCREEN}${ANSI_HIDE_CURSOR}${normalizeTerminalScreenForTty(screen)}`);
|
|
13274
|
-
return;
|
|
13275
|
-
}
|
|
13276
|
-
stream.write(`\n${screen}`);
|
|
13277
|
-
}
|
|
13278
|
-
|
|
13279
13357
|
async function waitForRetryOrSignal(signalExit, delayMs) {
|
|
13280
13358
|
let timer;
|
|
13281
13359
|
const retry = new Promise((resolve) => {
|
|
@@ -13401,6 +13479,10 @@ async function connectTerminalControl({
|
|
|
13401
13479
|
let heartbeatTimer = null;
|
|
13402
13480
|
let resolveClosed;
|
|
13403
13481
|
let closedResolved = false;
|
|
13482
|
+
let resolveTakeoverResponseSent;
|
|
13483
|
+
const takeoverResponseSent = new Promise((resolve) => {
|
|
13484
|
+
resolveTakeoverResponseSent = resolve;
|
|
13485
|
+
});
|
|
13404
13486
|
const closed = new Promise((resolve) => {
|
|
13405
13487
|
resolveClosed = resolve;
|
|
13406
13488
|
});
|
|
@@ -13411,6 +13493,7 @@ async function connectTerminalControl({
|
|
|
13411
13493
|
heartbeatTimer = null;
|
|
13412
13494
|
}
|
|
13413
13495
|
requester.rejectAll('terminal_control_closed');
|
|
13496
|
+
resolveTakeoverResponseSent(false);
|
|
13414
13497
|
if (closedResolved) return;
|
|
13415
13498
|
closedResolved = true;
|
|
13416
13499
|
resolveClosed({
|
|
@@ -13431,7 +13514,7 @@ async function connectTerminalControl({
|
|
|
13431
13514
|
});
|
|
13432
13515
|
}
|
|
13433
13516
|
|
|
13434
|
-
function sendResponse(id, ok, data, error) {
|
|
13517
|
+
function sendResponse(id, ok, data, error, onSent) {
|
|
13435
13518
|
ws.send(
|
|
13436
13519
|
JSON.stringify({
|
|
13437
13520
|
type: 'response',
|
|
@@ -13440,6 +13523,7 @@ async function connectTerminalControl({
|
|
|
13440
13523
|
...(data === undefined ? {} : { data }),
|
|
13441
13524
|
...(error ? { error } : {}),
|
|
13442
13525
|
}),
|
|
13526
|
+
onSent,
|
|
13443
13527
|
);
|
|
13444
13528
|
}
|
|
13445
13529
|
|
|
@@ -13467,21 +13551,28 @@ async function connectTerminalControl({
|
|
|
13467
13551
|
restoreTerminalAfterNativeTui(stderr, process.stdin, terminalLineDiscipline);
|
|
13468
13552
|
setMode('remoteDaemon');
|
|
13469
13553
|
await sendSession('remoteDaemon');
|
|
13470
|
-
|
|
13471
|
-
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
|
|
13476
|
-
|
|
13477
|
-
|
|
13478
|
-
|
|
13479
|
-
|
|
13480
|
-
|
|
13481
|
-
|
|
13482
|
-
|
|
13554
|
+
if (agent !== 'codex') {
|
|
13555
|
+
renderTerminalControlScreen(stderr, {
|
|
13556
|
+
title: 'VIBELET APP CONTROL',
|
|
13557
|
+
subtitle: 'Remote takeover is active',
|
|
13558
|
+
agent,
|
|
13559
|
+
cwd,
|
|
13560
|
+
sessionId: currentSessionId,
|
|
13561
|
+
task: currentTaskPreview,
|
|
13562
|
+
bodyLines: [
|
|
13563
|
+
'The Vibelet app is now controlling this session.',
|
|
13564
|
+
'The native terminal UI is paused so messages and tool output stay in the app.',
|
|
13565
|
+
'Leave this terminal open while you work from the app.',
|
|
13566
|
+
],
|
|
13567
|
+
footerLines: [
|
|
13568
|
+
'Press any key to restore the native terminal UI.',
|
|
13569
|
+
'Press Ctrl-C to close this terminal monitor.',
|
|
13570
|
+
],
|
|
13571
|
+
});
|
|
13572
|
+
}
|
|
13573
|
+
sendResponse(msg.id, true, { mode: 'remoteDaemon' }, undefined, (error) => {
|
|
13574
|
+
resolveTakeoverResponseSent(!error);
|
|
13483
13575
|
});
|
|
13484
|
-
sendResponse(msg.id, true, { mode: 'remoteDaemon' });
|
|
13485
13576
|
});
|
|
13486
13577
|
|
|
13487
13578
|
ws.on('close', (code, reason) => {
|
|
@@ -13522,6 +13613,7 @@ async function connectTerminalControl({
|
|
|
13522
13613
|
|
|
13523
13614
|
return {
|
|
13524
13615
|
closed,
|
|
13616
|
+
takeoverResponseSent,
|
|
13525
13617
|
getTerminalId() {
|
|
13526
13618
|
return terminalId;
|
|
13527
13619
|
},
|
|
@@ -13617,9 +13709,10 @@ async function runManagedNativeTerminal({
|
|
|
13617
13709
|
cwd = process.cwd(),
|
|
13618
13710
|
env = process.env,
|
|
13619
13711
|
stderr = process.stderr,
|
|
13712
|
+
controlToken,
|
|
13620
13713
|
}) {
|
|
13621
13714
|
const command = resolveNativeAgentCommand(agent, env);
|
|
13622
|
-
const token = readTerminalControlToken();
|
|
13715
|
+
const token = controlToken ?? readTerminalControlToken();
|
|
13623
13716
|
const terminalLineDiscipline = captureTerminalLineDiscipline();
|
|
13624
13717
|
let initialSessionId = extractInitialSessionId(agent, args);
|
|
13625
13718
|
let nativeArgs = args;
|
|
@@ -13736,6 +13829,15 @@ async function runManagedNativeTerminal({
|
|
|
13736
13829
|
if (modeState.getMode() !== 'remoteDaemon') {
|
|
13737
13830
|
return exitCodeFromChildExit(exit);
|
|
13738
13831
|
}
|
|
13832
|
+
if (agent === 'codex') {
|
|
13833
|
+
const acknowledged = await waitForTakeoverResponseSent(control);
|
|
13834
|
+
stderr.write(
|
|
13835
|
+
acknowledged
|
|
13836
|
+
? 'Codex session moved to Vibelet. This terminal session is closed.\n'
|
|
13837
|
+
: 'Codex terminal stopped, but Vibelet takeover was not acknowledged.\n',
|
|
13838
|
+
);
|
|
13839
|
+
return acknowledged ? 0 : 1;
|
|
13840
|
+
}
|
|
13739
13841
|
|
|
13740
13842
|
const monitorAction = await waitForRemoteMonitorInput(signalHandlers.signalExit);
|
|
13741
13843
|
if (monitorAction.type === 'exit') {
|
|
@@ -14040,7 +14142,7 @@ function parseAccessTargetArg(argv, fail, env = process.env) {
|
|
|
14040
14142
|
/* harmony export */ });
|
|
14041
14143
|
/* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(3024);
|
|
14042
14144
|
/* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_1__ = __nccwpck_require__(6760);
|
|
14043
|
-
/* harmony import */ var _cloudflared_tunnel_manager_mjs__WEBPACK_IMPORTED_MODULE_2__ = __nccwpck_require__(
|
|
14145
|
+
/* harmony import */ var _cloudflared_tunnel_manager_mjs__WEBPACK_IMPORTED_MODULE_2__ = __nccwpck_require__(1484);
|
|
14044
14146
|
|
|
14045
14147
|
|
|
14046
14148
|
|
|
@@ -15975,7 +16077,7 @@ __nccwpck_require__.a(__webpack_module__, async (__webpack_handle_async_dependen
|
|
|
15975
16077
|
/* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_4__ = __nccwpck_require__(6760);
|
|
15976
16078
|
/* harmony import */ var node_url__WEBPACK_IMPORTED_MODULE_5__ = __nccwpck_require__(3136);
|
|
15977
16079
|
/* harmony import */ var _vibelet_cli_args_mjs__WEBPACK_IMPORTED_MODULE_17__ = __nccwpck_require__(6927);
|
|
15978
|
-
/* harmony import */ var _cloudflared_tunnel_manager_mjs__WEBPACK_IMPORTED_MODULE_6__ = __nccwpck_require__(
|
|
16080
|
+
/* harmony import */ var _cloudflared_tunnel_manager_mjs__WEBPACK_IMPORTED_MODULE_6__ = __nccwpck_require__(1484);
|
|
15979
16081
|
/* harmony import */ var _vibelet_cloudflare_runtime_mjs__WEBPACK_IMPORTED_MODULE_7__ = __nccwpck_require__(3869);
|
|
15980
16082
|
/* harmony import */ var _vibelet_launchd_mjs__WEBPACK_IMPORTED_MODULE_13__ = __nccwpck_require__(1010);
|
|
15981
16083
|
/* harmony import */ var _linux_systemd_mjs__WEBPACK_IMPORTED_MODULE_8__ = __nccwpck_require__(4217);
|
|
@@ -15983,7 +16085,7 @@ __nccwpck_require__.a(__webpack_module__, async (__webpack_handle_async_dependen
|
|
|
15983
16085
|
/* harmony import */ var _vibelet_help_mjs__WEBPACK_IMPORTED_MODULE_16__ = __nccwpck_require__(4162);
|
|
15984
16086
|
/* harmony import */ var _vibelet_tailcat_config_mjs__WEBPACK_IMPORTED_MODULE_9__ = __nccwpck_require__(5798);
|
|
15985
16087
|
/* harmony import */ var _vibelet_runtime_policy_mjs__WEBPACK_IMPORTED_MODULE_12__ = __nccwpck_require__(4);
|
|
15986
|
-
/* harmony import */ var _terminal_wrapper_mjs__WEBPACK_IMPORTED_MODULE_10__ = __nccwpck_require__(
|
|
16088
|
+
/* harmony import */ var _terminal_wrapper_mjs__WEBPACK_IMPORTED_MODULE_10__ = __nccwpck_require__(5028);
|
|
15987
16089
|
/* harmony import */ var _vibelet_pairing_connections_mjs__WEBPACK_IMPORTED_MODULE_15__ = __nccwpck_require__(7721);
|
|
15988
16090
|
/* harmony import */ var _vibelet_pairing_output_mjs__WEBPACK_IMPORTED_MODULE_11__ = __nccwpck_require__(9485);
|
|
15989
16091
|
|