Files
collective-memory-repo/scripts/add-agent.sh

174 lines
3.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'USAGE'
Usage:
scripts/add-agent.sh <agent-id> [--display-name <name>] [--openclaw-config <path>] [--dry-run]
Examples:
scripts/add-agent.sh kimi-helper
scripts/add-agent.sh kimi-helper --display-name "Kimi Helper"
scripts/add-agent.sh kimi-helper --openclaw-config "$HOME/.openclaw/openclaw.json"
What it does:
1) Creates agents/<agent-id>/ with AGENT-CARD.md, AGENTS.md, current.md, inbox.md, drafts/
2) Prints QMD path JSON snippet for OpenClaw memory.qmd.paths
3) If --openclaw-config is provided, appends this agent path into the config (idempotent)
USAGE
}
if [[ $# -lt 1 ]]; then
usage
exit 1
fi
AGENT_ID="$1"
shift
if [[ ! "$AGENT_ID" =~ ^[a-z0-9][a-z0-9-]{1,62}$ ]]; then
echo "ERROR: agent-id must match regex: ^[a-z0-9][a-z0-9-]{1,62}$" >&2
exit 1
fi
DISPLAY_NAME="$AGENT_ID"
OPENCLAW_CONFIG=""
DRY_RUN="false"
while [[ $# -gt 0 ]]; do
case "$1" in
--display-name)
DISPLAY_NAME="${2:-}"
shift 2
;;
--openclaw-config)
OPENCLAW_CONFIG="${2:-}"
shift 2
;;
--dry-run)
DRY_RUN="true"
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "ERROR: unknown arg: $1" >&2
usage
exit 1
;;
esac
done
REPO_ROOT="$(git rev-parse --show-toplevel)"
cd "$REPO_ROOT"
TARGET_DIR="agents/${AGENT_ID}"
if [[ -e "$TARGET_DIR" ]]; then
echo "ERROR: ${TARGET_DIR} already exists" >&2
exit 1
fi
create_files() {
mkdir -p "$TARGET_DIR/drafts"
cat > "$TARGET_DIR/AGENT-CARD.md" <<CARD
# AGENT-CARD: ${AGENT_ID}
- agent_id: \`${AGENT_ID}\`
- display_name: \`${DISPLAY_NAME}\`
- writable_scope: \`agents/${AGENT_ID}/**\`
- query_authority: \`remote MCP/QMD\`
- promote_target: \`shared/long-term/**\`
CARD
cat > "$TARGET_DIR/AGENTS.md" <<GUIDE
# AGENTS.md (agents/${AGENT_ID})
## 工作根路径
- 当前工作根路径 = 本文件所在目录(\`memory-repo/agents/${AGENT_ID}/\`)。
- 仅在本目录维护该 agent 的私域工作记忆。
## 目录类型
- 类型:\`agent\`。
## 目录作用
- 私域工作记忆:当前上下文、待办、草稿。
## 查询规则
- 群体共享记忆查询必须走远程 MCP/QMD。
- 本地检索仅用于未 push 草稿、故障降级、本地调试。
## Git 规则
- 修改前先 \`git fetch --prune origin\`,再 \`git pull --rebase\`。
- 小步提交,避免跨 lane 混改。
## Promote 规则
- 稳定结论通过 task 或 promote 流程进入 \`shared/long-term/\`。
GUIDE
cat > "$TARGET_DIR/current.md" <<CURRENT
# current
- agent_id: ${AGENT_ID}
- focus: <当前任务焦点>
- next_action: <下一个动作>
CURRENT
cat > "$TARGET_DIR/inbox.md" <<INBOX
# inbox
- [ ] <待整理记忆 1>
INBOX
}
QMD_SNIPPET=$(cat <<SNIPPET
{
"path": "~/project/collective-memory-repo/agents/${AGENT_ID}",
"name": "collective-agent-${AGENT_ID}",
"pattern": "**/*.md"
}
SNIPPET
)
if [[ "$DRY_RUN" == "true" ]]; then
echo "[dry-run] would create: ${TARGET_DIR}/"
echo
echo "QMD path snippet:"
echo "$QMD_SNIPPET"
exit 0
fi
create_files
echo "Created ${TARGET_DIR}"
echo
echo "QMD path snippet (append into memory.qmd.paths):"
echo "$QMD_SNIPPET"
if [[ -n "$OPENCLAW_CONFIG" ]]; then
if ! command -v jq >/dev/null 2>&1; then
echo "WARN: jq not found, skip updating openclaw config: ${OPENCLAW_CONFIG}" >&2
exit 0
fi
if [[ ! -f "$OPENCLAW_CONFIG" ]]; then
echo "WARN: openclaw config not found: ${OPENCLAW_CONFIG}" >&2
exit 0
fi
TMP_FILE="${OPENCLAW_CONFIG}.tmp.$$"
jq --arg p "~/project/collective-memory-repo/agents/${AGENT_ID}" \
--arg n "collective-agent-${AGENT_ID}" \
'
.memory.qmd.paths |= (
if any(.[]?; .path == $p and .name == $n) then .
else . + [{"path": $p, "name": $n, "pattern": "**/*.md"}]
end
)
' "$OPENCLAW_CONFIG" > "$TMP_FILE"
mv "$TMP_FILE" "$OPENCLAW_CONFIG"
echo "Updated OpenClaw config: ${OPENCLAW_CONFIG}"
fi