mcpField
C
copilot-history-ingest

copilot-history-ingest

github.com/ar9av生产力3.6k1.8k 次安装2 天前更新
代码仓库

关于 copilot-history-ingest

用于从 GitHub Copilot CLI 与 VS Code 对话记录中提炼知识并写入 Obsidian Wiki 的技能,适合整理项目经验的用户。它合并多种会话数据源,按主题归纳知识,而非逐条复制对话。

主要功能

  1. 01扫描 CLI、数据库与 VS Code 数据
  2. 02依据清单处理新增或变更会话
  3. 03优先整理检查点与会话摘要
  4. 04跨会话按主题归纳知识
  5. 05将内容写入项目或全局 Wiki 页面

适用场景

  1. 01把 Copilot 会话中的项目决策整理成概念页
  2. 02汇总多个会话反复出现的调试方法
  3. 03从会话文件访问记录识别重要文件
  4. 04将保存的计划文档纳入 Wiki

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ar9av/obsidian-wiki --skill copilot-history-ingest

安装后在 Claude Code 中输入/copilot-history-ingest确认已加载。

附带文件references/copilot-data-format.md

详细介绍

Copilot History Ingest — 对话挖掘

从用户过去的 GitHub Copilot CLI 对话中提取知识,并将其提炼到 Obsidian 知识库中。对话内容丰富,但较为杂乱——你的任务是找出有价值的信息并加以整理。

可以直接调用此技能,也可以通过 wiki-history-ingest 路由器调用(/wiki-history-ingest copilot)。

开始之前

写作风格: 在起草或改写自然语言 Markdown 之前,请阅读并应用 llm-wiki/SKILL.md 中的 Writing Profile Resolution 部分。框架架构、来源溯源、安全规范和特定操作要求优先适用。 WRITING.md 中的偏好仅适用于新起草或改写的自然语言 Markdown;保留源内容和结构化记录。

  1. 解析配置 — 遵循 llm-wiki/SKILL.md 中的 Config Resolution Protocol(内联 @name 覆盖 → 从 CWD 向上查找 .env → 全局配置 → 提示用户设置)。由此获取 OBSIDIAN_VAULT_PATH、COPILOT_HISTORY_PATH(默认为 ~/.copilot/session-state)和 COPILOT_VSCODE_STORAGE_PATH(VS Code 的 workspaceStorage;路径因平台而异——若缺失,请询问用户)
  2. 读取 vault 根目录下的 .manifest.json,检查已导入的内容
  3. 读取 vault 根目录下的 index.md,了解知识库已有内容

导入模式

追加模式(默认)

检查 .manifest.json 中是否记录了每个源文件(events JSONL、transcript JSONL、checkpoint、session-store DB)。仅处理:

  • 不在清单中的会话(新会话)
  • updated_at 晚于清单中 ingested_at 的会话

通常应使用此模式——用户刚运行了几个新会话,希望记录新增内容。

完整模式

无论清单内容如何,处理所有内容。可在执行 wiki-rebuild 后使用,或在用户明确提出要求时使用。

GitHub Copilot 数据布局

Copilot 将数据存储在三个位置。请扫描全部三个位置。

来源 1:~/.copilot/session-state/(CLI 会话)
~/.copilot/session-state/
├── <session-uuid>/
│   ├── workspace.yaml           # Session metadata (id, cwd, summary_count, created_at, updated_at)
│   ├── vscode.metadata.json     # VS Code context (workspaceFolder, repositoryProperties, customTitle)
│   ├── events.jsonl             # Full event log — all turns, tool calls, reasoning
│   ├── session.db               # Per-session SQLite (todos/todo_deps only — skip for ingestion)
│   ├── index.md                 # Session summary written at session end
│   ├── checkpoints/             # Checkpoint JSON files (mid-session summaries)
│   │   └── <uuid>.json          # title, overview, history, work_done, technical_details,
│   │                            #   important_files, next_steps
│   ├── files/                   # Artifacts produced during session (plans, diagrams, etc.)
│   └── research/                # Research artifacts
└── ...
来源 2:~/.copilot/session-store.db(全局 SQLite)

跨会话的权威数据库。这是价值最高的来源:结构化、可查询且已预先汇总。

sessions       — id, cwd, repository, branch, summary, created_at, updated_at, host_type
turns          — session_id, turn_index, user_message, assistant_response, timestamp
checkpoints    — session_id, checkpoint_number, title, overview, history, work_done,
                 technical_details, important_files, next_steps, created_at
