forkit-ai-footprints 0.2.1 → 0.2.4

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.
@@ -16,27 +16,28 @@ function renderActivityApplicationPage(input) {
16
16
  <style>
17
17
  :root{--bg:#f1ece3;--paper:#fbf8f2;--surface:#f6f1e9;--surface-2:#ece7de;--ink:#282624;--muted:#736e66;--line:rgba(40,38,36,.14);--line-strong:rgba(40,38,36,.24);--brand:#00888d;--brand-soft:#d9eeee;--active:#00888d;--idle:#cfc8bd;--excluded:#8a857e;--gold:#d99022;--good:#237d65;--shadow:0 18px 55px rgba(38,34,30,.08)}
18
18
  @media(prefers-color-scheme:dark){:root{--bg:#151716;--paper:#202220;--surface:#292b28;--surface-2:#343632;--ink:#f3eee4;--muted:#aaa49a;--line:rgba(243,238,228,.13);--line-strong:rgba(243,238,228,.24);--brand:#69c3bd;--brand-soft:#203c39;--active:#69c3bd;--idle:#4c4944;--excluded:#858079;--gold:#e4ae39;--good:#69bea4;--shadow:0 20px 60px rgba(0,0,0,.27)}}
19
- *{box-sizing:border-box}html{background:var(--bg)}body{margin:0;color:var(--ink);background:radial-gradient(circle at 0 0,color-mix(in srgb,var(--gold) 12%,transparent),transparent 28rem),radial-gradient(circle at 100% 0,color-mix(in srgb,var(--brand) 13%,transparent),transparent 30rem),var(--bg);font-family:Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;-webkit-font-smoothing:antialiased}button{font:inherit}[hidden]{display:none!important}.shell{width:min(1220px,calc(100% - 24px));margin:auto;padding:12px 0 24px}.surface{border:1px solid var(--line);border-radius:18px;background:color-mix(in srgb,var(--paper) 94%,transparent);box-shadow:var(--shadow)}
19
+ *{box-sizing:border-box}html{background:var(--bg)}body{margin:0;overflow-x:hidden;color:var(--ink);background:radial-gradient(circle at 0 0,color-mix(in srgb,var(--gold) 12%,transparent),transparent 28rem),radial-gradient(circle at 100% 0,color-mix(in srgb,var(--brand) 13%,transparent),transparent 30rem),var(--bg);font-family:Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;-webkit-font-smoothing:antialiased}button{font:inherit}[hidden]{display:none!important}.shell{width:min(1220px,calc(100% - 24px));margin:auto;padding:12px 0 24px}.surface{border:1px solid var(--line);border-radius:18px;background:color-mix(in srgb,var(--paper) 94%,transparent);box-shadow:var(--shadow)}
20
20
  .command{position:relative;display:flex;min-height:54px;align-items:center;justify-content:space-between;gap:16px;padding:8px 10px 8px 12px}.brand{display:flex;min-width:0;align-items:center;gap:10px}.brand-icon,.brand-fallback{width:34px;height:34px;border-radius:10px;object-fit:contain}.brand-fallback{display:grid;place-items:center;color:#fff;background:linear-gradient(145deg,var(--brand),var(--gold));font-weight:900}.brand-copy{min-width:0}.brand-copy strong{display:block;font-size:14px;letter-spacing:-.02em}.status{display:flex;align-items:center;gap:7px;margin-top:2px;color:var(--muted);font-size:10px}.status-dot{width:7px;height:7px;border-radius:999px;background:var(--good);box-shadow:0 0 0 3px color-mix(in srgb,var(--good) 13%,transparent)}.status.paused .status-dot{background:var(--gold)}.status.stopped .status-dot{background:var(--muted)}.command-actions{display:flex;align-items:center;gap:6px}.privacy-chip{display:inline-flex;align-items:center;gap:6px;padding:0 9px;color:var(--muted);font-size:9px;font-weight:760}.privacy-chip b{color:var(--good)}.button,.icon-button{min-height:32px;border:1px solid var(--line-strong);border-radius:9px;color:var(--ink);background:transparent;cursor:pointer;font-size:10px;font-weight:780}.button{padding:0 12px}.button.primary{border-color:var(--brand);color:#fff;background:var(--brand)}.button:disabled{cursor:not-allowed;opacity:.45}.locale{display:flex;padding:2px;border:1px solid var(--line);border-radius:9px}.locale button{min-width:30px;min-height:26px;border:0;border-radius:7px;color:var(--muted);background:transparent;cursor:pointer;font-size:9px;font-weight:850}.locale button.active{color:var(--ink);background:var(--surface-2)}.more{position:relative}.more summary{display:grid;min-width:48px;min-height:32px;place-items:center;border:1px solid var(--line-strong);border-radius:9px;cursor:pointer;font-size:10px;font-weight:780;list-style:none}.more summary::-webkit-details-marker{display:none}.more-menu{position:absolute;z-index:20;right:0;top:40px;display:grid;width:190px;gap:6px;padding:8px;border:1px solid var(--line);border-radius:12px;background:var(--paper);box-shadow:var(--shadow)}.more-menu .button{width:100%;text-align:left}.scan-status{padding:3px 7px;color:var(--muted);font-size:9px;line-height:1.4}
21
21
  .metric-rail{display:grid;grid-template-columns:1.12fr .9fr 1fr;margin-top:8px;overflow:hidden}.headline{min-height:70px;padding:11px 14px;border-right:1px solid var(--line)}.headline:last-child{border-right:0}.metric-label{color:var(--muted);font-size:8px;font-weight:850;letter-spacing:.12em;text-transform:uppercase}.metric-value{display:block;margin-top:6px;font-size:22px;font-weight:900;letter-spacing:-.045em}.headline:first-child .metric-value{color:var(--active);font-size:27px}.metric-sub{display:block;margin-top:1px;color:var(--muted);font-size:8px}
22
22
  .workspace{display:grid;grid-template-columns:minmax(0,1fr) 350px;gap:8px;margin-top:8px;align-items:start}.explorer{min-width:0;padding:12px}.panel-head{display:flex;align-items:start;justify-content:space-between;gap:12px}.eyebrow{margin:0 0 3px;color:var(--brand);font-size:8px;font-weight:900;letter-spacing:.14em;text-transform:uppercase}.panel-head h1,.panel-head h2,.compact h2{margin:0;font-size:16px;letter-spacing:-.025em}.panel-copy{margin:3px 0 0;color:var(--muted);font-size:9px}.chart-controls{display:flex;gap:4px}.icon-button{min-width:31px;padding:0 8px}.chart-wrap{position:relative;margin-top:8px}.chart-canvas{display:block;width:100%;height:206px;border:1px solid var(--line);border-radius:12px;background:var(--surface);outline:none}.navigator{display:block;width:100%;height:30px;margin-top:5px;border:1px solid var(--line);border-radius:8px;background:var(--surface);cursor:pointer}.chart-tooltip{position:absolute;z-index:10;max-width:240px;padding:8px 9px;border:1px solid var(--line-strong);border-radius:9px;color:var(--ink);background:var(--paper);box-shadow:var(--shadow);font-size:9px;line-height:1.45;pointer-events:none}.chart-help{display:flex;justify-content:space-between;gap:12px;margin-top:5px;color:var(--muted);font-size:8px}.legend{display:flex;gap:11px;flex-wrap:wrap}.legend span{display:inline-flex;align-items:center;gap:5px}.legend i{width:8px;height:8px;border-radius:2px;background:var(--idle)}.legend .active{background:var(--active)}.legend .excluded{background:repeating-linear-gradient(135deg,var(--excluded),var(--excluded) 2px,transparent 2px,transparent 4px);border:1px solid var(--excluded)}.selected-evidence{min-height:34px;padding:7px 8px;border:1px solid var(--line);border-radius:9px;color:var(--muted);background:var(--surface);font-size:9px;line-height:1.4}.selected-evidence strong{color:var(--ink)}
23
23
  .insight-rail{display:flex;max-height:calc(100vh - 86px);min-height:420px;flex-direction:column;padding:12px;overflow:auto;scrollbar-width:thin}.insight-rail h2{margin:0;font-size:17px;letter-spacing:-.025em}.insight-copy{margin:3px 0 8px;color:var(--muted);font-size:9px}.device-identity{display:flex;align-items:start;justify-content:space-between;gap:10px;padding-bottom:9px;border-bottom:1px solid var(--line)}.device-identity strong{display:block;max-width:220px;overflow:hidden;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.observation-number{flex:none;padding:4px 6px;border:1px solid var(--line);border-radius:7px;color:var(--muted);font-size:8px;font-weight:800}.rail-section{padding:10px 0;border-bottom:1px solid var(--line)}.rail-section:last-child{padding-bottom:0;border-bottom:0}.rail-heading{display:flex;align-items:end;justify-content:space-between;gap:8px;margin-bottom:6px}.rail-heading strong{font-size:10px}.rail-heading span{color:var(--muted);font-size:7px}.insight-list{display:grid;gap:6px;margin-top:6px}.insight{width:100%;padding:8px 9px;border:1px solid var(--line);border-left:3px solid var(--accent-system,var(--brand));border-radius:9px;color:var(--ink);background:var(--surface);text-align:left;cursor:pointer;font-size:9px;font-weight:720;line-height:1.35}.insight:hover,.insight:focus-visible{border-color:var(--accent-system,var(--brand));outline:none}.early{padding:10px;border:1px dashed var(--line-strong);border-radius:9px;color:var(--muted);font-size:9px;line-height:1.45}.observation-grid,.resource-grid{display:grid;grid-template-columns:1fr 1fr;gap:5px}.rail-stat{min-width:0;padding:7px 8px;border:1px solid var(--line);border-radius:8px;background:var(--surface)}.rail-stat span{display:block;color:var(--muted);font-size:7px;font-weight:780;letter-spacing:.07em;text-transform:uppercase}.rail-stat strong{display:block;margin-top:3px;overflow:hidden;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.rail-list{display:grid;gap:5px}.runtime-item{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:7px 8px;border:1px solid var(--line);border-radius:8px;background:var(--surface);font-size:8px}.runtime-item strong{font-size:9px}.runtime-item span{color:var(--muted);text-align:right}.system-mix{padding-top:10px}.mix-bar{display:flex;height:9px;margin-top:7px;overflow:hidden;border-radius:999px;background:var(--surface-2)}.mix-bar button{height:100%;min-width:3px;border:0;padding:0;cursor:pointer}.mix-list{display:grid;gap:4px;margin-top:7px}.mix-item{display:grid;grid-template-columns:9px minmax(0,1fr) auto;align-items:center;gap:6px;width:100%;border:1px solid transparent;border-radius:8px;padding:6px;color:var(--muted);background:transparent;cursor:pointer;text-align:left;font-size:8px}.mix-item:hover,.mix-item:focus-visible{border-color:var(--line);outline:none}.mix-item i{width:7px;height:7px;border-radius:2px;background:var(--system-color)}.mix-item strong{overflow:hidden;color:var(--ink);font-size:9px;text-overflow:ellipsis;white-space:nowrap}.all-apps{display:block;width:100%;margin-top:7px}.app-inspector{display:grid;gap:6px;margin-top:7px;padding-top:7px;border-top:1px solid var(--line)}
24
- .observation-tools{display:grid;grid-template-columns:repeat(4,1fr);gap:5px;padding:10px 0;border-bottom:1px solid var(--line)}.feature-tool{position:relative;display:grid;min-width:0;min-height:58px;place-items:center;gap:3px;padding:7px 3px;border:1px solid var(--line);border-radius:10px;color:var(--muted);background:var(--surface);cursor:pointer}.feature-tool:hover,.feature-tool:focus-visible{z-index:4;border-color:var(--brand);color:var(--ink);outline:none}.feature-tool[aria-pressed="true"]{border-color:var(--brand);color:var(--ink);background:color-mix(in srgb,var(--brand-soft) 64%,var(--surface))}.feature-icon{display:grid;width:22px;height:22px;place-items:center;border-radius:7px;color:var(--brand);background:var(--paper);font-size:15px;font-weight:900}.feature-tool>span:last-of-type{overflow:hidden;max-width:100%;font-size:7px;font-weight:850;text-overflow:ellipsis;white-space:nowrap}.feature-tool::after{position:absolute;z-index:30;top:calc(100% + 5px);left:50%;display:none;width:150px;padding:7px 8px;border:1px solid var(--line-strong);border-radius:8px;color:var(--ink);background:var(--paper);box-shadow:var(--shadow);content:attr(data-tip);font-size:8px;font-weight:650;line-height:1.35;transform:translateX(-50%);pointer-events:none}.feature-tool:first-child::after{left:0;transform:none}.feature-tool:last-child::after{right:0;left:auto;transform:none}.feature-tool:hover::after,.feature-tool:focus-visible::after{display:block}.focus-summary{display:grid;grid-template-columns:minmax(150px,.65fr) minmax(0,1.35fr);gap:8px;margin-top:8px;padding:9px;border:1px solid var(--line);border-left:3px solid var(--accent-system,var(--brand));border-radius:10px;background:var(--surface)}.focus-copy strong{display:block;font-size:12px}.focus-copy span{display:block;margin-top:3px;color:var(--muted);font-size:8px;line-height:1.4}.focus-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:5px}.focus-stats .inspector-stat{padding:6px}.focus-stats .inspector-stat strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rail-section[data-view]{cursor:pointer}.rail-section[data-view]:hover .rail-heading strong{color:var(--brand)}
24
+ .observation-tools{display:grid;grid-template-columns:repeat(2,1fr);gap:5px;padding:10px 0;border-bottom:1px solid var(--line)}.feature-tool{position:relative;display:grid;min-width:0;min-height:58px;place-items:center;gap:3px;padding:7px 3px;border:1px solid var(--line);border-radius:10px;color:var(--muted);background:var(--surface);cursor:pointer}.feature-tool:hover,.feature-tool:focus-visible{z-index:4;border-color:var(--brand);color:var(--ink);outline:none}.feature-tool[aria-pressed="true"]{border-color:var(--brand);color:var(--ink);background:color-mix(in srgb,var(--brand-soft) 64%,var(--surface))}.feature-icon{display:grid;width:22px;height:22px;place-items:center;border-radius:7px;color:var(--brand);background:var(--paper);font-size:15px;font-weight:900}.feature-tool>span:last-of-type{overflow:hidden;max-width:100%;font-size:7px;font-weight:850;text-overflow:ellipsis;white-space:nowrap}.feature-tool::after{position:absolute;z-index:30;top:calc(100% + 5px);left:50%;display:none;width:150px;padding:7px 8px;border:1px solid var(--line-strong);border-radius:8px;color:var(--ink);background:var(--paper);box-shadow:var(--shadow);content:attr(data-tip);font-size:8px;font-weight:650;line-height:1.35;transform:translateX(-50%);pointer-events:none}.feature-tool:first-child::after{left:0;transform:none}.feature-tool:last-child::after{right:0;left:auto;transform:none}.feature-tool:hover::after,.feature-tool:focus-visible::after{display:block}.focus-summary{display:grid;grid-template-columns:minmax(150px,.65fr) minmax(0,1.35fr);gap:8px;margin-top:8px;padding:9px;border:1px solid var(--line);border-left:3px solid var(--accent-system,var(--brand));border-radius:10px;background:var(--surface)}.focus-copy strong{display:block;font-size:12px}.focus-copy span{display:block;margin-top:3px;color:var(--muted);font-size:8px;line-height:1.4}.focus-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:5px}.focus-stats .inspector-stat{padding:6px}.focus-stats .inspector-stat strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rail-section[data-view]{cursor:pointer}.rail-section[data-view]:hover .rail-heading strong{color:var(--brand)}
25
25
  .summary-row{display:grid;grid-template-columns:1.55fr 1fr .82fr;gap:8px;margin-top:8px}.compact{min-height:126px;padding:12px}.compact-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:9px}.compact-stat{min-width:0;padding-right:8px;border-right:1px solid var(--line)}.compact-stat:last-child{border-right:0}.compact-stat strong{display:block;margin-top:5px;overflow:hidden;font-size:13px;text-overflow:ellipsis;white-space:nowrap}.compact-stat span{display:block;margin-top:2px;color:var(--muted);font-size:8px}.compact-stat strong>span{display:inline;margin:0;color:inherit;font-size:inherit}.statement{margin:9px 0 0;padding:7px 8px;border-left:3px solid var(--accent-system,var(--brand));border-radius:6px;color:var(--ink);background:var(--surface);font-size:9px;font-weight:720;line-height:1.35}.global-state{display:flex;height:100%;flex-direction:column;justify-content:space-between}.global-state strong{font-size:18px;letter-spacing:-.03em}.global-state p{margin:4px 0;color:var(--muted);font-size:9px;line-height:1.4}
26
26
  .advanced{margin-top:8px;padding:0 12px}.advanced>summary{padding:11px 0;cursor:pointer;font-size:10px;font-weight:800}.details-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:7px;padding:0 0 12px}.detail-box{min-height:95px;padding:10px;border:1px solid var(--line);border-radius:10px;background:var(--surface)}.detail-box h3{margin:0 0 7px;font-size:10px}.detail-list{display:grid;gap:5px;margin:0;padding:0;list-style:none}.detail-list li{color:var(--muted);font-size:8px;line-height:1.4}.detail-list strong{display:block;color:var(--ink);font-size:9px}.footer{display:flex;justify-content:space-between;gap:14px;padding:10px 3px 0;color:var(--muted);font-size:8px}
27
27
  dialog{width:min(780px,calc(100% - 28px));padding:0;border:1px solid var(--line);border-radius:18px;color:var(--ink);background:var(--paper);box-shadow:0 28px 90px rgba(0,0,0,.38)}dialog::backdrop{background:rgba(0,0,0,.72)}.share-layout{display:grid;grid-template-columns:minmax(280px,1fr) 250px;gap:14px;padding:14px}.share-preview{overflow:hidden;border-radius:12px;background:#ede8df}.share-preview canvas{display:block;width:100%;height:auto}.share-side{display:flex;flex-direction:column}.share-side h2{margin:0;font-size:19px}.share-side p{color:var(--muted);font-size:9px;line-height:1.45}.share-actions{display:grid;grid-template-columns:1fr 1fr;gap:6px;margin-top:auto}.share-actions .button{min-height:38px}.share-status{min-height:30px;margin-top:8px;color:var(--muted);font-size:8px;line-height:1.4}
28
28
  .temporal{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:8px 0 0;padding:7px 10px;border:1px solid var(--line);border-radius:10px;background:var(--surface)}.temporal-main{display:flex;align-items:center;gap:8px}.temporal strong{font-size:10px}.temporal span{color:var(--muted);font-size:8px}.date-picker{position:relative}.date-picker summary{cursor:pointer;list-style:none}.date-picker summary::-webkit-details-marker{display:none}.date-popover{position:absolute;z-index:14;top:28px;left:0;display:grid;min-width:220px;gap:5px;padding:8px;border:1px solid var(--line);border-radius:10px;background:var(--paper);box-shadow:var(--shadow)}.date-option{display:flex;justify-content:space-between;gap:8px;min-height:30px;align-items:center;padding:0 8px;border:1px solid var(--line);border-radius:8px;color:var(--ink);background:var(--surface);cursor:pointer;font-size:9px}.date-option.active{border-color:var(--brand);color:var(--brand)}.resource-modes{display:flex;gap:3px;padding:2px;border:1px solid var(--line);border-radius:8px}.resource-modes button{min-height:25px;padding:0 7px;border:0;border-radius:6px;color:var(--muted);background:transparent;cursor:pointer;font-size:8px;font-weight:800}.resource-modes button.active{color:#fff;background:var(--brand)}.chart-canvas{height:276px}.inspector{display:grid;gap:7px}.inspector-head{display:flex;align-items:start;justify-content:space-between;gap:8px}.inspector-head strong{font-size:14px}.inspector-state{font-size:8px;font-weight:850;text-transform:uppercase}.inspector-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px}.inspector-stat{padding:7px;border:1px solid var(--line);border-radius:8px;background:var(--surface)}.inspector-stat span{display:block;color:var(--muted);font-size:7px;text-transform:uppercase;letter-spacing:.08em}.inspector-stat strong{display:block;margin-top:3px;font-size:10px}.system-selected{color:var(--ink)!important}.mix-item[aria-pressed="true"]{color:var(--ink);font-weight:850}.mix-item[aria-pressed="true"] strong{text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:3px}.footprint-strip{display:grid;grid-template-columns:1fr auto;align-items:center;gap:12px;margin-top:8px;padding:10px 12px}.local-strip{display:flex;align-items:center;gap:22px;min-width:0}.local-strip>div{min-width:0}.local-strip strong{display:block;font-size:13px}.local-strip span{color:var(--muted);font-size:8px}.global-action{display:flex;align-items:center;gap:8px}.monitor-line{display:flex;justify-content:space-between;gap:12px;margin-top:7px;padding:0 3px;color:var(--muted);font-size:8px}
29
29
  .date-picker[data-single="true"] summary{cursor:default}.date-picker[data-single="true"] .date-popover{display:none}
30
- .shell{width:min(1760px,calc(100vw - 16px))}.workspace{grid-template-columns:minmax(240px,.25fr) minmax(680px,1fr) minmax(340px,.34fr);gap:10px}.system-panel{grid-column:1;grid-row:1;align-self:start;max-height:calc(100vh - 86px);overflow:auto;padding:12px;border:1px solid var(--line);border-radius:18px;background:color-mix(in srgb,var(--paper) 94%,transparent);box-shadow:var(--shadow);scrollbar-width:thin}.system-panel .rail-heading{align-items:center}.system-panel .mix-bar{height:6px}.system-panel .mix-list{gap:6px}.system-panel .mix-item{grid-template-columns:10px minmax(0,1fr);padding:9px 8px;border-color:var(--line);background:var(--surface)}.system-panel .mix-item>span{grid-column:2}.system-panel .mix-item[aria-pressed="true"]{border-color:var(--system-color);box-shadow:inset 3px 0 0 var(--system-color)}.system-panel .mix-item.is-focused{background:color-mix(in srgb,var(--system-color) 14%,var(--surface))}.system-actions{display:grid;grid-template-columns:1fr 1fr;gap:5px;margin-top:7px}.system-actions .button{padding:0 7px;font-size:8px}.system-help{margin:6px 0 0;color:var(--muted);font-size:7px;line-height:1.4}.workspace>.explorer{grid-column:2;grid-row:1}.workspace>.insight-rail{grid-column:3;grid-row:1}.explorer{overflow:hidden}.chart-wrap{min-height:270px}.legacy-timeline{position:absolute!important;left:-9999px!important;width:1px!important;height:1px!important;opacity:0;pointer-events:none}.system-timeline{display:grid;gap:7px;min-height:244px;padding:10px;border:1px solid var(--line);border-radius:12px;background:linear-gradient(180deg,color-mix(in srgb,var(--surface) 96%,transparent),var(--surface))}.timeline-axis,.timeline-row{display:grid;grid-template-columns:minmax(88px,112px) minmax(0,1fr);gap:8px;align-items:center}.timeline-axis-label{color:var(--muted);font-size:7px;font-weight:800;text-transform:uppercase}.timeline-ticks{position:relative;height:22px;border-bottom:1px solid var(--line)}.timeline-tick{position:absolute;bottom:4px;color:var(--muted);font-size:7px;transform:translateX(-50%);white-space:nowrap}.timeline-tick:first-child{transform:none}.timeline-tick:last-child{transform:translateX(-100%)}.timeline-row{min-height:50px}.timeline-system{display:grid;grid-template-columns:9px minmax(0,1fr);align-items:center;gap:7px;width:100%;padding:7px;border:1px solid transparent;border-radius:9px;color:var(--ink);background:transparent;cursor:pointer;text-align:left}.timeline-system:hover,.timeline-system:focus-visible{border-color:var(--line-strong);outline:none}.timeline-system[aria-pressed="true"]{border-color:var(--system-color);background:color-mix(in srgb,var(--system-color) 10%,transparent)}.timeline-system i{width:8px;height:8px;border-radius:3px;background:var(--system-color)}.timeline-system strong{overflow:hidden;font-size:9px;text-overflow:ellipsis;white-space:nowrap}.timeline-system span{grid-column:2;color:var(--muted);font-size:7px}.timeline-track{position:relative;height:42px;overflow:hidden;border:1px solid var(--line);border-radius:9px;background:repeating-linear-gradient(135deg,var(--surface-2),var(--surface-2) 5px,color-mix(in srgb,var(--surface-2) 70%,transparent) 5px,color-mix(in srgb,var(--surface-2) 70%,transparent) 10px)}.timeline-row.is-selected .timeline-track{border-color:var(--system-color)}.timeline-row.is-focused .timeline-track{box-shadow:0 0 0 1px var(--system-color),0 0 20px color-mix(in srgb,var(--system-color) 18%,transparent)}.timeline-block{position:absolute;top:4px;bottom:4px;min-width:3px;overflow:hidden;border:1px solid color-mix(in srgb,var(--system-color) 72%,white);border-radius:6px;color:#fff;background:color-mix(in srgb,var(--system-color) 76%,#071315);cursor:pointer;text-align:left;font-size:7px;font-weight:800;white-space:nowrap}.timeline-block:hover,.timeline-block:focus-visible{z-index:3;filter:brightness(1.14);outline:2px solid color-mix(in srgb,var(--system-color) 65%,white)}.timeline-block.is-longest{box-shadow:inset 0 -3px 0 var(--gold)}.timeline-block.is-pinned{outline:2px solid var(--ink);outline-offset:1px}.timeline-empty{display:grid;height:100%;place-items:center;color:var(--muted);font-size:8px}.focus-summary{margin-top:7px}.navigator{height:28px}.below-timeline{display:grid;grid-template-columns:1.25fr 1fr 1fr;gap:7px;margin-top:9px}.below-card{min-width:0;padding:10px;border:1px solid var(--line);border-radius:11px;background:var(--surface)}.below-card h2{margin:0;font-size:11px}.observation-metrics{grid-column:1/-1}.below-metrics{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:5px;margin-top:7px}.below-stat{min-width:0;padding:7px;border:1px solid var(--line);border-radius:8px;background:var(--paper)}.below-stat span{display:block;color:var(--muted);font-size:7px;font-weight:760;text-transform:uppercase}.below-stat strong{display:block;margin-top:3px;overflow:hidden;font-size:10px;text-overflow:ellipsis;white-space:nowrap}.runtime-footprint-list{display:grid;gap:5px;margin-top:7px}.runtime-footprint-row{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:7px;align-items:center;padding:7px;border:1px solid var(--line);border-radius:8px;background:var(--paper);cursor:pointer}.runtime-footprint-row:hover,.runtime-footprint-row:focus-visible{border-color:var(--system-color);outline:none}.runtime-footprint-row.is-selected{box-shadow:inset 3px 0 0 var(--system-color)}.runtime-footprint-row strong{overflow:hidden;font-size:8px;text-overflow:ellipsis;white-space:nowrap}.runtime-footprint-row span{color:var(--muted);font-size:7px}.resource-summary,.local-summary{display:grid;grid-template-columns:1fr 1fr;gap:5px;margin-top:7px}.truth-note{margin:7px 0 0;color:var(--muted);font-size:7px;line-height:1.4}.insight-rail [data-view][hidden]{display:none!important}.inspector-app-list{display:grid;gap:5px}.inspector-app-row{padding:7px;border:1px solid var(--line);border-radius:8px;background:var(--surface)}.inspector-app-row strong{display:block;font-size:9px}.inspector-app-row span{display:block;margin-top:2px;color:var(--muted);font-size:7px}.footprint-strip{display:none}.metric-rail{display:none}.center-app-list{display:grid;gap:6px;margin-top:8px}.center-app-row{display:grid;grid-template-columns:minmax(120px,1fr) repeat(3,minmax(74px,.55fr));gap:6px;align-items:center;width:100%;padding:9px;border:1px solid var(--line);border-radius:9px;color:var(--ink);background:var(--paper);cursor:pointer;text-align:left}.center-app-row:hover,.center-app-row:focus-visible,.center-app-row.is-selected{border-color:var(--system-color);outline:none}.center-app-row strong{font-size:9px}.center-app-row span{color:var(--muted);font-size:7px}.below-timeline>[data-center-view]{display:none}.insight-rail .rail-section[data-view="pulse"]{display:block!important}.insight-rail .rail-section[data-view="runtime"],.insight-rail .rail-section[data-view="resources"],.insight-rail .rail-section[data-view="apps"]{display:none!important}html[data-explorer-mode="pulse"] .focus-summary{display:none}html[data-explorer-mode="pulse"] .below-timeline>[data-center-view="pulse"],html[data-explorer-mode="runtime"] .below-timeline>[data-center-view="runtime"],html[data-explorer-mode="resources"] .below-timeline>[data-center-view="resources"],html[data-explorer-mode="apps"] .below-timeline>[data-center-view="apps"]{display:block;grid-column:1/-1}html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .temporal,html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .chart-wrap,html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .chart-help,html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .chart-controls{display:none}html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .focus-summary{display:grid;grid-template-columns:minmax(150px,.65fr) minmax(0,1.35fr);min-height:150px;align-content:start}html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .below-timeline{grid-template-columns:1fr}.resource-modes{display:none}
30
+ .shell{width:min(1760px,calc(100vw - 16px))}.workspace{grid-template-columns:minmax(240px,.25fr) minmax(680px,1fr) minmax(340px,.34fr);gap:10px}.workspace>*{min-width:0}.system-panel{grid-column:1;grid-row:1;align-self:start;max-height:calc(100vh - 86px);overflow:auto;padding:12px;border:1px solid var(--line);border-radius:18px;background:color-mix(in srgb,var(--paper) 94%,transparent);box-shadow:var(--shadow);scrollbar-width:thin}.system-panel .rail-heading{align-items:center}.system-panel .mix-bar{height:6px}.system-panel .mix-list{gap:6px}.system-panel .mix-item{grid-template-columns:10px minmax(0,1fr);padding:9px 8px;border-color:var(--line);background:var(--surface)}.system-panel .mix-item>span{grid-column:2}.system-panel .mix-item[aria-pressed="true"]{border-color:var(--system-color);box-shadow:inset 3px 0 0 var(--system-color)}.system-panel .mix-item.is-focused{background:color-mix(in srgb,var(--system-color) 14%,var(--surface))}.system-actions{display:grid;grid-template-columns:1fr 1fr;gap:5px;margin-top:7px}.system-actions .button{padding:0 7px;font-size:8px}.system-help{margin:6px 0 0;color:var(--muted);font-size:7px;line-height:1.4}.workspace>.explorer{grid-column:2;grid-row:1}.workspace>.insight-rail{grid-column:3;grid-row:1}.explorer{overflow:hidden}.chart-wrap{min-height:270px}.legacy-timeline{position:absolute!important;left:-9999px!important;width:1px!important;height:1px!important;opacity:0;pointer-events:none}.system-timeline{display:grid;gap:7px;min-height:244px;padding:10px;border:1px solid var(--line);border-radius:12px;background:linear-gradient(180deg,color-mix(in srgb,var(--surface) 96%,transparent),var(--surface))}.timeline-axis,.timeline-row{display:grid;grid-template-columns:minmax(88px,112px) minmax(0,1fr);gap:8px;align-items:center}.timeline-axis-label{color:var(--muted);font-size:7px;font-weight:800;text-transform:uppercase}.timeline-ticks{position:relative;height:22px;border-bottom:1px solid var(--line)}.timeline-tick{position:absolute;bottom:4px;color:var(--muted);font-size:7px;transform:translateX(-50%);white-space:nowrap}.timeline-tick:first-child{transform:none}.timeline-tick:last-child{transform:translateX(-100%)}.timeline-row{min-height:50px}.timeline-system{display:grid;grid-template-columns:9px minmax(0,1fr);align-items:center;gap:7px;width:100%;padding:7px;border:1px solid transparent;border-radius:9px;color:var(--ink);background:transparent;cursor:pointer;text-align:left}.timeline-system:hover,.timeline-system:focus-visible{border-color:var(--line-strong);outline:none}.timeline-system[aria-pressed="true"]{border-color:var(--system-color);background:color-mix(in srgb,var(--system-color) 10%,transparent)}.timeline-system i{width:8px;height:8px;border-radius:3px;background:var(--system-color)}.timeline-system strong{overflow:hidden;font-size:9px;text-overflow:ellipsis;white-space:nowrap}.timeline-system span{grid-column:2;color:var(--muted);font-size:7px}.timeline-track{position:relative;height:42px;overflow:hidden;border:1px solid var(--line);border-radius:9px;background:repeating-linear-gradient(135deg,var(--surface-2),var(--surface-2) 5px,color-mix(in srgb,var(--surface-2) 70%,transparent) 5px,color-mix(in srgb,var(--surface-2) 70%,transparent) 10px)}.timeline-row.is-selected .timeline-track{border-color:var(--system-color)}.timeline-row.is-focused .timeline-track{box-shadow:0 0 0 1px var(--system-color),0 0 20px color-mix(in srgb,var(--system-color) 18%,transparent)}.timeline-block{position:absolute;top:4px;bottom:4px;min-width:3px;overflow:hidden;border:1px solid color-mix(in srgb,var(--system-color) 72%,white);border-radius:6px;color:#fff;background:color-mix(in srgb,var(--system-color) 76%,#071315);cursor:pointer;text-align:left;font-size:7px;font-weight:800;white-space:nowrap}.timeline-block:hover,.timeline-block:focus-visible{z-index:3;filter:brightness(1.14);outline:2px solid color-mix(in srgb,var(--system-color) 65%,white)}.timeline-block.is-longest{box-shadow:inset 0 -3px 0 var(--gold)}.timeline-block.is-pinned{outline:2px solid var(--ink);outline-offset:1px}.timeline-empty{display:grid;height:100%;place-items:center;color:var(--muted);font-size:8px}.focus-summary{margin-top:7px}.navigator{height:28px}.below-timeline{display:grid;grid-template-columns:1.25fr 1fr 1fr;gap:7px;margin-top:9px}.below-card{min-width:0;padding:10px;border:1px solid var(--line);border-radius:11px;background:var(--surface)}.below-card h2{margin:0;font-size:11px}.observation-metrics{grid-column:1/-1}.below-metrics{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:5px;margin-top:7px}.below-stat{min-width:0;padding:7px;border:1px solid var(--line);border-radius:8px;background:var(--paper)}.below-stat span{display:block;color:var(--muted);font-size:7px;font-weight:760;text-transform:uppercase}.below-stat strong{display:block;margin-top:3px;overflow:hidden;font-size:10px;text-overflow:ellipsis;white-space:nowrap}.runtime-footprint-list{display:grid;gap:5px;margin-top:7px}.runtime-footprint-row{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:7px;align-items:center;padding:7px;border:1px solid var(--line);border-radius:8px;background:var(--paper);cursor:pointer}.runtime-footprint-row:hover,.runtime-footprint-row:focus-visible{border-color:var(--system-color);outline:none}.runtime-footprint-row.is-selected{box-shadow:inset 3px 0 0 var(--system-color)}.runtime-footprint-row strong{overflow:hidden;font-size:8px;text-overflow:ellipsis;white-space:nowrap}.runtime-footprint-row span{color:var(--muted);font-size:7px}.resource-summary,.local-summary{display:grid;grid-template-columns:1fr 1fr;gap:5px;margin-top:7px}.truth-note{margin:7px 0 0;color:var(--muted);font-size:7px;line-height:1.4}.insight-rail [data-view][hidden]{display:none!important}.inspector-app-list{display:grid;gap:5px}.inspector-app-row{padding:7px;border:1px solid var(--line);border-radius:8px;background:var(--surface)}.inspector-app-row strong{display:block;font-size:9px}.inspector-app-row span{display:block;margin-top:2px;color:var(--muted);font-size:7px}.footprint-strip{display:none}.metric-rail{display:none}.center-app-list{display:grid;gap:6px;margin-top:8px}.center-app-row{display:grid;grid-template-columns:minmax(120px,1fr) repeat(3,minmax(74px,.55fr));gap:6px;align-items:center;width:100%;padding:9px;border:1px solid var(--line);border-radius:9px;color:var(--ink);background:var(--paper);cursor:pointer;text-align:left}.center-app-row:hover,.center-app-row:focus-visible,.center-app-row.is-selected{border-color:var(--system-color);outline:none}.center-app-row strong{font-size:9px}.center-app-row span{color:var(--muted);font-size:7px}.below-timeline>[data-center-view]{display:none}.insight-rail .rail-section[data-view="pulse"]{display:block!important}.insight-rail .rail-section[data-view="runtime"],.insight-rail .rail-section[data-view="resources"],.insight-rail .rail-section[data-view="apps"]{display:none!important}html[data-explorer-mode="pulse"] .focus-summary{display:none}html[data-explorer-mode="pulse"] .below-timeline>[data-center-view="pulse"],html[data-explorer-mode="runtime"] .below-timeline>[data-center-view="runtime"],html[data-explorer-mode="resources"] .below-timeline>[data-center-view="resources"],html[data-explorer-mode="apps"] .below-timeline>[data-center-view="apps"]{display:block;grid-column:1/-1}html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .temporal,html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .chart-wrap,html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .chart-help,html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .chart-controls{display:none}html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .focus-summary{display:grid;grid-template-columns:minmax(150px,.65fr) minmax(0,1.35fr);min-height:150px;align-content:start}html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .below-timeline{grid-template-columns:1fr}.resource-modes{display:none}
31
31
  .system-panel .app-inspector>.eyebrow,.system-panel .app-inspector>.inspector-grid:nth-of-type(2),.system-panel .app-inspector>.inspector{display:none}.system-panel .app-inspector>.inspector-grid:first-of-type .inspector-stat:nth-child(n+4){display:none}
32
32
  .system-panel .app-inspector>.inspector-head+.inspector-grid{display:grid}.system-panel .app-inspector>.eyebrow+.inspector-grid{display:none}.system-panel .app-inspector>.inspector-head+.inspector-grid .inspector-stat:nth-child(n+4){display:none}
33
33
  :root{--ui-xs:clamp(12px,.76rem + .08vw,14px);--ui-sm:clamp(13px,.82rem + .12vw,16px);--ui-md:clamp(14px,.88rem + .16vw,18px);--ui-lg:clamp(17px,1rem + .26vw,23px);--ui-title:clamp(23px,1.18rem + .55vw,34px);--ui-value:clamp(24px,1.35rem + .72vw,42px);--tap:clamp(42px,3vw,52px)}
34
34
  body{font-size:var(--ui-md);line-height:1.45}.brand-copy strong,.inspector-head strong{font-size:var(--ui-lg)}.status,.privacy-chip,.button,.icon-button,.more summary,.scan-status,.metric-sub,.panel-copy,.chart-tooltip,.selected-evidence,.insight-copy,.early,.runtime-item,.mix-item,.feature-tool::after,.focus-copy span,.compact-stat span,.statement,.global-state p,.advanced>summary,.detail-list li,.share-side p,.share-status,.temporal span,.date-option,.resource-modes button,.inspector-state,.footer,.system-help,.timeline-axis-label,.timeline-tick,.timeline-system span,.timeline-block,.timeline-empty,.below-stat span,.runtime-footprint-row span,.truth-note,.inspector-app-row span,.center-app-row span{font-size:var(--ui-xs)}.eyebrow,.metric-label,.rail-stat span,.inspector-stat span{font-size:var(--ui-xs);letter-spacing:.1em}.button,.icon-button,.more summary{min-height:var(--tap)}.feature-tool{min-height:calc(var(--tap) + 22px)}.feature-tool>span:last-of-type,.system-actions .button{font-size:var(--ui-xs)}.panel-head h1,.panel-head h2,.compact h2{font-size:var(--ui-title)}.insight-rail h2{font-size:var(--ui-title)}.rail-heading strong,.detail-box h3,.below-card h2,.temporal strong{font-size:var(--ui-md)}.metric-value,.headline:first-child .metric-value{font-size:var(--ui-value)}.rail-stat strong,.inspector-stat strong,.below-stat strong,.compact-stat strong,.runtime-footprint-row strong,.inspector-app-row strong,.center-app-row strong,.timeline-system strong{font-size:var(--ui-sm)}.timeline-row{min-height:56px}.timeline-track{height:46px}.timeline-block{padding:0 6px}.resource-history-title{margin:12px 0 6px;font-size:var(--ui-md)}.resource-history-list{display:grid;gap:6px;margin-top:7px}.resource-history-row{display:grid;grid-template-columns:minmax(125px,1fr) repeat(4,minmax(78px,.65fr));gap:6px;align-items:center;padding:8px;border:1px solid var(--line);border-left:3px solid var(--system-color,var(--brand));border-radius:8px;background:var(--paper)}.resource-history-row strong{overflow:hidden;font-size:var(--ui-sm);text-overflow:ellipsis;white-space:nowrap}.resource-history-row span{color:var(--muted);font-size:var(--ui-xs)}html[data-explorer-mode="resources"] .below-timeline{display:grid}
35
- @media(max-width:980px){.privacy-chip{display:none}.workspace{grid-template-columns:minmax(0,1fr) 310px}.summary-row{grid-template-columns:1fr 1fr}.summary-row .global-card{grid-column:1/-1}.details-grid{grid-template-columns:1fr 1fr}}
35
+ @media(max-width:1320px){.privacy-chip{display:none}.workspace{grid-template-columns:minmax(0,1fr) 310px}.summary-row{grid-template-columns:1fr 1fr}.summary-row .global-card{grid-column:1/-1}.details-grid{grid-template-columns:1fr 1fr}}
36
36
  @media(max-width:760px){.shell{width:calc(100% - 14px);padding-top:7px}.command{align-items:flex-start}.command-actions{flex-wrap:wrap;justify-content:flex-end}.metric-rail{grid-template-columns:1fr}.headline{border-right:0;border-bottom:1px solid var(--line)}.workspace,.summary-row{grid-template-columns:1fr}.insight-rail{max-height:none;min-height:0}.compact-grid{grid-template-columns:1fr}.compact-stat{padding:6px 0;border-right:0;border-bottom:1px solid var(--line)}.share-layout{grid-template-columns:1fr}.share-preview{max-height:55vh}.share-preview canvas{height:55vh;object-fit:contain}.footer{display:block}.footer span{display:block;margin-top:3px}.temporal{align-items:flex-start;flex-direction:column}.footprint-strip{grid-template-columns:1fr}.local-strip{align-items:flex-start;flex-wrap:wrap}.global-action{justify-content:space-between}.focus-summary{grid-template-columns:1fr}.focus-stats{grid-template-columns:1fr 1fr}}
37
37
  @media(max-width:480px){.brand-copy strong{max-width:145px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.command-actions>.button.primary{order:3}.metric-value{font-size:19px}.chart-canvas{height:260px}.details-grid{grid-template-columns:1fr}.chart-controls{flex-wrap:wrap}.resource-modes{order:2}}
38
- @media(max-width:980px){.workspace{grid-template-columns:minmax(185px,.34fr) minmax(0,1fr)}.workspace>.system-panel{grid-column:1;grid-row:1}.workspace>.explorer{grid-column:2;grid-row:1}.workspace>.insight-rail{grid-column:1/-1;grid-row:2;max-height:none}.below-timeline{grid-template-columns:1fr 1fr}.observation-metrics{grid-column:1/-1}.below-metrics{grid-template-columns:repeat(3,1fr)}}
38
+ @media(max-width:1320px){.workspace{grid-template-columns:minmax(210px,.28fr) minmax(0,1fr)}.workspace>.system-panel{grid-column:1;grid-row:1}.workspace>.explorer{grid-column:2;grid-row:1}.workspace>.insight-rail{grid-column:1/-1;grid-row:2;max-height:none}.observation-tools{grid-template-columns:repeat(4,1fr)}.below-timeline{grid-template-columns:1fr 1fr}.observation-metrics{grid-column:1/-1}.below-metrics{grid-template-columns:repeat(3,1fr)}}
39
39
  @media(max-width:760px){.workspace{grid-template-columns:1fr}.workspace>.system-panel,.workspace>.explorer,.workspace>.insight-rail{grid-column:1;grid-row:auto;max-height:none}.workspace>.explorer{order:-1}.below-timeline{grid-template-columns:1fr}.observation-metrics{grid-column:1}.below-metrics{grid-template-columns:1fr 1fr}.timeline-axis,.timeline-row{grid-template-columns:82px minmax(0,1fr)}}
40
+ @media(max-width:760px){.timeline-tick:not(:first-child):not(:last-child){display:none}}
40
41
  @media(prefers-reduced-motion:reduce){*{scroll-behavior:auto!important;transition:none!important}}
41
42
  </style></head><body><main class="shell">
42
43
  <header class="surface command"><div class="brand">${brand}<div class="brand-copy"><strong>Forkit AI Footprint</strong><span class="status stopped" id="monitor-status"><i class="status-dot"></i><span id="monitor-status-text">${t('stopped')}</span></span></div></div><div class="command-actions"><span class="privacy-chip"><b>${t('localOnly')}</b> · ${t('nothingUploaded')}</span><div class="locale" aria-label="Language"><button id="locale-en" class="${locale === 'en' ? 'active' : ''}" type="button">EN</button><button id="locale-de" class="${locale === 'de' ? 'active' : ''}" type="button">DE</button></div><button class="button primary" id="share-button" type="button">${t('share')}</button>${rescan ? `<button class="button" id="monitor-button" type="button">${t('startMonitoring')}</button><details class="more"><summary>${t('more')}</summary><div class="more-menu"><button class="button" id="clear-button" type="button">${t('clearHistory')}</button><button class="button" id="scan-button" type="button">${t('scanAgain')}</button><span class="scan-status" id="scan-status"></span></div></details>` : ''}</div></header>
@@ -50,7 +51,7 @@ body{font-size:var(--ui-md);line-height:1.45}.brand-copy strong,.inspector-head
50
51
  <dialog id="share-dialog"><div class="share-layout"><div class="share-preview"><canvas id="share-canvas" width="1080" height="1080"></canvas></div><div class="share-side"><p class="eyebrow">${t('shareTitle')}</p><h2 id="share-heading">${t('shareHeading')}</h2><p>${t('shareFormat')}</p><div class="share-actions"><button class="button primary" id="native-share" type="button">${t('share')}</button><button class="button" id="download-share" type="button">${t('savePng')}</button><button class="button" id="copy-image" type="button">${t('copyImage')}</button><button class="button" id="copy-share" type="button">${t('copyCaption')}</button><button class="button" id="close-share" type="button">${t('close')}</button></div><p class="share-status" id="share-status">${t('sharePrivacy')}</p></div></div></dialog>
51
52
  <script>
52
53
  const copy=${safeScriptJson(localization_1.UI_COPY)},locale=${safeScriptJson(locale)},config=${safeScriptJson(config)},globalUrl=${safeScriptJson(globalUrl)},shareLogo=${safeScriptJson(shareLogo)};
53
- let footprint=${safeScriptJson(view ?? snapshot)},monitor={lifecycle:'stopped',observed_seconds:0,active_seconds:0,activity_ratio:null,products:[],timeline:[],resource_history:[],insights:[],presence:{state:'active',observation_eligible:true},overhead:{current_cpu_percent:null,current_memory_bytes:0,history_bytes:0},activity_view:{segments:[],contributions:[],insights:[],systems:[],extent:null,active_block_count:0,longest_active_seconds:0,longest_active_range:null,idle_seconds:0,excluded_seconds:0,simultaneous_systems_max:0,active_tool_count:0,observation_ids:[],available_date_keys:[],current_resources:{cpu_percent:null,memory_bytes:null,process_count:0},resource_history:{buckets:[],systems:[]},resource_history_state:'not-retained'},last_observation:null};
54
+ let footprint=${safeScriptJson(view ?? snapshot)},monitor={lifecycle:'stopped',observed_seconds:0,active_seconds:0,activity_ratio:null,products:[],timeline:[],resource_history:[],insights:[],presence:{state:'active',observation_eligible:true},overhead:{current_cpu_percent:null,current_memory_bytes:0,history_bytes:0},activity_view:{segments:[],contributions:[],insights:[],systems:[],extent:null,active_block_count:0,longest_active_seconds:0,longest_active_range:null,idle_seconds:0,excluded_seconds:0,simultaneous_systems_max:0,active_tool_count:0,observation_ids:[],continuity_ids:[],available_date_keys:[],current_resources:{cpu_percent:null,memory_bytes:null,process_count:0},resource_history:{buckets:[],systems:[]},resource_history_state:'not-retained'},last_observation:null};
54
55
  const $=id=>document.getElementById(id),format=new Intl.NumberFormat(locale),clock=new Intl.DateTimeFormat(locale,{day:'2-digit',month:'short',hour:'2-digit',minute:'2-digit',second:'2-digit'}),fullMoment=new Intl.DateTimeFormat(locale,{dateStyle:'medium',timeStyle:'medium'}),dateLabel=new Intl.DateTimeFormat(locale,{weekday:'short',day:'numeric',month:'short',year:'numeric'}),shareDateLabel=new Intl.DateTimeFormat(locale,{day:'numeric',month:'short',year:'numeric'}),systemPalette=['#00888d','#d98a25','#7758c7','#2e8f68','#c85578','#487bc4','#9b6b37','#637b2f'],colorsKey='forkit-footprints-colors-v1',lastSummaryKey='forkit-footprints-last-summary-v1';
55
56
  function text(key,values={}){let value=copy[locale][key]||key;for(const [name,replacement] of Object.entries(values))value=value.split('{'+name+'}').join(String(replacement));return value}
56
57
  function loadJson(key,fallback){try{return JSON.parse(localStorage.getItem(key)||'null')||fallback}catch{return fallback}}
@@ -60,7 +61,7 @@ function productMap(){return new Map((monitor.products||[]).map(product=>[produc
60
61
  let resourceMode='both',resourceSamples=[],selectedDateKey=null,explorerMode='pulse',selectedSystemSignature=null,focusedSystemSignature=null;function localDateKey(value){const date=new Date(value),year=date.getFullYear(),month=String(date.getMonth()+1).padStart(2,'0'),day=String(date.getDate()).padStart(2,'0');return year+'-'+month+'-'+day}function observationDateRange(){const extent=monitor.activity_view?.extent;if(!extent)return '—';const start=new Date(extent.start_ms),end=new Date(Math.max(extent.start_ms,extent.end_ms-1));return localDateKey(start)===localDateKey(end)?dateLabel.format(start):dateLabel.format(start)+' – '+dateLabel.format(end)}function shareObservationDate(){const extent=monitor.activity_view?.extent;if(!extent)return '';const start=new Date(extent.start_ms),end=new Date(Math.max(extent.start_ms,extent.end_ms-1)),first=shareDateLabel.format(start).toLocaleUpperCase(locale);return localDateKey(start)===localDateKey(end)?first:(first+' – '+shareDateLabel.format(end).toLocaleUpperCase(locale))}function aggregateResources(products){const cpu=products.map(product=>product.cpu_percent).filter(Number.isFinite),memory=products.map(product=>product.memory_bytes).filter(Number.isFinite);return {cpu:cpu.length?cpu.reduce((sum,value)=>sum+Math.max(0,value),0):null,memory:memory.length?memory.reduce((sum,value)=>sum+Math.max(0,value),0):null,processes:products.reduce((sum,product)=>sum+Math.max(0,Number(product.process_count)||0),0)}}function resourceStatusText(state){return state==='retained-local-buckets'?text('resourceRetainedLocal'):state==='collecting'?text('resourceCollecting'):text('resourceNotRetained')}function averageBuckets(buckets,key){let total=0,weight=0;for(const bucket of buckets){const value=bucket[key];if(!Number.isFinite(value))continue;const seconds=Math.max(0,Number(bucket.observed_seconds)||0);if(!seconds)continue;total+=value*seconds;weight+=seconds}return weight?total/weight:null}function summarizeResourceBuckets(buckets){const grouped=new Map();for(const bucket of buckets||[]){const signature=bucket.system_signature;if(!signature)continue;grouped.set(signature,[...(grouped.get(signature)||[]),bucket])}return [...grouped.entries()].map(([signature,items])=>({signature,name:items.at(-1)?.system_name||signature,kind:items.at(-1)?.kind||'unknown',observed_seconds:items.reduce((sum,item)=>sum+(Number(item.observed_seconds)||0),0),active_seconds:items.reduce((sum,item)=>sum+(Number(item.active_seconds)||0),0),avg_cpu_percent:averageBuckets(items,'avg_cpu_percent'),peak_cpu_percent:items.reduce((max,item)=>Number.isFinite(item.peak_cpu_percent)?Math.max(max,Number(item.peak_cpu_percent)):max,0)||null,avg_memory_bytes:averageBuckets(items,'avg_memory_bytes'),peak_memory_bytes:items.reduce((max,item)=>Number.isFinite(item.peak_memory_bytes)?Math.max(max,Number(item.peak_memory_bytes)):max,0)||null,peak_process_count:items.reduce((max,item)=>Math.max(max,Number(item.peak_process_count)||0),0),sample_count:items.reduce((sum,item)=>sum+(Number(item.sample_count)||0),0)})).sort((a,b)=>b.active_seconds-a.active_seconds||b.observed_seconds-a.observed_seconds||a.name.localeCompare(b.name))}function filterResourceHistory(view,{start=null,end=null,signature=null}={}){const buckets=(view?.resource_history?.buckets||[]).filter(bucket=>(!signature||bucket.system_signature===signature)&&(!Number.isFinite(start)||bucket.end_ms>start)&&(!Number.isFinite(end)||bucket.start_ms<end)).map(bucket=>({...bucket,start_ms:Number.isFinite(start)?Math.max(bucket.start_ms,start):bucket.start_ms,end_ms:Number.isFinite(end)?Math.min(bucket.end_ms,end):bucket.end_ms}));return {buckets,systems:summarizeResourceBuckets(buckets)}}function appendResourceSample(){resourceSamples=(monitor.activity_view?.resource_history?.buckets||[]).map(bucket=>({at:bucket.end_ms,cpu:bucket.avg_cpu_percent,memory:bucket.avg_memory_bytes,processes:bucket.peak_process_count,systems:{[bucket.system_signature]:{cpu:bucket.avg_cpu_percent,memory:bucket.avg_memory_bytes,processes:bucket.peak_process_count}}}));if(monitor.lifecycle!=='monitoring')return;const extent=monitor.activity_view?.extent,at=extent?.end_ms;if(!Number.isFinite(at))return;const all=aggregateResources(monitor.products||[]),systems={};for(const product of monitor.products||[])systems[product.signature]={cpu:Number.isFinite(product.cpu_percent)?product.cpu_percent:null,memory:Number.isFinite(product.memory_bytes)?product.memory_bytes:null,processes:product.process_count||0};if(all.cpu===null&&all.memory===null)return;const sample={at,cpu:all.cpu,memory:all.memory,processes:all.processes,systems};const previous=resourceSamples.at(-1);if(previous&&previous.at===sample.at)resourceSamples[resourceSamples.length-1]=sample;else resourceSamples.push(sample);resourceSamples=resourceSamples.slice(-Math.max(60,monitor.history_limit||900))}
61
62
  function add(listNode,title,note){const li=document.createElement('li'),strong=document.createElement('strong');strong.textContent=title;li.append(strong,document.createTextNode(note));listNode.append(li)}
62
63
  class ActivityExplorer{constructor(canvas,navigator,tooltip,output){this.canvas=canvas;this.navigator=navigator;this.tooltip=tooltip;this.output=output;this.view=monitor.activity_view;this.range=null;this.hover=null;this.selected=null;this.focusSignature=null;this.drag=null;this.frame=0;this.resizeObserver=new ResizeObserver(()=>this.schedule());this.resizeObserver.observe(canvas);this.resizeObserver.observe(navigator);canvas.addEventListener('pointermove',event=>this.pointerMove(event));canvas.addEventListener('pointerleave',()=>{this.hover=null;this.tooltip.hidden=true;this.schedule()});canvas.addEventListener('pointerdown',event=>{this.drag={x:event.clientX,range:this.range&&[...this.range]};canvas.setPointerCapture(event.pointerId)});canvas.addEventListener('pointerup',event=>{if(this.drag&&Math.abs(event.clientX-this.drag.x)<4)this.selectAt(event);this.drag=null});canvas.addEventListener('wheel',event=>{event.preventDefault();this.zoom(event.deltaY<0?.7:1.35,this.eventTime(event))},{passive:false});canvas.addEventListener('dblclick',()=>this.reset());canvas.addEventListener('keydown',event=>this.key(event));navigator.addEventListener('pointerdown',event=>this.navigate(event))}setData(view){const oldExtent=this.view.extent;const wasAtEnd=this.range&&oldExtent&&Math.abs(this.range[1]-oldExtent.end_ms)<2000;this.view=view||monitor.activity_view;if(!this.range&&this.view.extent)this.range=[this.view.extent.start_ms,this.view.extent.end_ms];else if(wasAtEnd&&this.range&&oldExtent&&this.view.extent){const width=this.range[1]-this.range[0];this.range=[Math.max(this.view.extent.start_ms,this.view.extent.end_ms-width),this.view.extent.end_ms]}if(this.selected&&!this.view.segments.some(segment=>segment.id===this.selected))this.selected=null;this.schedule()}schedule(){if(this.frame)return;this.frame=requestAnimationFrame(()=>{this.frame=0;this.draw()})}size(canvas){const rect=canvas.getBoundingClientRect(),dpr=Math.max(1,window.devicePixelRatio||1),width=Math.max(1,Math.round(rect.width*dpr)),height=Math.max(1,Math.round(rect.height*dpr));if(canvas.width!==width||canvas.height!==height){canvas.width=width;canvas.height=height}const context=canvas.getContext('2d');context.setTransform(dpr,0,0,dpr,0,0);return {context,width:rect.width,height:rect.height}}visibleRange(){return this.range||this.view.extent&&[this.view.extent.start_ms,this.view.extent.end_ms]||[0,1]}eventTime(event){const rect=this.canvas.getBoundingClientRect(),range=this.visibleRange(),left=64,right=rect.width-12,ratio=Math.max(0,Math.min(1,(event.clientX-rect.left-left)/(right-left)));return range[0]+ratio*(range[1]-range[0])}segmentAt(time){return this.view.segments.find(segment=>time>=segment.start_ms&&time<=Math.max(segment.end_ms,segment.start_ms+monitor.sample_interval_ms||1000))||null}zoom(factor,center){if(!this.view.extent)return;const range=this.visibleRange(),full=this.view.extent.end_ms-this.view.extent.start_ms,min=Math.min(full,30000),width=Math.max(min,Math.min(full,(range[1]-range[0])*factor)),ratio=(center-range[0])/Math.max(1,range[1]-range[0]);let start=center-width*ratio,end=start+width;if(start<this.view.extent.start_ms){start=this.view.extent.start_ms;end=start+width}if(end>this.view.extent.end_ms){end=this.view.extent.end_ms;start=end-width}this.range=[start,end];this.schedule()}pan(deltaRatio){if(!this.view.extent||!this.range)return;const width=this.range[1]-this.range[0],delta=deltaRatio*width;let start=this.range[0]+delta,end=this.range[1]+delta;if(start<this.view.extent.start_ms){start=this.view.extent.start_ms;end=start+width}if(end>this.view.extent.end_ms){end=this.view.extent.end_ms;start=end-width}this.range=[start,end];this.schedule()}reset(){this.range=this.view.extent?[this.view.extent.start_ms,this.view.extent.end_ms]:null;this.focusSignature=null;this.selected=null;this.output.textContent=text('noSelection');this.schedule()}focusSystem(signature){this.focusSignature=signature;this.selected=null;this.schedule()}focusRange(start,end){if(!this.view.extent)return;const padding=Math.max(5000,(end-start)*.15);this.range=[Math.max(this.view.extent.start_ms,start-padding),Math.min(this.view.extent.end_ms,end+padding)];this.selected=null;this.output.innerHTML='<strong>'+clock.format(start)+'–'+clock.format(end)+'</strong> · '+seconds((end-start)/1000)+' · '+text('longestMarker');this.schedule()}focusSegment(id){const segment=this.view.segments.find(item=>item.id===id);if(!segment)return;const width=Math.max(30000,(segment.end_ms-segment.start_ms)*2),center=(segment.start_ms+segment.end_ms)/2;this.range=[center-width/2,center+width/2];if(this.view.extent){this.range[0]=Math.max(this.view.extent.start_ms,this.range[0]);this.range[1]=Math.min(this.view.extent.end_ms,this.range[1])}this.selected=id;this.describe(segment);this.schedule()}pointerMove(event){if(this.drag&&this.drag.range){const rect=this.canvas.getBoundingClientRect(),delta=(this.drag.x-event.clientX)/Math.max(1,rect.width-76);this.range=[...this.drag.range];this.pan(delta);return}const segment=this.segmentAt(this.eventTime(event));this.hover=segment&&segment.id;this.showTooltip(event,segment);this.schedule()}selectAt(event){const segment=this.segmentAt(this.eventTime(event));this.selected=segment&&segment.id;this.describe(segment);this.schedule()}describe(segment){if(!segment){this.output.textContent=text('noSelection');return}const systems=segment.system_signatures.map(signature=>productMap().get(signature)?.name||signature);this.output.innerHTML='<strong>'+clock.format(segment.start_ms)+'–'+clock.format(segment.end_ms)+'</strong> · '+seconds(segment.duration_seconds)+' · '+this.stateLabel(segment)+(systems.length?' · '+list(systems):'')}stateLabel(segment){return segment.state==='active'?text('working'):segment.state==='idle'?text('idleTimeLabel'):text('observationExcluded')}showTooltip(event,segment){if(!segment){this.tooltip.hidden=true;return}const rect=this.canvas.parentElement.getBoundingClientRect(),systems=segment.system_signatures.map(signature=>productMap().get(signature)?.name||signature);this.tooltip.textContent=clock.format(segment.start_ms)+'–'+clock.format(segment.end_ms)+' · '+seconds(segment.duration_seconds)+' · '+this.stateLabel(segment)+(systems.length?' · '+list(systems):'');this.tooltip.hidden=false;this.tooltip.style.left=Math.min(event.clientX-rect.left+10,rect.width-this.tooltip.offsetWidth-6)+'px';this.tooltip.style.top=Math.max(4,event.clientY-rect.top-this.tooltip.offsetHeight-8)+'px'}key(event){const visible=this.view.segments.filter(segment=>this.range&&segment.end_ms>=this.range[0]&&segment.start_ms<=this.range[1]);if(!visible.length)return;let index=Math.max(0,visible.findIndex(segment=>segment.id===this.selected));if(event.key==='ArrowRight')index=Math.min(visible.length-1,index+1);else if(event.key==='ArrowLeft')index=Math.max(0,index-1);else if(event.key==='Enter'||event.key===' '){const segment=visible[index];if(segment){event.preventDefault();this.selected=segment.id;this.describe(segment);this.schedule()}return}else return;event.preventDefault();const segment=visible[index];if(segment){this.selected=segment.id;this.describe(segment);this.schedule()}}navigate(event){if(!this.view.extent||!this.range)return;const rect=this.navigator.getBoundingClientRect(),ratio=Math.max(0,Math.min(1,(event.clientX-rect.left)/rect.width)),width=this.range[1]-this.range[0],center=this.view.extent.start_ms+ratio*(this.view.extent.end_ms-this.view.extent.start_ms);this.range=[center-width/2,center+width/2];this.pan(0)}paintSegment(context,segment,x,width,y,height){const signatures=segment.system_signatures;if(segment.state==='excluded'){context.fillStyle=getComputedStyle(document.documentElement).getPropertyValue('--surface-2');context.fillRect(x,y,width,height);context.strokeStyle=getComputedStyle(document.documentElement).getPropertyValue('--excluded');for(let offset=-height;offset<width+height;offset+=7){context.beginPath();context.moveTo(x+offset,y+height);context.lineTo(x+offset+height,y);context.stroke()}return}if(segment.state==='idle'){context.fillStyle=getComputedStyle(document.documentElement).getPropertyValue('--idle');context.fillRect(x,y,width,height);return}const parts=signatures.length||1,partHeight=height/parts;for(let index=0;index<parts;index++){context.fillStyle=signatures[index]?systemColor(signatures[index]):getComputedStyle(document.documentElement).getPropertyValue('--active');context.fillRect(x,y+index*partHeight,width,partHeight)}if(this.focusSignature&&!signatures.includes(this.focusSignature)){context.fillStyle='rgba(20,20,20,.58)';context.fillRect(x,y,width,height)}}draw(){const main=this.size(this.canvas),nav=this.size(this.navigator),context=main.context,range=this.visibleRange(),left=64,right=main.width-12,plotWidth=Math.max(1,right-left),segments=this.view.segments.filter(segment=>segment.end_ms>=range[0]&&segment.start_ms<=range[1]),style=getComputedStyle(document.documentElement);context.clearRect(0,0,main.width,main.height);context.font='700 9px Inter, sans-serif';context.fillStyle=style.getPropertyValue('--muted');context.fillText(text('activityDensity'),8,40);context.fillText(text('overallLane'),8,103);context.strokeStyle=style.getPropertyValue('--line');context.beginPath();context.moveTo(left,52);context.lineTo(right,52);context.moveTo(left,116);context.lineTo(right,116);context.stroke();const xFor=time=>left+(time-range[0])/Math.max(1,range[1]-range[0])*plotWidth;for(const segment of segments){const x=xFor(Math.max(range[0],segment.start_ms)),end=xFor(Math.min(range[1],Math.max(segment.end_ms,segment.start_ms+(monitor.sample_interval_ms||1000)))),width=Math.max(2,end-x);if(segment.state==='active'){context.fillStyle=segment.system_signatures[0]?systemColor(segment.system_signatures[0]):style.getPropertyValue('--active');const density=Math.max(1,segment.system_signatures.length),height=Math.min(29,density*8);context.fillRect(x,48-height,width,height)}this.paintSegment(context,segment,x,width,82,34);if(segment.is_longest_active){context.strokeStyle=style.getPropertyValue('--gold');context.lineWidth=2;context.strokeRect(x+1,80,width-2,38)}if(segment.id===this.selected){context.strokeStyle=style.getPropertyValue('--ink');context.lineWidth=2;context.strokeRect(x,78,width,42)}}if(this.hover){const segment=this.view.segments.find(item=>item.id===this.hover);if(segment){const x=xFor(Math.max(range[0],Math.min(range[1],(segment.start_ms+segment.end_ms)/2)));context.strokeStyle=style.getPropertyValue('--ink');context.setLineDash([3,3]);context.beginPath();context.moveTo(x,16);context.lineTo(x,154);context.stroke();context.setLineDash([])}}context.fillStyle=style.getPropertyValue('--muted');context.font='650 8px Inter, sans-serif';context.fillText(clock.format(range[0]),left,178);const endLabel=clock.format(range[1]);context.fillText(endLabel,right-context.measureText(endLabel).width,178);context.fillText(seconds((range[1]-range[0])/1000),left,195);nav.context.clearRect(0,0,nav.width,nav.height);if(this.view.extent){const full=this.view.extent.end_ms-this.view.extent.start_ms||1,xNav=time=>(time-this.view.extent.start_ms)/full*nav.width;for(const segment of this.view.segments){const x=xNav(segment.start_ms),width=Math.max(1,xNav(Math.max(segment.end_ms,segment.start_ms+(monitor.sample_interval_ms||1000)))-x);if(segment.state==='active')nav.context.fillStyle=segment.system_signatures[0]?systemColor(segment.system_signatures[0]):style.getPropertyValue('--active');else if(segment.state==='idle')nav.context.fillStyle=style.getPropertyValue('--idle');else nav.context.fillStyle=style.getPropertyValue('--excluded');nav.context.fillRect(x,5,width,nav.height-10)}nav.context.fillStyle='rgba(20,20,20,.22)';nav.context.fillRect(xNav(this.range[0]),1,Math.max(3,xNav(this.range[1])-xNav(this.range[0])),nav.height-2);nav.context.strokeStyle=style.getPropertyValue('--ink');nav.context.strokeRect(xNav(this.range[0]),1,Math.max(3,xNav(this.range[1])-xNav(this.range[0])),nav.height-2)}}}
63
- function viewForDate(view,key){if(!key||!view?.segments?.length)return view;const [year,month,day]=key.split('-').map(Number),start=new Date(year,month-1,day).getTime(),end=new Date(year,month-1,day+1).getTime(),segments=view.segments.filter(segment=>segment.end_ms>start&&segment.start_ms<end).map(segment=>({...segment,start_ms:Math.max(start,segment.start_ms),end_ms:Math.min(end,segment.end_ms)})),resource_history=filterResourceHistory(view,{start,end});if(!segments.length)return {...view,segments:[],contributions:[],systems:[],extent:null,resource_history};const secondsBySystem=new Map();for(const segment of segments)if(segment.state==='active')for(const signature of segment.system_signatures)secondsBySystem.set(signature,(secondsBySystem.get(signature)||0)+(segment.end_ms-segment.start_ms)/1000);const total=[...secondsBySystem.values()].reduce((sum,value)=>sum+value,0),contributions=(view.contributions||[]).filter(item=>secondsBySystem.has(item.signature)).map(item=>({...item,active_seconds:secondsBySystem.get(item.signature),share:total?secondsBySystem.get(item.signature)/total:0})).sort((a,b)=>b.active_seconds-a.active_seconds),systems=(view.systems||[]).filter(item=>secondsBySystem.has(item.signature)||resource_history.systems.some(resource=>resource.signature===item.signature)).map(item=>{const periods=segments.filter(segment=>segment.state==='active'&&segment.system_signatures.includes(item.signature)),resource=resource_history.systems.find(next=>next.signature===item.signature);return {...item,active_seconds:secondsBySystem.get(item.signature)||0,share:total?((secondsBySystem.get(item.signature)||0)/total):0,period_count:periods.length,longest_active_seconds:periods.reduce((maximum,segment)=>Math.max(maximum,(segment.end_ms-segment.start_ms)/1000),0),first_observed_ms:periods[0]?.start_ms||null,last_observed_ms:periods.at(-1)?.end_ms||null,resource_observed_seconds:resource?.observed_seconds||0,resource_active_seconds:resource?.active_seconds||0,avg_cpu_percent:resource?.avg_cpu_percent??null,peak_cpu_percent:resource?.peak_cpu_percent??null,avg_memory_bytes:resource?.avg_memory_bytes??null,peak_memory_bytes:resource?.peak_memory_bytes??null,peak_process_count:resource?.peak_process_count||0,resource_sample_count:resource?.sample_count||0}});return {...view,segments,contributions,systems,resource_history,extent:{start_ms:segments[0].start_ms,end_ms:segments.at(-1).end_ms}}}function viewForSystem(view,signature){if(!signature||!view?.segments?.length)return view;const selected=(view.systems||[]).find(system=>system.signature===signature);if(!selected)return view;const resource_history=filterResourceHistory(view,{signature}),resource=resource_history.systems[0],segments=view.segments.map(segment=>segment.state==='active'?{...segment,state:segment.system_signatures.includes(signature)?'active':'idle',system_signatures:segment.system_signatures.includes(signature)?[signature]:[]}:segment),active=segments.filter(segment=>segment.state==='active'),activeSeconds=active.reduce((sum,segment)=>sum+segment.duration_seconds,0),longest=active.reduce((best,segment)=>!best||segment.duration_seconds>best.duration_seconds?segment:best,null),system={...selected,active_seconds:activeSeconds,share:activeSeconds?1:0,period_count:active.length,longest_active_seconds:longest?.duration_seconds||0,first_observed_ms:active[0]?.start_ms||null,last_observed_ms:active.at(-1)?.end_ms||null,resource_observed_seconds:resource?.observed_seconds||0,resource_active_seconds:resource?.active_seconds||0,avg_cpu_percent:resource?.avg_cpu_percent??null,peak_cpu_percent:resource?.peak_cpu_percent??null,avg_memory_bytes:resource?.avg_memory_bytes??null,peak_memory_bytes:resource?.peak_memory_bytes??null,peak_process_count:resource?.peak_process_count||0,resource_sample_count:resource?.sample_count||0};return {...view,segments,systems:[system],resource_history,contributions:activeSeconds?[{...system,share:1}]:[],active_block_count:active.length,longest_active_seconds:longest?.duration_seconds||0,longest_active_range:longest?{start_ms:longest.start_ms,end_ms:longest.end_ms}:null}}function currentView(){return viewForSystem(viewForDate(monitor.activity_view,selectedDateKey),focusedSystemSignature)}function viewTotals(view){const valid=(view?.segments||[]).filter(segment=>segment.valid),active=valid.filter(segment=>segment.state==='active').reduce((sum,segment)=>sum+segment.duration_seconds,0),observed=valid.reduce((sum,segment)=>sum+segment.duration_seconds,0);return {active,observed,ratio:observed?active/observed:null}}
64
+ function activeBlockStats(segments){const blocks=[];for(let index=0;index<segments.length;index++){const segment=segments[index];if(segment.state!=='active')continue;const continuity=segment.continuity_id??segment.observation_id??null,previous=blocks.at(-1),continues=previous&&previous.last_index===index-1&&previous.continuity_id===continuity&&segment.start_ms-previous.end_ms<=Math.max(1500,(monitor.sample_interval_ms||1000)*3);if(continues){previous.end_ms=Math.max(previous.end_ms,segment.end_ms);previous.indexes.push(index);previous.last_index=index}else blocks.push({start_ms:segment.start_ms,end_ms:segment.end_ms,indexes:[index],last_index:index,continuity_id:continuity})}const longest=blocks.reduce((best,block)=>!best||block.end_ms-block.start_ms>best.end_ms-best.start_ms?block:best,null);return {count:blocks.length,longest_seconds:longest?(longest.end_ms-longest.start_ms)/1000:0,longest_range:longest?{start_ms:longest.start_ms,end_ms:longest.end_ms}:null,longest_indexes:new Set(longest?.indexes||[])}}function scopedSystemSegments(segments,signature){return segments.map(segment=>segment.state==='active'?{...segment,state:segment.system_signatures.includes(signature)?'active':'idle',system_signatures:segment.system_signatures.includes(signature)?[signature]:[]}:segment)}function viewForDate(view,key){if(!key||!view?.segments?.length)return view;const [year,month,day]=key.split('-').map(Number),start=new Date(year,month-1,day).getTime(),end=new Date(year,month-1,day+1).getTime(),clipped=view.segments.filter(segment=>segment.end_ms>start&&segment.start_ms<end).map(segment=>{const start_ms=Math.max(start,segment.start_ms),end_ms=Math.min(end,segment.end_ms);return {...segment,start_ms,end_ms,duration_seconds:Math.max(0,end_ms-start_ms)/1000,is_longest_active:false}}),resource_history=filterResourceHistory(view,{start,end});if(!clipped.length)return {...view,segments:[],contributions:[],systems:[],extent:null,resource_history,active_block_count:0,longest_active_seconds:0,longest_active_range:null};const blockStats=activeBlockStats(clipped),segments=clipped.map((segment,index)=>({...segment,is_longest_active:blockStats.longest_indexes.has(index)})),secondsBySystem=new Map();for(const segment of segments)if(segment.state==='active')for(const signature of segment.system_signatures)secondsBySystem.set(signature,(secondsBySystem.get(signature)||0)+segment.duration_seconds);const total=[...secondsBySystem.values()].reduce((sum,value)=>sum+value,0),contributions=(view.contributions||[]).filter(item=>secondsBySystem.has(item.signature)).map(item=>({...item,active_seconds:secondsBySystem.get(item.signature),share:total?secondsBySystem.get(item.signature)/total:0})).sort((a,b)=>b.active_seconds-a.active_seconds),systems=(view.systems||[]).filter(item=>secondsBySystem.has(item.signature)||resource_history.systems.some(resource=>resource.signature===item.signature)).map(item=>{const scoped=scopedSystemSegments(segments,item.signature),periods=scoped.filter(segment=>segment.state==='active'),stats=activeBlockStats(scoped),resource=resource_history.systems.find(next=>next.signature===item.signature);return {...item,active_seconds:secondsBySystem.get(item.signature)||0,share:total?((secondsBySystem.get(item.signature)||0)/total):0,period_count:stats.count,longest_active_seconds:stats.longest_seconds,first_observed_ms:periods[0]?.start_ms||null,last_observed_ms:periods.at(-1)?.end_ms||null,resource_observed_seconds:resource?.observed_seconds||0,resource_active_seconds:resource?.active_seconds||0,avg_cpu_percent:resource?.avg_cpu_percent??null,peak_cpu_percent:resource?.peak_cpu_percent??null,avg_memory_bytes:resource?.avg_memory_bytes??null,peak_memory_bytes:resource?.peak_memory_bytes??null,peak_process_count:resource?.peak_process_count||0,resource_sample_count:resource?.sample_count||0}});return {...view,segments,contributions,systems,resource_history,extent:{start_ms:segments[0].start_ms,end_ms:segments.at(-1).end_ms},active_block_count:blockStats.count,longest_active_seconds:blockStats.longest_seconds,longest_active_range:blockStats.longest_range,observation_ids:[...new Set(segments.flatMap(segment=>segment.observation_id===null?[]:[segment.observation_id]))],continuity_ids:[...new Set(segments.flatMap(segment=>segment.continuity_id===null?[]:[segment.continuity_id]))]}}function viewForSystem(view,signature){if(!signature||!view?.segments?.length)return view;const selected=(view.systems||[]).find(system=>system.signature===signature);if(!selected)return view;const resource_history=filterResourceHistory(view,{signature}),resource=resource_history.systems[0],scoped=scopedSystemSegments(view.segments,signature),stats=activeBlockStats(scoped),segments=scoped.map((segment,index)=>({...segment,is_longest_active:stats.longest_indexes.has(index)})),active=segments.filter(segment=>segment.state==='active'),activeSeconds=active.reduce((sum,segment)=>sum+segment.duration_seconds,0),system={...selected,active_seconds:activeSeconds,share:activeSeconds?1:0,period_count:stats.count,longest_active_seconds:stats.longest_seconds,first_observed_ms:active[0]?.start_ms||null,last_observed_ms:active.at(-1)?.end_ms||null,resource_observed_seconds:resource?.observed_seconds||0,resource_active_seconds:resource?.active_seconds||0,avg_cpu_percent:resource?.avg_cpu_percent??null,peak_cpu_percent:resource?.peak_cpu_percent??null,avg_memory_bytes:resource?.avg_memory_bytes??null,peak_memory_bytes:resource?.peak_memory_bytes??null,peak_process_count:resource?.peak_process_count||0,resource_sample_count:resource?.sample_count||0};return {...view,segments,systems:[system],resource_history,contributions:activeSeconds?[{...system,share:1}]:[],active_block_count:stats.count,longest_active_seconds:stats.longest_seconds,longest_active_range:stats.longest_range}}function currentView(){return viewForSystem(viewForDate(monitor.activity_view,selectedDateKey),focusedSystemSignature)}function viewTotals(view){const valid=(view?.segments||[]).filter(segment=>segment.valid),active=valid.filter(segment=>segment.state==='active').reduce((sum,segment)=>sum+segment.duration_seconds,0),observed=valid.reduce((sum,segment)=>sum+segment.duration_seconds,0);return {active,observed,ratio:observed?active/observed:null}}
64
65
  class FootprintExplorer extends ActivityExplorer{reset(){super.reset();selectedSystemSignature=null;focusedSystemSignature=null;this.focusSignature=null;renderInspector();renderFocusSummary();renderSystemTimeline()}selectSystem(signature){selectedSystemSignature=signature||null;this.selected=null;this.output.textContent=text('noSelection');renderInspector();renderFocusSummary();renderMix();renderSystemTimeline();renderRuntimeFootprint();renderInspectorApps()}focusSystem(signature){selectedSystemSignature=signature||selectedSystemSignature;focusedSystemSignature=focusedSystemSignature===selectedSystemSignature?null:selectedSystemSignature;this.focusSignature=focusedSystemSignature;this.selected=null;this.output.textContent=text('noSelection');renderMonitor()}focusRange(start,end){super.focusRange(start,end);explorerMode='pulse';syncModeButtons();renderFocusSummary();renderSystemTimeline()}focusSegment(id){super.focusSegment(id);explorerMode='pulse';syncModeButtons();renderFocusSummary();renderSystemTimeline()}describe(segment){super.describe(segment);if(segment?.system_signatures?.length)selectedSystemSignature=segment.system_signatures[0];explorerMode='pulse';syncModeButtons();renderInspector();renderFocusSummary();renderSystemTimeline()}setResourceMode(mode){resourceMode=mode;this.schedule()}resourceValue(sample,key){const scoped=selectedSystemSignature?sample.systems?.[selectedSystemSignature]:sample;return scoped?.[key]??null}showTooltip(event,segment){if(!segment){this.tooltip.hidden=true;return}const time=this.eventTime(event),sample=[...resourceSamples].sort((a,b)=>Math.abs(a.at-time)-Math.abs(b.at-time))[0],systems=segment.system_signatures.map(signature=>productMap().get(signature)?.name||signature),resources=[];if(sample&&Math.abs(sample.at-time)<=Math.max(2500,monitor.sample_interval_ms*2)){const cpu=this.resourceValue(sample,'cpu'),memory=this.resourceValue(sample,'memory');if(Number.isFinite(cpu))resources.push(text('cpu')+' '+format.format(Number(cpu.toFixed(1)))+'%');if(Number.isFinite(memory))resources.push(text('memory')+' '+bytes(memory))}const rect=this.canvas.parentElement.getBoundingClientRect();this.tooltip.textContent=fullMoment.format(segment.start_ms)+' – '+fullMoment.format(segment.end_ms)+' · '+seconds(segment.duration_seconds)+' · '+this.stateLabel(segment)+(systems.length?' · '+list(systems):'')+(resources.length?' · '+resources.join(' · '):'');this.tooltip.hidden=false;this.tooltip.style.left=Math.min(event.clientX-rect.left+10,rect.width-this.tooltip.offsetWidth-6)+'px';this.tooltip.style.top=Math.max(4,event.clientY-rect.top-this.tooltip.offsetHeight-8)+'px'}draw(){super.draw();const main=this.size(this.canvas),context=main.context,range=this.visibleRange(),left=64,right=main.width-12,width=Math.max(1,right-left),style=getComputedStyle(document.documentElement),samples=resourceSamples.filter(sample=>sample.at>=range[0]&&sample.at<=range[1]);context.fillStyle=style.getPropertyValue('--muted');context.font='700 9px Inter,sans-serif';context.fillText(text('resourcePulse'),8,224);context.font='650 8px Inter,sans-serif';context.fillText(!samples.length&&monitor.lifecycle!=='monitoring'?text('resourceNotRetained'):text('resourceLiveOnly'),8,239);context.strokeStyle=style.getPropertyValue('--line');context.beginPath();context.moveTo(left,214);context.lineTo(right,214);context.moveTo(left,258);context.lineTo(right,258);context.stroke();if(!samples.length){if(monitor.lifecycle==='monitoring'){context.fillStyle=style.getPropertyValue('--muted');context.fillText(text('resourceCollecting'),Math.max(left,210),239)}return}const xFor=time=>left+(time-range[0])/Math.max(1,range[1]-range[0])*width,series=[];if(resourceMode!=='memory')series.push({key:'cpu',color:style.getPropertyValue('--brand')});if(resourceMode!=='cpu')series.push({key:'memory',color:'#F49355'});for(const item of series){const values=samples.map(sample=>this.resourceValue(sample,item.key)).filter(Number.isFinite),maximum=Math.max(1,...values);context.strokeStyle=item.color;context.lineWidth=resourceMode==='both'?1.7:2.4;context.beginPath();let started=false;for(const sample of samples){const value=this.resourceValue(sample,item.key);if(!Number.isFinite(value))continue;const x=xFor(sample.at),y=256-(value/maximum)*36;if(!started){context.moveTo(x,y);started=true}else context.lineTo(x,y)}context.stroke()}const key=resourceMode==='memory'?'memory':'cpu',latest=samples.at(-1),value=latest&&this.resourceValue(latest,key);if(Number.isFinite(value)){context.fillStyle=style.getPropertyValue('--muted');const label=(key==='cpu'?format.format(Number(value.toFixed(1)))+'%':bytes(value));context.fillText(label,right-context.measureText(label).width,210)}}}
65
66
  const explorer=new FootprintExplorer($('activity-explorer'),$('activity-navigator'),$('chart-tooltip'),$('selected-evidence'));
66
67
  const selectSystemBase=explorer.selectSystem.bind(explorer);explorer.selectSystem=signature=>{explorerMode='apps';selectSystemBase(signature);syncModeButtons();renderFocusSummary();renderCenterApps()}
@@ -71,9 +72,9 @@ function syncModeButtons(){document.documentElement.dataset.explorerMode=explore
71
72
  function setExplorerMode(mode,selectDefault=true){if(!['pulse','runtime','resources','apps'].includes(mode))return;explorerMode=mode;if(mode==='apps'&&selectDefault&&!selectedSystemSignature){const first=(currentView()?.systems||[])[0]||null;selectedSystemSignature=first?.signature||null}if(mode==='resources'){resourceMode='both';for(const item of document.querySelectorAll('[data-resource-mode]'))item.classList.toggle('active',item.dataset.resourceMode==='both')}syncModeButtons();renderInspector();renderFocusSummary();renderInspectorApps();renderCenterApps();explorer.schedule()}
72
73
  function renderFocusSummary(){const view=currentView()||{segments:[],systems:[],active_block_count:0,longest_active_seconds:0},unfiltered=viewForDate(monitor.activity_view,selectedDateKey)||view,totals=selectedDateKey||focusedSystemSignature?viewTotals(view):{active:monitor.active_seconds,observed:monitor.observed_seconds,ratio:monitor.activity_ratio},system=(unfiltered.systems||[]).find(item=>item.signature===selectedSystemSignature)||null,selected=(view.segments||[]).find(item=>item.id===explorer.selected)||(unfiltered.segments||[]).find(item=>item.id===explorer.selected)||null,products=monitor.products||[],resources=aggregateResources(products),historical=selectedDateKey&&selectedDateKey!==localDateKey(monitor.activity_view?.extent?.end_ms||Date.now()),live=!historical&&monitor.lifecycle==='monitoring',title=$('focus-title'),copyNode=$('focus-copy'),stats=$('focus-stats');stats.replaceChildren();let heading=text('pulseDetailTitle'),description=text('pulseDetailCopy'),eyebrow=text('currentSession'),panelTitle=text('activityExplorer'),panelCopy=text('activityExplorerCopy');if(explorerMode==='pulse'){if(selected){heading=text('selectedBlock');description=fullMoment.format(selected.start_ms)+' – '+fullMoment.format(selected.end_ms);appendInspectorStat(stats,text('selectedDate'),dateLabel.format(new Date(selected.start_ms)));appendInspectorStat(stats,text('selectedTime'),clock.format(selected.start_ms)+' – '+clock.format(selected.end_ms));appendInspectorStat(stats,text('duration'),seconds(selected.duration_seconds));appendInspectorStat(stats,text('state'),explorer.stateLabel(selected))}else{appendInspectorStat(stats,text('observationDate'),observationDateRange());appendInspectorStat(stats,text('observed'),seconds(totals.observed));appendInspectorStat(stats,text('activityBlocks'),format.format(view.active_block_count||0));appendInspectorStat(stats,text('activeAiTools'),format.format((view.systems||[]).filter(item=>item.active_seconds>0).length))}}else if(explorerMode==='runtime'){heading=system?system.name:text('runtimeDetailTitle');description=focusedSystemSignature?text('focusSystemHelp'):text('runtimeDetailCopy');panelTitle=text('runtimeDetailTitle');panelCopy=text('runtimeDetailCopy');appendInspectorStat(stats,text('observationDate'),observationDateRange());appendInspectorStat(stats,text('observed'),seconds(totals.observed));appendInspectorStat(stats,text('aiActive'),seconds(totals.active));appendInspectorStat(stats,text('activityRatio'),pct(totals.ratio));appendInspectorStat(stats,text('longestActive'),seconds(view.longest_active_seconds||0));appendInspectorStat(stats,text('activityBlocks'),format.format(view.active_block_count||0));appendInspectorStat(stats,text('availableRuntimes'),format.format(footprint.local_details?.runtimes?.length||0));appendInspectorStat(stats,text('hostedModelsRunning'),format.format(footprint.confirmed_running_model_count||0))}else if(explorerMode==='resources'){heading=system?system.name+' · '+text('resourcesNow'):text('resourcesDetailTitle');description=live?text('resourcesDetailCopy'):text('resourceNotRetained');eyebrow=system?.name||text('currentSession');panelTitle=text('resourcesDetailTitle');panelCopy=text('resourcesDetailCopy');const scoped=system||resources,cpuValue=system?scoped.current_cpu_percent:scoped.cpu,memoryValue=system?scoped.current_memory_bytes:scoped.memory;appendInspectorStat(stats,text('cpu'),live&&Number.isFinite(cpuValue)?format.format(Number(cpuValue.toFixed(1)))+'%':'—');appendInspectorStat(stats,text('memory'),live&&Number.isFinite(memoryValue)?bytes(memoryValue):'—');appendInspectorStat(stats,text('gpu'),text('notMeasured'));appendInspectorStat(stats,system?text('appSpace'):text('recognizedModelSpace'),system?text('notAttributed'):bytes(footprint.model_storage_bytes||0))}else{heading=system?.name||text('appsDetailTitle');description=system?text('appsDetailCopy'):text('noAppSelected');eyebrow=system?.name||text('currentSession');panelTitle=system?.name||text('appsDetailTitle');panelCopy=text('appsDetailCopy');if(system){document.documentElement.style.setProperty('--accent-system',systemColor(system.signature));appendInspectorStat(stats,text('activeDuration'),seconds(system.active_seconds));appendInspectorStat(stats,text('contribution'),Math.round(system.share*100)+'%');appendInspectorStat(stats,text('currentAppState'),system.state==='working-now'?text('workingNow'):text('openIdle'));appendInspectorStat(stats,text('activityPeriods'),format.format(system.period_count));appendInspectorStat(stats,text('firstObserved'),system.first_observed_ms?fullMoment.format(system.first_observed_ms):'—');appendInspectorStat(stats,text('lastObserved'),system.last_observed_ms?fullMoment.format(system.last_observed_ms):'—');appendInspectorStat(stats,text('cpu'),live&&Number.isFinite(system.current_cpu_percent)?format.format(Number(system.current_cpu_percent.toFixed(1)))+'%':'—');appendInspectorStat(stats,text('memory'),live&&Number.isFinite(system.current_memory_bytes)?bytes(system.current_memory_bytes):'—')}else{appendInspectorStat(stats,text('observationDate'),observationDateRange());appendInspectorStat(stats,text('appsView'),format.format((view.systems||[]).length));appendInspectorStat(stats,text('activeDuration'),seconds(totals.active));appendInspectorStat(stats,text('observed'),seconds(totals.observed))}}title.textContent=heading;copyNode.textContent=description;$('explorer-eyebrow').textContent=eyebrow;$('explorer-title').textContent=panelTitle;$('explorer-copy').textContent=panelCopy;syncModeButtons()}
73
74
  function appendInspectorStat(container,label,value){const node=document.createElement('div'),name=document.createElement('span'),strong=document.createElement('strong');node.className='inspector-stat';name.textContent=label;strong.textContent=value;node.append(name,strong);container.append(node)}function syncMixSelection(){for(const button of document.querySelectorAll('.mix-item')){const selected=button.dataset.signature===selectedSystemSignature,focused=button.dataset.signature===focusedSystemSignature;button.setAttribute('aria-pressed',String(selected));button.classList.toggle('is-focused',focused)}$('all-apps')?.classList.toggle('primary',!selectedSystemSignature&&!focusedSystemSignature);const focus=$('focus-system');if(focus){focus.disabled=!selectedSystemSignature;focus.textContent=focusedSystemSignature===selectedSystemSignature?text('clearFocus'):text('focusSystem');focus.classList.toggle('primary',Boolean(selectedSystemSignature&&focusedSystemSignature===selectedSystemSignature))}}function restoreInsightHeadline(){const headline=$('inspector-headline'),title=document.createElement('h2'),copyNode=document.createElement('p');title.textContent=text('observationShows');copyNode.className='insight-copy';copyNode.textContent=text('selectTimelineBlock');headline.replaceChildren(title,copyNode)}function productKindLabel(kind){return kind==='local-model-runtime'?text('systemModelRuntime'):kind==='ai-app'?text('systemAiApp'):text('systemAgent')}function renderInspector(){syncMixSelection();const container=$('app-inspector'),view=viewForDate(monitor.activity_view,selectedDateKey);if(!selectedSystemSignature){container.hidden=true;container.replaceChildren();return}const system=(view?.systems||[]).find(item=>item.signature===selectedSystemSignature),product=(monitor.products||[]).find(item=>item.signature===selectedSystemSignature);if(!system||!product){selectedSystemSignature=null;container.hidden=true;container.replaceChildren();syncMixSelection();return}container.hidden=false;container.replaceChildren();const head=document.createElement('div'),title=document.createElement('strong'),state=document.createElement('span'),runtime=document.createElement('div'),resources=document.createElement('div'),resourceTitle=document.createElement('p');head.className='inspector-head';title.textContent=system.name;state.className='inspector-state';state.textContent=system.state==='working-now'?text('workingNow'):text('openIdle');head.append(title,state);runtime.className='inspector-grid';appendInspectorStat(runtime,text('appType'),productKindLabel(system.kind));appendInspectorStat(runtime,text('activeDuration'),seconds(system.active_seconds));appendInspectorStat(runtime,text('contribution'),Math.round(system.share*100)+'%');appendInspectorStat(runtime,text('activityPeriods'),format.format(system.period_count));appendInspectorStat(runtime,text('longestActive'),seconds(system.longest_active_seconds));appendInspectorStat(runtime,text('detectedProcesses'),format.format(system.current_process_count));resourceTitle.className='eyebrow';resourceTitle.textContent=text('resourcesNow');resources.className='inspector-grid';const historical=selectedDateKey&&selectedDateKey!==localDateKey(monitor.activity_view?.extent?.end_ms||Date.now()),live=!historical&&monitor.lifecycle==='monitoring';appendInspectorStat(resources,text('cpu'),live&&Number.isFinite(system.current_cpu_percent)?format.format(Number(system.current_cpu_percent.toFixed(1)))+'%':'—');appendInspectorStat(resources,text('memory'),live&&Number.isFinite(system.current_memory_bytes)?bytes(system.current_memory_bytes):'—');appendInspectorStat(resources,text('gpu'),text('notMeasured'));appendInspectorStat(resources,text('appSpace'),text('notAttributed'));container.append(head,runtime,resourceTitle,resources)}
74
- function measuredDateKeys(view){const keys=new Set();for(const segment of view?.segments||[]){if(!segment.valid)continue;const end=Math.max(segment.start_ms,segment.end_ms-1);for(let cursor=segment.start_ms;cursor<end;cursor+=6*60*60*1000)keys.add(localDateKey(cursor));keys.add(localDateKey(end))}return [...keys].sort()}function renderDates(){const view=monitor.activity_view,keys=measuredDateKeys(view),picker=$('date-picker'),options=$('date-options');if(selectedDateKey&&!keys.includes(selectedDateKey))selectedDateKey=null;$('observation-date').textContent=selectedDateKey?dateLabel.format(new Date(selectedDateKey+'T12:00:00')):observationDateRange();$('observation-span').textContent=(view?.observation_ids?.length||0)>1?text('observationSessions',{count:format.format(view.observation_ids.length)}):text('observationSpan');picker.dataset.single=String(keys.length<2);options.replaceChildren();for(const key of keys){const button=document.createElement('button'),mark=document.createElement('span');button.type='button';button.className='date-option'+(selectedDateKey===key?' active':'');button.textContent=dateLabel.format(new Date(key+'T12:00:00'));mark.textContent='●';button.append(mark);button.addEventListener('click',()=>{selectedDateKey=key;picker.open=false;renderMonitor()});options.append(button)}$('resource-history-state').textContent=monitor.lifecycle==='monitoring'&&(!selectedDateKey||selectedDateKey===localDateKey(view?.extent?.end_ms||Date.now()))?text('resourceLiveOnly'):text('resourceNotRetained')}
75
+ function measuredDateKeys(view){const keys=new Set();for(const segment of view?.segments||[]){if(!segment.valid)continue;const end=Math.max(segment.start_ms,segment.end_ms-1);for(let cursor=segment.start_ms;cursor<end;cursor+=6*60*60*1000)keys.add(localDateKey(cursor));keys.add(localDateKey(end))}return [...keys].sort()}function renderDates(){const view=monitor.activity_view,keys=measuredDateKeys(view),picker=$('date-picker'),options=$('date-options');if(selectedDateKey&&!keys.includes(selectedDateKey))selectedDateKey=null;$('observation-date').textContent=selectedDateKey?dateLabel.format(new Date(selectedDateKey+'T12:00:00')):observationDateRange();$('observation-span').textContent=((view?.continuity_ids?.length||view?.observation_ids?.length||0)>1)?text('observationSessions',{count:format.format(view.continuity_ids?.length||view.observation_ids.length)}):text('observationSpan');picker.dataset.single=String(keys.length<2);options.replaceChildren();for(const key of keys){const button=document.createElement('button'),mark=document.createElement('span');button.type='button';button.className='date-option'+(selectedDateKey===key?' active':'');button.textContent=dateLabel.format(new Date(key+'T12:00:00'));mark.textContent='●';button.append(mark);button.addEventListener('click',()=>{selectedDateKey=key;picker.open=false;renderMonitor()});options.append(button)}$('resource-history-state').textContent=monitor.lifecycle==='monitoring'&&(!selectedDateKey||selectedDateKey===localDateKey(view?.extent?.end_ms||Date.now()))?text('resourceLiveOnly'):text('resourceNotRetained')}
75
76
  function renderInsights(){const listNode=$('insight-list'),view=monitor.activity_view||{},insights=view.insights||[];listNode.replaceChildren();if(!insights.length){const note=document.createElement('div');note.className='early';note.textContent=monitor.observed_seconds<60?text('earlyObservationCopy'):text('pulseWaiting');listNode.append(note);return}for(const insight of insights){const button=document.createElement('button');button.type='button';button.className='insight';const evidence=insight.evidence||{type:'observation'},contribution=(view.contributions||[])[0];button.style.setProperty('--accent-system',contribution?systemColor(contribution.signature):'var(--brand)');button.textContent=insight.text;button.addEventListener('click',()=>{if(evidence.type==='range')explorer.focusRange(evidence.start_ms,evidence.end_ms);else if(evidence.type==='segment')explorer.focusSegment(evidence.segment_id);else if(evidence.type==='system')explorer.selectSystem(evidence.signature);else explorer.reset()});listNode.append(button)}}
76
- function renderSystemTimeline(){const container=$('system-timeline'),view=currentView()||{},extent=view.extent,range=explorer.visibleRange();container.replaceChildren();if(!extent||!view.segments?.length){const empty=document.createElement('div');empty.className='timeline-empty';empty.textContent=text('noMeasuredActivity');container.append(empty);return}const axis=document.createElement('div'),axisLabel=document.createElement('span'),ticks=document.createElement('div');axis.className='timeline-axis';axisLabel.className='timeline-axis-label';axisLabel.textContent=text('systems');ticks.className='timeline-ticks';for(let index=0;index<5;index++){const ratio=index/4,tick=document.createElement('span');tick.className='timeline-tick';tick.style.left=ratio*100+'%';tick.textContent=clock.format(range[0]+ratio*(range[1]-range[0]));ticks.append(tick)}axis.append(axisLabel,ticks);container.append(axis);const products=(focusedSystemSignature?listedProducts().filter(product=>product.signature===focusedSystemSignature):listedProducts()),systems=new Map((view.systems||[]).map(system=>[system.signature,system]));for(const product of products){const system=systems.get(product.signature);if(focusedSystemSignature&&!system)continue;const row=document.createElement('div'),label=document.createElement('button'),dot=document.createElement('i'),name=document.createElement('strong'),meta=document.createElement('span'),track=document.createElement('div'),color=systemColor(product.signature),segments=(view.segments||[]).filter(segment=>segment.state==='active'&&segment.system_signatures.includes(product.signature)&&segment.end_ms>=range[0]&&segment.start_ms<=range[1]);row.className='timeline-row'+(selectedSystemSignature===product.signature?' is-selected':'')+(focusedSystemSignature===product.signature?' is-focused':'');row.style.setProperty('--system-color',color);label.type='button';label.className='timeline-system';label.setAttribute('aria-pressed',String(selectedSystemSignature===product.signature));dot.setAttribute('aria-hidden','true');name.textContent=product.name;meta.textContent=(product.state==='working-now'?text('workingNow'):text('openIdle'))+' · '+seconds(system?.active_seconds||product.active_seconds||0);label.append(dot,name,meta);label.addEventListener('click',()=>explorer.selectSystem(product.signature));track.className='timeline-track';for(const segment of segments){const start=Math.max(range[0],segment.start_ms),end=Math.min(range[1],Math.max(segment.end_ms,segment.start_ms+(monitor.sample_interval_ms||1000))),left=(start-range[0])/Math.max(1,range[1]-range[0])*100,width=Math.max(.35,(end-start)/Math.max(1,range[1]-range[0])*100),block=document.createElement('button');block.type='button';block.className='timeline-block'+(segment.id===explorer.selected?' is-pinned':'')+(segment.is_longest_active||Math.abs(segment.duration_seconds-(system?.longest_active_seconds||-1))<.01?' is-longest':'');block.style.left=left+'%';block.style.width=width+'%';block.style.setProperty('--system-color',color);block.textContent=width>7?seconds(segment.duration_seconds):'';const evidence=product.name+' · '+fullMoment.format(segment.start_ms)+' – '+fullMoment.format(segment.end_ms)+' · '+seconds(segment.duration_seconds)+' · '+explorer.stateLabel(segment);block.setAttribute('aria-label',evidence);block.addEventListener('pointerenter',event=>{explorer.tooltip.textContent=evidence;explorer.tooltip.hidden=false;const rect=container.getBoundingClientRect();explorer.tooltip.style.left=Math.min(event.clientX-rect.left+8,rect.width-explorer.tooltip.offsetWidth-5)+'px';explorer.tooltip.style.top=Math.max(3,event.clientY-rect.top-explorer.tooltip.offsetHeight-8)+'px'});block.addEventListener('pointerleave',()=>{explorer.tooltip.hidden=true});block.addEventListener('click',()=>{selectedSystemSignature=product.signature;explorer.focusSegment(segment.id)});track.append(block)}if(!segments.length){const empty=document.createElement('span');empty.className='timeline-empty';empty.textContent=text('noMeasuredActivity');track.append(empty)}row.append(label,track);container.append(row)}}
77
+ function renderSystemTimeline(){const container=$('system-timeline'),view=currentView()||{},extent=view.extent,range=explorer.visibleRange();container.replaceChildren();if(!extent||!view.segments?.length){const empty=document.createElement('div');empty.className='timeline-empty';empty.textContent=text('noMeasuredActivity');container.append(empty);return}const axis=document.createElement('div'),axisLabel=document.createElement('span'),ticks=document.createElement('div');axis.className='timeline-axis';axisLabel.className='timeline-axis-label';axisLabel.textContent=text('systems');ticks.className='timeline-ticks';const trackWidth=Math.max(1,container.clientWidth-130),tickCount=trackWidth<420?2:trackWidth<700?3:5;for(let index=0;index<tickCount;index++){const ratio=index/(tickCount-1),tick=document.createElement('span');tick.className='timeline-tick';tick.style.left=ratio*100+'%';tick.textContent=clock.format(range[0]+ratio*(range[1]-range[0]));ticks.append(tick)}axis.append(axisLabel,ticks);container.append(axis);const products=(focusedSystemSignature?listedProducts().filter(product=>product.signature===focusedSystemSignature):listedProducts()),systems=new Map((view.systems||[]).map(system=>[system.signature,system]));for(const product of products){const system=systems.get(product.signature);if(focusedSystemSignature&&!system)continue;const row=document.createElement('div'),label=document.createElement('button'),dot=document.createElement('i'),name=document.createElement('strong'),meta=document.createElement('span'),track=document.createElement('div'),color=systemColor(product.signature),segments=(view.segments||[]).filter(segment=>segment.state==='active'&&segment.system_signatures.includes(product.signature)&&segment.end_ms>=range[0]&&segment.start_ms<=range[1]);row.className='timeline-row'+(selectedSystemSignature===product.signature?' is-selected':'')+(focusedSystemSignature===product.signature?' is-focused':'');row.style.setProperty('--system-color',color);label.type='button';label.className='timeline-system';label.setAttribute('aria-pressed',String(selectedSystemSignature===product.signature));dot.setAttribute('aria-hidden','true');name.textContent=product.name;meta.textContent=(product.state==='working-now'?text('workingNow'):text('openIdle'))+' · '+seconds(system?.active_seconds||product.active_seconds||0);label.append(dot,name,meta);label.addEventListener('click',()=>explorer.selectSystem(product.signature));track.className='timeline-track';for(const segment of segments){const start=Math.max(range[0],segment.start_ms),end=Math.min(range[1],Math.max(segment.end_ms,segment.start_ms+(monitor.sample_interval_ms||1000))),left=(start-range[0])/Math.max(1,range[1]-range[0])*100,width=Math.max(.35,(end-start)/Math.max(1,range[1]-range[0])*100),block=document.createElement('button');block.type='button';block.className='timeline-block'+(segment.id===explorer.selected?' is-pinned':'')+(segment.is_longest_active||Math.abs(segment.duration_seconds-(system?.longest_active_seconds||-1))<.01?' is-longest':'');block.style.left=left+'%';block.style.width=width+'%';block.style.setProperty('--system-color',color);block.textContent=width>7?seconds(segment.duration_seconds):'';const evidence=product.name+' · '+fullMoment.format(segment.start_ms)+' – '+fullMoment.format(segment.end_ms)+' · '+seconds(segment.duration_seconds)+' · '+explorer.stateLabel(segment);block.setAttribute('aria-label',evidence);block.addEventListener('pointerenter',event=>{explorer.tooltip.textContent=evidence;explorer.tooltip.hidden=false;const rect=container.getBoundingClientRect();explorer.tooltip.style.left=Math.min(event.clientX-rect.left+8,rect.width-explorer.tooltip.offsetWidth-5)+'px';explorer.tooltip.style.top=Math.max(3,event.clientY-rect.top-explorer.tooltip.offsetHeight-8)+'px'});block.addEventListener('pointerleave',()=>{explorer.tooltip.hidden=true});block.addEventListener('click',()=>{selectedSystemSignature=product.signature;explorer.focusSegment(segment.id)});track.append(block)}if(!segments.length){const empty=document.createElement('span');empty.className='timeline-empty';empty.textContent=text('noMeasuredActivity');track.append(empty)}row.append(label,track);container.append(row)}}
77
78
  function renderRuntimeFootprint(){const container=$('runtime-footprint-list'),view=currentView()||{},systems=view.systems||[];container.replaceChildren();if(!systems.length){const empty=document.createElement('div');empty.className='early';empty.textContent=text('noMeasuredContribution');container.append(empty);return}for(const system of systems){const row=document.createElement('button'),name=document.createElement('strong'),runtime=document.createElement('span'),share=document.createElement('span');row.type='button';row.className='runtime-footprint-row'+(selectedSystemSignature===system.signature?' is-selected':'');row.style.setProperty('--system-color',systemColor(system.signature));name.textContent=system.name;runtime.textContent=seconds(system.active_seconds);share.textContent=Math.round(system.share*100)+'%';row.append(name,runtime,share);row.addEventListener('click',()=>explorer.selectSystem(system.signature));container.append(row)}}
78
79
  function renderInspectorApps(){const container=$('inspector-apps-list');if(!container)return;container.replaceChildren();for(const product of listedProducts()){const row=document.createElement('div'),name=document.createElement('strong'),note=document.createElement('span'),parts=[product.state==='working-now'?text('workingNow'):text('openIdle'),format.format(product.process_count||0)+' '+text((product.process_count||0)===1?'measuredProcess':'measuredProcesses')];if(Number.isFinite(product.cpu_percent))parts.push(format.format(Number(product.cpu_percent.toFixed(1)))+'% '+text('cpu'));if(Number.isFinite(product.memory_bytes))parts.push(bytes(product.memory_bytes)+' '+text('memory'));row.className='inspector-app-row';name.textContent=product.name;note.textContent=parts.join(' · ');row.append(name,note);container.append(row)}if(!container.children.length){const empty=document.createElement('div');empty.className='early';empty.textContent=text('noMeasuredContribution');container.append(empty)}}
79
80
  function renderBelowSummary(){const view=currentView()||{systems:[],active_block_count:0,longest_active_seconds:0},totals=selectedDateKey||focusedSystemSignature?viewTotals(view):{active:monitor.active_seconds,observed:monitor.observed_seconds,ratio:monitor.activity_ratio},resources=aggregateResources(monitor.products||[]),historical=selectedDateKey&&selectedDateKey!==localDateKey(monitor.activity_view?.extent?.end_ms||Date.now()),live=!historical&&monitor.lifecycle==='monitoring';$('below-observed').textContent=seconds(totals.observed);$('below-active').textContent=seconds(totals.active);$('below-ratio').textContent=pct(totals.ratio);$('below-periods').textContent=format.format(view.active_block_count||0);$('below-longest').textContent=seconds(view.longest_active_seconds||0);$('below-systems').textContent=format.format((view.systems||[]).length);$('below-cpu').textContent=live&&Number.isFinite(resources.cpu)?format.format(Number(resources.cpu.toFixed(1)))+'%':'—';$('below-memory').textContent=live&&Number.isFinite(resources.memory)?bytes(resources.memory):'—';$('below-runtimes').textContent=format.format(footprint.local_details?.runtimes?.length||0);$('below-models').textContent=format.format(footprint.model_record_count||0);$('below-running').textContent=format.format(footprint.confirmed_running_model_count||0);$('below-space').textContent=bytes(footprint.model_storage_bytes||0);$('below-local-insight').textContent=$('hosted-insight').textContent;renderRuntimeFootprint()}
@@ -81,18 +82,18 @@ function renderMix(){const bar=$('mix-bar'),listNode=$('mix-list'),view=viewForD
81
82
  function renderHostedLocal(){const products=monitor.products||[],workingLocal=products.filter(product=>product.kind==='local-model-runtime'&&product.state==='working-now'),running=footprint.confirmed_running_model_count||0;$('models-found').textContent=format.format(footprint.model_record_count||0);$('models-running').textContent=format.format(running);$('device-storage').textContent=bytes(footprint.model_storage_bytes||0);$('metric-local').textContent=format.format(footprint.model_record_count||0)+' · '+bytes(footprint.model_storage_bytes||0);$('metric-local-running').textContent=format.format(running)+' '+text('runningShort');$('hosted-insight').textContent=running>0||workingLocal.length?text('hostedModelsRunningInsight'):text('localAiNone')}
82
83
  function renderRuntimes(){const container=$('rail-runtimes');container.replaceChildren();for(const runtime of footprint.local_details?.runtimes||[]){const row=document.createElement('button'),name=document.createElement('strong'),status=document.createElement('span');row.type='button';row.className='runtime-item';row.title=text('inspectRuntimeHint');name.textContent=runtime.name;status.textContent=runtime.loaded_model_count?text('modelsLoaded',{count:runtime.loaded_model_count,models:runtime.loaded_model_count===1?text('model'):text('models')}):text('verifiedAvailable');row.append(name,status);row.addEventListener('click',()=>setExplorerMode('runtime'));container.append(row)}if(!container.children.length){const note=document.createElement('div');note.className='early';note.textContent='—';container.append(note)}}function renderDetails(){if(!footprint.local_details)return;const details=footprint.local_details,runtimeList=$('runtime-list'),modelList=$('model-list'),appList=$('app-list');for(const node of [runtimeList,modelList,appList])node.replaceChildren();for(const runtime of details.runtimes)add(runtimeList,runtime.name,runtime.loaded_model_count?text('modelsLoaded',{count:runtime.loaded_model_count,models:runtime.loaded_model_count===1?text('model'):text('models')}):text('verifiedAvailable'));for(const model of details.models.filter(item=>item.loaded))add(modelList,model.name,text('loaded',{count:''}).trim());for(const product of monitor.products||[]){const note=[text(product.state==='working-now'?'working':'openIdleLegend'),format.format(product.process_count)+' '+text(product.process_count===1?'measuredProcess':'measuredProcesses'),product.memory_bytes?bytes(product.memory_bytes):''].filter(Boolean).join(' · ');add(appList,product.name,note)}if(!appList.children.length)for(const agent of details.agents)add(appList,agent.name,text('processActivity'));if($('raw-system-count'))$('raw-system-count').textContent=format.format((monitor.products||[]).length);renderRuntimes()}
83
84
  function saveLastSummary(){if(!monitor.observed_seconds)return;const dominant=dominantProduct();try{localStorage.setItem(lastSummaryKey,JSON.stringify({activity_ratio:monitor.activity_ratio,active_tool:dominant?.name||null,local_models_found:footprint.model_record_count||0,local_models_running:footprint.confirmed_running_model_count||0}))}catch{}}
84
- function renderMonitor(){const products=monitor.products||[],working=userFacingProducts().filter(product=>product.state==='working-now'),presence=monitor.presence||{state:'active',observation_eligible:true},status=$('monitor-status');status.className='status';let statusText;if(monitor.lifecycle==='stopped'){status.classList.add('stopped');statusText=text('stopped')}else if(!presence.observation_eligible){status.classList.add('paused');statusText=text('paused')}else if(working.length)statusText=text('menuWorking',{count:working.length});else statusText=text('menuMonitoring');$('monitor-status-text').textContent=statusText;if($('monitor-button'))$('monitor-button').textContent=monitor.lifecycle==='monitoring'?text('stopMonitoring'):monitor.observed_seconds?text('startMonitoringAgain'):text('startMonitoring');appendResourceSample();renderDates();const view=currentView()||{segments:[],contributions:[],systems:[],insights:[],longest_active_seconds:0},totals=selectedDateKey||focusedSystemSignature?viewTotals(view):{active:monitor.active_seconds,observed:monitor.observed_seconds,ratio:monitor.activity_ratio},resources=aggregateResources(products),historical=selectedDateKey&&selectedDateKey!==localDateKey(monitor.activity_view?.extent?.end_ms||Date.now()),live=!historical&&monitor.lifecycle==='monitoring',dominant=dominantProduct();if(dominant)document.documentElement.style.setProperty('--accent-system',systemColor(dominant));$('metric-ratio').textContent=pct(totals.ratio);$('ratio-label').textContent=totals.observed<60?text('earlyObservation'):totals.ratio>=.7?text('mostlyActive'):totals.ratio<=.3?text('mostlyIdle'):text('mixedActivity');$('metric-active').textContent=seconds(totals.active);$('metric-observed').textContent=seconds(totals.observed);$('metric-systems').textContent=format.format((view.systems||[]).filter(system=>system.active_seconds>0||system.state==='working-now').length);$('metric-longest').textContent=seconds(view.longest_active_seconds||0);$('observation-identity').textContent=text('observationIdentity',{number:monitor.observation_id??'—'});$('rail-observed').textContent=seconds(totals.observed);$('rail-active').textContent=seconds(totals.active);$('rail-ratio').textContent=pct(totals.ratio);$('rail-longest').textContent=seconds(view.longest_active_seconds||0);$('rail-cpu').textContent=live&&Number.isFinite(resources.cpu)?format.format(Number(resources.cpu.toFixed(1)))+'%':'—';$('rail-memory').textContent=live&&Number.isFinite(resources.memory)?bytes(resources.memory):'—';$('rail-space').textContent=bytes(footprint.model_storage_bytes||0);explorer.setData(view);renderInsights();renderMix();renderHostedLocal();renderDetails();renderInspector();renderFocusSummary();renderSystemTimeline();renderInspectorApps();renderBelowSummary();if($('overhead')){$('overhead').textContent=monitor.overhead?.current_cpu_percent===null?text('warmingUp'):format.format(Number(monitor.overhead.current_cpu_percent.toFixed(1)))+'% CPU';$('overhead-note').textContent=bytes(monitor.overhead?.current_memory_bytes||0)+' RAM'}if($('review-payload')){const eligible=monitor.observed_seconds>=3600;$('review-payload').disabled=!eligible;$('compare-progress').textContent=eligible?'':text('globalProgress',{remaining:seconds(Math.max(0,3600-monitor.observed_seconds))})}saveLastSummary()}
85
+ function renderMonitor(){const products=monitor.products||[],working=userFacingProducts().filter(product=>product.state==='working-now'),presence=monitor.presence||{state:'active',observation_eligible:true},status=$('monitor-status');status.className='status';let statusText;if(monitor.lifecycle==='stopped'){status.classList.add('stopped');statusText=text('stopped')}else if(!presence.observation_eligible){status.classList.add('paused');statusText=text('paused')}else if(working.length)statusText=text('menuWorking',{count:working.length});else statusText=text('menuMonitoring');$('monitor-status-text').textContent=statusText;if($('monitor-button'))$('monitor-button').textContent=monitor.lifecycle==='monitoring'?text('stopMonitoring'):monitor.observed_seconds?text('startMonitoringAgain'):text('startMonitoring');appendResourceSample();renderDates();const view=currentView()||{segments:[],contributions:[],systems:[],insights:[],longest_active_seconds:0},totals=selectedDateKey||focusedSystemSignature?viewTotals(view):{active:monitor.active_seconds,observed:monitor.observed_seconds,ratio:monitor.activity_ratio},resources=aggregateResources(products),historical=selectedDateKey&&selectedDateKey!==localDateKey(monitor.activity_view?.extent?.end_ms||Date.now()),live=!historical&&monitor.lifecycle==='monitoring',dominant=dominantProduct();if(dominant)document.documentElement.style.setProperty('--accent-system',systemColor(dominant));$('metric-ratio').textContent=pct(totals.ratio);$('ratio-label').textContent=totals.observed<60?text('earlyObservation'):totals.ratio>=.7?text('mostlyActive'):totals.ratio<=.3?text('mostlyIdle'):text('mixedActivity');$('metric-active').textContent=seconds(totals.active);$('metric-observed').textContent=seconds(totals.observed);$('metric-systems').textContent=format.format((view.systems||[]).filter(system=>system.active_seconds>0||system.state==='working-now').length);$('metric-longest').textContent=seconds(view.longest_active_seconds||0);$('observation-identity').textContent=text('observationIdentity',{number:monitor.observation_id??'—'});$('rail-observed').textContent=seconds(totals.observed);$('rail-active').textContent=seconds(totals.active);$('rail-ratio').textContent=pct(totals.ratio);$('rail-longest').textContent=seconds(view.longest_active_seconds||0);$('rail-cpu').textContent=live&&Number.isFinite(resources.cpu)?format.format(Number(resources.cpu.toFixed(1)))+'%':'—';$('rail-memory').textContent=live&&Number.isFinite(resources.memory)?bytes(resources.memory):'—';$('rail-space').textContent=bytes(footprint.model_storage_bytes||0);explorer.setData(view);renderInsights();renderMix();renderHostedLocal();renderDetails();renderInspector();renderFocusSummary();renderSystemTimeline();renderInspectorApps();renderBelowSummary();if($('overhead')){$('overhead').textContent=monitor.overhead?.current_cpu_percent===null?text('warmingUp'):format.format(Number(monitor.overhead.current_cpu_percent.toFixed(1)))+'% CPU';$('overhead-note').textContent=bytes(monitor.overhead?.current_memory_bytes||0)+' RAM'}if($('review-payload')){const eligible=monitor.observed_seconds>=3600;$('review-payload').disabled=!eligible;$('compare-progress').textContent=eligible?'':text('globalProgress',{remaining:seconds(Math.max(0,3600-monitor.observed_seconds))});const preview=monitor.global_preview;$('global-result').textContent=preview?.state==='contributed'?text('previewContributed'):preview?.state==='unavailable'?text('previewUnavailable'):monitor.global_permission==='granted'?text('previewWaiting'):text('permissionNeeded')}saveLastSummary()}
85
86
  function shareObservationWindow(){const extent=monitor.activity_view?.extent;if(!extent)return text('shareMeasuredLocally');const start=new Date(extent.start_ms),end=new Date(Math.max(extent.start_ms,extent.end_ms-1));return shareDateLabel.format(start)+' '+clock.format(start)+' – '+shareDateLabel.format(end)+' '+clock.format(end)}
86
87
  function primaryInsight(){return monitor.insights?.[0]||text('activeShareFallback',{ratio:pct(monitor.activity_ratio)})}function shareInsightLine(){const tools=activeToolNames();if(tools.length===1)return text('shareFocusedLine');if(tools.length>1)return text('shareMultiLine',{count:format.format(tools.length)});if(footprint.model_record_count)return text('shareModelReserveLine');return primaryInsight()}function shareDurationLine(){return monitor.observed_seconds?text('shareMeasuredDurations',{observed:seconds(monitor.observed_seconds),active:seconds(monitor.active_seconds||0)}):''}function shareCaption(){const tools=activeToolNames(),running=footprint.confirmed_running_model_count||0,details=[text('shareActivity',{ratio:pct(monitor.activity_ratio)}),shareDurationLine(),tools.length?text('shareTool',{tools:list(tools)}):'',text('shareModels',{count:footprint.model_record_count,models:footprint.model_record_count===1?text('model'):text('models'),running:format.format(running)})].filter(Boolean).join(' ');return text('captionFirst',{ratio:pct(monitor.activity_ratio)})+'\\n\\n'+details+'\\n\\n'+text('captionQuestion')+'\\n\\nforkit.dev/ai-footprint'}
87
88
  function wrap(x,value,left,top,maxWidth,lineHeight,maxLines){const words=String(value||'').split(' '),lines=[];let line='';for(const word of words){const next=line?line+' '+word:word;if(x.measureText(next).width>maxWidth&&line){lines.push(line);line=word}else line=next}if(line)lines.push(line);for(let index=0;index<Math.min(lines.length,maxLines);index++)x.fillText(lines[index],left,top+index*lineHeight)}
88
89
  async function drawShare(){const canvas=$('share-canvas'),context=canvas.getContext('2d'),view=currentView()||monitor.activity_view,contributions=(view?.contributions||[]).slice(0,3),tools=activeToolNames(),running=footprint.confirmed_running_model_count||0,totals=selectedDateKey?viewTotals(view):{active:monitor.active_seconds,observed:monitor.observed_seconds,ratio:monitor.activity_ratio},activity=totals.observed?pct(totals.ratio):format.format(footprint.model_record_count),purple='#2A1F55',teal='#008190',lightTeal='#6AA7AB',orange='#F49355',cream='#F1EBDF',gradient=context.createLinearGradient(0,0,1080,1080);gradient.addColorStop(0,purple);gradient.addColorStop(.55,'#342761');gradient.addColorStop(1,teal);context.fillStyle=gradient;context.fillRect(0,0,1080,1080);context.fillStyle=cream;context.beginPath();context.roundRect(42,42,996,996,44);context.fill();context.fillStyle=orange;context.fillRect(42,42,996,16);if(shareLogo){const image=await new Promise(resolve=>{const value=new Image();value.onload=()=>resolve(value);value.onerror=()=>resolve(null);value.src=shareLogo});if(image)context.drawImage(image,78,78,72,72)}context.fillStyle=purple;context.font='900 28px Inter,sans-serif';context.fillText(text('myFootprint'),78,200);context.fillStyle=teal;context.font='950 160px Inter,sans-serif';context.fillText(activity,70,400);context.font='900 31px Inter,sans-serif';context.fillText(totals.observed?text('shareActive'):text('localModels'),82,450);context.fillStyle=purple;context.font='850 24px Inter,sans-serif';context.fillText(shareObservationDate()||text('shareMeasuredLocally').toLocaleUpperCase(locale),82,505);context.fillStyle=lightTeal;context.beginPath();context.roundRect(78,548,924,260,28);context.fill();context.fillStyle=purple;context.font='900 23px Inter,sans-serif';context.fillText(tools.length===1?text('oneActiveTool'):text('activeToolsCount',{count:tools.length}),108,595);let y=650;context.font='850 28px Inter,sans-serif';for(const item of contributions){context.fillStyle=systemColor(item.signature);context.beginPath();context.arc(116,y-9,7,0,Math.PI*2);context.fill();context.fillStyle=purple;context.fillText(item.name,140,y);context.textAlign='right';context.fillText(Math.round(item.share*100)+'%',956,y);context.textAlign='left';y+=47}context.fillStyle=purple;context.font='800 24px Inter,sans-serif';context.fillText(seconds(totals.active)+' '+text('shareActive').toLowerCase()+' · '+seconds(totals.observed)+' '+text('validObservation').toLowerCase(),108,770);context.fillStyle=purple;context.font='900 22px Inter,sans-serif';context.fillText(text('localAi').toLocaleUpperCase(locale),82,872);context.font='820 27px Inter,sans-serif';context.fillText(format.format(footprint.model_record_count)+' '+text('models').toLowerCase()+' · '+bytes(footprint.model_storage_bytes||0)+' · '+format.format(running)+' '+text('runningShort'),82,915);context.fillStyle=teal;context.font='800 22px Inter,sans-serif';context.fillText('forkit.dev/ai-footprint',82,992);context.textAlign='right';context.fillStyle=purple;context.font='750 20px Inter,sans-serif';context.fillText('Forkit AI Footprint',998,992);context.textAlign='left'}
89
90
  const drawShareBase=drawShare;drawShare=async function(){await drawShareBase();const canvas=$('share-canvas'),context=canvas.getContext('2d'),purple='#2A1F55',teal='#008190',cream='#F1EBDF';context.fillStyle=cream;context.fillRect(70,474,940,48);context.fillStyle=purple;context.font='850 22px Inter,sans-serif';wrap(context,shareObservationWindow(),82,505,900,26,1);context.fillStyle=teal;context.font='900 22px Inter,sans-serif';wrap(context,text('shareLocalChoice'),82,833,900,27,2)}
90
91
  const dialog=$('share-dialog');async function openShare(){$('share-heading').textContent=shareInsightLine();await drawShare();dialog.showModal()}$('share-button').addEventListener('click',openShare);$('close-share').addEventListener('click',()=>dialog.close());async function blob(){await drawShare();return new Promise(resolve=>$('share-canvas').toBlob(resolve,'image/png'))}async function dataUrl(){const value=await blob();if(!value)return null;return new Promise(resolve=>{const reader=new FileReader();reader.onload=()=>resolve(reader.result);reader.onerror=()=>resolve(null);reader.readAsDataURL(value)})}function nativeAction(action,payload={}){const bridge=window.webkit?.messageHandlers?.forkitShare;if(!bridge)return false;bridge.postMessage({action,...payload});return true}window.forkitNativeShareResult=result=>{if(result.action==='open-global'){$('global-result').textContent=result.message||'';return}$('share-status').textContent=result.message||text('sharePrivacy');if(result.action==='copy-image')$('copy-image').textContent=text('copied');if(result.action==='copy-caption')$('copy-share').textContent=text('copied')};$('download-share').addEventListener('click',async()=>{const png=await dataUrl();if(!png)return;if(nativeAction('save',{png}))return;const value=await blob(),url=URL.createObjectURL(value),anchor=document.createElement('a');anchor.href=url;anchor.download='my-forkit-ai-footprint.png';anchor.click();setTimeout(()=>URL.revokeObjectURL(url),1000)});$('copy-share').addEventListener('click',async()=>{const caption=shareCaption();if(nativeAction('copy-caption',{caption}))return;await navigator.clipboard.writeText(caption);$('copy-share').textContent=text('copied')});$('copy-image').addEventListener('click',async()=>{const png=await dataUrl();if(!png)return;if(nativeAction('copy-image',{png}))return;const value=await blob();try{await navigator.clipboard.write([new ClipboardItem({'image/png':value})]);$('copy-image').textContent=text('copied')}catch{$('share-status').textContent=text('copyUnavailable')}});$('native-share').addEventListener('click',async()=>{const png=await dataUrl();if(!png)return;const caption=shareCaption();if(nativeAction('share',{png,caption}))return;const value=await blob(),file=new File([value],'my-forkit-ai-footprint.png',{type:'image/png'});if(navigator.share&&(!navigator.canShare||navigator.canShare({files:[file]})))await navigator.share({title:text('shareTitle'),text:caption,files:[file]});else await navigator.clipboard.writeText(caption)});
91
- for(const button of document.querySelectorAll('[data-resource-mode]'))button.addEventListener('click',()=>{explorerMode='resources';syncModeButtons();resourceMode=button.dataset.resourceMode;for(const item of document.querySelectorAll('[data-resource-mode]'))item.classList.toggle('active',item===button);explorer.setResourceMode(resourceMode);renderFocusSummary()});for(const button of document.querySelectorAll('[data-explorer-mode]'))button.addEventListener('click',()=>setExplorerMode(button.dataset.explorerMode));for(const section of document.querySelectorAll('.rail-section[data-view]'))section.addEventListener('click',event=>{if(event.target.closest('button,select'))return;setExplorerMode(section.dataset.view)});$('zoom-in').addEventListener('click',()=>{explorer.zoom(.65,explorer.visibleRange().reduce((a,b)=>a+b)/2);renderSystemTimeline()});$('zoom-out').addEventListener('click',()=>{explorer.zoom(1.4,explorer.visibleRange().reduce((a,b)=>a+b)/2);renderSystemTimeline()});$('reset-view').addEventListener('click',()=>{explorer.reset();setExplorerMode('pulse',false);renderMonitor()});$('system-timeline').addEventListener('wheel',event=>{event.preventDefault();explorer.zoom(event.deltaY<0?.78:1.22,explorer.visibleRange().reduce((a,b)=>a+b)/2);renderSystemTimeline()},{passive:false});for(const next of ['en','de'])$('locale-'+next).addEventListener('click',()=>{localStorage.setItem('forkit-footprints-locale',next);const url=new URL(location.href);url.searchParams.set('lang',next);location.href=url.href});const preferred=localStorage.getItem('forkit-footprints-locale');if(preferred&&preferred!==locale){const url=new URL(location.href);url.searchParams.set('lang',preferred);location.replace(url.href)}
92
+ for(const button of document.querySelectorAll('[data-resource-mode]'))button.addEventListener('click',()=>{explorerMode='resources';syncModeButtons();resourceMode=button.dataset.resourceMode;for(const item of document.querySelectorAll('[data-resource-mode]'))item.classList.toggle('active',item===button);explorer.setResourceMode(resourceMode);renderFocusSummary()});for(const button of document.querySelectorAll('[data-explorer-mode]'))button.addEventListener('click',()=>setExplorerMode(button.dataset.explorerMode));for(const section of document.querySelectorAll('.rail-section[data-view]'))section.addEventListener('click',event=>{if(event.target.closest('button,select'))return;setExplorerMode(section.dataset.view)});$('zoom-in').addEventListener('click',()=>{explorer.zoom(.65,explorer.visibleRange().reduce((a,b)=>a+b)/2);renderSystemTimeline()});$('zoom-out').addEventListener('click',()=>{explorer.zoom(1.4,explorer.visibleRange().reduce((a,b)=>a+b)/2);renderSystemTimeline()});$('reset-view').addEventListener('click',()=>{explorer.reset();setExplorerMode('pulse',false);renderMonitor()});$('system-timeline').addEventListener('wheel',event=>{event.preventDefault();explorer.zoom(event.deltaY<0?.78:1.22,explorer.visibleRange().reduce((a,b)=>a+b)/2);renderSystemTimeline()},{passive:false});let timelineResizeFrame=0;new ResizeObserver(()=>{cancelAnimationFrame(timelineResizeFrame);timelineResizeFrame=requestAnimationFrame(renderSystemTimeline)}).observe($('system-timeline'));for(const next of ['en','de'])$('locale-'+next).addEventListener('click',()=>{localStorage.setItem('forkit-footprints-locale',next);const url=new URL(location.href);url.searchParams.set('lang',next);location.href=url.href});const preferred=localStorage.getItem('forkit-footprints-locale');if(preferred&&preferred!==locale){const url=new URL(location.href);url.searchParams.set('lang',preferred);location.replace(url.href)}
92
93
  async function auth(endpoint,options={}){return fetch(endpoint,{method:'POST',headers:{'x-forkit-footprints-session':config.session_token,'content-type':'application/json'},...options})}
93
94
  if(config){void auth(config.locale_endpoint,{body:JSON.stringify({locale})});$('monitor-button').addEventListener('click',async()=>{const endpoint=monitor.lifecycle==='monitoring'?config.monitor_stop_endpoint:config.monitor_start_endpoint,response=await auth(endpoint);if(response.ok){monitor=await response.json();renderMonitor()}});$('clear-button').addEventListener('click',async()=>{if(!confirm(text('clearConfirm')))return;const response=await auth(config.monitor_clear_endpoint);if(response.ok){monitor=await response.json();renderMonitor()}});$('scan-button').addEventListener('click',async()=>{const button=$('scan-button');button.disabled=true;$('scan-status').textContent=text('scanning');try{const response=await auth(config.endpoint);if(!response.ok)throw new Error();footprint=await response.json();renderHostedLocal();renderDetails();$('scan-status').textContent=text('refreshed')}catch{$('scan-status').textContent=text('scanFailed')}finally{button.disabled=false}});$('review-payload').addEventListener('click',()=>{if(!nativeAction('open-global'))location.assign(globalUrl)});(async()=>{try{const response=await auth(config.monitor_stream_endpoint);if(!response.ok||!response.body)return;const reader=response.body.getReader(),decoder=new TextDecoder();let buffer='';while(true){const part=await reader.read();if(part.done)break;buffer+=decoder.decode(part.value,{stream:true});const lines=buffer.split('\\n');buffer=lines.pop()||'';for(const line of lines)if(line){monitor=JSON.parse(line);renderMonitor()}}}catch{}})()}
94
- function appendSystemComparison(){const view=viewForDate(monitor.activity_view,selectedDateKey),selected=(view?.systems||[]).find(system=>system.signature===selectedSystemSignature),others=(view?.systems||[]).filter(system=>system.signature!==selectedSystemSignature&&system.active_seconds>0);if(!selected||!others.length)return;const container=document.createElement('div'),label=document.createElement('label'),select=document.createElement('select'),comparison=document.createElement('div');container.className='inspector';label.className='eyebrow';label.textContent=text('compareSystems');select.className='button';for(const system of others){const option=document.createElement('option');option.value=system.signature;option.textContent=system.name;select.append(option)}comparison.className='inspector-grid';const draw=()=>{comparison.replaceChildren();const other=(view.systems||[]).find(system=>system.signature===select.value);if(!other)return;appendInspectorStat(comparison,selected.name+' · '+text('activeDuration'),seconds(selected.active_seconds));appendInspectorStat(comparison,other.name+' · '+text('activeDuration'),seconds(other.active_seconds));appendInspectorStat(comparison,selected.name+' · '+text('contribution'),Math.round(selected.share*100)+'%');appendInspectorStat(comparison,other.name+' · '+text('contribution'),Math.round(other.share*100)+'%');appendInspectorStat(comparison,selected.name+' · '+text('longestActive'),seconds(selected.longest_active_seconds));appendInspectorStat(comparison,other.name+' · '+text('longestActive'),seconds(other.longest_active_seconds))};select.addEventListener('change',draw);container.append(label,select,comparison);$('app-inspector').append(container);draw()}const currentViewBase=currentView;currentView=function(){const view=currentViewBase();if(!selectedDateKey||!view?.segments?.length)return view;const active=view.segments.filter(segment=>segment.state==='active'),longest=active.reduce((best,segment)=>!best||segment.duration_seconds>best.duration_seconds?segment:best,null);return {...view,active_block_count:active.length,longest_active_seconds:longest?.duration_seconds||0,longest_active_range:longest?{start_ms:longest.start_ms,end_ms:longest.end_ms}:null}};const activeToolNamesBase=activeToolNames;activeToolNames=function(){return selectedDateKey?(currentView()?.systems||[]).filter(system=>system.active_seconds>0).map(system=>system.name):activeToolNamesBase()};const renderInsightsBase=renderInsights;renderInsights=function(){const source=monitor.activity_view?.insights;if(!source)return renderInsightsBase();monitor.activity_view.insights=source.filter(insight=>insight.kind!=='activity-share');try{return renderInsightsBase()}finally{monitor.activity_view.insights=source}};const renderInspectorBase=renderInspector;renderInspector=function(){renderInspectorBase();appendSystemComparison()};
95
- const renderInspectorLifecycleBase=renderInspector;renderInspector=function(){renderInspectorLifecycleBase();const stateNode=document.querySelector('.inspector-state');if(stateNode&&monitor.lifecycle!=='monitoring')stateNode.textContent=text('previousObservationSaved')};
95
+ function appendSystemComparison(){const view=viewForDate(monitor.activity_view,selectedDateKey),selected=(view?.systems||[]).find(system=>system.signature===selectedSystemSignature),others=(view?.systems||[]).filter(system=>system.signature!==selectedSystemSignature&&system.active_seconds>0);if(!selected||!others.length)return;const container=document.createElement('div'),label=document.createElement('label'),select=document.createElement('select'),comparison=document.createElement('div');container.className='inspector';label.className='eyebrow';label.textContent=text('compareSystems');select.className='button';for(const system of others){const option=document.createElement('option');option.value=system.signature;option.textContent=system.name;select.append(option)}comparison.className='inspector-grid';const draw=()=>{comparison.replaceChildren();const other=(view.systems||[]).find(system=>system.signature===select.value);if(!other)return;appendInspectorStat(comparison,selected.name+' · '+text('activeDuration'),seconds(selected.active_seconds));appendInspectorStat(comparison,other.name+' · '+text('activeDuration'),seconds(other.active_seconds));appendInspectorStat(comparison,selected.name+' · '+text('contribution'),Math.round(selected.share*100)+'%');appendInspectorStat(comparison,other.name+' · '+text('contribution'),Math.round(other.share*100)+'%');appendInspectorStat(comparison,selected.name+' · '+text('longestActive'),seconds(selected.longest_active_seconds));appendInspectorStat(comparison,other.name+' · '+text('longestActive'),seconds(other.longest_active_seconds))};select.addEventListener('change',draw);container.append(label,select,comparison);$('app-inspector').append(container);draw()}const activeToolNamesBase=activeToolNames;activeToolNames=function(){return selectedDateKey?(currentView()?.systems||[]).filter(system=>system.active_seconds>0).map(system=>system.name):activeToolNamesBase()};const renderInsightsBase=renderInsights;renderInsights=function(){const source=monitor.activity_view?.insights;if(!source)return renderInsightsBase();monitor.activity_view.insights=source.filter(insight=>insight.kind!=='activity-share');try{return renderInsightsBase()}finally{monitor.activity_view.insights=source}};const renderInspectorBase=renderInspector;renderInspector=function(){renderInspectorBase();appendSystemComparison()};
96
+ const renderInspectorLifecycleBase=renderInspector;renderInspector=function(){renderInspectorLifecycleBase();const stateNode=document.querySelector('.inspector-state'),evidence=$('selected-evidence'),previous=monitor.last_observation;if(stateNode&&monitor.lifecycle!=='monitoring')stateNode.textContent=text('previousObservationSaved');if(evidence&&monitor.lifecycle==='monitoring'&&!monitor.presence?.observation_eligible&&!monitor.observed_seconds&&previous)evidence.textContent=text('lastObservation')+' · '+pct(previous.activity_ratio)+' '+text('aiActive')+' · '+(previous.active_tool||text('noApp'))+' · '+format.format(previous.local_models_found||0)+' '+text('models')+' · '+format.format(previous.local_models_running||0)+' '+text('runningShort')};
96
97
  const renderInspectorResourceBase=renderInspector;renderInspector=function(){renderInspectorResourceBase();if(!selectedSystemSignature)return;const container=$('app-inspector'),view=viewForDate(monitor.activity_view,selectedDateKey)||monitor.activity_view,system=(view?.systems||[]).find(item=>item.signature===selectedSystemSignature);if(!container||container.hidden||!system)return;const title=document.createElement('p'),grid=document.createElement('div');title.className='eyebrow';title.textContent=text('resourceHistory');grid.className='inspector-grid';appendInspectorStat(grid,text('resourceMeasuredTime'),system.resource_observed_seconds?seconds(system.resource_observed_seconds):'—');appendInspectorStat(grid,text('resourceAvgCpu'),Number.isFinite(system.avg_cpu_percent)?format.format(Number(system.avg_cpu_percent.toFixed(1)))+'%':'—');appendInspectorStat(grid,text('resourcePeakCpu'),Number.isFinite(system.peak_cpu_percent)?format.format(Number(system.peak_cpu_percent.toFixed(1)))+'%':'—');appendInspectorStat(grid,text('resourceAvgMemory'),Number.isFinite(system.avg_memory_bytes)?bytes(system.avg_memory_bytes):'—');appendInspectorStat(grid,text('resourcePeakMemory'),Number.isFinite(system.peak_memory_bytes)?bytes(system.peak_memory_bytes):'—');appendInspectorStat(grid,text('resourceSamples'),system.resource_sample_count?format.format(system.resource_sample_count):'—');container.append(title,grid)};
97
98
  function renderCenterApps(){const container=$('center-apps-list');if(!container)return;container.replaceChildren();const view=viewForDate(monitor.activity_view,selectedDateKey)||{},systems=new Map((view.systems||[]).map(system=>[system.signature,system])),live=monitor.lifecycle==='monitoring'&&(!selectedDateKey||selectedDateKey===localDateKey(monitor.activity_view?.extent?.end_ms||Date.now()));for(const product of listedProducts()){const system=systems.get(product.signature),row=document.createElement('button'),name=document.createElement('strong'),runtime=document.createElement('span'),processes=document.createElement('span'),resources=document.createElement('span'),parts=[];row.type='button';row.className='center-app-row'+(selectedSystemSignature===product.signature?' is-selected':'');row.style.setProperty('--system-color',systemColor(product.signature));name.textContent=product.name;runtime.textContent=text('activeDuration')+': '+seconds(system?.active_seconds||product.active_seconds||0);processes.textContent=format.format(product.process_count||0)+' '+text((product.process_count||0)===1?'measuredProcess':'measuredProcesses');if(live&&Number.isFinite(product.cpu_percent))parts.push(format.format(Number(product.cpu_percent.toFixed(1)))+'% '+text('cpu'));if(live&&Number.isFinite(product.memory_bytes))parts.push(bytes(product.memory_bytes)+' '+text('memory'));if(Number.isFinite(system?.avg_cpu_percent))parts.push(text('resourceAvgCpu')+' '+format.format(Number(system.avg_cpu_percent.toFixed(1)))+'%');if(Number.isFinite(system?.avg_memory_bytes))parts.push(text('resourceAvgMemory')+' '+bytes(system.avg_memory_bytes));resources.textContent=parts.join(' · ')||text('measuredCurrentOnly');row.append(name,runtime,processes,resources);row.addEventListener('click',()=>explorer.selectSystem(product.signature));container.append(row)}if(!container.children.length){const empty=document.createElement('div');empty.className='early';empty.textContent=text('noMeasuredContribution');container.append(empty)}}
98
99
  function renderResourceFootprint(){const container=$('center-resource-history');if(!container)return;const view=currentView()||{},state=view.resource_history_state||monitor.activity_view?.resource_history_state||'not-retained',visibleSignatures=new Set((view.systems||[]).map(item=>item.signature)),systems=(view.resource_history?.systems||[]).filter(item=>!visibleSignatures.size||visibleSignatures.has(item.signature));const label=resourceStatusText(state);$('resource-history-label').textContent=label;$('resource-history-note').textContent=label;container.replaceChildren();if(!systems.length){const empty=document.createElement('div');empty.className='early';empty.textContent=state==='collecting'?text('resourceCollecting'):text('resourceNotRetained');container.append(empty);return}for(const item of systems){const row=document.createElement('button'),name=document.createElement('strong'),observed=document.createElement('span'),cpu=document.createElement('span'),memory=document.createElement('span'),samples=document.createElement('span');row.type='button';row.className='resource-history-row'+(selectedSystemSignature===item.signature?' is-selected':'');row.style.setProperty('--system-color',systemColor(item.signature));name.textContent=item.name;observed.textContent=text('resourceMeasuredTime')+': '+seconds(item.observed_seconds);cpu.textContent=text('resourceAvgCpu')+': '+(Number.isFinite(item.avg_cpu_percent)?format.format(Number(item.avg_cpu_percent.toFixed(1)))+'%':'—')+' · '+text('resourcePeakCpu')+': '+(Number.isFinite(item.peak_cpu_percent)?format.format(Number(item.peak_cpu_percent.toFixed(1)))+'%':'—');memory.textContent=text('resourceAvgMemory')+': '+(Number.isFinite(item.avg_memory_bytes)?bytes(item.avg_memory_bytes):'—')+' · '+text('resourcePeakMemory')+': '+(Number.isFinite(item.peak_memory_bytes)?bytes(item.peak_memory_bytes):'—');samples.textContent=text('resourceSamples')+': '+format.format(item.sample_count||0);row.append(name,observed,cpu,memory,samples);row.addEventListener('click',()=>explorer.selectSystem(item.signature));container.append(row)}}
@@ -10,8 +10,10 @@ export interface ActivityVisualSegment {
10
10
  valid: boolean;
11
11
  system_signatures: string[];
12
12
  observation_id: number | null;
13
+ continuity_id: number | null;
13
14
  excluded_reason: null;
14
15
  is_longest_active: boolean;
16
+ active_block_id: number | null;
15
17
  }
16
18
  export interface SystemContribution {
17
19
  signature: string;
@@ -113,6 +115,7 @@ export interface ActivityExplorerViewModel {
113
115
  simultaneous_systems_max: number;
114
116
  active_tool_count: number;
115
117
  observation_ids: number[];
118
+ continuity_ids: number[];
116
119
  available_date_keys: string[];
117
120
  systems: SystemActivitySummary[];
118
121
  current_resources: CurrentAiResources;
@@ -126,6 +129,7 @@ interface NormalizedSegment {
126
129
  valid: boolean;
127
130
  system_signatures: string[];
128
131
  observation_id: number | null;
132
+ continuity_id: number | null;
129
133
  excluded_reason: null;
130
134
  }
131
135
  export declare function mergeActivitySegments(segments: NormalizedSegment[], toleranceMs: number): NormalizedSegment[];
@@ -21,7 +21,7 @@ function sameStrings(left, right) {
21
21
  function canMerge(left, right, toleranceMs) {
22
22
  return left.state === right.state
23
23
  && left.valid === right.valid
24
- && left.observation_id === right.observation_id
24
+ && left.continuity_id === right.continuity_id
25
25
  && left.excluded_reason === right.excluded_reason
26
26
  && sameStrings(left.system_signatures, right.system_signatures)
27
27
  && right.start_ms - left.end_ms <= toleranceMs;
@@ -51,6 +51,7 @@ function normalizeActivitySegments(timeline, sampleIntervalMs) {
51
51
  valid: true,
52
52
  system_signatures: [...new Set(segment.product_signatures)].sort(),
53
53
  observation_id: segment.observation_id ?? null,
54
+ continuity_id: segment.continuity_id ?? segment.observation_id ?? null,
54
55
  excluded_reason: null,
55
56
  }];
56
57
  }).sort((left, right) => left.start_ms - right.start_ms || left.end_ms - right.end_ms);
@@ -70,6 +71,7 @@ function normalizeActivitySegments(timeline, sampleIntervalMs) {
70
71
  valid: false,
71
72
  system_signatures: [],
72
73
  observation_id: null,
74
+ continuity_id: null,
73
75
  excluded_reason: null,
74
76
  });
75
77
  }
@@ -83,7 +85,7 @@ function normalizeActivitySegments(timeline, sampleIntervalMs) {
83
85
  return;
84
86
  const previous = activeBlocks.at(-1);
85
87
  const continues = previous
86
- && previous.observation_id === segment.observation_id
88
+ && previous.continuity_id === segment.continuity_id
87
89
  && segment.start_ms - previous.end_ms <= safeInterval * 3
88
90
  && merged.slice(previous.indexes.at(-1) + 1, index).every((between) => between.state === 'active');
89
91
  if (continues) {
@@ -91,15 +93,17 @@ function normalizeActivitySegments(timeline, sampleIntervalMs) {
91
93
  previous.indexes.push(index);
92
94
  }
93
95
  else
94
- activeBlocks.push({ start_ms: segment.start_ms, end_ms: segment.end_ms, indexes: [index], observation_id: segment.observation_id });
96
+ activeBlocks.push({ start_ms: segment.start_ms, end_ms: segment.end_ms, indexes: [index], continuity_id: segment.continuity_id });
95
97
  });
96
98
  const longestBlock = activeBlocks.sort((left, right) => (right.end_ms - right.start_ms) - (left.end_ms - left.start_ms))[0] ?? null;
97
99
  const longestIndexes = new Set(longestBlock?.indexes ?? []);
100
+ const activeBlockByIndex = new Map(activeBlocks.flatMap((block, blockIndex) => block.indexes.map((index) => [index, blockIndex])));
98
101
  return merged.map((segment, index) => ({
99
102
  id: `segment-${index}-${segment.start_ms}`,
100
103
  ...segment,
101
104
  duration_seconds: Math.max(0, segment.end_ms - segment.start_ms) / 1000,
102
105
  is_longest_active: longestIndexes.has(index),
106
+ active_block_id: activeBlockByIndex.get(index) ?? null,
103
107
  }));
104
108
  }
105
109
  function calculateSystemContributions(products) {
@@ -319,6 +323,7 @@ function buildActivityExplorerViewModel(snapshot, insights = []) {
319
323
  const resourceHistory = buildResourceHistoryView(snapshot.resource_history ?? []);
320
324
  const contributions = calculateSystemContributions(snapshot.products);
321
325
  const activeSegments = segments.filter((segment) => segment.state === 'active');
326
+ const activeBlockIds = new Set(activeSegments.flatMap((segment) => segment.active_block_id === null ? [] : [segment.active_block_id]));
322
327
  const longestSegments = activeSegments.filter((segment) => segment.is_longest_active);
323
328
  const longestRange = longestSegments.length
324
329
  ? { start_ms: longestSegments[0].start_ms, end_ms: longestSegments.at(-1).end_ms }
@@ -338,7 +343,7 @@ function buildActivityExplorerViewModel(snapshot, insights = []) {
338
343
  evidence: insightEvidenceTarget(insight.kind, segments, contributions),
339
344
  })),
340
345
  extent,
341
- active_block_count: activeSegments.length,
346
+ active_block_count: activeBlockIds.size,
342
347
  longest_active_seconds: longestRange ? Math.max(0, longestRange.end_ms - longestRange.start_ms) / 1000 : 0,
343
348
  longest_active_range: longestRange,
344
349
  idle_seconds: Math.max(0, snapshot.observed_seconds - snapshot.active_seconds),
@@ -346,6 +351,7 @@ function buildActivityExplorerViewModel(snapshot, insights = []) {
346
351
  simultaneous_systems_max: activeSegments.reduce((maximum, segment) => Math.max(maximum, segment.system_signatures.length), 0),
347
352
  active_tool_count: systems.filter((system) => system.active_seconds > 0 || system.state === 'working-now').length,
348
353
  observation_ids: [...new Set(segments.flatMap((segment) => segment.observation_id === null ? [] : [segment.observation_id]))].sort((left, right) => left - right),
354
+ continuity_ids: [...new Set(segments.flatMap((segment) => segment.continuity_id === null ? [] : [segment.continuity_id]))].sort((left, right) => left - right),
349
355
  available_date_keys: availableLocalDateKeys(segments),
350
356
  systems,
351
357
  current_resources: aggregateCurrentAiResources(snapshot.products),
package/dist/cli.js CHANGED
@@ -41,7 +41,7 @@ Options:
41
41
  --guess <count> Compare your estimate with discovered models
42
42
  --copy Copy the rendered local result to the clipboard
43
43
  --anonymous-payload Reserved for a completed one-hour monitor session
44
- --consent-share Separate consent; never enables upload in this build
44
+ --consent-share Prepare an aggregate payload; native-app consent controls Preview sync
45
45
  --output <file> Save the selected human or JSON report
46
46
  --model-dir <path> Inspect an explicit model directory; repeatable
47
47
  --truth <file> Evaluate locally against manually labelled macOS truth
@@ -55,9 +55,10 @@ Options:
55
55
  -h, --help Show this help
56
56
 
57
57
  Privacy:
58
- AI Footprints reads metadata only. It does not read model bytes, retain raw process
59
- commands or MCP configuration values, authenticate to Forkit.dev, or write to
60
- any passport, registry, Runtime_C2, or production service.
58
+ AI Footprints reads metadata only. It does not read model bytes or retain raw
59
+ process commands or MCP configuration values. It does not write to any passport,
60
+ registry, or Runtime_C2 service. The installed app may sync only the allowlisted anonymous
61
+ Global AI Preview aggregate after explicit v2 consent and one valid hour.
61
62
  `;
62
63
  function parseArgs(args) {
63
64
  let command = 'install';
@@ -354,7 +355,7 @@ async function main(args = process.argv.slice(2)) {
354
355
  }
355
356
  if (options.command === 'install') {
356
357
  const destination = await installPersistentMacApp();
357
- process.stdout.write(`Forkit AI Footprint is installed at ${destination}\nOpen it later from Applications or Spotlight; Terminal is no longer required.\nOn first launch, Forkit asks whether aggregate-only measurements may be prepared for global comparison. No contribution is sent unless verified collection is available.\n`);
358
+ process.stdout.write(`Forkit AI Footprint is installed at ${destination}\nOpen it later from Applications or Spotlight; Terminal is no longer required.\nOn first launch, Forkit asks whether an aggregate-only measurement may be contributed to the Global AI Preview after one valid observed hour. Nothing is sent unless the person explicitly agrees.\n`);
358
359
  return 0;
359
360
  }
360
361
  if (options.command === 'serve') {
@@ -0,0 +1,34 @@
1
+ import type { AnonymousAiFootprintContribution } from './sharing';
2
+ export declare const GLOBAL_PREVIEW_ENDPOINT = "https://www.forkit.dev/api/v1/ai-footprints";
3
+ export declare const GLOBAL_PREVIEW_SYNC_INTERVAL_MS: number;
4
+ export interface GlobalPreviewStatus {
5
+ state: 'disabled' | 'waiting' | 'syncing' | 'contributed' | 'unavailable';
6
+ last_attempt_at: string | null;
7
+ last_success_at: string | null;
8
+ last_observed_seconds: number;
9
+ last_error: string | null;
10
+ }
11
+ export interface GlobalPreviewContributorOptions {
12
+ stateDirectory?: string;
13
+ endpoint?: string;
14
+ fetchFn?: typeof fetch;
15
+ now?: () => Date;
16
+ minimumSyncIntervalMs?: number;
17
+ }
18
+ export declare class GlobalPreviewContributor {
19
+ private readonly stateDirectory;
20
+ private readonly endpoint;
21
+ private readonly fetchFn;
22
+ private readonly now;
23
+ private readonly minimumSyncIntervalMs;
24
+ private currentStatus;
25
+ private loaded;
26
+ private syncing;
27
+ constructor(options?: GlobalPreviewContributorOptions);
28
+ status(permission: 'granted' | 'declined' | 'unset'): GlobalPreviewStatus;
29
+ private loadReceipt;
30
+ private saveStatus;
31
+ sync(contribution: AnonymousAiFootprintContribution, permission: 'granted' | 'declined' | 'unset'): Promise<GlobalPreviewStatus>;
32
+ private performSync;
33
+ }
34
+ //# sourceMappingURL=global-preview.d.ts.map