@winspan/claude-forge 1.16.3 → 1.16.5

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.
@@ -0,0 +1,72 @@
1
+ /**
2
+ * 项目根目录 CLAUDE.md 中的「续接」与 Pipeline 状态摘要的统一落盘格式。
3
+ *
4
+ * - 写入:`buildForgeResumeEnvelope`(ResumeEngine、PipelineEngine.persistPipelineStateToClaude)
5
+ * - 剥离:`stripForgeResumeBlocks`(注入前清理、clearResumeBlock)
6
+ * - 检测:`hasForgeResumeBlock`(含旧版 `<!-- forge:resume -->` 与新版 begin 标记)
7
+ * - 解码:`decodeForgeResumeInnerFromClaudeMd`(测试 / 工具;模型阅读时按块内说明自行解码)
8
+ */
9
+ import { randomUUID } from 'crypto';
10
+ /** 旧版续接块(正文裸放,易被 HTML 注释子串破坏) */
11
+ const LEGACY_RESUME_BLOCK_RE = /\n*<!-- forge:resume -->[\s\S]*?<!-- forge:end-resume -->\s*/g;
12
+ /** forge:resume-begin / end 之间的 UUID(randomUUID 小写) */
13
+ const RESUME_UUID = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}';
14
+ function scopedResumeBlockRe() {
15
+ return new RegExp(`\\n*<!-- forge:resume-begin:(${RESUME_UUID}) -->[\\s\\S]*?<!-- forge:resume-end:\\1 -->\\s*`, 'gi');
16
+ }
17
+ const FENCE_OPEN = '```forge-resume-body';
18
+ const FENCE_CLOSE = '```';
19
+ /**
20
+ * 构造续接信封:外层用 UUID 配对注释定界,正文 UTF-8 经 base64url 放入专用 fence,
21
+ * 正文中任意 `<!--`、`-->`、`forge:*` 均不可能破坏块边界解析。
22
+ */
23
+ export function buildForgeResumeEnvelope(innerUtf8Markdown) {
24
+ const id = randomUUID();
25
+ const b64 = Buffer.from(innerUtf8Markdown, 'utf8').toString('base64url');
26
+ const lines = b64.length > 0 ? b64.match(/.{1,80}/g) ?? [b64] : [''];
27
+ const iso = new Date().toISOString();
28
+ return [
29
+ `<!-- forge:resume-begin:${id} -->`,
30
+ '_续接正文在下方 `forge-resume-body` 代码块中以 Base64(UTF-8、base64url)编码,避免与 HTML 注释冲突;阅读时请解码。_',
31
+ '',
32
+ FENCE_OPEN,
33
+ ...lines,
34
+ FENCE_CLOSE,
35
+ '',
36
+ `forge_generated_at: ${iso}`,
37
+ `<!-- forge:resume-end:${id} -->`,
38
+ ].join('\n');
39
+ }
40
+ /** 是否包含旧版或新版续接块 */
41
+ export function hasForgeResumeBlock(content) {
42
+ return (content.includes('<!-- forge:resume -->') ||
43
+ new RegExp(`<!-- forge:resume-begin:${RESUME_UUID} -->`).test(content));
44
+ }
45
+ /**
46
+ * 移除全部续接块(新版 UUID 信封 + 旧版裸正文),并压缩多余空行。
47
+ */
48
+ export function stripForgeResumeBlocks(content) {
49
+ let s = content.replace(scopedResumeBlockRe(), '\n');
50
+ s = s.replace(LEGACY_RESUME_BLOCK_RE, '\n');
51
+ s = s.replace(/\n{4,}/g, '\n\n\n');
52
+ return s.trimEnd();
53
+ }
54
+ /**
55
+ * 从 CLAUDE.md 文本中解码第一处新版续接正文(供测试或工具链;失败返回 null)。
56
+ */
57
+ export function decodeForgeResumeInnerFromClaudeMd(content) {
58
+ const re = new RegExp(`<!-- forge:resume-begin:${RESUME_UUID} -->[\\s\\S]*?${FENCE_OPEN}\\n([\\s\\S]*?)\\n${FENCE_CLOSE}`, 'i');
59
+ const m = content.match(re);
60
+ if (!m)
61
+ return null;
62
+ const compact = m[1].replace(/\s+/g, '');
63
+ if (!compact)
64
+ return '';
65
+ try {
66
+ return Buffer.from(compact, 'base64url').toString('utf8');
67
+ }
68
+ catch {
69
+ return null;
70
+ }
71
+ }
72
+ //# sourceMappingURL=forge-resume-block.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forge-resume-block.js","sourceRoot":"","sources":["../../src/utils/forge-resume-block.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,iCAAiC;AACjC,MAAM,sBAAsB,GAAG,+DAA+D,CAAC;AAE/F,uDAAuD;AACvD,MAAM,WAAW,GAAG,8DAA8D,CAAC;AAEnF,SAAS,mBAAmB;IAC1B,OAAO,IAAI,MAAM,CACf,gCAAgC,WAAW,kDAAkD,EAC7F,IAAI,CACL,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,GAAG,sBAAsB,CAAC;AAC1C,MAAM,WAAW,GAAG,KAAK,CAAC;AAE1B;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,iBAAyB;IAChE,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;IACxB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACzE,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACrE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,OAAO;QACL,2BAA2B,EAAE,MAAM;QACnC,qFAAqF;QACrF,EAAE;QACF,UAAU;QACV,GAAG,KAAK;QACR,WAAW;QACX,EAAE;QACF,uBAAuB,GAAG,EAAE;QAC5B,yBAAyB,EAAE,MAAM;KAClC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,mBAAmB;AACnB,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,OAAO,CACL,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QACzC,IAAI,MAAM,CAAC,2BAA2B,WAAW,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CACvE,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAe;IACpD,IAAI,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,IAAI,CAAC,CAAC;IACrD,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACnC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kCAAkC,CAAC,OAAe;IAChE,MAAM,EAAE,GAAG,IAAI,MAAM,CACnB,2BAA2B,WAAW,iBAAiB,UAAU,qBAAqB,WAAW,EAAE,EACnG,GAAG,CACJ,CAAC;IACF,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC5B,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACzC,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}