@graph-tl/graph 0.1.8 → 0.1.9
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/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ if (args[0] === "activate") {
|
|
|
9
9
|
const { init } = await import("./init-PPICS5PC.js");
|
|
10
10
|
init();
|
|
11
11
|
} else {
|
|
12
|
-
const { startServer } = await import("./server-
|
|
12
|
+
const { startServer } = await import("./server-L7KF2UWS.js");
|
|
13
13
|
startServer().catch((error) => {
|
|
14
14
|
console.error("Failed to start graph:", error);
|
|
15
15
|
process.exit(1);
|
|
@@ -35,7 +35,10 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
|
35
35
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
36
36
|
import {
|
|
37
37
|
CallToolRequestSchema,
|
|
38
|
-
ListToolsRequestSchema
|
|
38
|
+
ListToolsRequestSchema,
|
|
39
|
+
ListResourcesRequestSchema,
|
|
40
|
+
ListResourceTemplatesRequestSchema,
|
|
41
|
+
ReadResourceRequestSchema
|
|
39
42
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
40
43
|
|
|
41
44
|
// src/tools/open.ts
|
|
@@ -308,6 +311,10 @@ function handleUpdate(input, agent) {
|
|
|
308
311
|
const resolvedIds = [];
|
|
309
312
|
let project = null;
|
|
310
313
|
for (const entry of updates) {
|
|
314
|
+
let evidence = entry.add_evidence;
|
|
315
|
+
if (entry.resolved_reason) {
|
|
316
|
+
evidence = [...evidence ?? [], { type: "note", ref: entry.resolved_reason }];
|
|
317
|
+
}
|
|
311
318
|
const node = updateNode({
|
|
312
319
|
node_id: entry.node_id,
|
|
313
320
|
agent,
|
|
@@ -318,7 +325,7 @@ function handleUpdate(input, agent) {
|
|
|
318
325
|
properties: entry.properties,
|
|
319
326
|
add_context_links: entry.add_context_links,
|
|
320
327
|
remove_context_links: entry.remove_context_links,
|
|
321
|
-
add_evidence:
|
|
328
|
+
add_evidence: evidence
|
|
322
329
|
});
|
|
323
330
|
updated.push({ node_id: node.id, rev: node.rev });
|
|
324
331
|
if (entry.resolved === true) {
|
|
@@ -1360,7 +1367,7 @@ var TOOLS = [
|
|
|
1360
1367
|
},
|
|
1361
1368
|
{
|
|
1362
1369
|
name: "graph_update",
|
|
1363
|
-
description: "Update one or more nodes. Can change resolved, state, summary, properties (merged), context_links, and add evidence. When resolving nodes, returns newly_actionable \u2014 nodes that became unblocked. ENFORCED: Resolving a node requires evidence \u2014
|
|
1370
|
+
description: "Update one or more nodes. Can change resolved, state, summary, properties (merged), context_links, and add evidence. When resolving nodes, returns newly_actionable \u2014 nodes that became unblocked. ENFORCED: Resolving a node requires evidence \u2014 use resolved_reason (shorthand, auto-creates note) or add_evidence array (type: 'git' for commits, 'note' for what was done and why, 'test' for results). Also add context_links to files you modified.",
|
|
1364
1371
|
inputSchema: {
|
|
1365
1372
|
type: "object",
|
|
1366
1373
|
properties: {
|
|
@@ -1371,6 +1378,7 @@ var TOOLS = [
|
|
|
1371
1378
|
properties: {
|
|
1372
1379
|
node_id: { type: "string" },
|
|
1373
1380
|
resolved: { type: "boolean" },
|
|
1381
|
+
resolved_reason: { type: "string", description: "Shorthand: auto-creates a note evidence entry. Use instead of add_evidence for simple cases." },
|
|
1374
1382
|
discovery: { type: "string", description: "Discovery phase status: 'pending' or 'done'. Set to 'done' after completing discovery interview." },
|
|
1375
1383
|
state: { description: "Agent-defined state, any type" },
|
|
1376
1384
|
summary: { type: "string" },
|
|
@@ -1609,7 +1617,7 @@ async function startServer() {
|
|
|
1609
1617
|
const tier = getLicenseTier(DB_PATH);
|
|
1610
1618
|
const server = new Server(
|
|
1611
1619
|
{ name: "graph", version: PKG_VERSION },
|
|
1612
|
-
{ capabilities: { tools: {} } }
|
|
1620
|
+
{ capabilities: { tools: {}, resources: {} } }
|
|
1613
1621
|
);
|
|
1614
1622
|
checkForUpdate();
|
|
1615
1623
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
@@ -1731,6 +1739,79 @@ async function startServer() {
|
|
|
1731
1739
|
};
|
|
1732
1740
|
}
|
|
1733
1741
|
});
|
|
1742
|
+
server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => ({
|
|
1743
|
+
resourceTemplates: [
|
|
1744
|
+
{
|
|
1745
|
+
uriTemplate: "graph://{project}/tree",
|
|
1746
|
+
name: "Project Tree",
|
|
1747
|
+
description: "Full task tree for a project with resolve status",
|
|
1748
|
+
mimeType: "application/json"
|
|
1749
|
+
},
|
|
1750
|
+
{
|
|
1751
|
+
uriTemplate: "graph://{project}/knowledge",
|
|
1752
|
+
name: "Project Knowledge",
|
|
1753
|
+
description: "All knowledge entries for a project",
|
|
1754
|
+
mimeType: "application/json"
|
|
1755
|
+
},
|
|
1756
|
+
{
|
|
1757
|
+
uriTemplate: "graph://{project}/knowledge/{key}",
|
|
1758
|
+
name: "Knowledge Entry",
|
|
1759
|
+
description: "A specific knowledge entry",
|
|
1760
|
+
mimeType: "application/json"
|
|
1761
|
+
}
|
|
1762
|
+
]
|
|
1763
|
+
}));
|
|
1764
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
1765
|
+
try {
|
|
1766
|
+
const { listProjects: listProjects2 } = await import("./nodes-4OJBNDHG.js");
|
|
1767
|
+
const projects = listProjects2();
|
|
1768
|
+
const resources = projects.flatMap((p) => [
|
|
1769
|
+
{
|
|
1770
|
+
uri: `graph://${p.project}/tree`,
|
|
1771
|
+
name: `${p.project} \u2014 Tree`,
|
|
1772
|
+
description: `Task tree: ${p.total} nodes (${p.resolved} resolved)`,
|
|
1773
|
+
mimeType: "application/json"
|
|
1774
|
+
},
|
|
1775
|
+
{
|
|
1776
|
+
uri: `graph://${p.project}/knowledge`,
|
|
1777
|
+
name: `${p.project} \u2014 Knowledge`,
|
|
1778
|
+
description: `Knowledge entries for ${p.project}`,
|
|
1779
|
+
mimeType: "application/json"
|
|
1780
|
+
}
|
|
1781
|
+
]);
|
|
1782
|
+
return { resources };
|
|
1783
|
+
} catch {
|
|
1784
|
+
return { resources: [] };
|
|
1785
|
+
}
|
|
1786
|
+
});
|
|
1787
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
1788
|
+
const uri = request.params.uri;
|
|
1789
|
+
const match = uri.match(/^graph:\/\/([^/]+)\/(.+)$/);
|
|
1790
|
+
if (!match) {
|
|
1791
|
+
throw new Error(`Invalid resource URI: ${uri}`);
|
|
1792
|
+
}
|
|
1793
|
+
const [, project, path] = match;
|
|
1794
|
+
if (path === "tree") {
|
|
1795
|
+
const result = handleTree({ project });
|
|
1796
|
+
return {
|
|
1797
|
+
contents: [{ uri, mimeType: "application/json", text: JSON.stringify(result, null, 2) }]
|
|
1798
|
+
};
|
|
1799
|
+
}
|
|
1800
|
+
if (path === "knowledge") {
|
|
1801
|
+
const result = handleKnowledgeRead({ project });
|
|
1802
|
+
return {
|
|
1803
|
+
contents: [{ uri, mimeType: "application/json", text: JSON.stringify(result, null, 2) }]
|
|
1804
|
+
};
|
|
1805
|
+
}
|
|
1806
|
+
const knowledgeMatch = path.match(/^knowledge\/(.+)$/);
|
|
1807
|
+
if (knowledgeMatch) {
|
|
1808
|
+
const result = handleKnowledgeRead({ project, key: knowledgeMatch[1] });
|
|
1809
|
+
return {
|
|
1810
|
+
contents: [{ uri, mimeType: "application/json", text: JSON.stringify(result, null, 2) }]
|
|
1811
|
+
};
|
|
1812
|
+
}
|
|
1813
|
+
throw new Error(`Unknown resource path: ${path}`);
|
|
1814
|
+
});
|
|
1734
1815
|
const transport = new StdioServerTransport();
|
|
1735
1816
|
await server.connect(transport);
|
|
1736
1817
|
const checkpointInterval = setInterval(() => {
|
|
@@ -1753,4 +1834,4 @@ async function startServer() {
|
|
|
1753
1834
|
export {
|
|
1754
1835
|
startServer
|
|
1755
1836
|
};
|
|
1756
|
-
//# sourceMappingURL=server-
|
|
1837
|
+
//# sourceMappingURL=server-L7KF2UWS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../src/tools/open.ts","../src/edges.ts","../src/tools/plan.ts","../src/tools/update.ts","../src/tools/connect.ts","../src/tools/context.ts","../src/tools/query.ts","../src/tools/next.ts","../src/tools/restructure.ts","../src/tools/history.ts","../src/tools/onboard.ts","../src/tools/tree.ts","../src/tools/knowledge.ts","../src/gates.ts"],"sourcesContent":["import { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n ListResourcesRequestSchema,\n ListResourceTemplatesRequestSchema,\n ReadResourceRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { setDbPath, closeDb, checkpointDb } from \"./db.js\";\nimport { ValidationError, EngineError } from \"./validate.js\";\nimport { handleOpen } from \"./tools/open.js\";\nimport { handlePlan } from \"./tools/plan.js\";\nimport { handleUpdate } from \"./tools/update.js\";\nimport { handleConnect } from \"./tools/connect.js\";\nimport { handleContext } from \"./tools/context.js\";\nimport { handleQuery } from \"./tools/query.js\";\nimport { handleNext } from \"./tools/next.js\";\nimport { handleRestructure } from \"./tools/restructure.js\";\nimport { handleHistory } from \"./tools/history.js\";\nimport { handleOnboard } from \"./tools/onboard.js\";\nimport { handleAgentConfig } from \"./tools/agent-config.js\";\nimport { handleTree } from \"./tools/tree.js\";\nimport { handleKnowledgeWrite, handleKnowledgeRead, handleKnowledgeDelete, handleKnowledgeSearch } from \"./tools/knowledge.js\";\nimport { getLicenseTier, type Tier } from \"./license.js\";\nimport { checkNodeLimit, checkProjectLimit, capEvidenceLimit, checkScope, checkKnowledgeTier } from \"./gates.js\";\n\nimport { createHash } from \"crypto\";\nimport { mkdirSync, readFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { join, resolve, dirname } from \"path\";\nimport { fileURLToPath } from \"url\";\n\n// Config from env\nconst AGENT_IDENTITY = process.env.GRAPH_AGENT ?? \"default-agent\";\nconst CLAIM_TTL = parseInt(process.env.GRAPH_CLAIM_TTL ?? \"60\", 10);\n\nfunction defaultDbPath(): string {\n const projectDir = resolve(\".\");\n const hash = createHash(\"sha256\").update(projectDir).digest(\"hex\").slice(0, 16);\n const dir = join(homedir(), \".graph\", \"db\", hash);\n mkdirSync(dir, { recursive: true });\n return join(dir, \"graph.db\");\n}\n\nconst DB_PATH = process.env.GRAPH_DB ?? defaultDbPath();\n\n// Read version from package.json\nconst PKG_NAME = \"@graph-tl/graph\";\nlet PKG_VERSION = \"0.0.0\";\ntry {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const pkg = JSON.parse(readFileSync(join(__dirname, \"..\", \"package.json\"), \"utf-8\"));\n PKG_VERSION = pkg.version;\n} catch {}\n\n// Version banner — shown once on first tool call\nlet versionBanner: string | null = `[graph] v${PKG_VERSION}`;\n\n// Non-blocking version check against npm registry\nlet updateWarning: string | null = null;\n\nasync function checkForUpdate(): Promise<void> {\n try {\n const res = await fetch(`https://registry.npmjs.org/${PKG_NAME}/latest`);\n if (!res.ok) return;\n const data = await res.json() as { version: string };\n if (data.version !== PKG_VERSION) {\n updateWarning = `[graph] Update available: ${PKG_VERSION} → ${data.version}. Run: npx clear-npx-cache && restart MCP server.`;\n }\n } catch {}\n}\n\n// Tool definitions\nconst TOOLS = [\n {\n name: \"graph_open\",\n description:\n \"Open an existing project or create a new one. Omit 'project' to list all projects. Returns project root node and summary stats (total, resolved, unresolved, blocked, actionable counts).\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: {\n type: \"string\",\n description: \"Project name (e.g. 'my-project'). Omit to list all projects.\",\n },\n goal: {\n type: \"string\",\n description: \"Project goal/description. Used on creation only.\",\n },\n },\n },\n },\n {\n name: \"graph_plan\",\n description:\n \"Batch create nodes with parent-child and dependency relationships in one atomic call. Use for decomposing work into subtrees. Each node needs a temp 'ref' for intra-batch references. parent_ref and depends_on can reference batch refs or existing node IDs.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n nodes: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n ref: {\n type: \"string\",\n description: \"Temp ID for referencing within this batch\",\n },\n parent_ref: {\n type: \"string\",\n description:\n \"Parent: a ref from this batch OR an existing node ID\",\n },\n summary: { type: \"string\" },\n context_links: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Pointers to files, commits, URLs\",\n },\n depends_on: {\n type: \"array\",\n items: { type: \"string\" },\n description:\n \"Refs within batch OR existing node IDs this depends on\",\n },\n properties: {\n type: \"object\",\n description: \"Freeform key-value properties\",\n },\n },\n required: [\"ref\", \"summary\"],\n },\n description: \"Nodes to create\",\n },\n },\n required: [\"nodes\"],\n },\n },\n {\n name: \"graph_next\",\n description:\n \"Get the next actionable node — an unresolved leaf with all dependencies resolved. Ranked by priority (from properties), depth, and least-recently-updated. Returns the node with ancestor chain, context links, and resolved dependency info. Use claim=true to soft-lock the node. When modifying code for this task, annotate key changes with // [sl:nodeId] so future agents can trace code back to this task.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: { type: \"string\", description: \"Project name (e.g. 'my-project'), not a node ID\" },\n scope: {\n type: \"string\",\n description: \"Node ID to scope results to. Only returns actionable descendants of this node.\",\n },\n filter: {\n type: \"object\",\n description: \"Match against node properties\",\n },\n count: {\n type: \"number\",\n description: \"Return top N nodes (default 1)\",\n },\n claim: {\n type: \"boolean\",\n description:\n \"If true, soft-lock returned nodes with agent identity\",\n },\n },\n required: [\"project\"],\n },\n },\n {\n name: \"graph_context\",\n description:\n \"Deep-read a node and its neighborhood: ancestors (scope chain), children tree (to configurable depth), dependency graph (what it depends on, what depends on it). Look for // [sl:nodeId] annotations in source files to find code tied to specific tasks.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n node_id: { type: \"string\", description: \"Node ID to inspect\" },\n depth: {\n type: \"number\",\n description: \"Levels of children to return (default 2)\",\n },\n },\n required: [\"node_id\"],\n },\n },\n {\n name: \"graph_update\",\n description:\n \"Update one or more nodes. Can change resolved, state, summary, properties (merged), context_links, and add evidence. When resolving nodes, returns newly_actionable — nodes that became unblocked. ENFORCED: Resolving a node requires evidence — use resolved_reason (shorthand, auto-creates note) or add_evidence array (type: 'git' for commits, 'note' for what was done and why, 'test' for results). Also add context_links to files you modified.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n updates: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n node_id: { type: \"string\" },\n resolved: { type: \"boolean\" },\n resolved_reason: { type: \"string\", description: \"Shorthand: auto-creates a note evidence entry. Use instead of add_evidence for simple cases.\" },\n discovery: { type: \"string\", description: \"Discovery phase status: 'pending' or 'done'. Set to 'done' after completing discovery interview.\" },\n state: { description: \"Agent-defined state, any type\" },\n summary: { type: \"string\" },\n properties: {\n type: \"object\",\n description:\n \"Merged into existing. Set a key to null to delete it.\",\n },\n add_context_links: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Files modified or created for this task. Add when resolving so future agents know what was touched.\",\n },\n remove_context_links: {\n type: \"array\",\n items: { type: \"string\" },\n },\n add_evidence: {\n type: \"array\",\n description: \"Evidence of work done. Always add when resolving. Types: 'git' (commit hash + summary), 'note' (what was implemented and why), 'test' (test results).\",\n items: {\n type: \"object\",\n properties: {\n type: { type: \"string\", description: \"Evidence type: git, note, test, or custom\" },\n ref: { type: \"string\", description: \"The evidence content — commit ref, implementation note, test result\" },\n },\n required: [\"type\", \"ref\"],\n },\n },\n },\n required: [\"node_id\"],\n },\n },\n },\n required: [\"updates\"],\n },\n },\n {\n name: \"graph_connect\",\n description:\n \"Add or remove edges between nodes. Types: 'depends_on' (with cycle detection), 'relates_to', or custom. Parent edges not allowed — use graph_restructure for reparenting.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n edges: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n from: { type: \"string\", description: \"Source node ID\" },\n to: { type: \"string\", description: \"Target node ID\" },\n type: {\n type: \"string\",\n description: \"'depends_on', 'relates_to', or custom\",\n },\n remove: {\n type: \"boolean\",\n description: \"True to remove this edge\",\n },\n },\n required: [\"from\", \"to\", \"type\"],\n },\n },\n },\n required: [\"edges\"],\n },\n },\n {\n name: \"graph_query\",\n description:\n \"Search and filter nodes. Filters: resolved, properties, text, ancestor (descendants of), is_leaf, is_actionable, is_blocked, claimed_by. Supports sorting and cursor pagination.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: { type: \"string\", description: \"Project name (e.g. 'my-project'), not a node ID\" },\n filter: {\n type: \"object\",\n properties: {\n resolved: { type: \"boolean\" },\n properties: { type: \"object\" },\n text: { type: \"string\", description: \"Substring match on summary\" },\n ancestor: {\n type: \"string\",\n description: \"Return all descendants of this node\",\n },\n has_evidence_type: { type: \"string\" },\n is_leaf: { type: \"boolean\" },\n is_actionable: { type: \"boolean\" },\n is_blocked: { type: \"boolean\" },\n claimed_by: {\n type: [\"string\", \"null\"],\n description: \"Filter by claim. null = unclaimed.\",\n },\n },\n },\n sort: {\n type: \"string\",\n enum: [\"readiness\", \"depth\", \"recent\", \"created\"],\n },\n limit: { type: \"number\", description: \"Max results (default 20, max 100)\" },\n cursor: { type: \"string\", description: \"Pagination cursor\" },\n },\n required: [\"project\"],\n },\n },\n {\n name: \"graph_restructure\",\n description:\n \"Modify graph structure: move (reparent), merge (combine two nodes), drop (resolve node + subtree with reason). Atomic. Reports newly_actionable nodes.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n operations: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n op: {\n type: \"string\",\n enum: [\"move\", \"merge\", \"drop\"],\n },\n node_id: { type: \"string\", description: \"For move and drop\" },\n new_parent: { type: \"string\", description: \"For move\" },\n source: { type: \"string\", description: \"For merge: node to absorb\" },\n target: {\n type: \"string\",\n description: \"For merge: node that survives\",\n },\n reason: { type: \"string\", description: \"For drop: why\" },\n },\n required: [\"op\"],\n },\n },\n },\n required: [\"operations\"],\n },\n },\n {\n name: \"graph_history\",\n description:\n \"Read the audit trail for a node. Shows who changed what, when, and why. Useful for understanding past decisions across sessions.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n node_id: { type: \"string\" },\n limit: { type: \"number\", description: \"Max events (default 20)\" },\n cursor: { type: \"string\", description: \"Pagination cursor\" },\n },\n required: [\"node_id\"],\n },\n },\n {\n name: \"graph_onboard\",\n description:\n \"Single-call orientation for new agents joining a project. Returns project summary, tree structure (depth 2), recent evidence from resolved nodes (knowledge transfer), all context links, and actionable tasks. Use this as your first call when starting work on an existing project.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: { type: \"string\", description: \"Project name (e.g. 'my-project'). Omit to auto-select (works when there's exactly one project).\" },\n evidence_limit: {\n type: \"number\",\n description: \"Max evidence entries to return (default 20, max 50)\",\n },\n },\n },\n },\n {\n name: \"graph_tree\",\n description:\n \"Full tree visualization for a project. Returns the complete task hierarchy with resolve status. Use when you need to see the whole project structure beyond graph_context's single-node neighborhood.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: { type: \"string\", description: \"Project name (e.g. 'my-project')\" },\n depth: {\n type: \"number\",\n description: \"Max tree depth to return (default 10, max 20)\",\n },\n },\n required: [\"project\"],\n },\n },\n {\n name: \"graph_agent_config\",\n description:\n \"Returns the graph-optimized agent configuration file for Claude Code. Save the returned content to .claude/agents/graph.md to enable the graph workflow agent.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {},\n },\n },\n {\n name: \"graph_knowledge_write\",\n description:\n \"Write a knowledge entry for a project. Creates or overwrites a named document. Use for persistent project-level knowledge (architecture decisions, conventions, API contracts) that outlives individual tasks.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: { type: \"string\", description: \"Project name\" },\n key: { type: \"string\", description: \"Knowledge entry key (e.g. 'auth', 'database-schema', 'api-contracts')\" },\n content: { type: \"string\", description: \"Free-form text content\" },\n },\n required: [\"project\", \"key\", \"content\"],\n },\n },\n {\n name: \"graph_knowledge_read\",\n description:\n \"Read knowledge entries for a project. Provide a key to read one entry, or omit to list all entries.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: { type: \"string\", description: \"Project name\" },\n key: { type: \"string\", description: \"Knowledge entry key. Omit to list all.\" },\n },\n required: [\"project\"],\n },\n },\n {\n name: \"graph_knowledge_delete\",\n description:\n \"Delete a knowledge entry from a project.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: { type: \"string\", description: \"Project name\" },\n key: { type: \"string\", description: \"Knowledge entry key to delete\" },\n },\n required: [\"project\", \"key\"],\n },\n },\n {\n name: \"graph_knowledge_search\",\n description:\n \"Search knowledge entries by substring match on key or content.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: { type: \"string\", description: \"Project name\" },\n query: { type: \"string\", description: \"Search string\" },\n },\n required: [\"project\", \"query\"],\n },\n },\n];\n\nexport async function startServer(): Promise<void> {\n // Set database path — db is created lazily on first tool call\n setDbPath(DB_PATH);\n\n // [sl:N0IDVJQIhENQFsov6-Lhg] Resolve license tier once at startup (reads license file, doesn't touch db)\n const tier: Tier = getLicenseTier(DB_PATH);\n\n const server = new Server(\n { name: \"graph\", version: PKG_VERSION },\n { capabilities: { tools: {}, resources: {} } }\n );\n\n // Fire-and-forget version check\n checkForUpdate();\n\n // List tools\n server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: TOOLS,\n }));\n\n // Handle tool calls\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n let result: unknown;\n\n switch (name) {\n case \"graph_open\": {\n const openArgs = args as any;\n // Gate: check project limit when creating a new project\n if (openArgs?.project) {\n const { getProjectRoot } = await import(\"./nodes.js\");\n if (!getProjectRoot(openArgs.project)) {\n checkProjectLimit(tier);\n }\n }\n result = handleOpen(openArgs, AGENT_IDENTITY);\n break;\n }\n\n case \"graph_plan\": {\n const planArgs = args as any;\n // Gate: check node limit before creating nodes\n if (planArgs?.nodes?.length > 0) {\n // Determine project from the first node's parent\n const { getNode } = await import(\"./nodes.js\");\n const firstParent = planArgs.nodes[0]?.parent_ref;\n if (firstParent && typeof firstParent === \"string\" && !planArgs.nodes.some((n: any) => n.ref === firstParent)) {\n const parentNode = getNode(firstParent);\n if (parentNode) {\n checkNodeLimit(tier, parentNode.project, planArgs.nodes.length);\n }\n }\n }\n result = handlePlan(planArgs, AGENT_IDENTITY);\n break;\n }\n\n case \"graph_next\": {\n const nextArgs = args as any;\n // Gate: strip scope on free tier\n if (nextArgs?.scope) {\n nextArgs.scope = checkScope(tier, nextArgs.scope);\n }\n result = handleNext(nextArgs, AGENT_IDENTITY, CLAIM_TTL);\n break;\n }\n\n case \"graph_context\":\n result = handleContext(args as any);\n break;\n\n case \"graph_update\":\n result = handleUpdate(args as any, AGENT_IDENTITY);\n break;\n\n case \"graph_connect\":\n result = handleConnect(args as any, AGENT_IDENTITY);\n break;\n\n case \"graph_query\":\n result = handleQuery(args as any);\n break;\n\n case \"graph_restructure\":\n result = handleRestructure(args as any, AGENT_IDENTITY);\n break;\n\n case \"graph_history\":\n result = handleHistory(args as any);\n break;\n\n case \"graph_onboard\": {\n const onboardArgs = args as any;\n // Gate: cap evidence limit on free tier\n onboardArgs.evidence_limit = capEvidenceLimit(tier, onboardArgs?.evidence_limit);\n result = handleOnboard(onboardArgs);\n break;\n }\n\n case \"graph_tree\":\n result = handleTree(args as any);\n break;\n\n case \"graph_agent_config\":\n result = handleAgentConfig();\n break;\n\n case \"graph_knowledge_write\":\n checkKnowledgeTier(tier);\n result = handleKnowledgeWrite(args as any, AGENT_IDENTITY);\n break;\n\n case \"graph_knowledge_read\":\n checkKnowledgeTier(tier);\n result = handleKnowledgeRead(args as any);\n break;\n\n case \"graph_knowledge_delete\":\n checkKnowledgeTier(tier);\n result = handleKnowledgeDelete(args as any);\n break;\n\n case \"graph_knowledge_search\":\n checkKnowledgeTier(tier);\n result = handleKnowledgeSearch(args as any);\n break;\n\n default:\n return {\n content: [\n { type: \"text\" as const, text: JSON.stringify({ error: `Unknown tool: ${name}` }) },\n ],\n isError: true,\n };\n }\n\n const content: Array<{ type: \"text\"; text: string }> = [\n { type: \"text\" as const, text: JSON.stringify(result, null, 2) },\n ];\n if (versionBanner) {\n content.push({ type: \"text\" as const, text: updateWarning ? `${versionBanner} — ${updateWarning}` : versionBanner });\n versionBanner = null;\n updateWarning = null;\n }\n return { content };\n } catch (error) {\n const message =\n error instanceof Error ? error.message : String(error);\n const code =\n error instanceof ValidationError\n ? \"validation_error\"\n : error instanceof EngineError\n ? (error as EngineError).code\n : \"error\";\n return {\n content: [\n {\n type: \"text\" as const,\n text: JSON.stringify({ error: message, code }),\n },\n ],\n isError: true,\n };\n }\n });\n\n // [sl:Ps3gCuzhMoQWK6tynsGA4] MCP resources — browsable read-only views of graph data\n\n // Resource templates (dynamic, parameterized URIs)\n server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => ({\n resourceTemplates: [\n {\n uriTemplate: \"graph://{project}/tree\",\n name: \"Project Tree\",\n description: \"Full task tree for a project with resolve status\",\n mimeType: \"application/json\",\n },\n {\n uriTemplate: \"graph://{project}/knowledge\",\n name: \"Project Knowledge\",\n description: \"All knowledge entries for a project\",\n mimeType: \"application/json\",\n },\n {\n uriTemplate: \"graph://{project}/knowledge/{key}\",\n name: \"Knowledge Entry\",\n description: \"A specific knowledge entry\",\n mimeType: \"application/json\",\n },\n ],\n }));\n\n // Static resource list (enumerate known projects)\n server.setRequestHandler(ListResourcesRequestSchema, async () => {\n try {\n const { listProjects } = await import(\"./nodes.js\");\n const projects = listProjects();\n const resources = projects.flatMap((p) => [\n {\n uri: `graph://${p.project}/tree`,\n name: `${p.project} — Tree`,\n description: `Task tree: ${p.total} nodes (${p.resolved} resolved)`,\n mimeType: \"application/json\",\n },\n {\n uri: `graph://${p.project}/knowledge`,\n name: `${p.project} — Knowledge`,\n description: `Knowledge entries for ${p.project}`,\n mimeType: \"application/json\",\n },\n ]);\n return { resources };\n } catch {\n return { resources: [] };\n }\n });\n\n // Read a specific resource\n server.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n const uri = request.params.uri;\n const match = uri.match(/^graph:\\/\\/([^/]+)\\/(.+)$/);\n if (!match) {\n throw new Error(`Invalid resource URI: ${uri}`);\n }\n\n const [, project, path] = match;\n\n if (path === \"tree\") {\n const result = handleTree({ project });\n return {\n contents: [{ uri, mimeType: \"application/json\", text: JSON.stringify(result, null, 2) }],\n };\n }\n\n if (path === \"knowledge\") {\n const result = handleKnowledgeRead({ project });\n return {\n contents: [{ uri, mimeType: \"application/json\", text: JSON.stringify(result, null, 2) }],\n };\n }\n\n const knowledgeMatch = path.match(/^knowledge\\/(.+)$/);\n if (knowledgeMatch) {\n const result = handleKnowledgeRead({ project, key: knowledgeMatch[1] });\n return {\n contents: [{ uri, mimeType: \"application/json\", text: JSON.stringify(result, null, 2) }],\n };\n }\n\n throw new Error(`Unknown resource path: ${path}`);\n });\n\n // Connect transport\n const transport = new StdioServerTransport();\n await server.connect(transport);\n\n // Periodic WAL checkpoint every 30s — flushes WAL data into main db file\n const checkpointInterval = setInterval(() => {\n try { checkpointDb(); } catch {}\n }, 30_000);\n\n // Cleanup on exit\n process.on(\"SIGINT\", () => {\n clearInterval(checkpointInterval);\n closeDb();\n process.exit(0);\n });\n process.on(\"SIGTERM\", () => {\n clearInterval(checkpointInterval);\n closeDb();\n process.exit(0);\n });\n}\n","import { createNode, getProjectRoot, listProjects, getProjectSummary } from \"../nodes.js\";\nimport { optionalString } from \"../validate.js\";\nimport type { Node } from \"../types.js\";\n\nexport interface OpenInput {\n project?: string;\n goal?: string;\n}\n\nexport type OpenResult =\n | {\n projects: Array<{\n project: string;\n id: string;\n summary: string;\n total: number;\n resolved: number;\n unresolved: number;\n updated_at: string;\n }>;\n }\n | {\n project: string;\n root: Node;\n summary: {\n total: number;\n resolved: number;\n unresolved: number;\n blocked: number;\n actionable: number;\n };\n hint?: string;\n };\n\nexport function handleOpen(input: OpenInput, agent: string): OpenResult {\n const project = optionalString(input?.project, \"project\");\n const goal = optionalString(input?.goal, \"goal\");\n\n if (!project) {\n return { projects: listProjects() };\n }\n\n let root = getProjectRoot(project);\n let isNew = false;\n\n if (!root) {\n root = createNode({\n project,\n summary: goal ?? project,\n discovery: \"pending\",\n agent,\n });\n isNew = true;\n }\n\n const summary = getProjectSummary(project);\n\n const result: OpenResult = { project, root, summary };\n\n // Guide the agent on what to do next\n if (isNew) {\n result.hint = `New project created. Discovery is pending — interview the user to understand scope and goals, then set discovery to \"done\" via graph_update before decomposing with graph_plan.`;\n } else if (root.discovery === \"pending\") {\n result.hint = `Discovery is still pending on this project. Complete the discovery interview, then set discovery to \"done\" via graph_update.`;\n } else if (summary.actionable > 0) {\n result.hint = `${summary.actionable} actionable task(s). Use graph_next to claim one.`;\n } else if (summary.unresolved > 0 && summary.actionable === 0) {\n result.hint = `All remaining tasks are blocked. Check dependencies with graph_query.`;\n }\n\n return result;\n}\n","import { nanoid } from \"nanoid\";\nimport { getDb } from \"./db.js\";\nimport { logEvent } from \"./events.js\";\nimport type { Edge } from \"./types.js\";\n\n// --- Cycle detection ---\n\nfunction wouldCreateCycle(from: string, to: string): boolean {\n // Adding edge \"from depends_on to\". Check if to can already reach from\n // through existing depends_on edges. If so, adding this edge creates a cycle.\n const db = getDb();\n const visited = new Set<string>();\n const stack = [to];\n\n while (stack.length > 0) {\n const current = stack.pop()!;\n if (current === from) return true;\n if (visited.has(current)) continue;\n visited.add(current);\n\n // Follow forward depends_on edges: what does current depend on?\n const deps = db\n .prepare(\n `SELECT to_node FROM edges WHERE from_node = ? AND type = 'depends_on'`\n )\n .all(current) as Array<{ to_node: string }>;\n\n for (const dep of deps) {\n stack.push(dep.to_node);\n }\n }\n\n return false;\n}\n\n// --- Add edge ---\n\nexport interface AddEdgeInput {\n from: string;\n to: string;\n type: string;\n agent: string;\n}\n\nexport interface AddEdgeResult {\n edge: Edge | null;\n rejected: boolean;\n reason?: string;\n}\n\nexport function addEdge(input: AddEdgeInput): AddEdgeResult {\n const db = getDb();\n\n // Check nodes exist\n const fromExists = db.prepare(\"SELECT id FROM nodes WHERE id = ?\").get(input.from);\n const toExists = db.prepare(\"SELECT id FROM nodes WHERE id = ?\").get(input.to);\n\n if (!fromExists) {\n return { edge: null, rejected: true, reason: \"node_not_found: \" + input.from };\n }\n if (!toExists) {\n return { edge: null, rejected: true, reason: \"node_not_found: \" + input.to };\n }\n\n // Check for duplicates\n const existing = db\n .prepare(\n \"SELECT id FROM edges WHERE from_node = ? AND to_node = ? AND type = ?\"\n )\n .get(input.from, input.to, input.type);\n\n if (existing) {\n return { edge: null, rejected: true, reason: \"duplicate_edge\" };\n }\n\n // Cycle detection for depends_on\n if (input.type === \"depends_on\") {\n if (wouldCreateCycle(input.from, input.to)) {\n return { edge: null, rejected: true, reason: \"cycle_detected\" };\n }\n }\n\n const edge: Edge = {\n id: nanoid(),\n from_node: input.from,\n to_node: input.to,\n type: input.type,\n created_at: new Date().toISOString(),\n };\n\n db.prepare(`\n INSERT INTO edges (id, from_node, to_node, type, created_at)\n VALUES (?, ?, ?, ?, ?)\n `).run(edge.id, edge.from_node, edge.to_node, edge.type, edge.created_at);\n\n logEvent(input.from, input.agent, \"edge_added\", [\n { field: \"edge\", before: null, after: { to: input.to, type: input.type } },\n ]);\n\n return { edge, rejected: false };\n}\n\n// --- Remove edge ---\n\nexport function removeEdge(\n from: string,\n to: string,\n type: string,\n agent: string\n): boolean {\n const db = getDb();\n\n const result = db\n .prepare(\n \"DELETE FROM edges WHERE from_node = ? AND to_node = ? AND type = ?\"\n )\n .run(from, to, type);\n\n if (result.changes > 0) {\n logEvent(from, agent, \"edge_removed\", [\n { field: \"edge\", before: { to, type }, after: null },\n ]);\n return true;\n }\n\n return false;\n}\n\n// --- Query edges ---\n\nexport function getEdgesFrom(nodeId: string, type?: string): Edge[] {\n const db = getDb();\n\n if (type) {\n return db\n .prepare(\"SELECT * FROM edges WHERE from_node = ? AND type = ?\")\n .all(nodeId, type) as Edge[];\n }\n\n return db\n .prepare(\"SELECT * FROM edges WHERE from_node = ?\")\n .all(nodeId) as Edge[];\n}\n\nexport function getEdgesTo(nodeId: string, type?: string): Edge[] {\n const db = getDb();\n\n if (type) {\n return db\n .prepare(\"SELECT * FROM edges WHERE to_node = ? AND type = ?\")\n .all(nodeId, type) as Edge[];\n }\n\n return db\n .prepare(\"SELECT * FROM edges WHERE to_node = ?\")\n .all(nodeId) as Edge[];\n}\n\n// [sl:uRocbNC_bArUXGr908Qbk] Find newly actionable nodes\n// Targeted: accepts resolved node IDs, checks only direct dependents.\n// Falls back to project-wide scan when no IDs provided.\n\nexport function findNewlyActionable(\n project: string,\n resolvedNodeIds?: string[]\n): Array<{ id: string; summary: string }> {\n const db = getDb();\n\n if (resolvedNodeIds && resolvedNodeIds.length > 0) {\n // Targeted: only check direct dependents of the resolved nodes + children of resolved nodes\n const placeholders = resolvedNodeIds.map(() => \"?\").join(\",\");\n const rows = db\n .prepare(\n `SELECT DISTINCT n.id, n.summary FROM nodes n\n WHERE n.resolved = 0 AND n.project = ?\n AND (\n -- nodes that had a depends_on edge to one of the resolved nodes\n n.id IN (\n SELECT e.from_node FROM edges e\n WHERE e.type = 'depends_on' AND e.to_node IN (${placeholders})\n )\n OR\n -- parents of resolved nodes (might now be leaf if all children resolved)\n n.id IN (SELECT parent FROM nodes WHERE id IN (${placeholders}) AND parent IS NOT NULL)\n )\n -- is a leaf (no unresolved children)\n AND NOT EXISTS (\n SELECT 1 FROM nodes child WHERE child.parent = n.id AND child.resolved = 0\n )\n -- all deps resolved\n AND NOT EXISTS (\n SELECT 1 FROM edges e\n JOIN nodes dep ON dep.id = e.to_node AND dep.resolved = 0\n WHERE e.from_node = n.id AND e.type = 'depends_on'\n )`\n )\n .all(project, ...resolvedNodeIds, ...resolvedNodeIds) as Array<{\n id: string;\n summary: string;\n }>;\n\n return rows;\n }\n\n // Fallback: project-wide scan\n const rows = db\n .prepare(\n `SELECT n.id, n.summary FROM nodes n\n WHERE n.project = ? AND n.resolved = 0\n AND NOT EXISTS (\n SELECT 1 FROM nodes child WHERE child.parent = n.id AND child.resolved = 0\n )\n AND NOT EXISTS (\n SELECT 1 FROM edges e\n JOIN nodes dep ON dep.id = e.to_node AND dep.resolved = 0\n WHERE e.from_node = n.id AND e.type = 'depends_on'\n )`\n )\n .all(project) as Array<{ id: string; summary: string }>;\n\n return rows;\n}\n","import { getDb } from \"../db.js\";\nimport { createNode, getNode } from \"../nodes.js\";\nimport { addEdge } from \"../edges.js\";\nimport { requireArray, requireString, ValidationError, EngineError } from \"../validate.js\";\n\nexport interface PlanNodeInput {\n ref: string;\n parent_ref?: string;\n summary: string;\n context_links?: string[];\n depends_on?: string[];\n properties?: Record<string, unknown>;\n}\n\nexport interface PlanInput {\n nodes: PlanNodeInput[];\n}\n\nexport interface PlanResult {\n created: Array<{ ref: string; id: string }>;\n}\n\nexport function handlePlan(input: PlanInput, agent: string): PlanResult {\n const db = getDb();\n const nodes = requireArray<PlanNodeInput>(input?.nodes, \"nodes\");\n\n // Validate each node has required fields\n for (let i = 0; i < nodes.length; i++) {\n const n = nodes[i];\n requireString(n.ref, `nodes[${i}].ref`);\n requireString(n.summary, `nodes[${i}].summary`);\n }\n\n // Ref -> real ID mapping\n const refMap = new Map<string, string>();\n const created: Array<{ ref: string; id: string }> = [];\n\n // Validate refs are unique\n const refs = new Set<string>();\n for (const node of nodes) {\n if (refs.has(node.ref)) {\n throw new Error(`Duplicate ref in batch: ${node.ref}`);\n }\n refs.add(node.ref);\n }\n\n // Run atomically\n const transaction = db.transaction(() => {\n // First pass: create all nodes\n for (const nodeInput of nodes) {\n // Resolve parent\n let parentId: string | undefined;\n if (nodeInput.parent_ref) {\n // Check if it's a batch ref or existing node ID\n parentId = refMap.get(nodeInput.parent_ref);\n if (!parentId) {\n // Try as existing node ID\n const existing = getNode(nodeInput.parent_ref);\n if (existing) {\n parentId = existing.id;\n } else {\n throw new Error(\n `parent_ref \"${nodeInput.parent_ref}\" is neither a batch ref nor an existing node ID`\n );\n }\n }\n }\n\n // Determine project from parent or require first node to have a parent\n let project: string;\n if (parentId) {\n const parentNode = getNode(parentId)!;\n // [sl:m3_UNy-eICtHeHExfHwUH] Block decomposition when node has pending discovery\n if (parentNode.discovery === \"pending\") {\n throw new EngineError(\n \"discovery_pending\",\n `Cannot add children to \"${parentNode.summary}\" — discovery is pending. Complete the discovery interview first (set discovery to 'done' via graph_update), then decompose.`\n );\n }\n project = parentNode.project;\n } else {\n // If no parent, the node must be a root. But we need a project.\n // Infer from first node that has a parent, or error.\n throw new Error(\n `Node \"${nodeInput.ref}\" has no parent_ref. All planned nodes must have a parent (an existing node or a batch ref).`\n );\n }\n\n const node = createNode({\n project,\n parent: parentId,\n summary: nodeInput.summary,\n context_links: nodeInput.context_links,\n properties: nodeInput.properties,\n agent,\n });\n\n refMap.set(nodeInput.ref, node.id);\n created.push({ ref: nodeInput.ref, id: node.id });\n }\n\n // Second pass: create dependency edges\n for (const nodeInput of nodes) {\n if (!nodeInput.depends_on || nodeInput.depends_on.length === 0) continue;\n\n const fromId = refMap.get(nodeInput.ref)!;\n\n for (const dep of nodeInput.depends_on) {\n // Resolve dep: batch ref or existing node ID\n let toId = refMap.get(dep);\n if (!toId) {\n const existing = getNode(dep);\n if (existing) {\n toId = existing.id;\n } else {\n throw new Error(\n `depends_on \"${dep}\" in node \"${nodeInput.ref}\" is neither a batch ref nor an existing node ID`\n );\n }\n }\n\n const result = addEdge({\n from: fromId,\n to: toId,\n type: \"depends_on\",\n agent,\n });\n\n if (result.rejected) {\n throw new Error(\n `Dependency edge from \"${nodeInput.ref}\" to \"${dep}\" rejected: ${result.reason}`\n );\n }\n }\n }\n });\n\n transaction();\n\n return { created };\n}\n","import { updateNode, getNode, getChildren } from \"../nodes.js\";\nimport { findNewlyActionable } from \"../edges.js\";\nimport { requireArray, requireString } from \"../validate.js\";\n\nexport interface UpdateEntry {\n node_id: string;\n resolved?: boolean;\n resolved_reason?: string; // [sl:QBEtldx8PBWACftEM8MYl] Shorthand — auto-creates note evidence\n discovery?: string | null;\n state?: unknown;\n summary?: string;\n properties?: Record<string, unknown>;\n add_context_links?: string[];\n remove_context_links?: string[];\n add_evidence?: Array<{ type: string; ref: string }>;\n}\n\nexport interface UpdateInput {\n updates: UpdateEntry[];\n}\n\nexport interface UpdateResult {\n updated: Array<{ node_id: string; rev: number }>;\n newly_actionable?: Array<{ id: string; summary: string }>;\n auto_resolved?: Array<{ node_id: string; summary: string }>;\n}\n\nexport function handleUpdate(input: UpdateInput, agent: string): UpdateResult {\n const updates = requireArray<UpdateEntry>(input?.updates, \"updates\");\n\n for (let i = 0; i < updates.length; i++) {\n requireString(updates[i].node_id, `updates[${i}].node_id`);\n if (updates[i].add_evidence) {\n for (let j = 0; j < updates[i].add_evidence!.length; j++) {\n requireString(updates[i].add_evidence![j].type, `updates[${i}].add_evidence[${j}].type`);\n requireString(updates[i].add_evidence![j].ref, `updates[${i}].add_evidence[${j}].ref`);\n }\n }\n }\n\n const updated: Array<{ node_id: string; rev: number }> = [];\n const resolvedIds: string[] = [];\n let project: string | null = null;\n\n for (const entry of updates) {\n // Expand resolved_reason shorthand into evidence\n let evidence = entry.add_evidence;\n if (entry.resolved_reason) {\n evidence = [...(evidence ?? []), { type: \"note\", ref: entry.resolved_reason }];\n }\n\n const node = updateNode({\n node_id: entry.node_id,\n agent,\n resolved: entry.resolved,\n discovery: entry.discovery,\n state: entry.state,\n summary: entry.summary,\n properties: entry.properties,\n add_context_links: entry.add_context_links,\n remove_context_links: entry.remove_context_links,\n add_evidence: evidence,\n });\n\n updated.push({ node_id: node.id, rev: node.rev });\n\n if (entry.resolved === true) {\n resolvedIds.push(node.id);\n project = node.project;\n }\n }\n\n // [sl:GBuFbmTFuFfnl5KWW-ja-] Auto-resolve parents when all children are resolved\n const autoResolved: Array<{ node_id: string; summary: string }> = [];\n if (resolvedIds.length > 0) {\n const seen = new Set<string>(resolvedIds);\n const queue = [...resolvedIds];\n\n while (queue.length > 0) {\n const nodeId = queue.shift()!;\n const node = getNode(nodeId);\n if (!node?.parent) continue;\n\n const parentId = node.parent;\n if (seen.has(parentId)) continue;\n seen.add(parentId);\n\n const parent = getNode(parentId);\n if (!parent || parent.resolved) continue;\n\n const children = getChildren(parentId);\n if (children.length === 0) continue;\n if (children.every((c) => c.resolved)) {\n const resolved = updateNode({\n node_id: parentId,\n agent,\n resolved: true,\n add_evidence: [{ type: \"note\", ref: \"Auto-resolved: all children completed\" }],\n });\n updated.push({ node_id: resolved.id, rev: resolved.rev });\n resolvedIds.push(parentId);\n autoResolved.push({ node_id: parentId, summary: parent.summary });\n queue.push(parentId);\n }\n }\n }\n\n const result: UpdateResult = { updated };\n\n if (resolvedIds.length > 0 && project) {\n result.newly_actionable = findNewlyActionable(project, resolvedIds);\n }\n\n if (autoResolved.length > 0) {\n result.auto_resolved = autoResolved;\n }\n\n return result;\n}\n","import { addEdge, removeEdge } from \"../edges.js\";\nimport { requireArray, requireString } from \"../validate.js\";\n\nexport interface ConnectEdgeInput {\n from: string;\n to: string;\n type: string;\n remove?: boolean;\n}\n\nexport interface ConnectInput {\n edges: ConnectEdgeInput[];\n}\n\nexport interface ConnectResult {\n applied: number;\n rejected?: Array<{ from: string; to: string; reason: string }>;\n}\n\nexport function handleConnect(input: ConnectInput, agent: string): ConnectResult {\n const edges = requireArray<ConnectEdgeInput>(input?.edges, \"edges\");\n\n for (let i = 0; i < edges.length; i++) {\n requireString(edges[i].from, `edges[${i}].from`);\n requireString(edges[i].to, `edges[${i}].to`);\n requireString(edges[i].type, `edges[${i}].type`);\n }\n\n let applied = 0;\n const rejected: Array<{ from: string; to: string; reason: string }> = [];\n\n for (const edge of edges) {\n if (edge.type === \"parent\") {\n rejected.push({\n from: edge.from,\n to: edge.to,\n reason: \"parent_edges_not_allowed: use graph_restructure to reparent\",\n });\n continue;\n }\n\n if (edge.remove) {\n const removed = removeEdge(edge.from, edge.to, edge.type, agent);\n if (removed) {\n applied++;\n } else {\n rejected.push({\n from: edge.from,\n to: edge.to,\n reason: \"edge_not_found\",\n });\n }\n } else {\n const result = addEdge({\n from: edge.from,\n to: edge.to,\n type: edge.type,\n agent,\n });\n\n if (result.rejected) {\n rejected.push({\n from: edge.from,\n to: edge.to,\n reason: result.reason!,\n });\n } else {\n applied++;\n }\n }\n }\n\n const result: ConnectResult = { applied };\n if (rejected.length > 0) {\n result.rejected = rejected;\n }\n return result;\n}\n","import { getNodeOrThrow, getChildren, getAncestors } from \"../nodes.js\";\nimport { getEdgesFrom, getEdgesTo } from \"../edges.js\";\nimport { getNode } from \"../nodes.js\";\nimport { requireString, optionalNumber } from \"../validate.js\";\nimport type { Node } from \"../types.js\";\n\nexport interface ContextInput {\n node_id: string;\n depth?: number;\n}\n\ninterface NodeTree {\n id: string;\n summary: string;\n resolved: boolean;\n discovery: string | null;\n state: unknown;\n children?: NodeTree[];\n child_count?: number;\n}\n\nexport interface ContextResult {\n node: Node;\n ancestors: Array<{ id: string; summary: string; resolved: boolean }>;\n children: NodeTree;\n depends_on: Array<{ node: Node; satisfied: boolean }>;\n depended_by: Array<{ node: Node; satisfied: boolean }>;\n}\n\nfunction buildNodeTree(nodeId: string, currentDepth: number, maxDepth: number): NodeTree {\n const node = getNodeOrThrow(nodeId);\n const children = getChildren(nodeId);\n\n const tree: NodeTree = {\n id: node.id,\n summary: node.summary,\n resolved: node.resolved,\n discovery: node.discovery,\n state: node.state,\n };\n\n if (children.length === 0) {\n return tree;\n }\n\n if (currentDepth < maxDepth) {\n tree.children = children.map((child) =>\n buildNodeTree(child.id, currentDepth + 1, maxDepth)\n );\n } else {\n tree.child_count = children.length;\n }\n\n return tree;\n}\n\nexport function handleContext(input: ContextInput): ContextResult {\n const nodeId = requireString(input?.node_id, \"node_id\");\n const depth = optionalNumber(input?.depth, \"depth\", 0, 10) ?? 2;\n const node = getNodeOrThrow(nodeId);\n const ancestors = getAncestors(nodeId);\n\n // Build children tree\n const children = buildNodeTree(nodeId, 0, depth);\n\n // Get dependency edges\n const depsOut = getEdgesFrom(nodeId, \"depends_on\");\n const depsIn = getEdgesTo(nodeId, \"depends_on\");\n\n const depends_on = depsOut.map((edge) => {\n const target = getNode(edge.to_node);\n return {\n node: target!,\n satisfied: target?.resolved ?? false,\n };\n });\n\n const depended_by = depsIn.map((edge) => {\n const source = getNode(edge.from_node);\n return {\n node: source!,\n satisfied: node.resolved,\n };\n });\n\n return { node, ancestors, children, depends_on, depended_by };\n}\n","import { getDb } from \"../db.js\";\nimport { requireString, optionalNumber, optionalString } from \"../validate.js\";\nimport type { NodeRow } from \"../types.js\";\n\nexport interface QueryFilter {\n resolved?: boolean;\n properties?: Record<string, unknown>;\n text?: string;\n ancestor?: string;\n has_evidence_type?: string;\n is_leaf?: boolean;\n is_actionable?: boolean;\n is_blocked?: boolean;\n claimed_by?: string | null;\n}\n\nexport interface QueryInput {\n project: string;\n filter?: QueryFilter;\n sort?: \"readiness\" | \"depth\" | \"recent\" | \"created\";\n limit?: number;\n cursor?: string;\n}\n\nexport interface QueryResultNode {\n id: string;\n summary: string;\n resolved: boolean;\n state: unknown;\n parent: string | null;\n depth: number;\n properties: Record<string, unknown>;\n}\n\nexport interface QueryResult {\n nodes: QueryResultNode[];\n total: number;\n next_cursor?: string;\n}\n\n// [sl:tfMDHhmJSXd5TPgwD2ZC6] Descendant lookup via recursive CTE (replaced JS BFS)\nfunction getDescendantIds(nodeId: string): string[] {\n const db = getDb();\n const rows = db\n .prepare(\n `WITH RECURSIVE descendants(id) AS (\n SELECT id FROM nodes WHERE parent = ?\n UNION ALL\n SELECT n.id FROM nodes n JOIN descendants d ON n.parent = d.id\n )\n SELECT id FROM descendants`\n )\n .all(nodeId) as Array<{ id: string }>;\n\n return rows.map((r) => r.id);\n}\n\n\nexport function handleQuery(input: QueryInput): QueryResult {\n const project = requireString(input?.project, \"project\");\n const db = getDb();\n const limit = Math.min(optionalNumber(input?.limit, \"limit\", 1, 100) ?? 20, 100);\n const filter = input?.filter;\n const cursor = optionalString(input?.cursor, \"cursor\");\n\n // Build WHERE clauses\n const conditions: string[] = [\"n.project = ?\"];\n const params: unknown[] = [project];\n\n if (filter?.resolved !== undefined) {\n conditions.push(\"n.resolved = ?\");\n params.push(filter.resolved ? 1 : 0);\n }\n\n if (filter?.text) {\n conditions.push(\"n.summary LIKE ?\");\n params.push(`%${filter.text}%`);\n }\n\n if (filter?.ancestor) {\n const descendantIds = getDescendantIds(filter.ancestor);\n if (descendantIds.length === 0) {\n return { nodes: [], total: 0 };\n }\n conditions.push(`n.id IN (${descendantIds.map(() => \"?\").join(\",\")})`);\n params.push(...descendantIds);\n }\n\n if (filter?.has_evidence_type) {\n conditions.push(\"n.evidence LIKE ?\");\n params.push(`%\"type\":\"${filter.has_evidence_type}\"%`);\n }\n\n if (filter?.is_leaf) {\n conditions.push(\n \"NOT EXISTS (SELECT 1 FROM nodes child WHERE child.parent = n.id AND child.resolved = 0)\"\n );\n }\n\n if (filter?.is_actionable) {\n conditions.push(\"n.resolved = 0\");\n conditions.push(\n \"NOT EXISTS (SELECT 1 FROM nodes child WHERE child.parent = n.id AND child.resolved = 0)\"\n );\n conditions.push(\n `NOT EXISTS (\n SELECT 1 FROM edges e\n JOIN nodes dep ON dep.id = e.to_node AND dep.resolved = 0\n WHERE e.from_node = n.id AND e.type = 'depends_on'\n )`\n );\n }\n\n if (filter?.is_blocked) {\n conditions.push(\"n.resolved = 0\");\n conditions.push(\n `EXISTS (\n SELECT 1 FROM edges e\n JOIN nodes dep ON dep.id = e.to_node AND dep.resolved = 0\n WHERE e.from_node = n.id AND e.type = 'depends_on'\n )`\n );\n }\n\n if (filter?.properties) {\n for (const [key, value] of Object.entries(filter.properties)) {\n conditions.push(\"json_extract(n.properties, ?) = ?\");\n params.push(`$.${key}`, value as string | number);\n }\n }\n\n if (filter?.claimed_by !== undefined) {\n if (filter.claimed_by === null) {\n conditions.push(\n \"(json_extract(n.properties, '$._claimed_by') IS NULL)\"\n );\n } else {\n conditions.push(\"json_extract(n.properties, '$._claimed_by') = ?\");\n params.push(filter.claimed_by);\n }\n }\n\n // Cursor: use created_at + id for stable pagination\n if (cursor) {\n const [cursorTime, cursorId] = cursor.split(\"|\");\n conditions.push(\"(n.created_at > ? OR (n.created_at = ? AND n.id > ?))\");\n params.push(cursorTime, cursorTime, cursorId);\n }\n\n const whereClause = conditions.join(\" AND \");\n\n // Sorting\n let orderBy: string;\n switch (input.sort) {\n case \"depth\":\n // Can't sort by computed depth in SQL easily, so sort by created and compute depth post-hoc\n orderBy = \"n.created_at ASC, n.id ASC\";\n break;\n case \"recent\":\n orderBy = \"n.updated_at DESC, n.id ASC\";\n break;\n case \"created\":\n orderBy = \"n.created_at ASC, n.id ASC\";\n break;\n case \"readiness\":\n default:\n orderBy = \"n.updated_at ASC, n.id ASC\";\n break;\n }\n\n // Count total\n // Count total (without cursor filter)\n const countConditions = cursor ? conditions.slice(0, -1) : conditions;\n const countParams = cursor ? params.slice(0, -3) : [...params];\n const total = (\n db.prepare(`SELECT COUNT(*) as count FROM nodes n WHERE ${countConditions.join(\" AND \")}`).get(...countParams) as { count: number }\n ).count;\n\n // Fetch\n params.push(limit + 1);\n const query = `SELECT * FROM nodes n WHERE ${whereClause} ORDER BY ${orderBy} LIMIT ?`;\n const rows = db.prepare(query).all(...params) as NodeRow[];\n\n const hasMore = rows.length > limit;\n const slice = hasMore ? rows.slice(0, limit) : rows;\n\n const nodes: QueryResultNode[] = slice.map((row) => ({\n id: row.id,\n summary: row.summary,\n resolved: row.resolved === 1,\n state: row.state ? JSON.parse(row.state) : null,\n parent: row.parent,\n depth: row.depth,\n properties: JSON.parse(row.properties),\n }));\n\n const result: QueryResult = { nodes, total };\n\n if (hasMore) {\n const last = slice[slice.length - 1];\n result.next_cursor = `${last.created_at}|${last.id}`;\n }\n\n return result;\n}\n","import { getDb } from \"../db.js\";\nimport { getNode, getAncestors, updateNode } from \"../nodes.js\";\nimport { getEdgesFrom } from \"../edges.js\";\nimport { requireString, optionalString, optionalNumber, optionalBoolean } from \"../validate.js\";\nimport type { Node, NodeRow, Evidence } from \"../types.js\";\n\nexport interface NextInput {\n project: string;\n scope?: string;\n filter?: Record<string, unknown>;\n count?: number;\n claim?: boolean;\n}\n\nexport interface NextResultNode {\n node: Node;\n ancestors: Array<{ id: string; summary: string }>;\n context_links: {\n self: string[];\n inherited: Array<{ node_id: string; links: string[] }>;\n };\n resolved_deps: Array<{\n id: string;\n summary: string;\n evidence: Evidence[];\n }>;\n}\n\nexport interface NextResult {\n nodes: NextResultNode[];\n}\n\nexport function handleNext(\n input: NextInput,\n agent: string,\n claimTtlMinutes: number = 60\n): NextResult {\n const project = requireString(input?.project, \"project\");\n const scope = optionalString(input?.scope, \"scope\");\n const count = optionalNumber(input?.count, \"count\", 1, 50) ?? 1;\n const claim = optionalBoolean(input?.claim, \"claim\") ?? false;\n const db = getDb();\n\n // [sl:HB5daFH1HlFXzuTluibnk] Scope filtering: restrict to descendants of a given node\n let scopeFilter = \"\";\n const scopeParams: unknown[] = [];\n if (scope) {\n const descendantIds = db\n .prepare(\n `WITH RECURSIVE descendants(id) AS (\n SELECT id FROM nodes WHERE parent = ?\n UNION ALL\n SELECT n.id FROM nodes n JOIN descendants d ON n.parent = d.id\n )\n SELECT id FROM descendants`\n )\n .all(scope) as Array<{ id: string }>;\n\n if (descendantIds.length === 0) {\n return { nodes: [] };\n }\n scopeFilter = `AND n.id IN (${descendantIds.map(() => \"?\").join(\",\")})`;\n scopeParams.push(...descendantIds.map((d) => d.id));\n }\n\n // Find actionable nodes: unresolved, leaf (no unresolved children), all deps resolved\n let query = `\n SELECT n.* FROM nodes n\n WHERE n.project = ? AND n.resolved = 0\n ${scopeFilter}\n AND NOT EXISTS (\n SELECT 1 FROM nodes child WHERE child.parent = n.id AND child.resolved = 0\n )\n AND NOT EXISTS (\n SELECT 1 FROM edges e\n JOIN nodes dep ON dep.id = e.to_node AND dep.resolved = 0\n WHERE e.from_node = n.id AND e.type = 'depends_on'\n )\n `;\n\n const params: unknown[] = [project, ...scopeParams];\n\n // Skip nodes claimed by other agents (if claim TTL hasn't expired)\n const claimCutoff = new Date(\n Date.now() - claimTtlMinutes * 60 * 1000\n ).toISOString();\n\n query += `\n AND (\n json_extract(n.properties, '$._claimed_by') IS NULL\n OR json_extract(n.properties, '$._claimed_by') = ?\n OR json_extract(n.properties, '$._claimed_at') <= ?\n )\n `;\n params.push(agent, claimCutoff);\n\n // Property filters\n if (input.filter) {\n for (const [key, value] of Object.entries(input.filter)) {\n query += \" AND json_extract(n.properties, ?) = ?\";\n params.push(`$.${key}`, value as string | number);\n }\n }\n\n // [sl:md48WyMYFlOf4KP99vmtv] Ranking fully in SQL — never loads more than N rows\n // Depth is cached on the node, priority extracted via json_extract\n query += `\n ORDER BY\n COALESCE(CAST(json_extract(n.properties, '$.priority') AS REAL), 0) DESC,\n n.depth DESC,\n n.updated_at ASC\n LIMIT ?\n `;\n params.push(count);\n\n const rows = db.prepare(query).all(...params) as NodeRow[];\n\n const selected = rows.map((row) => ({ row }));\n\n const results: NextResultNode[] = selected.map(({ row }) => {\n const node = getNode(row.id)!;\n const ancestors = getAncestors(row.id);\n\n // Context links: self + inherited from ancestors\n const inherited: Array<{ node_id: string; links: string[] }> = [];\n for (const anc of ancestors) {\n const ancNode = getNode(anc.id);\n if (ancNode && ancNode.context_links.length > 0) {\n inherited.push({ node_id: anc.id, links: ancNode.context_links });\n }\n }\n\n // Resolved dependencies\n const depEdges = getEdgesFrom(row.id, \"depends_on\");\n const resolved_deps = depEdges\n .map((edge) => {\n const depNode = getNode(edge.to_node);\n if (!depNode || !depNode.resolved) return null;\n return {\n id: depNode.id,\n summary: depNode.summary,\n evidence: depNode.evidence,\n };\n })\n .filter(Boolean) as NextResultNode[\"resolved_deps\"];\n\n // Claim if requested\n if (claim) {\n updateNode({\n node_id: node.id,\n agent,\n properties: {\n _claimed_by: agent,\n _claimed_at: new Date().toISOString(),\n },\n });\n }\n\n return {\n node: claim ? getNode(row.id)! : node,\n ancestors: ancestors.map((a) => ({ id: a.id, summary: a.summary })),\n context_links: {\n self: node.context_links,\n inherited,\n },\n resolved_deps,\n };\n });\n\n return { nodes: results };\n}\n","import { getDb } from \"../db.js\";\nimport { getNodeOrThrow, getNode, getChildren, updateNode } from \"../nodes.js\";\nimport { getEdgesFrom, getEdgesTo, findNewlyActionable } from \"../edges.js\";\nimport { logEvent } from \"../events.js\";\nimport { requireArray, requireString } from \"../validate.js\";\nimport type { Evidence } from \"../types.js\";\n\nexport interface MoveOp {\n op: \"move\";\n node_id: string;\n new_parent: string;\n}\n\nexport interface MergeOp {\n op: \"merge\";\n source: string;\n target: string;\n}\n\nexport interface DropOp {\n op: \"drop\";\n node_id: string;\n reason: string;\n}\n\nexport type RestructureOp = MoveOp | MergeOp | DropOp;\n\nexport interface RestructureInput {\n operations: RestructureOp[];\n}\n\nexport interface RestructureResult {\n applied: number;\n details: Array<{ op: string; node_id: string; result: string }>;\n newly_actionable?: Array<{ id: string; summary: string }>;\n}\n\nfunction wouldCreateParentCycle(nodeId: string, newParentId: string): boolean {\n // Check if newParentId is a descendant of nodeId (which would create a cycle)\n const db = getDb();\n let current: string | null = newParentId;\n\n while (current) {\n if (current === nodeId) return true;\n const row = db\n .prepare(\"SELECT parent FROM nodes WHERE id = ?\")\n .get(current) as { parent: string | null } | undefined;\n current = row?.parent ?? null;\n }\n\n return false;\n}\n\nfunction getAllDescendants(nodeId: string): string[] {\n const ids: string[] = [];\n const stack = [nodeId];\n\n while (stack.length > 0) {\n const current = stack.pop()!;\n const children = getChildren(current);\n for (const child of children) {\n ids.push(child.id);\n stack.push(child.id);\n }\n }\n\n return ids;\n}\n\nfunction recomputeSubtreeDepth(nodeId: string, newDepth: number): void {\n const db = getDb();\n db.prepare(\"UPDATE nodes SET depth = ? WHERE id = ?\").run(newDepth, nodeId);\n const children = db.prepare(\"SELECT id FROM nodes WHERE parent = ?\").all(nodeId) as Array<{ id: string }>;\n for (const child of children) {\n recomputeSubtreeDepth(child.id, newDepth + 1);\n }\n}\n\nfunction handleMove(op: MoveOp, agent: string): { node_id: string; result: string } {\n const db = getDb();\n const node = getNodeOrThrow(op.node_id);\n const newParent = getNodeOrThrow(op.new_parent);\n\n if (wouldCreateParentCycle(op.node_id, op.new_parent)) {\n throw new Error(\n `Move would create cycle: ${op.node_id} cannot be moved under ${op.new_parent}`\n );\n }\n\n const oldParent = node.parent;\n const now = new Date().toISOString();\n db.prepare(\"UPDATE nodes SET parent = ?, updated_at = ? WHERE id = ?\").run(\n op.new_parent,\n now,\n op.node_id\n );\n\n // Recompute depth for moved node and all descendants\n recomputeSubtreeDepth(op.node_id, newParent.depth + 1);\n\n logEvent(op.node_id, agent, \"moved\", [\n { field: \"parent\", before: oldParent, after: op.new_parent },\n ]);\n\n return { node_id: op.node_id, result: `moved under ${op.new_parent}` };\n}\n\nfunction handleMerge(op: MergeOp, agent: string): { node_id: string; result: string } {\n const db = getDb();\n const source = getNodeOrThrow(op.source);\n const target = getNodeOrThrow(op.target);\n\n // Move source's children to target and recompute their depths\n const movedChildren = db.prepare(\"SELECT id FROM nodes WHERE parent = ?\").all(op.source) as Array<{ id: string }>;\n db.prepare(\"UPDATE nodes SET parent = ?, updated_at = ? WHERE parent = ?\").run(\n op.target,\n new Date().toISOString(),\n op.source\n );\n for (const child of movedChildren) {\n recomputeSubtreeDepth(child.id, target.depth + 1);\n }\n\n // Append source's evidence to target\n const targetEvidence: Evidence[] = [...target.evidence, ...source.evidence];\n db.prepare(\"UPDATE nodes SET evidence = ?, updated_at = ? WHERE id = ?\").run(\n JSON.stringify(targetEvidence),\n new Date().toISOString(),\n op.target\n );\n\n // Transfer source's dependency edges to target\n const sourceOutEdges = getEdgesFrom(op.source);\n const sourceInEdges = getEdgesTo(op.source);\n\n for (const edge of sourceOutEdges) {\n // source depends_on X -> target depends_on X\n const existing = db\n .prepare(\n \"SELECT id FROM edges WHERE from_node = ? AND to_node = ? AND type = ?\"\n )\n .get(op.target, edge.to_node, edge.type);\n\n if (!existing) {\n db.prepare(\n \"UPDATE edges SET from_node = ? WHERE id = ?\"\n ).run(op.target, edge.id);\n } else {\n db.prepare(\"DELETE FROM edges WHERE id = ?\").run(edge.id);\n }\n }\n\n for (const edge of sourceInEdges) {\n // X depends_on source -> X depends_on target\n const existing = db\n .prepare(\n \"SELECT id FROM edges WHERE from_node = ? AND to_node = ? AND type = ?\"\n )\n .get(edge.from_node, op.target, edge.type);\n\n if (!existing) {\n db.prepare(\n \"UPDATE edges SET to_node = ? WHERE id = ?\"\n ).run(op.target, edge.id);\n } else {\n db.prepare(\"DELETE FROM edges WHERE id = ?\").run(edge.id);\n }\n }\n\n // Log events\n logEvent(op.target, agent, \"merged\", [\n { field: \"merged_from\", before: null, after: op.source },\n ]);\n logEvent(op.source, agent, \"merged_into\", [\n { field: \"merged_into\", before: null, after: op.target },\n ]);\n\n // Delete source node\n db.prepare(\"DELETE FROM edges WHERE from_node = ? OR to_node = ?\").run(\n op.source,\n op.source\n );\n db.prepare(\"DELETE FROM nodes WHERE id = ?\").run(op.source);\n\n return { node_id: op.target, result: `merged ${op.source} into ${op.target}` };\n}\n\nfunction handleDrop(op: DropOp, agent: string): { node_id: string; result: string } {\n const now = new Date().toISOString();\n\n // Get all descendants\n const descendants = getAllDescendants(op.node_id);\n const allIds = [op.node_id, ...descendants];\n\n // Mark all as resolved with evidence\n for (const id of allIds) {\n const node = getNode(id);\n if (!node || node.resolved) continue;\n\n updateNode({\n node_id: id,\n agent,\n resolved: true,\n add_evidence: [{ type: \"dropped\", ref: op.reason }],\n });\n\n logEvent(id, agent, \"dropped\", [\n { field: \"resolved\", before: false, after: true },\n { field: \"reason\", before: null, after: op.reason },\n ]);\n }\n\n return {\n node_id: op.node_id,\n result: `dropped ${allIds.length} node(s): ${op.reason}`,\n };\n}\n\nexport function handleRestructure(\n input: RestructureInput,\n agent: string\n): RestructureResult {\n const operations = requireArray<RestructureOp>(input?.operations, \"operations\");\n\n for (let i = 0; i < operations.length; i++) {\n const op = operations[i];\n requireString(op.op, `operations[${i}].op`);\n if (op.op === \"move\") {\n requireString((op as MoveOp).node_id, `operations[${i}].node_id`);\n requireString((op as MoveOp).new_parent, `operations[${i}].new_parent`);\n } else if (op.op === \"merge\") {\n requireString((op as MergeOp).source, `operations[${i}].source`);\n requireString((op as MergeOp).target, `operations[${i}].target`);\n } else if (op.op === \"drop\") {\n requireString((op as DropOp).node_id, `operations[${i}].node_id`);\n requireString((op as DropOp).reason, `operations[${i}].reason`);\n } else {\n throw new Error(`Unknown operation: ${op.op}`);\n }\n }\n\n const db = getDb();\n let applied = 0;\n const details: Array<{ op: string; node_id: string; result: string }> = [];\n let project: string | null = null;\n\n const transaction = db.transaction(() => {\n for (const op of operations) {\n let detail: { node_id: string; result: string };\n\n switch (op.op) {\n case \"move\":\n detail = handleMove(op, agent);\n project = getNode(op.node_id)?.project ?? project;\n break;\n case \"merge\":\n detail = handleMerge(op, agent);\n project = getNode(op.target)?.project ?? project;\n break;\n case \"drop\":\n detail = handleDrop(op, agent);\n project = getNode(op.node_id)?.project ?? project;\n break;\n default:\n throw new Error(`Unknown operation: ${(op as RestructureOp).op}`);\n }\n\n details.push({ op: op.op, ...detail });\n applied++;\n }\n });\n\n transaction();\n\n const result: RestructureResult = { applied, details };\n\n if (project) {\n const actionable = findNewlyActionable(project);\n if (actionable.length > 0) {\n result.newly_actionable = actionable;\n }\n }\n\n return result;\n}\n","import { getEvents } from \"../events.js\";\nimport { getNodeOrThrow } from \"../nodes.js\";\nimport { requireString, optionalNumber, optionalString } from \"../validate.js\";\n\nexport interface HistoryInput {\n node_id: string;\n limit?: number;\n cursor?: string;\n}\n\nexport interface HistoryResult {\n events: Array<{\n timestamp: string;\n agent: string;\n action: string;\n changes: Array<{ field: string; before: unknown; after: unknown }>;\n }>;\n next_cursor?: string;\n}\n\nexport function handleHistory(input: HistoryInput): HistoryResult {\n const nodeId = requireString(input?.node_id, \"node_id\");\n const limit = optionalNumber(input?.limit, \"limit\", 1, 100) ?? 20;\n const cursor = optionalString(input?.cursor, \"cursor\");\n\n getNodeOrThrow(nodeId);\n\n const { events, next_cursor } = getEvents(nodeId, limit, cursor);\n\n const result: HistoryResult = {\n events: events.map((e) => ({\n timestamp: e.timestamp,\n agent: e.agent,\n action: e.action,\n changes: e.changes,\n })),\n };\n\n if (next_cursor) {\n result.next_cursor = next_cursor;\n }\n\n return result;\n}\n","import { getDb } from \"../db.js\";\nimport { getProjectRoot, getProjectSummary, listProjects } from \"../nodes.js\";\nimport { optionalString, optionalNumber } from \"../validate.js\";\nimport { EngineError } from \"../validate.js\";\nimport type { NodeRow, Evidence } from \"../types.js\";\n\n// [sl:yosc4NuV6j43Zv0fsDXDj] graph_onboard — single-call orientation for new agents\n\nexport interface OnboardInput {\n project?: string;\n evidence_limit?: number;\n}\n\nexport interface OnboardResult {\n project: string;\n goal: string;\n discovery: string | null;\n hint?: string;\n summary: {\n total: number;\n resolved: number;\n unresolved: number;\n blocked: number;\n actionable: number;\n };\n tree: Array<{\n id: string;\n summary: string;\n resolved: boolean;\n children: Array<{\n id: string;\n summary: string;\n resolved: boolean;\n child_count: number;\n }>;\n }>;\n recent_evidence: Array<{\n node_id: string;\n node_summary: string;\n type: string;\n ref: string;\n agent: string;\n timestamp: string;\n }>;\n context_links: string[];\n knowledge: Array<{\n key: string;\n content: string;\n updated_at: string;\n }>;\n recently_resolved: Array<{\n id: string;\n summary: string;\n resolved_at: string;\n agent: string;\n }>;\n last_activity: string | null;\n actionable: Array<{\n id: string;\n summary: string;\n properties: Record<string, unknown>;\n }>;\n}\n\n// [sl:1pRRsWFomcv04XAkdLMAj] Allow graph_onboard without project name\nexport function handleOnboard(input: OnboardInput): OnboardResult | { projects: ReturnType<typeof listProjects>; hint: string } {\n const evidenceLimit = optionalNumber(input?.evidence_limit, \"evidence_limit\", 1, 50) ?? 20;\n const db = getDb();\n\n // Auto-resolve project when not specified\n let project = optionalString(input?.project, \"project\");\n if (!project) {\n const projects = listProjects();\n if (projects.length === 0) {\n return {\n projects: [],\n hint: \"No projects yet. Create one with graph_open({ project: \\\"my-project\\\", goal: \\\"...\\\" }).\",\n };\n }\n if (projects.length === 1) {\n project = projects[0].project;\n } else {\n return {\n projects,\n hint: `${projects.length} projects found. Call graph_onboard with a specific project name.`,\n };\n }\n }\n\n // Verify project exists\n const root = getProjectRoot(project);\n if (!root) {\n throw new EngineError(\"project_not_found\", `Project not found: ${project}`);\n }\n\n // 1. Project summary counts\n const summary = getProjectSummary(project);\n\n // 2. Tree structure — root's children + their children (depth 1-2)\n const topChildren = db\n .prepare(\"SELECT * FROM nodes WHERE parent = ? ORDER BY created_at ASC\")\n .all(root.id) as NodeRow[];\n\n const tree = topChildren.map((child) => {\n const grandchildren = db\n .prepare(\n `SELECT id, summary, resolved,\n (SELECT COUNT(*) FROM nodes gc WHERE gc.parent = n.id) as child_count\n FROM nodes n WHERE parent = ? ORDER BY created_at ASC`\n )\n .all(child.id) as Array<{\n id: string;\n summary: string;\n resolved: number;\n child_count: number;\n }>;\n\n return {\n id: child.id,\n summary: child.summary,\n resolved: child.resolved === 1,\n discovery: child.discovery,\n children: grandchildren.map((gc) => ({\n id: gc.id,\n summary: gc.summary,\n resolved: gc.resolved === 1,\n child_count: gc.child_count,\n })),\n };\n });\n\n // 3. Recent evidence across all resolved nodes, sorted by timestamp\n const allNodes = db\n .prepare(\"SELECT id, summary, evidence FROM nodes WHERE project = ? AND resolved = 1 AND evidence != '[]'\")\n .all(project) as Array<{ id: string; summary: string; evidence: string }>;\n\n const allEvidence: OnboardResult[\"recent_evidence\"] = [];\n for (const node of allNodes) {\n const evidence: Evidence[] = JSON.parse(node.evidence);\n for (const ev of evidence) {\n allEvidence.push({\n node_id: node.id,\n node_summary: node.summary,\n type: ev.type,\n ref: ev.ref,\n agent: ev.agent,\n timestamp: ev.timestamp,\n });\n }\n }\n allEvidence.sort((a, b) => b.timestamp.localeCompare(a.timestamp));\n const recent_evidence = allEvidence.slice(0, evidenceLimit);\n\n // 4. All context_links aggregated and deduplicated\n const linkRows = db\n .prepare(\"SELECT context_links FROM nodes WHERE project = ? AND context_links != '[]'\")\n .all(project) as Array<{ context_links: string }>;\n\n const linkSet = new Set<string>();\n for (const row of linkRows) {\n const links: string[] = JSON.parse(row.context_links);\n for (const link of links) {\n linkSet.add(link);\n }\n }\n const context_links = [...linkSet].sort();\n\n // 5. Knowledge entries\n const knowledgeRows = db\n .prepare(\"SELECT key, content, updated_at FROM knowledge WHERE project = ? ORDER BY updated_at DESC\")\n .all(project) as Array<{ key: string; content: string; updated_at: string }>;\n\n // 6. Actionable tasks preview (like graph_next without claiming)\n const actionableRows = db\n .prepare(\n `SELECT n.id, n.summary, n.properties FROM nodes n\n WHERE n.project = ? AND n.resolved = 0\n AND NOT EXISTS (\n SELECT 1 FROM nodes child WHERE child.parent = n.id AND child.resolved = 0\n )\n AND NOT EXISTS (\n SELECT 1 FROM edges e\n JOIN nodes dep ON dep.id = e.to_node AND dep.resolved = 0\n WHERE e.from_node = n.id AND e.type = 'depends_on'\n )\n ORDER BY\n COALESCE(CAST(json_extract(n.properties, '$.priority') AS REAL), 0) DESC,\n n.depth DESC,\n n.updated_at ASC\n LIMIT 10`\n )\n .all(project) as Array<{ id: string; summary: string; properties: string }>;\n\n const actionable = actionableRows.map((row) => ({\n id: row.id,\n summary: row.summary,\n properties: JSON.parse(row.properties),\n }));\n\n // 7. Recently resolved nodes (last 24h) — cross-session continuity\n const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();\n const recentlyResolvedRows = db\n .prepare(\n `SELECT id, summary, updated_at,\n (SELECT json_extract(value, '$.agent') FROM json_each(evidence) ORDER BY json_extract(value, '$.timestamp') DESC LIMIT 1) as last_agent\n FROM nodes\n WHERE project = ? AND resolved = 1 AND updated_at > ?\n ORDER BY updated_at DESC\n LIMIT 10`\n )\n .all(project, oneDayAgo) as Array<{ id: string; summary: string; updated_at: string; last_agent: string | null }>;\n\n const recently_resolved = recentlyResolvedRows.map((row) => ({\n id: row.id,\n summary: row.summary,\n resolved_at: row.updated_at,\n agent: row.last_agent ?? \"unknown\",\n }));\n\n // 8. Last activity timestamp\n const lastActivityRow = db\n .prepare(\"SELECT MAX(updated_at) as last FROM nodes WHERE project = ?\")\n .get(project) as { last: string | null };\n const last_activity = lastActivityRow.last;\n\n // Build hint based on project state\n let hint: string | undefined;\n if (root.discovery === \"pending\") {\n hint = `Discovery is pending. Interview the user to understand scope and goals, write knowledge entries with findings, then set discovery to \"done\" via graph_update before decomposing with graph_plan.`;\n } else if (actionable.length > 0) {\n const recentNote = recently_resolved.length > 0\n ? ` ${recently_resolved.length} task(s) resolved recently.`\n : \"\";\n hint = `${actionable.length} actionable task(s) ready.${recentNote} Use graph_next({ project: \"${project}\", claim: true }) to claim one.`;\n } else if (summary.unresolved > 0 && summary.actionable === 0) {\n hint = `All remaining tasks are blocked. Check dependencies with graph_query.`;\n } else if (summary.total <= 1 && root.discovery !== \"pending\") {\n hint = `Project is empty — use graph_plan to decompose the goal into tasks.`;\n }\n\n return {\n project,\n goal: root.summary,\n discovery: root.discovery,\n hint,\n summary,\n tree,\n recent_evidence,\n context_links,\n knowledge: knowledgeRows,\n recently_resolved,\n last_activity,\n actionable,\n };\n}\n","import { getProjectRoot, getChildren } from \"../nodes.js\";\nimport { requireString, optionalNumber } from \"../validate.js\";\nimport { EngineError } from \"../validate.js\";\nimport type { Node } from \"../types.js\";\n\n// [sl:ahq-BLHS9pJkJUlBZO92L] Full tree visualization — \"show me the whole tree\"\n\nexport interface TreeInput {\n project: string;\n depth?: number;\n}\n\ninterface TreeNode {\n id: string;\n summary: string;\n resolved: boolean;\n properties: Record<string, unknown>;\n children?: TreeNode[];\n child_count?: number;\n}\n\nexport interface TreeResult {\n project: string;\n tree: TreeNode;\n stats: {\n total: number;\n resolved: number;\n unresolved: number;\n };\n}\n\nfunction buildTree(node: Node, currentDepth: number, maxDepth: number, stats: { total: number; resolved: number }): TreeNode {\n stats.total++;\n if (node.resolved) stats.resolved++;\n\n const children = getChildren(node.id);\n const treeNode: TreeNode = {\n id: node.id,\n summary: node.summary,\n resolved: node.resolved,\n properties: node.properties,\n };\n\n if (children.length === 0) return treeNode;\n\n if (currentDepth < maxDepth) {\n treeNode.children = children.map((child) =>\n buildTree(child, currentDepth + 1, maxDepth, stats)\n );\n } else {\n treeNode.child_count = children.length;\n }\n\n return treeNode;\n}\n\nexport function handleTree(input: TreeInput): TreeResult {\n const project = requireString(input?.project, \"project\");\n const depth = optionalNumber(input?.depth, \"depth\", 1, 20) ?? 10;\n\n const root = getProjectRoot(project);\n if (!root) {\n throw new EngineError(\"project_not_found\", `Project not found: ${project}`);\n }\n\n const stats = { total: 0, resolved: 0 };\n const tree = buildTree(root, 0, depth, stats);\n\n return {\n project,\n tree,\n stats: {\n total: stats.total,\n resolved: stats.resolved,\n unresolved: stats.total - stats.resolved,\n },\n };\n}\n","import { nanoid } from \"nanoid\";\nimport { getDb } from \"../db.js\";\nimport { getProjectRoot } from \"../nodes.js\";\nimport { EngineError, requireString } from \"../validate.js\";\n\n// [sl:4PrMkE09nf6ptz8LLR9rW] Knowledge tools — persistent project-level knowledge store\n\ninterface KnowledgeRow {\n id: string;\n project: string;\n key: string;\n content: string;\n created_by: string;\n created_at: string;\n updated_at: string;\n}\n\n// --- graph_knowledge_write ---\n\nexport interface KnowledgeWriteInput {\n project: string;\n key: string;\n content: string;\n}\n\nexport function handleKnowledgeWrite(input: KnowledgeWriteInput, agent: string) {\n const project = requireString(input.project, \"project\");\n const key = requireString(input.key, \"key\");\n const content = requireString(input.content, \"content\");\n\n const root = getProjectRoot(project);\n if (!root) {\n throw new EngineError(\"not_found\", `Project '${project}' not found`);\n }\n\n const db = getDb();\n const now = new Date().toISOString();\n\n const existing = db\n .prepare(\"SELECT id FROM knowledge WHERE project = ? AND key = ?\")\n .get(project, key) as { id: string } | undefined;\n\n if (existing) {\n db.prepare(\n \"UPDATE knowledge SET content = ?, updated_at = ? WHERE id = ?\"\n ).run(content, now, existing.id);\n return { key, action: \"updated\" };\n } else {\n const id = nanoid();\n db.prepare(\n \"INSERT INTO knowledge (id, project, key, content, created_by, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?)\"\n ).run(id, project, key, content, agent, now, now);\n return { key, action: \"created\" };\n }\n}\n\n// --- graph_knowledge_read ---\n\nexport interface KnowledgeReadInput {\n project: string;\n key?: string;\n}\n\nexport function handleKnowledgeRead(input: KnowledgeReadInput) {\n const project = requireString(input.project, \"project\");\n\n const root = getProjectRoot(project);\n if (!root) {\n throw new EngineError(\"not_found\", `Project '${project}' not found`);\n }\n\n const db = getDb();\n\n if (input.key) {\n const row = db\n .prepare(\"SELECT * FROM knowledge WHERE project = ? AND key = ?\")\n .get(project, input.key) as KnowledgeRow | undefined;\n\n if (!row) {\n throw new EngineError(\"not_found\", `Knowledge entry '${input.key}' not found in project '${project}'`);\n }\n\n return {\n key: row.key,\n content: row.content,\n updated_at: row.updated_at,\n created_by: row.created_by,\n };\n }\n\n // List all\n const rows = db\n .prepare(\"SELECT key, content, updated_at, created_by FROM knowledge WHERE project = ? ORDER BY updated_at DESC\")\n .all(project) as Array<{ key: string; content: string; updated_at: string; created_by: string }>;\n\n return { entries: rows };\n}\n\n// --- graph_knowledge_delete ---\n\nexport interface KnowledgeDeleteInput {\n project: string;\n key: string;\n}\n\nexport function handleKnowledgeDelete(input: KnowledgeDeleteInput) {\n const project = requireString(input.project, \"project\");\n const key = requireString(input.key, \"key\");\n\n const root = getProjectRoot(project);\n if (!root) {\n throw new EngineError(\"not_found\", `Project '${project}' not found`);\n }\n\n const db = getDb();\n const result = db\n .prepare(\"DELETE FROM knowledge WHERE project = ? AND key = ?\")\n .run(project, key);\n\n if (result.changes === 0) {\n throw new EngineError(\"not_found\", `Knowledge entry '${key}' not found in project '${project}'`);\n }\n\n return { key, action: \"deleted\" };\n}\n\n// --- graph_knowledge_search ---\n\nexport interface KnowledgeSearchInput {\n project: string;\n query: string;\n}\n\nexport function handleKnowledgeSearch(input: KnowledgeSearchInput) {\n const project = requireString(input.project, \"project\");\n const query = requireString(input.query, \"query\");\n\n const root = getProjectRoot(project);\n if (!root) {\n throw new EngineError(\"not_found\", `Project '${project}' not found`);\n }\n\n const db = getDb();\n const pattern = `%${query}%`;\n\n const rows = db\n .prepare(\n \"SELECT key, content, updated_at, created_by FROM knowledge WHERE project = ? AND (key LIKE ? OR content LIKE ?) ORDER BY updated_at DESC\"\n )\n .all(project, pattern, pattern) as Array<{ key: string; content: string; updated_at: string; created_by: string }>;\n\n return { entries: rows, query };\n}\n","import { getDb } from \"./db.js\";\nimport { EngineError } from \"./validate.js\";\nimport type { Tier } from \"./license.js\";\n\n// [sl:N0IDVJQIhENQFsov6-Lhg] Feature gates — enforce free vs pro limits\n\n// Limits relaxed — everything free while building user base (Phase 1: Acquisition)\nconst FREE_LIMITS = {\n maxProjects: Infinity,\n maxNodesPerProject: Infinity,\n onboardEvidenceLimit: 50,\n scopeEnabled: true,\n};\n\n/**\n * Check if creating nodes would exceed the free tier node limit.\n * Throws EngineError if limit would be exceeded.\n */\nexport function checkNodeLimit(tier: Tier, project: string, adding: number): void {\n if (tier === \"pro\") return;\n\n const db = getDb();\n const { count } = db\n .prepare(\"SELECT COUNT(*) as count FROM nodes WHERE project = ?\")\n .get(project) as { count: number };\n\n if (count + adding > FREE_LIMITS.maxNodesPerProject) {\n throw new EngineError(\n \"free_tier_limit\",\n `Free tier is limited to ${FREE_LIMITS.maxNodesPerProject} nodes per project. ` +\n `Current: ${count}, adding: ${adding}. Activate a license key to remove this limit.`\n );\n }\n}\n\n/**\n * Check if creating a new project would exceed the free tier project limit.\n * Throws EngineError if limit would be exceeded.\n */\nexport function checkProjectLimit(tier: Tier): void {\n if (tier === \"pro\") return;\n\n const db = getDb();\n const { count } = db\n .prepare(\"SELECT COUNT(*) as count FROM nodes WHERE parent IS NULL\")\n .get() as { count: number };\n\n if (count >= FREE_LIMITS.maxProjects) {\n throw new EngineError(\n \"free_tier_limit\",\n `Free tier is limited to ${FREE_LIMITS.maxProjects} project. ` +\n `Activate a license key to create unlimited projects.`\n );\n }\n}\n\n/**\n * Cap the evidence limit for graph_onboard on free tier.\n */\nexport function capEvidenceLimit(tier: Tier, requested?: number): number {\n const max = tier === \"pro\" ? (requested ?? 20) : FREE_LIMITS.onboardEvidenceLimit;\n return Math.min(requested ?? max, tier === \"pro\" ? 50 : FREE_LIMITS.onboardEvidenceLimit);\n}\n\n/**\n * Check if knowledge tools are allowed on the current tier.\n * Currently free for all — everything ungated during acquisition phase.\n */\nexport function checkKnowledgeTier(_tier: Tier): void {\n // All tiers allowed during acquisition phase\n return;\n}\n\n/**\n * Check if scope parameter is allowed.\n * Currently free for all during acquisition phase.\n */\nexport function checkScope(_tier: Tier, scope?: string): string | undefined {\n return scope;\n}\n"],"mappings":"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","names":["rows","result","nanoid","nanoid","getProjectRoot","getNode","listProjects"]}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts","../src/tools/open.ts","../src/edges.ts","../src/tools/plan.ts","../src/tools/update.ts","../src/tools/connect.ts","../src/tools/context.ts","../src/tools/query.ts","../src/tools/next.ts","../src/tools/restructure.ts","../src/tools/history.ts","../src/tools/onboard.ts","../src/tools/tree.ts","../src/tools/knowledge.ts","../src/gates.ts"],"sourcesContent":["import { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { setDbPath, closeDb, checkpointDb } from \"./db.js\";\nimport { ValidationError, EngineError } from \"./validate.js\";\nimport { handleOpen } from \"./tools/open.js\";\nimport { handlePlan } from \"./tools/plan.js\";\nimport { handleUpdate } from \"./tools/update.js\";\nimport { handleConnect } from \"./tools/connect.js\";\nimport { handleContext } from \"./tools/context.js\";\nimport { handleQuery } from \"./tools/query.js\";\nimport { handleNext } from \"./tools/next.js\";\nimport { handleRestructure } from \"./tools/restructure.js\";\nimport { handleHistory } from \"./tools/history.js\";\nimport { handleOnboard } from \"./tools/onboard.js\";\nimport { handleAgentConfig } from \"./tools/agent-config.js\";\nimport { handleTree } from \"./tools/tree.js\";\nimport { handleKnowledgeWrite, handleKnowledgeRead, handleKnowledgeDelete, handleKnowledgeSearch } from \"./tools/knowledge.js\";\nimport { getLicenseTier, type Tier } from \"./license.js\";\nimport { checkNodeLimit, checkProjectLimit, capEvidenceLimit, checkScope, checkKnowledgeTier } from \"./gates.js\";\n\nimport { createHash } from \"crypto\";\nimport { mkdirSync, readFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { join, resolve, dirname } from \"path\";\nimport { fileURLToPath } from \"url\";\n\n// Config from env\nconst AGENT_IDENTITY = process.env.GRAPH_AGENT ?? \"default-agent\";\nconst CLAIM_TTL = parseInt(process.env.GRAPH_CLAIM_TTL ?? \"60\", 10);\n\nfunction defaultDbPath(): string {\n const projectDir = resolve(\".\");\n const hash = createHash(\"sha256\").update(projectDir).digest(\"hex\").slice(0, 16);\n const dir = join(homedir(), \".graph\", \"db\", hash);\n mkdirSync(dir, { recursive: true });\n return join(dir, \"graph.db\");\n}\n\nconst DB_PATH = process.env.GRAPH_DB ?? defaultDbPath();\n\n// Read version from package.json\nconst PKG_NAME = \"@graph-tl/graph\";\nlet PKG_VERSION = \"0.0.0\";\ntry {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const pkg = JSON.parse(readFileSync(join(__dirname, \"..\", \"package.json\"), \"utf-8\"));\n PKG_VERSION = pkg.version;\n} catch {}\n\n// Version banner — shown once on first tool call\nlet versionBanner: string | null = `[graph] v${PKG_VERSION}`;\n\n// Non-blocking version check against npm registry\nlet updateWarning: string | null = null;\n\nasync function checkForUpdate(): Promise<void> {\n try {\n const res = await fetch(`https://registry.npmjs.org/${PKG_NAME}/latest`);\n if (!res.ok) return;\n const data = await res.json() as { version: string };\n if (data.version !== PKG_VERSION) {\n updateWarning = `[graph] Update available: ${PKG_VERSION} → ${data.version}. Run: npx clear-npx-cache && restart MCP server.`;\n }\n } catch {}\n}\n\n// Tool definitions\nconst TOOLS = [\n {\n name: \"graph_open\",\n description:\n \"Open an existing project or create a new one. Omit 'project' to list all projects. Returns project root node and summary stats (total, resolved, unresolved, blocked, actionable counts).\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: {\n type: \"string\",\n description: \"Project name (e.g. 'my-project'). Omit to list all projects.\",\n },\n goal: {\n type: \"string\",\n description: \"Project goal/description. Used on creation only.\",\n },\n },\n },\n },\n {\n name: \"graph_plan\",\n description:\n \"Batch create nodes with parent-child and dependency relationships in one atomic call. Use for decomposing work into subtrees. Each node needs a temp 'ref' for intra-batch references. parent_ref and depends_on can reference batch refs or existing node IDs.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n nodes: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n ref: {\n type: \"string\",\n description: \"Temp ID for referencing within this batch\",\n },\n parent_ref: {\n type: \"string\",\n description:\n \"Parent: a ref from this batch OR an existing node ID\",\n },\n summary: { type: \"string\" },\n context_links: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Pointers to files, commits, URLs\",\n },\n depends_on: {\n type: \"array\",\n items: { type: \"string\" },\n description:\n \"Refs within batch OR existing node IDs this depends on\",\n },\n properties: {\n type: \"object\",\n description: \"Freeform key-value properties\",\n },\n },\n required: [\"ref\", \"summary\"],\n },\n description: \"Nodes to create\",\n },\n },\n required: [\"nodes\"],\n },\n },\n {\n name: \"graph_next\",\n description:\n \"Get the next actionable node — an unresolved leaf with all dependencies resolved. Ranked by priority (from properties), depth, and least-recently-updated. Returns the node with ancestor chain, context links, and resolved dependency info. Use claim=true to soft-lock the node. When modifying code for this task, annotate key changes with // [sl:nodeId] so future agents can trace code back to this task.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: { type: \"string\", description: \"Project name (e.g. 'my-project'), not a node ID\" },\n scope: {\n type: \"string\",\n description: \"Node ID to scope results to. Only returns actionable descendants of this node.\",\n },\n filter: {\n type: \"object\",\n description: \"Match against node properties\",\n },\n count: {\n type: \"number\",\n description: \"Return top N nodes (default 1)\",\n },\n claim: {\n type: \"boolean\",\n description:\n \"If true, soft-lock returned nodes with agent identity\",\n },\n },\n required: [\"project\"],\n },\n },\n {\n name: \"graph_context\",\n description:\n \"Deep-read a node and its neighborhood: ancestors (scope chain), children tree (to configurable depth), dependency graph (what it depends on, what depends on it). Look for // [sl:nodeId] annotations in source files to find code tied to specific tasks.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n node_id: { type: \"string\", description: \"Node ID to inspect\" },\n depth: {\n type: \"number\",\n description: \"Levels of children to return (default 2)\",\n },\n },\n required: [\"node_id\"],\n },\n },\n {\n name: \"graph_update\",\n description:\n \"Update one or more nodes. Can change resolved, state, summary, properties (merged), context_links, and add evidence. When resolving nodes, returns newly_actionable — nodes that became unblocked. ENFORCED: Resolving a node requires evidence — the engine rejects resolved=true if the node has no existing evidence and no add_evidence in the call. Include at least one add_evidence entry (type: 'git' for commits, 'note' for what was done and why, 'test' for results). Also add context_links to files you modified.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n updates: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n node_id: { type: \"string\" },\n resolved: { type: \"boolean\" },\n discovery: { type: \"string\", description: \"Discovery phase status: 'pending' or 'done'. Set to 'done' after completing discovery interview.\" },\n state: { description: \"Agent-defined state, any type\" },\n summary: { type: \"string\" },\n properties: {\n type: \"object\",\n description:\n \"Merged into existing. Set a key to null to delete it.\",\n },\n add_context_links: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Files modified or created for this task. Add when resolving so future agents know what was touched.\",\n },\n remove_context_links: {\n type: \"array\",\n items: { type: \"string\" },\n },\n add_evidence: {\n type: \"array\",\n description: \"Evidence of work done. Always add when resolving. Types: 'git' (commit hash + summary), 'note' (what was implemented and why), 'test' (test results).\",\n items: {\n type: \"object\",\n properties: {\n type: { type: \"string\", description: \"Evidence type: git, note, test, or custom\" },\n ref: { type: \"string\", description: \"The evidence content — commit ref, implementation note, test result\" },\n },\n required: [\"type\", \"ref\"],\n },\n },\n },\n required: [\"node_id\"],\n },\n },\n },\n required: [\"updates\"],\n },\n },\n {\n name: \"graph_connect\",\n description:\n \"Add or remove edges between nodes. Types: 'depends_on' (with cycle detection), 'relates_to', or custom. Parent edges not allowed — use graph_restructure for reparenting.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n edges: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n from: { type: \"string\", description: \"Source node ID\" },\n to: { type: \"string\", description: \"Target node ID\" },\n type: {\n type: \"string\",\n description: \"'depends_on', 'relates_to', or custom\",\n },\n remove: {\n type: \"boolean\",\n description: \"True to remove this edge\",\n },\n },\n required: [\"from\", \"to\", \"type\"],\n },\n },\n },\n required: [\"edges\"],\n },\n },\n {\n name: \"graph_query\",\n description:\n \"Search and filter nodes. Filters: resolved, properties, text, ancestor (descendants of), is_leaf, is_actionable, is_blocked, claimed_by. Supports sorting and cursor pagination.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: { type: \"string\", description: \"Project name (e.g. 'my-project'), not a node ID\" },\n filter: {\n type: \"object\",\n properties: {\n resolved: { type: \"boolean\" },\n properties: { type: \"object\" },\n text: { type: \"string\", description: \"Substring match on summary\" },\n ancestor: {\n type: \"string\",\n description: \"Return all descendants of this node\",\n },\n has_evidence_type: { type: \"string\" },\n is_leaf: { type: \"boolean\" },\n is_actionable: { type: \"boolean\" },\n is_blocked: { type: \"boolean\" },\n claimed_by: {\n type: [\"string\", \"null\"],\n description: \"Filter by claim. null = unclaimed.\",\n },\n },\n },\n sort: {\n type: \"string\",\n enum: [\"readiness\", \"depth\", \"recent\", \"created\"],\n },\n limit: { type: \"number\", description: \"Max results (default 20, max 100)\" },\n cursor: { type: \"string\", description: \"Pagination cursor\" },\n },\n required: [\"project\"],\n },\n },\n {\n name: \"graph_restructure\",\n description:\n \"Modify graph structure: move (reparent), merge (combine two nodes), drop (resolve node + subtree with reason). Atomic. Reports newly_actionable nodes.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n operations: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n op: {\n type: \"string\",\n enum: [\"move\", \"merge\", \"drop\"],\n },\n node_id: { type: \"string\", description: \"For move and drop\" },\n new_parent: { type: \"string\", description: \"For move\" },\n source: { type: \"string\", description: \"For merge: node to absorb\" },\n target: {\n type: \"string\",\n description: \"For merge: node that survives\",\n },\n reason: { type: \"string\", description: \"For drop: why\" },\n },\n required: [\"op\"],\n },\n },\n },\n required: [\"operations\"],\n },\n },\n {\n name: \"graph_history\",\n description:\n \"Read the audit trail for a node. Shows who changed what, when, and why. Useful for understanding past decisions across sessions.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n node_id: { type: \"string\" },\n limit: { type: \"number\", description: \"Max events (default 20)\" },\n cursor: { type: \"string\", description: \"Pagination cursor\" },\n },\n required: [\"node_id\"],\n },\n },\n {\n name: \"graph_onboard\",\n description:\n \"Single-call orientation for new agents joining a project. Returns project summary, tree structure (depth 2), recent evidence from resolved nodes (knowledge transfer), all context links, and actionable tasks. Use this as your first call when starting work on an existing project.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: { type: \"string\", description: \"Project name (e.g. 'my-project'). Omit to auto-select (works when there's exactly one project).\" },\n evidence_limit: {\n type: \"number\",\n description: \"Max evidence entries to return (default 20, max 50)\",\n },\n },\n },\n },\n {\n name: \"graph_tree\",\n description:\n \"Full tree visualization for a project. Returns the complete task hierarchy with resolve status. Use when you need to see the whole project structure beyond graph_context's single-node neighborhood.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: { type: \"string\", description: \"Project name (e.g. 'my-project')\" },\n depth: {\n type: \"number\",\n description: \"Max tree depth to return (default 10, max 20)\",\n },\n },\n required: [\"project\"],\n },\n },\n {\n name: \"graph_agent_config\",\n description:\n \"Returns the graph-optimized agent configuration file for Claude Code. Save the returned content to .claude/agents/graph.md to enable the graph workflow agent.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {},\n },\n },\n {\n name: \"graph_knowledge_write\",\n description:\n \"Write a knowledge entry for a project. Creates or overwrites a named document. Use for persistent project-level knowledge (architecture decisions, conventions, API contracts) that outlives individual tasks.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: { type: \"string\", description: \"Project name\" },\n key: { type: \"string\", description: \"Knowledge entry key (e.g. 'auth', 'database-schema', 'api-contracts')\" },\n content: { type: \"string\", description: \"Free-form text content\" },\n },\n required: [\"project\", \"key\", \"content\"],\n },\n },\n {\n name: \"graph_knowledge_read\",\n description:\n \"Read knowledge entries for a project. Provide a key to read one entry, or omit to list all entries.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: { type: \"string\", description: \"Project name\" },\n key: { type: \"string\", description: \"Knowledge entry key. Omit to list all.\" },\n },\n required: [\"project\"],\n },\n },\n {\n name: \"graph_knowledge_delete\",\n description:\n \"Delete a knowledge entry from a project.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: { type: \"string\", description: \"Project name\" },\n key: { type: \"string\", description: \"Knowledge entry key to delete\" },\n },\n required: [\"project\", \"key\"],\n },\n },\n {\n name: \"graph_knowledge_search\",\n description:\n \"Search knowledge entries by substring match on key or content.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n project: { type: \"string\", description: \"Project name\" },\n query: { type: \"string\", description: \"Search string\" },\n },\n required: [\"project\", \"query\"],\n },\n },\n];\n\nexport async function startServer(): Promise<void> {\n // Set database path — db is created lazily on first tool call\n setDbPath(DB_PATH);\n\n // [sl:N0IDVJQIhENQFsov6-Lhg] Resolve license tier once at startup (reads license file, doesn't touch db)\n const tier: Tier = getLicenseTier(DB_PATH);\n\n const server = new Server(\n { name: \"graph\", version: PKG_VERSION },\n { capabilities: { tools: {} } }\n );\n\n // Fire-and-forget version check\n checkForUpdate();\n\n // List tools\n server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: TOOLS,\n }));\n\n // Handle tool calls\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n let result: unknown;\n\n switch (name) {\n case \"graph_open\": {\n const openArgs = args as any;\n // Gate: check project limit when creating a new project\n if (openArgs?.project) {\n const { getProjectRoot } = await import(\"./nodes.js\");\n if (!getProjectRoot(openArgs.project)) {\n checkProjectLimit(tier);\n }\n }\n result = handleOpen(openArgs, AGENT_IDENTITY);\n break;\n }\n\n case \"graph_plan\": {\n const planArgs = args as any;\n // Gate: check node limit before creating nodes\n if (planArgs?.nodes?.length > 0) {\n // Determine project from the first node's parent\n const { getNode } = await import(\"./nodes.js\");\n const firstParent = planArgs.nodes[0]?.parent_ref;\n if (firstParent && typeof firstParent === \"string\" && !planArgs.nodes.some((n: any) => n.ref === firstParent)) {\n const parentNode = getNode(firstParent);\n if (parentNode) {\n checkNodeLimit(tier, parentNode.project, planArgs.nodes.length);\n }\n }\n }\n result = handlePlan(planArgs, AGENT_IDENTITY);\n break;\n }\n\n case \"graph_next\": {\n const nextArgs = args as any;\n // Gate: strip scope on free tier\n if (nextArgs?.scope) {\n nextArgs.scope = checkScope(tier, nextArgs.scope);\n }\n result = handleNext(nextArgs, AGENT_IDENTITY, CLAIM_TTL);\n break;\n }\n\n case \"graph_context\":\n result = handleContext(args as any);\n break;\n\n case \"graph_update\":\n result = handleUpdate(args as any, AGENT_IDENTITY);\n break;\n\n case \"graph_connect\":\n result = handleConnect(args as any, AGENT_IDENTITY);\n break;\n\n case \"graph_query\":\n result = handleQuery(args as any);\n break;\n\n case \"graph_restructure\":\n result = handleRestructure(args as any, AGENT_IDENTITY);\n break;\n\n case \"graph_history\":\n result = handleHistory(args as any);\n break;\n\n case \"graph_onboard\": {\n const onboardArgs = args as any;\n // Gate: cap evidence limit on free tier\n onboardArgs.evidence_limit = capEvidenceLimit(tier, onboardArgs?.evidence_limit);\n result = handleOnboard(onboardArgs);\n break;\n }\n\n case \"graph_tree\":\n result = handleTree(args as any);\n break;\n\n case \"graph_agent_config\":\n result = handleAgentConfig();\n break;\n\n case \"graph_knowledge_write\":\n checkKnowledgeTier(tier);\n result = handleKnowledgeWrite(args as any, AGENT_IDENTITY);\n break;\n\n case \"graph_knowledge_read\":\n checkKnowledgeTier(tier);\n result = handleKnowledgeRead(args as any);\n break;\n\n case \"graph_knowledge_delete\":\n checkKnowledgeTier(tier);\n result = handleKnowledgeDelete(args as any);\n break;\n\n case \"graph_knowledge_search\":\n checkKnowledgeTier(tier);\n result = handleKnowledgeSearch(args as any);\n break;\n\n default:\n return {\n content: [\n { type: \"text\" as const, text: JSON.stringify({ error: `Unknown tool: ${name}` }) },\n ],\n isError: true,\n };\n }\n\n const content: Array<{ type: \"text\"; text: string }> = [\n { type: \"text\" as const, text: JSON.stringify(result, null, 2) },\n ];\n if (versionBanner) {\n content.push({ type: \"text\" as const, text: updateWarning ? `${versionBanner} — ${updateWarning}` : versionBanner });\n versionBanner = null;\n updateWarning = null;\n }\n return { content };\n } catch (error) {\n const message =\n error instanceof Error ? error.message : String(error);\n const code =\n error instanceof ValidationError\n ? \"validation_error\"\n : error instanceof EngineError\n ? (error as EngineError).code\n : \"error\";\n return {\n content: [\n {\n type: \"text\" as const,\n text: JSON.stringify({ error: message, code }),\n },\n ],\n isError: true,\n };\n }\n });\n\n // Connect transport\n const transport = new StdioServerTransport();\n await server.connect(transport);\n\n // Periodic WAL checkpoint every 30s — flushes WAL data into main db file\n const checkpointInterval = setInterval(() => {\n try { checkpointDb(); } catch {}\n }, 30_000);\n\n // Cleanup on exit\n process.on(\"SIGINT\", () => {\n clearInterval(checkpointInterval);\n closeDb();\n process.exit(0);\n });\n process.on(\"SIGTERM\", () => {\n clearInterval(checkpointInterval);\n closeDb();\n process.exit(0);\n });\n}\n","import { createNode, getProjectRoot, listProjects, getProjectSummary } from \"../nodes.js\";\nimport { optionalString } from \"../validate.js\";\nimport type { Node } from \"../types.js\";\n\nexport interface OpenInput {\n project?: string;\n goal?: string;\n}\n\nexport type OpenResult =\n | {\n projects: Array<{\n project: string;\n id: string;\n summary: string;\n total: number;\n resolved: number;\n unresolved: number;\n updated_at: string;\n }>;\n }\n | {\n project: string;\n root: Node;\n summary: {\n total: number;\n resolved: number;\n unresolved: number;\n blocked: number;\n actionable: number;\n };\n hint?: string;\n };\n\nexport function handleOpen(input: OpenInput, agent: string): OpenResult {\n const project = optionalString(input?.project, \"project\");\n const goal = optionalString(input?.goal, \"goal\");\n\n if (!project) {\n return { projects: listProjects() };\n }\n\n let root = getProjectRoot(project);\n let isNew = false;\n\n if (!root) {\n root = createNode({\n project,\n summary: goal ?? project,\n discovery: \"pending\",\n agent,\n });\n isNew = true;\n }\n\n const summary = getProjectSummary(project);\n\n const result: OpenResult = { project, root, summary };\n\n // Guide the agent on what to do next\n if (isNew) {\n result.hint = `New project created. Discovery is pending — interview the user to understand scope and goals, then set discovery to \"done\" via graph_update before decomposing with graph_plan.`;\n } else if (root.discovery === \"pending\") {\n result.hint = `Discovery is still pending on this project. Complete the discovery interview, then set discovery to \"done\" via graph_update.`;\n } else if (summary.actionable > 0) {\n result.hint = `${summary.actionable} actionable task(s). Use graph_next to claim one.`;\n } else if (summary.unresolved > 0 && summary.actionable === 0) {\n result.hint = `All remaining tasks are blocked. Check dependencies with graph_query.`;\n }\n\n return result;\n}\n","import { nanoid } from \"nanoid\";\nimport { getDb } from \"./db.js\";\nimport { logEvent } from \"./events.js\";\nimport type { Edge } from \"./types.js\";\n\n// --- Cycle detection ---\n\nfunction wouldCreateCycle(from: string, to: string): boolean {\n // Adding edge \"from depends_on to\". Check if to can already reach from\n // through existing depends_on edges. If so, adding this edge creates a cycle.\n const db = getDb();\n const visited = new Set<string>();\n const stack = [to];\n\n while (stack.length > 0) {\n const current = stack.pop()!;\n if (current === from) return true;\n if (visited.has(current)) continue;\n visited.add(current);\n\n // Follow forward depends_on edges: what does current depend on?\n const deps = db\n .prepare(\n `SELECT to_node FROM edges WHERE from_node = ? AND type = 'depends_on'`\n )\n .all(current) as Array<{ to_node: string }>;\n\n for (const dep of deps) {\n stack.push(dep.to_node);\n }\n }\n\n return false;\n}\n\n// --- Add edge ---\n\nexport interface AddEdgeInput {\n from: string;\n to: string;\n type: string;\n agent: string;\n}\n\nexport interface AddEdgeResult {\n edge: Edge | null;\n rejected: boolean;\n reason?: string;\n}\n\nexport function addEdge(input: AddEdgeInput): AddEdgeResult {\n const db = getDb();\n\n // Check nodes exist\n const fromExists = db.prepare(\"SELECT id FROM nodes WHERE id = ?\").get(input.from);\n const toExists = db.prepare(\"SELECT id FROM nodes WHERE id = ?\").get(input.to);\n\n if (!fromExists) {\n return { edge: null, rejected: true, reason: \"node_not_found: \" + input.from };\n }\n if (!toExists) {\n return { edge: null, rejected: true, reason: \"node_not_found: \" + input.to };\n }\n\n // Check for duplicates\n const existing = db\n .prepare(\n \"SELECT id FROM edges WHERE from_node = ? AND to_node = ? AND type = ?\"\n )\n .get(input.from, input.to, input.type);\n\n if (existing) {\n return { edge: null, rejected: true, reason: \"duplicate_edge\" };\n }\n\n // Cycle detection for depends_on\n if (input.type === \"depends_on\") {\n if (wouldCreateCycle(input.from, input.to)) {\n return { edge: null, rejected: true, reason: \"cycle_detected\" };\n }\n }\n\n const edge: Edge = {\n id: nanoid(),\n from_node: input.from,\n to_node: input.to,\n type: input.type,\n created_at: new Date().toISOString(),\n };\n\n db.prepare(`\n INSERT INTO edges (id, from_node, to_node, type, created_at)\n VALUES (?, ?, ?, ?, ?)\n `).run(edge.id, edge.from_node, edge.to_node, edge.type, edge.created_at);\n\n logEvent(input.from, input.agent, \"edge_added\", [\n { field: \"edge\", before: null, after: { to: input.to, type: input.type } },\n ]);\n\n return { edge, rejected: false };\n}\n\n// --- Remove edge ---\n\nexport function removeEdge(\n from: string,\n to: string,\n type: string,\n agent: string\n): boolean {\n const db = getDb();\n\n const result = db\n .prepare(\n \"DELETE FROM edges WHERE from_node = ? AND to_node = ? AND type = ?\"\n )\n .run(from, to, type);\n\n if (result.changes > 0) {\n logEvent(from, agent, \"edge_removed\", [\n { field: \"edge\", before: { to, type }, after: null },\n ]);\n return true;\n }\n\n return false;\n}\n\n// --- Query edges ---\n\nexport function getEdgesFrom(nodeId: string, type?: string): Edge[] {\n const db = getDb();\n\n if (type) {\n return db\n .prepare(\"SELECT * FROM edges WHERE from_node = ? AND type = ?\")\n .all(nodeId, type) as Edge[];\n }\n\n return db\n .prepare(\"SELECT * FROM edges WHERE from_node = ?\")\n .all(nodeId) as Edge[];\n}\n\nexport function getEdgesTo(nodeId: string, type?: string): Edge[] {\n const db = getDb();\n\n if (type) {\n return db\n .prepare(\"SELECT * FROM edges WHERE to_node = ? AND type = ?\")\n .all(nodeId, type) as Edge[];\n }\n\n return db\n .prepare(\"SELECT * FROM edges WHERE to_node = ?\")\n .all(nodeId) as Edge[];\n}\n\n// [sl:uRocbNC_bArUXGr908Qbk] Find newly actionable nodes\n// Targeted: accepts resolved node IDs, checks only direct dependents.\n// Falls back to project-wide scan when no IDs provided.\n\nexport function findNewlyActionable(\n project: string,\n resolvedNodeIds?: string[]\n): Array<{ id: string; summary: string }> {\n const db = getDb();\n\n if (resolvedNodeIds && resolvedNodeIds.length > 0) {\n // Targeted: only check direct dependents of the resolved nodes + children of resolved nodes\n const placeholders = resolvedNodeIds.map(() => \"?\").join(\",\");\n const rows = db\n .prepare(\n `SELECT DISTINCT n.id, n.summary FROM nodes n\n WHERE n.resolved = 0 AND n.project = ?\n AND (\n -- nodes that had a depends_on edge to one of the resolved nodes\n n.id IN (\n SELECT e.from_node FROM edges e\n WHERE e.type = 'depends_on' AND e.to_node IN (${placeholders})\n )\n OR\n -- parents of resolved nodes (might now be leaf if all children resolved)\n n.id IN (SELECT parent FROM nodes WHERE id IN (${placeholders}) AND parent IS NOT NULL)\n )\n -- is a leaf (no unresolved children)\n AND NOT EXISTS (\n SELECT 1 FROM nodes child WHERE child.parent = n.id AND child.resolved = 0\n )\n -- all deps resolved\n AND NOT EXISTS (\n SELECT 1 FROM edges e\n JOIN nodes dep ON dep.id = e.to_node AND dep.resolved = 0\n WHERE e.from_node = n.id AND e.type = 'depends_on'\n )`\n )\n .all(project, ...resolvedNodeIds, ...resolvedNodeIds) as Array<{\n id: string;\n summary: string;\n }>;\n\n return rows;\n }\n\n // Fallback: project-wide scan\n const rows = db\n .prepare(\n `SELECT n.id, n.summary FROM nodes n\n WHERE n.project = ? AND n.resolved = 0\n AND NOT EXISTS (\n SELECT 1 FROM nodes child WHERE child.parent = n.id AND child.resolved = 0\n )\n AND NOT EXISTS (\n SELECT 1 FROM edges e\n JOIN nodes dep ON dep.id = e.to_node AND dep.resolved = 0\n WHERE e.from_node = n.id AND e.type = 'depends_on'\n )`\n )\n .all(project) as Array<{ id: string; summary: string }>;\n\n return rows;\n}\n","import { getDb } from \"../db.js\";\nimport { createNode, getNode } from \"../nodes.js\";\nimport { addEdge } from \"../edges.js\";\nimport { requireArray, requireString, ValidationError, EngineError } from \"../validate.js\";\n\nexport interface PlanNodeInput {\n ref: string;\n parent_ref?: string;\n summary: string;\n context_links?: string[];\n depends_on?: string[];\n properties?: Record<string, unknown>;\n}\n\nexport interface PlanInput {\n nodes: PlanNodeInput[];\n}\n\nexport interface PlanResult {\n created: Array<{ ref: string; id: string }>;\n}\n\nexport function handlePlan(input: PlanInput, agent: string): PlanResult {\n const db = getDb();\n const nodes = requireArray<PlanNodeInput>(input?.nodes, \"nodes\");\n\n // Validate each node has required fields\n for (let i = 0; i < nodes.length; i++) {\n const n = nodes[i];\n requireString(n.ref, `nodes[${i}].ref`);\n requireString(n.summary, `nodes[${i}].summary`);\n }\n\n // Ref -> real ID mapping\n const refMap = new Map<string, string>();\n const created: Array<{ ref: string; id: string }> = [];\n\n // Validate refs are unique\n const refs = new Set<string>();\n for (const node of nodes) {\n if (refs.has(node.ref)) {\n throw new Error(`Duplicate ref in batch: ${node.ref}`);\n }\n refs.add(node.ref);\n }\n\n // Run atomically\n const transaction = db.transaction(() => {\n // First pass: create all nodes\n for (const nodeInput of nodes) {\n // Resolve parent\n let parentId: string | undefined;\n if (nodeInput.parent_ref) {\n // Check if it's a batch ref or existing node ID\n parentId = refMap.get(nodeInput.parent_ref);\n if (!parentId) {\n // Try as existing node ID\n const existing = getNode(nodeInput.parent_ref);\n if (existing) {\n parentId = existing.id;\n } else {\n throw new Error(\n `parent_ref \"${nodeInput.parent_ref}\" is neither a batch ref nor an existing node ID`\n );\n }\n }\n }\n\n // Determine project from parent or require first node to have a parent\n let project: string;\n if (parentId) {\n const parentNode = getNode(parentId)!;\n // [sl:m3_UNy-eICtHeHExfHwUH] Block decomposition when node has pending discovery\n if (parentNode.discovery === \"pending\") {\n throw new EngineError(\n \"discovery_pending\",\n `Cannot add children to \"${parentNode.summary}\" — discovery is pending. Complete the discovery interview first (set discovery to 'done' via graph_update), then decompose.`\n );\n }\n project = parentNode.project;\n } else {\n // If no parent, the node must be a root. But we need a project.\n // Infer from first node that has a parent, or error.\n throw new Error(\n `Node \"${nodeInput.ref}\" has no parent_ref. All planned nodes must have a parent (an existing node or a batch ref).`\n );\n }\n\n const node = createNode({\n project,\n parent: parentId,\n summary: nodeInput.summary,\n context_links: nodeInput.context_links,\n properties: nodeInput.properties,\n agent,\n });\n\n refMap.set(nodeInput.ref, node.id);\n created.push({ ref: nodeInput.ref, id: node.id });\n }\n\n // Second pass: create dependency edges\n for (const nodeInput of nodes) {\n if (!nodeInput.depends_on || nodeInput.depends_on.length === 0) continue;\n\n const fromId = refMap.get(nodeInput.ref)!;\n\n for (const dep of nodeInput.depends_on) {\n // Resolve dep: batch ref or existing node ID\n let toId = refMap.get(dep);\n if (!toId) {\n const existing = getNode(dep);\n if (existing) {\n toId = existing.id;\n } else {\n throw new Error(\n `depends_on \"${dep}\" in node \"${nodeInput.ref}\" is neither a batch ref nor an existing node ID`\n );\n }\n }\n\n const result = addEdge({\n from: fromId,\n to: toId,\n type: \"depends_on\",\n agent,\n });\n\n if (result.rejected) {\n throw new Error(\n `Dependency edge from \"${nodeInput.ref}\" to \"${dep}\" rejected: ${result.reason}`\n );\n }\n }\n }\n });\n\n transaction();\n\n return { created };\n}\n","import { updateNode, getNode, getChildren } from \"../nodes.js\";\nimport { findNewlyActionable } from \"../edges.js\";\nimport { requireArray, requireString } from \"../validate.js\";\n\nexport interface UpdateEntry {\n node_id: string;\n resolved?: boolean;\n discovery?: string | null;\n state?: unknown;\n summary?: string;\n properties?: Record<string, unknown>;\n add_context_links?: string[];\n remove_context_links?: string[];\n add_evidence?: Array<{ type: string; ref: string }>;\n}\n\nexport interface UpdateInput {\n updates: UpdateEntry[];\n}\n\nexport interface UpdateResult {\n updated: Array<{ node_id: string; rev: number }>;\n newly_actionable?: Array<{ id: string; summary: string }>;\n auto_resolved?: Array<{ node_id: string; summary: string }>;\n}\n\nexport function handleUpdate(input: UpdateInput, agent: string): UpdateResult {\n const updates = requireArray<UpdateEntry>(input?.updates, \"updates\");\n\n for (let i = 0; i < updates.length; i++) {\n requireString(updates[i].node_id, `updates[${i}].node_id`);\n if (updates[i].add_evidence) {\n for (let j = 0; j < updates[i].add_evidence!.length; j++) {\n requireString(updates[i].add_evidence![j].type, `updates[${i}].add_evidence[${j}].type`);\n requireString(updates[i].add_evidence![j].ref, `updates[${i}].add_evidence[${j}].ref`);\n }\n }\n }\n\n const updated: Array<{ node_id: string; rev: number }> = [];\n const resolvedIds: string[] = [];\n let project: string | null = null;\n\n for (const entry of updates) {\n const node = updateNode({\n node_id: entry.node_id,\n agent,\n resolved: entry.resolved,\n discovery: entry.discovery,\n state: entry.state,\n summary: entry.summary,\n properties: entry.properties,\n add_context_links: entry.add_context_links,\n remove_context_links: entry.remove_context_links,\n add_evidence: entry.add_evidence,\n });\n\n updated.push({ node_id: node.id, rev: node.rev });\n\n if (entry.resolved === true) {\n resolvedIds.push(node.id);\n project = node.project;\n }\n }\n\n // [sl:GBuFbmTFuFfnl5KWW-ja-] Auto-resolve parents when all children are resolved\n const autoResolved: Array<{ node_id: string; summary: string }> = [];\n if (resolvedIds.length > 0) {\n const seen = new Set<string>(resolvedIds);\n const queue = [...resolvedIds];\n\n while (queue.length > 0) {\n const nodeId = queue.shift()!;\n const node = getNode(nodeId);\n if (!node?.parent) continue;\n\n const parentId = node.parent;\n if (seen.has(parentId)) continue;\n seen.add(parentId);\n\n const parent = getNode(parentId);\n if (!parent || parent.resolved) continue;\n\n const children = getChildren(parentId);\n if (children.length === 0) continue;\n if (children.every((c) => c.resolved)) {\n const resolved = updateNode({\n node_id: parentId,\n agent,\n resolved: true,\n add_evidence: [{ type: \"note\", ref: \"Auto-resolved: all children completed\" }],\n });\n updated.push({ node_id: resolved.id, rev: resolved.rev });\n resolvedIds.push(parentId);\n autoResolved.push({ node_id: parentId, summary: parent.summary });\n queue.push(parentId);\n }\n }\n }\n\n const result: UpdateResult = { updated };\n\n if (resolvedIds.length > 0 && project) {\n result.newly_actionable = findNewlyActionable(project, resolvedIds);\n }\n\n if (autoResolved.length > 0) {\n result.auto_resolved = autoResolved;\n }\n\n return result;\n}\n","import { addEdge, removeEdge } from \"../edges.js\";\nimport { requireArray, requireString } from \"../validate.js\";\n\nexport interface ConnectEdgeInput {\n from: string;\n to: string;\n type: string;\n remove?: boolean;\n}\n\nexport interface ConnectInput {\n edges: ConnectEdgeInput[];\n}\n\nexport interface ConnectResult {\n applied: number;\n rejected?: Array<{ from: string; to: string; reason: string }>;\n}\n\nexport function handleConnect(input: ConnectInput, agent: string): ConnectResult {\n const edges = requireArray<ConnectEdgeInput>(input?.edges, \"edges\");\n\n for (let i = 0; i < edges.length; i++) {\n requireString(edges[i].from, `edges[${i}].from`);\n requireString(edges[i].to, `edges[${i}].to`);\n requireString(edges[i].type, `edges[${i}].type`);\n }\n\n let applied = 0;\n const rejected: Array<{ from: string; to: string; reason: string }> = [];\n\n for (const edge of edges) {\n if (edge.type === \"parent\") {\n rejected.push({\n from: edge.from,\n to: edge.to,\n reason: \"parent_edges_not_allowed: use graph_restructure to reparent\",\n });\n continue;\n }\n\n if (edge.remove) {\n const removed = removeEdge(edge.from, edge.to, edge.type, agent);\n if (removed) {\n applied++;\n } else {\n rejected.push({\n from: edge.from,\n to: edge.to,\n reason: \"edge_not_found\",\n });\n }\n } else {\n const result = addEdge({\n from: edge.from,\n to: edge.to,\n type: edge.type,\n agent,\n });\n\n if (result.rejected) {\n rejected.push({\n from: edge.from,\n to: edge.to,\n reason: result.reason!,\n });\n } else {\n applied++;\n }\n }\n }\n\n const result: ConnectResult = { applied };\n if (rejected.length > 0) {\n result.rejected = rejected;\n }\n return result;\n}\n","import { getNodeOrThrow, getChildren, getAncestors } from \"../nodes.js\";\nimport { getEdgesFrom, getEdgesTo } from \"../edges.js\";\nimport { getNode } from \"../nodes.js\";\nimport { requireString, optionalNumber } from \"../validate.js\";\nimport type { Node } from \"../types.js\";\n\nexport interface ContextInput {\n node_id: string;\n depth?: number;\n}\n\ninterface NodeTree {\n id: string;\n summary: string;\n resolved: boolean;\n discovery: string | null;\n state: unknown;\n children?: NodeTree[];\n child_count?: number;\n}\n\nexport interface ContextResult {\n node: Node;\n ancestors: Array<{ id: string; summary: string; resolved: boolean }>;\n children: NodeTree;\n depends_on: Array<{ node: Node; satisfied: boolean }>;\n depended_by: Array<{ node: Node; satisfied: boolean }>;\n}\n\nfunction buildNodeTree(nodeId: string, currentDepth: number, maxDepth: number): NodeTree {\n const node = getNodeOrThrow(nodeId);\n const children = getChildren(nodeId);\n\n const tree: NodeTree = {\n id: node.id,\n summary: node.summary,\n resolved: node.resolved,\n discovery: node.discovery,\n state: node.state,\n };\n\n if (children.length === 0) {\n return tree;\n }\n\n if (currentDepth < maxDepth) {\n tree.children = children.map((child) =>\n buildNodeTree(child.id, currentDepth + 1, maxDepth)\n );\n } else {\n tree.child_count = children.length;\n }\n\n return tree;\n}\n\nexport function handleContext(input: ContextInput): ContextResult {\n const nodeId = requireString(input?.node_id, \"node_id\");\n const depth = optionalNumber(input?.depth, \"depth\", 0, 10) ?? 2;\n const node = getNodeOrThrow(nodeId);\n const ancestors = getAncestors(nodeId);\n\n // Build children tree\n const children = buildNodeTree(nodeId, 0, depth);\n\n // Get dependency edges\n const depsOut = getEdgesFrom(nodeId, \"depends_on\");\n const depsIn = getEdgesTo(nodeId, \"depends_on\");\n\n const depends_on = depsOut.map((edge) => {\n const target = getNode(edge.to_node);\n return {\n node: target!,\n satisfied: target?.resolved ?? false,\n };\n });\n\n const depended_by = depsIn.map((edge) => {\n const source = getNode(edge.from_node);\n return {\n node: source!,\n satisfied: node.resolved,\n };\n });\n\n return { node, ancestors, children, depends_on, depended_by };\n}\n","import { getDb } from \"../db.js\";\nimport { requireString, optionalNumber, optionalString } from \"../validate.js\";\nimport type { NodeRow } from \"../types.js\";\n\nexport interface QueryFilter {\n resolved?: boolean;\n properties?: Record<string, unknown>;\n text?: string;\n ancestor?: string;\n has_evidence_type?: string;\n is_leaf?: boolean;\n is_actionable?: boolean;\n is_blocked?: boolean;\n claimed_by?: string | null;\n}\n\nexport interface QueryInput {\n project: string;\n filter?: QueryFilter;\n sort?: \"readiness\" | \"depth\" | \"recent\" | \"created\";\n limit?: number;\n cursor?: string;\n}\n\nexport interface QueryResultNode {\n id: string;\n summary: string;\n resolved: boolean;\n state: unknown;\n parent: string | null;\n depth: number;\n properties: Record<string, unknown>;\n}\n\nexport interface QueryResult {\n nodes: QueryResultNode[];\n total: number;\n next_cursor?: string;\n}\n\n// [sl:tfMDHhmJSXd5TPgwD2ZC6] Descendant lookup via recursive CTE (replaced JS BFS)\nfunction getDescendantIds(nodeId: string): string[] {\n const db = getDb();\n const rows = db\n .prepare(\n `WITH RECURSIVE descendants(id) AS (\n SELECT id FROM nodes WHERE parent = ?\n UNION ALL\n SELECT n.id FROM nodes n JOIN descendants d ON n.parent = d.id\n )\n SELECT id FROM descendants`\n )\n .all(nodeId) as Array<{ id: string }>;\n\n return rows.map((r) => r.id);\n}\n\n\nexport function handleQuery(input: QueryInput): QueryResult {\n const project = requireString(input?.project, \"project\");\n const db = getDb();\n const limit = Math.min(optionalNumber(input?.limit, \"limit\", 1, 100) ?? 20, 100);\n const filter = input?.filter;\n const cursor = optionalString(input?.cursor, \"cursor\");\n\n // Build WHERE clauses\n const conditions: string[] = [\"n.project = ?\"];\n const params: unknown[] = [project];\n\n if (filter?.resolved !== undefined) {\n conditions.push(\"n.resolved = ?\");\n params.push(filter.resolved ? 1 : 0);\n }\n\n if (filter?.text) {\n conditions.push(\"n.summary LIKE ?\");\n params.push(`%${filter.text}%`);\n }\n\n if (filter?.ancestor) {\n const descendantIds = getDescendantIds(filter.ancestor);\n if (descendantIds.length === 0) {\n return { nodes: [], total: 0 };\n }\n conditions.push(`n.id IN (${descendantIds.map(() => \"?\").join(\",\")})`);\n params.push(...descendantIds);\n }\n\n if (filter?.has_evidence_type) {\n conditions.push(\"n.evidence LIKE ?\");\n params.push(`%\"type\":\"${filter.has_evidence_type}\"%`);\n }\n\n if (filter?.is_leaf) {\n conditions.push(\n \"NOT EXISTS (SELECT 1 FROM nodes child WHERE child.parent = n.id AND child.resolved = 0)\"\n );\n }\n\n if (filter?.is_actionable) {\n conditions.push(\"n.resolved = 0\");\n conditions.push(\n \"NOT EXISTS (SELECT 1 FROM nodes child WHERE child.parent = n.id AND child.resolved = 0)\"\n );\n conditions.push(\n `NOT EXISTS (\n SELECT 1 FROM edges e\n JOIN nodes dep ON dep.id = e.to_node AND dep.resolved = 0\n WHERE e.from_node = n.id AND e.type = 'depends_on'\n )`\n );\n }\n\n if (filter?.is_blocked) {\n conditions.push(\"n.resolved = 0\");\n conditions.push(\n `EXISTS (\n SELECT 1 FROM edges e\n JOIN nodes dep ON dep.id = e.to_node AND dep.resolved = 0\n WHERE e.from_node = n.id AND e.type = 'depends_on'\n )`\n );\n }\n\n if (filter?.properties) {\n for (const [key, value] of Object.entries(filter.properties)) {\n conditions.push(\"json_extract(n.properties, ?) = ?\");\n params.push(`$.${key}`, value as string | number);\n }\n }\n\n if (filter?.claimed_by !== undefined) {\n if (filter.claimed_by === null) {\n conditions.push(\n \"(json_extract(n.properties, '$._claimed_by') IS NULL)\"\n );\n } else {\n conditions.push(\"json_extract(n.properties, '$._claimed_by') = ?\");\n params.push(filter.claimed_by);\n }\n }\n\n // Cursor: use created_at + id for stable pagination\n if (cursor) {\n const [cursorTime, cursorId] = cursor.split(\"|\");\n conditions.push(\"(n.created_at > ? OR (n.created_at = ? AND n.id > ?))\");\n params.push(cursorTime, cursorTime, cursorId);\n }\n\n const whereClause = conditions.join(\" AND \");\n\n // Sorting\n let orderBy: string;\n switch (input.sort) {\n case \"depth\":\n // Can't sort by computed depth in SQL easily, so sort by created and compute depth post-hoc\n orderBy = \"n.created_at ASC, n.id ASC\";\n break;\n case \"recent\":\n orderBy = \"n.updated_at DESC, n.id ASC\";\n break;\n case \"created\":\n orderBy = \"n.created_at ASC, n.id ASC\";\n break;\n case \"readiness\":\n default:\n orderBy = \"n.updated_at ASC, n.id ASC\";\n break;\n }\n\n // Count total\n // Count total (without cursor filter)\n const countConditions = cursor ? conditions.slice(0, -1) : conditions;\n const countParams = cursor ? params.slice(0, -3) : [...params];\n const total = (\n db.prepare(`SELECT COUNT(*) as count FROM nodes n WHERE ${countConditions.join(\" AND \")}`).get(...countParams) as { count: number }\n ).count;\n\n // Fetch\n params.push(limit + 1);\n const query = `SELECT * FROM nodes n WHERE ${whereClause} ORDER BY ${orderBy} LIMIT ?`;\n const rows = db.prepare(query).all(...params) as NodeRow[];\n\n const hasMore = rows.length > limit;\n const slice = hasMore ? rows.slice(0, limit) : rows;\n\n const nodes: QueryResultNode[] = slice.map((row) => ({\n id: row.id,\n summary: row.summary,\n resolved: row.resolved === 1,\n state: row.state ? JSON.parse(row.state) : null,\n parent: row.parent,\n depth: row.depth,\n properties: JSON.parse(row.properties),\n }));\n\n const result: QueryResult = { nodes, total };\n\n if (hasMore) {\n const last = slice[slice.length - 1];\n result.next_cursor = `${last.created_at}|${last.id}`;\n }\n\n return result;\n}\n","import { getDb } from \"../db.js\";\nimport { getNode, getAncestors, updateNode } from \"../nodes.js\";\nimport { getEdgesFrom } from \"../edges.js\";\nimport { requireString, optionalString, optionalNumber, optionalBoolean } from \"../validate.js\";\nimport type { Node, NodeRow, Evidence } from \"../types.js\";\n\nexport interface NextInput {\n project: string;\n scope?: string;\n filter?: Record<string, unknown>;\n count?: number;\n claim?: boolean;\n}\n\nexport interface NextResultNode {\n node: Node;\n ancestors: Array<{ id: string; summary: string }>;\n context_links: {\n self: string[];\n inherited: Array<{ node_id: string; links: string[] }>;\n };\n resolved_deps: Array<{\n id: string;\n summary: string;\n evidence: Evidence[];\n }>;\n}\n\nexport interface NextResult {\n nodes: NextResultNode[];\n}\n\nexport function handleNext(\n input: NextInput,\n agent: string,\n claimTtlMinutes: number = 60\n): NextResult {\n const project = requireString(input?.project, \"project\");\n const scope = optionalString(input?.scope, \"scope\");\n const count = optionalNumber(input?.count, \"count\", 1, 50) ?? 1;\n const claim = optionalBoolean(input?.claim, \"claim\") ?? false;\n const db = getDb();\n\n // [sl:HB5daFH1HlFXzuTluibnk] Scope filtering: restrict to descendants of a given node\n let scopeFilter = \"\";\n const scopeParams: unknown[] = [];\n if (scope) {\n const descendantIds = db\n .prepare(\n `WITH RECURSIVE descendants(id) AS (\n SELECT id FROM nodes WHERE parent = ?\n UNION ALL\n SELECT n.id FROM nodes n JOIN descendants d ON n.parent = d.id\n )\n SELECT id FROM descendants`\n )\n .all(scope) as Array<{ id: string }>;\n\n if (descendantIds.length === 0) {\n return { nodes: [] };\n }\n scopeFilter = `AND n.id IN (${descendantIds.map(() => \"?\").join(\",\")})`;\n scopeParams.push(...descendantIds.map((d) => d.id));\n }\n\n // Find actionable nodes: unresolved, leaf (no unresolved children), all deps resolved\n let query = `\n SELECT n.* FROM nodes n\n WHERE n.project = ? AND n.resolved = 0\n ${scopeFilter}\n AND NOT EXISTS (\n SELECT 1 FROM nodes child WHERE child.parent = n.id AND child.resolved = 0\n )\n AND NOT EXISTS (\n SELECT 1 FROM edges e\n JOIN nodes dep ON dep.id = e.to_node AND dep.resolved = 0\n WHERE e.from_node = n.id AND e.type = 'depends_on'\n )\n `;\n\n const params: unknown[] = [project, ...scopeParams];\n\n // Skip nodes claimed by other agents (if claim TTL hasn't expired)\n const claimCutoff = new Date(\n Date.now() - claimTtlMinutes * 60 * 1000\n ).toISOString();\n\n query += `\n AND (\n json_extract(n.properties, '$._claimed_by') IS NULL\n OR json_extract(n.properties, '$._claimed_by') = ?\n OR json_extract(n.properties, '$._claimed_at') <= ?\n )\n `;\n params.push(agent, claimCutoff);\n\n // Property filters\n if (input.filter) {\n for (const [key, value] of Object.entries(input.filter)) {\n query += \" AND json_extract(n.properties, ?) = ?\";\n params.push(`$.${key}`, value as string | number);\n }\n }\n\n // [sl:md48WyMYFlOf4KP99vmtv] Ranking fully in SQL — never loads more than N rows\n // Depth is cached on the node, priority extracted via json_extract\n query += `\n ORDER BY\n COALESCE(CAST(json_extract(n.properties, '$.priority') AS REAL), 0) DESC,\n n.depth DESC,\n n.updated_at ASC\n LIMIT ?\n `;\n params.push(count);\n\n const rows = db.prepare(query).all(...params) as NodeRow[];\n\n const selected = rows.map((row) => ({ row }));\n\n const results: NextResultNode[] = selected.map(({ row }) => {\n const node = getNode(row.id)!;\n const ancestors = getAncestors(row.id);\n\n // Context links: self + inherited from ancestors\n const inherited: Array<{ node_id: string; links: string[] }> = [];\n for (const anc of ancestors) {\n const ancNode = getNode(anc.id);\n if (ancNode && ancNode.context_links.length > 0) {\n inherited.push({ node_id: anc.id, links: ancNode.context_links });\n }\n }\n\n // Resolved dependencies\n const depEdges = getEdgesFrom(row.id, \"depends_on\");\n const resolved_deps = depEdges\n .map((edge) => {\n const depNode = getNode(edge.to_node);\n if (!depNode || !depNode.resolved) return null;\n return {\n id: depNode.id,\n summary: depNode.summary,\n evidence: depNode.evidence,\n };\n })\n .filter(Boolean) as NextResultNode[\"resolved_deps\"];\n\n // Claim if requested\n if (claim) {\n updateNode({\n node_id: node.id,\n agent,\n properties: {\n _claimed_by: agent,\n _claimed_at: new Date().toISOString(),\n },\n });\n }\n\n return {\n node: claim ? getNode(row.id)! : node,\n ancestors: ancestors.map((a) => ({ id: a.id, summary: a.summary })),\n context_links: {\n self: node.context_links,\n inherited,\n },\n resolved_deps,\n };\n });\n\n return { nodes: results };\n}\n","import { getDb } from \"../db.js\";\nimport { getNodeOrThrow, getNode, getChildren, updateNode } from \"../nodes.js\";\nimport { getEdgesFrom, getEdgesTo, findNewlyActionable } from \"../edges.js\";\nimport { logEvent } from \"../events.js\";\nimport { requireArray, requireString } from \"../validate.js\";\nimport type { Evidence } from \"../types.js\";\n\nexport interface MoveOp {\n op: \"move\";\n node_id: string;\n new_parent: string;\n}\n\nexport interface MergeOp {\n op: \"merge\";\n source: string;\n target: string;\n}\n\nexport interface DropOp {\n op: \"drop\";\n node_id: string;\n reason: string;\n}\n\nexport type RestructureOp = MoveOp | MergeOp | DropOp;\n\nexport interface RestructureInput {\n operations: RestructureOp[];\n}\n\nexport interface RestructureResult {\n applied: number;\n details: Array<{ op: string; node_id: string; result: string }>;\n newly_actionable?: Array<{ id: string; summary: string }>;\n}\n\nfunction wouldCreateParentCycle(nodeId: string, newParentId: string): boolean {\n // Check if newParentId is a descendant of nodeId (which would create a cycle)\n const db = getDb();\n let current: string | null = newParentId;\n\n while (current) {\n if (current === nodeId) return true;\n const row = db\n .prepare(\"SELECT parent FROM nodes WHERE id = ?\")\n .get(current) as { parent: string | null } | undefined;\n current = row?.parent ?? null;\n }\n\n return false;\n}\n\nfunction getAllDescendants(nodeId: string): string[] {\n const ids: string[] = [];\n const stack = [nodeId];\n\n while (stack.length > 0) {\n const current = stack.pop()!;\n const children = getChildren(current);\n for (const child of children) {\n ids.push(child.id);\n stack.push(child.id);\n }\n }\n\n return ids;\n}\n\nfunction recomputeSubtreeDepth(nodeId: string, newDepth: number): void {\n const db = getDb();\n db.prepare(\"UPDATE nodes SET depth = ? WHERE id = ?\").run(newDepth, nodeId);\n const children = db.prepare(\"SELECT id FROM nodes WHERE parent = ?\").all(nodeId) as Array<{ id: string }>;\n for (const child of children) {\n recomputeSubtreeDepth(child.id, newDepth + 1);\n }\n}\n\nfunction handleMove(op: MoveOp, agent: string): { node_id: string; result: string } {\n const db = getDb();\n const node = getNodeOrThrow(op.node_id);\n const newParent = getNodeOrThrow(op.new_parent);\n\n if (wouldCreateParentCycle(op.node_id, op.new_parent)) {\n throw new Error(\n `Move would create cycle: ${op.node_id} cannot be moved under ${op.new_parent}`\n );\n }\n\n const oldParent = node.parent;\n const now = new Date().toISOString();\n db.prepare(\"UPDATE nodes SET parent = ?, updated_at = ? WHERE id = ?\").run(\n op.new_parent,\n now,\n op.node_id\n );\n\n // Recompute depth for moved node and all descendants\n recomputeSubtreeDepth(op.node_id, newParent.depth + 1);\n\n logEvent(op.node_id, agent, \"moved\", [\n { field: \"parent\", before: oldParent, after: op.new_parent },\n ]);\n\n return { node_id: op.node_id, result: `moved under ${op.new_parent}` };\n}\n\nfunction handleMerge(op: MergeOp, agent: string): { node_id: string; result: string } {\n const db = getDb();\n const source = getNodeOrThrow(op.source);\n const target = getNodeOrThrow(op.target);\n\n // Move source's children to target and recompute their depths\n const movedChildren = db.prepare(\"SELECT id FROM nodes WHERE parent = ?\").all(op.source) as Array<{ id: string }>;\n db.prepare(\"UPDATE nodes SET parent = ?, updated_at = ? WHERE parent = ?\").run(\n op.target,\n new Date().toISOString(),\n op.source\n );\n for (const child of movedChildren) {\n recomputeSubtreeDepth(child.id, target.depth + 1);\n }\n\n // Append source's evidence to target\n const targetEvidence: Evidence[] = [...target.evidence, ...source.evidence];\n db.prepare(\"UPDATE nodes SET evidence = ?, updated_at = ? WHERE id = ?\").run(\n JSON.stringify(targetEvidence),\n new Date().toISOString(),\n op.target\n );\n\n // Transfer source's dependency edges to target\n const sourceOutEdges = getEdgesFrom(op.source);\n const sourceInEdges = getEdgesTo(op.source);\n\n for (const edge of sourceOutEdges) {\n // source depends_on X -> target depends_on X\n const existing = db\n .prepare(\n \"SELECT id FROM edges WHERE from_node = ? AND to_node = ? AND type = ?\"\n )\n .get(op.target, edge.to_node, edge.type);\n\n if (!existing) {\n db.prepare(\n \"UPDATE edges SET from_node = ? WHERE id = ?\"\n ).run(op.target, edge.id);\n } else {\n db.prepare(\"DELETE FROM edges WHERE id = ?\").run(edge.id);\n }\n }\n\n for (const edge of sourceInEdges) {\n // X depends_on source -> X depends_on target\n const existing = db\n .prepare(\n \"SELECT id FROM edges WHERE from_node = ? AND to_node = ? AND type = ?\"\n )\n .get(edge.from_node, op.target, edge.type);\n\n if (!existing) {\n db.prepare(\n \"UPDATE edges SET to_node = ? WHERE id = ?\"\n ).run(op.target, edge.id);\n } else {\n db.prepare(\"DELETE FROM edges WHERE id = ?\").run(edge.id);\n }\n }\n\n // Log events\n logEvent(op.target, agent, \"merged\", [\n { field: \"merged_from\", before: null, after: op.source },\n ]);\n logEvent(op.source, agent, \"merged_into\", [\n { field: \"merged_into\", before: null, after: op.target },\n ]);\n\n // Delete source node\n db.prepare(\"DELETE FROM edges WHERE from_node = ? OR to_node = ?\").run(\n op.source,\n op.source\n );\n db.prepare(\"DELETE FROM nodes WHERE id = ?\").run(op.source);\n\n return { node_id: op.target, result: `merged ${op.source} into ${op.target}` };\n}\n\nfunction handleDrop(op: DropOp, agent: string): { node_id: string; result: string } {\n const now = new Date().toISOString();\n\n // Get all descendants\n const descendants = getAllDescendants(op.node_id);\n const allIds = [op.node_id, ...descendants];\n\n // Mark all as resolved with evidence\n for (const id of allIds) {\n const node = getNode(id);\n if (!node || node.resolved) continue;\n\n updateNode({\n node_id: id,\n agent,\n resolved: true,\n add_evidence: [{ type: \"dropped\", ref: op.reason }],\n });\n\n logEvent(id, agent, \"dropped\", [\n { field: \"resolved\", before: false, after: true },\n { field: \"reason\", before: null, after: op.reason },\n ]);\n }\n\n return {\n node_id: op.node_id,\n result: `dropped ${allIds.length} node(s): ${op.reason}`,\n };\n}\n\nexport function handleRestructure(\n input: RestructureInput,\n agent: string\n): RestructureResult {\n const operations = requireArray<RestructureOp>(input?.operations, \"operations\");\n\n for (let i = 0; i < operations.length; i++) {\n const op = operations[i];\n requireString(op.op, `operations[${i}].op`);\n if (op.op === \"move\") {\n requireString((op as MoveOp).node_id, `operations[${i}].node_id`);\n requireString((op as MoveOp).new_parent, `operations[${i}].new_parent`);\n } else if (op.op === \"merge\") {\n requireString((op as MergeOp).source, `operations[${i}].source`);\n requireString((op as MergeOp).target, `operations[${i}].target`);\n } else if (op.op === \"drop\") {\n requireString((op as DropOp).node_id, `operations[${i}].node_id`);\n requireString((op as DropOp).reason, `operations[${i}].reason`);\n } else {\n throw new Error(`Unknown operation: ${op.op}`);\n }\n }\n\n const db = getDb();\n let applied = 0;\n const details: Array<{ op: string; node_id: string; result: string }> = [];\n let project: string | null = null;\n\n const transaction = db.transaction(() => {\n for (const op of operations) {\n let detail: { node_id: string; result: string };\n\n switch (op.op) {\n case \"move\":\n detail = handleMove(op, agent);\n project = getNode(op.node_id)?.project ?? project;\n break;\n case \"merge\":\n detail = handleMerge(op, agent);\n project = getNode(op.target)?.project ?? project;\n break;\n case \"drop\":\n detail = handleDrop(op, agent);\n project = getNode(op.node_id)?.project ?? project;\n break;\n default:\n throw new Error(`Unknown operation: ${(op as RestructureOp).op}`);\n }\n\n details.push({ op: op.op, ...detail });\n applied++;\n }\n });\n\n transaction();\n\n const result: RestructureResult = { applied, details };\n\n if (project) {\n const actionable = findNewlyActionable(project);\n if (actionable.length > 0) {\n result.newly_actionable = actionable;\n }\n }\n\n return result;\n}\n","import { getEvents } from \"../events.js\";\nimport { getNodeOrThrow } from \"../nodes.js\";\nimport { requireString, optionalNumber, optionalString } from \"../validate.js\";\n\nexport interface HistoryInput {\n node_id: string;\n limit?: number;\n cursor?: string;\n}\n\nexport interface HistoryResult {\n events: Array<{\n timestamp: string;\n agent: string;\n action: string;\n changes: Array<{ field: string; before: unknown; after: unknown }>;\n }>;\n next_cursor?: string;\n}\n\nexport function handleHistory(input: HistoryInput): HistoryResult {\n const nodeId = requireString(input?.node_id, \"node_id\");\n const limit = optionalNumber(input?.limit, \"limit\", 1, 100) ?? 20;\n const cursor = optionalString(input?.cursor, \"cursor\");\n\n getNodeOrThrow(nodeId);\n\n const { events, next_cursor } = getEvents(nodeId, limit, cursor);\n\n const result: HistoryResult = {\n events: events.map((e) => ({\n timestamp: e.timestamp,\n agent: e.agent,\n action: e.action,\n changes: e.changes,\n })),\n };\n\n if (next_cursor) {\n result.next_cursor = next_cursor;\n }\n\n return result;\n}\n","import { getDb } from \"../db.js\";\nimport { getProjectRoot, getProjectSummary, listProjects } from \"../nodes.js\";\nimport { optionalString, optionalNumber } from \"../validate.js\";\nimport { EngineError } from \"../validate.js\";\nimport type { NodeRow, Evidence } from \"../types.js\";\n\n// [sl:yosc4NuV6j43Zv0fsDXDj] graph_onboard — single-call orientation for new agents\n\nexport interface OnboardInput {\n project?: string;\n evidence_limit?: number;\n}\n\nexport interface OnboardResult {\n project: string;\n goal: string;\n discovery: string | null;\n hint?: string;\n summary: {\n total: number;\n resolved: number;\n unresolved: number;\n blocked: number;\n actionable: number;\n };\n tree: Array<{\n id: string;\n summary: string;\n resolved: boolean;\n children: Array<{\n id: string;\n summary: string;\n resolved: boolean;\n child_count: number;\n }>;\n }>;\n recent_evidence: Array<{\n node_id: string;\n node_summary: string;\n type: string;\n ref: string;\n agent: string;\n timestamp: string;\n }>;\n context_links: string[];\n knowledge: Array<{\n key: string;\n content: string;\n updated_at: string;\n }>;\n recently_resolved: Array<{\n id: string;\n summary: string;\n resolved_at: string;\n agent: string;\n }>;\n last_activity: string | null;\n actionable: Array<{\n id: string;\n summary: string;\n properties: Record<string, unknown>;\n }>;\n}\n\n// [sl:1pRRsWFomcv04XAkdLMAj] Allow graph_onboard without project name\nexport function handleOnboard(input: OnboardInput): OnboardResult | { projects: ReturnType<typeof listProjects>; hint: string } {\n const evidenceLimit = optionalNumber(input?.evidence_limit, \"evidence_limit\", 1, 50) ?? 20;\n const db = getDb();\n\n // Auto-resolve project when not specified\n let project = optionalString(input?.project, \"project\");\n if (!project) {\n const projects = listProjects();\n if (projects.length === 0) {\n return {\n projects: [],\n hint: \"No projects yet. Create one with graph_open({ project: \\\"my-project\\\", goal: \\\"...\\\" }).\",\n };\n }\n if (projects.length === 1) {\n project = projects[0].project;\n } else {\n return {\n projects,\n hint: `${projects.length} projects found. Call graph_onboard with a specific project name.`,\n };\n }\n }\n\n // Verify project exists\n const root = getProjectRoot(project);\n if (!root) {\n throw new EngineError(\"project_not_found\", `Project not found: ${project}`);\n }\n\n // 1. Project summary counts\n const summary = getProjectSummary(project);\n\n // 2. Tree structure — root's children + their children (depth 1-2)\n const topChildren = db\n .prepare(\"SELECT * FROM nodes WHERE parent = ? ORDER BY created_at ASC\")\n .all(root.id) as NodeRow[];\n\n const tree = topChildren.map((child) => {\n const grandchildren = db\n .prepare(\n `SELECT id, summary, resolved,\n (SELECT COUNT(*) FROM nodes gc WHERE gc.parent = n.id) as child_count\n FROM nodes n WHERE parent = ? ORDER BY created_at ASC`\n )\n .all(child.id) as Array<{\n id: string;\n summary: string;\n resolved: number;\n child_count: number;\n }>;\n\n return {\n id: child.id,\n summary: child.summary,\n resolved: child.resolved === 1,\n discovery: child.discovery,\n children: grandchildren.map((gc) => ({\n id: gc.id,\n summary: gc.summary,\n resolved: gc.resolved === 1,\n child_count: gc.child_count,\n })),\n };\n });\n\n // 3. Recent evidence across all resolved nodes, sorted by timestamp\n const allNodes = db\n .prepare(\"SELECT id, summary, evidence FROM nodes WHERE project = ? AND resolved = 1 AND evidence != '[]'\")\n .all(project) as Array<{ id: string; summary: string; evidence: string }>;\n\n const allEvidence: OnboardResult[\"recent_evidence\"] = [];\n for (const node of allNodes) {\n const evidence: Evidence[] = JSON.parse(node.evidence);\n for (const ev of evidence) {\n allEvidence.push({\n node_id: node.id,\n node_summary: node.summary,\n type: ev.type,\n ref: ev.ref,\n agent: ev.agent,\n timestamp: ev.timestamp,\n });\n }\n }\n allEvidence.sort((a, b) => b.timestamp.localeCompare(a.timestamp));\n const recent_evidence = allEvidence.slice(0, evidenceLimit);\n\n // 4. All context_links aggregated and deduplicated\n const linkRows = db\n .prepare(\"SELECT context_links FROM nodes WHERE project = ? AND context_links != '[]'\")\n .all(project) as Array<{ context_links: string }>;\n\n const linkSet = new Set<string>();\n for (const row of linkRows) {\n const links: string[] = JSON.parse(row.context_links);\n for (const link of links) {\n linkSet.add(link);\n }\n }\n const context_links = [...linkSet].sort();\n\n // 5. Knowledge entries\n const knowledgeRows = db\n .prepare(\"SELECT key, content, updated_at FROM knowledge WHERE project = ? ORDER BY updated_at DESC\")\n .all(project) as Array<{ key: string; content: string; updated_at: string }>;\n\n // 6. Actionable tasks preview (like graph_next without claiming)\n const actionableRows = db\n .prepare(\n `SELECT n.id, n.summary, n.properties FROM nodes n\n WHERE n.project = ? AND n.resolved = 0\n AND NOT EXISTS (\n SELECT 1 FROM nodes child WHERE child.parent = n.id AND child.resolved = 0\n )\n AND NOT EXISTS (\n SELECT 1 FROM edges e\n JOIN nodes dep ON dep.id = e.to_node AND dep.resolved = 0\n WHERE e.from_node = n.id AND e.type = 'depends_on'\n )\n ORDER BY\n COALESCE(CAST(json_extract(n.properties, '$.priority') AS REAL), 0) DESC,\n n.depth DESC,\n n.updated_at ASC\n LIMIT 10`\n )\n .all(project) as Array<{ id: string; summary: string; properties: string }>;\n\n const actionable = actionableRows.map((row) => ({\n id: row.id,\n summary: row.summary,\n properties: JSON.parse(row.properties),\n }));\n\n // 7. Recently resolved nodes (last 24h) — cross-session continuity\n const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();\n const recentlyResolvedRows = db\n .prepare(\n `SELECT id, summary, updated_at,\n (SELECT json_extract(value, '$.agent') FROM json_each(evidence) ORDER BY json_extract(value, '$.timestamp') DESC LIMIT 1) as last_agent\n FROM nodes\n WHERE project = ? AND resolved = 1 AND updated_at > ?\n ORDER BY updated_at DESC\n LIMIT 10`\n )\n .all(project, oneDayAgo) as Array<{ id: string; summary: string; updated_at: string; last_agent: string | null }>;\n\n const recently_resolved = recentlyResolvedRows.map((row) => ({\n id: row.id,\n summary: row.summary,\n resolved_at: row.updated_at,\n agent: row.last_agent ?? \"unknown\",\n }));\n\n // 8. Last activity timestamp\n const lastActivityRow = db\n .prepare(\"SELECT MAX(updated_at) as last FROM nodes WHERE project = ?\")\n .get(project) as { last: string | null };\n const last_activity = lastActivityRow.last;\n\n // Build hint based on project state\n let hint: string | undefined;\n if (root.discovery === \"pending\") {\n hint = `Discovery is pending. Interview the user to understand scope and goals, write knowledge entries with findings, then set discovery to \"done\" via graph_update before decomposing with graph_plan.`;\n } else if (actionable.length > 0) {\n const recentNote = recently_resolved.length > 0\n ? ` ${recently_resolved.length} task(s) resolved recently.`\n : \"\";\n hint = `${actionable.length} actionable task(s) ready.${recentNote} Use graph_next({ project: \"${project}\", claim: true }) to claim one.`;\n } else if (summary.unresolved > 0 && summary.actionable === 0) {\n hint = `All remaining tasks are blocked. Check dependencies with graph_query.`;\n } else if (summary.total <= 1 && root.discovery !== \"pending\") {\n hint = `Project is empty — use graph_plan to decompose the goal into tasks.`;\n }\n\n return {\n project,\n goal: root.summary,\n discovery: root.discovery,\n hint,\n summary,\n tree,\n recent_evidence,\n context_links,\n knowledge: knowledgeRows,\n recently_resolved,\n last_activity,\n actionable,\n };\n}\n","import { getProjectRoot, getChildren } from \"../nodes.js\";\nimport { requireString, optionalNumber } from \"../validate.js\";\nimport { EngineError } from \"../validate.js\";\nimport type { Node } from \"../types.js\";\n\n// [sl:ahq-BLHS9pJkJUlBZO92L] Full tree visualization — \"show me the whole tree\"\n\nexport interface TreeInput {\n project: string;\n depth?: number;\n}\n\ninterface TreeNode {\n id: string;\n summary: string;\n resolved: boolean;\n properties: Record<string, unknown>;\n children?: TreeNode[];\n child_count?: number;\n}\n\nexport interface TreeResult {\n project: string;\n tree: TreeNode;\n stats: {\n total: number;\n resolved: number;\n unresolved: number;\n };\n}\n\nfunction buildTree(node: Node, currentDepth: number, maxDepth: number, stats: { total: number; resolved: number }): TreeNode {\n stats.total++;\n if (node.resolved) stats.resolved++;\n\n const children = getChildren(node.id);\n const treeNode: TreeNode = {\n id: node.id,\n summary: node.summary,\n resolved: node.resolved,\n properties: node.properties,\n };\n\n if (children.length === 0) return treeNode;\n\n if (currentDepth < maxDepth) {\n treeNode.children = children.map((child) =>\n buildTree(child, currentDepth + 1, maxDepth, stats)\n );\n } else {\n treeNode.child_count = children.length;\n }\n\n return treeNode;\n}\n\nexport function handleTree(input: TreeInput): TreeResult {\n const project = requireString(input?.project, \"project\");\n const depth = optionalNumber(input?.depth, \"depth\", 1, 20) ?? 10;\n\n const root = getProjectRoot(project);\n if (!root) {\n throw new EngineError(\"project_not_found\", `Project not found: ${project}`);\n }\n\n const stats = { total: 0, resolved: 0 };\n const tree = buildTree(root, 0, depth, stats);\n\n return {\n project,\n tree,\n stats: {\n total: stats.total,\n resolved: stats.resolved,\n unresolved: stats.total - stats.resolved,\n },\n };\n}\n","import { nanoid } from \"nanoid\";\nimport { getDb } from \"../db.js\";\nimport { getProjectRoot } from \"../nodes.js\";\nimport { EngineError, requireString } from \"../validate.js\";\n\n// [sl:4PrMkE09nf6ptz8LLR9rW] Knowledge tools — persistent project-level knowledge store\n\ninterface KnowledgeRow {\n id: string;\n project: string;\n key: string;\n content: string;\n created_by: string;\n created_at: string;\n updated_at: string;\n}\n\n// --- graph_knowledge_write ---\n\nexport interface KnowledgeWriteInput {\n project: string;\n key: string;\n content: string;\n}\n\nexport function handleKnowledgeWrite(input: KnowledgeWriteInput, agent: string) {\n const project = requireString(input.project, \"project\");\n const key = requireString(input.key, \"key\");\n const content = requireString(input.content, \"content\");\n\n const root = getProjectRoot(project);\n if (!root) {\n throw new EngineError(\"not_found\", `Project '${project}' not found`);\n }\n\n const db = getDb();\n const now = new Date().toISOString();\n\n const existing = db\n .prepare(\"SELECT id FROM knowledge WHERE project = ? AND key = ?\")\n .get(project, key) as { id: string } | undefined;\n\n if (existing) {\n db.prepare(\n \"UPDATE knowledge SET content = ?, updated_at = ? WHERE id = ?\"\n ).run(content, now, existing.id);\n return { key, action: \"updated\" };\n } else {\n const id = nanoid();\n db.prepare(\n \"INSERT INTO knowledge (id, project, key, content, created_by, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?)\"\n ).run(id, project, key, content, agent, now, now);\n return { key, action: \"created\" };\n }\n}\n\n// --- graph_knowledge_read ---\n\nexport interface KnowledgeReadInput {\n project: string;\n key?: string;\n}\n\nexport function handleKnowledgeRead(input: KnowledgeReadInput) {\n const project = requireString(input.project, \"project\");\n\n const root = getProjectRoot(project);\n if (!root) {\n throw new EngineError(\"not_found\", `Project '${project}' not found`);\n }\n\n const db = getDb();\n\n if (input.key) {\n const row = db\n .prepare(\"SELECT * FROM knowledge WHERE project = ? AND key = ?\")\n .get(project, input.key) as KnowledgeRow | undefined;\n\n if (!row) {\n throw new EngineError(\"not_found\", `Knowledge entry '${input.key}' not found in project '${project}'`);\n }\n\n return {\n key: row.key,\n content: row.content,\n updated_at: row.updated_at,\n created_by: row.created_by,\n };\n }\n\n // List all\n const rows = db\n .prepare(\"SELECT key, content, updated_at, created_by FROM knowledge WHERE project = ? ORDER BY updated_at DESC\")\n .all(project) as Array<{ key: string; content: string; updated_at: string; created_by: string }>;\n\n return { entries: rows };\n}\n\n// --- graph_knowledge_delete ---\n\nexport interface KnowledgeDeleteInput {\n project: string;\n key: string;\n}\n\nexport function handleKnowledgeDelete(input: KnowledgeDeleteInput) {\n const project = requireString(input.project, \"project\");\n const key = requireString(input.key, \"key\");\n\n const root = getProjectRoot(project);\n if (!root) {\n throw new EngineError(\"not_found\", `Project '${project}' not found`);\n }\n\n const db = getDb();\n const result = db\n .prepare(\"DELETE FROM knowledge WHERE project = ? AND key = ?\")\n .run(project, key);\n\n if (result.changes === 0) {\n throw new EngineError(\"not_found\", `Knowledge entry '${key}' not found in project '${project}'`);\n }\n\n return { key, action: \"deleted\" };\n}\n\n// --- graph_knowledge_search ---\n\nexport interface KnowledgeSearchInput {\n project: string;\n query: string;\n}\n\nexport function handleKnowledgeSearch(input: KnowledgeSearchInput) {\n const project = requireString(input.project, \"project\");\n const query = requireString(input.query, \"query\");\n\n const root = getProjectRoot(project);\n if (!root) {\n throw new EngineError(\"not_found\", `Project '${project}' not found`);\n }\n\n const db = getDb();\n const pattern = `%${query}%`;\n\n const rows = db\n .prepare(\n \"SELECT key, content, updated_at, created_by FROM knowledge WHERE project = ? AND (key LIKE ? OR content LIKE ?) ORDER BY updated_at DESC\"\n )\n .all(project, pattern, pattern) as Array<{ key: string; content: string; updated_at: string; created_by: string }>;\n\n return { entries: rows, query };\n}\n","import { getDb } from \"./db.js\";\nimport { EngineError } from \"./validate.js\";\nimport type { Tier } from \"./license.js\";\n\n// [sl:N0IDVJQIhENQFsov6-Lhg] Feature gates — enforce free vs pro limits\n\n// Limits relaxed — everything free while building user base (Phase 1: Acquisition)\nconst FREE_LIMITS = {\n maxProjects: Infinity,\n maxNodesPerProject: Infinity,\n onboardEvidenceLimit: 50,\n scopeEnabled: true,\n};\n\n/**\n * Check if creating nodes would exceed the free tier node limit.\n * Throws EngineError if limit would be exceeded.\n */\nexport function checkNodeLimit(tier: Tier, project: string, adding: number): void {\n if (tier === \"pro\") return;\n\n const db = getDb();\n const { count } = db\n .prepare(\"SELECT COUNT(*) as count FROM nodes WHERE project = ?\")\n .get(project) as { count: number };\n\n if (count + adding > FREE_LIMITS.maxNodesPerProject) {\n throw new EngineError(\n \"free_tier_limit\",\n `Free tier is limited to ${FREE_LIMITS.maxNodesPerProject} nodes per project. ` +\n `Current: ${count}, adding: ${adding}. Activate a license key to remove this limit.`\n );\n }\n}\n\n/**\n * Check if creating a new project would exceed the free tier project limit.\n * Throws EngineError if limit would be exceeded.\n */\nexport function checkProjectLimit(tier: Tier): void {\n if (tier === \"pro\") return;\n\n const db = getDb();\n const { count } = db\n .prepare(\"SELECT COUNT(*) as count FROM nodes WHERE parent IS NULL\")\n .get() as { count: number };\n\n if (count >= FREE_LIMITS.maxProjects) {\n throw new EngineError(\n \"free_tier_limit\",\n `Free tier is limited to ${FREE_LIMITS.maxProjects} project. ` +\n `Activate a license key to create unlimited projects.`\n );\n }\n}\n\n/**\n * Cap the evidence limit for graph_onboard on free tier.\n */\nexport function capEvidenceLimit(tier: Tier, requested?: number): number {\n const max = tier === \"pro\" ? (requested ?? 20) : FREE_LIMITS.onboardEvidenceLimit;\n return Math.min(requested ?? max, tier === \"pro\" ? 50 : FREE_LIMITS.onboardEvidenceLimit);\n}\n\n/**\n * Check if knowledge tools are allowed on the current tier.\n * Currently free for all — everything ungated during acquisition phase.\n */\nexport function checkKnowledgeTier(_tier: Tier): void {\n // All tiers allowed during acquisition phase\n return;\n}\n\n/**\n * Check if scope parameter is allowed.\n * Currently free for all during acquisition phase.\n */\nexport function checkScope(_tier: Tier, scope?: string): string | undefined {\n return scope;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,cAAc;AACvB,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,OACK;;;AC6BA,SAAS,WAAW,OAAkB,OAA2B;AACtE,QAAM,UAAU,eAAe,OAAO,SAAS,SAAS;AACxD,QAAM,OAAO,eAAe,OAAO,MAAM,MAAM;AAE/C,MAAI,CAAC,SAAS;AACZ,WAAO,EAAE,UAAU,aAAa,EAAE;AAAA,EACpC;AAEA,MAAI,OAAO,eAAe,OAAO;AACjC,MAAI,QAAQ;AAEZ,MAAI,CAAC,MAAM;AACT,WAAO,WAAW;AAAA,MAChB;AAAA,MACA,SAAS,QAAQ;AAAA,MACjB,WAAW;AAAA,MACX;AAAA,IACF,CAAC;AACD,YAAQ;AAAA,EACV;AAEA,QAAM,UAAU,kBAAkB,OAAO;AAEzC,QAAM,SAAqB,EAAE,SAAS,MAAM,QAAQ;AAGpD,MAAI,OAAO;AACT,WAAO,OAAO;AAAA,EAChB,WAAW,KAAK,cAAc,WAAW;AACvC,WAAO,OAAO;AAAA,EAChB,WAAW,QAAQ,aAAa,GAAG;AACjC,WAAO,OAAO,GAAG,QAAQ,UAAU;AAAA,EACrC,WAAW,QAAQ,aAAa,KAAK,QAAQ,eAAe,GAAG;AAC7D,WAAO,OAAO;AAAA,EAChB;AAEA,SAAO;AACT;;;ACvEA,SAAS,cAAc;AAOvB,SAAS,iBAAiB,MAAc,IAAqB;AAG3D,QAAM,KAAK,MAAM;AACjB,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,QAAQ,CAAC,EAAE;AAEjB,SAAO,MAAM,SAAS,GAAG;AACvB,UAAM,UAAU,MAAM,IAAI;AAC1B,QAAI,YAAY,KAAM,QAAO;AAC7B,QAAI,QAAQ,IAAI,OAAO,EAAG;AAC1B,YAAQ,IAAI,OAAO;AAGnB,UAAM,OAAO,GACV;AAAA,MACC;AAAA,IACF,EACC,IAAI,OAAO;AAEd,eAAW,OAAO,MAAM;AACtB,YAAM,KAAK,IAAI,OAAO;AAAA,IACxB;AAAA,EACF;AAEA,SAAO;AACT;AAiBO,SAAS,QAAQ,OAAoC;AAC1D,QAAM,KAAK,MAAM;AAGjB,QAAM,aAAa,GAAG,QAAQ,mCAAmC,EAAE,IAAI,MAAM,IAAI;AACjF,QAAM,WAAW,GAAG,QAAQ,mCAAmC,EAAE,IAAI,MAAM,EAAE;AAE7E,MAAI,CAAC,YAAY;AACf,WAAO,EAAE,MAAM,MAAM,UAAU,MAAM,QAAQ,qBAAqB,MAAM,KAAK;AAAA,EAC/E;AACA,MAAI,CAAC,UAAU;AACb,WAAO,EAAE,MAAM,MAAM,UAAU,MAAM,QAAQ,qBAAqB,MAAM,GAAG;AAAA,EAC7E;AAGA,QAAM,WAAW,GACd;AAAA,IACC;AAAA,EACF,EACC,IAAI,MAAM,MAAM,MAAM,IAAI,MAAM,IAAI;AAEvC,MAAI,UAAU;AACZ,WAAO,EAAE,MAAM,MAAM,UAAU,MAAM,QAAQ,iBAAiB;AAAA,EAChE;AAGA,MAAI,MAAM,SAAS,cAAc;AAC/B,QAAI,iBAAiB,MAAM,MAAM,MAAM,EAAE,GAAG;AAC1C,aAAO,EAAE,MAAM,MAAM,UAAU,MAAM,QAAQ,iBAAiB;AAAA,IAChE;AAAA,EACF;AAEA,QAAM,OAAa;AAAA,IACjB,IAAI,OAAO;AAAA,IACX,WAAW,MAAM;AAAA,IACjB,SAAS,MAAM;AAAA,IACf,MAAM,MAAM;AAAA,IACZ,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,EACrC;AAEA,KAAG,QAAQ;AAAA;AAAA;AAAA,GAGV,EAAE,IAAI,KAAK,IAAI,KAAK,WAAW,KAAK,SAAS,KAAK,MAAM,KAAK,UAAU;AAExE,WAAS,MAAM,MAAM,MAAM,OAAO,cAAc;AAAA,IAC9C,EAAE,OAAO,QAAQ,QAAQ,MAAM,OAAO,EAAE,IAAI,MAAM,IAAI,MAAM,MAAM,KAAK,EAAE;AAAA,EAC3E,CAAC;AAED,SAAO,EAAE,MAAM,UAAU,MAAM;AACjC;AAIO,SAAS,WACd,MACA,IACA,MACA,OACS;AACT,QAAM,KAAK,MAAM;AAEjB,QAAM,SAAS,GACZ;AAAA,IACC;AAAA,EACF,EACC,IAAI,MAAM,IAAI,IAAI;AAErB,MAAI,OAAO,UAAU,GAAG;AACtB,aAAS,MAAM,OAAO,gBAAgB;AAAA,MACpC,EAAE,OAAO,QAAQ,QAAQ,EAAE,IAAI,KAAK,GAAG,OAAO,KAAK;AAAA,IACrD,CAAC;AACD,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAIO,SAAS,aAAa,QAAgB,MAAuB;AAClE,QAAM,KAAK,MAAM;AAEjB,MAAI,MAAM;AACR,WAAO,GACJ,QAAQ,sDAAsD,EAC9D,IAAI,QAAQ,IAAI;AAAA,EACrB;AAEA,SAAO,GACJ,QAAQ,yCAAyC,EACjD,IAAI,MAAM;AACf;AAEO,SAAS,WAAW,QAAgB,MAAuB;AAChE,QAAM,KAAK,MAAM;AAEjB,MAAI,MAAM;AACR,WAAO,GACJ,QAAQ,oDAAoD,EAC5D,IAAI,QAAQ,IAAI;AAAA,EACrB;AAEA,SAAO,GACJ,QAAQ,uCAAuC,EAC/C,IAAI,MAAM;AACf;AAMO,SAAS,oBACd,SACA,iBACwC;AACxC,QAAM,KAAK,MAAM;AAEjB,MAAI,mBAAmB,gBAAgB,SAAS,GAAG;AAEjD,UAAM,eAAe,gBAAgB,IAAI,MAAM,GAAG,EAAE,KAAK,GAAG;AAC5D,UAAMA,QAAO,GACV;AAAA,MACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,6DAMqD,YAAY;AAAA;AAAA;AAAA;AAAA,4DAIb,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAYlE,EACC,IAAI,SAAS,GAAG,iBAAiB,GAAG,eAAe;AAKtD,WAAOA;AAAA,EACT;AAGA,QAAM,OAAO,GACV;AAAA,IACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUF,EACC,IAAI,OAAO;AAEd,SAAO;AACT;;;ACvMO,SAAS,WAAW,OAAkB,OAA2B;AACtE,QAAM,KAAK,MAAM;AACjB,QAAM,QAAQ,aAA4B,OAAO,OAAO,OAAO;AAG/D,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,IAAI,MAAM,CAAC;AACjB,kBAAc,EAAE,KAAK,SAAS,CAAC,OAAO;AACtC,kBAAc,EAAE,SAAS,SAAS,CAAC,WAAW;AAAA,EAChD;AAGA,QAAM,SAAS,oBAAI,IAAoB;AACvC,QAAM,UAA8C,CAAC;AAGrD,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,IAAI,KAAK,GAAG,GAAG;AACtB,YAAM,IAAI,MAAM,2BAA2B,KAAK,GAAG,EAAE;AAAA,IACvD;AACA,SAAK,IAAI,KAAK,GAAG;AAAA,EACnB;AAGA,QAAM,cAAc,GAAG,YAAY,MAAM;AAEvC,eAAW,aAAa,OAAO;AAE7B,UAAI;AACJ,UAAI,UAAU,YAAY;AAExB,mBAAW,OAAO,IAAI,UAAU,UAAU;AAC1C,YAAI,CAAC,UAAU;AAEb,gBAAM,WAAW,QAAQ,UAAU,UAAU;AAC7C,cAAI,UAAU;AACZ,uBAAW,SAAS;AAAA,UACtB,OAAO;AACL,kBAAM,IAAI;AAAA,cACR,eAAe,UAAU,UAAU;AAAA,YACrC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAGA,UAAI;AACJ,UAAI,UAAU;AACZ,cAAM,aAAa,QAAQ,QAAQ;AAEnC,YAAI,WAAW,cAAc,WAAW;AACtC,gBAAM,IAAI;AAAA,YACR;AAAA,YACA,2BAA2B,WAAW,OAAO;AAAA,UAC/C;AAAA,QACF;AACA,kBAAU,WAAW;AAAA,MACvB,OAAO;AAGL,cAAM,IAAI;AAAA,UACR,SAAS,UAAU,GAAG;AAAA,QACxB;AAAA,MACF;AAEA,YAAM,OAAO,WAAW;AAAA,QACtB;AAAA,QACA,QAAQ;AAAA,QACR,SAAS,UAAU;AAAA,QACnB,eAAe,UAAU;AAAA,QACzB,YAAY,UAAU;AAAA,QACtB;AAAA,MACF,CAAC;AAED,aAAO,IAAI,UAAU,KAAK,KAAK,EAAE;AACjC,cAAQ,KAAK,EAAE,KAAK,UAAU,KAAK,IAAI,KAAK,GAAG,CAAC;AAAA,IAClD;AAGA,eAAW,aAAa,OAAO;AAC7B,UAAI,CAAC,UAAU,cAAc,UAAU,WAAW,WAAW,EAAG;AAEhE,YAAM,SAAS,OAAO,IAAI,UAAU,GAAG;AAEvC,iBAAW,OAAO,UAAU,YAAY;AAEtC,YAAI,OAAO,OAAO,IAAI,GAAG;AACzB,YAAI,CAAC,MAAM;AACT,gBAAM,WAAW,QAAQ,GAAG;AAC5B,cAAI,UAAU;AACZ,mBAAO,SAAS;AAAA,UAClB,OAAO;AACL,kBAAM,IAAI;AAAA,cACR,eAAe,GAAG,cAAc,UAAU,GAAG;AAAA,YAC/C;AAAA,UACF;AAAA,QACF;AAEA,cAAM,SAAS,QAAQ;AAAA,UACrB,MAAM;AAAA,UACN,IAAI;AAAA,UACJ,MAAM;AAAA,UACN;AAAA,QACF,CAAC;AAED,YAAI,OAAO,UAAU;AACnB,gBAAM,IAAI;AAAA,YACR,yBAAyB,UAAU,GAAG,SAAS,GAAG,eAAe,OAAO,MAAM;AAAA,UAChF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,cAAY;AAEZ,SAAO,EAAE,QAAQ;AACnB;;;AClHO,SAAS,aAAa,OAAoB,OAA6B;AAC5E,QAAM,UAAU,aAA0B,OAAO,SAAS,SAAS;AAEnE,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,kBAAc,QAAQ,CAAC,EAAE,SAAS,WAAW,CAAC,WAAW;AACzD,QAAI,QAAQ,CAAC,EAAE,cAAc;AAC3B,eAAS,IAAI,GAAG,IAAI,QAAQ,CAAC,EAAE,aAAc,QAAQ,KAAK;AACxD,sBAAc,QAAQ,CAAC,EAAE,aAAc,CAAC,EAAE,MAAM,WAAW,CAAC,kBAAkB,CAAC,QAAQ;AACvF,sBAAc,QAAQ,CAAC,EAAE,aAAc,CAAC,EAAE,KAAK,WAAW,CAAC,kBAAkB,CAAC,OAAO;AAAA,MACvF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAmD,CAAC;AAC1D,QAAM,cAAwB,CAAC;AAC/B,MAAI,UAAyB;AAE7B,aAAW,SAAS,SAAS;AAC3B,UAAM,OAAO,WAAW;AAAA,MACtB,SAAS,MAAM;AAAA,MACf;AAAA,MACA,UAAU,MAAM;AAAA,MAChB,WAAW,MAAM;AAAA,MACjB,OAAO,MAAM;AAAA,MACb,SAAS,MAAM;AAAA,MACf,YAAY,MAAM;AAAA,MAClB,mBAAmB,MAAM;AAAA,MACzB,sBAAsB,MAAM;AAAA,MAC5B,cAAc,MAAM;AAAA,IACtB,CAAC;AAED,YAAQ,KAAK,EAAE,SAAS,KAAK,IAAI,KAAK,KAAK,IAAI,CAAC;AAEhD,QAAI,MAAM,aAAa,MAAM;AAC3B,kBAAY,KAAK,KAAK,EAAE;AACxB,gBAAU,KAAK;AAAA,IACjB;AAAA,EACF;AAGA,QAAM,eAA4D,CAAC;AACnE,MAAI,YAAY,SAAS,GAAG;AAC1B,UAAM,OAAO,IAAI,IAAY,WAAW;AACxC,UAAM,QAAQ,CAAC,GAAG,WAAW;AAE7B,WAAO,MAAM,SAAS,GAAG;AACvB,YAAM,SAAS,MAAM,MAAM;AAC3B,YAAM,OAAO,QAAQ,MAAM;AAC3B,UAAI,CAAC,MAAM,OAAQ;AAEnB,YAAM,WAAW,KAAK;AACtB,UAAI,KAAK,IAAI,QAAQ,EAAG;AACxB,WAAK,IAAI,QAAQ;AAEjB,YAAM,SAAS,QAAQ,QAAQ;AAC/B,UAAI,CAAC,UAAU,OAAO,SAAU;AAEhC,YAAM,WAAW,YAAY,QAAQ;AACrC,UAAI,SAAS,WAAW,EAAG;AAC3B,UAAI,SAAS,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG;AACrC,cAAM,WAAW,WAAW;AAAA,UAC1B,SAAS;AAAA,UACT;AAAA,UACA,UAAU;AAAA,UACV,cAAc,CAAC,EAAE,MAAM,QAAQ,KAAK,wCAAwC,CAAC;AAAA,QAC/E,CAAC;AACD,gBAAQ,KAAK,EAAE,SAAS,SAAS,IAAI,KAAK,SAAS,IAAI,CAAC;AACxD,oBAAY,KAAK,QAAQ;AACzB,qBAAa,KAAK,EAAE,SAAS,UAAU,SAAS,OAAO,QAAQ,CAAC;AAChE,cAAM,KAAK,QAAQ;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAuB,EAAE,QAAQ;AAEvC,MAAI,YAAY,SAAS,KAAK,SAAS;AACrC,WAAO,mBAAmB,oBAAoB,SAAS,WAAW;AAAA,EACpE;AAEA,MAAI,aAAa,SAAS,GAAG;AAC3B,WAAO,gBAAgB;AAAA,EACzB;AAEA,SAAO;AACT;;;AC5FO,SAAS,cAAc,OAAqB,OAA8B;AAC/E,QAAM,QAAQ,aAA+B,OAAO,OAAO,OAAO;AAElE,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,kBAAc,MAAM,CAAC,EAAE,MAAM,SAAS,CAAC,QAAQ;AAC/C,kBAAc,MAAM,CAAC,EAAE,IAAI,SAAS,CAAC,MAAM;AAC3C,kBAAc,MAAM,CAAC,EAAE,MAAM,SAAS,CAAC,QAAQ;AAAA,EACjD;AAEA,MAAI,UAAU;AACd,QAAM,WAAgE,CAAC;AAEvE,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,SAAS,UAAU;AAC1B,eAAS,KAAK;AAAA,QACZ,MAAM,KAAK;AAAA,QACX,IAAI,KAAK;AAAA,QACT,QAAQ;AAAA,MACV,CAAC;AACD;AAAA,IACF;AAEA,QAAI,KAAK,QAAQ;AACf,YAAM,UAAU,WAAW,KAAK,MAAM,KAAK,IAAI,KAAK,MAAM,KAAK;AAC/D,UAAI,SAAS;AACX;AAAA,MACF,OAAO;AACL,iBAAS,KAAK;AAAA,UACZ,MAAM,KAAK;AAAA,UACX,IAAI,KAAK;AAAA,UACT,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,IACF,OAAO;AACL,YAAMC,UAAS,QAAQ;AAAA,QACrB,MAAM,KAAK;AAAA,QACX,IAAI,KAAK;AAAA,QACT,MAAM,KAAK;AAAA,QACX;AAAA,MACF,CAAC;AAED,UAAIA,QAAO,UAAU;AACnB,iBAAS,KAAK;AAAA,UACZ,MAAM,KAAK;AAAA,UACX,IAAI,KAAK;AAAA,UACT,QAAQA,QAAO;AAAA,QACjB,CAAC;AAAA,MACH,OAAO;AACL;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAwB,EAAE,QAAQ;AACxC,MAAI,SAAS,SAAS,GAAG;AACvB,WAAO,WAAW;AAAA,EACpB;AACA,SAAO;AACT;;;AChDA,SAAS,cAAc,QAAgB,cAAsB,UAA4B;AACvF,QAAM,OAAO,eAAe,MAAM;AAClC,QAAM,WAAW,YAAY,MAAM;AAEnC,QAAM,OAAiB;AAAA,IACrB,IAAI,KAAK;AAAA,IACT,SAAS,KAAK;AAAA,IACd,UAAU,KAAK;AAAA,IACf,WAAW,KAAK;AAAA,IAChB,OAAO,KAAK;AAAA,EACd;AAEA,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,MAAI,eAAe,UAAU;AAC3B,SAAK,WAAW,SAAS;AAAA,MAAI,CAAC,UAC5B,cAAc,MAAM,IAAI,eAAe,GAAG,QAAQ;AAAA,IACpD;AAAA,EACF,OAAO;AACL,SAAK,cAAc,SAAS;AAAA,EAC9B;AAEA,SAAO;AACT;AAEO,SAAS,cAAc,OAAoC;AAChE,QAAM,SAAS,cAAc,OAAO,SAAS,SAAS;AACtD,QAAM,QAAQ,eAAe,OAAO,OAAO,SAAS,GAAG,EAAE,KAAK;AAC9D,QAAM,OAAO,eAAe,MAAM;AAClC,QAAM,YAAY,aAAa,MAAM;AAGrC,QAAM,WAAW,cAAc,QAAQ,GAAG,KAAK;AAG/C,QAAM,UAAU,aAAa,QAAQ,YAAY;AACjD,QAAM,SAAS,WAAW,QAAQ,YAAY;AAE9C,QAAM,aAAa,QAAQ,IAAI,CAAC,SAAS;AACvC,UAAM,SAAS,QAAQ,KAAK,OAAO;AACnC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,WAAW,QAAQ,YAAY;AAAA,IACjC;AAAA,EACF,CAAC;AAED,QAAM,cAAc,OAAO,IAAI,CAAC,SAAS;AACvC,UAAM,SAAS,QAAQ,KAAK,SAAS;AACrC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,WAAW,KAAK;AAAA,IAClB;AAAA,EACF,CAAC;AAED,SAAO,EAAE,MAAM,WAAW,UAAU,YAAY,YAAY;AAC9D;;;AC7CA,SAAS,iBAAiB,QAA0B;AAClD,QAAM,KAAK,MAAM;AACjB,QAAM,OAAO,GACV;AAAA,IACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMF,EACC,IAAI,MAAM;AAEb,SAAO,KAAK,IAAI,CAAC,MAAM,EAAE,EAAE;AAC7B;AAGO,SAAS,YAAY,OAAgC;AAC1D,QAAM,UAAU,cAAc,OAAO,SAAS,SAAS;AACvD,QAAM,KAAK,MAAM;AACjB,QAAM,QAAQ,KAAK,IAAI,eAAe,OAAO,OAAO,SAAS,GAAG,GAAG,KAAK,IAAI,GAAG;AAC/E,QAAM,SAAS,OAAO;AACtB,QAAM,SAAS,eAAe,OAAO,QAAQ,QAAQ;AAGrD,QAAM,aAAuB,CAAC,eAAe;AAC7C,QAAM,SAAoB,CAAC,OAAO;AAElC,MAAI,QAAQ,aAAa,QAAW;AAClC,eAAW,KAAK,gBAAgB;AAChC,WAAO,KAAK,OAAO,WAAW,IAAI,CAAC;AAAA,EACrC;AAEA,MAAI,QAAQ,MAAM;AAChB,eAAW,KAAK,kBAAkB;AAClC,WAAO,KAAK,IAAI,OAAO,IAAI,GAAG;AAAA,EAChC;AAEA,MAAI,QAAQ,UAAU;AACpB,UAAM,gBAAgB,iBAAiB,OAAO,QAAQ;AACtD,QAAI,cAAc,WAAW,GAAG;AAC9B,aAAO,EAAE,OAAO,CAAC,GAAG,OAAO,EAAE;AAAA,IAC/B;AACA,eAAW,KAAK,YAAY,cAAc,IAAI,MAAM,GAAG,EAAE,KAAK,GAAG,CAAC,GAAG;AACrE,WAAO,KAAK,GAAG,aAAa;AAAA,EAC9B;AAEA,MAAI,QAAQ,mBAAmB;AAC7B,eAAW,KAAK,mBAAmB;AACnC,WAAO,KAAK,YAAY,OAAO,iBAAiB,IAAI;AAAA,EACtD;AAEA,MAAI,QAAQ,SAAS;AACnB,eAAW;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,eAAe;AACzB,eAAW,KAAK,gBAAgB;AAChC,eAAW;AAAA,MACT;AAAA,IACF;AACA,eAAW;AAAA,MACT;AAAA;AAAA;AAAA;AAAA;AAAA,IAKF;AAAA,EACF;AAEA,MAAI,QAAQ,YAAY;AACtB,eAAW,KAAK,gBAAgB;AAChC,eAAW;AAAA,MACT;AAAA;AAAA;AAAA;AAAA;AAAA,IAKF;AAAA,EACF;AAEA,MAAI,QAAQ,YAAY;AACtB,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,UAAU,GAAG;AAC5D,iBAAW,KAAK,mCAAmC;AACnD,aAAO,KAAK,KAAK,GAAG,IAAI,KAAwB;AAAA,IAClD;AAAA,EACF;AAEA,MAAI,QAAQ,eAAe,QAAW;AACpC,QAAI,OAAO,eAAe,MAAM;AAC9B,iBAAW;AAAA,QACT;AAAA,MACF;AAAA,IACF,OAAO;AACL,iBAAW,KAAK,iDAAiD;AACjE,aAAO,KAAK,OAAO,UAAU;AAAA,IAC/B;AAAA,EACF;AAGA,MAAI,QAAQ;AACV,UAAM,CAAC,YAAY,QAAQ,IAAI,OAAO,MAAM,GAAG;AAC/C,eAAW,KAAK,uDAAuD;AACvE,WAAO,KAAK,YAAY,YAAY,QAAQ;AAAA,EAC9C;AAEA,QAAM,cAAc,WAAW,KAAK,OAAO;AAG3C,MAAI;AACJ,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AAEH,gBAAU;AACV;AAAA,IACF,KAAK;AACH,gBAAU;AACV;AAAA,IACF,KAAK;AACH,gBAAU;AACV;AAAA,IACF,KAAK;AAAA,IACL;AACE,gBAAU;AACV;AAAA,EACJ;AAIA,QAAM,kBAAkB,SAAS,WAAW,MAAM,GAAG,EAAE,IAAI;AAC3D,QAAM,cAAc,SAAS,OAAO,MAAM,GAAG,EAAE,IAAI,CAAC,GAAG,MAAM;AAC7D,QAAM,QACJ,GAAG,QAAQ,+CAA+C,gBAAgB,KAAK,OAAO,CAAC,EAAE,EAAE,IAAI,GAAG,WAAW,EAC7G;AAGF,SAAO,KAAK,QAAQ,CAAC;AACrB,QAAM,QAAQ,+BAA+B,WAAW,aAAa,OAAO;AAC5E,QAAM,OAAO,GAAG,QAAQ,KAAK,EAAE,IAAI,GAAG,MAAM;AAE5C,QAAM,UAAU,KAAK,SAAS;AAC9B,QAAM,QAAQ,UAAU,KAAK,MAAM,GAAG,KAAK,IAAI;AAE/C,QAAM,QAA2B,MAAM,IAAI,CAAC,SAAS;AAAA,IACnD,IAAI,IAAI;AAAA,IACR,SAAS,IAAI;AAAA,IACb,UAAU,IAAI,aAAa;AAAA,IAC3B,OAAO,IAAI,QAAQ,KAAK,MAAM,IAAI,KAAK,IAAI;AAAA,IAC3C,QAAQ,IAAI;AAAA,IACZ,OAAO,IAAI;AAAA,IACX,YAAY,KAAK,MAAM,IAAI,UAAU;AAAA,EACvC,EAAE;AAEF,QAAM,SAAsB,EAAE,OAAO,MAAM;AAE3C,MAAI,SAAS;AACX,UAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,WAAO,cAAc,GAAG,KAAK,UAAU,IAAI,KAAK,EAAE;AAAA,EACpD;AAEA,SAAO;AACT;;;AC5KO,SAAS,WACd,OACA,OACA,kBAA0B,IACd;AACZ,QAAM,UAAU,cAAc,OAAO,SAAS,SAAS;AACvD,QAAM,QAAQ,eAAe,OAAO,OAAO,OAAO;AAClD,QAAM,QAAQ,eAAe,OAAO,OAAO,SAAS,GAAG,EAAE,KAAK;AAC9D,QAAM,QAAQ,gBAAgB,OAAO,OAAO,OAAO,KAAK;AACxD,QAAM,KAAK,MAAM;AAGjB,MAAI,cAAc;AAClB,QAAM,cAAyB,CAAC;AAChC,MAAI,OAAO;AACT,UAAM,gBAAgB,GACnB;AAAA,MACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMF,EACC,IAAI,KAAK;AAEZ,QAAI,cAAc,WAAW,GAAG;AAC9B,aAAO,EAAE,OAAO,CAAC,EAAE;AAAA,IACrB;AACA,kBAAc,gBAAgB,cAAc,IAAI,MAAM,GAAG,EAAE,KAAK,GAAG,CAAC;AACpE,gBAAY,KAAK,GAAG,cAAc,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAAA,EACpD;AAGA,MAAI,QAAQ;AAAA;AAAA;AAAA,MAGR,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWf,QAAM,SAAoB,CAAC,SAAS,GAAG,WAAW;AAGlD,QAAM,cAAc,IAAI;AAAA,IACtB,KAAK,IAAI,IAAI,kBAAkB,KAAK;AAAA,EACtC,EAAE,YAAY;AAEd,WAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOT,SAAO,KAAK,OAAO,WAAW;AAG9B,MAAI,MAAM,QAAQ;AAChB,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,MAAM,GAAG;AACvD,eAAS;AACT,aAAO,KAAK,KAAK,GAAG,IAAI,KAAwB;AAAA,IAClD;AAAA,EACF;AAIA,WAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOT,SAAO,KAAK,KAAK;AAEjB,QAAM,OAAO,GAAG,QAAQ,KAAK,EAAE,IAAI,GAAG,MAAM;AAE5C,QAAM,WAAW,KAAK,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE;AAE5C,QAAM,UAA4B,SAAS,IAAI,CAAC,EAAE,IAAI,MAAM;AAC1D,UAAM,OAAO,QAAQ,IAAI,EAAE;AAC3B,UAAM,YAAY,aAAa,IAAI,EAAE;AAGrC,UAAM,YAAyD,CAAC;AAChE,eAAW,OAAO,WAAW;AAC3B,YAAM,UAAU,QAAQ,IAAI,EAAE;AAC9B,UAAI,WAAW,QAAQ,cAAc,SAAS,GAAG;AAC/C,kBAAU,KAAK,EAAE,SAAS,IAAI,IAAI,OAAO,QAAQ,cAAc,CAAC;AAAA,MAClE;AAAA,IACF;AAGA,UAAM,WAAW,aAAa,IAAI,IAAI,YAAY;AAClD,UAAM,gBAAgB,SACnB,IAAI,CAAC,SAAS;AACb,YAAM,UAAU,QAAQ,KAAK,OAAO;AACpC,UAAI,CAAC,WAAW,CAAC,QAAQ,SAAU,QAAO;AAC1C,aAAO;AAAA,QACL,IAAI,QAAQ;AAAA,QACZ,SAAS,QAAQ;AAAA,QACjB,UAAU,QAAQ;AAAA,MACpB;AAAA,IACF,CAAC,EACA,OAAO,OAAO;AAGjB,QAAI,OAAO;AACT,iBAAW;AAAA,QACT,SAAS,KAAK;AAAA,QACd;AAAA,QACA,YAAY;AAAA,UACV,aAAa;AAAA,UACb,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,QACtC;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,MAAM,QAAQ,QAAQ,IAAI,EAAE,IAAK;AAAA,MACjC,WAAW,UAAU,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,SAAS,EAAE,QAAQ,EAAE;AAAA,MAClE,eAAe;AAAA,QACb,MAAM,KAAK;AAAA,QACX;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,EAAE,OAAO,QAAQ;AAC1B;;;ACrIA,SAAS,uBAAuB,QAAgB,aAA8B;AAE5E,QAAM,KAAK,MAAM;AACjB,MAAI,UAAyB;AAE7B,SAAO,SAAS;AACd,QAAI,YAAY,OAAQ,QAAO;AAC/B,UAAM,MAAM,GACT,QAAQ,uCAAuC,EAC/C,IAAI,OAAO;AACd,cAAU,KAAK,UAAU;AAAA,EAC3B;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,QAA0B;AACnD,QAAM,MAAgB,CAAC;AACvB,QAAM,QAAQ,CAAC,MAAM;AAErB,SAAO,MAAM,SAAS,GAAG;AACvB,UAAM,UAAU,MAAM,IAAI;AAC1B,UAAM,WAAW,YAAY,OAAO;AACpC,eAAW,SAAS,UAAU;AAC5B,UAAI,KAAK,MAAM,EAAE;AACjB,YAAM,KAAK,MAAM,EAAE;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,sBAAsB,QAAgB,UAAwB;AACrE,QAAM,KAAK,MAAM;AACjB,KAAG,QAAQ,yCAAyC,EAAE,IAAI,UAAU,MAAM;AAC1E,QAAM,WAAW,GAAG,QAAQ,uCAAuC,EAAE,IAAI,MAAM;AAC/E,aAAW,SAAS,UAAU;AAC5B,0BAAsB,MAAM,IAAI,WAAW,CAAC;AAAA,EAC9C;AACF;AAEA,SAAS,WAAW,IAAY,OAAoD;AAClF,QAAM,KAAK,MAAM;AACjB,QAAM,OAAO,eAAe,GAAG,OAAO;AACtC,QAAM,YAAY,eAAe,GAAG,UAAU;AAE9C,MAAI,uBAAuB,GAAG,SAAS,GAAG,UAAU,GAAG;AACrD,UAAM,IAAI;AAAA,MACR,4BAA4B,GAAG,OAAO,0BAA0B,GAAG,UAAU;AAAA,IAC/E;AAAA,EACF;AAEA,QAAM,YAAY,KAAK;AACvB,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,KAAG,QAAQ,0DAA0D,EAAE;AAAA,IACrE,GAAG;AAAA,IACH;AAAA,IACA,GAAG;AAAA,EACL;AAGA,wBAAsB,GAAG,SAAS,UAAU,QAAQ,CAAC;AAErD,WAAS,GAAG,SAAS,OAAO,SAAS;AAAA,IACnC,EAAE,OAAO,UAAU,QAAQ,WAAW,OAAO,GAAG,WAAW;AAAA,EAC7D,CAAC;AAED,SAAO,EAAE,SAAS,GAAG,SAAS,QAAQ,eAAe,GAAG,UAAU,GAAG;AACvE;AAEA,SAAS,YAAY,IAAa,OAAoD;AACpF,QAAM,KAAK,MAAM;AACjB,QAAM,SAAS,eAAe,GAAG,MAAM;AACvC,QAAM,SAAS,eAAe,GAAG,MAAM;AAGvC,QAAM,gBAAgB,GAAG,QAAQ,uCAAuC,EAAE,IAAI,GAAG,MAAM;AACvF,KAAG,QAAQ,8DAA8D,EAAE;AAAA,IACzE,GAAG;AAAA,KACH,oBAAI,KAAK,GAAE,YAAY;AAAA,IACvB,GAAG;AAAA,EACL;AACA,aAAW,SAAS,eAAe;AACjC,0BAAsB,MAAM,IAAI,OAAO,QAAQ,CAAC;AAAA,EAClD;AAGA,QAAM,iBAA6B,CAAC,GAAG,OAAO,UAAU,GAAG,OAAO,QAAQ;AAC1E,KAAG,QAAQ,4DAA4D,EAAE;AAAA,IACvE,KAAK,UAAU,cAAc;AAAA,KAC7B,oBAAI,KAAK,GAAE,YAAY;AAAA,IACvB,GAAG;AAAA,EACL;AAGA,QAAM,iBAAiB,aAAa,GAAG,MAAM;AAC7C,QAAM,gBAAgB,WAAW,GAAG,MAAM;AAE1C,aAAW,QAAQ,gBAAgB;AAEjC,UAAM,WAAW,GACd;AAAA,MACC;AAAA,IACF,EACC,IAAI,GAAG,QAAQ,KAAK,SAAS,KAAK,IAAI;AAEzC,QAAI,CAAC,UAAU;AACb,SAAG;AAAA,QACD;AAAA,MACF,EAAE,IAAI,GAAG,QAAQ,KAAK,EAAE;AAAA,IAC1B,OAAO;AACL,SAAG,QAAQ,gCAAgC,EAAE,IAAI,KAAK,EAAE;AAAA,IAC1D;AAAA,EACF;AAEA,aAAW,QAAQ,eAAe;AAEhC,UAAM,WAAW,GACd;AAAA,MACC;AAAA,IACF,EACC,IAAI,KAAK,WAAW,GAAG,QAAQ,KAAK,IAAI;AAE3C,QAAI,CAAC,UAAU;AACb,SAAG;AAAA,QACD;AAAA,MACF,EAAE,IAAI,GAAG,QAAQ,KAAK,EAAE;AAAA,IAC1B,OAAO;AACL,SAAG,QAAQ,gCAAgC,EAAE,IAAI,KAAK,EAAE;AAAA,IAC1D;AAAA,EACF;AAGA,WAAS,GAAG,QAAQ,OAAO,UAAU;AAAA,IACnC,EAAE,OAAO,eAAe,QAAQ,MAAM,OAAO,GAAG,OAAO;AAAA,EACzD,CAAC;AACD,WAAS,GAAG,QAAQ,OAAO,eAAe;AAAA,IACxC,EAAE,OAAO,eAAe,QAAQ,MAAM,OAAO,GAAG,OAAO;AAAA,EACzD,CAAC;AAGD,KAAG,QAAQ,sDAAsD,EAAE;AAAA,IACjE,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AACA,KAAG,QAAQ,gCAAgC,EAAE,IAAI,GAAG,MAAM;AAE1D,SAAO,EAAE,SAAS,GAAG,QAAQ,QAAQ,UAAU,GAAG,MAAM,SAAS,GAAG,MAAM,GAAG;AAC/E;AAEA,SAAS,WAAW,IAAY,OAAoD;AAClF,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AAGnC,QAAM,cAAc,kBAAkB,GAAG,OAAO;AAChD,QAAM,SAAS,CAAC,GAAG,SAAS,GAAG,WAAW;AAG1C,aAAW,MAAM,QAAQ;AACvB,UAAM,OAAO,QAAQ,EAAE;AACvB,QAAI,CAAC,QAAQ,KAAK,SAAU;AAE5B,eAAW;AAAA,MACT,SAAS;AAAA,MACT;AAAA,MACA,UAAU;AAAA,MACV,cAAc,CAAC,EAAE,MAAM,WAAW,KAAK,GAAG,OAAO,CAAC;AAAA,IACpD,CAAC;AAED,aAAS,IAAI,OAAO,WAAW;AAAA,MAC7B,EAAE,OAAO,YAAY,QAAQ,OAAO,OAAO,KAAK;AAAA,MAChD,EAAE,OAAO,UAAU,QAAQ,MAAM,OAAO,GAAG,OAAO;AAAA,IACpD,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,SAAS,GAAG;AAAA,IACZ,QAAQ,WAAW,OAAO,MAAM,aAAa,GAAG,MAAM;AAAA,EACxD;AACF;AAEO,SAAS,kBACd,OACA,OACmB;AACnB,QAAM,aAAa,aAA4B,OAAO,YAAY,YAAY;AAE9E,WAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,UAAM,KAAK,WAAW,CAAC;AACvB,kBAAc,GAAG,IAAI,cAAc,CAAC,MAAM;AAC1C,QAAI,GAAG,OAAO,QAAQ;AACpB,oBAAe,GAAc,SAAS,cAAc,CAAC,WAAW;AAChE,oBAAe,GAAc,YAAY,cAAc,CAAC,cAAc;AAAA,IACxE,WAAW,GAAG,OAAO,SAAS;AAC5B,oBAAe,GAAe,QAAQ,cAAc,CAAC,UAAU;AAC/D,oBAAe,GAAe,QAAQ,cAAc,CAAC,UAAU;AAAA,IACjE,WAAW,GAAG,OAAO,QAAQ;AAC3B,oBAAe,GAAc,SAAS,cAAc,CAAC,WAAW;AAChE,oBAAe,GAAc,QAAQ,cAAc,CAAC,UAAU;AAAA,IAChE,OAAO;AACL,YAAM,IAAI,MAAM,sBAAsB,GAAG,EAAE,EAAE;AAAA,IAC/C;AAAA,EACF;AAEA,QAAM,KAAK,MAAM;AACjB,MAAI,UAAU;AACd,QAAM,UAAkE,CAAC;AACzE,MAAI,UAAyB;AAE7B,QAAM,cAAc,GAAG,YAAY,MAAM;AACvC,eAAW,MAAM,YAAY;AAC3B,UAAI;AAEJ,cAAQ,GAAG,IAAI;AAAA,QACb,KAAK;AACH,mBAAS,WAAW,IAAI,KAAK;AAC7B,oBAAU,QAAQ,GAAG,OAAO,GAAG,WAAW;AAC1C;AAAA,QACF,KAAK;AACH,mBAAS,YAAY,IAAI,KAAK;AAC9B,oBAAU,QAAQ,GAAG,MAAM,GAAG,WAAW;AACzC;AAAA,QACF,KAAK;AACH,mBAAS,WAAW,IAAI,KAAK;AAC7B,oBAAU,QAAQ,GAAG,OAAO,GAAG,WAAW;AAC1C;AAAA,QACF;AACE,gBAAM,IAAI,MAAM,sBAAuB,GAAqB,EAAE,EAAE;AAAA,MACpE;AAEA,cAAQ,KAAK,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC;AACrC;AAAA,IACF;AAAA,EACF,CAAC;AAED,cAAY;AAEZ,QAAM,SAA4B,EAAE,SAAS,QAAQ;AAErD,MAAI,SAAS;AACX,UAAM,aAAa,oBAAoB,OAAO;AAC9C,QAAI,WAAW,SAAS,GAAG;AACzB,aAAO,mBAAmB;AAAA,IAC5B;AAAA,EACF;AAEA,SAAO;AACT;;;ACxQO,SAAS,cAAc,OAAoC;AAChE,QAAM,SAAS,cAAc,OAAO,SAAS,SAAS;AACtD,QAAM,QAAQ,eAAe,OAAO,OAAO,SAAS,GAAG,GAAG,KAAK;AAC/D,QAAM,SAAS,eAAe,OAAO,QAAQ,QAAQ;AAErD,iBAAe,MAAM;AAErB,QAAM,EAAE,QAAQ,YAAY,IAAI,UAAU,QAAQ,OAAO,MAAM;AAE/D,QAAM,SAAwB;AAAA,IAC5B,QAAQ,OAAO,IAAI,CAAC,OAAO;AAAA,MACzB,WAAW,EAAE;AAAA,MACb,OAAO,EAAE;AAAA,MACT,QAAQ,EAAE;AAAA,MACV,SAAS,EAAE;AAAA,IACb,EAAE;AAAA,EACJ;AAEA,MAAI,aAAa;AACf,WAAO,cAAc;AAAA,EACvB;AAEA,SAAO;AACT;;;ACsBO,SAAS,cAAc,OAAkG;AAC9H,QAAM,gBAAgB,eAAe,OAAO,gBAAgB,kBAAkB,GAAG,EAAE,KAAK;AACxF,QAAM,KAAK,MAAM;AAGjB,MAAI,UAAU,eAAe,OAAO,SAAS,SAAS;AACtD,MAAI,CAAC,SAAS;AACZ,UAAM,WAAW,aAAa;AAC9B,QAAI,SAAS,WAAW,GAAG;AACzB,aAAO;AAAA,QACL,UAAU,CAAC;AAAA,QACX,MAAM;AAAA,MACR;AAAA,IACF;AACA,QAAI,SAAS,WAAW,GAAG;AACzB,gBAAU,SAAS,CAAC,EAAE;AAAA,IACxB,OAAO;AACL,aAAO;AAAA,QACL;AAAA,QACA,MAAM,GAAG,SAAS,MAAM;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAGA,QAAM,OAAO,eAAe,OAAO;AACnC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,YAAY,qBAAqB,sBAAsB,OAAO,EAAE;AAAA,EAC5E;AAGA,QAAM,UAAU,kBAAkB,OAAO;AAGzC,QAAM,cAAc,GACjB,QAAQ,8DAA8D,EACtE,IAAI,KAAK,EAAE;AAEd,QAAM,OAAO,YAAY,IAAI,CAAC,UAAU;AACtC,UAAM,gBAAgB,GACnB;AAAA,MACC;AAAA;AAAA;AAAA,IAGF,EACC,IAAI,MAAM,EAAE;AAOf,WAAO;AAAA,MACL,IAAI,MAAM;AAAA,MACV,SAAS,MAAM;AAAA,MACf,UAAU,MAAM,aAAa;AAAA,MAC7B,WAAW,MAAM;AAAA,MACjB,UAAU,cAAc,IAAI,CAAC,QAAQ;AAAA,QACnC,IAAI,GAAG;AAAA,QACP,SAAS,GAAG;AAAA,QACZ,UAAU,GAAG,aAAa;AAAA,QAC1B,aAAa,GAAG;AAAA,MAClB,EAAE;AAAA,IACJ;AAAA,EACF,CAAC;AAGD,QAAM,WAAW,GACd,QAAQ,iGAAiG,EACzG,IAAI,OAAO;AAEd,QAAM,cAAgD,CAAC;AACvD,aAAW,QAAQ,UAAU;AAC3B,UAAM,WAAuB,KAAK,MAAM,KAAK,QAAQ;AACrD,eAAW,MAAM,UAAU;AACzB,kBAAY,KAAK;AAAA,QACf,SAAS,KAAK;AAAA,QACd,cAAc,KAAK;AAAA,QACnB,MAAM,GAAG;AAAA,QACT,KAAK,GAAG;AAAA,QACR,OAAO,GAAG;AAAA,QACV,WAAW,GAAG;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,EACF;AACA,cAAY,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,cAAc,EAAE,SAAS,CAAC;AACjE,QAAM,kBAAkB,YAAY,MAAM,GAAG,aAAa;AAG1D,QAAM,WAAW,GACd,QAAQ,6EAA6E,EACrF,IAAI,OAAO;AAEd,QAAM,UAAU,oBAAI,IAAY;AAChC,aAAW,OAAO,UAAU;AAC1B,UAAM,QAAkB,KAAK,MAAM,IAAI,aAAa;AACpD,eAAW,QAAQ,OAAO;AACxB,cAAQ,IAAI,IAAI;AAAA,IAClB;AAAA,EACF;AACA,QAAM,gBAAgB,CAAC,GAAG,OAAO,EAAE,KAAK;AAGxC,QAAM,gBAAgB,GACnB,QAAQ,2FAA2F,EACnG,IAAI,OAAO;AAGd,QAAM,iBAAiB,GACpB;AAAA,IACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeF,EACC,IAAI,OAAO;AAEd,QAAM,aAAa,eAAe,IAAI,CAAC,SAAS;AAAA,IAC9C,IAAI,IAAI;AAAA,IACR,SAAS,IAAI;AAAA,IACb,YAAY,KAAK,MAAM,IAAI,UAAU;AAAA,EACvC,EAAE;AAGF,QAAM,YAAY,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,GAAI,EAAE,YAAY;AACzE,QAAM,uBAAuB,GAC1B;AAAA,IACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMF,EACC,IAAI,SAAS,SAAS;AAEzB,QAAM,oBAAoB,qBAAqB,IAAI,CAAC,SAAS;AAAA,IAC3D,IAAI,IAAI;AAAA,IACR,SAAS,IAAI;AAAA,IACb,aAAa,IAAI;AAAA,IACjB,OAAO,IAAI,cAAc;AAAA,EAC3B,EAAE;AAGF,QAAM,kBAAkB,GACrB,QAAQ,6DAA6D,EACrE,IAAI,OAAO;AACd,QAAM,gBAAgB,gBAAgB;AAGtC,MAAI;AACJ,MAAI,KAAK,cAAc,WAAW;AAChC,WAAO;AAAA,EACT,WAAW,WAAW,SAAS,GAAG;AAChC,UAAM,aAAa,kBAAkB,SAAS,IAC1C,IAAI,kBAAkB,MAAM,gCAC5B;AACJ,WAAO,GAAG,WAAW,MAAM,6BAA6B,UAAU,+BAA+B,OAAO;AAAA,EAC1G,WAAW,QAAQ,aAAa,KAAK,QAAQ,eAAe,GAAG;AAC7D,WAAO;AAAA,EACT,WAAW,QAAQ,SAAS,KAAK,KAAK,cAAc,WAAW;AAC7D,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA,MAAM,KAAK;AAAA,IACX,WAAW,KAAK;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AC/NA,SAAS,UAAU,MAAY,cAAsB,UAAkB,OAAsD;AAC3H,QAAM;AACN,MAAI,KAAK,SAAU,OAAM;AAEzB,QAAM,WAAW,YAAY,KAAK,EAAE;AACpC,QAAM,WAAqB;AAAA,IACzB,IAAI,KAAK;AAAA,IACT,SAAS,KAAK;AAAA,IACd,UAAU,KAAK;AAAA,IACf,YAAY,KAAK;AAAA,EACnB;AAEA,MAAI,SAAS,WAAW,EAAG,QAAO;AAElC,MAAI,eAAe,UAAU;AAC3B,aAAS,WAAW,SAAS;AAAA,MAAI,CAAC,UAChC,UAAU,OAAO,eAAe,GAAG,UAAU,KAAK;AAAA,IACpD;AAAA,EACF,OAAO;AACL,aAAS,cAAc,SAAS;AAAA,EAClC;AAEA,SAAO;AACT;AAEO,SAAS,WAAW,OAA8B;AACvD,QAAM,UAAU,cAAc,OAAO,SAAS,SAAS;AACvD,QAAM,QAAQ,eAAe,OAAO,OAAO,SAAS,GAAG,EAAE,KAAK;AAE9D,QAAM,OAAO,eAAe,OAAO;AACnC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,YAAY,qBAAqB,sBAAsB,OAAO,EAAE;AAAA,EAC5E;AAEA,QAAM,QAAQ,EAAE,OAAO,GAAG,UAAU,EAAE;AACtC,QAAM,OAAO,UAAU,MAAM,GAAG,OAAO,KAAK;AAE5C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO;AAAA,MACL,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,YAAY,MAAM,QAAQ,MAAM;AAAA,IAClC;AAAA,EACF;AACF;;;AC7EA,SAAS,UAAAC,eAAc;AAyBhB,SAAS,qBAAqB,OAA4B,OAAe;AAC9E,QAAM,UAAU,cAAc,MAAM,SAAS,SAAS;AACtD,QAAM,MAAM,cAAc,MAAM,KAAK,KAAK;AAC1C,QAAM,UAAU,cAAc,MAAM,SAAS,SAAS;AAEtD,QAAM,OAAO,eAAe,OAAO;AACnC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,YAAY,aAAa,YAAY,OAAO,aAAa;AAAA,EACrE;AAEA,QAAM,KAAK,MAAM;AACjB,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AAEnC,QAAM,WAAW,GACd,QAAQ,wDAAwD,EAChE,IAAI,SAAS,GAAG;AAEnB,MAAI,UAAU;AACZ,OAAG;AAAA,MACD;AAAA,IACF,EAAE,IAAI,SAAS,KAAK,SAAS,EAAE;AAC/B,WAAO,EAAE,KAAK,QAAQ,UAAU;AAAA,EAClC,OAAO;AACL,UAAM,KAAKC,QAAO;AAClB,OAAG;AAAA,MACD;AAAA,IACF,EAAE,IAAI,IAAI,SAAS,KAAK,SAAS,OAAO,KAAK,GAAG;AAChD,WAAO,EAAE,KAAK,QAAQ,UAAU;AAAA,EAClC;AACF;AASO,SAAS,oBAAoB,OAA2B;AAC7D,QAAM,UAAU,cAAc,MAAM,SAAS,SAAS;AAEtD,QAAM,OAAO,eAAe,OAAO;AACnC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,YAAY,aAAa,YAAY,OAAO,aAAa;AAAA,EACrE;AAEA,QAAM,KAAK,MAAM;AAEjB,MAAI,MAAM,KAAK;AACb,UAAM,MAAM,GACT,QAAQ,uDAAuD,EAC/D,IAAI,SAAS,MAAM,GAAG;AAEzB,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,YAAY,aAAa,oBAAoB,MAAM,GAAG,2BAA2B,OAAO,GAAG;AAAA,IACvG;AAEA,WAAO;AAAA,MACL,KAAK,IAAI;AAAA,MACT,SAAS,IAAI;AAAA,MACb,YAAY,IAAI;AAAA,MAChB,YAAY,IAAI;AAAA,IAClB;AAAA,EACF;AAGA,QAAM,OAAO,GACV,QAAQ,uGAAuG,EAC/G,IAAI,OAAO;AAEd,SAAO,EAAE,SAAS,KAAK;AACzB;AASO,SAAS,sBAAsB,OAA6B;AACjE,QAAM,UAAU,cAAc,MAAM,SAAS,SAAS;AACtD,QAAM,MAAM,cAAc,MAAM,KAAK,KAAK;AAE1C,QAAM,OAAO,eAAe,OAAO;AACnC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,YAAY,aAAa,YAAY,OAAO,aAAa;AAAA,EACrE;AAEA,QAAM,KAAK,MAAM;AACjB,QAAM,SAAS,GACZ,QAAQ,qDAAqD,EAC7D,IAAI,SAAS,GAAG;AAEnB,MAAI,OAAO,YAAY,GAAG;AACxB,UAAM,IAAI,YAAY,aAAa,oBAAoB,GAAG,2BAA2B,OAAO,GAAG;AAAA,EACjG;AAEA,SAAO,EAAE,KAAK,QAAQ,UAAU;AAClC;AASO,SAAS,sBAAsB,OAA6B;AACjE,QAAM,UAAU,cAAc,MAAM,SAAS,SAAS;AACtD,QAAM,QAAQ,cAAc,MAAM,OAAO,OAAO;AAEhD,QAAM,OAAO,eAAe,OAAO;AACnC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,YAAY,aAAa,YAAY,OAAO,aAAa;AAAA,EACrE;AAEA,QAAM,KAAK,MAAM;AACjB,QAAM,UAAU,IAAI,KAAK;AAEzB,QAAM,OAAO,GACV;AAAA,IACC;AAAA,EACF,EACC,IAAI,SAAS,SAAS,OAAO;AAEhC,SAAO,EAAE,SAAS,MAAM,MAAM;AAChC;;;ACjJA,IAAM,cAAc;AAAA,EAClB,aAAa;AAAA,EACb,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,cAAc;AAChB;AAMO,SAAS,eAAe,MAAY,SAAiB,QAAsB;AAChF,MAAI,SAAS,MAAO;AAEpB,QAAM,KAAK,MAAM;AACjB,QAAM,EAAE,MAAM,IAAI,GACf,QAAQ,uDAAuD,EAC/D,IAAI,OAAO;AAEd,MAAI,QAAQ,SAAS,YAAY,oBAAoB;AACnD,UAAM,IAAI;AAAA,MACR;AAAA,MACA,2BAA2B,YAAY,kBAAkB,gCAC7C,KAAK,aAAa,MAAM;AAAA,IACtC;AAAA,EACF;AACF;AAMO,SAAS,kBAAkB,MAAkB;AAClD,MAAI,SAAS,MAAO;AAEpB,QAAM,KAAK,MAAM;AACjB,QAAM,EAAE,MAAM,IAAI,GACf,QAAQ,0DAA0D,EAClE,IAAI;AAEP,MAAI,SAAS,YAAY,aAAa;AACpC,UAAM,IAAI;AAAA,MACR;AAAA,MACA,2BAA2B,YAAY,WAAW;AAAA,IAEpD;AAAA,EACF;AACF;AAKO,SAAS,iBAAiB,MAAY,WAA4B;AACvE,QAAM,MAAM,SAAS,QAAS,aAAa,KAAM,YAAY;AAC7D,SAAO,KAAK,IAAI,aAAa,KAAK,SAAS,QAAQ,KAAK,YAAY,oBAAoB;AAC1F;AAMO,SAAS,mBAAmB,OAAmB;AAEpD;AACF;AAMO,SAAS,WAAW,OAAa,OAAoC;AAC1E,SAAO;AACT;;;AdvDA,SAAS,kBAAkB;AAC3B,SAAS,WAAW,oBAAoB;AACxC,SAAS,eAAe;AACxB,SAAS,MAAM,SAAS,eAAe;AACvC,SAAS,qBAAqB;AAG9B,IAAM,iBAAiB,QAAQ,IAAI,eAAe;AAClD,IAAM,YAAY,SAAS,QAAQ,IAAI,mBAAmB,MAAM,EAAE;AAElE,SAAS,gBAAwB;AAC/B,QAAM,aAAa,QAAQ,GAAG;AAC9B,QAAM,OAAO,WAAW,QAAQ,EAAE,OAAO,UAAU,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AAC9E,QAAM,MAAM,KAAK,QAAQ,GAAG,UAAU,MAAM,IAAI;AAChD,YAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAClC,SAAO,KAAK,KAAK,UAAU;AAC7B;AAEA,IAAM,UAAU,QAAQ,IAAI,YAAY,cAAc;AAGtD,IAAM,WAAW;AACjB,IAAI,cAAc;AAClB,IAAI;AACF,QAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,QAAM,MAAM,KAAK,MAAM,aAAa,KAAK,WAAW,MAAM,cAAc,GAAG,OAAO,CAAC;AACnF,gBAAc,IAAI;AACpB,QAAQ;AAAC;AAGT,IAAI,gBAA+B,YAAY,WAAW;AAG1D,IAAI,gBAA+B;AAEnC,eAAe,iBAAgC;AAC7C,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,8BAA8B,QAAQ,SAAS;AACvE,QAAI,CAAC,IAAI,GAAI;AACb,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,QAAI,KAAK,YAAY,aAAa;AAChC,sBAAgB,6BAA6B,WAAW,WAAM,KAAK,OAAO;AAAA,IAC5E;AAAA,EACF,QAAQ;AAAA,EAAC;AACX;AAGA,IAAM,QAAQ;AAAA,EACZ;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS;AAAA,UACP,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,OAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO;AAAA,YACL,MAAM;AAAA,YACN,YAAY;AAAA,cACV,KAAK;AAAA,gBACH,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,YAAY;AAAA,gBACV,MAAM;AAAA,gBACN,aACE;AAAA,cACJ;AAAA,cACA,SAAS,EAAE,MAAM,SAAS;AAAA,cAC1B,eAAe;AAAA,gBACb,MAAM;AAAA,gBACN,OAAO,EAAE,MAAM,SAAS;AAAA,gBACxB,aAAa;AAAA,cACf;AAAA,cACA,YAAY;AAAA,gBACV,MAAM;AAAA,gBACN,OAAO,EAAE,MAAM,SAAS;AAAA,gBACxB,aACE;AAAA,cACJ;AAAA,cACA,YAAY;AAAA,gBACV,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,YACF;AAAA,YACA,UAAU,CAAC,OAAO,SAAS;AAAA,UAC7B;AAAA,UACA,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,OAAO;AAAA,IACpB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS,EAAE,MAAM,UAAU,aAAa,kDAAkD;AAAA,QAC1F,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aACE;AAAA,QACJ;AAAA,MACF;AAAA,MACA,UAAU,CAAC,SAAS;AAAA,IACtB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS,EAAE,MAAM,UAAU,aAAa,qBAAqB;AAAA,QAC7D,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,SAAS;AAAA,IACtB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS;AAAA,UACP,MAAM;AAAA,UACN,OAAO;AAAA,YACL,MAAM;AAAA,YACN,YAAY;AAAA,cACV,SAAS,EAAE,MAAM,SAAS;AAAA,cAC1B,UAAU,EAAE,MAAM,UAAU;AAAA,cAC5B,WAAW,EAAE,MAAM,UAAU,aAAa,mGAAmG;AAAA,cAC7I,OAAO,EAAE,aAAa,gCAAgC;AAAA,cACtD,SAAS,EAAE,MAAM,SAAS;AAAA,cAC1B,YAAY;AAAA,gBACV,MAAM;AAAA,gBACN,aACE;AAAA,cACJ;AAAA,cACA,mBAAmB;AAAA,gBACjB,MAAM;AAAA,gBACN,OAAO,EAAE,MAAM,SAAS;AAAA,gBACxB,aAAa;AAAA,cACf;AAAA,cACA,sBAAsB;AAAA,gBACpB,MAAM;AAAA,gBACN,OAAO,EAAE,MAAM,SAAS;AAAA,cAC1B;AAAA,cACA,cAAc;AAAA,gBACZ,MAAM;AAAA,gBACN,aAAa;AAAA,gBACb,OAAO;AAAA,kBACL,MAAM;AAAA,kBACN,YAAY;AAAA,oBACV,MAAM,EAAE,MAAM,UAAU,aAAa,4CAA4C;AAAA,oBACjF,KAAK,EAAE,MAAM,UAAU,aAAa,2EAAsE;AAAA,kBAC5G;AAAA,kBACA,UAAU,CAAC,QAAQ,KAAK;AAAA,gBAC1B;AAAA,cACF;AAAA,YACF;AAAA,YACA,UAAU,CAAC,SAAS;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AAAA,MACA,UAAU,CAAC,SAAS;AAAA,IACtB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,OAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO;AAAA,YACL,MAAM;AAAA,YACN,YAAY;AAAA,cACV,MAAM,EAAE,MAAM,UAAU,aAAa,iBAAiB;AAAA,cACtD,IAAI,EAAE,MAAM,UAAU,aAAa,iBAAiB;AAAA,cACpD,MAAM;AAAA,gBACJ,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,QAAQ;AAAA,gBACN,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,YACF;AAAA,YACA,UAAU,CAAC,QAAQ,MAAM,MAAM;AAAA,UACjC;AAAA,QACF;AAAA,MACF;AAAA,MACA,UAAU,CAAC,OAAO;AAAA,IACpB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS,EAAE,MAAM,UAAU,aAAa,kDAAkD;AAAA,QAC1F,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,YAAY;AAAA,YACV,UAAU,EAAE,MAAM,UAAU;AAAA,YAC5B,YAAY,EAAE,MAAM,SAAS;AAAA,YAC7B,MAAM,EAAE,MAAM,UAAU,aAAa,6BAA6B;AAAA,YAClE,UAAU;AAAA,cACR,MAAM;AAAA,cACN,aAAa;AAAA,YACf;AAAA,YACA,mBAAmB,EAAE,MAAM,SAAS;AAAA,YACpC,SAAS,EAAE,MAAM,UAAU;AAAA,YAC3B,eAAe,EAAE,MAAM,UAAU;AAAA,YACjC,YAAY,EAAE,MAAM,UAAU;AAAA,YAC9B,YAAY;AAAA,cACV,MAAM,CAAC,UAAU,MAAM;AAAA,cACvB,aAAa;AAAA,YACf;AAAA,UACF;AAAA,QACF;AAAA,QACA,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,MAAM,CAAC,aAAa,SAAS,UAAU,SAAS;AAAA,QAClD;AAAA,QACA,OAAO,EAAE,MAAM,UAAU,aAAa,oCAAoC;AAAA,QAC1E,QAAQ,EAAE,MAAM,UAAU,aAAa,oBAAoB;AAAA,MAC7D;AAAA,MACA,UAAU,CAAC,SAAS;AAAA,IACtB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,YAAY;AAAA,UACV,MAAM;AAAA,UACN,OAAO;AAAA,YACL,MAAM;AAAA,YACN,YAAY;AAAA,cACV,IAAI;AAAA,gBACF,MAAM;AAAA,gBACN,MAAM,CAAC,QAAQ,SAAS,MAAM;AAAA,cAChC;AAAA,cACA,SAAS,EAAE,MAAM,UAAU,aAAa,oBAAoB;AAAA,cAC5D,YAAY,EAAE,MAAM,UAAU,aAAa,WAAW;AAAA,cACtD,QAAQ,EAAE,MAAM,UAAU,aAAa,4BAA4B;AAAA,cACnE,QAAQ;AAAA,gBACN,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,QAAQ,EAAE,MAAM,UAAU,aAAa,gBAAgB;AAAA,YACzD;AAAA,YACA,UAAU,CAAC,IAAI;AAAA,UACjB;AAAA,QACF;AAAA,MACF;AAAA,MACA,UAAU,CAAC,YAAY;AAAA,IACzB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS,EAAE,MAAM,SAAS;AAAA,QAC1B,OAAO,EAAE,MAAM,UAAU,aAAa,0BAA0B;AAAA,QAChE,QAAQ,EAAE,MAAM,UAAU,aAAa,oBAAoB;AAAA,MAC7D;AAAA,MACA,UAAU,CAAC,SAAS;AAAA,IACtB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS,EAAE,MAAM,UAAU,aAAa,kGAAkG;AAAA,QAC1I,gBAAgB;AAAA,UACd,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS,EAAE,MAAM,UAAU,aAAa,mCAAmC;AAAA,QAC3E,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,SAAS;AAAA,IACtB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS,EAAE,MAAM,UAAU,aAAa,eAAe;AAAA,QACvD,KAAK,EAAE,MAAM,UAAU,aAAa,wEAAwE;AAAA,QAC5G,SAAS,EAAE,MAAM,UAAU,aAAa,yBAAyB;AAAA,MACnE;AAAA,MACA,UAAU,CAAC,WAAW,OAAO,SAAS;AAAA,IACxC;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS,EAAE,MAAM,UAAU,aAAa,eAAe;AAAA,QACvD,KAAK,EAAE,MAAM,UAAU,aAAa,yCAAyC;AAAA,MAC/E;AAAA,MACA,UAAU,CAAC,SAAS;AAAA,IACtB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS,EAAE,MAAM,UAAU,aAAa,eAAe;AAAA,QACvD,KAAK,EAAE,MAAM,UAAU,aAAa,gCAAgC;AAAA,MACtE;AAAA,MACA,UAAU,CAAC,WAAW,KAAK;AAAA,IAC7B;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS,EAAE,MAAM,UAAU,aAAa,eAAe;AAAA,QACvD,OAAO,EAAE,MAAM,UAAU,aAAa,gBAAgB;AAAA,MACxD;AAAA,MACA,UAAU,CAAC,WAAW,OAAO;AAAA,IAC/B;AAAA,EACF;AACF;AAEA,eAAsB,cAA6B;AAEjD,YAAU,OAAO;AAGjB,QAAM,OAAa,eAAe,OAAO;AAEzC,QAAM,SAAS,IAAI;AAAA,IACjB,EAAE,MAAM,SAAS,SAAS,YAAY;AAAA,IACtC,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,EAAE;AAAA,EAChC;AAGA,iBAAe;AAGf,SAAO,kBAAkB,wBAAwB,aAAa;AAAA,IAC5D,OAAO;AAAA,EACT,EAAE;AAGF,SAAO,kBAAkB,uBAAuB,OAAO,YAAY;AACjE,UAAM,EAAE,MAAM,WAAW,KAAK,IAAI,QAAQ;AAE1C,QAAI;AACF,UAAI;AAEJ,cAAQ,MAAM;AAAA,QACZ,KAAK,cAAc;AACjB,gBAAM,WAAW;AAEjB,cAAI,UAAU,SAAS;AACrB,kBAAM,EAAE,gBAAAC,gBAAe,IAAI,MAAM,OAAO,qBAAY;AACpD,gBAAI,CAACA,gBAAe,SAAS,OAAO,GAAG;AACrC,gCAAkB,IAAI;AAAA,YACxB;AAAA,UACF;AACA,mBAAS,WAAW,UAAU,cAAc;AAC5C;AAAA,QACF;AAAA,QAEA,KAAK,cAAc;AACjB,gBAAM,WAAW;AAEjB,cAAI,UAAU,OAAO,SAAS,GAAG;AAE/B,kBAAM,EAAE,SAAAC,SAAQ,IAAI,MAAM,OAAO,qBAAY;AAC7C,kBAAM,cAAc,SAAS,MAAM,CAAC,GAAG;AACvC,gBAAI,eAAe,OAAO,gBAAgB,YAAY,CAAC,SAAS,MAAM,KAAK,CAAC,MAAW,EAAE,QAAQ,WAAW,GAAG;AAC7G,oBAAM,aAAaA,SAAQ,WAAW;AACtC,kBAAI,YAAY;AACd,+BAAe,MAAM,WAAW,SAAS,SAAS,MAAM,MAAM;AAAA,cAChE;AAAA,YACF;AAAA,UACF;AACA,mBAAS,WAAW,UAAU,cAAc;AAC5C;AAAA,QACF;AAAA,QAEA,KAAK,cAAc;AACjB,gBAAM,WAAW;AAEjB,cAAI,UAAU,OAAO;AACnB,qBAAS,QAAQ,WAAW,MAAM,SAAS,KAAK;AAAA,UAClD;AACA,mBAAS,WAAW,UAAU,gBAAgB,SAAS;AACvD;AAAA,QACF;AAAA,QAEA,KAAK;AACH,mBAAS,cAAc,IAAW;AAClC;AAAA,QAEF,KAAK;AACH,mBAAS,aAAa,MAAa,cAAc;AACjD;AAAA,QAEF,KAAK;AACH,mBAAS,cAAc,MAAa,cAAc;AAClD;AAAA,QAEF,KAAK;AACH,mBAAS,YAAY,IAAW;AAChC;AAAA,QAEF,KAAK;AACH,mBAAS,kBAAkB,MAAa,cAAc;AACtD;AAAA,QAEF,KAAK;AACH,mBAAS,cAAc,IAAW;AAClC;AAAA,QAEF,KAAK,iBAAiB;AACpB,gBAAM,cAAc;AAEpB,sBAAY,iBAAiB,iBAAiB,MAAM,aAAa,cAAc;AAC/E,mBAAS,cAAc,WAAW;AAClC;AAAA,QACF;AAAA,QAEA,KAAK;AACH,mBAAS,WAAW,IAAW;AAC/B;AAAA,QAEF,KAAK;AACH,mBAAS,kBAAkB;AAC3B;AAAA,QAEF,KAAK;AACH,6BAAmB,IAAI;AACvB,mBAAS,qBAAqB,MAAa,cAAc;AACzD;AAAA,QAEF,KAAK;AACH,6BAAmB,IAAI;AACvB,mBAAS,oBAAoB,IAAW;AACxC;AAAA,QAEF,KAAK;AACH,6BAAmB,IAAI;AACvB,mBAAS,sBAAsB,IAAW;AAC1C;AAAA,QAEF,KAAK;AACH,6BAAmB,IAAI;AACvB,mBAAS,sBAAsB,IAAW;AAC1C;AAAA,QAEF;AACE,iBAAO;AAAA,YACL,SAAS;AAAA,cACP,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,EAAE,OAAO,iBAAiB,IAAI,GAAG,CAAC,EAAE;AAAA,YACpF;AAAA,YACA,SAAS;AAAA,UACX;AAAA,MACJ;AAEA,YAAM,UAAiD;AAAA,QACrD,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE;AAAA,MACjE;AACA,UAAI,eAAe;AACjB,gBAAQ,KAAK,EAAE,MAAM,QAAiB,MAAM,gBAAgB,GAAG,aAAa,WAAM,aAAa,KAAK,cAAc,CAAC;AACnH,wBAAgB;AAChB,wBAAgB;AAAA,MAClB;AACA,aAAO,EAAE,QAAQ;AAAA,IACnB,SAAS,OAAO;AACd,YAAM,UACJ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACvD,YAAM,OACJ,iBAAiB,kBACb,qBACA,iBAAiB,cACd,MAAsB,OACvB;AACR,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM,KAAK,UAAU,EAAE,OAAO,SAAS,KAAK,CAAC;AAAA,UAC/C;AAAA,QACF;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF,CAAC;AAGD,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAG9B,QAAM,qBAAqB,YAAY,MAAM;AAC3C,QAAI;AAAE,mBAAa;AAAA,IAAG,QAAQ;AAAA,IAAC;AAAA,EACjC,GAAG,GAAM;AAGT,UAAQ,GAAG,UAAU,MAAM;AACzB,kBAAc,kBAAkB;AAChC,YAAQ;AACR,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AACD,UAAQ,GAAG,WAAW,MAAM;AAC1B,kBAAc,kBAAkB;AAChC,YAAQ;AACR,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AACH;","names":["rows","result","nanoid","nanoid","getProjectRoot","getNode"]}
|