Skip to content
cccskills
FreePublished on GitHub

gitlab-portfolio

Use when you need a single-pane cross-repo health view across all vault-registered GitLab and GitHub projects. Discovers repos from `_overview.md` frontmatter in `<vault>/01-projects/*/`, aggregates open issues, MRs, critical labels, and stale signals via parallel `glab`/`gh` calls, then writes an idempotent `_PORTFOLIO.md` dashboard. Runs automatically at session-start Phase 2 when `gitlab-portfolio.enabled=true`. Triggers: "show portfolio status", "refresh the portfolio dashboard", "which repos have critical issues", "run /portfolio". <example>Context: session-start, gitlab-portfolio.enabled=true, vault has 5 registered repos. user: "/session deep" assistant: "Portfolio: 3 critical issues across 2 repos — run /portfolio for details. Dashboard written to vault/01-projects/_PORTFOLIO.md."</example>

The English summary is being prepared. Showing the original description.

Kanevry/session-orchestrator52 stars(GitHub 52 + cccskills 0)
Works withGitHubGitLab

Run score Not tested

See how to install

Files included (1)

  • SKILL.md9.8 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

GitLab Portfolio Skill

Aggregates cross-repo health signals from vault-registered projects into a single _PORTFOLIO.md dashboard — idempotent, opt-in, and _generator-marked.

Soul

gitlab-portfolio gives you a single-pane view of your entire project portfolio. It iterates all vault-registered repositories, dispatches parallel CLI calls to glab / gh, and writes a structured Markdown dashboard at <vault-dir>/01-projects/_PORTFOLIO.md. The result is a living status snapshot — updated on demand or at session-start — that never overwrites hand-edited files.

When to use

  • You want a cross-repo issue/MR summary across many projects without opening each GitLab/GitHub UI.
  • Session-start should surface a portfolio health banner (critical open issues, stale repos).
  • A nightly routine should refresh the dashboard automatically via /portfolio.
  • You need --dry-run preview before committing a refresh to the vault.

When NOT to use

  • Bidirectional sync (writing issues back to GitLab/GitHub) — use gitlab-ops for write operations.
  • Single-repo deep-dives — use /discovery or direct glab commands.
  • Projects not registered in the vault (_overview.md or .vault.yaml) — unregistered repos are silently skipped.
  • Replacing a hand-authored _PORTFOLIO.md — the _generator guard prevents overwriting human content.

Phase 1: Discovery

Implementation: scripts/lib/gitlab-portfolio/aggregator.mjs — discoverRepos().

Iterates <vault-dir>/01-projects/*/ subdirectories:

  1. Primary — Read _overview.md YAML frontmatter. Look for gitlab: <namespace/repo> and/or github: <owner/repo>. Both keys may be present on a single repo.
  2. Fallback — If _overview.md is absent or missing those keys, read .vault.yaml at the project root: spec.links.gitlab / spec.links.github.
  3. Skip — Directories with neither source are silently skipped.

Output is an array of RepoDescriptor objects: { slug, gitlab, github }.

Phase 2: Aggregation

Implementation: scripts/lib/gitlab-portfolio/aggregator.mjs — aggregateAll(repos, config).

All repos are fetched in parallel via Promise.allSettled. Per-repo CLI dispatch:

# GitLab
glab issue list --repo <namespace/repo> --state opened --output json
glab mr list   --repo <namespace/repo> --state opened --output json

# GitHub
gh issue list --repo <owner/repo> --state open --json number,title,labels,createdAt,updatedAt,milestone
gh pr list    --repo <owner/repo> --state open --json number,title,labels,createdAt,updatedAt

Per-repo summary fields derived from JSON output:

FieldDerivation
openIssues / openMRsarray lengths
criticalissues where any label matches critical-labels (case-insensitive)
staleissues where updatedAt older than stale-days days
nextMilestoneearliest non-null milestone.title across open issues
lastActivitymax updatedAt across all issues + MRs
topIssuesfirst 3 open issues sorted by createdAt ascending (oldest open first)

On CLI failure per repo: behaviour is controlled by mode (see Error Handling).

Phase 3: Output

Implementation: scripts/lib/gitlab-portfolio/markdown-writer.mjs — renderDashboard(summaries, config).

Output path: <vault-dir>/01-projects/_PORTFOLIO.md. Frontmatter keys: _generator: session-orchestrator-gitlab-portfolio@1, created (ISO8601, set once), updated (ISO8601, refreshed each write), repos (count). Atomic write: content built in memory, committed via a single writeFileSync.

Phase 4: Idempotency

parseFrontmatter and emitAction imported from scripts/lib/vault-mirror/utils.mjs. Rules:

  1. No file → created.
  2. File exists, _generator absent or differs → skipped-handwritten (never overwrite human content).
  3. File exists, generator matches, updated ≤ fresh data → updated.
  4. File exists, generator matches, updated > fresh data → skipped-noop.

Stdout action shape: {"action":"updated","path":"01-projects/_PORTFOLIO.md","repos":16,"critical":3}

Config

Opt-in via the gitlab-portfolio: block in Session Config (CLAUDE.md / AGENTS.md):

gitlab-portfolio:
  enabled: true
  mode: warn          # warn | strict | off
  stale-days: 30
  critical-labels: ["priority::critical", "priority::high"]
FieldDefaultMeaning
enabledfalseMaster switch.
modewarnwarn / strict / off — failure handling; off ≡ disabled.
stale-days30Issues older than N days are flagged stale.
critical-labels["priority::critical","priority::high"]Label substrings that classify an issue as critical (case-insensitive).

Security

--vault-dir validation (SEC, GH #44). The --vault-dir CLI argument and vault-integration.vault-dir Session Config value are validated against the user's home directory via validatePathInsideProject (scripts/lib/path-utils.mjs). Both phases apply:

  • Lexical: paths containing .. traversal that resolve outside os.homedir() are rejected (exit 2).
  • Symlink: paths whose real-path (after symlink resolution) escapes os.homedir() are rejected (exit 2).

Configure vault-integration.vault-dir only with user-controlled paths under ~. The same guard applies to the implicit Phase 2.7 portfolio snapshot at session-start. Reference: CWE-22 path traversal · .claude/rules/security.md SEC-014 adjacent guidance.

Note: vault-dir must be a CHILD of ~ (the home directory), not ~ itself. The guard uses strict isPathInside semantics, which require a proper descendant path.

CLI

node scripts/lib/gitlab-portfolio/aggregator.mjs \
  --vault-dir ~/Projects/vault \
  [--dry-run]
FlagRequiredDescription
--vault-diryesAbsolute path to Meta-Vault root. Must exist.
--dry-runnoRun discovery + aggregation; print diff to stdout; do not write the dashboard.

Exit codes: 0 success · 1 bad args/config · 2 vault-dir not found or write failed · 3 repo fetch failures in strict mode.

Hook

When gitlab-portfolio.enabled: true and vault-integration.enabled: true, session-start Phase 2 invokes the aggregator in parallel with ecosystem-health. The hook always runs in warn mode — session-start must not block on non-fatal failures. On critical issues found, a banner is emitted:

🔴 Portfolio: 3 critical issues across 2 repos — run /portfolio for details

Output format

---
_generator: session-orchestrator-gitlab-portfolio@1
created: 2026-05-16T08:00:00Z
updated: 2026-05-16T08:00:00Z
repos: 2
---

# Portfolio Dashboard

> Generated: 2026-05-16 08:00 UTC · 2 repos · 1 critical · 0 stale

## Summary

| Repo | Open Issues | Open MRs | Critical | Stale | Last Activity |
|---|---|---|---|---|---|
| session-orchestrator | 9 | 2 | 1 | 0 | 2026-05-16 |
| my-saas-app          | 4 | 1 | 0 | 0 | 2026-05-15 |

## session-orchestrator

**gitlab:** `kanevry/session-orchestrator` · Open: 9 issues / 2 MRs · Critical: 1 · Next milestone: v3.7

| # | Title | Labels | Updated |
|---|---|---|---|
| #41 | gitlab-portfolio skill | enhancement | 2026-05-16 |
| #42 | session-end echo-stub | bug | 2026-05-14 |
| #35 | superpowers adoption | enhancement | 2026-05-10 |

## my-saas-app

**github:** `owner/my-saas-app` · Open: 4 issues / 1 PR · Critical: 0

Error handling

Behaviour is governed by mode. warn: emit warning to stderr, continue with partial data; repo rows show (fetch failed). strict: any repo fetch failure exits 2 after the scan. off: the CLI exits 0 with one line before resolving the vault-dir or scanning any repo, and writes nothing (#1619).

--vault-dir not found and write errors always exit 2 regardless of mode. _PORTFOLIO.md with no _generator key always results in skipped-handwritten (all modes). No repos discovered: exit 0 in every mode (no file written).

Anti-Patterns

  • Sequential glab calls — always use Promise.allSettled; sequential calls time out on large portfolios.
  • Writing without idempotency check — always inspect _generator before overwriting.
  • Hardcoding label strings — read critical-labels from config.
  • Blocking session-start on fetch failures — hook always runs in warn mode.
  • Overwriting created on refresh — created is set once; only updated changes.

Critical Rules

  • _generator: session-orchestrator-gitlab-portfolio@1 MUST appear in every file written by this skill.
  • Output path is always <vault-dir>/01-projects/_PORTFOLIO.md. No other path is valid.
  • Promise.allSettled is mandatory — one failing repo must never abort the entire run.
  • Atomic write: build full content in memory, then a single writeFileSync.
  • Implementation files: scripts/lib/gitlab-portfolio/aggregator.mjs (discovery + aggregation) · scripts/lib/gitlab-portfolio/markdown-writer.mjs (rendering + idempotency) · shared helpers from scripts/lib/vault-mirror/utils.mjs.

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Use when the user asks to improve architecture, find refactoring opportunities, surface deepening opportunities, consolidate tightly-coupled modules, or make a codebase more testable and AI-navigable. Surfaces shallow modules and hypothetical seams using a precise vocabulary (Module / Interface / Implementation / Depth / Seam / Adapter / Leverage / Locality from LANGUAGE.md).

The English summary is being prepared. Showing the original description.

Kanevry/session-orchestrator52Updated Oct 26, 2026

Use this skill when running an autonomous session-orchestration loop. Chains session-start → session-plan → wave-executor → session-end for N iterations with all 10 kill-switches (SPIRAL, FAILED wave, carryover > 50%, max-hours, max-sessions, resource-overload, token-budget, stall-timeout, sub-threshold confidence, user-abort). Reads Mode-Selector output (Phase B) to decide auto-execute vs. fallback. Writes one autopilot.jsonl record per loop run. Phase C scaffold (issue #277); implementation lives in scripts/lib/autopilot.mjs (Phase C-1 follow-up).

The English summary is being prepared. Showing the original description.

Kanevry/session-orchestrator52Updated Oct 26, 2026

Use this skill when scaffolding the minimum repository structure required by session-orchestrator. Invoked automatically by the Bootstrap Gate when CLAUDE.md, Session Config, or bootstrap.lock is missing. Also available as /bootstrap for manual invocation. Three intensity tiers: fast (demos/spikes), standard (MVPs), deep (production/team).

The English summary is being prepared. Showing the original description.

Kanevry/session-orchestrator52Updated Oct 26, 2026

Use when you have a feature idea but the scope or UX is still ambiguous — runs a lightweight Socratic design dialogue (3-5 AUQ rounds) and writes a spec markdown file. Use BEFORE /plan feature when product intent needs validation; skip to /plan feature when scope is already clear. HARD-GATE prevents any code work until the design is user-approved.

The English summary is being prepared. Showing the original description.

Kanevry/session-orchestrator52Updated Oct 26, 2026

Use when detecting drift between CLAUDE.md (or AGENTS.md, the Codex CLI alias) / _meta narrative and live repository state. Ten checks: absolute-path resolution, 01-projects/ count claims, issue-reference freshness, session-file existence, command-count sync, session-config-parity (mandatory template keys = error, opt-in gaps = note, unknown local keys = warning), vault-dir-parity (CLAUDE.md vs AGENTS.md), generated-rule-staleness (WARN-only), rule-scoping (paths:/globs: frontmatter defects, dangling rule citations, zero-match globs), and docs-parity (docs/components.md count-claims vs on-disk counts, template-vs-reference config-key parity, stale .claude/metrics/ paths). Full per-check spec in the body table. Invoked as an opt-in session-end phase; mirrors vault-sync's lean JSON+exit-code contract.

The English summary is being prepared. Showing the original description.

Kanevry/session-orchestrator52Updated Oct 26, 2026

close

Free

End session with verification, commits, and documentation

The English summary is being prepared. Showing the original description.

Kanevry/session-orchestrator52Updated Oct 26, 2026

See all skills by Kanevry

Report a problem with this skill