codeksei 0.1.0 → 0.1.1

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 (68) hide show
  1. package/LICENSE +661 -661
  2. package/README.en.md +109 -47
  3. package/README.md +79 -58
  4. package/bin/cyberboss.js +1 -1
  5. package/package.json +86 -86
  6. package/scripts/open_shared_wechat_thread.sh +77 -77
  7. package/scripts/open_wechat_thread.sh +108 -108
  8. package/scripts/shared-common.js +144 -144
  9. package/scripts/shared-open.js +14 -14
  10. package/scripts/shared-start.js +5 -5
  11. package/scripts/shared-status.js +27 -27
  12. package/scripts/show_shared_status.sh +45 -45
  13. package/scripts/start_shared_app_server.sh +52 -52
  14. package/scripts/start_shared_wechat.sh +94 -94
  15. package/scripts/timeline-screenshot.sh +14 -14
  16. package/src/adapters/channel/weixin/account-store.js +99 -99
  17. package/src/adapters/channel/weixin/api-v2.js +50 -50
  18. package/src/adapters/channel/weixin/api.js +169 -169
  19. package/src/adapters/channel/weixin/context-token-store.js +84 -84
  20. package/src/adapters/channel/weixin/index.js +618 -604
  21. package/src/adapters/channel/weixin/legacy.js +579 -566
  22. package/src/adapters/channel/weixin/media-mime.js +22 -22
  23. package/src/adapters/channel/weixin/media-receive.js +370 -370
  24. package/src/adapters/channel/weixin/media-send.js +102 -102
  25. package/src/adapters/channel/weixin/message-utils-v2.js +282 -282
  26. package/src/adapters/channel/weixin/message-utils.js +199 -199
  27. package/src/adapters/channel/weixin/redact.js +41 -41
  28. package/src/adapters/channel/weixin/reminder-queue-store.js +101 -101
  29. package/src/adapters/channel/weixin/sync-buffer-store.js +35 -35
  30. package/src/adapters/runtime/codex/events.js +215 -215
  31. package/src/adapters/runtime/codex/index.js +109 -104
  32. package/src/adapters/runtime/codex/message-utils.js +95 -95
  33. package/src/adapters/runtime/codex/model-catalog.js +106 -106
  34. package/src/adapters/runtime/codex/protocol-leak-monitor.js +75 -75
  35. package/src/adapters/runtime/codex/rpc-client.js +339 -339
  36. package/src/adapters/runtime/codex/session-store.js +286 -286
  37. package/src/app/channel-send-file-cli.js +57 -57
  38. package/src/app/diary-write-cli.js +236 -88
  39. package/src/app/note-sync-cli.js +2 -2
  40. package/src/app/reminder-write-cli.js +215 -210
  41. package/src/app/review-cli.js +7 -5
  42. package/src/app/system-checkin-poller.js +64 -64
  43. package/src/app/system-send-cli.js +129 -129
  44. package/src/app/timeline-event-cli.js +28 -25
  45. package/src/app/timeline-screenshot-cli.js +103 -100
  46. package/src/core/app.js +1763 -1763
  47. package/src/core/branding.js +2 -1
  48. package/src/core/command-registry.js +381 -369
  49. package/src/core/config.js +30 -14
  50. package/src/core/default-targets.js +163 -163
  51. package/src/core/durable-note-schema.js +9 -8
  52. package/src/core/instructions-template.js +17 -16
  53. package/src/core/note-sync.js +8 -7
  54. package/src/core/path-utils.js +54 -0
  55. package/src/core/project-radar.js +11 -10
  56. package/src/core/review.js +48 -50
  57. package/src/core/stream-delivery.js +1162 -983
  58. package/src/core/system-message-dispatcher.js +68 -68
  59. package/src/core/system-message-queue-store.js +128 -128
  60. package/src/core/thread-state-store.js +96 -96
  61. package/src/core/timeline-screenshot-queue-store.js +134 -134
  62. package/src/core/timezone.js +436 -0
  63. package/src/core/workspace-bootstrap.js +9 -1
  64. package/src/index.js +148 -146
  65. package/src/integrations/timeline/index.js +130 -74
  66. package/src/integrations/timeline/state-sync.js +240 -0
  67. package/templates/weixin-instructions.md +12 -38
  68. package/templates/weixin-operations.md +29 -31
@@ -1,98 +1,98 @@
1
- const crypto = require("crypto");
1
+ const crypto = require("crypto");
2
2
  const path = require("path");
3
3
  const fs = require("fs/promises");
4
4
 
5
5
  const { getUploadUrl, sendMessage } = require("./api");
6
6
  const { getUploadUrlV2, sendMessageV2 } = require("./api-v2");
7
7
  const { getMimeFromFilename } = require("./media-mime");
