@prbe.ai/electron-sdk 0.1.6 → 0.1.8

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.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as PRBEToolDeclaration, a as PRBEToolParameter, b as PRBEInteractionRequester, F as FlaggedFileIn, c as PRBEAgentState, d as PRBEAgentConfig, I as InvestigationSource, e as InteractionPayload, f as InteractionResponse, g as PollResponse, T as TicketInfoOut } from './types-DHT-JxMT.mjs';
2
- export { A as API_URL, h as AskQuestionPayload, i as AskQuestionResponse, C as ContextRequestOut, D as DEFAULT_PRBE_STATE, j as InteractionType, k as InvestigationResult, M as MIDDLEWARE_URL, l as PRBEAgentConfigKey, m as PRBEAgentError, n as PRBEAgentErrorType, o as PRBEAgentStatus, p as PRBEAgentStatusType, q as PRBECRInvestigation, r as PRBECompletedInvestigation, s as PRBEInteractionHandler, t as PRBESerializedCR, u as PRBESerializedCompletedInvestigation, v as PRBESerializedState, w as PRBESerializedTicket, x as PRBEStateEvent, y as PRBEStatusEvent, z as PollRequest, R as RequestPathAccessPayload, B as RequestPathAccessResponse, E as RequestPermissionPayload, G as RequestPermissionResponse, H as ResolvedInteraction, J as TicketInfoRequest, K as TicketInfoResponse, L as TicketStatusOut, N as ToolName, O as ToolParamType, W as WSMessage, Q as WSMessageType, S as redactPII, U as serializePRBEState } from './types-DHT-JxMT.mjs';
1
+ import { P as PRBEToolDeclaration, a as PRBEToolParameter, b as PRBEInteractionRequester, F as FlaggedFileIn, c as PRBEAgentState, d as PRBEAgentConfig, I as InvestigationSource, e as InteractionPayload, f as InteractionResponse, g as PollResponse, T as TicketInfoOut } from './types-CwYRJCG0.mjs';
2
+ export { A as API_URL, h as AskQuestionPayload, i as AskQuestionResponse, C as ContextRequestOut, D as DEFAULT_PRBE_STATE, j as InteractionType, k as InvestigationResult, M as MIDDLEWARE_URL, l as PRBEAgentConfigKey, m as PRBEAgentError, n as PRBEAgentErrorType, o as PRBEAgentStatus, p as PRBEAgentStatusType, q as PRBECRInvestigation, r as PRBECompletedInvestigation, s as PRBEInteractionHandler, t as PRBESerializedCR, u as PRBESerializedCompletedInvestigation, v as PRBESerializedState, w as PRBESerializedTicket, x as PRBEStateEvent, y as PRBEStatusEvent, z as PollRequest, R as RequestPathAccessPayload, B as RequestPathAccessResponse, E as RequestPermissionPayload, G as RequestPermissionResponse, H as ResolvedInteraction, J as TicketInfoRequest, K as TicketInfoResponse, L as TicketStatusOut, N as ToolName, O as ToolParamType, W as WSMessage, Q as WSMessageType, S as redactPII, U as serializePRBEState } from './types-CwYRJCG0.mjs';
3
3
  import 'events';
4
4
 
5
5
  /**
@@ -21,7 +21,9 @@ declare class PRBEToolRegistry {
21
21
  declare class PRBEClosureTool implements PRBETool {
22
22
  readonly declaration: PRBEToolDeclaration;
23
23
  private readonly handler;
24
- constructor(name: string, description: string, parameters: PRBEToolParameter[], handler: (args: Record<string, unknown>) => Promise<string>);
24
+ constructor(name: string, description: string, parameters: PRBEToolParameter[], handler: (args: Record<string, unknown>) => Promise<string>, options?: {
25
+ interactive?: boolean;
26
+ });
25
27
  execute(args: Record<string, unknown>): Promise<string>;
26
28
  }
27
29
  /**
@@ -144,6 +146,7 @@ declare class PRBEAgent implements PRBEInteractionRequester {
144
146
  private fetchAbortController;
145
147
  private currentInvestigationSource;
146
148
  private currentCRId;
149
+ private readonly historyStore;
147
150
  /** Files flagged during the current tool call — uploaded immediately after the tool returns. */
