docs: record spike 2 results, add spike 1/3 manual scripts

Spike 2 (data source) completed:
- All SQLite threads fields verified stable (model, cwd, git_branch, tokens_used)
- JSONL event names stable across 2 sessions (function_call, task_started, token_count, etc.)
- Bonus: token_count event has rate_limits.primary/secondary.used_percent and plan_type
- HudState updated with rateLimitPrimary, rateLimitSecondary, planType fields

Spike 1 (pane mode): pending - tmux not installed, manual steps documented
Spike 3 (inline): pending - needs real TTY, test script provided

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
manpengan
2026-03-22 09:05:37 +08:00
parent ebaf9c8f9a
commit befc86acaa

View File

@@ -140,6 +140,11 @@ type HudState = {
toolCounts: Record<string, number>
taskProgress: { done: number; total: number } | null
// from JSONL token_count event (bonus: rate limit data)
rateLimitPrimary: { usedPercent: number; windowMinutes: number; resetsAt: number } | null
rateLimitSecondary: { usedPercent: number; windowMinutes: number; resetsAt: number } | null
planType: string | null // "plus" | "pro" | "team" | ...
// from timer
elapsedSec: number
@@ -360,6 +365,14 @@ inline 初始化失败 --> 自动降级到 passthrough mode
> 这三个 spike 必须在写 implementation plan 之前完成。每个 spike 是独立的小脚本或手工验证,目标是锁定架构假设,不是实现功能。
**Spike 状态总览2026-03-22**
| Spike | 状态 | 结论 |
|-------|------|------|
| Spike 1: Pane Mode Capability | 待手工验证 | tmux 未安装,需先安装再测 |
| Spike 2: Data Source Stability | **已完成** | SQLite + JSONL 均稳定可依赖,有额外 rate limit 发现 |
| Spike 3: Inline Fallback Safety | 待手工验证 | 需在真实 TTY 中运行测试脚本 |
---
### Spike 1: Pane Mode Capability
@@ -391,6 +404,9 @@ codex
- 探测不可靠 → pane mode 进入条件收紧,宁可误降级到 inline 也不误进 pane
- kill-pane 不可靠 → pane 生命周期改为"codex 退出时发送信号给 HUD 子进程HUD 进程自行退出"
**当前状态2026-03-22tmux 未安装,待手工验证。**
手工步骤:`brew install tmux` → 在 tmux session 内运行上述验证命令 → 记录结论。
---
### Spike 2: Data Source Stability
@@ -434,6 +450,54 @@ tail -f ~/.codex/sessions/$(date +%Y/%m/%d)/rollout-*.jsonl | \
---
### Spike 2 结论已完成2026-03-22
**SQLite `threads` 表 — 全部字段已验证稳定:**
| 字段 | 实测值样本 | 结论 |
|------|-----------|------|
| `model` | `gpt-5.4` | 稳定session 开始时写入 |
| `cwd` | `/Users/manpengan/pro/nas-infra` | 稳定,准确 |
| `git_branch` | `main` / 空字符串(非 git 目录) | 稳定,非 git 目录为空字符串 |
| `tokens_used` | `710865`, `6413335` | 稳定递增,线程累计值 |
| `updated_at` | Unix timestamp | 每轮对话更新 |
**JSONL 事件 — 跨 2 个 session 验证,事件名稳定:**
| event 类型 | payload.type | 关键字段 | HUD 用途 |
|-----------|--------------|----------|----------|
| `session_meta` | — | `cwd`, `cli_version`, `model_provider` | session 初始化 |
| `event_msg` | `task_started` | `turn_id`, `model_context_window: 258400` | turn 开始context window 大小 |
| `event_msg` | `task_complete` | `turn_id`, `last_agent_message` | turn 结束 |
| `event_msg` | `token_count` | `rate_limits.primary.used_percent`, `secondary.used_percent`, `plan_type` | **rate limit 显示** |
| `event_msg` | `agent_message` | `message`, `phase` | agent 回复内容 |
| `response_item` | `function_call` | `name`(工具名), `call_id` | tool 开始 |
| `response_item` | `function_call_output` | `call_id`(匹配) | tool 结束 |
| `response_item` | `reasoning` | 内部推理 | 可忽略 |
| `turn_context` | — | `cwd`, `timezone`, `approval_policy` | 每轮上下文 |
**额外发现(超出原预期):**
- `token_count.rate_limits` 直接给出 `primary.used_percent`5分钟窗口和 `secondary.used_percent`(周窗口)
- 这是 claude-hud 需要单独调用 OAuth API 才能拿到的数据Codex 直接写在 JSONL 里
- `model_context_window: 258400` 给出每个 turn 的 context 窗口大小
**结论对 HudState 的影响:**
- `tokensUsedTotal`:来自 SQLite `threads.tokens_used`,可信
- `rateLimitPrimary` / `rateLimitSecondary`:来自 `token_count` JSONL 事件,可信(**新增字段**
- `activeTool`:来自 `function_call` / `function_call_output` 配对,可信
- `taskProgress`:无直接字段,需从 `task_started`/`task_complete` 事件计数推断
- context window usage`model_context_window` 大小已知,但当前 turn 的 input token 数暂未找到来源
**更新后的 HudState在 Section 4.2 中同步):**
```typescript
// 新增字段(来自 token_count 事件)
rateLimitPrimary: { usedPercent: number; windowMinutes: number; resetsAt: number } | null
rateLimitSecondary: { usedPercent: number; windowMinutes: number; resetsAt: number } | null
planType: string | null // "plus" | "pro" | ...
```
---
### Spike 3: Inline Fallback Safety
**目标:** 确认 `codex --no-alt-screen` 下能预留底部区域,且 wrapper crash/exit 后不会弄脏终端。
@@ -472,6 +536,36 @@ setTimeout(() => {
- scroll region 在任一目标终端不稳定 → inline mode 标记为"实验性",默认不启用,需 `--inline` flag 显式开启
- cleanup 不可靠 → cleanup 逻辑改为双重保险:正常路径 + `process.on('exit')` 兜底
**当前状态2026-03-22需在真实 TTY 中手工验证。**
在真实终端(非 Claude Code 子 shell中运行
```bash
# 保存到 /tmp/spike3.mjs 后执行node /tmp/spike3.mjs
const rows = process.stdout.rows;
const cols = process.stdout.columns;
if (!rows) { console.error('Not a TTY'); process.exit(1); }
console.log(`Terminal: ${cols}x${rows}`);
process.stdout.write('\x1b[s');
process.stdout.write(`\x1b[1;${rows - 4}r`);
process.stdout.write(`\x1b[${rows - 3};1H\x1b[2K=== HUD 1: model | cwd | main* | 2m ===`);
process.stdout.write(`\x1b[${rows - 2};1H\x1b[2K=== HUD 2: tokens 12,340 | Write 3s ===`);
process.stdout.write(`\x1b[${rows - 1};1H\x1b[2K=== HUD 3: shell(3) read(7) ===`);
process.stdout.write(`\x1b[${rows};1H\x1b[2K=== HUD 4: task 3/5 ===`);
process.stdout.write('\x1b[u');
setTimeout(() => {
process.stdout.write('\x1b[r');
for (let i = rows - 3; i <= rows; i++)
process.stdout.write(`\x1b[${i};1H\x1b[2K`);
process.stdout.write(`\x1b[${rows};1H`);
console.log('\nCLEANUP OK');
}, 3000);
```
通过标准:
- HUD 4 行固定在底部,主区域可自由滚动
- 3 秒后自动清除,光标恢复,终端无残留
- 在 macOS Terminal.app / iTerm2 / Ghostty 中各测一次
---
**三个 spike 全部通过后,才进入 implementation plan。**