openclaw - 💡(How to fix) Fix [Feature]: Expose skills-registry, frontmatter, and env-sanitizer helpers via plugin-sdk

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Re-export the existing loadWorkspaceSkillEntries, parseFrontmatter, resolveOpenClawMetadata, and sanitizeSystemRunEnvOverrides helpers from openclaw/plugin-sdk/skills-runtime (and ./plugin-sdk/sandbox) so third-party plugins can reach the skills registry, SKILL.md frontmatter parser, and host-env sanitizer that OpenClaw already uses internally.

Root Cause

Concrete real-world plugin: a third-party plugin registering a skills.setup gateway RPC method (runs an installed skill's setup hook, complementary to #80213) carries ~120 lines of code that exists solely because the upstream helpers aren't reachable.

Fix Action

Fix / Workaround

This forces plugin authors into the same two fragile workarounds #74900 calls out for the embedding-provider case: either deep-import internals with no semver protection, or carry a hand-rolled copy that silently drifts from upstream.

Code Example

// existing:
export {
  bumpSkillsSnapshotVersion,
  getSkillsSnapshotVersion,
  registerSkillsChangeListener,
  shouldRefreshSnapshotForVersion,
  type SkillsChangeEvent,
} from "../agents/skills/refresh-state.js";

// proposed additions:
export {
  loadWorkspaceSkillEntries,
  loadVisibleWorkspaceSkillEntries,
} from "../agents/skills/workspace.js";

export {
  parseFrontmatter,
  resolveOpenClawMetadata,
  resolveSkillKey,
} from "../agents/skills/frontmatter.js";

export type {
  Skill,
  SkillEntry,
  ParsedSkillFrontmatter,
  OpenClawSkillMetadata,
} from "../agents/skills/types.js";

---

export {
  sanitizeSystemRunEnvOverrides,
  isDangerousHostEnvOverrideVarName,
} from "../infra/host-env-security.js";
RAW_BUFFERClick to expand / collapse

Summary

Re-export the existing loadWorkspaceSkillEntries, parseFrontmatter, resolveOpenClawMetadata, and sanitizeSystemRunEnvOverrides helpers from openclaw/plugin-sdk/skills-runtime (and ./plugin-sdk/sandbox) so third-party plugins can reach the skills registry, SKILL.md frontmatter parser, and host-env sanitizer that OpenClaw already uses internally.

Problem to solve

openclaw/plugin-sdk/skills-runtime currently exposes only refresh-state helpers (src/plugin-sdk/skills-runtime.ts). The published package's "exports" map blocks plugin imports outside ./plugin-sdk/*, so any third-party plugin that needs to inspect or operate on installed skills must reimplement directory resolution, frontmatter parsing, and env-overlay sanitization from scratch.

This forces plugin authors into the same two fragile workarounds #74900 calls out for the embedding-provider case: either deep-import internals with no semver protection, or carry a hand-rolled copy that silently drifts from upstream.

Concrete real-world plugin: a third-party plugin registering a skills.setup gateway RPC method (runs an installed skill's setup hook, complementary to #80213) carries ~120 lines of code that exists solely because the upstream helpers aren't reachable.

Reinvented in pluginUpstream equivalentPlugin LoC saved
Resolve <workspace>/skills/<slug>/ with path.resolve + realpath + isPathInside boundary checks + hand-rolled ENOENT translationloadWorkspaceSkillEntries(workspaceDir, opts?) returns SkillEntry[] with skill.baseDir already resolved + boundary-safe~30
extractFrontmatterBlock + parseIndentedSetupScript + normalizeScalar — a homemade indent-aware YAML parser scoped to one key pathparseFrontmatter(content) returns ParsedSkillFrontmatter; resolveOpenClawMetadata handles the structured metadata block~55
normalizeEnvMap + hard-coded RESERVED_ENV_KEYS = {HOME, PATH, SKILL_DIR, XDG_CONFIG_HOME, XDG_DATA_HOME} for sanitizing operator-provided env overrides before spawning a sub-processsanitizeSystemRunEnvOverrides backed by host-env-security-policy.json already enforces this policy for OpenClaw-internal subprocess spawns~20

The hand-rolled YAML parser is the most concerning piece: it can't handle quoted strings with embedded #, doesn't honor block scalars, and silently trails upstream's parser as the SKILL.md frontmatter shape evolves.

Proposed solution

Two additions to src/plugin-sdk/skills-runtime.ts, following the same re-export pattern as src/plugin-sdk/agent-runtime.ts (export * from "../agents/agent-scope.js" + sibling re-exports):

// existing:
export {
  bumpSkillsSnapshotVersion,
  getSkillsSnapshotVersion,
  registerSkillsChangeListener,
  shouldRefreshSnapshotForVersion,
  type SkillsChangeEvent,
} from "../agents/skills/refresh-state.js";

// proposed additions:
export {
  loadWorkspaceSkillEntries,
  loadVisibleWorkspaceSkillEntries,
} from "../agents/skills/workspace.js";

export {
  parseFrontmatter,
  resolveOpenClawMetadata,
  resolveSkillKey,
} from "../agents/skills/frontmatter.js";

export type {
  Skill,
  SkillEntry,
  ParsedSkillFrontmatter,
  OpenClawSkillMetadata,
} from "../agents/skills/types.js";

One addition to src/plugin-sdk/sandbox.ts (or a new ./plugin-sdk/host-env):

export {
  sanitizeSystemRunEnvOverrides,
  isDangerousHostEnvOverrideVarName,
} from "../infra/host-env-security.js";

All four target files already export the listed symbols. The proposal is purely re-export plumbing in plugin-sdk/*; no changes to the underlying helpers' implementations or signatures.

Alternatives considered

  • Widen the "exports" map to expose ./agents/* directly. Rejected — leaks the entire internals tree past a stable boundary and prevents future refactors. The SDK re-export pattern keeps the public surface curated.
  • skills.status over an in-process gateway RPC (#76756 would enable this). Useful for the curated-metadata case but doesn't carry raw frontmatter, doesn't help the env-sanitizer case, and adds an RPC round-trip for what is conceptually a local read. Complementary, not a substitute.
  • Continue hand-rolling per plugin (status quo). Each plugin that touches the skills domain re-derives the same code; the hand-rolled YAML parsers in particular silently trail upstream's.

Impact

  • Affected: every third-party plugin that needs to inspect installed skills, parse SKILL.md frontmatter, or sanitize environment overlays before spawning a sub-process. Examples: setup-hook plugins (complementary to #80213), audit / lint tooling, custom skill-management UIs, integration-management plugins.
  • Severity: medium. Plugins can ship today by reimplementing — they're not blocked — but each reimplementation is a future-correctness liability.
  • Frequency: one-time author cost per plugin, then ongoing drift as upstream evolves the SKILL.md shape and env-sanitizer policy.
  • Consequence: plugin code duplicates ~100 LoC of upstream logic per implementation, with the YAML parser specifically prone to silent divergence. Today's third-party skills-setup plugin is a concrete instance of this cost.

Evidence/examples

Additional information

  • Verified against: [email protected] (the project's currently-pinned release). Same gap exists on main.
  • Not a duplicate of #80213. That issue defines the skill-author-side setup.script hook spec. This proposal is the plugin-side SDK gap that affects any plugin operating on the skills domain — and would still apply to audit / inspection / UI plugins after #80213 lands.
  • Backward compatibility: purely additive. Existing imports from openclaw/plugin-sdk/skills-runtime continue to work.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix [Feature]: Expose skills-registry, frontmatter, and env-sanitizer helpers via plugin-sdk