@minhpnq1807/contextos 0.5.34 → 0.5.36

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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.36
4
+
5
+ - **Fix ctx_score_context MCP output not rendering in Antigravity editor:** The `content` text block returned by the MCP tool previously only contained raw telemetry JSON, which editors cannot render as user-facing context. Now the tool uses `scheduleContext()` to produce the same human-readable markdown (Critical ContextOS rules, Suggested files, Skills, Workflows) that the hook path generates, and returns it as the primary `content[0].text` block. Telemetry JSON is pushed to a secondary content block. This ensures Antigravity (and any MCP-compatible editor) displays the scored rules and file suggestions.
6
+ - **Fix symlink incompatibility with antigravity-awesome-skills:** `copyDirectory` in `skillshare-sync.js` was preserving symlinks when copying skills, which caused `antigravity-awesome-skills` to crash with "Skipping unsafe destination symlink" on re-install. Now follows symlinks and copies actual file content instead, making output compatible with all tools that write to the same skills directory.
7
+ - **Updated MCP protocol smoke test:** Assertions now validate the two-block content structure — human-readable context first, telemetry JSON last.
8
+
9
+ ## 0.5.35
10
+
11
+ - **Add GitHub Copilot agent support:** New `copilot` agent for `ctx install --agent copilot` and `ctx setup`. Creates `.github/copilot-instructions.md` with ContextOS integration marker and configures `ctx-mcp` MCP server in `.vscode/mcp.json`. Copilot is now recognized by Ruler (`ctx sync --rules`) and Skillshare (`ctx sync --skills`) alongside existing codex, claude, and agy agents.
12
+ - **Agent selection defaults to none:** `ctx setup` and `ctx install` no longer pre-select all agents. Users must explicitly choose which agents to install via the interactive multiSelect prompt or `--agents` flag. This prevents accidental installation of unwanted agent hooks.
13
+ - **copilot-hooks.js:** Writes a managed `copilot-instructions.md` file under `.github/`, appending to existing content if present. Uses a marker comment (`<!-- managed by ContextOS -->`) to avoid duplicate sections.
14
+ - **copilot-mcp.js:** Configures `ctx-mcp` server in `.vscode/mcp.json` using the same pattern as existing claude/antigravity MCP modules.
15
+
3
16
  ## 0.5.34
4
17
 
5
18
  - **Real-time streaming output during install/setup:** Replaced `captureSetupOutput` (buffered) with `streamSetupOutput` — now prints each line immediately with `│ ` prefix as it arrives, eliminating the perceived "hang" during long-running downloads and installs.
package/bin/ctx.js CHANGED
@@ -24,6 +24,8 @@ import { installClaudeHooks } from "../plugins/ctx/lib/claude-hooks.js";
24
24
  import { installClaudeMcp } from "../plugins/ctx/lib/claude-mcp.js";
25
25
  import { installAntigravityHooks } from "../plugins/ctx/lib/antigravity-hooks.js";
26
26
  import { installAntigravityMcp } from "../plugins/ctx/lib/antigravity-mcp.js";
27
+ import { installCopilotHooks } from "../plugins/ctx/lib/copilot-hooks.js";
28
+ import { installCopilotMcp } from "../plugins/ctx/lib/copilot-mcp.js";
27
29
  import { syncRules } from "../plugins/ctx/lib/ruler-sync.js";
28
30
  import { writeInnerGitignore, ensureRootGitignore } from "../plugins/ctx/lib/gitignore.js";
29
31
  import { syncSkills } from "../plugins/ctx/lib/skillshare-sync.js";
