feat(cli): serve deployed Orbit skills
What does this MR do and why?
glab orbit skills now reads the skill from the GitLab instance. It checks and caches the remote files, merges them with the local skill, and keeps the embedded skill for offline or older instances.
Related Issues
Relates to #1063 (closed)
Testing
Passed mise build, mise lint:code, mise test:fast (2,633 passed, 2 skipped), mise test:cli (45 passed), and cargo nextest run -p orbit-cli --test skills_remote (18 passed) after rebasing onto main. Live cross-repository E2E passed at 2d60414f6, which is code-identical to 7a22f84bd; the only subsequent code change is the missing-ETag fallback. The Rails endpoint from gitlab-org/gitlab!256543 (merged) is merged and serving on GitLab.com.
Performance Analysis
One conditional request per read and one full download per new version. Cache reads verify the stored files; graph indexing and queries are unchanged.
- This merge request does not introduce any performance regression. If a performance regression is expected, explain why.
Agent context: implementation mechanics and verification
The CLI uses the complete glab-exported API/authentication tuple for this command, without invoking the credential helper in local-only mode. Collection and item requests reuse the remote HTTP client. It validates response identity, the "<version>" ETag, top-level frontmatter version and compatibility with the shared parser, normalized contained paths, unique files, and per-file SHA-256. It does not require or compute a whole-tree hash. Weak version ETags are accepted and normalized for conditional requests. server_version is deployment provenance, not cache identity.
Complete remote trees are staged, fsynced, and atomically published under an origin-isolated OS cache directory keyed by skill name and version. OS advisory locks release on process death without unlinking the lock inode; a cache write failure warns but still serves the validated download. The cached files remain byte-for-byte remote files; composition happens in memory. Two versions are retained per origin and skill. Version reuse with different content is not detectable through a 304 and is not treated as a content identity guarantee.
Runtime composition uses the shared marker parser: matching slots are replaced, remote-only slots dropped, local-only sections appended under ## Local CLI, and structural markers removed. Mock HTTP coverage includes list, get, 304, version-bump refresh, 404, offline and 5xx fallback, local-only mode, authentication failures, unsafe paths, host isolation, stale lock files, unavailable cache storage, weak and missing ETags, and concurrent cache writers.
Local mock HTTP tests cover list, get, 304 revalidation, cache refresh on version bump, and missing-ETag fallback. Live cross-repository E2E passed at 2d60414f6, which is code-identical to 7a22f84bd; only the missing-ETag fallback changed afterward. The Rails endpoint from gitlab-org/gitlab!256543 (merged) is merged and serving on GitLab.com.