Install
$ agentstack add skill-sailingnaturali-claude-skills-signalk-plugin ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Author & publish a SignalK plugin
Hard-won notes for building a SignalK Node-server plugin and shipping it to npm. Mirror a clean reference: openwatersio/signalk-tides (TypeScript) is the best one to read for the @signalk/server-api calls.
1. Scaffold
Public repo, npm package, MIT, zero runtime deps where possible. Files: index.js (or TS src/ built with tsc), package.json, LICENSE, README.md, .gitignore (node_modules, *.tgz), tests (index.test.js via node:test, or test/ via vitest), .github/workflows/{test.yml,publish.yml}.
package.json essentials — a missing files ships nothing because .gitignore excludes the build:
{
"name": "signalk-",
"files": ["index.js"],
"keywords": ["signalk-node-server-plugin", "signalk-category-utility"],
"license": "MIT"
}
For a scoped package add "publishConfig": { "access": "public" }. For TypeScript use "files": ["dist"] and "prepare": "npm run build" so npm publish builds first. The signalk-node-server-plugin keyword is what surfaces it in the SignalK app store.
2. The @signalk/server-api patterns that actually work
- Serve plugin data via
app.registerResourceProvider({ type, methods: { listResources, getResource, setResource, deleteResource } })— it's served at/signalk/v2/api/resources/and is anonymously readable under the server'sallow_readonly. Do NOT serve data withregisterWithRouter—/plugins//*routes are admin-gated, so every consumer would need an admin token. This is the single biggest gotcha. - Publish a value:
app.handleMessage(plugin.id, { updates: [{ values: [{ path: '' as Path, value }] }] }). - Read the vessel position:
app.getSelfPath('navigation.position.value') as Position | undefined(note the.valuesuffix). - Provide a config
schema(an object, or() => ({...})). Do periodic work insetInterval, and wrap each cycle — and each independent step inside it — intry/catch→app.error(...), so one failing fetch can't blank everything else or kill the loop. - Avoid an
expressruntime dependency: register routes on theIRouterthe server hands you viaregisterWithRouter, or use the resource API; keep@types/expressdev-only viaimport type(erased at build).
3. Publish to npm
Ship via OIDC trusted publishing so each GitHub release auto-publishes with no token/OTP. The full flow — the release-triggered publish.yml, the new-package first-publish chicken-and-egg (CLI+OTP once, then configure the trusted publisher), and the registry-propagation 404 gotcha — is in the npm-oidc-publish skill in this marketplace. SignalK-specific bits: the signalk-node-server-plugin keyword is what surfaces the package in the app store, and ship index.js/dist via "files".
4. Install on a SignalK server
Install from the admin UI Appstore (search your plugin), or npm install signalk- in the server's data dir (~/.signalk), then restart. Config persists under ~/.signalk/plugin-config-data/. If the server runs in Docker and you develop locally, never bind-mount a plugin inside node_modules — the app store reifies that tree with npm and can't rename a mount point (EBUSY), which breaks every plugin install/update. Mount outside node_modules and link it with a file: dep, or just npm install it as a tracked dependency (anything extraneous gets pruned on the next reify).
Testing
Keep pure helpers (parsing, mapping, math) separate and test them directly; inject/mock the I/O boundary (HTTP fetches, the SignalK app.* calls), or exercise it against a throwaway local http server in the test. node:test for JS, vitest for TS.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: sailingnaturali
- Source: sailingnaturali/claude-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.