@@ -42,11 +44,11 @@ function usage() {
42
44
 
43
45
  Usage:
44
46
  ctx install Interactive multi-select agent installer
45
- ctx install --agent <name> Install a specific agent (codex|claude|agy)
47
+ ctx install --agent <name> Install a specific agent (codex|claude|agy|copilot)
46
48
  ctx install --copy Legacy: copy plugin folder only (no hooks/mcp)
47
49
  ctx setup Interactive full setup wizard
48
50
  ctx setup --yes Auto-confirm all setup prompts
49
- ctx setup --agents codex,claude,agy Pre-select agents to install
51
+ ctx setup --agents codex,claude,agy,copilot Pre-select agents to install
50
52
  ctx setup --no-rules Skip AGENTS.md rule sync
51
53
  ctx setup --no-skills Skip skill sync
52
54
  ctx setup --quiet Quiet mode (minimal output)
@@ -56,17 +58,17 @@ Usage:
56
58
  ctx stats Show workspace statistics
57
59
  ctx benchmark -- "task" Benchmark workspace for a task
58
60
  ctx sync --rules Sync AGENTS.md rules to all agents
59
- ctx sync --rules --agents codex,claude,agy Sync rules to specific agents only
61
+ ctx sync --rules --agents codex,claude,agy,copilot Sync rules to specific agents only
60
62
  ctx sync --rules --dry-run Preview rule sync without writing
61
63
  ctx sync --rules --no-import-codex-mcp Skip importing Codex MCP servers
62
64
  ctx sync --skills Sync skills across agents
63
- ctx sync --skills --agents codex,claude,agy Sync skills to specific agents only
65
+ ctx sync --skills --agents codex,claude,agy,copilot Sync skills to specific agents only
64
66
  ctx sync --skills --dry-run Preview skill sync without writing
65
67
  ctx sync --skills --no-collect Skip collecting new skills
66
68
  ctx sync --skills --no-embeddings Skip embedding generation
67
69
  ctx sync --skills --verbose Verbose skill sync output
68
70
  ctx sync --workflows Sync workflows across agents
69
- ctx sync --workflows --agents codex,claude,agy Sync workflows to specific agents
71
+ ctx sync --workflows --agents codex,claude,agy,copilot Sync workflows to specific agents
70
72
  ctx sync --workflows --dry-run Preview workflow sync without writing
71
73
  ctx embeddings warm -- "task" Pre-warm embedding caches for a task
72
74
  ctx ruler -- <ruler args> Passthrough to ruler CLI
@@ -76,9 +78,10 @@ Usage:
76
78
  }
77
79
 
78
80
  const SUPPORTED_AGENTS = [
79
- { label: "Codex", value: "codex", selected: true },
80
- { label: "Claude Code", value: "claude", selected: true },
81
- { label: "Antigravity (agy)", value: "agy", selected: true }
81
+ { label: "Codex", value: "codex", selected: false },
82
+ { label: "Claude Code", value: "claude", selected: false },
83
+ { label: "Antigravity (agy)", value: "agy", selected: false },
84
+ { label: "GitHub Copilot", value: "copilot", selected: false }
82
85
  ];
83
86
 
84
87
  function normalizeInstallAgent(agent) {
@@ -90,8 +93,9 @@ function normalizeInstallAgent(agent) {
90
93
  " ctx install --agent codex",
91
94
  " ctx install --agent claude",
92
95
  " ctx install --agent agy",
96
+ " ctx install --agent copilot",
93
97
  "",
94
- "Do not run `ctx install --agent codex|claude|agy`: `|` is a shell pipe."
98
+ "Do not run `ctx install --agent codex|claude|agy|copilot`: `|` is a shell pipe."
95
99
  ].join("\n"));
96
100
  }
97
101
  if (normalized === "antigravity") return "agy";
@@ -271,8 +275,35 @@ async function install({ copy = false, agent = "codex" } = {}) {
271
275
  return;
272
276
  }
273
277
 
