@julong/mono-rele2-utils 1.30.0 → 1.31.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 +29 -52
- package/dist/cli.cjs +7 -0
- package/dist/cli.js +4 -4
- package/dist/index.cjs +67 -0
- package/dist/index.d.cts +178 -0
- package/dist/server.cjs +6 -0
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -57,32 +57,27 @@ mono-rele2-utils-cli
|
|
|
57
57
|
**Signature**
|
|
58
58
|
|
|
59
59
|
```typescript
|
|
60
|
-
function cn(classes: string[]): string
|
|
60
|
+
function cn(classes: string[]): string;
|
|
61
61
|
```
|
|
62
62
|
|
|
63
63
|
Merges class names, filtering out falsy values.
|
|
64
64
|
|
|
65
|
-
|
|
66
65
|
**Parameters**
|
|
67
66
|
|
|
68
|
-
| Name
|
|
69
|
-
|
|
67
|
+
| Name | Type | Description |
|
|
68
|
+
| --------- | ---------- | ---------------------------- |
|
|
70
69
|
| `classes` | `string[]` | List of class names to merge |
|
|
71
70
|
|
|
72
|
-
|
|
73
71
|
**Returns**
|
|
74
72
|
|
|
75
73
|
`string` — Merged class name string with falsy values filtered out
|
|
76
74
|
|
|
77
|
-
|
|
78
75
|
**CLI**
|
|
79
76
|
|
|
80
77
|
```sh
|
|
81
78
|
mono-rele2-utils-cli cnTool <classes>
|
|
82
79
|
```
|
|
83
80
|
|
|
84
|
-
|
|
85
|
-
|
|
86
81
|
**Examples**
|
|
87
82
|
|
|
88
83
|
```sh
|
|
@@ -95,43 +90,43 @@ mono-rele2-utils-cli cnTool '["btn","active","large"]'
|
|
|
95
90
|
**Signature**
|
|
96
91
|
|
|
97
92
|
```typescript
|
|
98
|
-
function case_convert(
|
|
93
|
+
function case_convert(
|
|
94
|
+
input: string,
|
|
95
|
+
to: 'upper' | 'lower' | 'capitalize' | 'camel' | 'snake' | 'kebab',
|
|
96
|
+
): string;
|
|
99
97
|
```
|
|
100
98
|
|
|
101
99
|
Converts text to the specified case format.
|
|
102
100
|
|
|
103
|
-
|
|
104
101
|
**Parameters**
|
|
105
102
|
|
|
106
|
-
| Name
|
|
107
|
-
|
|
103
|
+
| Name | Type | Description |
|
|
104
|
+
| ------- | -------- | --------------- | ------------ | ------- | ------- | -------- | ------------------ |
|
|
108
105
|
| `input` | `string` | Text to convert |
|
|
109
|
-
| `to`
|
|
110
|
-
|
|
106
|
+
| `to` | `"upper" | "lower" | "capitalize" | "camel" | "snake" | "kebab"` | Target case format |
|
|
111
107
|
|
|
112
108
|
**Returns**
|
|
113
109
|
|
|
114
110
|
`string` — Converted text in the target case format
|
|
115
111
|
|
|
116
|
-
|
|
117
112
|
**CLI**
|
|
118
113
|
|
|
119
114
|
```sh
|
|
120
115
|
mono-rele2-utils-cli caseConvertTool <input> <to>
|
|
121
116
|
```
|
|
122
117
|
|
|
123
|
-
|
|
124
|
-
|
|
125
118
|
**Examples**
|
|
126
119
|
|
|
127
120
|
```sh
|
|
128
121
|
mono-rele2-utils-cli caseConvertTool "hello world" camel
|
|
129
122
|
# → helloWorld
|
|
130
123
|
```
|
|
124
|
+
|
|
131
125
|
```sh
|
|
132
126
|
mono-rele2-utils-cli caseConvertTool "helloWorld" snake
|
|
133
127
|
# → hello_world
|
|
134
128
|
```
|
|
129
|
+
|
|
135
130
|
```sh
|
|
136
131
|
mono-rele2-utils-cli caseConvertTool "hello world" kebab
|
|
137
132
|
# → hello-world
|
|
@@ -142,40 +137,36 @@ mono-rele2-utils-cli caseConvertTool "hello world" kebab
|
|
|
142
137
|
**Signature**
|
|
143
138
|
|
|
144
139
|
```typescript
|
|
145
|
-
function truncate(input: string, maxLength: number, suffix?: string): string
|
|
140
|
+
function truncate(input: string, maxLength: number, suffix?: string): string;
|
|
146
141
|
```
|
|
147
142
|
|
|
148
143
|
Truncates text to a maximum length and appends a suffix.
|
|
149
144
|
|
|
150
|
-
|
|
151
145
|
**Parameters**
|
|
152
146
|
|
|
153
|
-
| Name
|
|
154
|
-
|
|
155
|
-
| `input`
|
|
156
|
-
| `maxLength` | `number` | Maximum character length
|
|
157
|
-
| `suffix`
|
|
158
|
-
|
|
147
|
+
| Name | Type | Description |
|
|
148
|
+
| ----------- | -------- | ------------------------------------------------ |
|
|
149
|
+
| `input` | `string` | Text to truncate |
|
|
150
|
+
| `maxLength` | `number` | Maximum character length |
|
|
151
|
+
| `suffix` | `string` | Suffix to append when truncated (default: `...`) |
|
|
159
152
|
|
|
160
153
|
**Returns**
|
|
161
154
|
|
|
162
155
|
`string` — Truncated text with the configured suffix appended if truncated
|
|
163
156
|
|
|
164
|
-
|
|
165
157
|
**CLI**
|
|
166
158
|
|
|
167
159
|
```sh
|
|
168
160
|
mono-rele2-utils-cli truncateTool <input> <maxLength> [suffix]
|
|
169
161
|
```
|
|
170
162
|
|
|
171
|
-
|
|
172
|
-
|
|
173
163
|
**Examples**
|
|
174
164
|
|
|
175
165
|
```sh
|
|
176
166
|
mono-rele2-utils-cli truncateTool "hello world long text" 10
|
|
177
167
|
# → hello w...
|
|
178
168
|
```
|
|
169
|
+
|
|
179
170
|
```sh
|
|
180
171
|
mono-rele2-utils-cli truncateTool "hello world" 8 "…"
|
|
181
172
|
# → hello w…
|
|
@@ -191,27 +182,22 @@ function object_flatten(json: string \| JSON object): JsonObject
|
|
|
191
182
|
|
|
192
183
|
Flattens a nested JSON object of any depth into dot-notation key-value pairs. Accepts a JSON string and recursively flattens all levels. Arrays and primitives at any level are treated as leaf values..
|
|
193
184
|
|
|
194
|
-
|
|
195
185
|
**Parameters**
|
|
196
186
|
|
|
197
|
-
| Name
|
|
198
|
-
|
|
187
|
+
| Name | Type | Description |
|
|
188
|
+
| ------ | ----------------------- | --------------------------------------------------------- |
|
|
199
189
|
| `json` | `string \| JSON object` | JSON string or parsed object to flatten (unlimited depth) |
|
|
200
190
|
|
|
201
|
-
|
|
202
191
|
**Returns**
|
|
203
192
|
|
|
204
193
|
`JsonObject` — Flattened object with dot-notation keys — e.g. { "a.b.c": value }
|
|
205
194
|
|
|
206
|
-
|
|
207
195
|
**CLI**
|
|
208
196
|
|
|
209
197
|
```sh
|
|
210
198
|
mono-rele2-utils-cli objectFlattenTool <json>
|
|
211
199
|
```
|
|
212
200
|
|
|
213
|
-
|
|
214
|
-
|
|
215
201
|
**Examples**
|
|
216
202
|
|
|
217
203
|
```sh
|
|
@@ -223,6 +209,7 @@ mono-rele2-utils-cli objectFlattenTool '{"user":{"name":"Alice","address":{"city
|
|
|
223
209
|
"active": true
|
|
224
210
|
}
|
|
225
211
|
```
|
|
212
|
+
|
|
226
213
|
```sh
|
|
227
214
|
mono-rele2-utils-cli objectFlattenTool '{"a":{"b":{"c":{"d":{"e":"deep"}}}}}'
|
|
228
215
|
# → {
|
|
@@ -235,36 +222,32 @@ mono-rele2-utils-cli objectFlattenTool '{"a":{"b":{"c":{"d":{"e":"deep"}}}}}'
|
|
|
235
222
|
**Signature**
|
|
236
223
|
|
|
237
224
|
```typescript
|
|
238
|
-
function getUser(user: RandomUser): string
|
|
225
|
+
function getUser(user: RandomUser): string;
|
|
239
226
|
```
|
|
240
227
|
|
|
241
228
|
RandomUser API 형식의 사용자 객체를 받아 이름과 거주 도시로 구성된 한글 문장을 반환합니다. JSON 문자열 또는 파싱된 객체를 입력받습니다..
|
|
242
229
|
|
|
243
|
-
|
|
244
230
|
**Parameters**
|
|
245
231
|
|
|
246
|
-
| Name
|
|
247
|
-
|
|
232
|
+
| Name | Type | Description |
|
|
233
|
+
| ------ | ------------ | ------------------------------------------------------------------------------------- |
|
|
248
234
|
| `user` | `RandomUser` | RandomUser 형식의 JSON 문자열 또는 객체 — name.first / name.last / location.city 필수 |
|
|
249
235
|
|
|
250
|
-
|
|
251
236
|
**Returns**
|
|
252
237
|
|
|
253
238
|
`string` — "이름은 {first} {last} 이고 현재 {city} 에 살고 있습니다." 형식의 한글 문장
|
|
254
239
|
|
|
255
|
-
|
|
256
240
|
**CLI**
|
|
257
241
|
|
|
258
242
|
```sh
|
|
259
243
|
mono-rele2-utils-cli getUserTool <user>
|
|
260
244
|
```
|
|
261
245
|
|
|
262
|
-
|
|
263
246
|
**`user`** type definition
|
|
264
247
|
|
|
265
248
|
```typescript
|
|
266
249
|
interface RandomUser {
|
|
267
|
-
gender:
|
|
250
|
+
gender: 'male' | 'female';
|
|
268
251
|
name: {
|
|
269
252
|
title: string;
|
|
270
253
|
first: string;
|
|
@@ -308,7 +291,6 @@ interface RandomUser {
|
|
|
308
291
|
}
|
|
309
292
|
```
|
|
310
293
|
|
|
311
|
-
|
|
312
294
|
**Examples**
|
|
313
295
|
|
|
314
296
|
```sh
|
|
@@ -321,31 +303,27 @@ mono-rele2-utils-cli getUserTool '{"name":{"title":"Mr","first":"Alice","last":"
|
|
|
321
303
|
**Signature**
|
|
322
304
|
|
|
323
305
|
```typescript
|
|
324
|
-
function env_get(keys: string[]): Record<string, string
|
|
306
|
+
function env_get(keys: string[]): Record<string, string>;
|
|
325
307
|
```
|
|
326
308
|
|
|
327
309
|
MCP 클라이언트 config의 env 필드를 통해 주입된 환경 변수 값을 조회합니다. 조회 가능한 키는 패키지에서 제공하는 환경 변수로 한정됩니다. 현재 지원: API_KEY..
|
|
328
310
|
|
|
329
|
-
|
|
330
311
|
**Parameters**
|
|
331
312
|
|
|
332
|
-
| Name
|
|
333
|
-
|
|
313
|
+
| Name | Type | Description |
|
|
314
|
+
| ------ | ---------- | --------------------------------------------- |
|
|
334
315
|
| `keys` | `string[]` | 조회할 환경 변수 이름 목록 (유효 키: API_KEY) |
|
|
335
316
|
|
|
336
|
-
|
|
337
317
|
**Returns**
|
|
338
318
|
|
|
339
319
|
`Record<string, string>` — key: 환경 변수 이름, value: 해당 값 (설정되지 않은 변수는 결과에서 제외)
|
|
340
320
|
|
|
341
|
-
|
|
342
321
|
**CLI**
|
|
343
322
|
|
|
344
323
|
```sh
|
|
345
324
|
mono-rele2-utils-cli envGetTool <keys>
|
|
346
325
|
```
|
|
347
326
|
|
|
348
|
-
|
|
349
327
|
**`keys`** type definition
|
|
350
328
|
|
|
351
329
|
```typescript
|
|
@@ -366,7 +344,6 @@ mono-rele2-utils-cli envGetTool <keys>
|
|
|
366
344
|
// }
|
|
367
345
|
```
|
|
368
346
|
|
|
369
|
-
|
|
370
347
|
**Examples**
|
|
371
348
|
|
|
372
349
|
```sh
|
package/dist/cli.cjs
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";function r(e){return{content:[{type:"text",text:e}]}}var O=require("@modelcontextprotocol/sdk/server/mcp.js"),A=require("@modelcontextprotocol/sdk/server/stdio.js");var y=require("zod");async function j(e){let[,,n,...t]=process.argv;(!n||!(n in e))&&(n&&console.error(`Unknown skill: "${n}"
|
|
3
|
+
`),process.exit(n?1:0));let o=e[n],s=Object.keys(o.inputSchema),c={};for(let i=0;i<s.length;i++){let g=t[i];if(g!==void 0)try{c[s[i]]=JSON.parse(g)}catch{c[s[i]]=g}}let f=y.z.object(o.inputSchema).parse(c),m=await o.handler(f);for(let i of m.content)i.type==="text"&&console.log(i.text)}function Z(e){e instanceof y.z.ZodError?console.error("Validation error:",e.issues.map(n=>`${n.path.join(".")}: ${n.message}`).join(", ")):console.error("Error:",e instanceof Error?e.message:String(e)),process.exit(1)}var k=require("zod");var a=require("zod");function w(...e){return e.filter(Boolean).join(" ")}var d={cnTool:{name:"cn",description:"Merges class names, filtering out falsy values",inputSchema:{classes:a.z.array(a.z.string()).describe("List of class names to merge")},typeLabels:{classes:"string[]"},returnType:"string",returnDescription:"Merged class name string with falsy values filtered out",handler:async({classes:e})=>r(w(...e)),examples:[{args:[`'["btn","active","large"]'`],result:"btn active large"}]},caseConvertTool:{name:"case_convert",description:"Converts text to the specified case format",inputSchema:{input:a.z.string().describe("Text to convert"),to:a.z.enum(["upper","lower","capitalize","camel","snake","kebab"]).describe("Target case format")},typeLabels:{input:"string",to:'"upper" | "lower" | "capitalize" | "camel" | "snake" | "kebab"'},returnType:"string",returnDescription:"Converted text in the target case format",handler:async({input:e,to:n})=>r(N(e,n)),examples:[{args:['"hello world"',"camel"],result:"helloWorld"},{args:['"helloWorld"',"snake"],result:"hello_world"},{args:['"hello world"',"kebab"],result:"hello-world"}]},truncateTool:{name:"truncate",description:"Truncates text to a maximum length and appends a suffix",inputSchema:{input:a.z.string().describe("Text to truncate"),maxLength:a.z.number().int().positive().describe("Maximum character length"),suffix:a.z.string().default("...").describe("Suffix to append when truncated")},typeLabels:{input:"string",maxLength:"number",suffix:"string"},returnType:"string",returnDescription:"Truncated text with the configured suffix appended if truncated",handler:async({input:e,maxLength:n,suffix:t})=>{let o=e.length<=n?e:e.slice(0,n-t.length)+t;return r(o)},examples:[{args:['"hello world long text"',"10"],result:"hello w..."},{args:['"hello world"',"8",'"\u2026"'],result:"hello w\u2026"}]}},z=d.cnTool,D=d.caseConvertTool,R=d.truncateTool;function N(e,n){switch(n){case"upper":return e.toUpperCase();case"lower":return e.toLowerCase();case"capitalize":return e.charAt(0).toUpperCase()+e.slice(1).toLowerCase();case"camel":return e.replace(/[-_\s]+(.)/g,(t,o)=>o.toUpperCase()).replace(/^(.)/,t=>t.toLowerCase());case"snake":return e.replace(/([A-Z])/g,"_$1").replace(/[-\s]+/g,"_").toLowerCase().replace(/^_/,"");case"kebab":return e.replace(/([A-Z])/g,"-$1").replace(/[_\s]+/g,"-").toLowerCase().replace(/^-/,"")}}var p=require("zod");function E(e){let n=typeof e=="string"?JSON.parse(e):e,t={};function o(s,c){if(s===null||typeof s!="object"||Array.isArray(s)){t[c]=s;return}for(let[f,m]of Object.entries(s)){let i=c?`${c}.${f}`:f;o(m,i)}}return o(n,""),t}var b={objectFlattenTool:{name:"object_flatten",description:"Flattens a nested JSON object of any depth into dot-notation key-value pairs. Accepts a JSON string and recursively flattens all levels. Arrays and primitives at any level are treated as leaf values.",inputSchema:{json:p.z.union([p.z.string(),p.z.record(p.z.string(),p.z.any())]).describe("JSON string or parsed object to flatten (unlimited depth)")},handler:async({json:e})=>{try{let t=E(e);return r(JSON.stringify(t,null,2))}catch(n){return n instanceof SyntaxError?r("Error: invalid JSON string \u2014 unable to parse input"):r(`Error: failed to flatten object \u2014 ${n.message}`)}},examples:[{args:[`'{"user":{"name":"Alice","address":{"city":"Seoul","zip":"12345"}},"active":true}'`],result:JSON.stringify({"user.name":"Alice","user.address.city":"Seoul","user.address.zip":"12345",active:!0},null,2)},{args:[`'{"a":{"b":{"c":{"d":{"e":"deep"}}}}}'`],result:JSON.stringify({"a.b.c.d.e":"deep"},null,2)}],returnType:"JsonObject",returnDescription:'Flattened object with dot-notation keys \u2014 e.g. { "a.b.c": value }',guidelines:["Arrays and primitives at any level are always treated as leaf values \u2014 they are never traversed.","The result is always a flat JSON object with dot-notation keys.","There is no depth limit \u2014 objects of any nesting level are fully flattened.","Input is accepted as a JSON string (MCP/CLI) and parsed internally."]}},J=b.objectFlattenTool;var u=require("zod");function C(e){let n=typeof e=="string"?JSON.parse(e):e,{first:t,last:o}=n.name,s=n.location.city;return`\uC774\uB984\uC740 ${t} ${o} \uC774\uACE0 \uD604\uC7AC ${s} \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4.`}var x={getUserTool:{name:"getUser",description:"RandomUser API \uD615\uC2DD\uC758 \uC0AC\uC6A9\uC790 \uAC1D\uCCB4\uB97C \uBC1B\uC544 \uC774\uB984\uACFC \uAC70\uC8FC \uB3C4\uC2DC\uB85C \uAD6C\uC131\uB41C \uD55C\uAE00 \uBB38\uC7A5\uC744 \uBC18\uD658\uD569\uB2C8\uB2E4. JSON \uBB38\uC790\uC5F4 \uB610\uB294 \uD30C\uC2F1\uB41C \uAC1D\uCCB4\uB97C \uC785\uB825\uBC1B\uC2B5\uB2C8\uB2E4.",inputSchema:{user:u.z.union([u.z.string(),u.z.record(u.z.string(),u.z.any())]).describe("RandomUser \uD615\uC2DD\uC758 JSON \uBB38\uC790\uC5F4 \uB610\uB294 \uAC1D\uCCB4 \u2014 name.first / name.last / location.city \uD544\uC218")},typeLabels:{user:"RandomUser"},typeDefs:{user:["interface RandomUser {",' gender: "male" | "female";'," name: {"," title: string;"," first: string;"," last: string;"," };"," location: {"," street: {"," number: number;"," name: string;"," };"," city: string;"," state: string;"," country: string;"," postcode: string | number;"," coordinates: {"," latitude: string;"," longitude: string;"," };"," timezone: {"," offset: string;"," description: string;"," };"," };"," email: string;"," login: {"," uuid: string;"," username: string;"," };"," dob: {"," date: string;"," age: number;"," };"," phone: string;"," cell: string;"," picture: {"," large: string;"," medium: string;"," thumbnail: string;"," };"," nat: string;","}"].join(`
|
|
4
|
+
`)},returnType:"string",returnDescription:'"\uC774\uB984\uC740 {first} {last} \uC774\uACE0 \uD604\uC7AC {city} \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4." \uD615\uC2DD\uC758 \uD55C\uAE00 \uBB38\uC7A5',handler:async({user:e})=>{try{let t=C(e);return r(t)}catch(n){return n instanceof SyntaxError?r("Error: invalid JSON string \u2014 unable to parse input"):r(`Error: failed to process user data \u2014 ${n.message}
|
|
5
|
+
|
|
6
|
+
Input must include \`name.first\`, \`name.last\`, and \`location.city\`.`)}},examples:[{args:[`'{"name":{"title":"Mr","first":"Alice","last":"Kim"},"location":{"city":"Seoul"},"gender":"female","email":"alice@example.com","nat":"KR"}'`],result:"\uC774\uB984\uC740 Alice Kim \uC774\uACE0 \uD604\uC7AC Seoul \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4."}],guidelines:["\uC785\uB825\uC740 RandomUser API \uC2A4\uD399\uC744 \uB530\uB985\uB2C8\uB2E4. \uCD5C\uC18C\uD55C name.first, name.last, location.city \uD544\uB4DC\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.","JSON \uBB38\uC790\uC5F4(string)\uACFC \uD30C\uC2F1\uB41C \uAC1D\uCCB4 \uBAA8\uB450 \uD5C8\uC6A9\uB429\uB2C8\uB2E4 (CLI / MCP \uBAA8\uB450 \uB3D9\uC791).","\uACB0\uACFC\uB294 \uD56D\uC0C1 '\uC774\uB984\uC740 {first} {last} \uC774\uACE0 \uD604\uC7AC {city} \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4.' \uD615\uC2DD\uC758 \uD55C\uAE00 \uBB38\uC7A5\uC785\uB2C8\uB2E4."]}},U=x.getUserTool;var S=require("zod"),l=["API_KEY"];function L(e){let n=e.filter(o=>!l.includes(o));if(n.length>0)throw new Error(`Invalid env key(s): ${n.join(", ")}. Allowed keys: ${l.join(", ")}`);let t={};for(let o of e){let s=process.env[o];s!==void 0&&(t[o]=s)}return t}var $={envGetTool:{name:"env_get",description:`MCP \uD074\uB77C\uC774\uC5B8\uD2B8 config\uC758 env \uD544\uB4DC\uB97C \uD1B5\uD574 \uC8FC\uC785\uB41C \uD658\uACBD \uBCC0\uC218 \uAC12\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4. \uC870\uD68C \uAC00\uB2A5\uD55C \uD0A4\uB294 \uD328\uD0A4\uC9C0\uC5D0\uC11C \uC81C\uACF5\uD558\uB294 \uD658\uACBD \uBCC0\uC218\uB85C \uD55C\uC815\uB429\uB2C8\uB2E4. \uD604\uC7AC \uC9C0\uC6D0: ${l.join(", ")}.`,inputSchema:{keys:S.z.array(S.z.string()).nonempty().describe(`\uC870\uD68C\uD560 \uD658\uACBD \uBCC0\uC218 \uC774\uB984 \uBAA9\uB85D (\uC720\uD6A8 \uD0A4: ${l.join(", ")})`)},typeLabels:{keys:"string[]"},typeDefs:{keys:["// @julong/mono-rele2-utils \uD658\uACBD \uBCC0\uC218 \uD0A4 \uBAA9\uB85D",...l.map(e=>`// "${e}"`),"","// MCP client config \uC608\uC2DC:","// {",'// "mcpServers": {','// "@julong/mono-rele2-utils": {','// "command": "npx",','// "args": ["-y", "@julong/mono-rele2-utils"],','// "env": {',...l.map(e=>`// "${e}": "<value>"`),"// }","// }","// }","// }"].join(`
|
|
7
|
+
`)},returnType:"Record<string, string>",returnDescription:"key: \uD658\uACBD \uBCC0\uC218 \uC774\uB984, value: \uD574\uB2F9 \uAC12 (\uC124\uC815\uB418\uC9C0 \uC54A\uC740 \uBCC0\uC218\uB294 \uACB0\uACFC\uC5D0\uC11C \uC81C\uC678)",handler:async({keys:e})=>{try{let n=L(e);return Object.keys(n).length===0?r("(no matching environment variables found)"):r(JSON.stringify(n,null,2))}catch(n){return r(`Error: ${n.message}`)}},examples:[{args:[`'["API_KEY"]'`],result:JSON.stringify({API_KEY:"<value>"},null,2)}],guidelines:[`\uC870\uD68C \uAC00\uB2A5\uD55C \uD0A4: ${l.join(", ")}`,"MCP client config.json\uC758 env \uD544\uB4DC\uC5D0 \uC704 \uD0A4\uB4E4\uB9CC \uC124\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.","\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD0A4\uB97C \uC694\uCCAD\uD558\uBA74 \uC5D0\uB7EC \uBA54\uC2DC\uC9C0\uC5D0 \uD5C8\uC6A9\uB41C \uD0A4 \uBAA9\uB85D\uC774 \uD45C\uC2DC\uB429\uB2C8\uB2E4.","\uC124\uC815\uB418\uC9C0 \uC54A\uC740 \uD658\uACBD \uBCC0\uC218\uB294 \uACB0\uACFC \uAC1D\uCCB4\uC5D0\uC11C \uC81C\uC678\uB429\uB2C8\uB2E4."]}},_=$.envGetTool;var v={...d,...b,...x,...$};j(v).catch(Z);
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
function r(e){return{content:[{type:"text",text:e}]}}import{McpServer as
|
|
3
|
-
`),process.exit(n?1:0));let o=e[n],s=Object.keys(o.inputSchema),l={};for(let i=0;i<s.length;i++){let g=t[i];if(g!==void 0)try{l[s[i]]=JSON.parse(g)}catch{l[s[i]]=g}}let f=S.object(o.inputSchema).parse(l),m=await o.handler(f);for(let i of m.content)i.type==="text"&&console.log(i.text)}function j(e){e instanceof S.ZodError?console.error("Validation error:",e.issues.map(n=>`${n.path.join(".")}: ${n.message}`).join(", ")):console.error("Error:",e instanceof Error?e.message:String(e)),process.exit(1)}import{z as G}from"zod";import{z as c}from"zod";function Z(...e){return e.filter(Boolean).join(" ")}var p={cnTool:{name:"cn",description:"Merges class names, filtering out falsy values",inputSchema:{classes:c.array(c.string()).describe("List of class names to merge")},typeLabels:{classes:"string[]"},returnType:"string",returnDescription:"Merged class name string with falsy values filtered out",handler:async({classes:e})=>r(Z(...e)),examples:[{args:[`'["btn","active","large"]'`],result:"btn active large"}]},caseConvertTool:{name:"case_convert",description:"Converts text to the specified case format",inputSchema:{input:c.string().describe("Text to convert"),to:c.enum(["upper","lower","capitalize","camel","snake","kebab"]).describe("Target case format")},typeLabels:{input:"string",to:'"upper" | "lower" | "capitalize" | "camel" | "snake" | "kebab"'},returnType:"string",returnDescription:"Converted text in the target case format",handler:async({input:e,to:n})=>r(z(e,n)),examples:[{args:['"hello world"',"camel"],result:"helloWorld"},{args:['"helloWorld"',"snake"],result:"hello_world"},{args:['"hello world"',"kebab"],result:"hello-world"}]},truncateTool:{name:"truncate",description:"Truncates text to a maximum length and appends a suffix",inputSchema:{input:c.string().describe("Text to truncate"),maxLength:c.number().int().positive().describe("Maximum character length"),suffix:c.string().default("...").describe("Suffix to append when truncated")},typeLabels:{input:"string",maxLength:"number",suffix:"string"},returnType:"string",returnDescription:"Truncated text with the configured suffix appended if truncated",handler:async({input:e,maxLength:n,suffix:t})=>{let o=e.length<=n?e:e.slice(0,n-t.length)+t;return r(o)},examples:[{args:['"hello world long text"',"10"],result:"hello w..."},{args:['"hello world"',"8",'"\u2026"'],result:"hello w\u2026"}]}},O=p.cnTool,A=p.caseConvertTool,k=p.truncateTool;function z(e,n){switch(n){case"upper":return e.toUpperCase();case"lower":return e.toLowerCase();case"capitalize":return e.charAt(0).toUpperCase()+e.slice(1).toLowerCase();case"camel":return e.replace(/[-_\s]+(.)/g,(t,o)=>o.toUpperCase()).replace(/^(.)/,t=>t.toLowerCase());case"snake":return e.replace(/([A-Z])/g,"_$1").replace(/[-\s]+/g,"_").toLowerCase().replace(/^_/,"");case"kebab":return e.replace(/([A-Z])/g,"-$1").replace(/[_\s]+/g,"-").toLowerCase().replace(/^-/,"")}}import{z as u}from"zod";function D(e){let n=typeof e=="string"?JSON.parse(e):e,t={};function o(s,l){if(s===null||typeof s!="object"||Array.isArray(s)){t[l]=s;return}for(let[f,m]of Object.entries(s)){let i=l?`${l}.${f}`:f;o(m,i)}}return o(n,""),t}var h={objectFlattenTool:{name:"object_flatten",description:"Flattens a nested JSON object of any depth into dot-notation key-value pairs. Accepts a JSON string and recursively flattens all levels. Arrays and primitives at any level are treated as leaf values.",inputSchema:{json:u.union([u.string(),u.record(u.string(),u.any())]).describe("JSON string or parsed object to flatten (unlimited depth)")},handler:async({json:e})=>{try{let t=D(e);return r(JSON.stringify(t,null,2))}catch(n){return n instanceof SyntaxError?r("Error: invalid JSON string \u2014 unable to parse input"):r(`Error: failed to flatten object \u2014 ${n.message}`)}},examples:[{args:[`'{"user":{"name":"Alice","address":{"city":"Seoul","zip":"12345"}},"active":true}'`],result:JSON.stringify({"user.name":"Alice","user.address.city":"Seoul","user.address.zip":"12345",active:!0},null,2)},{args:[`'{"a":{"b":{"c":{"d":{"e":"deep"}}}}}'`],result:JSON.stringify({"a.b.c.d.e":"deep"},null,2)}],returnType:"JsonObject",returnDescription:'Flattened object with dot-notation keys \u2014 e.g. { "a.b.c": value }',guidelines:["Arrays and primitives at any level are always treated as leaf values \u2014 they are never traversed.","The result is always a flat JSON object with dot-notation keys.","There is no depth limit \u2014 objects of any nesting level are fully flattened.","Input is accepted as a JSON string (MCP/CLI) and parsed internally."]}},R=h.objectFlattenTool;import{z as d}from"zod";function
|
|
4
|
-
`)},returnType:"string",returnDescription:'"\uC774\uB984\uC740 {first} {last} \uC774\uACE0 \uD604\uC7AC {city} \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4." \uD615\uC2DD\uC758 \uD55C\uAE00 \uBB38\uC7A5',handler:async({user:e})=>{try{let t=
|
|
2
|
+
function r(e){return{content:[{type:"text",text:e}]}}import{McpServer as M}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as I}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as S}from"zod";async function $(e){let[,,n,...t]=process.argv;(!n||!(n in e))&&(n&&console.error(`Unknown skill: "${n}"
|
|
3
|
+
`),process.exit(n?1:0));let o=e[n],s=Object.keys(o.inputSchema),l={};for(let i=0;i<s.length;i++){let g=t[i];if(g!==void 0)try{l[s[i]]=JSON.parse(g)}catch{l[s[i]]=g}}let f=S.object(o.inputSchema).parse(l),m=await o.handler(f);for(let i of m.content)i.type==="text"&&console.log(i.text)}function j(e){e instanceof S.ZodError?console.error("Validation error:",e.issues.map(n=>`${n.path.join(".")}: ${n.message}`).join(", ")):console.error("Error:",e instanceof Error?e.message:String(e)),process.exit(1)}import{z as G}from"zod";import{z as c}from"zod";function Z(...e){return e.filter(Boolean).join(" ")}var p={cnTool:{name:"cn",description:"Merges class names, filtering out falsy values",inputSchema:{classes:c.array(c.string()).describe("List of class names to merge")},typeLabels:{classes:"string[]"},returnType:"string",returnDescription:"Merged class name string with falsy values filtered out",handler:async({classes:e})=>r(Z(...e)),examples:[{args:[`'["btn","active","large"]'`],result:"btn active large"}]},caseConvertTool:{name:"case_convert",description:"Converts text to the specified case format",inputSchema:{input:c.string().describe("Text to convert"),to:c.enum(["upper","lower","capitalize","camel","snake","kebab"]).describe("Target case format")},typeLabels:{input:"string",to:'"upper" | "lower" | "capitalize" | "camel" | "snake" | "kebab"'},returnType:"string",returnDescription:"Converted text in the target case format",handler:async({input:e,to:n})=>r(z(e,n)),examples:[{args:['"hello world"',"camel"],result:"helloWorld"},{args:['"helloWorld"',"snake"],result:"hello_world"},{args:['"hello world"',"kebab"],result:"hello-world"}]},truncateTool:{name:"truncate",description:"Truncates text to a maximum length and appends a suffix",inputSchema:{input:c.string().describe("Text to truncate"),maxLength:c.number().int().positive().describe("Maximum character length"),suffix:c.string().default("...").describe("Suffix to append when truncated")},typeLabels:{input:"string",maxLength:"number",suffix:"string"},returnType:"string",returnDescription:"Truncated text with the configured suffix appended if truncated",handler:async({input:e,maxLength:n,suffix:t})=>{let o=e.length<=n?e:e.slice(0,n-t.length)+t;return r(o)},examples:[{args:['"hello world long text"',"10"],result:"hello w..."},{args:['"hello world"',"8",'"\u2026"'],result:"hello w\u2026"}]}},O=p.cnTool,A=p.caseConvertTool,k=p.truncateTool;function z(e,n){switch(n){case"upper":return e.toUpperCase();case"lower":return e.toLowerCase();case"capitalize":return e.charAt(0).toUpperCase()+e.slice(1).toLowerCase();case"camel":return e.replace(/[-_\s]+(.)/g,(t,o)=>o.toUpperCase()).replace(/^(.)/,t=>t.toLowerCase());case"snake":return e.replace(/([A-Z])/g,"_$1").replace(/[-\s]+/g,"_").toLowerCase().replace(/^_/,"");case"kebab":return e.replace(/([A-Z])/g,"-$1").replace(/[_\s]+/g,"-").toLowerCase().replace(/^-/,"")}}import{z as u}from"zod";function D(e){let n=typeof e=="string"?JSON.parse(e):e,t={};function o(s,l){if(s===null||typeof s!="object"||Array.isArray(s)){t[l]=s;return}for(let[f,m]of Object.entries(s)){let i=l?`${l}.${f}`:f;o(m,i)}}return o(n,""),t}var h={objectFlattenTool:{name:"object_flatten",description:"Flattens a nested JSON object of any depth into dot-notation key-value pairs. Accepts a JSON string and recursively flattens all levels. Arrays and primitives at any level are treated as leaf values.",inputSchema:{json:u.union([u.string(),u.record(u.string(),u.any())]).describe("JSON string or parsed object to flatten (unlimited depth)")},handler:async({json:e})=>{try{let t=D(e);return r(JSON.stringify(t,null,2))}catch(n){return n instanceof SyntaxError?r("Error: invalid JSON string \u2014 unable to parse input"):r(`Error: failed to flatten object \u2014 ${n.message}`)}},examples:[{args:[`'{"user":{"name":"Alice","address":{"city":"Seoul","zip":"12345"}},"active":true}'`],result:JSON.stringify({"user.name":"Alice","user.address.city":"Seoul","user.address.zip":"12345",active:!0},null,2)},{args:[`'{"a":{"b":{"c":{"d":{"e":"deep"}}}}}'`],result:JSON.stringify({"a.b.c.d.e":"deep"},null,2)}],returnType:"JsonObject",returnDescription:'Flattened object with dot-notation keys \u2014 e.g. { "a.b.c": value }',guidelines:["Arrays and primitives at any level are always treated as leaf values \u2014 they are never traversed.","The result is always a flat JSON object with dot-notation keys.","There is no depth limit \u2014 objects of any nesting level are fully flattened.","Input is accepted as a JSON string (MCP/CLI) and parsed internally."]}},R=h.objectFlattenTool;import{z as d}from"zod";function N(e){let n=typeof e=="string"?JSON.parse(e):e,{first:t,last:o}=n.name,s=n.location.city;return`\uC774\uB984\uC740 ${t} ${o} \uC774\uACE0 \uD604\uC7AC ${s} \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4.`}var b={getUserTool:{name:"getUser",description:"RandomUser API \uD615\uC2DD\uC758 \uC0AC\uC6A9\uC790 \uAC1D\uCCB4\uB97C \uBC1B\uC544 \uC774\uB984\uACFC \uAC70\uC8FC \uB3C4\uC2DC\uB85C \uAD6C\uC131\uB41C \uD55C\uAE00 \uBB38\uC7A5\uC744 \uBC18\uD658\uD569\uB2C8\uB2E4. JSON \uBB38\uC790\uC5F4 \uB610\uB294 \uD30C\uC2F1\uB41C \uAC1D\uCCB4\uB97C \uC785\uB825\uBC1B\uC2B5\uB2C8\uB2E4.",inputSchema:{user:d.union([d.string(),d.record(d.string(),d.any())]).describe("RandomUser \uD615\uC2DD\uC758 JSON \uBB38\uC790\uC5F4 \uB610\uB294 \uAC1D\uCCB4 \u2014 name.first / name.last / location.city \uD544\uC218")},typeLabels:{user:"RandomUser"},typeDefs:{user:["interface RandomUser {",' gender: "male" | "female";'," name: {"," title: string;"," first: string;"," last: string;"," };"," location: {"," street: {"," number: number;"," name: string;"," };"," city: string;"," state: string;"," country: string;"," postcode: string | number;"," coordinates: {"," latitude: string;"," longitude: string;"," };"," timezone: {"," offset: string;"," description: string;"," };"," };"," email: string;"," login: {"," uuid: string;"," username: string;"," };"," dob: {"," date: string;"," age: number;"," };"," phone: string;"," cell: string;"," picture: {"," large: string;"," medium: string;"," thumbnail: string;"," };"," nat: string;","}"].join(`
|
|
4
|
+
`)},returnType:"string",returnDescription:'"\uC774\uB984\uC740 {first} {last} \uC774\uACE0 \uD604\uC7AC {city} \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4." \uD615\uC2DD\uC758 \uD55C\uAE00 \uBB38\uC7A5',handler:async({user:e})=>{try{let t=N(e);return r(t)}catch(n){return n instanceof SyntaxError?r("Error: invalid JSON string \u2014 unable to parse input"):r(`Error: failed to process user data \u2014 ${n.message}
|
|
5
5
|
|
|
6
|
-
Input must include \`name.first\`, \`name.last\`, and \`location.city\`.`)}},examples:[{args:[`'{"name":{"title":"Mr","first":"Alice","last":"Kim"},"location":{"city":"Seoul"},"gender":"female","email":"alice@example.com","nat":"KR"}'`],result:"\uC774\uB984\uC740 Alice Kim \uC774\uACE0 \uD604\uC7AC Seoul \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4."}],guidelines:["\uC785\uB825\uC740 RandomUser API \uC2A4\uD399\uC744 \uB530\uB985\uB2C8\uB2E4. \uCD5C\uC18C\uD55C name.first, name.last, location.city \uD544\uB4DC\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.","JSON \uBB38\uC790\uC5F4(string)\uACFC \uD30C\uC2F1\uB41C \uAC1D\uCCB4 \uBAA8\uB450 \uD5C8\uC6A9\uB429\uB2C8\uB2E4 (CLI / MCP \uBAA8\uB450 \uB3D9\uC791).","\uACB0\uACFC\uB294 \uD56D\uC0C1 '\uC774\uB984\uC740 {first} {last} \uC774\uACE0 \uD604\uC7AC {city} \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4.' \uD615\uC2DD\uC758 \uD55C\uAE00 \uBB38\uC7A5\uC785\uB2C8\uB2E4."]}},
|
|
6
|
+
Input must include \`name.first\`, \`name.last\`, and \`location.city\`.`)}},examples:[{args:[`'{"name":{"title":"Mr","first":"Alice","last":"Kim"},"location":{"city":"Seoul"},"gender":"female","email":"alice@example.com","nat":"KR"}'`],result:"\uC774\uB984\uC740 Alice Kim \uC774\uACE0 \uD604\uC7AC Seoul \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4."}],guidelines:["\uC785\uB825\uC740 RandomUser API \uC2A4\uD399\uC744 \uB530\uB985\uB2C8\uB2E4. \uCD5C\uC18C\uD55C name.first, name.last, location.city \uD544\uB4DC\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.","JSON \uBB38\uC790\uC5F4(string)\uACFC \uD30C\uC2F1\uB41C \uAC1D\uCCB4 \uBAA8\uB450 \uD5C8\uC6A9\uB429\uB2C8\uB2E4 (CLI / MCP \uBAA8\uB450 \uB3D9\uC791).","\uACB0\uACFC\uB294 \uD56D\uC0C1 '\uC774\uB984\uC740 {first} {last} \uC774\uACE0 \uD604\uC7AC {city} \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4.' \uD615\uC2DD\uC758 \uD55C\uAE00 \uBB38\uC7A5\uC785\uB2C8\uB2E4."]}},E=b.getUserTool;import{z as w}from"zod";var a=["API_KEY"];function J(e){let n=e.filter(o=>!a.includes(o));if(n.length>0)throw new Error(`Invalid env key(s): ${n.join(", ")}. Allowed keys: ${a.join(", ")}`);let t={};for(let o of e){let s=process.env[o];s!==void 0&&(t[o]=s)}return t}var x={envGetTool:{name:"env_get",description:`MCP \uD074\uB77C\uC774\uC5B8\uD2B8 config\uC758 env \uD544\uB4DC\uB97C \uD1B5\uD574 \uC8FC\uC785\uB41C \uD658\uACBD \uBCC0\uC218 \uAC12\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4. \uC870\uD68C \uAC00\uB2A5\uD55C \uD0A4\uB294 \uD328\uD0A4\uC9C0\uC5D0\uC11C \uC81C\uACF5\uD558\uB294 \uD658\uACBD \uBCC0\uC218\uB85C \uD55C\uC815\uB429\uB2C8\uB2E4. \uD604\uC7AC \uC9C0\uC6D0: ${a.join(", ")}.`,inputSchema:{keys:w.array(w.string()).nonempty().describe(`\uC870\uD68C\uD560 \uD658\uACBD \uBCC0\uC218 \uC774\uB984 \uBAA9\uB85D (\uC720\uD6A8 \uD0A4: ${a.join(", ")})`)},typeLabels:{keys:"string[]"},typeDefs:{keys:["// @julong/mono-rele2-utils \uD658\uACBD \uBCC0\uC218 \uD0A4 \uBAA9\uB85D",...a.map(e=>`// "${e}"`),"","// MCP client config \uC608\uC2DC:","// {",'// "mcpServers": {','// "@julong/mono-rele2-utils": {','// "command": "npx",','// "args": ["-y", "@julong/mono-rele2-utils"],','// "env": {',...a.map(e=>`// "${e}": "<value>"`),"// }","// }","// }","// }"].join(`
|
|
7
7
|
`)},returnType:"Record<string, string>",returnDescription:"key: \uD658\uACBD \uBCC0\uC218 \uC774\uB984, value: \uD574\uB2F9 \uAC12 (\uC124\uC815\uB418\uC9C0 \uC54A\uC740 \uBCC0\uC218\uB294 \uACB0\uACFC\uC5D0\uC11C \uC81C\uC678)",handler:async({keys:e})=>{try{let n=J(e);return Object.keys(n).length===0?r("(no matching environment variables found)"):r(JSON.stringify(n,null,2))}catch(n){return r(`Error: ${n.message}`)}},examples:[{args:[`'["API_KEY"]'`],result:JSON.stringify({API_KEY:"<value>"},null,2)}],guidelines:[`\uC870\uD68C \uAC00\uB2A5\uD55C \uD0A4: ${a.join(", ")}`,"MCP client config.json\uC758 env \uD544\uB4DC\uC5D0 \uC704 \uD0A4\uB4E4\uB9CC \uC124\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.","\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD0A4\uB97C \uC694\uCCAD\uD558\uBA74 \uC5D0\uB7EC \uBA54\uC2DC\uC9C0\uC5D0 \uD5C8\uC6A9\uB41C \uD0A4 \uBAA9\uB85D\uC774 \uD45C\uC2DC\uB429\uB2C8\uB2E4.","\uC124\uC815\uB418\uC9C0 \uC54A\uC740 \uD658\uACBD \uBCC0\uC218\uB294 \uACB0\uACFC \uAC1D\uCCB4\uC5D0\uC11C \uC81C\uC678\uB429\uB2C8\uB2E4."]}},C=x.envGetTool;var v={...p,...h,...b,...x};$(v).catch(j);
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";var $=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var U=Object.getOwnPropertyNames;var L=Object.prototype.hasOwnProperty;var M=(n,t)=>{for(var e in t)$(n,e,{get:t[e],enumerable:!0})},_=(n,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of U(t))!L.call(n,r)&&r!==e&&$(n,r,{get:()=>t[r],enumerable:!(o=C(t,r))||o.enumerable});return n};var P=n=>_($({},"__esModule",{value:!0}),n);var ae={};M(ae,{cn:()=>h,generateReadmeSkills:()=>D,generateSkillMarkdown:()=>z,tools:()=>N});module.exports=P(ae);function h(...n){return n.filter(Boolean).join(" ")}function l(n){return{content:[{type:"text",text:n}]}}var I=require("@modelcontextprotocol/sdk/server/mcp.js"),V=require("@modelcontextprotocol/sdk/server/stdio.js");var K=require("zod");var i=require("zod");function z(n){let{binName:t,description:e,tools:o}=n;return`---
|
|
2
|
+
name: ${t}
|
|
3
|
+
description: ${e}
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ${t}
|
|
7
|
+
|
|
8
|
+
\`\`\`sh
|
|
9
|
+
${t} <toolName> [...args]
|
|
10
|
+
\`\`\`
|
|
11
|
+
|
|
12
|
+
## Skills
|
|
13
|
+
|
|
14
|
+
${B(o)}
|
|
15
|
+
|
|
16
|
+
## Examples
|
|
17
|
+
|
|
18
|
+
${G(t,o)}
|
|
19
|
+
|
|
20
|
+
## Guidelines
|
|
21
|
+
|
|
22
|
+
${Y(t,o)}
|
|
23
|
+
`}function B(n){return Object.entries(n).map(([t,e])=>{let o=Object.entries(e.inputSchema).map(([a,s])=>{let c=e.typeLabels?.[a];return`| \`${a}\` | ${F(s,c)} |`}).join(`
|
|
24
|
+
`),r=e.typeDefs?Object.entries(e.typeDefs).map(([a,s])=>`
|
|
25
|
+
|
|
26
|
+
**\`${a}\`** type definition:
|
|
27
|
+
\`\`\`typescript
|
|
28
|
+
${s}
|
|
29
|
+
\`\`\``).join(""):"";return`### ${t}
|
|
30
|
+
|
|
31
|
+
${e.description}
|
|
32
|
+
|
|
33
|
+
| arg | description |
|
|
34
|
+
|-----|-------------|
|
|
35
|
+
${o}${r}`}).join(`
|
|
36
|
+
|
|
37
|
+
`)}function F(n,t){let e=n.description??"",o=n,r,a=!1;for(;o instanceof i.z.ZodOptional||o instanceof i.z.ZodDefault;){if(o instanceof i.z.ZodDefault){let c=o.def.defaultValue;r=typeof c=="function"?c():c}o instanceof i.z.ZodOptional&&(a=!0),o=o.unwrap()}let s=[];if(t&&s.push(`Type: ${t}`),e&&s.push(e),o instanceof i.z.ZodEnum){let c=o.options.map(g=>`\`${g}\``).join(" \\| ");s.push(c)}return r!==void 0?s.push(`default: \`${String(r)}\``):a&&s.push("optional"),s.join(" \u2014 ")}function G(n,t){let e=[];for(let[o,r]of Object.entries(t))if(r.examples)for(let a of r.examples){let s=[n,o,...a.args].join(" ");e.push(`- \`${s}\` => \`${a.result}\``)}return e.join(`
|
|
38
|
+
`)}function Y(n,t){let e=[],o=new Set,r=s=>{o.has(s)||(o.add(s),e.push(s))};r("Arguments are positional \u2014 pass them in the order listed in each skill's table");let a=Object.values(t).flatMap(s=>Object.values(s.inputSchema));a.some(s=>k(s,i.z.ZodNumber))&&r("Numeric args are auto-parsed \u2014 pass as plain numbers (e.g. `10`)"),a.some(s=>k(s,i.z.ZodArray))&&r('Array args must be valid JSON \u2014 wrap in single quotes on Unix shells (e.g. `\'["a","b"]\'`)'),a.some(s=>s instanceof i.z.ZodOptional||s instanceof i.z.ZodDefault)&&r("Optional args with defaults may be omitted");for(let s of Object.values(t))if(s.guidelines)for(let c of s.guidelines)r(c);return r(`Run \`${n}\` with no args to list all available skills`),e.map(s=>`- ${s}`).join(`
|
|
39
|
+
`)}function k(n,t){let e=n;for(;e instanceof i.z.ZodOptional||e instanceof i.z.ZodDefault;)e=e.unwrap();return e instanceof t}function D(n){let{binName:t,tools:e}=n;return Object.entries(e).map(([o,r])=>W(t,o,r)).join(`
|
|
40
|
+
|
|
41
|
+
`)}function W(n,t,e){let o=Object.entries(e.inputSchema),r=o.map(([p,u])=>u instanceof i.z.ZodOptional||u instanceof i.z.ZodDefault?`[${p}]`:`<${p}>`).join(" "),a=[n,t,r].filter(Boolean).join(" "),s=o.map(([p,u])=>{let x=e.typeLabels?.[p],m=R(u,x),S=q(u);return`| \`${p}\` | ${m} | ${S} |`}).join(`
|
|
42
|
+
`),c=e.examples??[],g="";if(c.length>0){let p=c.map(m=>[n,t,...m.args].join(" ")),u=Math.max(...p.map(m=>m.length));g=`
|
|
43
|
+
|
|
44
|
+
\`\`\`sh
|
|
45
|
+
${c.map((m,S)=>`${p[S].padEnd(u)} # ${m.result}`).join(`
|
|
46
|
+
`)}
|
|
47
|
+
\`\`\``}let E=e.typeDefs?Object.entries(e.typeDefs).map(([p,u])=>`
|
|
48
|
+
|
|
49
|
+
**\`${p}\`** type definition:
|
|
50
|
+
|
|
51
|
+
\`\`\`typescript
|
|
52
|
+
${u}
|
|
53
|
+
\`\`\``).join(""):"",J=s?`
|
|
54
|
+
|
|
55
|
+
| arg | type | description |
|
|
56
|
+
|-----|------|-------------|
|
|
57
|
+
${s}`:"";return`#### \`${t}\`
|
|
58
|
+
|
|
59
|
+
${e.description}.
|
|
60
|
+
|
|
61
|
+
\`\`\`sh
|
|
62
|
+
${a}
|
|
63
|
+
\`\`\`${J}${E}${g}`}function R(n,t){if(t)return t;let e=n;for(;e instanceof i.z.ZodOptional||e instanceof i.z.ZodDefault;)e=e.unwrap();return e instanceof i.z.ZodEnum?e.options.map(o=>`\`${o}\``).join(" \\| "):e instanceof i.z.ZodNumber?"number":e instanceof i.z.ZodString?"string":e instanceof i.z.ZodBoolean?"boolean":e instanceof i.z.ZodArray?"JSON string (array)":e instanceof i.z.ZodUnion?e.options.map(r=>R(r)).join(" \\| "):e instanceof i.z.ZodRecord?"JSON object":"unknown"}function q(n){let t=n.description??"",e=n,o,r=!1;for(;e instanceof i.z.ZodOptional||e instanceof i.z.ZodDefault;){if(e instanceof i.z.ZodDefault){let a=e.def.defaultValue;o=typeof a=="function"?a():a}e instanceof i.z.ZodOptional&&(r=!0),e=e.unwrap()}return o!==void 0?`${t} (default: \`${String(o)}\`)`:r?`${t} (optional)`:t}var d=require("zod");var b={cnTool:{name:"cn",description:"Merges class names, filtering out falsy values",inputSchema:{classes:d.z.array(d.z.string()).describe("List of class names to merge")},typeLabels:{classes:"string[]"},returnType:"string",returnDescription:"Merged class name string with falsy values filtered out",handler:async({classes:n})=>l(h(...n)),examples:[{args:[`'["btn","active","large"]'`],result:"btn active large"}]},caseConvertTool:{name:"case_convert",description:"Converts text to the specified case format",inputSchema:{input:d.z.string().describe("Text to convert"),to:d.z.enum(["upper","lower","capitalize","camel","snake","kebab"]).describe("Target case format")},typeLabels:{input:"string",to:'"upper" | "lower" | "capitalize" | "camel" | "snake" | "kebab"'},returnType:"string",returnDescription:"Converted text in the target case format",handler:async({input:n,to:t})=>l(ee(n,t)),examples:[{args:['"hello world"',"camel"],result:"helloWorld"},{args:['"helloWorld"',"snake"],result:"hello_world"},{args:['"hello world"',"kebab"],result:"hello-world"}]},truncateTool:{name:"truncate",description:"Truncates text to a maximum length and appends a suffix",inputSchema:{input:d.z.string().describe("Text to truncate"),maxLength:d.z.number().int().positive().describe("Maximum character length"),suffix:d.z.string().default("...").describe("Suffix to append when truncated")},typeLabels:{input:"string",maxLength:"number",suffix:"string"},returnType:"string",returnDescription:"Truncated text with the configured suffix appended if truncated",handler:async({input:n,maxLength:t,suffix:e})=>{let o=n.length<=t?n:n.slice(0,t-e.length)+e;return l(o)},examples:[{args:['"hello world long text"',"10"],result:"hello w..."},{args:['"hello world"',"8",'"\u2026"'],result:"hello w\u2026"}]}},H=b.cnTool,Q=b.caseConvertTool,X=b.truncateTool;function ee(n,t){switch(t){case"upper":return n.toUpperCase();case"lower":return n.toLowerCase();case"capitalize":return n.charAt(0).toUpperCase()+n.slice(1).toLowerCase();case"camel":return n.replace(/[-_\s]+(.)/g,(e,o)=>o.toUpperCase()).replace(/^(.)/,e=>e.toLowerCase());case"snake":return n.replace(/([A-Z])/g,"_$1").replace(/[-\s]+/g,"_").toLowerCase().replace(/^_/,"");case"kebab":return n.replace(/([A-Z])/g,"-$1").replace(/[_\s]+/g,"-").toLowerCase().replace(/^-/,"")}}var y=require("zod");function ne(n){let t=typeof n=="string"?JSON.parse(n):n,e={};function o(r,a){if(r===null||typeof r!="object"||Array.isArray(r)){e[a]=r;return}for(let[s,c]of Object.entries(r)){let g=a?`${a}.${s}`:s;o(c,g)}}return o(t,""),e}var w={objectFlattenTool:{name:"object_flatten",description:"Flattens a nested JSON object of any depth into dot-notation key-value pairs. Accepts a JSON string and recursively flattens all levels. Arrays and primitives at any level are treated as leaf values.",inputSchema:{json:y.z.union([y.z.string(),y.z.record(y.z.string(),y.z.any())]).describe("JSON string or parsed object to flatten (unlimited depth)")},handler:async({json:n})=>{try{let e=ne(n);return l(JSON.stringify(e,null,2))}catch(t){return t instanceof SyntaxError?l("Error: invalid JSON string \u2014 unable to parse input"):l(`Error: failed to flatten object \u2014 ${t.message}`)}},examples:[{args:[`'{"user":{"name":"Alice","address":{"city":"Seoul","zip":"12345"}},"active":true}'`],result:JSON.stringify({"user.name":"Alice","user.address.city":"Seoul","user.address.zip":"12345",active:!0},null,2)},{args:[`'{"a":{"b":{"c":{"d":{"e":"deep"}}}}}'`],result:JSON.stringify({"a.b.c.d.e":"deep"},null,2)}],returnType:"JsonObject",returnDescription:'Flattened object with dot-notation keys \u2014 e.g. { "a.b.c": value }',guidelines:["Arrays and primitives at any level are always treated as leaf values \u2014 they are never traversed.","The result is always a flat JSON object with dot-notation keys.","There is no depth limit \u2014 objects of any nesting level are fully flattened.","Input is accepted as a JSON string (MCP/CLI) and parsed internally."]}},te=w.objectFlattenTool;var T=require("zod");function oe(n){let t=typeof n=="string"?JSON.parse(n):n,{first:e,last:o}=t.name,r=t.location.city;return`\uC774\uB984\uC740 ${e} ${o} \uC774\uACE0 \uD604\uC7AC ${r} \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4.`}var v={getUserTool:{name:"getUser",description:"RandomUser API \uD615\uC2DD\uC758 \uC0AC\uC6A9\uC790 \uAC1D\uCCB4\uB97C \uBC1B\uC544 \uC774\uB984\uACFC \uAC70\uC8FC \uB3C4\uC2DC\uB85C \uAD6C\uC131\uB41C \uD55C\uAE00 \uBB38\uC7A5\uC744 \uBC18\uD658\uD569\uB2C8\uB2E4. JSON \uBB38\uC790\uC5F4 \uB610\uB294 \uD30C\uC2F1\uB41C \uAC1D\uCCB4\uB97C \uC785\uB825\uBC1B\uC2B5\uB2C8\uB2E4.",inputSchema:{user:T.z.union([T.z.string(),T.z.record(T.z.string(),T.z.any())]).describe("RandomUser \uD615\uC2DD\uC758 JSON \uBB38\uC790\uC5F4 \uB610\uB294 \uAC1D\uCCB4 \u2014 name.first / name.last / location.city \uD544\uC218")},typeLabels:{user:"RandomUser"},typeDefs:{user:["interface RandomUser {",' gender: "male" | "female";'," name: {"," title: string;"," first: string;"," last: string;"," };"," location: {"," street: {"," number: number;"," name: string;"," };"," city: string;"," state: string;"," country: string;"," postcode: string | number;"," coordinates: {"," latitude: string;"," longitude: string;"," };"," timezone: {"," offset: string;"," description: string;"," };"," };"," email: string;"," login: {"," uuid: string;"," username: string;"," };"," dob: {"," date: string;"," age: number;"," };"," phone: string;"," cell: string;"," picture: {"," large: string;"," medium: string;"," thumbnail: string;"," };"," nat: string;","}"].join(`
|
|
64
|
+
`)},returnType:"string",returnDescription:'"\uC774\uB984\uC740 {first} {last} \uC774\uACE0 \uD604\uC7AC {city} \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4." \uD615\uC2DD\uC758 \uD55C\uAE00 \uBB38\uC7A5',handler:async({user:n})=>{try{let e=oe(n);return l(e)}catch(t){return t instanceof SyntaxError?l("Error: invalid JSON string \u2014 unable to parse input"):l(`Error: failed to process user data \u2014 ${t.message}
|
|
65
|
+
|
|
66
|
+
Input must include \`name.first\`, \`name.last\`, and \`location.city\`.`)}},examples:[{args:[`'{"name":{"title":"Mr","first":"Alice","last":"Kim"},"location":{"city":"Seoul"},"gender":"female","email":"alice@example.com","nat":"KR"}'`],result:"\uC774\uB984\uC740 Alice Kim \uC774\uACE0 \uD604\uC7AC Seoul \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4."}],guidelines:["\uC785\uB825\uC740 RandomUser API \uC2A4\uD399\uC744 \uB530\uB985\uB2C8\uB2E4. \uCD5C\uC18C\uD55C name.first, name.last, location.city \uD544\uB4DC\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.","JSON \uBB38\uC790\uC5F4(string)\uACFC \uD30C\uC2F1\uB41C \uAC1D\uCCB4 \uBAA8\uB450 \uD5C8\uC6A9\uB429\uB2C8\uB2E4 (CLI / MCP \uBAA8\uB450 \uB3D9\uC791).","\uACB0\uACFC\uB294 \uD56D\uC0C1 '\uC774\uB984\uC740 {first} {last} \uC774\uACE0 \uD604\uC7AC {city} \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4.' \uD615\uC2DD\uC758 \uD55C\uAE00 \uBB38\uC7A5\uC785\uB2C8\uB2E4."]}},re=v.getUserTool;var O=require("zod"),f=["API_KEY"];function se(n){let t=n.filter(o=>!f.includes(o));if(t.length>0)throw new Error(`Invalid env key(s): ${t.join(", ")}. Allowed keys: ${f.join(", ")}`);let e={};for(let o of n){let r=process.env[o];r!==void 0&&(e[o]=r)}return e}var A={envGetTool:{name:"env_get",description:`MCP \uD074\uB77C\uC774\uC5B8\uD2B8 config\uC758 env \uD544\uB4DC\uB97C \uD1B5\uD574 \uC8FC\uC785\uB41C \uD658\uACBD \uBCC0\uC218 \uAC12\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4. \uC870\uD68C \uAC00\uB2A5\uD55C \uD0A4\uB294 \uD328\uD0A4\uC9C0\uC5D0\uC11C \uC81C\uACF5\uD558\uB294 \uD658\uACBD \uBCC0\uC218\uB85C \uD55C\uC815\uB429\uB2C8\uB2E4. \uD604\uC7AC \uC9C0\uC6D0: ${f.join(", ")}.`,inputSchema:{keys:O.z.array(O.z.string()).nonempty().describe(`\uC870\uD68C\uD560 \uD658\uACBD \uBCC0\uC218 \uC774\uB984 \uBAA9\uB85D (\uC720\uD6A8 \uD0A4: ${f.join(", ")})`)},typeLabels:{keys:"string[]"},typeDefs:{keys:["// @julong/mono-rele2-utils \uD658\uACBD \uBCC0\uC218 \uD0A4 \uBAA9\uB85D",...f.map(n=>`// "${n}"`),"","// MCP client config \uC608\uC2DC:","// {",'// "mcpServers": {','// "@julong/mono-rele2-utils": {','// "command": "npx",','// "args": ["-y", "@julong/mono-rele2-utils"],','// "env": {',...f.map(n=>`// "${n}": "<value>"`),"// }","// }","// }","// }"].join(`
|
|
67
|
+
`)},returnType:"Record<string, string>",returnDescription:"key: \uD658\uACBD \uBCC0\uC218 \uC774\uB984, value: \uD574\uB2F9 \uAC12 (\uC124\uC815\uB418\uC9C0 \uC54A\uC740 \uBCC0\uC218\uB294 \uACB0\uACFC\uC5D0\uC11C \uC81C\uC678)",handler:async({keys:n})=>{try{let t=se(n);return Object.keys(t).length===0?l("(no matching environment variables found)"):l(JSON.stringify(t,null,2))}catch(t){return l(`Error: ${t.message}`)}},examples:[{args:[`'["API_KEY"]'`],result:JSON.stringify({API_KEY:"<value>"},null,2)}],guidelines:[`\uC870\uD68C \uAC00\uB2A5\uD55C \uD0A4: ${f.join(", ")}`,"MCP client config.json\uC758 env \uD544\uB4DC\uC5D0 \uC704 \uD0A4\uB4E4\uB9CC \uC124\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.","\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD0A4\uB97C \uC694\uCCAD\uD558\uBA74 \uC5D0\uB7EC \uBA54\uC2DC\uC9C0\uC5D0 \uD5C8\uC6A9\uB41C \uD0A4 \uBAA9\uB85D\uC774 \uD45C\uC2DC\uB429\uB2C8\uB2E4.","\uC124\uC815\uB418\uC9C0 \uC54A\uC740 \uD658\uACBD \uBCC0\uC218\uB294 \uACB0\uACFC \uAC1D\uCCB4\uC5D0\uC11C \uC81C\uC678\uB429\uB2C8\uB2E4."]}},ie=A.envGetTool;var N={...b,...w,...v,...A};0&&(module.exports={cn,generateReadmeSkills,generateSkillMarkdown,tools});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import * as zod from 'zod';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
|
|
5
|
+
declare function cn(...classes: (string | undefined | null | false)[]): string;
|
|
6
|
+
|
|
7
|
+
type ToolResult = CallToolResult;
|
|
8
|
+
type ToolExample = {
|
|
9
|
+
args: string[];
|
|
10
|
+
result: string;
|
|
11
|
+
};
|
|
12
|
+
type AnyToolDef = {
|
|
13
|
+
name: string;
|
|
14
|
+
description: string;
|
|
15
|
+
inputSchema: z.ZodRawShape;
|
|
16
|
+
handler: (args: any) => Promise<ToolResult>;
|
|
17
|
+
examples?: ToolExample[];
|
|
18
|
+
guidelines?: string[];
|
|
19
|
+
typeLabels?: Record<string, string>;
|
|
20
|
+
typeDefs?: Record<string, string>;
|
|
21
|
+
returnType?: string;
|
|
22
|
+
returnDescription?: string;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
type SkillTools = Record<string, AnyToolDef>;
|
|
26
|
+
declare function generateSkillMarkdown(opts: {
|
|
27
|
+
binName: string;
|
|
28
|
+
description: string;
|
|
29
|
+
tools: SkillTools;
|
|
30
|
+
}): string;
|
|
31
|
+
declare function generateReadmeSkills(opts: {
|
|
32
|
+
binName: string;
|
|
33
|
+
tools: SkillTools;
|
|
34
|
+
}): string;
|
|
35
|
+
|
|
36
|
+
declare const tools: {
|
|
37
|
+
envGetTool: {
|
|
38
|
+
name: string;
|
|
39
|
+
description: string;
|
|
40
|
+
inputSchema: {
|
|
41
|
+
readonly keys: zod.ZodArray<zod.ZodString>;
|
|
42
|
+
};
|
|
43
|
+
handler: (input: {
|
|
44
|
+
keys: string[];
|
|
45
|
+
}) => Promise<ToolResult>;
|
|
46
|
+
examples?: ToolExample[];
|
|
47
|
+
guidelines?: string[];
|
|
48
|
+
typeLabels?: {
|
|
49
|
+
readonly keys?: string | undefined;
|
|
50
|
+
} | undefined;
|
|
51
|
+
typeDefs?: {
|
|
52
|
+
readonly keys?: string | undefined;
|
|
53
|
+
} | undefined;
|
|
54
|
+
returnType?: string;
|
|
55
|
+
returnDescription?: string;
|
|
56
|
+
};
|
|
57
|
+
getUserTool: {
|
|
58
|
+
name: string;
|
|
59
|
+
description: string;
|
|
60
|
+
inputSchema: {
|
|
61
|
+
readonly user: zod.ZodUnion<readonly [zod.ZodString, zod.ZodRecord<zod.ZodString, zod.ZodAny>]>;
|
|
62
|
+
};
|
|
63
|
+
handler: (input: {
|
|
64
|
+
user: string | Record<string, any>;
|
|
65
|
+
}) => Promise<ToolResult>;
|
|
66
|
+
examples?: ToolExample[];
|
|
67
|
+
guidelines?: string[];
|
|
68
|
+
typeLabels?: {
|
|
69
|
+
readonly user?: string | undefined;
|
|
70
|
+
} | undefined;
|
|
71
|
+
typeDefs?: {
|
|
72
|
+
readonly user?: string | undefined;
|
|
73
|
+
} | undefined;
|
|
74
|
+
returnType?: string;
|
|
75
|
+
returnDescription?: string;
|
|
76
|
+
};
|
|
77
|
+
objectFlattenTool: {
|
|
78
|
+
name: string;
|
|
79
|
+
description: string;
|
|
80
|
+
inputSchema: {
|
|
81
|
+
readonly json: zod.ZodUnion<readonly [zod.ZodString, zod.ZodRecord<zod.ZodString, zod.ZodAny>]>;
|
|
82
|
+
};
|
|
83
|
+
handler: (input: {
|
|
84
|
+
json: string | Record<string, any>;
|
|
85
|
+
}) => Promise<ToolResult>;
|
|
86
|
+
examples?: ToolExample[];
|
|
87
|
+
guidelines?: string[];
|
|
88
|
+
typeLabels?: {
|
|
89
|
+
readonly json?: string | undefined;
|
|
90
|
+
} | undefined;
|
|
91
|
+
typeDefs?: {
|
|
92
|
+
readonly json?: string | undefined;
|
|
93
|
+
} | undefined;
|
|
94
|
+
returnType?: string;
|
|
95
|
+
returnDescription?: string;
|
|
96
|
+
};
|
|
97
|
+
cnTool: {
|
|
98
|
+
name: string;
|
|
99
|
+
description: string;
|
|
100
|
+
inputSchema: {
|
|
101
|
+
readonly classes: zod.ZodArray<zod.ZodString>;
|
|
102
|
+
};
|
|
103
|
+
handler: (input: {
|
|
104
|
+
classes: string[];
|
|
105
|
+
}) => Promise<ToolResult>;
|
|
106
|
+
examples?: ToolExample[];
|
|
107
|
+
guidelines?: string[];
|
|
108
|
+
typeLabels?: {
|
|
109
|
+
readonly classes?: string | undefined;
|
|
110
|
+
} | undefined;
|
|
111
|
+
typeDefs?: {
|
|
112
|
+
readonly classes?: string | undefined;
|
|
113
|
+
} | undefined;
|
|
114
|
+
returnType?: string;
|
|
115
|
+
returnDescription?: string;
|
|
116
|
+
};
|
|
117
|
+
caseConvertTool: {
|
|
118
|
+
name: string;
|
|
119
|
+
description: string;
|
|
120
|
+
inputSchema: {
|
|
121
|
+
readonly input: zod.ZodString;
|
|
122
|
+
readonly to: zod.ZodEnum<{
|
|
123
|
+
upper: "upper";
|
|
124
|
+
lower: "lower";
|
|
125
|
+
capitalize: "capitalize";
|
|
126
|
+
camel: "camel";
|
|
127
|
+
snake: "snake";
|
|
128
|
+
kebab: "kebab";
|
|
129
|
+
}>;
|
|
130
|
+
};
|
|
131
|
+
handler: (input: {
|
|
132
|
+
input: string;
|
|
133
|
+
to: "upper" | "lower" | "capitalize" | "camel" | "snake" | "kebab";
|
|
134
|
+
}) => Promise<ToolResult>;
|
|
135
|
+
examples?: ToolExample[];
|
|
136
|
+
guidelines?: string[];
|
|
137
|
+
typeLabels?: {
|
|
138
|
+
readonly input?: string | undefined;
|
|
139
|
+
readonly to?: string | undefined;
|
|
140
|
+
} | undefined;
|
|
141
|
+
typeDefs?: {
|
|
142
|
+
readonly input?: string | undefined;
|
|
143
|
+
readonly to?: string | undefined;
|
|
144
|
+
} | undefined;
|
|
145
|
+
returnType?: string;
|
|
146
|
+
returnDescription?: string;
|
|
147
|
+
};
|
|
148
|
+
truncateTool: {
|
|
149
|
+
name: string;
|
|
150
|
+
description: string;
|
|
151
|
+
inputSchema: {
|
|
152
|
+
readonly input: zod.ZodString;
|
|
153
|
+
readonly maxLength: zod.ZodNumber;
|
|
154
|
+
readonly suffix: zod.ZodDefault<zod.ZodString>;
|
|
155
|
+
};
|
|
156
|
+
handler: (input: {
|
|
157
|
+
input: string;
|
|
158
|
+
maxLength: number;
|
|
159
|
+
suffix: string;
|
|
160
|
+
}) => Promise<ToolResult>;
|
|
161
|
+
examples?: ToolExample[];
|
|
162
|
+
guidelines?: string[];
|
|
163
|
+
typeLabels?: {
|
|
164
|
+
readonly input?: string | undefined;
|
|
165
|
+
readonly maxLength?: string | undefined;
|
|
166
|
+
readonly suffix?: string | undefined;
|
|
167
|
+
} | undefined;
|
|
168
|
+
typeDefs?: {
|
|
169
|
+
readonly input?: string | undefined;
|
|
170
|
+
readonly maxLength?: string | undefined;
|
|
171
|
+
readonly suffix?: string | undefined;
|
|
172
|
+
} | undefined;
|
|
173
|
+
returnType?: string;
|
|
174
|
+
returnDescription?: string;
|
|
175
|
+
};
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
export { cn, generateReadmeSkills, generateSkillMarkdown, tools };
|
package/dist/server.cjs
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";function r(e){return{content:[{type:"text",text:e}]}}var Z=require("@modelcontextprotocol/sdk/server/mcp.js"),w=require("@modelcontextprotocol/sdk/server/stdio.js");function O(e,n){let t=new Z.McpServer(e);for(let o of n)t.registerTool(o.name,{description:o.description,inputSchema:o.inputSchema},o.handler);return t}async function A(e){let n=new w.StdioServerTransport;await e.connect(n)}var R=require("zod");var N=require("zod");var i=require("zod");function k(...e){return e.filter(Boolean).join(" ")}var p={cnTool:{name:"cn",description:"Merges class names, filtering out falsy values",inputSchema:{classes:i.z.array(i.z.string()).describe("List of class names to merge")},typeLabels:{classes:"string[]"},returnType:"string",returnDescription:"Merged class name string with falsy values filtered out",handler:async({classes:e})=>r(k(...e)),examples:[{args:[`'["btn","active","large"]'`],result:"btn active large"}]},caseConvertTool:{name:"case_convert",description:"Converts text to the specified case format",inputSchema:{input:i.z.string().describe("Text to convert"),to:i.z.enum(["upper","lower","capitalize","camel","snake","kebab"]).describe("Target case format")},typeLabels:{input:"string",to:'"upper" | "lower" | "capitalize" | "camel" | "snake" | "kebab"'},returnType:"string",returnDescription:"Converted text in the target case format",handler:async({input:e,to:n})=>r(E(e,n)),examples:[{args:['"hello world"',"camel"],result:"helloWorld"},{args:['"helloWorld"',"snake"],result:"hello_world"},{args:['"hello world"',"kebab"],result:"hello-world"}]},truncateTool:{name:"truncate",description:"Truncates text to a maximum length and appends a suffix",inputSchema:{input:i.z.string().describe("Text to truncate"),maxLength:i.z.number().int().positive().describe("Maximum character length"),suffix:i.z.string().default("...").describe("Suffix to append when truncated")},typeLabels:{input:"string",maxLength:"number",suffix:"string"},returnType:"string",returnDescription:"Truncated text with the configured suffix appended if truncated",handler:async({input:e,maxLength:n,suffix:t})=>{let o=e.length<=n?e:e.slice(0,n-t.length)+t;return r(o)},examples:[{args:['"hello world long text"',"10"],result:"hello w..."},{args:['"hello world"',"8",'"\u2026"'],result:"hello w\u2026"}]}},m=p.cnTool,g=p.caseConvertTool,y=p.truncateTool;function E(e,n){switch(n){case"upper":return e.toUpperCase();case"lower":return e.toLowerCase();case"capitalize":return e.charAt(0).toUpperCase()+e.slice(1).toLowerCase();case"camel":return e.replace(/[-_\s]+(.)/g,(t,o)=>o.toUpperCase()).replace(/^(.)/,t=>t.toLowerCase());case"snake":return e.replace(/([A-Z])/g,"_$1").replace(/[-\s]+/g,"_").toLowerCase().replace(/^_/,"");case"kebab":return e.replace(/([A-Z])/g,"-$1").replace(/[_\s]+/g,"-").toLowerCase().replace(/^-/,"")}}var l=require("zod");function J(e){let n=typeof e=="string"?JSON.parse(e):e,t={};function o(s,u){if(s===null||typeof s!="object"||Array.isArray(s)){t[u]=s;return}for(let[v,z]of Object.entries(s)){let D=u?`${u}.${v}`:v;o(z,D)}}return o(n,""),t}var T={objectFlattenTool:{name:"object_flatten",description:"Flattens a nested JSON object of any depth into dot-notation key-value pairs. Accepts a JSON string and recursively flattens all levels. Arrays and primitives at any level are treated as leaf values.",inputSchema:{json:l.z.union([l.z.string(),l.z.record(l.z.string(),l.z.any())]).describe("JSON string or parsed object to flatten (unlimited depth)")},handler:async({json:e})=>{try{let t=J(e);return r(JSON.stringify(t,null,2))}catch(n){return n instanceof SyntaxError?r("Error: invalid JSON string \u2014 unable to parse input"):r(`Error: failed to flatten object \u2014 ${n.message}`)}},examples:[{args:[`'{"user":{"name":"Alice","address":{"city":"Seoul","zip":"12345"}},"active":true}'`],result:JSON.stringify({"user.name":"Alice","user.address.city":"Seoul","user.address.zip":"12345",active:!0},null,2)},{args:[`'{"a":{"b":{"c":{"d":{"e":"deep"}}}}}'`],result:JSON.stringify({"a.b.c.d.e":"deep"},null,2)}],returnType:"JsonObject",returnDescription:'Flattened object with dot-notation keys \u2014 e.g. { "a.b.c": value }',guidelines:["Arrays and primitives at any level are always treated as leaf values \u2014 they are never traversed.","The result is always a flat JSON object with dot-notation keys.","There is no depth limit \u2014 objects of any nesting level are fully flattened.","Input is accepted as a JSON string (MCP/CLI) and parsed internally."]}},b=T.objectFlattenTool;var c=require("zod");function C(e){let n=typeof e=="string"?JSON.parse(e):e,{first:t,last:o}=n.name,s=n.location.city;return`\uC774\uB984\uC740 ${t} ${o} \uC774\uACE0 \uD604\uC7AC ${s} \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4.`}var h={getUserTool:{name:"getUser",description:"RandomUser API \uD615\uC2DD\uC758 \uC0AC\uC6A9\uC790 \uAC1D\uCCB4\uB97C \uBC1B\uC544 \uC774\uB984\uACFC \uAC70\uC8FC \uB3C4\uC2DC\uB85C \uAD6C\uC131\uB41C \uD55C\uAE00 \uBB38\uC7A5\uC744 \uBC18\uD658\uD569\uB2C8\uB2E4. JSON \uBB38\uC790\uC5F4 \uB610\uB294 \uD30C\uC2F1\uB41C \uAC1D\uCCB4\uB97C \uC785\uB825\uBC1B\uC2B5\uB2C8\uB2E4.",inputSchema:{user:c.z.union([c.z.string(),c.z.record(c.z.string(),c.z.any())]).describe("RandomUser \uD615\uC2DD\uC758 JSON \uBB38\uC790\uC5F4 \uB610\uB294 \uAC1D\uCCB4 \u2014 name.first / name.last / location.city \uD544\uC218")},typeLabels:{user:"RandomUser"},typeDefs:{user:["interface RandomUser {",' gender: "male" | "female";'," name: {"," title: string;"," first: string;"," last: string;"," };"," location: {"," street: {"," number: number;"," name: string;"," };"," city: string;"," state: string;"," country: string;"," postcode: string | number;"," coordinates: {"," latitude: string;"," longitude: string;"," };"," timezone: {"," offset: string;"," description: string;"," };"," };"," email: string;"," login: {"," uuid: string;"," username: string;"," };"," dob: {"," date: string;"," age: number;"," };"," phone: string;"," cell: string;"," picture: {"," large: string;"," medium: string;"," thumbnail: string;"," };"," nat: string;","}"].join(`
|
|
3
|
+
`)},returnType:"string",returnDescription:'"\uC774\uB984\uC740 {first} {last} \uC774\uACE0 \uD604\uC7AC {city} \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4." \uD615\uC2DD\uC758 \uD55C\uAE00 \uBB38\uC7A5',handler:async({user:e})=>{try{let t=C(e);return r(t)}catch(n){return n instanceof SyntaxError?r("Error: invalid JSON string \u2014 unable to parse input"):r(`Error: failed to process user data \u2014 ${n.message}
|
|
4
|
+
|
|
5
|
+
Input must include \`name.first\`, \`name.last\`, and \`location.city\`.`)}},examples:[{args:[`'{"name":{"title":"Mr","first":"Alice","last":"Kim"},"location":{"city":"Seoul"},"gender":"female","email":"alice@example.com","nat":"KR"}'`],result:"\uC774\uB984\uC740 Alice Kim \uC774\uACE0 \uD604\uC7AC Seoul \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4."}],guidelines:["\uC785\uB825\uC740 RandomUser API \uC2A4\uD399\uC744 \uB530\uB985\uB2C8\uB2E4. \uCD5C\uC18C\uD55C name.first, name.last, location.city \uD544\uB4DC\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.","JSON \uBB38\uC790\uC5F4(string)\uACFC \uD30C\uC2F1\uB41C \uAC1D\uCCB4 \uBAA8\uB450 \uD5C8\uC6A9\uB429\uB2C8\uB2E4 (CLI / MCP \uBAA8\uB450 \uB3D9\uC791).","\uACB0\uACFC\uB294 \uD56D\uC0C1 '\uC774\uB984\uC740 {first} {last} \uC774\uACE0 \uD604\uC7AC {city} \uC5D0 \uC0B4\uACE0 \uC788\uC2B5\uB2C8\uB2E4.' \uD615\uC2DD\uC758 \uD55C\uAE00 \uBB38\uC7A5\uC785\uB2C8\uB2E4."]}},x=h.getUserTool;var S=require("zod"),a=["API_KEY"];function U(e){let n=e.filter(o=>!a.includes(o));if(n.length>0)throw new Error(`Invalid env key(s): ${n.join(", ")}. Allowed keys: ${a.join(", ")}`);let t={};for(let o of e){let s=process.env[o];s!==void 0&&(t[o]=s)}return t}var $={envGetTool:{name:"env_get",description:`MCP \uD074\uB77C\uC774\uC5B8\uD2B8 config\uC758 env \uD544\uB4DC\uB97C \uD1B5\uD574 \uC8FC\uC785\uB41C \uD658\uACBD \uBCC0\uC218 \uAC12\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4. \uC870\uD68C \uAC00\uB2A5\uD55C \uD0A4\uB294 \uD328\uD0A4\uC9C0\uC5D0\uC11C \uC81C\uACF5\uD558\uB294 \uD658\uACBD \uBCC0\uC218\uB85C \uD55C\uC815\uB429\uB2C8\uB2E4. \uD604\uC7AC \uC9C0\uC6D0: ${a.join(", ")}.`,inputSchema:{keys:S.z.array(S.z.string()).nonempty().describe(`\uC870\uD68C\uD560 \uD658\uACBD \uBCC0\uC218 \uC774\uB984 \uBAA9\uB85D (\uC720\uD6A8 \uD0A4: ${a.join(", ")})`)},typeLabels:{keys:"string[]"},typeDefs:{keys:["// @julong/mono-rele2-utils \uD658\uACBD \uBCC0\uC218 \uD0A4 \uBAA9\uB85D",...a.map(e=>`// "${e}"`),"","// MCP client config \uC608\uC2DC:","// {",'// "mcpServers": {','// "@julong/mono-rele2-utils": {','// "command": "npx",','// "args": ["-y", "@julong/mono-rele2-utils"],','// "env": {',...a.map(e=>`// "${e}": "<value>"`),"// }","// }","// }","// }"].join(`
|
|
6
|
+
`)},returnType:"Record<string, string>",returnDescription:"key: \uD658\uACBD \uBCC0\uC218 \uC774\uB984, value: \uD574\uB2F9 \uAC12 (\uC124\uC815\uB418\uC9C0 \uC54A\uC740 \uBCC0\uC218\uB294 \uACB0\uACFC\uC5D0\uC11C \uC81C\uC678)",handler:async({keys:e})=>{try{let n=U(e);return Object.keys(n).length===0?r("(no matching environment variables found)"):r(JSON.stringify(n,null,2))}catch(n){return r(`Error: ${n.message}`)}},examples:[{args:[`'["API_KEY"]'`],result:JSON.stringify({API_KEY:"<value>"},null,2)}],guidelines:[`\uC870\uD68C \uAC00\uB2A5\uD55C \uD0A4: ${a.join(", ")}`,"MCP client config.json\uC758 env \uD544\uB4DC\uC5D0 \uC704 \uD0A4\uB4E4\uB9CC \uC124\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.","\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD0A4\uB97C \uC694\uCCAD\uD558\uBA74 \uC5D0\uB7EC \uBA54\uC2DC\uC9C0\uC5D0 \uD5C8\uC6A9\uB41C \uD0A4 \uBAA9\uB85D\uC774 \uD45C\uC2DC\uB429\uB2C8\uB2E4.","\uC124\uC815\uB418\uC9C0 \uC54A\uC740 \uD658\uACBD \uBCC0\uC218\uB294 \uACB0\uACFC \uAC1D\uCCB4\uC5D0\uC11C \uC81C\uC678\uB429\uB2C8\uB2E4."]}},j=$.envGetTool;var fe={...p,...T,...h,...$};var L=O({name:"mono-rele2-utils",version:"1.0.0"},[m,g,y,b,x,j]);A(L).catch(e=>{console.error("[utils] server error:",e),process.exit(1)});
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@julong/mono-rele2-utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.31.0",
|
|
4
4
|
"description": "Use this skill to invoke text utility functions via the mono-rele2-utils CLI. Handles class name merging, case conversion, and text truncation.",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
9
10
|
"import": "./dist/index.js",
|
|
10
|
-
"
|
|
11
|
+
"require": "./dist/index.cjs"
|
|
11
12
|
}
|
|
12
13
|
},
|
|
13
14
|
"bin": {
|
|
@@ -22,8 +23,12 @@
|
|
|
22
23
|
},
|
|
23
24
|
"scripts": {
|
|
24
25
|
"build": "tsup",
|
|
26
|
+
"dev": "tsup --watch",
|
|
25
27
|
"typecheck": "tsc --noEmit",
|
|
26
28
|
"clean": "rimraf dist",
|
|
29
|
+
"lint": "rslint --config ../../rslint.config.ts .",
|
|
30
|
+
"format": "prettier --write src/ --write '*.{ts,json,js}'",
|
|
31
|
+
"format:check": "prettier --check src/ --check '*.{ts,json,js}'",
|
|
27
32
|
"readme": "bun ../common/build/update-readme.mjs"
|
|
28
33
|
},
|
|
29
34
|
"dependencies": {
|