@runfusion/fusion 0.28.1 → 0.30.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.
Files changed (88) hide show
  1. package/dist/bin.js +13194 -3642
  2. package/dist/client/assets/AgentDetailView-CY-O6VkV.css +1 -0
  3. package/dist/client/assets/AgentDetailView-Cu4TgvBn.js +18 -0
  4. package/dist/client/assets/AgentPermissionPolicyEditor-Ceg2Dszn.js +6 -0
  5. package/dist/client/assets/AgentPermissionPolicyEditor-CthjqUL_.css +1 -0
  6. package/dist/client/assets/AgentsView-BI_CESkd.css +1 -0
  7. package/dist/client/assets/AgentsView-CIH4Acck.js +34 -0
  8. package/dist/client/assets/ChatView-DqJoFquZ.js +1 -0
  9. package/dist/client/assets/DevServerView-Bd8JZ-3C.js +1 -0
  10. package/dist/client/assets/{DirectoryPicker-BfShQutV.js → DirectoryPicker-BOGqZNiq.js} +1 -1
  11. package/dist/client/assets/DocumentsView-B-ELcw4o.js +1 -0
  12. package/dist/client/assets/EvalsView-Ccl9QBYN.js +1 -0
  13. package/dist/client/assets/{ExperimentalAgentOnboardingModal-CtR7eRBv.js → ExperimentalAgentOnboardingModal-BM7EnSvJ.js} +1 -1
  14. package/dist/client/assets/ExperimentalAgentOnboardingModal-BNpveCEk.css +1 -0
  15. package/dist/client/assets/{InsightsView-BGbXkJpz.js → InsightsView-DLF49bzu.js} +3 -3
  16. package/dist/client/assets/{MemoryView-CRbaCcG_.js → MemoryView-CE1D9euM.js} +2 -2
  17. package/dist/client/assets/{NodesView-Hjxwv7rE.js → NodesView-Zxusnhxu.js} +2 -2
  18. package/dist/client/assets/{PiExtensionsManager-ckNj1Wvv.js → PiExtensionsManager-BlMmxtLZ.js} +2 -2
  19. package/dist/client/assets/PluginManager-BJQXdUmV.css +1 -0
  20. package/dist/client/assets/PluginManager-D4eZ0zA4.js +1 -0
  21. package/dist/client/assets/ReliabilityView-KmH60I_5.js +1 -0
  22. package/dist/client/assets/ReliabilityView-rxA_HgEG.css +1 -0
  23. package/dist/client/assets/ResearchView-C14Zh7c9.js +1 -0
  24. package/dist/client/assets/ResearchView-DTh8FLUm.css +1 -0
  25. package/dist/client/assets/SettingsModal-BAx4gt2A.css +1 -0
  26. package/dist/client/assets/{SettingsModal-Bqfq-gnu.js → SettingsModal-DRnZ6eBW.js} +1 -1
  27. package/dist/client/assets/SettingsModal-c1QwWno0.js +31 -0
  28. package/dist/client/assets/SettingsModal-sp7SNwS9.css +1 -0
  29. package/dist/client/assets/SetupWizardModal-BmmRM3g-.js +1 -0
  30. package/dist/client/assets/SkillsView-CUbSBeZ2.css +1 -0
  31. package/dist/client/assets/SkillsView-DWVtT2-8.js +1 -0
  32. package/dist/client/assets/StashRecoveryView-CKkaWzzc.js +1 -0
  33. package/dist/client/assets/{TodoView-CDtkPdrq.js → TodoView-hbD0NOCY.js} +2 -2
  34. package/dist/client/assets/dashboard-view-VNPB3ca0.js +21 -0
  35. package/dist/client/assets/{folder-open-D8Qfxakh.js → folder-open-BTN2_Wuv.js} +1 -1
  36. package/dist/client/assets/index-CZFBq256.css +1 -0
  37. package/dist/client/assets/index-DzSLVOnp.js +695 -0
  38. package/dist/client/assets/{upload-BHiYszS2.js → upload-euJEs_N2.js} +1 -1
  39. package/dist/client/assets/{users-Ch_Fnf5M.js → users-B7miEHCZ.js} +1 -1
  40. package/dist/client/assets/vendor-codemirror-jBKmHyH0.js +27 -0
  41. package/dist/client/index.html +3 -2
  42. package/dist/client/version.json +1 -1
  43. package/dist/droid-cli/package.json +1 -1
  44. package/dist/extension.js +9987 -1944
  45. package/dist/pi-claude-cli/package.json +1 -1
  46. package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
  47. package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/registration.test.ts +20 -3
  48. package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/workflow-integration.test.ts +103 -8
  49. package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/workflow-steps-verdict-contract.test.ts +42 -0
  50. package/dist/plugins/fusion-plugin-cli-printing-press/src/index.ts +4 -0
  51. package/dist/plugins/fusion-plugin-cli-printing-press/src/workflow-steps.ts +14 -0
  52. package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
  53. package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
  54. package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
  55. package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
  56. package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
  57. package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
  58. package/dist/plugins/fusion-plugin-reports/package.json +1 -1
  59. package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
  60. package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
  61. package/package.json +1 -1
  62. package/skill/fusion/SKILL.md +2 -2
  63. package/skill/fusion/references/extension-tools.md +28 -5
  64. package/skill/fusion/references/fusion-capabilities.md +7 -5
  65. package/dist/client/assets/AgentDetailView-DG01uRND.js +0 -18
  66. package/dist/client/assets/AgentDetailView-DSpIqBOs.css +0 -1
  67. package/dist/client/assets/AgentsView-B3ADnF0D.css +0 -1
  68. package/dist/client/assets/AgentsView-B6IKroR1.js +0 -34
  69. package/dist/client/assets/ChatView-DKstOyUm.js +0 -1
  70. package/dist/client/assets/DevServerView-DQQcGd2N.js +0 -1
  71. package/dist/client/assets/DocumentsView-C4Ky-ZkQ.js +0 -1
  72. package/dist/client/assets/EvalsView-B-z_KLLW.js +0 -1
  73. package/dist/client/assets/ExperimentalAgentOnboardingModal-B-APN_lM.css +0 -1
  74. package/dist/client/assets/PluginManager-C4UoLv4U.css +0 -1
  75. package/dist/client/assets/PluginManager-CpY9rYNq.js +0 -1
  76. package/dist/client/assets/ResearchView-BMxwiVk9.js +0 -1
  77. package/dist/client/assets/ResearchView-C7uXon3o.css +0 -1
  78. package/dist/client/assets/SettingsModal-3Jxv4PMI.js +0 -31
  79. package/dist/client/assets/SettingsModal-Ci0_sqbU.css +0 -1
  80. package/dist/client/assets/SettingsModal-DWKgRxBA.css +0 -1
  81. package/dist/client/assets/SetupWizardModal-SVUr5Mpm.js +0 -1
  82. package/dist/client/assets/SkillsView-COs7muvr.js +0 -1
  83. package/dist/client/assets/SkillsView-Cytf009Z.css +0 -1
  84. package/dist/client/assets/StashRecoveryView-BhB_6Fvq.js +0 -1
  85. package/dist/client/assets/dashboard-view-Czurx3BJ.js +0 -21
  86. package/dist/client/assets/index-CD0_dkME.css +0 -1
  87. package/dist/client/assets/index-u6AOHWO5.js +0 -692
  88. package/dist/client/assets/star-BkCn1oUu.js +0 -6
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion/pi-claude-cli",
3
- "version": "0.28.1",
3
+ "version": "0.30.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,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/cli-printing-press",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "type": "module",
5
5
  "description": "CLI Printing Press plugin package for Fusion",
