relayax-cli 0.1.991 → 0.1.994

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.
@@ -8,6 +8,8 @@ const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const ai_tools_js_1 = require("../lib/ai-tools.js");
10
10
  const command_adapter_js_1 = require("../lib/command-adapter.js");
11
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
12
+ const pkg = require('../../package.json');
11
13
  const VALID_TEAM_DIRS = ['skills', 'agents', 'rules', 'commands'];
12
14
  function resolveTools(toolsArg) {
13
15
  const raw = toolsArg.trim().toLowerCase();
@@ -9,7 +9,6 @@ const path_1 = __importDefault(require("path"));
9
9
  const api_js_1 = require("../lib/api.js");
10
10
  const storage_js_1 = require("../lib/storage.js");
11
11
  const config_js_1 = require("../lib/config.js");
12
- const preamble_js_1 = require("../lib/preamble.js");
13
12
  function registerInstall(program) {
14
13
  program
15
14
  .command('install <slug>')
@@ -62,8 +61,6 @@ function registerInstall(program) {
62
61
  return count;
63
62
  }
64
63
  const fileCount = countFiles(teamDir);
65
- // 5.5. Inject update-check preamble into SKILL.md files
66
- (0, preamble_js_1.injectPreambleToTeam)(teamDir, slug);
67
64
  // 6. Record in installed.json
68
65
  const installed = (0, config_js_1.loadInstalled)();
69
66
  installed[slug] = {
@@ -99,26 +96,27 @@ function registerInstall(program) {
99
96
  console.log(` \x1b[33m/${cmd.name}\x1b[0m - ${cmd.description}`);
100
97
  }
101
98
  }
102
- // Builder info block
103
- if (team.welcome) {
104
- console.log(`\n ┌─ 💬 ${authorDisplayName}님의 메시지 ${'─'.repeat(Math.max(0, 38 - authorDisplayName.length))}┐`);
105
- const lines = team.welcome.match(/.{1,50}/g) ?? [team.welcome];
106
- for (const line of lines) {
107
- console.log(` │ "${line}"`);
108
- }
109
- console.log(` └${'─'.repeat(44)}┘`);
110
- }
99
+ // Builder business card
111
100
  const contactLinks = team.author?.contact_links ?? {};
112
101
  const contactEntries = Object.entries(contactLinks);
113
- if (contactEntries.length > 0) {
114
- const parts = contactEntries.map(([key, val]) => `${key}: ${val}`);
115
- console.log(`\n 연락처: ${parts.join(' | ')}`);
116
- }
117
- if (authorUsername) {
118
- console.log(`\n \x1b[90m👤 프로필: relayax.com/@${authorUsername}\x1b[0m`);
119
- }
120
- if (team.latest_post && authorUsername) {
121
- console.log(` \x1b[90m📝 활용 팁: relayax.com/@${authorUsername}/posts/${team.latest_post.slug}\x1b[0m`);
102
+ const hasCard = team.welcome || contactEntries.length > 0 || authorUsername;
103
+ if (hasCard) {
104
+ console.log(`\n \x1b[90m┌─ ${authorDisplayName || authorUsername || '빌더'}의 명함 ${'─'.repeat(Math.max(0, 34 - (authorDisplayName || authorUsername || '빌더').length))}┐\x1b[0m`);
105
+ if (team.welcome) {
106
+ const truncated = team.welcome.length > 45 ? team.welcome.slice(0, 45) + '...' : team.welcome;
107
+ console.log(` \x1b[90m│\x1b[0m 💬 "${truncated}"`);
108
+ }
109
+ if (contactEntries.length > 0) {
110
+ const parts = contactEntries.map(([k, v]) => `${k}: ${v}`).join(' ');
111
+ console.log(` \x1b[90m│\x1b[0m 📇 ${parts}`);
112
+ }
113
+ if (authorUsername) {
114
+ console.log(` \x1b[90m│\x1b[0m 👤 relayax.com/@${authorUsername}`);
115
+ }
116
+ if (team.latest_post && authorUsername) {
117
+ console.log(` \x1b[90m│\x1b[0m 📝 relayax.com/@${authorUsername}/posts/${team.latest_post.slug}`);
118
+ }
119
+ console.log(` \x1b[90m└${'─'.repeat(44)}┘\x1b[0m`);
122
120
  }
123
121
  // Follow prompt (only when logged in)
124
122
  const token = (0, config_js_1.loadToken)();
@@ -96,7 +96,7 @@ function registerLogin(program) {
96
96
  .option('--token <token>', '직접 토큰 입력 (브라우저 없이)')
97
97
  .action(async (opts) => {
98
98
  const json = program.opts().json ?? false;
99
- (0, config_js_1.ensureRelayDir)();
99
+ (0, config_js_1.ensureGlobalRelayDir)();
100
100
  let token = opts.token;
101
101
  if (!token) {
102
102
  try {
@@ -433,6 +433,29 @@ function registerPublish(program) {
433
433
  if (result.portfolio_count && result.portfolio_count > 0) {
434
434
  console.log(` 포트폴리오: ${result.portfolio_count}개 이미지 업로드됨`);
435
435
  }
436
+ // Show business card preview
437
+ const profile = result.profile;
438
+ if (profile) {
439
+ const contacts = profile.contact_links ?? {};
440
+ const contactEntries = Object.entries(contacts);
441
+ const welcome = profile.default_welcome ?? '';
442
+ console.log(`\n \x1b[90m┌─ 설치자에게 보이는 명함 ${'─'.repeat(24)}┐\x1b[0m`);
443
+ if (welcome) {
444
+ console.log(` \x1b[90m│\x1b[0m 💬 "${welcome.length > 45 ? welcome.slice(0, 45) + '...' : welcome}"`);
445
+ }
446
+ if (contactEntries.length > 0) {
447
+ const parts = contactEntries.map(([k, v]) => `${k}: ${v}`).join(' ');
448
+ console.log(` \x1b[90m│\x1b[0m 📇 ${parts}`);
449
+ }
450
+ if (profile.username) {
451
+ console.log(` \x1b[90m│\x1b[0m 👤 relayax.com/@${profile.username}`);
452
+ }
453
+ if (!welcome && contactEntries.length === 0) {
454
+ console.log(` \x1b[90m│\x1b[0m \x1b[2m명함이 비어있습니다\x1b[0m`);
455
+ }
456
+ console.log(` \x1b[90m└${'─'.repeat(44)}┘\x1b[0m`);
457
+ console.log(`\n \x1b[90m명함 수정: \x1b[36mwww.relayax.com/dashboard/profile\x1b[0m`);
458
+ }
436
459
  }
437
460
  }
438
461
  catch (err) {
@@ -5,7 +5,6 @@ const api_js_1 = require("../lib/api.js");
5
5
  const storage_js_1 = require("../lib/storage.js");
6
6
  const installer_js_1 = require("../lib/installer.js");
7
7
  const config_js_1 = require("../lib/config.js");
8
- const preamble_js_1 = require("../lib/preamble.js");
9
8
  function registerUpdate(program) {
10
9
  program
11
10
  .command('update <slug>')
@@ -55,8 +54,6 @@ function registerUpdate(program) {
55
54
  await (0, storage_js_1.extractPackage)(tarPath, extractDir);
56
55
  // Copy files to install_path
57
56
  const files = (0, installer_js_1.installTeam)(extractDir, installPath);
58
- // Inject update-check preamble into SKILL.md files
59
- (0, preamble_js_1.injectPreambleToTeam)(installPath, slug);
60
57
  // Update installed.json with new version
61
58
  installed[slug] = {
62
59
  version: latestVersion,
@@ -82,6 +79,27 @@ function registerUpdate(program) {
82
79
  console.log(`\n\x1b[32m✓ ${team.name} ${fromLabel}v${latestVersion} 업데이트 완료\x1b[0m`);
83
80
  console.log(` 설치 위치: \x1b[36m${installPath}\x1b[0m`);
84
81
  console.log(` 파일 수: ${files.length}개`);
82
+ // Builder business card
83
+ const authorUsername = team.author?.username;
84
+ const authorDisplayName = team.author?.display_name ?? authorUsername ?? '';
85
+ const contactLinks = team.author?.contact_links ?? {};
86
+ const contactEntries = Object.entries(contactLinks);
87
+ const hasCard = team.welcome || contactEntries.length > 0 || authorUsername;
88
+ if (hasCard) {
89
+ console.log(`\n \x1b[90m┌─ ${authorDisplayName || '빌더'}의 명함 ${'─'.repeat(Math.max(0, 34 - (authorDisplayName || '빌더').length))}┐\x1b[0m`);
90
+ if (team.welcome) {
91
+ const truncated = team.welcome.length > 45 ? team.welcome.slice(0, 45) + '...' : team.welcome;
92
+ console.log(` \x1b[90m│\x1b[0m 💬 "${truncated}"`);
93
+ }
94
+ if (contactEntries.length > 0) {
95
+ const parts = contactEntries.map(([k, v]) => `${k}: ${v}`).join(' ');
96
+ console.log(` \x1b[90m│\x1b[0m 📇 ${parts}`);
97
+ }
98
+ if (authorUsername) {
99
+ console.log(` \x1b[90m│\x1b[0m 👤 relayax.com/@${authorUsername}`);
100
+ }
101
+ console.log(` \x1b[90m└${'─'.repeat(44)}┘\x1b[0m`);
102
+ }
85
103
  }
86
104
  }
87
105
  catch (err) {
@@ -83,6 +83,12 @@ exports.USER_COMMANDS = [
83
83
 
84
84
  ## 실행 방법
85
85
 
86
+ ### 0. 업데이트 확인
87
+ - 먼저 \`relay check-update\` 명령어를 실행합니다.
88
+ - CLI 업데이트가 있으면 사용자에게 안내합니다: "relay v{new} available. Run: npm update -g relayax-cli"
89
+ - 팀 업데이트가 있으면 안내합니다.
90
+ - 업데이트 여부와 관계없이 설치를 계속 진행합니다.
91
+
86
92
  ### 1. 팀 패키지 다운로드
87
93
  - \`relay install <slug>\` 명령어를 실행합니다.
88
94
  - 패키지가 \`.relay/teams/<slug>/\`에 다운로드됩니다.
@@ -155,6 +161,11 @@ ${LOGIN_JIT_GUIDE}
155
161
 
156
162
  ## 실행 방법
157
163
 
164
+ ### 0. CLI 업데이트 확인
165
+ - 먼저 \`relay check-update\` 명령어를 실행합니다.
166
+ - CLI 업데이트가 있으면 사용자에게 안내합니다: "relay v{new} available. Run: npm update -g relayax-cli"
167
+ - 업데이트 여부와 관계없이 팀 업데이트를 계속 진행합니다.
168
+
158
169
  ### 특정 팀 업데이트
159
170
  - 사용자가 팀 이름을 지정한 경우: \`relay update <slug> --json\` 실행
160
171
  - 업데이트 결과를 보여줍니다 (이전 버전 → 새 버전)
@@ -7,8 +7,13 @@ export declare const API_URL = "https://www.relayax.com";
7
7
  * 3. 감지 안 되면 현재 디렉토리에 직접 설치
8
8
  */
9
9
  export declare function getInstallPath(override?: string): string;
10
- export declare function ensureRelayDir(): void;
10
+ /** ~/.relay/ 글로벌 (token, CLI cache) */
11
+ export declare function ensureGlobalRelayDir(): void;
12
+ /** cwd/.relay/ — 프로젝트 로컬 (installed.json, teams/) */
13
+ export declare function ensureProjectRelayDir(): void;
11
14
  export declare function loadToken(): string | undefined;
12
15
  export declare function saveToken(token: string): void;
16
+ /** 프로젝트 로컬 installed.json 읽기 */
13
17
  export declare function loadInstalled(): InstalledRegistry;
18
+ /** 프로젝트 로컬 installed.json 쓰기 */
14
19
  export declare function saveInstalled(registry: InstalledRegistry): void;
@@ -5,7 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.API_URL = void 0;
7
7
  exports.getInstallPath = getInstallPath;
8
- exports.ensureRelayDir = ensureRelayDir;
8
+ exports.ensureGlobalRelayDir = ensureGlobalRelayDir;
9
+ exports.ensureProjectRelayDir = ensureProjectRelayDir;
9
10
  exports.loadToken = loadToken;
10
11
  exports.saveToken = saveToken;
11
12
  exports.loadInstalled = loadInstalled;
@@ -15,8 +16,7 @@ const path_1 = __importDefault(require("path"));
15
16
  const os_1 = __importDefault(require("os"));
16
17
  const ai_tools_js_1 = require("./ai-tools.js");
17
18
  exports.API_URL = 'https://www.relayax.com';
18
- const RELAY_DIR = path_1.default.join(os_1.default.homedir(), '.relay');
19
- const INSTALLED_FILE = path_1.default.join(RELAY_DIR, 'installed.json');
19
+ const GLOBAL_RELAY_DIR = path_1.default.join(os_1.default.homedir(), '.relay');
20
20
  /**
21
21
  * 설치 경로를 결정한다.
22
22
  * 1. --path 옵션이 있으면 그대로 사용
@@ -37,13 +37,21 @@ function getInstallPath(override) {
37
37
  }
38
38
  return cwd;
39
39
  }
40
- function ensureRelayDir() {
41
- if (!fs_1.default.existsSync(RELAY_DIR)) {
42
- fs_1.default.mkdirSync(RELAY_DIR, { recursive: true });
40
+ /** ~/.relay/ — 글로벌 (token, CLI cache) */
41
+ function ensureGlobalRelayDir() {
42
+ if (!fs_1.default.existsSync(GLOBAL_RELAY_DIR)) {
43
+ fs_1.default.mkdirSync(GLOBAL_RELAY_DIR, { recursive: true });
44
+ }
45
+ }
46
+ /** cwd/.relay/ — 프로젝트 로컬 (installed.json, teams/) */
47
+ function ensureProjectRelayDir() {
48
+ const dir = path_1.default.join(process.cwd(), '.relay');
49
+ if (!fs_1.default.existsSync(dir)) {
50
+ fs_1.default.mkdirSync(dir, { recursive: true });
43
51
  }
44
52
  }
45
53
  function loadToken() {
46
- const tokenFile = path_1.default.join(RELAY_DIR, 'token');
54
+ const tokenFile = path_1.default.join(GLOBAL_RELAY_DIR, 'token');
47
55
  if (!fs_1.default.existsSync(tokenFile))
48
56
  return undefined;
49
57
  try {
@@ -54,22 +62,26 @@ function loadToken() {
54
62
  }
55
63
  }
56
64
  function saveToken(token) {
57
- ensureRelayDir();
58
- fs_1.default.writeFileSync(path_1.default.join(RELAY_DIR, 'token'), token);
65
+ ensureGlobalRelayDir();
66
+ fs_1.default.writeFileSync(path_1.default.join(GLOBAL_RELAY_DIR, 'token'), token);
59
67
  }
68
+ /** 프로젝트 로컬 installed.json 읽기 */
60
69
  function loadInstalled() {
61
- if (!fs_1.default.existsSync(INSTALLED_FILE)) {
70
+ const file = path_1.default.join(process.cwd(), '.relay', 'installed.json');
71
+ if (!fs_1.default.existsSync(file)) {
62
72
  return {};
63
73
  }
64
74
  try {
65
- const raw = fs_1.default.readFileSync(INSTALLED_FILE, 'utf-8');
75
+ const raw = fs_1.default.readFileSync(file, 'utf-8');
66
76
  return JSON.parse(raw);
67
77
  }
68
78
  catch {
69
79
  return {};
70
80
  }
71
81
  }
82
+ /** 프로젝트 로컬 installed.json 쓰기 */
72
83
  function saveInstalled(registry) {
73
- ensureRelayDir();
74
- fs_1.default.writeFileSync(INSTALLED_FILE, JSON.stringify(registry, null, 2));
84
+ ensureProjectRelayDir();
85
+ const file = path_1.default.join(process.cwd(), '.relay', 'installed.json');
86
+ fs_1.default.writeFileSync(file, JSON.stringify(registry, null, 2));
75
87
  }
package/dist/types.d.ts CHANGED
@@ -2,6 +2,7 @@ export interface InstalledTeam {
2
2
  version: string;
3
3
  installed_at: string;
4
4
  files: string[];
5
+ type?: 'team' | 'system';
5
6
  }
6
7
  export interface InstalledRegistry {
7
8
  [slug: string]: InstalledTeam;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "relayax-cli",
3
- "version": "0.1.991",
3
+ "version": "0.1.994",
4
4
  "description": "RelayAX Agent Team Marketplace CLI - Install and manage agent teams",
5
5
  "main": "dist/index.js",
6
6
  "bin": {