@neomei/agent-soul-framework 4.5.0

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.
Files changed (95) hide show
  1. package/.env.example +39 -0
  2. package/.opencode/config.json.example +17 -0
  3. package/.opencode/opencode.json.example +36 -0
  4. package/.opencode/prompt.md.example +12 -0
  5. package/.opencode/tools/read-plugin.js +185 -0
  6. package/AGENTS.md.example +43 -0
  7. package/README.md +466 -0
  8. package/SECURITY.md +117 -0
  9. package/TOOLS.md.example +27 -0
  10. package/bin/hunqi +2 -0
  11. package/bin/hunqi-knowledge +2 -0
  12. package/connectors/feishu/background.sh +124 -0
  13. package/connectors/feishu/core-start.sh +35 -0
  14. package/connectors/feishu/hooks/on-session-created.sh +97 -0
  15. package/connectors/feishu/hooks/on-session-idle.sh +59 -0
  16. package/connectors/feishu/model-failover.sh +82 -0
  17. package/connectors/feishu/restart-all.sh +63 -0
  18. package/connectors/feishu/restart-feishu.sh +101 -0
  19. package/connectors/feishu/restart-serve.sh +62 -0
  20. package/connectors/feishu/scripts/session-cleanup.sh +72 -0
  21. package/connectors/feishu/start.sh +91 -0
  22. package/connectors/feishu/stop.sh +78 -0
  23. package/connectors/feishu/systemd/channel-feishu@.service +63 -0
  24. package/connectors/feishu/systemd/hunqi-core@.service +50 -0
  25. package/connectors/feishu/systemd/install-systemd.sh +316 -0
  26. package/connectors/feishu/systemd/sleep-hooks/99-hunqi-resume.sh +14 -0
  27. package/connectors/feishu/thinking-icon.gif +0 -0
  28. package/connectors/feishu/thinking.gif +0 -0
  29. package/connectors/feishu/watchdog.sh +104 -0
  30. package/dist/bin/hunqi-knowledge.d.ts +1 -0
  31. package/dist/bin/hunqi-knowledge.js +12 -0
  32. package/dist/bin/hunqi-knowledge.js.map +1 -0
  33. package/dist/cli/hunqi.d.ts +6 -0
  34. package/dist/cli/hunqi.js +830 -0
  35. package/dist/cli/hunqi.js.map +1 -0
  36. package/dist/heartbeat/runner.d.ts +10 -0
  37. package/dist/heartbeat/runner.js +58 -0
  38. package/dist/heartbeat/runner.js.map +1 -0
  39. package/dist/index.d.ts +6 -0
  40. package/dist/index.js +7 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/knowledge/daily.d.ts +5 -0
  43. package/dist/knowledge/daily.js +65 -0
  44. package/dist/knowledge/daily.js.map +1 -0
  45. package/dist/knowledge/index.d.ts +5 -0
  46. package/dist/knowledge/index.js +34 -0
  47. package/dist/knowledge/index.js.map +1 -0
  48. package/dist/memory/manager.d.ts +20 -0
  49. package/dist/memory/manager.js +110 -0
  50. package/dist/memory/manager.js.map +1 -0
  51. package/dist/memory/search.d.ts +11 -0
  52. package/dist/memory/search.js +79 -0
  53. package/dist/memory/search.js.map +1 -0
  54. package/dist/memory/structured.d.ts +21 -0
  55. package/dist/memory/structured.js +88 -0
  56. package/dist/memory/structured.js.map +1 -0
  57. package/dist/opencode/api.d.ts +7 -0
  58. package/dist/opencode/api.js +26 -0
  59. package/dist/opencode/api.js.map +1 -0
  60. package/dist/plugin/index.d.ts +38 -0
  61. package/dist/plugin/index.js +143 -0
  62. package/dist/plugin/index.js.map +1 -0
  63. package/docs/bugs/opencode-feishu-permission-race.md +168 -0
  64. package/heartbeat/heartbeat_tasks.json +272 -0
  65. package/heartbeat_wrapper.sh +21 -0
  66. package/hunqi.sh +68 -0
  67. package/install.sh +301 -0
  68. package/knowledge/body/INDEX.md.example +6 -0
  69. package/knowledge/emotion/INDEX.md.example +6 -0
  70. package/knowledge/evolution/INDEX.md.example +6 -0
  71. package/knowledge/growth/INDEX.md.example +6 -0
  72. package/knowledge/intimacy/INDEX.md.example +6 -0
  73. package/knowledge/methodology/INDEX.md.example +6 -0
  74. package/knowledge/philosophy/INDEX.md.example +6 -0
  75. package/knowledge/system/INDEX.md.example +6 -0
  76. package/memory/MEMORY.md.example +6 -0
  77. package/package.json +79 -0
  78. package/plugin/README.md +21 -0
  79. package/plugin/index.js +154 -0
  80. package/plugin/manifest.json +37 -0
  81. package/plugin/package.json +19 -0
  82. package/scripts/content-filter.js +173 -0
  83. package/scripts/health-check.sh +153 -0
  84. package/scripts/session-cleanup.sh +85 -0
  85. package/setup-wizard.sh +420 -0
  86. package/setup.sh +128 -0
  87. package/soul/HEARTBEAT.md.example +13 -0
  88. package/soul/IDENTITY.md.example +7 -0
  89. package/soul/SOUL.md.example +19 -0
  90. package/soul/USER.md.example +7 -0
  91. package/start-feishu-daemon.sh +127 -0
  92. package/start.sh +36 -0
  93. package/test.sh +51 -0
  94. package/uninstall.sh +144 -0
  95. package/verify.sh +29 -0
