@jpkme/diff-review 0.1.13 → 0.1.15

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 (103) hide show
  1. package/bin/diff-review.mjs +183 -100
  2. package/lib/acp-shell.mjs +23 -1
  3. package/lib/acp-shell.test.mjs +7 -0
  4. package/lib/prompt.mjs +8 -6
  5. package/package.json +1 -1
  6. package/web/build/client/_app/immutable/assets/2.C4whE4xz.css +1 -0
  7. package/web/build/client/_app/immutable/assets/2.C4whE4xz.css.br +0 -0
  8. package/web/build/client/_app/immutable/assets/2.C4whE4xz.css.gz +0 -0
  9. package/web/build/client/_app/immutable/assets/3.Cw1J6YTM.css +1 -0
  10. package/web/build/client/_app/immutable/assets/3.Cw1J6YTM.css.br +0 -0
  11. package/web/build/client/_app/immutable/assets/3.Cw1J6YTM.css.gz +0 -0
  12. package/web/build/client/_app/immutable/assets/storage.TlsiS-AP.css +1 -0
  13. package/web/build/client/_app/immutable/assets/storage.TlsiS-AP.css.br +0 -0
  14. package/web/build/client/_app/immutable/assets/storage.TlsiS-AP.css.gz +0 -0
  15. package/web/build/client/_app/immutable/chunks/{Bu1mm6Oz.js → BpVtXA-T.js} +1 -1
  16. package/web/build/client/_app/immutable/chunks/BpVtXA-T.js.br +2 -0
  17. package/web/build/client/_app/immutable/chunks/BpVtXA-T.js.gz +0 -0
  18. package/web/build/client/_app/immutable/chunks/{BXUWMim4.js → CUhrLa7d.js} +12 -15
  19. package/web/build/client/_app/immutable/chunks/CUhrLa7d.js.br +0 -0
  20. package/web/build/client/_app/immutable/chunks/CUhrLa7d.js.gz +0 -0
  21. package/web/build/client/_app/immutable/chunks/{DPfXzQnm.js → QvO6K-HK.js} +2 -2
  22. package/web/build/client/_app/immutable/chunks/QvO6K-HK.js.br +0 -0
  23. package/web/build/client/_app/immutable/chunks/QvO6K-HK.js.gz +0 -0
  24. package/web/build/client/_app/immutable/entry/{app.CTgiuiU1.js → app.BjJsHui4.js} +2 -2
  25. package/web/build/client/_app/immutable/entry/app.BjJsHui4.js.br +0 -0
  26. package/web/build/client/_app/immutable/entry/app.BjJsHui4.js.gz +0 -0
  27. package/web/build/client/_app/immutable/entry/start.D4unRHC4.js +1 -0
  28. package/web/build/client/_app/immutable/entry/start.D4unRHC4.js.br +0 -0
  29. package/web/build/client/_app/immutable/entry/start.D4unRHC4.js.gz +0 -0
  30. package/web/build/client/_app/immutable/nodes/{1.0PQZpSbJ.js → 1.C8JJYlWG.js} +1 -1
  31. package/web/build/client/_app/immutable/nodes/1.C8JJYlWG.js.br +1 -0
  32. package/web/build/client/_app/immutable/nodes/1.C8JJYlWG.js.gz +0 -0
  33. package/web/build/client/_app/immutable/nodes/2.CDI0Ipi4.js +10 -0
  34. package/web/build/client/_app/immutable/nodes/2.CDI0Ipi4.js.br +0 -0
  35. package/web/build/client/_app/immutable/nodes/2.CDI0Ipi4.js.gz +0 -0
  36. package/web/build/client/_app/immutable/nodes/3.DVC22CDg.js +171 -0
  37. package/web/build/client/_app/immutable/nodes/3.DVC22CDg.js.br +0 -0
  38. package/web/build/client/_app/immutable/nodes/3.DVC22CDg.js.gz +0 -0
  39. package/web/build/client/_app/version.json +1 -1
  40. package/web/build/client/_app/version.json.br +0 -0
  41. package/web/build/client/_app/version.json.gz +0 -0
  42. package/web/build/handler.js +3 -3
  43. package/web/build/index.js +3 -3
  44. package/web/build/server/chunks/1-DUj63QTT.js +7 -0
  45. package/web/build/server/chunks/{1-C2qlInYk.js.map → 1-DUj63QTT.js.map} +1 -1
  46. package/web/build/server/chunks/2-B4PSKe5P.js +7 -0
  47. package/web/build/server/chunks/2-B4PSKe5P.js.map +1 -0
  48. package/web/build/server/chunks/3-C7UD6rei.js +7 -0
  49. package/web/build/server/chunks/{3-SO3atuWO.js.map → 3-C7UD6rei.js.map} +1 -1
  50. package/web/build/server/chunks/{_server.ts-CRNhzL2a.js → _server.ts-4RcoUd0l.js} +4 -4
  51. package/web/build/server/chunks/{_server.ts-CRNhzL2a.js.map → _server.ts-4RcoUd0l.js.map} +1 -1
  52. package/web/build/server/chunks/{agent-sessions-kcUaLhK5.js → agent-sessions-C_hlZJKN.js} +77 -16
  53. package/web/build/server/chunks/agent-sessions-C_hlZJKN.js.map +1 -0
  54. package/web/build/server/chunks/{git-review-CXKcjYgZ.js → git-review-Bh1w0gak.js} +7 -7
  55. package/web/build/server/chunks/{git-review-CXKcjYgZ.js.map → git-review-Bh1w0gak.js.map} +1 -1
  56. package/web/build/server/chunks/{handler-_E0NucKN.js → handler-e2lEvjVT.js} +3 -3
  57. package/web/build/server/chunks/{handler-_E0NucKN.js.map → handler-e2lEvjVT.js.map} +1 -1
  58. package/web/build/server/chunks/{hooks.server-D7yPODoc.js → hooks.server-Um1Sknmz.js} +3 -3
  59. package/web/build/server/chunks/{hooks.server-D7yPODoc.js.map → hooks.server-Um1Sknmz.js.map} +1 -1
  60. package/web/build/server/chunks/{index.js-lMtDM8ZQ.js → index.js-C3-YX8SA.js} +876 -879
  61. package/web/build/server/chunks/index.js-C3-YX8SA.js.map +1 -0
  62. package/web/build/server/chunks/{manifest.js-BIm6jot5.js → manifest.js-CmbRPv0j.js} +8 -8
  63. package/web/build/server/chunks/{manifest.js-BIm6jot5.js.map → manifest.js-CmbRPv0j.js.map} +1 -1
  64. package/web/build/server/chunks/{remote-1g4ayag-DmqxwUIz.js → remote-1g4ayag-DMiPy1mT.js} +4 -4
  65. package/web/build/server/chunks/{remote-1g4ayag-DmqxwUIz.js.map → remote-1g4ayag-DMiPy1mT.js.map} +1 -1
  66. package/web/build/server/chunks/{remote-wh6t6j-DZk0W9Pp.js → remote-wh6t6j-RlIVOUe-.js} +5 -5
  67. package/web/build/server/chunks/{remote-wh6t6j-DZk0W9Pp.js.map → remote-wh6t6j-RlIVOUe-.js.map} +1 -1
  68. package/web/build/server/chunks/{validate-BsTKyhsq.js → validate-CAQ31C7k.js} +2 -2
  69. package/web/build/server/chunks/{validate-BsTKyhsq.js.map → validate-CAQ31C7k.js.map} +1 -1
  70. package/web/build/client/_app/immutable/assets/2.tqrMRTM0.css +0 -1
  71. package/web/build/client/_app/immutable/assets/2.tqrMRTM0.css.br +0 -0
  72. package/web/build/client/_app/immutable/assets/2.tqrMRTM0.css.gz +0 -0
  73. package/web/build/client/_app/immutable/assets/3.BT54aVKb.css +0 -1
  74. package/web/build/client/_app/immutable/assets/3.BT54aVKb.css.br +0 -0
  75. package/web/build/client/_app/immutable/assets/3.BT54aVKb.css.gz +0 -0
  76. package/web/build/client/_app/immutable/assets/storage.DqYH0w6R.css +0 -1
  77. package/web/build/client/_app/immutable/assets/storage.DqYH0w6R.css.br +0 -0
  78. package/web/build/client/_app/immutable/assets/storage.DqYH0w6R.css.gz +0 -0
  79. package/web/build/client/_app/immutable/chunks/BXUWMim4.js.br +0 -0
  80. package/web/build/client/_app/immutable/chunks/BXUWMim4.js.gz +0 -0
  81. package/web/build/client/_app/immutable/chunks/Bu1mm6Oz.js.br +0 -0
  82. package/web/build/client/_app/immutable/chunks/Bu1mm6Oz.js.gz +0 -0
  83. package/web/build/client/_app/immutable/chunks/DPfXzQnm.js.br +0 -0
  84. package/web/build/client/_app/immutable/chunks/DPfXzQnm.js.gz +0 -0
  85. package/web/build/client/_app/immutable/entry/app.CTgiuiU1.js.br +0 -0
  86. package/web/build/client/_app/immutable/entry/app.CTgiuiU1.js.gz +0 -0
  87. package/web/build/client/_app/immutable/entry/start.CFSl0kht.js +0 -1
  88. package/web/build/client/_app/immutable/entry/start.CFSl0kht.js.br +0 -0
  89. package/web/build/client/_app/immutable/entry/start.CFSl0kht.js.gz +0 -0
  90. package/web/build/client/_app/immutable/nodes/1.0PQZpSbJ.js.br +0 -2
  91. package/web/build/client/_app/immutable/nodes/1.0PQZpSbJ.js.gz +0 -0
  92. package/web/build/client/_app/immutable/nodes/2.DQaoQoy4.js +0 -10
  93. package/web/build/client/_app/immutable/nodes/2.DQaoQoy4.js.br +0 -0
  94. package/web/build/client/_app/immutable/nodes/2.DQaoQoy4.js.gz +0 -0
  95. package/web/build/client/_app/immutable/nodes/3.AciugOtL.js +0 -171
  96. package/web/build/client/_app/immutable/nodes/3.AciugOtL.js.br +0 -0
  97. package/web/build/client/_app/immutable/nodes/3.AciugOtL.js.gz +0 -0
  98. package/web/build/server/chunks/1-C2qlInYk.js +0 -7
  99. package/web/build/server/chunks/2-DyE177MK.js +0 -7
  100. package/web/build/server/chunks/2-DyE177MK.js.map +0 -1
  101. package/web/build/server/chunks/3-SO3atuWO.js +0 -7
  102. package/web/build/server/chunks/agent-sessions-kcUaLhK5.js.map +0 -1
  103. package/web/build/server/chunks/index.js-lMtDM8ZQ.js.map +0 -1
@@ -201,12 +201,15 @@ function defaultBase(listed, branch) {
201
201
  return listed.branches.find((b) => b !== branch) || preferred || '';
202
202
  }
203
203
 
