fix(opencode): stop exporting parseCommandFile from plugin module (#301)
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>
This commit is contained in:
parent
8e69b4a55f
commit
511ddd4d62
|
|
@ -0,0 +1,23 @@
|
|||
'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 };
|
||||
|
|
@ -21,6 +21,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|||
const require = createRequire(import.meta.url);
|
||||
const { getPonytailInstructions } = require('../../hooks/ponytail-instructions');
|
||||
const { getDefaultMode, normalizePersistedMode } = require('../../hooks/ponytail-config');
|
||||
const { parseCommandFile } = require('./ponytail-frontmatter.cjs');
|
||||
|
||||
// OpenCode has no flag-file convention of its own; keep mode beside its config.
|
||||
const statePath = path.join(
|
||||
|
|
@ -42,15 +43,6 @@ function writeMode(mode) {
|
|||
fs.writeFileSync(statePath, mode);
|
||||
}
|
||||
|
||||
export function parseCommandFile(filePath) {
|
||||
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() };
|
||||
}
|
||||
|
||||
export default async ({ client } = {}) => {
|
||||
const log = (level, message) => {
|
||||
try { client && client.app && client.app.log({ body: { service: 'ponytail', level, message } }); } catch (e) {}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,11 @@ test.before(async () => {
|
|||
const url = pathToFileURL(path.join(__dirname, '..', '.opencode', 'plugins', 'ponytail.mjs'));
|
||||
const mod = await import(url);
|
||||
loadPlugin = mod.default;
|
||||
parseCommandFile = mod.parseCommandFile;
|
||||
// The frontmatter parser used to be exported from the plugin module itself.
|
||||
// OpenCode's legacy loader treats every exported function as a plugin and
|
||||
// tried to invoke it with the plugin context object, which crashed. The
|
||||
// parser now lives in its own .cjs sibling; require it directly.
|
||||
parseCommandFile = require(path.join(__dirname, '..', '.opencode', 'plugins', 'ponytail-frontmatter.cjs')).parseCommandFile;
|
||||
});
|
||||
|
||||
function transform(hooks) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue