Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,34 @@ Use an existing category when possible. The validator warns on unknown categorie
Current categories: **Auth**, **Core**, **DeFi**, **Frontend**, **Governance**, **Infrastructure**, **Integration**, **Motoko**, **Security**

To add a new category: update the description string in `skills/skill.schema.json`, the `KNOWN_CATEGORIES` array in `scripts/check-project.js`, and the `CATEGORY_ORDER` array in `src/lib/skills.ts`.

---

## Adding a Community Skill

Community skills are maintained by third parties and linked from `skills.internetcomputer.org` under the **Ecosystem** section. DFINITY curates the list but does not own or maintain the skill content.

### Requirements

1. The skill must exist at a public GitHub URL and follow the [Agent Skills spec](https://agentskills.io/specification) — a valid `SKILL.md` with `name` and `description` frontmatter.
2. The maintainer must be reachable: a GitHub org or a contact listed in the repository.
3. The linked file must be stable. If the URL goes dead and is not fixed within a reasonable time, the entry will be removed.

### How to add

Open a PR that adds one entry to [`community/index.json`](community/index.json):

```json
{
"name": "your-skill-name",
"title": "Your Skill Title",
"description": "One or two sentences: what it does and when an agent should load it.",
"maintainer": "Your Org Name",
"github": "https://github.com/your-org/your-repo/tree/main/skills/your-skill",
"added": "YYYY-MM-DD"
}
```

The `description` should match or be condensed from the `description` field in your `SKILL.md`.

**No eval results required.** Community skill PRs are lightweight: one JSON entry, a reachable maintainer, and a working link to a valid `SKILL.md`.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ node scripts/evaluate-skills.js <skill-name> --triggers-only # Trigger evals

Results are saved to `evaluations/results/` (gitignored). See [CONTRIBUTING.md](CONTRIBUTING.md#4-add-evaluation-cases) for how to write eval cases and prompts.

## Community Skills

Third-party skills for the ICP ecosystem, maintained by their respective authors. These appear in the **Ecosystem** section on the skills site, clearly separated from DFINITY-maintained skills.

| Skill | Maintainer | Description |
|-------|------------|-------------|
| [Liquidium SDK Integration](https://github.com/Liquidium-Inc/liquidium-sdk/tree/main/skills/liquidium-sdk-integration) | Liquidium Inc | Authless instant-loan flow, market data, and profile-based lending via `@liquidium/client` on ICP. |

Community skills are not maintained by DFINITY. To propose a community skill, see [CONTRIBUTING.md](CONTRIBUTING.md#adding-a-community-skill).

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for how to add or update skills.
Expand Down
10 changes: 10 additions & 0 deletions community/index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"name": "liquidium-sdk-integration",
"title": "Liquidium SDK Integration",
"description": "Authless instant-loan flow, market data, and profile-based lending via @liquidium/client on the Internet Computer. Covers LiquidiumClient setup, instantLoans, accounts, lending, positions, and quote modules.",
"maintainer": "Liquidium Inc",
"github": "https://github.com/Liquidium-Inc/liquidium-sdk/tree/main/skills/liquidium-sdk-integration",
"added": "2026-06-09"
}
]
68 changes: 68 additions & 0 deletions public/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,75 @@ h4 { font-size: 1.05rem; }
/* Prose */
.prose pre { padding: 0.75rem 0.85rem; font-size: 0.85em; }
.prose table { font-size: 0.85rem; display: block; overflow-x: auto; }

/* Community section — no overrides needed */
}

/* ---------- 404 ---------- */
main h1 { font-family: var(--serif); }

/* ---------- Community / Ecosystem section ---------- */
.community-divider {
display: flex; align-items: center; gap: 1rem;
margin: 4rem 0 0;
color: var(--muted); font-size: 0.72rem; font-family: var(--mono);
text-transform: uppercase; letter-spacing: 0.16em;
}
.community-divider::before,
.community-divider::after {
content: ''; flex: 1; border-top: 1px dashed var(--rule);
}

.community-notice {
display: flex; gap: 0.75rem; align-items: flex-start;
margin: 0 0 1.5rem; padding: 0.9rem 1.1rem;
border-left: 3px solid var(--rule-strong);
background: var(--bg-sunk); border-radius: 0 6px 6px 0;
}
.community-notice-icon {
font-size: 1rem; line-height: 1.55; flex-shrink: 0; color: var(--fg-secondary);
}
.community-notice p {
margin: 0; font-size: 0.95rem; color: var(--fg-secondary);
}

.community-badge {
display: inline-block; margin-left: 0.5rem;
padding: 0.1em 0.45em;
background: var(--bg-sunk); border: 1px solid var(--rule); border-radius: 9999px;
font-size: 0.65rem; font-family: var(--mono);
text-transform: uppercase; letter-spacing: 0.08em;
color: var(--muted); vertical-align: middle;
}

.skill-maintainer {
color: var(--muted); font-size: 0.82rem; font-style: italic; margin: 0.2rem 0 0;
}

.community-skill-row .skill-title a {
color: var(--fg-secondary);
}
.community-skill-row .skill-title a:hover { color: var(--accent); }

.community-skill-row > div { min-width: 0; }

.community-install-btn {
display: inline-flex; align-items: center; gap: 0.45rem;
background: none; border: none; cursor: pointer; padding: 0;
margin-top: 0.55rem; color: var(--muted); font-family: inherit;
font-size: inherit; text-align: left; width: 100%;
}
.community-install-btn:hover svg { color: var(--accent); }

.community-install-code {
font-family: var(--mono); font-size: 0.82rem;
background: var(--code-bg); color: var(--code-fg);
padding: 0.2em 0.55em; border-radius: 4px;
border: 1px solid var(--rule);
white-space: nowrap; overflow-x: auto; display: block;
max-width: 100%;
}

.community-install-btn .icon-check { display: none; color: var(--accent); }
.community-install-btn.copied .icon-copy { display: none; }
.community-install-btn.copied .icon-check { display: inline; }
57 changes: 57 additions & 0 deletions src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import BaseLayout from '../layouts/BaseLayout.astro';
import { SITE, absUrl } from '../lib/site';
import { getAllSkills, getSkillsByCategory, skillUrl, skillMarkdownUrl } from '../lib/skills';
import communitySkills from '../../community/index.json';

const all = await getAllSkills();
const grouped = await getSkillsByCategory();
Expand Down Expand Up @@ -96,6 +97,49 @@ const collectionLd = {
</ul>
</section>
))}

{communitySkills.length > 0 && (
<div class="community-divider" aria-hidden="true"><span>Ecosystem</span></div>

<section class="category community-section" id="category-ecosystem" aria-labelledby="cat-h-ecosystem">
<div class="cat-head">
<h2 id="cat-h-ecosystem">Ecosystem Skills</h2>
<span class="count">{communitySkills.length} skill{communitySkills.length === 1 ? '' : 's'}</span>
</div>
<div class="community-notice" role="note">
<span class="community-notice-icon" aria-hidden="true">⚠</span>
<p>Not maintained, reviewed, or verified by DFINITY Foundation. Use at your own risk.</p>
</div>
<ul class="skill-list">
{communitySkills.map((s) => {
const skillsPath = s.github
.replace('https://github.com/', '')
.replace(/\/tree\/[^/]+/, '');
const installCmd = `npx skills add ${skillsPath}`;
return (
<li class="skill-row community-skill-row" data-skill-id={s.name}>
<div class="skill-title">
<a href={s.github} target="_blank" rel="noopener noreferrer">{s.title}</a>
<span class="community-badge">community</span>
</div>
<div>
<p class="skill-desc">{s.description}</p>
<p class="skill-maintainer">by {s.maintainer}</p>
<button class="community-install-btn" data-command={installCmd}>
<code class="community-install-code">$ {installCmd}</code>
<svg class="icon-copy" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2" /><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" /></svg>
<svg class="icon-check" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12" /></svg>
</button>
</div>
<div class="skill-links">
<a href={s.github} target="_blank" rel="noopener noreferrer">GitHub ↗</a>
</div>
</li>
);
})}
</ul>
</section>
)}
</BaseLayout>

<script is:inline define:vars={{ promptText }}>
Expand All @@ -114,6 +158,19 @@ const collectionLd = {
})();
</script>

<script is:inline>
(function () {
document.querySelectorAll('.community-install-btn').forEach(function (btn) {
btn.addEventListener('click', function () {
var cmd = btn.getAttribute('data-command');
navigator.clipboard.writeText(cmd).catch(function () {});
btn.classList.add('copied');
setTimeout(function () { btn.classList.remove('copied'); }, 2000);
});
});
})();
</script>

<script is:inline>
(function () {
var input = document.getElementById('skill-search');
Expand Down
Loading