@wrongstack/cli 0.4.0 → 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 +98 -75
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
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
|
-
|
|
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" ?
|
|
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 ??
|
|
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(
|
|
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(
|
|
1288
|
-
if (await pathExists(
|
|
1289
|
-
if (await pathExists(
|
|
1290
|
-
if (await pathExists(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 =
|
|
1813
|
-
const file =
|
|
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(
|
|
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(
|
|
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 =
|
|
2260
|
-
const file =
|
|
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(`(${
|
|
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
|
|
2574
|
+
const path16 = typeof o["path"] === "string" ? o["path"] : "";
|
|
2570
2575
|
const reps = typeof o["replacements"] === "number" ? o["replacements"] : 0;
|
|
2571
|
-
return `${
|
|
2576
|
+
return `${path16} ${reps} replacement${reps === 1 ? "" : "s"}`.trim();
|
|
2572
2577
|
}
|
|
2573
2578
|
if (name === "write") {
|
|
2574
|
-
const
|
|
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 ? `${
|
|
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 =
|
|
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(
|
|
3443
|
-
await fs14.writeFile(
|
|
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
|
-
|
|
3504
|
-
|
|
3505
|
-
const
|
|
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 =
|
|
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(
|
|
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
|
|
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:
|
|
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:
|
|
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 ?
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
5191
|
-
if (e.name === "read" &&
|
|
5192
|
-
else if (e.name === "edit" &&
|
|
5193
|
-
else if (e.name === "write" &&
|
|
5194
|
-
this.writtenPaths.add(
|
|
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:
|
|
5539
|
-
const queueStore = new QueueStore({ dir:
|
|
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 =
|
|
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 =
|
|
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 =
|
|
5560
|
-
const dirState = await loadDirectorState(
|
|
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
|
|
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 ?
|
|
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 =
|
|
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
|
-
|
|
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:
|
|
5916
|
-
|
|
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 ?
|
|
5929
|
-
const manifestPath = directorMode ? typeof process.env["WRONGSTACK_FLEET_MANIFEST"] === "string" ? process.env["WRONGSTACK_FLEET_MANIFEST"] :
|
|
5930
|
-
const sharedScratchpadPath = directorMode ?
|
|
5931
|
-
const subagentSessionsRoot = directorMode ?
|
|
5932
|
-
const stateCheckpointPath = directorMode ?
|
|
5933
|
-
const fleetRootForPromotion =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
6272
|
-
const sp =
|
|
6273
|
-
const ss =
|
|
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(", ")}`,
|