asmgr 0.1.0 → 0.2.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 (3) hide show
  1. package/README.md +174 -146
  2. package/dist/asmgr.mjs +1277 -119
  3. package/package.json +3 -2
package/dist/asmgr.mjs CHANGED
@@ -4340,21 +4340,21 @@ var require_react_development = __commonJS({
4340
4340
  );
4341
4341
  actScopeDepth = prevActScopeDepth;
4342
4342
  }
4343
- function recursivelyFlushAsyncActWork(returnValue, resolve9, reject) {
4343
+ function recursivelyFlushAsyncActWork(returnValue, resolve10, reject) {
4344
4344
  var queue = ReactSharedInternals.actQueue;
4345
4345
  if (null !== queue)
4346
4346
  if (0 !== queue.length)
4347
4347
  try {
4348
4348
  flushActQueue(queue);
4349
4349
  enqueueTask(function() {
4350
- return recursivelyFlushAsyncActWork(returnValue, resolve9, reject);
4350
+ return recursivelyFlushAsyncActWork(returnValue, resolve10, reject);
4351
4351
  });
4352
4352
  return;
4353
4353
  } catch (error) {
4354
4354
  ReactSharedInternals.thrownErrors.push(error);
4355
4355
  }
4356
4356
  else ReactSharedInternals.actQueue = null;
4357
- 0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) : resolve9(returnValue);
4357
+ 0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) : resolve10(returnValue);
4358
4358
  }
4359
4359
  function flushActQueue(queue) {
4360
4360
  if (!isFlushing) {
@@ -4541,7 +4541,7 @@ var require_react_development = __commonJS({
4541
4541
  ));
4542
4542
  });
