首页
/ Session: YYYY-MM-DD

Session: YYYY-MM-DD

2026-09-07 14:00:11作者:咎竹峻Karen

Started: [approximate time if known] Last Updated: [current time] Project: [project name or path] Topic: [one-line summary of what this session was about]


What We Are Building

[1-3 paragraphs describing the feature, bug fix, or task. Include enough context that someone with zero memory of this session can understand the goal. Include: what it does, why it's needed, how it fits into the larger system.]


What WORKED (with evidence)

[List only things that are confirmed working. For each item include WHY you know it works — test passed, ran in browser, Postman returned 200, etc. Without evidence, move it to "Not Tried Yet" instead.]

  • [thing that works] — confirmed by: [specific evidence]
  • [thing that works] — confirmed by: [specific evidence]

If nothing is confirmed working yet: "Nothing confirmed working yet — all approaches still in progress or untested."


What Did NOT Work (and why)

[This is the most important section. List every approach tried that failed. For each failure write the EXACT reason so the next session doesn't retry it. Be specific: "threw X error because Y" is useful. "didn't work" is not.]

  • [approach tried] — failed because: [exact reason / error message]
  • [approach tried] — failed because: [exact reason / error message]

If nothing failed: "No failed approaches yet."


What Has NOT Been Tried Yet

[Approaches that seem promising but haven't been attempted. Ideas from the conversation. Alternative solutions worth exploring. Be specific enough that the next session knows exactly what to try.]

  • [approach / idea]
  • [approach / idea]

If nothing is queued: "No specific untried approaches identified."


Current State of Files

[Every file touched this session. Be precise about what state each file is in.]

File Status Notes
path/to/file.ts PASS: Complete [what it does]
path/to/file.ts In Progress [what's done, what's left]
path/to/file.ts FAIL: Broken [what's wrong]
path/to/file.ts Not Started [planned but not touched]

If no files were touched: "No files modified this session."


Decisions Made

[Architecture choices, tradeoffs accepted, approaches chosen and why. These prevent the next session from relitigating settled decisions.]

  • [decision] — reason: [why this was chosen over alternatives]

If no significant decisions: "No major decisions made this session."


Blockers & Open Questions

[Anything unresolved that the next session needs to address or investigate. Questions that came up but weren't answered. External dependencies waiting on.]

  • [blocker / open question]

If none: "No active blockers."


Exact Next Step

[If known: The single most important thing to do when resuming. Be precise enough that resuming requires zero thinking about where to start.]

[If not known: "Next step not determined — review 'What Has NOT Been Tried Yet' and 'Blockers' sections to decide on direction before starting."]


Environment & Setup Notes

[Only fill this if relevant — commands needed to run the project, env vars required, services that need to be running, etc. Skip if standard setup.]

[If none: omit this section entirely.]


这套结构并非随意设计:会话头部与正文中的结构化章节会被 [session-manager.js 的 `parseSessionMetadata`](https://gitcode.com/GitHub_Trending/ev/ECC/blob/22e8cf01d0b54719b3a49002fab2ccbda4ff5b9e/scripts/lib/session-manager.js?utm_source=gitcode_repo_files) 用正则解析出 `title`、`date`、`started`、`lastUpdated`、`project`、`branch`、`worktree`、`completed`、`inProgress`、`notes`、`context` 等元数据。也就是说,保存时的排版越规范,后续 `/sessions list`、`/sessions info` 能提取的信息就越丰富。

## 参考示例输出

以下是命令文档中展示的一份 JWT 认证开发会话的完整示例,可作为填写各类章节的对照样本:

```markdown
# Session: 2024-01-15

**Started:** ~2pm
**Last Updated:** 5:30pm
**Project:** my-app
**Topic:** Building JWT authentication with httpOnly cookies

---

## What We Are Building

User authentication system for the Next.js app. Users register with email/password,
receive a JWT stored in an httpOnly cookie (not localStorage), and protected routes
check for a valid token via middleware. The goal is session persistence across browser
refreshes without exposing the token to JavaScript.

---

## What WORKED (with evidence)

- **`/api/auth/register` endpoint** — confirmed by: Postman POST returns 200 with user
  object, row visible in Supabase dashboard, bcrypt hash stored correctly
- **JWT generation in `lib/auth.ts`** — confirmed by: unit test passes
  (`npm test -- auth.test.ts`), decoded token at jwt.io shows correct payload
- **Password hashing** — confirmed by: `bcrypt.compare()` returns true in test

---

## What Did NOT Work (and why)

- **Next-Auth library** — failed because: conflicts with our custom Prisma adapter,
  threw "Cannot use adapter with credentials provider in this configuration" on every
  request. Not worth debugging — too opinionated for our setup.
- **Storing JWT in localStorage** — failed because: SSR renders happen before
  localStorage is available, caused React hydration mismatch error on every page load.
  This approach is fundamentally incompatible with Next.js SSR.

---

## What Has NOT Been Tried Yet

- Store JWT as httpOnly cookie in the login route response (most likely solution)
- Use `cookies()` from `next/headers` to read token in server components
- Write middleware.ts to protect routes by checking cookie existence

---

## Current State of Files

| File                             | Status         | Notes                                           |
| -------------------------------- | -------------- | ----------------------------------------------- |
| `app/api/auth/register/route.ts` | PASS: Complete    | Works, tested                                   |
| `app/api/auth/login/route.ts`    |  In Progress | Token generates but not setting cookie yet      |
| `lib/auth.ts`                    | PASS: Complete    | JWT helpers, all tested                         |
| `middleware.ts`                  |  Not Started | Route protection, needs cookie read logic first |
| `app/login/page.tsx`             |  Not Started | UI not started                                  |

---

## Decisions Made

- **httpOnly cookie over localStorage** — reason: prevents XSS token theft, works with SSR
- **Custom auth over Next-Auth** — reason: Next-Auth conflicts with our Prisma setup, not worth the fight

---

## Blockers & Open Questions

- Does `cookies().set()` work inside a Route Handler or only in Server Actions? Need to verify.

---

## Exact Next Step

In `app/api/auth/login/route.ts`, after generating the JWT, set it as an httpOnly
cookie using `cookies().set('token', jwt, { httpOnly: true, secure: true, sameSite: 'strict' })`.
Then test with Postman — the response should include a `Set-Cookie` header.

注意示例中 "What Did NOT Work" 的写法原则:必须写精确原因("threw X error because Y"),而不是笼统的 "didn't work"——后者对下一个会话毫无价值。

存储位置与目录解析:从 ~/.claude/session-data 到 ECC_AGENT_DATA_HOME

命令文档约定存储位置为 ~/.claude/session-data/。从源码看,这一路径由 scripts/lib/utils.jsgetSessionsDir()path.join(getClaudeDir(), 'session-data'))解析得出,而 getClaudeDir() 实际代理到 scripts/lib/agent-data-home.jsresolveAgentDataHome(),其解析优先级为:

  1. 环境变量 ECC_AGENT_DATA_HOME(显式可信覆盖);
  2. 项目级配置 .cursor/ecc-agent-data.json 中声明的 agentDataHome / ECC_AGENT_DATA_HOME 字段(必须是 ~ 锚定或绝对路径,且不允许 .. 穿越,并通过 assertWithinTrustedRoot 校验仍处于默认 Cursor / Claude 数据目录内);
  3. 运行环境判定:Cursor hook 运行时(检测 CURSOR_VERSION / CURSOR_PROJECT_DIR)回落到 ~/.cursor/ecc,其余默认 ~/.claude

因此命令文档中 "canonical sessions folder in the user's Claude home directory" 的说法,在跨 harness(Cursor、Codex、Opencode)部署时会解析到对应 agent 数据主目录下的 session-data/ 子目录。

同时,读取侧保持向后兼容:getSessionSearchDirs() 返回 [getSessionsDir(), getLegacySessionsDir()] 的去重数组,其中旧目录为 ~/.claude/sessions。这正是 commands/resume-session.md 中"legacy format 文件也能被加载"以及 /sessions 支持"legacy reads from ~/.claude/sessions/"的底层原因。写入新会话文件时仍应使用 ~/.claude/session-data/ 这一规范目录。

文件名合法性的正则实现与日历级校验

会话文件命名并非仅靠文档约定——session-manager.js 顶部声明的正则对每种命名形态都有精确对应:

const SESSION_FILENAME_REGEX = /^(\d{4}-\d{2}-\d{2})(?:-([a-zA-Z0-9_][a-zA-Z0-9_-]*))?-session\.tmp$/;

逐段拆解可以看到命名约束的严谨之处:

  • (\d{4}-\d{2}-\d{2}):日期部分,YYYY-MM-DD
  • (?:-([a-zA-Z0-9_][a-zA-Z0-9_-]*))?:整个 short-id 段可选(兼容旧格式);short-id 第一个字符必须是字母、数字或下划线(不能以连字符开头),其后可跟字母、数字、下划线、连字符;
  • -session\.tmp$:固定后缀。

该正则能匹配 2026-02-01-session.tmp2026-02-01-a1b2c3d4-session.tmp2026-02-01-frontend-worktree-1-session.tmp2026-02-01-ChezMoi_2-session.tmp 四类文件名——frontend-worktree-1 之所以合法,正是因为后续连字符段由 [a-zA-Z0-9_-]* 承接。

更值得注意的是日期校验并不停留在格式层。parseSessionFilename() 会额外做日历准确性校验:月份必须在 1-12、日期必须在 1-31,然后构造 new Date(year, month - 1, day) 并反向核对 getMonth()/getDate(),以剔除诸如 2 月 31 日、4 月 31 日这类会被 Date 自动"滚过去"的非法日期。文件头解析日期时还刻意使用本地时间构造函数 new Date(year, month - 1, day) 而非 new Date(dateStr),避免负 UTC 时区下日期"显示成前一天"的问题。这些边界行为在 tests/lib/session-manager.test.js 中有成体系的用例覆盖,例如 rejects Feb 31 (calendar-inaccurate date)rejects Feb 29 in non-leap yearaccepts Feb 29 in leap yearaccepts uppercase letters in short IDaccepts underscores in short ID 等。

底层读写与去重排序逻辑

会话文件的 CRUD 全部封装在 scripts/lib/session-manager.js 的导出函数中,save-session 的"写文件"动作对应其中:

  • writeSessionContent(sessionPath, content):以 utf8 同步写入;
  • appendSessionContent(sessionPath, content):追加内容(供会话中途追加保存场景使用);
  • sessionExists(sessionPath):判断会话是否已存在;
  • deleteSession(sessionPath):删除会话文件。

读取侧的关键设计是多目录扫描 + 去重 + 排序

  • getSessionCandidates() 遍历 getSessionSearchDirs()(规范目录优先),仅收集 .tmp 后缀且能通过文件名解析的文件;
  • 文件系统细节上,创建时间优先取 birthtime,当 birthtimeMs 为 0(如容器 overlayfs 环境)时回退到 ctime
  • 按文件名去重(规范目录条目优先,即便 legacy 副本更新也会被规范目录条目覆盖,测试用例 getAllSessions prefers canonical session-data duplicates over newer legacy copies 即验证此行为);
  • 最终按 modifiedTime 降序排列。

getSessionById() 的匹配方式也相当宽松:short-id 支持前缀匹配(metadata.shortId.startsWith(normalizedSessionId)),同时还支持传完整文件名、去掉 .tmp 的文件名,以及旧格式无 ID 文件的 YYYY-MM-DD-session.tmp 精确匹配。因此 /resume-session 2024-01-15/resume-session a1b2 这类模糊用法都能命中目标。

与 /resume-session 配对:保存之后如何续接

保存的最终目的是续接。在 ECC 中,续接入口是 commands/resume-session.md(与 /save-session 互为配套命令),其加载行为与 save-session 的文件结构严格咬合:

  • 无参数:默认读取 session-data 中最新的实质会话文件;
  • 传日期 YYYY-MM-DD:先搜 session-data、再搜 legacy sessions,应用候选排序后取当日最高排名文件;
  • 传文件路径:原样精确读取该文件,不参与候选排序、不被其他更新文件替代。

续接前会对自动发现(非显式路径)的候选做内容质量排名:先剔除空文件、纯占位符文件(如只有 headings / metadata / [Session context goes here] / 孤立的 - [ ])以及"仅含单一任务且无实质填充字段"的摘要回声;随后在实质候选间按修改时间取新,时间相同时依次比较填充章节数、非占位内容量、字节数、字典序更小的解析路径,从而让选择结果可确定。这解释了 save-session 文档为何反复强调"每个章节都要诚实填写"——文件不完整,续接时就会被排名机制淘汰。

恢复时,Agent 会以固定简报格式输出 SESSION LOADED、PROJECT、WHAT WE'RE BUILDING、CURRENT STATE、WHAT NOT TO RETRY、OPEN QUESTIONS / BLOCKERS、NEXT STEP,然后等待用户指令,绝不自动动工。其中 "What Not To Retry" 被刻意要求必须展示(即使为空)——与保存模板中 "What Did NOT Work (and why) 是最重要章节" 的定位前后呼应,因为"失败原因"是防止未来会话盲目重试失败方案的关键护栏。

保存与恢复的另一条纪律是:续接时只读、绝不修改历史会话文件,它是一份只读历史记录;新会话结束时应再次运行 /save-session 生成一份新的带日期文件,而不是追加到旧文件。

会话的日常管理与别名

session-data 中的文件积累变多后,可用 commands/sessions.md 管理会话历史(列表、加载、别名、信息、删除别名)。其常用命令:

/sessions                                # 列出全部会话(默认)
/sessions list --limit 10                # 仅显示 10 条
/sessions list --date 2026-02-01         # 按日期过滤
/sessions list --search abc              # 按会话 ID 搜索
/sessions load a1b2c3d4                  # 按 short ID 加载(前缀足够短也常可用)
/sessions alias 2026-02-01 today         # 给会话创建别名
/sessions load today                     # 按别名加载
/sessions info today                     # 显示会话统计
/sessions alias --remove today           # 删除别名
/sessions aliases                        # 列出全部别名
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391