Title: Issue · GitHub
Open Graph Title: Issue · EntityProcess/allagents
X Title: Issue · EntityProcess/allagents
Description: CLI tool for managing multi-repo AI agent workspaces with plugin synchronization across multiple AI clients. - Issue · EntityProcess/allagents
Open Graph Description: CLI tool for managing multi-repo AI agent workspaces with plugin synchronization across multiple AI clients. - Issue · EntityProcess/allagents
X Description: CLI tool for managing multi-repo AI agent workspaces with plugin synchronization across multiple AI clients. - Issue · EntityProcess/allagents
Opengraph URL: https://github.com/EntityProcess/allagents
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"feat: version pinning for skills and plugins (@version suffix and --pin flag)","articleBody":"\u003e **Priority:** high · Unlocks reproducible installs across team members and across agent sessions.\n\n## Problem\n\n\\`allagents\\` has no way to pin a skill or plugin to a specific Git ref. \\`src/utils/plugin-path.ts::parseGitHubUrl\\` recognizes \\`branch\\` (via \\`/tree/\u003cbranch\u003e\\` in a URL) but doesn't accept an \\`owner/repo@ref\\` shorthand, and \\`@\\` in install args is already taken by the marketplace shorthand (\\`my-plugin@official\\`). Consequences:\n\n- Two team members running \\`allagents update\\` on different days can get different skill bodies.\n- An agent running in CI cannot guarantee reproducible session-startup state.\n- There is no audit trail for which version of a skill a deployed agent was running.\n\nBy contrast \\`gh skill install\\` supports both inline \\`@v1.2.0\\` and \\`--pin \u003ctag-or-sha\u003e\\` (mutually exclusive). Implementation reference: \\`pkg/cmd/skills/install/install.go::parseSkillFromOpts\\` and \\`resolveVersion\\` in \\`cli/cli\\`.\n\n## Current behavior\n\n\\`\\`\\`bash\n$ allagents plugin install --help | grep -E 'pin|version|@'\n $ allagents plugin install my-plugin@official # @ means marketplace, NOT version\n $ allagents plugin install my-plugin@official --scope user\n\n# No --pin flag exists. Passing a tag-style @ref does not work:\n$ allagents plugin install owner/repo@v1.2.0\n# Treats v1.2.0 as a marketplace name and fails to resolve\n\n# workspace.yaml has no pin field; sync-state records no resolved ref:\n$ cat .allagents/sync-state.json\n{\n \\\"version\\\": 1,\n \\\"lastSync\\\": \\\"2026-05-12T10:54:56.311Z\\\",\n \\\"files\\\": { \\\"claude\\\": [] },\n \\\"mcpServers\\\": { \\\"claude\\\": [] }\n}\n\\`\\`\\`\n\n## Expected behavior\n\n\\`\\`\\`bash\n# Inline pin\n$ allagents skills add foo --from owner/repo@v1.2.0\n✓ Added foo from owner/repo (pinned to v1.2.0)\n\n# Explicit flag (equivalent)\n$ allagents skills add foo --from owner/repo --pin v1.2.0\n✓ Added foo from owner/repo (pinned to v1.2.0)\n\n# Inline + --pin → conflict\n$ allagents skills add foo --from owner/repo@v1.2.0 --pin abc1234\nError: cannot combine inline @version with --pin\n\n# workspace.yaml form\nplugins:\n - source: owner/repo\n pin: v1.2.0 # new optional field\n\n# sync-state.json records the resolved ref + SHA so subsequent updates can detect drift\n$ cat .allagents/sync-state.json | jq .sources\n{\n \\\"owner/repo\\\": {\n \\\"pluginSpec\\\": \\\"owner/repo\\\",\n \\\"resolvedRef\\\": \\\"v1.2.0\\\",\n \\\"resolvedSha\\\": \\\"abc1234...\\\",\n \\\"pinnedRef\\\": \\\"v1.2.0\\\"\n }\n}\n\\`\\`\\`\n\n## Verification gate (must pass before closing)\n\n\\`\\`\\`bash\nset -euo pipefail\n\nbun run build\nWS=\\$(mktemp -d)\ncd \\\"\\$WS\\\"\nallagents workspace init --client claude\n\n# (1) Inline @version is accepted (use any small public skills repo with a tagged release)\nallagents skills add brainstorming --from anthropics/superpowers@v0.1.0\ntest -d .agents/skills/brainstorming/\n\n# (2) --pin flag is accepted and equivalent\nrm -rf .agents\nallagents skills add brainstorming --from anthropics/superpowers --pin v0.1.0\ntest -d .agents/skills/brainstorming/\n\n# (3) Inline + --pin together is rejected\n! allagents skills add brainstorming --from anthropics/superpowers@v0.1.0 --pin v0.1.0\n\n# (4) Resolved ref is recorded in sync-state\njq -e '.sources[\\\"anthropics/superpowers\\\"].pinnedRef == \\\"v0.1.0\\\"' .allagents/sync-state.json\njq -e '.sources[\\\"anthropics/superpowers\\\"].resolvedSha | length \u003e= 7' .allagents/sync-state.json\n\n# (5) workspace.yaml round-trips a pin field\ncat \u003e .allagents/workspace.yaml \u003c\u003cYAML\nclients: [claude]\nplugins:\n - source: anthropics/superpowers\n pin: v0.1.0\nYAML\nallagents update\njq -e '.sources[\\\"anthropics/superpowers\\\"].pinnedRef == \\\"v0.1.0\\\"' .allagents/sync-state.json\n\ncd / \u0026\u0026 rm -rf \\\"\\$WS\\\"\n\\`\\`\\`\n\nAll five checks must pass. (Substitute the example repo/tag with a stable public alternative if needed; the integration test should use a known stable source.)\n\n## Implementation notes\n\n- \\`src/utils/plugin-path.ts::parseGitHubUrl\\`: extend to recognize \\`owner/repo@\u003cref\u003e\\` shorthand. Distinguish from \\`name@marketplace\\` by checking whether the left side looks like \\`owner/repo\\` (contains a slash) — \\`@\\` after a slash is a Git ref; \\`@\\` without a slash is a marketplace.\n- \\`src/cli/commands/plugin-skills.ts::addCmd\\`: add \\`--pin \u003cref\u003e\\` option. Validate mutual exclusivity with inline \\`@version\\` in the positional.\n- \\`src/cli/commands/plugin.ts::installCmd\\` (\\`plugin install\\`): same \\`--pin\\` flag.\n- \\`src/core/plugin.ts::fetchPlugin\\`: extend signature to accept \\`{ ref?: string }\\` and return the resolved ref + SHA. The shallow-clone path needs to clone the specific ref (or fetch + checkout).\n- \\`src/models/workspace-config.ts::PluginEntrySchema\\`: add an optional \\`pin: z.string().optional()\\` field to the object form.\n- \\`src/models/sync-state.ts::SyncStateSchema\\`: add an optional \\`sources\\` record keyed by plugin spec with \\`{ pluginSpec, resolvedRef, resolvedSha, pinnedRef? }\\`. Don't break the existing \\`files\\` field — additive only.\n- This issue partially overlaps with content-hash tracking; the \\`sources\\` block above is designed to be a strict subset of the schema proposed in the companion lockfile-hashes issue, so the two can land together cleanly.\n\n## Refs\n\n- Reference impl: \\`cli/cli\\` \\`pkg/cmd/skills/install/install.go::parseSkillFromOpts\\`, \\`resolveVersion\\`.\n- Companion wiki page: \\`concepts/allagents-vs-gh-skill.md\\` § \\\"Pinning vs declarative re-sync\\\".\n- Related issue: content-hash tracking in sync-state (filed separately).","author":{"url":"https://github.com/christso","@type":"Person","name":"christso"},"datePublished":"2026-05-12T10:56:28.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/372/allagents/issues/372"}
| route-pattern | /:user_id/:repository/issues/:id(.:format) |
| route-controller | issues |
| route-action | show |
| fetch-nonce | v2:23559c24-5d04-873e-816a-a97ff7dd5033 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 82E6:B72C9:10EAB0D:1747804:6A4DDEA3 |
| html-safe-nonce | fd2edc1a2003e0379c338d825ffbcdcb40012956f124b8586ae85a179042f8a9 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4MkU2OkI3MkM5OjEwRUFCMEQ6MTc0NzgwNDo2QTREREVBMyIsInZpc2l0b3JfaWQiOiI0NDY2ODk3NTQwMTc2Nzk3MzQ3IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | eb139d0d6a1b1bccca857446182fdde9c4686ad646d031c58389ff0835753cfe |
| hovercard-subject-tag | repository:1139437609 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/EntityProcess/allagents/issues/372 |
| twitter:image | https://opengraph.githubassets.com/d93aee447ffc8c95d776e838d2a9fef78c306b896e4ff86bc5f35b44fd4fcd43/EntityProcess/allagents |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/d93aee447ffc8c95d776e838d2a9fef78c306b896e4ff86bc5f35b44fd4fcd43/EntityProcess/allagents |
| og:image:alt | CLI tool for managing multi-repo AI agent workspaces with plugin synchronization across multiple AI clients. - Issue · EntityProcess/allagents |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | 06b8a6144231bf3a234f1c2e9993861e07ce98a905912b114aa386c2d7e84b33 |
| turbo-cache-control | no-cache |
| go-import | github.com/EntityProcess/allagents git https://github.com/EntityProcess/allagents.git |
| octolytics-dimension-user_id | 8837957 |
| octolytics-dimension-user_login | EntityProcess |
| octolytics-dimension-repository_id | 1139437609 |
| octolytics-dimension-repository_nwo | EntityProcess/allagents |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 1139437609 |
| octolytics-dimension-repository_network_root_nwo | EntityProcess/allagents |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 1d344bdb7547fe6bca17a59bb2b8aac3dc9532a0 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width