@contentrain/mcp 1.6.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +8 -7
  2. package/dist/{apply-manager-BJ3nKEls.mjs → apply-manager-BRmB27H5.mjs} +5 -5
  3. package/dist/{apply-manager-BJ3nKEls.mjs.map → apply-manager-BRmB27H5.mjs.map} +1 -1
  4. package/dist/branch-lifecycle-7dQoF22r.d.mts +141 -0
  5. package/dist/branch-lifecycle-7dQoF22r.d.mts.map +1 -0
  6. package/dist/branch-lifecycle-D7tXOE4f.mjs +444 -0
  7. package/dist/branch-lifecycle-D7tXOE4f.mjs.map +1 -0
  8. package/dist/{config-Lw7vpK9n.mjs → config-DlFcTxFG.mjs} +3 -2
  9. package/dist/config-DlFcTxFG.mjs.map +1 -0
  10. package/dist/{context-DS40WOdw.mjs → context-CYN__o3Q.mjs} +24 -11
  11. package/dist/context-CYN__o3Q.mjs.map +1 -0
  12. package/dist/core/apply-manager.mjs +6 -6
  13. package/dist/core/config.d.mts.map +1 -1
  14. package/dist/core/config.mjs +1 -1
  15. package/dist/core/context.d.mts +20 -2
  16. package/dist/core/context.d.mts.map +1 -1
  17. package/dist/core/context.mjs +2 -2
  18. package/dist/core/doctor.mjs +3 -3
  19. package/dist/core/validator/index.mjs +2 -2
  20. package/dist/{detect-DL9mFmaS.mjs → detect-eWS6lvoH.mjs} +1 -1
  21. package/dist/{detect-DL9mFmaS.mjs.map → detect-eWS6lvoH.mjs.map} +1 -1
  22. package/dist/{doctor-Dxu_SzZy.mjs → doctor-qiUKCy9b.mjs} +34 -15
  23. package/dist/doctor-qiUKCy9b.mjs.map +1 -0
  24. package/dist/git/branch-lifecycle.d.mts +2 -57
  25. package/dist/git/branch-lifecycle.mjs +3 -3
  26. package/dist/git/transaction.d.mts +2 -0
  27. package/dist/git/transaction.d.mts.map +1 -1
  28. package/dist/git/transaction.mjs +5 -4
  29. package/dist/{id-CIO9s0x_.mjs → id-DV_T9Ic8.mjs} +1 -1
  30. package/dist/{id-CIO9s0x_.mjs.map → id-DV_T9Ic8.mjs.map} +1 -1
  31. package/dist/index.mjs +11 -11
  32. package/dist/{local-D56D9e5T.mjs → local-BZEUWBoC.mjs} +8 -11
  33. package/dist/local-BZEUWBoC.mjs.map +1 -0
  34. package/dist/providers/github/index.d.mts +23 -2
  35. package/dist/providers/github/index.d.mts.map +1 -1
  36. package/dist/providers/github/index.mjs +112 -51
  37. package/dist/providers/github/index.mjs.map +1 -1
  38. package/dist/providers/gitlab/index.d.mts +3 -1
  39. package/dist/providers/gitlab/index.d.mts.map +1 -1
  40. package/dist/providers/gitlab/index.mjs +21 -5
  41. package/dist/providers/gitlab/index.mjs.map +1 -1
  42. package/dist/providers/local/index.mjs +6 -5
  43. package/dist/server/http/index.d.mts +1 -1
  44. package/dist/server/http/index.mjs +11 -11
  45. package/dist/{server-WqGx6ait.d.mts → server-DZBcZWhE.d.mts} +1 -1
  46. package/dist/{server-WqGx6ait.d.mts.map → server-DZBcZWhE.d.mts.map} +1 -1
  47. package/dist/{server-CufhOunD.mjs → server-tTuinKHD.mjs} +56 -22
  48. package/dist/server-tTuinKHD.mjs.map +1 -0
  49. package/dist/server.d.mts +1 -1
  50. package/dist/server.mjs +11 -11
  51. package/dist/{transaction-LiTjan9Q.mjs → transaction-qliKvBRL.mjs} +104 -60
  52. package/dist/transaction-qliKvBRL.mjs.map +1 -0
  53. package/dist/util/detect.mjs +1 -1
  54. package/dist/util/id.mjs +1 -1
  55. package/dist/{validator-Bo06QPVB.mjs → validator-Z3DGNWQ6.mjs} +2 -2
  56. package/dist/{validator-Bo06QPVB.mjs.map → validator-Z3DGNWQ6.mjs.map} +1 -1
  57. package/package.json +2 -2
  58. package/dist/branch-lifecycle-DjX3MXNG.mjs +0 -149
  59. package/dist/branch-lifecycle-DjX3MXNG.mjs.map +0 -1
  60. package/dist/config-Lw7vpK9n.mjs.map +0 -1
  61. package/dist/context-DS40WOdw.mjs.map +0 -1
  62. package/dist/doctor-Dxu_SzZy.mjs.map +0 -1
  63. package/dist/git/branch-lifecycle.d.mts.map +0 -1
  64. package/dist/local-D56D9e5T.mjs.map +0 -1
  65. package/dist/server-CufhOunD.mjs.map +0 -1
  66. package/dist/transaction-LiTjan9Q.mjs.map +0 -1
@@ -2,11 +2,12 @@ import "../../contracts-DfL0BfrD.mjs";
2
2
  import "../../ops-Dh2T3u53.mjs";
3
3
  import "../../serialization-B1CEzR4H.mjs";
4
4
  import "../../fs-DLbVB-Ek.mjs";
5
- import "../../config-Lw7vpK9n.mjs";
5
+ import "../../config-DlFcTxFG.mjs";
6
6
  import { C as LocalReader } from "../../model-manager-BhLsUgaB.mjs";
7
7
  import "../../meta-manager-C900rEyG.mjs";
8
- import "../../context-DS40WOdw.mjs";
9
- import "../../id-CIO9s0x_.mjs";
10
- import "../../transaction-LiTjan9Q.mjs";
11
- import { t as LocalProvider } from "../../local-D56D9e5T.mjs";
8
+ import "../../context-CYN__o3Q.mjs";
9
+ import "../../branch-lifecycle-D7tXOE4f.mjs";
10
+ import "../../id-DV_T9Ic8.mjs";
11
+ import "../../transaction-qliKvBRL.mjs";
12
+ import { t as LocalProvider } from "../../local-BZEUWBoC.mjs";
12
13
  export { LocalProvider, LocalReader };
@@ -1,4 +1,4 @@
1
- import { n as ToolProvider } from "../../server-WqGx6ait.mjs";
1
+ import { n as ToolProvider } from "../../server-DZBcZWhE.mjs";
2
2
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import http from "node:http";
4
4
 
@@ -2,24 +2,24 @@ import "../../contracts-DfL0BfrD.mjs";
2
2
  import "../../ops-Dh2T3u53.mjs";
3
3
  import "../../serialization-B1CEzR4H.mjs";
4
4
  import "../../fs-DLbVB-Ek.mjs";
5
- import "../../config-Lw7vpK9n.mjs";
5
+ import "../../config-DlFcTxFG.mjs";
6
6
  import "../../model-manager-BhLsUgaB.mjs";
7
7
  import "../../meta-manager-C900rEyG.mjs";
8
- import "../../context-DS40WOdw.mjs";
9
- import "../../id-CIO9s0x_.mjs";
10
- import "../../transaction-LiTjan9Q.mjs";
11
- import "../../local-D56D9e5T.mjs";
12
- import "../../detect-DL9mFmaS.mjs";
13
- import "../../branch-lifecycle-DjX3MXNG.mjs";
8
+ import "../../context-CYN__o3Q.mjs";
9
+ import "../../branch-lifecycle-D7tXOE4f.mjs";
10
+ import "../../id-DV_T9Ic8.mjs";
11
+ import "../../transaction-qliKvBRL.mjs";
12
+ import "../../local-BZEUWBoC.mjs";
13
+ import "../../detect-eWS6lvoH.mjs";
14
14
  import "../../annotations-BFJbfSKe.mjs";
15
- import { t as createServer } from "../../server-CufhOunD.mjs";
16
- import "../../validator-Bo06QPVB.mjs";
15
+ import { t as createServer } from "../../server-tTuinKHD.mjs";
16
+ import "../../validator-Z3DGNWQ6.mjs";
17
17
  import "../../scan-config-jC6XmiqF.mjs";
18
18
  import "../../graph-builder-DXv2JEp-.mjs";
19
19
  import "../../scanner-DKMwc03k.mjs";
20
20
  import "../../tsx-parser-CQc6nr-o.mjs";
21
- import "../../apply-manager-BJ3nKEls.mjs";
22
- import "../../doctor-Dxu_SzZy.mjs";
21
+ import "../../apply-manager-BRmB27H5.mjs";
22
+ import "../../doctor-qiUKCy9b.mjs";
23
23
  import { randomUUID } from "node:crypto";
24
24
  import http from "node:http";
25
25
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
@@ -47,4 +47,4 @@ declare function createServer(projectRoot: string): McpServer;
47
47
  declare function createServer(opts: CreateServerOptions): McpServer;
48
48
  //#endregion
49
49
  export { ToolProvider as n, createServer as r, CreateServerOptions as t };
50
- //# sourceMappingURL=server-WqGx6ait.d.mts.map
50
+ //# sourceMappingURL=server-DZBcZWhE.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server-WqGx6ait.d.mts","names":[],"sources":["../src/server.ts"],"mappings":";;;;;;AAWA;;;;;KAAY,YAAA,GAAe,YAAA;AAAA,UAWV,mBAAA;;;;;;;EAOf,QAAA,GAAW,YAAA;EA2BG;;;;;AAChB;EArBE,WAAA;AAAA;;;;;;;;;;;;;;;;;;iBAoBc,YAAA,CAAa,WAAA,WAAsB,SAAA;AAAA,iBACnC,YAAA,CAAa,IAAA,EAAM,mBAAA,GAAsB,SAAA"}
1
+ {"version":3,"file":"server-DZBcZWhE.d.mts","names":[],"sources":["../src/server.ts"],"mappings":";;;;;;AAWA;;;;;KAAY,YAAA,GAAe,YAAA;AAAA,UAWV,mBAAA;;;;;;;EAOf,QAAA,GAAW,YAAA;EA2BG;;;;;AAChB;EArBE,WAAA;AAAA;;;;;;;;;;;;;;;;;;iBAoBc,YAAA,CAAa,WAAA,WAAsB,SAAA;AAAA,iBACnC,YAAA,CAAa,IAAA,EAAM,mBAAA,GAAsB,SAAA"}
@@ -1,22 +1,22 @@
1
1
  import { i as planContentDelete, n as planModelDelete, r as planContentSave, t as planModelSave } from "./ops-Dh2T3u53.mjs";
2
2
  import { n as contentFilePath, t as contentDirPath } from "./paths-CYl5vCBD.mjs";
3
3
  import { a as readJson, n as ensureDir, r as pathExists, s as writeJson, t as contentrainDir } from "./fs-DLbVB-Ek.mjs";
4
- import { n as readVocabulary, t as readConfig } from "./config-Lw7vpK9n.mjs";
4
+ import { n as readVocabulary, t as readConfig } from "./config-DlFcTxFG.mjs";
5
5
  import { S as writeContent, _ as resolveMdFilePath, a as fieldDefZodSchema, c as validateModelDefinition, d as listContent, g as resolveLocaleStrategy, h as resolveJsonFilePath, l as writeModel, m as resolveContentDir, n as checkReferences, o as listModels, r as countEntries, s as readModel, u as deleteContent } from "./model-manager-BhLsUgaB.mjs";
6
6
  import { n as readMeta, r as writeMeta } from "./meta-manager-C900rEyG.mjs";
7
- import { n as readContext } from "./context-DS40WOdw.mjs";
8
- import { i as mergeBranch, n as createTransaction, r as ensureContentBranch, t as buildBranchName } from "./transaction-LiTjan9Q.mjs";
9
- import { n as isMerged, t as LocalProvider } from "./local-D56D9e5T.mjs";
10
- import { t as detectStack } from "./detect-DL9mFmaS.mjs";
11
- import { n as checkBranchHealth, r as cleanupMergedBranches } from "./branch-lifecycle-DjX3MXNG.mjs";
7
+ import { n as readContext } from "./context-CYN__o3Q.mjs";
8
+ import { a as deleteRemoteBranch, c as pruneMergedRemoteBranches, i as cleanupMergedBranches, n as checkBranchHealth, s as listRemoteCrBranches } from "./branch-lifecycle-D7tXOE4f.mjs";
9
+ import { i as mergeBranch, n as createTransaction, r as ensureContentBranch, t as buildBranchName } from "./transaction-qliKvBRL.mjs";
10
+ import { n as isMerged, t as LocalProvider } from "./local-BZEUWBoC.mjs";
11
+ import { t as detectStack } from "./detect-eWS6lvoH.mjs";
12
12
  import { t as TOOL_ANNOTATIONS } from "./annotations-BFJbfSKe.mjs";
13
13
  import { n as listTemplates, t as getTemplate } from "./templates-VrLVqfe5.mjs";
14
- import { t as validateProject } from "./validator-Bo06QPVB.mjs";
14
+ import { t as validateProject } from "./validator-Z3DGNWQ6.mjs";
15
15
  import { t as OverlayReader } from "./overlay-reader-CUs9jgqk.mjs";
16
16
  import { t as buildGraph } from "./graph-builder-DXv2JEp-.mjs";
17
17
  import { n as scanSummary, t as scanCandidates } from "./scanner-DKMwc03k.mjs";
18
- import { n as applyExtract, r as applyReuse } from "./apply-manager-BJ3nKEls.mjs";
19
- import { t as runDoctor } from "./doctor-Dxu_SzZy.mjs";
18
+ import { n as applyExtract, r as applyReuse } from "./apply-manager-BRmB27H5.mjs";
19
+ import { t as runDoctor } from "./doctor-qiUKCy9b.mjs";
20
20
  import { join } from "node:path";
21
21
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
22
22
  import { CONTENTRAIN_BRANCH } from "@contentrain/types";
@@ -1576,10 +1576,15 @@ function registerWorkflowTools(server, provider, projectRoot) {
1576
1576
  await git.push(remoteName, CONTENTRAIN_BRANCH);
1577
1577
  } catch {}
1578
1578
  const cleanup = await cleanupMergedBranches(projectRoot);
1579
+ const remotePrune = await pruneMergedRemoteBranches(projectRoot, {
1580
+ config,
1581
+ max: 20
1582
+ });
1579
1583
  const nextSteps = [];
1580
1584
  if (pushed.length > 0) nextSteps.push("Create PRs on your git platform for review");
1581
1585
  if (pushed.length > 0) nextSteps.push("For merge: use contentrain_merge or direct user to http://localhost:3333/branches");
1582
1586
  if (errors.length > 0) nextSteps.push("Fix push errors and retry");
1587
+ if (remotePrune.errors.length > 0) nextSteps.push("Some merged remote branches could not be pruned — run `contentrain prune`");
1583
1588
  if (cleanup.remaining >= 50) nextSteps.push(`Warning: ${cleanup.remaining} active contentrain branches. Consider reviewing old branches.`);
1584
1589
  return { content: [{
1585
1590
  type: "text",
@@ -1593,6 +1598,7 @@ function registerWorkflowTools(server, provider, projectRoot) {
1593
1598
  deleted: cleanup.deleted,
1594
1599
  remaining: cleanup.remaining
1595
1600
  } : void 0,
1601
+ remote_cleanup: remotePrune.deleted.length > 0 ? { deleted: remotePrune.deleted.length } : void 0,
1596
1602
  next_steps: nextSteps
1597
1603
  }, null, 2)
1598
1604
  }] };
@@ -1644,10 +1650,12 @@ function registerWorkflowTools(server, provider, projectRoot) {
1644
1650
  action: result.action,
1645
1651
  commit: result.commit,
1646
1652
  sync: result.sync,
1653
+ ...result.remote ? { remote: result.remote } : {},
1647
1654
  next_steps: [
1648
1655
  "Run `contentrain generate` (or `npx contentrain-query generate`) to update the SDK client",
1649
1656
  "Run contentrain_validate to verify content integrity",
1650
- result.sync.skipped.length > 0 ? `${result.sync.skipped.length} file(s) skipped due to local changes — resolve manually` : ""
1657
+ result.sync.skipped.length > 0 ? `${result.sync.skipped.length} file(s) skipped due to local changes — resolve manually` : "",
1658
+ result.remote?.warning ? `Remote copy not deleted (${result.remote.warning}) — delete it manually: git push <remote> --delete ${targetBranch}` : ""
1651
1659
  ].filter(Boolean)
1652
1660
  }, null, 2)
1653
1661
  }] };
@@ -1661,12 +1669,17 @@ function registerWorkflowTools(server, provider, projectRoot) {
1661
1669
  };
1662
1670
  }
1663
1671
  });
1664
- server.tool("contentrain_branch_list", "List pending contentrain (cr/*) branches with their merge status against the contentrain branch. Use this to discover branch names for contentrain_merge / contentrain_branch_delete, and to monitor branch-health limits (warning at 50, blocked at 80 unmerged).", { unmerged_only: z.boolean().optional().describe("Only list branches not yet merged into contentrain. Default: false") }, TOOL_ANNOTATIONS["contentrain_branch_list"], async (input) => {
1672
+ server.tool("contentrain_branch_list", "List pending contentrain (cr/*) branches with their merge status against the contentrain branch. Use this to discover branch names for contentrain_merge / contentrain_branch_delete, and to monitor branch-health limits (warning at 50, blocked at 80 unmerged).", {
1673
+ unmerged_only: z.boolean().optional().describe("Only list branches not yet merged into contentrain. Default: false"),
1674
+ remote: z.boolean().optional().describe("Also check the git remote: annotate entries with on_remote and report remote-only cr/* leftovers. Requires network. Default: false")
1675
+ }, TOOL_ANNOTATIONS["contentrain_branch_list"], async (input) => {
1665
1676
  if (!provider.capabilities.localWorktree || !projectRoot) return capabilityError("contentrain_branch_list", "localWorktree");
1666
1677
  try {
1667
1678
  const git = simpleGit(projectRoot);
1668
1679
  const summary = await git.branchLocal();
1669
1680
  const crBranches = summary.all.filter((b) => b.startsWith("cr/") && b !== CONTENTRAIN_BRANCH);
1681
+ const remoteList = input.remote ? await listRemoteCrBranches(projectRoot) : void 0;
1682
+ const remoteNames = remoteList && !remoteList.error ? new Set(remoteList.branches.map((b) => b.name)) : void 0;
1670
1683
  const ordered = (await Promise.all(crBranches.map(async (name) => {
1671
1684
  const [merged, ts] = await Promise.all([isMerged(projectRoot, name, CONTENTRAIN_BRANCH), git.raw([
1672
1685
  "log",
@@ -1678,17 +1691,21 @@ function registerWorkflowTools(server, provider, projectRoot) {
1678
1691
  name,
1679
1692
  sha: summary.branches[name]?.commit ?? "",
1680
1693
  merged,
1681
- lastCommit: ts
1694
+ lastCommit: ts,
1695
+ ...remoteNames ? { on_remote: remoteNames.has(name) } : {}
1682
1696
  };
1683
1697
  }))).toSorted((left, right) => right.lastCommit.localeCompare(left.lastCommit));
1684
1698
  const filtered = input.unmerged_only ? ordered.filter((b) => !b.merged) : ordered;
1685
1699
  const health = await checkBranchHealth(projectRoot);
1700
+ const localNames = new Set(crBranches);
1701
+ const remoteExtras = input.remote ? remoteList === null ? { remote_error: "No git remote configured." } : remoteList.error ? { remote_error: remoteList.error } : { remote_only: remoteList.branches.filter((b) => !localNames.has(b.name)).map((b) => b.name) } : {};
1686
1702
  return { content: [{
1687
1703
  type: "text",
1688
1704
  text: JSON.stringify({
1689
1705
  total: ordered.length,
1690
1706
  unmerged: ordered.filter((b) => !b.merged).length,
1691
1707
  branches: filtered,
1708
+ ...remoteExtras,
1692
1709
  health: {
1693
1710
  warning: health.warning,
1694
1711
  blocked: health.blocked,
@@ -1721,28 +1738,45 @@ function registerWorkflowTools(server, provider, projectRoot) {
1721
1738
  };
1722
1739
  try {
1723
1740
  const git = simpleGit(projectRoot);
1724
- if (!(await git.branchLocal()).all.includes(input.branch)) return {
1725
- content: [{
1741
+ if (!(await git.branchLocal()).all.includes(input.branch)) {
1742
+ const remoteOnly = await deleteRemoteBranch(projectRoot, input.branch);
1743
+ if (remoteOnly.deleted) return { content: [{
1726
1744
  type: "text",
1727
1745
  text: JSON.stringify({
1728
- error: `Branch "${input.branch}" not found locally.`,
1729
- next_steps: ["List branches with contentrain_branch_list"]
1730
- })
1731
- }],
1732
- isError: true
1733
- };
1746
+ status: "deleted",
1747
+ branch: input.branch,
1748
+ scope: "remote-only",
1749
+ message: "Branch was not present locally; its remote copy was deleted."
1750
+ }, null, 2)
1751
+ }] };
1752
+ return {
1753
+ content: [{
1754
+ type: "text",
1755
+ text: JSON.stringify({
1756
+ error: `Branch "${input.branch}" not found locally${remoteOnly.skipped === "not-found" ? " or on the remote" : ""}.`,
1757
+ ...remoteOnly.warning ? { remote_warning: remoteOnly.warning } : {},
1758
+ next_steps: ["List branches with contentrain_branch_list"]
1759
+ })
1760
+ }],
1761
+ isError: true
1762
+ };
1763
+ }
1734
1764
  const merged = await isMerged(projectRoot, input.branch, CONTENTRAIN_BRANCH);
1735
1765
  await git.raw([
1736
1766
  "branch",
1737
1767
  "-D",
1738
1768
  input.branch
1739
1769
  ]);
1770
+ const remote = await deleteRemoteBranch(projectRoot, input.branch);
1740
1771
  return { content: [{
1741
1772
  type: "text",
1742
1773
  text: JSON.stringify({
1743
1774
  status: "deleted",
1744
1775
  branch: input.branch,
1745
1776
  was_merged: merged,
1777
+ remote_deleted: remote.deleted,
1778
+ ...remote.skipped ? { remote_skipped: remote.skipped } : {},
1779
+ ...remote.warning ? { remote_warning: remote.warning } : {},
1746
1780
  warning: merged ? void 0 : "Branch was not merged — its commits were discarded."
1747
1781
  }, null, 2)
1748
1782
  }] };
@@ -2334,7 +2368,7 @@ function registerDoctorTools(server, _provider, projectRoot) {
2334
2368
  }
2335
2369
  //#endregion
2336
2370
  //#region package.json
2337
- var version = "1.6.0";
2371
+ var version = "1.8.0";
2338
2372
  //#endregion
2339
2373
  //#region src/server.ts
2340
2374
  function createServer(input) {
@@ -2375,4 +2409,4 @@ function resolveServerContext(input) {
2375
2409
  //#endregion
2376
2410
  export { createServer as t };
2377
2411
 
2378
- //# sourceMappingURL=server-CufhOunD.mjs.map
2412
+ //# sourceMappingURL=server-tTuinKHD.mjs.map