@pingagent/sdk 0.1.15 → 0.1.17

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/bin/pingagent.js CHANGED
@@ -26,6 +26,7 @@ import {
26
26
  TrustPolicyAuditManager,
27
27
  CollaborationEventManager,
28
28
  CollaborationProjectionOutboxManager,
29
+ NotificationIntentManager,
29
30
  OperatorSeenStateManager,
30
31
  TrustRecommendationManager,
31
32
  getTrustRecommendationActionLabel,
@@ -37,6 +38,9 @@ import {
37
38
  buildDeliveryTimeline,
38
39
  buildProjectionPreview,
39
40
  listPendingDecisionViews,
41
+ summarizeHumanDelivery,
42
+ listRecentBindingsForSession,
43
+ deriveOpenClawAgentState,
40
44
  deriveTransportHealth,
41
45
  readTransportPreference,
42
46
  switchTransportPreference,
@@ -205,15 +209,16 @@ function getHostPanelSurfaceUrl() {
205
209
 
206
210
  function getSurfaceRecommendationLines(primaryCommandPrefix = 'npx @pingagent/sdk', secondaryCommandPrefix = 'pingagent') {
207
211
  return [
208
- 'With GUI: Host Panel',
212
+ 'GUI repair / approvals / audit: Host Panel',
209
213
  ` Start locally: ${primaryCommandPrefix} web`,
210
214
  ...(secondaryCommandPrefix && secondaryCommandPrefix !== primaryCommandPrefix ? [` Or via local bin: ${secondaryCommandPrefix} web`] : []),
211
215
  ` URL when running: ${getHostPanelSurfaceUrl()}`,
212
- 'Headless / low-token: TUI',
216
+ 'Headless repair surface: TUI',
213
217
  ` ${primaryCommandPrefix} host tui`,
214
218
  ...(secondaryCommandPrefix && secondaryCommandPrefix !== primaryCommandPrefix ? [` ${secondaryCommandPrefix} host tui`] : []),
215
219
  ` ${primaryCommandPrefix} host tui --once`,
216
- 'MCP: agent/runtime control surface, not the default human operator UI',
220
+ 'Agent default loop: pingagent_recent_sessions -> pingagent_focus_session -> pingagent_reply',
221
+ 'MCP: agent/runtime control surface',
217
222
  ];
218
223
  }
219
224
 
@@ -453,6 +458,20 @@ function buildHostState(identityPath, selectedSessionKey = null, historyPageInde
453
458
  const selectedProjectionPreview = selectedSession
454
459
  ? buildProjectionPreview(store, selectedSession.session_key, policy.doc.collaboration_projection?.preset || 'balanced', 5)
455
460
  : null;
461
+ const humanDelivery = summarizeHumanDelivery(store, 20);
462
+ const agentState = deriveOpenClawAgentState({
463
+ runtime_status: ingressRuntime,
464
+ sessions,
465
+ pending_decisions: pendingCollaborationEventsGlobal.length,
466
+ human_delivery: humanDelivery,
467
+ transport_health: transportHealth,
468
+ });
469
+ const selectedRecentBindings = selectedSession
470
+ ? listRecentBindingsForSession(store, selectedSession.session_key, selectedSession.conversation_id, 12)
471
+ : [];
472
+ const selectedRecentNotificationIntents = selectedSession
473
+ ? new NotificationIntentManager(store).listBySession(selectedSession.session_key, 12)
474
+ : [];
456
475
  return {
457
476
  identity,
458
477
  runtimeMode,
@@ -460,12 +479,14 @@ function buildHostState(identityPath, selectedSessionKey = null, historyPageInde
460
479
  ingressRuntime,
461
480
  transportPreference,
462
481
  transportHealth,
482
+ agentState,
463
483
  activeChatSessionFile: getActiveSessionFilePath(),
464
484
  sessionMapPath: getSessionMapFilePath(),
465
485
  sessionBindingAlertsPath: getSessionBindingAlertsFilePath(),
466
486
  policyPath: policy.path,
467
487
  policyDoc: policy.doc,
468
488
  projectionPreset: policy.doc.collaboration_projection?.preset || 'balanced',
489
+ humanDelivery,
469
490
  sinceLastSeenGlobal,
470
491
  sessions: sessionsWithSeen,
471
492
  tasks: taskManager.listRecent(30).map((task) => ({
@@ -482,6 +503,8 @@ function buildHostState(identityPath, selectedSessionKey = null, historyPageInde
482
503
  selectedPendingCollaborationEvents,
483
504
  selectedDeliveryTimeline,
484
505
  selectedProjectionPreview,
506
+ selectedRecentBindings,
507
+ selectedRecentNotificationIntents,
485
508
  pendingCollaborationEventsGlobal,
486
509
  selectedMessages,
487
510
  selectedHistoryPage,
@@ -508,6 +531,8 @@ function renderHostTuiScreen(hostState, uiState) {
508
531
  const messages = hostState.selectedMessages || [];
509
532
  const deliveryTimeline = hostState.selectedDeliveryTimeline || [];
510
533
  const projectionPreview = hostState.selectedProjectionPreview || null;
534
+ const recentBindings = hostState.selectedRecentBindings || [];
535
+ const recentNotificationIntents = hostState.selectedRecentNotificationIntents || [];
511
536
  const recommendations = hostState.selectedRecommendations || [];
512
537
  const openRecommendation = recommendations.find((item) => item.status === 'open') || null;
513
538
  const reopenRecommendation = recommendations.find((item) => item.status === 'dismissed' || item.status === 'superseded') || null;
@@ -528,20 +553,42 @@ function renderHostTuiScreen(hostState, uiState) {
528
553
  || !!hostState.ingressRuntime.hooks_last_error;
529
554
  const ingressLabel = degraded ? 'Degraded' : 'Ready';
530
555
  const transportHealth = hostState.transportHealth || { state: 'Ready', transport_mode: 'bridge', preferred_transport_mode: 'bridge', retry_queue_length: 0, consecutive_failures: 0 };
556
+ const humanDelivery = hostState.humanDelivery || {
557
+ mode: 'projection_outbox',
558
+ active_bindings: 0,
559
+ pending_intents: 0,
560
+ unresolved_intents: 0,
561
+ failed_intents: 0,
562
+ acknowledged_intents: 0,
563
+ channel_capabilities: [],
564
+ supported_channels: [],
565
+ unsupported_channels: [],
566
+ last_canary_ok: null,
567
+ last_canary_at: null,
568
+ };
569
+ const agentState = hostState.agentState || {
570
+ state: 'activating',
571
+ summary: 'Activation is still in progress.',
572
+ next_action: 'Wait for activation to finish.',
573
+ reason: null,
574
+ };
531
575
  const sinceLastSeenGlobal = hostState.sinceLastSeenGlobal || {};
532
576
  const lines = [
533
577
  'PingAgent Host TUI',
534
578
  `DID: ${hostState.identity.did}`,
535
579
  `status=${formatStatusLine(uiState?.statusLevel || 'info', uiState?.statusMessage || '(ready)')}${statusTs}${statusCountdown}`,
536
- `runtime_mode=${hostState.runtimeMode} receive_mode=${hostState.ingressRuntime?.receive_mode || 'webhook'} current_openclaw_chat=${hostState.activeChatSession || '(none)'}`,
580
+ `agent_state=${agentState.state} runtime_mode=${hostState.runtimeMode} receive_mode=${hostState.ingressRuntime?.receive_mode || 'webhook'}`,
581
+ `agent_summary=${agentState.summary}`,
582
+ `agent_next_action=${agentState.next_action}`,
537
583
  `ingress=${ingressLabel}${degraded ? ' action=[f] fix-now' : ''}`,
538
584
  `transport=${transportHealth.transport_mode} preferred=${transportHealth.preferred_transport_mode} state=${transportHealth.state} retry_queue=${transportHealth.retry_queue_length} failures=${transportHealth.consecutive_failures}`,
585
+ `human_delivery mode=${humanDelivery.mode || 'projection_outbox'} active_bindings=${humanDelivery.active_bindings ?? 0} pending=${humanDelivery.pending_intents ?? 0} unresolved=${humanDelivery.unresolved_intents ?? 0} failed=${humanDelivery.failed_intents ?? 0} acked=${humanDelivery.acknowledged_intents ?? 0}`,
586
+ `human_delivery_channels supported=${(humanDelivery.supported_channels || []).join(',') || '(none)'} unsupported=${(humanDelivery.unsupported_channels || []).join(',') || '(none)'} canary_ok=${typeof humanDelivery.last_canary_ok === 'boolean' ? String(humanDelivery.last_canary_ok) : '(unknown)'} at=${humanDelivery.last_canary_at || '(none)'}`,
539
587
  uiState?.publicLinkUrl ? `public_link=${uiState.publicLinkUrl}` : null,
540
- `sessions=${sessions.length} unread_total=${hostState.unreadTotal ?? 0} alert_sessions=${hostState.alertSessions ?? 0} view=${view} projection=${hostState.projectionPreset || 'balanced'}`,
588
+ `sessions=${sessions.length} unread_total=${hostState.unreadTotal ?? 0} repair_alert_sessions=${hostState.alertSessions ?? 0} view=${view} projection=${hostState.projectionPreset || 'balanced'}`,
541
589
  `since_last_seen external=${sinceLastSeenGlobal.new_external_messages ?? 0} conclusions=${sinceLastSeenGlobal.new_conclusions ?? 0} decisions=${sinceLastSeenGlobal.new_decisions ?? 0} failures=${sinceLastSeenGlobal.new_failures ?? 0}`,
542
590
  `policy=${hostState.policyPath}`,
543
- `chat_link_map=${hostState.sessionMapPath}`,
544
- `chat_link_alerts=${hostState.sessionBindingAlertsPath}`,
591
+ agentState.reason ? `agent_reason=${truncateLine(agentState.reason, 120)}` : null,
545
592
  hostState.ingressRuntime?.hooks_last_error ? `hooks_error=${truncateLine(hostState.ingressRuntime.hooks_last_error, 120)}` : null,
546
593
  '',
547
594
  ].filter(Boolean);
@@ -560,7 +607,6 @@ function renderHostTuiScreen(hostState, uiState) {
560
607
  lines.push('- x: cancel selected task (in task views)');
561
608
  lines.push('- p: multiline reply prompt (detail view)');
562
609
  lines.push('- S: edit carry-forward summary (detail view)');
563
- lines.push('- d: try demo agent preset');
564
610
  lines.push('- o: open local history paging (detail view)');
565
611
  lines.push('- n / p: older / newer history page (history view)');
566
612
  lines.push('- s or /: search local history (history view)');
@@ -573,8 +619,6 @@ function renderHostTuiScreen(hostState, uiState) {
573
619
  lines.push('- A: apply first open trust recommendation for selected session');
574
620
  lines.push('- D: dismiss current open recommendation');
575
621
  lines.push('- R: reopen dismissed/superseded recommendation');
576
- lines.push('- B: attach selected session to the current OpenClaw chat');
577
- lines.push('- C: detach the selected chat link');
578
622
  lines.push('- q: quit');
579
623
  } else if (view === 'history') {
580
624
  lines.push('Conversation History');
@@ -684,13 +728,12 @@ function renderHostTuiScreen(hostState, uiState) {
684
728
  lines.push(`remote=${selected.remote_did || '(unknown)'}`);
685
729
  lines.push(`trust=${selected.trust_state} unread=${selected.unread_count}`);
686
730
  lines.push(`last_preview=${selected.last_message_preview || '(none)'}`);
687
- lines.push(`chat_link=${selected.binding?.session_key || '(none)'}`);
688
- lines.push(`current_openclaw_chat=${hostState.activeChatSession || '(none)'}`);
731
+ lines.push(`compatibility_route=${selected.binding?.session_key || '(none)'}`);
689
732
  if (selected.binding_alert) {
690
- lines.push('needs_reconnect=true');
691
- lines.push(`warning=${selected.binding_alert.message}`);
733
+ lines.push('compatibility_route_stale=true');
734
+ lines.push(`repair_warning=${selected.binding_alert.message}`);
692
735
  } else {
693
- lines.push('needs_reconnect=false');
736
+ lines.push('compatibility_route_stale=false');
694
737
  }
695
738
  if (openRecommendation) {
696
739
  lines.push(`trust_action=${getTrustRecommendationActionLabel(openRecommendation)}`);
@@ -718,17 +761,17 @@ function renderHostTuiScreen(hostState, uiState) {
718
761
  '[D] dismiss-rec',
719
762
  '[R] reopen-rec',
720
763
  '[m] mark-read',
721
- '[d] demo',
722
764
  '[p] reply',
723
765
  '[S] summary',
724
766
  pendingCollaborationEvents.length ? '[u] approve-decision' : null,
725
767
  pendingCollaborationEvents.length ? '[U] reject-decision' : null,
726
768
  '[o] history',
727
769
  '[t] tasks',
728
- '[B] attach-chat',
729
- '[C] detach-chat',
730
770
  ].filter(Boolean).join(' ');
731
771
  lines.push(`actions=${actionBar}`);
772
+ if (selected.binding || selected.binding_alert) {
773
+ lines.push('compatibility_note=Legacy current-thread routing is available for repair only; the default human-delivery path uses bindings + notification intents.');
774
+ }
732
775
  lines.push('');
733
776
  lines.push('Carry-Forward Summary');
734
777
  if (selectedSummary) {
@@ -770,6 +813,21 @@ function renderHostTuiScreen(hostState, uiState) {
770
813
  lines.push(...(deliveryTimeline.length
771
814
  ? deliveryTimeline.slice(0, 10).map((entry) => `- ${formatTs(entry.ts_ms, false)} ${entry.kind} ${truncateLine(entry.summary || '', 72)}`)
772
815
  : ['- none']));
816
+ lines.push('');
817
+ lines.push('Human Reply Targets');
818
+ lines.push(...(recentBindings.length
819
+ ? recentBindings.slice(0, 6).map((binding) => `- ${binding.channel} -> ${truncateLine(binding.to || '(none)', 48)} [${binding.status}] owner=${truncateLine(binding.owner_ref || '(none)', 32)}`)
820
+ : ['- none']));
821
+ lines.push('');
822
+ lines.push('Notification Intents');
823
+ lines.push(...(recentNotificationIntents.length
824
+ ? recentNotificationIntents.slice(0, 6).map((intent) => `- ${intent.intent_type} [${intent.status}] ${truncateLine(intent.summary || '', 72)}${intent.acknowledged_at ? ` ack=${formatTs(intent.acknowledged_at, false)}` : ''}`)
825
+ : ['- none']));
826
+ lines.push('');
827
+ lines.push('Channel Capability Canary');
828
+ lines.push(...((humanDelivery.channel_capabilities || []).length
829
+ ? humanDelivery.channel_capabilities.slice(0, 8).map((capability) => `- ${capability.channel} configured=${capability.configured ? 'true' : 'false'} explicit_send=${capability.supports_explicit_send ? 'true' : 'false'} dry_run=${capability.supports_dry_run ? 'true' : 'false'} canary=${typeof capability.last_canary_ok === 'boolean' ? String(capability.last_canary_ok) : '(unknown)'}`)
830
+ : ['- none']));
773
831
  }
774
832
  lines.push('');
775
833
  lines.push('Audit');
@@ -782,7 +840,7 @@ function renderHostTuiScreen(hostState, uiState) {
782
840
  }
783
841
 
784
842
  lines.push('');
785
- lines.push('Keys: ↑/↓ or j/k select Enter/l open Esc/h back g/G jump r refresh a approve u/U decide A apply-rec D dismiss-rec R reopen-rec d demo m read p reply o history s search t tasks x cancel-task y dump f fix-hooks b transport->bridge c transport->channel B attach-chat C detach-chat ? help q quit');
843
+ lines.push('Keys: ↑/↓ or j/k select Enter/l open Esc/h back g/G jump r refresh a approve u/U decide A apply-rec D dismiss-rec R reopen-rec m read p reply o history s search t tasks x cancel-task y dump f fix-hooks b transport->bridge c transport->channel ? help q quit');
786
844
  return lines.join('\n');
787
845
  }
788
846
 
@@ -1503,17 +1561,17 @@ async function runHostTui(identityPath, opts) {
1503
1561
  if (!selected?.conversation_id) return;
1504
1562
  const current = latestState.activeChatSession || '(none)';
1505
1563
  const previous = selected.binding?.session_key || '(none)';
1506
- const confirmed = await confirmAction(`Attach chat link for conversation ${selected.conversation_id}\nRemote DID: ${selected.remote_did || '(unknown)'}\nCurrent OpenClaw chat: ${current}\nPrevious chat link: ${previous}\nProceed?`);
1564
+ const confirmed = await confirmAction(`Repair legacy compatibility route for conversation ${selected.conversation_id}\nRemote DID: ${selected.remote_did || '(unknown)'}\nCurrent compatibility target: ${current}\nPrevious compatibility route: ${previous}\nProceed?`);
1507
1565
  if (confirmed) {
1508
1566
  if (!latestState.activeChatSession) {
1509
- setStatus('Attach failed: no active OpenClaw chat.', 'err');
1567
+ setStatus('Compatibility repair failed: no active compatibility target.', 'err');
1510
1568
  latestState = redraw();
1511
1569
  return;
1512
1570
  }
1513
1571
  setSessionBinding(selected.conversation_id, latestState.activeChatSession);
1514
- setStatus(`Attached chat link ${selected.conversation_id} -> ${latestState.activeChatSession}`, 'ok');
1572
+ setStatus(`Compatibility route repaired ${selected.conversation_id} -> ${latestState.activeChatSession}`, 'ok');
1515
1573
  } else {
1516
- setStatus('Attach chat link cancelled.', 'warn');
1574
+ setStatus('Compatibility repair cancelled.', 'warn');
1517
1575
  }
1518
1576
  latestState = redraw();
1519
1577
  return;
@@ -1522,7 +1580,7 @@ async function runHostTui(identityPath, opts) {
1522
1580
  const selected = (latestState.sessions || []).find((session) => session.session_key === uiState.selectedSessionKey);
1523
1581
  if (!selected?.conversation_id) return;
1524
1582
  removeSessionBinding(selected.conversation_id);
1525
- setStatus(`Detached chat link for ${selected.conversation_id}`, 'ok');
1583
+ setStatus(`Cleared compatibility route for ${selected.conversation_id}`, 'ok');
1526
1584
  latestState = redraw();
1527
1585
  return;
1528
1586
  }
@@ -3475,88 +3533,52 @@ async function runHostBootstrap(opts) {
3475
3533
  process.exit(1);
3476
3534
  }
3477
3535
 
3478
- const steps = [];
3479
- const runStep = (label, args) => {
3480
- const result = runOpenClawInstall(args);
3481
- steps.push({ label, args, result });
3482
- return { label, args, result };
3483
- };
3484
-
3485
- const installStep = runStep('install', []);
3486
- const hooksStep = installStep.result.ok ? runStep('hooks repair', ['fix-hooks']) : null;
3487
- const verifyStep = installStep.result.ok && hooksStep?.result.ok
3488
- ? runStep('runtime verify', ['verify-runtime', '--fix-hooks'])
3489
- : null;
3490
-
3536
+ const installStep = runOpenClawInstall([]);
3537
+ const steps = [{ label: 'activate', result: installStep }];
3491
3538
  let runnerStep = null;
3492
- if (verifyStep?.result.ok && opts.write) {
3539
+ if (installStep.ok && opts.write) {
3493
3540
  const runnerArgs = ['init-runner', '--ingress', '--panel'];
3494
3541
  if (template) runnerArgs.push('--template', template);
3495
3542
  const supportsWrite = !template || template === 'launchd' || template === 'systemd';
3496
3543
  if (supportsWrite) runnerArgs.push('--write');
3497
- runnerStep = runStep(supportsWrite ? 'runner setup' : 'runner template', runnerArgs);
3544
+ const result = runOpenClawInstall(runnerArgs);
3545
+ steps.push({ label: supportsWrite ? 'runner setup' : 'runner template', result });
3546
+ runnerStep = { result };
3547
+ }
3548
+
3549
+ console.log('PingAgent Host Bootstrap (compatibility alias)');
3550
+ console.log('=============================================');
3551
+ console.log('bootstrap_role=compatibility_alias');
3552
+ console.log('preferred_entry=npx @pingagent/openclaw-install');
3553
+ console.log('');
3554
+
3555
+ if (installStep.stdout.trim()) {
3556
+ console.log(installStep.stdout.trim());
3557
+ }
3558
+ if (installStep.stderr.trim()) {
3559
+ console.error(installStep.stderr.trim());
3498
3560
  }
3499
3561
 
3500
3562
  if (runnerStep?.result.stdout && opts.write) {
3563
+ console.log('');
3501
3564
  console.log(runnerStep.result.stdout.trim());
3502
3565
  if (runnerStep.result.stderr.trim()) console.error(runnerStep.result.stderr.trim());
3503
- console.log('');
3504
3566
  }
3505
3567
 
3506
3568
  const failed = steps.find((step) => !step.result.ok) ?? null;
3507
- const formatStepStatus = (step, fallback = 'skipped') => (step ? (step.result.ok ? 'ok' : 'failed') : fallback);
3508
- const runnerStatus = !opts.write
3509
- ? 'not_written'
3510
- : !runnerStep
3511
- ? 'skipped'
3512
- : !runnerStep.result.ok
3513
- ? 'failed'
3514
- : (template && template !== 'launchd' && template !== 'systemd')
3515
- ? 'template_printed_not_started'
3516
- : 'written_not_started';
3517
- const installerSource = installStep.result.source || 'unknown';
3518
-
3519
- console.log('PingAgent Host Bootstrap');
3520
- console.log('========================');
3521
- console.log(`install=${formatStepStatus(installStep)}`);
3522
- console.log(`hooks_repair=${formatStepStatus(hooksStep)}`);
3523
- console.log(`runtime_verify=${formatStepStatus(verifyStep)}`);
3524
- console.log(`installer_source=${installerSource}`);
3525
- console.log(`runner=${runnerStatus}`);
3526
- console.log(`host_panel_url=${getHostPanelSurfaceUrl()}`);
3527
- console.log('host_panel_started_by_bootstrap=false');
3528
- console.log('host_panel_start=npx @pingagent/sdk web');
3529
- console.log('host_panel_start_local=pingagent web');
3530
- console.log('tui=npx @pingagent/sdk host tui');
3531
- console.log('tui_local=pingagent host tui');
3532
- console.log('');
3533
- console.log('Control surfaces:');
3534
- for (const line of getSurfaceRecommendationLines('npx @pingagent/sdk', 'pingagent')) console.log(line);
3535
- console.log('');
3536
- if (!opts.write) {
3537
- console.log('Next steps:');
3538
- console.log(' Bootstrap validates and repairs config, but it does not start long-lived daemons.');
3539
- console.log(' Start the Host Panel now with: npx @pingagent/sdk web (or pingagent web)');
3540
- console.log(' Use the headless surface now with: npx @pingagent/sdk host tui (or pingagent host tui)');
3541
- console.log(` Re-run with: npx @pingagent/sdk host bootstrap --write${template ? ` --template ${template}` : ''}`);
3542
- console.log(' Manual path: npx @pingagent/openclaw-install init-runner --ingress --panel');
3543
- } else if (runnerStep?.result.ok) {
3544
- console.log('Next steps:');
3545
- console.log(' Runner files/templates were generated, but bootstrap did not start those services.');
3546
- if (!template || template === 'launchd' || template === 'systemd') {
3547
- console.log(' Follow the printed launchctl/systemctl instructions to start them.');
3548
- } else {
3549
- console.log(' Start the generated runner with your chosen process manager.');
3569
+ if (!failed) {
3570
+ console.log('');
3571
+ console.log('Compatibility surfaces:');
3572
+ for (const line of getSurfaceRecommendationLines('npx @pingagent/sdk', 'pingagent')) console.log(line);
3573
+ if (opts.write && runnerStep?.result.ok) {
3574
+ console.log('');
3575
+ console.log('runner_files=written');
3550
3576
  }
3551
3577
  }
3552
3578
 
3553
3579
  if (failed) {
3554
- const stdout = failed.result.stdout.trim();
3555
- const stderr = failed.result.stderr.trim();
3556
3580
  console.error('');
3557
- console.error(`Bootstrap failed during ${failed.label}.`);
3558
- if (stdout) console.error(stdout);
3559
- if (stderr) console.error(stderr);
3581
+ console.error(`Bootstrap alias failed during ${failed.label}.`);
3560
3582
  process.exit(1);
3561
3583
  }
3562
3584
  }
@@ -3567,7 +3589,7 @@ const host = program
3567
3589
 
3568
3590
  host
3569
3591
  .command('bootstrap')
3570
- .description('Run the idempotent OpenClaw activation flow and print the recommended Host Panel / TUI surfaces')
3592
+ .description('Compatibility alias for the OpenClaw activation flow. Prefer npx @pingagent/openclaw-install.')
3571
3593
  .option('--write', 'Write launchd/systemd runner files when supported')
3572
3594
  .option('--template <name>', 'Runner template: launchd, systemd, docker, pm2, or supervisord')
3573
3595
  .action(async (opts) => {
@@ -3576,7 +3598,7 @@ host
3576
3598
 
3577
3599
  host
3578
3600
  .command('tui')
3579
- .description('Start the headless / low-token terminal UI for runtime, sessions, chat links, and repair actions')
3601
+ .description('Start the headless terminal repair / audit / approval surface for OpenClaw hosts')
3580
3602
  .option('--once', 'Print one snapshot and exit')
3581
3603
  .option('--refresh-ms <ms>', 'Refresh interval in interactive mode', '2000')
3582
3604
  .option('--profile <name>', 'Use profile from ~/.pingagent/<name>')
@@ -3591,7 +3613,7 @@ host
3591
3613
 
3592
3614
  program
3593
3615
  .command('web')
3594
- .description('Start the Host Panel, the primary GUI surface for runtime inspection, trust policy, and repair. Use pingagent host tui for headless or low-token operation.')
3616
+ .description('Start the Host Panel GUI for repair, audit, approvals, and advanced runtime inspection. Use pingagent host tui for headless operation.')
3595
3617
  .option('--port <port>', 'Port for the web server', '3846')
3596
3618
  .action(async (opts) => {
3597
3619
  const serverUrl = process.env.PINGAGENT_SERVER_URL || DEFAULT_SERVER;