본문으로 건너뛰기
cccskills
무료GitHub에 공개

inbox

Show every item across managed projects needing the user's attention — PRs, assigned issues, comments, blockers.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

me2resh/apexyard스타 538(GitHub 538 + cccskills 0)
연동 도구GitHubGitLab

실행 점수 미검증

설치 방법 보기

포함된 파일(2)

  • SKILL.md12.9 KB
  • tests/smoke.sh7.0 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Writing: read docs/skills/shared/writing-rule.md before you write a durable artifact.

/inbox — Items Needing Your Attention

Aggregates everything that's currently waiting on you across the projects ApexYard manages. Designed to be the first thing you run in a session.

Path resolution

Read the registry path via portfolio_registry, the per-project docs dir via portfolio_projects_dir, and the ideas backlog via portfolio_ideas_backlog — all from .claude/hooks/_lib-portfolio-paths.sh. Source the helper at the top of any bash block that touches those paths:

source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-read-config.sh"
source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-portfolio-paths.sh"
source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-tracker.sh"
registry=$(portfolio_registry)

Defaults match today's single-fork layout (./apexyard.projects.yaml, ./projects, ./projects/ideas-backlog.md). Adopters in split-portfolio mode override the portfolio.{registry, projects_dir, ideas_backlog} keys in .claude/project-config.json. Don't hardcode literal apexyard.projects.yaml or projects/ paths in bash blocks — the helper resolves whichever mode the adopter is in. See docs/multi-project.md.

Tracker-agnostic issue listing (#710 / AgDR-0093)

The issue sections below (assigned to you, your issues with new comments, blocked items) call tracker_list from _lib-tracker.sh instead of hardcoding gh issue list, so they work on a project whose tracker.kind is glab (GitLab) too. Pass the project's repo: (from the registry) as the first argument — the tracker is resolved per-project — plus generic filters:

# tracker_list <owner/repo> [state=…] [assignee=@me|none|<user>] [author=…] [labels=csv] [search=…] [since=ISO] [limit=N]
# → emits a JSON array: [{ref,number,state,title,url,labels,updatedAt}, …]  ([] on empty/unavailable)
tracker_list "$repo" state=open assignee=@me limit=50 2>/dev/null

Check that each read was complete (#1441). tracker_list prints [] and returns non-zero on failure, and a result that fills the limit may be a short read. Use tracker_list_to, which writes the array to a file and returns the verdict on stdout:

tmp=$(mktemp) || return 1
status=$(tracker_list_to "$tmp" "$repo" state=open assignee=@me limit=50 2>/dev/null); rc=$?
if [ "$status" = "TRUNCATED" ]; then
  status=$(tracker_list_to "$tmp" "$repo" state=open assignee=@me limit=200 2>/dev/null); rc=$?
fi
case "$status" in
  UNKNOWN)
    if [ "$rc" -ne 0 ]; then
      echo "$repo: could not read issues"            # a failure, never print 0
    else
      echo "$repo: read $(jq -r 'length' < "$tmp"), completeness unknown"
    fi ;;
  TRUNCATED) echo "$repo: at least $(jq -r 'length' < "$tmp") issues" ;;  # still not the end
esac
items=$(cat "$tmp"); rm -f "$tmp"

UNKNOWN means two different things, and the exit status tells them apart. A non-zero status is a failed read, so report it as unread. A zero status with UNKNOWN is a successful read whose completeness this library cannot judge: a custom adapter called with no limit, or a payload it cannot count. The rows are good. Only the "is that all of them" answer is missing.

Do not write items=$(tracker_list …) and then read TRACKER_LIST_STATUS. Command substitution runs the call in a subshell, so the variable never reaches you, and a stale verdict from an earlier project reads as this project's. That turns a failed read into a confident zero, which is the failure this check exists to prevent. TRACKER_LIST_STATUS is correct only for a call made in the current shell.

On UNKNOWN, say the count is unknown for that project. Do not fold it into a zero. GitLab caps a page at 100, so a glab project stays TRUNCATED there.

