@wrongstack/cli 0.273.1 → 0.274.0
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/data/providers.json +47 -0
- package/dist/index.js +291 -136
- package/dist/index.js.map +1 -1
- package/package.json +13 -13
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
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, resolveWstackPaths, projectHash, wstackGlobalRoot, TOKENS, ToolRegistry, GlobalMailbox, resolveSessionLoggingConfig, createSessionEventBridge, HookRegistry, HookRunner, normalizeTokenSavingTier, SlashCommandRegistry, attachDepWatcherBridge, createFallbackModelExtension, SessionMemoryConsolidator, BrainDecisionQueue, ObservableBrainArbiter, HumanEscalatingBrainArbiter, createTieredBrainArbiter, DefaultBrainArbiter, BrainMonitor, mailboxSessionTag, createDelegateTool, FLEET_ROSTER, createMcpControlTool, startTechStackConsumer, startPackageOutdatedWatcher, SddRunRegistry, recordFileAction, createAutonomyBrain, DefaultPluginAPI, SpecVersioning, buildTranscriptFromEvents, DEFAULT_CONTEXT_WINDOW_MODE_ID, resolveProjectDir, DefaultLogger, DefaultModelsRegistry, isStdinTTY, atomicWrite, DefaultPathResolver, EventBus, runProviderWithRetry, ReplayLogStore, ReplayProviderRunner, mergeCustomModelDefs, DefaultSystemPromptBuilder, makeAutonomyPromptContributor, createContextManagerTool, makeMailboxTool, makeMailSendTool, makeMailInboxTool, applyToolDescriptionModes, InMemoryMetricsSink, wireMetricsToEvents, DefaultHealthRegistry, startMetricsServer, createHqPublisherFromEnv, DEFAULT_SESSION_PRUNE_DAYS, RecoveryLock, DefaultAttachmentStore, Context, QueueStore, loadTodosCheckpoint, attachTodosCheckpoint, loadDirectorState, loadPlan, createDefaultPipelines, applyModelRuntime, resolveContextWindowPolicy, resolveAuditLevel, AutoCompactionMiddleware, estimateRequestTokensCalibrated, Agent, FleetManager, makeDirectorSessionFactory, Director, makeFleetEmitTool, AdaptiveConcurrencyController, resolveModelMatrix, DEFAULT_SUBAGENT_BASELINE, DefaultTokenCounter, AutoApprovePermissionPolicy, WIDE_SUBAGENT_CAPABILITIES, PhaseStore, AutoPhasePlanner, PhaseGraphBuilder, WorktreeManager, PhaseOrchestrator, assignNickname, makeLLMClassifier, writeOut, ParallelEternalEngine, EternalAutonomyEngine, allServers as allServers$1, CHIMERA_REVIEW_PROMPT, setQueuedMessagesSnapshot, projectSlug, recentTextTurns, gatedEnhancerReasoning, enhanceUserPrompt, repairToolUseAdjacency, mutateTasks, loadTasks, mutatePlan, setPlanItemStatus, getPlanTemplate, emptyPlan, addPlanItem, savePlan, resolveProviderModelList, bootConfig as bootConfig$1, setOutputLineGuard, setRawMode, DefaultSessionReader, ToolAuditLog, DefaultSessionRewinder, DefaultSessionStore as DefaultSessionStore$1, ProviderRegistry, makeAgentSubagentRunner, NULL_FLEET_BUS, FsError, ERROR_CODES, buildChildEnv, formatContextWindowModeList, getContextWindowMode, AGENT_CATALOG, dispatchAgent, normalizeToolDescriptionMode, setToolDescriptionMode, getToolDescriptionMode, 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, truncate, estimateMessageTokens, AGENTS_BY_PHASE, validateAgainstSchema, ConfigError, resolveMailboxIdentity, smartDefaultFallbackChain, AutonomousCoordinator, mutateHqAuthFile, mintHqToken, readHqAuthFile, isSecretField as isSecretField$1, startSessionTelemetryBridge } from '@wrongstack/core';
|
|
2
|
+
import { color, CODEX_MODELS, 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, resolveWstackPaths, projectHash, wstackGlobalRoot, TOKENS, ToolRegistry, GlobalMailbox, resolveSessionLoggingConfig, createSessionEventBridge, HookRegistry, HookRunner, normalizeTokenSavingTier, SlashCommandRegistry, attachDepWatcherBridge, createFallbackModelExtension, SessionMemoryConsolidator, BrainDecisionQueue, ObservableBrainArbiter, HumanEscalatingBrainArbiter, createTieredBrainArbiter, DefaultBrainArbiter, BrainMonitor, mailboxSessionTag, createDelegateTool, FLEET_ROSTER, createMcpControlTool, startTechStackConsumer, startPackageOutdatedWatcher, SddRunRegistry, recordFileAction, createAutonomyBrain, DefaultPluginAPI, SpecVersioning, buildTranscriptFromEvents, DEFAULT_CONTEXT_WINDOW_MODE_ID, resolveProjectDir, DefaultLogger, DefaultModelsRegistry, isStdinTTY, atomicWrite, DefaultPathResolver, EventBus, runProviderWithRetry, ReplayLogStore, ReplayProviderRunner, mergeCustomModelDefs, DefaultSystemPromptBuilder, makeAutonomyPromptContributor, createContextManagerTool, makeMailboxTool, makeMailSendTool, makeMailInboxTool, applyToolDescriptionModes, InMemoryMetricsSink, wireMetricsToEvents, DefaultHealthRegistry, startMetricsServer, createHqPublisherFromEnv, DEFAULT_SESSION_PRUNE_DAYS, RecoveryLock, DefaultAttachmentStore, Context, QueueStore, loadTodosCheckpoint, attachTodosCheckpoint, loadDirectorState, loadPlan, createDefaultPipelines, applyModelRuntime, resolveContextWindowPolicy, resolveAuditLevel, AutoCompactionMiddleware, estimateRequestTokensCalibrated, Agent, FleetManager, makeDirectorSessionFactory, Director, makeFleetEmitTool, AdaptiveConcurrencyController, resolveModelMatrix, DEFAULT_SUBAGENT_BASELINE, DefaultTokenCounter, AutoApprovePermissionPolicy, WIDE_SUBAGENT_CAPABILITIES, PhaseStore, AutoPhasePlanner, PhaseGraphBuilder, WorktreeManager, PhaseOrchestrator, assignNickname, makeLLMClassifier, writeOut, ParallelEternalEngine, EternalAutonomyEngine, allServers as allServers$1, CHIMERA_REVIEW_PROMPT, setQueuedMessagesSnapshot, projectSlug, recentTextTurns, gatedEnhancerReasoning, enhanceUserPrompt, repairToolUseAdjacency, mutateTasks, loadTasks, mutatePlan, setPlanItemStatus, getPlanTemplate, emptyPlan, addPlanItem, savePlan, resolveProviderModelList, bootConfig as bootConfig$1, setOutputLineGuard, setRawMode, DefaultSessionReader, ToolAuditLog, DefaultSessionRewinder, DefaultSessionStore as DefaultSessionStore$1, ProviderRegistry, makeAgentSubagentRunner, NULL_FLEET_BUS, FsError, ERROR_CODES, buildChildEnv, formatContextWindowModeList, getContextWindowMode, AGENT_CATALOG, dispatchAgent, normalizeToolDescriptionMode, setToolDescriptionMode, getToolDescriptionMode, 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, truncate, estimateMessageTokens, AGENTS_BY_PHASE, validateAgainstSchema, ConfigError, resolveMailboxIdentity, smartDefaultFallbackChain, AutonomousCoordinator, mutateHqAuthFile, mintHqToken, readHqAuthFile, isSecretField as isSecretField$1, startSessionTelemetryBridge } from '@wrongstack/core';
|
|
3
3
|
import * as fs4 from 'fs/promises';
|
|
4
|
+
import { access, readFile } from 'fs/promises';
|
|
4
5
|
import { decryptConfigSecrets, encryptConfigSecrets, DefaultSecretVault as DefaultSecretVault$1, isSecretField } from '@wrongstack/core/security';
|
|
5
6
|
import * as path4 from 'path';
|
|
6
7
|
import { join } from 'path';
|
|
@@ -12,14 +13,14 @@ import * as os7 from 'os';
|
|
|
12
13
|
import os7__default from 'os';
|
|
13
14
|
import { WebSocketServer, WebSocket } from 'ws';
|
|
14
15
|
import { createRequire } from 'module';
|
|
15
|
-
import { findFreePort, AutoPhaseWebSocketHandler, WorktreeWebSocketHandler, SpecsWebSocketHandler, SddBoardWebSocketHandler, SddWizardWebSocketHandler, buildSddWizardDeps,
|
|
16
|
+
import { envFlag, findFreePort, AutoPhaseWebSocketHandler, WorktreeWebSocketHandler, SpecsWebSocketHandler, SddBoardWebSocketHandler, SddWizardWebSocketHandler, buildSddWizardDeps, resolveAuthToken, buildWebUIAccessUrl, verifyClient, createEternalSubscription, handleShellOpen, handleGitInfo, handleGitDiff, handleGitChanges, handleSkillsExport, handleSkillsEdit, handleSkillsCreate, handleSkillsUpdate, handleSkillsUninstall, handleSkillsInstall, handleSkillsContent, handleMcpRestart, handleMcpDisable, handleMcpEnable, handleMcpDiscover, handleMcpSleep, handleMcpWake, handleMcpUpdate, handleMcpRemove, handleMcpAdd, handleMcpList, handleMemoryForget, handleMemoryRemember, handleMemoryList, handleCompletionRequest, createToolLspCompletionSource, handleFilesWrite, handleFilesRead, handleFilesTree, handleFilesList, createHttpServer, registerInstance, openBrowser as openBrowser$1, unregisterInstance, estimateTokens as estimateTokens$1, stringifyContent, messagePreview, messageTokens, createCustomModeStore } from '@wrongstack/webui/server';
|
|
16
17
|
import { toErrorMessage, readJsonObjectFile, updateJsonObjectFile, setJsonPath, jsonObjectFileExists, removeJsonPath } from '@wrongstack/core/utils';
|
|
17
|
-
import { setOAuthTokenPersister, capabilitiesFor, makeProviderFromConfig, buildProviderFactoriesFromRegistry, refreshCopilotToken, copilotBaseUrlFromToken } from '@wrongstack/providers';
|
|
18
|
+
import { setOAuthTokenPersister, capabilitiesFor, makeProviderFromConfig, buildProviderFactoriesFromRegistry, withCatalogCapabilities, refreshCopilotToken, copilotBaseUrlFromToken } from '@wrongstack/providers';
|
|
18
19
|
import { ensureSessionShell, builtinToolsPack, rememberTool, forgetTool, searchMemoryTool, relatedMemoryTool, configureExecPolicy, runStartupIndex, isIndexableFile, enqueueReindex, cancelPendingReindexes, shutdownCodebaseIndexHost, getProcessRegistry, TIER2_TOOLS, TIER3_TOOLS, TIER1_TOOLS, resetIndexCircuitBreaker } from '@wrongstack/tools';
|
|
19
20
|
import { DefaultSessionStore } from '@wrongstack/core/storage';
|
|
20
21
|
import { probeLocalLlm } from '@wrongstack/runtime/probe';
|
|
21
|
-
import * as
|
|
22
|
-
import { watch, writeFileSync, existsSync, realpathSync
|
|
22
|
+
import * as fs37 from 'fs';
|
|
23
|
+
import { watch, writeFileSync, existsSync, realpathSync } from 'fs';
|
|
23
24
|
import { SkillInstaller } from '@wrongstack/core/skills';
|
|
24
25
|
import { spawn, execFile, execFileSync } from 'child_process';
|
|
25
26
|
import { MCPRegistry, MCPServer, serveHttp, serveStdio } from '@wrongstack/mcp';
|
|
@@ -166,7 +167,7 @@ function unknownSubcommand(cmd, valid, name) {
|
|
|
166
167
|
const list = valid.join(", ");
|
|
167
168
|
return name ? `Unknown subcommand "${cmd}" for /${name}. Valid: ${list}.` : `Unknown subcommand "${cmd}". Valid: ${list}.`;
|
|
168
169
|
}
|
|
169
|
-
async function
|
|
170
|
+
async function pathExists2(file) {
|
|
170
171
|
try {
|
|
171
172
|
await fs4.access(file);
|
|
172
173
|
return true;
|
|
@@ -221,10 +222,10 @@ async function detectPackageManager2(root, declared) {
|
|
|
221
222
|
const name = declared.split("@")[0];
|
|
222
223
|
if (name) return name;
|
|
223
224
|
}
|
|
224
|
-
if (await
|
|
225
|
-
if (await
|
|
226
|
-
if (await
|
|
227
|
-
if (await
|
|
225
|
+
if (await pathExists2(path4.join(root, "pnpm-lock.yaml"))) return "pnpm";
|
|
226
|
+
if (await pathExists2(path4.join(root, "bun.lockb"))) return "bun";
|
|
227
|
+
if (await pathExists2(path4.join(root, "bun.lock"))) return "bun";
|
|
228
|
+
if (await pathExists2(path4.join(root, "yarn.lock"))) return "yarn";
|
|
228
229
|
return "npm";
|
|
229
230
|
}
|
|
230
231
|
function hasUsableScript(scripts, name) {
|
|
@@ -299,14 +300,14 @@ async function detectProjectFacts(root) {
|
|
|
299
300
|
} catch {
|
|
300
301
|
}
|
|
301
302
|
try {
|
|
302
|
-
if (!await
|
|
303
|
+
if (!await pathExists2(path4.join(root, "pyproject.toml"))) throw new Error("not python");
|
|
303
304
|
facts.test ??= "pytest";
|
|
304
305
|
facts.lint ??= "ruff check .";
|
|
305
306
|
facts.hints.push("pyproject.toml");
|
|
306
307
|
} catch {
|
|
307
308
|
}
|
|
308
309
|
try {
|
|
309
|
-
if (!await
|
|
310
|
+
if (!await pathExists2(path4.join(root, "go.mod"))) throw new Error("not go");
|
|
310
311
|
facts.build ??= "go build ./...";
|
|
311
312
|
facts.test ??= "go test ./...";
|
|
312
313
|
facts.run ??= "go run .";
|
|
@@ -314,7 +315,7 @@ async function detectProjectFacts(root) {
|
|
|
314
315
|
} catch {
|
|
315
316
|
}
|
|
316
317
|
try {
|
|
317
|
-
if (!await
|
|
318
|
+
if (!await pathExists2(path4.join(root, "Cargo.toml"))) throw new Error("not rust");
|
|
318
319
|
facts.build ??= "cargo build";
|
|
319
320
|
facts.test ??= "cargo test";
|
|
320
321
|
facts.lint ??= "cargo clippy";
|
|
@@ -342,23 +343,23 @@ async function detectProjectFacts(root) {
|
|
|
342
343
|
} catch {
|
|
343
344
|
}
|
|
344
345
|
try {
|
|
345
|
-
if (!await
|
|
346
|
+
if (!await pathExists2(path4.join(root, "pom.xml"))) throw new Error("not maven");
|
|
346
347
|
facts.build ??= "mvn package";
|
|
347
348
|
facts.test ??= "mvn test";
|
|
348
349
|
facts.hints.push("pom.xml");
|
|
349
350
|
} catch {
|
|
350
351
|
}
|
|
351
352
|
try {
|
|
352
|
-
const hasGradle = await
|
|
353
|
+
const hasGradle = await pathExists2(path4.join(root, "build.gradle")) || await pathExists2(path4.join(root, "build.gradle.kts"));
|
|
353
354
|
if (!hasGradle) throw new Error("not gradle");
|
|
354
|
-
const g = await
|
|
355
|
+
const g = await pathExists2(path4.join(root, "gradlew")) ? "./gradlew" : "gradle";
|
|
355
356
|
facts.build ??= `${g} build`;
|
|
356
357
|
facts.test ??= `${g} test`;
|
|
357
358
|
facts.hints.push("Gradle");
|
|
358
359
|
} catch {
|
|
359
360
|
}
|
|
360
361
|
try {
|
|
361
|
-
const hasDotnet = await
|
|
362
|
+
const hasDotnet = await pathExists2(path4.join(root, "global.json")) || await hasRootFileWithSuffix(root, [".csproj", ".fsproj", ".sln"]);
|
|
362
363
|
if (!hasDotnet) throw new Error("not dotnet");
|
|
363
364
|
facts.build ??= "dotnet build";
|
|
364
365
|
facts.test ??= "dotnet test";
|
|
@@ -367,7 +368,7 @@ async function detectProjectFacts(root) {
|
|
|
367
368
|
} catch {
|
|
368
369
|
}
|
|
369
370
|
try {
|
|
370
|
-
if (!await
|
|
371
|
+
if (!await pathExists2(path4.join(root, "mix.exs"))) throw new Error("not elixir");
|
|
371
372
|
facts.build ??= "mix compile";
|
|
372
373
|
facts.test ??= "mix test";
|
|
373
374
|
facts.lint ??= "mix format --check-formatted";
|
|
@@ -376,14 +377,14 @@ async function detectProjectFacts(root) {
|
|
|
376
377
|
} catch {
|
|
377
378
|
}
|
|
378
379
|
try {
|
|
379
|
-
if (!await
|
|
380
|
+
if (!await pathExists2(path4.join(root, "pubspec.yaml"))) throw new Error("not dart");
|
|
380
381
|
facts.test ??= "dart test";
|
|
381
382
|
facts.lint ??= "dart analyze";
|
|
382
383
|
facts.hints.push("pubspec.yaml");
|
|
383
384
|
} catch {
|
|
384
385
|
}
|
|
385
386
|
try {
|
|
386
|
-
const hasDeno = await
|
|
387
|
+
const hasDeno = await pathExists2(path4.join(root, "deno.json")) || await pathExists2(path4.join(root, "deno.jsonc"));
|
|
387
388
|
if (!hasDeno) throw new Error("not deno");
|
|
388
389
|
facts.test ??= "deno test";
|
|
389
390
|
facts.lint ??= "deno lint";
|
|
@@ -391,7 +392,7 @@ async function detectProjectFacts(root) {
|
|
|
391
392
|
} catch {
|
|
392
393
|
}
|
|
393
394
|
try {
|
|
394
|
-
if (!await
|
|
395
|
+
if (!await pathExists2(path4.join(root, "Package.swift"))) throw new Error("not swift");
|
|
395
396
|
facts.build ??= "swift build";
|
|
396
397
|
facts.test ??= "swift test";
|
|
397
398
|
facts.run ??= "swift run";
|
|
@@ -399,20 +400,20 @@ async function detectProjectFacts(root) {
|
|
|
399
400
|
} catch {
|
|
400
401
|
}
|
|
401
402
|
try {
|
|
402
|
-
if (!await
|
|
403
|
-
if (await
|
|
403
|
+
if (!await pathExists2(path4.join(root, "Gemfile"))) throw new Error("not ruby");
|
|
404
|
+
if (await pathExists2(path4.join(root, "Rakefile"))) facts.test ??= "bundle exec rake test";
|
|
404
405
|
facts.hints.push("Gemfile");
|
|
405
406
|
} catch {
|
|
406
407
|
}
|
|
407
408
|
try {
|
|
408
|
-
if (!await
|
|
409
|
+
if (!await pathExists2(path4.join(root, "CMakeLists.txt"))) throw new Error("not cmake");
|
|
409
410
|
facts.build ??= "cmake -B build && cmake --build build";
|
|
410
411
|
facts.test ??= "ctest --test-dir build";
|
|
411
412
|
facts.hints.push("CMakeLists.txt");
|
|
412
413
|
} catch {
|
|
413
414
|
}
|
|
414
415
|
try {
|
|
415
|
-
const hasPip = await
|
|
416
|
+
const hasPip = await pathExists2(path4.join(root, "requirements.txt")) || await pathExists2(path4.join(root, "setup.py")) || await pathExists2(path4.join(root, "setup.cfg"));
|
|
416
417
|
if (!hasPip) throw new Error("not pip");
|
|
417
418
|
facts.test ??= "pytest";
|
|
418
419
|
facts.hints.push("requirements.txt");
|
|
@@ -5521,7 +5522,11 @@ function registerWebuiInstance(p, deps = {}) {
|
|
|
5521
5522
|
projectRoot: p.projectRoot,
|
|
5522
5523
|
projectName: path4.basename(p.projectRoot) || p.projectRoot,
|
|
5523
5524
|
startedAt: p.startedAt,
|
|
5524
|
-
url:
|
|
5525
|
+
url: buildWebUIAccessUrl({
|
|
5526
|
+
host: p.host,
|
|
5527
|
+
port: p.httpPort,
|
|
5528
|
+
publicUrl: p.publicUrl
|
|
5529
|
+
})
|
|
5525
5530
|
},
|
|
5526
5531
|
p.registryBaseDir
|
|
5527
5532
|
).catch(() => {
|
|
@@ -5530,7 +5535,12 @@ function registerWebuiInstance(p, deps = {}) {
|
|
|
5530
5535
|
function announceWebuiReady(p) {
|
|
5531
5536
|
const log = p.log ?? ((m) => console.log(m));
|
|
5532
5537
|
const launch = p.openBrowserFn ?? openBrowser$1;
|
|
5533
|
-
const openUrl =
|
|
5538
|
+
const openUrl = buildWebUIAccessUrl({
|
|
5539
|
+
host: p.host,
|
|
5540
|
+
port: p.httpPort,
|
|
5541
|
+
token: p.wsToken,
|
|
5542
|
+
publicUrl: p.publicUrl
|
|
5543
|
+
});
|
|
5534
5544
|
p.server.on("listening", () => {
|
|
5535
5545
|
log(
|
|
5536
5546
|
`
|
|
@@ -5667,7 +5677,9 @@ function startStaticServe(opts, deps = {}) {
|
|
|
5667
5677
|
wsPort: opts.wsPort,
|
|
5668
5678
|
globalRoot: opts.globalRoot,
|
|
5669
5679
|
onFleetPing: opts.onFleetPing,
|
|
5670
|
-
|
|
5680
|
+
publicWsUrl: opts.publicWsUrl,
|
|
5681
|
+
apiToken: opts.apiToken,
|
|
5682
|
+
requireToken: opts.requireToken
|
|
5671
5683
|
});
|
|
5672
5684
|
server.listen(opts.httpPort, opts.host);
|
|
5673
5685
|
return { server, port: opts.httpPort };
|
|
@@ -7298,7 +7310,10 @@ __export(webui_server_exports, {
|
|
|
7298
7310
|
runWebUI: () => runWebUI
|
|
7299
7311
|
});
|
|
7300
7312
|
async function runWebUI(opts) {
|
|
7301
|
-
const host = "127.0.0.1";
|
|
7313
|
+
const host = opts.host ?? process.env["WEBUI_HOST"] ?? process.env["WS_HOST"] ?? "127.0.0.1";
|
|
7314
|
+
const publicUrl = opts.publicUrl ?? process.env["WEBUI_PUBLIC_URL"];
|
|
7315
|
+
const publicWsUrl = opts.publicWsUrl ?? process.env["WEBUI_PUBLIC_WS_URL"];
|
|
7316
|
+
const requireToken = opts.requireToken ?? envFlag("WEBUI_REQUIRE_TOKEN");
|
|
7302
7317
|
const requestedWsPort = opts.port ?? 3457;
|
|
7303
7318
|
const requestedHttpPort = opts.httpPort ?? 3456;
|
|
7304
7319
|
const strictPort = process.env["WEBUI_STRICT_PORT"] === "1" || process.env["WEBUI_STRICT_PORT"] === "true";
|
|
@@ -7472,7 +7487,21 @@ async function runWebUI(opts) {
|
|
|
7472
7487
|
webuiHqConnection = void 0;
|
|
7473
7488
|
};
|
|
7474
7489
|
registerWebuiClient();
|
|
7475
|
-
const wsToken =
|
|
7490
|
+
const wsToken = resolveAuthToken(opts.accessToken);
|
|
7491
|
+
const publicHostnames = [publicUrl, publicWsUrl].map((value) => {
|
|
7492
|
+
if (!value) return void 0;
|
|
7493
|
+
try {
|
|
7494
|
+
return new URL(value).hostname;
|
|
7495
|
+
} catch {
|
|
7496
|
+
return void 0;
|
|
7497
|
+
}
|
|
7498
|
+
}).filter((value) => Boolean(value));
|
|
7499
|
+
const accessUrl = buildWebUIAccessUrl({
|
|
7500
|
+
host,
|
|
7501
|
+
port: httpPort,
|
|
7502
|
+
token: wsToken,
|
|
7503
|
+
publicUrl
|
|
7504
|
+
});
|
|
7476
7505
|
const wss = new WebSocketServer({ port, host, maxPayload: 1 * 1024 * 1024 });
|
|
7477
7506
|
console.log(`[WebUI] WebSocket server starting on ws://${host}:${port}`);
|
|
7478
7507
|
let fleetBroadcastCli = null;
|
|
@@ -7484,7 +7513,9 @@ async function runWebUI(opts) {
|
|
|
7484
7513
|
onFleetPing: () => {
|
|
7485
7514
|
void fleetBroadcastCli?.();
|
|
7486
7515
|
},
|
|
7487
|
-
|
|
7516
|
+
publicWsUrl,
|
|
7517
|
+
apiToken: wsToken,
|
|
7518
|
+
requireToken
|
|
7488
7519
|
});
|
|
7489
7520
|
if (httpServer) {
|
|
7490
7521
|
announceWebuiReady({
|
|
@@ -7493,7 +7524,8 @@ async function runWebUI(opts) {
|
|
|
7493
7524
|
httpPort,
|
|
7494
7525
|
wsPort,
|
|
7495
7526
|
open: !!opts.open,
|
|
7496
|
-
wsToken
|
|
7527
|
+
wsToken,
|
|
7528
|
+
publicUrl
|
|
7497
7529
|
});
|
|
7498
7530
|
} else {
|
|
7499
7531
|
console.warn(
|
|
@@ -7507,6 +7539,7 @@ async function runWebUI(opts) {
|
|
|
7507
7539
|
host,
|
|
7508
7540
|
httpPort,
|
|
7509
7541
|
wsPort,
|
|
7542
|
+
publicUrl,
|
|
7510
7543
|
projectRoot: opts.projectRoot,
|
|
7511
7544
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7512
7545
|
registryBaseDir
|
|
@@ -8278,7 +8311,7 @@ ${text}` : text;
|
|
|
8278
8311
|
wss.on("listening", () => {
|
|
8279
8312
|
console.log(`[WebUI] WebSocket server running on ws://${host}:${port}`);
|
|
8280
8313
|
setupEvents();
|
|
8281
|
-
opts.onListening?.({ httpPort, wsPort, host });
|
|
8314
|
+
opts.onListening?.({ httpPort, wsPort, host, url: accessUrl });
|
|
8282
8315
|
const globalRoot = opts.globalConfigPath ? path4.dirname(opts.globalConfigPath) : void 0;
|
|
8283
8316
|
if (globalRoot) {
|
|
8284
8317
|
const broadcastSessions = async () => {
|
|
@@ -8348,7 +8381,10 @@ ${text}` : text;
|
|
|
8348
8381
|
remoteAddress: req2.socket.remoteAddress,
|
|
8349
8382
|
cookieHeader: req2.headers.cookie,
|
|
8350
8383
|
wsHost: host,
|
|
8351
|
-
expectedToken: wsToken
|
|
8384
|
+
expectedToken: wsToken,
|
|
8385
|
+
requireToken,
|
|
8386
|
+
allowedHostnames: publicHostnames,
|
|
8387
|
+
allowBrowserUrlToken: Boolean(publicWsUrl)
|
|
8352
8388
|
});
|
|
8353
8389
|
if (!ok) {
|
|
8354
8390
|
ws.close(4003, "Forbidden");
|
|
@@ -8794,6 +8830,14 @@ var init_webui_server = __esm({
|
|
|
8794
8830
|
|
|
8795
8831
|
// src/cli-main.ts
|
|
8796
8832
|
init_provider_config_utils();
|
|
8833
|
+
async function pathExists(p) {
|
|
8834
|
+
try {
|
|
8835
|
+
await access(p);
|
|
8836
|
+
return true;
|
|
8837
|
+
} catch {
|
|
8838
|
+
return false;
|
|
8839
|
+
}
|
|
8840
|
+
}
|
|
8797
8841
|
var DEFAULT_TASK_CONCURRENCY = 2;
|
|
8798
8842
|
function resolveTaskConcurrency() {
|
|
8799
8843
|
const raw = Number.parseInt(process.env["WRONGSTACK_AUTOPHASE_TASK_CONCURRENCY"] ?? "", 10);
|
|
@@ -8909,15 +8953,21 @@ function runCmd(cmd, args, cwd, shell = false) {
|
|
|
8909
8953
|
});
|
|
8910
8954
|
});
|
|
8911
8955
|
}
|
|
8912
|
-
function detectPackageManager(root) {
|
|
8913
|
-
|
|
8914
|
-
|
|
8915
|
-
|
|
8956
|
+
async function detectPackageManager(root) {
|
|
8957
|
+
const [pnpm, yarn, bun] = await Promise.all([
|
|
8958
|
+
pathExists(join(root, "pnpm-lock.yaml")),
|
|
8959
|
+
pathExists(join(root, "yarn.lock")),
|
|
8960
|
+
pathExists(join(root, "bun.lockb"))
|
|
8961
|
+
]);
|
|
8962
|
+
if (pnpm) return "pnpm";
|
|
8963
|
+
if (yarn) return "yarn";
|
|
8964
|
+
if (bun) return "bun";
|
|
8916
8965
|
return "npm";
|
|
8917
8966
|
}
|
|
8918
|
-
function readScripts(cwd) {
|
|
8967
|
+
async function readScripts(cwd) {
|
|
8919
8968
|
try {
|
|
8920
|
-
const
|
|
8969
|
+
const raw = await readFile(join(cwd, "package.json"), "utf8");
|
|
8970
|
+
const pkg = JSON.parse(raw);
|
|
8921
8971
|
return pkg.scripts ?? {};
|
|
8922
8972
|
} catch {
|
|
8923
8973
|
return {};
|
|
@@ -8993,7 +9043,7 @@ function createAutoPhaseHost(deps) {
|
|
|
8993
9043
|
].join("\n");
|
|
8994
9044
|
}
|
|
8995
9045
|
async function runVerify(cwd) {
|
|
8996
|
-
if (!
|
|
9046
|
+
if (!await pathExists(join(cwd, "node_modules")) && !await pathExists(join(deps.projectRoot, "node_modules"))) {
|
|
8997
9047
|
return { ok: true, output: "verify skipped: node_modules not found" };
|
|
8998
9048
|
}
|
|
8999
9049
|
const custom = process.env["WRONGSTACK_AUTOPHASE_VERIFY_CMD"]?.trim();
|
|
@@ -9002,8 +9052,8 @@ function createAutoPhaseHost(deps) {
|
|
|
9002
9052
|
return res.code === 0 ? { ok: true } : { ok: false, output: `[verify] exited ${res.code}
|
|
9003
9053
|
${res.out}` };
|
|
9004
9054
|
}
|
|
9005
|
-
const pm = detectPackageManager(deps.projectRoot);
|
|
9006
|
-
const scripts = readScripts(cwd);
|
|
9055
|
+
const pm = await detectPackageManager(deps.projectRoot);
|
|
9056
|
+
const scripts = await readScripts(cwd);
|
|
9007
9057
|
const steps = ["typecheck", "lint"].filter((s) => typeof scripts[s] === "string");
|
|
9008
9058
|
if (steps.length === 0) return { ok: true, output: "verify skipped: no typecheck/lint script" };
|
|
9009
9059
|
for (const step of steps) {
|
|
@@ -9283,6 +9333,8 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
|
9283
9333
|
"metrics",
|
|
9284
9334
|
"webui",
|
|
9285
9335
|
"open",
|
|
9336
|
+
"webui-require-token",
|
|
9337
|
+
"require-token",
|
|
9286
9338
|
"no-check",
|
|
9287
9339
|
"no-models-refresh",
|
|
9288
9340
|
"director",
|
|
@@ -9751,27 +9803,28 @@ function shouldSuppress(flags) {
|
|
|
9751
9803
|
return false;
|
|
9752
9804
|
}
|
|
9753
9805
|
var wrap = (n) => (n % GROUPS.length + GROUPS.length) % GROUPS.length;
|
|
9754
|
-
function pickGroupIndex(opts) {
|
|
9806
|
+
async function pickGroupIndex(opts) {
|
|
9755
9807
|
if (typeof opts.groupIndex === "number") return wrap(opts.groupIndex);
|
|
9756
9808
|
if (opts.cursorFile) {
|
|
9757
9809
|
try {
|
|
9758
9810
|
let current = 0;
|
|
9759
9811
|
try {
|
|
9760
|
-
const
|
|
9812
|
+
const raw = await fs4.readFile(opts.cursorFile, "utf8");
|
|
9813
|
+
const parsed = Number.parseInt(raw.trim(), 10);
|
|
9761
9814
|
if (Number.isFinite(parsed)) current = wrap(parsed);
|
|
9762
9815
|
} catch {
|
|
9763
9816
|
}
|
|
9764
|
-
|
|
9765
|
-
|
|
9817
|
+
await fs4.mkdir(path4.dirname(opts.cursorFile), { recursive: true });
|
|
9818
|
+
await fs4.writeFile(opts.cursorFile, String(wrap(current + 1)));
|
|
9766
9819
|
return current;
|
|
9767
9820
|
} catch {
|
|
9768
9821
|
}
|
|
9769
9822
|
}
|
|
9770
9823
|
return Math.floor(Math.random() * GROUPS.length);
|
|
9771
9824
|
}
|
|
9772
|
-
function printLaunchHints(renderer, flags, opts = {}) {
|
|
9825
|
+
async function printLaunchHints(renderer, flags, opts = {}) {
|
|
9773
9826
|
if (shouldSuppress(flags)) return;
|
|
9774
|
-
const idx = pickGroupIndex(opts);
|
|
9827
|
+
const idx = await pickGroupIndex(opts);
|
|
9775
9828
|
const group = GROUPS[idx];
|
|
9776
9829
|
if (!group) return;
|
|
9777
9830
|
const lines = [];
|
|
@@ -21861,12 +21914,9 @@ function extractAccountId(token) {
|
|
|
21861
21914
|
const id = auth?.chatgpt_account_id;
|
|
21862
21915
|
return typeof id === "string" && id.length > 0 ? id : null;
|
|
21863
21916
|
}
|
|
21864
|
-
var FALLBACK_CODEX_MODELS =
|
|
21865
|
-
{ id:
|
|
21866
|
-
|
|
21867
|
-
{ id: "gpt-5.4-mini", name: "gpt-5.4-mini" },
|
|
21868
|
-
{ id: "gpt-5.3-codex-spark", name: "gpt-5.3-codex-spark" }
|
|
21869
|
-
];
|
|
21917
|
+
var FALLBACK_CODEX_MODELS = CODEX_MODELS.map(
|
|
21918
|
+
(m) => ({ id: m.id, name: m.name })
|
|
21919
|
+
);
|
|
21870
21920
|
var CODEX_CATALOG_FAMILIES = /* @__PURE__ */ new Set(["gpt-codex", "gpt-codex-spark"]);
|
|
21871
21921
|
function fallbackCodexModelIds() {
|
|
21872
21922
|
return FALLBACK_CODEX_MODELS.map((m) => m.id);
|
|
@@ -22274,6 +22324,15 @@ Try \`wstack models refresh\` once you have network access, or run with --no-fea
|
|
|
22274
22324
|
} catch (err) {
|
|
22275
22325
|
throw new Error(`Failed to create provider: ${err instanceof Error ? err.message : err}`);
|
|
22276
22326
|
}
|
|
22327
|
+
if (config.features.modelsRegistry) {
|
|
22328
|
+
provider = await withCatalogCapabilities(
|
|
22329
|
+
modelsRegistry,
|
|
22330
|
+
config.provider,
|
|
22331
|
+
provider,
|
|
22332
|
+
{ ...providerConfig, type: config.provider, model: config.model },
|
|
22333
|
+
logger
|
|
22334
|
+
);
|
|
22335
|
+
}
|
|
22277
22336
|
return { resolvedProvider, provider, providerRegistry };
|
|
22278
22337
|
}
|
|
22279
22338
|
|
|
@@ -27124,37 +27183,38 @@ async function listFleetRuns(deps) {
|
|
|
27124
27183
|
return 1;
|
|
27125
27184
|
}
|
|
27126
27185
|
const runs = [];
|
|
27127
|
-
|
|
27128
|
-
|
|
27129
|
-
|
|
27130
|
-
|
|
27131
|
-
|
|
27132
|
-
|
|
27133
|
-
|
|
27134
|
-
|
|
27135
|
-
|
|
27136
|
-
|
|
27137
|
-
|
|
27138
|
-
|
|
27139
|
-
|
|
27140
|
-
|
|
27141
|
-
|
|
27142
|
-
|
|
27143
|
-
|
|
27144
|
-
|
|
27145
|
-
|
|
27146
|
-
|
|
27147
|
-
|
|
27148
|
-
|
|
27149
|
-
|
|
27150
|
-
|
|
27151
|
-
|
|
27152
|
-
|
|
27153
|
-
|
|
27154
|
-
|
|
27155
|
-
|
|
27156
|
-
|
|
27157
|
-
|
|
27186
|
+
const perEntry = await Promise.all(
|
|
27187
|
+
entries.map(async (id) => {
|
|
27188
|
+
const runDir = path4.join(deps.paths.projectSessions, id);
|
|
27189
|
+
try {
|
|
27190
|
+
const stat8 = await fs4.stat(runDir);
|
|
27191
|
+
if (!stat8.isDirectory()) return null;
|
|
27192
|
+
} catch {
|
|
27193
|
+
return null;
|
|
27194
|
+
}
|
|
27195
|
+
const [manifestResult, checkpointResult, subagentFilesResult] = await Promise.all([
|
|
27196
|
+
fs4.access(path4.join(runDir, "fleet.json")).then(
|
|
27197
|
+
() => true,
|
|
27198
|
+
() => false
|
|
27199
|
+
),
|
|
27200
|
+
fs4.access(path4.join(runDir, "checkpoint.json")).then(
|
|
27201
|
+
() => true,
|
|
27202
|
+
() => false
|
|
27203
|
+
),
|
|
27204
|
+
fs4.readdir(path4.join(runDir, "subagents")).then(
|
|
27205
|
+
(files) => files.filter((f) => f.endsWith(".jsonl")).length,
|
|
27206
|
+
() => 0
|
|
27207
|
+
)
|
|
27208
|
+
]);
|
|
27209
|
+
return {
|
|
27210
|
+
id,
|
|
27211
|
+
manifest: manifestResult,
|
|
27212
|
+
checkpoint: checkpointResult,
|
|
27213
|
+
subagents: subagentFilesResult
|
|
27214
|
+
};
|
|
27215
|
+
})
|
|
27216
|
+
);
|
|
27217
|
+
for (const r of perEntry) if (r) runs.push(r);
|
|
27158
27218
|
if (runs.length === 0) {
|
|
27159
27219
|
deps.renderer.write("No fleet runs found.\n");
|
|
27160
27220
|
return 0;
|
|
@@ -27268,17 +27328,22 @@ Fleet Run: ${runId}
|
|
|
27268
27328
|
deps.renderer.write(`
|
|
27269
27329
|
Subagent transcripts (${subagentFiles.length}):
|
|
27270
27330
|
`);
|
|
27271
|
-
|
|
27272
|
-
|
|
27273
|
-
|
|
27274
|
-
|
|
27275
|
-
|
|
27276
|
-
|
|
27277
|
-
|
|
27278
|
-
|
|
27279
|
-
|
|
27331
|
+
const sortedFiles = subagentFiles.sort();
|
|
27332
|
+
const sizes = await Promise.all(
|
|
27333
|
+
sortedFiles.map(async (f) => {
|
|
27334
|
+
const filePath = path4.join(subagentsDir, f);
|
|
27335
|
+
try {
|
|
27336
|
+
const s = await fs4.stat(filePath);
|
|
27337
|
+
return s.size;
|
|
27338
|
+
} catch {
|
|
27339
|
+
return 0;
|
|
27340
|
+
}
|
|
27341
|
+
})
|
|
27342
|
+
);
|
|
27343
|
+
for (let i = 0; i < sortedFiles.length; i++) {
|
|
27344
|
+
const size = sizes[i] ?? 0;
|
|
27280
27345
|
const sizeStr = size > 1024 * 1024 ? `${(size / 1024 / 1024).toFixed(1)}MB` : `${(size / 1024).toFixed(0)}KB`;
|
|
27281
|
-
deps.renderer.write(` ${color.dim(
|
|
27346
|
+
deps.renderer.write(` ${color.dim(sortedFiles[i] ?? "")} ${color.dim(sizeStr)}
|
|
27282
27347
|
`);
|
|
27283
27348
|
}
|
|
27284
27349
|
} else {
|
|
@@ -27682,9 +27747,10 @@ var helpCmd = async (_args, deps) => {
|
|
|
27682
27747
|
" --yolo-destructive Deprecated \u2014 YOLO now auto-approves everything by default",
|
|
27683
27748
|
" --tui / --no-tui Force or disable TUI mode",
|
|
27684
27749
|
" --mouse Full mouse mode in the TUI (in-app scroll + clickable UI)",
|
|
27685
|
-
" --webui [--port <n>] [--
|
|
27686
|
-
"
|
|
27687
|
-
"
|
|
27750
|
+
" --webui [--host <h>] [--webui-port <n>] [--ws-port <n>] [--webui-token <t>] [--open]",
|
|
27751
|
+
" [--webui-public-url <url>] [--webui-public-ws-url <url>] [--webui-require-token]",
|
|
27752
|
+
" Serve the browser UI + WS bridge (prints a token URL,",
|
|
27753
|
+
" --open pops the browser; shares this terminal's agent)",
|
|
27688
27754
|
' --eternal "<mission>" Start an eternal-autonomy loop',
|
|
27689
27755
|
" --no-hints Hide launch hints",
|
|
27690
27756
|
" --skip-index Skip codebase indexing and the large-codebase prompt"
|
|
@@ -28039,7 +28105,7 @@ async function boot(argv) {
|
|
|
28039
28105
|
await persistLaunchChoices(wpaths.globalConfig, toPersist);
|
|
28040
28106
|
} catch {
|
|
28041
28107
|
}
|
|
28042
|
-
printLaunchHints(renderer, flags, {
|
|
28108
|
+
await printLaunchHints(renderer, flags, {
|
|
28043
28109
|
cursorFile: path4.join(wpaths.cacheDir, "hint-cursor")
|
|
28044
28110
|
});
|
|
28045
28111
|
} else {
|
|
@@ -28785,11 +28851,79 @@ async function runWebUIDispatch(ctx) {
|
|
|
28785
28851
|
agent.disableInteractiveConfirmation();
|
|
28786
28852
|
renderer.setSilent(true);
|
|
28787
28853
|
const { runWebUI: runWebUI2 } = await Promise.resolve().then(() => (init_webui_server(), webui_server_exports));
|
|
28854
|
+
const flagValue = (names) => {
|
|
28855
|
+
for (const name of names) {
|
|
28856
|
+
if (!Object.prototype.hasOwnProperty.call(flags, name)) continue;
|
|
28857
|
+
const value = flags[name];
|
|
28858
|
+
if (typeof value === "string" && value.trim() !== "") return value.trim();
|
|
28859
|
+
throw new Error(`--${name} requires a value`);
|
|
28860
|
+
}
|
|
28861
|
+
return void 0;
|
|
28862
|
+
};
|
|
28863
|
+
const flagBoolean = (names) => {
|
|
28864
|
+
for (const name of names) {
|
|
28865
|
+
if (!Object.prototype.hasOwnProperty.call(flags, name)) continue;
|
|
28866
|
+
const value = flags[name];
|
|
28867
|
+
if (value === void 0) continue;
|
|
28868
|
+
if (typeof value === "boolean") return value;
|
|
28869
|
+
const normalized = value.trim().toLowerCase();
|
|
28870
|
+
if (["1", "true", "yes", "on"].includes(normalized)) return true;
|
|
28871
|
+
if (["0", "false", "no", "off"].includes(normalized)) return false;
|
|
28872
|
+
throw new Error(`--${name} must be a boolean value`);
|
|
28873
|
+
}
|
|
28874
|
+
return void 0;
|
|
28875
|
+
};
|
|
28876
|
+
const envFlag2 = (name) => {
|
|
28877
|
+
const value = process.env[name]?.trim().toLowerCase();
|
|
28878
|
+
return value === "1" || value === "true" || value === "yes" || value === "on";
|
|
28879
|
+
};
|
|
28880
|
+
const parsePort = (value, fallback, label) => {
|
|
28881
|
+
if (value === void 0) return fallback;
|
|
28882
|
+
const parsed = Number.parseInt(value, 10);
|
|
28883
|
+
if (!Number.isInteger(parsed) || parsed <= 0 || parsed > 65535) {
|
|
28884
|
+
throw new Error(`${label} must be a port between 1 and 65535`);
|
|
28885
|
+
}
|
|
28886
|
+
return parsed;
|
|
28887
|
+
};
|
|
28888
|
+
let webuiHost;
|
|
28889
|
+
let webuiHttpPort;
|
|
28890
|
+
let webuiWsPort;
|
|
28891
|
+
let webuiAccessToken;
|
|
28892
|
+
let webuiPublicUrl;
|
|
28893
|
+
let webuiPublicWsUrl;
|
|
28894
|
+
let webuiRequireToken;
|
|
28895
|
+
try {
|
|
28896
|
+
webuiHost = flagValue(["webui-host", "host"]) ?? process.env["WEBUI_HOST"] ?? process.env["WS_HOST"] ?? "127.0.0.1";
|
|
28897
|
+
webuiHttpPort = parsePort(
|
|
28898
|
+
flagValue(["webui-port", "http-port"]) ?? process.env["WEBUI_PORT"] ?? process.env["PORT"],
|
|
28899
|
+
3456,
|
|
28900
|
+
"--webui-port"
|
|
28901
|
+
);
|
|
28902
|
+
webuiWsPort = parsePort(
|
|
28903
|
+
flagValue(["ws-port"]) ?? flagValue(["port"]) ?? process.env["WS_PORT"],
|
|
28904
|
+
3457,
|
|
28905
|
+
"--ws-port"
|
|
28906
|
+
);
|
|
28907
|
+
webuiAccessToken = flagValue(["webui-token"]) ?? process.env["WEBUI_TOKEN"] ?? process.env["WEBUI_AUTH_TOKEN"];
|
|
28908
|
+
webuiPublicUrl = flagValue(["webui-public-url", "public-url"]) ?? process.env["WEBUI_PUBLIC_URL"];
|
|
28909
|
+
webuiPublicWsUrl = flagValue(["webui-public-ws-url", "public-ws-url"]) ?? process.env["WEBUI_PUBLIC_WS_URL"];
|
|
28910
|
+
webuiRequireToken = flagBoolean(["webui-require-token", "require-token"]) ?? envFlag2("WEBUI_REQUIRE_TOKEN");
|
|
28911
|
+
} catch (err) {
|
|
28912
|
+
renderer.setSilent(false);
|
|
28913
|
+
renderer.writeInfo(color.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
28914
|
+
return 1;
|
|
28915
|
+
}
|
|
28788
28916
|
const webuiPromise = runWebUI2({
|
|
28789
28917
|
agent,
|
|
28790
28918
|
events,
|
|
28791
28919
|
session,
|
|
28792
|
-
|
|
28920
|
+
host: webuiHost,
|
|
28921
|
+
port: webuiWsPort,
|
|
28922
|
+
httpPort: webuiHttpPort,
|
|
28923
|
+
accessToken: webuiAccessToken,
|
|
28924
|
+
publicUrl: webuiPublicUrl,
|
|
28925
|
+
publicWsUrl: webuiPublicWsUrl,
|
|
28926
|
+
requireToken: webuiRequireToken,
|
|
28793
28927
|
projectRoot,
|
|
28794
28928
|
appConfig: config,
|
|
28795
28929
|
open: !!flags.open,
|
|
@@ -28813,16 +28947,13 @@ async function runWebUIDispatch(ctx) {
|
|
|
28813
28947
|
needsSetup,
|
|
28814
28948
|
sddSubagentFactory,
|
|
28815
28949
|
// Print the "open this" banner only once the server is actually
|
|
28816
|
-
// listening, using the RESOLVED ports.
|
|
28817
|
-
//
|
|
28818
|
-
//
|
|
28819
|
-
|
|
28820
|
-
// so the host must be the literal IPv4 loopback — `localhost` resolves
|
|
28821
|
-
// to `::1` first on Windows and never reaches the server.
|
|
28822
|
-
onListening: ({ httpPort: boundHttpPort }) => {
|
|
28950
|
+
// listening, using the RESOLVED ports. Requested ports auto-advance past
|
|
28951
|
+
// busy ports inside runWebUI, so a banner printed up-front lies whenever
|
|
28952
|
+
// 3456/3457 are taken (a second instance, leftover sockets).
|
|
28953
|
+
onListening: ({ url }) => {
|
|
28823
28954
|
renderer.writeInfo(
|
|
28824
28955
|
color.green(
|
|
28825
|
-
` \u2726 WebUI running \u2192 ${color.bold(
|
|
28956
|
+
` \u2726 WebUI running \u2192 ${color.bold(url)}`
|
|
28826
28957
|
)
|
|
28827
28958
|
);
|
|
28828
28959
|
renderer.writeInfo(
|
|
@@ -32989,7 +33120,7 @@ async function setupCodebaseIndexing(deps) {
|
|
|
32989
33120
|
let watcher;
|
|
32990
33121
|
if (idx.watchExternal) {
|
|
32991
33122
|
try {
|
|
32992
|
-
watcher =
|
|
33123
|
+
watcher = fs37.watch(projectRoot, { recursive: true }, (_event, filename) => {
|
|
32993
33124
|
if (!filename) return;
|
|
32994
33125
|
const rel = filename.toString();
|
|
32995
33126
|
if (isIgnored(rel)) return;
|
|
@@ -34248,6 +34379,7 @@ async function main(argv) {
|
|
|
34248
34379
|
config = patchConfig(config, { provider: providerId, model: modelId });
|
|
34249
34380
|
configStore.update({ provider: providerId, model: modelId });
|
|
34250
34381
|
await refreshMaxContextFor(providerId, modelId);
|
|
34382
|
+
await refreshActiveReasoningConfig(providerId, modelId);
|
|
34251
34383
|
return null;
|
|
34252
34384
|
} catch (err) {
|
|
34253
34385
|
return err instanceof Error ? err.message : String(err);
|
|
@@ -34941,29 +35073,36 @@ ${color.dim("\u2500".repeat(40))}` : "";
|
|
|
34941
35073
|
return "No fleet transcripts on disk \u2014 no subagents have been spawned for this session.";
|
|
34942
35074
|
}
|
|
34943
35075
|
const found = [];
|
|
34944
|
-
|
|
34945
|
-
|
|
34946
|
-
|
|
34947
|
-
|
|
34948
|
-
files = await fs4.readdir(runDir);
|
|
34949
|
-
} catch {
|
|
34950
|
-
continue;
|
|
34951
|
-
}
|
|
34952
|
-
for (const f of files) {
|
|
34953
|
-
if (!f.endsWith(".jsonl")) continue;
|
|
34954
|
-
const full = path4.join(runDir, f);
|
|
35076
|
+
const runResults = await Promise.all(
|
|
35077
|
+
runDirs.map(async (runId) => {
|
|
35078
|
+
const runDir = path4.join(subagentsRoot, runId);
|
|
35079
|
+
let files;
|
|
34955
35080
|
try {
|
|
34956
|
-
|
|
34957
|
-
found.push({
|
|
34958
|
-
runId,
|
|
34959
|
-
subagentId: f.replace(/\.jsonl$/, ""),
|
|
34960
|
-
file: full,
|
|
34961
|
-
size: stat8.size
|
|
34962
|
-
});
|
|
35081
|
+
files = await fs4.readdir(runDir);
|
|
34963
35082
|
} catch {
|
|
35083
|
+
return [];
|
|
34964
35084
|
}
|
|
34965
|
-
|
|
34966
|
-
|
|
35085
|
+
const jsonlFiles = files.filter((f) => f.endsWith(".jsonl"));
|
|
35086
|
+
const fileResults = await Promise.all(
|
|
35087
|
+
jsonlFiles.map(async (f) => {
|
|
35088
|
+
const full = path4.join(runDir, f);
|
|
35089
|
+
try {
|
|
35090
|
+
const stat8 = await fs4.stat(full);
|
|
35091
|
+
return {
|
|
35092
|
+
runId,
|
|
35093
|
+
subagentId: f.replace(/\.jsonl$/, ""),
|
|
35094
|
+
file: full,
|
|
35095
|
+
size: stat8.size
|
|
35096
|
+
};
|
|
35097
|
+
} catch {
|
|
35098
|
+
return null;
|
|
35099
|
+
}
|
|
35100
|
+
})
|
|
35101
|
+
);
|
|
35102
|
+
return fileResults.filter((r) => r !== null);
|
|
35103
|
+
})
|
|
35104
|
+
);
|
|
35105
|
+
for (const runResult of runResults) found.push(...runResult);
|
|
34967
35106
|
if (found.length === 0) {
|
|
34968
35107
|
return "No subagent transcripts found on disk.";
|
|
34969
35108
|
}
|
|
@@ -35355,12 +35494,28 @@ Restart WrongStack to load or unload plugin code in this session.`;
|
|
|
35355
35494
|
const core = await import('@wrongstack/core');
|
|
35356
35495
|
let worktrees;
|
|
35357
35496
|
if (process.env["WRONGSTACK_SDD_WORKTREES"] !== "0") {
|
|
35358
|
-
const
|
|
35359
|
-
|
|
35360
|
-
|
|
35361
|
-
|
|
35362
|
-
|
|
35363
|
-
|
|
35497
|
+
const inGit = await new Promise((resolve13) => {
|
|
35498
|
+
let resolved = false;
|
|
35499
|
+
const settle = (v) => {
|
|
35500
|
+
if (resolved) return;
|
|
35501
|
+
resolved = true;
|
|
35502
|
+
resolve13(v);
|
|
35503
|
+
};
|
|
35504
|
+
try {
|
|
35505
|
+
const child = spawn("git", ["rev-parse", "--is-inside-work-tree"], {
|
|
35506
|
+
cwd: projectRoot,
|
|
35507
|
+
env: process.env,
|
|
35508
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
35509
|
+
windowsHide: true
|
|
35510
|
+
});
|
|
35511
|
+
const chunks = [];
|
|
35512
|
+
child.stdout?.on("data", (c) => chunks.push(c.toString()));
|
|
35513
|
+
child.on("error", () => settle(false));
|
|
35514
|
+
child.on("close", (code) => settle(code === 0 && chunks.join("").trim() === "true"));
|
|
35515
|
+
} catch {
|
|
35516
|
+
settle(false);
|
|
35517
|
+
}
|
|
35518
|
+
});
|
|
35364
35519
|
if (inGit) worktrees = new core.WorktreeManager({ projectRoot, events });
|
|
35365
35520
|
}
|
|
35366
35521
|
const boardStore = new core.SddBoardStore({ baseDir: wpaths.projectSddBoards });
|