@nanhara/hara 0.130.1 → 0.130.2
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/CHANGELOG.md +9 -0
- package/dist/gateway/weixin.js +26 -1
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,15 @@ All notable changes to `@nanhara/hara`.
|
|
|
5
5
|
> Versioning (pre-1.0, SemVer-style): the **minor** (middle) number bumps for a **new feature**; the
|
|
6
6
|
> **patch** (last) number bumps for **optimizations/fixes of existing features**.
|
|
7
7
|
|
|
8
|
+
## 0.130.2 — 2026-07-21 — Weixin delivery identity
|
|
9
|
+
|
|
10
|
+
- Personal WeChat iLink messages now pass valid `message_id` and `create_time_ms` metadata into Hara's
|
|
11
|
+
cross-restart stale-event, deduplication, and no-rerun boundary.
|
|
12
|
+
- Missing or invalid metadata remains genuinely optional: the adapter omits `messageId` and `createdAtMs`
|
|
13
|
+
instead of adding own properties whose value is `undefined`.
|
|
14
|
+
- The Feishu SDK's transitive `protobufjs` parser is pinned to the patched 7.6.5 release.
|
|
15
|
+
- Upgrade with `npm i -g @nanhara/hara@0.130.2`.
|
|
16
|
+
|
|
8
17
|
## 0.130.1 — 2026-07-21 — Windows private-state portability
|
|
9
18
|
|
|
10
19
|
- `hara serve` no longer calls the inapplicable POSIX `fchmod` operation on Windows discovery
|
package/dist/gateway/weixin.js
CHANGED
|
@@ -45,6 +45,19 @@ const WEIXIN_CDN_ALLOWLIST = new Set([
|
|
|
45
45
|
const IMAGE_EXTS = new Set(["jpg", "jpeg", "png", "gif", "webp", "bmp"]);
|
|
46
46
|
const num = (v) => (typeof v === "number" ? v : 0);
|
|
47
47
|
const str = (v) => (v == null ? "" : String(v));
|
|
48
|
+
function stableWeixinMessageId(value) {
|
|
49
|
+
if (typeof value === "string")
|
|
50
|
+
return value.trim() || undefined;
|
|
51
|
+
if (Number.isSafeInteger(value))
|
|
52
|
+
return String(value);
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
function weixinCreatedAtMs(value) {
|
|
56
|
+
const parsed = Number(value);
|
|
57
|
+
if (!Number.isFinite(parsed) || parsed <= 0)
|
|
58
|
+
return undefined;
|
|
59
|
+
return Math.trunc(parsed);
|
|
60
|
+
}
|
|
48
61
|
// ── pure protocol helpers (unit-tested) ──────────────────────────────────────
|
|
49
62
|
/** X-WECHAT-UIN: base64 of the decimal string of a random uint32 (regenerated per request). */
|
|
50
63
|
export function randomWechatUin() {
|
|
@@ -145,7 +158,19 @@ export function parseWeixinMessage(msg, accountId) {
|
|
|
145
158
|
// This tells it the text is already transcribed so it just answers.
|
|
146
159
|
const isVoice = !items.some((i) => i?.type === ITEM_TEXT) && items.some((i) => i?.type === 3);
|
|
147
160
|
const tagged = isVoice ? `(The user sent this as a voice message; it is already transcribed to text below — just reply to it normally, you don't have or need the audio.)\n\n${text}` : text;
|
|
148
|
-
|
|
161
|
+
const messageId = stableWeixinMessageId(msg?.message_id);
|
|
162
|
+
const createdAtMs = weixinCreatedAtMs(msg?.create_time_ms);
|
|
163
|
+
return {
|
|
164
|
+
inbound: {
|
|
165
|
+
chatId: from,
|
|
166
|
+
userId: from,
|
|
167
|
+
userName: from,
|
|
168
|
+
text: tagged,
|
|
169
|
+
...(messageId ? { messageId } : {}),
|
|
170
|
+
...(createdAtMs === undefined ? {} : { createdAtMs }),
|
|
171
|
+
},
|
|
172
|
+
contextToken: str(msg?.context_token).trim(),
|
|
173
|
+
};
|
|
149
174
|
}
|
|
150
175
|
/** iLink signals expiry via -14, or -2 + errmsg "unknown error" (a stale-session masquerading as rate-limit). */
|
|
151
176
|
export function isSessionExpired(ret, errcode, errmsg) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nanhara/hara",
|
|
3
|
-
"version": "0.130.
|
|
3
|
+
"version": "0.130.2",
|
|
4
4
|
"description": "hara — a coding agent CLI that runs like an engineering org.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"hara": "runtime-bootstrap.cjs"
|
|
@@ -75,7 +75,8 @@
|
|
|
75
75
|
},
|
|
76
76
|
"overrides": {
|
|
77
77
|
"@larksuiteoapi/node-sdk": {
|
|
78
|
-
"axios": "1.18.1"
|
|
78
|
+
"axios": "1.18.1",
|
|
79
|
+
"protobufjs": "7.6.5"
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
82
|
}
|