feat: Context Ring 实时与压缩状态支持 - #169

Closed
gy212 wants to merge 4 commits into
op7418:mainfrom
gy212:codex/context-ring-review
Closed

feat: Context Ring 实时与压缩状态支持#169
gy212 wants to merge 4 commits into
op7418:mainfrom
gy212:codex/context-ring-review

Conversation

@gy212

@gy212gy212 commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

概述

  • MessageInput 增加 Context Ring:0–50% 绿、50–70% 黄、>70% 红
  • streaming 期间通过 message_start/context_tokens 实时刷新
  • auto-compaction 期间紫色旋转;compact_boundary 后灰色 stale,下一次 token 更新清除

测试

  • npm run test(Windows 本地因 claude-session-parser 的 ESM URL scheme 失败,需进一步处理)

@gy212
gy212force-pushed the codex/context-ring-review branch from 5291e71 to 2fab15fCompareMarch 5, 2026 10:19
@gy212gy212 changed the title fix(test): 解决 Windows 下 ESM 导入报错feat: Context Ring 实时与压缩状态支持Mar 5, 2026
@gy212
gy212force-pushed the codex/context-ring-review branch from 2fab15f to a64147cCompareMarch 5, 2026 10:22

@op7418op7418 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #169 Review: Context Ring 实时与压缩状态支持

总体评价

非常实用的功能,在输入框区域展示上下文 token 使用情况的环形进度条,并支持压缩状态显示。数据流设计合理,从 SDK 事件到 SSE 到前端状态的整条链路都考虑到了。

需要改进的地方

1. MessageInput 中内联了大量渲染逻辑
Context usage ring 的渲染使用了一个 IIFE (() => { ... })() 包裹了约 60 行代码直接内联在 JSX 中。建议提取为独立的 ContextUsageRing 组件,接收 contextTokensmaxContextisCompactingcontextStale 作为 props。这样也更便于单独测试和复用。

2. 颜色阈值硬编码

ratio>0.7 ? '#ef4444' : ratio>0.5 ? '#eab308' : '#22c55e'

建议使用 Tailwind CSS 变量或至少定义为常量,方便主题适配。直接用十六进制颜色会在暗色主题下可能有对比度问题。

3. contextTokens 的 useMemo 遍历所有消息

constcontextTokens=useMemo(()=>{for(leti=messages.length-1;i>=0;i--){ ... }},[messages]);

这个 memo 在每次 messages 数组引用变化时都会重新执行,但实际上只关心最后一条 assistant 消息的 token_usage。如果消息列表很长,反向遍历虽然效率尚可,但 messages 数组引用频繁变化(每次追加流式文本)会导致频繁重计算。建议考虑将 context token 信息直接通过 snapshot 传递,而非从消息列表反推。

4. sanitizeEnvValue 的 eslint-disable 注释被错误删除

- // eslint-disable-next-line no-control-regex+

删除了 ESLint disable 注释但保留了空行,后面的正则表达式 /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g 可能会触发 ESLint 的 no-control-regex 规则。如果项目已在 ESLint 配置中全局禁用了该规则则无影响,否则需要保留注释。

5. extractTokenUsage 中的 modelUsage 类型断言链较复杂

constmodelUsage=(msgasRecord<string,unknown>).modelUsageas ...

多层 as 断言降低了类型安全性。建议定义一个明确的接口来描述 SDK result message 的扩展字段,或者使用运行时类型检查。

6. spin 动画未定义
压缩状态使用了 animation: 'spin 1.5s linear infinite',但没有看到对应的 CSS @keyframes spin 定义。Tailwind 内置了 animate-spin,但直接在 inline style 中使用 spin 关键帧需要确保全局 CSS 中有定义。

7. 缺少单元测试
Context Ring 的状态计算逻辑(ratio 计算、token 格式化、颜色选择)可以用纯函数提取并编写单元测试。

