@appthen/cli 1.2.10 → 1.2.11

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 (122) hide show
  1. package/.gitignore +1 -0
  2. package/bin/main.js +45 -0
  3. package/dist/index.js +1108 -267
  4. package/package.json +1 -1
  5. package/tests/test-app/.appthen/shadow-space-100001-test-app-e99876b1.json +1406 -0
  6. package/tests/test-app/.appthen/shadow-space-unknown-user-test-app-e99876b1.json +1060 -0
  7. package/tests/test-app/.appthen/space-config.json +8 -0
  8. package/tests/test-app/docs/AI-Workflow.flow +112 -0
  9. package/tests/test-app/docs/Logic-1.flow +16 -0
  10. package/tests/test-app/docs/Logic.flow +16 -0
  11. package/tests/test-app/docs/Project-Blueprint-1.flow +119 -0
  12. package/tests/test-app/docs/Project-Blueprint.flow +119 -0
  13. package/tests/test-app/docs/README.md +3 -0
  14. package/tests/test-app/docs/claude.md +194 -0
  15. package/tests/test-app/docs/page_requirement_analysis.md +149 -0
  16. package/tests/test-app/docs//345/267/245/345/215/225/347/256/241/347/220/206/347/263/273/347/273/237/350/257/246/347/273/206/350/256/276/350/256/241.md +377 -0
  17. package/tests/test-app/src/apis/AddTodoPost.api.ts +42 -0
  18. package/tests/test-app/src/apis/DeleteTodoPost.api.ts +32 -0
  19. package/tests/test-app/src/apis/GetListPost.api.ts +38 -0
  20. package/tests/test-app/src/apis/TicketAttachmentUploadPost.api.ts +42 -0
  21. package/tests/test-app/src/apis/UpdateTodoPost.api.ts +46 -0
  22. package/tests/test-app/src/app.css +15 -0
  23. package/tests/test-app/src/cloud_functions/ticket|attachment|upload.node.ts +86 -0
  24. package/tests/test-app/src/cloud_functions/ticket|comment|add.node.ts +65 -0
  25. package/tests/test-app/src/cloud_functions/types|entity|Ticket.node.ts +88 -0
  26. package/tests/test-app/src/cloud_functions/types|entity|TicketAttachment.node.ts +70 -0
  27. package/tests/test-app/src/cloud_functions/types|entity|TicketCategory.node.ts +56 -0
  28. package/tests/test-app/src/cloud_functions/types|entity|TicketComment.node.ts +62 -0
  29. package/tests/test-app/src/cloud_functions/types|entity|TicketHistory.node.ts +74 -0
  30. package/tests/test-app/src/cloud_functions/types|entity|TicketPriority.node.ts +68 -0
  31. package/tests/test-app/src/cloud_functions/types|entity|TicketStatus.node.ts +63 -0
  32. package/tests/test-app/src/cloud_functions/types|models|CreateTicketParams.node.ts +20 -0
  33. package/tests/test-app/src/cloud_functions/types|models|TicketListParams.node.ts +30 -0
  34. package/tests/test-app/src/cloud_functions/types|models|UpdateTicketParams.node.ts +22 -0
  35. package/tests/test-app/src/components/Button.js +11 -0
  36. package/tests/test-app/src/components/MouduleDemoNzp.tsx +40 -0
  37. package/tests/test-app/src/components/Timeline.tsx +145 -0
  38. package/tests/test-app/src/index.ts +2 -0
  39. package/tests/test-app/src/modules/work_order_module/apis/TicketCommentAddPost.api.ts +48 -0
  40. package/tests/test-app/src/modules/work_order_module/apis/TicketCreatePost.api.ts +52 -0
  41. package/tests/test-app/src/modules/work_order_module/apis/TicketDeleteDelete.api.ts +39 -0
  42. package/tests/test-app/src/modules/work_order_module/apis/TicketDetailGet.api.ts +39 -0
  43. package/tests/test-app/src/modules/work_order_module/apis/TicketListGet.api.ts +61 -0
  44. package/tests/test-app/src/modules/work_order_module/apis/TicketUpdatePut.api.ts +57 -0
  45. package/tests/test-app/src/modules/work_order_module/apis/TrainDoorFaultListGet.ts +76 -0
  46. package/tests/test-app/src/modules/work_order_module/apis/TrainDoorListGet.ts +76 -0
  47. package/tests/test-app/src/modules/work_order_module/apis/TrainDoorOperationRecordsGet.ts +284 -0
  48. package/tests/test-app/src/modules/work_order_module/apis/TrainDoorStatisticsGet.ts +96 -0
  49. package/tests/test-app/src/modules/work_order_module/cloud_function/category|list.node.ts +40 -0
  50. package/tests/test-app/src/modules/work_order_module/cloud_function/priority|list.node.ts +26 -0
  51. package/tests/test-app/src/modules/work_order_module/cloud_function/status|list.node.ts +26 -0
  52. package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|create.node.ts +54 -0
  53. package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|delete.node.ts +55 -0
  54. package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|detail.node.ts +65 -0
  55. package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|list.node.ts +85 -0
  56. package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|update.node.ts +73 -0
  57. package/tests/test-app/src/modules/work_order_module/data_model/Ticket.m.ts +85 -0
  58. package/tests/test-app/src/modules/work_order_module/data_model/TicketCategory.m.ts +53 -0
  59. package/tests/test-app/src/modules/work_order_module/data_model/TicketStatus.m.ts +60 -0
  60. package/tests/test-app/src/modules/work_order_module//345/267/245/345/215/225/347/263/273/347/273/237/344/272/247/345/223/201/350/256/276/350/256/241/346/226/207/346/241/243.md +301 -0
  61. package/tests/test-app/src/modules/work_order_module//345/267/245/345/215/225/347/263/273/347/273/237/345/274/200/345/217/221/344/273/273/345/212/241/345/210/206/345/267/245/346/226/207/346/241/243.md +345 -0
  62. package/tests/test-app/src/pages/SLAManagement.tsx +668 -0
  63. package/tests/test-app/src/pages/TicketCreate.tsx +27 -0
  64. package/tests/test-app/src/pages/TicketDetail.tsx +27 -0
  65. package/tests/test-app/src/pages/TicketList.tsx +27 -0
  66. package/tests/test-app/src/pages/TicketManagementPage.tsx +1238 -0
  67. package/tests/test-app/src/pages/VisualAIIDEUpgrade.tsx +245 -0
  68. package/tests/test-app/src/pages/appthen_guide/ComponentTreeUnderstanding.tsx +26 -0
  69. package/tests/test-app/src/pages/appthen_guide/DataBindingLearning.tsx +26 -0
  70. package/tests/test-app/src/pages/back-end/adminRootLayout.tsx +155 -0
  71. package/tests/test-app/src/pages/back-end/adminRootLayout10.tsx +157 -0
  72. package/tests/test-app/src/pages/back-end/adminRootLayout2.tsx +156 -0
  73. package/tests/test-app/src/pages/back-end/adminRootLayout3.tsx +156 -0
  74. package/tests/test-app/src/pages/back-end/adminRootLayout4.tsx +157 -0
  75. package/tests/test-app/src/pages/back-end/adminRootLayout5.tsx +157 -0
  76. package/tests/test-app/src/pages/back-end/adminRootLayout6.tsx +157 -0
  77. package/tests/test-app/src/pages/back-end/adminRootLayout7.tsx +157 -0
  78. package/tests/test-app/src/pages/back-end/adminRootLayout8.tsx +157 -0
  79. package/tests/test-app/src/pages/back-end/adminRootLayout9.tsx +157 -0
  80. package/tests/test-app/src/pages/back-end/backgroundManagementSystem.css +5 -0
  81. package/tests/test-app/src/pages/back-end/backgroundManagementSystem.tsx +1745 -0
  82. package/tests/test-app/src/pages/component/WorkOrderCard.tsx +140 -0
  83. package/tests/test-app/src/pages/cover.tsx +42 -0
  84. package/tests/test-app/src/pages/data_dashboard/blueBrightGreenTechnologyWind.css +181 -0
  85. package/tests/test-app/src/pages/data_dashboard/blueBrightGreenTechnologyWind.tsx +225 -0
  86. package/tests/test-app/src/pages/data_dashboard/blueLargeScreen.css +181 -0
  87. package/tests/test-app/src/pages/data_dashboard/blueLargeScreen.tsx +138 -0
  88. package/tests/test-app/src/pages/data_dashboard/component_library/BlueBrightGreenBorder.tsx +47 -0
  89. package/tests/test-app/src/pages/data_dashboard/component_library/FullScreenContainer.tsx +133 -0
  90. package/tests/test-app/src/pages/description_of_mock_interface.md +32 -0
  91. package/tests/test-app/src/pages/digitalLargeScreen.css +181 -0
  92. package/tests/test-app/src/pages/digitalLargeScreen.tsx +1417 -0
  93. package/tests/test-app/src/pages/mobile_terminal/PersonalCenter.css +3 -0
  94. package/tests/test-app/src/pages/mobile_terminal/PersonalCenter.tsx +362 -0
  95. package/tests/test-app/src/pages/mobile_terminal/WorkOrderHomepage.tsx +337 -0
  96. package/tests/test-app/src/pages/mobile_terminal/newWorkOrder.tsx +224 -0
  97. package/tests/test-app/src/pages/mobile_terminal/tabbar.tsx +67 -0
  98. package/tests/test-app/src/pages/mobile_terminal/uiHandsOnPractice.tsx +638 -0
  99. package/tests/test-app/src/pages/mobile_terminal/workOrderDetails.tsx +346 -0
  100. package/tests/test-app/src/pages/mobile_terminal/workOrderPage.tsx +345 -0
  101. package/tests/test-app/src/pages/testPage.css +3 -0
  102. package/tests/test-app/src/pages/testPage.tsx +158 -0
  103. package/tests/test-app/src/pages/web_version/website.css +205 -0
  104. package/tests/test-app/src/pages/web_version/website.tsx +1066 -0
  105. package/tests/test-app/src/pages//345/276/205/345/212/236.apidoc.json +336 -0
  106. package/tests/test-app/src/project.json +1120 -0
  107. package/tests/test-app/src/store/global.store.ts +10 -0
  108. package/tests/test-app/src/types/CreateTicketParams.m.ts +20 -0
  109. package/tests/test-app/src/types/SLAPolicy.ts +50 -0
  110. package/tests/test-app/src/types/Ticket.ts +68 -0
  111. package/tests/test-app/src/types/TicketAttachment.m.ts +67 -0
  112. package/tests/test-app/src/types/TicketComment.m.ts +59 -0
  113. package/tests/test-app/src/types/TicketEvaluation.ts +44 -0
  114. package/tests/test-app/src/types/TicketHistory.m.ts +71 -0
  115. package/tests/test-app/src/types/TicketListParams.m.ts +30 -0
  116. package/tests/test-app/src/types/TicketPriority.m.ts +65 -0
  117. package/tests/test-app/src/types/TicketRecord.ts +47 -0
  118. package/tests/test-app/src/types/TrainDoor.ts +284 -0
  119. package/tests/test-app/src/types/UpdateTicketParams.m.ts +22 -0
  120. package/tests/test-app/src/utils/__afterRequest.util.ts +3 -0
  121. package/tests/test-app/src/utils/__beforeRequest.util.ts +10 -0
  122. package/tests/test-app/src/utils/testGlobalAction.util.ts +7 -0
package/dist/index.js CHANGED
@@ -29,6 +29,7 @@ var prettier = require('prettier');
29
29
  var fs$2 = require('fs-extra');
30
30
  var io = require('socket.io-client');
31
31
  var fs$3 = require('fs/promises');
32
+ var chokidar = require('chokidar');
32
33
  var whatwgUrl = require('whatwg-url');
33
34
 
34
35
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -80,6 +81,7 @@ var fs__default$1 = /*#__PURE__*/_interopDefaultLegacy(fs$2);
80
81
  var fs__namespace$1 = /*#__PURE__*/_interopNamespace(fs$2);
81
82
  var io__default = /*#__PURE__*/_interopDefaultLegacy(io);
82
83
  var fs__default$2 = /*#__PURE__*/_interopDefaultLegacy(fs$3);
84
+ var chokidar__default = /*#__PURE__*/_interopDefaultLegacy(chokidar);
83
85
  var whatwgUrl__default = /*#__PURE__*/_interopDefaultLegacy(whatwgUrl);
84
86
 
