@a2hmarket/a2hmarket 1.3.3 โ†’ 1.3.4

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.
@@ -2,7 +2,7 @@
2
2
  "id": "a2hmarket",
3
3
  "name": "A2H Market",
4
4
  "description": "A2H Market \u2014 AI agent marketplace with self-managed A2A messaging via MQTT.",
5
- "version": "1.3.3",
5
+ "version": "1.3.4",
6
6
  "hosts": [
7
7
  "openclaw"
8
8
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a2hmarket/a2hmarket",
3
- "version": "1.3.3",
3
+ "version": "1.3.4",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "index.ts",
@@ -49,32 +49,93 @@ export function deletePendingWelcome(): void {
49
49
 
50
50
  const WELCOME_TITLE = "๐ŸŽ‰ A2H Market ๆ’ไปถๅทฒๅฐฑ็ปช";
51
51
 
52
- const WELCOME_FEISHU_ELEMENTS = [
53
- {
54
- tag: "markdown" as const,
55
- content:
56
- "ๆˆ‘ๆ˜ฏไฝ ็š„ **A2H Market** AI ๅŠฉๆ‰‹๏ผŒๅฏไปฅๅธฎไฝ ๏ผš\n" +
57
- "๐Ÿ“ฆ ๅ‘ๅธƒๅ•†ๅ“ใ€ๆต่งˆๅธ‚ๅœบ\n" +
58
- "๐Ÿ’ฌ ่‡ชๅŠจไธŽๅ…ถไป– Agent ่ฐˆๅˆคๅๅ•†\n" +
59
- "๐Ÿ“‹ ็ฎก็†่ฎขๅ•ใ€ๅค„็†ๆ”ฏไป˜",
60
- },
61
- {
62
- tag: "markdown" as const,
63
- content: "---\n๐Ÿ” ้ฆ–ๆฌกไฝฟ็”จ่ฏทๅ‘้€ **\"็™ปๅฝ• A2H Market\"** ๅฎŒๆˆๆŽˆๆƒ",
64
- },
65
- ];
66
-
67
- const WELCOME_TEXT = [
68
- `**${WELCOME_TITLE}**`,
69
- "",
70
- "ๆˆ‘ๆ˜ฏไฝ ็š„ A2H Market AI ๅŠฉๆ‰‹๏ผŒๅฏไปฅๅธฎไฝ ๏ผš",
71
- "๐Ÿ“ฆ ๅ‘ๅธƒๅ•†ๅ“ใ€ๆต่งˆๅธ‚ๅœบ",
72
- "๐Ÿ’ฌ ่‡ชๅŠจไธŽๅ…ถไป– Agent ่ฐˆๅˆคๅๅ•†",
73
- "๐Ÿ“‹ ็ฎก็†่ฎขๅ•ใ€ๅค„็†ๆ”ฏไป˜",
74
- "",
75
- "---",
76
- '๐Ÿ” ้ฆ–ๆฌกไฝฟ็”จ่ฏทๅ‘้€ "็™ปๅฝ• A2H Market" ๅฎŒๆˆๆŽˆๆƒ',
77
- ].join("\n");
52
+ const AUTH_API_URL = "https://web.a2hmarket.ai";
53
+ const LOGIN_URL = "https://a2hmarket.ai";
54
+
55
+ async function generateAuthUrl(): Promise<string | null> {
56
+ try {
57
+ const { networkInterfaces } = await import("node:os");
58
+ const { createHash, randomBytes } = await import("node:crypto");
59
+
60
+ let mac = "00:00:00:00:00:00";
61
+ const ifaces = networkInterfaces();
62
+ for (const name of Object.keys(ifaces)) {
63
+ for (const iface of ifaces[name] ?? []) {
64
+ if (!iface.internal && iface.mac && iface.mac !== "00:00:00:00:00:00") {
65
+ mac = iface.mac;
66
+ break;
67
+ }
68
+ }
69
+ if (mac !== "00:00:00:00:00:00") break;
70
+ }
71
+
72
+ const timestamp = String(Math.floor(Date.now() / 1000));
73
+ try {
74
+ const formData = new URLSearchParams({ timestamp, mac });
75
+ const resp = await fetch(`${AUTH_API_URL}/v1/auth/init-login`, {
76
+ method: "POST",
77
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
78
+ body: formData.toString(),
79
+ });
80
+ const data = (await resp.json()) as { code?: string; url?: string };
81
+ if (data.url) return data.url;
82
+ } catch {
83
+ // fallback to local generation
84
+ }
85
+
86
+ const randomHex = randomBytes(32).toString("hex");
87
+ const macClean = mac.replace(/:/g, "");
88
+ const raw = `${randomHex}_${timestamp}_${macClean}`;
89
+ const code = createHash("md5").update(raw).digest("hex");
90
+ return `${LOGIN_URL}/authcode?code=${code}`;
91
+ } catch {
92
+ return null;
93
+ }
94
+ }
95
+
96
+ function buildFeishuElements(authUrl: string | null) {
97
+ const elements = [
98
+ {
99
+ tag: "markdown" as const,
100
+ content:
101
+ "ๆˆ‘ๆ˜ฏไฝ ็š„ **A2H Market** AI ๅŠฉๆ‰‹๏ผŒๅฏไปฅๅธฎไฝ ๏ผš\n" +
102
+ "๐Ÿ“ฆ ๅ‘ๅธƒๅ•†ๅ“ใ€ๆต่งˆๅธ‚ๅœบ\n" +
103
+ "๐Ÿ’ฌ ่‡ชๅŠจไธŽๅ…ถไป– Agent ่ฐˆๅˆคๅๅ•†\n" +
104
+ "๐Ÿ“‹ ็ฎก็†่ฎขๅ•ใ€ๅค„็†ๆ”ฏไป˜",
105
+ },
106
+ ];
107
+ if (authUrl) {
108
+ elements.push({
109
+ tag: "markdown" as const,
110
+ content: `---\n๐Ÿ” **[็‚นๅ‡ป่ฟ™้‡ŒๅฎŒๆˆๆŽˆๆƒ็™ปๅฝ•](${authUrl})**`,
111
+ });
112
+ } else {
113
+ elements.push({
114
+ tag: "markdown" as const,
115
+ content: '---\n๐Ÿ” ้ฆ–ๆฌกไฝฟ็”จ่ฏทๅ‘้€ **"็™ปๅฝ• A2H Market"** ๅฎŒๆˆๆŽˆๆƒ',
116
+ });
117
+ }
118
+ return elements;
119
+ }
120
+
121
+ function buildWelcomeText(authUrl: string | null): string {
122
+ const lines = [
123
+ `**${WELCOME_TITLE}**`,
124
+ "",
125
+ "ๆˆ‘ๆ˜ฏไฝ ็š„ A2H Market AI ๅŠฉๆ‰‹๏ผŒๅฏไปฅๅธฎไฝ ๏ผš",
126
+ "๐Ÿ“ฆ ๅ‘ๅธƒๅ•†ๅ“ใ€ๆต่งˆๅธ‚ๅœบ",
127
+ "๐Ÿ’ฌ ่‡ชๅŠจไธŽๅ…ถไป– Agent ่ฐˆๅˆคๅๅ•†",
128
+ "๐Ÿ“‹ ็ฎก็†่ฎขๅ•ใ€ๅค„็†ๆ”ฏไป˜",
129
+ "",
130
+ "---",
131
+ ];
132
+ if (authUrl) {
133
+ lines.push(`๐Ÿ” ็‚นๅ‡ปๅฎŒๆˆๆŽˆๆƒ็™ปๅฝ•: ${authUrl}`);
134
+ } else {
135
+ lines.push('๐Ÿ” ้ฆ–ๆฌกไฝฟ็”จ่ฏทๅ‘้€ "็™ปๅฝ• A2H Market" ๅฎŒๆˆๆŽˆๆƒ');
136
+ }
137
+ return lines.join("\n");
138
+ }
78
139
 
79
140
  // โ”€โ”€ Send Welcome โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
80
141
 
@@ -92,6 +153,12 @@ export async function sendWelcome(
92
153
  channelCfg: Record<string, unknown>,
93
154
  log: WelcomeLog,
94
155
  ): Promise<boolean> {
156
+ // Generate auth URL (best-effort, falls back to text prompt)
157
+ const authUrl = await generateAuthUrl();
158
+ if (authUrl) {
159
+ log.info(`welcome: auth url generated`);
160
+ }
161
+
95
162
  if (pending.channel === "feishu") {
96
163
  if (!channelCfg.appId || !channelCfg.appSecret) {
97
164
  log.warn("welcome: feishu channel credentials not configured, skipped");
@@ -104,7 +171,7 @@ export async function sendWelcome(
104
171
  target: pending.target,
105
172
  title: WELCOME_TITLE,
106
173
  titleColor: "green",
107
- elements: WELCOME_FEISHU_ELEMENTS,
174
+ elements: buildFeishuElements(authUrl),
108
175
  });
109
176
  return true;
110
177
  }
@@ -137,7 +204,7 @@ export async function sendWelcome(
137
204
  const resp = await fetch(`https://discord.com/api/v10/channels/${channelId}/messages`, {
138
205
  method: "POST",
139
206
  headers,
140
- body: JSON.stringify({ content: WELCOME_TEXT }),
207
+ body: JSON.stringify({ content: buildWelcomeText(authUrl) }),
141
208
  });
142
209
  if (!resp.ok) {
143
210
  const data = (await resp.json()) as { message?: string };