checkpoint-cli 0.3.9 → 0.4.1
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.js +42 -13
- package/dist/tracking-script-minimal.js +14 -24
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -282,6 +282,35 @@ async function registerTunnel(sb, opts) {
|
|
|
282
282
|
return null;
|
|
283
283
|
}
|
|
284
284
|
const APP_URL = (0, config_js_1.getAppUrl)();
|
|
285
|
+
const userId = userData.user.id;
|
|
286
|
+
// Try to find an existing tunnel with the same name for this user
|
|
287
|
+
const { data: existing } = await sb
|
|
288
|
+
.from('tunnels')
|
|
289
|
+
.select('id, share_id')
|
|
290
|
+
.eq('user_id', userId)
|
|
291
|
+
.eq('name', opts.name)
|
|
292
|
+
.order('created_at', { ascending: false })
|
|
293
|
+
.limit(1)
|
|
294
|
+
.single();
|
|
295
|
+
if (existing) {
|
|
296
|
+
// Reconnect: reuse the same share_id, update the tunnel URL
|
|
297
|
+
const { error } = await sb
|
|
298
|
+
.from('tunnels')
|
|
299
|
+
.update({
|
|
300
|
+
tunnel_url: opts.tunnelUrl,
|
|
301
|
+
local_port: opts.port,
|
|
302
|
+
status: 'active',
|
|
303
|
+
last_seen_at: new Date().toISOString(),
|
|
304
|
+
})
|
|
305
|
+
.eq('id', existing.id);
|
|
306
|
+
if (error) {
|
|
307
|
+
console.log(chalk_1.default.yellow(` ⚠ Could not reconnect: ${error.message}`));
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
310
|
+
console.log(chalk_1.default.green(' ✓ Reconnected to existing tunnel') + chalk_1.default.gray(` (${opts.name})`));
|
|
311
|
+
return { shareUrl: `${APP_URL}/share/${existing.share_id}`, tunnelId: existing.id };
|
|
312
|
+
}
|
|
313
|
+
// No existing tunnel — create a new one
|
|
285
314
|
const shareId = generateShareId();
|
|
286
315
|
const { data, error } = await sb.from('tunnels').insert({
|
|
287
316
|
name: opts.name,
|
|
@@ -289,7 +318,7 @@ async function registerTunnel(sb, opts) {
|
|
|
289
318
|
tunnel_url: opts.tunnelUrl,
|
|
290
319
|
share_id: shareId,
|
|
291
320
|
status: 'active',
|
|
292
|
-
user_id:
|
|
321
|
+
user_id: userId,
|
|
293
322
|
last_seen_at: new Date().toISOString(),
|
|
294
323
|
}).select('id').single();
|
|
295
324
|
if (error || !data) {
|
|
@@ -417,12 +446,12 @@ function loginWithBrowser() {
|
|
|
417
446
|
const program = new commander_1.Command();
|
|
418
447
|
program
|
|
419
448
|
.name('checkpoint')
|
|
420
|
-
.description('Share your localhost with reviewers — get visual feedback directly on the page')
|
|
421
|
-
.version('0.
|
|
449
|
+
.description('Share your localhost with reviewers — get visual feedback directly on the page.\n\nQuick start:\n 1. checkpoint login Sign in to your Checkpoint account\n 2. checkpoint start -p 3000 Start tunneling and get a share link\n\nReuse a tunnel name to keep the same share URL and preserve all comments.')
|
|
450
|
+
.version('0.4.1');
|
|
422
451
|
// ── checkpoint login ──
|
|
423
452
|
program
|
|
424
453
|
.command('login')
|
|
425
|
-
.description('
|
|
454
|
+
.description('Sign in to your Checkpoint account. Opens the browser for authentication.')
|
|
426
455
|
.action(async () => {
|
|
427
456
|
console.log('');
|
|
428
457
|
console.log(chalk_1.default.blue.bold(' ⟐ Checkpoint'));
|
|
@@ -468,7 +497,7 @@ program
|
|
|
468
497
|
// ── checkpoint logout ──
|
|
469
498
|
program
|
|
470
499
|
.command('logout')
|
|
471
|
-
.description('Sign out and
|
|
500
|
+
.description('Sign out and clear saved credentials from this machine.')
|
|
472
501
|
.action(() => {
|
|
473
502
|
console.log('');
|
|
474
503
|
console.log(chalk_1.default.blue.bold(' ⟐ Checkpoint'));
|
|
@@ -480,9 +509,9 @@ program
|
|
|
480
509
|
// ── checkpoint start ──
|
|
481
510
|
program
|
|
482
511
|
.command('start')
|
|
483
|
-
.description('
|
|
484
|
-
.requiredOption('-p, --port <port>', 'Local port
|
|
485
|
-
.option('-n, --name <name>', '
|
|
512
|
+
.description('Start tunneling a local port and get a shareable link for reviewers.\nIf a tunnel with the same name already exists, it reconnects to it —\nkeeping the same share URL and all previous comments intact.')
|
|
513
|
+
.requiredOption('-p, --port <port>', 'Local port your dev server is running on (e.g. 3000, 5173)', '3000')
|
|
514
|
+
.option('-n, --name <name>', 'Tunnel name. Reuse a name to resume the same share URL.')
|
|
486
515
|
.option('--provider <provider>', 'Tunnel provider: cloudflared (default) or ngrok')
|
|
487
516
|
.action(async (opts) => {
|
|
488
517
|
requireAuth();
|
|
@@ -582,10 +611,10 @@ program
|
|
|
582
611
|
// ── checkpoint share ──
|
|
583
612
|
program
|
|
584
613
|
.command('share')
|
|
585
|
-
.description('Register an existing tunnel URL with Checkpoint')
|
|
586
|
-
.requiredOption('-u, --url <url>', '
|
|
614
|
+
.description('Register an existing tunnel URL (e.g. from ngrok) with Checkpoint.\nUse this if you already have a tunnel running and just need a share link.')
|
|
615
|
+
.requiredOption('-u, --url <url>', 'The public tunnel URL to register (https://...)')
|
|
587
616
|
.option('-n, --name <name>', 'Name for this tunnel', 'My Tunnel')
|
|
588
|
-
.option('-p, --port <port>', 'Local port
|
|
617
|
+
.option('-p, --port <port>', 'Local port for reference', '3000')
|
|
589
618
|
.action(async (opts) => {
|
|
590
619
|
requireAuth();
|
|
591
620
|
console.log('');
|
|
@@ -644,7 +673,7 @@ program
|
|
|
644
673
|
// ── checkpoint status ──
|
|
645
674
|
program
|
|
646
675
|
.command('status')
|
|
647
|
-
.description('
|
|
676
|
+
.description('Show login status and which tunnel providers are installed.')
|
|
648
677
|
.action(async () => {
|
|
649
678
|
console.log('');
|
|
650
679
|
console.log(chalk_1.default.blue.bold(' ⟐ Checkpoint — Status'));
|
|
@@ -682,7 +711,7 @@ program
|
|
|
682
711
|
// ── checkpoint whoami ──
|
|
683
712
|
program
|
|
684
713
|
.command('whoami')
|
|
685
|
-
.description('
|
|
714
|
+
.description('Print the email of the currently logged-in user.')
|
|
686
715
|
.action(async () => {
|
|
687
716
|
const config = (0, config_js_1.loadConfig)();
|
|
688
717
|
if (!config) {
|
|
@@ -451,29 +451,19 @@ function buildMinimalTrackingScript() {
|
|
|
451
451
|
return { coordFallback:null, strategy:'none', matchedSelector:null, status:'none' };
|
|
452
452
|
}
|
|
453
453
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
var source='(no source)';
|
|
468
|
-
if(anchor){
|
|
469
|
-
var file=anchor.source_file?String(anchor.source_file).split(/[\\/]/).pop():'';
|
|
470
|
-
if(file&&typeof anchor.source_line==='number') source=file+':'+anchor.source_line;
|
|
471
|
-
else if(file) source=file;
|
|
472
|
-
else if(anchor.component_name) source=anchor.component_name;
|
|
473
|
-
if(anchor.explicit_id) source=source+' · #'+anchor.explicit_id;
|
|
474
|
-
}
|
|
475
|
-
return selector+'\n'+source;
|
|
476
|
-
}
|
|
454
|
+
function getInspectLabelText(target){
|
|
455
|
+
if(!target||!target.tagName) return '';
|
|
456
|
+
var tag=String(target.tagName).toLowerCase();
|
|
457
|
+
var id=target.id?('#'+target.id):'';
|
|
458
|
+
var cls='';
|
|
459
|
+
try{
|
|
460
|
+
var classes=(target.className&&typeof target.className==='string')
|
|
461
|
+
? target.className.trim().split(/\s+/).filter(Boolean).slice(0,3)
|
|
462
|
+
: [];
|
|
463
|
+
if(classes.length>0) cls='.'+classes.join('.');
|
|
464
|
+
}catch(e){}
|
|
465
|
+
return shortText(tag+id+cls);
|
|
466
|
+
}
|
|
477
467
|
|
|
478
468
|
function ensureInspectUi(){
|
|
479
469
|
if(!document.body) return;
|
|
@@ -505,7 +495,7 @@ inspectBox.style.border='2px solid #F26522';
|
|
|
505
495
|
inspectLabel.style.background='rgba(15,23,42,0.96)';
|
|
506
496
|
inspectLabel.style.color='#e2e8f0';
|
|
507
497
|
inspectLabel.style.font='12px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace';
|
|
508
|
-
inspectLabel.style.whiteSpace='
|
|
498
|
+
inspectLabel.style.whiteSpace='nowrap';
|
|
509
499
|
inspectLabel.style.wordBreak='break-word';
|
|
510
500
|
inspectLabel.style.pointerEvents='none';
|
|
511
501
|
inspectLabel.style.zIndex='2147483647';
|