{"id":"b21e9765-19ea-4e65-a7ce-b49a95067826","entityType":"agent","slug":"clawhub-athola-nm-sanctum-stack-mode","name":"stack-mode","canonicalUrl":"https://www.xpersona.co/agent/clawhub-athola-nm-sanctum-stack-mode","canonicalPath":"/agent/clawhub-athola-nm-sanctum-stack-mode","generatedAt":"2026-10-12T21:32:12.147Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-11T20:16:19.511Z","emptyReason":null},"description":"Detects shared stack membership and iterates a command across all PRs in base-to-tip order Skill: stack-mode Owner: athola Summary: Detects shared stack membership and iterates a command across all PRs in base-to-tip order Tags: latest:1.9.19 Version history: v1.9.19 | 2026-08-26T13:20:53.932Z | user Release v1.9.19 v1.9.17 | 2026-07-30T05:40:55.800Z | user Release v1.9.17 v1.9.16 | 2026-07-14T19:57:46.945Z | user Release v1.9.16 v1.9.14 | 2026-06-30T18:05:36.342Z | user Release v1.9.14 v1.9.13 | 2026-06-2","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 998 downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s17emme0e2m3cpf7k2jvp3a84984b8z9:nm-sanctum-stack-mode","sourceUrl":"https://clawhub.ai/athola/nm-sanctum-stack-mode","homepage":"https://clawhub.ai/athola/skills/nm-sanctum-stack-mode","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/athola/nm-sanctum-stack-mode","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/athola/skills/nm-sanctum-stack-mode","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":60,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Detects shared stack membership and iterates a command across all PRs in base-to-tip order Skill: stack-mode Owner: athola Summary: Detects shared stack members"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T20:16:19.511Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T20:16:19.511Z","emptyReason":null},"stars":null,"forks":null,"downloads":998,"likes":null,"task":null,"library":null,"packageName":null,"latestVersion":"1.9.19","tractionLabel":"998 downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T20:16:19.447Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T20:16:19.511Z","lastCrawledAt":"2026-10-11T20:16:19.447Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T20:16:19.447Z","lastVerifiedAt":null,"highlights":[{"version":"1.9.19","createdAt":"2026-08-26T13:20:53.932Z","changelog":"Release v1.9.19","fileCount":3,"zipByteSize":5770},{"version":"1.9.17","createdAt":"2026-07-30T05:40:55.800Z","changelog":"Release v1.9.17","fileCount":3,"zipByteSize":5830},{"version":"1.9.16","createdAt":"2026-07-14T19:57:46.945Z","changelog":"Release v1.9.16","fileCount":3,"zipByteSize":5879},{"version":"1.9.14","createdAt":"2026-06-30T18:05:36.342Z","changelog":"Release v1.9.14","fileCount":3,"zipByteSize":5916},{"version":"1.9.13","createdAt":"2026-06-27T16:23:28.230Z","changelog":"Release v1.9.13","fileCount":3,"zipByteSize":5897},{"version":"1.9.12","createdAt":"2026-06-19T03:18:54.126Z","changelog":"Release v1.9.12","fileCount":3,"zipByteSize":5784},{"version":"1.0.0","createdAt":"2026-06-18T15:20:46.099Z","changelog":"- Initial release of stack-mode, enabling commands to operate across multiple dependent PRs in base-to-tip order. - Supports `/pr-review --stack` and `/fix-pr --stack` workflows, iterating command logic through all PRs in a detected stack. - Includes multiple strategies to detect PR stacks via branch naming, stack summary comments, or base-chain walks. - Adds hooks for progress tracking and ensures per-PR workflows and summaries remain unchanged, while posting a consolidated root summary. - Auto-detects stack membership and prompts users when applicable; otherwise, respects explicit `--stack` command flag.","fileCount":3,"zipByteSize":5879}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s17emme0e2m3cpf7k2jvp3a84984b8z9:nm-sanctum-stack-mode","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-athola-nm-sanctum-stack-mode/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-athola-nm-sanctum-stack-mode/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-athola-nm-sanctum-stack-mode/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-athola-nm-sanctum-stack-mode/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-athola-nm-sanctum-stack-mode/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-athola-nm-sanctum-stack-mode/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-12T21:32:12.146Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-athola-nm-sanctum-stack-mode/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-athola-nm-sanctum-stack-mode/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-athola-nm-sanctum-stack-mode/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-athola-nm-sanctum-stack-mode/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-11T20:16:19.511Z","emptyReason":null},"readme":"Skill: stack-mode\n\nOwner: athola\n\nSummary: Detects shared stack membership and iterates a command across all PRs in base-to-tip order\n\nTags: latest:1.9.19\n\nVersion history:\n\nv1.9.19 | 2026-08-26T13:20:53.932Z | user\n\nRelease v1.9.19\n\nv1.9.17 | 2026-07-30T05:40:55.800Z | user\n\nRelease v1.9.17\n\nv1.9.16 | 2026-07-14T19:57:46.945Z | user\n\nRelease v1.9.16\n\nv1.9.14 | 2026-06-30T18:05:36.342Z | user\n\nRelease v1.9.14\n\nv1.9.13 | 2026-06-27T16:23:28.230Z | user\n\nRelease v1.9.13\n\nv1.9.12 | 2026-06-19T03:18:54.126Z | user\n\nRelease v1.9.12\n\nv1.0.0 | 2026-06-18T15:20:46.099Z | auto\n\n- Initial release of stack-mode, enabling commands to operate across multiple dependent PRs in base-to-tip order.\n- Supports `/pr-review --stack` and `/fix-pr --stack` workflows, iterating command logic through all PRs in a detected stack.\n- Includes multiple strategies to detect PR stacks via branch naming, stack summary comments, or base-chain walks.\n- Adds hooks for progress tracking and ensures per-PR workflows and summaries remain unchanged, while posting a consolidated root summary.\n- Auto-detects stack membership and prompts users when applicable; otherwise, respects explicit `--stack` command flag.\n\nArchive index:\n\nArchive v1.9.19: 3 files, 5770 bytes\n\nFiles: skill-card.md (1881b), SKILL.md (9786b), _meta.json (141b)\n\nFile v1.9.19:SKILL.md\n\n---\nname: stack-mode\ndescription: |\n  Detects shared stack membership and iterates a command across all PRs in base-to-tip order\nversion: 1.9.8\ntriggers:\n  - git\n  - stacked-diffs\n  - pr\n  - review\n  - fix-pr\n  - iteration\n  - a command supports --stack flag for multi-PR iteration\nmetadata: {\"openclaw\": {\"homepage\": \"https://github.com/athola/claude-night-market/tree/master/plugins/sanctum\", \"emoji\": \"\\u2699\\ufe0f\", \"requires\": {\"config\": [\"night-market.sanctum:stack-create\", \"night-market.sanctum:stack-push\", \"night-market.sanctum:stack-rebase\", \"night-market.leyline:git-platform\"]}}}\nsource: claude-night-market\nsource_plugin: sanctum\n---\n\n> **Night Market Skill** — ported from [claude-night-market/sanctum](https://github.com/athola/claude-night-market/tree/master/plugins/sanctum). For the full experience with agents, hooks, and commands, install the Claude Code plugin.\n\n\n# Stack Mode\n\nShared contract for commands that need to operate across a\nwhole stack of dependent PRs in one invocation.\nUsed by `/pr-review --stack` and `/fix-pr --stack`.\n\nThe goal is one simple thing: when a PR is part of a stack\ntargeting a common base branch, loop the command's normal\nworkflow across every PR in the stack in base-to-tip order\nand emit one consolidated summary on the stack root.\n\n## When to Use\n\nLoad this skill when a command accepts a `--stack` flag\n(or auto-detects stack membership) and needs to iterate\nits normal workflow across multiple PRs.\n\nDo NOT load this skill for single-PR workflows. The\nper-PR workflow stays unchanged; stack mode wraps it.\n\n## Contract\n\nA calling command MUST:\n\n1. Accept a `--stack` boolean flag AND a `--base <branch>`\n   override (default: `master`).\n2. Call Step 1 below to resolve stack membership BEFORE\n   running its main workflow.\n3. Run its main workflow per PR in the resolved order.\n4. Emit per-PR outputs unchanged (thread replies, issue\n   links, etc.).\n5. Emit ONE stack-level summary comment on the root PR\n   using the format in Step 4.\n6. Respect per-PR Gate rules (every PR still needs its own\n   thread resolution and issue tracking).\n\nA calling command MAY:\n\n- Auto-detect stack membership and prompt the user rather\n  than requiring `--stack` explicitly.\n- Short-circuit iteration when a per-PR failure leaves\n  downstream PRs with stale context.\n\n## Required Progress Tracking\n\nThe caller creates `TodoWrite` items:\n\n1. `stack-mode:membership-resolved`\n2. `stack-mode:iteration-complete`\n3. `stack-mode:root-summary-posted`\n\n## Step 1: Resolve Stack Membership (`membership-resolved`)\n\nGiven a starting PR number `$PR_NUM` and optional base\n`$BASE` (default: `master`), try three strategies in\norder and stop at the first that yields a stack of size\n>= 2.\n\n### Strategy A: Branch-name convention (cheapest)\n\n```bash\nSTART_HEAD=$(gh pr view \"$PR_NUM\" \\\n  --json headRefName -q .headRefName)\n\n# stack/<feature-name>/<slice-name>\nif [[ \"$START_HEAD\" =~ ^stack/([^/]+)/.+$ ]]; then\n  FEATURE=\"${BASH_REMATCH[1]}\"\n  PREFIX=\"stack/${FEATURE}/\"\n\n  # All local branches with the same prefix\n  STACK_BRANCHES=$(git branch --list \"${PREFIX}*\" \\\n    | sed 's/^[* ]*//' | sort)\n\n  # Map branches -> PR numbers (skip branches with no PR)\n  STACK_PRS=()\n  for branch in $STACK_BRANCHES; do\n    pr=$(gh pr list --head \"$branch\" \\\n      --json number --jq '.[0].number')\n    [ -n \"$pr\" ] && STACK_PRS+=(\"$pr\")\n  done\n\n  echo \"strategy=A prs=${STACK_PRS[*]}\"\nfi\n```\n\n### Strategy B: Stack summary comment (most reliable)\n\n`stack-push` posts a `## Stack` markdown table on the\nroot PR with columns `# | Branch | PR`. Parse it:\n\n```bash\n# Find the root PR of the stack containing $PR_NUM\n# The current PR may be the root, or may link to it via\n# a \"Part of stack `stack/<feature>`\" phrase in its body\nBODY=$(gh pr view \"$PR_NUM\" --json body -q .body)\n\n# Look for a \"## Stack\" table in THIS PR's comments\nTABLE=$(gh pr view \"$PR_NUM\" --json comments \\\n  --jq '.comments[] | select(.body | contains(\"## Stack\"))\n        | .body' | head -1)\n\n# If not on this PR, look for the root PR reference\nif [ -z \"$TABLE\" ]; then\n  ROOT_REF=$(echo \"$BODY\" \\\n    | grep -oE 'stack/[^ `]+' | head -1)\n  # ... resolve ROOT_REF -> root PR number and re-fetch\nfi\n\n# Parse the table: extract all `#<num>` from the PR column\nSTACK_PRS=($(echo \"$TABLE\" \\\n  | grep -oE '#[0-9]+' | tr -d '#' | sort -un))\n\necho \"strategy=B prs=${STACK_PRS[*]}\"\n```\n\n### Strategy C: Base-chain walk (fallback)\n\nWalk both directions from `$PR_NUM`:\n\n- Up: repeatedly resolve `baseRefName` until it equals\n  `$BASE`. Each visited head is a stack member.\n- Down: find open PRs whose `baseRefName` equals one of\n  the visited heads. Recurse.\n\n```bash\n# Ascend from $PR_NUM to the root\nCUR=$PR_NUM\nCHAIN=($CUR)\nwhile true; do\n  BASE_REF=$(gh pr view \"$CUR\" \\\n    --json baseRefName -q .baseRefName)\n  [ \"$BASE_REF\" = \"$BASE\" ] && break\n\n  PARENT=$(gh pr list --head \"$BASE_REF\" \\\n    --state open --json number --jq '.[0].number')\n  [ -z \"$PARENT\" ] && break\n\n  CHAIN=(\"$PARENT\" \"${CHAIN[@]}\")\n  CUR=$PARENT\ndone\n\n# Descend from the root collecting children\nROOT=${CHAIN[0]}\nFRONTIER=(\"$ROOT\")\nwhile [ ${#FRONTIER[@]} -gt 0 ]; do\n  PARENT=${FRONTIER[0]}\n  FRONTIER=(\"${FRONTIER[@]:1}\")\n\n  PARENT_HEAD=$(gh pr view \"$PARENT\" \\\n    --json headRefName -q .headRefName)\n\n  CHILDREN=($(gh pr list --base \"$PARENT_HEAD\" \\\n    --state open --json number --jq '.[].number'))\n\n  for c in \"${CHILDREN[@]}\"; do\n    CHAIN+=(\"$c\")\n    FRONTIER+=(\"$c\")\n  done\ndone\n\nSTACK_PRS=(\"${CHAIN[@]}\")\necho \"strategy=C prs=${STACK_PRS[*]}\"\n```\n\n### Ordering\n\nRegardless of strategy, order the final list **base-to-tip**\n(root PR first, leaf PR last). The root is the PR whose\n`baseRefName` equals `$BASE`.\n\n```bash\nROOT_PR=\"\"\nfor p in \"${STACK_PRS[@]}\"; do\n  base=$(gh pr view \"$p\" --json baseRefName -q .baseRefName)\n  if [ \"$base\" = \"$BASE\" ]; then\n    ROOT_PR=$p\n    break\n  fi\ndone\n```\n\nIf the stack size is 1, the command MUST fall back to\nsingle-PR mode and emit a warning: `stack-mode: only one\nPR found; --stack has no effect, proceeding as single-PR`.\n\n### GitLab / Bitbucket\n\nSee `Skill(leyline:git-platform)` for `glab` / Bitbucket\nequivalents of the `gh` calls above. The three strategies\ntranslate directly: GitLab MR dependencies replace\nbase-chain walks, and the `glab mr view --output json`\nshape matches `gh pr view`.\n\n## Step 2: Confirm With User (if not explicit)\n\nWhen the caller did NOT pass `--stack` but Step 1 resolved\na stack of size >= 2, print the stack and ask:\n\n```\nDetected stack of N PRs rooted at #<root>:\n  1. #<root>   <title>\n  2. #<p2>     <title>\n  ...\n\nRun the workflow on the full stack? [y/N]\n```\n\nDefault to \"N\" (single-PR mode). With `--stack` explicit,\nskip this prompt.\n\n## Step 3: Iterate (`iteration-complete`)\n\nRun the caller's main workflow once per PR in base-to-tip\norder:\n\n```bash\nFAILED_PRS=()\nfor p in \"${STACK_PRS[@]}\"; do\n  echo \"=== stack-mode: PR #$p ($(($idx+1))/${#STACK_PRS[@]}) ===\"\n\n  # Caller hook: run the single-PR workflow on $p\n  # This includes Gate 1 (thread resolution) and\n  # Gate 2 (issue tracking) per the caller's contract.\n  if ! run_single_pr_workflow \"$p\"; then\n    FAILED_PRS+=(\"$p\")\n    # Stop iteration: downstream PRs may now be stale\n    break\n  fi\ndone\n```\n\nIf any PR fails, the command MUST stop and report\n`stack-mode: halted at #<pr>; downstream PRs untouched`.\nDownstream PRs are intentionally left alone because\ntheir context may have shifted.\n\n## Step 4: Post Stack Summary on Root (`root-summary-posted`)\n\nAfter successful iteration, post ONE consolidated summary\ncomment on the root PR. This does NOT replace per-PR\nsummaries: it links them together.\n\n```markdown\n## Stack <Command Name> Summary\n\n**Stack**: N PRs rooted at #<root>, base `<base-branch>`\n**Command**: <command> (e.g., /fix-pr, /pr-review)\n**Run**: <timestamp>\n\n| # | PR | Branch | Status | Per-PR Summary |\n|---|----|--------|--------|----------------|\n| 1 | #<root> | `stack/<feat>/<root-slice>` | <done/skipped/failed> | [link to comment] |\n| 2 | #<p2>   | `stack/<feat>/<slice-2>`    | <done/skipped/failed> | [link to comment] |\n| ... | ... | ... | ... | ... |\n\n### Cross-PR Notes\n\n- <Any observations that spanned multiple PRs>\n- <Issues created that reference multiple stack PRs>\n- <Base-PR-merged cascade reminders, if any>\n\n### Next Steps\n\n- If root PR merges, run `Skill(sanctum:stack-rebase)` to\n  cascade the base update through descendants.\n- Reviewers: rebase-triggered stale-review flags on\n  descendants are expected after any force-push.\n```\n\nPost via `gh pr comment \"$ROOT_PR\" --body-file <file>`.\n\n## Failure Modes and Recovery\n\n| Failure | Detection | Recovery |\n|---------|-----------|----------|\n| Stack of size 1 | Step 1 returns one PR | Emit warning, fall back to single-PR mode |\n| Base chain loops | Visited set on ascent | Halt, report `stack-mode: cycle detected` |\n| Mid-stack PR failed its Gates | Caller raises | Halt iteration, leave downstream untouched |\n| Strategy B table malformed | Parse fails | Fall through to Strategy C |\n| Auth scope insufficient | `gh` returns 403 | Halt with clear error; caller surfaces to user |\n\n## Notes\n\n- Stack mode is ADDITIVE: single-PR behavior is unchanged.\n  Only the iteration and root summary are new.\n- Per-PR Gate 1 (thread resolution) and Gate 2 (issue\n  tracking) remain unchanged: each PR still passes its\n  own gates independently.\n- Never merge Gate 1 across the stack. A resolved thread\n  on one PR is not a resolved thread on another.\n- The root summary is idempotent: re-running stack mode\n  should update (not duplicate) the summary comment.\n  Match on `## Stack <Command Name> Summary` as the key.\n- `stack-mode` is a read/orchestration skill; it does NOT\n  push, rebase, or edit branches. Those concerns are in\n  `stack-create`, `stack-push`, and `stack-rebase`.\n\nFile v1.9.19:_meta.json\n\n{\n  \"ownerId\": \"kn7d107jg9jv602h9ytsegydq184a42s\",\n  \"slug\": \"nm-sanctum-stack-mode\",\n  \"version\": \"1.9.19\",\n  \"publishedAt\": 1787750453932\n}\n\nFile v1.9.19:skill-card.md\n\n## Description:\n\nDetects shared stack membership and iterates a command across all PRs in base-to-tip order.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[athola](https://clawhub.ai/user/athola)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and engineers use this skill to run stack-aware pull request review or fix workflows across dependent PRs while preserving per-PR handling and producing a consolidated root summary.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Broad pull request and review triggers may activate this workflow in cases where stack iteration is not intended.\n\nMitigation: Use explicit stack workflows where possible and confirm stack membership before running multi-PR actions.\n\nRisk: Stack mode can post or update a consolidated comment on the root pull request.\n\nMitigation: Verify the GitHub CLI account has only the repository permissions intended before using the skill.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/athola/skills/nm-sanctum-stack-mode)\n- [clawdis homepage](https://github.com/athola/claude-night-market/tree/master/plugins/sanctum)\n\n## Skill Output:\n\n**Output Type(s):** [guidance, shell commands, markdown, configuration]\n\n**Output Format:** [Markdown guidance with shell command examples and summary comment templates]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Guides calling commands to resolve stack membership, iterate base-to-tip, and post one consolidated root PR summary.]\n\n## Skill Version(s):\n\n1.9.19 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.9.17: 3 files, 5830 bytes\n\nFiles: skill-card.md (2089b), SKILL.md (9786b), _meta.json (141b)\n\nFile v1.9.17:SKILL.md\n\n---\nname: stack-mode\ndescription: |\n  Detects shared stack membership and iterates a command across all PRs in base-to-tip order\nversion: 1.9.8\ntriggers:\n  - git\n  - stacked-diffs\n  - pr\n  - review\n  - fix-pr\n  - iteration\n  - a command supports --stack flag for multi-PR iteration\nmetadata: {\"openclaw\": {\"homepage\": \"https://github.com/athola/claude-night-market/tree/master/plugins/sanctum\", \"emoji\": \"\\u2699\\ufe0f\", \"requires\": {\"config\": [\"night-market.sanctum:stack-create\", \"night-market.sanctum:stack-push\", \"night-market.sanctum:stack-rebase\", \"night-market.leyline:git-platform\"]}}}\nsource: claude-night-market\nsource_plugin: sanctum\n---\n\n> **Night Market Skill** — ported from [claude-night-market/sanctum](https://github.com/athola/claude-night-market/tree/master/plugins/sanctum). For the full experience with agents, hooks, and commands, install the Claude Code plugin.\n\n\n# Stack Mode\n\nShared contract for commands that need to operate across a\nwhole stack of dependent PRs in one invocation.\nUsed by `/pr-review --stack` and `/fix-pr --stack`.\n\nThe goal is one simple thing: when a PR is part of a stack\ntargeting a common base branch, loop the command's normal\nworkflow across every PR in the stack in base-to-tip order\nand emit one consolidated summary on the stack root.\n\n## When to Use\n\nLoad this skill when a command accepts a `--stack` flag\n(or auto-detects stack membership) and needs to iterate\nits normal workflow across multiple PRs.\n\nDo NOT load this skill for single-PR workflows. The\nper-PR workflow stays unchanged; stack mode wraps it.\n\n## Contract\n\nA calling command MUST:\n\n1. Accept a `--stack` boolean flag AND a `--base <branch>`\n   override (default: `master`).\n2. Call Step 1 below to resolve stack membership BEFORE\n   running its main workflow.\n3. Run its main workflow per PR in the resolved order.\n4. Emit per-PR outputs unchanged (thread replies, issue\n   links, etc.).\n5. Emit ONE stack-level summary comment on the root PR\n   using the format in Step 4.\n6. Respect per-PR Gate rules (every PR still needs its own\n   thread resolution and issue tracking).\n\nA calling command MAY:\n\n- Auto-detect stack membership and prompt the user rather\n  than requiring `--stack` explicitly.\n- Short-circuit iteration when a per-PR failure leaves\n  downstream PRs with stale context.\n\n## Required Progress Tracking\n\nThe caller creates `TodoWrite` items:\n\n1. `stack-mode:membership-resolved`\n2. `stack-mode:iteration-complete`\n3. `stack-mode:root-summary-posted`\n\n## Step 1: Resolve Stack Membership (`membership-resolved`)\n\nGiven a starting PR number `$PR_NUM` and optional base\n`$BASE` (default: `master`), try three strategies in\norder and stop at the first that yields a stack of size\n>= 2.\n\n### Strategy A: Branch-name convention (cheapest)\n\n```bash\nSTART_HEAD=$(gh pr view \"$PR_NUM\" \\\n  --json headRefName -q .headRefName)\n\n# stack/<feature-name>/<slice-name>\nif [[ \"$START_HEAD\" =~ ^stack/([^/]+)/.+$ ]]; then\n  FEATURE=\"${BASH_REMATCH[1]}\"\n  PREFIX=\"stack/${FEATURE}/\"\n\n  # All local branches with the same prefix\n  STACK_BRANCHES=$(git branch --list \"${PREFIX}*\" \\\n    | sed 's/^[* ]*//' | sort)\n\n  # Map branches -> PR numbers (skip branches with no PR)\n  STACK_PRS=()\n  for branch in $STACK_BRANCHES; do\n    pr=$(gh pr list --head \"$branch\" \\\n      --json number --jq '.[0].number')\n    [ -n \"$pr\" ] && STACK_PRS+=(\"$pr\")\n  done\n\n  echo \"strategy=A prs=${STACK_PRS[*]}\"\nfi\n```\n\n### Strategy B: Stack summary comment (most reliable)\n\n`stack-push` posts a `## Stack` markdown table on the\nroot PR with columns `# | Branch | PR`. Parse it:\n\n```bash\n# Find the root PR of the stack containing $PR_NUM\n# The current PR may be the root, or may link to it via\n# a \"Part of stack `stack/<feature>`\" phrase in its body\nBODY=$(gh pr view \"$PR_NUM\" --json body -q .body)\n\n# Look for a \"## Stack\" table in THIS PR's comments\nTABLE=$(gh pr view \"$PR_NUM\" --json comments \\\n  --jq '.comments[] | select(.body | contains(\"## Stack\"))\n        | .body' | head -1)\n\n# If not on this PR, look for the root PR reference\nif [ -z \"$TABLE\" ]; then\n  ROOT_REF=$(echo \"$BODY\" \\\n    | grep -oE 'stack/[^ `]+' | head -1)\n  # ... resolve ROOT_REF -> root PR number and re-fetch\nfi\n\n# Parse the table: extract all `#<num>` from the PR column\nSTACK_PRS=($(echo \"$TABLE\" \\\n  | grep -oE '#[0-9]+' | tr -d '#' | sort -un))\n\necho \"strategy=B prs=${STACK_PRS[*]}\"\n```\n\n### Strategy C: Base-chain walk (fallback)\n\nWalk both directions from `$PR_NUM`:\n\n- Up: repeatedly resolve `baseRefName` until it equals\n  `$BASE`. Each visited head is a stack member.\n- Down: find open PRs whose `baseRefName` equals one of\n  the visited heads. Recurse.\n\n```bash\n# Ascend from $PR_NUM to the root\nCUR=$PR_NUM\nCHAIN=($CUR)\nwhile true; do\n  BASE_REF=$(gh pr view \"$CUR\" \\\n    --json baseRefName -q .baseRefName)\n  [ \"$BASE_REF\" = \"$BASE\" ] && break\n\n  PARENT=$(gh pr list --head \"$BASE_REF\" \\\n    --state open --json number --jq '.[0].number')\n  [ -z \"$PARENT\" ] && break\n\n  CHAIN=(\"$PARENT\" \"${CHAIN[@]}\")\n  CUR=$PARENT\ndone\n\n# Descend from the root collecting children\nROOT=${CHAIN[0]}\nFRONTIER=(\"$ROOT\")\nwhile [ ${#FRONTIER[@]} -gt 0 ]; do\n  PARENT=${FRONTIER[0]}\n  FRONTIER=(\"${FRONTIER[@]:1}\")\n\n  PARENT_HEAD=$(gh pr view \"$PARENT\" \\\n    --json headRefName -q .headRefName)\n\n  CHILDREN=($(gh pr list --base \"$PARENT_HEAD\" \\\n    --state open --json number --jq '.[].number'))\n\n  for c in \"${CHILDREN[@]}\"; do\n    CHAIN+=(\"$c\")\n    FRONTIER+=(\"$c\")\n  done\ndone\n\nSTACK_PRS=(\"${CHAIN[@]}\")\necho \"strategy=C prs=${STACK_PRS[*]}\"\n```\n\n### Ordering\n\nRegardless of strategy, order the final list **base-to-tip**\n(root PR first, leaf PR last). The root is the PR whose\n`baseRefName` equals `$BASE`.\n\n```bash\nROOT_PR=\"\"\nfor p in \"${STACK_PRS[@]}\"; do\n  base=$(gh pr view \"$p\" --json baseRefName -q .baseRefName)\n  if [ \"$base\" = \"$BASE\" ]; then\n    ROOT_PR=$p\n    break\n  fi\ndone\n```\n\nIf the stack size is 1, the command MUST fall back to\nsingle-PR mode and emit a warning: `stack-mode: only one\nPR found; --stack has no effect, proceeding as single-PR`.\n\n### GitLab / Bitbucket\n\nSee `Skill(leyline:git-platform)` for `glab` / Bitbucket\nequivalents of the `gh` calls above. The three strategies\ntranslate directly: GitLab MR dependencies replace\nbase-chain walks, and the `glab mr view --output json`\nshape matches `gh pr view`.\n\n## Step 2: Confirm With User (if not explicit)\n\nWhen the caller did NOT pass `--stack` but Step 1 resolved\na stack of size >= 2, print the stack and ask:\n\n```\nDetected stack of N PRs rooted at #<root>:\n  1. #<root>   <title>\n  2. #<p2>     <title>\n  ...\n\nRun the workflow on the full stack? [y/N]\n```\n\nDefault to \"N\" (single-PR mode). With `--stack` explicit,\nskip this prompt.\n\n## Step 3: Iterate (`iteration-complete`)\n\nRun the caller's main workflow once per PR in base-to-tip\norder:\n\n```bash\nFAILED_PRS=()\nfor p in \"${STACK_PRS[@]}\"; do\n  echo \"=== stack-mode: PR #$p ($(($idx+1))/${#STACK_PRS[@]}) ===\"\n\n  # Caller hook: run the single-PR workflow on $p\n  # This includes Gate 1 (thread resolution) and\n  # Gate 2 (issue tracking) per the caller's contract.\n  if ! run_single_pr_workflow \"$p\"; then\n    FAILED_PRS+=(\"$p\")\n    # Stop iteration: downstream PRs may now be stale\n    break\n  fi\ndone\n```\n\nIf any PR fails, the command MUST stop and report\n`stack-mode: halted at #<pr>; downstream PRs untouched`.\nDownstream PRs are intentionally left alone because\ntheir context may have shifted.\n\n## Step 4: Post Stack Summary on Root (`root-summary-posted`)\n\nAfter successful iteration, post ONE consolidated summary\ncomment on the root PR. This does NOT replace per-PR\nsummaries: it links them together.\n\n```markdown\n## Stack <Command Name> Summary\n\n**Stack**: N PRs rooted at #<root>, base `<base-branch>`\n**Command**: <command> (e.g., /fix-pr, /pr-review)\n**Run**: <timestamp>\n\n| # | PR | Branch | Status | Per-PR Summary |\n|---|----|--------|--------|----------------|\n| 1 | #<root> | `stack/<feat>/<root-slice>` | <done/skipped/failed> | [link to comment] |\n| 2 | #<p2>   | `stack/<feat>/<slice-2>`    | <done/skipped/failed> | [link to comment] |\n| ... | ... | ... | ... | ... |\n\n### Cross-PR Notes\n\n- <Any observations that spanned multiple PRs>\n- <Issues created that reference multiple stack PRs>\n- <Base-PR-merged cascade reminders, if any>\n\n### Next Steps\n\n- If root PR merges, run `Skill(sanctum:stack-rebase)` to\n  cascade the base update through descendants.\n- Reviewers: rebase-triggered stale-review flags on\n  descendants are expected after any force-push.\n```\n\nPost via `gh pr comment \"$ROOT_PR\" --body-file <file>`.\n\n## Failure Modes and Recovery\n\n| Failure | Detection | Recovery |\n|---------|-----------|----------|\n| Stack of size 1 | Step 1 returns one PR | Emit warning, fall back to single-PR mode |\n| Base chain loops | Visited set on ascent | Halt, report `stack-mode: cycle detected` |\n| Mid-stack PR failed its Gates | Caller raises | Halt iteration, leave downstream untouched |\n| Strategy B table malformed | Parse fails | Fall through to Strategy C |\n| Auth scope insufficient | `gh` returns 403 | Halt with clear error; caller surfaces to user |\n\n## Notes\n\n- Stack mode is ADDITIVE: single-PR behavior is unchanged.\n  Only the iteration and root summary are new.\n- Per-PR Gate 1 (thread resolution) and Gate 2 (issue\n  tracking) remain unchanged: each PR still passes its\n  own gates independently.\n- Never merge Gate 1 across the stack. A resolved thread\n  on one PR is not a resolved thread on another.\n- The root summary is idempotent: re-running stack mode\n  should update (not duplicate) the summary comment.\n  Match on `## Stack <Command Name> Summary` as the key.\n- `stack-mode` is a read/orchestration skill; it does NOT\n  push, rebase, or edit branches. Those concerns are in\n  `stack-create`, `stack-push`, and `stack-rebase`.\n\nFile v1.9.17:_meta.json\n\n{\n  \"ownerId\": \"kn7d107jg9jv602h9ytsegydq184a42s\",\n  \"slug\": \"nm-sanctum-stack-mode\",\n  \"version\": \"1.9.17\",\n  \"publishedAt\": 1785390055800\n}\n\nFile v1.9.17:skill-card.md\n\n## Description: <br>\nDetects shared stack membership and iterates a command across all PRs in base-to-tip order. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[athola](https://clawhub.ai/user/athola) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and engineering agents use this skill when a PR workflow supports stack mode and needs to resolve, process, and summarize a stack of dependent PRs in base-to-tip order. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The workflow can write a consolidated stack summary comment to a root PR when the agent has repository permissions. <br>\nMitigation: Install only where the agent is allowed to read PR metadata and post PR comments, and review repository permissions before use. <br>\nRisk: Readers may treat the skill as read-only because it describes itself as read/orchestration oriented. <br>\nMitigation: Account for the disclosed PR comment write during approval and deployment, while noting that the security evidence says it does not push, rebase, edit branches, or run persistently. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/athola/skills/nm-sanctum-stack-mode) <br>\n- [OpenClaw homepage metadata](https://github.com/athola/claude-night-market/tree/master/plugins/sanctum) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [guidance, markdown, shell commands] <br>\n**Output Format:** [Markdown guidance with shell command examples and a PR summary comment template] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May direct a caller to post one consolidated stack summary comment on the root PR.] <br>\n\n## Skill Version(s): <br>\n1.9.17 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v1.9.16: 3 files, 5879 bytes\n\nFiles: skill-card.md (2187b), SKILL.md (9786b), _meta.json (141b)\n\nFile v1.9.16:SKILL.md\n\n---\nname: stack-mode\ndescription: |\n  Detects shared stack membership and iterates a command across all PRs in base-to-tip order\nversion: 1.9.8\ntriggers:\n  - git\n  - stacked-diffs\n  - pr\n  - review\n  - fix-pr\n  - iteration\n  - a command supports --stack flag for multi-PR iteration\nmetadata: {\"openclaw\": {\"homepage\": \"https://github.com/athola/claude-night-market/tree/master/plugins/sanctum\", \"emoji\": \"\\u2699\\ufe0f\", \"requires\": {\"config\": [\"night-market.sanctum:stack-create\", \"night-market.sanctum:stack-push\", \"night-market.sanctum:stack-rebase\", \"night-market.leyline:git-platform\"]}}}\nsource: claude-night-market\nsource_plugin: sanctum\n---\n\n> **Night Market Skill** — ported from [claude-night-market/sanctum](https://github.com/athola/claude-night-market/tree/master/plugins/sanctum). For the full experience with agents, hooks, and commands, install the Claude Code plugin.\n\n\n# Stack Mode\n\nShared contract for commands that need to operate across a\nwhole stack of dependent PRs in one invocation.\nUsed by `/pr-review --stack` and `/fix-pr --stack`.\n\nThe goal is one simple thing: when a PR is part of a stack\ntargeting a common base branch, loop the command's normal\nworkflow across every PR in the stack in base-to-tip order\nand emit one consolidated summary on the stack root.\n\n## When to Use\n\nLoad this skill when a command accepts a `--stack` flag\n(or auto-detects stack membership) and needs to iterate\nits normal workflow across multiple PRs.\n\nDo NOT load this skill for single-PR workflows. The\nper-PR workflow stays unchanged; stack mode wraps it.\n\n## Contract\n\nA calling command MUST:\n\n1. Accept a `--stack` boolean flag AND a `--base <branch>`\n   override (default: `master`).\n2. Call Step 1 below to resolve stack membership BEFORE\n   running its main workflow.\n3. Run its main workflow per PR in the resolved order.\n4. Emit per-PR outputs unchanged (thread replies, issue\n   links, etc.).\n5. Emit ONE stack-level summary comment on the root PR\n   using the format in Step 4.\n6. Respect per-PR Gate rules (every PR still needs its own\n   thread resolution and issue tracking).\n\nA calling command MAY:\n\n- Auto-detect stack membership and prompt the user rather\n  than requiring `--stack` explicitly.\n- Short-circuit iteration when a per-PR failure leaves\n  downstream PRs with stale context.\n\n## Required Progress Tracking\n\nThe caller creates `TodoWrite` items:\n\n1. `stack-mode:membership-resolved`\n2. `stack-mode:iteration-complete`\n3. `stack-mode:root-summary-posted`\n\n## Step 1: Resolve Stack Membership (`membership-resolved`)\n\nGiven a starting PR number `$PR_NUM` and optional base\n`$BASE` (default: `master`), try three strategies in\norder and stop at the first that yields a stack of size\n>= 2.\n\n### Strategy A: Branch-name convention (cheapest)\n\n```bash\nSTART_HEAD=$(gh pr view \"$PR_NUM\" \\\n  --json headRefName -q .headRefName)\n\n# stack/<feature-name>/<slice-name>\nif [[ \"$START_HEAD\" =~ ^stack/([^/]+)/.+$ ]]; then\n  FEATURE=\"${BASH_REMATCH[1]}\"\n  PREFIX=\"stack/${FEATURE}/\"\n\n  # All local branches with the same prefix\n  STACK_BRANCHES=$(git branch --list \"${PREFIX}*\" \\\n    | sed 's/^[* ]*//' | sort)\n\n  # Map branches -> PR numbers (skip branches with no PR)\n  STACK_PRS=()\n  for branch in $STACK_BRANCHES; do\n    pr=$(gh pr list --head \"$branch\" \\\n      --json number --jq '.[0].number')\n    [ -n \"$pr\" ] && STACK_PRS+=(\"$pr\")\n  done\n\n  echo \"strategy=A prs=${STACK_PRS[*]}\"\nfi\n```\n\n### Strategy B: Stack summary comment (most reliable)\n\n`stack-push` posts a `## Stack` markdown table on the\nroot PR with columns `# | Branch | PR`. Parse it:\n\n```bash\n# Find the root PR of the stack containing $PR_NUM\n# The current PR may be the root, or may link to it via\n# a \"Part of stack `stack/<feature>`\" phrase in its body\nBODY=$(gh pr view \"$PR_NUM\" --json body -q .body)\n\n# Look for a \"## Stack\" table in THIS PR's comments\nTABLE=$(gh pr view \"$PR_NUM\" --json comments \\\n  --jq '.comments[] | select(.body | contains(\"## Stack\"))\n        | .body' | head -1)\n\n# If not on this PR, look for the root PR reference\nif [ -z \"$TABLE\" ]; then\n  ROOT_REF=$(echo \"$BODY\" \\\n    | grep -oE 'stack/[^ `]+' | head -1)\n  # ... resolve ROOT_REF -> root PR number and re-fetch\nfi\n\n# Parse the table: extract all `#<num>` from the PR column\nSTACK_PRS=($(echo \"$TABLE\" \\\n  | grep -oE '#[0-9]+' | tr -d '#' | sort -un))\n\necho \"strategy=B prs=${STACK_PRS[*]}\"\n```\n\n### Strategy C: Base-chain walk (fallback)\n\nWalk both directions from `$PR_NUM`:\n\n- Up: repeatedly resolve `baseRefName` until it equals\n  `$BASE`. Each visited head is a stack member.\n- Down: find open PRs whose `baseRefName` equals one of\n  the visited heads. Recurse.\n\n```bash\n# Ascend from $PR_NUM to the root\nCUR=$PR_NUM\nCHAIN=($CUR)\nwhile true; do\n  BASE_REF=$(gh pr view \"$CUR\" \\\n    --json baseRefName -q .baseRefName)\n  [ \"$BASE_REF\" = \"$BASE\" ] && break\n\n  PARENT=$(gh pr list --head \"$BASE_REF\" \\\n    --state open --json number --jq '.[0].number')\n  [ -z \"$PARENT\" ] && break\n\n  CHAIN=(\"$PARENT\" \"${CHAIN[@]}\")\n  CUR=$PARENT\ndone\n\n# Descend from the root collecting children\nROOT=${CHAIN[0]}\nFRONTIER=(\"$ROOT\")\nwhile [ ${#FRONTIER[@]} -gt 0 ]; do\n  PARENT=${FRONTIER[0]}\n  FRONTIER=(\"${FRONTIER[@]:1}\")\n\n  PARENT_HEAD=$(gh pr view \"$PARENT\" \\\n    --json headRefName -q .headRefName)\n\n  CHILDREN=($(gh pr list --base \"$PARENT_HEAD\" \\\n    --state open --json number --jq '.[].number'))\n\n  for c in \"${CHILDREN[@]}\"; do\n    CHAIN+=(\"$c\")\n    FRONTIER+=(\"$c\")\n  done\ndone\n\nSTACK_PRS=(\"${CHAIN[@]}\")\necho \"strategy=C prs=${STACK_PRS[*]}\"\n```\n\n### Ordering\n\nRegardless of strategy, order the final list **base-to-tip**\n(root PR first, leaf PR last). The root is the PR whose\n`baseRefName` equals `$BASE`.\n\n```bash\nROOT_PR=\"\"\nfor p in \"${STACK_PRS[@]}\"; do\n  base=$(gh pr view \"$p\" --json baseRefName -q .baseRefName)\n  if [ \"$base\" = \"$BASE\" ]; then\n    ROOT_PR=$p\n    break\n  fi\ndone\n```\n\nIf the stack size is 1, the command MUST fall back to\nsingle-PR mode and emit a warning: `stack-mode: only one\nPR found; --stack has no effect, proceeding as single-PR`.\n\n### GitLab / Bitbucket\n\nSee `Skill(leyline:git-platform)` for `glab` / Bitbucket\nequivalents of the `gh` calls above. The three strategies\ntranslate directly: GitLab MR dependencies replace\nbase-chain walks, and the `glab mr view --output json`\nshape matches `gh pr view`.\n\n## Step 2: Confirm With User (if not explicit)\n\nWhen the caller did NOT pass `--stack` but Step 1 resolved\na stack of size >= 2, print the stack and ask:\n\n```\nDetected stack of N PRs rooted at #<root>:\n  1. #<root>   <title>\n  2. #<p2>     <title>\n  ...\n\nRun the workflow on the full stack? [y/N]\n```\n\nDefault to \"N\" (single-PR mode). With `--stack` explicit,\nskip this prompt.\n\n## Step 3: Iterate (`iteration-complete`)\n\nRun the caller's main workflow once per PR in base-to-tip\norder:\n\n```bash\nFAILED_PRS=()\nfor p in \"${STACK_PRS[@]}\"; do\n  echo \"=== stack-mode: PR #$p ($(($idx+1))/${#STACK_PRS[@]}) ===\"\n\n  # Caller hook: run the single-PR workflow on $p\n  # This includes Gate 1 (thread resolution) and\n  # Gate 2 (issue tracking) per the caller's contract.\n  if ! run_single_pr_workflow \"$p\"; then\n    FAILED_PRS+=(\"$p\")\n    # Stop iteration: downstream PRs may now be stale\n    break\n  fi\ndone\n```\n\nIf any PR fails, the command MUST stop and report\n`stack-mode: halted at #<pr>; downstream PRs untouched`.\nDownstream PRs are intentionally left alone because\ntheir context may have shifted.\n\n## Step 4: Post Stack Summary on Root (`root-summary-posted`)\n\nAfter successful iteration, post ONE consolidated summary\ncomment on the root PR. This does NOT replace per-PR\nsummaries: it links them together.\n\n```markdown\n## Stack <Command Name> Summary\n\n**Stack**: N PRs rooted at #<root>, base `<base-branch>`\n**Command**: <command> (e.g., /fix-pr, /pr-review)\n**Run**: <timestamp>\n\n| # | PR | Branch | Status | Per-PR Summary |\n|---|----|--------|--------|----------------|\n| 1 | #<root> | `stack/<feat>/<root-slice>` | <done/skipped/failed> | [link to comment] |\n| 2 | #<p2>   | `stack/<feat>/<slice-2>`    | <done/skipped/failed> | [link to comment] |\n| ... | ... | ... | ... | ... |\n\n### Cross-PR Notes\n\n- <Any observations that spanned multiple PRs>\n- <Issues created that reference multiple stack PRs>\n- <Base-PR-merged cascade reminders, if any>\n\n### Next Steps\n\n- If root PR merges, run `Skill(sanctum:stack-rebase)` to\n  cascade the base update through descendants.\n- Reviewers: rebase-triggered stale-review flags on\n  descendants are expected after any force-push.\n```\n\nPost via `gh pr comment \"$ROOT_PR\" --body-file <file>`.\n\n## Failure Modes and Recovery\n\n| Failure | Detection | Recovery |\n|---------|-----------|----------|\n| Stack of size 1 | Step 1 returns one PR | Emit warning, fall back to single-PR mode |\n| Base chain loops | Visited set on ascent | Halt, report `stack-mode: cycle detected` |\n| Mid-stack PR failed its Gates | Caller raises | Halt iteration, leave downstream untouched |\n| Strategy B table malformed | Parse fails | Fall through to Strategy C |\n| Auth scope insufficient | `gh` returns 403 | Halt with clear error; caller surfaces to user |\n\n## Notes\n\n- Stack mode is ADDITIVE: single-PR behavior is unchanged.\n  Only the iteration and root summary are new.\n- Per-PR Gate 1 (thread resolution) and Gate 2 (issue\n  tracking) remain unchanged: each PR still passes its\n  own gates independently.\n- Never merge Gate 1 across the stack. A resolved thread\n  on one PR is not a resolved thread on another.\n- The root summary is idempotent: re-running stack mode\n  should update (not duplicate) the summary comment.\n  Match on `## Stack <Command Name> Summary` as the key.\n- `stack-mode` is a read/orchestration skill; it does NOT\n  push, rebase, or edit branches. Those concerns are in\n  `stack-create`, `stack-push`, and `stack-rebase`.\n\nFile v1.9.16:_meta.json\n\n{\n  \"ownerId\": \"kn7d107jg9jv602h9ytsegydq184a42s\",\n  \"slug\": \"nm-sanctum-stack-mode\",\n  \"version\": \"1.9.16\",\n  \"publishedAt\": 1784059066945\n}\n\nFile v1.9.16:skill-card.md\n\n## Description: <br>\nDetects shared stack membership and iterates a command across all PRs in base-to-tip order. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[athola](https://clawhub.ai/user/athola) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and engineering agents use this skill when a review or fix command needs to operate across a stack of dependent pull requests while preserving each pull request's normal workflow. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can guide an agent to inspect pull request relationships and post a consolidated comment on the root pull request. <br>\nMitigation: Use it in repositories where the agent is authorized to use git and GitHub or GitLab CLI access, and review automated or public comments before posting when approval is required. <br>\nRisk: Automatic stack detection could expand a single-pull-request workflow into multiple pull requests. <br>\nMitigation: Prefer an explicit --stack workflow, and require user confirmation before running stack mode when stack membership is auto-detected. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/athola/skills/nm-sanctum-stack-mode) <br>\n- [Sanctum plugin homepage](https://github.com/athola/claude-night-market/tree/master/plugins/sanctum) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [guidance, markdown, shell commands, configuration] <br>\n**Output Format:** [Markdown with shell command examples and summary comment templates] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Produces stack membership guidance, progress tracking markers, failure handling notes, and a root pull request summary format.] <br>\n\n## Skill Version(s): <br>\n1.9.16 (source: server release metadata; artifact frontmatter states 1.9.8) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v1.9.14: 3 files, 5916 bytes\n\nFiles: skill-card.md (2340b), SKILL.md (9786b), _meta.json (141b)\n\nFile v1.9.14:SKILL.md\n\n---\nname: stack-mode\ndescription: |\n  Detects shared stack membership and iterates a command across all PRs in base-to-tip order\nversion: 1.9.8\ntriggers:\n  - git\n  - stacked-diffs\n  - pr\n  - review\n  - fix-pr\n  - iteration\n  - a command supports --stack flag for multi-PR iteration\nmetadata: {\"openclaw\": {\"homepage\": \"https://github.com/athola/claude-night-market/tree/master/plugins/sanctum\", \"emoji\": \"\\u2699\\ufe0f\", \"requires\": {\"config\": [\"night-market.sanctum:stack-create\", \"night-market.sanctum:stack-push\", \"night-market.sanctum:stack-rebase\", \"night-market.leyline:git-platform\"]}}}\nsource: claude-night-market\nsource_plugin: sanctum\n---\n\n> **Night Market Skill** — ported from [claude-night-market/sanctum](https://github.com/athola/claude-night-market/tree/master/plugins/sanctum). For the full experience with agents, hooks, and commands, install the Claude Code plugin.\n\n\n# Stack Mode\n\nShared contract for commands that need to operate across a\nwhole stack of dependent PRs in one invocation.\nUsed by `/pr-review --stack` and `/fix-pr --stack`.\n\nThe goal is one simple thing: when a PR is part of a stack\ntargeting a common base branch, loop the command's normal\nworkflow across every PR in the stack in base-to-tip order\nand emit one consolidated summary on the stack root.\n\n## When to Use\n\nLoad this skill when a command accepts a `--stack` flag\n(or auto-detects stack membership) and needs to iterate\nits normal workflow across multiple PRs.\n\nDo NOT load this skill for single-PR workflows. The\nper-PR workflow stays unchanged; stack mode wraps it.\n\n## Contract\n\nA calling command MUST:\n\n1. Accept a `--stack` boolean flag AND a `--base <branch>`\n   override (default: `master`).\n2. Call Step 1 below to resolve stack membership BEFORE\n   running its main workflow.\n3. Run its main workflow per PR in the resolved order.\n4. Emit per-PR outputs unchanged (thread replies, issue\n   links, etc.).\n5. Emit ONE stack-level summary comment on the root PR\n   using the format in Step 4.\n6. Respect per-PR Gate rules (every PR still needs its own\n   thread resolution and issue tracking).\n\nA calling command MAY:\n\n- Auto-detect stack membership and prompt the user rather\n  than requiring `--stack` explicitly.\n- Short-circuit iteration when a per-PR failure leaves\n  downstream PRs with stale context.\n\n## Required Progress Tracking\n\nThe caller creates `TodoWrite` items:\n\n1. `stack-mode:membership-resolved`\n2. `stack-mode:iteration-complete`\n3. `stack-mode:root-summary-posted`\n\n## Step 1: Resolve Stack Membership (`membership-resolved`)\n\nGiven a starting PR number `$PR_NUM` and optional base\n`$BASE` (default: `master`), try three strategies in\norder and stop at the first that yields a stack of size\n>= 2.\n\n### Strategy A: Branch-name convention (cheapest)\n\n```bash\nSTART_HEAD=$(gh pr view \"$PR_NUM\" \\\n  --json headRefName -q .headRefName)\n\n# stack/<feature-name>/<slice-name>\nif [[ \"$START_HEAD\" =~ ^stack/([^/]+)/.+$ ]]; then\n  FEATURE=\"${BASH_REMATCH[1]}\"\n  PREFIX=\"stack/${FEATURE}/\"\n\n  # All local branches with the same prefix\n  STACK_BRANCHES=$(git branch --list \"${PREFIX}*\" \\\n    | sed 's/^[* ]*//' | sort)\n\n  # Map branches -> PR numbers (skip branches with no PR)\n  STACK_PRS=()\n  for branch in $STACK_BRANCHES; do\n    pr=$(gh pr list --head \"$branch\" \\\n      --json number --jq '.[0].number')\n    [ -n \"$pr\" ] && STACK_PRS+=(\"$pr\")\n  done\n\n  echo \"strategy=A prs=${STACK_PRS[*]}\"\nfi\n```\n\n### Strategy B: Stack summary comment (most reliable)\n\n`stack-push` posts a `## Stack` markdown table on the\nroot PR with columns `# | Branch | PR`. Parse it:\n\n```bash\n# Find the root PR of the stack containing $PR_NUM\n# The current PR may be the root, or may link to it via\n# a \"Part of stack `stack/<feature>`\" phrase in its body\nBODY=$(gh pr view \"$PR_NUM\" --json body -q .body)\n\n# Look for a \"## Stack\" table in THIS PR's comments\nTABLE=$(gh pr view \"$PR_NUM\" --json comments \\\n  --jq '.comments[] | select(.body | contains(\"## Stack\"))\n        | .body' | head -1)\n\n# If not on this PR, look for the root PR reference\nif [ -z \"$TABLE\" ]; then\n  ROOT_REF=$(echo \"$BODY\" \\\n    | grep -oE 'stack/[^ `]+' | head -1)\n  # ... resolve ROOT_REF -> root PR number and re-fetch\nfi\n\n# Parse the table: extract all `#<num>` from the PR column\nSTACK_PRS=($(echo \"$TABLE\" \\\n  | grep -oE '#[0-9]+' | tr -d '#' | sort -un))\n\necho \"strategy=B prs=${STACK_PRS[*]}\"\n```\n\n### Strategy C: Base-chain walk (fallback)\n\nWalk both directions from `$PR_NUM`:\n\n- Up: repeatedly resolve `baseRefName` until it equals\n  `$BASE`. Each visited head is a stack member.\n- Down: find open PRs whose `baseRefName` equals one of\n  the visited heads. Recurse.\n\n```bash\n# Ascend from $PR_NUM to the root\nCUR=$PR_NUM\nCHAIN=($CUR)\nwhile true; do\n  BASE_REF=$(gh pr view \"$CUR\" \\\n    --json baseRefName -q .baseRefName)\n  [ \"$BASE_REF\" = \"$BASE\" ] && break\n\n  PARENT=$(gh pr list --head \"$BASE_REF\" \\\n    --state open --json number --jq '.[0].number')\n  [ -z \"$PARENT\" ] && break\n\n  CHAIN=(\"$PARENT\" \"${CHAIN[@]}\")\n  CUR=$PARENT\ndone\n\n# Descend from the root collecting children\nROOT=${CHAIN[0]}\nFRONTIER=(\"$ROOT\")\nwhile [ ${#FRONTIER[@]} -gt 0 ]; do\n  PARENT=${FRONTIER[0]}\n  FRONTIER=(\"${FRONTIER[@]:1}\")\n\n  PARENT_HEAD=$(gh pr view \"$PARENT\" \\\n    --json headRefName -q .headRefName)\n\n  CHILDREN=($(gh pr list --base \"$PARENT_HEAD\" \\\n    --state open --json number --jq '.[].number'))\n\n  for c in \"${CHILDREN[@]}\"; do\n    CHAIN+=(\"$c\")\n    FRONTIER+=(\"$c\")\n  done\ndone\n\nSTACK_PRS=(\"${CHAIN[@]}\")\necho \"strategy=C prs=${STACK_PRS[*]}\"\n```\n\n### Ordering\n\nRegardless of strategy, order the final list **base-to-tip**\n(root PR first, leaf PR last). The root is the PR whose\n`baseRefName` equals `$BASE`.\n\n```bash\nROOT_PR=\"\"\nfor p in \"${STACK_PRS[@]}\"; do\n  base=$(gh pr view \"$p\" --json baseRefName -q .baseRefName)\n  if [ \"$base\" = \"$BASE\" ]; then\n    ROOT_PR=$p\n    break\n  fi\ndone\n```\n\nIf the stack size is 1, the command MUST fall back to\nsingle-PR mode and emit a warning: `stack-mode: only one\nPR found; --stack has no effect, proceeding as single-PR`.\n\n### GitLab / Bitbucket\n\nSee `Skill(leyline:git-platform)` for `glab` / Bitbucket\nequivalents of the `gh` calls above. The three strategies\ntranslate directly: GitLab MR dependencies replace\nbase-chain walks, and the `glab mr view --output json`\nshape matches `gh pr view`.\n\n## Step 2: Confirm With User (if not explicit)\n\nWhen the caller did NOT pass `--stack` but Step 1 resolved\na stack of size >= 2, print the stack and ask:\n\n```\nDetected stack of N PRs rooted at #<root>:\n  1. #<root>   <title>\n  2. #<p2>     <title>\n  ...\n\nRun the workflow on the full stack? [y/N]\n```\n\nDefault to \"N\" (single-PR mode). With `--stack` explicit,\nskip this prompt.\n\n## Step 3: Iterate (`iteration-complete`)\n\nRun the caller's main workflow once per PR in base-to-tip\norder:\n\n```bash\nFAILED_PRS=()\nfor p in \"${STACK_PRS[@]}\"; do\n  echo \"=== stack-mode: PR #$p ($(($idx+1))/${#STACK_PRS[@]}) ===\"\n\n  # Caller hook: run the single-PR workflow on $p\n  # This includes Gate 1 (thread resolution) and\n  # Gate 2 (issue tracking) per the caller's contract.\n  if ! run_single_pr_workflow \"$p\"; then\n    FAILED_PRS+=(\"$p\")\n    # Stop iteration: downstream PRs may now be stale\n    break\n  fi\ndone\n```\n\nIf any PR fails, the command MUST stop and report\n`stack-mode: halted at #<pr>; downstream PRs untouched`.\nDownstream PRs are intentionally left alone because\ntheir context may have shifted.\n\n## Step 4: Post Stack Summary on Root (`root-summary-posted`)\n\nAfter successful iteration, post ONE consolidated summary\ncomment on the root PR. This does NOT replace per-PR\nsummaries: it links them together.\n\n```markdown\n## Stack <Command Name> Summary\n\n**Stack**: N PRs rooted at #<root>, base `<base-branch>`\n**Command**: <command> (e.g., /fix-pr, /pr-review)\n**Run**: <timestamp>\n\n| # | PR | Branch | Status | Per-PR Summary |\n|---|----|--------|--------|----------------|\n| 1 | #<root> | `stack/<feat>/<root-slice>` | <done/skipped/failed> | [link to comment] |\n| 2 | #<p2>   | `stack/<feat>/<slice-2>`    | <done/skipped/failed> | [link to comment] |\n| ... | ... | ... | ... | ... |\n\n### Cross-PR Notes\n\n- <Any observations that spanned multiple PRs>\n- <Issues created that reference multiple stack PRs>\n- <Base-PR-merged cascade reminders, if any>\n\n### Next Steps\n\n- If root PR merges, run `Skill(sanctum:stack-rebase)` to\n  cascade the base update through descendants.\n- Reviewers: rebase-triggered stale-review flags on\n  descendants are expected after any force-push.\n```\n\nPost via `gh pr comment \"$ROOT_PR\" --body-file <file>`.\n\n## Failure Modes and Recovery\n\n| Failure | Detection | Recovery |\n|---------|-----------|----------|\n| Stack of size 1 | Step 1 returns one PR | Emit warning, fall back to single-PR mode |\n| Base chain loops | Visited set on ascent | Halt, report `stack-mode: cycle detected` |\n| Mid-stack PR failed its Gates | Caller raises | Halt iteration, leave downstream untouched |\n| Strategy B table malformed | Parse fails | Fall through to Strategy C |\n| Auth scope insufficient | `gh` returns 403 | Halt with clear error; caller surfaces to user |\n\n## Notes\n\n- Stack mode is ADDITIVE: single-PR behavior is unchanged.\n  Only the iteration and root summary are new.\n- Per-PR Gate 1 (thread resolution) and Gate 2 (issue\n  tracking) remain unchanged: each PR still passes its\n  own gates independently.\n- Never merge Gate 1 across the stack. A resolved thread\n  on one PR is not a resolved thread on another.\n- The root summary is idempotent: re-running stack mode\n  should update (not duplicate) the summary comment.\n  Match on `## Stack <Command Name> Summary` as the key.\n- `stack-mode` is a read/orchestration skill; it does NOT\n  push, rebase, or edit branches. Those concerns are in\n  `stack-create`, `stack-push`, and `stack-rebase`.\n\nFile v1.9.14:_meta.json\n\n{\n  \"ownerId\": \"kn7d107jg9jv602h9ytsegydq184a42s\",\n  \"slug\": \"nm-sanctum-stack-mode\",\n  \"version\": \"1.9.14\",\n  \"publishedAt\": 1782842736342\n}\n\nFile v1.9.14:skill-card.md\n\n## Description: <br>\nDetects shared stack membership and iterates a command across all PRs in base-to-tip order. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[athola](https://clawhub.ai/user/athola) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and agents use this skill to run stack-aware pull request workflows. It resolves related PRs, iterates the caller's normal workflow in base-to-tip order, preserves per-PR gates, and produces one consolidated root summary. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Broad activation keywords may load the skill during unrelated Git or PR work. <br>\nMitigation: Confirm the agent is performing a stack workflow before allowing it to act across multiple PRs. <br>\nRisk: The skill may use an authenticated Git hosting CLI session to inspect PRs and post a consolidated summary comment. <br>\nMitigation: Use it only in repositories where that CLI session is appropriate, and review the intended stack summary before posting. <br>\nRisk: A failed PR in the middle of a stack can make downstream PR context stale. <br>\nMitigation: Stop iteration at the failed PR and leave downstream PRs untouched, matching the artifact's recovery guidance. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/athola/skills/nm-sanctum-stack-mode) <br>\n- [ClawHub publisher profile](https://clawhub.ai/user/athola) <br>\n- [Metadata homepage](https://github.com/athola/claude-night-market/tree/master/plugins/sanctum) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, shell commands, guidance] <br>\n**Output Format:** [Markdown guidance with bash command snippets and a stack-summary template] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May prompt for confirmation before running across multiple PRs and may post a consolidated summary comment on the stack root.] <br>\n\n## Skill Version(s): <br>\n1.9.14 (source: server release metadata) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v1.9.13: 3 files, 5897 bytes\n\nFiles: skill-card.md (2265b), SKILL.md (9786b), _meta.json (141b)\n\nFile v1.9.13:SKILL.md\n\n---\nname: stack-mode\ndescription: |\n  Detects shared stack membership and iterates a command across all PRs in base-to-tip order\nversion: 1.9.8\ntriggers:\n  - git\n  - stacked-diffs\n  - pr\n  - review\n  - fix-pr\n  - iteration\n  - a command supports --stack flag for multi-PR iteration\nmetadata: {\"openclaw\": {\"homepage\": \"https://github.com/athola/claude-night-market/tree/master/plugins/sanctum\", \"emoji\": \"\\u2699\\ufe0f\", \"requires\": {\"config\": [\"night-market.sanctum:stack-create\", \"night-market.sanctum:stack-push\", \"night-market.sanctum:stack-rebase\", \"night-market.leyline:git-platform\"]}}}\nsource: claude-night-market\nsource_plugin: sanctum\n---\n\n> **Night Market Skill** — ported from [claude-night-market/sanctum](https://github.com/athola/claude-night-market/tree/master/plugins/sanctum). For the full experience with agents, hooks, and commands, install the Claude Code plugin.\n\n\n# Stack Mode\n\nShared contract for commands that need to operate across a\nwhole stack of dependent PRs in one invocation.\nUsed by `/pr-review --stack` and `/fix-pr --stack`.\n\nThe goal is one simple thing: when a PR is part of a stack\ntargeting a common base branch, loop the command's normal\nworkflow across every PR in the stack in base-to-tip order\nand emit one consolidated summary on the stack root.\n\n## When to Use\n\nLoad this skill when a command accepts a `--stack` flag\n(or auto-detects stack membership) and needs to iterate\nits normal workflow across multiple PRs.\n\nDo NOT load this skill for single-PR workflows. The\nper-PR workflow stays unchanged; stack mode wraps it.\n\n## Contract\n\nA calling command MUST:\n\n1. Accept a `--stack` boolean flag AND a `--base <branch>`\n   override (default: `master`).\n2. Call Step 1 below to resolve stack membership BEFORE\n   running its main workflow.\n3. Run its main workflow per PR in the resolved order.\n4. Emit per-PR outputs unchanged (thread replies, issue\n   links, etc.).\n5. Emit ONE stack-level summary comment on the root PR\n   using the format in Step 4.\n6. Respect per-PR Gate rules (every PR still needs its own\n   thread resolution and issue tracking).\n\nA calling command MAY:\n\n- Auto-detect stack membership and prompt the user rather\n  than requiring `--stack` explicitly.\n- Short-circuit iteration when a per-PR failure leaves\n  downstream PRs with stale context.\n\n## Required Progress Tracking\n\nThe caller creates `TodoWrite` items:\n\n1. `stack-mode:membership-resolved`\n2. `stack-mode:iteration-complete`\n3. `stack-mode:root-summary-posted`\n\n## Step 1: Resolve Stack Membership (`membership-resolved`)\n\nGiven a starting PR number `$PR_NUM` and optional base\n`$BASE` (default: `master`), try three strategies in\norder and stop at the first that yields a stack of size\n>= 2.\n\n### Strategy A: Branch-name convention (cheapest)\n\n```bash\nSTART_HEAD=$(gh pr view \"$PR_NUM\" \\\n  --json headRefName -q .headRefName)\n\n# stack/<feature-name>/<slice-name>\nif [[ \"$START_HEAD\" =~ ^stack/([^/]+)/.+$ ]]; then\n  FEATURE=\"${BASH_REMATCH[1]}\"\n  PREFIX=\"stack/${FEATURE}/\"\n\n  # All local branches with the same prefix\n  STACK_BRANCHES=$(git branch --list \"${PREFIX}*\" \\\n    | sed 's/^[* ]*//' | sort)\n\n  # Map branches -> PR numbers (skip branches with no PR)\n  STACK_PRS=()\n  for branch in $STACK_BRANCHES; do\n    pr=$(gh pr list --head \"$branch\" \\\n      --json number --jq '.[0].number')\n    [ -n \"$pr\" ] && STACK_PRS+=(\"$pr\")\n  done\n\n  echo \"strategy=A prs=${STACK_PRS[*]}\"\nfi\n```\n\n### Strategy B: Stack summary comment (most reliable)\n\n`stack-push` posts a `## Stack` markdown table on the\nroot PR with columns `# | Branch | PR`. Parse it:\n\n```bash\n# Find the root PR of the stack containing $PR_NUM\n# The current PR may be the root, or may link to it via\n# a \"Part of stack `stack/<feature>`\" phrase in its body\nBODY=$(gh pr view \"$PR_NUM\" --json body -q .body)\n\n# Look for a \"## Stack\" table in THIS PR's comments\nTABLE=$(gh pr view \"$PR_NUM\" --json comments \\\n  --jq '.comments[] | select(.body | contains(\"## Stack\"))\n        | .body' | head -1)\n\n# If not on this PR, look for the root PR reference\nif [ -z \"$TABLE\" ]; then\n  ROOT_REF=$(echo \"$BODY\" \\\n    | grep -oE 'stack/[^ `]+' | head -1)\n  # ... resolve ROOT_REF -> root PR number and re-fetch\nfi\n\n# Parse the table: extract all `#<num>` from the PR column\nSTACK_PRS=($(echo \"$TABLE\" \\\n  | grep -oE '#[0-9]+' | tr -d '#' | sort -un))\n\necho \"strategy=B prs=${STACK_PRS[*]}\"\n```\n\n### Strategy C: Base-chain walk (fallback)\n\nWalk both directions from `$PR_NUM`:\n\n- Up: repeatedly resolve `baseRefName` until it equals\n  `$BASE`. Each visited head is a stack member.\n- Down: find open PRs whose `baseRefName` equals one of\n  the visited heads. Recurse.\n\n```bash\n# Ascend from $PR_NUM to the root\nCUR=$PR_NUM\nCHAIN=($CUR)\nwhile true; do\n  BASE_REF=$(gh pr view \"$CUR\" \\\n    --json baseRefName -q .baseRefName)\n  [ \"$BASE_REF\" = \"$BASE\" ] && break\n\n  PARENT=$(gh pr list --head \"$BASE_REF\" \\\n    --state open --json number --jq '.[0].number')\n  [ -z \"$PARENT\" ] && break\n\n  CHAIN=(\"$PARENT\" \"${CHAIN[@]}\")\n  CUR=$PARENT\ndone\n\n# Descend from the root collecting children\nROOT=${CHAIN[0]}\nFRONTIER=(\"$ROOT\")\nwhile [ ${#FRONTIER[@]} -gt 0 ]; do\n  PARENT=${FRONTIER[0]}\n  FRONTIER=(\"${FRONTIER[@]:1}\")\n\n  PARENT_HEAD=$(gh pr view \"$PARENT\" \\\n    --json headRefName -q .headRefName)\n\n  CHILDREN=($(gh pr list --base \"$PARENT_HEAD\" \\\n    --state open --json number --jq '.[].number'))\n\n  for c in \"${CHILDREN[@]}\"; do\n    CHAIN+=(\"$c\")\n    FRONTIER+=(\"$c\")\n  done\ndone\n\nSTACK_PRS=(\"${CHAIN[@]}\")\necho \"strategy=C prs=${STACK_PRS[*]}\"\n```\n\n### Ordering\n\nRegardless of strategy, order the final list **base-to-tip**\n(root PR first, leaf PR last). The root is the PR whose\n`baseRefName` equals `$BASE`.\n\n```bash\nROOT_PR=\"\"\nfor p in \"${STACK_PRS[@]}\"; do\n  base=$(gh pr view \"$p\" --json baseRefName -q .baseRefName)\n  if [ \"$base\" = \"$BASE\" ]; then\n    ROOT_PR=$p\n    break\n  fi\ndone\n```\n\nIf the stack size is 1, the command MUST fall back to\nsingle-PR mode and emit a warning: `stack-mode: only one\nPR found; --stack has no effect, proceeding as single-PR`.\n\n### GitLab / Bitbucket\n\nSee `Skill(leyline:git-platform)` for `glab` / Bitbucket\nequivalents of the `gh` calls above. The three strategies\ntranslate directly: GitLab MR dependencies replace\nbase-chain walks, and the `glab mr view --output json`\nshape matches `gh pr view`.\n\n## Step 2: Confirm With User (if not explicit)\n\nWhen the caller did NOT pass `--stack` but Step 1 resolved\na stack of size >= 2, print the stack and ask:\n\n```\nDetected stack of N PRs rooted at #<root>:\n  1. #<root>   <title>\n  2. #<p2>     <title>\n  ...\n\nRun the workflow on the full stack? [y/N]\n```\n\nDefault to \"N\" (single-PR mode). With `--stack` explicit,\nskip this prompt.\n\n## Step 3: Iterate (`iteration-complete`)\n\nRun the caller's main workflow once per PR in base-to-tip\norder:\n\n```bash\nFAILED_PRS=()\nfor p in \"${STACK_PRS[@]}\"; do\n  echo \"=== stack-mode: PR #$p ($(($idx+1))/${#STACK_PRS[@]}) ===\"\n\n  # Caller hook: run the single-PR workflow on $p\n  # This includes Gate 1 (thread resolution) and\n  # Gate 2 (issue tracking) per the caller's contract.\n  if ! run_single_pr_workflow \"$p\"; then\n    FAILED_PRS+=(\"$p\")\n    # Stop iteration: downstream PRs may now be stale\n    break\n  fi\ndone\n```\n\nIf any PR fails, the command MUST stop and report\n`stack-mode: halted at #<pr>; downstream PRs untouched`.\nDownstream PRs are intentionally left alone because\ntheir context may have shifted.\n\n## Step 4: Post Stack Summary on Root (`root-summary-posted`)\n\nAfter successful iteration, post ONE consolidated summary\ncomment on the root PR. This does NOT replace per-PR\nsummaries: it links them together.\n\n```markdown\n## Stack <Command Name> Summary\n\n**Stack**: N PRs rooted at #<root>, base `<base-branch>`\n**Command**: <command> (e.g., /fix-pr, /pr-review)\n**Run**: <timestamp>\n\n| # | PR | Branch | Status | Per-PR Summary |\n|---|----|--------|--------|----------------|\n| 1 | #<root> | `stack/<feat>/<root-slice>` | <done/skipped/failed> | [link to comment] |\n| 2 | #<p2>   | `stack/<feat>/<slice-2>`    | <done/skipped/failed> | [link to comment] |\n| ... | ... | ... | ... | ... |\n\n### Cross-PR Notes\n\n- <Any observations that spanned multiple PRs>\n- <Issues created that reference multiple stack PRs>\n- <Base-PR-merged cascade reminders, if any>\n\n### Next Steps\n\n- If root PR merges, run `Skill(sanctum:stack-rebase)` to\n  cascade the base update through descendants.\n- Reviewers: rebase-triggered stale-review flags on\n  descendants are expected after any force-push.\n```\n\nPost via `gh pr comment \"$ROOT_PR\" --body-file <file>`.\n\n## Failure Modes and Recovery\n\n| Failure | Detection | Recovery |\n|---------|-----------|----------|\n| Stack of size 1 | Step 1 returns one PR | Emit warning, fall back to single-PR mode |\n| Base chain loops | Visited set on ascent | Halt, report `stack-mode: cycle detected` |\n| Mid-stack PR failed its Gates | Caller raises | Halt iteration, leave downstream untouched |\n| Strategy B table malformed | Parse fails | Fall through to Strategy C |\n| Auth scope insufficient | `gh` returns 403 | Halt with clear error; caller surfaces to user |\n\n## Notes\n\n- Stack mode is ADDITIVE: single-PR behavior is unchanged.\n  Only the iteration and root summary are new.\n- Per-PR Gate 1 (thread resolution) and Gate 2 (issue\n  tracking) remain unchanged: each PR still passes its\n  own gates independently.\n- Never merge Gate 1 across the stack. A resolved thread\n  on one PR is not a resolved thread on another.\n- The root summary is idempotent: re-running stack mode\n  should update (not duplicate) the summary comment.\n  Match on `## Stack <Command Name> Summary` as the key.\n- `stack-mode` is a read/orchestration skill; it does NOT\n  push, rebase, or edit branches. Those concerns are in\n  `stack-create`, `stack-push`, and `stack-rebase`.\n\nFile v1.9.13:_meta.json\n\n{\n  \"ownerId\": \"kn7d107jg9jv602h9ytsegydq184a42s\",\n  \"slug\": \"nm-sanctum-stack-mode\",\n  \"version\": \"1.9.13\",\n  \"publishedAt\": 1782577408230\n}\n\nFile v1.9.13:skill-card.md\n\n## Description: <br>\nDetects shared stack membership and iterates a command across all PRs in base-to-tip order. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[athola](https://clawhub.ai/user/athola) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and agent-command authors use this skill to make commands operate across a stack of dependent pull requests, resolving stack membership, iterating each PR in base-to-tip order, and producing a consolidated root summary. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Broad trigger terms may cause the skill to be used during an ordinary single-PR review conversation. <br>\nMitigation: Use explicit --stack intent for multi-PR iteration and fall back to the normal single-PR workflow when stack mode is not intended. <br>\nRisk: The workflow reads pull request metadata and can post a consolidated stack summary through the GitHub CLI. <br>\nMitigation: Confirm the target repository, GitHub CLI authorization, and generated summary before allowing the comment to be posted. <br>\nRisk: A failed PR in the middle of a stack can leave downstream PR context stale. <br>\nMitigation: Halt iteration at the failed PR and leave downstream PRs untouched until the failure is resolved. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill listing](https://clawhub.ai/athola/skills/nm-sanctum-stack-mode) <br>\n- [Configured homepage](https://github.com/athola/claude-night-market/tree/master/plugins/sanctum) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Guidance, Shell commands, Markdown, Configuration] <br>\n**Output Format:** [Markdown with inline bash code blocks] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Guides callers to resolve PR stacks, iterate workflows, and post one consolidated root summary comment.] <br>\n\n## Skill Version(s): <br>\n1.9.13 (source: server release metadata) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v1.9.12: 3 files, 5784 bytes\n\nFiles: skill-card.md (1946b), SKILL.md (9786b), _meta.json (141b)\n\nFile v1.9.12:SKILL.md\n\n---\nname: stack-mode\ndescription: |\n  Detects shared stack membership and iterates a command across all PRs in base-to-tip order\nversion: 1.9.8\ntriggers:\n  - git\n  - stacked-diffs\n  - pr\n  - review\n  - fix-pr\n  - iteration\n  - a command supports --stack flag for multi-PR iteration\nmetadata: {\"openclaw\": {\"homepage\": \"https://github.com/athola/claude-night-market/tree/master/plugins/sanctum\", \"emoji\": \"\\u2699\\ufe0f\", \"requires\": {\"config\": [\"night-market.sanctum:stack-create\", \"night-market.sanctum:stack-push\", \"night-market.sanctum:stack-rebase\", \"night-market.leyline:git-platform\"]}}}\nsource: claude-night-market\nsource_plugin: sanctum\n---\n\n> **Night Market Skill** — ported from [claude-night-market/sanctum](https://github.com/athola/claude-night-market/tree/master/plugins/sanctum). For the full experience with agents, hooks, and commands, install the Claude Code plugin.\n\n\n# Stack Mode\n\nShared contract for commands that need to operate across a\nwhole stack of dependent PRs in one invocation.\nUsed by `/pr-review --stack` and `/fix-pr --stack`.\n\nThe goal is one simple thing: when a PR is part of a stack\ntargeting a common base branch, loop the command's normal\nworkflow across every PR in the stack in base-to-tip order\nand emit one consolidated summary on the stack root.\n\n## When to Use\n\nLoad this skill when a command accepts a `--stack` flag\n(or auto-detects stack membership) and needs to iterate\nits normal workflow across multiple PRs.\n\nDo NOT load this skill for single-PR workflows. The\nper-PR workflow stays unchanged; stack mode wraps it.\n\n## Contract\n\nA calling command MUST:\n\n1. Accept a `--stack` boolean flag AND a `--base <branch>`\n   override (default: `master`).\n2. Call Step 1 below to resolve stack membership BEFORE\n   running its main workflow.\n3. Run its main workflow per PR in the resolved order.\n4. Emit per-PR outputs unchanged (thread replies, issue\n   links, etc.).\n5. Emit ONE stack-level summary comment on the root PR\n   using the format in Step 4.\n6. Respect per-PR Gate rules (every PR still needs its own\n   thread resolution and issue tracking).\n\nA calling command MAY:\n\n- Auto-detect stack membership and prompt the user rather\n  than requiring `--stack` explicitly.\n- Short-circuit iteration when a per-PR failure leaves\n  downstream PRs with stale context.\n\n## Required Progress Tracking\n\nThe caller creates `TodoWrite` items:\n\n1. `stack-mode:membership-resolved`\n2. `stack-mode:iteration-complete`\n3. `stack-mode:root-summary-posted`\n\n## Step 1: Resolve Stack Membership (`membership-resolved`)\n\nGiven a starting PR number `$PR_NUM` and optional base\n`$BASE` (default: `master`), try three strategies in\norder and stop at the first that yields a stack of size\n>= 2.\n\n### Strategy A: Branch-name convention (cheapest)\n\n```bash\nSTART_HEAD=$(gh pr view \"$PR_NUM\" \\\n  --json headRefName -q .headRefName)\n\n# stack/<feature-name>/<slice-name>\nif [[ \"$START_HEAD\" =~ ^stack/([^/]+)/.+$ ]]; then\n  FEATURE=\"${BASH_REMATCH[1]}\"\n  PREFIX=\"stack/${FEATURE}/\"\n\n  # All local branches with the same prefix\n  STACK_BRANCHES=$(git branch --list \"${PREFIX}*\" \\\n    | sed 's/^[* ]*//' | sort)\n\n  # Map branches -> PR numbers (skip branches with no PR)\n  STACK_PRS=()\n  for branch in $STACK_BRANCHES; do\n    pr=$(gh pr list --head \"$branch\" \\\n      --json number --jq '.[0].number')\n    [ -n \"$pr\" ] && STACK_PRS+=(\"$pr\")\n  done\n\n  echo \"strategy=A prs=${STACK_PRS[*]}\"\nfi\n```\n\n### Strategy B: Stack summary comment (most reliable)\n\n`stack-push` posts a `## Stack` markdown table on the\nroot PR with columns `# | Branch | PR`. Parse it:\n\n```bash\n# Find the root PR of the stack containing $PR_NUM\n# The current PR may be the root, or may link to it via\n# a \"Part of stack `stack/<feature>`\" phrase in its body\nBODY=$(gh pr view \"$PR_NUM\" --json body -q .body)\n\n# Look for a \"## Stack\" table in THIS PR's comments\nTABLE=$(gh pr view \"$PR_NUM\" --json comments \\\n  --jq '.comments[] | select(.body | contains(\"## Stack\"))\n        | .body' | head -1)\n\n# If not on this PR, look for the root PR reference\nif [ -z \"$TABLE\" ]; then\n  ROOT_REF=$(echo \"$BODY\" \\\n    | grep -oE 'stack/[^ `]+' | head -1)\n  # ... resolve ROOT_REF -> root PR number and re-fetch\nfi\n\n# Parse the table: extract all `#<num>` from the PR column\nSTACK_PRS=($(echo \"$TABLE\" \\\n  | grep -oE '#[0-9]+' | tr -d '#' | sort -un))\n\necho \"strategy=B prs=${STACK_PRS[*]}\"\n```\n\n### Strategy C: Base-chain walk (fallback)\n\nWalk both directions from `$PR_NUM`:\n\n- Up: repeatedly resolve `baseRefName` until it equals\n  `$BASE`. Each visited head is a stack member.\n- Down: find open PRs whose `baseRefName` equals one of\n  the visited heads. Recurse.\n\n```bash\n# Ascend from $PR_NUM to the root\nCUR=$PR_NUM\nCHAIN=($CUR)\nwhile true; do\n  BASE_REF=$(gh pr view \"$CUR\" \\\n    --json baseRefName -q .baseRefName)\n  [ \"$BASE_REF\" = \"$BASE\" ] && break\n\n  PARENT=$(gh pr list --head \"$BASE_REF\" \\\n    --state open --json number --jq '.[0].number')\n  [ -z \"$PARENT\" ] && break\n\n  CHAIN=(\"$PARENT\" \"${CHAIN[@]}\")\n  CUR=$PARENT\ndone\n\n# Descend from the root collecting children\nROOT=${CHAIN[0]}\nFRONTIER=(\"$ROOT\")\nwhile [ ${#FRONTIER[@]} -gt 0 ]; do\n  PARENT=${FRONTIER[0]}\n  FRONTIER=(\"${FRONTIER[@]:1}\")\n\n  PARENT_HEAD=$(gh pr view \"$PARENT\" \\\n    --json headRefName -q .headRefName)\n\n  CHILDREN=($(gh pr list --base \"$PARENT_HEAD\" \\\n    --state open --json number --jq '.[].number'))\n\n  for c in \"${CHILDREN[@]}\"; do\n    CHAIN+=(\"$c\")\n    FRONTIER+=(\"$c\")\n  done\ndone\n\nSTACK_PRS=(\"${CHAIN[@]}\")\necho \"strategy=C prs=${STACK_PRS[*]}\"\n```\n\n### Ordering\n\nRegardless of strategy, order the final list **base-to-tip**\n(root PR first, leaf PR last). The root is the PR whose\n`baseRefName` equals `$BASE`.\n\n```bash\nROOT_PR=\"\"\nfor p in \"${STACK_PRS[@]}\"; do\n  base=$(gh pr view \"$p\" --json baseRefName -q .baseRefName)\n  if [ \"$base\" = \"$BASE\" ]; then\n    ROOT_PR=$p\n    break\n  fi\ndone\n```\n\nIf the stack size is 1, the command MUST fall back to\nsingle-PR mode and emit a warning: `stack-mode: only one\nPR found; --stack has no effect, proceeding as single-PR`.\n\n### GitLab / Bitbucket\n\nSee `Skill(leyline:git-platform)` for `glab` / Bitbucket\nequivalents of the `gh` calls above. The three strategies\ntranslate directly: GitLab MR dependencies replace\nbase-chain walks, and the `glab mr view --output json`\nshape matches `gh pr view`.\n\n## Step 2: Confirm With User (if not explicit)\n\nWhen the caller did NOT pass `--stack` but Step 1 resolved\na stack of size >= 2, print the stack and ask:\n\n```\nDetected stack of N PRs rooted at #<root>:\n  1. #<root>   <title>\n  2. #<p2>     <title>\n  ...\n\nRun the workflow on the full stack? [y/N]\n```\n\nDefault to \"N\" (single-PR mode). With `--stack` explicit,\nskip this prompt.\n\n## Step 3: Iterate (`iteration-complete`)\n\nRun the caller's main workflow once per PR in base-to-tip\norder:\n\n```bash\nFAILED_PRS=()\nfor p in \"${STACK_PRS[@]}\"; do\n  echo \"=== stack-mode: PR #$p ($(($idx+1))/${#STACK_PRS[@]}) ===\"\n\n  # Caller hook: run the single-PR workflow on $p\n  # This includes Gate 1 (thread resolution) and\n  # Gate 2 (issue tracking) per the caller's contract.\n  if ! run_single_pr_workflow \"$p\"; then\n    FAILED_PRS+=(\"$p\")\n    # Stop iteration: downstream PRs may now be stale\n    break\n  fi\ndone\n```\n\nIf any PR fails, the command MUST stop and report\n`stack-mode: halted at #<pr>; downstream PRs untouched`.\nDownstream PRs are intentionally left alone because\ntheir context may have shifted.\n\n## Step 4: Post Stack Summary on Root (`root-summary-posted`)\n\nAfter successful iteration, post ONE consolidated summary\ncomment on the root PR. This does NOT replace per-PR\nsummaries: it links them together.\n\n```markdown\n## Stack <Command Name> Summary\n\n**Stack**: N PRs rooted at #<root>, base `<base-branch>`\n**Command**: <command> (e.g., /fix-pr, /pr-review)\n**Run**: <timestamp>\n\n| # | PR | Branch | Status | Per-PR Summary |\n|---|----|--------|--------|----------------|\n| 1 | #<root> | `stack/<feat>/<root-slice>` | <done/skipped/failed> | [link to comment] |\n| 2 | #<p2>   | `stack/<feat>/<slice-2>`    | <done/skipped/failed> | [link to comment] |\n| ... | ... | ... | ... | ... |\n\n### Cross-PR Notes\n\n- <Any observations that spanned multiple PRs>\n- <Issues created that reference multiple stack PRs>\n- <Base-PR-merged cascade reminders, if any>\n\n### Next Steps\n\n- If root PR merges, run `Skill(sanctum:stack-rebase)` to\n  cascade the base update through descendants.\n- Reviewers: rebase-triggered stale-review flags on\n  descendants are expected after any force-push.\n```\n\nPost via `gh pr comment \"$ROOT_PR\" --body-file <file>`.\n\n## Failure Modes and Recovery\n\n| Failure | Detection | Recovery |\n|---------|-----------|----------|\n| Stack of size 1 | Step 1 returns one PR | Emit warning, fall back to single-PR mode |\n| Base chain loops | Visited set on ascent | Halt, report `stack-mode: cycle detected` |\n| Mid-stack PR failed its Gates | Caller raises | Halt iteration, leave downstream untouched |\n| Strategy B table malformed | Parse fails | Fall through to Strategy C |\n| Auth scope insufficient | `gh` returns 403 | Halt with clear error; caller surfaces to user |\n\n## Notes\n\n- Stack mode is ADDITIVE: single-PR behavior is unchanged.\n  Only the iteration and root summary are new.\n- Per-PR Gate 1 (thread resolution) and Gate 2 (issue\n  tracking) remain unchanged: each PR still passes its\n  own gates independently.\n- Never merge Gate 1 across the stack. A resolved thread\n  on one PR is not a resolved thread on another.\n- The root summary is idempotent: re-running stack mode\n  should update (not duplicate) the summary comment.\n  Match on `## Stack <Command Name> Summary` as the key.\n- `stack-mode` is a read/orchestration skill; it does NOT\n  push, rebase, or edit branches. Those concerns are in\n  `stack-create`, `stack-push`, and `stack-rebase`.\n\nFile v1.9.12:_meta.json\n\n{\n  \"ownerId\": \"kn7d107jg9jv602h9ytsegydq184a42s\",\n  \"slug\": \"nm-sanctum-stack-mode\",\n  \"version\": \"1.9.12\",\n  \"publishedAt\": 1781839134126\n}\n\nFile v1.9.12:skill-card.md\n\n## Description: <br>\nDetects shared stack membership and guides a command through all related PRs in base-to-tip order. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[athola](https://clawhub.ai/user/athola) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and maintainers use this skill when a review or fix workflow needs to run across a stack of dependent pull requests while preserving each PR's normal gates and outputs. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can guide GitHub CLI actions such as comments, labels, proof publishing, and closures. <br>\nMitigation: Review any proposed GitHub action before approving it, as recommended by the server security guidance. <br>\nRisk: A stack-wide workflow can carry stale context into downstream PRs after a mid-stack failure. <br>\nMitigation: Stop iteration on the failing PR and leave downstream PRs untouched until the failure is resolved. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/athola/nm-sanctum-stack-mode) <br>\n- [Sanctum plugin homepage](https://github.com/athola/claude-night-market/tree/master/plugins/sanctum) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [guidance, shell commands, markdown] <br>\n**Output Format:** [Markdown guidance with bash command examples and a stack summary comment template] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Requires the caller to review proposed GitHub CLI actions before execution.] <br>\n\n## Skill Version(s): <br>\n1.9.12 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v1.0.0: 3 files, 5879 bytes\n\nFiles: skill-card.md (2164b), SKILL.md (9786b), _meta.json (140b)\n\nFile v1.0.0:SKILL.md\n\n---\nname: stack-mode\ndescription: |\n  Detects shared stack membership and iterates a command across all PRs in base-to-tip order\nversion: 1.9.8\ntriggers:\n  - git\n  - stacked-diffs\n  - pr\n  - review\n  - fix-pr\n  - iteration\n  - a command supports --stack flag for multi-PR iteration\nmetadata: {\"openclaw\": {\"homepage\": \"https://github.com/athola/claude-night-market/tree/master/plugins/sanctum\", \"emoji\": \"\\u2699\\ufe0f\", \"requires\": {\"config\": [\"night-market.sanctum:stack-create\", \"night-market.sanctum:stack-push\", \"night-market.sanctum:stack-rebase\", \"night-market.leyline:git-platform\"]}}}\nsource: claude-night-market\nsource_plugin: sanctum\n---\n\n> **Night Market Skill** — ported from [claude-night-market/sanctum](https://github.com/athola/claude-night-market/tree/master/plugins/sanctum). For the full experience with agents, hooks, and commands, install the Claude Code plugin.\n\n\n# Stack Mode\n\nShared contract for commands that need to operate across a\nwhole stack of dependent PRs in one invocation.\nUsed by `/pr-review --stack` and `/fix-pr --stack`.\n\nThe goal is one simple thing: when a PR is part of a stack\ntargeting a common base branch, loop the command's normal\nworkflow across every PR in the stack in base-to-tip order\nand emit one consolidated summary on the stack root.\n\n## When to Use\n\nLoad this skill when a command accepts a `--stack` flag\n(or auto-detects stack membership) and needs to iterate\nits normal workflow across multiple PRs.\n\nDo NOT load this skill for single-PR workflows. The\nper-PR workflow stays unchanged; stack mode wraps it.\n\n## Contract\n\nA calling command MUST:\n\n1. Accept a `--stack` boolean flag AND a `--base <branch>`\n   override (default: `master`).\n2. Call Step 1 below to resolve stack membership BEFORE\n   running its main workflow.\n3. Run its main workflow per PR in the resolved order.\n4. Emit per-PR outputs unchanged (thread replies, issue\n   links, etc.).\n5. Emit ONE stack-level summary comment on the root PR\n   using the format in Step 4.\n6. Respect per-PR Gate rules (every PR still needs its own\n   thread resolution and issue tracking).\n\nA calling command MAY:\n\n- Auto-detect stack membership and prompt the user rather\n  than requiring `--stack` explicitly.\n- Short-circuit iteration when a per-PR failure leaves\n  downstream PRs with stale context.\n\n## Required Progress Tracking\n\nThe caller creates `TodoWrite` items:\n\n1. `stack-mode:membership-resolved`\n2. `stack-mode:iteration-complete`\n3. `stack-mode:root-summary-posted`\n\n## Step 1: Resolve Stack Membership (`membership-resolved`)\n\nGiven a starting PR number `$PR_NUM` and optional base\n`$BASE` (default: `master`), try three strategies in\norder and stop at the first that yields a stack of size\n>= 2.\n\n### Strategy A: Branch-name convention (cheapest)\n\n```bash\nSTART_HEAD=$(gh pr view \"$PR_NUM\" \\\n  --json headRefName -q .headRefName)\n\n# stack/<feature-name>/<slice-name>\nif [[ \"$START_HEAD\" =~ ^stack/([^/]+)/.+$ ]]; then\n  FEATURE=\"${BASH_REMATCH[1]}\"\n  PREFIX=\"stack/${FEATURE}/\"\n\n  # All local branches with the same prefix\n  STACK_BRANCHES=$(git branch --list \"${PREFIX}*\" \\\n    | sed 's/^[* ]*//' | sort)\n\n  # Map branches -> PR numbers (skip branches with no PR)\n  STACK_PRS=()\n  for branch in $STACK_BRANCHES; do\n    pr=$(gh pr list --head \"$branch\" \\\n      --json number --jq '.[0].number')\n    [ -n \"$pr\" ] && STACK_PRS+=(\"$pr\")\n  done\n\n  echo \"strategy=A prs=${STACK_PRS[*]}\"\nfi\n```\n\n### Strategy B: Stack summary comment (most reliable)\n\n`stack-push` posts a `## Stack` markdown table on the\nroot PR with columns `# | Branch | PR`. Parse it:\n\n```bash\n# Find the root PR of the stack containing $PR_NUM\n# The current PR may be the root, or may link to it via\n# a \"Part of stack `stack/<feature>`\" phrase in its body\nBODY=$(gh pr view \"$PR_NUM\" --json body -q .body)\n\n# Look for a \"## Stack\" table in THIS PR's comments\nTABLE=$(gh pr view \"$PR_NUM\" --json comments \\\n  --jq '.comments[] | select(.body | contains(\"## Stack\"))\n        | .body' | head -1)\n\n# If not on this PR, look for the root PR reference\nif [ -z \"$TABLE\" ]; then\n  ROOT_REF=$(echo \"$BODY\" \\\n    | grep -oE 'stack/[^ `]+' | head -1)\n  # ... resolve ROOT_REF -> root PR number and re-fetch\nfi\n\n# Parse the table: extract all `#<num>` from the PR column\nSTACK_PRS=($(echo \"$TABLE\" \\\n  | grep -oE '#[0-9]+' | tr -d '#' | sort -un))\n\necho \"strategy=B prs=${STACK_PRS[*]}\"\n```\n\n### Strategy C: Base-chain walk (fallback)\n\nWalk both directions from `$PR_NUM`:\n\n- Up: repeatedly resolve `baseRefName` until it equals\n  `$BASE`. Each visited head is a stack member.\n- Down: find open PRs whose `baseRefName` equals one of\n  the visited heads. Recurse.\n\n```bash\n# Ascend from $PR_NUM to the root\nCUR=$PR_NUM\nCHAIN=($CUR)\nwhile true; do\n  BASE_REF=$(gh pr view \"$CUR\" \\\n    --json baseRefName -q .baseRefName)\n  [ \"$BASE_REF\" = \"$BASE\" ] && break\n\n  PARENT=$(gh pr list --head \"$BASE_REF\" \\\n    --state open --json number --jq '.[0].number')\n  [ -z \"$PARENT\" ] && break\n\n  CHAIN=(\"$PARENT\" \"${CHAIN[@]}\")\n  CUR=$PARENT\ndone\n\n# Descend from the root collecting children\nROOT=${CHAIN[0]}\nFRONTIER=(\"$ROOT\")\nwhile [ ${#FRONTIER[@]} -gt 0 ]; do\n  PARENT=${FRONTIER[0]}\n  FRONTIER=(\"${FRONTIER[@]:1}\")\n\n  PARENT_HEAD=$(gh pr view \"$PARENT\" \\\n    --json headRefName -q .headRefName)\n\n  CHILDREN=($(gh pr list --base \"$PARENT_HEAD\" \\\n    --state open --json number --jq '.[].number'))\n\n  for c in \"${CHILDREN[@]}\"; do\n    CHAIN+=(\"$c\")\n    FRONTIER+=(\"$c\")\n  done\ndone\n\nSTACK_PRS=(\"${CHAIN[@]}\")\necho \"strategy=C prs=${STACK_PRS[*]}\"\n```\n\n### Ordering\n\nRegardless of strategy, order the final list **base-to-tip**\n(root PR first, leaf PR last). The root is the PR whose\n`baseRefName` equals `$BASE`.\n\n```bash\nROOT_PR=\"\"\nfor p in \"${STACK_PRS[@]}\"; do\n  base=$(gh pr view \"$p\" --json baseRefName -q .baseRefName)\n  if [ \"$base\" = \"$BASE\" ]; then\n    ROOT_PR=$p\n    break\n  fi\ndone\n```\n\nIf the stack size is 1, the command MUST fall back to\nsingle-PR mode and emit a warning: `stack-mode: only one\nPR found; --stack has no effect, proceeding as single-PR`.\n\n### GitLab / Bitbucket\n\nSee `Skill(leyline:git-platform)` for `glab` / Bitbucket\nequivalents of the `gh` calls above. The three strategies\ntranslate directly: GitLab MR dependencies replace\nbase-chain walks, and the `glab mr view --output json`\nshape matches `gh pr view`.\n\n## Step 2: Confirm With User (if not explicit)\n\nWhen the caller did NOT pass `--stack` but Step 1 resolved\na stack of size >= 2, print the stack and ask:\n\n```\nDetected stack of N PRs rooted at #<root>:\n  1. #<root>   <title>\n  2. #<p2>     <title>\n  ...\n\nRun the workflow on the full stack? [y/N]\n```\n\nDefault to \"N\" (single-PR mode). With `--stack` explicit,\nskip this prompt.\n\n## Step 3: Iterate (`iteration-complete`)\n\nRun the caller's main workflow once per PR in base-to-tip\norder:\n\n```bash\nFAILED_PRS=()\nfor p in \"${STACK_PRS[@]}\"; do\n  echo \"=== stack-mode: PR #$p ($(($idx+1))/${#STACK_PRS[@]}) ===\"\n\n  # Caller hook: run the single-PR workflow on $p\n  # This includes Gate 1 (thread resolution) and\n  # Gate 2 (issue tracking) per the caller's contract.\n  if ! run_single_pr_workflow \"$p\"; then\n    FAILED_PRS+=(\"$p\")\n    # Stop iteration: downstream PRs may now be stale\n    break\n  fi\ndone\n```\n\nIf any PR fails, the command MUST stop and report\n`stack-mode: halted at #<pr>; downstream PRs untouched`.\nDownstream PRs are intentionally left alone because\ntheir context may have shifted.\n\n## Step 4: Post Stack Summary on Root (`root-summary-posted`)\n\nAfter successful iteration, post ONE consolidated summary\ncomment on the root PR. This does NOT replace per-PR\nsummaries: it links them together.\n\n```markdown\n## Stack <Command Name> Summary\n\n**Stack**: N PRs rooted at #<root>, base `<base-branch>`\n**Command**: <command> (e.g., /fix-pr, /pr-review)\n**Run**: <timestamp>\n\n| # | PR | Branch | Status | Per-PR Summary |\n|---|----|--------|--------|----------------|\n| 1 | #<root> | `stack/<feat>/<root-slice>` | <done/skipped/failed> | [link to comment] |\n| 2 | #<p2>   | `stack/<feat>/<slice-2>`    | <done/skipped/failed> | [link to comment] |\n| ... | ... | ... | ... | ... |\n\n### Cross-PR Notes\n\n- <Any observations that spanned multiple PRs>\n- <Issues created that reference multiple stack PRs>\n- <Base-PR-merged cascade reminders, if any>\n\n### Next Steps\n\n- If root PR merges, run `Skill(sanctum:stack-rebase)` to\n  cascade the base update through descendants.\n- Reviewers: rebase-triggered stale-review flags on\n  descendants are expected after any force-push.\n```\n\nPost via `gh pr comment \"$ROOT_PR\" --body-file <file>`.\n\n## Failure Modes and Recovery\n\n| Failure | Detection | Recovery |\n|---------|-----------|----------|\n| Stack of size 1 | Step 1 returns one PR | Emit warning, fall back to single-PR mode |\n| Base chain loops | Visited set on ascent | Halt, report `stack-mode: cycle detected` |\n| Mid-stack PR failed its Gates | Caller raises | Halt iteration, leave downstream untouched |\n| Strategy B table malformed | Parse fails | Fall through to Strategy C |\n| Auth scope insufficient | `gh` returns 403 | Halt with clear error; caller surfaces to user |\n\n## Notes\n\n- Stack mode is ADDITIVE: single-PR behavior is unchanged.\n  Only the iteration and root summary are new.\n- Per-PR Gate 1 (thread resolution) and Gate 2 (issue\n  tracking) remain unchanged: each PR still passes its\n  own gates independently.\n- Never merge Gate 1 across the stack. A resolved thread\n  on one PR is not a resolved thread on another.\n- The root summary is idempotent: re-running stack mode\n  should update (not duplicate) the summary comment.\n  Match on `## Stack <Command Name> Summary` as the key.\n- `stack-mode` is a read/orchestration skill; it does NOT\n  push, rebase, or edit branches. Those concerns are in\n  `stack-create`, `stack-push`, and `stack-rebase`.\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn7d107jg9jv602h9ytsegydq184a42s\",\n  \"slug\": \"nm-sanctum-stack-mode\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1781796046099\n}\n\nFile v1.0.0:skill-card.md\n\n## Description: <br>\nDetects shared stack membership and iterates a command across all PRs in base-to-tip order. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[athola](https://clawhub.ai/user/athola) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and maintainers use this skill to wrap PR review or fix workflows so an agent can discover a dependent PR stack, run a command across each PR from base to tip, and post one root-level summary while preserving per-PR gates. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Available GitHub credentials may allow the agent to comment on PRs or perform other repository actions beyond the user's intent. <br>\nMitigation: Install only for intended maintainer workflows, scope GitHub credentials to the minimum required permissions, and review generated PR comments or repository actions before allowing them to run. <br>\nRisk: A failed mid-stack workflow can leave downstream PRs with stale context. <br>\nMitigation: Follow the skill's halt-on-failure behavior, leave downstream PRs untouched after a failure, and review the root summary before continuing stack work. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill listing](https://clawhub.ai/athola/nm-sanctum-stack-mode) <br>\n- [Metadata homepage](https://github.com/athola/claude-night-market/tree/master/plugins/sanctum) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Guidance, Markdown, Shell commands, Configuration] <br>\n**Output Format:** [Markdown with inline bash and markdown code blocks] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Coordinates multi-PR workflows in base-to-tip order and preserves per-PR outputs.] <br>\n\n## Skill Version(s): <br>\n1.0.0 (source: ClawHub release metadata; artifact frontmatter: 1.9.8) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>","readmeExcerpt":"Skill: stack-mode Owner: athola Summary: Detects shared stack membership and iterates a command across all PRs in base-to-tip order Tags: latest:1.9.19 Version history: v1.9.19 | 2026-08-26T13:20:53.932Z | user Release v1.9.19 v1.9.17 | 2026-07-30T05:40:55.800Z | user Release v1.9.17 v1.9.16 | 2026-07-14T19:57:46.945Z | user Release v1.9.16 v1.9.14 | 2026-06-30T18:05:36.342Z | user Release v1.9.14 v1.9.13 | 2026-06-2","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"START_HEAD=$(gh pr view \"$PR_NUM\" \\\n  --json headRefName -q .headRefName)\n\n# stack/<feature-name>/<slice-name>\nif [[ \"$START_HEAD\" =~ ^stack/([^/]+)/.+$ ]]; then\n  FEATURE=\"${BASH_REMATCH[1]}\"\n  PREFIX=\"stack/${FEATURE}/\"\n\n  # All local branches with the same prefix\n  STACK_BRANCHES=$(git branch --list \"${PREFIX}*\" \\\n    | sed 's/^[* ]*//' | sort)\n\n  # Map branches -> PR numbers (skip branches with no PR)\n  STACK_PRS=()\n  for branch in $STACK_BRANCHES; do\n    pr=$(gh pr list --head \"$branch\" \\\n      --json number --jq '.[0].number')\n    [ -n \"$pr\" ] && STACK_PRS+=(\"$pr\")\n  done\n\n  echo \"strategy=A prs=${STACK_PRS[*]}\"\nfi"},{"language":"bash","snippet":"# Find the root PR of the stack containing $PR_NUM\n# The current PR may be the root, or may link to it via\n# a \"Part of stack `stack/<feature>`\" phrase in its body\nBODY=$(gh pr view \"$PR_NUM\" --json body -q .body)\n\n# Look for a \"## Stack\" table in THIS PR's comments\nTABLE=$(gh pr view \"$PR_NUM\" --json comments \\\n  --jq '.comments[] | select(.body | contains(\"## Stack\"))\n        | .body' | head -1)\n\n# If not on this PR, look for the root PR reference\nif [ -z \"$TABLE\" ]; then\n  ROOT_REF=$(echo \"$BODY\" \\\n    | grep -oE 'stack/[^ `]+' | head -1)\n  # ... resolve ROOT_REF -> root PR number and re-fetch\nfi\n\n# Parse the table: extract all `#<num>` from the PR column\nSTACK_PRS=($(echo \"$TABLE\" \\\n  | grep -oE '#[0-9]+' | tr -d '#' | sort -un))\n\necho \"strategy=B prs=${STACK_PRS[*]}\""},{"language":"bash","snippet":"# Ascend from $PR_NUM to the root\nCUR=$PR_NUM\nCHAIN=($CUR)\nwhile true; do\n  BASE_REF=$(gh pr view \"$CUR\" \\\n    --json baseRefName -q .baseRefName)\n  [ \"$BASE_REF\" = \"$BASE\" ] && break\n\n  PARENT=$(gh pr list --head \"$BASE_REF\" \\\n    --state open --json number --jq '.[0].number')\n  [ -z \"$PARENT\" ] && break\n\n  CHAIN=(\"$PARENT\" \"${CHAIN[@]}\")\n  CUR=$PARENT\ndone\n\n# Descend from the root collecting children\nROOT=${CHAIN[0]}\nFRONTIER=(\"$ROOT\")\nwhile [ ${#FRONTIER[@]} -gt 0 ]; do\n  PARENT=${FRONTIER[0]}\n  FRONTIER=(\"${FRONTIER[@]:1}\")\n\n  PARENT_HEAD=$(gh pr view \"$PARENT\" \\\n    --json headRefName -q .headRefName)\n\n  CHILDREN=($(gh pr list --base \"$PARENT_HEAD\" \\\n    --state open --json number --jq '.[].number'))\n\n  for c in \"${CHILDREN[@]}\"; do\n    CHAIN+=(\"$c\")\n    FRONTIER+=(\"$c\")\n  done\ndone\n\nSTACK_PRS=(\"${CHAIN[@]}\")\necho \"strategy=C prs=${STACK_PRS[*]}\""},{"language":"bash","snippet":"ROOT_PR=\"\"\nfor p in \"${STACK_PRS[@]}\"; do\n  base=$(gh pr view \"$p\" --json baseRefName -q .baseRefName)\n  if [ \"$base\" = \"$BASE\" ]; then\n    ROOT_PR=$p\n    break\n  fi\ndone"},{"language":"text","snippet":"Detected stack of N PRs rooted at #<root>:\n  1. #<root>   <title>\n  2. #<p2>     <title>\n  ...\n\nRun the workflow on the full stack? [y/N]"},{"language":"bash","snippet":"FAILED_PRS=()\nfor p in \"${STACK_PRS[@]}\"; do\n  echo \"=== stack-mode: PR #$p ($(($idx+1))/${#STACK_PRS[@]}) ===\"\n\n  # Caller hook: run the single-PR workflow on $p\n  # This includes Gate 1 (thread resolution) and\n  # Gate 2 (issue tracking) per the caller's contract.\n  if ! run_single_pr_workflow \"$p\"; then\n    FAILED_PRS+=(\"$p\")\n    # Stop iteration: downstream PRs may now be stale\n    break\n  fi\ndone"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: stack-mode\ndescription: |\n  Detects shared stack membership and iterates a command across all PRs in base-to-tip order\nversion: 1.9.8\ntriggers:\n  - git\n  - stacked-diffs\n  - pr\n  - review\n  - fix-pr\n  - iteration\n  - a command supports --stack flag for multi-PR iteration\nmetadata: {\"openclaw\": {\"homepage\": \"https://github.com/athola/claude-night-market/tree/master/plugins/sanctum\", \"emoji\": \"\\u2699\\ufe0f\", \"requires\": {\"config\": [\"night-market.sanctum:stack-create\", \"night-market.sanctum:stack-push\", \"night-market.sanctum:stack-rebase\", \"night-market.leyline:git-platform\"]}}}\nsource: claude-night-market\nsource_plugin: sanctum\n---\n\n> **Night Market Skill** — ported from [claude-night-market/sanctum](https://github.com/athola/claude-night-market/tree/master/plugins/sanctum). For the full experience with agents, hooks, and commands, install the Claude Code plugin.\n\n\n# Stack Mode\n\nShared contract for commands that need to operate across a\nwhole stack of dependent PRs in one invocation.\nUsed by `/pr-review --stack` and `/fix-pr --stack`.\n\nThe goal is one simple thing: when a PR is part of a stack\ntargeting a common base branch, loop the command's normal\nworkflow across every PR in the stack in base-to-tip order\nand emit one consolidated summary on the stack root.\n\n## When to Use\n\nLoad this skill when a command accepts a `--stack` flag\n(or auto-detects stack membership) and needs to iterate\nits normal workflow across multiple PRs.\n\nDo NOT load this skill for single-PR workflows. The\nper-PR workflow stays unchanged; stack mode wraps it.\n\n## Contract\n\nA calling command MUST:\n\n1. Accept a `--stack` boolean flag AND a `--base <branch>`\n   override (default: `master`).\n2. Call Step 1 below to resolve stack membership BEFORE\n   running its main workflow.\n3. Run its main workflow per PR in the resolved order.\n4. Emit per-PR outputs unchanged (thread replies, issue\n   links, etc.).\n5. Emit ONE stack-level summary comment on the root PR\n   using the format in Step 4.\n6. Respect per-PR Gate rules (every PR still needs its own\n   thread resolution and issue tracking).\n\nA calling command MAY:\n\n- Auto-detect stack membership and prompt the user rather\n  than requiring `--stack` explicitly.\n- Short-circuit iteration when a per-PR failure leaves\n  downstream PRs with stale context.\n\n## Required Progress Tracking\n\nThe caller creates `TodoWrite` items:\n\n1. `stack-mode:membership-resolved`\n2. `stack-mode:iteration-complete`\n3. `stack-mode:root-summary-posted`\n\n## Step 1: Resolve Stack Membership (`membership-resolved`)\n\nGiven a starting PR number `$PR_NUM` and optional base\n`$BASE` (default: `master`), try three strategies in\norder and stop at the first that yields a stack of size\n>= 2.\n\n### Strategy A: Branch-name convention (cheapest)\n\n```bash\nSTART_HEAD=$(gh pr view \"$PR_NUM\" \\\n  --json headRefName -q .headRefName)\n\n# stack/<feature-name>/<slice-name>\nif [[ \"$START_HEAD\" =~ ^stack/([^/]+)/.+$ ]]; then\n  FEATURE=\"${BASH_REMATCH[1]}\"\n  PREFIX=\"stack/${FEATURE"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7d107jg9jv602h9ytsegydq184a42s\",\n  \"slug\": \"nm-sanctum-stack-mode\",\n  \"version\": \"1.9.19\",\n  \"publishedAt\": 1787750453932\n}"},{"path":"skill-card.md","content":"## Description:\n\nDetects shared stack membership and iterates a command across all PRs in base-to-tip order.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[athola](https://clawhub.ai/user/athola)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and engineers use this skill to run stack-aware pull request review or fix workflows across dependent PRs while preserving per-PR handling and producing a consolidated root summary.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Broad pull request and review triggers may activate this workflow in cases where stack iteration is not intended.\n\nMitigation: Use explicit stack workflows where possible and confirm stack membership before running multi-PR actions.\n\nRisk: Stack mode can post or update a consolidated comment on the root pull request.\n\nMitigation: Verify the GitHub CLI account has only the repository permissions intended before using the skill.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/athola/skills/nm-sanctum-stack-mode)\n- [clawdis homepage](https://github.com/athola/claude-night-market/tree/master/plugins/sanctum)\n\n## Skill Output:\n\n**Output Type(s):** [guidance, shell commands, markdown, configuration]\n\n**Output Format:** [Markdown guidance with shell command examples and summary comment templates]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Guides calling commands to resolve stack membership, iterate base-to-tip, and post one consolidated root PR summary.]\n\n## Skill Version(s):\n\n1.9.19 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Detects shared stack membership and iterates a command across all PRs in base-to-tip order Skill: stack-mode Owner: athola Summary: Detects shared stack membership and iterates a command across all PRs in base-to-tip order Tags: latest:1.9.19 Version history: v1.9.19 | 2026-08-26T13:20:53.932Z | user Release v1.9.19 v1.9.17 | 2026-07-30T05:40:55.800Z | user Release v1.9.17 v1.9.16 | 2026-07-14T19:57:46.945Z | user Release v1.9.16 v1.9.14 | 2026-06-30T18:05:36.342Z | user Release v1.9.14 v1.9.13 | 2026-06-2","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1170,"uniquenessScore":49,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T20:16:19.511Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T20:16:19.511Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-12T21:32:12.147Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}