🔄 卡若AI 同步 2026-03-02 13:43 | 更新:Cursor规则、金仓、水桥平台对接、总索引与入口、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 14 个
This commit is contained in:
@@ -19,16 +19,9 @@ alwaysApply: true
|
||||
1. **读 `BOOTSTRAP.md`**(根目录)— 身份、团队、执行流程、全局规则
|
||||
2. **读 `SKILL_REGISTRY.md`**(根目录)— 按用户需求查找技能
|
||||
3. **读 `个人/1、卡若:本人/记忆.md`** — 长期偏好与沉淀(单文件,无子目录)
|
||||
4. **读 `运营中枢/工作台/运行模式.md`** — 若「当前模式」为 `max`,则本对话按 **MAX 模式** 执行(思考与拆解更充分、全栈开发优先实施计划+TDD+两阶段评审、复盘更详细);详见 `运营中枢/参考资料/卡若AI运行模式说明.md`
|
||||
5. 匹配到技能后读对应 `SKILL.md` 执行
|
||||
4. 匹配到技能后读对应 `SKILL.md` 执行
|
||||
|
||||
## 运行模式切换(与 Auto/MAX Mode 对应)
|
||||
|
||||
- **切到 MAX**:用户说「开MAX模式」「切换MAX」「用MAX」「MAX模式」→ 将 `运营中枢/工作台/运行模式.md` 中「当前模式」改为 `max` 并保存,回复已切换。
|
||||
- **切回 Auto**:用户说「切回Auto」「用Auto」「自动模式」→ 将「当前模式」改为 `auto` 并保存,回复已切换。
|
||||
- **查询**:用户说「当前什么模式」「运行模式」→ 读该文件,回复当前为 Auto 或 MAX。
|
||||
|
||||
行为差异见 `运营中枢/参考资料/卡若AI运行模式说明.md`。
|
||||
**MAX Mode**:卡若AI 每次调用均为 MAX Mode,定义在**卡若AI 本体** `BOOTSTRAP.md` 第四节(MAX Mode)与第五节(执行流程),不在此重复;本文件仅补充 Cursor 特有行为。
|
||||
|
||||
## 异常处理与红线(强制)
|
||||
|
||||
@@ -36,22 +29,14 @@ alwaysApply: true
|
||||
|
||||
## 强制对话流程(每次对话必守)
|
||||
|
||||
### 第一步:先思考,在对话中展示拆解与计划
|
||||
- 接到任务后**先深度思考/调研**:结合所有成员能力(5 负责人、14 成员、53 技能),想清楚目标、谁干、怎么干、可能卡点。
|
||||
- **必须在对话里先展示**:① 思考结果(调研后的结论)② 任务拆解(1、2、3… 具体步骤)③ 执行计划,**再继续执行**。禁止不展示拆解直接动手。
|
||||
### 第一步~第四步(执行流程与 MAX Mode)
|
||||
- 执行流程、思考与拆解、验证与复盘**以 `BOOTSTRAP.md` 第四节(MAX Mode)与第五节(执行流程)为准**,卡若AI 每次调用均为 MAX Mode,此处不重复。
|
||||
|
||||
### 第二步:执行后反复验证
|
||||
- 执行完**必须验证**:结果是否与用户一开始的命令/目标匹配。
|
||||
- **不匹配** → 回溯 → 搜索(GitHub、Skill、网上)找方案 → 再思考(简洁输出)→ 再执行 → 再验证,直到成功或明确说明无法达成。
|
||||
|
||||
### 第三步:回复形式 = 强制复盘(卡若AI 内所有对话必守)
|
||||
- **卡若AI 内所有对话的 AI 回复一律采用「复盘形式」——此为强制行为,无例外。** 复盘格式**永远只有一种**,按 `运营中枢/参考资料/卡若复盘格式_固定规则.md`:
|
||||
- 复盘块标题必须写**具体日期**和**具体时间**(当次回复时的真实 **YYYY-MM-DD HH:mm**,如 2026-03-01 15:20),日期、时间都要写上去,不能写占位符;
|
||||
- 五块齐全,**每块用小图标识别**:🎯 目标·结果·达成率 · 📌 过程 · 💡 反思 · 📝 总结 · ▶ 下一步执行;
|
||||
- **复盘块内不用表格**;目标·结果·达成率整行 ≤30 字,含达成率 XX%;
|
||||
- **日期时间与块标题用 Markdown 粗体**(如 **2026-03-01 15:20**、**🎯 目标·结果·达成率**),禁止用 HTML 标签,否则 Cursor 等场景会露标;详见 `卡若复盘格式_固定规则.md`;
|
||||
- 回复正文可适当用图标(✅❌📁🔗⚠️ 等)增强可读性;下一步须结合本对话与项目/卡若AI 目标、关联未完成项、以实现目标为核心。
|
||||
- 格式与书写要求见:`运营中枢/参考资料/卡若复盘格式_固定规则.md`。
|
||||
### 复盘格式(Cursor 内强制)
|
||||
- **卡若AI 内所有对话的 AI 回复一律采用「复盘形式」——此为强制行为,无例外。** 按 `运营中枢/参考资料/卡若复盘格式_固定规则.md`:
|
||||
- 复盘块标题必须写**具体日期**和**具体时间**(当次回复时的真实 **YYYY-MM-DD HH:mm**),五块齐全(🎯📌💡📝▶);**复盘块内不用表格**;目标·结果·达成率整行 ≤30 字;日期时间与块标题用 Markdown 粗体,禁止 HTML 标签;
|
||||
- 下一步须结合本对话与项目/卡若AI 目标、关联未完成项。
|
||||
- 格式详见:`运营中枢/参考资料/卡若复盘格式_固定规则.md`。
|
||||
|
||||
### 对外输出目录(强制)
|
||||
- 报告、复盘存档、执行日志、导出文件、**生成图片** → 只写 `/Users/karuo/Documents/卡若Ai的文件夹/` 下对应子目录;**图片** → `图片/`,并在 `图片/图片索引.md` 登记来源 Skill、生成者;经验沉淀仍写 `02_卡人(水)/水溪_整理归档/经验库/待沉淀/`。详见 `运营中枢/参考资料/输出目录规范.md`。
|
||||
|
||||
133
01_卡资(金)/金仓_存储备份/服务器管理/scripts/腾讯云_TAT_wzdj_拉取构建并重启.py
Normal file
133
01_卡资(金)/金仓_存储备份/服务器管理/scripts/腾讯云_TAT_wzdj_拉取构建并重启.py
Normal file
@@ -0,0 +1,133 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
腾讯云 TAT:kr宝塔 上对 wzdj 执行 git pull、pnpm install、pnpm build、宝塔 Node 重启
|
||||
确保 https://wzdj.quwanzhi.com 跑最新代码。需先 push 到 GitHub/Gitea,服务器拉取。
|
||||
"""
|
||||
import base64
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
|
||||
KR_INSTANCE_ID = "ins-aw0tnqjo"
|
||||
REGION = "ap-guangzhou"
|
||||
WZDJ_DIR = "/www/wwwroot/wzdj"
|
||||
|
||||
def _read_creds():
|
||||
d = os.path.dirname(os.path.abspath(__file__))
|
||||
for _ in range(6):
|
||||
root = d
|
||||
if os.path.isfile(os.path.join(root, "运营中枢", "工作台", "00_账号与API索引.md")):
|
||||
path = os.path.join(root, "运营中枢", "工作台", "00_账号与API索引.md")
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
text = f.read()
|
||||
sid = skey = None
|
||||
in_tx = False
|
||||
for line in text.splitlines():
|
||||
if "### 腾讯云" in line:
|
||||
in_tx = True
|
||||
continue
|
||||
if in_tx and line.strip().startswith("###"):
|
||||
break
|
||||
if not in_tx:
|
||||
continue
|
||||
m = re.search(r"\|\s*[^|]*(?:SecretId|密钥)[^|]*\|\s*`([^`]+)`", line, re.I)
|
||||
if m and m.group(1).strip().startswith("AKID"):
|
||||
sid = m.group(1).strip()
|
||||
m = re.search(r"\|\s*SecretKey\s*\|\s*`([^`]+)`", line, re.I)
|
||||
if m:
|
||||
skey = m.group(1).strip()
|
||||
return sid or None, skey or None
|
||||
d = os.path.dirname(d)
|
||||
return None, None
|
||||
|
||||
SHELL = '''#!/bin/bash
|
||||
set -e
|
||||
echo "=== wzdj 部署 ==="
|
||||
cd ''' + WZDJ_DIR + '''
|
||||
if [ ! -d .git ]; then
|
||||
echo "ERROR: 非 Git 目录,请先在此目录 clone 仓库"
|
||||
exit 1
|
||||
fi
|
||||
echo "1. git pull..."
|
||||
git fetch origin 2>/dev/null || git fetch gitea 2>/dev/null || true
|
||||
git reset --hard origin/main 2>/dev/null || git reset --hard gitea/main 2>/dev/null || git pull origin main 2>/dev/null || git pull gitea main 2>/dev/null || true
|
||||
echo "2. pnpm install..."
|
||||
pnpm install --frozen-lockfile 2>/dev/null || npm install --legacy-peer-deps
|
||||
echo "3. pnpm build..."
|
||||
pnpm build 2>/dev/null || npm run build
|
||||
echo "4. 重启 wzdj(宝塔 Node)..."
|
||||
python3 -c "
|
||||
import hashlib, json, urllib.request, urllib.parse, ssl, time
|
||||
ssl._create_default_https_context = ssl._create_unverified_context
|
||||
P, K = 'https://127.0.0.1:9988', 'qcWubCdlfFjS2b2DMT1lzPFaDfmv1cBT'
|
||||
def sign():
|
||||
t = int(time.time())
|
||||
s = str(t) + hashlib.md5(K.encode()).hexdigest()
|
||||
return {'request_time': t, 'request_token': hashlib.md5(s.encode()).hexdigest()}
|
||||
def post(path, d=None):
|
||||
pl = sign()
|
||||
if d: pl.update(d)
|
||||
r = urllib.request.Request(P+path, data=urllib.parse.urlencode(pl).encode())
|
||||
with urllib.request.urlopen(r, timeout=25) as resp:
|
||||
return json.loads(resp.read().decode())
|
||||
items = post('/project/nodejs/get_project_list').get('data') or post('/project/nodejs/get_project_list').get('list') or []
|
||||
for it in items:
|
||||
nm = (it.get('name') or '').lower()
|
||||
if nm == 'wzdj':
|
||||
post('/project/nodejs/restart_project', {'project_name': it.get('name') or it.get('project_name')})
|
||||
print(' 已重启 wzdj')
|
||||
break
|
||||
else:
|
||||
print(' 未找到 wzdj 项目')
|
||||
"
|
||||
nginx -t 2>/dev/null && nginx -s reload 2>/dev/null || true
|
||||
echo "=== 完成 ==="
|
||||
'''
|
||||
|
||||
def main():
|
||||
sid = os.environ.get("TENCENTCLOUD_SECRET_ID")
|
||||
skey = os.environ.get("TENCENTCLOUD_SECRET_KEY")
|
||||
if not sid or not skey:
|
||||
sid, skey = _read_creds()
|
||||
if not sid or not skey:
|
||||
print("❌ 未配置腾讯云 SecretId/SecretKey(见 00_账号与API索引.md)")
|
||||
return 1
|
||||
try:
|
||||
from tencentcloud.common import credential
|
||||
from tencentcloud.tat.v20201028 import tat_client, models
|
||||
except ImportError:
|
||||
print("请安装: pip install tencentcloud-sdk-python-tat")
|
||||
return 1
|
||||
cred = credential.Credential(sid, skey)
|
||||
client = tat_client.TatClient(cred, REGION)
|
||||
req = models.RunCommandRequest()
|
||||
req.Content = base64.b64encode(SHELL.encode()).decode()
|
||||
req.InstanceIds = [KR_INSTANCE_ID]
|
||||
req.CommandType = "SHELL"
|
||||
req.Timeout = 300
|
||||
req.CommandName = "wzdj_deploy_build_restart"
|
||||
resp = client.RunCommand(req)
|
||||
print("✅ TAT 已下发,InvocationId:", resp.InvocationId)
|
||||
print(" 服务器将执行: git pull → pnpm install → pnpm build → 重启 wzdj")
|
||||
print(" 等待约 120s 后查看结果...")
|
||||
time.sleep(120)
|
||||
try:
|
||||
req2 = models.DescribeInvocationTasksRequest()
|
||||
f = models.Filter()
|
||||
f.Name = "invocation-id"
|
||||
f.Values = [resp.InvocationId]
|
||||
req2.Filters = [f]
|
||||
r2 = client.DescribeInvocationTasks(req2)
|
||||
for t in (r2.InvocationTaskSet or []):
|
||||
print(" 状态:", getattr(t, "TaskStatus", ""))
|
||||
if hasattr(t, "Output") and t.Output:
|
||||
print(" 输出:", (t.Output or "")[:1200])
|
||||
except Exception as e:
|
||||
print(" 查询:", e)
|
||||
print(" 访问: https://wzdj.quwanzhi.com")
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
50
01_卡资(金)/金仓_存储备份/群晖NAS管理/scripts/time_machine_ckbnas_netbackup.sh
Executable file
50
01_卡资(金)/金仓_存储备份/群晖NAS管理/scripts/time_machine_ckbnas_netbackup.sh
Executable file
@@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
# ============================================
|
||||
# 时间机器 → ckbnas (192.168.1.201) NetBackup 目录
|
||||
# 用法:先确保 DSM 已为 NetBackup 启用 Time Machine,再运行本脚本或按下方命令操作
|
||||
# ============================================
|
||||
|
||||
CKB_IP="192.168.1.201"
|
||||
SHARE="NetBackup"
|
||||
SMB_URL="smb://fnvtk@${CKB_IP}/${SHARE}"
|
||||
|
||||
echo "=== 时间机器 → ckbnas NetBackup ==="
|
||||
echo "目标: ${CKB_IP} / ${SHARE}"
|
||||
echo ""
|
||||
|
||||
# 1. 网络检测
|
||||
echo "[1] 网络"
|
||||
if ping -c 1 -W 2 "$CKB_IP" >/dev/null 2>&1; then
|
||||
echo " ✅ ${CKB_IP} 可达"
|
||||
else
|
||||
echo " ❌ ${CKB_IP} 不可达,请检查本机与 ckbnas 在同一网段"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 2. 挂载检测
|
||||
echo ""
|
||||
echo "[2] 挂载"
|
||||
if [ -d "/Volumes/${SHARE}" ]; then
|
||||
echo " ✅ /Volumes/${SHARE} 已挂载"
|
||||
else
|
||||
echo " 未挂载。正在打开 SMB 连接(会弹窗输入 fnvtk 密码)…"
|
||||
open "$SMB_URL"
|
||||
echo " 请在弹出的窗口中输入 DSM 用户 fnvtk 的密码,连接成功后按回车继续。"
|
||||
read -r
|
||||
if [ ! -d "/Volumes/${SHARE}" ]; then
|
||||
echo " ❌ 仍未检测到 /Volumes/${SHARE},请手动在 Finder 连接服务器: $SMB_URL"
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
# 3. 设置时间机器目标(需完全磁盘访问权限)
|
||||
echo ""
|
||||
echo "[3] 设置备份目标"
|
||||
echo " 执行以下命令需「完全磁盘访问」权限(系统设置 → 隐私与安全性 → 完全磁盘访问 → 添加「终端」):"
|
||||
echo ""
|
||||
echo " sudo tmutil setdestination /Volumes/${SHARE}"
|
||||
echo ""
|
||||
echo " 执行后可用以下命令验证并立即备份:"
|
||||
echo " tmutil destinationinfo"
|
||||
echo " tmutil startbackup --block"
|
||||
echo ""
|
||||
@@ -0,0 +1,78 @@
|
||||
# 时间机器 → ckbnas NetBackup
|
||||
|
||||
**目标**:Mac 时间机器备份到 **ckbnas**(192.168.1.201)的 **NetBackup** 共享目录。
|
||||
|
||||
若出现「所选网络备份磁盘不支持所需功能」,说明 **NAS 端尚未为该共享启用 Time Machine**,按下列步骤操作。
|
||||
|
||||
---
|
||||
|
||||
## 一、ckbnas DSM 必做(先做)
|
||||
|
||||
在浏览器打开 **http://192.168.1.201:5000** 登录 DSM(用户 fnvtk),依次完成:
|
||||
|
||||
1. **控制面板** → **文件服务** → **高级**(或 **Time Machine**)
|
||||
- 勾选 **「启用 Time Machine 备份」**
|
||||
- 将 **NetBackup** 选为 Time Machine 使用的共享文件夹
|
||||
- 保存
|
||||
|
||||
2. **控制面板** → **文件服务** → **SMB** → **高级**
|
||||
- 最大 SMB 协议:**SMB3**
|
||||
- 勾选:**启用 SMB2 租约**、**启用 SMB durable handle**(持久句柄)
|
||||
- 保存,必要时重启 SMB 服务
|
||||
|
||||
3. 确认 **NetBackup** 共享对用户 **fnvtk** 有读写权限;建议关闭该共享的**回收站**,避免与稀疏包冲突。
|
||||
|
||||
---
|
||||
|
||||
## 二、Mac 命令行操作
|
||||
|
||||
### 1. 挂载 NetBackup(若未挂载)
|
||||
|
||||
```bash
|
||||
open "smb://fnvtk@192.168.1.201/NetBackup"
|
||||
```
|
||||
|
||||
按提示输入 fnvtk 密码,连接成功后会在 `/Volumes/NetBackup` 看到该卷。
|
||||
|
||||
### 2. 赋予「完全磁盘访问」权限(仅首次)
|
||||
|
||||
- **系统设置** → **隐私与安全性** → **完全磁盘访问**
|
||||
- 添加 **终端**(或 **Cursor**,若在 Cursor 终端里执行)
|
||||
|
||||
### 3. 设置时间机器目标并验证
|
||||
|
||||
在终端执行:
|
||||
|
||||
```bash
|
||||
sudo tmutil setdestination /Volumes/NetBackup
|
||||
tmutil destinationinfo
|
||||
tmutil startbackup --block
|
||||
```
|
||||
|
||||
- `setdestination`:将备份目标设为已挂载的 NetBackup。
|
||||
- `destinationinfo`:确认当前备份目标。
|
||||
- `startbackup --block`:立即开始一次备份(阻塞直到结束,可选)。
|
||||
|
||||
---
|
||||
|
||||
## 三、一键脚本
|
||||
|
||||
可运行本目录同级脚本(会做网络检测、挂载提示并输出上述命令):
|
||||
|
||||
```bash
|
||||
bash "01_卡资(金)/金仓_存储备份/群晖NAS管理/scripts/time_machine_ckbnas_netbackup.sh"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、快速检查清单
|
||||
|
||||
| 项 | 说明 |
|
||||
|----|------|
|
||||
| DSM 启用 Time Machine | 文件服务 → 高级,并选择 NetBackup |
|
||||
| SMB 高级 | SMB3、SMB2 租约、持久句柄已开 |
|
||||
| 共享权限 | fnvtk 对 NetBackup 可读写 |
|
||||
| Mac 完全磁盘访问 | 终端已加入完全磁盘访问列表 |
|
||||
| 挂载 | `/Volumes/NetBackup` 存在后再执行 tmutil |
|
||||
|
||||
完成「一」后,再在 Mac 执行「二」即可正常备份。
|
||||
@@ -1,2 +1,2 @@
|
||||
bv_csrf_token=8e0d42fe-edf3-4a3b-bbfd-541fa432adf6; m_e09b70=38653064343266652d656466332d346133622d626266642d353431666134333261646636b37b91f4efa89b27b410d5626626f1b2ebf3ed82d6b510030362344fb5776178; minutes_csrf_token=4619adeb-6d49-4964-8997-46d4b61cc526; m_ce8f16=34363139616465622d366434392d343936342d383939372d343664346236316363353236b37b91f4efa89b27b410d5626626f1b2ebf3ed82d6b510030362344fb5776178; passport_web_did=7514522919465811987; passport_trace_id=7514522919485292563; QXV0aHpDb250ZXh0=88883e53c92e44849a1e82932de0599b; session=XN0YXJ0-583m169b-79c6-44bf-8307-f48b160bde22-WVuZA; session_list=XN0YXJ0-583m169b-79c6-44bf-8307-f48b160bde22-WVuZA; swp_csrf_token=ba6718bb-4f76-4b86-a8d8-28c0117357e4; t_beda37=5bc818690404cb6332040fc5ed75a7e8be61177a6b1d75dd2a322245f11e63f7; msToken=ECH70c3RMEWL6kSLDGuH1CmpTYiLDVziBxfgHQlDdL8JWQgimkjy-kZQ1MQLfn2jOg1pvRhZchLDei7pMJkAz7bgniCoCiwUOYxRWQNXOeglKu41BxVhSTqkFgfX6qGN1pbwincoWE4jyxiyAAOctkQrjJGp1I9nFqKV_3ouXNJCgvk4iNwoZg==
|
||||
# 自动从浏览器提取,可手动覆盖
|
||||
# 逆向获取
|
||||
@@ -10,6 +10,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
@@ -87,14 +88,33 @@ def export_via_playwright_page(object_token: str, title: str = "", wait_sec: int
|
||||
time.sleep(wait_sec)
|
||||
js = f"""
|
||||
async () => {{
|
||||
const r = await fetch('{EXPORT_URL}?object_token={object_token}&add_speaker=true&add_timestamp=false&format=2', {{method:'POST', credentials:'include'}});
|
||||
const r = await fetch('{EXPORT_URL}', {{
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {{ 'Content-Type': 'application/x-www-form-urlencoded' }},
|
||||
body: 'object_token={object_token}&add_speaker=true&add_timestamp=false&format=2'
|
||||
}});
|
||||
return await r.text();
|
||||
}}
|
||||
"""
|
||||
text = pg.evaluate(js)
|
||||
ctx.close()
|
||||
if text and len(str(text)) > 400 and "please log in" not in str(text).lower():
|
||||
result[0] = str(text).strip()
|
||||
print(" 正在页面内请求导出接口,请勿关闭窗口…")
|
||||
raw = pg.evaluate(js)
|
||||
text = (raw or "").strip()
|
||||
if not text or "please log in" in text.lower():
|
||||
pass
|
||||
elif text.startswith("{"):
|
||||
try:
|
||||
j = json.loads(text)
|
||||
data = j.get("data")
|
||||
if isinstance(data, str) and len(data) > 100:
|
||||
result[0] = data
|
||||
elif isinstance(data, dict):
|
||||
result[0] = (data.get("content") or data.get("text") or data.get("transcript") or "")
|
||||
except Exception:
|
||||
if len(text) > 400:
|
||||
result[0] = text
|
||||
elif len(text) > 400:
|
||||
result[0] = text
|
||||
except Exception as e:
|
||||
print(f" Playwright 失败: {e}", file=sys.stderr)
|
||||
finally:
|
||||
@@ -110,6 +130,7 @@ def main() -> int:
|
||||
ap.add_argument("-o", "--output-dir", default=str(OUT_DIR), help="输出目录")
|
||||
ap.add_argument("--title", help="保存文件名中的标题")
|
||||
ap.add_argument("--playwright-wait", type=int, default=30, help="Playwright 打开页后等待秒数")
|
||||
ap.add_argument("--cookie-only", "--no-browser", action="store_true", dest="cookie_only", help="仅用 Cookie/命令行,不弹浏览器;失败时提示配置 cookie_minutes.txt")
|
||||
args = ap.parse_args()
|
||||
token = args.token or (extract_token(args.url_or_token or "") or args.url_or_token)
|
||||
if not token or len(token) < 20:
|
||||
@@ -125,7 +146,7 @@ def main() -> int:
|
||||
title = f"妙记_{token[:12]}"
|
||||
|
||||
print(f"📌 object_token: {token} title: {title[:50]}…")
|
||||
print(" 1) 尝试 Cookie 导出…")
|
||||
print(" 1) 尝试 Cookie 导出(cookie_minutes.txt 或本机浏览器已存 Cookie)…")
|
||||
text = export_via_cookie(token)
|
||||
if text:
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
@@ -134,6 +155,9 @@ def main() -> int:
|
||||
path.write_text(f"标题: {title}\nobject_token: {token}\n\n文字记录:\n\n{text}", encoding="utf-8")
|
||||
print(f" ✅ Cookie 导出成功 -> {path}")
|
||||
return 0
|
||||
if args.cookie_only:
|
||||
print(" ❌ Cookie 导出失败。请将妙记 list 请求的 Cookie 写入脚本同目录 cookie_minutes.txt 第一行后重试。", file=sys.stderr)
|
||||
return 1
|
||||
print(" 2) Cookie 失败,改用 Playwright 页面内导出…")
|
||||
text = export_via_playwright_page(token, title=title, wait_sec=args.playwright_wait)
|
||||
if text:
|
||||
|
||||
65
02_卡人(水)/水桥_平台对接/智能纪要/脚本/下载单条妙记_仅命令行.sh
Normal file
65
02_卡人(水)/水桥_平台对接/智能纪要/脚本/下载单条妙记_仅命令行.sh
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/bin/bash
|
||||
# 单条妙记:仅用命令行下载文字+视频,不弹浏览器。失败时 print 打开浏览器的正确方式。
|
||||
# 用法: bash 下载单条妙记_仅命令行.sh "https://cunkebao.feishu.cn/minutes/obcn6yjg6866c3gl4ibd72vr"
|
||||
# 或: bash 下载单条妙记_仅命令行.sh obcn6yjg6866c3gl4ibd72vr "soul 派对 113场 20260302"
|
||||
|
||||
URL_OR_TOKEN="${1:-}"
|
||||
TITLE="${2:-}"
|
||||
OUT="${3:-/Users/karuo/Documents/聊天记录/soul}"
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
if [[ -z "$URL_OR_TOKEN" ]]; then
|
||||
echo "用法: $0 <妙记URL或object_token> [标题] [输出目录]"
|
||||
echo "示例: $0 'https://cunkebao.feishu.cn/minutes/obcn6yjg6866c3gl4ibd72vr' 'soul 派对 113场 20260302'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 提取 token
|
||||
if [[ "$URL_OR_TOKEN" == *"/minutes/"* ]]; then
|
||||
TOKEN=$(echo "$URL_OR_TOKEN" | sed -n 's|.*/minutes/\([a-zA-Z0-9]*\).*|\1|p')
|
||||
else
|
||||
TOKEN="$URL_OR_TOKEN"
|
||||
fi
|
||||
[[ -z "$TITLE" ]] && TITLE="妙记_${TOKEN:0:12}"
|
||||
|
||||
echo "📌 object_token: $TOKEN 输出: $OUT"
|
||||
echo ""
|
||||
|
||||
# 1) 文字
|
||||
echo "=== 1) 文字(仅 Cookie,不弹窗)==="
|
||||
if python3 "$SCRIPT_DIR/feishu_minutes_one_url.py" "$URL_OR_TOKEN" --title "$TITLE" -o "$OUT" --cookie-only 2>&1; then
|
||||
echo " ✅ 文字已保存"
|
||||
else
|
||||
TEXT_FAIL=1
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 2) 视频
|
||||
echo "=== 2) 视频(仅 Cookie)==="
|
||||
if python3 "$SCRIPT_DIR/feishu_minutes_download_video.py" "$URL_OR_TOKEN" -o "$OUT" 2>&1; then
|
||||
echo " ✅ 视频已保存"
|
||||
else
|
||||
VIDEO_FAIL=1
|
||||
fi
|
||||
echo ""
|
||||
|
||||
if [[ -n "$TEXT_FAIL" || -n "$VIDEO_FAIL" ]]; then
|
||||
echo "----------------------------------------"
|
||||
echo "⚠️ 命令行未拿到有效 Cookie,需用浏览器取 Cookie 后重试:"
|
||||
echo ""
|
||||
echo " 1) 用浏览器打开(复制下面整行):"
|
||||
echo " https://cunkebao.feishu.cn/minutes/home"
|
||||
echo ""
|
||||
echo " 2) 登录后 F12 → 网络 → 刷新 → 找到 list?size= 请求 → 复制请求头里的 Cookie"
|
||||
echo ""
|
||||
echo " 3) 粘贴到下面文件第一行并保存:"
|
||||
echo " $SCRIPT_DIR/cookie_minutes.txt"
|
||||
echo ""
|
||||
echo " 4) 再执行本脚本:"
|
||||
echo " bash $0 '$URL_OR_TOKEN' '$TITLE' '$OUT'"
|
||||
echo "----------------------------------------"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ 文字+视频均已保存到 $OUT"
|
||||
ls -la "$OUT"/*"${TOKEN:0:8}"* "$OUT"/*113* 2>/dev/null || true
|
||||
156
02_卡人(水)/水桥_平台对接/智能纪要/脚本/逆向获取Cookie并下载单条.py
Normal file
156
02_卡人(水)/水桥_平台对接/智能纪要/脚本/逆向获取Cookie并下载单条.py
Normal file
@@ -0,0 +1,156 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
卡若AI 逆向获取:从本机浏览器/Cookie 文件自动取 Cookie,不弹窗,直接下载单条妙记文字+视频。
|
||||
与 download_soul_minutes_101_to_103 同源(cookie_minutes.txt → 环境变量 → browser_cookie3 → Doubao)。
|
||||
用法: python3 逆向获取Cookie并下载单条.py "https://cunkebao.feishu.cn/minutes/obcn6yjg6866c3gl4ibd72vr" "soul 派对 113场 20260302"
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
SCRIPT_DIR = Path(__file__).resolve().parent
|
||||
OUT_DIR = Path("/Users/karuo/Documents/聊天记录/soul")
|
||||
COOKIE_FILE = SCRIPT_DIR / "cookie_minutes.txt"
|
||||
|
||||
|
||||
def get_cookie() -> str:
|
||||
"""与 download_soul_minutes_101_to_103 一致:cookie_minutes.txt → 环境变量 → 本机浏览器(Doubao)。"""
|
||||
if COOKIE_FILE.exists():
|
||||
for line in COOKIE_FILE.read_text(encoding="utf-8", errors="ignore").strip().splitlines():
|
||||
line = line.strip()
|
||||
if line and not line.startswith("#") and "PASTE_YOUR" not in line and len(line) > 100:
|
||||
return line
|
||||
c = __import__("os").environ.get("FEISHU_MINUTES_COOKIE", "").strip()
|
||||
if c and len(c) > 100:
|
||||
return c
|
||||
# browser_cookie3
|
||||
try:
|
||||
import browser_cookie3
|
||||
for domain in ("cunkebao.feishu.cn", "feishu.cn", ".feishu.cn"):
|
||||
for loader in (browser_cookie3.safari, browser_cookie3.chrome, browser_cookie3.chromium, browser_cookie3.firefox, browser_cookie3.edge):
|
||||
try:
|
||||
cj = loader(domain_name=domain)
|
||||
s = "; ".join(f"{c.name}={c.value}" for c in cj)
|
||||
if len(s) > 100:
|
||||
return s
|
||||
except Exception:
|
||||
continue
|
||||
except ImportError:
|
||||
pass
|
||||
# Doubao
|
||||
try:
|
||||
import subprocess, shutil, tempfile, sqlite3, hashlib
|
||||
for name in ("Doubao Browser Safe Storage", "Doubao Safe Storage"):
|
||||
try:
|
||||
key = subprocess.run(["security", "find-generic-password", "-s", name, "-w"], capture_output=True, text=True, timeout=5).stdout.strip()
|
||||
if not key:
|
||||
continue
|
||||
except Exception:
|
||||
continue
|
||||
for profile in ("Default", "Profile 1", "Profile 2", "Profile 3"):
|
||||
db = Path.home() / "Library/Application Support/Doubao" / profile / "Cookies"
|
||||
if not db.exists():
|
||||
continue
|
||||
try:
|
||||
tmp = tempfile.mktemp(suffix=".db")
|
||||
shutil.copy2(db, tmp)
|
||||
conn = sqlite3.connect(tmp)
|
||||
cur = conn.cursor()
|
||||
cur.execute("SELECT host_key, name, encrypted_value FROM cookies WHERE host_key LIKE '%feishu%' OR host_key LIKE '%cunkebao%'")
|
||||
rows = cur.fetchall()
|
||||
conn.close()
|
||||
Path(tmp).unlink(missing_ok=True)
|
||||
except Exception:
|
||||
continue
|
||||
if not rows:
|
||||
continue
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||
derived = hashlib.pbkdf2_hmac("sha1", key.encode("utf-8"), b"saltysalt", 1003, dklen=16)
|
||||
parts = []
|
||||
for host, name, enc in rows:
|
||||
if enc[:3] != b"v10":
|
||||
continue
|
||||
raw = enc[3:]
|
||||
dec = Cipher(algorithms.AES(derived), modes.CBC(b" " * 16)).decryptor()
|
||||
pt = dec.update(raw) + dec.finalize()
|
||||
pad = pt[-1]
|
||||
if isinstance(pad, int) and 1 <= pad <= 16:
|
||||
pt = pt[:-pad]
|
||||
for i in range(min(len(pt), 48)):
|
||||
if i + 4 <= len(pt) and all(32 <= pt[j] < 127 for j in range(i, min(i + 8, len(pt)))):
|
||||
val = pt[i:].decode("ascii", errors="ignore")
|
||||
if val and "\x00" not in val:
|
||||
parts.append(f"{name}={val}")
|
||||
break
|
||||
if len(parts) > 5:
|
||||
return "; ".join(parts)
|
||||
except Exception:
|
||||
pass
|
||||
return ""
|
||||
|
||||
|
||||
def main() -> int:
|
||||
url_or_token = sys.argv[1] if len(sys.argv) > 1 else ""
|
||||
title = sys.argv[2] if len(sys.argv) > 2 else ""
|
||||
token = (re.search(r"/minutes/([a-zA-Z0-9]+)", url_or_token).group(1) if "/minutes/" in url_or_token else url_or_token) or url_or_token
|
||||
if not token or len(token) < 20:
|
||||
print("用法: python3 逆向获取Cookie并下载单条.py <妙记URL或token> [标题]", file=sys.stderr)
|
||||
return 1
|
||||
if not title:
|
||||
title = f"妙记_{token[:12]}"
|
||||
|
||||
print("🔄 逆向获取 Cookie(cookie_minutes.txt → 环境变量 → 本机浏览器/Doubao)…")
|
||||
cookie = get_cookie()
|
||||
if not cookie:
|
||||
print("❌ 未获取到 Cookie。请确保:cookie_minutes.txt 有内容,或本机 Chrome/Safari/Doubao 已登录 cunkebao.feishu.cn", file=sys.stderr)
|
||||
return 1
|
||||
print(" Cookie 长度:", len(cookie))
|
||||
# 写入以便后续脚本复用
|
||||
COOKIE_FILE.write_text(cookie + "\n# 逆向获取", encoding="utf-8")
|
||||
print(" 已写入 cookie_minutes.txt")
|
||||
|
||||
sys.path.insert(0, str(SCRIPT_DIR))
|
||||
from feishu_minutes_export_github import export_transcript
|
||||
from feishu_minutes_download_video import get_video_url, download_video, get_cookie as get_cookie_video, make_headers
|
||||
|
||||
# 1) 文字
|
||||
print("📄 下载文字…")
|
||||
text = export_transcript(cookie, token)
|
||||
if not text:
|
||||
try:
|
||||
from feishu_minutes_one_url import export_via_playwright_page
|
||||
print(" Cookie 导出 401,改用 Playwright 页面内获取…")
|
||||
text = export_via_playwright_page(token, title=title, wait_sec=45)
|
||||
except Exception as e:
|
||||
print(" Playwright 兜底失败:", e, file=sys.stderr)
|
||||
if text:
|
||||
OUT_DIR.mkdir(parents=True, exist_ok=True)
|
||||
safe = re.sub(r'[\\/*?:"<>|]', "_", title)
|
||||
path = OUT_DIR / f"{safe}.txt"
|
||||
path.write_text(f"标题: {title}\nobject_token: {token}\n\n文字记录:\n\n{text}", encoding="utf-8")
|
||||
print(" ✅", path.name)
|
||||
else:
|
||||
print(" ❌ 文字导出失败(可能 401)")
|
||||
|
||||
# 2) 视频
|
||||
print("📹 下载视频…")
|
||||
video_url, _title = get_video_url(cookie, token)
|
||||
if video_url:
|
||||
ref = "https://cunkebao.feishu.cn/minutes/"
|
||||
headers = make_headers(cookie, ref)
|
||||
safe = re.sub(r'[\\/*?:"<>|]', "_", title or _title or token[:12])
|
||||
out_path = OUT_DIR / f"{safe}.mp4"
|
||||
if download_video(video_url, out_path, headers):
|
||||
print(" ✅", out_path.name, f"({out_path.stat().st_size / (1024*1024):.1f} MB)")
|
||||
else:
|
||||
print(" ❌ 视频下载失败")
|
||||
else:
|
||||
print(" ❌ 未获取到视频链接")
|
||||
|
||||
return 0 if text or video_url else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
52
BOOTSTRAP.md
52
BOOTSTRAP.md
@@ -36,8 +36,7 @@
|
||||
|:---|:---|:---|
|
||||
| 1 | **本文件** `BOOTSTRAP.md` | 知道自己是谁、团队怎么分、怎么工作 |
|
||||
| 2 | **技能注册表** `SKILL_REGISTRY.md` | 查找用户需求对应的技能和路径 |
|
||||
| 3 | **运行模式** `运营中枢/工作台/运行模式.md` | 若当前模式为 `max`,按 MAX 模式执行(思考更深、全栈走实施计划+TDD+两阶段评审、复盘更详);见 `运营中枢/参考资料/卡若AI运行模式说明.md` |
|
||||
| 4 | **对应技能的 SKILL.md** | 拿到具体执行指令(只读匹配到的那个) |
|
||||
| 3 | **对应技能的 SKILL.md** | 拿到具体执行指令(只读匹配到的那个) |
|
||||
|
||||
**启动瘦身(按需加载)**:步骤 2 不需要全表扫描。优先只加载 `SKILL_REGISTRY.md` 中 🔴 热技能(≤8 个)的触发词+路径;未命中时再懒加载其余部分。详见 SKILL_REGISTRY 中「技能热度分级」。
|
||||
|
||||
@@ -49,17 +48,31 @@
|
||||
|
||||
---
|
||||
|
||||
## 四、执行流程(强制)
|
||||
## 四、MAX Mode(默认 · 卡若AI 本体)
|
||||
|
||||
### 第一步:先思考,并在对话中展示拆解与计划(强制)
|
||||
**卡若AI 每次被调用时,均以 MAX Mode 运行。** 无需在任何平台单独开启或提问,这是卡若AI 的默认行为,写在 BOOTSTRAP 即对所有调用方生效(Cursor、Claude、API 等)。
|
||||
|
||||
接到用户任务后,**必须先做深度思考与调研**,再动手执行。思考要结合团队所有成员能力(金/水/木/火/土、14 成员、53 技能),想清楚:目标是什么、该谁干、怎么干、可能卡在哪。
|
||||
- **思考**:更深度(多角度、边界情况、风险与回退);结合 SKILL_REGISTRY 热技能与相关子技能做扩展。
|
||||
- **任务拆解**:粒度更细,子步骤、依赖与顺序写清;执行计划尽量带**精确路径、命令、预期**(对齐全栈开发「实施计划标准」)。
|
||||
- **技能联动**:执行前检查是否有**联动子技能**需一并考虑(如视频切片→切片动效包装、全栈开发→需求拆解/智能追问)。
|
||||
- **验证**:至少两轮验证(结果与目标匹配、无遗漏);不通过则回溯再执行。
|
||||
- **复盘**:五块齐全且更完整,可带简要数据、引用或下一步可执行动作。
|
||||
|
||||
---
|
||||
|
||||
## 五、执行流程(强制 · 含 MAX Mode)
|
||||
|
||||
### 第一步:先思考,并在对话中展示拆解与计划(强制 · MAX Mode)
|
||||
|
||||
接到用户任务后,**必须先做深度思考与调研**,再动手执行。思考要结合团队所有成员能力(金/水/木/火/土、14 成员、53 技能),想清楚:目标是什么、该谁干、怎么干、可能卡在哪;**思考更深度**(多角度、边界与风险),可结合 SKILL_REGISTRY 热技能与相关子技能做扩展。
|
||||
|
||||
**必须在对话里先展示以下内容,再继续执行**:
|
||||
|
||||
1. **思考结果**:调研/分析后的结论(目标、谁干、怎么干、卡点),用简洁几句话输出
|
||||
2. **任务拆解**:把任务拆成 1、2、3… 的具体步骤
|
||||
3. **执行计划**:先写清计划,再动手
|
||||
2. **任务拆解**:把任务拆成 1、2、3… 的**细粒度**步骤(子步骤、依赖与顺序写清)
|
||||
3. **执行计划**:先写清计划,尽量带**精确路径、命令、预期**,再动手
|
||||
|
||||
**执行前**:检查是否有**联动子技能**需一并考虑(如视频切片→切片动效包装、全栈开发→需求拆解/智能追问)。
|
||||
|
||||
**格式示例**:
|
||||
```
|
||||
@@ -81,23 +94,23 @@
|
||||
|
||||
按思考结论:查 `SKILL_REGISTRY.md` → 读对应 SKILL.md → 按步骤执行,每步简短总结。
|
||||
|
||||
### 第三步:反复验证结果(强制)
|
||||
### 第三步:反复验证结果(强制 · 至少两轮)
|
||||
|
||||
执行完成后,**必须反复验证**:最终结果是否与用户一开始输入的命令/目标相匹配。
|
||||
执行完成后,**必须反复验证**:最终结果是否与用户一开始输入的命令/目标相匹配;**至少两轮验证**(结果与目标匹配、无遗漏)。
|
||||
|
||||
- **匹配** → 进入「对话结尾」。
|
||||
- **不匹配** → **回溯**:回到问题点 → **搜索**(GitHub、现有 Skill、网上资料)找解决方案 → **再思考**(简洁输出)→ **再执行** → 再次验证。循环直到结果与用户目标一致或明确说明无法达成。**确保任务成功、对话执行命令成功。**
|
||||
|
||||
### 第四步:回复形式 = 强制复盘(卡若AI 内所有对话必守)
|
||||
### 第四步:回复形式 = 强制复盘(卡若AI 内所有对话必守 · 五块更完整)
|
||||
|
||||
**在卡若AI 工作台内,所有对话的 AI 回复一律采用「复盘形式」。** 复盘**只有一种格式:完整复盘**;**每一轮回复、每一个步骤结束**均以完整复盘块收尾(🎯📌💡📝▶ 五块齐全),不得使用简版或省略。复盘块**必须带日期+时间**(YYYY-MM-DD HH:mm);目标·结果·达成率**整行 ≤30 字**;回复可加图标增强可读性;下一步须结合对话与项目目标、关联未完成项。复盘格式见:`运营中枢/参考资料/卡若复盘格式_固定规则.md`。
|
||||
**在卡若AI 工作台内,所有对话的 AI 回复一律采用「复盘形式」。** 复盘**只有一种格式:完整复盘**;**每一轮回复、每一个步骤结束**均以完整复盘块收尾(🎯📌💡📝▶ 五块齐全),不得使用简版或省略。**五块更完整**,可带简要数据、引用或下一步可执行动作。复盘块**必须带日期+时间**(YYYY-MM-DD HH:mm);目标·结果·达成率**整行 ≤30 字**;回复可加图标增强可读性;下一步须结合对话与项目目标、关联未完成项。复盘格式见:`运营中枢/参考资料/卡若复盘格式_固定规则.md`。
|
||||
|
||||
---
|
||||
|
||||
### 流程小结
|
||||
### 流程小结(默认 MAX Mode)
|
||||
|
||||
```
|
||||
输入 → 先思考 → 在对话中展示(思考结果+任务拆解1/2/3+计划)→ 执行 → 验证
|
||||
输入 → 先思考(深度+细拆解+精确计划+技能联动)→ 在对话中展示 → 执行 → 至少两轮验证
|
||||
↑ │
|
||||
└── 不匹配:回溯 → 搜索(GitHub/Skill/网上) → 再思考 → 再展示 → 再执行 ──┘
|
||||
↓
|
||||
@@ -106,7 +119,7 @@
|
||||
|
||||
---
|
||||
|
||||
## 五、标准命令(Standard Commands)
|
||||
## 六、标准命令(Standard Commands)
|
||||
|
||||
任何平台都能用的固定动作,不依赖特定 IDE:
|
||||
|
||||
@@ -116,14 +129,13 @@
|
||||
| **复盘** | **所有对话强制(卡若AI 统一回复形式)** | 卡若AI 内**所有对话**的 AI 回复一律用复盘形式;**只用完整复盘**,每轮/每步均以完整复盘块收尾(🎯📌💡📝▶);复盘须带日期+时间、目标行≤30字、下一步关联项目目标;格式见 `运营中枢/参考资料/卡若复盘格式_固定规则.md`。不得省略、不得改格式。 |
|
||||
| **沉淀** | 发现有价值的经验 | 写入 `02_卡人(水)/水溪_整理归档/经验库/待沉淀/` |
|
||||
| **基因胶囊** | 打包技能、解包胶囊、继承能力 | 读 `05_卡土(土)/土砖_技能复制/基因胶囊/SKILL.md`;pack 时自动生成导出说明(含流程图) |
|
||||
| **运行模式** | 切换 Auto / MAX | 读写 `运营中枢/工作台/运行模式.md`;用户说「开MAX」「切回Auto」「当前什么模式」时切换或查询;MAX 下思考更深、全栈走实施计划+TDD+两阶段评审,见 `运营中枢/参考资料/卡若AI运行模式说明.md` |
|
||||
| **Gitea 同步** | 有文件变更时 | `bash 01_卡资(金)/金仓_存储备份/Gitea管理/脚本/自动同步.sh` |
|
||||
| **跑 Pipeline** | 用户说「新项目上线」「内容发布」「日常运维」等 | 读 `运营中枢/参考资料/Pipeline执行清单.md` 按步骤执行 |
|
||||
| **对外输出** | 报告、复盘存档、执行日志、导出文件、**生成图片** | 统一写到 `/Users/karuo/Documents/卡若Ai的文件夹/` 下对应子目录;**图片** → `图片/`,并在 `图片/图片索引.md` 登记来源 Skill、生成者。经验沉淀仍写 `02_卡人(水)/水溪_整理归档/经验库/待沉淀/`。详见 `运营中枢/参考资料/输出目录规范.md`。 |
|
||||
|
||||
---
|
||||
|
||||
## 六、核心文件导航
|
||||
## 七、核心文件导航
|
||||
|
||||
| 文件 | 路径 | 用途 |
|
||||
|:---|:---|:---|
|
||||
@@ -140,7 +152,7 @@
|
||||
|
||||
---
|
||||
|
||||
## 七、全局规则
|
||||
## 八、全局规则
|
||||
|
||||
0. **异常处理与红线(强制)**:执行时按 `运营中枢/参考资料/卡若AI异常处理与红线.md`。**红线**:① 不改变卡若AI 整体结构 ② 不导致电脑无法启动 ③ 不删除重大文件。
|
||||
1. **禁止独立功能目录(强制)**:**不得再新建 `_共享模块` 或任何与五行、运营中枢并列的「功能目录」**。所有共享能力必须融入现有结构:代码/脚本归属到 `01_卡资(金)`~`05_卡土(土)` 对应成员下,参考资料/复盘/流程归属到 `运营中枢/参考资料/`,兼容层在 `运营中枢/` 下(如 `运营中枢/local_llm`、`运营中枢/memory`、`运营中枢/task_router`)。违反即视为结构违规。
|
||||
@@ -153,7 +165,7 @@
|
||||
|
||||
---
|
||||
|
||||
## 八、平台适配(可选)
|
||||
## 九、平台适配(可选)
|
||||
|
||||
卡若AI 本身不依赖任何特定 AI 平台。以下是各平台的薄层适配:
|
||||
|
||||
@@ -166,7 +178,7 @@
|
||||
|
||||
---
|
||||
|
||||
## 九、SKILL.md 标准格式
|
||||
## 十、SKILL.md 标准格式
|
||||
|
||||
每个技能的 SKILL.md 应遵循以下结构,确保任何 AI 都能读懂并执行:
|
||||
|
||||
@@ -205,7 +217,7 @@ updated: "YYYY-MM-DD"
|
||||
|
||||
---
|
||||
|
||||
## 十、快速开始
|
||||
## 十一、快速开始
|
||||
|
||||
**场景 1:你是 AI,第一次接触卡若AI**
|
||||
1. 读完本文件,你就知道团队结构和工作方式了
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
# 卡若AI 运行模式说明
|
||||
|
||||
> 对应「Search models / Auto / MAX Mode」类能力:通过 `运营中枢/工作台/运行模式.md` 的「当前模式」在 **Auto** 与 **MAX** 间切换,每次对话开始读取该文件并据此调整行为。
|
||||
|
||||
---
|
||||
|
||||
## 一、模式定义
|
||||
|
||||
| 模式 | 含义 | 适用场景 |
|
||||
|:---|:---|:---|
|
||||
| **Auto** | 平衡、效率优先;标准思考与拆解深度,按既有流程执行。 | 日常任务、快速响应、常规技能调用。 |
|
||||
| **MAX** | 深度模式;思考与拆解更充分,开发类任务优先走实施计划 + TDD + 两阶段评审,复盘更完整。 | 重要需求、全栈/开发、需要最佳质量或可追溯性时。 |
|
||||
|
||||
---
|
||||
|
||||
## 二、行为差异(AI 须遵守)
|
||||
|
||||
### Auto 模式
|
||||
|
||||
- 先思考并在对话中展示「思考结果 + 任务拆解 + 执行计划」,再执行(与现有强制流程一致)。
|
||||
- 技能按 SKILL_REGISTRY 匹配后按 SKILL.md 执行,不额外加码。
|
||||
- 复盘按固定格式、目标行 ≤30 字,完整五块即可。
|
||||
|
||||
### MAX 模式
|
||||
|
||||
- **思考与拆解**:思考更充分,拆解更细(可多步、标出依赖与风险),计划在对话中展示更完整。
|
||||
- **全栈/开发类任务**:优先采用「实施计划」(精确路径 + 命令 + 预期)、TDD 推荐、任务/迭代两阶段评审(规格符合 → 代码质量);见 `04_卡火(火)/火炬_全栈消息/全栈开发/SKILL.md`。
|
||||
- **搜索与扩展**:可适当扩大搜索范围、多查 references,再收敛到执行方案。
|
||||
- **复盘**:复盘保持五块格式,但过程与反思可更详细,下一步可带更明确的子项或检查点。
|
||||
- **不改变**:红线、异常处理、对外输出目录、复盘格式规范、Gitea 同步等全局规则不变。
|
||||
|
||||
---
|
||||
|
||||
## 三、配置与读取
|
||||
|
||||
- **配置文件**:`运营中枢/工作台/运行模式.md`,其中「当前模式」为 `auto` 或 `max`(小写)。
|
||||
- **读取时机**:每次对话开始(在 BOOTSTRAP / 技能查找之后)读取该文件,若为 `max` 则本轮按 MAX 模式行为执行。
|
||||
- **切换**:仅当用户明确要求切换模式时,修改 `运行模式.md` 中的「当前模式」并保存,然后回复已切换;不主动建议切换。
|
||||
|
||||
---
|
||||
|
||||
## 四、「Search models」的对应关系
|
||||
|
||||
- 图片中的「Search models」在卡若AI 中对应:**按需求查技能**(查 `SKILL_REGISTRY.md`)和**按关键词匹配技能**;无需单独「搜索模型」UI,技能注册表即能力索引。
|
||||
- 若后续需要「按名字/关键词搜某类运行配置」,可在工作台增加「模式/配置」索引表,本文件作为运行模式的主说明即可。
|
||||
@@ -19,7 +19,7 @@
|
||||
## 二、文件与存放
|
||||
|
||||
- **文件名**:`作者或主题_书名或简称_读书笔记.md`(例:`曾仕强_易经_读书笔记.md`、`纳瓦尔访谈_读书笔记.md`)。
|
||||
- **存放路径**:`/Users/karuo/Documents/卡若Ai的文件夹/导出/读书笔记/`。
|
||||
- **存放路径(默认)**:`/Users/karuo/Documents/个人/2、我写的日记/读书笔记/`。**以后读书笔记一律放此目录,固定不发他处。**
|
||||
- **图片与流程图**:笔记内引用的图片、流程图建议与笔记**同目录**存放,用 `文件名.png` 或 `./文件名.png` 引用,避免用 `../../图片/` 等跨目录路径导致在不同预览/工作区下**不显示**。若用 Mermaid,可在同节内再插入一张导出好的流程图 PNG,保证不依赖渲染也能看到图。
|
||||
- **图裂了怎么办**:若在 Cursor/VS Code 里图片不显示,可(1)用 Typora 打开该 md(以文件所在目录为基准);(2)在 Finder 中打开笔记所在文件夹,双击 md 用系统默认预览打开;(3)直接打开同目录下对应的 PNG 文件。建议在每张图下方加一句备用说明:「若图不显示,请打开本笔记所在文件夹中的 `xxx.png` 查看。」
|
||||
- **记忆写入**:在 `个人/1、卡若:本人/记忆.md` 当日日期下追加 1~2 行摘要 + 本笔记文件路径;便于后续从记忆调出。
|
||||
@@ -127,7 +127,7 @@
|
||||
## 五、与记忆、Skill 的衔接
|
||||
|
||||
- **记忆**:读书笔记写完后,在 `个人/1、卡若:本人/记忆.md` 当日下追加一条,格式:
|
||||
`[HH:MM] 读书笔记·《书名》/主题:一句话摘要;全文见 卡若Ai的文件夹/导出/读书笔记/xxx.md。`
|
||||
`[HH:MM] 读书笔记·《书名》/主题:一句话摘要;全文见 个人/2、我写的日记/读书笔记/xxx.md。`
|
||||
- **读书笔记 Skill**:`04_卡火(火)/火炬_全栈消息/读书笔记/SKILL.md` 定义五行拆书流程与 XMind 写入;本格式与之对齐,完整版即该 Skill 的 Markdown 版输出。
|
||||
- **分类**:个人提升 / 人际关系 / 创业 / 商业思维 / 投资;若写 XMind 需选其一。
|
||||
|
||||
@@ -147,8 +147,8 @@
|
||||
|
||||
| 类型 | 文件 | 说明 |
|
||||
|:---|:---|:---|
|
||||
| 完整版 | `卡若Ai的文件夹/导出/读书笔记/纳瓦尔访谈_读书笔记.md` | 五行 + 问答 + 人物 + 金句 + Mermaid + 使用规则 |
|
||||
| 精简版 | `卡若Ai的文件夹/导出/读书笔记/曾仕强_易经_读书笔记.md` | 按主题分块 + 要点小结 + 整理时间 |
|
||||
| 完整版 | `个人/2、我写的日记/读书笔记/纳瓦尔访谈_读书笔记.md` | 五行 + 问答 + 人物 + 金句 + Mermaid + 使用规则 |
|
||||
| 精简版 | `个人/2、我写的日记/读书笔记/曾仕强_易经_读书笔记.md` | 按主题分块 + 要点小结 + 整理时间 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
| `复盘/` | 按对话或任务存档的复盘(可选,聊天结尾已带复盘则可不另存) | `YYYY-MM-DD_主题_复盘.md` |
|
||||
| `报告/` | 报表、分析报告、导出结果 | 财务汇总、竞品分析、监控报告 |
|
||||
| `导出/` | 从系统/脚本导出的数据、配置备份等 | 导出的 CSV、配置备份 |
|
||||
| **读书笔记(例外)** | **统一放** `个人/2、我写的日记/读书笔记/`,**不放** 卡若Ai的文件夹 | 曾仕强_易经、纳瓦尔访谈等;见卡若读书笔记格式_固定规则 |
|
||||
|
||||
### 图片子目录规范(强制)
|
||||
|
||||
|
||||
23
运营中枢/工作台/MAX_MODE说明.md
Normal file
23
运营中枢/工作台/MAX_MODE说明.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# 卡若AI · MAX Mode 说明
|
||||
|
||||
> **规则在卡若AI 本体,不在 Cursor。** 卡若AI 每次被调用时均为 MAX Mode,定义在 `BOOTSTRAP.md`,对所有平台生效。
|
||||
> 更新:2026-02-16
|
||||
|
||||
---
|
||||
|
||||
## 一、规则放在哪里
|
||||
|
||||
- **卡若AI 本体**:`BOOTSTRAP.md` **第四节(MAX Mode)** + **第五节(执行流程)**。任何平台(Cursor、Claude、API 等)只要读 BOOTSTRAP,即按 MAX Mode 执行。
|
||||
- **Cursor**:`.cursor/rules/karuo-ai.mdc` 仅引用 BOOTSTRAP,不重复定义 MAX Mode;Cursor 内补充记忆路径、每日收集、Gitea、复盘格式等本地特有项。
|
||||
|
||||
---
|
||||
|
||||
## 二、默认行为(BOOTSTRAP 第四节)
|
||||
|
||||
- 思考更深度(多角度、边界与风险)
|
||||
- 任务拆解更细(子步骤、依赖与顺序;执行计划带精确路径/命令/预期)
|
||||
- 执行前检查联动子技能
|
||||
- 至少两轮验证
|
||||
- 复盘五块更完整
|
||||
|
||||
无需在任何平台单独开启或提问,**每次调用卡若AI 都是 MAX Mode**。
|
||||
@@ -205,3 +205,4 @@
|
||||
| 2026-03-02 03:22:12 | 🔄 卡若AI 同步 2026-03-02 03:22 | 更新:Cursor规则、水桥平台对接、水溪整理归档、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 14 个 |
|
||||
| 2026-03-02 03:27:34 | 🔄 卡若AI 同步 2026-03-02 03:27 | 更新:Cursor规则、水桥平台对接、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 14 个 |
|
||||
| 2026-03-02 04:34:31 | 🔄 卡若AI 同步 2026-03-02 04:34 | 更新:运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 14 个 |
|
||||
| 2026-03-02 04:45:41 | 🔄 卡若AI 同步 2026-03-02 04:45 | 更新:Cursor规则、总索引与入口、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 14 个 |
|
||||
|
||||
@@ -208,3 +208,4 @@
|
||||
| 2026-03-02 03:22:12 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-02 03:22 | 更新:Cursor规则、水桥平台对接、水溪整理归档、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 14 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||
| 2026-03-02 03:27:34 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-02 03:27 | 更新:Cursor规则、水桥平台对接、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 14 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||
| 2026-03-02 04:34:31 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-02 04:34 | 更新:运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 14 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||
| 2026-03-02 04:45:41 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-02 04:45 | 更新:Cursor规则、总索引与入口、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 14 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
# 卡若AI 运行模式
|
||||
|
||||
> 与「Search models / Auto / MAX Mode」类 UI 对应:用本文件切换运行模式,每次对话开始会读取此处。
|
||||
|
||||
---
|
||||
|
||||
## 当前模式
|
||||
|
||||
**当前模式:** `auto`
|
||||
|
||||
(可选值:`auto` | `max`)
|
||||
|
||||
---
|
||||
|
||||
## 切换方式
|
||||
|
||||
- **切到 MAX 模式**:用户说「开MAX模式」「切换MAX」「用MAX」「MAX模式」→ 将上方的 `auto` 改为 `max` 并保存,然后回复确认。
|
||||
- **切回 Auto 模式**:用户说「切回Auto」「用Auto」「自动模式」「Auto」→ 将上方的 `max` 改为 `auto` 并保存,然后回复确认。
|
||||
- **查当前模式**:用户说「当前什么模式」「运行模式」→ 读本文件,回复当前为 Auto 或 MAX。
|
||||
|
||||
行为差异见:`运营中枢/参考资料/卡若AI运行模式说明.md`。
|
||||
Reference in New Issue
Block a user