refactor: cherry-pick improvements from dev-agent's PR #700
Two wins from the dev-agent's implementation: 1. exec-briefing.sh: rewritten to just call exec-inject.sh with a briefing prompt (57 lines, down from 154). No more duplicated compass/character/context loading. 2. exec-inject.sh: response capture now uses agent_wait_for_claude_ready + pane line diff instead of custom EXEC-RESPONSE-START/END markers. Claude just responds naturally — no special output format needed. Also: matrix listener uses nohup for robustness and validates TOML path before passing to exec-inject.sh.
This commit is contained in:
parent
8375611244
commit
c3acce7f8f
5 changed files with 111 additions and 230 deletions
|
|
@ -2,15 +2,10 @@
|
|||
# =============================================================================
|
||||
# exec-briefing.sh — Daily morning briefing via the executive assistant
|
||||
#
|
||||
# Cron wrapper: spawns a one-shot Claude session that gathers factory state
|
||||
# and posts a morning briefing to Matrix. Unlike the interactive session,
|
||||
# this runs, posts, and exits.
|
||||
# Cron entry: 0 7 * * * /path/to/disinto/exec/exec-briefing.sh [project.toml]
|
||||
#
|
||||
# Usage:
|
||||
# exec-briefing.sh [projects/disinto.toml]
|
||||
#
|
||||
# Cron:
|
||||
# 0 7 * * * /path/to/disinto/exec/exec-briefing.sh
|
||||
# Sends a briefing prompt to exec-inject.sh, which handles session management,
|
||||
# response capture, and Matrix posting. No duplication of compass/context logic.
|
||||
# =============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
|
|
@ -20,134 +15,43 @@ FACTORY_ROOT="$(dirname "$SCRIPT_DIR")"
|
|||
export PROJECT_TOML="${1:-$FACTORY_ROOT/projects/disinto.toml}"
|
||||
# shellcheck source=../lib/env.sh
|
||||
source "$FACTORY_ROOT/lib/env.sh"
|
||||
# shellcheck source=../lib/agent-session.sh
|
||||
source "$FACTORY_ROOT/lib/agent-session.sh"
|
||||
# shellcheck source=../lib/formula-session.sh
|
||||
source "$FACTORY_ROOT/lib/formula-session.sh"
|
||||
# shellcheck source=../lib/guard.sh
|
||||
source "$FACTORY_ROOT/lib/guard.sh"
|
||||
|
||||
LOG_FILE="$SCRIPT_DIR/exec.log"
|
||||
# shellcheck disable=SC2034 # consumed by run_formula_and_monitor
|
||||
SESSION_NAME="exec-briefing-${PROJECT_NAME}"
|
||||
PHASE_FILE="/tmp/exec-briefing-${PROJECT_NAME}.phase"
|
||||
# shellcheck disable=SC2034
|
||||
PHASE_POLL_INTERVAL=10
|
||||
|
||||
log() { echo "[$(date -u +%Y-%m-%dT%H:%M:%S)Z] $*" >> "$LOG_FILE"; }
|
||||
|
||||
# ── Guards ────────────────────────────────────────────────────────────────
|
||||
check_active exec
|
||||
acquire_cron_lock "/tmp/exec-briefing.lock"
|
||||
check_memory 2000
|
||||
|
||||
# Memory guard
|
||||
AVAIL_MB=$(free -m 2>/dev/null | awk '/Mem:/{print $7}' || echo 9999)
|
||||
if [ "${AVAIL_MB:-0}" -lt 2000 ]; then
|
||||
log "SKIP: low memory (${AVAIL_MB}MB available)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log "--- Exec briefing start ---"
|
||||
|
||||
# ── Load compass (required) ────────────────────────────────────────────
|
||||
COMPASS_FILE="${EXEC_COMPASS:-${HOME}/.disinto/compass.md}"
|
||||
if [ ! -f "$COMPASS_FILE" ]; then
|
||||
log "FATAL: compass not found at ${COMPASS_FILE} — exec agent refuses to start without its compass"
|
||||
exit 1
|
||||
fi
|
||||
COMPASS_BLOCK=$(cat "$COMPASS_FILE")
|
||||
BRIEFING_PROMPT="Daily briefing request (automated, $(date -u '+%Y-%m-%d')):
|
||||
|
||||
# ── Load character (voice/relationships from repo) ────────────────────
|
||||
CHARACTER_FILE="${EXEC_CHARACTER:-$SCRIPT_DIR/CHARACTER.md}"
|
||||
CHARACTER_BLOCK=""
|
||||
if [ -f "$CHARACTER_FILE" ]; then
|
||||
CHARACTER_BLOCK=$(cat "$CHARACTER_FILE")
|
||||
fi
|
||||
Produce a concise morning briefing covering:
|
||||
1. Pipeline status — blocked issues, failing CI, stale PRs?
|
||||
2. Recent activity — what merged/closed in the last 24h?
|
||||
3. Backlog health — depth, underspecified issues?
|
||||
4. Predictions — any unreviewed from the predictor?
|
||||
5. Concerns — anything needing human attention today?
|
||||
|
||||
# Merge: compass first, then character
|
||||
CHARACTER_BLOCK="${COMPASS_BLOCK}
|
||||
Check the forge API, git log, agent journals, and issue tracker.
|
||||
Under 500 words. Lead with what needs action."
|
||||
|
||||
${CHARACTER_BLOCK}"
|
||||
|
||||
# ── Load memory ─────────────────────────────────────────────────────────
|
||||
MEMORY_BLOCK="(no previous memory)"
|
||||
MEMORY_FILE="$PROJECT_REPO_ROOT/exec/MEMORY.md"
|
||||
if [ -f "$MEMORY_FILE" ]; then
|
||||
MEMORY_BLOCK=$(cat "$MEMORY_FILE")
|
||||
fi
|
||||
|
||||
# ── Gather factory state ───────────────────────────────────────────────
|
||||
# Open issues count
|
||||
OPEN_ISSUES=$(curl -sf -H "Authorization: token ${FORGE_TOKEN}" \
|
||||
"${FORGE_API}/issues?state=open&type=issues&limit=1" 2>/dev/null \
|
||||
| jq 'length' 2>/dev/null || echo "?")
|
||||
|
||||
# Open PRs
|
||||
OPEN_PRS=$(curl -sf -H "Authorization: token ${FORGE_TOKEN}" \
|
||||
"${FORGE_API}/pulls?state=open&limit=1" 2>/dev/null \
|
||||
| jq 'length' 2>/dev/null || echo "?")
|
||||
|
||||
# Pending vault items
|
||||
VAULT_PENDING=$(ls "$FACTORY_ROOT/vault/pending/" 2>/dev/null | wc -l || echo 0)
|
||||
|
||||
# Recent agent activity (last 24h log lines)
|
||||
RECENT_ACTIVITY=""
|
||||
for agent_dir in supervisor planner predictor gardener dev review; do
|
||||
latest_log="$FACTORY_ROOT/${agent_dir}/${agent_dir}.log"
|
||||
if [ -f "$latest_log" ]; then
|
||||
lines=$(grep "$(date -u +%Y-%m-%d)" "$latest_log" 2>/dev/null | tail -5 || true)
|
||||
if [ -n "$lines" ]; then
|
||||
RECENT_ACTIVITY="${RECENT_ACTIVITY}
|
||||
### ${agent_dir} (today)
|
||||
${lines}
|
||||
"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# ── Build briefing prompt ──────────────────────────────────────────────
|
||||
# shellcheck disable=SC2034 # consumed by run_formula_and_monitor
|
||||
PROMPT="You are the executive assistant for ${FORGE_REPO}. This is a morning briefing run.
|
||||
|
||||
## Your character
|
||||
${CHARACTER_BLOCK}
|
||||
|
||||
## Your memory
|
||||
${MEMORY_BLOCK}
|
||||
|
||||
## Current factory state
|
||||
- Open issues: ${OPEN_ISSUES}
|
||||
- Open PRs: ${OPEN_PRS}
|
||||
- Pending vault items: ${VAULT_PENDING}
|
||||
|
||||
${RECENT_ACTIVITY}
|
||||
|
||||
## Task
|
||||
|
||||
Produce a morning briefing for the executive. Be concise — 10-15 lines max.
|
||||
Cover:
|
||||
1. What happened overnight (merges, CI failures, agent activity)
|
||||
2. What needs attention today (blocked issues, vault items, stale work)
|
||||
3. One observation or recommendation
|
||||
|
||||
Fetch additional data if needed:
|
||||
- Open issues: curl -sf -H \"Authorization: token \${FORGE_TOKEN}\" '${FORGE_API}/issues?state=open&type=issues&limit=20'
|
||||
- Recent closed: curl -sf -H \"Authorization: token \${FORGE_TOKEN}\" '${FORGE_API}/issues?state=closed&type=issues&limit=10&sort=updated&direction=desc'
|
||||
- Prerequisite tree: cat ${PROJECT_REPO_ROOT}/planner/prerequisite-tree.md
|
||||
|
||||
Write your briefing between markers:
|
||||
\`\`\`
|
||||
---EXEC-RESPONSE-START---
|
||||
Your briefing here.
|
||||
---EXEC-RESPONSE-END---
|
||||
\`\`\`
|
||||
|
||||
Then log the briefing to: ${PROJECT_REPO_ROOT}/exec/journal/\$(date -u +%Y-%m-%d).md
|
||||
(append, don't overwrite — there may be interactive sessions later today)
|
||||
|
||||
Then: echo 'PHASE:done' > '${PHASE_FILE}'
|
||||
|
||||
## Environment
|
||||
FACTORY_ROOT=${FACTORY_ROOT}
|
||||
PROJECT_REPO_ROOT=${PROJECT_REPO_ROOT}
|
||||
PHASE_FILE=${PHASE_FILE}"
|
||||
|
||||
# ── Run session ──────────────────────────────────────────────────────────
|
||||
export CLAUDE_MODEL="${CLAUDE_MODEL:-sonnet}"
|
||||
run_formula_and_monitor "exec-briefing" 600
|
||||
bash "$SCRIPT_DIR/exec-inject.sh" \
|
||||
"briefing-cron" \
|
||||
"$BRIEFING_PROMPT" \
|
||||
"" \
|
||||
"$PROJECT_TOML" || {
|
||||
log "briefing injection failed"
|
||||
exit 1
|
||||
}
|
||||
|
||||
log "--- Exec briefing done ---"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue