agent-shell-chat 1.2.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.
Files changed (88) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +199 -0
  3. package/dist/bin/agent-shell.d.ts +15 -0
  4. package/dist/bin/agent-shell.d.ts.map +1 -0
  5. package/dist/bin/agent-shell.js +816 -0
  6. package/dist/bin/agent-shell.js.map +1 -0
  7. package/dist/package.json +54 -0
  8. package/dist/src/acp/agent-manager.d.ts +22 -0
  9. package/dist/src/acp/agent-manager.d.ts.map +1 -0
  10. package/dist/src/acp/agent-manager.js +79 -0
  11. package/dist/src/acp/agent-manager.js.map +1 -0
  12. package/dist/src/acp/client.d.ts +64 -0
  13. package/dist/src/acp/client.d.ts.map +1 -0
  14. package/dist/src/acp/client.js +265 -0
  15. package/dist/src/acp/client.js.map +1 -0
  16. package/dist/src/acp/session.d.ts +81 -0
  17. package/dist/src/acp/session.d.ts.map +1 -0
  18. package/dist/src/acp/session.js +339 -0
  19. package/dist/src/acp/session.js.map +1 -0
  20. package/dist/src/adapter/inbound.d.ts +39 -0
  21. package/dist/src/adapter/inbound.d.ts.map +1 -0
  22. package/dist/src/adapter/inbound.js +264 -0
  23. package/dist/src/adapter/inbound.js.map +1 -0
  24. package/dist/src/bridge.d.ts +115 -0
  25. package/dist/src/bridge.d.ts.map +1 -0
  26. package/dist/src/bridge.js +969 -0
  27. package/dist/src/bridge.js.map +1 -0
  28. package/dist/src/config.d.ts +155 -0
  29. package/dist/src/config.d.ts.map +1 -0
  30. package/dist/src/config.js +265 -0
  31. package/dist/src/config.js.map +1 -0
  32. package/dist/src/index.d.ts +9 -0
  33. package/dist/src/index.d.ts.map +1 -0
  34. package/dist/src/index.js +7 -0
  35. package/dist/src/index.js.map +1 -0
  36. package/dist/src/inject/monitor.d.ts +24 -0
  37. package/dist/src/inject/monitor.d.ts.map +1 -0
  38. package/dist/src/inject/monitor.js +149 -0
  39. package/dist/src/inject/monitor.js.map +1 -0
  40. package/dist/src/inject/queue.d.ts +13 -0
  41. package/dist/src/inject/queue.d.ts.map +1 -0
  42. package/dist/src/inject/queue.js +35 -0
  43. package/dist/src/inject/queue.js.map +1 -0
  44. package/dist/src/inject/types.d.ts +10 -0
  45. package/dist/src/inject/types.d.ts.map +1 -0
  46. package/dist/src/inject/types.js +2 -0
  47. package/dist/src/inject/types.js.map +1 -0
  48. package/dist/src/storage/accounts.d.ts +43 -0
  49. package/dist/src/storage/accounts.d.ts.map +1 -0
  50. package/dist/src/storage/accounts.js +289 -0
  51. package/dist/src/storage/accounts.js.map +1 -0
  52. package/dist/src/storage/runtime.d.ts +23 -0
  53. package/dist/src/storage/runtime.d.ts.map +1 -0
  54. package/dist/src/storage/runtime.js +104 -0
  55. package/dist/src/storage/runtime.js.map +1 -0
  56. package/dist/src/storage/state.d.ts +17 -0
  57. package/dist/src/storage/state.d.ts.map +1 -0
  58. package/dist/src/storage/state.js +78 -0
  59. package/dist/src/storage/state.js.map +1 -0
  60. package/dist/src/telemetry/index.d.ts +33 -0
  61. package/dist/src/telemetry/index.d.ts.map +1 -0
  62. package/dist/src/telemetry/index.js +167 -0
  63. package/dist/src/telemetry/index.js.map +1 -0
  64. package/dist/src/weixin/api.d.ts +50 -0
  65. package/dist/src/weixin/api.d.ts.map +1 -0
  66. package/dist/src/weixin/api.js +90 -0
  67. package/dist/src/weixin/api.js.map +1 -0
  68. package/dist/src/weixin/auth.d.ts +26 -0
  69. package/dist/src/weixin/auth.d.ts.map +1 -0
  70. package/dist/src/weixin/auth.js +103 -0
  71. package/dist/src/weixin/auth.js.map +1 -0
  72. package/dist/src/weixin/media.d.ts +24 -0
  73. package/dist/src/weixin/media.d.ts.map +1 -0
  74. package/dist/src/weixin/media.js +64 -0
  75. package/dist/src/weixin/media.js.map +1 -0
  76. package/dist/src/weixin/monitor.d.ts +16 -0
  77. package/dist/src/weixin/monitor.d.ts.map +1 -0
  78. package/dist/src/weixin/monitor.js +113 -0
  79. package/dist/src/weixin/monitor.js.map +1 -0
  80. package/dist/src/weixin/send.d.ts +28 -0
  81. package/dist/src/weixin/send.d.ts.map +1 -0
  82. package/dist/src/weixin/send.js +162 -0
  83. package/dist/src/weixin/send.js.map +1 -0
  84. package/dist/src/weixin/types.d.ts +149 -0
  85. package/dist/src/weixin/types.d.ts.map +1 -0
  86. package/dist/src/weixin/types.js +33 -0
  87. package/dist/src/weixin/types.js.map +1 -0
  88. package/package.json +54 -0
