diff --git a/plugins/dev-team/skills/concurrent-orchestrate/SKILL.md b/plugins/dev-team/skills/concurrent-orchestrate/SKILL.md index 8e144c7..fee1f52 100644 --- a/plugins/dev-team/skills/concurrent-orchestrate/SKILL.md +++ b/plugins/dev-team/skills/concurrent-orchestrate/SKILL.md @@ -58,20 +58,6 @@ and stopping on `"complete"` or `"blocked"`. ## Steps -### 0 — Verify `python3` is available - -Every step below drives `concurrent_schedule.py` (and, transitively, every spawned -`workflow-orchestrate` run) through `python3` — nothing in this pipeline works without it. -Before running step 1 for the first time this session, confirm the interpreter is present: - -```bash -command -v python3 -``` - -If this reports nothing (a non-zero exit), stop immediately and report to the user that -`python3` is required but was not found on this system, rather than proceeding and failing on -the first script invocation with a less obvious "command not found" error. - ### 1 — Reconcile against what's already running Run once before entering the main loop (step 2) — the first thing this session does whether @@ -82,11 +68,9 @@ This step detects that and respawns. 1. Take one non-blocking snapshot — `--max-poll-cycles 0` is a new invocation mode, distinct from step 2a's default ~5-minute polling behavior, that returns after exactly one poll - instead of blocking until something becomes actionable: - ```bash - python3 "/scripts/concurrent_schedule.py" --up-to "" --max-poll-cycles 0 - ``` - or the `--list` form, matching whichever target mode this run uses. + instead of blocking until something becomes actionable. Use the `run-python-script` skill with + `--script "/scripts/concurrent_schedule.py" --args '--up-to "" + --max-poll-cycles 0'` (or the `--list` form, matching whichever target mode this run uses). 2. For each `{task_id, status, last_updated, worktree_path}` entry in the returned `running` list, check whether this session already holds a live spawn handle for it — i.e. whether this session itself spawned it via step 2c, in this run or an earlier one before a restart. Keep @@ -110,19 +94,12 @@ Repeat the following until the script reports `"complete"` or `"blocked"`. #### 2a — Run the scheduler script -```bash -python3 "/scripts/concurrent_schedule.py" --up-to "" -``` - -or, for the explicit-list form: - -```bash -python3 "/scripts/concurrent_schedule.py" --list "" -``` +Use the `run-python-script` skill with `--script "/scripts/concurrent_schedule.py" +--args '--up-to ""'` (or `--args '--list ""'` for the explicit-list form). -The script blocks internally rather than returning the instant it sees nothing to do. -Invoke this `Bash` call with an explicit `timeout` of at least `330000` -(5.5 minutes) — comfortably past the script's own ~5-minute default polling budget. +The script blocks internally rather than returning the instant it sees nothing to do. Pass +`--timeout 330000` (5.5 minutes) to `run-python-script` — comfortably past the script's own +~5-minute default polling budget. Capture stdout — a single JSON object `{"status": ..., "spawn": [...], "blocked_tasks": [...], "running": [...]}`. If the script exits @@ -243,3 +220,5 @@ step — there is no PR to monitor, so no `dev-team:monitor-pr` is spawned for i - `use-context-file` — pre-populating `base_branch`, and recording `worktree_path` / `worktree_branch`, on a spawned task's context file +- `run-python-script` — the `python3` availability check and every `concurrent_schedule.py` + invocation diff --git a/plugins/dev-team/skills/dev-spec-task-breakdown/SKILL.md b/plugins/dev-team/skills/dev-spec-task-breakdown/SKILL.md index 7f31442..17ad392 100644 --- a/plugins/dev-team/skills/dev-spec-task-breakdown/SKILL.md +++ b/plugins/dev-team/skills/dev-spec-task-breakdown/SKILL.md @@ -95,11 +95,8 @@ environment variable. `task_dependencies.py` lives in the sibling `workflow-orch `scripts/` directory, reachable relative to `` — this skill may run in a repo other than the one containing these plugin files (e.g. as an installed plugin), so resolve the path this way rather than assuming a particular repo layout or that the Bash tool's CWD is the repo -root. Run it via `Bash`: - -```bash -python3 "/../workflow-orchestrate/scripts/task_dependencies.py" "" -``` +root. Use the `run-python-script` skill with `--script +"/../workflow-orchestrate/scripts/task_dependencies.py" --args ""`. If it exits non-zero, it printed a clear `Error: ...` message to stderr naming the offending task and reference (a dangling reference or a dependency cycle). Surface that error to the user and diff --git a/plugins/dev-team/skills/ensure-working-branch/SKILL.md b/plugins/dev-team/skills/ensure-working-branch/SKILL.md index 4ca4869..7d99424 100644 --- a/plugins/dev-team/skills/ensure-working-branch/SKILL.md +++ b/plugins/dev-team/skills/ensure-working-branch/SKILL.md @@ -96,9 +96,9 @@ task's own dependencies from. Otherwise: -1. Read this task's own dependency ids: invoke - `python3 "/../workflow-orchestrate/scripts/task_dependencies.py" ""` via - `Bash`. It prints the whole spec's `{task_key: [dependency_ids]}` graph as JSON on success. +1. Read this task's own dependency ids: use the `run-python-script` skill with `--script + "/../workflow-orchestrate/scripts/task_dependencies.py" --args ""`. It + prints the whole spec's `{task_key: [dependency_ids]}` graph as JSON on success. Look up this task's own work-item-id key in that graph — that list is this task's own dependency ids (an empty list if the task declares `— none —` or has no `Depends on:` line at all). If the command exits non-zero, it prints a clear `Error: ...` message to stderr instead @@ -107,12 +107,12 @@ Otherwise: 2. If that list is empty, skip the rest of this sub-step and fall through to 4c unchanged (no dependencies means nothing for this step to override). -3. Otherwise, invoke - `python3 "/../workflow-orchestrate/scripts/task_readiness.py" "" ",,..."` - via `Bash`, passing this task's own dependency ids as a comma-separated list. It prints - `{"status": "eligible" | "waiting" | "blocked", "base_branch": }` as JSON - on success. If the command exits non-zero, it prints a clear `Error: ...` message to stderr - instead of JSON — stop and report that error in detail; do not fall through to 4c. +3. Otherwise, use the `run-python-script` skill with `--script + "/../workflow-orchestrate/scripts/task_readiness.py" --args " + ,,..."`, passing this task's own dependency ids as a comma-separated list. It + prints `{"status": "eligible" | "waiting" | "blocked", "base_branch": }` + as JSON on success. If the command exits non-zero, it prints a clear `Error: ...` message to + stderr instead of JSON — stop and report that error in detail; do not fall through to 4c. 4. If `status` is `"eligible"` and `base_branch` is a real (non-null) branch name: write it to the context file's `base_branch` field via `use-context-file`, then skip the rest of step 4 diff --git a/plugins/dev-team/skills/get-project-configuration/SKILL.md b/plugins/dev-team/skills/get-project-configuration/SKILL.md index 4ec4b8d..fd8aa4f 100644 --- a/plugins/dev-team/skills/get-project-configuration/SKILL.md +++ b/plugins/dev-team/skills/get-project-configuration/SKILL.md @@ -17,9 +17,7 @@ Use this skill when: skill" path shown when this skill was invoked. Resolve it to that literal path; it is not an environment variable. -```bash -python3 "/scripts/merge_config.py" -``` +Use the `run-python-script` skill with `--script "/scripts/merge_config.py"`. Prints the merged configuration as JSON to stdout and exits 0. On failure (malformed YAML, no repo root found) it prints `Error: ...` to stderr and exits non-zero — stop and report the diff --git a/plugins/dev-team/skills/implement-tdd/SKILL.md b/plugins/dev-team/skills/implement-tdd/SKILL.md index 4b29889..cb52919 100644 --- a/plugins/dev-team/skills/implement-tdd/SKILL.md +++ b/plugins/dev-team/skills/implement-tdd/SKILL.md @@ -42,17 +42,10 @@ whole thing: `` refers to this skill's own base directory — the "Base directory for this skill" path shown when this skill was invoked. Resolve it to that literal path. -Pass the component prompt on the script's stdin (e.g. a heredoc), not as a file: - -```bash -python3 "/scripts/tdd_cycle.py" \ - --component-name "" \ - --repo-root \ - --work-item-id \ - --state-file <<'EOF' - -EOF -``` +Pass the component prompt on the script's stdin (e.g. a heredoc), not as a file. Use the +`run-python-script` skill with `--script "/scripts/tdd_cycle.py" --args +"--component-name \"\" --repo-root --work-item-id +--state-file " --stdin ""`. Use a `` unique to this component (e.g. under a scratch directory) — it's how the script resumes a specific component's in-progress loop after you resolve an escalation. Every @@ -129,3 +122,4 @@ builds/tests on their behalf. against - `implement-direct` — used for a `resolve_directly` Tier 2 escalation, before re-running the script +- `run-python-script` — the `python3` availability check and the `tdd_cycle.py` invocation diff --git a/plugins/dev-team/skills/monitor-pr/SKILL.md b/plugins/dev-team/skills/monitor-pr/SKILL.md index 2ca41b7..1f25fd1 100644 --- a/plugins/dev-team/skills/monitor-pr/SKILL.md +++ b/plugins/dev-team/skills/monitor-pr/SKILL.md @@ -114,9 +114,8 @@ Repeat the following indefinitely, until step 4b's `task_merged` case stops you, #### 4a — Poll -```bash -python3 "/../workflow-orchestrate/scripts/watch_pr_poll.py" -``` +Use the `run-python-script` skill with `--script +"/../workflow-orchestrate/scripts/watch_pr_poll.py" --args ""`. Parse stdout as JSON. If it is the literal string `"no_change"`, go straight back to step 4a — `watch_pr_poll.py` already blocked internally for its own bounded window; no additional wait is @@ -250,3 +249,6 @@ the spawn's generic `successful` status: argument - `workflow-worker` — the mediated spawn pattern (`--context-file`/`--write-section`/`--skill`/ `--skill-args`) for nested `fix-pr` and `resolve-rebase-conflict` calls +- `run-python-script` — the `python3` availability check and the `watch_pr_poll.py` invocation + (step 4a); the rebase mechanic's inline `python3 -c` block (step 4c) is a documented carve-out, + not migrated — see `run-python-script/SKILL.md`'s "Carve-outs" section diff --git a/plugins/dev-team/skills/run-python-script/SKILL.md b/plugins/dev-team/skills/run-python-script/SKILL.md new file mode 100644 index 0000000..682dd50 --- /dev/null +++ b/plugins/dev-team/skills/run-python-script/SKILL.md @@ -0,0 +1,99 @@ +--- +name: run-python-script +user-invocable: false +description: > + Shared skill that centralizes the `python3` availability check and script invocation. Verifies + `python3` is present (skipping the check if already verified earlier in this session) and stops + with a clear, stop-and-tell-the-user failure if missing, then runs a given Python script (with + its arguments) via `python3`. Every other skill that invokes a Python script should delegate to + this skill instead of inlining its own `python3