@runfusion/fusion 0.0.2 → 0.0.3
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/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Runfusion
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -20,13 +20,30 @@
|
|
|
20
20
|
|
|
21
21
|
## Install
|
|
22
22
|
|
|
23
|
-
Zero install, straight from npm
|
|
23
|
+
**Zero install, straight from npm:**
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
npx
|
|
26
|
+
npx runfusion.ai
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
Boots the dashboard. Subcommands forward through (`npx runfusion.ai task list`, etc). Long form: `npx @runfusion/fusion dashboard`.
|
|
30
|
+
|
|
31
|
+
**One-line installer** (macOS & Linux — auto-picks Homebrew, falls back to npm):
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
curl -fsSL https://runfusion.ai/install.sh | sh
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Homebrew** (macOS & Linux):
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
brew tap runfusion/fusion
|
|
41
|
+
brew install fusion
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Or as a one-liner: `brew install runfusion/fusion/fusion`.
|
|
45
|
+
|
|
46
|
+
**npm global**:
|
|
30
47
|
|
|
31
48
|
```bash
|
|
32
49
|
npm install -g @runfusion/fusion
|
package/dist/bin.js
CHANGED
|
@@ -46017,10 +46017,10 @@ function pushAlias(aliases, value) {
|
|
|
46017
46017
|
if (pathRef !== normalized && pathRef.length > 0) {
|
|
46018
46018
|
aliases.add(pathRef);
|
|
46019
46019
|
}
|
|
46020
|
-
const
|
|
46021
|
-
if (
|
|
46022
|
-
aliases.add(
|
|
46023
|
-
const basenameSlug = slugifyAgentReference(
|
|
46020
|
+
const basename14 = extractPathBasename(value);
|
|
46021
|
+
if (basename14) {
|
|
46022
|
+
aliases.add(basename14);
|
|
46023
|
+
const basenameSlug = slugifyAgentReference(basename14);
|
|
46024
46024
|
if (basenameSlug.length > 0) {
|
|
46025
46025
|
aliases.add(basenameSlug);
|
|
46026
46026
|
}
|
|
@@ -51110,11 +51110,43 @@ var init_terminal_service = __esm({
|
|
|
51110
51110
|
if (this.isWindows) {
|
|
51111
51111
|
ptyOptions.useConpty = false;
|
|
51112
51112
|
}
|
|
51113
|
+
const attemptedSpawns = /* @__PURE__ */ new Set();
|
|
51114
|
+
const spawnAttempts = [];
|
|
51115
|
+
const addSpawnAttempt = (shellPath, args, reason) => {
|
|
51116
|
+
const key = `${shellPath}\0${args.join("\0")}`;
|
|
51117
|
+
if (attemptedSpawns.has(key)) return;
|
|
51118
|
+
attemptedSpawns.add(key);
|
|
51119
|
+
spawnAttempts.push({ shell: shellPath, args, reason });
|
|
51120
|
+
};
|
|
51121
|
+
addSpawnAttempt(shell, shellArgs, "primary");
|
|
51122
|
+
if (shellArgs.length > 0) {
|
|
51123
|
+
addSpawnAttempt(shell, [], "retry-without-login");
|
|
51124
|
+
}
|
|
51125
|
+
for (const allowedShell of this.getAllowedShells()) {
|
|
51126
|
+
if (allowedShell === shell || !existsSync17(allowedShell)) continue;
|
|
51127
|
+
const shellName = path.basename(allowedShell).toLowerCase().replace(".exe", "");
|
|
51128
|
+
const fallbackArgs = shellName === "bash" || shellName === "zsh" ? [] : [];
|
|
51129
|
+
addSpawnAttempt(allowedShell, fallbackArgs, "allowed-fallback");
|
|
51130
|
+
}
|
|
51113
51131
|
let ptyProcess;
|
|
51114
|
-
|
|
51115
|
-
|
|
51116
|
-
|
|
51117
|
-
|
|
51132
|
+
let lastSpawnError;
|
|
51133
|
+
for (const attempt of spawnAttempts) {
|
|
51134
|
+
try {
|
|
51135
|
+
console.info(
|
|
51136
|
+
`[createSession] Spawning terminal via ${attempt.reason}: ${attempt.shell} ${attempt.args.join(" ")} in ${cwd}`
|
|
51137
|
+
);
|
|
51138
|
+
ptyProcess = pty.spawn(attempt.shell, attempt.args, ptyOptions);
|
|
51139
|
+
break;
|
|
51140
|
+
} catch (spawnError) {
|
|
51141
|
+
lastSpawnError = spawnError;
|
|
51142
|
+
console.error(
|
|
51143
|
+
`[createSession] PTY spawn failed (${attempt.reason}) for ${attempt.shell} ${attempt.args.join(" ")}:`,
|
|
51144
|
+
spawnError
|
|
51145
|
+
);
|
|
51146
|
+
}
|
|
51147
|
+
}
|
|
51148
|
+
if (!ptyProcess) {
|
|
51149
|
+
console.error(`[createSession] All PTY spawn attempts failed`, lastSpawnError);
|
|
51118
51150
|
return {
|
|
51119
51151
|
success: false,
|
|
51120
51152
|
code: "pty_spawn_failed",
|
|
@@ -51393,7 +51425,7 @@ var init_terminal_service = __esm({
|
|
|
51393
51425
|
});
|
|
51394
51426
|
|
|
51395
51427
|
// ../dashboard/src/file-service.ts
|
|
51396
|
-
import { join as join23, resolve as resolve12, relative as relative3, dirname as dirname8, basename as
|
|
51428
|
+
import { join as join23, resolve as resolve12, relative as relative3, dirname as dirname8, basename as basename7 } from "node:path";
|
|
51397
51429
|
import { readdir as readdir7, readFile as fsReadFile, writeFile as fsWriteFile, stat as stat5, copyFile as fsCopyFile, rename as fsRename, rm as fsRm, mkdir as mkdir11, access as access3 } from "node:fs/promises";
|
|
51398
51430
|
async function getTaskBasePath(store, taskId) {
|
|
51399
51431
|
try {
|
|
@@ -51847,7 +51879,7 @@ async function getWorkspaceFileForDownload(store, workspace, filePath) {
|
|
|
51847
51879
|
mtime: stats.mtime,
|
|
51848
51880
|
isFile: true
|
|
51849
51881
|
},
|
|
51850
|
-
fileName:
|
|
51882
|
+
fileName: basename7(resolvedPath)
|
|
51851
51883
|
};
|
|
51852
51884
|
}
|
|
51853
51885
|
async function getWorkspaceFolderForZip(store, workspace, dirPath) {
|
|
@@ -51875,7 +51907,7 @@ async function getWorkspaceFolderForZip(store, workspace, dirPath) {
|
|
|
51875
51907
|
}
|
|
51876
51908
|
return {
|
|
51877
51909
|
absolutePath: resolvedPath,
|
|
51878
|
-
dirName:
|
|
51910
|
+
dirName: basename7(resolvedPath)
|
|
51879
51911
|
};
|
|
51880
51912
|
}
|
|
51881
51913
|
async function walkDirForMarkdown(basePath, currentRelative, results) {
|
|
@@ -60432,7 +60464,7 @@ __export(pi_exports, {
|
|
|
60432
60464
|
import { existsSync as existsSync21, readFileSync as readFileSync8 } from "node:fs";
|
|
60433
60465
|
import { exec } from "node:child_process";
|
|
60434
60466
|
import { promisify as promisify2 } from "node:util";
|
|
60435
|
-
import { basename as
|
|
60467
|
+
import { basename as basename8, dirname as dirname9, join as join28, relative as relative4, isAbsolute as isAbsolute6, resolve as resolve13 } from "node:path";
|
|
60436
60468
|
import { createAgentSession, createCodingTools, createExtensionRuntime, createReadOnlyTools, DefaultResourceLoader, DefaultPackageManager, discoverAndLoadExtensions, ModelRegistry, SessionManager, SettingsManager } from "@mariozechner/pi-coding-agent";
|
|
60437
60469
|
function getSessionStateError(session) {
|
|
60438
60470
|
const error = session.state?.error;
|
|
@@ -60645,7 +60677,7 @@ function hasPackageManagerSettings(settings) {
|
|
|
60645
60677
|
return Array.isArray(settings.packages) || Array.isArray(settings.npmCommand);
|
|
60646
60678
|
}
|
|
60647
60679
|
function siblingAgentDir(agentDir, siblingRoot) {
|
|
60648
|
-
if (
|
|
60680
|
+
if (basename8(agentDir) !== "agent") {
|
|
60649
60681
|
return void 0;
|
|
60650
60682
|
}
|
|
60651
60683
|
return join28(dirname9(dirname9(agentDir)), siblingRoot, "agent");
|
|
@@ -87057,7 +87089,7 @@ var init_rate_limit = __esm({
|
|
|
87057
87089
|
// ../dashboard/src/plugin-routes.ts
|
|
87058
87090
|
import { Router as Router5 } from "express";
|
|
87059
87091
|
import { access as access5, stat as stat8, readFile as readFile21 } from "node:fs/promises";
|
|
87060
|
-
import { join as join41, isAbsolute as isAbsolute11, dirname as dirname13, basename as
|
|
87092
|
+
import { join as join41, isAbsolute as isAbsolute11, dirname as dirname13, basename as basename9 } from "node:path";
|
|
87061
87093
|
async function resolvePluginManifest(sourcePath) {
|
|
87062
87094
|
try {
|
|
87063
87095
|
await access5(sourcePath);
|
|
@@ -87081,7 +87113,7 @@ async function resolvePluginManifest(sourcePath) {
|
|
|
87081
87113
|
} catch (err) {
|
|
87082
87114
|
if (err instanceof ApiError) throw err;
|
|
87083
87115
|
}
|
|
87084
|
-
const dirName =
|
|
87116
|
+
const dirName = basename9(sourcePath).toLowerCase();
|
|
87085
87117
|
if (DIST_DIR_NAMES.has(dirName)) {
|
|
87086
87118
|
const parentDir = dirname13(sourcePath);
|
|
87087
87119
|
const parentManifestPath = join41(parentDir, "manifest.json");
|
|
@@ -124010,7 +124042,7 @@ ${body}`;
|
|
|
124010
124042
|
const nodeId = req.query.nodeId;
|
|
124011
124043
|
if (nodeId) {
|
|
124012
124044
|
const { CentralCore: CentralCore2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
124013
|
-
const central = new CentralCore2();
|
|
124045
|
+
const central = new CentralCore2(store.getFusionDir());
|
|
124014
124046
|
await central.init();
|
|
124015
124047
|
const localNodes = await central.listNodes();
|
|
124016
124048
|
const localNode = localNodes.find((n) => n.type === "local");
|
|
@@ -124037,6 +124069,9 @@ ${body}`;
|
|
|
124037
124069
|
headers,
|
|
124038
124070
|
signal: AbortSignal.timeout(3e4)
|
|
124039
124071
|
});
|
|
124072
|
+
if (proxyRes.status === 401 && !node.apiKey) {
|
|
124073
|
+
throw unauthorized("Remote node rejected directory browse request. Configure an apiKey for that node in Fusion settings.");
|
|
124074
|
+
}
|
|
124040
124075
|
const body = Buffer.from(await proxyRes.arrayBuffer());
|
|
124041
124076
|
const skipHeaders = /* @__PURE__ */ new Set(["connection", "keep-alive", "transfer-encoding", "upgrade"]);
|
|
124042
124077
|
for (const [key, value] of proxyRes.headers.entries()) {
|
|
@@ -133089,9 +133124,9 @@ var init_port_prompt = __esm({
|
|
|
133089
133124
|
|
|
133090
133125
|
// src/commands/provider-settings.ts
|
|
133091
133126
|
import { existsSync as existsSync31, readFileSync as readFileSync11, writeFileSync as writeFileSync2, mkdirSync as mkdirSync6 } from "node:fs";
|
|
133092
|
-
import { join as join46, dirname as dirname16, basename as
|
|
133127
|
+
import { join as join46, dirname as dirname16, basename as basename10 } from "node:path";
|
|
133093
133128
|
function siblingAgentDir2(agentDir, siblingRoot) {
|
|
133094
|
-
if (
|
|
133129
|
+
if (basename10(agentDir) !== "agent") {
|
|
133095
133130
|
return void 0;
|
|
133096
133131
|
}
|
|
133097
133132
|
return join46(dirname16(dirname16(agentDir)), siblingRoot, "agent");
|
|
@@ -135731,10 +135766,10 @@ async function runTaskCreate(descriptionArg, attachFiles, depends, projectName)
|
|
|
135731
135766
|
console.log(` Path: .fusion/tasks/${task.id}/`);
|
|
135732
135767
|
if (attachFiles && attachFiles.length > 0) {
|
|
135733
135768
|
const { readFile: readFile24 } = await import("node:fs/promises");
|
|
135734
|
-
const { basename:
|
|
135769
|
+
const { basename: basename14, extname, resolve: resolve29 } = await import("node:path");
|
|
135735
135770
|
for (const filePath of attachFiles) {
|
|
135736
135771
|
const resolvedPath = resolve29(filePath);
|
|
135737
|
-
const filename =
|
|
135772
|
+
const filename = basename14(resolvedPath);
|
|
135738
135773
|
const ext = extname(filename).toLowerCase();
|
|
135739
135774
|
const mimeType = MIME_TYPES[ext];
|
|
135740
135775
|
if (!mimeType) {
|
|
@@ -135980,10 +136015,10 @@ async function runTaskMerge(id, projectName) {
|
|
|
135980
136015
|
}
|
|
135981
136016
|
async function runTaskAttach(id, filePath, projectName) {
|
|
135982
136017
|
const { readFile: readFile24 } = await import("node:fs/promises");
|
|
135983
|
-
const { basename:
|
|
136018
|
+
const { basename: basename14, extname } = await import("node:path");
|
|
135984
136019
|
const { resolve: resolve29 } = await import("node:path");
|
|
135985
136020
|
const resolvedPath = resolve29(filePath);
|
|
135986
|
-
const filename =
|
|
136021
|
+
const filename = basename14(resolvedPath);
|
|
135987
136022
|
const ext = extname(filename).toLowerCase();
|
|
135988
136023
|
const mimeType = MIME_TYPES[ext];
|
|
135989
136024
|
if (!mimeType) {
|
|
@@ -138204,7 +138239,7 @@ __export(project_exports, {
|
|
|
138204
138239
|
runProjectSetDefault: () => runProjectSetDefault,
|
|
138205
138240
|
runProjectShow: () => runProjectShow
|
|
138206
138241
|
});
|
|
138207
|
-
import { resolve as resolve25, isAbsolute as isAbsolute13, relative as relative11, basename as
|
|
138242
|
+
import { resolve as resolve25, isAbsolute as isAbsolute13, relative as relative11, basename as basename11 } from "node:path";
|
|
138208
138243
|
import { existsSync as existsSync38, statSync as statSync9 } from "node:fs";
|
|
138209
138244
|
import { createInterface as createInterface7 } from "node:readline/promises";
|
|
138210
138245
|
function formatDisplayPath(projectPath) {
|
|
@@ -138212,7 +138247,7 @@ function formatDisplayPath(projectPath) {
|
|
|
138212
138247
|
if (rel && !rel.startsWith("..") && rel !== "") {
|
|
138213
138248
|
return rel;
|
|
138214
138249
|
}
|
|
138215
|
-
return
|
|
138250
|
+
return basename11(projectPath) || ".";
|
|
138216
138251
|
}
|
|
138217
138252
|
function formatLastActivity2(timestamp) {
|
|
138218
138253
|
if (!timestamp) return "never";
|
|
@@ -138362,7 +138397,7 @@ async function runProjectAdd(name, path4, options = {}) {
|
|
|
138362
138397
|
}
|
|
138363
138398
|
}
|
|
138364
138399
|
if (!projectName) {
|
|
138365
|
-
const suggested =
|
|
138400
|
+
const suggested = basename11(absolutePath2);
|
|
138366
138401
|
projectName = await rl.question(` Project name [${suggested}]: `);
|
|
138367
138402
|
projectName = projectName.trim() || suggested;
|
|
138368
138403
|
}
|
|
@@ -138651,7 +138686,7 @@ __export(init_exports, {
|
|
|
138651
138686
|
runInit: () => runInit
|
|
138652
138687
|
});
|
|
138653
138688
|
import { existsSync as existsSync39, mkdirSync as mkdirSync7, writeFileSync as writeFileSync3, readFileSync as readFileSync15 } from "node:fs";
|
|
138654
|
-
import { join as join54, resolve as resolve26, basename as
|
|
138689
|
+
import { join as join54, resolve as resolve26, basename as basename12 } from "node:path";
|
|
138655
138690
|
import { exec as exec11 } from "node:child_process";
|
|
138656
138691
|
import { promisify as promisify13 } from "node:util";
|
|
138657
138692
|
async function runInit(options = {}) {
|
|
@@ -138767,7 +138802,7 @@ async function detectProjectName(dir2) {
|
|
|
138767
138802
|
}
|
|
138768
138803
|
} catch {
|
|
138769
138804
|
}
|
|
138770
|
-
return
|
|
138805
|
+
return basename12(dir2) || "my-project";
|
|
138771
138806
|
}
|
|
138772
138807
|
async function addLocalStorageToGitignore(cwd) {
|
|
138773
138808
|
const gitignorePath = join54(cwd, ".gitignore");
|
|
@@ -139949,7 +139984,7 @@ __export(native_patch_exports, {
|
|
|
139949
139984
|
isTerminalAvailable: () => isTerminalAvailable,
|
|
139950
139985
|
setupNativeResolution: () => setupNativeResolution
|
|
139951
139986
|
});
|
|
139952
|
-
import { join as join57, basename as
|
|
139987
|
+
import { join as join57, basename as basename13, dirname as dirname19 } from "node:path";
|
|
139953
139988
|
import { existsSync as existsSync43, copyFileSync, mkdirSync as mkdirSync10, symlinkSync, rmSync as rmSync3, lstatSync as lstatSync2, readlinkSync } from "node:fs";
|
|
139954
139989
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
139955
139990
|
function findStagedNativeDir2() {
|
|
@@ -139999,7 +140034,7 @@ function setupNativeResolution() {
|
|
|
139999
140034
|
const tmpRoot = join57(tmpdir3(), `fn-bunfs-${process.pid}`);
|
|
140000
140035
|
const fnDir = join57(tmpRoot, "fn");
|
|
140001
140036
|
const prebuildsDir = join57(fnDir, "prebuilds");
|
|
140002
|
-
const platformDir = join57(prebuildsDir,
|
|
140037
|
+
const platformDir = join57(prebuildsDir, basename13(nativeDir));
|
|
140003
140038
|
try {
|
|
140004
140039
|
cleanupStaleBunfsLinks();
|
|
140005
140040
|
mkdirSync10(platformDir, { recursive: true });
|