@wrongstack/cli 0.7.6 → 0.7.7
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 +182 -125
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import * as
|
|
2
|
+
import * as path24 from 'path';
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
import * as fsp2 from 'fs/promises';
|
|
5
5
|
import { readdir, readFile } from 'fs/promises';
|
|
6
|
-
import { color, DefaultPathResolver, TOKENS, DefaultSystemPromptBuilder, makeAutonomyPromptContributor, ToolRegistry, createContextManagerTool, EventBus, SlashCommandRegistry, createDelegateTool, FLEET_ROSTER, createMcpControlTool, EternalAutonomyEngine, DefaultLogger, DefaultModelsRegistry, ProviderRegistry, InMemoryMetricsSink, wireMetricsToEvents, DefaultHealthRegistry, startMetricsServer, RecoveryLock, DefaultAttachmentStore, QueueStore, Context, loadTodosCheckpoint, attachTodosCheckpoint, loadDirectorState, loadPlan, createDefaultPipelines, AutoCompactionMiddleware, estimateRequestTokens, Agent, loadPlugins, FleetManager, makeDirectorSessionFactory, Director, AutoApprovePermissionPolicy, makeLLMClassifier, resolveWstackPaths, DefaultSecretVault, migratePlaintextSecrets, DefaultConfigLoader, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, atomicWrite, DefaultPluginAPI, makeAgentSubagentRunner, NULL_FLEET_BUS, formatContextWindowModeList, repairToolUseAdjacency, getContextWindowMode, resolveContextWindowPolicy, AGENTS_BY_PHASE, dispatchAgent, formatTodosList, emptyPlan, clearPlan, savePlan, formatPlanTemplates, getPlanTemplate, addPlanItem, formatPlan, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, SpecStore, TaskGraphStore, analyzeCriticalPath, getTemplate, listTemplates, templateToMarkdown, SpecParser, renderSpecAnalysis, AISpecBuilder, DefaultTaskStore, TaskTracker, renderProgress, renderTaskGraph, loadGoal, goalFilePath, summarizeUsage, saveGoal, emptyGoal, buildGoalPreamble, formatGoal, InputBuilder, FsError, ERROR_CODES, projectHash, WrongStackError, defaultOrchestrator, decryptConfigSecrets, encryptConfigSecrets as encryptConfigSecrets$1, SpecVersioning, ParallelEternalEngine, allServers as allServers$1 } from '@wrongstack/core';
|
|
6
|
+
import { color, DefaultPathResolver, TOKENS, DefaultSystemPromptBuilder, makeAutonomyPromptContributor, ToolRegistry, createContextManagerTool, EventBus, SlashCommandRegistry, createDelegateTool, FLEET_ROSTER, createMcpControlTool, EternalAutonomyEngine, DefaultLogger, DefaultModelsRegistry, ProviderRegistry, InMemoryMetricsSink, wireMetricsToEvents, DefaultHealthRegistry, startMetricsServer, RecoveryLock, DefaultAttachmentStore, QueueStore, Context, loadTodosCheckpoint, attachTodosCheckpoint, loadDirectorState, loadPlan, createDefaultPipelines, AutoCompactionMiddleware, estimateRequestTokens, Agent, loadPlugins, FleetManager, makeDirectorSessionFactory, Director, AutoApprovePermissionPolicy, makeLLMClassifier, resolveWstackPaths, DefaultSecretVault, migratePlaintextSecrets, DefaultConfigLoader, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, atomicWrite, DefaultPluginAPI, makeAgentSubagentRunner, NULL_FLEET_BUS, formatContextWindowModeList, repairToolUseAdjacency, getContextWindowMode, resolveContextWindowPolicy, AGENTS_BY_PHASE, dispatchAgent, formatTodosList, emptyPlan, clearPlan, savePlan, formatPlanTemplates, getPlanTemplate, addPlanItem, formatPlan, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, SpecStore, TaskGraphStore, analyzeCriticalPath, getTemplate, listTemplates, templateToMarkdown, SpecParser, renderSpecAnalysis, AISpecBuilder, DefaultTaskStore, TaskTracker, renderProgress, renderTaskGraph, loadGoal, goalFilePath, summarizeUsage, saveGoal, emptyGoal, buildGoalPreamble, formatGoal, pendingBtwCount, setBtwNote, InputBuilder, FsError, ERROR_CODES, projectHash, WrongStackError, defaultOrchestrator, decryptConfigSecrets, encryptConfigSecrets as encryptConfigSecrets$1, SpecVersioning, ParallelEternalEngine, allServers as allServers$1 } from '@wrongstack/core';
|
|
7
7
|
import { createRequire } from 'module';
|
|
8
8
|
import * as os6 from 'os';
|
|
9
9
|
import os6__default from 'os';
|
|
@@ -16,6 +16,8 @@ import { buildProviderFactoriesFromRegistry, makeProviderFromConfig, capabilitie
|
|
|
16
16
|
import { createDefaultContainer, routeImagesForModel, readClipboardImage } from '@wrongstack/runtime';
|
|
17
17
|
import { builtinToolsPack, rememberTool, forgetTool } from '@wrongstack/tools';
|
|
18
18
|
import * as readline from 'readline';
|
|
19
|
+
import * as fs4 from 'fs';
|
|
20
|
+
import { writeFileSync } from 'fs';
|
|
19
21
|
import { spawn } from 'child_process';
|
|
20
22
|
import { SkillInstaller } from '@wrongstack/core/skills';
|
|
21
23
|
import { WrongStackACPServer } from '@wrongstack/acp/agent';
|
|
@@ -24,7 +26,6 @@ import { ACP_AGENTS, SubagentBudget } from '@wrongstack/core/coordination';
|
|
|
24
26
|
import { allServers } from '@wrongstack/core/infrastructure';
|
|
25
27
|
import { createToolVisionAdapters } from '@wrongstack/runtime/vision';
|
|
26
28
|
import { ToolExecutor } from '@wrongstack/core/execution';
|
|
27
|
-
import { writeFileSync } from 'fs';
|
|
28
29
|
|
|
29
30
|
var __defProp = Object.defineProperty;
|
|
30
31
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -1397,7 +1398,7 @@ function sddHelp() {
|
|
|
1397
1398
|
async function gatherProjectContext(projectRoot) {
|
|
1398
1399
|
const parts = [];
|
|
1399
1400
|
try {
|
|
1400
|
-
const pkgPath =
|
|
1401
|
+
const pkgPath = path24.join(projectRoot, "package.json");
|
|
1401
1402
|
const pkgRaw = await fsp2.readFile(pkgPath, "utf8");
|
|
1402
1403
|
const pkg = JSON.parse(pkgRaw);
|
|
1403
1404
|
parts.push(`Project: ${String(pkg.name ?? "unknown")}`);
|
|
@@ -1413,13 +1414,13 @@ async function gatherProjectContext(projectRoot) {
|
|
|
1413
1414
|
} catch {
|
|
1414
1415
|
}
|
|
1415
1416
|
try {
|
|
1416
|
-
const tsconfigPath =
|
|
1417
|
+
const tsconfigPath = path24.join(projectRoot, "tsconfig.json");
|
|
1417
1418
|
await fsp2.access(tsconfigPath);
|
|
1418
1419
|
parts.push("Language: TypeScript");
|
|
1419
1420
|
} catch {
|
|
1420
1421
|
}
|
|
1421
1422
|
try {
|
|
1422
|
-
const srcDir =
|
|
1423
|
+
const srcDir = path24.join(projectRoot, "src");
|
|
1423
1424
|
const entries = await fsp2.readdir(srcDir, { withFileTypes: true });
|
|
1424
1425
|
const dirs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
1425
1426
|
if (dirs.length > 0) {
|
|
@@ -1575,7 +1576,7 @@ __export(update_check_exports, {
|
|
|
1575
1576
|
getUpdateNotification: () => getUpdateNotification
|
|
1576
1577
|
});
|
|
1577
1578
|
function cachePath(homeFn = defaultHomeDir2) {
|
|
1578
|
-
return
|
|
1579
|
+
return path24.join(homeFn(), ".wrongstack", "update-cache.json");
|
|
1579
1580
|
}
|
|
1580
1581
|
function currentVersion() {
|
|
1581
1582
|
const req2 = createRequire(import.meta.url);
|
|
@@ -1612,7 +1613,7 @@ async function readCache(homeFn = defaultHomeDir2) {
|
|
|
1612
1613
|
}
|
|
1613
1614
|
async function writeCache(entry, homeFn = defaultHomeDir2) {
|
|
1614
1615
|
try {
|
|
1615
|
-
const dir =
|
|
1616
|
+
const dir = path24.dirname(cachePath(homeFn));
|
|
1616
1617
|
await fsp2.mkdir(dir, { recursive: true });
|
|
1617
1618
|
await fsp2.writeFile(cachePath(homeFn), JSON.stringify(entry, null, 2), "utf8");
|
|
1618
1619
|
} catch {
|
|
@@ -2216,7 +2217,7 @@ async function runWebUI(opts) {
|
|
|
2216
2217
|
return {};
|
|
2217
2218
|
}
|
|
2218
2219
|
if (!parsed.providers) return {};
|
|
2219
|
-
const keyFile =
|
|
2220
|
+
const keyFile = path24.join(path24.dirname(opts.globalConfigPath), ".key");
|
|
2220
2221
|
const vault = new DefaultSecretVault$1({ keyFile });
|
|
2221
2222
|
return decryptConfigSecrets$1(parsed.providers, vault);
|
|
2222
2223
|
}
|
|
@@ -2249,7 +2250,7 @@ async function runWebUI(opts) {
|
|
|
2249
2250
|
parsed = {};
|
|
2250
2251
|
}
|
|
2251
2252
|
parsed.providers = providers;
|
|
2252
|
-
const keyFile =
|
|
2253
|
+
const keyFile = path24.join(path24.dirname(opts.globalConfigPath), ".key");
|
|
2253
2254
|
const vault = new DefaultSecretVault$1({ keyFile });
|
|
2254
2255
|
const encrypted = encryptConfigSecrets(parsed, vault);
|
|
2255
2256
|
await atomicWrite(opts.globalConfigPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
|
|
@@ -2453,7 +2454,7 @@ function parseSpawnFlags(input) {
|
|
|
2453
2454
|
return { description: rest.trim(), opts };
|
|
2454
2455
|
}
|
|
2455
2456
|
async function bootConfig(flags) {
|
|
2456
|
-
const cwd = typeof flags["cwd"] === "string" ?
|
|
2457
|
+
const cwd = typeof flags["cwd"] === "string" ? path24.resolve(flags["cwd"]) : process.cwd();
|
|
2457
2458
|
const pathResolver = new DefaultPathResolver(cwd);
|
|
2458
2459
|
const projectRoot = pathResolver.projectRoot;
|
|
2459
2460
|
const userHome = os6.homedir();
|
|
@@ -2520,7 +2521,7 @@ var ReadlineInputReader = class {
|
|
|
2520
2521
|
history = [];
|
|
2521
2522
|
pending = false;
|
|
2522
2523
|
constructor(opts = {}) {
|
|
2523
|
-
this.historyFile = opts.historyFile ??
|
|
2524
|
+
this.historyFile = opts.historyFile ?? path24.join(os6.homedir(), ".wrongstack", "history");
|
|
2524
2525
|
}
|
|
2525
2526
|
async loadHistory() {
|
|
2526
2527
|
try {
|
|
@@ -2532,7 +2533,7 @@ var ReadlineInputReader = class {
|
|
|
2532
2533
|
}
|
|
2533
2534
|
async saveHistory() {
|
|
2534
2535
|
try {
|
|
2535
|
-
await fsp2.mkdir(
|
|
2536
|
+
await fsp2.mkdir(path24.dirname(this.historyFile), { recursive: true });
|
|
2536
2537
|
await fsp2.writeFile(this.historyFile, this.history.slice(-1e3).join("\n"));
|
|
2537
2538
|
} catch {
|
|
2538
2539
|
}
|
|
@@ -2759,20 +2760,20 @@ function assertSafeToDelete(filename, parentDir) {
|
|
|
2759
2760
|
if (PROTECTED_BASENAMES.has(filename)) {
|
|
2760
2761
|
throw new Error(`Refusing to delete protected file: ${filename}`);
|
|
2761
2762
|
}
|
|
2762
|
-
if (filename !==
|
|
2763
|
+
if (filename !== path24.basename(filename)) {
|
|
2763
2764
|
throw new Error(`Refusing to delete path with traversal: ${filename}`);
|
|
2764
2765
|
}
|
|
2765
2766
|
if (!filename.startsWith("config.json.") || !filename.endsWith(".bak")) {
|
|
2766
2767
|
throw new Error(`Refusing to delete unknown file: ${filename}`);
|
|
2767
2768
|
}
|
|
2768
|
-
const resolvedParent =
|
|
2769
|
+
const resolvedParent = path24.resolve(parentDir);
|
|
2769
2770
|
if (!resolvedParent.endsWith(".wrongstack")) {
|
|
2770
2771
|
throw new Error(`Unexpected parent directory for bak prune: ${resolvedParent}`);
|
|
2771
2772
|
}
|
|
2772
2773
|
}
|
|
2773
2774
|
async function safeDelete(filePath) {
|
|
2774
|
-
const dir =
|
|
2775
|
-
const filename =
|
|
2775
|
+
const dir = path24.dirname(filePath);
|
|
2776
|
+
const filename = path24.basename(filePath);
|
|
2776
2777
|
try {
|
|
2777
2778
|
assertSafeToDelete(filename, dir);
|
|
2778
2779
|
await fsp2.unlink(filePath);
|
|
@@ -2817,16 +2818,16 @@ function diffSummary(oldCfg, newCfg) {
|
|
|
2817
2818
|
}
|
|
2818
2819
|
var defaultHomeDir = () => os6__default.homedir();
|
|
2819
2820
|
function historyDir(homeFn = defaultHomeDir) {
|
|
2820
|
-
return
|
|
2821
|
+
return path24.join(homeFn(), ".wrongstack", "config.history", "entries");
|
|
2821
2822
|
}
|
|
2822
2823
|
function historyIndexPath(homeFn = defaultHomeDir) {
|
|
2823
|
-
return
|
|
2824
|
+
return path24.join(homeFn(), ".wrongstack", "config.history", "index.json");
|
|
2824
2825
|
}
|
|
2825
2826
|
function configPath(homeFn = defaultHomeDir) {
|
|
2826
|
-
return
|
|
2827
|
+
return path24.join(homeFn(), ".wrongstack", "config.json");
|
|
2827
2828
|
}
|
|
2828
2829
|
function backupLastPath(homeFn = defaultHomeDir) {
|
|
2829
|
-
return
|
|
2830
|
+
return path24.join(homeFn(), ".wrongstack", "config.json.last");
|
|
2830
2831
|
}
|
|
2831
2832
|
function entryId(ts) {
|
|
2832
2833
|
return ts.replace(/[:.]/g, "-").slice(0, 19);
|
|
@@ -2881,17 +2882,17 @@ async function backupCurrent(homeFn = defaultHomeDir) {
|
|
|
2881
2882
|
}
|
|
2882
2883
|
if (content !== void 0) {
|
|
2883
2884
|
try {
|
|
2884
|
-
const bakPath =
|
|
2885
|
+
const bakPath = path24.join(homeFn(), ".wrongstack", `config.json.${ts}.bak`);
|
|
2885
2886
|
await atomicWrite(bakPath, content);
|
|
2886
2887
|
} catch {
|
|
2887
2888
|
}
|
|
2888
2889
|
}
|
|
2889
2890
|
try {
|
|
2890
|
-
const dir =
|
|
2891
|
+
const dir = path24.join(homeFn(), ".wrongstack");
|
|
2891
2892
|
const files = await fsp2.readdir(dir);
|
|
2892
2893
|
const baks = files.filter((f) => f.startsWith("config.json.") && f.endsWith(".bak")).sort().reverse();
|
|
2893
2894
|
for (const f of baks.slice(10)) {
|
|
2894
|
-
await safeDelete(
|
|
2895
|
+
await safeDelete(path24.join(dir, f));
|
|
2895
2896
|
}
|
|
2896
2897
|
} catch {
|
|
2897
2898
|
}
|
|
@@ -2909,7 +2910,7 @@ async function appendHistory(oldCfg, newCfg, description, homeFn = defaultHomeDi
|
|
|
2909
2910
|
};
|
|
2910
2911
|
try {
|
|
2911
2912
|
await fsp2.writeFile(
|
|
2912
|
-
|
|
2913
|
+
path24.join(historyDir(homeFn), `${id}.json`),
|
|
2913
2914
|
JSON.stringify(entry, null, 2),
|
|
2914
2915
|
"utf8"
|
|
2915
2916
|
);
|
|
@@ -2917,7 +2918,7 @@ async function appendHistory(oldCfg, newCfg, description, homeFn = defaultHomeDi
|
|
|
2917
2918
|
throw new FsError({
|
|
2918
2919
|
message: err instanceof Error ? err.message : String(err),
|
|
2919
2920
|
code: ERROR_CODES.FS_WRITE_FAILED,
|
|
2920
|
-
path:
|
|
2921
|
+
path: path24.join(historyDir(homeFn), `${id}.json`),
|
|
2921
2922
|
cause: err
|
|
2922
2923
|
});
|
|
2923
2924
|
}
|
|
@@ -2932,7 +2933,7 @@ async function listHistory(homeFn = defaultHomeDir) {
|
|
|
2932
2933
|
}
|
|
2933
2934
|
async function getHistoryEntry(id, homeFn = defaultHomeDir) {
|
|
2934
2935
|
try {
|
|
2935
|
-
const raw = await fsp2.readFile(
|
|
2936
|
+
const raw = await fsp2.readFile(path24.join(historyDir(homeFn), `${id}.json`), "utf8");
|
|
2936
2937
|
return JSON.parse(raw);
|
|
2937
2938
|
} catch {
|
|
2938
2939
|
return null;
|
|
@@ -2992,10 +2993,10 @@ var theme = { primary: color.amber };
|
|
|
2992
2993
|
async function saveToGlobalConfig(configPath2, provider, model, homeFn = () => process.env.HOME ?? __require("os").homedir()) {
|
|
2993
2994
|
try {
|
|
2994
2995
|
const { atomicWrite: atomicWrite8 } = await import('@wrongstack/core');
|
|
2995
|
-
const
|
|
2996
|
+
const fs21 = await import('fs/promises');
|
|
2996
2997
|
let existing = {};
|
|
2997
2998
|
try {
|
|
2998
|
-
const raw = await
|
|
2999
|
+
const raw = await fs21.readFile(configPath2, "utf8");
|
|
2999
3000
|
existing = JSON.parse(raw);
|
|
3000
3001
|
} catch {
|
|
3001
3002
|
}
|
|
@@ -3284,6 +3285,7 @@ var GROUPS = [
|
|
|
3284
3285
|
items: [
|
|
3285
3286
|
{ key: "Esc (while busy)", blurb: "soft interrupt \u2014 next message carries a STEERING preamble" },
|
|
3286
3287
|
{ key: "/steer <text>", blurb: "mid-flight redirect, works when Esc is eaten by tmux" },
|
|
3288
|
+
{ key: "/btw <note>", blurb: "non-aborting nudge \u2014 agent folds it in at its next step" },
|
|
3287
3289
|
{ key: "Ctrl+C \xD7 1 / \xD7 2 / \xD7 3", blurb: "cancel iteration \xB7 force-exit Ink \xB7 hard exit(130)" }
|
|
3288
3290
|
]
|
|
3289
3291
|
},
|
|
@@ -3309,7 +3311,8 @@ var GROUPS = [
|
|
|
3309
3311
|
]
|
|
3310
3312
|
}
|
|
3311
3313
|
];
|
|
3312
|
-
|
|
3314
|
+
GROUPS.reduce((n, g) => n + g.items.length, 0);
|
|
3315
|
+
GROUPS.map((g) => g.title);
|
|
3313
3316
|
function shouldSuppress(flags) {
|
|
3314
3317
|
if (flags["no-hints"] === true) return true;
|
|
3315
3318
|
if (flags["hints"] === false) return true;
|
|
@@ -3317,22 +3320,41 @@ function shouldSuppress(flags) {
|
|
|
3317
3320
|
if (env && env !== "0" && env.toLowerCase() !== "false") return true;
|
|
3318
3321
|
return false;
|
|
3319
3322
|
}
|
|
3320
|
-
|
|
3323
|
+
var wrap = (n) => (n % GROUPS.length + GROUPS.length) % GROUPS.length;
|
|
3324
|
+
function pickGroupIndex(opts) {
|
|
3325
|
+
if (typeof opts.groupIndex === "number") return wrap(opts.groupIndex);
|
|
3326
|
+
if (opts.cursorFile) {
|
|
3327
|
+
try {
|
|
3328
|
+
let current = 0;
|
|
3329
|
+
try {
|
|
3330
|
+
const parsed = Number.parseInt(fs4.readFileSync(opts.cursorFile, "utf8").trim(), 10);
|
|
3331
|
+
if (Number.isFinite(parsed)) current = wrap(parsed);
|
|
3332
|
+
} catch {
|
|
3333
|
+
}
|
|
3334
|
+
fs4.mkdirSync(path24.dirname(opts.cursorFile), { recursive: true });
|
|
3335
|
+
fs4.writeFileSync(opts.cursorFile, String(wrap(current + 1)));
|
|
3336
|
+
return current;
|
|
3337
|
+
} catch {
|
|
3338
|
+
}
|
|
3339
|
+
}
|
|
3340
|
+
return Math.floor(Math.random() * GROUPS.length);
|
|
3341
|
+
}
|
|
3342
|
+
function printLaunchHints(renderer, flags, opts = {}) {
|
|
3321
3343
|
if (shouldSuppress(flags)) return;
|
|
3344
|
+
const idx = pickGroupIndex(opts);
|
|
3345
|
+
const group = GROUPS[idx];
|
|
3346
|
+
if (!group) return;
|
|
3322
3347
|
const lines = [];
|
|
3323
3348
|
lines.push("");
|
|
3324
3349
|
lines.push(
|
|
3325
|
-
` ${color.cyan("\u25C6")} ${color.bold(`
|
|
3350
|
+
` ${color.cyan("\u25C6")} ${color.bold(group.title)} ${color.dim(`(${idx + 1}/${GROUPS.length} \xB7 more each launch)`)}`
|
|
3326
3351
|
);
|
|
3327
|
-
for (const
|
|
3328
|
-
lines.push(` ${color.dim("\
|
|
3329
|
-
for (const item of group.items) {
|
|
3330
|
-
lines.push(` ${color.bold(item.key)} ${color.dim("\u2014")} ${color.dim(item.blurb)}`);
|
|
3331
|
-
}
|
|
3352
|
+
for (const item of group.items) {
|
|
3353
|
+
lines.push(` ${color.bold(item.key)} ${color.dim("\u2014")} ${color.dim(item.blurb)}`);
|
|
3332
3354
|
}
|
|
3333
3355
|
lines.push("");
|
|
3334
3356
|
lines.push(
|
|
3335
|
-
` ${color.dim(
|
|
3357
|
+
` ${color.dim(`${color.bold("/help")} lists everything \xB7 hide with ${color.bold("--no-hints")}`)}`
|
|
3336
3358
|
);
|
|
3337
3359
|
lines.push("");
|
|
3338
3360
|
renderer.write(`${lines.join("\n")}
|
|
@@ -3351,10 +3373,10 @@ async function detectPackageManager(root, declared) {
|
|
|
3351
3373
|
const name = declared.split("@")[0];
|
|
3352
3374
|
if (name) return name;
|
|
3353
3375
|
}
|
|
3354
|
-
if (await pathExists(
|
|
3355
|
-
if (await pathExists(
|
|
3356
|
-
if (await pathExists(
|
|
3357
|
-
if (await pathExists(
|
|
3376
|
+
if (await pathExists(path24.join(root, "pnpm-lock.yaml"))) return "pnpm";
|
|
3377
|
+
if (await pathExists(path24.join(root, "bun.lockb"))) return "bun";
|
|
3378
|
+
if (await pathExists(path24.join(root, "bun.lock"))) return "bun";
|
|
3379
|
+
if (await pathExists(path24.join(root, "yarn.lock"))) return "yarn";
|
|
3358
3380
|
return "npm";
|
|
3359
3381
|
}
|
|
3360
3382
|
function hasUsableScript(scripts, name) {
|
|
@@ -3375,7 +3397,7 @@ function parseMakeTargets(makefile) {
|
|
|
3375
3397
|
async function detectProjectFacts(root) {
|
|
3376
3398
|
const facts = { hints: [] };
|
|
3377
3399
|
try {
|
|
3378
|
-
const pkg = JSON.parse(await fsp2.readFile(
|
|
3400
|
+
const pkg = JSON.parse(await fsp2.readFile(path24.join(root, "package.json"), "utf8"));
|
|
3379
3401
|
const scripts = pkg.scripts ?? {};
|
|
3380
3402
|
const pm = await detectPackageManager(root, pkg.packageManager);
|
|
3381
3403
|
if (hasUsableScript(scripts, "build")) facts.build = `${pm} run build`;
|
|
@@ -3389,14 +3411,14 @@ async function detectProjectFacts(root) {
|
|
|
3389
3411
|
} catch {
|
|
3390
3412
|
}
|
|
3391
3413
|
try {
|
|
3392
|
-
if (!await pathExists(
|
|
3414
|
+
if (!await pathExists(path24.join(root, "pyproject.toml"))) throw new Error("not python");
|
|
3393
3415
|
facts.test ??= "pytest";
|
|
3394
3416
|
facts.lint ??= "ruff check .";
|
|
3395
3417
|
facts.hints.push("pyproject.toml");
|
|
3396
3418
|
} catch {
|
|
3397
3419
|
}
|
|
3398
3420
|
try {
|
|
3399
|
-
if (!await pathExists(
|
|
3421
|
+
if (!await pathExists(path24.join(root, "go.mod"))) throw new Error("not go");
|
|
3400
3422
|
facts.build ??= "go build ./...";
|
|
3401
3423
|
facts.test ??= "go test ./...";
|
|
3402
3424
|
facts.run ??= "go run .";
|
|
@@ -3404,7 +3426,7 @@ async function detectProjectFacts(root) {
|
|
|
3404
3426
|
} catch {
|
|
3405
3427
|
}
|
|
3406
3428
|
try {
|
|
3407
|
-
if (!await pathExists(
|
|
3429
|
+
if (!await pathExists(path24.join(root, "Cargo.toml"))) throw new Error("not rust");
|
|
3408
3430
|
facts.build ??= "cargo build";
|
|
3409
3431
|
facts.test ??= "cargo test";
|
|
3410
3432
|
facts.lint ??= "cargo clippy";
|
|
@@ -3413,7 +3435,7 @@ async function detectProjectFacts(root) {
|
|
|
3413
3435
|
} catch {
|
|
3414
3436
|
}
|
|
3415
3437
|
try {
|
|
3416
|
-
const makefile = await fsp2.readFile(
|
|
3438
|
+
const makefile = await fsp2.readFile(path24.join(root, "Makefile"), "utf8");
|
|
3417
3439
|
const targets = parseMakeTargets(makefile);
|
|
3418
3440
|
facts.build ??= targets.has("build") ? "make build" : "make";
|
|
3419
3441
|
if (targets.has("test")) facts.test ??= "make test";
|
|
@@ -4305,8 +4327,8 @@ function buildInitCommand(opts) {
|
|
|
4305
4327
|
name: "init",
|
|
4306
4328
|
description: "Create or update .wrongstack/AGENTS.md project context for the system prompt.",
|
|
4307
4329
|
async run(_args, ctx) {
|
|
4308
|
-
const dir =
|
|
4309
|
-
const file =
|
|
4330
|
+
const dir = path24.join(ctx.projectRoot, ".wrongstack");
|
|
4331
|
+
const file = path24.join(dir, "AGENTS.md");
|
|
4310
4332
|
const detected = await detectProjectFacts(ctx.projectRoot);
|
|
4311
4333
|
const body = renderAgentsTemplate(detected);
|
|
4312
4334
|
await fsp2.mkdir(dir, { recursive: true });
|
|
@@ -4497,18 +4519,18 @@ function stateBadge(state) {
|
|
|
4497
4519
|
return color.dim(state);
|
|
4498
4520
|
}
|
|
4499
4521
|
}
|
|
4500
|
-
async function readConfig(
|
|
4522
|
+
async function readConfig(path25) {
|
|
4501
4523
|
try {
|
|
4502
|
-
return JSON.parse(await fsp2.readFile(
|
|
4524
|
+
return JSON.parse(await fsp2.readFile(path25, "utf8"));
|
|
4503
4525
|
} catch {
|
|
4504
4526
|
return {};
|
|
4505
4527
|
}
|
|
4506
4528
|
}
|
|
4507
|
-
async function writeConfig(
|
|
4529
|
+
async function writeConfig(path25, cfg) {
|
|
4508
4530
|
const raw = JSON.stringify(cfg, null, 2);
|
|
4509
|
-
const tmp =
|
|
4531
|
+
const tmp = path25 + ".tmp";
|
|
4510
4532
|
await fsp2.writeFile(tmp, raw, "utf8");
|
|
4511
|
-
await fsp2.rename(tmp,
|
|
4533
|
+
await fsp2.rename(tmp, path25);
|
|
4512
4534
|
}
|
|
4513
4535
|
|
|
4514
4536
|
// src/slash-commands/mcp.ts
|
|
@@ -5194,6 +5216,38 @@ ${color.dim("YOLO forced ON. Use /autonomy stop to end. Journal at /goal journal
|
|
|
5194
5216
|
}
|
|
5195
5217
|
};
|
|
5196
5218
|
}
|
|
5219
|
+
function buildBtwCommand(opts) {
|
|
5220
|
+
return {
|
|
5221
|
+
name: "btw",
|
|
5222
|
+
description: 'Drop a "by the way" note for the running agent without interrupting it \u2014 delivered at the next step',
|
|
5223
|
+
argsHint: "<note>",
|
|
5224
|
+
help: [
|
|
5225
|
+
"/btw <note> Stash a note; the agent reads it at the start of its next",
|
|
5226
|
+
" iteration (between tool calls) without restarting.",
|
|
5227
|
+
"/btw Show how many notes are pending.",
|
|
5228
|
+
"",
|
|
5229
|
+
"Use `/steer` instead when you need to abort the current work immediately."
|
|
5230
|
+
].join("\n"),
|
|
5231
|
+
async run(args) {
|
|
5232
|
+
const ctx = opts.context;
|
|
5233
|
+
if (!ctx) {
|
|
5234
|
+
return { message: "No active session \u2014 start a turn first, then use /btw to nudge it." };
|
|
5235
|
+
}
|
|
5236
|
+
const text = args.trim();
|
|
5237
|
+
if (!text) {
|
|
5238
|
+
const n = pendingBtwCount(ctx);
|
|
5239
|
+
return {
|
|
5240
|
+
message: n === 0 ? "No notes pending. Usage: /btw <note>" : `${n} note(s) pending \u2014 will reach the agent at its next step.`
|
|
5241
|
+
};
|
|
5242
|
+
}
|
|
5243
|
+
const pending = setBtwNote(ctx, text);
|
|
5244
|
+
return {
|
|
5245
|
+
message: `\u21AF Noted (${pending} pending) \u2014 the agent will fold this in at its next step:
|
|
5246
|
+
${text}`
|
|
5247
|
+
};
|
|
5248
|
+
}
|
|
5249
|
+
};
|
|
5250
|
+
}
|
|
5197
5251
|
var KNOWN_VERBS = /* @__PURE__ */ new Set([
|
|
5198
5252
|
"",
|
|
5199
5253
|
"show",
|
|
@@ -5705,7 +5759,7 @@ var DEFAULTS = {
|
|
|
5705
5759
|
cost: true
|
|
5706
5760
|
};
|
|
5707
5761
|
function resolveConfigPath() {
|
|
5708
|
-
return process.env[CONFIG_ENV] ??
|
|
5762
|
+
return process.env[CONFIG_ENV] ?? path24.join(process.env.HOME ?? "", ".wrongstack", "statusline.json");
|
|
5709
5763
|
}
|
|
5710
5764
|
async function loadStatuslineConfig() {
|
|
5711
5765
|
const p = resolveConfigPath();
|
|
@@ -5719,7 +5773,7 @@ async function loadStatuslineConfig() {
|
|
|
5719
5773
|
async function saveStatuslineConfig(cfg) {
|
|
5720
5774
|
const p = resolveConfigPath();
|
|
5721
5775
|
try {
|
|
5722
|
-
await fsp2.mkdir(
|
|
5776
|
+
await fsp2.mkdir(path24.dirname(p), { recursive: true });
|
|
5723
5777
|
await atomicWrite(p, JSON.stringify(cfg, null, 2));
|
|
5724
5778
|
} catch (err) {
|
|
5725
5779
|
throw new FsError({
|
|
@@ -6618,11 +6672,11 @@ When the error confidence is low (< 0.85) or the problem spans multiple files,
|
|
|
6618
6672
|
};
|
|
6619
6673
|
}
|
|
6620
6674
|
function makeInstaller(opts, projectRoot, global) {
|
|
6621
|
-
const globalRoot =
|
|
6675
|
+
const globalRoot = path24.join(os6.homedir(), ".wrongstack");
|
|
6622
6676
|
return new SkillInstaller({
|
|
6623
|
-
manifestPath:
|
|
6624
|
-
projectSkillsDir:
|
|
6625
|
-
globalSkillsDir:
|
|
6677
|
+
manifestPath: path24.join(globalRoot, "installed-skills.json"),
|
|
6678
|
+
projectSkillsDir: path24.join(projectRoot, ".wrongstack", "skills"),
|
|
6679
|
+
globalSkillsDir: path24.join(globalRoot, "skills"),
|
|
6626
6680
|
projectHash: projectHash(projectRoot),
|
|
6627
6681
|
skillLoader: opts.skillLoader
|
|
6628
6682
|
});
|
|
@@ -6812,6 +6866,7 @@ function buildBuiltinSlashCommands(opts) {
|
|
|
6812
6866
|
buildYoloCommand(opts),
|
|
6813
6867
|
buildAutonomyCommand(opts),
|
|
6814
6868
|
buildGoalCommand(opts),
|
|
6869
|
+
buildBtwCommand(opts),
|
|
6815
6870
|
buildModeCommand(opts),
|
|
6816
6871
|
buildExitCommand(opts),
|
|
6817
6872
|
buildCommitCommand(),
|
|
@@ -6846,13 +6901,13 @@ var MANIFESTS = [
|
|
|
6846
6901
|
];
|
|
6847
6902
|
async function detectProjectKind(projectRoot) {
|
|
6848
6903
|
try {
|
|
6849
|
-
await fsp2.access(
|
|
6904
|
+
await fsp2.access(path24.join(projectRoot, ".wrongstack", "AGENTS.md"));
|
|
6850
6905
|
return "initialized";
|
|
6851
6906
|
} catch {
|
|
6852
6907
|
}
|
|
6853
6908
|
for (const m of MANIFESTS) {
|
|
6854
6909
|
try {
|
|
6855
|
-
await fsp2.access(
|
|
6910
|
+
await fsp2.access(path24.join(projectRoot, m));
|
|
6856
6911
|
return "project";
|
|
6857
6912
|
} catch {
|
|
6858
6913
|
}
|
|
@@ -6860,8 +6915,8 @@ async function detectProjectKind(projectRoot) {
|
|
|
6860
6915
|
return "empty";
|
|
6861
6916
|
}
|
|
6862
6917
|
async function scaffoldAgentsMd(projectRoot) {
|
|
6863
|
-
const dir =
|
|
6864
|
-
const file =
|
|
6918
|
+
const dir = path24.join(projectRoot, ".wrongstack");
|
|
6919
|
+
const file = path24.join(dir, "AGENTS.md");
|
|
6865
6920
|
const facts = await detectProjectFacts(projectRoot);
|
|
6866
6921
|
const body = renderAgentsTemplate(facts);
|
|
6867
6922
|
await fsp2.mkdir(dir, { recursive: true });
|
|
@@ -6874,7 +6929,7 @@ async function runProjectCheck(opts) {
|
|
|
6874
6929
|
if (kind === "initialized") {
|
|
6875
6930
|
renderer.write(
|
|
6876
6931
|
`
|
|
6877
|
-
${color.green("\u2713")} Project initialized ${color.dim(`(${
|
|
6932
|
+
${color.green("\u2713")} Project initialized ${color.dim(`(${path24.join(projectRoot, ".wrongstack", "AGENTS.md")})`)}
|
|
6878
6933
|
`
|
|
6879
6934
|
);
|
|
6880
6935
|
return true;
|
|
@@ -6905,7 +6960,7 @@ async function runProjectCheck(opts) {
|
|
|
6905
6960
|
}
|
|
6906
6961
|
return true;
|
|
6907
6962
|
}
|
|
6908
|
-
const gitDir =
|
|
6963
|
+
const gitDir = path24.join(projectRoot, ".git");
|
|
6909
6964
|
let hasGit = false;
|
|
6910
6965
|
try {
|
|
6911
6966
|
await fsp2.access(gitDir);
|
|
@@ -7298,14 +7353,14 @@ function summarize(value, name) {
|
|
|
7298
7353
|
if (typeof v === "object" && v !== null) {
|
|
7299
7354
|
const o = v;
|
|
7300
7355
|
if (name === "edit") {
|
|
7301
|
-
const
|
|
7356
|
+
const path25 = typeof o["path"] === "string" ? o["path"] : "";
|
|
7302
7357
|
const reps = typeof o["replacements"] === "number" ? o["replacements"] : 0;
|
|
7303
|
-
return `${
|
|
7358
|
+
return `${path25} ${reps} replacement${reps === 1 ? "" : "s"}`.trim();
|
|
7304
7359
|
}
|
|
7305
7360
|
if (name === "write") {
|
|
7306
|
-
const
|
|
7361
|
+
const path25 = typeof o["path"] === "string" ? o["path"] : "";
|
|
7307
7362
|
const bytes = typeof o["bytes"] === "number" ? o["bytes"] : void 0;
|
|
7308
|
-
return bytes !== void 0 ? `${
|
|
7363
|
+
return bytes !== void 0 ? `${path25} ${bytes}B` : path25;
|
|
7309
7364
|
}
|
|
7310
7365
|
if (typeof o["count"] === "number") {
|
|
7311
7366
|
return `${o["count"]} match${o["count"] === 1 ? "" : "es"}`;
|
|
@@ -8315,7 +8370,7 @@ var doctorCmd = async (_args, deps) => {
|
|
|
8315
8370
|
}
|
|
8316
8371
|
try {
|
|
8317
8372
|
await fsp2.mkdir(deps.paths.projectSessions, { recursive: true });
|
|
8318
|
-
const probe =
|
|
8373
|
+
const probe = path24.join(deps.paths.projectSessions, `.probe-${Date.now()}`);
|
|
8319
8374
|
await fsp2.writeFile(probe, "");
|
|
8320
8375
|
await fsp2.unlink(probe);
|
|
8321
8376
|
checks.push({ name: "sessions writable", status: "ok", detail: deps.paths.projectSessions });
|
|
@@ -8418,8 +8473,8 @@ var exportCmd = async (args, deps) => {
|
|
|
8418
8473
|
return 1;
|
|
8419
8474
|
}
|
|
8420
8475
|
if (output) {
|
|
8421
|
-
await fsp2.mkdir(
|
|
8422
|
-
await fsp2.writeFile(
|
|
8476
|
+
await fsp2.mkdir(path24.dirname(path24.resolve(deps.cwd, output)), { recursive: true });
|
|
8477
|
+
await fsp2.writeFile(path24.resolve(deps.cwd, output), rendered, "utf8");
|
|
8423
8478
|
deps.renderer.write(`Wrote ${rendered.length} bytes to ${output}
|
|
8424
8479
|
`);
|
|
8425
8480
|
} else {
|
|
@@ -8492,8 +8547,8 @@ var initCmd = async (_args, deps) => {
|
|
|
8492
8547
|
const vault = new DefaultSecretVault$1({ keyFile: deps.paths.secretsKey });
|
|
8493
8548
|
const encrypted = encryptConfigSecrets(config, vault);
|
|
8494
8549
|
await atomicWrite(deps.paths.globalConfig, JSON.stringify(encrypted, null, 2));
|
|
8495
|
-
await fsp2.mkdir(
|
|
8496
|
-
const agentsFile =
|
|
8550
|
+
await fsp2.mkdir(path24.join(deps.projectRoot, ".wrongstack"), { recursive: true });
|
|
8551
|
+
const agentsFile = path24.join(deps.projectRoot, ".wrongstack", "AGENTS.md");
|
|
8497
8552
|
const projectFacts = await detectProjectFacts(deps.projectRoot);
|
|
8498
8553
|
await atomicWrite(agentsFile, renderAgentsTemplate(projectFacts));
|
|
8499
8554
|
deps.renderer.writeInfo(`Wrote ${deps.paths.globalConfig}`);
|
|
@@ -8799,7 +8854,7 @@ var usageCmd = async (_args, deps) => {
|
|
|
8799
8854
|
return 0;
|
|
8800
8855
|
};
|
|
8801
8856
|
var projectsCmd = async (_args, deps) => {
|
|
8802
|
-
const projectsRoot =
|
|
8857
|
+
const projectsRoot = path24.join(deps.paths.globalRoot, "projects");
|
|
8803
8858
|
try {
|
|
8804
8859
|
const entries = await fsp2.readdir(projectsRoot);
|
|
8805
8860
|
if (entries.length === 0) {
|
|
@@ -8809,7 +8864,7 @@ var projectsCmd = async (_args, deps) => {
|
|
|
8809
8864
|
for (const hash of entries) {
|
|
8810
8865
|
try {
|
|
8811
8866
|
const meta = JSON.parse(
|
|
8812
|
-
await fsp2.readFile(
|
|
8867
|
+
await fsp2.readFile(path24.join(projectsRoot, hash, "meta.json"), "utf8")
|
|
8813
8868
|
);
|
|
8814
8869
|
deps.renderer.write(
|
|
8815
8870
|
` ${color.dim(hash)} ${color.dim(meta.lastSeen ?? "")} ${meta.root ?? "?"}
|
|
@@ -8968,7 +9023,7 @@ async function listFleetRuns(deps) {
|
|
|
8968
9023
|
}
|
|
8969
9024
|
const runs = [];
|
|
8970
9025
|
for (const id of entries) {
|
|
8971
|
-
const runDir =
|
|
9026
|
+
const runDir = path24.join(deps.paths.projectSessions, id);
|
|
8972
9027
|
let stat3;
|
|
8973
9028
|
try {
|
|
8974
9029
|
stat3 = await fsp2.stat(runDir);
|
|
@@ -8981,17 +9036,17 @@ async function listFleetRuns(deps) {
|
|
|
8981
9036
|
let subagentCount = 0;
|
|
8982
9037
|
let subagentsDir;
|
|
8983
9038
|
try {
|
|
8984
|
-
await fsp2.access(
|
|
9039
|
+
await fsp2.access(path24.join(runDir, "fleet.json"));
|
|
8985
9040
|
manifest = true;
|
|
8986
9041
|
} catch {
|
|
8987
9042
|
}
|
|
8988
9043
|
try {
|
|
8989
|
-
await fsp2.access(
|
|
9044
|
+
await fsp2.access(path24.join(runDir, "checkpoint.json"));
|
|
8990
9045
|
checkpoint = true;
|
|
8991
9046
|
} catch {
|
|
8992
9047
|
}
|
|
8993
9048
|
try {
|
|
8994
|
-
subagentsDir =
|
|
9049
|
+
subagentsDir = path24.join(runDir, "subagents");
|
|
8995
9050
|
const files = await fsp2.readdir(subagentsDir);
|
|
8996
9051
|
subagentCount = files.filter((f) => f.endsWith(".jsonl")).length;
|
|
8997
9052
|
} catch {
|
|
@@ -9020,7 +9075,7 @@ async function listFleetRuns(deps) {
|
|
|
9020
9075
|
return 0;
|
|
9021
9076
|
}
|
|
9022
9077
|
async function showFleetRun(runId, deps) {
|
|
9023
|
-
const runDir =
|
|
9078
|
+
const runDir = path24.join(deps.paths.projectSessions, runId);
|
|
9024
9079
|
let stat3;
|
|
9025
9080
|
try {
|
|
9026
9081
|
stat3 = await fsp2.stat(runDir);
|
|
@@ -9037,7 +9092,7 @@ async function showFleetRun(runId, deps) {
|
|
|
9037
9092
|
deps.renderer.write(color.bold(`
|
|
9038
9093
|
Fleet Run: ${runId}
|
|
9039
9094
|
`) + "\n");
|
|
9040
|
-
const manifestPath =
|
|
9095
|
+
const manifestPath = path24.join(runDir, "fleet.json");
|
|
9041
9096
|
let manifestData = null;
|
|
9042
9097
|
try {
|
|
9043
9098
|
manifestData = await fsp2.readFile(manifestPath, "utf8");
|
|
@@ -9053,7 +9108,7 @@ Fleet Run: ${runId}
|
|
|
9053
9108
|
deps.renderer.write(` ${color.dim("\u25CB")} fleet.json \u2014 not found
|
|
9054
9109
|
`);
|
|
9055
9110
|
}
|
|
9056
|
-
const checkpointPath =
|
|
9111
|
+
const checkpointPath = path24.join(runDir, "checkpoint.json");
|
|
9057
9112
|
let checkpointData = null;
|
|
9058
9113
|
try {
|
|
9059
9114
|
checkpointData = await fsp2.readFile(checkpointPath, "utf8");
|
|
@@ -9100,7 +9155,7 @@ Fleet Run: ${runId}
|
|
|
9100
9155
|
} catch {
|
|
9101
9156
|
}
|
|
9102
9157
|
}
|
|
9103
|
-
const subagentsDir =
|
|
9158
|
+
const subagentsDir = path24.join(runDir, "subagents");
|
|
9104
9159
|
let subagentFiles = [];
|
|
9105
9160
|
try {
|
|
9106
9161
|
subagentFiles = await fsp2.readdir(subagentsDir);
|
|
@@ -9112,7 +9167,7 @@ Fleet Run: ${runId}
|
|
|
9112
9167
|
Subagent transcripts (${subagentFiles.length}):
|
|
9113
9168
|
`);
|
|
9114
9169
|
for (const f of subagentFiles.sort()) {
|
|
9115
|
-
const filePath =
|
|
9170
|
+
const filePath = path24.join(subagentsDir, f);
|
|
9116
9171
|
let size;
|
|
9117
9172
|
try {
|
|
9118
9173
|
const s = await fsp2.stat(filePath);
|
|
@@ -9129,7 +9184,7 @@ Fleet Run: ${runId}
|
|
|
9129
9184
|
${color.dim("\u25CB")} No subagent transcripts
|
|
9130
9185
|
`);
|
|
9131
9186
|
}
|
|
9132
|
-
const sharedDir =
|
|
9187
|
+
const sharedDir = path24.join(runDir, "shared");
|
|
9133
9188
|
try {
|
|
9134
9189
|
const files = await fsp2.readdir(sharedDir);
|
|
9135
9190
|
deps.renderer.write(`
|
|
@@ -9296,7 +9351,7 @@ function findSessionId(args) {
|
|
|
9296
9351
|
var rewindCmd = async (args, deps) => {
|
|
9297
9352
|
const flags = parseRewindFlags(args);
|
|
9298
9353
|
const wpaths = resolveWstackPaths({ projectRoot: deps.projectRoot });
|
|
9299
|
-
const sessionsDir =
|
|
9354
|
+
const sessionsDir = path24.join(wpaths.globalRoot, "sessions");
|
|
9300
9355
|
const rewind = new DefaultSessionRewinder(sessionsDir);
|
|
9301
9356
|
let sessionId = findSessionId(args);
|
|
9302
9357
|
if (!sessionId) {
|
|
@@ -9533,7 +9588,7 @@ function resolveBundledSkillsDir() {
|
|
|
9533
9588
|
try {
|
|
9534
9589
|
const req2 = createRequire(import.meta.url);
|
|
9535
9590
|
const corePkg = req2.resolve("@wrongstack/core/package.json");
|
|
9536
|
-
return
|
|
9591
|
+
return path24.join(path24.dirname(corePkg), "skills");
|
|
9537
9592
|
} catch {
|
|
9538
9593
|
return void 0;
|
|
9539
9594
|
}
|
|
@@ -9664,7 +9719,9 @@ async function boot(argv) {
|
|
|
9664
9719
|
flags["no-tui"] = true;
|
|
9665
9720
|
}
|
|
9666
9721
|
if (choices.yolo !== config.yolo) config = patchConfig(config, { yolo: choices.yolo });
|
|
9667
|
-
printLaunchHints(renderer, flags
|
|
9722
|
+
printLaunchHints(renderer, flags, {
|
|
9723
|
+
cursorFile: path24.join(wpaths.cacheDir, "hint-cursor")
|
|
9724
|
+
});
|
|
9668
9725
|
}
|
|
9669
9726
|
return {
|
|
9670
9727
|
config,
|
|
@@ -10694,7 +10751,7 @@ async function execute(deps) {
|
|
|
10694
10751
|
supportsVision,
|
|
10695
10752
|
attachments,
|
|
10696
10753
|
effectiveMaxContext,
|
|
10697
|
-
projectName:
|
|
10754
|
+
projectName: path24.basename(projectRoot) || void 0,
|
|
10698
10755
|
projectRoot,
|
|
10699
10756
|
getAutonomy,
|
|
10700
10757
|
onAutonomy,
|
|
@@ -10716,7 +10773,7 @@ async function execute(deps) {
|
|
|
10716
10773
|
supportsVision,
|
|
10717
10774
|
attachments,
|
|
10718
10775
|
effectiveMaxContext,
|
|
10719
|
-
projectName:
|
|
10776
|
+
projectName: path24.basename(projectRoot) || void 0,
|
|
10720
10777
|
getAutonomy,
|
|
10721
10778
|
onAutonomy,
|
|
10722
10779
|
getEternalEngine,
|
|
@@ -10818,7 +10875,7 @@ var MultiAgentHost = class {
|
|
|
10818
10875
|
doneCondition: { type: "all_tasks_done" },
|
|
10819
10876
|
maxConcurrent: this.opts.maxConcurrent ?? 4
|
|
10820
10877
|
};
|
|
10821
|
-
const defaultScratchpad = this.opts.sharedScratchpadPath || (this.opts.sessionsRoot && this.opts.directorRunId ?
|
|
10878
|
+
const defaultScratchpad = this.opts.sharedScratchpadPath || (this.opts.sessionsRoot && this.opts.directorRunId ? path24.join(this.opts.sessionsRoot, this.opts.directorRunId, "shared") : void 0);
|
|
10822
10879
|
this.director = new Director({
|
|
10823
10880
|
config: coordinatorConfig,
|
|
10824
10881
|
manifestPath: this.opts.manifestPath,
|
|
@@ -11063,7 +11120,7 @@ var MultiAgentHost = class {
|
|
|
11063
11120
|
model: opts?.model,
|
|
11064
11121
|
tools: opts?.tools
|
|
11065
11122
|
};
|
|
11066
|
-
const transcriptPath = this.sessionFactory ?
|
|
11123
|
+
const transcriptPath = this.sessionFactory ? path24.join(this.sessionFactory.dir, `${subagentConfig.name}.jsonl`) : void 0;
|
|
11067
11124
|
const { subagentId, taskId } = await this._spawnAndAssign(subagentConfig);
|
|
11068
11125
|
this.fleetManager?.addPendingTask(taskId, subagentId, description);
|
|
11069
11126
|
this.deps.events.emit("subagent.spawned", {
|
|
@@ -11206,16 +11263,16 @@ var MultiAgentHost = class {
|
|
|
11206
11263
|
if (this.director) return this.director;
|
|
11207
11264
|
this.opts.directorMode = true;
|
|
11208
11265
|
if (this.opts.fleetRoot && !this.opts.manifestPath) {
|
|
11209
|
-
this.opts.manifestPath =
|
|
11266
|
+
this.opts.manifestPath = path24.join(this.opts.fleetRoot, "fleet.json");
|
|
11210
11267
|
}
|
|
11211
11268
|
if (this.opts.fleetRoot && !this.opts.sharedScratchpadPath) {
|
|
11212
|
-
this.opts.sharedScratchpadPath =
|
|
11269
|
+
this.opts.sharedScratchpadPath = path24.join(this.opts.fleetRoot, "shared");
|
|
11213
11270
|
}
|
|
11214
11271
|
if (this.opts.fleetRoot && !this.opts.sessionsRoot) {
|
|
11215
|
-
this.opts.sessionsRoot =
|
|
11272
|
+
this.opts.sessionsRoot = path24.join(this.opts.fleetRoot, "subagents");
|
|
11216
11273
|
}
|
|
11217
11274
|
if (this.opts.fleetRoot && !this.opts.stateCheckpointPath) {
|
|
11218
|
-
this.opts.stateCheckpointPath =
|
|
11275
|
+
this.opts.stateCheckpointPath = path24.join(this.opts.fleetRoot, "director-state.json");
|
|
11219
11276
|
}
|
|
11220
11277
|
await this.ensureDirector();
|
|
11221
11278
|
return this.director ?? null;
|
|
@@ -11381,11 +11438,11 @@ var SessionStats = class {
|
|
|
11381
11438
|
if (e.name === "bash") this.bashCommands++;
|
|
11382
11439
|
else if (e.name === "fetch") this.fetches++;
|
|
11383
11440
|
if (!e.ok) return;
|
|
11384
|
-
const
|
|
11385
|
-
if (e.name === "read" &&
|
|
11386
|
-
else if (e.name === "edit" &&
|
|
11387
|
-
else if (e.name === "write" &&
|
|
11388
|
-
this.writtenPaths.add(
|
|
11441
|
+
const path25 = typeof input?.path === "string" ? input.path : void 0;
|
|
11442
|
+
if (e.name === "read" && path25) this.readPaths.add(path25);
|
|
11443
|
+
else if (e.name === "edit" && path25) this.editedPaths.add(path25);
|
|
11444
|
+
else if (e.name === "write" && path25) {
|
|
11445
|
+
this.writtenPaths.add(path25);
|
|
11389
11446
|
const content = typeof input?.content === "string" ? input.content : "";
|
|
11390
11447
|
this.bytesWritten += Buffer.byteLength(content, "utf8");
|
|
11391
11448
|
}
|
|
@@ -11673,7 +11730,7 @@ function setupMetrics(params) {
|
|
|
11673
11730
|
const dumpMetrics = () => {
|
|
11674
11731
|
if (!metricsSink) return;
|
|
11675
11732
|
try {
|
|
11676
|
-
const out =
|
|
11733
|
+
const out = path24.join(wpaths.projectSessions, "metrics.json");
|
|
11677
11734
|
const snap = metricsSink.snapshot();
|
|
11678
11735
|
writeFileSync(out, JSON.stringify(snap, null, 2));
|
|
11679
11736
|
} catch {
|
|
@@ -11864,12 +11921,12 @@ async function setupSession(params) {
|
|
|
11864
11921
|
}
|
|
11865
11922
|
const sessionRef = { current: session };
|
|
11866
11923
|
await recoveryLock.write(session.id).catch(() => void 0);
|
|
11867
|
-
const attachments = new DefaultAttachmentStore({ spoolDir:
|
|
11868
|
-
const queueStore = new QueueStore({ dir:
|
|
11924
|
+
const attachments = new DefaultAttachmentStore({ spoolDir: path24.join(wpaths.projectSessions, session.id, "attachments") });
|
|
11925
|
+
const queueStore = new QueueStore({ dir: path24.join(wpaths.projectSessions, session.id) });
|
|
11869
11926
|
const ctxSignal = new AbortController().signal;
|
|
11870
11927
|
const context = new Context({ systemPrompt, provider, session, signal: ctxSignal, tokenCounter, cwd, projectRoot, model: config.model });
|
|
11871
11928
|
if (restoredMessages.length > 0) context.state.replaceMessages(restoredMessages);
|
|
11872
|
-
const todosCheckpointPath =
|
|
11929
|
+
const todosCheckpointPath = path24.join(wpaths.projectSessions, `${session.id}.todos.json`);
|
|
11873
11930
|
if (resumeId) {
|
|
11874
11931
|
try {
|
|
11875
11932
|
const restoredTodos = await loadTodosCheckpoint(todosCheckpointPath);
|
|
@@ -11881,13 +11938,13 @@ async function setupSession(params) {
|
|
|
11881
11938
|
}
|
|
11882
11939
|
}
|
|
11883
11940
|
const detachTodosCheckpoint = attachTodosCheckpoint(context.state, todosCheckpointPath, session.id);
|
|
11884
|
-
const planPath =
|
|
11941
|
+
const planPath = path24.join(wpaths.projectSessions, `${session.id}.plan.json`);
|
|
11885
11942
|
context.state.setMeta("plan.path", planPath);
|
|
11886
11943
|
let dirState;
|
|
11887
11944
|
if (resumeId) {
|
|
11888
11945
|
try {
|
|
11889
|
-
const fleetRoot =
|
|
11890
|
-
dirState = await loadDirectorState(
|
|
11946
|
+
const fleetRoot = path24.join(wpaths.projectSessions, session.id);
|
|
11947
|
+
dirState = await loadDirectorState(path24.join(fleetRoot, "director-state.json"));
|
|
11891
11948
|
if (dirState) {
|
|
11892
11949
|
const tCounts = {};
|
|
11893
11950
|
for (const t of dirState.tasks) tCounts[t.status] = (tCounts[t.status] ?? 0) + 1;
|
|
@@ -11914,7 +11971,7 @@ function resolveBundledSkillsDir2() {
|
|
|
11914
11971
|
try {
|
|
11915
11972
|
const req2 = createRequire(import.meta.url);
|
|
11916
11973
|
const corePkg = req2.resolve("@wrongstack/core/package.json");
|
|
11917
|
-
return
|
|
11974
|
+
return path24.join(path24.dirname(corePkg), "skills");
|
|
11918
11975
|
} catch {
|
|
11919
11976
|
return void 0;
|
|
11920
11977
|
}
|
|
@@ -12014,7 +12071,7 @@ async function main(argv) {
|
|
|
12014
12071
|
modeId,
|
|
12015
12072
|
modePrompt,
|
|
12016
12073
|
modelCapabilities,
|
|
12017
|
-
planPath: () => sessionRef.current ?
|
|
12074
|
+
planPath: () => sessionRef.current ? path24.join(wpaths.projectSessions, `${sessionRef.current.id}.plan.json`) : void 0,
|
|
12018
12075
|
contributors: [
|
|
12019
12076
|
// Injects the ETERNAL AUTONOMY block when the user has activated
|
|
12020
12077
|
// `/autonomy eternal`. Without this, the per-iteration directive
|
|
@@ -12213,12 +12270,12 @@ async function main(argv) {
|
|
|
12213
12270
|
}
|
|
12214
12271
|
}
|
|
12215
12272
|
};
|
|
12216
|
-
const fleetRoot = directorMode ?
|
|
12217
|
-
const manifestPath = directorMode ? typeof process.env["WRONGSTACK_FLEET_MANIFEST"] === "string" ? process.env["WRONGSTACK_FLEET_MANIFEST"] :
|
|
12218
|
-
const sharedScratchpadPath = directorMode ?
|
|
12219
|
-
const subagentSessionsRoot = directorMode ?
|
|
12220
|
-
const stateCheckpointPath = directorMode ?
|
|
12221
|
-
const fleetRootForPromotion =
|
|
12273
|
+
const fleetRoot = directorMode ? path24.join(wpaths.projectSessions, session.id) : void 0;
|
|
12274
|
+
const manifestPath = directorMode ? typeof process.env["WRONGSTACK_FLEET_MANIFEST"] === "string" ? process.env["WRONGSTACK_FLEET_MANIFEST"] : path24.join(fleetRoot, "fleet.json") : void 0;
|
|
12275
|
+
const sharedScratchpadPath = directorMode ? path24.join(fleetRoot, "shared") : void 0;
|
|
12276
|
+
const subagentSessionsRoot = directorMode ? path24.join(fleetRoot, "subagents") : void 0;
|
|
12277
|
+
const stateCheckpointPath = directorMode ? path24.join(fleetRoot, "director-state.json") : void 0;
|
|
12278
|
+
const fleetRootForPromotion = path24.join(wpaths.projectSessions, session.id);
|
|
12222
12279
|
const multiAgentHost = new MultiAgentHost(
|
|
12223
12280
|
{
|
|
12224
12281
|
container,
|
|
@@ -12528,7 +12585,7 @@ async function main(argv) {
|
|
|
12528
12585
|
return director.spawn(cfg);
|
|
12529
12586
|
},
|
|
12530
12587
|
onFleetLog: async (subagentId, mode) => {
|
|
12531
|
-
const subagentsRoot =
|
|
12588
|
+
const subagentsRoot = path24.join(fleetRootForPromotion, "subagents");
|
|
12532
12589
|
let runDirs;
|
|
12533
12590
|
try {
|
|
12534
12591
|
runDirs = await fsp2.readdir(subagentsRoot);
|
|
@@ -12537,7 +12594,7 @@ async function main(argv) {
|
|
|
12537
12594
|
}
|
|
12538
12595
|
const found = [];
|
|
12539
12596
|
for (const runId of runDirs) {
|
|
12540
|
-
const runDir =
|
|
12597
|
+
const runDir = path24.join(subagentsRoot, runId);
|
|
12541
12598
|
let files;
|
|
12542
12599
|
try {
|
|
12543
12600
|
files = await fsp2.readdir(runDir);
|
|
@@ -12546,7 +12603,7 @@ async function main(argv) {
|
|
|
12546
12603
|
}
|
|
12547
12604
|
for (const f of files) {
|
|
12548
12605
|
if (!f.endsWith(".jsonl")) continue;
|
|
12549
|
-
const full =
|
|
12606
|
+
const full = path24.join(runDir, f);
|
|
12550
12607
|
try {
|
|
12551
12608
|
const stat3 = await fsp2.stat(full);
|
|
12552
12609
|
found.push({
|
|
@@ -12643,7 +12700,7 @@ async function main(argv) {
|
|
|
12643
12700
|
}
|
|
12644
12701
|
const dir = await multiAgentHost.ensureDirector();
|
|
12645
12702
|
if (!dir) return "Director is not available.";
|
|
12646
|
-
const dirStatePath =
|
|
12703
|
+
const dirStatePath = path24.join(fleetRootForPromotion, "director-state.json");
|
|
12647
12704
|
const prior = await loadDirectorState(dirStatePath);
|
|
12648
12705
|
if (!prior) {
|
|
12649
12706
|
return "No prior director-state.json found \u2014 nothing to retry.";
|
|
@@ -12714,9 +12771,9 @@ async function main(argv) {
|
|
|
12714
12771
|
for (const tool of director2.tools(FLEET_ROSTER)) {
|
|
12715
12772
|
toolRegistry.register(tool);
|
|
12716
12773
|
}
|
|
12717
|
-
const mp =
|
|
12718
|
-
const sp =
|
|
12719
|
-
const ss =
|
|
12774
|
+
const mp = path24.join(fleetRootForPromotion, "fleet.json");
|
|
12775
|
+
const sp = path24.join(fleetRootForPromotion, "shared");
|
|
12776
|
+
const ss = path24.join(fleetRootForPromotion, "subagents");
|
|
12720
12777
|
const lines = [
|
|
12721
12778
|
`${color.green("\u2713")} Promoted to director mode.`,
|
|
12722
12779
|
` Roster: ${Object.keys(FLEET_ROSTER).join(", ")}`,
|