@bolloon/bolloon-agent 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/bolloon-cli.cjs +15 -4
- package/bin/ipfs +0 -0
- package/dist/agents/parse-tool-call.js +304 -0
- package/dist/agents/pi-sdk.js +201 -291
- package/dist/agents/react-loop.js +120 -0
- package/dist/agents/session-store.js +157 -0
- package/dist/agents/tool-registry.js +136 -0
- package/dist/agents/workflow-pivot-loop.js +40 -0
- package/dist/bollharness/src/index.js +5 -0
- package/dist/bollharness/src/scripts/checks/check_adr_plan_numbering.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_api_types.js +45 -0
- package/dist/bollharness/src/scripts/checks/check_artifact_link.js +146 -0
- package/dist/bollharness/src/scripts/checks/check_bridge_deps.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_bugfix_binding.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_bugfix_binding_ci.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_doc_file_references.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_doc_freshness.js +135 -0
- package/dist/bollharness/src/scripts/checks/check_doc_links.js +31 -0
- package/dist/bollharness/src/scripts/checks/check_file_existence_claims.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_fragment_integrity.js +34 -0
- package/dist/bollharness/src/scripts/checks/check_hook_installed.js +63 -0
- package/dist/bollharness/src/scripts/checks/check_issue_closure.js +41 -0
- package/dist/bollharness/src/scripts/checks/check_mcp_parity.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_security.js +48 -0
- package/dist/bollharness/src/scripts/checks/check_skill_parity.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_versions.js +6 -0
- package/dist/bollharness/src/scripts/checks/finding.js +13 -0
- package/dist/bollharness/src/scripts/checks/next_decision_number.js +20 -0
- package/dist/bollharness/src/scripts/checks/regenerate_magic_docs.js +6 -0
- package/dist/bollharness/src/scripts/ci/detect_rebaseline_triggers.js +8 -0
- package/dist/bollharness/src/scripts/ci/scan_subprocess_cfg.js +8 -0
- package/dist/bollharness/src/scripts/ci/scan_verify_artifacts.js +8 -0
- package/dist/bollharness/src/scripts/ci/scan_yaml_schema.js +8 -0
- package/dist/bollharness/src/scripts/context_router.js +67 -0
- package/dist/bollharness/src/scripts/deploy-guard.js +157 -0
- package/dist/bollharness/src/scripts/guard-feedback.js +192 -0
- package/dist/bollharness/src/scripts/guard_router.js +158 -0
- package/dist/bollharness/src/scripts/hooks/_hook_output.js +6 -0
- package/dist/bollharness/src/scripts/hooks/auto-python3.js +6 -0
- package/dist/bollharness/src/scripts/hooks/deploy-progress-on-session-end.js +6 -0
- package/dist/bollharness/src/scripts/hooks/failure-analyzer.js +6 -0
- package/dist/bollharness/src/scripts/hooks/gate-judgment-inject.js +92 -0
- package/dist/bollharness/src/scripts/hooks/gate-transition-judgment.js +63 -0
- package/dist/bollharness/src/scripts/hooks/inbox-ack.js +6 -0
- package/dist/bollharness/src/scripts/hooks/inbox-inject-on-start.js +6 -0
- package/dist/bollharness/src/scripts/hooks/inbox-validate.js +6 -0
- package/dist/bollharness/src/scripts/hooks/inbox-write-ledger.js +6 -0
- package/dist/bollharness/src/scripts/hooks/initializer-agent.js +6 -0
- package/dist/bollharness/src/scripts/hooks/loop-detection.js +73 -0
- package/dist/bollharness/src/scripts/hooks/owner-guard.js +6 -0
- package/dist/bollharness/src/scripts/hooks/precompact.js +6 -0
- package/dist/bollharness/src/scripts/hooks/review-agent-gatekeeper.js +6 -0
- package/dist/bollharness/src/scripts/hooks/risk-tracker.js +108 -0
- package/dist/bollharness/src/scripts/hooks/sanitize-on-read.js +6 -0
- package/dist/bollharness/src/scripts/hooks/session-reflection.js +7 -0
- package/dist/bollharness/src/scripts/hooks/session-start-magic-docs.js +7 -0
- package/dist/bollharness/src/scripts/hooks/session-start-reset-risk.js +7 -0
- package/dist/bollharness/src/scripts/hooks/session-start-toolkit-reminder.js +7 -0
- package/dist/bollharness/src/scripts/hooks/stop-evaluator.js +157 -0
- package/dist/bollharness/src/scripts/hooks/tool-call-counter.js +6 -0
- package/dist/bollharness/src/scripts/hooks/trace-analyzer.js +10 -0
- package/dist/bollharness/src/scripts/install/install-trust-token.js +7 -0
- package/dist/bollharness/src/scripts/install/multi_project_registry.js +9 -0
- package/dist/bollharness/src/scripts/install/phase2_auto.js +21 -0
- package/dist/bollharness/src/scripts/install/pre_commit_installer.js +6 -0
- package/dist/bollharness/src/scripts/install/tier_selector.js +7 -0
- package/dist/bollharness/src/scripts/install/transcript_miner.js +7 -0
- package/dist/bollharness/src/scripts/lib/claim_patterns.js +10 -0
- package/dist/bollharness/src/scripts/lib/sanitize_patterns.js +12 -0
- package/dist/bollharness/src/scripts/sanitize.js +6 -0
- package/dist/constraint-runtime/src/tools/PolymarketSDK/cancelOrder.js +6 -0
- package/dist/constraint-runtime/src/tools/PolymarketSDK/createOrder.js +6 -0
- package/dist/constraint-runtime/src/tools/PolymarketSDK/getMarket.js +5 -0
- package/dist/constraint-runtime/src/tools/PolymarketSDK/getOrders.js +6 -0
- package/dist/constraint-runtime/src/tools/PolymarketSDK/listMarkets.js +4 -0
- package/dist/constraint-runtime/src/tools/SafeSDK/deploySafe.js +6 -0
- package/dist/constraint-runtime/src/tools/WalletTools/autoPay.js +29 -0
- package/dist/constraint-runtime/src/tools/WalletTools/createWallet.js +10 -0
- package/dist/constraint-runtime/src/tools/WalletTools/getBalance.js +13 -0
- package/dist/constraint-runtime/src/tools/WalletTools/importWallet.js +22 -0
- package/dist/constraint-runtime/src/tools/WalletTools/sendTransaction.js +25 -0
- package/dist/constraint-runtime/src/tools/WalletTools/signMessage.js +10 -0
- package/dist/constraint-runtime/src/tools/WalletTools/transferToken.js +25 -0
- package/dist/electron/config.js.map +1 -0
- package/dist/electron/dialogs.js.map +1 -0
- package/dist/electron/first-run.js.map +1 -0
- package/dist/electron/ipc.js.map +1 -0
- package/dist/electron/logger.js.map +1 -0
- package/dist/electron/main.js.map +1 -0
- package/dist/electron/menu.js.map +1 -0
- package/dist/electron/paths.js.map +1 -0
- package/dist/electron/server.js.map +1 -0
- package/dist/electron/tray.js.map +1 -0
- package/dist/electron/window.js.map +1 -0
- package/dist/electron-preload.js +29 -0
- package/dist/electron-preload.js.map +1 -0
- package/dist/electron.js +5 -0
- package/dist/electron.js.map +1 -0
- package/dist/llm/config-store.js +24 -8
- package/dist/llm/pi-ai.js +33 -19
- package/dist/web/server.js +16 -1
- package/dist/workflows/collaboration.js +374 -0
- package/dist/workflows/index.js +54 -0
- package/package.json +12 -3
- package/CLAUDE.md +0 -3
- package/build/icon.icns +0 -0
- package/build/icon.ico +0 -0
- package/build/icon.png +0 -0
- package/build/tray.png +0 -0
- package/build/trayTemplate.png +0 -0
- package/ios/App/App/AppDelegate.swift +0 -49
- package/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png +0 -0
- package/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -14
- package/ios/App/App/Assets.xcassets/Contents.json +0 -6
- package/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json +0 -23
- package/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png +0 -0
- package/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png +0 -0
- package/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png +0 -0
- package/ios/App/App/Base.lproj/LaunchScreen.storyboard +0 -32
- package/ios/App/App/Base.lproj/Main.storyboard +0 -19
- package/ios/App/App/Info.plist +0 -88
- package/ios/App/App.xcodeproj/project.pbxproj +0 -376
- package/ios/App/App.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- package/ios/App/CapApp-SPM/Package.swift +0 -25
- package/ios/App/CapApp-SPM/README.md +0 -5
- package/ios/App/CapApp-SPM/Sources/CapApp-SPM/CapApp-SPM.swift +0 -1
- package/ios/debug.xcconfig +0 -1
- package/scripts/auto-evolve-oneshot.sh +0 -155
- package/scripts/auto-evolve-snapshot.sh +0 -136
- package/scripts/build-app-bundle.cjs +0 -170
- package/scripts/build-cli.js +0 -216
- package/scripts/detect-schema-changes.sh +0 -48
- package/scripts/lefthook-helper.sh +0 -69
- package/scripts/postinstall.js +0 -153
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# auto-evolve-snapshot.sh — 阶段 C 护栏 2 + 3
|
|
3
|
-
#
|
|
4
|
-
# 用法 (LLM 改源码前必调):
|
|
5
|
-
# bash scripts/auto-evolve-snapshot.sh # 打 baseline tag + 记当前 HEAD
|
|
6
|
-
# bash scripts/auto-evolve-snapshot.sh apply <patch-id> # 人类批准后合并 staging → main
|
|
7
|
-
# bash scripts/auto-evolve-snapshot.sh list # 列所有 baseline
|
|
8
|
-
# bash scripts/auto-evolve-snapshot.sh rollback <tag> # 回滚到指定 baseline
|
|
9
|
-
#
|
|
10
|
-
# 流程:
|
|
11
|
-
# 1. LLM 改之前调 snapshot: 当前 HEAD 打 auto-evolve-baseline-<ts> tag
|
|
12
|
-
# 2. LLM 改 staging/auto-evolve/<patch-id>/ (不进 src/)
|
|
13
|
-
# 3. 护栏 1 (lefthook) 跑 vitest + tsc, 坏就 abort
|
|
14
|
-
# 4. 护栏 4 (reviewer hook) 审 diff, 通过才准 apply
|
|
15
|
-
# 5. 人类调 apply: git apply staging/auto-evolve/<patch-id>/*.patch → src/
|
|
16
|
-
# 6. 出问题: 调 rollback → git reset --hard <tag>
|
|
17
|
-
|
|
18
|
-
set -euo pipefail
|
|
19
|
-
|
|
20
|
-
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
21
|
-
cd "$REPO_ROOT"
|
|
22
|
-
|
|
23
|
-
STAGING_DIR="staging/auto-evolve"
|
|
24
|
-
TAG_PREFIX="auto-evolve-baseline-"
|
|
25
|
-
|
|
26
|
-
cmd="${1:-snapshot}"
|
|
27
|
-
patch_id="${2:-}"
|
|
28
|
-
|
|
29
|
-
case "$cmd" in
|
|
30
|
-
snapshot)
|
|
31
|
-
# 护栏 2: 打 baseline tag
|
|
32
|
-
if ! git diff --quiet HEAD 2>/dev/null; then
|
|
33
|
-
echo "❌ 有未提交改动. 先 git commit 或 git stash"
|
|
34
|
-
exit 1
|
|
35
|
-
fi
|
|
36
|
-
ts="$(date -u +%Y%m%dT%H%M%SZ)"
|
|
37
|
-
tag="${TAG_PREFIX}${ts}"
|
|
38
|
-
git tag -a "$tag" -m "auto-evolve baseline @ ${ts}" HEAD
|
|
39
|
-
echo "✅ baseline tag: $tag"
|
|
40
|
-
echo "$tag" > .last-auto-evolve-baseline
|
|
41
|
-
echo " 回滚命令: bash $0 rollback $tag"
|
|
42
|
-
;;
|
|
43
|
-
|
|
44
|
-
prepare)
|
|
45
|
-
# LLM 改之前调: 创建 staging 目录
|
|
46
|
-
if [ -z "$patch_id" ]; then
|
|
47
|
-
echo "用法: $0 prepare <patch-id>"
|
|
48
|
-
exit 1
|
|
49
|
-
fi
|
|
50
|
-
mkdir -p "$STAGING_DIR/$patch_id"
|
|
51
|
-
echo "$patch_id" > "$STAGING_DIR/$patch_id/.patch-id"
|
|
52
|
-
echo "✅ staging 创建: $STAGING_DIR/$patch_id/"
|
|
53
|
-
echo " LLM 改完后把 patch 放这里: $STAGING_DIR/$patch_id/*.patch"
|
|
54
|
-
;;
|
|
55
|
-
|
|
56
|
-
apply)
|
|
57
|
-
# 人类批准: 把 staging 的 patch 合并到 src/
|
|
58
|
-
if [ -z "$patch_id" ]; then
|
|
59
|
-
echo "用法: $0 apply <patch-id>"
|
|
60
|
-
exit 1
|
|
61
|
-
fi
|
|
62
|
-
patch_dir="$STAGING_DIR/$patch_id"
|
|
63
|
-
if [ ! -d "$patch_dir" ]; then
|
|
64
|
-
echo "❌ staging 不存在: $patch_dir"
|
|
65
|
-
exit 1
|
|
66
|
-
fi
|
|
67
|
-
# 必须先 snapshot
|
|
68
|
-
if [ ! -f .last-auto-evolve-baseline ]; then
|
|
69
|
-
echo "❌ 没有 baseline. 先跑: $0 snapshot"
|
|
70
|
-
exit 1
|
|
71
|
-
fi
|
|
72
|
-
baseline="$(cat .last-auto-evolve-baseline)"
|
|
73
|
-
|
|
74
|
-
# 应用所有 patch
|
|
75
|
-
applied=0
|
|
76
|
-
for p in "$patch_dir"/*.patch; do
|
|
77
|
-
[ -e "$p" ] || continue
|
|
78
|
-
echo " applying: $p"
|
|
79
|
-
if ! git apply --check "$p"; then
|
|
80
|
-
echo "❌ patch 不可用: $p (可能已应用过)"
|
|
81
|
-
exit 1
|
|
82
|
-
fi
|
|
83
|
-
git apply "$p"
|
|
84
|
-
applied=$((applied + 1))
|
|
85
|
-
done
|
|
86
|
-
|
|
87
|
-
if [ $applied -eq 0 ]; then
|
|
88
|
-
echo "❌ staging 里没有 .patch 文件"
|
|
89
|
-
exit 1
|
|
90
|
-
fi
|
|
91
|
-
|
|
92
|
-
echo "✅ 应用 $applied 个 patch"
|
|
93
|
-
echo " 建议现在跑: npm test + git commit -m 'auto-evolve: $patch_id'"
|
|
94
|
-
echo " 出问题回滚: $0 rollback $baseline"
|
|
95
|
-
;;
|
|
96
|
-
|
|
97
|
-
rollback)
|
|
98
|
-
# 回滚到指定 baseline
|
|
99
|
-
if [ -z "$patch_id" ]; then
|
|
100
|
-
echo "用法: $0 rollback <tag>"
|
|
101
|
-
echo "可用的 baseline:"
|
|
102
|
-
git tag -l "${TAG_PREFIX}*" | sort -r | head -10
|
|
103
|
-
exit 1
|
|
104
|
-
fi
|
|
105
|
-
if ! git tag -l | grep -qx "$patch_id"; then
|
|
106
|
-
echo "❌ tag 不存在: $patch_id"
|
|
107
|
-
exit 1
|
|
108
|
-
fi
|
|
109
|
-
echo "⚠️ 将回滚到 $patch_id (hard reset, 丢弃之后所有改动)"
|
|
110
|
-
read -p "确认? [y/N] " -n 1 -r
|
|
111
|
-
echo
|
|
112
|
-
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
113
|
-
git reset --hard "$patch_id"
|
|
114
|
-
echo "✅ 回滚到 $patch_id"
|
|
115
|
-
else
|
|
116
|
-
echo "取消"
|
|
117
|
-
fi
|
|
118
|
-
;;
|
|
119
|
-
|
|
120
|
-
list)
|
|
121
|
-
echo "auto-evolve baselines (最近 10):"
|
|
122
|
-
git tag -l "${TAG_PREFIX}*" | sort -r | head -10 | while read tag; do
|
|
123
|
-
msg="$(git tag -l --format='%(contents)' "$tag" | head -1)"
|
|
124
|
-
echo " $tag — $msg"
|
|
125
|
-
done
|
|
126
|
-
if [ -f .last-auto-evolve-baseline ]; then
|
|
127
|
-
echo ""
|
|
128
|
-
echo "当前 baseline: $(cat .last-auto-evolve-baseline)"
|
|
129
|
-
fi
|
|
130
|
-
;;
|
|
131
|
-
|
|
132
|
-
*)
|
|
133
|
-
echo "用法: $0 {snapshot|prepare <id>|apply <id>|rollback <tag>|list}"
|
|
134
|
-
exit 1
|
|
135
|
-
;;
|
|
136
|
-
esac
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* scripts/build-app-bundle.js
|
|
3
|
-
*
|
|
4
|
-
* 手搓 macOS .app bundle, 完全绕过 electron-builder 的 npm walker
|
|
5
|
-
* (那个 walker 在 1.1G @rayhanadev + app-builder-lib@26.x 下 OOM, 见
|
|
6
|
-
* memory/electron-pack-oom-2026-06-24.md).
|
|
7
|
-
*
|
|
8
|
-
* 步骤:
|
|
9
|
-
* 1. 复制 node_modules/electron/dist/Electron.app → release/mac-arm64/Bolloon Agent.app
|
|
10
|
-
* 2. 替换 Contents/Info.plist + PkgInfo + icon.icns
|
|
11
|
-
* 3. 复制 dist/ + node_modules/ + package.json → Contents/Resources/app/
|
|
12
|
-
* 4. (可选) 复制 build/tray.png → Contents/Resources/build/ (给 tray 用)
|
|
13
|
-
*
|
|
14
|
-
* 输出: release/mac-arm64/Bolloon Agent.app (可直接 open /Applications)
|
|
15
|
-
* 不生成 .dmg — 用 electron-builder --prepackaged 后续可补 (但现在跳过)
|
|
16
|
-
*/
|
|
17
|
-
const fs = require('fs');
|
|
18
|
-
const path = require('path');
|
|
19
|
-
const { execSync } = require('child_process');
|
|
20
|
-
|
|
21
|
-
const ROOT = path.resolve(__dirname, '..');
|
|
22
|
-
const ELECTRON_DIST = path.join(ROOT, 'node_modules', 'electron', 'dist');
|
|
23
|
-
const ELECTRON_APP = path.join(ELECTRON_DIST, 'Electron.app');
|
|
24
|
-
const APP_NAME = 'Bolloon Agent';
|
|
25
|
-
const PRODUCT_NAME = 'Bolloon Agent';
|
|
26
|
-
const APP_ID = 'com.bolloon.agent';
|
|
27
|
-
const OUTPUT_DIR = path.join(ROOT, 'release', 'mac-arm64');
|
|
28
|
-
const TARGET_APP = path.join(OUTPUT_DIR, `${APP_NAME}.app`);
|
|
29
|
-
|
|
30
|
-
function log(msg) {
|
|
31
|
-
console.log(`[build-app-bundle] ${msg}`);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function rmrf(p) {
|
|
35
|
-
if (fs.existsSync(p)) fs.rmSync(p, { recursive: true, force: true });
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function copyDir(src, dst) {
|
|
39
|
-
fs.mkdirSync(dst, { recursive: true });
|
|
40
|
-
execSync(`cp -R "${src}/." "${dst}/"`, { stdio: 'inherit' });
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function writeInfoPlist(appPath) {
|
|
44
|
-
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
45
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
46
|
-
<plist version="1.0">
|
|
47
|
-
<dict>
|
|
48
|
-
<key>CFBundleName</key>
|
|
49
|
-
<string>${APP_NAME}</string>
|
|
50
|
-
<key>CFBundleDisplayName</key>
|
|
51
|
-
<string>${APP_NAME}</string>
|
|
52
|
-
<key>CFBundleExecutable</key>
|
|
53
|
-
<string>Electron</string>
|
|
54
|
-
<key>CFBundleIdentifier</key>
|
|
55
|
-
<string>${APP_ID}</string>
|
|
56
|
-
<key>CFBundleVersion</key>
|
|
57
|
-
<string>0.1.42</string>
|
|
58
|
-
<key>CFBundleShortVersionString</key>
|
|
59
|
-
<string>0.1.42</string>
|
|
60
|
-
<key>CFBundleInfoDictionaryVersion</key>
|
|
61
|
-
<string>6.0</string>
|
|
62
|
-
<key>CFBundlePackageType</key>
|
|
63
|
-
<string>APPL</string>
|
|
64
|
-
<key>CFBundleSignature</key>
|
|
65
|
-
<string>????</string>
|
|
66
|
-
<key>LSMinimumSystemVersion</key>
|
|
67
|
-
<string>10.13.0</string>
|
|
68
|
-
<key>NSHighResolutionCapable</key>
|
|
69
|
-
<true/>
|
|
70
|
-
<key>NSPrincipalClass</key>
|
|
71
|
-
<string>NSApplication</string>
|
|
72
|
-
<key>LSApplicationCategoryType</key>
|
|
73
|
-
<string>public.app-category.productivity</string>
|
|
74
|
-
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
|
75
|
-
<true/>
|
|
76
|
-
<key>ElectronAsarIntegrity</key>
|
|
77
|
-
<dict/>
|
|
78
|
-
<key>NSAppTransportSecurity</key>
|
|
79
|
-
<dict>
|
|
80
|
-
<key>NSAllowsLocalNetworking</key>
|
|
81
|
-
<true/>
|
|
82
|
-
</dict>
|
|
83
|
-
</dict>
|
|
84
|
-
</plist>
|
|
85
|
-
`;
|
|
86
|
-
fs.writeFileSync(path.join(appPath, 'Contents', 'Info.plist'), plist);
|
|
87
|
-
fs.writeFileSync(path.join(appPath, 'Contents', 'PkgInfo'), 'APPL????');
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function main() {
|
|
91
|
-
if (!fs.existsSync(ELECTRON_APP)) {
|
|
92
|
-
console.error(`[build-app-bundle] FATAL: ${ELECTRON_APP} not found. Run: node node_modules/electron/install.js`);
|
|
93
|
-
process.exit(1);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
log(`Cleaning ${OUTPUT_DIR}`);
|
|
97
|
-
rmrf(OUTPUT_DIR);
|
|
98
|
-
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
|
|
99
|
-
|
|
100
|
-
log(`Copying Electron.app → ${TARGET_APP}`);
|
|
101
|
-
copyDir(ELECTRON_APP, TARGET_APP);
|
|
102
|
-
|
|
103
|
-
log(`Writing Info.plist + PkgInfo`);
|
|
104
|
-
writeInfoPlist(TARGET_APP);
|
|
105
|
-
|
|
106
|
-
// 替换 icon
|
|
107
|
-
const iconSrc = path.join(ROOT, 'build', 'icon.icns');
|
|
108
|
-
if (fs.existsSync(iconSrc)) {
|
|
109
|
-
log(`Copying icon: ${iconSrc}`);
|
|
110
|
-
fs.copyFileSync(iconSrc, path.join(TARGET_APP, 'Contents', 'Resources', 'electron.icns'));
|
|
111
|
-
} else {
|
|
112
|
-
log(`WARN: ${iconSrc} missing — app will use default Electron icon`);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// 复制 app 内容 → Contents/Resources/app/
|
|
116
|
-
const appContentDir = path.join(TARGET_APP, 'Contents', 'Resources', 'app');
|
|
117
|
-
log(`Building app content dir: ${appContentDir}`);
|
|
118
|
-
rmrf(appContentDir);
|
|
119
|
-
fs.mkdirSync(appContentDir, { recursive: true });
|
|
120
|
-
|
|
121
|
-
log(`Copying dist/`);
|
|
122
|
-
copyDir(path.join(ROOT, 'dist'), path.join(appContentDir, 'dist'));
|
|
123
|
-
|
|
124
|
-
log(`Copying package.json`);
|
|
125
|
-
fs.copyFileSync(path.join(ROOT, 'package.json'), path.join(appContentDir, 'package.json'));
|
|
126
|
-
|
|
127
|
-
log(`Copying node_modules/ (excluding devDeps) — this is the slow part`);
|
|
128
|
-
// 不能用 rsync 因为 OOM, 用 cp -R
|
|
129
|
-
const srcNm = path.join(ROOT, 'node_modules');
|
|
130
|
-
const dstNm = path.join(appContentDir, 'node_modules');
|
|
131
|
-
fs.mkdirSync(dstNm, { recursive: true });
|
|
132
|
-
// 排除大且 dev-only 的 packages, 但 @rayhanadev 必须保留 (生产代码用)
|
|
133
|
-
const entries = fs.readdirSync(srcNm);
|
|
134
|
-
let count = 0;
|
|
135
|
-
for (const name of entries) {
|
|
136
|
-
if (name.startsWith('.')) continue;
|
|
137
|
-
const src = path.join(srcNm, name);
|
|
138
|
-
const dst = path.join(dstNm, name);
|
|
139
|
-
fs.cpSync(src, dst, { recursive: true, dereference: false, filter: (s) => {
|
|
140
|
-
// 跳过 .bin, .cache, .package-lock.json
|
|
141
|
-
const base = path.basename(s);
|
|
142
|
-
if (base === '.bin' || base === '.cache' || base === '.package-lock.json') return false;
|
|
143
|
-
// 跳过 doc/test/assets 巨型 dir, 运行时不需要
|
|
144
|
-
if (base === 'test' || base === 'docs' || base === '__tests__') return false;
|
|
145
|
-
return true;
|
|
146
|
-
}});
|
|
147
|
-
count++;
|
|
148
|
-
if (count % 20 === 0) log(` copied ${count}/${entries.length} node_modules/*`);
|
|
149
|
-
}
|
|
150
|
-
log(`Copied ${count} node_modules entries`);
|
|
151
|
-
|
|
152
|
-
// 复制 bin/
|
|
153
|
-
const binSrc = path.join(ROOT, 'bin');
|
|
154
|
-
if (fs.existsSync(binSrc)) {
|
|
155
|
-
log(`Copying bin/`);
|
|
156
|
-
copyDir(binSrc, path.join(appContentDir, 'bin'));
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// 复制 build/ → Resources/build/ (tray 图标用)
|
|
160
|
-
const buildSrc = path.join(ROOT, 'build');
|
|
161
|
-
if (fs.existsSync(buildSrc)) {
|
|
162
|
-
log(`Copying build/ → Resources/build/`);
|
|
163
|
-
copyDir(buildSrc, path.join(TARGET_APP, 'Contents', 'Resources', 'build'));
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
log(`Done. App bundle: ${TARGET_APP}`);
|
|
167
|
-
log(`To run: open "${TARGET_APP}"`);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
main();
|
package/scripts/build-cli.js
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLI 构建脚本
|
|
3
|
-
*
|
|
4
|
-
* 生成 bin/bolloon.js 和 bin/bolloon.cmd 入口文件
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import * as fs from 'fs';
|
|
8
|
-
import * as path from 'path';
|
|
9
|
-
import { fileURLToPath } from 'url';
|
|
10
|
-
|
|
11
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
-
const __dirname = path.dirname(__filename);
|
|
13
|
-
const rootDir = path.join(__dirname, '..');
|
|
14
|
-
|
|
15
|
-
const binDir = path.join(rootDir, 'bin');
|
|
16
|
-
if (!fs.existsSync(binDir)) {
|
|
17
|
-
fs.mkdirSync(binDir, { recursive: true });
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// Windows 批处理入口
|
|
21
|
-
const winContent = `@echo off
|
|
22
|
-
set "BOLLOON_ROOT=%~dp0"
|
|
23
|
-
set "BOLLOON_ROOT=%BOLLOON_ROOT:~0,-1%"
|
|
24
|
-
|
|
25
|
-
REM 确定入口文件
|
|
26
|
-
set "ENTRY=%BOLLOON_ROOT%\\dist\\index.js"
|
|
27
|
-
if not exist "%ENTRY%" (
|
|
28
|
-
set "ENTRY=%BOLLOON_ROOT%\\src\\index.ts"
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
node "%ENTRY%" %*
|
|
32
|
-
`;
|
|
33
|
-
|
|
34
|
-
fs.writeFileSync(path.join(binDir, 'bolloon.cmd'), winContent);
|
|
35
|
-
|
|
36
|
-
// Unix/Linux/Mac 入口脚本
|
|
37
|
-
const unixContent = `#!/usr/bin/env node
|
|
38
|
-
const path = require("path");
|
|
39
|
-
const { spawn } = require("child_process");
|
|
40
|
-
const fs = require("fs");
|
|
41
|
-
|
|
42
|
-
const RESET = "\\x1b[0m";
|
|
43
|
-
const BOLD = "\\x1b[1m";
|
|
44
|
-
const CYAN = "\\x1b[36m";
|
|
45
|
-
const GREEN = "\\x1b[32m";
|
|
46
|
-
const MAGENTA = "\\x1b[35m";
|
|
47
|
-
|
|
48
|
-
function log(msg, color) {
|
|
49
|
-
console.log((color || RESET) + msg + RESET);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function printBanner() {
|
|
53
|
-
console.log("\\n" + CYAN + BOLD + [
|
|
54
|
-
" ╔═══════════════════════════════════════════╗",
|
|
55
|
-
" ║ 🤖 Bolloon Agent ║",
|
|
56
|
-
" ║ P2P AI Document Processor ║",
|
|
57
|
-
" ╚═══════════════════════════════════════════╝"
|
|
58
|
-
].join("\\n") + RESET + "\\n");
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function getMainEntry() {
|
|
62
|
-
const distDir = path.dirname(require.main.filename);
|
|
63
|
-
const distIndex = path.join(distDir, "index.js");
|
|
64
|
-
if (fs.existsSync(distIndex)) {
|
|
65
|
-
return distIndex;
|
|
66
|
-
}
|
|
67
|
-
return path.join(process.cwd(), "src", "index.ts");
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function parseArgs() {
|
|
71
|
-
const args = process.argv.slice(2);
|
|
72
|
-
if (args.length === 0) {
|
|
73
|
-
return { mode: "gui", args: [] };
|
|
74
|
-
}
|
|
75
|
-
const first = args[0];
|
|
76
|
-
switch (first) {
|
|
77
|
-
case "-v":
|
|
78
|
-
case "--version":
|
|
79
|
-
return { mode: "version", args: [] };
|
|
80
|
-
case "-h":
|
|
81
|
-
case "--help":
|
|
82
|
-
return { mode: "help", args: [] };
|
|
83
|
-
case "-g":
|
|
84
|
-
case "--gui":
|
|
85
|
-
return { mode: "gui", args: args.slice(1) };
|
|
86
|
-
case "-w":
|
|
87
|
-
case "--web":
|
|
88
|
-
return { mode: "web", args: args.slice(1) };
|
|
89
|
-
case "-c":
|
|
90
|
-
case "--cli":
|
|
91
|
-
return { mode: "cli", args: args.slice(1) };
|
|
92
|
-
default:
|
|
93
|
-
return { mode: "passthrough", args };
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
async function startElectron(additionalArgs) {
|
|
98
|
-
try {
|
|
99
|
-
const electron = require("electron");
|
|
100
|
-
const distDir = path.dirname(require.main.filename);
|
|
101
|
-
let mainPath = path.join(distDir, "electron.js");
|
|
102
|
-
if (!fs.existsSync(mainPath)) {
|
|
103
|
-
mainPath = path.join(process.cwd(), "src", "electron.ts");
|
|
104
|
-
}
|
|
105
|
-
log("启动 Electron...", CYAN);
|
|
106
|
-
const child = spawn(electron, [mainPath, ...additionalArgs], {
|
|
107
|
-
stdio: "inherit",
|
|
108
|
-
env: { ...process.env, NODE_ENV: "development" }
|
|
109
|
-
});
|
|
110
|
-
child.on("error", (err) => {
|
|
111
|
-
log("Electron 启动失败: " + err.message, MAGENTA);
|
|
112
|
-
process.exit(1);
|
|
113
|
-
});
|
|
114
|
-
child.on("exit", (code) => process.exit(code || 0));
|
|
115
|
-
} catch (err) {
|
|
116
|
-
log("Electron 不可用,切换到 Web 模式...", CYAN);
|
|
117
|
-
await startWebServer(additionalArgs);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
async function startWebServer(additionalArgs) {
|
|
122
|
-
const mainPath = getMainEntry();
|
|
123
|
-
const webArgs = ["--web", ...additionalArgs];
|
|
124
|
-
log("启动 Web 服务...", CYAN);
|
|
125
|
-
const child = spawn(process.execPath, [mainPath, ...webArgs], { stdio: "inherit" });
|
|
126
|
-
child.on("error", (err) => {
|
|
127
|
-
log("Web 服务启动失败: " + err.message, MAGENTA);
|
|
128
|
-
process.exit(1);
|
|
129
|
-
});
|
|
130
|
-
child.on("exit", (code) => process.exit(code || 0));
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
async function startCLI(additionalArgs) {
|
|
134
|
-
const mainPath = getMainEntry();
|
|
135
|
-
log("启动命令行界面...", CYAN);
|
|
136
|
-
const child = spawn(process.execPath, [mainPath, ...additionalArgs], { stdio: "inherit" });
|
|
137
|
-
child.on("error", (err) => {
|
|
138
|
-
log("CLI 启动失败: " + err.message, MAGENTA);
|
|
139
|
-
process.exit(1);
|
|
140
|
-
});
|
|
141
|
-
child.on("exit", (code) => process.exit(code || 0));
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
async function main() {
|
|
145
|
-
const { mode, args } = parseArgs();
|
|
146
|
-
switch (mode) {
|
|
147
|
-
case "version":
|
|
148
|
-
console.log("Bolloon Agent v0.1.1");
|
|
149
|
-
break;
|
|
150
|
-
case "help":
|
|
151
|
-
printBanner();
|
|
152
|
-
console.log(BOLD + "用法:" + RESET + " bolloon [选项] [命令] [参数]");
|
|
153
|
-
console.log(BOLD + "选项:" + RESET + " --gui, -g 启动图形界面");
|
|
154
|
-
console.log(" --web, -w 启动 Web UI");
|
|
155
|
-
console.log(" --cli, -c 启动命令行界面");
|
|
156
|
-
console.log(" --version, -v 显示版本");
|
|
157
|
-
console.log(" --help, -h 显示帮助");
|
|
158
|
-
console.log(BOLD + "示例:" + RESET + " bolloon # 启动图形界面");
|
|
159
|
-
console.log(" bolloon --web # 启动 Web UI");
|
|
160
|
-
console.log(" bolloon --read file # 读取文档");
|
|
161
|
-
break;
|
|
162
|
-
case "gui":
|
|
163
|
-
printBanner();
|
|
164
|
-
await startElectron(args);
|
|
165
|
-
break;
|
|
166
|
-
case "web":
|
|
167
|
-
printBanner();
|
|
168
|
-
await startWebServer(args);
|
|
169
|
-
break;
|
|
170
|
-
case "cli":
|
|
171
|
-
await startCLI(args);
|
|
172
|
-
break;
|
|
173
|
-
case "passthrough":
|
|
174
|
-
const mainPath = getMainEntry();
|
|
175
|
-
const child = spawn(process.execPath, [mainPath, ...args], { stdio: "inherit" });
|
|
176
|
-
child.on("error", (err) => {
|
|
177
|
-
log("执行失败: " + err.message, MAGENTA);
|
|
178
|
-
process.exit(1);
|
|
179
|
-
});
|
|
180
|
-
child.on("exit", (code) => process.exit(code || 0));
|
|
181
|
-
break;
|
|
182
|
-
default:
|
|
183
|
-
log("未知模式: " + mode, MAGENTA);
|
|
184
|
-
printBanner();
|
|
185
|
-
console.log("输入 --help 查看帮助");
|
|
186
|
-
process.exit(1);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
main().catch((err) => {
|
|
191
|
-
console.error("Fatal error:", err);
|
|
192
|
-
process.exit(1);
|
|
193
|
-
});
|
|
194
|
-
`;
|
|
195
|
-
|
|
196
|
-
fs.writeFileSync(path.join(binDir, 'bolloon.cjs'), unixContent);
|
|
197
|
-
|
|
198
|
-
// 确保 bin/bolloon.js 存在(npm link 需要)
|
|
199
|
-
// 优先用符号链接(POSIX),Windows 上若权限不足则退化为复制文件
|
|
200
|
-
const jsSymlink = path.join(binDir, 'bolloon.js');
|
|
201
|
-
if (fs.existsSync(jsSymlink)) fs.unlinkSync(jsSymlink);
|
|
202
|
-
try {
|
|
203
|
-
fs.symlinkSync('bolloon.cjs', jsSymlink);
|
|
204
|
-
} catch (err) {
|
|
205
|
-
if (err && err.code === 'EPERM') {
|
|
206
|
-
fs.copyFileSync(path.join(binDir, 'bolloon.cjs'), jsSymlink);
|
|
207
|
-
console.warn(' ⚠ symlink 不支持(Windows),已退化为文件复制');
|
|
208
|
-
} else {
|
|
209
|
-
throw err;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
console.log("✓ CLI 构建完成");
|
|
214
|
-
console.log(" bin/bolloon.cjs - CommonJS 入口");
|
|
215
|
-
console.log(" bin/bolloon.js - 符号链接 -> bolloon.cjs");
|
|
216
|
-
console.log(" bin/bolloon.cmd - Windows 入口");
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# detect-schema-changes.sh — 阶段 C 护栏 6
|
|
3
|
-
#
|
|
4
|
-
# 检查 LLM 改的文件里有没有动 schema (interface / type / enum 声明)
|
|
5
|
-
# 有则强制要求 reviewer 双签 (在 .auto-evolve-review-required 文件)
|
|
6
|
-
#
|
|
7
|
-
# 用法 (在 staging 准备好 patch 后, apply 前):
|
|
8
|
-
# bash scripts/detect-schema-changes.sh <patch-id>
|
|
9
|
-
|
|
10
|
-
set -euo pipefail
|
|
11
|
-
|
|
12
|
-
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
13
|
-
cd "$REPO_ROOT"
|
|
14
|
-
|
|
15
|
-
patch_id="${1:-}"
|
|
16
|
-
if [ -z "$patch_id" ]; then
|
|
17
|
-
echo "用法: $0 <patch-id>"
|
|
18
|
-
exit 1
|
|
19
|
-
fi
|
|
20
|
-
|
|
21
|
-
staging_dir="staging/auto-evolve/$patch_id"
|
|
22
|
-
if [ ! -d "$staging_dir" ]; then
|
|
23
|
-
echo "❌ staging 不存在: $staging_dir"
|
|
24
|
-
exit 1
|
|
25
|
-
fi
|
|
26
|
-
|
|
27
|
-
flag="$staging_dir/.schema-changed"
|
|
28
|
-
rm -f "$flag"
|
|
29
|
-
|
|
30
|
-
found=0
|
|
31
|
-
for patch in "$staging_dir"/*.patch; do
|
|
32
|
-
[ -e "$patch" ] || continue
|
|
33
|
-
# 检查 patch 里有没有新增/修改 interface、type、enum 声明
|
|
34
|
-
if grep -E '^\+.*(interface |type [A-Z][a-zA-Z0-9_]* =|enum [A-Z][a-zA-Z0-9_]*)' "$patch" > /dev/null 2>&1; then
|
|
35
|
-
found=1
|
|
36
|
-
echo "⚠️ schema 改动检测到: $patch"
|
|
37
|
-
grep -E '^\+.*(interface |type [A-Z][a-zA-Z0-9_]* =|enum [A-Z][a-zA-Z0-9_]*)' "$patch" | head -3
|
|
38
|
-
fi
|
|
39
|
-
done
|
|
40
|
-
|
|
41
|
-
if [ $found -eq 1 ]; then
|
|
42
|
-
touch "$flag"
|
|
43
|
-
echo ""
|
|
44
|
-
echo "🚨 schema 改动标记: $flag"
|
|
45
|
-
echo " 护栏 6 触发: apply 时会强制要求双签 reviewer"
|
|
46
|
-
else
|
|
47
|
-
echo "✅ 无 schema 改动, 走单签"
|
|
48
|
-
fi
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
# 2026-06-17: lefthook helper — agent auto-evolve branch detection
|
|
3
|
-
# 写在独立文件里避免 lefthook 嵌套引号 + Windows bash 解析问题
|
|
4
|
-
# 用法: lefthook.yml 里 run: sh scripts/lefthook-helper.sh <command>
|
|
5
|
-
# <command> = commit | vitest-full | build-check | tag-baseline
|
|
6
|
-
|
|
7
|
-
CMD="$1"
|
|
8
|
-
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo none)
|
|
9
|
-
AUTO_EVOLVE_MSG=$(git log -1 --pretty=%B 2>/dev/null | head -1 | grep -c ^auto-evolve: || echo 0)
|
|
10
|
-
|
|
11
|
-
is_master_main() {
|
|
12
|
-
[ "$BRANCH" = "master" ] || [ "$BRANCH" = "main" ]
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
is_auto_evolve() {
|
|
16
|
-
if [ "$BOLLOON_AUTO_EVOLVE" = "1" ]; then return 0; fi
|
|
17
|
-
if [ "$AUTO_EVOLVE_MSG" -gt 0 ] 2>/dev/null; then return 0; fi
|
|
18
|
-
return 1
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
case "$CMD" in
|
|
22
|
-
commit-vitest-bail)
|
|
23
|
-
if is_auto_evolve; then
|
|
24
|
-
echo "[skip] vitest-bail (auto-evolve mode, branch=$BRANCH)"
|
|
25
|
-
exit 0
|
|
26
|
-
fi
|
|
27
|
-
npx vitest run --bail=1 --reporter=dot
|
|
28
|
-
;;
|
|
29
|
-
commit-tsc-check)
|
|
30
|
-
if is_auto_evolve; then
|
|
31
|
-
echo "[skip] tsc-check (auto-evolve mode, branch=$BRANCH)"
|
|
32
|
-
exit 0
|
|
33
|
-
fi
|
|
34
|
-
npx tsc --noEmit
|
|
35
|
-
;;
|
|
36
|
-
push-vitest-full)
|
|
37
|
-
if is_master_main; then
|
|
38
|
-
npx vitest run --reporter=dot
|
|
39
|
-
else
|
|
40
|
-
echo "[skip] vitest-full (branch=$BRANCH, not master/main)"
|
|
41
|
-
exit 0
|
|
42
|
-
fi
|
|
43
|
-
;;
|
|
44
|
-
push-build-check)
|
|
45
|
-
if is_master_main; then
|
|
46
|
-
npm run build:main
|
|
47
|
-
else
|
|
48
|
-
echo "[skip] build-check (branch=$BRANCH, not master/main)"
|
|
49
|
-
exit 0
|
|
50
|
-
fi
|
|
51
|
-
;;
|
|
52
|
-
push-tag-baseline)
|
|
53
|
-
if is_master_main; then
|
|
54
|
-
if git tag -l 'auto-evolve-baseline-*' | grep -q .; then
|
|
55
|
-
exit 0
|
|
56
|
-
else
|
|
57
|
-
echo "[ERROR] push to master/main requires auto-evolve-baseline-* tag. Run: bash scripts/auto-evolve-snapshot.sh"
|
|
58
|
-
exit 1
|
|
59
|
-
fi
|
|
60
|
-
else
|
|
61
|
-
echo "[skip] tag-baseline (branch=$BRANCH, not master/main)"
|
|
62
|
-
exit 0
|
|
63
|
-
fi
|
|
64
|
-
;;
|
|
65
|
-
*)
|
|
66
|
-
echo "Unknown command: $CMD"
|
|
67
|
-
exit 1
|
|
68
|
-
;;
|
|
69
|
-
esac
|