@christopherlittle51/postclaw 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard/public/app.js +743 -0
- package/dashboard/public/index.html +350 -0
- package/dashboard/public/styles.css +571 -0
- package/dist/dashboard/helpers.d.ts +32 -0
- package/dist/dashboard/helpers.d.ts.map +1 -0
- package/dist/dashboard/helpers.js +122 -0
- package/dist/dashboard/helpers.js.map +1 -0
- package/dist/dashboard/router.d.ts +39 -0
- package/dist/dashboard/router.d.ts.map +1 -0
- package/dist/dashboard/router.js +94 -0
- package/dist/dashboard/router.js.map +1 -0
- package/dist/dashboard/routes/config.d.ts +3 -0
- package/dist/dashboard/routes/config.d.ts.map +1 -0
- package/dist/dashboard/routes/config.js +53 -0
- package/dist/dashboard/routes/config.js.map +1 -0
- package/dist/dashboard/routes/graph.d.ts +11 -0
- package/dist/dashboard/routes/graph.d.ts.map +1 -0
- package/dist/dashboard/routes/graph.js +131 -0
- package/dist/dashboard/routes/graph.js.map +1 -0
- package/dist/dashboard/routes/memories.d.ts +12 -0
- package/dist/dashboard/routes/memories.d.ts.map +1 -0
- package/dist/dashboard/routes/memories.js +199 -0
- package/dist/dashboard/routes/memories.js.map +1 -0
- package/dist/dashboard/routes/personas.d.ts +11 -0
- package/dist/dashboard/routes/personas.d.ts.map +1 -0
- package/dist/dashboard/routes/personas.js +71 -0
- package/dist/dashboard/routes/personas.js.map +1 -0
- package/dist/dashboard/routes/scripts.d.ts +9 -0
- package/dist/dashboard/routes/scripts.d.ts.map +1 -0
- package/dist/dashboard/routes/scripts.js +62 -0
- package/dist/dashboard/routes/scripts.js.map +1 -0
- package/dist/dashboard/routes/workspace.d.ts +10 -0
- package/dist/dashboard/routes/workspace.d.ts.map +1 -0
- package/dist/dashboard/routes/workspace.js +82 -0
- package/dist/dashboard/routes/workspace.js.map +1 -0
- package/dist/dashboard/server.d.ts +14 -0
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/dashboard/server.js +97 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +142 -46
- package/dist/index.js.map +1 -1
- package/dist/schemas/validation.d.ts +123 -0
- package/dist/schemas/validation.d.ts.map +1 -1
- package/dist/schemas/validation.js +70 -1
- package/dist/schemas/validation.js.map +1 -1
- package/dist/scripts/setup-db.d.ts.map +1 -1
- package/dist/scripts/setup-db.js +24 -25
- package/dist/scripts/setup-db.js.map +1 -1
- package/dist/scripts/sleep_cycle.d.ts +12 -0
- package/dist/scripts/sleep_cycle.d.ts.map +1 -1
- package/dist/scripts/sleep_cycle.js +45 -33
- package/dist/scripts/sleep_cycle.js.map +1 -1
- package/dist/services/config.d.ts +31 -0
- package/dist/services/config.d.ts.map +1 -0
- package/dist/services/config.js +125 -0
- package/dist/services/config.js.map +1 -0
- package/dist/services/memoryService.d.ts +10 -19
- package/dist/services/memoryService.d.ts.map +1 -1
- package/dist/services/memoryService.js +20 -76
- package/dist/services/memoryService.js.map +1 -1
- package/dist/services/personaService.d.ts +22 -0
- package/dist/services/personaService.d.ts.map +1 -0
- package/dist/services/personaService.js +148 -0
- package/dist/services/personaService.js.map +1 -0
- package/dist/tests/dashboard-schemas.test.d.ts +6 -0
- package/dist/tests/dashboard-schemas.test.d.ts.map +1 -0
- package/dist/tests/dashboard-schemas.test.js +171 -0
- package/dist/tests/dashboard-schemas.test.js.map +1 -0
- package/dist/tests/helpers.test.d.ts +5 -0
- package/dist/tests/helpers.test.d.ts.map +1 -0
- package/dist/tests/helpers.test.js +66 -0
- package/dist/tests/helpers.test.js.map +1 -0
- package/dist/tests/router.test.d.ts +5 -0
- package/dist/tests/router.test.d.ts.map +1 -0
- package/dist/tests/router.test.js +125 -0
- package/dist/tests/router.test.js.map +1 -0
- package/openclaw.plugin.json +23 -0
- package/package.json +7 -2
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Dashboard HTTP Helpers — Shared utilities for the dashboard server.
|
|
4
|
+
*
|
|
5
|
+
* parseBody(), sendJson(), sendError(), serveStatic()
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.parseBody = parseBody;
|
|
9
|
+
exports.sendJson = sendJson;
|
|
10
|
+
exports.sendError = sendError;
|
|
11
|
+
exports.serveStatic = serveStatic;
|
|
12
|
+
exports.parseQuery = parseQuery;
|
|
13
|
+
const promises_1 = require("node:fs/promises");
|
|
14
|
+
const node_path_1 = require("node:path");
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// MIME TYPES
|
|
17
|
+
// =============================================================================
|
|
18
|
+
const MIME_TYPES = {
|
|
19
|
+
".html": "text/html; charset=utf-8",
|
|
20
|
+
".css": "text/css; charset=utf-8",
|
|
21
|
+
".js": "application/javascript; charset=utf-8",
|
|
22
|
+
".json": "application/json; charset=utf-8",
|
|
23
|
+
".png": "image/png",
|
|
24
|
+
".svg": "image/svg+xml",
|
|
25
|
+
".ico": "image/x-icon",
|
|
26
|
+
".woff2": "font/woff2",
|
|
27
|
+
".woff": "font/woff",
|
|
28
|
+
};
|
|
29
|
+
// =============================================================================
|
|
30
|
+
// BODY PARSING
|
|
31
|
+
// =============================================================================
|
|
32
|
+
/**
|
|
33
|
+
* Parse the request body as JSON. Returns null if body is empty or invalid.
|
|
34
|
+
*/
|
|
35
|
+
async function parseBody(req) {
|
|
36
|
+
return new Promise((resolve) => {
|
|
37
|
+
const chunks = [];
|
|
38
|
+
req.on("data", (chunk) => chunks.push(chunk));
|
|
39
|
+
req.on("end", () => {
|
|
40
|
+
const raw = Buffer.concat(chunks).toString("utf-8").trim();
|
|
41
|
+
if (!raw)
|
|
42
|
+
return resolve(null);
|
|
43
|
+
try {
|
|
44
|
+
resolve(JSON.parse(raw));
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
resolve(null);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
req.on("error", () => resolve(null));
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
// =============================================================================
|
|
54
|
+
// RESPONSE HELPERS
|
|
55
|
+
// =============================================================================
|
|
56
|
+
/**
|
|
57
|
+
* Send a JSON response with the standard { ok, data?, error? } shape.
|
|
58
|
+
*/
|
|
59
|
+
function sendJson(res, statusCode, data) {
|
|
60
|
+
const body = JSON.stringify(data);
|
|
61
|
+
res.writeHead(statusCode, {
|
|
62
|
+
"Content-Type": "application/json; charset=utf-8",
|
|
63
|
+
"Content-Length": Buffer.byteLength(body),
|
|
64
|
+
"Access-Control-Allow-Origin": "*",
|
|
65
|
+
});
|
|
66
|
+
res.end(body);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Send an error response.
|
|
70
|
+
*/
|
|
71
|
+
function sendError(res, statusCode, message) {
|
|
72
|
+
sendJson(res, statusCode, { ok: false, error: message });
|
|
73
|
+
}
|
|
74
|
+
// =============================================================================
|
|
75
|
+
// STATIC FILE SERVING
|
|
76
|
+
// =============================================================================
|
|
77
|
+
/**
|
|
78
|
+
* Serve a static file from the given base directory.
|
|
79
|
+
* Returns true if the file was served, false if not found.
|
|
80
|
+
*/
|
|
81
|
+
async function serveStatic(res, baseDirs, requestPath) {
|
|
82
|
+
// Normalize path — prevent directory traversal
|
|
83
|
+
const safePath = requestPath.replace(/\.\./g, "").replace(/\/+/g, "/");
|
|
84
|
+
const filePath = safePath === "/" ? "/index.html" : safePath;
|
|
85
|
+
for (const baseDir of baseDirs) {
|
|
86
|
+
const fullPath = (0, node_path_1.join)(baseDir, filePath);
|
|
87
|
+
try {
|
|
88
|
+
const content = await (0, promises_1.readFile)(fullPath);
|
|
89
|
+
const ext = (0, node_path_1.extname)(fullPath);
|
|
90
|
+
const mime = MIME_TYPES[ext] || "application/octet-stream";
|
|
91
|
+
res.writeHead(200, {
|
|
92
|
+
"Content-Type": mime,
|
|
93
|
+
"Content-Length": content.length,
|
|
94
|
+
"Cache-Control": "no-cache",
|
|
95
|
+
});
|
|
96
|
+
res.end(content);
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// File not found in this dir, try next
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
// =============================================================================
|
|
106
|
+
// QUERY STRING PARSING
|
|
107
|
+
// =============================================================================
|
|
108
|
+
/**
|
|
109
|
+
* Parse query parameters from a URL string.
|
|
110
|
+
*/
|
|
111
|
+
function parseQuery(url) {
|
|
112
|
+
const qIndex = url.indexOf("?");
|
|
113
|
+
if (qIndex === -1)
|
|
114
|
+
return {};
|
|
115
|
+
const params = {};
|
|
116
|
+
const searchParams = new URLSearchParams(url.substring(qIndex + 1));
|
|
117
|
+
for (const [key, value] of searchParams) {
|
|
118
|
+
params[key] = value;
|
|
119
|
+
}
|
|
120
|
+
return params;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../dashboard/helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard Router — Lightweight path-based routing for the dashboard API.
|
|
3
|
+
*
|
|
4
|
+
* Supports path parameters like /api/memories/:id and method matching.
|
|
5
|
+
*/
|
|
6
|
+
import { IncomingMessage, ServerResponse } from "node:http";
|
|
7
|
+
export interface RouteParams {
|
|
8
|
+
[key: string]: string;
|
|
9
|
+
}
|
|
10
|
+
export interface RouteContext {
|
|
11
|
+
params: RouteParams;
|
|
12
|
+
query: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
export type RouteHandler = (req: IncomingMessage, res: ServerResponse, ctx: RouteContext) => Promise<void>;
|
|
15
|
+
export declare class Router {
|
|
16
|
+
private routes;
|
|
17
|
+
/**
|
|
18
|
+
* Register a route. Supports :param syntax for path parameters.
|
|
19
|
+
*/
|
|
20
|
+
add(method: string, path: string, handler: RouteHandler): void;
|
|
21
|
+
/** Shorthand route registration */
|
|
22
|
+
get(path: string, handler: RouteHandler): void;
|
|
23
|
+
post(path: string, handler: RouteHandler): void;
|
|
24
|
+
put(path: string, handler: RouteHandler): void;
|
|
25
|
+
delete(path: string, handler: RouteHandler): void;
|
|
26
|
+
/**
|
|
27
|
+
* Match an incoming request against registered routes.
|
|
28
|
+
* Returns the handler and extracted params, or null if no match.
|
|
29
|
+
*/
|
|
30
|
+
match(method: string, pathname: string): {
|
|
31
|
+
handler: RouteHandler;
|
|
32
|
+
params: RouteParams;
|
|
33
|
+
} | null;
|
|
34
|
+
/**
|
|
35
|
+
* Handle an incoming request. Returns true if a route matched.
|
|
36
|
+
*/
|
|
37
|
+
handle(req: IncomingMessage, res: ServerResponse): Promise<boolean>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../dashboard/router.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAO5D,MAAM,WAAW,WAAW;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,MAAM,MAAM,YAAY,GAAG,CACzB,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,YAAY,KACd,OAAO,CAAC,IAAI,CAAC,CAAC;AAanB,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAe;IAE7B;;OAEG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAc9D,mCAAmC;IACnC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAC9C,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAC/C,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAC9C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAEjD;;;OAGG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,GAAG,IAAI;IAe9F;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;CAoC1E"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Dashboard Router — Lightweight path-based routing for the dashboard API.
|
|
4
|
+
*
|
|
5
|
+
* Supports path parameters like /api/memories/:id and method matching.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.Router = void 0;
|
|
9
|
+
const helpers_js_1 = require("./helpers.js");
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// ROUTER
|
|
12
|
+
// =============================================================================
|
|
13
|
+
class Router {
|
|
14
|
+
routes = [];
|
|
15
|
+
/**
|
|
16
|
+
* Register a route. Supports :param syntax for path parameters.
|
|
17
|
+
*/
|
|
18
|
+
add(method, path, handler) {
|
|
19
|
+
const paramNames = [];
|
|
20
|
+
const regexStr = path.replace(/:([a-zA-Z_]+)/g, (_match, name) => {
|
|
21
|
+
paramNames.push(name);
|
|
22
|
+
return "([^/]+)";
|
|
23
|
+
});
|
|
24
|
+
this.routes.push({
|
|
25
|
+
method: method.toUpperCase(),
|
|
26
|
+
pattern: new RegExp(`^${regexStr}$`),
|
|
27
|
+
paramNames,
|
|
28
|
+
handler,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/** Shorthand route registration */
|
|
32
|
+
get(path, handler) { this.add("GET", path, handler); }
|
|
33
|
+
post(path, handler) { this.add("POST", path, handler); }
|
|
34
|
+
put(path, handler) { this.add("PUT", path, handler); }
|
|
35
|
+
delete(path, handler) { this.add("DELETE", path, handler); }
|
|
36
|
+
/**
|
|
37
|
+
* Match an incoming request against registered routes.
|
|
38
|
+
* Returns the handler and extracted params, or null if no match.
|
|
39
|
+
*/
|
|
40
|
+
match(method, pathname) {
|
|
41
|
+
for (const route of this.routes) {
|
|
42
|
+
if (route.method !== method.toUpperCase())
|
|
43
|
+
continue;
|
|
44
|
+
const match = pathname.match(route.pattern);
|
|
45
|
+
if (!match)
|
|
46
|
+
continue;
|
|
47
|
+
const params = {};
|
|
48
|
+
route.paramNames.forEach((name, i) => {
|
|
49
|
+
params[name] = decodeURIComponent(match[i + 1]);
|
|
50
|
+
});
|
|
51
|
+
return { handler: route.handler, params };
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Handle an incoming request. Returns true if a route matched.
|
|
57
|
+
*/
|
|
58
|
+
async handle(req, res) {
|
|
59
|
+
const url = req.url || "/";
|
|
60
|
+
const pathname = url.split("?")[0];
|
|
61
|
+
const method = req.method || "GET";
|
|
62
|
+
// Handle CORS preflight
|
|
63
|
+
if (method === "OPTIONS") {
|
|
64
|
+
res.writeHead(204, {
|
|
65
|
+
"Access-Control-Allow-Origin": "*",
|
|
66
|
+
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
|
|
67
|
+
"Access-Control-Allow-Headers": "Content-Type",
|
|
68
|
+
});
|
|
69
|
+
res.end();
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
const result = this.match(method, pathname);
|
|
73
|
+
if (!result)
|
|
74
|
+
return false;
|
|
75
|
+
const query = {};
|
|
76
|
+
const qIndex = url.indexOf("?");
|
|
77
|
+
if (qIndex !== -1) {
|
|
78
|
+
const searchParams = new URLSearchParams(url.substring(qIndex + 1));
|
|
79
|
+
for (const [key, value] of searchParams) {
|
|
80
|
+
query[key] = value;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
await result.handler(req, res, { params: result.params, query });
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
console.error("[Dashboard] Route error:", err);
|
|
88
|
+
(0, helpers_js_1.sendError)(res, 500, err instanceof Error ? err.message : "Internal server error");
|
|
89
|
+
}
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
exports.Router = Router;
|
|
94
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../dashboard/router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../dashboard/routes/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAItC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,QA8ClD"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerConfigRoutes = registerConfigRoutes;
|
|
4
|
+
const helpers_js_1 = require("../helpers.js");
|
|
5
|
+
const config_js_1 = require("../../services/config.js");
|
|
6
|
+
function registerConfigRoutes(router) {
|
|
7
|
+
// GET /api/config — Get current PostClaw configuration
|
|
8
|
+
router.get("/api/config", async (req, res) => {
|
|
9
|
+
try {
|
|
10
|
+
const parsedUrl = new URL(req.url, "http://localhost");
|
|
11
|
+
const agentId = parsedUrl.searchParams.get("agentId") || "main";
|
|
12
|
+
const config = await (0, config_js_1.loadConfig)(agentId);
|
|
13
|
+
(0, helpers_js_1.sendJson)(res, 200, { ok: true, data: config });
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
(0, helpers_js_1.sendError)(res, 500, `Failed to get config: ${err}`);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
// POST /api/config — Update PostClaw configuration
|
|
20
|
+
router.post("/api/config", async (req, res) => {
|
|
21
|
+
try {
|
|
22
|
+
const parsedUrl = new URL(req.url, "http://localhost");
|
|
23
|
+
const agentId = parsedUrl.searchParams.get("agentId") || "main";
|
|
24
|
+
const body = await (0, helpers_js_1.parseBody)(req);
|
|
25
|
+
if (!body)
|
|
26
|
+
return (0, helpers_js_1.sendError)(res, 400, "Missing request body");
|
|
27
|
+
await (0, config_js_1.saveConfig)(agentId, body);
|
|
28
|
+
(0, helpers_js_1.sendJson)(res, 200, { ok: true, data: (0, config_js_1.getCurrentConfig)(agentId) });
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
(0, helpers_js_1.sendError)(res, 500, `Failed to save config: ${err}`);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
// POST /api/config/reset — Reset to defaults
|
|
35
|
+
router.post("/api/config/reset", async (req, res) => {
|
|
36
|
+
try {
|
|
37
|
+
const parsedUrl = new URL(req.url, "http://localhost");
|
|
38
|
+
const agentId = parsedUrl.searchParams.get("agentId") || "main";
|
|
39
|
+
// We can reset by simply deleting the config keys for this agent from the DB
|
|
40
|
+
const { getSql } = await import("../../services/db.js");
|
|
41
|
+
const { loadConfig } = await import("../../services/config.js");
|
|
42
|
+
const sql = getSql();
|
|
43
|
+
await sql `DELETE FROM plugin_config WHERE agent_id = ${agentId}`;
|
|
44
|
+
// Reload defaults into memory
|
|
45
|
+
const config = await loadConfig(agentId);
|
|
46
|
+
(0, helpers_js_1.sendJson)(res, 200, { ok: true, data: config });
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
(0, helpers_js_1.sendError)(res, 500, `Failed to reset config: ${err}`);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../dashboard/routes/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard API Routes — Knowledge graph endpoints.
|
|
3
|
+
*
|
|
4
|
+
* GET /api/graph — Full graph data for D3 visualization
|
|
5
|
+
* GET /api/edges — List edges
|
|
6
|
+
* POST /api/edges — Create edge
|
|
7
|
+
* DELETE /api/edges/:id — Delete edge
|
|
8
|
+
*/
|
|
9
|
+
import { Router } from "../router.js";
|
|
10
|
+
export declare function registerGraphRoutes(router: Router): void;
|
|
11
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../dashboard/routes/graph.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAStC,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAgIxD"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Dashboard API Routes — Knowledge graph endpoints.
|
|
4
|
+
*
|
|
5
|
+
* GET /api/graph — Full graph data for D3 visualization
|
|
6
|
+
* GET /api/edges — List edges
|
|
7
|
+
* POST /api/edges — Create edge
|
|
8
|
+
* DELETE /api/edges/:id — Delete edge
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.registerGraphRoutes = registerGraphRoutes;
|
|
12
|
+
const helpers_js_1 = require("../helpers.js");
|
|
13
|
+
const db_js_1 = require("../../services/db.js");
|
|
14
|
+
const validation_js_1 = require("../../schemas/validation.js");
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// REGISTER ROUTES
|
|
17
|
+
// =============================================================================
|
|
18
|
+
function registerGraphRoutes(router) {
|
|
19
|
+
// FULL GRAPH — nodes + edges for D3 force graph
|
|
20
|
+
router.get("/api/graph", async (_req, res, ctx) => {
|
|
21
|
+
const agentId = ctx.query.agentId || "main";
|
|
22
|
+
const sql = (0, db_js_1.getSql)();
|
|
23
|
+
const result = await sql.begin(async (tx) => {
|
|
24
|
+
await tx `SELECT set_config('app.current_agent_id', ${agentId}, true)`;
|
|
25
|
+
const nodes = await tx `
|
|
26
|
+
SELECT id, content, category, tier, access_count, usefulness_score, is_archived
|
|
27
|
+
FROM memory_semantic
|
|
28
|
+
WHERE agent_id = ${agentId} AND is_archived = false
|
|
29
|
+
ORDER BY created_at DESC
|
|
30
|
+
LIMIT 200
|
|
31
|
+
`;
|
|
32
|
+
const edges = await tx `
|
|
33
|
+
SELECT id, source_memory_id, target_memory_id, relationship_type, weight
|
|
34
|
+
FROM entity_edges
|
|
35
|
+
WHERE agent_id = ${agentId}
|
|
36
|
+
`;
|
|
37
|
+
return { nodes, edges };
|
|
38
|
+
});
|
|
39
|
+
// Filter to only include edges where both source and target exist in nodes
|
|
40
|
+
const nodeIds = new Set(result.nodes.map((n) => n.id));
|
|
41
|
+
const validEdges = result.edges.filter((e) => nodeIds.has(e.source_memory_id) && nodeIds.has(e.target_memory_id));
|
|
42
|
+
(0, helpers_js_1.sendJson)(res, 200, {
|
|
43
|
+
ok: true,
|
|
44
|
+
data: {
|
|
45
|
+
nodes: result.nodes.map((n) => ({
|
|
46
|
+
id: n.id,
|
|
47
|
+
label: n.content.substring(0, 80),
|
|
48
|
+
category: n.category,
|
|
49
|
+
tier: n.tier,
|
|
50
|
+
accessCount: n.access_count,
|
|
51
|
+
score: n.usefulness_score,
|
|
52
|
+
})),
|
|
53
|
+
edges: validEdges.map((e) => ({
|
|
54
|
+
id: e.id,
|
|
55
|
+
source: e.source_memory_id,
|
|
56
|
+
target: e.target_memory_id,
|
|
57
|
+
relationship: e.relationship_type,
|
|
58
|
+
weight: e.weight,
|
|
59
|
+
})),
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
// LIST EDGES
|
|
64
|
+
router.get("/api/edges", async (_req, res, ctx) => {
|
|
65
|
+
const agentId = ctx.query.agentId || "main";
|
|
66
|
+
const sql = (0, db_js_1.getSql)();
|
|
67
|
+
const rows = await sql.begin(async (tx) => {
|
|
68
|
+
await tx `SELECT set_config('app.current_agent_id', ${agentId}, true)`;
|
|
69
|
+
return await tx `
|
|
70
|
+
SELECT e.id, e.source_memory_id, e.target_memory_id,
|
|
71
|
+
e.relationship_type, e.weight, e.created_at,
|
|
72
|
+
s.content AS source_content, t.content AS target_content
|
|
73
|
+
FROM entity_edges e
|
|
74
|
+
LEFT JOIN memory_semantic s ON e.source_memory_id = s.id
|
|
75
|
+
LEFT JOIN memory_semantic t ON e.target_memory_id = t.id
|
|
76
|
+
WHERE e.agent_id = ${agentId}
|
|
77
|
+
ORDER BY e.created_at DESC
|
|
78
|
+
LIMIT 200
|
|
79
|
+
`;
|
|
80
|
+
});
|
|
81
|
+
(0, helpers_js_1.sendJson)(res, 200, { ok: true, data: rows });
|
|
82
|
+
});
|
|
83
|
+
// CREATE EDGE
|
|
84
|
+
router.post("/api/edges", async (req, res, ctx) => {
|
|
85
|
+
const agentId = ctx.query.agentId || "main";
|
|
86
|
+
const body = await (0, helpers_js_1.parseBody)(req);
|
|
87
|
+
if (!body)
|
|
88
|
+
return (0, helpers_js_1.sendError)(res, 400, "Invalid JSON body");
|
|
89
|
+
try {
|
|
90
|
+
const data = validation_js_1.GraphEdgeCreateSchema.parse(body);
|
|
91
|
+
const sql = (0, db_js_1.getSql)();
|
|
92
|
+
const rows = await sql.begin(async (tx) => {
|
|
93
|
+
await tx `SELECT set_config('app.current_agent_id', ${agentId}, true)`;
|
|
94
|
+
return await tx `
|
|
95
|
+
INSERT INTO entity_edges (
|
|
96
|
+
agent_id, source_memory_id, target_memory_id, relationship_type, weight
|
|
97
|
+
) VALUES (
|
|
98
|
+
${agentId}, ${data.source_memory_id}, ${data.target_memory_id},
|
|
99
|
+
${data.relationship_type}, ${data.weight}
|
|
100
|
+
)
|
|
101
|
+
ON CONFLICT (source_memory_id, target_memory_id, relationship_type) DO NOTHING
|
|
102
|
+
RETURNING id
|
|
103
|
+
`;
|
|
104
|
+
});
|
|
105
|
+
if (rows.length === 0) {
|
|
106
|
+
return (0, helpers_js_1.sendJson)(res, 200, { ok: true, data: { status: "already_exists" } });
|
|
107
|
+
}
|
|
108
|
+
(0, helpers_js_1.sendJson)(res, 201, { ok: true, data: { id: rows[0].id } });
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
(0, helpers_js_1.sendError)(res, 400, err instanceof Error ? err.message : "Create failed");
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
// DELETE EDGE
|
|
115
|
+
router.delete("/api/edges/:id", async (_req, res, ctx) => {
|
|
116
|
+
const agentId = ctx.query.agentId || "main";
|
|
117
|
+
const sql = (0, db_js_1.getSql)();
|
|
118
|
+
const rows = await sql.begin(async (tx) => {
|
|
119
|
+
await tx `SELECT set_config('app.current_agent_id', ${agentId}, true)`;
|
|
120
|
+
return await tx `
|
|
121
|
+
DELETE FROM entity_edges
|
|
122
|
+
WHERE id = ${ctx.params.id} AND agent_id = ${agentId}
|
|
123
|
+
RETURNING id
|
|
124
|
+
`;
|
|
125
|
+
});
|
|
126
|
+
if (rows.length === 0)
|
|
127
|
+
return (0, helpers_js_1.sendError)(res, 404, "Edge not found");
|
|
128
|
+
(0, helpers_js_1.sendJson)(res, 200, { ok: true, data: { deleted: true } });
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../../dashboard/routes/graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard API Routes — Memory management endpoints.
|
|
3
|
+
*
|
|
4
|
+
* GET /api/memories — List memories (paginated, filterable)
|
|
5
|
+
* POST /api/memories — Create memory
|
|
6
|
+
* PUT /api/memories/:id — Update memory
|
|
7
|
+
* DELETE /api/memories/:id — Archive memory
|
|
8
|
+
* POST /api/memories/import — Import from markdown content
|
|
9
|
+
*/
|
|
10
|
+
import { Router } from "../router.js";
|
|
11
|
+
export declare function registerMemoryRoutes(router: Router): void;
|
|
12
|
+
//# sourceMappingURL=memories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memories.d.ts","sourceRoot":"","sources":["../../../dashboard/routes/memories.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAetC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CA8LzD"}
|