mirror of
https://github.com/johndoe6345789/AutoMetabuilder.git
synced 2026-04-24 13:54:59 +00:00
Introduce AutoMetabuilder core components and workflow packages:
- Implement core components: CLI argument parsing, environment loading, GitHub service creation, and logging configuration. - Add support for OpenAI client setup and model resolution. - Develop SDLC context loader from GitHub and repository files. - Implement workflow context and engine builders. - Introduce major workflow packages: `game_tick_loop` and `contextual_iterative_loop`. - Update localization files with new package descriptions and labels. - Streamline web navigation by loading items from a dedicated JSON file.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useEffect } from "react";
|
||||
import { Alert, Snackbar } from "@mui/material";
|
||||
import DashboardSection from "../components/sections/DashboardSection";
|
||||
import PromptSection from "../components/sections/PromptSection";
|
||||
@@ -8,42 +8,29 @@ import SettingsSection from "../components/sections/SettingsSection";
|
||||
import TranslationsSection from "../components/sections/TranslationsSection";
|
||||
import WorkflowSection from "../components/sections/WorkflowSection";
|
||||
import PageLayout from "../components/layout/PageLayout";
|
||||
import useWebhook, { emitWebhook } from "../hooks/useWebhook";
|
||||
import {
|
||||
fetchContext,
|
||||
fetchWorkflowPackage,
|
||||
runBot,
|
||||
savePrompt,
|
||||
saveSettings,
|
||||
saveWorkflow,
|
||||
} from "../lib/api";
|
||||
import { UIContext } from "../lib/types";
|
||||
import useDashboardContext from "../hooks/useDashboardContext";
|
||||
import { emitWebhook, useWebhook } from "../hooks/useWebhook";
|
||||
import { fetchWorkflowPackage, runBot, savePrompt, saveSettings, saveWorkflow } from "../lib/api";
|
||||
|
||||
export default function HomePage() {
|
||||
const [context, setContext] = useState<UIContext | null>(null);
|
||||
const [selectedSection, setSelectedSection] = useState("dashboard");
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState("");
|
||||
const [snack, setSnack] = useState("");
|
||||
const [snackOpen, setSnackOpen] = useState(false);
|
||||
|
||||
const loadContext = async () => {
|
||||
setLoading(true);
|
||||
setError("");
|
||||
try {
|
||||
const data = await fetchContext();
|
||||
setContext(data);
|
||||
setSelectedSection((prev) => prev || data.navigation[0]?.section || "dashboard");
|
||||
} catch (err) {
|
||||
setError(String(err));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
const {
|
||||
context,
|
||||
selectedSection,
|
||||
setSelectedSection,
|
||||
loading,
|
||||
error,
|
||||
snack,
|
||||
setSnack,
|
||||
snackOpen,
|
||||
setSnackOpen,
|
||||
ready,
|
||||
loadContext,
|
||||
t,
|
||||
} = useDashboardContext();
|
||||
|
||||
useEffect(() => {
|
||||
void loadContext();
|
||||
}, []);
|
||||
}, [loadContext]);
|
||||
|
||||
useWebhook(
|
||||
"botRunComplete",
|
||||
@@ -55,39 +42,13 @@ export default function HomePage() {
|
||||
[]
|
||||
);
|
||||
|
||||
const t = useMemo(
|
||||
() => (key: string, fallback?: string) => context?.messages[key] ?? fallback ?? key,
|
||||
[context]
|
||||
);
|
||||
|
||||
const handleRun = async (payload: Parameters<typeof runBot>[0]) => {
|
||||
await runBot(payload);
|
||||
await loadContext();
|
||||
emitWebhook("runRequested", payload);
|
||||
};
|
||||
|
||||
const handleWorkflowSave = async (content: string) => {
|
||||
await saveWorkflow(content);
|
||||
emitWebhook("botRunComplete", payload);
|
||||
await loadContext();
|
||||
};
|
||||
|
||||
const handleTemplateSelect = async (id: string) => {
|
||||
const pkg = await fetchWorkflowPackage(id);
|
||||
const workflowPayload = JSON.stringify(pkg.workflow ?? {}, null, 2);
|
||||
setContext((prev) => (prev ? { ...prev, workflow_content: workflowPayload } : prev));
|
||||
};
|
||||
|
||||
const handlePromptSave = async (content: string) => {
|
||||
await savePrompt(content);
|
||||
await loadContext();
|
||||
};
|
||||
|
||||
const handleSettingsSave = async (values: Record<string, string>) => {
|
||||
await saveSettings(values);
|
||||
await loadContext();
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<main className="app-loading">
|
||||
<p>Loading dashboard…</p>
|
||||
@@ -95,7 +56,7 @@ export default function HomePage() {
|
||||
);
|
||||
}
|
||||
|
||||
if (error || !context) {
|
||||
if (error || !ready || !context) {
|
||||
return (
|
||||
<main className="app-loading">
|
||||
<p>{error || "Unable to load context."}</p>
|
||||
@@ -108,31 +69,54 @@ export default function HomePage() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageLayout
|
||||
navItems={context.navigation}
|
||||
section={selectedSection}
|
||||
onSectionChange={setSelectedSection}
|
||||
t={t}
|
||||
>
|
||||
{selectedSection === "dashboard" && (
|
||||
<DashboardSection logs={context.logs} status={context.status} onRun={handleRun} t={t} />
|
||||
)}
|
||||
{selectedSection === "workflow" && (
|
||||
<WorkflowSection
|
||||
content={context.workflow_content}
|
||||
packages={context.workflow_packages}
|
||||
onSave={handleWorkflowSave}
|
||||
onTemplateSelect={handleTemplateSelect}
|
||||
t={t}
|
||||
/>
|
||||
)}
|
||||
{selectedSection === "prompt" && <PromptSection content={context.prompt_content} onSave={handlePromptSave} t={t} />}
|
||||
{selectedSection === "settings" && (
|
||||
<SettingsSection envVars={context.env_vars} onSave={handleSettingsSave} t={t} />
|
||||
)}
|
||||
{selectedSection === "translations" && (
|
||||
<TranslationsSection languages={context.translations} onRefresh={loadContext} t={t} />
|
||||
)}
|
||||
<PageLayout navItems={context.navigation} section={selectedSection} onSectionChange={setSelectedSection} t={t}>
|
||||
{selectedSection === "dashboard" && (
|
||||
<DashboardSection logs={context.logs} status={context.status} onRun={handleRun} t={t} />
|
||||
)}
|
||||
{selectedSection === "workflow" && (
|
||||
<WorkflowSection
|
||||
content={context.workflow_content}
|
||||
packages={context.workflow_packages}
|
||||
onSave={async (content) => {
|
||||
await saveWorkflow(content);
|
||||
emitWebhook("workflow.save", { content });
|
||||
await loadContext();
|
||||
}}
|
||||
onTemplateSelect={async (id) => {
|
||||
const pkg = await fetchWorkflowPackage(id);
|
||||
if (pkg.workflow) {
|
||||
const workflowPayload = JSON.stringify(pkg.workflow ?? {}, null, 2);
|
||||
await saveWorkflow(workflowPayload);
|
||||
emitWebhook("workflow.template.selected", { id });
|
||||
await loadContext();
|
||||
}
|
||||
}}
|
||||
t={t}
|
||||
/>
|
||||
)}
|
||||
{selectedSection === "prompt" && (
|
||||
<PromptSection
|
||||
content={context.prompt_content}
|
||||
onSave={async (content) => {
|
||||
await savePrompt(content);
|
||||
emitWebhook("prompt.save", { content });
|
||||
await loadContext();
|
||||
}}
|
||||
t={t}
|
||||
/>
|
||||
)}
|
||||
{selectedSection === "settings" && (
|
||||
<SettingsSection
|
||||
envVars={context.env_vars}
|
||||
onSave={async (values) => {
|
||||
await saveSettings(values);
|
||||
emitWebhook("settings.save", { values });
|
||||
await loadContext();
|
||||
}}
|
||||
t={t}
|
||||
/>
|
||||
)}
|
||||
{selectedSection === "translations" && <TranslationsSection languages={context.translations} onRefresh={loadContext} t={t} />}
|
||||
</PageLayout>
|
||||
<Snackbar open={snackOpen} autoHideDuration={4000} onClose={() => setSnackOpen(false)}>
|
||||
<Alert onClose={() => setSnackOpen(false)} severity="info" sx={{ width: "100%" }}>
|
||||
|
||||
47
frontend/autometabuilder/hooks/useDashboardContext.ts
Normal file
47
frontend/autometabuilder/hooks/useDashboardContext.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { fetchContext } from "../lib/api";
|
||||
import { UIContext } from "../lib/types";
|
||||
|
||||
export default function useDashboardContext() {
|
||||
const [context, setContext] = useState<UIContext | null>(null);
|
||||
const [selectedSection, setSelectedSection] = useState("dashboard");
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState("");
|
||||
const [snack, setSnack] = useState("");
|
||||
const [snackOpen, setSnackOpen] = useState(false);
|
||||
|
||||
const loadContext = async () => {
|
||||
setLoading(true);
|
||||
setError("");
|
||||
try {
|
||||
const data = await fetchContext();
|
||||
setContext(data);
|
||||
setSelectedSection((prev) => prev || data.navigation[0]?.section || "dashboard");
|
||||
} catch (err) {
|
||||
setError(String(err));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const ready = context !== null;
|
||||
const t = useMemo(
|
||||
() => (key: string, fallback?: string) => (context?.messages[key] ?? fallback ?? key),
|
||||
[context]
|
||||
);
|
||||
|
||||
return {
|
||||
context,
|
||||
selectedSection,
|
||||
setSelectedSection,
|
||||
loading,
|
||||
error,
|
||||
snack,
|
||||
setSnack,
|
||||
snackOpen,
|
||||
setSnackOpen,
|
||||
loadContext,
|
||||
t,
|
||||
ready,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user