278
+ if (agent === "copilot") {
279
+ progress.step(10, "copying package");
280
+ const installRoot = copyPackageRoot({ rootDir, targetRoot: agentInstallRoot("copilot") });
281
+ progress.step(25, "installing hooks");
282
+ const hooksPath = installCopilotHooks({ cwd: process.cwd(), installRoot });
283
+ progress.step(40, "installing mcp");
284
+ const mcpConfigPath = installCopilotMcp({ cwd: process.cwd(), installRoot });
285
+ progress.step(50, "configuring gitignore");
286
+ writeInnerGitignore(installRoot);
287
+ ensureRootGitignore(process.cwd());
288
+ progress.step(55, "warming embeddings");
289
+ const warmResult = await warmInstallEmbeddings();
290
+ progress.done("copilot installed");
291
+ console.log("Installed ctx hooks for GitHub Copilot.");
292
+ console.log(`Stable install root: ${installRoot}`);
293
+ console.log(`Installed ContextOS instructions to ${hooksPath}`);
294
+ console.log(`Installed ctx-mcp MCP server to ${mcpConfigPath}`);
295
+ console.log(`Embedding model cache: ${modelCacheDir(contextOSDataDir())}`);
296
+ console.log(`Embedding vectors cache: ${warmResult.cachePath}`);
297
+ console.log(`File path embeddings warmed: ${warmResult.fileCount || 0}`);
298
+ console.log(`Skill embeddings warmed: ${warmResult.skillCount || 0}`);
299
+ console.log(`Workflow embeddings warmed: ${warmResult.workflowCount || 0}`);
300
+ console.log(`Prompt context injection: ${inject ? "enabled" : "quiet logging only"}`);
301
+ console.log("Restart VS Code or Copilot if it was already running, then submit a task to trigger ContextOS.");
302
+ return;
303
+ }
304
+
274
305
  if (agent !== "codex") {
275
- throw new Error(`Unknown agent '${agent}'. Expected codex, claude, or agy.`);
306
+ throw new Error(`Unknown agent '${agent}'. Expected codex, claude, agy, or copilot.`);
276
307
  }
277
308
 
278
309
  progress.step(10, "copying marketplace");
@@ -547,9 +578,10 @@ async function setup({ args = [], cwd = process.cwd() } = {}) {
547
578
  const selected = await multiSelect({
548
579
  message: "Select agents to install:",
549
580
  options: [
550
- { label: "Codex", value: "codex", selected: options.agents.includes("codex") },
551
- { label: "Claude", value: "claude", selected: options.agents.includes("claude") },
552
- { label: "Antigravity (agy)", value: "agy", selected: options.agents.includes("agy") }
581
+ { label: "Codex", value: "codex", selected: options.agents.includes("codex") },
582
+ { label: "Claude", value: "claude", selected: options.agents.includes("claude") },
583
+ { label: "Antigravity (agy)", value: "agy", selected: options.agents.includes("agy") },
584
+ { label: "GitHub Copilot", value: "copilot", selected: options.agents.includes("copilot") }
553
585
  ]
554
586
  });
555
587
  options.agents = selected;
@@ -576,7 +608,7 @@ async function setup({ args = [], cwd = process.cwd() } = {}) {
576
608
  for (const line of setupSummaryLines({ cwd, ...options })) console.log(`│ ${line}`);
577
609
  console.log("");
578
610
 
579
- if (!options.agents.length) throw new Error("No agents selected. Use --agents codex,claude,agy.");
611
+ if (!options.agents.length) throw new Error("No agents selected. Use --agents codex,claude,agy,copilot.");
580
612
 
581
613
  for (const agent of options.agents) {
582
614
  console.log(`◇ Setting up ${agent}...`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minhpnq1807/contextos",
3
- "version": "0.5.34",
3
+ "version": "0.5.36",
4
4
  "description": "Task-aware AGENTS.md context injection and compliance reporting for Codex, Claude Code, and Antigravity.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ctx",
3
- "version": "0.5.34",
3
+ "version": "0.5.36",
4
4
  "description": "Inject task-relevant AGENTS.md rules into Codex through plugin hooks.",
5
5
  "author": {
6
6
  "name": "ContextOS"
@@ -0,0 +1,58 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+
4
+ /**
5
+ * Copilot reads instructions from:
6
+ * 1. .github/copilot-instructions.md (repo-level)
7
+ * 2. AGENTS.md files (nearest in directory tree)
8
+ *
9
+ * Since ContextOS already syncs AGENTS.md through Ruler,
10
+ * this module writes a copilot-instructions.md that signals
11
+ * ContextOS integration and points Copilot at the ctx-mcp MCP server.
12
+ */
13
+
14
+ const MARKER = "<!-- managed by ContextOS -->";
15
+
16
+ function buildCopilotInstructions({ installRoot } = {}) {
17
+ return [
18
+ MARKER,
19
+ "# ContextOS Integration",
20
+ "",
21
+ "This project uses [ContextOS](https://github.com/khovan123/contextOS) for task-aware context injection.",
22
+ "",
23
+ "## MCP Server",
24
+ "",
25
+ "The `ctx-mcp` MCP server is configured in `.vscode/mcp.json`.",
26
+ "It provides semantic file search, skill discovery, and rule scoring for this workspace.",
27
+ "",
28
+ "## Rules",
29
+ "",
30
+ "Project rules are defined in `AGENTS.md` files managed by Ruler.",
31
+ "These rules are automatically injected into your prompt context.",
32
+ ""
33
+ ].join("\n");
34
+ }
35
+
36
+ export function copilotInstructionsPath(cwd = process.cwd()) {
37
+ return path.join(cwd, ".github", "copilot-instructions.md");
38
+ }
39
+
40
+ export function installCopilotHooks({ cwd = process.cwd(), installRoot } = {}) {
41
+ const instructionsPath = copilotInstructionsPath(cwd);
42
+ const dir = path.dirname(instructionsPath);
43
+ fs.mkdirSync(dir, { recursive: true });
44
+
45
+ // If the file exists and wasn't created by us, don't overwrite
46
+ if (fs.existsSync(instructionsPath)) {
47
+ const existing = fs.readFileSync(instructionsPath, "utf8");
48
+ if (!existing.includes(MARKER)) {
49
+ // Append our section
50
+ const content = existing.trimEnd() + "\n\n" + buildCopilotInstructions({ installRoot });
51
+ fs.writeFileSync(instructionsPath, content, "utf8");
52
+ return instructionsPath;
53
+ }
54
+ }
55
+
56
+ fs.writeFileSync(instructionsPath, buildCopilotInstructions({ installRoot }), "utf8");
57
+ return instructionsPath;
58
+ }
@@ -0,0 +1,43 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+
4
+ /**
5
+ * Copilot MCP configuration lives at .vscode/mcp.json (workspace-level).
6
+ * This is the standard location for VS Code / GitHub Copilot agent mode.
7
+ */
8
+
9
+ function readJsonFile(filePath, fallback) {
10
+ if (!fs.existsSync(filePath)) return fallback;
11
+ const raw = fs.readFileSync(filePath, "utf8").trim();
12
+ if (!raw) return fallback;
13
+ try {
14
+ return JSON.parse(raw);
15
+ } catch {
16
+ console.warn(`[ctx] warning: corrupt JSON in ${filePath}, overwriting with defaults`);
17
+ return fallback;
18
+ }
19
+ }
20
+
21
+ export function copilotMcpConfigPath(cwd = process.cwd()) {
22
+ return path.join(cwd, ".vscode", "mcp.json");
23
+ }
24
+
25
+ export function buildCopilotMcpConfig(existingConfig, { installRoot } = {}) {
26
+ const config = existingConfig && typeof existingConfig === "object" ? structuredClone(existingConfig) : {};
27
+ if (!config.mcpServers || typeof config.mcpServers !== "object") config.mcpServers = {};
28
+ config.mcpServers["ctx-mcp"] = {
29
+ type: "stdio",
30
+ command: "node",
31
+ args: [path.join(installRoot, "plugins", "ctx", "mcp", "server.js")]
32
+ };
33
+ return config;
34
+ }
35
+
36
+ export function installCopilotMcp({ cwd = process.cwd(), configPath, installRoot } = {}) {
37
+ const mcpPath = configPath || copilotMcpConfigPath(cwd);
38
+ const existing = readJsonFile(mcpPath, {});
39
+ const next = buildCopilotMcpConfig(existing, { installRoot });
40
+ fs.mkdirSync(path.dirname(mcpPath), { recursive: true });
41
+ fs.writeFileSync(mcpPath, `${JSON.stringify(next, null, 2)}\n`, "utf8");
42
+ return mcpPath;
43
+ }
@@ -7,7 +7,7 @@ import { execFileSync, spawn } from "node:child_process";
7
7
 
8
8
  import { defaultDataRoot } from "./workspace-data.js";
9
9
 
10
- const DEFAULT_AGENTS = ["codex", "claude", "antigravity"];
10
+ const DEFAULT_AGENTS = ["codex", "claude", "antigravity", "copilot"];
11
11
  const CTX_MCP_NAME = "ctx-mcp";
12
12
  const CONTEXTOS_PROXY_MARKER = "/contextos/plugins/ctx/mcp/proxy.js";
13
13
  const MCP_SERVER_RELATIVE = path.join("plugins", "ctx", "mcp", "server.js");
@@ -15,7 +15,8 @@ const AGENT_ALIASES = new Map([
15
15
  ["agy", "antigravity"],
16
16
  ["antigravity", "antigravity"],
17
17
  ["codex", "codex"],
18
- ["claude", "claude"]
18
+ ["claude", "claude"],
19
+ ["copilot", "copilot"]
19
20
  ]);
20
21
 
21
22
  function statusLine(label, value) {
@@ -508,6 +509,10 @@ export function verifySync({ cwd = process.cwd(), agents = DEFAULT_AGENTS } = {}
508
509
  path.join(cwd, ".gemini", "mcp.json"),
509
510
  ...antigravityMcpConfigPaths(),
510
511
  path.join(cwd, "AGENTS.md")
512
+ ],
513
+ copilot: [
514
+ path.join(cwd, ".vscode", "mcp.json"),
515
+ path.join(cwd, ".github", "copilot-instructions.md")
511
516
  ]
512
517
  };
513
518
 
@@ -526,6 +531,7 @@ function resolveStableMcpServerPath(rootDir) {
526
531
  path.join(codexRoot, MCP_SERVER_RELATIVE),
527
532
  path.join(dataRoot, "agents", "claude", "contextos", MCP_SERVER_RELATIVE),
528
533
  path.join(dataRoot, "agents", "agy", "contextos", MCP_SERVER_RELATIVE),
534
+ path.join(dataRoot, "agents", "copilot", "contextos", MCP_SERVER_RELATIVE),
529
535
  path.join(rootDir, MCP_SERVER_RELATIVE)
530
536
  ];
531
537
  for (const candidate of candidates) {
@@ -542,7 +548,7 @@ export async function syncRules({
542
548
  logger = console.log
543
549
  } = {}) {
544
550
  const options = parseSyncRulesArgs(args);
545
- if (!options.rules) throw new Error("Usage: ctx sync --rules [--agents codex,claude,antigravity] [--dry-run] [--force]");
551
+ if (!options.rules) throw new Error("Usage: ctx sync --rules [--agents codex,claude,antigravity,copilot] [--dry-run] [--force]");
546
552
 
547
553
  logger("");
548
554
  const ruler = checkRulerInstalled({ run });
@@ -608,6 +614,23 @@ export async function syncRules({
608
614
  logger(statusLine("Syncing Antigravity MCP config...", antigravityMcp.servers.length ? `✓ ${antigravityMcp.servers.join(", ")}` : "none found"));
609
615
  }
610
616
 
617
+ let copilotMcp = { changed: false };
618
+ if (options.agents.includes("copilot")) {
619
+ // Copilot MCP is managed by copilot-mcp.js during install,
620
+ // but we verify it's still in place during sync.
621
+ const vscodeMcpPath = path.join(cwd, ".vscode", "mcp.json");
622
+ if (fs.existsSync(vscodeMcpPath)) {
623
+ try {
624
+ const content = JSON.parse(fs.readFileSync(vscodeMcpPath, "utf8"));
625
+ copilotMcp.changed = Boolean(content?.mcpServers?.[CTX_MCP_NAME]);
626
+ logger(statusLine("Verifying Copilot MCP config...", copilotMcp.changed ? "✓ ctx-mcp found" : "not configured"));
627
+ } catch {
628
+ logger(statusLine("Verifying Copilot MCP config...", "⚠ parse error"));
629
+ }
630
+ } else {
631
+ logger(statusLine("Verifying Copilot MCP config...", "not installed (run ctx install --agent copilot)"));
632
+ }
633
+ }
611
634
  logger("[ctx] Verifying sync...");
612
635
  const checks = options.dryRun ? options.agents.map((agent) => ({ agent, ok: true, filePath: "(dry-run)" })) : verifySync({ cwd, agents: options.agents });
613
636
  for (const check of checks) {
@@ -1,4 +1,5 @@
1
- const DEFAULT_AGENTS = ["codex", "claude", "agy"];
1
+ // No agents pre-selected by default — user must choose explicitly
2
+ const DEFAULT_AGENTS = [];
2
3
 
3
4
  export function parseSetupArgs(args = []) {
4
5
  const agentsFlag = args.indexOf("--agents");
@@ -5,14 +5,15 @@ import readline from "node:readline/promises";
5
5
  import { stdin as input, stdout as output } from "node:process";
6
6
  import { execFileSync, execSync, spawn } from "node:child_process";
7
7
 
8
- const DEFAULT_AGENTS = ["codex", "claude", "antigravity"];
8
+ const DEFAULT_AGENTS = ["codex", "claude", "antigravity", "copilot"];
9
9
  const INSTALL_SH_URL = "https://raw.githubusercontent.com/runkids/skillshare/main/install.sh";
10
10
  const INSTALL_PS_URL = "https://raw.githubusercontent.com/runkids/skillshare/main/install.ps1";
11
11
  const AGENT_ALIASES = new Map([
12
12
  ["agy", "antigravity"],
13
13
  ["antigravity", "antigravity"],
14
14
  ["codex", "codex"],
15
- ["claude", "claude"]
15
+ ["claude", "claude"],
16
+ ["copilot", "copilot"]
16
17
  ]);
17
18
 
18
19
  function statusLine(label, value) {
@@ -329,11 +330,18 @@ function copyDirectory(sourceDir, targetDir) {
329
330
  for (const entry of fs.readdirSync(sourceDir, { withFileTypes: true })) {
330
331
  const source = path.join(sourceDir, entry.name);
331
332
  const target = path.join(targetDir, entry.name);
332
- if (entry.isDirectory()) {
333
+ if (entry.isSymbolicLink()) {
334
+ // Follow symlinks and copy real content to avoid incompatibility
335
+ // with tools like antigravity-awesome-skills that reject symlinks.
336
+ const real = fs.realpathSync(source);
337
+ const stat = fs.statSync(real);
338
+ if (stat.isDirectory()) {
339
+ copyDirectory(real, target);
340
+ } else if (stat.isFile()) {
341
+ fs.copyFileSync(real, target);
342
+ }
343
+ } else if (entry.isDirectory()) {
333
344
  copyDirectory(source, target);
334
- } else if (entry.isSymbolicLink()) {
335
- const link = fs.readlinkSync(source);
336
- fs.symlinkSync(link, target);
337
345
  } else if (entry.isFile()) {
338
346
  fs.copyFileSync(source, target);
339
347
  }
@@ -2,6 +2,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { z } from "zod";
3
3
 
4
4
  import { scoreContext } from "../lib/score-context.js";
5
+ import { scheduleContext } from "../lib/scheduler.js";
5
6
 
6
7
  export function createContextOSMcpServer({ dataDir }) {
7
8
  const server = new McpServer({
@@ -51,13 +52,31 @@ export function createContextOSMcpServer({ dataDir }) {
51
52
  skills: args.skills,
52
53
  workflows: args.workflows
53
54
  });
55
+
56
+ // Format the same human-readable context that the hook path produces
57
+ const scheduled = scheduleContext({
58
+ rules: result.scoredRules,
59
+ relevantFiles: result.suggestedFiles,
60
+ suggestedSkills: result.suggestedSkills,
61
+ suggestedWorkflows: result.suggestedWorkflows
62
+ });
63
+
64
+ const contextText = scheduled.additionalContext || "";
65
+ const contentBlocks = [];
66
+
67
+ // Primary block: human-readable rules, files, skills, workflows
68
+ if (contextText) {
69
+ contentBlocks.push({ type: "text", text: contextText });
70
+ }
71
+
72
+ // Secondary block: telemetry metadata
73
+ contentBlocks.push({
74
+ type: "text",
75
+ text: JSON.stringify(result.telemetry)
76
+ });
77
+
54
78
  return {
55
- content: [
56
- {
57
- type: "text",
58
- text: JSON.stringify(result.telemetry)
59
- }
60
- ],
79
+ content: contentBlocks,
61
80
  structuredContent: {
62
81
  scoredRules: result.scoredRules,
63
82
  suggestedFiles: result.suggestedFiles,
@@ -70,3 +89,4 @@ export function createContextOSMcpServer({ dataDir }) {
70
89
 
71
90
  return server;
72
91
  }
92
+