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.
- package/README.md +59 -51
- package/dist/{chunk-GW5DYUQJ.js → chunk-CHWIPVQN.js} +174 -74
- package/dist/{chunk-37BQOJDZ.js → chunk-WXDEVIFL.js} +87 -8
- package/dist/{chunk-JEGRDY6W.js → chunk-ZJJD2F5T.js} +487 -89
- package/dist/cli.js +30 -4
- package/dist/github-integration-YODGZH3K.js +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +3 -3
- package/dist/{tools-O44Q52RD.js → tools-MNMGDTQI.js} +2 -2
- package/package.json +4 -4
- package/skills/README.md +77 -0
- package/skills/autonomous-dev/SKILL.md +56 -0
- package/skills/bin/sync.js +50 -0
- package/skills/bun/SKILL.md +156 -0
- package/skills/github-commander/SKILL.md +1 -1
- package/skills/github-commander/workflows/code-quality-audit.md +7 -5
- package/skills/github-commander/workflows/issue-triage.md +13 -4
- package/skills/github-commander/workflows/milestone-sprint.md +9 -1
- package/skills/github-commander/workflows/perf-audit.md +2 -0
- package/skills/github-commander/workflows/pr-review.md +9 -3
- package/skills/github-commander/workflows/roadmap-kickoff.md +79 -0
- package/skills/github-commander/workflows/security-audit.md +3 -3
- package/skills/github-commander/workflows/update-deps.md +2 -2
- package/skills/gitlab/SKILL.md +115 -0
- package/skills/gitlab/package-lock.json +392 -0
- package/skills/gitlab/package.json +14 -0
- package/skills/gitlab/scripts/gitlab-client.ts +125 -0
- package/skills/gitlab/scripts/gitlab-helper.ts +80 -0
- package/skills/golang/SKILL.md +54 -0
- package/skills/mysql/SKILL.md +30 -0
- package/skills/package.json +48 -0
- package/skills/playwright-standard/SKILL.md +58 -0
- package/skills/playwright-standard/examples/fixtures.ts +66 -0
- package/skills/playwright-standard/examples/type-stubs.d.ts +10 -0
- package/skills/playwright-standard/references/advanced-scenarios.md +59 -0
- package/skills/playwright-standard/references/infrastructure.md +43 -0
- package/skills/postgres/SKILL.md +33 -0
- package/skills/react-best-practices/AGENTS.md +2883 -0
- package/skills/react-best-practices/README.md +127 -0
- package/skills/react-best-practices/SKILL.md +138 -0
- package/skills/react-best-practices/metadata.json +17 -0
- package/skills/react-best-practices/rules/_sections.md +46 -0
- package/skills/react-best-practices/rules/_template.md +28 -0
- package/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/skills/react-best-practices/rules/advanced-init-once.md +42 -0
- package/skills/react-best-practices/rules/advanced-use-latest.md +39 -0
- package/skills/react-best-practices/rules/async-api-routes.md +35 -0
- package/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/skills/react-best-practices/rules/async-dependencies.md +48 -0
- package/skills/react-best-practices/rules/async-parallel.md +24 -0
- package/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/skills/react-best-practices/rules/bundle-conditional.md +37 -0
- package/skills/react-best-practices/rules/bundle-defer-third-party.md +48 -0
- package/skills/react-best-practices/rules/bundle-dynamic-imports.md +34 -0
- package/skills/react-best-practices/rules/bundle-preload.md +44 -0
- package/skills/react-best-practices/rules/client-event-listeners.md +78 -0
- package/skills/react-best-practices/rules/client-localstorage-schema.md +74 -0
- package/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/skills/react-best-practices/rules/js-batch-dom-css.md +110 -0
- package/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/skills/react-best-practices/rules/js-cache-storage.md +68 -0
- package/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/skills/react-best-practices/rules/js-length-check-first.md +50 -0
- package/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/skills/react-best-practices/rules/rendering-activity.md +24 -0
- package/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +38 -0
- package/skills/react-best-practices/rules/rendering-conditional-render.md +32 -0
- package/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/skills/react-best-practices/rules/rendering-hoist-jsx.md +36 -0
- package/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +72 -0
- package/skills/react-best-practices/rules/rendering-hydration-suppress-warning.md +26 -0
- package/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/skills/react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/skills/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/skills/react-best-practices/rules/rerender-functional-setstate.md +77 -0
- package/skills/react-best-practices/rules/rerender-lazy-state-init.md +56 -0
- package/skills/react-best-practices/rules/rerender-memo-with-default-value.md +36 -0
- package/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/skills/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/skills/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/skills/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/skills/react-best-practices/rules/server-auth-actions.md +96 -0
- package/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/skills/react-best-practices/rules/server-cache-react.md +76 -0
- package/skills/react-best-practices/rules/server-dedup-props.md +65 -0
- package/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/skills/rust/SKILL.md +86 -0
- package/skills/shadcn-ui/SKILL.md +72 -0
- package/skills/skill-builder/SKILL.md +457 -0
- package/skills/skill-builder/checklist.md +65 -0
- package/skills/sqlite/SKILL.md +38 -0
- package/skills/typescript/SKILL.md +453 -0
- package/skills/typescript/assets/eslint-template.js +102 -0
- package/skills/typescript/assets/tsconfig-template.json +45 -0
- package/skills/typescript/references/enterprise-patterns.md +531 -0
- package/skills/typescript/references/generics.md +493 -0
- package/skills/typescript/references/nestjs-integration.md +579 -0
- package/skills/typescript/references/react-integration.md +616 -0
- package/skills/typescript/references/toolchain.md +547 -0
- package/skills/typescript/references/type-system.md +481 -0
- package/skills/vitest-standard/SKILL.md +82 -0
- package/skills/vitest-standard/examples/service-mock.ts +60 -0
- package/skills/vitest-standard/examples/tdd-calculator.ts +41 -0
- package/skills/vitest-standard/examples/type-stubs.d.ts +18 -0
- package/skills/vitest-standard/references/async-and-errors.md +58 -0
- package/skills/vitest-standard/references/coverage-and-config.md +53 -0
- package/skills/vitest-standard/references/mocking.md +61 -0
- package/skills/vitest-standard/references/tdd-patterns.md +60 -0
- package/dist/github-integration-FOJ4U6I5.js +0 -1
- 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-
|
|
2
|
-
import { logger, GitHubIntegration, ConfigurationError, ResourceNotFoundError, ConnectionError, QueryError, assertNoPathTraversal, ValidationError, MemoryJournalMcpError, validateDateFormatPattern } from './chunk-
|
|
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
|
|
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,
|
|
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",
|
|
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 {
|
|
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
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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.
|
|
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.
|
|
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 =
|
|
4138
|
-
if (milestoneResult.status === "fulfilled"
|
|
4139
|
-
milestoneSummary =
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
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-
|
|
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
|
-
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6460
|
-
|
|
6461
|
-
|
|
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
|
}
|