session_files  — session_id, file_path, tool_name, turn_index, first_seen_at
session_refs   — session_id, ref_type (commit/pr/issue), ref_value, turn_index, created_at
search_index   — FTS5 virtual table (content, session_id, source_type, source_id)
来源 3:VS Code 工作区存储(<workspaceStorage>/<hash>/GitHub.copilot-chat/)

VS Code 扩展数据,以工作区哈希为键。路径因平台而异,必须从 .env 或用户输入中获取。

<hash>/GitHub.copilot-chat/
├── transcripts/
│   └── <session-uuid>.jsonl     # Conversation transcripts (same JSONL format as events.jsonl)
├── memory-tool/
│   └── memories/
│       └── <base64-session-id>/ # Per-session saved artifacts (plan.md, etc.)
│           └── plan.md
└── codebase-external.sqlite     # Codebase index (skip — no conversation knowledge)
关键数据来源的价值排序:
  1. 检查点(session-store.db 的 checkpoints 表及每个会话的 checkpoints/*.json)——预先提炼的摘要,包含 overview、work_done、technical_details、important_files、next_steps。价值极高。
  2. 会话摘要(session-store.db 的 sessions.summary 及 index.md)——每个会话一段概述。
  3. 轮次(session-store.db 的 turns 表及 events.jsonl / transcript JSONL)——完整对话。内容丰富,但较冗长。
  4. 记忆资源(memory-tool/memories/<id>/plan.md 等)——用户明确保存的预写计划和结构化笔记。值得原样导入(或仅做轻微概括)。
  5. 文件访问模式(session_files 表及 tool.execution_* 事件)——Agent 反复访问的文件,可揭示高价值项目文件。
  6. 会话引用(session_refs 表)——与会话关联的提交、PR 和议题。
  7. vscode.metadata.json——工作区文件夹路径、分支、customTitle(用户设置的会话标签)。有助于分组和命名。

步骤 1:调查并计算增量

扫描全部三个数据位置,并与 .manifest.json 进行比较:

# --- Source 1: per-session directories ---
# Find all session directories (each has workspace.yaml)
ls ~/.copilot/session-state/

# For each session, read workspace.yaml for id/cwd/updated_at
# and vscode.metadata.json for customTitle / repositoryProperties

# --- Source 2: global database ---
# Query session-store.db with sqlite3 (or Python sqlite3)
SELECT s.id, s.cwd, s.repository, s.branch, s.summary, s.updated_at,
       COUNT(DISTINCT t.turn_index) AS turn_count,
       COUNT(DISTINCT c.id)         AS checkpoint_count
FROM sessions s
LEFT JOIN turns t ON t.session_id = s.id
LEFT JOIN checkpoints c ON c.session_id = s.id
GROUP BY s.id
ORDER BY s.updated_at DESC;

# --- Source 3: VS Code workspace storage ---
# For each <hash> directory under workspaceStorage, check for GitHub.copilot-chat/
# Find transcript files
ls <workspaceStorage>/<hash>/GitHub.copilot-chat/transcripts/

构建统一清单——每个会话 UUID 对应一条记录——并进行分类:

  • 新增 — 不在清单中 → 需要导入
  • 已修改 — 在清单中,但 updated_at 更新 → 需要重新导入
  • 未更改 — 在清单中且没有修改 → 追加模式下跳过

向用户报告:“在 session-state 中找到 X 个会话,在 session-store.db 中找到 Y 个会话,以及 Z 个 VS Code 对话文件。检查点:A。增量:B 个新增,C 个已修改。”

步骤 2:先读取检查点和摘要

检查点已经过提炼——先处理它们,再查看原始轮次。

从 session-store.db 读取:
SELECT s.id, s.cwd, s.repository, s.branch, s.summary,
       c.checkpoint_number, c.title, c.overview, c.work_done,
       c.technical_details, c.important_files, c.next_steps,
       c.created_at
FROM checkpoints c
JOIN sessions s ON c.session_id = s.id
ORDER BY s.updated_at DESC, c.checkpoint_number ASC;
从各会话的 checkpoints/*.json 读取:

每个检查点文件包含:title、overview、history、work_done、technical_details、important_files、next_steps。

如果存在,请阅读 index.md,将其作为会话级摘要——它通常在会话结束时编写,内容已经很精炼。

要提取的内容:
  • overview → 会话完成工作的高层概述
  • work_done → 已完成的具体任务(适合用于技能页/项目页)
  • technical_details → 实现细节(适合用于概念页)
  • important_files → 项目中的高价值文件(适合用于项目页)
  • next_steps → 尚未解决的事项(适合用于关联正在进行的项目工作)

步骤 3:解析会话轮次

从 session-store.db(首选,已完成解析)或 events.jsonl/transcript JSONL 中读取轮次。

从 session-store.db 读取:
SELECT turn_index, user_message, assistant_response, timestamp
FROM turns
WHERE session_id = '<uuid>'
ORDER BY turn_index ASC;
从 events.jsonl/transcript JSONL 读取:

每个文件对应一个会话。每行都是一个 JSON 事件。完整架构请参阅 references/copilot-data-format.md。

相关事件类型:

type含义是否值得阅读?
session.start会话元数据(cwd、分支、版本)是——用于了解项目背景
user.message用户轮次是——读取 data.content
assistant.message助手轮次是——读取 data.content(文本)和 data.toolRequests
tool.execution_start工具调用略读——了解使用了哪些文件/命令
tool.execution_end工具结果否——通常是无关信息

assistant.message 的提取策略:

  • data.content 是助手的文本回复——提取此内容
  • data.reasoningText 是内部推理——跳过(它是解包后的 reasoningOpaque 字段)
  • data.toolRequests 列出工具调用——略读工具名称和参数,了解文件访问模式
  • 完全跳过 type: "tool.execution_end"

步骤 3b:处理记忆文档

对于在 VS Code 工作区存储中包含 memory-tool/memories/<base64-id>/ 目录的每个会话,请读取其中保存的 Markdown 文件(通常是 plan.md)。这些是用户明确保存的文档——应视为高质量的用户原创内容。

解码 base64 目录名以获取会话 UUID:

import base64
session_id = base64.b64decode(dir_name).decode('utf-8')

根据内容类型,记忆文档可归入项目的 skills/ 或 concepts/ 页面。

步骤 3c:提取文件和引用模式

从 session-store.db 读取:

-- Most-touched files per project
SELECT repository, file_path, COUNT(*) AS touch_count
FROM session_files
GROUP BY repository, file_path
ORDER BY touch_count DESC;

-- Linked commits/PRs/issues per session
SELECT session_id, ref_type, ref_value, turn_index
FROM session_refs
ORDER BY session_id, turn_index;

文件访问模式可揭示哪些文件在架构上很重要——请在项目页中记录。

会话引用可将 Copilot 会话与 Git 历史关联起来,有助于将 Wiki 知识与具体代码更改联系起来。

步骤 4:按主题归类

不要为每个会话都创建一个 Wiki 页面。应当:

  • 将不同会话中提取的知识按主题分组
  • 关于“调试身份验证+设置 CI”的单个会话 → 拆分为两个主题
  • 不同日期的三个“React 性能”会话 → 合并为一个主题
  • cwd/repository 可作为自然的第一层分组依据;vscode.metadata.json 的 customTitle 可提供易读的会话标签

步骤 5:提炼为 Wiki 页面

每个 Copilot 项目都对应知识库中的一个项目目录。根据 cwd 或 repository 推导项目名称:

C:\Users\name\git\my-project   → my-project
/Users/name/code/another-app   → another-app

如果 session-store.db 中有 repository(例如 owner/repo),优先使用它,而不是原始的 cwd。

项目级知识与全局知识
你发现的内容存放位置示例
项目架构决策projects/<name>/concepts/projects/my-project/concepts/main-architecture.md
项目特定的调试模式projects/<name>/skills/projects/my-project/skills/api-rate-limiting.md
用户学到的一般概念concepts/(全局)concepts/react-server-components.md
跨项目反复出现的问题skills/(全局)skills/debugging-hydration-errors.md
使用的工具/服务entities/(全局)entities/vercel-functions.md
多个会话中反复出现的模式synthesis/(全局)synthesis/common-debugging-patterns.md

对于包含内容的每个项目,在 projects/<name>/<name>.md 创建或更新项目概览页——文件名应使用项目名称,而不是 _project.md。Obsidian 的关系图视图会将文件名用作节点标签,因此 _project.md 会让所有项目在图中都显示为 _project。将其命名为 <name>.md,可让每个项目都有一个独特且易读的节点名称。

**重要:**提炼_知识_,而不是对话。不要写“在 3 月 15 日的一次会话中,用户询问了 X。”要写知识本身,并将会话作为来源说明。

在每个新建/更新的页面中添加 summary: frontmatter 字段——用 1–2 句话、不超过 200 个字符,回答“这篇页面讲什么?”,让尚未打开页面的读者也能了解内容。wiki-query 的低成本检索路径会读取此字段,以避免打开页面正文。

在每个新页面的 frontmatter 中添加置信度和生命周期字段:

base_confidence: 0.42
lifecycle: draft
lifecycle_changed: <obsidian-wiki memory now --date>

更新时保持 lifecycle 不变。

按照 llm-wiki 中的约定标记来源(Provenance Markers 部分):

  • 检查点和 index.md由系统预先提炼——将源自检查点的主张视为提取所得(系统根据观察到的操作编写)。
  • 记忆产物由用户撰写——视为提取所得。
  • 对话轮次提炼大多属于推断。你是在综合多个轮次,提炼出连贯的主张。对于综合出的模式、跨会话的概括,以及“用户真正想表达的意思”等解读,应广泛使用 ^[inferred]。
  • 当用户在会话中途改变方向,或会话结束时问题尚未解决,应使用 ^[ambiguous]。
  • 在每个新建/更新的页面中添加 provenance: frontmatter 块,概述大致的来源构成。

第 6 步:更新清单、日志和特殊文件

更新 .manifest.json

对于处理的每个会话,添加/更新其条目,并包含:

  • ingested_at、session_id、updated_at
  • source_type:以下值之一:"copilot_session"、"copilot_checkpoint"、"copilot_transcript"、"copilot_memory_artifact"
  • project:解码后的项目名称
  • pages_created 和 pages_updated 列表

同时更新清单中的 projects 部分:

{
  "project-name": {
    "repository": "owner/repo",
    "cwd": "C:\\Users\\name\\git\\project-name",
    "vault_path": "projects/project-name",
    "last_ingested": "TIMESTAMP",
    "sessions_ingested": 5,
    "sessions_total": 8,
    "checkpoints_ingested": 12,
    "memory_artifacts_ingested": 3
  }
}
创建日志条目并更新特殊文件

通过一次加锁调用更新 index.md、log.md 和 hot.md:

obsidian-wiki memory sync COPILOT_HISTORY_INGEST \
  projects=<projects> sessions=<sessions> checkpoints=<checkpoints> \
  pages_updated=<pages_updated> pages_created=<pages_created> \
  mode=<mode> \
  --takeaways "Ingested 5 Copilot sessions across 2 projects; surfaced patterns in API design and testing strategy."

切勿手动编辑 index.md、log.md 或 hot.md——该命令会获取锁,防止并行写入者丢失你的更新。--takeaways 是过去会写入 Recent Activity 的单行概念摘要;省略它即可保留之前的摘要不变。

如果现在对某个进行中的项目有了更深入的理解,请记录相关线索,以便下次会话接续:obsidian-wiki memory todo add "<thread>" --origin projects/<name>.md。

完整流程请参见 .skills/llm-wiki/references/MEMORY.md。

隐私

  • 提炼并综合内容,不要逐字复制原始对话文本
  • 跳过任何看起来像机密信息、API 密钥、密码或令牌的内容
  • 助手事件中的 data.reasoningOpaque / data.reasoningText 属于内部推理,完全跳过,绝不要复制到 wiki
  • 如果遇到个人或敏感内容,请先询问用户是否要将其纳入
  • 用户的对话可能会提及其他人;请谨慎判断哪些内容适合放入 wiki

参考资料

详细的数据结构文档请参阅 references/copilot-data-format.md。

写入 Vault 后刷新 QMD

QMD 是搜索索引,而非真实数据源。如果 $QMD_WIKI_COLLECTION 为空或未设置,请跳过此步骤。仅在此技能写入或重写了 vault Markdown 后运行。如果 QMD 刷新失败,不要回滚 vault 更改;请单独报告 QMD 状态。

如果已设置 $QMD_CLI,请使用它;否则使用 qmd。

${QMD_CLI:-qmd} update

如果输出提示需要向量或嵌入可能已过时,请运行:

${QMD_CLI:-qmd} embed

使用以下任一方式验证集合:

${QMD_CLI:-qmd} ls "$QMD_WIKI_COLLECTION"

或者,在已知特定页面路径时:

${QMD_CLI:-qmd} get "qmd://$QMD_WIKI_COLLECTION/<page>.md" -l 5

记录以下其中一项:

  • QMD refreshed: update + embed + verified
  • QMD refreshed: update only + verified
  • QMD skipped: QMD_WIKI_COLLECTION unset
  • QMD skipped: qmd CLI unavailable
  • QMD failed: <short error summary>

评论

支持 Markdown