@better-i18n/mcp 0.15.5 → 0.16.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 +41 -3
- package/dist/tools/getTranslations.d.ts +11 -4
- package/dist/tools/getTranslations.d.ts.map +1 -1
- package/dist/tools/getTranslations.js +21 -8
- package/dist/tools/getTranslations.js.map +1 -1
- package/dist/tools/proposeLanguageEdits.d.ts.map +1 -1
- package/dist/tools/proposeLanguageEdits.js +10 -0
- package/dist/tools/proposeLanguageEdits.js.map +1 -1
- package/dist/tools/proposeLanguages.d.ts.map +1 -1
- package/dist/tools/proposeLanguages.js +4 -0
- package/dist/tools/proposeLanguages.js.map +1 -1
- package/package.json +3 -2
- package/dist/__tests__/base-tool.test.d.ts +0 -2
- package/dist/__tests__/base-tool.test.d.ts.map +0 -1
- package/dist/__tests__/base-tool.test.js +0 -193
- package/dist/__tests__/base-tool.test.js.map +0 -1
- package/dist/__tests__/contract.test.d.ts +0 -24
- package/dist/__tests__/contract.test.d.ts.map +0 -1
- package/dist/__tests__/contract.test.js +0 -919
- package/dist/__tests__/contract.test.js.map +0 -1
- package/dist/__tests__/fixtures/mock-client.d.ts +0 -11
- package/dist/__tests__/fixtures/mock-client.d.ts.map +0 -1
- package/dist/__tests__/fixtures/mock-client.js +0 -33
- package/dist/__tests__/fixtures/mock-client.js.map +0 -1
- package/dist/__tests__/helpers.d.ts +0 -10
- package/dist/__tests__/helpers.d.ts.map +0 -1
- package/dist/__tests__/helpers.js +0 -27
- package/dist/__tests__/helpers.js.map +0 -1
- package/dist/__tests__/schema-alignment.test.d.ts +0 -15
- package/dist/__tests__/schema-alignment.test.d.ts.map +0 -1
- package/dist/__tests__/schema-alignment.test.js +0 -1011
- package/dist/__tests__/schema-alignment.test.js.map +0 -1
- package/dist/__tests__/server-dispatch.test.d.ts +0 -10
- package/dist/__tests__/server-dispatch.test.d.ts.map +0 -1
- package/dist/__tests__/server-dispatch.test.js +0 -202
- package/dist/__tests__/server-dispatch.test.js.map +0 -1
- package/dist/__tests__/version-check.test.d.ts +0 -2
- package/dist/__tests__/version-check.test.d.ts.map +0 -1
- package/dist/__tests__/version-check.test.js +0 -89
- package/dist/__tests__/version-check.test.js.map +0 -1
- package/dist/tools/__tests__/createKeys.test.d.ts +0 -2
- package/dist/tools/__tests__/createKeys.test.d.ts.map +0 -1
- package/dist/tools/__tests__/createKeys.test.js +0 -139
- package/dist/tools/__tests__/createKeys.test.js.map +0 -1
- package/dist/tools/__tests__/deleteKeys.test.d.ts +0 -2
- package/dist/tools/__tests__/deleteKeys.test.d.ts.map +0 -1
- package/dist/tools/__tests__/deleteKeys.test.js +0 -91
- package/dist/tools/__tests__/deleteKeys.test.js.map +0 -1
- package/dist/tools/__tests__/getPendingChanges.test.d.ts +0 -2
- package/dist/tools/__tests__/getPendingChanges.test.d.ts.map +0 -1
- package/dist/tools/__tests__/getPendingChanges.test.js +0 -50
- package/dist/tools/__tests__/getPendingChanges.test.js.map +0 -1
- package/dist/tools/__tests__/getProject.test.d.ts +0 -2
- package/dist/tools/__tests__/getProject.test.d.ts.map +0 -1
- package/dist/tools/__tests__/getProject.test.js +0 -55
- package/dist/tools/__tests__/getProject.test.js.map +0 -1
- package/dist/tools/__tests__/getSync.test.d.ts +0 -2
- package/dist/tools/__tests__/getSync.test.d.ts.map +0 -1
- package/dist/tools/__tests__/getSync.test.js +0 -42
- package/dist/tools/__tests__/getSync.test.js.map +0 -1
- package/dist/tools/__tests__/getSyncs.test.d.ts +0 -2
- package/dist/tools/__tests__/getSyncs.test.d.ts.map +0 -1
- package/dist/tools/__tests__/getSyncs.test.js +0 -66
- package/dist/tools/__tests__/getSyncs.test.js.map +0 -1
- package/dist/tools/__tests__/getTranslations.test.d.ts +0 -2
- package/dist/tools/__tests__/getTranslations.test.d.ts.map +0 -1
- package/dist/tools/__tests__/getTranslations.test.js +0 -114
- package/dist/tools/__tests__/getTranslations.test.js.map +0 -1
- package/dist/tools/__tests__/listKeys.test.d.ts +0 -2
- package/dist/tools/__tests__/listKeys.test.d.ts.map +0 -1
- package/dist/tools/__tests__/listKeys.test.js +0 -98
- package/dist/tools/__tests__/listKeys.test.js.map +0 -1
- package/dist/tools/__tests__/listProjects.test.d.ts +0 -2
- package/dist/tools/__tests__/listProjects.test.d.ts.map +0 -1
- package/dist/tools/__tests__/listProjects.test.js +0 -45
- package/dist/tools/__tests__/listProjects.test.js.map +0 -1
- package/dist/tools/__tests__/proposeLanguageEdits.test.d.ts +0 -2
- package/dist/tools/__tests__/proposeLanguageEdits.test.d.ts.map +0 -1
- package/dist/tools/__tests__/proposeLanguageEdits.test.js +0 -87
- package/dist/tools/__tests__/proposeLanguageEdits.test.js.map +0 -1
- package/dist/tools/__tests__/proposeLanguages.test.d.ts +0 -2
- package/dist/tools/__tests__/proposeLanguages.test.d.ts.map +0 -1
- package/dist/tools/__tests__/proposeLanguages.test.js +0 -109
- package/dist/tools/__tests__/proposeLanguages.test.js.map +0 -1
- package/dist/tools/__tests__/publishTranslations.test.d.ts +0 -2
- package/dist/tools/__tests__/publishTranslations.test.d.ts.map +0 -1
- package/dist/tools/__tests__/publishTranslations.test.js +0 -127
- package/dist/tools/__tests__/publishTranslations.test.js.map +0 -1
- package/dist/tools/__tests__/updateKeys.test.d.ts +0 -2
- package/dist/tools/__tests__/updateKeys.test.d.ts.map +0 -1
- package/dist/tools/__tests__/updateKeys.test.js +0 -122
- package/dist/tools/__tests__/updateKeys.test.js.map +0 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ MCP (Model Context Protocol) server for [Better i18n](https://better-i18n.com).
|
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
17
|
# With npx (no install needed)
|
|
18
|
-
npx @better-i18n/mcp
|
|
18
|
+
npx -y @better-i18n/mcp@latest
|
|
19
19
|
|
|
20
20
|
# Or install globally
|
|
21
21
|
npm install -g @better-i18n/mcp
|
|
@@ -43,7 +43,9 @@ export const i18n = createI18n({
|
|
|
43
43
|
|
|
44
44
|
The AI assistant will read this file to get the `project` value and include it in all tool calls.
|
|
45
45
|
|
|
46
|
-
### 3. Configure
|
|
46
|
+
### 3. Configure Your AI Client
|
|
47
|
+
|
|
48
|
+
#### Cursor
|
|
47
49
|
|
|
48
50
|
Add to `~/.cursor/mcp.json`:
|
|
49
51
|
|
|
@@ -52,7 +54,43 @@ Add to `~/.cursor/mcp.json`:
|
|
|
52
54
|
"mcpServers": {
|
|
53
55
|
"better-i18n": {
|
|
54
56
|
"command": "npx",
|
|
55
|
-
"args": ["@better-i18n/mcp"],
|
|
57
|
+
"args": ["-y", "@better-i18n/mcp@latest"],
|
|
58
|
+
"env": {
|
|
59
|
+
"BETTER_I18N_API_KEY": "your-api-key-here"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
#### Claude Desktop
|
|
67
|
+
|
|
68
|
+
Add to `claude_desktop_config.json`:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"mcpServers": {
|
|
73
|
+
"better-i18n": {
|
|
74
|
+
"command": "npx",
|
|
75
|
+
"args": ["-y", "@better-i18n/mcp@latest"],
|
|
76
|
+
"env": {
|
|
77
|
+
"BETTER_I18N_API_KEY": "your-api-key-here"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### Claude Code
|
|
85
|
+
|
|
86
|
+
Add to `.claude/settings.json` or `~/.claude/settings.json`:
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"mcpServers": {
|
|
91
|
+
"better-i18n": {
|
|
92
|
+
"command": "npx",
|
|
93
|
+
"args": ["-y", "@better-i18n/mcp@latest"],
|
|
56
94
|
"env": {
|
|
57
95
|
"BETTER_I18N_API_KEY": "your-api-key-here"
|
|
58
96
|
}
|
|
@@ -7,9 +7,15 @@
|
|
|
7
7
|
* USE THIS when you need actual translation text (to translate, review, or update).
|
|
8
8
|
* Use listKeys instead for browsing/exploring keys — it's faster and uses fewer tokens.
|
|
9
9
|
*
|
|
10
|
-
* SEARCH
|
|
11
|
-
* - search
|
|
12
|
-
*
|
|
10
|
+
* SEARCH BEHAVIOR:
|
|
11
|
+
* - search WITHOUT languages: searches key names, source text, AND all translation texts across every language.
|
|
12
|
+
* Use this when you don't know which language the text is in (e.g., user mentions text they saw on screen).
|
|
13
|
+
* - search WITH languages: searches key names, source text (if source language included), AND translations
|
|
14
|
+
* only in the specified languages. Faster and more targeted.
|
|
15
|
+
* - Without search: returns all keys (filtered by other params).
|
|
16
|
+
*
|
|
17
|
+
* FILTER PARAMETERS:
|
|
18
|
+
* - languages: Languages to search in AND return translations for
|
|
13
19
|
* - status: Filter by translation status ("missing", "draft", "published", "all")
|
|
14
20
|
* - namespaces: Filter by namespace(s)
|
|
15
21
|
* - keys: Fetch specific keys by exact name
|
|
@@ -21,9 +27,10 @@
|
|
|
21
27
|
* - hasMore: true when total > limit — use narrower filters to get specific keys
|
|
22
28
|
*
|
|
23
29
|
* EXAMPLES:
|
|
30
|
+
* - Find text in ANY language: { project: "org/project", search: "Mehmet" }
|
|
24
31
|
* - Find "login" in source: { project: "org/project", search: "login" }
|
|
25
32
|
* - Multi-term search: { project: "org/project", search: ["login", "signup", "forgot_password"] }
|
|
26
|
-
* - Find "Giriş" in Turkish: { project: "org/project", search: "Giriş", languages: ["tr"] }
|
|
33
|
+
* - Find "Giriş" in Turkish (faster): { project: "org/project", search: "Giriş", languages: ["tr"] }
|
|
27
34
|
* - Get all Turkish translations: { project: "org/project", languages: ["tr"] }
|
|
28
35
|
* - Get missing Turkish: { project: "org/project", languages: ["tr"], status: "missing" }
|
|
29
36
|
* - Get specific keys: { project: "org/project", keys: ["auth.login.title", "auth.login.button"] }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getTranslations.d.ts","sourceRoot":"","sources":["../../src/tools/getTranslations.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"getTranslations.d.ts","sourceRoot":"","sources":["../../src/tools/getTranslations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AASH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAW9C,eAAO,MAAM,eAAe,EAAE,IAmG7B,CAAC"}
|
|
@@ -7,9 +7,15 @@
|
|
|
7
7
|
* USE THIS when you need actual translation text (to translate, review, or update).
|
|
8
8
|
* Use listKeys instead for browsing/exploring keys — it's faster and uses fewer tokens.
|
|
9
9
|
*
|
|
10
|
-
* SEARCH
|
|
11
|
-
* - search
|
|
12
|
-
*
|
|
10
|
+
* SEARCH BEHAVIOR:
|
|
11
|
+
* - search WITHOUT languages: searches key names, source text, AND all translation texts across every language.
|
|
12
|
+
* Use this when you don't know which language the text is in (e.g., user mentions text they saw on screen).
|
|
13
|
+
* - search WITH languages: searches key names, source text (if source language included), AND translations
|
|
14
|
+
* only in the specified languages. Faster and more targeted.
|
|
15
|
+
* - Without search: returns all keys (filtered by other params).
|
|
16
|
+
*
|
|
17
|
+
* FILTER PARAMETERS:
|
|
18
|
+
* - languages: Languages to search in AND return translations for
|
|
13
19
|
* - status: Filter by translation status ("missing", "draft", "published", "all")
|
|
14
20
|
* - namespaces: Filter by namespace(s)
|
|
15
21
|
* - keys: Fetch specific keys by exact name
|
|
@@ -21,9 +27,10 @@
|
|
|
21
27
|
* - hasMore: true when total > limit — use narrower filters to get specific keys
|
|
22
28
|
*
|
|
23
29
|
* EXAMPLES:
|
|
30
|
+
* - Find text in ANY language: { project: "org/project", search: "Mehmet" }
|
|
24
31
|
* - Find "login" in source: { project: "org/project", search: "login" }
|
|
25
32
|
* - Multi-term search: { project: "org/project", search: ["login", "signup", "forgot_password"] }
|
|
26
|
-
* - Find "Giriş" in Turkish: { project: "org/project", search: "Giriş", languages: ["tr"] }
|
|
33
|
+
* - Find "Giriş" in Turkish (faster): { project: "org/project", search: "Giriş", languages: ["tr"] }
|
|
27
34
|
* - Get all Turkish translations: { project: "org/project", languages: ["tr"] }
|
|
28
35
|
* - Get missing Turkish: { project: "org/project", languages: ["tr"], status: "missing" }
|
|
29
36
|
* - Get specific keys: { project: "org/project", keys: ["auth.login.title", "auth.login.button"] }
|
|
@@ -50,8 +57,13 @@ IMPORTANT: status filter REQUIRES languages parameter.
|
|
|
50
57
|
{ status: "missing" } alone returns ALL keys (filter silently ignored).
|
|
51
58
|
Always pair: { languages: ["hr"], status: "missing" }
|
|
52
59
|
|
|
53
|
-
SEARCH
|
|
54
|
-
- search
|
|
60
|
+
SEARCH BEHAVIOR:
|
|
61
|
+
- search WITHOUT languages: searches key names, source text, AND all translations across every language.
|
|
62
|
+
Use this when you don't know which language the text is in.
|
|
63
|
+
- search WITH languages: searches only in specified languages (faster, more targeted).
|
|
64
|
+
Use this when you know the language of the text you're looking for.
|
|
65
|
+
|
|
66
|
+
FILTER PARAMETERS:
|
|
55
67
|
- languages: Languages to search in AND return translations for
|
|
56
68
|
- status: Filter by translation status ("missing", "draft", "published", "all")
|
|
57
69
|
- namespaces: Filter by namespace(s)
|
|
@@ -64,9 +76,10 @@ RESPONSE METADATA:
|
|
|
64
76
|
- hasMore: true when total > limit — narrow your filters to get specific results
|
|
65
77
|
|
|
66
78
|
EXAMPLES:
|
|
79
|
+
- Find text in ANY language: { search: "Mehmet" }
|
|
67
80
|
- Find "login" in source: { search: "login" }
|
|
68
81
|
- Multi-term search: { search: ["login", "signup", "forgot_password"] }
|
|
69
|
-
- Find "Giriş" in Turkish: { search: "Giriş", languages: ["tr"] }
|
|
82
|
+
- Find "Giriş" in Turkish (faster): { search: "Giriş", languages: ["tr"] }
|
|
70
83
|
- Get all Turkish translations: { languages: ["tr"] }
|
|
71
84
|
- Get missing Turkish translations: { languages: ["tr"], status: "missing" }
|
|
72
85
|
- Get specific keys: { keys: ["auth.login.title", "auth.login.button"] }
|
|
@@ -78,7 +91,7 @@ Response includes namespaceDetails: a map of namespace metadata (name, keyCount,
|
|
|
78
91
|
...projectInputProperty,
|
|
79
92
|
search: {
|
|
80
93
|
type: "string",
|
|
81
|
-
description: "Text to search for
|
|
94
|
+
description: "Text to search for (case-insensitive). Single string or array of strings for multi-term OR search. Searches key names + source text always. Without languages: also searches ALL translation texts across every language. With languages: searches only in those languages (faster).",
|
|
82
95
|
},
|
|
83
96
|
languages: {
|
|
84
97
|
type: "array",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getTranslations.js","sourceRoot":"","sources":["../../src/tools/getTranslations.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"getTranslations.js","sourceRoot":"","sources":["../../src/tools/getTranslations.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proposeLanguageEdits.d.ts","sourceRoot":"","sources":["../../src/tools/proposeLanguageEdits.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAc9C,eAAO,MAAM,oBAAoB,EAAE,
|
|
1
|
+
{"version":3,"file":"proposeLanguageEdits.d.ts","sourceRoot":"","sources":["../../src/tools/proposeLanguageEdits.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAc9C,eAAO,MAAM,oBAAoB,EAAE,IA8DlC,CAAC"}
|
|
@@ -54,11 +54,21 @@ export const proposeLanguageEdits = {
|
|
|
54
54
|
projectSlug,
|
|
55
55
|
updates,
|
|
56
56
|
});
|
|
57
|
+
// Build contextual hints
|
|
58
|
+
let hint;
|
|
59
|
+
if (result.notFound.length > 0) {
|
|
60
|
+
hint = `${result.notFound.length} language(s) not found: [${result.notFound.join(", ")}]. Language codes are case-normalized. Call getProject to see exact codes.`;
|
|
61
|
+
}
|
|
62
|
+
else if (result.results.every((r) => !r.changed)) {
|
|
63
|
+
hint = "All language status updates were no-ops — the requested status was already set.";
|
|
64
|
+
}
|
|
57
65
|
return success({
|
|
58
66
|
success: result.success,
|
|
59
67
|
results: result.results,
|
|
60
68
|
notFound: result.notFound,
|
|
61
69
|
project: input.project,
|
|
70
|
+
...(result.pendingPublish ? { pendingPublish: result.pendingPublish } : {}),
|
|
71
|
+
...(hint ? { hint } : {}),
|
|
62
72
|
});
|
|
63
73
|
}),
|
|
64
74
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proposeLanguageEdits.js","sourceRoot":"","sources":["../../src/tools/proposeLanguageEdits.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,aAAa,EACb,OAAO,GACR,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC;IACvC,KAAK,EAAE,CAAC;SACL,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;QACP,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QACvC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;KACnD,CAAC,CACH;SACA,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,EAAE,CAAC;CACX,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAS;IACxC,UAAU,EAAE;QACV,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EACT,0MAA0M;QAC5M,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,GAAG,oBAAoB;gBACvB,KAAK,EAAE;oBACL,IAAI,EAAE,OAAO;oBACb,WAAW,EACT,kGAAkG;oBACpG,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uGAAuG,EAAE;4BACtJ,SAAS,EAAE;gCACT,IAAI,EAAE,QAAQ;gCACd,IAAI,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC;gCACrC,WAAW,EAAE,sFAAsF;6BACpG;yBACF;wBACD,QAAQ,EAAE,CAAC,cAAc,EAAE,WAAW,CAAC;qBACxC;iBACF;aACF;YACD,QAAQ,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC;SAC/B;KACF;IAED,OAAO,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CACxB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE;QAC3E,2EAA2E;QAC3E,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACzC,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE;YAC7C,MAAM,EAAE,IAAI,CAAC,SAAS;SACvB,CAAC,CAAC,CAAC;QAEJ,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC;YACrD,OAAO,EAAE,WAAW;YACpB,WAAW;YACX,OAAO;SACR,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;YACb,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,OAAO,EAAE,KAAK,CAAC,OAAO;
|
|
1
|
+
{"version":3,"file":"proposeLanguageEdits.js","sourceRoot":"","sources":["../../src/tools/proposeLanguageEdits.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proposeLanguages.d.ts","sourceRoot":"","sources":["../../src/tools/proposeLanguages.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAc9C,eAAO,MAAM,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"proposeLanguages.d.ts","sourceRoot":"","sources":["../../src/tools/proposeLanguages.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAc9C,eAAO,MAAM,gBAAgB,EAAE,IAyD9B,CAAC"}
|
|
@@ -60,6 +60,10 @@ export const proposeLanguages = {
|
|
|
60
60
|
skipped: result.skipped,
|
|
61
61
|
results: result.results,
|
|
62
62
|
project: input.project,
|
|
63
|
+
...(result.pendingPublish ? { pendingPublish: result.pendingPublish } : {}),
|
|
64
|
+
...(result.added === 0 && result.skipped > 0
|
|
65
|
+
? { hint: `All ${result.skipped} submitted language(s) already exist — nothing was added. To change their status, use proposeLanguageEdits.` }
|
|
66
|
+
: {}),
|
|
63
67
|
});
|
|
64
68
|
}),
|
|
65
69
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proposeLanguages.js","sourceRoot":"","sources":["../../src/tools/proposeLanguages.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,aAAa,EACb,OAAO,GACR,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC;IACvC,SAAS,EAAE,CAAC;SACT,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;QACP,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QACvC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE;KACjE,CAAC,CACH;SACA,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,EAAE,CAAC;CACX,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAS;IACpC,UAAU,EAAE;QACV,IAAI,EAAE,kBAAkB;QACxB,WAAW,EACT,iMAAiM;QACnM,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,GAAG,oBAAoB;gBACvB,SAAS,EAAE;oBACT,IAAI,EAAE,OAAO;oBACb,WAAW,EACT,iHAAiH;oBACnH,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mFAAmF,EAAE;4BAClI,MAAM,EAAE;gCACN,IAAI,EAAE,QAAQ;gCACd,IAAI,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;gCACzB,WAAW,EAAE,4FAA4F;6BAC1G;yBACF;wBACD,QAAQ,EAAE,CAAC,cAAc,CAAC;qBAC3B;iBACF;aACF;YACD,QAAQ,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC;SACnC;KACF;IAED,OAAO,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CACxB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE;QAC3E,wCAAwC;QACxC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC7C,GAAG,IAAI;YACP,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE;SAC9C,CAAC,CAAC,CAAC;QAEJ,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC;YAClD,OAAO,EAAE,WAAW;YACpB,WAAW;YACX,SAAS;SACV,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;YACb,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,OAAO,EAAE,KAAK,CAAC,OAAO;
|
|
1
|
+
{"version":3,"file":"proposeLanguages.js","sourceRoot":"","sources":["../../src/tools/proposeLanguages.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,aAAa,EACb,OAAO,GACR,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC;IACvC,SAAS,EAAE,CAAC;SACT,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;QACP,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QACvC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE;KACjE,CAAC,CACH;SACA,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,EAAE,CAAC;CACX,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAS;IACpC,UAAU,EAAE;QACV,IAAI,EAAE,kBAAkB;QACxB,WAAW,EACT,iMAAiM;QACnM,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,GAAG,oBAAoB;gBACvB,SAAS,EAAE;oBACT,IAAI,EAAE,OAAO;oBACb,WAAW,EACT,iHAAiH;oBACnH,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mFAAmF,EAAE;4BAClI,MAAM,EAAE;gCACN,IAAI,EAAE,QAAQ;gCACd,IAAI,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;gCACzB,WAAW,EAAE,4FAA4F;6BAC1G;yBACF;wBACD,QAAQ,EAAE,CAAC,cAAc,CAAC;qBAC3B;iBACF;aACF;YACD,QAAQ,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC;SACnC;KACF;IAED,OAAO,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CACxB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE;QAC3E,wCAAwC;QACxC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC7C,GAAG,IAAI;YACP,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE;SAC9C,CAAC,CAAC,CAAC;QAEJ,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC;YAClD,OAAO,EAAE,WAAW;YACpB,WAAW;YACX,SAAS;SACV,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;YACb,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3E,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC;gBAC1C,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,MAAM,CAAC,OAAO,6GAA6G,EAAE;gBAC9I,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CAAC;IACL,CAAC,CAAC;CACL,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-i18n/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "MCP server for Better i18n translation management - AI-powered translation workflow for Cursor, Claude, and other AI assistants",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
13
|
"dist",
|
|
14
|
+
"!dist/**/__tests__",
|
|
14
15
|
"package.json",
|
|
15
16
|
"README.md"
|
|
16
17
|
],
|
|
@@ -50,12 +51,12 @@
|
|
|
50
51
|
"prepublishOnly": "npm run clean && npm run build && chmod +x ./dist/index.js ./dist/http.js"
|
|
51
52
|
},
|
|
52
53
|
"dependencies": {
|
|
53
|
-
"@better-i18n/mcp-types": "0.0.0",
|
|
54
54
|
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
55
55
|
"@trpc/client": "^11.0.0",
|
|
56
56
|
"zod": "^3.25.1"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
+
"@better-i18n/mcp-types": "0.0.0",
|
|
59
60
|
"@types/node": "^20.0.0",
|
|
60
61
|
"typescript": "~5.9.2"
|
|
61
62
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base-tool.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/base-tool.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
import { parseProject } from "../helpers.js";
|
|
4
|
-
import { success, error, executeTool, executeSimpleTool, projectSchema, } from "../base-tool.js";
|
|
5
|
-
import { isErrorResult, expectSuccess, expectError } from "./helpers.js";
|
|
6
|
-
// ---------------------------------------------------------------------------
|
|
7
|
-
// parseProject
|
|
8
|
-
// ---------------------------------------------------------------------------
|
|
9
|
-
describe("parseProject", () => {
|
|
10
|
-
it('parses "org/project" into workspaceId and projectSlug', () => {
|
|
11
|
-
expect(parseProject("org/project")).toEqual({
|
|
12
|
-
workspaceId: "org",
|
|
13
|
-
projectSlug: "project",
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
it("throws a descriptive error for a single-segment string", () => {
|
|
17
|
-
expect(() => parseProject("invalid")).toThrow(/Invalid project format "invalid"/);
|
|
18
|
-
});
|
|
19
|
-
it("throws for an empty string", () => {
|
|
20
|
-
expect(() => parseProject("")).toThrow(/Invalid project format/);
|
|
21
|
-
});
|
|
22
|
-
it("throws when there are 3 segments (a/b/c)", () => {
|
|
23
|
-
expect(() => parseProject("a/b/c")).toThrow(/Invalid project format "a\/b\/c"/);
|
|
24
|
-
});
|
|
25
|
-
it("throws when the slug part is empty (org/)", () => {
|
|
26
|
-
expect(() => parseProject("org/")).toThrow(/Invalid project format "org\/"/);
|
|
27
|
-
});
|
|
28
|
-
it("throws when the org part is empty (/project)", () => {
|
|
29
|
-
expect(() => parseProject("/project")).toThrow(/Invalid project format "\/project"/);
|
|
30
|
-
});
|
|
31
|
-
it("handles hyphens in both org and slug", () => {
|
|
32
|
-
expect(parseProject("org-with-hyphens/proj-123")).toEqual({
|
|
33
|
-
workspaceId: "org-with-hyphens",
|
|
34
|
-
projectSlug: "proj-123",
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
// ---------------------------------------------------------------------------
|
|
39
|
-
// projectSchema
|
|
40
|
-
// ---------------------------------------------------------------------------
|
|
41
|
-
describe("projectSchema", () => {
|
|
42
|
-
it("accepts a non-empty project string", () => {
|
|
43
|
-
expect(() => projectSchema.parse({ project: "org/slug" })).not.toThrow();
|
|
44
|
-
});
|
|
45
|
-
it("rejects an empty project string", () => {
|
|
46
|
-
expect(() => projectSchema.parse({ project: "" })).toThrow();
|
|
47
|
-
});
|
|
48
|
-
it("rejects a missing project field", () => {
|
|
49
|
-
expect(() => projectSchema.parse({})).toThrow();
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
// ---------------------------------------------------------------------------
|
|
53
|
-
// success
|
|
54
|
-
// ---------------------------------------------------------------------------
|
|
55
|
-
describe("success", () => {
|
|
56
|
-
it("produces a result with type=text content", () => {
|
|
57
|
-
const result = success({ data: 1 });
|
|
58
|
-
expect(result.content).toHaveLength(1);
|
|
59
|
-
expect(result.content[0]?.type).toBe("text");
|
|
60
|
-
});
|
|
61
|
-
it("serialises the payload as valid JSON", () => {
|
|
62
|
-
const result = success({ hello: "world", count: 42 });
|
|
63
|
-
const text = result.content[0]?.text;
|
|
64
|
-
expect(text).toBeDefined();
|
|
65
|
-
expect(() => JSON.parse(text)).not.toThrow();
|
|
66
|
-
expect(JSON.parse(text)).toEqual({ hello: "world", count: 42 });
|
|
67
|
-
});
|
|
68
|
-
it("does not set isError", () => {
|
|
69
|
-
const result = success({ ok: true });
|
|
70
|
-
expect(result.isError).toBeUndefined();
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
// ---------------------------------------------------------------------------
|
|
74
|
-
// error
|
|
75
|
-
// ---------------------------------------------------------------------------
|
|
76
|
-
describe("error", () => {
|
|
77
|
-
it("sets isError: true", () => {
|
|
78
|
-
const result = error("something went wrong");
|
|
79
|
-
expect(result.isError).toBe(true);
|
|
80
|
-
});
|
|
81
|
-
it("includes the message in the text content", () => {
|
|
82
|
-
const msg = "something went wrong";
|
|
83
|
-
const result = error(msg);
|
|
84
|
-
expect(result.content[0]?.text).toBe(msg);
|
|
85
|
-
});
|
|
86
|
-
it("produces exactly one content entry", () => {
|
|
87
|
-
const result = error("oops");
|
|
88
|
-
expect(result.content).toHaveLength(1);
|
|
89
|
-
expect(result.content[0]?.type).toBe("text");
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
// ---------------------------------------------------------------------------
|
|
93
|
-
// executeTool
|
|
94
|
-
// ---------------------------------------------------------------------------
|
|
95
|
-
describe("executeTool", () => {
|
|
96
|
-
const schema = z.object({ project: z.string().min(1), value: z.string() });
|
|
97
|
-
it("calls the handler with parsed input and ParsedProject on success", async () => {
|
|
98
|
-
const result = await executeTool({ project: "acme/website", value: "hello" }, schema, async (input, parsed) => {
|
|
99
|
-
return success({
|
|
100
|
-
value: input.value,
|
|
101
|
-
workspaceId: parsed.workspaceId,
|
|
102
|
-
projectSlug: parsed.projectSlug,
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
const data = expectSuccess(result);
|
|
106
|
-
expect(data.value).toBe("hello");
|
|
107
|
-
expect(data.workspaceId).toBe("acme");
|
|
108
|
-
expect(data.projectSlug).toBe("website");
|
|
109
|
-
});
|
|
110
|
-
it("returns isError: true with 'Validation error' on Zod failure", async () => {
|
|
111
|
-
const result = await executeTool({ project: "valid/project" /* missing required `value` */ }, schema, async () => success({}));
|
|
112
|
-
expect(isErrorResult(result)).toBe(true);
|
|
113
|
-
const msg = expectError(result);
|
|
114
|
-
expect(msg).toMatch(/Validation error/i);
|
|
115
|
-
});
|
|
116
|
-
it("returns isError: true when the handler throws", async () => {
|
|
117
|
-
const result = await executeTool({ project: "acme/website", value: "x" }, schema, async () => {
|
|
118
|
-
throw new Error("handler blew up");
|
|
119
|
-
});
|
|
120
|
-
expect(isErrorResult(result)).toBe(true);
|
|
121
|
-
expect(expectError(result)).toContain("handler blew up");
|
|
122
|
-
});
|
|
123
|
-
it("returns isError: true for invalid project format", async () => {
|
|
124
|
-
const result = await executeTool({ project: "not-a-valid-format", value: "x" }, schema, async () => success({}));
|
|
125
|
-
expect(isErrorResult(result)).toBe(true);
|
|
126
|
-
expect(expectError(result)).toMatch(/Invalid project format/i);
|
|
127
|
-
});
|
|
128
|
-
it("returns isError: true when args fail schema type coercion", async () => {
|
|
129
|
-
const result = await executeTool(null, // completely invalid args
|
|
130
|
-
schema, async () => success({}));
|
|
131
|
-
expect(isErrorResult(result)).toBe(true);
|
|
132
|
-
});
|
|
133
|
-
it("passes the full parsed project to the handler", async () => {
|
|
134
|
-
let capturedParsed = null;
|
|
135
|
-
await executeTool({ project: "my-org/my-slug", value: "test" }, schema, async (_input, parsed) => {
|
|
136
|
-
capturedParsed = parsed;
|
|
137
|
-
return success({});
|
|
138
|
-
});
|
|
139
|
-
expect(capturedParsed).toEqual({
|
|
140
|
-
workspaceId: "my-org",
|
|
141
|
-
projectSlug: "my-slug",
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
it("surfaces non-Error throws as string messages", async () => {
|
|
145
|
-
const result = await executeTool({ project: "acme/website", value: "x" }, schema, async () => {
|
|
146
|
-
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
|
147
|
-
throw "string error";
|
|
148
|
-
});
|
|
149
|
-
expect(isErrorResult(result)).toBe(true);
|
|
150
|
-
expect(expectError(result)).toBe("string error");
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
// ---------------------------------------------------------------------------
|
|
154
|
-
// executeSimpleTool
|
|
155
|
-
// ---------------------------------------------------------------------------
|
|
156
|
-
describe("executeSimpleTool", () => {
|
|
157
|
-
const schema = z.object({ name: z.string().min(1), count: z.number() });
|
|
158
|
-
it("calls the handler with parsed input and returns its result", async () => {
|
|
159
|
-
const result = await executeSimpleTool({ name: "test", count: 5 }, schema, async (input) => success({ echo: input.name, times: input.count }));
|
|
160
|
-
const data = expectSuccess(result);
|
|
161
|
-
expect(data.echo).toBe("test");
|
|
162
|
-
expect(data.times).toBe(5);
|
|
163
|
-
});
|
|
164
|
-
it("returns isError: true with 'Validation error' on Zod failure", async () => {
|
|
165
|
-
const result = await executeSimpleTool({ name: "" /* fails min(1) */, count: 3 }, schema, async () => success({}));
|
|
166
|
-
expect(isErrorResult(result)).toBe(true);
|
|
167
|
-
expect(expectError(result)).toMatch(/Validation error/i);
|
|
168
|
-
});
|
|
169
|
-
it("returns isError: true when the handler throws an Error", async () => {
|
|
170
|
-
const result = await executeSimpleTool({ name: "good", count: 1 }, schema, async () => {
|
|
171
|
-
throw new Error("simple handler failed");
|
|
172
|
-
});
|
|
173
|
-
expect(isErrorResult(result)).toBe(true);
|
|
174
|
-
expect(expectError(result)).toContain("simple handler failed");
|
|
175
|
-
});
|
|
176
|
-
it("returns isError: true when the handler throws a non-Error value", async () => {
|
|
177
|
-
const result = await executeSimpleTool({ name: "good", count: 1 }, schema, async () => {
|
|
178
|
-
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
|
179
|
-
throw 42;
|
|
180
|
-
});
|
|
181
|
-
expect(isErrorResult(result)).toBe(true);
|
|
182
|
-
expect(expectError(result)).toBe("42");
|
|
183
|
-
});
|
|
184
|
-
it("returns isError: true when args are completely invalid", async () => {
|
|
185
|
-
const result = await executeSimpleTool(undefined, schema, async () => success({}));
|
|
186
|
-
expect(isErrorResult(result)).toBe(true);
|
|
187
|
-
});
|
|
188
|
-
it("does not include isError on a successful result", async () => {
|
|
189
|
-
const result = await executeSimpleTool({ name: "ok", count: 0 }, schema, async () => success({ ok: true }));
|
|
190
|
-
expect(result.isError).toBeUndefined();
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
//# sourceMappingURL=base-tool.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base-tool.test.js","sourceRoot":"","sources":["../../src/__tests__/base-tool.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* contract.test.ts
|
|
3
|
-
*
|
|
4
|
-
* End-to-end contract tests that bridge the gap between tool logic and the real API.
|
|
5
|
-
*
|
|
6
|
-
* THREE test sections:
|
|
7
|
-
*
|
|
8
|
-
* 1. FORWARD CONTRACT — tool output → API schema validation
|
|
9
|
-
* Execute each tool with a mock client, capture what it ACTUALLY sends to the
|
|
10
|
-
* API (orgSlug, projectSlug, payload), and validate those args against the
|
|
11
|
-
* mcp-types Zod schemas (the real API contract). If the API schema rejects it,
|
|
12
|
-
* the tool has a normalization or mapping bug.
|
|
13
|
-
*
|
|
14
|
-
* 2. REVERSE CONTRACT — LLM-plausible args → tool acceptance
|
|
15
|
-
* Simulate inputs an LLM would plausibly generate from reading inputSchema,
|
|
16
|
-
* and assert the tool accepts them without isError. Catches regressions where
|
|
17
|
-
* a schema tightening breaks something an LLM was expected to send.
|
|
18
|
-
*
|
|
19
|
-
* 3. NEGATIVE CONTRACT — invalid args MUST be rejected
|
|
20
|
-
* Guard rails: assert that clearly invalid inputs are rejected (isError=true)
|
|
21
|
-
* so we never silently swallow bad data from an LLM.
|
|
22
|
-
*/
|
|
23
|
-
export {};
|
|
24
|
-
//# sourceMappingURL=contract.test.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"contract.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/contract.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG"}
|