fix(FN-000): backup routine uses npx runfusion.ai; alias exposes fn/fusion

Backup automation now emits `npx runfusion.ai backup --create` so scheduled
backups work for users on the zero-install path where `fn` is not on PATH.

`runfusion.ai` also exposes `fn` and `fusion` bins, so `npm i -g runfusion.ai`
puts them on PATH (npm does not link dep bins globally). Alias only defaults
to the dashboard when invoked as `runfusion.ai` / `runfusion`; `fn` / `fusion`
forward args verbatim so bare `fn` still prints help.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-04-22 19:19:07 -07:00
parent 88ccd2d4e2
commit dd37cdc5b4
6 changed files with 31 additions and 20 deletions

View File

@@ -674,7 +674,7 @@ export function RoutineEditor({ routine, onSubmit, onCancel, scope: formScope, p
{simpleActionType === "command" ? (
<div className="form-group">
<label htmlFor="routine-command">Command</label>
<input id="routine-command" type="text" placeholder="e.g. fn backup --create" value={command} onChange={(e) => setCommand(e.target.value)} aria-invalid={!!errors.command} aria-describedby={errors.command ? commandErrorId : undefined} />
<input id="routine-command" type="text" placeholder="e.g. npx runfusion.ai backup --create" value={command} onChange={(e) => setCommand(e.target.value)} aria-invalid={!!errors.command} aria-describedby={errors.command ? commandErrorId : undefined} />
{errors.command ? <small id={commandErrorId} className="field-error">{errors.command}</small> : <small>Shell command to execute.</small>}
</div>
) : simpleActionType === "ai-prompt" ? (

View File

@@ -118,7 +118,7 @@ describe("ScheduledTasksModal", () => {
it("shows routine cards and the new automation button when routines exist", async () => {
mockFetchRoutines.mockResolvedValue([
makeRoutine({ name: "Database Backup", command: "fn backup --create" }),
makeRoutine({ name: "Database Backup", command: "npx runfusion.ai backup --create" }),
]);
render(<ScheduledTasksModal onClose={onClose} addToast={addToast} />);
@@ -126,7 +126,7 @@ describe("ScheduledTasksModal", () => {
await waitFor(() => {
expect(screen.getByText("Database Backup")).toBeDefined();
});
expect(screen.getByText("fn backup --create")).toBeDefined();
expect(screen.getByText("npx runfusion.ai backup --create")).toBeDefined();
expect(screen.getByText("New Automation")).toBeDefined();
});