@openchambery/web 1.18.2-beta.12 → 1.18.2-beta.13

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 (50) hide show
  1. package/dist/assets/{AssistantView-De54yQXX.js → AssistantView-Bbqfj9CK.js} +1 -1
  2. package/dist/assets/{ChatContainer-9cw5pRwD.js → ChatContainer-hDTv6UXl.js} +4 -4
  3. package/dist/assets/{DiagramView-DmZ4jKmn.js → DiagramView-1hFDtyEy.js} +1 -1
  4. package/dist/assets/{MarkdownRendererImpl-B6zceXlX.js → MarkdownRendererImpl-5BLw0qYH.js} +1 -1
  5. package/dist/assets/{MobileDetailNavigation-fdO6J2xj.js → MobileDetailNavigation-DIyVGM50.js} +1 -1
  6. package/dist/assets/{MobileShareBridge-Czlandhf.js → MobileShareBridge-BQM-WOll.js} +1 -1
  7. package/dist/assets/{MobileSurface-DppgVqKs.js → MobileSurface-KZ-kuSM-.js} +1 -1
  8. package/dist/assets/{MultiRunWindow-CvMgGQLj.js → MultiRunWindow-DPOSSmY_.js} +1 -1
  9. package/dist/assets/{OverlayScrollbar-DwdKeYSb.js → OverlayScrollbar-C2pMNVMM.js} +1 -1
  10. package/dist/assets/{SettingsView-cfFQW5LJ.js → SettingsView-DxL07Iba.js} +1 -1
  11. package/dist/assets/{SettingsWindow-DebnkbG9.js → SettingsWindow-DJ2o4zvh.js} +1 -1
  12. package/dist/assets/{TerminalView-CWBmPQJ_.js → TerminalView-BB3tvloy.js} +1 -1
  13. package/dist/assets/{ToolOutputDialog-CyKqI69B.js → ToolOutputDialog-D7DqChuM.js} +1 -1
  14. package/dist/assets/{appThemeRegistry-CmZlBPov.js → appThemeRegistry-DhaoeTus.js} +2 -2
  15. package/dist/assets/{context-menu-Bbd153RL.js → context-menu-D88vCGyB.js} +1 -1
  16. package/dist/assets/{gitApi-BlInY34O.js → gitApi-DVNC4iYD.js} +1 -1
  17. package/dist/assets/{insertionBoundaries-CiTMpUdk.js → insertionBoundaries-hcIB6RSd.js} +1 -1
  18. package/dist/assets/{main-CUN5Brht.js → main-CQrMAdMF.js} +4 -4
  19. package/dist/assets/{main-DQxV4rh8.js → main-D4aa2ZJz.js} +2 -2
  20. package/dist/assets/{miniChat-Bx2cMtJS.js → miniChat-4N2-z2vf.js} +2 -2
  21. package/dist/assets/{mobile-BvWi_rq9.js → mobile-C-RRGcDW.js} +2 -2
  22. package/dist/assets/{multirun-DaUWpTWM.js → multirun-Co8LbTjb.js} +1 -1
  23. package/dist/assets/{projectMeta-DtoKE1uJ.js → projectMeta-D-ncdr5Z.js} +1 -1
  24. package/dist/assets/{radio-BiawVf-W.js → radio-CD4P-ogh.js} +1 -1
  25. package/dist/assets/{renderElectronMiniChatApp-BPvk5Kd6.js → renderElectronMiniChatApp-D5QcQTL0.js} +2 -2
  26. package/dist/assets/{renderMobileApp-D7V_905J.js → renderMobileApp-CnZZVbHU.js} +4 -4
  27. package/dist/assets/{runtimeEndpointReset-DpaiHzaP.js → runtimeEndpointReset-BQ5F5VZS.js} +2 -2
  28. package/dist/assets/{sortable-tabs-strip-BEalEtjO.js → sortable-tabs-strip-DQsv96ke.js} +1 -1
  29. package/dist/assets/{useAppFontEffects-DOb592S6.js → useAppFontEffects-DygV6JSW.js} +2 -2
  30. package/dist/assets/{useDesktopWindowControlsLayout-COCcsUGy.js → useDesktopWindowControlsLayout-Cj63sNDg.js} +1 -1
  31. package/dist/assets/{useEffectiveDirectory-DXGFGuv0.js → useEffectiveDirectory-Dc904Fjg.js} +1 -1
  32. package/dist/assets/{useMobileNavigationStore-D5XHlGZB.js → useMobileNavigationStore-DNoNQA4y.js} +2 -2
  33. package/dist/assets/{useSessionAutoCleanup-DvK0S9G6.js → useSessionAutoCleanup-bBkcz_hu.js} +1 -1
  34. package/dist/assets/{useWorkerHighlightedLines-BTFe-rdw.js → useWorkerHighlightedLines-mhBD0Do9.js} +1 -1
  35. package/dist/index.html +1 -1
  36. package/dist/mini-chat.html +1 -1
  37. package/dist/mobile.html +1 -1
  38. package/package.json +1 -1
  39. package/server/lib/event-stream/DOCUMENTATION.md +2 -2
  40. package/server/lib/event-stream/diff-summary.js +28 -19
  41. package/server/lib/event-stream/diff-summary.test.js +37 -10
  42. package/server/lib/event-stream/protocol.test.js +66 -3
  43. package/server/lib/opencode/DOCUMENTATION.md +1 -1
  44. package/server/lib/session-turn-pages/DOCUMENTATION.md +3 -3
  45. package/server/lib/session-turn-pages/reconcile.routes.test.js +6 -2
  46. package/server/lib/session-turn-pages/reconcile.service.test.js +6 -2
  47. package/server/lib/session-turn-pages/routes.js +3 -3
  48. package/server/lib/session-turn-pages/routes.test.js +41 -13
  49. package/server/lib/session-turn-pages/service.js +4 -2
  50. package/server/lib/session-turn-pages/service.test.js +13 -3
