@x12i/memorix-service 3.7.6 → 3.7.7

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.
Files changed (57) hide show
  1. package/dist/activity-ring.d.ts +16 -0
  2. package/dist/activity-ring.d.ts.map +1 -1
  3. package/dist/activity-ring.js +15 -0
  4. package/dist/activity-ring.js.map +1 -1
  5. package/dist/activity-routes.d.ts.map +1 -1
  6. package/dist/activity-routes.js +6 -0
  7. package/dist/activity-routes.js.map +1 -1
  8. package/dist/activity-ui.d.ts +1 -1
  9. package/dist/activity-ui.d.ts.map +1 -1
  10. package/dist/activity-ui.js +383 -177
  11. package/dist/activity-ui.js.map +1 -1
  12. package/dist/app.d.ts.map +1 -1
  13. package/dist/app.js +8 -1
  14. package/dist/app.js.map +1 -1
  15. package/dist/catalog-bridge.d.ts.map +1 -1
  16. package/dist/catalog-bridge.js +6 -0
  17. package/dist/catalog-bridge.js.map +1 -1
  18. package/dist/cli.d.ts.map +1 -1
  19. package/dist/cli.js +9 -1
  20. package/dist/cli.js.map +1 -1
  21. package/dist/data-changes-ui.js +1 -1
  22. package/dist/graph-ui.d.ts +3 -0
  23. package/dist/graph-ui.d.ts.map +1 -0
  24. package/dist/graph-ui.js +676 -0
  25. package/dist/graph-ui.js.map +1 -0
  26. package/dist/knowledge-upstream.d.ts +13 -0
  27. package/dist/knowledge-upstream.d.ts.map +1 -0
  28. package/dist/knowledge-upstream.js +38 -0
  29. package/dist/knowledge-upstream.js.map +1 -0
  30. package/dist/live-ops-nav.d.ts +2 -0
  31. package/dist/live-ops-nav.d.ts.map +1 -0
  32. package/dist/live-ops-nav.js +53 -0
  33. package/dist/live-ops-nav.js.map +1 -0
  34. package/dist/live.d.ts.map +1 -1
  35. package/dist/mcp/nexum-tools.d.ts +28 -0
  36. package/dist/mcp/nexum-tools.d.ts.map +1 -0
  37. package/dist/mcp/nexum-tools.js +257 -0
  38. package/dist/mcp/nexum-tools.js.map +1 -0
  39. package/dist/mcp/service-public-url.d.ts +7 -0
  40. package/dist/mcp/service-public-url.d.ts.map +1 -0
  41. package/dist/mcp/service-public-url.js +19 -0
  42. package/dist/mcp/service-public-url.js.map +1 -0
  43. package/dist/routes/data.d.ts.map +1 -1
  44. package/dist/routes/data.js +8 -2
  45. package/dist/routes/data.js.map +1 -1
  46. package/dist/routes/knowledge.d.ts.map +1 -1
  47. package/dist/routes/knowledge.js +9 -37
  48. package/dist/routes/knowledge.js.map +1 -1
  49. package/dist/routes/nexum-mcp.d.ts +9 -0
  50. package/dist/routes/nexum-mcp.d.ts.map +1 -0
  51. package/dist/routes/nexum-mcp.js +95 -0
  52. package/dist/routes/nexum-mcp.js.map +1 -0
  53. package/dist/safe-query.d.ts +28 -0
  54. package/dist/safe-query.d.ts.map +1 -0
  55. package/dist/safe-query.js +104 -0
  56. package/dist/safe-query.js.map +1 -0
  57. package/package.json +1 -1
@@ -1,33 +1,9 @@
1
1
  import { resolveScope } from "../request-scope.js";
2
2
  import { ServiceError } from "../errors.js";
3
3
  import { requireCallbackAccess } from "../access-gate.js";