4543
4543
  return {
4544
- then: function(resolve9, reject) {
4544
+ then: function(resolve10, reject) {
4545
4545
  didAwaitActCall = true;
4546
4546
  thenable.then(
4547
4547
  function(returnValue) {
@@ -4551,7 +4551,7 @@ var require_react_development = __commonJS({
4551
4551
  flushActQueue(queue), enqueueTask(function() {
4552
4552
  return recursivelyFlushAsyncActWork(
4553
4553
  returnValue,
4554
- resolve9,
4554
+ resolve10,
4555
4555
  reject
4556
4556
  );
4557
4557
  });
@@ -4565,7 +4565,7 @@ var require_react_development = __commonJS({
4565
4565
  ReactSharedInternals.thrownErrors.length = 0;
4566
4566
  reject(_thrownError);
4567
4567
  }
4568
- } else resolve9(returnValue);
4568
+ } else resolve10(returnValue);
4569
4569
  },
4570
4570
  function(error) {
4571
4571
  popActScope(prevActQueue, prevActScopeDepth);
@@ -4587,15 +4587,15 @@ var require_react_development = __commonJS({
4587
4587
  if (0 < ReactSharedInternals.thrownErrors.length)
4588
4588
  throw callback = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, callback;
4589
4589
  return {
4590
- then: function(resolve9, reject) {
4590
+ then: function(resolve10, reject) {
4591
4591
  didAwaitActCall = true;
4592
4592
  0 === prevActScopeDepth ? (ReactSharedInternals.actQueue = queue, enqueueTask(function() {
4593
4593
  return recursivelyFlushAsyncActWork(
4594
4594
  returnValue$jscomp$0,
4595
- resolve9,
4595
+ resolve10,
4596
4596
  reject
4597
4597
  );
4598
- })) : resolve9(returnValue$jscomp$0);
4598
+ })) : resolve10(returnValue$jscomp$0);
4599
4599
  }
4600
4600
  };
4601
4601
  };
@@ -6147,16 +6147,16 @@ var require_react_dom_server_legacy_node_production = __commonJS({
6147
6147
  }
6148
6148
  }
6149
6149
  if (null != selectedValue) {
6150
- var stringValue = null !== value ? "" + value : flattenOptionChildren(children$jscomp$1);
6150
+ var stringValue2 = null !== value ? "" + value : flattenOptionChildren(children$jscomp$1);
6151
6151
  if (isArrayImpl(selectedValue))
6152
6152
  for (var i3 = 0; i3 < selectedValue.length; i3++) {
6153
- if ("" + selectedValue[i3] === stringValue) {
6153
+ if ("" + selectedValue[i3] === stringValue2) {
6154
6154
  target$jscomp$0.push(' selected=""');
6155
6155
  break;
6156
6156
  }
6157
6157
  }
6158
6158
  else
6159
- "" + selectedValue === stringValue && target$jscomp$0.push(' selected=""');
6159
+ "" + selectedValue === stringValue2 && target$jscomp$0.push(' selected=""');
6160
6160
  } else selected && target$jscomp$0.push(' selected=""');
6161
6161
  target$jscomp$0.push(">");
6162
6162
  pushInnerHTML(target$jscomp$0, innerHTML$jscomp$1, children$jscomp$1);
@@ -11341,16 +11341,16 @@ var require_react_dom_server_node_production = __commonJS({
11341
11341
  }
11342
11342
  }
11343
11343
  if (null != selectedValue) {
11344
- var stringValue = null !== value ? "" + value : flattenOptionChildren(children$jscomp$1);
11344
+ var stringValue2 = null !== value ? "" + value : flattenOptionChildren(children$jscomp$1);
11345
11345
  if (isArrayImpl(selectedValue))
11346
11346
  for (var i3 = 0; i3 < selectedValue.length; i3++) {
11347
- if ("" + selectedValue[i3] === stringValue) {
11347
+ if ("" + selectedValue[i3] === stringValue2) {
11348
11348
  target$jscomp$0.push(selectedMarkerAttribute);
11349
11349
  break;
11350
11350
  }
11351
11351
  }
11352
11352
  else
11353
- "" + selectedValue === stringValue && target$jscomp$0.push(selectedMarkerAttribute);
11353
+ "" + selectedValue === stringValue2 && target$jscomp$0.push(selectedMarkerAttribute);
11354
11354
  } else selected && target$jscomp$0.push(selectedMarkerAttribute);
11355
11355
  target$jscomp$0.push(endOfStartTag);
11356
11356
  pushInnerHTML(target$jscomp$0, innerHTML$jscomp$1, children$jscomp$1);
@@ -15684,7 +15684,7 @@ var require_react_dom_server_node_production = __commonJS({
15684
15684
  };
15685
15685
  }
15686
15686
  exports.prerender = function(children, options) {
15687
- return new Promise(function(resolve9, reject) {
15687
+ return new Promise(function(resolve10, reject) {
15688
15688
  var onHeaders = options ? options.onHeaders : void 0, onHeadersImpl;
15689
15689
  onHeaders && (onHeadersImpl = function(headersDescriptor) {
15690
15690
  onHeaders(new Headers(headersDescriptor));
@@ -15727,7 +15727,7 @@ var require_react_dom_server_node_production = __commonJS({
15727
15727
  { highWaterMark: 0 }
15728
15728
  );
15729
15729
  stream2 = { postponed: getPostponedState(request), prelude: stream2 };
15730
- resolve9(stream2);
15730
+ resolve10(stream2);
15731
15731
  },
15732
15732
  void 0,
15733
15733
  void 0,
@@ -15749,7 +15749,7 @@ var require_react_dom_server_node_production = __commonJS({
15749
15749
  });
15750
15750
  };
15751
15751
  exports.prerenderToNodeStream = function(children, options) {
15752
- return new Promise(function(resolve9, reject) {
15752
+ return new Promise(function(resolve10, reject) {
15753
15753
  var resumableState = createResumableState(
15754
15754
  options ? options.identifierPrefix : void 0,
15755
15755
  options ? options.unstable_externalRuntimeSrc : void 0,
@@ -15780,7 +15780,7 @@ var require_react_dom_server_node_production = __commonJS({
15780
15780
  postponed: getPostponedState(request),
15781
15781
  prelude: readable
15782
15782
  };
15783
- resolve9(readable);
15783
+ resolve10(readable);
15784
15784
  },
15785
15785
  void 0,
15786
15786
  void 0,
@@ -15836,7 +15836,7 @@ var require_react_dom_server_node_production = __commonJS({
15836
15836
  };
15837
15837
  };
15838
15838
  exports.renderToReadableStream = function(children, options) {
15839
- return new Promise(function(resolve9, reject) {
15839
+ return new Promise(function(resolve10, reject) {
15840
15840
  var onFatalError, onAllReady, allReady = new Promise(function(res, rej) {
15841
15841
  onAllReady = res;
15842
15842
  onFatalError = rej;
@@ -15885,7 +15885,7 @@ var require_react_dom_server_node_production = __commonJS({
15885
15885
  { highWaterMark: 0 }
15886
15886
  );
15887
15887
  stream2.allReady = allReady;
15888
- resolve9(stream2);
15888
+ resolve10(stream2);
15889
15889
  },
15890
15890
  function(error) {
15891
15891
  allReady.catch(function() {
@@ -15911,7 +15911,7 @@ var require_react_dom_server_node_production = __commonJS({
15911
15911
  });
15912
15912
  };
15913
15913
  exports.resume = function(children, postponedState, options) {
15914
- return new Promise(function(resolve9, reject) {
15914
+ return new Promise(function(resolve10, reject) {
15915
15915
  var onFatalError, onAllReady, allReady = new Promise(function(res, rej) {
15916
15916
  onAllReady = res;
15917
15917
  onFatalError = rej;
@@ -15948,7 +15948,7 @@ var require_react_dom_server_node_production = __commonJS({
15948
15948
  { highWaterMark: 0 }
15949
15949
  );
15950
15950
  stream2.allReady = allReady;
15951
- resolve9(stream2);
15951
+ resolve10(stream2);
15952
15952
  },
15953
15953
  function(error) {
15954
15954
  allReady.catch(function() {
@@ -15973,7 +15973,7 @@ var require_react_dom_server_node_production = __commonJS({
15973
15973
  });
15974
15974
  };
15975
15975
  exports.resumeAndPrerender = function(children, postponedState, options) {
15976
- return new Promise(function(resolve9, reject) {
15976
+ return new Promise(function(resolve10, reject) {
15977
15977
  var request = resumeAndPrerenderRequest(
15978
15978
  children,
15979
15979
  postponedState,
@@ -16004,7 +16004,7 @@ var require_react_dom_server_node_production = __commonJS({
16004
16004
  { highWaterMark: 0 }
16005
16005
  );
16006
16006
  stream2 = { postponed: getPostponedState(request), prelude: stream2 };
16007
- resolve9(stream2);
16007
+ resolve10(stream2);
16008
16008
  },
16009
16009
  void 0,
16010
16010
  void 0,
@@ -16026,7 +16026,7 @@ var require_react_dom_server_node_production = __commonJS({
16026
16026
  });
16027
16027
  };
16028
16028
  exports.resumeAndPrerenderToNodeStream = function(children, postponedState, options) {
16029
- return new Promise(function(resolve9, reject) {
16029
+ return new Promise(function(resolve10, reject) {
16030
16030
  var request = resumeAndPrerenderRequest(
16031
16031
  children,
16032
16032
  postponedState,
@@ -16046,7 +16046,7 @@ var require_react_dom_server_node_production = __commonJS({
16046
16046
  }
16047
16047
  }), writable = createFakeWritableFromReadable(readable);
16048
16048
  readable = { postponed: getPostponedState(request), prelude: readable };
16049
- resolve9(readable);
16049
+ resolve10(readable);
16050
16050
  },
16051
16051
  void 0,
16052
16052
  void 0,
@@ -17415,20 +17415,20 @@ var require_react_dom_server_legacy_node_development = __commonJS({
17415
17415
  if (null != selectedValue) {
17416
17416
  if (null !== value) {
17417
17417
  checkAttributeStringCoercion(value, "value");
17418
- var stringValue = "" + value;
17418
+ var stringValue2 = "" + value;
17419
17419
  } else
17420
17420
  null === innerHTML$jscomp$1 || didWarnInvalidOptionInnerHTML || (didWarnInvalidOptionInnerHTML = true, console.error(
17421
17421
  "Pass a `value` prop if you set dangerouslyInnerHTML so React knows which value should be selected."
17422
- )), stringValue = flattenOptionChildren(children$jscomp$1);
17422
+ )), stringValue2 = flattenOptionChildren(children$jscomp$1);
17423
17423
  if (isArrayImpl(selectedValue))
17424
17424
  for (var i3 = 0; i3 < selectedValue.length; i3++) {
17425
- if (checkAttributeStringCoercion(selectedValue[i3], "value"), "" + selectedValue[i3] === stringValue) {
17425
+ if (checkAttributeStringCoercion(selectedValue[i3], "value"), "" + selectedValue[i3] === stringValue2) {
17426
17426
  target$jscomp$0.push(' selected=""');
17427
17427
  break;
17428
17428
  }
17429
17429
  }
17430
17430
  else
17431
- checkAttributeStringCoercion(selectedValue, "select.value"), "" + selectedValue === stringValue && target$jscomp$0.push(' selected=""');
17431
+ checkAttributeStringCoercion(selectedValue, "select.value"), "" + selectedValue === stringValue2 && target$jscomp$0.push(' selected=""');
17432
17432
  } else selected && target$jscomp$0.push(' selected=""');
17433
17433
  target$jscomp$0.push(endOfStartTag);
17434
17434
  pushInnerHTML(target$jscomp$0, innerHTML$jscomp$1, children$jscomp$1);
@@ -24694,20 +24694,20 @@ var require_react_dom_server_node_development = __commonJS({
24694
24694
  if (null != selectedValue) {
24695
24695
  if (null !== value) {
24696
24696
  checkAttributeStringCoercion(value, "value");
24697
- var stringValue = "" + value;
24697
+ var stringValue2 = "" + value;
24698
24698
  } else
24699
24699
  null === innerHTML$jscomp$1 || didWarnInvalidOptionInnerHTML || (didWarnInvalidOptionInnerHTML = true, console.error(
24700
24700
  "Pass a `value` prop if you set dangerouslyInnerHTML so React knows which value should be selected."
24701
- )), stringValue = flattenOptionChildren(children$jscomp$1);
24701
+ )), stringValue2 = flattenOptionChildren(children$jscomp$1);
24702
24702
  if (isArrayImpl(selectedValue))
24703
24703
  for (var i3 = 0; i3 < selectedValue.length; i3++) {
24704
- if (checkAttributeStringCoercion(selectedValue[i3], "value"), "" + selectedValue[i3] === stringValue) {
24704
+ if (checkAttributeStringCoercion(selectedValue[i3], "value"), "" + selectedValue[i3] === stringValue2) {
24705
24705
  target$jscomp$0.push(selectedMarkerAttribute);
24706
24706
  break;
24707
24707
  }
24708
24708
  }
24709
24709
  else
24710
- checkAttributeStringCoercion(selectedValue, "select.value"), "" + selectedValue === stringValue && target$jscomp$0.push(selectedMarkerAttribute);
24710
+ checkAttributeStringCoercion(selectedValue, "select.value"), "" + selectedValue === stringValue2 && target$jscomp$0.push(selectedMarkerAttribute);
24711
24711
  } else selected && target$jscomp$0.push(selectedMarkerAttribute);
24712
24712
  target$jscomp$0.push(endOfStartTag);
24713
24713
  pushInnerHTML(target$jscomp$0, innerHTML$jscomp$1, children$jscomp$1);
@@ -30673,7 +30673,7 @@ var require_react_dom_server_node_development = __commonJS({
30673
30673
  ensureCorrectIsomorphicReactVersion();
30674
30674
  ensureCorrectIsomorphicReactVersion();
30675
30675
  exports.prerender = function(children, options) {
30676
- return new Promise(function(resolve9, reject) {
30676
+ return new Promise(function(resolve10, reject) {
30677
30677
  var onHeaders = options ? options.onHeaders : void 0, onHeadersImpl;
30678
30678
  onHeaders && (onHeadersImpl = function(headersDescriptor) {
30679
30679
  onHeaders(new Headers(headersDescriptor));
@@ -30721,7 +30721,7 @@ var require_react_dom_server_node_development = __commonJS({
30721
30721
  postponed: getPostponedState(request),
30722
30722
  prelude: stream2
30723
30723
  };
30724
- resolve9(stream2);
30724
+ resolve10(stream2);
30725
30725
  },
30726
30726
  void 0,
30727
30727
  void 0,
@@ -30743,7 +30743,7 @@ var require_react_dom_server_node_development = __commonJS({
30743
30743
  });
30744
30744
  };
30745
30745
  exports.prerenderToNodeStream = function(children, options) {
30746
- return new Promise(function(resolve9, reject) {
30746
+ return new Promise(function(resolve10, reject) {
30747
30747
  var resumableState = createResumableState(
30748
30748
  options ? options.identifierPrefix : void 0,
30749
30749
  options ? options.unstable_externalRuntimeSrc : void 0,
@@ -30774,7 +30774,7 @@ var require_react_dom_server_node_development = __commonJS({
30774
30774
  postponed: getPostponedState(request),
30775
30775
  prelude: readable
30776
30776
  };
30777
- resolve9(readable);
30777
+ resolve10(readable);
30778
30778
  },
30779
30779
  void 0,
30780
30780
  void 0,
@@ -30830,7 +30830,7 @@ var require_react_dom_server_node_development = __commonJS({
30830
30830
  };
30831
30831
  };
30832
30832
  exports.renderToReadableStream = function(children, options) {
30833
- return new Promise(function(resolve9, reject) {
30833
+ return new Promise(function(resolve10, reject) {
30834
30834
  var onFatalError, onAllReady, allReady = new Promise(function(res, rej) {
30835
30835
  onAllReady = res;
30836
30836
  onFatalError = rej;
@@ -30879,7 +30879,7 @@ var require_react_dom_server_node_development = __commonJS({
30879
30879
  { highWaterMark: 0 }
30880
30880
  );
30881
30881
  stream2.allReady = allReady;
30882
- resolve9(stream2);
30882
+ resolve10(stream2);
30883
30883
  },
30884
30884
  function(error) {
30885
30885
  allReady.catch(function() {
@@ -30905,7 +30905,7 @@ var require_react_dom_server_node_development = __commonJS({
30905
30905
  });
30906
30906
  };
30907
30907
  exports.resume = function(children, postponedState, options) {
30908
- return new Promise(function(resolve9, reject) {
30908
+ return new Promise(function(resolve10, reject) {
30909
30909
  var onFatalError, onAllReady, allReady = new Promise(function(res, rej) {
30910
30910
  onAllReady = res;
30911
30911
  onFatalError = rej;
@@ -30942,7 +30942,7 @@ var require_react_dom_server_node_development = __commonJS({
30942
30942
  { highWaterMark: 0 }
30943
30943
  );
30944
30944
  stream2.allReady = allReady;
30945
- resolve9(stream2);
30945
+ resolve10(stream2);
30946
30946
  },
30947
30947
  function(error) {
30948
30948
  allReady.catch(function() {
@@ -30967,7 +30967,7 @@ var require_react_dom_server_node_development = __commonJS({
30967
30967
  });
30968
30968
  };
30969
30969
  exports.resumeAndPrerender = function(children, postponedState, options) {
30970
- return new Promise(function(resolve9, reject) {
30970
+ return new Promise(function(resolve10, reject) {
30971
30971
  var request = resumeAndPrerenderRequest(
30972
30972
  children,
30973
30973
  postponedState,
@@ -31000,7 +31000,7 @@ var require_react_dom_server_node_development = __commonJS({
31000
31000
  { highWaterMark: 0 }
31001
31001
  );
31002
31002
  stream2 = { postponed: getPostponedState(request), prelude: stream2 };
31003
- resolve9(stream2);
31003
+ resolve10(stream2);
31004
31004
  },
31005
31005
  void 0,
31006
31006
  void 0,
@@ -31022,7 +31022,7 @@ var require_react_dom_server_node_development = __commonJS({
31022
31022
  });
31023
31023
  };
31024
31024
  exports.resumeAndPrerenderToNodeStream = function(children, postponedState, options) {
31025
- return new Promise(function(resolve9, reject) {
31025
+ return new Promise(function(resolve10, reject) {
31026
31026
  var request = resumeAndPrerenderRequest(
31027
31027
  children,
31028
31028
  postponedState,
@@ -31045,7 +31045,7 @@ var require_react_dom_server_node_development = __commonJS({
31045
31045
  postponed: getPostponedState(request),
31046
31046
  prelude: readable
31047
31047
  };
31048
- resolve9(readable);
31048
+ resolve10(readable);
31049
31049
  },
31050
31050
  void 0,
31051
31051
  void 0,
@@ -33517,12 +33517,12 @@ function mergeObjects(target, ...sources) {
33517
33517
  });
33518
33518
  return target;
33519
33519
  }
33520
- function basename6(path3) {
33520
+ function basename7(path3) {
33521
33521
  const idx = ~path3.lastIndexOf("/") || ~path3.lastIndexOf("\\");
33522
33522
  if (idx === 0) {
33523
33523
  return path3;
33524
33524
  } else if (~idx === path3.length - 1) {
33525
- return basename6(path3.substring(0, path3.length - 1));
33525
+ return basename7(path3.substring(0, path3.length - 1));
33526
33526
  } else {
33527
33527
  return path3.substr(~idx + 1);
33528
33528
  }
@@ -34982,7 +34982,7 @@ var init_dist2 = __esm({
34982
34982
  this._contentNameIsCapturing = RegexSource.hasCaptures(this._contentName);
34983
34983
  }
34984
34984
  get debugName() {
34985
- const location2 = this.$location ? `${basename6(this.$location.filename)}:${this.$location.line}` : "unknown";
34985
+ const location2 = this.$location ? `${basename7(this.$location.filename)}:${this.$location.line}` : "unknown";
34986
34986
  return `${this.constructor.name}#${this.id} @ ${location2}`;
34987
34987
  }
34988
34988
  getName(lineText, captureIndices) {
@@ -43220,11 +43220,11 @@ var {
43220
43220
  var BIN_NAME = "asmgr";
43221
43221
 
43222
43222
  // src/cli/version.ts
43223
- var VERSION = true ? "0.1.0" : devVersion();
43223
+ var VERSION = true ? "0.2.0" : devVersion();
43224
43224
 
43225
43225
  // src/core/index.ts
43226
43226
  import { stat as stat2 } from "node:fs/promises";
43227
- import { basename as basename5 } from "node:path";
43227
+ import { basename as basename6 } from "node:path";
43228
43228
 
43229
43229
  // src/core/adapters/claude.ts
43230
43230
  import { basename as basename2 } from "node:path";
@@ -43341,6 +43341,9 @@ async function readJsonl(path3) {
43341
43341
  }
43342
43342
  return rows;
43343
43343
  }
43344
+ async function readJson(path3) {
43345
+ return JSON.parse(await readFile(path3, "utf8"));
43346
+ }
43344
43347
  function fileStem(path3) {
43345
43348
  return basename(path3).replace(/\.jsonl$/, "");
43346
43349
  }
@@ -44080,15 +44083,1035 @@ function isIntentionallyIgnoredEvent(type) {
44080
44083
  return INTENTIONALLY_IGNORED_EVENT_TYPES.has(type) || type.startsWith("hook.") || type.startsWith("assistant.turn_");
44081
44084
  }
44082
44085
 
44086
+ // src/core/adapters/chatgpt.ts
44087
+ import { homedir as homedir2 } from "node:os";
44088
+ import { basename as basename5, join as join2 } from "node:path";
44089
+
44090
+ // node_modules/.pnpm/turbo-stream@2.4.1/node_modules/turbo-stream/dist/turbo-stream.mjs
44091
+ var HOLE = -1;
44092
+ var NAN = -2;
44093
+ var NEGATIVE_INFINITY = -3;
44094
+ var NEGATIVE_ZERO = -4;
44095
+ var NULL = -5;
44096
+ var POSITIVE_INFINITY = -6;
44097
+ var UNDEFINED = -7;
44098
+ var TYPE_BIGINT = "B";
44099
+ var TYPE_DATE = "D";
44100
+ var TYPE_ERROR = "E";
44101
+ var TYPE_MAP = "M";
44102
+ var TYPE_NULL_OBJECT = "N";
44103
+ var TYPE_PROMISE = "P";
44104
+ var TYPE_REGEXP = "R";
44105
+ var TYPE_SET = "S";
44106
+ var TYPE_SYMBOL = "Y";
44107
+ var TYPE_URL = "U";
44108
+ var TYPE_PREVIOUS_RESOLVED = "Z";
44109
+ var Deferred = class {
44110
+ promise;
44111
+ resolve;
44112
+ reject;
44113
+ constructor() {
44114
+ this.promise = new Promise((resolve10, reject) => {
44115
+ this.resolve = resolve10;
44116
+ this.reject = reject;
44117
+ });
44118
+ }
44119
+ };
44120
+ function createLineSplittingTransform() {
44121
+ const decoder = new TextDecoder();
44122
+ let leftover = "";
44123
+ return new TransformStream({
44124
+ transform(chunk, controller) {
44125
+ const str2 = decoder.decode(chunk, { stream: true });
44126
+ const parts = (leftover + str2).split("\n");
44127
+ leftover = parts.pop() || "";
44128
+ for (const part of parts) {
44129
+ controller.enqueue(part);
44130
+ }
44131
+ },
44132
+ flush(controller) {
44133
+ if (leftover) {
44134
+ controller.enqueue(leftover);
44135
+ }
44136
+ }
44137
+ });
44138
+ }
44139
+ var objectProtoNames = Object.getOwnPropertyNames(Object.prototype).sort().join("\0");
44140
+ var globalObj = typeof window !== "undefined" ? window : typeof globalThis !== "undefined" ? globalThis : void 0;
44141
+ function unflatten(parsed) {
44142
+ const { hydrated, values } = this;
44143
+ if (typeof parsed === "number")
44144
+ return hydrate.call(this, parsed);
44145
+ if (!Array.isArray(parsed) || !parsed.length)
44146
+ throw new SyntaxError();
44147
+ const startIndex = values.length;
44148
+ for (const value of parsed) {
44149
+ values.push(value);
44150
+ }
44151
+ hydrated.length = values.length;
44152
+ return hydrate.call(this, startIndex);
44153
+ }
44154
+ function hydrate(index2) {
44155
+ const { hydrated, values, deferred, plugins } = this;
44156
+ let result;
44157
+ const stack = [
44158
+ [
44159
+ index2,
44160
+ (v2) => {
44161
+ result = v2;
44162
+ }
44163
+ ]
44164
+ ];
44165
+ let postRun = [];
44166
+ while (stack.length > 0) {
44167
+ const [index22, set] = stack.pop();
44168
+ switch (index22) {
44169
+ case UNDEFINED:
44170
+ set(void 0);
44171
+ continue;
44172
+ case NULL:
44173
+ set(null);
44174
+ continue;
44175
+ case NAN:
44176
+ set(NaN);
44177
+ continue;
44178
+ case POSITIVE_INFINITY:
44179
+ set(Infinity);
44180
+ continue;
44181
+ case NEGATIVE_INFINITY:
44182
+ set(-Infinity);
44183
+ continue;
44184
+ case NEGATIVE_ZERO:
44185
+ set(-0);
44186
+ continue;
44187
+ }
44188
+ if (hydrated[index22]) {
44189
+ set(hydrated[index22]);
44190
+ continue;
44191
+ }
44192
+ const value = values[index22];
44193
+ if (!value || typeof value !== "object") {
44194
+ hydrated[index22] = value;
44195
+ set(value);
44196
+ continue;
44197
+ }
44198
+ if (Array.isArray(value)) {
44199
+ if (typeof value[0] === "string") {
44200
+ const [type, b3, c] = value;
44201
+ switch (type) {
44202
+ case TYPE_DATE:
44203
+ set(hydrated[index22] = new Date(b3));
44204
+ continue;
44205
+ case TYPE_URL:
44206
+ set(hydrated[index22] = new URL(b3));
44207
+ continue;
44208
+ case TYPE_BIGINT:
44209
+ set(hydrated[index22] = BigInt(b3));
44210
+ continue;
44211
+ case TYPE_REGEXP:
44212
+ set(hydrated[index22] = new RegExp(b3, c));
44213
+ continue;
44214
+ case TYPE_SYMBOL:
44215
+ set(hydrated[index22] = Symbol.for(b3));
44216
+ continue;
44217
+ case TYPE_SET:
44218
+ const newSet = /* @__PURE__ */ new Set();
44219
+ hydrated[index22] = newSet;
44220
+ for (let i3 = 1; i3 < value.length; i3++)
44221
+ stack.push([
44222
+ value[i3],
44223
+ (v2) => {
44224
+ newSet.add(v2);
44225
+ }
44226
+ ]);
44227
+ set(newSet);
44228
+ continue;
44229
+ case TYPE_MAP:
44230
+ const map3 = /* @__PURE__ */ new Map();
44231
+ hydrated[index22] = map3;
44232
+ for (let i3 = 1; i3 < value.length; i3 += 2) {
44233
+ const r4 = [];
44234
+ stack.push([
44235
+ value[i3 + 1],
44236
+ (v2) => {
44237
+ r4[1] = v2;
44238
+ }
44239
+ ]);
44240
+ stack.push([
44241
+ value[i3],
44242
+ (k3) => {
44243
+ r4[0] = k3;
44244
+ }
44245
+ ]);
44246
+ postRun.push(() => {
44247
+ map3.set(r4[0], r4[1]);
44248
+ });
44249
+ }
44250
+ set(map3);
44251
+ continue;
44252
+ case TYPE_NULL_OBJECT:
44253
+ const obj = /* @__PURE__ */ Object.create(null);
44254
+ hydrated[index22] = obj;
44255
+ for (const key2 of Object.keys(b3).reverse()) {
44256
+ const r4 = [];
44257
+ stack.push([
44258
+ b3[key2],
44259
+ (v2) => {
44260
+ r4[1] = v2;
44261
+ }
44262
+ ]);
44263
+ stack.push([
44264
+ Number(key2.slice(1)),
44265
+ (k3) => {
44266
+ r4[0] = k3;
44267
+ }
44268
+ ]);
44269
+ postRun.push(() => {
44270
+ obj[r4[0]] = r4[1];
44271
+ });
44272
+ }
44273
+ set(obj);
44274
+ continue;
44275
+ case TYPE_PROMISE:
44276
+ if (hydrated[b3]) {
44277
+ set(hydrated[index22] = hydrated[b3]);
44278
+ } else {
44279
+ const d2 = new Deferred();
44280
+ deferred[b3] = d2;
44281
+ set(hydrated[index22] = d2.promise);
44282
+ }
44283
+ continue;
44284
+ case TYPE_ERROR:
44285
+ const [, message, errorType] = value;
44286
+ let error = errorType && globalObj && globalObj[errorType] ? new globalObj[errorType](message) : new Error(message);
44287
+ hydrated[index22] = error;
44288
+ set(error);
44289
+ continue;
44290
+ case TYPE_PREVIOUS_RESOLVED:
44291
+ set(hydrated[index22] = hydrated[b3]);
44292
+ continue;
44293
+ default:
44294
+ if (Array.isArray(plugins)) {
44295
+ const r4 = [];
44296
+ const vals = value.slice(1);
44297
+ for (let i3 = 0; i3 < vals.length; i3++) {
44298
+ const v2 = vals[i3];
44299
+ stack.push([
44300
+ v2,
44301
+ (v22) => {
44302
+ r4[i3] = v22;
44303
+ }
44304
+ ]);
44305
+ }
44306
+ postRun.push(() => {
44307
+ for (const plugin of plugins) {
44308
+ const result2 = plugin(value[0], ...r4);
44309
+ if (result2) {
44310
+ set(hydrated[index22] = result2.value);
44311
+ return;
44312
+ }
44313
+ }
44314
+ throw new SyntaxError();
44315
+ });
44316
+ continue;
44317
+ }
44318
+ throw new SyntaxError();
44319
+ }
44320
+ } else {
44321
+ const array = [];
44322
+ hydrated[index22] = array;
44323
+ for (let i3 = 0; i3 < value.length; i3++) {
44324
+ const n = value[i3];
44325
+ if (n !== HOLE) {
44326
+ stack.push([
44327
+ n,
44328
+ (v2) => {
44329
+ array[i3] = v2;
44330
+ }
44331
+ ]);
44332
+ }
44333
+ }
44334
+ set(array);
44335
+ continue;
44336
+ }
44337
+ } else {
44338
+ const object = {};
44339
+ hydrated[index22] = object;
44340
+ for (const key2 of Object.keys(value).reverse()) {
44341
+ const r4 = [];
44342
+ stack.push([
44343
+ value[key2],
44344
+ (v2) => {
44345
+ r4[1] = v2;
44346
+ }
44347
+ ]);
44348
+ stack.push([
44349
+ Number(key2.slice(1)),
44350
+ (k3) => {
44351
+ r4[0] = k3;
44352
+ }
44353
+ ]);
44354
+ postRun.push(() => {
44355
+ object[r4[0]] = r4[1];
44356
+ });
44357
+ }
44358
+ set(object);
44359
+ continue;
44360
+ }
44361
+ }
44362
+ while (postRun.length > 0) {
44363
+ postRun.pop()();
44364
+ }
44365
+ return result;
44366
+ }
44367
+ async function decode(readable, options) {
44368
+ const { plugins } = options ?? {};
44369
+ const done = new Deferred();
44370
+ const reader = readable.pipeThrough(createLineSplittingTransform()).getReader();
44371
+ const decoder = {
44372
+ values: [],
44373
+ hydrated: [],
44374
+ deferred: {},
44375
+ plugins
44376
+ };
44377
+ const decoded = await decodeInitial.call(decoder, reader);
44378
+ let donePromise = done.promise;
44379
+ if (decoded.done) {
44380
+ done.resolve();
44381
+ } else {
44382
+ donePromise = decodeDeferred.call(decoder, reader).then(done.resolve).catch((reason) => {
44383
+ for (const deferred of Object.values(decoder.deferred)) {
44384
+ deferred.reject(reason);
44385
+ }
44386
+ done.reject(reason);
44387
+ });
44388
+ }
44389
+ return {
44390
+ done: donePromise.then(() => reader.closed),
44391
+ value: decoded.value
44392
+ };
44393
+ }
44394
+ async function decodeInitial(reader) {
44395
+ const read = await reader.read();
44396
+ if (!read.value) {
44397
+ throw new SyntaxError();
44398
+ }
44399
+ let line;
44400
+ try {
44401
+ line = JSON.parse(read.value);
44402
+ } catch (reason) {
44403
+ throw new SyntaxError();
44404
+ }
44405
+ return {
44406
+ done: read.done,
44407
+ value: unflatten.call(this, line)
44408
+ };
44409
+ }
44410
+ async function decodeDeferred(reader) {
44411
+ let read = await reader.read();
44412
+ while (!read.done) {
44413
+ if (!read.value)
44414
+ continue;
44415
+ const line = read.value;
44416
+ switch (line[0]) {
44417
+ case TYPE_PROMISE: {
44418
+ const colonIndex = line.indexOf(":");
44419
+ const deferredId = Number(line.slice(1, colonIndex));
44420
+ const deferred = this.deferred[deferredId];
44421
+ if (!deferred) {
44422
+ throw new Error(`Deferred ID ${deferredId} not found in stream`);
44423
+ }
44424
+ const lineData = line.slice(colonIndex + 1);
44425
+ let jsonLine;
44426
+ try {
44427
+ jsonLine = JSON.parse(lineData);
44428
+ } catch (reason) {
44429
+ throw new SyntaxError();
44430
+ }
44431
+ const value = unflatten.call(this, jsonLine);
44432
+ deferred.resolve(value);
44433
+ break;
44434
+ }
44435
+ case TYPE_ERROR: {
44436
+ const colonIndex = line.indexOf(":");
44437
+ const deferredId = Number(line.slice(1, colonIndex));
44438
+ const deferred = this.deferred[deferredId];
44439
+ if (!deferred) {
44440
+ throw new Error(`Deferred ID ${deferredId} not found in stream`);
44441
+ }
44442
+ const lineData = line.slice(colonIndex + 1);
44443
+ let jsonLine;
44444
+ try {
44445
+ jsonLine = JSON.parse(lineData);
44446
+ } catch (reason) {
44447
+ throw new SyntaxError();
44448
+ }
44449
+ const value = unflatten.call(this, jsonLine);
44450
+ deferred.reject(value);
44451
+ break;
44452
+ }
44453
+ default:
44454
+ throw new SyntaxError();
44455
+ }
44456
+ read = await reader.read();
44457
+ }
44458
+ }
44459
+
44460
+ // src/core/adapters/chatgpt.ts
44461
+ var SNAPSHOT_FORMAT = "asmgr.chatgpt-share";
44462
+ var SNAPSHOT_VERSION = 1;
44463
+ var SNAPSHOT_SUFFIX = ".chatgpt-share.json";
44464
+ var MAX_SHARE_HTML_BYTES = 50 * 1024 * 1024;
44465
+ var CHATGPT_HOSTS = /* @__PURE__ */ new Set(["chatgpt.com", "www.chatgpt.com", "chat.openai.com"]);
44466
+ var SHARE_LINK_EXAMPLE = "https://chatgpt.com/share/<\u4F1A\u8BDDID>";
44467
+ function chatGptRoot(root5) {
44468
+ if (root5) return expandHome(root5);
44469
+ const env2 = process.env;
44470
+ const base2 = env2.ASMGR_DATA_HOME ? expandHome(env2.ASMGR_DATA_HOME) : env2.XDG_DATA_HOME ? expandHome(env2.XDG_DATA_HOME) : process.platform === "win32" && env2.LOCALAPPDATA ? env2.LOCALAPPDATA : process.platform === "darwin" ? join2(homedir2(), "Library", "Application Support") : join2(homedir2(), ".local", "share");
44471
+ return join2(base2, "asmgr", "imports", "chatgpt");
44472
+ }
44473
+ function chatGptSnapshotPath(id, root5) {
44474
+ return join2(chatGptRoot(root5), `${id}${SNAPSHOT_SUFFIX}`);
44475
+ }
44476
+ function isHttpUrl(value) {
44477
+ try {
44478
+ const url = new URL(value);
44479
+ return url.protocol === "http:" || url.protocol === "https:";
44480
+ } catch {
44481
+ return false;
44482
+ }
44483
+ }
44484
+ function parseChatGptShareUrl(value) {
44485
+ let url;
44486
+ try {
44487
+ url = new URL(value);
44488
+ } catch {
44489
+ throw new Error(`\u65E0\u6548\u7684 URL\uFF1A${value}`);
44490
+ }
44491
+ if (url.protocol !== "https:") {
44492
+ throw new Error("ChatGPT \u5206\u4EAB\u94FE\u63A5\u5FC5\u987B\u4F7F\u7528 https");
44493
+ }
44494
+ if (!CHATGPT_HOSTS.has(url.hostname.toLowerCase())) {
44495
+ throw new Error(
44496
+ `\u76EE\u524D\u53EA\u652F\u6301 ChatGPT \u7684\u516C\u5F00\u5206\u4EAB\u94FE\u63A5\uFF0C\u683C\u5F0F\u5E94\u4E3A ${SHARE_LINK_EXAMPLE}`
44497
+ );
44498
+ }
44499
+ if (isAddressBarConversationPath(url.pathname)) {
44500
+ throw new Error(
44501
+ `\u68C0\u6D4B\u5230\u8FD9\u662F\u4ECE ChatGPT \u5730\u5740\u680F\u590D\u5236\u7684\u79C1\u6709\u4F1A\u8BDD\u94FE\u63A5\uFF0Casmgr \u65E0\u6CD5\u76F4\u63A5\u8BFB\u53D6\u3002\u8BF7\u5728 ChatGPT \u4E2D\u6253\u5F00\u8BE5\u4F1A\u8BDD\uFF0C\u70B9\u51FB\u53F3\u4E0A\u89D2\u201C\u5206\u4EAB\u201D\uFF0C\u521B\u5EFA\u5206\u4EAB\u94FE\u63A5\u540E\uFF0C\u518D\u590D\u5236\u5F62\u5982 ${SHARE_LINK_EXAMPLE} \u7684\u94FE\u63A5`
44502
+ );
44503
+ }
44504
+ if (url.port !== "" || url.username !== "" || url.password !== "" || !/^\/share\/[A-Za-z0-9_-]+\/?$/u.test(url.pathname)) {
44505
+ throw new Error(
44506
+ `\u8FD9\u4E0D\u662F ChatGPT \u5206\u4EAB\u94FE\u63A5\u3002\u8BF7\u6253\u5F00\u76EE\u6807\u4F1A\u8BDD\uFF0C\u70B9\u51FB\u201C\u5206\u4EAB\u201D\uFF0C\u518D\u590D\u5236\u5F62\u5982 ${SHARE_LINK_EXAMPLE} \u7684\u94FE\u63A5`
44507
+ );
44508
+ }
44509
+ url.hash = "";
44510
+ return url;
44511
+ }
44512
+ function chatGptConversationId(value) {
44513
+ const url = parseChatGptShareUrl(value);
44514
+ return url.pathname.split("/").filter(Boolean)[1] ?? "";
44515
+ }
44516
+ async function captureChatGptShare(value, fetchImpl = fetch) {
44517
+ const requested = parseChatGptShareUrl(value);
44518
+ const { response, finalUrl } = await fetchSharePage(requested, fetchImpl);
44519
+ if (!response.ok) {
44520
+ throw new Error(`\u83B7\u53D6 ChatGPT \u5206\u4EAB\u9875\u5931\u8D25\uFF1AHTTP ${response.status}`);
44521
+ }
44522
+ const contentType = response.headers.get("content-type") ?? "";
44523
+ if (!contentType.toLowerCase().includes("text/html")) {
44524
+ throw new Error(`ChatGPT \u5206\u4EAB\u9875\u8FD4\u56DE\u4E86\u5F02\u5E38\u7684\u5185\u5BB9\u7C7B\u578B\uFF1A${contentType || "\u672A\u63D0\u4F9B"}`);
44525
+ }
44526
+ const contentLength = Number(response.headers.get("content-length") ?? "0");
44527
+ if (contentLength > MAX_SHARE_HTML_BYTES) {
44528
+ throw new Error(`ChatGPT \u5206\u4EAB\u9875\u8FC7\u5927\uFF1A${contentLength} \u5B57\u8282`);
44529
+ }
44530
+ const html7 = await response.text();
44531
+ if (Buffer.byteLength(html7, "utf8") > MAX_SHARE_HTML_BYTES) {
44532
+ throw new Error(`ChatGPT \u5206\u4EAB\u9875\u8D85\u8FC7\u5927\u5C0F\u9650\u5236\uFF1A${MAX_SHARE_HTML_BYTES} \u5B57\u8282`);
44533
+ }
44534
+ const data = await decodeShareData(html7);
44535
+ if (data.is_public === false) {
44536
+ throw new Error("\u8BE5 ChatGPT \u4F1A\u8BDD\u672A\u516C\u5F00\uFF0C\u65E0\u6CD5\u8BFB\u53D6");
44537
+ }
44538
+ return {
44539
+ format: SNAPSHOT_FORMAT,
44540
+ version: SNAPSHOT_VERSION,
44541
+ capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
44542
+ requestedUrl: requested.toString(),
44543
+ sourceUrl: finalUrl.toString(),
44544
+ data
44545
+ };
44546
+ }
44547
+ async function readChatGptSnapshot(path3) {
44548
+ return validateSnapshot(await readJson(path3), path3);
44549
+ }
44550
+ function isChatGptShareSnapshot(value) {
44551
+ const snapshot = asRecord(value);
44552
+ return snapshot?.format === SNAPSHOT_FORMAT;
44553
+ }
44554
+ async function discoverChatGpt(root5 = chatGptRoot()) {
44555
+ const files = await walkFiles(expandHome(root5), (path3) => path3.endsWith(SNAPSHOT_SUFFIX));
44556
+ const refs = [];
44557
+ for (const path3 of files) {
44558
+ refs.push(refFromSnapshot(path3, await readChatGptSnapshot(path3)));
44559
+ }
44560
+ return refs.sort((a2, b3) => a2.id.localeCompare(b3.id));
44561
+ }
44562
+ async function refFromChatGptFile(path3) {
44563
+ return refFromSnapshot(path3, await readChatGptSnapshot(path3));
44564
+ }
44565
+ function refFromChatGptUrl(value) {
44566
+ const url = parseChatGptShareUrl(value);
44567
+ return {
44568
+ agent: "chatgpt",
44569
+ id: chatGptConversationId(url.toString()),
44570
+ path: url.toString(),
44571
+ source: {
44572
+ kind: "chatgpt-share",
44573
+ path: url.toString(),
44574
+ lossy: false,
44575
+ origin: url.toString()
44576
+ }
44577
+ };
44578
+ }
44579
+ async function parseChatGpt(ref) {
44580
+ const snapshot = isHttpUrl(ref.path) ? await captureChatGptShare(ref.path) : await readChatGptSnapshot(ref.path);
44581
+ return parseChatGptSnapshot(ref, snapshot);
44582
+ }
44583
+ function parseChatGptSnapshot(ref, snapshot) {
44584
+ const data = snapshot.data;
44585
+ const rows = Array.isArray(data.linear_conversation) ? data.linear_conversation : [];
44586
+ if (rows.length === 0) {
44587
+ throw new Error("ChatGPT \u5206\u4EAB\u6570\u636E\u4E2D\u6CA1\u6709\u53EF\u8BFB\u53D6\u7684 linear_conversation \u6D88\u606F");
44588
+ }
44589
+ const entries = [];
44590
+ const diagnosticCounts = { handled: 0, ignored: 0, unknown: 0 };
44591
+ const unknownTypes = /* @__PURE__ */ new Set();
44592
+ const fidelity = inspectChatGptFidelity(data);
44593
+ const {
44594
+ redactedToolResults,
44595
+ unredactedToolResults,
44596
+ omittedContentParts,
44597
+ omittedContentKinds
44598
+ } = fidelity;
44599
+ const {
44600
+ resultByCallPosition,
44601
+ callByResultPosition
44602
+ } = matchChatGptToolResults(rows);
44603
+ const firstUserPosition = rows.findIndex((row2) => {
44604
+ const message = asRecord(asRecord(row2)?.message);
44605
+ return stringValue(asRecord(message?.author)?.role) === "user";
44606
+ });
44607
+ function push2(entry) {
44608
+ entries.push({ index: entries.length, ...entry });
44609
+ }
44610
+ for (let position4 = 0; position4 < rows.length; position4 += 1) {
44611
+ const node2 = asRecord(rows[position4]);
44612
+ const message = asRecord(node2?.message);
44613
+ if (!message) {
44614
+ diagnosticCounts.ignored += 1;
44615
+ continue;
44616
+ }
44617
+ const author = asRecord(message.author);
44618
+ const metadata = asRecord(message.metadata);
44619
+ const role = stringValue(author?.role) ?? "unknown";
44620
+ const authorName = stringValue(author?.name);
44621
+ const recipient = stringValue(message.recipient);
44622
+ const content3 = asRecord(message.content);
44623
+ const contentType = stringValue(content3?.content_type) ?? "unknown";
44624
+ const text9 = messageText(message);
44625
+ const timestamp = isoTimestamp(message.create_time);
44626
+ const visuallyHidden = metadata?.is_visually_hidden_from_conversation === true;
44627
+ const rawType = `chatgpt/${role}/${contentType}${recipient ? `/${recipient}` : ""}`;
44628
+ const commonData = compactRecord({
44629
+ position: position4,
44630
+ nodeId: stringValue(node2?.id),
44631
+ parent: stringValue(node2?.parent),
44632
+ children: Array.isArray(node2?.children) ? node2.children : void 0,
44633
+ messageId: stringValue(message.id),
44634
+ authorName,
44635
+ recipient,
44636
+ channel: stringValue(message.channel),
44637
+ contentType,
44638
+ model: stringValue(metadata?.model_slug ?? metadata?.resolved_model_slug),
44639
+ turnExchangeId: stringValue(metadata?.turn_exchange_id),
44640
+ citations: metadata?.citations,
44641
+ contentReferences: metadata?.content_references,
44642
+ searchResultGroups: metadata?.search_result_groups,
44643
+ visuallyHidden
44644
+ });
44645
+ if (role === "user") {
44646
+ if (!text9.trim()) {
44647
+ diagnosticCounts.ignored += 1;
44648
+ continue;
44649
+ }
44650
+ diagnosticCounts.handled += 1;
44651
+ push2({ role: "user", kind: "message", text: text9, timestamp, rawType, data: commonData });
44652
+ continue;
44653
+ }
44654
+ if (role === "assistant") {
44655
+ if (contentType === "thoughts" || contentType === "reasoning_recap") {
44656
+ if (!text9.trim()) {
44657
+ diagnosticCounts.ignored += 1;
44658
+ continue;
44659
+ }
44660
+ diagnosticCounts.handled += 1;
44661
+ push2({ role: "reasoning", kind: contentType, text: text9, timestamp, rawType, data: commonData });
44662
+ continue;
44663
+ }
44664
+ if (recipient && recipient !== "all") {
44665
+ const matchedResult = resultByCallPosition.get(position4);
44666
+ const entryData = matchedResult ? compactRecord({
44667
+ ...commonData,
44668
+ toolResultPosition: matchedResult.position,
44669
+ toolResultNodeId: matchedResult.nodeId,
44670
+ toolResultMessageId: matchedResult.messageId
44671
+ }) : commonData;
44672
+ diagnosticCounts.handled += 1;
44673
+ push2({
44674
+ role: "tool",
44675
+ kind: "tool",
44676
+ title: recipient,
44677
+ text: "",
44678
+ timestamp,
44679
+ rawType,
44680
+ data: entryData,
44681
+ tool: {
44682
+ callId: stringValue(message.id),
44683
+ name: recipient,
44684
+ arguments: parseToolArguments(text9),
44685
+ intentionSummary: stringValue(metadata?.search_display_string),
44686
+ result: matchedResult ? normalizedToolResult(matchedResult) : { type: "pending" }
44687
+ }
44688
+ });
44689
+ continue;
44690
+ }
44691
+ if (contentType !== "text") {
44692
+ if (!text9.trim()) {
44693
+ diagnosticCounts.ignored += 1;
44694
+ continue;
44695
+ }
44696
+ diagnosticCounts.handled += 1;
44697
+ push2({ role: "system", kind: contentType, text: text9, timestamp, rawType, data: commonData });
44698
+ continue;
44699
+ }
44700
+ if (visuallyHidden || !text9.trim()) {
44701
+ diagnosticCounts.ignored += 1;
44702
+ continue;
44703
+ }
44704
+ diagnosticCounts.handled += 1;
44705
+ if (firstUserPosition >= 0 && position4 < firstUserPosition) {
44706
+ push2({ role: "system", kind: "preamble", text: text9, timestamp, rawType, data: commonData });
44707
+ } else {
44708
+ push2({ role: "assistant", kind: "message", text: text9, timestamp, rawType, data: commonData });
44709
+ }
44710
+ continue;
44711
+ }
44712
+ if (role === "tool") {
44713
+ const redacted = isRedactedToolResult(message);
44714
+ if (callByResultPosition.has(position4)) {
44715
+ diagnosticCounts.handled += 1;
44716
+ continue;
44717
+ }
44718
+ if (!redacted && !text9.trim()) {
44719
+ diagnosticCounts.ignored += 1;
44720
+ continue;
44721
+ }
44722
+ diagnosticCounts.handled += 1;
44723
+ push2({
44724
+ role: "tool",
44725
+ kind: "tool_result",
44726
+ title: authorName ?? "tool result",
44727
+ text: redacted ? "" : text9,
44728
+ timestamp,
44729
+ rawType,
44730
+ data: commonData,
44731
+ tool: {
44732
+ name: authorName ?? "tool result",
44733
+ result: redacted ? {
44734
+ type: "redacted",
44735
+ log: "ChatGPT \u5DF2\u5728\u516C\u5F00\u5206\u4EAB\u4E2D\u9690\u85CF\u8BE5\u5DE5\u5177\u7684\u539F\u59CB\u8F93\u51FA\u3002"
44736
+ } : { type: "success", log: text9 }
44737
+ }
44738
+ });
44739
+ continue;
44740
+ }
44741
+ if (role === "system") {
44742
+ if (!text9.trim()) {
44743
+ diagnosticCounts.ignored += 1;
44744
+ continue;
44745
+ }
44746
+ diagnosticCounts.handled += 1;
44747
+ push2({ role: "system", kind: contentType, text: text9, timestamp, rawType, data: commonData });
44748
+ continue;
44749
+ }
44750
+ diagnosticCounts.unknown += 1;
44751
+ unknownTypes.add(rawType);
44752
+ }
44753
+ const sourceInfoEntries = [];
44754
+ if (redactedToolResults > 0) {
44755
+ sourceInfoEntries.push({
44756
+ role: "event",
44757
+ kind: "info",
44758
+ text: `${redactedToolResults} \u6761\u5DE5\u5177\u7ED3\u679C\u5DF2\u88AB ChatGPT \u9690\u85CF\uFF1B\u4ECD\u53EF\u67E5\u770B\u5DE5\u5177\u53C2\u6570\u548C\u6D3E\u751F\u5F15\u7528\u3002`,
44759
+ rawType: "chatgpt/redaction-summary",
44760
+ data: { redactedToolResults, unredactedToolResults }
44761
+ });
44762
+ }
44763
+ if (omittedContentParts > 0) {
44764
+ sourceInfoEntries.push({
44765
+ role: "event",
44766
+ kind: "info",
44767
+ text: `${omittedContentParts} \u4E2A\u56FE\u7247\u6216\u9644\u4EF6\u5185\u5BB9\u672A\u968F\u516C\u5F00\u5206\u4EAB\u5F52\u6863\uFF1B\u62A5\u544A\u4EC5\u4FDD\u7559\u5360\u4F4D\u7B26\u3002`,
44768
+ rawType: "chatgpt/omitted-content-summary",
44769
+ data: { omittedContentParts, omittedContentKinds }
44770
+ });
44771
+ }
44772
+ if (sourceInfoEntries.length > 0) {
44773
+ entries.unshift(...sourceInfoEntries.map((entry, index2) => ({ index: index2, ...entry })));
44774
+ entries.forEach((entry, index2) => {
44775
+ entry.index = index2;
44776
+ });
44777
+ }
44778
+ const id = stringValue(data.conversation_id) || ref.id;
44779
+ const warning = chatGptFidelityWarning(fidelity);
44780
+ const diagnostics = {
44781
+ ...diagnosticCounts,
44782
+ unknownTypes: [...unknownTypes].sort()
44783
+ };
44784
+ return {
44785
+ ...ref,
44786
+ agent: "chatgpt",
44787
+ id,
44788
+ title: stringValue(data.title) ?? ref.title,
44789
+ startedAt: isoTimestamp(data.create_time) ?? ref.startedAt,
44790
+ updatedAt: isoTimestamp(data.update_time) ?? ref.updatedAt,
44791
+ source: {
44792
+ kind: "chatgpt-share",
44793
+ path: ref.path,
44794
+ lossy: Boolean(warning),
44795
+ warning,
44796
+ origin: snapshot.sourceUrl
44797
+ },
44798
+ diagnostics,
44799
+ entries
44800
+ };
44801
+ }
44802
+ function refFromSnapshot(path3, snapshot) {
44803
+ const data = snapshot.data;
44804
+ const fallbackId = basename5(path3).replace(new RegExp(`${escapeRegExp(SNAPSHOT_SUFFIX)}$`, "u"), "");
44805
+ const fidelity = inspectChatGptFidelity(data);
44806
+ const warning = chatGptFidelityWarning(fidelity);
44807
+ return {
44808
+ agent: "chatgpt",
44809
+ id: stringValue(data.conversation_id) || fallbackId,
44810
+ path: path3,
44811
+ title: stringValue(data.title),
44812
+ startedAt: isoTimestamp(data.create_time),
44813
+ updatedAt: isoTimestamp(data.update_time),
44814
+ source: {
44815
+ kind: "chatgpt-share",
44816
+ path: path3,
44817
+ lossy: Boolean(warning),
44818
+ warning,
44819
+ origin: snapshot.sourceUrl
44820
+ }
44821
+ };
44822
+ }
44823
+ function validateSnapshot(value, path3) {
44824
+ const snapshot = asRecord(value);
44825
+ if (snapshot?.format !== SNAPSHOT_FORMAT) {
44826
+ throw new Error(`\u4E0D\u652F\u6301\u7684 JSON \u4F1A\u8BDD\u683C\u5F0F\uFF1A${path3}`);
44827
+ }
44828
+ if (snapshot.version !== SNAPSHOT_VERSION) {
44829
+ throw new Error(`\u4E0D\u652F\u6301\u7684 ChatGPT \u5FEB\u7167\u7248\u672C\uFF1A${String(snapshot.version)}`);
44830
+ }
44831
+ const data = asRecord(snapshot.data);
44832
+ if (!data || !Array.isArray(data.linear_conversation)) {
44833
+ throw new Error(`\u65E0\u6548\u7684 ChatGPT \u5206\u4EAB\u5FEB\u7167\uFF1A${path3}`);
44834
+ }
44835
+ const capturedAt = stringValue(snapshot.capturedAt);
44836
+ const requestedUrl = stringValue(snapshot.requestedUrl);
44837
+ const sourceUrl = stringValue(snapshot.sourceUrl);
44838
+ if (!capturedAt || !requestedUrl || !sourceUrl) {
44839
+ throw new Error(`ChatGPT \u5206\u4EAB\u5FEB\u7167\u5143\u6570\u636E\u4E0D\u5B8C\u6574\uFF1A${path3}`);
44840
+ }
44841
+ return {
44842
+ format: SNAPSHOT_FORMAT,
44843
+ version: SNAPSHOT_VERSION,
44844
+ capturedAt,
44845
+ requestedUrl,
44846
+ sourceUrl,
44847
+ data
44848
+ };
44849
+ }
44850
+ async function decodeShareData(html7) {
44851
+ const chunks = extractEnqueuedChunks(html7);
44852
+ if (chunks.length === 0) {
44853
+ throw new Error(
44854
+ "\u672A\u627E\u5230 ChatGPT \u5206\u4EAB\u6570\u636E\uFF1B\u94FE\u63A5\u53EF\u80FD\u662F\u79C1\u6709\u4F1A\u8BDD\u3001\u5DF2\u5931\u6548\uFF0C\u6216\u9875\u9762\u683C\u5F0F\u5DF2\u7ECF\u53D8\u5316"
44855
+ );
44856
+ }
44857
+ const encoder = new TextEncoder();
44858
+ const stream = new ReadableStream({
44859
+ start(controller) {
44860
+ for (const chunk of chunks) controller.enqueue(encoder.encode(chunk));
44861
+ controller.close();
44862
+ }
44863
+ });
44864
+ const decoded = await decode(stream);
44865
+ await decoded.done;
44866
+ const root5 = asRecord(decoded.value);
44867
+ const loaderData = asRecord(root5?.loaderData);
44868
+ for (const route of Object.values(loaderData ?? {})) {
44869
+ const routeData = asRecord(asRecord(route)?.serverResponse)?.data;
44870
+ const candidate = asRecord(routeData);
44871
+ if (candidate && Array.isArray(candidate.linear_conversation)) return candidate;
44872
+ }
44873
+ throw new Error(
44874
+ "\u672A\u627E\u5230 ChatGPT \u5206\u4EAB\u6570\u636E\uFF1B\u9875\u9762\u683C\u5F0F\u53EF\u80FD\u5DF2\u7ECF\u53D8\u5316"
44875
+ );
44876
+ }
44877
+ function extractEnqueuedChunks(html7) {
44878
+ const chunks = [];
44879
+ const marker = "streamController.enqueue(";
44880
+ let offset = 0;
44881
+ while (offset < html7.length) {
44882
+ const markerIndex = html7.indexOf(marker, offset);
44883
+ if (markerIndex < 0) break;
44884
+ let start2 = markerIndex + marker.length;
44885
+ while (/\s/u.test(html7[start2] ?? "")) start2 += 1;
44886
+ if (html7[start2] !== '"') {
44887
+ offset = start2 + 1;
44888
+ continue;
44889
+ }
44890
+ let end = start2 + 1;
44891
+ while (end < html7.length) {
44892
+ if (html7[end] === "\\") {
44893
+ end += 2;
44894
+ continue;
44895
+ }
44896
+ if (html7[end] === '"') break;
44897
+ end += 1;
44898
+ }
44899
+ if (end >= html7.length) {
44900
+ throw new Error("ChatGPT \u5206\u4EAB\u9875\u7684\u6C34\u5408\u6570\u636E\u5305\u542B\u672A\u7ED3\u675F\u7684\u5B57\u7B26\u4E32");
44901
+ }
44902
+ try {
44903
+ chunks.push(JSON.parse(html7.slice(start2, end + 1)));
44904
+ } catch {
44905
+ throw new Error("ChatGPT \u5206\u4EAB\u9875\u7684\u6C34\u5408\u6570\u636E\u5305\u542B\u65E0\u6548\u7684 JavaScript \u5B57\u7B26\u4E32");
44906
+ }
44907
+ offset = end + 1;
44908
+ }
44909
+ return chunks;
44910
+ }
44911
+ function messageText(message) {
44912
+ const content3 = asRecord(message.content);
44913
+ if (!content3) return "";
44914
+ if (Array.isArray(content3.parts)) {
44915
+ return content3.parts.map(partToText).filter(Boolean).join("\n");
44916
+ }
44917
+ if (typeof content3.text === "string") return content3.text;
44918
+ if (Array.isArray(content3.thoughts)) {
44919
+ return content3.thoughts.map((value) => {
44920
+ const thought = asRecord(value);
44921
+ return [stringValue(thought?.summary), stringValue(thought?.content)].filter(Boolean).join("\n");
44922
+ }).filter(Boolean).join("\n\n");
44923
+ }
44924
+ if (typeof content3.content === "string") return content3.content;
44925
+ return contentToText(content3);
44926
+ }
44927
+ function partToText(value) {
44928
+ if (typeof value === "string") return value;
44929
+ const part = asRecord(value);
44930
+ if (!part) return String(value ?? "");
44931
+ if (part.content_type === "text" && typeof part.text === "string") return part.text;
44932
+ if (part.content_type === "image_asset_pointer") {
44933
+ return `[image:${stringValue(part.asset_pointer) ?? "unknown"}]`;
44934
+ }
44935
+ return contentToText(part);
44936
+ }
44937
+ function parseToolArguments(text9) {
44938
+ if (!text9) return void 0;
44939
+ try {
44940
+ return JSON.parse(text9);
44941
+ } catch {
44942
+ return text9;
44943
+ }
44944
+ }
44945
+ function matchChatGptToolResults(rows) {
44946
+ const segments = [];
44947
+ let segment = [];
44948
+ for (let position4 = 0; position4 < rows.length; position4 += 1) {
44949
+ const message = asRecord(asRecord(rows[position4])?.message);
44950
+ const role = stringValue(asRecord(message?.author)?.role);
44951
+ if (role === "user" && segment.length > 0) {
44952
+ segments.push(segment);
44953
+ segment = [];
44954
+ }
44955
+ segment.push(position4);
44956
+ }
44957
+ if (segment.length > 0) segments.push(segment);
44958
+ const resultByCallPosition = /* @__PURE__ */ new Map();
44959
+ const callByResultPosition = /* @__PURE__ */ new Map();
44960
+ for (const positions of segments) {
44961
+ const calls = positions.flatMap((position4) => {
44962
+ const message = asRecord(asRecord(rows[position4])?.message);
44963
+ const role = stringValue(asRecord(message?.author)?.role);
44964
+ const name2 = stringValue(message?.recipient);
44965
+ return role === "assistant" && name2 && name2 !== "all" ? [{ position: position4, name: name2 }] : [];
44966
+ });
44967
+ const unmatchedCalls = new Set(calls.map((call) => call.position));
44968
+ for (const position4 of positions) {
44969
+ const node2 = asRecord(rows[position4]);
44970
+ const message = asRecord(node2?.message);
44971
+ const role = stringValue(asRecord(message?.author)?.role);
44972
+ if (role !== "tool" || !message) continue;
44973
+ const text9 = messageText(message);
44974
+ const redacted = isRedactedToolResult(message);
44975
+ if (!redacted && !text9.trim()) continue;
44976
+ const name2 = stringValue(asRecord(message.author)?.name);
44977
+ const candidates = calls.filter((call2) => unmatchedCalls.has(call2.position) && (name2 ? call2.name === name2 : true));
44978
+ if (candidates.length !== 1) continue;
44979
+ const call = candidates[0];
44980
+ const result = {
44981
+ position: position4,
44982
+ name: name2,
44983
+ text: text9,
44984
+ redacted,
44985
+ nodeId: stringValue(node2?.id),
44986
+ messageId: stringValue(message.id)
44987
+ };
44988
+ resultByCallPosition.set(call.position, result);
44989
+ callByResultPosition.set(position4, call.position);
44990
+ unmatchedCalls.delete(call.position);
44991
+ }
44992
+ }
44993
+ return { resultByCallPosition, callByResultPosition };
44994
+ }
44995
+ function normalizedToolResult(result) {
44996
+ return result.redacted ? {
44997
+ type: "redacted",
44998
+ log: "ChatGPT \u5DF2\u5728\u516C\u5F00\u5206\u4EAB\u4E2D\u9690\u85CF\u8BE5\u5DE5\u5177\u7684\u539F\u59CB\u8F93\u51FA\u3002"
44999
+ } : { type: "success", log: result.text };
45000
+ }
45001
+ function isRedactedToolResult(message) {
45002
+ const metadata = asRecord(message.metadata);
45003
+ return metadata?.is_redacted === true || messageText(message) === "The output of this plugin was redacted.";
45004
+ }
45005
+ function inspectChatGptFidelity(data) {
45006
+ const rows = Array.isArray(data.linear_conversation) ? data.linear_conversation : [];
45007
+ let redactedToolResults = 0;
45008
+ let unredactedToolResults = 0;
45009
+ let omittedContentParts = 0;
45010
+ const omittedContentKinds = /* @__PURE__ */ new Set();
45011
+ for (const row2 of rows) {
45012
+ const message = asRecord(asRecord(row2)?.message);
45013
+ if (!message) continue;
45014
+ if (stringValue(asRecord(message.author)?.role) === "tool") {
45015
+ if (isRedactedToolResult(message)) redactedToolResults += 1;
45016
+ else unredactedToolResults += 1;
45017
+ }
45018
+ omittedContentParts += collectOmittedContentKinds(message.content, omittedContentKinds);
45019
+ }
45020
+ return {
45021
+ redactedToolResults,
45022
+ unredactedToolResults,
45023
+ omittedContentParts,
45024
+ omittedContentKinds: [...omittedContentKinds].sort()
45025
+ };
45026
+ }
45027
+ function collectOmittedContentKinds(value, kinds) {
45028
+ if (Array.isArray(value)) {
45029
+ return value.reduce((count, item) => count + collectOmittedContentKinds(item, kinds), 0);
45030
+ }
45031
+ const record = asRecord(value);
45032
+ if (!record) return 0;
45033
+ const contentType = stringValue(record.content_type);
45034
+ const hasExternalAsset = typeof record.asset_pointer === "string" || "image_url" in record || "audio_url" in record || "video_url" in record || "file_id" in record;
45035
+ if (hasExternalAsset) {
45036
+ kinds.add(contentType ?? "external_asset");
45037
+ return 1;
45038
+ }
45039
+ return Object.values(record).reduce((count, item) => count + collectOmittedContentKinds(item, kinds), 0);
45040
+ }
45041
+ function chatGptFidelityWarning(fidelity) {
45042
+ const warnings = [];
45043
+ if (fidelity.redactedToolResults > 0) {
45044
+ warnings.push(
45045
+ `\u6765\u6E90\u5DF2\u9690\u85CF ${fidelity.redactedToolResults} \u6761 ChatGPT \u5DE5\u5177\u7ED3\u679C\uFF0C\u539F\u59CB\u8F93\u51FA\u65E0\u6CD5\u6062\u590D`
45046
+ );
45047
+ }
45048
+ if (fidelity.omittedContentParts > 0) {
45049
+ const kinds = fidelity.omittedContentKinds.length > 0 ? `\uFF08${fidelity.omittedContentKinds.join("\u3001")}\uFF09` : "";
45050
+ warnings.push(
45051
+ `\u516C\u5F00\u5206\u4EAB\u4E2D\u7684 ${fidelity.omittedContentParts} \u4E2A\u56FE\u7247\u6216\u9644\u4EF6\u5185\u5BB9\u672A\u5F52\u6863${kinds}\uFF0C\u4EC5\u4FDD\u7559\u5360\u4F4D\u7B26`
45052
+ );
45053
+ }
45054
+ return warnings.length > 0 ? warnings.join("\uFF1B") : void 0;
45055
+ }
45056
+ function isoTimestamp(value) {
45057
+ if (typeof value === "number" && Number.isFinite(value)) {
45058
+ return new Date(value * 1e3).toISOString();
45059
+ }
45060
+ if (typeof value === "string" && value) {
45061
+ const milliseconds = Date.parse(value);
45062
+ return Number.isNaN(milliseconds) ? void 0 : new Date(milliseconds).toISOString();
45063
+ }
45064
+ return void 0;
45065
+ }
45066
+ function asRecord(value) {
45067
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
45068
+ }
45069
+ function stringValue(value) {
45070
+ return typeof value === "string" && value ? value : void 0;
45071
+ }
45072
+ function compactRecord(value) {
45073
+ return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== void 0));
45074
+ }
45075
+ function escapeRegExp(value) {
45076
+ return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
45077
+ }
45078
+ async function fetchSharePage(requested, fetchImpl) {
45079
+ let current = requested;
45080
+ for (let redirectCount = 0; redirectCount <= 5; redirectCount += 1) {
45081
+ const response = await fetchImpl(current, {
45082
+ redirect: "manual",
45083
+ signal: AbortSignal.timeout(3e4),
45084
+ headers: {
45085
+ accept: "text/html,application/xhtml+xml",
45086
+ "user-agent": "asmgr ChatGPT share importer"
45087
+ }
45088
+ });
45089
+ if (![301, 302, 303, 307, 308].includes(response.status)) {
45090
+ return { response, finalUrl: current };
45091
+ }
45092
+ const location2 = response.headers.get("location");
45093
+ if (!location2) throw new Error("ChatGPT \u5206\u4EAB\u9875\u91CD\u5B9A\u5411\u65F6\u6CA1\u6709\u63D0\u4F9B\u76EE\u6807\u5730\u5740");
45094
+ try {
45095
+ current = parseChatGptShareUrl(new URL(location2, current).toString());
45096
+ } catch {
45097
+ throw new Error("\u8BE5\u94FE\u63A5\u91CD\u5B9A\u5411\u5230\u4E86 ChatGPT \u516C\u5F00\u5206\u4EAB\u9875\u4E4B\u5916\uFF0C\u5DF2\u505C\u6B62\u8BBF\u95EE");
45098
+ }
45099
+ }
45100
+ throw new Error("ChatGPT \u5206\u4EAB\u9875\u91CD\u5B9A\u5411\u6B21\u6570\u8FC7\u591A");
45101
+ }
45102
+ function isAddressBarConversationPath(pathname) {
45103
+ return /^\/c\/[^/]+\/?$/u.test(pathname) || /^\/g\/[^/]+\/c\/[^/]+\/?$/u.test(pathname);
45104
+ }
45105
+
44083
45106
  // src/core/project.ts
44084
45107
  import { existsSync } from "node:fs";
44085
- import { dirname as dirname3, join as join2 } from "node:path";
45108
+ import { dirname as dirname3, join as join3 } from "node:path";
44086
45109
  function deriveProject(cwd) {
44087
45110
  if (!cwd) return "(unscoped)";
44088
45111
  if (existsSync(cwd)) {
44089
45112
  let dir = cwd;
44090
45113
  for (let i3 = 0; i3 < 40; i3 += 1) {
44091
- if (existsSync(join2(dir, ".git"))) return dir;
45114
+ if (existsSync(join3(dir, ".git"))) return dir;
44092
45115
  const parent = dirname3(dir);
44093
45116
  if (parent === dir) break;
44094
45117
  dir = parent;
@@ -44098,18 +45121,20 @@ function deriveProject(cwd) {
44098
45121
  }
44099
45122
 
44100
45123
  // src/core/index.ts
44101
- var AGENTS = ["copilot", "claude", "codex"];
45124
+ var AGENTS = ["copilot", "claude", "codex", "chatgpt"];
44102
45125
  async function discoverSessions(agents = AGENTS, roots = {}) {
44103
45126
  const found = [];
44104
45127
  if (agents.includes("copilot")) found.push(...await discoverCopilot(roots.copilot, roots.copilotDb));
44105
45128
  if (agents.includes("claude")) found.push(...await discoverClaude(roots.claude));
44106
45129
  if (agents.includes("codex")) found.push(...await discoverCodex(roots.codex));
45130
+ if (agents.includes("chatgpt")) found.push(...await discoverChatGpt(roots.chatgpt));
44107
45131
  return found.sort((a2, b3) => a2.agent.localeCompare(b3.agent) || a2.id.localeCompare(b3.id));
44108
45132
  }
44109
45133
  async function parseSession(ref) {
44110
45134
  if (ref.agent === "copilot") return parseCopilot(ref);
44111
45135
  if (ref.agent === "claude") return parseClaude(ref);
44112
- return parseCodex(ref);
45136
+ if (ref.agent === "codex") return parseCodex(ref);
45137
+ return parseChatGpt(ref);
44113
45138
  }
44114
45139
  async function findSession(id, agents = AGENTS, roots = {}) {
44115
45140
  return findSessionAmong(await discoverSessions(agents, roots), id);
@@ -44197,7 +45222,7 @@ function detectAgent(rows, path3) {
44197
45222
  }
44198
45223
  }
44199
45224
  if (copilot === 0 && codex === 0 && claude === 0) {
44200
- return path3 && basename5(path3) === "events.jsonl" ? "copilot" : void 0;
45225
+ return path3 && basename6(path3) === "events.jsonl" ? "copilot" : void 0;
44201
45226
  }
44202
45227
  if (copilot >= codex && copilot >= claude) return "copilot";
44203
45228
  if (codex >= claude) return "codex";
@@ -44212,7 +45237,7 @@ function deriveId(path3, agent, rows) {
44212
45237
  const data = record.data ?? {};
44213
45238
  if (typeof data.sessionId === "string" && data.sessionId) return data.sessionId;
44214
45239
  }
44215
- return basename5(path3) === "events.jsonl" ? parentName(path3) : fileStem(path3);
45240
+ return basename6(path3) === "events.jsonl" ? parentName(path3) : fileStem(path3);
44216
45241
  }
44217
45242
  if (agent === "codex") {
44218
45243
  for (const row2 of rows.slice(0, 10)) {
@@ -44230,23 +45255,62 @@ function deriveId(path3, agent, rows) {
44230
45255
  }
44231
45256
  async function refFromFile(path3, agentOverride) {
44232
45257
  const abs = expandHome(path3);
45258
+ let document4;
45259
+ let isJsonDocument = false;
45260
+ if (!abs.endsWith(".jsonl")) {
45261
+ try {
45262
+ document4 = await readJson(abs);
45263
+ isJsonDocument = true;
45264
+ } catch {
45265
+ }
45266
+ }
45267
+ if (isJsonDocument) {
45268
+ if (isChatGptShareSnapshot(document4)) {
45269
+ if (agentOverride && agentOverride !== "chatgpt") {
45270
+ throw new Error(`\u8BE5\u6587\u4EF6\u5305\u542B ChatGPT \u4F1A\u8BDD\u6570\u636E\uFF0C\u4E0E --agent ${agentOverride} \u4E0D\u5339\u914D\uFF1A${path3}`);
45271
+ }
45272
+ return refFromChatGptFile(abs);
45273
+ }
45274
+ const detected = detectAgent([document4], abs);
45275
+ if (!detected || detected === "chatgpt") {
45276
+ throw new Error(`\u4E0D\u652F\u6301\u7684 JSON \u4F1A\u8BDD\u683C\u5F0F\uFF1A${path3}`);
45277
+ }
45278
+ const agent2 = agentOverride ?? detected;
45279
+ if (agent2 === "chatgpt") {
45280
+ throw new Error(`\u8BE5\u6587\u4EF6\u5305\u542B ${detected} \u4F1A\u8BDD\u6570\u636E\uFF0C\u4E0E --agent chatgpt \u4E0D\u5339\u914D\uFF1A${path3}`);
45281
+ }
45282
+ return { agent: agent2, id: deriveId(abs, agent2, [document4]), path: abs };
45283
+ }
45284
+ if (agentOverride === "chatgpt" || abs.endsWith(".chatgpt-share.json")) {
45285
+ return refFromChatGptFile(abs);
45286
+ }
44233
45287
  const rows = await readJsonl(abs);
44234
- const agent = agentOverride ?? detectAgent(rows, abs) ?? "copilot";
45288
+ const agent = agentOverride ?? detectAgent(rows, abs);
45289
+ if (!agent) throw new Error(`\u4E0D\u652F\u6301\u7684\u4F1A\u8BDD\u6587\u4EF6\u683C\u5F0F\uFF1A${path3}`);
45290
+ if (agent === "chatgpt") return refFromChatGptFile(abs);
44235
45291
  return { agent, id: deriveId(abs, agent, rows), path: abs };
44236
45292
  }
45293
+ function refFromUrl(value) {
45294
+ if (!isHttpUrl(value)) throw new Error(`\u65E0\u6548\u7684 URL\uFF1A${value}`);
45295
+ return refFromChatGptUrl(value);
45296
+ }
44237
45297
  async function discoverPath(path3, agentOverride) {
44238
45298
  const abs = expandHome(path3);
44239
45299
  if (!await pathExists(abs)) throw new Error(`path not found: ${path3}`);
44240
45300
  const info = await stat2(abs);
44241
45301
  if (info.isFile()) return [await refFromFile(abs, agentOverride)];
44242
- const files = await walkFiles(abs, (candidate) => candidate.endsWith(".jsonl"));
45302
+ const files = await walkFiles(
45303
+ abs,
45304
+ (candidate) => candidate.endsWith(".jsonl") || candidate.endsWith(".chatgpt-share.json")
45305
+ );
44243
45306
  const refs = [];
44244
45307
  for (const file of files) refs.push(await refFromFile(file, agentOverride));
44245
45308
  return refs.sort((a2, b3) => a2.agent.localeCompare(b3.agent) || a2.id.localeCompare(b3.id));
44246
45309
  }
44247
45310
  var LOSSY_SOURCE_WARNING = "\u6570\u636E\u6E90\u56DE\u9000\u5230 db.turns (fallback) \u2014\u2014 \u4EA4\u4E92\u5F0F\u7528\u6237\u51B3\u7B56\u4E0E\u5DE5\u5177\u6761\u76EE\u5728\u6B64\u6A21\u5F0F\u4E0B\u4E0D\u53EF\u6062\u590D";
44248
45311
  function lossySourceWarning(source) {
44249
- return source && (source.lossy || source.kind === "db-turns") ? LOSSY_SOURCE_WARNING : void 0;
45312
+ if (!source || !source.lossy && source.kind !== "db-turns") return void 0;
45313
+ return source.warning ?? LOSSY_SOURCE_WARNING;
44250
45314
  }
44251
45315
  function sessionToText(session) {
44252
45316
  return renderSessionText(session, session.entries);
@@ -44320,13 +45384,13 @@ ${text9}`);
44320
45384
 
44321
45385
  // src/cli/options/common.ts
44322
45386
  function withAgent(cmd) {
44323
- return cmd.option("-a, --agent <agent>", "copilot|claude|codex|all", "all");
45387
+ return cmd.option("-a, --agent <agent>", "copilot|claude|codex|chatgpt|all", "all");
44324
45388
  }
44325
45389
  function withSource(cmd, fileDescription) {
44326
45390
  return cmd.option("--file <path>", fileDescription).option("--events <path>", "alias of --file (an explicit events.jsonl path)");
44327
45391
  }
44328
45392
  function withRoots(cmd) {
44329
- return cmd.option("--copilot-root <path>", "override Copilot session-state root").option("--copilot-db <path>", "override Copilot session-store.db (for pruned/DB-only sessions)").option("--claude-root <path>", "override Claude projects root").option("--codex-root <path>", "override Codex sessions root");
45393
+ return cmd.option("--copilot-root <path>", "override Copilot session-state root").option("--copilot-db <path>", "override Copilot session-store.db (for pruned/DB-only sessions)").option("--claude-root <path>", "override Claude projects root").option("--codex-root <path>", "override Codex sessions root").option("--chatgpt-root <path>", "\u8986\u76D6\u6258\u7BA1\u7684 ChatGPT \u5BFC\u5165\u76EE\u5F55");
44330
45394
  }
44331
45395
  function withReadSource(cmd, fileDescription) {
44332
45396
  return withRoots(withSource(withAgent(cmd), fileDescription));
@@ -44335,7 +45399,7 @@ function withReadSource(cmd, fileDescription) {
44335
45399
  // src/cli/options/resolve.ts
44336
45400
  function parseAgents(value) {
44337
45401
  if (value === "all") return AGENTS;
44338
- if (value === "copilot" || value === "claude" || value === "codex") return [value];
45402
+ if (value === "copilot" || value === "claude" || value === "codex" || value === "chatgpt") return [value];
44339
45403
  throw new Error(`unknown agent: ${value}`);
44340
45404
  }
44341
45405
  function filePathFromOptions(opts) {
@@ -44351,7 +45415,8 @@ function rootsFromOptions(opts) {
44351
45415
  copilot: typeof opts.copilotRoot === "string" ? opts.copilotRoot : void 0,
44352
45416
  copilotDb: typeof opts.copilotDb === "string" ? opts.copilotDb : void 0,
44353
45417
  claude: typeof opts.claudeRoot === "string" ? opts.claudeRoot : void 0,
44354
- codex: typeof opts.codexRoot === "string" ? opts.codexRoot : void 0
45418
+ codex: typeof opts.codexRoot === "string" ? opts.codexRoot : void 0,
45419
+ chatgpt: typeof opts.chatgptRoot === "string" ? opts.chatgptRoot : void 0
44355
45420
  };
44356
45421
  }
44357
45422
  async function resolveRefs(opts) {
@@ -44361,6 +45426,14 @@ async function resolveRefs(opts) {
44361
45426
  }
44362
45427
  async function resolveOne(id, opts) {
44363
45428
  const file = filePathFromOptions(opts);
45429
+ if (id && isHttpUrl(id)) {
45430
+ if (file) throw new Error("\u4F1A\u8BDD\u94FE\u63A5\u4E0D\u80FD\u4E0E --file \u540C\u65F6\u4F7F\u7528");
45431
+ const agent = String(opts.agent ?? "all");
45432
+ if (agent !== "all" && agent !== "chatgpt") {
45433
+ throw new Error("\u4F1A\u8BDD\u94FE\u63A5\u4EC5\u652F\u6301 --agent chatgpt");
45434
+ }
45435
+ return refFromUrl(id);
45436
+ }
44364
45437
  if (file) {
44365
45438
  const refs = await discoverPath(file, agentOverrideFromOptions(opts));
44366
45439
  if (refs.length === 0) throw new Error(`no sessions found in --file path: ${file}`);
@@ -44441,7 +45514,7 @@ function buildSearchCommand() {
44441
45514
  import { mkdir, writeFile } from "node:fs/promises";
44442
45515
  import { dirname as dirname4, resolve } from "node:path";
44443
45516
  function buildShowCommand() {
44444
- const cmd = new Command("show").argument("[session-id]", "session id (optional when --file points at a single file)").description("Print a session as text, dialogue, or JSON");
45517
+ const cmd = new Command("show").argument("[session-id-or-url]", "\u4F1A\u8BDD ID \u6216 ChatGPT \u516C\u5F00\u5206\u4EAB\u94FE\u63A5\uFF08--file \u53EA\u6709\u4E00\u4E2A\u4F1A\u8BDD\u65F6\u53EF\u7701\u7565\uFF09").description("Print a session as text, dialogue, or JSON");
44445
45518
  withAgent(cmd).option("-f, --format <format>", "text|dialogue|json", "text").option("-o, --out <path>", "output file (default: stdout)");
44446
45519
  withSource(cmd, "read an explicit session file/directory instead of the live agent homes");
44447
45520
  withRoots(cmd);
@@ -47697,10 +48770,10 @@ function resolveAll(constructs2, events, context) {
47697
48770
  const called = [];
47698
48771
  let index2 = -1;
47699
48772
  while (++index2 < constructs2.length) {
47700
- const resolve9 = constructs2[index2].resolveAll;
47701
- if (resolve9 && !called.includes(resolve9)) {
47702
- events = resolve9(events, context);
47703
- called.push(resolve9);
48773
+ const resolve10 = constructs2[index2].resolveAll;
48774
+ if (resolve10 && !called.includes(resolve10)) {
48775
+ events = resolve10(events, context);
48776
+ called.push(resolve10);
47704
48777
  }
47705
48778
  }
47706
48779
  return events;
@@ -51310,9 +52383,9 @@ function preprocess() {
51310
52383
  // node_modules/.pnpm/micromark-util-decode-string@2.0.1/node_modules/micromark-util-decode-string/index.js
51311
52384
  var characterEscapeOrReference = /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi;
51312
52385
  function decodeString(value) {
51313
- return value.replace(characterEscapeOrReference, decode);
52386
+ return value.replace(characterEscapeOrReference, decode2);
51314
52387
  }
51315
- function decode($0, $1, $22) {
52388
+ function decode2($0, $1, $22) {
51316
52389
  if ($1) {
51317
52390
  return $1;
51318
52391
  }
@@ -53510,10 +54583,10 @@ var VFile = class {
53510
54583
  * @returns {undefined}
53511
54584
  * Nothing.
53512
54585
  */
53513
- set basename(basename7) {
53514
- assertNonEmpty(basename7, "basename");
53515
- assertPart(basename7, "basename");
53516
- this.path = default2.join(this.dirname || "", basename7);
54586
+ set basename(basename8) {
54587
+ assertNonEmpty(basename8, "basename");
54588
+ assertPart(basename8, "basename");
54589
+ this.path = default2.join(this.dirname || "", basename8);
53517
54590
  }
53518
54591
  /**
53519
54592
  * Get the parent path (example: `'~'`).
@@ -53534,9 +54607,9 @@ var VFile = class {
53534
54607
  * @returns {undefined}
53535
54608
  * Nothing.
53536
54609
  */
53537
- set dirname(dirname8) {
54610
+ set dirname(dirname9) {
53538
54611
  assertPath(this.basename, "dirname");
53539
- this.path = default2.join(dirname8 || "", this.basename);
54612
+ this.path = default2.join(dirname9 || "", this.basename);
53540
54613
  }
53541
54614
  /**
53542
54615
  * Get the extname (including dot) (example: `'.js'`).
@@ -54135,7 +55208,7 @@ var Processor = class _Processor extends CallableInstance {
54135
55208
  assertParser("process", this.parser || this.Parser);
54136
55209
  assertCompiler("process", this.compiler || this.Compiler);
54137
55210
  return done ? executor(void 0, done) : new Promise(executor);
54138
- function executor(resolve9, reject) {
55211
+ function executor(resolve10, reject) {
54139
55212
  const realFile = vfile(file);
54140
55213
  const parseTree3 = (
54141
55214
  /** @type {HeadTree extends undefined ? Node : HeadTree} */
@@ -54166,8 +55239,8 @@ var Processor = class _Processor extends CallableInstance {
54166
55239
  function realDone(error, file2) {
54167
55240
  if (error || !file2) {
54168
55241
  reject(error);
54169
- } else if (resolve9) {
54170
- resolve9(file2);
55242
+ } else if (resolve10) {
55243
+ resolve10(file2);
54171
55244
  } else {
54172
55245
  ok(done, "`done` is defined if `resolve` is not");
54173
55246
  done(void 0, file2);
@@ -54269,7 +55342,7 @@ var Processor = class _Processor extends CallableInstance {
54269
55342
  file = void 0;
54270
55343
  }
54271
55344
  return done ? executor(void 0, done) : new Promise(executor);
54272
- function executor(resolve9, reject) {
55345
+ function executor(resolve10, reject) {
54273
55346
  ok(
54274
55347
  typeof file !== "function",
54275
55348
  "`file` can\u2019t be a `done` anymore, we checked"
@@ -54283,8 +55356,8 @@ var Processor = class _Processor extends CallableInstance {
54283
55356
  );
54284
55357
  if (error) {
54285
55358
  reject(error);
54286
- } else if (resolve9) {
54287
- resolve9(resultingTree);
55359
+ } else if (resolve10) {
55360
+ resolve10(resultingTree);
54288
55361
  } else {
54289
55362
  ok(done, "`done` is defined if `resolve` is not");
54290
55363
  done(void 0, resultingTree, file2);
@@ -63811,15 +64884,15 @@ function collectText(node2, info) {
63811
64884
  start2 = end + 1;
63812
64885
  }
63813
64886
  let index2 = -1;
63814
- let join4;
64887
+ let join5;
63815
64888
  while (++index2 < lines.length) {
63816
64889
  if (lines[index2].charCodeAt(lines[index2].length - 1) === 8203 || index2 < lines.length - 1 && lines[index2 + 1].charCodeAt(0) === 8203) {
63817
64890
  result.push(lines[index2]);
63818
- join4 = void 0;
64891
+ join5 = void 0;
63819
64892
  } else if (lines[index2]) {
63820
- if (typeof join4 === "number") result.push(join4);
64893
+ if (typeof join5 === "number") result.push(join5);
63821
64894
  result.push(lines[index2]);
63822
- join4 = 0;
64895
+ join5 = 0;
63823
64896
  } else if (index2 === 0 || index2 === lines.length - 1) {
63824
64897
  result.push(0);
63825
64898
  }
@@ -82104,7 +83177,7 @@ var PILL_ORDER = [
82104
83177
  var PILL_DEFS = {
82105
83178
  summary: { key: "summary", label: "\u603B\u7ED3", icon: "star", accent: "amber" },
82106
83179
  user: { key: "user", label: "\u7528\u6237", icon: "user", accent: "blue" },
82107
- assistant: { key: "assistant", label: "Copilot", icon: "bot", accent: "green" },
83180
+ assistant: { key: "assistant", label: "\u52A9\u624B", icon: "bot", accent: "green" },
82108
83181
  tool: { key: "tool", label: "\u5DE5\u5177", icon: "wrench", accent: "violet" },
82109
83182
  reasoning: { key: "reasoning", label: "\u63A8\u7406", icon: "brain", accent: "amber" },
82110
83183
  group: { key: "group", label: "\u5206\u7EC4", icon: "layers", accent: "violet" },
@@ -82155,7 +83228,7 @@ function Report({ session, summary, sourceLabel }) {
82155
83228
  const visiblePills = PILL_ORDER.filter((key2) => counts[key2] > 0);
82156
83229
  const title = reportTitle(session);
82157
83230
  const sessionStart = session.startedAt;
82158
- const showFallbackWarning = sourceLabel && sourceLabel !== "events.jsonl";
83231
+ const sourceWarning = lossySourceWarning(session.source) ?? sourceLabelWarning(sourceLabel);
82159
83232
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("html", { lang: "en", className: "dark", children: [
82160
83233
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("head", { children: [
82161
83234
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { charSet: "utf-8" }),
@@ -82186,9 +83259,9 @@ ${css}` } })
82186
83259
  session.entries.length,
82187
83260
  " entries"
82188
83261
  ] }),
82189
- showFallbackWarning && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "fallback-warning", title: "Data source is not the canonical events.jsonl", children: [
83262
+ sourceWarning && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "fallback-warning", title: "\u8BE5\u6570\u636E\u6E90\u5B58\u5728\u5DF2\u77E5\u7684\u4FDD\u771F\u9650\u5236", children: [
82190
83263
  "\u26A0 ",
82191
- LOSSY_SOURCE_WARNING
83264
+ sourceWarning
82192
83265
  ] })
82193
83266
  ] })
82194
83267
  ] }),
@@ -82201,7 +83274,7 @@ ${css}` } })
82201
83274
  const def = PILL_DEFS[key2];
82202
83275
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", className: `filter accent-${def.accent}`, "data-filter": key2, "aria-pressed": "true", children: [
82203
83276
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon, { name: def.icon }),
82204
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: def.label }),
83277
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: pillLabel(key2, session.agent) }),
82205
83278
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("small", { children: counts[key2] })
82206
83279
  ] }, key2);
82207
83280
  }) }),
@@ -82240,14 +83313,14 @@ ${css}` } })
82240
83313
  "#",
82241
83314
  entry.index + 1
82242
83315
  ] }),
82243
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: PILL_DEFS[key2].label }),
83316
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: pillLabel(key2, session.agent) }),
82244
83317
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("em", { children: text9 })
82245
83318
  ] }, entry.index);
82246
83319
  })
82247
83320
  ] }) }),
82248
83321
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("main", { children: [
82249
83322
  summary && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SummaryCard, { html: summary }),
82250
- session.entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Entry, { entry, sessionStart }, entry.index)),
83323
+ session.entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Entry, { entry, sessionStart, agent: session.agent }, entry.index)),
82251
83324
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("footer", { children: [
82252
83325
  "Generated by ",
82253
83326
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "agent-session-manager" }),
@@ -82259,11 +83332,13 @@ ${css}` } })
82259
83332
  ] })
82260
83333
  ] });
82261
83334
  }
82262
- function Entry({ entry, sessionStart }) {
83335
+ function Entry({ entry, sessionStart, agent }) {
82263
83336
  if (entry.role === "tool") return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ToolCard, { entry, sessionStart });
82264
83337
  if (entry.role === "event") return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EventCard, { entry, sessionStart });
82265
83338
  if (entry.role === "user") return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SimpleEntry, { entry, isMarkdown: false, icon: "user", sessionStart });
82266
- if (entry.role === "assistant") return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SimpleEntry, { entry, isMarkdown: true, icon: "bot", sessionStart });
83339
+ if (entry.role === "assistant") {
83340
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SimpleEntry, { entry, isMarkdown: true, icon: "bot", sessionStart, label: assistantLabel(agent) });
83341
+ }
82267
83342
  if (entry.role === "reasoning") return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SimpleEntry, { entry, isMarkdown: false, icon: "brain", sessionStart });
82268
83343
  if (entry.role === "system") return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SimpleEntry, { entry, isMarkdown: false, icon: "info", sessionStart });
82269
83344
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SimpleEntry, { entry, isMarkdown: false, icon: "info", sessionStart });
@@ -82274,7 +83349,7 @@ function defaultOpen(entry) {
82274
83349
  if (entry.role === "event" && (entry.kind === "error" || entry.kind === "task_complete")) return true;
82275
83350
  return false;
82276
83351
  }
82277
- function SimpleEntry({ entry, isMarkdown, icon: iconName, sessionStart }) {
83352
+ function SimpleEntry({ entry, isMarkdown, icon: iconName, sessionStart, label }) {
82278
83353
  const key2 = entryFilterKey(entry);
82279
83354
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("details", { ...entryAttrs(entry, key2), open: defaultOpen(entry), children: [
82280
83355
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("summary", { children: [
@@ -82284,7 +83359,7 @@ function SimpleEntry({ entry, isMarkdown, icon: iconName, sessionStart }) {
82284
83359
  entry.index + 1
82285
83360
  ] }),
82286
83361
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon, { name: iconName }),
82287
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "role", children: PILL_DEFS[key2].label }),
83362
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "role", children: label ?? PILL_DEFS[key2].label }),
82288
83363
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "snippet", children: firstLine(entry.text) }),
82289
83364
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TimestampLink, { entry, sessionStart })
82290
83365
  ] }),
@@ -82712,8 +83787,22 @@ function resultIcon(kind) {
82712
83787
  if (kind === "failure") return "x";
82713
83788
  if (kind === "rejected") return "ban";
82714
83789
  if (kind === "denied") return "triangle-alert";
83790
+ if (kind === "redacted") return "circle-dashed";
82715
83791
  return "hourglass";
82716
83792
  }
83793
+ function assistantLabel(agent) {
83794
+ if (agent === "copilot") return "Copilot";
83795
+ if (agent === "claude") return "Claude";
83796
+ if (agent === "codex") return "Codex";
83797
+ return "ChatGPT";
83798
+ }
83799
+ function pillLabel(key2, agent) {
83800
+ return key2 === "assistant" ? assistantLabel(agent) : PILL_DEFS[key2].label;
83801
+ }
83802
+ function sourceLabelWarning(sourceLabel) {
83803
+ if (!sourceLabel || sourceLabel === "events.jsonl") return void 0;
83804
+ return sourceLabel === "db.turns (fallback)" ? LOSSY_SOURCE_WARNING : sourceLabel;
83805
+ }
82717
83806
  function isDiff(text9) {
82718
83807
  return text9.includes("diff --git") || text9.includes("@@") && (text9.includes("+++") || text9.includes("---"));
82719
83808
  }
@@ -82725,7 +83814,7 @@ function Markdown2({ text: text9 }) {
82725
83814
  Markdown,
82726
83815
  {
82727
83816
  remarkPlugins: [remarkGfm, remarkMath],
82728
- rehypePlugins: [rehypeKatex],
83817
+ rehypePlugins: [[rehypeKatex, { strict: false, throwOnError: false }]],
82729
83818
  components: {
82730
83819
  pre: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children }),
82731
83820
  code({ className, children, ...props }) {
@@ -83120,6 +84209,7 @@ main { min-width:0; }
83120
84209
  .entry.tool.tool-rejected { border-left-color:var(--gray); }
83121
84210
  .entry.tool.tool-denied { border-left-color:var(--amber); }
83122
84211
  .entry.tool.tool-pending { border-left-color:var(--blue); }
84212
+ .entry.tool.tool-redacted { border-left-color:var(--gray); }
83123
84213
  .entry.group { border-left-color:var(--violet); }
83124
84214
  .entry.notification { border-left-color:var(--sky); }
83125
84215
  .entry.handoff { border-left-color:var(--sky); }
@@ -83151,6 +84241,7 @@ main { min-width:0; }
83151
84241
  .tool-status.status-rejected { color:var(--gray); }
83152
84242
  .tool-status.status-denied { color:var(--amber); }
83153
84243
  .tool-status.status-pending { color:var(--blue); }
84244
+ .tool-status.status-redacted { color:var(--gray); }
83154
84245
  .tool-args { color:var(--muted); font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size:12px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:520px; }
83155
84246
  .snippet { min-width:0; flex:1; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; color:var(--muted); font-size:13px; }
83156
84247
  time { color:var(--muted); font-size:12px; }
@@ -83218,7 +84309,9 @@ function parseSummaryFormat(value) {
83218
84309
  function sourceLabelForSession(session) {
83219
84310
  const source = session.source;
83220
84311
  if (!source || !source.lossy && source.kind !== "db-turns") return void 0;
83221
- return "db.turns (fallback)";
84312
+ if (source.kind === "db-turns") return "db.turns (fallback)";
84313
+ if (source.kind === "chatgpt-share") return "ChatGPT \u5206\u4EAB";
84314
+ return `${source.kind} (lossy)`;
83222
84315
  }
83223
84316
  function summaryMismatchWarning(summaryPath, declaredFormat, requiredFormat) {
83224
84317
  if (typeof summaryPath !== "string" || !summaryPath) return void 0;
@@ -83233,7 +84326,7 @@ function summaryMismatchWarning(summaryPath, declaredFormat, requiredFormat) {
83233
84326
 
83234
84327
  // src/cli/commands/html.ts
83235
84328
  function buildHtmlCommand() {
83236
- const cmd = new Command("html").argument("[session-id]", "session id (optional when --file points at a single file)").description("Generate a single-file HTML report");
84329
+ const cmd = new Command("html").argument("[session-id-or-url]", "\u4F1A\u8BDD ID \u6216 ChatGPT \u516C\u5F00\u5206\u4EAB\u94FE\u63A5\uFF08--file \u53EA\u6709\u4E00\u4E2A\u4F1A\u8BDD\u65F6\u53EF\u7701\u7565\uFF09").description("Generate a single-file HTML report");
83237
84330
  withAgent(cmd).option("-o, --out <path>", "output file", "session.html").option("-s, --summary <path>", "inject a raw HTML fragment at the top of the report").option("--summary-format <html|markdown>", "declare the summary fragment format (no conversion)", parseSummaryFormat, "html");
83238
84331
  withSource(cmd, "read an explicit session file/directory instead of the live agent homes");
83239
84332
  withRoots(cmd);
@@ -83266,9 +84359,10 @@ function renderSessionMarkdown(session, opts = {}) {
83266
84359
  const duration = formatDuration(Math.max(0, Math.floor((exportedAt.getTime() - start2.getTime()) / 1e3)));
83267
84360
  const agentTitle = agentDisplay(session.agent);
83268
84361
  const visible = session.entries.filter((entry) => includeReasoning || entry.role !== "reasoning");
83269
- const sourceNote = opts.sourceLabel && opts.sourceLabel !== "events.jsonl" ? `
84362
+ const sourceWarning = lossySourceWarning(session.source) ?? sourceLabelWarning2(opts.sourceLabel);
84363
+ const sourceNote = sourceWarning ? `
83270
84364
  > [!WARNING]
83271
- > ${LOSSY_SOURCE_WARNING}
84365
+ > ${sourceWarning}
83272
84366
  ` : "";
83273
84367
  const header = `# ${agentTitle}
83274
84368
 
@@ -83293,7 +84387,7 @@ function renderSessionMarkdown(session, opts = {}) {
83293
84387
  const prefix = elapsed ? `<sub>\u23F1\uFE0F ${elapsed}</sub>
83294
84388
 
83295
84389
  ` : "";
83296
- return prefix + renderEntry(entry);
84390
+ return prefix + renderEntry(entry, session.agent);
83297
84391
  }).join("\n---\n\n");
83298
84392
  const footer2 = opts.footer === "" ? "" : `
83299
84393
  ---
@@ -83306,12 +84400,13 @@ function agentDisplay(agent) {
83306
84400
  if (agent === "copilot") return "\u{1F916} Copilot CLI Session";
83307
84401
  if (agent === "claude") return "\u{1F300} Claude Code Session";
83308
84402
  if (agent === "codex") return "\u{1F300} Codex CLI Session";
84403
+ if (agent === "chatgpt") return "\u{1F300} ChatGPT \u5206\u4EAB\u4F1A\u8BDD";
83309
84404
  return `\u{1F300} ${agent} Session`;
83310
84405
  }
83311
- function renderEntry(entry) {
84406
+ function renderEntry(entry, agent) {
83312
84407
  if (entry.role === "tool" && entry.tool) return renderTool(entry.tool);
83313
84408
  if (entry.role === "user") return heading3("\u{1F464} User", entry.text);
83314
- if (entry.role === "assistant") return heading3("\u{1F4AC} Copilot", entry.text);
84409
+ if (entry.role === "assistant") return heading3(`\u{1F4AC} ${assistantLabel2(agent)}`, entry.text);
83315
84410
  if (entry.role === "reasoning") return heading3("\u{1F4AD} Reasoning", `*${escapeMd(entry.text)}*`, { escape: false });
83316
84411
  if (entry.role === "system") return heading3("\u2139\uFE0F System", entry.text);
83317
84412
  if (entry.role === "event") {
@@ -83473,15 +84568,26 @@ ${tail}
83473
84568
  return out;
83474
84569
  }
83475
84570
  function hasResultBody(kind) {
83476
- return kind === "success" || kind === "failure" || kind === "denied";
84571
+ return kind === "success" || kind === "failure" || kind === "denied" || kind === "redacted";
83477
84572
  }
83478
84573
  function resultEmoji(kind) {
83479
84574
  if (kind === "success") return "\u2705";
83480
84575
  if (kind === "failure") return "\u274C";
83481
84576
  if (kind === "rejected") return "\u{1F6AB}";
83482
84577
  if (kind === "denied") return "\u26D4";
84578
+ if (kind === "redacted") return "\u{1F512}";
83483
84579
  return "\u{1F527}";
83484
84580
  }
84581
+ function assistantLabel2(agent) {
84582
+ if (agent === "copilot") return "Copilot";
84583
+ if (agent === "claude") return "Claude";
84584
+ if (agent === "codex") return "Codex";
84585
+ return "ChatGPT";
84586
+ }
84587
+ function sourceLabelWarning2(sourceLabel) {
84588
+ if (!sourceLabel || sourceLabel === "events.jsonl") return void 0;
84589
+ return sourceLabel === "db.turns (fallback)" ? LOSSY_SOURCE_WARNING : sourceLabel;
84590
+ }
83485
84591
  function renderToolArgs(name2, args) {
83486
84592
  const compact = toolArgSummary(name2, args);
83487
84593
  if (compact) return `\`${compact}\``;
@@ -83593,7 +84699,7 @@ function formatMilliseconds(milliseconds) {
83593
84699
 
83594
84700
  // src/cli/commands/md.ts
83595
84701
  function buildMdCommand() {
83596
- const cmd = new Command("md").alias("markdown").argument("[session-id]", "session id (optional when --file points at a single file)").description("Export the session as a Markdown file (replicates Copilot CLI /share file)");
84702
+ const cmd = new Command("md").alias("markdown").argument("[session-id-or-url]", "\u4F1A\u8BDD ID \u6216 ChatGPT \u516C\u5F00\u5206\u4EAB\u94FE\u63A5\uFF08--file \u53EA\u6709\u4E00\u4E2A\u4F1A\u8BDD\u65F6\u53EF\u7701\u7565\uFF09").description("Export the session as a Markdown file (replicates Copilot CLI /share file)");
83597
84703
  withAgent(cmd).option("-o, --out <path>", "output file (default: stdout)").option("-s, --summary <path>", "inject a Markdown fragment after the header note").option("--summary-format <html|markdown>", "declare the summary fragment format (no conversion)", parseSummaryFormat, "markdown").option("--no-reasoning", "drop reasoning entries (default: include)");
83598
84704
  withSource(cmd, "read an explicit session file/directory instead of the live agent homes");
83599
84705
  withRoots(cmd);
@@ -83664,26 +84770,31 @@ import { existsSync as existsSync3 } from "node:fs";
83664
84770
  import { resolve as resolve8 } from "node:path";
83665
84771
 
83666
84772
  // src/cli/commands/backup/cache-target.ts
83667
- import { homedir as homedir2 } from "node:os";
83668
- import { join as join3, resolve as resolve7, sep } from "node:path";
84773
+ import { homedir as homedir3 } from "node:os";
84774
+ import { join as join4, resolve as resolve7, sep } from "node:path";
83669
84775
  function expandHome2(path3) {
83670
- if (path3 === "~") return homedir2();
83671
- if (path3.startsWith("~/")) return join3(homedir2(), path3.slice(2));
84776
+ if (path3 === "~") return homedir3();
84777
+ if (path3.startsWith("~/")) return join4(homedir3(), path3.slice(2));
83672
84778
  return path3;
83673
84779
  }
83674
84780
  function defaultCacheDir() {
83675
- return join3(homedir2(), ".cache", BIN_NAME, "restic-cache");
84781
+ return join4(homedir3(), ".cache", BIN_NAME, "restic-cache");
83676
84782
  }
83677
84783
  function assertSafeCacheTarget(target) {
83678
84784
  const resolved = resolve7(expandHome2(target));
83679
- const home = homedir2();
84785
+ const home = homedir3();
83680
84786
  if (resolved === home) {
83681
84787
  throw new Error(`refusing to restore into the home directory (${home}); choose a dedicated --target`);
83682
84788
  }
83683
- for (const name2 of [".copilot", ".claude", ".codex"]) {
83684
- const forbidden = join3(home, name2);
84789
+ const forbiddenRoots = [
84790
+ join4(home, ".copilot"),
84791
+ join4(home, ".claude"),
84792
+ join4(home, ".codex"),
84793
+ resolve7(chatGptRoot())
84794
+ ];
84795
+ for (const forbidden of forbiddenRoots) {
83685
84796
  if (resolved === forbidden || resolved.startsWith(forbidden + sep)) {
83686
- throw new Error(`refusing to restore into a live agent home (${forbidden}); choose a --target outside it`);
84797
+ throw new Error(`refusing to restore into a live or managed session directory (${forbidden}); choose a dedicated --target`);
83687
84798
  }
83688
84799
  }
83689
84800
  return resolved;
@@ -83719,15 +84830,62 @@ function buildBackupCommand() {
83719
84830
  return cmd;
83720
84831
  }
83721
84832
 
84833
+ // src/cli/commands/import.ts
84834
+ import { access, chmod, mkdir as mkdir4, writeFile as writeFile4 } from "node:fs/promises";
84835
+ import { dirname as dirname8, resolve as resolve9 } from "node:path";
84836
+ function buildImportCommand() {
84837
+ const cmd = new Command("import").argument("<url>", "ChatGPT \u516C\u5F00\u5206\u4EAB\u94FE\u63A5").description("\u628A ChatGPT \u516C\u5F00\u5206\u4EAB\u5BFC\u5165\u672C\u5730 asmgr \u5F52\u6863").option("-o, --out <path>", "\u6307\u5B9A\u5FEB\u7167\u8F93\u51FA\u8DEF\u5F84").option("--chatgpt-root <path>", "\u8986\u76D6 ChatGPT \u5BFC\u5165\u6587\u4EF6\u7684\u6258\u7BA1\u76EE\u5F55").option("--force", "\u8986\u76D6\u5DF2\u7ECF\u5B58\u5728\u7684\u5FEB\u7167");
84838
+ cmd.action(async (url, opts) => {
84839
+ const sourceUrl = String(url);
84840
+ const id = chatGptConversationId(sourceUrl);
84841
+ const out = opts.out ? resolve9(String(opts.out)) : chatGptSnapshotPath(id, typeof opts.chatgptRoot === "string" ? opts.chatgptRoot : void 0);
84842
+ if (!opts.force && await fileExists(out)) {
84843
+ throw new Error(`\u8F93\u51FA\u6587\u4EF6\u5DF2\u5B58\u5728\uFF1A${out}\uFF08\u5982\u9700\u8986\u76D6\uFF0C\u8BF7\u52A0 --force\uFF09`);
84844
+ }
84845
+ const snapshot = await captureChatGptShare(sourceUrl);
84846
+ await mkdir4(dirname8(out), { recursive: true });
84847
+ try {
84848
+ await writeFile4(out, `${JSON.stringify(snapshot, null, 2)}
84849
+ `, {
84850
+ encoding: "utf8",
84851
+ mode: 384,
84852
+ flag: opts.force ? "w" : "wx"
84853
+ });
84854
+ } catch (error) {
84855
+ if (isAlreadyExists(error)) {
84856
+ throw new Error(`\u8F93\u51FA\u6587\u4EF6\u5DF2\u5B58\u5728\uFF1A${out}\uFF08\u5982\u9700\u8986\u76D6\uFF0C\u8BF7\u52A0 --force\uFF09`);
84857
+ }
84858
+ throw error;
84859
+ }
84860
+ await chmod(out, 384);
84861
+ console.log(out);
84862
+ });
84863
+ return cmd;
84864
+ }
84865
+ async function fileExists(path3) {
84866
+ try {
84867
+ await access(path3);
84868
+ return true;
84869
+ } catch {
84870
+ return false;
84871
+ }
84872
+ }
84873
+ function isAlreadyExists(error) {
84874
+ return Boolean(
84875
+ error && typeof error === "object" && "code" in error && error.code === "EEXIST"
84876
+ );
84877
+ }
84878
+
83722
84879
  // src/cli/program.ts
83723
84880
  function buildProgram() {
83724
84881
  const program2 = new Command();
83725
- program2.name(BIN_NAME).description("Search and render local coding-agent session histories").version(VERSION);
84882
+ program2.name(BIN_NAME).description("Search and render coding-agent sessions and public ChatGPT shares").version(VERSION);
83726
84883
  program2.addCommand(buildListCommand());
83727
84884
  program2.addCommand(buildSearchCommand());
83728
84885
  program2.addCommand(buildShowCommand());
83729
84886
  program2.addCommand(buildHtmlCommand());
83730
84887
  program2.addCommand(buildMdCommand());
84888
+ program2.addCommand(buildImportCommand());
83731
84889
  program2.addCommand(buildBackupCommand());
83732
84890
  return program2;
83733
84891
  }