Skip to content
Denofy
Esc
  • Pages

    Browse all packages
  • Verified packages
  • New packages
  • Collections
  • Documentation
  • CLI reference
  • How verification works
  • Publish a skill
↑↓ to navigate · Enter to open

Publish a package

Repository layout, SKILL.md frontmatter, package types, versioning, GitHub import, the Sync button and webhooks.

Packages are imported from public GitHub repositories. Denofy downloads the repository at an exact commit, verifies the package folder and stores it as an immutable tarball. You never upload files by hand, so every version can be traced back to a commit.

Repository layout#

One repository can hold any number of packages; each package is a folder (or the repository root). A typical skill:

my-skills/
├── commit-helper/          ← package folder ("Path in repo": commit-helper)
│   ├── SKILL.md            ← required for skills
│   ├── reference.md        ← resources the skill links to
│   ├── scripts/
│   │   └── changelog.sh    ← scanned strictly as executable code
│   ├── denofy.json         ← optional: {"version": "1.3.0"}
│   ├── denofy.yml          ← optional: exceptions for the security scan
│   └── README.md           ← shown on the package page
└── pr-checklist/
    └── ...

Ignored during import: .git, node_modules, .DS_Store and __MACOSX.

LimitValue
Files per package200
Size of one file1 MiB
Total package size5 MiB
Frontmatter description20–1024 characters
Recommended length of SKILL.md≤ 500 lines

Package types#

TypeWhat the folder containsTools
SkillSKILL.md with frontmatter, plus any resources it referencesClaude Code, Codex, Cursor
Cursor RuleOne or more .mdc files with description / globs / alwaysApplyCursor
AGENTS.mdAn AGENTS.md (or one markdown file) that is merged into the targetCodex, Claude Code, Cursor
SubagentMarkdown files with name and description frontmatterClaude Code
Slash CommandMarkdown files whose file name is the command (deploy.md → /deploy)Claude Code, Codex, Cursor

Where each type is installed is listed in the CLI reference.

SKILL.md frontmatter#

markdown
---
name: commit-helper
description: Writes Conventional Commit messages from the staged diff. Use when the user asks for a commit message or wants to commit.
version: 1.3.0
license: MIT
---

# Commit helper

1. Run `git diff --staged`.
2. Read [the conventions](reference.md) …
FieldRequiredRules
nameyesLowercase letters, digits and hyphens. Should equal the package name (warning if not).
descriptionyes20–1024 characters. Agents use it to decide when to load the skill — say when.
versionnoSemver; used as the version on import (see below).
licensenoSPDX id, shown on the package page.

Every relative link ([text](file.md), images) must point to a file inside the package — missing files fail the structure check. Paths mentioned in backticks that do not exist produce a warning.

Versioning#

Each import is pinned to one commit. The version number is chosen in this order:

  1. The version you type in the Sync dialog, or the tag of a tag push (v1.4.0 → 1.4.0).
  2. version in denofy.json in the package folder.
  3. version (or metadata.version) in the frontmatter of SKILL.md / the main file.
  4. Otherwise the patch version is bumped automatically (1.2.3 → 1.2.4; the first version is 1.0.0).

Rules:

  • A version number can only exist once. Importing the same version from a different commit fails with "Bump the version to publish changes".
  • Importing a commit that is already published does nothing.
  • Versions are never edited after import. You can yank a version (hidden from ranges and latest, still installable by exact number) from the dashboard.
  • latest is the highest version that is not yanked, not blocked and did not fail verification.

Import from GitHub#

Sign in with GitHub#

Sign in and open Publish in the header.

Choose repository and path#

Enter the repository (owner/repo), the path of the package folder (empty for the root) and optionally a branch (default branch if empty).

Describe the package#

Name (the slug used in denofy add <name>, cannot be changed later), title, summary, type, supported tools, category, tags and license. The description defaults to the package's README.

Submit#

Denofy queues the import. The worker downloads the repository at the current commit, runs the verifier and stores the tarball — usually within a few seconds. The dashboard shows the result and the full verification report.

New accounts can create a limited number of packages per day; see rate limits.

Sync button#

On Dashboard → your package the Sync button imports the newest commit of the configured branch. You can optionally enter a version and a changelog. Re-verify runs the current rules again on an existing version without creating a new one.

Webhook: publish on every push#

With a webhook, a push to your repository publishes a new version automatically.

Open the webhook settings#

In your GitHub repository go to Settings → Webhooks → Add webhook.

Fill in the form#

  • Payload URL: https://denofy.com/api/webhooks/github (also shown with a copy button in your package dashboard)
  • Content type: application/json
  • Secret: the webhook secret of the Denofy instance — the value of GITHUB_WEBHOOK_SECRET on a self-hosted instance; for denofy.com ask the Denofy team
  • Events: Just the push event

Enable auto-sync#

Keep Auto-sync enabled in the package settings (it is on by default).

Push#

  • A push to the package's branch that changes files under the package path publishes a new version (patch bump, or the version declared in denofy.json / frontmatter).
  • Pushing a tag like v1.4.0 publishes exactly that version from the tagged commit.
  • Pushes that do not touch the package path are ignored.

GitHub shows the delivery result under Recent Deliveries. A 200 response lists the packages that were queued, for example {"ok": true, "queued": ["commit-helper"]}. 401 means the secret does not match. Webhook syncs count against the per-package sync limit.

After publishing#

  • Add the README badge to your repository.
  • Look at the verification report on the package page. If a finding is a false positive, either rephrase the text (see how context works) or add an exception with a reason in denofy.yml.
  • Watch installs and views in analytics.
Edit this page on GitHub