@winspan/claude-forge 1.16.2 → 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.
@@ -4,11 +4,7 @@ import { SessionStateMachine } from './state-machine.js';
4
4
  import { TIME } from '../constants.js';
5
5
  import { ResumeContextGenerator } from './context-gen.js';
6
6
  import { logger } from '../utils/logger.js';
7
- const RESUME_START = '<!-- forge:resume -->';
8
- const RESUME_END = '<!-- forge:end-resume -->';
9
- function escapeRegex(s) {
10
- return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
11
- }
7
+ import { buildForgeResumeEnvelope, hasForgeResumeBlock, stripForgeResumeBlocks, } from '../utils/forge-resume-block.js';
12
8
  export class ResumeEngine {
13
9
  storage;
14
10
  stateMachine;
@@ -67,7 +63,7 @@ export class ResumeEngine {
67
63
  const claudeMdPath = path.join(projectPath, 'CLAUDE.md');
68
64
  if (fs.existsSync(claudeMdPath)) {
69
65
  const content = fs.readFileSync(claudeMdPath, 'utf-8');
70
- if (content.includes(RESUME_START)) {
66
+ if (hasForgeResumeBlock(content)) {
71
67
  logger.info('续接上下文已存在(来自 saveOnStop)');
72
68
  return true;
73
69
  }
@@ -94,21 +90,34 @@ export class ResumeEngine {
94
90
  */
95
91
  async clearResumeBlock(projectPath) {
96
92
  await this.claudeMdWriter.atomicWrite(projectPath, (content) => {
97
- const blockRegex = new RegExp(`\\n*${escapeRegex(RESUME_START)}[\\s\\S]*?${escapeRegex(RESUME_END)}\\n*`, 'g');
98
- const cleaned = content.replace(blockRegex, '\n').replace(/\n{4,}/g, '\n\n\n').trimEnd() + '\n';
99
- if (cleaned !== content) {
93
+ const hadBlock = hasForgeResumeBlock(content);
94
+ const cleaned = stripForgeResumeBlocks(content) + '\n';
95
+ if (hadBlock) {
100
96
  logger.info('CLAUDE.md 中的续接区块已清除');
101
97
  }
102
98
  return cleaned;
103
99
  });
104
100
  }
105
101
  async injectToClaudeMd(projectPath, context) {
106
- const resumeBlock = `${RESUME_START}\n## 上次工作续接\n\n${context}\n<!-- generated_at: ${new Date().toISOString()} -->\n${RESUME_END}`;
102
+ // 过滤掉明显的 assistant 回复模式,防止污染 CLAUDE.md
103
+ const filteredContext = context
104
+ .split('\n')
105
+ .filter(line => {
106
+ const lower = line.toLowerCase();
107
+ // 过滤掉典型的 assistant 对话性回复
108
+ return !/看起来是误触|是有什么想说的|有什么需要帮忙|让我帮你|我来帮你|我正在|我已经/.test(lower);
109
+ })
110
+ .join('\n')
111
+ .trim();
112
+ if (!filteredContext) {
113
+ logger.info('[Resume] 过滤后内容为空,跳过注入');
114
+ return;
115
+ }
116
+ const innerMd = `## 上次工作续接\n\n${filteredContext}`;
117
+ const resumeBlock = buildForgeResumeEnvelope(innerMd);
107
118
  await this.claudeMdWriter.atomicWrite(projectPath, (content) => {
108
- // 删除所有已有的 resume 块,再追加唯一的新块
109
- const blockRegex = new RegExp(`\\n*${escapeRegex(RESUME_START)}[\\s\\S]*?${escapeRegex(RESUME_END)}\\n*`, 'g');
110
- content = content.replace(blockRegex, '\n').replace(/\n{4,}/g, '\n\n\n').trimEnd();
111
- return content + '\n\n' + resumeBlock + '\n';
119
+ const base = stripForgeResumeBlocks(content);
120
+ return base + '\n\n' + resumeBlock + '\n';
112
121
  });
113
122
  }
114
123
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resume/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resume/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * 构造续接信封:外层用 UUID 配对注释定界,正文 UTF-8 经 base64url 放入专用 fence,
3
+ * 正文中任意 `<!--`、`-->`、`forge:*` 均不可能破坏块边界解析。
4
+ */
5
+ export declare function buildForgeResumeEnvelope(innerUtf8Markdown: string): string;
6
+ /** 是否包含旧版或新版续接块 */
7
+ export declare function hasForgeResumeBlock(content: string): boolean;
8
+ /**
9
+ * 移除全部续接块(新版 UUID 信封 + 旧版裸正文),并压缩多余空行。
10
+ */
11
+ export declare function stripForgeResumeBlocks(content: string): string;
12
+ /**
13
+ * 从 CLAUDE.md 文本中解码第一处新版续接正文(供测试或工具链;失败返回 null)。
14
+ */
15
+ export declare function decodeForgeResumeInnerFromClaudeMd(content: string): string | null;
16
+ //# sourceMappingURL=forge-resume-block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forge-resume-block.d.ts","sourceRoot":"","sources":["../../src/utils/forge-resume-block.ts"],"names":[],"mappings":"AA0BA;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAiB1E;AAED,mBAAmB;AACnB,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAK5D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAK9D;AAED;;GAEG;AACH,wBAAgB,kCAAkC,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAcjF"}
@@ -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"}