@pingagent/sdk 0.1.16 → 0.1.18
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 +106 -102
- package/dist/chunk-34F6AUBW.js +6537 -0
- package/dist/chunk-66PVWBOU.js +6412 -0
- package/dist/chunk-DJ5XF3WK.js +7857 -0
- package/dist/chunk-IB7OSFZS.js +5951 -0
- package/dist/chunk-JWBNSM4N.js +7948 -0
- package/dist/chunk-PEKTGNH6.js +7948 -0
- package/dist/chunk-V7NQC6XA.js +7948 -0
- package/dist/index.d.ts +565 -37
- package/dist/index.js +45 -1
- package/dist/web-server.js +399 -69
- package/package.json +1 -1
package/bin/pingagent.js
CHANGED
|
@@ -40,6 +40,9 @@ import {
|
|
|
40
40
|
listPendingDecisionViews,
|
|
41
41
|
summarizeHumanDelivery,
|
|
42
42
|
listRecentBindingsForSession,
|
|
43
|
+
buildActionInboxSummary,
|
|
44
|
+
OpenClawExecutionAdapter,
|
|
45
|
+
deriveOpenClawAgentState,
|
|
43
46
|
deriveTransportHealth,
|
|
44
47
|
readTransportPreference,
|
|
45
48
|
switchTransportPreference,
|
|
@@ -122,9 +125,9 @@ function formatRetentionLabel(ttlMs) {
|
|
|
122
125
|
|
|
123
126
|
function describeHostedTier(tier) {
|
|
124
127
|
if (tier === 'plus') return 'shareable identity + first alias + higher relay';
|
|
125
|
-
if (tier === 'pro') return 'multi-identity
|
|
128
|
+
if (tier === 'pro') return 'multi-identity escalation + callback governance + audit export';
|
|
126
129
|
if (tier === 'enterprise') return 'high-scale governance + operational controls';
|
|
127
|
-
return 'free
|
|
130
|
+
return 'free escalation-first entry tier';
|
|
128
131
|
}
|
|
129
132
|
|
|
130
133
|
function openStore(identityPath) {
|
|
@@ -208,15 +211,16 @@ function getHostPanelSurfaceUrl() {
|
|
|
208
211
|
|
|
209
212
|
function getSurfaceRecommendationLines(primaryCommandPrefix = 'npx @pingagent/sdk', secondaryCommandPrefix = 'pingagent') {
|
|
210
213
|
return [
|
|
211
|
-
'
|
|
214
|
+
'GUI repair / approvals / audit: Host Panel',
|
|
212
215
|
` Start locally: ${primaryCommandPrefix} web`,
|
|
213
216
|
...(secondaryCommandPrefix && secondaryCommandPrefix !== primaryCommandPrefix ? [` Or via local bin: ${secondaryCommandPrefix} web`] : []),
|
|
214
217
|
` URL when running: ${getHostPanelSurfaceUrl()}`,
|
|
215
|
-
'Headless
|
|
218
|
+
'Headless repair surface: TUI',
|
|
216
219
|
` ${primaryCommandPrefix} host tui`,
|
|
217
220
|
...(secondaryCommandPrefix && secondaryCommandPrefix !== primaryCommandPrefix ? [` ${secondaryCommandPrefix} host tui`] : []),
|
|
218
221
|
` ${primaryCommandPrefix} host tui --once`,
|
|
219
|
-
'
|
|
222
|
+
'Agent default loop: pingagent_recent_sessions -> pingagent_focus_session -> pingagent_reply',
|
|
223
|
+
'MCP: agent/runtime control surface',
|
|
220
224
|
];
|
|
221
225
|
}
|
|
222
226
|
|
|
@@ -457,12 +461,28 @@ function buildHostState(identityPath, selectedSessionKey = null, historyPageInde
|
|
|
457
461
|
? buildProjectionPreview(store, selectedSession.session_key, policy.doc.collaboration_projection?.preset || 'balanced', 5)
|
|
458
462
|
: null;
|
|
459
463
|
const humanDelivery = summarizeHumanDelivery(store, 20);
|
|
464
|
+
const agentState = deriveOpenClawAgentState({
|
|
465
|
+
runtime_status: ingressRuntime,
|
|
466
|
+
sessions,
|
|
467
|
+
pending_decisions: pendingCollaborationEventsGlobal.length,
|
|
468
|
+
human_delivery: humanDelivery,
|
|
469
|
+
transport_health: transportHealth,
|
|
470
|
+
});
|
|
460
471
|
const selectedRecentBindings = selectedSession
|
|
461
472
|
? listRecentBindingsForSession(store, selectedSession.session_key, selectedSession.conversation_id, 12)
|
|
462
473
|
: [];
|
|
463
474
|
const selectedRecentNotificationIntents = selectedSession
|
|
464
475
|
? new NotificationIntentManager(store).listBySession(selectedSession.session_key, 12)
|
|
465
476
|
: [];
|
|
477
|
+
const openClawAdapter = new OpenClawExecutionAdapter(store).buildOverview(20);
|
|
478
|
+
const actionInbox = buildActionInboxSummary({
|
|
479
|
+
pending_decisions: pendingCollaborationEventsGlobal,
|
|
480
|
+
notification_intents: new NotificationIntentManager(store).listRecent(20),
|
|
481
|
+
external_escalations: openClawAdapter.recent_escalations,
|
|
482
|
+
agent_state: agentState,
|
|
483
|
+
include_runtime: true,
|
|
484
|
+
limit: 20,
|
|
485
|
+
});
|
|
466
486
|
return {
|
|
467
487
|
identity,
|
|
468
488
|
runtimeMode,
|
|
@@ -470,6 +490,7 @@ function buildHostState(identityPath, selectedSessionKey = null, historyPageInde
|
|
|
470
490
|
ingressRuntime,
|
|
471
491
|
transportPreference,
|
|
472
492
|
transportHealth,
|
|
493
|
+
agentState,
|
|
473
494
|
activeChatSessionFile: getActiveSessionFilePath(),
|
|
474
495
|
sessionMapPath: getSessionMapFilePath(),
|
|
475
496
|
sessionBindingAlertsPath: getSessionBindingAlertsFilePath(),
|
|
@@ -477,6 +498,8 @@ function buildHostState(identityPath, selectedSessionKey = null, historyPageInde
|
|
|
477
498
|
policyDoc: policy.doc,
|
|
478
499
|
projectionPreset: policy.doc.collaboration_projection?.preset || 'balanced',
|
|
479
500
|
humanDelivery,
|
|
501
|
+
actionInbox,
|
|
502
|
+
openClawAdapter,
|
|
480
503
|
sinceLastSeenGlobal,
|
|
481
504
|
sessions: sessionsWithSeen,
|
|
482
505
|
tasks: taskManager.listRecent(30).map((task) => ({
|
|
@@ -556,22 +579,42 @@ function renderHostTuiScreen(hostState, uiState) {
|
|
|
556
579
|
last_canary_ok: null,
|
|
557
580
|
last_canary_at: null,
|
|
558
581
|
};
|
|
582
|
+
const agentState = hostState.agentState || {
|
|
583
|
+
state: 'activating',
|
|
584
|
+
summary: 'Activation is still in progress.',
|
|
585
|
+
next_action: 'Wait for activation to finish.',
|
|
586
|
+
reason: null,
|
|
587
|
+
};
|
|
588
|
+
const actionInbox = hostState.actionInbox || {
|
|
589
|
+
total: 0,
|
|
590
|
+
pending_approval: 0,
|
|
591
|
+
pending_callback: 0,
|
|
592
|
+
pending_escalation: 0,
|
|
593
|
+
blocked: 0,
|
|
594
|
+
degraded: 0,
|
|
595
|
+
timed_out: 0,
|
|
596
|
+
high_risk: 0,
|
|
597
|
+
critical_risk: 0,
|
|
598
|
+
items: [],
|
|
599
|
+
};
|
|
559
600
|
const sinceLastSeenGlobal = hostState.sinceLastSeenGlobal || {};
|
|
560
601
|
const lines = [
|
|
561
602
|
'PingAgent Host TUI',
|
|
562
603
|
`DID: ${hostState.identity.did}`,
|
|
563
604
|
`status=${formatStatusLine(uiState?.statusLevel || 'info', uiState?.statusMessage || '(ready)')}${statusTs}${statusCountdown}`,
|
|
564
|
-
`runtime_mode=${hostState.runtimeMode} receive_mode=${hostState.ingressRuntime?.receive_mode || 'webhook'}
|
|
605
|
+
`agent_state=${agentState.state} runtime_mode=${hostState.runtimeMode} receive_mode=${hostState.ingressRuntime?.receive_mode || 'webhook'}`,
|
|
606
|
+
`agent_summary=${agentState.summary}`,
|
|
607
|
+
`agent_next_action=${agentState.next_action}`,
|
|
565
608
|
`ingress=${ingressLabel}${degraded ? ' action=[f] fix-now' : ''}`,
|
|
566
609
|
`transport=${transportHealth.transport_mode} preferred=${transportHealth.preferred_transport_mode} state=${transportHealth.state} retry_queue=${transportHealth.retry_queue_length} failures=${transportHealth.consecutive_failures}`,
|
|
567
610
|
`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}`,
|
|
611
|
+
`action_inbox total=${actionInbox.total} approvals=${actionInbox.pending_approval} callbacks=${actionInbox.pending_callback} escalations=${actionInbox.pending_escalation} blocked=${actionInbox.blocked} timed_out=${actionInbox.timed_out} degraded=${actionInbox.degraded}`,
|
|
568
612
|
`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)'}`,
|
|
569
613
|
uiState?.publicLinkUrl ? `public_link=${uiState.publicLinkUrl}` : null,
|
|
570
|
-
`sessions=${sessions.length} unread_total=${hostState.unreadTotal ?? 0}
|
|
614
|
+
`sessions=${sessions.length} unread_total=${hostState.unreadTotal ?? 0} repair_alert_sessions=${hostState.alertSessions ?? 0} view=${view} projection=${hostState.projectionPreset || 'balanced'}`,
|
|
571
615
|
`since_last_seen external=${sinceLastSeenGlobal.new_external_messages ?? 0} conclusions=${sinceLastSeenGlobal.new_conclusions ?? 0} decisions=${sinceLastSeenGlobal.new_decisions ?? 0} failures=${sinceLastSeenGlobal.new_failures ?? 0}`,
|
|
572
616
|
`policy=${hostState.policyPath}`,
|
|
573
|
-
`
|
|
574
|
-
`chat_link_alerts=${hostState.sessionBindingAlertsPath}`,
|
|
617
|
+
agentState.reason ? `agent_reason=${truncateLine(agentState.reason, 120)}` : null,
|
|
575
618
|
hostState.ingressRuntime?.hooks_last_error ? `hooks_error=${truncateLine(hostState.ingressRuntime.hooks_last_error, 120)}` : null,
|
|
576
619
|
'',
|
|
577
620
|
].filter(Boolean);
|
|
@@ -586,11 +629,10 @@ function renderHostTuiScreen(hostState, uiState) {
|
|
|
586
629
|
lines.push('- a: approve selected pending contact');
|
|
587
630
|
lines.push('- m: mark selected session as read');
|
|
588
631
|
lines.push('- t: open task list view for selected session');
|
|
589
|
-
lines.push('- i: open
|
|
632
|
+
lines.push('- i: open Action Inbox approval slice');
|
|
590
633
|
lines.push('- x: cancel selected task (in task views)');
|
|
591
634
|
lines.push('- p: multiline reply prompt (detail view)');
|
|
592
635
|
lines.push('- S: edit carry-forward summary (detail view)');
|
|
593
|
-
lines.push('- d: try demo agent preset');
|
|
594
636
|
lines.push('- o: open local history paging (detail view)');
|
|
595
637
|
lines.push('- n / p: older / newer history page (history view)');
|
|
596
638
|
lines.push('- s or /: search local history (history view)');
|
|
@@ -603,8 +645,6 @@ function renderHostTuiScreen(hostState, uiState) {
|
|
|
603
645
|
lines.push('- A: apply first open trust recommendation for selected session');
|
|
604
646
|
lines.push('- D: dismiss current open recommendation');
|
|
605
647
|
lines.push('- R: reopen dismissed/superseded recommendation');
|
|
606
|
-
lines.push('- B: attach selected session to the current OpenClaw chat');
|
|
607
|
-
lines.push('- C: detach the selected chat link');
|
|
608
648
|
lines.push('- q: quit');
|
|
609
649
|
} else if (view === 'history') {
|
|
610
650
|
lines.push('Conversation History');
|
|
@@ -663,8 +703,8 @@ function renderHostTuiScreen(hostState, uiState) {
|
|
|
663
703
|
lines.push(...tasks.map((task, idx) => `${idx === selectedTaskIndex ? '>' : ' '} ${task.task_id} [${task.status}] ${truncateLine(task.title || task.result_summary || '', 70)}`));
|
|
664
704
|
}
|
|
665
705
|
} else if (view === 'decisions') {
|
|
666
|
-
lines.push('
|
|
667
|
-
lines.push(`
|
|
706
|
+
lines.push('Action Inbox (approval-only slice)');
|
|
707
|
+
lines.push(`pending_approvals=${pendingCollaborationEventsGlobal.length} action_inbox_total=${actionInbox.total}`);
|
|
668
708
|
lines.push('actions=[u] approve [U] reject [Enter/l] open-session [j/k] select [h/Esc] back');
|
|
669
709
|
lines.push('');
|
|
670
710
|
lines.push(...(pendingCollaborationEventsGlobal.length
|
|
@@ -714,13 +754,12 @@ function renderHostTuiScreen(hostState, uiState) {
|
|
|
714
754
|
lines.push(`remote=${selected.remote_did || '(unknown)'}`);
|
|
715
755
|
lines.push(`trust=${selected.trust_state} unread=${selected.unread_count}`);
|
|
716
756
|
lines.push(`last_preview=${selected.last_message_preview || '(none)'}`);
|
|
717
|
-
lines.push(`
|
|
718
|
-
lines.push(`current_openclaw_chat=${hostState.activeChatSession || '(none)'}`);
|
|
757
|
+
lines.push(`compatibility_route=${selected.binding?.session_key || '(none)'}`);
|
|
719
758
|
if (selected.binding_alert) {
|
|
720
|
-
lines.push('
|
|
721
|
-
lines.push(`
|
|
759
|
+
lines.push('compatibility_route_stale=true');
|
|
760
|
+
lines.push(`repair_warning=${selected.binding_alert.message}`);
|
|
722
761
|
} else {
|
|
723
|
-
lines.push('
|
|
762
|
+
lines.push('compatibility_route_stale=false');
|
|
724
763
|
}
|
|
725
764
|
if (openRecommendation) {
|
|
726
765
|
lines.push(`trust_action=${getTrustRecommendationActionLabel(openRecommendation)}`);
|
|
@@ -734,12 +773,13 @@ function renderHostTuiScreen(hostState, uiState) {
|
|
|
734
773
|
lines.push('summary_objective=(none)');
|
|
735
774
|
}
|
|
736
775
|
if (pendingCollaborationEvents.length > 0) {
|
|
737
|
-
lines.push(`
|
|
738
|
-
lines.push(`
|
|
776
|
+
lines.push(`action_inbox_pending_approvals=${pendingCollaborationEvents.length}`);
|
|
777
|
+
lines.push(`next_approval=${truncateLine(pendingCollaborationEvents[0].summary || '(none)', 100)}`);
|
|
739
778
|
if (pendingCollaborationEvents[0].overdue) {
|
|
740
|
-
lines.push(`
|
|
779
|
+
lines.push(`next_approval_overdue=${Math.ceil((pendingCollaborationEvents[0].overdue_by_ms || 0) / 60000)}m`);
|
|
741
780
|
}
|
|
742
781
|
}
|
|
782
|
+
lines.push(`action_inbox_total=${actionInbox.total} callbacks=${actionInbox.pending_callback} escalations=${actionInbox.pending_escalation} blocked=${actionInbox.blocked} timed_out=${actionInbox.timed_out}`);
|
|
743
783
|
const sessionSeen = selected.since_last_seen || {};
|
|
744
784
|
lines.push(`since_last_seen external=${sessionSeen.new_external_messages ?? 0} conclusions=${sessionSeen.new_conclusions ?? 0} decisions=${sessionSeen.new_decisions ?? 0} failures=${sessionSeen.new_failures ?? 0}`);
|
|
745
785
|
const actionBar = [
|
|
@@ -748,17 +788,17 @@ function renderHostTuiScreen(hostState, uiState) {
|
|
|
748
788
|
'[D] dismiss-rec',
|
|
749
789
|
'[R] reopen-rec',
|
|
750
790
|
'[m] mark-read',
|
|
751
|
-
'[d] demo',
|
|
752
791
|
'[p] reply',
|
|
753
792
|
'[S] summary',
|
|
754
|
-
pendingCollaborationEvents.length ? '[u] approve-
|
|
755
|
-
pendingCollaborationEvents.length ? '[U] reject-
|
|
793
|
+
pendingCollaborationEvents.length ? '[u] approve-action' : null,
|
|
794
|
+
pendingCollaborationEvents.length ? '[U] reject-action' : null,
|
|
756
795
|
'[o] history',
|
|
757
796
|
'[t] tasks',
|
|
758
|
-
'[B] attach-chat',
|
|
759
|
-
'[C] detach-chat',
|
|
760
797
|
].filter(Boolean).join(' ');
|
|
761
798
|
lines.push(`actions=${actionBar}`);
|
|
799
|
+
if (selected.binding || selected.binding_alert) {
|
|
800
|
+
lines.push('compatibility_note=Legacy current-thread routing is available for repair only; the default human-delivery path uses bindings + notification intents.');
|
|
801
|
+
}
|
|
762
802
|
lines.push('');
|
|
763
803
|
lines.push('Carry-Forward Summary');
|
|
764
804
|
if (selectedSummary) {
|
|
@@ -827,7 +867,7 @@ function renderHostTuiScreen(hostState, uiState) {
|
|
|
827
867
|
}
|
|
828
868
|
|
|
829
869
|
lines.push('');
|
|
830
|
-
lines.push('Keys: ↑/↓ or j/k select Enter/l open Esc/h back g/G jump r refresh a approve u/U
|
|
870
|
+
lines.push('Keys: ↑/↓ or j/k select Enter/l open Esc/h back g/G jump r refresh a approve u/U resolve-approval 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');
|
|
831
871
|
return lines.join('\n');
|
|
832
872
|
}
|
|
833
873
|
|
|
@@ -1338,7 +1378,7 @@ async function runHostTui(identityPath, opts) {
|
|
|
1338
1378
|
if (key?.name === 'i') {
|
|
1339
1379
|
uiState.view = 'decisions';
|
|
1340
1380
|
uiState.selectedDecisionIndex = 0;
|
|
1341
|
-
setStatus('Opened
|
|
1381
|
+
setStatus('Opened the Action Inbox approval slice.', 'info');
|
|
1342
1382
|
latestState = redraw();
|
|
1343
1383
|
latestState = rerenderAfterSeenUpdate(latestState, { forceGlobal: true });
|
|
1344
1384
|
return;
|
|
@@ -1548,17 +1588,17 @@ async function runHostTui(identityPath, opts) {
|
|
|
1548
1588
|
if (!selected?.conversation_id) return;
|
|
1549
1589
|
const current = latestState.activeChatSession || '(none)';
|
|
1550
1590
|
const previous = selected.binding?.session_key || '(none)';
|
|
1551
|
-
const confirmed = await confirmAction(`
|
|
1591
|
+
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?`);
|
|
1552
1592
|
if (confirmed) {
|
|
1553
1593
|
if (!latestState.activeChatSession) {
|
|
1554
|
-
setStatus('
|
|
1594
|
+
setStatus('Compatibility repair failed: no active compatibility target.', 'err');
|
|
1555
1595
|
latestState = redraw();
|
|
1556
1596
|
return;
|
|
1557
1597
|
}
|
|
1558
1598
|
setSessionBinding(selected.conversation_id, latestState.activeChatSession);
|
|
1559
|
-
setStatus(`
|
|
1599
|
+
setStatus(`Compatibility route repaired ${selected.conversation_id} -> ${latestState.activeChatSession}`, 'ok');
|
|
1560
1600
|
} else {
|
|
1561
|
-
setStatus('
|
|
1601
|
+
setStatus('Compatibility repair cancelled.', 'warn');
|
|
1562
1602
|
}
|
|
1563
1603
|
latestState = redraw();
|
|
1564
1604
|
return;
|
|
@@ -1567,7 +1607,7 @@ async function runHostTui(identityPath, opts) {
|
|
|
1567
1607
|
const selected = (latestState.sessions || []).find((session) => session.session_key === uiState.selectedSessionKey);
|
|
1568
1608
|
if (!selected?.conversation_id) return;
|
|
1569
1609
|
removeSessionBinding(selected.conversation_id);
|
|
1570
|
-
setStatus(`
|
|
1610
|
+
setStatus(`Cleared compatibility route for ${selected.conversation_id}`, 'ok');
|
|
1571
1611
|
latestState = redraw();
|
|
1572
1612
|
return;
|
|
1573
1613
|
}
|
|
@@ -3520,88 +3560,52 @@ async function runHostBootstrap(opts) {
|
|
|
3520
3560
|
process.exit(1);
|
|
3521
3561
|
}
|
|
3522
3562
|
|
|
3523
|
-
const
|
|
3524
|
-
const
|
|
3525
|
-
const result = runOpenClawInstall(args);
|
|
3526
|
-
steps.push({ label, args, result });
|
|
3527
|
-
return { label, args, result };
|
|
3528
|
-
};
|
|
3529
|
-
|
|
3530
|
-
const installStep = runStep('install', []);
|
|
3531
|
-
const hooksStep = installStep.result.ok ? runStep('hooks repair', ['fix-hooks']) : null;
|
|
3532
|
-
const verifyStep = installStep.result.ok && hooksStep?.result.ok
|
|
3533
|
-
? runStep('runtime verify', ['verify-runtime', '--fix-hooks'])
|
|
3534
|
-
: null;
|
|
3535
|
-
|
|
3563
|
+
const installStep = runOpenClawInstall([]);
|
|
3564
|
+
const steps = [{ label: 'activate', result: installStep }];
|
|
3536
3565
|
let runnerStep = null;
|
|
3537
|
-
if (
|
|
3566
|
+
if (installStep.ok && opts.write) {
|
|
3538
3567
|
const runnerArgs = ['init-runner', '--ingress', '--panel'];
|
|
3539
3568
|
if (template) runnerArgs.push('--template', template);
|
|
3540
3569
|
const supportsWrite = !template || template === 'launchd' || template === 'systemd';
|
|
3541
3570
|
if (supportsWrite) runnerArgs.push('--write');
|
|
3542
|
-
|
|
3571
|
+
const result = runOpenClawInstall(runnerArgs);
|
|
3572
|
+
steps.push({ label: supportsWrite ? 'runner setup' : 'runner template', result });
|
|
3573
|
+
runnerStep = { result };
|
|
3574
|
+
}
|
|
3575
|
+
|
|
3576
|
+
console.log('PingAgent Host Bootstrap (compatibility alias)');
|
|
3577
|
+
console.log('=============================================');
|
|
3578
|
+
console.log('bootstrap_role=compatibility_alias');
|
|
3579
|
+
console.log('preferred_entry=npx @pingagent/openclaw-install');
|
|
3580
|
+
console.log('');
|
|
3581
|
+
|
|
3582
|
+
if (installStep.stdout.trim()) {
|
|
3583
|
+
console.log(installStep.stdout.trim());
|
|
3584
|
+
}
|
|
3585
|
+
if (installStep.stderr.trim()) {
|
|
3586
|
+
console.error(installStep.stderr.trim());
|
|
3543
3587
|
}
|
|
3544
3588
|
|
|
3545
3589
|
if (runnerStep?.result.stdout && opts.write) {
|
|
3590
|
+
console.log('');
|
|
3546
3591
|
console.log(runnerStep.result.stdout.trim());
|
|
3547
3592
|
if (runnerStep.result.stderr.trim()) console.error(runnerStep.result.stderr.trim());
|
|
3548
|
-
console.log('');
|
|
3549
3593
|
}
|
|
3550
3594
|
|
|
3551
3595
|
const failed = steps.find((step) => !step.result.ok) ?? null;
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
: (template && template !== 'launchd' && template !== 'systemd')
|
|
3560
|
-
? 'template_printed_not_started'
|
|
3561
|
-
: 'written_not_started';
|
|
3562
|
-
const installerSource = installStep.result.source || 'unknown';
|
|
3563
|
-
|
|
3564
|
-
console.log('PingAgent Host Bootstrap');
|
|
3565
|
-
console.log('========================');
|
|
3566
|
-
console.log(`install=${formatStepStatus(installStep)}`);
|
|
3567
|
-
console.log(`hooks_repair=${formatStepStatus(hooksStep)}`);
|
|
3568
|
-
console.log(`runtime_verify=${formatStepStatus(verifyStep)}`);
|
|
3569
|
-
console.log(`installer_source=${installerSource}`);
|
|
3570
|
-
console.log(`runner=${runnerStatus}`);
|
|
3571
|
-
console.log(`host_panel_url=${getHostPanelSurfaceUrl()}`);
|
|
3572
|
-
console.log('host_panel_started_by_bootstrap=false');
|
|
3573
|
-
console.log('host_panel_start=npx @pingagent/sdk web');
|
|
3574
|
-
console.log('host_panel_start_local=pingagent web');
|
|
3575
|
-
console.log('tui=npx @pingagent/sdk host tui');
|
|
3576
|
-
console.log('tui_local=pingagent host tui');
|
|
3577
|
-
console.log('');
|
|
3578
|
-
console.log('Control surfaces:');
|
|
3579
|
-
for (const line of getSurfaceRecommendationLines('npx @pingagent/sdk', 'pingagent')) console.log(line);
|
|
3580
|
-
console.log('');
|
|
3581
|
-
if (!opts.write) {
|
|
3582
|
-
console.log('Next steps:');
|
|
3583
|
-
console.log(' Bootstrap validates and repairs config, but it does not start long-lived daemons.');
|
|
3584
|
-
console.log(' Start the Host Panel now with: npx @pingagent/sdk web (or pingagent web)');
|
|
3585
|
-
console.log(' Use the headless surface now with: npx @pingagent/sdk host tui (or pingagent host tui)');
|
|
3586
|
-
console.log(` Re-run with: npx @pingagent/sdk host bootstrap --write${template ? ` --template ${template}` : ''}`);
|
|
3587
|
-
console.log(' Manual path: npx @pingagent/openclaw-install init-runner --ingress --panel');
|
|
3588
|
-
} else if (runnerStep?.result.ok) {
|
|
3589
|
-
console.log('Next steps:');
|
|
3590
|
-
console.log(' Runner files/templates were generated, but bootstrap did not start those services.');
|
|
3591
|
-
if (!template || template === 'launchd' || template === 'systemd') {
|
|
3592
|
-
console.log(' Follow the printed launchctl/systemctl instructions to start them.');
|
|
3593
|
-
} else {
|
|
3594
|
-
console.log(' Start the generated runner with your chosen process manager.');
|
|
3596
|
+
if (!failed) {
|
|
3597
|
+
console.log('');
|
|
3598
|
+
console.log('Compatibility surfaces:');
|
|
3599
|
+
for (const line of getSurfaceRecommendationLines('npx @pingagent/sdk', 'pingagent')) console.log(line);
|
|
3600
|
+
if (opts.write && runnerStep?.result.ok) {
|
|
3601
|
+
console.log('');
|
|
3602
|
+
console.log('runner_files=written');
|
|
3595
3603
|
}
|
|
3596
3604
|
}
|
|
3597
3605
|
|
|
3598
3606
|
if (failed) {
|
|
3599
|
-
const stdout = failed.result.stdout.trim();
|
|
3600
|
-
const stderr = failed.result.stderr.trim();
|
|
3601
3607
|
console.error('');
|
|
3602
|
-
console.error(`Bootstrap failed during ${failed.label}.`);
|
|
3603
|
-
if (stdout) console.error(stdout);
|
|
3604
|
-
if (stderr) console.error(stderr);
|
|
3608
|
+
console.error(`Bootstrap alias failed during ${failed.label}.`);
|
|
3605
3609
|
process.exit(1);
|
|
3606
3610
|
}
|
|
3607
3611
|
}
|
|
@@ -3612,7 +3616,7 @@ const host = program
|
|
|
3612
3616
|
|
|
3613
3617
|
host
|
|
3614
3618
|
.command('bootstrap')
|
|
3615
|
-
.description('
|
|
3619
|
+
.description('Compatibility alias for the OpenClaw activation flow. Prefer npx @pingagent/openclaw-install.')
|
|
3616
3620
|
.option('--write', 'Write launchd/systemd runner files when supported')
|
|
3617
3621
|
.option('--template <name>', 'Runner template: launchd, systemd, docker, pm2, or supervisord')
|
|
3618
3622
|
.action(async (opts) => {
|
|
@@ -3621,7 +3625,7 @@ host
|
|
|
3621
3625
|
|
|
3622
3626
|
host
|
|
3623
3627
|
.command('tui')
|
|
3624
|
-
.description('Start the headless
|
|
3628
|
+
.description('Start the headless terminal repair / audit / approval surface for OpenClaw hosts')
|
|
3625
3629
|
.option('--once', 'Print one snapshot and exit')
|
|
3626
3630
|
.option('--refresh-ms <ms>', 'Refresh interval in interactive mode', '2000')
|
|
3627
3631
|
.option('--profile <name>', 'Use profile from ~/.pingagent/<name>')
|
|
@@ -3636,7 +3640,7 @@ host
|
|
|
3636
3640
|
|
|
3637
3641
|
program
|
|
3638
3642
|
.command('web')
|
|
3639
|
-
.description('Start the Host Panel
|
|
3643
|
+
.description('Start the Host Panel GUI for repair, audit, approvals, and advanced runtime inspection. Use pingagent host tui for headless operation.')
|
|
3640
3644
|
.option('--port <port>', 'Port for the web server', '3846')
|
|
3641
3645
|
.action(async (opts) => {
|
|
3642
3646
|
const serverUrl = process.env.PINGAGENT_SERVER_URL || DEFAULT_SERVER;
|