@runfusion/fusion 0.22.0 → 0.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/dist/bin.js +4546 -1223
- package/dist/client/assets/AgentDetailView-C1XceMgi.js +18 -0
- package/dist/client/assets/AgentsView-DSGQWObq.css +1 -0
- package/dist/client/assets/AgentsView-Deh125ss.js +527 -0
- package/dist/client/assets/ChatView-7D_RQDqT.js +1 -0
- package/dist/client/assets/{DevServerView-l8RCyL2k.js → DevServerView-C9lzHrcT.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-CS1dwqcC.js → DirectoryPicker-aVdFaV37.js} +1 -1
- package/dist/client/assets/{DocumentsView-DmthQWDZ.js → DocumentsView-DIpg3NSP.js} +1 -1
- package/dist/client/assets/{InsightsView-DvXpMKmH.js → InsightsView-jKjEFAx_.js} +1 -1
- package/dist/client/assets/{MemoryView-CPwlKnUI.js → MemoryView-nXlTqebk.js} +1 -1
- package/dist/client/assets/{NodesView-BLlfUfsy.js → NodesView-Di2SvOhg.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-j8rPXqmB.js → PiExtensionsManager-Buopv-jb.js} +1 -1
- package/dist/client/assets/PluginManager-B9-NbQ8f.js +1 -0
- package/dist/client/assets/PluginManager-C1DbPaar.css +1 -0
- package/dist/client/assets/{ResearchView-D9DNJYDq.js → ResearchView-_BHXUv2j.js} +1 -1
- package/dist/client/assets/{RoadmapsView-Djc_X35v.js → RoadmapsView-DHWjUoc8.js} +1 -1
- package/dist/client/assets/{SettingsModal-fxvTFLtR.js → SettingsModal-C89Ikhfm.js} +1 -1
- package/dist/client/assets/SettingsModal-DHitIpsa.css +1 -0
- package/dist/client/assets/SettingsModal-DR_yirvK.js +31 -0
- package/dist/client/assets/{SetupWizardModal-tG_MF_nA.js → SetupWizardModal-BtDMY9pa.js} +1 -1
- package/dist/client/assets/{SkillsView-Ddf0YL8z.js → SkillsView-hDpTBdFT.js} +1 -1
- package/dist/client/assets/{agentSkills-EwIwBlG8.js → agentSkills-B-w5wFHh.js} +1 -1
- package/dist/client/assets/{folder-open-BiJpmnaT.js → folder-open-usZkXdq2.js} +1 -1
- package/dist/client/assets/index-Bc6ZdGMz.css +1 -0
- package/dist/client/assets/index-D__RMku8.js +694 -0
- package/dist/client/assets/{star-BwRZmiuZ.js → star-BAT_ObKE.js} +1 -1
- package/dist/client/assets/{upload-D4NwZhPp.js → upload-BC2YKNEV.js} +1 -1
- package/dist/client/assets/{users-DNISDtI1.js → users-Dkd4rtrN.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +1 -1
- package/dist/extension.js +3266 -540
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/src/DependencyGraphView.css +12 -3
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/storage.test.ts +12 -2
- package/dist/plugins/fusion-plugin-dependency-graph/src/storage.ts +6 -7
- package/dist/plugins/fusion-plugin-hermes-runtime/bundled.js +176 -7
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/package.json +1 -1
- package/skill/fusion/references/engine-tools.md +5 -2
- package/dist/client/assets/AgentDetailView-BKKpbp1S.js +0 -18
- package/dist/client/assets/AgentsView-BRXFmrcJ.js +0 -527
- package/dist/client/assets/AgentsView-Bs03ptrd.css +0 -1
- package/dist/client/assets/ChatView-D7L2e_qu.js +0 -1
- package/dist/client/assets/PluginManager-DA_T0GHn.css +0 -1
- package/dist/client/assets/PluginManager-pW6RMz5z.js +0 -1
- package/dist/client/assets/SettingsModal-BWe0KrGY.css +0 -1
- package/dist/client/assets/SettingsModal-WGCF_pk8.js +0 -31
- package/dist/client/assets/index-D6ebxTPF.css +0 -1
- package/dist/client/assets/index-DYDLmOcK.js +0 -694
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion/pi-claude-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Fusion vendored fork: pi coding-agent extension that routes LLM calls through the Claude Code CLI. Forked from rchern/pi-claude-cli (MIT). See UPSTREAM.md.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": true,
|
|
@@ -51,10 +51,12 @@
|
|
|
51
51
|
|
|
52
52
|
.dependency-graph-edge.is-related {
|
|
53
53
|
stroke: var(--todo);
|
|
54
|
+
opacity: 1;
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
.dependency-graph-edge.is-dimmed {
|
|
57
|
-
|
|
58
|
+
stroke: var(--border);
|
|
59
|
+
opacity: 0.35;
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
.dependency-graph-node {
|
|
@@ -76,10 +78,13 @@
|
|
|
76
78
|
.dependency-graph-node.is-selected .card {
|
|
77
79
|
box-shadow: var(--focus-ring-strong);
|
|
78
80
|
border-color: var(--todo);
|
|
81
|
+
opacity: 1;
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
.dependency-graph-node.is-related:not(.is-selected) .card {
|
|
82
85
|
border-color: var(--in-progress);
|
|
86
|
+
box-shadow: var(--shadow-sm);
|
|
87
|
+
opacity: 1;
|
|
83
88
|
}
|
|
84
89
|
|
|
85
90
|
.dependency-graph-node.is-dimmed {
|
|
@@ -87,6 +92,10 @@
|
|
|
87
92
|
filter: saturate(0.8);
|
|
88
93
|
}
|
|
89
94
|
|
|
95
|
+
.dependency-graph-node.is-dimmed .card {
|
|
96
|
+
border-color: var(--border);
|
|
97
|
+
}
|
|
98
|
+
|
|
90
99
|
.dependency-graph-empty {
|
|
91
100
|
display: flex;
|
|
92
101
|
align-items: center;
|
|
@@ -112,8 +121,8 @@
|
|
|
112
121
|
}
|
|
113
122
|
|
|
114
123
|
.dependency-graph-controls .btn {
|
|
115
|
-
min-height:
|
|
116
|
-
min-width:
|
|
124
|
+
min-height: calc(var(--space-xs) * 11);
|
|
125
|
+
min-width: calc(var(--space-xs) * 11);
|
|
117
126
|
}
|
|
118
127
|
|
|
119
128
|
.dependency-graph-canvas {
|
|
@@ -20,12 +20,22 @@ describe("storage", () => {
|
|
|
20
20
|
localStorage.clear();
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
-
it("builds project-scoped key", () => {
|
|
24
|
-
expect(projectScopedKey("proj_123")).toBe("kb:proj_123:dependency-graph
|
|
23
|
+
it("builds project-scoped key with canonical base key", () => {
|
|
24
|
+
expect(projectScopedKey("proj_123")).toBe("kb:proj_123:fusion-plugin-dependency-graph:positions");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("falls back to unscoped key when projectId is missing or empty", () => {
|
|
28
|
+
expect(projectScopedKey()).toBe("fusion-plugin-dependency-graph:positions");
|
|
29
|
+
expect(projectScopedKey("")).toBe("fusion-plugin-dependency-graph:positions");
|
|
25
30
|
});
|
|
26
31
|
|
|
27
32
|
it("persists and restores positions", () => {
|
|
28
33
|
savePositions("proj_123", { "FN-1": { x: 10, y: 20 } });
|
|
29
34
|
expect(loadPositions("proj_123")).toEqual({ "FN-1": { x: 10, y: 20 } });
|
|
30
35
|
});
|
|
36
|
+
|
|
37
|
+
it("returns empty object for invalid JSON", () => {
|
|
38
|
+
localStorage.setItem("kb:proj_123:fusion-plugin-dependency-graph:positions", "not-json");
|
|
39
|
+
expect(loadPositions("proj_123")).toEqual({});
|
|
40
|
+
});
|
|
31
41
|
});
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
import { getScopedItem, scopedKey, setScopedItem } from "../../../packages/dashboard/app/utils/projectStorage";
|
|
2
|
+
|
|
3
|
+
const BASE_KEY = "fusion-plugin-dependency-graph:positions";
|
|
2
4
|
|
|
3
5
|
export function projectScopedKey(projectId?: string): string {
|
|
4
|
-
|
|
5
|
-
return `kb:${suffix}:${BASE_KEY}`;
|
|
6
|
+
return scopedKey(BASE_KEY, projectId);
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
export function loadPositions(projectId?: string): Record<string, { x: number; y: number }> {
|
|
9
|
-
if (typeof window === "undefined") return {};
|
|
10
10
|
try {
|
|
11
|
-
const raw =
|
|
11
|
+
const raw = getScopedItem(BASE_KEY, projectId);
|
|
12
12
|
if (!raw) return {};
|
|
13
13
|
const parsed = JSON.parse(raw) as Record<string, { x: number; y: number }>;
|
|
14
14
|
return parsed ?? {};
|
|
@@ -18,6 +18,5 @@ export function loadPositions(projectId?: string): Record<string, { x: number; y
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export function savePositions(projectId: string | undefined, positions: Record<string, { x: number; y: number }>): void {
|
|
21
|
-
|
|
22
|
-
window.localStorage.setItem(projectScopedKey(projectId), JSON.stringify(positions));
|
|
21
|
+
setScopedItem(BASE_KEY, JSON.stringify(positions), projectId);
|
|
23
22
|
}
|
|
@@ -83,7 +83,7 @@ function hermesProfileHome(profileName) {
|
|
|
83
83
|
async function listHermesProfiles(opts) {
|
|
84
84
|
const binary = resolveBinaryForSpawn(opts?.binaryPath ?? "hermes");
|
|
85
85
|
const timeoutMs = opts?.timeoutMs ?? 5e3;
|
|
86
|
-
return new Promise((
|
|
86
|
+
return new Promise((resolve2, reject) => {
|
|
87
87
|
let settled = false;
|
|
88
88
|
const child = spawn(binary, ["profile", "list"], {
|
|
89
89
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -126,7 +126,7 @@ async function listHermesProfiles(opts) {
|
|
|
126
126
|
${combined}`));
|
|
127
127
|
return;
|
|
128
128
|
}
|
|
129
|
-
|
|
129
|
+
resolve2(parseProfileListOutput(stdout));
|
|
130
130
|
});
|
|
131
131
|
});
|
|
132
132
|
}
|
|
@@ -203,7 +203,7 @@ function buildHermesArgs(prompt, settings, resumeSessionId) {
|
|
|
203
203
|
async function invokeHermesCli(prompt, settings, resumeSessionId, signal) {
|
|
204
204
|
const args = buildHermesArgs(prompt, settings, resumeSessionId);
|
|
205
205
|
const binary = resolveBinaryForSpawn(settings.binaryPath);
|
|
206
|
-
return new Promise((
|
|
206
|
+
return new Promise((resolve2, reject) => {
|
|
207
207
|
let settled = false;
|
|
208
208
|
const spawnEnv = { ...process.env, PYTHONUNBUFFERED: "1" };
|
|
209
209
|
if (settings.profile) {
|
|
@@ -271,7 +271,7 @@ ${combined}`));
|
|
|
271
271
|
return;
|
|
272
272
|
}
|
|
273
273
|
try {
|
|
274
|
-
|
|
274
|
+
resolve2(parseHermesOutput(stdout, stderr));
|
|
275
275
|
} catch (parseErr) {
|
|
276
276
|
reject(parseErr);
|
|
277
277
|
}
|
|
@@ -279,7 +279,161 @@ ${combined}`));
|
|
|
279
279
|
});
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
+
// ../../plugins/fusion-plugin-hermes-runtime/dist/fusion-skill-install.js
|
|
283
|
+
import { cpSync, existsSync, lstatSync, mkdirSync, readFileSync, readlinkSync, rmSync, symlinkSync, unlinkSync } from "node:fs";
|
|
284
|
+
import { homedir } from "node:os";
|
|
285
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
286
|
+
import { fileURLToPath } from "node:url";
|
|
287
|
+
var FUSION_SKILL_NAME = "fusion";
|
|
288
|
+
function resolveHermesHome(profile) {
|
|
289
|
+
const base = process.env.HERMES_HOME ?? join(homedir(), ".hermes");
|
|
290
|
+
if (!profile || profile === "default")
|
|
291
|
+
return base;
|
|
292
|
+
return join(base, "profiles", profile);
|
|
293
|
+
}
|
|
294
|
+
function getFusionSkillSourceCandidates(moduleUrl = import.meta.url) {
|
|
295
|
+
const here = fileURLToPath(moduleUrl);
|
|
296
|
+
const moduleDir = dirname(here);
|
|
297
|
+
return [
|
|
298
|
+
resolve(moduleDir, "..", "..", "..", "..", "packages", "cli", "skill", FUSION_SKILL_NAME),
|
|
299
|
+
resolve(moduleDir, "..", "..", "..", "skill", FUSION_SKILL_NAME),
|
|
300
|
+
resolve(moduleDir, "..", "..", "skill", FUSION_SKILL_NAME),
|
|
301
|
+
resolve(moduleDir, "..", "..", "..", "..", "skill", FUSION_SKILL_NAME)
|
|
302
|
+
];
|
|
303
|
+
}
|
|
304
|
+
function resolveBundledFusionSkillSource() {
|
|
305
|
+
const candidates = getFusionSkillSourceCandidates();
|
|
306
|
+
for (const candidate of candidates) {
|
|
307
|
+
if (existsSync(join(candidate, "SKILL.md")))
|
|
308
|
+
return candidate;
|
|
309
|
+
}
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
function installFusionSkillIntoHermesHome(options = {}) {
|
|
313
|
+
const sourceDir = options.sourceDir ?? resolveBundledFusionSkillSource();
|
|
314
|
+
const targetDir = join(resolveHermesHome(options.profile), "skills", FUSION_SKILL_NAME);
|
|
315
|
+
if (!sourceDir) {
|
|
316
|
+
return {
|
|
317
|
+
outcome: "warning",
|
|
318
|
+
sourceDir,
|
|
319
|
+
targetDir,
|
|
320
|
+
reason: "bundled Fusion skill source directory not found"
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
try {
|
|
324
|
+
mkdirSync(dirname(targetDir), { recursive: true });
|
|
325
|
+
let replaced = false;
|
|
326
|
+
if (existsSync(targetDir) || isBrokenSymlink(targetDir)) {
|
|
327
|
+
const stat = lstatSync(targetDir);
|
|
328
|
+
if (stat.isSymbolicLink()) {
|
|
329
|
+
const currentTarget = safeReadlink(targetDir);
|
|
330
|
+
if (currentTarget && resolve(dirname(targetDir), currentTarget) === resolve(sourceDir)) {
|
|
331
|
+
return { outcome: "already-installed", sourceDir, targetDir };
|
|
332
|
+
}
|
|
333
|
+
if (!looksLikeFusionSkillTarget(resolve(dirname(targetDir), currentTarget ?? ""))) {
|
|
334
|
+
return {
|
|
335
|
+
outcome: "skipped",
|
|
336
|
+
sourceDir,
|
|
337
|
+
targetDir,
|
|
338
|
+
reason: "existing symlink does not look like a Fusion skill install"
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
unlinkSync(targetDir);
|
|
342
|
+
replaced = true;
|
|
343
|
+
} else {
|
|
344
|
+
if (!looksLikePriorFusionInstall(targetDir)) {
|
|
345
|
+
return {
|
|
346
|
+
outcome: "skipped",
|
|
347
|
+
sourceDir,
|
|
348
|
+
targetDir,
|
|
349
|
+
reason: "existing directory does not look like a Fusion skill install"
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
rmSync(targetDir, { recursive: true, force: true });
|
|
353
|
+
replaced = true;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
try {
|
|
357
|
+
symlinkSync(sourceDir, targetDir, "dir");
|
|
358
|
+
} catch (error) {
|
|
359
|
+
const symlinkReason = error instanceof Error ? error.message : String(error);
|
|
360
|
+
try {
|
|
361
|
+
cpSync(sourceDir, targetDir, { recursive: true });
|
|
362
|
+
return {
|
|
363
|
+
outcome: replaced ? "replaced" : "installed",
|
|
364
|
+
sourceDir,
|
|
365
|
+
targetDir,
|
|
366
|
+
reason: `symlink failed (${symlinkReason}); copied files instead`
|
|
367
|
+
};
|
|
368
|
+
} catch (copyError) {
|
|
369
|
+
return {
|
|
370
|
+
outcome: "warning",
|
|
371
|
+
sourceDir,
|
|
372
|
+
targetDir,
|
|
373
|
+
reason: copyError instanceof Error ? copyError.message : String(copyError)
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return { outcome: replaced ? "replaced" : "installed", sourceDir, targetDir };
|
|
378
|
+
} catch (error) {
|
|
379
|
+
return {
|
|
380
|
+
outcome: "warning",
|
|
381
|
+
sourceDir,
|
|
382
|
+
targetDir,
|
|
383
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
function safeReadlink(path2) {
|
|
388
|
+
try {
|
|
389
|
+
return readlinkSync(path2);
|
|
390
|
+
} catch {
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
function isBrokenSymlink(path2) {
|
|
395
|
+
try {
|
|
396
|
+
const stat = lstatSync(path2);
|
|
397
|
+
return stat.isSymbolicLink() && !existsSync(path2);
|
|
398
|
+
} catch {
|
|
399
|
+
return false;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
function looksLikePriorFusionInstall(path2) {
|
|
403
|
+
const skillMd = join(path2, "SKILL.md");
|
|
404
|
+
if (!existsSync(skillMd))
|
|
405
|
+
return false;
|
|
406
|
+
try {
|
|
407
|
+
const body = readFileSync(skillMd, "utf-8");
|
|
408
|
+
return /\bfusion\b/i.test(body) && /\bskill\b/i.test(body);
|
|
409
|
+
} catch {
|
|
410
|
+
return false;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
function looksLikeFusionSkillTarget(path2) {
|
|
414
|
+
if (!path2)
|
|
415
|
+
return false;
|
|
416
|
+
if (basename(path2).toLowerCase() === FUSION_SKILL_NAME)
|
|
417
|
+
return true;
|
|
418
|
+
return existsSync(join(path2, "SKILL.md"));
|
|
419
|
+
}
|
|
420
|
+
|
|
282
421
|
// ../../plugins/fusion-plugin-hermes-runtime/dist/runtime-adapter.js
|
|
422
|
+
function buildRuntimeContextSection(options) {
|
|
423
|
+
const skillNames = Array.isArray(options.skills) ? options.skills.filter((value) => typeof value === "string" && value.trim().length > 0) : [];
|
|
424
|
+
const skillSelection = options.skillSelection;
|
|
425
|
+
const selectionSkillNames = Array.isArray(skillSelection?.requestedSkillNames) ? skillSelection.requestedSkillNames.filter((value) => typeof value === "string" && value.trim().length > 0) : [];
|
|
426
|
+
const mergedSkills = skillNames.length > 0 ? skillNames : selectionSkillNames;
|
|
427
|
+
const lines = [
|
|
428
|
+
"Fusion runtime context:",
|
|
429
|
+
`- Tool mode: ${options.tools ?? "coding"}`
|
|
430
|
+
];
|
|
431
|
+
if (mergedSkills.length > 0) {
|
|
432
|
+
lines.push(`- Requested skills: ${mergedSkills.join(", ")}`);
|
|
433
|
+
}
|
|
434
|
+
lines.push("- If fn_* tools are available in your runtime, use them directly for coordination/memory/task actions.");
|
|
435
|
+
return lines.join("\n");
|
|
436
|
+
}
|
|
283
437
|
var HermesRuntimeAdapter = class {
|
|
284
438
|
id = "hermes";
|
|
285
439
|
name = "Hermes Runtime";
|
|
@@ -302,13 +456,19 @@ var HermesRuntimeAdapter = class {
|
|
|
302
456
|
onToolStart: options.onToolStart,
|
|
303
457
|
onToolEnd: options.onToolEnd
|
|
304
458
|
},
|
|
459
|
+
runtimeContext: options.runtimeContext,
|
|
460
|
+
fusedSystemPrompt: [options.systemPrompt.trim(), buildRuntimeContextSection(options).trim()].filter((part) => part.length > 0).join("\n\n"),
|
|
305
461
|
dispose: () => void 0
|
|
306
462
|
};
|
|
307
463
|
return { session, sessionFile: void 0 };
|
|
308
464
|
}
|
|
309
465
|
async promptWithFallback(session, prompt, _options) {
|
|
310
466
|
const resumeId = session.sessionId || void 0;
|
|
311
|
-
const
|
|
467
|
+
const promptWithContext = resumeId ? prompt : `${session.fusedSystemPrompt}
|
|
468
|
+
|
|
469
|
+
User request:
|
|
470
|
+
${prompt}`;
|
|
471
|
+
const result = await invokeHermesCli(promptWithContext, this.settings, resumeId);
|
|
312
472
|
session.sessionId = result.sessionId;
|
|
313
473
|
session.lastModelDescription = this.describeFromSettings();
|
|
314
474
|
if (result.body) {
|
|
@@ -450,7 +610,13 @@ var plugin = definePlugin({
|
|
|
450
610
|
hooks: {
|
|
451
611
|
onLoad: (ctx) => {
|
|
452
612
|
const settings = resolveCliSettings(ctx.settings);
|
|
453
|
-
|
|
613
|
+
const skillInstall = installFusionSkillIntoHermesHome({ profile: settings.profile });
|
|
614
|
+
if (skillInstall.outcome === "warning") {
|
|
615
|
+
ctx.logger.warn(`Hermes Runtime Plugin: Fusion skill auto-install warning: ${skillInstall.reason ?? "unknown"}`);
|
|
616
|
+
} else if (skillInstall.outcome === "skipped") {
|
|
617
|
+
ctx.logger.warn(`Hermes Runtime Plugin: Fusion skill auto-install skipped: ${skillInstall.reason ?? "unknown"}`);
|
|
618
|
+
}
|
|
619
|
+
ctx.logger.info(`Hermes Runtime Plugin loaded \u2014 binary=${settings.binaryPath} model=${settings.model ?? "(default)"} fusionSkill=${skillInstall.outcome}`);
|
|
454
620
|
ctx.emitEvent("hermes-runtime:loaded", {
|
|
455
621
|
runtimeId: HERMES_RUNTIME_ID,
|
|
456
622
|
version: HERMES_RUNTIME_VERSION
|
|
@@ -472,9 +638,12 @@ export {
|
|
|
472
638
|
index_default as default,
|
|
473
639
|
hermesRuntimeFactory,
|
|
474
640
|
hermesRuntimeMetadata,
|
|
641
|
+
installFusionSkillIntoHermesHome,
|
|
475
642
|
invokeHermesCli,
|
|
476
643
|
listHermesProfiles,
|
|
477
644
|
parseHermesOutput,
|
|
478
645
|
probeHermesBinary,
|
|
479
|
-
|
|
646
|
+
resolveBundledFusionSkillSource,
|
|
647
|
+
resolveCliSettings,
|
|
648
|
+
resolveHermesHome
|
|
480
649
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runfusion/fusion",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Fusion CLI: HTTP API server, daemon, dashboard launcher, and task tooling for the Fusion AI coding agent.",
|
|
6
6
|
"homepage": "https://github.com/Runfusion/Fusion#readme",
|
|
@@ -4,6 +4,7 @@ These tools are **not** part of the user-invokable extension surface. They are i
|
|
|
4
4
|
|
|
5
5
|
- Source files: `packages/engine/src/agent-tools.ts`, `triage.ts`, `executor.ts`, `merger.ts`, `agent-heartbeat.ts`
|
|
6
6
|
- Availability: only when the engine creates a session for the matching agent role
|
|
7
|
+
- Runtime contract: engine sessions now forward requested skill names (`skillSelection.requestedSkillNames`) into the generic runtime `skills` field so non-pi runtimes can still receive Fusion skill intent.
|
|
7
8
|
- Important: do not tell users to call these directly from the generic extension tool list
|
|
8
9
|
|
|
9
10
|
## Shared runtime tools (`agent-tools.ts`)
|
|
@@ -28,8 +29,8 @@ These tools are **not** part of the user-invokable extension surface. They are i
|
|
|
28
29
|
| `fn_delegate_task` | triage, executor, heartbeat | Create and assign a new task to a specific agent | `agent_id` (string), `description` (string), `dependencies?` (string[]) |
|
|
29
30
|
| `fn_get_agent_config` | executor, heartbeat | Read full config for a direct-report agent | `agent_id` (string) |
|
|
30
31
|
| `fn_update_agent_config` | executor, heartbeat | Update config fields for a direct-report, non-ephemeral agent | `agent_id` (string), optional: `soul`, `instructions_text`, `instructions_path`, `heartbeat_procedure_path`, `heartbeat_interval_ms`, `heartbeat_timeout_ms`, `max_concurrent_runs`, `message_response_mode` |
|
|
31
|
-
| `fn_send_message` | executor, heartbeat | Send inbox messages to agents/users | `to_id` (string), `content` (string), `type?` (`agent-to-agent` \| `agent-to-user`), `reply_to_message_id?` (string) |
|
|
32
|
-
| `fn_read_messages` | executor, heartbeat | Read inbox messages | `unread_only?` (boolean), `limit?` (number) |
|
|
32
|
+
| `fn_send_message` | executor, step-session, heartbeat | Send inbox messages to agents/users | `to_id` (string), `content` (string), `type?` (`agent-to-agent` \| `agent-to-user`), `reply_to_message_id?` (string) |
|
|
33
|
+
| `fn_read_messages` | executor, step-session, heartbeat | Read inbox messages | `unread_only?` (boolean), `limit?` (number) |
|
|
33
34
|
|
|
34
35
|
## Triage-only runtime tools (`triage.ts`)
|
|
35
36
|
|
|
@@ -41,6 +42,8 @@ These tools are **not** part of the user-invokable extension surface. They are i
|
|
|
41
42
|
|
|
42
43
|
## Executor-only runtime tools (`executor.ts`)
|
|
43
44
|
|
|
45
|
+
Note: step-session execution (`step-session-executor.ts`) reuses executor coordination tools (`fn_send_message`, `fn_read_messages`, `fn_list_agents`, `fn_delegate_task`, task-document tools, and memory tools) so spawned/session-sliced execution keeps parity with main executor runs.
|
|
46
|
+
|
|
44
47
|
| Tool | Purpose | Parameters |
|
|
45
48
|
|---|---|---|
|
|
46
49
|
| `fn_task_update` | Update a spec step status (`pending`/`in-progress`/`done`/`skipped`) | `step` (number), `status` (enum) |
|