8
-
9
- const WEIXIN_MEDIA_TYPE = {
10
- IMAGE: 1,
11
- VIDEO: 2,
12
- FILE: 3,
13
- };
14
-
15
- function encryptAesEcb(plaintext, key) {
16
- const cipher = crypto.createCipheriv("aes-128-ecb", key, null);
17
- return Buffer.concat([cipher.update(plaintext), cipher.final()]);
18
- }
19
-
20
- function aesEcbPaddedSize(plaintextSize) {
21
- return Math.ceil((plaintextSize + 1) / 16) * 16;
22
- }
23
-
24
- function buildCdnUploadUrl({ cdnBaseUrl, uploadParam, filekey }) {
25
- return `${cdnBaseUrl}/upload?encrypted_query_param=${encodeURIComponent(uploadParam)}&filekey=${encodeURIComponent(filekey)}`;
26
- }
27
-
28
- async function uploadBufferToCdn({ buf, uploadParam, filekey, cdnBaseUrl, aeskey }) {
29
- const ciphertext = encryptAesEcb(buf, aeskey);
30
- const cdnUrl = buildCdnUploadUrl({ cdnBaseUrl, uploadParam, filekey });
31
- const response = await fetch(cdnUrl, {
32
- method: "POST",
33
- headers: { "Content-Type": "application/octet-stream" },
34
- body: new Uint8Array(ciphertext),
35
- });
36
- if (response.status !== 200) {
37
- const errMsg = response.headers.get("x-error-message") || await response.text();
38
- throw new Error(`CDN upload failed: ${errMsg || response.status}`);
39
- }
40
- const downloadParam = response.headers.get("x-encrypted-param") || "";
41
- if (!downloadParam) {
42
- throw new Error("CDN upload response missing x-encrypted-param header");
43
- }
44
- return { downloadParam };
45
- }
46
-
8
+
9
+ const WEIXIN_MEDIA_TYPE = {
10
+ IMAGE: 1,
11
+ VIDEO: 2,
12
+ FILE: 3,
13
+ };
14
+
15
+ function encryptAesEcb(plaintext, key) {
16
+ const cipher = crypto.createCipheriv("aes-128-ecb", key, null);
17
+ return Buffer.concat([cipher.update(plaintext), cipher.final()]);
18
+ }
19
+
20
+ function aesEcbPaddedSize(plaintextSize) {
21
+ return Math.ceil((plaintextSize + 1) / 16) * 16;
22
+ }
23
+
24
+ function buildCdnUploadUrl({ cdnBaseUrl, uploadParam, filekey }) {
25
+ return `${cdnBaseUrl}/upload?encrypted_query_param=${encodeURIComponent(uploadParam)}&filekey=${encodeURIComponent(filekey)}`;
26
+ }
27
+
28
+ async function uploadBufferToCdn({ buf, uploadParam, filekey, cdnBaseUrl, aeskey }) {
29
+ const ciphertext = encryptAesEcb(buf, aeskey);
30
+ const cdnUrl = buildCdnUploadUrl({ cdnBaseUrl, uploadParam, filekey });
31
+ const response = await fetch(cdnUrl, {
32
+ method: "POST",
33
+ headers: { "Content-Type": "application/octet-stream" },
34
+ body: new Uint8Array(ciphertext),
35
+ });
36
+ if (response.status !== 200) {
37
+ const errMsg = response.headers.get("x-error-message") || await response.text();
38
+ throw new Error(`CDN upload failed: ${errMsg || response.status}`);
39
+ }
40
+ const downloadParam = response.headers.get("x-encrypted-param") || "";
41
+ if (!downloadParam) {
42
+ throw new Error("CDN upload response missing x-encrypted-param header");
43
+ }
44
+ return { downloadParam };
45
+ }
46
+
47
47
  async function uploadMediaToWeixin({ filePath, toUserId, opts, cdnBaseUrl, mediaType, getUploadUrlImpl }) {
48
48
  const plaintext = await fs.readFile(filePath);
49
49
  const rawsize = plaintext.length;
50
50
  const rawfilemd5 = crypto.createHash("md5").update(plaintext).digest("hex");
51
- const filesize = aesEcbPaddedSize(rawsize);
52
- const filekey = crypto.randomBytes(16).toString("hex");
53
- const aeskey = crypto.randomBytes(16);
54
-
51
+ const filesize = aesEcbPaddedSize(rawsize);
52
+ const filekey = crypto.randomBytes(16).toString("hex");
53
+ const aeskey = crypto.randomBytes(16);
54
+
55
55
  const uploadUrlResp = await getUploadUrlImpl({
56
56
  ...opts,
57
57
  filekey,
58
58
  media_type: mediaType,
59
- to_user_id: toUserId,
60
- rawsize,
61
- rawfilemd5,
62
- filesize,
63
- no_need_thumb: true,
64
- aeskey: aeskey.toString("hex"),
65
- });
66
-
67
- const uploadParam = uploadUrlResp?.upload_param || "";
68
- if (!uploadParam) {
69
- throw new Error("getUploadUrl returned no upload_param");
70
- }
71
-
72
- const { downloadParam } = await uploadBufferToCdn({
73
- buf: plaintext,
74
- uploadParam,
75
- filekey,
76
- cdnBaseUrl,
77
- aeskey,
78
- });
79
-
80
- return {
81
- downloadEncryptedQueryParam: downloadParam,
82
- aeskey: aeskey.toString("hex"),
83
- fileSize: rawsize,
84
- fileSizeCiphertext: filesize,
85
- };
86
- }
87
-
88
- function buildMediaRef(uploaded) {
89
- return {
90
- encrypt_query_param: uploaded.downloadEncryptedQueryParam,
91
- aes_key: Buffer.from(uploaded.aeskey).toString("base64"),
92
- encrypt_type: 1,
93
- };
94
- }
95
-
59
+ to_user_id: toUserId,
60
+ rawsize,
61
+ rawfilemd5,
62
+ filesize,
63
+ no_need_thumb: true,
64
+ aeskey: aeskey.toString("hex"),
65
+ });
66
+
67
+ const uploadParam = uploadUrlResp?.upload_param || "";
68
+ if (!uploadParam) {
69
+ throw new Error("getUploadUrl returned no upload_param");
70
+ }
71
+
72
+ const { downloadParam } = await uploadBufferToCdn({
73
+ buf: plaintext,
74
+ uploadParam,
75
+ filekey,
76
+ cdnBaseUrl,
77
+ aeskey,
78
+ });
79
+
80
+ return {
81
+ downloadEncryptedQueryParam: downloadParam,
82
+ aeskey: aeskey.toString("hex"),
83
+ fileSize: rawsize,
84
+ fileSizeCiphertext: filesize,
85
+ };
86
+ }
87
+
88
+ function buildMediaRef(uploaded) {
89
+ return {
90
+ encrypt_query_param: uploaded.downloadEncryptedQueryParam,
91
+ aes_key: Buffer.from(uploaded.aeskey).toString("base64"),
92
+ encrypt_type: 1,
93
+ };
94
+ }
95
+
96
96
  async function sendMediaItem({ to, item, contextToken, baseUrl, token, routeTag = "", clientVersion = "", sendMessageImpl }) {
97
97
  await sendMessageImpl({
98
98
  baseUrl,
@@ -103,14 +103,14 @@ async function sendMediaItem({ to, item, contextToken, baseUrl, token, routeTag
103
103
  msg: {
104
104
  from_user_id: "",
105
105
  to_user_id: to,
106
- client_id: crypto.randomUUID(),
107
- message_type: 2,
108
- message_state: 2,
109
- item_list: [item],
110
- context_token: contextToken,
111
- },
112
- },
113
- });
106
+ client_id: crypto.randomUUID(),
107
+ message_type: 2,
108
+ message_state: 2,
109
+ item_list: [item],
110
+ context_token: contextToken,
111
+ },
112
+ },
113
+ });
114
114
  }
