@versot/vaguspi 0.1.6 → 0.1.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 CHANGED
@@ -300,6 +300,7 @@ var VagModelsStore = class {
300
300
  };
301
301
 
302
302
  // packages/host/engine/dist/vagus-engine.js
303
+ import { spawn } from "node:child_process";
303
304
  import { createAgentSession, DefaultResourceLoader, ModelRuntime, SessionManager as SessionManager2, SettingsManager } from "@earendil-works/pi-coding-agent";
304
305
  import { homedir } from "node:os";
305
306
  import { basename, dirname as dirname3, isAbsolute as isAbsolute2, join as join5, resolve, sep } from "node:path";
@@ -870,6 +871,17 @@ var ExtensionUiBridge = class {
870
871
  };
871
872
 
872
873
  // packages/host/engine/dist/vagus-engine.js
874
+ function runCapture(cmd, args) {
875
+ return new Promise((res) => {
876
+ const child = spawn(cmd, args, { windowsHide: true });
877
+ let stdout = "";
878
+ child.stdout?.on("data", (d) => {
879
+ stdout += String(d);
880
+ });
881
+ child.on("error", () => res({ stdout, code: 1 }));
882
+ child.on("close", (code) => res({ stdout, code: code ?? 1 }));
883
+ });
884
+ }
873
885
  var VagusEngine = class _VagusEngine {
874
886
  options;
875
887
  sessions = /* @__PURE__ */ new Map();
@@ -1971,18 +1983,76 @@ var VagusEngine = class _VagusEngine {
1971
1983
  const session = this.requireSession(sessionId);
1972
1984
  await session.steer(text);
1973
1985
  }
1974
- /** Cancels a queued message by removing it from pi's steering queue. */
1986
+ /** Cancels a queued message by removing it from pi's steering queue.
1987
+ * pi keeps TWO queues in sync: AgentSession._steeringMessages (display
1988
+ * tracking) and Agent.steeringQueue.messages (the real send queue —
1989
+ * clearing only the former still delivers the message). Remove from both;
1990
+ * match by message text on the agent queue (AgentMessage.content text). */
1975
1991
  async cancelQueuedMessage(sessionId, text) {
1976
1992
  const session = this.requireSession(sessionId);
1993
+ let cancelled = false;
1977
1994
  const msgs = session["_steeringMessages"];
1978
1995
  if (msgs) {
1979
1996
  const idx = msgs.indexOf(text);
1980
1997
  if (idx !== -1) {
1981
1998
  msgs.splice(idx, 1);
1982
- return { cancelled: true };
1999
+ cancelled = true;
2000
+ }
2001
+ }
2002
+ const agent = session["agent"];
2003
+ const q = agent?.steeringQueue;
2004
+ if (q?.messages) {
2005
+ const idx = q.messages.findIndex((m) => m.content.some((c) => c.type === "text" && c.text === text));
2006
+ if (idx !== -1) {
2007
+ q.messages.splice(idx, 1);
2008
+ cancelled = true;
1983
2009
  }
1984
2010
  }
1985
- return { cancelled: false };
2011
+ if (cancelled) {
2012
+ session._emitQueueUpdate?.();
2013
+ }
2014
+ return { cancelled };
2015
+ }
2016
+ /**
2017
+ * Opens the OS-native folder picker on the daemon host and returns the
2018
+ * chosen path (null = user cancelled / unsupported platform). Windows uses
2019
+ * the FolderBrowserDialog via PowerShell (zero deps, -STA so the dialog
2020
+ * works, TopMost host so it isn't buried behind other windows); macOS uses
2021
+ * osascript; Linux tries zenity then kdialog.
2022
+ */
2023
+ async pickNativeDirectory() {
2024
+ const platform = process.platform;
2025
+ if (platform === "win32") {
2026
+ const ps = "Add-Type -AssemblyName System.Windows.Forms;$host2 = New-Object System.Windows.Forms.Form -Property @{TopMost=$true; ShowInTaskbar=$false};$f = New-Object System.Windows.Forms.FolderBrowserDialog;$f.ShowNewFolderButton = $true;if ($f.ShowDialog($host2) -eq [System.Windows.Forms.DialogResult]::OK) { $f.SelectedPath }";
2027
+ const { stdout } = await runCapture("powershell", ["-NoProfile", "-STA", "-Command", ps]);
2028
+ const p = stdout.trim();
2029
+ return { path: p === "" ? null : p };
2030
+ }
2031
+ if (platform === "darwin") {
2032
+ const script = [
2033
+ "try",
2034
+ "with timeout of 3600 seconds",
2035
+ 'set selectedFolder to choose folder with prompt "\u9009\u62E9\u5DE5\u4F5C\u76EE\u5F55"',
2036
+ "POSIX path of selectedFolder",
2037
+ "on error number -128",
2038
+ 'return ""',
2039
+ "end try"
2040
+ ].join("\n");
2041
+ const { stdout, code } = await runCapture("osascript", ["-e", script]);
2042
+ const p = stdout.trim().replace(/\/$/, "");
2043
+ return { path: code === 0 && p !== "" ? p : null };
2044
+ }
2045
+ if (platform === "linux") {
2046
+ let { stdout, code } = await runCapture("zenity", ["--file-selection", "--directory", "--title=\u9009\u62E9\u5DE5\u4F5C\u76EE\u5F55"]);
2047
+ if (code === 127) {
2048
+ ({ stdout, code } = await runCapture("kdialog", ["--getexistingdirectory", ".", "--title", "\u9009\u62E9\u5DE5\u4F5C\u76EE\u5F55"]));
2049
+ if (code === 127)
2050
+ throw new Error("\u672A\u627E\u5230 zenity \u6216 kdialog\uFF0C\u65E0\u6CD5\u6253\u5F00\u7CFB\u7EDF\u76EE\u5F55\u9009\u62E9\u5668\uFF08\u8BF7\u5728\u670D\u52A1\u5668\u4E0A\u5B89\u88C5 zenity\uFF09");
2051
+ }
2052
+ const p = stdout.trim();
2053
+ return { path: code === 0 && p !== "" ? p : null };
2054
+ }
2055
+ throw new Error(`\u7CFB\u7EDF\u76EE\u5F55\u9009\u62E9\u5668\u4E0D\u652F\u6301\u5728 ${platform} \u4E0A\u8FD0\u884C`);
1986
2056
  }
1987
2057
  /**
1988
2058
  * Queues a follow-up message.
@@ -7566,6 +7636,7 @@ async function runDaemon() {
7566
7636
  const { sessionId, text } = params ?? {};
7567
7637
  return host.followUpSession(requireString(sessionId, "sessionId"), requireString(text, "text"));
7568
7638
  });
7639
+ srv.registerMethod("project.pickNative", () => host.pickNativeDirectory());
7569
7640
  srv.registerMethod("session.cancelQueued", (params) => {
7570
7641
  const { sessionId, text } = params ?? {};
7571
7642
  return host.cancelQueuedMessage(requireString(sessionId, "sessionId"), requireString(text, "text"));
@@ -7733,13 +7804,13 @@ async function runDaemon() {
7733
7804
  }
7734
7805
 
7735
7806
  // apps/cli/src/commands/web.ts
7736
- import { spawn as spawn2 } from "node:child_process";
7807
+ import { spawn as spawn3 } from "node:child_process";
7737
7808
  import { existsSync as existsSync8 } from "node:fs";
7738
7809
  import { join as join9 } from "node:path";
7739
7810
  import { fileURLToPath as fileURLToPath3 } from "node:url";
7740
7811
 
7741
7812
  // apps/cli/src/daemon.ts
7742
- import { execSync, spawn } from "node:child_process";
7813
+ import { execSync, spawn as spawn2 } from "node:child_process";
7743
7814
  import { existsSync as existsSync7 } from "node:fs";
7744
7815
  import { fileURLToPath as fileURLToPath2 } from "node:url";
7745
7816
  function detectSystemProxy() {
@@ -7801,7 +7872,7 @@ function spawnDaemon(options = {}) {
7801
7872
  process.stderr.write(`vagus: proxy env already set (HTTPS_PROXY=${process.env.HTTPS_PROXY ?? process.env.HTTP_PROXY})
7802
7873
  `);
7803
7874
  }
7804
- return spawn(process.execPath, args, {
7875
+ return spawn2(process.execPath, args, {
7805
7876
  stdio: options.stdio ?? ["pipe", "pipe", "pipe"],
7806
7877
  env: { ...process.env, ...injected, ...options.env }
7807
7878
  });
@@ -7819,11 +7890,11 @@ function guiDistPath() {
7819
7890
  function openBrowser(url) {
7820
7891
  const platform = process.platform;
7821
7892
  if (platform === "win32") {
7822
- spawn2("cmd", ["/c", "start", "", url], { stdio: "ignore", detached: true }).unref();
7893
+ spawn3("cmd", ["/c", "start", "", url], { stdio: "ignore", detached: true }).unref();
7823
7894
  } else if (platform === "darwin") {
7824
- spawn2("open", [url], { stdio: "ignore", detached: true }).unref();
7895
+ spawn3("open", [url], { stdio: "ignore", detached: true }).unref();
7825
7896
  } else {
7826
- spawn2("xdg-open", [url], { stdio: "ignore", detached: true }).unref();
7897
+ spawn3("xdg-open", [url], { stdio: "ignore", detached: true }).unref();
7827
7898
  }
7828
7899
  }
7829
7900
  async function runWeb() {