148
151
  private pendingFlaggedFiles;
149
152
  private get agentID();
@@ -166,7 +169,9 @@ declare class PRBEAgent implements PRBEInteractionRequester {
166
169
  /**
167
170
  * Register a custom tool that the middleware can invoke during investigations.
168
171
  */
169
- registerTool(name: string, description: string, parameters: PRBEToolParameter[], handler: (args: Record<string, unknown>) => Promise<string>): void;
172
+ registerTool(name: string, description: string, parameters: PRBEToolParameter[], handler: (args: Record<string, unknown>) => Promise<string>, options?: {
173
+ interactive?: boolean;
174
+ }): void;
170
175
  /**
171
176
  * User-initiated investigation. Updates `state` events/report directly.
172
177
  */
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as PRBEToolDeclaration, a as PRBEToolParameter, b as PRBEInteractionRequester, F as FlaggedFileIn, c as PRBEAgentState, d as PRBEAgentConfig, I as InvestigationSource, e as InteractionPayload, f as InteractionResponse, g as PollResponse, T as TicketInfoOut } from './types-DHT-JxMT.js';
2
- export { A as API_URL, h as AskQuestionPayload, i as AskQuestionResponse, C as ContextRequestOut, D as DEFAULT_PRBE_STATE, j as InteractionType, k as InvestigationResult, M as MIDDLEWARE_URL, l as PRBEAgentConfigKey, m as PRBEAgentError, n as PRBEAgentErrorType, o as PRBEAgentStatus, p as PRBEAgentStatusType, q as PRBECRInvestigation, r as PRBECompletedInvestigation, s as PRBEInteractionHandler, t as PRBESerializedCR, u as PRBESerializedCompletedInvestigation, v as PRBESerializedState, w as PRBESerializedTicket, x as PRBEStateEvent, y as PRBEStatusEvent, z as PollRequest, R as RequestPathAccessPayload, B as RequestPathAccessResponse, E as RequestPermissionPayload, G as RequestPermissionResponse, H as ResolvedInteraction, J as TicketInfoRequest, K as TicketInfoResponse, L as TicketStatusOut, N as ToolName, O as ToolParamType, W as WSMessage, Q as WSMessageType, S as redactPII, U as serializePRBEState } from './types-DHT-JxMT.js';
1
+ import { P as PRBEToolDeclaration, a as PRBEToolParameter, b as PRBEInteractionRequester, F as FlaggedFileIn, c as PRBEAgentState, d as PRBEAgentConfig, I as InvestigationSource, e as InteractionPayload, f as InteractionResponse, g as PollResponse, T as TicketInfoOut } from './types-CwYRJCG0.js';
2
+ export { A as API_URL, h as AskQuestionPayload, i as AskQuestionResponse, C as ContextRequestOut, D as DEFAULT_PRBE_STATE, j as InteractionType, k as InvestigationResult, M as MIDDLEWARE_URL, l as PRBEAgentConfigKey, m as PRBEAgentError, n as PRBEAgentErrorType, o as PRBEAgentStatus, p as PRBEAgentStatusType, q as PRBECRInvestigation, r as PRBECompletedInvestigation, s as PRBEInteractionHandler, t as PRBESerializedCR, u as PRBESerializedCompletedInvestigation, v as PRBESerializedState, w as PRBESerializedTicket, x as PRBEStateEvent, y as PRBEStatusEvent, z as PollRequest, R as RequestPathAccessPayload, B as RequestPathAccessResponse, E as RequestPermissionPayload, G as RequestPermissionResponse, H as ResolvedInteraction, J as TicketInfoRequest, K as TicketInfoResponse, L as TicketStatusOut, N as ToolName, O as ToolParamType, W as WSMessage, Q as WSMessageType, S as redactPII, U as serializePRBEState } from './types-CwYRJCG0.js';
3
3
  import 'events';
4
4
 
