@jingyi0605/codingns 0.7.3 → 0.7.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.
@@ -0,0 +1,51 @@
1
+ export type WechatClawLoginStatus = "not_logged_in" | "waiting_scan" | "scan_confirmed" | "active" | "expired";
2
+ export interface WechatClawStartLoginResult {
3
+ sessionKey: string;
4
+ qrcode: string;
5
+ qrcodeUrl: string | null;
6
+ status: WechatClawLoginStatus;
7
+ }
8
+ export interface WechatClawPollLoginResult {
9
+ status: WechatClawLoginStatus;
10
+ botToken: string | null;
11
+ baseUrl: string | null;
12
+ remoteBotId: string | null;
13
+ boundUserId: string | null;
14
+ redirectHost: string | null;
15
+ }
16
+ export interface WechatClawPollMessagesResult {
17
+ nextCursor: string | null;
18
+ longPollingTimeoutMs: number | null;
19
+ messages: WechatClawInboundMessage[];
20
+ }
21
+ export interface WechatClawInboundMessage {
22
+ messageId: string;
23
+ fromUserId: string | null;
24
+ toUserId: string | null;
25
+ text: string | null;
26
+ timestamp: string | null;
27
+ contextToken: string | null;
28
+ rawPayload: Record<string, unknown>;
29
+ }
30
+ export interface WechatClawSendTextResult {
31
+ messageRef: string | null;
32
+ }
33
+ export declare function startWechatClawLogin(): Promise<WechatClawStartLoginResult>;
34
+ export declare function pollWechatClawLoginStatus(options: {
35
+ qrcode: string;
36
+ authBaseUrl?: string | null;
37
+ }): Promise<WechatClawPollLoginResult>;
38
+ export declare function pollWechatClawMessages(options: {
39
+ baseUrl?: string | null;
40
+ botToken: string;
41
+ cursor?: string | null;
42
+ timeoutMs?: number;
43
+ }): Promise<WechatClawPollMessagesResult>;
44
+ export declare function sendWechatClawText(options: {
45
+ baseUrl?: string | null;
46
+ botToken: string;
47
+ toUserId: string;
48
+ contextToken: string;
49
+ text: string;
50
+ }): Promise<WechatClawSendTextResult>;
51
+ export declare function normalizeWechatClawBaseUrl(value?: string | null): string;
@@ -0,0 +1,245 @@
1
+ import { randomInt } from "node:crypto";
2
+ import { AppError } from "../../shared/errors/app-error.js";
3
+ const WECHAT_CLAW_FIXED_BASE_URL = "https://ilinkai.weixin.qq.com";
4
+ const WECHAT_CLAW_BOT_TYPE = "3";
5
+ const WECHAT_CLAW_APP_ID = "bot";
6
+ const WECHAT_CLAW_APP_CLIENT_VERSION = String(0x00020107);
7
+ export async function startWechatClawLogin() {
8
+ const payload = await fetchWechatClawJson(`${WECHAT_CLAW_FIXED_BASE_URL}/ilink/bot/get_bot_qrcode?bot_type=${encodeURIComponent(WECHAT_CLAW_BOT_TYPE)}`);
9
+ const qrcode = readBodyText(payload, "qrcode");
10
+ if (!qrcode) {
11
+ throw platformRequestFailed("微信 claw 登录二维码响应缺少 qrcode");
12
+ }
13
+ return {
14
+ sessionKey: qrcode,
15
+ qrcode,
16
+ qrcodeUrl: readBodyText(payload, "qrcode_img_content"),
17
+ status: "waiting_scan"
18
+ };
19
+ }
20
+ export async function pollWechatClawLoginStatus(options) {
21
+ const payload = await fetchWechatClawJson(`${normalizeWechatClawBaseUrl(options.authBaseUrl)}/ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(options.qrcode)}`);
22
+ const rawStatus = readBodyText(payload, "status");
23
+ switch (rawStatus) {
24
+ case "wait":
25
+ return createWechatClawPollLoginResult("waiting_scan");
26
+ case "scaned":
27
+ return createWechatClawPollLoginResult("scan_confirmed");
28
+ case "expired":
29
+ return createWechatClawPollLoginResult("expired");
30
+ case "scaned_but_redirect":
31
+ return {
32
+ ...createWechatClawPollLoginResult("scan_confirmed"),
33
+ redirectHost: readBodyText(payload, "redirect_host")
34
+ };
35
+ case "confirmed":
36
+ return {
37
+ status: "active",
38
+ botToken: readBodyText(payload, "bot_token"),
39
+ baseUrl: readBodyText(payload, "baseurl") ?? normalizeWechatClawBaseUrl(options.authBaseUrl),
40
+ remoteBotId: readBodyText(payload, "ilink_bot_id"),
41
+ boundUserId: readBodyText(payload, "ilink_user_id"),
42
+ redirectHost: null
43
+ };
44
+ default:
45
+ throw platformRequestFailed(`微信 claw 登录状态无法识别:${rawStatus ?? "unknown"}`);
46
+ }
47
+ }
48
+ export async function pollWechatClawMessages(options) {
49
+ const payload = ensurePlainObject(await fetchJson(`${normalizeWechatClawBaseUrl(options.baseUrl)}/ilink/bot/getupdates`, {
50
+ method: "POST",
51
+ headers: buildWechatClawHeaders(options.botToken),
52
+ body: JSON.stringify({
53
+ base_info: {
54
+ channel_version: "2.0.0"
55
+ },
56
+ get_updates_buf: options.cursor ?? "",
57
+ timeout: Math.max(options.timeoutMs ?? 0, 0),
58
+ max_items: 50
59
+ })
60
+ }), "wechat claw getupdates response");
61
+ const errorCode = readBodyInteger(payload, "errcode");
62
+ if (errorCode === -14) {
63
+ throw platformLoginExpired("个人微信(claw)登录已失效,请重新扫码绑定");
64
+ }
65
+ if (typeof errorCode === "number" && errorCode !== 0) {
66
+ throw platformRequestFailed(`微信 claw 拉取消息失败:${readBodyText(payload, "errmsg") ?? `errcode=${errorCode}`}`);
67
+ }
68
+ const cursor = readBodyText(payload, "get_updates_buf")
69
+ ?? readBodyText(payload, "next_cursor")
70
+ ?? readBodyText(payload, "sync_buf");
71
+ const items = Array.isArray(payload.msgs)
72
+ ? payload.msgs
73
+ : Array.isArray(payload.messages)
74
+ ? payload.messages
75
+ : Array.isArray(payload.msg_list)
76
+ ? payload.msg_list
77
+ : [];
78
+ return {
79
+ nextCursor: cursor,
80
+ longPollingTimeoutMs: readBodyInteger(payload, "longpolling_timeout_ms"),
81
+ messages: items
82
+ .map((item) => parseWechatClawInboundMessage(item))
83
+ .filter((item) => item !== null)
84
+ };
85
+ }
86
+ export async function sendWechatClawText(options) {
87
+ const payload = ensurePlainObject(await fetchJson(`${normalizeWechatClawBaseUrl(options.baseUrl)}/ilink/bot/sendmessage`, {
88
+ method: "POST",
89
+ headers: buildWechatClawHeaders(options.botToken),
90
+ body: JSON.stringify({
91
+ to_user_id: options.toUserId,
92
+ context_token: options.contextToken,
93
+ item_list: [
94
+ {
95
+ type: "text",
96
+ text_item: {
97
+ text: options.text
98
+ }
99
+ }
100
+ ]
101
+ })
102
+ }), "wechat claw sendmessage response");
103
+ return {
104
+ messageRef: readBodyText(payload, "message_id") ?? readBodyText(payload, "msg_id")
105
+ };
106
+ }
107
+ export function normalizeWechatClawBaseUrl(value) {
108
+ const normalized = value?.trim();
109
+ return normalized && normalized.length > 0 ? normalized : WECHAT_CLAW_FIXED_BASE_URL;
110
+ }
111
+ function createWechatClawPollLoginResult(status) {
112
+ return {
113
+ status,
114
+ botToken: null,
115
+ baseUrl: null,
116
+ remoteBotId: null,
117
+ boundUserId: null,
118
+ redirectHost: null
119
+ };
120
+ }
121
+ function buildWechatClawHeaders(botToken) {
122
+ return {
123
+ authorization: `Bearer ${botToken}`,
124
+ authorizationtype: "ilink_bot_token",
125
+ "content-type": "application/json",
126
+ "ilink-app-id": WECHAT_CLAW_APP_ID,
127
+ "ilink-app-clientversion": WECHAT_CLAW_APP_CLIENT_VERSION,
128
+ "x-wechat-uin": Buffer.from(String(randomInt(1, 0xffffffff))).toString("base64")
129
+ };
130
+ }
131
+ function parseWechatClawInboundMessage(value) {
132
+ const payload = ensurePlainObject(value, "wechat claw message");
133
+ const text = extractWechatClawText(payload);
134
+ const fromUserId = readBodyText(payload, "from_user_id");
135
+ if (!text || !fromUserId) {
136
+ return null;
137
+ }
138
+ return {
139
+ messageId: readBodyText(payload, "message_id")
140
+ ?? readBodyText(payload, "msg_id")
141
+ ?? `wechat-claw:${Date.now()}:${Math.random().toString(16).slice(2, 10)}`,
142
+ fromUserId,
143
+ toUserId: readBodyText(payload, "to_user_id"),
144
+ text,
145
+ timestamp: readBodyText(payload, "timestamp"),
146
+ contextToken: readBodyText(payload, "context_token"),
147
+ rawPayload: payload
148
+ };
149
+ }
150
+ function extractWechatClawText(payload) {
151
+ const itemList = payload.item_list;
152
+ if (!Array.isArray(itemList)) {
153
+ return null;
154
+ }
155
+ for (const item of itemList) {
156
+ if (!item || typeof item !== "object" || Array.isArray(item)) {
157
+ continue;
158
+ }
159
+ const entry = item;
160
+ if (readBodyText(entry, "type") !== "text") {
161
+ continue;
162
+ }
163
+ const textItem = ensurePlainObject(entry.text_item ?? {}, "wechat claw text_item");
164
+ const text = readBodyText(textItem, "text");
165
+ if (text) {
166
+ return text;
167
+ }
168
+ }
169
+ return null;
170
+ }
171
+ async function fetchWechatClawJson(url) {
172
+ return ensurePlainObject(await fetchJson(url), "wechat claw response");
173
+ }
174
+ async function fetchJson(url, init) {
175
+ const response = await fetch(url, init);
176
+ const text = await response.text();
177
+ const payload = text ? safeJsonParse(text) : null;
178
+ if (!response.ok) {
179
+ throw new AppError({
180
+ statusCode: 502,
181
+ errorCode: "CHANNEL_PLATFORM_REQUEST_FAILED",
182
+ detail: `请求 ${url} 失败:${response.status} ${response.statusText}`
183
+ });
184
+ }
185
+ return payload;
186
+ }
187
+ function safeJsonParse(text) {
188
+ try {
189
+ return JSON.parse(text);
190
+ }
191
+ catch {
192
+ return {
193
+ raw: text
194
+ };
195
+ }
196
+ }
197
+ function ensurePlainObject(value, field) {
198
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
199
+ throw platformRequestFailed(`${field} 必须是对象`);
200
+ }
201
+ return value;
202
+ }
203
+ function readBodyText(source, key) {
204
+ if (!source || typeof source !== "object" || Array.isArray(source)) {
205
+ return null;
206
+ }
207
+ const value = source[key];
208
+ if (typeof value === "string") {
209
+ const normalized = value.trim();
210
+ return normalized.length > 0 ? normalized : null;
211
+ }
212
+ if (typeof value === "number" && Number.isFinite(value)) {
213
+ return String(value);
214
+ }
215
+ return null;
216
+ }
217
+ function readBodyInteger(source, key) {
218
+ if (!source || typeof source !== "object" || Array.isArray(source)) {
219
+ return null;
220
+ }
221
+ const value = source[key];
222
+ if (typeof value === "number" && Number.isFinite(value)) {
223
+ return Math.trunc(value);
224
+ }
225
+ if (typeof value === "string") {
226
+ const parsed = Number.parseInt(value.trim(), 10);
227
+ return Number.isFinite(parsed) ? parsed : null;
228
+ }
229
+ return null;
230
+ }
231
+ function platformRequestFailed(detail) {
232
+ return new AppError({
233
+ statusCode: 502,
234
+ errorCode: "CHANNEL_PLATFORM_REQUEST_FAILED",
235
+ detail
236
+ });
237
+ }
238
+ function platformLoginExpired(detail) {
239
+ return new AppError({
240
+ statusCode: 401,
241
+ errorCode: "CHANNEL_PLATFORM_LOGIN_EXPIRED",
242
+ detail
243
+ });
244
+ }
245
+ //# sourceMappingURL=wechat-claw-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wechat-claw-client.js","sourceRoot":"","sources":["../../../../src/modules/channels/wechat-claw-client.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jingyi0605/codingns",
3
- "version": "0.7.3",
3
+ "version": "0.7.4",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "codingns": "./bin/codingns.mjs"
@@ -94,29 +94,13 @@ async function verifyCodexRuntime() {
94
94
  return false;
95
95
  }
