From ccb1c8cd59d02b8b1b5d42d414664161b269e679 Mon Sep 17 00:00:00 2001 From: charly Date: Tue, 20 Oct 2026 01:22:19 +0200 Subject: [PATCH] feat(skills): move the skill bodies to .agents/skills The bodies lived only as inline content: blocks on the skill: nodes. They now live in the repo that owns them, at .agents/skills//SKILL.md, and each node keeps its routing metadata (name, family, owner, description) with no body of its own. The plugin-marketplace generator reads this shape (skillfile.go): it takes the body from the first declared tree that holds the file and hard-errors when an inline content: disagrees with the file, so no stale second copy can survive. --- .agents/skills/nodejs/SKILL.md | 97 ++++++++++++++++++++++++++++++++++ charly.yml | 91 ------------------------------- 2 files changed, 97 insertions(+), 91 deletions(-) create mode 100644 .agents/skills/nodejs/SKILL.md diff --git a/.agents/skills/nodejs/SKILL.md b/.agents/skills/nodejs/SKILL.md new file mode 100644 index 0000000..c4955d1 --- /dev/null +++ b/.agents/skills/nodejs/SKILL.md @@ -0,0 +1,97 @@ +--- +name: nodejs +description: 'Node.js and npm via system packages (RPM/DEB) with global npm prefix. + + Use when working with Node.js, npm, or JavaScript/TypeScript tooling.' +--- + +# nodejs -- Node.js and npm runtime + +## Candy Properties + +| Property | Value | +|----------|-------| +| Install files | `charly.yml`, `task:` | + +## Environment Variables + +| Variable | Value | +|----------|-------| +| `NPM_CONFIG_PREFIX` | `~/.npm-global` | +| `npm_config_cache` | `~/.cache/npm` | + +PATH additions: `~/.npm-global/bin` + +## Packages + +RPM: `nodejs`, `npm` +DEB: `nodejs` (NodeSource node 22.x on Ubuntu + Debian; npm is bundled +by NodeSource, not the separate apt `npm` package) +PAC: `nodejs`, `npm` + +## pnpm (standalone binary) + +The candy installs the **pnpm** standalone binary (self-contained — it bundles +its own node) to `/usr/local/bin/pnpm` via a `task:` download. It is deliberately +NOT a `package.json` dependency: a `package.json` would trigger the npm +multi-stage builder on this candy, and the builder images that COMPOSE nodejs +(`arch-builder` / `fedora-builder`) cannot self-provide the npm builder. The +binary on `/usr/local/bin` is on the default system PATH for every user (incl. +root — Immich runs its pnpm build as root). Immich and other pnpm consumers use +this pnpm to drive their build. + +### The pin and a consumer's `allowBuilds` KEY FORM are a COUPLED PAIR + +pnpm >= 10 blocks a dependency's build/install scripts unless it is allowlisted, +and for a **git-specifier** dependency the KEY FORM of that allowlist entry is +version-coupled: the two forms fail on each other's pin, so no single form works +at both. MEASURED in the real build image (Fedora 43, node 22.22.2) against +pod-dsh's `dsh-web` profile — `opencharly/layer-nodejs#5`: + +| `allowBuilds` key form | pnpm `10.33.4` | pnpm `10.34.6` | +|---|---|---| +| bare name — `"@perrylink/dsh-github": true` | PASS | `ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED` | +| fully-qualified URL key — `"@perrylink/dsh-github@https://codeload.github.com///.git": true` | `ERR_PNPM_INVALID_VERSION_UNION` | PASS | + +A wrong pair hard-fails the consumer's profile install at IMAGE BUILD time. So +`PNPM_VERSION`, `PNPM_ALLOWBUILDS_GIT_KEY_FORM` and the two PROBED_* constants move +together, and the candy's own +`check: the pinned pnpm version's allowBuilds git-key form matches the recorded measurement` +makes a bump that forgets them RED instead of a hard-failed consumer build. Only the +two probed versions are accepted: a bump to any other pin must RE-MEASURE the form and +record it. (pod-dsh vendored its git-hosted plugins as prebuilt `file:` tarballs in +pod-dsh#28, so no git dep remains there today — the rule still binds any consumer +that pins one.) + +## Usage + +```yaml +# charly.yml +my-image: + candy: + - nodejs +``` + +## Used In Boxes + +- `/charly-distros:fedora-builder` +- `/charly-distros:arch-builder` +- Transitive dependency for `openclaw`, `pre-commit`, and other candies + +## Related Candies + +- `/charly-coder:pre-commit` -- depends on nodejs +- `/charly-immich:immich-layer` -- uses the candy's pnpm to build Immich + +## When to Use This Skill + +Use when the user asks about: + +- Node.js or npm setup in containers +- Global npm package installation +- The `nodejs` candy or npm configuration + +## Related + +- `/charly-image:layer` — candy authoring reference (`charly.yml` schema, task verbs, service declarations) +- `/charly-check:check` — declarative testing (`check:` block, `charly check box`, `charly check live`) diff --git a/charly.yml b/charly.yml index 0cad567..2e39e6c 100644 --- a/charly.yml +++ b/charly.yml @@ -192,94 +192,3 @@ nodejs-skill: description: |- Node.js and npm via system packages (RPM/DEB) with global npm prefix. Use when working with Node.js, npm, or JavaScript/TypeScript tooling. - content: |- - # nodejs -- Node.js and npm runtime - - ## Candy Properties - - | Property | Value | - |----------|-------| - | Install files | `charly.yml`, `task:` | - - ## Environment Variables - - | Variable | Value | - |----------|-------| - | `NPM_CONFIG_PREFIX` | `~/.npm-global` | - | `npm_config_cache` | `~/.cache/npm` | - - PATH additions: `~/.npm-global/bin` - - ## Packages - - RPM: `nodejs`, `npm` - DEB: `nodejs` (NodeSource node 22.x on Ubuntu + Debian; npm is bundled - by NodeSource, not the separate apt `npm` package) - PAC: `nodejs`, `npm` - - ## pnpm (standalone binary) - - The candy installs the **pnpm** standalone binary (self-contained — it bundles - its own node) to `/usr/local/bin/pnpm` via a `task:` download. It is deliberately - NOT a `package.json` dependency: a `package.json` would trigger the npm - multi-stage builder on this candy, and the builder images that COMPOSE nodejs - (`arch-builder` / `fedora-builder`) cannot self-provide the npm builder. The - binary on `/usr/local/bin` is on the default system PATH for every user (incl. - root — Immich runs its pnpm build as root). Immich and other pnpm consumers use - this pnpm to drive their build. - - ### The pin and a consumer's `allowBuilds` KEY FORM are a COUPLED PAIR - - pnpm >= 10 blocks a dependency's build/install scripts unless it is allowlisted, - and for a **git-specifier** dependency the KEY FORM of that allowlist entry is - version-coupled: the two forms fail on each other's pin, so no single form works - at both. MEASURED in the real build image (Fedora 43, node 22.22.2) against - pod-dsh's `dsh-web` profile — `opencharly/layer-nodejs#5`: - - | `allowBuilds` key form | pnpm `10.33.4` | pnpm `10.34.6` | - |---|---|---| - | bare name — `"@perrylink/dsh-github": true` | PASS | `ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED` | - | fully-qualified URL key — `"@perrylink/dsh-github@https://codeload.github.com///.git": true` | `ERR_PNPM_INVALID_VERSION_UNION` | PASS | - - A wrong pair hard-fails the consumer's profile install at IMAGE BUILD time. So - `PNPM_VERSION`, `PNPM_ALLOWBUILDS_GIT_KEY_FORM` and the two PROBED_* constants move - together, and the candy's own - `check: the pinned pnpm version's allowBuilds git-key form matches the recorded measurement` - makes a bump that forgets them RED instead of a hard-failed consumer build. Only the - two probed versions are accepted: a bump to any other pin must RE-MEASURE the form and - record it. (pod-dsh vendored its git-hosted plugins as prebuilt `file:` tarballs in - pod-dsh#28, so no git dep remains there today — the rule still binds any consumer - that pins one.) - - ## Usage - - ```yaml - # charly.yml - my-image: - candy: - - nodejs - ``` - - ## Used In Boxes - - - `/charly-distros:fedora-builder` - - `/charly-distros:arch-builder` - - Transitive dependency for `openclaw`, `pre-commit`, and other candies - - ## Related Candies - - - `/charly-coder:pre-commit` -- depends on nodejs - - `/charly-immich:immich-layer` -- uses the candy's pnpm to build Immich - - ## When to Use This Skill - - Use when the user asks about: - - - Node.js or npm setup in containers - - Global npm package installation - - The `nodejs` candy or npm configuration - - ## Related - - - `/charly-image:layer` — candy authoring reference (`charly.yml` schema, task verbs, service declarations) - - `/charly-check:check` — declarative testing (`check:` block, `charly check box`, `charly check live`)