opencode-vibe-webhook 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +236 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -47,11 +47,23 @@ interface SessionData {
|
|
|
47
47
|
title?: string;
|
|
48
48
|
parentID?: string;
|
|
49
49
|
}
|
|
50
|
+
interface Part {
|
|
51
|
+
type: string;
|
|
52
|
+
text?: string;
|
|
53
|
+
[key: string]: unknown;
|
|
54
|
+
}
|
|
50
55
|
type Plugin = (ctx: PluginContext) => Promise<{
|
|
51
56
|
event?: (args: {
|
|
52
57
|
event: OpenCodeEvent;
|
|
53
58
|
}) => Promise<void>;
|
|
54
59
|
tool?: Record<string, ReturnType<typeof tool>>;
|
|
60
|
+
"command.execute.before"?: (input: {
|
|
61
|
+
command: string;
|
|
62
|
+
sessionID: string;
|
|
63
|
+
arguments: string;
|
|
64
|
+
}, output: {
|
|
65
|
+
parts: Part[];
|
|
66
|
+
}) => Promise<void>;
|
|
55
67
|
}>;
|
|
56
68
|
export declare const VibeWebhookPlugin: Plugin;
|
|
57
69
|
export default VibeWebhookPlugin;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAiBhD,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE;YACR,GAAG,EAAE,CAAC,IAAI,EAAE;gBAAE,IAAI,EAAE;oBAAE,EAAE,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,KAAK,OAAO,CAAC;gBAAE,IAAI,CAAC,EAAE,WAAW,CAAA;aAAE,CAAC,CAAC;SAC1E,CAAC;KACH,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,WAAW;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAk1BD,KAAK,MAAM,GAAG,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC;IAC5C,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,aAAa,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAiBhD,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE;YACR,GAAG,EAAE,CAAC,IAAI,EAAE;gBAAE,IAAI,EAAE;oBAAE,EAAE,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,KAAK,OAAO,CAAC;gBAAE,IAAI,CAAC,EAAE,WAAW,CAAA;aAAE,CAAC,CAAC;SAC1E,CAAC;KACH,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,WAAW;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAk1BD,UAAU,IAAI;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AA+ND,KAAK,MAAM,GAAG,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC;IAC5C,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,aAAa,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;IAC/C,wBAAwB,CAAC,EAAE,CACzB,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAChE,MAAM,EAAE;QAAE,KAAK,EAAE,IAAI,EAAE,CAAA;KAAE,KACtB,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC,CAAC;AAEH,eAAO,MAAM,iBAAiB,EAAE,MA6B/B,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -695,6 +695,233 @@ Direct webhooks will still work.`;
|
|
|
695
695
|
}
|
|
696
696
|
}
|
|
697
697
|
});
|
|
698
|
+
async function handleVibehookCommand(args) {
|
|
699
|
+
const config = loadConfigFile();
|
|
700
|
+
const parts = args.trim().split(/\s+/);
|
|
701
|
+
const command = parts[0] || "status";
|
|
702
|
+
switch (command) {
|
|
703
|
+
case "status": {
|
|
704
|
+
const vibeStatus = config.vibeNotifyEnabled ? `✅ Enabled (${config.vibeAgentUrl})` : "❌ Disabled";
|
|
705
|
+
const vibeEvents = config.vibeNotifyEvents.join(", ");
|
|
706
|
+
const webhookCount = config.webhooks.filter((w) => w.enabled).length;
|
|
707
|
+
let status = `**VibeControls Webhook Plugin**
|
|
708
|
+
|
|
709
|
+
`;
|
|
710
|
+
status += `**VibeControls Agent**: ${vibeStatus}
|
|
711
|
+
`;
|
|
712
|
+
status += `**Events**: ${vibeEvents}
|
|
713
|
+
`;
|
|
714
|
+
status += `**Additional Webhooks**: ${webhookCount} enabled
|
|
715
|
+
`;
|
|
716
|
+
status += `**Config**: ${config.configPath}
|
|
717
|
+
`;
|
|
718
|
+
if (config.webhooks.length > 0) {
|
|
719
|
+
status += `
|
|
720
|
+
**Webhooks**:
|
|
721
|
+
`;
|
|
722
|
+
for (const w of config.webhooks) {
|
|
723
|
+
const icon = w.enabled ? "✅" : "❌";
|
|
724
|
+
status += `${icon} ${w.name} (${w.id})
|
|
725
|
+
`;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
return status;
|
|
729
|
+
}
|
|
730
|
+
case "add": {
|
|
731
|
+
const url = parts[1];
|
|
732
|
+
const name = parts.slice(2).join(" ");
|
|
733
|
+
if (!url) {
|
|
734
|
+
return `Error: URL is required.
|
|
735
|
+
|
|
736
|
+
Usage: /vibehook add <url> [name]
|
|
737
|
+
|
|
738
|
+
Examples:
|
|
739
|
+
- /vibehook add https://hooks.slack.com/services/xxx
|
|
740
|
+
- /vibehook add https://discord.com/api/webhooks/xxx "My Discord"`;
|
|
741
|
+
}
|
|
742
|
+
const existing = config.webhooks.find((w) => w.url === url);
|
|
743
|
+
if (existing) {
|
|
744
|
+
return `Webhook already exists: ${existing.name} (${existing.id})`;
|
|
745
|
+
}
|
|
746
|
+
const webhook = {
|
|
747
|
+
id: generateId(),
|
|
748
|
+
url,
|
|
749
|
+
name: name || detectWebhookName(url),
|
|
750
|
+
enabled: true,
|
|
751
|
+
events: ["default"]
|
|
752
|
+
};
|
|
753
|
+
config.webhooks.push(webhook);
|
|
754
|
+
saveConfigFile(config);
|
|
755
|
+
return `✅ Webhook added!
|
|
756
|
+
|
|
757
|
+
**ID**: ${webhook.id}
|
|
758
|
+
**Name**: ${webhook.name}
|
|
759
|
+
**URL**: ${webhook.url}
|
|
760
|
+
**Events**: default`;
|
|
761
|
+
}
|
|
762
|
+
case "list": {
|
|
763
|
+
if (config.webhooks.length === 0) {
|
|
764
|
+
return `No additional webhooks configured.
|
|
765
|
+
|
|
766
|
+
VibeControls Agent is the primary webhook destination.
|
|
767
|
+
Add more with: /vibehook add <url>`;
|
|
768
|
+
}
|
|
769
|
+
const lines = config.webhooks.map((w) => {
|
|
770
|
+
const status = w.enabled ? "✅" : "❌";
|
|
771
|
+
return `${status} **${w.name}** (${w.id})
|
|
772
|
+
URL: ${w.url}
|
|
773
|
+
Events: ${w.events.join(", ")}`;
|
|
774
|
+
});
|
|
775
|
+
return `**Additional Webhooks (${config.webhooks.length})**
|
|
776
|
+
|
|
777
|
+
${lines.join(`
|
|
778
|
+
|
|
779
|
+
`)}`;
|
|
780
|
+
}
|
|
781
|
+
case "remove": {
|
|
782
|
+
const id = parts[1];
|
|
783
|
+
if (!id) {
|
|
784
|
+
return `Error: ID is required.
|
|
785
|
+
|
|
786
|
+
Usage: /vibehook remove <id>
|
|
787
|
+
|
|
788
|
+
Run /vibehook list to see webhook IDs.`;
|
|
789
|
+
}
|
|
790
|
+
const index = config.webhooks.findIndex((w) => w.id === id);
|
|
791
|
+
if (index === -1) {
|
|
792
|
+
return `Webhook not found: ${id}`;
|
|
793
|
+
}
|
|
794
|
+
const removed = config.webhooks.splice(index, 1)[0];
|
|
795
|
+
saveConfigFile(config);
|
|
796
|
+
return `✅ Webhook removed: ${removed.name}`;
|
|
797
|
+
}
|
|
798
|
+
case "enable": {
|
|
799
|
+
const id = parts[1];
|
|
800
|
+
if (!id) {
|
|
801
|
+
return `Error: ID is required.
|
|
802
|
+
|
|
803
|
+
Usage: /vibehook enable <id>`;
|
|
804
|
+
}
|
|
805
|
+
const webhook = config.webhooks.find((w) => w.id === id);
|
|
806
|
+
if (!webhook) {
|
|
807
|
+
return `Webhook not found: ${id}`;
|
|
808
|
+
}
|
|
809
|
+
webhook.enabled = true;
|
|
810
|
+
saveConfigFile(config);
|
|
811
|
+
return `✅ Webhook enabled: ${webhook.name}`;
|
|
812
|
+
}
|
|
813
|
+
case "disable": {
|
|
814
|
+
const id = parts[1];
|
|
815
|
+
if (!id) {
|
|
816
|
+
return `Error: ID is required.
|
|
817
|
+
|
|
818
|
+
Usage: /vibehook disable <id>`;
|
|
819
|
+
}
|
|
820
|
+
const webhook = config.webhooks.find((w) => w.id === id);
|
|
821
|
+
if (!webhook) {
|
|
822
|
+
return `Webhook not found: ${id}`;
|
|
823
|
+
}
|
|
824
|
+
webhook.enabled = false;
|
|
825
|
+
saveConfigFile(config);
|
|
826
|
+
return `✅ Webhook disabled: ${webhook.name}`;
|
|
827
|
+
}
|
|
828
|
+
case "test": {
|
|
829
|
+
const testPayload = {
|
|
830
|
+
id: generateEventId(),
|
|
831
|
+
timestamp: new Date().toISOString(),
|
|
832
|
+
event: {
|
|
833
|
+
type: "test",
|
|
834
|
+
sessionTitle: "Test notification from OpenCode",
|
|
835
|
+
properties: { test: true }
|
|
836
|
+
},
|
|
837
|
+
source: {
|
|
838
|
+
agent: "opencode",
|
|
839
|
+
plugin: "opencode-vibe-webhook",
|
|
840
|
+
version: PLUGIN_VERSION
|
|
841
|
+
}
|
|
842
|
+
};
|
|
843
|
+
const id = parts[1];
|
|
844
|
+
if (!id) {
|
|
845
|
+
const vibeUrl = `${config.vibeAgentUrl}${VIBE_NOTIFY_ENDPOINT}`;
|
|
846
|
+
try {
|
|
847
|
+
const response = await fetch(vibeUrl, {
|
|
848
|
+
method: "POST",
|
|
849
|
+
headers: { "Content-Type": "application/json" },
|
|
850
|
+
body: JSON.stringify(testPayload),
|
|
851
|
+
signal: AbortSignal.timeout(5000)
|
|
852
|
+
});
|
|
853
|
+
if (response.ok) {
|
|
854
|
+
return `✅ VibeControls Agent is reachable!
|
|
855
|
+
|
|
856
|
+
URL: ${vibeUrl}
|
|
857
|
+
Webhooks configured in VibeControls will receive events.`;
|
|
858
|
+
} else {
|
|
859
|
+
return `⚠️ VibeControls Agent returned ${response.status}
|
|
860
|
+
|
|
861
|
+
URL: ${vibeUrl}
|
|
862
|
+
Make sure vibe-plugin-notify is installed and running.`;
|
|
863
|
+
}
|
|
864
|
+
} catch (error) {
|
|
865
|
+
return `❌ VibeControls Agent not reachable
|
|
866
|
+
|
|
867
|
+
URL: ${vibeUrl}
|
|
868
|
+
Error: ${error instanceof Error ? error.message : error}
|
|
869
|
+
|
|
870
|
+
Make sure VibeControls Agent is running with vibe-plugin-notify.`;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
const webhook = config.webhooks.find((w) => w.id === id);
|
|
874
|
+
if (!webhook) {
|
|
875
|
+
return `Webhook not found: ${id}`;
|
|
876
|
+
}
|
|
877
|
+
const success = await sendWebhook(webhook.url, testPayload, config, webhook.name);
|
|
878
|
+
return success ? `✅ Test sent to ${webhook.name}` : `❌ Test failed for ${webhook.name}. Check the URL.`;
|
|
879
|
+
}
|
|
880
|
+
case "events": {
|
|
881
|
+
const presets = Object.entries(EVENT_PRESETS).map(([name, events]) => `**${name}**: ${events.join(", ")}`).join(`
|
|
882
|
+
`);
|
|
883
|
+
return `**Event Presets**
|
|
884
|
+
|
|
885
|
+
${presets}
|
|
886
|
+
|
|
887
|
+
**Default**: Webhooks use "default" preset.
|
|
888
|
+
|
|
889
|
+
Edit ${config.configPath} to customize events per webhook.`;
|
|
890
|
+
}
|
|
891
|
+
case "vibe-enable": {
|
|
892
|
+
config.vibeNotifyEnabled = true;
|
|
893
|
+
saveConfigFile(config);
|
|
894
|
+
return `✅ VibeControls notifications enabled.
|
|
895
|
+
|
|
896
|
+
Events will be sent to: ${config.vibeAgentUrl}`;
|
|
897
|
+
}
|
|
898
|
+
case "vibe-disable": {
|
|
899
|
+
config.vibeNotifyEnabled = false;
|
|
900
|
+
saveConfigFile(config);
|
|
901
|
+
return `❌ VibeControls notifications disabled.
|
|
902
|
+
|
|
903
|
+
Direct webhooks will still work.`;
|
|
904
|
+
}
|
|
905
|
+
case "help":
|
|
906
|
+
default:
|
|
907
|
+
return `**VibeControls Webhook Plugin**
|
|
908
|
+
|
|
909
|
+
Manage webhook notifications for OpenCode events.
|
|
910
|
+
|
|
911
|
+
**Commands:**
|
|
912
|
+
- \`/vibehook\` or \`/vibehook status\` - Show current configuration
|
|
913
|
+
- \`/vibehook add <url> [name]\` - Add a webhook (Slack, Discord, custom)
|
|
914
|
+
- \`/vibehook list\` - List all additional webhooks
|
|
915
|
+
- \`/vibehook remove <id>\` - Remove a webhook
|
|
916
|
+
- \`/vibehook enable <id>\` - Enable a webhook
|
|
917
|
+
- \`/vibehook disable <id>\` - Disable a webhook
|
|
918
|
+
- \`/vibehook test [id]\` - Test a webhook (or VibeControls if no id)
|
|
919
|
+
- \`/vibehook events\` - Show available event presets
|
|
920
|
+
- \`/vibehook vibe-enable\` - Enable VibeControls notifications
|
|
921
|
+
- \`/vibehook vibe-disable\` - Disable VibeControls notifications
|
|
922
|
+
- \`/vibehook help\` - Show this help message`;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
698
925
|
var VibeWebhookPlugin = async (ctx) => {
|
|
699
926
|
const config = loadConfigFile();
|
|
700
927
|
log(config, `Plugin initialized (v${PLUGIN_VERSION})`);
|
|
@@ -707,6 +934,15 @@ var VibeWebhookPlugin = async (ctx) => {
|
|
|
707
934
|
},
|
|
708
935
|
tool: {
|
|
709
936
|
vibehook: vibehookTool
|
|
937
|
+
},
|
|
938
|
+
"command.execute.before": async (input, output) => {
|
|
939
|
+
if (input.command === "vibehook") {
|
|
940
|
+
const result = await handleVibehookCommand(input.arguments);
|
|
941
|
+
output.parts.push({
|
|
942
|
+
type: "text",
|
|
943
|
+
text: result
|
|
944
|
+
});
|
|
945
|
+
}
|
|
710
946
|
}
|
|
711
947
|
};
|
|
712
948
|
};
|