niuma-codex 0.0.1-beta.22 → 0.0.1-beta.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -378,6 +378,7 @@ var init_app_bundle = __esm({
378
378
 
379
379
  // apps/desktop/src/autostart/manager.ts
380
380
  import fs4 from "node:fs";
381
+ import { isDeepStrictEqual } from "node:util";
381
382
  import fsp2 from "node:fs/promises";
382
383
  import path4 from "node:path";
383
384
  import os from "node:os";
@@ -553,7 +554,7 @@ var init_manager = __esm({
553
554
  await privateDirectory(this.root);
554
555
  const release2 = acquire(path4.join(this.root, "operation.lock"));
555
556
  const snapshot2 = async () => {
556
- if (await readJson(this.root + "/transaction.json")) throw new AutostartError(900615, "npm \u81EA\u542F\u52A8\u6709\u672A\u5B8C\u6210\u4E8B\u52A1\uFF0C\u8BF7\u5148\u4FEE\u590D");
557
+ if (!await this.finishSettledTransaction()) throw new AutostartError(900615, "npm \u81EA\u542F\u52A8\u6709\u672A\u5B8C\u6210\u4E8B\u52A1\uFF0C\u8BF7\u5148\u4FEE\u590D");
557
558
  const registration = await readJson(this.metadata);
558
559
  const status2 = await this.status();
559
560
  const fingerprint2 = createHash2("sha256").update(JSON.stringify({ registration, loaded: status2.loaded, available: status2.available })).digest("hex");
@@ -616,8 +617,28 @@ var init_manager = __esm({
616
617
  if (status2.operation?.state === "failed") throw new AutostartError(status2.operation.code, status2.operation.message);
617
618
  return status2;
618
619
  }
620
+ /** 调用者持有 operation.lock;仅收尾已恢复的同配置原生登记,不改变系统开关。 */
621
+ async finishSettledTransaction() {
622
+ const file = path4.join(this.root, "transaction.json");
623
+ const t2 = await readJson(file);
624
+ if (!t2) return true;
625
+ const previous = t2.previous;
626
+ if (t2.owner !== "niuma-autostart-v1" || !previous || previous.owner !== "niuma-autostart-v1" || previous.service !== "application-agent" || !previous.appPath || (t2.wasRegistered ?? t2.wasLoaded) !== true || !isDeepStrictEqual(previous, t2.next) || !isDeepStrictEqual(previous, await readJson(this.metadata))) return false;
627
+ try {
628
+ await fsp2.lstat(this.plist);
629
+ return false;
630
+ } catch (e) {
631
+ if (e.code !== "ENOENT") throw e;
632
+ }
633
+ const state = await this.registrationState(previous);
634
+ if (state !== 1 && state !== 2) return false;
635
+ if (!isDeepStrictEqual(t2, await readJson(file))) return false;
636
+ await fsp2.rm(file);
637
+ return true;
638
+ }
619
639
  /** 注册文件和元数据的两次写入由恢复记录覆盖,崩溃后只恢复可证明自有的内容。 */
620
640
  async recoverTransaction() {
641
+ if (await this.finishSettledTransaction()) return;
621
642
  const file = path4.join(this.root, "transaction.json");
622
643
  const transaction = await readJson(file);
623
644
  if (!transaction) return;
@@ -677,7 +698,7 @@ var init_manager = __esm({
677
698
  const appPath = await prepareAutostartApp(this.root, config, installed.entryPath);
678
699
  await this.options.guard?.();
679
700
  next = { owner: "niuma-autostart-v1", service: "application-agent", config, entryPath: installed.entryPath, appPath, plist: renderLaunchAgent(config, installed.entryPath, this.root, true) };
680
- if (reusable && previous.service === next.service && previous.appPath === appPath && previous.plist === next.plist) {
701
+ if ((reusable || priorState === 2) && isDeepStrictEqual(previous, next)) {
681
702
  await this.run(LSREGISTER, ["-f", appPath]);
682
703
  return;
683
704
  }
@@ -10232,7 +10253,7 @@ var init_src = __esm({
10232
10253
  // apps/desktop/src/release-version.ts
10233
10254
  import { readFileSync } from "node:fs";
10234
10255
  function desktopReleaseVersion() {
10235
- return false ? null : "0.0.1-beta.22";
10256
+ return false ? null : "0.0.1-beta.23";
10236
10257
  }
10237
10258
  function desktopPresenceVersion() {
10238
10259
  return desktopReleaseVersion() ?? sourcePresenceVersion;
@@ -15579,7 +15600,7 @@ var init_project_list_stream = __esm({
15579
15600
  });
15580
15601
 
15581
15602
  // apps/desktop/src/daemon/thread-projection-publisher.ts
15582
- import { isDeepStrictEqual } from "node:util";
15603
+ import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
15583
15604
  function clone2(value) {
15584
15605
  return structuredClone(value);
15585
15606
  }
@@ -15608,7 +15629,7 @@ function changesBetween(previous, next) {
15608
15629
  ];
15609
15630
  for (const key of keys3) {
15610
15631
  if (key === "execution" && next.execution === void 0) continue;
15611
- if (!isDeepStrictEqual(previous[key], next[key])) {
15632
+ if (!isDeepStrictEqual2(previous[key], next[key])) {
15612
15633
  changes[key] = clone2(next[key]);
15613
15634
  }
15614
15635
  }
@@ -15620,9 +15641,9 @@ function createThreadViewPatch(previous, next) {
15620
15641
  const nextItems = itemMap(next.items);
15621
15642
  const previousProcessGroups = processGroupMap(previous.process_groups);
15622
15643
  const nextProcessGroups = processGroupMap(next.process_groups);
15623
- const upsertItems = next.items.filter((item) => !isDeepStrictEqual(previousItems.get(item.id), item));
15644
+ const upsertItems = next.items.filter((item) => !isDeepStrictEqual2(previousItems.get(item.id), item));
15624
15645
  const removeItemIds = previous.items.filter((item) => !nextItems.has(item.id)).map((item) => item.id);
15625
- const upsertProcessGroups = next.process_groups.filter((group2) => !isDeepStrictEqual(previousProcessGroups.get(group2.id), group2));
15646
+ const upsertProcessGroups = next.process_groups.filter((group2) => !isDeepStrictEqual2(previousProcessGroups.get(group2.id), group2));
15626
15647
  const removeProcessGroupIds = previous.process_groups.filter((group2) => !nextProcessGroups.has(group2.id)).map((group2) => group2.id);
15627
15648
  const changes = changesBetween(previous, next);
15628
15649
  if (Object.keys(changes).length === 0 && upsertItems.length === 0 && removeItemIds.length === 0 && upsertProcessGroups.length === 0 && removeProcessGroupIds.length === 0) {
@@ -15683,9 +15704,9 @@ function isRunningTextOnlyPatch(patch, previous, next) {
15683
15704
  const { content: content2, updated_at, ...rest } = value;
15684
15705
  return rest;
15685
15706
  };
15686
- if (!isDeepStrictEqual(withoutContent(oldItem), withoutContent(item))) return false;
15707
+ if (!isDeepStrictEqual2(withoutContent(oldItem), withoutContent(item))) return false;
15687
15708
  const monotonicUpdatedAt2 = oldItem.updated_at === null || item.updated_at === null || item.updated_at >= oldItem.updated_at;
15688
- return monotonicUpdatedAt2 && !isDeepStrictEqual(oldItem.content, item.content) && next.revision === patch.revision;
15709
+ return monotonicUpdatedAt2 && !isDeepStrictEqual2(oldItem.content, item.content) && next.revision === patch.revision;
15689
15710
  }
15690
15711
  var TEXT_DELTA_THROTTLE_MS, ThreadProjectionPublisher;
15691
15712
  var init_thread_projection_publisher = __esm({
@@ -15889,7 +15910,7 @@ var init_thread_projection_publisher = __esm({
15889
15910
  }
15890
15911
  if (this.closed || !this.publication.latestView) return;
15891
15912
  const next = this.currentView();
15892
- if (!next || !this.publication.needsWindowSnapshot && isDeepStrictEqual({ ...next, revision: 0 }, { ...this.publication.latestView, revision: 0 })) return;
15913
+ if (!next || !this.publication.needsWindowSnapshot && isDeepStrictEqual2({ ...next, revision: 0 }, { ...this.publication.latestView, revision: 0 })) return;
15893
15914
  this.flushQueuedPatch();
15894
15915
  this.publication.needsWindowSnapshot = false;
15895
15916
  this.publication.latestView = clone2(next);
@@ -19200,7 +19221,7 @@ async function runLiteInstall() {
19200
19221
  if (process.platform !== "darwin") throw Error("\u8F7B\u91CF\u684C\u9762\u5E94\u7528\u4EC5\u652F\u6301 macOS\uFF0C\u8BF7\u4F7F\u7528 --background");
19201
19222
  const version2 = desktopReleaseVersion();
19202
19223
  if (!version2 || false || false) throw Error("\u6B64\u7248\u672C\u5C1A\u672A\u914D\u7F6E Tauri \u8F7B\u91CF\u53D1\u884C\u8D44\u6E90\uFF0C\u6682\u4E0D\u80FD\u901A\u8FC7 install-app \u5B89\u88C5\uFF1B\u7EAF\u540E\u53F0\u8BF7\u4F7F\u7528 --background");
19203
- const manifest = validateManifest(JSON.parse('{\n "schema": 2,\n "source": "bundled",\n "mode": "experimental",\n "combinationId": "0.0.1-beta.22",\n "cliVersion": "0.0.1-beta.22",\n "daemonVersion": "0.0.1-beta.22",\n "nodeRange": ">=18.20.5",\n "artifacts": {\n "darwin-arm64": {\n "app": {\n "path": "resources/niuma-lite-arm64.dmg",\n "size": 8124330,\n "sha256": "5089ad693fa3afdce595caa225f08a9ce31dbbbafc6c574c8de9894a0deab3a9"\n },\n "runtime": {\n "path": "resources/niuma-daemon-arm64.tgz",\n "size": 18281810,\n "sha256": "438a15f5e54c6c7918c68651eb03d380b9946c7b0e99e97205cd9442636119e5"\n }\n }\n }\n}\n'), version2, process.arch);
19224
+ const manifest = validateManifest(JSON.parse('{\n "schema": 2,\n "source": "bundled",\n "mode": "experimental",\n "combinationId": "0.0.1-beta.23",\n "cliVersion": "0.0.1-beta.23",\n "daemonVersion": "0.0.1-beta.23",\n "nodeRange": ">=18.20.5",\n "artifacts": {\n "darwin-arm64": {\n "app": {\n "path": "resources/niuma-lite-arm64.dmg",\n "size": 8126371,\n "sha256": "eac9e20cb8180d5e1c5b93e93973bbb956e7897e8552e8b6a3b6fc8922627cc9"\n },\n "runtime": {\n "path": "resources/niuma-daemon-arm64.tgz",\n "size": 18282144,\n "sha256": "71e836c6cdd50868fb0bd8394a56a0032a822df63f1ad3b61dcbc98a13d400c9"\n }\n }\n }\n}\n'), version2, process.arch);
19204
19225
  if (manifest.schema === 2) await confirmExperimental(manifest.mode, !!process.stdin.isTTY && !!process.stdout.isTTY, async () => {
19205
19226
  const prompt = createInterface3({ input: process.stdin, output: process.stdout });
19206
19227
  try {
@@ -32831,7 +32852,7 @@ var init_thread_list_cache = __esm({
32831
32852
  });
32832
32853
 
32833
32854
  // apps/desktop/src/daemon/thread-settings-cache.ts
32834
- import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
32855
+ import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
32835
32856
  function cloneModel(model) {
32836
32857
  return model ? { ...model } : null;
32837
32858
  }
@@ -33098,11 +33119,11 @@ var init_thread_settings_cache = __esm({
33098
33119
  const project3 = this.projects.get(input.projectRoot) ?? this.emptySettingsEntry(now);
33099
33120
  const nextThread = this.mergeRememberedEntry(thread4, input, input.projectRoot);
33100
33121
  const nextProject = this.mergeRememberedEntry(project3, input);
33101
- const threadChanged = !isDeepStrictEqual2(
33122
+ const threadChanged = !isDeepStrictEqual3(
33102
33123
  publicLayer(thread4),
33103
33124
  publicLayer(nextThread)
33104
33125
  ) || thread4.projectRoot !== nextThread.projectRoot;
33105
- const projectChanged = !isDeepStrictEqual2(publicLayer(project3), publicLayer(nextProject));
33126
+ const projectChanged = !isDeepStrictEqual3(publicLayer(project3), publicLayer(nextProject));
33106
33127
  if (!threadChanged && !projectChanged) {
33107
33128
  const existingThread = this.threads.get(input.threadId);
33108
33129
  const existingProject = this.projects.get(input.projectRoot);
@@ -36278,7 +36299,7 @@ var init_session_pending = __esm({
36278
36299
 
36279
36300
  // apps/desktop/src/remote-session/connection-handoff-service.ts
36280
36301
  import { randomBytes as randomBytes4 } from "node:crypto";
36281
- import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
36302
+ import { isDeepStrictEqual as isDeepStrictEqual4 } from "node:util";
36282
36303
  function logicalDescriptor(descriptor) {
36283
36304
  if (descriptor.pathname !== "/api/v1/thread/open") return descriptor;
36284
36305
  const { load_id: _loadId, range_resume_token: _rangeToken, ...query2 } = descriptor.query;
@@ -36387,7 +36408,7 @@ var init_connection_handoff_service = __esm({
36387
36408
  this.live(existing);
36388
36409
  if (existing.scope.sessionId !== scope.sessionId) fail15(200004, "\u4EA4\u63A5\u4E0D\u53EF\u7528");
36389
36410
  if (existing.candidateSession !== request2.target_session_id) fail15(100101, "\u4EA4\u63A5\u76EE\u6807\u51B2\u7A81");
36390
- if (!isDeepStrictEqual3(existing.response.tickets.map(({ source_id, epoch }) => ({ source_id, epoch })), request2.sources)) fail15(100101, "\u4EA4\u63A5\u5185\u5BB9\u51B2\u7A81");
36411
+ if (!isDeepStrictEqual4(existing.response.tickets.map(({ source_id, epoch }) => ({ source_id, epoch })), request2.sources)) fail15(100101, "\u4EA4\u63A5\u5185\u5BB9\u51B2\u7A81");
36391
36412
  return structuredClone(existing.response);
36392
36413
  }
36393
36414
  for (const group3 of [...this.groups.values()]) {
@@ -36397,7 +36418,7 @@ var init_connection_handoff_service = __esm({
36397
36418
  const selected = request2.sources.map((identity6) => {
36398
36419
  const source2 = this.sources.get(identity6.source_id);
36399
36420
  if (!source2 || source2.bindingId !== scope.bindingId || source2.ownerSessionId() !== scope.sessionId) fail15(200004, "\u4EA4\u63A5\u4E0D\u53EF\u7528");
36400
- if (!isDeepStrictEqual3(source2.identity(), identity6)) fail15(100202, "\u903B\u8F91\u6E90\u5DF2\u5931\u6548");
36421
+ if (!isDeepStrictEqual4(source2.identity(), identity6)) fail15(100202, "\u903B\u8F91\u6E90\u5DF2\u5931\u6548");
36401
36422
  return { source: source2, identity: identity6 };
36402
36423
  });
36403
36424
  const target = this.targets.get(this.key(scope, request2.target_session_id));
@@ -36459,9 +36480,9 @@ var init_connection_handoff_service = __esm({
36459
36480
  if (group2.scope.bindingId !== scope.bindingId || group2.scope.sessionId === scope.sessionId) fail15(200004, "\u4EA4\u63A5\u4E0D\u53EF\u7528");
36460
36481
  const ticket2 = group2.tickets.find((ticket3) => ticket3.token === token3);
36461
36482
  if (ticket2.consumer || group2.committed) fail15(100202, "\u4EA4\u63A5\u7968\u636E\u5DF2\u9886\u53D6");
36462
- if (!isDeepStrictEqual3(logicalDescriptor(ticket2.source.descriptor), logicalDescriptor(descriptor))) fail15(200004, "\u4EA4\u63A5\u4E0D\u53EF\u7528");
36483
+ if (!isDeepStrictEqual4(logicalDescriptor(ticket2.source.descriptor), logicalDescriptor(descriptor))) fail15(200004, "\u4EA4\u63A5\u4E0D\u53EF\u7528");
36463
36484
  if (group2.candidateSession !== scope.sessionId) fail15(200004, "\u4EA4\u63A5\u4E0D\u53EF\u7528");
36464
- if (!isDeepStrictEqual3(ticket2.source.identity(), ticket2.identity)) fail15(100202, "\u903B\u8F91\u6E90\u5DF2\u5931\u6548");
36485
+ if (!isDeepStrictEqual4(ticket2.source.identity(), ticket2.identity)) fail15(100202, "\u903B\u8F91\u6E90\u5DF2\u5931\u6548");
36465
36486
  const claimed = ticket2.reservation.claim(scope, context);
36466
36487
  let closed = false;
36467
36488
  const consumer = {
@@ -36496,7 +36517,7 @@ var init_connection_handoff_service = __esm({
36496
36517
  if (request2.tickets.length !== group2.tickets.length || group2.tickets.some((ticket2) => !request2.tickets.includes(ticket2.token))) fail15(100101, "\u4EA4\u63A5\u7968\u636E\u96C6\u5408\u4E0D\u5339\u914D");
36497
36518
  group2.target.assertCurrent();
36498
36519
  for (const ticket2 of group2.tickets) {
36499
- if (!ticket2.consumer || ticket2.sessionId !== scope.sessionId || !isDeepStrictEqual3(ticket2.source.identity(), ticket2.identity)) fail15(100202, "\u4EA4\u63A5\u5C1A\u672A\u5C31\u7EEA");
36520
+ if (!ticket2.consumer || ticket2.sessionId !== scope.sessionId || !isDeepStrictEqual4(ticket2.source.identity(), ticket2.identity)) fail15(100202, "\u4EA4\u63A5\u5C1A\u672A\u5C31\u7EEA");
36500
36521
  ticket2.consumer.assertCurrent();
36501
36522
  }
36502
36523
  if (!group2.committed) {
@@ -59923,7 +59944,7 @@ var init_thread_view_reducer = __esm({
59923
59944
 
59924
59945
  // apps/desktop/src/daemon/thread-view-store.ts
59925
59946
  import { createHash as createHash25, randomUUID as randomUUID39 } from "node:crypto";
59926
- import { isDeepStrictEqual as isDeepStrictEqual4 } from "node:util";
59947
+ import { isDeepStrictEqual as isDeepStrictEqual5 } from "node:util";
59927
59948
  function clone5(value) {
59928
59949
  return structuredClone(value);
59929
59950
  }
@@ -60167,7 +60188,7 @@ var init_thread_view_store = __esm({
60167
60188
  const result = [];
60168
60189
  for (const item of delivered.filter((item2) => item2.type === "assistant_message" && item2.turn_id === turnId)) {
60169
60190
  const original = source2.get(item.id);
60170
- if (!original || entry.deferredMessageIds?.has(item.id) || original.type !== item.type || original.turn_id !== turnId || !isDeepStrictEqual4(this.publicItem(threadId2, original).content, item.content)) return null;
60191
+ if (!original || entry.deferredMessageIds?.has(item.id) || original.type !== item.type || original.turn_id !== turnId || !isDeepStrictEqual5(this.publicItem(threadId2, original).content, item.content)) return null;
60171
60192
  result.push(clone5(original));
60172
60193
  }
60173
60194
  return result;
@@ -60737,7 +60758,7 @@ var init_thread_view_store = __esm({
60737
60758
  const hasBaseline = events.some((event) => event.type === "ThreadBaselineReceived");
60738
60759
  const stableContentChanged = previousStableContent.some(({ item, processFact }) => {
60739
60760
  const nextItem = nextAggregate.committedItems.get(item.id) ?? nextAggregate.activeTurn?.items.get(item.id);
60740
- return !nextItem || !isDeepStrictEqual4(item, nextItem) || !isDeepStrictEqual4(processFact, nextAggregate.processFacts.get(item.id) ?? null);
60761
+ return !nextItem || !isDeepStrictEqual5(item, nextItem) || !isDeepStrictEqual5(processFact, nextAggregate.processFacts.get(item.id) ?? null);
60741
60762
  });
60742
60763
  const stableChanged = historyOrderReset || orderCorrected || stableContentChanged;
60743
60764
  const baselineReplaced = stableChanged || hasBaseline;
@@ -60822,7 +60843,7 @@ var init_thread_view_store = __esm({
60822
60843
  }
60823
60844
  const newlyDeferred = [...deferredMessageIds].filter((id5) => !initialEntry.deferredMessageIds?.has(id5));
60824
60845
  if (newlyDeferred.length) this.options.onMessagePublicationDeferred?.(threadId2, newlyDeferred);
60825
- const samePublicView = isDeepStrictEqual4(
60846
+ const samePublicView = isDeepStrictEqual5(
60826
60847
  { ...previousView, revision: 0 },
60827
60848
  { ...nextView, revision: 0 }
60828
60849
  );
@@ -60848,7 +60869,7 @@ var init_thread_view_store = __esm({
60848
60869
  const previousItems = new Map(initialEntry.aggregate.projection.items.map((item) => [item.id, item]));
60849
60870
  const changed2 = nextAggregate.projection.items.filter((item) => {
60850
60871
  const previous = previousItems.get(item.id);
60851
- return !previous || !isDeepStrictEqual4(previous.content, item.content);
60872
+ return !previous || !isDeepStrictEqual5(previous.content, item.content);
60852
60873
  });
60853
60874
  if (changed2.length) {
60854
60875
  for (const lease of this.subscriptions) {
@@ -60875,7 +60896,7 @@ var init_thread_view_store = __esm({
60875
60896
  previous_revision: previousRevision,
60876
60897
  baseline_replaced: baselineReplaced,
60877
60898
  // 比较完整 committed 层而非公开尾窗,保护 Web 已补页内容与在途分页响应。
60878
- ...baselineReplaced && !stableChanged && nextEntry.baselineContinuityKey !== null && nextEntry.baselineContinuityKey === initialEntry.baselineContinuityKey && isDeepStrictEqual4(previousView.window, nextView.window) ? { baseline_patch_safe: true } : {},
60899
+ ...baselineReplaced && !stableChanged && nextEntry.baselineContinuityKey !== null && nextEntry.baselineContinuityKey === initialEntry.baselineContinuityKey && isDeepStrictEqual5(previousView.window, nextView.window) ? { baseline_patch_safe: true } : {},
60879
60900
  // 本次事务已构造公开内容;只补齐提交后的 revision,避免重新解析全部历史。
60880
60901
  view: clone5({ ...nextView, revision: nextEntry.revision })
60881
60902
  };
@@ -60951,11 +60972,11 @@ var init_thread_view_store = __esm({
60951
60972
  this.assertCurrent();
60952
60973
  const next = window.getSnapshot();
60953
60974
  const previous = this.source.current.snapshot;
60954
- if (!sourceChanged && isDeepStrictEqual4(next, previous)) return;
60975
+ if (!sourceChanged && isDeepStrictEqual5(next, previous)) return;
60955
60976
  const nextIds = new Set(next.items.map((item) => item.id));
60956
60977
  const installed = installedVersion !== window.installVersion;
60957
60978
  installedVersion = window.installVersion;
60958
- if (installed || sourceChanged || previous.items.some((item) => !nextIds.has(item.id)) || !isDeepStrictEqual4(previous.capabilities, next.capabilities)) this.source.replaceEpoch(randomUUID39(), next);
60979
+ if (installed || sourceChanged || previous.items.some((item) => !nextIds.has(item.id)) || !isDeepStrictEqual5(previous.capabilities, next.capabilities)) this.source.replaceEpoch(randomUUID39(), next);
60959
60980
  else this.source.publish(next);
60960
60981
  };
60961
60982
  this.unsubscribe = store.subscribe((mutation) => {
@@ -69492,7 +69513,7 @@ var init_file_resources = __esm({
69492
69513
  });
69493
69514
 
69494
69515
  // apps/desktop/src/niuma/desktop-settings-events.ts
69495
- import { isDeepStrictEqual as isDeepStrictEqual5 } from "node:util";
69516
+ import { isDeepStrictEqual as isDeepStrictEqual6 } from "node:util";
69496
69517
  function record23(value) {
69497
69518
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
69498
69519
  }
@@ -69669,7 +69690,7 @@ var init_desktop_settings_events = __esm({
69669
69690
  const previous = this.lastSettingsByThread.get(threadId2) ?? {};
69670
69691
  const next = { ...previous, ...settings };
69671
69692
  this.lastSettingsByThread.set(threadId2, next);
69672
- if (source2 === "patch" && isDeepStrictEqual5(previous, next)) {
69693
+ if (source2 === "patch" && isDeepStrictEqual6(previous, next)) {
69673
69694
  return [];
69674
69695
  }
69675
69696
  return [{ threadId: threadId2, settings, source: source2, occurredAt: occurredAt3() }];
@@ -6881,7 +6881,7 @@ var init_src2 = __esm({
6881
6881
  // apps/desktop/src/release-version.ts
6882
6882
  import { readFileSync } from "node:fs";
6883
6883
  function desktopReleaseVersion() {
6884
- return false ? null : "0.0.1-beta.22";
6884
+ return false ? null : "0.0.1-beta.23";
6885
6885
  }
6886
6886
  function desktopPresenceVersion() {
6887
6887
  return desktopReleaseVersion() ?? sourcePresenceVersion;
@@ -30507,6 +30507,7 @@ var init_app_bundle = __esm({
30507
30507
 
30508
30508
  // apps/desktop/src/autostart/manager.ts
30509
30509
  import fs23 from "node:fs";
30510
+ import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
30510
30511
  import fsp2 from "node:fs/promises";
30511
30512
  import path32 from "node:path";
30512
30513
  import os2 from "node:os";
@@ -30682,7 +30683,7 @@ var init_manager = __esm({
30682
30683
  await privateDirectory(this.root);
30683
30684
  const release2 = acquire(path32.join(this.root, "operation.lock"));
30684
30685
  const snapshot2 = async () => {
30685
- if (await readJson(this.root + "/transaction.json")) throw new AutostartError(900615, "npm \u81EA\u542F\u52A8\u6709\u672A\u5B8C\u6210\u4E8B\u52A1\uFF0C\u8BF7\u5148\u4FEE\u590D");
30686
+ if (!await this.finishSettledTransaction()) throw new AutostartError(900615, "npm \u81EA\u542F\u52A8\u6709\u672A\u5B8C\u6210\u4E8B\u52A1\uFF0C\u8BF7\u5148\u4FEE\u590D");
30686
30687
  const registration = await readJson(this.metadata);
30687
30688
  const status2 = await this.status();
30688
30689
  const fingerprint = createHash11("sha256").update(JSON.stringify({ registration, loaded: status2.loaded, available: status2.available })).digest("hex");
@@ -30745,8 +30746,28 @@ var init_manager = __esm({
30745
30746
  if (status2.operation?.state === "failed") throw new AutostartError(status2.operation.code, status2.operation.message);
30746
30747
  return status2;
30747
30748
  }
30749
+ /** 调用者持有 operation.lock;仅收尾已恢复的同配置原生登记,不改变系统开关。 */
30750
+ async finishSettledTransaction() {
30751
+ const file = path32.join(this.root, "transaction.json");
30752
+ const t = await readJson(file);
30753
+ if (!t) return true;
30754
+ const previous = t.previous;
30755
+ if (t.owner !== "niuma-autostart-v1" || !previous || previous.owner !== "niuma-autostart-v1" || previous.service !== "application-agent" || !previous.appPath || (t.wasRegistered ?? t.wasLoaded) !== true || !isDeepStrictEqual3(previous, t.next) || !isDeepStrictEqual3(previous, await readJson(this.metadata))) return false;
30756
+ try {
30757
+ await fsp2.lstat(this.plist);
30758
+ return false;
30759
+ } catch (e) {
30760
+ if (e.code !== "ENOENT") throw e;
30761
+ }
30762
+ const state = await this.registrationState(previous);
30763
+ if (state !== 1 && state !== 2) return false;
30764
+ if (!isDeepStrictEqual3(t, await readJson(file))) return false;
30765
+ await fsp2.rm(file);
30766
+ return true;
30767
+ }
30748
30768
  /** 注册文件和元数据的两次写入由恢复记录覆盖,崩溃后只恢复可证明自有的内容。 */
30749
30769
  async recoverTransaction() {
30770
+ if (await this.finishSettledTransaction()) return;
30750
30771
  const file = path32.join(this.root, "transaction.json");
30751
30772
  const transaction = await readJson(file);
30752
30773
  if (!transaction) return;
@@ -30806,7 +30827,7 @@ var init_manager = __esm({
30806
30827
  const appPath = await prepareAutostartApp(this.root, config, installed.entryPath);
30807
30828
  await this.options.guard?.();
30808
30829
  next = { owner: "niuma-autostart-v1", service: "application-agent", config, entryPath: installed.entryPath, appPath, plist: renderLaunchAgent(config, installed.entryPath, this.root, true) };
30809
- if (reusable && previous.service === next.service && previous.appPath === appPath && previous.plist === next.plist) {
30830
+ if ((reusable || priorState === 2) && isDeepStrictEqual3(previous, next)) {
30810
30831
  await this.run(LSREGISTER, ["-f", appPath]);
30811
30832
  return;
30812
30833
  }
@@ -31707,7 +31728,7 @@ var init_transfer_http = __esm({
31707
31728
  });
31708
31729
 
31709
31730
  // apps/desktop/src/daemon/thread-projection-publisher.ts
31710
- import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
31731
+ import { isDeepStrictEqual as isDeepStrictEqual4 } from "node:util";
31711
31732
  function clone2(value) {
31712
31733
  return structuredClone(value);
31713
31734
  }
@@ -31736,7 +31757,7 @@ function changesBetween(previous, next) {
31736
31757
  ];
31737
31758
  for (const key of keys3) {
31738
31759
  if (key === "execution" && next.execution === void 0) continue;
31739
- if (!isDeepStrictEqual3(previous[key], next[key])) {
31760
+ if (!isDeepStrictEqual4(previous[key], next[key])) {
31740
31761
  changes[key] = clone2(next[key]);
31741
31762
  }
31742
31763
  }
@@ -31748,9 +31769,9 @@ function createThreadViewPatch(previous, next) {
31748
31769
  const nextItems = itemMap(next.items);
31749
31770
  const previousProcessGroups = processGroupMap(previous.process_groups);
31750
31771
  const nextProcessGroups = processGroupMap(next.process_groups);
31751
- const upsertItems = next.items.filter((item) => !isDeepStrictEqual3(previousItems.get(item.id), item));
31772
+ const upsertItems = next.items.filter((item) => !isDeepStrictEqual4(previousItems.get(item.id), item));
31752
31773
  const removeItemIds = previous.items.filter((item) => !nextItems.has(item.id)).map((item) => item.id);
31753
- const upsertProcessGroups = next.process_groups.filter((group2) => !isDeepStrictEqual3(previousProcessGroups.get(group2.id), group2));
31774
+ const upsertProcessGroups = next.process_groups.filter((group2) => !isDeepStrictEqual4(previousProcessGroups.get(group2.id), group2));
31754
31775
  const removeProcessGroupIds = previous.process_groups.filter((group2) => !nextProcessGroups.has(group2.id)).map((group2) => group2.id);
31755
31776
  const changes = changesBetween(previous, next);
31756
31777
  if (Object.keys(changes).length === 0 && upsertItems.length === 0 && removeItemIds.length === 0 && upsertProcessGroups.length === 0 && removeProcessGroupIds.length === 0) {
@@ -31811,9 +31832,9 @@ function isRunningTextOnlyPatch(patch, previous, next) {
31811
31832
  const { content: content2, updated_at, ...rest } = value;
31812
31833
  return rest;
31813
31834
  };
31814
- if (!isDeepStrictEqual3(withoutContent(oldItem), withoutContent(item))) return false;
31835
+ if (!isDeepStrictEqual4(withoutContent(oldItem), withoutContent(item))) return false;
31815
31836
  const monotonicUpdatedAt2 = oldItem.updated_at === null || item.updated_at === null || item.updated_at >= oldItem.updated_at;
31816
- return monotonicUpdatedAt2 && !isDeepStrictEqual3(oldItem.content, item.content) && next.revision === patch.revision;
31837
+ return monotonicUpdatedAt2 && !isDeepStrictEqual4(oldItem.content, item.content) && next.revision === patch.revision;
31817
31838
  }
31818
31839
  var TEXT_DELTA_THROTTLE_MS, ThreadProjectionPublisher;
31819
31840
  var init_thread_projection_publisher = __esm({
@@ -32017,7 +32038,7 @@ var init_thread_projection_publisher = __esm({
32017
32038
  }
32018
32039
  if (this.closed || !this.publication.latestView) return;
32019
32040
  const next = this.currentView();
32020
- if (!next || !this.publication.needsWindowSnapshot && isDeepStrictEqual3({ ...next, revision: 0 }, { ...this.publication.latestView, revision: 0 })) return;
32041
+ if (!next || !this.publication.needsWindowSnapshot && isDeepStrictEqual4({ ...next, revision: 0 }, { ...this.publication.latestView, revision: 0 })) return;
32021
32042
  this.flushQueuedPatch();
32022
32043
  this.publication.needsWindowSnapshot = false;
32023
32044
  this.publication.latestView = clone2(next);
@@ -58042,7 +58063,7 @@ var init_thread_view_reducer = __esm({
58042
58063
 
58043
58064
  // apps/desktop/src/daemon/thread-view-store.ts
58044
58065
  import { createHash as createHash23, randomUUID as randomUUID35 } from "node:crypto";
58045
- import { isDeepStrictEqual as isDeepStrictEqual4 } from "node:util";
58066
+ import { isDeepStrictEqual as isDeepStrictEqual5 } from "node:util";
58046
58067
  function clone5(value) {
58047
58068
  return structuredClone(value);
58048
58069
  }
@@ -58286,7 +58307,7 @@ var init_thread_view_store = __esm({
58286
58307
  const result = [];
58287
58308
  for (const item of delivered.filter((item2) => item2.type === "assistant_message" && item2.turn_id === turnId)) {
58288
58309
  const original = source2.get(item.id);
58289
- if (!original || entry.deferredMessageIds?.has(item.id) || original.type !== item.type || original.turn_id !== turnId || !isDeepStrictEqual4(this.publicItem(threadId2, original).content, item.content)) return null;
58310
+ if (!original || entry.deferredMessageIds?.has(item.id) || original.type !== item.type || original.turn_id !== turnId || !isDeepStrictEqual5(this.publicItem(threadId2, original).content, item.content)) return null;
58290
58311
  result.push(clone5(original));
58291
58312
  }
58292
58313
  return result;
@@ -58856,7 +58877,7 @@ var init_thread_view_store = __esm({
58856
58877
  const hasBaseline = events.some((event) => event.type === "ThreadBaselineReceived");
58857
58878
  const stableContentChanged = previousStableContent.some(({ item, processFact }) => {
58858
58879
  const nextItem = nextAggregate.committedItems.get(item.id) ?? nextAggregate.activeTurn?.items.get(item.id);
58859
- return !nextItem || !isDeepStrictEqual4(item, nextItem) || !isDeepStrictEqual4(processFact, nextAggregate.processFacts.get(item.id) ?? null);
58880
+ return !nextItem || !isDeepStrictEqual5(item, nextItem) || !isDeepStrictEqual5(processFact, nextAggregate.processFacts.get(item.id) ?? null);
58860
58881
  });
58861
58882
  const stableChanged = historyOrderReset || orderCorrected || stableContentChanged;
58862
58883
  const baselineReplaced = stableChanged || hasBaseline;
@@ -58941,7 +58962,7 @@ var init_thread_view_store = __esm({
58941
58962
  }
58942
58963
  const newlyDeferred = [...deferredMessageIds].filter((id5) => !initialEntry.deferredMessageIds?.has(id5));
58943
58964
  if (newlyDeferred.length) this.options.onMessagePublicationDeferred?.(threadId2, newlyDeferred);
58944
- const samePublicView = isDeepStrictEqual4(
58965
+ const samePublicView = isDeepStrictEqual5(
58945
58966
  { ...previousView, revision: 0 },
58946
58967
  { ...nextView, revision: 0 }
58947
58968
  );
@@ -58967,7 +58988,7 @@ var init_thread_view_store = __esm({
58967
58988
  const previousItems = new Map(initialEntry.aggregate.projection.items.map((item) => [item.id, item]));
58968
58989
  const changed2 = nextAggregate.projection.items.filter((item) => {
58969
58990
  const previous = previousItems.get(item.id);
58970
- return !previous || !isDeepStrictEqual4(previous.content, item.content);
58991
+ return !previous || !isDeepStrictEqual5(previous.content, item.content);
58971
58992
  });
58972
58993
  if (changed2.length) {
58973
58994
  for (const lease of this.subscriptions) {
@@ -58994,7 +59015,7 @@ var init_thread_view_store = __esm({
58994
59015
  previous_revision: previousRevision,
58995
59016
  baseline_replaced: baselineReplaced,
58996
59017
  // 比较完整 committed 层而非公开尾窗,保护 Web 已补页内容与在途分页响应。
58997
- ...baselineReplaced && !stableChanged && nextEntry.baselineContinuityKey !== null && nextEntry.baselineContinuityKey === initialEntry.baselineContinuityKey && isDeepStrictEqual4(previousView.window, nextView.window) ? { baseline_patch_safe: true } : {},
59018
+ ...baselineReplaced && !stableChanged && nextEntry.baselineContinuityKey !== null && nextEntry.baselineContinuityKey === initialEntry.baselineContinuityKey && isDeepStrictEqual5(previousView.window, nextView.window) ? { baseline_patch_safe: true } : {},
58998
59019
  // 本次事务已构造公开内容;只补齐提交后的 revision,避免重新解析全部历史。
58999
59020
  view: clone5({ ...nextView, revision: nextEntry.revision })
59000
59021
  };
@@ -59070,11 +59091,11 @@ var init_thread_view_store = __esm({
59070
59091
  this.assertCurrent();
59071
59092
  const next = window.getSnapshot();
59072
59093
  const previous = this.source.current.snapshot;
59073
- if (!sourceChanged && isDeepStrictEqual4(next, previous)) return;
59094
+ if (!sourceChanged && isDeepStrictEqual5(next, previous)) return;
59074
59095
  const nextIds = new Set(next.items.map((item) => item.id));
59075
59096
  const installed = installedVersion !== window.installVersion;
59076
59097
  installedVersion = window.installVersion;
59077
- if (installed || sourceChanged || previous.items.some((item) => !nextIds.has(item.id)) || !isDeepStrictEqual4(previous.capabilities, next.capabilities)) this.source.replaceEpoch(randomUUID35(), next);
59098
+ if (installed || sourceChanged || previous.items.some((item) => !nextIds.has(item.id)) || !isDeepStrictEqual5(previous.capabilities, next.capabilities)) this.source.replaceEpoch(randomUUID35(), next);
59078
59099
  else this.source.publish(next);
59079
59100
  };
59080
59101
  this.unsubscribe = store.subscribe((mutation) => {
@@ -67702,7 +67723,7 @@ var init_file_resources = __esm({
67702
67723
  });
67703
67724
 
67704
67725
  // apps/desktop/src/niuma/desktop-settings-events.ts
67705
- import { isDeepStrictEqual as isDeepStrictEqual5 } from "node:util";
67726
+ import { isDeepStrictEqual as isDeepStrictEqual6 } from "node:util";
67706
67727
  function record23(value) {
67707
67728
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
67708
67729
  }
@@ -67879,7 +67900,7 @@ var init_desktop_settings_events = __esm({
67879
67900
  const previous = this.lastSettingsByThread.get(threadId2) ?? {};
67880
67901
  const next = { ...previous, ...settings };
67881
67902
  this.lastSettingsByThread.set(threadId2, next);
67882
- if (source2 === "patch" && isDeepStrictEqual5(previous, next)) {
67903
+ if (source2 === "patch" && isDeepStrictEqual6(previous, next)) {
67883
67904
  return [];
67884
67905
  }
67885
67906
  return [{ threadId: threadId2, settings, source: source2, occurredAt: occurredAt3() }];
package/dist/managed.js CHANGED
@@ -8487,7 +8487,7 @@ function parseAttachmentTaskV2StatusQuery(value) {
8487
8487
 
8488
8488
  // apps/desktop/src/release-version.ts
8489
8489
  function desktopReleaseVersion() {
8490
- return false ? null : "0.0.1-beta.22";
8490
+ return false ? null : "0.0.1-beta.23";
8491
8491
  }
8492
8492
  var sourcePresenceVersion = (() => {
8493
8493
  if (true) return null;
@@ -29389,6 +29389,7 @@ import path33 from "node:path";
29389
29389
 
29390
29390
  // apps/desktop/src/autostart/manager.ts
29391
29391
  import fs20 from "node:fs";
29392
+ import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
29392
29393
 
29393
29394
  // apps/desktop/src/autostart/selection.ts
29394
29395
  import fs18 from "node:fs";
@@ -29875,7 +29876,7 @@ var AutostartManager = class {
29875
29876
  await privateDirectory(this.root);
29876
29877
  const release2 = acquire(path31.join(this.root, "operation.lock"));
29877
29878
  const snapshot2 = async () => {
29878
- if (await readJson(this.root + "/transaction.json")) throw new AutostartError(900615, "npm \u81EA\u542F\u52A8\u6709\u672A\u5B8C\u6210\u4E8B\u52A1\uFF0C\u8BF7\u5148\u4FEE\u590D");
29879
+ if (!await this.finishSettledTransaction()) throw new AutostartError(900615, "npm \u81EA\u542F\u52A8\u6709\u672A\u5B8C\u6210\u4E8B\u52A1\uFF0C\u8BF7\u5148\u4FEE\u590D");
29879
29880
  const registration = await readJson(this.metadata);
29880
29881
  const status2 = await this.status();
29881
29882
  const fingerprint = createHash11("sha256").update(JSON.stringify({ registration, loaded: status2.loaded, available: status2.available })).digest("hex");
@@ -29938,8 +29939,28 @@ var AutostartManager = class {
29938
29939
  if (status2.operation?.state === "failed") throw new AutostartError(status2.operation.code, status2.operation.message);
29939
29940
  return status2;
29940
29941
  }
29942
+ /** 调用者持有 operation.lock;仅收尾已恢复的同配置原生登记,不改变系统开关。 */
29943
+ async finishSettledTransaction() {
29944
+ const file = path31.join(this.root, "transaction.json");
29945
+ const t = await readJson(file);
29946
+ if (!t) return true;
29947
+ const previous = t.previous;
29948
+ if (t.owner !== "niuma-autostart-v1" || !previous || previous.owner !== "niuma-autostart-v1" || previous.service !== "application-agent" || !previous.appPath || (t.wasRegistered ?? t.wasLoaded) !== true || !isDeepStrictEqual3(previous, t.next) || !isDeepStrictEqual3(previous, await readJson(this.metadata))) return false;
29949
+ try {
29950
+ await fsp2.lstat(this.plist);
29951
+ return false;
29952
+ } catch (e) {
29953
+ if (e.code !== "ENOENT") throw e;
29954
+ }
29955
+ const state = await this.registrationState(previous);
29956
+ if (state !== 1 && state !== 2) return false;
29957
+ if (!isDeepStrictEqual3(t, await readJson(file))) return false;
29958
+ await fsp2.rm(file);
29959
+ return true;
29960
+ }
29941
29961
  /** 注册文件和元数据的两次写入由恢复记录覆盖,崩溃后只恢复可证明自有的内容。 */
29942
29962
  async recoverTransaction() {
29963
+ if (await this.finishSettledTransaction()) return;
29943
29964
  const file = path31.join(this.root, "transaction.json");
29944
29965
  const transaction = await readJson(file);
29945
29966
  if (!transaction) return;
@@ -29999,7 +30020,7 @@ var AutostartManager = class {
29999
30020
  const appPath = await prepareAutostartApp(this.root, config, installed.entryPath);
30000
30021
  await this.options.guard?.();
30001
30022
  next = { owner: "niuma-autostart-v1", service: "application-agent", config, entryPath: installed.entryPath, appPath, plist: renderLaunchAgent(config, installed.entryPath, this.root, true) };
30002
- if (reusable && previous.service === next.service && previous.appPath === appPath && previous.plist === next.plist) {
30023
+ if ((reusable || priorState === 2) && isDeepStrictEqual3(previous, next)) {
30003
30024
  await this.run(LSREGISTER, ["-f", appPath]);
30004
30025
  return;
30005
30026
  }
@@ -30825,7 +30846,7 @@ async function dispatchAttachmentTransferRoute(request2, service) {
30825
30846
  import { z as z10 } from "zod";
30826
30847
 
30827
30848
  // apps/desktop/src/daemon/thread-projection-publisher.ts
30828
- import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
30849
+ import { isDeepStrictEqual as isDeepStrictEqual4 } from "node:util";
30829
30850
  var TEXT_DELTA_THROTTLE_MS = 100;
30830
30851
  function clone2(value) {
30831
30852
  return structuredClone(value);
@@ -30855,7 +30876,7 @@ function changesBetween(previous, next) {
30855
30876
  ];
30856
30877
  for (const key of keys3) {
30857
30878
  if (key === "execution" && next.execution === void 0) continue;
30858
- if (!isDeepStrictEqual3(previous[key], next[key])) {
30879
+ if (!isDeepStrictEqual4(previous[key], next[key])) {
30859
30880
  changes[key] = clone2(next[key]);
30860
30881
  }
30861
30882
  }
@@ -30867,9 +30888,9 @@ function createThreadViewPatch(previous, next) {
30867
30888
  const nextItems = itemMap(next.items);
30868
30889
  const previousProcessGroups = processGroupMap(previous.process_groups);
30869
30890
  const nextProcessGroups = processGroupMap(next.process_groups);
30870
- const upsertItems = next.items.filter((item) => !isDeepStrictEqual3(previousItems.get(item.id), item));
30891
+ const upsertItems = next.items.filter((item) => !isDeepStrictEqual4(previousItems.get(item.id), item));
30871
30892
  const removeItemIds = previous.items.filter((item) => !nextItems.has(item.id)).map((item) => item.id);
30872
- const upsertProcessGroups = next.process_groups.filter((group2) => !isDeepStrictEqual3(previousProcessGroups.get(group2.id), group2));
30893
+ const upsertProcessGroups = next.process_groups.filter((group2) => !isDeepStrictEqual4(previousProcessGroups.get(group2.id), group2));
30873
30894
  const removeProcessGroupIds = previous.process_groups.filter((group2) => !nextProcessGroups.has(group2.id)).map((group2) => group2.id);
30874
30895
  const changes = changesBetween(previous, next);
30875
30896
  if (Object.keys(changes).length === 0 && upsertItems.length === 0 && removeItemIds.length === 0 && upsertProcessGroups.length === 0 && removeProcessGroupIds.length === 0) {
@@ -30930,9 +30951,9 @@ function isRunningTextOnlyPatch(patch, previous, next) {
30930
30951
  const { content: content2, updated_at, ...rest } = value;
30931
30952
  return rest;
30932
30953
  };
30933
- if (!isDeepStrictEqual3(withoutContent(oldItem), withoutContent(item))) return false;
30954
+ if (!isDeepStrictEqual4(withoutContent(oldItem), withoutContent(item))) return false;
30934
30955
  const monotonicUpdatedAt2 = oldItem.updated_at === null || item.updated_at === null || item.updated_at >= oldItem.updated_at;
30935
- return monotonicUpdatedAt2 && !isDeepStrictEqual3(oldItem.content, item.content) && next.revision === patch.revision;
30956
+ return monotonicUpdatedAt2 && !isDeepStrictEqual4(oldItem.content, item.content) && next.revision === patch.revision;
30936
30957
  }
30937
30958
  var ThreadProjectionPublisher = class {
30938
30959
  store;
@@ -31131,7 +31152,7 @@ var ThreadProjectionPublisher = class {
31131
31152
  }
31132
31153
  if (this.closed || !this.publication.latestView) return;
31133
31154
  const next = this.currentView();
31134
- if (!next || !this.publication.needsWindowSnapshot && isDeepStrictEqual3({ ...next, revision: 0 }, { ...this.publication.latestView, revision: 0 })) return;
31155
+ if (!next || !this.publication.needsWindowSnapshot && isDeepStrictEqual4({ ...next, revision: 0 }, { ...this.publication.latestView, revision: 0 })) return;
31135
31156
  this.flushQueuedPatch();
31136
31157
  this.publication.needsWindowSnapshot = false;
31137
31158
  this.publication.latestView = clone2(next);
@@ -53843,7 +53864,7 @@ init_session_history_reader();
53843
53864
 
53844
53865
  // apps/desktop/src/daemon/thread-view-store.ts
53845
53866
  import { createHash as createHash23, randomUUID as randomUUID35 } from "node:crypto";
53846
- import { isDeepStrictEqual as isDeepStrictEqual4 } from "node:util";
53867
+ import { isDeepStrictEqual as isDeepStrictEqual5 } from "node:util";
53847
53868
 
53848
53869
  // apps/desktop/src/daemon/thread-action-policy.ts
53849
53870
  var yes = { allowed: true, reason: null };
@@ -55079,7 +55100,7 @@ var ThreadViewStore = class {
55079
55100
  const result = [];
55080
55101
  for (const item of delivered.filter((item2) => item2.type === "assistant_message" && item2.turn_id === turnId)) {
55081
55102
  const original = source2.get(item.id);
55082
- if (!original || entry.deferredMessageIds?.has(item.id) || original.type !== item.type || original.turn_id !== turnId || !isDeepStrictEqual4(this.publicItem(threadId2, original).content, item.content)) return null;
55103
+ if (!original || entry.deferredMessageIds?.has(item.id) || original.type !== item.type || original.turn_id !== turnId || !isDeepStrictEqual5(this.publicItem(threadId2, original).content, item.content)) return null;
55083
55104
  result.push(clone5(original));
55084
55105
  }
55085
55106
  return result;
@@ -55649,7 +55670,7 @@ var ThreadViewStore = class {
55649
55670
  const hasBaseline = events.some((event) => event.type === "ThreadBaselineReceived");
55650
55671
  const stableContentChanged = previousStableContent.some(({ item, processFact }) => {
55651
55672
  const nextItem = nextAggregate.committedItems.get(item.id) ?? nextAggregate.activeTurn?.items.get(item.id);
55652
- return !nextItem || !isDeepStrictEqual4(item, nextItem) || !isDeepStrictEqual4(processFact, nextAggregate.processFacts.get(item.id) ?? null);
55673
+ return !nextItem || !isDeepStrictEqual5(item, nextItem) || !isDeepStrictEqual5(processFact, nextAggregate.processFacts.get(item.id) ?? null);
55653
55674
  });
55654
55675
  const stableChanged = historyOrderReset || orderCorrected || stableContentChanged;
55655
55676
  const baselineReplaced = stableChanged || hasBaseline;
@@ -55734,7 +55755,7 @@ var ThreadViewStore = class {
55734
55755
  }
55735
55756
  const newlyDeferred = [...deferredMessageIds].filter((id5) => !initialEntry.deferredMessageIds?.has(id5));
55736
55757
  if (newlyDeferred.length) this.options.onMessagePublicationDeferred?.(threadId2, newlyDeferred);
55737
- const samePublicView = isDeepStrictEqual4(
55758
+ const samePublicView = isDeepStrictEqual5(
55738
55759
  { ...previousView, revision: 0 },
55739
55760
  { ...nextView, revision: 0 }
55740
55761
  );
@@ -55760,7 +55781,7 @@ var ThreadViewStore = class {
55760
55781
  const previousItems = new Map(initialEntry.aggregate.projection.items.map((item) => [item.id, item]));
55761
55782
  const changed2 = nextAggregate.projection.items.filter((item) => {
55762
55783
  const previous = previousItems.get(item.id);
55763
- return !previous || !isDeepStrictEqual4(previous.content, item.content);
55784
+ return !previous || !isDeepStrictEqual5(previous.content, item.content);
55764
55785
  });
55765
55786
  if (changed2.length) {
55766
55787
  for (const lease of this.subscriptions) {
@@ -55787,7 +55808,7 @@ var ThreadViewStore = class {
55787
55808
  previous_revision: previousRevision,
55788
55809
  baseline_replaced: baselineReplaced,
55789
55810
  // 比较完整 committed 层而非公开尾窗,保护 Web 已补页内容与在途分页响应。
55790
- ...baselineReplaced && !stableChanged && nextEntry.baselineContinuityKey !== null && nextEntry.baselineContinuityKey === initialEntry.baselineContinuityKey && isDeepStrictEqual4(previousView.window, nextView.window) ? { baseline_patch_safe: true } : {},
55811
+ ...baselineReplaced && !stableChanged && nextEntry.baselineContinuityKey !== null && nextEntry.baselineContinuityKey === initialEntry.baselineContinuityKey && isDeepStrictEqual5(previousView.window, nextView.window) ? { baseline_patch_safe: true } : {},
55791
55812
  // 本次事务已构造公开内容;只补齐提交后的 revision,避免重新解析全部历史。
55792
55813
  view: clone5({ ...nextView, revision: nextEntry.revision })
55793
55814
  };
@@ -55863,11 +55884,11 @@ var ThreadHandoffRange = class {
55863
55884
  this.assertCurrent();
55864
55885
  const next = window.getSnapshot();
55865
55886
  const previous = this.source.current.snapshot;
55866
- if (!sourceChanged && isDeepStrictEqual4(next, previous)) return;
55887
+ if (!sourceChanged && isDeepStrictEqual5(next, previous)) return;
55867
55888
  const nextIds = new Set(next.items.map((item) => item.id));
55868
55889
  const installed = installedVersion !== window.installVersion;
55869
55890
  installedVersion = window.installVersion;
55870
- if (installed || sourceChanged || previous.items.some((item) => !nextIds.has(item.id)) || !isDeepStrictEqual4(previous.capabilities, next.capabilities)) this.source.replaceEpoch(randomUUID35(), next);
55891
+ if (installed || sourceChanged || previous.items.some((item) => !nextIds.has(item.id)) || !isDeepStrictEqual5(previous.capabilities, next.capabilities)) this.source.replaceEpoch(randomUUID35(), next);
55871
55892
  else this.source.publish(next);
55872
55893
  };
55873
55894
  this.unsubscribe = store.subscribe((mutation) => {
@@ -64155,7 +64176,7 @@ var FileResources = class {
64155
64176
  };
64156
64177
 
64157
64178
  // apps/desktop/src/niuma/desktop-settings-events.ts
64158
- import { isDeepStrictEqual as isDeepStrictEqual5 } from "node:util";
64179
+ import { isDeepStrictEqual as isDeepStrictEqual6 } from "node:util";
64159
64180
  var SETTINGS_CONTAINERS = /* @__PURE__ */ new Set(["threadSettings", "latestThreadSettings"]);
64160
64181
  var CURRENT_PERMISSIONS_CONTAINER = "currentPermissions";
64161
64182
  var BASE_SETTING_FIELDS = [
@@ -64328,7 +64349,7 @@ var DesktopThreadSettingsTracker = class {
64328
64349
  const previous = this.lastSettingsByThread.get(threadId2) ?? {};
64329
64350
  const next = { ...previous, ...settings };
64330
64351
  this.lastSettingsByThread.set(threadId2, next);
64331
- if (source2 === "patch" && isDeepStrictEqual5(previous, next)) {
64352
+ if (source2 === "patch" && isDeepStrictEqual6(previous, next)) {
64332
64353
  return [];
64333
64354
  }
64334
64355
  return [{ threadId: threadId2, settings, source: source2, occurredAt: occurredAt3() }];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "niuma-codex",
3
- "version": "0.0.1-beta.22",
3
+ "version": "0.0.1-beta.23",
4
4
  "description": "Niuma Desktop CLI:连接本机 Codex 与远程客户端。",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -2,21 +2,21 @@
2
2
  "schema": 2,
3
3
  "source": "bundled",
4
4
  "mode": "experimental",
5
- "combinationId": "0.0.1-beta.22",
6
- "cliVersion": "0.0.1-beta.22",
7
- "daemonVersion": "0.0.1-beta.22",
5
+ "combinationId": "0.0.1-beta.23",
6
+ "cliVersion": "0.0.1-beta.23",
7
+ "daemonVersion": "0.0.1-beta.23",
8
8
  "nodeRange": ">=18.20.5",
9
9
  "artifacts": {
10
10
  "darwin-arm64": {
11
11
  "app": {
12
12
  "path": "resources/niuma-lite-arm64.dmg",
13
- "size": 8124330,
14
- "sha256": "5089ad693fa3afdce595caa225f08a9ce31dbbbafc6c574c8de9894a0deab3a9"
13
+ "size": 8126371,
14
+ "sha256": "eac9e20cb8180d5e1c5b93e93973bbb956e7897e8552e8b6a3b6fc8922627cc9"
15
15
  },
16
16
  "runtime": {
17
17
  "path": "resources/niuma-daemon-arm64.tgz",
18
- "size": 18281810,
19
- "sha256": "438a15f5e54c6c7918c68651eb03d380b9946c7b0e99e97205cd9442636119e5"
18
+ "size": 18282144,
19
+ "sha256": "71e836c6cdd50868fb0bd8394a56a0032a822df63f1ad3b61dcbc98a13d400c9"
20
20
  }
21
21
  }
22
22
  }
Binary file
Binary file