@remnic/core 9.69.25 → 9.69.26

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 (134) hide show
  1. package/dist/access-admin-ops-surface.d.ts +1 -1
  2. package/dist/access-admin-ops-surface.js +4 -4
  3. package/dist/access-authorization-probe.d.ts +1 -1
  4. package/dist/access-authorization-probe.js +5 -5
  5. package/dist/access-boundary.d.ts +1 -1
  6. package/dist/access-boundary.js +4 -4
  7. package/dist/access-cli.js +29 -29
  8. package/dist/access-extraction-force-flush.d.ts +1 -1
  9. package/dist/access-extraction-force-flush.js +4 -4
  10. package/dist/access-http-briefing.d.ts +1 -1
  11. package/dist/access-http-briefing.js +5 -5
  12. package/dist/access-http-lcm-compaction.d.ts +1 -1
  13. package/dist/access-http-lifecycle-flush.d.ts +1 -1
  14. package/dist/access-http-offline-stream.d.ts +1 -1
  15. package/dist/access-http-query.js +4 -4
  16. package/dist/access-http.d.ts +2 -2
  17. package/dist/access-http.js +16 -16
  18. package/dist/access-identity-continuity-surface.js +4 -4
  19. package/dist/access-lcm-surface.d.ts +1 -1
  20. package/dist/access-lcm-surface.js +4 -4
  21. package/dist/access-mcp.d.ts +1 -1
  22. package/dist/access-mcp.js +11 -11
  23. package/dist/access-namespace-preflight.js +4 -4
  24. package/dist/access-observe-write-surface.d.ts +1 -1
  25. package/dist/access-observe-write-surface.js +4 -4
  26. package/dist/access-operations-batch.js +5 -5
  27. package/dist/access-operations.d.ts +1 -1
  28. package/dist/access-operations.js +10 -10
  29. package/dist/access-recall-concurrency.d.ts +1 -1
  30. package/dist/access-recall-concurrency.js +4 -4
  31. package/dist/access-recall-response.d.ts +1 -1
  32. package/dist/access-recall-response.js +4 -4
  33. package/dist/access-recall-surface.d.ts +1 -1
  34. package/dist/access-recall-surface.js +4 -4
  35. package/dist/access-service-helpers.d.ts +1 -1
  36. package/dist/access-service.d.ts +1 -1
  37. package/dist/access-service.js +4 -4
  38. package/dist/access-surface-catalog.d.ts +1 -1
  39. package/dist/access-surface-catalog.js +6 -6
  40. package/dist/active-recall.js +4 -4
  41. package/dist/buffer.js +4 -4
  42. package/dist/{chunk-OGUKSLYZ.js → chunk-2OO6TPQG.js} +2 -2
  43. package/dist/{chunk-66OJSCI6.js → chunk-3GGUMRS4.js} +2 -2
  44. package/dist/{chunk-PX4UMA5Z.js → chunk-3NYTZE5G.js} +2 -2
  45. package/dist/{chunk-FVOP3NT7.js → chunk-5IEV3YBY.js} +2 -2
  46. package/dist/{chunk-2ITE4C2Z.js → chunk-6LLLREDJ.js} +2 -2
  47. package/dist/{chunk-K7724CH2.js → chunk-6VF3R3XQ.js} +2 -2
  48. package/dist/{chunk-56Y6EKZN.js → chunk-CGJV2YIY.js} +2 -2
  49. package/dist/{chunk-KB2G2I6Q.js → chunk-DDB3S53L.js} +2 -2
  50. package/dist/{chunk-KTWG7CNY.js → chunk-EWCNCQOU.js} +2 -2
  51. package/dist/{chunk-L7Z57SID.js → chunk-FHYVNJBN.js} +2 -2
  52. package/dist/{chunk-33JKYLPX.js → chunk-GGRD3JEH.js} +2 -2
  53. package/dist/{chunk-37KUQPX4.js → chunk-GNMELJGM.js} +2 -2
  54. package/dist/{chunk-2IOHTUP3.js → chunk-GRCREL6Q.js} +3 -3
  55. package/dist/{chunk-H54VWRPS.js → chunk-JJ4XK25O.js} +2 -2
  56. package/dist/{chunk-SVXJLDDC.js → chunk-KH6PK4EQ.js} +5 -5
  57. package/dist/{chunk-NLYVH66G.js → chunk-MT47LH5L.js} +2 -2
  58. package/dist/{chunk-SMWTZLHE.js → chunk-MZLV2OJE.js} +9 -9
  59. package/dist/{chunk-ICKJ52PE.js → chunk-OU4K7IFP.js} +3 -3
  60. package/dist/{chunk-27QVNSQ3.js → chunk-QBH7M7Q4.js} +2 -2
  61. package/dist/{chunk-O6ZNNVSP.js → chunk-RX3SC4C5.js} +2 -2
  62. package/dist/{chunk-RJYJ7KR7.js → chunk-SO4IYSGT.js} +12 -12
  63. package/dist/{chunk-C553ZTLF.js → chunk-THQTFTQS.js} +8 -8
  64. package/dist/{chunk-X5K5TAQZ.js → chunk-V4ZBR7CW.js} +2 -2
  65. package/dist/{chunk-P6FHFTZ7.js → chunk-XPFC6D45.js} +12 -7
  66. package/dist/chunk-XPFC6D45.js.map +1 -0
  67. package/dist/{chunk-ZIW5JVRM.js → chunk-XTJC7CVX.js} +2 -2
  68. package/dist/{chunk-Z6COGHHN.js → chunk-Y2MZGBOY.js} +2 -2
  69. package/dist/{chunk-H4SEGIZY.js → chunk-ZO2AZIRT.js} +2 -2
  70. package/dist/{chunk-UNNPNBR2.js → chunk-ZUNNRGJX.js} +4 -4
  71. package/dist/{chunk-BLJWYCNO.js → chunk-ZY4DSWZ5.js} +2 -2
  72. package/dist/{cli-BqMNkQn5.d.ts → cli-B_YwqoIr.d.ts} +1 -1
  73. package/dist/cli.d.ts +2 -2
  74. package/dist/cli.js +22 -22
  75. package/dist/config.js +4 -4
  76. package/dist/deep-recall-http-glue.d.ts +1 -1
  77. package/dist/deep-recall-mcp-tools.d.ts +1 -1
  78. package/dist/external-wiki-access.d.ts +1 -1
  79. package/dist/external-wiki-access.js +5 -5
  80. package/dist/external-wiki-mcp-tools.d.ts +1 -1
  81. package/dist/extraction.js +5 -5
  82. package/dist/index.d.ts +11 -7
  83. package/dist/index.js +29 -29
  84. package/dist/location/index.js +5 -5
  85. package/dist/mcp-memory-inspector-app.d.ts +1 -1
  86. package/dist/memory-subject-cli.d.ts +1 -1
  87. package/dist/memory-subject.d.ts +1 -1
  88. package/dist/operator-toolkit.js +5 -5
  89. package/dist/orchestration/maintenance.js +6 -6
  90. package/dist/orchestrator.js +29 -29
  91. package/dist/{public-http-ByX2eTla.d.ts → public-http-D6d4W8x-.d.ts} +1 -1
  92. package/dist/resume-bundles.js +5 -5
  93. package/dist/schemas.d.ts +42 -42
  94. package/dist/source-agent-qualifier.js +4 -4
  95. package/dist/standup/build.js +2 -2
  96. package/dist/support-passport/index.d.ts +4 -4
  97. package/dist/support-passport/index.js +7 -7
  98. package/dist/transfer/types.d.ts +12 -12
  99. package/dist/who-knows-cli.d.ts +1 -1
  100. package/dist/who-knows.d.ts +1 -1
  101. package/package.json +2 -2
  102. package/src/activity/digest.test.ts +34 -0
  103. package/src/activity/digest.ts +34 -8
  104. package/src/activity/timeline/weekly.test.ts +29 -0
  105. package/dist/chunk-P6FHFTZ7.js.map +0 -1
  106. package/dist/{access-service-GrdVg_-Z.d.ts → access-service-Cv8Rizo0.d.ts} +6 -6
  107. /package/dist/{chunk-OGUKSLYZ.js.map → chunk-2OO6TPQG.js.map} +0 -0
  108. /package/dist/{chunk-66OJSCI6.js.map → chunk-3GGUMRS4.js.map} +0 -0
  109. /package/dist/{chunk-PX4UMA5Z.js.map → chunk-3NYTZE5G.js.map} +0 -0
  110. /package/dist/{chunk-FVOP3NT7.js.map → chunk-5IEV3YBY.js.map} +0 -0
  111. /package/dist/{chunk-2ITE4C2Z.js.map → chunk-6LLLREDJ.js.map} +0 -0
  112. /package/dist/{chunk-K7724CH2.js.map → chunk-6VF3R3XQ.js.map} +0 -0
  113. /package/dist/{chunk-56Y6EKZN.js.map → chunk-CGJV2YIY.js.map} +0 -0
  114. /package/dist/{chunk-KB2G2I6Q.js.map → chunk-DDB3S53L.js.map} +0 -0
  115. /package/dist/{chunk-KTWG7CNY.js.map → chunk-EWCNCQOU.js.map} +0 -0
  116. /package/dist/{chunk-L7Z57SID.js.map → chunk-FHYVNJBN.js.map} +0 -0
  117. /package/dist/{chunk-33JKYLPX.js.map → chunk-GGRD3JEH.js.map} +0 -0
  118. /package/dist/{chunk-37KUQPX4.js.map → chunk-GNMELJGM.js.map} +0 -0
  119. /package/dist/{chunk-2IOHTUP3.js.map → chunk-GRCREL6Q.js.map} +0 -0
  120. /package/dist/{chunk-H54VWRPS.js.map → chunk-JJ4XK25O.js.map} +0 -0
  121. /package/dist/{chunk-SVXJLDDC.js.map → chunk-KH6PK4EQ.js.map} +0 -0
  122. /package/dist/{chunk-NLYVH66G.js.map → chunk-MT47LH5L.js.map} +0 -0
  123. /package/dist/{chunk-SMWTZLHE.js.map → chunk-MZLV2OJE.js.map} +0 -0
  124. /package/dist/{chunk-ICKJ52PE.js.map → chunk-OU4K7IFP.js.map} +0 -0
  125. /package/dist/{chunk-27QVNSQ3.js.map → chunk-QBH7M7Q4.js.map} +0 -0
  126. /package/dist/{chunk-O6ZNNVSP.js.map → chunk-RX3SC4C5.js.map} +0 -0
  127. /package/dist/{chunk-RJYJ7KR7.js.map → chunk-SO4IYSGT.js.map} +0 -0
  128. /package/dist/{chunk-C553ZTLF.js.map → chunk-THQTFTQS.js.map} +0 -0
  129. /package/dist/{chunk-X5K5TAQZ.js.map → chunk-V4ZBR7CW.js.map} +0 -0
  130. /package/dist/{chunk-ZIW5JVRM.js.map → chunk-XTJC7CVX.js.map} +0 -0
  131. /package/dist/{chunk-Z6COGHHN.js.map → chunk-Y2MZGBOY.js.map} +0 -0
  132. /package/dist/{chunk-H4SEGIZY.js.map → chunk-ZO2AZIRT.js.map} +0 -0
  133. /package/dist/{chunk-UNNPNBR2.js.map → chunk-ZUNNRGJX.js.map} +0 -0
  134. /package/dist/{chunk-BLJWYCNO.js.map → chunk-ZY4DSWZ5.js.map} +0 -0
@@ -4,7 +4,7 @@ import {
4
4
  SUPPORT_PASSPORT_MODEL_RESULT_PATH,
5
5
  SupportPassportModelBridge,
6
6
  parseSupportPassportModelJob
7
- } from "../chunk-27QVNSQ3.js";
7
+ } from "../chunk-QBH7M7Q4.js";
8
8
  import {
9
9
  DEFAULT_SUPPORT_PASSPORT_CONFIG,
10
10
  parseSupportPassportConfig
@@ -14,8 +14,8 @@ import {
14
14
  buildSupportPassportPublicRequestHandler,
15
15
  composeSupportPassportExternalRequestHandlers,
16
16
  normalizeSupportPassportNetworkAddress
17
- } from "../chunk-FVOP3NT7.js";
18
- import "../chunk-K7724CH2.js";
17
+ } from "../chunk-5IEV3YBY.js";
18
+ import "../chunk-6VF3R3XQ.js";
19
19
  import {
20
20
  SUPPORT_PASSPORT_DRAFT_MAX_CONTENT_CHARACTERS,
21
21
  SUPPORT_PASSPORT_DRAFT_MAX_MEMORIES,
@@ -56,7 +56,7 @@ import {
56
56
  notifySupportPassportCommitted,
57
57
  resolveSupportPassportModelRoutePlan,
58
58
  syncDirectoryForDurability
59
- } from "../chunk-ICKJ52PE.js";
59
+ } from "../chunk-OU4K7IFP.js";
60
60
  import "../chunk-W4F3C7N7.js";
