@prbe.ai/electron-sdk 0.1.8 → 0.1.10

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.mjs CHANGED
@@ -122,7 +122,7 @@ var PRBEAgentState = class extends EventEmitter {
122
122
  activeCRs = /* @__PURE__ */ new Map();
123
123
  completedCRs = [];
124
124
  // Tracked tickets
125
- trackedTicketIDs = [];
125
+ trackedSessionIDs = [];
126
126
  ticketInfo = [];
127
127
  // Computed
128
128
  get hasActiveWork() {
@@ -350,8 +350,8 @@ var PRBEAgentState = class extends EventEmitter {
350
350
  this.emit("status" /* STATUS */);
351
351
  }
352
352
  // ---------- Tickets ----------
353
- updateTrackedTicketIDs(ids) {
354
- this.trackedTicketIDs = ids;
353
+ updateTrackedSessionIDs(ids) {
354
+ this.trackedSessionIDs = ids;
355
355
  this.emit("tickets-changed" /* TICKETS_CHANGED */, ids);
356
356
  this.emit("status" /* STATUS */);
357
357
  }
@@ -629,7 +629,8 @@ var SearchContentTool = class {
629
629
  { name: "pattern", type: "STRING" /* STRING */, description: "Regex pattern", required: true },
630
630
  { name: "path", type: "STRING" /* STRING */, description: "File or directory to search", required: true },
631
631
  { name: "context_lines", type: "INTEGER" /* INTEGER */, description: "Context lines (default 2)", required: false },
632
- { name: "max_results", type: "INTEGER" /* INTEGER */, description: "Max results (default 50)", required: false }
632
+ { name: "max_results", type: "INTEGER" /* INTEGER */, description: "Max results (default 50)", required: false },
633
+ { name: "case_sensitive", type: "BOOLEAN" /* BOOLEAN */, description: "Case-sensitive search (default false)", required: false }
633
634
  ]
634
635
  };
635
636
  }
@@ -642,9 +643,10 @@ var SearchContentTool = class {
642
643
  if (!resolved) return `Error: ${resolveErr}`;
643
644
  const contextLines = typeof args["context_lines"] === "number" ? args["context_lines"] : 2;
644
645
  const maxResults = typeof args["max_results"] === "number" ? args["max_results"] : 50;
646
+ const caseSensitive = args["case_sensitive"] === true;
645
647
  let regex;
646
648
  try {
647
- regex = new RegExp(pattern);
649
+ regex = new RegExp(pattern, caseSensitive ? "" : "i");
648
650
  } catch {
649
651
  return `Error: invalid regex pattern '${pattern}'`;
650
652
  }
@@ -732,7 +734,8 @@ var FindFilesTool = class {
732
734
  parameters: [
733
735
  { name: "pattern", type: "STRING" /* STRING */, description: "Glob pattern", required: true },
734
736
  { name: "path", type: "STRING" /* STRING */, description: "Directory to search", required: true },
735
- { name: "max_results", type: "INTEGER" /* INTEGER */, description: "Max results (default 50)", required: false }
737
+ { name: "max_results", type: "INTEGER" /* INTEGER */, description: "Max results (default 50)", required: false },
738
+ { name: "case_sensitive", type: "BOOLEAN" /* BOOLEAN */, description: "Case-sensitive matching (default false)", required: false }
736
739
  ]
737
740
  };
738
741
  }
@@ -744,8 +747,9 @@ var FindFilesTool = class {
744
747
  const [resolved, resolveErr] = await resolvePath(pathStr, this.autoApprovedDirs, this.requester, this.grantedPaths);
745
748
  if (!resolved) return `Error: ${resolveErr}`;
746
749
  const maxResults = typeof args["max_results"] === "number" ? args["max_results"] : 50;
750
+ const caseSensitive = args["case_sensitive"] === true;
747
751
  const matches = [];
748
- this.walkAndMatch(resolved, pattern, matches);
752
+ this.walkAndMatch(resolved, pattern, matches, caseSensitive);
749
753
  matches.sort((a, b) => b.modified.getTime() - a.modified.getTime());
750
754
  const limited = matches.slice(0, maxResults);
751
755
  if (limited.length === 0) {
@@ -762,7 +766,7 @@ var FindFilesTool = class {
762
766
  }
763
767
  return result;
764
768
  }
765
- walkAndMatch(dirPath, pattern, matches) {
769
+ walkAndMatch(dirPath, pattern, matches, caseSensitive) {
766
770
  let entries;
767
771
  try {
768
772
  entries = fs.readdirSync(dirPath, { withFileTypes: true });
@@ -773,9 +777,9 @@ var FindFilesTool = class {
773
777
  if (entry.name.startsWith(".")) continue;
774
778
  const fullPath = path2.join(dirPath, entry.name);
775
779
  if (entry.isDirectory()) {
776
- this.walkAndMatch(fullPath, pattern, matches);
780
+ this.walkAndMatch(fullPath, pattern, matches, caseSensitive);
777
781
  } else if (entry.isFile()) {
778
- if (this.globMatch(entry.name, pattern)) {
782
+ if (this.globMatch(entry.name, pattern, caseSensitive)) {
779
783
  try {
780
784
  const stat = fs.statSync(fullPath);
781
785
  matches.push({
@@ -793,7 +797,7 @@ var FindFilesTool = class {
793
797
  * Simple glob matching: supports *, ?, and character classes [...].
794
798
  * Converts glob to regex and tests against the filename.
795
799
  */
796
- globMatch(filename, pattern) {
800
+ globMatch(filename, pattern, caseSensitive) {
797
801
  let regexStr = "^";
798
802
  for (let i = 0; i < pattern.length; i++) {
799
803
  const c = pattern[i];
@@ -831,7 +835,7 @@ var FindFilesTool = class {
831
835
  }
832
836
  regexStr += "$";
833
837
  try {
834
- return new RegExp(regexStr).test(filename);
838
+ return new RegExp(regexStr, caseSensitive ? "" : "i").test(filename);
835
839
  } catch {
836
840
  return false;
837
841
  }
@@ -1740,13 +1744,13 @@ var PRBEAgent = class _PRBEAgent {
1740
1744
  savePersistedData(this.persistedData);
1741
1745
  return newID;
1742
1746
  }
1743
- get trackedTicketIDs() {
1744
- return this.persistedData.ticketIds ?? [];
1747
+ get trackedSessionIDs() {
1748
+ return this.persistedData.sessionIds ?? [];
1745
1749
  }
1746
- set trackedTicketIDs(ids) {
1747
- this.persistedData.ticketIds = ids;
1750
+ set trackedSessionIDs(ids) {
1751
+ this.persistedData.sessionIds = ids;
1748
1752
  savePersistedData(this.persistedData);
1749
- this.state.updateTrackedTicketIDs(ids);
1753
+ this.state.updateTrackedSessionIDs(ids);
1750
1754
  this.syncPolling(ids.length > 0);
1751
1755
  }
1752
1756
  get respondedCRIDs() {
@@ -1756,19 +1760,19 @@ var PRBEAgent = class _PRBEAgent {
1756
1760
  this.persistedData.respondedCRIds = Array.from(ids);
1757
1761
  savePersistedData(this.persistedData);
1758
1762
  }
1759
- syncPolling(hasTickets) {
1760
- if (this.config.backgroundPolling && hasTickets) {
1763
+ syncPolling(hasSessions) {
1764
+ if (this.config.backgroundPolling && hasSessions) {
1761
1765
  if (this.pollingTimer === null) {
1762
1766
  this.startPolling();
1763
1767
  }
1764
- } else if (!hasTickets) {
1768
+ } else if (!hasSessions) {
1765
1769
  this.stopPolling();
1766
1770
  }
1767
1771
  }
1768
- addTrackedTicket(id) {
1769
- const ids = this.trackedTicketIDs;
1772
+ addTrackedSession(id) {
1773
+ const ids = this.trackedSessionIDs;
1770
1774
  if (!ids.includes(id)) {
1771
- this.trackedTicketIDs = [...ids, id];
1775
+ this.trackedSessionIDs = [...ids, id];
1772
1776
  }
1773
1777
  }
1774
1778
  // ---------- Constructor ----------
@@ -1826,9 +1830,9 @@ var PRBEAgent = class _PRBEAgent {
1826
1830
  if (config.ipcMain) {
1827
1831
  this.hookRendererLogs(config.ipcMain, config.rendererLogChannel ?? "prbe-renderer-log");
1828
1832
  }
1829
- const existingTickets = this.trackedTicketIDs;
1830
- if (existingTickets.length > 0) {
1831
- this.trackedTicketIDs = existingTickets;
1833
+ const existingSessions = this.trackedSessionIDs;
1834
+ if (existingSessions.length > 0) {
1835
+ this.trackedSessionIDs = existingSessions;
1832
1836
  }
1833
1837
  }
1834
1838
  // ---------- Log integration ----------
@@ -1959,8 +1963,8 @@ var PRBEAgent = class _PRBEAgent {
1959
1963
  );
1960
1964
  this.currentInvestigationSource = "user" /* USER */;
1961
1965
  this.currentCRId = null;
1962
- if (result?.ticketId) {
1963
- this.addTrackedTicket(result.ticketId);
1966
+ if (result?.sessionId) {
1967
+ this.addTrackedSession(result.sessionId);
1964
1968
  } else if (!result) {
1965
1969
  if (this.state.isInvestigating) {
1966
1970
  const message = this.userCancelled ? "Investigation cancelled" : "Investigation ended unexpectedly";
@@ -1992,33 +1996,37 @@ var PRBEAgent = class _PRBEAgent {
1992
1996
  }
1993
1997
  /**
1994
1998
  * Poll the backend for context requests on tracked tickets.
1999
+ * Resolves session IDs → ticket IDs first, then polls with ticket IDs.
1995
2000
  */
1996
2001
  async poll() {
1997
- const ticketIDs = this.trackedTicketIDs;
1998
- if (ticketIDs.length === 0) return null;
1999
- const request = {
2000
- agent_id: this.agentID,
2001
- ticket_ids: ticketIDs
2002
- };
2002
+ const sessionIDs = this.trackedSessionIDs;
2003
+ if (sessionIDs.length === 0) return null;
2003
2004
  try {
2005
+ const resolved = await this.resolveSessions(sessionIDs);
2006
+ const returnedSessionIDs = new Set(
2007
+ resolved.tickets.flatMap((t) => t.session_ids)
2008
+ );
2009
+ const resolvedSessionIDs = new Set(
2010
+ resolved.tickets.filter((t) => t.status === "resolved").flatMap((t) => t.session_ids)
2011
+ );
2012
+ const survivingSessions = sessionIDs.filter(
2013
+ (id) => returnedSessionIDs.has(id) && !resolvedSessionIDs.has(id)
2014
+ );
2015
+ if (survivingSessions.length !== sessionIDs.length) {
2016
+ this.trackedSessionIDs = survivingSessions;
2017
+ }
2018
+ const ticketIDs = resolved.tickets.filter((t) => t.status !== "resolved").map((t) => t.ticket_id);
2019
+ if (ticketIDs.length === 0) return { tickets: [] };
2020
+ const request = {
2021
+ agent_id: this.agentID,
2022
+ ticket_ids: ticketIDs
2023
+ };
2004
2024
  const response = await this.post(
2005
2025
  "/api/agent/poll",
2006
2026
  request
2007
2027
  );
2008
- const returnedIDs = new Set(response.tickets.map((t) => t.ticket_id));
2009
- const orphaned = ticketIDs.filter((id) => !returnedIDs.has(id));
2010
- if (orphaned.length > 0) {
2011
- this.trackedTicketIDs = this.trackedTicketIDs.filter(
2012
- (id) => !orphaned.includes(id)
2013
- );
2014
- }
2015
2028
  const knownCRIDs = /* @__PURE__ */ new Set();
2016
2029
  for (const ticket of response.tickets) {
2017
- if (ticket.status === "resolved") {
2018
- this.trackedTicketIDs = this.trackedTicketIDs.filter(
2019
- (id) => id !== ticket.ticket_id
2020
- );
2021
- }
2022
2030
  for (const cr of ticket.context_requests) {
2023
2031
  knownCRIDs.add(cr.id);
2024
2032
  if (!cr.is_active || this.respondedCRIDs.has(cr.id)) continue;
@@ -2044,13 +2052,17 @@ var PRBEAgent = class _PRBEAgent {
2044
2052
  }
2045
2053
  }
2046
2054
  /**
2047
- * Fetch ticket display info for all tracked tickets.
2055
+ * Fetch ticket display info for all tracked sessions.
2056
+ * Resolves session IDs → ticket IDs first, then fetches ticket info.
2048
2057
  */
2049
2058
  async fetchTicketInfo() {
2050
- const ticketIDs = this.trackedTicketIDs;
2051
- if (ticketIDs.length === 0) return [];
2052
- const request = { ticket_ids: ticketIDs };
2059
+ const sessionIDs = this.trackedSessionIDs;
2060
+ if (sessionIDs.length === 0) return [];
2053
2061
  try {
2062
+ const resolved = await this.resolveSessions(sessionIDs);
2063
+ const ticketIDs = resolved.tickets.map((t) => t.ticket_id);
2064
+ if (ticketIDs.length === 0) return [];
2065
+ const request = { ticket_ids: ticketIDs };
2054
2066
  const response = await this.post(
2055
2067
  "/api/agent/tickets",
2056
2068
  request
@@ -2068,7 +2080,7 @@ var PRBEAgent = class _PRBEAgent {
2068
2080
  }
2069
2081
  }
2070
2082
  resumePolling() {
2071
- if (this.trackedTicketIDs.length === 0) return;
2083
+ if (this.trackedSessionIDs.length === 0) return;
2072
2084
  this.startPolling();
2073
2085
  }
2074
2086
  /**
@@ -2091,7 +2103,7 @@ var PRBEAgent = class _PRBEAgent {
2091
2103
  this.state.completedInvestigations = [];
2092
2104
  this.state.activeCRs.clear();
2093
2105
  this.state.completedCRs = [];
2094
- this.state.trackedTicketIDs = [];
2106
+ this.state.trackedSessionIDs = [];
2095
2107
  this.state.ticketInfo = [];
2096
2108
  this.state.emit("status" /* STATUS */);
2097
2109
  }
@@ -2150,8 +2162,8 @@ var PRBEAgent = class _PRBEAgent {
2150
2162
  );
2151
2163
  this.currentInvestigationSource = "user" /* USER */;
2152
2164
  this.currentCRId = null;
2153
- if (result?.ticketId) {
2154
- this.addTrackedTicket(result.ticketId);
2165
+ if (result?.sessionId) {
2166
+ this.addTrackedSession(result.sessionId);
2155
2167
  }
2156
2168
  }
2157
2169
  // ---------- WebSocket Investigation ----------
@@ -2328,6 +2340,7 @@ var PRBEAgent = class _PRBEAgent {
2328
2340
  const report = msg.content ?? "";
2329
2341
  const userSummary = msg.metadata?.["user_summary"] ?? "";
2330
2342
  const ticketId2 = msg.metadata?.["ticket_id"];
2343
+ const sessionId = msg.metadata?.["session_id"];
2331
2344
  emit({
2332
2345
  type: "completed" /* COMPLETED */,
2333
2346
  report,
@@ -2335,7 +2348,7 @@ var PRBEAgent = class _PRBEAgent {
2335
2348
  ticketId: ticketId2
2336
2349
  });
2337
2350
  ws.close(1e3, "Complete");
2338
- finish({ report, userSummary, ticketId: ticketId2 });
2351
+ finish({ report, userSummary, ticketId: ticketId2, sessionId });
2339
2352
  break;
2340
2353
  }
2341
2354
  case "error" /* ERROR */:
@@ -2446,12 +2459,23 @@ var PRBEAgent = class _PRBEAgent {
2446
2459
  this.stopPolling();
2447
2460
  this.pollingTimer = setInterval(() => {
2448
2461
  void this.poll().then(() => {
2449
- if (this.trackedTicketIDs.length === 0) {
2462
+ if (this.trackedSessionIDs.length === 0) {
2450
2463
  this.stopPolling();
2451
2464
  }
2452
2465
  });
2453
2466
  }, this.config.pollingInterval);
2454
2467
  }
2468
+ // ---------- Session Resolution ----------
2469
+ async resolveSessions(sessionIDs) {
2470
+ const request = {
2471
+ agent_id: this.agentID,
2472
+ session_ids: sessionIDs
2473
+ };
2474
+ return this.post(
2475
+ "/api/agent/resolve-sessions",
2476
+ request
2477
+ );
2478
+ }
2455
2479
  // ---------- Networking ----------
2456
2480
  /**
2457
2481
  * Abort all in-flight fetch requests to prevent orphaned DNS lookups
@@ -2506,7 +2530,7 @@ var DEFAULT_PRBE_STATE = {
2506
2530
  completedInvestigations: [],
2507
2531
  activeCRs: [],
2508
2532
  completedCRs: [],
2509
- trackedTicketIDs: [],
2533
+ trackedSessionIDs: [],
2510
2534
  ticketInfo: [],
2511
2535
  hasActiveWork: false
2512
2536
  };
@@ -2550,7 +2574,7 @@ function serializePRBEState(state) {
2550
2574
  })),
2551
2575
  activeCRs: Array.from(state.activeCRs.values()).map(serializeCR),
2552
2576
  completedCRs: state.completedCRs.map(serializeCR),
2553
- trackedTicketIDs: state.trackedTicketIDs,
2577
+ trackedSessionIDs: state.trackedSessionIDs,
2554
2578
  ticketInfo: state.ticketInfo,
2555
2579
  hasActiveWork: state.hasActiveWork
2556
2580
  };