inkdrift 0.1.0

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 (107) hide show
  1. package/.env.example +23 -0
  2. package/README.md +119 -0
  3. package/dist/index-once.d.ts +8 -0
  4. package/dist/index-once.d.ts.map +1 -0
  5. package/dist/index-once.js +45 -0
  6. package/dist/index-once.js.map +1 -0
  7. package/dist/index.d.ts +9 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +72 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/modules/bot/index.d.ts +11 -0
  12. package/dist/modules/bot/index.d.ts.map +1 -0
  13. package/dist/modules/bot/index.js +60 -0
  14. package/dist/modules/bot/index.js.map +1 -0
  15. package/dist/modules/bot/test.d.ts +13 -0
  16. package/dist/modules/bot/test.d.ts.map +1 -0
  17. package/dist/modules/bot/test.js +37 -0
  18. package/dist/modules/bot/test.js.map +1 -0
  19. package/dist/modules/distiller/index.d.ts +24 -0
  20. package/dist/modules/distiller/index.d.ts.map +1 -0
  21. package/dist/modules/distiller/index.js +124 -0
  22. package/dist/modules/distiller/index.js.map +1 -0
  23. package/dist/modules/distiller/test.d.ts +10 -0
  24. package/dist/modules/distiller/test.d.ts.map +1 -0
  25. package/dist/modules/distiller/test.js +92 -0
  26. package/dist/modules/distiller/test.js.map +1 -0
  27. package/dist/modules/extractor/index.d.ts +52 -0
  28. package/dist/modules/extractor/index.d.ts.map +1 -0
  29. package/dist/modules/extractor/index.js +114 -0
  30. package/dist/modules/extractor/index.js.map +1 -0
  31. package/dist/modules/extractor/test.d.ts +10 -0
  32. package/dist/modules/extractor/test.d.ts.map +1 -0
  33. package/dist/modules/extractor/test.js +80 -0
  34. package/dist/modules/extractor/test.js.map +1 -0
  35. package/dist/modules/fetcher/index.d.ts +2 -0
  36. package/dist/modules/fetcher/index.d.ts.map +1 -0
  37. package/dist/modules/fetcher/index.js +3 -0
  38. package/dist/modules/fetcher/index.js.map +1 -0
  39. package/dist/modules/fetcher/test.d.ts +2 -0
  40. package/dist/modules/fetcher/test.d.ts.map +1 -0
  41. package/dist/modules/fetcher/test.js +3 -0
  42. package/dist/modules/fetcher/test.js.map +1 -0
  43. package/dist/modules/flowus-source/index.d.ts +55 -0
  44. package/dist/modules/flowus-source/index.d.ts.map +1 -0
  45. package/dist/modules/flowus-source/index.js +195 -0
  46. package/dist/modules/flowus-source/index.js.map +1 -0
  47. package/dist/modules/flowus-source/test.d.ts +14 -0
  48. package/dist/modules/flowus-source/test.d.ts.map +1 -0
  49. package/dist/modules/flowus-source/test.js +63 -0
  50. package/dist/modules/flowus-source/test.js.map +1 -0
  51. package/dist/modules/flowus-source/types.d.ts +93 -0
  52. package/dist/modules/flowus-source/types.d.ts.map +1 -0
  53. package/dist/modules/flowus-source/types.js +5 -0
  54. package/dist/modules/flowus-source/types.js.map +1 -0
  55. package/dist/modules/memorizer/index.d.ts +29 -0
  56. package/dist/modules/memorizer/index.d.ts.map +1 -0
  57. package/dist/modules/memorizer/index.js +72 -0
  58. package/dist/modules/memorizer/index.js.map +1 -0
  59. package/dist/modules/memorizer/test.d.ts +10 -0
  60. package/dist/modules/memorizer/test.d.ts.map +1 -0
  61. package/dist/modules/memorizer/test.js +69 -0
  62. package/dist/modules/memorizer/test.js.map +1 -0
  63. package/dist/modules/queue/index.d.ts +45 -0
  64. package/dist/modules/queue/index.d.ts.map +1 -0
  65. package/dist/modules/queue/index.js +161 -0
  66. package/dist/modules/queue/index.js.map +1 -0
  67. package/dist/modules/queue/test.d.ts +2 -0
  68. package/dist/modules/queue/test.d.ts.map +1 -0
  69. package/dist/modules/queue/test.js +3 -0
  70. package/dist/modules/queue/test.js.map +1 -0
  71. package/dist/modules/webhook/index.d.ts +8 -0
  72. package/dist/modules/webhook/index.d.ts.map +1 -0
  73. package/dist/modules/webhook/index.js +8 -0
  74. package/dist/modules/webhook/index.js.map +1 -0
  75. package/dist/modules/webhook/test.d.ts +12 -0
  76. package/dist/modules/webhook/test.d.ts.map +1 -0
  77. package/dist/modules/webhook/test.js +14 -0
  78. package/dist/modules/webhook/test.js.map +1 -0
  79. package/dist/modules/wechat-client/index.d.ts +8 -0
  80. package/dist/modules/wechat-client/index.d.ts.map +1 -0
  81. package/dist/modules/wechat-client/index.js +8 -0
  82. package/dist/modules/wechat-client/index.js.map +1 -0
  83. package/dist/modules/wechat-client/test.d.ts +12 -0
  84. package/dist/modules/wechat-client/test.d.ts.map +1 -0
  85. package/dist/modules/wechat-client/test.js +14 -0
  86. package/dist/modules/wechat-client/test.js.map +1 -0
  87. package/dist/modules/wechat-fetcher/index.d.ts +18 -0
  88. package/dist/modules/wechat-fetcher/index.d.ts.map +1 -0
  89. package/dist/modules/wechat-fetcher/index.js +75 -0
  90. package/dist/modules/wechat-fetcher/index.js.map +1 -0
  91. package/dist/scripts/reset-one.d.ts +6 -0
  92. package/dist/scripts/reset-one.d.ts.map +1 -0
  93. package/dist/scripts/reset-one.js +40 -0
  94. package/dist/scripts/reset-one.js.map +1 -0
  95. package/dist/utils/config.d.ts +24 -0
  96. package/dist/utils/config.d.ts.map +1 -0
  97. package/dist/utils/config.js +35 -0
  98. package/dist/utils/config.js.map +1 -0
  99. package/dist/utils/logger.d.ts +2 -0
  100. package/dist/utils/logger.d.ts.map +1 -0
  101. package/dist/utils/logger.js +3 -0
  102. package/dist/utils/logger.js.map +1 -0
  103. package/dist/web/server.d.ts +2 -0
  104. package/dist/web/server.d.ts.map +1 -0
  105. package/dist/web/server.js +3 -0
  106. package/dist/web/server.js.map +1 -0
  107. package/package.json +61 -0
@@ -0,0 +1,161 @@
1
+ /**
2
+ * queue module - serial task queue
3
+ *
4
+ * Processes FlowUs articles one at a time through the full pipeline:
5
+ * fetch content → extract → distill → memorize → update status.
6
+ */
7
+ import { FlowUsClient } from '../flowus-source/index.js';
8
+ import { extract, isPlaceholderContent, extractUrl } from '../extractor/index.js';
9
+ import { distill } from '../distiller/index.js';
10
+ import { checkNmemAvailable, saveMemories } from '../memorizer/index.js';
11
+ import { fetchWechatArticle } from '../wechat-fetcher/index.js';
12
+ // ---- Queue ----
13
+ export class SerialQueue {
14
+ client;
15
+ distillConfig;
16
+ logDir;
17
+ constructor(config) {
18
+ this.client = new FlowUsClient({
19
+ baseUrl: config.flowus.baseUrl,
20
+ token: config.flowus.token,
21
+ databaseId: config.flowus.databaseId,
22
+ });
23
+ this.distillConfig = config.distill;
24
+ this.logDir = config.logDir;
25
+ }
26
+ /**
27
+ * Fetch new articles from FlowUs and process them one by one.
28
+ * Returns results for each processed article.
29
+ */
30
+ async processAll() {
31
+ // Step 1: Check nmem availability
32
+ console.log('[queue] Checking nmem availability...');
33
+ const nmemOk = await checkNmemAvailable();
34
+ if (!nmemOk) {
35
+ console.error('[queue] nmem service is not available. Start with: nmem serve');
36
+ return [];
37
+ }
38
+ console.log('[queue] nmem available ✓');
39
+ // Step 2: Query new articles
40
+ console.log('[queue] Querying new articles from FlowUs...');
41
+ const pages = await this.client.queryNewArticles();
42
+ if (pages.length === 0) {
43
+ console.log('[queue] No new articles to process.');
44
+ return [];
45
+ }
46
+ console.log(`[queue] Found ${pages.length} new article(s).\n`);
47
+ // Step 3: Process each article serially
48
+ const results = [];
49
+ for (let i = 0; i < pages.length; i++) {
50
+ const page = pages[i];
51
+ const title = getPageTitle(page);
52
+ console.log(`--- [${i + 1}/${pages.length}] ${title} ---`);
53
+ const result = await this.processPage(page);
54
+ results.push(result);
55
+ if (result.success) {
56
+ console.log(` ✓ Done: ${result.pointsCount} points, ${result.savedCount} saved\n`);
57
+ }
58
+ else {
59
+ console.log(` ✗ Failed: ${result.error}\n`);
60
+ }
61
+ }
62
+ return results;
63
+ }
64
+ /**
65
+ * Process a single article through the full pipeline.
66
+ */
67
+ async processPage(page) {
68
+ const pageId = page.id;
69
+ let title = getPageTitle(page);
70
+ try {
71
+ // Mark as processing
72
+ await this.client.markProcessing(pageId);
73
+ // 1. Fetch full article content
74
+ console.log(` [1/4] Fetching article content...`);
75
+ const article = await this.client.getFullArticle(page);
76
+ if (!article.content || article.content.trim().length === 0) {
77
+ await this.client.markAsFailed(pageId, 'Empty article content');
78
+ return { task: { type: 'flowus_article', pageId, url: article.url, title }, success: false, pointsCount: 0, savedCount: 0, error: 'Empty content' };
79
+ }
80
+ // 2. Extract (clean markdown)
81
+ console.log(` [2/4] Extracting...`);
82
+ let extracted = extract(article.content);
83
+ // Check for FlowUs capture failure placeholder
84
+ if (isPlaceholderContent(article.content)) {
85
+ const originalUrl = extractUrl(article.content) ?? article.url;
86
+ console.log(` [queue] Placeholder detected, trying Chrome cookies fetch... URL: ${originalUrl}`);
87
+ try {
88
+ const fetched = await fetchWechatArticle(originalUrl);
89
+ console.log(` [queue] Fallback fetch OK, got ${fetched.content.length} chars`);
90
+ // Replace article content with fetched content and re-extract
91
+ article.content = fetched.content;
92
+ article.url = originalUrl;
93
+ if (fetched.title && !title) {
94
+ title = fetched.title;
95
+ }
96
+ }
97
+ catch (fetchErr) {
98
+ const fetchMsg = fetchErr instanceof Error ? fetchErr.message : String(fetchErr);
99
+ console.log(` [queue] Fallback fetch failed: ${fetchMsg}`);
100
+ console.log(` [queue] Article "${title}" needs manual fetch. URL: ${originalUrl}`);
101
+ await this.client.markAsFailed(pageId, '需要手动抓取');
102
+ return { task: { type: 'flowus_article', pageId, url: originalUrl, title }, success: false, pointsCount: 0, savedCount: 0, error: '需要手动抓取' };
103
+ }
104
+ // Re-extract with the fetched content
105
+ extracted = extract(article.content);
106
+ }
107
+ if (extracted.wordCount < 10) {
108
+ await this.client.markAsFailed(pageId, 'Article too short after extraction');
109
+ return { task: { type: 'flowus_article', pageId, url: article.url, title }, success: false, pointsCount: 0, savedCount: 0, error: 'Too short' };
110
+ }
111
+ // 3. Distill knowledge points
112
+ console.log(` [3/4] Distilling knowledge points...`);
113
+ const points = await distill(extracted.markdown, article.url, this.distillConfig);
114
+ if (points.length === 0) {
115
+ console.log(` No knowledge points extracted (article may lack substance).`);
116
+ await this.client.markAsProcessed(pageId);
117
+ return { task: { type: 'flowus_article', pageId, url: article.url, title }, success: true, pointsCount: 0, savedCount: 0 };
118
+ }
119
+ console.log(` ${points.length} knowledge point(s) extracted.`);
120
+ // 4. Save to nmem
121
+ console.log(` [4/4] Saving to nmem...`);
122
+ const memResult = await saveMemories(points, this.logDir);
123
+ if (memResult.failed > 0) {
124
+ console.warn(` Warning: ${memResult.failed} point(s) failed to save.`);
125
+ for (const e of memResult.errors) {
126
+ console.warn(` - ${e}`);
127
+ }
128
+ }
129
+ // Mark as processed
130
+ await this.client.markAsProcessed(pageId);
131
+ return {
132
+ task: { type: 'flowus_article', pageId, url: article.url, title },
133
+ success: true,
134
+ pointsCount: points.length,
135
+ savedCount: memResult.saved,
136
+ };
137
+ }
138
+ catch (err) {
139
+ const msg = err instanceof Error ? err.message : String(err);
140
+ console.error(` Error processing article: ${msg}`);
141
+ try {
142
+ await this.client.markAsFailed(pageId, msg);
143
+ }
144
+ catch (markErr) {
145
+ console.error(` Failed to mark article as failed: ${markErr}`);
146
+ }
147
+ return { task: { type: 'flowus_article', pageId, url: '', title }, success: false, pointsCount: 0, savedCount: 0, error: msg };
148
+ }
149
+ }
150
+ }
151
+ /** Extract display title from a FlowUsPage's properties. */
152
+ function getPageTitle(page) {
153
+ const titleProp = page.properties['title'];
154
+ if (titleProp && 'title' in titleProp) {
155
+ return titleProp.title
156
+ .map((t) => t.plain_text)
157
+ .join('');
158
+ }
159
+ return page.id;
160
+ }
161
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/queue/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../../src/modules/queue/test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ export {};
2
+ // queue module - standalone test entry
3
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../../../src/modules/queue/test.ts"],"names":[],"mappings":";AAAA,uCAAuC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * webhook module
3
+ *
4
+ * Receives WeChatPadPro webhook pushes (messages, events)
5
+ * and dispatches them to the appropriate handlers.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/modules/webhook/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * webhook module
3
+ *
4
+ * Receives WeChatPadPro webhook pushes (messages, events)
5
+ * and dispatches them to the appropriate handlers.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/webhook/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * webhook module standalone test
3
+ *
4
+ * Usage: npx tsx src/modules/webhook/test.ts
5
+ *
6
+ * Validation:
7
+ * 1. Webhook endpoint responds to POST requests
8
+ * 2. Message events are parsed correctly
9
+ * 3. Article URLs are extracted and forwarded to queue
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../../src/modules/webhook/test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * webhook module standalone test
3
+ *
4
+ * Usage: npx tsx src/modules/webhook/test.ts
5
+ *
6
+ * Validation:
7
+ * 1. Webhook endpoint responds to POST requests
8
+ * 2. Message events are parsed correctly
9
+ * 3. Article URLs are extracted and forwarded to queue
10
+ */
11
+ // TODO: implement webhook tests
12
+ console.log('webhook test - TODO');
13
+ export {};
14
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../../../src/modules/webhook/test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,gCAAgC;AAChC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * wechat-client module
3
+ *
4
+ * HTTP client for WeChatPadPro API (iPad protocol).
5
+ * Handles sending messages and interacting with the WeChatPadPro service.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/modules/wechat-client/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * wechat-client module
3
+ *
4
+ * HTTP client for WeChatPadPro API (iPad protocol).
5
+ * Handles sending messages and interacting with the WeChatPadPro service.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/wechat-client/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * wechat-client module standalone test
3
+ *
4
+ * Usage: npx tsx src/modules/wechat-client/test.ts
5
+ *
6
+ * Validation:
7
+ * 1. WeChatPadPro service is reachable
8
+ * 2. Login status check works
9
+ * 3. Send message API works
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../../src/modules/wechat-client/test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * wechat-client module standalone test
3
+ *
4
+ * Usage: npx tsx src/modules/wechat-client/test.ts
5
+ *
6
+ * Validation:
7
+ * 1. WeChatPadPro service is reachable
8
+ * 2. Login status check works
9
+ * 3. Send message API works
10
+ */
11
+ // TODO: implement wechat-client tests
12
+ console.log('wechat-client test - TODO');
13
+ export {};
14
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../../../src/modules/wechat-client/test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,sCAAsC;AACtC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * wechat-fetcher module
3
+ *
4
+ * Fetches WeChat article content using local Chrome cookies.
5
+ * Falls back to direct browser fetch when FlowUs capture fails.
6
+ *
7
+ * Flow: read Chrome cookies → request URL with cookies → cheerio extract → turndown → Markdown
8
+ */
9
+ export interface FetchedArticle {
10
+ title: string;
11
+ content: string;
12
+ }
13
+ /**
14
+ * Fetch a WeChat article using local Chrome cookies.
15
+ * Returns the article title and content as Markdown.
16
+ */
17
+ export declare function fetchWechatArticle(url: string): Promise<FetchedArticle>;
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/modules/wechat-fetcher/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAkBD;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAqD7E"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * wechat-fetcher module
3
+ *
4
+ * Fetches WeChat article content using local Chrome cookies.
5
+ * Falls back to direct browser fetch when FlowUs capture fails.
6
+ *
7
+ * Flow: read Chrome cookies → request URL with cookies → cheerio extract → turndown → Markdown
8
+ */
9
+ import { getCookiesPromised } from 'chrome-cookies-secure';
10
+ import got from 'got';
11
+ import * as cheerio from 'cheerio';
12
+ import TurndownService from 'turndown';
13
+ // ---- Helpers ----
14
+ const turndown = new TurndownService();
15
+ /**
16
+ * Build a Cookie header string from a cookie object returned by chrome-cookies-secure.
17
+ * Input: { name: value, ... } → Output: "name=value; name2=value2"
18
+ */
19
+ function buildCookieHeader(cookies) {
20
+ return Object.entries(cookies)
21
+ .map(([name, value]) => `${name}=${value}`)
22
+ .join('; ');
23
+ }
24
+ // ---- API ----
25
+ /**
26
+ * Fetch a WeChat article using local Chrome cookies.
27
+ * Returns the article title and content as Markdown.
28
+ */
29
+ export async function fetchWechatArticle(url) {
30
+ // Step 1: Read Chrome cookies for mp.weixin.qq.com
31
+ let cookieHeader;
32
+ try {
33
+ const cookies = await getCookiesPromised('https://mp.weixin.qq.com');
34
+ cookieHeader = buildCookieHeader(cookies);
35
+ }
36
+ catch (err) {
37
+ const msg = err instanceof Error ? err.message : String(err);
38
+ throw new Error(`Failed to read Chrome cookies: ${msg}`);
39
+ }
40
+ if (!cookieHeader) {
41
+ throw new Error('No Chrome cookies found for mp.weixin.qq.com');
42
+ }
43
+ // Step 2: Fetch article HTML with cookies
44
+ let html;
45
+ try {
46
+ const response = await got(url, {
47
+ headers: {
48
+ Cookie: cookieHeader,
49
+ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
50
+ },
51
+ timeout: { request: 30000 },
52
+ });
53
+ html = response.body;
54
+ }
55
+ catch (err) {
56
+ const msg = err instanceof Error ? err.message : String(err);
57
+ throw new Error(`Failed to fetch article: ${msg}`);
58
+ }
59
+ // Step 3: Extract content with cheerio
60
+ const $ = cheerio.load(html);
61
+ const title = $('#activity-name').text().trim() ||
62
+ $('h1').first().text().trim() ||
63
+ '';
64
+ const contentHtml = $('#js_content').html();
65
+ if (!contentHtml) {
66
+ throw new Error('Article body not found (#js_content is empty or missing)');
67
+ }
68
+ // Step 4: Convert to Markdown
69
+ const content = turndown.turndown(contentHtml);
70
+ if (!content || content.trim().length === 0) {
71
+ throw new Error('Converted Markdown is empty');
72
+ }
73
+ return { title, content };
74
+ }
75
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/wechat-fetcher/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Reset one completed article back to "未处理" for testing.
3
+ * Usage: npx tsx src/scripts/reset-one.ts
4
+ */
5
+ import '../utils/config.js';
6
+ //# sourceMappingURL=reset-one.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset-one.d.ts","sourceRoot":"","sources":["../../src/scripts/reset-one.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,oBAAoB,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Reset one completed article back to "未处理" for testing.
3
+ * Usage: npx tsx src/scripts/reset-one.ts
4
+ */
5
+ import '../utils/config.js';
6
+ import { config } from '../utils/config.js';
7
+ import got from 'got';
8
+ // Query completed articles
9
+ const res = await got
10
+ .post(`https://api.flowus.cn/v1/databases/${config.flowus.databaseId}/query`, {
11
+ headers: {
12
+ Authorization: `Bearer ${config.flowus.token}`,
13
+ 'Content-Type': 'application/json',
14
+ },
15
+ json: {
16
+ page_size: 10,
17
+ filter: { property: 'status', select: { equals: '已完成' } },
18
+ },
19
+ })
20
+ .json();
21
+ console.log(`Found ${res.results.length} completed article(s)`);
22
+ if (res.results.length > 0) {
23
+ const page = res.results[0];
24
+ console.log(`Resetting ${page.id}...`);
25
+ await got
26
+ .patch(`https://api.flowus.cn/v1/pages/${page.id}`, {
27
+ headers: {
28
+ Authorization: `Bearer ${config.flowus.token}`,
29
+ 'Content-Type': 'application/json',
30
+ },
31
+ json: {
32
+ properties: {
33
+ status: { type: 'select', select: { name: '未处理' } },
34
+ },
35
+ },
36
+ })
37
+ .json();
38
+ console.log('Done - article reset to 未处理');
39
+ }
40
+ //# sourceMappingURL=reset-one.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset-one.js","sourceRoot":"","sources":["../../src/scripts/reset-one.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,oBAAoB,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,2BAA2B;AAC3B,MAAM,GAAG,GAAG,MAAM,GAAG;KAClB,IAAI,CAAC,sCAAsC,MAAM,CAAC,MAAM,CAAC,UAAU,QAAQ,EAAE;IAC5E,OAAO,EAAE;QACP,aAAa,EAAE,UAAU,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE;QAC9C,cAAc,EAAE,kBAAkB;KACnC;IACD,IAAI,EAAE;QACJ,SAAS,EAAE,EAAE;QACb,MAAM,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;KAC1D;CACF,CAAC;KACD,IAAI,EAAsC,CAAC;AAE9C,OAAO,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,OAAO,CAAC,MAAM,uBAAuB,CAAC,CAAC;AAEhE,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;IACvC,MAAM,GAAG;SACN,KAAK,CAAC,kCAAkC,IAAI,CAAC,EAAE,EAAE,EAAE;QAClD,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE;YAC9C,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI,EAAE;YACJ,UAAU,EAAE;gBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;aACpD;SACF;KACF,CAAC;SACD,IAAI,EAAE,CAAC;IACV,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,24 @@
1
+ export declare const config: {
2
+ flowus: {
3
+ baseUrl: string;
4
+ token: string;
5
+ databaseId: string;
6
+ };
7
+ glm: {
8
+ baseUrl: string;
9
+ apiKey: string;
10
+ model: string;
11
+ };
12
+ web: {
13
+ port: number;
14
+ };
15
+ retry: {
16
+ max: number;
17
+ intervalMs: number;
18
+ };
19
+ log: {
20
+ level: string;
21
+ dir: string;
22
+ };
23
+ };
24
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;CAsBlB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import dotenv from 'dotenv';
2
+ import { existsSync } from 'node:fs';
3
+ import { fileURLToPath } from 'node:url';
4
+ import path from 'node:path';
5
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
+ // Prefer .env from current working directory (npx global usage),
7
+ // fallback to project-root .env (development mode)
8
+ const cwdEnv = path.resolve(process.cwd(), '.env');
9
+ const projectEnv = path.resolve(__dirname, '../../.env');
10
+ const envPath = existsSync(cwdEnv) ? cwdEnv : projectEnv;
11
+ dotenv.config({ path: envPath });
12
+ export const config = {
13
+ flowus: {
14
+ baseUrl: process.env.FLOWUS_BASE_URL || 'https://api.flowus.cn',
15
+ token: process.env.FLOWUS_TOKEN || '',
16
+ databaseId: process.env.FLOWUS_DATABASE_ID || '',
17
+ },
18
+ glm: {
19
+ baseUrl: process.env.GLM_BASE_URL || 'https://aiping.cn/api/v1',
20
+ apiKey: process.env.GLM_API_KEY || '',
21
+ model: process.env.GLM_MODEL || 'GLM-4.7',
22
+ },
23
+ web: {
24
+ port: parseInt(process.env.WEB_PORT || '3000', 10),
25
+ },
26
+ retry: {
27
+ max: parseInt(process.env.RETRY_MAX || '3', 10),
28
+ intervalMs: parseInt(process.env.RETRY_INTERVAL_MS || '60000', 10),
29
+ },
30
+ log: {
31
+ level: process.env.LOG_LEVEL || 'info',
32
+ dir: process.env.LOG_DIR || './logs',
33
+ },
34
+ };
35
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE/D,iEAAiE;AACjE,mDAAmD;AACnD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;AACnD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;AACzD,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC;AAEzD,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAEjC,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,MAAM,EAAE;QACN,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,uBAAuB;QAC/D,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE;QACrC,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE;KACjD;IACD,GAAG,EAAE;QACH,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,0BAA0B;QAC/D,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE;QACrC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,SAAS;KAC1C;IACD,GAAG,EAAE;QACH,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,MAAM,EAAE,EAAE,CAAC;KACnD;IACD,KAAK,EAAE;QACL,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,GAAG,EAAE,EAAE,CAAC;QAC/C,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,EAAE,EAAE,CAAC;KACnE;IACD,GAAG,EAAE;QACH,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM;QACtC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,QAAQ;KACrC;CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ export {};
2
+ // pino logger setup
3
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":";AAAA,oBAAoB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ export {};
2
+ // fastify web server - status page & QR code
3
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":";AAAA,6CAA6C"}