mirror of
https://github.com/basketikun/infinite-canvas.git
synced 2026-08-05 08:54:23 +08:00
feat: rename package to @basketikun/canvas-agent and update related configurations
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import express, { type NextFunction, type Request, type Response } from "express";
|
||||
|
||||
import { DEFAULT_PORT, loadConfig, saveConfig, type CanvasAgentConfig } from "./config.js";
|
||||
import { DEFAULT_PORT, ensureCanvasWorkspace, loadConfig, saveConfig, updateCanvasWorkspace, type CanvasAgentConfig } from "./config.js";
|
||||
import { CanvasSession } from "./canvas-session.js";
|
||||
import { runClaudeTurn, runCodexTurn, withAgentPrompt } from "./agents.js";
|
||||
import { archiveCodexThread, listCodexThreads, readCodexThread, resumeCodexThread, runClaudeTurn, runCodexTurn, startCodexThread, summarizeCodexThread, withAgentPrompt } from "./agents.js";
|
||||
import type { AgentAttachment } from "./types.js";
|
||||
|
||||
export function startHttpServer() {
|
||||
@@ -38,10 +38,53 @@ export function startHttpServer() {
|
||||
res.json({ ok: true });
|
||||
});
|
||||
app.post("/api/tools", route(async (req, res) => res.json({ ok: true, result: await session.callTool(req.body?.name, req.body?.input || {}) })));
|
||||
app.get("/agent/codex/workspace", (req, res) => {
|
||||
const workspace = ensureCanvasWorkspace(config, String(req.query.canvasId || ""));
|
||||
res.json({ ok: true, workspace });
|
||||
});
|
||||
app.get("/agent/codex/threads", route(async (req, res) => {
|
||||
const workspace = ensureCanvasWorkspace(config, String(req.query.canvasId || ""));
|
||||
const result = await listCodexThreads(emit, { cwd: workspace.workspacePath, all: req.query.all === "1", searchTerm: String(req.query.searchTerm || "") });
|
||||
res.json({ ok: true, workspace, ...result });
|
||||
}));
|
||||
app.post("/agent/codex/threads/new", route(async (req, res) => {
|
||||
const workspace = ensureCanvasWorkspace(config, String(req.body?.canvasId || ""));
|
||||
const thread = await startCodexThread(emit, workspace.workspacePath);
|
||||
const activeThreadId = String((thread as Record<string, unknown>).id || "");
|
||||
updateCanvasWorkspace(config, workspace.canvasId, { activeThreadId });
|
||||
res.json({ ok: true, workspace: { ...workspace, activeThreadId }, thread: summarizeCodexThread(thread), messages: [] });
|
||||
}));
|
||||
app.get("/agent/codex/threads/:threadId", route(async (req, res) => {
|
||||
const threadId = routeParam(req.params.threadId);
|
||||
res.json({ ok: true, ...(await readCodexThread(emit, threadId)) });
|
||||
}));
|
||||
app.post("/agent/codex/threads/:threadId/resume", route(async (req, res) => {
|
||||
const workspace = ensureCanvasWorkspace(config, String(req.body?.canvasId || ""));
|
||||
const threadId = routeParam(req.params.threadId);
|
||||
const result = await resumeCodexThread(emit, threadId, workspace.workspacePath);
|
||||
updateCanvasWorkspace(config, workspace.canvasId, { activeThreadId: threadId });
|
||||
res.json({ ok: true, workspace: { ...workspace, activeThreadId: threadId }, ...result });
|
||||
}));
|
||||
app.post("/agent/codex/threads/:threadId/delete", route(async (req, res) => {
|
||||
const workspace = ensureCanvasWorkspace(config, String(req.body?.canvasId || ""));
|
||||
const threadId = routeParam(req.params.threadId);
|
||||
await archiveCodexThread(emit, threadId);
|
||||
if (workspace.activeThreadId === threadId) updateCanvasWorkspace(config, workspace.canvasId, { activeThreadId: undefined });
|
||||
res.json({ ok: true });
|
||||
}));
|
||||
app.post("/agent/codex/turn", route(async (req, res) => {
|
||||
const attachments = Array.isArray(req.body?.attachments) ? (req.body.attachments as AgentAttachment[]) : [];
|
||||
void runCodexTurn(withAgentPrompt(String(req.body?.prompt || "")), emit, attachments);
|
||||
res.json({ ok: true });
|
||||
const workspace = ensureCanvasWorkspace(config, String(req.body?.canvasId || ""));
|
||||
let threadId = String(req.body?.threadId || workspace.activeThreadId || "");
|
||||
if (!threadId) {
|
||||
const thread = await startCodexThread(emit, workspace.workspacePath);
|
||||
threadId = String((thread as Record<string, unknown>).id || "");
|
||||
updateCanvasWorkspace(config, workspace.canvasId, { activeThreadId: threadId });
|
||||
} else if (threadId !== workspace.activeThreadId) {
|
||||
updateCanvasWorkspace(config, workspace.canvasId, { activeThreadId: threadId });
|
||||
}
|
||||
void runCodexTurn(withAgentPrompt(String(req.body?.prompt || "")), emit, attachments, { threadId, cwd: workspace.workspacePath });
|
||||
res.json({ ok: true, threadId });
|
||||
}));
|
||||
app.post("/agent/claude/turn", (req, res) => {
|
||||
runClaudeTurn(withAgentPrompt(String(req.body?.prompt || "")), emit);
|
||||
@@ -54,7 +97,7 @@ export function startHttpServer() {
|
||||
console.log("Infinite Canvas Agent");
|
||||
console.log(`Local URL: ${config.url}`);
|
||||
console.log(`Connect token: ${config.token}`);
|
||||
console.log("Codex MCP: codex mcp add infinite-canvas -- npx -y canvas-agent mcp");
|
||||
console.log("Codex MCP: codex mcp add infinite-canvas -- npx -y @basketikun/canvas-agent mcp");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -62,6 +105,10 @@ function route(handler: (req: Request, res: Response) => Promise<unknown>) {
|
||||
return (req: Request, res: Response, next: NextFunction) => void handler(req, res).catch(next);
|
||||
}
|
||||
|
||||
function routeParam(value: string | string[]) {
|
||||
return Array.isArray(value) ? value[0] || "" : value;
|
||||
}
|
||||
|
||||
function requestUrl(req: Request, config: CanvasAgentConfig) {
|
||||
return new URL(req.originalUrl || req.url || "/", config.url);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user