github-issue-tower-defence-management 1.116.9 → 1.117.1

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 (76) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +3 -3
  3. package/bin/adapter/entry-points/console/consoleReadApi.js +13 -1
  4. package/bin/adapter/entry-points/console/consoleReadApi.js.map +1 -1
  5. package/bin/adapter/entry-points/console/ui-dist/assets/index-CJJsRF8i.js +101 -0
  6. package/bin/adapter/entry-points/console/ui-dist/assets/{index-D1V2fi29.css → index-DGVKvwux.css} +1 -1
  7. package/bin/adapter/entry-points/console/ui-dist/index.html +2 -2
  8. package/bin/adapter/repositories/FileSystemSubAgentTranscriptDirectoryResolver.js +9 -2
  9. package/bin/adapter/repositories/FileSystemSubAgentTranscriptDirectoryResolver.js.map +1 -1
  10. package/bin/adapter/repositories/TranscriptSessionSubAgentActivityRepository.js +3 -2
  11. package/bin/adapter/repositories/TranscriptSessionSubAgentActivityRepository.js.map +1 -1
  12. package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js +1 -0
  13. package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js.map +1 -1
  14. package/bin/domain/usecases/NotifySilentLiveSessionsUseCase.js +13 -3
  15. package/bin/domain/usecases/NotifySilentLiveSessionsUseCase.js.map +1 -1
  16. package/package.json +1 -1
  17. package/src/adapter/entry-points/console/consoleReadApi.test.ts +4 -0
  18. package/src/adapter/entry-points/console/consoleReadApi.ts +18 -0
  19. package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +2 -0
  20. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleItemDetail.stories.tsx +2 -0
  21. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleItemDetail.test.tsx +3 -1
  22. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleItemDetail.tsx +1 -1
  23. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsolePullRequestDetail.test.tsx +1 -0
  24. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsolePullRequestDetail.tsx +1 -1
  25. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsolePullRequestStatusBadges.stories.tsx +15 -5
  26. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsolePullRequestStatusBadges.test.tsx +38 -8
  27. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsolePullRequestStatusBadges.tsx +35 -12
  28. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleDetailPrefetch.test.ts +117 -0
  29. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleDetailPrefetch.ts +83 -0
  30. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleItemDetailData.test.ts +2 -0
  31. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleItemDetailData.ts +1 -0
  32. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOperations.test.ts +67 -0
  33. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOperations.ts +26 -6
  34. package/src/adapter/entry-points/console/ui/src/features/console/lib/consoleApi.test.ts +21 -0
  35. package/src/adapter/entry-points/console/ui/src/features/console/lib/consoleApi.ts +14 -0
  36. package/src/adapter/entry-points/console/ui/src/features/console/lib/resourceCache.test.ts +48 -0
  37. package/src/adapter/entry-points/console/ui/src/features/console/lib/resourceCache.ts +24 -0
  38. package/src/adapter/entry-points/console/ui/src/features/console/logic/types.ts +4 -0
  39. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.test.tsx +1 -0
  40. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.tsx +9 -1
  41. package/src/adapter/entry-points/console/ui/src/features/console/testing/fixtures.ts +1 -0
  42. package/src/adapter/entry-points/console/ui/src/index.css +10 -1
  43. package/src/adapter/entry-points/console/ui-dist/assets/index-CJJsRF8i.js +101 -0
  44. package/src/adapter/entry-points/console/ui-dist/assets/{index-D1V2fi29.css → index-DGVKvwux.css} +1 -1
  45. package/src/adapter/entry-points/console/ui-dist/index.html +2 -2
  46. package/src/adapter/entry-points/console/webServer.test.ts +2 -0
  47. package/src/adapter/repositories/FileSystemSubAgentTranscriptDirectoryResolver.test.ts +40 -4
  48. package/src/adapter/repositories/FileSystemSubAgentTranscriptDirectoryResolver.ts +12 -6
  49. package/src/adapter/repositories/TranscriptSessionSubAgentActivityRepository.test.ts +107 -29
  50. package/src/adapter/repositories/TranscriptSessionSubAgentActivityRepository.ts +7 -2
  51. package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts +1 -0
  52. package/src/domain/usecases/CheckIssueReviewReadinessUseCase.test.ts +1 -0
  53. package/src/domain/usecases/IssueRejectionEvaluator.test.ts +1 -0
  54. package/src/domain/usecases/NotifySilentLiveSessionsUseCase.test.ts +84 -4
  55. package/src/domain/usecases/NotifySilentLiveSessionsUseCase.ts +16 -3
  56. package/src/domain/usecases/RevertOrphanedPreparationUseCase.test.ts +1 -0
  57. package/src/domain/usecases/StartPreparationUseCase.test.ts +9 -0
  58. package/src/domain/usecases/adapter-interfaces/IssueRepository.ts +1 -0
  59. package/src/domain/usecases/adapter-interfaces/SessionSubAgentActivityRepository.ts +1 -0
  60. package/src/domain/usecases/adapter-interfaces/SubAgentTranscriptDirectoryResolver.ts +4 -1
  61. package/types/adapter/entry-points/console/consoleReadApi.d.ts +4 -0
  62. package/types/adapter/entry-points/console/consoleReadApi.d.ts.map +1 -1
  63. package/types/adapter/repositories/FileSystemSubAgentTranscriptDirectoryResolver.d.ts +1 -1
  64. package/types/adapter/repositories/FileSystemSubAgentTranscriptDirectoryResolver.d.ts.map +1 -1
  65. package/types/adapter/repositories/TranscriptSessionSubAgentActivityRepository.d.ts +1 -1
  66. package/types/adapter/repositories/TranscriptSessionSubAgentActivityRepository.d.ts.map +1 -1
  67. package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts.map +1 -1
  68. package/types/domain/usecases/NotifySilentLiveSessionsUseCase.d.ts.map +1 -1
  69. package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts +1 -0
  70. package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts.map +1 -1
  71. package/types/domain/usecases/adapter-interfaces/SessionSubAgentActivityRepository.d.ts +1 -1
  72. package/types/domain/usecases/adapter-interfaces/SessionSubAgentActivityRepository.d.ts.map +1 -1
  73. package/types/domain/usecases/adapter-interfaces/SubAgentTranscriptDirectoryResolver.d.ts +1 -1
  74. package/types/domain/usecases/adapter-interfaces/SubAgentTranscriptDirectoryResolver.d.ts.map +1 -1
  75. package/bin/adapter/entry-points/console/ui-dist/assets/index-Bm0wt3Mn.js +0 -101
  76. package/src/adapter/entry-points/console/ui-dist/assets/index-Bm0wt3Mn.js +0 -101