Scope caveat (forge axis, #711). The PR sections still call gh pr list directly. The PR/MR forge abstraction is a separate ticket (#711); until it lands, /inbox's PR sections are GitHub-only. /inbox is therefore issue-axis tracker-agnostic, not fully tracker-agnostic. Filters GitHub expresses but GitLab can't (mentions:, commenter:) stay on a gh-only path, documented at the section that uses them.

Usage

/inbox
/inbox --me octocat
/inbox --since 24h

Scope

/inbox iterates every project in apexyard.projects.yaml at the root of your ops repo (your fork of apexyard). If the registry doesn't exist, print a clear error pointing at docs/multi-project.md.

What goes in the inbox

The inbox is grouped by section. Empty sections are omitted.

1. PRs awaiting your review

Forge axis (#711) — GitHub-only until the PR/MR abstraction lands.

gh pr list \
  --search "is:open is:pr review-requested:@me" \
  --json number,title,url,headRepository,updatedAt,author \
  --limit 50

Run this per repo: from the registry (or use --search "user:your-org" if you have an org).

2. PRs you authored that have changes requested

gh pr list \
  --search "is:open is:pr author:@me review:changes_requested" \
  --json number,title,url

These are blocking you, not your reviewers — they're your inbox.

3. PRs you authored that are approved and ready to merge

gh pr list \
  --search "is:open is:pr author:@me review:approved" \
  --json number,title,url,mergeable,mergeStateStatus

Filter to ones where mergeStateStatus is CLEAN — those are ready to merge right now.

4. Issues assigned to you

Issue axis — tracker-agnostic via tracker_list (run per repo: from the registry):

tracker_list "$repo" state=open assignee=@me limit=50
# → [{ref,number,state,title,url,labels,updatedAt}, …]

5. Issues you opened that have new comments since you last looked

The "new comments since last looked" part is a GitHub-only search qualifier (commenter:>@me) with no GitLab equivalent, so tracker_list fetches your open-authored issues and the comment recency is filtered client-side (the established degradation for no-equivalent filters):

tracker_list "$repo" state=open author=@me
# Then filter client-side on `updatedAt` against a stored "last seen" timestamp
# if available, otherwise show everything from the last 7 days.

6. Mentions in comments

mentions:@me is a cross-repo GitHub-search capability (a different operation than a repo-scoped list) with no GitLab CLI equivalent, so this section stays on a gh-only path — it returns nothing on non-GitHub trackers, and --no-mentions hides it entirely:

# gh-only (degrades to empty on glab / other trackers):
if [ "$(tracker_kind "$repo")" = "gh" ]; then
  gh search issues "mentions:@me is:open" \
    --json number,title,url,repository,updatedAt
fi

7. PRs failing CI on a branch you authored

Forge axis (#711) — GitHub-only until the PR/MR abstraction lands.

gh pr list \
  --search "is:open is:pr author:@me" \
  --json number,title,url,statusCheckRollup

Filter client-side to those where any check is FAILURE.

8. Blocking labels across managed projects

Issue axis — tracker-agnostic via tracker_list (run per project from the registry):

tracker_list "$repo" state=open labels=blocked

9. Reconcile — open issues that already have a merged PR (#923)

Forge axis (#711) — GitHub-only until the PR/MR abstraction lands.

The sibling of the reconcile-before-build rule: that rule stops NEW drift at the spawn boundary; this section surfaces EXISTING drift that already happened. The signature is cheap and mechanical — an issue that is still OPEN but a merged PR already references it (Closes #N that didn't fire because the PR merged to dev, not the release branch; or Refs #N left open on purpose for a QA gate).

Fetch once per repo, not once per open issue — a batched query is the whole point, both for gh rate limits and for wall-clock time across a portfolio:

# 1. Open issue numbers for this repo (one call).
open_issues=$(gh issue list --repo "$repo" --state open --json number --jq '.[].number')

# 2. Merged PRs for this repo, bounded so the scan stays cheap (one call).
#    --limit 200 is a reasonable default; tighten it further with --search
#    "merged:>=<since-date>" on a very active repo, or when --since is passed.
gh pr list --repo "$repo" --state merged \
  --json number,title,body,url,mergedAt --limit 200

Then, for each merged PR's title + body, extract issue references and classify them:

  • Closing keywords — close[sd]?, fix(e[sd])?, resolve[sd]? immediately followed by #N (case-insensitive). A match here against an issue still open is very likely a release-cut artifact — the PR's Closes #N didn't auto-fire because it merged to a non-default branch.
  • Referencing keywords — refs?, references?, related to immediately followed by #N. A match here is likely an intentional QA gate — the ticket is deliberately held open pending verification (see workflows/sdlc.md Phase 5) — surface it as lower-urgency than a closing-keyword match.

Conservative by construction: only count a reference when a closing/referencing keyword sits directly next to the #N (not any bare number appearing anywhere in a PR body) AND N is in the open_issues set fetched in step 1. A PR that happens to mention an unrelated number, or a #N for an issue that's already closed, produces no flag. This is what keeps the section from ever flagging a genuinely-open or gated ticket.

Graceful degradation: if either gh call fails for a repo (rate limit, auth, network), skip that repo's contribution to this section and continue — same as Rule 5 below. If a repo produces zero matches, the section is simply absent for it (Rule 4).

Output format

Group everything under headings, project-prefixed:

INBOX — 2026-04-06 09:14
=========================

🔴 PRs awaiting your review (3)
  · example-app#42  Add export to CSV         updated 1h ago   https://…
  · billing-api#8   Fix invoice rounding      updated 3h ago   https://…
  · marketing#12    Hero copy refresh         updated 1d ago   https://…

🟡 Your PRs with changes requested (1)
  · example-app#39  Refactor session store    Code Reviewer requested changes   https://…

🟢 Your PRs ready to merge (1)
  · example-app#41  Add health endpoint       2 approvals · CI green            https://…

📬 Issues assigned to you (4)
  · example-app#117 [Bug] Login fails on Safari       priority-high   https://…
  · billing-api#22  [Feature] Multi-currency support  priority-medium https://…
  · …

💬 New comments on issues you opened (2)
  · example-app#98   3 new comments since yesterday    https://…
  · marketing#5      Designer left a comment           https://…

🚨 PRs with failing CI (1)
  · example-app#42   lint job failed                    https://…

🛑 Blocked items (1)
  · billing-api#19   Waiting on API key from vendor     https://…

🔁 Reconcile — open issues with a merged PR (2)
  · example-app#88   Closes-but-open · merged PR #101 (release-cut?)   https://…
  · billing-api#31   Refs-open · merged PR #64 (QA gate?)              https://…

Summary: 12 items · 3 PRs to review · 1 ready to merge · 1 blocking CI failure · 2 to reconcile

If everything is empty:

✨ Inbox zero. Nothing waiting on you across {N} projects.

Filters

FlagEffect
--me <user>Run as if <user> is the current user (default: @me)
--since <duration>Only items updated in the window (e.g. 24h, 7d)
--project <name>Limit to one project from the registry
--no-mentionsHide the mentions section
--no-reconcileHide the Reconcile section (#923)

Rules

  1. Read-only — never close, comment, or assign anything from this skill
  2. Always sort by recency within each section — newest updates first
  3. Registry-scoped — only projects listed in apexyard.projects.yaml count; never shell out to "all repos in the org"
  4. Skip empty sections — don't print headers with (0)
  5. Never error on a single project — if one repo is unreachable, mark it ? and continue
  6. Always include URLs — every row needs a clickable link
  7. No noise — items where you have no possible action shouldn't appear (e.g. PRs you've already approved)
  8. Reconcile is a passive surface, not an action — flag drift, never close/re-tag the issue or comment on the PR from this skill; the operator decides what to do with each flagged item

Related skills

  • /tasks — same data but flattened into a single ordered TODO list
  • /status — current project's git/CI snapshot
  • /projects — portfolio-level health snapshot

Part of ApexYard — multi-project SDLC framework for Claude Code · MIT.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

WCAG 2.1 AA audit — perceivable, operable, understandable, robust criteria. Deep-dive for /launch-check accessibility.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

me2resh/apexyard5382026년 10월 26일 업데이트

WCAG 2.2 AA audit — perceivable, operable, understandable, robust criteria. Deep-dive for /launch-check accessibility.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

me2resh/apexyard5382026년 10월 26일 업데이트

agdr

무료

Browse / search / show / stats AgDRs across the portfolio — recalls "have we decided this before?".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

me2resh/apexyard5382026년 10월 26일 업데이트

Analytics audit — SDK config, event naming, funnel completeness, dashboards. Deep-dive for /launch-check analytics.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

me2resh/apexyard5382026년 10월 26일 업데이트

Record per-PR architecture-review approval for design-artifact PRs (required by the architecture gate). ONLY on an explicit per-PR architect "approved".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

me2resh/apexyard5382026년 10월 26일 업데이트

Record per-PR design-review approval (UI merge gate). ONLY on an explicit per-PR designer "approved".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

me2resh/apexyard5382026년 10월 26일 업데이트

me2resh의 스킬 모두 보기

이 스킬의 문제 신고