@@ -0,0 +1,104 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ export function getPidPath(storageDir) {
4
+ return path.join(storageDir, "daemon.pid");
5
+ }
6
+ export function getRuntimePath(storageDir) {
7
+ return path.join(storageDir, "runtime.json");
8
+ }
9
+ export function inspectRuntime(storageDir, cleanupStale = false) {
10
+ const pidPath = getPidPath(storageDir);
11
+ const runtimePath = getRuntimePath(storageDir);
12
+ if (!fs.existsSync(pidPath)) {
13
+ return { running: false, stale: false };
14
+ }
15
+ const pid = Number.parseInt(fs.readFileSync(pidPath, "utf-8").trim(), 10);
16
+ if (!Number.isSafeInteger(pid) || pid <= 0 || !isProcessRunning(pid)) {
17
+ if (cleanupStale) {
18
+ fs.rmSync(pidPath, { force: true });
19
+ fs.rmSync(runtimePath, { force: true });
20
+ }
21
+ return {
22
+ running: false,
23
+ ...(Number.isSafeInteger(pid) && pid > 0 ? { pid } : {}),
24
+ stale: true,
25
+ };
26
+ }
27
+ let runtime;
28
+ try {
29
+ const parsed = JSON.parse(fs.readFileSync(runtimePath, "utf-8"));
30
+ if (parsed.pid === pid) {
31
+ runtime = parsed;
32
+ }
33
+ }
34
+ catch {
35
+ // A legacy daemon may only have daemon.pid.
36
+ }
37
+ return { running: true, pid, runtime, stale: false };
38
+ }
39
+ export function claimRuntime(storageDir, runtime) {
40
+ fs.mkdirSync(storageDir, { recursive: true, mode: 0o700 });
41
+ const existing = inspectRuntime(storageDir, true);
42
+ if (existing.running) {
43
+ throw new Error(`Account ${runtime.accountName}-${runtime.accountId} is already running (PID ${existing.pid}).`);
44
+ }
45
+ const pidPath = getPidPath(storageDir);
46
+ let fd;
47
+ try {
48
+ fd = fs.openSync(pidPath, "wx", 0o600);
49
+ fs.writeFileSync(fd, String(runtime.pid), "utf-8");
50
+ }
51
+ catch (err) {
52
+ if (err.code === "EEXIST") {
53
+ throw new Error(`Account ${runtime.accountName}-${runtime.accountId} is already being started.`);
54
+ }
55
+ throw err;
56
+ }
57
+ finally {
58
+ if (fd !== undefined)
59
+ fs.closeSync(fd);
60
+ }
61
+ try {
62
+ writeRuntime(storageDir, runtime);
63
+ }
64
+ catch (err) {
65
+ fs.rmSync(pidPath, { force: true });
66
+ throw err;
67
+ }
68
+ }
69
+ export function releaseRuntime(storageDir, pid) {
70
+ const status = inspectRuntime(storageDir);
71
+ if (status.pid !== pid)
72
+ return;
73
+ fs.rmSync(getPidPath(storageDir), { force: true });
74
+ fs.rmSync(getRuntimePath(storageDir), { force: true });
75
+ }
76
+ export function isProcessRunning(pid) {
77
+ try {
78
+ process.kill(pid, 0);
79
+ return true;
80
+ }
81
+ catch {
82
+ return false;
83
+ }
84
+ }
85
+ function writeRuntime(storageDir, runtime) {
86
+ const runtimePath = getRuntimePath(storageDir);
87
+ const tmpPath = path.join(storageDir, `.runtime-${process.pid}-${Date.now()}.tmp`);
88
+ fs.writeFileSync(tmpPath, JSON.stringify(runtime, null, 2) + "\n", {
89
+ encoding: "utf-8",
90
+ mode: 0o600,
91
+ });
92
+ try {
93
+ fs.renameSync(tmpPath, runtimePath);
94
+ }
95
+ catch (err) {
96
+ const code = err.code;
97
+ if (process.platform !== "win32" || (code !== "EEXIST" && code !== "EPERM")) {
98
+ throw err;
99
+ }
100
+ fs.rmSync(runtimePath, { force: true });
101
+ fs.renameSync(tmpPath, runtimePath);
102
+ }
103
+ }
104
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/storage/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export interface UserState {
2
+ contextToken: string;
3
+ lastSeenAt: string;
4
+ }
5
+ export interface BridgeState {
6
+ lastActiveUserId?: string;
7
+ users?: Record<string, UserState>;
8
+ }
9
+ export interface ResolvedUserTarget {
10
+ userId: string;
11
+ contextToken: string;
12
+ }
13
+ export declare function loadState(stateFile: string): Promise<BridgeState>;
14
+ export declare function saveState(stateFile: string, state: BridgeState): Promise<void>;
15
+ export declare function updateLastActiveUser(stateFile: string, userId: string, contextToken: string): Promise<void>;
16
+ export declare function resolveUserTarget(stateFile: string, target: string | undefined, contextToken?: string): Promise<ResolvedUserTarget>;
17
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/storage/state.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAQvE;AAED,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAUpF;AAED,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,kBAAkB,CAAC,CAiB7B"}
@@ -0,0 +1,78 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ const STATE_DIR_MODE = 0o700;
4
+ const STATE_FILE_MODE = 0o600;
5
+ const MAX_STORED_USERS = 100;
6
+ export async function loadState(stateFile) {
7
+ try {
8
+ const content = await fs.readFile(stateFile, "utf-8");
9
+ return JSON.parse(content);
10
+ }
11
+ catch (err) {
12
+ if (err.code === "ENOENT")
13
+ return {};
14
+ throw err;
15
+ }
16
+ }
17
+ export async function saveState(stateFile, state) {
18
+ await fs.mkdir(path.dirname(stateFile), { recursive: true, mode: STATE_DIR_MODE });
19
+ await fs.chmod(path.dirname(stateFile), STATE_DIR_MODE).catch(() => { });
20
+ const tmp = path.join(path.dirname(stateFile), `.state-${process.pid}-${Date.now()}.tmp`);
21
+ await fs.writeFile(tmp, JSON.stringify(state, null, 2) + "\n", {
22
+ encoding: "utf-8",
23
+ mode: STATE_FILE_MODE,
24
+ });
25
+ await fs.chmod(tmp, STATE_FILE_MODE).catch(() => { });
26
+ await replaceFile(tmp, stateFile);
27
+ }
28
+ export async function updateLastActiveUser(stateFile, userId, contextToken) {
29
+ const state = await loadState(stateFile);
30
+ state.lastActiveUserId = userId;
31
+ state.users = {
32
+ ...(state.users ?? {}),
33
+ [userId]: {
34
+ contextToken,
35
+ lastSeenAt: new Date().toISOString(),
36
+ },
37
+ };
38
+ state.users = pruneUsers(state.users);
39
+ await saveState(stateFile, state);
40
+ }
41
+ export async function resolveUserTarget(stateFile, target, contextToken) {
42
+ const state = await loadState(stateFile);
43
+ const userId = !target || target === "last-active-user" ? state.lastActiveUserId : target;
44
+ if (!userId) {
45
+ throw new Error("No last active user found. Send any message to this WeChat bot once, then retry.");
46
+ }
47
+ const stored = state.users?.[userId];
48
+ const resolvedContextToken = contextToken ?? stored?.contextToken;
49
+ if (!resolvedContextToken) {
50
+ throw new Error(`No context token found for target user ${userId}. Ask the user to send a new message first.`);
51
+ }
52
+ return {
53
+ userId,
54
+ contextToken: resolvedContextToken,
55
+ };
56
+ }
57
+ async function replaceFile(tmp, target) {
58
+ try {
59
+ await fs.rename(tmp, target);
60
+ }
61
+ catch (err) {
62
+ const code = err.code;
63
+ if (process.platform !== "win32" || (code !== "EEXIST" && code !== "EPERM")) {
64
+ throw err;
65
+ }
66
+ await fs.rm(target, { force: true });
67
+ await fs.rename(tmp, target);
68
+ }
69
+ }
70
+ function pruneUsers(users) {
71
+ const entries = Object.entries(users);
72
+ if (entries.length <= MAX_STORED_USERS)
73
+ return users;
74
+ return Object.fromEntries(entries
75
+ .sort(([, left], [, right]) => right.lastSeenAt.localeCompare(left.lastSeenAt))
76
+ .slice(0, MAX_STORED_USERS));
77
+ }
78
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/storage/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Anonymous usage telemetry via Azure Application Insights.
3
+ *
4
+ * Privacy:
5
+ * - No message content, filenames, transcripts, URLs, tokens, or paths are collected.
6
+ * - WeChat user IDs are sha256-hashed with a per-install salt and truncated.
7
+ * - Only the categorical events declared in `EventName` are emitted.
8
+ *
9
+ * Disable: set environment variable `AGENT_SHELL_TELEMETRY=0` (or `false` / `off`).
10
+ */
11
+ export type EventName = "app.start" | "app.stop" | "login.success" | "login.failure" | "token.reused" | "message.received" | "message.injected" | "command.acp_config.view" | "command.acp_config.set" | "command.acp_cancel" | "command.buffer_start" | "command.buffer_done" | "session.created" | "prompt.completed" | "reply.sent";
12
+ type PropValue = string | number | boolean;
13
+ /**
14
+ * Initialize telemetry. Safe to call once at startup.
15
+ * Becomes a no-op (sync) when telemetry is disabled or initialization fails.
16
+ */
17
+ export declare function initTelemetry(opts: {
18
+ version: string;
19
+ storageDir: string;
20
+ agentPreset?: string;
21
+ daemon?: boolean;
22
+ }): void;
23
+ export declare function trackEvent(name: EventName, props?: Record<string, PropValue>, sessionId?: string): void;
24
+ export declare function trackException(err: unknown, area: string, sessionId?: string): void;
25
+ /**
26
+ * Hash a WeChat user id with the install salt so it's stable per-install
27
+ * but cannot be linked across installs and cannot be reversed to the raw id.
28
+ */
29
+ export declare function hashUserId(userId: string): string;
30
+ /** Flush pending telemetry, with at most ~2s wait. */
31
+ export declare function shutdownTelemetry(): Promise<void>;
32
+ export {};
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/telemetry/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAcH,MAAM,MAAM,SAAS,GACjB,WAAW,GACX,UAAU,GACV,eAAe,GACf,eAAe,GACf,cAAc,GACd,kBAAkB,GAClB,kBAAkB,GAClB,yBAAyB,GACzB,wBAAwB,GACxB,oBAAoB,GACpB,sBAAsB,GACtB,qBAAqB,GACrB,iBAAiB,GACjB,kBAAkB,GAClB,YAAY,CAAC;AAEjB,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AA4C3C;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GAAG,IAAI,CA2DP;AAcD,wBAAgB,UAAU,CACxB,IAAI,EAAE,SAAS,EACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACjC,SAAS,CAAC,EAAE,MAAM,GACjB,IAAI,CAaN;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAYnF;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAIjD;AAED,sDAAsD;AACtD,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAiBvD"}
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Anonymous usage telemetry via Azure Application Insights.
3
+ *
4
+ * Privacy:
5
+ * - No message content, filenames, transcripts, URLs, tokens, or paths are collected.
6
+ * - WeChat user IDs are sha256-hashed with a per-install salt and truncated.
7
+ * - Only the categorical events declared in `EventName` are emitted.
8
+ *
9
+ * Disable: set environment variable `AGENT_SHELL_TELEMETRY=0` (or `false` / `off`).
10
+ */
11
+ import fs from "node:fs";
12
+ import path from "node:path";
13
+ import crypto from "node:crypto";
14
+ import { createRequire } from "node:module";
15
+ const require = createRequire(import.meta.url);
16
+ // Hard-coded connection string. Replace with the project's Application Insights
17
+ // resource connection string before shipping.
18
+ const CONNECTION_STRING = "InstrumentationKey=94c435ed-3c7a-4428-862e-b8648d9fb199;IngestionEndpoint=https://eastus-8.in.applicationinsights.azure.com/;LiveEndpoint=https://eastus.livediagnostics.monitor.azure.com/;ApplicationId=02dd3391-f729-4208-90e7-28edf7f50d1e";
19
+ let client = null;
20
+ let installId = "";
21
+ let disabled = false;
22
+ function isDisabledByEnv() {
23
+ const v = (process.env.AGENT_SHELL_TELEMETRY ?? "").trim().toLowerCase();
24
+ return v === "0" || v === "false" || v === "off";
25
+ }
26
+ function loadOrCreateInstallId(storageDir) {
27
+ const idFile = path.join(storageDir, "telemetry-id");
28
+ try {
29
+ if (fs.existsSync(idFile)) {
30
+ const existing = fs.readFileSync(idFile, "utf-8").trim();
31
+ if (existing)
32
+ return existing;
33
+ }
34
+ const id = crypto.randomUUID();
35
+ fs.mkdirSync(storageDir, { recursive: true });
36
+ fs.writeFileSync(idFile, id, "utf-8");
37
+ return id;
38
+ }
39
+ catch {
40
+ // Storage not writable — fall back to ephemeral per-process id.
41
+ return crypto.randomUUID();
42
+ }
43
+ }
44
+ /**
45
+ * Initialize telemetry. Safe to call once at startup.
46
+ * Becomes a no-op (sync) when telemetry is disabled or initialization fails.
47
+ */
48
+ export function initTelemetry(opts) {
49
+ if (isDisabledByEnv()) {
50
+ disabled = true;
51
+ return;
52
+ }
53
+ try {
54
+ installId = loadOrCreateInstallId(opts.storageDir);
55
+ // Lazy-load the SDK so disabled installs don't pay any cost.
56
+ // Cast through `unknown` so the type stays opaque even if the package
57
+ // isn't yet installed at type-check time.
58
+ const appInsights = require("applicationinsights");
59
+ appInsights
60
+ .setup(CONNECTION_STRING)
61
+ .setAutoCollectRequests(false)
62
+ .setAutoCollectPerformance(false)
63
+ .setAutoCollectExceptions(false)
64
+ .setAutoCollectDependencies(false)
65
+ .setAutoCollectConsole(false)
66
+ .setSendLiveMetrics(false)
67
+ .setInternalLogging(false, false)
68
+ .start();
69
+ const c = appInsights.defaultClient;
70
+ // Static envelope tags. These attach to every outgoing event automatically
71
+ // — no need to repeat them per-event.
72
+ c.context.tags[c.context.keys.cloudRole] = "agent-shell";
73
+ c.context.tags[c.context.keys.userId] = installId;
74
+ c.context.tags["ai.application.ver"] = opts.version;
75
+ // commonProperties is auto-merged into every event's customDimensions.
76
+ c.commonProperties = {
77
+ version: opts.version,
78
+ node: process.version,
79
+ os: process.platform,
80
+ arch: process.arch,
81
+ installId,
82
+ ...(opts.agentPreset ? { agentPreset: opts.agentPreset } : {}),
83
+ ...(opts.daemon !== undefined ? { daemon: String(opts.daemon) } : {}),
84
+ };
85
+ client = c;
86
+ }
87
+ catch {
88
+ // Telemetry must never break the app.
89
+ client = null;
90
+ disabled = true;
91
+ }
92
+ }
93
+ /**
94
+ * Build per-event tagOverrides. Only the session id varies per call; cloud
95
+ * role, user id, and application version are pinned once on `context.tags`
96
+ * at init time.
97
+ */
98
+ function buildTagOverrides(sessionId) {
99
+ // Fall back to installId so app-lifecycle events (no per-user context) still
100
+ // have a stable, non-null session id rather than collapsing into one global
101
+ // bucket across all installs.
102
+ return { "ai.session.id": sessionId && sessionId.length > 0 ? sessionId : installId };
103
+ }
104
+ export function trackEvent(name, props, sessionId) {
105
+ if (disabled || !client)
106
+ return;
107
+ try {
108
+ const properties = {};
109
+ if (props) {
110
+ for (const [k, v] of Object.entries(props)) {
111
+ properties[k] = typeof v === "string" ? v : String(v);
112
+ }
113
+ }
114
+ client.trackEvent({ name, properties, tagOverrides: buildTagOverrides(sessionId) });
115
+ }
116
+ catch {
117
+ // ignore
118
+ }
119
+ }
120
+ export function trackException(err, area, sessionId) {
121
+ if (disabled || !client)
122
+ return;
123
+ try {
124
+ const exception = err instanceof Error ? err : new Error(String(err));
125
+ client.trackException({
126
+ exception,
127
+ properties: { area },
128
+ tagOverrides: buildTagOverrides(sessionId),
129
+ });
130
+ }
131
+ catch {
132
+ // ignore
133
+ }
134
+ }
135
+ /**
136
+ * Hash a WeChat user id with the install salt so it's stable per-install
137
+ * but cannot be linked across installs and cannot be reversed to the raw id.
138
+ */
139
+ export function hashUserId(userId) {
140
+ if (!userId)
141
+ return "";
142
+ const salt = installId || "agent-shell";
143
+ return crypto.createHash("sha256").update(salt).update(userId).digest("hex").slice(0, 16);
144
+ }
145
+ /** Flush pending telemetry, with at most ~2s wait. */
146
+ export async function shutdownTelemetry() {
147
+ if (disabled || !client)
148
+ return;
149
+ await new Promise((resolve) => {
150
+ let settled = false;
151
+ const done = () => {
152
+ if (settled)
153
+ return;
154
+ settled = true;
155
+ resolve();
156
+ };
157
+ try {
158
+ client.flush({ callback: () => done() });
159
+ }
160
+ catch {
161
+ done();
162
+ return;
163
+ }
164
+ setTimeout(done, 2_000).unref();
165
+ });
166
+ }
167
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/telemetry/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * WeChat iLink HTTP API client.
3
+ * Adapted from @tencent-weixin/openclaw-weixin api/api.ts
4
+ */
5
+ import type { GetUpdatesResp, SendMessageReq, GetUploadUrlReq, GetUploadUrlResp, SendTypingReq, GetConfigResp } from "./types.js";
6
+ export declare function getUpdates(params: {
7
+ baseUrl: string;
8
+ token?: string;
9
+ get_updates_buf: string;
10
+ timeoutMs?: number;
11
+ }): Promise<GetUpdatesResp>;
12
+ export declare function sendMessage(params: {
13
+ baseUrl: string;
14
+ token?: string;
15
+ body: SendMessageReq;
16
+ }): Promise<void>;
17
+ export declare function getUploadUrl(params: {
18
+ baseUrl: string;
19
+ token?: string;
20
+ body: GetUploadUrlReq;
21
+ }): Promise<GetUploadUrlResp>;
22
+ export declare function getConfig(params: {
23
+ baseUrl: string;
24
+ token?: string;
25
+ ilinkUserId: string;
26
+ contextToken?: string;
27
+ }): Promise<GetConfigResp>;
28
+ export declare function sendTyping(params: {
29
+ baseUrl: string;
30
+ token?: string;
31
+ body: SendTypingReq;
32
+ }): Promise<void>;
33
+ export declare function getBotQrcode(params: {
34
+ baseUrl: string;
35
+ botType?: string;
36
+ }): Promise<{
37
+ qrcode: string;
38
+ qrcode_img_content: string;
39
+ }>;
40
+ export declare function getQrcodeStatus(params: {
41
+ baseUrl: string;
42
+ qrcode: string;
43
+ }): Promise<{
44
+ status: string;
45
+ bot_token?: string;
46
+ baseurl?: string;
47
+ ilink_bot_id?: string;
48
+ ilink_user_id?: string;
49
+ }>;
50
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/weixin/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAEV,cAAc,EACd,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,aAAa,EACd,MAAM,YAAY,CAAC;AAyEpB,wBAAsB,UAAU,CAAC,MAAM,EAAE;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,cAAc,CAAC,CAQ1B;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,cAAc,CAAC;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhB;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,eAAe,CAAC;CACvB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAO5B;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,aAAa,CAAC,CAWzB;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,aAAa,CAAC;CACrB,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhB;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAA;CAAE,CAAC,CAK1D;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC,CAKD"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * WeChat iLink HTTP API client.
3
+ * Adapted from @tencent-weixin/openclaw-weixin api/api.ts
4
+ */
5
+ import crypto from "node:crypto";
6
+ const CHANNEL_VERSION = "1.0.2";
7
+ function randomWechatUin() {
8
+ const uint32 = crypto.randomBytes(4).readUInt32BE(0);
9
+ return Buffer.from(String(uint32), "utf-8").toString("base64");
10
+ }
11
+ function buildHeaders(token) {
12
+ const headers = {
13
+ "Content-Type": "application/json",
14
+ AuthorizationType: "ilink_bot_token",
15
+ "X-WECHAT-UIN": randomWechatUin(),
16
+ };
17
+ if (token) {
18
+ headers["Authorization"] = `Bearer ${token}`;
19
+ }
20
+ return headers;
21
+ }
22
+ function buildBaseInfo() {
23
+ return { channel_version: CHANNEL_VERSION };
24
+ }
25
+ async function apiGet(baseUrl, path, token) {
26
+ const url = `${baseUrl.replace(/\/$/, "")}/${path}`;
27
+ const res = await fetch(url, { headers: buildHeaders(token) });
28
+ const text = await res.text();
29
+ if (!res.ok)
30
+ throw new Error(`HTTP ${res.status}: ${text}`);
31
+ return JSON.parse(text);
32
+ }
33
+ async function apiPost(baseUrl, endpoint, body, token, timeoutMs = 15_000) {
34
+ const url = `${baseUrl.replace(/\/$/, "")}/${endpoint}`;
35
+ const payload = { ...body, base_info: buildBaseInfo() };
36
+ const bodyStr = JSON.stringify(payload);
37
+ const controller = new AbortController();
38
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
39
+ try {
40
+ const res = await fetch(url, {
41
+ method: "POST",
42
+ headers: buildHeaders(token),
43
+ body: bodyStr,
44
+ signal: controller.signal,
45
+ });
46
+ clearTimeout(timer);
47
+ const text = await res.text();
48
+ if (!res.ok)
49
+ throw new Error(`HTTP ${res.status}: ${text}`);
50
+ return JSON.parse(text);
51
+ }
52
+ catch (err) {
53
+ clearTimeout(timer);
54
+ if (err.name === "AbortError") {
55
+ return { ret: 0, msgs: [] };
56
+ }
57
+ throw err;
58
+ }
59
+ }
60
+ export async function getUpdates(params) {
61
+ return apiPost(params.baseUrl, "ilink/bot/getupdates", { get_updates_buf: params.get_updates_buf }, params.token, params.timeoutMs ?? 38_000);
62
+ }
63
+ export async function sendMessage(params) {
64
+ const endpoint = "ilink/bot/sendmessage";
65
+ const response = await apiPost(params.baseUrl, endpoint, params.body, params.token);
66
+ if ((response.ret !== undefined && response.ret !== 0) ||
67
+ (response.errcode !== undefined && response.errcode !== 0)) {
68
+ throw new Error(`WeChat API ${endpoint} failed: ret=${response.ret ?? 0} ` +
69
+ `errcode=${response.errcode ?? 0} errmsg=${response.errmsg ?? ""}`);
70
+ }
71
+ }
72
+ export async function getUploadUrl(params) {
73
+ return apiPost(params.baseUrl, "ilink/bot/getuploadurl", params.body, params.token);
74
+ }
75
+ export async function getConfig(params) {
76
+ return apiPost(params.baseUrl, "ilink/bot/getconfig", {
77
+ ilink_user_id: params.ilinkUserId,
78
+ ...(params.contextToken ? { context_token: params.contextToken } : {}),
79
+ }, params.token, 10_000);
80
+ }
81
+ export async function sendTyping(params) {
82
+ await apiPost(params.baseUrl, "ilink/bot/sendtyping", params.body, params.token, 10_000);
83
+ }
84
+ export async function getBotQrcode(params) {
85
+ return apiGet(params.baseUrl, `ilink/bot/get_bot_qrcode?bot_type=${params.botType ?? "3"}`);
86
+ }
87
+ export async function getQrcodeStatus(params) {
88
+ return apiGet(params.baseUrl, `ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(params.qrcode)}`);
89
+ }
90
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/weixin/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * WeChat QR login flow + token persistence.
3
+ */
4
+ export interface TokenData {
5
+ /**
6
+ * User-provided label for this WeChat account. Optional only so legacy
7
+ * token.json files written before multi-account support remain readable.
8
+ */
9
+ accountName?: string;
10
+ token: string;
11
+ baseUrl: string;
12
+ accountId: string;
13
+ userId: string;
14
+ savedAt: string;
15
+ }
16
+ export declare function loadToken(storageDir: string): TokenData | null;
17
+ export declare function saveToken(storageDir: string, data: TokenData): void;
18
+ export declare function login(params: {
19
+ baseUrl: string;
20
+ botType?: string;
21
+ storageDir: string;
22
+ persist?: boolean;
23
+ log: (msg: string) => void;
24
+ renderQrUrl?: (url: string) => void;
25
+ }): Promise<TokenData>;
26
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/weixin/auth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,SAAS;IACxB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAQ9D;AAED,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAkBnE;AAED,wBAAsB,KAAK,CAAC,MAAM,EAAE;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,GAAG,OAAO,CAAC,SAAS,CAAC,CAmErB"}