talon-agent 3.22.1 → 3.23.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.
package/bin/talon.js CHANGED
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import("tsx").then(() => import("../src/cli.ts")).catch((err) => {
3
- console.error("Failed to start Talon:", err.message);
4
- process.exit(1);
5
- });
2
+ (process.versions.bun ? Promise.resolve() : import("tsx"))
3
+ .then(() => import("../src/cli.ts"))
4
+ .catch((err) => {
5
+ console.error("Failed to start Talon:", err.message);
6
+ process.exit(1);
7
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "talon-agent",
3
- "version": "3.22.1",
3
+ "version": "3.23.0",
4
4
  "description": "Multi-frontend AI agent with full tool access, streaming, cron jobs, and plugin system",
5
5
  "author": "Dylan Neve",
6
6
  "license": "MIT",
@@ -55,10 +55,13 @@
55
55
  "tsconfig.json"
56
56
  ],
57
57
  "scripts": {
58
- "start": "tsx src/index.ts",
59
- "cli": "tsx src/cli.ts",
60
- "setup": "tsx src/cli.ts setup",
61
- "dev": "tsx --watch src/index.ts",
58
+ "start": "bun src/index.ts",
59
+ "start:node": "tsx src/index.ts",
60
+ "cli": "bun src/cli.ts",
61
+ "cli:node": "tsx src/cli.ts",
62
+ "setup": "bun src/cli.ts setup",
63
+ "dev": "bun --watch src/index.ts",
64
+ "dev:node": "tsx --watch src/index.ts",
62
65
  "test": "vitest run",
63
66
  "test:ci": "vitest run --reporter=verbose --reporter=json --outputFile=test-results.json",
64
67
  "test:functional": "vitest run --reporter=verbose --reporter=json --outputFile=functional-results.json src/__tests__/package.functional.test.ts src/__tests__/tool-functional.test.ts src/__tests__/mcp-launcher.test.ts src/__tests__/mcp-launcher-functional.test.ts src/__tests__/integration/sdk-stub.test.ts src/__tests__/integration/talon-functional.test.ts",
@@ -14,6 +14,7 @@
14
14
 
15
15
  import { spawn } from "node:child_process";
16
16
  import { dirname, resolve } from "node:path";
17
+ import { isBunRuntime } from "../../util/runtime.js";
17
18
  import {
18
19
  readPidRecord,
19
20
  writePidRecord,
@@ -93,13 +94,18 @@ export async function startDaemon(opts: {
93
94
  // Compiled binaries: re-invoke `process.execPath` with no extra args.
94
95
  // The binary's own entrypoint (src/index.ts, embedded) handles the
95
96
  // server startup the same way a tsx run would.
97
+ //
98
+ // Bun source runs need no loader at all — bun executes the TS entry
99
+ // directly, so a bun-launched CLI spawns a bun daemon.
96
100
  const spawnCmd = process.execPath;
97
101
  const spawnArgs = isBunBinary
98
102
  ? []
99
- : [
100
- resolve(opts.pkgRoot, "node_modules", "tsx", "dist", "cli.mjs"),
101
- resolve(opts.pkgRoot, "src", "index.ts"),
102
- ];
103
+ : isBunRuntime()
104
+ ? [resolve(opts.pkgRoot, "src", "index.ts")]
105
+ : [
106
+ resolve(opts.pkgRoot, "node_modules", "tsx", "dist", "cli.mjs"),
107
+ resolve(opts.pkgRoot, "src", "index.ts"),
108
+ ];
103
109
  const spawnCwd = isBunBinary ? dirname(process.execPath) : opts.pkgRoot;
104
110
 
105
111
  let child;
@@ -6,6 +6,7 @@
6
6
 
7
7
  import { resolve } from "node:path";
8
8
  import { wrapMcpServer } from "../../util/mcp-launcher.js";
9
+ import { isBunRuntime } from "../../util/runtime.js";
9
10
  import { registry, reloadState } from "./registry.js";
10
11
  import type { McpServerConfig } from "./types.js";
11
12
 
@@ -60,11 +61,16 @@ export function getPluginMcpServers(
60
61
  env: baseEnv,
61
62
  });
62
63
  } else if (plugin.mcpServerPath) {
63
- // Existing Node/tsx pattern
64
+ // TS server entry: bun runs it directly; node needs the tsx loader.
64
65
  servers[`${plugin.name}-tools`] = wrapMcpServer({
65
- command: process.platform === "win32" ? "npx" : "node",
66
- args:
67
- process.platform === "win32"
66
+ command: isBunRuntime()
67
+ ? process.execPath
68
+ : process.platform === "win32"
69
+ ? "npx"
70
+ : "node",
71
+ args: isBunRuntime()
72
+ ? [plugin.mcpServerPath]
73
+ : process.platform === "win32"
68
74
  ? ["tsx", plugin.mcpServerPath]
69
75
  : ["--import", tsxPath, plugin.mcpServerPath],
70
76
  env: baseEnv,
@@ -18,6 +18,7 @@
18
18
 
19
19
  import { dirname, resolve } from "node:path";
20
20
  import { fileURLToPath, pathToFileURL } from "node:url";
21
+ import { isBunRuntime } from "../../util/runtime.js";
21
22
 
22
23
  // ── Env-var names (shared constants, not stringly-typed call sites) ────────
23
24
 
@@ -76,6 +77,11 @@ export function buildTalonMcpEnv(
76
77
  */
77
78
  export function talonMcpServerCommand(): string[] {
78
79
  const here = dirname(fileURLToPath(import.meta.url));
80
+ // Bun executes the TS entry natively — no loader, and use the running
81
+ // bun binary itself so the child matches the daemon's runtime.
82
+ if (isBunRuntime()) {
83
+ return [process.execPath, resolve(here, "mcp-server.ts")];
84
+ }
79
85
  const tsxImport = pathToFileURL(
80
86
  resolve(here, "../../../node_modules/tsx/dist/esm/index.mjs"),
81
87
  ).href;
@@ -16,6 +16,7 @@
16
16
  */
17
17
 
18
18
  import type { TalonConfig } from "../../util/config.js";
19
+ import { isBunRuntime } from "../../util/runtime.js";
19
20
  import type { ContextManager } from "../../core/types.js";
20
21
  import type { Gateway } from "../../core/engine/gateway.js";
21
22
  import { mkdir, writeFile } from "node:fs/promises";
@@ -983,11 +984,13 @@ export function createNativeFrontend(
983
984
  const cmd = process.execPath;
984
985
  const args = isBunBinary
985
986
  ? ["restart"]
986
- : [
987
- resolve(PKG_ROOT, "node_modules", "tsx", "dist", "cli.mjs"),
988
- resolve(PKG_ROOT, "src", "cli.ts"),
989
- "restart",
990
- ];
987
+ : isBunRuntime()
988
+ ? [resolve(PKG_ROOT, "src", "cli.ts"), "restart"]
989
+ : [
990
+ resolve(PKG_ROOT, "node_modules", "tsx", "dist", "cli.mjs"),
991
+ resolve(PKG_ROOT, "src", "cli.ts"),
992
+ "restart",
993
+ ];
991
994
  const cwd = isBunBinary ? dirname(process.execPath) : PKG_ROOT;
992
995
  const child = spawn(cmd, args, {
993
996
  cwd,
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Runtime detection for source runs.
3
+ *
4
+ * Talon source runs work on two runtimes: Node (which needs the tsx
5
+ * CLI/loader to execute `.ts` entrypoints) and Bun (which executes
6
+ * TypeScript natively). Every place that re-invokes a TS entrypoint in
7
+ * a child process — the daemon spawn, the restart handoff, MCP server
8
+ * commands — branches on this instead of hardcoding the tsx recipe, so
9
+ * `bun src/cli.ts start` yields a bun daemon with bun children while
10
+ * node+tsx runs stay byte-identical to before.
11
+ *
12
+ * Bun-COMPILED binaries are a third shape detected separately (argv[1]
13
+ * points into the embedded virtual fs) — see the existing `$bunfs`
14
+ * checks at the spawn sites and in `util/mcp-launcher.ts`.
15
+ */
16
+
17
+ /** True when the current process is executing under the Bun runtime. */
18
+ export function isBunRuntime(): boolean {
19
+ return typeof process.versions.bun === "string";
20
+ }