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.
- package/PRIVACY.md +20 -16
- package/README.md +4 -3
- package/STATUS.md +31 -15
- package/dist/activity-page.js +14 -13
- package/dist/activity-view-model.d.ts +4 -0
- package/dist/activity-view-model.js +10 -4
- package/dist/bootstrap/Forkit AI Footprint.app.zip +0 -0
- package/dist/cli.js +6 -5
- package/dist/global-preview.d.ts +34 -0
- package/dist/global-preview.js +209 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -1
- package/dist/local-observation-state.d.ts +1 -0
- package/dist/local-observation-state.js +13 -2
- package/dist/locales.json +46 -40
- package/dist/localization.d.ts +46 -40
- package/dist/localization.js +10 -10
- package/dist/monitor.d.ts +5 -0
- package/dist/monitor.js +85 -19
- package/dist/server.d.ts +2 -0
- package/dist/server.js +68 -21
- package/dist/sharing.d.ts +1 -1
- package/dist/sharing.js +1 -1
- package/docs/GLOBAL_DISTRIBUTION.md +3 -3
- package/docs/MACOS_TESTER_GUIDE.md +6 -5
- package/package.json +1 -1
- package/release/channels.json +3 -3
package/dist/activity-page.js
CHANGED
|
@@ -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(
|
|
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:
|
|
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:
|
|
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(),
|
|
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<
|
|
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
|
|
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.
|
|
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.
|
|
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],
|
|
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:
|
|
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),
|
|
Binary file
|
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
|
|
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
|
|
59
|
-
commands or MCP configuration values
|
|
60
|
-
|
|
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
|
|
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
|