memory-journal-mcp 7.1.0 → 7.3.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 (124) hide show
  1. package/README.md +59 -51
  2. package/dist/{chunk-GW5DYUQJ.js → chunk-CHWIPVQN.js} +174 -74
  3. package/dist/{chunk-37BQOJDZ.js → chunk-WXDEVIFL.js} +87 -8
  4. package/dist/{chunk-JEGRDY6W.js → chunk-ZJJD2F5T.js} +487 -89
  5. package/dist/cli.js +30 -4
  6. package/dist/github-integration-YODGZH3K.js +1 -0
  7. package/dist/index.d.ts +5 -1
  8. package/dist/index.js +3 -3
  9. package/dist/{tools-O44Q52RD.js → tools-MNMGDTQI.js} +2 -2
  10. package/package.json +4 -4
  11. package/skills/README.md +77 -0
  12. package/skills/autonomous-dev/SKILL.md +56 -0
  13. package/skills/bin/sync.js +50 -0
  14. package/skills/bun/SKILL.md +156 -0
  15. package/skills/github-commander/SKILL.md +1 -1
  16. package/skills/github-commander/workflows/code-quality-audit.md +7 -5
  17. package/skills/github-commander/workflows/issue-triage.md +13 -4
  18. package/skills/github-commander/workflows/milestone-sprint.md +9 -1
  19. package/skills/github-commander/workflows/perf-audit.md +2 -0
  20. package/skills/github-commander/workflows/pr-review.md +9 -3
  21. package/skills/github-commander/workflows/roadmap-kickoff.md +79 -0
  22. package/skills/github-commander/workflows/security-audit.md +3 -3
  23. package/skills/github-commander/workflows/update-deps.md +2 -2
  24. package/skills/gitlab/SKILL.md +115 -0
  25. package/skills/gitlab/package-lock.json +392 -0
  26. package/skills/gitlab/package.json +14 -0
  27. package/skills/gitlab/scripts/gitlab-client.ts +125 -0
  28. package/skills/gitlab/scripts/gitlab-helper.ts +80 -0
  29. package/skills/golang/SKILL.md +54 -0
  30. package/skills/mysql/SKILL.md +30 -0
  31. package/skills/package.json +48 -0
  32. package/skills/playwright-standard/SKILL.md +58 -0
  33. package/skills/playwright-standard/examples/fixtures.ts +66 -0
  34. package/skills/playwright-standard/examples/type-stubs.d.ts +10 -0
  35. package/skills/playwright-standard/references/advanced-scenarios.md +59 -0
  36. package/skills/playwright-standard/references/infrastructure.md +43 -0
  37. package/skills/postgres/SKILL.md +33 -0
  38. package/skills/react-best-practices/AGENTS.md +2883 -0
  39. package/skills/react-best-practices/README.md +127 -0
  40. package/skills/react-best-practices/SKILL.md +138 -0
  41. package/skills/react-best-practices/metadata.json +17 -0
  42. package/skills/react-best-practices/rules/_sections.md +46 -0
  43. package/skills/react-best-practices/rules/_template.md +28 -0
  44. package/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  45. package/skills/react-best-practices/rules/advanced-init-once.md +42 -0
  46. package/skills/react-best-practices/rules/advanced-use-latest.md +39 -0
  47. package/skills/react-best-practices/rules/async-api-routes.md +35 -0
  48. package/skills/react-best-practices/rules/async-defer-await.md +80 -0
  49. package/skills/react-best-practices/rules/async-dependencies.md +48 -0
  50. package/skills/react-best-practices/rules/async-parallel.md +24 -0
  51. package/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
  52. package/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
  53. package/skills/react-best-practices/rules/bundle-conditional.md +37 -0
  54. package/skills/react-best-practices/rules/bundle-defer-third-party.md +48 -0
  55. package/skills/react-best-practices/rules/bundle-dynamic-imports.md +34 -0
  56. package/skills/react-best-practices/rules/bundle-preload.md +44 -0
  57. package/skills/react-best-practices/rules/client-event-listeners.md +78 -0
  58. package/skills/react-best-practices/rules/client-localstorage-schema.md +74 -0
  59. package/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
  60. package/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
  61. package/skills/react-best-practices/rules/js-batch-dom-css.md +110 -0
  62. package/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
  63. package/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
  64. package/skills/react-best-practices/rules/js-cache-storage.md +68 -0
  65. package/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
  66. package/skills/react-best-practices/rules/js-early-exit.md +50 -0
  67. package/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
  68. package/skills/react-best-practices/rules/js-index-maps.md +37 -0
  69. package/skills/react-best-practices/rules/js-length-check-first.md +50 -0
  70. package/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
  71. package/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
  72. package/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
  73. package/skills/react-best-practices/rules/rendering-activity.md +24 -0
  74. package/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +38 -0
  75. package/skills/react-best-practices/rules/rendering-conditional-render.md +32 -0
  76. package/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
  77. package/skills/react-best-practices/rules/rendering-hoist-jsx.md +36 -0
  78. package/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +72 -0
  79. package/skills/react-best-practices/rules/rendering-hydration-suppress-warning.md +26 -0
  80. package/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
  81. package/skills/react-best-practices/rules/rendering-usetransition-loading.md +75 -0
  82. package/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
  83. package/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
  84. package/skills/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
  85. package/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
  86. package/skills/react-best-practices/rules/rerender-functional-setstate.md +77 -0
  87. package/skills/react-best-practices/rules/rerender-lazy-state-init.md +56 -0
  88. package/skills/react-best-practices/rules/rerender-memo-with-default-value.md +36 -0
  89. package/skills/react-best-practices/rules/rerender-memo.md +44 -0
  90. package/skills/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
  91. package/skills/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
  92. package/skills/react-best-practices/rules/rerender-transitions.md +40 -0
  93. package/skills/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
  94. package/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
  95. package/skills/react-best-practices/rules/server-auth-actions.md +96 -0
  96. package/skills/react-best-practices/rules/server-cache-lru.md +41 -0
  97. package/skills/react-best-practices/rules/server-cache-react.md +76 -0
  98. package/skills/react-best-practices/rules/server-dedup-props.md +65 -0
  99. package/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
  100. package/skills/react-best-practices/rules/server-serialization.md +38 -0
  101. package/skills/rust/SKILL.md +86 -0
  102. package/skills/shadcn-ui/SKILL.md +72 -0
  103. package/skills/skill-builder/SKILL.md +457 -0
  104. package/skills/skill-builder/checklist.md +65 -0
  105. package/skills/sqlite/SKILL.md +38 -0
  106. package/skills/typescript/SKILL.md +453 -0
  107. package/skills/typescript/assets/eslint-template.js +102 -0
  108. package/skills/typescript/assets/tsconfig-template.json +45 -0
  109. package/skills/typescript/references/enterprise-patterns.md +531 -0
  110. package/skills/typescript/references/generics.md +493 -0
  111. package/skills/typescript/references/nestjs-integration.md +579 -0
  112. package/skills/typescript/references/react-integration.md +616 -0
  113. package/skills/typescript/references/toolchain.md +547 -0
  114. package/skills/typescript/references/type-system.md +481 -0
  115. package/skills/vitest-standard/SKILL.md +82 -0
  116. package/skills/vitest-standard/examples/service-mock.ts +60 -0
  117. package/skills/vitest-standard/examples/tdd-calculator.ts +41 -0
  118. package/skills/vitest-standard/examples/type-stubs.d.ts +18 -0
  119. package/skills/vitest-standard/references/async-and-errors.md +58 -0
  120. package/skills/vitest-standard/references/coverage-and-config.md +53 -0
  121. package/skills/vitest-standard/references/mocking.md +61 -0
  122. package/skills/vitest-standard/references/tdd-patterns.md +60 -0
  123. package/dist/github-integration-FOJ4U6I5.js +0 -1
  124. package/skills/github-commander/workflows/full-audit.md +0 -134
@@ -1,5 +1,5 @@
1
- import { withSessionInit, withPriority, ASSISTANT_FOCUSED, TOOL_GROUPS, HIGH_PRIORITY, LOW_PRIORITY, MEDIUM_PRIORITY, setDefaultSandboxMode, initializeAuditLogger, parseToolFilter, getFilterSummary, getToolFilterFromEnv, getTools, getEnabledGroups, callTool, getGlobalAuditLogger, sendProgress, SUPPORTED_SCOPES, getRequiredScope, hasScope, getAuditResourceDef, execQuery, transformEntryRow, resolveGitHubRepo, isResourceError, milestoneCompletionPct, parseScopes, BASE_SCOPES, getAllToolNames, globalMetrics, DEFAULT_BRIEFING_CONFIG } from './chunk-JEGRDY6W.js';
2
- import { logger, GitHubIntegration, ConfigurationError, ResourceNotFoundError, ConnectionError, QueryError, assertNoPathTraversal, ValidationError, MemoryJournalMcpError, validateDateFormatPattern } from './chunk-37BQOJDZ.js';
1
+ import { withSessionInit, withPriority, ASSISTANT_FOCUSED, TOOL_GROUPS, HIGH_PRIORITY, LOW_PRIORITY, MEDIUM_PRIORITY, setDefaultSandboxMode, initializeAuditLogger, parseToolFilter, getFilterSummary, getToolFilterFromEnv, getTools, getEnabledGroups, callTool, getGlobalAuditLogger, sendProgress, SUPPORTED_SCOPES, getRequiredScope, hasScope, getAuditResourceDef, execQuery, transformEntryRow, resolveGitHubRepo, isResourceError, milestoneCompletionPct, parseScopes, BASE_SCOPES, getAllToolNames, globalMetrics, DEFAULT_BRIEFING_CONFIG } from './chunk-ZJJD2F5T.js';
2
+ import { logger, GitHubIntegration, ConfigurationError, ResourceNotFoundError, ConnectionError, QueryError, assertNoPathTraversal, ValidationError, MemoryJournalMcpError, validateDateFormatPattern } from './chunk-WXDEVIFL.js';
3
3
  import { createRequire } from 'module';
4
4
  import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
5
5
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
@@ -1540,7 +1540,7 @@ var VectorSearchManager = class {
1540
1540
  WHERE embedding MATCH ?
1541
1541
  ORDER BY distance
1542
1542
  LIMIT ?`
1543
- ).all(queryVec, limit * 2);
1543
+ ).all(queryVec, limit);
1544
1544
  const filteredResults = results.map((r) => ({
1545
1545
  entryId: r.entry_id,
1546
1546
  score: 1 / (1 + r.distance)
@@ -1593,7 +1593,7 @@ var VectorSearchManager = class {
1593
1593
  WHERE embedding MATCH ?
1594
1594
  ORDER BY distance
1595
1595
  LIMIT ?`
1596
- ).all(queryVec, (limit + 1) * 2);
1596
+ ).all(queryVec, limit + 1);
1597
1597
  const filteredResults = results.filter((r) => r.entry_id !== entryId).map((r) => ({
1598
1598
  entryId: r.entry_id,
1599
1599
  score: 1 / (1 + r.distance)
@@ -1828,7 +1828,7 @@ async function buildGitHubSection(github, config) {
1828
1828
  const [ciStatus, issuesAndPrs, milestones, insights, copilotReviews] = await Promise.all([
1829
1829
  fetchCiStatus(github, owner, repo, config),
1830
1830
  fetchIssuesAndPrs(github, owner, repo, config),
1831
- fetchMilestones(github, owner, repo),
1831
+ fetchMilestones(github, owner, repo, config.milestoneCount ?? 3),
1832
1832
  fetchInsights(github, owner, repo),
1833
1833
  config.copilotReviews ? fetchCopilotReviews(github, owner, repo) : Promise.resolve(void 0)
1834
1834
  ]);
@@ -1959,9 +1959,10 @@ async function fetchIssuesAndPrs(github, owner, repo, config) {
1959
1959
  return { openIssues: 0, openPRs: 0 };
1960
1960
  }
1961
1961
  }
1962
- async function fetchMilestones(github, owner, repo) {
1962
+ async function fetchMilestones(github, owner, repo, limit) {
1963
+ if (limit <= 0) return [];
1963
1964
  try {
1964
- const msList = await github.getMilestones(owner, repo, "open", 3);
1965
+ const msList = await github.getMilestones(owner, repo, "open", limit);
1965
1966
  return msList.map((m) => {
1966
1967
  const pct = milestoneCompletionPct(m.openIssues, m.closedIssues);
1967
1968
  return {
@@ -2039,8 +2040,8 @@ async function fetchCopilotReviews(github, owner, repo) {
2039
2040
  }
2040
2041
  }
2041
2042
  var PREVIEW_LENGTH = 80;
2042
- function buildJournalContext(context, config) {
2043
- const recentEntries = context.db.getRecentEntries(config.entryCount);
2043
+ function buildJournalContext(context, config, projectNumber) {
2044
+ const recentEntries = typeof projectNumber === "number" ? context.db.searchEntries("", { limit: config.entryCount, projectNumber }) : context.db.getRecentEntries(config.entryCount);
2044
2045
  const latestEntries = recentEntries.map((e) => {
2045
2046
  const content = e.content ?? "";
2046
2047
  return {
@@ -2050,16 +2051,47 @@ function buildJournalContext(context, config) {
2050
2051
  preview: content.slice(0, PREVIEW_LENGTH) + (content.length > PREVIEW_LENGTH ? "..." : "")
2051
2052
  };
2052
2053
  });
2054
+ const summaryEntries = typeof projectNumber === "number" ? context.db.searchEntries("", {
2055
+ limit: config.summaryCount,
2056
+ projectNumber,
2057
+ tags: ["session-summary"]
2058
+ }) : context.db.searchEntries("", {
2059
+ limit: config.summaryCount,
2060
+ tags: ["session-summary"]
2061
+ });
2062
+ const retroEntries = summaryEntries.length === 0 ? typeof projectNumber === "number" ? context.db.searchEntries("", {
2063
+ limit: config.summaryCount,
2064
+ projectNumber,
2065
+ entryType: "retrospective"
2066
+ }) : context.db.searchEntries("", {
2067
+ limit: config.summaryCount,
2068
+ entryType: "retrospective"
2069
+ }) : [];
2070
+ const finalSummaryEntries = summaryEntries.length > 0 ? summaryEntries : retroEntries;
2071
+ let latestSessionSummary;
2072
+ let sessionSummaries;
2073
+ if (finalSummaryEntries.length > 0) {
2074
+ sessionSummaries = finalSummaryEntries.map((entry) => {
2075
+ const c = entry.content ?? "";
2076
+ return {
2077
+ id: entry.id,
2078
+ timestamp: entry.timestamp,
2079
+ type: entry.entryType,
2080
+ preview: c.slice(0, PREVIEW_LENGTH) + (c.length > PREVIEW_LENGTH ? "..." : "")
2081
+ };
2082
+ });
2083
+ latestSessionSummary = sessionSummaries[0];
2084
+ }
2053
2085
  const totalEntries = context.db.getActiveEntryCount();
2054
2086
  const lastModified = recentEntries[0]?.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
2055
- return { totalEntries, latestEntries, lastModified };
2087
+ return { totalEntries, latestEntries, latestSessionSummary, sessionSummaries, lastModified };
2056
2088
  }
2057
2089
  var TEAM_PREVIEW_LENGTH = 60;
2058
- function buildTeamContext(context, config) {
2090
+ function buildTeamContext(context, config, projectNumber) {
2059
2091
  if (!context.teamDb) return void 0;
2060
2092
  try {
2061
2093
  const teamTotalEntries = context.teamDb.getActiveEntryCount();
2062
- const teamRecent = context.teamDb.getRecentEntries(1);
2094
+ const teamRecent = typeof projectNumber === "number" ? context.teamDb.searchEntries("", { limit: 1, projectNumber }) : context.teamDb.getRecentEntries(1);
2063
2095
  const teamLatestEntry = teamRecent[0];
2064
2096
  const teamContent = teamLatestEntry ? teamLatestEntry["content"] ?? "" : "";
2065
2097
  const teamLatest = teamLatestEntry ? `#${String(teamLatestEntry["id"])}: ${teamContent.slice(0, TEAM_PREVIEW_LENGTH)}${teamContent.length > TEAM_PREVIEW_LENGTH ? "..." : ""}` : null;
@@ -2069,7 +2101,7 @@ function buildTeamContext(context, config) {
2069
2101
  };
2070
2102
  let teamLatestEntries = void 0;
2071
2103
  if (config.includeTeam) {
2072
- const teamEntries = context.teamDb.getRecentEntries(config.entryCount);
2104
+ const teamEntries = typeof projectNumber === "number" ? context.teamDb.searchEntries("", { limit: config.entryCount, projectNumber }) : context.teamDb.getRecentEntries(config.entryCount);
2073
2105
  teamLatestEntries = teamEntries.map((e) => {
2074
2106
  const content = e.content ?? "";
2075
2107
  return {
@@ -2136,8 +2168,18 @@ function buildSkillsDirInfo(skillsDirPath) {
2136
2168
  }
2137
2169
 
2138
2170
  // src/handlers/resources/core/briefing/user-message.ts
2171
+ var escapeTableCell = (text) => text.replace(/\\/g, "\\\\").replace(/\|/g, "\\|").replace(/\r?\n/g, "<br>");
2139
2172
  function formatUserMessage(opts) {
2140
- const { repoName, branchName, totalEntries, latestPreview, github, rulesFile, skillsDir } = opts;
2173
+ const {
2174
+ repoName,
2175
+ branchName,
2176
+ totalEntries,
2177
+ latestPreview,
2178
+ summaryPreviews,
2179
+ github,
2180
+ rulesFile,
2181
+ skillsDir
2182
+ } = opts;
2141
2183
  let ciDisplay = opts.ciStatus;
2142
2184
  if (github?.workflowSummary) {
2143
2185
  const ws = github.workflowSummary;
@@ -2165,7 +2207,7 @@ function formatUserMessage(opts) {
2165
2207
  if (github.openIssueList && github.openIssueList.length > 0) {
2166
2208
  const titles = github.openIssueList.map((i) => `#${String(i.number)} ${i.title}`).join(" \xB7 ");
2167
2209
  issuesRow = `
2168
- | **Issues** | ${String(github.openIssues)} open: ${titles} |`;
2210
+ | **Issues** | ${String(github.openIssues)} open: ${escapeTableCell(titles)} |`;
2169
2211
  } else {
2170
2212
  issuesRow = `
2171
2213
  | **Issues** | ${String(github.openIssues)} open |`;
@@ -2181,14 +2223,14 @@ function formatUserMessage(opts) {
2181
2223
  } else if (github.openPrList && github.openPrList.length > 0) {
2182
2224
  const titles = github.openPrList.map((p) => `#${String(p.number)} ${p.title}`).join(" \xB7 ");
2183
2225
  prsRow = `
2184
- | **PRs** | ${String(github.openPRs)} open: ${titles} |`;
2226
+ | **PRs** | ${String(github.openPRs)} open: ${escapeTableCell(titles)} |`;
2185
2227
  } else {
2186
2228
  prsRow = `
2187
2229
  | **PRs** | ${String(github.openPRs)} open |`;
2188
2230
  }
2189
2231
  }
2190
2232
  const milestoneRow = github?.milestones && github.milestones.length > 0 ? `
2191
- | **Milestones** | ${github.milestones.map((m) => `${m.title} (${m.progress}${m.dueOn ? `, due ${m.dueOn.split("T")[0] ?? ""}` : ""})`).join(", ")} |` : "";
2233
+ | **Milestones** | ${escapeTableCell(github.milestones.map((m) => `${m.title} (${m.progress}${m.dueOn ? `, due ${m.dueOn.split("T")[0] ?? ""}` : ""})`).join(", "))} |` : "";
2192
2234
  let insightsRow = "";
2193
2235
  if (github?.insights) {
2194
2236
  const parts = [];
@@ -2206,16 +2248,18 @@ function formatUserMessage(opts) {
2206
2248
  }
2207
2249
  const copilotRow = github?.copilotReviews ? `
2208
2250
  | **Copilot** | ${String(github.copilotReviews.reviewed)} reviewed \xB7 ${String(github.copilotReviews.approved)} approved${github.copilotReviews.changesRequested > 0 ? ` \xB7 ${String(github.copilotReviews.changesRequested)} changes requested` : ""}${github.copilotReviews.totalComments > 0 ? ` (${String(github.copilotReviews.totalComments)} comments)` : ""} |` : "";
2251
+ const summariesOutput = summaryPreviews && summaryPreviews.length > 0 ? summaryPreviews.map((s) => `
2252
+ | **Summary** | ${escapeTableCell(s)} |`).join("") : "";
2209
2253
  return `\u{1F4CB} **Session Context Loaded**
2210
2254
  | Context | Value |
2211
2255
  |---------|-------|
2212
- | **Project** | ${repoName} |
2213
- | **Branch** | ${branchName} |
2214
- | **CI** | ${ciDisplay} |
2256
+ | **Project** | ${escapeTableCell(repoName)} |
2257
+ | **Branch** | ${escapeTableCell(branchName)} |
2258
+ | **CI** | ${escapeTableCell(ciDisplay)} |
2215
2259
  | **Journal** | ${totalEntries} entries |${opts.teamTotalEntries !== void 0 ? `
2216
2260
  | **Team DB** | ${opts.teamTotalEntries} entries |` : ""}
2217
- | **Latest** | ${latestPreview} |${issuesRow}${prsRow}${milestoneRow}${insightsRow}${copilotRow}${rulesFile ? `
2218
- | **Rules** | ${rulesFile.name} (${String(rulesFile.sizeKB)} KB, updated ${rulesFile.lastModified}) |` : ""}${skillsDir ? `
2261
+ | **Latest** | ${escapeTableCell(latestPreview)} |${summariesOutput}${issuesRow}${prsRow}${milestoneRow}${insightsRow}${copilotRow}${rulesFile ? `
2262
+ | **Rules** | ${escapeTableCell(rulesFile.name)} (${String(rulesFile.sizeKB)} KB, updated ${rulesFile.lastModified}) |` : ""}${skillsDir ? `
2219
2263
  | **Skills** | ${String(skillsDir.count)} skill${skillsDir.count !== 1 ? "s" : ""} available |` : ""}`;
2220
2264
  }
2221
2265
 
@@ -2252,24 +2296,28 @@ var dynamicBriefingResource = {
2252
2296
  }
2253
2297
  };
2254
2298
  async function buildBriefingData(context, targetRepo) {
2255
- const config = context.briefingConfig ?? DEFAULT_BRIEFING_CONFIG;
2299
+ const config = { ...DEFAULT_BRIEFING_CONFIG, ...context.briefingConfig };
2256
2300
  let activeGithub = context.github;
2301
+ let activeProjectNumber = config.defaultProjectNumber;
2257
2302
  if (targetRepo && config.projectRegistry?.[targetRepo]) {
2258
2303
  const repoPath = config.projectRegistry[targetRepo].path;
2259
2304
  activeGithub = new GitHubIntegration(repoPath);
2305
+ activeProjectNumber = config.projectRegistry[targetRepo].project_number ?? void 0;
2260
2306
  }
2261
- const journal = buildJournalContext(context, config);
2307
+ const journal = buildJournalContext(context, config, activeProjectNumber);
2262
2308
  const github = await buildGitHubSection(activeGithub, config);
2263
- const team = buildTeamContext(context, config);
2309
+ const team = buildTeamContext(context, config, activeProjectNumber);
2264
2310
  const rulesFile = buildRulesFileInfo(config.rulesFilePath);
2265
2311
  const skillsDir = buildSkillsDirInfo(config.skillsDirPath);
2266
2312
  const latestPreview = journal.latestEntries[0] ? `#${journal.latestEntries[0].id} (${journal.latestEntries[0].type}): ${journal.latestEntries[0].preview}` : "No entries yet";
2313
+ const summaryPreviews = journal.sessionSummaries ? journal.sessionSummaries.map((s) => `#${s.id} (${s.type}): ${s.preview}`) : null;
2267
2314
  const userMessage = formatUserMessage({
2268
2315
  repoName: github?.repo ?? "local",
2269
2316
  branchName: github?.branch ?? "unknown",
2270
2317
  ciStatus: github?.ci ?? "unknown",
2271
2318
  totalEntries: journal.totalEntries,
2272
2319
  latestPreview,
2320
+ summaryPreviews,
2273
2321
  github,
2274
2322
  teamTotalEntries: team?.teamInfo.totalEntries,
2275
2323
  rulesFile,
@@ -2281,7 +2329,8 @@ async function buildBriefingData(context, targetRepo) {
2281
2329
  serverTime: (/* @__PURE__ */ new Date()).toISOString(),
2282
2330
  journal: {
2283
2331
  totalEntries: journal.totalEntries,
2284
- latestEntries: journal.latestEntries
2332
+ latestEntries: journal.latestEntries,
2333
+ ...journal.latestSessionSummary ? { latestSessionSummary: journal.latestSessionSummary } : {}
2285
2334
  },
2286
2335
  github,
2287
2336
  teamContext: team?.teamInfo,
@@ -2324,7 +2373,7 @@ async function buildBriefingData(context, targetRepo) {
2324
2373
  // src/constants/server-instructions.ts
2325
2374
  var CORE_INSTRUCTIONS = `# memory-journal-mcp
2326
2375
 
2327
- ## ESSENTIAL SESSION START!**
2376
+ ## **ESSENTIAL SESSION START!**
2328
2377
 
2329
2378
  1. You **MUST** read the \`memory://briefing/{repo_name}\` at the start of each chat!
2330
2379
  2. Use the standard MCP \`read_resource\` tool for this (do NOT use Code Mode/execute_code).
@@ -2384,6 +2433,13 @@ When you notice the user consistently applies patterns, preferences, or workflow
2384
2433
  - **Always ask the user first** \u2014 never create or modify rules/skills silently
2385
2434
  - Frame suggestions as: "I noticed you always [pattern]. Would you like me to add/update a rule for this?"
2386
2435
  - For skills, explain the workflow it would automate and what triggers it
2436
+
2437
+ ### Native Agent Skills (NPM Distribution)
2438
+
2439
+ This server leverages the \`neverinfamous-agent-skills\` package. If the user's \`SKILLS_DIR_PATH\` environment variable targets these, you have native access to foundational frameworks (\`mastering-typescript\`, \`react-best-practices\`, \`playwright-standard\`, \`golang\`, \`rust\`, \`shadcn-ui\`) and the \`github-commander\` DevOps workflows (\`issue-triage\`, \`pr-review\`, etc.).
2440
+
2441
+ - The user can distribute or update these skills across their repositories by running \`npx neverinfamous-agent-skills@latest\`.
2442
+ - If you need to create a new skill, reference the bundled \`skill-builder\` instructions!
2387
2443
  `;
2388
2444
  var COPILOT_REVIEW_INSTRUCTIONS = `
2389
2445
  ## Copilot Review Patterns
@@ -2444,12 +2500,7 @@ var CODE_MODE_NAMESPACE_ROWS = [
2444
2500
  namespace: "`mj.relationships.*`",
2445
2501
  example: '`mj.relationships.linkEntries(1, 2, "implements")`'
2446
2502
  },
2447
- {
2448
- group: "io",
2449
- label: "IO",
2450
- namespace: "`mj.io.*`",
2451
- example: '`mj.io.exportEntries("json")`'
2452
- },
2503
+ { group: "io", label: "IO", namespace: "`mj.io.*`", example: '`mj.io.exportEntries("json")`' },
2453
2504
  {
2454
2505
  group: "admin",
2455
2506
  label: "Admin",
@@ -2542,7 +2593,7 @@ var GITHUB_INSTRUCTIONS = `
2542
2593
  - Include \`issue_number\`/\`pr_number\` in \`create_entry\` to auto-link
2543
2594
  - After closing issue/merging PR \u2192 create summary entry with learnings
2544
2595
  - CI failures \u2192 \`actions-failure-digest\` prompt or \`memory://actions/recent\`
2545
- - Kanban: \`get_kanban_board\` \u2192 \`move_kanban_item\` \u2192 document completion (project_number auto-resolves if repo is registered)
2596
+ - Kanban: \`get_kanban_board\` \u2192 \`add_kanban_item\` / \`move_kanban_item\` / \`delete_kanban_item\` \u2192 document completion (project_number auto-resolves if repo is registered)
2546
2597
  - Milestones: \`get_github_milestones\` \u2192 track project progress, \`memory://github/milestones\`
2547
2598
  - **Multi-Project Routing**: If \`memory://briefing\` shows "Registered Workspaces":
2548
2599
  - **Tools**: Pass a \`repo\` parameter to ALL GitHub tools (including \`get_github_context\`) to explicitly target a specific project.
@@ -2873,6 +2924,12 @@ Provide insights on patterns, productivity, and recommendations.`
2873
2924
  LIMIT 20
2874
2925
  `
2875
2926
  );
2927
+ const mappedEntries = entries.map((e) => ({
2928
+ id: e["id"],
2929
+ type: e["entry_type"] ?? e["entryType"],
2930
+ timestamp: e["timestamp"],
2931
+ content: typeof e["content"] === "string" && e["content"].length > 250 ? e["content"].slice(0, 250) + "..." : e["content"]
2932
+ }));
2876
2933
  return {
2877
2934
  messages: [
2878
2935
  {
@@ -2881,7 +2938,7 @@ Provide insights on patterns, productivity, and recommendations.`
2881
2938
  type: "text",
2882
2939
  text: `Track goals and milestones based on significant entries:
2883
2940
 
2884
- ${JSON.stringify(entries, null, 2)}
2941
+ ${JSON.stringify(mappedEntries, null, 2)}
2885
2942
 
2886
2943
  Summarize progress toward goals and highlight achievements.`
2887
2944
  }
@@ -3069,6 +3126,14 @@ ${entrySummary}
3069
3126
  }
3070
3127
 
3071
3128
  // src/handlers/prompts/github.ts
3129
+ function formatPromptEntries(entries, maxCount = 50) {
3130
+ return entries.slice(0, maxCount).map((e) => ({
3131
+ id: e["id"],
3132
+ type: e["entry_type"] ?? e["entryType"],
3133
+ timestamp: e["timestamp"],
3134
+ content: typeof e["content"] === "string" && e["content"].length > 250 ? e["content"].slice(0, 250) + "..." : e["content"]
3135
+ }));
3136
+ }
3072
3137
  function getGitHubPromptDefinitions() {
3073
3138
  return [
3074
3139
  {
@@ -3099,7 +3164,7 @@ function getGitHubPromptDefinitions() {
3099
3164
  type: "text",
3100
3165
  text: `Generate a status summary for Project #${String(projectNumber)}:
3101
3166
 
3102
- Entries: ${JSON.stringify(entries, null, 2)}
3167
+ Entries: ${JSON.stringify(formatPromptEntries(entries), null, 2)}
3103
3168
 
3104
3169
  Provide: overview, recent activity, blockers, next steps.`
3105
3170
  }
@@ -3133,7 +3198,7 @@ Provide: overview, recent activity, blockers, next steps.`
3133
3198
  type: "text",
3134
3199
  text: `Summarize PR #${String(prNumber)} activity:
3135
3200
 
3136
- Journal entries: ${JSON.stringify(entries, null, 2)}
3201
+ Journal entries: ${JSON.stringify(formatPromptEntries(entries), null, 2)}
3137
3202
 
3138
3203
  Provide: summary of changes, decisions made, testing done.`
3139
3204
  }
@@ -3167,7 +3232,7 @@ Provide: summary of changes, decisions made, testing done.`
3167
3232
  type: "text",
3168
3233
  text: `Prepare for code review of PR #${String(prNumber)}:
3169
3234
 
3170
- Context entries: ${JSON.stringify(entries, null, 2)}
3235
+ Context entries: ${JSON.stringify(formatPromptEntries(entries), null, 2)}
3171
3236
 
3172
3237
  Provide: review checklist, areas of concern, testing recommendations.`
3173
3238
  }
@@ -3201,7 +3266,7 @@ Provide: review checklist, areas of concern, testing recommendations.`
3201
3266
  type: "text",
3202
3267
  text: `Retrospective for PR #${String(prNumber)}:
3203
3268
 
3204
- Journal entries: ${JSON.stringify(entries, null, 2)}
3269
+ Journal entries: ${JSON.stringify(formatPromptEntries(entries), null, 2)}
3205
3270
 
3206
3271
  Provide: what went well, challenges, lessons learned.`
3207
3272
  }
@@ -3234,7 +3299,7 @@ Provide: what went well, challenges, lessons learned.`
3234
3299
  type: "text",
3235
3300
  text: `Analyze CI/CD failures from these workflow entries:
3236
3301
 
3237
- ${JSON.stringify(entries, null, 2)}
3302
+ ${JSON.stringify(formatPromptEntries(entries), null, 2)}
3238
3303
 
3239
3304
  Provide: failure patterns, root causes, remediation steps.`
3240
3305
  }
@@ -3271,7 +3336,7 @@ Provide: failure patterns, root causes, remediation steps.`
3271
3336
  type: "text",
3272
3337
  text: `Track milestones for Project #${String(projectNumber)}:
3273
3338
 
3274
- Milestone entries: ${JSON.stringify(entries, null, 2)}
3339
+ Milestone entries: ${JSON.stringify(formatPromptEntries(entries), null, 2)}
3275
3340
 
3276
3341
  Provide: progress summary, upcoming milestones, timeline.`
3277
3342
  }
@@ -3528,6 +3593,9 @@ var statisticsResource = {
3528
3593
  return context.db.getStatistics("week");
3529
3594
  }
3530
3595
  };
3596
+ var cachedRulesContent = null;
3597
+ var rulesLastScanTime = 0;
3598
+ var RULES_CACHE_TTL_MS = 5 * 60 * 1e3;
3531
3599
  var rulesResource = {
3532
3600
  uri: "memory://rules",
3533
3601
  name: "Rules File",
@@ -3536,7 +3604,7 @@ var rulesResource = {
3536
3604
  mimeType: "text/markdown",
3537
3605
  icons: [ICON_BRIEFING],
3538
3606
  annotations: withPriority(0.7, ASSISTANT_FOCUSED),
3539
- handler: (_uri, _context) => {
3607
+ handler: async (_uri, _context) => {
3540
3608
  const rulesPath = process.env["RULES_FILE_PATH"];
3541
3609
  if (!rulesPath) {
3542
3610
  return {
@@ -3547,11 +3615,24 @@ var rulesResource = {
3547
3615
  };
3548
3616
  }
3549
3617
  try {
3550
- const content = fs2.readFileSync(rulesPath, "utf8");
3618
+ if (cachedRulesContent && Date.now() - rulesLastScanTime < RULES_CACHE_TTL_MS) {
3619
+ const stat2 = await fs2.promises.stat(rulesPath).catch(() => ({ mtimeMs: Date.now() }));
3620
+ return {
3621
+ data: cachedRulesContent,
3622
+ annotations: {
3623
+ lastModified: new Date(stat2.mtimeMs).toISOString()
3624
+ }
3625
+ };
3626
+ }
3627
+ const content = await fs2.promises.readFile(rulesPath, "utf8");
3628
+ const stat = await fs2.promises.stat(rulesPath).catch(() => ({ mtimeMs: Date.now() }));
3629
+ const mtimeMs = stat.mtimeMs;
3630
+ cachedRulesContent = content;
3631
+ rulesLastScanTime = Date.now();
3551
3632
  return {
3552
3633
  data: content,
3553
3634
  annotations: {
3554
- lastModified: new Date(fs2.statSync(rulesPath).mtimeMs).toISOString()
3635
+ lastModified: new Date(mtimeMs).toISOString()
3555
3636
  }
3556
3637
  };
3557
3638
  } catch (err) {
@@ -3617,15 +3698,15 @@ function getShippedSkillsDir() {
3617
3698
  return void 0;
3618
3699
  }
3619
3700
  }
3620
- function scanSkillsDir(dir, source) {
3701
+ async function scanSkillsDir(dir, source) {
3621
3702
  if (!fs2.existsSync(dir)) return [];
3622
- const entries = fs2.readdirSync(dir, { withFileTypes: true });
3703
+ const entries = await fs2.promises.readdir(dir, { withFileTypes: true });
3623
3704
  const skills = [];
3624
3705
  for (const entry of entries) {
3625
3706
  if (!entry.isDirectory()) continue;
3626
3707
  const skillMdPath = path4.join(dir, entry.name, "SKILL.md");
3627
3708
  if (!fs2.existsSync(skillMdPath)) continue;
3628
- const content = fs2.readFileSync(skillMdPath, "utf8");
3709
+ const content = await fs2.promises.readFile(skillMdPath, "utf8");
3629
3710
  const lines = content.split("\n");
3630
3711
  const excerptLine = lines.find(
3631
3712
  (l) => l.trim().length > 0 && !l.startsWith("#") && !l.startsWith("---")
@@ -3643,7 +3724,7 @@ var skillsResource = {
3643
3724
  mimeType: "application/json",
3644
3725
  icons: [ICON_BRIEFING],
3645
3726
  annotations: { ...MEDIUM_PRIORITY, audience: ["assistant"] },
3646
- handler: (_uri, _context) => {
3727
+ handler: async (_uri, _context) => {
3647
3728
  const userSkillsDir = process.env["SKILLS_DIR_PATH"];
3648
3729
  const shippedSkillsDir = getShippedSkillsDir();
3649
3730
  const hasAnySource = !!userSkillsDir || !!shippedSkillsDir;
@@ -3670,12 +3751,12 @@ var skillsResource = {
3670
3751
  }
3671
3752
  const skillMap = /* @__PURE__ */ new Map();
3672
3753
  if (shippedSkillsDir) {
3673
- for (const skill of scanSkillsDir(shippedSkillsDir, "shipped")) {
3754
+ for (const skill of await scanSkillsDir(shippedSkillsDir, "shipped")) {
3674
3755
  skillMap.set(skill.name, skill);
3675
3756
  }
3676
3757
  }
3677
3758
  if (userSkillsDir) {
3678
- for (const skill of scanSkillsDir(userSkillsDir, "user")) {
3759
+ for (const skill of await scanSkillsDir(userSkillsDir, "user")) {
3679
3760
  skillMap.set(skill.name, skill);
3680
3761
  }
3681
3762
  }
@@ -4134,21 +4215,25 @@ function getGitHubResourceDefinitions() {
4134
4215
  error: kanbanResult.reason
4135
4216
  });
4136
4217
  }
4137
- let milestoneSummary = null;
4138
- if (milestoneResult.status === "fulfilled" && milestoneResult.value.length > 0) {
4139
- milestoneSummary = milestoneResult.value.map((ms) => {
4140
- const pct = milestoneCompletionPct(ms.openIssues, ms.closedIssues);
4141
- return {
4142
- number: ms.number,
4143
- title: ms.title,
4144
- state: ms.state,
4145
- openIssues: ms.openIssues,
4146
- closedIssues: ms.closedIssues,
4147
- completionPercentage: pct,
4148
- dueOn: ms.dueOn
4149
- };
4150
- });
4218
+ let milestoneSummary = { openCount: 0, items: [] };
4219
+ if (milestoneResult.status === "fulfilled") {
4220
+ milestoneSummary = {
4221
+ openCount: milestoneResult.value.length,
4222
+ items: milestoneResult.value.map((ms) => {
4223
+ const pct = milestoneCompletionPct(ms.openIssues, ms.closedIssues);
4224
+ return {
4225
+ number: ms.number,
4226
+ title: ms.title,
4227
+ state: ms.state,
4228
+ openIssues: ms.openIssues,
4229
+ closedIssues: ms.closedIssues,
4230
+ completionPercentage: pct,
4231
+ dueOn: ms.dueOn
4232
+ };
4233
+ })
4234
+ };
4151
4235
  } else if (milestoneResult.status === "rejected") {
4236
+ milestoneSummary = null;
4152
4237
  logger.debug("Failed to fetch milestones", {
4153
4238
  module: "RESOURCE",
4154
4239
  operation: "github-status",
@@ -4894,7 +4979,7 @@ function getHelpResourceDefinitions() {
4894
4979
  var toolIndexModule = null;
4895
4980
  async function getAllToolDefinitionsAsync(context) {
4896
4981
  try {
4897
- toolIndexModule ??= await import('./tools-O44Q52RD.js');
4982
+ toolIndexModule ??= await import('./tools-MNMGDTQI.js');
4898
4983
  if (toolIndexModule === null) return [];
4899
4984
  const tools = toolIndexModule.getTools(context.db, null);
4900
4985
  return tools.map((t) => ({
@@ -6450,15 +6535,30 @@ function registerPrompts(server, prompts, db, teamDb) {
6450
6535
  ...promptDef.icons ? { icons: promptDef.icons } : {}
6451
6536
  },
6452
6537
  (providedArgs) => {
6453
- const args = providedArgs;
6454
- const promptResult = getPrompt(promptDef.name, args, db, teamDb);
6455
- const result = {
6456
- messages: promptResult.messages.map((m) => ({
6457
- role: m.role,
6458
- content: m.content
6459
- }))
6460
- };
6461
- return Promise.resolve(result);
6538
+ try {
6539
+ const args = providedArgs;
6540
+ const promptResult = getPrompt(promptDef.name, args, db, teamDb);
6541
+ const result = {
6542
+ messages: promptResult.messages.map((m) => ({
6543
+ role: m.role,
6544
+ content: m.content
6545
+ }))
6546
+ };
6547
+ return Promise.resolve(result);
6548
+ } catch (err) {
6549
+ const message = err instanceof Error ? err.message : String(err);
6550
+ return Promise.resolve({
6551
+ messages: [
6552
+ {
6553
+ role: "user",
6554
+ content: {
6555
+ type: "text",
6556
+ text: `[Prompt handler error] ${message}`
6557
+ }
6558
+ }
6559
+ ]
6560
+ });
6561
+ }
6462
6562
  }
6463
6563
  );
6464
6564
  }