@runfusion/fusion 0.4.1 → 1.0.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 +34074 -34923
- package/dist/client/assets/{AgentDetailView-sy6Hg1Xr.js → AgentDetailView-dhJd4os0.js} +6 -11
- package/dist/client/assets/{AgentsView-DpEpW88a.js → AgentsView-CYVTv2_l.js} +3 -3
- package/dist/client/assets/{ChatView-BUt3C4cf.js → ChatView-ByPhfQZ6.js} +1 -1
- package/dist/client/assets/{DevServerView-BOyWtQJM.js → DevServerView-CD7mgC11.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-BJyEEso5.js → DirectoryPicker-Cm0FCC9M.js} +1 -1
- package/dist/client/assets/{DocumentsView-Dx0M1YHw.js → DocumentsView-oB319uCj.js} +1 -1
- package/dist/client/assets/{InsightsView-BtXdAo7D.js → InsightsView-BHdMNnOa.js} +1 -1
- package/dist/client/assets/{MemoryView-kKPuqmwf.js → MemoryView-BDJMlzlM.js} +1 -1
- package/dist/client/assets/{NodesView-B_ZwUORz.js → NodesView-BfOlOj-Q.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-Db0EGr0Q.js → PiExtensionsManager-D-IznnkU.js} +2 -2
- package/dist/client/assets/{PluginManager-mOwWndfg.js → PluginManager-D40uAE-p.js} +1 -1
- package/dist/client/assets/{RoadmapsView-DbUzBLeF.js → RoadmapsView-DtgL8yl3.js} +1 -1
- package/dist/client/assets/{SettingsModal-TRJu_mTn.js → SettingsModal-0IyoaKEv.js} +1 -1
- package/dist/client/assets/SettingsModal-D1vZdAS4.js +31 -0
- package/dist/client/assets/{SetupWizardModal-D1bmCQrf.js → SetupWizardModal-BaQ8VkZm.js} +1 -1
- package/dist/client/assets/{SkillsView-Dzzpd5Md.js → SkillsView-DAvaRl37.js} +1 -1
- package/dist/client/assets/TodoView-BXRQSmSw.js +1 -0
- package/dist/client/assets/TodoView-DNi8blBB.css +1 -0
- package/dist/client/assets/{folder-open-BcuByk6U.js → folder-open-BJ4SvamV.js} +1 -1
- package/dist/client/assets/index-B7TDbn3p.css +1 -0
- package/dist/client/assets/index-CGW6tOaX.js +631 -0
- package/dist/client/assets/list-checks-CpGwz9gV.js +6 -0
- package/dist/client/assets/{upload-BzNbXYEj.js → upload-DJYyvab0.js} +1 -1
- package/dist/client/assets/{users-BvIqhSXp.js → users-ndAFpylb.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/extension.js +3262 -599
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/pi-claude-cli/src/__tests__/process-manager.test.ts +50 -17
- package/dist/pi-claude-cli/src/__tests__/setup-test-isolation.test.ts +30 -0
- package/dist/pi-claude-cli/src/__tests__/setup-test-isolation.ts +6 -0
- package/package.json +5 -5
- package/skill/fusion/references/extension-tools.md +5 -5
- package/skill/fusion/references/fusion-capabilities.md +5 -5
- package/dist/client/assets/SettingsModal-Bs_lNs5B.js +0 -31
- package/dist/client/assets/index-BipedNj4.css +0 -1
- package/dist/client/assets/index-k2c4LrUr.js +0 -616
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion/pi-claude-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.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,
|
|
@@ -23,11 +23,27 @@ vi.mock("node:child_process", () => ({
|
|
|
23
23
|
execSync: vi.fn(),
|
|
24
24
|
}));
|
|
25
25
|
|
|
26
|
+
const mocks = vi.hoisted(() => ({
|
|
27
|
+
writeFileSync: vi.fn(),
|
|
28
|
+
unlinkSync: vi.fn(),
|
|
29
|
+
existsSync: vi.fn(),
|
|
30
|
+
readFileSync: vi.fn(),
|
|
31
|
+
tmpdir: vi.fn(() => "/mock-tmp"),
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
vi.mock("node:fs", () => ({
|
|
35
|
+
writeFileSync: mocks.writeFileSync,
|
|
36
|
+
unlinkSync: mocks.unlinkSync,
|
|
37
|
+
existsSync: mocks.existsSync,
|
|
38
|
+
readFileSync: mocks.readFileSync,
|
|
39
|
+
}));
|
|
40
|
+
|
|
41
|
+
vi.mock("node:os", () => ({
|
|
42
|
+
tmpdir: mocks.tmpdir,
|
|
43
|
+
}));
|
|
44
|
+
|
|
26
45
|
import spawn from "cross-spawn";
|
|
27
46
|
import { execSync } from "node:child_process";
|
|
28
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
29
|
-
import { join } from "node:path";
|
|
30
|
-
import { tmpdir } from "node:os";
|
|
31
47
|
import {
|
|
32
48
|
spawnClaude,
|
|
33
49
|
writeUserMessage,
|
|
@@ -44,6 +60,11 @@ import {
|
|
|
44
60
|
describe("spawnClaude", () => {
|
|
45
61
|
beforeEach(() => {
|
|
46
62
|
vi.clearAllMocks();
|
|
63
|
+
mocks.writeFileSync.mockReset();
|
|
64
|
+
mocks.existsSync.mockReset();
|
|
65
|
+
mocks.readFileSync.mockReset();
|
|
66
|
+
mocks.tmpdir.mockReset();
|
|
67
|
+
mocks.tmpdir.mockReturnValue("/mock-tmp");
|
|
47
68
|
});
|
|
48
69
|
|
|
49
70
|
it("spawns claude with all required CLI flags", () => {
|
|
@@ -94,20 +115,27 @@ describe("spawnClaude", () => {
|
|
|
94
115
|
it("writes system prompt to temp file and passes path via --append-system-prompt", () => {
|
|
95
116
|
spawnClaude("claude-sonnet-4-5-20250929", "You are a helpful assistant.");
|
|
96
117
|
const args = (spawn as any).mock.calls[0][1] as string[];
|
|
118
|
+
const expectedTmpFile = `/mock-tmp/pi-claude-cli-sysprompt-${process.pid}.txt`;
|
|
97
119
|
|
|
120
|
+
expect(mocks.writeFileSync).toHaveBeenCalledWith(
|
|
121
|
+
expectedTmpFile,
|
|
122
|
+
"You are a helpful assistant.",
|
|
123
|
+
"utf-8",
|
|
124
|
+
);
|
|
98
125
|
expect(args).toContain("--append-system-prompt");
|
|
99
126
|
const idx = args.indexOf("--append-system-prompt");
|
|
100
127
|
expect(args[idx + 1]).toContain("pi-claude-cli-sysprompt-");
|
|
128
|
+
expect(args[idx + 1]).toBe(expectedTmpFile);
|
|
101
129
|
});
|
|
102
130
|
|
|
103
131
|
it("temp file contains the system prompt text", () => {
|
|
104
132
|
spawnClaude("claude-sonnet-4-5-20250929", "You are a helpful assistant.");
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
133
|
+
|
|
134
|
+
expect(mocks.writeFileSync).toHaveBeenCalledWith(
|
|
135
|
+
`/mock-tmp/pi-claude-cli-sysprompt-${process.pid}.txt`,
|
|
136
|
+
"You are a helpful assistant.",
|
|
137
|
+
"utf-8",
|
|
108
138
|
);
|
|
109
|
-
expect(existsSync(tmpFile)).toBe(true);
|
|
110
|
-
expect(readFileSync(tmpFile, "utf-8")).toBe("You are a helpful assistant.");
|
|
111
139
|
});
|
|
112
140
|
|
|
113
141
|
it("does not include --append-system-prompt when no system prompt", () => {
|
|
@@ -599,21 +627,26 @@ describe("resume session flag", () => {
|
|
|
599
627
|
});
|
|
600
628
|
|
|
601
629
|
describe("cleanupSystemPromptFile", () => {
|
|
602
|
-
|
|
630
|
+
beforeEach(() => {
|
|
631
|
+
vi.clearAllMocks();
|
|
632
|
+
mocks.unlinkSync.mockReset();
|
|
633
|
+
mocks.tmpdir.mockReset();
|
|
634
|
+
mocks.tmpdir.mockReturnValue("/mock-tmp");
|
|
635
|
+
});
|
|
603
636
|
|
|
604
637
|
it("deletes the temp file when it exists", () => {
|
|
605
|
-
// Create the file by spawning with a system prompt
|
|
606
|
-
spawnClaude("claude-sonnet-4-5-20250929", "test prompt");
|
|
607
|
-
expect(existsSync(tmpFile)).toBe(true);
|
|
608
|
-
|
|
609
638
|
cleanupSystemPromptFile();
|
|
610
|
-
|
|
639
|
+
|
|
640
|
+
expect(mocks.unlinkSync).toHaveBeenCalledWith(
|
|
641
|
+
`/mock-tmp/pi-claude-cli-sysprompt-${process.pid}.txt`,
|
|
642
|
+
);
|
|
611
643
|
});
|
|
612
644
|
|
|
613
645
|
it("does not throw when file does not exist", () => {
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
646
|
+
mocks.unlinkSync.mockImplementation(() => {
|
|
647
|
+
throw new Error("ENOENT");
|
|
648
|
+
});
|
|
649
|
+
|
|
617
650
|
expect(() => cleanupSystemPromptFile()).not.toThrow();
|
|
618
651
|
});
|
|
619
652
|
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { homedir, tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
|
|
5
|
+
const TEMP_HOME_PREFIX = "fn-test-home-";
|
|
6
|
+
|
|
7
|
+
describe("test isolation setup", () => {
|
|
8
|
+
it("overrides process.env.HOME to a temp directory", () => {
|
|
9
|
+
const home = process.env.HOME;
|
|
10
|
+
|
|
11
|
+
expect(home).toBeDefined();
|
|
12
|
+
expect(home).toContain(tmpdir());
|
|
13
|
+
expect(home).toContain(TEMP_HOME_PREFIX);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("resolves homedir() to the temp HOME", () => {
|
|
17
|
+
const home = homedir();
|
|
18
|
+
|
|
19
|
+
expect(home).toContain(tmpdir());
|
|
20
|
+
expect(home).toContain(TEMP_HOME_PREFIX);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("resolves ~/.pi/agent/AGENTS.md under the temp HOME", () => {
|
|
24
|
+
const agentsPath = join(homedir(), ".pi", "agent", "AGENTS.md");
|
|
25
|
+
|
|
26
|
+
expect(agentsPath).toContain(tmpdir());
|
|
27
|
+
expect(agentsPath).toContain(TEMP_HOME_PREFIX);
|
|
28
|
+
expect(agentsPath).toMatch(/fn-test-home-.*[\\/]\.pi[\\/]agent[\\/]AGENTS\.md$/);
|
|
29
|
+
});
|
|
30
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runfusion/fusion",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.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",
|
|
@@ -75,10 +75,10 @@
|
|
|
75
75
|
"typescript": "^5.7.0",
|
|
76
76
|
"vitest": "^3.1.0",
|
|
77
77
|
"yaml": "^2.8.3",
|
|
78
|
-
"@fusion/
|
|
79
|
-
"@fusion/dashboard": "0.
|
|
80
|
-
"@fusion/
|
|
81
|
-
"@fusion/
|
|
78
|
+
"@fusion/engine": "1.0.0",
|
|
79
|
+
"@fusion/dashboard": "1.0.0",
|
|
80
|
+
"@fusion/core": "1.0.0",
|
|
81
|
+
"@fusion/pi-claude-cli": "1.0.0"
|
|
82
82
|
},
|
|
83
83
|
"repository": {
|
|
84
84
|
"type": "git",
|
|
@@ -10,7 +10,7 @@ All tools are registered via the pi extension. They are available in any pi agen
|
|
|
10
10
|
|
|
11
11
|
### fn_task_create
|
|
12
12
|
|
|
13
|
-
Create a new task on the Fusion task board. The task enters the
|
|
13
|
+
Create a new task on the Fusion task board. The task enters the planning column where the AI planning agent will plan it into a full prompt with steps, file scope, and acceptance criteria.
|
|
14
14
|
|
|
15
15
|
| Parameter | Type | Required | Description |
|
|
16
16
|
|-----------|------|----------|-------------|
|
|
@@ -82,7 +82,7 @@ Retry a failed task — clears the error state and moves it back to the todo col
|
|
|
82
82
|
|
|
83
83
|
### fn_task_duplicate
|
|
84
84
|
|
|
85
|
-
Duplicate an existing task, creating a fresh copy in
|
|
85
|
+
Duplicate an existing task, creating a fresh copy in planning. Copies the title and description but resets all execution state. The AI planning agent will replan the new task.
|
|
86
86
|
|
|
87
87
|
| Parameter | Type | Required | Description |
|
|
88
88
|
|-----------|------|----------|-------------|
|
|
@@ -90,7 +90,7 @@ Duplicate an existing task, creating a fresh copy in triage. Copies the title an
|
|
|
90
90
|
|
|
91
91
|
### fn_task_refine
|
|
92
92
|
|
|
93
|
-
Request a refinement of a completed or in-review task. Creates a new follow-up task in
|
|
93
|
+
Request a refinement of a completed or in-review task. Creates a new follow-up task in planning that references the original task as a dependency. Use this when a done or in-review task needs additional work, improvements, or follow-up changes.
|
|
94
94
|
|
|
95
95
|
| Parameter | Type | Required | Description |
|
|
96
96
|
|-----------|------|----------|-------------|
|
|
@@ -133,7 +133,7 @@ Create a task via AI-guided planning mode — interactive conversation to refine
|
|
|
133
133
|
|
|
134
134
|
### fn_task_import_github
|
|
135
135
|
|
|
136
|
-
Import GitHub issues as Fusion tasks. Fetches open issues from a repository and creates tasks in the
|
|
136
|
+
Import GitHub issues as Fusion tasks. Fetches open issues from a repository and creates tasks in the planning column. Each task includes the issue title and body with a link to the source issue.
|
|
137
137
|
|
|
138
138
|
| Parameter | Type | Required | Description |
|
|
139
139
|
|-----------|------|----------|-------------|
|
|
@@ -143,7 +143,7 @@ Import GitHub issues as Fusion tasks. Fetches open issues from a repository and
|
|
|
143
143
|
|
|
144
144
|
### fn_task_import_github_issue
|
|
145
145
|
|
|
146
|
-
Import a specific GitHub issue as a Fusion task. Fetches the issue by number and creates a single task in the
|
|
146
|
+
Import a specific GitHub issue as a Fusion task. Fetches the issue by number and creates a single task in the planning column with the issue title and body.
|
|
147
147
|
|
|
148
148
|
| Parameter | Type | Required | Description |
|
|
149
149
|
|-----------|------|----------|-------------|
|
|
@@ -12,7 +12,7 @@ All skill/extension tool invocations in this catalog use the public `fn_*` names
|
|
|
12
12
|
<!-- BEGIN: fusion-capabilities-tool-table (auto-generated by scripts/sync-fusion-skill-tools.mjs — do not edit by hand) -->
|
|
13
13
|
| Tool | Purpose |
|
|
14
14
|
|------|---------|
|
|
15
|
-
| `fn_task_create` | Create a new task on the Fusion task board. The task enters the
|
|
15
|
+
| `fn_task_create` | Create a new task on the Fusion task board. The task enters the planning column where the AI planning agent will plan it into a full prompt with steps, file scope, and acceptance criteria. |
|
|
16
16
|
| `fn_task_update` | Update fields on an existing task. Supports modifying the title, description, dependencies, and assigned agent after task creation. |
|
|
17
17
|
| `fn_task_list` | List all tasks on the Fusion board, grouped by column. |
|
|
18
18
|
| `fn_task_show` | Show full details for a task including steps, progress, and log entries. |
|
|
@@ -20,13 +20,13 @@ All skill/extension tool invocations in this catalog use the public `fn_*` names
|
|
|
20
20
|
| `fn_task_pause` | Pause a task — stops all automated agent and scheduler interaction for this task. |
|
|
21
21
|
| `fn_task_unpause` | Unpause a task — resumes automated agent and scheduler interaction. |
|
|
22
22
|
| `fn_task_retry` | Retry a failed task — clears the error state and moves it back to the todo column for re-execution. |
|
|
23
|
-
| `fn_task_duplicate` | Duplicate an existing task, creating a fresh copy in
|
|
24
|
-
| `fn_task_refine` | Request a refinement of a completed or in-review task. Creates a new follow-up task in
|
|
23
|
+
| `fn_task_duplicate` | Duplicate an existing task, creating a fresh copy in planning. Copies the title and description but resets all execution state. The AI planning agent will replan the new task. |
|
|
24
|
+
| `fn_task_refine` | Request a refinement of a completed or in-review task. Creates a new follow-up task in planning that references the original task as a dependency. Use this when a done or in-review task needs additional work, improvements, or follow-up changes. |
|
|
25
25
|
| `fn_task_archive` | Archive a done task (move from done → archived). Archived tasks are preserved for historical reference but moved out of the main board view. |
|
|
26
26
|
| `fn_task_unarchive` | Unarchive an archived task (move from archived → done). Restores the task to the done column. |
|
|
27
27
|
| `fn_task_delete` | Permanently delete a task from the Fusion board. Tasks are deleted immediately and cannot be recovered. |
|
|
28
|
-
| `fn_task_import_github` | Import GitHub issues as Fusion tasks. Fetches open issues from a repository and creates tasks in the
|
|
29
|
-
| `fn_task_import_github_issue` | Import a specific GitHub issue as a Fusion task. Fetches the issue by number and creates a single task in the
|
|
28
|
+
| `fn_task_import_github` | Import GitHub issues as Fusion tasks. Fetches open issues from a repository and creates tasks in the planning column. Each task includes the issue title and body with a link to the source issue. |
|
|
29
|
+
| `fn_task_import_github_issue` | Import a specific GitHub issue as a Fusion task. Fetches the issue by number and creates a single task in the planning column with the issue title and body. |
|
|
30
30
|
| `fn_task_browse_github_issues` | List open GitHub issues from a repository to browse before importing. Returns issue numbers, titles, and URLs for selection. Use with fn_task_import_github_issue to import specific issues by number. |
|
|
31
31
|
| `fn_task_plan` | Create a task via AI-guided planning mode — interactive conversation to refine your idea into a well-specified task. |
|
|
32
32
|
| `fn_mission_create` | Create a new mission — a high-level objective that can span multiple milestones. Missions contain milestones that break down work into phases. |
|