61
61
  import "../chunk-MPC7TYTZ.js";
62
62
  import "../chunk-VVX5PZFS.js";
@@ -165,8 +165,8 @@ import "../chunk-R7QY5ZVB.js";
165
165
  import "../chunk-5WITETWU.js";
166
166
  import "../chunk-6CIAGZ6X.js";
167
167
  import "../chunk-UBCBDJOB.js";
168
- import "../chunk-L7Z57SID.js";
169
- import "../chunk-NLYVH66G.js";
168
+ import "../chunk-FHYVNJBN.js";
169
+ import "../chunk-MT47LH5L.js";
170
170
  import "../chunk-CSAKJVXW.js";
171
171
  import "../chunk-K2XUWZBM.js";
172
172
  import "../chunk-OD4FM2U7.js";
@@ -198,7 +198,7 @@ import "../chunk-QDW3E4RD.js";
198
198
  import "../chunk-B3O3IRZN.js";
199
199
  import "../chunk-NXH34IPL.js";
200
200
  import "../chunk-ZIKENA2C.js";
201
- import "../chunk-P6FHFTZ7.js";
201
+ import "../chunk-XPFC6D45.js";
202
202
  import "../chunk-VYCOJKSX.js";
203
203
  import "../chunk-6Q3ZTEF6.js";
204
204
  import "../chunk-W5BIQOAJ.js";
@@ -313,13 +313,13 @@ declare const CapsuleBlockSchema: z.ZodObject<{
313
313
  peerProfiles: boolean;
314
314
  }>;
