@mohak34/opencode-notifier 0.1.21 → 0.1.22-beta.0

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.
Files changed (2) hide show
  1. package/dist/index.js +53 -19
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3756,28 +3756,32 @@ var DEFAULT_CONFIG = {
3756
3756
  complete: { ...DEFAULT_EVENT_CONFIG },
3757
3757
  subagent_complete: { sound: false, notification: false },
3758
3758
  error: { ...DEFAULT_EVENT_CONFIG },
3759
- question: { ...DEFAULT_EVENT_CONFIG }
3759
+ question: { ...DEFAULT_EVENT_CONFIG },
3760
+ interrupted: { ...DEFAULT_EVENT_CONFIG }
3760
3761
  },
3761
3762
  messages: {
3762
3763
  permission: "Session needs permission: {sessionTitle}",
3763
3764
  complete: "Session has finished: {sessionTitle}",
3764
3765
  subagent_complete: "Subagent task completed: {sessionTitle}",
3765
3766
  error: "Session encountered an error: {sessionTitle}",
3766
- question: "Session has a question: {sessionTitle}"
3767
+ question: "Session has a question: {sessionTitle}",
3768
+ interrupted: "Session was interrupted: {sessionTitle}"
3767
3769
  },
3768
3770
  sounds: {
3769
3771
  permission: null,
3770
3772
  complete: null,
3771
3773
  subagent_complete: null,
3772
3774
  error: null,
3773
- question: null
3775
+ question: null,
3776
+ interrupted: null
3774
3777
  },
3775
3778
  volumes: {
3776
3779
  permission: 1,
3777
3780
  complete: 1,
3778
3781
  subagent_complete: 1,
3779
3782
  error: 1,
3780
- question: 1
3783
+ question: 1,
3784
+ interrupted: 1
3781
3785
  }
3782
3786
  };
3783
3787
  function getConfigPath() {
@@ -3846,28 +3850,32 @@ function loadConfig() {
3846
3850
  complete: parseEventConfig(userConfig.events?.complete ?? userConfig.complete, defaultWithGlobal),
3847
3851
  subagent_complete: parseEventConfig(userConfig.events?.subagent_complete ?? userConfig.subagent_complete, { sound: false, notification: false }),
3848
3852
  error: parseEventConfig(userConfig.events?.error ?? userConfig.error, defaultWithGlobal),
3849
- question: parseEventConfig(userConfig.events?.question ?? userConfig.question, defaultWithGlobal)
3853
+ question: parseEventConfig(userConfig.events?.question ?? userConfig.question, defaultWithGlobal),
3854
+ interrupted: parseEventConfig(userConfig.events?.interrupted ?? userConfig.interrupted, defaultWithGlobal)
3850
3855
  },
3851
3856
  messages: {
3852
3857
  permission: userConfig.messages?.permission ?? DEFAULT_CONFIG.messages.permission,
3853
3858
  complete: userConfig.messages?.complete ?? DEFAULT_CONFIG.messages.complete,
3854
3859
  subagent_complete: userConfig.messages?.subagent_complete ?? DEFAULT_CONFIG.messages.subagent_complete,
3855
3860
  error: userConfig.messages?.error ?? DEFAULT_CONFIG.messages.error,
3856
- question: userConfig.messages?.question ?? DEFAULT_CONFIG.messages.question
3861
+ question: userConfig.messages?.question ?? DEFAULT_CONFIG.messages.question,
3862
+ interrupted: userConfig.messages?.interrupted ?? DEFAULT_CONFIG.messages.interrupted
3857
3863
  },
3858
3864
  sounds: {
3859
3865
  permission: userConfig.sounds?.permission ?? DEFAULT_CONFIG.sounds.permission,
3860
3866
  complete: userConfig.sounds?.complete ?? DEFAULT_CONFIG.sounds.complete,
3861
3867
  subagent_complete: userConfig.sounds?.subagent_complete ?? DEFAULT_CONFIG.sounds.subagent_complete,
3862
3868
  error: userConfig.sounds?.error ?? DEFAULT_CONFIG.sounds.error,
3863
- question: userConfig.sounds?.question ?? DEFAULT_CONFIG.sounds.question
3869
+ question: userConfig.sounds?.question ?? DEFAULT_CONFIG.sounds.question,
3870
+ interrupted: userConfig.sounds?.interrupted ?? DEFAULT_CONFIG.sounds.interrupted
3864
3871
  },
3865
3872
  volumes: {
3866
3873
  permission: parseVolume(userConfig.volumes?.permission, DEFAULT_CONFIG.volumes.permission),
3867
3874
  complete: parseVolume(userConfig.volumes?.complete, DEFAULT_CONFIG.volumes.complete),
3868
3875
  subagent_complete: parseVolume(userConfig.volumes?.subagent_complete, DEFAULT_CONFIG.volumes.subagent_complete),
3869
3876
  error: parseVolume(userConfig.volumes?.error, DEFAULT_CONFIG.volumes.error),
3870
- question: parseVolume(userConfig.volumes?.question, DEFAULT_CONFIG.volumes.question)
3877
+ question: parseVolume(userConfig.volumes?.question, DEFAULT_CONFIG.volumes.question),
3878
+ interrupted: parseVolume(userConfig.volumes?.interrupted, DEFAULT_CONFIG.volumes.interrupted)
3871
3879
  }
3872
3880
  };
3873
3881
  } catch {
@@ -4119,6 +4127,15 @@ function runCommand2(config, event, message, sessionTitle, projectName) {
4119
4127
  }
4120
4128
 
4121
4129
  // src/index.ts
4130
+ var recentErrors = new Map;
4131
+ setInterval(() => {
4132
+ const cutoff = Date.now() - 5 * 60 * 1000;
4133
+ for (const [sessionID, timestamp] of recentErrors) {
4134
+ if (timestamp < cutoff) {
4135
+ recentErrors.delete(sessionID);
4136
+ }
4137
+ }
4138
+ }, 5 * 60 * 1000);
4122
4139
  function getNotificationTitle(config, projectName) {
4123
4140
  if (config.showProjectName && projectName) {
4124
4141
  return `OpenCode (${projectName})`;
@@ -4156,7 +4173,7 @@ function getSessionIDFromEvent(event) {
4156
4173
  }
4157
4174
  return null;
4158
4175
  }
4159
- async function getElapsedSinceLastPrompt(client, sessionID) {
4176
+ async function getElapsedSinceLastPrompt(client, sessionID, nowMs = Date.now()) {
4160
4177
  try {
4161
4178
  const response = await client.session.messages({ path: { id: sessionID } });
4162
4179
  const messages = response.data ?? [];
@@ -4170,7 +4187,7 @@ async function getElapsedSinceLastPrompt(client, sessionID) {
4170
4187
  }
4171
4188
  }
4172
4189
  if (lastUserMessageTime !== null) {
4173
- return (Date.now() - lastUserMessageTime) / 1000;
4190
+ return (nowMs - lastUserMessageTime) / 1000;
4174
4191
  }
4175
4192
  } catch {}
4176
4193
  return null;
@@ -4217,11 +4234,18 @@ var NotifierPlugin = async ({ client, directory }) => {
4217
4234
  if (event.type === "session.idle") {
4218
4235
  const sessionID = getSessionIDFromEvent(event);
4219
4236
  if (sessionID) {
4220
- const sessionInfo = await getSessionInfo(client, sessionID);
4221
- if (!sessionInfo.isChild) {
4222
- await handleEventWithElapsedTime(client, config, "complete", projectName, event, sessionInfo.title);
4237
+ const errorTime = recentErrors.get(sessionID);
4238
+ if (errorTime && Date.now() - errorTime < 500) {
4239
+ recentErrors.delete(sessionID);
4240
+ const sessionInfo = await getSessionInfo(client, sessionID);
4241
+ await handleEventWithElapsedTime(client, config, "interrupted", projectName, event, sessionInfo.title);
4223
4242
  } else {
4224
- await handleEventWithElapsedTime(client, config, "subagent_complete", projectName, event, sessionInfo.title);
4243
+ const sessionInfo = await getSessionInfo(client, sessionID);
4244
+ if (!sessionInfo.isChild) {
4245
+ await handleEventWithElapsedTime(client, config, "complete", projectName, event, sessionInfo.title);
4246
+ } else {
4247
+ await handleEventWithElapsedTime(client, config, "subagent_complete", projectName, event, sessionInfo.title);
4248
+ }
4225
4249
  }
4226
4250
  } else {
4227
4251
  await handleEventWithElapsedTime(client, config, "complete", projectName, event);
@@ -4229,12 +4253,22 @@ var NotifierPlugin = async ({ client, directory }) => {
4229
4253
  }
4230
4254
  if (event.type === "session.error") {
4231
4255
  const sessionID = getSessionIDFromEvent(event);
4232
- let sessionTitle = null;
4233
- if (sessionID && config.showSessionTitle) {
4234
- const info = await getSessionInfo(client, sessionID);
4235
- sessionTitle = info.title;
4256
+ if (sessionID) {
4257
+ recentErrors.set(sessionID, Date.now());
4258
+ let sessionTitle = null;
4259
+ if (config.showSessionTitle) {
4260
+ const info = await getSessionInfo(client, sessionID);
4261
+ sessionTitle = info.title;
4262
+ }
4263
+ setTimeout(() => {
4264
+ if (recentErrors.has(sessionID)) {
4265
+ recentErrors.delete(sessionID);
4266
+ handleEventWithElapsedTime(client, config, "error", projectName, event, sessionTitle);
4267
+ }
4268
+ }, 100);
4269
+ } else {
4270
+ await handleEventWithElapsedTime(client, config, "error", projectName, event);
4236
4271
  }
4237
- await handleEventWithElapsedTime(client, config, "error", projectName, event, sessionTitle);
4238
4272
  }
4239
4273
  },
4240
4274
  "permission.ask": async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mohak34/opencode-notifier",
3
- "version": "0.1.21",
3
+ "version": "0.1.22-beta.0",
4
4
  "description": "OpenCode plugin that sends system notifications and plays sounds when permission is needed, generation completes, or errors occur",
5
5
  "author": "mohak34",
6
6
  "license": "MIT",