5
5
  /**
@@ -21,7 +21,9 @@ declare class PRBEToolRegistry {
21
21
  declare class PRBEClosureTool implements PRBETool {
22
22
  readonly declaration: PRBEToolDeclaration;
23
23
  private readonly handler;
24
- constructor(name: string, description: string, parameters: PRBEToolParameter[], handler: (args: Record<string, unknown>) => Promise<string>);
24
+ constructor(name: string, description: string, parameters: PRBEToolParameter[], handler: (args: Record<string, unknown>) => Promise<string>, options?: {
25
+ interactive?: boolean;
26
+ });
25
27
  execute(args: Record<string, unknown>): Promise<string>;
26
28
  }
27
29
  /**
@@ -144,6 +146,7 @@ declare class PRBEAgent implements PRBEInteractionRequester {
144
146
  private fetchAbortController;
145
147
  private currentInvestigationSource;
146
148
  private currentCRId;
149
+ private readonly historyStore;
147
150
  /** Files flagged during the current tool call — uploaded immediately after the tool returns. */
148
151
  private pendingFlaggedFiles;
149
152
  private get agentID();
@@ -166,7 +169,9 @@ declare class PRBEAgent implements PRBEInteractionRequester {
166
169
  /**
167
170
  * Register a custom tool that the middleware can invoke during investigations.
168
171
  */
169
- registerTool(name: string, description: string, parameters: PRBEToolParameter[], handler: (args: Record<string, unknown>) => Promise<string>): void;
172
+ registerTool(name: string, description: string, parameters: PRBEToolParameter[], handler: (args: Record<string, unknown>) => Promise<string>, options?: {
173
+ interactive?: boolean;
174
+ }): void;
170
175
  /**
171
176
  * User-initiated investigation. Updates `state` events/report directly.
172
177
  */
package/dist/index.js CHANGED
@@ -69,9 +69,9 @@ __export(src_exports, {
69
69
  module.exports = __toCommonJS(src_exports);
70
70
 
71
71
  // src/agent.ts
72
- var fs2 = __toESM(require("fs"));
73
- var path4 = __toESM(require("path"));
74
- var os = __toESM(require("os"));
72
+ var fs3 = __toESM(require("fs"));
73
+ var path5 = __toESM(require("path"));
74
+ var os2 = __toESM(require("os"));
75
75
  var import_crypto5 = require("crypto");
76
76
 
77
77
  // src/models.ts
@@ -250,7 +250,7 @@ var PRBEAgentState = class extends import_events.EventEmitter {
250
250
  this.emit("status" /* STATUS */);
251
251
  }
252
252
  }
253
- completeInvestigation(report, summary) {
253
+ completeInvestigation(report, summary, ticketId) {
254
254
  if (this.events.length > 0) {
255
255
  this.events[this.events.length - 1].isCompleted = true;
256
256
  }
@@ -260,6 +260,9 @@ var PRBEAgentState = class extends import_events.EventEmitter {
260
260
  query: this.currentQuery,
261
261
  report,
262
262
  summary,
263
+ ticketId,
264
+ events: [...this.events],
265
+ resolvedInteractions: [...this.resolvedInteractions],
263
266
  completedAt: /* @__PURE__ */ new Date()
264
267
  });
265
268
  this.report = report;
@@ -335,11 +338,12 @@ var PRBEAgentState = class extends import_events.EventEmitter {
335
338
  }
336
339
  }
337
340
  // ---------- CR state mutations ----------
338
- beginCR(id, query, slug) {
341
+ beginCR(id, query, slug, ticketId) {
339
342
  const cr = {
340
343
  id,
341
344
  query,
342
345
  slug,
346
+ ticketId,
343
347
  events: [],
344
348
  resolvedInteractions: [],
345
349
  isRunning: true,
@@ -465,8 +469,13 @@ var PRBEToolRegistry = class {
465
469
  var PRBEClosureTool = class {
466
470
  declaration;
467
471
  handler;
468
- constructor(name, description, parameters, handler) {
469
- this.declaration = { name, description, parameters };
472
+ constructor(name, description, parameters, handler, options) {
473
+ this.declaration = {
474
+ name,
475
+ description,
476
+ parameters,
477
+ ...options?.interactive ? { interactive: true } : {}
478
+ };
470
479
  this.handler = handler;
471
480
  }
472
481
  async execute(args) {
@@ -1569,20 +1578,196 @@ var BashExecuteTool = class {
1569
1578
  }
1570
1579
  };
1571
1580
 
1572
- // src/agent.ts
1573
- function getPersistencePath() {
1581
+ // src/history.ts
1582
+ var fs2 = __toESM(require("fs"));
1583
+ var path4 = __toESM(require("path"));
1584
+ var os = __toESM(require("os"));
1585
+ var crypto = __toESM(require("crypto"));
1586
+ var HKDF_SALT = Buffer.from("prbe-history-encryption-salt", "utf-8");
1587
+ var HKDF_INFO = Buffer.from("prbe-history-v1", "utf-8");
1588
+ function getAppDataDir() {
1574
1589
  const appData = process.env["APPDATA"] || (process.platform === "darwin" ? path4.join(os.homedir(), "Library", "Application Support") : path4.join(os.homedir(), ".local", "share"));
1575
- const dir = path4.join(appData, "prbe-agent");
1590
+ return path4.join(appData, "prbe-agent");
1591
+ }
1592
+ function getHistoryDir() {
1593
+ const dir = path4.join(getAppDataDir(), "history" /* HISTORY_DIR */);
1576
1594
  if (!fs2.existsSync(dir)) {
1577
1595
  fs2.mkdirSync(dir, { recursive: true });
1578
1596
  }
1579
- return path4.join(dir, "agent-state.json");
1597
+ return dir;
1598
+ }
1599
+ function deriveKey(apiKey) {
1600
+ return Buffer.from(
1601
+ crypto.hkdfSync(
1602
+ "sha256",
1603
+ Buffer.from(apiKey, "utf-8"),
1604
+ HKDF_SALT,
1605
+ HKDF_INFO,
1606
+ 32 /* KEY_LENGTH */
1607
+ )
1608
+ );
1609
+ }
1610
+ function encrypt(plaintext, key) {
1611
+ const iv = crypto.randomBytes(12 /* IV_LENGTH */);
1612
+ const cipher = crypto.createCipheriv(
1613
+ "aes-256-gcm" /* ALGORITHM */,
1614
+ key,
1615
+ iv,
1616
+ { authTagLength: 16 /* AUTH_TAG_LENGTH */ }
1617
+ );
1618
+ const encrypted = Buffer.concat([cipher.update(plaintext, "utf-8"), cipher.final()]);
1619
+ const authTag = cipher.getAuthTag();
1620
+ return Buffer.concat([iv, authTag, encrypted]);
1621
+ }
1622
+ function decrypt(data, key) {
1623
+ const iv = data.subarray(0, 12 /* IV_LENGTH */);
1624
+ const authTag = data.subarray(
1625
+ 12 /* IV_LENGTH */,
1626
+ 12 /* IV_LENGTH */ + 16 /* AUTH_TAG_LENGTH */
1627
+ );
1628
+ const ciphertext = data.subarray(
1629
+ 12 /* IV_LENGTH */ + 16 /* AUTH_TAG_LENGTH */
1630
+ );
1631
+ const decipher = crypto.createDecipheriv(
1632
+ "aes-256-gcm" /* ALGORITHM */,
1633
+ key,
1634
+ iv,
1635
+ { authTagLength: 16 /* AUTH_TAG_LENGTH */ }
1636
+ );
1637
+ decipher.setAuthTag(authTag);
1638
+ return decipher.update(ciphertext) + decipher.final("utf-8");
1639
+ }
1640
+ var HistoryStore = class {
1641
+ key;
1642
+ constructor(apiKey) {
1643
+ this.key = deriveKey(apiKey);
1644
+ }
1645
+ load() {
1646
+ const investigations = [];
1647
+ const crs = [];
1648
+ try {
1649
+ const dir = getHistoryDir();
1650
+ let files;
1651
+ try {
1652
+ files = fs2.readdirSync(dir);
1653
+ } catch {
1654
+ return { investigations, crs };
1655
+ }
1656
+ for (const filename of files) {
1657
+ try {
1658
+ const filePath = path4.join(dir, filename);
1659
+ const raw = fs2.readFileSync(filePath);
1660
+ const json = decrypt(raw, this.key);
1661
+ if (filename.startsWith("inv-") && filename.endsWith(".json")) {
1662
+ const item = JSON.parse(json);
1663
+ investigations.push({
1664
+ ...item,
1665
+ completedAt: new Date(item.completedAt)
1666
+ });
1667
+ } else if (filename.startsWith("cr-") && filename.endsWith(".json")) {
1668
+ const item = JSON.parse(json);
1669
+ crs.push({
1670
+ ...item,
1671
+ startedAt: new Date(item.startedAt),
1672
+ resolvedInteractions: item.resolvedInteractions ?? []
1673
+ });
1674
+ }
1675
+ } catch {
1676
+ console.warn(`[PRBEAgent] Skipping unreadable history file: ${filename}`);
1677
+ }
1678
+ }
1679
+ } catch {
1680
+ }
1681
+ investigations.sort(
1682
+ (a, b) => b.completedAt.getTime() - a.completedAt.getTime()
1683
+ );
1684
+ crs.sort((a, b) => b.startedAt.getTime() - a.startedAt.getTime());
1685
+ return { investigations, crs };
1686
+ }
1687
+ save(investigations, crs) {
1688
+ try {
1689
+ const dir = getHistoryDir();
1690
+ const desiredFiles = /* @__PURE__ */ new Set();
1691
+ for (const inv of investigations) {
1692
+ const filename = `inv-${inv.id}.json`;
1693
+ desiredFiles.add(filename);
1694
+ const data = {
1695
+ id: inv.id,
1696
+ query: inv.query,
1697
+ report: inv.report,
1698
+ summary: inv.summary,
1699
+ ticketId: inv.ticketId,
1700
+ events: inv.events,
1701
+ resolvedInteractions: inv.resolvedInteractions,
1702
+ completedAt: inv.completedAt.toISOString()
1703
+ };
1704
+ fs2.writeFileSync(
1705
+ path4.join(dir, filename),
1706
+ encrypt(JSON.stringify(data), this.key)
1707
+ );
1708
+ }
1709
+ for (const cr of crs) {
1710
+ const filename = `cr-${cr.id}.json`;
1711
+ desiredFiles.add(filename);
1712
+ const data = {
1713
+ id: cr.id,
1714
+ query: cr.query,
1715
+ slug: cr.slug,
1716
+ ticketId: cr.ticketId,
1717
+ events: cr.events,
1718
+ isRunning: cr.isRunning,
1719
+ isCompleted: cr.isCompleted,
1720
+ isFailed: cr.isFailed,
1721
+ report: cr.report,
1722
+ summary: cr.summary,
1723
+ errorMessage: cr.errorMessage,
1724
+ startedAt: cr.startedAt.toISOString(),
1725
+ pendingInteraction: cr.pendingInteraction,
1726
+ resolvedInteractions: cr.resolvedInteractions ?? []
1727
+ };
1728
+ fs2.writeFileSync(
1729
+ path4.join(dir, filename),
1730
+ encrypt(JSON.stringify(data), this.key)
1731
+ );
1732
+ }
1733
+ try {
1734
+ const existing = fs2.readdirSync(dir);
1735
+ for (const filename of existing) {
1736
+ if (!desiredFiles.has(filename)) {
1737
+ fs2.unlinkSync(path4.join(dir, filename));
1738
+ }
1739
+ }
1740
+ } catch {
1741
+ }
1742
+ } catch {
1743
+ console.error("[PRBEAgent] Failed to save investigation history");
1744
+ }
1745
+ }
1746
+ static clear() {
1747
+ try {
1748
+ const dir = path4.join(getAppDataDir(), "history" /* HISTORY_DIR */);
1749
+ if (fs2.existsSync(dir)) {
1750
+ fs2.rmSync(dir, { recursive: true, force: true });
1751
+ }
1752
+ } catch {
1753
+ }
1754
+ }
1755
+ };
1756
+
1757
+ // src/agent.ts
1758
+ function getPersistencePath() {
1759
+ const appData = process.env["APPDATA"] || (process.platform === "darwin" ? path5.join(os2.homedir(), "Library", "Application Support") : path5.join(os2.homedir(), ".local", "share"));
1760
+ const dir = path5.join(appData, "prbe-agent");
1761
+ if (!fs3.existsSync(dir)) {
1762
+ fs3.mkdirSync(dir, { recursive: true });
1763
+ }
1764
+ return path5.join(dir, "agent-state.json");
1580
1765
  }
1581
1766
  function loadPersistedData() {
1582
1767
  try {
1583
1768
  const filePath = getPersistencePath();
1584
- if (fs2.existsSync(filePath)) {
1585
- const raw = fs2.readFileSync(filePath, "utf-8");
1769
+ if (fs3.existsSync(filePath)) {
1770
+ const raw = fs3.readFileSync(filePath, "utf-8");
1586
1771
  return JSON.parse(raw);
1587
1772
  }
1588
1773
  } catch {
@@ -1592,7 +1777,7 @@ function loadPersistedData() {
1592
1777
  function savePersistedData(data) {
1593
1778
  try {
1594
1779
  const filePath = getPersistencePath();
1595
- fs2.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
1780
+ fs3.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
1596
1781
  } catch {
1597
1782
  console.error("[PRBEAgent] Failed to save persisted data");
1598
1783
  }
@@ -1612,6 +1797,7 @@ var PRBEAgent = class _PRBEAgent {
1612
1797
  fetchAbortController = null;
1613
1798
  currentInvestigationSource = "user" /* USER */;
1614
1799
  currentCRId = null;
1800
+ historyStore;
1615
1801
  /** Files flagged during the current tool call — uploaded immediately after the tool returns. */
1616
1802
  pendingFlaggedFiles = [];
1617
1803
  // ---------- Persistence ----------
@@ -1673,6 +1859,10 @@ var PRBEAgent = class _PRBEAgent {
1673
1859
  this.state = new PRBEAgentState();
1674
1860
  this.logCapture = new PRBELogCapture(this.config.maxLogEntries);
1675
1861
  this.persistedData = loadPersistedData();
1862
+ this.historyStore = new HistoryStore(this.config.apiKey);
1863
+ const history = this.historyStore.load();
1864
+ this.state.completedInvestigations = history.investigations;
1865
+ this.state.completedCRs = history.crs;
1676
1866
  const roots = this.config.autoApprovedDirs;
1677
1867
  const requester = this.interactionHandler ? this : void 0;
1678
1868
  const grantedPaths = this.grantedPaths;
@@ -1793,9 +1983,9 @@ var PRBEAgent = class _PRBEAgent {
1793
1983
  /**
1794
1984
  * Register a custom tool that the middleware can invoke during investigations.
1795
1985
  */
1796
- registerTool(name, description, parameters, handler) {
1986
+ registerTool(name, description, parameters, handler, options) {
1797
1987
  this.registry.register(
1798
- new PRBEClosureTool(name, description, parameters, handler)
1988
+ new PRBEClosureTool(name, description, parameters, handler, options)
1799
1989
  );
1800
1990
  }
1801
1991
  /**
@@ -1823,7 +2013,8 @@ var PRBEAgent = class _PRBEAgent {
1823
2013
  this.state.appendEvent("Thinking", status.text);
1824
2014
  break;
1825
2015
  case "completed" /* COMPLETED */:
1826
- this.state.completeInvestigation(status.report, status.userSummary);
2016
+ this.state.completeInvestigation(status.report, status.userSummary, status.ticketId);
2017
+ this.historyStore.save(this.state.completedInvestigations, this.state.completedCRs);
1827
2018
  break;
1828
2019
  case "error" /* ERROR */:
1829
2020
  this.state.failInvestigation(status.message);
@@ -1965,6 +2156,7 @@ var PRBEAgent = class _PRBEAgent {
1965
2156
  this.stopPolling();
1966
2157
  this.persistedData = {};
1967
2158
  savePersistedData(this.persistedData);
2159
+ HistoryStore.clear();
1968
2160
  this.state.resetInvestigation();
1969
2161
  this.state.completedInvestigations = [];
1970
2162
  this.state.activeCRs.clear();
@@ -1979,9 +2171,10 @@ var PRBEAgent = class _PRBEAgent {
1979
2171
  static clearPersistedData() {
1980
2172
  try {
1981
2173
  const filePath = getPersistencePath();
1982
- if (fs2.existsSync(filePath)) {
1983
- fs2.unlinkSync(filePath);
2174
+ if (fs3.existsSync(filePath)) {
2175
+ fs3.unlinkSync(filePath);
1984
2176
  }
2177
+ HistoryStore.clear();
1985
2178
  } catch {
1986
2179
  }
1987
2180
  }
@@ -1990,7 +2183,7 @@ var PRBEAgent = class _PRBEAgent {
1990
2183
  const crID = cr.id;
1991
2184
  this.currentInvestigationSource = "context_request" /* CONTEXT_REQUEST */;
1992
2185
  this.currentCRId = crID;
1993
- this.state.beginCR(crID, cr.query, cr.slug ?? void 0);
2186
+ this.state.beginCR(crID, cr.query, cr.slug ?? void 0, ticketId);
1994
2187
  const emitter = (status) => {
1995
2188
  switch (status.type) {
1996
2189
  case "started" /* STARTED */:
@@ -2009,9 +2202,11 @@ var PRBEAgent = class _PRBEAgent {
2009
2202
  break;
2010
2203
  case "completed" /* COMPLETED */:
2011
2204
  this.state.completeCR(crID, status.report, status.userSummary);
2205
+ this.historyStore.save(this.state.completedInvestigations, this.state.completedCRs);
2012
2206
  break;
2013
2207
  case "error" /* ERROR */:
2014
2208
  this.state.failCR(crID, status.message);
2209
+ this.historyStore.save(this.state.completedInvestigations, this.state.completedCRs);
2015
2210
  break;
2016
2211
  }
2017
2212
  };
@@ -2150,7 +2345,7 @@ var PRBEAgent = class _PRBEAgent {
2150
2345
  const uploadPrefix = this.extractUploadPrefix(uploadBaseUrl);
2151
2346
  const uploadedRefs = [];
2152
2347
  for (const file of this.pendingFlaggedFiles) {
2153
- const filename = path4.basename(file.originalPath);
2348
+ const filename = path5.basename(file.originalPath);
2154
2349
  const safeName = encodeURIComponent(filename);
2155
2350
  const storagePath = `${uploadPrefix}/${safeName}`;
2156
2351
  uploadedRefs.push({
@@ -2206,7 +2401,8 @@ var PRBEAgent = class _PRBEAgent {
2206
2401
  emit({
2207
2402
  type: "completed" /* COMPLETED */,
2208
2403
  report,
2209
- userSummary
2404
+ userSummary,
2405
+ ticketId: ticketId2
2210
2406
  });
2211
2407
  ws.close(1e3, "Complete");
2212
2408
  finish({ report, userSummary, ticketId: ticketId2 });
@@ -2389,6 +2585,7 @@ function serializeCR(cr) {
2389
2585
  id: cr.id,
2390
2586
  query: cr.query,
2391
2587
  slug: cr.slug,
2588
+ ticketId: cr.ticketId,
2392
2589
  events: cr.events,
2393
2590
  isRunning: cr.isRunning,
2394
2591
  isCompleted: cr.isCompleted,
@@ -2416,6 +2613,9 @@ function serializePRBEState(state) {
2416
2613
  query: inv.query,
2417
2614
  report: inv.report,
2418
2615
  summary: inv.summary,
2616
+ ticketId: inv.ticketId,
2617
+ events: inv.events,
2618
+ resolvedInteractions: inv.resolvedInteractions,
2419
2619
  completedAt: inv.completedAt.toISOString()
2420
2620
  })),
2421
2621
  activeCRs: Array.from(state.activeCRs.values()).map(serializeCR),