bama
BAMA: 모든 Mac 앱을 만들 수 있습니다
또 다른 AI 워크플로우
Yet another AI workflow
스킬Shell · JavaScriptGitHub @yowcow직접 설치운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Yet another AI workflow.
dude packages the skills that carry a change from an issue to a pull request
whose CI passes and whose review is clean, and the skills that root-cause a
problem before any change is proposed. Merging is left to a person, and so is
everything that depends on it. They are written to wire into one another: each
names the next flow rather than absorbing it, and each has its own gate.
The change flow is plan-work → implement-work → pr-to-ready, entered at
whichever stage the work has actually reached. An investigation —
settle-question, `investREADME 전문 보기 ↗Yet another AI workflow.
dude packages the skills that carry a change from an issue to a pull request whose CI passes and whose review is clean, and the skills that root-cause a problem before any change is proposed. Merging is left to a person, and so is everything that depends on it. They are written to wire into one another: each names the next flow rather than absorbing it, and each has its own gate.
| Skill | When to use it |
|---|---|
audit-code | Use to scan a repository or path and report what to fix, without changing code. |
implement-work | Use to implement one PR-sized task. |
investigate-anomaly | Use to investigate an observed anomaly — a failure, an incident, or an unexplained metric or cost change other than a performance shortfall. |
investigate-performance | Use to investigate an observed performance shortfall — a slow endpoint, job, or query, or a latency, throughput, CPU, or memory metric that moved. |
judge-findings | Use when another skill needs review findings judged accept, reject, or needs-user outside its own main loop. |
plan-work | Use to plan a change, including a multi-PR fix that arrives on investigation findings. |
propose-alternatives | Use as a component when another skill needs the most direct route to a named purpose, including doing nothing or doing something else. |
pr-to-ready | Use to take an open PR to ready, or a branch with no PR yet to ready. |
review-code | Use to review code. |
review-findings | Use to review report claims. |
review-plan | Use to review a planning artifact. |
review-pr | Use to review a PR and return the findings to it as a PR review. |
settle-question | Use to settle an open question whose deliverable is a judgment, with no runtime symptom to root-cause. |
simplify-code | Use to simplify recently modified code and human-facing docs while preserving behavior and stated facts. |
using-dude | Use when starting a task to classify it and select its workflow. |
vet-code | Use as a component when another skill needs one round of code review findings, each already judged. |
Skills by layer and the dependencies between them. Solid arrows point to a lower
layer; dashed arrows are the upward and lateral edges. using-dude is left out because every skill may
name it.
flowchart TB
subgraph Flows
plan-work
implement-work
pr-to-ready
end
subgraph Parts
review-code
review-plan
simplify-code
review-pr
audit-code
settle-question
investigate-anomaly
investigate-performance
end
subgraph Components
vet-code
propose-alternatives
end
subgraph Primitives
judge-findings
review-findings
end
plan-work -.-> implement-work
implement-work -.-> plan-work
implement-work -.-> pr-to-ready
pr-to-ready -.-> implement-work
pr-to-ready -.-> plan-work
review-code -.-> implement-work
review-pr -.-> implement-work
review-pr -.-> plan-work
audit-code -.-> plan-work
review-findings -.-> review-plan
plan-work --> review-plan
plan-work --> settle-question
plan-work --> propose-alternatives
plan-work --> review-findings
implement-work --> review-code
implement-work --> review-plan
implement-work --> simplify-code
implement-work --> propose-alternatives
implement-work --> review-findings
pr-to-ready --> vet-code
pr-to-ready --> judge-findings
pr-to-ready --> propose-alternatives
pr-to-ready --> review-findings
audit-code --> review-findings
investigate-anomaly --> review-findings
investigate-performance --> review-findings
settle-question --> review-findings
review-code --> vet-code
review-pr --> vet-code
review-pr --> propose-alternatives
review-pr --> review-findings
propose-alternatives --> review-findings
vet-code --> judge-findings
review-code --> judge-findings
review-plan --> judge-findings
simplify-code --> judge-findings
The canonical source is tests/skill-deps_test.sh and the skills' own
mentions of each other; the figure draws the dependencies those mentions
imply, not every mention a classification table records.
The change flow is plan-work → implement-work → pr-to-ready, entered at
whichever stage the work has actually reached. An investigation —
settle-question, investigate-anomaly, or investigate-performance —
runs first when there's a cause to find or a question to settle, and hands
its findings to plan-work. A scan — audit-code — runs first when a
repository or path needs sweeping for what to fix, and hands its report to
plan-work.
dude requires Superpowers. Install it first, in the same runtime you are installing dude into. dude's skills name Superpowers procedures and neither ship nor reimplement them, so those calls have nowhere to go until Superpowers is present.
It also requires jq, which review-pr's build-review-payload.sh and post-review.sh use to build and post the review. Without it they stop with exit 1 naming it, rather than reporting your arguments as the fault.
OpenCode:
opencode plugin add github:obra/superpowers
opencode plugin add github:yowcow/dude
Both land in the global OpenCode config. Restart OpenCode afterward.
Claude Code:
/plugin marketplace add yowcow/dude
/plugin install dude@dude
Codex:
codex plugin marketplace add yowcow/dude
codex plugin add dude@dude
Measured primary (Muse Code 1.4.0, hermetic HOME):
muse plugins install ./
muse plugins approve dude
Measured alternative (Muse Code 1.4.0, hermetic HOME):
muse plugins marketplace add dude <path-to-dude-clone>
muse plugins install dude@dude
Measured: with the primary install present, installing the same dude id
from the marketplace fails with invalid-plugin-package ("already installed
from a different source"); the reverse order is unmeasured.
Codex records hook trust per hook rather than per plugin — ~/.codex/config.toml
gains a [hooks.state."dude@dude:hooks/hooks.json:session_start:0:0"] entry
carrying a trusted_hash. Installing dude does not grant it: codex plugin add
records no such entry, and an untrusted hook does not run, so using-dude is
not in context until you trust it — though the skills are still invocable
by name. Codex asks at the start of the next interactive session instead: after
the directory-trust prompt, a Hooks need review prompt offers to review the
hook, trust it, or continue without trusting. Codex's hook trust decides whether
injection happens at all. Editing the hook's matcher or command invalidates its
trust and Codex shows Hooks need review again on the next interactive start;
adding a trailing newline does not.
Muse Code's help gives approve as approve <plugin-id[[:kind]:capability-id] | stable-id>; only the bare-id form is measured here: bare
muse plugins approve dude flips exactly runtime_capabilities[0].status
from review_needed to trusted_enabled for
plugin:dude:hook:session-start.
Trust is per capability — skills need no approval and the hook did not appear
in the observed inspect output for effective_capabilities. Whether one
bare-id approval covers multiple hooks is unmeasured. Behavior of an
unapproved hook is unmeasured. Whether editing the hook requires re-approval
is unmeasured.
dude is versioned with semver. The same value lives in
six places: .claude-plugin/plugin.json, the plugin entry in
.claude-plugin/marketplace.json, .codex-plugin/plugin.json,
.muse-plugin/plugin.json, the plugin entry in
.muse-plugin/marketplace.json, and package.json. .agents/plugins/marketplace.json is a versionless mirror:
its schema carries no version, so bump and the version check leave it
alone. What each runtime does with one:
| Runtime | Requires version? | Uses it to decide an update? |
|---|---|---|
| OpenCode | yes | no, git-backed installs do not use it to decide an update |
| Claude Code | no — validate only warns | yes — run /plugin update after a bump to pick it up |
| Codex | yes, strict semver | no |
| Muse Code | yes | yes — run muse plugins update after a bump to pick it up |
So the two manifests Claude Code reads — .claude-plugin/plugin.json and the
plugin entry in .claude-plugin/marketplace.json — carry the shared "version" value.
claude plugin update dude@dude compares versions, so a bump reaches existing
installs only after a manual update.
The two manifests Muse Code reads — .muse-plugin/plugin.json and the
plugin entry in .muse-plugin/marketplace.json — carry the shared "version" value.
muse plugins validate rejects a manifest missing "version" (invalid-manifest-schema).
muse plugins update dude picked up the bumped test version, reporting
previous/new manifest shas.
.codex-plugin/plugin.json and package.json read the same "version"
because their formats require one. Codex keeps a per-version
cache directory (e.g. ~/.codex/plugins/cache/<marketplace>/<plugin>/<version>/),
but marketplace upgrade plus re-adding still advances the checkout to the new
commit.
OpenCode: run opencode plugin update after a bump (or
opencode plugin update github:yowcow/dude for one package).
What each runtime printed when this was measured — and the throwaway plugins the version-less control was taken with — is recorded in issue #42. The 0.154.0 Codex probe is recorded in issue #304.
An investigation is optional, and runs before plan-work only when there's a
cause to find or a question to settle first:
flowchart LR
issue[Issue]
invq[settle-question]
inva[investigate-anomaly]
invp[investigate-performance]
audit[audit-code]
plan[plan-work]
impl[implement-work]
pr[pr-to-ready]
issue --> plan
issue -. optional .-> invq --> plan
issue -. optional .-> inva --> plan
issue -. optional .-> invp --> plan
issue -. optional .-> audit --> plan
plan --> impl --> pr
A run starts with an issue and ends with a pull request waiting for a person to merge it — that issue plus three prompts, across three kinds of session:
Open an issue for what you want done. It is what the plan gets published against, and the parent the sub-issues hang from.
Plan it, in one session:
/dude:plan-work <issue-url>
It researches, agrees a design with you, then publishes that design plus a numbered TODO list at PR granularity as one comment on the issue, and opens one sub-issue per item.
Implement each item, one fresh session per sub-issue:
/dude:implement-work <sub-issue-url>
It takes the item to a draft PR on a pushed branch of verified commits, and ends by naming that PR's URL.
Take that PR to ready, in another fresh session:
/dude:pr-to-ready <pr-url> (ready-on-clean=yes)
It resolves the branch, base and repository from the PR, sets up its own worktree, then loops on CI and review until both are clean.
Then wait for the PR.
Steps 3 and 4 are separate sessions rather than two prompts in one because the
second flow's cost is dominated by re-reading the first's context: measured over
126 runs, the stretch after pr-to-ready starts is 41% of the session's cost,
and starting it fresh drops what it re-reads each turn from roughly 269k tokens
to roughly 60k. Handing it the PR URL is what makes that split practical — the
reference is the whole entry, so no branch name has to be remembered and no
checkout prepared by hand.
A run's sessions need not all be at the same tier.
| What the main loop keeps | Skills | Main loop's tier |
|---|---|---|
| Deciding what to look at and where to dig; a bad choice or an oversight is hard to recover later | plan-work, audit-code, settle-question, investigate-* | Highest tier you have |
| Mostly executing and inquiring | implement-work, pr-to-ready | A cheaper tier carries them |
Every other session runs at whatever tier you launch it at. Three sections below are what that
leaves you to handle: What tier a marked worker runs at, for keeping each
marked worker at its tier once the session under it is cheap,
What the run's own tier decides, for the judgments that come down with the
session instead of staying with those workers, and What else the run's cost
rides on, for the session length and worker count that remain after the
model is cheap. Whether a cheap main loop still
runs implement-work's gates and pr-to-ready's clean judgment at the same
fidelity is not settled here, so nothing below reports that it holds. That
unsettled question does not reach What the run's own tier decides, which
records a different thing: where those judgments run, and what a lowered tier
costs them.
Only the first name on each of those lines is a slash command: Claude Code
passes everything after it to the skill as free text. That is what makes
ready-on-clean=yes usable — it answers in the same breath the one question
pr-to-ready would otherwise stop and ask, whether a clean run should mark the
PR ready. It is not a parsed flag; the argument text is read rather than matched
against a grammar, and it is Claude Code's pass-through that was measured, not
the other runtimes'. Muse Code pass-through is unmeasured.
A fresh session per sub-issue is the shape rather than a preference: a later PR is never a continuation of the previous one and inherits none of its verification. And dude stops at ready — merging, closing the parent issue, and deleting the branch and worktree are yours.
| Runtime | using-dude in context at session start? | How to reach it by hand |
|---|---|---|
| OpenCode | yes — a summary stub via ctx.session.hook("context", …) editing event.system | — |
| Claude Code | yes — a summary stub via a SessionStart hook | — |
| Codex | yes, once the hook is trusted — the same stub via hooks/hooks.json | dude:using-dude |
| Muse Code | yes, on startup once the hook is trusted — a summary stub via a SessionStart hook | — |
Each row's evidence is in the prose below.
OpenCode's package plugin registers all of dude's skills via ctx.skill.transform and appends a summary
stub of using-dude — the same stub sentences as the hook stub under a different envelope — to event.system
through ctx.session.hook("context", …), so the stub is in
context at session start and the full rules load on a dude:using-dude skill
call. The injected text uses a dude-only marker
and does not contain EXTREMELY_IMPORTANT, so Superpowers' bootstrap and
this one do not skip each other. Two loads of the same plugin (a global git
install plus the checkout's .opencode/plugins/) still inject once.
Claude Code needs no invocation: a SessionStart hook injects the ~0.6KB summary
stub inline on startup, clear, and compact (resume and fork keep the
prior session's stub, so the hook does not re-inject there); the full rules load
on a dude:using-dude skill call.
Codex installs all of dude's skills and runs the shared hooks/hooks.json once
the hook is trusted, receiving the same stub — the Install section above
covers what trust involves. The dude:using-dude skill works whether the hook is
trusted or not.
Muse Code needs no invocation: a SessionStart hook injects the summary
stub of using-dude on startup (measured: exit 0 with the stub in the
injection context, Muse Code 1.4.0) — the Install section above covers
what trust involves. Behavior on other sources and with an unapproved
hook is unmeasured.
The skill bodies use bare names (plan-work), because the dude: prefix is a
plugin namespace the host adds.
On Claude Code, dude ships one agent type per tier in using-dude's
Worker tier: dude:highest-tier, whose definition carries model: best,
which Claude Code resolves to the highest model it has available, and
dude:high-tier, whose definition carries model: opus, the top of the
regular lineup. A marked worker dispatched as its tier's type without a model
of its own runs there, whatever the run's own tier and the subagent default.
Any other marked worker dispatched without a model of its own lands on the
runtime's subagent default rather than the run's own tier, which only takes over
when no default is set — so raising the run's own tier does not reach the worker
where the default sits below it. An explicit model argument on the dispatch
overrides both outright, even to a lower tier — which is also how to cap a tier
below what its type carries — so neither the type nor the
default being set correctly is evidence that every marked dispatch honors it. On
Claude Code the default is the environment variable
CLAUDE_CODE_SUBAGENT_MODEL, not a settings.json key; set it to the highest
tier you have and leave it there regardless of the run's own tier.
Effort is a second, separate ceiling: on Claude Code, in a session whose effort
was set with CLAUDE_CODE_EFFORT_LEVEL, or for a worker whose agent definition
carries no effort, a worker runs at the session's own effort and no dispatch
can raise it above that, even where its model lands on the highest tier. Launch
even a cheap main-loop session at the effort you want its marked workers to
have.
Confirming the ceiling actually held takes two checks, not just the first:
the default against the environment
(env | grep CLAUDE_CODE_SUBAGENT_MODEL), then each marked worker's own
transcript for what model and effort it actually ran on — a self-report is
the worker's own account, not the runtime's record of the call
(measurements;
full classification).
This was measured on Claude Code alone; where a runtime carries no such lever,
using-dude's Worker tier leaves it undecided, so leave the main loop's
tier alone there.
A review finding's verdict and a simplify-code proposal's go out to marked
workers, but implement-work's two gates and pr-to-ready's clean check stay
in the main loop and come down with its tier.
The run still reports clean, and no gate in the flow catches the drop.
Cost doesn't ride on tier alone: a grown session's per-request cost rises from re-reading context, eating the cheap-tier saving, and the total is dominated by worker count, which lowering the main loop's tier does not reduce (measurements; correction).
The subagent default also carries the roles that no skill marks —
implement-work's plan drafter and the execution method's per-task reviewer
and per-task implementer. Dispatched without a model of its own, each rides
the same ceiling that What tier a marked worker runs at above sets for the
marked workers' sake. Across 158 Claude Code dispatches of implement-work's
plan drafter, simplify-code's proposer, and the execution method's per-task
reviewer and per-task implementer, the 58 with no model argument all landed
on Opus, at $61 over a four-day window, and the 100 with one all landed off
Opus — the implement-work plan drafter alone accounted for $35 of that $61
(measurements).
Lowering the default would pull every marked worker dispatched as neither
dude:high-tier nor dude:highest-tier down with it
(yowcow/dude#266).
Point a marketplace at a local clone instead of the remote:
/plugin marketplace add <path-to-dude-clone>
/plugin install dude@dude
codex plugin marketplace add <path-to-dude-clone>
codex plugin add dude@dude
muse plugins marketplace add dude-test <path-to-dude-clone>
muse plugins install dude@dude-test
Starting OpenCode from the repository checkout loads
.opencode/plugins/dude.js as a project plugin. Temporarily remove any globally
configured dude plugin entry first, then use the native skill tool to verify
every local skill.
The checkout's plugin context hook and the hook emit the same stub: try hook changes by
editing hooks/session-start and tests/hooks/session-start_test.sh in place,
and keep .opencode/plugins/dude.js repeating those stub sentences. The four stub
sentences are compared whole across the two emitters, with only the install path
and the cksum derived from it normalized — see tests/opencode-plugin_test.sh.
Installing dude a second time under a throwaway name is not a way to try hook
changes out. Two installs run the SessionStart hook twice, and both blocks
reach the same session. Which tree each one came from is readable — the injected
text names the install path it ran from — but the session is still carrying
the stub twice, counted twice against the context in two near-identical blocks.
Neither block carries the rules — both are static summaries — so invoke
dude:using-dude from the intended install for the full rules. Uninstalling the github-sourced
dude@dude first is what avoids that, and it rewrites somebody's plugin
environment — ask whoever owns it.
The hazard is the hook running twice, so it is not specific to Claude Code:
Codex runs hooks/hooks.json too, once the hook is trusted. Whether a second
Codex install injects twice as well has not been measured here.
Whether a second Muse install injects twice is unmeasured here.
Check the manifests before installing:
make manifest
claude plugin validate starts from .claude-plugin/marketplace.json and reaches that same
plugin.json through the entry's "source": "./". It passes without a version
warning while all six version fields agree.
muse plugins validate covers .muse-plugin/. The two validators do not cover
every manifest, so make manifest JSON-parses .agents/plugins/marketplace.json (versionless mirror, no
version), package.json, hooks/hooks.json, .muse-plugin/plugin.json, and
.muse-plugin/marketplace.json, syntax only. make lint test runs neither vendor
validator and never compares the six version fields; the suite checks only that the
three marketplaces agree and that bump's list covers every version-carrying
manifest.
CI's manifest job is the merge gate. It pins the Claude Code validator and the
action SHAs, but
the Muse validator is not pinned (its installer ships only the stable channel),
so that result can change without a commit here. manifest-latest
is a non-required pull-request/weekly compatibility signal using current Claude
Code and Muse releases; investigate upstream failures, update the fixed
baseline when warranted, or deliberately retain it.
AUTHORING.md holds the rules for writing and editing these skills — where
each kind of text belongs, and the deletion test every sentence has to pass.
MIT. See LICENSE.