Add Submit to Antigravity or Codex for Development modal with model picker and deep links
This commit is contained in:
1 parent
b5af03b628
commit
92c5039bcb
6 files changed
+752
-1
No files matched your search
+101
-1
@@ -19,8 +19,11 @@ import {
|
||||
} from "./nano_banana.js";
|
||||
import {
|
||||
DEFAULT_USER_BACKGROUND,
|
||||
DEV_HANDOFF_TARGETS,
|
||||
generatePersonalizedRandomIdea,
|
||||
generateNameSuggestions
|
||||
generateNameSuggestions,
|
||||
buildDevelopmentSpecMarkdown,
|
||||
executeDevelopmentHandoff
|
||||
} from "./idea_generator.js";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
@@ -257,6 +260,103 @@ export function createAppServer({
|
||||
return sendJson(res, 200, result);
|
||||
}
|
||||
|
||||
// 3c. GET /api/ideas/:id/spec.md (Download / Fetch Compiled Development Spec)
|
||||
const specMdMatch = pathname.match(/^\/api\/ideas\/(\d+)\/spec\.md$/);
|
||||
if (method === "GET" && specMdMatch) {
|
||||
const id = Number(specMdMatch[1]);
|
||||
const idea = store.getIdea(id);
|
||||
if (!idea) return sendJson(res, 404, { error: "Idea not found" });
|
||||
|
||||
const targetApp = parsedUrl.searchParams.get("target") || "antigravity";
|
||||
const model = parsedUrl.searchParams.get("model") || "";
|
||||
const includeHomelab = parsedUrl.searchParams.get("includeHomelab") !== "false";
|
||||
const userBackground =
|
||||
store.getSetting("user_background", DEFAULT_USER_BACKGROUND) || DEFAULT_USER_BACKGROUND;
|
||||
const host = req.headers.host || "sparkvault.vloser.us";
|
||||
const proto = req.headers["x-forwarded-proto"] || "https";
|
||||
const publicBaseUrl = `${proto}://${host}`;
|
||||
|
||||
const md = buildDevelopmentSpecMarkdown({
|
||||
idea,
|
||||
targetApp,
|
||||
model,
|
||||
includeHomelab,
|
||||
publicBaseUrl,
|
||||
userBackground
|
||||
});
|
||||
|
||||
res.writeHead(200, {
|
||||
"Content-Type": "text/markdown; charset=utf-8",
|
||||
"Content-Disposition": `attachment; filename="spark-${idea.id}-spec.md"`
|
||||
});
|
||||
res.end(md);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3d. POST /api/ideas/:id/dev-handoff (Submit Idea to Antigravity or Codex for Development)
|
||||
const devHandoffMatch = pathname.match(/^\/api\/ideas\/(\d+)\/dev-handoff$/);
|
||||
if (method === "POST" && devHandoffMatch) {
|
||||
const id = Number(devHandoffMatch[1]);
|
||||
const idea = store.getIdea(id);
|
||||
if (!idea) return sendJson(res, 404, { error: "Idea not found" });
|
||||
|
||||
const body = await readJsonBody(req);
|
||||
const targetApp = body.targetApp === "codex" ? "codex" : "antigravity";
|
||||
const model = String(body.model || "").trim();
|
||||
const customPrompt = String(body.customPrompt || "").trim();
|
||||
const extraInstructions = String(body.extraInstructions || "").trim();
|
||||
const includeHomelab = body.includeHomelab !== false;
|
||||
const moveStatusToBuilding = body.moveStatusToBuilding !== false;
|
||||
const executeServerCodex = Boolean(body.executeServerCodex);
|
||||
|
||||
const userBackground =
|
||||
store.getSetting("user_background", DEFAULT_USER_BACKGROUND) || DEFAULT_USER_BACKGROUND;
|
||||
const host = req.headers.host || "sparkvault.vloser.us";
|
||||
const proto = req.headers["x-forwarded-proto"] || "https";
|
||||
const publicBaseUrl = `${proto}://${host}`;
|
||||
const workspacesRootDir = path.join(path.dirname(mockupsDir), "dev_workspaces");
|
||||
|
||||
const handoff = await executeDevelopmentHandoff({
|
||||
idea,
|
||||
targetApp,
|
||||
model,
|
||||
customPrompt,
|
||||
includeHomelab,
|
||||
extraInstructions,
|
||||
executeServerCodex,
|
||||
publicBaseUrl,
|
||||
userBackground,
|
||||
workspacesRootDir
|
||||
});
|
||||
|
||||
// Record the handoff on the Spark and optionally move to "building"
|
||||
const handoffAttachment = {
|
||||
id: `dev-${Date.now()}`,
|
||||
type: "note",
|
||||
title: `🚀 Submitted to ${handoff.targetLabel} (${handoff.model})`,
|
||||
textContent: handoff.codexExecution?.output
|
||||
? `Submitted to ${handoff.targetLabel} using model ${handoff.model}.\n\n--- CODEX IMPLEMENTATION PLAN ---\n${handoff.codexExecution.output}`
|
||||
: `Submitted full Spark specification to ${handoff.targetLabel} using model \`${handoff.model}\`.`,
|
||||
sourceUrl: handoff.specUrl,
|
||||
imageUrl: "",
|
||||
createdAt: handoff.submittedAt
|
||||
};
|
||||
|
||||
const patch = {
|
||||
attachments: [handoffAttachment, ...(idea.attachments || [])]
|
||||
};
|
||||
if (moveStatusToBuilding && (idea.status === "spark" || idea.status === "exploring")) {
|
||||
patch.status = "building";
|
||||
}
|
||||
const updatedIdea = store.updateIdea(id, patch);
|
||||
|
||||
return sendJson(res, 200, {
|
||||
idea: updatedIdea,
|
||||
handoff,
|
||||
devTargets: DEV_HANDOFF_TARGETS
|
||||
});
|
||||
}
|
||||
|
||||
// 4. GET /api/whack-cards
|
||||
if (method === "GET" && pathname === "/api/whack-cards") {
|
||||
const allIdeas = store.listIdeas({});
|
||||
|
||||
Reference in new issue
Block a user