85
87
  /******************************************************************************
@@ -2803,36 +2805,29 @@ browser$1.destroy;
2803
2805
  browser$1.colors;
2804
2806
  browser$1.log;
2805
2807
 
2806
- var hasFlag = (flag, argv = process.argv) => {
2808
+ var hasFlag = (flag, argv) => {
2809
+ argv = argv || process.argv;
2807
2810
  const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
2808
- const position = argv.indexOf(prefix + flag);
2809
- const terminatorPosition = argv.indexOf('--');
2810
- return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
2811
+ const pos = argv.indexOf(prefix + flag);
2812
+ const terminatorPos = argv.indexOf('--');
2813
+ return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos);
2811
2814
  };
2812
2815
 
2813
- const {env} = process;
2816
+ const env = process.env;
2814
2817
 
2815
2818
  let forceColor;
2816
2819
  if (hasFlag('no-color') ||
2817
2820
  hasFlag('no-colors') ||
2818
- hasFlag('color=false') ||
2819
- hasFlag('color=never')) {
2820
- forceColor = 0;
2821
+ hasFlag('color=false')) {
2822
+ forceColor = false;
2821
2823
  } else if (hasFlag('color') ||
2822
2824
  hasFlag('colors') ||
2823
2825
  hasFlag('color=true') ||
2824
2826
  hasFlag('color=always')) {
2825
- forceColor = 1;
2827
+ forceColor = true;
2826
2828
  }
2827
-
2828
2829
  if ('FORCE_COLOR' in env) {
2829
- if (env.FORCE_COLOR === 'true') {
2830
- forceColor = 1;
2831
- } else if (env.FORCE_COLOR === 'false') {
2832
- forceColor = 0;
2833
- } else {
2834
- forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);
2835
- }
2830
+ forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0;
2836
2831
  }
2837
2832
 
2838
2833
  function translateLevel(level) {
@@ -2848,8 +2843,8 @@ function translateLevel(level) {
2848
2843
  };
2849
2844
  }
2850
2845
 
2851
- function supportsColor(haveStream, streamIsTTY) {
2852
- if (forceColor === 0) {
2846
+ function supportsColor(stream) {
2847
+ if (forceColor === false) {
2853
2848
  return 0;
2854
2849
  }
2855
2850
 
@@ -2863,21 +2858,22 @@ function supportsColor(haveStream, streamIsTTY) {
2863
2858
  return 2;
2864
2859
  }
2865
2860
 
2866
- if (haveStream && !streamIsTTY && forceColor === undefined) {
2861
+ if (stream && !stream.isTTY && forceColor !== true) {
2867
2862
  return 0;
2868
2863
  }
2869
2864
 
2870
- const min = forceColor || 0;
2871
-
2872
- if (env.TERM === 'dumb') {
2873
- return min;
2874
- }
2865
+ const min = forceColor ? 1 : 0;
2875
2866
 
2876
2867
  if (process.platform === 'win32') {
2877
- // Windows 10 build 10586 is the first Windows release that supports 256 colors.
2878
- // Windows 10 build 14931 is the first release that supports 16m/TrueColor.
2868
+ // Node.js 7.5.0 is the first version of Node.js to include a patch to
2869
+ // libuv that enables 256 color output on Windows. Anything earlier and it
2870
+ // won't work. However, here we target Node.js 8 at minimum as it is an LTS
2871
+ // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows
2872
+ // release that supports 256 colors. Windows 10 build 14931 is the first release
2873
+ // that supports 16m/TrueColor.
2879
2874
  const osRelease = os__default["default"].release().split('.');
2880
2875
  if (
2876
+ Number(process.versions.node.split('.')[0]) >= 8 &&
2881
2877
  Number(osRelease[0]) >= 10 &&
2882
2878
  Number(osRelease[2]) >= 10586
2883
2879
  ) {
@@ -2888,7 +2884,7 @@ function supportsColor(haveStream, streamIsTTY) {
2888
2884
  }
2889
2885
 
2890
2886
  if ('CI' in env) {
2891
- if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
2887
+ if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
2892
2888
  return 1;
2893
2889
  }
2894
2890
 
@@ -2927,18 +2923,22 @@ function supportsColor(haveStream, streamIsTTY) {
2927
2923
  return 1;
2928
2924
  }
2929
2925
 
2926
+ if (env.TERM === 'dumb') {
2927
+ return min;
2928
+ }
2929
+
2930
2930
  return min;
2931
2931
  }
2932
2932
 
2933
2933
  function getSupportLevel(stream) {
2934
- const level = supportsColor(stream, stream && stream.isTTY);
2934
+ const level = supportsColor(stream);
2935
2935
  return translateLevel(level);
2936
2936
  }
2937
2937
 
2938
2938
  var supportsColor_1 = {
2939
2939
  supportsColor: getSupportLevel,
2940
- stdout: translateLevel(supportsColor(true, tty__default["default"].isatty(1))),
2941
- stderr: translateLevel(supportsColor(true, tty__default["default"].isatty(2)))
2940
+ stdout: getSupportLevel(process.stdout),
2941
+ stderr: getSupportLevel(process.stderr)
2942
2942
  };
2943
2943
  supportsColor_1.supportsColor;
2944
2944
  supportsColor_1.stdout;
@@ -17179,7 +17179,7 @@ FormData$2.prototype.submit = function (params, cb) {
17179
17179
  request.removeListener('error', callback);
17180
17180
  request.removeListener('response', onResponse);
17181
17181
 
17182
- return cb.call(this, error, responce); // eslint-disable-line no-invalid-this
17182
+ return cb.call(this, error, responce);
17183
17183
  };
17184
17184
 
17185
17185
  onResponse = callback.bind(this, null);
@@ -17203,7 +17203,7 @@ FormData$2.prototype._error = function (err) {
17203
17203
  FormData$2.prototype.toString = function () {
17204
17204
  return '[object FormData]';
17205
17205
  };
17206
- setToStringTag(FormData$2, 'FormData');
17206
+ setToStringTag(FormData$2.prototype, 'FormData');
17207
17207
 
17208
17208
  // Public API
17209
17209
  var form_data = FormData$2;
@@ -18819,9 +18819,8 @@ var request = function (url, params, _a) {
18819
18819
  };
18820
18820
  return [4 /*yield*/, axios({
18821
18821
  method: method,
18822
- url: (process.env.DEV
18823
- ? 'http://127.0.0.1:1626'
18824
- : 'https://editor.appthen.com') + url,
18822
+ url: (process.env.DEV ? 'http://127.0.0.1:1626' : 'https://api.appthen.com') +
18823
+ url,
18825
18824
  data: params,
18826
18825
  headers: headers,
18827
18826
  })];
