From yellow-devin
Send a follow-up message to an active Devin session. Use when user wants to give Devin additional context, says "tell Devin to...", "update Devin", or "send message to session".
How this command is triggered — by the user, by Claude, or both
Slash command
/yellow-devin:message <session-id> <message>devin/This command is limited to the following tools:
The summary Claude sees in its command listing — used to decide when to auto-load this command
# Send Message to Devin Session Send a follow-up message to provide additional context, instructions, or course corrections to a Devin session. ## Workflow ### Step 1: Validate Prerequisites Validate `DEVIN_SERVICE_USER_TOKEN` and `DEVIN_ORG_ID` are set. Check `jq` is available. See `devin-workflows` skill for validation functions. ### Step 2: Parse Arguments Parse `$ARGUMENTS`: - First token is the session ID - Remaining text is the message If session ID or message is missing, prompt via AskUserQuestion. ### Step 3: Validate Inputs - **Session ID:** Validate with `validate_sessio...
Send a follow-up message to provide additional context, instructions, or course corrections to a Devin session.
Validate DEVIN_SERVICE_USER_TOKEN and DEVIN_ORG_ID are set. Check jq is
available. See devin-workflows skill for validation functions.
Parse $ARGUMENTS:
If session ID or message is missing, prompt via AskUserQuestion.
validate_session_id from devin-workflows
skill — ^[a-zA-Z0-9_-]{8,64}$Fetch session status using the org-scoped list endpoint with session_ids
filter (see Session Lookup Pattern in devin-workflows skill):
DEVIN_API_BASE="https://api.devin.ai/v3"
ORG_URL="${DEVIN_API_BASE}/organizations/${DEVIN_ORG_ID}"
response=$(curl -s --connect-timeout 5 --max-time 10 \
-w "\n%{http_code}" \
-X GET "${ORG_URL}/sessions?session_ids=${SESSION_ID}&first=1" \
-H "Authorization: Bearer $DEVIN_SERVICE_USER_TOKEN")
Parse from items array: jq '.items[0]'. If the result is null or the array
is empty, report "Session not found."
Check session status against messageable states:
Messageable states:
running — proceed normallysuspended — inform user: "Session is suspended. Sending a message will
auto-resume it." Then proceed.Not messageable:
resuming — report: "Session is resuming. Wait a moment and try again, or
use /devin:status {id} to check."new, claimed — report: "Session is {status} — waiting to start. Try again
shortly or use /devin:status to monitor."exit, error (terminal) — report: "Session is {status} — cannot send
messages to a completed session."Construct JSON via jq and POST. Try the org-scoped endpoint first (requires
ManageOrgSessions); if it returns 403, fall back to the enterprise endpoint
(requires ManageAccountSessions):
# Try org-scoped endpoint first
response=$(jq -n --arg msg "$MESSAGE" '{message: $msg}' | \
curl -s --connect-timeout 5 --max-time 30 \
-w "\n%{http_code}" \
-X POST "${ORG_URL}/sessions/${SESSION_ID}/messages" \
-H "Authorization: Bearer $DEVIN_SERVICE_USER_TOKEN" \
-H "Content-Type: application/json" \
-d @-)
curl_exit=$?
http_status=${response##*$'\n'}
body=${response%$'\n'*}
# Fall back to enterprise endpoint on 403
if [ "$curl_exit" -eq 0 ] && [ "$http_status" = "403" ]; then
printf 'WARN: Org-scoped message endpoint returned 403, trying enterprise scope...\n' >&2
ENTERPRISE_URL="${DEVIN_API_BASE}/enterprise"
response=$(jq -n --arg msg "$MESSAGE" '{message: $msg}' | \
curl -s --connect-timeout 5 --max-time 30 \
-w "\n%{http_code}" \
-X POST "${ENTERPRISE_URL}/sessions/${SESSION_ID}/messages" \
-H "Authorization: Bearer $DEVIN_SERVICE_USER_TOKEN" \
-H "Content-Type: application/json" \
-d @-)
curl_exit=$?
http_status=${response##*$'\n'}
body=${response%$'\n'*}
fi
Never use the message_as_user_id field — impersonation risk.
Check curl exit code, HTTP status, jq parse — see devin-workflows skill.
If both org-scoped and enterprise endpoints returned 403, offer to post the message as a PR comment instead. Devin automatically responds to PR comments as long as the session is not archived.
Check gh availability inline:
if ! command -v gh >/dev/null 2>&1; then
printf 'gh CLI not found — PR comment fallback unavailable.\n'
# Fall through to standard error reporting
elif ! gh auth status >/dev/null 2>&1; then
printf 'gh not authenticated — run `gh auth login` to enable PR comment fallback.\n'
# Fall through to standard error reporting
fi
If gh is not available or not authenticated, skip the PR comment
fallback and report the 403 error with a note to run /devin:setup.
Detect current repo:
REPO_SLUG=$(gh repo view --json nameWithOwner -q .nameWithOwner 2>/dev/null || echo "")
If REPO_SLUG is empty, skip the PR comment fallback — cannot determine
the current repo.
Extract PRs from session data (already fetched in Step 4):
Parse pull_requests from the session response. Filter for PRs matching
the current repo (REPO_SLUG). Extract PR number from the PR URL.
Offer fallback via AskUserQuestion:
If matching PRs exist:
API message failed (403 — ManageOrgSessions may be missing).
This session has PR #N in this repo. Devin monitors PR comments
and will pick up instructions posted there.
Options:
- Comment on PR — Post as PR comment with @devin prefix
- Run /devin:setup — Check and fix permissions
- Cancel
If no matching PRs: skip the fallback, show the 403 error with a note to
run /devin:setup.
Post comment if chosen:
Check archived status first: If the session's is_archived field is
true, warn in the AskUserQuestion prompt: "Session {id} is archived — Devin
will not respond to PR comments for archived sessions." Change the option
label to "Comment on PR anyway — for documentation purposes".
Compose with @devin prefix first, then sanitize before posting (prevent
cog_ and apk_ token leakage):
COMMENT_BODY="@devin ${MESSAGE}"
SAFE_BODY=$(printf '%s' "$COMMENT_BODY" | sed 's/\(cog\|apk\)_[a-zA-Z0-9_-]*/***REDACTED***/g')
gh pr comment "$PR_NUMBER" --repo "$REPO_SLUG" --body "$SAFE_BODY"
@devin must be at the very start of the comment body (prefix match for
mention-only filtering). The comment posts as the authenticated GitHub user,
which Devin responds to by default. The message is already bounded by the
2000-char input validation in Step 3, so no additional truncation is needed.
Check the exit code of gh pr comment. If non-zero, report the error:
"Failed to post PR comment: {error}. Check gh auth status and repo
permissions." Do not proceed to step 6.
Report result (only on success): "Message posted as comment on PR #N. Devin will pick up the instructions automatically."
Display confirmation with updated session status from the response.
If the session was suspended and is now resuming:
/devin:status {id} to check when it's running."Otherwise:
/devin:status {id} to check progress."See devin-workflows skill for error handling patterns. All error output must
sanitize tokens.
npx claudepluginhub kinginyellows/yellow-plugins --plugin yellow-devin/msgSends a message to a specified Claude Code session by ID or name. Auto-lists sessions with it2 session list, delivers via it2 session send-text, and reports success.
/setupValidates that Devin Handoff dependencies (curl, jq) are installed, DEVIN_API_KEY is set, and performs a validation API call to confirm connectivity.
/continueResumes a previous Codex session using its thread ID, allowing follow-up prompts like fixing issues, running tests, or drilling deeper.