@wrongstack/cli 0.272.0 → 0.272.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 +369 -70
- package/dist/index.js.map +1 -1
- package/package.json +13 -13
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { color, writeErr, loadPlugins, renderProgress, SpecStore, TaskGraphStore, analyzeCriticalPath, getTemplate, listTemplates, templateToMarkdown, SpecParser, renderSpecAnalysis, AISpecBuilder, expectDefined, DefaultTaskStore, TaskTracker, renderTaskGraph, withFileLock, resolveHqDataDir, ensureHqFirstRunAuthFile, DEFAULT_HQ_REDACTION_POLICY, watchHqAuthFile, parseHqFrame, HQ_PROTOCOL_VERSION, parseHqEventPayload, scrubAndTruncateHqPreview, DefaultSecretScrubber, projectHash, wstackGlobalRoot, TOKENS, ToolRegistry,
|
|
2
|
+
import { color, writeErr, loadPlugins, renderProgress, SpecStore, TaskGraphStore, analyzeCriticalPath, getTemplate, listTemplates, templateToMarkdown, SpecParser, renderSpecAnalysis, AISpecBuilder, expectDefined, DefaultTaskStore, TaskTracker, renderTaskGraph, withFileLock, resolveHqDataDir, ensureHqFirstRunAuthFile, DEFAULT_HQ_REDACTION_POLICY, watchHqAuthFile, parseHqFrame, HQ_PROTOCOL_VERSION, parseHqEventPayload, scrubAndTruncateHqPreview, DefaultSecretScrubber, projectHash, wstackGlobalRoot, TOKENS, ToolRegistry, GlobalMailbox, resolveSessionLoggingConfig, createSessionEventBridge, HookRegistry, HookRunner, normalizeTokenSavingTier, SlashCommandRegistry, attachDepWatcherBridge, SessionMemoryConsolidator, BrainDecisionQueue, ObservableBrainArbiter, HumanEscalatingBrainArbiter, createTieredBrainArbiter, DefaultBrainArbiter, BrainMonitor, mailboxSessionTag, createDelegateTool, FLEET_ROSTER, createMcpControlTool, startTechStackConsumer, startPackageOutdatedWatcher, recordFileAction, createAutonomyBrain, DefaultPluginAPI, SpecVersioning, buildTranscriptFromEvents, DEFAULT_CONTEXT_WINDOW_MODE_ID, resolveProjectDir, recentTextTurns, gatedEnhancerReasoning, enhanceUserPrompt, projectSlug, DefaultSystemPromptBuilder, mutateTasks, loadTasks, resolveContextWindowPolicy, repairToolUseAdjacency, mutatePlan, setPlanItemStatus, getPlanTemplate, loadPlan, emptyPlan, addPlanItem, savePlan, resolveProviderModelList, DefaultLogger, DefaultModelsRegistry, isStdinTTY, atomicWrite, DefaultPathResolver, EventBus, runProviderWithRetry, ReplayLogStore, ReplayProviderRunner, mergeCustomModelDefs, makeAutonomyPromptContributor, createContextManagerTool, makeMailboxTool, makeMailSendTool, makeMailInboxTool, InMemoryMetricsSink, wireMetricsToEvents, DefaultHealthRegistry, startMetricsServer, createHqPublisherFromEnv, DEFAULT_SESSION_PRUNE_DAYS, RecoveryLock, DefaultAttachmentStore, Context, QueueStore, loadTodosCheckpoint, attachTodosCheckpoint, loadDirectorState, createDefaultPipelines, applyModelRuntime, resolveAuditLevel, AutoCompactionMiddleware, estimateRequestTokensCalibrated, Agent, FleetManager, makeDirectorSessionFactory, Director, makeFleetEmitTool, makeFleetStatusTool, AdaptiveConcurrencyController, resolveModelMatrix, DEFAULT_SUBAGENT_BASELINE, AutoApprovePermissionPolicy, WIDE_SUBAGENT_CAPABILITIES, PhaseStore, AutoPhasePlanner, PhaseGraphBuilder, WorktreeManager, PhaseOrchestrator, makeLLMClassifier, writeOut, ParallelEternalEngine, EternalAutonomyEngine, allServers as allServers$1, CHIMERA_REVIEW_PROMPT, setQueuedMessagesSnapshot, DefaultSessionRewinder, bootConfig as bootConfig$1, setOutputLineGuard, setRawMode, DefaultSessionReader, resolveWstackPaths, ToolAuditLog, DefaultSessionStore as DefaultSessionStore$1, ProviderRegistry, StreamHangError, ProviderError, makeAgentSubagentRunner, NULL_FLEET_BUS, buildChildEnv, formatContextWindowModeList, getContextWindowMode, AGENT_CATALOG, dispatchAgent, noOpVault, formatTodosList, formatTaskList, formatTaskProgress, formatPlan, SessionRecovery, loadGoal, goalFilePath, summarizeUsage, saveGoal, formatGoal, emptyGoal, buildGoalPreamble, pendingBtwCount, setBtwNote, readHqRuntimeFileSync, resolveHqConfig, MATRIX_PHASE_KEYS, matrixKeyKind, phaseForRole, onResize, InputBuilder, DefaultSecretVault, decryptConfigSecrets as decryptConfigSecrets$1, encryptConfigSecrets as encryptConfigSecrets$1, HQ_AUTH_FILE_VERSION, FsError, ERROR_CODES, truncate, estimateMessageTokens, AGENTS_BY_PHASE, validateAgainstSchema, ConfigError, resolveMailboxIdentity, AutonomousCoordinator, mutateHqAuthFile, mintHqToken, readHqAuthFile, DefaultTokenCounter, isSecretField as isSecretField$1, startSessionTelemetryBridge } from '@wrongstack/core';
|
|
3
3
|
import * as fs4 from 'fs/promises';
|
|
4
4
|
import { decryptConfigSecrets, encryptConfigSecrets, DefaultSecretVault as DefaultSecretVault$1, isSecretField } from '@wrongstack/core/security';
|
|
5
5
|
import * as path4 from 'path';
|
|
@@ -19,7 +19,7 @@ import { getProcessRegistry, builtinToolsPack, rememberTool, forgetTool, searchM
|
|
|
19
19
|
import { DefaultSessionStore } from '@wrongstack/core/storage';
|
|
20
20
|
import { probeLocalLlm } from '@wrongstack/runtime/probe';
|
|
21
21
|
import * as fs3 from 'fs';
|
|
22
|
-
import { watch, writeFileSync, existsSync, readFileSync } from 'fs';
|
|
22
|
+
import { watch, writeFileSync, existsSync, realpathSync, readFileSync } from 'fs';
|
|
23
23
|
import { SkillInstaller } from '@wrongstack/core/skills';
|
|
24
24
|
import { spawn, execFile, execFileSync } from 'child_process';
|
|
25
25
|
import { MCPRegistry, MCPServer, serveHttp, serveStdio } from '@wrongstack/mcp';
|
|
@@ -3040,6 +3040,8 @@ var init_hq_dashboard_html = __esm({
|
|
|
3040
3040
|
.acard-stream { margin-top: 8px; font-size: 11px; color: var(--muted); background: var(--inset); border: 1px solid var(--border); border-radius: 8px; padding: 6px 8px; font-family: ui-monospace, monospace; max-height: 58px; overflow: hidden; white-space: pre-wrap; word-break: break-word; }
|
|
3041
3041
|
.acard-meta { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 9px; font-size: 10.5px; color: var(--dim); font-variant-numeric: tabular-nums; }
|
|
3042
3042
|
.acard-meta .mut { color: var(--dim); }
|
|
3043
|
+
.acard-meta .warm { color: var(--amber); }
|
|
3044
|
+
.acard-meta .hot { color: var(--red); }
|
|
3043
3045
|
.ctxbar { margin-top: 9px; height: 4px; border-radius: 999px; background: var(--inset); overflow: hidden; }
|
|
3044
3046
|
.ctxbar-fill { height: 100%; background: var(--accent); border-radius: 999px; transition: width 0.3s ease; }
|
|
3045
3047
|
.ctxbar-fill.warm { background: var(--amber); }
|
|
@@ -3082,7 +3084,7 @@ var init_hq_dashboard_html = __esm({
|
|
|
3082
3084
|
.fnode.terminal.k-repl { border-left-color: var(--amber); }
|
|
3083
3085
|
.fnode.terminal.k-webui { border-left-color: var(--accent); }
|
|
3084
3086
|
.fnode.terminal.k-cli { border-left-color: var(--cyan); }
|
|
3085
|
-
.fnode.agent { width:
|
|
3087
|
+
.fnode.agent { width: 220px; }
|
|
3086
3088
|
.fnode.agent.s-running, .fnode.agent.s-streaming { border-color: var(--green); box-shadow: 0 0 0 1px rgba(63,185,80,0.25), 0 10px 22px rgba(0,0,0,0.4); animation: pulse 1.8s ease-in-out infinite; }
|
|
3087
3089
|
.fnode.agent.s-waiting_user { border-color: var(--amber); }
|
|
3088
3090
|
.fnode.agent.s-error { border-color: var(--red); }
|
|
@@ -3164,6 +3166,7 @@ function withTok(p){ var u = new URL(p, location.href); var t = tokenStr(); if (
|
|
|
3164
3166
|
function shortId(s){ if(!s) return '\u2014'; s=String(s); return s.length>16 ? s.slice(0,8)+'\u2026'+s.slice(-5) : s; }
|
|
3165
3167
|
function fmtTime(iso){ if(!iso) return ''; var d=new Date(iso); return isNaN(d.getTime())?'':d.toLocaleTimeString(); }
|
|
3166
3168
|
function fmtAgo(iso){ if(!iso) return ''; var d=new Date(iso).getTime(); if(isNaN(d)) return ''; var s=Math.max(0,Math.floor((Date.now()-d)/1000)); if(s<5) return 'now'; if(s<60) return s+'s ago'; var m=Math.floor(s/60); if(m<60) return m+'m ago'; var hh=Math.floor(m/60); if(hh<24) return hh+'h ago'; return Math.floor(hh/24)+'d ago'; }
|
|
3169
|
+
function fmtElapsed(iso){ if(!iso) return ''; var d=new Date(iso).getTime(); if(isNaN(d)) return ''; var s=Math.max(0,Math.floor((Date.now()-d)/1000)); if(s<60) return s+'s'; var m=Math.floor(s/60); if(m<60) return m+'m '+(s%60)+'s'; var h=Math.floor(m/60); if(h<24) return h+'h '+(m%60)+'m'; return Math.floor(h/24)+'d '+(h%24)+'h'; }
|
|
3167
3170
|
function fmtNum(n){ n=Number(n)||0; if(n>=1e6) return (n/1e6).toFixed(1)+'M'; if(n>=1e3) return (n/1e3).toFixed(1)+'k'; return String(n); }
|
|
3168
3171
|
function esc(s){ if(s==null) return ''; return String(s); }
|
|
3169
3172
|
|
|
@@ -3298,19 +3301,60 @@ function machineKey(hostname, machineId){
|
|
|
3298
3301
|
function buildTree(snap){
|
|
3299
3302
|
var sessions = (snap && snap.liveSessions) || [];
|
|
3300
3303
|
var machines = (snap && snap.machines) || [];
|
|
3304
|
+
var clients = (snap && snap.clients) || [];
|
|
3305
|
+
var projects = (snap && snap.projects) || [];
|
|
3301
3306
|
var mMap = {};
|
|
3307
|
+
var pMap = {};
|
|
3308
|
+
projects.forEach(function(p){ if(p && p.projectId) pMap[p.projectId] = p; });
|
|
3302
3309
|
function ensure(hostname, machineId){
|
|
3303
3310
|
var key = machineKey(hostname, machineId);
|
|
3304
3311
|
if(!mMap[key]) mMap[key] = { key: key, machineId: machineId || key, hostname: (hostname && String(hostname).trim()) || machineId || 'machine', projects: {}, sessionCount: 0, agentCount: 0 };
|
|
3305
3312
|
return mMap[key];
|
|
3306
3313
|
}
|
|
3314
|
+
function ensureProject(mm, pid, seed){
|
|
3315
|
+
if(!mm.projects[pid]) mm.projects[pid] = {
|
|
3316
|
+
projectId: pid,
|
|
3317
|
+
projectName: (seed && (seed.projectName || seed.projectId)) || pid,
|
|
3318
|
+
gitBranch: seed && seed.gitBranch,
|
|
3319
|
+
terminals: []
|
|
3320
|
+
};
|
|
3321
|
+
return mm.projects[pid];
|
|
3322
|
+
}
|
|
3307
3323
|
sessions.forEach(function(s){
|
|
3308
3324
|
var mm = ensure(s.hostname, s.machineId);
|
|
3309
3325
|
mm.sessionCount++;
|
|
3310
3326
|
mm.agentCount += (s.agents ? s.agents.length : 0);
|
|
3311
3327
|
var pid = s.projectId || 'unknown';
|
|
3312
|
-
|
|
3313
|
-
|
|
3328
|
+
ensureProject(mm, pid, s).terminals.push(s);
|
|
3329
|
+
});
|
|
3330
|
+
clients.forEach(function(c){
|
|
3331
|
+
var alreadyRepresented = sessions.some(function(s){
|
|
3332
|
+
return s.projectId === c.projectId &&
|
|
3333
|
+
String(s.clientKind||'') === String(c.kind||'') &&
|
|
3334
|
+
(!c.pid || !s.pid || c.pid === s.pid);
|
|
3335
|
+
});
|
|
3336
|
+
if(alreadyRepresented) return;
|
|
3337
|
+
var project = pMap[c.projectId] || {};
|
|
3338
|
+
var mm = ensure(c.hostname, c.machineId);
|
|
3339
|
+
mm.sessionCount++;
|
|
3340
|
+
var terminal = {
|
|
3341
|
+
sessionId: 'client:' + (c.clientId || c.projectId || 'unknown'),
|
|
3342
|
+
clientKind: c.kind || 'cli',
|
|
3343
|
+
machineId: c.machineId,
|
|
3344
|
+
hostname: c.hostname,
|
|
3345
|
+
projectId: c.projectId || 'unknown',
|
|
3346
|
+
projectName: project.projectName || c.projectId || 'unknown',
|
|
3347
|
+
projectRoot: project.projectRootDisplay || '',
|
|
3348
|
+
gitBranch: project.gitBranch,
|
|
3349
|
+
status: c.connected ? 'active' : 'stale',
|
|
3350
|
+
startedAt: c.connectedAt,
|
|
3351
|
+
lastActivityAt: c.lastSeenAt,
|
|
3352
|
+
pid: c.pid,
|
|
3353
|
+
agentCount: 0,
|
|
3354
|
+
agents: [],
|
|
3355
|
+
synthetic: true
|
|
3356
|
+
};
|
|
3357
|
+
ensureProject(mm, terminal.projectId, terminal).terminals.push(terminal);
|
|
3314
3358
|
});
|
|
3315
3359
|
// Include machines that have a connected client but no live session yet.
|
|
3316
3360
|
machines.forEach(function(m){ ensure(m.hostname, m.machineId); });
|
|
@@ -3379,21 +3423,26 @@ function projNode(id, p, machine){
|
|
|
3379
3423
|
});
|
|
3380
3424
|
}
|
|
3381
3425
|
function termNode(id, t, sel){
|
|
3426
|
+
var synthetic = !!t.synthetic;
|
|
3382
3427
|
return fleetNode(id, 'terminal', {
|
|
3383
3428
|
termKind: t.clientKind, status: t.status, icon: kindIcon(t.clientKind),
|
|
3384
3429
|
label: (t.clientKind||'cli').toUpperCase() + ' \xB7 ' + shortId(t.sessionId),
|
|
3385
|
-
sub: t.status + (t.pid ? (' \xB7 pid '+t.pid) : ''),
|
|
3386
|
-
chips: [ (t.agentCount||(t.agents?t.agents.length:0))+' agents' ],
|
|
3387
|
-
clickable:
|
|
3388
|
-
onClick: function(){ selectSession(t.sessionId); }
|
|
3430
|
+
sub: t.status + (t.pid ? (' \xB7 pid '+t.pid) : '') + (synthetic ? ' \xB7 waiting for session telemetry' : ''),
|
|
3431
|
+
chips: synthetic ? ['connected', '0 agents'] : [ (t.agentCount||(t.agents?t.agents.length:0))+' agents' ],
|
|
3432
|
+
clickable: !synthetic, selected: !synthetic && !!(sel && sel.sessionId === t.sessionId && !sel.agentId),
|
|
3433
|
+
onClick: synthetic ? undefined : function(){ selectSession(t.sessionId); }
|
|
3389
3434
|
});
|
|
3390
3435
|
}
|
|
3391
3436
|
function agentNode(id, a, t, sel){
|
|
3392
3437
|
var chips = [];
|
|
3438
|
+
var ctx = typeof a.ctxPct==='number' ? Math.max(0, Math.min(100, a.ctxPct)) : null;
|
|
3439
|
+
var active = a.status==='running'||a.status==='streaming'||a.status==='waiting_user';
|
|
3393
3440
|
if(a.currentTool) chips.push('\u2699 '+a.currentTool);
|
|
3441
|
+
if(a.model) chips.push(a.model);
|
|
3442
|
+
if(ctx!=null) chips.push('ctx '+ctx+'%');
|
|
3443
|
+
if(a.startedAt) chips.push((active?'run ':'last ')+fmtElapsed(a.startedAt));
|
|
3394
3444
|
chips.push((a.iterations||0)+' it');
|
|
3395
3445
|
if(typeof a.costUsd === 'number' && a.costUsd > 0) chips.push('$'+a.costUsd.toFixed(2));
|
|
3396
|
-
if(a.model) chips.push(a.model);
|
|
3397
3446
|
return fleetNode(id, 'agent', {
|
|
3398
3447
|
status: a.status, label: a.name || a.id,
|
|
3399
3448
|
sub: a.status + (a.partialText ? (' \xB7 '+String(a.partialText).slice(0,44)) : ''),
|
|
@@ -3406,7 +3455,7 @@ function kindIcon(k){ return k==='tui'?'\u{1F5B3}':k==='webui'?'\u{1F310}':k==='
|
|
|
3406
3455
|
function miniColor(n){ var k=n.data&&n.data.kind; return k==='machine'?'#a371f7':k==='project'?'#58a6ff':k==='agent'?'#3fb950':'#39d0d8'; }
|
|
3407
3456
|
|
|
3408
3457
|
// Node footprints (width \xD7 height) for dagre sizing.
|
|
3409
|
-
var NODE_SIZE = { machine: [220, 78], project: [220, 78], terminal: [220, 70], agent: [
|
|
3458
|
+
var NODE_SIZE = { machine: [220, 78], project: [220, 78], terminal: [220, 70], agent: [230, 92] };
|
|
3410
3459
|
// Auto-layout the logical nodes into a clean tree using dagre.
|
|
3411
3460
|
function layoutTree(nodes, edges, dir, dagre){
|
|
3412
3461
|
if(!dagre || !nodes.length) return nodes;
|
|
@@ -3702,13 +3751,16 @@ async function boot(){
|
|
|
3702
3751
|
var a = p.a, s = p.s, sel = Store.selected;
|
|
3703
3752
|
var seld = sel && sel.sessionId===s.sessionId && sel.agentId===a.id;
|
|
3704
3753
|
var meta = [];
|
|
3754
|
+
var active = a.status==='running'||a.status==='streaming'||a.status==='waiting_user';
|
|
3755
|
+
var ctx = typeof a.ctxPct==='number' ? Math.max(0, Math.min(100, a.ctxPct)) : null;
|
|
3756
|
+
if(a.model) meta.push(h('span', { key:'md', className:'mut' }, 'model '+a.model));
|
|
3757
|
+
if(ctx!=null) meta.push(h('span', { key:'cx', className: ctx>=85?'hot':ctx>=60?'warm':'mut' }, 'ctx '+ctx+'%'));
|
|
3758
|
+
if(a.startedAt) meta.push(h('span', { key:'rt', className:'mut' }, (active?'run ':'last run ')+fmtElapsed(a.startedAt)));
|
|
3705
3759
|
meta.push(h('span', { key:'it' }, (a.iterations||0)+' it'));
|
|
3706
3760
|
if(a.toolCalls!=null) meta.push(h('span', { key:'tc' }, (a.toolCalls||0)+' tools'));
|
|
3707
3761
|
if(a.tokensIn||a.tokensOut) meta.push(h('span', { key:'tk' }, fmtNum((a.tokensIn||0)+(a.tokensOut||0))+' tok'));
|
|
3708
3762
|
if(typeof a.costUsd==='number' && a.costUsd>0) meta.push(h('span', { key:'co' }, '$'+a.costUsd.toFixed(3)));
|
|
3709
|
-
if(a.model) meta.push(h('span', { key:'md', className:'mut' }, a.model));
|
|
3710
3763
|
if(a.lastActivityAt) meta.push(h('span', { key:'ag', className:'mut' }, fmtAgo(a.lastActivityAt)));
|
|
3711
|
-
var ctx = typeof a.ctxPct==='number' ? Math.max(0, Math.min(100, a.ctxPct)) : null;
|
|
3712
3764
|
return h('div', { className: 'acard s-'+(a.status||'idle')+(seld?' selected':''), onClick: function(){ selectSession(s.sessionId, a.id); } },
|
|
3713
3765
|
h('div', { className: 'acard-top' },
|
|
3714
3766
|
h('span', { className: 'dot '+(a.status||'idle') }),
|
|
@@ -3832,6 +3884,10 @@ async function boot(){
|
|
|
3832
3884
|
var streaming = ag && (ag.status==='streaming' || ag.status==='running');
|
|
3833
3885
|
var liveText = streaming && ag.partialText ? String(ag.partialText) : '';
|
|
3834
3886
|
var liveTool = streaming && ag.currentTool ? ag.currentTool : '';
|
|
3887
|
+
var agBits = [];
|
|
3888
|
+
if(ag && ag.model) agBits.push('model '+ag.model);
|
|
3889
|
+
if(ag && typeof ag.ctxPct==='number') agBits.push('ctx '+Math.max(0, Math.min(100, ag.ctxPct))+'%');
|
|
3890
|
+
if(ag && ag.startedAt) agBits.push((streaming?'run ':'last run ')+fmtElapsed(ag.startedAt));
|
|
3835
3891
|
|
|
3836
3892
|
// Keep pinned to the bottom while new content streams in, unless the user
|
|
3837
3893
|
// has scrolled up to read history.
|
|
@@ -3840,7 +3896,8 @@ async function boot(){
|
|
|
3840
3896
|
}, [entries.length, liveText, liveTool, sel && sel.sessionId, sel && sel.agentId]);
|
|
3841
3897
|
function onScroll(){ var el = bodyRef.current; if(!el) return; stickRef.current = (el.scrollHeight - el.scrollTop - el.clientHeight) < 40; }
|
|
3842
3898
|
|
|
3843
|
-
var
|
|
3899
|
+
var baseMeta = isSub ? (entries.length + ' messages' + (streaming?' \xB7 live':'')) : ((tc && tc.total!=null ? (tc.total+' turns') : '') + (tc && tc.source ? (' \xB7 '+tc.source) : ''));
|
|
3900
|
+
var metaText = (agBits.length ? (agBits.join(' \xB7 ') + (baseMeta ? ' \xB7 ' : '')) : '') + baseMeta;
|
|
3844
3901
|
var bodyEls = [];
|
|
3845
3902
|
if(!isSub && tc && tc.loading && !entries.length && !liveText){ bodyEls.push(h('div', { key:'l', className: 'loading' }, 'Loading full chat history\u2026')); }
|
|
3846
3903
|
else if(!entries.length && !liveText){ bodyEls.push(h('div', { key:'e', className: 'side-empty' }, isSub ? ('No messages from ' + (ag?ag.name:'this subagent') + ' yet \u2014 its conversation streams here live as it works.') : ((tc&&tc.error)?'Could not load history.':'No transcript yet for this terminal.'))); }
|
|
@@ -3937,9 +3994,15 @@ function renderFallback(){
|
|
|
3937
3994
|
html += '<div style="margin:6px 0 4px;color:var(--accent)">\u{1F4C1} '+escAttr(p.projectName)+(p.gitBranch?(' \u2387 '+escAttr(p.gitBranch)):'')+'</div>';
|
|
3938
3995
|
p.terminals.forEach(function(term){
|
|
3939
3996
|
html += '<div style="margin:2px 0 2px 14px">';
|
|
3940
|
-
html += '<
|
|
3997
|
+
if(term.synthetic) html += '<span style="color:var(--cyan)">\u25B7 '+escAttr((term.clientKind||'cli').toUpperCase())+' \xB7 '+escAttr(shortId(term.sessionId))+'</span> <span class="pill">'+escAttr(term.status)+'</span> <span class="pill">waiting for session telemetry</span>';
|
|
3998
|
+
else html += '<a href="#" data-sid="'+escAttr(term.sessionId)+'" style="color:var(--cyan);text-decoration:none">\u25B7 '+escAttr((term.clientKind||'cli').toUpperCase())+' \xB7 '+escAttr(shortId(term.sessionId))+'</a> <span class="pill">'+escAttr(term.status)+'</span>';
|
|
3941
3999
|
(term.agents||[]).forEach(function(a){
|
|
3942
|
-
|
|
4000
|
+
var active = a.status==='running'||a.status==='streaming'||a.status==='waiting_user';
|
|
4001
|
+
var extra = '';
|
|
4002
|
+
if(a.model) extra += ' <span class="pill">model '+escAttr(a.model)+'</span>';
|
|
4003
|
+
if(typeof a.ctxPct==='number') extra += ' <span class="pill">ctx '+escAttr(Math.max(0, Math.min(100, a.ctxPct)))+'%</span>';
|
|
4004
|
+
if(a.startedAt) extra += ' <span class="pill">'+escAttr(active?'run ':'last ')+escAttr(fmtElapsed(a.startedAt))+'</span>';
|
|
4005
|
+
html += '<div style="margin-left:22px;color:var(--muted)"><a href="#" data-sid="'+escAttr(term.sessionId)+'" data-aid="'+escAttr(a.id)+'" style="color:var(--text);text-decoration:none"><span class="dot '+escAttr(a.status||'idle')+'"></span> '+escAttr(a.name||a.id)+'</a> <span class="pill">'+escAttr(a.status)+'</span>'+(a.currentTool?(' <span class="pill">\u2699 '+escAttr(a.currentTool)+'</span>'):'')+extra+'</div>';
|
|
3943
4006
|
});
|
|
3944
4007
|
html += '</div>';
|
|
3945
4008
|
});
|
|
@@ -5058,6 +5121,70 @@ var init_update_check = __esm({
|
|
|
5058
5121
|
CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
5059
5122
|
}
|
|
5060
5123
|
});
|
|
5124
|
+
function nodeWsSocketFactory(url) {
|
|
5125
|
+
return new WebSocket(url);
|
|
5126
|
+
}
|
|
5127
|
+
function createCliHqPublisher(options) {
|
|
5128
|
+
return createHqPublisherFromEnv({
|
|
5129
|
+
...options,
|
|
5130
|
+
socketFactory: options.socketFactory ?? nodeWsSocketFactory
|
|
5131
|
+
});
|
|
5132
|
+
}
|
|
5133
|
+
function hqExplicitlyDisabled(options) {
|
|
5134
|
+
const envEnabled = process.env["WRONGSTACK_HQ_ENABLED"]?.trim();
|
|
5135
|
+
if (envEnabled !== void 0 && envEnabled.length > 0) return envEnabled === "0";
|
|
5136
|
+
if (options.config?.enabled !== void 0) return options.config.enabled === false;
|
|
5137
|
+
return options.appConfig?.hq?.enabled === false;
|
|
5138
|
+
}
|
|
5139
|
+
function resolvedHqConnectionKey(options) {
|
|
5140
|
+
if (options.config !== void 0) {
|
|
5141
|
+
return options.config.enabled === false ? void 0 : `${options.config.url}
|
|
5142
|
+
${options.config.token ?? ""}`;
|
|
5143
|
+
}
|
|
5144
|
+
const config = resolveHqConfig({ config: options.appConfig?.hq });
|
|
5145
|
+
return config === void 0 ? void 0 : `${config.url}
|
|
5146
|
+
${config.token ?? ""}`;
|
|
5147
|
+
}
|
|
5148
|
+
function startCliHqConnection(options) {
|
|
5149
|
+
let publisher;
|
|
5150
|
+
let publisherKey;
|
|
5151
|
+
let timer;
|
|
5152
|
+
const tryConnect = () => {
|
|
5153
|
+
const nextKey = resolvedHqConnectionKey(options);
|
|
5154
|
+
if (nextKey === void 0) return;
|
|
5155
|
+
if (publisher !== void 0 && publisherKey === nextKey) return;
|
|
5156
|
+
publisher?.close();
|
|
5157
|
+
publisher = void 0;
|
|
5158
|
+
publisherKey = void 0;
|
|
5159
|
+
const next = createCliHqPublisher(options);
|
|
5160
|
+
if (next === void 0) return;
|
|
5161
|
+
publisher = next;
|
|
5162
|
+
publisherKey = nextKey;
|
|
5163
|
+
next.connect();
|
|
5164
|
+
options.onConnect?.(next);
|
|
5165
|
+
};
|
|
5166
|
+
tryConnect();
|
|
5167
|
+
if (!hqExplicitlyDisabled(options)) {
|
|
5168
|
+
timer = setInterval(tryConnect, options.retryIntervalMs ?? 2500);
|
|
5169
|
+
timer.unref?.();
|
|
5170
|
+
}
|
|
5171
|
+
return {
|
|
5172
|
+
getPublisher: () => publisher,
|
|
5173
|
+
stop: () => {
|
|
5174
|
+
if (timer !== void 0) {
|
|
5175
|
+
clearInterval(timer);
|
|
5176
|
+
timer = void 0;
|
|
5177
|
+
}
|
|
5178
|
+
publisher?.close();
|
|
5179
|
+
publisher = void 0;
|
|
5180
|
+
publisherKey = void 0;
|
|
5181
|
+
}
|
|
5182
|
+
};
|
|
5183
|
+
}
|
|
5184
|
+
var init_hq_publisher = __esm({
|
|
5185
|
+
"src/hq-publisher.ts"() {
|
|
5186
|
+
}
|
|
5187
|
+
});
|
|
5061
5188
|
|
|
5062
5189
|
// src/webui-server/cost-helpers.ts
|
|
5063
5190
|
function getCostRates(model) {
|
|
@@ -7168,33 +7295,40 @@ async function runWebUI(opts) {
|
|
|
7168
7295
|
let webuiClientId = null;
|
|
7169
7296
|
let webuiHeartbeatTimer = null;
|
|
7170
7297
|
let stopWebuiHqBridge;
|
|
7298
|
+
let webuiHqConnection;
|
|
7171
7299
|
const CLIENT_HEARTBEAT_MS = 15e3;
|
|
7172
7300
|
const registerWebuiClient = async () => {
|
|
7173
7301
|
if (!opts.projectRoot) return null;
|
|
7174
7302
|
try {
|
|
7175
|
-
const
|
|
7176
|
-
const
|
|
7177
|
-
|
|
7178
|
-
|
|
7179
|
-
|
|
7180
|
-
|
|
7181
|
-
|
|
7182
|
-
|
|
7183
|
-
|
|
7184
|
-
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7303
|
+
const projectRoot = opts.projectRoot;
|
|
7304
|
+
const projectDir = resolveProjectDir(projectRoot, wstackGlobalRoot());
|
|
7305
|
+
webuiHqConnection = startCliHqConnection({
|
|
7306
|
+
clientKind: "webui",
|
|
7307
|
+
projectRoot,
|
|
7308
|
+
projectName: path4.basename(projectRoot),
|
|
7309
|
+
appConfig: opts.appConfig,
|
|
7310
|
+
onConnect: (publisher) => {
|
|
7311
|
+
stopWebuiHqBridge?.();
|
|
7312
|
+
stopWebuiHqBridge = void 0;
|
|
7313
|
+
void import('@wrongstack/core').then(({ startSessionTelemetryBridge: startSessionTelemetryBridge2 }) => {
|
|
7314
|
+
stopWebuiHqBridge = startSessionTelemetryBridge2({
|
|
7315
|
+
publisher,
|
|
7316
|
+
events: opts.events,
|
|
7317
|
+
sessionId: opts.session.id,
|
|
7318
|
+
projectRoot,
|
|
7319
|
+
projectName: path4.basename(projectRoot),
|
|
7320
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7321
|
+
});
|
|
7322
|
+
}).catch(() => {
|
|
7188
7323
|
});
|
|
7189
|
-
} catch {
|
|
7190
7324
|
}
|
|
7191
|
-
}
|
|
7192
|
-
const mailbox = new GlobalMailbox(projectDir, opts.events,
|
|
7325
|
+
});
|
|
7326
|
+
const mailbox = new GlobalMailbox(projectDir, opts.events, () => webuiHqConnection?.getPublisher());
|
|
7193
7327
|
webuiClientId = `webui@${crypto2.randomUUID().slice(0, 8)}`;
|
|
7194
7328
|
const projectName = opts.projectRoot ? path4.basename(opts.projectRoot) : "unknown";
|
|
7195
7329
|
await mailbox.registerClient({
|
|
7196
7330
|
clientId: webuiClientId,
|
|
7197
|
-
sessionId:
|
|
7331
|
+
sessionId: projectRoot,
|
|
7198
7332
|
name: `WebUI [${projectName}]`,
|
|
7199
7333
|
source: "webui",
|
|
7200
7334
|
pid: process.pid
|
|
@@ -7218,6 +7352,8 @@ async function runWebUI(opts) {
|
|
|
7218
7352
|
stopWebuiHqBridge();
|
|
7219
7353
|
stopWebuiHqBridge = void 0;
|
|
7220
7354
|
}
|
|
7355
|
+
webuiHqConnection?.stop();
|
|
7356
|
+
webuiHqConnection = void 0;
|
|
7221
7357
|
};
|
|
7222
7358
|
registerWebuiClient();
|
|
7223
7359
|
const wsToken = generateAuthToken();
|
|
@@ -8768,6 +8904,7 @@ ${text}` : text;
|
|
|
8768
8904
|
}
|
|
8769
8905
|
var init_webui_server = __esm({
|
|
8770
8906
|
"src/webui-server.ts"() {
|
|
8907
|
+
init_hq_publisher();
|
|
8771
8908
|
init_cost_helpers();
|
|
8772
8909
|
init_prefs_seeding();
|
|
8773
8910
|
init_lifecycle();
|
|
@@ -22430,8 +22567,8 @@ function startLoopbackServer(expectedState) {
|
|
|
22430
22567
|
function openBrowser(url) {
|
|
22431
22568
|
try {
|
|
22432
22569
|
const platform3 = process.platform;
|
|
22433
|
-
const { command, args } = platform3 === "win32" ? { command: "cmd", args: ["/c", "start", "", url] } : platform3 === "darwin" ? { command: "open", args: [url] } : { command: "xdg-open", args: [url] };
|
|
22434
|
-
const child = spawn(
|
|
22570
|
+
const { command: command2, args } = platform3 === "win32" ? { command: "cmd", args: ["/c", "start", "", url] } : platform3 === "darwin" ? { command: "open", args: [url] } : { command: "xdg-open", args: [url] };
|
|
22571
|
+
const child = spawn(command2, args, { stdio: "ignore", windowsHide: true });
|
|
22435
22572
|
child.on("error", () => {
|
|
22436
22573
|
});
|
|
22437
22574
|
child.unref();
|
|
@@ -22563,8 +22700,8 @@ var COPILOT_PROVIDER_ID = "github-copilot";
|
|
|
22563
22700
|
function openBrowser2(url) {
|
|
22564
22701
|
try {
|
|
22565
22702
|
const platform3 = process.platform;
|
|
22566
|
-
const { command, args } = platform3 === "win32" ? { command: "cmd", args: ["/c", "start", "", url] } : platform3 === "darwin" ? { command: "open", args: [url] } : { command: "xdg-open", args: [url] };
|
|
22567
|
-
const child = spawn(
|
|
22703
|
+
const { command: command2, args } = platform3 === "win32" ? { command: "cmd", args: ["/c", "start", "", url] } : platform3 === "darwin" ? { command: "open", args: [url] } : { command: "xdg-open", args: [url] };
|
|
22704
|
+
const child = spawn(command2, args, { stdio: "ignore", windowsHide: true });
|
|
22568
22705
|
child.on("error", () => {
|
|
22569
22706
|
});
|
|
22570
22707
|
child.unref();
|
|
@@ -22931,8 +23068,8 @@ function startLoopbackServer2(state) {
|
|
|
22931
23068
|
function openBrowser3(url) {
|
|
22932
23069
|
try {
|
|
22933
23070
|
const platform3 = process.platform;
|
|
22934
|
-
const { command, args } = platform3 === "win32" ? { command: "cmd", args: ["/c", "start", "", url] } : platform3 === "darwin" ? { command: "open", args: [url] } : { command: "xdg-open", args: [url] };
|
|
22935
|
-
const child = spawn(
|
|
23071
|
+
const { command: command2, args } = platform3 === "win32" ? { command: "cmd", args: ["/c", "start", "", url] } : platform3 === "darwin" ? { command: "open", args: [url] } : { command: "xdg-open", args: [url] };
|
|
23072
|
+
const child = spawn(command2, args, { stdio: "ignore", windowsHide: true });
|
|
22936
23073
|
child.on("error", () => {
|
|
22937
23074
|
});
|
|
22938
23075
|
child.unref();
|
|
@@ -26858,9 +26995,15 @@ var skillsCmd = async (_args, deps) => {
|
|
|
26858
26995
|
init_update_check();
|
|
26859
26996
|
var updateCmd = async (args, deps) => {
|
|
26860
26997
|
const cwd = deps.cwd;
|
|
26861
|
-
const
|
|
26998
|
+
const parsed = parseUpdateArgs(args);
|
|
26999
|
+
if (parsed.error) {
|
|
27000
|
+
deps.renderer.write(`${parsed.error}
|
|
27001
|
+
`);
|
|
27002
|
+
deps.renderer.write("Usage: wrongstack update [--check-only] [--pm npm|pnpm|yarn|bun]\n");
|
|
27003
|
+
return 1;
|
|
27004
|
+
}
|
|
26862
27005
|
const info = await checkForUpdate();
|
|
26863
|
-
if (checkOnly) {
|
|
27006
|
+
if (parsed.checkOnly) {
|
|
26864
27007
|
if (info.outdated) {
|
|
26865
27008
|
deps.renderer.write(`Update available: v${info.current} \u2192 v${info.latest}
|
|
26866
27009
|
`);
|
|
@@ -26875,40 +27018,58 @@ var updateCmd = async (args, deps) => {
|
|
|
26875
27018
|
`);
|
|
26876
27019
|
return 0;
|
|
26877
27020
|
}
|
|
27021
|
+
const packageManager = parsed.packageManager ?? detectUpdatePackageManager();
|
|
27022
|
+
const updateCommand = buildUpdateCommand(packageManager);
|
|
26878
27023
|
deps.renderer.write(`Updating wrongstack from v${info.current} to v${info.latest}...
|
|
27024
|
+
`);
|
|
27025
|
+
deps.renderer.write(`Running: ${updateCommand.display}
|
|
26879
27026
|
`);
|
|
26880
27027
|
try {
|
|
26881
|
-
const result = await new Promise(
|
|
26882
|
-
|
|
26883
|
-
|
|
26884
|
-
|
|
26885
|
-
|
|
26886
|
-
|
|
26887
|
-
|
|
26888
|
-
|
|
26889
|
-
|
|
26890
|
-
|
|
26891
|
-
|
|
26892
|
-
|
|
26893
|
-
|
|
26894
|
-
|
|
26895
|
-
|
|
27028
|
+
const result = await new Promise(
|
|
27029
|
+
(resolve13, reject) => {
|
|
27030
|
+
const child = spawn(updateCommand.executable, updateCommand.args, {
|
|
27031
|
+
cwd,
|
|
27032
|
+
stdio: "pipe",
|
|
27033
|
+
signal: AbortSignal.timeout(12e4),
|
|
27034
|
+
windowsHide: true
|
|
27035
|
+
});
|
|
27036
|
+
let stdout = "";
|
|
27037
|
+
let stderr = "";
|
|
27038
|
+
child.stdout?.on("data", (d) => {
|
|
27039
|
+
stdout += d;
|
|
27040
|
+
});
|
|
27041
|
+
child.stderr?.on("data", (d) => {
|
|
27042
|
+
stderr += d;
|
|
27043
|
+
});
|
|
27044
|
+
child.on("error", reject);
|
|
27045
|
+
child.on("close", (code) => resolve13({ code: code ?? 0, stdout, stderr }));
|
|
27046
|
+
}
|
|
27047
|
+
);
|
|
26896
27048
|
if (result.code === 0) {
|
|
26897
27049
|
deps.renderer.write(
|
|
26898
27050
|
`
|
|
26899
27051
|
Updated to v${info.latest}. Restart wrongstack to use the new version.
|
|
26900
27052
|
`
|
|
26901
27053
|
);
|
|
27054
|
+
const warning = installWarningSummary(`${result.stderr}
|
|
27055
|
+
${result.stdout}`);
|
|
27056
|
+
if (warning) deps.renderer.write(`
|
|
27057
|
+
${warning}
|
|
27058
|
+
`);
|
|
26902
27059
|
} else {
|
|
26903
27060
|
deps.renderer.write(`
|
|
26904
27061
|
Update failed with exit code ${result.code}.
|
|
26905
27062
|
`);
|
|
26906
|
-
const detail = result.stderr
|
|
27063
|
+
const detail = `${result.stderr}
|
|
27064
|
+
${result.stdout}`.trim();
|
|
26907
27065
|
if (detail) deps.renderer.write(`
|
|
26908
27066
|
${detail}
|
|
26909
27067
|
`);
|
|
26910
27068
|
deps.renderer.write(
|
|
26911
|
-
|
|
27069
|
+
`
|
|
27070
|
+
Try the matching global update command manually:
|
|
27071
|
+
${updateCommand.display}
|
|
27072
|
+
` + otherManagerCommands(packageManager)
|
|
26912
27073
|
);
|
|
26913
27074
|
}
|
|
26914
27075
|
return result.code;
|
|
@@ -26916,7 +27077,7 @@ ${detail}
|
|
|
26916
27077
|
const msg = err instanceof Error ? err.message : String(err);
|
|
26917
27078
|
if (msg.includes("ENOENT")) {
|
|
26918
27079
|
deps.renderer.write(`
|
|
26919
|
-
Update failed:
|
|
27080
|
+
Update failed: ${packageManager} not found in PATH.
|
|
26920
27081
|
`);
|
|
26921
27082
|
return 1;
|
|
26922
27083
|
}
|
|
@@ -26926,6 +27087,100 @@ Update failed: ${msg}
|
|
|
26926
27087
|
return 1;
|
|
26927
27088
|
}
|
|
26928
27089
|
};
|
|
27090
|
+
function parseUpdateArgs(args) {
|
|
27091
|
+
let checkOnly = false;
|
|
27092
|
+
let packageManager;
|
|
27093
|
+
for (let i = 0; i < args.length; i++) {
|
|
27094
|
+
const arg = args[i];
|
|
27095
|
+
if (arg === void 0) continue;
|
|
27096
|
+
if (arg === "--check-only" || arg === "-c") {
|
|
27097
|
+
checkOnly = true;
|
|
27098
|
+
continue;
|
|
27099
|
+
}
|
|
27100
|
+
if (arg === "--pm" || arg === "--package-manager") {
|
|
27101
|
+
const value = args[++i];
|
|
27102
|
+
const pm = parsePackageManager(value);
|
|
27103
|
+
if (!pm)
|
|
27104
|
+
return {
|
|
27105
|
+
checkOnly,
|
|
27106
|
+
packageManager,
|
|
27107
|
+
error: `Invalid package manager: ${value ?? "<missing>"}`
|
|
27108
|
+
};
|
|
27109
|
+
packageManager = pm;
|
|
27110
|
+
continue;
|
|
27111
|
+
}
|
|
27112
|
+
const pmEq = arg.match(/^--(?:pm|package-manager)=(.+)$/)?.[1];
|
|
27113
|
+
if (pmEq) {
|
|
27114
|
+
const pm = parsePackageManager(pmEq);
|
|
27115
|
+
if (!pm) return { checkOnly, packageManager, error: `Invalid package manager: ${pmEq}` };
|
|
27116
|
+
packageManager = pm;
|
|
27117
|
+
continue;
|
|
27118
|
+
}
|
|
27119
|
+
const shorthand = arg.match(/^--(npm|pnpm|yarn|bun)$/)?.[1];
|
|
27120
|
+
if (shorthand) {
|
|
27121
|
+
packageManager = shorthand;
|
|
27122
|
+
}
|
|
27123
|
+
}
|
|
27124
|
+
return { checkOnly, packageManager, error: void 0 };
|
|
27125
|
+
}
|
|
27126
|
+
function parsePackageManager(value) {
|
|
27127
|
+
if (value === "npm" || value === "pnpm" || value === "yarn" || value === "bun") return value;
|
|
27128
|
+
return void 0;
|
|
27129
|
+
}
|
|
27130
|
+
function detectUpdatePackageManager(env = process.env, argv = process.argv) {
|
|
27131
|
+
const forced = parsePackageManager(env.WRONGSTACK_UPDATE_PM);
|
|
27132
|
+
if (forced) return forced;
|
|
27133
|
+
const userAgent = env.npm_config_user_agent ?? "";
|
|
27134
|
+
if (/\bpnpm\//i.test(userAgent)) return "pnpm";
|
|
27135
|
+
if (/\byarn\//i.test(userAgent)) return "yarn";
|
|
27136
|
+
if (/\bbun\//i.test(userAgent)) return "bun";
|
|
27137
|
+
if (/\bnpm\//i.test(userAgent)) return "npm";
|
|
27138
|
+
const execPath = `${env.npm_execpath ?? ""} ${argv[1] ?? ""}`;
|
|
27139
|
+
const realPaths = [env.npm_execpath, argv[1]].filter((p) => typeof p === "string" && p.length > 0).map((p) => {
|
|
27140
|
+
try {
|
|
27141
|
+
return existsSync(p) ? realpathSync(p) : p;
|
|
27142
|
+
} catch {
|
|
27143
|
+
return p;
|
|
27144
|
+
}
|
|
27145
|
+
}).join(" ");
|
|
27146
|
+
const hint = `${execPath} ${realPaths}`.replace(/\\/g, "/").toLowerCase();
|
|
27147
|
+
if (hint.includes("/pnpm/") || hint.includes("/.pnpm/") || hint.includes("pnpm-global"))
|
|
27148
|
+
return "pnpm";
|
|
27149
|
+
if (hint.includes("/yarn/") || hint.includes("/.yarn/")) return "yarn";
|
|
27150
|
+
if (hint.includes("/bun/") || hint.includes("/.bun/")) return "bun";
|
|
27151
|
+
return "npm";
|
|
27152
|
+
}
|
|
27153
|
+
function buildUpdateCommand(packageManager) {
|
|
27154
|
+
switch (packageManager) {
|
|
27155
|
+
case "pnpm":
|
|
27156
|
+
return command(packageManager, ["add", "-g", "wrongstack@latest"]);
|
|
27157
|
+
case "yarn":
|
|
27158
|
+
return command(packageManager, ["global", "add", "wrongstack@latest"]);
|
|
27159
|
+
case "bun":
|
|
27160
|
+
return command(packageManager, ["add", "-g", "wrongstack@latest"]);
|
|
27161
|
+
case "npm":
|
|
27162
|
+
return command(packageManager, ["install", "-g", "wrongstack@latest"]);
|
|
27163
|
+
}
|
|
27164
|
+
}
|
|
27165
|
+
function command(pm, args) {
|
|
27166
|
+
const executable = process.platform === "win32" && pm !== "bun" ? `${pm}.cmd` : pm;
|
|
27167
|
+
return {
|
|
27168
|
+
executable,
|
|
27169
|
+
args,
|
|
27170
|
+
display: `${pm} ${args.join(" ")}`
|
|
27171
|
+
};
|
|
27172
|
+
}
|
|
27173
|
+
function otherManagerCommands(selected) {
|
|
27174
|
+
const commands = ["npm", "pnpm", "yarn", "bun"].filter((pm) => pm !== selected).map((pm) => ` ${buildUpdateCommand(pm).display}`);
|
|
27175
|
+
return commands.length > 0 ? `
|
|
27176
|
+
Other package managers:
|
|
27177
|
+
${commands.join("\n")}
|
|
27178
|
+
` : "";
|
|
27179
|
+
}
|
|
27180
|
+
function installWarningSummary(output) {
|
|
27181
|
+
if (!/allow-scripts|allowScripts/i.test(output)) return null;
|
|
27182
|
+
return "Install completed, but npm reported blocked lifecycle scripts. If a native optional feature is missing, rerun the update with npm script approval for the named package.";
|
|
27183
|
+
}
|
|
26929
27184
|
var versionCmd = async (_args, deps) => {
|
|
26930
27185
|
deps.renderer.write(
|
|
26931
27186
|
`WrongStack ${CLI_VERSION} (apiVersion ${API_VERSION}, node ${process.version}, ${os.platform()})
|
|
@@ -29243,6 +29498,7 @@ async function predictNextTasks(input, opts) {
|
|
|
29243
29498
|
|
|
29244
29499
|
// src/execution.ts
|
|
29245
29500
|
init_provider_config_utils();
|
|
29501
|
+
init_hq_publisher();
|
|
29246
29502
|
init_sdd();
|
|
29247
29503
|
init_utils();
|
|
29248
29504
|
var DEFAULT_MAX_CONSECUTIVE_AUTO_PROCEED = 50;
|
|
@@ -29297,9 +29553,8 @@ async function runRepl(opts) {
|
|
|
29297
29553
|
const replProjectRoot = opts.projectRoot ?? process.cwd();
|
|
29298
29554
|
const projectDir = resolveProjectDir(replProjectRoot, wstackGlobalRoot());
|
|
29299
29555
|
const clientId = `repl@${crypto2.randomUUID().slice(0, 8)}`;
|
|
29300
|
-
const
|
|
29301
|
-
|
|
29302
|
-
const clientMailbox = new GlobalMailbox(projectDir, void 0, hqPublisher);
|
|
29556
|
+
const hqConnection = startCliHqConnection({ clientKind: "repl", projectRoot: replProjectRoot, projectName: path4.basename(replProjectRoot), appConfig: opts.appConfig });
|
|
29557
|
+
const clientMailbox = new GlobalMailbox(projectDir, void 0, () => hqConnection.getPublisher());
|
|
29303
29558
|
let clientHeartbeat;
|
|
29304
29559
|
clientMailbox.registerClient({
|
|
29305
29560
|
clientId,
|
|
@@ -29879,6 +30134,7 @@ ${color.dim(lines)}
|
|
|
29879
30134
|
await opts.reader.close().catch(() => {
|
|
29880
30135
|
});
|
|
29881
30136
|
clearInterval(clientHeartbeat);
|
|
30137
|
+
hqConnection.stop();
|
|
29882
30138
|
opts.onDestroy?.();
|
|
29883
30139
|
}
|
|
29884
30140
|
}
|
|
@@ -30775,6 +31031,9 @@ async function execute(deps) {
|
|
|
30775
31031
|
return code;
|
|
30776
31032
|
}
|
|
30777
31033
|
|
|
31034
|
+
// src/cli-main.ts
|
|
31035
|
+
init_hq_publisher();
|
|
31036
|
+
|
|
30778
31037
|
// src/hooks-wiring.ts
|
|
30779
31038
|
var HookBlockedError = class extends Error {
|
|
30780
31039
|
constructor(reason) {
|
|
@@ -30879,6 +31138,10 @@ var MultiAgentHost = class _MultiAgentHost {
|
|
|
30879
31138
|
acpRunnerCache = /* @__PURE__ */ new Map();
|
|
30880
31139
|
acpRunnerAccessOrder = [];
|
|
30881
31140
|
static ACP_CACHE_MAX = 20;
|
|
31141
|
+
/** Adaptive concurrency controller — created in buildDirector() when config has
|
|
31142
|
+
* adaptiveConcurrency.enabled = true. Monitors FleetBus for 429 errors and
|
|
31143
|
+
* automatically adjusts maxConcurrent to prevent rate limiting. */
|
|
31144
|
+
adaptiveConcurrencyController;
|
|
30882
31145
|
/**
|
|
30883
31146
|
* Force the lazy build path to run *now* and return the live Director,
|
|
30884
31147
|
* or null when director mode is off. Used by the CLI to register the
|
|
@@ -31040,6 +31303,14 @@ var MultiAgentHost = class _MultiAgentHost {
|
|
|
31040
31303
|
this.coordinatorOffHandle = () => coordinator.off("task.assigned", coordinatorTaskAssignedHandler);
|
|
31041
31304
|
this.fleetEmitTool = makeFleetEmitTool(this.director);
|
|
31042
31305
|
this.fleetStatusTool = makeFleetStatusTool(this.director);
|
|
31306
|
+
const adaptiveConfig = this.deps.configStore.get().adaptiveConcurrency;
|
|
31307
|
+
if (adaptiveConfig?.enabled) {
|
|
31308
|
+
this.adaptiveConcurrencyController = new AdaptiveConcurrencyController(
|
|
31309
|
+
this.director.fleet,
|
|
31310
|
+
(n) => coordinator.setMaxConcurrent(n),
|
|
31311
|
+
adaptiveConfig
|
|
31312
|
+
);
|
|
31313
|
+
}
|
|
31043
31314
|
const runner = await this.buildSubagentRunner(config);
|
|
31044
31315
|
if (!this.directorRunnerSet) {
|
|
31045
31316
|
this.getCoordinator().setRunner(runner);
|
|
@@ -31693,6 +31964,8 @@ Start your heartbeat loop now.`,
|
|
|
31693
31964
|
this.directorOffHandles.length = 0;
|
|
31694
31965
|
this.coordinatorOffHandle?.();
|
|
31695
31966
|
this.coordinatorOffHandle = null;
|
|
31967
|
+
this.adaptiveConcurrencyController?.dispose();
|
|
31968
|
+
this.adaptiveConcurrencyController = void 0;
|
|
31696
31969
|
if (this.director) {
|
|
31697
31970
|
await this.director.shutdown();
|
|
31698
31971
|
}
|
|
@@ -32810,7 +33083,7 @@ async function main(argv) {
|
|
|
32810
33083
|
const promptBuilder = container.resolve(TOKENS.SystemPromptBuilder);
|
|
32811
33084
|
let onlineAgents = [];
|
|
32812
33085
|
try {
|
|
32813
|
-
const hqPublisher2 =
|
|
33086
|
+
const hqPublisher2 = createCliHqPublisher({ clientKind: tuiOwnsScreen ? "tui" : "cli", projectRoot, projectName: path4.basename(projectRoot), appConfig: config });
|
|
32814
33087
|
hqPublisher2?.connect();
|
|
32815
33088
|
if (hqPublisher2) teardownHandlers.push(() => hqPublisher2.close());
|
|
32816
33089
|
const systemMailbox = new GlobalMailbox(wpaths.projectDir, void 0, hqPublisher2);
|
|
@@ -33353,19 +33626,45 @@ async function main(argv) {
|
|
|
33353
33626
|
outcome: e.intervened ? "steered the agent" : "observed (no action)"
|
|
33354
33627
|
});
|
|
33355
33628
|
});
|
|
33356
|
-
|
|
33357
|
-
|
|
33358
|
-
|
|
33359
|
-
|
|
33629
|
+
let hqPublisher;
|
|
33630
|
+
let stopHqSessionBridge;
|
|
33631
|
+
const hqConnection = startCliHqConnection({
|
|
33632
|
+
clientKind: tuiOwnsScreen ? "tui" : "cli",
|
|
33633
|
+
projectRoot,
|
|
33634
|
+
projectName: path4.basename(projectRoot),
|
|
33635
|
+
appConfig: config,
|
|
33636
|
+
onConnect: (publisher) => {
|
|
33637
|
+
hqPublisher = publisher;
|
|
33638
|
+
stopHqSessionBridge?.();
|
|
33639
|
+
stopHqSessionBridge = void 0;
|
|
33640
|
+
try {
|
|
33641
|
+
stopHqSessionBridge = startSessionTelemetryBridge({
|
|
33642
|
+
publisher,
|
|
33643
|
+
events,
|
|
33644
|
+
sessionId: session.id,
|
|
33645
|
+
projectRoot,
|
|
33646
|
+
projectName: path4.basename(projectRoot),
|
|
33647
|
+
globalRoot: wpaths.globalRoot,
|
|
33648
|
+
initialAgents: tracker?.getAgents(),
|
|
33649
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
33650
|
+
});
|
|
33651
|
+
} catch {
|
|
33652
|
+
}
|
|
33653
|
+
}
|
|
33654
|
+
});
|
|
33655
|
+
hqPublisher = hqConnection.getPublisher();
|
|
33656
|
+
teardownHandlers.push(() => stopHqSessionBridge?.());
|
|
33657
|
+
teardownHandlers.push(() => hqConnection.stop());
|
|
33658
|
+
if (agentMonitor) {
|
|
33360
33659
|
const offMsg = events.on("agent.timeline.message", (payload) => {
|
|
33361
33660
|
try {
|
|
33362
|
-
hqPublisher
|
|
33661
|
+
hqPublisher?.publishEvent({ type: "agent.message", payload, timestamp: payload.ts });
|
|
33363
33662
|
} catch {
|
|
33364
33663
|
}
|
|
33365
33664
|
});
|
|
33366
33665
|
const offStatus = events.on("agent.status_changed", (payload) => {
|
|
33367
33666
|
try {
|
|
33368
|
-
hqPublisher
|
|
33667
|
+
hqPublisher?.publishEvent({ type: "agent.status", payload, timestamp: payload.ts });
|
|
33369
33668
|
} catch {
|
|
33370
33669
|
}
|
|
33371
33670
|
});
|
|
@@ -33374,7 +33673,7 @@ async function main(argv) {
|
|
|
33374
33673
|
offStatus();
|
|
33375
33674
|
});
|
|
33376
33675
|
}
|
|
33377
|
-
const brainMailbox = new GlobalMailbox(wpaths.projectDir, events, hqPublisher);
|
|
33676
|
+
const brainMailbox = new GlobalMailbox(wpaths.projectDir, events, () => hqPublisher);
|
|
33378
33677
|
const brainMonitor = new BrainMonitor({
|
|
33379
33678
|
events,
|
|
33380
33679
|
brain,
|