315
315
  }, "strip", z.ZodTypeAny, {
316
+ schemaVersion: string;
316
317
  includes: {
317
318
  procedural: boolean;
318
319
  taxonomy: boolean;
319
320
  identityAnchors: boolean;
320
321
  peerProfiles: boolean;
321
322
  };
322
- schemaVersion: string;
323
323
  id: string;
324
324
  description: string;
325
325
  version: string;
@@ -334,13 +334,13 @@ declare const CapsuleBlockSchema: z.ZodObject<{
334
334
  forkRoot: string;
335
335
  } | null;
336
336
  }, {
337
+ schemaVersion: string;
337
338
  includes: {
338
339
  procedural: boolean;
339
340
  taxonomy: boolean;
340
341
  identityAnchors: boolean;
341
342
  peerProfiles: boolean;
342
343
  };
343
- schemaVersion: string;
344
344
  id: string;
345
345
  description: string;
346
346
  version: string;
@@ -464,13 +464,13 @@ declare const ExportManifestV2Schema: z.ZodObject<{
464
464
  peerProfiles: boolean;
465
465
  }>;
466
466
  }, "strip", z.ZodTypeAny, {
467
+ schemaVersion: string;
467
468
  includes: {
468
469
  procedural: boolean;
469
470
  taxonomy: boolean;
470
471
  identityAnchors: boolean;
471
472
  peerProfiles: boolean;
472
473
  };
473
- schemaVersion: string;
474
474
  id: string;
475
475
  description: string;
476
476
  version: string;
@@ -485,13 +485,13 @@ declare const ExportManifestV2Schema: z.ZodObject<{
485
485
  forkRoot: string;
486
486
  } | null;
487
487
  }, {
488
+ schemaVersion: string;
488
489
  includes: {
489
490
  procedural: boolean;
490
491
  taxonomy: boolean;
491
492
  identityAnchors: boolean;
492
493
  peerProfiles: boolean;
493
494
  };
494
- schemaVersion: string;
495
495
  id: string;
496
496
  description: string;
497
497
  version: string;
@@ -518,13 +518,13 @@ declare const ExportManifestV2Schema: z.ZodObject<{
518
518
  pluginVersion: string;
519
519
  includesTranscripts: boolean;
520
520
  capsule: {
521
+ schemaVersion: string;
521
522
  includes: {
522
523
  procedural: boolean;
523
524
  taxonomy: boolean;
524
525
  identityAnchors: boolean;
525
526
  peerProfiles: boolean;
526
527
  };
527
- schemaVersion: string;
528
528
  id: string;
529
529
  description: string;
530
530
  version: string;
@@ -551,13 +551,13 @@ declare const ExportManifestV2Schema: z.ZodObject<{
551
551
  pluginVersion: string;
552
552
  includesTranscripts: boolean;
553
553
  capsule: {
554
+ schemaVersion: string;
554
555
  includes: {
555
556
  procedural: boolean;
556
557
  taxonomy: boolean;
557
558
  identityAnchors: boolean;
558
559
  peerProfiles: boolean;
559
560
  };
560
- schemaVersion: string;
561
561
  id: string;
562
562
  description: string;
563
563
  version: string;
@@ -683,13 +683,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
683
683
  peerProfiles: boolean;
684
684
  }>;
685
685
  }, "strip", z.ZodTypeAny, {
686
+ schemaVersion: string;
686
687
  includes: {
687
688
  procedural: boolean;
688
689
  taxonomy: boolean;
689
690
  identityAnchors: boolean;
690
691
  peerProfiles: boolean;
691
692
  };
692
- schemaVersion: string;
693
693
  id: string;
694
694
  description: string;
695
695
  version: string;
@@ -704,13 +704,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
704
704
  forkRoot: string;
705
705
  } | null;
706
706
  }, {
707
+ schemaVersion: string;
707
708
  includes: {
708
709
  procedural: boolean;
709
710
  taxonomy: boolean;
710
711
  identityAnchors: boolean;
711
712
  peerProfiles: boolean;
712
713
  };
713
- schemaVersion: string;
714
714
  id: string;
715
715
  description: string;
716
716
  version: string;
@@ -737,13 +737,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
737
737
  pluginVersion: string;
738
738
  includesTranscripts: boolean;
739
739
  capsule: {
740
+ schemaVersion: string;
740
741
  includes: {
741
742
  procedural: boolean;
742
743
  taxonomy: boolean;
743
744
  identityAnchors: boolean;
744
745
  peerProfiles: boolean;
745
746
  };
746
- schemaVersion: string;
747
747
  id: string;
748
748
  description: string;
749
749
  version: string;
@@ -770,13 +770,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
770
770
  pluginVersion: string;
771
771
  includesTranscripts: boolean;
772
772
  capsule: {
773
+ schemaVersion: string;
773
774
  includes: {
774
775
  procedural: boolean;
775
776
  taxonomy: boolean;
776
777
  identityAnchors: boolean;
777
778
  peerProfiles: boolean;
778
779
  };
779
- schemaVersion: string;
780
780
  id: string;
781
781
  description: string;
782
782
  version: string;
@@ -815,13 +815,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
815
815
  pluginVersion: string;
816
816
  includesTranscripts: boolean;
817
817
  capsule: {
818
+ schemaVersion: string;
818
819
  includes: {
819
820
  procedural: boolean;
820
821
  taxonomy: boolean;
821
822
  identityAnchors: boolean;
822
823
  peerProfiles: boolean;
823
824
  };
824
- schemaVersion: string;
825
825
  id: string;
826
826
  description: string;
827
827
  version: string;
@@ -854,13 +854,13 @@ declare const ExportBundleV2Schema: z.ZodObject<{
854
854
  pluginVersion: string;
855
855
  includesTranscripts: boolean;
856
856
  capsule: {
857
+ schemaVersion: string;
857
858
  includes: {
858
859
  procedural: boolean;
859
860
  taxonomy: boolean;
860
861
  identityAnchors: boolean;
861
862
  peerProfiles: boolean;
862
863
  };
863
- schemaVersion: string;
864
864
  id: string;
865
865
  description: string;
866
866
  version: string;
@@ -1,4 +1,4 @@
1
- import { W as WhoKnowsResult } from './access-service-GrdVg_-Z.js';
1
+ import { W as WhoKnowsResult } from './access-service-Cv8Rizo0.js';
2
2
  import './types-YY-eKKU7.js';
3
3
  import './message-parts/index.js';
4
4
  import './bounded-jsonl-state.js';
@@ -1,4 +1,4 @@
1
- export { bA as WHO_KNOWS_AUTHORSHIP_BONUS, bB as WHO_KNOWS_DEFAULT_LIMIT, bC as WHO_KNOWS_MAX_EVIDENCE, bD as WHO_KNOWS_MAX_LIMIT, bE as WHO_KNOWS_MCP_TOOLS, bF as WhoKnowsEntity, bG as WhoKnowsEvidence, bH as WhoKnowsHit, bI as WhoKnowsHttpOutcome, W as WhoKnowsResult, bJ as WhoKnowsStorage, bT as computeWhoKnows, bZ as handleWhoKnowsHttpQuery, c2 as loadWhoKnowsEntities, c9 as tokenizeTopic, ca as validateWhoKnowsInput } from './access-service-GrdVg_-Z.js';
1
+ export { bA as WHO_KNOWS_AUTHORSHIP_BONUS, bB as WHO_KNOWS_DEFAULT_LIMIT, bC as WHO_KNOWS_MAX_EVIDENCE, bD as WHO_KNOWS_MAX_LIMIT, bE as WHO_KNOWS_MCP_TOOLS, bF as WhoKnowsEntity, bG as WhoKnowsEvidence, bH as WhoKnowsHit, bI as WhoKnowsHttpOutcome, W as WhoKnowsResult, bJ as WhoKnowsStorage, bT as computeWhoKnows, bZ as handleWhoKnowsHttpQuery, c2 as loadWhoKnowsEntities, c9 as tokenizeTopic, ca as validateWhoKnowsInput } from './access-service-Cv8Rizo0.js';
2
2
  import './types-YY-eKKU7.js';
3
3
  import './orchestrator-DgyvFfPR.js';
4
4
  import './recall-state.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/core",
3
- "version": "9.69.25",
3
+ "version": "9.69.26",
4
4
  "description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -3227,7 +3227,7 @@
3227
3227
  "core"
3228
3228
  ],
3229
3229
  "peerDependencies": {
3230
- "@remnic/coding-graph": "^9.69.25"
3230
+ "@remnic/coding-graph": "^9.69.26"
3231
3231
  },
3232
3232
  "peerDependenciesMeta": {
3233
3233
  "@remnic/coding-graph": {
@@ -2,6 +2,7 @@ import assert from "node:assert/strict";
2
2
  import { test } from "node:test";
3
3
 
4
4
  import {
5
+ activityDateInTimezone,
5
6
  activityDayWindow,
6
7
  activityDigestPath,
7
8
  composeActivityDigestBody,
@@ -162,6 +163,39 @@ test("activityDayWindow does not backdate a skipped local midnight", () => {
162
163
  assert.ok(local.startsWith("2026-04-24"), local);
163
164
  });
164
165
 
166
+ test("activityDayWindow keeps the last real day whole across an entirely skipped civil date", () => {
167
+ // Pacific/Apia jumped the date line at 2011-12-29 23:59:59-10:00 →
168
+ // 2011-12-31 00:00:00+14:00, so local 2011-12-30 never existed. Pre-fix,
169
+ // the skipped date's day start backdated into 2011-12-29, collapsing the
170
+ // 29th's window to identical bounds — a `wearables sync --date
171
+ // 2011-12-29` then dropped every Fireflies transcript of the day.
172
+ const w = activityDayWindow("2011-12-29", "Pacific/Apia");
173
+ assert.equal(w.startUtc, "2011-12-29T10:00:00.000Z"); // 2011-12-29 00:00 -10:00
174
+ assert.equal(w.endUtc, "2011-12-30T10:00:00.000Z"); // the jump instant
175
+ assert.ok(Date.parse(w.endUtc) > Date.parse(w.startUtc), "window must be non-degenerate");
176
+ // Attribution is exact: every instant in the window is locally the 29th.
177
+ assert.equal(activityDateInTimezone(new Date(w.startUtc), "Pacific/Apia"), "2011-12-29");
178
+ assert.equal(activityDateInTimezone(new Date(Date.parse(w.endUtc) - 1), "Pacific/Apia"), "2011-12-29");
179
+ });
180
+
181
+ test("activityDayWindow gives an entirely skipped civil date no interval", () => {
182
+ // 2011-12-30 never occurred in Pacific/Apia: the date-line jump went
183
+ // 2011-12-29 23:59:59-10:00 → 2011-12-31 00:00:00+14:00. The skipped
184
+ // date's nominal start and 2011-12-31's start both resolve to that jump
185
+ // instant, so its window is zero-width [jump, jump). A date that never
186
+ // occurred owns no interval: it must not adopt 2011-12-31's, which
187
+ // double-attributed the 31st's cards to two daily totals and made
188
+ // connector syncs for the skipped date fetch the 31st's records.
189
+ const w = activityDayWindow("2011-12-30", "Pacific/Apia");
190
+ assert.equal(w.startUtc, "2011-12-30T10:00:00.000Z"); // the jump instant
191
+ assert.equal(w.endUtc, w.startUtc); // zero-width: syncs nothing
192
+ // The 31st keeps its OWN window; no interval is shared with the skip.
193
+ const dec31 = activityDayWindow("2011-12-31", "Pacific/Apia");
194
+ assert.equal(dec31.startUtc, "2011-12-30T10:00:00.000Z");
195
+ assert.equal(dec31.endUtc, "2011-12-31T10:00:00.000Z");
196
+ assert.notDeepEqual(w, dec31);
197
+ });
198
+
165
199
  test("timeline keeps a second machine's span even with the same app/window", () => {
166
200
  const a = snap({ machine: "A", capturedAtUtc: "2026-03-10T14:00:00.000Z", app: "Chrome", windowTitle: "Doc", contentHash: "a1", text: "" });
167
201
  const b = snap({ machine: "B", capturedAtUtc: "2026-03-10T14:00:30.000Z", app: "Chrome", windowTitle: "Doc", contentHash: "b1", text: "" });
@@ -109,9 +109,24 @@ function zonedDayStartIso(date: string, timezone: string): string {
109
109
  }
110
110
  }
111
111
  if (best === null) {
112
- // Degenerate safety net: use the noon-derived offset for a deterministic start.
113
- const noon = timezoneOffsetIso(new Date(`${date}T12:00:00Z`), timezone);
114
- best = Date.parse(`${date}T00:00:00${noon}`);
112
+ // The ENTIRE civil date was skipped no local wall-clock time on it
113
+ // exists (Pacific/Apia 2011-12-30 is the canonical case: the date-line
114
+ // jump went 2011-12-29 23:59:59-10:00 → 2011-12-31 00:00:00+14:00).
115
+ // Extending the never-backdate convention above, resolve the day start
116
+ // to the transition instant: the earliest instant whose local calendar
117
+ // date reaches `date`. Local date is monotone non-decreasing in the UTC
118
+ // instant (a fall-back never crosses local midnight backwards), so
119
+ // binary-search a 48h bracket at minute granularity. The bracket is
120
+ // safe: `<date>T00:00Z − 24h` is always locally before `date`, and
121
+ // `<date>T00:00Z + 24h` is always locally on/after it.
122
+ let lo = Date.parse(`${date}T00:00:00Z`) - 24 * 3_600_000;
123
+ let hi = lo + 48 * 3_600_000;
124
+ while (hi - lo > 60_000) {
125
+ const mid = lo + Math.floor((hi - lo) / 2 / 60_000) * 60_000;
126
+ if (activityDateInTimezone(new Date(mid), timezone) >= date) hi = mid;
127
+ else lo = mid;
128
+ }
129
+ best = hi;
115
130
  }
116
131
  if (best === null || !Number.isFinite(best)) {
117
132
  throw new RangeError(`activity: could not resolve a local day start for "${date}" in "${timezone}".`);
@@ -129,16 +144,27 @@ function nextIsoDate(date: string): string {
129
144
  return shiftIsoDate(date, 1);
130
145
  }
131
146
 
132
- /** Half-open [start, end) UTC ISO bounds of a local day. */
147
+ /**
148
+ * Half-open [start, end) UTC ISO bounds of a local day. A civil date the
149
+ * zone skipped entirely owns no interval: the window is zero-width
150
+ * `[transition, transition)`.
151
+ */
133
152
  export function activityDayWindow(date: string, timezone: string): { startUtc: string; endUtc: string } {
134
153
  if (!isValidActivityDate(date)) {
135
154
  throw new RangeError(`Invalid activity date "${date}"; expected a real YYYY-MM-DD day.`);
136
155
  }
137
156
  assertValidTimezone(timezone);
138
- return {
139
- startUtc: new Date(zonedDayStartIso(date, timezone)).toISOString(),
140
- endUtc: new Date(zonedDayStartIso(nextIsoDate(date), timezone)).toISOString(),
141
- };
157
+ const startUtc = zonedDayStartIso(date, timezone);
158
+ const endUtc = zonedDayStartIso(nextIsoDate(date), timezone);
159
+ // Skipped-date semantics (Pacific/Apia 2011-12-30 class): the skipped
160
+ // date's start and the following date's start both resolve to the
161
+ // transition instant, so the window is naturally zero-width. Keep it
162
+ // that way: a date that never occurred contributes to no daily total
163
+ // (daysOverlappingWeek drops zero-width days) and a connector sync for
164
+ // it fetches nothing. Pushing the end forward to stay non-degenerate
165
+ // would alias the next real day's interval and double-attribute every
166
+ // card in it to two daily totals.
167
+ return { startUtc, endUtc };
142
168
  }
143
169
 
144
170
  /**
@@ -213,3 +213,32 @@ test("equal durations sort by categoryId ascending", () => {
213
213
  ["beta", "development", "alpha"],
214
214
  );
215
215
  });
216
+
217
+ test("a card is attributed to exactly one daily total across an entirely skipped civil date", () => {
218
+ // Pacific/Apia skipped local 2011-12-30 at the date-line jump. The
219
+ // skipped date owns a zero-width window, so it appears as no day entry,
220
+ // and the 31st's card lands on exactly one daily total — never also on
221
+ // the skipped date, which pre-fix shared the 31st's interval.
222
+ const summary = buildWeeklyActivitySummary(
223
+ [
224
+ // Dec 29 10:00-11:00 local (-10:00).
225
+ card({ id: "before-jump", startUtc: "2011-12-29T20:00:00.000Z", endUtc: "2011-12-29T21:00:00.000Z" }),
226
+ // Dec 31 02:00-03:00 local (+14:00).
227
+ card({ id: "after-jump", startUtc: "2011-12-30T12:00:00.000Z", endUtc: "2011-12-30T13:00:00.000Z" }),
228
+ ],
229
+ options({
230
+ timezone: "Pacific/Apia",
231
+ weekStartUtc: "2011-12-26T10:00:00.000Z",
232
+ weekEndUtc: "2012-01-02T10:00:00.000Z",
233
+ }),
234
+ );
235
+ assert.equal(summary.days.some((day) => day.date === "2011-12-30"), false);
236
+ const activeDays = summary.days.filter((day) => day.activeMs > 0);
237
+ assert.deepEqual(
238
+ activeDays.map((day) => [day.date, day.activeMs]),
239
+ [
240
+ ["2011-12-29", HOUR],
241
+ ["2011-12-31", HOUR],
242
+ ],
243
+ );
244
+ });
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/activity/digest.ts"],"sourcesContent":["/**\n * Deterministic screen-activity day-digest renderer (issue #1899).\n *\n * Renders a day's snapshots into markdown with YAML frontmatter, placed at\n * `<memoryDir>/activity/<date>.md` — outside the memory scan roots but inside\n * the QMD collection root (searchable, never auto-recalled). No LLM: the body\n * is a pure, byte-identical function of its inputs so an unchanged day skips\n * rewrite by contentHash. Day bucketing is DST-aware and half-open\n * [start, end) (AGENTS.md §23); sort keys are total with stable tiebreakers\n * (§12).\n */\n\nimport { createHash } from \"node:crypto\";\nimport path from \"node:path\";\n\nimport type { ActivityDayDigest, ActivityDayMeta, ActivitySnapshot } from \"./types.js\";\n\nexport const ACTIVITY_DIGEST_FORMAT_VERSION = 1;\nexport const ACTIVITY_DIR_NAME = \"activity\";\n\n/** Attribute at most this much dwell to a single snapshot (idle gaps capped). */\nconst MAX_DWELL_MS = 15 * 60_000;\n/** Notable-excerpt caps. */\nconst NOTABLE_MAX_WINDOWS = 10;\nconst NOTABLE_EXCERPT_CHARS = 280;\n\nconst DATE_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nexport function isValidActivityDate(date: string): boolean {\n if (typeof date !== \"string\" || !DATE_PATTERN.test(date)) return false;\n // Reject impossible calendar days (e.g. 2026-02-30, 2026-13-01): the UTC\n // round-trip must reproduce the same Y-M-D, else Date normalized an overflow.\n const parsed = new Date(`${date}T00:00:00Z`);\n return Number.isFinite(parsed.getTime()) && parsed.toISOString().slice(0, 10) === date;\n}\n\nexport function activityDigestPath(memoryDir: string, date: string): string {\n if (!isValidActivityDate(date)) {\n // Never interpolate an unvalidated date into a filesystem path (a `../`\n // would escape <memoryDir>/activity/). Reject loudly.\n throw new RangeError(`Invalid activity date \"${date}\"; expected YYYY-MM-DD.`);\n }\n return path.join(memoryDir, ACTIVITY_DIR_NAME, `${date}.md`);\n}\n\n// ── DST-aware local-day window ──────────────────────────────────────────────\n\nexport function timezoneOffsetIso(instant: Date, timezone: string): string {\n const parts = new Intl.DateTimeFormat(\"en-US\", {\n timeZone: timezone,\n timeZoneName: \"longOffset\",\n }).formatToParts(instant);\n const name = parts.find((part) => part.type === \"timeZoneName\")?.value ?? \"GMT\";\n const match = name.match(/GMT([+-]\\d{2}:\\d{2})?/);\n return match?.[1] ?? \"+00:00\";\n}\n\nexport function assertValidTimezone(timezone: string): void {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: timezone });\n } catch {\n throw new RangeError(`Invalid IANA timezone \"${timezone}\".`);\n }\n}\n\nfunction zonedDayStartIso(date: string, timezone: string): string {\n // The first UTC instant whose local wall-clock is this date at 00:00. Probe\n // several instants across the day to collect every offset in play; keep an\n // offset only if constructing local midnight with it lands back on that same\n // offset (so it is genuinely local midnight, not a wall-clock that never\n // occurred), then take the EARLIEST such instant — the FIRST 00:00 across a\n // DST fall-back that repeats local midnight.\n // Probe the previous UTC day too: for zones east of UTC the requested date's\n // UTC instants all fall after local midnight, so the pre-transition offset\n // valid at the real local 00:00 is only observable on the prior UTC day.\n const prevDate = shiftIsoDate(date, -1);\n const probeOffsets = new Set(\n [\n `${prevDate}T12:00:00Z`,\n `${prevDate}T23:00:00Z`,\n `${date}T00:00:00Z`,\n `${date}T12:00:00Z`,\n `${date}T23:00:00Z`,\n ].map((iso) => timezoneOffsetIso(new Date(iso), timezone)),\n );\n let best: number | null = null;\n for (const offset of probeOffsets) {\n const candidate = Date.parse(`${date}T00:00:00${offset}`);\n if (!Number.isFinite(candidate)) continue;\n // Reject an offset whose local midnight does not actually occur (the wall\n // clock skipped by a spring-forward): the offset in effect at the candidate\n // instant must be the same offset we used to build it.\n if (timezoneOffsetIso(new Date(candidate), timezone) !== offset) continue;\n if (best === null || candidate < best) best = candidate;\n }\n if (best === null) {\n // Local midnight was skipped by a spring-forward at 00:00. Advance to the\n // first local wall-clock minute on this date that actually exists (never\n // backdating to a 00:00 that never occurred), scanning forward up to 3h.\n for (let minute = 1; minute <= 180 && best === null; minute++) {\n const hh = String(Math.floor(minute / 60)).padStart(2, \"0\");\n const mm = String(minute % 60).padStart(2, \"0\");\n for (const offset of probeOffsets) {\n const candidate = Date.parse(`${date}T${hh}:${mm}:00${offset}`);\n if (!Number.isFinite(candidate)) continue;\n if (timezoneOffsetIso(new Date(candidate), timezone) !== offset) continue;\n if (best === null || candidate < best) best = candidate;\n }\n }\n }\n if (best === null) {\n // Degenerate safety net: use the noon-derived offset for a deterministic start.\n const noon = timezoneOffsetIso(new Date(`${date}T12:00:00Z`), timezone);\n best = Date.parse(`${date}T00:00:00${noon}`);\n }\n if (best === null || !Number.isFinite(best)) {\n throw new RangeError(`activity: could not resolve a local day start for \"${date}\" in \"${timezone}\".`);\n }\n return new Date(best).toISOString();\n}\n\nfunction shiftIsoDate(date: string, days: number): string {\n const parsed = new Date(`${date}T00:00:00Z`);\n parsed.setUTCDate(parsed.getUTCDate() + days);\n return parsed.toISOString().slice(0, 10);\n}\n\nfunction nextIsoDate(date: string): string {\n return shiftIsoDate(date, 1);\n}\n\n/** Half-open [start, end) UTC ISO bounds of a local day. */\nexport function activityDayWindow(date: string, timezone: string): { startUtc: string; endUtc: string } {\n if (!isValidActivityDate(date)) {\n throw new RangeError(`Invalid activity date \"${date}\"; expected a real YYYY-MM-DD day.`);\n }\n assertValidTimezone(timezone);\n return {\n startUtc: new Date(zonedDayStartIso(date, timezone)).toISOString(),\n endUtc: new Date(zonedDayStartIso(nextIsoDate(date), timezone)).toISOString(),\n };\n}\n\n/**\n * The local calendar day (YYYY-MM-DD) an instant falls in for an IANA\n * timezone — the day key `activityDayWindow` buckets on. Callers that need\n * \"today\" for activity artifacts MUST use this rather than the host-local\n * date, which drifts a day near either timezone's midnight.\n */\nexport function activityDateInTimezone(instant: Date, timezone: string): string {\n try {\n const parts = new Intl.DateTimeFormat(\"en-CA\", {\n timeZone: timezone,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n }).formatToParts(instant);\n const get = (type: string): string => parts.find((part) => part.type === type)?.value ?? \"\";\n return `${get(\"year\")}-${get(\"month\")}-${get(\"day\")}`;\n } catch {\n return instant.toISOString().slice(0, 10);\n }\n}\n\n// ── Rendering ───────────────────────────────────────────────────────────────\n\nfunction sortedByTime(snapshots: ActivitySnapshot[]): ActivitySnapshot[] {\n return [...snapshots].sort((a, b) => {\n // Compare by parsed instant, not raw string, so mixed valid ISO forms\n // (Z vs offset, varying precision) still order chronologically.\n const at = Date.parse(a.capturedAtUtc);\n const bt = Date.parse(b.capturedAtUtc);\n if (at !== bt && Number.isFinite(at) && Number.isFinite(bt)) return at < bt ? -1 : 1;\n const aid = a.id ?? 0;\n const bid = b.id ?? 0;\n if (aid < bid) return -1;\n if (aid > bid) return 1;\n // Unsaved snapshots (pre-store) both default to id 0; fall back to the\n // content hash (their dedup identity), then app/window, for a total order.\n if (a.contentHash !== b.contentHash) return a.contentHash < b.contentHash ? -1 : 1;\n if (a.app !== b.app) return a.app < b.app ? -1 : 1;\n if (a.windowTitle !== b.windowTitle) return a.windowTitle < b.windowTitle ? -1 : 1;\n return 0;\n });\n}\n\n/**\n * Per-snapshot dwell (gap to that machine's next snapshot, capped), scoped per\n * capture machine so an interleaved snapshot from another machine can't steal\n * or truncate a snapshot's dwell (multi-machine days).\n */\nfunction computeDwell(snapshots: ActivitySnapshot[]): Map<ActivitySnapshot, number> {\n const byMachine = new Map<string, ActivitySnapshot[]>();\n for (const snapshot of snapshots) {\n const list = byMachine.get(snapshot.machine);\n if (list === undefined) byMachine.set(snapshot.machine, [snapshot]);\n else list.push(snapshot);\n }\n const dwell = new Map<ActivitySnapshot, number>();\n for (const list of byMachine.values()) {\n const ordered = sortedByTime(list);\n for (let index = 0; index < ordered.length; index++) {\n const current = ordered[index];\n if (current === undefined) continue;\n const next = ordered[index + 1];\n let value = 0;\n if (next !== undefined) {\n const delta = Date.parse(next.capturedAtUtc) - Date.parse(current.capturedAtUtc);\n if (Number.isFinite(delta) && delta > 0) value = Math.min(delta, MAX_DWELL_MS);\n }\n dwell.set(current, value);\n }\n }\n return dwell;\n}\n\nfunction formatDurationMinutes(ms: number): string {\n return `${Math.round(ms / 60_000)}m`;\n}\n\nfunction clockHhMm(iso: string, timezone: string): string {\n const ms = Date.parse(iso);\n if (!Number.isFinite(ms)) return \"??:??\";\n const parts = new Intl.DateTimeFormat(\"en-GB\", {\n timeZone: timezone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false,\n }).formatToParts(new Date(ms));\n const hour = parts.find((p) => p.type === \"hour\")?.value ?? \"00\";\n const minute = parts.find((p) => p.type === \"minute\")?.value ?? \"00\";\n return `${hour}:${minute}`;\n}\n\nfunction collapseWhitespace(text: string): string {\n return text.replace(/\\s+/g, \" \").trim();\n}\n\nfunction perAppSection(ordered: ActivitySnapshot[], dwell: Map<ActivitySnapshot, number>): string {\n const totals = new Map<string, number>();\n for (const snapshot of ordered) {\n totals.set(snapshot.app, (totals.get(snapshot.app) ?? 0) + (dwell.get(snapshot) ?? 0));\n }\n const rows = [...totals.entries()].sort((a, b) => {\n if (b[1] !== a[1]) return b[1] - a[1];\n if (a[0] < b[0]) return -1;\n if (a[0] > b[0]) return 1;\n return 0;\n });\n const lines = [\"## Per-app time\", \"\"];\n if (rows.length === 0) {\n lines.push(\"_No activity recorded._\");\n } else {\n for (const [app, ms] of rows) {\n lines.push(`- ${app}: ${formatDurationMinutes(ms)}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\ninterface TimelineSpan {\n startIso: string;\n machine: string;\n app: string;\n windowTitle: string;\n browserUrl?: string;\n}\n\nfunction timelineSpans(ordered: ActivitySnapshot[]): TimelineSpan[] {\n const spans: TimelineSpan[] = [];\n for (const snapshot of ordered) {\n const last = spans[spans.length - 1];\n if (\n last !== undefined &&\n last.machine === snapshot.machine &&\n last.app === snapshot.app &&\n last.windowTitle === snapshot.windowTitle &&\n last.browserUrl === snapshot.browserUrl\n ) {\n continue;\n }\n spans.push({\n startIso: snapshot.capturedAtUtc,\n machine: snapshot.machine,\n app: snapshot.app,\n windowTitle: snapshot.windowTitle,\n ...(snapshot.browserUrl !== undefined ? { browserUrl: snapshot.browserUrl } : {}),\n });\n }\n return spans;\n}\n\nfunction timelineSection(ordered: ActivitySnapshot[], timezone: string): string {\n const lines = [\"## Timeline\", \"\"];\n const spans = timelineSpans(ordered);\n if (spans.length === 0) {\n lines.push(\"_No activity recorded._\");\n return lines.join(\"\\n\");\n }\n for (const span of spans) {\n const clock = clockHhMm(span.startIso, timezone);\n const window = collapseWhitespace(span.windowTitle);\n const url = span.browserUrl !== undefined ? ` (${collapseWhitespace(span.browserUrl)})` : \"\";\n lines.push(`- [${clock}] ${span.app}${window.length > 0 ? ` — ${window}` : \"\"}${url}`);\n }\n return lines.join(\"\\n\");\n}\n\nfunction notableSection(ordered: ActivitySnapshot[], dwell: Map<ActivitySnapshot, number>): string {\n const withDwell = ordered.map((snapshot) => ({ snapshot, dwell: dwell.get(snapshot) ?? 0 }));\n const ranked = withDwell\n .filter((entry) => collapseWhitespace(entry.snapshot.text).length > 0)\n .sort((a, b) => {\n if (b.dwell !== a.dwell) return b.dwell - a.dwell;\n const at = Date.parse(a.snapshot.capturedAtUtc);\n const bt = Date.parse(b.snapshot.capturedAtUtc);\n if (at !== bt && Number.isFinite(at) && Number.isFinite(bt)) return at < bt ? -1 : 1;\n const idDelta = (a.snapshot.id ?? 0) - (b.snapshot.id ?? 0);\n if (idDelta !== 0) return idDelta;\n if (a.snapshot.contentHash !== b.snapshot.contentHash) {\n return a.snapshot.contentHash < b.snapshot.contentHash ? -1 : 1;\n }\n return 0;\n })\n .slice(0, NOTABLE_MAX_WINDOWS);\n const lines = [\"## Notable\", \"\"];\n if (ranked.length === 0) {\n lines.push(\"_No notable text captured._\");\n return lines.join(\"\\n\");\n }\n for (const { snapshot } of ranked) {\n const excerpt = collapseWhitespace(snapshot.text).slice(0, NOTABLE_EXCERPT_CHARS);\n lines.push(`- **${snapshot.app}** — ${excerpt}`);\n }\n return lines.join(\"\\n\");\n}\n\nexport function composeActivityDigestBody(\n date: string,\n timezone: string,\n snapshots: ActivitySnapshot[],\n): string {\n assertValidTimezone(timezone);\n const ordered = sortedByTime(snapshots);\n const dwell = computeDwell(ordered);\n return [\n `# Activity — ${date}`,\n \"\",\n perAppSection(ordered, dwell),\n \"\",\n timelineSection(ordered, timezone),\n \"\",\n notableSection(ordered, dwell),\n \"\",\n ].join(\"\\n\");\n}\n\nexport function hashActivityBody(body: string): string {\n return createHash(\"sha256\").update(body, \"utf8\").digest(\"hex\");\n}\n\nexport function composeActivityDigestMeta(\n date: string,\n machines: string[],\n snapshots: ActivitySnapshot[],\n body: string,\n): ActivityDayMeta {\n const uniqueMachines = [...new Set(machines)].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n return {\n kind: \"activity-digest\",\n date,\n machines: uniqueMachines,\n snapshotCount: snapshots.length,\n contentHash: hashActivityBody(body),\n formatVersion: ACTIVITY_DIGEST_FORMAT_VERSION,\n };\n}\n\nexport function serializeActivityDigest(meta: ActivityDayMeta, body: string): string {\n const frontmatter = [\n \"---\",\n `kind: ${meta.kind}`,\n `date: ${meta.date}`,\n `machines: ${JSON.stringify(meta.machines)}`,\n `snapshotCount: ${meta.snapshotCount}`,\n `contentHash: ${meta.contentHash}`,\n `formatVersion: ${meta.formatVersion}`,\n \"---\",\n \"\",\n ].join(\"\\n\");\n return `${frontmatter}${body}`;\n}\n\nexport function parseActivityDigest(raw: string): ActivityDayDigest | null {\n if (typeof raw !== \"string\" || !raw.startsWith(\"---\\n\")) return null;\n const end = raw.indexOf(\"\\n---\\n\", 4);\n if (end === -1) return null;\n const frontmatter = raw.slice(4, end);\n const body = raw.slice(end + 5).replace(/^\\n/, \"\");\n const fields = new Map<string, string>();\n for (const line of frontmatter.split(\"\\n\")) {\n const idx = line.indexOf(\":\");\n if (idx === -1) continue;\n fields.set(line.slice(0, idx).trim(), line.slice(idx + 1).trim());\n }\n const date = fields.get(\"date\");\n const contentHash = fields.get(\"contentHash\");\n if (date === undefined || !isValidActivityDate(date) || contentHash === undefined) return null;\n if (fields.get(\"kind\") !== \"activity-digest\") return null;\n const machines = parseMachinesList(fields.get(\"machines\") ?? \"[]\");\n const snapshotCount = parseNonNegativeInt(fields.get(\"snapshotCount\"));\n const formatVersion = parseNonNegativeInt(fields.get(\"formatVersion\"));\n if (snapshotCount === null || formatVersion === null) return null;\n return {\n meta: {\n kind: \"activity-digest\",\n date,\n machines,\n snapshotCount,\n contentHash,\n formatVersion,\n },\n body,\n };\n}\n\nfunction parseNonNegativeInt(value: string | undefined): number | null {\n if (value === undefined) return null;\n const trimmed = value.trim();\n if (!/^\\d+$/.test(trimmed)) return null;\n const parsed = Number(trimmed);\n return Number.isSafeInteger(parsed) ? parsed : null;\n}\n\nfunction parseMachinesList(raw: string): string[] {\n try {\n const parsed: unknown = JSON.parse(raw);\n if (Array.isArray(parsed)) {\n return parsed.filter((entry): entry is string => typeof entry === \"string\");\n }\n } catch {\n // Legacy unquoted inline form (`[a, b]`) — fall through to the split parse.\n }\n return raw\n .replace(/^\\[/, \"\")\n .replace(/\\]$/, \"\")\n .split(\",\")\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0);\n}\n"],"mappings":"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","names":[]}
@@ -1098,34 +1098,34 @@ declare const SupportPassportDraftModelInputSchema: z.ZodEffects<z.ZodObject<{
1098
1098
  memoryId: z.ZodString;
1099
1099
  content: z.ZodString;
1100
1100
  }, "strict", z.ZodTypeAny, {
1101
- content: string;
1102
1101
  memoryId: string;
1103
- }, {
1104
1102
  content: string;
1103
+ }, {
1105
1104
  memoryId: string;
1105
+ content: string;
1106
1106
  }>, "many">;
1107
1107
  }, "strict", z.ZodTypeAny, {
1108
1108
  memories: {
1109
- content: string;
1110
1109
  memoryId: string;
1110
+ content: string;
1111
1111
  }[];
1112
1112
  consent: true;
1113
1113
  }, {
1114
1114
  memories: {
1115
- content: string;
1116
1115
  memoryId: string;
1116
+ content: string;
1117
1117
  }[];
1118
1118
  consent: true;
1119
1119
  }>, {
1120
1120
  memories: {
1121
- content: string;
1122
1121
  memoryId: string;
1122
+ content: string;
1123
1123
  }[];
1124
1124
  consent: true;
1125
1125
  }, {
1126
1126
  memories: {
1127
- content: string;
1128
1127
  memoryId: string;
1128
+ content: string;
1129
1129
  }[];
1130
1130
  consent: true;
1131
1131
  }>;