@@ -244,17 +244,21 @@ describe('registerSessionTurnPageRoutes — reconcile', () => {
244
244
 
245
245
  expect(res.statusCode).toBe(200);
246
246
  expect(res.body.records[0].info.summary).toEqual({
247
+ diffs: [{
248
+ file: 'src/large.ts',
249
+ status: 'modified',
250
+ additions: 5,
251
+ deletions: 1,
252
+ }],
247
253
  diffCount: 1,
248
254
  hasDiffs: true,
249
255
  });
250
- expect(res.body.records[0].info.summary.diffs).toBeUndefined();
251
256
  expect(res.body.records[0].parts[0]).toEqual({
252
257
  id: 'prt_1',
253
258
  type: 'text',
254
259
  text: 'full recovery text',
255
260
  });
256
261
  expect(JSON.stringify(res.body)).not.toContain(patch);
257
- expect(JSON.stringify(res.body)).not.toContain('src/large.ts');
258
262
  });
259
263
 
260
264
  it('returns HTTP 200 for resetRequired (anchor lost / budget rebuild)', async () => {
@@ -512,13 +512,17 @@ describe('createSessionReconcileService', () => {
512
512
 
513
513
  expect(result.ok).toBe(true);
514
514
  expect(result.records[0].info.summary).toEqual({
515
+ diffs: [{
516
+ file: 'src/large.ts',
517
+ status: 'modified',
518
+ additions: 7,
519
+ deletions: 2,
520
+ }],
515
521
  diffCount: 1,
516
522
  hasDiffs: true,
517
523
  });
518
- expect(result.records[0].info.summary.diffs).toBeUndefined();
519
524
  expect(result.responseBytes).toBeLessThanOrEqual(1024);
520
525
  expect(JSON.stringify(result.records)).not.toContain(patch);
521
- expect(JSON.stringify(result.records)).not.toContain('src/large.ts');
522
526
  });
523
527
 
524
528
  it('rejects continuation that does not bind runtime/directory/session/anchor/head', async () => {
@@ -307,7 +307,7 @@ const createSdkFetchDiff = ({ buildOpenCodeUrl, getOpenCodeAuthHeaders, logger }
307
307
 
308
308
  /**
309
309
  * Project exact message GET payload: keep original `{ info, parts }` shape,
310
- * only L1-project `info.summary.diffs` → diffCount/hasDiffs.
310
+ * only L1-project `info.summary.diffs` → slim file list + diffCount/hasDiffs.
311
311
  */
312
312
  export const projectExactMessagePayload = (payload) => {
313
313
  if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
@@ -625,8 +625,8 @@ export const registerSessionTurnPageRoutes = (app, dependencies = {}) => {
625
625
 
626
626
  /**
627
627
  * Exact message GET — registered before generic `/api` proxy so materialize /
628
- * recovery never relay a raw 14MB `summary.diffs` array. Returns the official
629
- * `{ info, parts }` shape with L1 summary projection only.
628
+ * recovery never relay raw multi-megabyte patch bodies in `summary.diffs`.
629
+ * Returns the official `{ info, parts }` shape with L1 slim-list projection.
630
630
  */
631
631
  app.get('/api/session/:sessionID/message/:messageID', async (req, res) => {
632
632
  const sessionID = req.params?.sessionID;
@@ -320,7 +320,7 @@ describe('registerSessionTurnPageRoutes', () => {
320
320
  expect(part.state.output).toBeUndefined();
321
321
  });
322
322
 
323
- it('projects message summary.diffs to L1 count/marker before serializing a turn-page response', async () => {
323
+ it('projects message summary.diffs to L1 slim list + markers before serializing a turn-page response', async () => {
324
324
  const patch = 'diff-body-'.repeat(20_000);
325
325
  const loadPage = vi.fn(async () => ({
326
326
  ok: true,
@@ -335,6 +335,8 @@ describe('registerSessionTurnPageRoutes', () => {
335
335
  additions: 9,
336
336
  deletions: 3,
337
337
  patch,
338
+ before: 'old',
339
+ after: 'new',
338
340
  }],
339
341
  },
340
342
  },
@@ -356,15 +358,21 @@ describe('registerSessionTurnPageRoutes', () => {
356
358
 
357
359
  expect(res.statusCode).toBe(200);
358
360
  expect(res.body.records[0].info.summary).toEqual({
361
+ diffs: [{
362
+ file: 'src/large.ts',
363
+ status: 'modified',
364
+ additions: 9,
365
+ deletions: 3,
366
+ }],
359
367
  diffCount: 1,
360
368
  hasDiffs: true,
361
369
  });
362
- expect(res.body.records[0].info.summary.diffs).toBeUndefined();
363
370
  expect(JSON.stringify(res.body)).not.toContain(patch);
364
- expect(JSON.stringify(res.body)).not.toContain('src/large.ts');
371
+ expect(JSON.stringify(res.body)).not.toContain('"before"');
372
+ expect(JSON.stringify(res.body)).not.toContain('"after"');
365
373
  });
366
374
 
367
- it('keeps L1 turn-page serialization under 64KiB for a 463-file / ~14MB patch summary', async () => {
375
+ it('keeps L1 turn-page serialization under 256KiB for a 463-file / ~14MB patch summary', async () => {
368
376
  const patchBody = 'P'.repeat(Math.floor((14 * 1024 * 1024) / 463));
369
377
  const diffs = Array.from({ length: 463 }, (_, i) => ({
370
378
  file: `src/generated/file-${i}.ts`,
@@ -374,6 +382,8 @@ describe('registerSessionTurnPageRoutes', () => {
374
382
  patch: `${patchBody}-${i}`,
375
383
  before: `before-${i}`,
376
384
  after: `after-${i}`,
385
+ from: `from-${i}`,
386
+ to: `to-${i}`,
377
387
  }));
378
388
  const loadPage = vi.fn(async () => ({
379
389
  ok: true,
@@ -401,16 +411,29 @@ describe('registerSessionTurnPageRoutes', () => {
401
411
 
402
412
  expect(res.statusCode).toBe(200);
403
413
  const serialized = JSON.stringify(res.body);
404
- expect(res.body.records[0].info.summary).toEqual({
405
- title: 'huge',
406
- diffCount: 463,
407
- hasDiffs: true,
414
+ const summary = res.body.records[0].info.summary;
415
+ expect(summary.diffCount).toBe(463);
416
+ expect(summary.hasDiffs).toBe(true);
417
+ expect(summary.diffs).toHaveLength(463);
418
+ expect(summary.diffs[0]).toEqual({
419
+ file: 'src/generated/file-0.ts',
420
+ status: 'modified',
421
+ additions: 0,
422
+ deletions: 0,
423
+ });
424
+ expect(summary.diffs[462]).toEqual({
425
+ file: 'src/generated/file-462.ts',
426
+ status: 'modified',
427
+ additions: 462 % 7,
428
+ deletions: 462 % 3,
408
429
  });
409
- expect(res.body.records[0].info.summary.diffs).toBeUndefined();
410
- expect(serialized).not.toContain('"diffs"');
411
430
  expect(serialized).not.toContain(patchBody.slice(0, 64));
412
- expect(serialized).not.toContain('src/generated/file-0.ts');
413
- expect(Buffer.byteLength(serialized, 'utf8')).toBeLessThan(64 * 1024);
431
+ expect(serialized).not.toContain('"patch"');
432
+ expect(serialized).not.toContain('"before"');
433
+ expect(serialized).not.toContain('"after"');
434
+ expect(serialized).not.toContain('"from"');
435
+ expect(serialized).not.toContain('"to"');
436
+ expect(Buffer.byteLength(serialized, 'utf8')).toBeLessThan(256 * 1024);
414
437
  });
415
438
 
416
439
  it('projects file parts on first packet and prepend the same way', async () => {
@@ -630,6 +653,12 @@ describe('registerSessionTurnPageRoutes — exact message GET', () => {
630
653
  role: 'user',
631
654
  summary: {
632
655
  title: 'turn',
656
+ diffs: [{
657
+ file: 'a.ts',
658
+ status: 'modified',
659
+ additions: 2,
660
+ deletions: 1,
661
+ }],
633
662
  diffCount: 1,
634
663
  hasDiffs: true,
635
664
  },
@@ -637,7 +666,6 @@ describe('registerSessionTurnPageRoutes — exact message GET', () => {
637
666
  parts: [{ id: 'prt_1', type: 'text', text: 'hello' }],
638
667
  });
639
668
  expect(JSON.stringify(res.body)).not.toContain(patch);
640
- expect(JSON.stringify(res.body)).not.toContain('a.ts');
641
669
  });
642
670
 
643
671
  it('rejects oversize messageID / sessionID with 400', async () => {
@@ -459,8 +459,10 @@ const isUserRecord = (record) => {
459
459
  };
460
460
 
461
461
  /**
462
- * L1: project message `summary.diffs` arrays to `{ diffCount, hasDiffs }` and
463
- * remove the file array. Preserves every other message / summary field.
462
+ * L1: project message `summary.diffs` to a slim file list
463
+ * `{ file, status?, additions, deletions }` plus additive `diffCount` /
464
+ * `hasDiffs`. Never retains patch/before/after/from/to. Preserves every other
465
+ * message / summary field.
464
466
  */
465
467
  export const projectMessageDiffSummaries = (records) => {
466
468
  if (!Array.isArray(records) || records.length === 0) return records;
@@ -172,7 +172,7 @@ describe('projectSlimParts', () => {
172
172
  },
173
173
  });
174
174
 
175
- it('projects message summary.diffs to L1 count/marker even when parts are empty', () => {
175
+ it('projects message summary.diffs to L1 slim list + markers even when parts are empty', () => {
176
176
  const patch = 'diff-body-'.repeat(20_000);
177
177
  const [projected] = projectSlimParts([{
178
178
  info: {
@@ -186,6 +186,10 @@ describe('projectSlimParts', () => {
186
186
  additions: 12,
187
187
  deletions: 4,
188
188
  patch,
189
+ before: 'old-body',
190
+ after: 'new-body',
191
+ from: 'from-blob',
192
+ to: 'to-blob',
189
193
  }],
190
194
  },
191
195
  },
@@ -194,12 +198,18 @@ describe('projectSlimParts', () => {
194
198
 
195
199
  expect(projected.info.summary).toEqual({
196
200
  title: 'kept',
201
+ diffs: [{
202
+ file: 'src/large.ts',
203
+ status: 'modified',
204
+ additions: 12,
205
+ deletions: 4,
206
+ }],
197
207
  diffCount: 1,
198
208
  hasDiffs: true,
199
209
  });
200
- expect(projected.info.summary.diffs).toBeUndefined();
201
210
  expect(JSON.stringify(projected)).not.toContain(patch);
202
- expect(JSON.stringify(projected)).not.toContain('src/large.ts');
211
+ expect(JSON.stringify(projected)).not.toContain('old-body');
212
+ expect(JSON.stringify(projected)).not.toContain('from-blob');
203
213
  });
204
214
 
205
215
  it('drops tool output and metadata but keeps identity and status', () => {