204
- function branchOptions(listed) {
205
- return listed.branches.map((b) => ({
206
- value: b,
207
- label: b,
208
- hint: b === listed.current ? 'actual' : b === listed.defaultBase ? 'base típica' : undefined
209
- }));
204
+ function branchOptions(listed, exclude = '') {
205
+ const skip = String(exclude || '').trim();
206
+ return listed.branches
207
+ .filter((b) => !skip || b !== skip)
208
+ .map((b) => ({
209
+ value: b,
210
+ label: b,
211
+ hint: b === listed.current ? 'actual' : b === listed.defaultBase ? 'base típica' : undefined
212
+ }));
210
213
  }
211
214
 
212
215
  /** Selects solo con terminal interactiva. (`p.isTTY` de Clack es una función, no un booleano.) */
@@ -230,8 +233,9 @@ function ensureValue(value, label) {
230
233
  * Selects interactivos salvo que --branch y --base vengan juntos.
231
234
  * @param {{ listed: { branches: string[], current: string, defaultBase: string }, repo: string }} launch
232
235
  * @param {{ branch: string, base: string }} opts
236
+ * @param {{ skipIntro?: boolean }} [pickOpts]
233
237
  */
234
- async function resolveBranchBase(launch, opts) {
238
+ async function resolveBranchBase(launch, opts, pickOpts = {}) {
235
239
  const flagBranch = String(opts.branch || '').trim();
236
240
  const flagBase = String(opts.base || '').trim();
237
241
  const bothFlags = Boolean(flagBranch && flagBase);
@@ -252,55 +256,86 @@ async function resolveBranchBase(launch, opts) {
252
256
  }
253
257
 
254
258
  const options = branchOptions(launch.listed);
255
- p.intro('diff-review');
256
- p.log.info(launch.repo);
257
-
258
- let branch = flagBranch;
259
- if (!branch) {
260
- branch = ensureValue(
261
- await autocompleteEs({
262
- message: 'Branch a revisar',
263
- options,
264
- initialValue: defaultBranch(launch.listed) || undefined,
265
- maxItems: 12
266
- }),
267
- 'branch'
268
- );
269
- } else {
270
- p.log.step(`Branch: ${branch}`);
259
+ if (!pickOpts.skipIntro) {
260
+ p.intro('diff-review');
261
+ p.log.info(launch.repo);
271
262
  }
272
263
 
264
+ /** @type {string} */
265
+ let branch = flagBranch;
266
+ /** @type {string} */
273
267
  let base = flagBase;
274
- if (!base) {
275
- base = ensureValue(
276
- await autocompleteEs({
277
- message: 'Base (merge-base)',
278
- options,
279
- initialValue: defaultBase(launch.listed, branch) || undefined,
280
- maxItems: 12
281
- }),
282
- 'base'
283
- );
284
- } else {
285
- p.log.step(`Base: ${base}`);
286
- }
268
+ let first = true;
287
269
 
288
- while (branch === base) {
289
- p.log.warn(`Branch y base son iguales (${branch}): el diff estaría vacío.`);
290
- base = ensureValue(
291
- await autocompleteEs({
292
- message: 'Elegí otra base',
293
- options,
294
- initialValue: defaultBase(launch.listed, branch) || undefined,
295
- maxItems: 12
296
- }),
297
- 'base'
298
- );
270
+ for (;;) {
271
+ if (!first) {
272
+ // Diff vacío / tips iguales: volver a preguntar branch y base (no solo la base).
273
+ branch = '';
274
+ base = '';
275
+ }
276
+ first = false;
277
+
278
+ if (!branch) {
279
+ branch = ensureValue(
280
+ await autocompleteEs({
281
+ message: 'Branch a revisar',
282
+ options,
283
+ initialValue: defaultBranch(launch.listed) || undefined,
284
+ maxItems: 12
285
+ }),
286
+ 'branch'
287
+ );
288
+ } else {
289
+ p.log.step(`Branch: ${branch}`);
290
+ }
291
+
292
+ const baseOptions = branchOptions(launch.listed, branch);
293
+ if (!baseOptions.length) {
294
+ p.cancel(`No hay otra base disponible distinta de \`${branch}\`.`);
295
+ process.exit(1);
296
+ }
297
+
298
+ if (!base) {
299
+ base = ensureValue(
300
+ await autocompleteEs({
301
+ message: 'Base (merge-base)',
302
+ options: baseOptions,
303
+ initialValue: defaultBase(launch.listed, branch) || undefined,
304
+ maxItems: 12
305
+ }),
306
+ 'base'
307
+ );
308
+ } else {
309
+ p.log.step(`Base: ${base}`);
310
+ }
311
+
312
+ if (branch === base || sameCommitTips(launch.repo, branch, base)) {
313
+ p.log.warn(emptyDiffPickMessage(branch, base));
314
+ continue;
315
+ }
316
+ break;
299
317
  }
300
318
 
301
319
  return { branch, base, prompted: true };
302
320
  }
303
321
 
322
+ /** ¿Branch y base resuelven al mismo SHA? (diff committed vacío aunque los nombres difieran). */
323
+ function sameCommitTips(repo, branch, base) {
324
+ try {
325
+ const { branchSha, baseSha } = branchTips(repo, branch, base);
326
+ return Boolean(branchSha && baseSha && branchSha === baseSha);
327
+ } catch {
328
+ return false;
329
+ }
330
+ }
331
+
332
+ function emptyDiffPickMessage(branch, base) {
333
+ if (branch === base) {
334
+ return `Branch y base son iguales (${branch}): no hay diff que revisar.`;
335
+ }
336
+ return `\`${branch}\` y \`${base}\` apuntan al mismo commit: no hay diff que revisar.`;
337
+ }
338
+
304
339
  function buildOutputFilename(repo, branch, base) {
305
340
  try {
306
341
  const tips = branchTips(repo, branch, base);
@@ -317,6 +352,49 @@ function buildOutputFilename(repo, branch, base) {
317
352
  }
318
353
  }
319
354
 
355
+ /**
356
+ * Precomputa el diff en CLI (spinner si hay Clack).
357
+ * @returns {{ empty: true, message: string } | { empty: false, promptOpts: ReturnType<typeof prepareReviewPromptOpts> }}
358
+ */
359
+ function prepareContext(launch, branch, base, outputFilename, { useClack }) {
360
+ const spin = useClack ? p.spinner() : null;
361
+ if (!useClack) console.log('Preparando el contexto…');
362
+ spin?.start('Preparando el contexto…');
363
+
364
+ /** @type {ReturnType<typeof prepareReviewPromptOpts>} */
365
+ let promptOpts = { outputFilename };
366
+ try {
367
+ promptOpts = prepareReviewPromptOpts({
368
+ repo: launch.repo,
369
+ branch,
370
+ base,
371
+ outputFilename
372
+ });
373
+ } catch (err) {
374
+ const msg = err instanceof Error ? err.message : String(err);
375
+ spin?.stop('No pude precomputar el diff');
376
+ if (useClack) p.log.warn(`No pude precomputar el diff: ${msg}`);
377
+ else console.warn('No pude precomputar el diff:', msg);
378
+ ensureReviewDir(launch.repo);
379
+ writeDiffCache(launch.repo, outputFilename, { branch, base });
380
+ return { empty: false, promptOpts };
381
+ }
382
+
383
+ const n = Array.isArray(promptOpts.files) ? promptOpts.files.length : 0;
384
+ if (n === 0) {
385
+ spin?.stop('Diff vacío');
386
+ return {
387
+ empty: true,
388
+ message: `El diff entre \`${branch}\` y \`${base}\` está vacío: no hay nada que revisar.`
389
+ };
390
+ }
391
+
392
+ const done = `Contexto listo · ${n} archivo${n === 1 ? '' : 's'}`;
393
+ spin?.stop(done);
394
+ if (!useClack) console.log(done);
395
+ return { empty: false, promptOpts };
396
+ }
397
+
320
398
  function copyPromptOrWarn(prompt) {
321
399
  if (copyTextToClipboard(prompt)) return true;
322
400
  p.log.warn(
@@ -622,21 +700,14 @@ async function runUiMode(opts, launch, launchCwd) {
622
700
  if (launch) {
623
701
  console.log(`Repo: ${launch.repo}`);
624
702
  console.log(`Branch: ${branch} (base: ${base})`);
625
- let promptOpts = { outputFilename };
626
- try {
627
- promptOpts = prepareReviewPromptOpts({
628
- repo: launch.repo,
629
- branch,
630
- base,
631
- outputFilename
632
- });
633
- } catch (err) {
634
- console.warn(
635
- 'No pude precomputar el diff:',
636
- err instanceof Error ? err.message : err
637
- );
638
- ensureReviewDir(launch.repo);
639
- writeDiffCache(launch.repo, outputFilename, { branch, base });
703
+ if (branch === base || sameCommitTips(launch.repo, branch, base)) {
704
+ console.error(emptyDiffPickMessage(branch, base));
705
+ process.exit(1);
706
+ }
707
+ const prep = prepareContext(launch, branch, base, outputFilename, { useClack: false });
708
+ if (prep.empty) {
709
+ console.error(prep.message);
710
+ process.exit(1);
640
711
  }
641
712
  const prompt = buildPrompt(
642
713
  {
@@ -646,7 +717,7 @@ async function runUiMode(opts, launch, launchCwd) {
646
717
  base,
647
718
  remoteUrl: launch.remoteUrl
648
719
  },
649
- promptOpts
720
+ prep.promptOpts
650
721
  );
651
722
  if (copyTextToClipboard(prompt)) {
652
723
  console.log('Prompt copiado al portapapeles.');
@@ -695,46 +766,58 @@ async function main() {
695
766
  process.exit(1);
696
767
  }
697
768
 
698
- const { branch, base, prompted } = await resolveBranchBase(launch, opts);
769
+ /** @type {{ branch: string, base: string }} */
770
+ let pick = { branch: opts.branch, base: opts.base };
771
+ let skipIntro = false;
772
+ /** @type {string} */
773
+ let branch;
774
+ /** @type {string} */
775
+ let base;
776
+ /** @type {boolean} */
777
+ let prompted;
778
+ /** @type {string} */
779
+ let outputFilename;
780
+ /** @type {ReturnType<typeof prepareReviewPromptOpts>} */
781
+ let promptOpts;
782
+
783
+ for (;;) {
784
+ ({ branch, base, prompted } = await resolveBranchBase(launch, pick, { skipIntro }));
785
+ if (prompted) skipIntro = true;
786
+
787
+ if (branch === base || sameCommitTips(launch.repo, branch, base)) {
788
+ const msg = emptyDiffPickMessage(branch, base);
789
+ if (prompted || isInteractive()) {
790
+ p.log.warn(msg);
791
+ pick = { branch: '', base: '' };
792
+ continue;
793
+ }
794
+ console.error(msg);
795
+ process.exit(1);
796
+ }
699
797
 
700
- if (branch === base) {
701
- // Ambos flags iguales / sin TTY: no se puede corregir en selects.
702
- console.log(
703
- `Branch y base son iguales (${branch}): el diff estaría vacío.\nAbro la UI para que elijas otra combinación.`
704
- );
705
- await startServer({
706
- host: opts.host,
707
- port: opts.port,
708
- open: opts.open,
709
- launchCwd,
710
- openPath: '/'
711
- });
712
- return;
713
- }
798
+ outputFilename = buildOutputFilename(launch.repo, branch, base);
799
+ if (!prompted) {
800
+ console.log(`Repo: ${launch.repo}`);
801
+ console.log(`Branch: ${branch} (base: ${base})`);
802
+ } else {
803
+ p.note(`${branch} → ${base}\n${outputRelPath(outputFilename)}`, 'Review');
804
+ }
714
805
 
715
- const outputFilename = buildOutputFilename(launch.repo, branch, base);
716
- // El agente escribe en .diff-review/ (que se ignora sola) y lee de ahí el diff ya calculado.
717
- let promptOpts = { outputFilename };
718
- try {
719
- promptOpts = prepareReviewPromptOpts({
720
- repo: launch.repo,
721
- branch,
722
- base,
723
- outputFilename
806
+ // El agente escribe en .diff-review/ (que se ignora sola) y lee de ahí el diff ya calculado.
807
+ const prep = prepareContext(launch, branch, base, outputFilename, {
808
+ useClack: prompted || isInteractive()
724
809
  });
725
- } catch (err) {
726
- const msg = err instanceof Error ? err.message : String(err);
727
- if (prompted) p.log.warn(`No pude precomputar el diff: ${msg}`);
728
- else console.warn('No pude precomputar el diff:', msg);
729
- ensureReviewDir(launch.repo);
730
- writeDiffCache(launch.repo, outputFilename, { branch, base });
731
- }
732
-
733
- if (!prompted) {
734
- console.log(`Repo: ${launch.repo}`);
735
- console.log(`Branch: ${branch} (base: ${base})`);
736
- } else {
737
- p.note(`${branch} → ${base}\n${outputRelPath(outputFilename)}`, 'Review');
810
+ if (prep.empty) {
811
+ if (prompted || isInteractive()) {
812
+ p.log.warn(prep.message);
813
+ pick = { branch: '', base: '' };
814
+ continue;
815
+ }
816
+ console.error(prep.message);
817
+ process.exit(1);
818
+ }
819
+ promptOpts = prep.promptOpts;
820
+ break;
738
821
  }
739
822
 
740
823
  const prompt = buildPrompt(
package/lib/acp-shell.mjs CHANGED
@@ -5,6 +5,9 @@
5
5
  *
6
6
  * El comando se tokeniza respetando comillas (un `grep "a\|b"` no es un pipe). Se aceptan `|`, `&&`, `||`, `;` y
7
7
  * descartar salida a /dev/null; cualquier otra redirección, `$(…)`, backticks o `&` lo rechazan.
8
+ *
9
+ * En PowerShell, `(Get-Content f).Count` llega como `(Get-Content` + `f).Count`: se quitan paréntesis de
10
+ * agrupación y el `.Miembro` colgado al path/flag antes de evaluar la allowlist.
8
11
  */
9
12
  import { realpathSync } from "node:fs";
10
13
  import { basename, dirname, isAbsolute, normalize, resolve } from "node:path";
@@ -376,6 +379,23 @@ function checkReviewDirMkdir(argv, ctx) {
376
379
  return null;
377
380
  }
378
381
 
382
+ /**
383
+ * Quita agrupación PowerShell pegada al token: `(Get-Content` → `Get-Content`,
384
+ * `file.diff).Count` → `file.diff`, `-Line).Lines` → `-Line`.
385
+ * @param {string} token
386
+ */
387
+ function stripPsGrouping(token) {
388
+ let t = String(token ?? "");
389
+ t = t.replace(/^\(+/, "");
390
+ t = t.replace(/\)+(?:\.[A-Za-z_][\w]*(?:\(\)?)?)*$/, "");
391
+ return t;
392
+ }
393
+
394
+ /** @param {string[]} argv */
395
+ function normalizePsArgv(argv) {
396
+ return argv.map(stripPsGrouping).filter((w) => w.length > 0);
397
+ }
398
+
379
399
  /**
380
400
  * @param {string} command
381
401
  * @param {{ repo?: string, platform?: NodeJS.Platform }} [opts]
@@ -387,7 +407,9 @@ export function checkShell(command, { repo, platform = process.platform } = {})
387
407
  if (!parsed.pipelines.length) return { ok: false, reason: "comando vacío" };
388
408
  const ctx = { repo: repo || process.cwd(), platform };
389
409
  for (const pipeline of parsed.pipelines) {
390
- for (const argv of pipeline) {
410
+ for (const rawArgv of pipeline) {
411
+ const argv = normalizePsArgv(rawArgv);
412
+ if (!argv.length) continue;
391
413
  const name = argv[0].toLowerCase();
392
414
  if (argv[0].includes("=")) return { ok: false, reason: `variables de entorno en el comando: ${argv[0]}` };
393
415
  /** @type {ShellCheck} */
@@ -64,6 +64,10 @@ test("checkShell deja git de lectura, el validate y comandos que solo leen", ()
64
64
  "git diff a...b -- lib 2>/dev/null || true",
65
65
  "Get-Content lib/agents.mjs | Select-Object -First 40",
66
66
  "Select-String -Path lib/*.mjs -Pattern 'export'",
67
+ // Agrupación PowerShell: `(cmd).Property` (Copilot/Opus suele contar líneas así).
68
+ "(Get-Content lib/agents.mjs).Count",
69
+ "(Get-Content .diff-review/diff-rev_x.diff).Count",
70
+ "(Get-Content lib/a.mjs | Measure-Object -Line).Lines",
67
71
  ]) {
68
72
  assert.equal(ok(cmd), true, cmd);
69
73
  }
@@ -73,6 +77,9 @@ test("checkShell rechaza escrituras, ejecución y paths fuera del repo", () => {
73
77
  const home = win ? "C:\\Users\\me\\.ssh\\id_rsa" : "/home/me/.ssh/id_rsa";
74
78
  for (const cmd of [
75
79
  "",
80
+ // Agrupar no habilita comandos fuera de la allowlist.
81
+ "(Remove-Item lib/a.mjs)",
82
+ "(Invoke-WebRequest https://example.com).Content",
76
83
  "git checkout main",
77
84
  "git branch -D feat",
78
85
  "git push",
package/lib/prompt.mjs CHANGED
@@ -91,7 +91,7 @@ const RULES = `- Ids: themes use \`t1\`, \`t2\`, …; findings use \`f1\`, \`f2\
91
91
  function workflowLocal(base, branch, ctx = {}) {
92
92
  if (ctx.hasDiff) {
93
93
  return `Workflow:
94
- 1. Read the three-dot diff from the path given in "Precomputed git context" below. Do not re-run \`git diff\` unless that file is missing.
94
+ 1. The host already computed the three-dot diff and wrote it to disk (see "Precomputed git context"). Read that file with your file tools. Do not run \`git diff\`, \`git merge-base\`, or rebuild the patch yourself unless that file is missing.
95
95
  2. Read enough surrounding code (types, callers, tests) to judge behavior, not only the hunk lines.
96
96
  3. Emit the JSON file. Do not modify the repo.
97
97
  4. Validate it with the command in the output section. If it prints INVALID, follow "How to continue" and re-run until it prints OK.`;
@@ -115,7 +115,7 @@ function workflowUrl(base, branch, ctx = {}) {
115
115
  if (ctx.hasDiff) {
116
116
  return `Workflow:
117
117
  1. If the repo is not local, clone it (or use whatever access you have). Do not modify it.
118
- 2. Read the three-dot diff from the path given in "Precomputed git context" below. Do not re-run \`git diff\` unless that file is missing.
118
+ 2. The host already computed the three-dot diff and wrote it to disk (see "Precomputed git context"). Read that file with your file tools. Do not run \`git diff\`, \`git merge-base\`, or rebuild the patch yourself unless that file is missing.
119
119
  3. Read enough surrounding code (types, callers, tests) to judge behavior, not only the hunk lines.
120
120
  4. Emit the JSON file.
121
121
  5. Validate it with the command in the output section. If it prints INVALID, follow "How to continue" and re-run until it prints OK.`;
@@ -133,7 +133,7 @@ function workflowUrl(base, branch, ctx = {}) {
133
133
  function workflowLocalAcp(ctx = {}) {
134
134
  if (ctx.hasDiff) {
135
135
  return `Workflow:
136
- 1. Read the three-dot diff from the path given in "Precomputed git context" below. Do not re-run \`git diff\` unless that file is missing.
136
+ 1. The host already computed the three-dot diff and wrote it to disk (see "Precomputed git context"). Read that file with your file tools. Do not run \`git diff\`, \`git merge-base\`, or rebuild the patch yourself unless that file is missing.
137
137
  2. Read enough surrounding code (types, callers, tests) to judge behavior, not only the hunk lines.
138
138
  3. Write the JSON with your file Write/Edit tool (never shell redirection). Do not modify other repo files. The host validates when your turn ends — do not run the validate CLI.`;
139
139
  }
@@ -147,7 +147,7 @@ function workflowUrlAcp(ctx = {}) {
147
147
  if (ctx.hasDiff) {
148
148
  return `Workflow:
149
149
  1. If the repo is not local, clone it (or use whatever access you have). Do not modify it.
150
- 2. Read the three-dot diff from the path given in "Precomputed git context" below. Do not re-run \`git diff\` unless that file is missing.
150
+ 2. The host already computed the three-dot diff and wrote it to disk (see "Precomputed git context"). Read that file with your file tools. Do not run \`git diff\`, \`git merge-base\`, or rebuild the patch yourself unless that file is missing.
151
151
  3. Read enough surrounding code (types, callers, tests) to judge behavior, not only the hunk lines.
152
152
  4. Write the JSON with your file Write/Edit tool (never shell redirection). The host validates when your turn ends — do not run the validate CLI.`;
153
153
  }
@@ -197,13 +197,15 @@ export function outputSchemaBlock(meta) {
197
197
  * }} ctx
198
198
  */
199
199
  function formatPrecomputedContext(ctx) {
200
- const lines = ["Precomputed git context (do not rediscover):"];
200
+ const lines = [
201
+ "Precomputed git context (provided by the host — do not rediscover or recompute):",
202
+ ];
201
203
  if (ctx.mergeBase) lines.push(`- Merge-base SHA: \`${ctx.mergeBase}\``);
202
204
  if (ctx.branchSha) lines.push(`- Branch tip SHA: \`${ctx.branchSha}\``);
203
205
  if (ctx.baseSha) lines.push(`- Base tip SHA: \`${ctx.baseSha}\``);
204
206
  if (ctx.diffRelPath) {
205
207
  lines.push(
206
- `- Diff file (relative to repo root): \`${ctx.diffRelPath}\` — read this file; do not re-run \`git diff\` unless it is missing.`
208
+ `- Diff file (relative to repo root): \`${ctx.diffRelPath}\` — Read this file for the full patch. Do not run \`git diff\` / \`git merge-base\` to rebuild it unless the file is missing.`
207
209
  );
208
210
  }
209
211
  const files = Array.isArray(ctx.files) ? ctx.files : [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jpkme/diff-review",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Local UI to prompt a coding agent for a branch review and browse the result.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1 @@
1
+ .live.svelte-18urbyr{background:radial-gradient(900px 420px at 8% -8%, color-mix(in srgb, var(--accent) 10%, transparent), transparent 70%), var(--bg);flex-direction:column;flex:1;min-height:0;display:flex}.bar.svelte-18urbyr{border-bottom:1px solid var(--border);background:color-mix(in srgb, var(--bg-elev) 90%, transparent);justify-content:space-between;align-items:center;gap:12px;padding:12px 20px;display:flex}.brand.svelte-18urbyr{align-items:center;gap:10px;min-width:0;font-size:14px;display:flex}.dot.svelte-18urbyr{background:var(--accent);width:8px;height:8px;box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);border-radius:50%;flex:none}.pill.svelte-18urbyr{letter-spacing:.02em;border:1px solid var(--border);color:var(--text-dim);background:var(--bg-card);text-transform:lowercase;border-radius:0;padding:3px 9px;font-size:11px;font-weight:500}.pill.busy.svelte-18urbyr{border-color:color-mix(in srgb, var(--accent) 45%, var(--border));color:var(--accent);background:var(--accent-soft)}.pill.error.svelte-18urbyr{border-color:var(--danger-border,var(--danger));color:var(--danger);background:var(--danger-bg,transparent)}.pill.gone.svelte-18urbyr{color:var(--text-faint)}.actions.svelte-18urbyr{flex:none;align-items:center;gap:8px;display:flex}.ghost.svelte-18urbyr{border:1px solid var(--border);color:var(--text);font:inherit;cursor:pointer;background:0 0;padding:6px 11px;font-size:13px}.ghost.svelte-18urbyr:hover{border-color:var(--accent)}.body.svelte-18urbyr{flex:1;grid-template-columns:minmax(280px,320px) 1fr;gap:20px;min-height:0;padding:20px 24px 24px;display:grid}.card.svelte-18urbyr{border:1px solid var(--border);background:var(--bg-elev);border-radius:0;align-self:start;padding:16px 16px 14px}.fields.svelte-18urbyr{flex-direction:column;gap:14px;margin:0;display:flex}.fields.svelte-18urbyr dt:where(.svelte-18urbyr){text-transform:uppercase;letter-spacing:.04em;color:var(--text-faint);margin:0 0 3px;font-size:11px}.fields.svelte-18urbyr dd:where(.svelte-18urbyr){font-size:13px;font-family:var(--mono);text-overflow:ellipsis;white-space:nowrap;color:var(--text);margin:0;overflow:hidden}.branch.svelte-18urbyr{color:var(--accent);font-weight:600}.arrow.svelte-18urbyr{color:var(--text-faint);margin:0 2px}.card-note.svelte-18urbyr{border-top:1px solid var(--border-soft,var(--border));color:var(--text-faint);margin:16px 0 0;padding-top:12px;font-size:12.5px;line-height:1.4}.stage.svelte-18urbyr{border:1px solid var(--border);background:var(--bg-elev);border-radius:0;flex-direction:column;min-width:0;min-height:0;display:flex;overflow:hidden}.center.svelte-18urbyr{text-align:center;flex-direction:column;flex:1;justify-content:center;align-items:center;gap:8px;padding:40px 24px;display:flex}.center.fail.svelte-18urbyr .title:where(.svelte-18urbyr){color:var(--danger)}.auth-actions.svelte-18urbyr{flex-wrap:wrap;justify-content:center;gap:8px;margin-top:12px;display:flex}.primary.svelte-18urbyr{border:1px solid color-mix(in srgb, var(--accent) 55%, var(--border));background:var(--accent-soft);color:var(--accent);font:inherit;cursor:pointer;border-radius:0;padding:7px 14px;font-size:13px;font-weight:600}.primary.svelte-18urbyr:hover:not(:disabled){border-color:var(--accent)}.primary.svelte-18urbyr:disabled{opacity:.6;cursor:default}.auth-note.svelte-18urbyr{max-width:28rem;color:var(--text-dim);margin:10px 0 0;font-size:13px}.auth-err.svelte-18urbyr{max-width:28rem;color:var(--danger);margin:8px 0 0;font-size:13px}.spinner.svelte-18urbyr{border:2px solid var(--border);border-top-color:var(--accent);border-radius:50%;width:34px;height:34px;margin-bottom:6px;animation:.8s linear infinite svelte-18urbyr-spin}@keyframes svelte-18urbyr-spin{to{transform:rotate(360deg)}}.title.svelte-18urbyr{margin:0;font-size:17px;font-weight:600}.detail.svelte-18urbyr{color:var(--text-dim);max-width:28rem;margin:0;font-size:14px}.hint.svelte-18urbyr{max-width:32rem;color:var(--text-faint);margin:6px 0 0;font-size:13px}.stage-header.svelte-18urbyr{border-bottom:1px solid var(--border);border-radius:0;flex:none;align-items:center;gap:8px;min-width:0;padding:10px 14px;display:flex}.stage-header.svelte-18urbyr strong:where(.svelte-18urbyr){font-size:13.5px;font-weight:650}.stage-header.svelte-18urbyr small:where(.svelte-18urbyr){font-family:var(--mono);color:var(--text-faint);text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:11.5px;overflow:hidden}.log-wrap.svelte-18urbyr{border-radius:0;flex-direction:column;flex:1;gap:10px;min-height:0;padding:12px 14px;display:flex}.log-wrap.svelte-18urbyr .log{flex:1;min-height:0}.stage-footer.svelte-18urbyr{border-top:1px solid var(--border);border-radius:0;flex-wrap:wrap;flex:none;align-items:center;gap:10px;min-width:0;margin-top:auto;padding-top:10px;display:flex}.stage-footer.svelte-18urbyr .trust{flex:0 auto;width:auto;min-width:0;max-width:100%}.footer-spacer.svelte-18urbyr{flex:8px;min-width:8px}.stage-footer.svelte-18urbyr .perm-actions{flex:none}.launch-banner.svelte-18urbyr{border:1px solid var(--border);background:color-mix(in srgb, var(--accent-soft) 70%, var(--bg-card));border-radius:0;align-items:flex-start;gap:12px;padding:10px 12px;display:flex}.launch-banner.svelte-18urbyr .title:where(.svelte-18urbyr){font-size:14px}.launch-banner.svelte-18urbyr .detail:where(.svelte-18urbyr){margin-top:2px;font-size:12.5px}.spinner.sm.svelte-18urbyr{flex:none;width:18px;height:18px;margin:2px 0 0}@media (width<=800px){.body.svelte-18urbyr{grid-template-rows:auto 1fr;grid-template-columns:1fr;gap:14px;padding:16px}.card.svelte-18urbyr{align-self:stretch}.stage.svelte-18urbyr{min-height:280px}}@media (width<=480px){.bar.svelte-18urbyr{flex-wrap:wrap;padding:10px 14px}.pill.svelte-18urbyr{font-size:10px}}.page.svelte-1uha8ag{flex-direction:column;min-height:100vh;display:flex}.page.live.svelte-1uha8ag{height:100vh;min-height:100vh;overflow:hidden}.diff-spinner.svelte-1uha8ag{border:2px solid var(--border);border-top-color:var(--accent);border-radius:50%;width:28px;height:28px;margin:0 auto;animation:.7s linear infinite svelte-1uha8ag-diff-spin}.cli-wait.svelte-1uha8ag{text-align:center;background:var(--bg);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:12px;min-height:0;padding:32px 24px;display:flex}.cli-wait-title.svelte-1uha8ag{color:var(--text);margin:0;font-size:15px}.cli-wait-detail.svelte-1uha8ag{color:var(--text-faint);margin:0;font-size:13px}.cli-wait.svelte-1uha8ag .ghost:where(.svelte-1uha8ag){border:1px solid var(--border);color:var(--text-dim);cursor:pointer;background:0 0;margin-top:8px;padding:6px 12px;font-size:13px}@keyframes svelte-1uha8ag-diff-spin{to{transform:rotate(360deg)}}.toast.svelte-1uha8ag{z-index:50;border:1px solid var(--border);background:var(--bg-card);color:var(--text);padding:10px 16px;font-size:13px;position:fixed;top:16px;left:50%;transform:translate(-50%);box-shadow:0 8px 24px #00000029}.topbar.svelte-1uha8ag{border-bottom:1px solid var(--border);background:var(--header-bg);z-index:5;justify-content:space-between;align-items:center;gap:12px;padding:16px 28px;display:flex;position:sticky;top:0}.brand.svelte-1uha8ag{color:var(--text);align-items:center;gap:10px;text-decoration:none;display:flex}.brand-dot.svelte-1uha8ag{background:linear-gradient(135deg,#6ea8fe,#c9a5ff);border-radius:50%;flex-shrink:0;width:9px;height:9px;box-shadow:0 0 12px #6ea8fe88}.title-block.svelte-1uha8ag{text-align:left;flex-direction:column;line-height:1.25;display:flex}.title-block.svelte-1uha8ag span:where(.svelte-1uha8ag):first-child{font-size:15px;font-weight:700}.title-block.svelte-1uha8ag small:where(.svelte-1uha8ag){color:var(--text-faint);font-size:11.5px;font-weight:400}.workspace.svelte-1uha8ag{flex:1;grid-template-columns:minmax(0,1fr) minmax(300px,380px);align-items:start;gap:28px;width:100%;max-width:1280px;margin:0 auto;padding:22px 28px 40px;display:grid;overflow:auto}.setup.svelte-1uha8ag{min-width:0}h2.svelte-1uha8ag{letter-spacing:.06em;text-transform:uppercase;color:var(--text-faint);margin:0 0 4px;font-size:13px;font-weight:600}.result-head.svelte-1uha8ag{margin-top:24px}.section-head.svelte-1uha8ag{justify-content:space-between;align-items:baseline;margin-top:22px;display:flex}.hint-text.svelte-1uha8ag{color:var(--text-dim);margin:0 0 12px;font-size:12.5px;line-height:1.5}.hint-text.svelte-1uha8ag code:where(.svelte-1uha8ag){font-family:var(--mono);color:var(--text);font-size:12px}.detect-banner.svelte-1uha8ag,.detect-wait.svelte-1uha8ag{color:var(--text-dim);margin:0 0 10px;font-size:13px}button.file-link.svelte-1uha8ag{color:var(--accent);font:inherit;cursor:pointer;background:0 0;border:0;padding:0;text-decoration:underline}.error-line.svelte-1uha8ag{color:var(--danger);margin:0 0 10px;font-size:12px}.ok-line.svelte-1uha8ag{color:var(--ok);margin:0 0 10px;font-size:12px}.row.svelte-1uha8ag{flex-wrap:wrap;gap:8px;display:flex}.repo-setup.svelte-1uha8ag{flex-direction:column;gap:10px;display:flex}.field.svelte-1uha8ag{flex-direction:column;flex:1;gap:4px;min-width:180px;display:flex}.repo-field.svelte-1uha8ag{flex:none;width:100%;min-width:0}.branches-row.svelte-1uha8ag .field:where(.svelte-1uha8ag){flex:1;min-width:160px}.field.svelte-1uha8ag span:where(.svelte-1uha8ag){color:var(--text-faint);font-size:11px}.repo-row.svelte-1uha8ag{gap:6px;min-width:0;display:flex}.repo-row.svelte-1uha8ag input[type=text]:where(.svelte-1uha8ag){flex:1;min-width:0}.repo-row.svelte-1uha8ag button:where(.svelte-1uha8ag){flex-shrink:0}.source-toggle.svelte-1uha8ag{margin-bottom:10px}input[type=text].svelte-1uha8ag,select.svelte-1uha8ag{background:var(--bg-card);border:1px solid var(--border);flex:1;min-width:0;padding:9px 12px}button.svelte-1uha8ag{background:var(--bg-card);border:1px solid var(--border);color:var(--text);padding:9px 12px;font-size:12.5px}button.svelte-1uha8ag:hover:not(:disabled){border-color:var(--accent)}button.svelte-1uha8ag:disabled{opacity:.5;cursor:not-allowed}.mode-toggle.svelte-1uha8ag{border:1px solid var(--border);width:fit-content;margin-bottom:10px;display:flex;overflow:hidden}.mode-toggle.svelte-1uha8ag button:where(.svelte-1uha8ag){background:0 0;border:0;padding:6px 12px;font-size:12px}.mode-toggle.svelte-1uha8ag button:where(.svelte-1uha8ag)+button:where(.svelte-1uha8ag){border-left:1px solid var(--border)}.mode-toggle.svelte-1uha8ag button.on:where(.svelte-1uha8ag){background:var(--accent-soft)}textarea.svelte-1uha8ag{resize:vertical;background:var(--bg);border:1px solid var(--border);width:100%;height:220px;font-family:var(--mono);color:var(--text);padding:12px;font-size:12px;line-height:1.5}.loading-models.svelte-1uha8ag{color:var(--text-faint);font-weight:400}.models-error.svelte-1uha8ag{flex-wrap:wrap;align-items:baseline;gap:8px;display:flex}button.linkish.svelte-1uha8ag{color:var(--accent,#3b82f6);cursor:pointer;font:inherit;background:0 0;border:none;padding:0;text-decoration:underline}.actions.svelte-1uha8ag{gap:8px;margin-top:10px;display:flex}button.primary.svelte-1uha8ag{background:var(--btn-primary-bg);border-color:var(--btn-primary-border);color:var(--btn-primary-text);font-weight:600}.coverage-box.svelte-1uha8ag{border:1px solid var(--border);border-left:3px solid var(--sev-med);background:var(--bg-card);flex-direction:column;gap:10px;margin-top:12px;padding:12px 14px;display:flex}.coverage-head.svelte-1uha8ag{flex-wrap:wrap;align-items:baseline;gap:8px;display:flex}.coverage-head.svelte-1uha8ag strong:where(.svelte-1uha8ag){color:var(--sev-med);font-size:13px}.coverage-head.svelte-1uha8ag span:where(.svelte-1uha8ag){color:var(--text-faint);font-size:11.5px}.coverage-box.svelte-1uha8ag summary:where(.svelte-1uha8ag){color:var(--text-dim);cursor:pointer;font-size:12px}.coverage-list.svelte-1uha8ag{max-height:180px;font-family:var(--mono);color:var(--text-faint);margin:8px 0 0;padding-left:18px;font-size:11px;overflow:auto}.coverage-box.svelte-1uha8ag textarea:where(.svelte-1uha8ag){resize:vertical;background:var(--bg);border:1px solid var(--border);width:100%;font-family:var(--mono);color:var(--text);padding:10px;font-size:11.5px;line-height:1.5}.coverage-actions.svelte-1uha8ag{flex-wrap:wrap;gap:8px;display:flex}.dropzone.svelte-1uha8ag{border:1.5px dashed var(--border);text-align:center;background:var(--bg-elev);padding:26px;transition:background .15s,border-color .15s}.dropzone.drag.svelte-1uha8ag{border-color:var(--accent);background:var(--accent-soft)}.dropzone.busy.svelte-1uha8ag{opacity:.7}.dropzone.svelte-1uha8ag p:where(.svelte-1uha8ag){color:var(--text-dim);margin:0 0 6px;font-size:14px}.visually-hidden.svelte-1uha8ag{clip:rect(0 0 0 0);width:1px;height:1px;position:absolute;overflow:hidden}.drop-errors.svelte-1uha8ag{background:var(--danger-bg);color:var(--danger);margin-top:10px;padding:10px 12px;font-size:12.5px}.drop-errors.svelte-1uha8ag strong:where(.svelte-1uha8ag){margin-bottom:4px;display:block}.drop-errors.svelte-1uha8ag ul:where(.svelte-1uha8ag){margin:0;padding-left:18px;line-height:1.6}.reports-col.svelte-1uha8ag{min-width:0;max-height:calc(100vh - 110px);position:sticky;top:88px;overflow:auto}.report-list.svelte-1uha8ag{flex-direction:column;gap:8px;margin:0;padding:0;list-style:none;display:flex}.report-item.svelte-1uha8ag{border:1px solid var(--border);background:var(--bg-card);align-items:stretch;display:flex;position:relative;overflow:visible}.report-item.svelte-1uha8ag:hover{background:var(--bg-card-hover);border-color:#33507a}.report-card.svelte-1uha8ag{min-width:0;color:var(--text);flex:1;padding:12px 8px 12px 14px;text-decoration:none;display:block}.report-actions.svelte-1uha8ag{flex-shrink:0;padding:8px 8px 0 0;position:relative}.kebab.svelte-1uha8ag{width:26px;height:26px;color:var(--text-faint);cursor:pointer;background:0 0;border:1px solid #0000;justify-content:center;align-items:center;padding:0;display:inline-flex}.kebab.svelte-1uha8ag:hover{border-color:var(--border);color:var(--text);background:var(--bg)}.report-menu.svelte-1uha8ag{z-index:40;border:1px solid var(--border);background:var(--bg-card);width:148px;padding:4px;position:fixed;box-shadow:0 8px 24px #0000002e}.report-menu.svelte-1uha8ag .menu-item:where(.svelte-1uha8ag){width:100%;color:var(--text);text-align:left;cursor:pointer;background:0 0;border:0;padding:8px 10px;font-size:12.5px;display:block}.report-menu.svelte-1uha8ag .menu-item:where(.svelte-1uha8ag):hover{background:var(--accent-soft)}.report-menu.svelte-1uha8ag .menu-item.danger:where(.svelte-1uha8ag){color:var(--danger)}.report-top.svelte-1uha8ag{justify-content:space-between;align-items:baseline;gap:12px;display:flex}.report-top.svelte-1uha8ag strong:where(.svelte-1uha8ag){font-size:14px}.report-prov.svelte-1uha8ag{min-width:0;color:var(--text-dim);align-items:center;gap:6px;margin-top:4px;font-size:12px;display:flex}.report-prov.svelte-1uha8ag .prov-agent:where(.svelte-1uha8ag){text-overflow:ellipsis;white-space:nowrap;flex:0 auto;min-width:0;overflow:hidden}.report-prov.svelte-1uha8ag .prov-sep:where(.svelte-1uha8ag){color:var(--text-faint);flex-shrink:0}.report-prov.svelte-1uha8ag .prov-model:where(.svelte-1uha8ag){min-width:0;font-family:var(--mono);text-overflow:ellipsis;white-space:nowrap;flex:auto;font-size:11.5px;overflow:hidden}.when.svelte-1uha8ag{color:var(--text-dim);font-size:12px}.report-meta.svelte-1uha8ag{color:var(--text-dim);justify-content:space-between;align-items:baseline;gap:12px;margin-top:6px;font-size:12px;display:flex}.report-base.svelte-1uha8ag{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.base-arrow.svelte-1uha8ag{color:var(--text-faint)}.report-counts.svelte-1uha8ag{flex-shrink:0;align-items:baseline;gap:8px;display:flex}.pill.svelte-1uha8ag{font-family:var(--mono);font-size:11px}.pill.bad.svelte-1uha8ag{color:var(--danger)}.report-intent.svelte-1uha8ag{color:var(--text-dim);-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;margin:8px 0 0;font-size:12.5px;line-height:1.45;display:-webkit-box;overflow:hidden}@media (width<=960px){.workspace.svelte-1uha8ag{grid-template-columns:1fr}.reports-col.svelte-1uha8ag{max-height:none;position:static}}
@@ -0,0 +1 @@
1
+ .resize-handle.svelte-ywcz8g{cursor:col-resize;z-index:2;touch-action:none;background:0 0;flex-shrink:0;width:6px;position:relative}.resize-handle.svelte-ywcz8g:after{content:"";background:0 0;width:2px;position:absolute;top:0;bottom:0;left:2px}.resize-handle.svelte-ywcz8g:hover:after,.resize-handle.dragging.svelte-ywcz8g:after{background:var(--accent)}.chat-shell.svelte-1nylsi{flex-shrink:0;align-self:stretch;min-width:0;min-height:0;display:flex}.chat.svelte-1nylsi{border-left:1px solid var(--border);background:var(--bg-elev);flex-direction:column;flex:1;min-width:0;min-height:0;display:flex}header.svelte-1nylsi{border-bottom:1px solid var(--border);justify-content:space-between;align-items:center;padding:10px 14px;display:flex}.title.svelte-1nylsi{align-items:center;gap:8px;min-width:0;display:flex}.title.svelte-1nylsi strong:where(.svelte-1nylsi){font-size:13.5px;font-weight:650}.title.svelte-1nylsi small:where(.svelte-1nylsi){font-family:var(--mono);color:var(--text-faint);text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:11.5px;overflow:hidden}.close.svelte-1nylsi{color:var(--text-dim);cursor:pointer;background:0 0;border:0;font-size:13px}.log-area.svelte-1nylsi{flex-direction:column;flex:1;gap:10px;min-height:0;padding:12px 14px;display:flex}.log.svelte-1nylsi{flex:1;min-height:0;display:flex}.log.svelte-1nylsi .log{flex:1;min-height:0}.picker.svelte-1nylsi{flex-direction:column;flex:1;gap:10px;padding:14px;display:flex}.field.svelte-1nylsi{color:var(--text-dim);flex-direction:column;gap:4px;font-size:12px;display:flex}.field.svelte-1nylsi .agent-select .trigger{padding:6px 8px;font-size:13px}.field.svelte-1nylsi small:where(.svelte-1nylsi){color:var(--text-faint)}.start.svelte-1nylsi{background:var(--btn-primary-bg);border:1px solid var(--btn-primary-border);color:var(--btn-primary-text);align-self:flex-start;padding:8px 14px;font-size:13px}.start.svelte-1nylsi:disabled{opacity:.5}.hint.svelte-1nylsi,.note.svelte-1nylsi,.err.svelte-1nylsi{color:var(--text-faint);margin:0;padding:8px 14px;font-size:12.5px}.picker.svelte-1nylsi .hint:where(.svelte-1nylsi){padding:0}.err.svelte-1nylsi{color:var(--danger)}.models-error.svelte-1nylsi{flex-wrap:wrap;align-items:baseline;gap:8px;padding-inline:0;display:flex}button.linkish.svelte-1nylsi{color:var(--accent,#3b82f6);cursor:pointer;font:inherit;background:0 0;border:none;padding:0;text-decoration:underline}.connecting.svelte-1nylsi{text-align:center;flex-direction:column;flex:1;justify-content:center;gap:6px;padding:18px 8px;display:flex}.connecting-title.svelte-1nylsi{color:var(--text);margin:0;font-size:13.5px;font-weight:650}.connecting-detail.svelte-1nylsi{font-size:12px;font-family:var(--mono);color:var(--text-dim);word-break:break-all;margin:0}.connecting-hint.svelte-1nylsi{color:var(--text-faint);margin:4px 0 0;font-size:12px}.composer.svelte-1nylsi{border-top:1px solid var(--border);flex-direction:column;gap:8px;padding:10px 14px 14px;display:flex}.composer-top.svelte-1nylsi{flex-wrap:wrap;align-items:flex-end;gap:10px;display:flex}.model-field.svelte-1nylsi{flex:0 auto;min-width:0;max-width:min(220px,42%);margin-left:auto}.mode-toggle.svelte-1nylsi{border:1px solid var(--border);flex-shrink:0;align-self:flex-start;display:flex}.mode-toggle.svelte-1nylsi button:where(.svelte-1nylsi){color:var(--text);background:0 0;border:0;padding:5px 10px;font-size:12px}.mode-toggle.svelte-1nylsi button:where(.svelte-1nylsi)+button:where(.svelte-1nylsi){border-left:1px solid var(--border)}.mode-toggle.svelte-1nylsi button.on:where(.svelte-1nylsi){background:var(--accent-soft)}textarea.svelte-1nylsi{resize:vertical;min-height:60px;font:inherit;background:var(--bg-card);color:var(--text);border:1px solid var(--border);padding:8px;font-size:13px}.actions.svelte-1nylsi{align-items:center;gap:8px;display:flex}.actions-spacer.svelte-1nylsi{flex:1;min-width:0}.actions.svelte-1nylsi button:where(.svelte-1nylsi){background:var(--bg-card);border:1px solid var(--border);color:var(--text);padding:6px 12px;font-size:12.5px}.actions.svelte-1nylsi button.primary:where(.svelte-1nylsi){background:var(--btn-primary-bg);border-color:var(--btn-primary-border);color:var(--btn-primary-text)}.actions.svelte-1nylsi button:where(.svelte-1nylsi):disabled{opacity:.5}.ask-agent.svelte-1dix5z0{border:1px solid var(--border);background:var(--bg-card);width:28px;height:28px;color:var(--text-dim);cursor:pointer;border-radius:0;flex-shrink:0;justify-content:center;align-items:center;padding:0;display:inline-flex}.ask-agent.svelte-1dix5z0:hover{border-color:var(--border-strong,var(--border));color:var(--text);background:var(--bg-elev,var(--bg-card))}.diff-wrap.svelte-13r6alg{background:var(--bg);--ln-w:calc(var(--diff-font-size,11.5px) * 3.1);--sign-w:calc(var(--diff-font-size,11.5px) * 1.05);--divider-w:5px}.collapse-bar.svelte-13r6alg{background:var(--diff-hunk-bg);border-bottom:1px solid var(--border-soft);color:var(--text-faint);flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px;padding:5px 10px;font-size:10.5px;display:flex}.link.svelte-13r6alg{color:var(--accent);background:0 0;border:0;padding:0;font-size:10.5px;text-decoration:underline}.gap-bar.svelte-13r6alg{background:var(--diff-hunk-bg);border-top:1px solid var(--border-soft);border-bottom:1px solid var(--border-soft);align-items:center;gap:10px;padding:3px 10px;display:flex}.gap-actions.svelte-13r6alg{border:1px solid var(--border);flex-shrink:0;display:flex;overflow:hidden}.gap-actions.svelte-13r6alg button:where(.svelte-13r6alg){background:var(--bg-card);font-family:var(--mono);font-size:calc(var(--diff-font-size,11.5px) * .87);color:var(--text-dim);border:0;padding:1px 8px;line-height:1.5}.gap-actions.svelte-13r6alg button:where(.svelte-13r6alg)+button:where(.svelte-13r6alg){border-left:1px solid var(--border)}.gap-actions.svelte-13r6alg button:where(.svelte-13r6alg):hover:not(:disabled){background:var(--accent-soft);color:var(--text)}.gap-actions.svelte-13r6alg button:where(.svelte-13r6alg):disabled{opacity:.4;cursor:not-allowed}.gap-info.svelte-13r6alg{font-family:var(--mono);font-size:calc(var(--diff-font-size,11.5px) * .87);color:var(--text-faint);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.empty.svelte-13r6alg{color:var(--text-faint);margin:0;padding:12px;font-size:11.5px}.diff.svelte-13r6alg,.hunk-header.svelte-13r6alg{font-family:var(--mono)}.diff.svelte-13r6alg{max-height:55vh;font-size:var(--diff-font-size,11.5px);overflow:auto}.diff.wrap.svelte-13r6alg{overflow-x:hidden}.diff.wrap.svelte-13r6alg .row:where(.svelte-13r6alg){width:auto;min-width:0}.diff.wrap.svelte-13r6alg .code:where(.svelte-13r6alg){white-space:pre-wrap;overflow-wrap:anywhere}.hunk-header.svelte-13r6alg{background:var(--diff-hunk-bg);border-top:1px solid var(--border-soft);border-bottom:1px solid var(--border-soft);font-size:calc(var(--diff-font-size,11.5px) * .913);color:var(--text-faint);white-space:nowrap;text-overflow:ellipsis;padding:3px 10px;overflow:hidden}.row.svelte-13r6alg{grid-template-columns:var(--ln-w) var(--ln-w) var(--sign-w) auto;border-left:2px solid #0000;width:max-content;min-width:100%;display:grid}.split-grid.svelte-13r6alg{align-items:stretch;display:grid}.srow.svelte-13r6alg{display:contents}.divider.svelte-13r6alg{background:var(--border-soft);cursor:col-resize;touch-action:none}.divider.svelte-13r6alg:hover,.divider.svelte-13r6alg:active{background:var(--accent)}.split-grid.svelte-13r6alg .code:where(.svelte-13r6alg){white-space:pre-wrap;overflow-wrap:anywhere}.ln.svelte-13r6alg{text-align:right;color:var(--diff-gutter);font-size:calc(var(--diff-font-size,11.5px) * .87);-webkit-user-select:none;user-select:none;font-variant-numeric:tabular-nums;border-left:2px solid #0000;padding-right:6px;overflow:hidden}.row.svelte-13r6alg .ln:where(.svelte-13r6alg){border-left:0}.sign.svelte-13r6alg{text-align:center;-webkit-user-select:none;user-select:none;color:var(--text-faint)}.sign.add.svelte-13r6alg{color:var(--diff-add-fg)}.sign.del.svelte-13r6alg{color:var(--diff-del-fg)}.code.svelte-13r6alg{white-space:pre;padding-right:10px}.row.add.svelte-13r6alg{background:var(--diff-add-bg)}.row.add.svelte-13r6alg .sign:where(.svelte-13r6alg){color:var(--diff-add-fg)}.row.del.svelte-13r6alg{background:var(--diff-del-bg)}.row.del.svelte-13r6alg .sign:where(.svelte-13r6alg){color:var(--diff-del-fg)}.file-icon.svelte-1dshc1f{flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}.file-icon.svelte-1dshc1f svg{width:100%;height:100%}.file-icon.branded.svelte-1dshc1f svg{width:78%;height:78%}.file-icon.svelte-1dshc1f:not(.branded) svg{fill:currentColor}.explore.svelte-1k3qopq{display:contents}.blocker-bar.svelte-1k3qopq{background:var(--danger-bg);border:1px solid var(--danger-border);color:var(--danger);margin:0;padding:10px 14px;font-size:13px;font-weight:600}h2.svelte-1k3qopq{letter-spacing:.07em;text-transform:uppercase;color:var(--text-faint);margin:0 0 8px;font-size:12px;font-weight:650}.intent.svelte-1k3qopq{border-bottom:1px solid var(--border);padding:0 0 16px}.intent-text.svelte-1k3qopq{color:var(--text);max-width:80ch;margin:0;font-size:14px;line-height:1.6}.note.svelte-1k3qopq{color:var(--text-faint);max-width:80ch;margin:8px 0 0;font-size:11.5px;line-height:1.5}.group.svelte-1k3qopq{flex-direction:column;gap:12px;padding:18px 0 6px;display:flex}.group-sticky.svelte-1k3qopq{z-index:4;background:var(--bg);border-bottom:1px solid var(--border-soft);flex-direction:column;gap:6px;margin:0 -20px;padding:14px 20px 12px;display:flex;position:sticky;top:-14px}.group-head.svelte-1k3qopq{flex-wrap:wrap;align-items:center;gap:10px;display:flex}.group-ask.svelte-1k3qopq{margin-left:auto}.group-head.svelte-1k3qopq .number:where(.svelte-1k3qopq){color:var(--text-faint);flex-shrink:0;font-size:12px;font-weight:700}.group-head.svelte-1k3qopq h2:where(.svelte-1k3qopq){color:var(--text);text-transform:none;letter-spacing:normal;margin:0;font-size:15px;font-weight:650;line-height:1.3}.kind-chip.svelte-1k3qopq{border:1px solid var(--border);background:var(--bg-card);flex-shrink:0;padding:2px 8px;font-size:11px;font-weight:700}.group-intent.svelte-1k3qopq{color:var(--text-dim);max-width:80ch;margin:0;font-size:12.5px;line-height:1.45}.loose.svelte-1k3qopq .kind-chip:where(.svelte-1k3qopq){color:var(--text-faint)}.file-section.svelte-1k3qopq{border-top:1px solid var(--border)}.file-head.svelte-1k3qopq{border-bottom:1px solid var(--border-soft);align-items:center;display:grid}.file-section.collapsed.svelte-1k3qopq .file-head:where(.svelte-1k3qopq){border-bottom:0}.file-head-main.svelte-1k3qopq{align-items:center;gap:8px;min-width:0;padding:6px 0;display:flex}.file-toggle.svelte-1k3qopq{text-align:left;min-width:0;color:inherit;cursor:pointer;background:0 0;border:0;flex:1;align-items:center;gap:8px;padding:4px 0;display:flex}.file-toggle.svelte-1k3qopq:hover .path:where(.svelte-1k3qopq){color:var(--accent)}.caret.svelte-1k3qopq{width:10px;color:var(--text-faint);flex-shrink:0;font-size:10px}.file-head-gutter.svelte-1k3qopq{flex-shrink:0}.file-head-explain.svelte-1k3qopq{align-items:center;padding:10px 0 10px 14px;display:flex}.path.svelte-1k3qopq{font-family:var(--mono);color:var(--text);text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:12.5px;overflow:hidden}.change-label.svelte-1k3qopq{color:var(--text-faint);flex:1;font-size:11px}.findings-control.svelte-1k3qopq{color:var(--text);background:0 0;border:0;flex-shrink:0;align-items:center;gap:6px;padding:0;display:flex}.count-badge.svelte-1k3qopq{justify-content:center;align-items:center;min-width:18px;height:18px;padding:0 4px;font-size:10.5px;font-weight:700;display:flex}.count-badge.done.svelte-1k3qopq{border:1px solid var(--fix-border);color:var(--ok)}.count-badge.open.svelte-1k3qopq{background:color-mix(in srgb, var(--finding-sev) 22%, transparent);color:var(--finding-sev)}.count-label.svelte-1k3qopq{color:var(--text-faint);font-size:11.5px}.count-label.open.svelte-1k3qopq{color:var(--text-dim)}.arrow.svelte-1k3qopq{color:var(--finding-sev,var(--accent));font-size:14px}.file-grid.svelte-1k3qopq{grid-template-columns:minmax(0,1fr) minmax(260px,320px);display:grid}.file-grid.no-explanations.svelte-1k3qopq{grid-template-columns:minmax(0,1fr)}.diff-col.svelte-1k3qopq{min-width:0}.explain-col.svelte-1k3qopq{border-left:1px solid var(--border-soft);background:var(--bg-elev);flex-direction:column;display:flex;overflow:auto}.explain-row.svelte-1k3qopq{border-bottom:1px solid var(--border-soft);padding:10px 14px}.explain-top.svelte-1k3qopq{align-items:center;gap:8px;margin-bottom:4px;display:flex}.explain-ask.svelte-1k3qopq{margin-left:auto}.lines.svelte-1k3qopq{color:var(--text-faint);font-size:10.5px;font-family:var(--mono)}.op.svelte-1k3qopq{color:var(--text-faint);text-transform:uppercase;letter-spacing:.04em;font-size:10px}.what.svelte-1k3qopq{color:var(--text);max-width:80ch;margin:0 0 3px;font-size:13px;line-height:1.4}.why.svelte-1k3qopq{color:var(--text-dim);max-width:80ch;margin:0;font-size:11.5px;line-height:1.4}.orphans.svelte-1k3qopq,.skipped.svelte-1k3qopq{border-top:1px solid var(--border-soft);padding-top:12px}.orphan-list.svelte-1k3qopq{flex-direction:column;gap:6px;display:flex}.orphan-row.svelte-1k3qopq{background:var(--bg-elev);border-left:2px solid #0000;align-items:baseline;gap:10px;padding:6px 10px;display:flex}.orphan-row.svelte-1k3qopq .badge:where(.svelte-1k3qopq){flex-shrink:0;font-size:10px;font-weight:700}.orphan-row.svelte-1k3qopq .what:where(.svelte-1k3qopq){flex:1;margin:0;font-size:12.5px}.orphan-row.svelte-1k3qopq .where:where(.svelte-1k3qopq){font-family:var(--mono);color:var(--text-faint);font-size:10.5px}.skipped-list.svelte-1k3qopq{flex-wrap:wrap;gap:6px;display:flex}.skipped-chip.svelte-1k3qopq{font-size:11px;font-family:var(--mono);color:var(--text-faint);border:1px solid var(--border);padding:4px 8px}.prompt-box.svelte-1dm34m1{border:1px solid var(--fix-border);background:var(--fix-bg);flex-direction:column;gap:10px;padding:14px 16px;display:flex}.prompt-box.publish.svelte-1dm34m1{border-color:var(--publish-border);background:var(--publish-bg)}.prompt-head.svelte-1dm34m1{justify-content:space-between;align-items:center;display:flex}.fix-title.svelte-1dm34m1{letter-spacing:.07em;text-transform:uppercase;color:var(--fix-text);margin:0;font-size:12px;font-weight:650}.publish-title.svelte-1dm34m1{letter-spacing:.07em;text-transform:uppercase;color:var(--publish-text);margin:0;font-size:12px;font-weight:650}.close.svelte-1dm34m1{color:var(--text-faint);background:0 0;border:0;padding:0;font-size:12px}.mode-toggle.svelte-1dm34m1{border:1px solid var(--border);width:fit-content;display:flex;overflow:hidden}.mode-toggle.svelte-1dm34m1 button:where(.svelte-1dm34m1){color:var(--text);background:0 0;border:0;padding:6px 12px;font-size:12px}.mode-toggle.svelte-1dm34m1 button:where(.svelte-1dm34m1)+button:where(.svelte-1dm34m1){border-left:1px solid var(--border)}.mode-toggle.svelte-1dm34m1 button.on:where(.svelte-1dm34m1){background:var(--accent-soft)}textarea.svelte-1dm34m1{resize:vertical;background:var(--bg);border:1px solid var(--border);width:100%;height:220px;font-family:var(--mono);color:var(--text);padding:12px;font-size:12px;line-height:1.5}.hint.svelte-1dm34m1{color:var(--text-faint);margin:0;font-size:11.5px}.copy.svelte-1dm34m1{background:var(--btn-primary-bg);border:1px solid var(--btn-primary-border);color:var(--btn-primary-text);padding:9px 14px;font-size:13px;font-weight:600}.detail-panel.svelte-1dm34m1{border:1px solid var(--border);background:var(--bg-card);flex-direction:column;flex:1;min-width:0;min-height:0;display:flex;overflow:hidden}.detail-head.svelte-1dm34m1{border-bottom:1px solid var(--border-soft);background:var(--bg-elev);flex-shrink:0;justify-content:space-between;align-items:center;gap:12px;padding:10px 16px;display:flex}.detail-head-left.svelte-1dm34m1{align-items:center;gap:8px;display:flex}.number.svelte-1dm34m1{color:var(--text);font-size:12px;font-weight:700}.badge.svelte-1dm34m1{font-size:10px;font-weight:700}.file-line.svelte-1dm34m1{min-width:0;font-family:var(--mono);align-items:baseline;gap:8px;display:flex}.file-name.svelte-1dm34m1{color:var(--text);flex-shrink:0;font-size:12px;font-weight:600}.file-dir.svelte-1dm34m1{color:var(--text-faint);text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:11px;overflow:hidden}.head-actions.svelte-1dm34m1{flex-shrink:0;align-items:center;gap:8px;display:flex}.decision-group.svelte-1dm34m1{border:1px solid var(--border);flex-shrink:0;display:flex;overflow:hidden}.decision-group.svelte-1dm34m1 button:where(.svelte-1dm34m1){color:var(--text-dim);background:0 0;border:0;padding:6px 14px;font-size:12px;font-weight:600}.decision-group.svelte-1dm34m1 button:first-child.on:where(.svelte-1dm34m1){background:var(--danger-bg);color:var(--danger)}.decision-group.svelte-1dm34m1 button:nth-child(2).on:where(.svelte-1dm34m1){background:var(--fix-bg);color:var(--ok)}.decision-group.svelte-1dm34m1 button:where(.svelte-1dm34m1)+button:where(.svelte-1dm34m1){border-left:1px solid var(--border)}.decision-group.svelte-1dm34m1 .clear:where(.svelte-1dm34m1){color:var(--text-faint);padding:6px 10px}.detail-grid.svelte-1dm34m1{flex:1;grid-template-columns:minmax(0,1fr) minmax(260px,320px);min-height:0;display:grid}.detail-grid.no-explanations.svelte-1dm34m1{grid-template-columns:minmax(0,1fr)}.diff-col.svelte-1dm34m1{flex-direction:column;min-width:0;display:flex;overflow:hidden auto}.file-path-bar.svelte-1dm34m1{border-bottom:1px solid var(--border-soft);background:var(--bg-elev);flex-shrink:0;align-items:center;gap:8px;min-width:0;padding:8px 14px;display:flex}.file-path-text.svelte-1dm34m1{font-family:var(--mono);color:var(--text-faint);text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:11px;overflow:hidden}.explain-col.svelte-1dm34m1{border-left:1px solid var(--border-soft);background:var(--bg-elev);flex-direction:column;gap:16px;padding:14px 16px;display:flex;overflow:auto}.explain-counter.svelte-1dm34m1{color:var(--text-dim);border:1px solid var(--border);background:var(--bg-card);align-self:flex-start;padding:3px 8px;font-size:10.5px;font-weight:650}.explain-col.svelte-1dm34m1 h3:where(.svelte-1dm34m1){letter-spacing:.06em;text-transform:uppercase;color:var(--text-faint);margin:0 0 4px;font-size:10.5px;font-weight:650}.explain-col.svelte-1dm34m1 .what:where(.svelte-1dm34m1){color:var(--text);margin:0;font-size:13px;line-height:1.45}.explain-col.svelte-1dm34m1 .fix:where(.svelte-1dm34m1){color:var(--text-dim);margin:0;font-size:13px;line-height:1.45}.backdrop.svelte-lfje9j{z-index:9;background:#00000059;position:fixed;inset:0}.drawer.svelte-lfje9j{background:var(--bg-card);border-left:1px solid var(--border);z-index:10;flex-direction:column;width:420px;transition:transform .2s;display:flex;position:fixed;top:0;bottom:0;right:0;transform:translate(100%)}.drawer.open.svelte-lfje9j{transform:translate(0)}.drawer-head.svelte-lfje9j{border-bottom:1px solid var(--border-soft);flex-shrink:0;justify-content:space-between;align-items:center;gap:8px;min-width:0;padding:12px 14px;display:flex}.drawer-title.svelte-lfje9j{flex:1;align-items:center;gap:8px;min-width:0;display:flex}.file-ref.svelte-lfje9j{align-items:baseline;gap:8px;min-width:0;display:flex;overflow:hidden}.name.svelte-lfje9j{color:var(--text);font-size:13px;font-weight:600;font-family:var(--mono);flex-shrink:0}.dir.svelte-lfje9j{color:var(--text-faint);font-size:11px;font-family:var(--mono);text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.close.svelte-lfje9j{color:var(--text-faint);background:0 0;border:0;flex-shrink:0;padding:0;font-size:14px}.list.svelte-lfje9j{flex-direction:column;display:flex;overflow:auto}.item.svelte-lfje9j{border-bottom:1px solid var(--border-soft)}.item-head.svelte-lfje9j{text-align:left;background:0 0;border:0;border-left:2px solid #0000;align-items:center;gap:8px;width:100%;padding:10px 14px;display:flex}.status.svelte-lfje9j{border:1px solid #0000;flex-shrink:0;justify-content:center;align-items:center;width:14px;height:14px;font-size:10px;line-height:1;display:flex}.badge.svelte-lfje9j{flex-shrink:0;font-size:10px;font-weight:700}.what.svelte-lfje9j{color:var(--text);text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-size:12.5px;overflow:hidden}.chevron.svelte-lfje9j{color:var(--text-faint);flex-shrink:0;font-size:11px}.item-body.svelte-lfje9j{flex-direction:column;gap:14px;padding:0 14px 14px 20px;display:flex}.item-body.svelte-lfje9j h4:where(.svelte-lfje9j){letter-spacing:.06em;text-transform:uppercase;color:var(--text-faint);margin:0 0 4px;font-size:10px;font-weight:650}.item-body.svelte-lfje9j p:where(.svelte-lfje9j){color:var(--text);margin:0;font-size:13px;line-height:1.5}.item-body.svelte-lfje9j p.fix:where(.svelte-lfje9j){color:var(--text-dim)}.item-actions.svelte-lfje9j{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.decision-group.svelte-lfje9j{border:1px solid var(--border);width:fit-content;display:flex;overflow:hidden}.decision-group.svelte-lfje9j button:where(.svelte-lfje9j){color:var(--text-dim);background:0 0;border:0;padding:7px 14px;font-size:12px;font-weight:600}.decision-group.svelte-lfje9j button:first-child.on:where(.svelte-lfje9j){background:var(--danger-bg);color:var(--danger)}.decision-group.svelte-lfje9j button:nth-child(2).on:where(.svelte-lfje9j){background:var(--fix-bg);color:var(--ok)}.decision-group.svelte-lfje9j button:where(.svelte-lfje9j)+button:where(.svelte-lfje9j){border-left:1px solid var(--border)}.decision-group.svelte-lfje9j .clear:where(.svelte-lfje9j){color:var(--text-faint);padding:7px 10px}.footer.svelte-67e2dl{border-top:1px solid var(--border);background:var(--bg-elev);flex-shrink:0;justify-content:space-between;align-items:center;gap:12px;min-height:33px;padding:6px 16px;display:flex}.right.svelte-67e2dl{align-items:center;gap:12px;display:flex}.reviewed.svelte-67e2dl{color:var(--text-faint);font-size:11px}.fix.svelte-67e2dl,.publish.svelte-67e2dl{border:1px solid;padding:6px 12px;font-size:11.5px;font-weight:600}.fix.svelte-67e2dl{background:var(--fix-bg);border-color:var(--fix-border);color:var(--ok)}.publish.svelte-67e2dl{background:var(--publish-bg);border-color:var(--publish-border);color:var(--publish-text)}.sidebar.svelte-xengl2{border-right:1px solid var(--border);background:var(--bg-elev);flex-direction:column;height:100%;min-height:0;padding:14px 0;display:flex;overflow:hidden}.sidebar.collapsed.svelte-xengl2{border-right:0}.mode-toggle.svelte-xengl2{border:1px solid var(--border);flex-shrink:0;margin:0 14px 12px;display:flex;overflow:hidden}.mode-toggle.svelte-xengl2 button:where(.svelte-xengl2){color:var(--text);background:0 0;border:0;flex:1;justify-content:center;align-items:center;gap:6px;padding:7px 8px;font-size:12px;display:flex}.mode-toggle.svelte-xengl2 button:where(.svelte-xengl2)+button:where(.svelte-xengl2){border-left:1px solid var(--border)}.mode-toggle.svelte-xengl2 button.on:where(.svelte-xengl2){background:var(--accent-soft)}.mode-label.svelte-xengl2{align-items:center;gap:6px;line-height:1;display:inline-flex}.count-badge.svelte-xengl2{font-family:var(--mono);border:1px solid color-mix(in srgb, var(--finding-sev,var(--border)) 45%, transparent);background:color-mix(in srgb, var(--finding-sev,var(--bg-card)) 18%, transparent);color:var(--finding-sev,var(--text-dim));justify-content:center;align-items:center;padding:2px 6px;font-size:10px;font-weight:700;line-height:1;display:inline-flex}.panel.svelte-xengl2{padding:0 14px 10px}.explore-panel.svelte-xengl2{flex-direction:column;flex:1;min-height:0;padding:0 0 10px;display:flex;overflow:hidden}.panel-chrome.svelte-xengl2{flex-shrink:0;padding:0 14px}.panel-scroll.svelte-xengl2{flex:1;min-height:0;padding:0 14px;overflow:hidden auto}h3.svelte-xengl2{letter-spacing:.06em;text-transform:uppercase;color:var(--text-faint);margin:0 0 8px;font-size:11.5px;font-weight:650}.index-tabs.svelte-xengl2{border-bottom:1px solid var(--border-soft);gap:12px;margin-bottom:8px;display:flex}.index-tabs.svelte-xengl2 button:where(.svelte-xengl2){letter-spacing:.06em;text-transform:uppercase;color:var(--text-faint);background:0 0;border:0;border-bottom:2px solid #0000;padding:0 0 6px;font-size:11.5px;font-weight:650}.index-tabs.svelte-xengl2 button.on:where(.svelte-xengl2){color:var(--text);border-bottom-color:var(--accent)}.files-toolbar.svelte-xengl2{justify-content:space-between;align-items:center;gap:6px;margin:-2px 0 8px;display:flex}.files-toolbar.svelte-xengl2 .tool:where(.svelte-xengl2){border:1px solid var(--border);background:var(--bg-card);width:26px;height:26px;color:var(--text-dim);justify-content:center;align-items:center;padding:0;display:inline-flex}.files-toolbar.svelte-xengl2 .tool:where(.svelte-xengl2):hover:not(:disabled){color:var(--text);border-color:var(--text-faint)}.files-toolbar.svelte-xengl2 .tool.on:where(.svelte-xengl2){background:var(--accent-soft);border-color:var(--border);color:var(--text)}.files-toolbar.svelte-xengl2 .tool:where(.svelte-xengl2):disabled{opacity:.35;cursor:default}.files-toolbar.svelte-xengl2 .tool-icon:where(.svelte-xengl2){width:14px;height:14px;display:block}.files-toolbar.svelte-xengl2 .seg:where(.svelte-xengl2){border:1px solid var(--border);display:flex;overflow:hidden}.files-toolbar.svelte-xengl2 .seg:where(.svelte-xengl2) .tool:where(.svelte-xengl2){background:0 0;border:0;border-radius:0}.files-toolbar.svelte-xengl2 .seg:where(.svelte-xengl2) .tool:where(.svelte-xengl2)+.tool:where(.svelte-xengl2){border-left:1px solid var(--border)}.files-toolbar.svelte-xengl2 .seg:where(.svelte-xengl2) .tool.on:where(.svelte-xengl2){background:var(--accent-soft)}.nav-list.svelte-xengl2{flex-direction:column;gap:2px;display:flex}.tree.svelte-xengl2{flex-direction:column;display:flex}.tree-row.svelte-xengl2{text-align:left;width:100%;color:var(--text);background:0 0;border:0;align-items:center;gap:4px;min-width:0;padding:2px 6px 2px 0;font-size:12px;display:flex;position:relative}.tree-row.svelte-xengl2:hover:not(:disabled){background:var(--bg-card)}.tree-row.dir.svelte-xengl2{color:var(--text-dim)}.tree-row.muted.svelte-xengl2{color:var(--text-faint);cursor:default}.tree-row.skipped.svelte-xengl2 .name:where(.svelte-xengl2){text-decoration:line-through;-webkit-text-decoration-color:var(--text-faint);text-decoration-color:var(--text-faint)}.tree-guides.svelte-xengl2{pointer-events:none;width:0;position:absolute;inset:0 auto 0 0}.tree-guide.svelte-xengl2{background:var(--border-soft);opacity:.9;width:1px;position:absolute;top:0;bottom:0}.tree-slot.svelte-xengl2{flex-shrink:0;justify-content:center;align-items:center;width:16px;height:16px;display:inline-flex}.caret.svelte-xengl2{color:var(--text-faint);font-size:10px;line-height:1}.mark.svelte-xengl2{width:9px;font-family:var(--mono);color:var(--text-faint);flex-shrink:0;font-size:9.5px;font-weight:700}.mark.add.svelte-xengl2{color:var(--diff-add-fg)}.mark.del.svelte-xengl2{color:var(--diff-del-fg)}.tree-row.svelte-xengl2 .name:where(.svelte-xengl2){text-overflow:ellipsis;white-space:nowrap;min-width:0;font-family:var(--mono);flex:1;font-size:11.5px;overflow:hidden}.tree-row.svelte-xengl2 .name-line:where(.svelte-xengl2){flex:1;align-items:baseline;gap:6px;min-width:0;display:flex;overflow:hidden}.tree-row.svelte-xengl2 .name-line:where(.svelte-xengl2) .name:where(.svelte-xengl2){text-overflow:ellipsis;flex:0 auto;overflow:hidden}.tree-row.svelte-xengl2 .name-line:where(.svelte-xengl2) .dir:where(.svelte-xengl2){text-overflow:ellipsis;white-space:nowrap;min-width:0;font-family:var(--mono);color:var(--text-faint);flex:1;font-size:10.5px;overflow:hidden}.tree-row.svelte-xengl2 .count:where(.svelte-xengl2),.group-link.svelte-xengl2 .count:where(.svelte-xengl2){color:var(--finding-sev,var(--danger));border:1px solid color-mix(in srgb, var(--finding-sev,var(--danger-border)) 55%, transparent);flex-shrink:0;padding:2px 5px;font-size:9.5px;font-weight:700;line-height:1}.tree-row.svelte-xengl2 .count.done:where(.svelte-xengl2),.group-link.svelte-xengl2 .count.done:where(.svelte-xengl2){color:var(--ok);border-color:var(--border)}.group-link.svelte-xengl2{min-width:0;color:var(--text);flex-direction:column;flex:1;gap:2px;padding:6px 8px 6px 0;font-size:12.5px;text-decoration:none;display:flex}.group-link.svelte-xengl2:hover{background:0 0}.group-item.svelte-xengl2{border-radius:0}.group-item.open.svelte-xengl2>.group-head-row:where(.svelte-xengl2){background:var(--bg-card)}.group-head-row.svelte-xengl2{align-items:flex-start;gap:0;display:flex}.group-head-row.svelte-xengl2:hover{background:var(--bg-card)}.group-caret.svelte-xengl2{width:20px;color:var(--text-faint);cursor:pointer;background:0 0;border:0;flex-shrink:0;justify-content:center;align-items:center;padding:8px 0 0;display:inline-flex}.group-caret.svelte-xengl2:hover{color:var(--text)}.group-files.svelte-xengl2{flex-direction:column;padding:0 0 4px 8px;display:flex}.row.svelte-xengl2{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.group-link.svelte-xengl2 .number:where(.svelte-xengl2){color:var(--text-faint);flex-shrink:0;font-size:10px;font-weight:700}.kind-chip.svelte-xengl2{border:1px solid var(--border);background:var(--bg-card);flex-shrink:0;padding:1px 5px;font-size:10px;font-weight:700}.group-link.svelte-xengl2 .title:where(.svelte-xengl2){white-space:normal;overflow-wrap:anywhere;line-height:1.35;display:block}.group-link.svelte-xengl2 .row:where(.svelte-xengl2)>.count:where(.svelte-xengl2){margin-left:auto}.meta.svelte-xengl2{color:var(--text-faint);padding-left:0;font-size:11px}.group-files.svelte-xengl2 .tree-row.file.active:where(.svelte-xengl2){background:var(--accent-soft)}.findings-panel.svelte-xengl2{flex-direction:column;flex:1;min-height:0;display:flex;overflow:hidden}.findings-head.svelte-xengl2{justify-content:space-between;align-items:baseline;margin-bottom:8px;display:flex}.findings-head.svelte-xengl2 h3:where(.svelte-xengl2){margin:0}.reviewed.svelte-xengl2{color:var(--text-faint);font-size:10.5px}.progress.svelte-xengl2{background:var(--border-soft);flex-shrink:0;height:3px;margin-bottom:10px;overflow:hidden}.progress-bar.svelte-xengl2{background:var(--accent);height:100%}.findings-list.svelte-xengl2{flex-direction:column;flex:1;gap:4px;min-height:0;display:flex;overflow:hidden auto}.finding-row.svelte-xengl2{text-align:left;border:0;border-bottom:1px solid var(--border-soft);background:var(--bg-elev);border-left:2px solid #0000;flex-direction:column;width:100%;min-width:0;padding:8px 10px;display:flex}.finding-row.active.svelte-xengl2{background:var(--accent-soft)}.finding-row.svelte-xengl2 .top:where(.svelte-xengl2){flex-wrap:wrap;justify-content:space-between;align-items:center;gap:4px 6px;margin-bottom:3px;display:flex}.finding-row.svelte-xengl2 .left:where(.svelte-xengl2){flex-wrap:wrap;align-items:center;gap:4px 6px;min-width:0;display:flex}.status.svelte-xengl2{border:1px solid #0000;flex-shrink:0;justify-content:center;align-items:center;width:14px;height:14px;font-size:10px;line-height:1;display:flex}.number.svelte-xengl2{color:var(--text-faint);font-size:9.5px;font-weight:650}.badge.svelte-xengl2{font-size:9.5px;font-weight:700}.decision.svelte-xengl2{font-size:9.5px;font-weight:650}.what.svelte-xengl2{color:var(--text);overflow-wrap:anywhere;font-size:12.5px;line-height:1.35;display:block}.file-line.svelte-xengl2{color:var(--text-faint);font-size:10.5px;font-family:var(--mono);overflow-wrap:anywhere;margin-top:3px;display:block}.report-shell.svelte-1ipe5j3{flex-direction:column;flex:1;min-height:0;display:flex}.report.svelte-1ipe5j3{flex:1;min-height:0;display:grid}.content.svelte-1ipe5j3{flex-direction:column;gap:18px;min-height:0;padding:14px 20px 24px;display:flex;overflow:auto}.page.svelte-67dwv3{background:var(--bg);flex-direction:column;height:100vh;min-height:0;display:flex}.body.svelte-67dwv3{flex:1;min-height:0;display:flex}.body.svelte-67dwv3>.report-shell{flex:1;min-width:0}.ghost.on.svelte-67dwv3{background:var(--accent-soft);border-color:var(--accent)}.chrome.svelte-67dwv3{border-bottom:1px solid var(--border);background:var(--header-bg);flex-shrink:0;grid-template-columns:1fr auto 1fr;align-items:center;gap:16px;padding:12px 28px;display:grid}.chrome-left.svelte-67dwv3{justify-self:start;align-items:center;gap:12px;min-width:0;display:flex}.chrome-center.svelte-67dwv3{justify-self:center;align-items:center;gap:10px;display:flex}.chrome-right.svelte-67dwv3{justify-self:end;align-items:center;gap:10px;display:flex}.brand.svelte-67dwv3{color:var(--text);flex-shrink:0;align-items:center;gap:10px;font-size:15px;font-weight:700;text-decoration:none;display:flex}.brand-dot.svelte-67dwv3{background:linear-gradient(135deg,#6ea8fe,#c9a5ff);border-radius:50%;flex-shrink:0;width:9px;height:9px;box-shadow:0 0 12px #6ea8fe88}.chrome-divider.svelte-67dwv3{background:var(--border);flex-shrink:0;width:1px;height:18px}.breadcrumb.svelte-67dwv3{font-family:var(--mono);align-items:center;gap:6px;min-width:0;font-size:12.5px;display:flex}.crumb-branch.svelte-67dwv3{color:var(--text);text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.crumb-sep.svelte-67dwv3{color:var(--text-faint)}.crumb-base.svelte-67dwv3{color:var(--text-faint);white-space:nowrap}.provenance.svelte-67dwv3{min-width:0;color:var(--text-dim);align-items:center;gap:6px;font-size:12px;display:flex}.prov-agent.svelte-67dwv3{white-space:nowrap}.prov-sep.svelte-67dwv3{color:var(--text-faint)}.prov-model.svelte-67dwv3{font-family:var(--mono);text-overflow:ellipsis;white-space:nowrap;font-size:11.5px;overflow:hidden}.menu-wrap.svelte-67dwv3{flex-shrink:0;position:relative}.menu.svelte-67dwv3{z-index:40;border:1px solid var(--border);background:var(--bg-card);min-width:180px;padding:4px;position:absolute;top:calc(100% + 4px);left:0;box-shadow:0 8px 24px #0000002e}.download-menu.svelte-67dwv3{flex-direction:column;gap:0;min-width:220px;padding:4px;display:flex;left:auto;right:0}.menu-item.svelte-67dwv3{width:100%;color:var(--text);text-align:left;cursor:pointer;background:0 0;border:0;flex-direction:column;align-items:flex-start;gap:0;padding:4px 8px;font-size:12px;line-height:1.25;display:flex}.download-menu.svelte-67dwv3 button.menu-item:where(.svelte-67dwv3){box-sizing:border-box;z-index:0;height:44px;min-height:44px;color:var(--text);font:inherit;letter-spacing:normal;text-align:left;cursor:pointer;appearance:none;background:0 0;border:0;border-radius:2px;flex-direction:row;justify-content:space-between;align-items:center;gap:8px;margin:0;padding:0 10px;font-size:12px;font-weight:400;line-height:1.2;display:flex;position:relative;overflow:hidden}.download-menu.svelte-67dwv3 button.menu-item:where(.svelte-67dwv3):hover{z-index:1;background:var(--accent-soft)}.menu-item.svelte-67dwv3:hover{background:var(--accent-soft)}.menu-item.danger.svelte-67dwv3{color:var(--danger)}.menu-item.svelte-67dwv3 .fmt:where(.svelte-67dwv3){flex-shrink:0;font-weight:600;line-height:1.2}.menu-item.svelte-67dwv3 .hint:where(.svelte-67dwv3){color:var(--text-faint);font-size:10.5px;line-height:1.2}.download-menu.svelte-67dwv3 .menu-item:where(.svelte-67dwv3) .fmt:where(.svelte-67dwv3),.download-menu.svelte-67dwv3 .menu-item:where(.svelte-67dwv3) .hint:where(.svelte-67dwv3){pointer-events:none}.download-menu.svelte-67dwv3 .menu-item:where(.svelte-67dwv3) .hint:where(.svelte-67dwv3){text-align:right;white-space:nowrap;text-overflow:ellipsis;min-width:0;font-size:10px;overflow:hidden}.mode-toggle.svelte-67dwv3{border:1px solid var(--border);display:flex;overflow:hidden}.mode-toggle.svelte-67dwv3 button:where(.svelte-67dwv3){white-space:nowrap;color:var(--text);background:0 0;border:0;padding:6px 12px;font-size:12px}.mode-toggle.svelte-67dwv3 button:where(.svelte-67dwv3)+button:where(.svelte-67dwv3){border-left:1px solid var(--border)}.mode-toggle.svelte-67dwv3 button.on:where(.svelte-67dwv3){background:var(--accent-soft)}.zoom.svelte-67dwv3{align-items:center;gap:4px;display:flex}.icon-btn.svelte-67dwv3{background:var(--bg-card);border:1px solid var(--border);width:26px;height:26px;color:var(--text-dim);justify-content:center;align-items:center;padding:0;font-size:13px;display:flex}.icon-btn.svelte-67dwv3:hover{border-color:var(--accent);color:var(--text)}.icon-btn.on.svelte-67dwv3{background:var(--accent-soft);border-color:var(--accent);color:var(--text)}.icon-btn.kebab.svelte-67dwv3{background:0 0;border-color:#0000;width:24px;height:24px}.icon-btn.kebab.svelte-67dwv3:hover{border-color:var(--border);background:var(--bg-card)}.icon-btn.panel.svelte-67dwv3{font-size:15px}.icon-btn.svelte-67dwv3:disabled{opacity:.4;cursor:not-allowed}.zoom-label.svelte-67dwv3{font-family:var(--mono);color:var(--text-faint);text-align:center;width:30px;font-size:10.5px}.ghost.svelte-67dwv3{background:var(--bg-card);border:1px solid var(--border);color:var(--text);padding:7px 12px;font-size:12.5px}.agent-btn.svelte-67dwv3,.download-btn.svelte-67dwv3{align-items:center;gap:6px;display:inline-flex}.download-btn.svelte-67dwv3 .caret:where(.svelte-67dwv3){opacity:.7}.hint.svelte-67dwv3{color:var(--text-faint);padding:40px 28px;font-size:13px}
@@ -0,0 +1 @@
1
+ .agent-icon.svelte-1o6iyhy{flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}.agent-icon.svelte-1o6iyhy svg:where(.svelte-1o6iyhy){width:100%;height:100%;display:block}.agent-select.svelte-grhxa3{flex:1;width:100%;min-width:0;position:relative}.trigger.svelte-grhxa3{box-sizing:border-box;background:var(--bg-card);border:1px solid var(--border);width:100%;min-width:0;min-height:38px;color:var(--text);font:inherit;font-size:inherit;text-align:left;cursor:pointer;align-items:center;gap:8px;padding:9px 12px;display:flex}.trigger.svelte-grhxa3:hover:not(:disabled){border-color:var(--accent)}.trigger.svelte-grhxa3:disabled{opacity:.5;cursor:not-allowed}.label.svelte-grhxa3{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.label.muted.svelte-grhxa3{color:var(--text-faint)}.caret.svelte-grhxa3{opacity:.7;color:var(--text-dim);flex-shrink:0}.agent-select.open.svelte-grhxa3 .caret:where(.svelte-grhxa3){transform:rotate(180deg)}.menu.svelte-grhxa3{z-index:40;border:1px solid var(--border);background:var(--bg-card);flex-direction:column;gap:0;padding:4px;display:flex;position:absolute;top:calc(100% + 4px);left:0;right:0;box-shadow:0 8px 24px #0000002e}.option.svelte-grhxa3{width:100%;color:var(--text);font:inherit;font-size:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:2px;align-items:center;gap:8px;padding:8px 10px;display:flex}.option.svelte-grhxa3:hover,.option.selected.svelte-grhxa3{background:var(--accent-soft)}.theme-toggle.svelte-lu0t34{background:var(--bg-card);border:1px solid var(--border);width:30px;height:30px;color:var(--text-dim);flex-shrink:0;justify-content:center;align-items:center;padding:0;font-size:14px;display:flex}.theme-toggle.svelte-lu0t34:hover{border-color:var(--accent);color:var(--text)}.md.svelte-cxb0dt{color:var(--text);overflow-wrap:anywhere}.md.svelte-cxb0dt>:first-child{margin-top:0}.md.svelte-cxb0dt>:last-child{margin-bottom:0}.md.svelte-cxb0dt p,.md.svelte-cxb0dt ul,.md.svelte-cxb0dt ol,.md.svelte-cxb0dt pre,.md.svelte-cxb0dt blockquote{margin:.45em 0}.md.svelte-cxb0dt ul,.md.svelte-cxb0dt ol{padding-left:1.35em}.md.svelte-cxb0dt li{margin:.15em 0}.md.svelte-cxb0dt h1,.md.svelte-cxb0dt h2,.md.svelte-cxb0dt h3,.md.svelte-cxb0dt h4{margin:.7em 0 .35em;font-size:1em;font-weight:650;line-height:1.35}.md.svelte-cxb0dt h1{font-size:1.15em}.md.svelte-cxb0dt h2{font-size:1.08em}.md.svelte-cxb0dt a{color:var(--accent)}.md.svelte-cxb0dt code{font-family:var(--mono);background:var(--bg-card);border:1px solid var(--border-soft,var(--border));border-radius:4px;padding:.1em .35em;font-size:.92em}.md.svelte-cxb0dt pre{background:var(--bg-card);border:1px solid var(--border);border-radius:6px;padding:8px 10px;overflow-x:auto}.md.svelte-cxb0dt pre code{background:0 0;border:none;padding:0;font-size:12px;line-height:1.45}.md.svelte-cxb0dt blockquote{border-left:3px solid var(--border);color:var(--text-dim);padding-left:10px}.md.svelte-cxb0dt hr{border:none;border-top:1px solid var(--border);margin:.75em 0}.md.svelte-cxb0dt table{border-collapse:collapse;width:100%;font-size:12.5px}.md.svelte-cxb0dt th,.md.svelte-cxb0dt td{border:1px solid var(--border);text-align:left;padding:4px 8px}.md.svelte-cxb0dt th{background:var(--bg-card);font-weight:600}.perm-actions.svelte-1l4yk48{flex-wrap:wrap;gap:8px;display:flex}.perm-actions.svelte-1l4yk48 button:where(.svelte-1l4yk48){border:1px solid var(--border);background:var(--bg-elev);color:var(--text);border-radius:0;padding:5px 10px;font-size:12px}.perm-actions.svelte-1l4yk48 .allow:where(.svelte-1l4yk48),.perm-actions.svelte-1l4yk48 .allow-all:where(.svelte-1l4yk48){background:var(--ok-bg);border-color:var(--ok);color:var(--ok)}.perm-actions.svelte-1l4yk48 .deny:where(.svelte-1l4yk48),.perm-actions.svelte-1l4yk48 .deny-all:where(.svelte-1l4yk48){background:var(--danger-bg);border-color:var(--danger-border);color:var(--danger)}.log.svelte-18syxl5{flex-direction:column;gap:6px;min-height:0;font-size:13px;line-height:1.45;display:flex;overflow-y:auto}p.svelte-18syxl5{white-space:pre-wrap;overflow-wrap:anywhere;margin:0}.user.svelte-18syxl5{background:var(--accent-soft);border:1px solid var(--btn-primary-border);border-radius:0;align-self:flex-end;max-width:90%;padding:6px 10px}.tag.svelte-18syxl5{text-transform:uppercase;letter-spacing:.06em;color:var(--text-faint);font-size:10px;display:block}.message.svelte-18syxl5{color:var(--text);max-width:100%}.thought.svelte-18syxl5{color:var(--text-faint);font-size:12px}.thought.svelte-18syxl5 summary:where(.svelte-18syxl5){cursor:pointer;font-style:italic}.thought.svelte-18syxl5 p:where(.svelte-18syxl5){max-height:200px;margin-top:4px;overflow-y:auto}.tool.svelte-18syxl5{font-family:var(--mono);color:var(--text-dim);gap:6px;font-size:12px;display:flex}.tool.svelte-18syxl5 .mark:where(.svelte-18syxl5){width:12px;color:var(--ok);flex:none}.tool.failed.svelte-18syxl5 .mark:where(.svelte-18syxl5),.tool.failed.svelte-18syxl5 .title:where(.svelte-18syxl5){color:var(--danger)}.tool.svelte-18syxl5 .title:where(.svelte-18syxl5){text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.permission.svelte-18syxl5{color:var(--warn);font-size:12px}.permission.allowed.svelte-18syxl5{color:var(--ok)}.permission.pending.svelte-18syxl5{border:1px solid var(--warn);background:var(--bg-card);color:var(--text);border-radius:0;padding:8px 10px}.perm-head.svelte-18syxl5{text-transform:uppercase;letter-spacing:.05em;color:var(--warn);flex-wrap:wrap;align-items:center;gap:8px;font-size:11px;display:flex}.perm-head.svelte-18syxl5 .kind:where(.svelte-18syxl5){color:var(--text-faint);font-family:var(--mono);text-transform:none;letter-spacing:0}.perm-head.svelte-18syxl5 .counter:where(.svelte-18syxl5){font-variant-numeric:tabular-nums;color:var(--text-dim);text-transform:none;letter-spacing:0;font-family:var(--mono);margin-left:auto}.perm-head.svelte-18syxl5 .nav:where(.svelte-18syxl5){gap:2px;display:flex}.nav-btn.svelte-18syxl5{border:1px solid var(--border);background:var(--bg-elev);color:var(--text-dim);border-radius:0;padding:2px 6px;font-size:11px;line-height:1.2}.perm-subtitle.svelte-18syxl5{color:var(--text-faint);margin:4px 0 0;font-size:11.5px}.perm-title.svelte-18syxl5{font-family:var(--mono);margin:4px 0 0;font-size:12px}.perm-command.svelte-18syxl5{font-family:var(--mono);white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word;background:var(--bg-elev);border:1px solid var(--border);border-radius:0;max-width:100%;margin:6px 0 0;padding:8px 10px;font-size:11.5px;line-height:1.4}.perm-command.collapsed.svelte-18syxl5{max-height:10.5em;overflow:hidden}.perm-expand.svelte-18syxl5{color:var(--accent);cursor:pointer;background:0 0;border:none;border-radius:0;margin:4px 0 0;padding:0;font-size:11.5px;text-decoration:underline}.perm-expand.svelte-18syxl5:hover{color:var(--text)}.perm-reason.svelte-18syxl5{color:var(--text-faint);margin:2px 0 0;font-size:11.5px}.permission.pending.svelte-18syxl5 .perm-actions{margin-top:8px}.permission.svelte-18syxl5 span:where(.svelte-18syxl5){color:var(--text-faint)}.plan.svelte-18syxl5{color:var(--text-dim);margin:0;padding-left:18px;font-size:12px}.plan.svelte-18syxl5 li.done:where(.svelte-18syxl5){color:var(--text-faint);text-decoration:line-through}.review.svelte-18syxl5{border-radius:0;padding:6px 10px;font-size:12px}.review.ok.svelte-18syxl5{background:var(--ok-bg);color:var(--ok)}.review.bad.svelte-18syxl5 .retry:where(.svelte-18syxl5){border:1px solid var(--danger-border);background:var(--bg-elev);color:var(--text);cursor:pointer;border-radius:0;margin-top:8px;padding:5px 12px;font-size:12px}.review.bad.svelte-18syxl5 .retry:where(.svelte-18syxl5):hover:not(:disabled){border-color:var(--accent)}.review.bad.svelte-18syxl5 .retry:where(.svelte-18syxl5):disabled{opacity:.55;cursor:default}.review.bad.svelte-18syxl5,.error.svelte-18syxl5{background:var(--danger-bg);border:1px solid var(--danger-border);color:var(--danger);border-radius:0;padding:6px 10px;font-size:12px}.review.svelte-18syxl5 ul:where(.svelte-18syxl5){margin:4px 0 0;padding-left:16px}.note.svelte-18syxl5{color:var(--text-faint);font-size:12px}.working.svelte-18syxl5{gap:4px;padding:4px 0;display:flex}.working.svelte-18syxl5 span:where(.svelte-18syxl5){background:var(--text-faint);border-radius:50%;width:6px;height:6px;animation:1.2s ease-in-out infinite svelte-18syxl5-blink}.working.svelte-18syxl5 span:where(.svelte-18syxl5):nth-child(2){animation-delay:.2s}.working.svelte-18syxl5 span:where(.svelte-18syxl5):nth-child(3){animation-delay:.4s}@keyframes svelte-18syxl5-blink{0%,80%,to{opacity:.2}40%{opacity:1}}.trust.svelte-3jjxns{border:1px solid var(--border);background:var(--bg-card);text-align:left;cursor:pointer;-webkit-user-select:none;user-select:none;width:100%;font:inherit;border-radius:0;flex:none;align-items:center;gap:8px;padding:5px 8px;display:flex}.trust.inline.svelte-3jjxns{width:auto;max-width:100%;padding:4px 8px}.trust.on.svelte-3jjxns{border-color:color-mix(in srgb, var(--ok) 45%, var(--border));background:var(--ok-bg)}.trust.svelte-3jjxns:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.switch.svelte-3jjxns{border:1px solid var(--border);background:var(--bg-elev);border-radius:999px;flex:none;width:30px;height:16px;transition:background .15s,border-color .15s;position:relative}.trust.on.svelte-3jjxns .switch:where(.svelte-3jjxns){background:var(--ok);border-color:var(--ok)}.knob.svelte-3jjxns{background:var(--text);opacity:.55;border-radius:50%;width:12px;height:12px;transition:transform .15s,background .15s,opacity .15s;position:absolute;top:1px;left:1px}.trust.on.svelte-3jjxns .knob:where(.svelte-3jjxns){background:var(--bg-card);opacity:1;transform:translate(14px)}.trust-text.svelte-3jjxns{flex-wrap:wrap;align-items:baseline;gap:4px;min-width:0;line-height:1.2;display:flex}.trust-text.svelte-3jjxns strong:where(.svelte-3jjxns){color:var(--text);font-size:12px;font-weight:600}.trust-text.svelte-3jjxns small:where(.svelte-3jjxns){color:var(--text-faint);font-size:11px}.model-select.svelte-9wkprr{flex:1;width:100%;min-width:0;position:relative}.trigger.svelte-9wkprr{box-sizing:border-box;background:var(--bg-card);border:1px solid var(--border);width:100%;min-width:0;min-height:38px;color:var(--text);font:inherit;font-size:inherit;text-align:left;cursor:pointer;align-items:center;gap:8px;padding:9px 12px;display:flex}.model-select.compact.svelte-9wkprr .trigger:where(.svelte-9wkprr){gap:6px;min-height:30px;padding:5px 10px;font-size:12px}.trigger.svelte-9wkprr:hover:not(:disabled){border-color:var(--accent)}.trigger.svelte-9wkprr:disabled{opacity:.5;cursor:not-allowed}.title.svelte-9wkprr{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.title.muted.svelte-9wkprr{color:var(--text-faint)}.badges.svelte-9wkprr{flex-wrap:wrap;flex-shrink:0;justify-content:flex-end;gap:4px;max-width:45%;display:flex}.badge.svelte-9wkprr{border:1px solid var(--border);background:var(--bg-elev,var(--bg-card));color:var(--text-dim,var(--text-faint));font-size:10px;line-height:1.35;font-family:var(--mono,ui-monospace, monospace);white-space:nowrap;border-radius:0;padding:0 5px}.hint.svelte-9wkprr{color:var(--text-faint);font-size:10px;font-family:var(--mono,ui-monospace, monospace);flex-shrink:0}.caret.svelte-9wkprr{opacity:.7;color:var(--text-dim);flex-shrink:0}.model-select.open.svelte-9wkprr .caret:where(.svelte-9wkprr){transform:rotate(180deg)}.menu.svelte-9wkprr{z-index:40;border:1px solid var(--border);background:var(--bg-card);flex-direction:column;max-height:min(360px,50vh);padding:4px;display:flex;position:absolute;inset:calc(100% + 4px) 0 auto;overflow:auto;box-shadow:0 8px 24px #0000002e}.model-select.drop-up.svelte-9wkprr .menu:where(.svelte-9wkprr){top:auto;bottom:calc(100% + 4px);box-shadow:0 -8px 24px #0000002e}.option.svelte-9wkprr{width:100%;color:var(--text);font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:2px;align-items:center;gap:6px;padding:6px 8px;font-size:12px;display:flex}.option.svelte-9wkprr:hover,.option.selected.svelte-9wkprr{background:var(--accent-soft)}