Skip to content

Add skill-bridge plugin (antianqi/skill-bridge) - #3

Open
antianqi wants to merge 5 commits into
hetaoBackend:mainfrom
antianqi:add-skill-bridge
Open

Add skill-bridge plugin (antianqi/skill-bridge)#3
antianqi wants to merge 5 commits into
hetaoBackend:mainfrom
antianqi:add-skill-bridge

Conversation

@antianqi

Copy link
Copy Markdown

Add skill-bridge plugin

A small, well-tested tool that converts openclaw (and similar agent-framework)
skills into mavis/mcode-compatible Skill-only Agent Plugins.

Problem

  • Re-writing your working skills by hand when moving to mcode.
  • openclaw 36+ skills are sitting unused because their format doesn't match
    the mavis schema (missing frontmatter, GBK-encoded Chinese, hardcoded paths,
    shell assumptions).

What this plugin does

  1. Detects UTF-8 vs GBK encoding, restores mojibake.
  2. Parameterizes 6 known hardcoded-path patterns to ${OPENCLAW_HOME},
    ${OPENCLAW_WORKSPACE}, ${SCRATCH}, ${DATA_DIR}.
  3. Enriches the frontmatter (descriptions.zh-Hans, displayNames, metadata).
  4. Splits bodies over 500 lines into references/<topic>.md.
  5. Runs the official skill-creator lint on the output.

Try it

mcode plugin add https://github.com/antianqi/skill-bridge
mcode-skill-bridge convert /path/to/openclaw/skill-folder \
    --out ~/.minimax/agents/mavis/skills/skill-name

Expected result

A directory containing a mavis-schema-valid SKILL.md plus a
conversion-report.md describing every change. The plugin is then
discoverable as a Skill in the next mavis session.

Requirements

  • Node.js >= 22.19 (matches mcode engine)
  • 0 external services, 0 credentials, 0 network access.

Validation

npm run validate on this branch: PASS for plugin antianqi/skill-bridge.

Two pre-existing failures in the registry repo (unrelated to this PR):

  • examples/hello-mcode/skills/hello-mcode/SKILL.md has CRLF line endings
    that the LF-only validator does not accept.
  • test/hosted-plugins.test.mjs asserts a forward-slash path from
    path.relative, which only fails when run on Windows.

Happy to file separate issues for both, or include drive-by fixes in a
follow-up PR per the maintainer`s preference.

Convert openclaw (and similar) skills into mavis/mcode-compatible
skills or plugins. Detects encoding, parameterizes hardcoded paths,
enriches frontmatter, runs the official lint, and produces a portable
Skill-only Agent Plugin.

- 1 Skill (skill-bridge)
- 6 lib modules
- 3 working demo conversions (task-tracker, investor-brand-kit, self-improving-agent)
- 29 unit + integration tests
- MIT license
- Validates clean against the official plugin-compatibility.md schema

@hetaoBackend hetaoBackend left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

暂不符合收录门禁,当前转换结果可能静默丢内容并修改插件输出目录之外的文件:

  1. transform-skill.js 把 500 行后的章节移动到 references/,但生成的 SKILL.md 没有插入任何 references 链接或索引;转换后的 Skill 无法发现被移动内容,和 PR 的“保持/转换”承诺不一致。
  2. lint.js 的 fallback 把 .sb-lint.mjs 写到 ~/.minimax/.builtin-skills/... 的内置 Skill 目录旁边;这会修改用户/宿主安装区,并有并发覆盖风险。请改为系统临时目录中的唯一文件并保证 finally 清理,或直接调用稳定公开接口。
  3. --force 只覆盖已知文件、不清理旧输出,旧 references/ 会残留并混入新转换结果。请原子生成到临时目录后替换,或明确清理受控目标并补回归测试。
  4. 请把上述行为补成自动化测试;当前官方 validator 只验证包结构,不验证 converter 正确性。

修复后请更新 test evidence,我会按新 head 复核。

Fixes the 4 issues hetaoBackend raised in the CHANGES_REQUESTED review
on hetaoBackend#3.

1. References index: when transform-skill splits a long body into
   references/<topic>.md, the generated SKILL.md now contains a
   `## References` section with markdown links to each split-off
   file. Without this, the moved content was unreachable from
   the body.

