buildwithnexus 0.7.3 → 0.8.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.
Files changed (2) hide show
  1. package/dist/bin.js +110 -41
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -918,7 +918,7 @@ async function startBackend() {
918
918
  const path11 = await import("path");
919
919
  const nexusDir = path11.join(os5.homedir(), "Projects", "nexus");
920
920
  log.step(`Starting Nexus backend from ${nexusDir}...`);
921
- const child = spawn2("python", ["-m", "src.deep_agents_server"], {
921
+ const child = spawn2("python3", ["-m", "src.deep_agents_server"], {
922
922
  cwd: nexusDir,
923
923
  detached: true,
924
924
  stdio: "ignore",
@@ -1593,7 +1593,7 @@ init_secrets();
1593
1593
  init_docker();
1594
1594
 
1595
1595
  // src/core/version.ts
1596
- var resolvedVersion = true ? "0.7.3" : pkg.version;
1596
+ var resolvedVersion = true ? "0.8.0" : pkg.version;
1597
1597
 
1598
1598
  // src/cli/interactive.ts
1599
1599
  var appVersion = resolvedVersion;
@@ -1771,9 +1771,30 @@ async function planModeLoop(task, backendUrl, ask) {
1771
1771
  console.error(chalk3.red("Backend error \u2014 cannot fetch plan."));
1772
1772
  return "cancel";
1773
1773
  }
1774
- const { run_id } = await response.json();
1774
+ const planText = await response.text();
1775
+ let planParsed;
1776
+ try {
1777
+ planParsed = JSON.parse(planText);
1778
+ } catch {
1779
+ console.error(chalk3.red(`Backend returned invalid JSON: ${planText.slice(0, 200)}`));
1780
+ return "cancel";
1781
+ }
1782
+ const { run_id: planRunId } = planParsed;
1783
+ if (!planRunId || typeof planRunId !== "string") {
1784
+ console.error(chalk3.red("Backend did not return a valid run ID"));
1785
+ return "cancel";
1786
+ }
1787
+ if (!/^[a-zA-Z0-9_-]+$/.test(planRunId)) {
1788
+ console.error(chalk3.red("Backend returned run ID with invalid characters"));
1789
+ return "cancel";
1790
+ }
1791
+ const run_id = planRunId;
1775
1792
  tui.displayConnected(run_id);
1776
1793
  const streamResponse = await fetch(`${backendUrl}/api/stream/${run_id}`, { signal: AbortSignal.timeout(12e4) });
1794
+ if (!streamResponse.ok) {
1795
+ console.error(chalk3.red(`Stream endpoint returned ${streamResponse.status}`));
1796
+ return "cancel";
1797
+ }
1777
1798
  const reader = streamResponse.body?.getReader();
1778
1799
  if (!reader) throw new Error("No response body");
1779
1800
  let planReceived = false;
@@ -1861,11 +1882,32 @@ async function buildModeLoop(task, backendUrl, ask) {
1861
1882
  console.error(chalk3.red("Backend error"));
1862
1883
  return "done";
1863
1884
  }
1864
- const { run_id } = await response.json();
1885
+ const buildText = await response.text();
1886
+ let buildParsed;
1887
+ try {
1888
+ buildParsed = JSON.parse(buildText);
1889
+ } catch {
1890
+ console.error(chalk3.red(`Backend returned invalid JSON: ${buildText.slice(0, 200)}`));
1891
+ return "done";
1892
+ }
1893
+ const { run_id: buildRunId } = buildParsed;
1894
+ if (!buildRunId || typeof buildRunId !== "string") {
1895
+ console.error(chalk3.red("Backend did not return a valid run ID"));
1896
+ return "done";
1897
+ }
1898
+ if (!/^[a-zA-Z0-9_-]+$/.test(buildRunId)) {
1899
+ console.error(chalk3.red("Backend returned run ID with invalid characters"));
1900
+ return "done";
1901
+ }
1902
+ const run_id = buildRunId;
1865
1903
  tui.displayConnected(run_id);
1866
1904
  console.log(chalk3.bold.green("\u2699\uFE0F Executing..."));
1867
1905
  tui.displayStreamStart();
1868
1906
  const streamResponse = await fetch(`${backendUrl}/api/stream/${run_id}`, { signal: AbortSignal.timeout(12e4) });
1907
+ if (!streamResponse.ok) {
1908
+ console.error(chalk3.red(`Stream endpoint returned ${streamResponse.status}`));
1909
+ return "done";
1910
+ }
1869
1911
  const reader = streamResponse.body?.getReader();
1870
1912
  if (!reader) throw new Error("No response body");
1871
1913
  for await (const parsed of parseSSEStream(reader)) {
@@ -1918,43 +1960,66 @@ async function brainstormModeLoop(task, backendUrl, ask) {
1918
1960
  signal: AbortSignal.timeout(12e4)
1919
1961
  });
1920
1962
  if (response.ok) {
1921
- const { run_id } = await response.json();
1963
+ const brainstormText = await response.text();
1964
+ let brainstormParsed;
1965
+ try {
1966
+ brainstormParsed = JSON.parse(brainstormText);
1967
+ } catch {
1968
+ console.error(chalk3.red(`Backend returned invalid JSON: ${brainstormText.slice(0, 200)}`));
1969
+ continue;
1970
+ }
1971
+ const { run_id: brainstormRunId } = brainstormParsed;
1972
+ if (!brainstormRunId || typeof brainstormRunId !== "string") {
1973
+ console.error(chalk3.red("Backend did not return a valid run ID"));
1974
+ continue;
1975
+ }
1976
+ if (!/^[a-zA-Z0-9_-]+$/.test(brainstormRunId)) {
1977
+ console.error(chalk3.red("Backend returned run ID with invalid characters"));
1978
+ continue;
1979
+ }
1980
+ const run_id = brainstormRunId;
1922
1981
  const streamResponse = await fetch(`${backendUrl}/api/stream/${run_id}`, { signal: AbortSignal.timeout(12e4) });
1982
+ if (!streamResponse.ok) {
1983
+ console.error(chalk3.red(`Stream endpoint returned ${streamResponse.status}`));
1984
+ continue;
1985
+ }
1923
1986
  const reader = streamResponse.body?.getReader();
1924
- if (reader) {
1925
- let responseText = "";
1926
- for await (const parsed of parseSSEStream(reader)) {
1927
- const type = parsed.type;
1928
- const data = parsed.data;
1929
- if (type === "done" || type === "execution_complete") {
1930
- const summary = data["summary"] || "";
1931
- if (summary) responseText = summary;
1932
- break;
1933
- } else if (type === "error") {
1934
- const errorMsg = data["error"] || data["content"] || "Unknown error";
1935
- responseText += errorMsg + "\n";
1936
- break;
1937
- } else if (type === "thought" || type === "observation") {
1938
- const content = data["content"] || "";
1939
- if (content) responseText += content + "\n";
1940
- } else if (type === "agent_response" || type === "agent_result") {
1941
- const content = data["content"] || data["result"] || "";
1942
- if (content) responseText += content + "\n";
1943
- } else if (type === "action") {
1944
- const content = data["content"] || "";
1945
- if (content) responseText += content + "\n";
1946
- } else if (type === "agent_working") {
1947
- } else if (type !== "plan") {
1948
- const content = data["content"] || data["response"] || "";
1949
- if (content) responseText += content + "\n";
1950
- }
1951
- }
1952
- if (responseText.trim()) {
1953
- tui.displayBrainstormResponse(responseText.trim());
1954
- } else {
1955
- console.log(chalk3.gray("(No response received from agent)"));
1987
+ if (!reader) {
1988
+ console.error(chalk3.red("No response body from agent"));
1989
+ continue;
1990
+ }
1991
+ let responseText = "";
1992
+ for await (const parsed of parseSSEStream(reader)) {
1993
+ const type = parsed.type;
1994
+ const data = parsed.data;
1995
+ if (type === "done" || type === "execution_complete" || type === "final_result") {
1996
+ const summary = data["summary"] || data["result"] || "";
1997
+ if (summary) responseText = summary;
1998
+ break;
1999
+ } else if (type === "error") {
2000
+ const errorMsg = data["error"] || data["content"] || "Unknown error";
2001
+ responseText += errorMsg + "\n";
2002
+ break;
2003
+ } else if (type === "thought" || type === "observation") {
2004
+ const content = data["content"] || "";
2005
+ if (content) responseText += content + "\n";
2006
+ } else if (type === "agent_response" || type === "agent_result") {
2007
+ const content = data["content"] || data["result"] || "";
2008
+ if (content) responseText += content + "\n";
2009
+ } else if (type === "action") {
2010
+ const content = data["content"] || "";
2011
+ if (content) responseText += content + "\n";
2012
+ } else if (type === "agent_working" || type === "started") {
2013
+ } else if (type !== "plan") {
2014
+ const content = data["content"] || data["response"] || "";
2015
+ if (content) responseText += content + "\n";
1956
2016
  }
1957
2017
  }
2018
+ if (responseText.trim()) {
2019
+ tui.displayBrainstormResponse(responseText.trim());
2020
+ } else {
2021
+ console.log(chalk3.gray("(No response received from agent)"));
2022
+ }
1958
2023
  } else {
1959
2024
  console.log(chalk3.red("Could not reach backend for brainstorm response."));
1960
2025
  }
@@ -2280,11 +2345,11 @@ var phases = [
2280
2345
  await withSpinner(
2281
2346
  spinner,
2282
2347
  "Installing cloudflared...",
2283
- () => installCloudflared(config.httpPort, platform.arch)
2348
+ () => installCloudflared(platform.arch)
2284
2349
  );
2285
2350
  spinner.text = "Starting tunnel...";
2286
2351
  spinner.start();
2287
- const url = await startTunnel(config.httpPort);
2352
+ const url = await startTunnel();
2288
2353
  if (url) {
2289
2354
  ctx.tunnelUrl = url;
2290
2355
  succeed(spinner, `Tunnel active: ${url}`);
@@ -2354,9 +2419,13 @@ var startCommand = new Command3("start").description("Start the NEXUS runtime").
2354
2419
  log.success("NEXUS is already running");
2355
2420
  return;
2356
2421
  }
2357
- let spinner = createSpinner("Pulling NEXUS image...");
2422
+ let spinner = createSpinner("Checking NEXUS image...");
2358
2423
  spinner.start();
2359
- await pullImage("buildwithnexus/nexus", "latest");
2424
+ const localExists = await imageExistsLocally("buildwithnexus/nexus", "latest");
2425
+ if (!localExists) {
2426
+ spinner.text = "Pulling NEXUS image...";
2427
+ await pullImage("buildwithnexus/nexus", "latest");
2428
+ }
2360
2429
  succeed(spinner, "Image ready");
2361
2430
  const keys = loadKeys();
2362
2431
  if (!keys) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "buildwithnexus",
3
- "version": "0.7.3",
3
+ "version": "0.8.0",
4
4
  "description": "Interactive AI agent orchestrator with intent-based planning, execution, and brainstorming modes",
5
5
  "type": "module",
6
6
  "bin": {