@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.
Files changed (122) hide show
  1. package/LICENSE +17 -0
  2. package/dist/commands/add.d.ts +3 -0
  3. package/dist/commands/add.d.ts.map +1 -0
  4. package/dist/commands/add.js +192 -0
  5. package/dist/commands/add.js.map +1 -0
  6. package/dist/commands/check.d.ts +3 -0
  7. package/dist/commands/check.d.ts.map +1 -0
  8. package/dist/commands/check.js +218 -0
  9. package/dist/commands/check.js.map +1 -0
  10. package/dist/commands/connect.d.ts +3 -0
  11. package/dist/commands/connect.d.ts.map +1 -0
  12. package/dist/commands/connect.js +135 -0
  13. package/dist/commands/connect.js.map +1 -0
  14. package/dist/commands/create.d.ts +3 -0
  15. package/dist/commands/create.d.ts.map +1 -0
  16. package/dist/commands/create.js +150 -0
  17. package/dist/commands/create.js.map +1 -0
  18. package/dist/commands/dev.d.ts +3 -0
  19. package/dist/commands/dev.d.ts.map +1 -0
  20. package/dist/commands/dev.js +184 -0
  21. package/dist/commands/dev.js.map +1 -0
  22. package/dist/commands/disconnect.d.ts +3 -0
  23. package/dist/commands/disconnect.d.ts.map +1 -0
  24. package/dist/commands/disconnect.js +69 -0
  25. package/dist/commands/disconnect.js.map +1 -0
  26. package/dist/commands/index.d.ts +13 -0
  27. package/dist/commands/index.d.ts.map +1 -0
  28. package/dist/commands/index.js +16 -0
  29. package/dist/commands/index.js.map +1 -0
  30. package/dist/commands/inspect.d.ts +3 -0
  31. package/dist/commands/inspect.d.ts.map +1 -0
  32. package/dist/commands/inspect.js +159 -0
  33. package/dist/commands/inspect.js.map +1 -0
  34. package/dist/commands/license.d.ts +3 -0
  35. package/dist/commands/license.d.ts.map +1 -0
  36. package/dist/commands/license.js +113 -0
  37. package/dist/commands/license.js.map +1 -0
  38. package/dist/commands/list.d.ts +3 -0
  39. package/dist/commands/list.d.ts.map +1 -0
  40. package/dist/commands/list.js +101 -0
  41. package/dist/commands/list.js.map +1 -0
  42. package/dist/commands/start.d.ts +3 -0
  43. package/dist/commands/start.d.ts.map +1 -0
  44. package/dist/commands/start.js +130 -0
  45. package/dist/commands/start.js.map +1 -0
  46. package/dist/commands/status.d.ts +3 -0
  47. package/dist/commands/status.d.ts.map +1 -0
  48. package/dist/commands/status.js +83 -0
  49. package/dist/commands/status.js.map +1 -0
  50. package/dist/commands/stop.d.ts +3 -0
  51. package/dist/commands/stop.d.ts.map +1 -0
  52. package/dist/commands/stop.js +56 -0
  53. package/dist/commands/stop.js.map +1 -0
  54. package/dist/index.d.ts +3 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +46 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/templates/agent/.ai/context.md +36 -0
  59. package/dist/templates/agent/.vscode/air.code-snippets +178 -0
  60. package/dist/templates/agent/package.json +17 -0
  61. package/dist/templates/agent/src/index.ts +98 -0
  62. package/dist/templates/agent/tsconfig.json +14 -0
  63. package/dist/templates/agent-ko/.ai/context.md +36 -0
  64. package/dist/templates/agent-ko/.vscode/air.code-snippets +178 -0
  65. package/dist/templates/agent-ko/package.json +17 -0
  66. package/dist/templates/agent-ko/src/index.ts +92 -0
  67. package/dist/templates/agent-ko/tsconfig.json +14 -0
  68. package/dist/templates/api/.ai/context.md +36 -0
  69. package/dist/templates/api/.vscode/air.code-snippets +178 -0
  70. package/dist/templates/api/package.json +17 -0
  71. package/dist/templates/api/src/index.ts +76 -0
  72. package/dist/templates/api/tsconfig.json +14 -0
  73. package/dist/templates/api-ko/.ai/context.md +36 -0
  74. package/dist/templates/api-ko/.vscode/air.code-snippets +178 -0
  75. package/dist/templates/api-ko/package.json +17 -0
  76. package/dist/templates/api-ko/src/index.ts +70 -0
  77. package/dist/templates/api-ko/tsconfig.json +14 -0
  78. package/dist/templates/basic/.ai/context.md +36 -0
  79. package/dist/templates/basic/.vscode/air.code-snippets +178 -0
  80. package/dist/templates/basic/package.json +17 -0
  81. package/dist/templates/basic/src/index.ts +39 -0
  82. package/dist/templates/basic/tsconfig.json +15 -0
  83. package/dist/templates/basic-ko/.ai/context.md +36 -0
  84. package/dist/templates/basic-ko/.vscode/air.code-snippets +178 -0
  85. package/dist/templates/basic-ko/package.json +17 -0
  86. package/dist/templates/basic-ko/src/index.ts +39 -0
  87. package/dist/templates/basic-ko/tsconfig.json +14 -0
  88. package/dist/templates/crud/.ai/context.md +36 -0
  89. package/dist/templates/crud/.vscode/air.code-snippets +178 -0
  90. package/dist/templates/crud/package.json +17 -0
  91. package/dist/templates/crud/src/index.ts +82 -0
  92. package/dist/templates/crud/tsconfig.json +14 -0
  93. package/dist/templates/crud-ko/.ai/context.md +36 -0
  94. package/dist/templates/crud-ko/.vscode/air.code-snippets +178 -0
  95. package/dist/templates/crud-ko/package.json +17 -0
  96. package/dist/templates/crud-ko/src/index.ts +81 -0
  97. package/dist/templates/crud-ko/tsconfig.json +14 -0
  98. package/dist/utils/index.d.ts +7 -0
  99. package/dist/utils/index.d.ts.map +1 -0
  100. package/dist/utils/index.js +8 -0
  101. package/dist/utils/index.js.map +1 -0
  102. package/dist/utils/json-editor.d.ts +45 -0
  103. package/dist/utils/json-editor.d.ts.map +1 -0
  104. package/dist/utils/json-editor.js +122 -0
  105. package/dist/utils/json-editor.js.map +1 -0
  106. package/dist/utils/path-resolver.d.ts +30 -0
  107. package/dist/utils/path-resolver.d.ts.map +1 -0
  108. package/dist/utils/path-resolver.js +121 -0
  109. package/dist/utils/path-resolver.js.map +1 -0
  110. package/dist/utils/printer.d.ts +26 -0
  111. package/dist/utils/printer.d.ts.map +1 -0
  112. package/dist/utils/printer.js +65 -0
  113. package/dist/utils/printer.js.map +1 -0
  114. package/dist/utils/process-manager.d.ts +36 -0
  115. package/dist/utils/process-manager.d.ts.map +1 -0
  116. package/dist/utils/process-manager.js +143 -0
  117. package/dist/utils/process-manager.js.map +1 -0
  118. package/dist/utils/test-console.d.ts +8 -0
  119. package/dist/utils/test-console.d.ts.map +1 -0
  120. package/dist/utils/test-console.js +198 -0
  121. package/dist/utils/test-console.js.map +1 -0
  122. 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,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const addCommand: Command;
3
+ //# sourceMappingURL=add.d.ts.map
@@ -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,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const checkCommand: Command;
3
+ //# sourceMappingURL=check.d.ts.map
@@ -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,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const connectCommand: Command;
3
+ //# sourceMappingURL=connect.d.ts.map
@@ -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,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const createCommand: Command;
3
+ //# sourceMappingURL=create.d.ts.map
@@ -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"}