OpenCode's legacy plugin loader iterates every exported function in a plugin module and tries to invoke each one with the plugin context object. parseCommandFile was exported alongside the default plugin function, so the loader called it with an object instead of a file path and crashed with 'path must be a string or a file descriptor' before any hook ran, which aborted the whole plugin load. Move the frontmatter parser to its own .cjs sibling; the plugin module now exposes exactly one top-level export (the default plugin function). The plugin requires the parser via createRequire, and the existing parseCommandFile tests now require the sibling directly. Co-authored-by: ayushere <ayushere@users.noreply.github.com>
24 lines
1.0 KiB
JavaScript
24 lines
1.0 KiB
JavaScript
'use strict';
|
|
|
|
// ponytail command-file frontmatter parser.
|
|
//
|
|
// Pulled out of ponytail.mjs so the plugin module's only top-level export is
|
|
// the plugin function itself. OpenCode's legacy plugin loader (the one that
|
|
// runs before v1 plugins are detected) treats every function exported from a
|
|
// plugin module as a plugin; calling the frontmatter parser as one threw
|
|
// "path must be a string or a file descriptor" because it got the plugin
|
|
// context object as its first argument. Keeping the parser in its own module
|
|
// leaves exactly one plugin-shaped export on ponytail.mjs.
|
|
|
|
function parseCommandFile(filePath) {
|
|
const fs = require('fs');
|
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
// Tolerate CRLF: a Windows checkout (autocrlf) delivers \r\n, npm ships \n.
|
|
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
|
|
if (!match) return null;
|
|
const description = match[1].match(/description:\s*(.+)/)?.[1]?.trim();
|
|
return { description, template: match[2].trim() };
|
|
}
|
|
|
|
module.exports = { parseCommandFile };
|