@bivy/bivy 0.10.1-staging.284 → 0.10.1-staging.285

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/bin/bivy.mjs +67 -6
  2. package/package.json +1 -1
package/bin/bivy.mjs CHANGED
@@ -922,9 +922,10 @@ async function resolveRunSpec(agentId, extraArgs) {
922
922
  return { spec: { agent: id, label: agent.label, command, args: [...(agent.args ?? []), ...extraArgs] } };
923
923
  }
924
924
 
925
- // Pull bivy's own `--name`/`--model` flags (space or `=` form) out of the run
926
- // args so they aren't blindly forwarded. Only honored before a `--` separator,
927
- // past which everything is the raw command the user asked to run.
925
+ // Pull bivy's own run flags out of the args so they aren't blindly forwarded.
926
+ // Only honored before a `--` separator, past which everything is the raw command
927
+ // the user asked to run. `--chat` selects the governed app-session path instead
928
+ // of the native PTY path; `--no-open` keeps that path headless after creation.
928
929
  // Does a token look like a git remote (URL, scp-style, owner/repo, or a path)
929
930
  // rather than an agent id? Lets `--clone <remote>` disambiguate from bare
930
931
  // `--clone` (= current folder's repo) without a required `=`.
@@ -936,10 +937,14 @@ function looksLikeRemote(value) {
936
937
  function extractRunFlags(args) {
937
938
  const rest = [];
938
939
  let name, model, node, workspace;
940
+ let chat = false;
941
+ let noOpen = false;
939
942
  let clone; // undefined = no clone; true = current repo; string = explicit remote
940
943
  for (let i = 0; i < args.length; i++) {
941
944
  const a = args[i];
942
945
  if (a === "--") { rest.push(...args.slice(i)); break; }
946
+ if (a === "--chat") { chat = true; continue; }
947
+ if (a === "--no-open") { noOpen = true; continue; }
943
948
  if (a === "--name" && args[i + 1] !== undefined) { name = args[++i]; continue; }
944
949
  if (a.startsWith("--name=")) { name = a.slice("--name=".length); continue; }
945
950
  if (a === "--model" && args[i + 1] !== undefined) { model = args[++i]; continue; }
@@ -952,7 +957,7 @@ function extractRunFlags(args) {
952
957
  if (a === "--clone") { clone = looksLikeRemote(args[i + 1]) ? args[++i] : true; continue; }
953
958
  rest.push(a);
954
959
  }
955
- return { name: name?.trim() || undefined, model: model?.trim() || undefined, node: node?.trim() || undefined, workspace: workspace?.trim() || undefined, clone, rest };
960
+ return { name: name?.trim() || undefined, model: model?.trim() || undefined, node: node?.trim() || undefined, workspace: workspace?.trim() || undefined, chat, noOpen, clone, rest };
956
961
  }
957
962
 
958
963
  // A safe-ish workspace dir name from a remote or path (basename minus .git).
@@ -1793,12 +1798,67 @@ complete -c bivy -n '__fish_seen_subcommand_from run' -a '${agents.join(" ")}'`)
1793
1798
  // flag on top of it.
1794
1799
  async function cmdRun(args = []) {
1795
1800
  if (!(await ensureDeps())) process.exit(1);
1796
- const { name, model, node, workspace, clone, rest } = extractRunFlags(args);
1801
+ const { name, model, node, workspace, chat, noOpen, clone, rest } = extractRunFlags(args);
1797
1802
  // Bare `bivy` (empty rest) resolves to the configured default agent; an
1798
1803
  // explicit `bivy run <agent>` keeps that agent verbatim.
1799
1804
  const [agentIdArg, ...extraArgs] = rest;
1800
1805
  const agentId = agentIdArg || resolveDefaultAgent();
1801
1806
 
1807
+ if (chat) {
1808
+ if (node) {
1809
+ console.error(c.red("--chat currently starts a governed session on this node; it can't be combined with --node."));
1810
+ process.exit(1);
1811
+ return;
1812
+ }
1813
+ if (agentId === "--" || extraArgs.length) {
1814
+ console.error(c.red("--chat starts a governed agent integration and does not accept native agent arguments or the raw '-- <command>' form."));
1815
+ process.exit(1);
1816
+ return;
1817
+ }
1818
+ let requestedWorkspace;
1819
+ try { requestedWorkspace = resolveWorkspaceDir({ clone, workspace }); }
1820
+ catch (error) { console.error(c.red(error?.message || String(error))); process.exit(1); return; }
1821
+ const config = loadConfig();
1822
+ // Preserve `bivy run`'s cwd contract: from inside a git checkout, a chat run
1823
+ // targets that checkout; elsewhere it uses the node's configured workspace.
1824
+ const sessionWorkspace = requestedWorkspace || defaultRunWorkspace(config);
1825
+ if (!(await ensureNodeRunning(config))) {
1826
+ console.error(c.red(`Could not start the Bivy node at ${url(config)}.`));
1827
+ process.exit(1);
1828
+ return;
1829
+ }
1830
+ try {
1831
+ const created = await localApi(config, "/api/session", {
1832
+ method: "POST",
1833
+ body: JSON.stringify({ agent: agentId, ...(model ? { model: { provider: "", id: model } } : {}), ...(sessionWorkspace ? { workspace: sessionWorkspace } : {}) }),
1834
+ });
1835
+ if (name) {
1836
+ await localApi(config, "/api/sessions/rename", {
1837
+ method: "POST",
1838
+ body: JSON.stringify({ sessionId: created.id, name }),
1839
+ });
1840
+ }
1841
+ const sessionPath = `/sessions/${encodeURIComponent(created.id)}`;
1842
+ const remote = await openRemoteApp({ open: !noOpen, remotePath: sessionPath });
1843
+ console.log(c.green(`Started chat session ${created.id} (${created.agentName || created.runtimeId || agentId}).`));
1844
+ if (remote && (noOpen || !canOpenBrowser())) console.log(`Open it in the Bivy app: ${c.cyan(remote.openUrl)}`);
1845
+ else if (!remote) {
1846
+ console.log(c.yellow("Remote app access is not configured on this node."));
1847
+ console.log(`Run ${c.cyan("bivy relay:setup")}, then open session ${c.cyan(created.id)} in the app.`);
1848
+ }
1849
+ return;
1850
+ } catch (error) {
1851
+ console.error(c.red(`Could not start chat session: ${error?.message || String(error)}`));
1852
+ process.exit(1);
1853
+ return;
1854
+ }
1855
+ }
1856
+ if (noOpen) {
1857
+ console.error(c.red("--no-open is only valid together with --chat."));
1858
+ process.exit(1);
1859
+ return;
1860
+ }
1861
+
1802
1862
  // A cloned/explicit workspace lives on THIS machine, so it only applies to the
1803
1863
  // local node. For a remote --node run the checkout would need to be made there.
1804
1864
  if (node && (clone !== undefined || workspace)) {
@@ -4573,9 +4633,10 @@ async function main() {
4573
4633
  // args (including its own --help) pass straight through to it — e.g.
4574
4634
  // 'bivy run claude --help' must show Claude's help, not bivy's.
4575
4635
  if (args[0] === "-h" || args[0] === "--help") {
4576
- console.log(`Usage: bivy run <agent> [--name <label>] [--model <model>] [--node <name>] [--clone [remote]] [--workspace <dir>] | -- <command>
4636
+ console.log(`Usage: bivy run <agent> [--chat [--no-open]] [--name <label>] [--model <model>] [--node <name>] [--clone [remote]] [--workspace <dir>] | -- <command>
4577
4637
 
4578
4638
  Run a native agent (real CLI/TUI) as a relay-visible session.
4639
+ Use --chat to start the governed session used by the app instead; --no-open prints its URL without launching a browser.
4579
4640
  Agents: ${[...AGENT_INTEGRATIONS.keys()].join(", ")}, or -- <command> for anything else.
4580
4641
  An agent's own --help passes through, e.g. 'bivy run claude --help'.`);
4581
4642
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bivy/bivy",
3
- "version": "0.10.1-staging.284",
3
+ "version": "0.10.1-staging.285",
4
4
  "type": "module",
5
5
  "license": "AGPL-3.0-only",
6
6
  "description": "Run coding agents on machines you own. Open-source, self-hostable agent workspace.",