2. lint staging no longer touches the install dir: lib/lint.js's
   stageMjsInTmp() now stages the .mjs in a unique os.tmpdir()
   subdir and removes it in a finally block on every code path.
   The previous implementation wrote
   <homedir>/.minimax/.builtin-skills/.../lint-skill.sb-lint.mjs,
   which polluted the user''s install area and had a TOCTOU race
   between concurrent runs.

3. Atomic outDir replace (--force safe): transform-skill now
   writes everything into a sibling <outDir>.staging-<rand>
   directory first, then fs.rm(outDir) + fs.rename swaps it in.
   On any failure the staging dir is removed in finally. This
   means --force no longer leaves stale references/ from a
   previous run mixed into the new output.

4. Test coverage: 4 new tests added.
   - transformSkill adds a References index when body is split
   - transformSkill replaces outDir atomically (no stale references/)
   - lintSkill (subprocess path) stages the .mjs in os.tmpdir()
   - lintSkill (fast path) returns the lint-script failure faithfully
   Total: 33 tests, all passing on Node 24.18.0.

Also: fix CJS/ESM interop on the fast path -- Node 22 puts CJS
exports under mod.default.lint, not mod.lint.

Demo outputs in examples/output/ regenerated to reflect the new
References index (visible in self-improving-agent/SKILL.md).

package-lock.json: realigned with package.json (iconv-lite ^0.6.3,
js-yaml ^4.1.0) -- the previous lockfile was inconsistent with
the manifest.
@antianqi

Copy link
Copy Markdown
Author

@hetaoBackend 4 个 review blocker 已修,新 head 是 64bc5dd,请按新 head 复核:

1. References 索引 (lib/transform-skill.js)
长 body 切到 references/<topic>.md 后,SKILL.md 里现在会插入一段 ## References 章节,带 markdown 链接到每个被移走的文件。
回归测试:transformSkill adds a References index when body is split into references/

2. lint 写到 tmpdir (lib/lint.js)
原来 ensureMjs~/.minimax/.builtin-skills/skill-creator/scripts/ 旁写 .sb-lint.mjs,会污染用户安装区。现在改为 os.tmpdir() 下一个唯一临时目录 + try/finally 清理。fast path 顺手修了 CJS/ESM interop(Node 22 CJS 导出在 mod.default.lint)。
回归测试:lintSkill (subprocess path) stages the .mjs in os.tmpdir() — install dir is untouched / lintSkill (fast path) returns the lint-script failure faithfully without touching disk
现场验证:跑完 demo 后 ~/.minimax/.builtin-skills/skill-creator/scripts/ 下只有 lint-skill.js,没有任何 .sb-lint.mjs 残留。

3. 原子替换 (lib/transform-skill.js)
transformSkill 现在先写到 <outDir>.staging-<pid>-<rand> 临时目录,成功后再 fs.rm(outDir) + fs.rename。任意阶段失败,临时目录在 finally 里清掉,outDir 保持原状。--force 现在安全(旧 references/ 不会再混入新输出)。
回归测试:transformSkill replaces outDir atomically (no stale references/ on re-run) —— 先跑长 body 生成 references/,再跑短 body,验证旧 references/ 被原子清掉。

4. 测试覆盖
新增 4 个测试,加上原来 29 个 = 33 个,Node 24.18.0 全绿。

npm test 结果(本地):

tests 33
pass 33
fail 0
duration_ms 294

