{"owner":"opencloud-eu","repo":"opencloud","hasSkills":true,"totalSkillsCount":14,"totalTokensCount":7206,"categories":["plugin-manifest","anthropic-skill"],"hasMcp":false,"mcpConfig":null,"found":["devtools/deployments/multi-tenancy/README.md","devtools/deployments/README.md",".agents/skills/bumping-web/SKILL.md",".agents/skills/bumping-reva/SKILL.md","vendor/github.com/go-micro/plugins/v4/client/grpc/README.md","devtools/deployments/opencloud_full/README.md","vendor/github.com/go-micro/plugins/v4/server/grpc/README.md","vendor/github.com/go-micro/plugins/v4/server/http/README.md","vendor/github.com/go-micro/plugins/v4/logger/zerolog/README.md","vendor/github.com/go-micro/plugins/v4/store/nats-js-kv/README.md","vendor/github.com/go-micro/plugins/v4/events/natsjs/README.md","vendor/github.com/go-micro/plugins/v4/store/nats-js/README.md","vendor/github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus/README.md","vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/README.md"],"skills":{"devtools/deployments/multi-tenancy/README.md":"# Development/Test Deployment for a multi-tenacy setup\n\nThe docker compose files in this directory are derived from the\nopencloud-compose project and can be used to deploy a Development or Testing\nenvironment for a multi-tenancy setup of OpenCloud. It consists of the\nfollowing services:\n\n* `provisioning`: The OpenCloud graph service deployed in a standalone mode. It\n  is configured to provide the libregraph education API for managing tenants\n  and users. The `ldap-server`service (see below) is used to store the tenants\n  and users.\n* `ldap-server`: An OpenLDAP server that is used by the provisioning service to\n  store tenants and users. Used by the OpenCloud services as the user directory\n  (for looking up users and searching for sharees).\n* `keycloak`: The OpenID Connect Provider used for authenticating users. The\n  pre-loaded realm is configured to add `tenantid` claim into the identity and\n  access tokens. It's also currently consuming user from the `ldap-server`\n  (this federation will likely go away in the future and is optional for future\n  configurations).\n* `opencloud`: The OpenCloud configured so that is hides users from different\n  tenants from each other.\n\nTo deploy the setup, run:\n\n```bash\ndocker compose -f docker-compose.yml -f keycloak.yml -f ldap-server.yml -f traefik.yml up\n```\n\nOnce deployed you can use the `initialize_users.go` to create a couple of example\ntenants and some users in each tenant:\n\n* Tenant `Famous Coders` with users `dennis` and `grace`\n* Tenant `Scientists` with users `einstein` and `marie`\n\nThe passwords for the users is set to `demo` in keycloak\n\n```\n> go run initialize_users.go\nCreated tenant: Famous Coders with id fc58e19a-3a2a-4afc-90ec-8f94986db340\nCreated user: Dennis Ritchie with id ee1e14e7-b00b-4eec-8b03-a6bf0e29c77c\nCreated user: Grace Hopper with id a29f3afd-e4a3-4552-91e8-cc99e26bffce\nCreated tenant: Scientists with id 18406c53-e2d6-4e83-98b6-a55880eef195\nCreated user: Albert Einstein with id 12023d37-d6ce-4f19-a318-b70866f265ba\nCreated user: Marie Curie with id 30c3c825-c37d-4e85-8195-0142e4884872\nSetting password for user: grace\nSetting password for user: marie\nSetting password for user: dennis\nSetting password for user: einstein\n```\n","devtools/deployments/README.md":"# Docker Compose Deployments for development use\n\nThe docker-compose deployments in this directory are for developement purposes only. They are\nnot actively maintained and not to be used in production.\n",".agents/skills/bumping-web/SKILL.md":"---\nname: bumping-web\ndescription: Use when the user asks to bump, update, or upgrade the OpenCloud web assets/frontend to a specific version (e.g. \"bump web to v7.0.0\", \"update web to v7.1.2\"). Covers editing the version files, the single commit, and opening the PR against the right branch.\n---\n\n# Bumping Web\n\n## Overview\n\nBumping web updates the pinned OpenCloud web frontend (assets + UI-test runner) to a tagged release of [opencloud-eu/web](https://github.com/opencloud-eu/web). It touches exactly two files, lands as one commit, and ships as a PR whose body is the web changelog for that version.\n\nTemplate PR: https://github.com/opencloud-eu/opencloud/pull/2733\n\n## Prerequisites\n\n- **`gh` (GitHub CLI), authenticated** — every lookup and the PR creation go through `gh api` / `gh pr`. Verify with `gh auth status`; if it fails, ask the user to run `gh auth login` (suggest `! gh auth login` so it runs in-session). Do not proceed without it.\n- `gh` needs the system keyring, so run all `gh` commands with the sandbox disabled.\n- `git` and `base64` (decoding the changelog) — standard on macOS/Linux.\n\n## What changes (exactly two files)\n\n| File                    | Variable             | New value                                        |\n| ----------------------- | -------------------- | ------------------------------------------------ |\n| `services/web/Makefile` | `WEB_ASSETS_VERSION` | the version tag, e.g. `v7.0.0`                   |\n| `services/web/Makefile` | `WEB_ASSETS_BRANCH`  | branch carrying the tag (`main` or `stable-X.Y`) |\n| `.woodpecker.env`       | `WEB_COMMITID`       | full commit sha the tag points to                |\n| `.woodpecker.env`       | `WEB_BRANCH`         | same branch as `WEB_ASSETS_BRANCH`               |\n\n`WEB_ASSETS_BRANCH` and `WEB_BRANCH` are always the same value.\n\n## Procedure\n\nLet `VERSION` be the requested tag (always normalize to a leading `v`, e.g. `v7.0.0`).\n\n### 1. Resolve the commit sha the tag points to\n\n```bash\ngh api repos/opencloud-eu/web/commits/$VERSION --jq '.sha'\n```\n\nThis full sha is the new `WEB_COMMITID`.\n\n### 2. Determine the branch (`main` vs `stable-X.Y`)\n\nThe branch is the line of development that carries the tag. Detect it:\n\n```bash\ngh api \"repos/opencloud-eu/web/compare/main...$VERSION\" --jq '.status'\n```\n\n- `identical` or `behind` → the tagged commit is reachable from `main` → use **`main`**.\n- `ahead` or `diverged` → the tag lives on a release line → use **`stable-X.Y`** matching the version's major.minor (e.g. `v7.1.2` → `stable-7.1`).\n\nSanity-check that the stable branch actually exists:\n\n```bash\ngh api repos/opencloud-eu/web/branches --paginate --jq '.[].name' | grep -E 'main|stable'\n```\n\nTypically a freshly released minor (`v7.1.0`) still sits on `main`, while later patches on an older line (`v7.0.3` after `7.1` exists) sit on `stable-7.0`.\n\n### 3. Fetch the changelog for the PR body\n\n```bash\ngh api \"repos/opencloud-eu/web/contents/CHANGELOG.md?ref=$VERSION\" --jq '.content' | base64 -d\n```\n\nTake **only the section for this version**. Match the template: start the PR body at the first content heading (e.g. `### 💥 Breaking changes` / `### 📈 Enhancement`) and drop the `# Changelog` title, the `## [x.y.z] - date` header, and the `### ❤️ Thanks to all contributors!` block. Stop before the next `## [...]` version header.\n\n### 4. Apply the edits\n\nEdit `services/web/Makefile` (`WEB_ASSETS_VERSION`, `WEB_ASSETS_BRANCH`) and `.woodpecker.env` (`WEB_COMMITID`, `WEB_BRANCH`).\n\n### 5. Pick the target branch for the PR\n\n- Major or minor release → target **`main`**.\n- Patch release → may need to target a stable branch instead. If the user did not specify, **ask them** which branch to target before continuing.\n\n### 6. Confirm before committing\n\nShow the user the diff of both files and the target branch, and ask them to confirm. Do not commit until they approve.\n\n### 7. Commit, push, open PR\n\n- Create a branch (do not commit on `main`).\n- One commit, conventional-commits format, **empty body**:\n  ```\n  chore: bump web to v7.0.0\n  ```\n- PR title: `[full-ci] chore: bump web to v7.0.0` (the commit message prefixed with `[full-ci] `).\n- PR base: the branch chosen in step 5.\n- PR body: the trimmed changelog from step 3.\n- Add the label `Type:Dependencies`.\n\n```bash\ngh pr create --base <target-branch> \\\n  --title \"[full-ci] chore: bump web to $VERSION\" \\\n  --label \"Type:Dependencies\" \\\n  --body-file <changelog-file>\n```\n\n(`gh` commands need the sandbox disabled — they require the system keyring.)\n\n## Quick reference\n\n```bash\nVERSION=v7.0.0\ngh api repos/opencloud-eu/web/commits/$VERSION --jq '.sha'                       # WEB_COMMITID\ngh api \"repos/opencloud-eu/web/compare/main...$VERSION\" --jq '.status'           # main vs stable\ngh api \"repos/opencloud-eu/web/contents/CHANGELOG.md?ref=$VERSION\" --jq '.content' | base64 -d  # changelog\n```\n\n## Common mistakes\n\n- Reading `WEB_COMMITID` or the changelog from web `main` instead of from the version tag (`?ref=$VERSION`). Always pin to the tag.\n- Leaving `WEB_ASSETS_BRANCH`/`WEB_BRANCH` on `main` for a patch that belongs on a stable line.\n- Forgetting `[full-ci] ` in the PR title or adding a commit body.\n- Committing before the user confirms the diff and target branch.\n",".agents/skills/bumping-reva/SKILL.md":"---\nname: bumping-reva\ndescription: Use when the user asks to bump, update, or upgrade the OpenCloud reva dependency to a specific version (e.g. \"reva bump to 2.48.0\", \"bump reva to v2.48.0\"). Covers editing go.mod, re-vendoring, bumping the OpenCloud LatestTag, the single commit, and opening the PR against main.\n---\n\n# Bumping Reva\n\n## Overview\n\nBumping reva updates the pinned [opencloud-eu/reva](https://github.com/opencloud-eu/reva) dependency (`github.com/opencloud-eu/reva/v2`) to a tagged release, re-vendors the module graph, and bumps the OpenCloud dev version. It touches `go.mod`, `go.sum`, `vendor/**` and `pkg/version/version.go`, lands as one commit, and ships as a PR whose body is the reva changelog for that version.\n\nTemplate PR: https://github.com/opencloud-eu/opencloud/pull/3127\n\n## Prerequisites\n\n- **The reva release must already be tagged.** A reva release is cut by merging its release PR (title `🎉 Release X.Y.Z`, branch `next-release/main`). The **user merges that PR themselves** — this skill starts *after* the tag `vX.Y.Z` exists. Verify the tag before doing anything (step 1); if it's missing, stop and ask the user to merge the reva release PR first.\n- **`gh` (GitHub CLI), authenticated** — tag lookup and PR creation go through `gh api` / `gh pr`. Verify with `gh auth status`; if it fails, ask the user to run `gh auth login` (suggest `! gh auth login` so it runs in-session).\n- `gh` needs the system keyring, so run all `gh` commands with the sandbox disabled.\n- **Go toolchain + network** — `go get` / `go mod tidy` / `go mod vendor` hit the Go module proxy. Run them with the sandbox disabled (network access).\n- `git` and `base64` (decoding the changelog) — standard on macOS/Linux.\n\n## Inputs\n\n- `REVA_VERSION` — the new reva tag, always normalized to a leading `v` (e.g. `v2.48.0`). If the user didn't give it, ask (or take the latest reva release tag).\n- `OC_VERSION` — the OpenCloud target for `LatestTag`, **without** the `+dev` suffix (e.g. `7.4.0`). **Do not ask or guess** — derive it from the open OpenCloud release PR (step 3). It can be a new major (e.g. `8.0.0`) when release-please picked up a breaking change.\n\n## What changes\n\n| File                     | What                                                                 |\n| ------------------------ | ------------------------------------------------------------------- |\n| `go.mod`                 | `github.com/opencloud-eu/reva/v2` → `REVA_VERSION` (+ indirect deps pulled by `go mod tidy`) |\n| `go.sum`                 | updated by `go get` / `go mod tidy`                                  |\n| `vendor/**`              | re-vendored by `go mod vendor` (incl. `vendor/modules.txt`)         |\n| `pkg/version/version.go` | `LatestTag = \"<OC_VERSION>+dev\"`                                     |\n\n## Procedure\n\n### 1. Verify the reva tag exists\n\n```bash\ngh api repos/opencloud-eu/reva/commits/$REVA_VERSION --jq '.sha'\n```\n\n- Success (a sha) → the release is tagged, continue.\n- `422`/`404` → the tag does not exist yet. The reva release PR (`🎉 Release X.Y.Z`) is probably not merged. **Stop** and tell the user to merge it first. Helpful checks:\n  ```bash\n  gh api repos/opencloud-eu/reva/releases/latest --jq '.tag_name'   # current latest tag\n  gh pr list --repo opencloud-eu/reva --search '🎉 Release in:title' --state open --json number,title\n  ```\n\n### 2. Bump the dependency and re-vendor\n\n```bash\ngo get github.com/opencloud-eu/reva/v2@$REVA_VERSION\ngo mod tidy\ngo mod vendor\n```\n\n(Sandbox disabled — these need network.) Notes:\n- Right after a fresh tag the module proxy can lag; if `go get` reports the version as unknown, retry, or use `GOPROXY=direct go get github.com/opencloud-eu/reva/v2@$REVA_VERSION`.\n- `go mod tidy` will also bump indirect dependencies that reva pulled in — that is expected (the template PR did the same).\n\n### 3. Bump the OpenCloud dev version\n\n`OC_VERSION` is the version of the **open OpenCloud release PR** — the release-please PR from branch `next-release/main`, titled `🎉 Release X.Y.Z` (e.g. #3143). Derive it, don't ask:\n\n```bash\ngh pr list --repo opencloud-eu/opencloud --head next-release/main --state open \\\n  --json title --jq '.[0].title' | grep -oE '[0-9]+\\.[0-9]+\\.[0-9]+' | head -1\n```\n\nThis is the next release target and tracks breaking changes — it may be a new major (e.g. `8.0.0`), not just a minor bump. If no such PR is open, stop and ask the user.\n\nEdit `pkg/version/version.go`:\n\n```go\nLatestTag = \"<OC_VERSION>+dev\"   // e.g. \"7.4.0+dev\"\n```\n\n### 4. Fetch the reva changelog for the PR body\n\n```bash\ngh api \"repos/opencloud-eu/reva/contents/CHANGELOG.md?ref=$REVA_VERSION\" --jq '.content' | base64 -d\n```\n\nTake **only the section for this version** and trim it exactly like the web bump: start at the first content heading (`### 🐛 Bug Fixes` / `### 📈 Enhancement` / `### 💥 Breaking changes`), drop the `# Changelog` title, the `## [x.y.z] - date` header and the `### ❤️ Thanks to all contributors!` block, and stop before the next `## [...]` version header.\n\nThen **prepend two summary bullets** so the final PR body is:\n\n```\n- bump opencloud version to <OC_VERSION>\n- reva bump <REVA_VERSION without the leading v>\n\n### 🐛 Bug Fixes\n...trimmed reva changelog...\n```\n\nWrite this to a file for `--body-file` (e.g. in the scratchpad).\n\n### 5. Confirm before committing\n\nThe `vendor/` diff is huge — do **not** dump it. Show the user:\n\n```bash\ngit diff go.mod pkg/version/version.go        # the meaningful edits\ngit diff --stat | tail -1                      # vendor churn summary\n```\n\nConfirm the reva line in `go.mod` is exactly `github.com/opencloud-eu/reva/v2 REVA_VERSION`, show the target branch (`main`), and the PR body. **Do not commit until the user approves.**\n\n### 6. Commit, push, open PR\n\n- Create a branch (do not commit on `main`), e.g. `reva-bump-2.48.0`.\n- Stage everything the bump touched: `git add go.mod go.sum vendor pkg/version/version.go`.\n- One commit, conventional-commits format, **empty body**:\n  ```\n  chore: bump reva to 2.48.0\n  ```\n- PR base: **`main`** (reva bumps always target main).\n- PR title: `[full-ci] chore: bump reva to 2.48.0` (the commit message prefixed with `[full-ci] `).\n- PR body: the file from step 4.\n- Add the label `Type:Maintenance`.\n\n```bash\ngh pr create --base main \\\n  --title \"[full-ci] chore: bump reva to $REVA_VERSION_NO_V\" \\\n  --label \"Type:Maintenance\" \\\n  --body-file <body-file>\n```\n\n(`gh` commands need the sandbox disabled — they require the system keyring.)\n\n## Quick reference\n\n```bash\nREVA_VERSION=v2.48.0\ngh api repos/opencloud-eu/reva/commits/$REVA_VERSION --jq '.sha'                       # verify tag exists\nOC_VERSION=$(gh pr list --repo opencloud-eu/opencloud --head next-release/main --state open \\\n  --json title --jq '.[0].title' | grep -oE '[0-9]+\\.[0-9]+\\.[0-9]+' | head -1)         # from open release PR\ngo get github.com/opencloud-eu/reva/v2@$REVA_VERSION && go mod tidy && go mod vendor    # bump + re-vendor\n# edit pkg/version/version.go -> LatestTag = \"$OC_VERSION+dev\"\ngh api \"repos/opencloud-eu/reva/contents/CHANGELOG.md?ref=$REVA_VERSION\" --jq '.content' | base64 -d  # changelog\n```\n\n## Common mistakes\n\n- Running the bump before the reva release PR is merged — the tag won't exist and `go get` will fail. Verify the tag first (step 1).\n- Forgetting to re-run `go mod vendor` after `go mod tidy`, leaving `vendor/` out of sync with `go.mod`.\n- Asking for or hardcoding `OC_VERSION` — always derive it from the open `next-release/main` release PR (step 3); it can even be a new major after a breaking change.\n- Reading the changelog from reva `main` instead of the tag (`?ref=$REVA_VERSION`). Always pin to the tag.\n- Missing the `[full-ci] ` prefix in the PR title, the `Type:Maintenance` label, or the two summary bullets at the top of the body.\n- Dumping the full `vendor/` diff at the confirmation step instead of `go.mod` + `version.go` + a `--stat` summary.\n- Committing before the user confirms the diff.\n","vendor/github.com/go-micro/plugins/v4/client/grpc/README.md":"# GRPC Client\n\nThe grpc client is a [micro.Client](https://godoc.org/github.com/micro/go-micro/client#Client) compatible client.\n\n## Overview\n\nThe client makes use of the [google.golang.org/grpc](google.golang.org/grpc) framework for the underlying communication mechanism.\n\n## Usage\n\nSpecify the client to your micro service\n\n```go\nimport (\n\t\"github.com/micro/go-micro\"\n\t\"github.com/micro/go-plugins/client/grpc\"\n)\n\nfunc main() {\n\tservice := micro.NewService(\n\t\tmicro.Name(\"greeter\"),\n\t\tmicro.Client(grpc.NewClient()),\n\t)\n}\n```\n","devtools/deployments/opencloud_full/README.md":"---\ndocument this deployment example in: docs/opencloud/deployment/opencloud_full.md\n---\n\n# OpenCloud WOPI Deployment Example\n\nThis deployment example is documented in two locations for different audiences:\n\n* In the [Admin Documentation](https://docs.opencloud.eu/docs/admin/intro)\\\n  Providing two variants using detailed configuration step by step guides:\\\n  [Docker Compose Setup](https://docs.opencloud.eu/docs/admin/getting-started/container/docker-compose) and [Docker Compose Local](https://docs.opencloud.eu/docs/admin/getting-started/container/docker-compose-local).\\\n  Note that these examples use LetsEncrypt certificates and are intended for production use.\n\n* In the [Developer Documentation](https://docs.opencloud.eu/docs/dev/intro)\\\n  Providing details which are more developer focused. This description can also be used when deviating from the default.\\\n  Note that this examples uses self signed certificates and is intended for testing purposes.\n\n\n","vendor/github.com/go-micro/plugins/v4/server/grpc/README.md":"# GRPC Server\n\nThe grpc server is a [micro.Server](https://pkg.go.dev/github.com/asim/go-micro/server#Server) compatible server.\n\n## Overview\n\nThe server makes use of the [google.golang.org/grpc](google.golang.org/grpc) framework for the underlying server \nbut continues to use micro handler signatures and protoc-gen-micro generated code.\n\n## Usage\n\nSpecify the server to your micro service\n\n```go\nimport (\n        \"go-micro.dev/v4\"\n        \"github.com/go-micro/plugins/v4/server/grpc\"\n)\n\nfunc main() {\n        service := micro.NewService(\n                // This needs to be first as it replaces the underlying server\n                // which causes any configuration set before it\n                // to be discarded\n                micro.Server(grpc.NewServer()),\n                micro.Name(\"greeter\"),\n        )\n}\n```\n**NOTE**: Setting the gRPC server and/or client causes the underlying the server/client to be replaced which causes any previous configuration set on that server/client to be discarded. It is therefore recommended to set gRPC server/client before any other configuration","vendor/github.com/go-micro/plugins/v4/server/http/README.md":"# HTTP Server\n\nThe HTTP Server is a go-micro.Server. It's a partial implementation which strips out codecs, transports, etc but enables you \nto create a HTTP Server that could potentially be used for REST based API services.\n\n## Usage\n\n```go\nimport (\n\t\"net/http\"\n\n\t\"github.com/micro/go-micro/server\"\n\thttpServer \"github.com/go-micro/plugins/v4/server/http\"\n)\n\nfunc main() {\n\tsrv := httpServer.NewServer(\n\t\tserver.Name(\"helloworld\"),\n\t)\n\n\tmux := http.NewServeMux()\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tw.Write([]byte(`hello world`))\n\t})\n\n\thd := srv.NewHandler(mux)\n\n\tsrv.Handle(hd)\n\tsrv.Start()\n\tsrv.Register()\n}\n```\n\nOr as part of a service\n\n```go\nimport (\n\t\"net/http\"\n\n\t\"go-micro.dev/v4\"\n\t\"github.com/micro/go-micro/server\"\n\thttpServer \"github.com/go-micro/plugins/v4/server/http\"\n)\n\nfunc main() {\n\tsrv := httpServer.NewServer(\n\t\tserver.Name(\"helloworld\"),\n\t)\n\n\tmux := http.NewServeMux()\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tw.Write([]byte(`hello world`))\n\t})\n\n\thd := srv.NewHandler(mux)\n\n\tsrv.Handle(hd)\n\n\tservice := micro.NewService(\n\t\tmicro.Server(srv),\n\t)\n\tservice.Init()\n\tservice.Run()\n}\n```\n","vendor/github.com/go-micro/plugins/v4/logger/zerolog/README.md":"# Zerolog\n\n[Zerolog](https://github.com/rs/zerolog) logger implementation for __go-micro__ [meta logger](https://github.com/micro/go-micro/tree/master/logger).\n\n## Usage\n\n```go\nfunc ExampleWithOut() {\n  logger.DefaultLogger = zerolog.NewLogger(logger.WithOutput(os.Stdout), logger.WithLevel(logger.DebugLevel))\n\n  logger.Infof(logger.InfoLevel, \"testing: %s\", \"Infof\")\n\n  // Output:\n  // {\"level\":\"info\",\"message\":\"testing: Infof\"}\n}\n```\n","vendor/github.com/go-micro/plugins/v4/store/nats-js-kv/README.md":"# NATS JetStream Key Value Store Plugin\n\nThis plugin uses the NATS JetStream [KeyValue Store](https://docs.nats.io/nats-concepts/jetstream/key-value-store) to implement the Go-Micro store interface.\n\nYou can use this plugin like any other store plugin. \nTo start a local NATS JetStream server run `nats-server -js`.\n\nTo manually create a new storage object call:\n\n```go\nnatsjskv.NewStore(opts ...store.Option)\n```\n\nThe Go-Micro store interface uses databases and tables to store keys. These translate\nto buckets (key value stores) and key prefixes. If no database (bucket name) is provided, \"default\" will be used.\n\nYou can call `Write` with any arbitrary database name, and if a bucket with that name does not exist yet,\nit will be automatically created.\n\nIf a table name is provided, it will use it to prefix the key as `<table>_<key>`.\n\nTo delete a bucket, and all the key/value pairs in it, pass the `DeleteBucket` option to the `Delete`\nmethod, then they key name will be interpreted as a bucket name, and the bucket will be deleted.\n\nNext to the default store options, a few NATS specific options are available:\n\n\n```go\n// NatsOptions accepts nats.Options\nNatsOptions(opts nats.Options)\n\n// JetStreamOptions accepts multiple nats.JSOpt\nJetStreamOptions(opts ...nats.JSOpt)\n\n// KeyValueOptions accepts multiple nats.KeyValueConfig\n// This will create buckets with the provided configs at initialization.\n//\n// type KeyValueConfig struct {\n//    Bucket       string\n//   Description  string\n//   MaxValueSize int32\n//   History      uint8\n//   TTL          time.Duration\n//   MaxBytes     int64\n//   Storage      StorageType\n//   Replicas     int\n//   Placement    *Placement\n//   RePublish    *RePublish\n//   Mirror       *StreamSource\n//   Sources      []*StreamSource\n}\nKeyValueOptions(cfg ...*nats.KeyValueConfig)\n\n// DefaultTTL sets the default TTL to use for new buckets\n//  By default no TTL is set.\n//\n// TTL ON INDIVIDUAL WRITE CALLS IS NOT SUPPORTED, only bucket wide TTL.\n// Either set a default TTL with this option or provide bucket specific options\n//  with ObjectStoreOptions\nDefaultTTL(ttl time.Duration)\n\n// DefaultMemory sets the default storage type to memory only.\n//\n//  The default is file storage, persisting storage between service restarts.\n// Be aware that the default storage location of NATS the /tmp dir is, and thus\n//  won't persist reboots.\nDefaultMemory()\n\n// DefaultDescription sets the default description to use when creating new\n//  buckets. The default is \"Store managed by go-micro\"\nDefaultDescription(text string)\n\n// DeleteBucket will use the key passed to Delete as a bucket (database) name,\n//  and delete the bucket.\n// This option should not be combined with the store.DeleteFrom option, as\n//  that will overwrite the delete action.\nDeleteBucket()\n```\n\n","vendor/github.com/go-micro/plugins/v4/events/natsjs/README.md":"# NATS JetStream\n\nThis plugin uses NATS with JetStream to send and receive events.\n","vendor/github.com/go-micro/plugins/v4/store/nats-js/README.md":"# NATS JetStream Store Plugin\n\n> **WARNING**: NATS Object Storage is still marked as an experimental preview.\n\nThis plugin uses the NATS JetStream [Object Store](https://docs.nats.io/nats-concepts/jetstream/obj_store) to implement the Go-Micro store interface.\n\nThis enables a key/value store with unlimited message size, allowing you to store files or data of any size under a single key.\n\nYou can use this plugin like any other store plugin. \nTo start a local NATS JetStream server run `nats-server -js`.\n\nTo manually create a new storage object call:\n\n```go\nnatsjs.NewStore(opts ...store.Option)\n```\n\nThe Go-Micro store interface uses databases and tables to store keys. These translate\nto buckets (object stores) and key prefixes. If no database (bucket name) is provided, \"default\" will be used.\n\nYou can call `Write` with any arbitrary database name, and if a bucket with that name does not exist yet,\nit will be automatically created.\n\nIf a table name is provided, it will use it to prefix the key as `<table>_<key>`.\n\nTo delete a bucket, and all the key/value pairs in it, pass the `DeleteBucket` option to the `Delete`\nmethod, then they key name will be interpreted as a bucket name, and the bucket will be deleted.\n\nNext to the default store options, a few NATS specific options are available:\n\n\n```go\n// NatsOptions accepts nats.Options\nNatsOptions(opts nats.Options)\n\n// JetStreamOptions accepts multiple nats.JSOpt\nJetStreamOptions(opts ...nats.JSOpt)\n\n// ObjectStoreOptions accepts multiple nats.ObjectStoreConfigs\n// This will create buckets with the provided configs at initialization.\n//\n// type ObjectStoreConfig struct {\n// \tBucket      string\n// \tDescription string\n// \tTTL         time.Duration\n// \tMaxBytes    int64\n// \tStorage     StorageType (either memory or file storage)\n// \tReplicas    int\n// \tPlacement   *Placement\n// }\n//\nObjectStoreOptions(cfg ...*nats.ObjectStoreConfig)\n\n// DefaultTTL sets the default TTL to use for new buckets\n//  By default no TTL is set.\n//\n// TTL ON INDIVIDUAL WRITE CALLS IS NOT SUPPORTED, only bucket wide TTL.\n// Either set a default TTL with this option or provide bucket specific options\n//  with ObjectStoreOptions\nDefaultTTL(ttl time.Duration)\n\n// DefaultMemory sets the default storage type to memory only.\n//\n//  The default is file storage, persisting storage between service restarts.\n// Be aware that the default storage location of NATS the /tmp dir is, and thus\n//  won't persist reboots.\nDefaultMemory()\n\n// DefaultDescription sets the default description to use when creating new\n//  buckets. The default is \"Store managed by go-micro\"\nDefaultDescription(text string)\n\n// DeleteBucket will use the key passed to Delete as a bucket (database) name,\n//  and delete the bucket.\n// This option should not be combined with the store.DeleteFrom option, as\n//  that will overwrite the delete action.\nDeleteBucket()\n```\n\n","vendor/github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus/README.md":"# prometheus Documentation\n\nPath: `vendor/github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/vendor/github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus/README.md)","vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/README.md":"# opentelemetry Documentation\n\nPath: `vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/README.md)"},"files":{"devtools/deployments/multi-tenancy/README.md":"# Development/Test Deployment for a multi-tenacy setup\n\nThe docker compose files in this directory are derived from the\nopencloud-compose project and can be used to deploy a Development or Testing\nenvironment for a multi-tenancy setup of OpenCloud. It consists of the\nfollowing services:\n\n* `provisioning`: The OpenCloud graph service deployed in a standalone mode. It\n  is configured to provide the libregraph education API for managing tenants\n  and users. The `ldap-server`service (see below) is used to store the tenants\n  and users.\n* `ldap-server`: An OpenLDAP server that is used by the provisioning service to\n  store tenants and users. Used by the OpenCloud services as the user directory\n  (for looking up users and searching for sharees).\n* `keycloak`: The OpenID Connect Provider used for authenticating users. The\n  pre-loaded realm is configured to add `tenantid` claim into the identity and\n  access tokens. It's also currently consuming user from the `ldap-server`\n  (this federation will likely go away in the future and is optional for future\n  configurations).\n* `opencloud`: The OpenCloud configured so that is hides users from different\n  tenants from each other.\n\nTo deploy the setup, run:\n\n```bash\ndocker compose -f docker-compose.yml -f keycloak.yml -f ldap-server.yml -f traefik.yml up\n```\n\nOnce deployed you can use the `initialize_users.go` to create a couple of example\ntenants and some users in each tenant:\n\n* Tenant `Famous Coders` with users `dennis` and `grace`\n* Tenant `Scientists` with users `einstein` and `marie`\n\nThe passwords for the users is set to `demo` in keycloak\n\n```\n> go run initialize_users.go\nCreated tenant: Famous Coders with id fc58e19a-3a2a-4afc-90ec-8f94986db340\nCreated user: Dennis Ritchie with id ee1e14e7-b00b-4eec-8b03-a6bf0e29c77c\nCreated user: Grace Hopper with id a29f3afd-e4a3-4552-91e8-cc99e26bffce\nCreated tenant: Scientists with id 18406c53-e2d6-4e83-98b6-a55880eef195\nCreated user: Albert Einstein with id 12023d37-d6ce-4f19-a318-b70866f265ba\nCreated user: Marie Curie with id 30c3c825-c37d-4e85-8195-0142e4884872\nSetting password for user: grace\nSetting password for user: marie\nSetting password for user: dennis\nSetting password for user: einstein\n```\n","devtools/deployments/README.md":"# Docker Compose Deployments for development use\n\nThe docker-compose deployments in this directory are for developement purposes only. They are\nnot actively maintained and not to be used in production.\n",".agents/skills/bumping-web/SKILL.md":"---\nname: bumping-web\ndescription: Use when the user asks to bump, update, or upgrade the OpenCloud web assets/frontend to a specific version (e.g. \"bump web to v7.0.0\", \"update web to v7.1.2\"). Covers editing the version files, the single commit, and opening the PR against the right branch.\n---\n\n# Bumping Web\n\n## Overview\n\nBumping web updates the pinned OpenCloud web frontend (assets + UI-test runner) to a tagged release of [opencloud-eu/web](https://github.com/opencloud-eu/web). It touches exactly two files, lands as one commit, and ships as a PR whose body is the web changelog for that version.\n\nTemplate PR: https://github.com/opencloud-eu/opencloud/pull/2733\n\n## Prerequisites\n\n- **`gh` (GitHub CLI), authenticated** — every lookup and the PR creation go through `gh api` / `gh pr`. Verify with `gh auth status`; if it fails, ask the user to run `gh auth login` (suggest `! gh auth login` so it runs in-session). Do not proceed without it.\n- `gh` needs the system keyring, so run all `gh` commands with the sandbox disabled.\n- `git` and `base64` (decoding the changelog) — standard on macOS/Linux.\n\n## What changes (exactly two files)\n\n| File                    | Variable             | New value                                        |\n| ----------------------- | -------------------- | ------------------------------------------------ |\n| `services/web/Makefile` | `WEB_ASSETS_VERSION` | the version tag, e.g. `v7.0.0`                   |\n| `services/web/Makefile` | `WEB_ASSETS_BRANCH`  | branch carrying the tag (`main` or `stable-X.Y`) |\n| `.woodpecker.env`       | `WEB_COMMITID`       | full commit sha the tag points to                |\n| `.woodpecker.env`       | `WEB_BRANCH`         | same branch as `WEB_ASSETS_BRANCH`               |\n\n`WEB_ASSETS_BRANCH` and `WEB_BRANCH` are always the same value.\n\n## Procedure\n\nLet `VERSION` be the requested tag (always normalize to a leading `v`, e.g. `v7.0.0`).\n\n### 1. Resolve the commit sha the tag points to\n\n```bash\ngh api repos/opencloud-eu/web/commits/$VERSION --jq '.sha'\n```\n\nThis full sha is the new `WEB_COMMITID`.\n\n### 2. Determine the branch (`main` vs `stable-X.Y`)\n\nThe branch is the line of development that carries the tag. Detect it:\n\n```bash\ngh api \"repos/opencloud-eu/web/compare/main...$VERSION\" --jq '.status'\n```\n\n- `identical` or `behind` → the tagged commit is reachable from `main` → use **`main`**.\n- `ahead` or `diverged` → the tag lives on a release line → use **`stable-X.Y`** matching the version's major.minor (e.g. `v7.1.2` → `stable-7.1`).\n\nSanity-check that the stable branch actually exists:\n\n```bash\ngh api repos/opencloud-eu/web/branches --paginate --jq '.[].name' | grep -E 'main|stable'\n```\n\nTypically a freshly released minor (`v7.1.0`) still sits on `main`, while later patches on an older line (`v7.0.3` after `7.1` exists) sit on `stable-7.0`.\n\n### 3. Fetch the changelog for the PR body\n\n```bash\ngh api \"repos/opencloud-eu/web/contents/CHANGELOG.md?ref=$VERSION\" --jq '.content' | base64 -d\n```\n\nTake **only the section for this version**. Match the template: start the PR body at the first content heading (e.g. `### 💥 Breaking changes` / `### 📈 Enhancement`) and drop the `# Changelog` title, the `## [x.y.z] - date` header, and the `### ❤️ Thanks to all contributors!` block. Stop before the next `## [...]` version header.\n\n### 4. Apply the edits\n\nEdit `services/web/Makefile` (`WEB_ASSETS_VERSION`, `WEB_ASSETS_BRANCH`) and `.woodpecker.env` (`WEB_COMMITID`, `WEB_BRANCH`).\n\n### 5. Pick the target branch for the PR\n\n- Major or minor release → target **`main`**.\n- Patch release → may need to target a stable branch instead. If the user did not specify, **ask them** which branch to target before continuing.\n\n### 6. Confirm before committing\n\nShow the user the diff of both files and the target branch, and ask them to confirm. Do not commit until they approve.\n\n### 7. Commit, push, open PR\n\n- Create a branch (do not commit on `main`).\n- One commit, conventional-commits format, **empty body**:\n  ```\n  chore: bump web to v7.0.0\n  ```\n- PR title: `[full-ci] chore: bump web to v7.0.0` (the commit message prefixed with `[full-ci] `).\n- PR base: the branch chosen in step 5.\n- PR body: the trimmed changelog from step 3.\n- Add the label `Type:Dependencies`.\n\n```bash\ngh pr create --base <target-branch> \\\n  --title \"[full-ci] chore: bump web to $VERSION\" \\\n  --label \"Type:Dependencies\" \\\n  --body-file <changelog-file>\n```\n\n(`gh` commands need the sandbox disabled — they require the system keyring.)\n\n## Quick reference\n\n```bash\nVERSION=v7.0.0\ngh api repos/opencloud-eu/web/commits/$VERSION --jq '.sha'                       # WEB_COMMITID\ngh api \"repos/opencloud-eu/web/compare/main...$VERSION\" --jq '.status'           # main vs stable\ngh api \"repos/opencloud-eu/web/contents/CHANGELOG.md?ref=$VERSION\" --jq '.content' | base64 -d  # changelog\n```\n\n## Common mistakes\n\n- Reading `WEB_COMMITID` or the changelog from web `main` instead of from the version tag (`?ref=$VERSION`). Always pin to the tag.\n- Leaving `WEB_ASSETS_BRANCH`/`WEB_BRANCH` on `main` for a patch that belongs on a stable line.\n- Forgetting `[full-ci] ` in the PR title or adding a commit body.\n- Committing before the user confirms the diff and target branch.\n",".agents/skills/bumping-reva/SKILL.md":"---\nname: bumping-reva\ndescription: Use when the user asks to bump, update, or upgrade the OpenCloud reva dependency to a specific version (e.g. \"reva bump to 2.48.0\", \"bump reva to v2.48.0\"). Covers editing go.mod, re-vendoring, bumping the OpenCloud LatestTag, the single commit, and opening the PR against main.\n---\n\n# Bumping Reva\n\n## Overview\n\nBumping reva updates the pinned [opencloud-eu/reva](https://github.com/opencloud-eu/reva) dependency (`github.com/opencloud-eu/reva/v2`) to a tagged release, re-vendors the module graph, and bumps the OpenCloud dev version. It touches `go.mod`, `go.sum`, `vendor/**` and `pkg/version/version.go`, lands as one commit, and ships as a PR whose body is the reva changelog for that version.\n\nTemplate PR: https://github.com/opencloud-eu/opencloud/pull/3127\n\n## Prerequisites\n\n- **The reva release must already be tagged.** A reva release is cut by merging its release PR (title `🎉 Release X.Y.Z`, branch `next-release/main`). The **user merges that PR themselves** — this skill starts *after* the tag `vX.Y.Z` exists. Verify the tag before doing anything (step 1); if it's missing, stop and ask the user to merge the reva release PR first.\n- **`gh` (GitHub CLI), authenticated** — tag lookup and PR creation go through `gh api` / `gh pr`. Verify with `gh auth status`; if it fails, ask the user to run `gh auth login` (suggest `! gh auth login` so it runs in-session).\n- `gh` needs the system keyring, so run all `gh` commands with the sandbox disabled.\n- **Go toolchain + network** — `go get` / `go mod tidy` / `go mod vendor` hit the Go module proxy. Run them with the sandbox disabled (network access).\n- `git` and `base64` (decoding the changelog) — standard on macOS/Linux.\n\n## Inputs\n\n- `REVA_VERSION` — the new reva tag, always normalized to a leading `v` (e.g. `v2.48.0`). If the user didn't give it, ask (or take the latest reva release tag).\n- `OC_VERSION` — the OpenCloud target for `LatestTag`, **without** the `+dev` suffix (e.g. `7.4.0`). **Do not ask or guess** — derive it from the open OpenCloud release PR (step 3). It can be a new major (e.g. `8.0.0`) when release-please picked up a breaking change.\n\n## What changes\n\n| File                     | What                                                                 |\n| ------------------------ | ------------------------------------------------------------------- |\n| `go.mod`                 | `github.com/opencloud-eu/reva/v2` → `REVA_VERSION` (+ indirect deps pulled by `go mod tidy`) |\n| `go.sum`                 | updated by `go get` / `go mod tidy`                                  |\n| `vendor/**`              | re-vendored by `go mod vendor` (incl. `vendor/modules.txt`)         |\n| `pkg/version/version.go` | `LatestTag = \"<OC_VERSION>+dev\"`                                     |\n\n## Procedure\n\n### 1. Verify the reva tag exists\n\n```bash\ngh api repos/opencloud-eu/reva/commits/$REVA_VERSION --jq '.sha'\n```\n\n- Success (a sha) → the release is tagged, continue.\n- `422`/`404` → the tag does not exist yet. The reva release PR (`🎉 Release X.Y.Z`) is probably not merged. **Stop** and tell the user to merge it first. Helpful checks:\n  ```bash\n  gh api repos/opencloud-eu/reva/releases/latest --jq '.tag_name'   # current latest tag\n  gh pr list --repo opencloud-eu/reva --search '🎉 Release in:title' --state open --json number,title\n  ```\n\n### 2. Bump the dependency and re-vendor\n\n```bash\ngo get github.com/opencloud-eu/reva/v2@$REVA_VERSION\ngo mod tidy\ngo mod vendor\n```\n\n(Sandbox disabled — these need network.) Notes:\n- Right after a fresh tag the module proxy can lag; if `go get` reports the version as unknown, retry, or use `GOPROXY=direct go get github.com/opencloud-eu/reva/v2@$REVA_VERSION`.\n- `go mod tidy` will also bump indirect dependencies that reva pulled in — that is expected (the template PR did the same).\n\n### 3. Bump the OpenCloud dev version\n\n`OC_VERSION` is the version of the **open OpenCloud release PR** — the release-please PR from branch `next-release/main`, titled `🎉 Release X.Y.Z` (e.g. #3143). Derive it, don't ask:\n\n```bash\ngh pr list --repo opencloud-eu/opencloud --head next-release/main --state open \\\n  --json title --jq '.[0].title' | grep -oE '[0-9]+\\.[0-9]+\\.[0-9]+' | head -1\n```\n\nThis is the next release target and tracks breaking changes — it may be a new major (e.g. `8.0.0`), not just a minor bump. If no such PR is open, stop and ask the user.\n\nEdit `pkg/version/version.go`:\n\n```go\nLatestTag = \"<OC_VERSION>+dev\"   // e.g. \"7.4.0+dev\"\n```\n\n### 4. Fetch the reva changelog for the PR body\n\n```bash\ngh api \"repos/opencloud-eu/reva/contents/CHANGELOG.md?ref=$REVA_VERSION\" --jq '.content' | base64 -d\n```\n\nTake **only the section for this version** and trim it exactly like the web bump: start at the first content heading (`### 🐛 Bug Fixes` / `### 📈 Enhancement` / `### 💥 Breaking changes`), drop the `# Changelog` title, the `## [x.y.z] - date` header and the `### ❤️ Thanks to all contributors!` block, and stop before the next `## [...]` version header.\n\nThen **prepend two summary bullets** so the final PR body is:\n\n```\n- bump opencloud version to <OC_VERSION>\n- reva bump <REVA_VERSION without the leading v>\n\n### 🐛 Bug Fixes\n...trimmed reva changelog...\n```\n\nWrite this to a file for `--body-file` (e.g. in the scratchpad).\n\n### 5. Confirm before committing\n\nThe `vendor/` diff is huge — do **not** dump it. Show the user:\n\n```bash\ngit diff go.mod pkg/version/version.go        # the meaningful edits\ngit diff --stat | tail -1                      # vendor churn summary\n```\n\nConfirm the reva line in `go.mod` is exactly `github.com/opencloud-eu/reva/v2 REVA_VERSION`, show the target branch (`main`), and the PR body. **Do not commit until the user approves.**\n\n### 6. Commit, push, open PR\n\n- Create a branch (do not commit on `main`), e.g. `reva-bump-2.48.0`.\n- Stage everything the bump touched: `git add go.mod go.sum vendor pkg/version/version.go`.\n- One commit, conventional-commits format, **empty body**:\n  ```\n  chore: bump reva to 2.48.0\n  ```\n- PR base: **`main`** (reva bumps always target main).\n- PR title: `[full-ci] chore: bump reva to 2.48.0` (the commit message prefixed with `[full-ci] `).\n- PR body: the file from step 4.\n- Add the label `Type:Maintenance`.\n\n```bash\ngh pr create --base main \\\n  --title \"[full-ci] chore: bump reva to $REVA_VERSION_NO_V\" \\\n  --label \"Type:Maintenance\" \\\n  --body-file <body-file>\n```\n\n(`gh` commands need the sandbox disabled — they require the system keyring.)\n\n## Quick reference\n\n```bash\nREVA_VERSION=v2.48.0\ngh api repos/opencloud-eu/reva/commits/$REVA_VERSION --jq '.sha'                       # verify tag exists\nOC_VERSION=$(gh pr list --repo opencloud-eu/opencloud --head next-release/main --state open \\\n  --json title --jq '.[0].title' | grep -oE '[0-9]+\\.[0-9]+\\.[0-9]+' | head -1)         # from open release PR\ngo get github.com/opencloud-eu/reva/v2@$REVA_VERSION && go mod tidy && go mod vendor    # bump + re-vendor\n# edit pkg/version/version.go -> LatestTag = \"$OC_VERSION+dev\"\ngh api \"repos/opencloud-eu/reva/contents/CHANGELOG.md?ref=$REVA_VERSION\" --jq '.content' | base64 -d  # changelog\n```\n\n## Common mistakes\n\n- Running the bump before the reva release PR is merged — the tag won't exist and `go get` will fail. Verify the tag first (step 1).\n- Forgetting to re-run `go mod vendor` after `go mod tidy`, leaving `vendor/` out of sync with `go.mod`.\n- Asking for or hardcoding `OC_VERSION` — always derive it from the open `next-release/main` release PR (step 3); it can even be a new major after a breaking change.\n- Reading the changelog from reva `main` instead of the tag (`?ref=$REVA_VERSION`). Always pin to the tag.\n- Missing the `[full-ci] ` prefix in the PR title, the `Type:Maintenance` label, or the two summary bullets at the top of the body.\n- Dumping the full `vendor/` diff at the confirmation step instead of `go.mod` + `version.go` + a `--stat` summary.\n- Committing before the user confirms the diff.\n","vendor/github.com/go-micro/plugins/v4/client/grpc/README.md":"# GRPC Client\n\nThe grpc client is a [micro.Client](https://godoc.org/github.com/micro/go-micro/client#Client) compatible client.\n\n## Overview\n\nThe client makes use of the [google.golang.org/grpc](google.golang.org/grpc) framework for the underlying communication mechanism.\n\n## Usage\n\nSpecify the client to your micro service\n\n```go\nimport (\n\t\"github.com/micro/go-micro\"\n\t\"github.com/micro/go-plugins/client/grpc\"\n)\n\nfunc main() {\n\tservice := micro.NewService(\n\t\tmicro.Name(\"greeter\"),\n\t\tmicro.Client(grpc.NewClient()),\n\t)\n}\n```\n","devtools/deployments/opencloud_full/README.md":"---\ndocument this deployment example in: docs/opencloud/deployment/opencloud_full.md\n---\n\n# OpenCloud WOPI Deployment Example\n\nThis deployment example is documented in two locations for different audiences:\n\n* In the [Admin Documentation](https://docs.opencloud.eu/docs/admin/intro)\\\n  Providing two variants using detailed configuration step by step guides:\\\n  [Docker Compose Setup](https://docs.opencloud.eu/docs/admin/getting-started/container/docker-compose) and [Docker Compose Local](https://docs.opencloud.eu/docs/admin/getting-started/container/docker-compose-local).\\\n  Note that these examples use LetsEncrypt certificates and are intended for production use.\n\n* In the [Developer Documentation](https://docs.opencloud.eu/docs/dev/intro)\\\n  Providing details which are more developer focused. This description can also be used when deviating from the default.\\\n  Note that this examples uses self signed certificates and is intended for testing purposes.\n\n\n","vendor/github.com/go-micro/plugins/v4/server/grpc/README.md":"# GRPC Server\n\nThe grpc server is a [micro.Server](https://pkg.go.dev/github.com/asim/go-micro/server#Server) compatible server.\n\n## Overview\n\nThe server makes use of the [google.golang.org/grpc](google.golang.org/grpc) framework for the underlying server \nbut continues to use micro handler signatures and protoc-gen-micro generated code.\n\n## Usage\n\nSpecify the server to your micro service\n\n```go\nimport (\n        \"go-micro.dev/v4\"\n        \"github.com/go-micro/plugins/v4/server/grpc\"\n)\n\nfunc main() {\n        service := micro.NewService(\n                // This needs to be first as it replaces the underlying server\n                // which causes any configuration set before it\n                // to be discarded\n                micro.Server(grpc.NewServer()),\n                micro.Name(\"greeter\"),\n        )\n}\n```\n**NOTE**: Setting the gRPC server and/or client causes the underlying the server/client to be replaced which causes any previous configuration set on that server/client to be discarded. It is therefore recommended to set gRPC server/client before any other configuration","vendor/github.com/go-micro/plugins/v4/server/http/README.md":"# HTTP Server\n\nThe HTTP Server is a go-micro.Server. It's a partial implementation which strips out codecs, transports, etc but enables you \nto create a HTTP Server that could potentially be used for REST based API services.\n\n## Usage\n\n```go\nimport (\n\t\"net/http\"\n\n\t\"github.com/micro/go-micro/server\"\n\thttpServer \"github.com/go-micro/plugins/v4/server/http\"\n)\n\nfunc main() {\n\tsrv := httpServer.NewServer(\n\t\tserver.Name(\"helloworld\"),\n\t)\n\n\tmux := http.NewServeMux()\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tw.Write([]byte(`hello world`))\n\t})\n\n\thd := srv.NewHandler(mux)\n\n\tsrv.Handle(hd)\n\tsrv.Start()\n\tsrv.Register()\n}\n```\n\nOr as part of a service\n\n```go\nimport (\n\t\"net/http\"\n\n\t\"go-micro.dev/v4\"\n\t\"github.com/micro/go-micro/server\"\n\thttpServer \"github.com/go-micro/plugins/v4/server/http\"\n)\n\nfunc main() {\n\tsrv := httpServer.NewServer(\n\t\tserver.Name(\"helloworld\"),\n\t)\n\n\tmux := http.NewServeMux()\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tw.Write([]byte(`hello world`))\n\t})\n\n\thd := srv.NewHandler(mux)\n\n\tsrv.Handle(hd)\n\n\tservice := micro.NewService(\n\t\tmicro.Server(srv),\n\t)\n\tservice.Init()\n\tservice.Run()\n}\n```\n","vendor/github.com/go-micro/plugins/v4/logger/zerolog/README.md":"# Zerolog\n\n[Zerolog](https://github.com/rs/zerolog) logger implementation for __go-micro__ [meta logger](https://github.com/micro/go-micro/tree/master/logger).\n\n## Usage\n\n```go\nfunc ExampleWithOut() {\n  logger.DefaultLogger = zerolog.NewLogger(logger.WithOutput(os.Stdout), logger.WithLevel(logger.DebugLevel))\n\n  logger.Infof(logger.InfoLevel, \"testing: %s\", \"Infof\")\n\n  // Output:\n  // {\"level\":\"info\",\"message\":\"testing: Infof\"}\n}\n```\n","vendor/github.com/go-micro/plugins/v4/store/nats-js-kv/README.md":"# NATS JetStream Key Value Store Plugin\n\nThis plugin uses the NATS JetStream [KeyValue Store](https://docs.nats.io/nats-concepts/jetstream/key-value-store) to implement the Go-Micro store interface.\n\nYou can use this plugin like any other store plugin. \nTo start a local NATS JetStream server run `nats-server -js`.\n\nTo manually create a new storage object call:\n\n```go\nnatsjskv.NewStore(opts ...store.Option)\n```\n\nThe Go-Micro store interface uses databases and tables to store keys. These translate\nto buckets (key value stores) and key prefixes. If no database (bucket name) is provided, \"default\" will be used.\n\nYou can call `Write` with any arbitrary database name, and if a bucket with that name does not exist yet,\nit will be automatically created.\n\nIf a table name is provided, it will use it to prefix the key as `<table>_<key>`.\n\nTo delete a bucket, and all the key/value pairs in it, pass the `DeleteBucket` option to the `Delete`\nmethod, then they key name will be interpreted as a bucket name, and the bucket will be deleted.\n\nNext to the default store options, a few NATS specific options are available:\n\n\n```go\n// NatsOptions accepts nats.Options\nNatsOptions(opts nats.Options)\n\n// JetStreamOptions accepts multiple nats.JSOpt\nJetStreamOptions(opts ...nats.JSOpt)\n\n// KeyValueOptions accepts multiple nats.KeyValueConfig\n// This will create buckets with the provided configs at initialization.\n//\n// type KeyValueConfig struct {\n//    Bucket       string\n//   Description  string\n//   MaxValueSize int32\n//   History      uint8\n//   TTL          time.Duration\n//   MaxBytes     int64\n//   Storage      StorageType\n//   Replicas     int\n//   Placement    *Placement\n//   RePublish    *RePublish\n//   Mirror       *StreamSource\n//   Sources      []*StreamSource\n}\nKeyValueOptions(cfg ...*nats.KeyValueConfig)\n\n// DefaultTTL sets the default TTL to use for new buckets\n//  By default no TTL is set.\n//\n// TTL ON INDIVIDUAL WRITE CALLS IS NOT SUPPORTED, only bucket wide TTL.\n// Either set a default TTL with this option or provide bucket specific options\n//  with ObjectStoreOptions\nDefaultTTL(ttl time.Duration)\n\n// DefaultMemory sets the default storage type to memory only.\n//\n//  The default is file storage, persisting storage between service restarts.\n// Be aware that the default storage location of NATS the /tmp dir is, and thus\n//  won't persist reboots.\nDefaultMemory()\n\n// DefaultDescription sets the default description to use when creating new\n//  buckets. The default is \"Store managed by go-micro\"\nDefaultDescription(text string)\n\n// DeleteBucket will use the key passed to Delete as a bucket (database) name,\n//  and delete the bucket.\n// This option should not be combined with the store.DeleteFrom option, as\n//  that will overwrite the delete action.\nDeleteBucket()\n```\n\n","vendor/github.com/go-micro/plugins/v4/events/natsjs/README.md":"# NATS JetStream\n\nThis plugin uses NATS with JetStream to send and receive events.\n","vendor/github.com/go-micro/plugins/v4/store/nats-js/README.md":"# NATS JetStream Store Plugin\n\n> **WARNING**: NATS Object Storage is still marked as an experimental preview.\n\nThis plugin uses the NATS JetStream [Object Store](https://docs.nats.io/nats-concepts/jetstream/obj_store) to implement the Go-Micro store interface.\n\nThis enables a key/value store with unlimited message size, allowing you to store files or data of any size under a single key.\n\nYou can use this plugin like any other store plugin. \nTo start a local NATS JetStream server run `nats-server -js`.\n\nTo manually create a new storage object call:\n\n```go\nnatsjs.NewStore(opts ...store.Option)\n```\n\nThe Go-Micro store interface uses databases and tables to store keys. These translate\nto buckets (object stores) and key prefixes. If no database (bucket name) is provided, \"default\" will be used.\n\nYou can call `Write` with any arbitrary database name, and if a bucket with that name does not exist yet,\nit will be automatically created.\n\nIf a table name is provided, it will use it to prefix the key as `<table>_<key>`.\n\nTo delete a bucket, and all the key/value pairs in it, pass the `DeleteBucket` option to the `Delete`\nmethod, then they key name will be interpreted as a bucket name, and the bucket will be deleted.\n\nNext to the default store options, a few NATS specific options are available:\n\n\n```go\n// NatsOptions accepts nats.Options\nNatsOptions(opts nats.Options)\n\n// JetStreamOptions accepts multiple nats.JSOpt\nJetStreamOptions(opts ...nats.JSOpt)\n\n// ObjectStoreOptions accepts multiple nats.ObjectStoreConfigs\n// This will create buckets with the provided configs at initialization.\n//\n// type ObjectStoreConfig struct {\n// \tBucket      string\n// \tDescription string\n// \tTTL         time.Duration\n// \tMaxBytes    int64\n// \tStorage     StorageType (either memory or file storage)\n// \tReplicas    int\n// \tPlacement   *Placement\n// }\n//\nObjectStoreOptions(cfg ...*nats.ObjectStoreConfig)\n\n// DefaultTTL sets the default TTL to use for new buckets\n//  By default no TTL is set.\n//\n// TTL ON INDIVIDUAL WRITE CALLS IS NOT SUPPORTED, only bucket wide TTL.\n// Either set a default TTL with this option or provide bucket specific options\n//  with ObjectStoreOptions\nDefaultTTL(ttl time.Duration)\n\n// DefaultMemory sets the default storage type to memory only.\n//\n//  The default is file storage, persisting storage between service restarts.\n// Be aware that the default storage location of NATS the /tmp dir is, and thus\n//  won't persist reboots.\nDefaultMemory()\n\n// DefaultDescription sets the default description to use when creating new\n//  buckets. The default is \"Store managed by go-micro\"\nDefaultDescription(text string)\n\n// DeleteBucket will use the key passed to Delete as a bucket (database) name,\n//  and delete the bucket.\n// This option should not be combined with the store.DeleteFrom option, as\n//  that will overwrite the delete action.\nDeleteBucket()\n```\n\n","vendor/github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus/README.md":"# prometheus Documentation\n\nPath: `vendor/github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/vendor/github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus/README.md)","vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/README.md":"# opentelemetry Documentation\n\nPath: `vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/README.md)"},"items":[{"name":"SKILL.md","path":".agents/skills/bumping-reva/SKILL.md","rawUrl":"https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/.agents/skills/bumping-reva/SKILL.md","title":"bumping-reva","category":"anthropic-skill","format":"markdown","content":"---\nname: bumping-reva\ndescription: Use when the user asks to bump, update, or upgrade the OpenCloud reva dependency to a specific version (e.g. \"reva bump to 2.48.0\", \"bump reva to v2.48.0\"). Covers editing go.mod, re-vendoring, bumping the OpenCloud LatestTag, the single commit, and opening the PR against main.\n---\n\n# Bumping Reva\n\n## Overview\n\nBumping reva updates the pinned [opencloud-eu/reva](https://github.com/opencloud-eu/reva) dependency (`github.com/opencloud-eu/reva/v2`) to a tagged release, re-vendors the module graph, and bumps the OpenCloud dev version. It touches `go.mod`, `go.sum`, `vendor/**` and `pkg/version/version.go`, lands as one commit, and ships as a PR whose body is the reva changelog for that version.\n\nTemplate PR: https://github.com/opencloud-eu/opencloud/pull/3127\n\n## Prerequisites\n\n- **The reva release must already be tagged.** A reva release is cut by merging its release PR (title `🎉 Release X.Y.Z`, branch `next-release/main`). The **user merges that PR themselves** — this skill starts *after* the tag `vX.Y.Z` exists. Verify the tag before doing anything (step 1); if it's missing, stop and ask the user to merge the reva release PR first.\n- **`gh` (GitHub CLI), authenticated** — tag lookup and PR creation go through `gh api` / `gh pr`. Verify with `gh auth status`; if it fails, ask the user to run `gh auth login` (suggest `! gh auth login` so it runs in-session).\n- `gh` needs the system keyring, so run all `gh` commands with the sandbox disabled.\n- **Go toolchain + network** — `go get` / `go mod tidy` / `go mod vendor` hit the Go module proxy. Run them with the sandbox disabled (network access).\n- `git` and `base64` (decoding the changelog) — standard on macOS/Linux.\n\n## Inputs\n\n- `REVA_VERSION` — the new reva tag, always normalized to a leading `v` (e.g. `v2.48.0`). If the user didn't give it, ask (or take the latest reva release tag).\n- `OC_VERSION` — the OpenCloud target for `LatestTag`, **without** the `+dev` suffix (e.g. `7.4.0`). **Do not ask or guess** — derive it from the open OpenCloud release PR (step 3). It can be a new major (e.g. `8.0.0`) when release-please picked up a breaking change.\n\n## What changes\n\n| File                     | What                                                                 |\n| ------------------------ | ------------------------------------------------------------------- |\n| `go.mod`                 | `github.com/opencloud-eu/reva/v2` → `REVA_VERSION` (+ indirect deps pulled by `go mod tidy`) |\n| `go.sum`                 | updated by `go get` / `go mod tidy`                                  |\n| `vendor/**`              | re-vendored by `go mod vendor` (incl. `vendor/modules.txt`)         |\n| `pkg/version/version.go` | `LatestTag = \"<OC_VERSION>+dev\"`                                     |\n\n## Procedure\n\n### 1. Verify the reva tag exists\n\n```bash\ngh api repos/opencloud-eu/reva/commits/$REVA_VERSION --jq '.sha'\n```\n\n- Success (a sha) → the release is tagged, continue.\n- `422`/`404` → the tag does not exist yet. The reva release PR (`🎉 Release X.Y.Z`) is probably not merged. **Stop** and tell the user to merge it first. Helpful checks:\n  ```bash\n  gh api repos/opencloud-eu/reva/releases/latest --jq '.tag_name'   # current latest tag\n  gh pr list --repo opencloud-eu/reva --search '🎉 Release in:title' --state open --json number,title\n  ```\n\n### 2. Bump the dependency and re-vendor\n\n```bash\ngo get github.com/opencloud-eu/reva/v2@$REVA_VERSION\ngo mod tidy\ngo mod vendor\n```\n\n(Sandbox disabled — these need network.) Notes:\n- Right after a fresh tag the module proxy can lag; if `go get` reports the version as unknown, retry, or use `GOPROXY=direct go get github.com/opencloud-eu/reva/v2@$REVA_VERSION`.\n- `go mod tidy` will also bump indirect dependencies that reva pulled in — that is expected (the template PR did the same).\n\n### 3. Bump the OpenCloud dev version\n\n`OC_VERSION` is the version of the **open OpenCloud release PR** — the release-please PR from branch `next-release/main`, titled `🎉 Release X.Y.Z` (e.g. #3143). Derive it, don't ask:\n\n```bash\ngh pr list --repo opencloud-eu/opencloud --head next-release/main --state open \\\n  --json title --jq '.[0].title' | grep -oE '[0-9]+\\.[0-9]+\\.[0-9]+' | head -1\n```\n\nThis is the next release target and tracks breaking changes — it may be a new major (e.g. `8.0.0`), not just a minor bump. If no such PR is open, stop and ask the user.\n\nEdit `pkg/version/version.go`:\n\n```go\nLatestTag = \"<OC_VERSION>+dev\"   // e.g. \"7.4.0+dev\"\n```\n\n### 4. Fetch the reva changelog for the PR body\n\n```bash\ngh api \"repos/opencloud-eu/reva/contents/CHANGELOG.md?ref=$REVA_VERSION\" --jq '.content' | base64 -d\n```\n\nTake **only the section for this version** and trim it exactly like the web bump: start at the first content heading (`### 🐛 Bug Fixes` / `### 📈 Enhancement` / `### 💥 Breaking changes`), drop the `# Changelog` title, the `## [x.y.z] - date` header and the `### ❤️ Thanks to all contributors!` block, and stop before the next `## [...]` version header.\n\nThen **prepend two summary bullets** so the final PR body is:\n\n```\n- bump opencloud version to <OC_VERSION>\n- reva bump <REVA_VERSION without the leading v>\n\n### 🐛 Bug Fixes\n...trimmed reva changelog...\n```\n\nWrite this to a file for `--body-file` (e.g. in the scratchpad).\n\n### 5. Confirm before committing\n\nThe `vendor/` diff is huge — do **not** dump it. Show the user:\n\n```bash\ngit diff go.mod pkg/version/version.go        # the meaningful edits\ngit diff --stat | tail -1                      # vendor churn summary\n```\n\nConfirm the reva line in `go.mod` is exactly `github.com/opencloud-eu/reva/v2 REVA_VERSION`, show the target branch (`main`), and the PR body. **Do not commit until the user approves.**\n\n### 6. Commit, push, open PR\n\n- Create a branch (do not commit on `main`), e.g. `reva-bump-2.48.0`.\n- Stage everything the bump touched: `git add go.mod go.sum vendor pkg/version/version.go`.\n- One commit, conventional-commits format, **empty body**:\n  ```\n  chore: bump reva to 2.48.0\n  ```\n- PR base: **`main`** (reva bumps always target main).\n- PR title: `[full-ci] chore: bump reva to 2.48.0` (the commit message prefixed with `[full-ci] `).\n- PR body: the file from step 4.\n- Add the label `Type:Maintenance`.\n\n```bash\ngh pr create --base main \\\n  --title \"[full-ci] chore: bump reva to $REVA_VERSION_NO_V\" \\\n  --label \"Type:Maintenance\" \\\n  --body-file <body-file>\n```\n\n(`gh` commands need the sandbox disabled — they require the system keyring.)\n\n## Quick reference\n\n```bash\nREVA_VERSION=v2.48.0\ngh api repos/opencloud-eu/reva/commits/$REVA_VERSION --jq '.sha'                       # verify tag exists\nOC_VERSION=$(gh pr list --repo opencloud-eu/opencloud --head next-release/main --state open \\\n  --json title --jq '.[0].title' | grep -oE '[0-9]+\\.[0-9]+\\.[0-9]+' | head -1)         # from open release PR\ngo get github.com/opencloud-eu/reva/v2@$REVA_VERSION && go mod tidy && go mod vendor    # bump + re-vendor\n# edit pkg/version/version.go -> LatestTag = \"$OC_VERSION+dev\"\ngh api \"repos/opencloud-eu/reva/contents/CHANGELOG.md?ref=$REVA_VERSION\" --jq '.content' | base64 -d  # changelog\n```\n\n## Common mistakes\n\n- Running the bump before the reva release PR is merged — the tag won't exist and `go get` will fail. Verify the tag first (step 1).\n- Forgetting to re-run `go mod vendor` after `go mod tidy`, leaving `vendor/` out of sync with `go.mod`.\n- Asking for or hardcoding `OC_VERSION` — always derive it from the open `next-release/main` release PR (step 3); it can even be a new major after a breaking change.\n- Reading the changelog from reva `main` instead of the tag (`?ref=$REVA_VERSION`). Always pin to the tag.\n- Missing the `[full-ci] ` prefix in the PR title, the `Type:Maintenance` label, or the two summary bullets at the top of the body.\n- Dumping the full `vendor/` diff at the confirmation step instead of `go.mod` + `version.go` + a `--stat` summary.\n- Committing before the user confirms the diff.\n","frontmatter":{"name":"bumping-reva","description":"Use when the user asks to bump, update, or upgrade the OpenCloud reva dependency to a specific version (e.g. \"reva bump to 2.48.0\", \"bump reva to v2.48.0\"). Covers editing go.mod, re-vendoring, bumping the OpenCloud LatestTag, the single commit, and opening the PR against main."},"isInternal":false,"tokens":2216,"sizeBytes":8037},{"name":"SKILL.md","path":".agents/skills/bumping-web/SKILL.md","rawUrl":"https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/.agents/skills/bumping-web/SKILL.md","title":"bumping-web","category":"anthropic-skill","format":"markdown","content":"---\nname: bumping-web\ndescription: Use when the user asks to bump, update, or upgrade the OpenCloud web assets/frontend to a specific version (e.g. \"bump web to v7.0.0\", \"update web to v7.1.2\"). Covers editing the version files, the single commit, and opening the PR against the right branch.\n---\n\n# Bumping Web\n\n## Overview\n\nBumping web updates the pinned OpenCloud web frontend (assets + UI-test runner) to a tagged release of [opencloud-eu/web](https://github.com/opencloud-eu/web). It touches exactly two files, lands as one commit, and ships as a PR whose body is the web changelog for that version.\n\nTemplate PR: https://github.com/opencloud-eu/opencloud/pull/2733\n\n## Prerequisites\n\n- **`gh` (GitHub CLI), authenticated** — every lookup and the PR creation go through `gh api` / `gh pr`. Verify with `gh auth status`; if it fails, ask the user to run `gh auth login` (suggest `! gh auth login` so it runs in-session). Do not proceed without it.\n- `gh` needs the system keyring, so run all `gh` commands with the sandbox disabled.\n- `git` and `base64` (decoding the changelog) — standard on macOS/Linux.\n\n## What changes (exactly two files)\n\n| File                    | Variable             | New value                                        |\n| ----------------------- | -------------------- | ------------------------------------------------ |\n| `services/web/Makefile` | `WEB_ASSETS_VERSION` | the version tag, e.g. `v7.0.0`                   |\n| `services/web/Makefile` | `WEB_ASSETS_BRANCH`  | branch carrying the tag (`main` or `stable-X.Y`) |\n| `.woodpecker.env`       | `WEB_COMMITID`       | full commit sha the tag points to                |\n| `.woodpecker.env`       | `WEB_BRANCH`         | same branch as `WEB_ASSETS_BRANCH`               |\n\n`WEB_ASSETS_BRANCH` and `WEB_BRANCH` are always the same value.\n\n## Procedure\n\nLet `VERSION` be the requested tag (always normalize to a leading `v`, e.g. `v7.0.0`).\n\n### 1. Resolve the commit sha the tag points to\n\n```bash\ngh api repos/opencloud-eu/web/commits/$VERSION --jq '.sha'\n```\n\nThis full sha is the new `WEB_COMMITID`.\n\n### 2. Determine the branch (`main` vs `stable-X.Y`)\n\nThe branch is the line of development that carries the tag. Detect it:\n\n```bash\ngh api \"repos/opencloud-eu/web/compare/main...$VERSION\" --jq '.status'\n```\n\n- `identical` or `behind` → the tagged commit is reachable from `main` → use **`main`**.\n- `ahead` or `diverged` → the tag lives on a release line → use **`stable-X.Y`** matching the version's major.minor (e.g. `v7.1.2` → `stable-7.1`).\n\nSanity-check that the stable branch actually exists:\n\n```bash\ngh api repos/opencloud-eu/web/branches --paginate --jq '.[].name' | grep -E 'main|stable'\n```\n\nTypically a freshly released minor (`v7.1.0`) still sits on `main`, while later patches on an older line (`v7.0.3` after `7.1` exists) sit on `stable-7.0`.\n\n### 3. Fetch the changelog for the PR body\n\n```bash\ngh api \"repos/opencloud-eu/web/contents/CHANGELOG.md?ref=$VERSION\" --jq '.content' | base64 -d\n```\n\nTake **only the section for this version**. Match the template: start the PR body at the first content heading (e.g. `### 💥 Breaking changes` / `### 📈 Enhancement`) and drop the `# Changelog` title, the `## [x.y.z] - date` header, and the `### ❤️ Thanks to all contributors!` block. Stop before the next `## [...]` version header.\n\n### 4. Apply the edits\n\nEdit `services/web/Makefile` (`WEB_ASSETS_VERSION`, `WEB_ASSETS_BRANCH`) and `.woodpecker.env` (`WEB_COMMITID`, `WEB_BRANCH`).\n\n### 5. Pick the target branch for the PR\n\n- Major or minor release → target **`main`**.\n- Patch release → may need to target a stable branch instead. If the user did not specify, **ask them** which branch to target before continuing.\n\n### 6. Confirm before committing\n\nShow the user the diff of both files and the target branch, and ask them to confirm. Do not commit until they approve.\n\n### 7. Commit, push, open PR\n\n- Create a branch (do not commit on `main`).\n- One commit, conventional-commits format, **empty body**:\n  ```\n  chore: bump web to v7.0.0\n  ```\n- PR title: `[full-ci] chore: bump web to v7.0.0` (the commit message prefixed with `[full-ci] `).\n- PR base: the branch chosen in step 5.\n- PR body: the trimmed changelog from step 3.\n- Add the label `Type:Dependencies`.\n\n```bash\ngh pr create --base <target-branch> \\\n  --title \"[full-ci] chore: bump web to $VERSION\" \\\n  --label \"Type:Dependencies\" \\\n  --body-file <changelog-file>\n```\n\n(`gh` commands need the sandbox disabled — they require the system keyring.)\n\n## Quick reference\n\n```bash\nVERSION=v7.0.0\ngh api repos/opencloud-eu/web/commits/$VERSION --jq '.sha'                       # WEB_COMMITID\ngh api \"repos/opencloud-eu/web/compare/main...$VERSION\" --jq '.status'           # main vs stable\ngh api \"repos/opencloud-eu/web/contents/CHANGELOG.md?ref=$VERSION\" --jq '.content' | base64 -d  # changelog\n```\n\n## Common mistakes\n\n- Reading `WEB_COMMITID` or the changelog from web `main` instead of from the version tag (`?ref=$VERSION`). Always pin to the tag.\n- Leaving `WEB_ASSETS_BRANCH`/`WEB_BRANCH` on `main` for a patch that belongs on a stable line.\n- Forgetting `[full-ci] ` in the PR title or adding a commit body.\n- Committing before the user confirms the diff and target branch.\n","frontmatter":{"name":"bumping-web","description":"Use when the user asks to bump, update, or upgrade the OpenCloud web assets/frontend to a specific version (e.g. \"bump web to v7.0.0\", \"update web to v7.1.2\"). Covers editing the version files, the single commit, and opening the PR against the right branch."},"isInternal":false,"tokens":1422,"sizeBytes":5280},{"name":"README.md","path":"devtools/deployments/multi-tenancy/README.md","rawUrl":"https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/devtools/deployments/multi-tenancy/README.md","title":"multi-tenancy Documentation","category":"plugin-manifest","format":"markdown","content":"# Development/Test Deployment for a multi-tenacy setup\n\nThe docker compose files in this directory are derived from the\nopencloud-compose project and can be used to deploy a Development or Testing\nenvironment for a multi-tenancy setup of OpenCloud. It consists of the\nfollowing services:\n\n* `provisioning`: The OpenCloud graph service deployed in a standalone mode. It\n  is configured to provide the libregraph education API for managing tenants\n  and users. The `ldap-server`service (see below) is used to store the tenants\n  and users.\n* `ldap-server`: An OpenLDAP server that is used by the provisioning service to\n  store tenants and users. Used by the OpenCloud services as the user directory\n  (for looking up users and searching for sharees).\n* `keycloak`: The OpenID Connect Provider used for authenticating users. The\n  pre-loaded realm is configured to add `tenantid` claim into the identity and\n  access tokens. It's also currently consuming user from the `ldap-server`\n  (this federation will likely go away in the future and is optional for future\n  configurations).\n* `opencloud`: The OpenCloud configured so that is hides users from different\n  tenants from each other.\n\nTo deploy the setup, run:\n\n```bash\ndocker compose -f docker-compose.yml -f keycloak.yml -f ldap-server.yml -f traefik.yml up\n```\n\nOnce deployed you can use the `initialize_users.go` to create a couple of example\ntenants and some users in each tenant:\n\n* Tenant `Famous Coders` with users `dennis` and `grace`\n* Tenant `Scientists` with users `einstein` and `marie`\n\nThe passwords for the users is set to `demo` in keycloak\n\n```\n> go run initialize_users.go\nCreated tenant: Famous Coders with id fc58e19a-3a2a-4afc-90ec-8f94986db340\nCreated user: Dennis Ritchie with id ee1e14e7-b00b-4eec-8b03-a6bf0e29c77c\nCreated user: Grace Hopper with id a29f3afd-e4a3-4552-91e8-cc99e26bffce\nCreated tenant: Scientists with id 18406c53-e2d6-4e83-98b6-a55880eef195\nCreated user: Albert Einstein with id 12023d37-d6ce-4f19-a318-b70866f265ba\nCreated user: Marie Curie with id 30c3c825-c37d-4e85-8195-0142e4884872\nSetting password for user: grace\nSetting password for user: marie\nSetting password for user: dennis\nSetting password for user: einstein\n```\n","isInternal":false,"tokens":603,"sizeBytes":2222},{"name":"README.md","path":"devtools/deployments/opencloud_full/README.md","rawUrl":"https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/devtools/deployments/opencloud_full/README.md","title":"opencloud_full Documentation","category":"plugin-manifest","format":"markdown","content":"---\ndocument this deployment example in: docs/opencloud/deployment/opencloud_full.md\n---\n\n# OpenCloud WOPI Deployment Example\n\nThis deployment example is documented in two locations for different audiences:\n\n* In the [Admin Documentation](https://docs.opencloud.eu/docs/admin/intro)\\\n  Providing two variants using detailed configuration step by step guides:\\\n  [Docker Compose Setup](https://docs.opencloud.eu/docs/admin/getting-started/container/docker-compose) and [Docker Compose Local](https://docs.opencloud.eu/docs/admin/getting-started/container/docker-compose-local).\\\n  Note that these examples use LetsEncrypt certificates and are intended for production use.\n\n* In the [Developer Documentation](https://docs.opencloud.eu/docs/dev/intro)\\\n  Providing details which are more developer focused. This description can also be used when deviating from the default.\\\n  Note that this examples uses self signed certificates and is intended for testing purposes.\n\n\n","frontmatter":{"document this deployment example in":"docs/opencloud/deployment/opencloud_full.md"},"isInternal":false,"tokens":193,"sizeBytes":968},{"name":"README.md","path":"devtools/deployments/README.md","rawUrl":"https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/devtools/deployments/README.md","title":"deployments Documentation","category":"plugin-manifest","format":"markdown","content":"# Docker Compose Deployments for development use\n\nThe docker-compose deployments in this directory are for developement purposes only. They are\nnot actively maintained and not to be used in production.\n","isInternal":false,"tokens":38,"sizeBytes":202},{"name":"README.md","path":"vendor/github.com/go-micro/plugins/v4/client/grpc/README.md","rawUrl":"https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/vendor/github.com/go-micro/plugins/v4/client/grpc/README.md","title":"grpc Documentation","category":"plugin-manifest","format":"markdown","content":"# GRPC Client\n\nThe grpc client is a [micro.Client](https://godoc.org/github.com/micro/go-micro/client#Client) compatible client.\n\n## Overview\n\nThe client makes use of the [google.golang.org/grpc](google.golang.org/grpc) framework for the underlying communication mechanism.\n\n## Usage\n\nSpecify the client to your micro service\n\n```go\nimport (\n\t\"github.com/micro/go-micro\"\n\t\"github.com/micro/go-plugins/client/grpc\"\n)\n\nfunc main() {\n\tservice := micro.NewService(\n\t\tmicro.Name(\"greeter\"),\n\t\tmicro.Client(grpc.NewClient()),\n\t)\n}\n```\n","isInternal":false,"tokens":130,"sizeBytes":529},{"name":"README.md","path":"vendor/github.com/go-micro/plugins/v4/events/natsjs/README.md","rawUrl":"https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/vendor/github.com/go-micro/plugins/v4/events/natsjs/README.md","title":"natsjs Documentation","category":"plugin-manifest","format":"markdown","content":"# NATS JetStream\n\nThis plugin uses NATS with JetStream to send and receive events.\n","isInternal":false,"tokens":20,"sizeBytes":83},{"name":"README.md","path":"vendor/github.com/go-micro/plugins/v4/logger/zerolog/README.md","rawUrl":"https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/vendor/github.com/go-micro/plugins/v4/logger/zerolog/README.md","title":"zerolog Documentation","category":"plugin-manifest","format":"markdown","content":"# Zerolog\n\n[Zerolog](https://github.com/rs/zerolog) logger implementation for __go-micro__ [meta logger](https://github.com/micro/go-micro/tree/master/logger).\n\n## Usage\n\n```go\nfunc ExampleWithOut() {\n  logger.DefaultLogger = zerolog.NewLogger(logger.WithOutput(os.Stdout), logger.WithLevel(logger.DebugLevel))\n\n  logger.Infof(logger.InfoLevel, \"testing: %s\", \"Infof\")\n\n  // Output:\n  // {\"level\":\"info\",\"message\":\"testing: Infof\"}\n}\n```\n","isInternal":false,"tokens":115,"sizeBytes":438},{"name":"README.md","path":"vendor/github.com/go-micro/plugins/v4/server/grpc/README.md","rawUrl":"https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/vendor/github.com/go-micro/plugins/v4/server/grpc/README.md","title":"grpc Documentation","category":"plugin-manifest","format":"markdown","content":"# GRPC Server\n\nThe grpc server is a [micro.Server](https://pkg.go.dev/github.com/asim/go-micro/server#Server) compatible server.\n\n## Overview\n\nThe server makes use of the [google.golang.org/grpc](google.golang.org/grpc) framework for the underlying server \nbut continues to use micro handler signatures and protoc-gen-micro generated code.\n\n## Usage\n\nSpecify the server to your micro service\n\n```go\nimport (\n        \"go-micro.dev/v4\"\n        \"github.com/go-micro/plugins/v4/server/grpc\"\n)\n\nfunc main() {\n        service := micro.NewService(\n                // This needs to be first as it replaces the underlying server\n                // which causes any configuration set before it\n                // to be discarded\n                micro.Server(grpc.NewServer()),\n                micro.Name(\"greeter\"),\n        )\n}\n```\n**NOTE**: Setting the gRPC server and/or client causes the underlying the server/client to be replaced which causes any previous configuration set on that server/client to be discarded. It is therefore recommended to set gRPC server/client before any other configuration","isInternal":false,"tokens":225,"sizeBytes":1092},{"name":"README.md","path":"vendor/github.com/go-micro/plugins/v4/server/http/README.md","rawUrl":"https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/vendor/github.com/go-micro/plugins/v4/server/http/README.md","title":"http Documentation","category":"plugin-manifest","format":"markdown","content":"# HTTP Server\n\nThe HTTP Server is a go-micro.Server. It's a partial implementation which strips out codecs, transports, etc but enables you \nto create a HTTP Server that could potentially be used for REST based API services.\n\n## Usage\n\n```go\nimport (\n\t\"net/http\"\n\n\t\"github.com/micro/go-micro/server\"\n\thttpServer \"github.com/go-micro/plugins/v4/server/http\"\n)\n\nfunc main() {\n\tsrv := httpServer.NewServer(\n\t\tserver.Name(\"helloworld\"),\n\t)\n\n\tmux := http.NewServeMux()\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tw.Write([]byte(`hello world`))\n\t})\n\n\thd := srv.NewHandler(mux)\n\n\tsrv.Handle(hd)\n\tsrv.Start()\n\tsrv.Register()\n}\n```\n\nOr as part of a service\n\n```go\nimport (\n\t\"net/http\"\n\n\t\"go-micro.dev/v4\"\n\t\"github.com/micro/go-micro/server\"\n\thttpServer \"github.com/go-micro/plugins/v4/server/http\"\n)\n\nfunc main() {\n\tsrv := httpServer.NewServer(\n\t\tserver.Name(\"helloworld\"),\n\t)\n\n\tmux := http.NewServeMux()\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tw.Write([]byte(`hello world`))\n\t})\n\n\thd := srv.NewHandler(mux)\n\n\tsrv.Handle(hd)\n\n\tservice := micro.NewService(\n\t\tmicro.Server(srv),\n\t)\n\tservice.Init()\n\tservice.Run()\n}\n```\n","isInternal":false,"tokens":312,"sizeBytes":1164},{"name":"README.md","path":"vendor/github.com/go-micro/plugins/v4/store/nats-js-kv/README.md","rawUrl":"https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/vendor/github.com/go-micro/plugins/v4/store/nats-js-kv/README.md","title":"nats-js-kv Documentation","category":"plugin-manifest","format":"markdown","content":"# NATS JetStream Key Value Store Plugin\n\nThis plugin uses the NATS JetStream [KeyValue Store](https://docs.nats.io/nats-concepts/jetstream/key-value-store) to implement the Go-Micro store interface.\n\nYou can use this plugin like any other store plugin. \nTo start a local NATS JetStream server run `nats-server -js`.\n\nTo manually create a new storage object call:\n\n```go\nnatsjskv.NewStore(opts ...store.Option)\n```\n\nThe Go-Micro store interface uses databases and tables to store keys. These translate\nto buckets (key value stores) and key prefixes. If no database (bucket name) is provided, \"default\" will be used.\n\nYou can call `Write` with any arbitrary database name, and if a bucket with that name does not exist yet,\nit will be automatically created.\n\nIf a table name is provided, it will use it to prefix the key as `<table>_<key>`.\n\nTo delete a bucket, and all the key/value pairs in it, pass the `DeleteBucket` option to the `Delete`\nmethod, then they key name will be interpreted as a bucket name, and the bucket will be deleted.\n\nNext to the default store options, a few NATS specific options are available:\n\n\n```go\n// NatsOptions accepts nats.Options\nNatsOptions(opts nats.Options)\n\n// JetStreamOptions accepts multiple nats.JSOpt\nJetStreamOptions(opts ...nats.JSOpt)\n\n// KeyValueOptions accepts multiple nats.KeyValueConfig\n// This will create buckets with the provided configs at initialization.\n//\n// type KeyValueConfig struct {\n//    Bucket       string\n//   Description  string\n//   MaxValueSize int32\n//   History      uint8\n//   TTL          time.Duration\n//   MaxBytes     int64\n//   Storage      StorageType\n//   Replicas     int\n//   Placement    *Placement\n//   RePublish    *RePublish\n//   Mirror       *StreamSource\n//   Sources      []*StreamSource\n}\nKeyValueOptions(cfg ...*nats.KeyValueConfig)\n\n// DefaultTTL sets the default TTL to use for new buckets\n//  By default no TTL is set.\n//\n// TTL ON INDIVIDUAL WRITE CALLS IS NOT SUPPORTED, only bucket wide TTL.\n// Either set a default TTL with this option or provide bucket specific options\n//  with ObjectStoreOptions\nDefaultTTL(ttl time.Duration)\n\n// DefaultMemory sets the default storage type to memory only.\n//\n//  The default is file storage, persisting storage between service restarts.\n// Be aware that the default storage location of NATS the /tmp dir is, and thus\n//  won't persist reboots.\nDefaultMemory()\n\n// DefaultDescription sets the default description to use when creating new\n//  buckets. The default is \"Store managed by go-micro\"\nDefaultDescription(text string)\n\n// DeleteBucket will use the key passed to Delete as a bucket (database) name,\n//  and delete the bucket.\n// This option should not be combined with the store.DeleteFrom option, as\n//  that will overwrite the delete action.\nDeleteBucket()\n```\n\n","isInternal":false,"tokens":659,"sizeBytes":2803},{"name":"README.md","path":"vendor/github.com/go-micro/plugins/v4/store/nats-js/README.md","rawUrl":"https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/vendor/github.com/go-micro/plugins/v4/store/nats-js/README.md","title":"nats-js Documentation","category":"plugin-manifest","format":"markdown","content":"# NATS JetStream Store Plugin\n\n> **WARNING**: NATS Object Storage is still marked as an experimental preview.\n\nThis plugin uses the NATS JetStream [Object Store](https://docs.nats.io/nats-concepts/jetstream/obj_store) to implement the Go-Micro store interface.\n\nThis enables a key/value store with unlimited message size, allowing you to store files or data of any size under a single key.\n\nYou can use this plugin like any other store plugin. \nTo start a local NATS JetStream server run `nats-server -js`.\n\nTo manually create a new storage object call:\n\n```go\nnatsjs.NewStore(opts ...store.Option)\n```\n\nThe Go-Micro store interface uses databases and tables to store keys. These translate\nto buckets (object stores) and key prefixes. If no database (bucket name) is provided, \"default\" will be used.\n\nYou can call `Write` with any arbitrary database name, and if a bucket with that name does not exist yet,\nit will be automatically created.\n\nIf a table name is provided, it will use it to prefix the key as `<table>_<key>`.\n\nTo delete a bucket, and all the key/value pairs in it, pass the `DeleteBucket` option to the `Delete`\nmethod, then they key name will be interpreted as a bucket name, and the bucket will be deleted.\n\nNext to the default store options, a few NATS specific options are available:\n\n\n```go\n// NatsOptions accepts nats.Options\nNatsOptions(opts nats.Options)\n\n// JetStreamOptions accepts multiple nats.JSOpt\nJetStreamOptions(opts ...nats.JSOpt)\n\n// ObjectStoreOptions accepts multiple nats.ObjectStoreConfigs\n// This will create buckets with the provided configs at initialization.\n//\n// type ObjectStoreConfig struct {\n// \tBucket      string\n// \tDescription string\n// \tTTL         time.Duration\n// \tMaxBytes    int64\n// \tStorage     StorageType (either memory or file storage)\n// \tReplicas    int\n// \tPlacement   *Placement\n// }\n//\nObjectStoreOptions(cfg ...*nats.ObjectStoreConfig)\n\n// DefaultTTL sets the default TTL to use for new buckets\n//  By default no TTL is set.\n//\n// TTL ON INDIVIDUAL WRITE CALLS IS NOT SUPPORTED, only bucket wide TTL.\n// Either set a default TTL with this option or provide bucket specific options\n//  with ObjectStoreOptions\nDefaultTTL(ttl time.Duration)\n\n// DefaultMemory sets the default storage type to memory only.\n//\n//  The default is file storage, persisting storage between service restarts.\n// Be aware that the default storage location of NATS the /tmp dir is, and thus\n//  won't persist reboots.\nDefaultMemory()\n\n// DefaultDescription sets the default description to use when creating new\n//  buckets. The default is \"Store managed by go-micro\"\nDefaultDescription(text string)\n\n// DeleteBucket will use the key passed to Delete as a bucket (database) name,\n//  and delete the bucket.\n// This option should not be combined with the store.DeleteFrom option, as\n//  that will overwrite the delete action.\nDeleteBucket()\n```\n\n","isInternal":false,"tokens":673,"sizeBytes":2885},{"name":"README.md","path":"vendor/github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus/README.md","rawUrl":"https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/vendor/github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus/README.md","title":"prometheus Documentation","category":"plugin-manifest","format":"markdown","content":"# prometheus Documentation\n\nPath: `vendor/github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/vendor/github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus/README.md)","tokens":300,"sizeBytes":284},{"name":"README.md","path":"vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/README.md","rawUrl":"https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/README.md","title":"opentelemetry Documentation","category":"plugin-manifest","format":"markdown","content":"# opentelemetry Documentation\n\nPath: `vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/README.md)","tokens":300,"sizeBytes":283}],"systemPromptSnippet":"<yakaai_skills repo=\"opencloud-eu/opencloud\">\n<!-- File: .agents/skills/bumping-reva/SKILL.md (Tokens: ~2216 | Category: anthropic-skill) -->\n---\nname: bumping-reva\ndescription: Use when the user asks to bump, update, or upgrade the OpenCloud reva dependency to a specific version (e.g. \"reva bump to 2.48.0\", \"bump reva to v2.48.0\"). Covers editing go.mod, re-vendoring, bumping the OpenCloud LatestTag, the single commit, and opening the PR against main.\n---\n\n# Bumping Reva\n\n## Overview\n\nBumping reva updates the pinned [opencloud-eu/reva](https://github.com/opencloud-eu/reva) dependency (`github.com/opencloud-eu/reva/v2`) to a tagged release, re-vendors the module graph, and bumps the OpenCloud dev version. It touches `go.mod`, `go.sum`, `vendor/**` and `pkg/version/version.go`, lands as one commit, and ships as a PR whose body is the reva changelog for that version.\n\nTemplate PR: https://github.com/opencloud-eu/opencloud/pull/3127\n\n## Prerequisites\n\n- **The reva release must already be tagged.** A reva release is cut by merging its release PR (title `🎉 Release X.Y.Z`, branch `next-release/main`). The **user merges that PR themselves** — this skill starts *after* the tag `vX.Y.Z` exists. Verify the tag before doing anything (step 1); if it's missing, stop and ask the user to merge the reva release PR first.\n- **`gh` (GitHub CLI), authenticated** — tag lookup and PR creation go through `gh api` / `gh pr`. Verify with `gh auth status`; if it fails, ask the user to run `gh auth login` (suggest `! gh auth login` so it runs in-session).\n- `gh` needs the system keyring, so run all `gh` commands with the sandbox disabled.\n- **Go toolchain + network** — `go get` / `go mod tidy` / `go mod vendor` hit the Go module proxy. Run them with the sandbox disabled (network access).\n- `git` and `base64` (decoding the changelog) — standard on macOS/Linux.\n\n## Inputs\n\n- `REVA_VERSION` — the new reva tag, always normalized to a leading `v` (e.g. `v2.48.0`). If the user didn't give it, ask (or take the latest reva release tag).\n- `OC_VERSION` — the OpenCloud target for `LatestTag`, **without** the `+dev` suffix (e.g. `7.4.0`). **Do not ask or guess** — derive it from the open OpenCloud release PR (step 3). It can be a new major (e.g. `8.0.0`) when release-please picked up a breaking change.\n\n## What changes\n\n| File                     | What                                                                 |\n| ------------------------ | ------------------------------------------------------------------- |\n| `go.mod`                 | `github.com/opencloud-eu/reva/v2` → `REVA_VERSION` (+ indirect deps pulled by `go mod tidy`) |\n| `go.sum`                 | updated by `go get` / `go mod tidy`                                  |\n| `vendor/**`              | re-vendored by `go mod vendor` (incl. `vendor/modules.txt`)         |\n| `pkg/version/version.go` | `LatestTag = \"<OC_VERSION>+dev\"`                                     |\n\n## Procedure\n\n### 1. Verify the reva tag exists\n\n```bash\ngh api repos/opencloud-eu/reva/commits/$REVA_VERSION --jq '.sha'\n```\n\n- Success (a sha) → the release is tagged, continue.\n- `422`/`404` → the tag does not exist yet. The reva release PR (`🎉 Release X.Y.Z`) is probably not merged. **Stop** and tell the user to merge it first. Helpful checks:\n  ```bash\n  gh api repos/opencloud-eu/reva/releases/latest --jq '.tag_name'   # current latest tag\n  gh pr list --repo opencloud-eu/reva --search '🎉 Release in:title' --state open --json number,title\n  ```\n\n### 2. Bump the dependency and re-vendor\n\n```bash\ngo get github.com/opencloud-eu/reva/v2@$REVA_VERSION\ngo mod tidy\ngo mod vendor\n```\n\n(Sandbox disabled — these need network.) Notes:\n- Right after a fresh tag the module proxy can lag; if `go get` reports the version as unknown, retry, or use `GOPROXY=direct go get github.com/opencloud-eu/reva/v2@$REVA_VERSION`.\n- `go mod tidy` will also bump indirect dependencies that reva pulled in — that is expected (the template PR did the same).\n\n### 3. Bump the OpenCloud dev version\n\n`OC_VERSION` is the version of the **open OpenCloud release PR** — the release-please PR from branch `next-release/main`, titled `🎉 Release X.Y.Z` (e.g. #3143). Derive it, don't ask:\n\n```bash\ngh pr list --repo opencloud-eu/opencloud --head next-release/main --state open \\\n  --json title --jq '.[0].title' | grep -oE '[0-9]+\\.[0-9]+\\.[0-9]+' | head -1\n```\n\nThis is the next release target and tracks breaking changes — it may be a new major (e.g. `8.0.0`), not just a minor bump. If no such PR is open, stop and ask the user.\n\nEdit `pkg/version/version.go`:\n\n```go\nLatestTag = \"<OC_VERSION>+dev\"   // e.g. \"7.4.0+dev\"\n```\n\n### 4. Fetch the reva changelog for the PR body\n\n```bash\ngh api \"repos/opencloud-eu/reva/contents/CHANGELOG.md?ref=$REVA_VERSION\" --jq '.content' | base64 -d\n```\n\nTake **only the section for this version** and trim it exactly like the web bump: start at the first content heading (`### 🐛 Bug Fixes` / `### 📈 Enhancement` / `### 💥 Breaking changes`), drop the `# Changelog` title, the `## [x.y.z] - date` header and the `### ❤️ Thanks to all contributors!` block, and stop before the next `## [...]` version header.\n\nThen **prepend two summary bullets** so the final PR body is:\n\n```\n- bump opencloud version to <OC_VERSION>\n- reva bump <REVA_VERSION without the leading v>\n\n### 🐛 Bug Fixes\n...trimmed reva changelog...\n```\n\nWrite this to a file for `--body-file` (e.g. in the scratchpad).\n\n### 5. Confirm before committing\n\nThe `vendor/` diff is huge — do **not** dump it. Show the user:\n\n```bash\ngit diff go.mod pkg/version/version.go        # the meaningful edits\ngit diff --stat | tail -1                      # vendor churn summary\n```\n\nConfirm the reva line in `go.mod` is exactly `github.com/opencloud-eu/reva/v2 REVA_VERSION`, show the target branch (`main`), and the PR body. **Do not commit until the user approves.**\n\n### 6. Commit, push, open PR\n\n- Create a branch (do not commit on `main`), e.g. `reva-bump-2.48.0`.\n- Stage everything the bump touched: `git add go.mod go.sum vendor pkg/version/version.go`.\n- One commit, conventional-commits format, **empty body**:\n  ```\n  chore: bump reva to 2.48.0\n  ```\n- PR base: **`main`** (reva bumps always target main).\n- PR title: `[full-ci] chore: bump reva to 2.48.0` (the commit message prefixed with `[full-ci] `).\n- PR body: the file from step 4.\n- Add the label `Type:Maintenance`.\n\n```bash\ngh pr create --base main \\\n  --title \"[full-ci] chore: bump reva to $REVA_VERSION_NO_V\" \\\n  --label \"Type:Maintenance\" \\\n  --body-file <body-file>\n```\n\n(`gh` commands need the sandbox disabled — they require the system keyring.)\n\n## Quick reference\n\n```bash\nREVA_VERSION=v2.48.0\ngh api repos/opencloud-eu/reva/commits/$REVA_VERSION --jq '.sha'                       # verify tag exists\nOC_VERSION=$(gh pr list --repo opencloud-eu/opencloud --head next-release/main --state open \\\n  --json title --jq '.[0].title' | grep -oE '[0-9]+\\.[0-9]+\\.[0-9]+' | head -1)         # from open release PR\ngo get github.com/opencloud-eu/reva/v2@$REVA_VERSION && go mod tidy && go mod vendor    # bump + re-vendor\n# edit pkg/version/version.go -> LatestTag = \"$OC_VERSION+dev\"\ngh api \"repos/opencloud-eu/reva/contents/CHANGELOG.md?ref=$REVA_VERSION\" --jq '.content' | base64 -d  # changelog\n```\n\n## Common mistakes\n\n- Running the bump before the reva release PR is merged — the tag won't exist and `go get` will fail. Verify the tag first (step 1).\n- Forgetting to re-run `go mod vendor` after `go mod tidy`, leaving `vendor/` out of sync with `go.mod`.\n- Asking for or hardcoding `OC_VERSION` — always derive it from the open `next-release/main` release PR (step 3); it can even be a new major after a breaking change.\n- Reading the changelog from reva `main` instead of the tag (`?ref=$REVA_VERSION`). Always pin to the tag.\n- Missing the `[full-ci] ` prefix in the PR title, the `Type:Maintenance` label, or the two summary bullets at the top of the body.\n- Dumping the full `vendor/` diff at the confirmation step instead of `go.mod` + `version.go` + a `--stat` summary.\n- Committing before the user confirms the diff.\n\n<!-- File: .agents/skills/bumping-web/SKILL.md (Tokens: ~1422 | Category: anthropic-skill) -->\n---\nname: bumping-web\ndescription: Use when the user asks to bump, update, or upgrade the OpenCloud web assets/frontend to a specific version (e.g. \"bump web to v7.0.0\", \"update web to v7.1.2\"). Covers editing the version files, the single commit, and opening the PR against the right branch.\n---\n\n# Bumping Web\n\n## Overview\n\nBumping web updates the pinned OpenCloud web frontend (assets + UI-test runner) to a tagged release of [opencloud-eu/web](https://github.com/opencloud-eu/web). It touches exactly two files, lands as one commit, and ships as a PR whose body is the web changelog for that version.\n\nTemplate PR: https://github.com/opencloud-eu/opencloud/pull/2733\n\n## Prerequisites\n\n- **`gh` (GitHub CLI), authenticated** — every lookup and the PR creation go through `gh api` / `gh pr`. Verify with `gh auth status`; if it fails, ask the user to run `gh auth login` (suggest `! gh auth login` so it runs in-session). Do not proceed without it.\n- `gh` needs the system keyring, so run all `gh` commands with the sandbox disabled.\n- `git` and `base64` (decoding the changelog) — standard on macOS/Linux.\n\n## What changes (exactly two files)\n\n| File                    | Variable             | New value                                        |\n| ----------------------- | -------------------- | ------------------------------------------------ |\n| `services/web/Makefile` | `WEB_ASSETS_VERSION` | the version tag, e.g. `v7.0.0`                   |\n| `services/web/Makefile` | `WEB_ASSETS_BRANCH`  | branch carrying the tag (`main` or `stable-X.Y`) |\n| `.woodpecker.env`       | `WEB_COMMITID`       | full commit sha the tag points to                |\n| `.woodpecker.env`       | `WEB_BRANCH`         | same branch as `WEB_ASSETS_BRANCH`               |\n\n`WEB_ASSETS_BRANCH` and `WEB_BRANCH` are always the same value.\n\n## Procedure\n\nLet `VERSION` be the requested tag (always normalize to a leading `v`, e.g. `v7.0.0`).\n\n### 1. Resolve the commit sha the tag points to\n\n```bash\ngh api repos/opencloud-eu/web/commits/$VERSION --jq '.sha'\n```\n\nThis full sha is the new `WEB_COMMITID`.\n\n### 2. Determine the branch (`main` vs `stable-X.Y`)\n\nThe branch is the line of development that carries the tag. Detect it:\n\n```bash\ngh api \"repos/opencloud-eu/web/compare/main...$VERSION\" --jq '.status'\n```\n\n- `identical` or `behind` → the tagged commit is reachable from `main` → use **`main`**.\n- `ahead` or `diverged` → the tag lives on a release line → use **`stable-X.Y`** matching the version's major.minor (e.g. `v7.1.2` → `stable-7.1`).\n\nSanity-check that the stable branch actually exists:\n\n```bash\ngh api repos/opencloud-eu/web/branches --paginate --jq '.[].name' | grep -E 'main|stable'\n```\n\nTypically a freshly released minor (`v7.1.0`) still sits on `main`, while later patches on an older line (`v7.0.3` after `7.1` exists) sit on `stable-7.0`.\n\n### 3. Fetch the changelog for the PR body\n\n```bash\ngh api \"repos/opencloud-eu/web/contents/CHANGELOG.md?ref=$VERSION\" --jq '.content' | base64 -d\n```\n\nTake **only the section for this version**. Match the template: start the PR body at the first content heading (e.g. `### 💥 Breaking changes` / `### 📈 Enhancement`) and drop the `# Changelog` title, the `## [x.y.z] - date` header, and the `### ❤️ Thanks to all contributors!` block. Stop before the next `## [...]` version header.\n\n### 4. Apply the edits\n\nEdit `services/web/Makefile` (`WEB_ASSETS_VERSION`, `WEB_ASSETS_BRANCH`) and `.woodpecker.env` (`WEB_COMMITID`, `WEB_BRANCH`).\n\n### 5. Pick the target branch for the PR\n\n- Major or minor release → target **`main`**.\n- Patch release → may need to target a stable branch instead. If the user did not specify, **ask them** which branch to target before continuing.\n\n### 6. Confirm before committing\n\nShow the user the diff of both files and the target branch, and ask them to confirm. Do not commit until they approve.\n\n### 7. Commit, push, open PR\n\n- Create a branch (do not commit on `main`).\n- One commit, conventional-commits format, **empty body**:\n  ```\n  chore: bump web to v7.0.0\n  ```\n- PR title: `[full-ci] chore: bump web to v7.0.0` (the commit message prefixed with `[full-ci] `).\n- PR base: the branch chosen in step 5.\n- PR body: the trimmed changelog from step 3.\n- Add the label `Type:Dependencies`.\n\n```bash\ngh pr create --base <target-branch> \\\n  --title \"[full-ci] chore: bump web to $VERSION\" \\\n  --label \"Type:Dependencies\" \\\n  --body-file <changelog-file>\n```\n\n(`gh` commands need the sandbox disabled — they require the system keyring.)\n\n## Quick reference\n\n```bash\nVERSION=v7.0.0\ngh api repos/opencloud-eu/web/commits/$VERSION --jq '.sha'                       # WEB_COMMITID\ngh api \"repos/opencloud-eu/web/compare/main...$VERSION\" --jq '.status'           # main vs stable\ngh api \"repos/opencloud-eu/web/contents/CHANGELOG.md?ref=$VERSION\" --jq '.content' | base64 -d  # changelog\n```\n\n## Common mistakes\n\n- Reading `WEB_COMMITID` or the changelog from web `main` instead of from the version tag (`?ref=$VERSION`). Always pin to the tag.\n- Leaving `WEB_ASSETS_BRANCH`/`WEB_BRANCH` on `main` for a patch that belongs on a stable line.\n- Forgetting `[full-ci] ` in the PR title or adding a commit body.\n- Committing before the user confirms the diff and target branch.\n\n<!-- File: devtools/deployments/multi-tenancy/README.md (Tokens: ~603 | Category: plugin-manifest) -->\n# Development/Test Deployment for a multi-tenacy setup\n\nThe docker compose files in this directory are derived from the\nopencloud-compose project and can be used to deploy a Development or Testing\nenvironment for a multi-tenancy setup of OpenCloud. It consists of the\nfollowing services:\n\n* `provisioning`: The OpenCloud graph service deployed in a standalone mode. It\n  is configured to provide the libregraph education API for managing tenants\n  and users. The `ldap-server`service (see below) is used to store the tenants\n  and users.\n* `ldap-server`: An OpenLDAP server that is used by the provisioning service to\n  store tenants and users. Used by the OpenCloud services as the user directory\n  (for looking up users and searching for sharees).\n* `keycloak`: The OpenID Connect Provider used for authenticating users. The\n  pre-loaded realm is configured to add `tenantid` claim into the identity and\n  access tokens. It's also currently consuming user from the `ldap-server`\n  (this federation will likely go away in the future and is optional for future\n  configurations).\n* `opencloud`: The OpenCloud configured so that is hides users from different\n  tenants from each other.\n\nTo deploy the setup, run:\n\n```bash\ndocker compose -f docker-compose.yml -f keycloak.yml -f ldap-server.yml -f traefik.yml up\n```\n\nOnce deployed you can use the `initialize_users.go` to create a couple of example\ntenants and some users in each tenant:\n\n* Tenant `Famous Coders` with users `dennis` and `grace`\n* Tenant `Scientists` with users `einstein` and `marie`\n\nThe passwords for the users is set to `demo` in keycloak\n\n```\n> go run initialize_users.go\nCreated tenant: Famous Coders with id fc58e19a-3a2a-4afc-90ec-8f94986db340\nCreated user: Dennis Ritchie with id ee1e14e7-b00b-4eec-8b03-a6bf0e29c77c\nCreated user: Grace Hopper with id a29f3afd-e4a3-4552-91e8-cc99e26bffce\nCreated tenant: Scientists with id 18406c53-e2d6-4e83-98b6-a55880eef195\nCreated user: Albert Einstein with id 12023d37-d6ce-4f19-a318-b70866f265ba\nCreated user: Marie Curie with id 30c3c825-c37d-4e85-8195-0142e4884872\nSetting password for user: grace\nSetting password for user: marie\nSetting password for user: dennis\nSetting password for user: einstein\n```\n\n<!-- File: devtools/deployments/opencloud_full/README.md (Tokens: ~193 | Category: plugin-manifest) -->\n---\ndocument this deployment example in: docs/opencloud/deployment/opencloud_full.md\n---\n\n# OpenCloud WOPI Deployment Example\n\nThis deployment example is documented in two locations for different audiences:\n\n* In the [Admin Documentation](https://docs.opencloud.eu/docs/admin/intro)\\\n  Providing two variants using detailed configuration step by step guides:\\\n  [Docker Compose Setup](https://docs.opencloud.eu/docs/admin/getting-started/container/docker-compose) and [Docker Compose Local](https://docs.opencloud.eu/docs/admin/getting-started/container/docker-compose-local).\\\n  Note that these examples use LetsEncrypt certificates and are intended for production use.\n\n* In the [Developer Documentation](https://docs.opencloud.eu/docs/dev/intro)\\\n  Providing details which are more developer focused. This description can also be used when deviating from the default.\\\n  Note that this examples uses self signed certificates and is intended for testing purposes.\n\n<!-- File: devtools/deployments/README.md (Tokens: ~38 | Category: plugin-manifest) -->\n# Docker Compose Deployments for development use\n\nThe docker-compose deployments in this directory are for developement purposes only. They are\nnot actively maintained and not to be used in production.\n\n<!-- File: vendor/github.com/go-micro/plugins/v4/client/grpc/README.md (Tokens: ~130 | Category: plugin-manifest) -->\n# GRPC Client\n\nThe grpc client is a [micro.Client](https://godoc.org/github.com/micro/go-micro/client#Client) compatible client.\n\n## Overview\n\nThe client makes use of the [google.golang.org/grpc](google.golang.org/grpc) framework for the underlying communication mechanism.\n\n## Usage\n\nSpecify the client to your micro service\n\n```go\nimport (\n\t\"github.com/micro/go-micro\"\n\t\"github.com/micro/go-plugins/client/grpc\"\n)\n\nfunc main() {\n\tservice := micro.NewService(\n\t\tmicro.Name(\"greeter\"),\n\t\tmicro.Client(grpc.NewClient()),\n\t)\n}\n```\n\n<!-- File: vendor/github.com/go-micro/plugins/v4/events/natsjs/README.md (Tokens: ~20 | Category: plugin-manifest) -->\n# NATS JetStream\n\nThis plugin uses NATS with JetStream to send and receive events.\n\n<!-- File: vendor/github.com/go-micro/plugins/v4/logger/zerolog/README.md (Tokens: ~115 | Category: plugin-manifest) -->\n# Zerolog\n\n[Zerolog](https://github.com/rs/zerolog) logger implementation for __go-micro__ [meta logger](https://github.com/micro/go-micro/tree/master/logger).\n\n## Usage\n\n```go\nfunc ExampleWithOut() {\n  logger.DefaultLogger = zerolog.NewLogger(logger.WithOutput(os.Stdout), logger.WithLevel(logger.DebugLevel))\n\n  logger.Infof(logger.InfoLevel, \"testing: %s\", \"Infof\")\n\n  // Output:\n  // {\"level\":\"info\",\"message\":\"testing: Infof\"}\n}\n```\n\n<!-- File: vendor/github.com/go-micro/plugins/v4/server/grpc/README.md (Tokens: ~225 | Category: plugin-manifest) -->\n# GRPC Server\n\nThe grpc server is a [micro.Server](https://pkg.go.dev/github.com/asim/go-micro/server#Server) compatible server.\n\n## Overview\n\nThe server makes use of the [google.golang.org/grpc](google.golang.org/grpc) framework for the underlying server \nbut continues to use micro handler signatures and protoc-gen-micro generated code.\n\n## Usage\n\nSpecify the server to your micro service\n\n```go\nimport (\n        \"go-micro.dev/v4\"\n        \"github.com/go-micro/plugins/v4/server/grpc\"\n)\n\nfunc main() {\n        service := micro.NewService(\n                // This needs to be first as it replaces the underlying server\n                // which causes any configuration set before it\n                // to be discarded\n                micro.Server(grpc.NewServer()),\n                micro.Name(\"greeter\"),\n        )\n}\n```\n**NOTE**: Setting the gRPC server and/or client causes the underlying the server/client to be replaced which causes any previous configuration set on that server/client to be discarded. It is therefore recommended to set gRPC server/client before any other configuration\n\n<!-- File: vendor/github.com/go-micro/plugins/v4/server/http/README.md (Tokens: ~312 | Category: plugin-manifest) -->\n# HTTP Server\n\nThe HTTP Server is a go-micro.Server. It's a partial implementation which strips out codecs, transports, etc but enables you \nto create a HTTP Server that could potentially be used for REST based API services.\n\n## Usage\n\n```go\nimport (\n\t\"net/http\"\n\n\t\"github.com/micro/go-micro/server\"\n\thttpServer \"github.com/go-micro/plugins/v4/server/http\"\n)\n\nfunc main() {\n\tsrv := httpServer.NewServer(\n\t\tserver.Name(\"helloworld\"),\n\t)\n\n\tmux := http.NewServeMux()\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tw.Write([]byte(`hello world`))\n\t})\n\n\thd := srv.NewHandler(mux)\n\n\tsrv.Handle(hd)\n\tsrv.Start()\n\tsrv.Register()\n}\n```\n\nOr as part of a service\n\n```go\nimport (\n\t\"net/http\"\n\n\t\"go-micro.dev/v4\"\n\t\"github.com/micro/go-micro/server\"\n\thttpServer \"github.com/go-micro/plugins/v4/server/http\"\n)\n\nfunc main() {\n\tsrv := httpServer.NewServer(\n\t\tserver.Name(\"helloworld\"),\n\t)\n\n\tmux := http.NewServeMux()\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tw.Write([]byte(`hello world`))\n\t})\n\n\thd := srv.NewHandler(mux)\n\n\tsrv.Handle(hd)\n\n\tservice := micro.NewService(\n\t\tmicro.Server(srv),\n\t)\n\tservice.Init()\n\tservice.Run()\n}\n```\n\n<!-- File: vendor/github.com/go-micro/plugins/v4/store/nats-js-kv/README.md (Tokens: ~659 | Category: plugin-manifest) -->\n# NATS JetStream Key Value Store Plugin\n\nThis plugin uses the NATS JetStream [KeyValue Store](https://docs.nats.io/nats-concepts/jetstream/key-value-store) to implement the Go-Micro store interface.\n\nYou can use this plugin like any other store plugin. \nTo start a local NATS JetStream server run `nats-server -js`.\n\nTo manually create a new storage object call:\n\n```go\nnatsjskv.NewStore(opts ...store.Option)\n```\n\nThe Go-Micro store interface uses databases and tables to store keys. These translate\nto buckets (key value stores) and key prefixes. If no database (bucket name) is provided, \"default\" will be used.\n\nYou can call `Write` with any arbitrary database name, and if a bucket with that name does not exist yet,\nit will be automatically created.\n\nIf a table name is provided, it will use it to prefix the key as `<table>_<key>`.\n\nTo delete a bucket, and all the key/value pairs in it, pass the `DeleteBucket` option to the `Delete`\nmethod, then they key name will be interpreted as a bucket name, and the bucket will be deleted.\n\nNext to the default store options, a few NATS specific options are available:\n\n\n```go\n// NatsOptions accepts nats.Options\nNatsOptions(opts nats.Options)\n\n// JetStreamOptions accepts multiple nats.JSOpt\nJetStreamOptions(opts ...nats.JSOpt)\n\n// KeyValueOptions accepts multiple nats.KeyValueConfig\n// This will create buckets with the provided configs at initialization.\n//\n// type KeyValueConfig struct {\n//    Bucket       string\n//   Description  string\n//   MaxValueSize int32\n//   History      uint8\n//   TTL          time.Duration\n//   MaxBytes     int64\n//   Storage      StorageType\n//   Replicas     int\n//   Placement    *Placement\n//   RePublish    *RePublish\n//   Mirror       *StreamSource\n//   Sources      []*StreamSource\n}\nKeyValueOptions(cfg ...*nats.KeyValueConfig)\n\n// DefaultTTL sets the default TTL to use for new buckets\n//  By default no TTL is set.\n//\n// TTL ON INDIVIDUAL WRITE CALLS IS NOT SUPPORTED, only bucket wide TTL.\n// Either set a default TTL with this option or provide bucket specific options\n//  with ObjectStoreOptions\nDefaultTTL(ttl time.Duration)\n\n// DefaultMemory sets the default storage type to memory only.\n//\n//  The default is file storage, persisting storage between service restarts.\n// Be aware that the default storage location of NATS the /tmp dir is, and thus\n//  won't persist reboots.\nDefaultMemory()\n\n// DefaultDescription sets the default description to use when creating new\n//  buckets. The default is \"Store managed by go-micro\"\nDefaultDescription(text string)\n\n// DeleteBucket will use the key passed to Delete as a bucket (database) name,\n//  and delete the bucket.\n// This option should not be combined with the store.DeleteFrom option, as\n//  that will overwrite the delete action.\nDeleteBucket()\n```\n\n<!-- File: vendor/github.com/go-micro/plugins/v4/store/nats-js/README.md (Tokens: ~673 | Category: plugin-manifest) -->\n# NATS JetStream Store Plugin\n\n> **WARNING**: NATS Object Storage is still marked as an experimental preview.\n\nThis plugin uses the NATS JetStream [Object Store](https://docs.nats.io/nats-concepts/jetstream/obj_store) to implement the Go-Micro store interface.\n\nThis enables a key/value store with unlimited message size, allowing you to store files or data of any size under a single key.\n\nYou can use this plugin like any other store plugin. \nTo start a local NATS JetStream server run `nats-server -js`.\n\nTo manually create a new storage object call:\n\n```go\nnatsjs.NewStore(opts ...store.Option)\n```\n\nThe Go-Micro store interface uses databases and tables to store keys. These translate\nto buckets (object stores) and key prefixes. If no database (bucket name) is provided, \"default\" will be used.\n\nYou can call `Write` with any arbitrary database name, and if a bucket with that name does not exist yet,\nit will be automatically created.\n\nIf a table name is provided, it will use it to prefix the key as `<table>_<key>`.\n\nTo delete a bucket, and all the key/value pairs in it, pass the `DeleteBucket` option to the `Delete`\nmethod, then they key name will be interpreted as a bucket name, and the bucket will be deleted.\n\nNext to the default store options, a few NATS specific options are available:\n\n\n```go\n// NatsOptions accepts nats.Options\nNatsOptions(opts nats.Options)\n\n// JetStreamOptions accepts multiple nats.JSOpt\nJetStreamOptions(opts ...nats.JSOpt)\n\n// ObjectStoreOptions accepts multiple nats.ObjectStoreConfigs\n// This will create buckets with the provided configs at initialization.\n//\n// type ObjectStoreConfig struct {\n// \tBucket      string\n// \tDescription string\n// \tTTL         time.Duration\n// \tMaxBytes    int64\n// \tStorage     StorageType (either memory or file storage)\n// \tReplicas    int\n// \tPlacement   *Placement\n// }\n//\nObjectStoreOptions(cfg ...*nats.ObjectStoreConfig)\n\n// DefaultTTL sets the default TTL to use for new buckets\n//  By default no TTL is set.\n//\n// TTL ON INDIVIDUAL WRITE CALLS IS NOT SUPPORTED, only bucket wide TTL.\n// Either set a default TTL with this option or provide bucket specific options\n//  with ObjectStoreOptions\nDefaultTTL(ttl time.Duration)\n\n// DefaultMemory sets the default storage type to memory only.\n//\n//  The default is file storage, persisting storage between service restarts.\n// Be aware that the default storage location of NATS the /tmp dir is, and thus\n//  won't persist reboots.\nDefaultMemory()\n\n// DefaultDescription sets the default description to use when creating new\n//  buckets. The default is \"Store managed by go-micro\"\nDefaultDescription(text string)\n\n// DeleteBucket will use the key passed to Delete as a bucket (database) name,\n//  and delete the bucket.\n// This option should not be combined with the store.DeleteFrom option, as\n//  that will overwrite the delete action.\nDeleteBucket()\n```\n\n<!-- File: vendor/github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus/README.md (Tokens: ~300 | Category: plugin-manifest) -->\n# prometheus Documentation\n\nPath: `vendor/github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/vendor/github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus/README.md)\n\n<!-- File: vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/README.md (Tokens: ~300 | Category: plugin-manifest) -->\n# opentelemetry Documentation\n\nPath: `vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/opencloud-eu/opencloud/HEAD/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/README.md)\n</yakaai_skills>"}