relayax-cli 0.1.997 → 0.1.999
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/dist/commands/install.js +5 -6
- package/dist/commands/publish.js +5 -6
- package/dist/commands/update.js +5 -6
- package/dist/lib/api.d.ts +1 -0
- package/dist/lib/api.js +17 -0
- package/dist/lib/command-adapter.js +1 -1
- package/dist/lib/contact-format.d.ts +7 -0
- package/dist/lib/contact-format.js +23 -0
- package/dist/lib/version-check.js +2 -0
- package/dist/types.d.ts +6 -1
- package/package.json +1 -1
package/dist/commands/install.js
CHANGED
|
@@ -10,6 +10,7 @@ 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
12
|
const slug_js_1 = require("../lib/slug.js");
|
|
13
|
+
const contact_format_js_1 = require("../lib/contact-format.js");
|
|
13
14
|
function registerInstall(program) {
|
|
14
15
|
program
|
|
15
16
|
.command('install <slug>')
|
|
@@ -101,18 +102,16 @@ function registerInstall(program) {
|
|
|
101
102
|
}
|
|
102
103
|
}
|
|
103
104
|
// Builder business card
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
const hasCard = team.welcome || contactEntries.length > 0 || authorUsername;
|
|
105
|
+
const contactParts = (0, contact_format_js_1.formatContactParts)(team.author?.contact_links);
|
|
106
|
+
const hasCard = team.welcome || contactParts.length > 0 || authorUsername;
|
|
107
107
|
if (hasCard) {
|
|
108
108
|
console.log(`\n \x1b[90m┌─ ${authorDisplayName || authorUsername || '빌더'}의 명함 ${'─'.repeat(Math.max(0, 34 - (authorDisplayName || authorUsername || '빌더').length))}┐\x1b[0m`);
|
|
109
109
|
if (team.welcome) {
|
|
110
110
|
const truncated = team.welcome.length > 45 ? team.welcome.slice(0, 45) + '...' : team.welcome;
|
|
111
111
|
console.log(` \x1b[90m│\x1b[0m 💬 "${truncated}"`);
|
|
112
112
|
}
|
|
113
|
-
if (
|
|
114
|
-
|
|
115
|
-
console.log(` \x1b[90m│\x1b[0m 📇 ${parts}`);
|
|
113
|
+
if (contactParts.length > 0) {
|
|
114
|
+
console.log(` \x1b[90m│\x1b[0m 📇 ${contactParts.join(' ')}`);
|
|
116
115
|
}
|
|
117
116
|
if (authorUsername) {
|
|
118
117
|
console.log(` \x1b[90m│\x1b[0m 👤 relayax.com/@${authorUsername}`);
|
package/dist/commands/publish.js
CHANGED
|
@@ -10,6 +10,7 @@ const os_1 = __importDefault(require("os"));
|
|
|
10
10
|
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
11
11
|
const tar_1 = require("tar");
|
|
12
12
|
const config_js_1 = require("../lib/config.js");
|
|
13
|
+
const contact_format_js_1 = require("../lib/contact-format.js");
|
|
13
14
|
const version_check_js_1 = require("../lib/version-check.js");
|
|
14
15
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
15
16
|
const cliPkg = require('../../package.json');
|
|
@@ -436,21 +437,19 @@ function registerPublish(program) {
|
|
|
436
437
|
// Show business card preview
|
|
437
438
|
const profile = result.profile;
|
|
438
439
|
if (profile) {
|
|
439
|
-
const
|
|
440
|
-
const contactEntries = Object.entries(contacts);
|
|
440
|
+
const contactParts = (0, contact_format_js_1.formatContactParts)(profile.contact_links);
|
|
441
441
|
const welcome = profile.default_welcome ?? '';
|
|
442
442
|
console.log(`\n \x1b[90m┌─ 설치자에게 보이는 명함 ${'─'.repeat(24)}┐\x1b[0m`);
|
|
443
443
|
if (welcome) {
|
|
444
444
|
console.log(` \x1b[90m│\x1b[0m 💬 "${welcome.length > 45 ? welcome.slice(0, 45) + '...' : welcome}"`);
|
|
445
445
|
}
|
|
446
|
-
if (
|
|
447
|
-
|
|
448
|
-
console.log(` \x1b[90m│\x1b[0m 📇 ${parts}`);
|
|
446
|
+
if (contactParts.length > 0) {
|
|
447
|
+
console.log(` \x1b[90m│\x1b[0m 📇 ${contactParts.join(' ')}`);
|
|
449
448
|
}
|
|
450
449
|
if (profile.username) {
|
|
451
450
|
console.log(` \x1b[90m│\x1b[0m 👤 relayax.com/@${profile.username}`);
|
|
452
451
|
}
|
|
453
|
-
if (!welcome &&
|
|
452
|
+
if (!welcome && contactParts.length === 0) {
|
|
454
453
|
console.log(` \x1b[90m│\x1b[0m \x1b[2m명함이 비어있습니다\x1b[0m`);
|
|
455
454
|
}
|
|
456
455
|
console.log(` \x1b[90m└${'─'.repeat(44)}┘\x1b[0m`);
|
package/dist/commands/update.js
CHANGED
|
@@ -6,6 +6,7 @@ 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
8
|
const slug_js_1 = require("../lib/slug.js");
|
|
9
|
+
const contact_format_js_1 = require("../lib/contact-format.js");
|
|
9
10
|
function registerUpdate(program) {
|
|
10
11
|
program
|
|
11
12
|
.command('update <slug>')
|
|
@@ -98,18 +99,16 @@ function registerUpdate(program) {
|
|
|
98
99
|
// Builder business card
|
|
99
100
|
const authorUsername = team.author?.username;
|
|
100
101
|
const authorDisplayName = team.author?.display_name ?? authorUsername ?? '';
|
|
101
|
-
const
|
|
102
|
-
const
|
|
103
|
-
const hasCard = team.welcome || contactEntries.length > 0 || authorUsername;
|
|
102
|
+
const contactParts = (0, contact_format_js_1.formatContactParts)(team.author?.contact_links);
|
|
103
|
+
const hasCard = team.welcome || contactParts.length > 0 || authorUsername;
|
|
104
104
|
if (hasCard) {
|
|
105
105
|
console.log(`\n \x1b[90m┌─ ${authorDisplayName || '빌더'}의 명함 ${'─'.repeat(Math.max(0, 34 - (authorDisplayName || '빌더').length))}┐\x1b[0m`);
|
|
106
106
|
if (team.welcome) {
|
|
107
107
|
const truncated = team.welcome.length > 45 ? team.welcome.slice(0, 45) + '...' : team.welcome;
|
|
108
108
|
console.log(` \x1b[90m│\x1b[0m 💬 "${truncated}"`);
|
|
109
109
|
}
|
|
110
|
-
if (
|
|
111
|
-
|
|
112
|
-
console.log(` \x1b[90m│\x1b[0m 📇 ${parts}`);
|
|
110
|
+
if (contactParts.length > 0) {
|
|
111
|
+
console.log(` \x1b[90m│\x1b[0m 📇 ${contactParts.join(' ')}`);
|
|
113
112
|
}
|
|
114
113
|
if (authorUsername) {
|
|
115
114
|
console.log(` \x1b[90m│\x1b[0m 👤 relayax.com/@${authorUsername}`);
|
package/dist/lib/api.d.ts
CHANGED
|
@@ -14,4 +14,5 @@ export interface ResolvedSlug {
|
|
|
14
14
|
full: string;
|
|
15
15
|
}
|
|
16
16
|
export declare function resolveSlugFromServer(name: string): Promise<ResolvedSlug[]>;
|
|
17
|
+
export declare function sendUsagePing(slug: string): Promise<void>;
|
|
17
18
|
export declare function followBuilder(username: string): Promise<void>;
|
package/dist/lib/api.js
CHANGED
|
@@ -5,6 +5,7 @@ exports.searchTeams = searchTeams;
|
|
|
5
5
|
exports.fetchTeamVersions = fetchTeamVersions;
|
|
6
6
|
exports.reportInstall = reportInstall;
|
|
7
7
|
exports.resolveSlugFromServer = resolveSlugFromServer;
|
|
8
|
+
exports.sendUsagePing = sendUsagePing;
|
|
8
9
|
exports.followBuilder = followBuilder;
|
|
9
10
|
const config_js_1 = require("./config.js");
|
|
10
11
|
async function fetchTeamInfo(slug) {
|
|
@@ -56,6 +57,22 @@ async function resolveSlugFromServer(name) {
|
|
|
56
57
|
const data = (await res.json());
|
|
57
58
|
return data.results;
|
|
58
59
|
}
|
|
60
|
+
async function sendUsagePing(slug) {
|
|
61
|
+
const registrySlug = slug.startsWith('@') ? slug.slice(1) : slug;
|
|
62
|
+
const { createHash } = await import('crypto');
|
|
63
|
+
const { hostname, userInfo } = await import('os');
|
|
64
|
+
const deviceHash = createHash('sha256')
|
|
65
|
+
.update(`${hostname()}:${userInfo().username}`)
|
|
66
|
+
.digest('hex');
|
|
67
|
+
const url = `${config_js_1.API_URL}/api/registry/${registrySlug}/ping`;
|
|
68
|
+
await fetch(url, {
|
|
69
|
+
method: 'POST',
|
|
70
|
+
headers: { 'Content-Type': 'application/json' },
|
|
71
|
+
body: JSON.stringify({ device_hash: deviceHash }),
|
|
72
|
+
}).catch(() => {
|
|
73
|
+
// fire-and-forget: ignore errors
|
|
74
|
+
});
|
|
75
|
+
}
|
|
59
76
|
async function followBuilder(username) {
|
|
60
77
|
const token = await (0, config_js_1.getValidToken)();
|
|
61
78
|
const headers = {
|
|
@@ -282,7 +282,7 @@ requires:
|
|
|
282
282
|
config:
|
|
283
283
|
command: "npx"
|
|
284
284
|
args: ["-y", "@supabase/mcp-server"]
|
|
285
|
-
env: [SUPABASE_URL,
|
|
285
|
+
env: [SUPABASE_URL, SUPABASE_SECRET_KEY]
|
|
286
286
|
- name: notion
|
|
287
287
|
package: "@notionhq/mcp-server"
|
|
288
288
|
required: false
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ContactItem } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* contact_links를 "key: value" 쌍의 배열로 정규화한다.
|
|
4
|
+
* - 배열 형식 (신규): [{type, label, value}, ...] → ["label: value", ...]
|
|
5
|
+
* - 객체 형식 (레거시): {email: "a@b"} → ["email: a@b", ...]
|
|
6
|
+
*/
|
|
7
|
+
export declare function formatContactParts(contactLinks: ContactItem[] | Record<string, string> | unknown): string[];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatContactParts = formatContactParts;
|
|
4
|
+
/**
|
|
5
|
+
* contact_links를 "key: value" 쌍의 배열로 정규화한다.
|
|
6
|
+
* - 배열 형식 (신규): [{type, label, value}, ...] → ["label: value", ...]
|
|
7
|
+
* - 객체 형식 (레거시): {email: "a@b"} → ["email: a@b", ...]
|
|
8
|
+
*/
|
|
9
|
+
function formatContactParts(contactLinks) {
|
|
10
|
+
if (!contactLinks)
|
|
11
|
+
return [];
|
|
12
|
+
if (Array.isArray(contactLinks)) {
|
|
13
|
+
return contactLinks
|
|
14
|
+
.filter((c) => c.value?.trim())
|
|
15
|
+
.map((c) => `${c.label || c.type}: ${c.value}`);
|
|
16
|
+
}
|
|
17
|
+
if (typeof contactLinks === 'object') {
|
|
18
|
+
return Object.entries(contactLinks)
|
|
19
|
+
.filter(([, v]) => typeof v === 'string' && v.trim())
|
|
20
|
+
.map(([k, v]) => `${k}: ${v}`);
|
|
21
|
+
}
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
@@ -42,6 +42,8 @@ async function checkTeamVersion(slug, force) {
|
|
|
42
42
|
}
|
|
43
43
|
const team = await (0, api_js_1.fetchTeamInfo)(slug);
|
|
44
44
|
(0, update_cache_js_1.updateCacheTimestamp)(slug);
|
|
45
|
+
// Fire-and-forget usage ping (only when cache expired = actual API call happened)
|
|
46
|
+
(0, api_js_1.sendUsagePing)(slug);
|
|
45
47
|
if (team.version !== entry.version) {
|
|
46
48
|
return {
|
|
47
49
|
type: 'team',
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
export interface ContactItem {
|
|
2
|
+
type: string;
|
|
3
|
+
label: string;
|
|
4
|
+
value: string;
|
|
5
|
+
}
|
|
1
6
|
export interface InstalledTeam {
|
|
2
7
|
version: string;
|
|
3
8
|
installed_at: string;
|
|
@@ -31,7 +36,7 @@ export interface TeamRegistryInfo {
|
|
|
31
36
|
author?: {
|
|
32
37
|
username: string;
|
|
33
38
|
display_name: string | null;
|
|
34
|
-
contact_links: Record<string, string>;
|
|
39
|
+
contact_links: ContactItem[] | Record<string, string>;
|
|
35
40
|
} | null;
|
|
36
41
|
latest_post?: {
|
|
37
42
|
title: string;
|