@wrongstack/cli 0.6.7 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +120 -27
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import * as path23 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, makeAgentSubagentRunner, NULL_FLEET_BUS, resolveWstackPaths, DefaultSecretVault, migratePlaintextSecrets, DefaultConfigLoader, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, atomicWrite, DefaultPluginAPI, AutoApprovePermissionPolicy, formatContextWindowModeList, repairToolUseAdjacency, getContextWindowMode, resolveContextWindowPolicy, 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, projectHash, 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, makeAgentSubagentRunner, NULL_FLEET_BUS, resolveWstackPaths, DefaultSecretVault, migratePlaintextSecrets, DefaultConfigLoader, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, atomicWrite, DefaultPluginAPI, AutoApprovePermissionPolicy, formatContextWindowModeList, repairToolUseAdjacency, getContextWindowMode, resolveContextWindowPolicy, 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';
|
|
7
7
|
import { createRequire } from 'module';
|
|
8
8
|
import * as os6 from 'os';
|
|
9
9
|
import os6__default from 'os';
|
|
@@ -2753,7 +2753,16 @@ function entryId(ts) {
|
|
|
2753
2753
|
return ts.replace(/[:.]/g, "-").slice(0, 19);
|
|
2754
2754
|
}
|
|
2755
2755
|
async function ensureHistoryDir(homeFn = defaultHomeDir) {
|
|
2756
|
-
|
|
2756
|
+
try {
|
|
2757
|
+
await fsp2.mkdir(historyDir(homeFn), { recursive: true });
|
|
2758
|
+
} catch (err) {
|
|
2759
|
+
throw new FsError({
|
|
2760
|
+
message: err instanceof Error ? err.message : String(err),
|
|
2761
|
+
code: ERROR_CODES.FS_MKDIR_FAILED,
|
|
2762
|
+
path: historyDir(homeFn),
|
|
2763
|
+
cause: err
|
|
2764
|
+
});
|
|
2765
|
+
}
|
|
2757
2766
|
}
|
|
2758
2767
|
async function readIndex(homeFn = defaultHomeDir) {
|
|
2759
2768
|
try {
|
|
@@ -2765,7 +2774,16 @@ async function readIndex(homeFn = defaultHomeDir) {
|
|
|
2765
2774
|
}
|
|
2766
2775
|
async function writeIndex(idx, homeFn = defaultHomeDir) {
|
|
2767
2776
|
await ensureHistoryDir(homeFn);
|
|
2768
|
-
|
|
2777
|
+
try {
|
|
2778
|
+
await atomicWrite(historyIndexPath(homeFn), JSON.stringify(idx, null, 2));
|
|
2779
|
+
} catch (err) {
|
|
2780
|
+
throw new FsError({
|
|
2781
|
+
message: err instanceof Error ? err.message : String(err),
|
|
2782
|
+
code: ERROR_CODES.FS_ATOMIC_WRITE_FAILED,
|
|
2783
|
+
path: historyIndexPath(homeFn),
|
|
2784
|
+
cause: err
|
|
2785
|
+
});
|
|
2786
|
+
}
|
|
2769
2787
|
}
|
|
2770
2788
|
async function backupCurrent(homeFn = defaultHomeDir) {
|
|
2771
2789
|
const cfg = configPath(homeFn);
|
|
@@ -2810,11 +2828,20 @@ async function appendHistory(oldCfg, newCfg, description, homeFn = defaultHomeDi
|
|
|
2810
2828
|
snapshotMasked: maskConfigSecrets(newCfg),
|
|
2811
2829
|
diffSummary: diffSummary(oldCfg, newCfg)
|
|
2812
2830
|
};
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2831
|
+
try {
|
|
2832
|
+
await fsp2.writeFile(
|
|
2833
|
+
path23.join(historyDir(homeFn), `${id}.json`),
|
|
2834
|
+
JSON.stringify(entry, null, 2),
|
|
2835
|
+
"utf8"
|
|
2836
|
+
);
|
|
2837
|
+
} catch (err) {
|
|
2838
|
+
throw new FsError({
|
|
2839
|
+
message: err instanceof Error ? err.message : String(err),
|
|
2840
|
+
code: ERROR_CODES.FS_WRITE_FAILED,
|
|
2841
|
+
path: path23.join(historyDir(homeFn), `${id}.json`),
|
|
2842
|
+
cause: err
|
|
2843
|
+
});
|
|
2844
|
+
}
|
|
2818
2845
|
const idx = await readIndex(homeFn);
|
|
2819
2846
|
idx.entries.unshift({ id, timestamp, description });
|
|
2820
2847
|
await writeIndex(idx, homeFn);
|
|
@@ -3476,17 +3503,37 @@ function buildClearCommand(opts) {
|
|
|
3476
3503
|
};
|
|
3477
3504
|
}
|
|
3478
3505
|
async function runGit(args, cwd) {
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3506
|
+
try {
|
|
3507
|
+
return await new Promise((resolve4, reject) => {
|
|
3508
|
+
const child = spawn("git", args, {
|
|
3509
|
+
cwd,
|
|
3510
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
3511
|
+
});
|
|
3512
|
+
let stdout = "";
|
|
3513
|
+
let stderr = "";
|
|
3514
|
+
child.stdout?.on("data", (d) => stdout += d);
|
|
3515
|
+
child.stderr?.on("data", (d) => stderr += d);
|
|
3516
|
+
child.on("error", (err) => {
|
|
3517
|
+
reject(new WrongStackError({
|
|
3518
|
+
message: `Failed to run git: ${err.message}`,
|
|
3519
|
+
code: ERROR_CODES.TOOL_EXECUTION_FAILED,
|
|
3520
|
+
subsystem: "tool",
|
|
3521
|
+
context: { command: "git", args, cwd },
|
|
3522
|
+
cause: err
|
|
3523
|
+
}));
|
|
3524
|
+
});
|
|
3525
|
+
child.on("close", (code) => resolve4({ stdout, stderr, code: code ?? 0 }));
|
|
3483
3526
|
});
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3527
|
+
} catch (err) {
|
|
3528
|
+
if (err instanceof WrongStackError) throw err;
|
|
3529
|
+
throw new WrongStackError({
|
|
3530
|
+
message: err instanceof Error ? err.message : String(err),
|
|
3531
|
+
code: ERROR_CODES.TOOL_EXECUTION_FAILED,
|
|
3532
|
+
subsystem: "tool",
|
|
3533
|
+
context: { command: "git", args, cwd },
|
|
3534
|
+
cause: err
|
|
3535
|
+
});
|
|
3536
|
+
}
|
|
3490
3537
|
}
|
|
3491
3538
|
function detectCommitType(stats) {
|
|
3492
3539
|
const lines = stats.split("\n");
|
|
@@ -5505,8 +5552,17 @@ async function loadStatuslineConfig() {
|
|
|
5505
5552
|
}
|
|
5506
5553
|
async function saveStatuslineConfig(cfg) {
|
|
5507
5554
|
const p = resolveConfigPath();
|
|
5508
|
-
|
|
5509
|
-
|
|
5555
|
+
try {
|
|
5556
|
+
await fsp2.mkdir(path23.dirname(p), { recursive: true });
|
|
5557
|
+
await atomicWrite(p, JSON.stringify(cfg, null, 2));
|
|
5558
|
+
} catch (err) {
|
|
5559
|
+
throw new FsError({
|
|
5560
|
+
message: err instanceof Error ? err.message : String(err),
|
|
5561
|
+
code: err instanceof Error && err.message.includes("mkdir") ? ERROR_CODES.FS_MKDIR_FAILED : ERROR_CODES.FS_ATOMIC_WRITE_FAILED,
|
|
5562
|
+
path: p,
|
|
5563
|
+
cause: err
|
|
5564
|
+
});
|
|
5565
|
+
}
|
|
5510
5566
|
}
|
|
5511
5567
|
function buildStatuslineCommand(deps) {
|
|
5512
5568
|
return {
|
|
@@ -6708,6 +6764,7 @@ async function runProjectCheck(opts) {
|
|
|
6708
6764
|
const { spawn: spawn3 } = await import('child_process');
|
|
6709
6765
|
await new Promise((resolve4, reject) => {
|
|
6710
6766
|
const child = spawn3("git", ["init"], { cwd: projectRoot });
|
|
6767
|
+
child.on("error", reject);
|
|
6711
6768
|
child.on("close", (code) => code === 0 ? resolve4() : reject(new Error(`git init failed with ${code}`)));
|
|
6712
6769
|
});
|
|
6713
6770
|
renderer.write(` ${color.green("\u2713")} Git repository initialized
|
|
@@ -7786,7 +7843,7 @@ var updateCmd = async (args, deps) => {
|
|
|
7786
7843
|
deps.renderer.write(`Updating wrongstack from v${info.current} to v${info.latest}...
|
|
7787
7844
|
`);
|
|
7788
7845
|
try {
|
|
7789
|
-
const result = await new Promise((resolve4) => {
|
|
7846
|
+
const result = await new Promise((resolve4, reject) => {
|
|
7790
7847
|
const child = spawn("npm", ["install", "-g", "wrongstack@latest"], {
|
|
7791
7848
|
cwd,
|
|
7792
7849
|
stdio: "pipe"
|
|
@@ -7795,6 +7852,7 @@ var updateCmd = async (args, deps) => {
|
|
|
7795
7852
|
child.stderr?.on("data", (d) => {
|
|
7796
7853
|
stderr += d;
|
|
7797
7854
|
});
|
|
7855
|
+
child.on("error", reject);
|
|
7798
7856
|
child.on("close", (code) => resolve4({ code: code ?? 0 }));
|
|
7799
7857
|
});
|
|
7800
7858
|
if (result.code === 0) {
|
|
@@ -9382,9 +9440,15 @@ async function runRepl(opts) {
|
|
|
9382
9440
|
} else {
|
|
9383
9441
|
const beforeGoal = await loadGoalSafe(opts);
|
|
9384
9442
|
const beforeIter = beforeGoal?.iterations ?? 0;
|
|
9443
|
+
const coord = engine.getCoordinator();
|
|
9444
|
+
if (coord) {
|
|
9445
|
+
const stats = coord.getStats();
|
|
9446
|
+
opts.renderer.write(
|
|
9447
|
+
color.dim(` \u250C\u2500 Fleet: ${stats.running} running, ${stats.idle} idle, ${stats.pending} pending, ${stats.completed} done`) + "\n"
|
|
9448
|
+
);
|
|
9449
|
+
}
|
|
9385
9450
|
opts.renderer.write(
|
|
9386
|
-
color.magenta(`
|
|
9387
|
-
\u21B3 [parallel #${beforeIter + 1}] launching fan-out\u2026
|
|
9451
|
+
color.magenta(` \u21B3 [parallel #${beforeIter + 1}] launching fan-out\u2026
|
|
9388
9452
|
`)
|
|
9389
9453
|
);
|
|
9390
9454
|
interrupts = 0;
|
|
@@ -9392,6 +9456,13 @@ async function runRepl(opts) {
|
|
|
9392
9456
|
const ok = await engine.runOneIteration();
|
|
9393
9457
|
const afterGoal = await loadGoalSafe(opts);
|
|
9394
9458
|
const last = afterGoal?.journal[afterGoal.journal.length - 1];
|
|
9459
|
+
if (coord) {
|
|
9460
|
+
const stats = coord.getStats();
|
|
9461
|
+
opts.renderer.write(
|
|
9462
|
+
color.dim(` \u2514\u2500 Fleet: ${stats.running} running, ${stats.idle} idle, ${stats.completed} done
|
|
9463
|
+
`)
|
|
9464
|
+
);
|
|
9465
|
+
}
|
|
9395
9466
|
if (last) {
|
|
9396
9467
|
const mark = last.status === "success" ? color.green("\u2713") : last.status === "failure" ? color.red("\u2717") : color.amber("\u2298");
|
|
9397
9468
|
const tail = last.note ? color.dim(` \u2014 ${last.note.slice(0, 80)}`) : "";
|
|
@@ -9743,9 +9814,17 @@ async function renderGoalBanner(opts) {
|
|
|
9743
9814
|
const goal = await loadGoalSafe(opts);
|
|
9744
9815
|
if (!goal) return;
|
|
9745
9816
|
const summary = goal.goal.length > 80 ? `${goal.goal.slice(0, 77)}\u2026` : goal.goal;
|
|
9817
|
+
const stateColor = goal.goalState === "active" ? color.green : goal.goalState === "paused" ? color.amber : goal.goalState === "completed" ? color.green : goal.goalState === "abandoned" ? color.dim : color.dim;
|
|
9746
9818
|
opts.renderer.write(
|
|
9747
|
-
color.dim("Goal: ") +
|
|
9819
|
+
color.dim("Goal: ") + stateColor(summary) + color.dim(` [${goal.goalState}] (iter ${goal.iterations})`) + "\n"
|
|
9748
9820
|
);
|
|
9821
|
+
if (goal.journal.length > 0) {
|
|
9822
|
+
const lastEntry = goal.journal[goal.journal.length - 1];
|
|
9823
|
+
const statusIcon2 = lastEntry.status === "success" ? "\u2713" : lastEntry.status === "failure" ? "\u2717" : lastEntry.status === "aborted" ? "\u2298" : lastEntry.status === "skipped" ? "\u229D" : "\xB7";
|
|
9824
|
+
opts.renderer.write(
|
|
9825
|
+
color.dim(` Last: ${statusIcon2} ${lastEntry.task} (${lastEntry.status})`) + "\n"
|
|
9826
|
+
);
|
|
9827
|
+
}
|
|
9749
9828
|
if (goal.engineState === "running") {
|
|
9750
9829
|
opts.renderer.write(
|
|
9751
9830
|
color.amber(" \u21BA Eternal engine was running when last session ended.") + "\n"
|
|
@@ -9770,6 +9849,18 @@ async function renderGoalBanner(opts) {
|
|
|
9770
9849
|
color.dim(" Use `/autonomy eternal` to resume.") + "\n"
|
|
9771
9850
|
);
|
|
9772
9851
|
}
|
|
9852
|
+
} else if (goal.goalState === "paused") {
|
|
9853
|
+
opts.renderer.write(
|
|
9854
|
+
color.amber(" \u23F8 Goal is paused. Use `/goal resume` to continue.") + "\n"
|
|
9855
|
+
);
|
|
9856
|
+
} else if (goal.goalState === "completed") {
|
|
9857
|
+
opts.renderer.write(
|
|
9858
|
+
color.green(" \u2713 Goal completed! Use `/goal clear` to set a new goal.") + "\n"
|
|
9859
|
+
);
|
|
9860
|
+
} else if (goal.goalState === "abandoned") {
|
|
9861
|
+
opts.renderer.write(
|
|
9862
|
+
color.dim(" Use `/goal clear` to set a new goal.") + "\n"
|
|
9863
|
+
);
|
|
9773
9864
|
}
|
|
9774
9865
|
opts.renderer.write("\n");
|
|
9775
9866
|
}
|
|
@@ -10011,6 +10102,7 @@ async function execute(deps) {
|
|
|
10011
10102
|
setStatuslineHiddenItems,
|
|
10012
10103
|
initialGoal: goalFlag,
|
|
10013
10104
|
initialAsk: askFlag,
|
|
10105
|
+
projectRoot,
|
|
10014
10106
|
getSDDContext: () => {
|
|
10015
10107
|
const { getActiveSDDContext: getActiveSDDContext2 } = (init_sdd(), __toCommonJS(sdd_exports));
|
|
10016
10108
|
return getActiveSDDContext2();
|
|
@@ -12095,10 +12187,11 @@ Restart WrongStack to load or unload plugin code in this session.`;
|
|
|
12095
12187
|
onBeforeExit: async () => {
|
|
12096
12188
|
const { spawn: spawn3 } = await import('child_process');
|
|
12097
12189
|
const cwd2 = projectRoot;
|
|
12098
|
-
const statusResult = await new Promise((resolve4) => {
|
|
12190
|
+
const statusResult = await new Promise((resolve4, reject) => {
|
|
12099
12191
|
const child = spawn3("git", ["status", "--porcelain"], { cwd: cwd2, stdio: ["ignore", "pipe", "pipe"] });
|
|
12100
12192
|
let stdout = "";
|
|
12101
12193
|
child.stdout?.on("data", (d) => stdout += d);
|
|
12194
|
+
child.on("error", reject);
|
|
12102
12195
|
child.on("close", (code) => resolve4({ stdout, code: code ?? 0 }));
|
|
12103
12196
|
});
|
|
12104
12197
|
if (statusResult.stdout.trim().length > 0) {
|
|
@@ -12262,12 +12355,12 @@ if (isMain) {
|
|
|
12262
12355
|
main(process.argv.slice(2)).then(
|
|
12263
12356
|
(c) => {
|
|
12264
12357
|
process.exitCode = c;
|
|
12265
|
-
setTimeout(() => process.exit(c),
|
|
12358
|
+
setTimeout(() => process.exit(c), 500).unref();
|
|
12266
12359
|
},
|
|
12267
12360
|
(err) => {
|
|
12268
12361
|
process.stderr.write((err instanceof Error ? err.stack : String(err)) + "\n");
|
|
12269
12362
|
process.exitCode = 1;
|
|
12270
|
-
setTimeout(() => process.exit(1),
|
|
12363
|
+
setTimeout(() => process.exit(1), 500).unref();
|
|
12271
12364
|
}
|
|
12272
12365
|
);
|
|
12273
12366
|
}
|