feat(plugins): core read-only scripts and user plugin system

Introduce plugin/<id> installs (zip, HTTPS git, example, fork),
jerapah-plugin.json manifests with jerapah semver ranges, isolated
plugin dirs under data/plugins, and app version 0.1.0. Core scripts
are non-editable; get-current-time moves to examples/plugins.

Co-authored-by: Nasyarobby Putra <nasyarobby@gmail.com>
This commit is contained in:
Cursor Agent
2026-08-19 16:04:00 +00:00
co-authored by nsrb
parent f66d0931bd
commit 611511ae60
23 changed files with 1843 additions and 132 deletions
+41
View File
@@ -89,6 +89,47 @@ export function useSaveScript() {
qc.invalidateQueries({ queryKey: ["scripts"] });
qc.invalidateQueries({ queryKey: ["scripts", vars.name] });
qc.invalidateQueries({ queryKey: ["dashboard"] });
qc.invalidateQueries({ queryKey: ["ops-status"] });
},
});
}
export function useCreatePlugin() {
const qc = useQueryClient();
return useMutation({
mutationFn: async ({ id, content, description }) =>
(await api.post("/plugins/create", { id, content, description })).data,
onSuccess: () => {
qc.invalidateQueries({ queryKey: ["scripts"] });
qc.invalidateQueries({ queryKey: ["ops-status"] });
},
});
}
export function useForkScript() {
const qc = useQueryClient();
return useMutation({
mutationFn: async ({ name, id, description }) =>
(
await api.post(`/scripts/${encodeURIComponent(name)}/fork`, {
id,
description,
})
).data,
onSuccess: () => {
qc.invalidateQueries({ queryKey: ["scripts"] });
qc.invalidateQueries({ queryKey: ["ops-status"] });
},
});
}
export function useInstallPlugin() {
const qc = useQueryClient();
return useMutation({
mutationFn: async (body) => (await api.post("/plugins/install", body)).data,
onSuccess: () => {
qc.invalidateQueries({ queryKey: ["scripts"] });
qc.invalidateQueries({ queryKey: ["ops-status"] });
},
});
}