Add Submit to Antigravity or Codex for Development modal with model picker and deep links

This commit is contained in:
airent106 committed 2026-10-29 22:30:48 -06:00
1 parent b5af03b628
commit 92c5039bcb
6 files changed
+752 -1

No files matched your search

+101 -1
View File
@@ -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({});