115
115
 
116
116
  function resolveWeixinMediaApi(apiVariant) {
@@ -205,11 +205,11 @@ async function sendWeixinMediaFile({
205
205
  });
206
206
  }
207
207
  }
208
-
209
- if (mime.startsWith("video/")) {
210
- const uploaded = await uploadMediaToWeixin({
211
- filePath,
212
- toUserId: to,
208
+
209
+ if (mime.startsWith("video/")) {
210
+ const uploaded = await uploadMediaToWeixin({
211
+ filePath,
212
+ toUserId: to,
213
213
  opts: uploadOpts,
214
214
  cdnBaseUrl,
215
215
  mediaType: WEIXIN_MEDIA_TYPE.VIDEO,
@@ -226,14 +226,14 @@ async function sendWeixinMediaFile({
226
226
  item: {
227
227
  type: 5,
228
228
  video_item: {
229
- media: buildMediaRef(uploaded),
230
- video_size: uploaded.fileSizeCiphertext,
231
- },
232
- },
233
- });
234
- return { kind: "video", fileName: path.basename(filePath) };
235
- }
236
-
229
+ media: buildMediaRef(uploaded),
230
+ video_size: uploaded.fileSizeCiphertext,
231
+ },
232
+ },
233
+ });
234
+ return { kind: "video", fileName: path.basename(filePath) };
235
+ }
236
+
237
237
  return sendFileFallback({
238
238
  filePath,
239
239
  to,