@mindstudio-ai/remy 0.1.143 → 0.1.144
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/headless.js +48 -37
- package/dist/index.js +159 -148
- package/package.json +1 -1
package/dist/headless.js
CHANGED
|
@@ -685,13 +685,13 @@ var log4 = createLogger("compaction");
|
|
|
685
685
|
var CONVERSATION_SUMMARY_PROMPT = readAsset("compaction", "conversation.md");
|
|
686
686
|
var SUBAGENT_SUMMARY_PROMPT = readAsset("compaction", "subagent.md");
|
|
687
687
|
var SUMMARIZABLE_SUBAGENTS = ["visualDesignExpert", "productVision"];
|
|
688
|
-
async function compactConversation(
|
|
689
|
-
const
|
|
688
|
+
async function compactConversation(messages, apiConfig, system, tools2) {
|
|
689
|
+
const endIndex = findSafeInsertionPoint(messages);
|
|
690
690
|
const summaries = [];
|
|
691
691
|
const tasks = [];
|
|
692
692
|
const conversationMessages = getConversationMessagesForSummary(
|
|
693
|
-
|
|
694
|
-
|
|
693
|
+
messages,
|
|
694
|
+
endIndex
|
|
695
695
|
);
|
|
696
696
|
if (conversationMessages.length > 0) {
|
|
697
697
|
tasks.push(
|
|
@@ -711,9 +711,9 @@ async function compactConversation(state, apiConfig, system, tools2) {
|
|
|
711
711
|
}
|
|
712
712
|
for (const name of SUMMARIZABLE_SUBAGENTS) {
|
|
713
713
|
const subagentMessages = getSubAgentMessagesForSummary(
|
|
714
|
-
|
|
714
|
+
messages,
|
|
715
715
|
name,
|
|
716
|
-
|
|
716
|
+
endIndex
|
|
717
717
|
);
|
|
718
718
|
if (subagentMessages.length > 0) {
|
|
719
719
|
tasks.push(
|
|
@@ -745,14 +745,8 @@ async function compactConversation(state, apiConfig, system, tools2) {
|
|
|
745
745
|
}
|
|
746
746
|
]
|
|
747
747
|
}));
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
}
|
|
751
|
-
log4.info("Compaction complete", {
|
|
752
|
-
summaries: summaries.length,
|
|
753
|
-
insertionIndex,
|
|
754
|
-
messagesAfter: state.messages.length - insertionIndex - checkpointMessages.length
|
|
755
|
-
});
|
|
748
|
+
log4.info("Compaction complete", { summaries: summaries.length });
|
|
749
|
+
return checkpointMessages;
|
|
756
750
|
}
|
|
757
751
|
function findSafeInsertionPoint(messages) {
|
|
758
752
|
let idx = messages.length;
|
|
@@ -5140,9 +5134,31 @@ function executeTool(name, input, context) {
|
|
|
5140
5134
|
return tool.execute(input, context);
|
|
5141
5135
|
}
|
|
5142
5136
|
|
|
5137
|
+
// src/compaction/trigger.ts
|
|
5138
|
+
var log7 = createLogger("compaction:trigger");
|
|
5139
|
+
var pendingSummaries = [];
|
|
5140
|
+
function getPendingSummaries() {
|
|
5141
|
+
return pendingSummaries.splice(0);
|
|
5142
|
+
}
|
|
5143
|
+
function triggerCompaction(state, apiConfig, callbacks) {
|
|
5144
|
+
callbacks?.onStart?.();
|
|
5145
|
+
const system = buildSystemPrompt("onboardingFinished");
|
|
5146
|
+
const tools2 = getToolDefinitions("onboardingFinished");
|
|
5147
|
+
compactConversation(state.messages, apiConfig, system, tools2).then((summaries) => {
|
|
5148
|
+
pendingSummaries.push(...summaries);
|
|
5149
|
+
callbacks?.onSummariesReady?.();
|
|
5150
|
+
log7.info("Compaction complete");
|
|
5151
|
+
}).catch((err) => {
|
|
5152
|
+
callbacks?.onError?.(err.message || "Compaction failed");
|
|
5153
|
+
log7.error("Compaction failed", { error: err.message });
|
|
5154
|
+
}).finally(() => {
|
|
5155
|
+
callbacks?.onFinally?.();
|
|
5156
|
+
});
|
|
5157
|
+
}
|
|
5158
|
+
|
|
5143
5159
|
// src/session.ts
|
|
5144
5160
|
import fs19 from "fs";
|
|
5145
|
-
var
|
|
5161
|
+
var log8 = createLogger("session");
|
|
5146
5162
|
var SESSION_FILE = ".remy-session.json";
|
|
5147
5163
|
function loadSession(state) {
|
|
5148
5164
|
try {
|
|
@@ -5150,7 +5166,7 @@ function loadSession(state) {
|
|
|
5150
5166
|
const data = JSON.parse(raw);
|
|
5151
5167
|
if (Array.isArray(data.messages) && data.messages.length > 0) {
|
|
5152
5168
|
state.messages = sanitizeMessages(data.messages);
|
|
5153
|
-
|
|
5169
|
+
log8.info("Session loaded", { messageCount: state.messages.length });
|
|
5154
5170
|
return true;
|
|
5155
5171
|
}
|
|
5156
5172
|
} catch {
|
|
@@ -5200,9 +5216,9 @@ function saveSession(state) {
|
|
|
5200
5216
|
JSON.stringify({ messages: state.messages }, null, 2),
|
|
5201
5217
|
"utf-8"
|
|
5202
5218
|
);
|
|
5203
|
-
|
|
5219
|
+
log8.info("Session saved", { messageCount: state.messages.length });
|
|
5204
5220
|
} catch (err) {
|
|
5205
|
-
|
|
5221
|
+
log8.warn("Session save failed", { error: err.message });
|
|
5206
5222
|
}
|
|
5207
5223
|
}
|
|
5208
5224
|
function clearSession(state) {
|
|
@@ -5213,24 +5229,6 @@ function clearSession(state) {
|
|
|
5213
5229
|
}
|
|
5214
5230
|
}
|
|
5215
5231
|
|
|
5216
|
-
// src/compaction/trigger.ts
|
|
5217
|
-
var log8 = createLogger("compaction:trigger");
|
|
5218
|
-
function triggerCompaction(state, apiConfig, callbacks) {
|
|
5219
|
-
callbacks?.onStart?.();
|
|
5220
|
-
const system = buildSystemPrompt("onboardingFinished");
|
|
5221
|
-
const tools2 = getToolDefinitions("onboardingFinished");
|
|
5222
|
-
compactConversation(state, apiConfig, system, tools2).then(() => {
|
|
5223
|
-
saveSession(state);
|
|
5224
|
-
callbacks?.onComplete?.();
|
|
5225
|
-
log8.info("Compaction complete");
|
|
5226
|
-
}).catch((err) => {
|
|
5227
|
-
callbacks?.onError?.(err.message || "Compaction failed");
|
|
5228
|
-
log8.error("Compaction failed", { error: err.message });
|
|
5229
|
-
}).finally(() => {
|
|
5230
|
-
callbacks?.onFinally?.();
|
|
5231
|
-
});
|
|
5232
|
-
}
|
|
5233
|
-
|
|
5234
5232
|
// src/parsePartialJson.ts
|
|
5235
5233
|
var PartialJSON = class extends Error {
|
|
5236
5234
|
};
|
|
@@ -6157,6 +6155,15 @@ ${xmlParts}
|
|
|
6157
6155
|
}
|
|
6158
6156
|
}
|
|
6159
6157
|
}
|
|
6158
|
+
function applyPendingSummaries() {
|
|
6159
|
+
const summaries = getPendingSummaries();
|
|
6160
|
+
if (summaries.length === 0) {
|
|
6161
|
+
return;
|
|
6162
|
+
}
|
|
6163
|
+
const idx = findSafeInsertionPoint(state.messages);
|
|
6164
|
+
state.messages.splice(idx, 0, ...summaries);
|
|
6165
|
+
saveSession(state);
|
|
6166
|
+
}
|
|
6160
6167
|
function onBackgroundComplete(toolCallId, name, result, subAgentMessages) {
|
|
6161
6168
|
pendingBlockUpdates.push({ toolCallId, result, subAgentMessages });
|
|
6162
6169
|
log11.info("Background complete", {
|
|
@@ -6238,6 +6245,7 @@ ${xmlParts}
|
|
|
6238
6245
|
rid
|
|
6239
6246
|
);
|
|
6240
6247
|
setTimeout(() => {
|
|
6248
|
+
applyPendingSummaries();
|
|
6241
6249
|
applyPendingBlockUpdates();
|
|
6242
6250
|
flushBackgroundQueue();
|
|
6243
6251
|
}, 0);
|
|
@@ -6549,7 +6557,10 @@ ${xmlParts}
|
|
|
6549
6557
|
} catch {
|
|
6550
6558
|
}
|
|
6551
6559
|
},
|
|
6552
|
-
|
|
6560
|
+
onSummariesReady: () => {
|
|
6561
|
+
if (!running) {
|
|
6562
|
+
applyPendingSummaries();
|
|
6563
|
+
}
|
|
6553
6564
|
emit("compaction_complete", {}, requestId);
|
|
6554
6565
|
emit("completed", { success: true }, requestId);
|
|
6555
6566
|
},
|
package/dist/index.js
CHANGED
|
@@ -1326,13 +1326,13 @@ var init_assets = __esm({
|
|
|
1326
1326
|
});
|
|
1327
1327
|
|
|
1328
1328
|
// src/compaction/index.ts
|
|
1329
|
-
async function compactConversation(
|
|
1330
|
-
const
|
|
1329
|
+
async function compactConversation(messages, apiConfig, system, tools2) {
|
|
1330
|
+
const endIndex = findSafeInsertionPoint(messages);
|
|
1331
1331
|
const summaries = [];
|
|
1332
1332
|
const tasks = [];
|
|
1333
1333
|
const conversationMessages = getConversationMessagesForSummary(
|
|
1334
|
-
|
|
1335
|
-
|
|
1334
|
+
messages,
|
|
1335
|
+
endIndex
|
|
1336
1336
|
);
|
|
1337
1337
|
if (conversationMessages.length > 0) {
|
|
1338
1338
|
tasks.push(
|
|
@@ -1352,9 +1352,9 @@ async function compactConversation(state, apiConfig, system, tools2) {
|
|
|
1352
1352
|
}
|
|
1353
1353
|
for (const name of SUMMARIZABLE_SUBAGENTS) {
|
|
1354
1354
|
const subagentMessages = getSubAgentMessagesForSummary(
|
|
1355
|
-
|
|
1355
|
+
messages,
|
|
1356
1356
|
name,
|
|
1357
|
-
|
|
1357
|
+
endIndex
|
|
1358
1358
|
);
|
|
1359
1359
|
if (subagentMessages.length > 0) {
|
|
1360
1360
|
tasks.push(
|
|
@@ -1386,14 +1386,8 @@ async function compactConversation(state, apiConfig, system, tools2) {
|
|
|
1386
1386
|
}
|
|
1387
1387
|
]
|
|
1388
1388
|
}));
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
}
|
|
1392
|
-
log2.info("Compaction complete", {
|
|
1393
|
-
summaries: summaries.length,
|
|
1394
|
-
insertionIndex,
|
|
1395
|
-
messagesAfter: state.messages.length - insertionIndex - checkpointMessages.length
|
|
1396
|
-
});
|
|
1389
|
+
log2.info("Compaction complete", { summaries: summaries.length });
|
|
1390
|
+
return checkpointMessages;
|
|
1397
1391
|
}
|
|
1398
1392
|
function findSafeInsertionPoint(messages) {
|
|
1399
1393
|
let idx = messages.length;
|
|
@@ -1909,112 +1903,35 @@ var init_prompt = __esm({
|
|
|
1909
1903
|
}
|
|
1910
1904
|
});
|
|
1911
1905
|
|
|
1912
|
-
// src/session.ts
|
|
1913
|
-
import fs10 from "fs";
|
|
1914
|
-
function loadSession(state) {
|
|
1915
|
-
try {
|
|
1916
|
-
const raw = fs10.readFileSync(SESSION_FILE, "utf-8");
|
|
1917
|
-
const data = JSON.parse(raw);
|
|
1918
|
-
if (Array.isArray(data.messages) && data.messages.length > 0) {
|
|
1919
|
-
state.messages = sanitizeMessages(data.messages);
|
|
1920
|
-
log4.info("Session loaded", { messageCount: state.messages.length });
|
|
1921
|
-
return true;
|
|
1922
|
-
}
|
|
1923
|
-
} catch {
|
|
1924
|
-
}
|
|
1925
|
-
return false;
|
|
1926
|
-
}
|
|
1927
|
-
function sanitizeMessages(messages) {
|
|
1928
|
-
const result = [];
|
|
1929
|
-
for (let i = 0; i < messages.length; i++) {
|
|
1930
|
-
result.push(messages[i]);
|
|
1931
|
-
const msg = messages[i];
|
|
1932
|
-
if (msg.role !== "assistant" || !Array.isArray(msg.content)) {
|
|
1933
|
-
continue;
|
|
1934
|
-
}
|
|
1935
|
-
const toolBlocks = msg.content.filter(
|
|
1936
|
-
(b) => b.type === "tool"
|
|
1937
|
-
);
|
|
1938
|
-
if (toolBlocks.length === 0) {
|
|
1939
|
-
continue;
|
|
1940
|
-
}
|
|
1941
|
-
const resultIds = /* @__PURE__ */ new Set();
|
|
1942
|
-
for (let j = i + 1; j < messages.length; j++) {
|
|
1943
|
-
const next = messages[j];
|
|
1944
|
-
if (next.role === "user" && next.toolCallId) {
|
|
1945
|
-
resultIds.add(next.toolCallId);
|
|
1946
|
-
} else {
|
|
1947
|
-
break;
|
|
1948
|
-
}
|
|
1949
|
-
}
|
|
1950
|
-
for (const tc of toolBlocks) {
|
|
1951
|
-
if (!resultIds.has(tc.id)) {
|
|
1952
|
-
result.push({
|
|
1953
|
-
role: "user",
|
|
1954
|
-
content: "Error: tool result lost (session recovered)",
|
|
1955
|
-
toolCallId: tc.id,
|
|
1956
|
-
isToolError: true
|
|
1957
|
-
});
|
|
1958
|
-
}
|
|
1959
|
-
}
|
|
1960
|
-
}
|
|
1961
|
-
return result;
|
|
1962
|
-
}
|
|
1963
|
-
function saveSession(state) {
|
|
1964
|
-
try {
|
|
1965
|
-
fs10.writeFileSync(
|
|
1966
|
-
SESSION_FILE,
|
|
1967
|
-
JSON.stringify({ messages: state.messages }, null, 2),
|
|
1968
|
-
"utf-8"
|
|
1969
|
-
);
|
|
1970
|
-
log4.info("Session saved", { messageCount: state.messages.length });
|
|
1971
|
-
} catch (err) {
|
|
1972
|
-
log4.warn("Session save failed", { error: err.message });
|
|
1973
|
-
}
|
|
1974
|
-
}
|
|
1975
|
-
function clearSession(state) {
|
|
1976
|
-
state.messages = [];
|
|
1977
|
-
try {
|
|
1978
|
-
fs10.unlinkSync(SESSION_FILE);
|
|
1979
|
-
} catch {
|
|
1980
|
-
}
|
|
1981
|
-
}
|
|
1982
|
-
var log4, SESSION_FILE;
|
|
1983
|
-
var init_session = __esm({
|
|
1984
|
-
"src/session.ts"() {
|
|
1985
|
-
"use strict";
|
|
1986
|
-
init_logger();
|
|
1987
|
-
log4 = createLogger("session");
|
|
1988
|
-
SESSION_FILE = ".remy-session.json";
|
|
1989
|
-
}
|
|
1990
|
-
});
|
|
1991
|
-
|
|
1992
1906
|
// src/compaction/trigger.ts
|
|
1907
|
+
function getPendingSummaries() {
|
|
1908
|
+
return pendingSummaries.splice(0);
|
|
1909
|
+
}
|
|
1993
1910
|
function triggerCompaction(state, apiConfig, callbacks) {
|
|
1994
1911
|
callbacks?.onStart?.();
|
|
1995
1912
|
const system = buildSystemPrompt("onboardingFinished");
|
|
1996
1913
|
const tools2 = getToolDefinitions("onboardingFinished");
|
|
1997
|
-
compactConversation(state, apiConfig, system, tools2).then(() => {
|
|
1998
|
-
|
|
1999
|
-
callbacks?.
|
|
2000
|
-
|
|
1914
|
+
compactConversation(state.messages, apiConfig, system, tools2).then((summaries) => {
|
|
1915
|
+
pendingSummaries.push(...summaries);
|
|
1916
|
+
callbacks?.onSummariesReady?.();
|
|
1917
|
+
log4.info("Compaction complete");
|
|
2001
1918
|
}).catch((err) => {
|
|
2002
1919
|
callbacks?.onError?.(err.message || "Compaction failed");
|
|
2003
|
-
|
|
1920
|
+
log4.error("Compaction failed", { error: err.message });
|
|
2004
1921
|
}).finally(() => {
|
|
2005
1922
|
callbacks?.onFinally?.();
|
|
2006
1923
|
});
|
|
2007
1924
|
}
|
|
2008
|
-
var
|
|
1925
|
+
var log4, pendingSummaries;
|
|
2009
1926
|
var init_trigger = __esm({
|
|
2010
1927
|
"src/compaction/trigger.ts"() {
|
|
2011
1928
|
"use strict";
|
|
2012
1929
|
init_compaction();
|
|
2013
1930
|
init_prompt();
|
|
2014
1931
|
init_tools6();
|
|
2015
|
-
init_session();
|
|
2016
1932
|
init_logger();
|
|
2017
|
-
|
|
1933
|
+
log4 = createLogger("compaction:trigger");
|
|
1934
|
+
pendingSummaries = [];
|
|
2018
1935
|
}
|
|
2019
1936
|
});
|
|
2020
1937
|
|
|
@@ -2049,7 +1966,7 @@ var init_compactConversation = __esm({
|
|
|
2049
1966
|
});
|
|
2050
1967
|
|
|
2051
1968
|
// src/tools/code/readFile.ts
|
|
2052
|
-
import
|
|
1969
|
+
import fs10 from "fs/promises";
|
|
2053
1970
|
function isBinary(buffer) {
|
|
2054
1971
|
const sample = buffer.subarray(0, 8192);
|
|
2055
1972
|
for (let i = 0; i < sample.length; i++) {
|
|
@@ -2090,7 +2007,7 @@ var init_readFile = __esm({
|
|
|
2090
2007
|
},
|
|
2091
2008
|
async execute(input) {
|
|
2092
2009
|
try {
|
|
2093
|
-
const buffer = await
|
|
2010
|
+
const buffer = await fs10.readFile(input.path);
|
|
2094
2011
|
if (isBinary(buffer)) {
|
|
2095
2012
|
const size = buffer.length;
|
|
2096
2013
|
const unit = size > 1024 * 1024 ? `${(size / (1024 * 1024)).toFixed(1)}MB` : `${(size / 1024).toFixed(1)}KB`;
|
|
@@ -2126,7 +2043,7 @@ var init_readFile = __esm({
|
|
|
2126
2043
|
});
|
|
2127
2044
|
|
|
2128
2045
|
// src/tools/code/writeFile.ts
|
|
2129
|
-
import
|
|
2046
|
+
import fs11 from "fs/promises";
|
|
2130
2047
|
import path5 from "path";
|
|
2131
2048
|
var writeFileTool;
|
|
2132
2049
|
var init_writeFile = __esm({
|
|
@@ -2170,7 +2087,7 @@ var init_writeFile = __esm({
|
|
|
2170
2087
|
lastNewlineCount = newlineCount;
|
|
2171
2088
|
const lastNewline = partial.content.lastIndexOf("\n");
|
|
2172
2089
|
const completeContent = partial.content.substring(0, lastNewline + 1);
|
|
2173
|
-
const oldContent = await
|
|
2090
|
+
const oldContent = await fs11.readFile(partial.path, "utf-8").catch(() => "");
|
|
2174
2091
|
return `Writing ${partial.path} (${newlineCount} lines)
|
|
2175
2092
|
${unifiedDiff(partial.path, oldContent, completeContent)}`;
|
|
2176
2093
|
}
|
|
@@ -2179,13 +2096,13 @@ ${unifiedDiff(partial.path, oldContent, completeContent)}`;
|
|
|
2179
2096
|
async execute(input) {
|
|
2180
2097
|
const release = await acquireFileLock(input.path);
|
|
2181
2098
|
try {
|
|
2182
|
-
await
|
|
2099
|
+
await fs11.mkdir(path5.dirname(input.path), { recursive: true });
|
|
2183
2100
|
let oldContent = null;
|
|
2184
2101
|
try {
|
|
2185
|
-
oldContent = await
|
|
2102
|
+
oldContent = await fs11.readFile(input.path, "utf-8");
|
|
2186
2103
|
} catch {
|
|
2187
2104
|
}
|
|
2188
|
-
await
|
|
2105
|
+
await fs11.writeFile(input.path, input.content, "utf-8");
|
|
2189
2106
|
const lineCount = input.content.split("\n").length;
|
|
2190
2107
|
const label = oldContent !== null ? "Wrote" : "Created";
|
|
2191
2108
|
return `${label} ${input.path} (${lineCount} lines)
|
|
@@ -2285,7 +2202,7 @@ var init_helpers2 = __esm({
|
|
|
2285
2202
|
});
|
|
2286
2203
|
|
|
2287
2204
|
// src/tools/code/editFile/index.ts
|
|
2288
|
-
import
|
|
2205
|
+
import fs12 from "fs/promises";
|
|
2289
2206
|
var editFileTool;
|
|
2290
2207
|
var init_editFile = __esm({
|
|
2291
2208
|
"src/tools/code/editFile/index.ts"() {
|
|
@@ -2324,7 +2241,7 @@ var init_editFile = __esm({
|
|
|
2324
2241
|
async execute(input) {
|
|
2325
2242
|
const release = await acquireFileLock(input.path);
|
|
2326
2243
|
try {
|
|
2327
|
-
const content = await
|
|
2244
|
+
const content = await fs12.readFile(input.path, "utf-8");
|
|
2328
2245
|
const { old_string, new_string, replace_all } = input;
|
|
2329
2246
|
const occurrences = findOccurrences(content, old_string);
|
|
2330
2247
|
if (replace_all) {
|
|
@@ -2340,7 +2257,7 @@ var init_editFile = __esm({
|
|
|
2340
2257
|
new_string
|
|
2341
2258
|
);
|
|
2342
2259
|
}
|
|
2343
|
-
await
|
|
2260
|
+
await fs12.writeFile(input.path, updated, "utf-8");
|
|
2344
2261
|
return `Replaced ${occurrences.length} occurrence${occurrences.length > 1 ? "s" : ""} in ${input.path}
|
|
2345
2262
|
${unifiedDiff(input.path, content, updated)}`;
|
|
2346
2263
|
}
|
|
@@ -2351,7 +2268,7 @@ ${unifiedDiff(input.path, content, updated)}`;
|
|
|
2351
2268
|
old_string.length,
|
|
2352
2269
|
new_string
|
|
2353
2270
|
);
|
|
2354
|
-
await
|
|
2271
|
+
await fs12.writeFile(input.path, updated, "utf-8");
|
|
2355
2272
|
return `Updated ${input.path}
|
|
2356
2273
|
${unifiedDiff(input.path, content, updated)}`;
|
|
2357
2274
|
}
|
|
@@ -2367,7 +2284,7 @@ ${unifiedDiff(input.path, content, updated)}`;
|
|
|
2367
2284
|
flex.matchedText.length,
|
|
2368
2285
|
new_string
|
|
2369
2286
|
);
|
|
2370
|
-
await
|
|
2287
|
+
await fs12.writeFile(input.path, updated, "utf-8");
|
|
2371
2288
|
return `Updated ${input.path} (matched with flexible whitespace at line ${flex.line})
|
|
2372
2289
|
${unifiedDiff(input.path, content, updated)}`;
|
|
2373
2290
|
}
|
|
@@ -2598,10 +2515,10 @@ var init_glob = __esm({
|
|
|
2598
2515
|
});
|
|
2599
2516
|
|
|
2600
2517
|
// src/tools/code/listDir.ts
|
|
2601
|
-
import
|
|
2518
|
+
import fs13 from "fs/promises";
|
|
2602
2519
|
import path6 from "path";
|
|
2603
2520
|
async function readAndSort(dirPath) {
|
|
2604
|
-
const entries = await
|
|
2521
|
+
const entries = await fs13.readdir(dirPath, { withFileTypes: true });
|
|
2605
2522
|
return entries.filter((e) => !EXCLUDE.has(e.name)).sort((a, b) => {
|
|
2606
2523
|
if (a.isDirectory() && !b.isDirectory()) {
|
|
2607
2524
|
return -1;
|
|
@@ -2642,7 +2559,7 @@ function formatSize(bytes) {
|
|
|
2642
2559
|
}
|
|
2643
2560
|
async function formatFile(dirPath, name, indent) {
|
|
2644
2561
|
try {
|
|
2645
|
-
const stat = await
|
|
2562
|
+
const stat = await fs13.stat(path6.join(dirPath, name));
|
|
2646
2563
|
return `${indent}${name}${" ".repeat(Math.max(1, 30 - indent.length - name.length))}${formatSize(stat.size)}`;
|
|
2647
2564
|
} catch {
|
|
2648
2565
|
return `${indent}${name}`;
|
|
@@ -3301,7 +3218,7 @@ async function runSubAgent(config) {
|
|
|
3301
3218
|
const signal = background ? bgAbort.signal : parentSignal;
|
|
3302
3219
|
const agentName = subAgentId || "sub-agent";
|
|
3303
3220
|
const runStart = Date.now();
|
|
3304
|
-
|
|
3221
|
+
log5.info("Sub-agent started", { requestId, parentToolId, agentName });
|
|
3305
3222
|
const emit2 = (e) => {
|
|
3306
3223
|
onEvent({ ...e, parentToolId });
|
|
3307
3224
|
};
|
|
@@ -3475,7 +3392,7 @@ ${partial}` : "[INTERRUPTED] Agent was interrupted before producing output.",
|
|
|
3475
3392
|
...hasArtifacts ? { artifacts } : {}
|
|
3476
3393
|
};
|
|
3477
3394
|
}
|
|
3478
|
-
|
|
3395
|
+
log5.info("Tools executing", {
|
|
3479
3396
|
requestId,
|
|
3480
3397
|
parentToolId,
|
|
3481
3398
|
count: toolCalls.length,
|
|
@@ -3552,7 +3469,7 @@ ${partial}` : "[INTERRUPTED] Agent was interrupted before producing output.",
|
|
|
3552
3469
|
run2(tc.input);
|
|
3553
3470
|
const r = await resultPromise;
|
|
3554
3471
|
toolRegistry?.unregister(tc.id);
|
|
3555
|
-
|
|
3472
|
+
log5.info("Tool completed", {
|
|
3556
3473
|
requestId,
|
|
3557
3474
|
parentToolId,
|
|
3558
3475
|
toolCallId: tc.id,
|
|
@@ -3603,7 +3520,7 @@ ${partial}` : "[INTERRUPTED] Agent was interrupted before producing output.",
|
|
|
3603
3520
|
const wrapRun = async () => {
|
|
3604
3521
|
try {
|
|
3605
3522
|
const result = await run();
|
|
3606
|
-
|
|
3523
|
+
log5.info("Sub-agent complete", {
|
|
3607
3524
|
requestId,
|
|
3608
3525
|
parentToolId,
|
|
3609
3526
|
agentName,
|
|
@@ -3612,7 +3529,7 @@ ${partial}` : "[INTERRUPTED] Agent was interrupted before producing output.",
|
|
|
3612
3529
|
});
|
|
3613
3530
|
return result;
|
|
3614
3531
|
} catch (err) {
|
|
3615
|
-
|
|
3532
|
+
log5.warn("Sub-agent error", {
|
|
3616
3533
|
requestId,
|
|
3617
3534
|
parentToolId,
|
|
3618
3535
|
agentName,
|
|
@@ -3624,7 +3541,7 @@ ${partial}` : "[INTERRUPTED] Agent was interrupted before producing output.",
|
|
|
3624
3541
|
if (!background) {
|
|
3625
3542
|
return wrapRun();
|
|
3626
3543
|
}
|
|
3627
|
-
|
|
3544
|
+
log5.info("Sub-agent backgrounded", { requestId, parentToolId, agentName });
|
|
3628
3545
|
toolRegistry?.register({
|
|
3629
3546
|
id: parentToolId,
|
|
3630
3547
|
name: agentName,
|
|
@@ -3651,7 +3568,7 @@ ${partial}` : "[INTERRUPTED] Agent was interrupted before producing output.",
|
|
|
3651
3568
|
});
|
|
3652
3569
|
return { text: ack, messages: [], backgrounded: true };
|
|
3653
3570
|
}
|
|
3654
|
-
var
|
|
3571
|
+
var log5;
|
|
3655
3572
|
var init_runner = __esm({
|
|
3656
3573
|
"src/subagents/runner.ts"() {
|
|
3657
3574
|
"use strict";
|
|
@@ -3659,7 +3576,7 @@ var init_runner = __esm({
|
|
|
3659
3576
|
init_logger();
|
|
3660
3577
|
init_statusWatcher();
|
|
3661
3578
|
init_cleanMessages();
|
|
3662
|
-
|
|
3579
|
+
log5 = createLogger("sub-agent");
|
|
3663
3580
|
}
|
|
3664
3581
|
});
|
|
3665
3582
|
|
|
@@ -3803,10 +3720,10 @@ var init_tools = __esm({
|
|
|
3803
3720
|
});
|
|
3804
3721
|
|
|
3805
3722
|
// src/subagents/browserAutomation/prompt.ts
|
|
3806
|
-
import
|
|
3723
|
+
import fs14 from "fs";
|
|
3807
3724
|
function getBrowserAutomationPrompt() {
|
|
3808
3725
|
try {
|
|
3809
|
-
const appSpec =
|
|
3726
|
+
const appSpec = fs14.readFileSync("src/app.md", "utf-8").trim();
|
|
3810
3727
|
return `${BASE_PROMPT}
|
|
3811
3728
|
|
|
3812
3729
|
<!-- cache_breakpoint -->
|
|
@@ -3828,7 +3745,7 @@ var init_prompt2 = __esm({
|
|
|
3828
3745
|
});
|
|
3829
3746
|
|
|
3830
3747
|
// src/subagents/browserAutomation/index.ts
|
|
3831
|
-
var
|
|
3748
|
+
var log6, browserAutomationTool;
|
|
3832
3749
|
var init_browserAutomation = __esm({
|
|
3833
3750
|
"src/subagents/browserAutomation/index.ts"() {
|
|
3834
3751
|
"use strict";
|
|
@@ -3840,7 +3757,7 @@ var init_browserAutomation = __esm({
|
|
|
3840
3757
|
init_screenshot();
|
|
3841
3758
|
init_runCli();
|
|
3842
3759
|
init_logger();
|
|
3843
|
-
|
|
3760
|
+
log6 = createLogger("browser-automation");
|
|
3844
3761
|
browserAutomationTool = {
|
|
3845
3762
|
clearable: true,
|
|
3846
3763
|
definition: {
|
|
@@ -3946,7 +3863,7 @@ var init_browserAutomation = __esm({
|
|
|
3946
3863
|
}
|
|
3947
3864
|
}
|
|
3948
3865
|
} catch {
|
|
3949
|
-
|
|
3866
|
+
log6.debug("Failed to parse batch analysis result", {
|
|
3950
3867
|
batchResult
|
|
3951
3868
|
});
|
|
3952
3869
|
}
|
|
@@ -4770,12 +4687,12 @@ var init_tools3 = __esm({
|
|
|
4770
4687
|
});
|
|
4771
4688
|
|
|
4772
4689
|
// src/subagents/common/context.ts
|
|
4773
|
-
import
|
|
4690
|
+
import fs15 from "fs";
|
|
4774
4691
|
import path7 from "path";
|
|
4775
4692
|
function walkMdFiles2(dir, skip) {
|
|
4776
4693
|
const files = [];
|
|
4777
4694
|
try {
|
|
4778
|
-
for (const entry of
|
|
4695
|
+
for (const entry of fs15.readdirSync(dir, { withFileTypes: true })) {
|
|
4779
4696
|
const full = path7.join(dir, entry.name);
|
|
4780
4697
|
if (entry.isDirectory()) {
|
|
4781
4698
|
if (!skip?.has(entry.name)) {
|
|
@@ -4791,7 +4708,7 @@ function walkMdFiles2(dir, skip) {
|
|
|
4791
4708
|
}
|
|
4792
4709
|
function parseFrontmatter2(filePath) {
|
|
4793
4710
|
try {
|
|
4794
|
-
const content =
|
|
4711
|
+
const content = fs15.readFileSync(filePath, "utf-8");
|
|
4795
4712
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
4796
4713
|
if (!match) {
|
|
4797
4714
|
return {};
|
|
@@ -4837,7 +4754,7 @@ function loadRoadmapIndex() {
|
|
|
4837
4754
|
const parts = [];
|
|
4838
4755
|
try {
|
|
4839
4756
|
const indexJson = JSON.parse(
|
|
4840
|
-
|
|
4757
|
+
fs15.readFileSync("src/roadmap/index.json", "utf-8")
|
|
4841
4758
|
);
|
|
4842
4759
|
if (indexJson.lanes?.length > 0) {
|
|
4843
4760
|
const laneLines = indexJson.lanes.map(
|
|
@@ -4945,7 +4862,7 @@ var init_context = __esm({
|
|
|
4945
4862
|
});
|
|
4946
4863
|
|
|
4947
4864
|
// src/subagents/designExpert/data/sampleCache.ts
|
|
4948
|
-
import
|
|
4865
|
+
import fs16 from "fs";
|
|
4949
4866
|
function generateIndices(poolSize, sampleSize) {
|
|
4950
4867
|
const n = Math.min(sampleSize, poolSize);
|
|
4951
4868
|
const indices = Array.from({ length: poolSize }, (_, i) => i);
|
|
@@ -4957,14 +4874,14 @@ function generateIndices(poolSize, sampleSize) {
|
|
|
4957
4874
|
}
|
|
4958
4875
|
function load() {
|
|
4959
4876
|
try {
|
|
4960
|
-
return JSON.parse(
|
|
4877
|
+
return JSON.parse(fs16.readFileSync(SAMPLE_FILE, "utf-8"));
|
|
4961
4878
|
} catch {
|
|
4962
4879
|
return null;
|
|
4963
4880
|
}
|
|
4964
4881
|
}
|
|
4965
4882
|
function save(indices) {
|
|
4966
4883
|
try {
|
|
4967
|
-
|
|
4884
|
+
fs16.writeFileSync(SAMPLE_FILE, JSON.stringify(indices));
|
|
4968
4885
|
} catch {
|
|
4969
4886
|
}
|
|
4970
4887
|
}
|
|
@@ -5361,7 +5278,7 @@ var init_tools4 = __esm({
|
|
|
5361
5278
|
});
|
|
5362
5279
|
|
|
5363
5280
|
// src/subagents/productVision/executor.ts
|
|
5364
|
-
import
|
|
5281
|
+
import fs17 from "fs";
|
|
5365
5282
|
import path8 from "path";
|
|
5366
5283
|
function resolve(filePath) {
|
|
5367
5284
|
return path8.join(ROADMAP_DIR, filePath);
|
|
@@ -5371,13 +5288,13 @@ async function executeVisionTool(name, input, context) {
|
|
|
5371
5288
|
case "writeFile": {
|
|
5372
5289
|
const filePath = resolve(input.path);
|
|
5373
5290
|
try {
|
|
5374
|
-
|
|
5291
|
+
fs17.mkdirSync(ROADMAP_DIR, { recursive: true });
|
|
5375
5292
|
let oldContent = null;
|
|
5376
5293
|
try {
|
|
5377
|
-
oldContent =
|
|
5294
|
+
oldContent = fs17.readFileSync(filePath, "utf-8");
|
|
5378
5295
|
} catch {
|
|
5379
5296
|
}
|
|
5380
|
-
|
|
5297
|
+
fs17.writeFileSync(filePath, input.content, "utf-8");
|
|
5381
5298
|
const lineCount = input.content.split("\n").length;
|
|
5382
5299
|
const label = oldContent !== null ? "Wrote" : "Created";
|
|
5383
5300
|
return `${label} ${filePath} (${lineCount} lines)
|
|
@@ -5389,11 +5306,11 @@ ${unifiedDiff(filePath, oldContent ?? "", input.content)}`;
|
|
|
5389
5306
|
case "deleteFile": {
|
|
5390
5307
|
const filePath = resolve(input.path);
|
|
5391
5308
|
try {
|
|
5392
|
-
if (!
|
|
5309
|
+
if (!fs17.existsSync(filePath)) {
|
|
5393
5310
|
return `Error: ${filePath} does not exist`;
|
|
5394
5311
|
}
|
|
5395
|
-
const oldContent =
|
|
5396
|
-
|
|
5312
|
+
const oldContent = fs17.readFileSync(filePath, "utf-8");
|
|
5313
|
+
fs17.unlinkSync(filePath);
|
|
5397
5314
|
return `Deleted ${filePath}
|
|
5398
5315
|
${unifiedDiff(filePath, oldContent, "")}`;
|
|
5399
5316
|
} catch (err) {
|
|
@@ -5406,8 +5323,8 @@ ${unifiedDiff(filePath, oldContent, "")}`;
|
|
|
5406
5323
|
}
|
|
5407
5324
|
const filePath = resolve("pitch.html");
|
|
5408
5325
|
try {
|
|
5409
|
-
|
|
5410
|
-
const existing =
|
|
5326
|
+
fs17.mkdirSync(ROADMAP_DIR, { recursive: true });
|
|
5327
|
+
const existing = fs17.existsSync(filePath) ? fs17.readFileSync(filePath, "utf-8").trim() : "";
|
|
5411
5328
|
const currentDeck = existing || PITCH_DECK_SHELL;
|
|
5412
5329
|
const task = `
|
|
5413
5330
|
<pitch_content>${input.task}</pitch_content>
|
|
@@ -5432,7 +5349,7 @@ Respond only with the complete HTML file and absolutely no other text. Your resp
|
|
|
5432
5349
|
/```(?:html|wireframe)\n([\s\S]*?)```/
|
|
5433
5350
|
);
|
|
5434
5351
|
const html = htmlMatch ? htmlMatch[1].trim() : result;
|
|
5435
|
-
|
|
5352
|
+
fs17.writeFileSync(filePath, html, "utf-8");
|
|
5436
5353
|
return `Pitch deck written successfully.`;
|
|
5437
5354
|
} catch (err) {
|
|
5438
5355
|
return `Error generating pitch deck: ${err.message}`;
|
|
@@ -5818,6 +5735,86 @@ var init_tools6 = __esm({
|
|
|
5818
5735
|
}
|
|
5819
5736
|
});
|
|
5820
5737
|
|
|
5738
|
+
// src/session.ts
|
|
5739
|
+
import fs18 from "fs";
|
|
5740
|
+
function loadSession(state) {
|
|
5741
|
+
try {
|
|
5742
|
+
const raw = fs18.readFileSync(SESSION_FILE, "utf-8");
|
|
5743
|
+
const data = JSON.parse(raw);
|
|
5744
|
+
if (Array.isArray(data.messages) && data.messages.length > 0) {
|
|
5745
|
+
state.messages = sanitizeMessages(data.messages);
|
|
5746
|
+
log7.info("Session loaded", { messageCount: state.messages.length });
|
|
5747
|
+
return true;
|
|
5748
|
+
}
|
|
5749
|
+
} catch {
|
|
5750
|
+
}
|
|
5751
|
+
return false;
|
|
5752
|
+
}
|
|
5753
|
+
function sanitizeMessages(messages) {
|
|
5754
|
+
const result = [];
|
|
5755
|
+
for (let i = 0; i < messages.length; i++) {
|
|
5756
|
+
result.push(messages[i]);
|
|
5757
|
+
const msg = messages[i];
|
|
5758
|
+
if (msg.role !== "assistant" || !Array.isArray(msg.content)) {
|
|
5759
|
+
continue;
|
|
5760
|
+
}
|
|
5761
|
+
const toolBlocks = msg.content.filter(
|
|
5762
|
+
(b) => b.type === "tool"
|
|
5763
|
+
);
|
|
5764
|
+
if (toolBlocks.length === 0) {
|
|
5765
|
+
continue;
|
|
5766
|
+
}
|
|
5767
|
+
const resultIds = /* @__PURE__ */ new Set();
|
|
5768
|
+
for (let j = i + 1; j < messages.length; j++) {
|
|
5769
|
+
const next = messages[j];
|
|
5770
|
+
if (next.role === "user" && next.toolCallId) {
|
|
5771
|
+
resultIds.add(next.toolCallId);
|
|
5772
|
+
} else {
|
|
5773
|
+
break;
|
|
5774
|
+
}
|
|
5775
|
+
}
|
|
5776
|
+
for (const tc of toolBlocks) {
|
|
5777
|
+
if (!resultIds.has(tc.id)) {
|
|
5778
|
+
result.push({
|
|
5779
|
+
role: "user",
|
|
5780
|
+
content: "Error: tool result lost (session recovered)",
|
|
5781
|
+
toolCallId: tc.id,
|
|
5782
|
+
isToolError: true
|
|
5783
|
+
});
|
|
5784
|
+
}
|
|
5785
|
+
}
|
|
5786
|
+
}
|
|
5787
|
+
return result;
|
|
5788
|
+
}
|
|
5789
|
+
function saveSession(state) {
|
|
5790
|
+
try {
|
|
5791
|
+
fs18.writeFileSync(
|
|
5792
|
+
SESSION_FILE,
|
|
5793
|
+
JSON.stringify({ messages: state.messages }, null, 2),
|
|
5794
|
+
"utf-8"
|
|
5795
|
+
);
|
|
5796
|
+
log7.info("Session saved", { messageCount: state.messages.length });
|
|
5797
|
+
} catch (err) {
|
|
5798
|
+
log7.warn("Session save failed", { error: err.message });
|
|
5799
|
+
}
|
|
5800
|
+
}
|
|
5801
|
+
function clearSession(state) {
|
|
5802
|
+
state.messages = [];
|
|
5803
|
+
try {
|
|
5804
|
+
fs18.unlinkSync(SESSION_FILE);
|
|
5805
|
+
} catch {
|
|
5806
|
+
}
|
|
5807
|
+
}
|
|
5808
|
+
var log7, SESSION_FILE;
|
|
5809
|
+
var init_session = __esm({
|
|
5810
|
+
"src/session.ts"() {
|
|
5811
|
+
"use strict";
|
|
5812
|
+
init_logger();
|
|
5813
|
+
log7 = createLogger("session");
|
|
5814
|
+
SESSION_FILE = ".remy-session.json";
|
|
5815
|
+
}
|
|
5816
|
+
});
|
|
5817
|
+
|
|
5821
5818
|
// src/parsePartialJson.ts
|
|
5822
5819
|
function parsePartialJson(jsonString) {
|
|
5823
5820
|
const length = jsonString.length;
|
|
@@ -6842,6 +6839,15 @@ ${xmlParts}
|
|
|
6842
6839
|
}
|
|
6843
6840
|
}
|
|
6844
6841
|
}
|
|
6842
|
+
function applyPendingSummaries() {
|
|
6843
|
+
const summaries = getPendingSummaries();
|
|
6844
|
+
if (summaries.length === 0) {
|
|
6845
|
+
return;
|
|
6846
|
+
}
|
|
6847
|
+
const idx = findSafeInsertionPoint(state.messages);
|
|
6848
|
+
state.messages.splice(idx, 0, ...summaries);
|
|
6849
|
+
saveSession(state);
|
|
6850
|
+
}
|
|
6845
6851
|
function onBackgroundComplete(toolCallId, name, result, subAgentMessages) {
|
|
6846
6852
|
pendingBlockUpdates.push({ toolCallId, result, subAgentMessages });
|
|
6847
6853
|
log11.info("Background complete", {
|
|
@@ -6923,6 +6929,7 @@ ${xmlParts}
|
|
|
6923
6929
|
rid
|
|
6924
6930
|
);
|
|
6925
6931
|
setTimeout(() => {
|
|
6932
|
+
applyPendingSummaries();
|
|
6926
6933
|
applyPendingBlockUpdates();
|
|
6927
6934
|
flushBackgroundQueue();
|
|
6928
6935
|
}, 0);
|
|
@@ -7234,7 +7241,10 @@ ${xmlParts}
|
|
|
7234
7241
|
} catch {
|
|
7235
7242
|
}
|
|
7236
7243
|
},
|
|
7237
|
-
|
|
7244
|
+
onSummariesReady: () => {
|
|
7245
|
+
if (!running) {
|
|
7246
|
+
applyPendingSummaries();
|
|
7247
|
+
}
|
|
7238
7248
|
emit("compaction_complete", {}, requestId);
|
|
7239
7249
|
emit("completed", { success: true }, requestId);
|
|
7240
7250
|
},
|
|
@@ -7287,6 +7297,7 @@ var init_headless = __esm({
|
|
|
7287
7297
|
init_config();
|
|
7288
7298
|
init_prompt();
|
|
7289
7299
|
init_trigger();
|
|
7300
|
+
init_compaction();
|
|
7290
7301
|
init_lsp();
|
|
7291
7302
|
init_agent();
|
|
7292
7303
|
init_session();
|