@wrongstack/cli 0.302.2 → 0.305.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/{acp-XCE4JJF3.js → acp-5ZLGFHWP.js} +5 -2
- package/dist/boot/system-prompt-builder.d.ts +24 -1
- package/dist/boot/tui-project-switch.d.ts +1 -1
- package/dist/boot/tui-runtime-state.d.ts +14 -0
- package/dist/boot/tui-theme-adapter.d.ts +33 -0
- package/dist/{chunk-BXQG3H2Y.js → chunk-53STH6CX.js} +87 -13
- package/dist/{chunk-JW75HY4F.js → chunk-FKWHSFX4.js} +33 -4
- package/dist/{chunk-WOXUE2CN.js → chunk-RHLQT3EV.js} +12 -2
- package/dist/{cli-main-PJMDZHDK.js → cli-main-W3T56YCY.js} +1498 -891
- package/dist/execute-deps.d.ts +16 -0
- package/dist/{execution-LZRYRGDD.js → execution-YMBD7YWC.js} +149 -37
- package/dist/fleet/host-context.d.ts +11 -0
- package/dist/fleet/host-learning-tracker.d.ts +2 -2
- package/dist/fleet/host-learning.d.ts +12 -1
- package/dist/fleet/host-session-writer.d.ts +33 -0
- package/dist/fleet/host-subagent-factory.d.ts +1 -1
- package/dist/fleet/host.d.ts +32 -0
- package/dist/{hq-AHPAE7EN.js → hq-5G6D5YIU.js} +2 -2
- package/dist/{hq-server-KU2Z54QU.js → hq-server-IVZLVCFV.js} +2 -2
- package/dist/index.js +15 -58
- package/dist/{mailbox-serve-DBOOOOWZ.js → mailbox-serve-V3QIJBDH.js} +2 -2
- package/dist/{mcp-E5EBGOHF.js → mcp-MSARYOPN.js} +5 -2
- package/dist/replay-XU6ZD7GM.js +34 -0
- package/dist/slash-commands/agent-improve.d.ts +4 -1
- package/dist/slash-commands/memory-triage.d.ts +4 -17
- package/dist/slash-commands/theme.d.ts +6 -0
- package/dist/subcommands/handlers/update.d.ts +2 -0
- package/dist/{update-LTDJGAFU.js → update-VZSOZGYC.js} +2 -2
- package/dist/{webui-server-E3OPEKU5.js → webui-server-FTG7JAZU.js} +5 -5
- package/dist/wiring/domain-glossary.d.ts +58 -0
- package/dist/wiring/domain-terms-mirror.d.ts +52 -0
- package/dist/wiring/pipeline.d.ts +2 -0
- package/dist/wiring/replay.d.ts +11 -1
- package/dist/wiring/sage.d.ts +4 -16
- package/package.json +23 -23
package/dist/execute-deps.d.ts
CHANGED
|
@@ -48,6 +48,7 @@ export interface ToolPickerItem {
|
|
|
48
48
|
owner: string;
|
|
49
49
|
category: string;
|
|
50
50
|
enabled: boolean;
|
|
51
|
+
exposure: 'direct' | 'lazy' | 'disabled';
|
|
51
52
|
mutating: boolean;
|
|
52
53
|
permission: string;
|
|
53
54
|
descMode: 'extend' | 'simple';
|
|
@@ -89,6 +90,21 @@ export interface CoreDeps {
|
|
|
89
90
|
positional: string[];
|
|
90
91
|
slashRegistry: SlashCommandRegistry;
|
|
91
92
|
tokenCounter: TokenCounter;
|
|
93
|
+
/**
|
|
94
|
+
* Forward-declared session ref owned by the host (cli-main). When an
|
|
95
|
+
* in-process `/resume` swaps the agent's active writer, the resume
|
|
96
|
+
* handler repoints `sessionRef.current` so provider-side
|
|
97
|
+
* `getSessionId: () => sessionRef.current?.id` callbacks and the
|
|
98
|
+
* record-mode `bindReplayToContainer` binding follow the resumed
|
|
99
|
+
* session instead of staying pinned to the boot session.
|
|
100
|
+
*
|
|
101
|
+
* Optional: hosts that don't need post-resume propagation (or tests
|
|
102
|
+
* that predate the refactor) can omit it; provider calls then stay
|
|
103
|
+
* pinned to the boot session — same behavior as before this existed.
|
|
104
|
+
*/
|
|
105
|
+
sessionRef?: {
|
|
106
|
+
current: import('@wrongstack/core/types').SessionWriter | undefined;
|
|
107
|
+
} | undefined;
|
|
92
108
|
/** Atomically move this process's SessionRegistry ownership after explicit resume. */
|
|
93
109
|
activateSessionIdentity?: ((sessionId: string, target?: import('./wiring/session-registry.js').SessionIdentityTarget) => Promise<void>) | undefined;
|
|
94
110
|
/**
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "./chunk-V3XH6XBJ.js";
|
|
11
11
|
import {
|
|
12
12
|
startCliHqConnection
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-FKWHSFX4.js";
|
|
14
14
|
import "./chunk-WHOIR577.js";
|
|
15
15
|
import {
|
|
16
16
|
advanceToNextTask,
|
|
@@ -25,17 +25,17 @@ import {
|
|
|
25
25
|
trySaveSpecFromAIOutput,
|
|
26
26
|
trySaveTasksFromAIOutput
|
|
27
27
|
} from "./chunk-DGXNL7OT.js";
|
|
28
|
-
import {
|
|
29
|
-
WEBUI_SESSION_CHILD_CAPABILITIES,
|
|
30
|
-
writeWebuiSessionChildError,
|
|
31
|
-
writeWebuiSessionChildReady
|
|
32
|
-
} from "./chunk-3JPTNADJ.js";
|
|
33
28
|
import {
|
|
34
29
|
theme
|
|
35
30
|
} from "./chunk-QD544J2B.js";
|
|
36
31
|
import {
|
|
37
32
|
fmtTok
|
|
38
33
|
} from "./chunk-TYO2OVAD.js";
|
|
34
|
+
import {
|
|
35
|
+
WEBUI_SESSION_CHILD_CAPABILITIES,
|
|
36
|
+
writeWebuiSessionChildError,
|
|
37
|
+
writeWebuiSessionChildReady
|
|
38
|
+
} from "./chunk-3JPTNADJ.js";
|
|
39
39
|
import {
|
|
40
40
|
resolveActiveApiKey
|
|
41
41
|
} from "./chunk-SZ42FYPT.js";
|
|
@@ -52,7 +52,7 @@ import {
|
|
|
52
52
|
import "./chunk-7OCVIDC7.js";
|
|
53
53
|
|
|
54
54
|
// src/execution.ts
|
|
55
|
-
import * as
|
|
55
|
+
import * as path13 from "node:path";
|
|
56
56
|
import { effectiveFallbackChain as effectiveFallbackChain2, setQueuedMessagesSnapshot as setQueuedMessagesSnapshot2 } from "@wrongstack/core/agent";
|
|
57
57
|
import { attachTodosCheckpoint as attachTodosCheckpoint2 } from "@wrongstack/core/storage";
|
|
58
58
|
import { normalizeTokenSavingTier as normalizeTokenSavingTier2 } from "@wrongstack/core/types";
|
|
@@ -203,7 +203,7 @@ async function runWebUIDispatch(ctx) {
|
|
|
203
203
|
const isSimpleUi = !isSessionChild && flags["simpleui"] === true;
|
|
204
204
|
agent.disableInteractiveConfirmation();
|
|
205
205
|
renderer.setSilent(true);
|
|
206
|
-
const { runWebUI } = await import("./webui-server-
|
|
206
|
+
const { runWebUI } = await import("./webui-server-FTG7JAZU.js");
|
|
207
207
|
const flagValue = (names) => {
|
|
208
208
|
for (const name of names) {
|
|
209
209
|
if (!Object.hasOwn(flags, name)) continue;
|
|
@@ -985,8 +985,13 @@ import {
|
|
|
985
985
|
DefaultSystemPromptBuilder,
|
|
986
986
|
setQueuedMessagesSnapshot
|
|
987
987
|
} from "@wrongstack/core/agent";
|
|
988
|
+
import { TOKENS } from "@wrongstack/core/kernel";
|
|
988
989
|
import { DefaultSessionStore } from "@wrongstack/core/storage";
|
|
989
|
-
import {
|
|
990
|
+
import {
|
|
991
|
+
activateProjectStateGuard,
|
|
992
|
+
resolveWstackPaths,
|
|
993
|
+
sessionScopedPath
|
|
994
|
+
} from "@wrongstack/core/utils";
|
|
990
995
|
async function switchProjectInPlace(ctx, targetRoot, displayName) {
|
|
991
996
|
const {
|
|
992
997
|
state,
|
|
@@ -1064,6 +1069,7 @@ async function switchProjectInPlace(ctx, targetRoot, displayName) {
|
|
|
1064
1069
|
});
|
|
1065
1070
|
targetActivated = true;
|
|
1066
1071
|
await state.activateSessionIdentity(nextWriter.id, target);
|
|
1072
|
+
await activateProjectStateGuard(resolved);
|
|
1067
1073
|
} catch (err) {
|
|
1068
1074
|
if (!targetActivated) await targetClaim?.cancel().catch(() => void 0);
|
|
1069
1075
|
else if (oldWriter) {
|
|
@@ -1124,6 +1130,13 @@ async function switchProjectInPlace(ctx, targetRoot, displayName) {
|
|
|
1124
1130
|
modeStore,
|
|
1125
1131
|
modeId: modeId ?? "default",
|
|
1126
1132
|
modePrompt: switchMode?.prompt ?? "",
|
|
1133
|
+
tokenSavingMode: config.features.tokenSavingMode,
|
|
1134
|
+
modelCapabilities: {
|
|
1135
|
+
maxContextTokens: context.provider.capabilities.maxContext,
|
|
1136
|
+
supportsTools: !!context.provider.capabilities.tools,
|
|
1137
|
+
supportsVision: !!context.provider.capabilities.vision,
|
|
1138
|
+
supportsReasoning: !!context.provider.capabilities.reasoning
|
|
1139
|
+
},
|
|
1127
1140
|
instructionPaths: {
|
|
1128
1141
|
globalDir: nextWpaths.globalInstructions,
|
|
1129
1142
|
projectDir: nextWpaths.inProjectInstructions,
|
|
@@ -1138,6 +1151,11 @@ async function switchProjectInPlace(ctx, targetRoot, displayName) {
|
|
|
1138
1151
|
provider: context.provider.id,
|
|
1139
1152
|
model: context.model
|
|
1140
1153
|
});
|
|
1154
|
+
if (agent.container.has(TOKENS.SystemPromptBuilder)) {
|
|
1155
|
+
agent.container.override(TOKENS.SystemPromptBuilder, () => switchBuilder, {
|
|
1156
|
+
owner: "tui-project-switch"
|
|
1157
|
+
});
|
|
1158
|
+
}
|
|
1141
1159
|
} catch (err) {
|
|
1142
1160
|
console.error(
|
|
1143
1161
|
JSON.stringify({
|
|
@@ -1298,6 +1316,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1298
1316
|
throw err;
|
|
1299
1317
|
}
|
|
1300
1318
|
writerSwapped = true;
|
|
1319
|
+
state.sessionRef && (state.sessionRef.current = resumed.writer);
|
|
1301
1320
|
await agent.ctx.flushConversationJournal().catch((err) => {
|
|
1302
1321
|
console.error(
|
|
1303
1322
|
JSON.stringify({
|
|
@@ -1851,6 +1870,57 @@ function createSettingsAdapter(ctx) {
|
|
|
1851
1870
|
return { getSettings, saveSettings };
|
|
1852
1871
|
}
|
|
1853
1872
|
|
|
1873
|
+
// src/boot/tui-theme-adapter.ts
|
|
1874
|
+
import * as fs4 from "node:fs/promises";
|
|
1875
|
+
import * as path9 from "node:path";
|
|
1876
|
+
import { atomicWrite as atomicWrite2 } from "@wrongstack/core/utils";
|
|
1877
|
+
var VALID_PRESETS = /* @__PURE__ */ new Set([
|
|
1878
|
+
"catppuccin",
|
|
1879
|
+
"tokyo-night",
|
|
1880
|
+
"nord",
|
|
1881
|
+
"cyberpunk",
|
|
1882
|
+
"dracula",
|
|
1883
|
+
"gruvbox-dark",
|
|
1884
|
+
"solarized-dark",
|
|
1885
|
+
"one-dark",
|
|
1886
|
+
"monokai",
|
|
1887
|
+
"rose-pine",
|
|
1888
|
+
"kanagawa",
|
|
1889
|
+
"ayu-dark",
|
|
1890
|
+
"everforest",
|
|
1891
|
+
"night-owl",
|
|
1892
|
+
"synthwave"
|
|
1893
|
+
]);
|
|
1894
|
+
function createThemeAdapter({ configStore, wpaths }) {
|
|
1895
|
+
return {
|
|
1896
|
+
getThemePreset: () => {
|
|
1897
|
+
const live = configStore.get();
|
|
1898
|
+
const candidate = live.themePreset;
|
|
1899
|
+
return candidate && VALID_PRESETS.has(candidate) ? candidate : void 0;
|
|
1900
|
+
},
|
|
1901
|
+
saveThemePreset: async (preset) => {
|
|
1902
|
+
if (!VALID_PRESETS.has(preset)) {
|
|
1903
|
+
throw new Error(`Unknown theme preset: ${preset}`);
|
|
1904
|
+
}
|
|
1905
|
+
configStore.update({ themePreset: preset });
|
|
1906
|
+
const configPath = activeProfileConfigPath(wpaths, configStore.get());
|
|
1907
|
+
let parsed = {};
|
|
1908
|
+
try {
|
|
1909
|
+
const raw = await fs4.readFile(configPath, "utf8");
|
|
1910
|
+
parsed = JSON.parse(raw);
|
|
1911
|
+
} catch (err) {
|
|
1912
|
+
const e = err;
|
|
1913
|
+
if (e.code !== "ENOENT") {
|
|
1914
|
+
throw err;
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
parsed.themePreset = preset;
|
|
1918
|
+
await fs4.mkdir(path9.dirname(configPath), { recursive: true });
|
|
1919
|
+
await atomicWrite2(configPath, JSON.stringify(parsed, null, 2), { mode: 384 });
|
|
1920
|
+
}
|
|
1921
|
+
};
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1854
1924
|
// src/brain-menu/panel-service.ts
|
|
1855
1925
|
import { BUILTIN_COUNCIL_PERSONAS } from "@wrongstack/core/execution";
|
|
1856
1926
|
var PERSONA_CATALOG = BUILTIN_COUNCIL_PERSONAS.map((persona) => ({
|
|
@@ -2268,7 +2338,9 @@ async function finalizeExecutionCleanup(input) {
|
|
|
2268
2338
|
|
|
2269
2339
|
// src/execution-kanban-dispatch.ts
|
|
2270
2340
|
import { randomUUID } from "node:crypto";
|
|
2341
|
+
import { missingRequiredRuntimeTools } from "@wrongstack/core/agent-catalog";
|
|
2271
2342
|
import { WIDE_SUBAGENT_CAPABILITIES } from "@wrongstack/core/security";
|
|
2343
|
+
import { stripFrontmatter } from "@wrongstack/core/skills";
|
|
2272
2344
|
|
|
2273
2345
|
// src/kanban-dispatch-route.ts
|
|
2274
2346
|
import { fallbackProfileChain, parseModelRef as parseModelRef2 } from "@wrongstack/core/agent";
|
|
@@ -2307,21 +2379,43 @@ function createKanbanDispatchHandler({
|
|
|
2307
2379
|
} = resolveKanbanDispatchRoute(config, spawnOpts);
|
|
2308
2380
|
let agentDescription = description;
|
|
2309
2381
|
if (spawnOpts?.skills?.length && skillLoader) {
|
|
2310
|
-
const
|
|
2311
|
-
|
|
2382
|
+
const availableToolNames = spawnOpts.tools;
|
|
2383
|
+
const loaded = [];
|
|
2384
|
+
for (const skillName of spawnOpts.skills) {
|
|
2385
|
+
try {
|
|
2312
2386
|
const manifest = await skillLoader.find(skillName);
|
|
2313
|
-
if (!manifest)
|
|
2314
|
-
|
|
2315
|
-
|
|
2387
|
+
if (!manifest) {
|
|
2388
|
+
process.emitWarning(`Kanban dispatch skill not found, skipped: ${skillName}`, {
|
|
2389
|
+
code: "WRONGSTACK_KANBAN_SKILL_SKIPPED"
|
|
2390
|
+
});
|
|
2391
|
+
continue;
|
|
2392
|
+
}
|
|
2393
|
+
if (availableToolNames !== void 0 && missingRequiredRuntimeTools(manifest.requiredTools, availableToolNames).length > 0) {
|
|
2394
|
+
process.emitWarning(
|
|
2395
|
+
`Kanban dispatch skill "${skillName}" needs tools this worker does not have, skipped.`,
|
|
2396
|
+
{ code: "WRONGSTACK_KANBAN_SKILL_SKIPPED" }
|
|
2397
|
+
);
|
|
2398
|
+
continue;
|
|
2399
|
+
}
|
|
2400
|
+
const body = stripFrontmatter(await skillLoader.readBody(skillName)).trim();
|
|
2401
|
+
if (!body) continue;
|
|
2402
|
+
loaded.push(`## Required skill: ${skillName}
|
|
2316
2403
|
|
|
2317
|
-
${body}
|
|
2318
|
-
})
|
|
2319
|
-
|
|
2320
|
-
|
|
2404
|
+
${body}`);
|
|
2405
|
+
} catch (err) {
|
|
2406
|
+
process.emitWarning(
|
|
2407
|
+
`Kanban dispatch skill "${skillName}" could not be loaded, skipped: ${err instanceof Error ? err.message : String(err)}`,
|
|
2408
|
+
{ code: "WRONGSTACK_KANBAN_SKILL_SKIPPED" }
|
|
2409
|
+
);
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
if (loaded.length > 0) {
|
|
2413
|
+
agentDescription = `${description}
|
|
2321
2414
|
|
|
2322
2415
|
# Required agentic skill instructions
|
|
2323
2416
|
|
|
2324
2417
|
${loaded.join("\n\n")}`;
|
|
2418
|
+
}
|
|
2325
2419
|
}
|
|
2326
2420
|
void (async () => {
|
|
2327
2421
|
const built = await sddSubagentFactory({
|
|
@@ -2664,7 +2758,7 @@ function createChimeraWorkRegistry() {
|
|
|
2664
2758
|
|
|
2665
2759
|
// src/execution-chimera-cascade.ts
|
|
2666
2760
|
import * as fsp from "node:fs/promises";
|
|
2667
|
-
import * as
|
|
2761
|
+
import * as path10 from "node:path";
|
|
2668
2762
|
import { emitReviewIfChanged } from "@wrongstack/core/plugin";
|
|
2669
2763
|
|
|
2670
2764
|
// src/chimera-review-task.ts
|
|
@@ -3027,7 +3121,7 @@ async function maybeReReviewCascade({
|
|
|
3027
3121
|
const reReadFiles = [];
|
|
3028
3122
|
for (const f of bundle.files) {
|
|
3029
3123
|
try {
|
|
3030
|
-
const absPath =
|
|
3124
|
+
const absPath = path10.join(bundle.cwd, f.path);
|
|
3031
3125
|
const content = await fsp.readFile(absPath, "utf8");
|
|
3032
3126
|
reReadFiles.push({ path: f.path, status: "modified", content });
|
|
3033
3127
|
} catch {
|
|
@@ -3096,7 +3190,7 @@ async function maybeReReviewCascade({
|
|
|
3096
3190
|
|
|
3097
3191
|
// src/execution-chimera-review.ts
|
|
3098
3192
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
3099
|
-
import
|
|
3193
|
+
import path11 from "node:path";
|
|
3100
3194
|
import { effectiveFallbackChain } from "@wrongstack/core/agent";
|
|
3101
3195
|
import {
|
|
3102
3196
|
CHIMERA_REVIEW_PROMPT,
|
|
@@ -3109,7 +3203,7 @@ import {
|
|
|
3109
3203
|
function normalizeFileKeyForCitation(raw, cwd) {
|
|
3110
3204
|
const forward = raw.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
3111
3205
|
const isAbsolute = forward.startsWith("/") || /^[a-zA-Z]:\//.test(forward);
|
|
3112
|
-
const pathMod = process.platform === "win32" ?
|
|
3206
|
+
const pathMod = process.platform === "win32" ? path11.win32 : path11;
|
|
3113
3207
|
const relative = isAbsolute ? pathMod.relative(cwd, forward).replace(/\\/g, "/").replace(/^\.\//, "") : forward;
|
|
3114
3208
|
return process.platform === "win32" ? relative.toLowerCase() : relative;
|
|
3115
3209
|
}
|
|
@@ -3307,7 +3401,7 @@ function installChimeraReviewHandler({
|
|
|
3307
3401
|
const changedBasenameIndex = /* @__PURE__ */ new Map();
|
|
3308
3402
|
for (const file of p.files) {
|
|
3309
3403
|
const normalized = normalizeFileKeyForCitation(file.path, p.cwd);
|
|
3310
|
-
const basename7 =
|
|
3404
|
+
const basename7 = path11.basename(file.path).toLowerCase();
|
|
3311
3405
|
const bucket = changedBasenameIndex.get(basename7);
|
|
3312
3406
|
if (bucket) bucket.push(normalized);
|
|
3313
3407
|
else changedBasenameIndex.set(basename7, [normalized]);
|
|
@@ -3315,7 +3409,7 @@ function installChimeraReviewHandler({
|
|
|
3315
3409
|
const droppedCitations = citedFindings.filter((finding) => {
|
|
3316
3410
|
const citedKey = normalizeFileKeyForCitation(finding.location.file, p.cwd);
|
|
3317
3411
|
if (citedPaths.has(citedKey)) return false;
|
|
3318
|
-
const basename7 =
|
|
3412
|
+
const basename7 = path11.basename(finding.location.file).toLowerCase();
|
|
3319
3413
|
const bucket = changedBasenameIndex.get(basename7);
|
|
3320
3414
|
return !(bucket && bucket.length === 1);
|
|
3321
3415
|
});
|
|
@@ -3616,6 +3710,7 @@ import {
|
|
|
3616
3710
|
} from "@wrongstack/core/utils";
|
|
3617
3711
|
import { readClipboardImage, routeImagesForModel } from "@wrongstack/runtime";
|
|
3618
3712
|
import { createAutoProceedLoopGuard } from "@wrongstack/tools/auto-proceed-loop-guard";
|
|
3713
|
+
import { todoTool } from "@wrongstack/tools/todo";
|
|
3619
3714
|
|
|
3620
3715
|
// src/repl-auto-proceed.ts
|
|
3621
3716
|
import { color as color6, estimateRequestTokensCalibrated } from "@wrongstack/core/utils";
|
|
@@ -3791,7 +3886,7 @@ async function runContextCompaction(opts, _signal) {
|
|
|
3791
3886
|
|
|
3792
3887
|
// src/repl-client-registration.ts
|
|
3793
3888
|
import * as crypto from "node:crypto";
|
|
3794
|
-
import * as
|
|
3889
|
+
import * as path12 from "node:path";
|
|
3795
3890
|
import { getSharedProjectMailbox, resolveProjectDir } from "@wrongstack/core/coordination";
|
|
3796
3891
|
import { wstackGlobalRoot } from "@wrongstack/core/utils";
|
|
3797
3892
|
function registerReplClient(opts) {
|
|
@@ -3801,7 +3896,7 @@ function registerReplClient(opts) {
|
|
|
3801
3896
|
const hqConnection = startCliHqConnection({
|
|
3802
3897
|
clientKind: "repl",
|
|
3803
3898
|
projectRoot: replProjectRoot,
|
|
3804
|
-
projectName:
|
|
3899
|
+
projectName: path12.basename(replProjectRoot),
|
|
3805
3900
|
appConfig: opts.appConfig,
|
|
3806
3901
|
capabilities: ["telemetry.publish", "mailbox.summary"]
|
|
3807
3902
|
});
|
|
@@ -3815,7 +3910,7 @@ function registerReplClient(opts) {
|
|
|
3815
3910
|
clientMailbox.registerClient({
|
|
3816
3911
|
clientId,
|
|
3817
3912
|
sessionId: opts.getSessionId?.() ?? replProjectRoot,
|
|
3818
|
-
name: `REPL [${
|
|
3913
|
+
name: `REPL [${path12.basename(replProjectRoot)}]`,
|
|
3819
3914
|
source: "repl",
|
|
3820
3915
|
pid: process.pid
|
|
3821
3916
|
}).then(() => {
|
|
@@ -4117,10 +4212,14 @@ ${lines.join("\n")}
|
|
|
4117
4212
|
if (resolved.source === "todo" && resolved.todoId) {
|
|
4118
4213
|
const selected = todos.find((todo) => todo.id === resolved.todoId);
|
|
4119
4214
|
if (selected?.status === "pending") {
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4215
|
+
await todoTool.execute(
|
|
4216
|
+
{
|
|
4217
|
+
todos: todos.map(
|
|
4218
|
+
(todo) => todo.id === resolved.todoId ? { ...todo, status: "in_progress" } : todo.status === "in_progress" ? { ...todo, status: "pending" } : todo
|
|
4219
|
+
)
|
|
4220
|
+
},
|
|
4221
|
+
opts.agent.ctx,
|
|
4222
|
+
{ signal: AbortSignal.timeout(3e4) }
|
|
4124
4223
|
);
|
|
4125
4224
|
}
|
|
4126
4225
|
}
|
|
@@ -4293,10 +4392,14 @@ ${color9.dim(taskList2)}
|
|
|
4293
4392
|
if (resolved.source === "todo" && resolved.todoId) {
|
|
4294
4393
|
const selected = opts.agent.ctx.todos.find((todo) => todo.id === resolved.todoId);
|
|
4295
4394
|
if (selected?.status === "pending") {
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4395
|
+
await todoTool.execute(
|
|
4396
|
+
{
|
|
4397
|
+
todos: opts.agent.ctx.todos.map(
|
|
4398
|
+
(todo) => todo.id === resolved.todoId ? { ...todo, status: "in_progress" } : todo.status === "in_progress" ? { ...todo, status: "pending" } : todo
|
|
4399
|
+
)
|
|
4400
|
+
},
|
|
4401
|
+
opts.agent.ctx,
|
|
4402
|
+
{ signal: AbortSignal.timeout(3e4) }
|
|
4300
4403
|
);
|
|
4301
4404
|
}
|
|
4302
4405
|
}
|
|
@@ -4678,6 +4781,7 @@ async function execute(deps) {
|
|
|
4678
4781
|
positional,
|
|
4679
4782
|
slashRegistry,
|
|
4680
4783
|
tokenCounter,
|
|
4784
|
+
sessionRef,
|
|
4681
4785
|
activateSessionIdentity,
|
|
4682
4786
|
updateInfo: initialUpdateInfo,
|
|
4683
4787
|
webuiSessionChild
|
|
@@ -4874,6 +4978,12 @@ async function execute(deps) {
|
|
|
4874
4978
|
activeSessionStore,
|
|
4875
4979
|
activateSessionIdentity,
|
|
4876
4980
|
detachActiveTodosCheckpoint,
|
|
4981
|
+
// Plumbed from cli-main.ts so `resumeSession` can repoint the ref
|
|
4982
|
+
// when an in-process `/resume` swaps the active writer. Optional
|
|
4983
|
+
// on TuiRuntimeState; tests/hosts that omit it revert to the
|
|
4984
|
+
// pre-refactor behavior where provider calls stay pinned to the
|
|
4985
|
+
// boot session.
|
|
4986
|
+
sessionRef,
|
|
4877
4987
|
pendingProjectSwitch: null,
|
|
4878
4988
|
autonomousCoordinator: null,
|
|
4879
4989
|
coordinatorRun: null,
|
|
@@ -4988,6 +5098,8 @@ async function execute(deps) {
|
|
|
4988
5098
|
fleetStreamController,
|
|
4989
5099
|
applyLiveSettings
|
|
4990
5100
|
}),
|
|
5101
|
+
...createThemeAdapter({ configStore, wpaths }),
|
|
5102
|
+
configStore,
|
|
4991
5103
|
effectiveMaxContext,
|
|
4992
5104
|
titleAnimation: config.autonomy?.["terminalTitleAnimation"] ?? true,
|
|
4993
5105
|
chime: config.autonomy?.["chime"] ?? false,
|
|
@@ -5191,7 +5303,7 @@ async function execute(deps) {
|
|
|
5191
5303
|
attachments,
|
|
5192
5304
|
effectiveMaxContext,
|
|
5193
5305
|
getEffectiveMaxContext,
|
|
5194
|
-
projectName:
|
|
5306
|
+
projectName: path13.basename(projectRoot) || void 0,
|
|
5195
5307
|
projectRoot,
|
|
5196
5308
|
appConfig: config,
|
|
5197
5309
|
getSessionId: () => agent.ctx.session?.id ?? session.id,
|
|
@@ -5250,4 +5362,4 @@ export {
|
|
|
5250
5362
|
execute,
|
|
5251
5363
|
resolveReviewerFallbackModels
|
|
5252
5364
|
};
|
|
5253
|
-
//# sourceMappingURL=execution-
|
|
5365
|
+
//# sourceMappingURL=execution-YMBD7YWC.js.map
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import type { SubagentConfig } from '@wrongstack/core/types';
|
|
2
2
|
import type { MultiAgentDeps } from './host-types.js';
|
|
3
|
+
/** Skills whose bodies were requested but did not make it into the prompt. */
|
|
4
|
+
export interface SkillResolutionReport {
|
|
5
|
+
content: string;
|
|
6
|
+
selected: string[];
|
|
7
|
+
/** skill → why it was dropped, so the omission is never silent. */
|
|
8
|
+
dropped: Record<string, 'not-found' | 'missing-capability' | 'missing-tool' | 'budget' | 'empty'>;
|
|
9
|
+
/** Skills kept under budget by shortening their bundled body. */
|
|
10
|
+
trimmed: string[];
|
|
11
|
+
}
|
|
12
|
+
export declare function resolveHostSubagentSkillResolution(deps: MultiAgentDeps, roster: Record<string, SubagentConfig>, subCfg: SubagentConfig, availableToolNames?: readonly string[]): Promise<SkillResolutionReport>;
|
|
13
|
+
/** Backwards-compatible wrapper for callers that only need the prompt text. */
|
|
3
14
|
export declare function resolveHostSubagentSkillContent(deps: MultiAgentDeps, roster: Record<string, SubagentConfig>, subCfg: SubagentConfig, availableToolNames?: readonly string[]): Promise<string>;
|
|
4
15
|
export declare function retrieveHostSubagentMemory(deps: MultiAgentDeps, getLeaderMode: (() => string | undefined) | undefined, subCfg: SubagentConfig, taskContext?: Record<string, unknown>): Promise<string[]>;
|
|
5
16
|
//# sourceMappingURL=host-context.d.ts.map
|
|
@@ -5,7 +5,7 @@ export declare class HostLearningRoleTracker {
|
|
|
5
5
|
private readonly roles;
|
|
6
6
|
private readonly accessOrder;
|
|
7
7
|
constructor(maxEntries?: number);
|
|
8
|
-
record(subagentId: string, role: string): void;
|
|
9
|
-
capture(result: TaskResult, deps: Pick<MultiAgentDeps, 'container' | 'projectRoot'
|
|
8
|
+
record(subagentId: string, role: string, skills?: readonly string[]): void;
|
|
9
|
+
capture(result: TaskResult, deps: Pick<MultiAgentDeps, 'container' | 'projectRoot'>, onCaptured?: (role: string) => void): void;
|
|
10
10
|
}
|
|
11
11
|
//# sourceMappingURL=host-learning-tracker.d.ts.map
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import type { TaskResult } from '@wrongstack/core/types';
|
|
2
2
|
import type { MultiAgentDeps } from './host-types.js';
|
|
3
|
-
|
|
3
|
+
/** What a spawn recorded about the agent that will produce this result. */
|
|
4
|
+
export interface LearningSubject {
|
|
5
|
+
role: string;
|
|
6
|
+
skills: readonly string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function captureCompletedTaskLearningForHost(result: TaskResult, deps: Pick<MultiAgentDeps, 'container' | 'projectRoot'>, subjects: ReadonlyMap<string, LearningSubject>,
|
|
9
|
+
/**
|
|
10
|
+
* Called when a capture persisted at least one directive. The auto-optimize
|
|
11
|
+
* scheduler uses it as its trigger, so distillation follows learning without
|
|
12
|
+
* anyone pressing a button.
|
|
13
|
+
*/
|
|
14
|
+
onCaptured?: (role: string) => void): void;
|
|
4
15
|
//# sourceMappingURL=host-learning.d.ts.map
|
|
@@ -1,3 +1,36 @@
|
|
|
1
1
|
import type { SessionWriter } from '@wrongstack/core/types';
|
|
2
|
+
/**
|
|
3
|
+
* Session writer for a subagent that has no journal of its own: its events are
|
|
4
|
+
* interleaved into the parent's JSONL.
|
|
5
|
+
*
|
|
6
|
+
* Lifecycle and rewind *control* stay no-ops — `writeCheckpoint`,
|
|
7
|
+
* `writeInFlightMarker`, `truncateToCheckpoint`, `clearSession` and `close`
|
|
8
|
+
* belong to the parent, and a subagent driving them would corrupt the parent's
|
|
9
|
+
* checkpoint chain and crash-recovery markers.
|
|
10
|
+
*
|
|
11
|
+
* Rewind *evidence* is a different thing and is forwarded. A subagent's file
|
|
12
|
+
* mutations are real edits to the user's working tree, made under the parent
|
|
13
|
+
* prompt that spawned it; dropping their `file_snapshot` records left `/rewind`
|
|
14
|
+
* quietly unable to undo them, with nothing in the transcript saying so. The
|
|
15
|
+
* parent writer files them against its own `activePromptIndex`, which is
|
|
16
|
+
* exactly the prompt a user rewinding this work would target.
|
|
17
|
+
*/
|
|
2
18
|
export declare function createParentSubagentSessionWriter(parentSession: SessionWriter): SessionWriter;
|
|
19
|
+
/**
|
|
20
|
+
* Wrap a subagent's own `SessionWriter` so its file mutations are ALSO recorded
|
|
21
|
+
* against the parent session.
|
|
22
|
+
*
|
|
23
|
+
* When a subagent gets a real per-subagent JSONL, its `file_snapshot` events
|
|
24
|
+
* land in that file — under the director run directory, which
|
|
25
|
+
* `DefaultSessionRewinder` never reads: it resolves one path, the session being
|
|
26
|
+
* rewound. So the richer, "proper" subagent-session path was the one that lost
|
|
27
|
+
* rewind coverage entirely, while the fallback shim above at least had the
|
|
28
|
+
* parent handle in reach.
|
|
29
|
+
*
|
|
30
|
+
* Recording to the parent as well keeps one authority for undo (the session the
|
|
31
|
+
* user actually rewinds) without taking anything away from the subagent's own
|
|
32
|
+
* transcript, which still receives every other event including the conversation
|
|
33
|
+
* that produced the edit.
|
|
34
|
+
*/
|
|
35
|
+
export declare function withParentFileSnapshots(subagentSession: SessionWriter, parentSession: SessionWriter): SessionWriter;
|
|
3
36
|
//# sourceMappingURL=host-session-writer.d.ts.map
|
|
@@ -9,7 +9,7 @@ export interface HostSubagentFactoryContext {
|
|
|
9
9
|
sessionFactory?: DirectorSessionFactory | undefined;
|
|
10
10
|
filterTools: (allow?: string[]) => Tool[];
|
|
11
11
|
mailboxProjectDir: () => string;
|
|
12
|
-
recordLearningRole: (subagentId: string, role: string) => void;
|
|
12
|
+
recordLearningRole: (subagentId: string, role: string, skills?: readonly string[]) => void;
|
|
13
13
|
subagentToolRegistry: (allow?: string[]) => ToolRegistry;
|
|
14
14
|
}
|
|
15
15
|
export declare function createHostSubagentFactory(config: Config, host: HostSubagentFactoryContext): AgentFactory;
|
package/dist/fleet/host.d.ts
CHANGED
|
@@ -39,6 +39,9 @@ export declare class MultiAgentHost {
|
|
|
39
39
|
* Bounded to 20 entries with LRU eviction to prevent unbounded memory growth. */
|
|
40
40
|
private readonly acpRunnerCache;
|
|
41
41
|
private readonly learningRoles;
|
|
42
|
+
/** Background distillation of captured learning into per-skill addenda. */
|
|
43
|
+
private learningOptimizer;
|
|
44
|
+
private learningSwept;
|
|
42
45
|
/** Adaptive concurrency controller — created in buildDirector() when config has
|
|
43
46
|
* adaptiveConcurrency.enabled = true. Monitors FleetBus for 429 errors and
|
|
44
47
|
* automatically adjusts maxConcurrent to prevent rate limiting. */
|
|
@@ -202,6 +205,35 @@ export declare class MultiAgentHost {
|
|
|
202
205
|
private emitLifecycleCompleted;
|
|
203
206
|
private recordLearningRole;
|
|
204
207
|
private captureCompletedTaskLearning;
|
|
208
|
+
/**
|
|
209
|
+
* Lazily built so a session that never spawns a subagent pays nothing, and
|
|
210
|
+
* so the policy is read from the live config rather than frozen at boot.
|
|
211
|
+
* Returns null when auto-optimization is switched off.
|
|
212
|
+
*/
|
|
213
|
+
private getLearningOptimizer;
|
|
214
|
+
/**
|
|
215
|
+
* Break a dispatch tie with a model when the keyword heuristic is ambiguous.
|
|
216
|
+
*
|
|
217
|
+
* Routes through the `dispatcher` model-matrix slot when one is configured —
|
|
218
|
+
* picking a role is a short classification, so it belongs on a cheap fast
|
|
219
|
+
* model rather than the leader's — and the session default otherwise.
|
|
220
|
+
* Returning `null` on any failure leaves the dispatcher on its heuristic
|
|
221
|
+
* result, so routing degrades rather than breaking a spawn.
|
|
222
|
+
*/
|
|
223
|
+
private classifyDispatch;
|
|
224
|
+
/**
|
|
225
|
+
* Resolve a model for the distillation pass. Uses the `memory-curator` slot
|
|
226
|
+
* of the model matrix when one is configured — curating learned knowledge is
|
|
227
|
+
* exactly that role's job — and the session default otherwise. A failure
|
|
228
|
+
* here is not fatal: the pass still writes the deterministic skill addenda.
|
|
229
|
+
*/
|
|
230
|
+
private resolveOptimizerLlm;
|
|
231
|
+
/**
|
|
232
|
+
* Evaluate every role with learning data once per session. Without it, a
|
|
233
|
+
* role that became eligible before this session would wait for its next
|
|
234
|
+
* capture — which for a rarely-used role can be never.
|
|
235
|
+
*/
|
|
236
|
+
private sweepLearningOptimization;
|
|
205
237
|
status(): FleetHostStatus;
|
|
206
238
|
/**
|
|
207
239
|
* Read-only concurrency + lifetime spawn budget for `/fleet status` and
|
|
@@ -47,7 +47,7 @@ var hqCmd = async (args, deps) => {
|
|
|
47
47
|
return 1;
|
|
48
48
|
};
|
|
49
49
|
async function startServer(deps) {
|
|
50
|
-
const { startHqServer } = await import("./hq-server-
|
|
50
|
+
const { startHqServer } = await import("./hq-server-IVZLVCFV.js");
|
|
51
51
|
const dataDir = resolveDataDir(deps);
|
|
52
52
|
const flags = deps.flags ?? {};
|
|
53
53
|
const host = typeof flags["host"] === "string" ? flags["host"] : HQ_CLI_DEFAULT_HOST;
|
|
@@ -612,4 +612,4 @@ export {
|
|
|
612
612
|
hqCmd,
|
|
613
613
|
resolveAuditActor
|
|
614
614
|
};
|
|
615
|
-
//# sourceMappingURL=hq-
|
|
615
|
+
//# sourceMappingURL=hq-5G6D5YIU.js.map
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
readLocalSubagentTranscript,
|
|
16
16
|
sanitizeApiError,
|
|
17
17
|
startHqServer
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-RHLQT3EV.js";
|
|
19
19
|
import "./chunk-KE7E7DPX.js";
|
|
20
20
|
import "./chunk-Q5GTM25S.js";
|
|
21
21
|
import "./chunk-7OCVIDC7.js";
|
|
@@ -37,4 +37,4 @@ export {
|
|
|
37
37
|
sanitizeApiError,
|
|
38
38
|
startHqServer
|
|
39
39
|
};
|
|
40
|
-
//# sourceMappingURL=hq-server-
|
|
40
|
+
//# sourceMappingURL=hq-server-IVZLVCFV.js.map
|