weflow-cli 1.11.0 → 1.11.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.
- package/CHANGELOG.md +38 -0
- package/OPERATIONS.md +7 -1
- package/bin/weflow-cli.ts +7 -0
- package/dist/bin/weflow-cli.js +8 -0
- package/dist/bin/weflow-cli.js.map +1 -1
- package/docs/RELEASING.md +33 -0
- package/package.json +1 -1
- package/scripts/export_chat_html.py +117 -15
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,44 @@ purpose** - a hand-written "latest is X" is exactly the claim that goes stale he
|
|
|
17
17
|
|
|
18
18
|
All notable user-facing changes are recorded here. This project follows [Semantic Versioning](https://semver.org/).
|
|
19
19
|
|
|
20
|
+
## 1.11.1
|
|
21
|
+
|
|
22
|
+
- **Five defects in 1.11.0's document export, all found by looking at a real export instead of the code.**
|
|
23
|
+
Re-exporting one 1,914-message conversation (29 documents on disk) and asking whether what got written can
|
|
24
|
+
actually be **opened** turned up two files that would have been unopenable in the reader's own editor:
|
|
25
|
+
|
|
26
|
+
1. A document whose name contains a half-width parenthesis - `…开题报告(2).pdf` - landed in the link target
|
|
27
|
+
as-is, and **every markdown renderer ends a target at the first `)`**, so the link stopped at `…报告(2`
|
|
28
|
+
and opened nothing. A space breaks it the same way (the target ends at whitespace). Targets are now
|
|
29
|
+
percent-encoded per path segment (`%282%29`, `%20`) while the link text stays the original name and
|
|
30
|
+
Chinese characters stay literal - `%E5%…` would be correct but unreadable.
|
|
31
|
+
2. The 80-character filename limit was applied to the whole name, so a long title lost its **extension**:
|
|
32
|
+
one file landed as `Chang 等 - 2022 - Environmental Justice Assessment of Fine Particles, Ozone, and`
|
|
33
|
+
with no `.pdf`, leaving the OS and every editor without a clue how to open it. The limit now applies to
|
|
34
|
+
the stem, with the extension kept.
|
|
35
|
+
|
|
36
|
+
Both were **invisible to the code and to the existing tests** - the first pass "worked" and produced a
|
|
37
|
+
complete-looking asset directory. Hunting for the rest of that class turned up three more:
|
|
38
|
+
|
|
39
|
+
3. **A filename containing a control character killed the whole export at the last step.** A tab in a message
|
|
40
|
+
title makes `open()` raise `OSError: Invalid argument` on Windows, and nothing caught it - minutes of
|
|
41
|
+
parsing and image extraction were thrown away by one bad name. Copy failures (bad name, path too long,
|
|
42
|
+
target locked) are now counted as `unavailable` instead. Control characters are also stripped from the
|
|
43
|
+
on-disk name, the link text, and `sanitize_filename` generally.
|
|
44
|
+
4. **Windows reserved device names** (`CON.pdf`, `NUL.txt`, `aux.docx`) cannot be created at all; they are now
|
|
45
|
+
prefixed with `_`. Checked alongside: 200-character titles, `[草稿]` brackets, `#`, `%`, quotes, emoji,
|
|
46
|
+
trailing dots, `|*?` - a battery of 21 real-world names, with every resulting link asserted to *resolve*.
|
|
47
|
+
5. **A narrower export silently erased a wider one's manifest.** The manifest lives in the shared
|
|
48
|
+
`<talker>_assets/` directory, so exporting the whole conversation and then running
|
|
49
|
+
`json --media --limit 600` into the same folder overwrote 585 entries with 150 - the wider run's documents
|
|
50
|
+
kept their links in the markdown but vanished from the manifest, and neither side reported anything. The
|
|
51
|
+
manifest is now **merged** with the existing one (entries whose file is gone are dropped), and it records
|
|
52
|
+
both `copied` (this run) and `exported` (present in the directory), because those were being conflated.
|
|
53
|
+
|
|
54
|
+
One more, not a defect but the same "silent" shape: `--media` together with `html` did nothing at all (HTML
|
|
55
|
+
writes no document bodies by design, so that is not a missing feature) and said nothing, which reads as a
|
|
56
|
+
broken switch. The CLI now names the reason and points at `md` / `json --media`.
|
|
57
|
+
|
|
20
58
|
## 1.11.0
|
|
21
59
|
|
|
22
60
|
- **Documents now travel with the export — all five formats, bodies included.** The same user report that asked
|
package/OPERATIONS.md
CHANGED
|
@@ -101,7 +101,13 @@ weflow-cli export "联系人A" json --output ./output
|
|
|
101
101
|
`msg/file/YYYY-MM/` 下,按 `(归一化名, 字节数)` 对上,同名多份时用 md5 定。本机实测 1,855 条文件消息里
|
|
102
102
|
**1,643 条对得上(88.6%)**,其余 212 条本地确实没有那份文件(没下载过或已清理)—— 这些消息仍是
|
|
103
103
|
`[文件] 名字` 的标签,不清单里凑数、也不猜。导出的计数里 `exported` 是"这份文档在 assets 里",
|
|
104
|
-
`written`
|
|
104
|
+
`written`(清单里叫 `documents.copied`)才是"这次新拷了几个",别把后者当成前者的成绩。
|
|
105
|
+
另外 `--media` 配 `html` 不生效(HTML 不写文档本体),CLI 会提示一句而不是静默忽略。
|
|
106
|
+
|
|
107
|
+
md 里指向文档的链接**把路径里的空格、括号等字符做了百分号编码**(如 `报告%282%29.pdf`),链接文字仍是原名。
|
|
108
|
+
这不是洁癖:文档名里带半角括号时(`报告(2).pdf` 这种),链接目标会被任何 markdown 渲染器在**第一个 `)`
|
|
109
|
+
处截断**,点开是空的(2026-10-13 重导时实测到;同一批里还有一份超长标题被 80 字符上限连 `.pdf` 一起截掉,
|
|
110
|
+
落成一个没有扩展名的文件——那条也修了)。
|
|
105
111
|
|
|
106
112
|
**HTML 导出(含 `--full-images`)不写文件本体**:HTML 的用法是"单文件可分享",把几 MB 的 PDF 内嵌成
|
|
107
113
|
base64 既没人打得开、也把网页撑大。要在文件本体上要文档,用 `md` 或 `json|txt|excel --media`。
|
package/bin/weflow-cli.ts
CHANGED
|
@@ -1881,6 +1881,13 @@ program
|
|
|
1881
1881
|
else console.log(chalk.red(`✗ 媒体抽取失败: ${media.error}`))
|
|
1882
1882
|
process.exit(1)
|
|
1883
1883
|
}
|
|
1884
|
+
} else if (opts.media && format === 'html') {
|
|
1885
|
+
// HTML 的用法是"单文件可分享",所以它不写文档本体(把几 MB 的 PDF 内嵌进网页,既打不开也把文件撑大)。
|
|
1886
|
+
// 静默忽略这个开关会让人以为它生效了 —— 明说一句,并给出该用哪个格式。
|
|
1887
|
+
if (!opts.json) {
|
|
1888
|
+
console.error(chalk.gray(' 提示:HTML 导出不含文档本体(单文件分享的用法),--media 对它不生效;'))
|
|
1889
|
+
console.error(chalk.gray(' 要连文档一起导出请用 md,或 json|txt|excel --media。'))
|
|
1890
|
+
}
|
|
1884
1891
|
}
|
|
1885
1892
|
switch (format) {
|
|
1886
1893
|
case 'json':
|
package/dist/bin/weflow-cli.js
CHANGED
|
@@ -1912,6 +1912,14 @@ program
|
|
|
1912
1912
|
process.exit(1);
|
|
1913
1913
|
}
|
|
1914
1914
|
}
|
|
1915
|
+
else if (opts.media && format === 'html') {
|
|
1916
|
+
// HTML 的用法是"单文件可分享",所以它不写文档本体(把几 MB 的 PDF 内嵌进网页,既打不开也把文件撑大)。
|
|
1917
|
+
// 静默忽略这个开关会让人以为它生效了 —— 明说一句,并给出该用哪个格式。
|
|
1918
|
+
if (!opts.json) {
|
|
1919
|
+
console.error(chalk.gray(' 提示:HTML 导出不含文档本体(单文件分享的用法),--media 对它不生效;'));
|
|
1920
|
+
console.error(chalk.gray(' 要连文档一起导出请用 md,或 json|txt|excel --media。'));
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1915
1923
|
switch (format) {
|
|
1916
1924
|
case 'json':
|
|
1917
1925
|
result = await exportService.exportJson(talker, opts.output, limit, from, to, opts.contract);
|