dsh-notch 0.3.1 → 0.3.6

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 (102) hide show
  1. package/README.en.md +58 -47
  2. package/README.md +60 -55
  3. package/cordis.patch.yml +3 -0
  4. package/desktop/README.md +29 -0
  5. package/desktop/notch-lifecycle.mjs +120 -0
  6. package/desktop/restart-probe.mjs +61 -0
  7. package/docs/desktop-017rc2.md +23 -0
  8. package/docs/elastic-edge-dock.md +127 -0
  9. package/docs/motion-audit.md +1 -1
  10. package/docs/releases/v0.3.2.md +38 -0
  11. package/docs/releases/v0.3.3.md +9 -0
  12. package/docs/subagent-compatibility.md +51 -0
  13. package/docs/verification/elastic-algorithm-timing.json +337 -0
  14. package/docs/verification/elastic-attention.json +44 -0
  15. package/docs/verification/elastic-frame-timing.json +240 -0
  16. package/docs/verification/elastic-tension.json +59 -0
  17. package/docs/verification/elastic-tip-taper.json +181 -0
  18. package/dshx.yml +2 -0
  19. package/lib/client.js +112 -0
  20. package/lib/client.js.map +1 -0
  21. package/lib/index.mjs +990 -0
  22. package/lib/index.mjs.map +1 -0
  23. package/package.json +66 -10
  24. package/src/board.ts +178 -35
  25. package/src/client/index.ts +104 -0
  26. package/src/dsh-notch.ts +19 -2
  27. package/src/http.ts +17 -2
  28. package/src/session-state.ts +15 -1
  29. package/src/store.ts +3 -3
  30. package/src/types.ts +3 -0
  31. package/BASELINE.md +0 -13
  32. package/DESIGN.md +0 -34
  33. package/cordis.yml +0 -5
  34. package/macos/Package.swift +0 -17
  35. package/macos/STATUS-MOTION.md +0 -49
  36. package/macos/Sources/Client.swift +0 -139
  37. package/macos/Sources/IdleRobot.swift +0 -423
  38. package/macos/Sources/NotchMarkdown.swift +0 -266
  39. package/macos/Sources/Panel.swift +0 -153
  40. package/macos/Sources/Resources/Idle/balance.json +0 -1
  41. package/macos/Sources/Resources/Idle/blink.json +0 -1
  42. package/macos/Sources/Resources/Idle/cube-in.json +0 -1
  43. package/macos/Sources/Resources/Idle/dance.json +0 -1
  44. package/macos/Sources/Resources/Idle/hop.json +0 -1
  45. package/macos/Sources/Resources/Idle/nod.json +0 -1
  46. package/macos/Sources/Resources/Idle/satellite-in.json +0 -1
  47. package/macos/Sources/Resources/Idle/satellite-out.json +0 -1
  48. package/macos/Sources/Resources/Idle/scan.json +0 -1
  49. package/macos/Sources/Resources/Idle/sleep.json +0 -1
  50. package/macos/Sources/Resources/Idle/sneeze.json +0 -1
  51. package/macos/Sources/Resources/Idle/stretch.json +0 -1
  52. package/macos/Sources/Resources/Idle/tilt.json +0 -1
  53. package/macos/Sources/ReviewStudio.swift +0 -337
  54. package/macos/Sources/RootView.swift +0 -1093
  55. package/macos/Sources/StatusOrbit.swift +0 -642
  56. package/macos/Sources/main.swift +0 -153
  57. package/macos/Tests/ExpandedHeightProbe.swift +0 -108
  58. package/macos/Tests/GeometryProbe.swift +0 -98
  59. package/macos/Tests/IdleProbe.swift +0 -294
  60. package/macos/Tests/MotionProbe.swift +0 -106
  61. package/macos/Tests/OutcomeProbe.swift +0 -133
  62. package/macos/Tests/ScrollbarProbe.swift +0 -91
  63. package/macos/Tests/expanded-height.sh +0 -13
  64. package/macos/Tests/geometry.sh +0 -14
  65. package/macos/Tests/idle.sh +0 -14
  66. package/macos/Tests/motion.sh +0 -14
  67. package/macos/Tests/outcome.sh +0 -14
  68. package/macos/Tests/scrollbar.sh +0 -13
  69. package/tests/answer-lifecycle.test.mjs +0 -23
  70. package/tests/board.test.mjs +0 -7
  71. package/tests/browse-sync.test.mjs +0 -20
  72. package/tests/mirror.test.mjs +0 -4
  73. package/tests/peer-range.test.mjs +0 -21
  74. package/tests/session-state.test.mjs +0 -54
  75. package/tests/unread-hold.test.mjs +0 -90
  76. package/tools/desktop-shell/README.md +0 -56
  77. package/tools/desktop-shell/child-log.mjs +0 -6
  78. package/tools/desktop-shell/child-log.test.mjs +0 -14
  79. package/tools/desktop-shell/package-recovery.py +0 -78
  80. package/tools/desktop-shell/recovery-probe.cjs +0 -50
  81. package/tools/desktop-shell/renderer-recovery.mjs +0 -95
  82. package/tools/desktop-shell/renderer-recovery.test.mjs +0 -24
  83. package/tools/diagnostics/completion-watch.py +0 -101
  84. package/tools/diagnostics/completion-watch.test.py +0 -17
  85. package/tools/diagnostics/renderer-diagnostics.mjs +0 -56
  86. package/tools/diagnostics/renderer-diagnostics.test.mjs +0 -32
  87. package/tools/idle/LICENSE.open-bot-motion +0 -21
  88. package/tools/idle/export.mjs +0 -40
  89. package/tools/idle/index.html +0 -4
  90. package/tools/idle/motions.js +0 -83
  91. package/tools/idle/original.js +0 -1673
  92. package/tools/idle/renderer.js +0 -1673
  93. package/tools/recording/Client.swift +0 -76
  94. package/tools/recording/DemoCatalog.swift +0 -174
  95. package/tools/recording/README.md +0 -23
  96. package/tools/recording/build.sh +0 -41
  97. package/tools/recording/main.swift +0 -100
  98. package/tools/review/ReviewStudio.swift +0 -236
  99. package/tools/review/audit.sh +0 -19
  100. package/tools/review/build.sh +0 -7
  101. package/tools/review/main.swift +0 -158
  102. package/tools/review/render-audit.swift +0 -32
@@ -0,0 +1,240 @@
1
+ {
2
+ "date": "2026-09-21",
3
+ "scope": "native standalone preview, offline fixture; three sequential runs",
4
+ "measurement": "App callback and submission timings, not screen-presented FPS. No screenshot or AX reads during each measured spring.",
5
+ "runs": [
6
+ {
7
+ "clock": "display-link",
8
+ "compositorSamples": 120,
9
+ "frames": 58,
10
+ "intervalMaxMs": 34.861375112086535,
11
+ "intervalP50Ms": 16.670416574925184,
12
+ "intervalP95Ms": 27.959875063970685,
13
+ "intervalsMs": [
14
+ 34.861375112086535,
15
+ 6.5582916140556335,
16
+ 17.302874941378832,
17
+ 27.959875063970685,
18
+ 4.727249965071678,
19
+ 16.68958319351077,
20
+ 16.676291823387146,
21
+ 16.656999941915274,
22
+ 16.710041789337993,
23
+ 16.63812482729554,
24
+ 16.635666834190488,
25
+ 16.894708154723048,
26
+ 16.461375169456005,
27
+ 16.690499847754836,
28
+ 16.629958292469382,
29
+ 16.67537516914308,
30
+ 16.701333224773407,
31
+ 16.626625088974833,
32
+ 16.66125003248453,
33
+ 16.679874854162335,
34
+ 16.670500161126256,
35
+ 16.679083229973912,
36
+ 16.634916653856635,
37
+ 17.509999917820096,
38
+ 15.84966666996479,
39
+ 16.700958367437124,
40
+ 16.670083394274116,
41
+ 16.616750042885542,
42
+ 16.661958303302526,
43
+ 29.162166640162468,
44
+ 16.80866675451398,
45
+ 16.519750002771616,
46
+ 16.673249891027808,
47
+ 16.665916657075286,
48
+ 17.111875116825104,
49
+ 16.247541643679142,
50
+ 16.651041572913527,
51
+ 16.663541784510016,
52
+ 16.789041692391038,
53
+ 16.586166573688388,
54
+ 16.847874969244003,
55
+ 16.50799997150898,
56
+ 16.65875012986362,
57
+ 16.600583214312792,
58
+ 16.665666596964,
59
+ 16.67720847763121,
60
+ 29.471416724845767,
61
+ 16.37149997986853,
62
+ 21.077791694551706,
63
+ 12.238583294674754,
64
+ 16.670416574925184,
65
+ 16.693166689947248,
66
+ 16.671125078573823,
67
+ 16.654749866575003,
68
+ 16.653666738420725,
69
+ 16.677791718393564,
70
+ 16.674875048920512,
71
+ 16.727374866604805
72
+ ],
73
+ "intervalsOver20Ms": 5,
74
+ "maskAllocations": 0,
75
+ "renderCostsMs": [
76
+ 10.3794583119452,
77
+ 4.547208547592163
78
+ ],
79
+ "renderMaxMs": 10.3794583119452,
80
+ "renderP95Ms": 4.547208547592163,
81
+ "renderUpdates": 2,
82
+ "windowResizes": 1
83
+ },
84
+ {
85
+ "clock": "display-link",
86
+ "compositorSamples": 120,
87
+ "frames": 58,
88
+ "intervalMaxMs": 45.83350010216236,
89
+ "intervalP50Ms": 16.659375047311187,
90
+ "intervalP95Ms": 18.008749932050705,
91
+ "intervalsMs": [
92
+ 45.83350010216236,
93
+ 13.767875032499433,
94
+ 16.680291621014476,
95
+ 16.768416622653604,
96
+ 16.571083338931203,
97
+ 16.666125040501356,
98
+ 16.655208310112357,
99
+ 16.658708453178406,
100
+ 29.17316649109125,
101
+ 16.645625000819564,
102
+ 16.684375004842877,
103
+ 16.65845839306712,
104
+ 16.706958413124084,
105
+ 16.65320829488337,
106
+ 16.644291579723358,
107
+ 16.733000054955482,
108
+ 16.59420831128955,
109
+ 16.801791731268167,
110
+ 16.545583261176944,
111
+ 16.652125166729093,
112
+ 16.647166572511196,
113
+ 16.699291532859206,
114
+ 16.753416741266847,
115
+ 16.576166730374098,
116
+ 17.028999980539083,
117
+ 16.30649995058775,
118
+ 16.661833273246884,
119
+ 16.68858341872692,
120
+ 16.653750091791153,
121
+ 16.809833236038685,
122
+ 16.534083290025592,
123
+ 16.64741663262248,
124
+ 16.697958344593644,
125
+ 16.642083413898945,
126
+ 16.647791722789407,
127
+ 16.684541711583734,
128
+ 16.660250024870038,
129
+ 16.666874988004565,
130
+ 16.64449996314943,
131
+ 16.671291552484035,
132
+ 16.659375047311187,
133
+ 16.676625004038215,
134
+ 16.673750011250377,
135
+ 16.65204158052802,
136
+ 16.702250111848116,
137
+ 29.168333392590284,
138
+ 16.644374933093786,
139
+ 16.646916745230556,
140
+ 18.008749932050705,
141
+ 17.02083321288228,
142
+ 15.007750131189823,
143
+ 16.67208317667246,
144
+ 16.654000151902437,
145
+ 16.73354161903262,
146
+ 16.651625046506524,
147
+ 16.60141651518643,
148
+ 16.678583342581987,
149
+ 16.646250151097775
150
+ ],
151
+ "intervalsOver20Ms": 3,
152
+ "maskAllocations": 0,
153
+ "renderCostsMs": [
154
+ 35.23687506094575,
155
+ 5.80887496471405
156
+ ],
157
+ "renderMaxMs": 35.23687506094575,
158
+ "renderP95Ms": 5.80887496471405,
159
+ "renderUpdates": 2,
160
+ "windowResizes": 1
161
+ },
162
+ {
163
+ "clock": "display-link",
164
+ "compositorSamples": 120,
165
+ "frames": 57,
166
+ "intervalMaxMs": 102.5239999871701,
167
+ "intervalP50Ms": 16.665458446368575,
168
+ "intervalP95Ms": 17.20512518659234,
169
+ "intervalsMs": [
170
+ 102.5239999871701,
171
+ 15.44966665096581,
172
+ 16.794208204373717,
173
+ 16.616000095382333,
174
+ 16.61158329807222,
175
+ 16.665458446368575,
176
+ 16.661708243191242,
177
+ 16.653791768476367,
178
+ 16.693041659891605,
179
+ 16.645999858155847,
180
+ 16.68491680175066,
181
+ 16.81279158219695,
182
+ 16.54229173436761,
183
+ 16.641666647046804,
184
+ 16.73054159618914,
185
+ 16.586333280429244,
186
+ 16.68279175646603,
187
+ 16.65116660296917,
188
+ 16.684166621416807,
189
+ 16.651500016450882,
190
+ 16.711875097826123,
191
+ 16.640166752040386,
192
+ 16.673874808475375,
193
+ 17.121833516284823,
194
+ 16.29924983717501,
195
+ 16.609833342954516,
196
+ 16.631250036880374,
197
+ 16.656041610985994,
198
+ 16.712750075384974,
199
+ 16.625666758045554,
200
+ 16.857333248481154,
201
+ 16.483458224684,
202
+ 16.673958394676447,
203
+ 16.668041702359915,
204
+ 16.648708377033472,
205
+ 16.663458198308945,
206
+ 16.690250020474195,
207
+ 16.63700002245605,
208
+ 16.687999945133924,
209
+ 18.626208417117596,
210
+ 14.73579159937799,
211
+ 16.88995840959251,
212
+ 16.521958401426673,
213
+ 16.5498333517462,
214
+ 16.705666668713093,
215
+ 16.667249845340848,
216
+ 17.20512518659234,
217
+ 28.595958137884736,
218
+ 16.68762508779764,
219
+ 16.804791754111648,
220
+ 16.49824995547533,
221
+ 16.728000016883016,
222
+ 16.62554149515927,
223
+ 16.662541776895523,
224
+ 16.684375004842877,
225
+ 16.643166542053223,
226
+ 16.781875165179372
227
+ ],
228
+ "intervalsOver20Ms": 2,
229
+ "maskAllocations": 0,
230
+ "renderCostsMs": [
231
+ 17.371458234265447,
232
+ 7.285375148057938
233
+ ],
234
+ "renderMaxMs": 17.371458234265447,
235
+ "renderP95Ms": 7.285375148057938,
236
+ "renderUpdates": 2,
237
+ "windowResizes": 1
238
+ }
239
+ ]
240
+ }
@@ -0,0 +1,59 @@
1
+ {
2
+ "date": "2026-09-23",
3
+ "baselineCommit": "36476b7df0e0333d50caffac05c90b185f647c44",
4
+ "scope": "Independent offline preview; no model calls or production replacement.",
5
+ "interaction": {
6
+ "freeDragPt": 128,
7
+ "asymptoticDragLimitPt": 240,
8
+ "limitScope": "per gesture, relative to the currently grabbed presentation",
9
+ "minimumCrossSectionScale": 0.44,
10
+ "contentsScaled": false
11
+ },
12
+ "algorithmBenchmark": {
13
+ "checksum": 11375661.124222511,
14
+ "geometry4800Frames": {
15
+ "maxMs": 64.04845835641026,
16
+ "medianMs": 50.329541554674506,
17
+ "microsecondsPerUnit": 10.485321157223856,
18
+ "runsMs": [
19
+ 44.830458238720894,
20
+ 64.04845835641026,
21
+ 58.664583368226886,
22
+ 48.70574991218746,
23
+ 50.329541554674506,
24
+ 46.03920830413699,
25
+ 51.87262501567602,
26
+ 55.251500103622675,
27
+ 49.07295829616487
28
+ ]
29
+ },
30
+ "solver240kSteps": {
31
+ "maxMs": 1.7863749526441097,
32
+ "medianMs": 1.5902500599622726,
33
+ "microsecondsPerUnit": 0.006626041916509469,
34
+ "runsMs": [
35
+ 1.7863749526441097,
36
+ 1.5902500599622726,
37
+ 1.7777499742805958,
38
+ 1.235166797414422,
39
+ 1.239958219230175,
40
+ 1.6297083348035812,
41
+ 1.6515832394361496,
42
+ 1.5842083375900984,
43
+ 1.5505000483244658
44
+ ]
45
+ }
46
+ },
47
+ "measurementLimits": "CPU microbenchmark only; does not measure display FPS. New shape computation has additional cost. Preview UI was not instrumented for a frame-rate claim.",
48
+ "verification": {
49
+ "javascriptPassed": 59,
50
+ "edgeDock": "FAILURES=0",
51
+ "denseSamples": 122,
52
+ "submittedSamples": 90,
53
+ "maximumHeldTranslationErrorPt": 0.02479452620063487,
54
+ "nativeSnapshots": "32/80/140/220 pt horizontal, diagonal, up/down, hidden cap and 60 return frames inspected",
55
+ "nativeInteraction": "Long diagonal drag reached hidden state; later native state showed restored idle."
56
+ },
57
+ "previewBinarySHA256": "e93c9b8e77f560e4868ae3189c5e688281172a3aee562efd54c907aaae53649a",
58
+ "productionBinarySHA256Unchanged": "2cdfe64bf7b4872dad9db81a0fa08cffab3d61da6cffa7cf513477e2ab3e2896"
59
+ }
@@ -0,0 +1,181 @@
1
+ {
2
+ "date": "2026-09-23",
3
+ "scope": "Independent native elastic preview; production DSH not replaced",
4
+ "reason": "The previous shape pinched only the middle and retained a thick grabbed end. The free end must itself become thinner.",
5
+ "geometry": {
6
+ "profile": "6t^5 - 15t^4 + 10t^3, clamped to 0 at attachment and 1 throughout grabbed body",
7
+ "tipScale": "1 - 0.56 L^2 / (L^2 + 75^2)",
8
+ "horizontalSamples": [
9
+ {
10
+ "inwardPt": 0,
11
+ "tipHeightPt": 44.0
12
+ },
13
+ {
14
+ "inwardPt": 32,
15
+ "tipHeightPt": 40.2052398856971
16
+ },
17
+ {
18
+ "inwardPt": 80,
19
+ "tipHeightPt": 30.885987525987524
20
+ },
21
+ {
22
+ "inwardPt": 140,
23
+ "tipHeightPt": 24.854549058473737
24
+ },
25
+ {
26
+ "inwardPt": 220,
27
+ "tipHeightPt": 21.925478944932898
28
+ }
29
+ ],
30
+ "content": "The same normal-axis contraction, centered on the body and compensated for the actual AppKit layer anchor"
31
+ },
32
+ "checks": {
33
+ "edgeDock": "PASS, FAILURES=0",
34
+ "nativeGeometry": "PASS, FAILURES=0",
35
+ "releasePreviewBuild": "PASS",
36
+ "nativeInteraction": [
37
+ "Short, medium and long held stretches show a progressively thinner free end and aligned robot",
38
+ "Diagonal drag tucks; dragging the exposed edge restores",
39
+ "Dragging from an option does not submit it; restoring still shows one pending decision",
40
+ "A single click on the restored option changes pending decision 1 to running 1"
41
+ ]
42
+ },
43
+ "previewBinarySha256": "cdfd84e041275c9e9980ec5aad746d60a8e0208f8520af7022062393b1b3f13c",
44
+ "unchangedProductionBinarySha256": "2cdfe64bf7b4872dad9db81a0fa08cffab3d61da6cffa7cf513477e2ab3e2896",
45
+ "cpuBenchmark": {
46
+ "checksum": 11375164.315598244,
47
+ "geometry4800Frames": {
48
+ "maxMs": 80.45195834711194,
49
+ "medianMs": 65.88037498295307,
50
+ "microsecondsPerUnit": 13.725078121448556,
51
+ "runsMs": [
52
+ 49.93099998682737,
53
+ 52.13516647927463,
54
+ 77.99987494945526,
55
+ 80.45195834711194,
56
+ 64.77391673251987,
57
+ 72.40758324041963,
58
+ 59.563791612163186,
59
+ 65.88037498295307,
60
+ 76.05079165659845
61
+ ]
62
+ },
63
+ "solver240kSteps": {
64
+ "maxMs": 2.3802914656698704,
65
+ "medianMs": 1.2395833618938923,
66
+ "microsecondsPerUnit": 0.005164930674557884,
67
+ "runsMs": [
68
+ 2.3802914656698704,
69
+ 1.2395833618938923,
70
+ 1.20449997484684,
71
+ 1.2065833434462547,
72
+ 1.2095833662897348,
73
+ 2.030583331361413,
74
+ 1.192083116620779,
75
+ 1.4146252069622278,
76
+ 1.803916646167636
77
+ ]
78
+ }
79
+ },
80
+ "nativeReplay": {
81
+ "clock": "display-link",
82
+ "compositorSamples": 90,
83
+ "frames": 76,
84
+ "intervalMaxMs": 26.089833350852132,
85
+ "intervalP50Ms": 13.34179169498384,
86
+ "intervalP95Ms": 15.199625166133046,
87
+ "intervalsMs": [
88
+ 20.58045845478773,
89
+ 9.317791555076838,
90
+ 13.358333380892873,
91
+ 13.348333304747939,
92
+ 13.654000125825405,
93
+ 13.040874851867557,
94
+ 13.589750044047832,
95
+ 15.892291674390435,
96
+ 10.717083467170596,
97
+ 14.603916555643082,
98
+ 11.840416584163904,
99
+ 15.199625166133046,
100
+ 11.535499943420291,
101
+ 13.385791564360261,
102
+ 13.360166689381003,
103
+ 26.089833350852132,
104
+ 1.2948750518262386,
105
+ 12.498041614890099,
106
+ 13.353041606023908,
107
+ 13.327916851267219,
108
+ 13.33999983035028,
109
+ 14.737500110641122,
110
+ 11.987083358690143,
111
+ 13.34179169498384,
112
+ 13.307541608810425,
113
+ 13.350041583180428,
114
+ 13.351583387702703,
115
+ 13.379791751503944,
116
+ 13.309541624039412,
117
+ 13.326166663318872,
118
+ 13.45525006763637,
119
+ 13.27608316205442,
120
+ 13.275583507493138,
121
+ 13.330291491001844,
122
+ 13.370166765525937,
123
+ 13.277583289891481,
124
+ 13.500958448275924,
125
+ 13.263833243399858,
126
+ 13.282000087201595,
127
+ 13.480541529133916,
128
+ 13.167666736990213,
129
+ 13.46524991095066,
130
+ 13.261291664093733,
131
+ 13.365000020712614,
132
+ 13.319833436980844,
133
+ 13.313999865204096,
134
+ 13.34200007840991,
135
+ 13.35799996741116,
136
+ 13.588541653007269,
137
+ 13.070625020191073,
138
+ 13.489958364516497,
139
+ 13.344750041142106,
140
+ 13.187541626393795,
141
+ 13.33558326587081,
142
+ 13.347458327189088,
143
+ 13.276083394885063,
144
+ 13.375833397731185,
145
+ 13.53804161772132,
146
+ 13.250000076368451,
147
+ 15.753999818116426,
148
+ 10.768333449959755,
149
+ 13.537791557610035,
150
+ 13.177833519876003,
151
+ 13.306666631251574,
152
+ 13.357624877244234,
153
+ 13.317208271473646,
154
+ 13.391666812822223,
155
+ 13.342583319172263,
156
+ 13.294041622430086,
157
+ 13.331791618838906,
158
+ 13.356458395719528,
159
+ 13.349333312362432,
160
+ 13.332375092431903,
161
+ 13.332499889656901,
162
+ 13.38308327831328,
163
+ 13.273750199005008
164
+ ],
165
+ "intervalsOver20Ms": 2,
166
+ "maskAllocations": 0,
167
+ "renderCostsMs": [
168
+ 3.3332083839923143,
169
+ 10.561124887317419
170
+ ],
171
+ "renderMaxMs": 10.561124887317419,
172
+ "renderP95Ms": 3.3332083839923143,
173
+ "renderUpdates": 2,
174
+ "windowResizes": 1
175
+ },
176
+ "limits": [
177
+ "CPU benchmark ran while native test and preview builds were active; do not treat it as a controlled before/after comparison.",
178
+ "Callback timing and CPU costs do not prove displayed frame rate.",
179
+ "This records agent checks; user acceptance of the new shape is pending."
180
+ ]
181
+ }
package/dshx.yml CHANGED
@@ -12,3 +12,5 @@ hotReload:
12
12
  - src/session-state.ts
13
13
  - src/types.ts
14
14
  - src/browse-sync.ts
15
+ - desktop/notch-lifecycle.mjs
16
+ - lib/index.mjs
package/lib/client.js ADDED
@@ -0,0 +1,112 @@
1
+ window.__ModuleLoader__.load({
2
+ id: "dsh-notch",
3
+ factory: (require) => {
4
+ var module = { exports: {} };
5
+ var exports = module.exports;
6
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ //#region src/client/index.ts
8
+ const name = "dsh-notch-client";
9
+ const inject = [
10
+ "sessions",
11
+ "uiWorkspace",
12
+ "uiSession"
13
+ ];
14
+ const POLL_MS = 400;
15
+ function apply(ctx) {
16
+ const sessions = ctx.get("sessions");
17
+ const clientId = crypto.randomUUID();
18
+ let lastAt = 0;
19
+ let armed = false;
20
+ let stopped = false;
21
+ const controller = new AbortController();
22
+ const open = async (sessionId) => {
23
+ try {
24
+ ctx.uiWorkspace.openSession(sessionId);
25
+ return;
26
+ } catch {}
27
+ try {
28
+ await sessions.refresh();
29
+ if (stopped) return;
30
+ ctx.uiWorkspace.openSession(sessionId);
31
+ } catch {}
32
+ };
33
+ const poll = async () => {
34
+ try {
35
+ const snapshot = sessions.list.getSnapshot();
36
+ if (snapshot.phase === "ready") {
37
+ const rows = snapshot.ids.map((id) => snapshot.byId[id]).filter((row) => row && row.origin !== "subagent").map((row) => ({
38
+ id: row.id,
39
+ title: row.displayTitle,
40
+ completed: ctx.uiSession.sessionStatus.getSnapshot().get(row.id)?.completionUnread === true,
41
+ running: row.running,
42
+ updatedAt: row.updatedAt
43
+ }));
44
+ const focused = document.hasFocus();
45
+ const current = rows.find((row) => row.id === Object.values(snapshot.byId).find((item) => (item.retainedBy?.mainView ?? 0) > 0)?.id);
46
+ const viewed = focused && current && !current.running ? {
47
+ id: current.id,
48
+ at: Date.now()
49
+ } : void 0;
50
+ await fetch("/dsh-notch/sidebar", {
51
+ signal: controller.signal,
52
+ method: "POST",
53
+ headers: {
54
+ "content-type": "application/json",
55
+ "x-dsh-notch-client": "1"
56
+ },
57
+ body: JSON.stringify({
58
+ clientId,
59
+ projectionVersion: 3,
60
+ focused,
61
+ viewed,
62
+ rows
63
+ })
64
+ });
65
+ }
66
+ if (stopped) return;
67
+ const response = await fetch("/dsh-notch/pending-focus", {
68
+ cache: "no-store",
69
+ signal: controller.signal
70
+ });
71
+ if (!response.ok) return;
72
+ const data = await response.json();
73
+ if (stopped) return;
74
+ const focus = data.focus;
75
+ if (!armed) {
76
+ armed = true;
77
+ if (focus && typeof focus.at === "number") lastAt = focus.at;
78
+ return;
79
+ }
80
+ if (!focus || typeof focus.at !== "number" || focus.at <= lastAt) return;
81
+ if (typeof focus.sessionId !== "string" || focus.sessionId === "") return;
82
+ lastAt = focus.at;
83
+ await open(focus.sessionId);
84
+ try {
85
+ if (stopped) return;
86
+ window.focus();
87
+ } catch {}
88
+ } catch {}
89
+ };
90
+ const tick = () => {
91
+ if (stopped) return;
92
+ poll().finally(() => {
93
+ if (!stopped) timer = window.setTimeout(tick, POLL_MS);
94
+ });
95
+ };
96
+ let timer;
97
+ tick();
98
+ ctx.effect(() => () => {
99
+ stopped = true;
100
+ if (timer !== void 0) window.clearTimeout(timer);
101
+ controller.abort();
102
+ }, "dsh-notch: client sync");
103
+ }
104
+ //#endregion
105
+ exports.apply = apply;
106
+ exports.inject = inject;
107
+ exports.name = name;
108
+ return module.exports;
109
+ }
110
+ });
111
+
112
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","names":[],"sources":["../src/client/index.ts"],"sourcesContent":["import type { ISessions } from '@deepseek-ai/dsh-api-session-controller/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-session/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-workspace/client'\nimport type { SessionId } from '@deepseek-ai/dsh-session/types'\n/**\n * Headless follower: polls the Host for notch focus wishes and selects the\n * session in every open DSH page (app webview or browser tab).\n *\n * First poll only arms (ignores a wish already sitting there) so a reload\n * does not yank the current session. A later click bumps `at` and opens.\n */\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\n\nexport const name = 'dsh-notch-client'\nexport const inject = ['sessions', 'uiWorkspace', 'uiSession']\n\ninterface PendingFocusWire {\n ok?: boolean\n focus?: { sessionId?: string; at?: number } | null\n}\n\nconst POLL_MS = 400\n\nexport function apply(ctx: ClientContext): void {\n const sessions = ctx.get('sessions') as unknown as ISessions\n const clientId = crypto.randomUUID()\n let lastAt = 0\n let armed = false\n let stopped = false\n const controller = new AbortController()\n\n const open = async (sessionId: string): Promise<void> => {\n try {\n ctx.uiWorkspace.openSession(sessionId as SessionId)\n return\n } catch {\n /* list may be stale; refresh once and retry */\n }\n try {\n await sessions.refresh()\n if (stopped) return\n ctx.uiWorkspace.openSession(sessionId as SessionId)\n } catch {\n /* session not in this page's list */\n }\n }\n\n const poll = async (): Promise<void> => {\n try {\n const snapshot = sessions.list.getSnapshot()\n if (snapshot.phase === 'ready') {\n // parentId also records independent user forks; only origin classifies\n // a delegated child, matching the official workspace sidebar.\n const rows = snapshot.ids.map(id => snapshot.byId[id]).filter(row => row && row.origin !== 'subagent').map(row => ({ id: row.id, title: row.displayTitle, completed: ctx.uiSession.sessionStatus.getSnapshot().get(row.id)?.completionUnread === true, running: row.running, updatedAt: row.updatedAt }))\n const focused = document.hasFocus()\n const current = rows.find(row => row.id === Object.values(snapshot.byId).find(item => (item.retainedBy?.mainView ?? 0) > 0)?.id)\n // updatedAt is the user's prompt timestamp, not the completion time.\n // Capture this observation before sending it, so a delayed request\n // cannot acknowledge a turn that finishes after the user looked.\n const viewed = focused && current && !current.running\n ? { id: current.id, at: Date.now() } : undefined\n await fetch('/dsh-notch/sidebar', { signal: controller.signal, method: 'POST', headers: { 'content-type': 'application/json', 'x-dsh-notch-client': '1' }, body: JSON.stringify({ clientId, projectionVersion: 3, focused, viewed, rows }) })\n }\n if (stopped) return\n const response = await fetch('/dsh-notch/pending-focus', { cache: 'no-store', signal: controller.signal })\n if (!response.ok) return\n const data = (await response.json()) as PendingFocusWire\n if (stopped) return\n const focus = data.focus\n if (!armed) {\n armed = true\n if (focus && typeof focus.at === 'number') lastAt = focus.at\n return\n }\n if (!focus || typeof focus.at !== 'number' || focus.at <= lastAt) return\n if (typeof focus.sessionId !== 'string' || focus.sessionId === '') return\n lastAt = focus.at\n await open(focus.sessionId)\n try {\n if (stopped) return\n window.focus()\n } catch {\n /* native helper already fronts DSH.app */\n }\n } catch {\n /* Host unreachable mid-poll; the next tick retries. */\n }\n }\n\n const tick = (): void => {\n if (stopped) return\n void poll().finally(() => {\n if (!stopped) timer = window.setTimeout(tick, POLL_MS)\n })\n }\n let timer: ReturnType<typeof window.setTimeout> | undefined\n tick()\n\n ctx.effect(() => () => {\n stopped = true\n if (timer !== undefined) window.clearTimeout(timer)\n controller.abort()\n }, 'dsh-notch: client sync')\n}\n"],"mappings":";;;;;;;EAaA,MAAa,OAAO;EACpB,MAAa,SAAS;GAAC;GAAY;GAAe;EAAW;EAO7D,MAAM,UAAU;EAEhB,SAAgB,MAAM,KAA0B;GAC9C,MAAM,WAAW,IAAI,IAAI,UAAU;GACnC,MAAM,WAAW,OAAO,WAAW;GACnC,IAAI,SAAS;GACb,IAAI,QAAQ;GACZ,IAAI,UAAU;GACd,MAAM,aAAa,IAAI,gBAAgB;GAEvC,MAAM,OAAO,OAAO,cAAqC;IACvD,IAAI;KACF,IAAI,YAAY,YAAY,SAAsB;KAClD;IACF,QAAQ,CAER;IACA,IAAI;KACF,MAAM,SAAS,QAAQ;KACvB,IAAI,SAAS;KACb,IAAI,YAAY,YAAY,SAAsB;IACpD,QAAQ,CAER;GACF;GAEA,MAAM,OAAO,YAA2B;IACtC,IAAI;KACF,MAAM,WAAW,SAAS,KAAK,YAAY;KAC3C,IAAI,SAAS,UAAU,SAAS;MAG9B,MAAM,OAAO,SAAS,IAAI,KAAI,OAAM,SAAS,KAAK,GAAG,CAAC,CAAC,QAAO,QAAO,OAAO,IAAI,WAAW,UAAU,CAAC,CAAC,KAAI,SAAQ;OAAE,IAAI,IAAI;OAAI,OAAO,IAAI;OAAc,WAAW,IAAI,UAAU,cAAc,YAAY,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,qBAAqB;OAAM,SAAS,IAAI;OAAS,WAAW,IAAI;MAAU,EAAE;MACxS,MAAM,UAAU,SAAS,SAAS;MAClC,MAAM,UAAU,KAAK,MAAK,QAAO,IAAI,OAAO,OAAO,OAAO,SAAS,IAAI,CAAC,CAAC,MAAK,UAAS,KAAK,YAAY,YAAY,KAAK,CAAC,CAAC,EAAE,EAAE;MAI/H,MAAM,SAAS,WAAW,WAAW,CAAC,QAAQ,UAC1C;OAAE,IAAI,QAAQ;OAAI,IAAI,KAAK,IAAI;MAAE,IAAI,KAAA;MACzC,MAAM,MAAM,sBAAsB;OAAE,QAAQ,WAAW;OAAQ,QAAQ;OAAQ,SAAS;QAAE,gBAAgB;QAAoB,sBAAsB;OAAI;OAAG,MAAM,KAAK,UAAU;QAAE;QAAU,mBAAmB;QAAG;QAAS;QAAQ;OAAK,CAAC;MAAE,CAAC;KAC9O;KACA,IAAI,SAAS;KACb,MAAM,WAAW,MAAM,MAAM,4BAA4B;MAAE,OAAO;MAAY,QAAQ,WAAW;KAAO,CAAC;KACzG,IAAI,CAAC,SAAS,IAAI;KAClB,MAAM,OAAQ,MAAM,SAAS,KAAK;KAClC,IAAI,SAAS;KACb,MAAM,QAAQ,KAAK;KACnB,IAAI,CAAC,OAAO;MACV,QAAQ;MACR,IAAI,SAAS,OAAO,MAAM,OAAO,UAAU,SAAS,MAAM;MAC1D;KACF;KACA,IAAI,CAAC,SAAS,OAAO,MAAM,OAAO,YAAY,MAAM,MAAM,QAAQ;KAClE,IAAI,OAAO,MAAM,cAAc,YAAY,MAAM,cAAc,IAAI;KACnE,SAAS,MAAM;KACf,MAAM,KAAK,MAAM,SAAS;KAC1B,IAAI;MACF,IAAI,SAAS;MACb,OAAO,MAAM;KACf,QAAQ,CAER;IACF,QAAQ,CAER;GACF;GAEA,MAAM,aAAmB;IACvB,IAAI,SAAS;IACb,KAAU,CAAC,CAAC,cAAc;KACxB,IAAI,CAAC,SAAS,QAAQ,OAAO,WAAW,MAAM,OAAO;IACvD,CAAC;GACH;GACA,IAAI;GACJ,KAAK;GAEL,IAAI,mBAAmB;IACrB,UAAU;IACV,IAAI,UAAU,KAAA,GAAW,OAAO,aAAa,KAAK;IAClD,WAAW,MAAM;GACnB,GAAG,wBAAwB;EAC7B"}