diff --git a/02_卡人(水)/水桥_平台对接/接收短信/SKILL.md b/02_卡人(水)/水桥_平台对接/接收短信/SKILL.md
new file mode 100644
index 00000000..07640fde
--- /dev/null
+++ b/02_卡人(水)/水桥_平台对接/接收短信/SKILL.md
@@ -0,0 +1,104 @@
+---
+name: 接收短信
+description: 通过 receivesms 类网站获取临时号码并抓取该号码最新一条短信(含发件人名字与内容)。触发词:接收短信、收短信、receivesms、接码、临时号码、获取短信、拿短信。
+owner: 水桥
+group: 水
+version: "1.0"
+updated: "2026-03-01"
+---
+
+# 接收短信 Skill
+
+> 从接码网站取号、拿最新短信,命令行完成,不打开网页。 —— 水桥
+
+---
+
+## 一、负责与入口
+
+- **负责人**:水桥(平台对接)
+- **触发词**:接收短信、收短信、receivesms、接码、临时号码、获取短信、拿短信、等刷新拿短信
+- **数据源网站**:**receivesms.co**(英国临时号码列表与收件页,公开、免注册)
+
+---
+
+## 二、要获取的「网站短信」类型说明
+
+本技能最终输出两类信息,请按需使用:
+
+| 输出项 | 含义 | 示例 |
+|:---|:---|:---|
+| **号码** | 当前使用的临时号码(来自 receivesms.co 英国号列表) | +447424907088 |
+| **短信内容** | 该号码收件页上**最新一条**短信的正文 | `[PUBG] code: 697881. Valid for 3 minutes.` |
+| **发件人名字(网站/服务名)** | 页面上显示的发送方标识,即「来自哪个网站/服务的短信」 | TRIBBU、bilibili、AIRBNB、hcloud、WhatsApp 等 |
+
+**当前脚本行为**:只输出**号码 + 最新一条短信正文**;发件人名字在网页上对应 `class="from-link"`,若你需要「只要某类网站/服务发来的短信」(如只要 bilibili、只要验证码类),可在本 Skill 下扩展脚本按发件人或关键词过滤。
+
+**可获取的短信类型(按来源名)**:凡在 receivesms.co 该号码收件页上出现的都会被抓到「最新一条」—— 包括但不限于:验证码类(各 App/网站 OTP)、营销类、通知类;发件人显示为服务名/短号(如 TRIBBU、hcloud、+***5113)。若你要的是「自己刚发过去的那条」,请用 `--wait` 模式(见下)。
+
+---
+
+## 三、整体流程(从取号到拿到短信)
+
+```
+① 请求 receivesms.co 英国号码列表页
+ ↓
+② 随机选取一个临时号码(+44 开头)
+ ↓
+③ [可选] --wait:先输出号码,等待 30~60 秒(你向该号发短信),再请求该号收件页
+ 或无 --wait:直接请求该号收件页
+ ↓
+④ 解析收件页 HTML,取「最新一条」短信正文(
)
+ ↓
+⑤ 输出:NUMBER、SMS(及 号码 | 短信 一行)
+```
+
+---
+
+## 四、执行方式(命令行,不打开网页)
+
+**脚本路径**(工作台内):
+
+```
+运营中枢/scripts/receivesms_get_sms.py
+```
+
+**用法**:
+
+| 模式 | 命令 | 说明 |
+|:---|:---|:---|
+| 立即取最新一条 | `python3 receivesms_get_sms.py` | 可能拿到历史/限流旧短信 |
+| 等刷新后取最新 | `python3 receivesms_get_sms.py --wait` | 先出号,等 45 秒后再抓,适合「你发短信后」拿刚收到的那条 |
+
+**执行目录**:
+
+```bash
+cd /Users/karuo/Documents/个人/卡若AI/运营中枢/scripts
+python3 receivesms_get_sms.py
+# 或
+python3 receivesms_get_sms.py --wait
+```
+
+---
+
+## 五、输出格式
+
+脚本标准输出示例:
+
+```
+NUMBER: +447476933927
+SMS: [PUBG] code: 697881. Valid for 3 minutes.
+---
++447476933927 | [PUBG] code: 697881. Valid for 3 minutes.
+```
+
+- **NUMBER**:当前使用的临时号码(receivesms.co 英国号)。
+- **SMS**:该号码在 receivesms.co 收件页上的**最新一条短信正文**;无短信时为 `(无)`。
+- 最后一行:`号码 | 短信`,便于复制或管道处理。
+
+---
+
+## 六、参考资料与扩展
+
+- **流程史记**:`运营中枢/参考资料/giffgaff发短信收短信_流程史记.md`(giffgaff 发短信到临时号时的操作与保号)。
+- **接码操作说明**:`运营中枢/参考资料/receivesms收短信_操作.md`(命令行用法摘要)。
+- **扩展**:若需按「发件人名字」或关键词过滤短信,可在本目录下扩展脚本(解析 `from-link` 或短信内容),并在本 SKILL 更新「要获取的网站短信类型」说明。
diff --git a/SKILL_REGISTRY.md b/SKILL_REGISTRY.md
index 8d05b903..0c589034 100644
--- a/SKILL_REGISTRY.md
+++ b/SKILL_REGISTRY.md
@@ -1,8 +1,8 @@
# 卡若AI 技能注册表(Skill Registry)
> **一张表查所有技能**。任何 AI 拿到这张表,就能按关键词找到对应技能的 SKILL.md 路径并执行。
-> 63 技能 | 14 成员 | 5 负责人
-> 版本:5.3 | 更新:2026-02-26
+> 64 技能 | 14 成员 | 5 负责人
+> 版本:5.4 | 更新:2026-03-01
---
@@ -89,6 +89,7 @@
| W12 | MCP 搜索与连接 | 水桥 | **MCP、找MCP、连接MCP、MCP搜索、发现MCP、添加MCP、需要MCP、MCP安装、MCP发现、查MCP、装MCP** | `02_卡人(水)/水桥_平台对接/MCP管理/SKILL.md` | 搜索 5000+ MCP 服务器→生成安装配置→写入 Cursor/Claude 等 |
| W13 | Excel表格与日报 | 水桥 | **Excel写飞书、Excel导入飞书、批量写飞书表格、飞书表格导入、CSV写飞书、日报图表发飞书、表格日报** | `02_卡人(水)/水桥_平台对接/飞书管理/Excel表格与日报_SKILL.md` | 本地 Excel/CSV→飞书表格→自动日报图表→发飞书群 |
| W14 | **卡猫复盘** | 水桥 | **卡猫复盘、婼瑄复盘、卡猫今日复盘、婼瑄今日、复盘到卡猫、发卡猫群** | `02_卡人(水)/水桥_平台对接/飞书管理/卡猫复盘/SKILL.md` | 婼瑄目录→目标=今年总目标+完成%+人/事/数具体→飞书+卡猫群 |
+| W15 | **接收短信** | 水桥 | **接收短信、收短信、receivesms、接码、临时号码、获取短信、拿短信、等刷新拿短信** | `02_卡人(水)/水桥_平台对接/接收短信/SKILL.md` | receivesms.co 取英国临时号→命令行抓该号最新一条短信(可 --wait 等刷新);输出号码+短信,含「要获取的网站短信类型」说明 |
## 木组 · 卡木(产品内容创造)
diff --git a/运营中枢/scripts/receivesms_analyze_all.py b/运营中枢/scripts/receivesms_analyze_all.py
new file mode 100644
index 00000000..e3e2e62a
--- /dev/null
+++ b/运营中枢/scripts/receivesms_analyze_all.py
@@ -0,0 +1,156 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+receivesms.co 整站收短信内容分析:拉取英国号列表下所有号码的收件页,汇总全部短信,
+按发件人、类型、关键词做统计并输出分析报告。
+"""
+import re
+import time
+import urllib.request
+from collections import Counter, defaultdict
+
+BASE = "https://www.receivesms.co"
+LIST_URL = BASE + "/british-phone-numbers/gb/"
+
+
+def fetch(url):
+ req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"})
+ with urllib.request.urlopen(req, timeout=20) as r:
+ return r.read().decode("utf-8", errors="replace")
+
+
+def parse_number_list(html):
+ blocks = re.findall(
+ r'href="/gb-phone-number/(\d+)/"[^>]*>.*?
(\+44[\d\s]+)',
+ html,
+ re.DOTALL
+ )
+ return [(mid, num.replace(" ", "").strip()) for mid, num in blocks]
+
+
+def parse_all_sms_in_inbox(html):
+ """解析一页收件页中所有短信:发件人 + 正文。"""
+ # 按 entry 块切:from-link 与紧随其后的 entry-body > div.sms
+ pattern = r'
([^<]*)\s*
'
+ matches = re.findall(pattern, html, re.DOTALL)
+ out = []
+ for sender, raw in matches:
+ text = re.sub(r"<[^>]+>", "", raw)
+ text = text.replace(" ", " ").replace("&", "&").replace("<", "<").replace(">", ">").replace("'", "'")
+ text = " ".join(text.split()).strip()
+ if text:
+ out.append((sender.strip(), text))
+ return out
+
+
+def classify_content(text):
+ """简单分类:验证码/OTP、营销/推广、通知、其他。"""
+ t = text.upper()
+ if any(k in t for k in ["CODE", "OTP", "VERIFICATION", "验证码", "验证", "CODIGO", "KODU"]):
+ return "验证码/OTP"
+ if any(k in t for k in ["PROMO", "OFFER", "DEAL", "SALE", "优惠", "促销", "http", "LINK", ".COM"]):
+ return "营销/推广"
+ if any(k in t for k in ["LOGIN", "CONFIRM", "ALERT", "NOTICE", "通知", "确认"]):
+ return "通知"
+ return "其他"
+
+
+def main():
+ print("正在获取英国号码列表…", flush=True)
+ html_list = fetch(LIST_URL)
+ pairs = parse_number_list(html_list)
+ if not pairs:
+ print("未解析到任何号码")
+ return
+ print(f"共 {len(pairs)} 个号码,开始逐页拉取收件…", flush=True)
+ all_messages = [] # (number, sender, text)
+ for i, (mid, number) in enumerate(pairs):
+ url = f"{BASE}/gb-phone-number/{mid}/"
+ try:
+ html = fetch(url)
+ msgs = parse_all_sms_in_inbox(html)
+ for sender, text in msgs:
+ all_messages.append((number, sender, text))
+ print(f" [{i+1}/{len(pairs)}] {number}: {len(msgs)} 条", flush=True)
+ except Exception as e:
+ print(f" [{i+1}/{len(pairs)}] {number}: 失败 {e}", flush=True)
+ time.sleep(0.8)
+ if not all_messages:
+ print("未采集到任何短信")
+ return
+ # 统计
+ by_sender = Counter(s for _, s, _ in all_messages)
+ by_type = Counter(classify_content(t) for _, _, t in all_messages)
+ keywords = []
+ for _, _, t in all_messages:
+ for w in re.findall(r"[a-zA-Z]{3,}", t):
+ keywords.append(w.lower())
+ kw_top = Counter(keywords).most_common(25)
+ # 输出报告(Markdown)
+ lines = [
+ "# receivesms.co 整站收短信内容分析报告",
+ "",
+ "> 数据来源:receivesms.co 英国临时号码列表下全部号码的收件页;采集时间:一次运行。",
+ "",
+ "## 一、概览",
+ "",
+ f"- **号码数量**:{len(pairs)}",
+ f"- **短信总条数**:{len(all_messages)}",
+ f"- **去重发件人数量**:{len(by_sender)}",
+ "",
+ "## 二、按发件人(网站/服务名)统计",
+ "",
+ "| 发件人 | 条数 |",
+ "|:---|:---|",
+ ]
+ for sender, cnt in by_sender.most_common(40):
+ lines.append(f"| {sender} | {cnt} |")
+ lines.extend([
+ "",
+ "## 三、按内容类型分类",
+ "",
+ "| 类型 | 条数 | 占比 |",
+ "|:---|:---|:---|",
+ ])
+ for typ, cnt in by_type.most_common():
+ pct = round(100 * cnt / len(all_messages), 1)
+ lines.append(f"| {typ} | {cnt} | {pct}% |")
+ lines.extend([
+ "",
+ "## 四、正文高频词(英文,≥3 字母)",
+ "",
+ "| 词 | 出现次数 |",
+ "|:---|:---|",
+ ])
+ for w, c in kw_top:
+ lines.append(f"| {w} | {c} |")
+ lines.extend([
+ "",
+ "## 五、样例短信(每类各 2 条)",
+ "",
+ ])
+ by_type_list = defaultdict(list)
+ for num, sender, text in all_messages:
+ typ = classify_content(text)
+ by_type_list[typ].append((sender, text[:120]))
+ for typ in ["验证码/OTP", "营销/推广", "通知", "其他"]:
+ lines.append(f"### {typ}")
+ lines.append("")
+ for sender, snippet in by_type_list.get(typ, [])[:2]:
+ lines.append(f"- **{sender}**:{snippet}…")
+ lines.append("")
+ report = "\n".join(lines)
+ print("\n" + "=" * 60)
+ print(report)
+ # 写文件
+ out_path = "/Users/karuo/Documents/卡若Ai的文件夹/报告/receivesms_整站收短信内容分析.md"
+ import os
+ os.makedirs(os.path.dirname(out_path), exist_ok=True)
+ with open(out_path, "w", encoding="utf-8") as f:
+ f.write(report)
+ print("=" * 60)
+ print(f"报告已写入:{out_path}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/运营中枢/scripts/receivesms_get_sms.py b/运营中枢/scripts/receivesms_get_sms.py
new file mode 100644
index 00000000..88d3e579
--- /dev/null
+++ b/运营中枢/scripts/receivesms_get_sms.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+receivesms.co 命令行:随机取一个英国临时号码,抓取该号码最新一条短信并输出。
+用法:
+ python3 receivesms_get_sms.py # 立即取最新一条(可能是历史/限流旧数据)
+ python3 receivesms_get_sms.py --wait # 取号 → 等 45 秒 → 再刷新收件页取最新(拿到你刚发的)
+"""
+import re
+import random
+import sys
+import time
+import urllib.request
+
+BASE = "https://www.receivesms.co"
+LIST_URL = BASE + "/british-phone-numbers/gb/"
+
+
+def fetch(url):
+ req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"})
+ with urllib.request.urlopen(req, timeout=15) as r:
+ return r.read().decode("utf-8", errors="replace")
+
+
+def parse_number_list(html):
+ # 每个 card 块内: href="/gb-phone-number/ID/" 与
+44 xxx
+ blocks = re.findall(
+ r'href="/gb-phone-number/(\d+)/"[^>]*>.*?
(\+44[\d\s]+)',
+ html,
+ re.DOTALL
+ )
+ pairs = [(mid, num.replace(" ", "").strip()) for mid, num in blocks]
+ return pairs
+
+
+def parse_latest_sms(html):
+ # 第一条
...
即最新短信
+ m = re.search(r'
(.*?)
', html, re.DOTALL)
+ if not m:
+ return None
+ text = m.group(1).strip()
+ # 去 HTML 实体与多余空白
+ text = re.sub(r"<[^>]+>", "", text)
+ text = text.replace(" ", " ").replace("&", "&").replace("<", "<").replace(">", ">").replace(""", '"')
+ return " ".join(text.split())
+
+
+def main():
+ do_wait = "--wait" in sys.argv
+ try:
+ html_list = fetch(LIST_URL)
+ except Exception as e:
+ print("ERROR: 获取号码列表失败:", e, file=sys.stderr)
+ sys.exit(1)
+ pairs = parse_number_list(html_list)
+ if not pairs:
+ print("ERROR: 未解析到任何号码", file=sys.stderr)
+ sys.exit(1)
+ mid, number = random.choice(pairs)
+ inbox_url = f"{BASE}/gb-phone-number/{mid}/"
+ print("NUMBER:", number)
+ if do_wait:
+ wait_sec = 45 # 30~60 秒取中值,等刷新后的新短信
+ print(f"请向该号码发短信,{wait_sec} 秒后自动刷新收件页…", flush=True)
+ time.sleep(wait_sec)
+ try:
+ html_inbox = fetch(inbox_url)
+ except Exception as e:
+ print("ERROR: 获取收件页失败:", e, file=sys.stderr)
+ sys.exit(1)
+ sms = parse_latest_sms(html_inbox)
+ print("SMS:", sms if sms else "(无)")
+ if sms:
+ print("---")
+ print(number, "|", sms)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/运营中枢/scripts/sora2_generate.py b/运营中枢/scripts/sora2_generate.py
new file mode 100644
index 00000000..8bcf8f25
--- /dev/null
+++ b/运营中枢/scripts/sora2_generate.py
@@ -0,0 +1,173 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+Sora 2 视频生成 API 脚本
+- 创建任务、轮询状态、下载 MP4,一键生成
+- 需环境变量 OPENAI_API_KEY;输出目录:卡若Ai的文件夹/导出/
+"""
+from __future__ import annotations
+
+import os
+import sys
+import time
+import argparse
+from pathlib import Path
+
+try:
+ import requests
+except ImportError:
+ print("请先安装: pip install requests")
+ sys.exit(1)
+
+# 默认输出目录(卡若AI 输出规范)
+OUTPUT_BASE = Path("/Users/karuo/Documents/卡若Ai的文件夹/导出")
+BASE_URL = "https://api.openai.com/v1/videos"
+POLL_INTERVAL = 15
+MAX_POLL_MINUTES = 20
+
+
+def get_api_key() -> str:
+ key = os.environ.get("OPENAI_API_KEY", "").strip()
+ if not key:
+ raise SystemExit("请设置环境变量 OPENAI_API_KEY")
+ return key
+
+
+def create_video(
+ api_key: str,
+ prompt: str,
+ model: str = "sora-2",
+ size: str = "1280x720",
+ seconds: str = "8",
+ input_reference_path: str | None = None,
+) -> dict:
+ """创建视频生成任务,返回 job 对象(含 id、status)。"""
+ headers = {"Authorization": f"Bearer {api_key}"}
+ data = {
+ "prompt": prompt,
+ "model": model,
+ "size": size,
+ "seconds": seconds,
+ }
+ files = None
+ if input_reference_path and os.path.isfile(input_reference_path):
+ mime = "image/jpeg"
+ if input_reference_path.lower().endswith(".png"):
+ mime = "image/png"
+ elif input_reference_path.lower().endswith(".webp"):
+ mime = "image/webp"
+ files = {"input_reference": (os.path.basename(input_reference_path), open(input_reference_path, "rb"), mime)}
+
+ if files:
+ resp = requests.post(BASE_URL, headers=headers, data=data, files=files, timeout=60)
+ for f in files.values():
+ f[1].close()
+ else:
+ resp = requests.post(BASE_URL, headers=headers, data=data, timeout=60)
+
+ resp.raise_for_status()
+ return resp.json()
+
+
+def get_video_status(api_key: str, video_id: str) -> dict:
+ """查询视频任务状态。"""
+ url = f"{BASE_URL}/{video_id}"
+ resp = requests.get(url, headers={"Authorization": f"Bearer {api_key}"}, timeout=30)
+ resp.raise_for_status()
+ return resp.json()
+
+
+def download_video(api_key: str, video_id: str, save_path: Path, variant: str = "video") -> Path:
+ """下载视频/缩略图/雪碧图到 save_path。variant: video | thumbnail | spritesheet"""
+ url = f"{BASE_URL}/{video_id}/content"
+ if variant != "video":
+ url += f"?variant={variant}"
+ resp = requests.get(url, headers={"Authorization": f"Bearer {api_key}"}, stream=True, timeout=120)
+ resp.raise_for_status()
+ save_path.parent.mkdir(parents=True, exist_ok=True)
+ with open(save_path, "wb") as f:
+ for chunk in resp.iter_content(chunk_size=8192):
+ f.write(chunk)
+ return save_path
+
+
+def create_and_download(
+ prompt: str,
+ model: str = "sora-2",
+ size: str = "1280x720",
+ seconds: str = "8",
+ input_reference: str | None = None,
+ output_dir: Path | None = None,
+ poll_interval: int = POLL_INTERVAL,
+ max_wait_minutes: int = MAX_POLL_MINUTES,
+) -> Path:
+ """
+ 创建 Sora 2 视频任务,轮询直到完成,下载 MP4 到 output_dir。
+ 返回最终 MP4 的 Path。
+ """
+ api_key = get_api_key()
+ out = output_dir or OUTPUT_BASE
+ out.mkdir(parents=True, exist_ok=True)
+
+ job = create_video(api_key, prompt, model=model, size=size, seconds=seconds, input_reference_path=input_reference)
+ video_id = job.get("id")
+ if not video_id:
+ raise RuntimeError(f"创建任务失败,无 id: {job}")
+
+ print(f"任务已创建: {video_id},轮询中...")
+ deadline = time.time() + max_wait_minutes * 60
+ while time.time() < deadline:
+ status_obj = get_video_status(api_key, video_id)
+ status = status_obj.get("status", "")
+ progress = status_obj.get("progress", 0)
+ if status == "completed":
+ break
+ if status == "failed":
+ err = status_obj.get("error", {}) or {}
+ raise RuntimeError(f"生成失败: {err.get('message', status_obj)}")
+ print(f" 状态: {status}, 进度: {progress}%")
+ time.sleep(poll_interval)
+
+ if status != "completed":
+ raise RuntimeError("超时未完成,请稍后用 video_id 自行下载")
+
+ # 下载 MP4,文件名含 video_id 前 12 位避免重复
+ short_id = video_id.replace("video_", "")[:12]
+ save_path = out / f"sora2_{short_id}.mp4"
+ download_video(api_key, video_id, save_path, variant="video")
+ print(f"已保存: {save_path}")
+ return save_path
+
+
+def main():
+ parser = argparse.ArgumentParser(description="Sora 2 视频生成:创建任务并下载 MP4")
+ parser.add_argument("prompt", nargs="?", help="视频描述文案(也可用 -p)")
+ parser.add_argument("-p", "--prompt", dest="prompt_opt", help="视频描述文案")
+ parser.add_argument("-m", "--model", default="sora-2", choices=["sora-2", "sora-2-pro"], help="模型")
+ parser.add_argument("-s", "--size", default="1280x720",
+ choices=["720x1280", "1280x720", "1024x1792", "1792x1024"], help="分辨率")
+ parser.add_argument("--seconds", default="8", choices=["4", "8", "12"], help="时长(秒)")
+ parser.add_argument("-i", "--input-reference", help="首帧参考图路径(可选)")
+ parser.add_argument("-o", "--output-dir", type=Path, default=OUTPUT_BASE, help="MP4 输出目录")
+ parser.add_argument("--poll-interval", type=int, default=POLL_INTERVAL, help="轮询间隔(秒)")
+ parser.add_argument("--max-wait", type=int, default=MAX_POLL_MINUTES, help="最长等待(分钟)")
+ args = parser.parse_args()
+
+ prompt = args.prompt_opt or args.prompt
+ if not prompt:
+ parser.error("请提供 prompt(位置参数或 -p/--prompt)")
+
+ create_and_download(
+ prompt=prompt,
+ model=args.model,
+ size=args.size,
+ seconds=args.seconds,
+ input_reference=args.input_reference,
+ output_dir=args.output_dir,
+ poll_interval=args.poll_interval,
+ max_wait_minutes=args.max_wait,
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/运营中枢/参考资料/giffgaff发短信收短信_流程史记.md b/运营中枢/参考资料/giffgaff发短信收短信_流程史记.md
index 3f6c040d..3301eddc 100644
--- a/运营中枢/参考资料/giffgaff发短信收短信_流程史记.md
+++ b/运营中枢/参考资料/giffgaff发短信收短信_流程史记.md
@@ -5,6 +5,16 @@
---
+## 精简版(约 300 字)
+
+**需要什么**:giffgaff SIM(或 eSIM)、插该卡的手机、账户有余额(Pay as you go 需先充值)。
+
+**如何操作**:① 插卡后约 30 分钟内收欢迎短信即激活。② 发短信:手机「信息」App,用 giffgaff 号;英国 +44 7XXX…,中国 +86…。③ 收短信:同一「信息」里看。④ 查余额:giffgaff.com → Log in,手机号+短信验证码(官网不能发/看短信)。⑤ 发不出:设置→蜂窝→运营商选移动/联通;eSIM 或换机后短信中心号改为 +447802002606。
+
+**费用**:发短信约 **0.3 英镑/条**;收短信一般不扣费。保号:**180 天**内余额须有变动(发 1 条短信或充值),否则号可能被收;建议每 5~6 个月发一条到 +447973000186。关语音信箱防扣费:拨号盘输入 ##002#。
+
+---
+
## 一、总览
| 动作 | 入口 | 说明 |
diff --git a/运营中枢/参考资料/receivesms收短信_操作.md b/运营中枢/参考资料/receivesms收短信_操作.md
new file mode 100644
index 00000000..514042fd
--- /dev/null
+++ b/运营中枢/参考资料/receivesms收短信_操作.md
@@ -0,0 +1,15 @@
+# receivesms 收短信 · 命令行用法
+
+## 一键取号 + 取最新短信(不打开网页)
+
+```bash
+cd /Users/karuo/Documents/个人/卡若AI/运营中枢/scripts
+python3 receivesms_get_sms.py
+```
+
+**输出示例**:
+- `NUMBER: +44xxxxxxxxx`:随机到的英国临时号码
+- `SMS: ...`:该号码当前最新一条短信内容(无则显示 `(无)`)
+- 最后一行:`号码 | 短信` 便于复制
+
+数据来源:https://www.receivesms.co 英国号列表与对应收件页,纯命令行抓取。
diff --git a/运营中枢/参考资料/sora2_api_使用说明.md b/运营中枢/参考资料/sora2_api_使用说明.md
new file mode 100644
index 00000000..c3a5a191
--- /dev/null
+++ b/运营中枢/参考资料/sora2_api_使用说明.md
@@ -0,0 +1,71 @@
+# Sora 2 生成 API 使用说明
+
+> 脚本位置:`运营中枢/scripts/sora2_generate.py`
+> 输出目录:`/Users/karuo/Documents/卡若Ai的文件夹/导出/`
+
+## 前置条件
+
+1. **API Key**:需 OpenAI 已开通 Sora 2 权限的账号,在环境变量中设置:
+ ```bash
+ export OPENAI_API_KEY="sk-xxx"
+ ```
+2. **权限说明**:Sora 2 API 目前为预览,需在 [OpenAI 控制台](https://platform.openai.com/) 确认账号已开通 Video API;未开通需联系 OpenAI 申请。
+
+## 命令行用法
+
+```bash
+# 进入工作台
+cd /Users/karuo/Documents/个人/卡若AI
+
+# 仅文本生成(必填 prompt)
+python 运营中枢/scripts/sora2_generate.py "一只橘猫在窗台上打哈欠,阳光洒进来"
+
+# 指定模型、分辨率、时长
+python 运营中枢/scripts/sora2_generate.py "海边日落延时" -m sora-2-pro -s 1792x1024 --seconds 12
+
+# 首帧参考图(图生视频)
+python 运营中枢/scripts/sora2_generate.py "她转身微笑,慢慢走出画面" -i /path/to/sample_720p.jpeg
+```
+
+### 参数一览
+
+| 参数 | 简写 | 默认 | 说明 |
+|:---|:---|:---|:---|
+| prompt | -p | 必填 | 视频描述文案 |
+| model | -m | sora-2 | sora-2 / sora-2-pro |
+| size | -s | 1280x720 | 720x1280 / 1280x720 / 1024x1792 / 1792x1024 |
+| seconds | — | 8 | 4 / 8 / 12 |
+| input-reference | -i | — | 首帧参考图路径(可选) |
+| output-dir | -o | 卡若Ai的文件夹/导出 | MP4 保存目录 |
+| poll-interval | — | 15 | 轮询间隔(秒) |
+| max-wait | — | 20 | 最长等待(分钟) |
+
+## 在代码中调用
+
+```python
+from pathlib import Path
+import sys
+sys.path.insert(0, "/Users/karuo/Documents/个人/卡若AI/运营中枢/scripts")
+from sora2_generate import create_and_download, get_api_key, create_video, get_video_status, download_video
+
+# 一键生成并下载
+out_path = create_and_download(
+ prompt="一只橘猫在窗台上打哈欠",
+ model="sora-2",
+ size="1280x720",
+ seconds="8",
+ output_dir=Path("/Users/karuo/Documents/卡若Ai的文件夹/导出"),
+)
+# out_path 为最终 MP4 路径
+```
+
+## API 端点摘要(直连用)
+
+- **创建任务**:`POST https://api.openai.com/v1/videos`
+ - Content-Type: multipart/form-data
+ - 字段:prompt(必填), model, size, seconds, input_reference(文件可选)
+- **查询状态**:`GET https://api.openai.com/v1/videos/{video_id}`
+- **下载视频**:`GET https://api.openai.com/v1/videos/{video_id}/content`
+ - 可选 `?variant=thumbnail` 或 `?variant=spritesheet`
+
+定价(参考):sora-2 约 $0.10/秒,sora-2-pro 约 $0.30–0.50/秒(按分辨率)。
diff --git a/运营中枢/工作台/gitea_push_log.md b/运营中枢/工作台/gitea_push_log.md
index 70525dda..58e36599 100644
--- a/运营中枢/工作台/gitea_push_log.md
+++ b/运营中枢/工作台/gitea_push_log.md
@@ -171,3 +171,4 @@
| 2026-02-28 06:25:45 | 🔄 卡若AI 同步 2026-02-28 06:25 | 更新:水桥平台对接、卡木、火炬、运营中枢工作台 | 排除 >20MB: 14 个 |
| 2026-02-28 13:25:18 | 🔄 卡若AI 同步 2026-02-28 13:25 | 更新:Cursor规则、金仓、火炬、总索引与入口、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 14 个 |
| 2026-02-28 13:27:29 | 🔄 卡若AI 同步 2026-02-28 13:27 | 更新:火炬、运营中枢工作台 | 排除 >20MB: 14 个 |
+| 2026-03-01 06:14:25 | 🔄 卡若AI 同步 2026-03-01 06:14 | 更新:金盾、水桥平台对接、水溪整理归档、卡木、总索引与入口、运营中枢参考资料、运营中枢工作台、运营中枢技能路由 | 排除 >20MB: 14 个 |
diff --git a/运营中枢/工作台/代码管理.md b/运营中枢/工作台/代码管理.md
index 855e339e..1128a259 100644
--- a/运营中枢/工作台/代码管理.md
+++ b/运营中枢/工作台/代码管理.md
@@ -174,3 +174,4 @@
| 2026-02-28 06:25:45 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-28 06:25 | 更新:水桥平台对接、卡木、火炬、运营中枢工作台 | 排除 >20MB: 14 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-02-28 13:25:18 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-28 13:25 | 更新:Cursor规则、金仓、火炬、总索引与入口、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 14 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-02-28 13:27:29 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-28 13:27 | 更新:火炬、运营中枢工作台 | 排除 >20MB: 14 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
+| 2026-03-01 06:14:25 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-01 06:14 | 更新:金盾、水桥平台对接、水溪整理归档、卡木、总索引与入口、运营中枢参考资料、运营中枢工作台、运营中枢技能路由 | 排除 >20MB: 14 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |