Install
$ agentstack add skill-gustavo-meilus-superpipelines-sk-pipeline-paths ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Pipeline Path Resolver — Scope-Aware Layout
The single tier-independent base directory (/.superpipelines/ or ~/.superpipelines/) where all generated pipeline DATA is persisted (RESOLVE_DATA_ROOT). A per-tier base directory (.claude/, .opencode/, …) resolved by RESOLVE_SCOPE_ROOT. No longer the artifact location — used only for read-only legacy back-compat and as the native materialization target. A central registry.json file tracking all pipelines within a specific scope. A temporary temp/{P}/edit-{ts}/ directory used for atomic mutations.
Data Root & Git Integration
Generated pipelines (v2.x+) are data under the single tier-independent data root (RESOLVE_DATA_ROOT); the per-tier scope roots below are legacy/materialization only.
| Scope | Physical Root | Git Status | Persistence | | :--- | :--- | :--- | :--- | | Project | /.superpipelines/ | Committed | Shared with the team. | | Local | /.superpipelines/ | Ignored | Machine-specific/temporary. | | User | ~/.superpipelines/ | External | Global across all workspaces. |
project and local scopes share the same physical directory; the distinction is managed via .gitignore entries for .superpipelines/.
Per-Tier Scope Roots (legacy back-compat reads + native materialization target)
These per-tier roots no longer locate generated pipeline data (see Data Root above). They are consumed only by (a) ENUMERATE_ALL_SCOPE_ROOTS read-only legacy back-compat and (b) sk-platform-dispatch MATERIALIZE, which writes the ephemeral native agent file into the host's own dir.
| Tier | Workspace root | User root | | :--- | :--- | :--- | | Tier 1 (CC) | /.claude/ | ~/.claude/ | | Tier 1b (OC) | /.opencode/ | ~/.opencode/ | | Tier 1c (Antigravity) | /.agents/antigravity/ | ~/.antigravity/ | | Tier 1d (Codex) | /.codex/ | ~/.codex/ | | Tier 2 (Cursor/Windsurf/Cline) | /.superpipelines/ | ~/.superpipelines/ |
Tier 1c uses a sub-namespaced .agents/antigravity/ path to avoid silent collisions on .agents/. Tier 1d uses Codex-native .codex/ so materialized agent TOMLs land under Codex discovery paths.
RESOLVESCOPEROOT(scope, tier): base = per-tier table above [tier] [scope-bucket] return absolute_path(base)
RESOLVEDATAROOT(scope): // Data-only pipelines (v2.x+): the single artifact root for ALL generated // pipeline DATA. Tier-INDEPENDENT — NOT the tier-1 scope root, a sibling of it. // Only dispatch + model resolution remain tier-specific (design spec §4). if scope in {project, local}: return RESOLVEHOSTWORKSPACE() + "/.superpipelines" if scope == user: return expand("~/.superpipelines")
RESOLVEHOSTWORKSPACE(): // The main-worktree root, NOT a linked worktree's cwd. Artifacts and state // MUST anchor here so they survive worktree teardown (issue #31). common = git rev-parse --path-format=absolute --git-common-dir // → /.git if command succeeds: return dirname(strip_trailing("/.git", common)) else (not a git repo): return cwd
// INVARIANT: the superpipelines/temp/{P}/{runId}/ artifact + state tree ALWAYS // resolves under RESOLVEHOSTWORKSPACE(), never a linked worktree path. Code // edits stay isolated in the worktree; coordination artifacts land on the host.
// LEGACY back-compat only. Data-only pipelines store paths relative to DATAROOT // (tier-independent), so PORTABILITYREWRITE is a no-op for them and retires for paths // (design spec §4). It still rewrites old-root (pre-v2) cross-tier paths. PORTABILITYREWRITE(artifactpath, sourcetier, targettier): if sourcetier == targettier: return artifactpath if sourcetier == "data" OR targettier == "data": return artifactpath // data paths are tier-independent sourceroot = per-tier table[sourcetier][workspaceoruser] targetroot = per-tier table[targettier][workspaceoruser] return artifactpath.replace(sourceroot, target_root, count=1)
// Discovery & resume: DATA-ROOT FIRST, legacy multi-root as a self-gating back-compat // tail. The DEFAULT cost is two REGISTRY reads (workspace + user .superpipelines/); // the §4 "no per-tier loop" win is about registry enumeration — registries are read // (in running-a-pipeline Phase 0) ONLY for the roots returned here. The legacy tail is // a profile-driven dir_exists sweep that parses NO registries and returns [] on an // all-data workspace, so a workspace with only data-only pipelines reads exactly two // registries. Legacy back-compat (design spec §8) is preserved for any workspace that // still holds a pre-v2 old-root dir, with the per-tier dir names sourced from the // profiles (DEPENDENCYINVERSION: PROFILEDRIVEN) — never duplicated in this body. ENUMERATEPIPELINEROOTS(workspace) → [{tier, scope, root, layout}, ...]: roots = [] // (1) Data-only roots — canonical, tier-independent. Two dir checks, no per-tier loop. IF direxists(RESOLVEDATAROOT(project)): roots.append({tier: "data", scope: "workspace", root: RESOLVEDATAROOT(project), layout: "data"}) IF direxists(RESOLVEDATAROOT(user)): roots.append({tier: "data", scope: "user", root: RESOLVEDATAROOT(user), layout: "data"}) // (2) Legacy per-tier roots — read-only back-compat tail; ENUMERATEALLSCOPEROOTS // returns [] when no legacy root dir exists (the common all-data case), so this // adds no registry I/O and is its own gate. roots += ENUMERATEALLSCOPEROOTS(workspace) // each annotated layout: "legacy"; [] on all-data workspace return roots
// Legacy multi-root enumeration — RETAINED as the self-gating back-compat tail above. // Old-root pipelines (pre-v2) still list/resume via these 5 per-tier scope roots. Reads // the per-tier scope-root dir names from the profile JSONs (single source of truth) and // does dir_exists only — it parses NO registries, so on an all-data workspace it // returns [] cheaply (small profile reads + dir stats, no per-pipeline I/O). ENUMERATEALLSCOPEROOTS(workspace) → [{tier, scope, root, layout}, ...]: roots = [] FOR tier IN [tier1, tier1b, tier1c, tier1d, tier2]: profile = READ(skills/sk-platform-dispatch/profiles/{tier}.json) workspaceroot = workspace + "/" + profile.scoperoot.workspace userroot = expand(profile.scoperoot.user) // A legacy old-root pipeline lives under the scope root's superpipelines/ subdir // (path templates below). tier2's scope root IS the data root, so its legacy // old-root pipelines are the ones whose registry sits at /superpipelines/..., // distinct from the data-only /registry.json — no double-count. IF direxists(workspaceroot + "/superpipelines"): roots.append({tier, scope: "workspace", root: workspaceroot, layout: "legacy"}) IF direxists(userroot + "/superpipelines"): roots.append({tier, scope: "user", root: user_root, layout: "legacy"}) return roots
For data-only pipelines (v2.x+), artifact and state paths are tier-independent — they resolve under the single .superpipelines/ data root (RESOLVE_DATA_ROOT) regardless of runtime tier, so PORTABILITY_REWRITE is a no-op for paths and is not invoked at state-update sites. PORTABILITY_REWRITE survives only on the legacy back-compat path, where an old per-tier-rooted pipeline discovered via ENUMERATE_ALL_SCOPE_ROOTS is read/resumed on a different runtime tier; there it consults metadata.runtime_tier and stamps metadata.source_scope_root for audit.
Path Templates
Data-Only Path Templates (v2.x — relative to DATA_ROOT)
The canonical templates for new pipelines. DATA_ROOT = RESOLVE_DATA_ROOT(scope) (the .superpipelines/ root). Everything a pipeline needs — including the entry orchestration body and inline CAD operational protocols — is DATA here; nothing is written to a tool dir as source.
| Artifact Type | Path Template (relative to DATA_ROOT) | | :--- | :--- | | Registry | registry.json | | Spec/Plan/Tasks | pipelines/{P}/ | | Topology Graph | pipelines/{P}/topology.json | | Audit Report | pipelines/{P}/audit/latest.md | | Canonical Agent Def (CAD) | pipelines/{P}/agents/{agent-name}.md | | Optional Shared References | pipelines/{P}/references/{name}.md | | Entry (data) | pipelines/{P}/entry.md | | Run Command (data) | pipelines/{P}/{P}.md | | Pipeline State | temp/{P}/{runId}/pipeline-state.json | | Staged Edits | temp/{P}/edit-{ts}/ |
Materialized CC Agent (ephemeral cache — Option A dispatch): RESOLVE_SCOPE_ROOT(scope, tier_1) + "/agents/superpipelines/{P}/{agent-name}.md". Written by sk-platform-dispatch MATERIALIZE just before native dispatch, translated from the CAD; regenerated every run; never read as source; cleaned at Phase 4 completion. This is the one place generated content lands in a tool dir, and it is disposable cache, not source.
Legacy Path Templates (READ-ONLY back-compat — old-root pipelines only)
Pipelines scaffolded before v2.x persist under per-tier scope roots ({ROOT} = RESOLVE_SCOPE_ROOT(scope, tier)). These templates are a read-only back-compat path for discovery and resume of existing pipelines — they are never a write target for new scaffolds (design spec §8: old-root writes removed immediately, old-root reads kept one major).
| Artifact Type | Path Template (relative to ROOT) | | :--- | :--- | | Registry | superpipelines/registry.json | | Spec/Plan/Tasks | superpipelines/pipelines/{P}/ | | Topology Graph | superpipelines/pipelines/{P}/topology.json | | Audit Report | superpipelines/pipelines/{P}/audit/latest.md | | Entry Skill | skills/superpipelines/{P}/run-{P}/SKILL.md | | Run Command | superpipelines/pipelines/{P}/{P}.md | | Step Skill | skills/superpipelines/{P}/{step}/SKILL.md | | Step Agent | agents/superpipelines/{P}/{agent-name}.md | | Pipeline State | superpipelines/temp/{P}/{runId}/pipeline-state.json | | Staged Edits | superpipelines/temp/{P}/edit-{ts}/ |
Pipeline Name Constraints
- Format: Lowercase alphanumeric and hyphens only (
[a-z0-9-]+). - Length: Maximum 48 characters to accommodate the
run-prefix within the 64-character skill limit. - Uniqueness within scope: Must be unique within the chosen scope's
registry.json. - Uniqueness across scopes: Same-name pipelines MAY exist in different scopes (e.g., a project-scope
deploy-featureand a user-scopedeploy-feature). Scaffolding-time uniqueness checks increating-a-pipelinePhase 1 MUST expand to all merged scopes and prompt the user to confirm when a same-name pipeline already exists elsewhere (no silent allow).
Collision Semantics
When discovery (ENUMERATE_PIPELINE_ROOTS, which merges the data roots with the gated legacy ENUMERATE_ALL_SCOPE_ROOTS tail) returns multiple registry entries with the same pipeline name across different scopes or tiers, the resolution contract is:
Precedence rule (highest wins):
workspace/project>workspace/local>user/global- Within the same scope-bucket,
runtime_tier> other tiers.
Disambiguation prompt: When two or more entries tie after applying precedence (e.g., same-name pipeline in both workspace/project tier_1 and workspace/project tier_2), the runner MUST present a disambiguated list and require explicit selection:
Multiple pipelines named `deploy-feature` found:
[1] project scope / tier_1 (.claude/) scaffolded 2026-04-10
[2] project scope / tier_2 (.superpipelines/) scaffolded 2026-05-12
Pick one: [1/2]
No silent first-wins. The slash-command form (/superpipelines:{P}, OC-only) follows the same precedence rule; OC's command resolver MUST honor it.
Registry Entry Schema
Each registry entry carries an explicit scope field to disambiguate project-vs-local entries that share the same physical .claude/ directory:
{
"name": "deploy-feature",
"scope": "project | local | user",
"source_tier": "tier_1 | tier_1b | tier_1c | tier_1d | tier_2",
"plugin_version": "2.0.0",
"...": "..."
}
The merge logic treats (name, scope, source_tier) as the composite identity key.
- NEVER hardcode absolute paths; always resolve via the current
{ROOT}and{P}context. - ALWAYS expand
~to the absolute home directory path before passing it to agent spawn prompts. - Atomic mutations MUST use the staged edits path before promotion to final locations.
Reference Files
sk-pipeline-state/SKILL.md— State persistence schema.sk-claude-code-conventions/SKILL.md— Frontmatter and directory rules.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: gustavo-meilus
- Source: gustavo-meilus/superpipelines
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.