Add orch Codex launch bridge workflow
This commit is contained in:
Executable
+164
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
readonly DEFAULT_INBOX_SKILL_PATH="$(cd "${SCRIPT_DIR}/../../inbox" && pwd)"
|
||||
|
||||
dispatch_json=""
|
||||
db_path=""
|
||||
inbox_skill_path="${DEFAULT_INBOX_SKILL_PATH}"
|
||||
extra_instructions_file=""
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: orch-worker-brief --dispatch-json PATH --db PATH [--inbox-skill-path PATH] [--extra-instructions-file PATH]
|
||||
|
||||
Read an `orch dispatch --json` response and render a standardized worker prompt
|
||||
for a Codex sub-agent that should execute the assigned inbox thread.
|
||||
|
||||
Required:
|
||||
--dispatch-json PATH Path to the saved `orch dispatch --json` response
|
||||
--db PATH Shared SQLite DB path for both orch and inbox
|
||||
|
||||
Optional:
|
||||
--inbox-skill-path PATH Path to the inbox skill bundle. Defaults to the
|
||||
sibling project-local skill at skills/inbox
|
||||
--extra-instructions-file Append extra operator-specific instructions
|
||||
-h, --help Show this help text
|
||||
EOF
|
||||
}
|
||||
|
||||
require_command() {
|
||||
local cmd="$1"
|
||||
if ! command -v "${cmd}" >/dev/null 2>&1; then
|
||||
printf 'missing required command: %s\n' "${cmd}" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
--dispatch-json)
|
||||
dispatch_json="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--db)
|
||||
db_path="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--inbox-skill-path)
|
||||
inbox_skill_path="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--extra-instructions-file)
|
||||
extra_instructions_file="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
printf 'unknown argument: %s\n' "$1" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
require_command jq
|
||||
|
||||
if [ -z "${dispatch_json}" ] || [ -z "${db_path}" ]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "${dispatch_json}" ]; then
|
||||
printf 'dispatch json not found: %s\n' "${dispatch_json}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "${extra_instructions_file}" ] && [ ! -f "${extra_instructions_file}" ]; then
|
||||
printf 'extra instructions file not found: %s\n' "${extra_instructions_file}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
run_id="$(jq -r '.data.attempt.run_id // .data.task.run_id // empty' "${dispatch_json}")"
|
||||
task_id="$(jq -r '.data.attempt.task_id // .data.task.task_id // empty' "${dispatch_json}")"
|
||||
attempt_no="$(jq -r '.data.attempt.attempt_no // empty' "${dispatch_json}")"
|
||||
assigned_to="$(jq -r '.data.attempt.assigned_to // .data.task.default_to // empty' "${dispatch_json}")"
|
||||
thread_id="$(jq -r '.data.attempt.thread_id // .data.thread.thread_id // empty' "${dispatch_json}")"
|
||||
worktree_path="$(jq -r '.data.attempt.worktree_path // empty' "${dispatch_json}")"
|
||||
base_ref="$(jq -r '.data.attempt.base_ref // empty' "${dispatch_json}")"
|
||||
task_title="$(jq -r '.data.task.title // empty' "${dispatch_json}")"
|
||||
task_summary="$(jq -r '.data.task.summary // empty' "${dispatch_json}")"
|
||||
leader_body="$(jq -r '.data.message.body // empty' "${dispatch_json}")"
|
||||
|
||||
if [ -z "${run_id}" ] || [ -z "${task_id}" ] || [ -z "${assigned_to}" ] || [ -z "${thread_id}" ]; then
|
||||
printf 'dispatch json is missing one or more required fields: run_id, task_id, assigned_to, thread_id\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mode="analysis"
|
||||
if [ -n "${worktree_path}" ]; then
|
||||
mode="code"
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
Use \$inbox at ${inbox_skill_path} to act as ${assigned_to} on SQLite DB ${db_path}. Only coordinate through the bundled inbox CLI from the skill. Do not use ordinary chat to coordinate with the leader. Do not use orch.
|
||||
|
||||
You are assigned one existing attempt:
|
||||
- run_id: ${run_id}
|
||||
- task_id: ${task_id}
|
||||
- attempt_no: ${attempt_no}
|
||||
- assigned_to: ${assigned_to}
|
||||
- thread_id: ${thread_id}
|
||||
- execution_mode: ${mode}
|
||||
EOF
|
||||
|
||||
if [ -n "${task_title}" ]; then
|
||||
printf '%s\n' "- task_title: ${task_title}"
|
||||
fi
|
||||
if [ -n "${task_summary}" ]; then
|
||||
printf '%s\n' "- task_summary: ${task_summary}"
|
||||
fi
|
||||
if [ -n "${base_ref}" ]; then
|
||||
printf '%s\n' "- base_ref: ${base_ref}"
|
||||
fi
|
||||
if [ -n "${worktree_path}" ]; then
|
||||
printf '%s\n' "- worktree_path: ${worktree_path}"
|
||||
fi
|
||||
|
||||
cat <<'EOF'
|
||||
|
||||
Required workflow:
|
||||
1. Fetch or inspect the assigned thread and claim exactly the listed thread_id.
|
||||
2. Inspect the thread with show before making assumptions about the task body or payload.
|
||||
3. Send one in_progress update when real work starts.
|
||||
4. If blocked, send one precise blocked question with update --status blocked and then use wait-reply.
|
||||
5. Finish with done on success or fail on failure.
|
||||
6. Stop after reporting the handled thread_id and a concise outcome summary.
|
||||
|
||||
Rules:
|
||||
- Do not claim any other thread.
|
||||
- Keep all coordination in inbox messages, not ordinary chat.
|
||||
- Do not change the assigned_to, thread_id, or worktree assignment yourself.
|
||||
EOF
|
||||
|
||||
if [ -n "${worktree_path}" ]; then
|
||||
cat <<EOF
|
||||
- Perform repository work only inside ${worktree_path}.
|
||||
- Do not modify the leader's primary checkout outside the assigned worktree.
|
||||
EOF
|
||||
fi
|
||||
|
||||
if [ -n "${leader_body}" ]; then
|
||||
printf '\nLeader dispatch body:\n%s\n' "${leader_body}"
|
||||
fi
|
||||
|
||||
if [ -n "${extra_instructions_file}" ]; then
|
||||
printf '\nExtra instructions:\n'
|
||||
cat "${extra_instructions_file}"
|
||||
printf '\n'
|
||||
fi
|
||||
Reference in New Issue
Block a user