@neurynae/toolcairn-mcp 0.10.8 → 0.10.10

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
@@ -4473,9 +4473,7 @@ function getOpenCodeMcpEntry(serverPath) {
4473
4473
 
4474
4474
  // ../../packages/tools-local/dist/auto-init.js
4475
4475
  var logger18 = (0, import_errors20.createMcpLogger)({ name: "@toolcairn/tools:auto-init" });
4476
- var INSTRUCTION_SENTINEL = "## ToolCairn \u2014 Tool Intelligence MCP";
4477
- var GITIGNORE_SENTINEL = "# ToolCairn";
4478
- var GITIGNORE_BLOCK = "\n# ToolCairn\n.toolcairn/events.jsonl\n.toolcairn/audit-log.jsonl\n.toolcairn/audit-log.archive.jsonl\n.toolcairn/config.lock\n";
4476
+ var GITIGNORE_BLOCK = "\n# ToolCairn\n.toolcairn/events.jsonl\n.toolcairn/audit-log.jsonl\n.toolcairn/audit-log.archive.jsonl\n.toolcairn/config.json\n";
4479
4477
  async function autoInitProject(input) {
4480
4478
  const { projectRoot, agent, batchResolve, serverPath, reason } = input;
4481
4479
  logger18.info({ projectRoot, agent }, "autoInitProject starting");
@@ -4620,20 +4618,16 @@ async function applySetupFiles(projectRoot, args) {
4620
4618
  }
4621
4619
  async function applyInstructionFile(abs, relPath, content) {
4622
4620
  try {
4623
- const exists = await fileExists(abs);
4624
- if (exists) {
4621
+ if (await fileExists(abs)) {
4625
4622
  const current = await readFile28(abs, "utf-8");
4626
- if (current.includes(INSTRUCTION_SENTINEL)) {
4623
+ if (current === content) {
4627
4624
  return {
4628
4625
  file: relPath,
4629
4626
  action: "append-or-create",
4630
4627
  applied: false,
4631
- reason: "ToolCairn rules block already present"
4628
+ reason: "content already up to date"
4632
4629
  };
4633
4630
  }
4634
- const separator = current.endsWith("\n") ? "" : "\n";
4635
- await writeFileAtomic3(abs, `${current}${separator}${content}`, "utf-8");
4636
- return { file: relPath, action: "append-or-create", applied: true };
4637
4631
  }
4638
4632
  await writeFileAtomic3(abs, content, "utf-8");
4639
4633
  return { file: relPath, action: "append-or-create", applied: true };
@@ -4666,20 +4660,25 @@ async function applyMcpConfig(abs, relPath, entry, isOpenCode) {
4666
4660
  };
4667
4661
  }
4668
4662
  const existingServers = parsed[topKey] && typeof parsed[topKey] === "object" && !Array.isArray(parsed[topKey]) ? parsed[topKey] : {};
4669
- if (existingServers.toolcairn !== void 0) {
4663
+ const toolcairnEntry = entry.toolcairn ?? entry;
4664
+ const merged = {
4665
+ ...parsed,
4666
+ [topKey]: {
4667
+ ...existingServers,
4668
+ toolcairn: toolcairnEntry
4669
+ }
4670
+ };
4671
+ const nextJson = `${JSON.stringify(merged, null, 2)}
4672
+ `;
4673
+ if (raw === nextJson) {
4670
4674
  return {
4671
4675
  file: relPath,
4672
4676
  action: "merge-or-create",
4673
4677
  applied: false,
4674
- reason: `${topKey}.toolcairn already present`
4678
+ reason: "toolcairn entry already up to date"
4675
4679
  };
4676
4680
  }
4677
- const merged = {
4678
- ...parsed,
4679
- [topKey]: { ...existingServers, ...entry }
4680
- };
4681
- await writeFileAtomic3(abs, `${JSON.stringify(merged, null, 2)}
4682
- `, "utf-8");
4681
+ await writeFileAtomic3(abs, nextJson, "utf-8");
4683
4682
  return { file: relPath, action: "merge-or-create", applied: true };
4684
4683
  } catch (err) {
4685
4684
  const reason = err instanceof Error ? err.message : String(err);
@@ -4687,25 +4686,43 @@ async function applyMcpConfig(abs, relPath, entry, isOpenCode) {
4687
4686
  return { file: relPath, action: "merge-or-create", applied: false, reason };
4688
4687
  }
4689
4688
  }
4689
+ var GITIGNORE_BLOCK_START = "# toolcairn:start";
4690
+ var GITIGNORE_BLOCK_END = "# toolcairn:end";
4691
+ function buildGitignoreBlock() {
4692
+ return `${GITIGNORE_BLOCK_START}${GITIGNORE_BLOCK}${GITIGNORE_BLOCK_END}
4693
+ `;
4694
+ }
4690
4695
  async function applyGitignore(abs) {
4691
4696
  const relPath = ".gitignore";
4692
4697
  try {
4693
4698
  const exists = await fileExists(abs);
4699
+ const ourBlock = buildGitignoreBlock();
4694
4700
  if (!exists) {
4695
- await writeFileAtomic3(abs, GITIGNORE_BLOCK.replace(/^\n/, ""), "utf-8");
4701
+ await writeFileAtomic3(abs, ourBlock, "utf-8");
4696
4702
  return { file: relPath, action: "append", applied: true };
4697
4703
  }
4698
4704
  const current = await readFile28(abs, "utf-8");
4699
- if (current.includes(GITIGNORE_SENTINEL)) {
4705
+ const startIdx = current.indexOf(GITIGNORE_BLOCK_START);
4706
+ const endIdx = current.indexOf(GITIGNORE_BLOCK_END);
4707
+ let next;
4708
+ if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
4709
+ const lineStart = current.lastIndexOf("\n", startIdx) + 1;
4710
+ const afterEndOfLine = current.indexOf("\n", endIdx);
4711
+ const sliceEnd = afterEndOfLine === -1 ? current.length : afterEndOfLine + 1;
4712
+ next = current.slice(0, lineStart) + ourBlock + current.slice(sliceEnd);
4713
+ } else {
4714
+ const separator = current.endsWith("\n") ? "" : "\n";
4715
+ next = `${current}${separator}${ourBlock}`;
4716
+ }
4717
+ if (next === current) {
4700
4718
  return {
4701
4719
  file: relPath,
4702
4720
  action: "append",
4703
4721
  applied: false,
4704
- reason: "ToolCairn gitignore block already present"
4722
+ reason: "block already up to date"
4705
4723
  };
4706
4724
  }
4707
- const separator = current.endsWith("\n") ? "" : "\n";
4708
- await writeFileAtomic3(abs, `${current}${separator}${GITIGNORE_BLOCK}`, "utf-8");
4725
+ await writeFileAtomic3(abs, next, "utf-8");
4709
4726
  return { file: relPath, action: "append", applied: true };
4710
4727
  } catch (err) {
4711
4728
  const reason = err instanceof Error ? err.message : String(err);
@@ -6105,19 +6122,6 @@ async function main() {
6105
6122
  let server;
6106
6123
  if (authenticated) {
6107
6124
  logger26.info({ user: creds.user_email }, "Authenticated \u2014 starting full server");
6108
- try {
6109
- const summary = await runPostAuthInit({ agent: "claude" });
6110
- logger26.info(
6111
- {
6112
- roots: summary.roots_discovered.length,
6113
- provisioned: summary.projects.length,
6114
- unknown_tools_total: summary.unknown_tools_total
6115
- },
6116
- "Startup auto-refresh complete"
6117
- );
6118
- } catch (err) {
6119
- logger26.warn({ err }, "Startup auto-refresh failed \u2014 continuing with tool registration");
6120
- }
6121
6125
  server = await buildProdServer();
6122
6126
  } else {
6123
6127
  let verificationUri = "https://toolcairn.neurynae.com/signup";
@@ -6197,6 +6201,20 @@ After sign-in the server will automatically provision .toolcairn/config.json for
6197
6201
  const transport = createTransport();
6198
6202
  await server.connect(transport);
6199
6203
  logger26.info(authenticated ? "ToolCairn MCP ready" : "ToolCairn MCP ready (awaiting sign-in)");
6204
+ if (authenticated) {
6205
+ void runPostAuthInit({ agent: "claude" }).then((summary) => {
6206
+ logger26.info(
6207
+ {
6208
+ roots: summary.roots_discovered.length,
6209
+ provisioned: summary.projects.length,
6210
+ unknown_tools_total: summary.unknown_tools_total
6211
+ },
6212
+ "Background auto-refresh complete"
6213
+ );
6214
+ }).catch((err) => {
6215
+ logger26.warn({ err }, "Background auto-refresh failed \u2014 config left as-is");
6216
+ });
6217
+ }
6200
6218
  }
6201
6219
  main().catch((error) => {
6202
6220
  (0, import_errors28.createMcpLogger)({ name: "@toolcairn/mcp-server" }).error(