buildwithnexus 0.8.7 → 0.8.8
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/bin.js +118 -72
- package/dist/nexus-release.tar.gz +0 -0
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -1605,10 +1605,25 @@ init_secrets();
|
|
|
1605
1605
|
init_docker();
|
|
1606
1606
|
|
|
1607
1607
|
// src/core/version.ts
|
|
1608
|
-
var resolvedVersion = true ? "0.8.
|
|
1608
|
+
var resolvedVersion = true ? "0.8.8" : pkg.version;
|
|
1609
1609
|
|
|
1610
1610
|
// src/cli/interactive.ts
|
|
1611
1611
|
var appVersion = resolvedVersion;
|
|
1612
|
+
var SSE_STALL_WARNING_MS = 8e3;
|
|
1613
|
+
async function reportBackendError(label, response) {
|
|
1614
|
+
let bodySnippet = "";
|
|
1615
|
+
try {
|
|
1616
|
+
const text = await response.text();
|
|
1617
|
+
bodySnippet = text.slice(0, 300);
|
|
1618
|
+
} catch {
|
|
1619
|
+
bodySnippet = "(could not read response body)";
|
|
1620
|
+
}
|
|
1621
|
+
console.error(chalk3.red(`${label}: HTTP ${response.status} ${response.statusText}`));
|
|
1622
|
+
if (bodySnippet) {
|
|
1623
|
+
console.error(chalk3.gray(` body: ${bodySnippet}`));
|
|
1624
|
+
}
|
|
1625
|
+
console.error(chalk3.gray(" Tip: stream backend logs with `buildwithnexus logs -f`"));
|
|
1626
|
+
}
|
|
1612
1627
|
async function interactiveMode() {
|
|
1613
1628
|
const backendUrl = process.env.BACKEND_URL || "http://localhost:4200";
|
|
1614
1629
|
const urlCheck = validateBackendUrl(backendUrl);
|
|
@@ -1782,7 +1797,7 @@ async function planModeLoop(task, backendUrl, currentMode, ask) {
|
|
|
1782
1797
|
signal: AbortSignal.timeout(12e4)
|
|
1783
1798
|
});
|
|
1784
1799
|
if (!response.ok) {
|
|
1785
|
-
|
|
1800
|
+
await reportBackendError("Backend error fetching plan", response);
|
|
1786
1801
|
return "cancel";
|
|
1787
1802
|
}
|
|
1788
1803
|
const planText = await response.text();
|
|
@@ -1806,27 +1821,36 @@ async function planModeLoop(task, backendUrl, currentMode, ask) {
|
|
|
1806
1821
|
tui.displayConnected(run_id);
|
|
1807
1822
|
const streamResponse = await fetch(`${backendUrl}/api/stream/${run_id}`, { signal: AbortSignal.timeout(12e4) });
|
|
1808
1823
|
if (!streamResponse.ok) {
|
|
1809
|
-
|
|
1824
|
+
await reportBackendError("Stream endpoint error", streamResponse);
|
|
1810
1825
|
return "cancel";
|
|
1811
1826
|
}
|
|
1812
1827
|
const reader = streamResponse.body?.getReader();
|
|
1813
1828
|
if (!reader) throw new Error("No response body");
|
|
1814
1829
|
let planReceived = false;
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1830
|
+
const stallTimer = setTimeout(() => {
|
|
1831
|
+
console.log(chalk3.gray(`(no events from backend after ${SSE_STALL_WARNING_MS / 1e3}s \u2014 backend may be stalled; check \`buildwithnexus logs -f\`)`));
|
|
1832
|
+
}, SSE_STALL_WARNING_MS);
|
|
1833
|
+
try {
|
|
1834
|
+
for await (const parsed of parseSSEStream(reader)) {
|
|
1835
|
+
if (parsed.type === "plan") {
|
|
1836
|
+
steps = parsed.data["steps"] || [];
|
|
1837
|
+
planReceived = true;
|
|
1838
|
+
reader.cancel();
|
|
1839
|
+
break;
|
|
1840
|
+
} else if (parsed.type === "error") {
|
|
1841
|
+
const errorMsg = parsed.data["error"] || parsed.data["content"] || "Unknown error";
|
|
1842
|
+
tui.displayError(errorMsg);
|
|
1843
|
+
reader.cancel();
|
|
1844
|
+
return "cancel";
|
|
1845
|
+
}
|
|
1826
1846
|
}
|
|
1847
|
+
} finally {
|
|
1848
|
+
clearTimeout(stallTimer);
|
|
1827
1849
|
}
|
|
1828
1850
|
if (!planReceived || steps.length === 0) {
|
|
1829
1851
|
console.log(chalk3.yellow("No plan received from backend."));
|
|
1852
|
+
console.log(chalk3.gray(" This usually means the backend exited without emitting a plan event."));
|
|
1853
|
+
console.log(chalk3.gray(" Check `buildwithnexus logs -f` for the underlying error."));
|
|
1830
1854
|
steps = ["(no steps returned \u2014 execute anyway?)"];
|
|
1831
1855
|
}
|
|
1832
1856
|
} catch (err) {
|
|
@@ -1841,7 +1865,7 @@ async function planModeLoop(task, backendUrl, currentMode, ask) {
|
|
|
1841
1865
|
if (answer === "" || answer === "y") {
|
|
1842
1866
|
return "BUILD";
|
|
1843
1867
|
}
|
|
1844
|
-
if (answer === "n" || answer === "
|
|
1868
|
+
if (answer === "n" || answer === "") {
|
|
1845
1869
|
console.log(chalk3.yellow("\nExecution cancelled.\n"));
|
|
1846
1870
|
return "cancel";
|
|
1847
1871
|
}
|
|
@@ -1893,7 +1917,7 @@ async function buildModeLoop(task, backendUrl, currentMode, ask) {
|
|
|
1893
1917
|
signal: AbortSignal.timeout(12e4)
|
|
1894
1918
|
});
|
|
1895
1919
|
if (!response.ok) {
|
|
1896
|
-
|
|
1920
|
+
await reportBackendError("Backend error starting run", response);
|
|
1897
1921
|
return "done";
|
|
1898
1922
|
}
|
|
1899
1923
|
const buildText = await response.text();
|
|
@@ -1919,30 +1943,45 @@ async function buildModeLoop(task, backendUrl, currentMode, ask) {
|
|
|
1919
1943
|
tui.displayStreamStart();
|
|
1920
1944
|
const streamResponse = await fetch(`${backendUrl}/api/stream/${run_id}`, { signal: AbortSignal.timeout(12e4) });
|
|
1921
1945
|
if (!streamResponse.ok) {
|
|
1922
|
-
|
|
1946
|
+
await reportBackendError("Stream endpoint error", streamResponse);
|
|
1923
1947
|
return "done";
|
|
1924
1948
|
}
|
|
1925
1949
|
const reader = streamResponse.body?.getReader();
|
|
1926
1950
|
if (!reader) throw new Error("No response body");
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1951
|
+
let sawTerminal = false;
|
|
1952
|
+
const stallTimer = setTimeout(() => {
|
|
1953
|
+
console.log(chalk3.gray(`(no events from backend after ${SSE_STALL_WARNING_MS / 1e3}s \u2014 backend may be stalled; check \`buildwithnexus logs -f\`)`));
|
|
1954
|
+
}, SSE_STALL_WARNING_MS);
|
|
1955
|
+
try {
|
|
1956
|
+
for await (const parsed of parseSSEStream(reader)) {
|
|
1957
|
+
const type = parsed.type;
|
|
1958
|
+
if (type === "execution_complete") {
|
|
1959
|
+
const summary = parsed.data["summary"] || "";
|
|
1960
|
+
const count = parsed.data["todos_completed"] || 0;
|
|
1961
|
+
tui.displayResults(summary, count);
|
|
1962
|
+
tui.displayComplete(tui.getElapsedTime());
|
|
1963
|
+
sawTerminal = true;
|
|
1964
|
+
break;
|
|
1965
|
+
} else if (type === "done") {
|
|
1966
|
+
tui.displayEvent(type, { content: "Task completed successfully" });
|
|
1967
|
+
tui.displayComplete(tui.getElapsedTime());
|
|
1968
|
+
sawTerminal = true;
|
|
1969
|
+
break;
|
|
1970
|
+
} else if (type === "error") {
|
|
1971
|
+
const errorMsg = parsed.data["error"] || parsed.data["content"] || "Unknown error";
|
|
1972
|
+
tui.displayError(errorMsg);
|
|
1973
|
+
sawTerminal = true;
|
|
1974
|
+
break;
|
|
1975
|
+
} else if (type !== "plan") {
|
|
1976
|
+
tui.displayEvent(type, parsed.data);
|
|
1977
|
+
}
|
|
1945
1978
|
}
|
|
1979
|
+
} finally {
|
|
1980
|
+
clearTimeout(stallTimer);
|
|
1981
|
+
}
|
|
1982
|
+
if (!sawTerminal) {
|
|
1983
|
+
console.log(chalk3.yellow("Stream ended without a terminal event (no execution_complete / done / error)."));
|
|
1984
|
+
console.log(chalk3.gray(" The backend likely crashed mid-run. Check `buildwithnexus logs -f`."));
|
|
1946
1985
|
}
|
|
1947
1986
|
} catch (err) {
|
|
1948
1987
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -1972,7 +2011,9 @@ async function brainstormModeLoop(task, backendUrl, currentMode, ask) {
|
|
|
1972
2011
|
)),
|
|
1973
2012
|
signal: AbortSignal.timeout(12e4)
|
|
1974
2013
|
});
|
|
1975
|
-
if (response.ok) {
|
|
2014
|
+
if (!response.ok) {
|
|
2015
|
+
await reportBackendError("Backend error in brainstorm", response);
|
|
2016
|
+
} else {
|
|
1976
2017
|
const brainstormText = await response.text();
|
|
1977
2018
|
let brainstormParsed;
|
|
1978
2019
|
try {
|
|
@@ -1993,7 +2034,7 @@ async function brainstormModeLoop(task, backendUrl, currentMode, ask) {
|
|
|
1993
2034
|
const run_id = brainstormRunId;
|
|
1994
2035
|
const streamResponse = await fetch(`${backendUrl}/api/stream/${run_id}`, { signal: AbortSignal.timeout(12e4) });
|
|
1995
2036
|
if (!streamResponse.ok) {
|
|
1996
|
-
|
|
2037
|
+
await reportBackendError("Stream endpoint error", streamResponse);
|
|
1997
2038
|
continue;
|
|
1998
2039
|
}
|
|
1999
2040
|
const reader = streamResponse.body?.getReader();
|
|
@@ -2003,50 +2044,55 @@ async function brainstormModeLoop(task, backendUrl, currentMode, ask) {
|
|
|
2003
2044
|
}
|
|
2004
2045
|
let responseText = "";
|
|
2005
2046
|
let firstEvent = true;
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
break;
|
|
2017
|
-
} else if (type === "error") {
|
|
2018
|
-
const errorMsg = data["error"] || data["content"] || "Unknown error";
|
|
2019
|
-
responseText += errorMsg + "\n";
|
|
2020
|
-
break;
|
|
2021
|
-
} else if (type === "thought" || type === "observation") {
|
|
2022
|
-
const content = data["content"] || "";
|
|
2023
|
-
if (content) {
|
|
2024
|
-
console.log(chalk3.gray("\u2192 " + content));
|
|
2025
|
-
responseText += content + "\n";
|
|
2047
|
+
const stallTimer = setTimeout(() => {
|
|
2048
|
+
console.log(chalk3.gray(`(no events from backend after ${SSE_STALL_WARNING_MS / 1e3}s \u2014 backend may be stalled; check \`buildwithnexus logs -f\`)`));
|
|
2049
|
+
}, SSE_STALL_WARNING_MS);
|
|
2050
|
+
try {
|
|
2051
|
+
for await (const parsed of parseSSEStream(reader)) {
|
|
2052
|
+
const type = parsed.type;
|
|
2053
|
+
const data = parsed.data;
|
|
2054
|
+
if (firstEvent && type !== "done" && type !== "error") {
|
|
2055
|
+
console.log(chalk3.bold.blue("\u{1F4AD} Thinking...\n"));
|
|
2056
|
+
firstEvent = false;
|
|
2026
2057
|
}
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2058
|
+
if (type === "done" || type === "execution_complete" || type === "final_result") {
|
|
2059
|
+
const summary = data["summary"] || data["result"] || "";
|
|
2060
|
+
if (summary) responseText = summary;
|
|
2061
|
+
break;
|
|
2062
|
+
} else if (type === "error") {
|
|
2063
|
+
const errorMsg = data["error"] || data["content"] || "Unknown error";
|
|
2064
|
+
responseText += errorMsg + "\n";
|
|
2065
|
+
break;
|
|
2066
|
+
} else if (type === "thought" || type === "observation") {
|
|
2067
|
+
const content = data["content"] || "";
|
|
2068
|
+
if (content) {
|
|
2069
|
+
console.log(chalk3.gray("\u2192 " + content));
|
|
2070
|
+
responseText += content + "\n";
|
|
2071
|
+
}
|
|
2072
|
+
} else if (type === "agent_response" || type === "agent_result") {
|
|
2073
|
+
const content = data["content"] || data["result"] || "";
|
|
2074
|
+
if (content) responseText += content + "\n";
|
|
2075
|
+
} else if (type === "action") {
|
|
2076
|
+
const content = data["content"] || "";
|
|
2077
|
+
if (content) {
|
|
2078
|
+
console.log(chalk3.cyan("\u2699\uFE0F " + content));
|
|
2079
|
+
responseText += content + "\n";
|
|
2080
|
+
}
|
|
2081
|
+
} else if (type === "agent_working" || type === "started") {
|
|
2082
|
+
} else if (type !== "plan") {
|
|
2083
|
+
const content = data["content"] || data["response"] || "";
|
|
2084
|
+
if (content) responseText += content + "\n";
|
|
2035
2085
|
}
|
|
2036
|
-
} else if (type === "agent_working" || type === "started") {
|
|
2037
|
-
} else if (type !== "plan") {
|
|
2038
|
-
const content = data["content"] || data["response"] || "";
|
|
2039
|
-
if (content) responseText += content + "\n";
|
|
2040
2086
|
}
|
|
2087
|
+
} finally {
|
|
2088
|
+
clearTimeout(stallTimer);
|
|
2041
2089
|
}
|
|
2042
2090
|
console.log("");
|
|
2043
2091
|
if (responseText.trim()) {
|
|
2044
2092
|
tui.displayBrainstormResponse(responseText.trim());
|
|
2045
2093
|
} else {
|
|
2046
|
-
console.log(chalk3.gray("(No response received from agent)"));
|
|
2094
|
+
console.log(chalk3.gray("(No response received from agent \u2014 check `buildwithnexus logs -f`)"));
|
|
2047
2095
|
}
|
|
2048
|
-
} else {
|
|
2049
|
-
console.log(chalk3.red("Could not reach backend for brainstorm response."));
|
|
2050
2096
|
}
|
|
2051
2097
|
} catch (err) {
|
|
2052
2098
|
const msg = err instanceof Error ? err.message : String(err);
|
|
Binary file
|