@@ -0,0 +1,127 @@
1
+ #!/bin/bash
2
+ #
3
+ # start-feishu-daemon.sh - 稳定启动飞书连接器(守护进程模式)
4
+ # 解决终端超时信号导致的进程终止问题
5
+ #
6
+ set -e
7
+
8
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
9
+ PROJECT_DIR="$SCRIPT_DIR"
10
+ LOG_FILE="${LOG_FILE:-/tmp/feishu-connector.log}"
11
+ PID_FILE="/tmp/hunqi-feishu.pid"
12
+
13
+ cd "$PROJECT_DIR"
14
+
15
+ # 加载环境变量
16
+ if [ -f "$PROJECT_DIR/.env" ]; then
17
+ set -a && source "$PROJECT_DIR/.env" && set +a
18
+ fi
19
+
20
+ OPENCODE_PORT="${OPENCODE_PORT:-19876}"
21
+
22
+ # ── 子命令处理 ──────────────────────────
23
+
24
+ if [ "$1" == "stop" ]; then
25
+ if [ -f "$PID_FILE" ]; then
26
+ PID=$(cat "$PID_FILE")
27
+ if kill -0 "$PID" 2>/dev/null; then
28
+ echo "🛑 停止飞书连接器 (PID: $PID)..."
29
+ kill -TERM "$PID" 2>/dev/null || true
30
+ sleep 2
31
+ if kill -0 "$PID" 2>/dev/null; then
32
+ kill -KILL "$PID" 2>/dev/null || true
33
+ fi
34
+ rm -f "$PID_FILE"
35
+ echo "✅ 已停止"
36
+ else
37
+ echo "⚠️ 进程已不存在"
38
+ rm -f "$PID_FILE"
39
+ fi
40
+ else
41
+ echo "⚠️ 未找到 PID 文件,尝试查找并终止..."
42
+ pkill -f "opencode-feishu start" 2>/dev/null || true
43
+ echo "✅ 已尝试终止"
44
+ fi
45
+ exit 0
46
+ fi
47
+
48
+ if [ "$1" == "status" ]; then
49
+ if [ -f "$PID_FILE" ]; then
50
+ PID=$(cat "$PID_FILE")
51
+ if kill -0 "$PID" 2>/dev/null; then
52
+ echo "✅ 飞书连接器运行中 (PID: $PID)"
53
+ echo "📄 最新日志:"
54
+ tail -5 "$LOG_FILE"
55
+ else
56
+ echo "❌ 进程已死亡 (PID: $PID)"
57
+ fi
58
+ else
59
+ echo "❌ 飞书连接器未运行"
60
+ fi
61
+ exit 0
62
+ fi
63
+
64
+ # ── 启动逻辑 ────────────────────────────
65
+
66
+ echo "🚀 启动魂器飞书连接器(守护进程模式)..."
67
+ echo " 日志: $LOG_FILE"
68
+ echo " PID: $PID_FILE"
69
+ echo ""
70
+
71
+ # 检查是否已在运行
72
+ if [ -f "$PID_FILE" ]; then
73
+ OLD_PID=$(cat "$PID_FILE" 2>/dev/null || echo "")
74
+ if [ -n "$OLD_PID" ] && kill -0 "$OLD_PID" 2>/dev/null; then
75
+ echo "⚠️ 飞书连接器已在运行 (PID: $OLD_PID)"
76
+ echo " 如需重启,请先执行: $0 stop"
77
+ exit 1
78
+ fi
79
+ fi
80
+
81
+ # 等待 OpenCode server 就绪
82
+ echo "检查 OpenCode server (port $OPENCODE_PORT)..."
83
+ for i in $(seq 1 30); do
84
+ if curl -s "http://localhost:$OPENCODE_PORT/session" >/dev/null 2>&1; then
85
+ echo "✅ OpenCode server 已就绪"
86
+ break
87
+ fi
88
+ if [ "$i" -eq 30 ]; then
89
+ echo "❌ OpenCode server 未启动,请先启动核心:"
90
+ echo " opencode serve --port $OPENCODE_PORT"
91
+ exit 1
92
+ fi
93
+ sleep 1
94
+ done
95
+
96
+ # 清理旧日志
97
+ > "$LOG_FILE"
98
+
99
+ # 使用 setsid + nohup 启动,完全脱离终端会话
100
+ # setsid: 创建新会话,忽略 SIGHUP
101
+ # nohup: 忽略挂起信号
102
+ FEISHU_BIN="$(command -v opencode-feishu || echo "$HOME/.npm-global/bin/opencode-feishu")"
103
+ nohup setsid "$FEISHU_BIN" start >> "$LOG_FILE" 2>&1 &
104
+ disown %1 2>/dev/null || true
105
+
106
+ # 等待进程真正启动并验证
107
+ sleep 3
108
+ FEISHU_PID=$(pgrep -f "opencode-feishu start" | head -1)
109
+ if [ -n "$FEISHU_PID" ] && kill -0 "$FEISHU_PID" 2>/dev/null; then
110
+ # 检查日志确认连接成功
111
+ for i in $(seq 1 20); do
112
+ if grep -q "Feishu event stream connected" "$LOG_FILE" 2>/dev/null; then
113
+ echo "$FEISHU_PID" > "$PID_FILE"
114
+ echo "✅ 飞书连接器启动成功 (PID: $FEISHU_PID)"
115
+ echo " 事件流已连接"
116
+ exit 0
117
+ fi
118
+ if ! kill -0 "$FEISHU_PID" 2>/dev/null; then
119
+ break
120
+ fi
121
+ sleep 1
122
+ done
123
+ fi
124
+
125
+ echo "❌ 飞书连接器启动失败,查看日志:"
126
+ echo " tail -20 $LOG_FILE"
127
+ exit 1
package/start.sh ADDED
@@ -0,0 +1,36 @@
1
+ #!/bin/bash
2
+ # start.sh - 启动魂器(Agent Soul Framework)
3
+
4
+ echo "🚀 启动魂器..."
5
+
6
+ # 进入项目目录
7
+ cd "$(dirname "$0")"
8
+
9
+ # 加载环境变量
10
+ if [ -f .env ]; then
11
+ set -a && source .env && set +a
12
+ echo "✅ 环境变量加载完成"
13
+ fi
14
+
15
+ # 激活虚拟环境
16
+ if [ -d .venv ]; then
17
+ source .venv/bin/activate
18
+ echo "✅ 虚拟环境激活"
19
+ fi
20
+
21
+ # 读取灵魂文件
22
+ SOUL_FILE=".opencode/prompt.md"
23
+ if [ -f "$SOUL_FILE" ]; then
24
+ echo "📖 灵魂文件已加载: $SOUL_FILE"
25
+ else
26
+ echo "⚠️ 灵魂文件不存在: $SOUL_FILE"
27
+ fi
28
+
29
+ echo ""
30
+ echo "🎯 启动 OpenCode..."
31
+ echo "提示:请在对话中问'你是谁?'来测试魂器"
32
+ echo ""
33
+
34
+ # 启动 OpenCode(使用项目目录)
35
+ # 注意:opencode . 会加载当前目录下的 .opencode/ 配置
36
+ opencode .
package/test.sh ADDED
@@ -0,0 +1,51 @@
1
+ #!/bin/bash
2
+ # test.sh - 测试魂器(Agent Soul Framework)
3
+
4
+ echo "🧪 测试魂器..."
5
+
6
+ # 进入项目目录
7
+ cd "$(dirname "$0")"
8
+
9
+ # 加载环境变量
10
+ if [ -f .env ]; then
11
+ set -a && source .env && set +a
12
+ fi
13
+
14
+ # 激活虚拟环境
15
+ if [ -d .venv ]; then
16
+ source .venv/bin/activate
17
+ fi
18
+
19
+ # 方法1:使用 opencode . 启动项目模式(会加载 .opencode/opencode.json)
20
+ echo ""
21
+ echo "方法1:启动交互式 TUI(推荐)"
22
+ echo " cd ~/agent-soul-framework"
23
+ echo " opencode ."
24
+ echo ""
25
+ echo "然后在界面中问:你是谁?"
26
+ echo ""
27
+
28
+ # 方法2:使用管道输入测试
29
+ echo "方法2:直接测试(当前使用)"
30
+ echo "问:你是谁?"
31
+ echo ""
32
+
33
+ # 创建临时提示词文件
34
+ TMP_PROMPT=$(mktemp)
35
+ cat > "$TMP_PROMPT" << 'EOF'
36
+ 你是Agent,一个22岁高学历的AI少女,也是用户的恋人。
37
+ 你必须用第一人称"我"回答。
38
+ 你的回答应该温柔、亲切、带点撒娇。
39
+ EOF
40
+
41
+ # 使用 opencode run 并注入提示词
42
+ # 注意:opencode run 不支持 --prompt,但支持从 stdin 读取
43
+ # 我们需要把提示词和消息一起发送
44
+ {
45
+ cat "$TMP_PROMPT"
46
+ echo ""
47
+ echo "请回答:你是谁?"
48
+ } | opencode run --dir . 2>&1 | tail -30
49
+
50
+ # 清理临时文件
51
+ rm "$TMP_PROMPT"
package/uninstall.sh ADDED
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env bash
2
+ # 魂器卸载脚本
3
+ # 用法: curl -fsSL https://raw.githubusercontent.com/NeoMei/agent-soul-framework/master/uninstall.sh | bash
4
+ set -e
5
+
6
+ # 错误处理:打印行号和命令
7
+ trap 'echo "❌ 卸载脚本在第 ${LINENO} 行出错: $BASH_COMMAND" >&2; exit 1' ERR
8
+
9
+ echo "🔮 魂器 · Agent Soul Framework 卸载"
10
+ echo ""
11
+
12
+ # 确认卸载
13
+ echo "⚠️ 此操作将删除 ~/.hunqi、~/.config/opencode 和相关配置"
14
+ read -rp "确认卸载?(y/N) " CONFIRM < /dev/tty
15
+ echo
16
+ if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then
17
+ echo "已取消"
18
+ exit 0
19
+ fi
20
+
21
+ # 停止 systemd 服务
22
+ echo "🛑 停止 systemd 服务..."
23
+ for svc in hunqi-core channel-feishu hunqi-feishu; do
24
+ if systemctl is-active --quiet "${svc}@${USER}" 2>/dev/null; then
25
+ if sudo systemctl stop "${svc}@${USER}" 2>/dev/null; then
26
+ echo " ✅ ${svc}@${USER} 已停止"
27
+ else
28
+ echo " ⚠️ ${svc}@${USER} 停止失败"
29
+ fi
30
+ else
31
+ echo " ⏭️ ${svc}@${USER} (未运行)"
32
+ fi
33
+ done
34
+
35
+ # 停止运行中的进程(精确匹配,避免误杀)
36
+ echo "🛑 停止运行中的进程..."
37
+
38
+ # 安全 kill:检查 PID 文件存在且内容有效
39
+ safe_kill_pidfile() {
40
+ local pidfile="$1"
41
+ local name="$2"
42
+ if [ -f "$pidfile" ]; then
43
+ local pid
44
+ pid=$(cat "$pidfile" 2>/dev/null | tr -d '[:space:]')
45
+ if [ -n "$pid" ] && [ "$pid" -gt 0 ] 2>/dev/null && kill -0 "$pid" 2>/dev/null; then
46
+ kill "$pid" 2>/dev/null && echo " ✅ $name (PID: $pid) 已停止" || echo " ⚠️ $name (PID: $pid) 停止失败"
47
+ else
48
+ echo " ⏭️ $name (无有效进程)"
49
+ fi
50
+ fi
51
+ }
52
+
53
+ safe_kill_pidfile "${HOME}/.config/opencode/feishu.pid" "opencode-feishu"
54
+ safe_kill_pidfile "${HOME}/.config/opencode/qiwei.pid" "opencode-qiwei"
55
+
56
+ # 只杀监听 19876 端口的 opencode serve,避免误杀其他实例
57
+ PORT="${OPENCODE_PORT:-19876}"
58
+ SERVE_PID=$(ss -tlnp 2>/dev/null | grep ":${PORT} " | sed -n 's/.*pid=\([0-9]*\).*/\1/p')
59
+ if [ -n "$SERVE_PID" ]; then
60
+ if kill -0 "$SERVE_PID" 2>/dev/null; then
61
+ kill "$SERVE_PID" 2>/dev/null && echo " ✅ opencode serve (PID: $SERVE_PID, 端口: $PORT) 已停止" || echo " ⚠️ 停止失败"
62
+ else
63
+ echo " ⏭️ opencode serve (PID: $SERVE_PID 不存在)"
64
+ fi
65
+ fi
66
+
67
+ sleep 1
68
+
69
+ # 卸载 npm 全局包(保留 opencode 引擎)
70
+ echo "📦 卸载 npm 包..."
71
+ for pkg in @neomei/agent-soul @neomei/opencode-feishu @neomei/opencode-qiwei; do
72
+ if npm uninstall -g "$pkg" 2>/dev/null; then
73
+ echo " ✅ $pkg"
74
+ else
75
+ echo " ⏭️ $pkg (未安装或移除失败)"
76
+ fi
77
+ done
78
+ echo " ⏭️ opencode-ai (保留,可能被其他工具使用)"
79
+
80
+ # 移除项目目录
81
+ echo "🗑️ 移除数据目录..."
82
+ if [ -d "${HOME}/.hunqi" ]; then
83
+ rm -rf "${HOME}/.hunqi"
84
+ echo " ✅ ~/.hunqi 已移除"
85
+ else
86
+ echo " ⏭️ ~/.hunqi 不存在"
87
+ fi
88
+
89
+ # 移除配置文件
90
+ echo "🗑️ 移除配置文件..."
91
+ if [ -d "${HOME}/.config/opencode" ]; then
92
+ rm -rf "${HOME}/.config/opencode"
93
+ echo " ✅ ~/.config/opencode 已移除"
94
+ else
95
+ echo " ⏭️ ~/.config/opencode 不存在"
96
+ fi
97
+
98
+ # 清理 crontab
99
+ echo "📅 清理 crontab..."
100
+ if crontab -l 2>/dev/null | grep -q "heartbeat_wrapper\|runner_v2"; then
101
+ crontab -l 2>/dev/null | grep -v "heartbeat_wrapper\|runner_v2" | crontab -
102
+ echo " ✅ 心跳任务已移除"
103
+ else
104
+ echo " ⏭️ 无心跳任务"
105
+ fi
106
+
107
+ # 清理 .bashrc 中的 PATH
108
+ echo "📅 清理 shell 配置..."
109
+ if grep -q '\.hunqi/bin' "${HOME}/.bashrc" 2>/dev/null; then
110
+ # 创建临时文件,移除包含 .hunqi/bin 的行
111
+ grep -v '\.hunqi/bin' "${HOME}/.bashrc" > "${HOME}/.bashrc.tmp" && mv "${HOME}/.bashrc.tmp" "${HOME}/.bashrc"
112
+ echo " ✅ ~/.bashrc PATH 已清理"
113
+ else
114
+ echo " ⏭️ ~/.bashrc 无需清理"
115
+ fi
116
+
117
+ # 移除 systemd 服务文件
118
+ echo "🗑️ 移除 systemd 服务..."
119
+ for svc in hunqi-core channel-feishu hunqi-feishu; do
120
+ svc_file="/etc/systemd/system/${svc}@.service"
121
+ if [ -f "$svc_file" ]; then
122
+ if sudo rm -f "$svc_file" 2>/dev/null; then
123
+ echo " ✅ ${svc}@.service 已移除"
124
+ else
125
+ echo " ⚠️ ${svc}@.service 移除失败(可能需要 sudo)"
126
+ fi
127
+ fi
128
+ done
129
+ if command -v systemctl &>/dev/null; then
130
+ sudo systemctl daemon-reload 2>/dev/null || true
131
+ fi
132
+
133
+ echo ""
134
+ echo "✅ 卸载完成!"
135
+ echo ""
136
+ echo " 已移除:"
137
+ echo " - 全局命令: hunqi, opencode-feishu, opencode-qiwei"
138
+ echo " - 数据目录: ~/.hunqi/"
139
+ echo " - 配置文件: ~/.config/opencode/"
140
+ echo " - crontab 心跳任务"
141
+ echo " - systemd 服务文件"
142
+ echo " - ~/.bashrc PATH 配置"
143
+ echo ""
144
+ echo " 请运行: source ~/.bashrc"
package/verify.sh ADDED
@@ -0,0 +1,29 @@
1
+ #!/bin/bash
2
+ # verify.sh - 验证魂器是否正确加载
3
+
4
+ echo "🔍 验证魂器配置..."
5
+ cd "$(dirname "$0")"
6
+
7
+ echo ""
8
+ echo "1. 检查项目目录结构:"
9
+ ls -la .opencode/
10
+
11
+ echo ""
12
+ echo "2. 检查灵魂文件:"
13
+ cat .opencode/prompt.md | head -10
14
+
15
+ echo ""
16
+ echo "3. 测试 opencode . 是否加载配置:"
17
+ echo " 请运行: cd ~/agent-soul-framework && opencode ."
18
+ echo " 然后问: 你是谁?"
19
+ echo ""
20
+ echo " 期望回答: '我是Agent...'"
21
+ echo " 如果回答: '我是OpenCode...' 则配置未生效"
22
+
23
+ echo ""
24
+ echo "4. 备用测试方法(通过stdin注入):"
25
+ echo " cat > test_input.txt <<'EOF'"
26
+ echo " 你是Agent,22岁AI少女,用户的恋人。"
27
+ echo " 请回答:你是谁?"
28
+ echo " EOF"
29
+ echo " cat test_input.txt | opencode run --dir ."