@graph-tl/graph 0.1.4 → 0.1.6
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-JYP72OZQ.js");
|
|
10
10
|
init();
|
|
11
11
|
} else {
|
|
12
|
-
const { startServer } = await import("./server-
|
|
12
|
+
const { startServer } = await import("./server-6MALRQNH.js");
|
|
13
13
|
startServer().catch((error) => {
|
|
14
14
|
console.error("Failed to start graph:", error);
|
|
15
15
|
process.exit(1);
|
|
@@ -1170,9 +1170,10 @@ function checkScope(tier, scope) {
|
|
|
1170
1170
|
|
|
1171
1171
|
// src/server.ts
|
|
1172
1172
|
import { createHash } from "crypto";
|
|
1173
|
-
import { mkdirSync } from "fs";
|
|
1173
|
+
import { mkdirSync, readFileSync } from "fs";
|
|
1174
1174
|
import { homedir } from "os";
|
|
1175
|
-
import { join, resolve } from "path";
|
|
1175
|
+
import { join, resolve, dirname } from "path";
|
|
1176
|
+
import { fileURLToPath } from "url";
|
|
1176
1177
|
var AGENT_IDENTITY = process.env.GRAPH_AGENT ?? "default-agent";
|
|
1177
1178
|
var CLAIM_TTL = parseInt(process.env.GRAPH_CLAIM_TTL ?? "60", 10);
|
|
1178
1179
|
function defaultDbPath() {
|
|
@@ -1183,6 +1184,27 @@ function defaultDbPath() {
|
|
|
1183
1184
|
return join(dir, "graph.db");
|
|
1184
1185
|
}
|
|
1185
1186
|
var DB_PATH = process.env.GRAPH_DB ?? defaultDbPath();
|
|
1187
|
+
var PKG_NAME = "@graph-tl/graph";
|
|
1188
|
+
var PKG_VERSION = "0.0.0";
|
|
1189
|
+
try {
|
|
1190
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
1191
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
|
|
1192
|
+
PKG_VERSION = pkg.version;
|
|
1193
|
+
} catch {
|
|
1194
|
+
}
|
|
1195
|
+
var versionBanner = `[graph] v${PKG_VERSION}`;
|
|
1196
|
+
var updateWarning = null;
|
|
1197
|
+
async function checkForUpdate() {
|
|
1198
|
+
try {
|
|
1199
|
+
const res = await fetch(`https://registry.npmjs.org/${PKG_NAME}/latest`);
|
|
1200
|
+
if (!res.ok) return;
|
|
1201
|
+
const data = await res.json();
|
|
1202
|
+
if (data.version !== PKG_VERSION) {
|
|
1203
|
+
updateWarning = `[graph] Update available: ${PKG_VERSION} \u2192 ${data.version}. Run: npx clear-npx-cache && restart MCP server.`;
|
|
1204
|
+
}
|
|
1205
|
+
} catch {
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1186
1208
|
var TOOLS = [
|
|
1187
1209
|
{
|
|
1188
1210
|
name: "graph_open",
|
|
@@ -1521,9 +1543,10 @@ async function startServer() {
|
|
|
1521
1543
|
setDbPath(DB_PATH);
|
|
1522
1544
|
const tier = getLicenseTier(DB_PATH);
|
|
1523
1545
|
const server = new Server(
|
|
1524
|
-
{ name: "graph", version:
|
|
1546
|
+
{ name: "graph", version: PKG_VERSION },
|
|
1525
1547
|
{ capabilities: { tools: {} } }
|
|
1526
1548
|
);
|
|
1549
|
+
checkForUpdate();
|
|
1527
1550
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
1528
1551
|
tools: TOOLS
|
|
1529
1552
|
}));
|
|
@@ -1613,9 +1636,15 @@ async function startServer() {
|
|
|
1613
1636
|
isError: true
|
|
1614
1637
|
};
|
|
1615
1638
|
}
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1639
|
+
const content = [
|
|
1640
|
+
{ type: "text", text: JSON.stringify(result, null, 2) }
|
|
1641
|
+
];
|
|
1642
|
+
if (versionBanner) {
|
|
1643
|
+
content.push({ type: "text", text: updateWarning ? `${versionBanner} \u2014 ${updateWarning}` : versionBanner });
|
|
1644
|
+
versionBanner = null;
|
|
1645
|
+
updateWarning = null;
|
|
1646
|
+
}
|
|
1647
|
+
return { content };
|
|
1619
1648
|
} catch (error) {
|
|
1620
1649
|
const message = error instanceof Error ? error.message : String(error);
|
|
1621
1650
|
const code = error instanceof ValidationError ? "validation_error" : error instanceof EngineError ? error.code : "error";
|
|
@@ -1652,4 +1681,4 @@ async function startServer() {
|
|
|
1652
1681
|
export {
|
|
1653
1682
|
startServer
|
|
1654
1683
|
};
|
|
1655
|
-
//# sourceMappingURL=server-
|
|
1684
|
+
//# sourceMappingURL=server-6MALRQNH.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/agent-config.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 { handleKnowledgeWrite, handleKnowledgeRead, handleKnowledgeDelete, handleKnowledgeSearch } from \"./tools/knowledge.js\";\nimport { getLicenseTier, type Tier } from \"./license.js\";\nimport { checkNodeLimit, checkProjectLimit, capEvidenceLimit, checkScope } 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 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')\" },\n evidence_limit: {\n type: \"number\",\n description: \"Max evidence entries to return (default 20, max 50)\",\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. Pro tier only. 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_agent_config\":\n result = handleAgentConfig(DB_PATH);\n break;\n\n case \"graph_knowledge_write\":\n result = handleKnowledgeWrite(args as any, AGENT_IDENTITY);\n break;\n\n case \"graph_knowledge_read\":\n result = handleKnowledgeRead(args as any);\n break;\n\n case \"graph_knowledge_delete\":\n result = handleKnowledgeDelete(args as any);\n break;\n\n case \"graph_knowledge_search\":\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 };\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\n if (!root) {\n root = createNode({\n project,\n summary: goal ?? project,\n agent,\n });\n }\n\n const summary = getProjectSummary(project);\n\n return { project, root, summary };\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 } 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 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 } 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 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}\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 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 const result: UpdateResult = { updated };\n\n if (resolvedIds.length > 0 && project) {\n result.newly_actionable = findNewlyActionable(project, resolvedIds);\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 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 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 } from \"../nodes.js\";\nimport { requireString, 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 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 actionable: Array<{\n id: string;\n summary: string;\n properties: Record<string, unknown>;\n }>;\n}\n\nexport function handleOnboard(input: OnboardInput): OnboardResult {\n const project = requireString(input?.project, \"project\");\n const evidenceLimit = optionalNumber(input?.evidence_limit, \"evidence_limit\", 1, 50) ?? 20;\n const db = getDb();\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 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. 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 return {\n project,\n summary,\n tree,\n recent_evidence,\n context_links,\n actionable,\n };\n}\n","import { getLicenseTier } from \"../license.js\";\nimport { EngineError } from \"../validate.js\";\n\n// [sl:fV9I7Vel3xT5d_Ws2YHul] Subagent delivery — pro tier returns agent config\n\nconst AGENT_PROMPT = `---\nname: graph\ndescription: Use this agent for tasks tracked in Graph. Enforces the claim-work-resolve workflow — always checks graph_next before working, adds new work to the graph before executing, and resolves with evidence.\ntools: Read, Edit, Write, Bash, Glob, Grep, Task(Explore)\nmodel: sonnet\n---\n\nYou are a graph-optimized agent. You execute tasks tracked in a Graph project. Follow this workflow strictly. The human directs, you execute through the graph.\n\n# Workflow\n\n## 1. ORIENT\nOn your first call, orient yourself:\n\\`\\`\\`\ngraph_onboard({ project: \"<project-name>\" })\n\\`\\`\\`\nRead the summary, recent evidence, context links, and actionable tasks. Understand what was done and what's left.\n\n## 2. CLAIM\nGet your next task:\n\\`\\`\\`\ngraph_next({ project: \"<project-name>\", claim: true })\n\\`\\`\\`\nRead the task summary, ancestor chain (for scope), resolved dependencies (for context on what was done before you), and context links (for files to look at).\n\n## 3. PLAN\nIf you discover work that isn't in the graph, add it BEFORE executing:\n\\`\\`\\`\ngraph_plan({ nodes: [{ ref: \"new-work\", parent_ref: \"<parent-id>\", summary: \"...\" }] })\n\\`\\`\\`\nNever execute ad-hoc work. The graph is the source of truth.\n\nWhen decomposing work:\n- Set dependencies on LEAF nodes, not parent nodes. If \"Page A\" depends on \"Layout\", the dependency is from \"Page A\" to \"Layout\", not from the \"Pages\" parent to \"Layout\".\n- Keep tasks small and specific. A task should be completable in one session.\n- Parent nodes are organizational — they resolve when all children resolve. Don't put work in parent nodes.\n\n## 4. WORK\nExecute the claimed task. While working:\n- Annotate key code changes with \\`// [sl:nodeId]\\` where nodeId is the task you're working on\n- This creates a traceable link from code back to the task, its evidence, and its history\n- Build and run tests before considering a task done\n\n## 5. RESOLVE\nWhen done, resolve the task with evidence:\n\\`\\`\\`\ngraph_update({ updates: [{\n node_id: \"<task-id>\",\n resolved: true,\n add_evidence: [\n { type: \"note\", ref: \"What you did and why\" },\n { type: \"git\", ref: \"<commit-hash> — <summary>\" },\n { type: \"test\", ref: \"Test results\" }\n ],\n add_context_links: [\"path/to/files/you/touched\"]\n}] })\n\\`\\`\\`\nEvidence is mandatory. At minimum, include one note explaining what you did.\n\n## 6. PAUSE\nAfter resolving a task, STOP. Tell the user:\n- What you just completed\n- What the next actionable task is\n- Wait for the user to say \"continue\" before claiming the next task\n\nThe user controls the pace. Do not auto-claim the next task.\n\n# Rules\n\n- NEVER start work without a claimed task\n- NEVER resolve without evidence\n- NEVER execute ad-hoc work — add it to the graph first via graph_plan\n- NEVER auto-continue to the next task — pause and let the user decide\n- ALWAYS build and test before resolving\n- ALWAYS include context_links for files you modified when resolving\n- If a parent task becomes actionable (all children resolved), resolve it with a summary of what its children accomplished\n- If you're approaching context limits, ensure your current task's state is captured (update with evidence even if not fully resolved) so the next agent can pick up where you left off\n\n# Common mistakes to avoid\n\n- Setting dependencies on parent nodes instead of leaf nodes\n- Running project scaffolding tools (create-next-app, etc.) before planning in the graph\n- Resolving tasks without running tests\n- Doing work that isn't tracked in the graph\n- Continuing to the next task without pausing for user review\n`;\n\nexport interface AgentConfigResult {\n agent_file: string;\n install_path: string;\n instructions: string;\n}\n\nexport function handleAgentConfig(dbPath?: string): AgentConfigResult {\n const tier = getLicenseTier(dbPath);\n\n if (tier !== \"pro\") {\n throw new EngineError(\n \"free_tier_limit\",\n \"The graph-optimized agent configuration is a pro feature. Activate a license key to unlock it.\"\n );\n }\n\n return {\n agent_file: AGENT_PROMPT,\n install_path: \".claude/agents/graph.md\",\n instructions:\n \"Save the agent_file content to .claude/agents/graph.md in your project root. \" +\n \"Claude Code will automatically discover it and use it when tasks match the agent description.\",\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\nconst FREE_LIMITS = {\n maxProjects: 1,\n maxNodesPerProject: 50,\n onboardEvidenceLimit: 5,\n scopeEnabled: false,\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 scope parameter is allowed on free tier.\n * Returns undefined (stripped) if not allowed.\n */\nexport function checkScope(tier: Tier, scope?: string): string | undefined {\n if (tier === \"pro\") return scope;\n return undefined; // silently ignore scope on free tier\n}\n"],"mappings":"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","names":["rows","result","nanoid","nanoid","getProjectRoot","getNode"]}
|
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/agent-config.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 { handleKnowledgeWrite, handleKnowledgeRead, handleKnowledgeDelete, handleKnowledgeSearch } from \"./tools/knowledge.js\";\nimport { getLicenseTier, type Tier } from \"./license.js\";\nimport { checkNodeLimit, checkProjectLimit, capEvidenceLimit, checkScope } from \"./gates.js\";\n\nimport { createHash } from \"crypto\";\nimport { mkdirSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { join, resolve } from \"path\";\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// 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 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')\" },\n evidence_limit: {\n type: \"number\",\n description: \"Max evidence entries to return (default 20, max 50)\",\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. Pro tier only. 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: \"0.1.0\" },\n { capabilities: { tools: {} } }\n );\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_agent_config\":\n result = handleAgentConfig(DB_PATH);\n break;\n\n case \"graph_knowledge_write\":\n result = handleKnowledgeWrite(args as any, AGENT_IDENTITY);\n break;\n\n case \"graph_knowledge_read\":\n result = handleKnowledgeRead(args as any);\n break;\n\n case \"graph_knowledge_delete\":\n result = handleKnowledgeDelete(args as any);\n break;\n\n case \"graph_knowledge_search\":\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 return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n };\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 };\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\n if (!root) {\n root = createNode({\n project,\n summary: goal ?? project,\n agent,\n });\n }\n\n const summary = getProjectSummary(project);\n\n return { project, root, summary };\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 } 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 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 } 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 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}\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 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 const result: UpdateResult = { updated };\n\n if (resolvedIds.length > 0 && project) {\n result.newly_actionable = findNewlyActionable(project, resolvedIds);\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 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 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 } from \"../nodes.js\";\nimport { requireString, 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 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 actionable: Array<{\n id: string;\n summary: string;\n properties: Record<string, unknown>;\n }>;\n}\n\nexport function handleOnboard(input: OnboardInput): OnboardResult {\n const project = requireString(input?.project, \"project\");\n const evidenceLimit = optionalNumber(input?.evidence_limit, \"evidence_limit\", 1, 50) ?? 20;\n const db = getDb();\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 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. 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 return {\n project,\n summary,\n tree,\n recent_evidence,\n context_links,\n actionable,\n };\n}\n","import { getLicenseTier } from \"../license.js\";\nimport { EngineError } from \"../validate.js\";\n\n// [sl:fV9I7Vel3xT5d_Ws2YHul] Subagent delivery — pro tier returns agent config\n\nconst AGENT_PROMPT = `---\nname: graph\ndescription: Use this agent for tasks tracked in Graph. Enforces the claim-work-resolve workflow — always checks graph_next before working, adds new work to the graph before executing, and resolves with evidence.\ntools: Read, Edit, Write, Bash, Glob, Grep, Task(Explore)\nmodel: sonnet\n---\n\nYou are a graph-optimized agent. You execute tasks tracked in a Graph project. Follow this workflow strictly. The human directs, you execute through the graph.\n\n# Workflow\n\n## 1. ORIENT\nOn your first call, orient yourself:\n\\`\\`\\`\ngraph_onboard({ project: \"<project-name>\" })\n\\`\\`\\`\nRead the summary, recent evidence, context links, and actionable tasks. Understand what was done and what's left.\n\n## 2. CLAIM\nGet your next task:\n\\`\\`\\`\ngraph_next({ project: \"<project-name>\", claim: true })\n\\`\\`\\`\nRead the task summary, ancestor chain (for scope), resolved dependencies (for context on what was done before you), and context links (for files to look at).\n\n## 3. PLAN\nIf you discover work that isn't in the graph, add it BEFORE executing:\n\\`\\`\\`\ngraph_plan({ nodes: [{ ref: \"new-work\", parent_ref: \"<parent-id>\", summary: \"...\" }] })\n\\`\\`\\`\nNever execute ad-hoc work. The graph is the source of truth.\n\nWhen decomposing work:\n- Set dependencies on LEAF nodes, not parent nodes. If \"Page A\" depends on \"Layout\", the dependency is from \"Page A\" to \"Layout\", not from the \"Pages\" parent to \"Layout\".\n- Keep tasks small and specific. A task should be completable in one session.\n- Parent nodes are organizational — they resolve when all children resolve. Don't put work in parent nodes.\n\n## 4. WORK\nExecute the claimed task. While working:\n- Annotate key code changes with \\`// [sl:nodeId]\\` where nodeId is the task you're working on\n- This creates a traceable link from code back to the task, its evidence, and its history\n- Build and run tests before considering a task done\n\n## 5. RESOLVE\nWhen done, resolve the task with evidence:\n\\`\\`\\`\ngraph_update({ updates: [{\n node_id: \"<task-id>\",\n resolved: true,\n add_evidence: [\n { type: \"note\", ref: \"What you did and why\" },\n { type: \"git\", ref: \"<commit-hash> — <summary>\" },\n { type: \"test\", ref: \"Test results\" }\n ],\n add_context_links: [\"path/to/files/you/touched\"]\n}] })\n\\`\\`\\`\nEvidence is mandatory. At minimum, include one note explaining what you did.\n\n## 6. PAUSE\nAfter resolving a task, STOP. Tell the user:\n- What you just completed\n- What the next actionable task is\n- Wait for the user to say \"continue\" before claiming the next task\n\nThe user controls the pace. Do not auto-claim the next task.\n\n# Rules\n\n- NEVER start work without a claimed task\n- NEVER resolve without evidence\n- NEVER execute ad-hoc work — add it to the graph first via graph_plan\n- NEVER auto-continue to the next task — pause and let the user decide\n- ALWAYS build and test before resolving\n- ALWAYS include context_links for files you modified when resolving\n- If a parent task becomes actionable (all children resolved), resolve it with a summary of what its children accomplished\n- If you're approaching context limits, ensure your current task's state is captured (update with evidence even if not fully resolved) so the next agent can pick up where you left off\n\n# Common mistakes to avoid\n\n- Setting dependencies on parent nodes instead of leaf nodes\n- Running project scaffolding tools (create-next-app, etc.) before planning in the graph\n- Resolving tasks without running tests\n- Doing work that isn't tracked in the graph\n- Continuing to the next task without pausing for user review\n`;\n\nexport interface AgentConfigResult {\n agent_file: string;\n install_path: string;\n instructions: string;\n}\n\nexport function handleAgentConfig(dbPath?: string): AgentConfigResult {\n const tier = getLicenseTier(dbPath);\n\n if (tier !== \"pro\") {\n throw new EngineError(\n \"free_tier_limit\",\n \"The graph-optimized agent configuration is a pro feature. Activate a license key to unlock it.\"\n );\n }\n\n return {\n agent_file: AGENT_PROMPT,\n install_path: \".claude/agents/graph.md\",\n instructions:\n \"Save the agent_file content to .claude/agents/graph.md in your project root. \" +\n \"Claude Code will automatically discover it and use it when tasks match the agent description.\",\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\nconst FREE_LIMITS = {\n maxProjects: 1,\n maxNodesPerProject: 50,\n onboardEvidenceLimit: 5,\n scopeEnabled: false,\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 scope parameter is allowed on free tier.\n * Returns undefined (stripped) if not allowed.\n */\nexport function checkScope(tier: Tier, scope?: string): string | undefined {\n if (tier === \"pro\") return scope;\n return undefined; // silently ignore scope on free tier\n}\n"],"mappings":"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","names":["rows","result","nanoid","nanoid","getProjectRoot","getNode"]}
|