6
6
  "private": true,
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
  import { validatePluginManifest } from "@fusion/core";
3
- import plugin from "../index.js";
3
+ import plugin, { CLI_PRINTING_PRESS_WORKFLOW_STEPS } from "../index.js";
4
4
  import { ensureCliPressSchema } from "../store/cli-press-store.js";
5
5
  import { makeFakeRegistry } from "./fixtures/registry.js";
6
6
 
@@ -18,10 +18,27 @@ describe("plugin registration contracts", () => {
18
18
  expect(plugin.routes?.some((route) => route.path === "/drafts")).toBe(true);
19
19
  expect(plugin.dashboardViews?.map((view) => view.viewId)).toEqual(["wizard", "manage"]);
20
20
  expect(typeof plugin.executorRuntimeEnv).toBe("function");
21
- // FN-4150/FN-3768 track future workflow step template contributions.
22
- expect(plugin.workflowStepTemplates).toBeUndefined();
21
+ expect(plugin.workflowSteps?.length).toBeGreaterThan(0);
23
22
  } finally {
24
23
  h.cleanup();
25
24
  }
26
25
  });
26
+
27
+ it("contributes script-mode workflow step templates", () => {
28
+ expect(plugin.workflowSteps?.length).toBeGreaterThan(0);
29
+ expect(plugin.workflowSteps).toEqual(CLI_PRINTING_PRESS_WORKFLOW_STEPS);
30
+
31
+ for (const step of plugin.workflowSteps ?? []) {
32
+ expect(step.stepId).toMatch(/^[a-z0-9]+(?:-[a-z0-9]+)*$/);
33
+ }
34
+
35
+ expect(
36
+ plugin.workflowSteps?.some((step) => step.mode === "script" && step.phase === "pre-merge"),
37
+ ).toBe(true);
38
+
39
+ expect(plugin.manifest.workflowSteps?.map((step) => step.stepId)).toEqual(
40
+ plugin.workflowSteps?.map((step) => step.stepId),
41
+ );
42
+ expect(validatePluginManifest(plugin.manifest).valid).toBe(true);
43
+ });
27
44
  });
