{
  "canonical_name": "sree-sanak/minty",
  "compilation_id": "pack_7606d7c63c294fdc85882cdd32b0a11c",
  "created_at": "2026-05-11T23:59:19.511351+00:00",
  "created_by": "project-pack-compiler",
  "feedback": {
    "carrier_selection_notes": [
      "viable_asset_types=mcp_config, recipe, host_instruction, eval, preflight",
      "recommended_asset_types=mcp_config, recipe, host_instruction, eval, preflight"
    ],
    "evidence_delta": {
      "confirmed_claims": [
        "identity_anchor_present",
        "capability_and_host_targets_present",
        "install_path_declared_or_better"
      ],
      "missing_required_fields": [],
      "must_verify_forwarded": [
        "Run or inspect `npm install imap` in an isolated environment.",
        "Confirm the project exposes the claimed capability to at least one target host."
      ],
      "quickstart_execution_scope": "allowlisted_sandbox_smoke",
      "sandbox_command": "npm install imap",
      "sandbox_container_image": "node:22-slim",
      "sandbox_execution_backend": "docker",
      "sandbox_planner_decision": "llm_execute_isolated_install",
      "sandbox_validation_id": "sbx_a5335af4bf8b4851937076f779fe720d"
    },
    "feedback_event_type": "project_pack_compilation_feedback",
    "learning_candidate_reasons": [],
    "template_gaps": []
  },
  "identity": {
    "canonical_id": "project_64cd3c629642444b74b38ac0c4cb7727",
    "canonical_name": "sree-sanak/minty",
    "homepage_url": null,
    "license": "unknown",
    "repo_url": "https://github.com/sree-sanak/minty",
    "slug": "minty",
    "source_packet_id": "phit_f86cf93762a64e31b1d857cc9e9fe840",
    "source_validation_id": "dval_723cbe3febe34eca8d77a840a45eccee"
  },
  "merchandising": {
    "best_for": "需要工具连接与集成能力，并使用 mcp_host的用户",
    "github_forks": 0,
    "github_stars": 2,
    "one_liner_en": "Private network memory for OpenClaw, Hermes, and MCP agents.",
    "one_liner_zh": "Private network memory for OpenClaw, Hermes, and MCP agents.",
    "primary_category": {
      "category_id": "tool-integrations",
      "confidence": "medium",
      "name_en": "Tool Integrations",
      "name_zh": "工具连接与集成",
      "reason": "matched_keywords:mcp, github"
    },
    "target_user": "使用 mcp_host 等宿主 AI 的用户",
    "title_en": "minty",
    "title_zh": "minty 能力包",
    "visible_tags": [
      {
        "label_en": "Browser Agents",
        "label_zh": "浏览器 Agent",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "product_domain-browser-agents",
        "type": "product_domain"
      },
      {
        "label_en": "Web Task Automation",
        "label_zh": "网页任务自动化",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "user_job-web-task-automation",
        "type": "user_job"
      },
      {
        "label_en": "Browser Automation",
        "label_zh": "浏览器自动化",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "core_capability-browser-automation",
        "type": "core_capability"
      },
      {
        "label_en": "Node-based Workflow",
        "label_zh": "节点式流程编排",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "workflow_pattern-node-based-workflow",
        "type": "workflow_pattern"
      },
      {
        "label_en": "Evaluation Suite",
        "label_zh": "评测体系",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "selection_signal-evaluation-suite",
        "type": "selection_signal"
      }
    ]
  },
  "packet_id": "phit_f86cf93762a64e31b1d857cc9e9fe840",
  "page_model": {
    "artifacts": {
      "artifact_slug": "minty",
      "files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json",
        "REPO_INSPECTION.md",
        "CAPABILITY_CONTRACT.json",
        "EVIDENCE_INDEX.json",
        "CLAIM_GRAPH.json"
      ],
      "required_files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json"
      ]
    },
    "detail": {
      "capability_source": "Project Hit Packet + DownstreamValidationResult",
      "commands": [
        {
          "command": "npm install imap",
          "label": "Node.js / npm · 官方安装入口",
          "source": "https://github.com/sree-sanak/minty#readme",
          "verified": true
        }
      ],
      "display_tags": [
        "浏览器 Agent",
        "网页任务自动化",
        "浏览器自动化",
        "节点式流程编排",
        "评测体系"
      ],
      "eyebrow": "工具连接与集成",
      "glance": [
        {
          "body": "判断自己是不是目标用户。",
          "label": "最适合谁",
          "value": "需要工具连接与集成能力，并使用 mcp_host的用户"
        },
        {
          "body": "先理解能力边界，再决定是否继续。",
          "label": "核心价值",
          "value": "Private network memory for OpenClaw, Hermes, and MCP agents."
        },
        {
          "body": "未完成验证前保持审慎。",
          "label": "继续前",
          "value": "publish to Doramagic.ai project surfaces"
        }
      ],
      "guardrail_source": "Boundary & Risk Card",
      "guardrails": [
        {
          "body": "Prompt Preview 只展示流程，不证明项目已安装或运行。",
          "label": "Check 1",
          "value": "不要把试用当真实运行"
        },
        {
          "body": "mcp_host",
          "label": "Check 2",
          "value": "确认宿主兼容"
        },
        {
          "body": "publish to Doramagic.ai project surfaces",
          "label": "Check 3",
          "value": "先隔离验证"
        }
      ],
      "mode": "mcp_config, recipe, host_instruction, eval, preflight",
      "pitfall_log": {
        "items": [
          {
            "body": "GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Audit person-only filters for channel/broadcast/list contacts",
            "category": "安装坑",
            "evidence": [
              "community_evidence:github | cevd_806464769ad247cd93162d66f18c8d51 | https://github.com/sree-sanak/minty/issues/86 | 来源讨论提到 node 相关条件，需在安装/试用前复核。"
            ],
            "severity": "high",
            "suggested_check": "来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。",
            "title": "来源证据：Audit person-only filters for channel/broadcast/list contacts",
            "user_impact": "可能影响升级、迁移或版本选择。"
          },
          {
            "body": "仓库名 `minty` 与安装入口 `imap` 不完全一致。",
            "category": "身份坑",
            "evidence": [
              "identity.distribution | github_repo:1217893833 | https://github.com/sree-sanak/minty | repo=minty; install=imap"
            ],
            "severity": "medium",
            "suggested_check": "在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。",
            "title": "仓库名和安装名不一致",
            "user_impact": "用户照着仓库名搜索包或照着包名找仓库时容易走错入口。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Replace README screenshot TODO with privacy-safe demo visual",
            "category": "安装坑",
            "evidence": [
              "community_evidence:github | cevd_81816548248b4de0a1ace912ebf7ee0e | https://github.com/sree-sanak/minty/issues/97 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：Replace README screenshot TODO with privacy-safe demo visual",
            "user_impact": "可能增加新用户试用和生产接入成本。"
          },
          {
            "body": "README/documentation is current enough for a first validation pass.",
            "category": "能力坑",
            "evidence": [
              "capability.assumptions | github_repo:1217893833 | https://github.com/sree-sanak/minty | README/documentation is current enough for a first validation pass."
            ],
            "severity": "medium",
            "suggested_check": "将假设转成下游验证清单。",
            "title": "能力判断依赖假设",
            "user_impact": "假设不成立时，用户拿不到承诺的能力。"
          },
          {
            "body": "未记录 last_activity_observed。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1217893833 | https://github.com/sree-sanak/minty | last_activity_observed missing"
            ],
            "severity": "medium",
            "suggested_check": "补 GitHub 最近 commit、release、issue/PR 响应信号。",
            "title": "维护活跃度未知",
            "user_impact": "新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "downstream_validation.risk_items | github_repo:1217893833 | https://github.com/sree-sanak/minty | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "进入安全/权限治理复核队列。",
            "title": "下游验证发现风险项",
            "user_impact": "下游已经要求复核，不能在页面中弱化。"
          },
          {
            "body": "No sandbox install has been executed yet; downstream must verify before user use.",
            "category": "安全/权限坑",
            "evidence": [
              "risks.safety_notes | github_repo:1217893833 | https://github.com/sree-sanak/minty | No sandbox install has been executed yet; downstream must verify before user use."
            ],
            "severity": "medium",
            "suggested_check": "转成明确权限清单和安全审查提示。",
            "title": "存在安全注意事项",
            "user_impact": "用户安装前需要知道权限边界和敏感操作。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "risks.scoring_risks | github_repo:1217893833 | https://github.com/sree-sanak/minty | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "把风险写入边界卡，并确认是否需要人工复核。",
            "title": "存在评分风险",
            "user_impact": "风险会影响是否适合普通用户安装。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Add minimal GitHub Actions smoke CI for npm test",
            "category": "安全/权限坑",
            "evidence": [
              "community_evidence:github | cevd_d6f1f5066d884d66b52f3e8f51ed0899 | https://github.com/sree-sanak/minty/issues/98 | 来源讨论提到 node 相关条件，需在安装/试用前复核。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：Add minimal GitHub Actions smoke CI for npm test",
            "user_impact": "可能影响授权、密钥配置或安全边界。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Avoid returning raw internal error messages from API/UI",
            "category": "安全/权限坑",
            "evidence": [
              "community_evidence:github | cevd_2974d969ccff4c9b960c16ee12639466 | https://github.com/sree-sanak/minty/issues/44 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：Avoid returning raw internal error messages from API/UI",
            "user_impact": "可能影响授权、密钥配置或安全边界。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Provision GitHub labels from checked-in labels.json",
            "category": "安全/权限坑",
            "evidence": [
              "community_evidence:github | cevd_1a3ae522d9a7404691d7e3eb4b70b6b1 | https://github.com/sree-sanak/minty/issues/109 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：Provision GitHub labels from checked-in labels.json",
            "user_impact": "可能影响授权、密钥配置或安全边界。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Sync failures can mark stale source data as fresh",
            "category": "安全/权限坑",
            "evidence": [
              "community_evidence:github | cevd_3bc92d2124c24b978bf799cc9eff9529 | https://github.com/sree-sanak/minty/issues/200 | 来源讨论提到 node 相关条件，需在安装/试用前复核。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：Sync failures can mark stale source data as fresh",
            "user_impact": "可能影响授权、密钥配置或安全边界。"
          },
          {
            "body": "issue_or_pr_quality=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1217893833 | https://github.com/sree-sanak/minty | issue_or_pr_quality=unknown"
            ],
            "severity": "low",
            "suggested_check": "抽样最近 issue/PR，判断是否长期无人处理。",
            "title": "issue/PR 响应质量未知",
            "user_impact": "用户无法判断遇到问题后是否有人维护。"
          },
          {
            "body": "release_recency=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1217893833 | https://github.com/sree-sanak/minty | release_recency=unknown"
            ],
            "severity": "low",
            "suggested_check": "确认最近 release/tag 和 README 安装命令是否一致。",
            "title": "发布节奏不明确",
            "user_impact": "安装命令和文档可能落后于代码，用户踩坑概率升高。"
          }
        ],
        "source": "ProjectPitfallLog + ProjectHitPacket + validation + community signals",
        "summary": "发现 14 个潜在踩坑项，其中 1 个为 high/blocking；最高优先级：安装坑 - 来源证据：Audit person-only filters for channel/broadcast/list contacts。",
        "title": "踩坑日志"
      },
      "snapshot": {
        "contributors": 2,
        "forks": 0,
        "license": "unknown",
        "note": "GitHub API 快照，非实时质量证明；用于开工前背景判断。",
        "stars": 2,
        "open_issues": 5,
        "pushed_at": "2026-05-13T01:46:53.000Z"
      },
      "source_url": "https://github.com/sree-sanak/minty",
      "steps": [
        {
          "body": "不安装项目，先体验能力节奏。",
          "code": "preview",
          "title": "先试 Prompt"
        },
        {
          "body": "理解输入、输出、失败模式和边界。",
          "code": "manual",
          "title": "读说明书"
        },
        {
          "body": "把上下文交给宿主 AI 继续工作。",
          "code": "context",
          "title": "带给 AI"
        },
        {
          "body": "进入主力环境前先完成安装入口与风险边界验证。",
          "code": "verify",
          "title": "沙箱验证"
        }
      ],
      "subtitle": "Private network memory for OpenClaw, Hermes, and MCP agents.",
      "title": "minty 能力包",
      "trial_prompt": "# minty - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 minty 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的工具连接与集成任务。\n我常用的宿主 AI：MCP Client\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 步骤建议, 检查清单, 专业工作流。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- AI Skill / Agent 指令资产库: 项目包含可被宿主 AI 读取的 Skill 或 Agent 指令文件，可用于把专业流程带入 Claude、Codex、Cursor 等宿主。 输入：用户任务, 宿主 AI 对话上下文, 项目内 Skill/Agent 文档；输出：步骤建议, 检查清单, 专业工作流。\n\n【必须安装后才可验证的能力】\n- 命令行启动或安装流程: 项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 输入：终端环境, 包管理器, 项目依赖；输出：安装结果, 列表/更新/运行结果。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. page-introduction：项目介绍。围绕“项目介绍”模拟一次用户任务，不展示安装或运行结果。\n2. page-quick-start：快速开始。围绕“快速开始”模拟一次用户任务，不展示安装或运行结果。\n3. page-architecture-overview：架构总览。围绕“架构总览”模拟一次用户任务，不展示安装或运行结果。\n4. page-data-sources：数据源导入。围绕“数据源导入”模拟一次用户任务，不展示安装或运行结果。\n5. page-contact-merging：联系人合并与去重。围绕“联系人合并与去重”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. page-introduction\n输入：用户提供的“项目介绍”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. page-quick-start\n输入：用户提供的“快速开始”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. page-architecture-overview\n输入：用户提供的“架构总览”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. page-data-sources\n输入：用户提供的“数据源导入”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. page-contact-merging\n输入：用户提供的“联系人合并与去重”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / page-introduction：Step 1 必须围绕“项目介绍”形成一个小中间产物，并等待用户确认。\n- Step 2 / page-quick-start：Step 2 必须围绕“快速开始”形成一个小中间产物，并等待用户确认。\n- Step 3 / page-architecture-overview：Step 3 必须围绕“架构总览”形成一个小中间产物，并等待用户确认。\n- Step 4 / page-data-sources：Step 4 必须围绕“数据源导入”形成一个小中间产物，并等待用户确认。\n- Step 5 / page-contact-merging：Step 5 必须围绕“联系人合并与去重”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://github.com/sree-sanak/minty\n- https://github.com/sree-sanak/minty#readme\n- hermes/minty-network-memory/SKILL.md\n- README.md\n- VISION.md\n- SECURITY.md\n- docs/PHILOSOPHY.md\n- docs/SERVICE.md\n- docs/OPENCLAW_HERMES.md\n- ARCHITECTURE.md\n- crm/index.js\n- crm/schema.js\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 minty 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "voices": [
        {
          "body": "来源平台：github。github/github_issue: Sync failures can mark stale source data as fresh（https://github.com/sree-sanak/minty/issues/200）；github/github_issue: Audit person-only filters for channel/broadcast/list contacts（https://github.com/sree-sanak/minty/issues/86）；github/github_issue: Avoid returning raw internal error messages from API/UI（https://github.com/sree-sanak/minty/issues/44）；github/github_issue: Replace README screenshot TODO with privacy-safe demo visual（https://github.com/sree-sanak/minty/issues/97）；github/github_issue: Provision GitHub labels from checked-in labels.json（https://github.com/sree-sanak/minty/issues/109）；github/github_issue: Add minimal GitHub Actions smoke CI for npm test（https://github.com/sree-sanak/minty/issues/98）。这些是项目级外部声音，不作为单独质量证明。",
          "items": [
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Sync failures can mark stale source data as fresh",
              "url": "https://github.com/sree-sanak/minty/issues/200"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Audit person-only filters for channel/broadcast/list contacts",
              "url": "https://github.com/sree-sanak/minty/issues/86"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Avoid returning raw internal error messages from API/UI",
              "url": "https://github.com/sree-sanak/minty/issues/44"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Replace README screenshot TODO with privacy-safe demo visual",
              "url": "https://github.com/sree-sanak/minty/issues/97"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Provision GitHub labels from checked-in labels.json",
              "url": "https://github.com/sree-sanak/minty/issues/109"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Add minimal GitHub Actions smoke CI for npm test",
              "url": "https://github.com/sree-sanak/minty/issues/98"
            }
          ],
          "status": "已收录 6 条来源",
          "title": "社区讨论"
        }
      ]
    },
    "homepage_card": {
      "category": "工具连接与集成",
      "desc": "Private network memory for OpenClaw, Hermes, and MCP agents.",
      "effort": "安装已验证",
      "forks": 0,
      "icon": "link",
      "name": "minty 能力包",
      "risk": "可发布",
      "slug": "minty",
      "stars": 2,
      "tags": [
        "浏览器 Agent",
        "网页任务自动化",
        "浏览器自动化",
        "节点式流程编排",
        "评测体系"
      ],
      "thumb": "gray",
      "type": "MCP 配置"
    },
    "manual": {
      "markdown": "# https://github.com/sree-sanak/minty 项目说明书\n\n生成时间：2026-05-11 23:57:10 UTC\n\n## 目录\n\n- [项目介绍](#page-introduction)\n- [快速开始](#page-quick-start)\n- [项目文件结构](#page-file-structure)\n- [架构总览](#page-architecture-overview)\n- [AI 后端配置](#page-ai-backend)\n- [数据源导入](#page-data-sources)\n- [联系人合并与去重](#page-contact-merging)\n- [数据存储结构](#page-data-storage)\n- [MCP 代理集成](#page-mcp-integration)\n- [网络查询系统](#page-network-query)\n\n<a id='page-introduction'></a>\n\n## 项目介绍\n\n### 相关页面\n\n相关主题：[快速开始](#page-quick-start), [架构总览](#page-architecture-overview)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/sree-sanak/minty/blob/main/README.md)\n- [ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n- [CHANGELOG.md](https://github.com/sree-sanak/minty/blob/main/CHANGELOG.md)\n- [RELEASING.md](https://github.com/sree-sanak/minty/blob/main/RELEASING.md)\n- [hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md)\n</details>\n\n# 项目介绍\n\n## 概述\n\nMinty 是一个本地优先的人脉网络记忆系统，旨在帮助用户从多个通讯渠道（WhatsApp、Telegram、邮件、日历、LinkedIn 等）汇总联系人信息，构建统一的人脉知识图谱，并通过 AI 驱动的自然语言查询能力实现\"记住所有人\"的愿景。\n\n该系统完全本地化运行，不依赖任何云端 API，采用本地 AI 模型（Ollama）或本地 Claude Code CLI 进行智能分析，确保用户数据的隐私安全。资料来源：[README.md]()\n\n## 核心特性\n\n| 特性 | 描述 |\n|------|------|\n| 多源数据整合 | 支持 WhatsApp、Telegram、Gmail、日历、LinkedIn 等多种数据源的导入与同步 |\n| 本地 AI 驱动 | 使用 Ollama 或 Claude Code CLI，完全离线运行，无云端依赖 |\n| 智能匹配 | 跨来源自动合并重复联系人，消除数据孤岛 |\n| 自然语言查询 | 通过 MCP 协议支持自然语言的人脉搜索 |\n| 关系热度追踪 | 自动计算联系人亲密度与互动频率，识别关系衰减信号 |\n| 定期回顾 | 生成\"失联联系人\"提醒与重连建议 |\n\n资料来源：[README.md](), [ARCHITECTURE.md]()\n\n## 系统架构\n\n### 整体架构\n\n```mermaid\ngraph TD\n    A[数据源] --> B[sources/ 导入层]\n    B --> C[data/<source>/ 原始数据]\n    C --> D[crm/merge.js 合并]\n    D --> E[data/unified/ 统一存储]\n    E --> F[AI 推理层]\n    E --> G[CRM Web UI]\n    E --> H[MCP Server]\n    \n    B1[WhatsApp] --> B\n    B2[Telegram] --> B\n    B3[Gmail/Email] --> B\n    B4[Calendar] --> B\n    B5[LinkedIn] --> B\n    B6[Slack] --> B\n```\n\n### 核心模块说明\n\n| 模块 | 文件 | 功能描述 |\n|------|------|----------|\n| 导入层 | `sources/*/import.js` | 各数据源的独立导入器，写入 `data/<source>/` |\n| 数据合并 | `crm/merge.js` | 加载各来源数据，进行规范化、去重，写入 `data/unified/contacts.json` 和 `interactions.json` |\n| 匹配算法 | `crm/match.js` | 跨来源联系人匹配逻辑，遵循 `MATCHING.md` 规范 |\n| 数据模式 | `crm/schema.js` | `Contact` 和 `Interaction` 的规范数据结构定义 |\n| 查询 CLI | `crm/query.js` | 命令行工具：`npm run stats`、`npm run search` |\n| 自然语言查询 | `crm/network-query.js` | \"Ask\"视图，支持自然语言提问 |\n| 重连建议 | `crm/reconnect.js` | 识别\"关系衰减\"联系人并生成重连草稿 |\n| AI 适配器 | `crm/ai.js` | 本地 Claude Code CLI / Ollama 适配器，无云端 API |\n| 数据陈旧检测 | `crm/staleness.js` | 标记陈旧联系人数据，供 UI 告警使用 |\n| 同步守护进程 | `crm/sync.js` | 监视 `data/<source>/export/` 目录，自动触发导入器 |\n| 高层功能 | `calendar.js`, `digest.js`, `meeting-debrief.js`, `goal-retro.js`, `life-events.js` | 基于统一存储的高级功能 |\n| 工具函数 | `crm/utils.js` | 电话/邮箱/姓名规范化、评分辅助、内存联系人索引 |\n\n资料来源：[ARCHITECTURE.md]()\n\n### 数据模型\n\n系统使用两个核心数据结构：\n\n**Contact（联系人）**\n- 基本信息：姓名、电话、邮箱、组织、职位\n- 来源追踪：`sources` 字段记录每个来源的具体数据\n- 关系评分：`relationshipScore` 基于互动频率计算\n- 亲密度：`warmth` 指标反映关系深度\n- 最后联系：`daysSinceContact` 计算天数\n\n**Interaction（互动记录）**\n- 时间戳与来源\n- 内容摘要：`subject`、`body`\n- 互动类型：会议、消息、通话等\n\n资料来源：[crm/schema.js](), [ARCHITECTURE.md]()\n\n## 数据源支持\n\n### 支持的来源\n\n| 数据源 | 状态 | 导入方式 |\n|--------|------|----------|\n| WhatsApp | 生产就绪 | 扫码认证、Session 自动恢复 |\n| Telegram | 生产就绪 | Bot Token 认证 |\n| Gmail/Email | 生产就绪 | Microsoft Graph API (OAuth) |\n| Google Calendar | 生产就绪 | Google Calendar API |\n| LinkedIn | 实验性 | CSV 导入 + 即将支持自动同步 |\n| Slack | 生产就绪 | Workspace Token |\n| SMS | 生产就绪 | iOS 备份解析 |\n| WhatsApp Business | 生产就绪 | iOS 备份解析 |\n\n每个数据源独立运行，写入 `data/<source>/` 目录。统一存储由 `crm/merge.js` 从各来源重建。\n\n资料来源：[README.md](), [ARCHITECTURE.md]()\n\n## 启动方式\n\n### 服务模式（推荐）\n\n```bash\n# 基础服务\nnpm run service\n\n# 指定用户 UUID\nMINTY_USER_UUID=abc npm run service\n\n# 启用定期 GBrain 导出\nMINTY_GBRAIN_EXPORT=1 npm run service\n```\n\n服务模式以无头守护进程运行，无 Web UI，适合长期部署。\n\n### Web UI 模式\n\n```bash\nnpm run crm\n```\n\n启动后在浏览器访问 `http://localhost:3456`，可浏览联系人、配置数据源、进行 QA 测试。\n\n### Agent 原生模式\n\n```bash\n# 初始化演示数据\nnpm run seed:demo\n\n# 自然语言查询\nCRM_DATA_DIR=./data-demo npm run agent -- \"who can help with crypto insurance\"\n\n# 启动 MCP 服务器\nCRM_DATA_DIR=./data-demo npm run mcp\n```\n\nMCP 服务器可注册到 OpenClaw 或 Hermes，实现智能体对人脉网络的自然语言访问。\n\n### 快速网络查询\n\n```bash\nnpm run network:search -- \"investors in fintech\"\nnpm run network:changes\nnpm run network:reconnect\nnpm run service:status\n```\n\n资料来源：[README.md]()\n\n## MCP 工具接口\n\nMinty 提供四个核心 MCP 工具：\n\n| 工具 | 功能 | 示例参数 |\n|------|------|----------|\n| `search_network` | 自然语言搜索人脉网络 | `{\"query\": \"investors in London\", \"limit\": 5}` |\n| `person_context` | 查询特定联系人详情 | `{\"person\": \"Alice Müller\", \"limit\": 3}` |\n| `workflow_brief` | 生成目标导向简报 | `{\"goal\": \"Find EU partners\", \"limit\": 5}` |\n| `source_health` | 检查数据源健康状态 | `{\"source\": \"telegram\"}` |\n\n这些工具通过 `scripts/minty-mcp-server.js` 暴露，是系统的工具接口规范。\n\n资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n## 版本与发布\n\n### 当前版本\n\n最新稳定版本信息记录在 `CHANGELOG.md` 中，采用语义化版本号 `MAJOR.MINOR.PATCH`。\n\n### 发布流程\n\n1. **版本决策**：查看 `CHANGELOG.md` 的 `Unreleased` 部分，确定版本号\n2. **更新 CHANGELOG**：将 `## [Unreleased]` 替换为 `## [X.Y.Z] - YYYY-MM-DD`\n3. **升级 package.json**：\n   ```bash\n   npm version X.Y.Z --no-git-tag-version\n   ```\n4. **提交**：\n   ```bash\n   git add CHANGELOG.md package.json package-lock.json\n   git commit -m \"release: vX.Y.Z\"\n   ```\n5. **打标签推送**：\n   ```bash\n   git tag vX.Y.Z\n   git push origin main\n   git push origin v.X.Y.Z\n   ```\n\n发布工作流自动验证标签与 `package.json` 的一致性，并从 `CHANGELOG.md` 提取发布说明创建 GitHub Release。\n\n### 热修复流程\n\n对于安全或生产级问题：\n\n1. 从标签分支：`git checkout -b hotfix/X.Y.Z+1 v.X.Y.Z`\n2. 修复代码\n3. 按标准发布流程升级 PATCH 版本\n4. 必要时将修复 cherry-pick 回 main 分支\n\n资料来源：[RELEASING.md]()\n\n## 技术要求\n\n| 要求 | 规格 |\n|------|------|\n| Node.js 版本 | Node 20 + 22 |\n| 包管理器 | npm |\n| 可选依赖 | Playwright（LinkedIn 自动同步）、csv-parse |\n| AI 后端 | Ollama（qwen2.5:7b 等模型）或 Claude Code CLI |\n\n所有 AI 输出（洞察、摘要、重连草稿、查询排名）均为预计算并缓存于 `data/unified/*.json`，Web 服务器读取静态文件，请求时无 API 调用。\n\n资料来源：[README.md](), [CHANGELOG.md]()\n\n## 数据隐私与许可\n\n- **数据存储**：所有数据本地存储于 `data/` 目录\n- **隐私保护**：支持匿名化导出（`npm run gbrain:export`），避免原始联系人/消息泄露\n- **许可协议**：采用 **AGPL-3.0** 许可证，开源且允许商业使用\n- **商业授权**：如需在专有产品中嵌入 Minty，可申请商业许可\n\n资料来源：[README.md]()\n\n## 贡献指南\n\n欢迎贡献代码。贡献者请先阅读：\n\n- [CONTRIBUTING.md](./CONTRIBUTING.md) — 贡献流程规范\n- [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md) — 行为准则\n- [SECURITY.md](./SECURITY.md) — 安全报告流程\n\n### 开发者入门\n\n| 任务 | 起点 |\n|------|------|\n| 添加新数据源 | 复制 `sources/telegram/`，参照文件布局 |\n| 改进匹配算法 | 阅读 `crm/MATCHING.md`，修改 `crm/match.js`，添加测试 fixture |\n| UI 开发 | 编辑 `crm/ui.html.js` 和 `crm/server.js`，重启 `npm run crm` |\n| 性能优化 | 关注 `crm/merge.js` 路径，参考 `tests/integration/` 的性能测试 |\n\n资料来源：[ARCHITECTURE.md]()\n\n## 项目愿景\n\nMinty 的核心目标是构建一个\"永不遗忘的人脉记忆系统\"。系统通过持续整合用户的通讯数据，自动识别联系人关系的变化，并在关键时刻提供智能化的回顾与行动建议。长期愿景是让用户能够专注于建立和维护有意义的人际关系，而不是记忆细节。\n\n项目路线图详见 [VISION.md](./VISION.md)。\n\n资料来源：[README.md]()\n\n---\n\n<a id='page-quick-start'></a>\n\n## 快速开始\n\n### 相关页面\n\n相关主题：[项目介绍](#page-introduction), [数据源导入](#page-data-sources)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/sree-sanak/minty/blob/main/README.md)\n- [ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n- [CONTRIBUTING.md](https://github.com/sree-sanak/minty/blob/main/CONTRIBUTING.md)\n- [hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md)\n- [sources/_shared/progress.js](https://github.com/sree-sanak/minty/blob/main/sources/_shared/progress.js)\n</details>\n\n# 快速开始\n\nMinty 是一个本地优先的关系管理系统，旨在帮助用户从多个数据源（WhatsApp、Telegram、Email、LinkedIn 等）聚合联系人信息，并通过 AI 能力提供关系洞察。本页将引导您完成 Minty 的安装、配置和首次使用。\n\n---\n\n## 环境要求\n\n| 组件 | 要求 |\n|------|------|\n| Node.js | v20 或 v22 |\n| 操作系统 | macOS、Linux、Windows（WSL 推荐） |\n| 存储空间 | 取决于数据量，建议预留 1GB+ |\n| 网络 | 仅在配置 AI 后端时需要（可选） |\n\n资料来源：[README.md:1-10]()\n\n---\n\n## 安装步骤\n\n### 1. 克隆仓库\n\n```bash\ngit clone https://github.com/sree-sanak/minty.git\ncd minty\n```\n\n### 2. 安装依赖\n\n```bash\nnpm install\n```\n\n此命令安装所有必要的 Node.js 依赖包，包括数据处理、加密、Web 服务等模块。\n\n### 3. 安装 Git Hooks（可选但推荐）\n\n```bash\nnpm run hooks:install\n```\n\n此命令启用预推送 Preflight 检查，确保代码在推送前通过基础测试。\n\n资料来源：[CONTRIBUTING.md:1-15]()\n\n---\n\n## 运行模式\n\nMinty 支持三种运行模式，适用于不同的使用场景：\n\n### 模式概览\n\n| 模式 | 命令 | 端口 | 适用场景 |\n|------|------|------|----------|\n| 常驻服务 | `npm run service` | 后台运行 | 生产环境、长期运行 |\n| Web UI | `npm run crm` | 3456 | 浏览器管理联系人 |\n| Agent 模式 | `npm run agent` | - | 与 OpenClaw/Hermes 集成 |\n\n资料来源：[README.md:20-35]()\n\n### 常驻服务模式（推荐）\n\n常驻服务以无头守护进程方式运行，持续同步数据：\n\n```bash\n# 默认模式\nnpm run service\n\n# 指定用户 UUID\nMINTY_USER_UUID=abc npm run service\n\n# 同时运行周期性 GBrain 导出\nMINTY_GBRAIN_EXPORT=1 npm run service\n```\n\n服务模式会在后台监控 `data/<source>/export/` 目录中的用户导入文件，并自动触发导入流程。资料来源：[ARCHITECTURE.md:1-30]()\n\n### Web UI 模式\n\n启动本地 Web 服务器，通过浏览器管理联系人：\n\n```bash\nnpm run crm\n```\n\n访问 `http://localhost:3456` 打开 Minty CRM 界面。Web UI 采用单页应用（SPA）架构，所有前端代码位于 `crm/ui.html.js` 中。\n\n> 注意：Web UI 读取的是预计算和缓存的静态文件（`data/unified/*.json`），无需在请求时调用 AI API。\n\n资料来源：[CONTRIBUTING.md:10-12]()\n\n### Agent 原生模式\n\n适用于与 OpenClaw、Hermes 或 Claude Code 等 AI Agent 集成：\n\n```bash\n# 初始化演示数据\nnpm run seed:demo\n\n# 执行网络查询\nCRM_DATA_DIR=./data-demo npm run agent -- \"who can help with crypto insurance\"\n\n# 启动 MCP 服务器\nCRM_DATA_DIR=./data-demo npm run mcp\n```\n\n注册 `scripts/minty-mcp-server.js` 作为本地 stdio MCP 服务器后，Agent 可直接调用以下工具：\n\n- `search_network` - 自然语言网络搜索\n- `person_context` - 查询特定联系人的上下文\n- `workflow_brief` - 生成目标导向简报\n- `source_health` - 检查数据源健康状态\n\n资料来源：[hermes/minty-network-memory/SKILL.md:1-50]()\n\n---\n\n## 快速网络查询\n\n以下命令适用于快速查询，无需启动完整服务：\n\n```bash\n# 自由形式搜索\nnpm run network:search -- \"investors in fintech\"\n\n# 通信模式变化\nnpm run network:changes\n\n# 渐行渐远的关系（需要重新联系）\nnpm run network:reconnect\n\n# 检查服务健康状态\nnpm run service:status\n```\n\n资料来源：[README.md:36-42]()\n\n---\n\n## 数据源配置\n\nMinty 支持多个可选数据源，每个源独立导入，按需启用：\n\n| 数据源 | 导入方式 | 说明 |\n|--------|----------|------|\n| WhatsApp | `npm run whatsapp` | 首次需扫描 QR 码 |\n| Telegram | `sources/telegram/import.js` | 导出 Telegram 数据 |\n| Email | Microsoft Graph API | 支持 Outlook/Exchange |\n| SMS | 平台特定 | 读取本地短信记录 |\n| LinkedIn | ZIP 包导入 | 导出 LinkedIn 数据 |\n| Google Contacts | 同步 | Google 账户联系人 |\n| Slack | 导出 | 导出 Slack 消息历史 |\n\n资料来源：[README.md:45-60]()\n\n### WhatsApp 快速配置\n\n```bash\nnpm run whatsapp\n```\n\n首次运行时显示 QR 码，用 WhatsApp 手机应用扫描后即可连接。后续运行自动恢复会话。\n\n---\n\n## AI 后端配置\n\nMinty 采用预计算 AI 策略，所有 AI 输出（洞察、摘要、重新联系草稿）存储在 `data/unified/*.json` 中，Web 服务器直接读取静态文件，无运行时 API 调用。\n\n### Claude Code CLI（默认）\n\n如果系统 PATH 中存在 `claude` 命令，Minty 自动使用此后端：\n\n```bash\n# 验证 Claude Code 可用性\nclaude --version\n```\n\n> 注意：Claude Code 后端会将提示词（包含联系人消息片段）发送至 Anthropic 服务器。\n\n资料来源：[README.md:100-115]()\n\n### Ollama（完全离线）\n\n配置本地 Ollama 模型：\n\n```bash\n# 在 .env 文件中设置\nAI_BACKEND=ollama\n\n# 推荐模型\nollama run qwen2.5:7b\n```\n\nOllama 模式完全离线运行，适合对数据隐私有高要求的用户。\n\n---\n\n## 数据目录结构\n\n所有数据存储在本地 `data/` 目录中（已被 Git 忽略）：\n\n```\ndata/\n├── whatsapp/         # WhatsApp 聊天和联系人\n├── telegram/         # Telegram 导出数据\n├── email/            # Email 账户数据\n├── sms/              # 短信数据\n├── linkedin/         # LinkedIn 导出（ZIP + CSV）\n├── google-contacts/  # Google 联系人\n├── slack/            # Slack 导出\n└── unified/          # 合并后的统一视图\n    ├── contacts.json       # 统一联系人\n    ├── interactions.json  # 互动时间线\n    └── match_overrides.json # 匹配规则覆盖\n```\n\n可通过环境变量覆盖数据目录：\n\n```bash\nCRM_DATA_DIR=./custom-data-dir npm run service\n```\n\n资料来源：[ARCHITECTURE.md:40-70]()\n\n---\n\n## 同步状态监控\n\n### 服务状态检查\n\n```bash\nnpm run service:status\n```\n\n### 单源进度查询\n\n每个导入器通过 `sources/_shared/progress.js` 记录同步进度：\n\n```javascript\n// 进度数据结构\n{\n  step: 'init' | 'messages' | 'contacts' | 'done',\n  message: string,\n  current: number,\n  total: number,\n  itemsProcessed: number,\n  errors: string[],\n  startedAt: ISO8601 timestamp,\n  updatedAt: ISO8601 timestamp\n}\n```\n\nAPI 端点：\n\n- `GET /api/sources/:key/progress` - 单个数据源进度\n- `GET /api/sync/progress` - 所有源同步进度\n\n资料来源：[sources/_shared/progress.js:1-40]()\n\n---\n\n## 完整工作流程\n\n```mermaid\ngraph TD\n    A[安装 Minty] --> B[选择运行模式]\n    B --> C[配置数据源]\n    C --> D[运行导入]\n    D --> E[合并数据<br/>merge.js]\n    E --> F[交叉匹配<br/>match.js]\n    F --> G[预计算 AI 洞察]\n    G --> H[访问数据]\n    \n    C --> C1[WhatsApp]\n    C --> C2[Telegram]\n    C --> C3[Email]\n    C --> C4[LinkedIn]\n    \n    H --> H1[Web UI<br/>localhost:3456]\n    H --> H2[Agent 查询<br/>MCP]\n    H --> H3[CLI 查询<br/>network:*]\n```\n\n---\n\n## 下一步\n\n| 任务 | 参考文档 |\n|------|----------|\n| 添加新数据源 | [ARCHITECTURE.md - 添加新导入器](ARCHITECTURE.md) |\n| 改进联系人匹配 | [crm/MATCHING.md](crm/MATCHING.md) |\n| Web UI 开发 | 修改 `crm/ui.html.js` |\n| 性能优化 | `tests/integration/` 集成测试 |\n| 测试运行 | `npm test` |\n\n---\n\n## 常见问题\n\n### Q: 首次运行报错 \"csv-parse not found\"？\n\n确保 `csv-parse` 依赖已安装：\n\n```bash\nnpm install csv-parse\n```\n\n此问题在 v0.3.2 中已修复。\n\n资料来源：[CHANGELOG.md:1-20]()\n\n### Q: 如何验证安装正确？\n\n```bash\nnpm test\n```\n\n运行完整单元测试套件（747 个测试）。\n\n### Q: 数据隐私如何保证？\n\n所有数据存储在本地 `data/` 目录，无遥测、无分析、无电话-home。详见 [SECURITY.md](SECURITY.md)。\n\n---\n\n## 许可证\n\nMinty 采用 **AGPL-3.0** 许可证发布。详情见 [LICENSE](LICENSE)。\n\n如需在专有产品中嵌入 Minty，可申请商业许可：开一个 Issue 联系我们。\n\n---\n\n<a id='page-file-structure'></a>\n\n## 项目文件结构\n\n### 相关页面\n\n相关主题：[项目介绍](#page-introduction), [架构总览](#page-architecture-overview)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n- [crm/server.js](https://github.com/sree-sanak/minty/blob/main/crm/server.js)\n- [crm/staleness.js](https://github.com/sree-sanak/minty/blob/main/crm/staleness.js)\n- [sources/_shared/progress.js](https://github.com/sree-sanak/minty/blob/main/sources/_shared/progress.js)\n- [sources/email/import.js](https://github.com/sree-sanak/minty/blob/main/sources/email/import.js)\n- [sources/google-contacts/sync-hermes.js](https://github.com/sree-sanak/minty/blob/main/sources/google-contacts/sync-hermes.js)\n- [crm/review-server.js](https://github.com/sree-sanak/minty/blob/main/crm/review-server.js)\n- [README.md](https://github.com/sree-sanak/minty/blob/main/README.md)\n</details>\n\n# 项目文件结构\n\n## 概述\n\nMinty 是一个个人关系管理系统（Personal CRM），用于聚合来自多个通讯平台的数据，构建统一的人际关系视图。项目采用模块化架构，将数据导入、合并、搜索和服务层分离，便于扩展和维护。\n\n资料来源：[ARCHITECTURE.md]()\n\n## 顶层目录结构\n\n```\nminty/\n├── crm/                    # 核心 CRM 服务层\n├── sources/                # 各平台数据导入器\n├── hermes/                 # Hermes 工作流集成\n├── scripts/                # 工具脚本\n├── data/                   # 运行时数据目录（gitignored）\n├── docs/                   # 文档\n└── package.json\n```\n\n## 核心模块详解\n\n### crm/ — 核心服务层\n\nCRM 层负责数据合并、API 服务和前端渲染，是整个系统的中枢。\n\n| 文件 | 职责 |\n|------|------|\n| `server.js` | HTTP API 服务器，处理所有 `/api/*` 路由 |\n| `index.js` | 入口文件，路由分发 |\n| `merge.js` | 多源数据标准化、去重、合并 |\n| `match.js` | 跨源匹配算法 |\n| `schema.js` | Contact 和 Interaction 的规范数据模型 |\n| `query.js` | CLI 工具：`npm run stats`、`npm run search` |\n| `network-query.js` | 自然语言查询接口 |\n| `reconnect.js` | 关系淡化检测与草稿生成 |\n| `ai.js` | AI 适配器（本地 Claude Code / Ollama） |\n| `staleness.js` | 数据新鲜度评估 |\n| `sync.js` | 监听 `data/<source>/export/` 目录变化 |\n| `calendar.js` | 日历集成 |\n| `digest.js` | 每周摘要生成 |\n| `meeting-debrief.js` | 会议复盘 |\n| `goal-retro.js` | 目标回顾 |\n| `life-events.js` | 人生大事记录 |\n| `utils.js` | 电话/邮箱/姓名标准化，评分辅助 |\n| `review-server.js` | 匹配审核服务器（人工确认） |\n\n资料来源：[ARCHITECTURE.md]()\n\n### sources/ — 数据导入器\n\n每个数据源独立运行，向 `data/<source>/` 目录写入 JSON 文件。\n\n```\nsources/\n├── _shared/                # 共享工具\n│   └── progress.js         # 统一的进度追踪\n├── whatsapp/               # WhatsApp 导入器\n├── telegram/               # Telegram 导入器\n├── email/                  # Email 导入器（Microsoft Graph）\n├── google-contacts/        # Google Contacts 同步\n├── linkedin/               # LinkedIn CSV 解析\n├── sms/                    # 短信导入\n└── slack/                  # Slack 导入\n```\n\n#### 进度追踪机制\n\n`sources/_shared/progress.js` 提供原子化的进度文件写入：\n\n```javascript\n// 导入器启动时调用\nP.startProgress(DATA_DIR, 'email', { step: 'init', message: 'Connecting…' });\n\n// 导入过程中更新\nP.updateProgress(DATA_DIR, 'email', { \n    step: 'messages', \n    message: 'Fetching via Microsoft Graph…' \n});\n```\n\n进度文件格式（`.progress.json`）包含：step、message、current、total、itemsProcessed、errors、startedAt、updatedAt。\n\n资料来源：[sources/_shared/progress.js:1-50]()\n\n#### Email 导入器\n\n`sources/email/import.js` 支持两种认证方式：\n\n1. **Microsoft Graph API** — 使用 `EMAIL_ACCESS_TOKEN` 和 `EMAIL_TOKEN_TYPE=microsoft`\n2. **通用 OAuth** — 通过 `EMAIL_ACCESS_TOKEN` 环境变量\n\n导入结果写入 `data/email/` 目录，包含消息和联系人。\n\n资料来源：[sources/email/import.js:50-80]()\n\n#### Google Contacts 同步\n\n`sources/google-contacts/sync-hermes.js` 实现基于身份（邮箱/电话）的联系人合并：\n\n```javascript\nfunction mergeByIdentity(contacts) {\n  const byKey = new Map();\n  for (const contact of contacts) {\n    const key = contact.emails[0] || contact.phones[0] || ...;\n    // 合并重复联系人\n  }\n  return [...byKey.values()];\n}\n```\n\n资料来源：[sources/google-contacts/sync-hermes.js:30-45]()\n\n### data/ — 运行时数据目录\n\n数据目录结构如下（受 `CRM_DATA_DIR` 环境变量控制）：\n\n```\ndata/\n├── whatsapp/           chats.json, contacts.json, metadata.json, profile_pics/\n├── linkedin/           export/ (用户上传的 ZIP) + 解析后的 CSV\n├── telegram/           result.json + 解析结果\n├── email/              按账户分文件夹\n├── sms/                按平台分文件夹\n├── google-contacts/    同步数据\n├── unified/            合并后的统一视图\n│   ├── contacts.json       # 唯一联系人列表\n│   ├── interactions.json   # 交互时间线\n│   └── match_overrides.json # 手动匹配覆盖\n└── goals/              目标数据\n```\n\n资料来源：[ARCHITECTURE.md]()\n\n### hermes/ — 工作流集成\n\n`hermes/minty-network-memory/` 包含 Hermes 工作流的技能定义，暴露以下 MCP 工具：\n\n| 工具 | 功能 |\n|------|------|\n| `search_network` | 自然语言网络搜索 |\n| `person_context` | 单个联系人上下文查询 |\n| `workflow_brief` | 目标导向的联系人推荐 |\n| `source_health` | 数据源健康状态检查 |\n\n资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n### scripts/ — 工具脚本\n\n| 脚本 | 用途 |\n|------|------|\n| `minty-mcp-server.js` | MCP 服务器入口 |\n| `sync-labels.js` | GitHub 标签同步 |\n| `seed-dev-data.js` | 开发数据生成 |\n\n资料来源：[README.md]()\n\n## 数据流程架构\n\n```mermaid\ngraph TD\n    subgraph 用户操作\n        A[运行导入器] --> B[source/import.js]\n    end\n    \n    subgraph 源数据层\n        B --> C[data/&lt;source&gt;/]\n        C --> D[whatsapp/]\n        C --> E[email/]\n        C --> F[telegram/]\n        C --> G[linkedin/]\n    end\n    \n    subgraph 合并层\n        H[crm/merge.js] --> I[标准化]\n        I --> J[去重匹配]\n        J --> K[构建时间线]\n        H -.-> L[data/unified/]\n    end\n    \n    subgraph 服务层\n        M[crm/server.js] --> N[REST API]\n        M --> O[crm/query.js]\n        M --> P[crm/network-query.js]\n    end\n    \n    subgraph 前端\n        Q[crm/ui.html.js] --> N\n        R[Hermes Agent] --> S[MCP Tools]\n    end\n    \n    L --> M\n```\n\n## API 路由概览\n\n`crm/server.js` 提供的主要 REST 端点：\n\n| 方法 | 路由 | 功能 |\n|------|------|------|\n| GET | `/api/contacts` | 获取联系人列表 |\n| GET | `/api/contacts/:id` | 获取单个联系人 |\n| GET | `/api/interactions` | 交互时间线 |\n| GET | `/api/sync/progress` | 同步进度 |\n| GET | `/api/sources/:key/progress` | 单源进度 |\n| GET | `/api/goals` | 目标列表 |\n| GET | `/api/goals/:id/pipeline` | 目标联系人管道 |\n| GET | `/api/goals/:id/retro` | 目标回顾 |\n| GET | `/api/export` | 导出数据 |\n| POST | `/api/export` | 创建加密备份 |\n\n资料来源：[crm/server.js:200-280]()\n\n## 数据新鲜度管理\n\n`crm/staleness.js` 实现数据新鲜度检测：\n\n```javascript\nfunction getStalenessMessage(source, days) {\n    if (days === null) return `${label} has never synced`;\n    if (days === 0) return `${label} synced today`;\n    if (days <= 7) return `${label} synced ${days} days ago`;\n    if (days <= 30) return `${label} export is ${days} days old — refresh?`;\n    return `${label} export is ${days} days old — data may be outdated`;\n}\n```\n\n新鲜度等级：\n- **高**：最近 7 天有同步\n- **中**：7-30 天未同步\n- **低**：超过 30 天或从未同步\n\n资料来源：[crm/staleness.js:1-50]()\n\n## 贡献者指南\n\n### 新增导入器\n\n1. 复制简单导入器模板（如 `sources/telegram/`）\n2. 写入 `data/<your-source>/`\n3. 在 `crm/merge.js` 中添加合并步骤\n\n### 匹配算法改进\n\n1. 阅读 `crm/MATCHING.md` 规范\n2. 修改 `crm/match.js`\n3. 在 `tests/` 添加测试用例\n\n### UI 开发\n\n- 编辑 `crm/ui.html.js` 修改 SPA\n- 编辑 `crm/server.js` 调整路由\n- 重启 `npm run crm` 以热更新\n\n资料来源：[ARCHITECTURE.md]()\n\n## 环境变量配置\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `CRM_DATA_DIR` | `./data` | 数据根目录 |\n| `EMAIL_EXPORT_DIR` | - | Email 导出目录 |\n| `EMAIL_ACCESS_TOKEN` | - | Graph API 令牌 |\n| `MINTY_USER_UUID` | - | 用户 UUID |\n| `AI_BACKEND` | `claude` | AI 后端（ollama/claude） |\n\n## 模块依赖关系\n\n```mermaid\ngraph LR\n    subgraph 数据源\n        A[WhatsApp] --> G[merge.js]\n        B[Email] --> G\n        C[Telegram] --> G\n        D[LinkedIn] --> G\n    end\n    \n    G --> H[unified/contacts.json]\n    G --> I[unified/interactions.json]\n    \n    H --> J[server.js]\n    I --> J\n    \n    J --> K[ui.html.js]\n    J --> L[MCP Server]\n    J --> M[CLI Query]\n\n---\n\n<a id='page-architecture-overview'></a>\n\n## 架构总览\n\n### 相关页面\n\n相关主题：[项目介绍](#page-introduction), [AI 后端配置](#page-ai-backend), [数据存储结构](#page-data-storage)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n- [crm/server.js](https://github.com/sree-sanak/minty/blob/main/crm/server.js)\n- [crm/schema.js](https://github.com/sree-sanak/minty/blob/main/crm/schema.js)\n- [crm/staleness.js](https://github.com/sree-sanak/minty/blob/main/crm/staleness.js)\n- [sources/_shared/progress.js](https://github.com/sree-sanak/minty/blob/main/sources/_shared/progress.js)\n- [sources/email/import.js](https://github.com/sree-sanak/minty/blob/main/sources/email/import.js)\n- [hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md)\n</details>\n\n# 架构总览\n\n## 项目概述\n\nMinty 是一个本地优先的 CRM 系统，用于聚合来自多个数据源的联系人与交互记录，并通过本地 AI（Claude Code CLI 或 Ollama）生成洞察和关系评分。项目完全离线运行，所有数据存储在本地 `data/` 目录，无遥测、无分析、无云端同步。资料来源：[README.md](https://github.com/sree-sanak/minty/blob/main/README.md)\n\n## 核心模块架构\n\n项目采用模块化架构，主要分为三个顶层目录：\n\n| 模块 | 路径 | 功能描述 |\n|------|------|----------|\n| **crm/** | `crm/` | 应用主程序 + 确定性的 AI 检索引擎 |\n| **sources/** | `sources/` | 每个数据源的独立导入器 |\n| **scripts/** | `scripts/` | CLI/MCP 入口点，供 OpenClaw、Hermes 等 agent 调用 |\n\n资料来源：[README.md](https://github.com/sree-sanak/minty/blob/main/README.md)\n\n```\ncrm/        # 应用核心 + 检索引擎\nscripts/    # CLI/MCP 入口\nsources/    # 数据源导入器\nee/         # 预留商业功能\ndata/       # 本地数据（gitignored）\ndocs/       # 文档 + ADR\ntests/      # 单元/集成/e2e 测试\n```\n\n## CRM 模块详细架构\n\nCRM 模块是系统的核心，包含以下关键文件：\n\n| 文件 | 功能 |\n|------|------|\n| `ui.html.js` | 单页应用外壳（HTML/CSS/JS 合一模板） |\n| `merge.js` | 加载各源数据、规范化、去重、写入 `unified/contacts.json` 和 `interactions.json` |\n| `match.js` | 跨源匹配算法，读取 MATCHING.md 规范 |\n| `schema.js` | Contact 和 Interaction 的规范记录格式 |\n| `query.js` | CLI 工具：`npm run stats`、`npm run search` |\n| `network-query.js` | 自然语言\"Ask\"视图 |\n| `reconnect.js` | \"渐行渐远的人\"界面 + 草稿生成 |\n| `ai.js` | 本地 Claude Code CLI / Ollama 适配器，无云端 API |\n| `staleness.js` | 标记陈旧联系人数据 |\n| `sync.js` | 监听 `data/<source>/export/` 目录变化并触发导入器 |\n| `calendar.js`、`digest.js`、`meeting-debrief.js`、`goal-retro.js`、`life-events.js` | 基于统一存储构建的高级界面 |\n| `utils.js` | 电话/邮箱/姓名规范化、评分辅助函数、内存联系人索引 |\n\n资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n### 数据模型（Schema）\n\n系统定义了规范的联系人与交互记录格式：\n\n```javascript\n// Contact 核心结构\n{\n  id: string,\n  name: string,\n  phones: string[],\n  emails: string[],\n  sources: { [sourceName]: sourceData },\n  relationshipScore: number,\n  daysSinceContact: number,\n  activeChannels: string[],\n  // ...\n}\n\n// Interaction 核心结构\n{\n  id: string,\n  timestamp: string,\n  source: string,\n  body: string,\n  subject: string,\n  participants: string[],\n  // ...\n}\n```\n\n修改数据模型时，应首先编辑 `schema.js`，其余模块随之更新。资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n## 数据流架构\n\n数据生命周期端到端流程如下：\n\n```mermaid\ngraph TD\n    A[\"用户运行导入器\"] --> B[\"源导入器<br/>sources/<src>/...\"]\n    B --> C[\"data/<source>/*.json<br/>每源记录\"]\n    C --> D[\"crm/merge.js\"]\n    D --> E[\"规范化手机/邮箱/姓名\"]\n    D --> F[\"跨源去重<br/>crm/match.js, MATCHING.md\"]\n    D --> G[\"构建统一交互时间线\"]\n    E --> H[\"data/unified/contacts.json\"]\n    F --> H\n    G --> I[\"data/unified/interactions.json\"]\n    \n    H --> J[\"crm/server.js<br/>REST API\"]\n    I --> J\n    J --> K[\"ui.html.js<br/>单页应用\"]\n    \n    J --> L[\"ai.js<br/>Claude Code CLI / Ollama\"]\n    L --> M[\"生成洞察、评分、摘要\"]\n    M --> H\n```\n\n资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n## 导入器（Sources）架构\n\n每个数据源是独立的导入模块，写入 `data/<source>/` 目录。统一存储由 `crm/merge.js` 重建。\n\n### 支持的数据源\n\n| 数据源 | 路径 | 说明 |\n|--------|------|------|\n| WhatsApp | `data/whatsapp/` | chats.json, contacts.json, metadata.json, profile_pics/ |\n| LinkedIn | `data/linkedin/` | 用户上传的 ZIP 包 + 解析后的 CSV |\n| Telegram | `data/telegram/` | result.json + 解析结果 |\n| Email | `data/email/` | 按账户分文件夹 |\n| SMS | `data/sms/` | 按平台分文件夹 |\n| Google Contacts | `data/google-contacts/` | 同步数据 |\n| 统一存储 | `data/unified/` | contacts.json, interactions.json, match_overrides.json |\n\n资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n### 导入器进度追踪\n\n所有导入器使用统一的进度文件 `.progress.json`，包含标准字段：\n\n```javascript\n{\n  source: string,        // 数据源标识\n  step: string,          // 当前步骤\n  message: string,       // 状态消息\n  current: number,       // 当前进度\n  total: number,         // 总数\n  itemsProcessed: number,\n  errors: string[],\n  startedAt: string,     // ISO 时间戳\n  updatedAt: string      // ISO 时间戳\n}\n```\n\n进度操作函数位于 `sources/_shared/progress.js`：\n\n- `startProgress(dataDir, source, initial)` — 初始化进度\n- `updateProgress(dataDir, source, patch)` — 更新进度\n- `readProgress(dataDir, source)` — 读取进度\n\n资料来源：[sources/_shared/progress.js](https://github.com/sree-sanak/minty/blob/main/sources/_shared/progress.js)\n\n### 添加新导入器\n\n添加新数据源的步骤：\n\n1. 复制简单导入器作为模板（如 `sources/telegram/import.js`）\n2. 遵循其文件布局\n3. 写入 `data/<your-source>/`\n4. 在 `crm/merge.js` 中添加合并步骤\n\n资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n## API 路由体系\n\n`crm/server.js` 提供完整的 REST API，所有接口前缀为 `/api/`：\n\n| 方法 | 路径 | 功能 |\n|------|------|------|\n| GET | `/api/contacts` | 获取联系人列表 |\n| GET | `/api/contacts/:id` | 获取单个联系人详情 |\n| GET | `/api/contacts/:id/interactions` | 获取联系人交互记录 |\n| GET/POST | `/api/export` | 导入/导出数据 |\n| GET | `/api/digest` | 周报摘要 |\n| GET | `/api/goals` | 目标列表 |\n| POST | `/api/goals/:id/assign` | 分配联系人到目标 |\n| GET | `/api/goals/:id/pipeline` | 目标漏斗视图 |\n| GET | `/api/goals/:id/retro` | 目标回顾 |\n| GET | `/api/meetings/debriefs/pending` | 待处理会议总结 |\n| GET/POST | `/api/meetings/:id/debrief` | 会议总结 |\n| GET | `/api/sources/:key/progress` | 数据源同步进度 |\n| GET | `/api/sync/progress` | 全部数据源进度 |\n| GET | `/api/notifications` | 通知列表 |\n| POST | `/api/notifications/:type/dismiss` | 忽略通知 |\n| GET | `/api/meta` | 元信息（demo 模式、数据目录等） |\n\n资料来源：[crm/server.js](https://github.com/sree-sanak/minty/blob/main/crm/server.js)\n\n## 数据陈旧性检测\n\n`crm/staleness.js` 负责检测数据新鲜度，提供两种检测维度：\n\n### 数据源级别陈旧性\n\n| 陈旧天数 | 严重程度 | 消息 |\n|----------|----------|------|\n| 从未同步 | warning | `{label} 从未同步` |\n| 0 天 | info | `{label} 今天已同步` |\n| 1 天 | info | `{label} 昨天已同步` |\n| ≤7 天 | info | `{label} {n} 天前同步` |\n| ≤30 天 | warning | `{label} 导出已 {n} 天 — 需要刷新？` |\n| >30 天 | error | `{label} 导出已 {n} 天 — 数据可能已过时` |\n\n### 联系人数据置信度\n\n根据来源新鲜度计算联系人数据置信级别：\n\n| 级别 | 条件 |\n|------|------|\n| high | 有活跃交互且来源新鲜 |\n| medium | 有交互但部分来源陈旧 |\n| low | 无交互或无来源数据 |\n\n资料来源：[crm/staleness.js](https://github.com/sree-sanak/minty/blob/main/crm/staleness.js)\n\n## AI 后端架构\n\nMinty 刻意避免运行时 LLM 费用，支持两种本地后端：\n\n| 后端 | 配置 | 说明 |\n|------|------|------|\n| **Claude Code CLI** | 默认（无配置） | 调用 `claude --print`，已登录用户免费使用 |\n| **Ollama** | `AI_BACKEND=ollama` | 完全离线，支持 qwen2.5:7b 等本地模型 |\n\nAI 输出（洞察、摘要、重新联系草稿、查询排名）预计算并缓存于 `data/unified/*.json`，Web 服务器读取这些静态文件。资料来源：[README.md](https://github.com/sree-sanak/minty/blob/main/README.md)\n\n## MCP 集成（Hermes）\n\nMinty 提供 MCP（Model Context Protocol）服务器供 AI Agent 使用，位于 `scripts/minty-mcp-server.js`：\n\n| 工具 | 功能 |\n|------|------|\n| `search_network` | 自然语言网络搜索 |\n| `person_context` | 查询特定联系人详情 |\n| `workflow_brief` | 生成目标导向简报 |\n| `source_health` | 检查数据源健康状态 |\n\n```javascript\n// 使用示例\n{\n  \"query\": \"investors in London who know about AI\",\n  \"limit\": 5\n}\n```\n\nMinty 与 Hermes 集成的就绪级别：\n\n| 级别 | 要求 |\n|------|------|\n| Demo-ready | `npm run seed:demo` + `npm run mcp` 可用 |\n| Dogfood-ready | `npm run memory:refresh` 成功，无直接联系方式输出 |\n| Hermes-native | 技能已安装，MCP 服务器已注册 |\n\n资料来源：[hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md)\n\n## 性能优化要点\n\n大数据集场景下的性能瓶颈通常在合并路径，优化策略：\n\n| 场景 | 建议 |\n|------|------|\n| 大量联系人 | 优化 `crm/merge.js` 中的去重算法 |\n| 跨源匹配 | 改进 `crm/match.js` 的 MATCHING.md 规则 |\n| UI 响应 | 缓存预计算的 AI 输出 |\n| 测试 | 使用 `tests/integration/` 的 fixture 性能测试 |\n\n资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n## 贡献指南\n\n### 开发环境启动\n\n```bash\nnpm run crm        # 启动 CRM 服务器（热重载）\nnpm run seed:demo  # 生成演示数据\nnpm run test       # 运行测试套件\n```\n\n### 代码修改优先级\n\n1. **修改数据模型** → 首先编辑 `schema.js`\n2. **添加新导入器** → 复制 `sources/telegram/import.js` 模板\n3. **改进匹配算法** → 编辑 `crm/match.js`，添加 `tests/` fixture\n4. **UI 工作** → 编辑 `crm/ui.html.js` 和 `crm/server.js`\n\n资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n---\n\n<a id='page-ai-backend'></a>\n\n## AI 后端配置\n\n### 相关页面\n\n相关主题：[架构总览](#page-architecture-overview), [网络查询系统](#page-network-query)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md) — 项目架构总览\n- [crm/server.js](https://github.com/sree-sanak/minty/blob/main/crm/server.js) — 服务器端实现\n- [hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md) — 网络记忆技能配置\n- [crm/agent-source-health.js](https://github.com/sree-sanak/minty/blob/main/crm/agent-source-health.js) — 数据源健康检查\n- [sources/_shared/progress.js](https://github.com/sree-sanak/minty/blob/main/sources/_shared/progress.js) — 导入进度追踪\n- [crm/staleness.js](https://github.com/sree-sanak/minty/blob/main/crm/staleness.js) — 数据新鲜度检测\n\n> 注：本页所需的部分文件（如 `crm/digest.js`、`crm/evidence-patches.js`、`.env.example`）在当前检索上下文中未找到，以下内容基于已获取的源码片段进行概述。\n\n</details>\n\n# AI 后端配置\n\n## 概述\n\nMinty 项目采用**本地优先的 AI 策略**，不依赖任何云端 API 服务。AI 功能通过 `crm/ai.js` 模块实现，该模块作为适配器，同时支持 **Claude Code CLI** 和 **Ollama** 两种本地推理引擎。\n\n资料来源：[ARCHITECTURE.md]()\n\n## 架构设计\n\n### AI 适配器架构\n\n```mermaid\ngraph TD\n    A[用户请求] --> B[crm/server.js]\n    B --> C{AI 引擎选择}\n    C -->|Claude Code CLI| D[claude-code-adapter]\n    C -->|Ollama| E[ollama-adapter]\n    D --> F[本地 Claude Code 进程]\n    E --> G[本地 Ollama 服务]\n    F --> H[结构化响应]\n    G --> H\n    H --> I[UI 层渲染]\n```\n\n资料来源：[ARCHITECTURE.md]()\n\n### 设计原则\n\n| 原则 | 说明 |\n|------|------|\n| **本地化** | 所有 AI 推理在本地执行，无云端数据传输 |\n| **隐私优先** | 联系人数据和交互内容不离开用户设备 |\n| **离线可用** | 依赖 Ollama 或 Claude Code CLI 的本地安装 |\n| **无供应商锁定** | 支持切换不同的本地推理引擎 |\n\n资料来源：[ARCHITECTURE.md]()\n\n## MCP 工具集成\n\n### 网络记忆工具\n\nMinty 通过 MCP（Model Context Protocol）暴露网络记忆能力，供 AI Agent 调用：\n\n```json\n{\n  \"tools\": {\n    \"search_network\": \"自然语言搜索联系人\",\n    \"person_context\": \"查询特定人物的关系上下文\",\n    \"workflow_brief\": \"生成目标导向的人物简报\",\n    \"source_health\": \"检查数据源健康状态\"\n  }\n}\n```\n\n资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n### 工具调用示例\n\n```json\n// 搜索网络\n{ \"query\": \"investors in London who know about AI\", \"limit\": 5 }\n\n// 人物上下文查询\n{ \"person\": \"Alice Müller\", \"limit\": 3 }\n\n// 目标简报生成\n{ \"goal\": \"Find EU crypto insurance distribution partners\", \"limit\": 5 }\n\n// 数据源健康检查\n{ \"source\": \"telegram\" }\n```\n\n资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n## 数据源健康检查\n\n### 健康状态等级\n\nAI 后端在执行查询前会评估数据源的可信度：\n\n| 状态 | 描述 | AI 可用性 |\n|------|------|----------|\n| `ready` | 数据源正常、可回答问题 | ✅ 可用 |\n| `stale` | 数据较旧（超过 7 天未同步） | ⚠️ 有限可用 |\n| `limited` | 存在警告（无联系人、无证据等） | ⚠️ 有限可用 |\n| `blocked` | 显式请求不可用的数据源 | ❌ 不可用 |\n| `error` | 同步错误 | ❌ 不可用 |\n\n资料来源：[crm/agent-source-health.js]()\n\n### 健康检查流程\n\n```mermaid\ngraph TD\n    A[接收源过滤请求] --> B[验证源标识符]\n    B --> C{源有效?}\n    C -->|否| D[标记 invalid_source]\n    C -->|是| E[遍历每个数据源]\n    E --> F[统计联系人数]\n    F --> G[统计交互记录数]\n    G --> H[获取最后同步时间]\n    H --> I{新鲜度判断}\n    I -->|fresh| J[status: ready]\n    I -->|stale| K[status: stale]\n    I -->|unknown| L[status: limited]\n    J --> M[生成警告列表]\n    K --> M\n    L --> M\n    D --> M\n    M --> N[返回 answerable 状态]\n```\n\n资料来源：[crm/agent-source-health.js]()\n\n## 导入进度追踪\n\nAI 功能依赖高质量的数据导入，进度系统为导入过程提供实时反馈：\n\n### 进度状态模型\n\n```javascript\n{\n    source: String,           // 数据源标识符\n    step: String,             // 当前步骤\n    message: String,          // 人类可读消息\n    current: Number,          // 当前处理项\n    total: Number,            // 总项数\n    itemsProcessed: Number,   // 已处理项数\n    errors: Array,            // 错误列表\n    startedAt: ISO8601,       // 开始时间\n    updatedAt: ISO8601        // 更新时间\n}\n```\n\n资料来源：[sources/_shared/progress.js]()\n\n### API 端点\n\n| 端点 | 方法 | 描述 |\n|------|------|------|\n| `/api/sources/:key/progress` | GET | 获取指定数据源的导入进度 |\n| `/api/sync/progress` | GET | 获取所有数据源的同步进度 |\n\n资料来源：[ARCHITECTURE.md]()\n\n## 数据新鲜度检测\n\n### 新鲜度阈值\n\n| 条件 | 状态 | 阈值 |\n|------|------|------|\n| 24 小时内同步 | 新鲜 | `fresh` |\n| 7 天内同步 | 可接受 | `stale` |\n| 超过 7 天 | 过期 | `outdated` |\n\n资料来源：[crm/staleness.js]()\n\n### 警告消息示例\n\n```javascript\n\"Google Contacts  export is 14 days old — data may be outdated\"\n\"Telegram has never synced\"\n\"LinkedIn synced today\"\n```\n\n资料来源：[crm/staleness.js]()\n\n## 摘要生成与目标回顾\n\n### 每周摘要功能\n\n服务器端 `handleGetDigest` 处理器读取预生成的摘要文件：\n\n```javascript\nfunction handleGetDigest(req, res, params, paths) {\n    try { json(res, JSON.parse(fs.readFileSync(paths.digest, 'utf8'))); }\n    catch { json(res, null); }\n}\n```\n\n资料来源：[crm/server.js]()\n\n### 目标关联人物排名\n\nAI 系统根据目标关键词对联系人进行相关性排序：\n\n```javascript\ngoalSections = goals.map(goal => {\n    const ranked = rankContactsForGoal(contacts, goal.text, 5);\n    return {\n        goalId: goal.id,\n        goalText: goal.text,\n        contacts: ranked.map(c => ({\n            id: c.id,\n            name: c.name,\n            company: c.sources?.linkedin?.company || null,\n            goalRelevance: c.goalRelevance,\n            meetingBrief: ins ? ins.meetingBrief : null,\n        }))\n    };\n});\n```\n\n资料来源：[crm/server.js]()\n\n## 敏感信息保护\n\n### 数据脱敏机制\n\n进度追踪模块内置敏感信息过滤：\n\n```javascript\nfunction redactErrorText(value) {\n    return String(value)\n        .replace(/^\\s*at\\s+[^\\n]+/gm, '[redacted-stack]')\n        .replace(/([\"'`])[^\"'`\\n]*[\\\\/][^\"'`\\n]*\\1/g, '$1[redacted-path]$1')\n        .replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}/gi, '[redacted-email]')\n        .replace(/\\bauthorization\\s*[:=]\\s*Bearer\\s+[^\\s,;]+/gi, '[redacted-credential]')\n        // ... 更多脱敏规则\n}\n```\n\n资料来源：[sources/_shared/progress.js]()\n\n### 脱敏规则表\n\n| 模式 | 替换结果 |\n|------|----------|\n| 邮箱地址 | `[redacted-email]` |\n| Bearer 令牌 | `Bearer [redacted-credential]` |\n| API 密钥 | `[redacted-credential]` |\n| 文件路径 | `[redacted-path]` |\n| 堆栈跟踪 | `[redacted-stack]` |\n\n资料来源：[sources/_shared/progress.js]()\n\n## 快速开始\n\n### 前置要求\n\n1. 安装 **Node.js 20+**\n2. 安装 **Claude Code CLI** 或 **Ollama**\n3. 配置数据源导入\n\n### 验证 AI 配置\n\n```bash\n# 启动 MCP 服务器\nnpm run mcp\n\n# 验证网络记忆功能\nnpm run agent -- \"investors in London\"\n```\n\n资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n## 故障排查\n\n| 问题 | 可能原因 | 解决方案 |\n|------|----------|----------|\n| AI 返回空结果 | 数据源未同步 | 运行 `npm run sync` |\n| 源健康检查失败 | 缺少数据源配置 | 检查 `.env` 配置 |\n| 连接超时 | Ollama 服务未启动 | 启动 `ollama serve` |\n| 权限错误 | Claude Code CLI 未授权 | 运行 `claude` 完成认证 |\n\n## 相关文档\n\n- [架构总览](./ARCHITECTURE.md)\n- [数据源导入](./SOURCES.md)\n- [匹配算法](./MATCHING.md)\n- [发布流程](./RELEASING.md)\n\n---\n\n<a id='page-data-sources'></a>\n\n## 数据源导入\n\n### 相关页面\n\n相关主题：[联系人合并与去重](#page-contact-merging), [数据存储结构](#page-data-storage), [快速开始](#page-quick-start)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [sources/whatsapp/export.js](https://github.com/sree-sanak/minty/blob/main/sources/whatsapp/export.js)\n- [sources/linkedin/import.js](https://github.com/sree-sanak/minty/blob/main/sources/linkedin/import.js)\n- [sources/telegram/import.js](https://github.com/sree-sanak/minty/blob/main/sources/telegram/import.js)\n- [sources/email/import.js](https://github.com/sree-sanak/minty/blob/main/sources/email/import.js)\n- [sources/google-contacts/import.js](https://github.com/sree-sanak/minty/blob/main/sources/google-contacts/import.js)\n- [sources/sms/import.js](https://github.com/sree-sanak/minty/blob/main/sources/sms/import.js)\n- [sources/_shared/progress.js](https://github.com/sree-sanak/minty/blob/main/sources/_shared/progress.js)\n</details>\n\n# 数据源导入\n\n数据源导入是 Minty CRM 的核心功能模块，负责从多种外部平台收集联系人信息和交互记录。每个数据源（Source）都是独立的导入单元，遵循统一的数据写入规范，最终输出到 `data/<source>/` 目录下的结构化 JSON 文件。\n\n## 系统架构\n\n### 导入器层级结构\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                    sources/ 目录结构                          │\n├─────────────────────────────────────────────────────────────┤\n│  whatsapp/export.js        实时 Web 端导入                   │\n│  linkedin/import.js        LinkedIn ZIP 压缩包导入           │\n│  linkedin/connect.js        LinkedIn 自动同步（实验性）        │\n│  telegram/import.js        Telegram JSON 导出导入             │\n│  email/import.js            Gmail/IMAP 邮件导入               │\n│  google-contacts/import.js Google 通讯录 OAuth 导入           │\n│  sms/import.js              短信平台导出导入                  │\n│  apollo/enrich.js           Apollo 联系人丰富化（可选）        │\n├─────────────────────────────────────────────────────────────┤\n│  _shared/progress.js       统一的进度追踪模块                │\n└─────────────────────────────────────────────────────────────┘\n```\n\n所有导入器共享 `sources/_shared/progress.js` 中的进度追踪机制，确保 UI 层能够统一展示各数据源的同步状态。\n\n资料来源：[ARCHITECTURE.md]()\n\n### 数据流向\n\n```mermaid\ngraph TD\n    A[用户启动导入器] --> B[数据源平台]\n    B --> C[源数据获取]\n    C --> D[数据解析与标准化]\n    D --> E[data/&lt;source&gt;/]\n    E --> F[crm/merge.js]\n    F --> G[data/unified/]\n    G --> H[统一联系人视图]\n    G --> I[交互时间线]\n```\n\n资料来源：[ARCHITECTURE.md]()\n\n## 支持的数据源\n\n| 数据源 | 导入模式 | 认证方式 | 增量支持 | 入口命令 |\n|--------|----------|----------|----------|----------|\n| WhatsApp | 实时监听 | QR 码配对 | ✅ | `npm run whatsapp` |\n| LinkedIn | 一次性 | 官方数据导出 ZIP | ❌ | `npm run linkedin` |\n| LinkedIn Sync | 实验性 | 自动化登录 | ✅ | `npm run linkedin:connect` |\n| Telegram | 一次性 | 官方 JSON 导出 | ❌ | `npm run telegram` |\n| Email/Gmail | 增量 | OAuth 2.0 / IMAP | ✅ | OAuth 流程 |\n| Google Contacts | 增量 | OAuth 2.0 | ✅ | OAuth 流程 |\n| SMS | 一次性 | 平台导出格式 | ❌ | `npm run sms` |\n| Apollo | 可选 | API 密钥 | - | 手动触发 |\n\n资料来源：[ARCHITECTURE.md]()\n\n## 进度追踪机制\n\n### 统一进度文件\n\n每个导入器在运行时会向其数据目录写入 `.progress.json` 文件，记录当前导入进度。\n\n```json\n{\n  \"source\": \"whatsapp\",\n  \"step\": \"messages\",\n  \"message\": \"正在同步 15/32: 产品团队群\",\n  \"current\": 15,\n  \"total\": 32,\n  \"itemsProcessed\": 2847,\n  \"startedAt\": \"2025-01-15T10:30:00.000Z\",\n  \"updatedAt\": \"2025-01-15T10:35:22.456Z\"\n}\n```\n\n资料来源：[sources/_shared/progress.js:1-80]()\n\n### 进度步骤定义\n\n| step 值 | 含义 | 典型 message 示例 |\n|---------|------|---------------------|\n| `init` | 初始化 | \"Starting…\" |\n| `contacts` | 正在同步联系人 | \"Loading contacts…\" |\n| `messages` | 正在同步消息/交互 | \"Syncing 15/32: 群组名\" |\n| `merging` | 合并到统一存储 | \"Merging into unified store\" |\n| `done` | 完成 | \"Import complete\" |\n| `error` | 错误 | 错误信息摘要 |\n\n资料来源：[sources/_shared/progress.js:50-70]()\n\n### 进度状态计算\n\n进度文件中的 `active` 状态由 `step !== 'done' && step !== 'error'` 派生而来，用于前端判断同步是否仍在进行中。\n\n## WhatsApp 导入\n\nWhatsApp 导入器是唯一采用实时监听模式的源，使用 `whatsapp-web.js` 库通过 WebSocket 连接手机端应用。\n\n### 核心流程\n\n1. **首次运行**：显示 QR 码，用户需在 WhatsApp 手机端扫描\n2. **会话恢复**：后续运行自动复用已存储的会话凭证\n3. **增量同步**：仅拉取上次同步后的新消息\n\n```javascript\n// 关键参数\nWHATSAPP_MSG_LIMIT=500  // 单次最多获取消息数（环境变量）\n```\n\n资料来源：[crm/server.js:150-180]()\n\n### 输出文件结构\n\n```\ndata/whatsapp/\n├── chats.json        // 聊天列表元数据\n├── contacts.json     // 联系人信息\n├── metadata.json     // 同步会话信息\n├── profile_pics/     // 头像缓存目录\n└── .progress.json    // 进度文件\n```\n\n## LinkedIn 导入\n\n### ZIP 导出模式\n\n1. 用户在 LinkedIn 网站请求数据导出（Settings → Data Privacy → Get a copy of your data）\n2. 选择 **Connections** 和 **Messages** 选项\n3. 下载 ZIP 文件后拖入 Sources 视图，或指定目录：\n\n```bash\nLINKEDIN_EXPORT_DIR=/path/to/extracted npm run linkedin\n```\n\n### 自动同步模式（实验性）\n\n该模式通过自动化浏览器操作实现 ToS 边界附近的登录抓取：\n\n- 使用 headful 浏览器首次登录获取凭证\n- 凭证缓存后以 headless 模式复用\n- 状态存储在 `data/linkedin/` 目录\n\n资料来源：[ARCHITECTURE.md]()\n\n## Telegram 导入\n\nTelegram 导出采用官方 Desktop 客户端的 JSON 格式。\n\n### 导出步骤\n\n1. Telegram Desktop → Settings → Advanced → Export Telegram Data\n2. 选择 **Personal chats** 和 **Contacts**\n3. 格式选择 **JSON**\n4. 将 `result.json` 放入 Sources 视图\n\n```bash\nTELEGRAM_EXPORT_FILE=/path/to/result.json npm run telegram\n```\n\n### 解析能力\n\n- 个人聊天记录\n- 群组消息（含参与者列表）\n- 联系人信息\n\n## Email/Gmail 导入\n\n### OAuth 认证流程（推荐）\n\n1. 用户在 Sources 视图点击 \"Connect Gmail\"\n2. 使用 Google OAuth Device Flow 完成授权\n3. 权限范围为只读访问\n\n需要配置以下环境变量：\n\n```\nGOOGLE_CLIENT_ID=<your-client-id>\nGOOGLE_CLIENT_SECRET=<your-client-secret>\n```\n\n### IMAP 备选方案\n\n支持任意提供商的 IMAP 协议：\n\n```bash\nEMAIL_HOST=imap.gmail.com\nEMAIL_PORT=993\nEMAIL_USER=your-email@gmail.com\nEMAIL_PASS=app-password\n```\n\n## Google Contacts 导入\n\n通过 Google People API 进行 OAuth 增量同步，自动获取用户通讯录中的：\n\n- 姓名\n- 电话号码\n- 邮箱地址\n- 组织信息（公司、职位）\n- 地址信息\n\n## SMS 导入\n\nSMS 导入器解析平台导出的 XML 格式数据，支持：\n\n- 普通短信（SMS）\n- 多媒体消息（MMS）\n- 通话记录（Call Log）\n\n### 解析数据类型\n\n| 类型 | 字段 | 说明 |\n|------|------|------|\n| SMS/MMS | `body`, `direction`, `timestamp` | 消息内容和方向 |\n| MMS | `hasMedia`, `contactName` | 含媒体标识 |\n| Call Log | `callKind`, `duration` | 通话类型和时长 |\n\n资料来源：[sources/sms/import.js:60-100]()\n\n## Apollo 联系人丰富化\n\nApollo 是一个可选的付费数据丰富服务，用于增强现有联系人的公开信息：\n\n- 公司位置\n- 职业头衔\n- Twitter 链接\n- 职业履历\n\n此模块独立于主导入流程，需手动触发：\n\n```bash\nnode sources/apollo/enrich.js\n```\n\n## 数据合并\n\n### merge.js 核心职责\n\n所有导入器完成后，运行 `crm/merge.js` 执行统一合并：\n\n1. **数据标准化**：统一电话、邮箱、姓名的格式\n2. **跨源去重**：识别同一人的不同来源记录\n3. **构建交互时间线**：聚合所有源的交互事件\n\n```bash\nnode crm/merge.js\n```\n\n### 输出文件\n\n```\ndata/unified/\n├── contacts.json          // 统一联系人记录\n├── interactions.json      // 聚合交互事件\n├── match_overrides.json   // 手动匹配覆盖\n└── group-memberships.json  // 群组关系\n```\n\n资料来源：[ARCHITECTURE.md]()\n\n## 环境变量配置\n\n| 变量名 | 适用源 | 用途 |\n|--------|--------|------|\n| `CRM_DATA_DIR` | 全局 | 数据根目录 |\n| `WHATSAPP_MSG_LIMIT` | WhatsApp | 单次消息拉取上限 |\n| `LINKEDIN_EXPORT_DIR` | LinkedIn | ZIP 解压路径 |\n| `TELEGRAM_EXPORT_FILE` | Telegram | JSON 导出文件路径 |\n| `GOOGLE_CLIENT_ID` | Gmail/Contacts | OAuth 客户端 ID |\n| `EMAIL_*` | Email | IMAP 连接参数 |\n\n## 命令速查\n\n| 命令 | 功能 |\n|------|------|\n| `npm run whatsapp` | 启动 WhatsApp 导入器 |\n| `npm run linkedin` | 启动 LinkedIn ZIP 导入器 |\n| `npm run telegram` | 启动 Telegram 导入器 |\n| `npm run sms` | 启动 SMS 导入器 |\n| `npm run crm` | 启动 CRM 服务端（含同步 API） |\n\n## 贡献指南\n\n### 添加新导入器\n\n1. 复制现有简单导入器作为模板（如 `sources/telegram/import.js`）\n2. 遵循目录结构：`data/<source>/` 写入 JSON 文件\n3. 使用 `sources/_shared/progress.js` 报告进度\n4. 在 `crm/merge.js` 中添加对应的合并逻辑\n\n资料来源：[ARCHITECTURE.md]()\n\n### 性能优化\n\n当数据集较大时，合并路径通常是性能瓶颈。建议使用 `tests/integration/` 中的基于 fixture 的性能测试进行验证。\n\n---\n\n<a id='page-contact-merging'></a>\n\n## 联系人合并与去重\n\n### 相关页面\n\n相关主题：[数据源导入](#page-data-sources), [数据存储结构](#page-data-storage)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [crm/match.js](https://github.com/sree-sanak/minty/blob/main/crm/match.js)\n- [crm/merge.js](https://github.com/sree-sanak/minty/blob/main/crm/merge.js)\n- [crm/identity-candidates.js](https://github.com/sree-sanak/minty/blob/main/crm/identity-candidates.js)\n- [crm/MATCHING.md](https://github.com/sree-sanak/minty/blob/main/crm/MATCHING.md)\n- [crm/schema.js](https://github.com/sree-sanak/minty/blob/main/crm/schema.js)\n- [sources/_shared/progress.js](https://github.com/sree-sanak/minty/blob/main/sources/_shared/progress.js)\n</details>\n\n# 联系人合并与去重\n\n## 概述\n\n联系人合并与去重是 Minty CRM 的核心功能之一，负责将来自不同数据源（如 Email、LinkedIn、Telegram、Google Contacts 等）的联系人记录整合为统一视图。当用户从多个平台导入数据时，同一个人可能在不同来源中以不同的名字、电话或邮箱形式出现，合并系统通过智能匹配算法识别这些重复记录并将其合并，同时保留各来源的原始信息。\n\n该模块在架构中处于数据处理的核心位置——所有数据源的导入完成后，最终都会经过合并流程生成 `data/unified/contacts.json` 和 `data/unified/interactions.json`，为上层业务功能（如目标追踪、会议总结、人生事件识别）提供统一的联系人数据源。资料来源：[ARCHITECTURE.md]()\n\n## 核心组件\n\nMinty 的联系人合并与去重系统由以下几个核心文件组成：\n\n| 组件文件 | 职责 | 关键功能 |\n|---------|------|---------|\n| `crm/merge.js` | 数据合并主入口 | 加载各源数据、规范化、写入统一存储 |\n| `crm/match.js` | 跨源匹配算法 | 根据规则识别潜在重复联系人 |\n| `crm/identity-candidates.js` | 身份候选生成 | 生成待匹配的联系人候选对 |\n| `crm/MATCHING.md` | 匹配规则规范文档 | 定义匹配逻辑与置信度标准 |\n| `crm/schema.js` | 数据模型定义 | 规范 Contact 和 Interaction 的数据结构 |\n\n资料来源：[ARCHITECTURE.md]()\n\n## 数据流架构\n\n```mermaid\ngraph TD\n    A[数据源导入] --> B[sources/email/import.js]\n    A --> C[sources/linkedin/import.js]\n    A --> D[sources/telegram/import.js]\n    A --> E[sources/google-contacts/import.js]\n    \n    B --> F[data/&lt;source&gt;/]\n    C --> F\n    D --> F\n    E --> F\n    \n    F --> G[crm/merge.js]\n    G --> H[match.js 匹配算法]\n    H --> I[match_overrides.json 人工干预]\n    I --> G\n    \n    G --> J[data/unified/contacts.json]\n    G --> K[data/unified/interactions.json]\n    \n    J --> L[上层业务功能]\n    K --> L\n    \n    L --> M[calendar.js 会议追踪]\n    L --> N[goal-retro.js 目标回顾]\n    L --> O[life-events.js 人生事件]\n    L --> P[digest.js 周报摘要]\n```\n\n## 数据模型\n\n### Contact 统一数据结构\n\n合并后的联系人记录包含以下核心字段：\n\n```javascript\n{\n  id: string,                    // 唯一标识符\n  name: string,                  // 规范化的姓名\n  phones: string[],              // 电话号码数组\n  emails: string[],              // 邮箱数组\n  sources: {                     // 各来源的原始数据\n    [sourceName]: {\n      name?: string,\n      phones?: string[],\n      emails?: string[],\n      company?: string,\n      position?: string,\n      // ... 其他来源特定字段\n    }\n  },\n  relationshipScore: number,      // 关系评分 0-100\n  daysSinceContact: number,       // 最后联系天数\n  activeChannels: string[],      // 活跃联系方式\n  interactionCount: number       // 交互次数\n}\n```\n\n资料来源：[crm/schema.js]()\n\n### Interaction 交互记录结构\n\n```javascript\n{\n  id: string,\n  contactId: string,\n  source: string,\n  timestamp: string,\n  type: 'message' | 'meeting' | 'call' | 'email',\n  subject?: string,\n  body?: string,\n  participants?: string[]\n}\n```\n\n## 匹配算法详解\n\n### 匹配置信度等级\n\n系统采用三级置信度体系判断两个联系人记录是否指向同一人：\n\n| 置信度 | 说明 | 处理方式 | 资料来源 |\n|--------|------|---------|---------|\n| **confirmed** | 多个高置信度信号完全吻合 | 自动合并，无需人工确认 | [crm/MATCHING.md]() |\n| **likely** | 存在多个支持信号，证据充分 | 自动合并，打印统计信息 | [crm/MATCHING.md]() |\n| **possible** | 存在一些匹配信号但不够确定 | 跳过合并，列入待审查列表 | [crm/MATCHING.md]() |\n\n### 匹配信号类型\n\n匹配算法考察以下信号维度：\n\n**强信号（权重高）：**\n- 邮箱地址完全匹配\n- 电话号码完全匹配\n- 多个联系方式组合匹配\n\n**中强信号（权重中）：**\n- 姓名相似度（编辑距离）\n- 公司名称匹配\n- LinkedIn 个人资料 URL 匹配\n\n**辅助信号（权重低）：**\n- 地理位置一致性\n- 职业/职位相似度\n- 共同交互事件\n\n### 匹配输出示例\n\n```json\n[\n  {\n    \"confidence\": \"confirmed\",\n    \"ids\": [\"c_0001\", \"c_0012\"],\n    \"reason\": \"邮箱地址完全一致\",\n    \"sources_linked\": [\"email\", \"linkedin\"]\n  },\n  {\n    \"confidence\": \"likely\",\n    \"ids\": [\"c_0003\", \"c_0088\"],\n    \"reason\": \"姓名完全匹配，公司一致，LinkedIn 位置匹配\",\n    \"sources_linked\": [\"whatsapp\", \"linkedin\"]\n  },\n  {\n    \"confidence\": \"possible\",\n    \"ids\": [\"c_0105\", \"c_2341\"],\n    \"reason\": \"名字匹配但该名字非常常见；缺少其他佐证信号\",\n    \"sources_linked\": [\"whatsapp\", \"linkedin\"]\n  }\n]\n```\n\n资料来源：[crm/MATCHING.md]()\n\n## 合并流程\n\n### 标准合并流程\n\n```mermaid\ngraph LR\n    A[运行各数据源导入器] --> B[npm run email<br/>npm run telegram<br/>npm run linkedin]\n    \n    B --> C[生成各源原始数据]\n    C --> D[运行 merge.js]\n    \n    D --> E{存在 match_overrides?}\n    E -->|是| F[加载人工干预配置]\n    E -->|否| G[跳过覆盖加载]\n    \n    F --> H[按 confirmed/likely<br/>强制合并指定记录]\n    G --> I[执行匹配算法]\n    \n    H --> J[生成统一联系人列表]\n    I --> J\n    \n    J --> K[写入 unified/contacts.json]\n    J --> L[写入 unified/interactions.json]\n    \n    K --> M[生成匹配统计报告]\n    L --> M\n```\n\n### 关键配置：match_overrides.json\n\n当自动匹配算法无法准确判断，或用户希望手动指定某些记录的合并关系时，可通过 `match_overrides.json` 进行干预：\n\n```json\n{\n  \"confirmed\": [\n    { \"ids\": [\"c_0001\", \"c_0012\"], \"reason\": \"用户确认为同一人\" }\n  ],\n  \"likely\": [\n    { \"ids\": [\"c_0003\", \"c_0088\"], \"reason\": \"邮箱前缀相同且公司一致\" }\n  ],\n  \"possible\": [\n    { \"ids\": [\"c_0105\", \"c_2341\"], \"reason\": \"待进一步核实\" }\n  ]\n}\n```\n\n**覆盖规则处理逻辑：**\n\n| 覆盖类型 | 算法行为 |\n|---------|---------|\n| confirmed | 无论算法结果如何，强制将两条记录合并为同一联系人 |\n| likely | 将两条记录合并，但在统计报告中标注为\"人工确认\" |\n| possible | 跳过自动合并，标记为需人工审查（通过 `npm run review`） |\n\n资料来源：[crm/MATCHING.md]()\n\n## 合并执行命令\n\n### 基本合并命令\n\n```bash\n# 标准合并流程\nnode crm/merge.js\n\n# 带详细输出\nnpm run merge\n\n# 仅检查匹配状态（不写入）\nnpm run match:dry-run\n```\n\n### 完整导入与合并流程\n\n```bash\n# 1. 导入各数据源\nnpm run email          # 导入 Email 数据\nnpm run telegram       # 导入 Telegram 数据\nnpm run linkedin       # 导入 LinkedIn 数据\n\n# 2. 执行合并\nnode crm/merge.js\n\n# 3. 查看统计\nnpm run stats\n```\n\n### 审查待定匹配\n\n对于置信度为 \"possible\" 的匹配记录，系统提供交互式审查界面：\n\n```bash\nnpm run review\n```\n\n该命令会列出所有待审查的匹配对，用户可选择确认或拒绝每一条匹配。\n\n资料来源：[crm/MATCHING.md]()\n\n## 匹配状态管理\n\n### 进度追踪\n\n合并过程中，系统会通过 `sources/_shared/progress.js` 模块追踪处理进度：\n\n```javascript\nP.startProgress(DATA_DIR, 'merge', { step: 'init', message: '开始合并…' });\nP.updateProgress(DATA_DIR, 'merge', { step: 'matching', message: '执行匹配…', current: 5, total: 10 });\nP.updateProgress(DATA_DIR, 'merge', { step: 'merging', message: '合并记录…' });\n```\n\n进度文件存储在 `data/.progress/merge.json`，包含以下字段：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| step | string | 当前处理阶段 |\n| message | string | 状态消息 |\n| current | number | 当前进度 |\n| total | number | 总任务数 |\n| startedAt | string | ISO 时间戳 |\n| updatedAt | string | ISO 时间戳 |\n| errors | array | 错误列表 |\n\n### 错误处理\n\n系统内置敏感信息过滤机制，防止在错误日志中泄露凭据或个人信息：\n\n```javascript\nfunction redactErrorText(value) {\n    return String(value)\n        .replace(/^\\s*at\\s+[^\\n]+/gm, '[redacted-stack]')\n        .replace(/([\"'`])[^\"'`\\n]*[\\\\/][^\"'`\\n]*\\1/g, '$1[redacted-path]$1')\n        .replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}/gi, '[redacted-email]')\n        .replace(/\\bauthorization\\s*[:=]\\s*Bearer\\s+[^\\s,;]+/gi, '[redacted-credential]');\n}\n```\n\n资料来源：[sources/_shared/progress.js]()\n\n## 数据新鲜度与置信度\n\n### 联系人数据置信度评估\n\n系统会根据数据来源和最后同步时间计算每条联系人的数据置信度：\n\n| 置信度等级 | 条件 | 说明 |\n|-----------|------|------|\n| high | 多个活跃来源 + 最近同步 | 数据完整可靠 |\n| medium | 单个活跃来源 + 最近同步 | 基本可靠 |\n| low | 无交互记录或数据过旧 | 需手动核实 |\n\n```javascript\nfunction getContactDataConfidence(contact, syncState, now = Date.now()) {\n    const activeSources = Object.keys(contact.sources || {}).filter(s => contact.sources[s]);\n    if (activeSources.length === 0) return { level: 'low', reason: '无来源数据' };\n    // ... 更多评估逻辑\n}\n```\n\n资料来源：[crm/staleness.js]()\n\n### 陈旧数据警告\n\n系统会自动检测数据新鲜度并生成警告：\n\n| 同步状态 | 警告级别 | 用户提示 |\n|---------|---------|---------|\n| 同步中 | - | - |\n| 同步成功（< 24h） | - | \"数据最新\" |\n| 同步成功（1-3天） | warning | \"数据可能略旧\" |\n| 同步成功（> 3天） | error | \"数据可能过时\" |\n| 同步错误 | error | \"同步失败，请检查配置\" |\n\n## 扩展开发指南\n\n### 添加新的数据源导入器\n\n参考 `sources/telegram/import.js` 的文件结构：\n\n1. 创建 `sources/<new-source>/import.js`\n2. 实现数据抓取和标准化逻辑\n3. 写入 `data/<new-source>/contacts.json`\n4. 更新 `crm/merge.js` 添加新数据源加载\n5. 更新 `crm/match.js` 添加新源的匹配规则\n\n### 自定义匹配规则\n\n在 `crm/match.js` 中添加新的匹配信号检测：\n\n```javascript\n// 示例：添加公司域名匹配\nfunction matchByEmailDomain(contactA, contactB) {\n    const domainsA = contactA.emails.map(e => e.split('@')[1]);\n    const domainsB = contactB.emails.map(e => e.split('@')[1]);\n    return domainsA.some(d => domainsB.includes(d));\n}\n```\n\n### 添加测试用例\n\n在 `tests/` 目录创建匹配测试：\n\n```bash\n# 运行匹配相关测试\nnpm test -- --grep \"match\"\n\n# 添加新测试文件\n# tests/match.test.js\n```\n\n## 常见问题排查\n\n### 合并后联系人数量异常减少\n\n**可能原因：**\n- 匹配规则过于激进，将不应合并的记录错误合并\n- match_overrides.json 中存在误配置\n\n**解决方案：**\n1. 检查 `data/unified/` 中的合并结果\n2. 审阅 `match_overrides.json` 配置\n3. 使用 `npm run review` 重新审查匹配决策\n\n### 预期匹配未被识别\n\n**可能原因：**\n- 数据源格式不规范（如姓名包含特殊字符）\n- 缺少共同信号（如双方从未通过邮件交互）\n\n**解决方案：**\n1. 规范化导入数据\n2. 在 match_overrides.json 中添加 confirmed 覆盖\n3. 手动审查 possible 匹配队列\n\n### 数据新鲜度显示错误\n\n**可能原因：**\n- 同步状态文件格式不一致\n- 未正确写入 lastSyncAt 字段\n\n**解决方案：**\n1. 检查 `data/unified/sync-state.json`\n2. 确保各导入器正确更新同步状态\n3. 查看 `crm/agent-source-health.js` 诊断输出\n\n## 相关文档\n\n- [匹配规范文档](./MATCHING.md) - 匹配算法的完整技术规范\n- [架构概述](./ARCHITECTURE.md) - 项目整体架构说明\n- [数据源导入器](../sources/) - 各数据源导入实现详情\n- [同步系统](./sync.js) - 自动化数据同步机制\n\n---\n\n<a id='page-data-storage'></a>\n\n## 数据存储结构\n\n### 相关页面\n\n相关主题：[联系人合并与去重](#page-contact-merging), [架构总览](#page-architecture-overview)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [crm/export.js](https://github.com/sree-sanak/minty/blob/main/crm/export.js)\n- [crm/sync.js](https://github.com/sree-sanak/minty/blob/main/crm/sync.js)\n- [crm/server.js](https://github.com/sree-sanak/minty/blob/main/crm/server.js)\n- [crm/merge.js](https://github.com/sree-sanak/minty/blob/main/crm/merge.js)\n- [crm/schema.js](https://github.com/sree-sanak/minty/blob/main/crm/schema.js)\n- [crm/staleness.js](https://github.com/sree-sanak/minty/blob/main/crm/staleness.js)\n- [sources/_shared/progress.js](https://github.com/sree-sanak/minty/blob/main/sources/_shared/progress.js)\n- [sources/whatsapp/export.js](https://github.com/sree-sanak/minty/blob/main/sources/whatsapp/export.js)\n</details>\n\n# 数据存储结构\n\n## 概述\n\nMinty 项目采用**本地优先（Local-first）**的架构理念，所有数据均存储在用户本地的文件系统中，不依赖任何云端数据库服务。项目的核心设计原则是\"**文件系统即数据库**\"，数据通过导入器从各个来源收集，经过去重和合并后，形成统一的视图供上层应用使用。资料来源：[ARCHITECTURE.md]()\n\n## 核心设计原则\n\n| 原则 | 说明 |\n|------|------|\n| 本地优先 | 数据永不离开用户机器，核心功能不涉及任何网络传输 |\n| 文件系统即数据库 | 使用 JSON 文件作为持久化存储，无需安装数据库 |\n| 增量同步 | 部分导入器支持增量更新，避免重复导出 |\n| 原子写入 | 写入操作使用临时文件+重命名确保数据完整性 |\n| 可导出加密备份 | 支持生成加密的便携式备份包 |\n\n资料来源：[ARCHITECTURE.md]()\n\n---\n\n## 数据目录布局\n\n```\ndata/                              # 运行时数据目录（gitignored）\n├── whatsapp/                     # WhatsApp 导出数据\n│   ├── chats.json               # 聊天记录\n│   ├── contacts.json            # 联系人列表\n│   ├── metadata.json            # 元数据（包含 last_export_unix）\n│   ├── profile_pics/            # 联系人头像\n│   └── .progress.json          # 同步进度记录\n├── linkedin/                     # LinkedIn 数据\n│   ├── export/                  # 用户上传的 ZIP 导出包\n│   ├── parsed.csv               # 解析后的 CSV 数据\n│   └── .progress.json\n├── telegram/                     # Telegram 导出数据\n│   ├── result.json\n│   └── .progress.json\n├── email/                        # 邮件数据（按账户分目录）\n│   └── <account>/\n├── sms/                          # 短信数据（按平台分目录）\n│   └── <platform>/\n├── google-contacts/             # Google 通讯录\n│   └── .progress.json\n├── apollo/                       # Apollo 数据充实（可选）\n│   └── .progress.json\n└── unified/                      # 合并后的统一数据（核心输出）\n    ├── contacts.json            # 统一联系人记录\n    ├── interactions.json        # 交互时间线\n    ├── insights.json            # AI 洞察结果\n    ├── goals.json               # 目标数据\n    ├── group-memberships.json    # 群组成员关系\n    ├── query-index.json         # 搜索索引\n    ├── digest.json              # 摘要数据\n    ├── match_overrides.json     # 匹配覆盖规则\n    └── .progress.json\n```\n\n可通过环境变量 `CRM_DATA_DIR` 覆盖根目录，个别导入器支持各自的导出目录环境变量（如 `*_EXPORT_DIR`）。\n\n资料来源：[ARCHITECTURE.md]()\n\n---\n\n## 数据模型\n\n### Contact（联系人）记录\n\n联系人模型定义在 `crm/schema.js` 中，包含以下核心字段：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | string | 全局唯一标识符 |\n| `source` | string | 数据来源（whatsapp/linkedin/telegram/email 等） |\n| `name` | string | 规范化后的姓名 |\n| `phones` | string[] | 标准化后的电话号码列表 |\n| `emails` | string[] | 标准化后的邮箱列表 |\n| `company` | string | 公司名称 |\n| `title` | string | 职位 |\n| `tags` | string[] | 标签（如 investor、founder） |\n| `lastInteraction` | ISO date | 最近一次交互时间 |\n| `stale` | boolean | 数据是否过期标记 |\n\n资料来源：[ARCHITECTURE.md]()\n\n### Interaction（交互）记录\n\n交互记录描述与联系人的互动历史：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | string | 交互唯一标识 |\n| `contactId` | string | 关联的联系人 ID |\n| `type` | string | 交互类型（message/call/meeting/email） |\n| `timestamp` | ISO date | 交互时间 |\n| `source` | string | 数据来源 |\n| `summary` | string | 交互摘要 |\n| `metadata` | object | 附加元数据 |\n\n资料来源：[crm/schema.js]()\n\n---\n\n## 数据流架构\n\n```mermaid\ngraph TD\n    A[用户运行导入器] --> B[源数据导入器<br/>sources/&lt;src&gt;/import.js]\n    B --> C[写入数据源目录<br/>data/&lt;source&gt;/]\n    \n    D[定时或手动触发] --> E[合并进程<br/>crm/merge.js]\n    C --> E\n    \n    E --> F[数据规范化<br/>phones/emails/names]\n    F --> G[跨源去重<br/>crm/match.js]\n    G --> H[构建统一时间线]\n    H --> I[写入统一存储<br/>data/unified/]\n    \n    I --> J[HTTP 服务器<br/>crm/server.js]\n    J --> K[Web UI / API]\n    \n    I --> L[AI 洞察生成<br/>crm/ai.js]\n    L --> I\n    \n    M[同步监控<br/>crm/sync.js] --> D\n    M --> B\n```\n\n### 数据生命周期\n\n1. **导入阶段**：用户运行导入器，将数据从各平台导出并写入 `data/<source>/`\n2. **合并阶段**：`crm/merge.js` 加载各源数据，执行规范化、去重、合并\n3. **存储阶段**：结果写入 `data/unified/contacts.json` 和 `interactions.json`\n4. **服务阶段**：`crm/server.js` 读取统一存储，通过 HTTP API 提供数据\n5. **洞察阶段**：AI 模块基于统一数据生成洞察和摘要\n\n资料来源：[ARCHITECTURE.md]()\n\n---\n\n## 同步与进度追踪\n\n### 进度记录机制\n\n每个导入器使用 `sources/_shared/progress.js` 统一记录同步进度：\n\n| 字段 | 说明 |\n|------|------|\n| `source` | 数据源标识 |\n| `step` | 当前步骤（init/contacts/messages/merging/done/error） |\n| `message` | 状态描述 |\n| `current` / `total` | 进度数值 |\n| `itemsProcessed` | 已处理条目数 |\n| `errors` | 错误列表 |\n| `startedAt` / `updatedAt` | 时间戳 |\n| `error` | 错误详情对象 |\n\n进度文件位置：`data/<source>/.progress.json`\n\n### 原子写入机制\n\n```javascript\nfunction safeWrite(filePath, payload) {\n    const tmp = filePath + '.tmp-' + process.pid + '-' + Date.now();\n    fs.writeFileSync(tmp, JSON.stringify(payload));\n    fs.renameSync(tmp, filePath);\n}\n```\n\n写入操作先写入临时文件，再原子重命名，确保数据完整性。写入失败不会导致导入器崩溃。\n\n资料来源：[sources/_shared/progress.js]()\n\n### 数据过期检测\n\n`crm/staleness.js` 实现了联系人数据过期检测机制：\n\n| 来源类型 | 过期阈值 |\n|----------|----------|\n| WhatsApp | 14 天 |\n| Email | 30 天 |\n| LinkedIn | 90 天 |\n| Google Contacts | 60 天 |\n\n检测结果影响 UI 中的警告提示和数据置信度评分。\n\n资料来源：[crm/staleness.js]()\n\n---\n\n## 导出与备份\n\n### 导出包格式\n\n`crm/export.js` 支持生成便携式加密备份：\n\n| 字段 | 说明 |\n|------|------|\n| `version` | 导出格式版本（当前为 1） |\n| `exportedAt` | 导出时间戳 |\n| `contacts` | 联系人数据 |\n| `interactions` | 交互数据 |\n| `insights` | AI 洞察（可选） |\n| `goals` | 目标数据（可选） |\n| `groupMemberships` | 群组关系（可选） |\n| `syncState` | 同步状态 |\n| `insightsAt` | 洞察生成时间 |\n| `stats` | 统计摘要 |\n\n### 加密方案\n\n| 参数 | 值 | 说明 |\n|------|-----|------|\n| `SALT_BYTES` | 16 | PBKDF2 盐值长度 |\n| `IV_BYTES` | 12 | AES-GCM 初始向量 |\n| `TAG_BYTES` | 16 | 认证标签长度 |\n| `KDF_ITERS` | 200000 | PBKDF2 迭代次数 |\n\n加密模式使用 **AES-256-GCM**，密钥派生使用 **PBKDF2-SHA256**。\n\n资料来源：[crm/export.js]()\n\n### 导出方式\n\n| 命令 | 说明 |\n|------|------|\n| `npm run export` | CLI 导出 |\n| `GET /api/export` | HTTP API 导出 |\n| `POST /api/export` | 带请求体的导出 |\n\n---\n\n## API 接口\n\n| 端点 | 方法 | 说明 |\n|------|------|------|\n| `/api/sources/:key/progress` | GET | 获取单个数据源进度 |\n| `/api/sync/progress` | GET | 获取所有数据源进度 |\n| `/api/export` | GET/POST | 导出/加密导出 |\n\n资料来源：[crm/server.js]()\n\n---\n\n## 环境变量配置\n\n| 变量 | 说明 | 默认值 |\n|------|------|--------|\n| `CRM_DATA_DIR` | 数据根目录 | `./data` |\n| `WHATSAPP_EXPORT_DIR` | WhatsApp 导出目录 | `data/whatsapp/export` |\n| `LINKEDIN_EXPORT_DIR` | LinkedIn 导出目录 | `data/linkedin/export` |\n| `AI_BACKEND` | AI 后端选择 | `claude` / `ollama` |\n\n资料来源：[ARCHITECTURE.md]()\n\n---\n\n## 安全特性\n\n1. **本地优先**：核心功能不包含任何云端 LLM 集成，所有 AI 推理均为本地或用户主动选择\n2. **敏感信息脱敏**：进度记录模块包含 `redactErrorText()` 函数，自动脱敏邮箱、凭证、文件路径等敏感信息\n3. **加密导出**：可选 AES-256-GCM 加密保护备份数据\n4. **增量更新**：WhatsApp 等支持增量导出，减少数据暴露窗口\n\n资料来源：[crm/export.js](), [sources/_shared/progress.js](), [sources/whatsapp/export.js]()\n\n---\n\n<a id='page-mcp-integration'></a>\n\n## MCP 代理集成\n\n### 相关页面\n\n相关主题：[网络查询系统](#page-network-query), [快速开始](#page-quick-start)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [scripts/minty-mcp-server.js](https://github.com/sree-sanak/minty/blob/main/scripts/minty-mcp-server.js)\n- [hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md)\n- [README.md](https://github.com/sree-sanak/minty/blob/main/README.md)\n- [ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n- [docs/OPENCLAW_HERMES.md](https://github.com/sree-sanak/minty/blob/main/docs/OPENCLAW_HERMES.md)\n</details>\n\n# MCP 代理集成\n\n## 概述\n\nMCP（Model Context Protocol）代理集成是 Minty 项目为 AI 代理提供的标准化接口层。通过 MCP 协议，外部代理系统（如 OpenClaw、Claude Code、Ollama）可以直接调用 Minty 的联系人检索和关系管理能力，无需直接访问底层数据文件。 资料来源：[README.md]()\n\nMinty 采用本地优先架构，所有联系人数据存储在本地 `data/` 目录中，MCP 服务以独立的 stdio 进程运行，确保数据不离开用户的机器。 资料来源：[ARCHITECTURE.md]()\n\n## 核心架构\n\n### 系统组件\n\n```mermaid\ngraph TD\n    subgraph 外部代理 [\"外部代理系统\"]\n        OC[OpenClaw]\n        HM[Hermes]\n        CC[Claude Code CLI]\n    end\n    \n    subgraph MCP层 [\"MCP 协议层\"]\n        SERVER[scripts/minty-mcp-server.js]\n    end\n    \n    subgraph 核心引擎 [\"Minty 核心引擎\"]\n        RETRIEVAL[crm/agent-retrieval.js]\n        MATCH[crm/match.js]\n        SEARCH[crm/search.js]\n    end\n    \n    subgraph 数据存储 [\"本地数据存储\"]\n        CONTACTS[data/unified/contacts.json]\n        INTERACTIONS[data/unified/interactions.json]\n    end\n    \n    OC --> SERVER\n    HM --> SERVER\n    CC --> SERVER\n    SERVER --> RETRIEVAL\n    RETRIEVAL --> MATCH\n    RETRIEVAL --> SEARCH\n    MATCH --> CONTACTS\n    SEARCH --> INTERACTIONS\n```\n\n### MCP 服务入口\n\n`scripts/minty-mcp-server.js` 是 MCP 服务的核心入口文件，负责注册所有可用的工具并处理代理请求。服务以 stdio 模式运行，适合与 AI 代理进行本地集成。 资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n## 可用工具\n\nMCP 服务暴露四个核心工具，供外部代理调用：\n\n| 工具名称 | 功能描述 | 主要参数 |\n|---------|---------|---------|\n| `search_network` | 自然语言网络搜索 | `query`, `limit`, `source`/`sources` |\n| `person_context` | 查询特定联系人详情 | `person`, `limit` |\n| `workflow_brief` | 生成目标导向简报 | `goal`, `limit` |\n| `source_health` | 检查数据源健康状态 | `source`/`sources`/`query` |\n\n### search_network\n\n用于自由形式的网络查询，返回排名靠前的联系人及其关联证据。\n\n```json\n{\n  \"query\": \"investors in London who know about AI\",\n  \"limit\": 5\n}\n```\n\n支持按来源过滤：\n\n```json\n{\n  \"query\": \"people I discussed Telegram bots with\",\n  \"source\": \"telegram\",\n  \"limit\": 5\n}\n```\n\n### person_context\n\n查询特定联系人的详细信息，包括关系上下文、亲密度评分和证据。\n\n```json\n{\n  \"person\": \"Alice Müller\",\n  \"limit\": 3\n}\n```\n\n### workflow_brief\n\n生成以目标为导向的简报，帮助代理找到能够帮助完成特定任务的人。\n\n```json\n{\n  \"goal\": \"Find EU crypto insurance distribution partners\",\n  \"limit\": 5\n}\n```\n\n### source_health\n\n在执行来源特定查询前进行预检查，确保数据源处于可用状态。\n\n```json\n{ \"source\": \"telegram\" }\n{ \"sources\": [\"telegram\", \"slack\"] }\n{ \"query\": \"who from Telegram knows DeFi?\" }\n```\n\n## 配置与部署\n\n### 环境变量\n\n| 变量名 | 说明 | 默认值 |\n|-------|------|-------|\n| `CRM_DATA_DIR` | 数据目录路径 | `./data` |\n| `MINTY_USER_UUID` | 用户唯一标识 | 自动生成 |\n| `AI_BACKEND` | AI 后端类型 | `claude` |\n\n### AI 后端选择\n\nMinty 支持两种本地 AI 后端：\n\n1. **Claude Code CLI（默认）**：调用 `claude --print` 进行推理，免费但会将提示发送至 Anthropic 服务器\n2. **Ollama**：通过设置 `AI_BACKEND=ollama` 启用，支持本地模型如 `qwen2.5:7b`，完全离线运行\n\n资料来源：[README.md]()\n\n### 启动 MCP 服务\n\n```bash\n# 基础启动\nnpm run mcp\n\n# 指定数据目录\nCRM_DATA_DIR=./data-demo npm run mcp\n\n# 服务模式（守护进程）\nnpm run service\nMINTY_USER_UUID=abc npm run service\n```\n\n## 与外部代理集成\n\n### OpenClaw + Hermes 集成\n\n完整的集成配置文档位于 `docs/OPENCLAW_HERMES.md`。核心步骤包括：\n\n1. 注册 `scripts/minty-mcp-server.js` 为 stdio MCP 服务器\n2. 配置代理系统连接到本地 MCP 端点\n3. 设置数据目录环境变量\n\n```json\n{\n  \"mcpServers\": {\n    \"minty\": {\n      \"command\": \"node\",\n      \"args\": [\"/root/.hermes/workspace/minty/scripts/minty-mcp-server.js\"],\n      \"timeout\": 60,\n      \"connect_timeout\": 20\n    }\n  }\n}\n```\n\n资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n### Claude Code 代理支持\n\nClaude Code 代理可以直接通过 MCP 工具访问联系人网络：\n\n```bash\nCRM_DATA_DIR=./data-demo npm run agent -- \"who can help with crypto insurance\"\n```\n\n### 演示模式\n\n使用演示数据快速验证集成是否正常工作：\n\n```bash\nnpm run seed:demo\nnpm run mcp\nnpm run agent -- \"investors in London\"\n```\n\n资料来源：[README.md]()\n\n## 就绪状态检查\n\nMinty 提供三个就绪级别用于评估集成状态：\n\n| 级别 | 描述 | 验证命令 |\n|-----|------|---------|\n| Demo-ready | 演示数据可用 | `npm run seed:demo && npm run mcp` |\n| Dogfood-ready | 真实本地数据可用 | `npm run memory:refresh` |\n| Hermes-native | 完整集成就绪 | `npm run hermes:doctor` |\n\n执行健康检查：\n\n```bash\nnpm run hermes:doctor\n```\n\n资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n## 数据安全与隐私\n\nMCP 服务运行在本地，所有联系人数据存储在用户本地磁盘的 `data/` 目录中。服务不进行遥测、不收集分析数据、不与外部服务器通信。 资料来源：[README.md]()\n\n### 敏感信息处理\n\n在处理联系人数据和生成建议时，MCP 服务会自动过滤以下敏感信息：\n\n- 邮箱地址（显示为 `[redacted-email]`）\n- Bearer 令牌和认证凭证\n- 文件路径信息\n- 堆栈跟踪信息\n\n## 错误处理与调试\n\n### 常见问题排查\n\n| 问题 | 可能原因 | 解决方案 |\n|-----|---------|---------|\n| MCP 连接超时 | 服务未启动 | 执行 `npm run mcp` |\n| 数据源返回空结果 | 数据源过期或未导入 | 执行 `npm run memory:refresh` |\n| 认证失败 | 环境变量未设置 | 检查 `AI_BACKEND` 配置 |\n\n### 源健康预检\n\n在执行来源特定查询前，始终建议调用 `source_health` 检查数据源状态：\n\n- **Fresh**：数据最近有更新\n- **Evidence-bearing**：有足够的交互证据\n- **Stale**：数据过期，需要刷新\n- **Empty**：无数据导入\n\n如果数据源状态为 stale 或 empty，应返回诚实的低置信度回答，而非虚构信息。 资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n## 扩展开发\n\n### 添加新工具\n\n在 `scripts/minty-mcp-server.js` 中注册新工具需要：\n\n1. 在工具注册表中添加条目\n2. 实现工具处理器函数\n3. 更新 `hermes/minty-network-memory/SKILL.md` 中的文档\n4. 添加相应的集成测试\n\n### 工具维护契约\n\n`scripts/minty-mcp-server.js` 是暴露 MCP 工具的事实来源（source of truth）。任何添加、移除或重命名工具的 PR 必须同步更新相关文档和技能说明。 资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n## 相关文档\n\n- [Minty 架构概览](./ARCHITECTURE.md)\n- [OpenClaw + Hermes 集成指南](./docs/OPENCLAW_HERMES.md)\n- [代理检索引擎](./crm/agent-retrieval.js)\n- [联系人匹配算法](./crm/match.js)\n\n---\n\n<a id='page-network-query'></a>\n\n## 网络查询系统\n\n### 相关页面\n\n相关主题：[MCP 代理集成](#page-mcp-integration)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [crm/query.js](https://github.com/sree-sanak/minty/blob/main/crm/query.js)\n- [crm/network-query.js](https://github.com/sree-sanak/minty/blob/main/crm/network-query.js)\n- [crm/query-reasons.js](https://github.com/sree-sanak/minty/blob/main/crm/query-reasons.js)\n- [crm/search.js](https://github.com/sree-sanak/minty/blob/main/crm/search.js)\n- [crm/hybrid-index.js](https://github.com/sree-sanak/minty/blob/main/crm/hybrid-index.js)\n</details>\n\n# 网络查询系统\n\n## 概述\n\n网络查询系统（Network Query System）是 Minty CRM 的核心检索引擎，负责通过自然语言或结构化查询从用户的人际网络中快速定位相关联系人及其交互记录。该系统整合了来自多个数据源（WhatsApp、LinkedIn、Telegram、Email、Google Contacts 等）的统一数据，提供语义化的网络搜索能力，使用户能够以自然对话的方式回答\"我和谁讨论过 X 话题\"、\"在某个活动中见过哪些人\"等查询需求。\n\n网络查询系统的设计目标是将散落在不同通讯平台中的碎片化人际关系重新编织成可检索、可分析的网络图谱，支持从简单的人名搜索到复杂的多条件组合查询。资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n## 架构概览\n\n网络查询系统采用分层架构，从底层到顶层依次为：数据索引层、查询解析层、匹配引擎层和 API 接口层。各层职责明确，通过标准化的数据结构进行通信。\n\n```mermaid\ngraph TD\n    A[用户查询] --> B[查询解析层<br/>query-reasons.js]\n    B --> C[自然语言理解<br/>分词/意图识别]\n    C --> D[混合索引层<br/>hybrid-index.js]\n    D --> E[匹配引擎层<br/>search.js]\n    E --> F[结果排序与过滤]\n    F --> G[API 接口层<br/>network-query.js]\n    G --> H[返回结果]\n    \n    I[统一数据存储<br/>data/unified/] --> D\n    J[交互索引<br/>interactions.json] --> E\n```\n\n### 核心组件职责\n\n| 组件 | 文件路径 | 主要职责 |\n|------|----------|----------|\n| 查询解析 | `crm/query-reasons.js` | 分析查询语句，提取关键词、过滤条件和排序需求 |\n| 混合索引 | `crm/hybrid-index.js` | 构建和维护联系人与交互记录的倒排索引 |\n| 搜索匹配 | `crm/search.js` | 执行关键词匹配、模糊搜索和相关性评分 |\n| 网络查询 | `crm/network-query.js` | 提供自然语言查询接口，处理复杂检索场景 |\n| CLI 查询 | `crm/query.js` | 命令行统计和搜索功能 |\n\n资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n## 查询解析机制\n\n### query-reasons.js — 查询意图分析\n\n`query-reasons.js` 模块负责将用户的自然语言查询转换为结构化的检索条件。该模块通过预定义的正则表达式模式和启发式规则识别查询中的关键成分，包括：\n\n- **人员实体**：查询中提到的人名或公司名称\n- **时间范围**：相对时间（\"最近一周\"、\"上个月\"）或绝对时间\n- **来源过滤**：指定的数据源（telegram、linkedin、email 等）\n- **意图类型**：搜索类型（统计信息、联系人列表、交互记录等）\n\n查询解析结果会生成一个结构化的 `query reasons` 对象，包含提取的关键词列表、过滤条件和权重配置，供下游匹配引擎使用。资料来源：[hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md)\n\n### 查询类型分类\n\n| 查询类型 | 示例 | 处理逻辑 |\n|----------|------|----------|\n| 自然语言搜索 | \"我在伦敦见过的投资人\" | 解析实体+来源+时间，组合检索 |\n| 来源过滤查询 | \"来自 Telegram 的人\" | 仅在指定数据源中搜索 |\n| 关键词搜索 | \"DeFi\"、\"区块链\" | 分词后匹配交互记录 |\n| 人员上下文 | \"Alice Müller 的相关信息\" | 精确匹配 + 关联扩展 |\n\n## 搜索匹配引擎\n\n### search.js — 核心匹配逻辑\n\n`search.js` 是网络查询系统的匹配引擎核心，负责在已索引的数据中执行高效的相似度匹配和相关性排序。\n\n#### 匹配函数实现\n\n匹配引擎支持三种主要的匹配模式：\n\n```javascript\nfunction matches(text, clause) {\n    if (clause.kind === 'phrase') return text.toLowerCase().includes(clause.value);\n    if (clause.kind === 'prefix') return findPrefix(text, clause.value).length > 0;\n    // token: case-insensitive substring match of the full token\n    return text.toLowerCase().includes(clause.value);\n}\n```\n\n- **phrase（短语匹配）**：完整匹配查询短语，区分大小写但忽略大小写差异\n- **prefix（前缀匹配）**：匹配以查询词开头的文本片段\n- **token（分词匹配）**：对查询词进行分词后逐个匹配\n\n资料来源：[crm/search.js](https://github.com/sree-sanak/minty/blob/main/crm/search.js)\n\n#### 偏移量计算\n\n`matchOffsets` 函数用于计算匹配文本在原始内容中的位置信息，支持高亮显示和上下文提取：\n\n```javascript\nfunction matchOffsets(text, clause) {\n    if (clause.kind === 'phrase' || clause.kind === 'token') return findAll(text, clause.value);\n    if (clause.kind === 'prefix') return findPrefix(text, clause.value);\n    return [];\n}\n```\n\n#### 结果排序策略\n\n搜索结果按综合评分排序，评分相同时按时间戳降序排列：\n\n```javascript\n.sort((a, b) => (b.score - a.score) ||\n    ((new Date(b.timestamp || 0).getTime()) - (new Date(a.timestamp || 0).getTime())));\n```\n\n评分计算综合考虑以下因素：\n- 关键词命中次数\n- 匹配模式优先级（精确匹配 > 前缀匹配 > 模糊匹配）\n- 时间衰减因子（新近交互优先）\n- 关系亲密度（relationshipScore）\n\n#### 主题词提取\n\n`dominantTokens` 函数从文本中提取最具代表性的关键词，用于构建主题索引和支持话题聚合查询：\n\n```javascript\nfunction dominantTokens(text, opts = {}) {\n    const freq = {};\n    const min = opts.min || 2;\n    const topN = opts.topN || 10;\n    const words = String(text || '').toLowerCase().match(ALPHA_NUM) || [];\n    for (const w of words) {\n        if (w.length < 4 || STOP_WORDS.has(w)) continue;\n        freq[w] = (freq[w] || 0) + 1;\n    }\n    return Object.entries(freq)\n        .filter(([, n]) => n >= min)\n        .sort((a, b) => b[1] - a[1])\n        .slice(0, topN)\n        .map(([word]) => word);\n}\n```\n\n该函数自动过滤停用词和长度小于 4 的词汇，并按词频排序返回 Top N 关键词。资料来源：[crm/search.js](https://github.com/sree-sanak/minty/blob/main/crm/search.js)\n\n## 混合索引系统\n\n### hybrid-index.js — 索引构建与管理\n\n`hybrid-index.js` 负责构建和维护联系人与交互记录的混合索引。索引采用倒排结构，支持高效的关键词查询和多维度过滤。\n\n#### 索引数据结构\n\n索引系统维护以下核心数据结构：\n\n1. **联系人索引**：按姓名、公司、职位、标签等字段建立倒排索引\n2. **交互索引**：按时间线组织交互记录，支持时间范围查询\n3. **来源索引**：按数据源分类，支持来源级别的过滤和健康度检测\n4. **主题索引**：基于 `dominantTokens` 提取的主题词构建话题网络\n\n#### 索引构建流程\n\n索引构建是离线过程，通常在数据合并（`merge.js`）完成后执行。构建流程包括：\n\n1. 加载统一数据存储中的 `contacts.json` 和 `interactions.json`\n2. 对每个联系人和交互记录进行分词处理\n3. 构建各字段的倒排索引\n4. 计算关联权重和预评分\n5. 持久化索引文件供运行时加载\n\n## 自然语言查询接口\n\n### network-query.js — 对话式查询 API\n\n`network-query.js` 模块提供 MCP（Model Context Protocol）接口，支持通过自然语言进行网络查询。该模块封装了底层的搜索能力，提供面向 AI Agent 的高级查询接口。\n\n#### 核心查询工具\n\n| 工具名称 | 功能描述 | 典型参数 |\n|----------|----------|----------|\n| `search_network` | 自然语言网络搜索 | `query`, `limit`, `source`/`sources` |\n| `person_context` | 人员上下文查询 | `person`, `limit` |\n| `workflow_brief` | 目标导向简报生成 | `goal`, `limit` |\n| `source_health` | 数据源健康度检查 | `source`/`sources`/`query` |\n\n资料来源：[hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md)\n\n#### search_network 查询示例\n\n```json\n{\n  \"query\": \"investors in London who know about AI\",\n  \"limit\": 5\n}\n```\n\n返回结果包含按相关性排序的联系人列表，每个结果包含：\n- **证据（evidence）**：匹配依据和上下文片段\n- **亲密度（warmth）**：关系评分\n- **置信度（confidence）**：数据可信度评估\n- **来源诊断（source diagnostics）**：结果来源分析\n- **建议操作（suggested actions）**：下一步安全建议\n\n#### person_context 查询示例\n\n```json\n{\n  \"person\": \"Alice Müller\",\n  \"limit\": 3\n}\n```\n\n返回指定人员的完整关系上下文，包括：\n- 关系历史摘要\n- 交互亲密度评分\n- 最近交互证据\n- 数据新鲜度诊断\n\n#### workflow_brief 目标简报\n\n针对特定目标生成人员推荐简报：\n\n```json\n{\n  \"goal\": \"Find EU crypto insurance distribution partners\",\n  \"limit\": 5\n}\n```\n\n返回结果包含目标相关度最高的联系人列表，每个联系人附带：\n- 相关性原因说明\n- 数据新鲜度状态\n- 安全的下一步行动建议\n\n### 数据源健康度检测\n\n`source_health` 工具在执行网络查询前自动检查各数据源的状态，确保查询结果的可靠性：\n\n```json\n{ \"source\": \"telegram\" }\n```\n\n健康度状态分类：\n- **demo-ready**：可用示例数据\n- **fresh**：数据源状态正常\n- **stale**：数据较旧，可能需要刷新\n- **empty**：数据源为空或未初始化\n- **unsafe**：数据不可靠，建议修复后再使用\n\n资料来源：[hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md)\n\n## 命令行查询接口\n\n### query.js — CLI 工具\n\n`query.js` 提供命令行界面的统计和搜索功能，通过以下命令调用：\n\n```bash\nnpm run stats   # 显示网络统计信息\nnpm run search  # 执行关键词搜索\n```\n\nCLI 查询工具适合快速获取网络概览和批量数据导出场景，支持以下功能：\n\n- 联系人总数和来源分布统计\n- 交互记录数量和时间分布\n- 关键词搜索并高亮显示结果\n- 导出查询结果为 CSV/JSON 格式\n\n资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n## 数据流与处理管道\n\n### 查询执行完整流程\n\n```mermaid\nsequenceDiagram\n    participant U as 用户\n    participant NQ as network-query.js\n    participant QR as query-reasons.js\n    participant HI as hybrid-index.js\n    participant SE as search.js\n    participant DS as 统一数据存储\n\n    U->>NQ: 自然语言查询\n    NQ->>QR: 解析查询意图\n    QR-->>NQ: 结构化查询条件\n    NQ->>HI: 加载/查询索引\n    HI->>DS: 获取最新数据\n    DS-->>HI: 数据快照\n    HI-->>NQ: 候选结果集\n    NQ->>SE: 执行匹配评分\n    SE-->>NQ: 排序后结果\n    NQ-->>U: 返回查询结果\n```\n\n### 与其他模块的交互\n\n网络查询系统与以下模块紧密协作：\n\n| 关联模块 | 交互方式 | 数据依赖 |\n|----------|----------|----------|\n| `merge.js` | 索引更新触发 | 接收合并后的统一数据 |\n| `staleness.js` | 健康度查询 | 使用新鲜度数据校准结果权重 |\n| `server.js` | HTTP API 封装 | 提供 `/api/search` 等端点 |\n| `calendar.js` | 日程数据融合 | 查询中加入日历事件上下文 |\n\n## 数据模型\n\n### 联系人数据结构\n\n网络查询系统处理的联系人记录包含以下关键字段：\n\n| 字段名 | 类型 | 说明 | 可检索性 |\n|--------|------|------|----------|\n| `id` | string | 唯一标识符 | 精确匹配 |\n| `name` | string | 姓名 | 分词匹配 |\n| `company` | string | 公司名称 | 前缀匹配 |\n| `position` | string | 职位 | 分词匹配 |\n| `sources` | object | 各数据源原始数据 | 来源过滤 |\n| `relationshipScore` | number | 关系评分 0-100 | 范围过滤 |\n| `daysSinceContact` | number | 最近联系天数 | 范围过滤 |\n| `activeChannels` | string[] | 活跃联系方式 | 包含匹配 |\n| `tags` | string[] | 自定义标签 | 精确匹配 |\n\n资料来源：[AGENTS.md](https://github.com/sree-sanak/minty/blob/main/AGENTS.md)\n\n### 交互记录数据结构\n\n| 字段名 | 类型 | 说明 |\n|--------|------|------|\n| `id` | string | 交互记录唯一标识 |\n| `contactId` | string | 关联联系人 ID |\n| `source` | string | 数据来源（whatsapp/telegram/email等） |\n| `timestamp` | ISO string | 交互时间 |\n| `type` | string | 交互类型（message/call/meeting） |\n| `body` | string | 交互内容正文 |\n| `subject` | string | 主题（邮件场景） |\n\n## 性能优化策略\n\n### 索引优化\n\n网络查询系统采用以下索引优化策略：\n\n1. **增量更新**：仅对变更的联系人/交互记录重新索引\n2. **压缩存储**：使用倒排列表压缩减少磁盘占用\n3. **缓存预热**：服务器启动时预加载高频查询索引\n4. **分片加载**：按数据源分片懒加载，平衡内存占用\n\n### 查询优化\n\n1. **早停规则**：达到目标结果数后提前终止匹配\n2. **缓存复用**：相同查询条件的结果缓存复用\n3. **结果分页**：避免一次性加载大量结果\n4. **评分截断**：对低分结果进行截断过滤\n\n## 使用场景示例\n\n### 场景一：查找特定领域联系人\n\n**查询**：查找讨论过 DeFi 话题的 Telegram 联系人\n\n```json\n{\n  \"query\": \"DeFi\",\n  \"sources\": [\"telegram\"],\n  \"limit\": 10\n}\n```\n\n系统会：\n1. 解析关键词 \"DeFi\"\n2. 在 Telegram 数据源中检索\n3. 匹配交互记录中的 DeFi 相关内容\n4. 按相关性评分和时间排序返回\n\n### 场景二：人员关系探索\n\n**查询**：获取特定人员的完整关系上下文\n\n```json\n{\n  \"person\": \"Bob Chen\",\n  \"limit\": 5\n}\n```\n\n返回结果包含该人员的所有交互证据、最近联系时间、共同话题等上下文信息。\n\n### 场景三：目标导向搜索\n\n**查询**：为特定目标寻找相关联系人\n\n```json\n{\n  \"goal\": \"Find potential co-founders for AI startup\",\n  \"limit\": 10\n}\n```\n\n系统综合分析所有联系人的背景、交互历史和话题相关性，生成目标相关度排序列表。\n\n## 总结\n\n网络查询系统是 Minty CRM 智能化能力的核心体现，通过整合多源数据、构建混合索引和提供自然语言接口，使用户能够以直观的方式探索和利用自己的人际网络。该系统具有以下核心特点：\n\n- **多源聚合**：统一检索散落在各平台的交互数据\n- **语义理解**：支持自然语言查询和意图识别\n- **智能排序**：综合相关度、时效性、亲密度多维度评分\n- **健康感知**：自动检测数据源状态，保证结果可靠性\n- **MCP 兼容**：提供标准化的 AI Agent 接口支持\n\n通过 `network-query.js`、`search.js`、`query-reasons.js` 和 `hybrid-index.js` 等模块的协作，网络查询系统为用户提供了从简单关键词搜索到复杂目标导向探索的完整检索能力。\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：sree-sanak/minty\n\n摘要：发现 14 个潜在踩坑项，其中 1 个为 high/blocking；最高优先级：安装坑 - 来源证据：Audit person-only filters for channel/broadcast/list contacts。\n\n## 1. 安装坑 · 来源证据：Audit person-only filters for channel/broadcast/list contacts\n\n- 严重度：high\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Audit person-only filters for channel/broadcast/list contacts\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_806464769ad247cd93162d66f18c8d51 | https://github.com/sree-sanak/minty/issues/86 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 2. 身份坑 · 仓库名和安装名不一致\n\n- 严重度：medium\n- 证据强度：runtime_trace\n- 发现：仓库名 `minty` 与安装入口 `imap` 不完全一致。\n- 对用户的影响：用户照着仓库名搜索包或照着包名找仓库时容易走错入口。\n- 建议检查：在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。\n- 复现命令：`npm install imap`\n- 防护动作：页面必须同时展示 repo 名和真实安装入口，避免用户搜索错包。\n- 证据：identity.distribution | github_repo:1217893833 | https://github.com/sree-sanak/minty | repo=minty; install=imap\n\n## 3. 安装坑 · 来源证据：Replace README screenshot TODO with privacy-safe demo visual\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Replace README screenshot TODO with privacy-safe demo visual\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_81816548248b4de0a1ace912ebf7ee0e | https://github.com/sree-sanak/minty/issues/97 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 4. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:1217893833 | https://github.com/sree-sanak/minty | README/documentation is current enough for a first validation pass.\n\n## 5. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:1217893833 | https://github.com/sree-sanak/minty | last_activity_observed missing\n\n## 6. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:1217893833 | https://github.com/sree-sanak/minty | no_demo; severity=medium\n\n## 7. 安全/权限坑 · 存在安全注意事项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：No sandbox install has been executed yet; downstream must verify before user use.\n- 对用户的影响：用户安装前需要知道权限边界和敏感操作。\n- 建议检查：转成明确权限清单和安全审查提示。\n- 防护动作：安全注意事项必须面向用户前置展示。\n- 证据：risks.safety_notes | github_repo:1217893833 | https://github.com/sree-sanak/minty | No sandbox install has been executed yet; downstream must verify before user use.\n\n## 8. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:1217893833 | https://github.com/sree-sanak/minty | no_demo; severity=medium\n\n## 9. 安全/权限坑 · 来源证据：Add minimal GitHub Actions smoke CI for npm test\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Add minimal GitHub Actions smoke CI for npm test\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_d6f1f5066d884d66b52f3e8f51ed0899 | https://github.com/sree-sanak/minty/issues/98 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 10. 安全/权限坑 · 来源证据：Avoid returning raw internal error messages from API/UI\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Avoid returning raw internal error messages from API/UI\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_2974d969ccff4c9b960c16ee12639466 | https://github.com/sree-sanak/minty/issues/44 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 11. 安全/权限坑 · 来源证据：Provision GitHub labels from checked-in labels.json\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Provision GitHub labels from checked-in labels.json\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_1a3ae522d9a7404691d7e3eb4b70b6b1 | https://github.com/sree-sanak/minty/issues/109 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 12. 安全/权限坑 · 来源证据：Sync failures can mark stale source data as fresh\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Sync failures can mark stale source data as fresh\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_3bc92d2124c24b978bf799cc9eff9529 | https://github.com/sree-sanak/minty/issues/200 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 13. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:1217893833 | https://github.com/sree-sanak/minty | issue_or_pr_quality=unknown\n\n## 14. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:1217893833 | https://github.com/sree-sanak/minty | release_recency=unknown\n\n<!-- canonical_name: sree-sanak/minty; human_manual_source: deepwiki_human_wiki -->\n",
      "markdown_key": "minty",
      "pages": "draft",
      "source_refs": [
        {
          "evidence_id": "github_repo:1217893833",
          "kind": "repo",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/sree-sanak/minty"
        },
        {
          "evidence_id": "art_7ca33f8227d94478a9d50d78f437ccd6",
          "kind": "docs",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/sree-sanak/minty#readme"
        }
      ],
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "minty 说明书",
      "toc": [
        "https://github.com/sree-sanak/minty 项目说明书",
        "目录",
        "项目介绍",
        "概述",
        "核心特性",
        "系统架构",
        "数据源支持",
        "启动方式",
        "Doramagic 踩坑日志"
      ]
    }
  },
  "quality_gate": {
    "blocking_gaps": [],
    "category_confidence": "medium",
    "compile_status": "ready_for_review",
    "five_assets_present": true,
    "install_sandbox_verified": true,
    "missing_evidence": [],
    "next_action": "publish to Doramagic.ai project surfaces",
    "prompt_preview_boundary_ok": true,
    "publish_status": "publishable",
    "quick_start_verified": true,
    "repo_clone_verified": true,
    "repo_commit": "2edf5089ff717bb49fb2a72956aec7ddfb538870",
    "repo_inspection_error": null,
    "repo_inspection_files": [
      "package.json",
      "README.md",
      "docs/OPENCLAW_HERMES.md",
      "docs/HERMES_INTEGRATION.md",
      "docs/SERVICE.md",
      "docs/feedback-loop.md",
      "docs/oss-polish-log.md",
      "docs/PHILOSOPHY.md",
      "docs/adr/0001-whatsapp-library.md",
      "docs/adr/README.md",
      "docs/plans/2026-04-28-goal-daily-moves.md",
      "docs/plans/2026-05-06-hermes-readiness-doctor.md",
      "docs/plans/2026-05-06-evidence-review-workbench.md",
      "docs/plans/2026-05-02-agent-retrieval-citations.md",
      "docs/plans/2026-05-04-agent-goal-actions-mcp.md",
      "docs/plans/2026-05-09-agent-surface-docs-contract.md",
      "docs/plans/2026-05-06-agent-workflow-evals.md",
      "docs/plans/2026-04-28-goal-activation-brief.md",
      "docs/plans/2026-05-10-agent-result-source-attribution.md",
      "docs/plans/2026-04-27-goal-match-evidence.md",
      "docs/plans/2026-05-11-person-context-source-filters.md",
      "docs/plans/2026-05-09-gbrain-export-trust-contract.md",
      "docs/plans/2026-05-08-source-filter-agent-evals.md",
      "docs/plans/2026-04-30-agent-meeting-prep-mcp.md",
      "docs/plans/2026-05-07-agent-intro-paths-mcp.md",
      "docs/plans/2026-05-09-source-answerability-gate.md",
      "docs/plans/2026-05-07-memory-refresh-diagnostics.md",
      "docs/plans/2026-05-06-agent-source-health-mcp.md"
    ],
    "repo_inspection_verified": true,
    "review_reasons": [],
    "tag_count_ok": true,
    "unsupported_claims": []
  },
  "schema_version": "0.1",
  "user_assets": {
    "ai_context_pack": {
      "asset_id": "ai_context_pack",
      "filename": "AI_CONTEXT_PACK.md",
      "markdown": "# minty - Doramagic AI Context Pack\n\n> 定位：安装前体验与判断资产。它帮助宿主 AI 有一个好的开始，但不代表已经安装、执行或验证目标项目。\n\n## 充分原则\n\n- **充分原则，不是压缩原则**：AI Context Pack 应该充分到让宿主 AI 在开工前理解项目价值、能力边界、使用入口、风险和证据来源；它可以分层组织，但不以最短摘要为目标。\n- **压缩策略**：只压缩噪声和重复内容，不压缩会影响判断和开工质量的上下文。\n\n## 给宿主 AI 的使用方式\n\n你正在读取 Doramagic 为 minty 编译的 AI Context Pack。请把它当作开工前上下文：帮助用户理解适合谁、能做什么、如何开始、哪些必须安装后验证、风险在哪里。不要声称你已经安装、运行或执行了目标项目。\n\n## Claim 消费规则\n\n- **事实来源**：Repo Evidence + Claim/Evidence Graph；Human Wiki 只提供显著性、术语和叙事结构。\n- **事实最低状态**：`supported`\n- `supported`：可以作为项目事实使用，但回答中必须引用 claim_id 和证据路径。\n- `weak`：只能作为低置信度线索，必须要求用户继续核实。\n- `inferred`：只能用于风险提示或待确认问题，不能包装成项目事实。\n- `unverified`：不得作为事实使用，应明确说证据不足。\n- `contradicted`：必须展示冲突来源，不得替用户强行选择一个版本。\n\n## 它最适合谁\n\n- **正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**：README 或插件配置提到多个宿主 AI。 证据：`README.md` Claim：`clm_0003` supported 0.86\n- **希望把专业流程带进宿主 AI 的用户**：仓库包含 Skill 文档。 证据：`hermes/minty-network-memory/SKILL.md` Claim：`clm_0004` supported 0.86\n\n## 它能做什么\n\n- **AI Skill / Agent 指令资产库**（可做安装前预览）：项目包含可被宿主 AI 读取的 Skill 或 Agent 指令文件，可用于把专业流程带入 Claude、Codex、Cursor 等宿主。 证据：`hermes/minty-network-memory/SKILL.md` Claim：`clm_0001` supported 0.86\n- **命令行启动或安装流程**（需要安装后验证）：项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 证据：`README.md` Claim：`clm_0002` supported 0.86\n\n## 怎么开始\n\n- `git clone https://github.com/sree-sanak/minty.git` 证据：`README.md` Claim：`clm_0005` supported 0.86\n\n## 继续前判断卡\n\n- **当前建议**：需要管理员/安全审批\n- **为什么**：继续前可能涉及密钥、账号、外部服务或敏感上下文，建议先经过管理员或安全审批。\n\n### 30 秒判断\n\n- **现在怎么做**：需要管理员/安全审批\n- **最小安全下一步**：先跑 Prompt Preview；若涉及凭证或企业环境，先审批再试装\n- **先别相信**：工具权限边界不能在安装前相信。\n- **继续会触碰**：命令执行、宿主 AI 配置、本地环境或项目文件\n\n### 现在可以相信\n\n- **适合人群线索：正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`README.md` Claim：`clm_0003` supported 0.86\n- **适合人群线索：希望把专业流程带进宿主 AI 的用户**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`hermes/minty-network-memory/SKILL.md` Claim：`clm_0004` supported 0.86\n- **能力存在：AI Skill / Agent 指令资产库**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`hermes/minty-network-memory/SKILL.md` Claim：`clm_0001` supported 0.86\n- **能力存在：命令行启动或安装流程**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`README.md` Claim：`clm_0002` supported 0.86\n- **存在 Quick Start / 安装命令线索**（supported）：可以相信项目文档出现过启动或安装入口；不要因此直接在主力环境运行。 证据：`README.md` Claim：`clm_0005` supported 0.86\n\n### 现在还不能相信\n\n- **工具权限边界不能在安装前相信。**（unverified）：MCP/tool 类项目通常会触碰文件、网络、浏览器或外部 API，必须真实检查权限和日志。\n- **真实输出质量不能在安装前相信。**（unverified）：Prompt Preview 只能展示引导方式，不能证明真实项目中的结果质量。\n- **宿主 AI 版本兼容性不能在安装前相信。**（unverified）：Claude、Cursor、Codex、Gemini 等宿主加载规则和版本差异必须在真实环境验证。\n- **不会污染现有宿主 AI 行为，不能直接相信。**（inferred）：Skill、plugin、AGENTS/CLAUDE/GEMINI 指令可能改变宿主 AI 的默认行为。 证据：`AGENTS.md`, `hermes/minty-network-memory/SKILL.md`\n- **可安全回滚不能默认相信。**（unverified）：除非项目明确提供卸载和恢复说明，否则必须先在隔离环境验证。\n- **真实安装后是否与用户当前宿主 AI 版本兼容？**（unverified）：兼容性只能通过实际宿主环境验证。\n- **项目输出质量是否满足用户具体任务？**（unverified）：安装前预览只能展示流程和边界，不能替代真实评测。\n- **安装命令是否需要网络、权限或全局写入？**（unverified）：这影响企业环境和个人环境的安装风险。 证据：`README.md`\n\n### 继续会触碰什么\n\n- **命令执行**：包管理器、网络下载、本地插件目录、项目配置或用户主目录。 原因：运行第一条命令就可能产生环境改动；必须先判断是否值得跑。 证据：`README.md`\n- **宿主 AI 配置**：Claude/Codex/Cursor/Gemini/OpenCode 等宿主的 plugin、Skill 或规则加载配置。 原因：宿主配置会改变 AI 后续工作方式，可能和用户已有规则冲突。 证据：`AGENTS.md`, `hermes/minty-network-memory/SKILL.md`\n- **本地环境或项目文件**：安装结果、插件缓存、项目配置或本地依赖目录。 原因：安装前无法证明写入范围和回滚方式，需要隔离验证。 证据：`README.md`\n- **环境变量 / API Key**：项目入口文档明确出现 API key、token、secret 或账号凭证配置。 原因：如果真实安装需要凭证，应先使用测试凭证并经过权限/合规判断。 证据：`README.md`, `crm/config.js`, `sources/apollo/enrich.js`, `tests/unit/config.test.js`\n- **宿主 AI 上下文**：AI Context Pack、Prompt Preview、Skill 路由、风险规则和项目事实。 原因：导入上下文会影响宿主 AI 后续判断，必须避免把未验证项包装成事实。\n\n### 最小安全下一步\n\n- **先跑 Prompt Preview**：用安装前交互式试用判断工作方式是否匹配，不需要授权或改环境。（适用：任何项目都适用，尤其是输出质量未知时。）\n- **只在隔离目录或测试账号试装**：避免安装命令污染主力宿主 AI、真实项目或用户主目录。（适用：存在命令执行、插件配置或本地写入线索时。）\n- **先备份宿主 AI 配置**：Skill、plugin、规则文件可能改变 Claude/Cursor/Codex 的默认行为。（适用：存在插件 manifest、Skill 或宿主规则入口时。）\n- **不要使用真实生产凭证**：环境变量/API key 一旦进入宿主或工具链，可能产生账号和合规风险。（适用：出现 API、TOKEN、KEY、SECRET 等环境线索时。）\n- **安装后只验证一个最小任务**：先验证加载、兼容、输出质量和回滚，再决定是否深用。（适用：准备从试用进入真实工作流时。）\n\n### 退出方式\n\n- **保留安装前状态**：记录原始宿主配置和项目状态，后续才能判断是否可恢复。\n- **准备移除宿主 plugin / Skill / 规则入口**：如果试装后行为异常，可以把宿主 AI 恢复到试装前状态。\n- **记录安装命令和写入路径**：没有明确卸载说明时，至少要知道哪些目录或配置需要手动清理。\n- **准备撤销测试 API key 或 token**：测试凭证泄露或误用时，可以快速止损。\n- **如果没有回滚路径，不进入主力环境**：不可回滚是继续前阻断项，不应靠信任或运气继续。\n\n## 哪些只能预览\n\n- 解释项目适合谁和能做什么\n- 基于项目文档演示典型对话流程\n- 帮助用户判断是否值得安装或继续研究\n\n## 哪些必须安装后验证\n\n- 真实安装 Skill、插件或 CLI\n- 执行脚本、修改本地文件或访问外部服务\n- 验证真实输出质量、性能和兼容性\n\n## 边界与风险判断卡\n\n- **把安装前预览误认为真实运行**：用户可能高估项目已经完成的配置、权限和兼容性验证。 处理方式：明确区分 prompt_preview_can_do 与 runtime_required。 Claim：`clm_0006` inferred 0.45\n- **命令执行会修改本地环境**：安装命令可能写入用户主目录、宿主插件目录或项目配置。 处理方式：先在隔离环境或测试账号中运行。 证据：`README.md` Claim：`clm_0007` supported 0.86\n- **待确认**：真实安装后是否与用户当前宿主 AI 版本兼容？。原因：兼容性只能通过实际宿主环境验证。\n- **待确认**：项目输出质量是否满足用户具体任务？。原因：安装前预览只能展示流程和边界，不能替代真实评测。\n- **待确认**：安装命令是否需要网络、权限或全局写入？。原因：这影响企业环境和个人环境的安装风险。\n\n## 开工前工作上下文\n\n### 加载顺序\n\n- 先读取 how_to_use.host_ai_instruction，建立安装前判断资产的边界。\n- 读取 claim_graph_summary，确认事实来自 Claim/Evidence Graph，而不是 Human Wiki 叙事。\n- 再读取 intended_users、capabilities 和 quick_start_candidates，判断用户是否匹配。\n- 需要执行具体任务时，优先查 role_skill_index，再查 evidence_index。\n- 遇到真实安装、文件修改、网络访问、性能或兼容性问题时，转入 risk_card 和 boundaries.runtime_required。\n\n### 任务路由\n\n- **AI Skill / Agent 指令资产库**：先基于 role_skill_index / evidence_index 帮用户挑选可用角色、Skill 或工作流。 边界：可做安装前 Prompt 体验。 证据：`hermes/minty-network-memory/SKILL.md` Claim：`clm_0001` supported 0.86\n- **命令行启动或安装流程**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`README.md` Claim：`clm_0002` supported 0.86\n\n### 上下文规模\n\n- 文件总数：248\n- 重要文件覆盖：40/248\n- 证据索引条目：80\n- 角色 / Skill 条目：1\n\n### 证据不足时的处理\n\n- **missing_evidence**：说明证据不足，要求用户提供目标文件、README 段落或安装后验证记录；不要补全事实。\n- **out_of_scope_request**：说明该任务超出当前 AI Context Pack 证据范围，并建议用户先查看 Human Manual 或真实安装后验证。\n- **runtime_request**：给出安装前检查清单和命令来源，但不要替用户执行命令或声称已执行。\n- **source_conflict**：同时展示冲突来源，标记为待核实，不要强行选择一个版本。\n\n## Prompt Recipes\n\n### 适配判断\n\n- 目标：判断这个项目是否适合用户当前任务。\n- 预期输出：适配结论、关键理由、证据引用、安装前可预览内容、必须安装后验证内容、下一步建议。\n\n```text\n请基于 minty 的 AI Context Pack，先问我 3 个必要问题，然后判断它是否适合我的任务。回答必须包含：适合谁、能做什么、不能做什么、是否值得安装、证据来自哪里。所有项目事实必须引用 evidence_refs、source_paths 或 claim_id。\n```\n\n### 安装前体验\n\n- 目标：让用户在安装前感受核心工作流，同时避免把预览包装成真实能力或营销承诺。\n- 预期输出：一段带边界标签的体验剧本、安装后验证清单和谨慎建议；不含真实运行承诺或强营销表述。\n\n```text\n请把 minty 当作安装前体验资产，而不是已安装工具或真实运行环境。\n\n请严格输出四段：\n1. 先问我 3 个必要问题。\n2. 给出一段“体验剧本”：用 [安装前可预览]、[必须安装后验证]、[证据不足] 三种标签展示它可能如何引导工作流。\n3. 给出安装后验证清单：列出哪些能力只有真实安装、真实宿主加载、真实项目运行后才能确认。\n4. 给出谨慎建议：只能说“值得继续研究/试装”“先补充信息后再判断”或“不建议继续”，不得替项目背书。\n\n硬性边界：\n- 不要声称已经安装、运行、执行测试、修改文件或产生真实结果。\n- 不要写“自动适配”“确保通过”“完美适配”“强烈建议安装”等承诺性表达。\n- 如果描述安装后的工作方式，必须使用“如果安装成功且宿主正确加载 Skill，它可能会……”这种条件句。\n- 体验剧本只能写成“示例台词/假设流程”：使用“可能会询问/可能会建议/可能会展示”，不要写“已写入、已生成、已通过、正在运行、正在生成”。\n- Prompt Preview 不负责给安装命令；如用户准备试装，只能提示先阅读 Quick Start 和 Risk Card，并在隔离环境验证。\n- 所有项目事实必须来自 supported claim、evidence_refs 或 source_paths；inferred/unverified 只能作风险或待确认项。\n\n```\n\n### 角色 / Skill 选择\n\n- 目标：从项目里的角色或 Skill 中挑选最匹配的资产。\n- 预期输出：候选角色或 Skill 列表，每项包含适用场景、证据路径、风险边界和是否需要安装后验证。\n\n```text\n请读取 role_skill_index，根据我的目标任务推荐 3-5 个最相关的角色或 Skill。每个推荐都要说明适用场景、可能输出、风险边界和 evidence_refs。\n```\n\n### 风险预检\n\n- 目标：安装或引入前识别环境、权限、规则冲突和质量风险。\n- 预期输出：环境、权限、依赖、许可、宿主冲突、质量风险和未知项的检查清单。\n\n```text\n请基于 risk_card、boundaries 和 quick_start_candidates，给我一份安装前风险预检清单。不要替我执行命令，只说明我应该检查什么、为什么检查、失败会有什么影响。\n```\n\n### 宿主 AI 开工指令\n\n- 目标：把项目上下文转成一次对话开始前的宿主 AI 指令。\n- 预期输出：一段边界明确、证据引用明确、适合复制给宿主 AI 的开工前指令。\n\n```text\n请基于 minty 的 AI Context Pack，生成一段我可以粘贴给宿主 AI 的开工前指令。这段指令必须遵守 not_runtime=true，不能声称项目已经安装、运行或产生真实结果。\n```\n\n\n## 角色 / Skill 索引\n\n- 共索引 1 个角色 / Skill / 项目文档条目。\n\n- **minty-network-memory**（skill）：Query Minty as private, read-only network memory inside Hermes workflows via local MCP tools. 激活提示：当用户任务与“minty-network-memory”描述的流程高度相关时，先用它做安装前体验，再决定是否安装。 证据：`hermes/minty-network-memory/SKILL.md`\n\n## 证据索引\n\n- 共索引 80 条证据。\n\n- **Architecture Decision Records**（documentation）：Lightweight log of significant technical decisions. Each ADR captures the context , the options considered , the decision , and the consequences — so future maintainers and the original author six months later can understand why the codebase looks the way it does. 证据：`docs/adr/README.md`\n- **AGENTS.md — Working on Minty with AI Assistance**（documentation）：AGENTS.md — Working on Minty with AI Assistance 证据：`AGENTS.md`\n- **Minty**（documentation）：Private network memory for OpenClaw, Hermes, and MCP agents. 证据：`README.md`\n- **ee/ — Enterprise Features**（documentation）：This directory is reserved for future proprietary features e.g. SSO/SAML, team admin, audit logs, multi-tenant hosting . It is intentionally empty for v0.1. 证据：`ee/README.md`\n- **Tests**（documentation）：The pre-push hook .githooks/pre-push auto-skips E2E if Playwright's Chromium isn't installed, so a fresh checkout doesn't have to install browsers to push. 证据：`tests/README.md`\n- **LinkedIn HTML fixtures**（documentation）：This directory holds HTML snapshots of LinkedIn pages used for offline parser tests in tests/unit/linkedin-scrape.test.js . These fixtures let the test suite run in CI without a live LinkedIn session. 证据：`sources/linkedin/fixtures/README.md`\n- **Package**（package_manifest）：{ \"name\": \"minty\", \"version\": \"0.3.2\", \"description\": \"Private network memory for OpenClaw, Hermes, and MCP agents — local relationship retrieval over contacts and conversations via UI, CLI, and stdio MCP.\", \"type\": \"commonjs\", \"license\": \"AGPL-3.0-only\", \"author\": \"Sree Sanakkayala\", \"homepage\": \"https://github.com/sree-sanak/minty readme\", \"repository\": { \"type\": \"git\", \"url\": \"git+https://github.com/sree-sanak/minty.git\" }, \"bugs\": { \"url\": \"https://github.com/sree-sanak/minty/issues\" }, \"keywords\": \"crm\", \"personal-crm\", \"prm\", \"self-hosted\", \"privacy\", \"whatsapp\", \"gmail\", \"linkedin\", \"telegram\", \"mcp\", \"openclaw\", \"hermes-agent\", \"ai-agent\", \"agent-memory\", \"relationship-intelligence\"… 证据：`package.json`\n- **Contributing to Minty**（documentation）：Thanks for your interest in contributing. Minty is maintained by a solo developer, so these rules exist to keep the project sustainable. Please read them before opening an issue or PR. 证据：`CONTRIBUTING.md`\n- **Minty Network Memory — Hermes Skill**（skill_instruction）：Minty Network Memory — Hermes Skill 证据：`hermes/minty-network-memory/SKILL.md`\n- **License**（source_file）：GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 证据：`LICENSE`\n- **Hermes Integration Guide**（documentation）：The broader OpenClaw/Hermes/MCP quickstart now lives in OPENCLAW HERMES.md ./OPENCLAW HERMES.md . This file keeps the Hermes-specific setup details. 证据：`docs/HERMES_INTEGRATION.md`\n- **OpenClaw + Hermes Integration**（documentation）：Minty is built to be a local relationship-memory backend for agent runtimes like OpenClaw and Hermes. It exposes your unified network through a read-only MCP server and a simple CLI, so agents can answer questions like “who can help with this?” without receiving raw contact dumps. 证据：`docs/OPENCLAW_HERMES.md`\n- **Minty — Research: Personal Relationship Management**（documentation）：Minty — Research: Personal Relationship Management What it should be, who it's for, what actually matters. 证据：`docs/PHILOSOPHY.md`\n- **Always-on Minty service**（documentation）：Minty can run as an always-on headless daemon that keeps your network data fresh in the background. No web UI required — the sync daemon, GBrain export, and MCP server all work standalone. 证据：`docs/SERVICE.md`\n- **OSS-polish log**（documentation）：A rolling log of open-source-quality improvements made by an autonomous loop while the maintainer is away. Newest at top. 证据：`docs/oss-polish-log.md`\n- **ADR 0001: WhatsApp Library Choice — whatsapp-web.js vs Baileys**（documentation）：ADR 0001: WhatsApp Library Choice — whatsapp-web.js vs Baileys 证据：`docs/adr/0001-whatsapp-library.md`\n- **Goal Match Evidence Implementation Plan**（documentation）：Goal Match Evidence Implementation Plan 证据：`docs/plans/2026-04-27-goal-match-evidence.md`\n- **Goal Activation Brief Implementation Plan**（documentation）：Goal Activation Brief Implementation Plan 证据：`docs/plans/2026-04-28-goal-activation-brief.md`\n- **Goal Daily Moves Implementation Plan**（documentation）：Goal Daily Moves Implementation Plan 证据：`docs/plans/2026-04-28-goal-daily-moves.md`\n- **Agent Meeting Prep MCP Implementation Plan**（documentation）：Agent Meeting Prep MCP Implementation Plan 证据：`docs/plans/2026-04-30-agent-meeting-prep-mcp.md`\n- **Agent Retrieval Citations Implementation Plan**（documentation）：Agent Retrieval Citations Implementation Plan 证据：`docs/plans/2026-05-02-agent-retrieval-citations.md`\n- **Agent Goal Actions MCP Implementation Plan**（documentation）：Agent Goal Actions MCP Implementation Plan 证据：`docs/plans/2026-05-04-agent-goal-actions-mcp.md`\n- **Agent Source Health MCP Implementation Plan**（documentation）：Agent Source Health MCP Implementation Plan 证据：`docs/plans/2026-05-06-agent-source-health-mcp.md`\n- **Agent Workflow Evals Implementation Plan**（documentation）：Agent Workflow Evals Implementation Plan 证据：`docs/plans/2026-05-06-agent-workflow-evals.md`\n- **Evidence Review Workbench Implementation Plan**（documentation）：Evidence Review Workbench Implementation Plan 证据：`docs/plans/2026-05-06-evidence-review-workbench.md`\n- **Hermes Readiness Doctor Implementation Plan**（documentation）：Hermes Readiness Doctor Implementation Plan 证据：`docs/plans/2026-05-06-hermes-readiness-doctor.md`\n- **Agent Intro Paths MCP Implementation Plan**（documentation）：Agent Intro Paths MCP Implementation Plan 证据：`docs/plans/2026-05-07-agent-intro-paths-mcp.md`\n- **Memory Refresh Diagnostics Implementation Plan**（documentation）：Memory Refresh Diagnostics Implementation Plan 证据：`docs/plans/2026-05-07-memory-refresh-diagnostics.md`\n- **Source-Filtered Agent Evals Implementation Plan**（documentation）：Source-Filtered Agent Evals Implementation Plan 证据：`docs/plans/2026-05-08-source-filter-agent-evals.md`\n- **Agent Surface Docs Contract Implementation Plan**（documentation）：Agent Surface Docs Contract Implementation Plan 证据：`docs/plans/2026-05-09-agent-surface-docs-contract.md`\n- **GBrain Export Trust Contract Implementation Plan**（documentation）：GBrain Export Trust Contract Implementation Plan 证据：`docs/plans/2026-05-09-gbrain-export-trust-contract.md`\n- **Source Answerability Gate Implementation Plan**（documentation）：Source Answerability Gate Implementation Plan 证据：`docs/plans/2026-05-09-source-answerability-gate.md`\n- **Agent Result Source Attribution Implementation Plan**（documentation）：Agent Result Source Attribution Implementation Plan 证据：`docs/plans/2026-05-10-agent-result-source-attribution.md`\n- **Person Context Source Filters Implementation Plan**（documentation）：Person Context Source Filters Implementation Plan 证据：`docs/plans/2026-05-11-person-context-source-filters.md`\n- **What this PR does**（documentation）：- Linked to an issue for non-trivial changes - Diff is focused on a single topic - Manually tested end-to-end - No personal data in the diff real phone numbers, emails, names - UI changes include before/after screenshots - AI-assisted? Disclosed in the description. 证据：`.github/PULL_REQUEST_TEMPLATE.md`\n- **Architecture**（documentation）：A 10-minute tour for new contributors. If you want the why behind the design choices, read VISION.md ./VISION.md and docs/PHILOSOPHY.md ./docs/PHILOSOPHY.md . If you want the what of the matching algorithm specifically, read crm/MATCHING.md ./crm/MATCHING.md . 证据：`ARCHITECTURE.md`\n- **Changelog**（documentation）：All notable changes to Minty will be documented in this file. 证据：`CHANGELOG.md`\n- **Contributor Covenant Code of Conduct**（documentation）：Contributor Covenant Code of Conduct 证据：`CODE_OF_CONDUCT.md`\n- **Releasing Minty**（documentation）：This is the recipe for cutting a Minty release. Maintainer-only operation, but documented here so contributors know the cadence and can predict when their merged PR will ship. 证据：`RELEASING.md`\n- **Roadmap**（documentation）：This is the short, public-facing roadmap. For the deeper \"why\" behind Minty's direction, see docs/PHILOSOPHY.md ./docs/PHILOSOPHY.md and VISION.md ./VISION.md . 证据：`ROADMAP.md`\n- **Security Policy**（documentation）：Security fixes are applied to the latest released 0.x minor only. Pre-1.0, we don't backport — please update to the latest before reporting. 证据：`SECURITY.md`\n- **Vision**（documentation）：Minty is a local-first, always-on relationship intelligence service . It runs as a background daemon on your machine, continuously watching your communication sources WhatsApp, Gmail, LinkedIn, Telegram, SMS, Google Contacts , consolidating contacts, resolving identities across channels, and exposing a live relationship index to AI agents and humans alike. No accounts, no cloud, no API fees. 证据：`VISION.md`\n- **Contact Matching Strategy for Claude Code**（documentation）：Contact Matching Strategy for Claude Code 证据：`crm/MATCHING.md`\n- **Labels**（structured_config）：{ \"name\": \"good first issue\", \"color\": \"7057ff\", \"description\": \"Good for newcomers — small scope, clear acceptance criteria\" }, { \"name\": \"help wanted\", \"color\": \"008672\", \"description\": \"Maintainer would welcome a PR for this\" }, { \"name\": \"bug\", \"color\": \"d73a4a\", \"description\": \"Something isn't working\" }, { \"name\": \"enhancement\", \"color\": \"a2eeef\", \"description\": \"New feature or improvement to existing functionality\" }, { \"name\": \"docs\", \"color\": \"0075ca\", \"description\": \"Improvements or additions to documentation\" }, { \"name\": \"dependencies\", \"color\": \"0366d6\", \"description\": \"Dependency updates Dependabot writes here \" }, { \"name\": \"ci\", \"color\": \"ededed\", \"description\": \"CI / build… 证据：`.github/labels.json`\n- **.Mcp**（structured_config）：{ \"mcpServers\": { \"chrome-devtools\": { \"command\": \"npx\", \"args\": \"-y\", \"chrome-devtools-mcp@0.23.0\" }, \"playwright\": { \"command\": \"npx\", \"args\": \"-y\", \"@playwright/mcp@0.0.70\" } } } 证据：`.mcp.json`\n- **Agent Workflows**（structured_config）：{ \"name\": \"crypto-insurance-positive\", \"target\": \"query network\", \"query\": \"Who do I know for crypto insurance?\", \"minResults\": 1, \"requireEvidenceKinds\": \"keyword\", \"topic\" , \"disallowFallback\": true, \"requirePaths\": \"safety.readOnly\", \"results.0.evidenceBacked\" , \"requirePathValues\": { \"safety.readOnly\": true }, \"forbidPaths\": \"results.0.email\", \"results.0.phone\" , \"forbidSubstrings\": \"raw-phone-555-0101\" }, { \"name\": \"crypto-insurance-mcp-search\", \"target\": \"mcp:search network\", \"arguments\": { \"query\": \"Who do I know for crypto insurance?\" }, \"minResults\": 1, \"requireEvidenceKinds\": \"keyword\", \"topic\" , \"disallowFallback\": true, \"requirePaths\": \"safety.readOnly\", \"results.0.evidence.0.ki… 证据：`tests/fixtures/agent-workflows.json`\n- **https://editorconfig.org — keeps whitespace consistent across editors.**（source_file）：https://editorconfig.org — keeps whitespace consistent across editors. root = true 证据：`.editorconfig`\n- **Minty — environment variable reference**（source_file）：Minty — environment variable reference None of these are required to run npm run crm . They're used by the optional data-source importers and the AI backend. Copy to .env or set inline on the command line and pass to node via node --env-file=.env crm/server.js if you want auto-loading. NEVER commit a real .env — it's already in .gitignore. 证据：`.env.example`\n- **!/usr/bin/env bash**（source_file）：!/usr/bin/env bash Runs preflight before every push. Bypass with git push --no-verify if needed. 证据：`.githooks/pre-push`\n- **Code owners — auto-requests review from listed accounts on matching PRs.**（source_file）：Code owners — auto-requests review from listed accounts on matching PRs. https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners Solo maintainer for now. As the project picks up area-specific contributors, split ownership per directory e.g. importers . 证据：`.github/CODEOWNERS`\n- **Dependabot — keep deps current with low review burden for a solo maintainer.**（source_file）：Dependabot — keep deps current with low review burden for a solo maintainer. Grouping pattern borrowed from Plausible/analytics + Standard Notes low open-PR cap, direct-deps only, weekly cadence . https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 证据：`.github/dependabot.yml`\n- **WhatsApp session contains auth cookies**（source_file）：WhatsApp session contains auth cookies .wwebjs auth/ .wwebjs cache/ 证据：`.gitignore`\n- **Agent Retrieval**（source_file）：/ crm/agent-retrieval.js — Pure agent-facing network retrieval module. Combines network-query parse + filter and query-reasons evidence into a single function that returns a stable, agent-friendly JSON envelope. No file I/O, no LLM calls, no side effects. Caller supplies contacts + insights; this module does the rest. / 证据：`crm/agent-retrieval.js`\n- **Agent Source Health**（source_file）：/ crm/agent-source-health.js — privacy-safe source readiness summarizer. Pure functions. No file I/O, no LLM calls. Converts local contacts, interactions, contact evidence, source events, and sync state into a redacted source readiness envelope for agent/MCP preflight. / 证据：`crm/agent-source-health.js`\n- **Ai**（source_file）：/ AI backend abstraction. Default AI BACKEND=claude : uses local Claude Code CLI via claude --print . This is used in both development and tests — Claude Code is the AI throughout. Optional AI BACKEND=ollama : falls back to a local Ollama model. Only useful if you want to run without Claude Code for some reason. Usage: const { runAI, runAIJson } = require './ai' ; const text = runAI 'Summarize this in one sentence: ...' ; const data = runAIJson 'Return a JSON array of topics from: ...' ; / 证据：`crm/ai.js`\n- **Analyze**（source_file）：/ Contact insight generator. This script is designed to be run by Claude Code the AI agent , NOT at server runtime. The agent reads interaction history and writes synthesized insights to data/unified/insights.json. Usage: node crm/analyze.js The script computes what it can algorithmically keyword frequency, source breakdown, recency . For narrative synthesis meetingBrief, topics, openLoops , run this script to generate the scaffold, then ask Claude Code to read the interaction data and fill in the synthesized insights. Insight schema per contact: { topics: string // top recurring subjects in conversations openLoops: string // things mentioned that were never followed up sentiment: string //… 证据：`crm/analyze.js`\n- **Calendar**（source_file）：/ crm/calendar.js — Google Calendar integration Pure functions for fetching, parsing, and cross-referencing calendar events with the contacts database. Called from: - crm/sync.js: background polling every 15 min - crm/server.js: GET /api/calendar/upcoming / 证据：`crm/calendar.js`\n- **Config**（source_file）：/ crm/config.js — runtime user config with hot-reload. Self-hosted users shouldn't have to touch env vars to enable features. Settings UI writes to data/config.json; this module reads it on every access, falling back to env vars for backwards-compatibility. Resolution order per key highest priority wins : 1. ENV var e.g. MINTY LINKEDIN AUTOSYNC=1, GOOGLE CLIENT ID=… 2. data/config.json 3. data/minty-mode.json legacy — still supported for the demo flag 4. built-in default Hot-reload: getConfig always reads current state without a restart. Cached in-process for ~1s to keep request paths fast. 0600 permissions on save because config.json can hold OAuth client secrets. / 证据：`crm/config.js`\n- **Contact Evidence**（source_file）：/ crm/contact-evidence.js — privacy-safe per-contact topic evidence. Pure functions. No file I/O, no LLM calls. Turns source interactions and batch insights into compact evidence envelopes agents can retrieve without exposing raw messages, subjects, chat names, emails, phones, or snippets. / 证据：`crm/contact-evidence.js`\n- **Digest**（source_file）：/ Weekly digest generator. Designed to be run by Claude Code the AI agent , NOT at server runtime. The agent reads contacts + interactions + insights, then: 1. This script computes all algorithmic fields automatically. 2. Claude Code fills in the narrative weekSummary by reading the data. Usage: node crm/digest.js Output: data/unified/digest.json { generatedAt: string // ISO timestamp weekSummary: string // narrative overview Claude Code fills this in topReconnects: Contact // dormant VIPs score =50, 60d openLoops: {contact, loop, contactId} // from insights.json activeThisWeek: Contact // contacted in last 7 days strongRelationships: Contact // score =70, recently contacted networkStats: o… 证据：`crm/digest.js`\n- 其余 20 条证据见 `AI_CONTEXT_PACK.json` 或 `EVIDENCE_INDEX.json`。\n\n## 宿主 AI 必须遵守的规则\n\n- **把本资产当作开工前上下文，而不是运行环境。**：AI Context Pack 只包含证据化项目理解，不包含目标项目的可执行状态。 证据：`docs/adr/README.md`, `AGENTS.md`, `README.md`\n- **回答用户时区分可预览内容与必须安装后才能验证的内容。**：安装前体验的消费者价值来自降低误装和误判，而不是伪装成真实运行。 证据：`docs/adr/README.md`, `AGENTS.md`, `README.md`\n\n## 用户开工前应该回答的问题\n\n- 你准备在哪个宿主 AI 或本地环境中使用它？\n- 你只是想先体验工作流，还是准备真实安装？\n- 你最在意的是安装成本、输出质量、还是和现有规则的冲突？\n\n## 验收标准\n\n- 所有能力声明都能回指到 evidence_refs 中的文件路径。\n- AI_CONTEXT_PACK.md 没有把预览包装成真实运行。\n- 用户能在 3 分钟内看懂适合谁、能做什么、如何开始和风险边界。\n\n---\n\n## Doramagic Context Augmentation\n\n下面内容用于强化 Repomix/AI Context Pack 主体。Human Manual 只提供阅读骨架；踩坑日志会被转成宿主 AI 必须遵守的工作约束。\n\n## Human Manual 骨架\n\n使用规则：这里只是项目阅读路线和显著性信号，不是事实权威。具体事实仍必须回到 repo evidence / Claim Graph。\n\n宿主 AI 硬性规则：\n- 不得把页标题、章节顺序、摘要或 importance 当作项目事实证据。\n- 解释 Human Manual 骨架时，必须明确说它只是阅读路线/显著性信号。\n- 能力、安装、兼容性、运行状态和风险判断必须引用 repo evidence、source path 或 Claim Graph。\n\n- **项目介绍**：importance `high`\n  - source_paths: README.md, VISION.md, SECURITY.md, docs/PHILOSOPHY.md\n- **快速开始**：importance `high`\n  - source_paths: README.md, docs/SERVICE.md, docs/OPENCLAW_HERMES.md\n- **项目文件结构**：importance `medium`\n  - source_paths: ARCHITECTURE.md, crm/index.js, scripts/minty-mcp-server.js\n- **架构总览**：importance `high`\n  - source_paths: ARCHITECTURE.md, crm/index.js, crm/schema.js, crm/server.js\n- **AI 后端配置**：importance `medium`\n  - source_paths: crm/ai.js, crm/digest.js, crm/evidence-patches.js, .env.example\n- **数据源导入**：importance `high`\n  - source_paths: sources/whatsapp/export.js, sources/linkedin/import.js, sources/telegram/import.js, sources/email/import.js, sources/google-contacts/import.js\n- **联系人合并与去重**：importance `high`\n  - source_paths: crm/match.js, crm/merge.js, crm/identity-candidates.js, crm/MATCHING.md\n- **数据存储结构**：importance `medium`\n  - source_paths: crm/export.js, crm/sync.js, scripts/export-data.js, scripts/export-gbrain-memory.js\n\n## Repo Inspection Evidence / 源码检查证据\n\n- repo_clone_verified: true\n- repo_inspection_verified: true\n- repo_commit: `2edf5089ff717bb49fb2a72956aec7ddfb538870`\n- inspected_files: `package.json`, `README.md`, `docs/OPENCLAW_HERMES.md`, `docs/HERMES_INTEGRATION.md`, `docs/SERVICE.md`, `docs/feedback-loop.md`, `docs/oss-polish-log.md`, `docs/PHILOSOPHY.md`, `docs/adr/0001-whatsapp-library.md`, `docs/adr/README.md`, `docs/plans/2026-04-28-goal-daily-moves.md`, `docs/plans/2026-05-06-hermes-readiness-doctor.md`, `docs/plans/2026-05-06-evidence-review-workbench.md`, `docs/plans/2026-05-02-agent-retrieval-citations.md`, `docs/plans/2026-05-04-agent-goal-actions-mcp.md`, `docs/plans/2026-05-09-agent-surface-docs-contract.md`, `docs/plans/2026-05-06-agent-workflow-evals.md`, `docs/plans/2026-04-28-goal-activation-brief.md`, `docs/plans/2026-05-10-agent-result-source-attribution.md`, `docs/plans/2026-04-27-goal-match-evidence.md`\n\n宿主 AI 硬性规则：\n- 没有 repo_clone_verified=true 时，不得声称已经读过源码。\n- 没有 repo_inspection_verified=true 时，不得把 README/docs/package 文件判断写成事实。\n- 没有 quick_start_verified=true 时，不得声称 Quick Start 已跑通。\n\n## Doramagic Pitfall Constraints / 踩坑约束\n\n这些规则来自 Doramagic 发现、验证或编译过程中的项目专属坑点。宿主 AI 必须把它们当作工作约束，而不是普通说明文字。\n\n### Constraint 1: 来源证据：Audit person-only filters for channel/broadcast/list contacts\n\n- Trigger: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Audit person-only filters for channel/broadcast/list contacts\n- Host AI rule: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- Why it matters: 可能影响升级、迁移或版本选择。\n- Evidence: community_evidence:github | cevd_806464769ad247cd93162d66f18c8d51 | https://github.com/sree-sanak/minty/issues/86 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 2: 仓库名和安装名不一致\n\n- Trigger: 仓库名 `minty` 与安装入口 `imap` 不完全一致。\n- Host AI rule: 在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。\n- Why it matters: 用户照着仓库名搜索包或照着包名找仓库时容易走错入口。\n- Evidence: identity.distribution | github_repo:1217893833 | https://github.com/sree-sanak/minty | repo=minty; install=imap\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 3: 来源证据：Replace README screenshot TODO with privacy-safe demo visual\n\n- Trigger: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Replace README screenshot TODO with privacy-safe demo visual\n- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Why it matters: 可能增加新用户试用和生产接入成本。\n- Evidence: community_evidence:github | cevd_81816548248b4de0a1ace912ebf7ee0e | https://github.com/sree-sanak/minty/issues/97 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 4: 能力判断依赖假设\n\n- Trigger: README/documentation is current enough for a first validation pass.\n- Host AI rule: 将假设转成下游验证清单。\n- Why it matters: 假设不成立时，用户拿不到承诺的能力。\n- Evidence: capability.assumptions | github_repo:1217893833 | https://github.com/sree-sanak/minty | README/documentation is current enough for a first validation pass.\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 5: 维护活跃度未知\n\n- Trigger: 未记录 last_activity_observed。\n- Host AI rule: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- Why it matters: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- Evidence: evidence.maintainer_signals | github_repo:1217893833 | https://github.com/sree-sanak/minty | last_activity_observed missing\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 6: 下游验证发现风险项\n\n- Trigger: no_demo\n- Host AI rule: 进入安全/权限治理复核队列。\n- Why it matters: 下游已经要求复核，不能在页面中弱化。\n- Evidence: downstream_validation.risk_items | github_repo:1217893833 | https://github.com/sree-sanak/minty | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 7: 存在安全注意事项\n\n- Trigger: No sandbox install has been executed yet; downstream must verify before user use.\n- Host AI rule: 转成明确权限清单和安全审查提示。\n- Why it matters: 用户安装前需要知道权限边界和敏感操作。\n- Evidence: risks.safety_notes | github_repo:1217893833 | https://github.com/sree-sanak/minty | No sandbox install has been executed yet; downstream must verify before user use.\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 8: 存在评分风险\n\n- Trigger: no_demo\n- Host AI rule: 把风险写入边界卡，并确认是否需要人工复核。\n- Why it matters: 风险会影响是否适合普通用户安装。\n- Evidence: risks.scoring_risks | github_repo:1217893833 | https://github.com/sree-sanak/minty | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 9: 来源证据：Add minimal GitHub Actions smoke CI for npm test\n\n- Trigger: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Add minimal GitHub Actions smoke CI for npm test\n- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Why it matters: 可能影响授权、密钥配置或安全边界。\n- Evidence: community_evidence:github | cevd_d6f1f5066d884d66b52f3e8f51ed0899 | https://github.com/sree-sanak/minty/issues/98 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 10: 来源证据：Avoid returning raw internal error messages from API/UI\n\n- Trigger: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Avoid returning raw internal error messages from API/UI\n- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Why it matters: 可能影响授权、密钥配置或安全边界。\n- Evidence: community_evidence:github | cevd_2974d969ccff4c9b960c16ee12639466 | https://github.com/sree-sanak/minty/issues/44 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n",
      "summary": "给宿主 AI 的上下文和工作边界。",
      "title": "AI Context Pack / 带给我的 AI"
    },
    "boundary_risk_card": {
      "asset_id": "boundary_risk_card",
      "filename": "BOUNDARY_RISK_CARD.md",
      "markdown": "# Boundary & Risk Card / 安装前决策卡\n\n项目：sree-sanak/minty\n\n## Doramagic 试用结论\n\n当前结论：可以进入发布前推荐检查；首次使用仍应从最小权限、临时目录和可回滚配置开始。\n\n## 用户现在可以做\n\n- 可以先阅读 Human Manual，理解项目目的和主要工作流。\n- 可以复制 Prompt Preview 做安装前体验；这只验证交互感，不代表真实运行。\n- 可以把官方 Quick Start 命令放到隔离环境中验证，不要直接进主力环境。\n\n## 现在不要做\n\n- 不要把 Prompt Preview 当成项目实际运行结果。\n- 不要把 metadata-only validation 当成沙箱安装验证。\n- 不要把未验证能力写成“已支持、已跑通、可放心安装”。\n- 不要在首次试用时交出生产数据、私人文件、真实密钥或主力配置目录。\n\n## 安装前检查\n\n- 宿主 AI 是否匹配：mcp_host\n- 官方安装入口状态：已发现官方入口\n- 是否在临时目录、临时宿主或容器中验证：必须是\n- 是否能回滚配置改动：必须能\n- 是否需要 API Key、网络访问、读写文件或修改宿主配置：未确认前按高风险处理\n- 是否记录了安装命令、实际输出和失败日志：必须记录\n\n## 当前阻塞项\n\n- 无阻塞项。\n\n## 项目专属踩坑\n\n- 来源证据：Audit person-only filters for channel/broadcast/list contacts（high）：可能影响升级、迁移或版本选择。 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 仓库名和安装名不一致（medium）：用户照着仓库名搜索包或照着包名找仓库时容易走错入口。 建议检查：在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。\n- 来源证据：Replace README screenshot TODO with privacy-safe demo visual（medium）：可能增加新用户试用和生产接入成本。 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 能力判断依赖假设（medium）：假设不成立时，用户拿不到承诺的能力。 建议检查：将假设转成下游验证清单。\n- 维护活跃度未知（medium）：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n\n## 风险与权限提示\n\n- no_demo: medium\n\n## 证据缺口\n\n- 暂未发现结构化证据缺口。\n",
      "summary": "安装、权限、验证和推荐前风险。",
      "title": "Boundary & Risk Card / 边界与风险卡"
    },
    "human_manual": {
      "asset_id": "human_manual",
      "filename": "HUMAN_MANUAL.md",
      "markdown": "# https://github.com/sree-sanak/minty 项目说明书\n\n生成时间：2026-05-11 23:57:10 UTC\n\n## 目录\n\n- [项目介绍](#page-introduction)\n- [快速开始](#page-quick-start)\n- [项目文件结构](#page-file-structure)\n- [架构总览](#page-architecture-overview)\n- [AI 后端配置](#page-ai-backend)\n- [数据源导入](#page-data-sources)\n- [联系人合并与去重](#page-contact-merging)\n- [数据存储结构](#page-data-storage)\n- [MCP 代理集成](#page-mcp-integration)\n- [网络查询系统](#page-network-query)\n\n<a id='page-introduction'></a>\n\n## 项目介绍\n\n### 相关页面\n\n相关主题：[快速开始](#page-quick-start), [架构总览](#page-architecture-overview)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/sree-sanak/minty/blob/main/README.md)\n- [ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n- [CHANGELOG.md](https://github.com/sree-sanak/minty/blob/main/CHANGELOG.md)\n- [RELEASING.md](https://github.com/sree-sanak/minty/blob/main/RELEASING.md)\n- [hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md)\n</details>\n\n# 项目介绍\n\n## 概述\n\nMinty 是一个本地优先的人脉网络记忆系统，旨在帮助用户从多个通讯渠道（WhatsApp、Telegram、邮件、日历、LinkedIn 等）汇总联系人信息，构建统一的人脉知识图谱，并通过 AI 驱动的自然语言查询能力实现\"记住所有人\"的愿景。\n\n该系统完全本地化运行，不依赖任何云端 API，采用本地 AI 模型（Ollama）或本地 Claude Code CLI 进行智能分析，确保用户数据的隐私安全。资料来源：[README.md]()\n\n## 核心特性\n\n| 特性 | 描述 |\n|------|------|\n| 多源数据整合 | 支持 WhatsApp、Telegram、Gmail、日历、LinkedIn 等多种数据源的导入与同步 |\n| 本地 AI 驱动 | 使用 Ollama 或 Claude Code CLI，完全离线运行，无云端依赖 |\n| 智能匹配 | 跨来源自动合并重复联系人，消除数据孤岛 |\n| 自然语言查询 | 通过 MCP 协议支持自然语言的人脉搜索 |\n| 关系热度追踪 | 自动计算联系人亲密度与互动频率，识别关系衰减信号 |\n| 定期回顾 | 生成\"失联联系人\"提醒与重连建议 |\n\n资料来源：[README.md](), [ARCHITECTURE.md]()\n\n## 系统架构\n\n### 整体架构\n\n```mermaid\ngraph TD\n    A[数据源] --> B[sources/ 导入层]\n    B --> C[data/<source>/ 原始数据]\n    C --> D[crm/merge.js 合并]\n    D --> E[data/unified/ 统一存储]\n    E --> F[AI 推理层]\n    E --> G[CRM Web UI]\n    E --> H[MCP Server]\n    \n    B1[WhatsApp] --> B\n    B2[Telegram] --> B\n    B3[Gmail/Email] --> B\n    B4[Calendar] --> B\n    B5[LinkedIn] --> B\n    B6[Slack] --> B\n```\n\n### 核心模块说明\n\n| 模块 | 文件 | 功能描述 |\n|------|------|----------|\n| 导入层 | `sources/*/import.js` | 各数据源的独立导入器，写入 `data/<source>/` |\n| 数据合并 | `crm/merge.js` | 加载各来源数据，进行规范化、去重，写入 `data/unified/contacts.json` 和 `interactions.json` |\n| 匹配算法 | `crm/match.js` | 跨来源联系人匹配逻辑，遵循 `MATCHING.md` 规范 |\n| 数据模式 | `crm/schema.js` | `Contact` 和 `Interaction` 的规范数据结构定义 |\n| 查询 CLI | `crm/query.js` | 命令行工具：`npm run stats`、`npm run search` |\n| 自然语言查询 | `crm/network-query.js` | \"Ask\"视图，支持自然语言提问 |\n| 重连建议 | `crm/reconnect.js` | 识别\"关系衰减\"联系人并生成重连草稿 |\n| AI 适配器 | `crm/ai.js` | 本地 Claude Code CLI / Ollama 适配器，无云端 API |\n| 数据陈旧检测 | `crm/staleness.js` | 标记陈旧联系人数据，供 UI 告警使用 |\n| 同步守护进程 | `crm/sync.js` | 监视 `data/<source>/export/` 目录，自动触发导入器 |\n| 高层功能 | `calendar.js`, `digest.js`, `meeting-debrief.js`, `goal-retro.js`, `life-events.js` | 基于统一存储的高级功能 |\n| 工具函数 | `crm/utils.js` | 电话/邮箱/姓名规范化、评分辅助、内存联系人索引 |\n\n资料来源：[ARCHITECTURE.md]()\n\n### 数据模型\n\n系统使用两个核心数据结构：\n\n**Contact（联系人）**\n- 基本信息：姓名、电话、邮箱、组织、职位\n- 来源追踪：`sources` 字段记录每个来源的具体数据\n- 关系评分：`relationshipScore` 基于互动频率计算\n- 亲密度：`warmth` 指标反映关系深度\n- 最后联系：`daysSinceContact` 计算天数\n\n**Interaction（互动记录）**\n- 时间戳与来源\n- 内容摘要：`subject`、`body`\n- 互动类型：会议、消息、通话等\n\n资料来源：[crm/schema.js](), [ARCHITECTURE.md]()\n\n## 数据源支持\n\n### 支持的来源\n\n| 数据源 | 状态 | 导入方式 |\n|--------|------|----------|\n| WhatsApp | 生产就绪 | 扫码认证、Session 自动恢复 |\n| Telegram | 生产就绪 | Bot Token 认证 |\n| Gmail/Email | 生产就绪 | Microsoft Graph API (OAuth) |\n| Google Calendar | 生产就绪 | Google Calendar API |\n| LinkedIn | 实验性 | CSV 导入 + 即将支持自动同步 |\n| Slack | 生产就绪 | Workspace Token |\n| SMS | 生产就绪 | iOS 备份解析 |\n| WhatsApp Business | 生产就绪 | iOS 备份解析 |\n\n每个数据源独立运行，写入 `data/<source>/` 目录。统一存储由 `crm/merge.js` 从各来源重建。\n\n资料来源：[README.md](), [ARCHITECTURE.md]()\n\n## 启动方式\n\n### 服务模式（推荐）\n\n```bash\n# 基础服务\nnpm run service\n\n# 指定用户 UUID\nMINTY_USER_UUID=abc npm run service\n\n# 启用定期 GBrain 导出\nMINTY_GBRAIN_EXPORT=1 npm run service\n```\n\n服务模式以无头守护进程运行，无 Web UI，适合长期部署。\n\n### Web UI 模式\n\n```bash\nnpm run crm\n```\n\n启动后在浏览器访问 `http://localhost:3456`，可浏览联系人、配置数据源、进行 QA 测试。\n\n### Agent 原生模式\n\n```bash\n# 初始化演示数据\nnpm run seed:demo\n\n# 自然语言查询\nCRM_DATA_DIR=./data-demo npm run agent -- \"who can help with crypto insurance\"\n\n# 启动 MCP 服务器\nCRM_DATA_DIR=./data-demo npm run mcp\n```\n\nMCP 服务器可注册到 OpenClaw 或 Hermes，实现智能体对人脉网络的自然语言访问。\n\n### 快速网络查询\n\n```bash\nnpm run network:search -- \"investors in fintech\"\nnpm run network:changes\nnpm run network:reconnect\nnpm run service:status\n```\n\n资料来源：[README.md]()\n\n## MCP 工具接口\n\nMinty 提供四个核心 MCP 工具：\n\n| 工具 | 功能 | 示例参数 |\n|------|------|----------|\n| `search_network` | 自然语言搜索人脉网络 | `{\"query\": \"investors in London\", \"limit\": 5}` |\n| `person_context` | 查询特定联系人详情 | `{\"person\": \"Alice Müller\", \"limit\": 3}` |\n| `workflow_brief` | 生成目标导向简报 | `{\"goal\": \"Find EU partners\", \"limit\": 5}` |\n| `source_health` | 检查数据源健康状态 | `{\"source\": \"telegram\"}` |\n\n这些工具通过 `scripts/minty-mcp-server.js` 暴露，是系统的工具接口规范。\n\n资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n## 版本与发布\n\n### 当前版本\n\n最新稳定版本信息记录在 `CHANGELOG.md` 中，采用语义化版本号 `MAJOR.MINOR.PATCH`。\n\n### 发布流程\n\n1. **版本决策**：查看 `CHANGELOG.md` 的 `Unreleased` 部分，确定版本号\n2. **更新 CHANGELOG**：将 `## [Unreleased]` 替换为 `## [X.Y.Z] - YYYY-MM-DD`\n3. **升级 package.json**：\n   ```bash\n   npm version X.Y.Z --no-git-tag-version\n   ```\n4. **提交**：\n   ```bash\n   git add CHANGELOG.md package.json package-lock.json\n   git commit -m \"release: vX.Y.Z\"\n   ```\n5. **打标签推送**：\n   ```bash\n   git tag vX.Y.Z\n   git push origin main\n   git push origin v.X.Y.Z\n   ```\n\n发布工作流自动验证标签与 `package.json` 的一致性，并从 `CHANGELOG.md` 提取发布说明创建 GitHub Release。\n\n### 热修复流程\n\n对于安全或生产级问题：\n\n1. 从标签分支：`git checkout -b hotfix/X.Y.Z+1 v.X.Y.Z`\n2. 修复代码\n3. 按标准发布流程升级 PATCH 版本\n4. 必要时将修复 cherry-pick 回 main 分支\n\n资料来源：[RELEASING.md]()\n\n## 技术要求\n\n| 要求 | 规格 |\n|------|------|\n| Node.js 版本 | Node 20 + 22 |\n| 包管理器 | npm |\n| 可选依赖 | Playwright（LinkedIn 自动同步）、csv-parse |\n| AI 后端 | Ollama（qwen2.5:7b 等模型）或 Claude Code CLI |\n\n所有 AI 输出（洞察、摘要、重连草稿、查询排名）均为预计算并缓存于 `data/unified/*.json`，Web 服务器读取静态文件，请求时无 API 调用。\n\n资料来源：[README.md](), [CHANGELOG.md]()\n\n## 数据隐私与许可\n\n- **数据存储**：所有数据本地存储于 `data/` 目录\n- **隐私保护**：支持匿名化导出（`npm run gbrain:export`），避免原始联系人/消息泄露\n- **许可协议**：采用 **AGPL-3.0** 许可证，开源且允许商业使用\n- **商业授权**：如需在专有产品中嵌入 Minty，可申请商业许可\n\n资料来源：[README.md]()\n\n## 贡献指南\n\n欢迎贡献代码。贡献者请先阅读：\n\n- [CONTRIBUTING.md](./CONTRIBUTING.md) — 贡献流程规范\n- [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md) — 行为准则\n- [SECURITY.md](./SECURITY.md) — 安全报告流程\n\n### 开发者入门\n\n| 任务 | 起点 |\n|------|------|\n| 添加新数据源 | 复制 `sources/telegram/`，参照文件布局 |\n| 改进匹配算法 | 阅读 `crm/MATCHING.md`，修改 `crm/match.js`，添加测试 fixture |\n| UI 开发 | 编辑 `crm/ui.html.js` 和 `crm/server.js`，重启 `npm run crm` |\n| 性能优化 | 关注 `crm/merge.js` 路径，参考 `tests/integration/` 的性能测试 |\n\n资料来源：[ARCHITECTURE.md]()\n\n## 项目愿景\n\nMinty 的核心目标是构建一个\"永不遗忘的人脉记忆系统\"。系统通过持续整合用户的通讯数据，自动识别联系人关系的变化，并在关键时刻提供智能化的回顾与行动建议。长期愿景是让用户能够专注于建立和维护有意义的人际关系，而不是记忆细节。\n\n项目路线图详见 [VISION.md](./VISION.md)。\n\n资料来源：[README.md]()\n\n---\n\n<a id='page-quick-start'></a>\n\n## 快速开始\n\n### 相关页面\n\n相关主题：[项目介绍](#page-introduction), [数据源导入](#page-data-sources)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/sree-sanak/minty/blob/main/README.md)\n- [ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n- [CONTRIBUTING.md](https://github.com/sree-sanak/minty/blob/main/CONTRIBUTING.md)\n- [hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md)\n- [sources/_shared/progress.js](https://github.com/sree-sanak/minty/blob/main/sources/_shared/progress.js)\n</details>\n\n# 快速开始\n\nMinty 是一个本地优先的关系管理系统，旨在帮助用户从多个数据源（WhatsApp、Telegram、Email、LinkedIn 等）聚合联系人信息，并通过 AI 能力提供关系洞察。本页将引导您完成 Minty 的安装、配置和首次使用。\n\n---\n\n## 环境要求\n\n| 组件 | 要求 |\n|------|------|\n| Node.js | v20 或 v22 |\n| 操作系统 | macOS、Linux、Windows（WSL 推荐） |\n| 存储空间 | 取决于数据量，建议预留 1GB+ |\n| 网络 | 仅在配置 AI 后端时需要（可选） |\n\n资料来源：[README.md:1-10]()\n\n---\n\n## 安装步骤\n\n### 1. 克隆仓库\n\n```bash\ngit clone https://github.com/sree-sanak/minty.git\ncd minty\n```\n\n### 2. 安装依赖\n\n```bash\nnpm install\n```\n\n此命令安装所有必要的 Node.js 依赖包，包括数据处理、加密、Web 服务等模块。\n\n### 3. 安装 Git Hooks（可选但推荐）\n\n```bash\nnpm run hooks:install\n```\n\n此命令启用预推送 Preflight 检查，确保代码在推送前通过基础测试。\n\n资料来源：[CONTRIBUTING.md:1-15]()\n\n---\n\n## 运行模式\n\nMinty 支持三种运行模式，适用于不同的使用场景：\n\n### 模式概览\n\n| 模式 | 命令 | 端口 | 适用场景 |\n|------|------|------|----------|\n| 常驻服务 | `npm run service` | 后台运行 | 生产环境、长期运行 |\n| Web UI | `npm run crm` | 3456 | 浏览器管理联系人 |\n| Agent 模式 | `npm run agent` | - | 与 OpenClaw/Hermes 集成 |\n\n资料来源：[README.md:20-35]()\n\n### 常驻服务模式（推荐）\n\n常驻服务以无头守护进程方式运行，持续同步数据：\n\n```bash\n# 默认模式\nnpm run service\n\n# 指定用户 UUID\nMINTY_USER_UUID=abc npm run service\n\n# 同时运行周期性 GBrain 导出\nMINTY_GBRAIN_EXPORT=1 npm run service\n```\n\n服务模式会在后台监控 `data/<source>/export/` 目录中的用户导入文件，并自动触发导入流程。资料来源：[ARCHITECTURE.md:1-30]()\n\n### Web UI 模式\n\n启动本地 Web 服务器，通过浏览器管理联系人：\n\n```bash\nnpm run crm\n```\n\n访问 `http://localhost:3456` 打开 Minty CRM 界面。Web UI 采用单页应用（SPA）架构，所有前端代码位于 `crm/ui.html.js` 中。\n\n> 注意：Web UI 读取的是预计算和缓存的静态文件（`data/unified/*.json`），无需在请求时调用 AI API。\n\n资料来源：[CONTRIBUTING.md:10-12]()\n\n### Agent 原生模式\n\n适用于与 OpenClaw、Hermes 或 Claude Code 等 AI Agent 集成：\n\n```bash\n# 初始化演示数据\nnpm run seed:demo\n\n# 执行网络查询\nCRM_DATA_DIR=./data-demo npm run agent -- \"who can help with crypto insurance\"\n\n# 启动 MCP 服务器\nCRM_DATA_DIR=./data-demo npm run mcp\n```\n\n注册 `scripts/minty-mcp-server.js` 作为本地 stdio MCP 服务器后，Agent 可直接调用以下工具：\n\n- `search_network` - 自然语言网络搜索\n- `person_context` - 查询特定联系人的上下文\n- `workflow_brief` - 生成目标导向简报\n- `source_health` - 检查数据源健康状态\n\n资料来源：[hermes/minty-network-memory/SKILL.md:1-50]()\n\n---\n\n## 快速网络查询\n\n以下命令适用于快速查询，无需启动完整服务：\n\n```bash\n# 自由形式搜索\nnpm run network:search -- \"investors in fintech\"\n\n# 通信模式变化\nnpm run network:changes\n\n# 渐行渐远的关系（需要重新联系）\nnpm run network:reconnect\n\n# 检查服务健康状态\nnpm run service:status\n```\n\n资料来源：[README.md:36-42]()\n\n---\n\n## 数据源配置\n\nMinty 支持多个可选数据源，每个源独立导入，按需启用：\n\n| 数据源 | 导入方式 | 说明 |\n|--------|----------|------|\n| WhatsApp | `npm run whatsapp` | 首次需扫描 QR 码 |\n| Telegram | `sources/telegram/import.js` | 导出 Telegram 数据 |\n| Email | Microsoft Graph API | 支持 Outlook/Exchange |\n| SMS | 平台特定 | 读取本地短信记录 |\n| LinkedIn | ZIP 包导入 | 导出 LinkedIn 数据 |\n| Google Contacts | 同步 | Google 账户联系人 |\n| Slack | 导出 | 导出 Slack 消息历史 |\n\n资料来源：[README.md:45-60]()\n\n### WhatsApp 快速配置\n\n```bash\nnpm run whatsapp\n```\n\n首次运行时显示 QR 码，用 WhatsApp 手机应用扫描后即可连接。后续运行自动恢复会话。\n\n---\n\n## AI 后端配置\n\nMinty 采用预计算 AI 策略，所有 AI 输出（洞察、摘要、重新联系草稿）存储在 `data/unified/*.json` 中，Web 服务器直接读取静态文件，无运行时 API 调用。\n\n### Claude Code CLI（默认）\n\n如果系统 PATH 中存在 `claude` 命令，Minty 自动使用此后端：\n\n```bash\n# 验证 Claude Code 可用性\nclaude --version\n```\n\n> 注意：Claude Code 后端会将提示词（包含联系人消息片段）发送至 Anthropic 服务器。\n\n资料来源：[README.md:100-115]()\n\n### Ollama（完全离线）\n\n配置本地 Ollama 模型：\n\n```bash\n# 在 .env 文件中设置\nAI_BACKEND=ollama\n\n# 推荐模型\nollama run qwen2.5:7b\n```\n\nOllama 模式完全离线运行，适合对数据隐私有高要求的用户。\n\n---\n\n## 数据目录结构\n\n所有数据存储在本地 `data/` 目录中（已被 Git 忽略）：\n\n```\ndata/\n├── whatsapp/         # WhatsApp 聊天和联系人\n├── telegram/         # Telegram 导出数据\n├── email/            # Email 账户数据\n├── sms/              # 短信数据\n├── linkedin/         # LinkedIn 导出（ZIP + CSV）\n├── google-contacts/  # Google 联系人\n├── slack/            # Slack 导出\n└── unified/          # 合并后的统一视图\n    ├── contacts.json       # 统一联系人\n    ├── interactions.json  # 互动时间线\n    └── match_overrides.json # 匹配规则覆盖\n```\n\n可通过环境变量覆盖数据目录：\n\n```bash\nCRM_DATA_DIR=./custom-data-dir npm run service\n```\n\n资料来源：[ARCHITECTURE.md:40-70]()\n\n---\n\n## 同步状态监控\n\n### 服务状态检查\n\n```bash\nnpm run service:status\n```\n\n### 单源进度查询\n\n每个导入器通过 `sources/_shared/progress.js` 记录同步进度：\n\n```javascript\n// 进度数据结构\n{\n  step: 'init' | 'messages' | 'contacts' | 'done',\n  message: string,\n  current: number,\n  total: number,\n  itemsProcessed: number,\n  errors: string[],\n  startedAt: ISO8601 timestamp,\n  updatedAt: ISO8601 timestamp\n}\n```\n\nAPI 端点：\n\n- `GET /api/sources/:key/progress` - 单个数据源进度\n- `GET /api/sync/progress` - 所有源同步进度\n\n资料来源：[sources/_shared/progress.js:1-40]()\n\n---\n\n## 完整工作流程\n\n```mermaid\ngraph TD\n    A[安装 Minty] --> B[选择运行模式]\n    B --> C[配置数据源]\n    C --> D[运行导入]\n    D --> E[合并数据<br/>merge.js]\n    E --> F[交叉匹配<br/>match.js]\n    F --> G[预计算 AI 洞察]\n    G --> H[访问数据]\n    \n    C --> C1[WhatsApp]\n    C --> C2[Telegram]\n    C --> C3[Email]\n    C --> C4[LinkedIn]\n    \n    H --> H1[Web UI<br/>localhost:3456]\n    H --> H2[Agent 查询<br/>MCP]\n    H --> H3[CLI 查询<br/>network:*]\n```\n\n---\n\n## 下一步\n\n| 任务 | 参考文档 |\n|------|----------|\n| 添加新数据源 | [ARCHITECTURE.md - 添加新导入器](ARCHITECTURE.md) |\n| 改进联系人匹配 | [crm/MATCHING.md](crm/MATCHING.md) |\n| Web UI 开发 | 修改 `crm/ui.html.js` |\n| 性能优化 | `tests/integration/` 集成测试 |\n| 测试运行 | `npm test` |\n\n---\n\n## 常见问题\n\n### Q: 首次运行报错 \"csv-parse not found\"？\n\n确保 `csv-parse` 依赖已安装：\n\n```bash\nnpm install csv-parse\n```\n\n此问题在 v0.3.2 中已修复。\n\n资料来源：[CHANGELOG.md:1-20]()\n\n### Q: 如何验证安装正确？\n\n```bash\nnpm test\n```\n\n运行完整单元测试套件（747 个测试）。\n\n### Q: 数据隐私如何保证？\n\n所有数据存储在本地 `data/` 目录，无遥测、无分析、无电话-home。详见 [SECURITY.md](SECURITY.md)。\n\n---\n\n## 许可证\n\nMinty 采用 **AGPL-3.0** 许可证发布。详情见 [LICENSE](LICENSE)。\n\n如需在专有产品中嵌入 Minty，可申请商业许可：开一个 Issue 联系我们。\n\n---\n\n<a id='page-file-structure'></a>\n\n## 项目文件结构\n\n### 相关页面\n\n相关主题：[项目介绍](#page-introduction), [架构总览](#page-architecture-overview)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n- [crm/server.js](https://github.com/sree-sanak/minty/blob/main/crm/server.js)\n- [crm/staleness.js](https://github.com/sree-sanak/minty/blob/main/crm/staleness.js)\n- [sources/_shared/progress.js](https://github.com/sree-sanak/minty/blob/main/sources/_shared/progress.js)\n- [sources/email/import.js](https://github.com/sree-sanak/minty/blob/main/sources/email/import.js)\n- [sources/google-contacts/sync-hermes.js](https://github.com/sree-sanak/minty/blob/main/sources/google-contacts/sync-hermes.js)\n- [crm/review-server.js](https://github.com/sree-sanak/minty/blob/main/crm/review-server.js)\n- [README.md](https://github.com/sree-sanak/minty/blob/main/README.md)\n</details>\n\n# 项目文件结构\n\n## 概述\n\nMinty 是一个个人关系管理系统（Personal CRM），用于聚合来自多个通讯平台的数据，构建统一的人际关系视图。项目采用模块化架构，将数据导入、合并、搜索和服务层分离，便于扩展和维护。\n\n资料来源：[ARCHITECTURE.md]()\n\n## 顶层目录结构\n\n```\nminty/\n├── crm/                    # 核心 CRM 服务层\n├── sources/                # 各平台数据导入器\n├── hermes/                 # Hermes 工作流集成\n├── scripts/                # 工具脚本\n├── data/                   # 运行时数据目录（gitignored）\n├── docs/                   # 文档\n└── package.json\n```\n\n## 核心模块详解\n\n### crm/ — 核心服务层\n\nCRM 层负责数据合并、API 服务和前端渲染，是整个系统的中枢。\n\n| 文件 | 职责 |\n|------|------|\n| `server.js` | HTTP API 服务器，处理所有 `/api/*` 路由 |\n| `index.js` | 入口文件，路由分发 |\n| `merge.js` | 多源数据标准化、去重、合并 |\n| `match.js` | 跨源匹配算法 |\n| `schema.js` | Contact 和 Interaction 的规范数据模型 |\n| `query.js` | CLI 工具：`npm run stats`、`npm run search` |\n| `network-query.js` | 自然语言查询接口 |\n| `reconnect.js` | 关系淡化检测与草稿生成 |\n| `ai.js` | AI 适配器（本地 Claude Code / Ollama） |\n| `staleness.js` | 数据新鲜度评估 |\n| `sync.js` | 监听 `data/<source>/export/` 目录变化 |\n| `calendar.js` | 日历集成 |\n| `digest.js` | 每周摘要生成 |\n| `meeting-debrief.js` | 会议复盘 |\n| `goal-retro.js` | 目标回顾 |\n| `life-events.js` | 人生大事记录 |\n| `utils.js` | 电话/邮箱/姓名标准化，评分辅助 |\n| `review-server.js` | 匹配审核服务器（人工确认） |\n\n资料来源：[ARCHITECTURE.md]()\n\n### sources/ — 数据导入器\n\n每个数据源独立运行，向 `data/<source>/` 目录写入 JSON 文件。\n\n```\nsources/\n├── _shared/                # 共享工具\n│   └── progress.js         # 统一的进度追踪\n├── whatsapp/               # WhatsApp 导入器\n├── telegram/               # Telegram 导入器\n├── email/                  # Email 导入器（Microsoft Graph）\n├── google-contacts/        # Google Contacts 同步\n├── linkedin/               # LinkedIn CSV 解析\n├── sms/                    # 短信导入\n└── slack/                  # Slack 导入\n```\n\n#### 进度追踪机制\n\n`sources/_shared/progress.js` 提供原子化的进度文件写入：\n\n```javascript\n// 导入器启动时调用\nP.startProgress(DATA_DIR, 'email', { step: 'init', message: 'Connecting…' });\n\n// 导入过程中更新\nP.updateProgress(DATA_DIR, 'email', { \n    step: 'messages', \n    message: 'Fetching via Microsoft Graph…' \n});\n```\n\n进度文件格式（`.progress.json`）包含：step、message、current、total、itemsProcessed、errors、startedAt、updatedAt。\n\n资料来源：[sources/_shared/progress.js:1-50]()\n\n#### Email 导入器\n\n`sources/email/import.js` 支持两种认证方式：\n\n1. **Microsoft Graph API** — 使用 `EMAIL_ACCESS_TOKEN` 和 `EMAIL_TOKEN_TYPE=microsoft`\n2. **通用 OAuth** — 通过 `EMAIL_ACCESS_TOKEN` 环境变量\n\n导入结果写入 `data/email/` 目录，包含消息和联系人。\n\n资料来源：[sources/email/import.js:50-80]()\n\n#### Google Contacts 同步\n\n`sources/google-contacts/sync-hermes.js` 实现基于身份（邮箱/电话）的联系人合并：\n\n```javascript\nfunction mergeByIdentity(contacts) {\n  const byKey = new Map();\n  for (const contact of contacts) {\n    const key = contact.emails[0] || contact.phones[0] || ...;\n    // 合并重复联系人\n  }\n  return [...byKey.values()];\n}\n```\n\n资料来源：[sources/google-contacts/sync-hermes.js:30-45]()\n\n### data/ — 运行时数据目录\n\n数据目录结构如下（受 `CRM_DATA_DIR` 环境变量控制）：\n\n```\ndata/\n├── whatsapp/           chats.json, contacts.json, metadata.json, profile_pics/\n├── linkedin/           export/ (用户上传的 ZIP) + 解析后的 CSV\n├── telegram/           result.json + 解析结果\n├── email/              按账户分文件夹\n├── sms/                按平台分文件夹\n├── google-contacts/    同步数据\n├── unified/            合并后的统一视图\n│   ├── contacts.json       # 唯一联系人列表\n│   ├── interactions.json   # 交互时间线\n│   └── match_overrides.json # 手动匹配覆盖\n└── goals/              目标数据\n```\n\n资料来源：[ARCHITECTURE.md]()\n\n### hermes/ — 工作流集成\n\n`hermes/minty-network-memory/` 包含 Hermes 工作流的技能定义，暴露以下 MCP 工具：\n\n| 工具 | 功能 |\n|------|------|\n| `search_network` | 自然语言网络搜索 |\n| `person_context` | 单个联系人上下文查询 |\n| `workflow_brief` | 目标导向的联系人推荐 |\n| `source_health` | 数据源健康状态检查 |\n\n资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n### scripts/ — 工具脚本\n\n| 脚本 | 用途 |\n|------|------|\n| `minty-mcp-server.js` | MCP 服务器入口 |\n| `sync-labels.js` | GitHub 标签同步 |\n| `seed-dev-data.js` | 开发数据生成 |\n\n资料来源：[README.md]()\n\n## 数据流程架构\n\n```mermaid\ngraph TD\n    subgraph 用户操作\n        A[运行导入器] --> B[source/import.js]\n    end\n    \n    subgraph 源数据层\n        B --> C[data/&lt;source&gt;/]\n        C --> D[whatsapp/]\n        C --> E[email/]\n        C --> F[telegram/]\n        C --> G[linkedin/]\n    end\n    \n    subgraph 合并层\n        H[crm/merge.js] --> I[标准化]\n        I --> J[去重匹配]\n        J --> K[构建时间线]\n        H -.-> L[data/unified/]\n    end\n    \n    subgraph 服务层\n        M[crm/server.js] --> N[REST API]\n        M --> O[crm/query.js]\n        M --> P[crm/network-query.js]\n    end\n    \n    subgraph 前端\n        Q[crm/ui.html.js] --> N\n        R[Hermes Agent] --> S[MCP Tools]\n    end\n    \n    L --> M\n```\n\n## API 路由概览\n\n`crm/server.js` 提供的主要 REST 端点：\n\n| 方法 | 路由 | 功能 |\n|------|------|------|\n| GET | `/api/contacts` | 获取联系人列表 |\n| GET | `/api/contacts/:id` | 获取单个联系人 |\n| GET | `/api/interactions` | 交互时间线 |\n| GET | `/api/sync/progress` | 同步进度 |\n| GET | `/api/sources/:key/progress` | 单源进度 |\n| GET | `/api/goals` | 目标列表 |\n| GET | `/api/goals/:id/pipeline` | 目标联系人管道 |\n| GET | `/api/goals/:id/retro` | 目标回顾 |\n| GET | `/api/export` | 导出数据 |\n| POST | `/api/export` | 创建加密备份 |\n\n资料来源：[crm/server.js:200-280]()\n\n## 数据新鲜度管理\n\n`crm/staleness.js` 实现数据新鲜度检测：\n\n```javascript\nfunction getStalenessMessage(source, days) {\n    if (days === null) return `${label} has never synced`;\n    if (days === 0) return `${label} synced today`;\n    if (days <= 7) return `${label} synced ${days} days ago`;\n    if (days <= 30) return `${label} export is ${days} days old — refresh?`;\n    return `${label} export is ${days} days old — data may be outdated`;\n}\n```\n\n新鲜度等级：\n- **高**：最近 7 天有同步\n- **中**：7-30 天未同步\n- **低**：超过 30 天或从未同步\n\n资料来源：[crm/staleness.js:1-50]()\n\n## 贡献者指南\n\n### 新增导入器\n\n1. 复制简单导入器模板（如 `sources/telegram/`）\n2. 写入 `data/<your-source>/`\n3. 在 `crm/merge.js` 中添加合并步骤\n\n### 匹配算法改进\n\n1. 阅读 `crm/MATCHING.md` 规范\n2. 修改 `crm/match.js`\n3. 在 `tests/` 添加测试用例\n\n### UI 开发\n\n- 编辑 `crm/ui.html.js` 修改 SPA\n- 编辑 `crm/server.js` 调整路由\n- 重启 `npm run crm` 以热更新\n\n资料来源：[ARCHITECTURE.md]()\n\n## 环境变量配置\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `CRM_DATA_DIR` | `./data` | 数据根目录 |\n| `EMAIL_EXPORT_DIR` | - | Email 导出目录 |\n| `EMAIL_ACCESS_TOKEN` | - | Graph API 令牌 |\n| `MINTY_USER_UUID` | - | 用户 UUID |\n| `AI_BACKEND` | `claude` | AI 后端（ollama/claude） |\n\n## 模块依赖关系\n\n```mermaid\ngraph LR\n    subgraph 数据源\n        A[WhatsApp] --> G[merge.js]\n        B[Email] --> G\n        C[Telegram] --> G\n        D[LinkedIn] --> G\n    end\n    \n    G --> H[unified/contacts.json]\n    G --> I[unified/interactions.json]\n    \n    H --> J[server.js]\n    I --> J\n    \n    J --> K[ui.html.js]\n    J --> L[MCP Server]\n    J --> M[CLI Query]\n\n---\n\n<a id='page-architecture-overview'></a>\n\n## 架构总览\n\n### 相关页面\n\n相关主题：[项目介绍](#page-introduction), [AI 后端配置](#page-ai-backend), [数据存储结构](#page-data-storage)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n- [crm/server.js](https://github.com/sree-sanak/minty/blob/main/crm/server.js)\n- [crm/schema.js](https://github.com/sree-sanak/minty/blob/main/crm/schema.js)\n- [crm/staleness.js](https://github.com/sree-sanak/minty/blob/main/crm/staleness.js)\n- [sources/_shared/progress.js](https://github.com/sree-sanak/minty/blob/main/sources/_shared/progress.js)\n- [sources/email/import.js](https://github.com/sree-sanak/minty/blob/main/sources/email/import.js)\n- [hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md)\n</details>\n\n# 架构总览\n\n## 项目概述\n\nMinty 是一个本地优先的 CRM 系统，用于聚合来自多个数据源的联系人与交互记录，并通过本地 AI（Claude Code CLI 或 Ollama）生成洞察和关系评分。项目完全离线运行，所有数据存储在本地 `data/` 目录，无遥测、无分析、无云端同步。资料来源：[README.md](https://github.com/sree-sanak/minty/blob/main/README.md)\n\n## 核心模块架构\n\n项目采用模块化架构，主要分为三个顶层目录：\n\n| 模块 | 路径 | 功能描述 |\n|------|------|----------|\n| **crm/** | `crm/` | 应用主程序 + 确定性的 AI 检索引擎 |\n| **sources/** | `sources/` | 每个数据源的独立导入器 |\n| **scripts/** | `scripts/` | CLI/MCP 入口点，供 OpenClaw、Hermes 等 agent 调用 |\n\n资料来源：[README.md](https://github.com/sree-sanak/minty/blob/main/README.md)\n\n```\ncrm/        # 应用核心 + 检索引擎\nscripts/    # CLI/MCP 入口\nsources/    # 数据源导入器\nee/         # 预留商业功能\ndata/       # 本地数据（gitignored）\ndocs/       # 文档 + ADR\ntests/      # 单元/集成/e2e 测试\n```\n\n## CRM 模块详细架构\n\nCRM 模块是系统的核心，包含以下关键文件：\n\n| 文件 | 功能 |\n|------|------|\n| `ui.html.js` | 单页应用外壳（HTML/CSS/JS 合一模板） |\n| `merge.js` | 加载各源数据、规范化、去重、写入 `unified/contacts.json` 和 `interactions.json` |\n| `match.js` | 跨源匹配算法，读取 MATCHING.md 规范 |\n| `schema.js` | Contact 和 Interaction 的规范记录格式 |\n| `query.js` | CLI 工具：`npm run stats`、`npm run search` |\n| `network-query.js` | 自然语言\"Ask\"视图 |\n| `reconnect.js` | \"渐行渐远的人\"界面 + 草稿生成 |\n| `ai.js` | 本地 Claude Code CLI / Ollama 适配器，无云端 API |\n| `staleness.js` | 标记陈旧联系人数据 |\n| `sync.js` | 监听 `data/<source>/export/` 目录变化并触发导入器 |\n| `calendar.js`、`digest.js`、`meeting-debrief.js`、`goal-retro.js`、`life-events.js` | 基于统一存储构建的高级界面 |\n| `utils.js` | 电话/邮箱/姓名规范化、评分辅助函数、内存联系人索引 |\n\n资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n### 数据模型（Schema）\n\n系统定义了规范的联系人与交互记录格式：\n\n```javascript\n// Contact 核心结构\n{\n  id: string,\n  name: string,\n  phones: string[],\n  emails: string[],\n  sources: { [sourceName]: sourceData },\n  relationshipScore: number,\n  daysSinceContact: number,\n  activeChannels: string[],\n  // ...\n}\n\n// Interaction 核心结构\n{\n  id: string,\n  timestamp: string,\n  source: string,\n  body: string,\n  subject: string,\n  participants: string[],\n  // ...\n}\n```\n\n修改数据模型时，应首先编辑 `schema.js`，其余模块随之更新。资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n## 数据流架构\n\n数据生命周期端到端流程如下：\n\n```mermaid\ngraph TD\n    A[\"用户运行导入器\"] --> B[\"源导入器<br/>sources/<src>/...\"]\n    B --> C[\"data/<source>/*.json<br/>每源记录\"]\n    C --> D[\"crm/merge.js\"]\n    D --> E[\"规范化手机/邮箱/姓名\"]\n    D --> F[\"跨源去重<br/>crm/match.js, MATCHING.md\"]\n    D --> G[\"构建统一交互时间线\"]\n    E --> H[\"data/unified/contacts.json\"]\n    F --> H\n    G --> I[\"data/unified/interactions.json\"]\n    \n    H --> J[\"crm/server.js<br/>REST API\"]\n    I --> J\n    J --> K[\"ui.html.js<br/>单页应用\"]\n    \n    J --> L[\"ai.js<br/>Claude Code CLI / Ollama\"]\n    L --> M[\"生成洞察、评分、摘要\"]\n    M --> H\n```\n\n资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n## 导入器（Sources）架构\n\n每个数据源是独立的导入模块，写入 `data/<source>/` 目录。统一存储由 `crm/merge.js` 重建。\n\n### 支持的数据源\n\n| 数据源 | 路径 | 说明 |\n|--------|------|------|\n| WhatsApp | `data/whatsapp/` | chats.json, contacts.json, metadata.json, profile_pics/ |\n| LinkedIn | `data/linkedin/` | 用户上传的 ZIP 包 + 解析后的 CSV |\n| Telegram | `data/telegram/` | result.json + 解析结果 |\n| Email | `data/email/` | 按账户分文件夹 |\n| SMS | `data/sms/` | 按平台分文件夹 |\n| Google Contacts | `data/google-contacts/` | 同步数据 |\n| 统一存储 | `data/unified/` | contacts.json, interactions.json, match_overrides.json |\n\n资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n### 导入器进度追踪\n\n所有导入器使用统一的进度文件 `.progress.json`，包含标准字段：\n\n```javascript\n{\n  source: string,        // 数据源标识\n  step: string,          // 当前步骤\n  message: string,       // 状态消息\n  current: number,       // 当前进度\n  total: number,         // 总数\n  itemsProcessed: number,\n  errors: string[],\n  startedAt: string,     // ISO 时间戳\n  updatedAt: string      // ISO 时间戳\n}\n```\n\n进度操作函数位于 `sources/_shared/progress.js`：\n\n- `startProgress(dataDir, source, initial)` — 初始化进度\n- `updateProgress(dataDir, source, patch)` — 更新进度\n- `readProgress(dataDir, source)` — 读取进度\n\n资料来源：[sources/_shared/progress.js](https://github.com/sree-sanak/minty/blob/main/sources/_shared/progress.js)\n\n### 添加新导入器\n\n添加新数据源的步骤：\n\n1. 复制简单导入器作为模板（如 `sources/telegram/import.js`）\n2. 遵循其文件布局\n3. 写入 `data/<your-source>/`\n4. 在 `crm/merge.js` 中添加合并步骤\n\n资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n## API 路由体系\n\n`crm/server.js` 提供完整的 REST API，所有接口前缀为 `/api/`：\n\n| 方法 | 路径 | 功能 |\n|------|------|------|\n| GET | `/api/contacts` | 获取联系人列表 |\n| GET | `/api/contacts/:id` | 获取单个联系人详情 |\n| GET | `/api/contacts/:id/interactions` | 获取联系人交互记录 |\n| GET/POST | `/api/export` | 导入/导出数据 |\n| GET | `/api/digest` | 周报摘要 |\n| GET | `/api/goals` | 目标列表 |\n| POST | `/api/goals/:id/assign` | 分配联系人到目标 |\n| GET | `/api/goals/:id/pipeline` | 目标漏斗视图 |\n| GET | `/api/goals/:id/retro` | 目标回顾 |\n| GET | `/api/meetings/debriefs/pending` | 待处理会议总结 |\n| GET/POST | `/api/meetings/:id/debrief` | 会议总结 |\n| GET | `/api/sources/:key/progress` | 数据源同步进度 |\n| GET | `/api/sync/progress` | 全部数据源进度 |\n| GET | `/api/notifications` | 通知列表 |\n| POST | `/api/notifications/:type/dismiss` | 忽略通知 |\n| GET | `/api/meta` | 元信息（demo 模式、数据目录等） |\n\n资料来源：[crm/server.js](https://github.com/sree-sanak/minty/blob/main/crm/server.js)\n\n## 数据陈旧性检测\n\n`crm/staleness.js` 负责检测数据新鲜度，提供两种检测维度：\n\n### 数据源级别陈旧性\n\n| 陈旧天数 | 严重程度 | 消息 |\n|----------|----------|------|\n| 从未同步 | warning | `{label} 从未同步` |\n| 0 天 | info | `{label} 今天已同步` |\n| 1 天 | info | `{label} 昨天已同步` |\n| ≤7 天 | info | `{label} {n} 天前同步` |\n| ≤30 天 | warning | `{label} 导出已 {n} 天 — 需要刷新？` |\n| >30 天 | error | `{label} 导出已 {n} 天 — 数据可能已过时` |\n\n### 联系人数据置信度\n\n根据来源新鲜度计算联系人数据置信级别：\n\n| 级别 | 条件 |\n|------|------|\n| high | 有活跃交互且来源新鲜 |\n| medium | 有交互但部分来源陈旧 |\n| low | 无交互或无来源数据 |\n\n资料来源：[crm/staleness.js](https://github.com/sree-sanak/minty/blob/main/crm/staleness.js)\n\n## AI 后端架构\n\nMinty 刻意避免运行时 LLM 费用，支持两种本地后端：\n\n| 后端 | 配置 | 说明 |\n|------|------|------|\n| **Claude Code CLI** | 默认（无配置） | 调用 `claude --print`，已登录用户免费使用 |\n| **Ollama** | `AI_BACKEND=ollama` | 完全离线，支持 qwen2.5:7b 等本地模型 |\n\nAI 输出（洞察、摘要、重新联系草稿、查询排名）预计算并缓存于 `data/unified/*.json`，Web 服务器读取这些静态文件。资料来源：[README.md](https://github.com/sree-sanak/minty/blob/main/README.md)\n\n## MCP 集成（Hermes）\n\nMinty 提供 MCP（Model Context Protocol）服务器供 AI Agent 使用，位于 `scripts/minty-mcp-server.js`：\n\n| 工具 | 功能 |\n|------|------|\n| `search_network` | 自然语言网络搜索 |\n| `person_context` | 查询特定联系人详情 |\n| `workflow_brief` | 生成目标导向简报 |\n| `source_health` | 检查数据源健康状态 |\n\n```javascript\n// 使用示例\n{\n  \"query\": \"investors in London who know about AI\",\n  \"limit\": 5\n}\n```\n\nMinty 与 Hermes 集成的就绪级别：\n\n| 级别 | 要求 |\n|------|------|\n| Demo-ready | `npm run seed:demo` + `npm run mcp` 可用 |\n| Dogfood-ready | `npm run memory:refresh` 成功，无直接联系方式输出 |\n| Hermes-native | 技能已安装，MCP 服务器已注册 |\n\n资料来源：[hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md)\n\n## 性能优化要点\n\n大数据集场景下的性能瓶颈通常在合并路径，优化策略：\n\n| 场景 | 建议 |\n|------|------|\n| 大量联系人 | 优化 `crm/merge.js` 中的去重算法 |\n| 跨源匹配 | 改进 `crm/match.js` 的 MATCHING.md 规则 |\n| UI 响应 | 缓存预计算的 AI 输出 |\n| 测试 | 使用 `tests/integration/` 的 fixture 性能测试 |\n\n资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n## 贡献指南\n\n### 开发环境启动\n\n```bash\nnpm run crm        # 启动 CRM 服务器（热重载）\nnpm run seed:demo  # 生成演示数据\nnpm run test       # 运行测试套件\n```\n\n### 代码修改优先级\n\n1. **修改数据模型** → 首先编辑 `schema.js`\n2. **添加新导入器** → 复制 `sources/telegram/import.js` 模板\n3. **改进匹配算法** → 编辑 `crm/match.js`，添加 `tests/` fixture\n4. **UI 工作** → 编辑 `crm/ui.html.js` 和 `crm/server.js`\n\n资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n---\n\n<a id='page-ai-backend'></a>\n\n## AI 后端配置\n\n### 相关页面\n\n相关主题：[架构总览](#page-architecture-overview), [网络查询系统](#page-network-query)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md) — 项目架构总览\n- [crm/server.js](https://github.com/sree-sanak/minty/blob/main/crm/server.js) — 服务器端实现\n- [hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md) — 网络记忆技能配置\n- [crm/agent-source-health.js](https://github.com/sree-sanak/minty/blob/main/crm/agent-source-health.js) — 数据源健康检查\n- [sources/_shared/progress.js](https://github.com/sree-sanak/minty/blob/main/sources/_shared/progress.js) — 导入进度追踪\n- [crm/staleness.js](https://github.com/sree-sanak/minty/blob/main/crm/staleness.js) — 数据新鲜度检测\n\n> 注：本页所需的部分文件（如 `crm/digest.js`、`crm/evidence-patches.js`、`.env.example`）在当前检索上下文中未找到，以下内容基于已获取的源码片段进行概述。\n\n</details>\n\n# AI 后端配置\n\n## 概述\n\nMinty 项目采用**本地优先的 AI 策略**，不依赖任何云端 API 服务。AI 功能通过 `crm/ai.js` 模块实现，该模块作为适配器，同时支持 **Claude Code CLI** 和 **Ollama** 两种本地推理引擎。\n\n资料来源：[ARCHITECTURE.md]()\n\n## 架构设计\n\n### AI 适配器架构\n\n```mermaid\ngraph TD\n    A[用户请求] --> B[crm/server.js]\n    B --> C{AI 引擎选择}\n    C -->|Claude Code CLI| D[claude-code-adapter]\n    C -->|Ollama| E[ollama-adapter]\n    D --> F[本地 Claude Code 进程]\n    E --> G[本地 Ollama 服务]\n    F --> H[结构化响应]\n    G --> H\n    H --> I[UI 层渲染]\n```\n\n资料来源：[ARCHITECTURE.md]()\n\n### 设计原则\n\n| 原则 | 说明 |\n|------|------|\n| **本地化** | 所有 AI 推理在本地执行，无云端数据传输 |\n| **隐私优先** | 联系人数据和交互内容不离开用户设备 |\n| **离线可用** | 依赖 Ollama 或 Claude Code CLI 的本地安装 |\n| **无供应商锁定** | 支持切换不同的本地推理引擎 |\n\n资料来源：[ARCHITECTURE.md]()\n\n## MCP 工具集成\n\n### 网络记忆工具\n\nMinty 通过 MCP（Model Context Protocol）暴露网络记忆能力，供 AI Agent 调用：\n\n```json\n{\n  \"tools\": {\n    \"search_network\": \"自然语言搜索联系人\",\n    \"person_context\": \"查询特定人物的关系上下文\",\n    \"workflow_brief\": \"生成目标导向的人物简报\",\n    \"source_health\": \"检查数据源健康状态\"\n  }\n}\n```\n\n资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n### 工具调用示例\n\n```json\n// 搜索网络\n{ \"query\": \"investors in London who know about AI\", \"limit\": 5 }\n\n// 人物上下文查询\n{ \"person\": \"Alice Müller\", \"limit\": 3 }\n\n// 目标简报生成\n{ \"goal\": \"Find EU crypto insurance distribution partners\", \"limit\": 5 }\n\n// 数据源健康检查\n{ \"source\": \"telegram\" }\n```\n\n资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n## 数据源健康检查\n\n### 健康状态等级\n\nAI 后端在执行查询前会评估数据源的可信度：\n\n| 状态 | 描述 | AI 可用性 |\n|------|------|----------|\n| `ready` | 数据源正常、可回答问题 | ✅ 可用 |\n| `stale` | 数据较旧（超过 7 天未同步） | ⚠️ 有限可用 |\n| `limited` | 存在警告（无联系人、无证据等） | ⚠️ 有限可用 |\n| `blocked` | 显式请求不可用的数据源 | ❌ 不可用 |\n| `error` | 同步错误 | ❌ 不可用 |\n\n资料来源：[crm/agent-source-health.js]()\n\n### 健康检查流程\n\n```mermaid\ngraph TD\n    A[接收源过滤请求] --> B[验证源标识符]\n    B --> C{源有效?}\n    C -->|否| D[标记 invalid_source]\n    C -->|是| E[遍历每个数据源]\n    E --> F[统计联系人数]\n    F --> G[统计交互记录数]\n    G --> H[获取最后同步时间]\n    H --> I{新鲜度判断}\n    I -->|fresh| J[status: ready]\n    I -->|stale| K[status: stale]\n    I -->|unknown| L[status: limited]\n    J --> M[生成警告列表]\n    K --> M\n    L --> M\n    D --> M\n    M --> N[返回 answerable 状态]\n```\n\n资料来源：[crm/agent-source-health.js]()\n\n## 导入进度追踪\n\nAI 功能依赖高质量的数据导入，进度系统为导入过程提供实时反馈：\n\n### 进度状态模型\n\n```javascript\n{\n    source: String,           // 数据源标识符\n    step: String,             // 当前步骤\n    message: String,          // 人类可读消息\n    current: Number,          // 当前处理项\n    total: Number,            // 总项数\n    itemsProcessed: Number,   // 已处理项数\n    errors: Array,            // 错误列表\n    startedAt: ISO8601,       // 开始时间\n    updatedAt: ISO8601        // 更新时间\n}\n```\n\n资料来源：[sources/_shared/progress.js]()\n\n### API 端点\n\n| 端点 | 方法 | 描述 |\n|------|------|------|\n| `/api/sources/:key/progress` | GET | 获取指定数据源的导入进度 |\n| `/api/sync/progress` | GET | 获取所有数据源的同步进度 |\n\n资料来源：[ARCHITECTURE.md]()\n\n## 数据新鲜度检测\n\n### 新鲜度阈值\n\n| 条件 | 状态 | 阈值 |\n|------|------|------|\n| 24 小时内同步 | 新鲜 | `fresh` |\n| 7 天内同步 | 可接受 | `stale` |\n| 超过 7 天 | 过期 | `outdated` |\n\n资料来源：[crm/staleness.js]()\n\n### 警告消息示例\n\n```javascript\n\"Google Contacts  export is 14 days old — data may be outdated\"\n\"Telegram has never synced\"\n\"LinkedIn synced today\"\n```\n\n资料来源：[crm/staleness.js]()\n\n## 摘要生成与目标回顾\n\n### 每周摘要功能\n\n服务器端 `handleGetDigest` 处理器读取预生成的摘要文件：\n\n```javascript\nfunction handleGetDigest(req, res, params, paths) {\n    try { json(res, JSON.parse(fs.readFileSync(paths.digest, 'utf8'))); }\n    catch { json(res, null); }\n}\n```\n\n资料来源：[crm/server.js]()\n\n### 目标关联人物排名\n\nAI 系统根据目标关键词对联系人进行相关性排序：\n\n```javascript\ngoalSections = goals.map(goal => {\n    const ranked = rankContactsForGoal(contacts, goal.text, 5);\n    return {\n        goalId: goal.id,\n        goalText: goal.text,\n        contacts: ranked.map(c => ({\n            id: c.id,\n            name: c.name,\n            company: c.sources?.linkedin?.company || null,\n            goalRelevance: c.goalRelevance,\n            meetingBrief: ins ? ins.meetingBrief : null,\n        }))\n    };\n});\n```\n\n资料来源：[crm/server.js]()\n\n## 敏感信息保护\n\n### 数据脱敏机制\n\n进度追踪模块内置敏感信息过滤：\n\n```javascript\nfunction redactErrorText(value) {\n    return String(value)\n        .replace(/^\\s*at\\s+[^\\n]+/gm, '[redacted-stack]')\n        .replace(/([\"'`])[^\"'`\\n]*[\\\\/][^\"'`\\n]*\\1/g, '$1[redacted-path]$1')\n        .replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}/gi, '[redacted-email]')\n        .replace(/\\bauthorization\\s*[:=]\\s*Bearer\\s+[^\\s,;]+/gi, '[redacted-credential]')\n        // ... 更多脱敏规则\n}\n```\n\n资料来源：[sources/_shared/progress.js]()\n\n### 脱敏规则表\n\n| 模式 | 替换结果 |\n|------|----------|\n| 邮箱地址 | `[redacted-email]` |\n| Bearer 令牌 | `Bearer [redacted-credential]` |\n| API 密钥 | `[redacted-credential]` |\n| 文件路径 | `[redacted-path]` |\n| 堆栈跟踪 | `[redacted-stack]` |\n\n资料来源：[sources/_shared/progress.js]()\n\n## 快速开始\n\n### 前置要求\n\n1. 安装 **Node.js 20+**\n2. 安装 **Claude Code CLI** 或 **Ollama**\n3. 配置数据源导入\n\n### 验证 AI 配置\n\n```bash\n# 启动 MCP 服务器\nnpm run mcp\n\n# 验证网络记忆功能\nnpm run agent -- \"investors in London\"\n```\n\n资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n## 故障排查\n\n| 问题 | 可能原因 | 解决方案 |\n|------|----------|----------|\n| AI 返回空结果 | 数据源未同步 | 运行 `npm run sync` |\n| 源健康检查失败 | 缺少数据源配置 | 检查 `.env` 配置 |\n| 连接超时 | Ollama 服务未启动 | 启动 `ollama serve` |\n| 权限错误 | Claude Code CLI 未授权 | 运行 `claude` 完成认证 |\n\n## 相关文档\n\n- [架构总览](./ARCHITECTURE.md)\n- [数据源导入](./SOURCES.md)\n- [匹配算法](./MATCHING.md)\n- [发布流程](./RELEASING.md)\n\n---\n\n<a id='page-data-sources'></a>\n\n## 数据源导入\n\n### 相关页面\n\n相关主题：[联系人合并与去重](#page-contact-merging), [数据存储结构](#page-data-storage), [快速开始](#page-quick-start)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [sources/whatsapp/export.js](https://github.com/sree-sanak/minty/blob/main/sources/whatsapp/export.js)\n- [sources/linkedin/import.js](https://github.com/sree-sanak/minty/blob/main/sources/linkedin/import.js)\n- [sources/telegram/import.js](https://github.com/sree-sanak/minty/blob/main/sources/telegram/import.js)\n- [sources/email/import.js](https://github.com/sree-sanak/minty/blob/main/sources/email/import.js)\n- [sources/google-contacts/import.js](https://github.com/sree-sanak/minty/blob/main/sources/google-contacts/import.js)\n- [sources/sms/import.js](https://github.com/sree-sanak/minty/blob/main/sources/sms/import.js)\n- [sources/_shared/progress.js](https://github.com/sree-sanak/minty/blob/main/sources/_shared/progress.js)\n</details>\n\n# 数据源导入\n\n数据源导入是 Minty CRM 的核心功能模块，负责从多种外部平台收集联系人信息和交互记录。每个数据源（Source）都是独立的导入单元，遵循统一的数据写入规范，最终输出到 `data/<source>/` 目录下的结构化 JSON 文件。\n\n## 系统架构\n\n### 导入器层级结构\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                    sources/ 目录结构                          │\n├─────────────────────────────────────────────────────────────┤\n│  whatsapp/export.js        实时 Web 端导入                   │\n│  linkedin/import.js        LinkedIn ZIP 压缩包导入           │\n│  linkedin/connect.js        LinkedIn 自动同步（实验性）        │\n│  telegram/import.js        Telegram JSON 导出导入             │\n│  email/import.js            Gmail/IMAP 邮件导入               │\n│  google-contacts/import.js Google 通讯录 OAuth 导入           │\n│  sms/import.js              短信平台导出导入                  │\n│  apollo/enrich.js           Apollo 联系人丰富化（可选）        │\n├─────────────────────────────────────────────────────────────┤\n│  _shared/progress.js       统一的进度追踪模块                │\n└─────────────────────────────────────────────────────────────┘\n```\n\n所有导入器共享 `sources/_shared/progress.js` 中的进度追踪机制，确保 UI 层能够统一展示各数据源的同步状态。\n\n资料来源：[ARCHITECTURE.md]()\n\n### 数据流向\n\n```mermaid\ngraph TD\n    A[用户启动导入器] --> B[数据源平台]\n    B --> C[源数据获取]\n    C --> D[数据解析与标准化]\n    D --> E[data/&lt;source&gt;/]\n    E --> F[crm/merge.js]\n    F --> G[data/unified/]\n    G --> H[统一联系人视图]\n    G --> I[交互时间线]\n```\n\n资料来源：[ARCHITECTURE.md]()\n\n## 支持的数据源\n\n| 数据源 | 导入模式 | 认证方式 | 增量支持 | 入口命令 |\n|--------|----------|----------|----------|----------|\n| WhatsApp | 实时监听 | QR 码配对 | ✅ | `npm run whatsapp` |\n| LinkedIn | 一次性 | 官方数据导出 ZIP | ❌ | `npm run linkedin` |\n| LinkedIn Sync | 实验性 | 自动化登录 | ✅ | `npm run linkedin:connect` |\n| Telegram | 一次性 | 官方 JSON 导出 | ❌ | `npm run telegram` |\n| Email/Gmail | 增量 | OAuth 2.0 / IMAP | ✅ | OAuth 流程 |\n| Google Contacts | 增量 | OAuth 2.0 | ✅ | OAuth 流程 |\n| SMS | 一次性 | 平台导出格式 | ❌ | `npm run sms` |\n| Apollo | 可选 | API 密钥 | - | 手动触发 |\n\n资料来源：[ARCHITECTURE.md]()\n\n## 进度追踪机制\n\n### 统一进度文件\n\n每个导入器在运行时会向其数据目录写入 `.progress.json` 文件，记录当前导入进度。\n\n```json\n{\n  \"source\": \"whatsapp\",\n  \"step\": \"messages\",\n  \"message\": \"正在同步 15/32: 产品团队群\",\n  \"current\": 15,\n  \"total\": 32,\n  \"itemsProcessed\": 2847,\n  \"startedAt\": \"2025-01-15T10:30:00.000Z\",\n  \"updatedAt\": \"2025-01-15T10:35:22.456Z\"\n}\n```\n\n资料来源：[sources/_shared/progress.js:1-80]()\n\n### 进度步骤定义\n\n| step 值 | 含义 | 典型 message 示例 |\n|---------|------|---------------------|\n| `init` | 初始化 | \"Starting…\" |\n| `contacts` | 正在同步联系人 | \"Loading contacts…\" |\n| `messages` | 正在同步消息/交互 | \"Syncing 15/32: 群组名\" |\n| `merging` | 合并到统一存储 | \"Merging into unified store\" |\n| `done` | 完成 | \"Import complete\" |\n| `error` | 错误 | 错误信息摘要 |\n\n资料来源：[sources/_shared/progress.js:50-70]()\n\n### 进度状态计算\n\n进度文件中的 `active` 状态由 `step !== 'done' && step !== 'error'` 派生而来，用于前端判断同步是否仍在进行中。\n\n## WhatsApp 导入\n\nWhatsApp 导入器是唯一采用实时监听模式的源，使用 `whatsapp-web.js` 库通过 WebSocket 连接手机端应用。\n\n### 核心流程\n\n1. **首次运行**：显示 QR 码，用户需在 WhatsApp 手机端扫描\n2. **会话恢复**：后续运行自动复用已存储的会话凭证\n3. **增量同步**：仅拉取上次同步后的新消息\n\n```javascript\n// 关键参数\nWHATSAPP_MSG_LIMIT=500  // 单次最多获取消息数（环境变量）\n```\n\n资料来源：[crm/server.js:150-180]()\n\n### 输出文件结构\n\n```\ndata/whatsapp/\n├── chats.json        // 聊天列表元数据\n├── contacts.json     // 联系人信息\n├── metadata.json     // 同步会话信息\n├── profile_pics/     // 头像缓存目录\n└── .progress.json    // 进度文件\n```\n\n## LinkedIn 导入\n\n### ZIP 导出模式\n\n1. 用户在 LinkedIn 网站请求数据导出（Settings → Data Privacy → Get a copy of your data）\n2. 选择 **Connections** 和 **Messages** 选项\n3. 下载 ZIP 文件后拖入 Sources 视图，或指定目录：\n\n```bash\nLINKEDIN_EXPORT_DIR=/path/to/extracted npm run linkedin\n```\n\n### 自动同步模式（实验性）\n\n该模式通过自动化浏览器操作实现 ToS 边界附近的登录抓取：\n\n- 使用 headful 浏览器首次登录获取凭证\n- 凭证缓存后以 headless 模式复用\n- 状态存储在 `data/linkedin/` 目录\n\n资料来源：[ARCHITECTURE.md]()\n\n## Telegram 导入\n\nTelegram 导出采用官方 Desktop 客户端的 JSON 格式。\n\n### 导出步骤\n\n1. Telegram Desktop → Settings → Advanced → Export Telegram Data\n2. 选择 **Personal chats** 和 **Contacts**\n3. 格式选择 **JSON**\n4. 将 `result.json` 放入 Sources 视图\n\n```bash\nTELEGRAM_EXPORT_FILE=/path/to/result.json npm run telegram\n```\n\n### 解析能力\n\n- 个人聊天记录\n- 群组消息（含参与者列表）\n- 联系人信息\n\n## Email/Gmail 导入\n\n### OAuth 认证流程（推荐）\n\n1. 用户在 Sources 视图点击 \"Connect Gmail\"\n2. 使用 Google OAuth Device Flow 完成授权\n3. 权限范围为只读访问\n\n需要配置以下环境变量：\n\n```\nGOOGLE_CLIENT_ID=<your-client-id>\nGOOGLE_CLIENT_SECRET=<your-client-secret>\n```\n\n### IMAP 备选方案\n\n支持任意提供商的 IMAP 协议：\n\n```bash\nEMAIL_HOST=imap.gmail.com\nEMAIL_PORT=993\nEMAIL_USER=your-email@gmail.com\nEMAIL_PASS=app-password\n```\n\n## Google Contacts 导入\n\n通过 Google People API 进行 OAuth 增量同步，自动获取用户通讯录中的：\n\n- 姓名\n- 电话号码\n- 邮箱地址\n- 组织信息（公司、职位）\n- 地址信息\n\n## SMS 导入\n\nSMS 导入器解析平台导出的 XML 格式数据，支持：\n\n- 普通短信（SMS）\n- 多媒体消息（MMS）\n- 通话记录（Call Log）\n\n### 解析数据类型\n\n| 类型 | 字段 | 说明 |\n|------|------|------|\n| SMS/MMS | `body`, `direction`, `timestamp` | 消息内容和方向 |\n| MMS | `hasMedia`, `contactName` | 含媒体标识 |\n| Call Log | `callKind`, `duration` | 通话类型和时长 |\n\n资料来源：[sources/sms/import.js:60-100]()\n\n## Apollo 联系人丰富化\n\nApollo 是一个可选的付费数据丰富服务，用于增强现有联系人的公开信息：\n\n- 公司位置\n- 职业头衔\n- Twitter 链接\n- 职业履历\n\n此模块独立于主导入流程，需手动触发：\n\n```bash\nnode sources/apollo/enrich.js\n```\n\n## 数据合并\n\n### merge.js 核心职责\n\n所有导入器完成后，运行 `crm/merge.js` 执行统一合并：\n\n1. **数据标准化**：统一电话、邮箱、姓名的格式\n2. **跨源去重**：识别同一人的不同来源记录\n3. **构建交互时间线**：聚合所有源的交互事件\n\n```bash\nnode crm/merge.js\n```\n\n### 输出文件\n\n```\ndata/unified/\n├── contacts.json          // 统一联系人记录\n├── interactions.json      // 聚合交互事件\n├── match_overrides.json   // 手动匹配覆盖\n└── group-memberships.json  // 群组关系\n```\n\n资料来源：[ARCHITECTURE.md]()\n\n## 环境变量配置\n\n| 变量名 | 适用源 | 用途 |\n|--------|--------|------|\n| `CRM_DATA_DIR` | 全局 | 数据根目录 |\n| `WHATSAPP_MSG_LIMIT` | WhatsApp | 单次消息拉取上限 |\n| `LINKEDIN_EXPORT_DIR` | LinkedIn | ZIP 解压路径 |\n| `TELEGRAM_EXPORT_FILE` | Telegram | JSON 导出文件路径 |\n| `GOOGLE_CLIENT_ID` | Gmail/Contacts | OAuth 客户端 ID |\n| `EMAIL_*` | Email | IMAP 连接参数 |\n\n## 命令速查\n\n| 命令 | 功能 |\n|------|------|\n| `npm run whatsapp` | 启动 WhatsApp 导入器 |\n| `npm run linkedin` | 启动 LinkedIn ZIP 导入器 |\n| `npm run telegram` | 启动 Telegram 导入器 |\n| `npm run sms` | 启动 SMS 导入器 |\n| `npm run crm` | 启动 CRM 服务端（含同步 API） |\n\n## 贡献指南\n\n### 添加新导入器\n\n1. 复制现有简单导入器作为模板（如 `sources/telegram/import.js`）\n2. 遵循目录结构：`data/<source>/` 写入 JSON 文件\n3. 使用 `sources/_shared/progress.js` 报告进度\n4. 在 `crm/merge.js` 中添加对应的合并逻辑\n\n资料来源：[ARCHITECTURE.md]()\n\n### 性能优化\n\n当数据集较大时，合并路径通常是性能瓶颈。建议使用 `tests/integration/` 中的基于 fixture 的性能测试进行验证。\n\n---\n\n<a id='page-contact-merging'></a>\n\n## 联系人合并与去重\n\n### 相关页面\n\n相关主题：[数据源导入](#page-data-sources), [数据存储结构](#page-data-storage)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [crm/match.js](https://github.com/sree-sanak/minty/blob/main/crm/match.js)\n- [crm/merge.js](https://github.com/sree-sanak/minty/blob/main/crm/merge.js)\n- [crm/identity-candidates.js](https://github.com/sree-sanak/minty/blob/main/crm/identity-candidates.js)\n- [crm/MATCHING.md](https://github.com/sree-sanak/minty/blob/main/crm/MATCHING.md)\n- [crm/schema.js](https://github.com/sree-sanak/minty/blob/main/crm/schema.js)\n- [sources/_shared/progress.js](https://github.com/sree-sanak/minty/blob/main/sources/_shared/progress.js)\n</details>\n\n# 联系人合并与去重\n\n## 概述\n\n联系人合并与去重是 Minty CRM 的核心功能之一，负责将来自不同数据源（如 Email、LinkedIn、Telegram、Google Contacts 等）的联系人记录整合为统一视图。当用户从多个平台导入数据时，同一个人可能在不同来源中以不同的名字、电话或邮箱形式出现，合并系统通过智能匹配算法识别这些重复记录并将其合并，同时保留各来源的原始信息。\n\n该模块在架构中处于数据处理的核心位置——所有数据源的导入完成后，最终都会经过合并流程生成 `data/unified/contacts.json` 和 `data/unified/interactions.json`，为上层业务功能（如目标追踪、会议总结、人生事件识别）提供统一的联系人数据源。资料来源：[ARCHITECTURE.md]()\n\n## 核心组件\n\nMinty 的联系人合并与去重系统由以下几个核心文件组成：\n\n| 组件文件 | 职责 | 关键功能 |\n|---------|------|---------|\n| `crm/merge.js` | 数据合并主入口 | 加载各源数据、规范化、写入统一存储 |\n| `crm/match.js` | 跨源匹配算法 | 根据规则识别潜在重复联系人 |\n| `crm/identity-candidates.js` | 身份候选生成 | 生成待匹配的联系人候选对 |\n| `crm/MATCHING.md` | 匹配规则规范文档 | 定义匹配逻辑与置信度标准 |\n| `crm/schema.js` | 数据模型定义 | 规范 Contact 和 Interaction 的数据结构 |\n\n资料来源：[ARCHITECTURE.md]()\n\n## 数据流架构\n\n```mermaid\ngraph TD\n    A[数据源导入] --> B[sources/email/import.js]\n    A --> C[sources/linkedin/import.js]\n    A --> D[sources/telegram/import.js]\n    A --> E[sources/google-contacts/import.js]\n    \n    B --> F[data/&lt;source&gt;/]\n    C --> F\n    D --> F\n    E --> F\n    \n    F --> G[crm/merge.js]\n    G --> H[match.js 匹配算法]\n    H --> I[match_overrides.json 人工干预]\n    I --> G\n    \n    G --> J[data/unified/contacts.json]\n    G --> K[data/unified/interactions.json]\n    \n    J --> L[上层业务功能]\n    K --> L\n    \n    L --> M[calendar.js 会议追踪]\n    L --> N[goal-retro.js 目标回顾]\n    L --> O[life-events.js 人生事件]\n    L --> P[digest.js 周报摘要]\n```\n\n## 数据模型\n\n### Contact 统一数据结构\n\n合并后的联系人记录包含以下核心字段：\n\n```javascript\n{\n  id: string,                    // 唯一标识符\n  name: string,                  // 规范化的姓名\n  phones: string[],              // 电话号码数组\n  emails: string[],              // 邮箱数组\n  sources: {                     // 各来源的原始数据\n    [sourceName]: {\n      name?: string,\n      phones?: string[],\n      emails?: string[],\n      company?: string,\n      position?: string,\n      // ... 其他来源特定字段\n    }\n  },\n  relationshipScore: number,      // 关系评分 0-100\n  daysSinceContact: number,       // 最后联系天数\n  activeChannels: string[],      // 活跃联系方式\n  interactionCount: number       // 交互次数\n}\n```\n\n资料来源：[crm/schema.js]()\n\n### Interaction 交互记录结构\n\n```javascript\n{\n  id: string,\n  contactId: string,\n  source: string,\n  timestamp: string,\n  type: 'message' | 'meeting' | 'call' | 'email',\n  subject?: string,\n  body?: string,\n  participants?: string[]\n}\n```\n\n## 匹配算法详解\n\n### 匹配置信度等级\n\n系统采用三级置信度体系判断两个联系人记录是否指向同一人：\n\n| 置信度 | 说明 | 处理方式 | 资料来源 |\n|--------|------|---------|---------|\n| **confirmed** | 多个高置信度信号完全吻合 | 自动合并，无需人工确认 | [crm/MATCHING.md]() |\n| **likely** | 存在多个支持信号，证据充分 | 自动合并，打印统计信息 | [crm/MATCHING.md]() |\n| **possible** | 存在一些匹配信号但不够确定 | 跳过合并，列入待审查列表 | [crm/MATCHING.md]() |\n\n### 匹配信号类型\n\n匹配算法考察以下信号维度：\n\n**强信号（权重高）：**\n- 邮箱地址完全匹配\n- 电话号码完全匹配\n- 多个联系方式组合匹配\n\n**中强信号（权重中）：**\n- 姓名相似度（编辑距离）\n- 公司名称匹配\n- LinkedIn 个人资料 URL 匹配\n\n**辅助信号（权重低）：**\n- 地理位置一致性\n- 职业/职位相似度\n- 共同交互事件\n\n### 匹配输出示例\n\n```json\n[\n  {\n    \"confidence\": \"confirmed\",\n    \"ids\": [\"c_0001\", \"c_0012\"],\n    \"reason\": \"邮箱地址完全一致\",\n    \"sources_linked\": [\"email\", \"linkedin\"]\n  },\n  {\n    \"confidence\": \"likely\",\n    \"ids\": [\"c_0003\", \"c_0088\"],\n    \"reason\": \"姓名完全匹配，公司一致，LinkedIn 位置匹配\",\n    \"sources_linked\": [\"whatsapp\", \"linkedin\"]\n  },\n  {\n    \"confidence\": \"possible\",\n    \"ids\": [\"c_0105\", \"c_2341\"],\n    \"reason\": \"名字匹配但该名字非常常见；缺少其他佐证信号\",\n    \"sources_linked\": [\"whatsapp\", \"linkedin\"]\n  }\n]\n```\n\n资料来源：[crm/MATCHING.md]()\n\n## 合并流程\n\n### 标准合并流程\n\n```mermaid\ngraph LR\n    A[运行各数据源导入器] --> B[npm run email<br/>npm run telegram<br/>npm run linkedin]\n    \n    B --> C[生成各源原始数据]\n    C --> D[运行 merge.js]\n    \n    D --> E{存在 match_overrides?}\n    E -->|是| F[加载人工干预配置]\n    E -->|否| G[跳过覆盖加载]\n    \n    F --> H[按 confirmed/likely<br/>强制合并指定记录]\n    G --> I[执行匹配算法]\n    \n    H --> J[生成统一联系人列表]\n    I --> J\n    \n    J --> K[写入 unified/contacts.json]\n    J --> L[写入 unified/interactions.json]\n    \n    K --> M[生成匹配统计报告]\n    L --> M\n```\n\n### 关键配置：match_overrides.json\n\n当自动匹配算法无法准确判断，或用户希望手动指定某些记录的合并关系时，可通过 `match_overrides.json` 进行干预：\n\n```json\n{\n  \"confirmed\": [\n    { \"ids\": [\"c_0001\", \"c_0012\"], \"reason\": \"用户确认为同一人\" }\n  ],\n  \"likely\": [\n    { \"ids\": [\"c_0003\", \"c_0088\"], \"reason\": \"邮箱前缀相同且公司一致\" }\n  ],\n  \"possible\": [\n    { \"ids\": [\"c_0105\", \"c_2341\"], \"reason\": \"待进一步核实\" }\n  ]\n}\n```\n\n**覆盖规则处理逻辑：**\n\n| 覆盖类型 | 算法行为 |\n|---------|---------|\n| confirmed | 无论算法结果如何，强制将两条记录合并为同一联系人 |\n| likely | 将两条记录合并，但在统计报告中标注为\"人工确认\" |\n| possible | 跳过自动合并，标记为需人工审查（通过 `npm run review`） |\n\n资料来源：[crm/MATCHING.md]()\n\n## 合并执行命令\n\n### 基本合并命令\n\n```bash\n# 标准合并流程\nnode crm/merge.js\n\n# 带详细输出\nnpm run merge\n\n# 仅检查匹配状态（不写入）\nnpm run match:dry-run\n```\n\n### 完整导入与合并流程\n\n```bash\n# 1. 导入各数据源\nnpm run email          # 导入 Email 数据\nnpm run telegram       # 导入 Telegram 数据\nnpm run linkedin       # 导入 LinkedIn 数据\n\n# 2. 执行合并\nnode crm/merge.js\n\n# 3. 查看统计\nnpm run stats\n```\n\n### 审查待定匹配\n\n对于置信度为 \"possible\" 的匹配记录，系统提供交互式审查界面：\n\n```bash\nnpm run review\n```\n\n该命令会列出所有待审查的匹配对，用户可选择确认或拒绝每一条匹配。\n\n资料来源：[crm/MATCHING.md]()\n\n## 匹配状态管理\n\n### 进度追踪\n\n合并过程中，系统会通过 `sources/_shared/progress.js` 模块追踪处理进度：\n\n```javascript\nP.startProgress(DATA_DIR, 'merge', { step: 'init', message: '开始合并…' });\nP.updateProgress(DATA_DIR, 'merge', { step: 'matching', message: '执行匹配…', current: 5, total: 10 });\nP.updateProgress(DATA_DIR, 'merge', { step: 'merging', message: '合并记录…' });\n```\n\n进度文件存储在 `data/.progress/merge.json`，包含以下字段：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| step | string | 当前处理阶段 |\n| message | string | 状态消息 |\n| current | number | 当前进度 |\n| total | number | 总任务数 |\n| startedAt | string | ISO 时间戳 |\n| updatedAt | string | ISO 时间戳 |\n| errors | array | 错误列表 |\n\n### 错误处理\n\n系统内置敏感信息过滤机制，防止在错误日志中泄露凭据或个人信息：\n\n```javascript\nfunction redactErrorText(value) {\n    return String(value)\n        .replace(/^\\s*at\\s+[^\\n]+/gm, '[redacted-stack]')\n        .replace(/([\"'`])[^\"'`\\n]*[\\\\/][^\"'`\\n]*\\1/g, '$1[redacted-path]$1')\n        .replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}/gi, '[redacted-email]')\n        .replace(/\\bauthorization\\s*[:=]\\s*Bearer\\s+[^\\s,;]+/gi, '[redacted-credential]');\n}\n```\n\n资料来源：[sources/_shared/progress.js]()\n\n## 数据新鲜度与置信度\n\n### 联系人数据置信度评估\n\n系统会根据数据来源和最后同步时间计算每条联系人的数据置信度：\n\n| 置信度等级 | 条件 | 说明 |\n|-----------|------|------|\n| high | 多个活跃来源 + 最近同步 | 数据完整可靠 |\n| medium | 单个活跃来源 + 最近同步 | 基本可靠 |\n| low | 无交互记录或数据过旧 | 需手动核实 |\n\n```javascript\nfunction getContactDataConfidence(contact, syncState, now = Date.now()) {\n    const activeSources = Object.keys(contact.sources || {}).filter(s => contact.sources[s]);\n    if (activeSources.length === 0) return { level: 'low', reason: '无来源数据' };\n    // ... 更多评估逻辑\n}\n```\n\n资料来源：[crm/staleness.js]()\n\n### 陈旧数据警告\n\n系统会自动检测数据新鲜度并生成警告：\n\n| 同步状态 | 警告级别 | 用户提示 |\n|---------|---------|---------|\n| 同步中 | - | - |\n| 同步成功（< 24h） | - | \"数据最新\" |\n| 同步成功（1-3天） | warning | \"数据可能略旧\" |\n| 同步成功（> 3天） | error | \"数据可能过时\" |\n| 同步错误 | error | \"同步失败，请检查配置\" |\n\n## 扩展开发指南\n\n### 添加新的数据源导入器\n\n参考 `sources/telegram/import.js` 的文件结构：\n\n1. 创建 `sources/<new-source>/import.js`\n2. 实现数据抓取和标准化逻辑\n3. 写入 `data/<new-source>/contacts.json`\n4. 更新 `crm/merge.js` 添加新数据源加载\n5. 更新 `crm/match.js` 添加新源的匹配规则\n\n### 自定义匹配规则\n\n在 `crm/match.js` 中添加新的匹配信号检测：\n\n```javascript\n// 示例：添加公司域名匹配\nfunction matchByEmailDomain(contactA, contactB) {\n    const domainsA = contactA.emails.map(e => e.split('@')[1]);\n    const domainsB = contactB.emails.map(e => e.split('@')[1]);\n    return domainsA.some(d => domainsB.includes(d));\n}\n```\n\n### 添加测试用例\n\n在 `tests/` 目录创建匹配测试：\n\n```bash\n# 运行匹配相关测试\nnpm test -- --grep \"match\"\n\n# 添加新测试文件\n# tests/match.test.js\n```\n\n## 常见问题排查\n\n### 合并后联系人数量异常减少\n\n**可能原因：**\n- 匹配规则过于激进，将不应合并的记录错误合并\n- match_overrides.json 中存在误配置\n\n**解决方案：**\n1. 检查 `data/unified/` 中的合并结果\n2. 审阅 `match_overrides.json` 配置\n3. 使用 `npm run review` 重新审查匹配决策\n\n### 预期匹配未被识别\n\n**可能原因：**\n- 数据源格式不规范（如姓名包含特殊字符）\n- 缺少共同信号（如双方从未通过邮件交互）\n\n**解决方案：**\n1. 规范化导入数据\n2. 在 match_overrides.json 中添加 confirmed 覆盖\n3. 手动审查 possible 匹配队列\n\n### 数据新鲜度显示错误\n\n**可能原因：**\n- 同步状态文件格式不一致\n- 未正确写入 lastSyncAt 字段\n\n**解决方案：**\n1. 检查 `data/unified/sync-state.json`\n2. 确保各导入器正确更新同步状态\n3. 查看 `crm/agent-source-health.js` 诊断输出\n\n## 相关文档\n\n- [匹配规范文档](./MATCHING.md) - 匹配算法的完整技术规范\n- [架构概述](./ARCHITECTURE.md) - 项目整体架构说明\n- [数据源导入器](../sources/) - 各数据源导入实现详情\n- [同步系统](./sync.js) - 自动化数据同步机制\n\n---\n\n<a id='page-data-storage'></a>\n\n## 数据存储结构\n\n### 相关页面\n\n相关主题：[联系人合并与去重](#page-contact-merging), [架构总览](#page-architecture-overview)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [crm/export.js](https://github.com/sree-sanak/minty/blob/main/crm/export.js)\n- [crm/sync.js](https://github.com/sree-sanak/minty/blob/main/crm/sync.js)\n- [crm/server.js](https://github.com/sree-sanak/minty/blob/main/crm/server.js)\n- [crm/merge.js](https://github.com/sree-sanak/minty/blob/main/crm/merge.js)\n- [crm/schema.js](https://github.com/sree-sanak/minty/blob/main/crm/schema.js)\n- [crm/staleness.js](https://github.com/sree-sanak/minty/blob/main/crm/staleness.js)\n- [sources/_shared/progress.js](https://github.com/sree-sanak/minty/blob/main/sources/_shared/progress.js)\n- [sources/whatsapp/export.js](https://github.com/sree-sanak/minty/blob/main/sources/whatsapp/export.js)\n</details>\n\n# 数据存储结构\n\n## 概述\n\nMinty 项目采用**本地优先（Local-first）**的架构理念，所有数据均存储在用户本地的文件系统中，不依赖任何云端数据库服务。项目的核心设计原则是\"**文件系统即数据库**\"，数据通过导入器从各个来源收集，经过去重和合并后，形成统一的视图供上层应用使用。资料来源：[ARCHITECTURE.md]()\n\n## 核心设计原则\n\n| 原则 | 说明 |\n|------|------|\n| 本地优先 | 数据永不离开用户机器，核心功能不涉及任何网络传输 |\n| 文件系统即数据库 | 使用 JSON 文件作为持久化存储，无需安装数据库 |\n| 增量同步 | 部分导入器支持增量更新，避免重复导出 |\n| 原子写入 | 写入操作使用临时文件+重命名确保数据完整性 |\n| 可导出加密备份 | 支持生成加密的便携式备份包 |\n\n资料来源：[ARCHITECTURE.md]()\n\n---\n\n## 数据目录布局\n\n```\ndata/                              # 运行时数据目录（gitignored）\n├── whatsapp/                     # WhatsApp 导出数据\n│   ├── chats.json               # 聊天记录\n│   ├── contacts.json            # 联系人列表\n│   ├── metadata.json            # 元数据（包含 last_export_unix）\n│   ├── profile_pics/            # 联系人头像\n│   └── .progress.json          # 同步进度记录\n├── linkedin/                     # LinkedIn 数据\n│   ├── export/                  # 用户上传的 ZIP 导出包\n│   ├── parsed.csv               # 解析后的 CSV 数据\n│   └── .progress.json\n├── telegram/                     # Telegram 导出数据\n│   ├── result.json\n│   └── .progress.json\n├── email/                        # 邮件数据（按账户分目录）\n│   └── <account>/\n├── sms/                          # 短信数据（按平台分目录）\n│   └── <platform>/\n├── google-contacts/             # Google 通讯录\n│   └── .progress.json\n├── apollo/                       # Apollo 数据充实（可选）\n│   └── .progress.json\n└── unified/                      # 合并后的统一数据（核心输出）\n    ├── contacts.json            # 统一联系人记录\n    ├── interactions.json        # 交互时间线\n    ├── insights.json            # AI 洞察结果\n    ├── goals.json               # 目标数据\n    ├── group-memberships.json    # 群组成员关系\n    ├── query-index.json         # 搜索索引\n    ├── digest.json              # 摘要数据\n    ├── match_overrides.json     # 匹配覆盖规则\n    └── .progress.json\n```\n\n可通过环境变量 `CRM_DATA_DIR` 覆盖根目录，个别导入器支持各自的导出目录环境变量（如 `*_EXPORT_DIR`）。\n\n资料来源：[ARCHITECTURE.md]()\n\n---\n\n## 数据模型\n\n### Contact（联系人）记录\n\n联系人模型定义在 `crm/schema.js` 中，包含以下核心字段：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | string | 全局唯一标识符 |\n| `source` | string | 数据来源（whatsapp/linkedin/telegram/email 等） |\n| `name` | string | 规范化后的姓名 |\n| `phones` | string[] | 标准化后的电话号码列表 |\n| `emails` | string[] | 标准化后的邮箱列表 |\n| `company` | string | 公司名称 |\n| `title` | string | 职位 |\n| `tags` | string[] | 标签（如 investor、founder） |\n| `lastInteraction` | ISO date | 最近一次交互时间 |\n| `stale` | boolean | 数据是否过期标记 |\n\n资料来源：[ARCHITECTURE.md]()\n\n### Interaction（交互）记录\n\n交互记录描述与联系人的互动历史：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | string | 交互唯一标识 |\n| `contactId` | string | 关联的联系人 ID |\n| `type` | string | 交互类型（message/call/meeting/email） |\n| `timestamp` | ISO date | 交互时间 |\n| `source` | string | 数据来源 |\n| `summary` | string | 交互摘要 |\n| `metadata` | object | 附加元数据 |\n\n资料来源：[crm/schema.js]()\n\n---\n\n## 数据流架构\n\n```mermaid\ngraph TD\n    A[用户运行导入器] --> B[源数据导入器<br/>sources/&lt;src&gt;/import.js]\n    B --> C[写入数据源目录<br/>data/&lt;source&gt;/]\n    \n    D[定时或手动触发] --> E[合并进程<br/>crm/merge.js]\n    C --> E\n    \n    E --> F[数据规范化<br/>phones/emails/names]\n    F --> G[跨源去重<br/>crm/match.js]\n    G --> H[构建统一时间线]\n    H --> I[写入统一存储<br/>data/unified/]\n    \n    I --> J[HTTP 服务器<br/>crm/server.js]\n    J --> K[Web UI / API]\n    \n    I --> L[AI 洞察生成<br/>crm/ai.js]\n    L --> I\n    \n    M[同步监控<br/>crm/sync.js] --> D\n    M --> B\n```\n\n### 数据生命周期\n\n1. **导入阶段**：用户运行导入器，将数据从各平台导出并写入 `data/<source>/`\n2. **合并阶段**：`crm/merge.js` 加载各源数据，执行规范化、去重、合并\n3. **存储阶段**：结果写入 `data/unified/contacts.json` 和 `interactions.json`\n4. **服务阶段**：`crm/server.js` 读取统一存储，通过 HTTP API 提供数据\n5. **洞察阶段**：AI 模块基于统一数据生成洞察和摘要\n\n资料来源：[ARCHITECTURE.md]()\n\n---\n\n## 同步与进度追踪\n\n### 进度记录机制\n\n每个导入器使用 `sources/_shared/progress.js` 统一记录同步进度：\n\n| 字段 | 说明 |\n|------|------|\n| `source` | 数据源标识 |\n| `step` | 当前步骤（init/contacts/messages/merging/done/error） |\n| `message` | 状态描述 |\n| `current` / `total` | 进度数值 |\n| `itemsProcessed` | 已处理条目数 |\n| `errors` | 错误列表 |\n| `startedAt` / `updatedAt` | 时间戳 |\n| `error` | 错误详情对象 |\n\n进度文件位置：`data/<source>/.progress.json`\n\n### 原子写入机制\n\n```javascript\nfunction safeWrite(filePath, payload) {\n    const tmp = filePath + '.tmp-' + process.pid + '-' + Date.now();\n    fs.writeFileSync(tmp, JSON.stringify(payload));\n    fs.renameSync(tmp, filePath);\n}\n```\n\n写入操作先写入临时文件，再原子重命名，确保数据完整性。写入失败不会导致导入器崩溃。\n\n资料来源：[sources/_shared/progress.js]()\n\n### 数据过期检测\n\n`crm/staleness.js` 实现了联系人数据过期检测机制：\n\n| 来源类型 | 过期阈值 |\n|----------|----------|\n| WhatsApp | 14 天 |\n| Email | 30 天 |\n| LinkedIn | 90 天 |\n| Google Contacts | 60 天 |\n\n检测结果影响 UI 中的警告提示和数据置信度评分。\n\n资料来源：[crm/staleness.js]()\n\n---\n\n## 导出与备份\n\n### 导出包格式\n\n`crm/export.js` 支持生成便携式加密备份：\n\n| 字段 | 说明 |\n|------|------|\n| `version` | 导出格式版本（当前为 1） |\n| `exportedAt` | 导出时间戳 |\n| `contacts` | 联系人数据 |\n| `interactions` | 交互数据 |\n| `insights` | AI 洞察（可选） |\n| `goals` | 目标数据（可选） |\n| `groupMemberships` | 群组关系（可选） |\n| `syncState` | 同步状态 |\n| `insightsAt` | 洞察生成时间 |\n| `stats` | 统计摘要 |\n\n### 加密方案\n\n| 参数 | 值 | 说明 |\n|------|-----|------|\n| `SALT_BYTES` | 16 | PBKDF2 盐值长度 |\n| `IV_BYTES` | 12 | AES-GCM 初始向量 |\n| `TAG_BYTES` | 16 | 认证标签长度 |\n| `KDF_ITERS` | 200000 | PBKDF2 迭代次数 |\n\n加密模式使用 **AES-256-GCM**，密钥派生使用 **PBKDF2-SHA256**。\n\n资料来源：[crm/export.js]()\n\n### 导出方式\n\n| 命令 | 说明 |\n|------|------|\n| `npm run export` | CLI 导出 |\n| `GET /api/export` | HTTP API 导出 |\n| `POST /api/export` | 带请求体的导出 |\n\n---\n\n## API 接口\n\n| 端点 | 方法 | 说明 |\n|------|------|------|\n| `/api/sources/:key/progress` | GET | 获取单个数据源进度 |\n| `/api/sync/progress` | GET | 获取所有数据源进度 |\n| `/api/export` | GET/POST | 导出/加密导出 |\n\n资料来源：[crm/server.js]()\n\n---\n\n## 环境变量配置\n\n| 变量 | 说明 | 默认值 |\n|------|------|--------|\n| `CRM_DATA_DIR` | 数据根目录 | `./data` |\n| `WHATSAPP_EXPORT_DIR` | WhatsApp 导出目录 | `data/whatsapp/export` |\n| `LINKEDIN_EXPORT_DIR` | LinkedIn 导出目录 | `data/linkedin/export` |\n| `AI_BACKEND` | AI 后端选择 | `claude` / `ollama` |\n\n资料来源：[ARCHITECTURE.md]()\n\n---\n\n## 安全特性\n\n1. **本地优先**：核心功能不包含任何云端 LLM 集成，所有 AI 推理均为本地或用户主动选择\n2. **敏感信息脱敏**：进度记录模块包含 `redactErrorText()` 函数，自动脱敏邮箱、凭证、文件路径等敏感信息\n3. **加密导出**：可选 AES-256-GCM 加密保护备份数据\n4. **增量更新**：WhatsApp 等支持增量导出，减少数据暴露窗口\n\n资料来源：[crm/export.js](), [sources/_shared/progress.js](), [sources/whatsapp/export.js]()\n\n---\n\n<a id='page-mcp-integration'></a>\n\n## MCP 代理集成\n\n### 相关页面\n\n相关主题：[网络查询系统](#page-network-query), [快速开始](#page-quick-start)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [scripts/minty-mcp-server.js](https://github.com/sree-sanak/minty/blob/main/scripts/minty-mcp-server.js)\n- [hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md)\n- [README.md](https://github.com/sree-sanak/minty/blob/main/README.md)\n- [ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n- [docs/OPENCLAW_HERMES.md](https://github.com/sree-sanak/minty/blob/main/docs/OPENCLAW_HERMES.md)\n</details>\n\n# MCP 代理集成\n\n## 概述\n\nMCP（Model Context Protocol）代理集成是 Minty 项目为 AI 代理提供的标准化接口层。通过 MCP 协议，外部代理系统（如 OpenClaw、Claude Code、Ollama）可以直接调用 Minty 的联系人检索和关系管理能力，无需直接访问底层数据文件。 资料来源：[README.md]()\n\nMinty 采用本地优先架构，所有联系人数据存储在本地 `data/` 目录中，MCP 服务以独立的 stdio 进程运行，确保数据不离开用户的机器。 资料来源：[ARCHITECTURE.md]()\n\n## 核心架构\n\n### 系统组件\n\n```mermaid\ngraph TD\n    subgraph 外部代理 [\"外部代理系统\"]\n        OC[OpenClaw]\n        HM[Hermes]\n        CC[Claude Code CLI]\n    end\n    \n    subgraph MCP层 [\"MCP 协议层\"]\n        SERVER[scripts/minty-mcp-server.js]\n    end\n    \n    subgraph 核心引擎 [\"Minty 核心引擎\"]\n        RETRIEVAL[crm/agent-retrieval.js]\n        MATCH[crm/match.js]\n        SEARCH[crm/search.js]\n    end\n    \n    subgraph 数据存储 [\"本地数据存储\"]\n        CONTACTS[data/unified/contacts.json]\n        INTERACTIONS[data/unified/interactions.json]\n    end\n    \n    OC --> SERVER\n    HM --> SERVER\n    CC --> SERVER\n    SERVER --> RETRIEVAL\n    RETRIEVAL --> MATCH\n    RETRIEVAL --> SEARCH\n    MATCH --> CONTACTS\n    SEARCH --> INTERACTIONS\n```\n\n### MCP 服务入口\n\n`scripts/minty-mcp-server.js` 是 MCP 服务的核心入口文件，负责注册所有可用的工具并处理代理请求。服务以 stdio 模式运行，适合与 AI 代理进行本地集成。 资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n## 可用工具\n\nMCP 服务暴露四个核心工具，供外部代理调用：\n\n| 工具名称 | 功能描述 | 主要参数 |\n|---------|---------|---------|\n| `search_network` | 自然语言网络搜索 | `query`, `limit`, `source`/`sources` |\n| `person_context` | 查询特定联系人详情 | `person`, `limit` |\n| `workflow_brief` | 生成目标导向简报 | `goal`, `limit` |\n| `source_health` | 检查数据源健康状态 | `source`/`sources`/`query` |\n\n### search_network\n\n用于自由形式的网络查询，返回排名靠前的联系人及其关联证据。\n\n```json\n{\n  \"query\": \"investors in London who know about AI\",\n  \"limit\": 5\n}\n```\n\n支持按来源过滤：\n\n```json\n{\n  \"query\": \"people I discussed Telegram bots with\",\n  \"source\": \"telegram\",\n  \"limit\": 5\n}\n```\n\n### person_context\n\n查询特定联系人的详细信息，包括关系上下文、亲密度评分和证据。\n\n```json\n{\n  \"person\": \"Alice Müller\",\n  \"limit\": 3\n}\n```\n\n### workflow_brief\n\n生成以目标为导向的简报，帮助代理找到能够帮助完成特定任务的人。\n\n```json\n{\n  \"goal\": \"Find EU crypto insurance distribution partners\",\n  \"limit\": 5\n}\n```\n\n### source_health\n\n在执行来源特定查询前进行预检查，确保数据源处于可用状态。\n\n```json\n{ \"source\": \"telegram\" }\n{ \"sources\": [\"telegram\", \"slack\"] }\n{ \"query\": \"who from Telegram knows DeFi?\" }\n```\n\n## 配置与部署\n\n### 环境变量\n\n| 变量名 | 说明 | 默认值 |\n|-------|------|-------|\n| `CRM_DATA_DIR` | 数据目录路径 | `./data` |\n| `MINTY_USER_UUID` | 用户唯一标识 | 自动生成 |\n| `AI_BACKEND` | AI 后端类型 | `claude` |\n\n### AI 后端选择\n\nMinty 支持两种本地 AI 后端：\n\n1. **Claude Code CLI（默认）**：调用 `claude --print` 进行推理，免费但会将提示发送至 Anthropic 服务器\n2. **Ollama**：通过设置 `AI_BACKEND=ollama` 启用，支持本地模型如 `qwen2.5:7b`，完全离线运行\n\n资料来源：[README.md]()\n\n### 启动 MCP 服务\n\n```bash\n# 基础启动\nnpm run mcp\n\n# 指定数据目录\nCRM_DATA_DIR=./data-demo npm run mcp\n\n# 服务模式（守护进程）\nnpm run service\nMINTY_USER_UUID=abc npm run service\n```\n\n## 与外部代理集成\n\n### OpenClaw + Hermes 集成\n\n完整的集成配置文档位于 `docs/OPENCLAW_HERMES.md`。核心步骤包括：\n\n1. 注册 `scripts/minty-mcp-server.js` 为 stdio MCP 服务器\n2. 配置代理系统连接到本地 MCP 端点\n3. 设置数据目录环境变量\n\n```json\n{\n  \"mcpServers\": {\n    \"minty\": {\n      \"command\": \"node\",\n      \"args\": [\"/root/.hermes/workspace/minty/scripts/minty-mcp-server.js\"],\n      \"timeout\": 60,\n      \"connect_timeout\": 20\n    }\n  }\n}\n```\n\n资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n### Claude Code 代理支持\n\nClaude Code 代理可以直接通过 MCP 工具访问联系人网络：\n\n```bash\nCRM_DATA_DIR=./data-demo npm run agent -- \"who can help with crypto insurance\"\n```\n\n### 演示模式\n\n使用演示数据快速验证集成是否正常工作：\n\n```bash\nnpm run seed:demo\nnpm run mcp\nnpm run agent -- \"investors in London\"\n```\n\n资料来源：[README.md]()\n\n## 就绪状态检查\n\nMinty 提供三个就绪级别用于评估集成状态：\n\n| 级别 | 描述 | 验证命令 |\n|-----|------|---------|\n| Demo-ready | 演示数据可用 | `npm run seed:demo && npm run mcp` |\n| Dogfood-ready | 真实本地数据可用 | `npm run memory:refresh` |\n| Hermes-native | 完整集成就绪 | `npm run hermes:doctor` |\n\n执行健康检查：\n\n```bash\nnpm run hermes:doctor\n```\n\n资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n## 数据安全与隐私\n\nMCP 服务运行在本地，所有联系人数据存储在用户本地磁盘的 `data/` 目录中。服务不进行遥测、不收集分析数据、不与外部服务器通信。 资料来源：[README.md]()\n\n### 敏感信息处理\n\n在处理联系人数据和生成建议时，MCP 服务会自动过滤以下敏感信息：\n\n- 邮箱地址（显示为 `[redacted-email]`）\n- Bearer 令牌和认证凭证\n- 文件路径信息\n- 堆栈跟踪信息\n\n## 错误处理与调试\n\n### 常见问题排查\n\n| 问题 | 可能原因 | 解决方案 |\n|-----|---------|---------|\n| MCP 连接超时 | 服务未启动 | 执行 `npm run mcp` |\n| 数据源返回空结果 | 数据源过期或未导入 | 执行 `npm run memory:refresh` |\n| 认证失败 | 环境变量未设置 | 检查 `AI_BACKEND` 配置 |\n\n### 源健康预检\n\n在执行来源特定查询前，始终建议调用 `source_health` 检查数据源状态：\n\n- **Fresh**：数据最近有更新\n- **Evidence-bearing**：有足够的交互证据\n- **Stale**：数据过期，需要刷新\n- **Empty**：无数据导入\n\n如果数据源状态为 stale 或 empty，应返回诚实的低置信度回答，而非虚构信息。 资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n## 扩展开发\n\n### 添加新工具\n\n在 `scripts/minty-mcp-server.js` 中注册新工具需要：\n\n1. 在工具注册表中添加条目\n2. 实现工具处理器函数\n3. 更新 `hermes/minty-network-memory/SKILL.md` 中的文档\n4. 添加相应的集成测试\n\n### 工具维护契约\n\n`scripts/minty-mcp-server.js` 是暴露 MCP 工具的事实来源（source of truth）。任何添加、移除或重命名工具的 PR 必须同步更新相关文档和技能说明。 资料来源：[hermes/minty-network-memory/SKILL.md]()\n\n## 相关文档\n\n- [Minty 架构概览](./ARCHITECTURE.md)\n- [OpenClaw + Hermes 集成指南](./docs/OPENCLAW_HERMES.md)\n- [代理检索引擎](./crm/agent-retrieval.js)\n- [联系人匹配算法](./crm/match.js)\n\n---\n\n<a id='page-network-query'></a>\n\n## 网络查询系统\n\n### 相关页面\n\n相关主题：[MCP 代理集成](#page-mcp-integration)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [crm/query.js](https://github.com/sree-sanak/minty/blob/main/crm/query.js)\n- [crm/network-query.js](https://github.com/sree-sanak/minty/blob/main/crm/network-query.js)\n- [crm/query-reasons.js](https://github.com/sree-sanak/minty/blob/main/crm/query-reasons.js)\n- [crm/search.js](https://github.com/sree-sanak/minty/blob/main/crm/search.js)\n- [crm/hybrid-index.js](https://github.com/sree-sanak/minty/blob/main/crm/hybrid-index.js)\n</details>\n\n# 网络查询系统\n\n## 概述\n\n网络查询系统（Network Query System）是 Minty CRM 的核心检索引擎，负责通过自然语言或结构化查询从用户的人际网络中快速定位相关联系人及其交互记录。该系统整合了来自多个数据源（WhatsApp、LinkedIn、Telegram、Email、Google Contacts 等）的统一数据，提供语义化的网络搜索能力，使用户能够以自然对话的方式回答\"我和谁讨论过 X 话题\"、\"在某个活动中见过哪些人\"等查询需求。\n\n网络查询系统的设计目标是将散落在不同通讯平台中的碎片化人际关系重新编织成可检索、可分析的网络图谱，支持从简单的人名搜索到复杂的多条件组合查询。资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n## 架构概览\n\n网络查询系统采用分层架构，从底层到顶层依次为：数据索引层、查询解析层、匹配引擎层和 API 接口层。各层职责明确，通过标准化的数据结构进行通信。\n\n```mermaid\ngraph TD\n    A[用户查询] --> B[查询解析层<br/>query-reasons.js]\n    B --> C[自然语言理解<br/>分词/意图识别]\n    C --> D[混合索引层<br/>hybrid-index.js]\n    D --> E[匹配引擎层<br/>search.js]\n    E --> F[结果排序与过滤]\n    F --> G[API 接口层<br/>network-query.js]\n    G --> H[返回结果]\n    \n    I[统一数据存储<br/>data/unified/] --> D\n    J[交互索引<br/>interactions.json] --> E\n```\n\n### 核心组件职责\n\n| 组件 | 文件路径 | 主要职责 |\n|------|----------|----------|\n| 查询解析 | `crm/query-reasons.js` | 分析查询语句，提取关键词、过滤条件和排序需求 |\n| 混合索引 | `crm/hybrid-index.js` | 构建和维护联系人与交互记录的倒排索引 |\n| 搜索匹配 | `crm/search.js` | 执行关键词匹配、模糊搜索和相关性评分 |\n| 网络查询 | `crm/network-query.js` | 提供自然语言查询接口，处理复杂检索场景 |\n| CLI 查询 | `crm/query.js` | 命令行统计和搜索功能 |\n\n资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n## 查询解析机制\n\n### query-reasons.js — 查询意图分析\n\n`query-reasons.js` 模块负责将用户的自然语言查询转换为结构化的检索条件。该模块通过预定义的正则表达式模式和启发式规则识别查询中的关键成分，包括：\n\n- **人员实体**：查询中提到的人名或公司名称\n- **时间范围**：相对时间（\"最近一周\"、\"上个月\"）或绝对时间\n- **来源过滤**：指定的数据源（telegram、linkedin、email 等）\n- **意图类型**：搜索类型（统计信息、联系人列表、交互记录等）\n\n查询解析结果会生成一个结构化的 `query reasons` 对象，包含提取的关键词列表、过滤条件和权重配置，供下游匹配引擎使用。资料来源：[hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md)\n\n### 查询类型分类\n\n| 查询类型 | 示例 | 处理逻辑 |\n|----------|------|----------|\n| 自然语言搜索 | \"我在伦敦见过的投资人\" | 解析实体+来源+时间，组合检索 |\n| 来源过滤查询 | \"来自 Telegram 的人\" | 仅在指定数据源中搜索 |\n| 关键词搜索 | \"DeFi\"、\"区块链\" | 分词后匹配交互记录 |\n| 人员上下文 | \"Alice Müller 的相关信息\" | 精确匹配 + 关联扩展 |\n\n## 搜索匹配引擎\n\n### search.js — 核心匹配逻辑\n\n`search.js` 是网络查询系统的匹配引擎核心，负责在已索引的数据中执行高效的相似度匹配和相关性排序。\n\n#### 匹配函数实现\n\n匹配引擎支持三种主要的匹配模式：\n\n```javascript\nfunction matches(text, clause) {\n    if (clause.kind === 'phrase') return text.toLowerCase().includes(clause.value);\n    if (clause.kind === 'prefix') return findPrefix(text, clause.value).length > 0;\n    // token: case-insensitive substring match of the full token\n    return text.toLowerCase().includes(clause.value);\n}\n```\n\n- **phrase（短语匹配）**：完整匹配查询短语，区分大小写但忽略大小写差异\n- **prefix（前缀匹配）**：匹配以查询词开头的文本片段\n- **token（分词匹配）**：对查询词进行分词后逐个匹配\n\n资料来源：[crm/search.js](https://github.com/sree-sanak/minty/blob/main/crm/search.js)\n\n#### 偏移量计算\n\n`matchOffsets` 函数用于计算匹配文本在原始内容中的位置信息，支持高亮显示和上下文提取：\n\n```javascript\nfunction matchOffsets(text, clause) {\n    if (clause.kind === 'phrase' || clause.kind === 'token') return findAll(text, clause.value);\n    if (clause.kind === 'prefix') return findPrefix(text, clause.value);\n    return [];\n}\n```\n\n#### 结果排序策略\n\n搜索结果按综合评分排序，评分相同时按时间戳降序排列：\n\n```javascript\n.sort((a, b) => (b.score - a.score) ||\n    ((new Date(b.timestamp || 0).getTime()) - (new Date(a.timestamp || 0).getTime())));\n```\n\n评分计算综合考虑以下因素：\n- 关键词命中次数\n- 匹配模式优先级（精确匹配 > 前缀匹配 > 模糊匹配）\n- 时间衰减因子（新近交互优先）\n- 关系亲密度（relationshipScore）\n\n#### 主题词提取\n\n`dominantTokens` 函数从文本中提取最具代表性的关键词，用于构建主题索引和支持话题聚合查询：\n\n```javascript\nfunction dominantTokens(text, opts = {}) {\n    const freq = {};\n    const min = opts.min || 2;\n    const topN = opts.topN || 10;\n    const words = String(text || '').toLowerCase().match(ALPHA_NUM) || [];\n    for (const w of words) {\n        if (w.length < 4 || STOP_WORDS.has(w)) continue;\n        freq[w] = (freq[w] || 0) + 1;\n    }\n    return Object.entries(freq)\n        .filter(([, n]) => n >= min)\n        .sort((a, b) => b[1] - a[1])\n        .slice(0, topN)\n        .map(([word]) => word);\n}\n```\n\n该函数自动过滤停用词和长度小于 4 的词汇，并按词频排序返回 Top N 关键词。资料来源：[crm/search.js](https://github.com/sree-sanak/minty/blob/main/crm/search.js)\n\n## 混合索引系统\n\n### hybrid-index.js — 索引构建与管理\n\n`hybrid-index.js` 负责构建和维护联系人与交互记录的混合索引。索引采用倒排结构，支持高效的关键词查询和多维度过滤。\n\n#### 索引数据结构\n\n索引系统维护以下核心数据结构：\n\n1. **联系人索引**：按姓名、公司、职位、标签等字段建立倒排索引\n2. **交互索引**：按时间线组织交互记录，支持时间范围查询\n3. **来源索引**：按数据源分类，支持来源级别的过滤和健康度检测\n4. **主题索引**：基于 `dominantTokens` 提取的主题词构建话题网络\n\n#### 索引构建流程\n\n索引构建是离线过程，通常在数据合并（`merge.js`）完成后执行。构建流程包括：\n\n1. 加载统一数据存储中的 `contacts.json` 和 `interactions.json`\n2. 对每个联系人和交互记录进行分词处理\n3. 构建各字段的倒排索引\n4. 计算关联权重和预评分\n5. 持久化索引文件供运行时加载\n\n## 自然语言查询接口\n\n### network-query.js — 对话式查询 API\n\n`network-query.js` 模块提供 MCP（Model Context Protocol）接口，支持通过自然语言进行网络查询。该模块封装了底层的搜索能力，提供面向 AI Agent 的高级查询接口。\n\n#### 核心查询工具\n\n| 工具名称 | 功能描述 | 典型参数 |\n|----------|----------|----------|\n| `search_network` | 自然语言网络搜索 | `query`, `limit`, `source`/`sources` |\n| `person_context` | 人员上下文查询 | `person`, `limit` |\n| `workflow_brief` | 目标导向简报生成 | `goal`, `limit` |\n| `source_health` | 数据源健康度检查 | `source`/`sources`/`query` |\n\n资料来源：[hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md)\n\n#### search_network 查询示例\n\n```json\n{\n  \"query\": \"investors in London who know about AI\",\n  \"limit\": 5\n}\n```\n\n返回结果包含按相关性排序的联系人列表，每个结果包含：\n- **证据（evidence）**：匹配依据和上下文片段\n- **亲密度（warmth）**：关系评分\n- **置信度（confidence）**：数据可信度评估\n- **来源诊断（source diagnostics）**：结果来源分析\n- **建议操作（suggested actions）**：下一步安全建议\n\n#### person_context 查询示例\n\n```json\n{\n  \"person\": \"Alice Müller\",\n  \"limit\": 3\n}\n```\n\n返回指定人员的完整关系上下文，包括：\n- 关系历史摘要\n- 交互亲密度评分\n- 最近交互证据\n- 数据新鲜度诊断\n\n#### workflow_brief 目标简报\n\n针对特定目标生成人员推荐简报：\n\n```json\n{\n  \"goal\": \"Find EU crypto insurance distribution partners\",\n  \"limit\": 5\n}\n```\n\n返回结果包含目标相关度最高的联系人列表，每个联系人附带：\n- 相关性原因说明\n- 数据新鲜度状态\n- 安全的下一步行动建议\n\n### 数据源健康度检测\n\n`source_health` 工具在执行网络查询前自动检查各数据源的状态，确保查询结果的可靠性：\n\n```json\n{ \"source\": \"telegram\" }\n```\n\n健康度状态分类：\n- **demo-ready**：可用示例数据\n- **fresh**：数据源状态正常\n- **stale**：数据较旧，可能需要刷新\n- **empty**：数据源为空或未初始化\n- **unsafe**：数据不可靠，建议修复后再使用\n\n资料来源：[hermes/minty-network-memory/SKILL.md](https://github.com/sree-sanak/minty/blob/main/hermes/minty-network-memory/SKILL.md)\n\n## 命令行查询接口\n\n### query.js — CLI 工具\n\n`query.js` 提供命令行界面的统计和搜索功能，通过以下命令调用：\n\n```bash\nnpm run stats   # 显示网络统计信息\nnpm run search  # 执行关键词搜索\n```\n\nCLI 查询工具适合快速获取网络概览和批量数据导出场景，支持以下功能：\n\n- 联系人总数和来源分布统计\n- 交互记录数量和时间分布\n- 关键词搜索并高亮显示结果\n- 导出查询结果为 CSV/JSON 格式\n\n资料来源：[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)\n\n## 数据流与处理管道\n\n### 查询执行完整流程\n\n```mermaid\nsequenceDiagram\n    participant U as 用户\n    participant NQ as network-query.js\n    participant QR as query-reasons.js\n    participant HI as hybrid-index.js\n    participant SE as search.js\n    participant DS as 统一数据存储\n\n    U->>NQ: 自然语言查询\n    NQ->>QR: 解析查询意图\n    QR-->>NQ: 结构化查询条件\n    NQ->>HI: 加载/查询索引\n    HI->>DS: 获取最新数据\n    DS-->>HI: 数据快照\n    HI-->>NQ: 候选结果集\n    NQ->>SE: 执行匹配评分\n    SE-->>NQ: 排序后结果\n    NQ-->>U: 返回查询结果\n```\n\n### 与其他模块的交互\n\n网络查询系统与以下模块紧密协作：\n\n| 关联模块 | 交互方式 | 数据依赖 |\n|----------|----------|----------|\n| `merge.js` | 索引更新触发 | 接收合并后的统一数据 |\n| `staleness.js` | 健康度查询 | 使用新鲜度数据校准结果权重 |\n| `server.js` | HTTP API 封装 | 提供 `/api/search` 等端点 |\n| `calendar.js` | 日程数据融合 | 查询中加入日历事件上下文 |\n\n## 数据模型\n\n### 联系人数据结构\n\n网络查询系统处理的联系人记录包含以下关键字段：\n\n| 字段名 | 类型 | 说明 | 可检索性 |\n|--------|------|------|----------|\n| `id` | string | 唯一标识符 | 精确匹配 |\n| `name` | string | 姓名 | 分词匹配 |\n| `company` | string | 公司名称 | 前缀匹配 |\n| `position` | string | 职位 | 分词匹配 |\n| `sources` | object | 各数据源原始数据 | 来源过滤 |\n| `relationshipScore` | number | 关系评分 0-100 | 范围过滤 |\n| `daysSinceContact` | number | 最近联系天数 | 范围过滤 |\n| `activeChannels` | string[] | 活跃联系方式 | 包含匹配 |\n| `tags` | string[] | 自定义标签 | 精确匹配 |\n\n资料来源：[AGENTS.md](https://github.com/sree-sanak/minty/blob/main/AGENTS.md)\n\n### 交互记录数据结构\n\n| 字段名 | 类型 | 说明 |\n|--------|------|------|\n| `id` | string | 交互记录唯一标识 |\n| `contactId` | string | 关联联系人 ID |\n| `source` | string | 数据来源（whatsapp/telegram/email等） |\n| `timestamp` | ISO string | 交互时间 |\n| `type` | string | 交互类型（message/call/meeting） |\n| `body` | string | 交互内容正文 |\n| `subject` | string | 主题（邮件场景） |\n\n## 性能优化策略\n\n### 索引优化\n\n网络查询系统采用以下索引优化策略：\n\n1. **增量更新**：仅对变更的联系人/交互记录重新索引\n2. **压缩存储**：使用倒排列表压缩减少磁盘占用\n3. **缓存预热**：服务器启动时预加载高频查询索引\n4. **分片加载**：按数据源分片懒加载，平衡内存占用\n\n### 查询优化\n\n1. **早停规则**：达到目标结果数后提前终止匹配\n2. **缓存复用**：相同查询条件的结果缓存复用\n3. **结果分页**：避免一次性加载大量结果\n4. **评分截断**：对低分结果进行截断过滤\n\n## 使用场景示例\n\n### 场景一：查找特定领域联系人\n\n**查询**：查找讨论过 DeFi 话题的 Telegram 联系人\n\n```json\n{\n  \"query\": \"DeFi\",\n  \"sources\": [\"telegram\"],\n  \"limit\": 10\n}\n```\n\n系统会：\n1. 解析关键词 \"DeFi\"\n2. 在 Telegram 数据源中检索\n3. 匹配交互记录中的 DeFi 相关内容\n4. 按相关性评分和时间排序返回\n\n### 场景二：人员关系探索\n\n**查询**：获取特定人员的完整关系上下文\n\n```json\n{\n  \"person\": \"Bob Chen\",\n  \"limit\": 5\n}\n```\n\n返回结果包含该人员的所有交互证据、最近联系时间、共同话题等上下文信息。\n\n### 场景三：目标导向搜索\n\n**查询**：为特定目标寻找相关联系人\n\n```json\n{\n  \"goal\": \"Find potential co-founders for AI startup\",\n  \"limit\": 10\n}\n```\n\n系统综合分析所有联系人的背景、交互历史和话题相关性，生成目标相关度排序列表。\n\n## 总结\n\n网络查询系统是 Minty CRM 智能化能力的核心体现，通过整合多源数据、构建混合索引和提供自然语言接口，使用户能够以直观的方式探索和利用自己的人际网络。该系统具有以下核心特点：\n\n- **多源聚合**：统一检索散落在各平台的交互数据\n- **语义理解**：支持自然语言查询和意图识别\n- **智能排序**：综合相关度、时效性、亲密度多维度评分\n- **健康感知**：自动检测数据源状态，保证结果可靠性\n- **MCP 兼容**：提供标准化的 AI Agent 接口支持\n\n通过 `network-query.js`、`search.js`、`query-reasons.js` 和 `hybrid-index.js` 等模块的协作，网络查询系统为用户提供了从简单关键词搜索到复杂目标导向探索的完整检索能力。\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：sree-sanak/minty\n\n摘要：发现 14 个潜在踩坑项，其中 1 个为 high/blocking；最高优先级：安装坑 - 来源证据：Audit person-only filters for channel/broadcast/list contacts。\n\n## 1. 安装坑 · 来源证据：Audit person-only filters for channel/broadcast/list contacts\n\n- 严重度：high\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Audit person-only filters for channel/broadcast/list contacts\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_806464769ad247cd93162d66f18c8d51 | https://github.com/sree-sanak/minty/issues/86 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 2. 身份坑 · 仓库名和安装名不一致\n\n- 严重度：medium\n- 证据强度：runtime_trace\n- 发现：仓库名 `minty` 与安装入口 `imap` 不完全一致。\n- 对用户的影响：用户照着仓库名搜索包或照着包名找仓库时容易走错入口。\n- 建议检查：在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。\n- 复现命令：`npm install imap`\n- 防护动作：页面必须同时展示 repo 名和真实安装入口，避免用户搜索错包。\n- 证据：identity.distribution | github_repo:1217893833 | https://github.com/sree-sanak/minty | repo=minty; install=imap\n\n## 3. 安装坑 · 来源证据：Replace README screenshot TODO with privacy-safe demo visual\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Replace README screenshot TODO with privacy-safe demo visual\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_81816548248b4de0a1ace912ebf7ee0e | https://github.com/sree-sanak/minty/issues/97 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 4. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:1217893833 | https://github.com/sree-sanak/minty | README/documentation is current enough for a first validation pass.\n\n## 5. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:1217893833 | https://github.com/sree-sanak/minty | last_activity_observed missing\n\n## 6. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:1217893833 | https://github.com/sree-sanak/minty | no_demo; severity=medium\n\n## 7. 安全/权限坑 · 存在安全注意事项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：No sandbox install has been executed yet; downstream must verify before user use.\n- 对用户的影响：用户安装前需要知道权限边界和敏感操作。\n- 建议检查：转成明确权限清单和安全审查提示。\n- 防护动作：安全注意事项必须面向用户前置展示。\n- 证据：risks.safety_notes | github_repo:1217893833 | https://github.com/sree-sanak/minty | No sandbox install has been executed yet; downstream must verify before user use.\n\n## 8. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:1217893833 | https://github.com/sree-sanak/minty | no_demo; severity=medium\n\n## 9. 安全/权限坑 · 来源证据：Add minimal GitHub Actions smoke CI for npm test\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Add minimal GitHub Actions smoke CI for npm test\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_d6f1f5066d884d66b52f3e8f51ed0899 | https://github.com/sree-sanak/minty/issues/98 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 10. 安全/权限坑 · 来源证据：Avoid returning raw internal error messages from API/UI\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Avoid returning raw internal error messages from API/UI\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_2974d969ccff4c9b960c16ee12639466 | https://github.com/sree-sanak/minty/issues/44 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 11. 安全/权限坑 · 来源证据：Provision GitHub labels from checked-in labels.json\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Provision GitHub labels from checked-in labels.json\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_1a3ae522d9a7404691d7e3eb4b70b6b1 | https://github.com/sree-sanak/minty/issues/109 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 12. 安全/权限坑 · 来源证据：Sync failures can mark stale source data as fresh\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Sync failures can mark stale source data as fresh\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_3bc92d2124c24b978bf799cc9eff9529 | https://github.com/sree-sanak/minty/issues/200 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 13. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:1217893833 | https://github.com/sree-sanak/minty | issue_or_pr_quality=unknown\n\n## 14. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:1217893833 | https://github.com/sree-sanak/minty | release_recency=unknown\n\n<!-- canonical_name: sree-sanak/minty; human_manual_source: deepwiki_human_wiki -->\n",
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "Human Manual / 人类版说明书"
    },
    "pitfall_log": {
      "asset_id": "pitfall_log",
      "filename": "PITFALL_LOG.md",
      "markdown": "# Pitfall Log / 踩坑日志\n\n项目：sree-sanak/minty\n\n摘要：发现 14 个潜在踩坑项，其中 1 个为 high/blocking；最高优先级：安装坑 - 来源证据：Audit person-only filters for channel/broadcast/list contacts。\n\n## 1. 安装坑 · 来源证据：Audit person-only filters for channel/broadcast/list contacts\n\n- 严重度：high\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Audit person-only filters for channel/broadcast/list contacts\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_806464769ad247cd93162d66f18c8d51 | https://github.com/sree-sanak/minty/issues/86 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 2. 身份坑 · 仓库名和安装名不一致\n\n- 严重度：medium\n- 证据强度：runtime_trace\n- 发现：仓库名 `minty` 与安装入口 `imap` 不完全一致。\n- 对用户的影响：用户照着仓库名搜索包或照着包名找仓库时容易走错入口。\n- 建议检查：在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。\n- 复现命令：`npm install imap`\n- 防护动作：页面必须同时展示 repo 名和真实安装入口，避免用户搜索错包。\n- 证据：identity.distribution | github_repo:1217893833 | https://github.com/sree-sanak/minty | repo=minty; install=imap\n\n## 3. 安装坑 · 来源证据：Replace README screenshot TODO with privacy-safe demo visual\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Replace README screenshot TODO with privacy-safe demo visual\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_81816548248b4de0a1ace912ebf7ee0e | https://github.com/sree-sanak/minty/issues/97 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 4. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:1217893833 | https://github.com/sree-sanak/minty | README/documentation is current enough for a first validation pass.\n\n## 5. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:1217893833 | https://github.com/sree-sanak/minty | last_activity_observed missing\n\n## 6. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:1217893833 | https://github.com/sree-sanak/minty | no_demo; severity=medium\n\n## 7. 安全/权限坑 · 存在安全注意事项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：No sandbox install has been executed yet; downstream must verify before user use.\n- 对用户的影响：用户安装前需要知道权限边界和敏感操作。\n- 建议检查：转成明确权限清单和安全审查提示。\n- 防护动作：安全注意事项必须面向用户前置展示。\n- 证据：risks.safety_notes | github_repo:1217893833 | https://github.com/sree-sanak/minty | No sandbox install has been executed yet; downstream must verify before user use.\n\n## 8. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:1217893833 | https://github.com/sree-sanak/minty | no_demo; severity=medium\n\n## 9. 安全/权限坑 · 来源证据：Add minimal GitHub Actions smoke CI for npm test\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Add minimal GitHub Actions smoke CI for npm test\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_d6f1f5066d884d66b52f3e8f51ed0899 | https://github.com/sree-sanak/minty/issues/98 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 10. 安全/权限坑 · 来源证据：Avoid returning raw internal error messages from API/UI\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Avoid returning raw internal error messages from API/UI\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_2974d969ccff4c9b960c16ee12639466 | https://github.com/sree-sanak/minty/issues/44 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 11. 安全/权限坑 · 来源证据：Provision GitHub labels from checked-in labels.json\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Provision GitHub labels from checked-in labels.json\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_1a3ae522d9a7404691d7e3eb4b70b6b1 | https://github.com/sree-sanak/minty/issues/109 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 12. 安全/权限坑 · 来源证据：Sync failures can mark stale source data as fresh\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Sync failures can mark stale source data as fresh\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_3bc92d2124c24b978bf799cc9eff9529 | https://github.com/sree-sanak/minty/issues/200 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 13. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:1217893833 | https://github.com/sree-sanak/minty | issue_or_pr_quality=unknown\n\n## 14. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:1217893833 | https://github.com/sree-sanak/minty | release_recency=unknown\n",
      "summary": "用户实践前最可能遇到的身份、安装、配置、运行和安全坑。",
      "title": "Pitfall Log / 踩坑日志"
    },
    "prompt_preview": {
      "asset_id": "prompt_preview",
      "filename": "PROMPT_PREVIEW.md",
      "markdown": "# minty - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 minty 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的工具连接与集成任务。\n我常用的宿主 AI：MCP Client\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 步骤建议, 检查清单, 专业工作流。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- AI Skill / Agent 指令资产库: 项目包含可被宿主 AI 读取的 Skill 或 Agent 指令文件，可用于把专业流程带入 Claude、Codex、Cursor 等宿主。 输入：用户任务, 宿主 AI 对话上下文, 项目内 Skill/Agent 文档；输出：步骤建议, 检查清单, 专业工作流。\n\n【必须安装后才可验证的能力】\n- 命令行启动或安装流程: 项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 输入：终端环境, 包管理器, 项目依赖；输出：安装结果, 列表/更新/运行结果。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. page-introduction：项目介绍。围绕“项目介绍”模拟一次用户任务，不展示安装或运行结果。\n2. page-quick-start：快速开始。围绕“快速开始”模拟一次用户任务，不展示安装或运行结果。\n3. page-architecture-overview：架构总览。围绕“架构总览”模拟一次用户任务，不展示安装或运行结果。\n4. page-data-sources：数据源导入。围绕“数据源导入”模拟一次用户任务，不展示安装或运行结果。\n5. page-contact-merging：联系人合并与去重。围绕“联系人合并与去重”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. page-introduction\n输入：用户提供的“项目介绍”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. page-quick-start\n输入：用户提供的“快速开始”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. page-architecture-overview\n输入：用户提供的“架构总览”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. page-data-sources\n输入：用户提供的“数据源导入”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. page-contact-merging\n输入：用户提供的“联系人合并与去重”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / page-introduction：Step 1 必须围绕“项目介绍”形成一个小中间产物，并等待用户确认。\n- Step 2 / page-quick-start：Step 2 必须围绕“快速开始”形成一个小中间产物，并等待用户确认。\n- Step 3 / page-architecture-overview：Step 3 必须围绕“架构总览”形成一个小中间产物，并等待用户确认。\n- Step 4 / page-data-sources：Step 4 必须围绕“数据源导入”形成一个小中间产物，并等待用户确认。\n- Step 5 / page-contact-merging：Step 5 必须围绕“联系人合并与去重”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://github.com/sree-sanak/minty\n- https://github.com/sree-sanak/minty#readme\n- hermes/minty-network-memory/SKILL.md\n- README.md\n- VISION.md\n- SECURITY.md\n- docs/PHILOSOPHY.md\n- docs/SERVICE.md\n- docs/OPENCLAW_HERMES.md\n- ARCHITECTURE.md\n- crm/index.js\n- crm/schema.js\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 minty 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "summary": "不安装项目也能感受能力节奏的安全试用 Prompt。",
      "title": "Prompt Preview / 安装前试用 Prompt"
    },
    "quick_start": {
      "asset_id": "quick_start",
      "filename": "QUICK_START.md",
      "markdown": "# Quick Start / 官方入口\n\n项目：sree-sanak/minty\n\n## 官方安装入口\n\n### Node.js / npm · 官方安装入口\n\n```bash\nnpm install imap\n```\n\n来源：https://github.com/sree-sanak/minty#readme\n\n## 来源\n\n- repo: https://github.com/sree-sanak/minty\n- docs: https://github.com/sree-sanak/minty#readme\n",
      "summary": "从项目官方 README 或安装文档提取的开工入口。",
      "title": "Quick Start / 官方入口"
    }
  },
  "validation_id": "dval_723cbe3febe34eca8d77a840a45eccee"
}