优点

  • SSE 事件类型设计清晰(compact_boundarycompacting status、context_tokens
  • contextTokensPendingRefresh 状态处理了压缩后等待刷新的中间态
  • i18n 支持完整(en.ts 和 zh.ts 都已更新)
  • streamingContextTokenscontextWindow 的分层设计合理

@gy212gy212 closed this May 21, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@gy212@op7418@codex-automation
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: Context Ring 实时与压缩状态支持 - #169

Closed
gy212 wants to merge 4 commits into
op7418:mainfrom
gy212:codex/context-ring-review
Closed

feat: Context Ring 实时与压缩状态支持#169
gy212 wants to merge 4 commits into
op7418:mainfrom
gy212:codex/context-ring-review

Conversation

@gy212

@gy212gy212 commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

概述

  • MessageInput 增加 Context Ring:0–50% 绿、50–70% 黄、>70% 红
  • streaming 期间通过 message_start/context_tokens 实时刷新
  • auto-compaction 期间紫色旋转;compact_boundary 后灰色 stale,下一次 token 更新清除

测试

  • npm run test(Windows 本地因 claude-session-parser 的 ESM URL scheme 失败,需进一步处理)

@gy212
gy212force-pushed the codex/context-ring-review branch from 5291e71 to 2fab15fCompareMarch 5, 2026 10:19
@gy212gy212 changed the title fix(test): 解决 Windows 下 ESM 导入报错feat: Context Ring 实时与压缩状态支持Mar 5, 2026
@gy212
gy212force-pushed the codex/context-ring-review branch from 2fab15f to a64147cCompareMarch 5, 2026 10:22

@op7418op7418 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #169 Review: Context Ring 实时与压缩状态支持

总体评价

非常实用的功能,在输入框区域展示上下文 token 使用情况的环形进度条,并支持压缩状态显示。数据流设计合理,从 SDK 事件到 SSE 到前端状态的整条链路都考虑到了。

需要改进的地方

1. MessageInput 中内联了大量渲染逻辑
Context usage ring 的渲染使用了一个 IIFE (() => { ... })() 包裹了约 60 行代码直接内联在 JSX 中。建议提取为独立的 ContextUsageRing 组件,接收 contextTokensmaxContextisCompactingcontextStale 作为 props。这样也更便于单独测试和复用。

2. 颜色阈值硬编码

ratio>0.7 ? '#ef4444' : ratio>0.5 ? '#eab308' : '#22c55e'

建议使用 Tailwind CSS 变量或至少定义为常量,方便主题适配。直接用十六进制颜色会在暗色主题下可能有对比度问题。

3. contextTokens 的 useMemo 遍历所有消息

constcontextTokens=useMemo(()=>{for(leti=messages.length-1;i>=0;i--){ ... }},[messages]);

这个 memo 在每次 messages 数组引用变化时都会重新执行,但实际上只关心最后一条 assistant 消息的 token_usage。如果消息列表很长,反向遍历虽然效率尚可,但 messages 数组引用频繁变化(每次追加流式文本)会导致频繁重计算。建议考虑将 context token 信息直接通过 snapshot 传递,而非从消息列表反推。

4. sanitizeEnvValue 的 eslint-disable 注释被错误删除

- // eslint-disable-next-line no-control-regex+

删除了 ESLint disable 注释但保留了空行,后面的正则表达式 /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g 可能会触发 ESLint 的 no-control-regex 规则。如果项目已在 ESLint 配置中全局禁用了该规则则无影响,否则需要保留注释。

5. extractTokenUsage 中的 modelUsage 类型断言链较复杂

constmodelUsage=(msgasRecord<string,unknown>).modelUsageas ...

多层 as 断言降低了类型安全性。建议定义一个明确的接口来描述 SDK result message 的扩展字段,或者使用运行时类型检查。

6. spin 动画未定义
压缩状态使用了 animation: 'spin 1.5s linear infinite',但没有看到对应的 CSS @keyframes spin 定义。Tailwind 内置了 animate-spin,但直接在 inline style 中使用 spin 关键帧需要确保全局 CSS 中有定义。

7. 缺少单元测试
Context Ring 的状态计算逻辑(ratio 计算、token 格式化、颜色选择)可以用纯函数提取并编写单元测试。

优点

  • SSE 事件类型设计清晰(compact_boundarycompacting status、context_tokens
  • contextTokensPendingRefresh 状态处理了压缩后等待刷新的中间态
  • i18n 支持完整(en.ts 和 zh.ts 都已更新)
  • streamingContextTokenscontextWindow 的分层设计合理

@gy212gy212 closed this May 21, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@gy212@op7418@codex-automation
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Context Ring 实时与压缩状态支持 - #169

Closed
gy212 wants to merge 4 commits into
op7418:mainfrom
gy212:codex/context-ring-review
Closed

feat: Context Ring 实时与压缩状态支持#169
gy212 wants to merge 4 commits into
op7418:mainfrom
gy212:codex/context-ring-review

Conversation

@gy212

@gy212gy212 commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

概述

  • MessageInput 增加 Context Ring:0–50% 绿、50–70% 黄、>70% 红
  • streaming 期间通过 message_start/context_tokens 实时刷新
  • auto-compaction 期间紫色旋转;compact_boundary 后灰色 stale,下一次 token 更新清除

测试

  • npm run test(Windows 本地因 claude-session-parser 的 ESM URL scheme 失败,需进一步处理)

@gy212
gy212force-pushed the codex/context-ring-review branch from 5291e71 to 2fab15fCompareMarch 5, 2026 10:19
@gy212gy212 changed the title fix(test): 解决 Windows 下 ESM 导入报错feat: Context Ring 实时与压缩状态支持Mar 5, 2026
@gy212
gy212force-pushed the codex/context-ring-review branch from 2fab15f to a64147cCompareMarch 5, 2026 10:22

@op7418op7418 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #169 Review: Context Ring 实时与压缩状态支持

总体评价

非常实用的功能,在输入框区域展示上下文 token 使用情况的环形进度条,并支持压缩状态显示。数据流设计合理,从 SDK 事件到 SSE 到前端状态的整条链路都考虑到了。

需要改进的地方

1. MessageInput 中内联了大量渲染逻辑
Context usage ring 的渲染使用了一个 IIFE (() => { ... })() 包裹了约 60 行代码直接内联在 JSX 中。建议提取为独立的 ContextUsageRing 组件,接收 contextTokensmaxContextisCompactingcontextStale 作为 props。这样也更便于单独测试和复用。

2. 颜色阈值硬编码

ratio>0.7 ? '#ef4444' : ratio>0.5 ? '#eab308' : '#22c55e'

建议使用 Tailwind CSS 变量或至少定义为常量,方便主题适配。直接用十六进制颜色会在暗色主题下可能有对比度问题。

3. contextTokens 的 useMemo 遍历所有消息

constcontextTokens=useMemo(()=>{for(leti=messages.length-1;i>=0;i--){ ... }},[messages]);

这个 memo 在每次 messages 数组引用变化时都会重新执行,但实际上只关心最后一条 assistant 消息的 token_usage。如果消息列表很长,反向遍历虽然效率尚可,但 messages 数组引用频繁变化(每次追加流式文本)会导致频繁重计算。建议考虑将 context token 信息直接通过 snapshot 传递,而非从消息列表反推。

4. sanitizeEnvValue 的 eslint-disable 注释被错误删除

- // eslint-disable-next-line no-control-regex+

删除了 ESLint disable 注释但保留了空行,后面的正则表达式 /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g 可能会触发 ESLint 的 no-control-regex 规则。如果项目已在 ESLint 配置中全局禁用了该规则则无影响,否则需要保留注释。

5. extractTokenUsage 中的 modelUsage 类型断言链较复杂

constmodelUsage=(msgasRecord<string,unknown>).modelUsageas ...

多层 as 断言降低了类型安全性。建议定义一个明确的接口来描述 SDK result message 的扩展字段,或者使用运行时类型检查。

6. spin 动画未定义
压缩状态使用了 animation: 'spin 1.5s linear infinite',但没有看到对应的 CSS @keyframes spin 定义。Tailwind 内置了 animate-spin,但直接在 inline style 中使用 spin 关键帧需要确保全局 CSS 中有定义。

7. 缺少单元测试
Context Ring 的状态计算逻辑(ratio 计算、token 格式化、颜色选择)可以用纯函数提取并编写单元测试。

优点

  • SSE 事件类型设计清晰(compact_boundarycompacting status、context_tokens
  • contextTokensPendingRefresh 状态处理了压缩后等待刷新的中间态
  • i18n 支持完整(en.ts 和 zh.ts 都已更新)
  • streamingContextTokenscontextWindow 的分层设计合理

@gy212gy212 closed this May 21, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@gy212@op7418@codex-automation
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Context Ring 实时与压缩状态支持 - #169

Closed
gy212 wants to merge 4 commits into
op7418:mainfrom
gy212:codex/context-ring-review
Closed

feat: Context Ring 实时与压缩状态支持#169
gy212 wants to merge 4 commits into
op7418:mainfrom
gy212:codex/context-ring-review

Conversation

@gy212

@gy212gy212 commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

概述

  • MessageInput 增加 Context Ring:0–50% 绿、50–70% 黄、>70% 红
  • streaming 期间通过 message_start/context_tokens 实时刷新
  • auto-compaction 期间紫色旋转;compact_boundary 后灰色 stale,下一次 token 更新清除

测试

  • npm run test(Windows 本地因 claude-session-parser 的 ESM URL scheme 失败,需进一步处理)

@gy212
gy212force-pushed the codex/context-ring-review branch from 5291e71 to 2fab15fCompareMarch 5, 2026 10:19
@gy212gy212 changed the title fix(test): 解决 Windows 下 ESM 导入报错feat: Context Ring 实时与压缩状态支持Mar 5, 2026
@gy212
gy212force-pushed the codex/context-ring-review branch from 2fab15f to a64147cCompareMarch 5, 2026 10:22

@op7418op7418 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #169 Review: Context Ring 实时与压缩状态支持

总体评价

非常实用的功能,在输入框区域展示上下文 token 使用情况的环形进度条,并支持压缩状态显示。数据流设计合理,从 SDK 事件到 SSE 到前端状态的整条链路都考虑到了。

需要改进的地方

1. MessageInput 中内联了大量渲染逻辑
Context usage ring 的渲染使用了一个 IIFE (() => { ... })() 包裹了约 60 行代码直接内联在 JSX 中。建议提取为独立的 ContextUsageRing 组件,接收 contextTokensmaxContextisCompactingcontextStale 作为 props。这样也更便于单独测试和复用。

2. 颜色阈值硬编码

ratio>0.7 ? '#ef4444' : ratio>0.5 ? '#eab308' : '#22c55e'

建议使用 Tailwind CSS 变量或至少定义为常量,方便主题适配。直接用十六进制颜色会在暗色主题下可能有对比度问题。

3. contextTokens 的 useMemo 遍历所有消息

constcontextTokens=useMemo(()=>{for(leti=messages.length-1;i>=0;i--){ ... }},[messages]);

这个 memo 在每次 messages 数组引用变化时都会重新执行,但实际上只关心最后一条 assistant 消息的 token_usage。如果消息列表很长,反向遍历虽然效率尚可,但 messages 数组引用频繁变化(每次追加流式文本)会导致频繁重计算。建议考虑将 context token 信息直接通过 snapshot 传递,而非从消息列表反推。

4. sanitizeEnvValue 的 eslint-disable 注释被错误删除

- // eslint-disable-next-line no-control-regex+

删除了 ESLint disable 注释但保留了空行,后面的正则表达式 /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g 可能会触发 ESLint 的 no-control-regex 规则。如果项目已在 ESLint 配置中全局禁用了该规则则无影响,否则需要保留注释。

5. extractTokenUsage 中的 modelUsage 类型断言链较复杂

constmodelUsage=(msgasRecord<string,unknown>).modelUsageas ...

多层 as 断言降低了类型安全性。建议定义一个明确的接口来描述 SDK result message 的扩展字段,或者使用运行时类型检查。

6. spin 动画未定义
压缩状态使用了 animation: 'spin 1.5s linear infinite',但没有看到对应的 CSS @keyframes spin 定义。Tailwind 内置了 animate-spin,但直接在 inline style 中使用 spin 关键帧需要确保全局 CSS 中有定义。

7. 缺少单元测试
Context Ring 的状态计算逻辑(ratio 计算、token 格式化、颜色选择)可以用纯函数提取并编写单元测试。

优点

  • SSE 事件类型设计清晰(compact_boundarycompacting status、context_tokens
  • contextTokensPendingRefresh 状态处理了压缩后等待刷新的中间态
  • i18n 支持完整(en.ts 和 zh.ts 都已更新)
  • streamingContextTokenscontextWindow 的分层设计合理

@gy212gy212 closed this May 21, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@gy212@op7418@codex-automation
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: Context Ring 实时与压缩状态支持 - #169

Closed
gy212 wants to merge 4 commits into
op7418:mainfrom
gy212:codex/context-ring-review
Closed

feat: Context Ring 实时与压缩状态支持#169
gy212 wants to merge 4 commits into
op7418:mainfrom
gy212:codex/context-ring-review

Conversation

@gy212

@gy212gy212 commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

概述

  • MessageInput 增加 Context Ring:0–50% 绿、50–70% 黄、>70% 红
  • streaming 期间通过 message_start/context_tokens 实时刷新
  • auto-compaction 期间紫色旋转;compact_boundary 后灰色 stale,下一次 token 更新清除

测试

  • npm run test(Windows 本地因 claude-session-parser 的 ESM URL scheme 失败,需进一步处理)

@gy212
gy212force-pushed the codex/context-ring-review branch from 5291e71 to 2fab15fCompareMarch 5, 2026 10:19
@gy212gy212 changed the title fix(test): 解决 Windows 下 ESM 导入报错feat: Context Ring 实时与压缩状态支持Mar 5, 2026
@gy212
gy212force-pushed the codex/context-ring-review branch from 2fab15f to a64147cCompareMarch 5, 2026 10:22

@op7418op7418 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #169 Review: Context Ring 实时与压缩状态支持

总体评价

非常实用的功能,在输入框区域展示上下文 token 使用情况的环形进度条,并支持压缩状态显示。数据流设计合理,从 SDK 事件到 SSE 到前端状态的整条链路都考虑到了。

需要改进的地方

1. MessageInput 中内联了大量渲染逻辑
Context usage ring 的渲染使用了一个 IIFE (() => { ... })() 包裹了约 60 行代码直接内联在 JSX 中。建议提取为独立的 ContextUsageRing 组件,接收 contextTokensmaxContextisCompactingcontextStale 作为 props。这样也更便于单独测试和复用。

2. 颜色阈值硬编码

ratio>0.7 ? '#ef4444' : ratio>0.5 ? '#eab308' : '#22c55e'

建议使用 Tailwind CSS 变量或至少定义为常量,方便主题适配。直接用十六进制颜色会在暗色主题下可能有对比度问题。

3. contextTokens 的 useMemo 遍历所有消息

constcontextTokens=useMemo(()=>{for(leti=messages.length-1;i>=0;i--){ ... }},[messages]);

这个 memo 在每次 messages 数组引用变化时都会重新执行,但实际上只关心最后一条 assistant 消息的 token_usage。如果消息列表很长,反向遍历虽然效率尚可,但 messages 数组引用频繁变化(每次追加流式文本)会导致频繁重计算。建议考虑将 context token 信息直接通过 snapshot 传递,而非从消息列表反推。

4. sanitizeEnvValue 的 eslint-disable 注释被错误删除

- // eslint-disable-next-line no-control-regex+

删除了 ESLint disable 注释但保留了空行,后面的正则表达式 /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g 可能会触发 ESLint 的 no-control-regex 规则。如果项目已在 ESLint 配置中全局禁用了该规则则无影响,否则需要保留注释。

5. extractTokenUsage 中的 modelUsage 类型断言链较复杂

constmodelUsage=(msgasRecord<string,unknown>).modelUsageas ...

多层 as 断言降低了类型安全性。建议定义一个明确的接口来描述 SDK result message 的扩展字段,或者使用运行时类型检查。

6. spin 动画未定义
压缩状态使用了 animation: 'spin 1.5s linear infinite',但没有看到对应的 CSS @keyframes spin 定义。Tailwind 内置了 animate-spin,但直接在 inline style 中使用 spin 关键帧需要确保全局 CSS 中有定义。

7. 缺少单元测试
Context Ring 的状态计算逻辑(ratio 计算、token 格式化、颜色选择)可以用纯函数提取并编写单元测试。

优点

  • SSE 事件类型设计清晰(compact_boundarycompacting status、context_tokens
  • contextTokensPendingRefresh 状态处理了压缩后等待刷新的中间态
  • i18n 支持完整(en.ts 和 zh.ts 都已更新)
  • streamingContextTokenscontextWindow 的分层设计合理

@gy212gy212 closed this May 21, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@gy212@op7418@codex-automation
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Context Ring 实时与压缩状态支持 - #169

Closed
gy212 wants to merge 4 commits into
op7418:mainfrom
gy212:codex/context-ring-review
Closed

feat: Context Ring 实时与压缩状态支持#169
gy212 wants to merge 4 commits into
op7418:mainfrom
gy212:codex/context-ring-review

Conversation

@gy212

@gy212gy212 commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

概述

  • MessageInput 增加 Context Ring:0–50% 绿、50–70% 黄、>70% 红
  • streaming 期间通过 message_start/context_tokens 实时刷新
  • auto-compaction 期间紫色旋转;compact_boundary 后灰色 stale,下一次 token 更新清除

测试

  • npm run test(Windows 本地因 claude-session-parser 的 ESM URL scheme 失败,需进一步处理)

@gy212
gy212force-pushed the codex/context-ring-review branch from 5291e71 to 2fab15fCompareMarch 5, 2026 10:19
@gy212gy212 changed the title fix(test): 解决 Windows 下 ESM 导入报错feat: Context Ring 实时与压缩状态支持Mar 5, 2026
@gy212
gy212force-pushed the codex/context-ring-review branch from 2fab15f to a64147cCompareMarch 5, 2026 10:22

@op7418op7418 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #169 Review: Context Ring 实时与压缩状态支持

总体评价

非常实用的功能,在输入框区域展示上下文 token 使用情况的环形进度条,并支持压缩状态显示。数据流设计合理,从 SDK 事件到 SSE 到前端状态的整条链路都考虑到了。

需要改进的地方

1. MessageInput 中内联了大量渲染逻辑
Context usage ring 的渲染使用了一个 IIFE (() => { ... })() 包裹了约 60 行代码直接内联在 JSX 中。建议提取为独立的 ContextUsageRing 组件,接收 contextTokensmaxContextisCompactingcontextStale 作为 props。这样也更便于单独测试和复用。

2. 颜色阈值硬编码

ratio>0.7 ? '#ef4444' : ratio>0.5 ? '#eab308' : '#22c55e'

建议使用 Tailwind CSS 变量或至少定义为常量,方便主题适配。直接用十六进制颜色会在暗色主题下可能有对比度问题。

3. contextTokens 的 useMemo 遍历所有消息

constcontextTokens=useMemo(()=>{for(leti=messages.length-1;i>=0;i--){ ... }},[messages]);

这个 memo 在每次 messages 数组引用变化时都会重新执行,但实际上只关心最后一条 assistant 消息的 token_usage。如果消息列表很长,反向遍历虽然效率尚可,但 messages 数组引用频繁变化(每次追加流式文本)会导致频繁重计算。建议考虑将 context token 信息直接通过 snapshot 传递,而非从消息列表反推。

4. sanitizeEnvValue 的 eslint-disable 注释被错误删除

- // eslint-disable-next-line no-control-regex+

删除了 ESLint disable 注释但保留了空行,后面的正则表达式 /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g 可能会触发 ESLint 的 no-control-regex 规则。如果项目已在 ESLint 配置中全局禁用了该规则则无影响,否则需要保留注释。

5. extractTokenUsage 中的 modelUsage 类型断言链较复杂

constmodelUsage=(msgasRecord<string,unknown>).modelUsageas ...

多层 as 断言降低了类型安全性。建议定义一个明确的接口来描述 SDK result message 的扩展字段,或者使用运行时类型检查。

6. spin 动画未定义
压缩状态使用了 animation: 'spin 1.5s linear infinite',但没有看到对应的 CSS @keyframes spin 定义。Tailwind 内置了 animate-spin,但直接在 inline style 中使用 spin 关键帧需要确保全局 CSS 中有定义。

7. 缺少单元测试
Context Ring 的状态计算逻辑(ratio 计算、token 格式化、颜色选择)可以用纯函数提取并编写单元测试。

优点

  • SSE 事件类型设计清晰(compact_boundarycompacting status、context_tokens
  • contextTokensPendingRefresh 状态处理了压缩后等待刷新的中间态
  • i18n 支持完整(en.ts 和 zh.ts 都已更新)
  • streamingContextTokenscontextWindow 的分层设计合理

@gy212gy212 closed this May 21, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@gy212@op7418@codex-automation
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Context Ring 实时与压缩状态支持 - #169

Closed
gy212 wants to merge 4 commits into
op7418:mainfrom
gy212:codex/context-ring-review
Closed

feat: Context Ring 实时与压缩状态支持#169
gy212 wants to merge 4 commits into
op7418:mainfrom
gy212:codex/context-ring-review

Conversation

@gy212

@gy212gy212 commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

概述

  • MessageInput 增加 Context Ring:0–50% 绿、50–70% 黄、>70% 红
  • streaming 期间通过 message_start/context_tokens 实时刷新
  • auto-compaction 期间紫色旋转;compact_boundary 后灰色 stale,下一次 token 更新清除

测试

  • npm run test(Windows 本地因 claude-session-parser 的 ESM URL scheme 失败,需进一步处理)

@gy212
gy212force-pushed the codex/context-ring-review branch from 5291e71 to 2fab15fCompareMarch 5, 2026 10:19
@gy212gy212 changed the title fix(test): 解决 Windows 下 ESM 导入报错feat: Context Ring 实时与压缩状态支持Mar 5, 2026
@gy212
gy212force-pushed the codex/context-ring-review branch from 2fab15f to a64147cCompareMarch 5, 2026 10:22

@op7418op7418 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #169 Review: Context Ring 实时与压缩状态支持

总体评价

非常实用的功能,在输入框区域展示上下文 token 使用情况的环形进度条,并支持压缩状态显示。数据流设计合理,从 SDK 事件到 SSE 到前端状态的整条链路都考虑到了。

需要改进的地方

1. MessageInput 中内联了大量渲染逻辑
Context usage ring 的渲染使用了一个 IIFE (() => { ... })() 包裹了约 60 行代码直接内联在 JSX 中。建议提取为独立的 ContextUsageRing 组件,接收 contextTokensmaxContextisCompactingcontextStale 作为 props。这样也更便于单独测试和复用。

2. 颜色阈值硬编码

ratio>0.7 ? '#ef4444' : ratio>0.5 ? '#eab308' : '#22c55e'

建议使用 Tailwind CSS 变量或至少定义为常量,方便主题适配。直接用十六进制颜色会在暗色主题下可能有对比度问题。

3. contextTokens 的 useMemo 遍历所有消息

constcontextTokens=useMemo(()=>{for(leti=messages.length-1;i>=0;i--){ ... }},[messages]);

这个 memo 在每次 messages 数组引用变化时都会重新执行,但实际上只关心最后一条 assistant 消息的 token_usage。如果消息列表很长,反向遍历虽然效率尚可,但 messages 数组引用频繁变化(每次追加流式文本)会导致频繁重计算。建议考虑将 context token 信息直接通过 snapshot 传递,而非从消息列表反推。

4. sanitizeEnvValue 的 eslint-disable 注释被错误删除

- // eslint-disable-next-line no-control-regex+

删除了 ESLint disable 注释但保留了空行,后面的正则表达式 /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g 可能会触发 ESLint 的 no-control-regex 规则。如果项目已在 ESLint 配置中全局禁用了该规则则无影响,否则需要保留注释。

5. extractTokenUsage 中的 modelUsage 类型断言链较复杂

constmodelUsage=(msgasRecord<string,unknown>).modelUsageas ...

多层 as 断言降低了类型安全性。建议定义一个明确的接口来描述 SDK result message 的扩展字段,或者使用运行时类型检查。

6. spin 动画未定义
压缩状态使用了 animation: 'spin 1.5s linear infinite',但没有看到对应的 CSS @keyframes spin 定义。Tailwind 内置了 animate-spin,但直接在 inline style 中使用 spin 关键帧需要确保全局 CSS 中有定义。

7. 缺少单元测试
Context Ring 的状态计算逻辑(ratio 计算、token 格式化、颜色选择)可以用纯函数提取并编写单元测试。

优点

  • SSE 事件类型设计清晰(compact_boundarycompacting status、context_tokens
  • contextTokensPendingRefresh 状态处理了压缩后等待刷新的中间态
  • i18n 支持完整(en.ts 和 zh.ts 都已更新)
  • streamingContextTokenscontextWindow 的分层设计合理

@gy212gy212 closed this May 21, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@gy212@op7418@codex-automation
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: Context Ring 实时与压缩状态支持 - #169

Closed
gy212 wants to merge 4 commits into
op7418:mainfrom
gy212:codex/context-ring-review
Closed

feat: Context Ring 实时与压缩状态支持#169
gy212 wants to merge 4 commits into
op7418:mainfrom
gy212:codex/context-ring-review

Conversation

@gy212

@gy212gy212 commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

概述

  • MessageInput 增加 Context Ring:0–50% 绿、50–70% 黄、>70% 红
  • streaming 期间通过 message_start/context_tokens 实时刷新
  • auto-compaction 期间紫色旋转;compact_boundary 后灰色 stale,下一次 token 更新清除

测试

  • npm run test(Windows 本地因 claude-session-parser 的 ESM URL scheme 失败,需进一步处理)

@gy212
gy212force-pushed the codex/context-ring-review branch from 5291e71 to 2fab15fCompareMarch 5, 2026 10:19
@gy212gy212 changed the title fix(test): 解决 Windows 下 ESM 导入报错feat: Context Ring 实时与压缩状态支持Mar 5, 2026
@gy212
gy212force-pushed the codex/context-ring-review branch from 2fab15f to a64147cCompareMarch 5, 2026 10:22

@op7418op7418 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #169 Review: Context Ring 实时与压缩状态支持

总体评价

非常实用的功能,在输入框区域展示上下文 token 使用情况的环形进度条,并支持压缩状态显示。数据流设计合理,从 SDK 事件到 SSE 到前端状态的整条链路都考虑到了。

需要改进的地方

1. MessageInput 中内联了大量渲染逻辑
Context usage ring 的渲染使用了一个 IIFE (() => { ... })() 包裹了约 60 行代码直接内联在 JSX 中。建议提取为独立的 ContextUsageRing 组件,接收 contextTokensmaxContextisCompactingcontextStale 作为 props。这样也更便于单独测试和复用。

2. 颜色阈值硬编码

ratio>0.7 ? '#ef4444' : ratio>0.5 ? '#eab308' : '#22c55e'

建议使用 Tailwind CSS 变量或至少定义为常量,方便主题适配。直接用十六进制颜色会在暗色主题下可能有对比度问题。

3. contextTokens 的 useMemo 遍历所有消息

constcontextTokens=useMemo(()=>{for(leti=messages.length-1;i>=0;i--){ ... }},[messages]);

这个 memo 在每次 messages 数组引用变化时都会重新执行,但实际上只关心最后一条 assistant 消息的 token_usage。如果消息列表很长,反向遍历虽然效率尚可,但 messages 数组引用频繁变化(每次追加流式文本)会导致频繁重计算。建议考虑将 context token 信息直接通过 snapshot 传递,而非从消息列表反推。

4. sanitizeEnvValue 的 eslint-disable 注释被错误删除

- // eslint-disable-next-line no-control-regex+

删除了 ESLint disable 注释但保留了空行,后面的正则表达式 /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g 可能会触发 ESLint 的 no-control-regex 规则。如果项目已在 ESLint 配置中全局禁用了该规则则无影响,否则需要保留注释。

5. extractTokenUsage 中的 modelUsage 类型断言链较复杂

constmodelUsage=(msgasRecord<string,unknown>).modelUsageas ...

多层 as 断言降低了类型安全性。建议定义一个明确的接口来描述 SDK result message 的扩展字段,或者使用运行时类型检查。

6. spin 动画未定义
压缩状态使用了 animation: 'spin 1.5s linear infinite',但没有看到对应的 CSS @keyframes spin 定义。Tailwind 内置了 animate-spin,但直接在 inline style 中使用 spin 关键帧需要确保全局 CSS 中有定义。

7. 缺少单元测试
Context Ring 的状态计算逻辑(ratio 计算、token 格式化、颜色选择)可以用纯函数提取并编写单元测试。

优点

  • SSE 事件类型设计清晰(compact_boundarycompacting status、context_tokens
  • contextTokensPendingRefresh 状态处理了压缩后等待刷新的中间态
  • i18n 支持完整(en.ts 和 zh.ts 都已更新)
  • streamingContextTokenscontextWindow 的分层设计合理

@gy212gy212 closed this May 21, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@gy212@op7418@codex-automation