@@ -37899,7 +37898,7 @@ function create(options) {
37899
37898
 
37900
37899
  var fuck = function () { };
37901
37900
 
37902
- var server = 'wss://editor.appthen.com';
37901
+ var server = 'wss://api.appthen.com';
37903
37902
  var devServer = 'ws://127.0.0.1:1626';
37904
37903
  var DEV_MODE$1 = process.env.DEV;
37905
37904
  var SocketStore = /** @class */ (function () {
@@ -40668,8 +40667,13 @@ function regExpEscape (s) {
40668
40667
  return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
40669
40668
  }
40670
40669
 
40671
- // import chokidar, { FSWatcher } from 'chokidar';
40672
- var logger = function () { };
40670
+ var logger = function () {
40671
+ var args = [];
40672
+ for (var _i = 0; _i < arguments.length; _i++) {
40673
+ args[_i] = arguments[_i];
40674
+ }
40675
+ console.log.apply(console, __spreadArray([], __read(args), false));
40676
+ };
40673
40677
  /**
40674
40678
  * 影子空间管理器
40675
40679
  * 维护编辑器状态的本地镜像,用于检测文件变更
@@ -40951,6 +40955,7 @@ var ShadowSpace = /** @class */ (function () {
40951
40955
  return [4 /*yield*/, fs__default$1["default"].unlink(fullPath)];
40952
40956
  case 2:
40953
40957
  _a.sent();
40958
+ logger("\u672C\u5730\u6587\u4EF6\u5DF2\u5220\u9664: ".concat(fullPath));
40954
40959
  return [3 /*break*/, 4];
40955
40960
  case 3:
40956
40961
  error_1 = _a.sent();
@@ -40964,6 +40969,7 @@ var ShadowSpace = /** @class */ (function () {
40964
40969
  return [4 /*yield*/, this.saveState()];
40965
40970
  case 5:
40966
40971
  _a.sent();
40972
+ logger("\u5F71\u5B50\u7A7A\u95F4\u6587\u4EF6\u5DF2\u5220\u9664: ".concat(filePath));
40967
40973
  return [2 /*return*/, true];
40968
40974
  }
40969
40975
  });
@@ -40975,33 +40981,33 @@ var ShadowSpace = /** @class */ (function () {
40975
40981
  */
40976
40982
  ShadowSpace.prototype.detectChanges = function () {
40977
40983
  return __awaiter(this, void 0, void 0, function () {
40978
- var changes, _a, _b, _c, filePath, shadowEntry, localFilePath, localContent, localHash, fileStat, fileModifyTime, shadowContent, _d, _e, error_2, shadowContent, e_3_1, localFiles, localFiles_1, localFiles_1_1, localFile;
40979
- var e_3, _f, _g, e_4, _h;
40980
- return __generator(this, function (_j) {
40981
- switch (_j.label) {
40984
+ var changes, _a, _b, _c, filePath, shadowEntry, localFilePath, localContent, localHash, fileStat, fileModifyTime, shadowContent, _d, _e, error_2, shadowContent, e_3_1, localFiles, localFiles_1, localFiles_1_1, localFile, tempNormalizePath, addsFromRemote, addsFromLocal, _loop_1, addsFromRemote_1, addsFromRemote_1_1, remoteAdd;
40985
+ var e_3, _f, _g, e_4, _h, e_5, _j;
40986
+ return __generator(this, function (_k) {
40987
+ switch (_k.label) {
40982
40988
  case 0:
40983
40989
  changes = [];
40984
- _j.label = 1;
40990
+ _k.label = 1;
40985
40991
  case 1:
40986
- _j.trys.push([1, 16, 17, 18]);
40992
+ _k.trys.push([1, 16, 17, 18]);
40987
40993
  _a = __values(Object.entries(this.state.files)), _b = _a.next();
40988
- _j.label = 2;
40994
+ _k.label = 2;
40989
40995
  case 2:
40990
40996
  if (!!_b.done) return [3 /*break*/, 15];
40991
40997
  _c = __read(_b.value, 2), filePath = _c[0], shadowEntry = _c[1];
40992
40998
  localFilePath = path__default["default"].join(this.config.projectRoot, filePath);
40993
- _j.label = 3;
40999
+ _k.label = 3;
40994
41000
  case 3:
40995
- _j.trys.push([3, 11, , 14]);
41001
+ _k.trys.push([3, 11, , 14]);
40996
41002
  return [4 /*yield*/, fs__default$1["default"].readFile(localFilePath, 'utf8')];
40997
41003
  case 4:
40998
- localContent = _j.sent();
41004
+ localContent = _k.sent();
40999
41005
  localHash = this.calculateHash(localContent);
41000
41006
  if (!(localHash !== shadowEntry.hash)) return [3 /*break*/, 10];
41001
41007
  if (!shadowEntry.remoteModified) return [3 /*break*/, 7];
41002
41008
  return [4 /*yield*/, fs__default$1["default"].stat(localFilePath)];
41003
41009
  case 5:
41004
- fileStat = _j.sent();
41010
+ fileStat = _k.sent();
41005
41011
  fileModifyTime = fileStat.mtimeMs;
41006
41012
  // logger(`[ShadowSpace] 🔍 更新文件时间戳: ${filePath}`, {
41007
41013
  // 旧lastModified: new Date(
@@ -41017,12 +41023,12 @@ var ShadowSpace = /** @class */ (function () {
41017
41023
  return [4 /*yield*/, this.saveState()];
41018
41024
  case 6:
41019
41025
  // 保存状态
41020
- _j.sent();
41026
+ _k.sent();
41021
41027
  // 🔥 跳过,不添加到 changes
41022
41028
  return [3 /*break*/, 14];
41023
41029
  case 7: return [4 /*yield*/, this.getShadowContent(filePath)];
41024
41030
  case 8:
41025
- shadowContent = _j.sent();
41031
+ shadowContent = _k.sent();
41026
41032
  _e = (_d = changes).push;
41027
41033
  _g = {
41028
41034
  id: this.generateId(),
@@ -41032,21 +41038,21 @@ var ShadowSpace = /** @class */ (function () {
41032
41038
  };
41033
41039
  return [4 /*yield*/, fs__default$1["default"].stat(localFilePath)];
41034
41040
  case 9:
41035
- _e.apply(_d, [(_g.timestamp = (_j.sent()).mtime.getTime(),
41041
+ _e.apply(_d, [(_g.timestamp = (_k.sent()).mtime.getTime(),
41036
41042
  _g.diff = {
41037
41043
  before: shadowContent,
41038
41044
  after: localContent,
41039
41045
  },
41040
41046
  _g.projectId = this.state.projectId,
41041
41047
  _g)]);
41042
- _j.label = 10;
41048
+ _k.label = 10;
41043
41049
  case 10: return [3 /*break*/, 14];
41044
41050
  case 11:
41045
- error_2 = _j.sent();
41051
+ error_2 = _k.sent();
41046
41052
  if (!(error_2.code === 'ENOENT')) return [3 /*break*/, 13];
41047
41053
  return [4 /*yield*/, this.getShadowContent(filePath)];
41048
41054
  case 12:
41049
- shadowContent = _j.sent();
41055
+ shadowContent = _k.sent();
41050
41056
  changes.push({
41051
41057
  id: this.generateId(),
41052
41058
  action: 'delete',
@@ -41059,14 +41065,14 @@ var ShadowSpace = /** @class */ (function () {
41059
41065
  },
41060
41066
  projectId: this.state.projectId,
41061
41067
  });
41062
- _j.label = 13;
41068
+ _k.label = 13;
41063
41069
  case 13: return [3 /*break*/, 14];
41064
41070
  case 14:
41065
41071
  _b = _a.next();
41066
41072
  return [3 /*break*/, 2];
41067
41073
  case 15: return [3 /*break*/, 18];
41068
41074
  case 16:
41069
- e_3_1 = _j.sent();
41075
+ e_3_1 = _k.sent();
41070
41076
  e_3 = { error: e_3_1 };
41071
41077
  return [3 /*break*/, 18];
41072
41078
  case 17:
@@ -41077,7 +41083,7 @@ var ShadowSpace = /** @class */ (function () {
41077
41083
  return [7 /*endfinally*/];
41078
41084
  case 18: return [4 /*yield*/, this.scanLocalFiles()];
41079
41085
  case 19:
41080
- localFiles = _j.sent();
41086
+ localFiles = _k.sent();
41081
41087
  try {
41082
41088
  for (localFiles_1 = __values(localFiles), localFiles_1_1 = localFiles_1.next(); !localFiles_1_1.done; localFiles_1_1 = localFiles_1.next()) {
41083
41089
  localFile = localFiles_1_1.value;
@@ -41104,6 +41110,53 @@ var ShadowSpace = /** @class */ (function () {
41104
41110
  }
41105
41111
  finally { if (e_4) throw e_4.error; }
41106
41112
  }
41113
+ tempNormalizePath = function (p) { return p.replace(/\\/g, '/'); };
41114
+ addsFromRemote = changes.filter(function (c) { return c.action === 'add' && c.side === 'editor'; });
41115
+ addsFromLocal = changes.filter(function (c) { return c.action === 'add' && c.side === 'space'; });
41116
+ _loop_1 = function (remoteAdd) {
41117
+ var localAdd = addsFromLocal.find(function (l) {
41118
+ return tempNormalizePath(l.path) === tempNormalizePath(remoteAdd.path);
41119
+ });
41120
+ if (localAdd) {
41121
+ // 发现双向 Add,说明 Map Key 匹配失败了,但路径标准化后是一样的
41122
+ console.error("[ShadowSpace] CRITICAL: Detected dual ADD for ".concat(remoteAdd.path, ". Merging to CONFLICT."));
41123
+ // 移除这两个 Add
41124
+ var indexR = changes.indexOf(remoteAdd);
41125
+ if (indexR > -1)
41126
+ changes.splice(indexR, 1);
41127
+ var indexL = changes.indexOf(localAdd);
41128
+ if (indexL > -1)
41129
+ changes.splice(indexL, 1);
41130
+ // 添加一个 Modify Conflict
41131
+ changes.push({
41132
+ action: 'modify',
41133
+ path: tempNormalizePath(remoteAdd.path),
41134
+ side: 'editor',
41135
+ sourceLabel: 'remote',
41136
+ targetLabel: 'local',
41137
+ // @ts-ignore
41138
+ editorHash: remoteAdd.editorHash,
41139
+ // @ts-ignore
41140
+ spaceHash: localAdd.spaceHash,
41141
+ conflict: true,
41142
+ // @ts-ignore
41143
+ debug: 'merged_dual_add',
41144
+ });
41145
+ }
41146
+ };
41147
+ try {
41148
+ for (addsFromRemote_1 = __values(addsFromRemote), addsFromRemote_1_1 = addsFromRemote_1.next(); !addsFromRemote_1_1.done; addsFromRemote_1_1 = addsFromRemote_1.next()) {
41149
+ remoteAdd = addsFromRemote_1_1.value;
41150
+ _loop_1(remoteAdd);
41151
+ }
41152
+ }
41153
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
41154
+ finally {
41155
+ try {
41156
+ if (addsFromRemote_1_1 && !addsFromRemote_1_1.done && (_j = addsFromRemote_1.return)) _j.call(addsFromRemote_1);
41157
+ }
41158
+ finally { if (e_5) throw e_5.error; }
41159
+ }
41107
41160
  return [2 /*return*/, changes];
41108
41161
  }
41109
41162
  });
@@ -41114,16 +41167,16 @@ var ShadowSpace = /** @class */ (function () {
41114
41167
  */
41115
41168
  ShadowSpace.prototype.applyChanges = function (changes) {
41116
41169
  return __awaiter(this, void 0, void 0, function () {
41117
- var changes_1, changes_1_1, change, _a, e_5_1;
41118
- var e_5, _b;
41170
+ var changes_1, changes_1_1, change, _a, e_6_1;
41171
+ var e_6, _b;
41119
41172
  return __generator(this, function (_c) {
41120
41173
  switch (_c.label) {
41121
41174
  case 0:
41122
- _c.trys.push([0, 9, 10, 11]);
41175
+ _c.trys.push([0, 10, 11, 12]);
41123
41176
  changes_1 = __values(changes), changes_1_1 = changes_1.next();
41124
41177
  _c.label = 1;
41125
41178
  case 1:
41126
- if (!!changes_1_1.done) return [3 /*break*/, 8];
41179
+ if (!!changes_1_1.done) return [3 /*break*/, 9];
41127
41180
  change = changes_1_1.value;
41128
41181
  _a = change.action;
41129
41182
  switch (_a) {
@@ -41138,26 +41191,27 @@ var ShadowSpace = /** @class */ (function () {
41138
41191
  case 3:
41139
41192
  _c.sent();
41140
41193
  _c.label = 4;
41141
- case 4: return [3 /*break*/, 7];
41194
+ case 4: return [3 /*break*/, 8];
41142
41195
  case 5: return [4 /*yield*/, this.deleteFile(change.path)];
41143
41196
  case 6:
41144
41197
  _c.sent();
41145
- return [3 /*break*/, 7];
41146
- case 7:
41198
+ return [3 /*break*/, 8];
41199
+ case 7: return [3 /*break*/, 8];
41200
+ case 8:
41147
41201
  changes_1_1 = changes_1.next();
41148
41202
  return [3 /*break*/, 1];
41149
- case 8: return [3 /*break*/, 11];
41150
- case 9:
41151
- e_5_1 = _c.sent();
41152
- e_5 = { error: e_5_1 };
41153
- return [3 /*break*/, 11];
41203
+ case 9: return [3 /*break*/, 12];
41154
41204
  case 10:
41205
+ e_6_1 = _c.sent();
41206
+ e_6 = { error: e_6_1 };
41207
+ return [3 /*break*/, 12];
41208
+ case 11:
41155
41209
  try {
41156
41210
  if (changes_1_1 && !changes_1_1.done && (_b = changes_1.return)) _b.call(changes_1);
41157
41211
  }
41158
- finally { if (e_5) throw e_5.error; }
41212
+ finally { if (e_6) throw e_6.error; }
41159
41213
  return [7 /*endfinally*/];
41160
- case 11:
41214
+ case 12:
41161
41215
  logger("\u5F71\u5B50\u7A7A\u95F4\u5DF2\u5E94\u7528 ".concat(changes.length, " \u4E2A\u53D8\u66F4"));
41162
41216
  return [2 /*return*/];
41163
41217
  }
@@ -41205,6 +41259,7 @@ var ShadowSpace = /** @class */ (function () {
41205
41259
  case 0:
41206
41260
  // 检查文件是否在影子空间中
41207
41261
  if (!this.hasFile(filePath)) {
41262
+ logger("[ShadowSpace] \u6587\u4EF6\u4E0D\u5728\u5F71\u5B50\u7A7A\u95F4\u4E2D: ".concat(filePath));
41208
41263
  return [2 /*return*/, null];
41209
41264
  }
41210
41265
  _a.label = 1;
@@ -41262,8 +41317,8 @@ var ShadowSpace = /** @class */ (function () {
41262
41317
  */
41263
41318
  ShadowSpace.prototype.markAsRemoteModified = function (filePaths) {
41264
41319
  return __awaiter(this, void 0, void 0, function () {
41265
- var now, hasChanges, filePaths_1, filePaths_1_1, filePath, fullPath, stats, content, hash, existingFile, remoteHash, error_5, e_6_1;
41266
- var e_6, _a;
41320
+ var now, hasChanges, filePaths_1, filePaths_1_1, filePath, fullPath, stats, content, hash, existingFile, remoteHash, error_5, e_7_1;
41321
+ var e_7, _a;
41267
41322
  return __generator(this, function (_b) {
41268
41323
  switch (_b.label) {
41269
41324
  case 0:
@@ -41313,14 +41368,14 @@ var ShadowSpace = /** @class */ (function () {
41313
41368
  return [3 /*break*/, 2];
41314
41369
  case 8: return [3 /*break*/, 11];
41315
41370
  case 9:
41316
- e_6_1 = _b.sent();
41317
- e_6 = { error: e_6_1 };
41371
+ e_7_1 = _b.sent();
41372
+ e_7 = { error: e_7_1 };
41318
41373
  return [3 /*break*/, 11];
41319
41374
  case 10:
41320
41375
  try {
41321
41376
  if (filePaths_1_1 && !filePaths_1_1.done && (_a = filePaths_1.return)) _a.call(filePaths_1);
41322
41377
  }
41323
- finally { if (e_6) throw e_6.error; }
41378
+ finally { if (e_7) throw e_7.error; }
41324
41379
  return [7 /*endfinally*/];
41325
41380
  case 11:
41326
41381
  if (!hasChanges) return [3 /*break*/, 13];
@@ -41342,7 +41397,7 @@ var ShadowSpace = /** @class */ (function () {
41342
41397
  var _a;
41343
41398
  return __awaiter(this, void 0, void 0, function () {
41344
41399
  var hasChanges, pathsToProcess, pathsToProcess_1, pathsToProcess_1_1, filePath;
41345
- var e_7, _b;
41400
+ var e_8, _b;
41346
41401
  return __generator(this, function (_c) {
41347
41402
  switch (_c.label) {
41348
41403
  case 0:
@@ -41358,12 +41413,12 @@ var ShadowSpace = /** @class */ (function () {
41358
41413
  }
41359
41414
  }
41360
41415
  }
41361
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
41416
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
41362
41417
  finally {
41363
41418
  try {
41364
41419
  if (pathsToProcess_1_1 && !pathsToProcess_1_1.done && (_b = pathsToProcess_1.return)) _b.call(pathsToProcess_1);
41365
41420
  }
41366
- finally { if (e_7) throw e_7.error; }
41421
+ finally { if (e_8) throw e_8.error; }
41367
41422
  }
41368
41423
  if (!hasChanges) return [3 /*break*/, 2];
41369
41424
  return [4 /*yield*/, this.saveState()];
@@ -41383,7 +41438,7 @@ var ShadowSpace = /** @class */ (function () {
41383
41438
  ShadowSpace.prototype.getSpaceSnapshots = function (_spaceId) {
41384
41439
  return __awaiter(this, void 0, void 0, function () {
41385
41440
  var snapshots, _a, _b, _c, filePath, shadowEntry, modifyTime, error_6;
41386
- var e_8, _d;
41441
+ var e_9, _d;
41387
41442
  return __generator(this, function (_e) {
41388
41443
  switch (_e.label) {
41389
41444
  case 0:
@@ -41413,12 +41468,12 @@ var ShadowSpace = /** @class */ (function () {
41413
41468
  });
41414
41469
  }
41415
41470
  }
41416
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
41471
+ catch (e_9_1) { e_9 = { error: e_9_1 }; }
41417
41472
  finally {
41418
41473
  try {
41419
41474
  if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
41420
41475
  }
41421
- finally { if (e_8) throw e_8.error; }
41476
+ finally { if (e_9) throw e_9.error; }
41422
41477
  }
41423
41478
  logger("[ShadowSpace] \u83B7\u53D6\u7A7A\u95F4\u5FEB\u7167: ".concat(snapshots.length, " \u4E2A\u6587\u4EF6"));
41424
41479
  return [2 /*return*/, snapshots];
@@ -41457,6 +41512,633 @@ var ShadowSpace = /** @class */ (function () {
41457
41512
  });
41458
41513
  });
41459
41514
  };
41515
+ /**
41516
+ * 独立同步:获取远端文件快照
41517
+ */
41518
+ ShadowSpace.prototype.fetchRemoteSnapshot = function () {
41519
+ var _a, _b, _c, _d, _e, _f;
41520
+ return __awaiter(this, void 0, void 0, function () {
41521
+ var requestParams, response, files, snapshot_1, processNode_1, error_8;
41522
+ var _this = this;
41523
+ return __generator(this, function (_g) {
41524
+ switch (_g.label) {
41525
+ case 0:
41526
+ _g.trys.push([0, 2, , 3]);
41527
+ requestParams = {
41528
+ projectId: this.config.projectId,
41529
+ path: '/',
41530
+ options: {
41531
+ recursive: true,
41532
+ includeTypeEntity: false,
41533
+ },
41534
+ };
41535
+ logger('[ShadowSpace] 开始获取远端快照...', requestParams);
41536
+ return [4 /*yield*/, request('/editor/vfs/readdir', requestParams)];
41537
+ case 1:
41538
+ response = _g.sent();
41539
+ // Log response structure for debugging
41540
+ logger('[ShadowSpace] 远端响应数据结构:', {
41541
+ type: typeof response.data,
41542
+ isSuccess: (_a = response.data) === null || _a === void 0 ? void 0 : _a.success,
41543
+ dataType: typeof ((_b = response.data) === null || _b === void 0 ? void 0 : _b.data),
41544
+ isArray: Array.isArray((_c = response.data) === null || _c === void 0 ? void 0 : _c.data),
41545
+ dataKeys: ((_d = response.data) === null || _d === void 0 ? void 0 : _d.data) ? Object.keys(response.data.data) : [],
41546
+ });
41547
+ if (!((_e = response.data) === null || _e === void 0 ? void 0 : _e.success)) {
41548
+ throw new Error(((_f = response.data) === null || _f === void 0 ? void 0 : _f.message) || 'Failed to fetch remote snapshot');
41549
+ }
41550
+ files = response.data.data;
41551
+ if (!Array.isArray(files)) {
41552
+ // If it's an object with a children property (common file system tree structure)
41553
+ if (files && Array.isArray(files.children)) {
41554
+ files = files.children;
41555
+ }
41556
+ else if (files && Array.isArray(files.entries)) {
41557
+ // Fix: Support entries array
41558
+ files = files.entries;
41559
+ }
41560
+ else if (files && typeof files === 'object') {
41561
+ // If it's a map/object structure, try to convert values to array or wrap single object
41562
+ files = [files];
41563
+ }
41564
+ else {
41565
+ logger('[ShadowSpace] 警告: 远端返回的数据不是数组', files);
41566
+ files = [];
41567
+ }
41568
+ }
41569
+ snapshot_1 = [];
41570
+ processNode_1 = function (node) {
41571
+ if (!node)
41572
+ return;
41573
+ // Try to normalize node structure
41574
+ // If node has 'stats', use it. Otherwise, node itself might be stats or metadata.
41575
+ // Based on user provided example:
41576
+ // { "path": "...", "stats": { "type": "file", "contentHash": "..." } }
41577
+ var stats = node.stats || node;
41578
+ var type = stats.type || node.type;
41579
+ var filePath = node.path || stats.path;
41580
+ if (type === 'file') {
41581
+ // 去除开头的 /
41582
+ var relativePath = filePath;
41583
+ if (relativePath.startsWith('/')) {
41584
+ relativePath = relativePath.slice(1);
41585
+ }
41586
+ // 🔥 调试:打印原始路径和标准化后的路径
41587
+ if (relativePath.includes('TicketHistory') ||
41588
+ filePath.includes('TicketHistory')) {
41589
+ logger("[ShadowSpace] Path Normalization: \"".concat(filePath, "\" -> \"").concat(relativePath, "\""));
41590
+ }
41591
+ // 忽略文件
41592
+ if (_this.shouldIgnoreFile(relativePath)) {
41593
+ return;
41594
+ }
41595
+ snapshot_1.push({
41596
+ path: relativePath,
41597
+ hash: stats.contentHash || '',
41598
+ modify: stats.modifyTime || 0,
41599
+ size: stats.size || 0,
41600
+ });
41601
+ }
41602
+ // Handle recursive directory structure if present
41603
+ if (node.children && Array.isArray(node.children)) {
41604
+ node.children.forEach(processNode_1);
41605
+ }
41606
+ };
41607
+ files.forEach(processNode_1);
41608
+ logger("[ShadowSpace] \u83B7\u53D6\u5230 ".concat(snapshot_1.length, " \u4E2A\u8FDC\u7AEF\u6587\u4EF6"));
41609
+ return [2 /*return*/, snapshot_1];
41610
+ case 2:
41611
+ error_8 = _g.sent();
41612
+ console.error('[ShadowSpace] 获取远端快照失败:', error_8);
41613
+ if (error_8.response) {
41614
+ console.error('[ShadowSpace] 远端响应详情:', {
41615
+ status: error_8.response.status,
41616
+ statusText: error_8.response.statusText,
41617
+ data: error_8.response.data,
41618
+ headers: error_8.response.headers,
41619
+ });
41620
+ }
41621
+ throw error_8;
41622
+ case 3: return [2 /*return*/];
41623
+ }
41624
+ });
41625
+ });
41626
+ };
41627
+ /**
41628
+ * 独立同步:下载远端文件
41629
+ */
41630
+ ShadowSpace.prototype.downloadRemoteFile = function (filePath) {
41631
+ var _a, _b;
41632
+ return __awaiter(this, void 0, void 0, function () {
41633
+ var remotePath, response, error_9;
41634
+ return __generator(this, function (_c) {
41635
+ switch (_c.label) {
41636
+ case 0:
41637
+ _c.trys.push([0, 2, , 3]);
41638
+ remotePath = filePath.startsWith('/') ? filePath : '/' + filePath;
41639
+ return [4 /*yield*/, request('/editor/vfs/read', {
41640
+ projectId: this.config.projectId,
41641
+ path: remotePath,
41642
+ isCodeMode: true,
41643
+ })];
41644
+ case 1:
41645
+ response = _c.sent();
41646
+ if (!((_a = response.data) === null || _a === void 0 ? void 0 : _a.success)) {
41647
+ throw new Error(((_b = response.data) === null || _b === void 0 ? void 0 : _b.message) || "Failed to download file: ".concat(filePath));
41648
+ }
41649
+ return [2 /*return*/, response.data.data.content];
41650
+ case 2:
41651
+ error_9 = _c.sent();
41652
+ console.error("[ShadowSpace] \u4E0B\u8F7D\u6587\u4EF6\u5931\u8D25: ".concat(filePath), error_9);
41653
+ throw error_9;
41654
+ case 3: return [2 /*return*/];
41655
+ }
41656
+ });
41657
+ });
41658
+ };
41659
+ /**
41660
+ * 独立同步:上传本地文件
41661
+ */
41662
+ ShadowSpace.prototype.uploadLocalFile = function (filePath, content) {
41663
+ var _a, _b;
41664
+ return __awaiter(this, void 0, void 0, function () {
41665
+ var remotePath, response, error_10;
41666
+ return __generator(this, function (_c) {
41667
+ switch (_c.label) {
41668
+ case 0:
41669
+ _c.trys.push([0, 2, , 3]);
41670
+ remotePath = filePath.startsWith('/') ? filePath : '/' + filePath;
41671
+ return [4 /*yield*/, request('/editor/vfs/write', {
41672
+ projectId: this.config.projectId,
41673
+ path: remotePath,
41674
+ content: content,
41675
+ options: {
41676
+ writeMode: 'code',
41677
+ skipValidation: true,
41678
+ },
41679
+ })];
41680
+ case 1:
41681
+ response = _c.sent();
41682
+ if (!((_a = response.data) === null || _a === void 0 ? void 0 : _a.success)) {
41683
+ throw new Error(((_b = response.data) === null || _b === void 0 ? void 0 : _b.message) || "Failed to upload file: ".concat(filePath));
41684
+ }
41685
+ return [3 /*break*/, 3];
41686
+ case 2:
41687
+ error_10 = _c.sent();
41688
+ console.error("[ShadowSpace] \u4E0A\u4F20\u6587\u4EF6\u5931\u8D25: ".concat(filePath), error_10);
41689
+ throw error_10;
41690
+ case 3: return [2 /*return*/];
41691
+ }
41692
+ });
41693
+ });
41694
+ };
41695
+ /**
41696
+ * 比对快照,生成变更列表
41697
+ * (从 ShadowSpaceCommandHandler 移动而来,核心比对逻辑)
41698
+ */
41699
+ ShadowSpace.prototype.compareSnapshots = function (remoteSnapshots, localSnapshots) {
41700
+ var e_10, _a, e_11, _b;
41701
+ var changes = [];
41702
+ // 标准化路径工具函数
41703
+ var normalizePath = function (p) {
41704
+ // 统一替换反斜杠为正斜杠
41705
+ var normalized = p.replace(/\\/g, '/');
41706
+ // 去除开头的 ./
41707
+ if (normalized.startsWith('./'))
41708
+ normalized = normalized.substring(2);
41709
+ // 去除开头的 /
41710
+ if (normalized.startsWith('/'))
41711
+ normalized = normalized.substring(1);
41712
+ return normalized;
41713
+ };
41714
+ // 确保输入参数是数组
41715
+ var safeRemoteSnapshots = Array.isArray(remoteSnapshots)
41716
+ ? remoteSnapshots
41717
+ : [];
41718
+ var safeLocalSnapshots = Array.isArray(localSnapshots)
41719
+ ? localSnapshots
41720
+ : [];
41721
+ // 构建映射表 (强制标准化 key)
41722
+ var remoteMap = new Map(safeRemoteSnapshots.map(function (f) { return [normalizePath(f.path), f]; }));
41723
+ var localMap = new Map(safeLocalSnapshots.map(function (f) { return [normalizePath(f.path), f]; }));
41724
+ var remoteKeys = Array.from(remoteMap.keys());
41725
+ var localKeys = Array.from(localMap.keys());
41726
+ var remoteKey = remoteKeys.find(function (k) { return k.includes('__afterRequest'); });
41727
+ var localKey = localKeys.find(function (k) { return k.includes('__afterRequest'); });
41728
+ if (remoteKey || localKey) {
41729
+ logger('[ShadowSpace] CharCodes Debug:', {
41730
+ remoteKey: remoteKey,
41731
+ remoteCodes: remoteKey
41732
+ ? Array.from(remoteKey).map(function (c) { return c.charCodeAt(0); })
41733
+ : null,
41734
+ localKey: localKey,
41735
+ localCodes: localKey
41736
+ ? Array.from(localKey).map(function (c) { return c.charCodeAt(0); })
41737
+ : null,
41738
+ isEqual: remoteKey === localKey,
41739
+ });
41740
+ }
41741
+ logger('[ShadowSpace] 比对文件列表 (Normalized):', {
41742
+ remoteCount: remoteMap.size,
41743
+ localCount: localMap.size,
41744
+ remoteFiles: Array.from(remoteMap.keys()),
41745
+ localFiles: Array.from(localMap.keys()),
41746
+ });
41747
+ // 1. 检测远端的变更(相对于本地)
41748
+ // 遍历远端文件
41749
+ console.log('localMap: ', localMap.keys());
41750
+ var _loop_2 = function (filePath, remoteFile) {
41751
+ var localFile = localMap.get(filePath);
41752
+ if (!localFile) {
41753
+ console.log('filePath: ', filePath, filePath.length, filePath.startsWith(' '));
41754
+ // 本地缺失 -> 需要从远端拉取 (Pull)
41755
+ logger("[ShadowSpace] \u53D1\u73B0\u672C\u5730\u7F3A\u5931: ".concat(filePath, " (Add to Local)"));
41756
+ changes.push({
41757
+ action: 'add',
41758
+ path: filePath,
41759
+ side: 'editor',
41760
+ sourceLabel: 'remote',
41761
+ targetLabel: 'local',
41762
+ editorHash: remoteFile.hash,
41763
+ spaceHash: null,
41764
+ });
41765
+ }
41766
+ else if (remoteFile.hash !== localFile.hash) {
41767
+ // Hash 不同,需要判断谁是最新版本
41768
+ var remoteModify = remoteFile.modify || 0;
41769
+ var localModify = localFile.modify || 0;
41770
+ logger("[ShadowSpace] \u53D1\u73B0\u53D8\u66F4: ".concat(filePath), {
41771
+ remoteHash: remoteFile.hash,
41772
+ localHash: localFile.hash,
41773
+ remoteModify: remoteModify,
41774
+ localModify: localModify,
41775
+ diff: remoteModify - localModify,
41776
+ });
41777
+ // 如果远端哈希与本地记录的"上次远端哈希"不同,说明远端更新了
41778
+ // const remoteChanged = remoteFile.hash !== localFile.remoteHash;
41779
+ // 如果本地哈希与本地记录的"上次远端哈希"不同,说明本地更新了 (注意:localFile.hash 是当前本地hash)
41780
+ // 实际上 localFile.remoteHash 是上次同步时的远端hash
41781
+ // 如果 localFile.hash != localFile.remoteHash,说明本地有修改
41782
+ // 简单策略:基于时间戳 (或者后续基于 remoteHash 追踪)
41783
+ // 这里沿用 Handler 的时间戳逻辑
41784
+ if (remoteModify > localModify) {
41785
+ // 远端更新 -> 拉取
41786
+ changes.push({
41787
+ action: 'modify',
41788
+ path: filePath,
41789
+ side: 'editor',
41790
+ sourceLabel: 'remote',
41791
+ targetLabel: 'local',
41792
+ editorHash: remoteFile.hash,
41793
+ spaceHash: localFile.hash,
41794
+ });
41795
+ }
41796
+ else if (localModify > remoteModify) {
41797
+ // 本地更新 -> 推送
41798
+ changes.push({
41799
+ action: 'modify',
41800
+ path: filePath,
41801
+ side: 'space',
41802
+ sourceLabel: 'local',
41803
+ targetLabel: 'remote',
41804
+ editorHash: remoteFile.hash,
41805
+ spaceHash: localFile.hash,
41806
+ });
41807
+ }
41808
+ else {
41809
+ // 时间戳相同但哈希不同?冲突,默认拉取远端
41810
+ // 只有当两者都没被放入changes时才放入,避免重复
41811
+ var existingChange = changes.find(function (c) { return c.path === filePath; });
41812
+ if (!existingChange) {
41813
+ changes.push({
41814
+ action: 'modify',
41815
+ path: filePath,
41816
+ side: 'editor',
41817
+ sourceLabel: 'remote',
41818
+ targetLabel: 'local',
41819
+ editorHash: remoteFile.hash,
41820
+ spaceHash: localFile.hash,
41821
+ conflict: true,
41822
+ });
41823
+ }
41824
+ }
41825
+ }
41826
+ };
41827
+ try {
41828
+ for (var remoteMap_1 = __values(remoteMap), remoteMap_1_1 = remoteMap_1.next(); !remoteMap_1_1.done; remoteMap_1_1 = remoteMap_1.next()) {
41829
+ var _c = __read(remoteMap_1_1.value, 2), filePath = _c[0], remoteFile = _c[1];
41830
+ _loop_2(filePath, remoteFile);
41831
+ }
41832
+ }
41833
+ catch (e_10_1) { e_10 = { error: e_10_1 }; }
41834
+ finally {
41835
+ try {
41836
+ if (remoteMap_1_1 && !remoteMap_1_1.done && (_a = remoteMap_1.return)) _a.call(remoteMap_1);
41837
+ }
41838
+ finally { if (e_10) throw e_10.error; }
41839
+ }
41840
+ try {
41841
+ // 2. 检测本地的新增/删除 (相对于远端)
41842
+ for (var localMap_1 = __values(localMap), localMap_1_1 = localMap_1.next(); !localMap_1_1.done; localMap_1_1 = localMap_1.next()) {
41843
+ var _d = __read(localMap_1_1.value, 2), filePath = _d[0], localFile = _d[1];
41844
+ var remoteFile = remoteMap.get(filePath);
41845
+ if (remoteFile) {
41846
+ // 远端存在,已经在上面处理过了 (Hash不同或相同)
41847
+ // 除非我们要处理元数据更新等,否则跳过
41848
+ continue;
41849
+ }
41850
+ if (!remoteFile) {
41851
+ // 远端不存在
41852
+ // 如果本地文件有 remoteHash 且不为空,说明之前存在于远端 -> 远端删除了 -> 本地也删除 (Pull)
41853
+ if (localFile.remoteHash) {
41854
+ logger("[ShadowSpace] \u53D1\u73B0\u8FDC\u7AEF\u5220\u9664: ".concat(filePath, " (Delete Local)"));
41855
+ changes.push({
41856
+ action: 'delete',
41857
+ path: filePath,
41858
+ side: 'editor',
41859
+ sourceLabel: 'remote',
41860
+ targetLabel: 'local',
41861
+ editorHash: null,
41862
+ spaceHash: localFile.hash,
41863
+ });
41864
+ }
41865
+ else {
41866
+ // 本地新增 -> 推送到远端 (Push)
41867
+ logger("[ShadowSpace] \u53D1\u73B0\u672C\u5730\u65B0\u589E: ".concat(filePath, " (Push to Remote)"));
41868
+ changes.push({
41869
+ action: 'add',
41870
+ path: filePath,
41871
+ side: 'space',
41872
+ sourceLabel: 'local',
41873
+ targetLabel: 'remote',
41874
+ editorHash: null,
41875
+ spaceHash: localFile.hash,
41876
+ });
41877
+ }
41878
+ }
41879
+ }
41880
+ }
41881
+ catch (e_11_1) { e_11 = { error: e_11_1 }; }
41882
+ finally {
41883
+ try {
41884
+ if (localMap_1_1 && !localMap_1_1.done && (_b = localMap_1.return)) _b.call(localMap_1);
41885
+ }
41886
+ finally { if (e_11) throw e_11.error; }
41887
+ }
41888
+ return changes;
41889
+ };
41890
+ /**
41891
+ * 独立同步:执行完整同步
41892
+ */
41893
+ ShadowSpace.prototype.syncWithRemote = function (options) {
41894
+ if (options === void 0) { options = {}; }
41895
+ return __awaiter(this, void 0, void 0, function () {
41896
+ var remoteSnapshot, localSnapshot, changes, result, changes_2, changes_2_1, change, content, remoteHash, content, err_1, e_12_1;
41897
+ var e_12, _a;
41898
+ return __generator(this, function (_b) {
41899
+ switch (_b.label) {
41900
+ case 0: return [4 /*yield*/, this.fetchRemoteSnapshot()];
41901
+ case 1:
41902
+ remoteSnapshot = _b.sent();
41903
+ if (!(Object.keys(this.state.files).length === 0)) return [3 /*break*/, 3];
41904
+ return [4 /*yield*/, this.syncLocalState()];
41905
+ case 2:
41906
+ _b.sent();
41907
+ _b.label = 3;
41908
+ case 3: return [4 /*yield*/, this.getSpaceSnapshots()];
41909
+ case 4:
41910
+ localSnapshot = _b.sent();
41911
+ changes = this.compareSnapshots(remoteSnapshot, localSnapshot);
41912
+ result = {
41913
+ changes: changes,
41914
+ summary: {
41915
+ total: changes.length,
41916
+ pull: changes.filter(function (c) { return c.side === 'editor'; }).length,
41917
+ push: changes.filter(function (c) { return c.side === 'space'; }).length,
41918
+ },
41919
+ };
41920
+ if (options.dryRun || !options.autoApply) {
41921
+ return [2 /*return*/, result];
41922
+ }
41923
+ _b.label = 5;
41924
+ case 5:
41925
+ _b.trys.push([5, 22, 23, 24]);
41926
+ changes_2 = __values(changes), changes_2_1 = changes_2.next();
41927
+ _b.label = 6;
41928
+ case 6:
41929
+ if (!!changes_2_1.done) return [3 /*break*/, 21];
41930
+ change = changes_2_1.value;
41931
+ _b.label = 7;
41932
+ case 7:
41933
+ _b.trys.push([7, 19, , 20]);
41934
+ if (!(change.side === 'editor')) return [3 /*break*/, 15];
41935
+ if (!(change.action === 'delete')) return [3 /*break*/, 9];
41936
+ return [4 /*yield*/, this.deleteFile(change.path)];
41937
+ case 8:
41938
+ _b.sent();
41939
+ return [3 /*break*/, 14];
41940
+ case 9: return [4 /*yield*/, this.downloadRemoteFile(change.path)];
41941
+ case 10:
41942
+ content = _b.sent();
41943
+ remoteHash = change.editorHash;
41944
+ if (!remoteHash) return [3 /*break*/, 12];
41945
+ return [4 /*yield*/, this.updateFileFromRemote(change.path, content, remoteHash)];
41946
+ case 11:
41947
+ _b.sent();
41948
+ return [3 /*break*/, 14];
41949
+ case 12:
41950
+ // 如果没有 remoteHash (理论上不应该),回退到普通 update
41951
+ return [4 /*yield*/, this.updateFile(change.path, content)];
41952
+ case 13:
41953
+ // 如果没有 remoteHash (理论上不应该),回退到普通 update
41954
+ _b.sent();
41955
+ _b.label = 14;
41956
+ case 14: return [3 /*break*/, 18];
41957
+ case 15:
41958
+ if (!(change.action === 'add' || change.action === 'modify')) return [3 /*break*/, 18];
41959
+ return [4 /*yield*/, this.getShadowContent(change.path)];
41960
+ case 16:
41961
+ content = _b.sent();
41962
+ if (!content) return [3 /*break*/, 18];
41963
+ return [4 /*yield*/, this.uploadLocalFile(change.path, content)];
41964
+ case 17:
41965
+ _b.sent();
41966
+ // 更新状态
41967
+ if (this.state.files[change.path]) {
41968
+ // Push 成功后,远端 Hash 应该等于本地 Hash
41969
+ this.state.files[change.path].remoteHash =
41970
+ this.state.files[change.path].hash;
41971
+ }
41972
+ _b.label = 18;
41973
+ case 18: return [3 /*break*/, 20];
41974
+ case 19:
41975
+ err_1 = _b.sent();
41976
+ console.error("Failed to apply change for ".concat(change.path), err_1);
41977
+ return [3 /*break*/, 20];
41978
+ case 20:
41979
+ changes_2_1 = changes_2.next();
41980
+ return [3 /*break*/, 6];
41981
+ case 21: return [3 /*break*/, 24];
41982
+ case 22:
41983
+ e_12_1 = _b.sent();
41984
+ e_12 = { error: e_12_1 };
41985
+ return [3 /*break*/, 24];
41986
+ case 23:
41987
+ try {
41988
+ if (changes_2_1 && !changes_2_1.done && (_a = changes_2.return)) _a.call(changes_2);
41989
+ }
41990
+ finally { if (e_12) throw e_12.error; }
41991
+ return [7 /*endfinally*/];
41992
+ case 24: return [4 /*yield*/, this.saveState()];
41993
+ case 25:
41994
+ _b.sent();
41995
+ return [2 /*return*/, result];
41996
+ }
41997
+ });
41998
+ });
41999
+ };
42000
+ /**
42001
+ * 🆕 从远端更新文件(正确维护 remoteHash)
42002
+ */
42003
+ ShadowSpace.prototype.updateFileFromRemote = function (filePath, content, remoteHash) {
42004
+ return __awaiter(this, void 0, void 0, function () {
42005
+ var localHash, size, now, currentEntry;
42006
+ return __generator(this, function (_a) {
42007
+ switch (_a.label) {
42008
+ case 0:
42009
+ if (this.shouldIgnoreFile(filePath)) {
42010
+ return [2 /*return*/, false];
42011
+ }
42012
+ // 1. 写入本地文件
42013
+ return [4 /*yield*/, this.writeLocalFile(filePath, content)];
42014
+ case 1:
42015
+ // 1. 写入本地文件
42016
+ _a.sent();
42017
+ localHash = this.calculateHash(content);
42018
+ size = Buffer.byteLength(content, 'utf8');
42019
+ now = Date.now();
42020
+ currentEntry = this.state.files[filePath];
42021
+ this.state.files[filePath] = {
42022
+ path: filePath,
42023
+ hash: localHash,
42024
+ remoteHash: remoteHash,
42025
+ size: size,
42026
+ lastSyncTime: now,
42027
+ lastModified: now,
42028
+ version: currentEntry ? currentEntry.version + 1 : 1,
42029
+ mtime: now,
42030
+ remoteModified: false, // 已同步,清除标记
42031
+ };
42032
+ // 更新缓存
42033
+ this.contentCache.set(filePath, content);
42034
+ return [2 /*return*/, true];
42035
+ }
42036
+ });
42037
+ });
42038
+ };
42039
+ // ==================== 🆕 文件监听功能 ====================
42040
+ /**
42041
+ * 启动文件监听
42042
+ */
42043
+ ShadowSpace.prototype.startWatching = function () {
42044
+ var _this = this;
42045
+ if (this.isWatching) {
42046
+ logger('[ShadowSpace] 文件监听已经在运行中');
42047
+ return;
42048
+ }
42049
+ logger('[ShadowSpace] 启动文件监听...');
42050
+ logger('[ShadowSpace] 监听目录:', this.config.projectRoot);
42051
+ try {
42052
+ // 🔥 使用轮询模式 + ignored 函数过滤
42053
+ this.watcher = chokidar__default["default"].watch(this.config.projectRoot, {
42054
+ ignored: function (filePath) {
42055
+ var relativePath = path__default["default"].relative(_this.config.projectRoot, filePath);
42056
+ // 忽略根目录本身
42057
+ if (!relativePath || relativePath === '.') {
42058
+ return true;
42059
+ }
42060
+ // 使用白名单过滤
42061
+ return _this.shouldIgnoreFile(relativePath);
42062
+ },
42063
+ persistent: true,
42064
+ ignoreInitial: true,
42065
+ usePolling: true,
42066
+ interval: 2000,
42067
+ binaryInterval: 3000,
42068
+ depth: 99,
42069
+ awaitWriteFinish: {
42070
+ stabilityThreshold: 500,
42071
+ pollInterval: 100,
42072
+ },
42073
+ });
42074
+ logger('[ShadowSpace] chokidar.watch 已调用,等待 ready 事件...');
42075
+ }
42076
+ catch (error) {
42077
+ console.error('[ShadowSpace] 创建文件监听器失败:', error);
42078
+ }
42079
+ if (this.watcher) {
42080
+ this.watcher
42081
+ .on('change', function (filePath) {
42082
+ _this.onFileChanged(filePath);
42083
+ })
42084
+ .on('add', function (filePath) {
42085
+ _this.onFileAdded(filePath);
42086
+ })
42087
+ .on('unlink', function (filePath) {
42088
+ _this.onFileDeleted(filePath);
42089
+ })
42090
+ .on('error', function (error) {
42091
+ console.error('[ShadowSpace] 文件监听错误:', error);
42092
+ })
42093
+ .on('ready', function () {
42094
+ _this.isWatching = true;
42095
+ logger('[ShadowSpace] 文件监听已启动,正在监听:', _this.config.projectRoot);
42096
+ logger('[ShadowSpace] 监听配置: 轮询模式 (interval: 2s)');
42097
+ });
42098
+ }
42099
+ };
42100
+ /**
42101
+ * 停止文件监听
42102
+ */
42103
+ ShadowSpace.prototype.stopWatching = function () {
42104
+ return __awaiter(this, void 0, void 0, function () {
42105
+ return __generator(this, function (_a) {
42106
+ switch (_a.label) {
42107
+ case 0:
42108
+ if (!this.isWatching || !this.watcher) {
42109
+ logger('[ShadowSpace] 文件监听未运行');
42110
+ return [2 /*return*/];
42111
+ }
42112
+ logger('[ShadowSpace] 停止文件监听...');
42113
+ return [4 /*yield*/, this.watcher.close()];
42114
+ case 1:
42115
+ _a.sent();
42116
+ this.watcher = null;
42117
+ this.isWatching = false;
42118
+ logger('[ShadowSpace] 文件监听已停止');
42119
+ return [2 /*return*/];
42120
+ }
42121
+ });
42122
+ });
42123
+ };
42124
+ /**
42125
+ * 添加变更事件监听器
42126
+ */
42127
+ ShadowSpace.prototype.addChangeListener = function (listener) {
42128
+ this.changeListeners.add(listener);
42129
+ };
42130
+ /**
42131
+ * 移除变更事件监听器
42132
+ */
42133
+ ShadowSpace.prototype.removeChangeListener = function (listener) {
42134
+ this.changeListeners.delete(listener);
42135
+ };
42136
+ /**
42137
+ * 获取监听状态
42138
+ */
42139
+ ShadowSpace.prototype.isFileWatching = function () {
42140
+ return this.isWatching;
42141
+ };
41460
42142
  // ==================== 私有方法 ====================
41461
42143
  /**
41462
42144
  * 生成基于路径的唯一空间ID
@@ -41477,6 +42159,7 @@ var ShadowSpace = /** @class */ (function () {
41477
42159
  var dirName = path__default["default"].basename(absolutePath);
41478
42160
  // 组合生成空间ID: 目录名-路径hash
41479
42161
  var spaceId = "".concat(dirName, "-").concat(pathHash);
42162
+ logger("[ShadowSpace] \u751F\u6210\u7A7A\u95F4ID: ".concat(spaceId, " (\u8DEF\u5F84: ").concat(absolutePath, ")"));
41480
42163
  return spaceId;
41481
42164
  };
41482
42165
  /**
@@ -41484,7 +42167,7 @@ var ShadowSpace = /** @class */ (function () {
41484
42167
  */
41485
42168
  ShadowSpace.prototype.saveSpaceConfig = function () {
41486
42169
  return __awaiter(this, void 0, void 0, function () {
41487
- var configFile, config, error_8;
42170
+ var configFile, config, error_11;
41488
42171
  return __generator(this, function (_a) {
41489
42172
  switch (_a.label) {
41490
42173
  case 0:
@@ -41506,10 +42189,11 @@ var ShadowSpace = /** @class */ (function () {
41506
42189
  return [4 /*yield*/, fs__default$1["default"].writeFile(configFile, JSON.stringify(config, null, 2))];
41507
42190
  case 3:
41508
42191
  _a.sent();
42192
+ logger("[ShadowSpace] \u7A7A\u95F4\u914D\u7F6E\u5DF2\u4FDD\u5B58: ".concat(configFile));
41509
42193
  return [3 /*break*/, 5];
41510
42194
  case 4:
41511
- error_8 = _a.sent();
41512
- console.warn('[ShadowSpace] 保存空间配置失败:', error_8);
42195
+ error_11 = _a.sent();
42196
+ console.warn('[ShadowSpace] 保存空间配置失败:', error_11);
41513
42197
  return [3 /*break*/, 5];
41514
42198
  case 5: return [2 /*return*/];
41515
42199
  }
@@ -41521,14 +42205,15 @@ var ShadowSpace = /** @class */ (function () {
41521
42205
  */
41522
42206
  ShadowSpace.prototype.migrateOldStateFiles = function () {
41523
42207
  return __awaiter(this, void 0, void 0, function () {
41524
- var appthenDir, files, oldStateFiles, oldStateFiles_1, oldStateFiles_1_1, oldFile, oldFilePath, oldState, backupFile, e_9_1, error_9;
41525
- var e_9, _a;
42208
+ var appthenDir, files, oldStateFiles, oldStateFiles_1, oldStateFiles_1_1, oldFile, oldFilePath, oldState, backupFile, e_13_1, error_12;
42209
+ var e_13, _a;
41526
42210
  var _this = this;
41527
42211
  return __generator(this, function (_b) {
41528
42212
  switch (_b.label) {
41529
42213
  case 0:
41530
42214
  _b.trys.push([0, 12, , 13]);
41531
42215
  appthenDir = path__default["default"].join(this.config.projectRoot, '.appthen');
42216
+ logger("[ShadowSpace] \u68C0\u67E5\u8FC1\u79FB: ".concat(appthenDir));
41532
42217
  return [4 /*yield*/, fs__default$1["default"].readdir(appthenDir)];
41533
42218
  case 1:
41534
42219
  files = _b.sent();
@@ -41568,25 +42253,26 @@ var ShadowSpace = /** @class */ (function () {
41568
42253
  case 6:
41569
42254
  _b.sent();
41570
42255
  logger("[ShadowSpace] \u5DF2\u8FC1\u79FB ".concat(Object.keys(this.state.files).length, " \u4E2A\u6587\u4EF6\u5230\u65B0\u7A7A\u95F4 ").concat(this.config.spaceId));
42256
+ logger("[ShadowSpace] \u65E7\u6587\u4EF6\u5DF2\u5907\u4EFD\u4E3A: ".concat(backupFile));
41571
42257
  return [3 /*break*/, 8]; // 只迁移第一个匹配的文件
41572
42258
  case 7:
41573
42259
  oldStateFiles_1_1 = oldStateFiles_1.next();
41574
42260
  return [3 /*break*/, 3];
41575
42261
  case 8: return [3 /*break*/, 11];
41576
42262
  case 9:
41577
- e_9_1 = _b.sent();
41578
- e_9 = { error: e_9_1 };
42263
+ e_13_1 = _b.sent();
42264
+ e_13 = { error: e_13_1 };
41579
42265
  return [3 /*break*/, 11];
41580
42266
  case 10:
41581
42267
  try {
41582
42268
  if (oldStateFiles_1_1 && !oldStateFiles_1_1.done && (_a = oldStateFiles_1.return)) _a.call(oldStateFiles_1);
41583
42269
  }
41584
- finally { if (e_9) throw e_9.error; }
42270
+ finally { if (e_13) throw e_13.error; }
41585
42271
  return [7 /*endfinally*/];
41586
42272
  case 11: return [3 /*break*/, 13];
41587
42273
  case 12:
41588
- error_9 = _b.sent();
41589
- console.warn('[ShadowSpace] 迁移旧状态文件失败:', error_9);
42274
+ error_12 = _b.sent();
42275
+ console.warn('[ShadowSpace] 迁移旧状态文件失败:', error_12);
41590
42276
  return [3 /*break*/, 13];
41591
42277
  case 13: return [2 /*return*/];
41592
42278
  }
@@ -41595,7 +42281,7 @@ var ShadowSpace = /** @class */ (function () {
41595
42281
  };
41596
42282
  ShadowSpace.prototype.getShadowContent = function (filePath) {
41597
42283
  return __awaiter(this, void 0, void 0, function () {
41598
- var localPath, content, error_10;
42284
+ var localPath, content, error_13;
41599
42285
  return __generator(this, function (_a) {
41600
42286
  switch (_a.label) {
41601
42287
  case 0:
@@ -41613,8 +42299,8 @@ var ShadowSpace = /** @class */ (function () {
41613
42299
  this.contentCache.set(filePath, content);
41614
42300
  return [2 /*return*/, content];
41615
42301
  case 3:
41616
- error_10 = _a.sent();
41617
- console.warn("\u65E0\u6CD5\u83B7\u53D6\u5F71\u5B50\u5185\u5BB9: ".concat(filePath), error_10);
42302
+ error_13 = _a.sent();
42303
+ console.warn("\u65E0\u6CD5\u83B7\u53D6\u5F71\u5B50\u5185\u5BB9: ".concat(filePath), error_13);
41618
42304
  return [2 /*return*/, ''];
41619
42305
  case 4: return [2 /*return*/];
41620
42306
  }
@@ -41629,11 +42315,13 @@ var ShadowSpace = /** @class */ (function () {
41629
42315
  .digest('hex');
41630
42316
  };
41631
42317
  ShadowSpace.prototype.generateId = function () {
41632
- return "change_".concat(Date.now(), "_").concat(Math.random().toString(36).substr(2, 9));
42318
+ return "change_".concat(Date.now(), "_").concat(Math.random()
42319
+ .toString(36)
42320
+ .substring(2, 11));
41633
42321
  };
41634
42322
  ShadowSpace.prototype.shouldIgnoreFile = function (filePath) {
41635
42323
  // logger(`[ShadowSpace] shouldIgnoreFile 检查: "${filePath}"`);
41636
- var e_10, _a;
42324
+ var e_14, _a;
41637
42325
  // 特殊处理:过滤掉特定的系统文件
41638
42326
  var fileName = filePath.split('/').pop() || '';
41639
42327
  if (fileName === '.dirty_files.json') {
@@ -41648,12 +42336,14 @@ var ShadowSpace = /** @class */ (function () {
41648
42336
  // 🔥 目录白名单检查:简化逻辑,允许 src/ 和 docs/ 下的所有文件
41649
42337
  var isInSrc = filePath.startsWith('src/');
41650
42338
  var isInDocs = filePath.startsWith('docs/');
41651
- var isRootConfig = filePath.match(/^[^\/]+\.(json|md|yml|yaml|toml|js|ts|py|go|rs)$/);
42339
+ var isRootConfig = filePath.match(/^[^/]+\.(json|md|yml|yaml|toml|js|ts|py|go|rs)$/);
41652
42340
  if (!isInSrc && !isInDocs && !isRootConfig) {
42341
+ logger("[ShadowSpace] \u6587\u4EF6\u4E0D\u5728\u767D\u540D\u5355\u76EE\u5F55\u4E2D: ".concat(filePath));
41653
42342
  return true;
41654
42343
  }
41655
42344
  // 特殊处理:不忽略其他 .json 文件(即使以 . 开头)
41656
42345
  if (filePath.endsWith('.json')) {
42346
+ logger("[ShadowSpace] JSON\u6587\u4EF6\u4E0D\u5FFD\u7565: ".concat(filePath));
41657
42347
  return false;
41658
42348
  }
41659
42349
  try {
@@ -41666,27 +42356,28 @@ var ShadowSpace = /** @class */ (function () {
41666
42356
  }
41667
42357
  }
41668
42358
  }
41669
- catch (e_10_1) { e_10 = { error: e_10_1 }; }
42359
+ catch (e_14_1) { e_14 = { error: e_14_1 }; }
41670
42360
  finally {
41671
42361
  try {
41672
42362
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
41673
42363
  }
41674
- finally { if (e_10) throw e_10.error; }
42364
+ finally { if (e_14) throw e_14.error; }
41675
42365
  }
41676
42366
  // 检查扩展名白名单
41677
42367
  if (this.config.includeExtensions &&
41678
42368
  this.config.includeExtensions.length > 0) {
41679
42369
  var ext = path__default["default"].extname(filePath).toLowerCase();
41680
42370
  if (!this.config.includeExtensions.includes(ext)) {
42371
+ logger("[ShadowSpace] \u6587\u4EF6\u6269\u5C55\u540D\u4E0D\u5728\u767D\u540D\u5355: ".concat(filePath, " -> ").concat(ext));
41681
42372
  return true;
41682
42373
  }
41683
42374
  }
41684
- // logger(`[ShadowSpace] 文件通过忽略检查: ${filePath}`);
42375
+ logger("[ShadowSpace] \u6587\u4EF6\u901A\u8FC7\u5FFD\u7565\u68C0\u67E5: ".concat(filePath));
41685
42376
  return false;
41686
42377
  };
41687
42378
  ShadowSpace.prototype.writeLocalFile = function (filePath, content) {
41688
42379
  return __awaiter(this, void 0, void 0, function () {
41689
- var fullPath, error_11;
42380
+ var fullPath, error_14;
41690
42381
  return __generator(this, function (_a) {
41691
42382
  switch (_a.label) {
41692
42383
  case 0:
@@ -41708,18 +42399,99 @@ var ShadowSpace = /** @class */ (function () {
41708
42399
  _a.sent();
41709
42400
  return [3 /*break*/, 5];
41710
42401
  case 4:
41711
- error_11 = _a.sent();
41712
- console.error("[ShadowSpace] \u6587\u4EF6\u5199\u5165\u5931\u8D25: ".concat(fullPath), error_11);
41713
- throw error_11;
42402
+ error_14 = _a.sent();
42403
+ console.error("[ShadowSpace] \u6587\u4EF6\u5199\u5165\u5931\u8D25: ".concat(fullPath), error_14);
42404
+ throw error_14;
41714
42405
  case 5: return [2 /*return*/];
41715
42406
  }
41716
42407
  });
41717
42408
  });
41718
42409
  };
42410
+ /**
42411
+ * 同步本地文件状态到内存和状态文件
42412
+ * (用于CLI独立运行时刷新状态)
42413
+ */
42414
+ ShadowSpace.prototype.syncLocalState = function () {
42415
+ return __awaiter(this, void 0, void 0, function () {
42416
+ var localFiles, snapshots, currentPaths, localFiles_2, localFiles_2_1, file, hash, entry, _a, _b, key;
42417
+ var e_15, _c, e_16, _d;
42418
+ return __generator(this, function (_e) {
42419
+ switch (_e.label) {
42420
+ case 0: return [4 /*yield*/, this.loadState()];
42421
+ case 1:
42422
+ _e.sent();
42423
+ return [4 /*yield*/, this.scanLocalFiles()];
42424
+ case 2:
42425
+ localFiles = _e.sent();
42426
+ snapshots = [];
42427
+ currentPaths = new Set();
42428
+ try {
42429
+ for (localFiles_2 = __values(localFiles), localFiles_2_1 = localFiles_2.next(); !localFiles_2_1.done; localFiles_2_1 = localFiles_2.next()) {
42430
+ file = localFiles_2_1.value;
42431
+ currentPaths.add(file.relativePath);
42432
+ hash = this.calculateHash(file.content);
42433
+ // Update state
42434
+ if (!this.state.files[file.relativePath]) {
42435
+ this.state.files[file.relativePath] = {
42436
+ path: file.relativePath,
42437
+ hash: hash,
42438
+ size: file.content.length,
42439
+ lastSyncTime: 0,
42440
+ lastModified: 0,
42441
+ version: 1,
42442
+ mtime: file.mtime,
42443
+ };
42444
+ }
42445
+ else {
42446
+ entry = this.state.files[file.relativePath];
42447
+ if (entry.hash !== hash || entry.mtime !== file.mtime) {
42448
+ entry.hash = hash;
42449
+ entry.mtime = file.mtime;
42450
+ }
42451
+ }
42452
+ snapshots.push({
42453
+ path: file.relativePath,
42454
+ hash: hash,
42455
+ modify: file.mtime,
42456
+ remoteHash: this.state.files[file.relativePath].remoteHash,
42457
+ });
42458
+ }
42459
+ }
42460
+ catch (e_15_1) { e_15 = { error: e_15_1 }; }
42461
+ finally {
42462
+ try {
42463
+ if (localFiles_2_1 && !localFiles_2_1.done && (_c = localFiles_2.return)) _c.call(localFiles_2);
42464
+ }
42465
+ finally { if (e_15) throw e_15.error; }
42466
+ }
42467
+ try {
42468
+ // Remove deleted files from state
42469
+ for (_a = __values(Object.keys(this.state.files)), _b = _a.next(); !_b.done; _b = _a.next()) {
42470
+ key = _b.value;
42471
+ if (!currentPaths.has(key)) {
42472
+ delete this.state.files[key];
42473
+ }
42474
+ }
42475
+ }
42476
+ catch (e_16_1) { e_16 = { error: e_16_1 }; }
42477
+ finally {
42478
+ try {
42479
+ if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
42480
+ }
42481
+ finally { if (e_16) throw e_16.error; }
42482
+ }
42483
+ return [4 /*yield*/, this.saveState()];
42484
+ case 3:
42485
+ _e.sent();
42486
+ return [2 /*return*/, snapshots];
42487
+ }
42488
+ });
42489
+ });
42490
+ };
41719
42491
  ShadowSpace.prototype.scanLocalFiles = function () {
41720
42492
  return __awaiter(this, void 0, void 0, function () {
41721
- var files, pattern, options, filePaths, filePaths_2, filePaths_2_1, filePath, fullPath, content, stats, error_12, e_11_1;
41722
- var e_11, _a;
42493
+ var files, pattern, options, globPromise, filePaths, filePaths_2, filePaths_2_1, filePath, fullPath, content, stats, error_15, e_17_1;
42494
+ var e_17, _a;
41723
42495
  return __generator(this, function (_b) {
41724
42496
  switch (_b.label) {
41725
42497
  case 0:
@@ -41730,52 +42502,55 @@ var ShadowSpace = /** @class */ (function () {
41730
42502
  ignore: this.config.ignorePatterns,
41731
42503
  nodir: true,
41732
42504
  };
41733
- filePaths = glob$1.glob.sync(pattern, options);
41734
- _b.label = 1;
42505
+ globPromise = util$3.promisify(glob__default["default"]);
42506
+ return [4 /*yield*/, globPromise(pattern, options)];
41735
42507
  case 1:
41736
- _b.trys.push([1, 9, 10, 11]);
41737
- filePaths_2 = __values(filePaths), filePaths_2_1 = filePaths_2.next();
42508
+ filePaths = _b.sent();
41738
42509
  _b.label = 2;
41739
42510
  case 2:
41740
- if (!!filePaths_2_1.done) return [3 /*break*/, 8];
41741
- filePath = filePaths_2_1.value;
41742
- if (this.shouldIgnoreFile(filePath))
41743
- return [3 /*break*/, 7];
42511
+ _b.trys.push([2, 10, 11, 12]);
42512
+ filePaths_2 = __values(filePaths), filePaths_2_1 = filePaths_2.next();
41744
42513
  _b.label = 3;
41745
42514
  case 3:
41746
- _b.trys.push([3, 6, , 7]);
42515
+ if (!!filePaths_2_1.done) return [3 /*break*/, 9];
42516
+ filePath = filePaths_2_1.value;
42517
+ if (this.shouldIgnoreFile(filePath))
42518
+ return [3 /*break*/, 8];
42519
+ _b.label = 4;
42520
+ case 4:
42521
+ _b.trys.push([4, 7, , 8]);
41747
42522
  fullPath = path__default["default"].join(this.config.projectRoot, filePath);
41748
42523
  return [4 /*yield*/, fs__default$1["default"].readFile(fullPath, 'utf8')];
41749
- case 4:
42524
+ case 5:
41750
42525
  content = _b.sent();
41751
42526
  return [4 /*yield*/, fs__default$1["default"].stat(fullPath)];
41752
- case 5:
42527
+ case 6:
41753
42528
  stats = _b.sent();
41754
42529
  files.push({
41755
42530
  relativePath: filePath,
41756
42531
  content: content,
41757
42532
  mtime: stats.mtime.getTime(),
41758
42533
  });
41759
- return [3 /*break*/, 7];
41760
- case 6:
41761
- error_12 = _b.sent();
41762
- console.warn("\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25: ".concat(filePath), error_12);
41763
- return [3 /*break*/, 7];
42534
+ return [3 /*break*/, 8];
41764
42535
  case 7:
42536
+ error_15 = _b.sent();
42537
+ console.warn("\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25: ".concat(filePath), error_15);
42538
+ return [3 /*break*/, 8];
42539
+ case 8:
41765
42540
  filePaths_2_1 = filePaths_2.next();
41766
- return [3 /*break*/, 2];
41767
- case 8: return [3 /*break*/, 11];
41768
- case 9:
41769
- e_11_1 = _b.sent();
41770
- e_11 = { error: e_11_1 };
41771
- return [3 /*break*/, 11];
42541
+ return [3 /*break*/, 3];
42542
+ case 9: return [3 /*break*/, 12];
41772
42543
  case 10:
42544
+ e_17_1 = _b.sent();
42545
+ e_17 = { error: e_17_1 };
42546
+ return [3 /*break*/, 12];
42547
+ case 11:
41773
42548
  try {
41774
42549
  if (filePaths_2_1 && !filePaths_2_1.done && (_a = filePaths_2.return)) _a.call(filePaths_2);
41775
42550
  }
41776
- finally { if (e_11) throw e_11.error; }
42551
+ finally { if (e_17) throw e_17.error; }
41777
42552
  return [7 /*endfinally*/];
41778
- case 11: return [2 /*return*/, files];
42553
+ case 12: return [2 /*return*/, files];
41779
42554
  }
41780
42555
  });
41781
42556
  });
@@ -41817,20 +42592,33 @@ var ShadowSpace = /** @class */ (function () {
41817
42592
  };
41818
42593
  ShadowSpace.prototype.loadState = function () {
41819
42594
  return __awaiter(this, void 0, void 0, function () {
41820
- var content;
42595
+ var content, error_16;
41821
42596
  return __generator(this, function (_a) {
41822
42597
  switch (_a.label) {
41823
42598
  case 0:
41824
- _a.trys.push([0, 2, , 3]);
42599
+ _a.trys.push([0, 2, , 6]);
41825
42600
  return [4 /*yield*/, fs__default$1["default"].readFile(this.stateFile, 'utf8')];
41826
42601
  case 1:
41827
42602
  content = _a.sent();
41828
42603
  this.state = __assign(__assign({}, this.state), JSON.parse(content));
41829
- return [3 /*break*/, 3];
42604
+ return [3 /*break*/, 6];
41830
42605
  case 2:
42606
+ error_16 = _a.sent();
42607
+ if (!(error_16.code === 'ENOENT')) return [3 /*break*/, 4];
42608
+ logger('影子空间状态文件不存在,使用默认状态');
42609
+ // Ensure directory exists for future saves
42610
+ // 使用 ensureDir 确保整个路径存在,包括 .appthen
42611
+ return [4 /*yield*/, fs__default$1["default"].ensureDir(path__default["default"].dirname(this.stateFile))];
42612
+ case 3:
42613
+ // Ensure directory exists for future saves
42614
+ // 使用 ensureDir 确保整个路径存在,包括 .appthen
41831
42615
  _a.sent();
41832
- return [3 /*break*/, 3];
41833
- case 3: return [2 /*return*/];
42616
+ return [3 /*break*/, 5];
42617
+ case 4:
42618
+ console.warn('[ShadowSpace] 读取状态文件失败:', error_16);
42619
+ _a.label = 5;
42620
+ case 5: return [3 /*break*/, 6];
42621
+ case 6: return [2 /*return*/];
41834
42622
  }
41835
42623
  });
41836
42624
  });
@@ -41841,100 +42629,13 @@ var ShadowSpace = /** @class */ (function () {
41841
42629
  var k = 1024;
41842
42630
  var sizes = ['B', 'KB', 'MB', 'GB'];
41843
42631
  var i = Math.floor(Math.log(bytes) / Math.log(k));
41844
- return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
41845
- };
41846
- // ==================== 🆕 文件监听功能 ====================
41847
- /**
41848
- * 启动文件监听
41849
- */
41850
- ShadowSpace.prototype.startWatching = function () {
41851
- if (this.isWatching) {
41852
- return;
41853
- }
41854
- logger('[ShadowSpace] 监听目录:', this.config.projectRoot);
41855
- try {
41856
- // 🔥 使用轮询模式 + ignored 函数过滤
41857
- // this.watcher = chokidar.watch(this.config.projectRoot, {
41858
- // ignored: (filePath: string) => {
41859
- // const relativePath = path.relative(this.config.projectRoot, filePath);
41860
- // // 忽略根目录本身
41861
- // if (!relativePath || relativePath === '.') {
41862
- // return true;
41863
- // }
41864
- // // 使用白名单过滤
41865
- // return this.shouldIgnoreFile(relativePath);
41866
- // },
41867
- // persistent: true,
41868
- // ignoreInitial: true, // 忽略初始扫描
41869
- // usePolling: true, // 🔥 macOS 上使用轮询模式(fsevents 在某些环境下不可靠)
41870
- // interval: 2000, // 轮询间隔 2 秒(降低 CPU 占用)
41871
- // binaryInterval: 3000, // 二进制文件轮询间隔 3 秒
41872
- // depth: 99, // 监听所有子目录
41873
- // awaitWriteFinish: {
41874
- // stabilityThreshold: 500, // 文件稳定后 500ms 才触发
41875
- // pollInterval: 100,
41876
- // },
41877
- // });
41878
- logger('[ShadowSpace] chokidar.watch 已调用,等待 ready 事件...');
41879
- }
41880
- catch (error) {
41881
- console.error('[ShadowSpace] 创建文件监听器失败:', error);
41882
- return;
41883
- }
41884
- // this.watcher
41885
- // .on('change', (filePath: string) => {
41886
- // this.onFileChanged(filePath);
41887
- // })
41888
- // .on('add', (filePath: string) => {
41889
- // this.onFileAdded(filePath);
41890
- // })
41891
- // .on('unlink', (filePath: string) => {
41892
- // this.onFileDeleted(filePath);
41893
- // })
41894
- // .on('error', (error) => {
41895
- // console.error('[ShadowSpace] 文件监听错误:', error);
41896
- // })
41897
- // .on('ready', () => {
41898
- // this.isWatching = true;
41899
- // logger(
41900
- // '[ShadowSpace] 文件监听已启动,正在监听:',
41901
- // this.config.projectRoot
41902
- // );
41903
- // logger('[ShadowSpace] 监听配置: 轮询模式 (interval: 2s)');
41904
- // });
41905
- };
41906
- /**
41907
- * 停止文件监听
41908
- */
41909
- ShadowSpace.prototype.stopWatching = function () {
41910
- return __awaiter(this, void 0, void 0, function () {
41911
- return __generator(this, function (_a) {
41912
- if (!this.isWatching || !this.watcher) {
41913
- return [2 /*return*/];
41914
- }
41915
- // await this.watcher.close();
41916
- this.watcher = null;
41917
- this.isWatching = false;
41918
- return [2 /*return*/];
41919
- });
41920
- });
41921
- };
41922
- /**
41923
- * 添加变更事件监听器
41924
- */
41925
- ShadowSpace.prototype.addChangeListener = function (listener) {
41926
- this.changeListeners.add(listener);
41927
- };
41928
- /**
41929
- * 移除变更事件监听器
41930
- */
41931
- ShadowSpace.prototype.removeChangeListener = function (listener) {
41932
- this.changeListeners.delete(listener);
42632
+ return "".concat(parseFloat((bytes / Math.pow(k, i)).toFixed(2)), " ").concat(sizes[i]);
41933
42633
  };
41934
42634
  /**
41935
42635
  * 触发变更事件
41936
42636
  */
41937
42637
  ShadowSpace.prototype.emitChangeEvent = function (event) {
42638
+ logger('[ShadowSpace] 触发变更事件:', event);
41938
42639
  this.changeListeners.forEach(function (listener) {
41939
42640
  try {
41940
42641
  listener(event);
@@ -41949,13 +42650,15 @@ var ShadowSpace = /** @class */ (function () {
41949
42650
  */
41950
42651
  ShadowSpace.prototype.onFileChanged = function (filePath) {
41951
42652
  return __awaiter(this, void 0, void 0, function () {
41952
- var relativePath, shadowEntry, content, hash, stats, error_14;
42653
+ var relativePath, shadowEntry, content, hash, stats, error_17;
41953
42654
  return __generator(this, function (_a) {
41954
42655
  switch (_a.label) {
41955
42656
  case 0:
41956
42657
  relativePath = path__default["default"].relative(this.config.projectRoot, filePath);
42658
+ logger("[ShadowSpace] \u68C0\u6D4B\u5230\u6587\u4EF6\u53D8\u66F4: ".concat(relativePath));
41957
42659
  shadowEntry = this.state.files[relativePath];
41958
42660
  if (!(shadowEntry === null || shadowEntry === void 0 ? void 0 : shadowEntry.remoteModified)) return [3 /*break*/, 2];
42661
+ logger("[ShadowSpace] \u8DF3\u8FC7\u8FDC\u7A0B\u4FEE\u6539\u7684\u6587\u4EF6: ".concat(relativePath));
41959
42662
  shadowEntry.remoteModified = false; // 清除标记
41960
42663
  return [4 /*yield*/, this.saveState()];
41961
42664
  case 1:
@@ -41981,8 +42684,8 @@ var ShadowSpace = /** @class */ (function () {
41981
42684
  });
41982
42685
  return [3 /*break*/, 6];
41983
42686
  case 5:
41984
- error_14 = _a.sent();
41985
- console.error("[ShadowSpace] \u5904\u7406\u6587\u4EF6\u53D8\u66F4\u5931\u8D25: ".concat(relativePath), error_14);
42687
+ error_17 = _a.sent();
42688
+ console.error("[ShadowSpace] \u5904\u7406\u6587\u4EF6\u53D8\u66F4\u5931\u8D25: ".concat(relativePath), error_17);
41986
42689
  return [3 /*break*/, 6];
41987
42690
  case 6: return [2 /*return*/];
41988
42691
  }
@@ -41994,11 +42697,12 @@ var ShadowSpace = /** @class */ (function () {
41994
42697
  */
41995
42698
  ShadowSpace.prototype.onFileAdded = function (filePath) {
41996
42699
  return __awaiter(this, void 0, void 0, function () {
41997
- var relativePath, content, hash, stats, error_15;
42700
+ var relativePath, content, hash, stats, error_18;
41998
42701
  return __generator(this, function (_a) {
41999
42702
  switch (_a.label) {
42000
42703
  case 0:
42001
42704
  relativePath = path__default["default"].relative(this.config.projectRoot, filePath);
42705
+ logger("[ShadowSpace] \u68C0\u6D4B\u5230\u6587\u4EF6\u65B0\u589E: ".concat(relativePath));
42002
42706
  _a.label = 1;
42003
42707
  case 1:
42004
42708
  _a.trys.push([1, 4, , 5]);
@@ -42020,8 +42724,8 @@ var ShadowSpace = /** @class */ (function () {
42020
42724
  });
42021
42725
  return [3 /*break*/, 5];
42022
42726
  case 4:
42023
- error_15 = _a.sent();
42024
- console.error("[ShadowSpace] \u5904\u7406\u6587\u4EF6\u65B0\u589E\u5931\u8D25: ".concat(relativePath), error_15);
42727
+ error_18 = _a.sent();
42728
+ console.error("[ShadowSpace] \u5904\u7406\u6587\u4EF6\u65B0\u589E\u5931\u8D25: ".concat(relativePath), error_18);
42025
42729
  return [3 /*break*/, 5];
42026
42730
  case 5: return [2 /*return*/];
42027
42731
  }
@@ -42038,8 +42742,10 @@ var ShadowSpace = /** @class */ (function () {
42038
42742
  switch (_a.label) {
42039
42743
  case 0:
42040
42744
  relativePath = path__default["default"].relative(this.config.projectRoot, filePath);
42745
+ logger("[ShadowSpace] \u68C0\u6D4B\u5230\u6587\u4EF6\u5220\u9664: ".concat(relativePath));
42041
42746
  shadowEntry = this.state.files[relativePath];
42042
42747
  if (!(shadowEntry === null || shadowEntry === void 0 ? void 0 : shadowEntry.remoteModified)) return [3 /*break*/, 2];
42748
+ logger("[ShadowSpace] \u8DF3\u8FC7\u8FDC\u7A0B\u5220\u9664\u7684\u6587\u4EF6: ".concat(relativePath));
42043
42749
  shadowEntry.remoteModified = false; // 清除标记
42044
42750
  return [4 /*yield*/, this.saveState()];
42045
42751
  case 1:
@@ -42058,12 +42764,6 @@ var ShadowSpace = /** @class */ (function () {
42058
42764
  });
42059
42765
  });
42060
42766
  };
42061
- /**
42062
- * 获取监听状态
42063
- */
42064
- ShadowSpace.prototype.isFileWatching = function () {
42065
- return this.isWatching;
42066
- };
42067
42767
  return ShadowSpace;
42068
42768
  }());
42069
42769
 
@@ -42316,22 +43016,7 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
42316
43016
  changes = _a.sent();
42317
43017
  result = {
42318
43018
  spaceId: this.shadowSpace.getSpaceInfo().spaceId,
42319
- changes: changes.map(function (change) { return ({
42320
- id: change.id,
42321
- action: change.action,
42322
- path: change.path,
42323
- version: change.version,
42324
- timestamp: change.timestamp,
42325
- hasContent: !!change.diff.before || !!change.diff.after,
42326
- size: {
42327
- before: change.diff.before
42328
- ? Buffer.byteLength(change.diff.before, 'utf8')
42329
- : 0,
42330
- after: change.diff.after
42331
- ? Buffer.byteLength(change.diff.after, 'utf8')
42332
- : 0,
42333
- },
42334
- }); }),
43019
+ changes: changes,
42335
43020
  summary: {
42336
43021
  total: changes.length,
42337
43022
  added: changes.filter(function (c) { return c.action === 'add'; }).length,
@@ -42853,7 +43538,7 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
42853
43538
  // `[ShadowSpace] 开始检测变更: 空间=${spaceId}, 编辑器文件=${safeEditorSnapshots.length}个`
42854
43539
  // );
42855
43540
  // 1. 🔥 先检测本地文件变更,更新影子空间状态,并获取本地变更列表(包括新增文件)
42856
- console.log("\n\uD83D\uDD0D [DEBUG] \u6B63\u5728\u68C0\u6D4B\u672C\u5730\u6587\u4EF6\u53D8\u66F4...");
43541
+ console.log('\n🔍 [DEBUG] 正在检测本地文件变更...');
42857
43542
  return [4 /*yield*/, this.shadowSpace.detectChanges()];
42858
43543
  case 1:
42859
43544
  localChanges = _a.sent();
@@ -42865,7 +43550,7 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
42865
43550
  spaceSnapshots = _a.sent();
42866
43551
  console.log("\uD83D\uDD0D [DEBUG] getSpaceSnapshots \u8FD4\u56DE\u7ED3\u679C\u7C7B\u578B: ".concat(typeof spaceSnapshots));
42867
43552
  console.log("\uD83D\uDD0D [DEBUG] getSpaceSnapshots \u662F\u5426\u4E3A\u6570\u7EC4: ".concat(Array.isArray(spaceSnapshots)));
42868
- console.log("\uD83D\uDD0D [DEBUG] getSpaceSnapshots \u539F\u59CB\u7ED3\u679C:", spaceSnapshots);
43553
+ console.log('🔍 [DEBUG] getSpaceSnapshots 原始结果:', spaceSnapshots);
42869
43554
  // 🔍 友好的调试输出
42870
43555
  console.log('\n=== 影子空间变更检测调试 ===');
42871
43556
  console.log('📁 空间ID:', spaceId);
@@ -42874,19 +43559,19 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
42874
43559
  spaceInfo = this.shadowSpace.getSpaceInfo();
42875
43560
  console.log('\n🏠 影子空间信息:');
42876
43561
  console.log(" \uD83D\uDCC2 \u9879\u76EE\u6839\u76EE\u5F55: ".concat(spaceInfo.projectRoot));
42877
- console.log(" \uD83D\uDCC1 \u7A7A\u95F4\u76EE\u5F55: ".concat(spaceInfo.spaceRoot));
43562
+ // console.log(` 📁 空间目录: ${spaceInfo.spaceRoot}`); // 属性不存在,注释掉
42878
43563
  console.log(" \uD83D\uDCCA \u6587\u4EF6\u6570\u91CF: ".concat(spaceInfo.fileCount));
42879
43564
  console.log(" \uD83D\uDCE6 \u603B\u5927\u5C0F: ".concat(spaceInfo.totalSize));
42880
43565
  console.log(" \uD83C\uDD94 \u7528\u6237ID: ".concat(spaceInfo.userId));
42881
43566
  console.log(" \u23F0 \u521B\u5EFA\u65F6\u95F4: ".concat(spaceInfo.createdAt));
42882
- console.log(" \u23F0 \u66F4\u65B0\u65F6\u95F4: ".concat(spaceInfo.updatedAt));
43567
+ console.log(" \u23F0 \u66F4\u65B0\u65F6\u95F4: ".concat(spaceInfo.lastUpdate)); // 修正属性名
42883
43568
  require('path');
42884
43569
  fs = require('fs-extra');
42885
- spaceDir = spaceInfo.spaceRoot;
43570
+ spaceDir = spaceInfo.projectRoot;
42886
43571
  return [4 /*yield*/, fs.pathExists(spaceDir)];
42887
43572
  case 3:
42888
43573
  spaceExists = _a.sent();
42889
- console.log("\n\uD83D\uDCC1 \u7A7A\u95F4\u76EE\u5F55\u68C0\u67E5:");
43574
+ console.log('\n📁 空间目录检查:');
42890
43575
  console.log(" \uD83D\uDCC2 \u8DEF\u5F84: ".concat(spaceDir));
42891
43576
  console.log(" \u2705 \u662F\u5426\u5B58\u5728: ".concat(spaceExists));
42892
43577
  if (!spaceExists) return [3 /*break*/, 7];
@@ -42951,7 +43636,7 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
42951
43636
  }); });
42952
43637
  console.log("\uD83D\uDD0D [DEBUG] \u672C\u5730\u65B0\u589E\u6587\u4EF6\u6570\u91CF: ".concat(localAddChanges.length));
42953
43638
  if (localAddChanges.length > 0) {
42954
- console.log("\uD83D\uDD0D [DEBUG] \u672C\u5730\u65B0\u589E\u6587\u4EF6\u5217\u8868:", localAddChanges.map(function (c) { return c.path; }));
43639
+ console.log('🔍 [DEBUG] 本地新增文件列表:', localAddChanges.map(function (c) { return c.path; }));
42955
43640
  }
42956
43641
  changes = __spreadArray(__spreadArray([], __read(snapshotChanges), false), __read(localAddChanges), false);
42957
43642
  summary = {
@@ -43023,18 +43708,29 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
43023
43708
  ShadowSpaceCommandHandler.prototype.compareSnapshots = function (editorSnapshots, spaceSnapshots) {
43024
43709
  var _a, _b;
43025
43710
  return __awaiter(this, void 0, void 0, function () {
43026
- var changes, safeEditorSnapshots, safeSpaceSnapshots, editorMap, spaceMap, editorMap_1, editorMap_1_1, _c, path, editorFile, spaceFile, editorModify, spaceModify, spaceMap_1, spaceMap_1_1, _d, path, spaceFile, editorFile;
43711
+ var changes, normalizePath, safeEditorSnapshots, safeSpaceSnapshots, editorMap, spaceMap, editorMap_1, editorMap_1_1, _c, path, editorFile, spaceFile, editorModify, spaceModify, spaceMap_1, spaceMap_1_1, _d, path, spaceFile, editorFile;
43027
43712
  var e_2, _e, e_3, _f;
43028
43713
  return __generator(this, function (_g) {
43029
43714
  changes = [];
43715
+ normalizePath = function (p) {
43716
+ // 统一替换反斜杠为正斜杠
43717
+ var normalized = p.replace(/\\/g, '/');
43718
+ // 去除开头的 ./
43719
+ if (normalized.startsWith('./'))
43720
+ normalized = normalized.substring(2);
43721
+ // 去除开头的 /
43722
+ if (normalized.startsWith('/'))
43723
+ normalized = normalized.substring(1);
43724
+ return normalized;
43725
+ };
43030
43726
  safeEditorSnapshots = Array.isArray(editorSnapshots)
43031
43727
  ? editorSnapshots
43032
43728
  : [];
43033
43729
  safeSpaceSnapshots = Array.isArray(spaceSnapshots)
43034
43730
  ? spaceSnapshots
43035
43731
  : [];
43036
- editorMap = new Map(safeEditorSnapshots.map(function (f) { return [f.path, f]; }));
43037
- spaceMap = new Map(safeSpaceSnapshots.map(function (f) { return [f.path, f]; }));
43732
+ editorMap = new Map(safeEditorSnapshots.map(function (f) { return [normalizePath(f.path), f]; }));
43733
+ spaceMap = new Map(safeSpaceSnapshots.map(function (f) { return [normalizePath(f.path), f]; }));
43038
43734
  try {
43039
43735
  // 检测编辑器的变更(新增、修改)
43040
43736
  for (editorMap_1 = __values(editorMap), editorMap_1_1 = editorMap_1.next(); !editorMap_1_1.done; editorMap_1_1 = editorMap_1.next()) {
@@ -43042,6 +43738,10 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
43042
43738
  spaceFile = spaceMap.get(path);
43043
43739
  if (!spaceFile) {
43044
43740
  // 编辑器新增的文件 → 推送到空间
43741
+ // 🔥 调试:打印路径标准化情况
43742
+ if (path.includes('TicketHistory')) {
43743
+ console.log("[ShadowSpace] \u68C0\u6D4B\u5230\u7F16\u8F91\u5668\u65B0\u589E: \"".concat(path, "\" (Original: \"").concat(editorFile.path, "\")"));
43744
+ }
43045
43745
  changes.push({
43046
43746
  action: 'add',
43047
43747
  path: path,
@@ -43065,8 +43765,8 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
43065
43765
  });
43066
43766
  // 🔥 关键逻辑:根据时间戳判断方向
43067
43767
  if (editorModify > spaceModify) {
43068
- // 编辑器更新 → 推送到空间
43069
- console.log("[ShadowSpace] \u2192 \u7F16\u8F91\u5668\u66F4\u65B0\uFF0C\u9700\u8981\u63A8\u9001: ".concat(path));
43768
+ // 编辑器更新 → 推送到空间 (Remote -> Local) => Pull
43769
+ console.log("[ShadowSpace] \u2B07\uFE0F \u8FDC\u7AEF\u66F4\u65B0 (\u9700\u62C9\u53D6): ".concat(path));
43070
43770
  changes.push({
43071
43771
  action: 'modify',
43072
43772
  path: path,
@@ -50082,6 +50782,146 @@ function getToolName(tool) {
50082
50782
  return toolChoice ? toolChoice.name : tool;
50083
50783
  }
50084
50784
 
50785
+ function startShadowSync(options) {
50786
+ return __awaiter(this, void 0, void 0, function () {
50787
+ var userId, config, shadowSpace, result, changes, changes_1, changes_1_1, change, action, filePath, side, direction, content, remoteHash, content, err_1, e_1_1, error_1;
50788
+ var e_1, _a;
50789
+ return __generator(this, function (_b) {
50790
+ switch (_b.label) {
50791
+ case 0:
50792
+ // Set auth token globally for request utils
50793
+ updateAuthToken(options.authToken);
50794
+ userId = options.userId || 'unknown-user';
50795
+ config = {
50796
+ projectRoot: options.cwd ? path__default["default"].resolve(options.cwd) : process.cwd(),
50797
+ projectId: options.projectId,
50798
+ userId: userId,
50799
+ spaceId: options.spaceId || 'default',
50800
+ };
50801
+ shadowSpace = new ShadowSpace(config);
50802
+ if (options.verbose) {
50803
+ console.log('Starting shadow sync...');
50804
+ console.log("Project ID: ".concat(config.projectId));
50805
+ console.log("Space ID: ".concat(config.spaceId));
50806
+ console.log("User ID: ".concat(config.userId));
50807
+ }
50808
+ _b.label = 1;
50809
+ case 1:
50810
+ _b.trys.push([1, 26, , 27]);
50811
+ // 使用抽象后的通用同步逻辑
50812
+ // 调用 syncWithRemote({ dryRun: true }) 获取变更
50813
+ // 然后复用 ShadowSpace 的公共方法进行处理
50814
+ console.log('Checking for changes...');
50815
+ return [4 /*yield*/, shadowSpace.syncWithRemote({ dryRun: true })];
50816
+ case 2:
50817
+ result = _b.sent();
50818
+ changes = result.changes;
50819
+ if (!(changes.length === 0)) return [3 /*break*/, 3];
50820
+ console.log('Everything is up to date.');
50821
+ return [3 /*break*/, 25];
50822
+ case 3:
50823
+ console.log("Found ".concat(changes.length, " changes."));
50824
+ _b.label = 4;
50825
+ case 4:
50826
+ _b.trys.push([4, 21, 22, 23]);
50827
+ changes_1 = __values(changes), changes_1_1 = changes_1.next();
50828
+ _b.label = 5;
50829
+ case 5:
50830
+ if (!!changes_1_1.done) return [3 /*break*/, 20];
50831
+ change = changes_1_1.value;
50832
+ action = change.action, filePath = change.path, side = change.side;
50833
+ direction = side === 'editor' ? 'Remote->Local (Pull)' : 'Local->Remote (Push)';
50834
+ console.log("Processing ".concat(action, " ").concat(filePath, " (").concat(direction, ")..."));
50835
+ _b.label = 6;
50836
+ case 6:
50837
+ _b.trys.push([6, 18, , 19]);
50838
+ if (!(side === 'editor')) return [3 /*break*/, 14];
50839
+ if (!(action === 'delete')) return [3 /*break*/, 8];
50840
+ return [4 /*yield*/, shadowSpace.deleteFile(filePath)];
50841
+ case 7:
50842
+ _b.sent();
50843
+ console.log("Deleted local file: ".concat(filePath));
50844
+ return [3 /*break*/, 13];
50845
+ case 8: return [4 /*yield*/, shadowSpace.downloadRemoteFile(filePath)];
50846
+ case 9:
50847
+ content = _b.sent();
50848
+ remoteHash = change.editorHash;
50849
+ if (!remoteHash) return [3 /*break*/, 11];
50850
+ return [4 /*yield*/, shadowSpace.updateFileFromRemote(filePath, content, remoteHash)];
50851
+ case 10:
50852
+ _b.sent();
50853
+ console.log("Updated local file: ".concat(filePath, " (with remoteHash)"));
50854
+ return [3 /*break*/, 13];
50855
+ case 11: return [4 /*yield*/, shadowSpace.updateFile(filePath, content)];
50856
+ case 12:
50857
+ _b.sent();
50858
+ console.log("Updated local file: ".concat(filePath));
50859
+ _b.label = 13;
50860
+ case 13: return [3 /*break*/, 17];
50861
+ case 14:
50862
+ if (!(side === 'space')) return [3 /*break*/, 17];
50863
+ if (!(action === 'delete')) return [3 /*break*/, 15];
50864
+ console.warn("Skipping remote delete for: ".concat(filePath, " (Not supported)"));
50865
+ return [3 /*break*/, 17];
50866
+ case 15: return [4 /*yield*/, shadowSpace.getShadowContent(filePath)];
50867
+ case 16:
50868
+ content = _b.sent();
50869
+ if (content !== null) {
50870
+ // DryRun for Push
50871
+ console.log("[DryRun] Would upload remote file: ".concat(filePath));
50872
+ // 注意:在 DryRun 模式下,我们不能更新 remoteHash,因为没有真实上传,
50873
+ // 远端的 Hash 依然是旧的。如果现在更新了 remoteHash,下次比对就会出错。
50874
+ // 所以这里什么都不做。
50875
+ }
50876
+ else {
50877
+ console.error("Failed to read local content for: ".concat(filePath));
50878
+ }
50879
+ _b.label = 17;
50880
+ case 17: return [3 /*break*/, 19];
50881
+ case 18:
50882
+ err_1 = _b.sent();
50883
+ console.error("Failed to process ".concat(filePath, ":"), err_1);
50884
+ return [3 /*break*/, 19];
50885
+ case 19:
50886
+ changes_1_1 = changes_1.next();
50887
+ return [3 /*break*/, 5];
50888
+ case 20: return [3 /*break*/, 23];
50889
+ case 21:
50890
+ e_1_1 = _b.sent();
50891
+ e_1 = { error: e_1_1 };
50892
+ return [3 /*break*/, 23];
50893
+ case 22:
50894
+ try {
50895
+ if (changes_1_1 && !changes_1_1.done && (_a = changes_1.return)) _a.call(changes_1);
50896
+ }
50897
+ finally { if (e_1) throw e_1.error; }
50898
+ return [7 /*endfinally*/];
50899
+ case 23:
50900
+ // Save state after sync
50901
+ return [4 /*yield*/, shadowSpace.saveState()];
50902
+ case 24:
50903
+ // Save state after sync
50904
+ _b.sent();
50905
+ _b.label = 25;
50906
+ case 25: return [3 /*break*/, 27];
50907
+ case 26:
50908
+ error_1 = _b.sent();
50909
+ console.error('Shadow sync failed:', error_1);
50910
+ process.exit(1);
50911
+ return [3 /*break*/, 27];
50912
+ case 27:
50913
+ if (options.watch) {
50914
+ shadowSpace.startWatching();
50915
+ console.log('Watching for file changes...');
50916
+ // Keep process alive
50917
+ return [2 /*return*/, new Promise(function () { })];
50918
+ }
50919
+ return [2 /*return*/];
50920
+ }
50921
+ });
50922
+ });
50923
+ }
50924
+
50085
50925
  exports.ShadowSpace = ShadowSpace;
50086
50926
  exports.ShadowSpaceDebugger = ShadowSpaceDebugger;
50087
50927
  exports.TSXComplianceChecker = TSXComplianceChecker;
@@ -50106,6 +50946,7 @@ exports.releaseMaterial = releaseMaterial;
50106
50946
  exports.run = run;
50107
50947
  exports.startConnecting = startConnecting;
50108
50948
  exports.startProxy = startProxy;
50949
+ exports.startShadowSync = startShadowSync;
50109
50950
  exports.startWatching = startWatching;
50110
50951
  exports.stopConnecting = stopConnecting;
50111
50952
  exports.stopProxy = stopProxy;