fix: Remove Matrix integration — notifications move to forge + OpenClaw (#732)
Remove all Matrix/Dendrite infrastructure: - Delete lib/matrix_listener.sh (long-poll daemon), lib/matrix_listener.service (systemd unit), lib/hooks/on-stop-matrix.sh (response streaming hook) - Remove matrix_send() and matrix_send_ctx() from lib/env.sh - Remove MATRIX_HOMESERVER auto-detection, MATRIX_THREAD_MAP from lib/env.sh - Remove [matrix] section parsing from lib/load-project.sh - Remove Matrix hook installation from lib/agent-session.sh - Remove notify/notify_ctx helpers and Matrix thread tracking from dev/dev-agent.sh and action/action-agent.sh - Remove all matrix_send calls from dev-poll.sh, phase-handler.sh, action-poll.sh, vault-poll.sh, vault-fire.sh, vault-reject.sh, review-poll.sh, review-pr.sh, supervisor-poll.sh, formula-session.sh - Remove Matrix listener startup from docker/agents/entrypoint.sh - Remove append_dendrite_compose() and setup_matrix() from bin/disinto - Remove --matrix flag from disinto init - Clean Matrix references from .env.example, projects/*.toml.example, formulas/*.toml, AGENTS.md, BOOTSTRAP.md, README.md, RESOURCES.md, PHASE-PROTOCOL.md, and all agent AGENTS.md/PROMPT.md files Status visibility now via Codeberg PR/issue activity. Human interaction via vault items through forge. Proactive alerts via OpenClaw heartbeats. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7996bb6c06
commit
23949083c0
43 changed files with 73 additions and 1157 deletions
225
bin/disinto
225
bin/disinto
|
|
@ -156,7 +156,7 @@ generate_compose() {
|
|||
cat > "$compose_file" <<'COMPOSEEOF'
|
||||
# docker-compose.yml — generated by disinto init
|
||||
# Brings up Forgejo, Woodpecker, and the agent runtime.
|
||||
# Dendrite (Matrix) is added only when init is called with --matrix.
|
||||
# Brings up Forgejo, Woodpecker, and the agent runtime.
|
||||
|
||||
services:
|
||||
forgejo:
|
||||
|
|
@ -272,70 +272,6 @@ COMPOSEEOF
|
|||
echo "Created: ${compose_file}"
|
||||
}
|
||||
|
||||
# Append Dendrite (Matrix) service to docker-compose.yml and generate config.
|
||||
# Called only when --matrix flag is passed to init.
|
||||
append_dendrite_compose() {
|
||||
local compose_file="${FACTORY_ROOT}/docker-compose.yml"
|
||||
local dendrite_config_dir="${FACTORY_ROOT}/docker/dendrite"
|
||||
local dendrite_yaml="${dendrite_config_dir}/dendrite.yaml"
|
||||
|
||||
mkdir -p "$dendrite_config_dir"
|
||||
|
||||
# Generate a minimal dendrite.yaml
|
||||
cat > "$dendrite_yaml" <<'DENDRITECFG'
|
||||
# dendrite.yaml — generated by disinto init --matrix
|
||||
version: 2
|
||||
global:
|
||||
server_name: disinto.local
|
||||
private_key: matrix_key.pem
|
||||
database:
|
||||
connection_string: file:dendrite.db
|
||||
cache:
|
||||
max_size_estimated: 512mb
|
||||
jetstream:
|
||||
storage_path: /etc/dendrite/jetstream
|
||||
client_api:
|
||||
registration_disabled: true
|
||||
DENDRITECFG
|
||||
echo "Created: ${dendrite_yaml}"
|
||||
|
||||
# Append dendrite service before the volumes: section
|
||||
python3 -c "
|
||||
import sys, pathlib
|
||||
p = pathlib.Path(sys.argv[1])
|
||||
text = p.read_text()
|
||||
dendrite_service = '''
|
||||
dendrite:
|
||||
image: matrixdotorg/dendrite-monolith:latest
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- dendrite-data:/etc/dendrite
|
||||
- ./docker/dendrite/dendrite.yaml:/etc/dendrite/dendrite.yaml:ro
|
||||
environment:
|
||||
DENDRITE_DOMAIN: disinto.local
|
||||
networks:
|
||||
- disinto-net
|
||||
'''
|
||||
# Insert dendrite service before 'volumes:' line
|
||||
text = text.replace('\nvolumes:\n', dendrite_service + '\nvolumes:\n', 1)
|
||||
# Add dendrite-data volume
|
||||
text = text.replace(' agent-data:', ' dendrite-data:\n agent-data:')
|
||||
# Add MATRIX_HOMESERVER env var to agents service
|
||||
text = text.replace(
|
||||
' DISINTO_CONTAINER: \"1\"',
|
||||
' MATRIX_HOMESERVER: http://dendrite:8008\n DISINTO_CONTAINER: \"1\"'
|
||||
)
|
||||
# Add dendrite dependency to agents service
|
||||
text = text.replace(
|
||||
' - woodpecker\n networks:',
|
||||
' - woodpecker\n - dendrite\n networks:'
|
||||
)
|
||||
p.write_text(text)
|
||||
" "$compose_file"
|
||||
|
||||
echo "Updated: ${compose_file} (added Dendrite service)"
|
||||
}
|
||||
|
||||
# Generate docker/agents/ files if they don't already exist.
|
||||
generate_agent_docker() {
|
||||
local docker_dir="${FACTORY_ROOT}/docker/agents"
|
||||
|
|
@ -1108,151 +1044,6 @@ activate_woodpecker_repo() {
|
|||
fi
|
||||
}
|
||||
|
||||
# Provision Dendrite Matrix homeserver: create bot user, room, and access token.
|
||||
# Stores MATRIX_TOKEN, MATRIX_ROOM_ID, MATRIX_BOT_USER in .env.
|
||||
setup_matrix() {
|
||||
local use_bare="${DISINTO_BARE:-false}"
|
||||
local env_file="${FACTORY_ROOT}/.env"
|
||||
|
||||
echo ""
|
||||
echo "── Matrix setup ───────────────────────────────────────"
|
||||
|
||||
# In compose mode, Dendrite runs inside the network at http://dendrite:8008.
|
||||
# For provisioning from the host during init, we exec into the container.
|
||||
local matrix_host="http://dendrite:8008"
|
||||
|
||||
# Skip if MATRIX_TOKEN is already configured
|
||||
if [ -n "${MATRIX_TOKEN:-}" ]; then
|
||||
echo "Matrix: already configured (MATRIX_TOKEN set)"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "$use_bare" = true ]; then
|
||||
echo "Matrix: skipped in bare mode (configure manually or install Dendrite)"
|
||||
echo " See: https://matrix-org.github.io/dendrite/"
|
||||
return
|
||||
fi
|
||||
|
||||
# Wait for Dendrite to become healthy
|
||||
echo -n "Waiting for Dendrite to start"
|
||||
local retries=0
|
||||
while true; do
|
||||
# Probe Dendrite via docker compose exec since it's not exposed on the host
|
||||
local version_resp
|
||||
version_resp=$(docker compose -f "${FACTORY_ROOT}/docker-compose.yml" exec -T dendrite \
|
||||
curl -sf --max-time 3 "http://localhost:8008/_matrix/client/versions" 2>/dev/null) || version_resp=""
|
||||
if [ -n "$version_resp" ]; then
|
||||
break
|
||||
fi
|
||||
retries=$((retries + 1))
|
||||
if [ "$retries" -gt 60 ]; then
|
||||
echo ""
|
||||
echo "Warning: Dendrite did not become ready within 60s — skipping Matrix setup" >&2
|
||||
echo " Run 'disinto init' again after Dendrite is healthy" >&2
|
||||
return
|
||||
fi
|
||||
echo -n "."
|
||||
sleep 1
|
||||
done
|
||||
echo " ready"
|
||||
|
||||
# Create bot user via Dendrite's create-account tool
|
||||
local bot_localpart="factory-bot"
|
||||
local bot_user="@${bot_localpart}:disinto.local"
|
||||
local bot_pass
|
||||
bot_pass="matrix-$(head -c 16 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 24)"
|
||||
|
||||
echo "Creating Matrix bot user: ${bot_user}"
|
||||
docker compose -f "${FACTORY_ROOT}/docker-compose.yml" exec -T dendrite \
|
||||
/usr/bin/create-account \
|
||||
-config /etc/dendrite/dendrite.yaml \
|
||||
-username "${bot_localpart}" \
|
||||
-password "${bot_pass}" 2>/dev/null || true
|
||||
|
||||
# Log in to get an access token
|
||||
local login_resp
|
||||
login_resp=$(docker compose -f "${FACTORY_ROOT}/docker-compose.yml" exec -T dendrite \
|
||||
curl -sf -X POST "http://localhost:8008/_matrix/client/v3/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"type\":\"m.login.password\",\"identifier\":{\"type\":\"m.id.user\",\"user\":\"${bot_localpart}\"},\"password\":\"${bot_pass}\"}" \
|
||||
2>/dev/null) || login_resp=""
|
||||
|
||||
local access_token
|
||||
access_token=$(printf '%s' "$login_resp" | jq -r '.access_token // empty' 2>/dev/null) || access_token=""
|
||||
|
||||
if [ -z "$access_token" ]; then
|
||||
echo "Warning: failed to obtain Matrix access token — skipping Matrix setup" >&2
|
||||
echo " Create the bot user manually via Dendrite admin API" >&2
|
||||
return
|
||||
fi
|
||||
|
||||
echo " Bot login successful"
|
||||
|
||||
# Create coordination room
|
||||
local room_resp
|
||||
room_resp=$(docker compose -f "${FACTORY_ROOT}/docker-compose.yml" exec -T dendrite \
|
||||
curl -sf -X POST "http://localhost:8008/_matrix/client/v3/createRoom" \
|
||||
-H "Authorization: Bearer ${access_token}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"room_alias_name":"factory","name":"disinto factory","topic":"Autonomous code factory coordination room","preset":"private_chat"}' \
|
||||
2>/dev/null) || room_resp=""
|
||||
|
||||
local room_id
|
||||
room_id=$(printf '%s' "$room_resp" | jq -r '.room_id // empty' 2>/dev/null) || room_id=""
|
||||
|
||||
if [ -z "$room_id" ]; then
|
||||
# Room might already exist — try resolving the alias
|
||||
local alias_resp
|
||||
alias_resp=$(docker compose -f "${FACTORY_ROOT}/docker-compose.yml" exec -T dendrite \
|
||||
curl -sf "http://localhost:8008/_matrix/client/v3/directory/room/%23factory%3Adisinto.local" \
|
||||
-H "Authorization: Bearer ${access_token}" \
|
||||
2>/dev/null) || alias_resp=""
|
||||
room_id=$(printf '%s' "$alias_resp" | jq -r '.room_id // empty' 2>/dev/null) || room_id=""
|
||||
fi
|
||||
|
||||
if [ -z "$room_id" ]; then
|
||||
echo "Warning: failed to create or find coordination room — skipping Matrix setup" >&2
|
||||
return
|
||||
fi
|
||||
|
||||
echo " Room: ${room_id} (alias: #factory:disinto.local)"
|
||||
|
||||
# Store Matrix credentials in .env
|
||||
local matrix_vars=(
|
||||
"MATRIX_HOMESERVER=${matrix_host}"
|
||||
"MATRIX_BOT_USER=${bot_user}"
|
||||
"MATRIX_TOKEN=${access_token}"
|
||||
"MATRIX_ROOM_ID=${room_id}"
|
||||
)
|
||||
|
||||
for var_line in "${matrix_vars[@]}"; do
|
||||
local var_name="${var_line%%=*}"
|
||||
if grep -q "^${var_name}=" "$env_file" 2>/dev/null; then
|
||||
# Use Python to avoid sed delimiter collisions with opaque tokens
|
||||
python3 -c "
|
||||
import sys, re, pathlib
|
||||
p = pathlib.Path(sys.argv[1])
|
||||
text = p.read_text()
|
||||
text = re.sub(r'^' + re.escape(sys.argv[2]) + r'=.*$', sys.argv[3], text, flags=re.MULTILINE)
|
||||
p.write_text(text)
|
||||
" "$env_file" "$var_name" "$var_line"
|
||||
else
|
||||
printf '%s\n' "$var_line" >> "$env_file"
|
||||
fi
|
||||
done
|
||||
|
||||
export MATRIX_TOKEN="$access_token"
|
||||
export MATRIX_BOT_USER="$bot_user"
|
||||
export MATRIX_ROOM_ID="$room_id"
|
||||
export MATRIX_HOMESERVER="$matrix_host"
|
||||
|
||||
echo " Credentials saved to .env"
|
||||
echo ""
|
||||
echo " To receive notifications in your Matrix client:"
|
||||
echo " 1. Add 'ports: [\"8008:8008\"]' to the dendrite service in docker-compose.yml"
|
||||
echo " 2. Join #factory:disinto.local from Element or another Matrix client"
|
||||
}
|
||||
|
||||
# ── init command ─────────────────────────────────────────────────────────────
|
||||
|
||||
disinto_init() {
|
||||
|
|
@ -1265,7 +1056,7 @@ disinto_init() {
|
|||
shift
|
||||
|
||||
# Parse flags
|
||||
local branch="" repo_root="" ci_id="0" auto_yes=false forge_url_flag="" bare=false enable_matrix=false
|
||||
local branch="" repo_root="" ci_id="0" auto_yes=false forge_url_flag="" bare=false
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--branch) branch="$2"; shift 2 ;;
|
||||
|
|
@ -1273,7 +1064,6 @@ disinto_init() {
|
|||
--ci-id) ci_id="$2"; shift 2 ;;
|
||||
--forge-url) forge_url_flag="$2"; shift 2 ;;
|
||||
--bare) bare=true; shift ;;
|
||||
--matrix) enable_matrix=true; shift ;;
|
||||
--yes) auto_yes=true; shift ;;
|
||||
*) echo "Unknown option: $1" >&2; exit 1 ;;
|
||||
esac
|
||||
|
|
@ -1357,9 +1147,6 @@ p.write_text(text)
|
|||
forge_port=$(printf '%s' "$forge_url" | sed -E 's|.*:([0-9]+)/?$|\1|')
|
||||
forge_port="${forge_port:-3000}"
|
||||
generate_compose "$forge_port"
|
||||
if [ "$enable_matrix" = true ]; then
|
||||
append_dendrite_compose
|
||||
fi
|
||||
generate_agent_docker
|
||||
fi
|
||||
|
||||
|
|
@ -1457,13 +1244,7 @@ p.write_text(text)
|
|||
echo ""
|
||||
echo "── Starting full stack ────────────────────────────────"
|
||||
docker compose -f "${FACTORY_ROOT}/docker-compose.yml" up -d
|
||||
if [ "$enable_matrix" = true ]; then
|
||||
echo "Stack: running (forgejo + woodpecker + dendrite + agents)"
|
||||
# Provision Matrix now that Dendrite is running
|
||||
setup_matrix
|
||||
else
|
||||
echo "Stack: running (forgejo + woodpecker + agents)"
|
||||
fi
|
||||
echo "Stack: running (forgejo + woodpecker + agents)"
|
||||
|
||||
# Activate repo in Woodpecker now that stack is running
|
||||
activate_woodpecker_repo "$forge_repo"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue