opencode-pilot 0.18.0 → 0.18.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-pilot",
3
- "version": "0.18.0",
3
+ "version": "0.18.1",
4
4
  "type": "module",
5
5
  "main": "plugin/index.js",
6
6
  "description": "Automation daemon for OpenCode - polls for work and spawns sessions",
@@ -124,7 +124,12 @@ export async function pollOnce(options = {}) {
124
124
  // Fetch items from source
125
125
  if (!skipMcp) {
126
126
  try {
127
- toolProviderConfig = getToolProviderConfig(source.tool.mcp);
127
+ // Get provider config - for MCP sources use source.tool.mcp, for CLI sources detect provider
128
+ let provider = source.tool.mcp;
129
+ if (!provider && Array.isArray(source.tool?.command) && source.tool.command[0] === 'gh') {
130
+ provider = 'github'; // CLI-based GitHub source
131
+ }
132
+ toolProviderConfig = getToolProviderConfig(provider);
128
133
  items = await pollGenericSource(source, { toolProviderConfig });
129
134
  debug(`Fetched ${items.length} items from ${sourceName}`);
130
135
 
package/service/poller.js CHANGED
@@ -12,7 +12,7 @@ import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
12
12
  import fs from "fs";
13
13
  import path from "path";
14
14
  import os from "os";
15
- import { getNestedValue } from "./utils.js";
15
+ import { getNestedValue, hasNonBotFeedback } from "./utils.js";
16
16
 
17
17
  /**
18
18
  * Expand template string with item fields
@@ -501,6 +501,22 @@ export async function fetchGitHubComments(item, options = {}) {
501
501
  }
502
502
  }
503
503
 
504
+ /**
505
+ * Check if a source is a GitHub source (MCP or CLI-based)
506
+ * @param {object} source - Source configuration
507
+ * @returns {boolean} True if this is a GitHub source
508
+ */
509
+ function isGitHubSource(source) {
510
+ // MCP-based GitHub source
511
+ if (source.tool?.mcp === "github") return true;
512
+
513
+ // CLI-based GitHub source (uses gh command)
514
+ const command = source.tool?.command;
515
+ if (Array.isArray(command) && command[0] === "gh") return true;
516
+
517
+ return false;
518
+ }
519
+
504
520
  /**
505
521
  * Enrich items with comments for bot filtering
506
522
  *
@@ -514,7 +530,7 @@ export async function fetchGitHubComments(item, options = {}) {
514
530
  */
515
531
  export async function enrichItemsWithComments(items, source, options = {}) {
516
532
  // Skip if not configured or not a GitHub source
517
- if (!source.filter_bot_comments || source.tool?.mcp !== "github") {
533
+ if (!source.filter_bot_comments || !isGitHubSource(source)) {
518
534
  return items;
519
535
  }
520
536
 
@@ -618,16 +634,11 @@ export function computeAttentionLabels(items, source) {
618
634
  reasons.push('Conflicts');
619
635
  }
620
636
 
621
- // Check for human feedback (non-bot, non-author comments)
637
+ // Check for human feedback using the shared hasNonBotFeedback utility
638
+ // This properly handles known bots like 'linear' that don't have [bot] suffix
622
639
  if (item._comments && item._comments.length > 0) {
623
640
  const authorUsername = item.user?.login || item.author?.login;
624
- const hasHumanFeedback = item._comments.some(comment => {
625
- const commenter = comment.user?.login || comment.author?.login;
626
- const isBot = commenter?.includes('[bot]') || comment.user?.type === 'Bot';
627
- const isAuthor = commenter === authorUsername;
628
- return !isBot && !isAuthor;
629
- });
630
- if (hasHumanFeedback) {
641
+ if (hasNonBotFeedback(item._comments, authorUsername)) {
631
642
  reasons.push('Feedback');
632
643
  }
633
644
  }
@@ -1013,5 +1013,25 @@ describe('poller.js', () => {
1013
1013
  assert.strictEqual(result[0]._attention_label, 'PR');
1014
1014
  assert.strictEqual(result[0]._has_attention, false);
1015
1015
  });
1016
+
1017
+ test('ignores known bots without [bot] suffix (e.g., linear)', async () => {
1018
+ const { computeAttentionLabels } = await import('../../service/poller.js');
1019
+
1020
+ const items = [{
1021
+ number: 123,
1022
+ title: 'Test PR',
1023
+ user: { login: 'author' },
1024
+ _mergeable: 'MERGEABLE',
1025
+ _comments: [
1026
+ // Linear bot posts linkback comments without [bot] suffix
1027
+ { user: { login: 'linear', type: 'User' }, body: '<!-- linear-linkback -->' }
1028
+ ]
1029
+ }];
1030
+
1031
+ const result = computeAttentionLabels(items, {});
1032
+
1033
+ assert.strictEqual(result[0]._attention_label, 'PR');
1034
+ assert.strictEqual(result[0]._has_attention, false);
1035
+ });
1016
1036
  });
1017
1037
  });