96
96
 
97
- const versionCheck = spawnSync(process.execPath, [codexBinPath, "--version"], {
98
- cwd: packageRoot,
99
- env: process.env,
100
- encoding: "utf8",
101
- timeout: 30_000
102
- });
103
-
104
- if (versionCheck.error) {
105
- console.error(`[codingns] Codex CLI 启动失败:${versionCheck.error.message}`);
97
+ if (!isExecutableFile(nativeCodexBinaryPath)) {
98
+ console.error(`[codingns] Codex CLI 平台二进制不可执行:${nativeCodexBinaryPath}`);
106
99
  return false;
107
100
  }
108
101
 
109
- if (versionCheck.status !== 0) {
110
- console.error(
111
- `[codingns] Codex CLI 校验失败:${formatSpawnFailure(versionCheck)}`
112
- );
113
- return false;
114
- }
115
-
116
- const versionText = versionCheck.stdout?.trim() || "unknown";
117
102
  logInfo(`[codingns] Codex CLI 入口已就绪:${codexBinPath}`);
118
103
  logInfo(`[codingns] Codex CLI 平台运行文件已就绪:${nativeCodexBinaryPath}`);
119
- logInfo(`[codingns] Codex CLI 版本:${versionText}`);
120
104
  return true;
121
105
  } catch (error) {
122
106
  const detail = error instanceof Error ? error.message : String(error);
@@ -251,17 +235,6 @@ function resolveCodexNativeBinaryPath(codexBinPath) {
251
235
  return fs.existsSync(platformBinaryPath) ? platformBinaryPath : null;
252
236
  }
253
237
 
254
- function formatSpawnFailure(result) {
255
- const parts = [
256
- result.stderr?.trim(),
257
- result.stdout?.trim(),
258
- result.signal ? `signal=${result.signal}` : null,
259
- typeof result.status === "number" ? `exitCode=${result.status}` : null
260
- ].filter(Boolean);
261
-
262
- return parts.join("\n") || "unknown error";
263
- }
264
-
265
238
  function resolveCodexPlatformPackageName() {
266
239
  switch (`${process.platform}/${process.arch}`) {
267
240
  case "linux/x64":
@@ -281,6 +254,15 @@ function resolveCodexPlatformPackageName() {
281
254
  }
282
255
  }
283
256
 
257
+ function isExecutableFile(filePath) {
258
+ try {
259
+ fs.accessSync(filePath, process.platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
260
+ return true;
261
+ } catch {
262
+ return false;
263
+ }
264
+ }
265
+
284
266
  function resolveCodexTargetTriple() {
285
267
  switch (`${process.platform}/${process.arch}`) {
286
268
  case "linux/x64":