@@ -1,22 +1,117 @@
1
- import { describe, expect, it } from "vitest";
1
+ import { exec } from "node:child_process";
2
+ import { mkdtemp, rm } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { promisify } from "node:util";
6
+ import { afterEach, describe, expect, it } from "vitest";
7
+ import { TaskStore, type WorkflowStepTemplate } from "@fusion/core";
2
8
  import plugin from "../index.js";
3
9
  import { installExecMock } from "./fixtures/exec-mock.js";
4
10
 
11
+ const execAsync = promisify(exec);
12
+
13
+ async function makeTaskStore() {
14
+ const rootDir = await mkdtemp(join(tmpdir(), "fn-4150-cli-printing-press-"));
15
+ const globalDir = await mkdtemp(join(tmpdir(), "fn-4150-cli-printing-press-global-"));
16
+ const store = new TaskStore(rootDir, globalDir, { inMemoryDb: true });
17
+ await store.init();
18
+ return { store, rootDir, globalDir };
19
+ }
20
+
21
+ async function cleanupTaskStore(ctx: Awaited<ReturnType<typeof makeTaskStore>>) {
22
+ ctx.store.stopWatching();
23
+ ctx.store.close();
24
+ await rm(ctx.rootDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 50 });
25
+ await rm(ctx.globalDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 50 });
26
+ }
27
+
28
+ function injectPluginTemplates(store: TaskStore): void {
29
+ const templates: Array<{ pluginId: string; template: WorkflowStepTemplate }> = (plugin.workflowSteps ?? []).map((template) => ({
30
+ pluginId: plugin.manifest.id,
31
+ template: {
32
+ id: `plugin:${plugin.manifest.id}:${template.stepId}`,
33
+ name: template.name,
34
+ description: template.description,
35
+ prompt: template.prompt ?? "",
36
+ mode: template.mode,
37
+ phase: template.phase,
38
+ scriptName: template.scriptName,
39
+ toolMode: template.toolMode,
40
+ defaultOn: template.defaultOn,
41
+ modelProvider: template.modelProvider,
42
+ modelId: template.modelId,
43
+ enabled: template.enabled,
44
+ category: "Plugin",
45
+ icon: "puzzle",
46
+ },
47
+ }));
48
+ store.setPluginWorkflowStepTemplates(templates);
49
+ }
50
+
51
+ async function runScriptStepFromSettings(store: TaskStore, scriptName: string): Promise<{ stdout: string; stderr: string }> {
52
+ const settings = await store.getSettings();
53
+ const command = settings.scripts?.[scriptName];
54
+ if (!command) {
55
+ throw new Error(`Missing script command for ${scriptName}`);
56
+ }
57
+ return execAsync(command, { timeout: 20_000, maxBuffer: 5 * 1024 * 1024 });
58
+ }
59
+
5
60
  describe("workflow integration contracts", () => {
6
- // FN-4150/FN-3768 track future workflow-step template + runWorkflowSteps coverage.
61
+ const stores: Array<Awaited<ReturnType<typeof makeTaskStore>>> = [];
62
+
63
+ afterEach(async () => {
64
+ while (stores.length > 0) {
65
+ const ctx = stores.pop();
66
+ if (ctx) {
67
+ await cleanupTaskStore(ctx);
68
+ }
69
+ }
70
+ });
71
+
7
72
  it("guards against execSync usage in workflow-oriented execution fixtures", () => {
8
73
  const execMock = installExecMock();
9
74
  execMock.assertExecSyncUnused();
10
75
  expect(typeof plugin.manifest.id).toBe("string");
11
76
  });
12
77
 
13
- it("does not currently contribute plugin workflow step templates", () => {
14
- expect(plugin.workflowStepTemplates).toBeUndefined();
78
+ it("materializes plugin script-mode workflow step through TaskStore", async () => {
79
+ const ctx = await makeTaskStore();
80
+ stores.push(ctx);
81
+ injectPluginTemplates(ctx.store);
82
+
83
+ const step = await ctx.store.getWorkflowStep("plugin:fusion-plugin-cli-printing-press:run-service-cli");
84
+ expect(step).toMatchObject({
85
+ id: "plugin:fusion-plugin-cli-printing-press:run-service-cli",
86
+ mode: "script",
87
+ phase: "pre-merge",
88
+ scriptName: "cli-printing-press:run-service-cli",
89
+ });
15
90
  });
16
91
 
17
- it("exposes no plugin workflow step IDs to runWorkflowSteps today", () => {
18
- const workflowStepTemplates = plugin.workflowStepTemplates ?? [];
19
- expect(workflowStepTemplates).toEqual([]);
20
- expect(workflowStepTemplates.some((template) => template.id.startsWith("plugin:"))).toBe(false);
92
+ it("runs a plugin script-mode step end-to-end via TaskStore plus project scripts", async () => {
93
+ const execMock = installExecMock();
94
+ execMock.setNextResult({ stdout: "ok\n", stderr: "", code: 0 });
95
+
96
+ const ctx = await makeTaskStore();
97
+ stores.push(ctx);
98
+ injectPluginTemplates(ctx.store);
99
+
100
+ await ctx.store.updateSettings({
101
+ scripts: {
102
+ "cli-printing-press:run-service-cli": "echo ok",
103
+ },
104
+ });
105
+
106
+ const step = await ctx.store.getWorkflowStep("plugin:fusion-plugin-cli-printing-press:run-service-cli");
107
+ expect(step).toMatchObject({
108
+ mode: "script",
109
+ scriptName: "cli-printing-press:run-service-cli",
110
+ phase: "pre-merge",
111
+ });
112
+
113
+ const result = await runScriptStepFromSettings(ctx.store, step!.scriptName!);
114
+ expect(result.stdout).toContain("ok");
115
+ execMock.assertExecSyncUnused();
21
116
  });
22
117
  });
@@ -0,0 +1,42 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { CLI_PRINTING_PRESS_WORKFLOW_STEPS } from "../workflow-steps.js";
3
+
4
+ describe("cli-printing-press workflow step verdict contract", () => {
5
+ it("exports a non-empty workflow step contribution list", () => {
6
+ expect(CLI_PRINTING_PRESS_WORKFLOW_STEPS.length).toBeGreaterThan(0);
7
+ });
8
+
9
+ it("requires script-mode steps to declare a non-empty scriptName", () => {
10
+ const scriptSteps = CLI_PRINTING_PRESS_WORKFLOW_STEPS.filter((step) => step.mode === "script");
11
+ expect(scriptSteps.length).toBeGreaterThan(0);
12
+
13
+ for (const step of scriptSteps) {
14
+ expect(step.scriptName?.trim().length ?? 0).toBeGreaterThan(0);
15
+ }
16
+ });
17
+
18
+ const promptSteps = CLI_PRINTING_PRESS_WORKFLOW_STEPS.filter((step) => step.mode === "prompt");
19
+
20
+ // Prompt-mode slice may be empty today; invariant activates automatically when prompt entries are added.
21
+ if (promptSteps.length === 0) {
22
+ it("has no prompt-mode steps today; invariant guard is dormant", () => {
23
+ expect(promptSteps).toHaveLength(0);
24
+ });
25
+ }
26
+
27
+ it.each(promptSteps.map((step) => [step.stepId, step] as const))(
28
+ "enforces structured verdict prompt contract for %s",
29
+ (_stepId, step) => {
30
+ expect(typeof step.prompt).toBe("string");
31
+ expect(step.prompt?.trim().length ?? 0).toBeGreaterThan(0);
32
+
33
+ const prompt = step.prompt ?? "";
34
+ expect(prompt).toMatch(/\{\s*"verdict"\s*:\s*"APPROVE\|APPROVE_WITH_NOTES\|REVISE"\s*,\s*"notes"\s*:/);
35
+ expect(prompt).not.toContain('"verdict":"PASS"');
36
+ expect(prompt).not.toContain('"verdict":"FAIL"');
37
+ expect(prompt).not.toContain("task_done(");
38
+ expect(prompt).not.toContain("task_log(");
39
+ expect(prompt).toMatch(/out of scope|Diff Scope/i);
40
+ },
41
+ );
42
+ });
@@ -2,6 +2,7 @@ import { definePlugin } from "@fusion/plugin-sdk";
2
2
  import { createCliPrintingPressRoutes } from "./routes/wizard-routes.js";
3
3
  import { buildExecutorRuntimeEnv } from "./runtime/executor-runtime-env.js";
4
4
  import { createCliPressStore, ensureCliPressSchema } from "./store/cli-press-store.js";
5
+ import { CLI_PRINTING_PRESS_WORKFLOW_STEPS } from "./workflow-steps.js";
5
6
 
6
7
  const storeByDb = new WeakMap<object, ReturnType<typeof createCliPressStore>>();
7
8
 
@@ -20,6 +21,7 @@ const plugin = definePlugin({
20
21
  name: "CLI Printing Press",
21
22
  version: "0.1.0",
22
23
  description: "Guided wizard for drafting external service CLI definitions",
24
+ workflowSteps: CLI_PRINTING_PRESS_WORKFLOW_STEPS.map((step) => ({ stepId: step.stepId, name: step.name })),
23
25
  },
24
26
  state: "installed",
25
27
  hooks: {
@@ -30,6 +32,7 @@ const plugin = definePlugin({
30
32
  const store = getStore(ctx.taskStore as { getDatabase: () => object });
31
33
  return buildExecutorRuntimeEnv(store, taskCtx, ctx);
32
34
  },
35
+ workflowSteps: CLI_PRINTING_PRESS_WORKFLOW_STEPS,
33
36
  dashboardViews: [
34
37
  {
35
38
  viewId: "wizard",
@@ -55,4 +58,5 @@ export { CliPrintingPressWizardView } from "./dashboard-view.js";
55
58
  export { CliPrintingPressManageView } from "./manage-view.js";
56
59
  export { CliPrintingPressTestRunner } from "./run/TestRunnerPanel.js";
57
60
  export { createCliPressStore, ensureCliPressSchema } from "./store/cli-press-store.js";
61
+ export { CLI_PRINTING_PRESS_WORKFLOW_STEPS } from "./workflow-steps.js";
58
62
  export * from "./store/cli-press-types.js";
@@ -0,0 +1,14 @@
1
+ import type { PluginWorkflowStepContribution } from "@fusion/plugin-sdk";
2
+
3
+ export const CLI_PRINTING_PRESS_WORKFLOW_STEPS: PluginWorkflowStepContribution[] = [
4
+ {
5
+ stepId: "run-service-cli",
6
+ name: "Run Service CLI",
7
+ description: "Run generated service CLI checks before merge using the task project script map.",
8
+ mode: "script",
9
+ phase: "pre-merge",
10
+ scriptName: "cli-printing-press:run-service-cli",
11
+ enabled: true,
12
+ defaultOn: false,
13
+ },
14
+ ];
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/cursor-runtime",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/dependency-graph",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/droid-runtime",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/hermes-runtime",
3
- "version": "0.2.38",
3
+ "version": "0.2.40",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/openclaw-runtime",
3
- "version": "0.2.38",
3
+ "version": "0.2.40",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/paperclip-runtime",
3
- "version": "0.2.38",
3
+ "version": "0.2.40",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/reports",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "type": "module",
5
5
  "description": "Reports plugin for Fusion",
6
6
  "private": true,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/roadmap",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/whatsapp-chat",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "type": "module",
5
5
  "description": "WhatsApp Web (Baileys) chat bridge for Fusion agents",
6
6
  "keywords": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runfusion/fusion",
3
- "version": "0.28.1",
3
+ "version": "0.30.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",
@@ -29,11 +29,11 @@ Mission → Milestone → Slice → Feature → Task
29
29
  <!-- BEGIN: tool-categories (auto-generated by scripts/sync-fusion-skill-tools.mjs — do not edit by hand) -->
30
30
  - **Task tools** — `fn_task_create`, `fn_task_update`, `fn_task_list`, `fn_task_show`, `fn_task_attach`, `fn_task_pause`, `fn_task_unpause`, `fn_task_retry`, `fn_task_duplicate`, `fn_task_refine`, `fn_task_archive`, `fn_task_unarchive`, `fn_task_delete`, `fn_task_plan`
31
31
  - **GitHub tools** — `fn_task_import_github`, `fn_task_import_github_issue`, `fn_task_browse_github_issues`
32
- - **Mission tools** — `fn_mission_create`, `fn_mission_list`, `fn_mission_show`, `fn_mission_delete`, `fn_milestone_add`, `fn_slice_add`, `fn_feature_add`, `fn_slice_activate`, `fn_feature_link_task`
32
+ - **Mission tools** — `fn_mission_create`, `fn_mission_list`, `fn_mission_show`, `fn_mission_delete`, `fn_milestone_add`, `fn_slice_add`, `fn_feature_add`, `fn_slice_activate`, `fn_feature_link_task`, `fn_feature_update`
33
33
  - **Agent tools** — `fn_agent_stop`, `fn_agent_start`, `fn_agent_create`, `fn_agent_delete`, `fn_list_agents`, `fn_delegate_task`, `fn_agent_show`, `fn_agent_org_chart`
34
34
  - **Skills tools** — `fn_skills_search`, `fn_skills_install`
35
35
  - **Insight tools** — `fn_insight_list`, `fn_insight_show`, `fn_insight_run_list`, `fn_insight_run_show`
36
- - **Other tools** — `fn_web_fetch`, `fn_research_run`, `fn_research_list`, `fn_research_get`, `fn_research_cancel`, `fn_research_retry`
36
+ - **Other tools** — `fn_web_fetch`, `fn_research_run`, `fn_research_list`, `fn_research_get`, `fn_research_cancel`, `fn_research_retry`, `fn_experiment_finalize`
37
37
  <!-- END: tool-categories -->
38
38
  - **Dashboard** — Use `/fn` command to start/stop the dashboard
39
39
 
@@ -248,6 +248,17 @@ Link a feature to a fn task for implementation. Updates the feature status to 't
248
248
  | `featureId` | string | ✓ | Feature ID to link (e.g., F-001) |
249
249
  | `taskId` | string | ✓ | Task ID to link to (e.g., FN-001) |
250
250
 
251
+ ### fn_feature_update
252
+
253
+ Update an existing feature's title, description, or acceptance criteria. Partial patches leave untouched fields intact.
254
+
255
+ | Parameter | Type | Required | Description |
256
+ |-----------|------|----------|-------------|
257
+ | `id` | string | ✓ | Feature ID to update (e.g., F-001) |
258
+ | `title` | string | — | Updated feature title |
259
+ | `description` | string | — | Updated feature description |
260
+ | `acceptanceCriteria` | string | — | Updated acceptance criteria for completing the feature |
261
+
251
262
  ## Agent Tools
252
263
 
253
264
  ### fn_agent_stop
@@ -407,7 +418,7 @@ Lightweight URL fetch (no JS rendering). Use agent-browser skill for JS-heavy pa
407
418
 
408
419
  ### fn_research_run
409
420
 
410
- Start a bounded research run and optionally wait for findings.
421
+ Cited-research pipeline: create a bounded search/fetch/synthesis run (not an autonomous experiment loop) and optionally wait for completion.
411
422
 
412
423
  | Parameter | Type | Required | Description |
413
424
  |-----------|------|----------|-------------|
@@ -417,7 +428,7 @@ Start a bounded research run and optionally wait for findings.
417
428
 
418
429
  ### fn_research_list
419
430
 
420
- List recent research runs.
431
+ Cited-research pipeline: list recent search/fetch/synthesis runs (not experiment-loop sessions).
421
432
 
422
433
  | Parameter | Type | Required | Description |
423
434
  |-----------|------|----------|-------------|
@@ -426,7 +437,7 @@ List recent research runs.
426
437
 
427
438
  ### fn_research_get
428
439
 
429
- Get one research run and structured findings.
440
+ Cited-research pipeline: get one run with structured findings and citations (not experiment-loop state).
430
441
 
431
442
  | Parameter | Type | Required | Description |
432
443
  |-----------|------|----------|-------------|
@@ -434,7 +445,7 @@ Get one research run and structured findings.
434
445
 
435
446
  ### fn_research_cancel
436
447
 
437
- Cancel an in-flight research run. Terminal runs return INVALID_TRANSITION.
448
+ Cited-research pipeline: cancel an in-flight run; terminal runs return INVALID_TRANSITION (does not control experiment loops).
438
449
 
439
450
  | Parameter | Type | Required | Description |
440
451
  |-----------|------|----------|-------------|
@@ -442,12 +453,24 @@ Cancel an in-flight research run. Terminal runs return INVALID_TRANSITION.
442
453
 
443
454
  ### fn_research_retry
444
455
 
445
- Retry a failed research run when lifecycle marks it retryable.
456
+ Cited-research pipeline: retry a failed run when lifecycle marks it retryable (not an autonomous experiment loop retry).
446
457
 
447
458
  | Parameter | Type | Required | Description |
448
459
  |-----------|------|----------|-------------|
449
460
  | `id` | string | ✓ | Research run ID |
450
461
 
462
+ ### fn_experiment_finalize
463
+
464
+ Group kept experiment runs into reviewable branches and finalize the session. Use dryRun=true to preview the plan without touching git.
465
+
466
+ | Parameter | Type | Required | Description |
467
+ |-----------|------|----------|-------------|
468
+ | `sessionId` | string | ✓ | Experiment session ID |
469
+ | `integrationBranch` | string | — | Integration branch to compute merge-base against (default: main) |
470
+ | `dryRun` | boolean | — | Preview plan only; do not create branches |
471
+ | `planOverride` | unknown | — | Optional plan override payload |
472
+ | `summary` | string | — | Optional finalize summary |
473
+
451
474
  <!-- END: extension-tools -->
452
475
  ## Dashboard Command
453
476
 
@@ -30,11 +30,12 @@ All skill/extension tool invocations in this catalog use the public `fn_*` names
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_web_fetch` | Lightweight URL fetch (no JS rendering). Use agent-browser skill for JS-heavy pages. URL to fetch (http/https) Optional extraction hint for downstream summarization Timeout in milliseconds (default: 30000) Max bytes to return (default: 512000) |
33
- | `fn_research_run` | Start a bounded research run and optionally wait for findings. |
34
- | `fn_research_list` | List recent research runs. |
35
- | `fn_research_get` | Get one research run and structured findings. |
36
- | `fn_research_cancel` | Cancel an in-flight research run. Terminal runs return INVALID_TRANSITION. |
37
- | `fn_research_retry` | Retry a failed research run when lifecycle marks it retryable. |
33
+ | `fn_research_run` | Cited-research pipeline: create a bounded search/fetch/synthesis run (not an autonomous experiment loop) and optionally wait for completion. |
34
+ | `fn_research_list` | Cited-research pipeline: list recent search/fetch/synthesis runs (not experiment-loop sessions). |
35
+ | `fn_research_get` | Cited-research pipeline: get one run with structured findings and citations (not experiment-loop state). |
36
+ | `fn_research_cancel` | Cited-research pipeline: cancel an in-flight run; terminal runs return INVALID_TRANSITION (does not control experiment loops). |
37
+ | `fn_research_retry` | Cited-research pipeline: retry a failed run when lifecycle marks it retryable (not an autonomous experiment loop retry). |
38
+ | `fn_experiment_finalize` | Group kept experiment runs into reviewable branches and finalize the session. Use dryRun=true to preview the plan without touching git. |
38
39
  | `fn_insight_list` | List persisted project insights with optional category/status filters. |
39
40
  | `fn_insight_show` | Show a single persisted insight by ID. |
40
41
  | `fn_insight_run_list` | List recent insight-generation runs with optional status/trigger filters. |
@@ -48,6 +49,7 @@ All skill/extension tool invocations in this catalog use the public `fn_*` names
48
49
  | `fn_feature_add` | Add a feature to a slice. Features are deliverables that can be linked to tasks. |
49
50
  | `fn_slice_activate` | Activate a pending slice for implementation. Sets status to 'active' and enables task linking for its features. |
50
51
  | `fn_feature_link_task` | Link a feature to a fn task for implementation. Updates the feature status to 'triaged' and associates it with the task. |
52
+ | `fn_feature_update` | Update an existing feature's title, description, or acceptance criteria. Partial patches leave untouched fields intact. |
51
53
  | `fn_agent_stop` | Stop a running agent — pauses its execution. Transitions the agent from running/active to paused state. |
52
54
  | `fn_agent_start` | Start a stopped agent — resumes its execution. Transitions the agent from paused to active state. |
53
55
  | `fn_agent_create` | Create a new non-ephemeral agent. |