@wrongstack/cli 0.3.8 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,12 +1,13 @@
1
1
  #!/usr/bin/env node
2
- import { color, allServers, DefaultPathResolver, TOKENS, DefaultSystemPromptBuilder, ToolRegistry, createContextManagerTool, EventBus, InMemoryMetricsSink, wireMetricsToEvents, DefaultHealthRegistry, startMetricsServer, SlashCommandRegistry, loadPlugins, createDelegateTool, FLEET_ROSTER, DefaultLogger, DefaultModelsRegistry, DefaultSessionStore, DefaultSkillLoader, ProviderRegistry, RecoveryLock, DefaultAttachmentStore, QueueStore, Context, loadTodosCheckpoint, attachTodosCheckpoint, loadDirectorState, loadPlan, createDefaultPipelines, AutoCompactionMiddleware, Agent, makeDirectorSessionFactory, Director, DefaultMultiAgentCoordinator, makeAgentSubagentRunner, resolveWstackPaths, DefaultSecretVault, migratePlaintextSecrets, DefaultConfigLoader, DefaultSessionReader, atomicWrite, AutoApprovePermissionPolicy, formatContextWindowModeList, repairToolUseAdjacency, getContextWindowMode, resolveContextWindowPolicy, formatTodosList, emptyPlan, clearPlan, savePlan, removePlanItem, formatPlan, setPlanItemStatus, addPlanItem, InputBuilder, decryptConfigSecrets, encryptConfigSecrets, DefaultPluginAPI } from '@wrongstack/core';
2
+ import { color, allServers, DefaultPathResolver, TOKENS, DefaultSystemPromptBuilder, ToolRegistry, createContextManagerTool, EventBus, InMemoryMetricsSink, wireMetricsToEvents, DefaultHealthRegistry, startMetricsServer, SlashCommandRegistry, loadPlugins, createDelegateTool, FLEET_ROSTER, DefaultLogger, DefaultModelsRegistry, DefaultSessionStore, DefaultSkillLoader, ProviderRegistry, RecoveryLock, DefaultAttachmentStore, QueueStore, Context, loadTodosCheckpoint, attachTodosCheckpoint, loadDirectorState, loadPlan, createDefaultPipelines, AutoCompactionMiddleware, Agent, makeDirectorSessionFactory, Director, DefaultMultiAgentCoordinator, makeAgentSubagentRunner, resolveWstackPaths, DefaultSecretVault, migratePlaintextSecrets, DefaultConfigLoader, DefaultSessionReader, atomicWrite, AutoApprovePermissionPolicy, formatContextWindowModeList, repairToolUseAdjacency, getContextWindowMode, resolveContextWindowPolicy, formatTodosList, emptyPlan, clearPlan, savePlan, removePlanItem, formatPlan, setPlanItemStatus, addPlanItem, InputBuilder, decryptConfigSecrets, encryptConfigSecrets as encryptConfigSecrets$1, DefaultPluginAPI } from '@wrongstack/core';
3
3
  import * as crypto from 'crypto';
4
4
  import { randomUUID } from 'crypto';
5
5
  import * as fs14 from 'fs/promises';
6
+ import * as path15 from 'path';
7
+ import { DefaultSecretVault as DefaultSecretVault$1, encryptConfigSecrets } from '@wrongstack/core/security';
6
8
  import { WebSocketServer, WebSocket } from 'ws';
7
9
  import { writeFileSync } from 'fs';
8
10
  import { createRequire } from 'module';
9
- import * as path14 from 'path';
10
11
  import { MCPRegistry } from '@wrongstack/mcp';
11
12
  import { buildProviderFactoriesFromRegistry, makeProviderFromConfig, capabilitiesFor } from '@wrongstack/providers';
12
13
  import { createDefaultContainer, routeImagesForModel, readClipboardImage } from '@wrongstack/runtime';
