midnight-mcp 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/resources/code.d.ts +5 -6
- package/dist/resources/code.js +5 -537
- package/dist/resources/content/code-content.d.ts +6 -0
- package/dist/resources/content/code-content.js +541 -0
- package/dist/resources/content/docs-content.d.ts +6 -0
- package/dist/resources/content/docs-content.js +897 -0
- package/dist/resources/content/index.d.ts +6 -0
- package/dist/resources/content/index.js +6 -0
- package/dist/resources/docs.d.ts +5 -6
- package/dist/resources/docs.js +5 -893
- package/dist/resources/index.d.ts +4 -4
- package/dist/resources/index.js +2 -2
- package/dist/tools/repository/constants.d.ts +19 -0
- package/dist/tools/repository/constants.js +103 -0
- package/dist/tools/repository/handlers.d.ts +180 -0
- package/dist/tools/repository/handlers.js +311 -0
- package/dist/tools/repository/index.d.ts +9 -0
- package/dist/tools/repository/index.js +13 -0
- package/dist/tools/repository/schemas.d.ts +111 -0
- package/dist/tools/repository/schemas.js +73 -0
- package/dist/tools/repository/tools.d.ts +7 -0
- package/dist/tools/repository/tools.js +237 -0
- package/dist/tools/repository.d.ts +3 -273
- package/dist/tools/repository.js +4 -700
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { documentationResources, getDocumentation, listDocumentationResources, } from "./docs.js";
|
|
2
|
-
export { codeResources, getCode, listCodeResources
|
|
3
|
-
export { schemaResources, getSchema, listSchemaResources
|
|
4
|
-
export type { ResourceDefinition } from "./
|
|
5
|
-
export declare const allResources: import("./
|
|
2
|
+
export { codeResources, getCode, listCodeResources } from "./code.js";
|
|
3
|
+
export { schemaResources, getSchema, listSchemaResources } from "./schemas.js";
|
|
4
|
+
export type { ResourceDefinition } from "./schemas.js";
|
|
5
|
+
export declare const allResources: import("./schemas.js").ResourceDefinition[];
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/resources/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { documentationResources, getDocumentation, listDocumentationResources, } from "./docs.js";
|
|
2
|
-
export { codeResources, getCode, listCodeResources
|
|
3
|
-
export { schemaResources, getSchema, listSchemaResources
|
|
2
|
+
export { codeResources, getCode, listCodeResources } from "./code.js";
|
|
3
|
+
export { schemaResources, getSchema, listSchemaResources } from "./schemas.js";
|
|
4
4
|
// Combine all resources
|
|
5
5
|
import { documentationResources } from "./docs.js";
|
|
6
6
|
import { codeResources } from "./code.js";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository constants
|
|
3
|
+
* Aliases, example definitions, and configuration data
|
|
4
|
+
*/
|
|
5
|
+
export declare const REPO_ALIASES: Record<string, {
|
|
6
|
+
owner: string;
|
|
7
|
+
repo: string;
|
|
8
|
+
}>;
|
|
9
|
+
export interface ExampleDefinition {
|
|
10
|
+
name: string;
|
|
11
|
+
repository: string;
|
|
12
|
+
description: string;
|
|
13
|
+
category: string;
|
|
14
|
+
complexity: "beginner" | "intermediate" | "advanced";
|
|
15
|
+
mainFile: string;
|
|
16
|
+
features: string[];
|
|
17
|
+
}
|
|
18
|
+
export declare const EXAMPLES: ExampleDefinition[];
|
|
19
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository constants
|
|
3
|
+
* Aliases, example definitions, and configuration data
|
|
4
|
+
*/
|
|
5
|
+
// Repository name mapping
|
|
6
|
+
export const REPO_ALIASES = {
|
|
7
|
+
// Core Language & SDK
|
|
8
|
+
compact: { owner: "midnightntwrk", repo: "compact" },
|
|
9
|
+
"midnight-js": { owner: "midnightntwrk", repo: "midnight-js" },
|
|
10
|
+
js: { owner: "midnightntwrk", repo: "midnight-js" },
|
|
11
|
+
sdk: { owner: "midnightntwrk", repo: "midnight-js" },
|
|
12
|
+
// Documentation
|
|
13
|
+
docs: { owner: "midnightntwrk", repo: "midnight-docs" },
|
|
14
|
+
"midnight-docs": { owner: "midnightntwrk", repo: "midnight-docs" },
|
|
15
|
+
// Example DApps
|
|
16
|
+
"example-counter": { owner: "midnightntwrk", repo: "example-counter" },
|
|
17
|
+
counter: { owner: "midnightntwrk", repo: "example-counter" },
|
|
18
|
+
"example-bboard": { owner: "midnightntwrk", repo: "example-bboard" },
|
|
19
|
+
bboard: { owner: "midnightntwrk", repo: "example-bboard" },
|
|
20
|
+
"example-dex": { owner: "midnightntwrk", repo: "example-dex" },
|
|
21
|
+
dex: { owner: "midnightntwrk", repo: "example-dex" },
|
|
22
|
+
// Developer Tools
|
|
23
|
+
"create-mn-app": { owner: "midnightntwrk", repo: "create-mn-app" },
|
|
24
|
+
"midnight-wallet": { owner: "midnightntwrk", repo: "midnight-wallet" },
|
|
25
|
+
wallet: { owner: "midnightntwrk", repo: "midnight-wallet" },
|
|
26
|
+
// Infrastructure
|
|
27
|
+
"midnight-indexer": { owner: "midnightntwrk", repo: "midnight-indexer" },
|
|
28
|
+
indexer: { owner: "midnightntwrk", repo: "midnight-indexer" },
|
|
29
|
+
"midnight-node-docker": {
|
|
30
|
+
owner: "midnightntwrk",
|
|
31
|
+
repo: "midnight-node-docker",
|
|
32
|
+
},
|
|
33
|
+
node: { owner: "midnightntwrk", repo: "midnight-node-docker" },
|
|
34
|
+
// APIs & Connectors
|
|
35
|
+
"midnight-dapp-connector-api": {
|
|
36
|
+
owner: "midnightntwrk",
|
|
37
|
+
repo: "midnight-dapp-connector-api",
|
|
38
|
+
},
|
|
39
|
+
connector: { owner: "midnightntwrk", repo: "midnight-dapp-connector-api" },
|
|
40
|
+
// Tooling
|
|
41
|
+
"compact-tree-sitter": {
|
|
42
|
+
owner: "midnightntwrk",
|
|
43
|
+
repo: "compact-tree-sitter",
|
|
44
|
+
},
|
|
45
|
+
// Community
|
|
46
|
+
"midnight-awesome-dapps": {
|
|
47
|
+
owner: "midnightntwrk",
|
|
48
|
+
repo: "midnight-awesome-dapps",
|
|
49
|
+
},
|
|
50
|
+
awesome: { owner: "midnightntwrk", repo: "midnight-awesome-dapps" },
|
|
51
|
+
"contributor-hub": { owner: "midnightntwrk", repo: "contributor-hub" },
|
|
52
|
+
// Partner Libraries (OpenZeppelin)
|
|
53
|
+
"compact-contracts": { owner: "OpenZeppelin", repo: "compact-contracts" },
|
|
54
|
+
openzeppelin: { owner: "OpenZeppelin", repo: "compact-contracts" },
|
|
55
|
+
oz: { owner: "OpenZeppelin", repo: "compact-contracts" },
|
|
56
|
+
};
|
|
57
|
+
export const EXAMPLES = [
|
|
58
|
+
{
|
|
59
|
+
name: "Counter",
|
|
60
|
+
repository: "midnightntwrk/example-counter",
|
|
61
|
+
description: "Simple counter contract demonstrating basic Compact concepts. Perfect for learning ledger state, circuits, and witnesses.",
|
|
62
|
+
category: "counter",
|
|
63
|
+
complexity: "beginner",
|
|
64
|
+
mainFile: "contract/src/counter.compact",
|
|
65
|
+
features: [
|
|
66
|
+
"Ledger state management",
|
|
67
|
+
"Basic circuit definition",
|
|
68
|
+
"Counter increment/decrement",
|
|
69
|
+
"TypeScript integration",
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: "Bulletin Board",
|
|
74
|
+
repository: "midnightntwrk/example-bboard",
|
|
75
|
+
description: "Full DApp example with CLI and React UI. Demonstrates posting messages with privacy features.",
|
|
76
|
+
category: "bboard",
|
|
77
|
+
complexity: "intermediate",
|
|
78
|
+
mainFile: "contract/src/bboard.compact",
|
|
79
|
+
features: [
|
|
80
|
+
"Private messaging",
|
|
81
|
+
"React frontend",
|
|
82
|
+
"CLI interface",
|
|
83
|
+
"Wallet integration",
|
|
84
|
+
"Disclose operations",
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: "DEX (Decentralized Exchange)",
|
|
89
|
+
repository: "midnightntwrk/example-dex",
|
|
90
|
+
description: "Advanced DApp example showing token swaps and liquidity pools with privacy-preserving transactions.",
|
|
91
|
+
category: "dex",
|
|
92
|
+
complexity: "advanced",
|
|
93
|
+
mainFile: "contract/src/dex.compact",
|
|
94
|
+
features: [
|
|
95
|
+
"Token swaps",
|
|
96
|
+
"Liquidity pools",
|
|
97
|
+
"Privacy-preserving trades",
|
|
98
|
+
"Price calculations",
|
|
99
|
+
"Advanced state management",
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
];
|
|
103
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository handler functions
|
|
3
|
+
* Business logic for repository-related MCP tools
|
|
4
|
+
*/
|
|
5
|
+
import type { GetFileInput, ListExamplesInput, GetLatestUpdatesInput, GetVersionInfoInput, CheckBreakingChangesInput, GetMigrationGuideInput, GetFileAtVersionInput, CompareSyntaxInput, GetLatestSyntaxInput } from "./schemas.js";
|
|
6
|
+
/**
|
|
7
|
+
* Resolve repository name alias to owner/repo
|
|
8
|
+
*/
|
|
9
|
+
export declare function resolveRepo(repoName?: string): {
|
|
10
|
+
owner: string;
|
|
11
|
+
repo: string;
|
|
12
|
+
} | null;
|
|
13
|
+
/**
|
|
14
|
+
* Retrieve a specific file from Midnight repositories
|
|
15
|
+
*/
|
|
16
|
+
export declare function getFile(input: GetFileInput): Promise<{
|
|
17
|
+
error: string;
|
|
18
|
+
suggestion: string;
|
|
19
|
+
repository?: undefined;
|
|
20
|
+
content?: undefined;
|
|
21
|
+
path?: undefined;
|
|
22
|
+
sha?: undefined;
|
|
23
|
+
size?: undefined;
|
|
24
|
+
url?: undefined;
|
|
25
|
+
} | {
|
|
26
|
+
error: string;
|
|
27
|
+
repository: string;
|
|
28
|
+
suggestion: string;
|
|
29
|
+
content?: undefined;
|
|
30
|
+
path?: undefined;
|
|
31
|
+
sha?: undefined;
|
|
32
|
+
size?: undefined;
|
|
33
|
+
url?: undefined;
|
|
34
|
+
} | {
|
|
35
|
+
content: string;
|
|
36
|
+
path: string;
|
|
37
|
+
repository: string;
|
|
38
|
+
sha: string;
|
|
39
|
+
size: number;
|
|
40
|
+
url: string;
|
|
41
|
+
error?: undefined;
|
|
42
|
+
suggestion?: undefined;
|
|
43
|
+
}>;
|
|
44
|
+
/**
|
|
45
|
+
* List available example contracts and DApps
|
|
46
|
+
*/
|
|
47
|
+
export declare function listExamples(input: ListExamplesInput): Promise<{
|
|
48
|
+
examples: {
|
|
49
|
+
name: string;
|
|
50
|
+
repository: string;
|
|
51
|
+
description: string;
|
|
52
|
+
complexity: "beginner" | "intermediate" | "advanced";
|
|
53
|
+
mainFile: string;
|
|
54
|
+
features: string[];
|
|
55
|
+
githubUrl: string;
|
|
56
|
+
}[];
|
|
57
|
+
totalCount: number;
|
|
58
|
+
categories: string[];
|
|
59
|
+
}>;
|
|
60
|
+
/**
|
|
61
|
+
* Retrieve recent changes across Midnight repositories
|
|
62
|
+
*/
|
|
63
|
+
export declare function getLatestUpdates(input: GetLatestUpdatesInput): Promise<{
|
|
64
|
+
summary: {
|
|
65
|
+
since: string;
|
|
66
|
+
totalCommits: number;
|
|
67
|
+
activeRepositories: number;
|
|
68
|
+
checkedRepositories: number;
|
|
69
|
+
};
|
|
70
|
+
updates: {
|
|
71
|
+
repository: string;
|
|
72
|
+
commitCount: number;
|
|
73
|
+
latestCommit: {
|
|
74
|
+
message: string;
|
|
75
|
+
date: string;
|
|
76
|
+
author: string;
|
|
77
|
+
url: string;
|
|
78
|
+
} | null;
|
|
79
|
+
recentCommits: {
|
|
80
|
+
message: string;
|
|
81
|
+
date: string;
|
|
82
|
+
sha: string;
|
|
83
|
+
}[];
|
|
84
|
+
}[];
|
|
85
|
+
}>;
|
|
86
|
+
/**
|
|
87
|
+
* Get version and release info for a repository
|
|
88
|
+
*/
|
|
89
|
+
export declare function getVersionInfo(input: GetVersionInfoInput): Promise<{
|
|
90
|
+
repository: string;
|
|
91
|
+
latestVersion: string;
|
|
92
|
+
latestStableVersion: string;
|
|
93
|
+
publishedAt: string | null;
|
|
94
|
+
releaseNotes: string | null;
|
|
95
|
+
recentReleases: {
|
|
96
|
+
version: string;
|
|
97
|
+
date: string;
|
|
98
|
+
isPrerelease: boolean;
|
|
99
|
+
url: string;
|
|
100
|
+
}[];
|
|
101
|
+
recentBreakingChanges: string[];
|
|
102
|
+
versionContext: string;
|
|
103
|
+
}>;
|
|
104
|
+
/**
|
|
105
|
+
* Check for breaking changes since a specific version
|
|
106
|
+
*/
|
|
107
|
+
export declare function checkBreakingChanges(input: CheckBreakingChangesInput): Promise<{
|
|
108
|
+
repository: string;
|
|
109
|
+
currentVersion: string;
|
|
110
|
+
latestVersion: string | null;
|
|
111
|
+
isOutdated: boolean;
|
|
112
|
+
versionsBehind: number;
|
|
113
|
+
hasBreakingChanges: boolean;
|
|
114
|
+
breakingChanges: string[];
|
|
115
|
+
recommendation: string;
|
|
116
|
+
}>;
|
|
117
|
+
/**
|
|
118
|
+
* Get migration guide between versions
|
|
119
|
+
*/
|
|
120
|
+
export declare function getMigrationGuide(input: GetMigrationGuideInput): Promise<{
|
|
121
|
+
repository: string;
|
|
122
|
+
from: string;
|
|
123
|
+
to: string;
|
|
124
|
+
summary: {
|
|
125
|
+
breakingChangesCount: number;
|
|
126
|
+
deprecationsCount: number;
|
|
127
|
+
newFeaturesCount: number;
|
|
128
|
+
};
|
|
129
|
+
breakingChanges: string[];
|
|
130
|
+
deprecations: string[];
|
|
131
|
+
newFeatures: string[];
|
|
132
|
+
migrationSteps: string[];
|
|
133
|
+
migrationDifficulty: string;
|
|
134
|
+
}>;
|
|
135
|
+
/**
|
|
136
|
+
* Get a file at a specific version - critical for version-accurate recommendations
|
|
137
|
+
*/
|
|
138
|
+
export declare function getFileAtVersion(input: GetFileAtVersionInput): Promise<{
|
|
139
|
+
repository: string;
|
|
140
|
+
path: string;
|
|
141
|
+
version: string;
|
|
142
|
+
content: string;
|
|
143
|
+
note: string;
|
|
144
|
+
}>;
|
|
145
|
+
/**
|
|
146
|
+
* Compare syntax between two versions - shows what changed
|
|
147
|
+
*/
|
|
148
|
+
export declare function compareSyntax(input: CompareSyntaxInput): Promise<{
|
|
149
|
+
repository: string;
|
|
150
|
+
path: string;
|
|
151
|
+
oldVersion: string;
|
|
152
|
+
newVersion: string;
|
|
153
|
+
hasDifferences: boolean;
|
|
154
|
+
oldContent: string | null;
|
|
155
|
+
newContent: string | null;
|
|
156
|
+
recommendation: string;
|
|
157
|
+
}>;
|
|
158
|
+
/**
|
|
159
|
+
* Get the latest syntax reference for Compact language
|
|
160
|
+
* This is the source of truth for writing valid, compilable contracts
|
|
161
|
+
*/
|
|
162
|
+
export declare function getLatestSyntax(input: GetLatestSyntaxInput): Promise<{
|
|
163
|
+
repository: string;
|
|
164
|
+
version: string;
|
|
165
|
+
warning: string;
|
|
166
|
+
syntaxFiles: never[];
|
|
167
|
+
examplePaths: string[];
|
|
168
|
+
note?: undefined;
|
|
169
|
+
} | {
|
|
170
|
+
repository: string;
|
|
171
|
+
version: string;
|
|
172
|
+
syntaxFiles: {
|
|
173
|
+
path: string;
|
|
174
|
+
content: string;
|
|
175
|
+
}[];
|
|
176
|
+
note: string;
|
|
177
|
+
warning?: undefined;
|
|
178
|
+
examplePaths?: undefined;
|
|
179
|
+
}>;
|
|
180
|
+
//# sourceMappingURL=handlers.d.ts.map
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository handler functions
|
|
3
|
+
* Business logic for repository-related MCP tools
|
|
4
|
+
*/
|
|
5
|
+
import { githubClient } from "../../pipeline/index.js";
|
|
6
|
+
import { releaseTracker } from "../../pipeline/releases.js";
|
|
7
|
+
import { logger, DEFAULT_REPOSITORIES } from "../../utils/index.js";
|
|
8
|
+
import { REPO_ALIASES, EXAMPLES } from "./constants.js";
|
|
9
|
+
/**
|
|
10
|
+
* Resolve repository name alias to owner/repo
|
|
11
|
+
*/
|
|
12
|
+
export function resolveRepo(repoName) {
|
|
13
|
+
// Default to compact if not provided
|
|
14
|
+
const name = repoName || "compact";
|
|
15
|
+
const normalized = name.toLowerCase().replace(/^midnightntwrk\//, "");
|
|
16
|
+
const alias = REPO_ALIASES[normalized];
|
|
17
|
+
if (alias)
|
|
18
|
+
return alias;
|
|
19
|
+
// Try to find in configured repos
|
|
20
|
+
for (const config of DEFAULT_REPOSITORIES) {
|
|
21
|
+
if (config.repo.toLowerCase() === normalized) {
|
|
22
|
+
return { owner: config.owner, repo: config.repo };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// Assume it's a full org/repo name
|
|
26
|
+
if (name.includes("/")) {
|
|
27
|
+
const [owner, repo] = name.split("/");
|
|
28
|
+
return { owner, repo };
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Retrieve a specific file from Midnight repositories
|
|
34
|
+
*/
|
|
35
|
+
export async function getFile(input) {
|
|
36
|
+
logger.debug("Getting file", { repo: input.repo, path: input.path });
|
|
37
|
+
const repoInfo = resolveRepo(input.repo);
|
|
38
|
+
if (!repoInfo) {
|
|
39
|
+
return {
|
|
40
|
+
error: `Unknown repository: ${input.repo}`,
|
|
41
|
+
suggestion: `Valid repositories: ${Object.keys(REPO_ALIASES).join(", ")}`,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const file = await githubClient.getFileContent(repoInfo.owner, repoInfo.repo, input.path, input.ref);
|
|
45
|
+
if (!file) {
|
|
46
|
+
return {
|
|
47
|
+
error: `File not found: ${input.path}`,
|
|
48
|
+
repository: `${repoInfo.owner}/${repoInfo.repo}`,
|
|
49
|
+
suggestion: "Check the file path and try again. Use midnight:list-examples to see available example files.",
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
content: file.content,
|
|
54
|
+
path: file.path,
|
|
55
|
+
repository: `${repoInfo.owner}/${repoInfo.repo}`,
|
|
56
|
+
sha: file.sha,
|
|
57
|
+
size: file.size,
|
|
58
|
+
url: `https://github.com/${repoInfo.owner}/${repoInfo.repo}/blob/${input.ref || "main"}/${file.path}`,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* List available example contracts and DApps
|
|
63
|
+
*/
|
|
64
|
+
export async function listExamples(input) {
|
|
65
|
+
logger.debug("Listing examples", { category: input.category });
|
|
66
|
+
let filteredExamples = EXAMPLES;
|
|
67
|
+
if (input.category && input.category !== "all") {
|
|
68
|
+
filteredExamples = EXAMPLES.filter((e) => e.category === input.category);
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
examples: filteredExamples.map((e) => ({
|
|
72
|
+
name: e.name,
|
|
73
|
+
repository: e.repository,
|
|
74
|
+
description: e.description,
|
|
75
|
+
complexity: e.complexity,
|
|
76
|
+
mainFile: e.mainFile,
|
|
77
|
+
features: e.features,
|
|
78
|
+
githubUrl: `https://github.com/${e.repository}`,
|
|
79
|
+
})),
|
|
80
|
+
totalCount: filteredExamples.length,
|
|
81
|
+
categories: [...new Set(EXAMPLES.map((e) => e.category))],
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Retrieve recent changes across Midnight repositories
|
|
86
|
+
*/
|
|
87
|
+
export async function getLatestUpdates(input) {
|
|
88
|
+
logger.debug("Getting latest updates", input);
|
|
89
|
+
// Default to last 7 days
|
|
90
|
+
const since = input.since || new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();
|
|
91
|
+
const repos = input.repos?.map(resolveRepo).filter(Boolean) ||
|
|
92
|
+
DEFAULT_REPOSITORIES.map((r) => ({ owner: r.owner, repo: r.repo }));
|
|
93
|
+
const updates = [];
|
|
94
|
+
for (const repo of repos) {
|
|
95
|
+
if (!repo)
|
|
96
|
+
continue;
|
|
97
|
+
const commits = await githubClient.getRecentCommits(repo.owner, repo.repo, since, 10);
|
|
98
|
+
if (commits.length > 0) {
|
|
99
|
+
updates.push({
|
|
100
|
+
repository: `${repo.owner}/${repo.repo}`,
|
|
101
|
+
commits,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Sort by most recent commit
|
|
106
|
+
updates.sort((a, b) => {
|
|
107
|
+
const aDate = a.commits[0]?.date || "";
|
|
108
|
+
const bDate = b.commits[0]?.date || "";
|
|
109
|
+
return bDate.localeCompare(aDate);
|
|
110
|
+
});
|
|
111
|
+
// Generate summary
|
|
112
|
+
const totalCommits = updates.reduce((sum, u) => sum + u.commits.length, 0);
|
|
113
|
+
const activeRepos = updates.filter((u) => u.commits.length > 0).length;
|
|
114
|
+
return {
|
|
115
|
+
summary: {
|
|
116
|
+
since,
|
|
117
|
+
totalCommits,
|
|
118
|
+
activeRepositories: activeRepos,
|
|
119
|
+
checkedRepositories: repos.length,
|
|
120
|
+
},
|
|
121
|
+
updates: updates.map((u) => ({
|
|
122
|
+
repository: u.repository,
|
|
123
|
+
commitCount: u.commits.length,
|
|
124
|
+
latestCommit: u.commits[0]
|
|
125
|
+
? {
|
|
126
|
+
message: u.commits[0].message.split("\n")[0], // First line only
|
|
127
|
+
date: u.commits[0].date,
|
|
128
|
+
author: u.commits[0].author,
|
|
129
|
+
url: u.commits[0].url,
|
|
130
|
+
}
|
|
131
|
+
: null,
|
|
132
|
+
recentCommits: u.commits.slice(0, 5).map((c) => ({
|
|
133
|
+
message: c.message.split("\n")[0],
|
|
134
|
+
date: c.date,
|
|
135
|
+
sha: c.sha.substring(0, 7),
|
|
136
|
+
})),
|
|
137
|
+
})),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get version and release info for a repository
|
|
142
|
+
*/
|
|
143
|
+
export async function getVersionInfo(input) {
|
|
144
|
+
logger.debug("Getting version info", input);
|
|
145
|
+
const resolved = resolveRepo(input.repo);
|
|
146
|
+
if (!resolved) {
|
|
147
|
+
throw new Error(`Unknown repository: ${input.repo}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
|
|
148
|
+
}
|
|
149
|
+
const versionInfo = await releaseTracker.getVersionInfo(resolved.owner, resolved.repo);
|
|
150
|
+
return {
|
|
151
|
+
repository: `${resolved.owner}/${resolved.repo}`,
|
|
152
|
+
latestVersion: versionInfo.latestRelease?.tag || "No releases found",
|
|
153
|
+
latestStableVersion: versionInfo.latestStableRelease?.tag || "No stable releases",
|
|
154
|
+
publishedAt: versionInfo.latestRelease?.publishedAt || null,
|
|
155
|
+
releaseNotes: versionInfo.latestRelease?.body || null,
|
|
156
|
+
recentReleases: versionInfo.recentReleases.slice(0, 5).map((r) => ({
|
|
157
|
+
version: r.tag,
|
|
158
|
+
date: r.publishedAt.split("T")[0],
|
|
159
|
+
isPrerelease: r.isPrerelease,
|
|
160
|
+
url: r.url,
|
|
161
|
+
})),
|
|
162
|
+
recentBreakingChanges: versionInfo.changelog
|
|
163
|
+
.slice(0, 3)
|
|
164
|
+
.flatMap((c) => c.changes.breaking)
|
|
165
|
+
.slice(0, 10),
|
|
166
|
+
versionContext: releaseTracker.getVersionContext(versionInfo),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Check for breaking changes since a specific version
|
|
171
|
+
*/
|
|
172
|
+
export async function checkBreakingChanges(input) {
|
|
173
|
+
logger.debug("Checking breaking changes", input);
|
|
174
|
+
const resolved = resolveRepo(input.repo);
|
|
175
|
+
if (!resolved) {
|
|
176
|
+
throw new Error(`Unknown repository: ${input.repo}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
|
|
177
|
+
}
|
|
178
|
+
const outdatedInfo = await releaseTracker.isOutdated(resolved.owner, resolved.repo, input.currentVersion);
|
|
179
|
+
const breakingChanges = await releaseTracker.getBreakingChangesSince(resolved.owner, resolved.repo, input.currentVersion);
|
|
180
|
+
return {
|
|
181
|
+
repository: `${resolved.owner}/${resolved.repo}`,
|
|
182
|
+
currentVersion: input.currentVersion,
|
|
183
|
+
latestVersion: outdatedInfo.latestVersion,
|
|
184
|
+
isOutdated: outdatedInfo.isOutdated,
|
|
185
|
+
versionsBehind: outdatedInfo.versionsBehind,
|
|
186
|
+
hasBreakingChanges: outdatedInfo.hasBreakingChanges,
|
|
187
|
+
breakingChanges: breakingChanges,
|
|
188
|
+
recommendation: outdatedInfo.hasBreakingChanges
|
|
189
|
+
? `⚠️ Breaking changes detected! Review the ${breakingChanges.length} breaking change(s) before upgrading.`
|
|
190
|
+
: outdatedInfo.isOutdated
|
|
191
|
+
? `✅ Safe to upgrade. No breaking changes detected since ${input.currentVersion}.`
|
|
192
|
+
: `✅ You're on the latest version.`,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Get migration guide between versions
|
|
197
|
+
*/
|
|
198
|
+
export async function getMigrationGuide(input) {
|
|
199
|
+
logger.debug("Getting migration guide", input);
|
|
200
|
+
const resolved = resolveRepo(input.repo);
|
|
201
|
+
if (!resolved) {
|
|
202
|
+
throw new Error(`Unknown repository: ${input.repo}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
|
|
203
|
+
}
|
|
204
|
+
const guide = await releaseTracker.getMigrationGuide(resolved.owner, resolved.repo, input.fromVersion, input.toVersion);
|
|
205
|
+
return {
|
|
206
|
+
repository: `${resolved.owner}/${resolved.repo}`,
|
|
207
|
+
from: guide.from,
|
|
208
|
+
to: guide.to,
|
|
209
|
+
summary: {
|
|
210
|
+
breakingChangesCount: guide.breakingChanges.length,
|
|
211
|
+
deprecationsCount: guide.deprecations.length,
|
|
212
|
+
newFeaturesCount: guide.newFeatures.length,
|
|
213
|
+
},
|
|
214
|
+
breakingChanges: guide.breakingChanges,
|
|
215
|
+
deprecations: guide.deprecations,
|
|
216
|
+
newFeatures: guide.newFeatures,
|
|
217
|
+
migrationSteps: guide.migrationSteps,
|
|
218
|
+
migrationDifficulty: guide.breakingChanges.length === 0
|
|
219
|
+
? "Easy - No breaking changes"
|
|
220
|
+
: guide.breakingChanges.length <= 3
|
|
221
|
+
? "Moderate - Few breaking changes"
|
|
222
|
+
: "Complex - Multiple breaking changes, plan carefully",
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Get a file at a specific version - critical for version-accurate recommendations
|
|
227
|
+
*/
|
|
228
|
+
export async function getFileAtVersion(input) {
|
|
229
|
+
logger.debug("Getting file at version", input);
|
|
230
|
+
const resolved = resolveRepo(input.repo);
|
|
231
|
+
if (!resolved) {
|
|
232
|
+
throw new Error(`Unknown repository: ${input.repo}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
|
|
233
|
+
}
|
|
234
|
+
const result = await releaseTracker.getFileAtVersion(resolved.owner, resolved.repo, input.path, input.version);
|
|
235
|
+
if (!result) {
|
|
236
|
+
throw new Error(`File not found: ${input.path} at version ${input.version} in ${input.repo}`);
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
repository: `${resolved.owner}/${resolved.repo}`,
|
|
240
|
+
path: input.path,
|
|
241
|
+
version: result.version,
|
|
242
|
+
content: result.content,
|
|
243
|
+
note: `This is the exact content at version ${result.version}. Use this as the source of truth for syntax and API at this version.`,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Compare syntax between two versions - shows what changed
|
|
248
|
+
*/
|
|
249
|
+
export async function compareSyntax(input) {
|
|
250
|
+
logger.debug("Comparing syntax between versions", input);
|
|
251
|
+
const resolved = resolveRepo(input.repo);
|
|
252
|
+
if (!resolved) {
|
|
253
|
+
throw new Error(`Unknown repository: ${input.repo}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
|
|
254
|
+
}
|
|
255
|
+
// If no newVersion specified, get latest
|
|
256
|
+
let newVersion = input.newVersion;
|
|
257
|
+
if (!newVersion) {
|
|
258
|
+
const versionInfo = await releaseTracker.getVersionInfo(resolved.owner, resolved.repo);
|
|
259
|
+
newVersion =
|
|
260
|
+
versionInfo.latestStableRelease?.tag ||
|
|
261
|
+
versionInfo.latestRelease?.tag ||
|
|
262
|
+
"main";
|
|
263
|
+
}
|
|
264
|
+
const comparison = await releaseTracker.compareSyntax(resolved.owner, resolved.repo, input.path, input.oldVersion, newVersion);
|
|
265
|
+
return {
|
|
266
|
+
repository: `${resolved.owner}/${resolved.repo}`,
|
|
267
|
+
path: input.path,
|
|
268
|
+
oldVersion: comparison.oldVersion,
|
|
269
|
+
newVersion: comparison.newVersion,
|
|
270
|
+
hasDifferences: comparison.hasDifferences,
|
|
271
|
+
oldContent: comparison.oldContent,
|
|
272
|
+
newContent: comparison.newContent,
|
|
273
|
+
recommendation: comparison.hasDifferences
|
|
274
|
+
? `⚠️ This file has changed between ${comparison.oldVersion} and ${comparison.newVersion}. Review the differences before using code patterns from the old version.`
|
|
275
|
+
: `✅ No changes in this file between versions.`,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Get the latest syntax reference for Compact language
|
|
280
|
+
* This is the source of truth for writing valid, compilable contracts
|
|
281
|
+
*/
|
|
282
|
+
export async function getLatestSyntax(input) {
|
|
283
|
+
logger.debug("Getting latest syntax reference", input);
|
|
284
|
+
const resolved = resolveRepo(input.repo);
|
|
285
|
+
if (!resolved) {
|
|
286
|
+
throw new Error(`Unknown repository: ${input.repo}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
|
|
287
|
+
}
|
|
288
|
+
const reference = await releaseTracker.getLatestSyntaxReference(resolved.owner, resolved.repo);
|
|
289
|
+
if (!reference || reference.syntaxFiles.length === 0) {
|
|
290
|
+
// Fallback: get example contracts as syntax reference
|
|
291
|
+
const versionInfo = await releaseTracker.getVersionInfo(resolved.owner, resolved.repo);
|
|
292
|
+
const version = versionInfo.latestStableRelease?.tag || "main";
|
|
293
|
+
return {
|
|
294
|
+
repository: `${resolved.owner}/${resolved.repo}`,
|
|
295
|
+
version,
|
|
296
|
+
warning: "No grammar documentation found. Use example contracts as reference.",
|
|
297
|
+
syntaxFiles: [],
|
|
298
|
+
examplePaths: ["examples/", "test/", "contracts/"],
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
repository: `${resolved.owner}/${resolved.repo}`,
|
|
303
|
+
version: reference.version,
|
|
304
|
+
syntaxFiles: reference.syntaxFiles.map((f) => ({
|
|
305
|
+
path: f.path,
|
|
306
|
+
content: f.content,
|
|
307
|
+
})),
|
|
308
|
+
note: `This is the authoritative syntax reference at version ${reference.version}. Use this to ensure contracts are compilable.`,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
//# sourceMappingURL=handlers.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository module exports
|
|
3
|
+
* Barrel file for repository-related tools
|
|
4
|
+
*/
|
|
5
|
+
export { GetFileInputSchema, ListExamplesInputSchema, GetLatestUpdatesInputSchema, GetVersionInfoInputSchema, CheckBreakingChangesInputSchema, GetMigrationGuideInputSchema, GetFileAtVersionInputSchema, CompareSyntaxInputSchema, GetLatestSyntaxInputSchema, type GetFileInput, type ListExamplesInput, type GetLatestUpdatesInput, type GetVersionInfoInput, type CheckBreakingChangesInput, type GetMigrationGuideInput, type GetFileAtVersionInput, type CompareSyntaxInput, type GetLatestSyntaxInput, } from "./schemas.js";
|
|
6
|
+
export { REPO_ALIASES, EXAMPLES, type ExampleDefinition } from "./constants.js";
|
|
7
|
+
export { resolveRepo, getFile, listExamples, getLatestUpdates, getVersionInfo, checkBreakingChanges, getMigrationGuide, getFileAtVersion, compareSyntax, getLatestSyntax, } from "./handlers.js";
|
|
8
|
+
export { repositoryTools } from "./tools.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository module exports
|
|
3
|
+
* Barrel file for repository-related tools
|
|
4
|
+
*/
|
|
5
|
+
// Schemas and types
|
|
6
|
+
export { GetFileInputSchema, ListExamplesInputSchema, GetLatestUpdatesInputSchema, GetVersionInfoInputSchema, CheckBreakingChangesInputSchema, GetMigrationGuideInputSchema, GetFileAtVersionInputSchema, CompareSyntaxInputSchema, GetLatestSyntaxInputSchema, } from "./schemas.js";
|
|
7
|
+
// Constants
|
|
8
|
+
export { REPO_ALIASES, EXAMPLES } from "./constants.js";
|
|
9
|
+
// Handlers
|
|
10
|
+
export { resolveRepo, getFile, listExamples, getLatestUpdates, getVersionInfo, checkBreakingChanges, getMigrationGuide, getFileAtVersion, compareSyntax, getLatestSyntax, } from "./handlers.js";
|
|
11
|
+
// Tools
|
|
12
|
+
export { repositoryTools } from "./tools.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|