session-steward 0.11.1 → 0.12.0
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.
- package/CHANGELOG.md +18 -0
- package/README.md +4 -2
- package/bin/session-steward.mjs +16 -0
- package/dist/assets/index-B8p_9FID.js +9 -0
- package/dist/assets/index-DHWhZO0c.css +2 -0
- package/dist/index.html +2 -2
- package/lib/cleanup-schedules.mjs +7 -0
- package/lib/providers/claude-code/store.mjs +3 -3
- package/lib/providers/codex/database-families.mjs +22 -25
- package/lib/providers/codex/store.mjs +8 -2
- package/lib/self-update.mjs +95 -0
- package/lib/server.mjs +134 -1
- package/lib/update-check.mjs +2 -2
- package/package.json +1 -1
- package/dist/assets/index-BAo7Iw_z.js +0 -9
- package/dist/assets/index-DQxHKbAB.css +0 -2
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@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-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--animate-spin:spin 1s linear infinite;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@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%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, 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;-webkit-text-decoration:inherit;-webkit-text-decoration: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:where(:not(iframe)){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]){appearance:button}::file-selector-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{.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.relative{position:relative}.mx-auto{margin-inline:auto}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-5{height:calc(var(--spacing) * 5)}.h-9{height:calc(var(--spacing) * 9)}.min-h-\[360px\]{min-height:360px}.min-h-screen{min-height:100vh}.w-16{width:calc(var(--spacing) * 16)}.w-32{width:calc(var(--spacing) * 32)}.w-\[min\(50\%\,20rem\)\]{width:min(50%,20rem)}.w-\[min\(75\%\,30rem\)\]{width:min(75%,30rem)}.max-w-\[1380px\]{max-width:1380px}.min-w-0{min-width:0}.min-w-40{min-width:calc(var(--spacing) * 40)}.shrink-0{flex-shrink:0}.animate-spin{animation:var(--animate-spin)}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col-reverse{flex-direction:column-reverse}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-end{justify-content:flex-end}.gap-1{gap:var(--spacing)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-3\.5{gap:calc(var(--spacing) * 3.5)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.rounded{border-radius:.25rem}.rounded-full{border-radius:2147483647px}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.text-left{text-align:left}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}@media (width>=40rem){.sm\:flex{display:flex}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}.sm\:py-8{padding-block:calc(var(--spacing) * 8)}}@media (width>=64rem){.lg\:hidden{display:none}.lg\:grid-cols-\[minmax\(0\,1fr\)_340px\]{grid-template-columns:minmax(0,1fr) 340px}.lg\:px-8{padding-inline:calc(var(--spacing) * 8)}}@media (width>=80rem){.xl\:grid-cols-\[minmax\(0\,1fr\)_420px\]{grid-template-columns:minmax(0,1fr) 420px}}@media (width>=96rem){.\32 xl\:grid-cols-\[minmax\(0\,1fr\)_480px\]{grid-template-columns:minmax(0,1fr) 480px}}}:root{--scrollbar-thumb:#404040;--scrollbar-thumb-hover:#525252;--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;font-synthesis:none;text-rendering:optimizelegibility}*{box-sizing:border-box}html,.app-shell,.app-shell *{scrollbar-color:var(--scrollbar-thumb) transparent;scrollbar-width:thin}html::-webkit-scrollbar{width:8px;height:8px}.app-shell::-webkit-scrollbar{width:8px;height:8px}.app-shell ::-webkit-scrollbar{width:8px;height:8px}html::-webkit-scrollbar-track{background:0 0}.app-shell::-webkit-scrollbar-track{background:0 0}.app-shell ::-webkit-scrollbar-track{background:0 0}html::-webkit-scrollbar-thumb{background:var(--scrollbar-thumb);background-clip:padding-box;border:2px solid #0000;border-radius:999px}.app-shell::-webkit-scrollbar-thumb{background:var(--scrollbar-thumb);background-clip:padding-box;border:2px solid #0000;border-radius:999px}.app-shell ::-webkit-scrollbar-thumb{background:var(--scrollbar-thumb);background-clip:padding-box;border:2px solid #0000;border-radius:999px}html::-webkit-scrollbar-thumb:hover{background-color:var(--scrollbar-thumb-hover)}.app-shell::-webkit-scrollbar-thumb:hover{background-color:var(--scrollbar-thumb-hover)}.app-shell ::-webkit-scrollbar-thumb:hover{background-color:var(--scrollbar-thumb-hover)}body{min-width:320px;margin:0}button,input,select{font:inherit}button{cursor:pointer}button:disabled{cursor:not-allowed}.app-shell{--canvas:#0a0a0a;--surface:#171717;--raised:#262626;--border-subtle:#262626;--border-strong:var(--scrollbar-thumb);--text-primary:#f5f5f5;--text-secondary:#d4d4d4;--text-muted:#a3a3a3;--text-faint:#737373;--accent:#34d399;--accent-soft:#173c2f;--danger:#dc2626;--danger-border:var(--danger)}@supports (color:color-mix(in lab, red, red)){.app-shell{--danger-border:color-mix(in srgb, var(--danger) 40%, var(--border-subtle))}}.app-shell{--danger-text:#fca5a5;--warning:#fbbf24;--success:#34d399;--focus-ring:#d4d4d4;--radius-control:.625rem;--radius-surface:1rem;min-height:100vh;color:var(--text-primary);background:radial-gradient(circle at 50% -12rem, var(--text-primary), transparent 28rem), var(--canvas);position:relative;overflow-x:hidden}@supports (color:color-mix(in lab, red, red)){.app-shell{background:radial-gradient(circle at 50% -12rem, color-mix(in srgb, var(--text-primary) 2%, transparent), transparent 28rem), var(--canvas)}}.app-shell:before{pointer-events:none;content:"";background:linear-gradient(90deg, transparent, var(--border-strong), transparent);height:1px;position:fixed;top:0;left:0;right:0}.app-shell button:focus-visible,.app-shell input:focus-visible,.app-shell select:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}.app-shell ::selection{color:var(--text-primary);background:var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.app-shell ::selection{background:color-mix(in srgb, var(--text-primary) 20%, transparent)}}.text-primary{color:var(--text-primary)}.section-title{color:var(--text-primary);font-size:16px;font-weight:650}.shown-count{color:var(--text-muted);font-variant-numeric:tabular-nums;font-size:13px}.surface{border:1px solid var(--border-strong);border-radius:var(--radius-surface);background:var(--surface);box-shadow:0 1px 0 var(--text-primary) inset, 0 16px 44px var(--canvas)}@supports (color:color-mix(in lab, red, red)){.surface{box-shadow:0 1px 0 color-mix(in srgb, var(--text-primary) 3%, transparent) inset, 0 16px 44px color-mix(in srgb, var(--canvas) 48%, transparent)}}.brand-mark{border:1px solid var(--border-strong);width:2.75rem;height:2.75rem;color:var(--text-secondary);background:linear-gradient(145deg, var(--raised), var(--surface));box-shadow:0 8px 24px var(--canvas);border-radius:.875rem;flex:none;place-items:center;display:grid}@supports (color:color-mix(in lab, red, red)){.brand-mark{box-shadow:0 8px 24px color-mix(in srgb, var(--canvas) 40%, transparent)}}.brand-kicker{color:var(--text-muted);margin-bottom:4px;font-size:12px;font-weight:550}.brand-title{letter-spacing:-.035em;color:var(--text-primary);font-size:28px;font-weight:650;line-height:32px}.provider-switch{background:var(--text-primary);border:0;border-radius:.75rem;gap:3px;padding:3px;display:inline-flex}@supports (color:color-mix(in lab, red, red)){.provider-switch{background:color-mix(in srgb, var(--text-primary) 4%, transparent)}}.provider-switch{box-shadow:0 1px 0 var(--text-primary) inset, 0 8px 24px var(--canvas)}@supports (color:color-mix(in lab, red, red)){.provider-switch{box-shadow:0 1px 0 color-mix(in srgb, var(--text-primary) 5%, transparent) inset, 0 8px 24px color-mix(in srgb, var(--canvas) 32%, transparent)}}.provider-switch button{min-height:33px;color:var(--text-muted);background:0 0;border:0;border-radius:.5rem;align-items:center;gap:6px;padding:0 13px;font-size:12px;font-weight:650;transition:color .15s ease-out,background .15s ease-out,box-shadow .15s ease-out;display:inline-flex}.provider-switch button:hover{color:var(--text-primary)}.provider-switch button[aria-pressed=true]{color:var(--text-primary);background:var(--raised);box-shadow:0 1px 4px var(--canvas)}@supports (color:color-mix(in lab, red, red)){.provider-switch button[aria-pressed=true]{box-shadow:0 1px 4px color-mix(in srgb, var(--canvas) 60%, transparent)}}.provider-icon{flex:none}.provider-context{align-items:center;min-height:36px;margin:-4px 4px 8px;padding:0 4px 4px;display:flex}.provider-context-row,.provider-context-main{min-width:0}.provider-context-main{align-items:center;gap:12px;display:flex}.provider-context-heading{flex:none;align-items:center;gap:8px;display:flex}.provider-context-label{color:var(--text-secondary);font-size:12px;font-weight:650}.provider-context code{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--text-muted);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:12px;overflow:hidden}.provider-context-actions{flex:none;align-items:center;gap:4px;display:flex}.provider-context-editing{border:1px solid var(--border-strong);border-radius:var(--radius-surface);background:var(--raised);box-shadow:0 18px 48px var(--canvas);margin:0 0 12px;padding:16px;display:block}@supports (color:color-mix(in lab, red, red)){.provider-context-editing{box-shadow:0 18px 48px color-mix(in srgb, var(--canvas) 54%, transparent)}}.provider-context-placeholder{border-radius:.75rem;height:48px;margin-bottom:12px}.provider-context-editing .provider-context-main{gap:8px;display:grid}.provider-context-form{border-top:1px solid var(--border-subtle);margin-top:12px;padding-top:12px}.context-and-view{justify-content:space-between;align-items:center;gap:16px;min-width:0;display:flex}.context-and-view .provider-context{flex:auto;min-width:0;margin-top:0}.context-and-view .app-header-actions{flex:none;margin-bottom:8px;margin-left:0}.context-and-view .refresh-button{width:36px;height:36px}.context-and-view .refresh-button svg{width:15px;height:15px}.page-switch{border:1px solid var(--border-subtle);background:var(--raised);border-radius:.65rem;flex:none;gap:2px;margin-bottom:8px;padding:3px;display:inline-flex}@supports (color:color-mix(in lab, red, red)){.page-switch{background:color-mix(in srgb, var(--raised) 25%, transparent)}}.page-switch a{min-height:36px;color:var(--text-muted);white-space:nowrap;border-radius:.45rem;justify-content:center;align-items:center;gap:7px;padding:0 14px;font-size:13px;font-weight:650;text-decoration:none;display:inline-flex}.page-switch a:hover{color:var(--text-primary)}.page-switch a[aria-current=page]{color:var(--text-primary);background:var(--raised);box-shadow:0 1px 4px var(--canvas)}@supports (color:color-mix(in lab, red, red)){.page-switch a[aria-current=page]{box-shadow:0 1px 4px color-mix(in srgb, var(--canvas) 60%, transparent)}}.page-switch a[aria-disabled=true]{cursor:not-allowed;opacity:.5}.page-switch a:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}.compact-action{border-radius:var(--radius-control);min-height:28px;color:var(--text-muted);background:0 0;border:0;padding:4px 8px;font-size:11px;font-weight:650}.compact-action:hover:not(:disabled){color:var(--text-primary);background:var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.compact-action:hover:not(:disabled){background:color-mix(in srgb, var(--text-primary) 6%, transparent)}}.compact-action:disabled{opacity:.42}.source-badge{border:1px solid var(--border-strong);color:var(--text-muted);background:var(--surface);border-radius:999px;padding:2px 8px;font-size:11px;font-weight:650}.overview-strip{--overview-columns:5;border-top:1px solid var(--border-subtle);border-bottom:1px solid var(--border-subtle);grid-template-columns:repeat(2,minmax(0,1fr));margin-bottom:16px;display:grid}.overview-item{min-width:0;color:var(--text-muted);grid-template-columns:auto minmax(0,1fr);align-items:center;gap:8px;padding:8px 12px 12px;display:grid}.overview-item-primary{color:var(--text-secondary);grid-column:1/-1}.overview-item:not(.overview-item-primary):nth-child(2n){border-right:1px solid var(--border-subtle)}.overview-strip>.overview-item:last-child{border-right:0}.overview-label{text-overflow:ellipsis;white-space:nowrap;color:var(--text-muted);font-size:11px;font-weight:600;line-height:16px;overflow:hidden}.overview-value{letter-spacing:-.015em;text-overflow:ellipsis;white-space:nowrap;color:var(--text-secondary);font-variant-numeric:tabular-nums;font-size:16px;font-weight:650;line-height:20px;overflow:hidden}.overview-item-primary .overview-value{color:var(--text-primary);font-size:20px;line-height:24px}.panel-label{color:var(--text-secondary);font-size:12px;font-weight:650}.cleanup-eyebrow{letter-spacing:.12em;text-transform:uppercase;color:var(--danger-text);align-items:center;gap:8px;margin-bottom:8px;font-size:11px;font-weight:700;display:flex}.button{border-radius:var(--radius-control);border:1px solid #0000;justify-content:center;align-items:center;gap:8px;min-height:36px;padding:8px 12px;font-size:13px;font-weight:650;line-height:16px;display:inline-flex}.button:disabled{opacity:.42}.button.secondary{border-color:var(--border-strong);color:var(--text-primary);background:var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.button.secondary{background:color-mix(in srgb, var(--text-primary) 6%, transparent)}}.button.secondary:hover:not(:disabled){background:var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.button.secondary:hover:not(:disabled){background:color-mix(in srgb, var(--text-primary) 10%, transparent)}}.button.ghost{border-color:var(--border-subtle);color:var(--text-secondary);background:0 0}.button.ghost:hover:not(:disabled){border-color:var(--border-strong);color:var(--text-primary);background:var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.button.ghost:hover:not(:disabled){background:color-mix(in srgb, var(--text-primary) 5%, transparent)}}.button.primary{border-color:var(--focus-ring);color:var(--canvas);background:var(--focus-ring);box-shadow:0 8px 24px var(--canvas)}@supports (color:color-mix(in lab, red, red)){.button.primary{box-shadow:0 8px 24px color-mix(in srgb, var(--canvas) 46%, transparent)}}.button.primary:hover:not(:disabled){background:var(--text-primary)}.button.keep-action{border-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.button.keep-action{border-color:color-mix(in srgb, var(--accent) 34%, var(--border-subtle))}}.button.keep-action{color:var(--accent);background:var(--accent)}@supports (color:color-mix(in lab, red, red)){.button.keep-action{background:color-mix(in srgb, var(--accent) 8%, transparent)}}.button.keep-action:hover:not(:disabled){border-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.button.keep-action:hover:not(:disabled){border-color:color-mix(in srgb, var(--accent) 56%, var(--border-strong))}}.button.keep-action:hover:not(:disabled){background:var(--accent)}@supports (color:color-mix(in lab, red, red)){.button.keep-action:hover:not(:disabled){background:color-mix(in srgb, var(--accent) 13%, transparent)}}.button.danger{border-color:var(--danger);color:#fff;background:var(--danger);box-shadow:0 8px 24px var(--danger)}@supports (color:color-mix(in lab, red, red)){.button.danger{box-shadow:0 8px 24px color-mix(in srgb, var(--danger) 18%, transparent)}}.button.danger:hover:not(:disabled){background:#b91c1c;border-color:#b91c1c}.icon-button{border-radius:var(--radius-control);width:32px;height:32px;color:var(--text-muted);background:0 0;border:1px solid #0000;flex:none;place-items:center;display:grid}.icon-button:hover:not(:disabled){border-color:var(--border-strong);color:var(--text-primary);background:var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.icon-button:hover:not(:disabled){background:color-mix(in srgb, var(--text-primary) 6%, transparent)}}.refresh-button{border-color:var(--border-subtle);background:var(--surface);width:40px;height:40px}.status-pill{border:1px solid;border-radius:999px;align-items:center;gap:8px;min-height:28px;padding:4px 8px;font-size:11px;font-weight:650;display:inline-flex}.status-pill:hover{filter:brightness(1.12)}.status-pill>span{background:currentColor;border-radius:999px;width:6px;height:6px}.status-ready{border-color:var(--success)}@supports (color:color-mix(in lab, red, red)){.status-ready{border-color:color-mix(in srgb, var(--success) 28%, transparent)}}.status-ready{color:var(--success);background:var(--success)}@supports (color:color-mix(in lab, red, red)){.status-ready{background:color-mix(in srgb, var(--success) 8%, transparent)}}.status-partial{border-color:var(--border-subtle);color:var(--text-secondary);background:var(--surface)}.status-warning{border-color:var(--warning)}@supports (color:color-mix(in lab, red, red)){.status-warning{border-color:color-mix(in srgb, var(--warning) 28%, transparent)}}.status-warning{color:var(--warning);background:var(--warning)}@supports (color:color-mix(in lab, red, red)){.status-warning{background:color-mix(in srgb, var(--warning) 8%, transparent)}}.status-error{border-color:var(--danger-border);color:var(--danger-text);background:var(--danger)}@supports (color:color-mix(in lab, red, red)){.status-error{background:color-mix(in srgb, var(--danger) 8%, transparent)}}.field{min-width:0;color:var(--text-muted);gap:4px;font-size:12px;font-weight:650;display:grid}.field>span{align-items:center;gap:4px;display:flex}.field input,.field select,.input-wrap,.sort-control select{border:1px solid var(--border-subtle);border-radius:var(--radius-control);width:100%;min-height:40px;color:var(--text-primary);background-color:var(--raised)}@supports (color:color-mix(in lab, red, red)){.field input,.field select,.input-wrap,.sort-control select{background-color:color-mix(in srgb, var(--raised) 18%, var(--canvas))}}.field input,.field select,.input-wrap,.sort-control select{box-shadow:inset 0 1px 0 var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.field input,.field select,.input-wrap,.sort-control select{box-shadow:inset 0 1px 0 color-mix(in srgb, var(--text-primary) 3%, transparent)}}.field>input{padding:8px 12px}.field select,.sort-control select{appearance:none;background-image:linear-gradient(45deg, transparent 50%, var(--text-muted) 50%), linear-gradient(135deg, var(--text-muted) 50%, transparent 50%);text-overflow:ellipsis;white-space:nowrap;background-position:calc(100% - 15px) 17px,calc(100% - 11px) 17px;background-repeat:no-repeat;background-size:4px 4px,4px 4px;padding:8px 36px 8px 12px;overflow:hidden}.field input::placeholder{color:var(--text-muted)}.field input:hover,.field select:hover,.input-wrap:hover,.sort-control select:hover{border-color:var(--border-strong)}.field input:focus,.field select:focus,.input-wrap:focus-within,.sort-control select:focus{border-color:var(--text-secondary)}@supports (color:color-mix(in lab, red, red)){.field input:focus,.field select:focus,.input-wrap:focus-within,.sort-control select:focus{border-color:color-mix(in srgb, var(--text-secondary) 58%, var(--border-strong))}}.field input:focus,.field select:focus,.input-wrap:focus-within,.sort-control select:focus{background-color:var(--canvas);box-shadow:0 0 0 3px var(--focus-ring), inset 0 1px 0 var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.field input:focus,.field select:focus,.input-wrap:focus-within,.sort-control select:focus{box-shadow:0 0 0 3px color-mix(in srgb, var(--focus-ring) 7%, transparent), inset 0 1px 0 color-mix(in srgb, var(--text-primary) 3%, transparent)}}.input-wrap{color:var(--text-muted);grid-template-columns:auto minmax(0,1fr) auto;align-items:center;padding:0 12px;display:grid}.input-wrap input{min-height:auto;box-shadow:none;background:0 0;border:0;border-radius:0;outline:0;padding:8px}.app-shell .input-wrap input:focus-visible{outline:0}.input-wrap button{color:var(--text-muted);background:0 0;border:0;place-items:center;display:grid}.session-list-header{border-bottom:1px solid var(--border-subtle);flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;min-height:60px;padding:12px 16px;display:flex}.collection-heading{flex-wrap:wrap;align-items:center;gap:10px;min-width:0;display:flex}.collection-switch{border:1px solid var(--border-subtle);background:var(--raised);border-radius:999px;align-items:center;gap:2px;padding:2px;display:inline-flex}@supports (color:color-mix(in lab, red, red)){.collection-switch{background:color-mix(in srgb, var(--raised) 30%, transparent)}}.collection-switch button{min-height:28px;color:var(--text-muted);background:0 0;border:0;border-radius:999px;align-items:center;gap:5px;padding:4px 10px;font-size:11px;font-weight:650;transition:color .12s ease-out,background .12s ease-out,box-shadow .12s ease-out;display:inline-flex}.collection-switch button:hover{color:var(--text-primary)}.collection-switch button[aria-pressed=true]{color:var(--text-primary);background:var(--raised);box-shadow:0 1px 3px var(--canvas), inset 0 1px 0 var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.collection-switch button[aria-pressed=true]{box-shadow:0 1px 3px color-mix(in srgb, var(--canvas) 52%, transparent), inset 0 1px 0 color-mix(in srgb, var(--text-primary) 5%, transparent)}}.kept-view-switch{border-bottom:1px solid var(--border-subtle);background:var(--surface);gap:20px;padding:0 16px;display:flex}@supports (color:color-mix(in lab, red, red)){.kept-view-switch{background:color-mix(in srgb, var(--surface) 90%, var(--canvas))}}.kept-view-switch button{min-height:44px;color:var(--text-muted);background:0 0;border:0;padding:0 1px;font-size:12px;font-weight:650;position:relative}.kept-view-switch button:hover,.kept-view-switch button[aria-pressed=true]{color:var(--text-primary)}.kept-view-switch button[aria-pressed=true]:after{background:var(--accent);content:"";border-radius:999px 999px 0 0;height:2px;position:absolute;bottom:-1px;left:0;right:0}.session-list-tools{align-items:center;gap:12px;display:flex}.sort-control{color:var(--text-muted);align-items:center;gap:8px;font-size:11px;font-weight:650;display:flex}.sort-control select{background-position:calc(100% - 15px) 13px,calc(100% - 11px) 13px;width:132px;min-height:32px;padding-top:4px;padding-bottom:4px;font-size:12px}.shortcut-hint{color:var(--text-muted);font-size:11px;display:none}.shortcut-hint kbd{border:1px solid var(--border-strong);background:var(--raised);color:var(--text-secondary);border-radius:.375rem;margin:0 4px;padding:1px 6px;font-family:inherit;font-size:11px}.session-filters{--filter-grid:minmax(0, 1fr) auto;border-bottom:1px solid var(--border-subtle);background:var(--surface);position:relative}@supports (color:color-mix(in lab, red, red)){.session-filters{background:color-mix(in srgb, var(--surface) 88%, var(--canvas))}}.filter-bar,.more-filters-row{grid-template-columns:var(--filter-grid);align-items:end;gap:12px;min-width:0;padding:12px 16px;display:grid}.filter-search{min-width:0}.filter-primary-controls,.filter-overflow-primary,.filter-overflow-controls{display:contents}.more-filters-wrap{min-width:0}.more-filters-button{border:1px solid var(--border-subtle);border-radius:var(--radius-control);min-height:40px;color:var(--text-secondary);background:var(--raised);align-items:center;gap:8px;padding:8px 12px;display:inline-flex}@supports (color:color-mix(in lab, red, red)){.more-filters-button{background:color-mix(in srgb, var(--raised) 18%, var(--canvas))}}.more-filters-button{box-shadow:inset 0 1px 0 var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.more-filters-button{box-shadow:inset 0 1px 0 color-mix(in srgb, var(--text-primary) 3%, transparent)}}.more-filters-button{white-space:nowrap;font-size:12px;font-weight:650}.more-filters-button:hover{border-color:var(--border-strong);color:var(--text-primary);background:var(--raised)}.more-filters-active{border-color:var(--border-strong);color:var(--text-primary)}.more-filters-button strong{min-width:20px;height:20px;color:var(--canvas);background:var(--text-secondary);font-variant-numeric:tabular-nums;border-radius:999px;place-items:center;font-size:11px;display:grid}.more-filters-row{border-top:1px solid var(--border-subtle);animation:.15s ease-out disclosure-in}.active-filter-row{border-top:1px solid var(--border-subtle);justify-content:space-between;align-items:center;gap:12px;min-height:44px;padding:8px 16px;display:flex}.active-filter-chips{flex-wrap:wrap;gap:8px;min-width:0;display:flex}.filter-chip{border:1px solid var(--border-strong);max-width:300px;min-height:28px;color:var(--text-secondary);background:var(--raised);border-radius:999px;align-items:center;gap:8px;padding:4px 8px 4px 12px;font-size:11px;transition:border-color .12s ease-out,background .12s ease-out;display:inline-flex}.filter-chip span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.filter-chip:hover{border-color:var(--focus-ring)}.filter-chip-exiting{pointer-events:none}.clear-all-filters{color:var(--text-muted);background:0 0;border:0;flex:none;padding:4px;font-size:11px;font-weight:650}.clear-all-filters:hover{color:var(--text-primary)}.unknown-activity-note{border-top:1px solid var(--border-subtle);color:var(--text-muted);padding:8px 16px;font-size:11px;line-height:16px}.toggle{cursor:pointer;border:1px solid var(--border-subtle);border-radius:var(--radius-control);min-width:0;min-height:40px;color:var(--text-secondary);background:var(--raised);align-items:center;gap:8px;padding:8px 12px;display:inline-flex}@supports (color:color-mix(in lab, red, red)){.toggle{background:color-mix(in srgb, var(--raised) 18%, var(--canvas))}}.toggle{box-shadow:inset 0 1px 0 var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.toggle{box-shadow:inset 0 1px 0 color-mix(in srgb, var(--text-primary) 3%, transparent)}}.toggle{font-size:12px;font-weight:600;transition:border-color .15s ease-out,background .15s ease-out,color .15s ease-out}.toggle:hover{border-color:var(--border-strong);color:var(--text-primary)}.toggle input{opacity:0;pointer-events:none;position:absolute}.toggle-track{background:var(--border-strong);border-radius:999px;flex:none;width:28px;height:16px;transition:background .15s ease-out;position:relative}.toggle-track span{background:var(--text-muted);border-radius:999px;width:10px;height:10px;transition:left .15s ease-out,background .15s ease-out;position:absolute;top:3px;left:3px}.toggle-copy{white-space:nowrap;align-items:center;gap:6px;min-width:0;display:flex}.toggle-copy>span{text-overflow:ellipsis;overflow:hidden}.toggle-active{border-color:var(--border-strong);color:var(--text-primary);background:var(--raised)}.toggle-active .toggle-track{background:var(--text-secondary)}.toggle-active .toggle-track span{background:var(--canvas);left:15px}.page-selection-row{border-bottom:1px solid var(--border-subtle);background:var(--text-primary);justify-content:space-between;align-items:center;gap:12px;min-height:44px;padding:8px 16px;display:flex}@supports (color:color-mix(in lab, red, red)){.page-selection-row{background:color-mix(in srgb, var(--text-primary) 1.5%, transparent)}}.selection-guidance{color:var(--text-muted);text-align:right;font-size:11px}.selection-control{cursor:pointer;color:var(--text-secondary);align-items:center;gap:8px;font-size:12px;font-weight:600;display:inline-flex}.selection-control input,.session-checkbox input{width:16px;height:16px;accent-color:var(--accent);margin:0}.session-row-block+.session-row-block{border-top:1px solid var(--border-subtle)}.session-row-block-grouped{border-top:0!important}.session-rows>.session-row+.session-row{border-top:1px solid var(--border-subtle)}.date-separator{min-height:30px;color:var(--text-faint);letter-spacing:.035em;align-items:center;gap:10px;padding:6px 16px;font-size:10px;font-weight:650;line-height:16px;display:flex}.date-separator-line{background:var(--border-subtle);flex:auto;height:1px}.session-row{grid-template-columns:32px minmax(0,1fr) auto auto;align-items:center;gap:8px;min-height:60px;padding:8px 16px;transition:background .12s ease-out,box-shadow .12s ease-out;display:grid;position:relative}.session-row:hover{background:var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.session-row:hover{background:color-mix(in srgb, var(--text-primary) 3%, transparent)}}.session-row-cursor:before{background:var(--text-primary);content:"";width:2px;height:28px;box-shadow:0 0 10px var(--text-primary);border-radius:999px;position:absolute;top:50%;left:3px;transform:translateY(-50%)}@supports (color:color-mix(in lab, red, red)){.session-row-cursor:before{box-shadow:0 0 10px color-mix(in srgb, var(--text-primary) 18%, transparent)}}.session-row-inspected{background:var(--accent)}@supports (color:color-mix(in lab, red, red)){.session-row-inspected{background:color-mix(in srgb, var(--accent) 10%, transparent)}}.session-row-selected{background:var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.session-row-selected{background:color-mix(in srgb, var(--text-primary) 6%, transparent)}}.session-row-kept{box-shadow:inset 2px 0 var(--accent)}@supports (color:color-mix(in lab, red, red)){.session-row-kept{box-shadow:inset 2px 0 color-mix(in srgb, var(--accent) 55%, transparent)}}.session-row-inspected.session-row-selected{background:var(--accent)}@supports (color:color-mix(in lab, red, red)){.session-row-inspected.session-row-selected{background:color-mix(in srgb, var(--accent) 12%, transparent)}}.session-checkbox{cursor:pointer;border-radius:var(--radius-control);place-items:center;width:40px;height:40px;margin:-4px;display:grid}.session-checkbox:hover{background:var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.session-checkbox:hover{background:color-mix(in srgb, var(--text-primary) 6%, transparent)}}.session-checkbox:focus-within{background:var(--focus-ring)}@supports (color:color-mix(in lab, red, red)){.session-checkbox:focus-within{background:color-mix(in srgb, var(--focus-ring) 8%, transparent)}}.session-checkbox:focus-within{box-shadow:0 0 0 2px var(--focus-ring)}@supports (color:color-mix(in lab, red, red)){.session-checkbox:focus-within{box-shadow:0 0 0 2px color-mix(in srgb, var(--focus-ring) 22%, transparent)}}.session-primary{min-width:0}.session-open{width:100%;min-width:0;color:inherit;background:0 0;border:0;padding:0;display:block}.session-context{align-items:center;gap:4px;min-width:0;margin-top:4px;display:flex}.session-title{color:var(--text-primary);text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:500;line-height:20px;display:block;overflow:hidden}.session-workspace{min-width:0;color:var(--text-muted);background:0 0;border:0;align-items:center;gap:4px;padding:0;font-size:12px;line-height:16px;display:flex}.session-workspace:hover{color:var(--text-secondary)}.session-row-meta{flex-direction:row;flex:none;justify-content:flex-end;align-items:center;gap:4px;display:flex}.time-badge,.kind-label,.size-badge,.archive-tag{border:1px solid var(--border-subtle);min-height:22px;color:var(--text-muted);background:var(--text-primary);border-radius:999px;align-items:center;gap:4px;padding:2px 6px;display:inline-flex}@supports (color:color-mix(in lab, red, red)){.time-badge,.kind-label,.size-badge,.archive-tag{background:color-mix(in srgb, var(--text-primary) 3%, transparent)}}.time-badge,.kind-label,.size-badge,.archive-tag{white-space:nowrap;font-size:11px;font-weight:600;line-height:16px}.archive-tag{min-height:20px;padding:1px 6px}.keep-tag{border:1px solid var(--accent);align-items:center;gap:4px;min-height:20px;display:inline-flex}@supports (color:color-mix(in lab, red, red)){.keep-tag{border:1px solid color-mix(in srgb, var(--accent) 35%, var(--border-subtle))}}.keep-tag{color:var(--accent);background:var(--accent);border-radius:999px;padding:1px 6px}@supports (color:color-mix(in lab, red, red)){.keep-tag{background:color-mix(in srgb, var(--accent) 8%, transparent)}}.keep-tag{white-space:nowrap;font-size:11px;font-weight:600;line-height:16px}.keep-tag-action{flex:none;transition:border-color .12s ease-out,background .12s ease-out}.keep-tag-action:hover:not(:disabled){border-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.keep-tag-action:hover:not(:disabled){border-color:color-mix(in srgb, var(--accent) 60%, var(--border-strong))}}.keep-tag-action:hover:not(:disabled){background:var(--accent)}@supports (color:color-mix(in lab, red, red)){.keep-tag-action:hover:not(:disabled){background:color-mix(in srgb, var(--accent) 14%, transparent)}}.keep-tag-action:focus-visible{box-shadow:0 0 0 3px var(--accent);outline:0}@supports (color:color-mix(in lab, red, red)){.keep-tag-action:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent)}}.session-row-chevron{color:var(--text-faint);flex:none;display:none}.session-row:hover .session-row-chevron{color:var(--text-muted);transform:translate(2px)}.session-row-chevron{transition:color .12s ease-out,transform .12s ease-out}.session-row-skeleton{grid-template-columns:32px minmax(0,1fr) auto auto}.badge-skeleton{border-radius:999px;width:56px;height:22px}.inspector{display:none;overflow:hidden}.inspector-backdrop{display:none}.inspector-header{border-bottom:1px solid var(--border-subtle);justify-content:space-between;align-items:center;padding:16px 20px;display:flex}.inspector-content{padding:20px}.inspector-title{overflow-wrap:anywhere;-webkit-line-clamp:2;color:var(--text-primary);-webkit-box-orient:vertical;font-size:14px;font-weight:500;line-height:20px;display:-webkit-box;overflow:hidden}.keep-controls{border-top:1px solid var(--border-subtle);margin-top:16px;padding-top:14px}.keep-control-actions{flex-wrap:wrap;gap:8px;display:flex}.keep-controls p{color:var(--text-muted);margin-top:9px;font-size:11px;line-height:17px}.workspace-rules-view{background:var(--surface)}@supports (color:color-mix(in lab, red, red)){.workspace-rules-view{background:color-mix(in srgb, var(--surface) 94%, var(--canvas))}}.workspace-rules-toolbar{border-bottom:1px solid var(--border-subtle);justify-content:flex-start;align-items:center;min-height:64px;padding:12px 16px;display:flex}.workspace-rule-search{border:1px solid var(--border-subtle);border-radius:var(--radius-control);width:min(360px,100%);color:var(--text-muted);background:var(--canvas);grid-template-columns:auto minmax(0,1fr) auto;align-items:center;padding:0 11px;display:grid}.workspace-rule-search:focus-within{border-color:var(--text-secondary)}@supports (color:color-mix(in lab, red, red)){.workspace-rule-search:focus-within{border-color:color-mix(in srgb, var(--text-secondary) 58%, var(--border-strong))}}.workspace-rule-search:focus-within{box-shadow:0 0 0 3px var(--focus-ring)}@supports (color:color-mix(in lab, red, red)){.workspace-rule-search:focus-within{box-shadow:0 0 0 3px color-mix(in srgb, var(--focus-ring) 7%, transparent)}}.workspace-rule-search input{min-width:0;min-height:38px;box-shadow:none;background:0 0;border:0;outline:0;padding:8px;font-size:12px}.app-shell .workspace-rule-search input:focus,.app-shell .workspace-rule-search input:focus-visible{box-shadow:none;border:0;outline:0}.workspace-rule-search button{color:var(--text-muted);background:0 0;border:0;place-items:center;display:grid}.workspace-rule-list{background:var(--surface)}.workspace-rule-row{border-bottom:1px solid var(--border-subtle);grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:12px;min-height:72px;padding:10px 16px;display:grid}.workspace-rule-row:hover{background:var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.workspace-rule-row:hover{background:color-mix(in srgb, var(--text-primary) 3%, transparent)}}.workspace-rule-icon{border:1px solid var(--accent);place-items:center;width:34px;height:34px;display:grid}@supports (color:color-mix(in lab, red, red)){.workspace-rule-icon{border:1px solid color-mix(in srgb, var(--accent) 24%, var(--border-subtle))}}.workspace-rule-icon{color:var(--accent);background:var(--accent);border-radius:.625rem}@supports (color:color-mix(in lab, red, red)){.workspace-rule-icon{background:color-mix(in srgb, var(--accent) 7%, transparent)}}.workspace-rule-row strong,.workspace-rule-row code,.workspace-rule-row span{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.workspace-rule-row strong{color:var(--text-primary);font-size:13px;font-weight:600}.workspace-rule-row code{color:var(--text-secondary);margin-top:2px;font-size:11px}.workspace-rule-row span{color:var(--text-faint);margin-top:3px;font-size:10px}.inspector-id{overflow-wrap:anywhere;color:var(--text-muted);margin-top:4px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:11px;line-height:16px}.inspector-chips{flex-wrap:wrap;gap:6px;margin:14px 0 0;padding:0;list-style:none;display:flex}.inspector-chip{color:var(--text-secondary);background:var(--raised);border-radius:999px;padding:4px 10px;font-size:11px;font-weight:600;line-height:16px}.inspector-details{grid-template-columns:repeat(2,minmax(0,1fr));gap:18px 16px;margin-top:20px;display:grid}.detail-row-wide{grid-column:1/-1}.detail-row dt{color:var(--text-muted);font-size:11px;font-weight:650;line-height:16px}.detail-row dd{overflow-wrap:anywhere;color:var(--text-secondary);margin-top:4px;font-size:13px;line-height:20px}.inspector-empty{text-align:center;place-items:center;min-height:260px;padding:28px;display:grid}.inspector-empty-icon{width:40px;height:40px;color:var(--text-faint);place-items:center;margin:0 auto;display:grid}.inspector-empty h2{color:var(--text-secondary);margin-top:8px;font-size:13px;font-weight:600}.inspector-empty p{max-width:220px;color:var(--text-muted);margin:8px auto 0;font-size:12px;line-height:16px}.related-sessions,.session-timeline{border-top:1px solid var(--border-subtle)}.inspector-tabs{border-top:1px solid var(--border-subtle);border-bottom:1px solid var(--border-subtle);align-items:stretch;gap:20px;padding:0 20px;display:flex}.inspector-tabs button{min-height:40px;color:var(--text-muted);background:0 0;border:0;padding:0;font-size:12px;font-weight:650;transition:color .15s ease-out;position:relative}.inspector-tabs button:hover{color:var(--text-secondary)}.inspector-tabs button[aria-selected=true]{color:var(--text-primary)}.inspector-tabs button[aria-selected=true]:after{content:"";background:var(--accent);border-radius:999px 999px 0 0;height:2px;position:absolute;bottom:-1px;left:0;right:0}.inspector-tab-count{color:var(--text-muted);font-variant-numeric:tabular-nums;margin-left:6px;font-weight:600}.inspector-tabpanel[hidden]{display:none}.inspector-tabpanel:focus-visible{outline:2px solid var(--focus-ring);outline-offset:-2px}.inspector-tabpanel>.related-sessions,.inspector-tabpanel>.session-timeline{border-top:0}.timeline-heading{justify-content:space-between;align-items:center;gap:12px;padding:16px 20px;display:flex}.timeline-heading>div>p:not(.panel-label){color:var(--text-muted);margin-top:3px;font-size:11px;line-height:16px}.related-session-list{border-top:1px solid var(--border-subtle)}.related-session-list button{border:0;border-bottom:1px solid var(--border-subtle);width:100%;min-width:0;color:var(--text-muted);text-align:left;background:0 0;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:8px;padding:10px 20px;display:grid}.related-session-list button:hover{color:var(--text-primary);background:var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.related-session-list button:hover{background:color-mix(in srgb, var(--text-primary) 3%, transparent)}}.related-session-copy{gap:2px;min-width:0;display:grid;overflow:hidden}.related-session-copy strong,.related-session-copy small,.related-session-copy code{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.related-session-copy strong{color:var(--text-secondary);font-size:11px;font-weight:600;line-height:16px}.related-session-copy small{color:var(--text-muted);font-size:10px;line-height:15px}.related-session-copy code{color:var(--text-faint);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:9px;line-height:14px}.timeline-region{border-top:1px solid var(--border-subtle);min-height:112px;position:relative}.timeline-initial-loading{min-height:112px;color:var(--text-muted);justify-content:center;align-items:center;gap:8px;font-size:12px;font-weight:600;display:flex}.timeline-events{display:grid}.timeline-event{border-bottom:1px solid var(--border-subtle);background:var(--text-primary);min-width:0;padding:14px 20px}@supports (color:color-mix(in lab, red, red)){.timeline-event{background:color-mix(in srgb, var(--text-primary) 1.5%, transparent)}}.timeline-event header{justify-content:space-between;align-items:center;gap:12px;margin-bottom:8px;display:flex}.timeline-event header span{border:1px solid var(--border-subtle);min-height:20px;color:var(--text-secondary);background:var(--raised);letter-spacing:.07em;text-transform:uppercase;border-radius:999px;align-items:center;padding:1px 7px;font-size:9px;font-weight:750;line-height:16px;display:inline-flex}.timeline-event time{color:var(--text-faint);font-size:10px;line-height:16px}.timeline-event-ran,.timeline-event-edit{background:0 0;padding-top:10px;padding-bottom:10px}.timeline-event-ran header,.timeline-event-edit header{margin-bottom:6px}.timeline-event-failed{border-color:var(--danger-border);background:var(--danger)}@supports (color:color-mix(in lab, red, red)){.timeline-event-failed{background:color-mix(in srgb, var(--danger) 7%, var(--surface))}}.timeline-event-failed header span,.timeline-event-failed .timeline-event-meta{color:var(--danger-text)}.timeline-event-copy p{overflow-wrap:anywhere;color:var(--text-secondary);white-space:pre-wrap;font-size:12px;line-height:19px}.timeline-event-ask{border:1px solid var(--border-strong);border-radius:var(--radius-control);background:var(--raised);justify-self:end;width:fit-content;max-width:85%;margin:12px 20px;padding:14px 16px}.timeline-event-ask header span{border-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.timeline-event-ask header span{border-color:color-mix(in srgb, var(--accent) 34%, transparent)}}.timeline-event-ask header span{color:var(--accent);background:var(--accent)}@supports (color:color-mix(in lab, red, red)){.timeline-event-ask header span{background:color-mix(in srgb, var(--accent) 16%, transparent)}}.timeline-event-said{padding-top:18px;padding-bottom:18px}.timeline-event-ask.timeline-event-injected{border-color:var(--border-subtle);background:var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.timeline-event-ask.timeline-event-injected{background:color-mix(in srgb, var(--text-primary) 4%, var(--surface))}}.timeline-event-ask.timeline-event-injected header span{border-color:var(--border-subtle);color:var(--text-secondary);background:var(--raised)}.timeline-event-ask .timeline-event-copy p,.timeline-event-said .timeline-event-copy p{color:var(--text-primary);font-size:13px;font-weight:500;line-height:21px}.timeline-event-copy button,.timeline-scroll-copy button{color:var(--text-muted);background:0 0;border:0;margin-top:7px;padding:0;font-size:11px;font-weight:650}.timeline-event-copy button:hover,.timeline-scroll-copy button:hover{color:var(--text-primary)}.timeline-event-copy span{color:var(--text-faint);margin-top:5px;font-size:10px;display:block}.timeline-scroll-copy{min-width:0}.timeline-scroll-copy>div{max-width:100%;color:var(--text-secondary);white-space:pre;padding-bottom:3px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:11px;line-height:18px;overflow-x:auto}.timeline-event-meta,.timeline-plan-summary{color:var(--text-muted);margin-top:8px;font-size:11px;line-height:17px}.timeline-secondary-value{min-width:0;margin-top:9px}.timeline-secondary-value>span{color:var(--text-faint);margin-bottom:4px;font-size:10px;font-weight:650;line-height:16px;display:block}.injected-events-toggle,.timeline-more{border:0;border-bottom:1px solid var(--border-subtle);width:100%;color:var(--text-muted);background:var(--text-primary);padding:10px 20px}@supports (color:color-mix(in lab, red, red)){.injected-events-toggle,.timeline-more{background:color-mix(in srgb, var(--text-primary) 2%, transparent)}}.injected-events-toggle,.timeline-more{text-align:left;font-size:11px;font-weight:650}.injected-events-toggle:hover,.timeline-more:hover:not(:disabled){color:var(--text-primary);background:var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.injected-events-toggle:hover,.timeline-more:hover:not(:disabled){background:color-mix(in srgb, var(--text-primary) 4%, transparent)}}.timeline-more{text-align:center}.timeline-more:disabled{opacity:.65}.timeline-coverage{color:var(--text-faint);padding:10px 20px;font-size:10px;line-height:16px}.timeline-coverage p+p{overflow-wrap:anywhere;margin-top:3px}.timeline-coverage-notice{border:1px solid var(--border-subtle);color:var(--text-secondary);background:var(--surface);border-radius:.625rem;align-items:flex-start;gap:9px;margin:12px;padding:11px;display:flex}.timeline-coverage-notice>svg{color:var(--text-muted);flex:none;margin-top:1px}.timeline-coverage-notice strong{font-size:12px;font-weight:650}.timeline-coverage-notice p{color:var(--text-muted);margin-top:3px;font-size:10px;line-height:16px}.timeline-empty{min-height:180px;color:var(--text-faint);text-align:center;align-content:center;place-items:center;padding:24px;display:grid}.timeline-empty h3{color:var(--text-secondary);margin-top:10px;font-size:13px;font-weight:650}.timeline-empty p{max-width:320px;color:var(--text-muted);margin-top:6px;font-size:11px;line-height:17px}.timeline-empty .button{margin-top:14px}.timeline-quiet-empty{color:var(--text-muted);text-align:center;padding:16px 20px;font-size:11px}.composition{--token-cachedInput:#199e70;--token-freshInput:#3987e5;--token-cacheWrites:#c98500;--token-output:#9085e9;--segment-toolOutput:#3987e5;--segment-largeRecords:#d95926;--segment-compaction:#199e70;--segment-attachments:#c98500;--segment-messages:#d55181;--segment-edits:#008300;--segment-reasoning:#9085e9;--segment-other:#737373;border-top:1px solid var(--border-subtle);padding:16px 20px}.composition-heading{justify-content:space-between;align-items:baseline;gap:12px;margin-bottom:10px;display:flex}.composition-heading>p:last-child{color:var(--text-secondary);font-variant-numeric:tabular-nums;font-size:12px;font-weight:650}.composition-bar{gap:2px;height:10px;display:flex}.composition-segment{border-radius:2px;min-width:3px;transition:opacity .15s ease-out}.composition-segment:first-child{border-radius:4px 2px 2px 4px}.composition-segment:last-child{border-radius:2px 4px 4px 2px}.composition-segment-muted{opacity:.26}.composition-legend{gap:1px;margin-top:12px;display:grid}.composition-legend-row{border-radius:6px;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;margin:0 -6px;padding:3px 6px;transition:background .15s ease-out,opacity .15s ease-out;display:flex}.composition-legend-row:hover{background:var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.composition-legend-row:hover{background:color-mix(in srgb, var(--text-primary) 4%, transparent)}}.composition-legend-row dt{min-width:0;color:var(--text-secondary);text-overflow:ellipsis;white-space:nowrap;align-items:center;gap:8px;font-size:12px;line-height:18px;display:flex;overflow:hidden}.composition-legend-row dd{color:var(--text-primary);font-variant-numeric:tabular-nums;flex:none;align-items:baseline;gap:8px;font-size:12px;font-weight:600;line-height:18px;display:flex}.composition-legend-row dd span{min-width:30px;color:var(--text-muted);text-align:right;font-weight:500}.composition-swatch{border-radius:2px;flex:none;width:8px;height:8px}.skeleton{vertical-align:-.15em;background:linear-gradient(90deg, var(--raised) 0%, var(--text-primary) 50%, var(--raised) 100%) 0 0 / 200% 100%;border-radius:4px;min-width:24px;height:1em;display:inline-block}@supports (color:color-mix(in lab, red, red)){.skeleton{background:linear-gradient(90deg, var(--raised) 0%, color-mix(in srgb, var(--text-primary) 12%, var(--raised)) 50%, var(--raised) 100%) 0 0 / 200% 100%}}.skeleton{animation:1.5s ease-in-out infinite skeleton-wave}.composition-bar .skeleton{border-radius:2px;height:10px}.composition-swatch.skeleton{min-width:0;height:8px}@keyframes skeleton-wave{0%{background-position:150% 0}to{background-position:-50% 0}}@media (prefers-reduced-motion:reduce){.skeleton{background:var(--raised);animation:none}}.app-header{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:16px;min-height:44px;display:flex}.app-header-leading{align-items:center;min-width:0;display:flex}.app-header-actions{flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:8px;margin-left:auto;display:flex}.app-header .page-switch{margin-bottom:0}.schedule-page{margin-bottom:64px}.schedule-alert{border-radius:var(--radius-control);border:1px solid;align-items:flex-start;gap:9px;margin-bottom:14px;padding:10px 12px;font-size:12px;line-height:18px;display:flex}.schedule-alert svg{flex:none}.schedule-alert span{flex:1}.schedule-alert button{color:inherit;background:0 0;border:0;padding:0}.schedule-alert-error{border-color:var(--danger-border);color:var(--danger-text);background:var(--danger)}@supports (color:color-mix(in lab, red, red)){.schedule-alert-error{background:color-mix(in srgb, var(--danger) 8%, var(--surface))}}.schedule-alert-success{border-color:var(--border-strong);color:var(--text-secondary);background:var(--surface)}.schedule-alert-success>svg{color:var(--accent)}.schedule-inline-warning{color:var(--warning);margin-bottom:14px;font-size:12px}.schedule-toolbar{justify-content:flex-end;align-items:center;gap:8px;min-height:36px;margin:-4px 4px 8px;padding:0 4px 4px;display:flex}.schedule-toolbar .button{min-height:36px;font-size:12px}.schedule-toolbar .refresh-button{width:36px;height:36px}.schedule-layout{grid-template-columns:minmax(0,1fr);align-items:start;gap:20px;display:grid}.schedule-collection,.schedule-detail{min-width:0;overflow:hidden}.schedule-collection .session-list-header{flex-wrap:nowrap}.schedule-collection .collection-heading{flex:1;width:auto}.schedule-list-empty{min-height:250px;color:var(--text-muted);text-align:center;place-items:center;padding:24px;font-size:12px;display:grid}.session-row.schedule-row{grid-template-columns:minmax(0,1fr) auto auto}.schedule-row .session-context{min-width:0}.schedule-row .session-workspace{cursor:default}.schedule-row .session-row-meta{min-width:0}.session-row.schedule-row .kind-label{display:inline-flex}.schedule-row .time-badge{text-overflow:ellipsis;max-width:190px;overflow:hidden}.schedule-row .time-badge svg{flex:none}.schedule-detail .inspector-content{padding-top:18px}.schedule-detail-actions{border-bottom:1px solid var(--border-subtle);flex-wrap:wrap;gap:7px;margin-top:18px;padding-bottom:18px;display:flex}.schedule-detail-actions .button{min-height:32px;padding:6px 10px;font-size:11px}.schedule-details-grid{margin-top:18px}.schedule-details-grid small{color:var(--text-muted);margin-top:2px;font-size:10px;display:block}.schedule-details-grid .schedule-failed{color:var(--danger-text)}.schedule-detail-foot{border-top:1px solid var(--border-subtle);margin-top:20px;padding-top:12px}.schedule-detail-foot p{color:var(--text-muted);font-size:11px;line-height:17px}.schedule-detail-foot .schedule-remove{color:var(--danger-text);align-items:center;gap:6px;margin-top:8px;display:inline-flex}.schedule-detail .inspector-empty{min-height:250px}.dialog-panel.schedule-dialog{max-width:624px}.dialog-panel.schedule-confirm{max-width:480px}.schedule-dialog-head{justify-content:space-between;align-items:flex-start;gap:16px;display:flex}.schedule-form-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin-top:20px;display:grid}.schedule-field-wide{grid-column:1/-1}.schedule-form-grid .field em{color:var(--text-faint);font-size:11px;font-style:normal;font-weight:400}.app-shell .schedule-dialog .field>input:focus-visible,.app-shell .schedule-dialog .field>select:focus-visible{outline:0}.schedule-number-field{border:1px solid var(--border-subtle);border-radius:var(--radius-control);background:var(--raised);align-items:center;min-height:40px;display:flex;overflow:hidden}@supports (color:color-mix(in lab, red, red)){.schedule-number-field{background:color-mix(in srgb, var(--raised) 18%, var(--canvas))}}.schedule-number-field{box-shadow:inset 0 1px 0 var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.schedule-number-field{box-shadow:inset 0 1px 0 color-mix(in srgb, var(--text-primary) 3%, transparent)}}.schedule-number-field:hover{border-color:var(--border-strong)}.schedule-number-field:focus-within{border-color:var(--text-secondary)}@supports (color:color-mix(in lab, red, red)){.schedule-number-field:focus-within{border-color:color-mix(in srgb, var(--text-secondary) 58%, var(--border-strong))}}.schedule-number-field:focus-within{background:var(--canvas);box-shadow:0 0 0 3px var(--focus-ring), inset 0 1px 0 var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.schedule-number-field:focus-within{box-shadow:0 0 0 3px color-mix(in srgb, var(--focus-ring) 7%, transparent), inset 0 1px 0 color-mix(in srgb, var(--text-primary) 3%, transparent)}}.app-shell .schedule-number-field input,.app-shell .schedule-number-field input:focus{min-width:0;box-shadow:none;background:0 0;border:0;border-radius:0;padding:8px 12px}.app-shell .schedule-number-field input:focus-visible{outline:0}.schedule-number-field>span{color:var(--text-muted);flex:none;padding:0 10px;font-size:11px}.schedule-mode{margin-top:18px}.schedule-mode>p{margin-bottom:8px}.schedule-mode-options{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;display:grid}.schedule-mode-options .scope-card{width:100%}.schedule-advanced-toggle{margin-top:18px}.schedule-advanced-fields{margin-top:14px}.schedule-extra-toggles{flex-wrap:wrap;gap:8px;display:flex}.schedule-dialog-actions{justify-content:flex-end;gap:9px;margin-top:20px;display:flex}@media (width>=1024px){.schedule-layout{grid-template-columns:minmax(0,1fr) 340px}}@media (width>=1280px){.schedule-layout{grid-template-columns:minmax(0,1fr) 420px}}@media (width>=1536px){.schedule-layout{grid-template-columns:minmax(0,1fr) 480px}}.schedule-layout-empty{grid-template-columns:minmax(0,1fr)}@media (width<=700px){.app-header-leading,.app-header .page-switch{width:100%}.context-and-view{flex-wrap:wrap;gap:4px}.context-and-view .provider-context{flex-basis:100%}.context-and-view .app-header-actions,.page-switch{width:100%}.page-switch a{flex:1}.schedule-collection .session-list-header{flex-wrap:wrap}.session-row.schedule-row{grid-template-columns:minmax(0,1fr) auto}.schedule-row .time-badge,.schedule-row .session-row-chevron{display:none}.schedule-form-grid,.schedule-mode-options{grid-template-columns:1fr}.schedule-field-wide{grid-column:1}}.tab-note{color:var(--text-muted);padding:16px 20px;font-size:12px;line-height:18px}.token-split{border:1px solid var(--border-subtle);border-radius:8px;margin-bottom:16px;padding:10px 12px}.token-split>div{justify-content:space-between;align-items:baseline;gap:12px;display:flex}.token-split>div+div{margin-top:4px}.token-split dt{color:var(--text-secondary);font-size:12px;line-height:18px}.token-split dd{color:var(--text-primary);font-variant-numeric:tabular-nums;font-size:12px;font-weight:600;line-height:18px}.token-split p{color:var(--text-muted);margin-top:8px;font-size:11px;line-height:16px}.token-sub-row{color:var(--text-muted);flex:0 0 100%;justify-content:space-between;gap:12px;padding-left:16px;font-size:11px;line-height:16px;display:flex}.token-sub-row span{font-variant-numeric:tabular-nums}.token-insight{color:var(--text-secondary);margin-top:12px;font-size:12px;line-height:18px}.token-models{border-top:1px solid var(--border-subtle);margin-top:16px;padding-top:12px}.token-note{color:var(--text-muted);margin-top:12px;font-size:11px;line-height:16px}.timeline-stats{grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;padding:16px 20px;display:grid}.timeline-stat{min-width:0}.timeline-stat .overview-value{color:var(--text-primary);margin-top:2px}.timeline-window-note{border-top:1px solid var(--border-subtle);color:var(--text-muted);padding:12px 20px 0;font-size:11px;font-weight:600;line-height:16px}.timeline-events .date-separator{z-index:1;color:var(--text-muted);background:var(--surface);padding-top:10px;padding-bottom:10px;font-size:11px;position:sticky;top:0}.pagination{border-top:1px solid var(--border-subtle);flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;min-height:56px;padding:8px 16px;display:flex}.pagination>span{color:var(--text-muted);font-variant-numeric:tabular-nums;font-size:12px}.pagination strong{color:var(--text-secondary);font-weight:600}.page-button{border-radius:var(--radius-control);min-width:32px;height:32px;color:var(--text-muted);background:0 0;border:1px solid #0000;place-items:center;padding:0 8px;font-size:11px;display:grid}.page-button:hover:not(:disabled){border-color:var(--border-strong);color:var(--text-primary);background:var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.page-button:hover:not(:disabled){background:color-mix(in srgb, var(--text-primary) 6%, transparent)}}.page-button[aria-current=page]{border-color:var(--focus-ring);color:var(--text-primary);background:var(--raised)}.page-button:disabled{opacity:.28}.empty-state{text-align:center;place-items:center;min-height:360px;padding:24px;display:grid}.empty-state-icon{border:1px solid var(--border-subtle);width:44px;height:44px;color:var(--text-muted);background:var(--text-primary);border-radius:.75rem;place-items:center;margin:0 auto;display:grid}@supports (color:color-mix(in lab, red, red)){.empty-state-icon{background:color-mix(in srgb, var(--text-primary) 4%, transparent)}}.empty-state h3{color:var(--text-secondary);margin-top:16px;font-size:14px;font-weight:650}.empty-state p{max-width:360px;color:var(--text-muted);margin:8px auto 0;font-size:12px;line-height:20px}.compatibility-popover{z-index:30;border:1px solid var(--border-strong);border-radius:var(--radius-surface);background:var(--raised);width:min(400px,100vw - 32px);box-shadow:0 24px 72px var(--canvas);padding:16px;position:absolute;top:calc(100% + 8px);right:0}@supports (color:color-mix(in lab, red, red)){.compatibility-popover{box-shadow:0 24px 72px color-mix(in srgb, var(--canvas) 72%, transparent)}}.compatibility-popover{animation:.15s ease-out raised-in}.popover-title{color:var(--text-primary);font-size:14px;font-weight:650}.popover-copy{color:var(--text-secondary);margin-top:4px;font-size:12px;line-height:20px}.version-list{border-top:1px solid var(--border-subtle);gap:8px;margin-top:16px;padding-top:16px;display:grid}.version-row{border:1px solid var(--border-subtle);border-radius:var(--radius-control);background:var(--surface);justify-content:space-between;align-items:center;gap:16px;padding:8px 12px;display:flex}.version-row p{color:var(--text-secondary);font-size:12px;font-weight:600}.version-row code{color:var(--text-muted);margin-top:2px;font-size:11px;display:block}.version-row>span{color:var(--text-muted);text-align:right;font-size:11px}.compatibility-note{color:var(--text-muted);margin-top:12px;font-size:12px;line-height:20px}.compatibility-details{color:var(--text-secondary);margin-top:12px;font-size:12px;line-height:20px}.compatibility-details li{gap:8px;display:flex}.semantic-dot{border-radius:999px;flex:none;width:4px;height:4px;margin-top:8px}.info-dot{background:var(--text-muted)}.warning-dot{background:var(--warning)}.success-icon{color:var(--success);flex:none;margin-top:2px}.alert{border:1px solid;border-radius:.75rem;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:12px;margin-bottom:20px;padding:12px;font-size:13px;animation:.15s ease-out raised-in;display:grid}.alert button{color:currentColor;opacity:.75;background:0 0;border:0;place-items:center;display:grid}.alert-success{border-color:var(--success)}@supports (color:color-mix(in lab, red, red)){.alert-success{border-color:color-mix(in srgb, var(--success) 28%, transparent)}}.alert-success{color:var(--success);background:var(--success)}@supports (color:color-mix(in lab, red, red)){.alert-success{background:color-mix(in srgb, var(--success) 8%, transparent)}}.alert-warning{border-color:var(--warning)}@supports (color:color-mix(in lab, red, red)){.alert-warning{border-color:color-mix(in srgb, var(--warning) 28%, transparent)}}.alert-warning{color:var(--warning);background:var(--warning)}@supports (color:color-mix(in lab, red, red)){.alert-warning{background:color-mix(in srgb, var(--warning) 8%, transparent)}}.alert-error{border-color:var(--danger-border);color:var(--danger-text);background:var(--danger)}@supports (color:color-mix(in lab, red, red)){.alert-error{background:color-mix(in srgb, var(--danger) 8%, transparent)}}.keep-toast{z-index:45;border:1px solid var(--border-strong);color:var(--text-secondary);background:var(--raised);box-shadow:0 18px 56px var(--canvas);border-radius:.75rem;grid-template-columns:auto minmax(0,1fr) auto auto;align-items:center;gap:10px;padding:11px 10px 11px 12px;display:grid;position:fixed;bottom:12px;left:12px;right:12px}@supports (color:color-mix(in lab, red, red)){.keep-toast{box-shadow:0 18px 56px color-mix(in srgb, var(--canvas) 72%, transparent)}}.keep-toast{transition:bottom .15s ease-out;animation:.15s ease-out selection-tray-in}.keep-toast-raised{bottom:232px}.keep-toast-icon{border:1px solid var(--accent);place-items:center;width:28px;height:28px;display:grid}@supports (color:color-mix(in lab, red, red)){.keep-toast-icon{border:1px solid color-mix(in srgb, var(--accent) 28%, var(--border-subtle))}}.keep-toast-icon{color:var(--accent);background:var(--accent);border-radius:.5rem}@supports (color:color-mix(in lab, red, red)){.keep-toast-icon{background:color-mix(in srgb, var(--accent) 8%, transparent)}}.keep-toast strong{color:var(--text-primary);font-size:12px;font-weight:650;line-height:16px;display:block}.keep-toast p{color:var(--text-muted);margin-top:2px;font-size:11px;line-height:16px}.keep-toast-undo,.keep-toast-dismiss{background:0 0;border:0}.keep-toast-undo{color:var(--accent);border-radius:.5rem;padding:6px 8px;font-size:11px;font-weight:700}.keep-toast-undo:hover:not(:disabled){background:var(--accent)}@supports (color:color-mix(in lab, red, red)){.keep-toast-undo:hover:not(:disabled){background:color-mix(in srgb, var(--accent) 10%, transparent)}}.keep-toast-dismiss{width:28px;height:28px;color:var(--text-muted);border-radius:.5rem;place-items:center;display:grid}.keep-toast-dismiss:hover{color:var(--text-primary);background:var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.keep-toast-dismiss:hover{background:color-mix(in srgb, var(--text-primary) 6%, transparent)}}.selection-tray{z-index:38;border:1px solid var(--border-strong);border-radius:var(--radius-surface);background:var(--raised);box-shadow:0 24px 80px var(--canvas);position:fixed;bottom:8px;left:8px;right:8px}@supports (color:color-mix(in lab, red, red)){.selection-tray{box-shadow:0 24px 80px color-mix(in srgb, var(--canvas) 76%, transparent)}}.selection-tray{animation:.15s ease-out selection-tray-in}.selection-tray-review{border-bottom:1px solid var(--border-subtle);border-radius:var(--radius-surface) var(--radius-surface) 0 0;background:var(--surface);overflow:hidden}.selection-tray-review-heading{justify-content:space-between;align-items:center;gap:16px;padding:16px;display:flex}.selection-tray-review-heading>span{border:1px solid var(--border-strong);min-width:28px;height:28px;color:var(--text-secondary);background:var(--raised);font-variant-numeric:tabular-nums;border-radius:999px;place-items:center;font-size:11px;font-weight:650;display:grid}.selection-tray-heading{color:var(--text-primary);font-size:14px;font-weight:650}.selection-tray-copy{color:var(--text-muted);margin-top:4px;font-size:12px}.selection-tray-records{border-top:1px solid var(--border-subtle);max-height:min(272px,42vh);overflow-y:auto}.selection-tray-record{border-bottom:1px solid var(--border-subtle);contain-intrinsic-size:auto 60px;content-visibility:auto;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:12px;min-height:60px;padding:8px 12px 8px 16px;display:grid}.selection-tray-record:last-child{border-bottom:0}.selection-tray-title{color:var(--text-secondary);text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:600;line-height:16px;overflow:hidden}.selection-tray-meta{min-width:0;color:var(--text-muted);align-items:center;gap:4px;margin-top:4px;font-size:11px;display:flex}.selection-kept{color:var(--accent);flex:none;align-items:center;gap:3px;display:inline-flex}.selection-tray-bar{border-radius:var(--radius-surface);background:var(--raised);flex-direction:column;gap:12px;padding:12px;display:flex}.selection-tray-review+.selection-tray-bar{border-radius:0 0 var(--radius-surface) var(--radius-surface)}.selection-tray-summary{min-width:0;color:var(--text-primary);font-variant-numeric:tabular-nums;font-size:13px;font-weight:650;line-height:20px}.selection-tray-count,.selection-tray-summary-value{display:inline-block}.selection-tray-actions{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;display:grid}.selection-more{min-width:0;position:relative}.selection-more>summary{width:100%;list-style:none}.selection-more>summary::-webkit-details-marker{display:none}.selection-more-menu{z-index:2;border:1px solid var(--border-strong);background:var(--raised);width:max-content;min-width:220px;box-shadow:0 18px 52px var(--canvas);border-radius:.75rem;padding:4px;display:grid;position:absolute;bottom:calc(100% + 8px);right:0;overflow:hidden}@supports (color:color-mix(in lab, red, red)){.selection-more-menu{box-shadow:0 18px 52px color-mix(in srgb, var(--canvas) 72%, transparent)}}.selection-more-menu button{min-height:40px;color:var(--text-secondary);text-align:left;background:0 0;border:0;border-radius:.5rem;align-items:center;gap:8px;padding:8px 10px;font-size:12px;font-weight:600;display:flex}.selection-more-menu button:hover:not(:disabled){color:var(--text-primary);background:var(--text-primary)}@supports (color:color-mix(in lab, red, red)){.selection-more-menu button:hover:not(:disabled){background:color-mix(in srgb, var(--text-primary) 6%, transparent)}}.selection-more-menu button svg{color:var(--text-muted)}.has-selection-tray{padding-bottom:216px;transition:padding-bottom .15s ease-out}.has-selection-tray-expanded{padding-bottom:496px}.dialog-backdrop{z-index:50;background:var(--canvas);place-items:center;display:grid;position:fixed;inset:0;overflow-y:auto}@supports (color:color-mix(in lab, red, red)){.dialog-backdrop{background:color-mix(in srgb, var(--canvas) 82%, transparent)}}.dialog-backdrop{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);padding:16px;animation:.15s ease-out backdrop-in}.dialog-panel,.shortcut-panel{border:1px solid var(--border-strong);border-radius:var(--radius-surface);background:var(--raised);width:100%;max-height:calc(100vh - 32px);box-shadow:0 36px 104px var(--canvas);padding:24px;overflow-y:auto}@supports (color:color-mix(in lab, red, red)){.dialog-panel,.shortcut-panel{box-shadow:0 36px 104px color-mix(in srgb, var(--canvas) 78%, transparent)}}.dialog-panel,.shortcut-panel{animation:.15s ease-out raised-in}.dialog-panel{max-width:624px}.shortcut-panel{max-width:704px}.dialog-title{color:var(--text-primary);letter-spacing:-.015em;margin-top:8px;font-size:20px;font-weight:650;line-height:24px}.dialog-copy{color:var(--text-secondary);margin-top:8px;font-size:14px;line-height:20px}.shortcut-groups{gap:12px;margin-top:20px;display:grid}.shortcut-groups>section{border:1px solid var(--border-subtle);background:var(--surface);border-radius:.75rem;overflow:hidden}.shortcut-groups h3{border-bottom:1px solid var(--border-subtle);color:var(--text-secondary);padding:8px 12px;font-size:12px;font-weight:650}.shortcut-groups dl>div{border-bottom:1px solid var(--border-subtle);justify-content:space-between;align-items:center;gap:12px;min-height:44px;padding:8px 12px;display:flex}.shortcut-groups dl>div:last-child{border-bottom:0}.shortcut-groups dt{color:var(--text-secondary);font-size:12px;line-height:16px}.shortcut-groups dd{flex:none}.shortcut-groups kbd{border:1px solid var(--border-strong);color:var(--text-secondary);background:var(--raised);box-shadow:0 1px 2px var(--canvas);border-radius:.375rem;padding:4px 8px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:11px;display:inline-block}@supports (color:color-mix(in lab, red, red)){.shortcut-groups kbd{box-shadow:0 1px 2px color-mix(in srgb, var(--canvas) 40%, transparent)}}.scope-card{border:1px solid var(--border-subtle);color:var(--text-secondary);background:var(--surface);text-align:left;border-radius:.75rem;padding:16px;transition:border-color .15s ease-out,background .15s ease-out}.scope-card:hover:not(:disabled){border-color:var(--border-strong);background:var(--surface)}@supports (color:color-mix(in lab, red, red)){.scope-card:hover:not(:disabled){background:color-mix(in srgb, var(--surface) 88%, var(--raised))}}.scope-card-active{border-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.scope-card-active{border-color:color-mix(in srgb, var(--accent) 52%, var(--border-strong))}}.scope-card-active{color:var(--text-primary);background:var(--accent-soft)}.scope-heading{justify-content:space-between;align-items:center;gap:8px;font-size:14px;font-weight:650;display:flex}.scope-check{border:1px solid var(--border-strong);border-radius:999px;place-items:center;width:20px;height:20px;display:grid}.scope-card-active .scope-check{border-color:var(--accent);color:var(--canvas);background:var(--accent)}.scope-card>p{color:var(--text-secondary);margin-top:8px;font-size:12px;line-height:20px}.metric{border:1px solid var(--border-subtle);background:var(--surface);border-radius:.75rem;padding:12px}.metric>p{min-height:32px;color:var(--text-muted);font-size:11px;font-weight:600;line-height:16px}.metric>strong{color:var(--text-primary);text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums;margin-top:4px;font-size:14px;font-weight:650;display:block;overflow:hidden}.dialog-plan-region{min-height:76px;margin-top:20px;position:relative}.metric-skeleton{border-radius:.75rem;height:76px}.dialog-plan-loading{z-index:1;color:var(--text-secondary);background:var(--raised);border-radius:.75rem;justify-content:center;align-items:center;gap:8px;display:flex;position:absolute;inset:-1px}@supports (color:color-mix(in lab, red, red)){.dialog-plan-loading{background:color-mix(in srgb, var(--raised) 88%, transparent)}}.dialog-plan-loading{-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);font-size:12px;font-weight:650}.dialog-message,.dialog-confirmation{border:1px solid;border-radius:.75rem;margin-top:16px;padding:12px;font-size:13px;line-height:20px}.message-warning{border-color:var(--warning)}@supports (color:color-mix(in lab, red, red)){.message-warning{border-color:color-mix(in srgb, var(--warning) 24%, var(--border-subtle))}}.message-warning{color:var(--text-secondary);background:var(--warning)}@supports (color:color-mix(in lab, red, red)){.message-warning{background:color-mix(in srgb, var(--warning) 5%, transparent)}}.message-danger{border-color:var(--danger-border);color:var(--danger-text);background:var(--danger)}@supports (color:color-mix(in lab, red, red)){.message-danger{background:color-mix(in srgb, var(--danger) 8%, transparent)}}.dialog-note,.dialog-information{color:var(--text-secondary);align-items:flex-start;gap:8px;margin-top:12px;font-size:12px;line-height:20px;display:flex}.dialog-note>svg,.dialog-information>svg{color:var(--text-muted);flex:none;margin-top:2px}.close-session-note{border:1px solid var(--border-subtle);background:var(--surface);border-radius:.75rem;margin-top:20px;padding:12px}.close-session-note strong{color:var(--text-primary);font-weight:650}.operation-panel{border:1px solid var(--border-subtle);background:var(--surface);border-radius:.75rem;margin-top:20px;padding:16px}.operation-heading{color:var(--text-secondary);justify-content:space-between;align-items:center;gap:16px;font-size:14px;display:flex}.operation-heading>span:first-child{font-weight:600}.operation-heading>span:last-child{color:var(--text-muted);font-variant-numeric:tabular-nums}.progress-track{background:var(--border-subtle);border-radius:999px;height:6px;margin-top:12px;overflow:hidden}.progress-value{border-radius:999px;height:100%;transition:width .15s ease-out}.progress-success{background:var(--success)}.progress-warning{background:var(--warning)}.progress-danger{background:var(--danger)}.progress-info{background:var(--text-secondary)}.operation-error{background:0 0;border:0;margin-top:12px;padding:0;font-size:12px;line-height:20px}.restore-copy{color:var(--text-secondary);margin-top:12px;font-size:12px;line-height:20px}.restore-copy>div{margin-top:8px}.restore-copy>div>p{color:var(--text-muted)}.restore-copy code{overflow-wrap:anywhere;color:var(--text-muted);font-size:11px;display:block}.dialog-confirmation>p{color:var(--text-primary);font-size:14px;font-weight:650}.dialog-confirmation>span{margin-top:4px;display:block}.skeleton{background:linear-gradient(90deg, var(--text-primary), var(--text-primary), var(--text-primary))}@supports (color:color-mix(in lab, red, red)){.skeleton{background:linear-gradient(90deg, color-mix(in srgb, var(--text-primary) 4%, transparent), color-mix(in srgb, var(--text-primary) 9%, transparent), color-mix(in srgb, var(--text-primary) 4%, transparent))}}.skeleton{background-size:200% 100%;animation:1.5s ease-in-out infinite shimmer}@keyframes shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}@keyframes selection-tray-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes raised-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes backdrop-in{0%{opacity:0}to{opacity:1}}@keyframes disclosure-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes checkbox-check-in{0%{opacity:.72;transform:scale(.88)}to{opacity:1;transform:scale(1)}}@keyframes filter-chip-in{0%{opacity:0;transform:translateY(2px)}to{opacity:1;transform:translateY(0)}}@keyframes filter-chip-out{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-2px)}}@keyframes selection-value-in{0%{opacity:.7;transform:translateY(2px)}to{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion:no-preference){.selection-control input:checked,.session-checkbox input:checked{animation:.12s ease-out checkbox-check-in}.filter-chip{animation:.14s ease-out filter-chip-in}.filter-chip-exiting{animation:.12s ease-out forwards filter-chip-out}.selection-tray-count,.selection-tray-summary-value{animation:.12s ease-out selection-value-in}}@media (width<=1023px){.inspector-open{z-index:40;max-height:min(576px,100vh - 48px);box-shadow:0 28px 90px var(--canvas);display:block;position:fixed;bottom:12px;left:12px;right:12px;overflow-y:auto}@supports (color:color-mix(in lab, red, red)){.inspector-open{box-shadow:0 28px 90px color-mix(in srgb, var(--canvas) 76%, transparent)}}.inspector-backdrop-open{z-index:39;background:var(--canvas);border:0;width:100%;height:100%;display:block;position:fixed;inset:0}@supports (color:color-mix(in lab, red, red)){.inspector-backdrop-open{background:color-mix(in srgb, var(--canvas) 64%, transparent)}}.inspector-backdrop-open{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}}@media (width>=640px){.session-list-header,.kept-view-switch,.filter-bar,.more-filters-row,.active-filter-row,.unknown-activity-note,.page-selection-row,.pagination,.workspace-rules-toolbar,.workspace-rule-row,.date-separator,.session-row{padding-left:20px;padding-right:20px}.shortcut-hint{display:block}.selection-tray{width:min(736px,100vw - 48px);bottom:20px;left:50%;right:auto;translate:-50%}.selection-tray-bar{flex-direction:row;align-items:center;padding:12px 12px 12px 16px}.selection-tray-summary{flex:auto}.selection-tray-actions{flex:none;display:flex}.selection-more>summary{width:auto}.has-selection-tray{padding-bottom:112px}.has-selection-tray-expanded{padding-bottom:400px}.keep-toast{width:min(440px,100vw - 48px);bottom:24px;left:auto;right:24px}.keep-toast-raised{bottom:104px}.session-row-chevron{display:block}}@media (width>=900px){.session-filters{--filter-grid:minmax(260px, 2fr) minmax(180px, 1fr) auto}.overview-strip{grid-template-columns:repeat(3,minmax(0,1fr))}.overview-item,.overview-item-primary{border-right:1px solid var(--border-subtle);border-bottom:0;grid-column:auto}.overview-item:nth-child(3n),.overview-strip>.overview-item:last-child{border-right:0}.shortcut-groups{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (width>=1024px){.inspector{max-height:calc(100vh - 48px);display:block;position:sticky;top:24px;overflow-y:auto}}@media (width>=900px) and (width<=1179px){.filter-primary-controls .filter-priority-1,.filter-overflow-primary .filter-priority-2{display:none}}@media (width>=1180px){.session-filters{--filter-grid:minmax(220px, 1.5fr) repeat(2, minmax(180px, 1fr)) auto}.overview-strip{grid-template-columns:repeat(var(--overview-columns), minmax(0, 1fr))}.overview-item,.overview-item-primary{border-right:1px solid var(--border-subtle);border-bottom:0}.overview-item:nth-child(3n){border-right:1px solid var(--border-subtle)}.overview-strip>.overview-item:last-child{border-right:0}.filter-overflow-primary{display:none}}@media (width<=639px){.brand-title{font-size:20px;line-height:24px}.brand-mark{width:40px;height:40px}.surface{border-radius:.875rem}.provider-context{align-items:flex-start}.provider-context-main{gap:4px;width:100%;display:grid}.provider-context code{width:100%}.date-separator{padding-left:12px;padding-right:12px}.session-row{grid-template-columns:28px minmax(0,1fr) auto;gap:4px;padding-left:12px;padding-right:12px}.session-row-chevron{display:none}.session-row-meta{gap:2px}.session-list-header{align-items:flex-start}.collection-heading{width:100%}.collection-heading .shown-count{margin-left:auto}.session-list-tools{justify-content:flex-end;width:100%}.kept-view-switch{gap:16px;overflow-x:auto}.selection-guidance{display:none}.workspace-rules-toolbar{min-height:62px}.workspace-rule-search{width:100%}.workspace-rule-row{grid-template-columns:auto minmax(0,1fr);padding-left:12px;padding-right:12px}.workspace-rule-row .button{grid-column:2;justify-self:start;min-height:32px}.time-badge,.kind-label,.size-badge{padding-left:4px;padding-right:4px}.time-badge svg,.kind-label svg,.size-badge svg{display:none}.compatibility-popover{width:auto;position:fixed;top:72px;left:16px;right:16px}.dialog-backdrop{align-items:end;padding:0}.dialog-panel,.shortcut-panel{border-radius:var(--radius-surface) var(--radius-surface) 0 0;border-bottom:0;border-left:0;border-right:0;max-height:92vh;padding:20px}}@media (width<=899px){.filter-primary-controls{display:none}}@media (width<=519px){.more-filters-button>span{display:none}.filter-bar{gap:8px}.sort-control>span,.shortcut-hint,.session-row .kind-label,.session-row .size-badge{display:none}}@media (prefers-reduced-motion:reduce){.active-filter-row-clearing,.filter-chip-exiting{display:none!important}*,:before,:after{scroll-behavior:auto!important;transition:none!important;animation:none!important}}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}
|
package/dist/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
|
|
6
6
|
<link href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='8' fill='%23171717'/%3E%3Cpath d='M16 4 26 8v7c0 6-4 11-10 13C10 26 6 21 6 15V8Z' fill='%23f5f5f5'/%3E%3Cpath d='m9.5 16 2.2-2.2 3 3 6.5-6.5 2.2 2.2-8.7 8.7Z' fill='%23171717'/%3E%3C/svg%3E" rel="icon"/>
|
|
7
7
|
<title>Session Steward</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-B8p_9FID.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DHWhZO0c.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
|
@@ -266,6 +266,8 @@ export function createCleanupScheduleStore({
|
|
|
266
266
|
},
|
|
267
267
|
|
|
268
268
|
async save(definition, { id } = {}) {
|
|
269
|
+
const hasHomeOverride = definition && typeof definition === "object"
|
|
270
|
+
&& Object.hasOwn(definition, "providerHomeOverride");
|
|
269
271
|
const normalized = normalizeDefinition(definition);
|
|
270
272
|
return mutate((state) => {
|
|
271
273
|
const currentTime = now();
|
|
@@ -294,6 +296,11 @@ export function createCleanupScheduleStore({
|
|
|
294
296
|
const schedule = {
|
|
295
297
|
...existing,
|
|
296
298
|
...normalized,
|
|
299
|
+
providerHomeOverride: hasHomeOverride
|
|
300
|
+
? normalized.providerHomeOverride
|
|
301
|
+
: existing.provider === normalized.provider
|
|
302
|
+
? existing.providerHomeOverride
|
|
303
|
+
: null,
|
|
297
304
|
nextRunAtMs: timingChanged
|
|
298
305
|
? nextRunAt(normalized, currentTime)
|
|
299
306
|
: existing.nextRunAtMs,
|
|
@@ -19,15 +19,15 @@ const PROVIDER_ID = "claude-code";
|
|
|
19
19
|
const COMPATIBILITY_PROFILE = Object.freeze({
|
|
20
20
|
id: "claude-local-store-2026-08",
|
|
21
21
|
builtFor: {
|
|
22
|
-
claudeCli: ["2.1.199", "2.1.220", "2.1.228", "2.1.237", "2.1.267"],
|
|
23
|
-
claudeDesktop: ["1.24012.9", "1.28929.0", "1.32885.1", "1.40609.0", "1.49585.0"],
|
|
22
|
+
claudeCli: ["2.1.199", "2.1.220", "2.1.228", "2.1.237", "2.1.267", "2.1.280"],
|
|
23
|
+
claudeDesktop: ["1.24012.9", "1.28929.0", "1.32885.1", "1.40609.0", "1.49585.0", "2.2553.1"],
|
|
24
24
|
},
|
|
25
25
|
});
|
|
26
26
|
const SUPPORTED_ENTRYPOINTS = new Set(["cli", "claude-desktop"]);
|
|
27
27
|
const SHARED_DESKTOP_STATE_FILES = new Set(["scheduled-tasks.json"]);
|
|
28
28
|
const KNOWN_TOP_LEVEL = new Set([
|
|
29
29
|
".DS_Store", ".last-cleanup", ".last-update-result.json", "agents", "backups", "cache", "commands", "debug", "downloads", "file-history", "history.jsonl", "history.jsonl.lock",
|
|
30
|
-
"ide", "paste-cache", "plans", "plugins", "projects", "session-env", "sessions", "settings.json",
|
|
30
|
+
"ide", "image-cache", "paste-cache", "plans", "plugins", "projects", "session-env", "sessions", "settings.json",
|
|
31
31
|
"settings.local.json", "shell-snapshots", "skills", "stats-cache.json", "tasks", "telemetry",
|
|
32
32
|
"todos", "uploads", "usage-data", "mcp-needs-auth-cache.json", "session-steward-backups",
|
|
33
33
|
]);
|
|
@@ -4,12 +4,24 @@ import path from "node:path";
|
|
|
4
4
|
import { queryRows } from "../../storage/sqlite.mjs";
|
|
5
5
|
|
|
6
6
|
const CACHE_TTL_MS = 2_000;
|
|
7
|
+
const MEMORY_TABLES = [
|
|
8
|
+
{ name: "stage1_outputs", requiredColumns: ["thread_id"] },
|
|
9
|
+
{
|
|
10
|
+
name: "jobs",
|
|
11
|
+
optional: true,
|
|
12
|
+
requiredColumns: [
|
|
13
|
+
"kind", "job_key", "status", "worker_id", "ownership_token", "started_at",
|
|
14
|
+
"finished_at", "lease_until", "retry_at", "retry_remaining", "last_error",
|
|
15
|
+
"input_watermark", "last_success_watermark",
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
];
|
|
7
19
|
|
|
8
20
|
export const CODEX_DATABASE_PROFILE = Object.freeze({
|
|
9
|
-
id: "codex-local-store-2026-
|
|
21
|
+
id: "codex-local-store-2026-09",
|
|
10
22
|
builtFor: {
|
|
11
|
-
chatgptDesktop: ["26.727.40816", "26.803.61601", "26.818.21641", "26.818.22352", "26.825.41651", "26.903.61454", "26.903.71938"],
|
|
12
|
-
codexCli: ["0.144.1", "0.146.0", "0.147.0", "0.148.0", "0.153.4", "0.154.0"],
|
|
23
|
+
chatgptDesktop: ["26.727.40816", "26.803.61601", "26.818.21641", "26.818.22352", "26.825.41651", "26.903.61454", "26.903.71938", "26.917.51856"],
|
|
24
|
+
codexCli: ["0.144.1", "0.146.0", "0.147.0", "0.148.0", "0.153.4", "0.154.0", "0.156.1"],
|
|
13
25
|
},
|
|
14
26
|
});
|
|
15
27
|
|
|
@@ -30,28 +42,13 @@ const SCHEMA_REQUIREMENTS = Object.freeze({
|
|
|
30
42
|
fallback: "memories_1.sqlite",
|
|
31
43
|
pattern: /^memories_(\d+)\.sqlite$/u,
|
|
32
44
|
required: false,
|
|
33
|
-
tables:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"job_key",
|
|
41
|
-
"status",
|
|
42
|
-
"worker_id",
|
|
43
|
-
"ownership_token",
|
|
44
|
-
"started_at",
|
|
45
|
-
"finished_at",
|
|
46
|
-
"lease_until",
|
|
47
|
-
"retry_at",
|
|
48
|
-
"retry_remaining",
|
|
49
|
-
"last_error",
|
|
50
|
-
"input_watermark",
|
|
51
|
-
"last_success_watermark",
|
|
52
|
-
],
|
|
53
|
-
},
|
|
54
|
-
],
|
|
45
|
+
tables: MEMORY_TABLES,
|
|
46
|
+
},
|
|
47
|
+
memoriesV2: {
|
|
48
|
+
fallback: "memories_v2_1.sqlite",
|
|
49
|
+
pattern: /^memories_v2_(\d+)\.sqlite$/u,
|
|
50
|
+
required: false,
|
|
51
|
+
tables: MEMORY_TABLES,
|
|
55
52
|
},
|
|
56
53
|
goals: {
|
|
57
54
|
fallback: "goals_1.sqlite",
|
|
@@ -479,7 +479,7 @@ export function getCodexPaths(codexHomeInput, { refresh = false } = {}) {
|
|
|
479
479
|
const archivedSessionsDirectory = path.join(codexHome, "archived_sessions");
|
|
480
480
|
const sessionsDirectory = path.join(codexHome, "sessions");
|
|
481
481
|
const resolution = resolveCodexDatabases(codexHome, { refresh });
|
|
482
|
-
const { goals, logs, memories, queue, state, threadHistory } = resolution.families;
|
|
482
|
+
const { goals, logs, memories, memoriesV2, queue, state, threadHistory } = resolution.families;
|
|
483
483
|
const stateDatabasePath = state.primary?.path ?? path.join(codexHome, "state_5.sqlite");
|
|
484
484
|
const logsDatabasePath = logs.primary?.path ?? path.join(codexHome, "logs_2.sqlite");
|
|
485
485
|
const memoryDatabasePath = memories.primary?.path ?? path.join(codexHome, "memories_1.sqlite");
|
|
@@ -500,7 +500,8 @@ export function getCodexPaths(codexHomeInput, { refresh = false } = {}) {
|
|
|
500
500
|
logsDatabasePath,
|
|
501
501
|
logsDatabasePaths: allValidDatabases(logs).map((database) => database.path),
|
|
502
502
|
memoryDatabasePath,
|
|
503
|
-
memoryDatabasePaths:
|
|
503
|
+
memoryDatabasePaths: [memories, memoriesV2].flatMap((family) =>
|
|
504
|
+
allValidDatabases(family).map((database) => database.path)),
|
|
504
505
|
queueDatabasePath,
|
|
505
506
|
queueDatabasePaths: allValidDatabases(queue).map((database) => database.path),
|
|
506
507
|
resolvedDatabases: databaseFamilySummary(resolution),
|
|
@@ -971,6 +972,8 @@ function stateSchema(database) {
|
|
|
971
972
|
? database.tables.thread_dynamic_tools
|
|
972
973
|
: inspectSqliteTable(database.path, "thread_dynamic_tools");
|
|
973
974
|
const schema = {
|
|
975
|
+
attachmentTables: ["thread_artifacts", "thread_attachments"]
|
|
976
|
+
.filter((tableName) => inspectSqliteTable(database.path, tableName).exists),
|
|
974
977
|
columns,
|
|
975
978
|
hasDynamicTools: Boolean(dynamicTools?.exists),
|
|
976
979
|
hasSpawnEdges: Boolean(spawn?.exists),
|
|
@@ -2408,6 +2411,9 @@ export async function fingerprintSessionDeletion({ plan, scope, store }) {
|
|
|
2408
2411
|
|
|
2409
2412
|
for (const database of store.stateDatabases ?? [{ path: store.stateDatabasePath }]) {
|
|
2410
2413
|
fingerprintRowsForIds(hash, database.path, "threads", "id", plan.ids);
|
|
2414
|
+
for (const tableName of stateSchema(database).attachmentTables) {
|
|
2415
|
+
fingerprintRowsForIds(hash, database.path, tableName, "thread_id", plan.ids);
|
|
2416
|
+
}
|
|
2411
2417
|
if (stateSchema(database).hasDynamicTools) {
|
|
2412
2418
|
fingerprintRowsForIds(hash, database.path, "thread_dynamic_tools", "thread_id", plan.ids);
|
|
2413
2419
|
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { createInterface } from "node:readline/promises";
|
|
3
|
+
|
|
4
|
+
import packageMetadata from "../package.json" with { type: "json" };
|
|
5
|
+
import { getCommandInvocation } from "./platform.mjs";
|
|
6
|
+
|
|
7
|
+
const PACKAGE_SPEC = `${packageMetadata.name}@latest`;
|
|
8
|
+
const INSTALL_ARGS = ["install", "--global", PACKAGE_SPEC];
|
|
9
|
+
const VERSION_ARGS = ["list", "--global", "--depth=0", "--json", packageMetadata.name];
|
|
10
|
+
|
|
11
|
+
async function runCommand(command, args, { captureStdout = false, platform, stderr, stdout }) {
|
|
12
|
+
const invocation = getCommandInvocation(command, args, { platform });
|
|
13
|
+
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
const child = spawn(invocation.command, invocation.args, {
|
|
16
|
+
stdio: ["inherit", "pipe", "pipe"],
|
|
17
|
+
windowsHide: invocation.windowsHide,
|
|
18
|
+
});
|
|
19
|
+
let errorOutput = "";
|
|
20
|
+
let output = "";
|
|
21
|
+
|
|
22
|
+
child.stdout.on("data", (chunk) => {
|
|
23
|
+
if (captureStdout) output = (output + chunk.toString()).slice(-16_384);
|
|
24
|
+
else stdout.write(chunk);
|
|
25
|
+
});
|
|
26
|
+
child.stderr.on("data", (chunk) => {
|
|
27
|
+
stderr.write(chunk);
|
|
28
|
+
errorOutput = (errorOutput + chunk.toString()).slice(-8_192);
|
|
29
|
+
});
|
|
30
|
+
child.on("error", reject);
|
|
31
|
+
child.on("close", (exitCode) => resolve({ exitCode: exitCode ?? 1, errorOutput, output }));
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function confirmSudo({ stdin, stdout }) {
|
|
36
|
+
const prompt = createInterface({ input: stdin, output: stdout });
|
|
37
|
+
try {
|
|
38
|
+
const answer = await prompt.question("Retry the update with sudo? [y/N] ");
|
|
39
|
+
return /^(?:y|yes)$/iu.test(answer.trim());
|
|
40
|
+
} finally {
|
|
41
|
+
prompt.close();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export async function updateSessionSteward({
|
|
46
|
+
confirm = confirmSudo,
|
|
47
|
+
currentVersion = packageMetadata.version,
|
|
48
|
+
platform = process.platform,
|
|
49
|
+
run = runCommand,
|
|
50
|
+
stdin = process.stdin,
|
|
51
|
+
stdout = process.stdout,
|
|
52
|
+
stderr = process.stderr,
|
|
53
|
+
} = {}) {
|
|
54
|
+
stdout.write(`Current version: ${currentVersion}\nUpdating Session Steward with npm...\n`);
|
|
55
|
+
let result = await run("npm", INSTALL_ARGS, { platform, stderr, stdout });
|
|
56
|
+
let usedSudo = false;
|
|
57
|
+
|
|
58
|
+
if (result.exitCode !== 0 && /\b(?:EACCES|EPERM)\b/u.test(result.errorOutput)) {
|
|
59
|
+
if (platform === "win32") {
|
|
60
|
+
stderr.write("Global npm install needs permission. Open an elevated terminal and run session-steward update.\n");
|
|
61
|
+
} else if (stdin.isTTY && stdout.isTTY) {
|
|
62
|
+
stdout.write("The global npm install needs elevated permission.\n");
|
|
63
|
+
if (await confirm({ stdin, stdout })) {
|
|
64
|
+
usedSudo = true;
|
|
65
|
+
result = await run("sudo", ["npm", ...INSTALL_ARGS], { platform, stderr, stdout });
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
stderr.write("Global npm install needs elevated permission. Run sudo session-steward update in a terminal.\n");
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (result.exitCode === 0) {
|
|
73
|
+
let installedVersion;
|
|
74
|
+
try {
|
|
75
|
+
const versionResult = await run(
|
|
76
|
+
usedSudo ? "sudo" : "npm",
|
|
77
|
+
usedSudo ? ["npm", ...VERSION_ARGS] : VERSION_ARGS,
|
|
78
|
+
{ captureStdout: true, platform, stderr, stdout },
|
|
79
|
+
);
|
|
80
|
+
if (versionResult.exitCode === 0) {
|
|
81
|
+
installedVersion = JSON.parse(versionResult.output)?.dependencies?.[packageMetadata.name]?.version;
|
|
82
|
+
}
|
|
83
|
+
} catch {
|
|
84
|
+
// Installation succeeded, but npm could not confirm the installed version.
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (typeof installedVersion === "string" && /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.+-]+)?$/u.test(installedVersion)) {
|
|
88
|
+
stdout.write(`Updated version: ${installedVersion}\n`);
|
|
89
|
+
} else {
|
|
90
|
+
stderr.write("Update completed, but the installed version could not be confirmed. Run session-steward --version.\n");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return result.exitCode;
|
|
95
|
+
}
|
package/lib/server.mjs
CHANGED
|
@@ -12,6 +12,8 @@ import {
|
|
|
12
12
|
} from "./session-event-reader.mjs";
|
|
13
13
|
import { createProviderSettings } from "./settings.mjs";
|
|
14
14
|
import { createSessionProtectionStore } from "./session-protections.mjs";
|
|
15
|
+
import { createCleanupScheduleStore, runCleanupSchedule } from "./cleanup-schedules.mjs";
|
|
16
|
+
import { createCleanupSchedulerService } from "./cleanup-scheduler-service.mjs";
|
|
15
17
|
import { classifyInstalledVersion } from "./version-support.mjs";
|
|
16
18
|
import {
|
|
17
19
|
acquireSessionMutationLock,
|
|
@@ -35,6 +37,10 @@ const ALLOWED_SORTS = new Set(["created", "cwd", "name", "size", "updated"]);
|
|
|
35
37
|
const publicDirectory = path.join(path.dirname(fileURLToPath(import.meta.url)), "..", "dist");
|
|
36
38
|
const staticAssets = new Map([
|
|
37
39
|
["/", { fileName: "index.html", contentType: "text/html; charset=utf-8" }],
|
|
40
|
+
["/automatic-cleanup", { fileName: "index.html", contentType: "text/html; charset=utf-8" }],
|
|
41
|
+
["/automatic-cleanup/", { fileName: "index.html", contentType: "text/html; charset=utf-8" }],
|
|
42
|
+
["/scheduled-cleanup", { fileName: "index.html", contentType: "text/html; charset=utf-8" }],
|
|
43
|
+
["/scheduled-cleanup/", { fileName: "index.html", contentType: "text/html; charset=utf-8" }],
|
|
38
44
|
]);
|
|
39
45
|
|
|
40
46
|
function providerOptions(providerId, home) {
|
|
@@ -127,6 +133,25 @@ function normalizeIds(value) {
|
|
|
127
133
|
return [...new Set(value)];
|
|
128
134
|
}
|
|
129
135
|
|
|
136
|
+
const SCHEDULE_FIELDS = new Set([
|
|
137
|
+
"archiveStatus", "cleanupMode", "enabled", "inactiveDays", "includeInternals",
|
|
138
|
+
"includeSupporting", "maxSessions", "minimumTranscriptBytes", "name", "provider",
|
|
139
|
+
"runEveryDays", "selectionOrder", "workspace",
|
|
140
|
+
]);
|
|
141
|
+
|
|
142
|
+
function scheduleDefinition(body) {
|
|
143
|
+
if (!body || typeof body !== "object" || Array.isArray(body)
|
|
144
|
+
|| Object.keys(body).some((key) => !SCHEDULE_FIELDS.has(key))) {
|
|
145
|
+
throw new Error("Enter valid cleanup schedule settings.");
|
|
146
|
+
}
|
|
147
|
+
for (const field of ["enabled", "includeInternals", "includeSupporting"]) {
|
|
148
|
+
if (body[field] !== undefined && typeof body[field] !== "boolean") {
|
|
149
|
+
throw new Error(`${field} must be true or false.`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return body;
|
|
153
|
+
}
|
|
154
|
+
|
|
130
155
|
function getScope(value) {
|
|
131
156
|
if (!ALLOWED_SCOPES.has(value)) {
|
|
132
157
|
throw new Error("scope must be either core or deep.");
|
|
@@ -338,7 +363,7 @@ function removeExpiredEntries(entries, ttlMs, maximum) {
|
|
|
338
363
|
}
|
|
339
364
|
}
|
|
340
365
|
|
|
341
|
-
export async function startLocalServer({ claudeHome, codexHome, configDirectory, port = 0 }) {
|
|
366
|
+
export async function startLocalServer({ claudeHome, codexHome, configDirectory, port = 0, scheduleStore, schedulerService }) {
|
|
342
367
|
if (!Number.isInteger(port) || port < 0 || port > 65535) {
|
|
343
368
|
throw new Error("port must be an integer between 0 and 65535.");
|
|
344
369
|
}
|
|
@@ -353,6 +378,12 @@ export async function startLocalServer({ claudeHome, codexHome, configDirectory,
|
|
|
353
378
|
const protectionStore = createSessionProtectionStore({
|
|
354
379
|
configDirectory: settings.getConfigDirectory(),
|
|
355
380
|
});
|
|
381
|
+
const schedules = scheduleStore ?? createCleanupScheduleStore({
|
|
382
|
+
configDirectory: settings.getConfigDirectory(),
|
|
383
|
+
});
|
|
384
|
+
const scheduler = schedulerService ?? createCleanupSchedulerService({
|
|
385
|
+
configDirectory: settings.getConfigDirectory(),
|
|
386
|
+
});
|
|
356
387
|
const mutationToken = randomBytes(32).toString("base64url");
|
|
357
388
|
let mutationInProgress = false;
|
|
358
389
|
let activeOperationId = null;
|
|
@@ -679,6 +710,108 @@ export async function startLocalServer({ claudeHome, codexHome, configDirectory,
|
|
|
679
710
|
return;
|
|
680
711
|
}
|
|
681
712
|
|
|
713
|
+
if (request.method === "GET" && requestUrl.pathname === "/api/automatic-cleanup") {
|
|
714
|
+
const [scheduleList, schedulerStatus] = await Promise.all([
|
|
715
|
+
schedules.list(),
|
|
716
|
+
scheduler.status(),
|
|
717
|
+
]);
|
|
718
|
+
sendJson(response, 200, { schedules: scheduleList, scheduler: schedulerStatus });
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
if (request.method === "POST" && requestUrl.pathname === "/api/automatic-cleanup/scheduler") {
|
|
723
|
+
requireMutationAuthorization({ request, requestUrl, token: mutationToken });
|
|
724
|
+
if (mutationInProgress || activeOperationId) {
|
|
725
|
+
sendJson(response, 409, { error: "Wait for the current cleanup or change to finish." });
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
728
|
+
const { action } = await readJsonBody(request);
|
|
729
|
+
if (action !== "start" && action !== "stop") throw new Error("Scheduler action must be start or stop.");
|
|
730
|
+
mutationInProgress = true;
|
|
731
|
+
try {
|
|
732
|
+
sendJson(response, 200, { scheduler: await scheduler[action]() });
|
|
733
|
+
} finally {
|
|
734
|
+
mutationInProgress = false;
|
|
735
|
+
}
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
const scheduleRoute = /^\/api\/automatic-cleanup\/schedules(?:\/([^/]+)(\/run)?)?$/u.exec(requestUrl.pathname);
|
|
740
|
+
if (scheduleRoute) {
|
|
741
|
+
requireMutationAuthorization({ request, requestUrl, token: mutationToken });
|
|
742
|
+
if (mutationInProgress || activeOperationId) {
|
|
743
|
+
sendJson(response, 409, { error: "Wait for the current cleanup or change to finish." });
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
const id = scheduleRoute[1] ? decodeURIComponent(scheduleRoute[1]) : null;
|
|
747
|
+
const runRoute = scheduleRoute[2] === "/run";
|
|
748
|
+
mutationInProgress = true;
|
|
749
|
+
try {
|
|
750
|
+
if (request.method === "POST" && !id) {
|
|
751
|
+
const definition = scheduleDefinition(await readJsonBody(request));
|
|
752
|
+
const providerSetting = settings.getAll()[definition.provider];
|
|
753
|
+
const schedule = await schedules.save({
|
|
754
|
+
...definition,
|
|
755
|
+
providerHomeOverride: providerSetting?.source === "startup"
|
|
756
|
+
? settings.getHome(definition.provider)
|
|
757
|
+
: null,
|
|
758
|
+
});
|
|
759
|
+
let schedulerStatus;
|
|
760
|
+
let warning = null;
|
|
761
|
+
try {
|
|
762
|
+
schedulerStatus = schedule.enabled ? await scheduler.start() : await scheduler.status();
|
|
763
|
+
} catch (error) {
|
|
764
|
+
schedulerStatus = await scheduler.status();
|
|
765
|
+
warning = `Schedule saved, but the background scheduler could not start: ${error.message}`;
|
|
766
|
+
}
|
|
767
|
+
sendJson(response, 200, { schedule, scheduler: schedulerStatus, warning });
|
|
768
|
+
} else if (request.method === "PUT" && id && !runRoute) {
|
|
769
|
+
const definition = scheduleDefinition(await readJsonBody(request));
|
|
770
|
+
const existing = (await schedules.list()).find((schedule) => schedule.id === id);
|
|
771
|
+
if (!existing) throw new Error("That cleanup schedule does not exist.");
|
|
772
|
+
const providerSetting = settings.getAll()[definition.provider];
|
|
773
|
+
const providerChanged = existing.provider !== definition.provider;
|
|
774
|
+
const schedule = await schedules.save({
|
|
775
|
+
...definition,
|
|
776
|
+
...(providerChanged ? {
|
|
777
|
+
providerHomeOverride: providerSetting?.source === "startup"
|
|
778
|
+
? settings.getHome(definition.provider)
|
|
779
|
+
: null,
|
|
780
|
+
} : {}),
|
|
781
|
+
}, { id });
|
|
782
|
+
let schedulerStatus;
|
|
783
|
+
let warning = null;
|
|
784
|
+
try {
|
|
785
|
+
schedulerStatus = schedule.enabled && !existing.enabled
|
|
786
|
+
? await scheduler.start()
|
|
787
|
+
: await scheduler.status();
|
|
788
|
+
} catch (error) {
|
|
789
|
+
schedulerStatus = await scheduler.status();
|
|
790
|
+
warning = `Schedule saved, but the background scheduler could not start: ${error.message}`;
|
|
791
|
+
}
|
|
792
|
+
sendJson(response, 200, { schedule, scheduler: schedulerStatus, warning });
|
|
793
|
+
} else if (request.method === "DELETE" && id && !runRoute) {
|
|
794
|
+
await schedules.remove(id);
|
|
795
|
+
sendJson(response, 200, { id, removed: true });
|
|
796
|
+
} else if (request.method === "POST" && id && runRoute) {
|
|
797
|
+
const run = await runCleanupSchedule({
|
|
798
|
+
force: true,
|
|
799
|
+
id,
|
|
800
|
+
protectionStore,
|
|
801
|
+
scheduleStore: schedules,
|
|
802
|
+
settings,
|
|
803
|
+
});
|
|
804
|
+
invalidateSessionOverview();
|
|
805
|
+
sendJson(response, 200, { run });
|
|
806
|
+
} else {
|
|
807
|
+
sendJson(response, 404, { error: "Route not found." });
|
|
808
|
+
}
|
|
809
|
+
} finally {
|
|
810
|
+
mutationInProgress = false;
|
|
811
|
+
}
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
|
|
682
815
|
if (request.method === "PUT" && requestUrl.pathname === "/api/settings/active-provider") {
|
|
683
816
|
requireMutationAuthorization({ request, requestUrl, token: mutationToken });
|
|
684
817
|
|
package/lib/update-check.mjs
CHANGED
|
@@ -80,6 +80,6 @@ export async function findAvailableUpdate({
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
export function formatUpdateNotice({ latestVersion
|
|
84
|
-
return `Session Steward ${latestVersion} is available. Update with:
|
|
83
|
+
export function formatUpdateNotice({ latestVersion }) {
|
|
84
|
+
return `Session Steward ${latestVersion} is available. Update with: session-steward update`;
|
|
85
85
|
}
|