@@ -76,9 +77,8 @@ async function runWebUI(opts) {
76
77
  const clients = /* @__PURE__ */ new Map();
77
78
  let abortController = null;
78
79
  const authToken = crypto.randomBytes(16).toString("hex");
79
- const wss = new WebSocketServer({ port, host: "127.0.0.1" });
80
+ const wss = new WebSocketServer({ port, host: "127.0.0.1", maxPayload: 1 * 1024 * 1024 });
80
81
  console.log(`[WebUI] WebSocket server starting on ws://localhost:${port}`);
81
- console.log(`[WebUI] Auth token: ${authToken}`);
82
82
  const eventUnsubscribers = [];
83
83
  function setupEvents() {
84
84
  for (const unsub of eventUnsubscribers) unsub();
@@ -198,6 +198,8 @@ async function runWebUI(opts) {
198
198
  }
199
199
  } else {
200
200
  if (!tokenOk) {
201
+ ws.close(4003, "Forbidden: auth token required for non-browser clients");
202
+ return;
201
203
  }
202
204
  }
203
205
  } catch {
@@ -574,7 +576,10 @@ async function runWebUI(opts) {
574
576
  parsed = {};
575
577
  }
576
578
  parsed.providers = providers;
577
- await atomicWrite(opts.globalConfigPath, JSON.stringify(parsed, null, 2), { mode: 384 });
579
+ const keyFile = path15.join(path15.dirname(opts.globalConfigPath), ".key");
580
+ const vault = new DefaultSecretVault$1({ keyFile });
581
+ const encrypted = encryptConfigSecrets(parsed, vault);
582
+ await atomicWrite(opts.globalConfigPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
578
583
  }
579
584
  function sendResult(ws, success, message) {
580
585
  send(ws, { type: "key.operation_result", payload: { success, message } });
@@ -723,7 +728,7 @@ function parseSpawnFlags(input) {
723
728
  return { description: rest.trim(), opts };
724
729
  }
725
730
  async function bootConfig(flags) {
726
- const cwd = typeof flags["cwd"] === "string" ? path14.resolve(flags["cwd"]) : process.cwd();
731
+ const cwd = typeof flags["cwd"] === "string" ? path15.resolve(flags["cwd"]) : process.cwd();
727
732
  const pathResolver = new DefaultPathResolver(cwd);
728
733
  const projectRoot = pathResolver.projectRoot;
729
734
  const userHome = os3.homedir();
@@ -790,7 +795,7 @@ var ReadlineInputReader = class {
790
795
  history = [];
791
796
  pending = false;
792
797
  constructor(opts = {}) {
793
- this.historyFile = opts.historyFile ?? path14.join(os3.homedir(), ".wrongstack", "history");
798
+ this.historyFile = opts.historyFile ?? path15.join(os3.homedir(), ".wrongstack", "history");
794
799
  }
795
800
  async loadHistory() {
796
801
  try {
@@ -802,7 +807,7 @@ var ReadlineInputReader = class {
802
807
  }
803
808
  async saveHistory() {
804
809
  try {
805
- await fs14.mkdir(path14.dirname(this.historyFile), { recursive: true });
810
+ await fs14.mkdir(path15.dirname(this.historyFile), { recursive: true });
806
811
  await fs14.writeFile(this.historyFile, this.history.slice(-1e3).join("\n"));
807
812
  } catch {
808
813
  }
@@ -1284,10 +1289,10 @@ async function detectPackageManager(root, declared) {
1284
1289
  const name = declared.split("@")[0];
1285
1290
  if (name) return name;
1286
1291
  }
1287
- if (await pathExists(path14.join(root, "pnpm-lock.yaml"))) return "pnpm";
1288
- if (await pathExists(path14.join(root, "bun.lockb"))) return "bun";
1289
- if (await pathExists(path14.join(root, "bun.lock"))) return "bun";
1290
- if (await pathExists(path14.join(root, "yarn.lock"))) return "yarn";
1292
+ if (await pathExists(path15.join(root, "pnpm-lock.yaml"))) return "pnpm";
1293
+ if (await pathExists(path15.join(root, "bun.lockb"))) return "bun";
1294
+ if (await pathExists(path15.join(root, "bun.lock"))) return "bun";
1295
+ if (await pathExists(path15.join(root, "yarn.lock"))) return "yarn";
1291
1296
  return "npm";
1292
1297
  }
1293
1298
  function hasUsableScript(scripts, name) {
@@ -1308,7 +1313,7 @@ function parseMakeTargets(makefile) {
1308
1313
  async function detectProjectFacts(root) {
1309
1314
  const facts = { hints: [] };
1310
1315
  try {
1311
- const pkg = JSON.parse(await fs14.readFile(path14.join(root, "package.json"), "utf8"));
1316
+ const pkg = JSON.parse(await fs14.readFile(path15.join(root, "package.json"), "utf8"));
1312
1317
  const scripts = pkg.scripts ?? {};
1313
1318
  const pm = await detectPackageManager(root, pkg.packageManager);
1314
1319
  if (hasUsableScript(scripts, "build")) facts.build = `${pm} run build`;
@@ -1322,14 +1327,14 @@ async function detectProjectFacts(root) {
1322
1327
  } catch {
1323
1328
  }
1324
1329
  try {
1325
- if (!await pathExists(path14.join(root, "pyproject.toml"))) throw new Error("not python");
1330
+ if (!await pathExists(path15.join(root, "pyproject.toml"))) throw new Error("not python");
1326
1331
  facts.test ??= "pytest";
1327
1332
  facts.lint ??= "ruff check .";
1328
1333
  facts.hints.push("pyproject.toml");
1329
1334
  } catch {
1330
1335
  }
1331
1336
  try {
1332
- if (!await pathExists(path14.join(root, "go.mod"))) throw new Error("not go");
1337
+ if (!await pathExists(path15.join(root, "go.mod"))) throw new Error("not go");
1333
1338
  facts.build ??= "go build ./...";
1334
1339
  facts.test ??= "go test ./...";
1335
1340
  facts.run ??= "go run .";
@@ -1337,7 +1342,7 @@ async function detectProjectFacts(root) {
1337
1342
  } catch {
1338
1343
  }
1339
1344
  try {
1340
- if (!await pathExists(path14.join(root, "Cargo.toml"))) throw new Error("not rust");
1345
+ if (!await pathExists(path15.join(root, "Cargo.toml"))) throw new Error("not rust");
1341
1346
  facts.build ??= "cargo build";
1342
1347
  facts.test ??= "cargo test";
1343
1348
  facts.lint ??= "cargo clippy";
@@ -1346,7 +1351,7 @@ async function detectProjectFacts(root) {
1346
1351
  } catch {
1347
1352
  }
1348
1353
  try {
1349
- const makefile = await fs14.readFile(path14.join(root, "Makefile"), "utf8");
1354
+ const makefile = await fs14.readFile(path15.join(root, "Makefile"), "utf8");
1350
1355
  const targets = parseMakeTargets(makefile);
1351
1356
  facts.build ??= targets.has("build") ? "make build" : "make";
1352
1357
  if (targets.has("test")) facts.test ??= "make test";
@@ -1809,8 +1814,8 @@ function buildInitCommand(opts) {
1809
1814
  description: "Create .wrongstack/AGENTS.md project context for the system prompt.",
1810
1815
  async run(args, ctx) {
1811
1816
  const force = args.trim() === "--force";
1812
- const dir = path14.join(ctx.projectRoot, ".wrongstack");
1813
- const file = path14.join(dir, "AGENTS.md");
1817
+ const dir = path15.join(ctx.projectRoot, ".wrongstack");
1818
+ const file = path15.join(dir, "AGENTS.md");
1814
1819
  try {
1815
1820
  await fs14.access(file);
1816
1821
  if (!force) {
@@ -2242,13 +2247,13 @@ var MANIFESTS = [
2242
2247
  ];
2243
2248
  async function detectProjectKind(projectRoot) {
2244
2249
  try {
2245
- await fs14.access(path14.join(projectRoot, ".wrongstack", "AGENTS.md"));
2250
+ await fs14.access(path15.join(projectRoot, ".wrongstack", "AGENTS.md"));
2246
2251
  return "initialized";
2247
2252
  } catch {
2248
2253
  }
2249
2254
  for (const m of MANIFESTS) {
2250
2255
  try {
2251
- await fs14.access(path14.join(projectRoot, m));
2256
+ await fs14.access(path15.join(projectRoot, m));
2252
2257
  return "project";
2253
2258
  } catch {
2254
2259
  }
@@ -2256,8 +2261,8 @@ async function detectProjectKind(projectRoot) {
2256
2261
  return "empty";
2257
2262
  }
2258
2263
  async function scaffoldAgentsMd(projectRoot) {
2259
- const dir = path14.join(projectRoot, ".wrongstack");
2260
- const file = path14.join(dir, "AGENTS.md");
2264
+ const dir = path15.join(projectRoot, ".wrongstack");
2265
+ const file = path15.join(dir, "AGENTS.md");
2261
2266
  const facts = await detectProjectFacts(projectRoot);
2262
2267
  const body = renderAgentsTemplate(facts);
2263
2268
  await fs14.mkdir(dir, { recursive: true });
@@ -2270,7 +2275,7 @@ async function runProjectCheck(opts) {
2270
2275
  if (kind === "initialized") {
2271
2276
  renderer.write(
2272
2277
  `
2273
- ${color.green("\u2713")} Project initialized ${color.dim(`(${path14.join(projectRoot, ".wrongstack", "AGENTS.md")})`)}
2278
+ ${color.green("\u2713")} Project initialized ${color.dim(`(${path15.join(projectRoot, ".wrongstack", "AGENTS.md")})`)}
2274
2279
  `
2275
2280
  );
2276
2281
  return true;
@@ -2566,14 +2571,14 @@ function summarize(value, name) {
2566
2571
  if (typeof v === "object" && v !== null) {
2567
2572
  const o = v;
2568
2573
  if (name === "edit") {
2569
- const path15 = typeof o["path"] === "string" ? o["path"] : "";
2574
+ const path16 = typeof o["path"] === "string" ? o["path"] : "";
2570
2575
  const reps = typeof o["replacements"] === "number" ? o["replacements"] : 0;
2571
- return `${path15} ${reps} replacement${reps === 1 ? "" : "s"}`.trim();
2576
+ return `${path16} ${reps} replacement${reps === 1 ? "" : "s"}`.trim();
2572
2577
  }
2573
2578
  if (name === "write") {
2574
- const path15 = typeof o["path"] === "string" ? o["path"] : "";
2579
+ const path16 = typeof o["path"] === "string" ? o["path"] : "";
2575
2580
  const bytes = typeof o["bytes"] === "number" ? o["bytes"] : void 0;
2576
- return bytes !== void 0 ? `${path15} ${bytes}B` : path15;
2581
+ return bytes !== void 0 ? `${path16} ${bytes}B` : path16;
2577
2582
  }
2578
2583
  if (typeof o["count"] === "number") {
2579
2584
  return `${o["count"]} match${o["count"] === 1 ? "" : "es"}`;
@@ -3199,7 +3204,7 @@ async function mutateProviders(deps, mutator) {
3199
3204
  const providers = decrypted.providers ?? {};
3200
3205
  mutator(providers);
3201
3206
  decrypted.providers = providers;
3202
- const encrypted = encryptConfigSecrets(decrypted, deps.vault);
3207
+ const encrypted = encryptConfigSecrets$1(decrypted, deps.vault);
3203
3208
  await atomicWrite(deps.globalConfigPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
3204
3209
  }
3205
3210
 
@@ -3336,7 +3341,7 @@ var doctorCmd = async (_args, deps) => {
3336
3341
  }
3337
3342
  try {
3338
3343
  await fs14.mkdir(deps.paths.projectSessions, { recursive: true });
3339
- const probe = path14.join(deps.paths.projectSessions, `.probe-${Date.now()}`);
3344
+ const probe = path15.join(deps.paths.projectSessions, `.probe-${Date.now()}`);
3340
3345
  await fs14.writeFile(probe, "");
3341
3346
  await fs14.unlink(probe);
3342
3347
  checks.push({ name: "sessions writable", status: "ok", detail: deps.paths.projectSessions });
@@ -3439,8 +3444,8 @@ var exportCmd = async (args, deps) => {
3439
3444
  return 1;
3440
3445
  }
3441
3446
  if (output) {
3442
- await fs14.mkdir(path14.dirname(path14.resolve(deps.cwd, output)), { recursive: true });
3443
- await fs14.writeFile(path14.resolve(deps.cwd, output), rendered, "utf8");
3447
+ await fs14.mkdir(path15.dirname(path15.resolve(deps.cwd, output)), { recursive: true });
3448
+ await fs14.writeFile(path15.resolve(deps.cwd, output), rendered, "utf8");
3444
3449
  deps.renderer.write(`Wrote ${rendered.length} bytes to ${output}
3445
3450
  `);
3446
3451
  } else {
@@ -3500,9 +3505,12 @@ var initCmd = async (_args, deps) => {
3500
3505
  await fs14.mkdir(deps.paths.globalRoot, { recursive: true });
3501
3506
  const config = { version: 1, provider: providerId, model: modelId };
3502
3507
  if (apiKey) config.apiKey = apiKey;
3503
- await atomicWrite(deps.paths.globalConfig, JSON.stringify(config, null, 2));
3504
- await fs14.mkdir(path14.join(deps.projectRoot, ".wrongstack"), { recursive: true });
3505
- const agentsFile = path14.join(deps.projectRoot, ".wrongstack", "AGENTS.md");
3508
+ const keyFile = path15.join(path15.dirname(deps.paths.globalConfig), ".key");
3509
+ const vault = new DefaultSecretVault$1({ keyFile });
3510
+ const encrypted = encryptConfigSecrets(config, vault);
3511
+ await atomicWrite(deps.paths.globalConfig, JSON.stringify(encrypted, null, 2));
3512
+ await fs14.mkdir(path15.join(deps.projectRoot, ".wrongstack"), { recursive: true });
3513
+ const agentsFile = path15.join(deps.projectRoot, ".wrongstack", "AGENTS.md");
3506
3514
  try {
3507
3515
  await fs14.access(agentsFile);
3508
3516
  } catch {
@@ -3812,7 +3820,7 @@ var usageCmd = async (_args, deps) => {
3812
3820
  return 0;
3813
3821
  };
3814
3822
  var projectsCmd = async (_args, deps) => {
3815
- const projectsRoot = path14.join(deps.paths.globalRoot, "projects");
3823
+ const projectsRoot = path15.join(deps.paths.globalRoot, "projects");
3816
3824
  try {
3817
3825
  const entries = await fs14.readdir(projectsRoot);
3818
3826
  if (entries.length === 0) {
@@ -3822,7 +3830,7 @@ var projectsCmd = async (_args, deps) => {
3822
3830
  for (const hash of entries) {
3823
3831
  try {
3824
3832
  const meta = JSON.parse(
3825
- await fs14.readFile(path14.join(projectsRoot, hash, "meta.json"), "utf8")
3833
+ await fs14.readFile(path15.join(projectsRoot, hash, "meta.json"), "utf8")
3826
3834
  );
3827
3835
  deps.renderer.write(
3828
3836
  ` ${color.dim(hash)} ${color.dim(meta.lastSeen ?? "")} ${meta.root ?? "?"}
@@ -4121,7 +4129,7 @@ function resolveBundledSkillsDir() {
4121
4129
  try {
4122
4130
  const req2 = createRequire(import.meta.url);
4123
4131
  const corePkg = req2.resolve("@wrongstack/core/package.json");
4124
- return path14.join(path14.dirname(corePkg), "skills");
4132
+ return path15.join(path15.dirname(corePkg), "skills");
4125
4133
  } catch {
4126
4134
  return void 0;
4127
4135
  }
@@ -4628,7 +4636,7 @@ async function execute(deps) {
4628
4636
  supportsVision,
4629
4637
  attachments,
4630
4638
  effectiveMaxContext,
4631
- projectName: path14.basename(projectRoot) || void 0
4639
+ projectName: path15.basename(projectRoot) || void 0
4632
4640
  });
4633
4641
  } finally {
4634
4642
  await webuiPromise.catch(() => void 0);
@@ -4644,7 +4652,7 @@ async function execute(deps) {
4644
4652
  supportsVision,
4645
4653
  attachments,
4646
4654
  effectiveMaxContext,
4647
- projectName: path14.basename(projectRoot) || void 0
4655
+ projectName: path15.basename(projectRoot) || void 0
4648
4656
  });
4649
4657
  }
4650
4658
  } finally {
@@ -4905,7 +4913,7 @@ var MultiAgentHost = class {
4905
4913
  model: opts?.model,
4906
4914
  tools: opts?.tools
4907
4915
  };
4908
- const transcriptPath = this.sessionFactory ? path14.join(this.sessionFactory.dir, `${subagentConfig.name}.jsonl`) : void 0;
4916
+ const transcriptPath = this.sessionFactory ? path15.join(this.sessionFactory.dir, `${subagentConfig.name}.jsonl`) : void 0;
4909
4917
  if (this.director) {
4910
4918
  const subagentId = await this.director.spawn(subagentConfig);
4911
4919
  const taskId2 = randomUUID();
@@ -5057,16 +5065,16 @@ var MultiAgentHost = class {
5057
5065
  }
5058
5066
  this.opts.directorMode = true;
5059
5067
  if (this.opts.fleetRoot && !this.opts.manifestPath) {
5060
- this.opts.manifestPath = path14.join(this.opts.fleetRoot, "fleet.json");
5068
+ this.opts.manifestPath = path15.join(this.opts.fleetRoot, "fleet.json");
5061
5069
  }
5062
5070
  if (this.opts.fleetRoot && !this.opts.sharedScratchpadPath) {
5063
- this.opts.sharedScratchpadPath = path14.join(this.opts.fleetRoot, "shared");
5071
+ this.opts.sharedScratchpadPath = path15.join(this.opts.fleetRoot, "shared");
5064
5072
  }
5065
5073
  if (this.opts.fleetRoot && !this.opts.sessionsRoot) {
5066
- this.opts.sessionsRoot = path14.join(this.opts.fleetRoot, "subagents");
5074
+ this.opts.sessionsRoot = path15.join(this.opts.fleetRoot, "subagents");
5067
5075
  }
5068
5076
  if (this.opts.fleetRoot && !this.opts.stateCheckpointPath) {
5069
- this.opts.stateCheckpointPath = path14.join(this.opts.fleetRoot, "director-state.json");
5077
+ this.opts.stateCheckpointPath = path15.join(this.opts.fleetRoot, "director-state.json");
5070
5078
  }
5071
5079
  await this.ensureDirector();
5072
5080
  return this.director ?? null;
@@ -5187,11 +5195,11 @@ var SessionStats = class {
5187
5195
  if (e.name === "bash") this.bashCommands++;
5188
5196
  else if (e.name === "fetch") this.fetches++;
5189
5197
  if (!e.ok) return;
5190
- const path15 = typeof input?.path === "string" ? input.path : void 0;
5191
- if (e.name === "read" && path15) this.readPaths.add(path15);
5192
- else if (e.name === "edit" && path15) this.editedPaths.add(path15);
5193
- else if (e.name === "write" && path15) {
5194
- this.writtenPaths.add(path15);
5198
+ const path16 = typeof input?.path === "string" ? input.path : void 0;
5199
+ if (e.name === "read" && path16) this.readPaths.add(path16);
5200
+ else if (e.name === "edit" && path16) this.editedPaths.add(path16);
5201
+ else if (e.name === "write" && path16) {
5202
+ this.writtenPaths.add(path16);
5195
5203
  const content = typeof input?.content === "string" ? input.content : "";
5196
5204
  this.bytesWritten += Buffer.byteLength(content, "utf8");
5197
5205
  }
@@ -5397,6 +5405,15 @@ async function setupCompaction(params) {
5397
5405
  const { compactor, events, modelsRegistry, context, config, provider, pipelines } = params;
5398
5406
  const resolvedCaps = await capabilitiesFor(modelsRegistry, provider.id, context.model).catch(() => void 0);
5399
5407
  const effectiveMaxContext = config.context.effectiveMaxContext ?? resolvedCaps?.maxContext ?? provider.capabilities.maxContext;
5408
+ console.error("[DEBUG] setupCompaction:", {
5409
+ providerId: provider.id,
5410
+ model: context.model,
5411
+ resolvedCapsMaxContext: resolvedCaps?.maxContext,
5412
+ providerCapMaxContext: provider.capabilities.maxContext,
5413
+ configEffectiveMaxContext: config.context.effectiveMaxContext,
5414
+ effectiveMaxContext,
5415
+ resolvedCapsKeys: resolvedCaps ? Object.keys(resolvedCaps) : null
5416
+ });
5400
5417
  if (config.context.autoCompact !== false) {
5401
5418
  const autoCompactor = new AutoCompactionMiddleware(
5402
5419
  compactor,
@@ -5535,12 +5552,12 @@ async function setupSession(params) {
5535
5552
  }
5536
5553
  const sessionRef = { current: session };
5537
5554
  await recoveryLock.write(session.id).catch(() => void 0);
5538
- const attachments = new DefaultAttachmentStore({ spoolDir: path14.join(wpaths.projectSessions, session.id, "attachments") });
5539
- const queueStore = new QueueStore({ dir: path14.join(wpaths.projectSessions, session.id) });
5555
+ const attachments = new DefaultAttachmentStore({ spoolDir: path15.join(wpaths.projectSessions, session.id, "attachments") });
5556
+ const queueStore = new QueueStore({ dir: path15.join(wpaths.projectSessions, session.id) });
5540
5557
  const ctxSignal = new AbortController().signal;
5541
5558
  const context = new Context({ systemPrompt, provider, session, signal: ctxSignal, tokenCounter, cwd, projectRoot, model: config.model });
5542
5559
  if (restoredMessages.length > 0) context.state.replaceMessages(restoredMessages);
5543
- const todosCheckpointPath = path14.join(wpaths.projectSessions, `${session.id}.todos.json`);
5560
+ const todosCheckpointPath = path15.join(wpaths.projectSessions, `${session.id}.todos.json`);
5544
5561
  if (resumeId) {
5545
5562
  try {
5546
5563
  const restoredTodos = await loadTodosCheckpoint(todosCheckpointPath);
@@ -5552,12 +5569,12 @@ async function setupSession(params) {
5552
5569
  }
5553
5570
  }
5554
5571
  const detachTodosCheckpoint = attachTodosCheckpoint(context.state, todosCheckpointPath, session.id);
5555
- const planPath = path14.join(wpaths.projectSessions, `${session.id}.plan.json`);
5572
+ const planPath = path15.join(wpaths.projectSessions, `${session.id}.plan.json`);
5556
5573
  context.state.setMeta("plan.path", planPath);
5557
5574
  if (resumeId) {
5558
5575
  try {
5559
- const fleetRoot = path14.join(wpaths.projectSessions, session.id);
5560
- const dirState = await loadDirectorState(path14.join(fleetRoot, "director-state.json"));
5576
+ const fleetRoot = path15.join(wpaths.projectSessions, session.id);
5577
+ const dirState = await loadDirectorState(path15.join(fleetRoot, "director-state.json"));
5561
5578
  if (dirState) {
5562
5579
  const tCounts = {};
5563
5580
  for (const t of dirState.tasks) tCounts[t.status] = (tCounts[t.status] ?? 0) + 1;
@@ -5584,7 +5601,7 @@ function resolveBundledSkillsDir2() {
5584
5601
  try {
5585
5602
  const req2 = createRequire(import.meta.url);
5586
5603
  const corePkg = req2.resolve("@wrongstack/core/package.json");
5587
- return path14.join(path14.dirname(corePkg), "skills");
5604
+ return path15.join(path15.dirname(corePkg), "skills");
5588
5605
  } catch {
5589
5606
  return void 0;
5590
5607
  }
@@ -5671,7 +5688,7 @@ async function main(argv) {
5671
5688
  modeId,
5672
5689
  modePrompt,
5673
5690
  modelCapabilities,
5674
- planPath: () => sessionRef.current ? path14.join(wpaths.projectSessions, `${sessionRef.current.id}.plan.json`) : void 0
5691
+ planPath: () => sessionRef.current ? path15.join(wpaths.projectSessions, `${sessionRef.current.id}.plan.json`) : void 0
5675
5692
  })
5676
5693
  );
5677
5694
  const toolRegistry = new ToolRegistry();
@@ -5716,7 +5733,7 @@ async function main(argv) {
5716
5733
  const dumpMetrics = () => {
5717
5734
  if (!metricsSink) return;
5718
5735
  try {
5719
- const out = path14.join(wpaths.projectSessions, "metrics.json");
5736
+ const out = path15.join(wpaths.projectSessions, "metrics.json");
5720
5737
  const snap = metricsSink.snapshot();
5721
5738
  writeFileSync(out, JSON.stringify(snap, null, 2));
5722
5739
  } catch {
@@ -5907,13 +5924,19 @@ async function main(argv) {
5907
5924
  }
5908
5925
  const switchProviderAndModel = (providerId, modelId) => {
5909
5926
  try {
5910
- const newCfg = config.providers?.[providerId] ?? {
5927
+ console.error("[DEBUG] switchProviderAndModel called with:", { providerId, modelId });
5928
+ const savedCfg = config.providers?.[providerId];
5929
+ const resolvedProviderId = savedCfg?.type ?? providerId;
5930
+ console.error("[DEBUG] switchProviderAndModel: resolvedProviderId:", resolvedProviderId, "savedCfg.type:", savedCfg?.type);
5931
+ const newCfg = savedCfg ?? {
5911
5932
  type: providerId,
5912
5933
  apiKey: config.apiKey,
5913
5934
  baseUrl: config.baseUrl
5914
5935
  };
5915
- const cfgWithType = { ...newCfg, type: providerId };
5916
- const newProvider = config.features.modelsRegistry && providerRegistry.has(providerId) ? providerRegistry.create(cfgWithType) : makeProviderFromConfig(providerId, cfgWithType);
5936
+ const cfgWithType = { ...newCfg, type: resolvedProviderId };
5937
+ console.error("[DEBUG] switchProviderAndModel: cfgWithType:", cfgWithType);
5938
+ const newProvider = config.features.modelsRegistry && providerRegistry.has(resolvedProviderId) ? providerRegistry.create(cfgWithType) : makeProviderFromConfig(resolvedProviderId, cfgWithType);
5939
+ console.error("[DEBUG] switchProviderAndModel: new provider id:", newProvider.id, "maxContext:", newProvider.capabilities.maxContext);
5917
5940
  context.provider = newProvider;
5918
5941
  context.model = modelId;
5919
5942
  config = patchConfig(config, { provider: providerId, model: modelId });
@@ -5925,12 +5948,12 @@ async function main(argv) {
5925
5948
  };
5926
5949
  const directorMode = flags["director"] === true;
5927
5950
  let director = null;
5928
- const fleetRoot = directorMode ? path14.join(wpaths.projectSessions, session.id) : void 0;
5929
- const manifestPath = directorMode ? typeof process.env["WRONGSTACK_FLEET_MANIFEST"] === "string" ? process.env["WRONGSTACK_FLEET_MANIFEST"] : path14.join(fleetRoot, "fleet.json") : void 0;
5930
- const sharedScratchpadPath = directorMode ? path14.join(fleetRoot, "shared") : void 0;
5931
- const subagentSessionsRoot = directorMode ? path14.join(fleetRoot, "subagents") : void 0;
5932
- const stateCheckpointPath = directorMode ? path14.join(fleetRoot, "director-state.json") : void 0;
5933
- const fleetRootForPromotion = path14.join(wpaths.projectSessions, session.id);
5951
+ const fleetRoot = directorMode ? path15.join(wpaths.projectSessions, session.id) : void 0;
5952
+ const manifestPath = directorMode ? typeof process.env["WRONGSTACK_FLEET_MANIFEST"] === "string" ? process.env["WRONGSTACK_FLEET_MANIFEST"] : path15.join(fleetRoot, "fleet.json") : void 0;
5953
+ const sharedScratchpadPath = directorMode ? path15.join(fleetRoot, "shared") : void 0;
5954
+ const subagentSessionsRoot = directorMode ? path15.join(fleetRoot, "subagents") : void 0;
5955
+ const stateCheckpointPath = directorMode ? path15.join(fleetRoot, "director-state.json") : void 0;
5956
+ const fleetRootForPromotion = path15.join(wpaths.projectSessions, session.id);
5934
5957
  const multiAgentHost = new MultiAgentHost(
5935
5958
  {
5936
5959
  container,
@@ -6082,7 +6105,7 @@ async function main(argv) {
6082
6105
  return `Unknown fleet action: ${action}`;
6083
6106
  },
6084
6107
  onFleetLog: async (subagentId, mode) => {
6085
- const subagentsRoot = path14.join(fleetRootForPromotion, "subagents");
6108
+ const subagentsRoot = path15.join(fleetRootForPromotion, "subagents");
6086
6109
  let runDirs;
6087
6110
  try {
6088
6111
  runDirs = await fs14.readdir(subagentsRoot);
@@ -6091,7 +6114,7 @@ async function main(argv) {
6091
6114
  }
6092
6115
  const found = [];
6093
6116
  for (const runId of runDirs) {
6094
- const runDir = path14.join(subagentsRoot, runId);
6117
+ const runDir = path15.join(subagentsRoot, runId);
6095
6118
  let files;
6096
6119
  try {
6097
6120
  files = await fs14.readdir(runDir);
@@ -6100,7 +6123,7 @@ async function main(argv) {
6100
6123
  }
6101
6124
  for (const f of files) {
6102
6125
  if (!f.endsWith(".jsonl")) continue;
6103
- const full = path14.join(runDir, f);
6126
+ const full = path15.join(runDir, f);
6104
6127
  try {
6105
6128
  const stat2 = await fs14.stat(full);
6106
6129
  found.push({
@@ -6197,7 +6220,7 @@ async function main(argv) {
6197
6220
  }
6198
6221
  const dir = await multiAgentHost.ensureDirector();
6199
6222
  if (!dir) return "Director is not available.";
6200
- const dirStatePath = path14.join(fleetRootForPromotion, "director-state.json");
6223
+ const dirStatePath = path15.join(fleetRootForPromotion, "director-state.json");
6201
6224
  const prior = await loadDirectorState(dirStatePath);
6202
6225
  if (!prior) {
6203
6226
  return "No prior director-state.json found \u2014 nothing to retry.";
@@ -6268,9 +6291,9 @@ async function main(argv) {
6268
6291
  for (const tool of director2.tools(FLEET_ROSTER)) {
6269
6292
  toolRegistry.register(tool);
6270
6293
  }
6271
- const mp = path14.join(fleetRootForPromotion, "fleet.json");
6272
- const sp = path14.join(fleetRootForPromotion, "shared");
6273
- const ss = path14.join(fleetRootForPromotion, "subagents");
6294
+ const mp = path15.join(fleetRootForPromotion, "fleet.json");
6295
+ const sp = path15.join(fleetRootForPromotion, "shared");
6296
+ const ss = path15.join(fleetRootForPromotion, "subagents");
6274
6297
  const lines = [
6275
6298
  `${color.green("\u2713")} Promoted to director mode.`,
6276
6299
  ` Roster: ${Object.keys(FLEET_ROSTER).join(", ")}`,