feat: repo_update tool (archive, description, visibility, template flag) #12

Closed
opened 2026-05-14 08:51:35 +00:00 by mathias · 1 comment
Owner

Summary

Add repo_update tool to modify repository metadata — most importantly the archived flag to mark repos as read-only without deleting them.

Gitea API

PATCH /api/v1/repos/{owner}/{repo}

Tool spec

tool: repo_update
params:
  owner:       string
  name:        string
  archived:    bool?    // mark repo as archived (read-only)
  description: string? // update description
  private:     bool?   // toggle visibility
  website:     string? // update homepage URL
  template:    bool?   // toggle template repo flag

Required token permission

write:repository scope on the Gitea API token.

Risk classification

MEDIUM — reversible (can unarchive), but visibility changes are significant. private: false should trigger ntfy confirmation.

Implementation notes

  • Only send fields that are explicitly set (use pointers)
  • Special case: private: false (making public) should warn in tool description
  • Test cases: archive, unarchive, description update, make template

Motivation

  1. ingestion-svc needed archiving — had to do README tombstone instead
  2. template-go-agent and template-go-web have template: false — should be true
  3. Future: hyperguild new-project will need to set description + template flag on newly created repos
## Summary Add `repo_update` tool to modify repository metadata — most importantly the `archived` flag to mark repos as read-only without deleting them. ## Gitea API `PATCH /api/v1/repos/{owner}/{repo}` ## Tool spec ``` tool: repo_update params: owner: string name: string archived: bool? // mark repo as archived (read-only) description: string? // update description private: bool? // toggle visibility website: string? // update homepage URL template: bool? // toggle template repo flag ``` ## Required token permission `write:repository` scope on the Gitea API token. ## Risk classification **MEDIUM** — reversible (can unarchive), but visibility changes are significant. `private: false` should trigger ntfy confirmation. ## Implementation notes - Only send fields that are explicitly set (use pointers) - Special case: `private: false` (making public) should warn in tool description - Test cases: archive, unarchive, description update, make template ## Motivation 1. `ingestion-svc` needed archiving — had to do README tombstone instead 2. `template-go-agent` and `template-go-web` have `template: false` — should be `true` 3. Future: `hyperguild new-project` will need to set description + template flag on newly created repos
Author
Owner

Review finding — missing fields (2026-05-14)

Code review of internal/tools/repo_update.go against the original spec revealed two gaps:

Gap 1 — archived and template fields missing (HIGH)

The original issue spec required:

archived:    bool?    // mark repo as archived (read-only)
template:    bool?    // toggle template repo flag

Current implementation only handles: description, private, website, default_branch.

Impact:

  • Cannot archive ingestion-svc (workaround: manual web UI)
  • Cannot set template: true on template-go-web and template-go-agent (blocks create_project_from_template working correctly)
  • Cannot toggle template flag as part of hyperguild new-project flow

Fix needed in internal/gitea/repos.goUpdateRepoArgs struct:

type UpdateRepoArgs struct {
    Description   *string
    Private       *bool
    Website       *string
    DefaultBranch *string
    Archived      *bool   // add this
    Template      *bool   // add this
}

And in internal/tools/repo_update.go input schema + repoUpdateArgs struct:

"archived": {"type": "boolean", "description": "Mark repo as archived (read-only)."},
"template": {"type": "boolean", "description": "Toggle template repo flag."}

Gap 2 — confirm guard missing for archived=true (LOW)

The confirm guard currently only protects private=false (making a repo public).
Archiving (archived=true) is effectively irreversible in practice and should require
the same confirm pattern:

if args.Archived != nil && *args.Archived {
    if args.Confirm != args.Name {
        return nil, fmt.Errorf("setting archived=true is irreversible: set confirm=%q to proceed", args.Name)
    }
}

Acceptance criteria additions

  • archived field added to UpdateRepoArgs, tool schema, and args struct
  • template field added to UpdateRepoArgs, tool schema, and args struct
  • archived=true requires confirm=<repo name>
  • Tests cover: set archived, set template, archived confirm guard
## Review finding — missing fields (2026-05-14) Code review of `internal/tools/repo_update.go` against the original spec revealed two gaps: ### Gap 1 — `archived` and `template` fields missing (HIGH) The original issue spec required: ``` archived: bool? // mark repo as archived (read-only) template: bool? // toggle template repo flag ``` Current implementation only handles: `description`, `private`, `website`, `default_branch`. **Impact:** - Cannot archive `ingestion-svc` (workaround: manual web UI) - Cannot set `template: true` on `template-go-web` and `template-go-agent` (blocks create_project_from_template working correctly) - Cannot toggle template flag as part of `hyperguild new-project` flow **Fix needed in `internal/gitea/repos.go` → `UpdateRepoArgs` struct:** ```go type UpdateRepoArgs struct { Description *string Private *bool Website *string DefaultBranch *string Archived *bool // add this Template *bool // add this } ``` And in `internal/tools/repo_update.go` input schema + `repoUpdateArgs` struct: ```json "archived": {"type": "boolean", "description": "Mark repo as archived (read-only)."}, "template": {"type": "boolean", "description": "Toggle template repo flag."} ``` ### Gap 2 — confirm guard missing for `archived=true` (LOW) The confirm guard currently only protects `private=false` (making a repo public). Archiving (`archived=true`) is effectively irreversible in practice and should require the same confirm pattern: ```go if args.Archived != nil && *args.Archived { if args.Confirm != args.Name { return nil, fmt.Errorf("setting archived=true is irreversible: set confirm=%q to proceed", args.Name) } } ``` ## Acceptance criteria additions - [ ] `archived` field added to `UpdateRepoArgs`, tool schema, and args struct - [ ] `template` field added to `UpdateRepoArgs`, tool schema, and args struct - [ ] `archived=true` requires `confirm=<repo name>` - [ ] Tests cover: set archived, set template, archived confirm guard
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mathias/gitea-mcp#12