🔄 卡若AI 同步 2026-03-23 20:12 | 更新:金仓、水桥平台对接、卡木、运营中枢、运营中枢工作台 | 排除 >20MB: 11 个

This commit is contained in:
2026-03-23 20:12:40 +08:00
parent 4f61065164
commit 7ab44e4704
8 changed files with 255 additions and 123 deletions

View File

@@ -1,13 +1,37 @@
{
"updated": "2026-03-23T08:37:37.372613+00:00",
"updated": "2026-03-23T12:12:36.198299+00:00",
"conversations": [
{
"对话ID": "6afeb85a-5117-478f-a216-b3bfebae5b51",
"名称": "信用卡请求",
"项目": "卡若AI",
"首条消息": "卡若ai把我的信用卡发给我",
"创建时间": "2026-03-23T12:09:02.290000+00:00",
"消息数量": 13
},
{
"对话ID": "462c354b-4f31-4180-9069-aad14a8a0937",
"名称": "卡若ai 邮箱注册",
"项目": "卡若AI",
"首条消息": "卡若ai 用skill注册一个邮箱",
"创建时间": "2026-03-23T12:03:58.396000+00:00",
"消息数量": 10
},
{
"对话ID": "5d22bebc-ecf7-46b2-aede-bea3b0b14d93",
"名称": "Rule configuration UI in admin panel",
"项目": "Soul创业",
"首条消息": "In the project at /Users/karuo/Documents/开发/3、自营项目/一场soul的创业实验-永平, I need to understand the rule configuration UI in the admin panel.\n\n1. Search for \"UserRule\" or \"user-rules\" or \"规则配置\" in the admin frontend (soul-admin/src/)\n2. The rules tab is in UsersPage.tsx - find the \"rules\" TabsContent section and report the full JSX for it\n3. Read the existing rules CRUD UI - how are rules listed, created, edited?\n4. Check if descriptions are currently shown inline\n\nReport all findings with exact line nu",
"创建时间": "2026-03-23T10:14:23.470000+00:00",
"消息数量": 18
},
{
"对话ID": "4ef4d028-04ea-4ea1-b7ce-e43b353b10ca",
"名称": "Web CLI skill integration",
"项目": "卡若AI",
"首条消息": "上面搜索网页cli的 skill。GitHub 上面搜索最新的网页,西游记分数最高的那个,然后帮我整合到卡罗伊的 skill 里面",
"创建时间": "2026-03-23T08:19:23.549000+00:00",
"消息数量": 127
"消息数量": 129
},
{
"对话ID": "f8f37966-e2ff-42a0-90bc-a28c005698c6",
@@ -216,30 +240,6 @@
"首条消息": "那个告诉我的注册信用卡的 skill然后把这个我最近注册的卡发给我",
"创建时间": "2026-03-20T23:40:45.815000+00:00",
"消息数量": 13
},
{
"对话ID": "93c2142a-5a2a-46c4-ba71-a09d3b195215",
"名称": "AI Brain project exploration",
"项目": "微信管理",
"首条消息": "I need to explore the AI Brain related code and scripts in the work phone project. Please find and summarize:\n\n1. All files related to AI Brain in the project at /Users/karuo/Documents/开发/2、私域银行/工作手机/\n2. All skill files under sdk/agent/skills/ - what skills exist and their actions\n3. The ai_brain module if it exists under sdk/agent/\n4. The index.html smart engine / AI Brain section (search for \"智能引擎\" or \"AI Brain\" in the static files)\n5. Any existing scripts or automation modules\n6. The wechat_h",
"创建时间": "2026-03-20T16:31:04.926000+00:00",
"消息数量": 1
},
{
"对话ID": "f756e455-b371-44e7-841e-ada153aefeee",
"名称": "WeChat account and device management UI",
"项目": "微信管理",
"首条消息": "You need to explore the Cunkebao v3 frontend project at `/Users/karuo/Documents/开发/2、私域银行/cunkebao_v3/Cunkebao/src` to understand how they design their WeChat account management and device management UI.\n\nSpecifically, look at these areas:\n1. `pages/mobile/mine/wechat-accounts/` - WeChat accounts list and detail pages\n2. `pages/mobile/mine/workphone/` - Work phone / device management pages \n3. `pages/mobile/mine/devices/` - Device management pages\n4. `components/DeviceSelection/` - Device selec",
"创建时间": "2026-03-20T15:18:46.161000+00:00",
"消息数量": 1
},
{
"对话ID": "1aa14661-39a1-4bb8-a189-e986cbbb233a",
"名称": "工作手机项目文件搜索",
"项目": "开发",
"首条消息": "在工作手机项目中,搜索以下内容并返回关键信息:\n\n1. 找到 `机擎/阿机/SKILL.md` 文件,返回其中关于 Hook/Frida 相关的部分\n2. 找到 `sdk/app/routers/unified.py` 中关于设备管理和 hook 相关的路由定义\n3. 找到 `sdk/app/services/hook_module_service.py` 的内容摘要\n4. 找到 `开发文档/8、部署/README.md` 的内容\n5. 找到 `机擎/SKILL.md` 中 § 一 岗位职责部分\n\n搜索目录: /Users/karuo/Documents/开发/2、私域银行/工作手机\n\n返回每个文件的关键内容和路径。",
"创建时间": "2026-03-20T14:46:24.917000+00:00",
"消息数量": 18
}
]
}

View File

@@ -26,10 +26,27 @@
| 电话 | `400-9030057` 客户服务;`400-9030142` 为不良信息举报专线 |
| 官网 | <https://www.soulapp.cn/contact> |
**发信**11 位手机号为绑定号,两版话术
**发信**11 位手机号为绑定号,单封大白话
`python3 运营中枢/scripts/send_soul_appeal_mail.py 15210897710`
`python3 运营中枢/scripts/send_soul_appeal_mail.py 13779954946`
**平台短信引用条款后的「分主题补充申诉」**(每号连发 4 封不同主题至同一批邮箱,间隔约 3 秒):
`python3 运营中枢/scripts/send_soul_appeal_mail.py 15210897710 --suite`
`python3 运营中枢/scripts/send_soul_appeal_mail.py --all-phones --suite`152 + 137 各 4 封,共 8 封)
### Soul《用户协议》被引用条款怎么理解辅助说明以 App 内最新版为准)
官方短信常见表述:违反 **2.2.3、2.2.4、2.2.5、3.2.1118、3.2.12** 等。
| 条款 | 常见含义(概括) | 备注 |
|:---|:---|:---|
| **2.2.3 / 2.2.4** | 与 **2.2** 节「用户使用账号时应遵守的义务」相关,多涉及**守法、不得干扰平台秩序**等 | 公开网页难逐字核对,**务必在 Soul App → 设置 → 关于 Soul → 用户协议** 打开当前版本对照 |
| **2.2.5** | 黑猫投诉等渠道有用户转述:不得利用账号**违法活动、捣乱、骚扰、欺骗其他用户**及**其他违反本协议的行为** | 与「骚扰/欺诈/破坏秩序」类处罚常一并出现 |
| **3.2.1118** | 多为**禁止发布或传播的信息类型**的**前八项列举**(如违法有害、低俗、侵权、虚假、营销导流等方向,**具体以协议原文分项为准** | 平台若未告知触线子项,可邮件请求**指明项号与事实概要**以便整改 |
| **3.2.12** | 常与 3.2.11 同属**内容与行为规范**,多为**并列或递进的禁止性规定**(以原文为准) | 再申诉宜写清**整改承诺**,避免空怼 |
**策略**:申诉未通过后,宜 **请求具体违规事实** + **分项承诺合规** + **申请二次复核****不能保证**一定解封。
---
## 二、抖音

View File

@@ -137,6 +137,11 @@ class EmailService:
if self.email_type == "tempmail":
return self._gen_tempmail()
elif self.email_type == "mailtm":
fixed = self._mailtm_fixed_credentials()
if fixed:
addr, pwd = fixed
log.info("[邮箱] 使用固定 mail.tmMAILTM_ADDRESS 或 config.mailtm.fixed_*")
return self._mailtm_login(addr, pwd)
return self._gen_mailtm()
elif self.email_type == "cloudflare_worker":
return self._gen_cf_worker()
@@ -151,29 +156,33 @@ class EmailService:
email = f"{prefix}{random_suffix}@tempmail.plus"
return email, {"type": "tempmail", "pin": cfg.get("pin", "")}
def _gen_mailtm(self) -> tuple[str, dict]:
"""mail.tm API 创建临时邮箱,可收验证码(与 Cerebras 同源)"""
def _mailtm_fixed_credentials(self) -> Optional[tuple[str, str]]:
"""环境变量或 config.mailtm 固定账号,供 Cursor 等复用已创建的 mail.tm。"""
cfg = self.config.get("mailtm") or {}
addr = (os.environ.get("MAILTM_ADDRESS") or cfg.get("fixed_address") or "").strip()
pwd = (os.environ.get("MAILTM_PASSWORD") or cfg.get("fixed_password") or "").strip()
if addr and pwd:
return addr, pwd
return None
def _mailtm_login(self, address: str, password: str) -> tuple[str, dict]:
import httpx
api = "https://api.mail.tm"
r = httpx.get(f"{api}/domains", timeout=10)
domains = r.json().get("hydra:member", [])
if not domains:
raise RuntimeError("mail.tm 无可用域名")
domain = domains[0]["domain"]
prefix = "".join(random.choices(string.ascii_lowercase + string.digits, k=12))
email = f"{prefix}@{domain}"
password = "".join(random.choices(string.ascii_letters + string.digits, k=16))
r = httpx.post(f"{api}/accounts", json={"address": email, "password": password}, timeout=15)
if r.status_code not in (200, 201):
raise RuntimeError(f"mail.tm 创建账号失败: {r.status_code} {r.text[:100]}")
r = httpx.post(f"{api}/token", json={"address": email, "password": password}, timeout=10)
t = 25
r = httpx.post(
f"{api}/token",
json={"address": address, "password": password},
timeout=t,
)
if r.status_code != 200:
raise RuntimeError("mail.tm 获取 token 失败")
raise RuntimeError(f"mail.tm 登录/token 失败: {r.status_code} {r.text[:120]}")
token = r.json().get("token", "")
return email, {"type": "mailtm", "token": token}
if not token:
raise RuntimeError("mail.tm 返回空 token")
return address, {"type": "mailtm", "token": token}
def _gen_mailtm(self) -> tuple[str, dict]:
"""mail.tm API 建临时邮箱,可收 Cursor 等验证码"""
"""mail.tm API 建临时邮箱Cursor / Cerebras 等同源)"""
import httpx
api = "https://api.mail.tm"
t = 25
@@ -188,38 +197,7 @@ class EmailService:
r = httpx.post(f"{api}/accounts", json={"address": email, "password": password}, timeout=t)
if r.status_code not in (200, 201):
raise RuntimeError(f"mail.tm 创建失败: {r.status_code} {r.text[:80]}")
r = httpx.post(f"{api}/token", json={"address": email, "password": password}, timeout=t)
if r.status_code != 200:
raise RuntimeError(f"mail.tm token 失败: {r.status_code}")
token = r.json().get("token", "")
return email, {"type": "mailtm", "token": token}
def _poll_mailtm(self, context: dict, timeout: int) -> Optional[str]:
"""轮询 mail.tm 收件箱提取 6 位验证码"""
import httpx
token = context.get("token", "")
if not token:
return None
headers = {"Authorization": f"Bearer {token}"}
api = "https://api.mail.tm"
start = time.time()
while time.time() - start < timeout:
try:
r = httpx.get(f"{api}/messages", headers=headers, timeout=10)
for msg in r.json().get("hydra:member", []):
mid = msg.get("id", "")
if not mid:
continue
d = httpx.get(f"{api}/messages/{mid}", headers=headers, timeout=10).json()
subject = d.get("subject", "")
text = d.get("text", "") or (d.get("html") or [""])[0] if isinstance(d.get("html"), list) else ""
code = self._extract_code(subject, text)
if code:
return code
except Exception as e:
log.warning(f"[邮箱] mail.tm 轮询异常: {e}")
time.sleep(3)
return None
return self._mailtm_login(email, password)
def _gen_cf_worker(self) -> tuple[str, dict]:
import httpx
@@ -363,14 +341,23 @@ class EmailService:
return None
def _extract_code(self, subject: str, body: str) -> Optional[str]:
"""从邮件主题和正文中提取 6 位 OTP"""
"""从邮件主题和正文中提取 6 位 OTP(正文可为 HTML"""
import re as _re
def _strip_html(s: str) -> str:
return _re.sub(r"<[^>]+>", " ", s or "")
plain = (body or "") + "\n" + _strip_html(body or "")
precise = self.RE_CODE_PRECISE.search(subject)
if precise:
return precise.group(1)
precise = self.RE_CODE_PRECISE.search(body)
precise = self.RE_CODE_PRECISE.search(plain)
if precise:
return precise.group(1)
match = self.RE_OTP.search(subject)
if match:
return match.group(1)
match = self.RE_OTP.search(plain)
if match:
return match.group(1)
return None

View File

@@ -58,6 +58,13 @@ class CursorProvider(BaseProvider):
self.provider_config = config.get("providers", {}).get("cursor", {})
self.browser_config = config.get("browser", {})
def _effective_headless(self) -> bool:
"""CURSOR_HEADLESS=0|false|no 时强制有界面,利于 Turnstile。"""
v = os.environ.get("CURSOR_HEADLESS", "").strip().lower()
if v in ("0", "false", "no", "off"):
return False
return self.browser_config.get("headless", True)
def _create_browser(self):
# 参考 ddCat-main/cursor-auto-register browser_utilsauto_port() + headless()
from DrissionPage import ChromiumPage, ChromiumOptions
@@ -70,7 +77,7 @@ class CursorProvider(BaseProvider):
co.set_argument("--remote-allow-origins=*")
co.set_argument("--window-size=1920,1080")
co.auto_port()
use_headless = self.browser_config.get("headless", True)
use_headless = self._effective_headless()
if use_headless:
co.set_argument("--headless=new")
co.headless(use_headless)
@@ -95,7 +102,7 @@ class CursorProvider(BaseProvider):
return None
signup_url = self.provider_config.get("signup_url", SIGNUP_URL)
settings_url = self.provider_config.get("settings_url", SETTINGS_URL)
headless = self.browser_config.get("headless", True)
headless = self._effective_headless()
with sync_playwright() as p:
browser = p.chromium.launch(headless=headless, args=["--no-sandbox"])
try:
@@ -103,22 +110,21 @@ class CursorProvider(BaseProvider):
page.goto(signup_url, wait_until="domcontentloaded", timeout=45000)
time.sleep(5)
log.info(f" [1/6] 打开注册页面 (Playwright)")
page.wait_for_selector('input', state="visible", timeout=25000)
time.sleep(1)
inputs = page.locator('input[type="text"], input[type="email"], input:not([type])')
n = inputs.count()
if n >= 3:
inputs.nth(0).fill(first)
time.sleep(0.15)
inputs.nth(1).fill(last)
time.sleep(0.15)
inputs.nth(2).fill(email)
else:
page.locator('input[name="first_name"], input[name="firstName"]').first.fill(first)
time.sleep(0.15)
page.locator('input[name="last_name"], input[name="lastName"]').first.fill(last)
time.sleep(0.15)
page.locator('input[name="email"], input[type="email"]').first.fill(email)
# 勿用裸 input否则会命中 type=hidden如 signals
fn = page.locator(
'input[name="first_name"], input[name="firstName"], input[autocomplete="given-name"]'
).first
fn.wait_for(state="visible", timeout=45000)
time.sleep(0.5)
fn.fill(first)
time.sleep(0.15)
page.locator(
'input[name="last_name"], input[name="lastName"], input[autocomplete="family-name"]'
).first.fill(last)
time.sleep(0.15)
page.locator(
'input[name="email"], input[type="email"], input[autocomplete="email"]'
).first.fill(email)
time.sleep(0.5)
page.locator('button[type="submit"], input[type="submit"], [type="submit"]').first.click()
time.sleep(3)

View File

@@ -2,9 +2,11 @@
"""从卡若 gateway .env 读 SMTP向 Soul 官方各邮箱发申诉邮件。
收件人soul@、hr@、ad@、commercial-b@、pc@(官网公示的 5 个邮箱)。
用法:
python3 send_soul_appeal_mail.py 15210897710 # 大白话 A
python3 send_soul_appeal_mail.py 13779954946 # 大白话 B 版
python3 send_soul_appeal_mail.py 15210897710 # 单封(大白话 A/B
python3 send_soul_appeal_mail.py 13779954946 --suite # 针对「条款引用」连发 4 封不同主题
python3 send_soul_appeal_mail.py --all-phones --suite # 152+137 各发 4 封(共 8 封)
不在终端打印密码。
"""
@@ -13,11 +15,11 @@ from __future__ import annotations
import os
import smtplib
import sys
import time
from email.message import EmailMessage
from pathlib import Path
DEFAULT_ENV = Path(__file__).resolve().parent / "karuo_ai_gateway" / ".env"
# Soul 官网公示的官方邮箱,用户要求账号申诉一并抄送
TO_LIST = [
"soul@soulapp.cn",
"hr@soulapp.cn",
@@ -25,6 +27,7 @@ TO_LIST = [
"commercial-b@soulapp.cn",
"pc@soulapp.cn",
]
DEFAULT_PHONES = ("15210897710", "13779954946")
def load_env_file(path: Path) -> None:
@@ -43,7 +46,6 @@ def load_env_file(path: Path) -> None:
def appeal_variant_a(phone: str) -> tuple[str, str]:
"""152 绑定号:分条 + 大白话。"""
subject = f"求助Soul账号被限制求人工复核手机{phone}"
body = f"""Soul 客服您好,
@@ -65,7 +67,6 @@ def appeal_variant_a(phone: str) -> tuple[str, str]:
def appeal_variant_b(phone: str) -> tuple[str, str]:
"""137 绑定号:另一套大白话(叙述流,同目的)。"""
subject = f"想申请恢复账号|绑定手机{phone}"
body = f"""您好,
@@ -90,15 +91,120 @@ def pick_variant(phone: str) -> tuple[str, str]:
return appeal_variant_b(phone)
def suite_appeals(phone: str) -> list[tuple[str, str]]:
"""针对平台短信引用 2.2.3、2.2.4、2.2.5、3.2.11(1-8)、3.2.12 的补充申诉(分封主题,避免一封过长)。"""
cite = "2.2.3、2.2.4、2.2.5、3.2.111-8、3.2.12"
return [
(
f"【二次申诉】绑定手机{phone}|已收贵司条款引用,恳请书面告知具体违规事实",
f"""Soul 客服团队您好,
我的绑定手机号为 {phone}。此前收到贵司通知,称申诉未通过,并引用《用户协议》{cite} 等条款。
本人已重新阅读 App 内《用户协议》相关章节,愿意遵守平台规则。但目前仍不清楚:**具体是哪一类行为、哪一条动态/私信/场景**触发了上述条款的适用,导致封号。没有可操作的违规事实说明,我无法完成针对性整改,也难以判断是否存在误判。
故恳请贵司在合规前提下,通过邮件或站内途径告知:**违规内容类型、大致时间、对应功能场景**(无需泄露他人隐私即可)。本人承诺在知悉后立刻整改,并申请**二次人工复核**。
回复请发至本邮件发件邮箱,亦可致电我登记号码 {phone}(如可外呼)。
感谢。
账号持有人({phone}
""",
),
(
f"【分项说明】绑定手机{phone}关于第2.2.3、2.2.4、2.2.5条之理解与承诺",
f"""Soul 客服您好,
绑定手机 {phone}。现就贵司援引的协议第 2.2.3、2.2.4、2.2.5 条说明如下:
据公开渠道中用户对 2.2.5 条的转述,该款大意包含:**不得利用账号从事违法活动、捣乱、骚扰、欺骗其他用户及违反协议的行为**。2.2.3、2.2.4 与同节条款通常指向**守法使用账号、维护平台秩序**等义务(**具体以本人 App 内当前版本《用户协议》原文为准**)。
本人确认:**无故意从事违法、欺诈、恶意骚扰或破坏社区秩序的主观意图**;若曾有言行被系统判定越界,愿在贵司指出具体事实后**立即纠正**,并加强自我约束。
恳请结合上述说明,对账号是否具备**从轻、整改后恢复**的空间予以复核。
账号持有人 {phone}
""",
),
(
f"【分项说明】绑定手机{phone}关于第3.2.11条第1-8项之合规承诺",
f"""Soul 客服您好,
绑定手机 {phone}。贵司通知中援引 3.2.11 条第18项。该类条款在实务中一般对应**禁止发布的多类违规信息**(如违法有害、低俗、人身攻击、虚假误导、侵权、违规营销导流等,**具体子项以 App 内协议原文为准**)。
本人承诺:
• 不在平台发布违反法律法规及《Soul 用户行为规范》的信息;
• 不从事恶意营销、刷屏骚扰、诱导站外交易或欺诈等行为;
• 对他人与平台保持尊重,不故意散布不实信息。
若贵司认定本人曾违反上述任一项,请**指明对应项号与事实概要**,本人愿删除相关内容、书面说明情况并申请复核。
账号持有人 {phone}
""",
),
(
f"【分项说明】绑定手机{phone}关于第3.2.12条及持续合规使用承诺",
f"""Soul 客服您好,
绑定手机 {phone}。就贵司一并援引的第 3.2.12 条,本人理解其通常与 3.2.11 等条款共同构成**内容与安全规范**体系(**以 App 内最新协议为准**)。
本人承诺后续将:
• 发帖、聊天、匹配互动前对照《用户行为规范》自查;
• 不参与灰产引流、不当交友诱导、违规广告等行为;
• 配合贵司合理的内容管理与身份核验要求。
鉴于此前申诉未通过,本人仍恳请贵司在本人**已表态整改、愿配合说明**的前提下,考虑是否给予**观察期、限制解除或账号恢复**的机会。
联系:本邮件发件地址;手机 {phone}
账号持有人
""",
),
]
def send_one(
host: str,
port: int,
user: str,
password: str,
subject: str,
body: str,
) -> None:
msg = EmailMessage()
msg["Subject"] = subject
msg["From"] = user
msg["To"] = ", ".join(TO_LIST)
msg.set_content(body)
with smtplib.SMTP_SSL(host, port, timeout=30) as smtp:
smtp.login(user, password)
smtp.send_message(msg)
def main() -> int:
phone = (sys.argv[1] if len(sys.argv) > 1 else "").strip()
if not phone:
print("用法: python3 send_soul_appeal_mail.py <11位手机号>", file=sys.stderr)
print("示例: … 15210897710 或 … 13779954946", file=sys.stderr)
return 1
if not phone.isdigit() or len(phone) != 11:
print("手机号须为 11 位数字", file=sys.stderr)
return 1
args = [a for a in sys.argv[1:] if not a.startswith("--")]
flags = {a for a in sys.argv[1:] if a.startswith("--")}
suite = "--suite" in flags
all_phones = "--all-phones" in flags
if all_phones:
phones = list(DEFAULT_PHONES)
else:
phone = (args[0] if args else "").strip()
if not phone:
print(
"用法:\n"
" python3 send_soul_appeal_mail.py <11位手机号>\n"
" python3 send_soul_appeal_mail.py <手机号> --suite\n"
" python3 send_soul_appeal_mail.py --all-phones --suite",
file=sys.stderr,
)
return 1
if not phone.isdigit() or len(phone) != 11:
print("手机号须为 11 位数字", file=sys.stderr)
return 1
phones = [phone]
env_path = Path(os.environ.get("KARUO_SMTP_ENV", str(DEFAULT_ENV)))
load_env_file(env_path)
@@ -109,27 +215,29 @@ def main() -> int:
port = int(os.environ.get("SMTP_PORT", "465") or "465")
if not user or not password:
print("错误:未从环境或", env_path, "读取到 SMTP_USER / SMTP_PASS", file=sys.stderr)
print("错误:未读取到 SMTP_USER / SMTP_PASS", env_path, file=sys.stderr)
return 1
subject, body = pick_variant(phone)
msg = EmailMessage()
msg["Subject"] = subject
msg["From"] = user
msg["To"] = ", ".join(TO_LIST)
msg.set_content(body)
try:
with smtplib.SMTP_SSL(host, port, timeout=30) as smtp:
smtp.login(user, password)
smtp.send_message(msg)
n_sent = 0
for phone in phones:
if suite:
pairs = suite_appeals(phone)
else:
pairs = [pick_variant(phone)]
for subject, body in pairs:
send_one(host, port, user, password, subject, body)
n_sent += 1
print("OK", n_sent, subject[:56] + ("" if len(subject) > 56 else ""))
if suite and len(pairs) > 1:
time.sleep(3)
print("共发送", n_sent, "封 →", ", ".join(TO_LIST))
except Exception as e:
print("发送失败:", type(e).__name__, str(e), file=sys.stderr)
return 2
print("已发送至", len(TO_LIST), "个邮箱:", ", ".join(TO_LIST))
print("主题:", subject)
return 0

View File

@@ -430,3 +430,4 @@
| 2026-03-23 16:22:10 | 🔄 卡若AI 同步 2026-03-23 16:22 | 更新:金仓、水溪整理归档、卡木、总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 |
| 2026-03-23 16:22:19 | 🔄 卡若AI 同步 2026-03-23 16:22 | 更新:总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 |
| 2026-03-23 16:35:47 | 🔄 卡若AI 同步 2026-03-23 16:35 | 更新Cursor规则、金仓、卡人、水溪整理归档、火炬、总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 |
| 2026-03-23 16:37:40 | 🔄 卡若AI 同步 2026-03-23 16:37 | 更新Cursor规则、金仓、水溪整理归档、总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 |

View File

@@ -433,3 +433,4 @@
| 2026-03-23 16:22:10 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-23 16:22 | 更新:金仓、水溪整理归档、卡木、总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-03-23 16:22:19 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-23 16:22 | 更新:总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-03-23 16:35:47 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-23 16:35 | 更新Cursor规则、金仓、卡人、水溪整理归档、火炬、总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-03-23 16:37:40 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-23 16:37 | 更新Cursor规则、金仓、水溪整理归档、总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |

View File

@@ -123,4 +123,16 @@
---
## 十、卡若 AI 网站(官网)对接阿猫 OpenClaw 网关
| 项目 | 说明 |
|------|------|
| **环境变量** | \`开发/3、自营项目/卡若ai网站/site/.env.local\` 已配置 \`OPENCLAW_GATEWAY_URL\`(默认 \`http://macbook.quwanzhi.com:18789\`)、\`OPENCLAW_GATEWAY_TOKEN\`(与阿猫 \`~/.openclaw/openclaw.json\` 中 \`gateway.auth.token\` 一致)、\`OPENCLAW_GATEWAY_MODEL\` 等。 |
| **Mongo** | \`storage-mongo\` 在初始化网关后会 **upsert** \`gw-openclaw-amiao\`展示名OpenClaw·阿猫笔记本龙虾。 |
| **路由** | 官网 \`gateway-router\` 对 \`claude*\` 模型在有该网关 Key 时 **优先** 走阿猫 OpenClaw。 |
| **Docker** | \`卡若ai网站/docker-compose.yml\` 已传入上述变量;生产环境须保证 **容器能访问** 阿猫网关地址(非把阿猫的 127.0.0.1 当本机)。 |
| **控制台** | 管理员 POST \`/api/gateway/sync-keys\` 时也会从环境变量合并 \`gw-openclaw-amiao\`。 |
---
*文档生成卡若AI 工作台。*