@airmcp-dev/cli 0.1.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/LICENSE +17 -0
- package/dist/commands/add.d.ts +3 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +192 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/check.d.ts +3 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +218 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/connect.d.ts +3 -0
- package/dist/commands/connect.d.ts.map +1 -0
- package/dist/commands/connect.js +135 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/create.d.ts +3 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +150 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/dev.d.ts +3 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +184 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/disconnect.d.ts +3 -0
- package/dist/commands/disconnect.d.ts.map +1 -0
- package/dist/commands/disconnect.js +69 -0
- package/dist/commands/disconnect.js.map +1 -0
- package/dist/commands/index.d.ts +13 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +16 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/inspect.d.ts +3 -0
- package/dist/commands/inspect.d.ts.map +1 -0
- package/dist/commands/inspect.js +159 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/license.d.ts +3 -0
- package/dist/commands/license.d.ts.map +1 -0
- package/dist/commands/license.js +113 -0
- package/dist/commands/license.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +101 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/start.d.ts +3 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +130 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +83 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +3 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +56 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/templates/agent/.ai/context.md +36 -0
- package/dist/templates/agent/.vscode/air.code-snippets +178 -0
- package/dist/templates/agent/package.json +17 -0
- package/dist/templates/agent/src/index.ts +98 -0
- package/dist/templates/agent/tsconfig.json +14 -0
- package/dist/templates/agent-ko/.ai/context.md +36 -0
- package/dist/templates/agent-ko/.vscode/air.code-snippets +178 -0
- package/dist/templates/agent-ko/package.json +17 -0
- package/dist/templates/agent-ko/src/index.ts +92 -0
- package/dist/templates/agent-ko/tsconfig.json +14 -0
- package/dist/templates/api/.ai/context.md +36 -0
- package/dist/templates/api/.vscode/air.code-snippets +178 -0
- package/dist/templates/api/package.json +17 -0
- package/dist/templates/api/src/index.ts +76 -0
- package/dist/templates/api/tsconfig.json +14 -0
- package/dist/templates/api-ko/.ai/context.md +36 -0
- package/dist/templates/api-ko/.vscode/air.code-snippets +178 -0
- package/dist/templates/api-ko/package.json +17 -0
- package/dist/templates/api-ko/src/index.ts +70 -0
- package/dist/templates/api-ko/tsconfig.json +14 -0
- package/dist/templates/basic/.ai/context.md +36 -0
- package/dist/templates/basic/.vscode/air.code-snippets +178 -0
- package/dist/templates/basic/package.json +17 -0
- package/dist/templates/basic/src/index.ts +39 -0
- package/dist/templates/basic/tsconfig.json +15 -0
- package/dist/templates/basic-ko/.ai/context.md +36 -0
- package/dist/templates/basic-ko/.vscode/air.code-snippets +178 -0
- package/dist/templates/basic-ko/package.json +17 -0
- package/dist/templates/basic-ko/src/index.ts +39 -0
- package/dist/templates/basic-ko/tsconfig.json +14 -0
- package/dist/templates/crud/.ai/context.md +36 -0
- package/dist/templates/crud/.vscode/air.code-snippets +178 -0
- package/dist/templates/crud/package.json +17 -0
- package/dist/templates/crud/src/index.ts +82 -0
- package/dist/templates/crud/tsconfig.json +14 -0
- package/dist/templates/crud-ko/.ai/context.md +36 -0
- package/dist/templates/crud-ko/.vscode/air.code-snippets +178 -0
- package/dist/templates/crud-ko/package.json +17 -0
- package/dist/templates/crud-ko/src/index.ts +81 -0
- package/dist/templates/crud-ko/tsconfig.json +14 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/json-editor.d.ts +45 -0
- package/dist/utils/json-editor.d.ts.map +1 -0
- package/dist/utils/json-editor.js +122 -0
- package/dist/utils/json-editor.js.map +1 -0
- package/dist/utils/path-resolver.d.ts +30 -0
- package/dist/utils/path-resolver.d.ts.map +1 -0
- package/dist/utils/path-resolver.js +121 -0
- package/dist/utils/path-resolver.js.map +1 -0
- package/dist/utils/printer.d.ts +26 -0
- package/dist/utils/printer.d.ts.map +1 -0
- package/dist/utils/printer.js +65 -0
- package/dist/utils/printer.js.map +1 -0
- package/dist/utils/process-manager.d.ts +36 -0
- package/dist/utils/process-manager.d.ts.map +1 -0
- package/dist/utils/process-manager.js +143 -0
- package/dist/utils/process-manager.js.map +1 -0
- package/dist/utils/test-console.d.ts +8 -0
- package/dist/utils/test-console.d.ts.map +1 -0
- package/dist/utils/test-console.js +198 -0
- package/dist/utils/test-console.js.map +1 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
you may not use this file except in compliance with the License.
|
|
7
|
+
You may obtain a copy of the License at
|
|
8
|
+
|
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
|
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
See the License for the specific language governing permissions and
|
|
15
|
+
limitations under the License.
|
|
16
|
+
|
|
17
|
+
Copyright 2026 CodePedia Labs (labs@codepedia.kr)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuKpC,eAAO,MAAM,UAAU,SAyCnB,CAAC"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
// Copyright 2026 CodePedia Labs. Licensed under Apache-2.0.
|
|
2
|
+
// air CLI — commands/add.ts
|
|
3
|
+
//
|
|
4
|
+
// air add <type> <name>
|
|
5
|
+
//
|
|
6
|
+
// 현재 프로젝트의 src/index.ts에 도구/리소스/프롬프트 scaffold를 추가한다.
|
|
7
|
+
// VS Code 스니펫과 달리 에디터에 종속되지 않는다.
|
|
8
|
+
//
|
|
9
|
+
// @example
|
|
10
|
+
// air add tool search
|
|
11
|
+
// air add tool search --params "query:string,limit:number"
|
|
12
|
+
// air add resource config
|
|
13
|
+
// air add prompt summarize
|
|
14
|
+
import { Command } from 'commander';
|
|
15
|
+
import { resolve } from 'node:path';
|
|
16
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
17
|
+
import { printer } from '../utils/printer.js';
|
|
18
|
+
/** 도구 scaffold 생성 */
|
|
19
|
+
function toolScaffold(name, paramsStr) {
|
|
20
|
+
let paramsBlock = ` // TODO: 파라미터를 정의하세요\n input: { type: 'string', description: '입력값' },`;
|
|
21
|
+
let destructure = 'input';
|
|
22
|
+
if (paramsStr) {
|
|
23
|
+
const pairs = paramsStr.split(',').map((p) => p.trim());
|
|
24
|
+
const lines = [];
|
|
25
|
+
const names = [];
|
|
26
|
+
for (const pair of pairs) {
|
|
27
|
+
const [pName, pType = 'string'] = pair.split(':').map((s) => s.trim());
|
|
28
|
+
lines.push(` ${pName}: { type: '${pType}', description: '${pName}' },`);
|
|
29
|
+
names.push(pName);
|
|
30
|
+
}
|
|
31
|
+
paramsBlock = lines.join('\n');
|
|
32
|
+
destructure = names.join(', ');
|
|
33
|
+
}
|
|
34
|
+
return `
|
|
35
|
+
defineTool('${name}', {
|
|
36
|
+
description: '${name} 도구',
|
|
37
|
+
params: {
|
|
38
|
+
${paramsBlock}
|
|
39
|
+
},
|
|
40
|
+
handler: async ({ ${destructure} }) => {
|
|
41
|
+
// TODO: 구현하세요
|
|
42
|
+
return \`${name} 결과: \${${destructure.split(',')[0].trim()}}\`;
|
|
43
|
+
},
|
|
44
|
+
}),`;
|
|
45
|
+
}
|
|
46
|
+
/** 리소스 scaffold 생성 */
|
|
47
|
+
function resourceScaffold(name) {
|
|
48
|
+
return `
|
|
49
|
+
defineResource({
|
|
50
|
+
name: '${name}',
|
|
51
|
+
uri: 'file:///${name}',
|
|
52
|
+
description: '${name} 리소스',
|
|
53
|
+
handler: async (uri, ctx) => {
|
|
54
|
+
// TODO: 구현하세요
|
|
55
|
+
return '${name} 데이터';
|
|
56
|
+
},
|
|
57
|
+
}),`;
|
|
58
|
+
}
|
|
59
|
+
/** 프롬프트 scaffold 생성 */
|
|
60
|
+
function promptScaffold(name) {
|
|
61
|
+
return `
|
|
62
|
+
definePrompt({
|
|
63
|
+
name: '${name}',
|
|
64
|
+
description: '${name} 프롬프트',
|
|
65
|
+
args: [
|
|
66
|
+
{ name: 'input', description: '입력 텍스트' },
|
|
67
|
+
],
|
|
68
|
+
handler: async ({ input }) => [
|
|
69
|
+
{ role: 'user', content: \`\${input}\` },
|
|
70
|
+
],
|
|
71
|
+
}),`;
|
|
72
|
+
}
|
|
73
|
+
/** src/index.ts에서 tools/resources/prompts 배열 끝에 삽입 */
|
|
74
|
+
async function insertIntoSource(cwd, type, scaffold) {
|
|
75
|
+
const srcPath = resolve(cwd, 'src/index.ts');
|
|
76
|
+
let src;
|
|
77
|
+
try {
|
|
78
|
+
src = await readFile(srcPath, 'utf-8');
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
printer.error('src/index.ts not found. Run this command in an air project directory.');
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
// 삽입 위치: tools: [...], resources: [...], prompts: [...]
|
|
85
|
+
const sectionMap = {
|
|
86
|
+
tool: 'tools',
|
|
87
|
+
resource: 'resources',
|
|
88
|
+
prompt: 'prompts',
|
|
89
|
+
};
|
|
90
|
+
const section = sectionMap[type];
|
|
91
|
+
// import 추가 (필요한 경우)
|
|
92
|
+
const importMap = {
|
|
93
|
+
tool: 'defineTool',
|
|
94
|
+
resource: 'defineResource',
|
|
95
|
+
prompt: 'definePrompt',
|
|
96
|
+
};
|
|
97
|
+
const importName = importMap[type];
|
|
98
|
+
if (!src.includes(importName)) {
|
|
99
|
+
// 기존 import에 추가
|
|
100
|
+
src = src.replace(/import\s*{([^}]+)}\s*from\s*'@air\/core'/, (match, imports) => {
|
|
101
|
+
const existing = imports.trim();
|
|
102
|
+
return `import { ${existing}, ${importName} } from '@airmcp-dev/core'`;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
// 섹션이 있으면 마지막 요소 뒤에 삽입
|
|
106
|
+
const sectionRegex = new RegExp(`${section}:\\s*\\[`);
|
|
107
|
+
if (sectionRegex.test(src)) {
|
|
108
|
+
// 마지막 ], 앞에 삽입
|
|
109
|
+
// 해당 배열의 마지막 닫는 ] 를 찾아서 그 앞에 삽입
|
|
110
|
+
const idx = src.indexOf(`${section}: [`);
|
|
111
|
+
if (idx === -1) {
|
|
112
|
+
printer.error(`Could not find "${section}: [" in src/index.ts.`);
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
// 배열 끝 찾기 — 간단하게 마지막 ], 앞에 삽입
|
|
116
|
+
let bracketCount = 0;
|
|
117
|
+
let insertPos = -1;
|
|
118
|
+
for (let i = idx + section.length + 3; i < src.length; i++) {
|
|
119
|
+
if (src[i] === '[')
|
|
120
|
+
bracketCount++;
|
|
121
|
+
if (src[i] === ']') {
|
|
122
|
+
if (bracketCount === 0) {
|
|
123
|
+
insertPos = i;
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
bracketCount--;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (insertPos === -1) {
|
|
130
|
+
printer.error(`Could not find closing bracket for "${section}" array.`);
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
src = src.slice(0, insertPos) + scaffold + '\n ' + src.slice(insertPos);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
// 섹션이 없으면 tools 뒤에 새 섹션 추가
|
|
137
|
+
const toolsEnd = src.indexOf('tools: [');
|
|
138
|
+
if (toolsEnd === -1) {
|
|
139
|
+
printer.error('Could not find "tools: [" in src/index.ts. Is this an air project?');
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
// defineServer 닫는 }) 앞에 새 섹션 추가
|
|
143
|
+
const closingIdx = src.lastIndexOf('});');
|
|
144
|
+
if (closingIdx === -1) {
|
|
145
|
+
printer.error('Could not find defineServer closing bracket.');
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
const newSection = `\n ${section}: [${scaffold}\n ],\n`;
|
|
149
|
+
src = src.slice(0, closingIdx) + newSection + src.slice(closingIdx);
|
|
150
|
+
}
|
|
151
|
+
await writeFile(srcPath, src, 'utf-8');
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
export const addCommand = new Command('add')
|
|
155
|
+
.description('Add a tool, resource, or prompt scaffold to the project')
|
|
156
|
+
.argument('<type>', 'What to add: tool | resource | prompt')
|
|
157
|
+
.argument('<name>', 'Name of the tool/resource/prompt')
|
|
158
|
+
.option('--params <params>', 'Parameters for tool (e.g. "query:string,limit:number")')
|
|
159
|
+
.action(async (type, name, opts) => {
|
|
160
|
+
const validTypes = ['tool', 'resource', 'prompt'];
|
|
161
|
+
if (!validTypes.includes(type)) {
|
|
162
|
+
printer.error(`Invalid type "${type}". Use: ${validTypes.join(', ')}`);
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
const cwd = process.cwd();
|
|
166
|
+
let scaffold;
|
|
167
|
+
switch (type) {
|
|
168
|
+
case 'tool':
|
|
169
|
+
scaffold = toolScaffold(name, opts.params);
|
|
170
|
+
break;
|
|
171
|
+
case 'resource':
|
|
172
|
+
scaffold = resourceScaffold(name);
|
|
173
|
+
break;
|
|
174
|
+
case 'prompt':
|
|
175
|
+
scaffold = promptScaffold(name);
|
|
176
|
+
break;
|
|
177
|
+
default:
|
|
178
|
+
process.exit(1);
|
|
179
|
+
}
|
|
180
|
+
printer.blank();
|
|
181
|
+
printer.step(1, 2, `Generating ${type} scaffold: "${name}"...`);
|
|
182
|
+
const success = await insertIntoSource(cwd, type, scaffold);
|
|
183
|
+
if (!success)
|
|
184
|
+
process.exit(1);
|
|
185
|
+
printer.step(2, 2, 'Done!');
|
|
186
|
+
printer.blank();
|
|
187
|
+
printer.success(`Added ${type} "${name}" to src/index.ts`);
|
|
188
|
+
printer.blank();
|
|
189
|
+
printer.info('Open src/index.ts and fill in the handler logic.');
|
|
190
|
+
printer.blank();
|
|
191
|
+
});
|
|
192
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyCpC,eAAO,MAAM,YAAY,SAmJrB,CAAC"}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
// Copyright 2026 CodePedia Labs. Licensed under Apache-2.0.
|
|
2
|
+
// air CLI — commands/check.ts
|
|
3
|
+
//
|
|
4
|
+
// air check
|
|
5
|
+
//
|
|
6
|
+
// 프로젝트 상태를 종합 진단한다.
|
|
7
|
+
// - 환경: Node.js, TypeScript, pnpm 버전
|
|
8
|
+
// - 의존성: @airmcp-dev/* 패키지 설치 상태
|
|
9
|
+
// - 빌드: tsc 타입체크 통과 여부
|
|
10
|
+
// - 테스트: vitest 실행 결과
|
|
11
|
+
// - 설정: shield, meter 활성화 상태
|
|
12
|
+
// - 도구: 등록된 도구 수
|
|
13
|
+
//
|
|
14
|
+
// @example
|
|
15
|
+
// air check
|
|
16
|
+
// air check --fix (향후: 자동 수정)
|
|
17
|
+
import { Command } from 'commander';
|
|
18
|
+
import { resolve } from 'node:path';
|
|
19
|
+
import { readFile, access } from 'node:fs/promises';
|
|
20
|
+
import { execSync } from 'node:child_process';
|
|
21
|
+
import { printer } from '../utils/printer.js';
|
|
22
|
+
/** 명령어 실행 헬퍼 (실패 시 null) */
|
|
23
|
+
function run(cmd, cwd) {
|
|
24
|
+
try {
|
|
25
|
+
return execSync(cmd, { cwd, encoding: 'utf-8', timeout: 30_000, stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** package.json 읽기 */
|
|
32
|
+
async function readPkg(cwd) {
|
|
33
|
+
try {
|
|
34
|
+
const raw = await readFile(resolve(cwd, 'package.json'), 'utf-8');
|
|
35
|
+
return JSON.parse(raw);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** 파일 존재 여부 */
|
|
42
|
+
async function exists(path) {
|
|
43
|
+
try {
|
|
44
|
+
await access(path);
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export const checkCommand = new Command('check')
|
|
52
|
+
.description('Diagnose project health — environment, build, tests, config')
|
|
53
|
+
.action(async () => {
|
|
54
|
+
const cwd = process.cwd();
|
|
55
|
+
const results = [];
|
|
56
|
+
printer.blank();
|
|
57
|
+
printer.heading('air check');
|
|
58
|
+
// ── 1. 환경 ──
|
|
59
|
+
const nodeVersion = run('node --version', cwd);
|
|
60
|
+
if (nodeVersion) {
|
|
61
|
+
const major = parseInt(nodeVersion.replace('v', ''));
|
|
62
|
+
results.push({
|
|
63
|
+
name: 'Node.js',
|
|
64
|
+
status: major >= 18 ? 'pass' : 'fail',
|
|
65
|
+
message: `${nodeVersion}${major < 18 ? ' (requires >= 18)' : ''}`,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
results.push({ name: 'Node.js', status: 'fail', message: 'not found' });
|
|
70
|
+
}
|
|
71
|
+
const tsVersion = run('npx tsc --version', cwd);
|
|
72
|
+
results.push({
|
|
73
|
+
name: 'TypeScript',
|
|
74
|
+
status: tsVersion ? 'pass' : 'warn',
|
|
75
|
+
message: tsVersion || 'not installed',
|
|
76
|
+
});
|
|
77
|
+
// ── 2. package.json ──
|
|
78
|
+
const pkg = await readPkg(cwd);
|
|
79
|
+
if (!pkg) {
|
|
80
|
+
results.push({ name: 'package.json', status: 'fail', message: 'not found' });
|
|
81
|
+
printResults(results);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
results.push({ name: 'package.json', status: 'pass', message: `${pkg.name}@${pkg.version || '0.0.0'}` });
|
|
85
|
+
// ── 3. 의존성 체크 ──
|
|
86
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
87
|
+
const airPackages = ['@airmcp-dev/core', '@airmcp-dev/shield', '@airmcp-dev/meter', '@airmcp-dev/logger', '@airmcp-dev/gateway', '@airmcp-dev/hive'];
|
|
88
|
+
for (const airPkg of airPackages) {
|
|
89
|
+
if (deps[airPkg]) {
|
|
90
|
+
results.push({ name: airPkg, status: 'pass', message: deps[airPkg] });
|
|
91
|
+
}
|
|
92
|
+
// 없는 패키지는 건너뜀 (필수가 아님)
|
|
93
|
+
}
|
|
94
|
+
if (!deps['@airmcp-dev/core']) {
|
|
95
|
+
results.push({ name: '@airmcp-dev/core', status: 'fail', message: 'not in dependencies — required' });
|
|
96
|
+
}
|
|
97
|
+
// ── 4. 소스 파일 체크 ──
|
|
98
|
+
const hasSrc = await exists(resolve(cwd, 'src/index.ts')) || await exists(resolve(cwd, 'src/index.js'));
|
|
99
|
+
results.push({
|
|
100
|
+
name: 'Source',
|
|
101
|
+
status: hasSrc ? 'pass' : 'fail',
|
|
102
|
+
message: hasSrc ? 'src/index.ts found' : 'src/index.ts not found',
|
|
103
|
+
});
|
|
104
|
+
// ── 5. 빌드 (타입체크) ──
|
|
105
|
+
const hasTsConfig = await exists(resolve(cwd, 'tsconfig.json'));
|
|
106
|
+
if (hasTsConfig && hasSrc) {
|
|
107
|
+
const tscResult = run('npx tsc --noEmit 2>&1', cwd);
|
|
108
|
+
if (tscResult === null || tscResult === '') {
|
|
109
|
+
results.push({ name: 'Type Check', status: 'pass', message: 'no errors' });
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
const errorCount = (tscResult.match(/error TS/g) || []).length;
|
|
113
|
+
results.push({
|
|
114
|
+
name: 'Type Check',
|
|
115
|
+
status: 'fail',
|
|
116
|
+
message: `${errorCount} error(s)`,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
results.push({ name: 'Type Check', status: 'skip', message: 'no tsconfig.json' });
|
|
122
|
+
}
|
|
123
|
+
// ── 6. 빌드 결과물 ──
|
|
124
|
+
const hasDist = await exists(resolve(cwd, 'dist/index.js')) || await exists(resolve(cwd, 'build/index.js'));
|
|
125
|
+
results.push({
|
|
126
|
+
name: 'Build',
|
|
127
|
+
status: hasDist ? 'pass' : 'warn',
|
|
128
|
+
message: hasDist ? 'dist/ found' : 'not built yet (run: npm run build)',
|
|
129
|
+
});
|
|
130
|
+
// ── 7. 테스트 ──
|
|
131
|
+
const hasTestDir = await exists(resolve(cwd, '__tests__')) || await exists(resolve(cwd, 'test')) || await exists(resolve(cwd, 'tests'));
|
|
132
|
+
const hasVitest = deps['vitest'] || await exists(resolve(cwd, 'vitest.config.ts'));
|
|
133
|
+
if (hasTestDir || hasVitest) {
|
|
134
|
+
const testResult = run('npx vitest run 2>&1', cwd);
|
|
135
|
+
if (testResult && testResult.includes('passed')) {
|
|
136
|
+
const match = testResult.match(/Tests\s+(\d+)\s+passed/);
|
|
137
|
+
const count = match ? match[1] : '?';
|
|
138
|
+
results.push({ name: 'Tests', status: 'pass', message: `${count} passed` });
|
|
139
|
+
}
|
|
140
|
+
else if (testResult && testResult.includes('failed')) {
|
|
141
|
+
const match = testResult.match(/(\d+)\s+failed/);
|
|
142
|
+
const failCount = match ? match[1] : '?';
|
|
143
|
+
results.push({ name: 'Tests', status: 'fail', message: `${failCount} failed` });
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
results.push({ name: 'Tests', status: 'skip', message: 'no tests found' });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
results.push({ name: 'Tests', status: 'skip', message: 'no test directory' });
|
|
151
|
+
}
|
|
152
|
+
// ── 8. air 설정 분석 (소스에서 shield/meter 사용 여부) ──
|
|
153
|
+
if (hasSrc) {
|
|
154
|
+
try {
|
|
155
|
+
const srcPath = resolve(cwd, 'src/index.ts');
|
|
156
|
+
const srcContent = await readFile(srcPath, 'utf-8');
|
|
157
|
+
// shield 설정 감지
|
|
158
|
+
if (srcContent.includes('shield:') || srcContent.includes('shield :')) {
|
|
159
|
+
const shieldEnabled = srcContent.includes('enabled: true') || srcContent.includes('enabled:true');
|
|
160
|
+
results.push({
|
|
161
|
+
name: 'Shield',
|
|
162
|
+
status: shieldEnabled ? 'pass' : 'warn',
|
|
163
|
+
message: shieldEnabled ? 'enabled' : 'configured but not enabled',
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
results.push({ name: 'Shield', status: 'warn', message: 'not configured' });
|
|
168
|
+
}
|
|
169
|
+
// meter 설정 감지
|
|
170
|
+
if (srcContent.includes('meter:') || srcContent.includes('meter :')) {
|
|
171
|
+
results.push({ name: 'Meter', status: 'pass', message: 'enabled' });
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
results.push({ name: 'Meter', status: 'warn', message: 'not configured' });
|
|
175
|
+
}
|
|
176
|
+
// 도구 수 감지
|
|
177
|
+
const toolCount = (srcContent.match(/defineTool\(/g) || []).length;
|
|
178
|
+
results.push({
|
|
179
|
+
name: 'Tools',
|
|
180
|
+
status: toolCount > 0 ? 'pass' : 'warn',
|
|
181
|
+
message: `${toolCount} tool(s) defined`,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
// 읽기 실패 시 스킵
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// ── 결과 출력 ──
|
|
189
|
+
printResults(results);
|
|
190
|
+
});
|
|
191
|
+
function printResults(results) {
|
|
192
|
+
printer.blank();
|
|
193
|
+
let passCount = 0;
|
|
194
|
+
let failCount = 0;
|
|
195
|
+
let warnCount = 0;
|
|
196
|
+
for (const r of results) {
|
|
197
|
+
const icon = r.status === 'pass' ? '✔' : r.status === 'fail' ? '✖' : r.status === 'warn' ? '⚠' : '–';
|
|
198
|
+
const color = r.status === 'pass' ? '\x1b[32m' : r.status === 'fail' ? '\x1b[31m' : r.status === 'warn' ? '\x1b[33m' : '\x1b[90m';
|
|
199
|
+
const reset = '\x1b[0m';
|
|
200
|
+
const name = r.name.padEnd(16);
|
|
201
|
+
console.log(` ${color}${icon}${reset} ${name} ${r.message}`);
|
|
202
|
+
if (r.status === 'pass')
|
|
203
|
+
passCount++;
|
|
204
|
+
else if (r.status === 'fail')
|
|
205
|
+
failCount++;
|
|
206
|
+
else if (r.status === 'warn')
|
|
207
|
+
warnCount++;
|
|
208
|
+
}
|
|
209
|
+
printer.blank();
|
|
210
|
+
if (failCount === 0) {
|
|
211
|
+
console.log(` \x1b[32m✅ All checks passed!${warnCount > 0 ? ` (${warnCount} warning${warnCount > 1 ? 's' : ''})` : ''}\x1b[0m`);
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
console.log(` \x1b[31m❌ ${failCount} check(s) failed, ${passCount} passed, ${warnCount} warning(s)\x1b[0m`);
|
|
215
|
+
}
|
|
216
|
+
printer.blank();
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwDpC,eAAO,MAAM,cAAc,SAqFvB,CAAC"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// Copyright 2026 CodePedia Labs. Licensed under Apache-2.0.
|
|
2
|
+
// air CLI — commands/connect.ts
|
|
3
|
+
//
|
|
4
|
+
// air connect <client> [--name <name>] [--transport stdio|http|sse] [--port <port>]
|
|
5
|
+
//
|
|
6
|
+
// MCP 클라이언트의 설정 파일에 현재 서버를 자동 등록한다.
|
|
7
|
+
// path-resolver로 OS별 경로를 해석하고, json-editor로 안전하게 수정.
|
|
8
|
+
//
|
|
9
|
+
// @example
|
|
10
|
+
// air connect claude-desktop
|
|
11
|
+
// air connect cursor --name my-db-tool
|
|
12
|
+
// air connect vscode --transport http --port 3100
|
|
13
|
+
import { Command } from 'commander';
|
|
14
|
+
import { resolve } from 'node:path';
|
|
15
|
+
import { readFile } from 'node:fs/promises';
|
|
16
|
+
import { printer } from '../utils/printer.js';
|
|
17
|
+
import { resolveClientConfig, listClients } from '../utils/path-resolver.js';
|
|
18
|
+
import { JsonEditor } from '../utils/json-editor.js';
|
|
19
|
+
/** package.json에서 서버 정보를 읽는다 */
|
|
20
|
+
async function readPkg(cwd) {
|
|
21
|
+
try {
|
|
22
|
+
const raw = await readFile(resolve(cwd, 'package.json'), 'utf-8');
|
|
23
|
+
const pkg = JSON.parse(raw);
|
|
24
|
+
return { name: pkg.name || 'air-server', version: pkg.version || '0.0.0' };
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return { name: 'air-server', version: '0.0.0' };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** MCP 서버 등록 엔트리 생성 */
|
|
31
|
+
function buildServerEntry(cwd, transport, port, opts) {
|
|
32
|
+
const host = opts.host || 'localhost';
|
|
33
|
+
if (transport === 'stdio') {
|
|
34
|
+
return {
|
|
35
|
+
command: 'npx',
|
|
36
|
+
args: ['tsx', `${cwd}/src/index.ts`],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (transport === 'sse') {
|
|
40
|
+
// mcp-proxy가 있으면 프록시 경유, 없으면 직접 연결
|
|
41
|
+
if (opts.proxyPath) {
|
|
42
|
+
return {
|
|
43
|
+
command: 'node',
|
|
44
|
+
args: [opts.proxyPath, `http://${host}:${port}`],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// 직접 SSE 연결 (클라이언트가 SSE를 지원하는 경우)
|
|
48
|
+
return {
|
|
49
|
+
url: `http://${host}:${port}/sse`,
|
|
50
|
+
transport: 'sse',
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// http (Streamable HTTP)
|
|
54
|
+
return {
|
|
55
|
+
url: `http://${host}:${port}`,
|
|
56
|
+
transport: 'http',
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export const connectCommand = new Command('connect')
|
|
60
|
+
.description('Register this MCP server with a client')
|
|
61
|
+
.argument('<client>', 'Client to connect: claude-desktop, cursor, vscode, ...')
|
|
62
|
+
.option('-n, --name <n>', 'Server name in client config (default: from package.json)')
|
|
63
|
+
.option('-t, --transport <type>', 'Transport: stdio | http | sse', 'stdio')
|
|
64
|
+
.option('-p, --port <port>', 'Port for http/sse transport', '3000')
|
|
65
|
+
.option('-H, --host <host>', 'Host for remote server (default: localhost)')
|
|
66
|
+
.option('--proxy <path>', 'Path to mcp-proxy.js for SSE via stdio-to-SSE proxy')
|
|
67
|
+
.action(async (client, opts) => {
|
|
68
|
+
const cwd = process.cwd();
|
|
69
|
+
// ── 1. 클라이언트 경로 해석 ──
|
|
70
|
+
let clientInfo;
|
|
71
|
+
try {
|
|
72
|
+
clientInfo = resolveClientConfig(client);
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
printer.error(err.message);
|
|
76
|
+
printer.blank();
|
|
77
|
+
printer.info('Available clients:');
|
|
78
|
+
printer.blank();
|
|
79
|
+
printer.list(listClients().map((c) => ({ name: c.id, description: c.name })));
|
|
80
|
+
printer.blank();
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
// custom 클라이언트는 경로 직접 지정 필요
|
|
84
|
+
if (client === 'custom') {
|
|
85
|
+
printer.error('Custom client requires manual config. See docs for details.');
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
// ── 2. 서버 이름 결정 ──
|
|
89
|
+
const pkg = await readPkg(cwd);
|
|
90
|
+
const serverName = opts.name || pkg.name;
|
|
91
|
+
// ── 3. 설정 파일 로드 ──
|
|
92
|
+
printer.blank();
|
|
93
|
+
printer.step(1, 3, `Loading ${clientInfo.displayName} config...`);
|
|
94
|
+
const editor = await JsonEditor.load(clientInfo.configPath);
|
|
95
|
+
// ── 4. 서버 엔트리 등록 ──
|
|
96
|
+
printer.step(2, 3, `Registering "${serverName}"...`);
|
|
97
|
+
const entryPath = `${clientInfo.mcpKey}.${serverName}`;
|
|
98
|
+
const entry = buildServerEntry(cwd, opts.transport, opts.port, {
|
|
99
|
+
host: opts.host,
|
|
100
|
+
proxyPath: opts.proxy,
|
|
101
|
+
});
|
|
102
|
+
// 이미 등록되어 있으면 덮어쓰기 경고
|
|
103
|
+
if (editor.has(entryPath)) {
|
|
104
|
+
printer.warn(`"${serverName}" already registered — overwriting.`);
|
|
105
|
+
}
|
|
106
|
+
editor.set(entryPath, entry);
|
|
107
|
+
// ── 5. 저장 ──
|
|
108
|
+
printer.step(3, 3, 'Saving config...');
|
|
109
|
+
await editor.save();
|
|
110
|
+
printer.blank();
|
|
111
|
+
printer.success(`Connected "${serverName}" to ${clientInfo.displayName}`);
|
|
112
|
+
printer.kv('config', clientInfo.configPath);
|
|
113
|
+
printer.kv('transport', opts.transport);
|
|
114
|
+
if (opts.transport !== 'stdio') {
|
|
115
|
+
printer.kv('host', opts.host || 'localhost');
|
|
116
|
+
printer.kv('port', opts.port);
|
|
117
|
+
}
|
|
118
|
+
if (opts.proxy) {
|
|
119
|
+
printer.kv('proxy', opts.proxy);
|
|
120
|
+
}
|
|
121
|
+
printer.blank();
|
|
122
|
+
if (opts.transport === 'stdio') {
|
|
123
|
+
printer.info('The client will start the server automatically via stdio.');
|
|
124
|
+
}
|
|
125
|
+
else if (opts.proxy) {
|
|
126
|
+
printer.info('The proxy will bridge stdio (client) ↔ SSE (server).');
|
|
127
|
+
printer.info(`Make sure the server is running: air start --transport sse --port ${opts.port}`);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
printer.info(`Make sure the server is running: air start --transport ${opts.transport} --port ${opts.port}`);
|
|
131
|
+
}
|
|
132
|
+
printer.blank();
|
|
133
|
+
});
|
|
134
|
+
;
|
|
135
|
+
//# sourceMappingURL=connect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqEpC,eAAO,MAAM,aAAa,SAoFtB,CAAC"}
|