Skip to content

[feat] Let teamai push --shared place a new resource at the shared root when roles/projects exist #1314

Closed

Description

@zxl199101-wq

Problem

A team that declares manifest/roles.yaml (or manifest/projects.yaml) can no longer publish a new team-wide resource at the shared root with teamai push.

namespaceCandidates() only returns { kind: 'shared-root' } when the candidate list is empty. Once roles exist:

This makes push disagree with pull: pull deliberately delivers root resources to everyone (#911, #1007), so the shared root is a first-class destination for pull but unreachable for push.

Concrete scenario

Team repo layout:

  • manifest/roles.yaml declares be, fe, client, qa
  • team-wide skills live at the root: skills/popo-im/, skills/km-ask/, skills/eagle-log-search/ (tag-filtered via tags.yaml)
  • role-specific skills live under skills/be/ (the Java audit suite)

Publishing a new team-wide skill (jira-assistant, a JIRA CLI assistant that is not backend-specific):

$ teamai push --skill <path>
✖ Several skills namespaces could take new skills (be, fe, client, qa), and there is no terminal to ask on. Pass --role <ns> to name one.

$ teamai push --skill <path> --role be
✔ pushed to skills/be/jira-assistant

The only way to reach the intended location was a manual git mv skills/be/jira-assistant skills/jira-assistant, a commit and a push. That works, but it bypasses push's placement bookkeeping (the placement record / pending-push state), so later edits of the local copy cannot be pushed back to the root path by teamai push, and nothing in the CLI hints this is the supported workflow.

Proposed solution

Add an explicit opt-in destination flag:

teamai push --skill <path> --shared     # also accept --root
  • Places the resource at the resource root: skills/<name>/, rules/<name>.md, agents/<name>.yaml, etc.
  • Mutually exclusive with --role / --project (exit 2 with a clear message if combined).
  • Also offer "shared root (all roles)" as an explicit choice in the interactive namespace prompt, keeping the current default selection unchanged.
  • Record the placement the same way [feat] Make all distributed resources pushable with project and role namespaces #1101 records namespaced placements, so a later edit of the root copy targets the root path again.

This keeps the "missing or ambiguous mappings fail instead of falling back to the shared root" rule intact: reaching the root becomes an explicit request, not a fallback.

Acceptance criteria

  • teamai push --skill <path> --shared writes skills/<name>/... to the push branch even when manifest/roles.yaml declares namespaces.
  • --shared combined with --role or --project exits 2 with a message naming the conflict.
  • The interactive namespace prompt includes the shared root as a selectable option; the default stays the previous behavior.
  • A subsequent edit of the delivered root copy is pushed back to the same root path (placement record), matching [feat] Make all distributed resources pushable with project and role namespaces #1101 behavior.
  • teamai review --branch does not flag intentionally shared-root items as undeclared namespaces.
  • Unit coverage in push-namespaces / push-role, plus an E2E case with a roles manifest and a new root skill.

Environment

  • teamai-cli 0.27.0 (latest published), macOS, provider: git
  • team repo with manifest/roles.yaml and tags.yaml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions