anpm-io 1.0.0 → 1.0.1

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 (69) hide show
  1. package/dist/commands/access.js +10 -82
  2. package/dist/commands/adopt.js +1 -1
  3. package/dist/commands/changelog.js +9 -59
  4. package/dist/commands/check-update.js +8 -69
  5. package/dist/commands/create.js +56 -56
  6. package/dist/commands/deploy-record.js +10 -10
  7. package/dist/commands/deploy.js +1 -1
  8. package/dist/commands/diff.js +8 -8
  9. package/dist/commands/feedback.js +7 -7
  10. package/dist/commands/grant.js +28 -28
  11. package/dist/commands/init.d.ts +1 -1
  12. package/dist/commands/init.js +38 -38
  13. package/dist/commands/install.js +75 -71
  14. package/dist/commands/join.d.ts +1 -4
  15. package/dist/commands/join.js +15 -83
  16. package/dist/commands/list.js +12 -12
  17. package/dist/commands/login.d.ts +2 -2
  18. package/dist/commands/login.js +26 -26
  19. package/dist/commands/orgs.js +24 -24
  20. package/dist/commands/outdated.js +35 -11
  21. package/dist/commands/package.d.ts +8 -8
  22. package/dist/commands/package.js +76 -76
  23. package/dist/commands/ping.js +4 -4
  24. package/dist/commands/publish.js +113 -113
  25. package/dist/commands/run.js +10 -10
  26. package/dist/commands/search.js +8 -8
  27. package/dist/commands/status.js +9 -9
  28. package/dist/commands/uninstall.js +9 -9
  29. package/dist/commands/update.js +10 -10
  30. package/dist/commands/versions.js +6 -6
  31. package/dist/index.js +23 -20
  32. package/dist/lib/ai-tools.d.ts +8 -8
  33. package/dist/lib/ai-tools.js +10 -10
  34. package/dist/lib/api.js +8 -8
  35. package/dist/lib/command-adapter.d.ts +10 -10
  36. package/dist/lib/command-adapter.js +78 -78
  37. package/dist/lib/config.d.ts +20 -20
  38. package/dist/lib/config.js +41 -41
  39. package/dist/lib/contact-format.d.ts +3 -3
  40. package/dist/lib/contact-format.js +3 -3
  41. package/dist/lib/error-report.d.ts +2 -2
  42. package/dist/lib/error-report.js +2 -2
  43. package/dist/lib/git-operations.d.ts +2 -2
  44. package/dist/lib/git-operations.js +6 -6
  45. package/dist/lib/installer.d.ts +10 -10
  46. package/dist/lib/installer.js +32 -32
  47. package/dist/lib/paths.d.ts +4 -4
  48. package/dist/lib/paths.js +4 -4
  49. package/dist/lib/preamble.d.ts +7 -7
  50. package/dist/lib/preamble.js +24 -19
  51. package/dist/lib/relay-config.js +1 -1
  52. package/dist/lib/requires-suggest.d.ts +3 -3
  53. package/dist/lib/requires-suggest.js +28 -28
  54. package/dist/lib/setup-command.d.ts +2 -2
  55. package/dist/lib/setup-command.js +22 -22
  56. package/dist/lib/slug.d.ts +8 -8
  57. package/dist/lib/slug.js +16 -16
  58. package/dist/lib/step-tracker.d.ts +2 -2
  59. package/dist/lib/step-tracker.js +2 -2
  60. package/dist/lib/version-check.js +2 -2
  61. package/dist/mcp/server.js +15 -15
  62. package/dist/postinstall.d.ts +3 -3
  63. package/dist/postinstall.js +16 -16
  64. package/dist/prompts/_error-handling.md +26 -26
  65. package/dist/prompts/create.md +115 -115
  66. package/dist/prompts/explore.md +19 -19
  67. package/dist/prompts/index.js +2 -2
  68. package/dist/types.d.ts +10 -10
  69. package/package.json +1 -1
@@ -1,90 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.registerAccess = registerAccess;
4
- const commander_1 = require("commander");
5
- const config_js_1 = require("../lib/config.js");
6
- async function claimAccess(slug, code) {
7
- const token = await (0, config_js_1.getValidToken)();
8
- if (!token) {
9
- throw new Error('LOGIN_REQUIRED');
10
- }
11
- const res = await fetch(`${config_js_1.API_URL}/api/agents/${slug}/claim-access`, {
12
- method: 'POST',
13
- headers: {
14
- 'Content-Type': 'application/json',
15
- Authorization: `Bearer ${token}`,
16
- },
17
- body: JSON.stringify({ code }),
18
- signal: AbortSignal.timeout(10000),
19
- });
20
- const body = (await res.json().catch(() => ({})));
21
- if (!res.ok) {
22
- const errCode = body.error ?? String(res.status);
23
- switch (errCode) {
24
- case 'INVALID_LINK':
25
- throw new Error('초대 링크가 유효하지 않거나 만료되었습니다.');
26
- case 'NOT_FOUND':
27
- throw new Error('에이전트를 찾을 수 없습니다.');
28
- case 'UNAUTHORIZED':
29
- throw new Error('LOGIN_REQUIRED');
30
- default:
31
- throw new Error(body.message ?? `접근 권한 요청 실패 (${res.status})`);
32
- }
33
- }
34
- return body;
35
- }
36
4
  function registerAccess(program) {
37
5
  program
38
- .command('access <slug>')
39
- .description('초대 코드로 에이전트에 접근 권한을 얻고 바로 설치합니다')
40
- .requiredOption('--code <code>', '에이전트 초대 코드')
6
+ .command('access <slug>', { hidden: true })
7
+ .description('(deprecated) Use anpm install --code instead')
8
+ .requiredOption('--code <code>', 'Agent access code')
41
9
  .action(async (slug, opts) => {
42
- const json = program.opts().json ?? false;
43
- try {
44
- const result = await claimAccess(slug, opts.code);
45
- if (!result.success || !result.agent) {
46
- throw new Error('서버 응답이 올바르지 않습니다.');
47
- }
48
- const agentSlug = result.agent.slug;
49
- if (json) {
50
- console.log(JSON.stringify({ status: 'ok', agent: result.agent }));
51
- }
52
- else {
53
- console.log(`\x1b[32m접근 권한이 부여되었습니다: ${result.agent.name}\x1b[0m`);
54
- console.log(`\x1b[33m에이전트를 설치합니다: anpm install ${agentSlug}\x1b[0m\n`);
55
- }
56
- // Automatically install the agent
57
- const { registerInstall } = await import('./install.js');
58
- const subProgram = new commander_1.Command();
59
- subProgram.option('--json', '구조화된 JSON 출력');
60
- if (json)
61
- subProgram.setOptionValue('json', true);
62
- registerInstall(subProgram);
63
- await subProgram.parseAsync(['node', 'relay', 'install', agentSlug]);
64
- }
65
- catch (err) {
66
- const message = err instanceof Error ? err.message : String(err);
67
- if (message === 'LOGIN_REQUIRED') {
68
- if (json) {
69
- console.error(JSON.stringify({
70
- error: 'LOGIN_REQUIRED',
71
- message: '로그인이 필요합니다. anpm login을 먼저 실행하세요.',
72
- fix: 'anpm login 실행 후 재시도하세요.',
73
- }));
74
- }
75
- else {
76
- console.error('\x1b[31m오류: 로그인이 필요합니다.\x1b[0m');
77
- console.error(' anpm login을 먼저 실행하세요.');
78
- }
79
- process.exit(1);
80
- }
81
- if (json) {
82
- console.error(JSON.stringify({ error: 'ACCESS_FAILED', message, fix: '접근 링크 코드를 확인하거나 에이전트 제작자에게 문의하세요.' }));
83
- }
84
- else {
85
- console.error(`\x1b[31m오류: ${message}\x1b[0m`);
86
- }
87
- process.exit(1);
88
- }
10
+ console.error('\x1b[33m⚠ access is deprecated. Use "anpm install --code" instead.\x1b[0m\n');
11
+ // Delegate to install --code
12
+ const args = ['node', 'anpm', 'install', slug, '--code', opts.code];
13
+ const json = program.opts().json;
14
+ if (json)
15
+ args.push('--json');
16
+ await program.parseAsync(args, { from: 'user' });
89
17
  });
90
18
  }
@@ -13,7 +13,7 @@ const installer_js_1 = require("../lib/installer.js");
13
13
  const agent_status_js_1 = require("../lib/agent-status.js");
14
14
  function registerAdopt(program) {
15
15
  program
16
- .command('adopt [path]')
16
+ .command('adopt [path]', { hidden: true })
17
17
  .description('Adopt unmanaged skills into anpm management')
18
18
  .option('--all', 'Adopt all unmanaged skills')
19
19
  .option('--global', 'Adopt to global scope')
@@ -1,67 +1,17 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.registerChangelog = registerChangelog;
7
- const fs_1 = __importDefault(require("fs"));
8
- const path_1 = __importDefault(require("path"));
9
- const js_yaml_1 = __importDefault(require("js-yaml"));
10
4
  function registerChangelog(program) {
11
- const changelog = program
12
- .command('changelog')
13
- .description('에이전트 패키지의 changelog를 관리합니다');
14
- changelog
15
- .command('add')
16
- .description('relay.yaml에 changelog 엔트리를 추가합니다')
17
- .argument('[message]', 'changelog 메시지 (없으면 에디터에서 입력)')
18
- .action(async (message) => {
19
- const yamlPath = path_1.default.resolve('relay.yaml');
20
- if (!fs_1.default.existsSync(yamlPath)) {
21
- console.error('relay.yaml을 찾을 수 없습니다. 에이전트 패키지 디렉토리에서 실행하세요.');
22
- process.exit(1);
5
+ program
6
+ .command('changelog [slug]', { hidden: true })
7
+ .description('(deprecated) Use anpm versions instead')
8
+ .action(async (slug) => {
9
+ console.error('\x1b[33m⚠ changelog is deprecated. Use "anpm versions <slug>" instead.\x1b[0m\n');
10
+ if (slug) {
11
+ await program.parseAsync(['node', 'anpm', 'versions', slug], { from: 'user' });
23
12
  }
24
- const content = fs_1.default.readFileSync(yamlPath, 'utf-8');
25
- const doc = js_yaml_1.default.load(content) ?? {};
26
- if (!message) {
27
- // Read from stdin if piped, otherwise prompt
28
- const readline = await import('readline');
29
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
30
- message = await new Promise((resolve) => {
31
- rl.question('Changelog 메시지: ', (answer) => {
32
- rl.close();
33
- resolve(answer);
34
- });
35
- });
13
+ else {
14
+ console.error('Usage: anpm versions <slug>');
36
15
  }
37
- if (!message || message.trim() === '') {
38
- console.error('changelog 메시지가 비어있습니다.');
39
- process.exit(1);
40
- }
41
- const version = String(doc.version ?? '1.0.0');
42
- const date = new Date().toISOString().split('T')[0];
43
- const entry = `## v${version} (${date})\n\n- ${message.trim()}`;
44
- const existing = doc.changelog ? String(doc.changelog) : '';
45
- doc.changelog = existing ? `${entry}\n\n${existing}` : entry;
46
- fs_1.default.writeFileSync(yamlPath, js_yaml_1.default.dump(doc, { lineWidth: -1, noRefs: true }), 'utf-8');
47
- console.log(`\x1b[32m✓\x1b[0m changelog 추가됨 (v${version})`);
48
- console.log(` ${message.trim()}`);
49
- });
50
- changelog
51
- .command('show')
52
- .description('현재 relay.yaml의 changelog를 표시합니다')
53
- .action(() => {
54
- const yamlPath = path_1.default.resolve('relay.yaml');
55
- if (!fs_1.default.existsSync(yamlPath)) {
56
- console.error('relay.yaml을 찾을 수 없습니다.');
57
- process.exit(1);
58
- }
59
- const content = fs_1.default.readFileSync(yamlPath, 'utf-8');
60
- const doc = js_yaml_1.default.load(content) ?? {};
61
- if (!doc.changelog) {
62
- console.log('changelog가 없습니다. `anpm changelog add "메시지"`로 추가하세요.');
63
- return;
64
- }
65
- console.log(String(doc.changelog));
66
16
  });
67
17
  }
@@ -1,76 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.registerCheckUpdate = registerCheckUpdate;
4
- const version_check_js_1 = require("../lib/version-check.js");
5
- const slug_js_1 = require("../lib/slug.js");
6
4
  function registerCheckUpdate(program) {
7
5
  program
8
- .command('check-update [slug]')
9
- .description('CLI 설치된 에이전트의 업데이트를 확인합니다')
10
- .option('--quiet', '업데이트가 있을 때만 머신 리더블 출력')
11
- .option('--force', '캐시를 무시하고 강제 체크')
12
- .action(async (slug, opts) => {
13
- const quiet = opts.quiet ?? false;
14
- const force = opts.force ?? false;
15
- // CLI version check
16
- const cliResult = await (0, version_check_js_1.checkCliVersion)(force);
17
- if (cliResult) {
18
- if (quiet) {
19
- console.log(`CLI_UPGRADE_AVAILABLE ${cliResult.current} ${cliResult.latest}`);
20
- }
21
- else {
22
- console.log(`\n\x1b[33m⚠ anpm v${cliResult.latest} available\x1b[0m (현재 v${cliResult.current})`);
23
- console.log(` 실행: npm update -g relayax-cli\n`);
24
- }
25
- }
26
- // Agent version check
27
- if (slug) {
28
- // Resolve to scoped slug
29
- let scopedSlug;
30
- if ((0, slug_js_1.isScopedSlug)(slug)) {
31
- scopedSlug = slug;
32
- }
33
- else {
34
- try {
35
- const parsed = await (0, slug_js_1.resolveSlug)(slug);
36
- scopedSlug = parsed.full;
37
- }
38
- catch {
39
- scopedSlug = slug;
40
- }
41
- }
42
- const agentResult = await (0, version_check_js_1.checkAgentVersion)(scopedSlug, force);
43
- if (agentResult) {
44
- if (quiet) {
45
- const byAuthor = agentResult.author ? ` ${agentResult.author}` : '';
46
- console.log(`AGENT_UPGRADE_AVAILABLE ${slug} ${agentResult.current} ${agentResult.latest}${byAuthor}`);
47
- }
48
- else {
49
- const byAuthor = agentResult.author ? ` \x1b[90m(by @${agentResult.author})\x1b[0m` : '';
50
- console.log(`\x1b[33m⚠ ${slug} v${agentResult.latest} available\x1b[0m${byAuthor} (현재 v${agentResult.current})`);
51
- console.log(` 실행: anpm update ${slug}`);
52
- }
53
- }
54
- else if (!quiet && !cliResult) {
55
- console.log('모든 것이 최신 상태입니다.');
56
- }
57
- }
58
- else {
59
- const agentResults = await (0, version_check_js_1.checkAllAgents)(force);
60
- for (const result of agentResults) {
61
- if (quiet) {
62
- const byAuthor = result.author ? ` ${result.author}` : '';
63
- console.log(`AGENT_UPGRADE_AVAILABLE ${result.slug} ${result.current} ${result.latest}${byAuthor}`);
64
- }
65
- else {
66
- const byAuthor = result.author ? ` \x1b[90m(by @${result.author})\x1b[0m` : '';
67
- console.log(`\x1b[33m⚠ ${result.slug} v${result.latest} available\x1b[0m${byAuthor} (현재 v${result.current})`);
68
- console.log(` 실행: anpm update ${result.slug}`);
69
- }
70
- }
71
- if (!quiet && !cliResult && agentResults.length === 0) {
72
- console.log('모든 것이 최신 상태입니다.');
73
- }
74
- }
6
+ .command('check-update [slug]', { hidden: true })
7
+ .description('(deprecated) Use anpm outdated instead')
8
+ .option('--quiet', 'Machine-readable output only when updates are available')
9
+ .option('--force', 'Force check, ignoring cache')
10
+ .action(async () => {
11
+ console.error('\x1b[33m⚠ check-update is deprecated. Use "anpm outdated" instead.\x1b[0m\n');
12
+ // Delegate to outdated
13
+ await program.parseAsync(['node', 'anpm', 'outdated'], { from: 'user' });
75
14
  });
76
15
  }
@@ -15,7 +15,7 @@ const slug_js_1 = require("../lib/slug.js");
15
15
  const paths_js_1 = require("../lib/paths.js");
16
16
  const DEFAULT_DIRS = ['.anpm/skills', '.anpm/commands'];
17
17
  /**
18
- * 글로벌 User 커맨드가 없으면 설치한다.
18
+ * Install global User commands if not already present.
19
19
  */
20
20
  function ensureGlobalUserCommands() {
21
21
  if ((0, init_js_1.hasGlobalUserCommands)())
@@ -26,12 +26,12 @@ function ensureGlobalUserCommands() {
26
26
  function registerCreate(program) {
27
27
  program
28
28
  .command('create <name>')
29
- .description(' 에이전트 프로젝트를 생성합니다')
30
- .option('--description <desc>', '에이전트 설명')
31
- .option('--slug <slug>', 'URL 식별자 (영문 소문자, 숫자, 하이픈)')
32
- .option('--tags <tags>', '태그 (쉼표 구분)')
33
- .option('--visibility <visibility>', '공개 범위 (public, private, internal)')
34
- .option('--project <dir>', '프로젝트 루트 경로 (기본: cwd, 환경변수: RELAY_PROJECT_PATH)')
29
+ .description('Create a new agent project')
30
+ .option('--description <desc>', 'Agent description')
31
+ .option('--slug <slug>', 'URL-safe identifier (lowercase, numbers, hyphens)')
32
+ .option('--tags <tags>', 'Tags (comma-separated)')
33
+ .option('--visibility <visibility>', 'Visibility (public, private, internal)')
34
+ .option('--project <dir>', 'Project root path (default: cwd, env: ANPM_PROJECT_PATH)')
35
35
  .action(async (name, opts) => {
36
36
  const json = program.opts().json ?? false;
37
37
  (0, step_tracker_js_1.trackCommand)('create');
@@ -39,37 +39,37 @@ function registerCreate(program) {
39
39
  const relayDir = path_1.default.join(projectPath, '.anpm');
40
40
  const relayYamlPath = path_1.default.join(relayDir, 'anpm.yaml');
41
41
  const isTTY = Boolean(process.stdin.isTTY) && !json;
42
- // 1. .anpm/anpm.yaml 이미 존재하면 에러
42
+ // 1. Error if .anpm/anpm.yaml already exists
43
43
  if (fs_1.default.existsSync(relayYamlPath)) {
44
44
  if (json) {
45
- console.error(JSON.stringify({ error: 'ALREADY_EXISTS', message: '.anpm/anpm.yaml 이미 존재합니다.', fix: '기존 .anpm/anpm.yaml 확인하세요. 새로 시작하려면 삭제 재시도.' }));
45
+ console.error(JSON.stringify({ error: 'ALREADY_EXISTS', message: '.anpm/anpm.yaml already exists.', fix: 'Check your existing .anpm/anpm.yaml. To start fresh, delete it and try again.' }));
46
46
  }
47
47
  else {
48
- console.error('.anpm/anpm.yaml 이미 존재합니다. 기존 에이전트 프로젝트에서는 `anpm init`을 사용하세요.');
48
+ console.error('.anpm/anpm.yaml already exists. Use `anpm init` for existing agent projects.');
49
49
  }
50
50
  process.exit(1);
51
51
  }
52
- // 2. 메타데이터 수집
52
+ // 2. Collect metadata
53
53
  let slug = opts.slug ?? (0, slug_js_1.slugify)(name);
54
54
  let description = opts.description ?? '';
55
55
  let tags = opts.tags ? opts.tags.split(',').map((t) => t.trim()).filter(Boolean) : [];
56
56
  let visibility = opts.visibility ?? 'public';
57
57
  if (json) {
58
- // --json 모드: slug 비어있으면 에러
58
+ // --json mode: error if slug is empty
59
59
  if (!slug) {
60
60
  console.error(JSON.stringify({
61
61
  error: 'INVALID_SLUG',
62
- message: '이름에서 유효한 slug 생성할 없습니다. 영문 이름을 사용하거나 --slug 옵션을 지정하세요.',
63
- fix: `anpm create "${name}" --slug <영문-slug> --description <설명> --json`,
62
+ message: 'Cannot generate a valid slug from the name. Use an ASCII name or specify --slug.',
63
+ fix: `anpm create "${name}" --slug <slug> --description <description> --json`,
64
64
  }));
65
65
  process.exit(1);
66
66
  }
67
- // --json 모드: 필수 부족 에러 반환 (프롬프트 없음)
67
+ // --json mode: error if required fields missing (no prompt)
68
68
  if (!opts.description) {
69
69
  console.error(JSON.stringify({
70
70
  error: 'MISSING_FIELD',
71
- message: '에이전트 설명이 필요합니다.',
72
- fix: `relay create ${name} --description <설명> --json`,
71
+ message: 'Agent description is required.',
72
+ fix: `anpm create ${name} --description <description> --json`,
73
73
  field: 'description',
74
74
  }));
75
75
  process.exit(1);
@@ -77,12 +77,12 @@ function registerCreate(program) {
77
77
  if (!opts.visibility) {
78
78
  console.error(JSON.stringify({
79
79
  error: 'MISSING_VISIBILITY',
80
- message: '공개 범위를 선택하세요.',
81
- fix: `relay create ${name} --description "${description}" --visibility <visibility> --json`,
80
+ message: 'Select visibility.',
81
+ fix: `anpm create ${name} --description "${description}" --visibility <visibility> --json`,
82
82
  options: [
83
- { value: 'public', label: '공개누구나 검색 설치 가능' },
84
- { value: 'private', label: '비공개허가 코드 등록자만 사용 가능' },
85
- { value: 'internal', label: '내부조직 내의 누구나 사용 가능' },
83
+ { value: 'public', label: 'Publicanyone can discover and install' },
84
+ { value: 'private', label: 'Privateonly authorized users with an access code' },
85
+ { value: 'internal', label: 'Internalanyone in the organization' },
86
86
  ],
87
87
  }));
88
88
  process.exit(1);
@@ -90,12 +90,12 @@ function registerCreate(program) {
90
90
  if (!['public', 'private', 'internal'].includes(opts.visibility)) {
91
91
  console.error(JSON.stringify({
92
92
  error: 'INVALID_FIELD',
93
- message: `유효하지 않은 visibility 값: ${opts.visibility}`,
94
- fix: `visibility public, private, internal 중 하나여야 합니다.`,
93
+ message: `Invalid visibility value: ${opts.visibility}`,
94
+ fix: `visibility must be one of: public, private, internal.`,
95
95
  options: [
96
- { value: 'public', label: '공개' },
97
- { value: 'private', label: '비공개' },
98
- { value: 'internal', label: '내부' },
96
+ { value: 'public', label: 'Public' },
97
+ { value: 'private', label: 'Private' },
98
+ { value: 'internal', label: 'Internal' },
99
99
  ],
100
100
  }));
101
101
  process.exit(1);
@@ -103,17 +103,17 @@ function registerCreate(program) {
103
103
  }
104
104
  else if (isTTY) {
105
105
  const { input: promptInput, select: promptSelect } = await import('@inquirer/prompts');
106
- console.log(`\n \x1b[33m⚡\x1b[0m \x1b[1mrelay create\x1b[0m — 에이전트 프로젝트\n`);
107
- // slug 비어있으면 (한국어 등 비ASCII 이름) slug를 직접 입력받음
106
+ console.log(`\n \x1b[33m⚡\x1b[0m \x1b[1manpm create\x1b[0m — New agent project\n`);
107
+ // If slug is empty (non-ASCII name), prompt for manual input
108
108
  if (!slug) {
109
109
  slug = await promptInput({
110
- message: 'Slug (URL/설치에 사용되는 영문 식별자):',
110
+ message: 'Slug (URL-safe identifier for install):',
111
111
  validate: (v) => {
112
112
  const trimmed = v.trim();
113
113
  if (!trimmed)
114
- return 'slug를 입력해주세요.';
114
+ return 'Please enter a slug.';
115
115
  if (!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(trimmed))
116
- return '소문자, 숫자, 하이픈만 사용 가능합니다.';
116
+ return 'Only lowercase letters, numbers, and hyphens allowed.';
117
117
  return true;
118
118
  },
119
119
  });
@@ -121,36 +121,36 @@ function registerCreate(program) {
121
121
  }
122
122
  if (!description) {
123
123
  description = await promptInput({
124
- message: '에이전트 설명:',
125
- validate: (v) => v.trim().length > 0 ? true : '설명을 입력해주세요.',
124
+ message: 'Agent description:',
125
+ validate: (v) => v.trim().length > 0 ? true : 'Please enter a description.',
126
126
  });
127
127
  }
128
128
  if (!opts.tags) {
129
129
  const tagsRaw = await promptInput({
130
- message: '태그 (쉼표로 구분, 선택):',
130
+ message: 'Tags (comma-separated, optional):',
131
131
  default: '',
132
132
  });
133
133
  tags = tagsRaw.split(',').map((t) => t.trim()).filter(Boolean);
134
134
  }
135
135
  if (!opts.visibility) {
136
136
  visibility = await promptSelect({
137
- message: '공개 범위:',
137
+ message: 'Visibility:',
138
138
  choices: [
139
- { name: '공개누구나 검색 설치 가능', value: 'public' },
140
- { name: '비공개허가 코드 등록자만 사용 가능', value: 'private' },
141
- { name: '내부조직 내의 누구나 사용 가능', value: 'internal' },
139
+ { name: 'Publicanyone can discover and install', value: 'public' },
140
+ { name: 'Privateonly authorized users with an access code', value: 'private' },
141
+ { name: 'Internalanyone in the organization', value: 'internal' },
142
142
  ],
143
143
  });
144
144
  }
145
145
  }
146
- // 3. recommended_scope 자동 추천
147
- // rules/ 존재 or 프레임워크 태그 → local, → global
146
+ // 3. Auto-recommend recommended_scope
147
+ // rules/ exists or framework tag → local, otherwise → global
148
148
  const frameworkTags = ['nextjs', 'react', 'vue', 'angular', 'svelte', 'nuxt', 'remix', 'astro', 'django', 'rails', 'laravel', 'spring', 'express', 'fastapi', 'flask'];
149
149
  const hasRules = fs_1.default.existsSync(path_1.default.join(projectPath, '.relay', 'rules'))
150
150
  || fs_1.default.existsSync(path_1.default.join(projectPath, 'rules'));
151
151
  const hasFrameworkTag = tags.some((t) => frameworkTags.includes(t.toLowerCase()));
152
152
  const recommendedScope = (hasRules || hasFrameworkTag) ? 'local' : 'global';
153
- // 4. .relay/relay.yaml 생성
153
+ // 4. Create .relay/relay.yaml
154
154
  fs_1.default.mkdirSync(relayDir, { recursive: true });
155
155
  const yamlData = {
156
156
  name,
@@ -164,7 +164,7 @@ function registerCreate(program) {
164
164
  contents: [],
165
165
  };
166
166
  fs_1.default.writeFileSync(relayYamlPath, js_yaml_1.default.dump(yamlData, { lineWidth: 120 }), 'utf-8');
167
- // 4. 디렉토리 구조 생성
167
+ // 4. Create directory structure
168
168
  const createdDirs = [];
169
169
  for (const dir of DEFAULT_DIRS) {
170
170
  const dirPath = path_1.default.join(projectPath, dir);
@@ -173,7 +173,7 @@ function registerCreate(program) {
173
173
  createdDirs.push(dir);
174
174
  }
175
175
  }
176
- // 5. 로컬 Builder 슬래시 커맨드 설치
176
+ // 5. Install local Builder slash commands
177
177
  const detected = (0, ai_tools_js_1.detectAgentCLIs)(projectPath);
178
178
  const localResults = [];
179
179
  for (const tool of detected) {
@@ -187,41 +187,41 @@ function registerCreate(program) {
187
187
  }
188
188
  localResults.push({ tool: tool.name, commands: installed });
189
189
  }
190
- // 6. 글로벌 User 커맨드 (없으면 설치)
190
+ // 6. Global User commands (install if absent)
191
191
  const globalInstalled = ensureGlobalUserCommands();
192
- // 7. 출력
192
+ // 7. Output
193
193
  if (json) {
194
194
  console.log(JSON.stringify({
195
195
  status: 'ok',
196
196
  name,
197
197
  slug: slug,
198
198
  recommended_scope: recommendedScope,
199
- relay_yaml: 'created',
199
+ anpm_yaml: 'created',
200
200
  directories: createdDirs,
201
201
  local_commands: localResults,
202
202
  global_commands: globalInstalled ? 'installed' : 'already',
203
203
  }));
204
204
  }
205
205
  else {
206
- const scopeLabel = recommendedScope === 'global' ? '\x1b[32m글로벌\x1b[0m' : '\x1b[33m로컬\x1b[0m';
207
- const scopeReason = hasRules ? 'rules/ 감지' : hasFrameworkTag ? '프레임워크 태그 감지' : '범용 에이전트';
208
- console.log(`\n\x1b[32m✓ ${name} 에이전트 프로젝트 생성 완료\x1b[0m\n`);
209
- console.log(` .relay/relay.yaml 생성됨`);
206
+ const scopeLabel = recommendedScope === 'global' ? '\x1b[32mglobal\x1b[0m' : '\x1b[33mlocal\x1b[0m';
207
+ const scopeReason = hasRules ? 'rules/ detected' : hasFrameworkTag ? 'framework tag detected' : 'general-purpose agent';
208
+ console.log(`\n\x1b[32m✓ ${name} agent project created\x1b[0m\n`);
209
+ console.log(` .anpm/anpm.yaml created`);
210
210
  console.log(` recommended_scope: ${scopeLabel} (${scopeReason})`);
211
211
  if (createdDirs.length > 0) {
212
- console.log(` 디렉토리 생성: ${createdDirs.join(', ')}`);
212
+ console.log(` Directories created: ${createdDirs.join(', ')}`);
213
213
  }
214
214
  if (localResults.length > 0) {
215
- console.log(`\n \x1b[36mBuilder 커맨드 (로컬)\x1b[0m`);
215
+ console.log(`\n \x1b[36mBuilder commands (local)\x1b[0m`);
216
216
  for (const r of localResults) {
217
217
  console.log(` ${r.tool}: ${r.commands.map((c) => `/${c}`).join(', ')}`);
218
218
  }
219
219
  }
220
220
  if (globalInstalled) {
221
- console.log(`\n \x1b[36mUser 커맨드 (글로벌)\x1b[0m — 설치됨`);
221
+ console.log(`\n \x1b[36mUser commands (global)\x1b[0m — installed`);
222
222
  }
223
- console.log(`\n 다음 단계: \x1b[33m/relay-publish\x1b[0m로 Space에 배포`);
224
- console.log(' IDE 재시작하면 슬래시 커맨드가 활성화됩니다.\n');
223
+ console.log(`\n Next steps: Publish to Space with \x1b[33m/anpm-create\x1b[0m`);
224
+ console.log(' Restart your IDE to activate slash commands.\n');
225
225
  }
226
226
  });
227
227
  }
@@ -9,20 +9,20 @@ const config_js_1 = require("../lib/config.js");
9
9
  const slug_js_1 = require("../lib/slug.js");
10
10
  function registerDeployRecord(program) {
11
11
  program
12
- .command('deploy-record <slug>')
13
- .description('에이전트가 배치한 파일 정보를 installed.json에 기록합니다')
14
- .requiredOption('--scope <scope>', '배치 범위 (global 또는 local)')
15
- .option('--files <paths...>', '배치된 파일 경로 목록')
12
+ .command('deploy-record <slug>', { hidden: true })
13
+ .description('Record deployed file info in installed.json')
14
+ .requiredOption('--scope <scope>', 'Deploy scope (global or local)')
15
+ .option('--files <paths...>', 'List of deployed file paths')
16
16
  .action((slugInput, opts) => {
17
17
  const json = program.opts().json ?? false;
18
18
  const scope = opts.scope;
19
19
  if (scope !== 'global' && scope !== 'local') {
20
- const msg = { error: 'INVALID_SCOPE', message: '--scope global 또는 local이어야 합니다.' };
20
+ const msg = { error: 'INVALID_SCOPE', message: '--scope must be global or local.' };
21
21
  if (json) {
22
22
  console.error(JSON.stringify(msg));
23
23
  }
24
24
  else {
25
- console.error(`\x1b[31m오류:\x1b[0m ${msg.message}`);
25
+ console.error(`\x1b[31mError:\x1b[0m ${msg.message}`);
26
26
  }
27
27
  process.exit(1);
28
28
  }
@@ -50,12 +50,12 @@ function registerDeployRecord(program) {
50
50
  // Check if agent exists in either registry
51
51
  const entry = localRegistry[slug] ?? globalRegistry[slug];
52
52
  if (!entry) {
53
- const msg = { error: 'NOT_INSTALLED', message: `'${slugInput}' 설치되어 있지 않습니다.` };
53
+ const msg = { error: 'NOT_INSTALLED', message: `'${slugInput}' is not installed.` };
54
54
  if (json) {
55
55
  console.error(JSON.stringify(msg));
56
56
  }
57
57
  else {
58
- console.error(`\x1b[31m오류:\x1b[0m ${msg.message}`);
58
+ console.error(`\x1b[31mError:\x1b[0m ${msg.message}`);
59
59
  }
60
60
  process.exit(1);
61
61
  }
@@ -86,8 +86,8 @@ function registerDeployRecord(program) {
86
86
  console.log(JSON.stringify(result));
87
87
  }
88
88
  else {
89
- const scopeLabel = scope === 'global' ? '글로벌' : '로컬';
90
- console.log(`\x1b[32m✓ ${slug} 배치 정보 기록 완료\x1b[0m (${scopeLabel}, ${resolvedFiles.length} 파일)`);
89
+ const scopeLabel = scope === 'global' ? 'global' : 'local';
90
+ console.log(`\x1b[32m✓ ${slug} deploy info recorded\x1b[0m (${scopeLabel}, ${resolvedFiles.length} files)`);
91
91
  }
92
92
  });
93
93
  }
@@ -276,7 +276,7 @@ function registerDeploy(program) {
276
276
  console.error(JSON.stringify({ error: 'DEPLOY_FAILED', message: msg }));
277
277
  }
278
278
  else {
279
- console.error(`\x1b[31m오류: ${msg}\x1b[0m`);
279
+ console.error(`\x1b[31mError: ${msg}\x1b[0m`);
280
280
  }
281
281
  process.exit(1);
282
282
  }