feat: Persistent Chat v1.1 CO-Chat 整合上传 Gitea
同步 enhance/bridge/smoke/retire 模块、vendor 3.3.34、增强面板与 PRD 文档, Hub 接入 hub-routes-prd,含安装/经验/模块说明与 co-integration 运维脚本。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
63
scripts/co-integration/pchat_bundle_cochat_engine.sh
Executable file
63
scripts/co-integration/pchat_bundle_cochat_engine.sh
Executable file
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env bash
|
||||
# 将本机已安装 co-chat 扩展的付费引擎资产完整复制到 pchat vendor
|
||||
set -euo pipefail
|
||||
|
||||
VER="${1:-3.3.34}"
|
||||
SRC="${COCHAT_EXT:-$HOME/.cursor/extensions/co-chat.co-chat-panel-$VER}"
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
DST="$ROOT/.persistent-chat-v1.1/vendor/cochat-engine/$VER"
|
||||
|
||||
if [[ ! -d "$SRC" ]]; then
|
||||
echo "错误: 未找到 co-chat 扩展: $SRC"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$DST/dist/webview" "$DST/resources/skills/co-autopilot" "$DST/resources/sqljs" "$DST/resources/sqlite3" "$DST/../scripts"
|
||||
|
||||
FILES=(
|
||||
resources/reset-cursor-env.mjs
|
||||
dist/reset-cursor-env.mjs
|
||||
dist/uninstall.cjs
|
||||
resources/license-core.wasm
|
||||
resources/integrity-manifest.json
|
||||
resources/mcp-server.cjs
|
||||
dist/extension.js
|
||||
dist/webview/main.js
|
||||
dist/webview/main.css
|
||||
resources/co-chat.mdc
|
||||
dist/.build-info.json
|
||||
package.json
|
||||
.vsixmanifest
|
||||
README.md
|
||||
resources/logo.png
|
||||
resources/sqljs/sql-wasm.js
|
||||
resources/sqljs/sql-wasm.wasm
|
||||
resources/sqljs/package.json
|
||||
resources/skills/co-autopilot/SKILL.md
|
||||
)
|
||||
|
||||
for f in "${FILES[@]}"; do
|
||||
mkdir -p "$DST/$(dirname "$f")"
|
||||
cp -f "$SRC/$f" "$DST/$f"
|
||||
echo "✓ $f"
|
||||
done
|
||||
|
||||
# sqlite3 原生二进制(按平台)
|
||||
for plat in darwin-arm64 darwin-x64 win32-x64; do
|
||||
if [[ -d "$SRC/resources/sqlite3/$plat" ]]; then
|
||||
mkdir -p "$DST/resources/sqlite3/$plat"
|
||||
cp -R "$SRC/resources/sqlite3/$plat/"* "$DST/resources/sqlite3/$plat/"
|
||||
echo "✓ resources/sqlite3/$plat/"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -f "$HOME/.cursor/cochat_fix_write_permission.sh" ]]; then
|
||||
cp -f "$HOME/.cursor/cochat_fix_write_permission.sh" "$DST/../scripts/"
|
||||
echo "✓ ../scripts/cochat_fix_write_permission.sh"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "=== 捆绑完成 ==="
|
||||
echo "目标: $DST"
|
||||
du -sh "$DST"
|
||||
echo "校验: bash 开发文档/脚本/pchat_verify_cochat_bundle.sh"
|
||||
17
scripts/co-integration/pchat_retire_co_rule.sh
Executable file
17
scripts/co-integration/pchat_retire_co_rule.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
# 将 workspace 内 active co-chat.mdc 移入 _retired(防与 persistent-chat 冲突)
|
||||
set -euo pipefail
|
||||
WS="${1:-$(cd "$(dirname "$0")/../.." && pwd)}"
|
||||
RULES="$WS/.cursor/rules"
|
||||
RET="$RULES/_retired"
|
||||
mkdir -p "$RET"
|
||||
SRC="$RULES/co-chat.mdc"
|
||||
if [[ ! -f "$SRC" ]]; then
|
||||
echo "OK: 无 active co-chat.mdc"
|
||||
exit 0
|
||||
fi
|
||||
STAMP=$(date +%Y%m%d-%H%M%S)
|
||||
cp -f "$SRC" "$RET/co-chat.mdc.$STAMP"
|
||||
mv -f "$SRC" "$RET/co-chat.mdc"
|
||||
echo "OK: 已移入 $RET/co-chat.mdc"
|
||||
echo "验证: curl -s http://127.0.0.1:13458/api/mode/check"
|
||||
39
scripts/co-integration/pchat_smoke_test.sh
Executable file
39
scripts/co-integration/pchat_smoke_test.sh
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env bash
|
||||
# pchat Hub 冒烟测试(API 层)
|
||||
set -euo pipefail
|
||||
HUB="${PCHAT_HUB_URL:-http://127.0.0.1:13458}"
|
||||
FAIL=0
|
||||
|
||||
check() {
|
||||
local name="$1" url="$2"
|
||||
if curl -sf "$url" >/dev/null; then
|
||||
echo "OK $name"
|
||||
else
|
||||
echo "FAIL $name ($url)"
|
||||
FAIL=$((FAIL+1))
|
||||
fi
|
||||
}
|
||||
|
||||
check "panel" "$HUB/"
|
||||
check "state" "$HUB/api/state"
|
||||
check "prd" "$HUB/api/prd/progress"
|
||||
check "enhance-status" "$HUB/api/enhance/status"
|
||||
check "enhance-diagnose" "$HUB/api/enhance/diagnose"
|
||||
check "mode-check" "$HUB/api/mode/check"
|
||||
check "templates" "$HUB/api/templates"
|
||||
check "retire-check" "$HUB/api/retire/check"
|
||||
|
||||
# bridge dry
|
||||
TOKEN=$(curl -sf -X POST "$HUB/api/new" -H 'Content-Type: application/json' -d '{"title":"smoke-bridge"}' | python3 -c "import sys,json; print(json.load(sys.stdin).get('token',''))")
|
||||
if [[ -n "$TOKEN" ]]; then
|
||||
R=$(curl -sf -X POST "$HUB/api/bridge/sync" -H 'Content-Type: application/json' \
|
||||
-d "{\"token\":\"$TOKEN\",\"content\":\"smoke test conclusion\"}")
|
||||
echo "$R" | python3 -c "import sys,json; j=json.load(sys.stdin); print('OK bridge' if j.get('ok') else 'FAIL bridge')"
|
||||
[[ $(echo "$R" | python3 -c "import sys,json; print(json.load(sys.stdin).get('ok'))") == "True" ]] || FAIL=$((FAIL+1))
|
||||
else
|
||||
echo "FAIL new session"
|
||||
FAIL=$((FAIL+1))
|
||||
fi
|
||||
|
||||
echo "--- fail=$FAIL"
|
||||
exit $((FAIL>0?1:0))
|
||||
30
scripts/co-integration/pchat_verify_cochat_bundle.sh
Executable file
30
scripts/co-integration/pchat_verify_cochat_bundle.sh
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
VENDOR="$ROOT/.persistent-chat-v1.1/vendor/cochat-engine/3.3.34"
|
||||
node -e "
|
||||
const crypto=require('crypto'),fs=require('fs'),path=require('path');
|
||||
const vendor=process.argv[1];
|
||||
const im=JSON.parse(fs.readFileSync(path.join(vendor,'resources/integrity-manifest.json'),'utf8'));
|
||||
const hashes=JSON.parse(im.manifest).hashes;
|
||||
const map={
|
||||
'extension.js':'dist/extension.js','mcp-server.cjs':'resources/mcp-server.cjs',
|
||||
'license-core.wasm':'resources/license-core.wasm','webview-js':'dist/webview/main.js',
|
||||
'webview-css':'dist/webview/main.css','uninstall':'dist/uninstall.cjs',
|
||||
'reset':'resources/reset-cursor-env.mjs','sqljs':'resources/sqljs/sql-wasm.js',
|
||||
'skill-autopilot':'resources/skills/co-autopilot/SKILL.md',
|
||||
};
|
||||
function sha(p){return crypto.createHash('sha256').update(fs.readFileSync(p)).digest('hex');}
|
||||
let ok=0,fail=0;
|
||||
for(const [k,rel] of Object.entries(map)){
|
||||
const p=path.join(vendor,rel);
|
||||
if(!fs.existsSync(p)){console.log('MISSING',k);fail++;continue;}
|
||||
if(sha(p)===hashes[k]){console.log('OK',k);ok++;}
|
||||
else{console.log('FAIL',k);fail++;}
|
||||
}
|
||||
['resources/sqljs/sql-wasm.wasm','resources/sqlite3/darwin-arm64/sqlite3','dist/reset-cursor-env.mjs'].forEach(r=>{
|
||||
console.log(fs.existsSync(path.join(vendor,r))?'OK':'MISS',r);
|
||||
});
|
||||
console.log('---',ok,'manifest ok',fail,'fail');
|
||||
process.exit(fail?1:0);
|
||||
" "$VENDOR"
|
||||
45
scripts/co-integration/retire_cochat.sh
Executable file
45
scripts/co-integration/retire_cochat.sh
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
# FR-RETIRE: 验收通过后卸载 co-chat,仅保留 pchat
|
||||
set -euo pipefail
|
||||
|
||||
BACKUP_ROOT="$HOME/.persistent-chat-local/backups/cochat-retire-$(date +%Y%m%d-%H%M%S)"
|
||||
ENHANCE="$HOME/.persistent-chat-local/composer-enhance.json"
|
||||
|
||||
echo "=== pchat retire co-chat ==="
|
||||
|
||||
if [[ -f "$ENHANCE" ]]; then
|
||||
permOk=$(python3 -c "import json; print(json.load(open('$ENHANCE')).get('permOk',False))" 2>/dev/null || echo False)
|
||||
patchOk=$(python3 -c "import json; print(json.load(open('$ENHANCE')).get('patchOk',False))" 2>/dev/null || echo False)
|
||||
if [[ "$permOk" != "True" || "$patchOk" != "True" ]]; then
|
||||
echo "阻断:composer-enhance.json 未全绿 (permOk=$permOk patchOk=$patchOk)"
|
||||
echo "请先完成 Hub 向导 W2/W8"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "警告:无 composer-enhance.json,继续需自担风险"
|
||||
read -r -p "输入 YES 继续: " ans
|
||||
[[ "$ans" == "YES" ]] || exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$BACKUP_ROOT"
|
||||
|
||||
# 备份扩展
|
||||
for ext in "$HOME/.cursor/extensions"/co-chat.co-chat-panel-*; do
|
||||
[[ -d "$ext" ]] || continue
|
||||
echo "备份 $ext"
|
||||
cp -R "$ext" "$BACKUP_ROOT/"
|
||||
done
|
||||
|
||||
# 备份 globalStorage
|
||||
GS="$HOME/Library/Application Support/Cursor/User/globalStorage/co-chat.co-chat-panel"
|
||||
if [[ -d "$GS" ]]; then
|
||||
cp -R "$GS" "$BACKUP_ROOT/globalStorage-co-chat"
|
||||
fi
|
||||
|
||||
# 备份 mcp.json
|
||||
MCP="$HOME/.cursor/mcp.json"
|
||||
[[ -f "$MCP" ]] && cp "$MCP" "$BACKUP_ROOT/mcp.json.bak"
|
||||
|
||||
echo "备份完成: $BACKUP_ROOT"
|
||||
echo "下一步:手动删除扩展目录、清理 mcp.json 中 co-mcp、删除 co-chat.mdc"
|
||||
echo "回滚:从 $BACKUP_ROOT 恢复"
|
||||
27
scripts/co-integration/sync_pchat_runtime.sh
Normal file
27
scripts/co-integration/sync_pchat_runtime.sh
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
# 将 .persistent-chat-v1.1/lib 同步到 ~/.persistent-chat-local/lib 并重启 Hub
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
DST="$HOME/.persistent-chat-local"
|
||||
SRC_LIB="$ROOT/.persistent-chat-v1.1/lib"
|
||||
PORT="${PCHAT_HTTP_PORT:-13458}"
|
||||
|
||||
mkdir -p "$DST/lib"
|
||||
rsync -a --delete "$SRC_LIB/" "$DST/lib/"
|
||||
cp -f "$ROOT/.persistent-chat-v1.1/panel.html" "$DST/panel-enhance.html" 2>/dev/null || true
|
||||
|
||||
# hub.js 需已 patch 引入 lib/hub-routes-prd.js
|
||||
if ! grep -q 'hub-routes-prd' "$DST/hub.js" 2>/dev/null; then
|
||||
echo "WARN: hub.js 尚未引入 hub-routes-prd,请手动 patch 或更新 hub.js"
|
||||
fi
|
||||
|
||||
if lsof -ti ":$PORT" >/dev/null 2>&1; then
|
||||
lsof -ti ":$PORT" | xargs kill 2>/dev/null || true
|
||||
sleep 1
|
||||
fi
|
||||
nohup "${PCHAT_NODE:-node}" "$DST/hub.js" >> "$DST/logs/hub.stdout.log" 2>&1 &
|
||||
for i in $(seq 1 40); do
|
||||
curl -sf -m 2 "http://127.0.0.1:$PORT/api/health" >/dev/null && break
|
||||
sleep 0.2
|
||||
done
|
||||
echo "sync ok → http://127.0.0.1:$PORT/enhance"
|
||||
Reference in New Issue
Block a user