@@ -1 +1 @@
1
- /*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-font-weight:initial;--tw-outline-style:solid;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-semibold:600;--radius-md:.375rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-input:#e5e5e5;--color-ring:#0a0a0a;--color-background:#fff;--color-foreground:#0a0a0a;--color-primary:#171717;--color-primary-foreground:#fafafa;--color-secondary:#f5f5f5;--color-secondary-foreground:#171717;--color-accent:#f5f5f5;--color-accent-foreground:#171717}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.relative{position:relative}.static{position:static}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.block{display:block}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.items-center{align-items:center}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing) * 2)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-input{border-color:var(--color-input)}.border-transparent{border-color:#0000}.bg-background{background-color:var(--color-background)}.bg-primary{background-color:var(--color-primary)}.bg-secondary{background-color:var(--color-secondary)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-2{padding-block:calc(var(--spacing) * 2)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-nowrap{white-space:nowrap}.text-foreground{color:var(--color-foreground)}.text-primary-foreground{color:var(--color-primary-foreground)}.text-secondary-foreground{color:var(--color-secondary-foreground)}.lowercase{text-transform:lowercase}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media(hover:hover){.hover\:bg-accent:hover{background-color:var(--color-accent)}.hover\:bg-primary\/90:hover{background-color:#171717e6}@supports (color:color-mix(in lab,red,red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab,var(--color-primary) 90%,transparent)}}.hover\:bg-secondary\/80:hover{background-color:#f5f5f5cc}@supports (color:color-mix(in lab,red,red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab,var(--color-secondary) 80%,transparent)}}.hover\:text-accent-foreground:hover{color:var(--color-accent-foreground)}}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--color-ring)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:opacity-50:disabled{opacity:.5}}html{font-size:clamp(15px,2.1vw,26px)}body{color:#e6edf3;background-color:#0d1117;margin:0;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif}.console-app{flex-direction:column;width:100%;min-height:100dvh;display:flex}.console-tabbar{-webkit-overflow-scrolling:touch;background:#161b22;border-bottom:2px solid #30363d;flex-wrap:nowrap;align-items:stretch;gap:0;min-height:42px;padding:0 8px;display:flex;overflow-x:auto}.console-tab{color:#8b949e;white-space:nowrap;cursor:pointer;background:0 0;border:none;border-bottom:2px solid #0000;align-items:center;gap:6px;margin-bottom:-2px;padding:10px 14px;font-size:.8125rem;font-weight:500;line-height:1.2;text-decoration:none;display:inline-flex}.console-tab:hover{color:#e6edf3}.console-tab[data-active=true]{color:#e6edf3;border-bottom-color:#2f81f7;font-weight:700}.console-tab-badge{text-align:center;color:#e6edf3;background:#484f58;border-radius:20px;min-width:20px;padding:1px 7px;font-size:.6875rem;font-weight:700;line-height:1.5}.console-tab-badge[data-zero=true]{color:#8b949e;background:#30363d}.console-tab-pjname{color:#8b949e;align-self:center;margin-left:auto;padding:0 8px;font-size:.7188rem}.console-tab-geninfo{color:#8b949e;align-self:center;padding:0 4px;font-size:.6875rem}.console-list{margin:0;padding:12px 18px 18px;list-style:none}.console-list-group{list-style:none}.console-item-row .console-item-icon{flex:none;margin-top:3px}.console-group-header{background:#0b0f14;border-bottom:1px solid #21262d;justify-content:space-between;align-items:center;padding:6px 12px;display:flex}.console-storytag{align-items:center;gap:8px;font-size:.8125rem;font-weight:700;display:inline-flex}.console-story-dot{border-radius:999px;width:10px;height:10px;display:inline-block}.console-group-count{color:#8b949e;font-size:.75rem}.console-item-row{color:#e6edf3;text-align:left;cursor:pointer;background:#161b22;border:1px solid #30363d;border-radius:8px;align-items:flex-start;gap:14px;width:100%;margin-bottom:10px;padding:12px 16px;display:flex}.console-item-row:hover{background:#1a2029;border-color:#484f58}.console-item-row[data-active=true]{background:#1a2029;border-color:#4493f8}.console-item-meta{flex:1;min-width:0}.console-item-title{font-size:.9063rem;font-weight:600;display:block}.console-item-sub{color:#8b949e;margin-top:3px;font-size:.7813rem;display:block}.console-item-pill{color:#8b949e;border:1px solid #30363d;border-radius:20px;margin-right:6px;padding:1px 8px;font-size:.6875rem;display:inline-block}.console-item-createdat{color:#8b949e;cursor:help}.console-item-fields{color:#adbac7;flex-wrap:wrap;gap:4px 10px;margin-top:4px;font-size:.7188rem;display:flex}.console-item-field{word-break:break-all;align-items:baseline;gap:4px;min-width:0;display:inline-flex}.console-item-field-label{color:#6e7681;text-transform:uppercase;letter-spacing:.03em;font-size:.625rem}.console-list-message{color:#8b949e;padding:16px;font-size:.875rem}.console-list-empty{text-align:center;color:#8b949e;padding:40px;font-size:.875rem}.console-list-error,.console-comment-error,.console-files-error,.console-commits-error,.console-detail-body-error{color:#f85149}.console-detail{flex-direction:column;flex:1 0 auto;gap:12px;padding:16px 16px 0;display:flex}.console-detail-title{align-items:center;gap:8px;margin:0;font-size:1.25rem;display:flex}.console-detail-title-text{flex:1}.console-detail-number{color:#8b949e;font-weight:400}.console-detail-closed-label{color:#a371f7;font-size:.8125rem}.console-detail-subbar{align-items:center;gap:12px;font-size:.8125rem;display:flex}.console-detail-link{color:#4493f8}.console-detail-repo{color:#8b949e;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.console-copy-url-button{color:#c9d1d9;border:1px solid #30363d;border-radius:6px;height:24px;padding:0 8px;font-size:.75rem}.console-copy-url-button:hover{color:#e6edf3;background-color:#21262d}.console-detail-pill,.console-label-chip,.console-detail-status-chip{border:1px solid #30363d;border-radius:999px;padding:2px 8px;font-size:.75rem;display:inline-block}.console-detail-pr-status-row{flex-wrap:wrap;align-items:center;gap:6px;margin-top:-4px;display:flex}.console-detail-pr-status{flex-wrap:wrap;align-items:center;gap:6px;display:inline-flex}.console-detail-ci-missing{opacity:.85;font-weight:400}.console-detail-labels{flex-wrap:wrap;gap:6px;display:flex}.console-detail-createdat{color:#8b949e;font-size:.75rem}.console-panel{border:1px solid #30363d;border-radius:8px;overflow:hidden}.console-panel-header{background:#161b22;justify-content:space-between;align-items:center;display:flex}.console-panel-toggle{color:#e6edf3;text-align:left;cursor:pointer;background:0 0;border:none;flex:1;align-items:center;gap:8px;padding:6px 12px;font-size:.875rem;font-weight:600;display:flex}.console-panel-toggle:hover{background:#1a2029}.console-panel-action{padding:6px 12px}.console-panel-body{padding:12px}.console-markdown{word-break:break-word;font-size:.875rem;line-height:1.5}.console-markdown ul{margin:.5em 0;padding-left:1.5em;list-style:outside}.console-markdown ol{margin:.5em 0;padding-left:1.5em;list-style:decimal}.console-markdown li{margin:.25em 0}.console-markdown table{border-collapse:collapse;margin:.5em 0}.console-markdown th,.console-markdown td{border:1px solid #30363d;padding:4px 8px}.console-markdown th{background:#161b22}.console-markdown h1,.console-markdown h2,.console-markdown h3,.console-markdown h4,.console-markdown h5,.console-markdown h6{margin:1em 0 .5em;font-weight:700;line-height:1.25}.console-markdown h1{font-size:1.6em}.console-markdown h2{font-size:1.4em}.console-markdown h3{font-size:1.2em}.console-markdown h4{font-size:1.05em}.console-markdown h5{font-size:.95em}.console-markdown h6{color:#8b949e;font-size:.9em}.console-markdown pre{background:#161b22;border:1px solid #30363d;border-radius:6px;margin:.5em 0;padding:12px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.8125rem;line-height:1.45;overflow-x:auto}.console-markdown code{background:#6e768166;border-radius:4px;padding:.15em .4em;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.9em}.console-markdown pre code{font-size:inherit;background:0 0;border-radius:0;padding:0}.console-markdown blockquote{color:#8b949e;border-left:3px solid #30363d;margin:.5em 0;padding:0 1em}.console-markdown a{color:#4493f8;text-decoration:none}.console-markdown a:hover{text-decoration:underline}.console-markdown-reference-host{display:inline}.console-markdown-reference{vertical-align:baseline;align-items:center;gap:.25em;display:inline-flex}.console-markdown-reference .console-item-icon{flex-shrink:0}.console-markdown-reference-title{text-decoration:none}.console-markdown-reference:hover .console-markdown-reference-title{text-decoration:underline}.console-markdown hr{border:none;border-top:1px solid #30363d;margin:1em 0}.console-mermaid-error{color:#f85149;font-size:.8125rem}.console-comment{border-top:1px solid #21262d;padding-top:8px}.console-comment-header{color:#8b949e;gap:8px;font-size:.75rem;display:flex}.console-comment-author{color:#e6edf3;font-weight:600}.console-files,.console-commits{margin:0;padding:0;list-style:none}.console-commit{align-items:center;gap:8px;padding:4px 0;font-size:.8125rem;display:flex}.console-file{flex-direction:column;font-size:.8125rem;display:flex}.console-file-badge{text-align:center;border:1px solid;border-radius:4px;width:18px;font-size:.6875rem}.console-file-path,.console-commit-message{flex:1;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.console-file-add,.console-pr-add{color:#3fb950}.console-file-del,.console-pr-del{color:#f85149}.console-commit-sha{color:#8b949e;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.console-actionbar{z-index:100;padding:10px 16px;padding-bottom:calc(10px + env(safe-area-inset-bottom));background:#161b22;border-top:2px solid #30363d;margin-top:auto;position:sticky;bottom:0}.console-operation-bar{flex-direction:column;gap:8px;width:100%;display:flex}.console-op-group{flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:8px;display:flex}.console-op-group-review{gap:10px}.console-op-group-stories{max-height:33vh;overflow-y:auto}.console-op-button{color:#e6edf3;white-space:nowrap;cursor:pointer;background:#21262d;border:1px solid #30363d;border-radius:6px;padding:7px 16px;font-size:.8125rem;font-weight:600}.console-op-button:hover{border-color:#484f58}.console-op-button-approve{color:#fff;background:#238636;border-color:#2ea043}.console-op-button-reject{color:#ffd166;background:#7d5000;border-color:#a06800}.console-op-button-wrong{color:#f85149;background:#3a1518;border-color:#f85149}.console-op-button-unneeded{color:#aab0b8;background:#2a2d31;border-color:#6e7681}.console-op-button-snooze{color:#79c0ff;background:#1c2b4a;border-color:#4493f8}.console-pr-section{border:1px solid #30363d;border-radius:8px;flex-direction:column;gap:10px;padding:12px;display:flex}.console-pr-statbar{color:#8b949e;gap:12px;font-size:.75rem;display:flex}.console-detail-screen{flex-direction:column;flex:1 0 auto;display:flex}.console-panel-open-link{color:#4493f8;font-size:.8125rem;font-weight:400}.console-composer{margin-top:4px}.console-composer-toggle{color:#8b949e;cursor:pointer;background:0 0;border:none;padding:2px 0;font-size:.7813rem}.console-composer-toggle:hover{color:#e6edf3}.console-composer-posted{flex-direction:column;gap:8px;margin-top:8px;display:flex}.console-composer-form{margin-top:8px}.console-composer-input{box-sizing:border-box;color:#e6edf3;width:100%;font:inherit;resize:vertical;background:#21262d;border:1px solid #30363d;border-radius:6px;padding:8px;font-size:.875rem}.console-composer-row{align-items:center;gap:8px;margin-top:6px;display:flex}.console-composer-submit{color:#fff;cursor:pointer;background:#238636;border:1px solid #2ea043;border-radius:6px;padding:7px 16px;font-size:.8125rem;font-weight:600}.console-composer-submit:disabled{opacity:.6;cursor:default}.console-composer-status{color:#8b949e;font-size:.75rem}.console-composer-error{color:#f85149}.console-undo-toast{z-index:9998;white-space:nowrap;border-radius:10px;align-items:center;gap:12px;max-width:92vw;padding:12px 18px;font-size:.8438rem;display:flex;position:fixed;top:12px;left:50%;transform:translate(-50%);box-shadow:0 4px 20px #0009}.console-undo-toast-green{color:#3fb950;background:#0d3320;border:1px solid #2ea043}.console-undo-toast-amber{color:#ffd166;background:#3a2800;border:1px solid #a06800}.console-undo-toast-red{color:#f85149;background:#3a1518;border:1px solid #da3633}.console-undo-toast-gray{color:#aab0b8;background:#2a2d31;border:1px solid #6e7681}.console-undo-toast-blue{color:#79c0ff;background:#0d1f40;border:1px solid #4493f8}.console-undo-toast-error{color:#f85149;background:#3a1518;border:1px solid #f85149}.console-undo-toast-message{text-overflow:ellipsis;flex:1;min-width:0;overflow:hidden}.console-undo-toast-undo{cursor:pointer;color:inherit;background:#ffffff1f;border:none;border-radius:6px;flex:none;padding:4px 12px;font-size:.8125rem;font-weight:700}.console-undo-toast-undo:hover{background:#ffffff38}.console-undo-toast-countdown{opacity:.7;flex:none;font-size:.6875rem}.console-undo-toast-bar{opacity:.5;background:currentColor;border-radius:0 0 10px 10px;height:3px;transition:width .1s linear;position:absolute;bottom:0;left:0}.console-file-row{width:100%;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;align-items:center;gap:8px;padding:4px 0;font-size:.8125rem;display:flex}.console-file-row:hover{background:#1a2029}.console-file-caret{color:#8b949e;flex:none;width:1em}.console-file-diff{border-collapse:collapse;width:100%;margin:4px 0 8px;font:.8125rem/1.6 ui-monospace,SFMono-Regular,Menlo,monospace}.console-file-diff td{white-space:pre-wrap;word-break:break-word;vertical-align:top;padding:0 10px}.console-diff-ln{text-align:right;color:#6e7681;-webkit-user-select:none;user-select:none;white-space:nowrap;border-right:1px solid #30363d;width:1%;padding:0 8px}.console-file-diff td.console-diff-ln{white-space:nowrap;word-break:normal;overflow-wrap:normal}.console-diff-add td{background:#2ea04326}.console-diff-add .console-diff-code{color:#aff5b4}.console-diff-del td{background:#f8514926}.console-diff-del .console-diff-code{color:#ffdcd7}.console-diff-hunk td{color:#79c0ff;background:#161b22}.console-diff-ctx .console-diff-code{color:#c9d1d9}.console-file-diff-empty{color:#8b949e;padding:8px 14px;font-size:.75rem}.console-diff-comment-cell{text-align:center;-webkit-user-select:none;user-select:none;width:1%;padding:0 2px}.console-diff-comment-button{color:#6e7681;cursor:pointer;opacity:.6;background:0 0;border:1px solid #30363d;border-radius:4px;width:18px;height:18px;padding:0;font-size:.875rem;line-height:16px}.console-diff-row:hover .console-diff-comment-button,.console-diff-comment-button:focus-visible,.console-diff-comment-button[aria-expanded=true]{opacity:1;color:#fff;background:#1f6feb;border-color:#2f81f7}.console-diff-composer-row td{background:#0d1117;padding:6px 10px}.console-diff-composer{background:#161b22;border:1px solid #30363d;border-radius:6px;flex-direction:column;gap:6px;padding:8px;display:flex}.console-diff-composer-anchor{color:#8b949e;font-size:.6875rem}.console-diff-composer-input{resize:vertical;color:#c9d1d9;width:100%;font:inherit;background:#0d1117;border:1px solid #30363d;border-radius:6px;padding:6px 8px}.console-diff-composer-controls{align-items:center;gap:8px;display:flex}.console-diff-composer-submit{color:#fff;cursor:pointer;background:#238636;border:1px solid #238636;border-radius:6px;padding:4px 12px}.console-diff-composer-submit:disabled{opacity:.6;cursor:default}.console-diff-composer-cancel{color:#c9d1d9;cursor:pointer;background:0 0;border:1px solid #30363d;border-radius:6px;padding:4px 12px}.console-diff-composer-status{color:#8b949e;font-size:.75rem}.console-diff-composer-error{color:#ff7b72}.console-diff-composer-posted{color:#3fb950;margin:0;font-size:.75rem}.console-pr-header{flex-wrap:wrap;align-items:center;gap:10px;padding-top:4px;display:flex}.console-pr-section-title{color:#e6edf3;font-size:.9375rem;font-weight:600}.console-pr-section-state{color:#8b949e;border:1px solid #6e7681;border-radius:999px;padding:1px 8px;font-size:.6875rem}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}
1
+ /*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-font-weight:initial;--tw-outline-style:solid;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-semibold:600;--radius-md:.375rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-input:#e5e5e5;--color-ring:#0a0a0a;--color-background:#fff;--color-foreground:#0a0a0a;--color-primary:#171717;--color-primary-foreground:#fafafa;--color-secondary:#f5f5f5;--color-secondary-foreground:#171717;--color-accent:#f5f5f5;--color-accent-foreground:#171717}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.relative{position:relative}.static{position:static}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.block{display:block}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.items-center{align-items:center}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing) * 2)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-input{border-color:var(--color-input)}.border-transparent{border-color:#0000}.bg-background{background-color:var(--color-background)}.bg-primary{background-color:var(--color-primary)}.bg-secondary{background-color:var(--color-secondary)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-2{padding-block:calc(var(--spacing) * 2)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-nowrap{white-space:nowrap}.text-foreground{color:var(--color-foreground)}.text-primary-foreground{color:var(--color-primary-foreground)}.text-secondary-foreground{color:var(--color-secondary-foreground)}.lowercase{text-transform:lowercase}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media(hover:hover){.hover\:bg-accent:hover{background-color:var(--color-accent)}.hover\:bg-primary\/90:hover{background-color:#171717e6}@supports (color:color-mix(in lab,red,red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab,var(--color-primary) 90%,transparent)}}.hover\:bg-secondary\/80:hover{background-color:#f5f5f5cc}@supports (color:color-mix(in lab,red,red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab,var(--color-secondary) 80%,transparent)}}.hover\:text-accent-foreground:hover{color:var(--color-accent-foreground)}}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--color-ring)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:opacity-50:disabled{opacity:.5}}html{font-size:clamp(15px,2.1vw,26px)}body{color:#e6edf3;background-color:#0d1117;margin:0;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif}.console-app{flex-direction:column;width:100%;min-height:100dvh;display:flex}.console-tabbar{-webkit-overflow-scrolling:touch;background:#161b22;border-bottom:2px solid #30363d;flex-wrap:nowrap;align-items:stretch;gap:0;min-height:42px;padding:0 8px;display:flex;overflow-x:auto}.console-tab{color:#8b949e;white-space:nowrap;cursor:pointer;background:0 0;border:none;border-bottom:2px solid #0000;align-items:center;gap:6px;margin-bottom:-2px;padding:10px 14px;font-size:.8125rem;font-weight:500;line-height:1.2;text-decoration:none;display:inline-flex}.console-tab:hover{color:#e6edf3}.console-tab[data-active=true]{color:#e6edf3;border-bottom-color:#2f81f7;font-weight:700}.console-tab-badge{text-align:center;color:#e6edf3;background:#484f58;border-radius:20px;min-width:20px;padding:1px 7px;font-size:.6875rem;font-weight:700;line-height:1.5}.console-tab-badge[data-zero=true]{color:#8b949e;background:#30363d}.console-tab-pjname{color:#8b949e;align-self:center;margin-left:auto;padding:0 8px;font-size:.7188rem}.console-tab-geninfo{color:#8b949e;align-self:center;padding:0 4px;font-size:.6875rem}.console-list{margin:0;padding:12px 18px 18px;list-style:none}.console-list-group{list-style:none}.console-item-row .console-item-icon{flex:none;margin-top:3px}.console-group-header{background:#0b0f14;border-bottom:1px solid #21262d;justify-content:space-between;align-items:center;padding:6px 12px;display:flex}.console-storytag{align-items:center;gap:8px;font-size:.8125rem;font-weight:700;display:inline-flex}.console-story-dot{border-radius:999px;width:10px;height:10px;display:inline-block}.console-group-count{color:#8b949e;font-size:.75rem}.console-item-row{color:#e6edf3;text-align:left;cursor:pointer;background:#161b22;border:1px solid #30363d;border-radius:8px;align-items:flex-start;gap:14px;width:100%;margin-bottom:10px;padding:12px 16px;display:flex}.console-item-row:hover{background:#1a2029;border-color:#484f58}.console-item-row[data-active=true]{background:#1a2029;border-color:#4493f8}.console-item-meta{flex:1;min-width:0}.console-item-title{font-size:.9063rem;font-weight:600;display:block}.console-item-sub{color:#8b949e;margin-top:3px;font-size:.7813rem;display:block}.console-item-pill{color:#8b949e;border:1px solid #30363d;border-radius:20px;margin-right:6px;padding:1px 8px;font-size:.6875rem;display:inline-block}.console-item-createdat{color:#8b949e;cursor:help}.console-item-fields{color:#adbac7;flex-wrap:wrap;gap:4px 10px;margin-top:4px;font-size:.7188rem;display:flex}.console-item-field{word-break:break-all;align-items:baseline;gap:4px;min-width:0;display:inline-flex}.console-item-field-label{color:#6e7681;text-transform:uppercase;letter-spacing:.03em;font-size:.625rem}.console-list-message{color:#8b949e;padding:16px;font-size:.875rem}.console-list-empty{text-align:center;color:#8b949e;padding:40px;font-size:.875rem}.console-list-error,.console-comment-error,.console-files-error,.console-commits-error,.console-detail-body-error{color:#f85149}.console-detail{flex-direction:column;flex:1 0 auto;gap:12px;padding:16px 16px 0;display:flex}.console-detail-title{align-items:center;gap:8px;margin:0;font-size:1.25rem;display:flex}.console-detail-title-text{flex:1}.console-detail-number{color:#8b949e;font-weight:400}.console-detail-closed-label{color:#a371f7;font-size:.8125rem}.console-detail-subbar{align-items:center;gap:12px;font-size:.8125rem;display:flex}.console-detail-link{color:#4493f8}.console-detail-repo{color:#8b949e;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.console-copy-url-button{color:#c9d1d9;border:1px solid #30363d;border-radius:6px;height:24px;padding:0 8px;font-size:.75rem}.console-copy-url-button:hover{color:#e6edf3;background-color:#21262d}.console-detail-pill,.console-label-chip,.console-detail-status-chip{border:1px solid #30363d;border-radius:999px;padding:2px 8px;font-size:.75rem;display:inline-block}.console-detail-pr-status-row{flex-wrap:wrap;align-items:center;gap:6px;margin-top:-4px;display:flex}.console-detail-pr-status{flex-wrap:wrap;align-items:center;gap:6px;display:inline-flex}.console-detail-ci-missing{opacity:.85;font-weight:400}.console-detail-mergeable-chip{font-weight:600}.console-detail-mergeable-chip-unknown{opacity:.7;font-weight:400}.console-detail-labels{flex-wrap:wrap;gap:6px;display:flex}.console-detail-createdat{color:#8b949e;font-size:.75rem}.console-panel{border:1px solid #30363d;border-radius:8px;overflow:hidden}.console-panel-header{background:#161b22;justify-content:space-between;align-items:center;display:flex}.console-panel-toggle{color:#e6edf3;text-align:left;cursor:pointer;background:0 0;border:none;flex:1;align-items:center;gap:8px;padding:6px 12px;font-size:.875rem;font-weight:600;display:flex}.console-panel-toggle:hover{background:#1a2029}.console-panel-action{padding:6px 12px}.console-panel-body{padding:12px}.console-markdown{word-break:break-word;font-size:.875rem;line-height:1.5}.console-markdown ul{margin:.5em 0;padding-left:1.5em;list-style:outside}.console-markdown ol{margin:.5em 0;padding-left:1.5em;list-style:decimal}.console-markdown li{margin:.25em 0}.console-markdown table{border-collapse:collapse;margin:.5em 0}.console-markdown th,.console-markdown td{border:1px solid #30363d;padding:4px 8px}.console-markdown th{background:#161b22}.console-markdown h1,.console-markdown h2,.console-markdown h3,.console-markdown h4,.console-markdown h5,.console-markdown h6{margin:1em 0 .5em;font-weight:700;line-height:1.25}.console-markdown h1{font-size:1.6em}.console-markdown h2{font-size:1.4em}.console-markdown h3{font-size:1.2em}.console-markdown h4{font-size:1.05em}.console-markdown h5{font-size:.95em}.console-markdown h6{color:#8b949e;font-size:.9em}.console-markdown pre{background:#161b22;border:1px solid #30363d;border-radius:6px;margin:.5em 0;padding:12px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.8125rem;line-height:1.45;overflow-x:auto}.console-markdown code{background:#6e768166;border-radius:4px;padding:.15em .4em;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.9em}.console-markdown pre code{font-size:inherit;background:0 0;border-radius:0;padding:0}.console-markdown blockquote{color:#8b949e;border-left:3px solid #30363d;margin:.5em 0;padding:0 1em}.console-markdown a{color:#4493f8;text-decoration:none}.console-markdown a:hover{text-decoration:underline}.console-markdown-reference-host{display:inline}.console-markdown-reference{vertical-align:baseline;align-items:center;gap:.25em;display:inline-flex}.console-markdown-reference .console-item-icon{flex-shrink:0}.console-markdown-reference-title{text-decoration:none}.console-markdown-reference:hover .console-markdown-reference-title{text-decoration:underline}.console-markdown hr{border:none;border-top:1px solid #30363d;margin:1em 0}.console-mermaid-error{color:#f85149;font-size:.8125rem}.console-comment{border-top:1px solid #21262d;padding-top:8px}.console-comment-header{color:#8b949e;gap:8px;font-size:.75rem;display:flex}.console-comment-author{color:#e6edf3;font-weight:600}.console-files,.console-commits{margin:0;padding:0;list-style:none}.console-commit{align-items:center;gap:8px;padding:4px 0;font-size:.8125rem;display:flex}.console-file{flex-direction:column;font-size:.8125rem;display:flex}.console-file-badge{text-align:center;border:1px solid;border-radius:4px;width:18px;font-size:.6875rem}.console-file-path,.console-commit-message{flex:1;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.console-file-add,.console-pr-add{color:#3fb950}.console-file-del,.console-pr-del{color:#f85149}.console-commit-sha{color:#8b949e;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.console-actionbar{z-index:100;padding:10px 16px;padding-bottom:calc(10px + env(safe-area-inset-bottom));background:#161b22;border-top:2px solid #30363d;margin-top:auto;position:sticky;bottom:0}.console-operation-bar{flex-direction:column;gap:8px;width:100%;display:flex}.console-op-group{flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:8px;display:flex}.console-op-group-review{gap:10px}.console-op-group-stories{max-height:33vh;overflow-y:auto}.console-op-button{color:#e6edf3;white-space:nowrap;cursor:pointer;background:#21262d;border:1px solid #30363d;border-radius:6px;padding:9px 16px;font-size:.8125rem;font-weight:600}.console-op-button:hover{border-color:#484f58}.console-op-button-approve{color:#fff;background:#238636;border-color:#2ea043}.console-op-button-reject{color:#ffd166;background:#7d5000;border-color:#a06800}.console-op-button-wrong{color:#f85149;background:#3a1518;border-color:#f85149}.console-op-button-unneeded{color:#aab0b8;background:#2a2d31;border-color:#6e7681}.console-op-button-snooze{color:#79c0ff;background:#1c2b4a;border-color:#4493f8}.console-pr-section{border:1px solid #30363d;border-radius:8px;flex-direction:column;gap:10px;padding:12px;display:flex}.console-pr-statbar{color:#8b949e;gap:12px;font-size:.75rem;display:flex}.console-detail-screen{flex-direction:column;flex:1 0 auto;display:flex}.console-panel-open-link{color:#4493f8;font-size:.8125rem;font-weight:400}.console-composer{margin-top:4px}.console-composer-toggle{color:#8b949e;cursor:pointer;background:0 0;border:none;padding:2px 0;font-size:.7813rem}.console-composer-toggle:hover{color:#e6edf3}.console-composer-posted{flex-direction:column;gap:8px;margin-top:8px;display:flex}.console-composer-form{margin-top:8px}.console-composer-input{box-sizing:border-box;color:#e6edf3;width:100%;font:inherit;resize:vertical;background:#21262d;border:1px solid #30363d;border-radius:6px;padding:8px;font-size:.875rem}.console-composer-row{align-items:center;gap:8px;margin-top:6px;display:flex}.console-composer-submit{color:#fff;cursor:pointer;background:#238636;border:1px solid #2ea043;border-radius:6px;padding:7px 16px;font-size:.8125rem;font-weight:600}.console-composer-submit:disabled{opacity:.6;cursor:default}.console-composer-status{color:#8b949e;font-size:.75rem}.console-composer-error{color:#f85149}.console-undo-toast{z-index:9998;white-space:nowrap;border-radius:10px;align-items:center;gap:12px;max-width:92vw;padding:12px 18px;font-size:.8438rem;display:flex;position:fixed;top:12px;left:50%;transform:translate(-50%);box-shadow:0 4px 20px #0009}.console-undo-toast-green{color:#3fb950;background:#0d3320;border:1px solid #2ea043}.console-undo-toast-amber{color:#ffd166;background:#3a2800;border:1px solid #a06800}.console-undo-toast-red{color:#f85149;background:#3a1518;border:1px solid #da3633}.console-undo-toast-gray{color:#aab0b8;background:#2a2d31;border:1px solid #6e7681}.console-undo-toast-blue{color:#79c0ff;background:#0d1f40;border:1px solid #4493f8}.console-undo-toast-error{color:#f85149;background:#3a1518;border:1px solid #f85149}.console-undo-toast-message{text-overflow:ellipsis;flex:1;min-width:0;overflow:hidden}.console-undo-toast-undo{cursor:pointer;color:inherit;background:#ffffff1f;border:none;border-radius:6px;flex:none;padding:4px 12px;font-size:.8125rem;font-weight:700}.console-undo-toast-undo:hover{background:#ffffff38}.console-undo-toast-countdown{opacity:.7;flex:none;font-size:.6875rem}.console-undo-toast-bar{opacity:.5;background:currentColor;border-radius:0 0 10px 10px;height:3px;transition:width .1s linear;position:absolute;bottom:0;left:0}.console-file-row{width:100%;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;align-items:center;gap:8px;padding:4px 0;font-size:.8125rem;display:flex}.console-file-row:hover{background:#1a2029}.console-file-caret{color:#8b949e;flex:none;width:1em}.console-file-diff{border-collapse:collapse;width:100%;margin:4px 0 8px;font:.8125rem/1.6 ui-monospace,SFMono-Regular,Menlo,monospace}.console-file-diff td{white-space:pre-wrap;word-break:break-word;vertical-align:top;padding:0 10px}.console-diff-ln{text-align:right;color:#6e7681;-webkit-user-select:none;user-select:none;white-space:nowrap;border-right:1px solid #30363d;width:1%;padding:0 8px}.console-file-diff td.console-diff-ln{white-space:nowrap;word-break:normal;overflow-wrap:normal}.console-diff-add td{background:#2ea04326}.console-diff-add .console-diff-code{color:#aff5b4}.console-diff-del td{background:#f8514926}.console-diff-del .console-diff-code{color:#ffdcd7}.console-diff-hunk td{color:#79c0ff;background:#161b22}.console-diff-ctx .console-diff-code{color:#c9d1d9}.console-file-diff-empty{color:#8b949e;padding:8px 14px;font-size:.75rem}.console-diff-comment-cell{text-align:center;-webkit-user-select:none;user-select:none;width:1%;padding:0 2px}.console-diff-comment-button{color:#6e7681;cursor:pointer;opacity:.6;background:0 0;border:1px solid #30363d;border-radius:4px;width:18px;height:18px;padding:0;font-size:.875rem;line-height:16px}.console-diff-row:hover .console-diff-comment-button,.console-diff-comment-button:focus-visible,.console-diff-comment-button[aria-expanded=true]{opacity:1;color:#fff;background:#1f6feb;border-color:#2f81f7}.console-diff-composer-row td{background:#0d1117;padding:6px 10px}.console-diff-composer{background:#161b22;border:1px solid #30363d;border-radius:6px;flex-direction:column;gap:6px;padding:8px;display:flex}.console-diff-composer-anchor{color:#8b949e;font-size:.6875rem}.console-diff-composer-input{resize:vertical;color:#c9d1d9;width:100%;font:inherit;background:#0d1117;border:1px solid #30363d;border-radius:6px;padding:6px 8px}.console-diff-composer-controls{align-items:center;gap:8px;display:flex}.console-diff-composer-submit{color:#fff;cursor:pointer;background:#238636;border:1px solid #238636;border-radius:6px;padding:4px 12px}.console-diff-composer-submit:disabled{opacity:.6;cursor:default}.console-diff-composer-cancel{color:#c9d1d9;cursor:pointer;background:0 0;border:1px solid #30363d;border-radius:6px;padding:4px 12px}.console-diff-composer-status{color:#8b949e;font-size:.75rem}.console-diff-composer-error{color:#ff7b72}.console-diff-composer-posted{color:#3fb950;margin:0;font-size:.75rem}.console-pr-header{flex-wrap:wrap;align-items:center;gap:10px;padding-top:4px;display:flex}.console-pr-section-title{color:#e6edf3;font-size:.9375rem;font-weight:600}.console-pr-section-state{color:#8b949e;border:1px solid #6e7681;border-radius:999px;padding:1px 8px;font-size:.6875rem}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>TDPM Console</title>
7
- <script type="module" crossorigin src="/assets/index-Bm0wt3Mn.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-D1V2fi29.css">
7
+ <script type="module" crossorigin src="/assets/index-CJJsRF8i.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-DGVKvwux.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
@@ -586,6 +586,7 @@ describe('webServer new routes integration', () => {
586
586
  createdAt: new Date('2026-06-18T03:21:00.000Z'),
587
587
  isDraft: false,
588
588
  isConflicted: true,
589
+ mergeable: 'CONFLICTING',
589
590
  isPassedAllCiJob: false,
590
591
  isCiStateSuccess: false,
591
592
  isResolvedAllReviewComments: false,
@@ -616,6 +617,7 @@ describe('webServer new routes integration', () => {
616
617
  found: true,
617
618
  status: {
618
619
  isConflicted: true,
620
+ mergeableStatus: 'CONFLICTING',
619
621
  isPassedAllCiJob: false,
620
622
  isCiStateSuccess: false,
621
623
  isBranchOutOfDate: true,
@@ -2,19 +2,28 @@ import * as path from 'path';
2
2
  import { FileSystemSubAgentTranscriptDirectoryResolver } from './FileSystemSubAgentTranscriptDirectoryResolver';
3
3
 
4
4
  describe('FileSystemSubAgentTranscriptDirectoryResolver', () => {
5
- it('builds the subagents directory under the session-specific directory', () => {
5
+ const rootDirectory = '/home/user/.claude/projects';
6
+ const mainTranscriptPath = path.join(
7
+ rootDirectory,
8
+ '-home-user-0-workspaces-workspace1-oss-some-repo-worktrees-i123',
9
+ 'ba0637e1-9ff1-41a8-b13c-f45e6a71efc5.jsonl',
10
+ );
11
+
12
+ it('derives the subagents directory next to the resolved main transcript path', () => {
6
13
  const resolver = new FileSystemSubAgentTranscriptDirectoryResolver(
7
- '/var/transcripts',
14
+ rootDirectory,
8
15
  );
9
16
 
10
17
  const result = resolver.resolveSubAgentsDirectory(
11
18
  'https_//github_com/owner/repo/issues/9',
19
+ mainTranscriptPath,
12
20
  );
13
21
 
14
22
  expect(result).toBe(
15
23
  path.join(
16
- '/var/transcripts',
17
- 'https_//github_com_owner_repo_issues_9'.replace(/\//g, '_'),
24
+ rootDirectory,
25
+ '-home-user-0-workspaces-workspace1-oss-some-repo-worktrees-i123',
26
+ 'ba0637e1-9ff1-41a8-b13c-f45e6a71efc5',
18
27
  'subagents',
19
28
  ),
20
29
  );
@@ -25,6 +34,33 @@ describe('FileSystemSubAgentTranscriptDirectoryResolver', () => {
25
34
 
26
35
  const result = resolver.resolveSubAgentsDirectory(
27
36
  'https_//github_com/owner/repo/issues/9',
37
+ mainTranscriptPath,
38
+ );
39
+
40
+ expect(result).toBeNull();
41
+ });
42
+
43
+ it('returns null when the main transcript path is unresolved', () => {
44
+ const resolver = new FileSystemSubAgentTranscriptDirectoryResolver(
45
+ rootDirectory,
46
+ );
47
+
48
+ const result = resolver.resolveSubAgentsDirectory(
49
+ 'https_//github_com/owner/repo/issues/9',
50
+ null,
51
+ );
52
+
53
+ expect(result).toBeNull();
54
+ });
55
+
56
+ it('returns null when the main transcript path is not a .jsonl file', () => {
57
+ const resolver = new FileSystemSubAgentTranscriptDirectoryResolver(
58
+ rootDirectory,
59
+ );
60
+
61
+ const result = resolver.resolveSubAgentsDirectory(
62
+ 'https_//github_com/owner/repo/issues/9',
63
+ path.join(rootDirectory, 'slug', 'no-extension'),
28
64
  );
29
65
 
30
66
  expect(result).toBeNull();
@@ -4,14 +4,20 @@ import { SubAgentTranscriptDirectoryResolver } from '../../domain/usecases/adapt
4
4
  export class FileSystemSubAgentTranscriptDirectoryResolver implements SubAgentTranscriptDirectoryResolver {
5
5
  constructor(private readonly rootDirectory: string | null) {}
6
6
 
7
- resolveSubAgentsDirectory = (sessionName: string): string | null => {
7
+ resolveSubAgentsDirectory = (
8
+ _sessionName: string,
9
+ mainTranscriptPath: string | null,
10
+ ): string | null => {
8
11
  if (this.rootDirectory === null) {
9
12
  return null;
10
13
  }
11
- return path.join(
12
- this.rootDirectory,
13
- sessionName.replace(/\//g, '_'),
14
- 'subagents',
15
- );
14
+ if (mainTranscriptPath === null) {
15
+ return null;
16
+ }
17
+ const sessionDirectory = mainTranscriptPath.replace(/\.jsonl$/, '');
18
+ if (sessionDirectory === mainTranscriptPath) {
19
+ return null;
20
+ }
21
+ return path.join(sessionDirectory, 'subagents');
16
22
  };
17
23
  }
@@ -2,6 +2,7 @@ import * as fs from 'fs';
2
2
  import * as os from 'os';
3
3
  import * as path from 'path';
4
4
  import { SubAgentTranscriptDirectoryResolver } from '../../domain/usecases/adapter-interfaces/SubAgentTranscriptDirectoryResolver';
5
+ import { FileSystemSubAgentTranscriptDirectoryResolver } from './FileSystemSubAgentTranscriptDirectoryResolver';
5
6
  import { TranscriptSessionSubAgentActivityRepository } from './TranscriptSessionSubAgentActivityRepository';
6
7
 
7
8
  describe('TranscriptSessionSubAgentActivityRepository', () => {
@@ -17,10 +18,32 @@ describe('TranscriptSessionSubAgentActivityRepository', () => {
17
18
  fs.rmSync(rootDirectory, { force: true, recursive: true });
18
19
  });
19
20
 
21
+ const cwdSlugFor = (sessionName: string): string =>
22
+ `-home-user-worktrees-${sessionName.replace(/[^a-zA-Z0-9]/g, '-')}`;
23
+
24
+ const sessionUuidFor = (sessionName: string): string =>
25
+ `uuid-${sessionName.replace(/[^a-zA-Z0-9]/g, '-')}`;
26
+
27
+ const mainTranscriptPathFor = (sessionName: string): string =>
28
+ path.join(
29
+ rootDirectory,
30
+ cwdSlugFor(sessionName),
31
+ `${sessionUuidFor(sessionName)}.jsonl`,
32
+ );
33
+
34
+ const transcriptMapFor = (sessionNames: string[]): Map<string, string> =>
35
+ new Map(
36
+ sessionNames.map((sessionName) => [
37
+ sessionName,
38
+ mainTranscriptPathFor(sessionName),
39
+ ]),
40
+ );
41
+
20
42
  const subAgentsDirFor = (sessionName: string): string => {
21
43
  const dir = path.join(
22
44
  rootDirectory,
23
- sessionName.replace(/\//g, '_'),
45
+ cwdSlugFor(sessionName),
46
+ sessionUuidFor(sessionName),
24
47
  'subagents',
25
48
  );
26
49
  fs.mkdirSync(dir, { recursive: true });
@@ -44,10 +67,8 @@ describe('TranscriptSessionSubAgentActivityRepository', () => {
44
67
  return filePath;
45
68
  };
46
69
 
47
- const createResolver = (): SubAgentTranscriptDirectoryResolver => ({
48
- resolveSubAgentsDirectory: (sessionName) =>
49
- path.join(rootDirectory, sessionName.replace(/\//g, '_'), 'subagents'),
50
- });
70
+ const createResolver = (): SubAgentTranscriptDirectoryResolver =>
71
+ new FileSystemSubAgentTranscriptDirectoryResolver(rootDirectory);
51
72
 
52
73
  const runningEntries = (startTimestamp: string): object[] => [
53
74
  { type: 'user', timestamp: startTimestamp, message: { role: 'user' } },
@@ -90,9 +111,10 @@ describe('TranscriptSessionSubAgentActivityRepository', () => {
90
111
  now,
91
112
  );
92
113
 
93
- const result = await repository.listSubAgentActivitiesBySessionName([
94
- sessionName,
95
- ]);
114
+ const result = await repository.listSubAgentActivitiesBySessionName(
115
+ [sessionName],
116
+ transcriptMapFor([sessionName]),
117
+ );
96
118
 
97
119
  expect(result.get(sessionName)).toEqual([
98
120
  { label: 'agent-aaa111', silentSeconds: 120, runningSeconds: 900 },
@@ -112,9 +134,10 @@ describe('TranscriptSessionSubAgentActivityRepository', () => {
112
134
  now,
113
135
  );
114
136
 
115
- const result = await repository.listSubAgentActivitiesBySessionName([
116
- sessionName,
117
- ]);
137
+ const result = await repository.listSubAgentActivitiesBySessionName(
138
+ [sessionName],
139
+ transcriptMapFor([sessionName]),
140
+ );
118
141
 
119
142
  expect(result.size).toBe(0);
120
143
  });
@@ -132,9 +155,10 @@ describe('TranscriptSessionSubAgentActivityRepository', () => {
132
155
  now,
133
156
  );
134
157
 
135
- const result = await repository.listSubAgentActivitiesBySessionName([
136
- sessionName,
137
- ]);
158
+ const result = await repository.listSubAgentActivitiesBySessionName(
159
+ [sessionName],
160
+ transcriptMapFor([sessionName]),
161
+ );
138
162
 
139
163
  expect(result.size).toBe(0);
140
164
  });
@@ -160,9 +184,10 @@ describe('TranscriptSessionSubAgentActivityRepository', () => {
160
184
  now,
161
185
  );
162
186
 
163
- const result = await repository.listSubAgentActivitiesBySessionName([
164
- sessionName,
165
- ]);
187
+ const result = await repository.listSubAgentActivitiesBySessionName(
188
+ [sessionName],
189
+ transcriptMapFor([sessionName]),
190
+ );
166
191
 
167
192
  expect(result.get(sessionName)).toEqual([
168
193
  { label: 'agent-link1', silentSeconds: 60, runningSeconds: 600 },
@@ -176,9 +201,10 @@ describe('TranscriptSessionSubAgentActivityRepository', () => {
176
201
  now,
177
202
  );
178
203
 
179
- const result = await repository.listSubAgentActivitiesBySessionName([
180
- 'https_//github_com/owner/repo/issues/9',
181
- ]);
204
+ const result = await repository.listSubAgentActivitiesBySessionName(
205
+ ['https_//github_com/owner/repo/issues/9'],
206
+ transcriptMapFor(['https_//github_com/owner/repo/issues/9']),
207
+ );
182
208
 
183
209
  expect(result.size).toBe(0);
184
210
  });
@@ -189,9 +215,10 @@ describe('TranscriptSessionSubAgentActivityRepository', () => {
189
215
  now,
190
216
  );
191
217
 
192
- const result = await repository.listSubAgentActivitiesBySessionName([
193
- 'https_//github_com/owner/repo/issues/404',
194
- ]);
218
+ const result = await repository.listSubAgentActivitiesBySessionName(
219
+ ['https_//github_com/owner/repo/issues/404'],
220
+ transcriptMapFor(['https_//github_com/owner/repo/issues/404']),
221
+ );
195
222
 
196
223
  expect(result.size).toBe(0);
197
224
  });
@@ -215,9 +242,10 @@ describe('TranscriptSessionSubAgentActivityRepository', () => {
215
242
  now,
216
243
  );
217
244
 
218
- const result = await repository.listSubAgentActivitiesBySessionName([
219
- sessionName,
220
- ]);
245
+ const result = await repository.listSubAgentActivitiesBySessionName(
246
+ [sessionName],
247
+ transcriptMapFor([sessionName]),
248
+ );
221
249
 
222
250
  expect(result.get(sessionName)).toHaveLength(2);
223
251
  });
@@ -235,12 +263,62 @@ describe('TranscriptSessionSubAgentActivityRepository', () => {
235
263
  now,
236
264
  );
237
265
 
238
- const result = await repository.listSubAgentActivitiesBySessionName([
239
- sessionName,
240
- ]);
266
+ const result = await repository.listSubAgentActivitiesBySessionName(
267
+ [sessionName],
268
+ transcriptMapFor([sessionName]),
269
+ );
241
270
 
242
271
  expect(result.get(sessionName)).toEqual([
243
272
  { label: 'agent-future', silentSeconds: 0, runningSeconds: 0 },
244
273
  ]);
245
274
  });
275
+
276
+ it('resolves sub-agent transcripts laid out exactly as Claude Code stores them on disk', async () => {
277
+ const sessionName = 'https_//github_com/HiromiShikata/repo/issues/2355';
278
+ const projectsRoot = path.join(rootDirectory, 'projects');
279
+ const cwdSlug =
280
+ '-home-user-0-workspaces-workspace1-oss-example-repo-worktrees-i2355';
281
+ const sessionUuid = 'ba0637e1-9ff1-41a8-b13c-f45e6a71efc5';
282
+ const mainTranscriptPath = path.join(
283
+ projectsRoot,
284
+ cwdSlug,
285
+ `${sessionUuid}.jsonl`,
286
+ );
287
+ const subagentsDir = path.join(
288
+ projectsRoot,
289
+ cwdSlug,
290
+ sessionUuid,
291
+ 'subagents',
292
+ );
293
+ fs.mkdirSync(subagentsDir, { recursive: true });
294
+ fs.mkdirSync(path.dirname(mainTranscriptPath), { recursive: true });
295
+ fs.writeFileSync(mainTranscriptPath, '', 'utf8');
296
+ const agentFile = path.join(subagentsDir, 'agent-afcbe335fdbec0a28.jsonl');
297
+ fs.writeFileSync(
298
+ agentFile,
299
+ runningEntries('2026-06-27T11:45:00.000Z')
300
+ .map((entry) => JSON.stringify(entry))
301
+ .join('\n'),
302
+ 'utf8',
303
+ );
304
+ fs.utimesSync(agentFile, nowEpochSeconds - 120, nowEpochSeconds - 120);
305
+
306
+ const repository = new TranscriptSessionSubAgentActivityRepository(
307
+ new FileSystemSubAgentTranscriptDirectoryResolver(projectsRoot),
308
+ now,
309
+ );
310
+
311
+ const result = await repository.listSubAgentActivitiesBySessionName(
312
+ [sessionName],
313
+ new Map([[sessionName, mainTranscriptPath]]),
314
+ );
315
+
316
+ expect(result.get(sessionName)).toEqual([
317
+ {
318
+ label: 'agent-afcbe335fdbec0a28',
319
+ silentSeconds: 120,
320
+ runningSeconds: 900,
321
+ },
322
+ ]);
323
+ });
246
324
  });
@@ -70,12 +70,17 @@ export class TranscriptSessionSubAgentActivityRepository implements SessionSubAg
70
70
 
71
71
  listSubAgentActivitiesBySessionName = async (
72
72
  sessionNames: string[],
73
+ transcriptPathBySessionName: Map<string, string>,
73
74
  ): Promise<Map<string, SubAgentActivity[]>> => {
74
75
  const result = new Map<string, SubAgentActivity[]>();
75
76
  const nowEpochSeconds = Math.floor(this.now.getTime() / 1000);
76
77
  for (const sessionName of sessionNames) {
77
- const directory =
78
- this.directoryResolver.resolveSubAgentsDirectory(sessionName);
78
+ const mainTranscriptPath =
79
+ transcriptPathBySessionName.get(sessionName) ?? null;
80
+ const directory = this.directoryResolver.resolveSubAgentsDirectory(
81
+ sessionName,
82
+ mainTranscriptPath,
83
+ );
79
84
  if (directory === null) {
80
85
  continue;
81
86
  }
@@ -996,6 +996,7 @@ export class ApiV3CheerioRestIssueRepository
996
996
  createdAt: new Date(0),
997
997
  isDraft: data.isDraft === true,
998
998
  isConflicted,
999
+ mergeable: data.mergeable ?? null,
999
1000
  isPassedAllCiJob,
1000
1001
  isCiStateSuccess,
1001
1002
  isResolvedAllReviewComments,
@@ -46,6 +46,7 @@ const createReadyPr = (
46
46
  createdAt: new Date('2000-01-01T00:00:00Z'),
47
47
  isDraft: false,
48
48
  isConflicted: false,
49
+ mergeable: null,
49
50
  isPassedAllCiJob: true,
50
51
  isCiStateSuccess: true,
51
52
  isResolvedAllReviewComments: true,
@@ -10,6 +10,7 @@ const createReadyPr = (
10
10
  createdAt: new Date('2000-01-01T00:00:00Z'),
11
11
  isDraft: false,
12
12
  isConflicted: false,
13
+ mergeable: null,
13
14
  isPassedAllCiJob: true,
14
15
  isCiStateSuccess: true,
15
16
  isResolvedAllReviewComments: true,
@@ -277,7 +277,7 @@ describe('NotifySilentLiveSessionsUseCase', () => {
277
277
  );
278
278
  expect(
279
279
  mockSubAgentActivityRepository.listSubAgentActivitiesBySessionName,
280
- ).toHaveBeenCalledWith([]);
280
+ ).toHaveBeenCalledWith([], new Map());
281
281
  expect(
282
282
  mockMessageComposer.composeMainStalledSection,
283
283
  ).not.toHaveBeenCalled();
@@ -335,7 +335,7 @@ describe('NotifySilentLiveSessionsUseCase', () => {
335
335
  ).toHaveBeenCalledWith(expectedMap);
336
336
  expect(
337
337
  mockSubAgentActivityRepository.listSubAgentActivitiesBySessionName,
338
- ).toHaveBeenCalledWith([GITHUB_SESSION]);
338
+ ).toHaveBeenCalledWith([GITHUB_SESSION], expectedMap);
339
339
  });
340
340
 
341
341
  it('suppresses the stalled section and sends nothing when an owner call is pending past the threshold', async () => {
@@ -693,19 +693,99 @@ describe('NotifySilentLiveSessionsUseCase', () => {
693
693
  warnSpy.mockRestore();
694
694
  });
695
695
 
696
- it('parses a github.com issue URL session name and rejects other names', () => {
696
+ it('gates on the real tmux session-name form by resolving its canonical issue URL', async () => {
697
+ const REAL_TMUX_SESSION =
698
+ 'https_//github_com/HiromiShikata/repo/issues/2355';
699
+ const CANONICAL_ISSUE_URL =
700
+ 'https://github.com/HiromiShikata/repo/issues/2355';
701
+ setupSilentMainSession(REAL_TMUX_SESSION);
702
+ mockHubTaskStatusResolver.getIssueByUrl.mockResolvedValue(
703
+ issueFor({
704
+ url: CANONICAL_ISSUE_URL,
705
+ state: 'OPEN',
706
+ status: ACTIVE_STATUS,
707
+ }),
708
+ );
709
+
710
+ await useCase.run(runParams({ activeHubTaskStatus: ACTIVE_STATUS }));
711
+
712
+ expect(mockHubTaskStatusResolver.getIssueByUrl).toHaveBeenCalledWith(
713
+ CANONICAL_ISSUE_URL,
714
+ );
715
+ expect(
716
+ mockNotificationRepository.sendSelfCheckNotification,
717
+ ).toHaveBeenCalledWith(REAL_TMUX_SESSION, MAIN_STALLED_SECTION);
718
+ });
719
+
720
+ it('skips the real tmux session-name form when its canonical hub task is no longer active', async () => {
721
+ const REAL_TMUX_SESSION =
722
+ 'https_//github_com/HiromiShikata/repo/issues/2355';
723
+ const CANONICAL_ISSUE_URL =
724
+ 'https://github.com/HiromiShikata/repo/issues/2355';
725
+ setupSilentMainSession(REAL_TMUX_SESSION);
726
+ mockHubTaskStatusResolver.getIssueByUrl.mockResolvedValue(
727
+ issueFor({
728
+ url: CANONICAL_ISSUE_URL,
729
+ state: 'OPEN',
730
+ status: 'Todo',
731
+ }),
732
+ );
733
+
734
+ await useCase.run(runParams({ activeHubTaskStatus: ACTIVE_STATUS }));
735
+
736
+ expect(mockHubTaskStatusResolver.getIssueByUrl).toHaveBeenCalledWith(
737
+ CANONICAL_ISSUE_URL,
738
+ );
739
+ expect(
740
+ mockNotificationRepository.sendSelfCheckNotification,
741
+ ).not.toHaveBeenCalled();
742
+ });
743
+
744
+ it('parses a clean github.com issue URL session name and rejects non-github names', () => {
697
745
  expect(parseHubTaskIssueUrlFromSessionName(HUB_TASK_SESSION)).toBe(
698
746
  HUB_TASK_SESSION,
699
747
  );
700
748
  expect(parseHubTaskIssueUrlFromSessionName('workbench')).toBeNull();
749
+ expect(
750
+ parseHubTaskIssueUrlFromSessionName(
751
+ 'https://example.com/HiromiShikata/repo/issues/42',
752
+ ),
753
+ ).toBeNull();
754
+ });
755
+
756
+ it('parses the real tmux session-name form produced by toTmuxSessionName for an issue', () => {
757
+ expect(
758
+ parseHubTaskIssueUrlFromSessionName(
759
+ 'https_//github_com/HiromiShikata/repo/issues/2355',
760
+ ),
761
+ ).toBe('https://github.com/HiromiShikata/repo/issues/2355');
762
+ });
763
+
764
+ it('parses the real tmux session-name form for a pull request', () => {
765
+ expect(
766
+ parseHubTaskIssueUrlFromSessionName(
767
+ 'https_//github_com/HiromiShikata/repo/pull/2474',
768
+ ),
769
+ ).toBe('https://github.com/HiromiShikata/repo/pull/2474');
770
+ });
771
+
772
+ it('accepts a clean github.com pull URL session name', () => {
701
773
  expect(
702
774
  parseHubTaskIssueUrlFromSessionName(
703
775
  'https://github.com/HiromiShikata/repo/pull/42',
704
776
  ),
777
+ ).toBe('https://github.com/HiromiShikata/repo/pull/42');
778
+ });
779
+
780
+ it('rejects an encoded non-github host or a non-issue/pull path', () => {
781
+ expect(
782
+ parseHubTaskIssueUrlFromSessionName(
783
+ 'https_//example_com/HiromiShikata/repo/issues/42',
784
+ ),
705
785
  ).toBeNull();
706
786
  expect(
707
787
  parseHubTaskIssueUrlFromSessionName(
708
- 'https://example.com/HiromiShikata/repo/issues/42',
788
+ 'https_//github_com/HiromiShikata/repo/discussions/42',
709
789
  ),
710
790
  ).toBeNull();
711
791
  });