4
- function knowledgeUpstreamUrl(env = process.env) {
5
- return (env.MEMORIX_NEXUM_EXPLORE_URL?.trim() ||
6
- env.NEXUM_API_URL?.trim() ||
7
- "http://127.0.0.1:8080").replace(/\/+$/, "");
8
- }
9
- async function proxyJson(method, url, opts) {
10
- const res = await fetch(url, {
11
- method,
12
- headers: {
13
- ...(opts?.body !== undefined
14
- ? { "content-type": "application/json" }
15
- : {}),
16
- ...(opts?.headers ?? {}),
17
- },
18
- ...(opts?.body !== undefined ? { body: JSON.stringify(opts.body) } : {}),
19
- signal: AbortSignal.timeout(30_000),
20
- });
21
- const text = await res.text();
22
- let parsed = text;
23
- try {
24
- parsed = text ? JSON.parse(text) : null;
25
- }
26
- catch {
27
- /* keep text */
28
- }
29
- return { status: res.status, body: parsed };
30
- }
4
+ import { knowledgeUpstreamUrl, proxyJson, throwIfKnowledgeUpstreamError, } from "../knowledge-upstream.js";
5
+ import { NEXUM_MCP_TOOL_NAMES } from "../mcp/nexum-tools.js";
6
+ import { nexumMcpPublicUrl } from "../mcp/service-public-url.js";
31
7
  export async function registerKnowledgeRoutes(app, _platform) {
32
8
  app.get("/api/knowledge/status", async (req) => {
33
9
  requireCallbackAccess(req, "explore");
@@ -53,7 +29,9 @@ export async function registerKnowledgeRoutes(app, _platform) {
53
29
  scope,
54
30
  upstreamOk: upstream.ok,
55
31
  upstream,
56
- note: "Knowledge canvas is separate from Memorix subject reads (/api/data/content)",
32
+ mcpUrl: nexumMcpPublicUrl(),
33
+ tools: [...NEXUM_MCP_TOOL_NAMES],
34
+ note: "Knowledge canvas is separate from Memorix subject reads (/api/data/content). mcpUrl is memorix-nexum (not the MGC connector MCP).",
57
35
  };
58
36
  });
59
37
  app.get("/api/knowledge/entities", async (req) => {
@@ -66,9 +44,7 @@ export async function registerKnowledgeRoutes(app, _platform) {
66
44
  ? `/v1/orgs/${encodeURIComponent(scope.orgId)}/graphs/${encodeURIComponent(graphId)}/search?q=${encodeURIComponent(q.q)}&limit=${encodeURIComponent(q.limit ?? "50")}`
67
45
  : `/v1/orgs/${encodeURIComponent(scope.orgId)}/graphs/${encodeURIComponent(graphId)}/visualization?maximumNodes=${encodeURIComponent(q.limit ?? "500")}`;
68
46
  const upstream = await proxyJson("GET", `${baseUrl}${path}`);
69
- if (upstream.status >= 400) {
70
- throw new ServiceError("KNOWLEDGE_UPSTREAM_ERROR", `knowledge upstream HTTP ${upstream.status}`, upstream.status >= 500 ? 502 : upstream.status, { upstream: upstream.body });
71
- }
47
+ throwIfKnowledgeUpstreamError(upstream);
72
48
  return { scope, graphId, result: upstream.body };
73
49
  });
74
50
  app.get("/api/knowledge/entities/:entityId", async (req) => {
@@ -83,9 +59,7 @@ export async function registerKnowledgeRoutes(app, _platform) {
83
59
  const baseUrl = knowledgeUpstreamUrl();
84
60
  const path = `/v1/orgs/${encodeURIComponent(scope.orgId)}/graphs/${encodeURIComponent(graphId)}/nodes/${encodeURIComponent(entityId)}`;
85
61
  const upstream = await proxyJson("GET", `${baseUrl}${path}`);
86
- if (upstream.status >= 400) {
87
- throw new ServiceError("KNOWLEDGE_UPSTREAM_ERROR", `knowledge upstream HTTP ${upstream.status}`, upstream.status >= 500 ? 502 : upstream.status, { upstream: upstream.body });
88
- }
62
+ throwIfKnowledgeUpstreamError(upstream);
89
63
  return { scope, graphId, entityId, result: upstream.body };
90
64
  });
91
65
  app.post("/api/knowledge/query", async (req) => {
@@ -105,9 +79,7 @@ export async function registerKnowledgeRoutes(app, _platform) {
105
79
  const depth = Number(body.depth ?? 1);
106
80
  const path = `/v1/orgs/${encodeURIComponent(scope.orgId)}/graphs/${encodeURIComponent(graphId)}/nodes/${encodeURIComponent(seed)}/neighbors?depth=${encodeURIComponent(String(depth))}`;
107
81
  const upstream = await proxyJson("GET", `${baseUrl}${path}`);
108
- if (upstream.status >= 400) {
109
- throw new ServiceError("KNOWLEDGE_UPSTREAM_ERROR", `knowledge upstream HTTP ${upstream.status}`, upstream.status >= 500 ? 502 : upstream.status, { upstream: upstream.body });
110
- }
82
+ throwIfKnowledgeUpstreamError(upstream);
111
83
  return { scope, graphId, seed, depth, result: upstream.body };
112
84
  });
113
85
  }
@@ -1 +1 @@
1
- {"version":3,"file":"knowledge.js","sourceRoot":"","sources":["../../src/routes/knowledge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"knowledge.js","sourceRoot":"","sources":["../../src/routes/knowledge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Compatibility JSON-RPC 2.0 over POST for memorix-nexum (read-only).
3
+ * Methods: initialize, tools/list, tools/call. Advertises protocolVersion 2024-11-05
4
+ * (not conformant Streamable HTTP). Scope via product headers.
5
+ */
6
+ import type { FastifyInstance } from "fastify";
7
+ import type { MemorixPlatform } from "../platform.js";
8
+ export declare function registerNexumMcpRoutes(app: FastifyInstance, platform: MemorixPlatform): Promise<void>;
9
+ //# sourceMappingURL=nexum-mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nexum-mcp.d.ts","sourceRoot":"","sources":["../../src/routes/nexum-mcp.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AA+BtD,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,eAAe,EACpB,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,IAAI,CAAC,CAgGf"}
@@ -0,0 +1,95 @@
1
+ import { resolveScope } from "../request-scope.js";
2
+ import { ServiceError } from "../errors.js";
3
+ import { NEXUM_MCP_TOOL_NAMES, NEXUM_MCP_TOOLS, callNexumMcpTool, } from "../mcp/nexum-tools.js";
4
+ import { nexumMcpPublicUrl } from "../mcp/service-public-url.js";
5
+ function rpcResult(id, result) {
6
+ return { jsonrpc: "2.0", id: id ?? null, result };
7
+ }
8
+ function rpcError(id, code, message, data) {
9
+ return {
10
+ jsonrpc: "2.0",
11
+ id: id ?? null,
12
+ error: { code, message, ...(data !== undefined ? { data } : {}) },
13
+ };
14
+ }
15
+ export async function registerNexumMcpRoutes(app, platform) {
16
+ app.get("/mcp/nexum", async (_req, reply) => {
17
+ return reply.send({
18
+ protocol: "mcp",
19
+ transport: "streamable-http",
20
+ server: "memorix-nexum",
21
+ mcpUrl: nexumMcpPublicUrl(),
22
+ tools: [...NEXUM_MCP_TOOL_NAMES],
23
+ note: "POST JSON-RPC (initialize, tools/list, tools/call). Scope: x-memorix-org-id + x-memorix-agent-ids. Not the MGC connector MCP.",
24
+ });
25
+ });
26
+ app.post("/mcp/nexum", async (req, reply) => {
27
+ const body = (req.body ?? {});
28
+ if (body.jsonrpc !== "2.0" || typeof body.method !== "string") {
29
+ return reply
30
+ .code(400)
31
+ .send(rpcError(body.id ?? null, -32600, "Invalid Request"));
32
+ }
33
+ const id = body.id ?? null;
34
+ const method = body.method;
35
+ // Notifications have no id and expect empty/accepted response.
36
+ if (id === null && method.startsWith("notifications/")) {
37
+ return reply.code(202).send();
38
+ }
39
+ try {
40
+ if (method === "initialize") {
41
+ return reply.send(rpcResult(id, {
42
+ protocolVersion: "2024-11-05",
43
+ capabilities: { tools: {} },
44
+ serverInfo: {
45
+ name: "memorix-nexum",
46
+ version: "1.0.0",
47
+ },
48
+ instructions: "Read-only Nexum: content/snapshots subjects and canvas (/api/knowledge). Product land/read stays HTTP. MGC connectors use a different MCP host.",
49
+ }));
50
+ }
51
+ if (method === "ping") {
52
+ return reply.send(rpcResult(id, {}));
53
+ }
54
+ if (method === "tools/list") {
55
+ return reply.send(rpcResult(id, {
56
+ tools: NEXUM_MCP_TOOLS.map((t) => ({
57
+ name: t.name,
58
+ description: t.description,
59
+ inputSchema: t.inputSchema,
60
+ })),
61
+ }));
62
+ }
63
+ if (method === "tools/call") {
64
+ const scope = resolveScope(req);
65
+ const params = (body.params ?? {});
66
+ const name = String(params.name ?? "").trim();
67
+ if (!name) {
68
+ return reply
69
+ .code(400)
70
+ .send(rpcError(id, -32602, "tools/call requires params.name"));
71
+ }
72
+ const result = await callNexumMcpTool({
73
+ platform,
74
+ scope,
75
+ name,
76
+ args: params.arguments,
77
+ });
78
+ return reply.send(rpcResult(id, result));
79
+ }
80
+ return reply
81
+ .code(404)
82
+ .send(rpcError(id, -32601, `Method not found: ${method}`));
83
+ }
84
+ catch (err) {
85
+ if (err instanceof ServiceError) {
86
+ return reply.code(err.statusCode >= 400 ? err.statusCode : 400).send(rpcError(id, -32000, err.message, {
87
+ code: err.code,
88
+ details: err.details,
89
+ }));
90
+ }
91
+ throw err;
92
+ }
93
+ });
94
+ }
95
+ //# sourceMappingURL=nexum-mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nexum-mcp.js","sourceRoot":"","sources":["../../src/routes/nexum-mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Parse OpenAPI SafeFilter / SafeSort query strings for GET /api/data/content.
3
+ * Grammar matches @x12i/memorix-data QueryFilter / QuerySort (no Mongo operators).
4
+ */
5
+ export type SafeFilter = {
6
+ field: string;
7
+ op: "eq" | "ne" | "gt" | "gte" | "lt" | "lte";
8
+ value: unknown;
9
+ } | {
10
+ field: string;
11
+ op: "in" | "nin";
12
+ value: unknown[];
13
+ } | {
14
+ field: string;
15
+ op: "exists";
16
+ value: boolean;
17
+ };
18
+ export type SafeSort = {
19
+ field: string;
20
+ direction: "asc" | "desc";
21
+ };
22
+ /**
23
+ * Accept SafeFilter[] JSON, a single SafeFilter, or an equality map
24
+ * `{ "data.status": "open" }` → `[{ field, op: "eq", value }]`.
25
+ */
26
+ export declare function parseSafeFilters(raw: string | undefined): SafeFilter[] | undefined;
27
+ export declare function parseSafeSort(raw: string | undefined): SafeSort[] | undefined;
28
+ //# sourceMappingURL=safe-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-query.d.ts","sourceRoot":"","sources":["../src/safe-query.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,MAAM,UAAU,GAClB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAChF;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,IAAI,GAAG,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,EAAE,CAAA;CAAE,GACrD;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAEpD,MAAM,MAAM,QAAQ,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,KAAK,GAAG,MAAM,CAAA;CAAE,CAAC;AAsDpE;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,EAAE,GAAG,SAAS,CAsBlF;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,EAAE,GAAG,SAAS,CAiB7E"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Parse OpenAPI SafeFilter / SafeSort query strings for GET /api/data/content.
3
+ * Grammar matches @x12i/memorix-data QueryFilter / QuerySort (no Mongo operators).
4
+ */
5
+ import { ServiceError } from "./errors.js";
6
+ const SCALAR_OPS = new Set(["eq", "ne", "gt", "gte", "lt", "lte"]);
7
+ const ARRAY_OPS = new Set(["in", "nin"]);
8
+ function isRecord(v) {
9
+ return Boolean(v) && typeof v === "object" && !Array.isArray(v);
10
+ }
11
+ function parseJsonParam(raw, label) {
12
+ try {
13
+ return JSON.parse(raw);
14
+ }
15
+ catch {
16
+ throw new ServiceError("VALIDATION", `${label} must be valid JSON`, 400);
17
+ }
18
+ }
19
+ function assertFilter(raw, index) {
20
+ if (!isRecord(raw)) {
21
+ throw new ServiceError("READ_QUERY_INVALID", `filter[${index}] must be an object`, 400);
22
+ }
23
+ const field = raw.field;
24
+ const op = raw.op;
25
+ if (typeof field !== "string" || !field.trim()) {
26
+ throw new ServiceError("READ_QUERY_INVALID", `filter[${index}].field must be a non-empty string`, 400);
27
+ }
28
+ if (typeof op !== "string") {
29
+ throw new ServiceError("READ_QUERY_INVALID", `filter[${index}].op is required`, 400);
30
+ }
31
+ if (SCALAR_OPS.has(op)) {
32
+ if (!("value" in raw)) {
33
+ throw new ServiceError("READ_QUERY_INVALID", `filter[${index}].value is required`, 400);
34
+ }
35
+ return {
36
+ field,
37
+ op: op,
38
+ value: raw.value,
39
+ };
40
+ }
41
+ if (ARRAY_OPS.has(op)) {
42
+ if (!Array.isArray(raw.value)) {
43
+ throw new ServiceError("READ_QUERY_INVALID", `filter[${index}].value must be an array for op ${op}`, 400);
44
+ }
45
+ return { field, op: op, value: raw.value };
46
+ }
47
+ if (op === "exists") {
48
+ if (typeof raw.value !== "boolean") {
49
+ throw new ServiceError("READ_QUERY_INVALID", `filter[${index}].value must be boolean for op exists`, 400);
50
+ }
51
+ return { field, op: "exists", value: raw.value };
52
+ }
53
+ throw new ServiceError("READ_QUERY_INVALID", `Unsupported filter op: ${JSON.stringify(op)}`, 400);
54
+ }
55
+ /**
56
+ * Accept SafeFilter[] JSON, a single SafeFilter, or an equality map
57
+ * `{ "data.status": "open" }` → `[{ field, op: "eq", value }]`.
58
+ */
59
+ export function parseSafeFilters(raw) {
60
+ if (raw == null || raw.trim() === "")
61
+ return undefined;
62
+ const parsed = parseJsonParam(raw, "filter");
63
+ if (Array.isArray(parsed)) {
64
+ if (parsed.length === 0)
65
+ return undefined;
66
+ return parsed.map((f, i) => assertFilter(f, i));
67
+ }
68
+ if (isRecord(parsed)) {
69
+ if ("field" in parsed && "op" in parsed) {
70
+ return [assertFilter(parsed, 0)];
71
+ }
72
+ // Equality map — keys are field paths, values are eq targets.
73
+ const out = [];
74
+ for (const [field, value] of Object.entries(parsed)) {
75
+ if (!field.trim()) {
76
+ throw new ServiceError("READ_QUERY_INVALID", "filter field must be a non-empty string", 400);
77
+ }
78
+ out.push({ field, op: "eq", value });
79
+ }
80
+ return out.length ? out : undefined;
81
+ }
82
+ throw new ServiceError("READ_QUERY_INVALID", "filter must be a JSON array or object", 400);
83
+ }
84
+ export function parseSafeSort(raw) {
85
+ if (raw == null || raw.trim() === "")
86
+ return undefined;
87
+ const parsed = parseJsonParam(raw, "sort");
88
+ const items = Array.isArray(parsed) ? parsed : [parsed];
89
+ if (items.length === 0)
90
+ return undefined;
91
+ const out = [];
92
+ for (let i = 0; i < items.length; i++) {
93
+ const s = items[i];
94
+ if (!isRecord(s) || typeof s.field !== "string" || !s.field.trim()) {
95
+ throw new ServiceError("READ_QUERY_INVALID", `sort[${i}].field must be a non-empty string`, 400);
96
+ }
97
+ if (s.direction !== "asc" && s.direction !== "desc") {
98
+ throw new ServiceError("READ_QUERY_INVALID", `sort[${i}].direction must be asc|desc`, 400);
99
+ }
100
+ out.push({ field: s.field, direction: s.direction });
101
+ }
102
+ return out;
103
+ }
104
+ //# sourceMappingURL=safe-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-query.js","sourceRoot":"","sources":["../src/safe-query.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x12i/memorix-service",
3
- "version": "3.7.6",
3
+ "version": "3.7.7",
4
4
  "description": "Memorix production service composition root — one versioned API over accepted packages.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",