Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "propulsion",
"version": "1.0.1",
"version": "1.0.2",
"description": "Propulsion workflow routing and skills for agentic coding.",
"author": {
"name": "Moon Pixels"
Expand Down Expand Up @@ -41,7 +41,7 @@
],
"brandColor": "#FF4F00",
"composerIcon": "./assets/propulsion_icon_square.png",
"logo": "./assets/banner.png",
"logo": "./assets/propulsion_icon_square.png",
"screenshots": []
}
}
32 changes: 25 additions & 7 deletions index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,31 @@ async function PropulsionPlugin() {
}
},
'experimental.chat.messages.transform': async (_input, output) => {
output.messages = [
{
role: 'system',
content: getPropulsionBootstrapGuidance(),
},
...(output.messages ?? []),
];
const bootstrap = getPropulsionBootstrapGuidance();
const firstUser = output.messages?.find(
(message) => message.info.role === 'user',
);

if (!firstUser?.parts?.length) {
return;
}

if (
firstUser.parts.some(
(part) =>
part.type === 'text' &&
part.text.includes('<EXTREMELY_IMPORTANT>'),
)
) {
return;
}

const ref = firstUser.parts[0];
firstUser.parts.unshift({
...ref,
type: 'text',
text: bootstrap,
});
},
};
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "propulsion",
"version": "1.0.1",
"version": "1.0.2",
"main": "./index.mjs",
"exports": "./index.mjs",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion skills/propulsion/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: propulsion
# prettier-ignore
description: Manage software-work request routing into Propulsion before any downstream stage is entered. Use when starting a session with software work.
description: Execute structured AI software development from planning through execution. Use when implementing or updating code, debugging issues, or starting repo software work.
---

# Propulsion
Expand Down
36 changes: 30 additions & 6 deletions tests/opencode-plugin.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,33 @@ describe('OpenCode Propulsion bootstrap guidance', () => {
);
});

test('registers an OpenCode messages transform that prepends Propulsion guidance', async () => {
test('registers an OpenCode messages transform that injects Propulsion guidance into the first user message', async () => {
const pluginPackage = (await import('../index.mjs')).default;
const PropulsionPlugin = pluginPackage.server;
const hooks = await PropulsionPlugin({});
const userPart = {
id: 'part-user',
type: 'text',
text: 'Build the thing',
};
const output = {
system: ['existing system prompt'],
messages: [{ role: 'user', content: 'Build the thing' }],
messages: [
{
info: { role: 'assistant' },
parts: [
{
id: 'part-assistant',
type: 'text',
text: 'Ready',
},
],
},
{
info: { role: 'user' },
parts: [userPart],
},
],
};

expect(hooks).toEqual(
Expand All @@ -102,15 +122,19 @@ describe('OpenCode Propulsion bootstrap guidance', () => {
);
expect(hooks).not.toHaveProperty('experimental.chat.system.transform');

await hooks['experimental.chat.messages.transform']({}, output);
await hooks['experimental.chat.messages.transform']({}, output);

expect(output.system).toEqual(['existing system prompt']);
expect(output.messages).toEqual([
expect(output.messages).toHaveLength(2);
expect(output.messages[0].info.role).toBe('assistant');
expect(output.messages[1].parts).toEqual([
{
role: 'system',
content: getPropulsionBootstrapGuidance(),
...userPart,
type: 'text',
text: getPropulsionBootstrapGuidance(),
},
{ role: 'user', content: 'Build the thing' },
userPart,
]);
});
});