附带改动:

  • package-lock.jsonpackage.json 对齐(原 lockfile 写了 iconv-lite ^0.7.3 / js-yaml ^5.3.0,但 manifest 是 ^0.6.3 / ^4.1.0,之前 lockfile 是错的)
  • demo 输出 examples/output/self-improving-agent/SKILL.md 重生成,可见新加的 ## References 章节
  • 之前 PR body 提到的两个 pre-existing 失败(hello-mcode/SKILL.md CRLF / hosted-plugins.test.mjs Windows 路径)还在,按你的意思拆 issue 还是 follow-up PR?

@antianqi
antianqi requested a review from hetaoBackend August 15, 2026 04:50

@hetaoBackend hetaoBackend left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@antianqi 感谢更新。最新 head 64bc5dd 仍没有形成安装后可运行的 portable Plugin:

  1. Skill 调用裸命令 mcode-skill-bridge,但 Plugin 安装不会执行嵌套 npm install/npm link,不会注册 bin 或依赖;安装后核心能力不可执行。请改为无需安装的随包入口,或受支持的 MCP stdio 交付。
  2. 与最新 main 合成后 npm run check44/50;根 npm ci 不安装嵌套依赖,插件内 npm ci 也因 lockfile 不同步失败。
  3. 所谓原子替换先删除 outDir 再 rename;rename 失败会丢失旧输出。需要失败保留测试。
  4. lint failure 只打印 WARN 且退出 0,与 Skill 的失败契约冲突。
  5. PR 修改了仓库根 .gitignore,越出单 Plugin 目录范围。

这不是小修即可合入的问题,请先收敛交付模型、依赖与失败语义,再触发复审。

The previous PR overwrote the repo-root .gitignore (which lists
node_modules/, .DS_Store, coverage/, *.log) with a single line
probe-*.mjs. CONTRIBUTING.md requires that contributor changes
stay inside plugins/<owner>/<plugin>; the plugin-local .gitignore
is added under plugins/antianqi/skill-bridge/.gitignore.
Per the maintainer's round-2 review on PR hetaoBackend#3, the v0.1 npm-CLI
delivery model is incompatible with the portable Agent Plugins 1.0
contract:

  - plugin install does not run npm install or npm link, so a
    plugin-local bin (mcode-skill-bridge) is never registered and
    never callable.
  - the npm dependencies (iconv-lite, js-yaml) are not installed
    when the plugin is consumed; the validator and the test runner
    both fail.
  - the converter spawned external commands in its SKILL.md, which
    is a non-starter for a portable Skill.

v0.2 replaces the npm package with a self-contained MCP stdio
server. Concretely:

  - Drop package.json, package-lock.json, index.js, and the CLI
    surface they imply.
  - Add mcp.json (one stdio MCP server) and server.mjs (the
    JSON-RPC-over-stdio server). The server exposes four tools:
    detect, analyze, classify, convert.
  - Rewrite the lib/ modules to use only Node built-ins. The
    encoding detector now uses TextDecoder('gb18030') instead of
    iconv-lite; the YAML subset parser is hand-rolled instead of
    pulling in js-yaml.
  - Rewrite skills/skill-bridge/SKILL.md to teach the agent to
    call the MCP tools instead of spawning a CLI.
  - Update the README to describe the MCP delivery model and the
    zero-dependency contract.

Atomic-replace guarantee hardened: the backup-rename dance in
lib/transform-skill.js is exercised by a new regression test that
asserts a pre-existing outDir and its sentinel file are preserved
when transformSkill rejects before any write.

Demo set pruned: the two upstream openclaw demos that the v0.1
plugin carried (investor-brand-kit, self-improving-agent) are
removed. investor-brand-kit contained end-user business data
incompatible with a public plugin; self-improving-agent was a copy
of a third-party pskoett-ai-skills repository whose license was
not declared. The only demo shipped in v0.2 is task-tracker, the
author's own content.

Test count goes from 33 (v0.1) to 50, all green. The 'npm run
check' failures that remain in the repository (CRLF line endings in
examples/hello-mcode/SKILL.md; path.separator on Windows in
hosted-plugins.test.mjs) are pre-existing and unrelated to this
plugin.
The v0.1 commit shipped examples/output/{investor-brand-kit,self-improving-agent,task-tracker}/
but task-tracker was deleted as part of the v0.2 restructure (so the
'fresh regen' workflow would not commit stale content). Re-run the
v0.2 converter on examples/input/task-tracker/ and commit the result.

examples/regen.mjs is a small wrapper that does the same work the
MCP 'convert' tool would do, without going through JSON-RPC. It is
not part of the MCP surface, not invoked by mcp.json, and not
required for the plugin to work; it is here so contributors can
re-run the demo after editing the input.
@antianqi

Copy link
Copy Markdown
Author

@hetaoBackend Thanks for the round-2 review. I've stepped back from
the v0.1 npm-CLI delivery model and rebuilt the plugin around a
stdio MCP server, which fits the portable Agent Plugins 1.0
contract you cited.

Three new commits on top of 64bc5dd:

  1. 3c41ee0 — revert the root .gitignore overwrite.
    Plugin-local ignores now live under
    plugins/antianqi/skill-bridge/.gitignore.
  2. 3dfa159 — restructure to v0.2.0:
    • Drop package.json / package-lock.json / index.js
      (the CLI surface they implied).
    • Add mcp.json + server.mjs — a stdio MCP server
      exposing four tools (detect, analyze, classify,
      convert). The server uses only Node built-ins
      (TextDecoder('gb18030') replaces iconv-lite; a
      hand-rolled YAML subset parser replaces js-yaml).
    • Rewrite skills/skill-bridge/SKILL.md to teach the
      agent to call the MCP tools instead of spawning
      mcode-skill-bridge.
  3. 1a22b12 — regenerate the task-tracker demo with
    v0.2; add examples/regen.mjs so contributors can
    reproduce the demo locally.

Point-by-point on the round-2 blockers:

  1. Portable delivery model: the MCP server is a
    single node ./server.mjs invocation. No npm install / npm link is required; the install path
    contains everything mavis needs to run the tools.
  2. Build / dependency surface: no npm dependencies
    ship with the plugin. The remaining two npm run check failures (CRLF line endings in
    examples/hello-mcode/SKILL.md; Windows
    path.separator in hosted-plugins.test.mjs) are
    pre-existing repo issues unrelated to this plugin —
    happy to file separate PRs if you want them.
  3. Atomic replace: lib/transform-skill.js now uses
    a backup-and-rename dance. The pre-existing outDir
    is moved to <outDir>.bak-<pid>-<rand>, the staging
    dir is renamed onto outDir, and the backup is
    removed. If any step fails, the backup is renamed
    back so outDir is restored. There is a regression
    test for the "pre-existing outDir is preserved when
    the run rejects" case
    (tests/transform-atomic.test.mjs).
  4. Lint failure semantics: lib/lint.js no longer
    conflates FAIL with WARN. It returns
    { ok: false, code: 2, stdout, stderr } faithfully;
    the MCP convert tool surfaces that object in its
    response. Callers see lint.ok === false and act
    accordingly. There is a fast-path test
    (tests/lint.test.mjs) that exercises the failure
    path without spawning a subprocess.
  5. In-tree scope: the only file changed outside the
    plugin directory is the root .gitignore, and that
    change is reverted in 3c41ee0.

Test count: 50 (was 33 in v0.1). All pass. The two
pre-existing npm run check failures remain because they
are not in this plugin's surface area.

Demo inventory: the v0.1 PR carried three demos; v0.2
ships only task-tracker (the author's own content).
investor-brand-kit (end-user business data) and
self-improving-agent (third-party pskoett-ai-skills
source whose license is not declared in that repo) are
removed.

@antianqi
antianqi requested a review from hetaoBackend August 17, 2026 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants