heyiam 0.2.29 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -0
- package/dist/auth.js +29 -3
- package/dist/config.js +10 -1
- package/dist/db.js +0 -1
- package/dist/export.js +124 -27
- package/dist/format-utils.js +5 -0
- package/dist/github.js +381 -0
- package/dist/index.js +168 -0
- package/dist/mount.js +300 -102
- package/dist/parsers/claude.js +2 -28
- package/dist/parsers/codex.js +2 -26
- package/dist/parsers/cursor.js +2 -26
- package/dist/parsers/duration.js +35 -0
- package/dist/parsers/gemini.js +2 -20
- package/dist/parsers/index.js +22 -3
- package/dist/parsers/types.js +0 -1
- package/dist/public/assets/index-Coilyhtr.css +1 -0
- package/dist/public/assets/index-D0noVMFu.js +44 -0
- package/dist/public/index.html +2 -2
- package/dist/redact.js +4 -104
- package/dist/render/build-render-data.js +9 -2
- package/dist/render/index.js +32 -5
- package/dist/render/liquid.js +147 -7
- package/dist/render/mock-data.js +303 -0
- package/dist/render/templates/aurora/portfolio.liquid +192 -0
- package/dist/render/templates/aurora/project.liquid +260 -0
- package/dist/render/templates/aurora/session.liquid +223 -0
- package/dist/render/templates/aurora/styles.css +1184 -0
- package/dist/render/templates/bauhaus/portfolio.liquid +169 -0
- package/dist/render/templates/bauhaus/project.liquid +300 -0
- package/dist/render/templates/bauhaus/session.liquid +333 -0
- package/dist/render/templates/bauhaus/styles.css +1645 -0
- package/dist/render/templates/blueprint/portfolio.liquid +153 -0
- package/dist/render/templates/blueprint/project.liquid +286 -0
- package/dist/render/templates/blueprint/session.liquid +248 -0
- package/dist/render/templates/blueprint/styles.css +1289 -0
- package/dist/render/templates/canvas/portfolio.liquid +203 -0
- package/dist/render/templates/canvas/project.liquid +235 -0
- package/dist/render/templates/canvas/session.liquid +223 -0
- package/dist/render/templates/canvas/styles.css +1440 -0
- package/dist/render/templates/carbon/portfolio.liquid +160 -0
- package/dist/render/templates/carbon/project.liquid +249 -0
- package/dist/render/templates/carbon/session.liquid +190 -0
- package/dist/render/templates/carbon/styles.css +1097 -0
- package/dist/render/templates/chalk/portfolio.liquid +189 -0
- package/dist/render/templates/chalk/project.liquid +245 -0
- package/dist/render/templates/chalk/session.liquid +215 -0
- package/dist/render/templates/chalk/styles.css +1161 -0
- package/dist/render/templates/circuit/portfolio.liquid +152 -0
- package/dist/render/templates/circuit/project.liquid +247 -0
- package/dist/render/templates/circuit/session.liquid +205 -0
- package/dist/render/templates/circuit/styles.css +1409 -0
- package/dist/render/templates/cosmos/portfolio.liquid +222 -0
- package/dist/render/templates/cosmos/project.liquid +327 -0
- package/dist/render/templates/cosmos/session.liquid +239 -0
- package/dist/render/templates/cosmos/styles.css +1157 -0
- package/dist/render/templates/daylight/portfolio.liquid +207 -0
- package/dist/render/templates/daylight/project.liquid +229 -0
- package/dist/render/templates/daylight/session.liquid +219 -0
- package/dist/render/templates/daylight/styles.css +1315 -0
- package/dist/render/templates/editorial/portfolio.liquid +110 -0
- package/dist/render/templates/editorial/project.liquid +202 -0
- package/dist/render/templates/editorial/session.liquid +171 -0
- package/dist/render/templates/editorial/styles.css +826 -0
- package/dist/render/templates/ember/portfolio.liquid +306 -0
- package/dist/render/templates/ember/project.liquid +232 -0
- package/dist/render/templates/ember/session.liquid +202 -0
- package/dist/render/templates/ember/styles.css +1289 -0
- package/dist/render/templates/glacier/portfolio.liquid +261 -0
- package/dist/render/templates/glacier/project.liquid +288 -0
- package/dist/render/templates/glacier/session.liquid +217 -0
- package/dist/render/templates/glacier/styles.css +1204 -0
- package/dist/render/templates/grid/portfolio.liquid +255 -0
- package/dist/render/templates/grid/project.liquid +306 -0
- package/dist/render/templates/grid/session.liquid +260 -0
- package/dist/render/templates/grid/styles.css +1445 -0
- package/dist/render/templates/kinetic/portfolio.liquid +158 -0
- package/dist/render/templates/kinetic/project.liquid +242 -0
- package/dist/render/templates/kinetic/session.liquid +228 -0
- package/dist/render/templates/kinetic/styles.css +948 -0
- package/dist/render/templates/meridian/portfolio.liquid +243 -0
- package/dist/render/templates/meridian/project.liquid +376 -0
- package/dist/render/templates/meridian/session.liquid +298 -0
- package/dist/render/templates/meridian/styles.css +1375 -0
- package/dist/render/templates/minimal/portfolio.liquid +71 -0
- package/dist/render/templates/minimal/project.liquid +154 -0
- package/dist/render/templates/minimal/session.liquid +140 -0
- package/dist/render/templates/minimal/styles.css +529 -0
- package/dist/render/templates/mono/portfolio.liquid +281 -0
- package/dist/render/templates/mono/project.liquid +275 -0
- package/dist/render/templates/mono/session.liquid +276 -0
- package/dist/render/templates/mono/styles.css +1022 -0
- package/dist/render/templates/neon/portfolio.liquid +207 -0
- package/dist/render/templates/neon/project.liquid +225 -0
- package/dist/render/templates/neon/session.liquid +195 -0
- package/dist/render/templates/neon/styles.css +1271 -0
- package/dist/render/templates/noir/portfolio.liquid +137 -0
- package/dist/render/templates/noir/project.liquid +220 -0
- package/dist/render/templates/noir/session.liquid +241 -0
- package/dist/render/templates/noir/styles.css +1229 -0
- package/dist/render/templates/obsidian/portfolio.liquid +247 -0
- package/dist/render/templates/obsidian/project.liquid +280 -0
- package/dist/render/templates/obsidian/session.liquid +241 -0
- package/dist/render/templates/obsidian/styles.css +1407 -0
- package/dist/render/templates/paper/portfolio.liquid +257 -0
- package/dist/render/templates/paper/project.liquid +235 -0
- package/dist/render/templates/paper/session.liquid +271 -0
- package/dist/render/templates/paper/styles.css +1513 -0
- package/dist/render/templates/parallax/portfolio.liquid +295 -0
- package/dist/render/templates/parallax/project.liquid +275 -0
- package/dist/render/templates/parallax/session.liquid +295 -0
- package/dist/render/templates/parallax/styles.css +1880 -0
- package/dist/render/templates/parchment/portfolio.liquid +280 -0
- package/dist/render/templates/parchment/project.liquid +289 -0
- package/dist/render/templates/parchment/session.liquid +346 -0
- package/dist/render/templates/parchment/styles.css +1401 -0
- package/dist/render/templates/partials/_beats.liquid +16 -0
- package/dist/render/templates/partials/_breadcrumb.liquid +9 -0
- package/dist/render/templates/partials/_footer.liquid +7 -0
- package/dist/render/templates/partials/_growth-chart.liquid +7 -0
- package/dist/render/templates/partials/_key-decisions.liquid +20 -0
- package/dist/render/templates/partials/_links.liquid +16 -0
- package/dist/render/templates/partials/_narrative.liquid +8 -0
- package/dist/render/templates/partials/_phases.liquid +20 -0
- package/dist/render/templates/partials/_portfolio-header.liquid +20 -0
- package/dist/render/templates/partials/_portfolio-projects.liquid +16 -0
- package/dist/render/templates/partials/_portfolio-stats.liquid +19 -0
- package/dist/render/templates/partials/_qa.liquid +13 -0
- package/dist/render/templates/partials/_screenshot.liquid +15 -0
- package/dist/render/templates/partials/_session-cards.liquid +30 -0
- package/dist/render/templates/partials/_session-header.liquid +39 -0
- package/dist/render/templates/partials/_session-sidebar.liquid +30 -0
- package/dist/render/templates/partials/_skills.liquid +12 -0
- package/dist/render/templates/partials/_source-breakdown.liquid +22 -0
- package/dist/render/templates/partials/_stats.liquid +38 -0
- package/dist/render/templates/partials/_work-timeline.liquid +7 -0
- package/dist/render/templates/project.liquid +7 -4
- package/dist/render/templates/radar/portfolio.liquid +223 -0
- package/dist/render/templates/radar/project.liquid +278 -0
- package/dist/render/templates/radar/session.liquid +300 -0
- package/dist/render/templates/radar/styles.css +1055 -0
- package/dist/render/templates/showcase/portfolio.liquid +221 -0
- package/dist/render/templates/showcase/project.liquid +237 -0
- package/dist/render/templates/showcase/session.liquid +210 -0
- package/dist/render/templates/showcase/styles.css +1284 -0
- package/dist/render/templates/signal/portfolio.liquid +217 -0
- package/dist/render/templates/signal/project.liquid +278 -0
- package/dist/render/templates/signal/session.liquid +282 -0
- package/dist/render/templates/signal/styles.css +1401 -0
- package/dist/render/templates/strata/portfolio.liquid +180 -0
- package/dist/render/templates/strata/project.liquid +282 -0
- package/dist/render/templates/strata/session.liquid +261 -0
- package/dist/render/templates/strata/styles.css +1354 -0
- package/dist/render/templates/styles.css +1190 -0
- package/dist/render/templates/terminal/portfolio.liquid +102 -0
- package/dist/render/templates/terminal/project.liquid +161 -0
- package/dist/render/templates/terminal/session.liquid +145 -0
- package/dist/render/templates/terminal/styles.css +497 -0
- package/dist/render/templates/verdant/portfolio.liquid +321 -0
- package/dist/render/templates/verdant/project.liquid +309 -0
- package/dist/render/templates/verdant/session.liquid +237 -0
- package/dist/render/templates/verdant/styles.css +1261 -0
- package/dist/render/templates/zen/portfolio.liquid +124 -0
- package/dist/render/templates/zen/project.liquid +187 -0
- package/dist/render/templates/zen/session.liquid +203 -0
- package/dist/render/templates/zen/styles.css +1211 -0
- package/dist/render/templates.js +90 -0
- package/dist/routes/auth.js +7 -3
- package/dist/routes/context.js +17 -10
- package/dist/routes/delete.js +195 -0
- package/dist/routes/enhance.js +57 -40
- package/dist/routes/export.js +14 -4
- package/dist/routes/github.js +254 -0
- package/dist/routes/index.js +2 -0
- package/dist/routes/portfolio-render-data.js +160 -0
- package/dist/routes/preview.js +555 -108
- package/dist/routes/projects.js +61 -24
- package/dist/routes/publish.js +320 -31
- package/dist/routes/settings.js +194 -1
- package/dist/routes/sse.js +9 -0
- package/dist/search.js +6 -0
- package/dist/server.js +11 -3
- package/dist/settings.js +112 -9
- package/package.json +3 -4
- package/dist/public/assets/index-CC9G8EF1.js +0 -21
- package/dist/public/assets/index-Dalqz2mC.css +0 -1
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
<div class="heyiam-portfolio circuit" data-render-version="2" data-template="circuit" data-username="{{ user.username }}">
|
|
2
|
+
|
|
3
|
+
{%- comment -%} Hero {%- endcomment -%}
|
|
4
|
+
{% if hasProfile %}
|
|
5
|
+
<section class="hero fade-in" aria-label="Profile">
|
|
6
|
+
<svg class="hero-trace" viewBox="0 0 200 200" aria-hidden="true">
|
|
7
|
+
<path d="M200 20 H160 V60 H120 V100 H80 V140 H40 V180"/>
|
|
8
|
+
<path d="M180 0 V40 H140 V80 H100"/>
|
|
9
|
+
<circle cx="200" cy="20" r="3"/>
|
|
10
|
+
<circle cx="120" cy="100" r="3"/>
|
|
11
|
+
<circle cx="40" cy="180" r="3"/>
|
|
12
|
+
<circle cx="100" cy="80" r="3"/>
|
|
13
|
+
</svg>
|
|
14
|
+
<div class="hero-profile">
|
|
15
|
+
{% if user.photoUrl %}
|
|
16
|
+
<div class="hero-photo-wrap">
|
|
17
|
+
<img src="{{ user.photoUrl }}" alt="{{ user.displayName }}" class="hero-photo" width="120" height="150" data-portfolio-field="photoBase64"{% unless user.photoUrl %} data-portfolio-empty="true"{% endunless %}>
|
|
18
|
+
<span class="pad-bl" aria-hidden="true"></span>
|
|
19
|
+
<span class="pad-br" aria-hidden="true"></span>
|
|
20
|
+
</div>
|
|
21
|
+
{% endif %}
|
|
22
|
+
<div class="hero-info">
|
|
23
|
+
{% if user.displayName != blank %}
|
|
24
|
+
<h1 data-portfolio-field="displayName">{{ user.displayName }}</h1>
|
|
25
|
+
{% endif %}
|
|
26
|
+
{% if user.bio %}
|
|
27
|
+
<p class="hero-bio" data-portfolio-field="bio">{{ user.bio }}</p>
|
|
28
|
+
{% endif %}
|
|
29
|
+
{% if user.location %}
|
|
30
|
+
<p class="hero-location" data-portfolio-field="location">{{ user.location }}</p>
|
|
31
|
+
{% endif %}
|
|
32
|
+
<ul class="hero-contact" aria-label="Contact and social links">
|
|
33
|
+
<li data-portfolio-field="email"{% unless user.email %} data-portfolio-empty="true"{% endunless %}><a href="{% if user.email %}mailto:{{ user.email }}{% endif %}"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m2 4 10 8 10-8"/></svg>{{ user.email }}</a></li>
|
|
34
|
+
<li data-portfolio-field="linkedinUrl"{% unless user.linkedinUrl %} data-portfolio-empty="true"{% endunless %}><a href="{% if user.linkedinUrl %}{{ user.linkedinUrl }}{% endif %}" target="_blank" rel="noopener"><svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M20.5 2h-17A1.5 1.5 0 002 3.5v17A1.5 1.5 0 003.5 22h17a1.5 1.5 0 001.5-1.5v-17A1.5 1.5 0 0020.5 2zM8 19H5v-9h3zM6.5 8.25A1.75 1.75 0 118.3 6.5a1.78 1.78 0 01-1.8 1.75zM19 19h-3v-4.74c0-1.42-.6-1.93-1.38-1.93A1.74 1.74 0 0013 14.19V19h-3v-9h2.9v1.3a3.11 3.11 0 012.7-1.4c1.55 0 3.36.86 3.36 3.66z"/></svg>LinkedIn</a></li>
|
|
35
|
+
<li data-portfolio-field="githubUrl"{% unless user.githubUrl %} data-portfolio-empty="true"{% endunless %}><a href="{% if user.githubUrl %}{{ user.githubUrl }}{% endif %}" target="_blank" rel="noopener"><svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"/></svg>GitHub</a></li>
|
|
36
|
+
<li data-portfolio-field="twitterHandle"{% unless user.twitterHandle %} data-portfolio-empty="true"{% endunless %}><a href="{% if user.twitterHandle %}https://x.com/{{ user.twitterHandle }}{% endif %}" target="_blank" rel="noopener"><svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>@{{ user.twitterHandle }}</a></li>
|
|
37
|
+
<li data-portfolio-field="websiteUrl"{% unless user.websiteUrl %} data-portfolio-empty="true"{% endunless %}><a href="{% if user.websiteUrl %}{{ user.websiteUrl }}{% endif %}" target="_blank" rel="noopener"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z"/><circle cx="12" cy="9" r="2.5"/></svg>{{ user.websiteUrl | stripProtocol }}</a></li>
|
|
38
|
+
</ul>
|
|
39
|
+
{% if user.resumeUrl %}
|
|
40
|
+
<a href="{{ user.resumeUrl }}" class="hero-resume"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="12" y1="18" x2="12" y2="12"/><polyline points="9 15 12 18 15 15"/></svg>Download Resume</a>
|
|
41
|
+
{% endif %}
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</section>
|
|
45
|
+
{% endif %}
|
|
46
|
+
|
|
47
|
+
{%- comment -%} Stats {%- endcomment -%}
|
|
48
|
+
<section class="stat-chips fade-in" aria-label="Aggregate statistics">
|
|
49
|
+
<div class="stat-chip" role="group" aria-label="Projects">
|
|
50
|
+
<span class="stat-chip-value">{{ projects.size }}</span>
|
|
51
|
+
<span class="stat-chip-label">Projects</span>
|
|
52
|
+
</div>
|
|
53
|
+
<div class="stat-chip" role="group" aria-label="Sessions">
|
|
54
|
+
<span class="stat-chip-value">{{ totalSessions }}</span>
|
|
55
|
+
<span class="stat-chip-label">Sessions</span>
|
|
56
|
+
</div>
|
|
57
|
+
{% if efficiencyMultiplier %}
|
|
58
|
+
<div class="stat-chip stat-chip--leverage" role="group" aria-label="{{ totalDurationMinutes | formatDuration }} you, {{ totalAgentDurationMinutes | formatDuration }} agents, {{ efficiencyMultiplier }} leverage">
|
|
59
|
+
<div class="leverage-row">
|
|
60
|
+
<span><span class="lev-val">{{ totalDurationMinutes | formatDuration }}</span> <span class="lev-lbl">you</span></span>
|
|
61
|
+
<span><span class="lev-val lev-val--agent">{{ totalAgentDurationMinutes | formatDuration }}</span> <span class="lev-lbl">agents</span></span>
|
|
62
|
+
<span><span class="lev-val lev-val--multi">{{ efficiencyMultiplier }}</span></span>
|
|
63
|
+
</div>
|
|
64
|
+
{% assign totalCombined = totalDurationMinutes | plus: totalAgentDurationMinutes %}
|
|
65
|
+
{% if totalCombined > 0 %}
|
|
66
|
+
{% assign humanPct = totalDurationMinutes | times: 100 | divided_by: totalCombined | round %}
|
|
67
|
+
{% assign agentPct = 100 | minus: humanPct %}
|
|
68
|
+
<div class="circuit-leverage-bar">
|
|
69
|
+
<div class="circuit-leverage-bar__human" style="width: {{ humanPct }}%"></div>
|
|
70
|
+
<div class="circuit-leverage-bar__agent" style="width: {{ agentPct }}%"></div>
|
|
71
|
+
</div>
|
|
72
|
+
{% endif %}
|
|
73
|
+
</div>
|
|
74
|
+
{% else %}
|
|
75
|
+
<div class="stat-chip" role="group" aria-label="Time">
|
|
76
|
+
<span class="stat-chip-value">{{ totalDurationMinutes | formatDuration }}</span>
|
|
77
|
+
<span class="stat-chip-label">Time</span>
|
|
78
|
+
</div>
|
|
79
|
+
{% endif %}
|
|
80
|
+
<div class="stat-chip" role="group" aria-label="Lines changed">
|
|
81
|
+
<span class="stat-chip-value">{{ totalLoc | formatLoc }}</span>
|
|
82
|
+
<span class="stat-chip-label">Lines Changed</span>
|
|
83
|
+
</div>
|
|
84
|
+
</section>
|
|
85
|
+
|
|
86
|
+
<div class="trace-connector" aria-hidden="true"></div>
|
|
87
|
+
|
|
88
|
+
{%- comment -%} Source Overview {%- endcomment -%}
|
|
89
|
+
{% if sourceCounts.size > 0 %}
|
|
90
|
+
<section class="fade-in" aria-label="Source overview" style="margin-bottom: 24px;">
|
|
91
|
+
<div class="source-overview">
|
|
92
|
+
<h3>Source Overview</h3>
|
|
93
|
+
{% for src in sourceCounts %}
|
|
94
|
+
{% assign srcPct = src.count | times: 100.0 | divided_by: totalSourceSessions | round %}
|
|
95
|
+
<div class="source-overview-row">
|
|
96
|
+
<span class="source-overview-name">{{ src.tool }}</span>
|
|
97
|
+
<div class="source-overview-bar">
|
|
98
|
+
<div class="source-overview-fill {% if forloop.first %}claude{% else %}cursor-fill{% endif %}" style="width: {{ srcPct }}%"></div>
|
|
99
|
+
</div>
|
|
100
|
+
<span class="source-overview-pct">{{ srcPct }}%</span>
|
|
101
|
+
</div>
|
|
102
|
+
{% endfor %}
|
|
103
|
+
</div>
|
|
104
|
+
</section>
|
|
105
|
+
{% endif %}
|
|
106
|
+
|
|
107
|
+
{%- comment -%} Aggregate Skills {%- endcomment -%}
|
|
108
|
+
{% if allSkills.size > 0 %}
|
|
109
|
+
<section class="all-skills-section fade-in" aria-label="All skills">
|
|
110
|
+
<h2 class="section-header">Skills</h2>
|
|
111
|
+
<div class="all-skills-grid">
|
|
112
|
+
{% for skill in allSkills %}
|
|
113
|
+
<div class="skill-ic"><span class="skill-ic-dot"></span> {{ skill.name }} <span class="skill-ic-count">{{ skill.projectCount }}</span></div>
|
|
114
|
+
{% endfor %}
|
|
115
|
+
</div>
|
|
116
|
+
</section>
|
|
117
|
+
{% endif %}
|
|
118
|
+
|
|
119
|
+
{%- comment -%} Projects {%- endcomment -%}
|
|
120
|
+
{% if projects.size > 0 %}
|
|
121
|
+
<section class="fade-in" aria-label="Projects" style="padding-bottom: 64px;">
|
|
122
|
+
<h2 class="section-header">Projects</h2>
|
|
123
|
+
<div class="projects-grid">
|
|
124
|
+
{% for p in projects %}
|
|
125
|
+
<article class="project-card pad-corner">
|
|
126
|
+
<div class="project-card-header">
|
|
127
|
+
<h3><a href="/{{ user.username }}/{{ p.slug }}">{{ p.title }}</a></h3>
|
|
128
|
+
</div>
|
|
129
|
+
{% if p.narrative %}
|
|
130
|
+
<p class="project-card-narrative">{{ p.narrative }}</p>
|
|
131
|
+
{% endif %}
|
|
132
|
+
<div class="project-card-stats">
|
|
133
|
+
<span><span class="val">{{ p.totalSessions }}</span> sessions</span>
|
|
134
|
+
<span><span class="val">{{ p.totalDurationMinutes | formatDuration }}</span></span>
|
|
135
|
+
<span><span class="val">{{ p.totalLoc | formatLoc }}</span> LOC</span>
|
|
136
|
+
</div>
|
|
137
|
+
{% if p.skills.size > 0 %}
|
|
138
|
+
<div class="skill-pins">
|
|
139
|
+
{% for skill in p.skills %}
|
|
140
|
+
<span class="skill-pin">{{ skill }}</span>
|
|
141
|
+
{% endfor %}
|
|
142
|
+
</div>
|
|
143
|
+
{% endif %}
|
|
144
|
+
</article>
|
|
145
|
+
{% endfor %}
|
|
146
|
+
</div>
|
|
147
|
+
</section>
|
|
148
|
+
{% endif %}
|
|
149
|
+
|
|
150
|
+
{%- comment -%} Fade-in animation script {%- endcomment -%}
|
|
151
|
+
|
|
152
|
+
</div>
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
<div class="heyiam-project circuit" data-render-version="2" data-template="circuit"{% if sessionBaseUrl %} data-session-base-url="{{ sessionBaseUrl }}"{% endif %} data-username="{{ user.username }}" data-project-slug="{{ project.slug }}">
|
|
2
|
+
|
|
3
|
+
{%- comment -%} Breadcrumb {%- endcomment -%}
|
|
4
|
+
<div class="breadcrumb" aria-label="Breadcrumb">
|
|
5
|
+
<a href="/{{ user.username }}">{{ user.username }}</a>
|
|
6
|
+
<span class="sep">/</span>
|
|
7
|
+
<span aria-current="page">{{ project.slug }}</span>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
{%- comment -%} Hero {%- endcomment -%}
|
|
11
|
+
<section class="hero fade-in" aria-label="Project header">
|
|
12
|
+
<h1 data-editable="title">{{ project.title }}</h1>
|
|
13
|
+
{% if project.repoUrl or project.projectUrl %}
|
|
14
|
+
<div class="hero-links">
|
|
15
|
+
{% if project.repoUrl %}
|
|
16
|
+
<a href="{{ project.repoUrl }}" target="_blank" rel="noopener">{{ project.repoUrl | stripProtocol }}</a>
|
|
17
|
+
{% endif %}
|
|
18
|
+
{% if project.projectUrl %}
|
|
19
|
+
<a href="{{ project.projectUrl }}" target="_blank" rel="noopener">{{ project.projectUrl | stripProtocol }}</a>
|
|
20
|
+
{% endif %}
|
|
21
|
+
</div>
|
|
22
|
+
{% endif %}
|
|
23
|
+
</section>
|
|
24
|
+
|
|
25
|
+
{%- comment -%} Screenshot {%- endcomment -%}
|
|
26
|
+
{% if project.screenshotUrl %}
|
|
27
|
+
<div class="screenshot fade-in" role="img" aria-label="{{ project.title }} screenshot">
|
|
28
|
+
<div class="screenshot-chrome" aria-hidden="true">
|
|
29
|
+
<span class="screenshot-dot"></span>
|
|
30
|
+
<span class="screenshot-dot"></span>
|
|
31
|
+
<span class="screenshot-dot"></span>
|
|
32
|
+
</div>
|
|
33
|
+
<img src="{{ project.screenshotUrl }}" alt="{{ project.title }}" style="width: 100%; height: 100%; object-fit: cover;">
|
|
34
|
+
</div>
|
|
35
|
+
{% endif %}
|
|
36
|
+
|
|
37
|
+
{%- comment -%} Stats {%- endcomment -%}
|
|
38
|
+
<section class="stat-chips fade-in" aria-label="Project statistics">
|
|
39
|
+
<div class="stat-chip" role="group" aria-label="Sessions">
|
|
40
|
+
<span class="stat-chip-value">{{ project.totalSessions }}</span>
|
|
41
|
+
<span class="stat-chip-label">Sessions</span>
|
|
42
|
+
</div>
|
|
43
|
+
{% if efficiencyMultiplier %}
|
|
44
|
+
<div class="stat-chip stat-chip--leverage" role="group" aria-label="{{ project.totalDurationMinutes | formatDuration }} you, {{ project.totalAgentDurationMinutes | formatDuration }} agents, {{ efficiencyMultiplier }} leverage">
|
|
45
|
+
<div class="leverage-row">
|
|
46
|
+
<span><span class="lev-val">{{ project.totalDurationMinutes | formatDuration }}</span> <span class="lev-lbl">you</span></span>
|
|
47
|
+
<span><span class="lev-val lev-val--agent">{{ project.totalAgentDurationMinutes | formatDuration }}</span> <span class="lev-lbl">agents</span></span>
|
|
48
|
+
<span><span class="lev-val lev-val--multi">{{ efficiencyMultiplier }}</span></span>
|
|
49
|
+
</div>
|
|
50
|
+
{% assign totalCombined = project.totalDurationMinutes | plus: project.totalAgentDurationMinutes %}
|
|
51
|
+
{% if totalCombined > 0 %}
|
|
52
|
+
{% assign humanPct = project.totalDurationMinutes | times: 100 | divided_by: totalCombined | round %}
|
|
53
|
+
{% assign agentPct = 100 | minus: humanPct %}
|
|
54
|
+
<div class="circuit-leverage-bar">
|
|
55
|
+
<div class="circuit-leverage-bar__human" style="width: {{ humanPct }}%"></div>
|
|
56
|
+
<div class="circuit-leverage-bar__agent" style="width: {{ agentPct }}%"></div>
|
|
57
|
+
</div>
|
|
58
|
+
{% endif %}
|
|
59
|
+
</div>
|
|
60
|
+
{% else %}
|
|
61
|
+
<div class="stat-chip" role="group" aria-label="Time">
|
|
62
|
+
<span class="stat-chip-value">{{ project.totalDurationMinutes | formatDuration }}</span>
|
|
63
|
+
<span class="stat-chip-label">Time</span>
|
|
64
|
+
</div>
|
|
65
|
+
{% endif %}
|
|
66
|
+
<div class="stat-chip" role="group" aria-label="Lines of code">
|
|
67
|
+
<span class="stat-chip-value">{{ project.totalLoc | formatLoc }}</span>
|
|
68
|
+
<span class="stat-chip-label">LOC</span>
|
|
69
|
+
</div>
|
|
70
|
+
<div class="stat-chip" role="group" aria-label="Files">
|
|
71
|
+
<span class="stat-chip-value">{{ project.totalFilesChanged }}</span>
|
|
72
|
+
<span class="stat-chip-label">Files</span>
|
|
73
|
+
</div>
|
|
74
|
+
{% if project.totalTokens %}
|
|
75
|
+
<div class="stat-chip" role="group" aria-label="Tokens">
|
|
76
|
+
<span class="stat-chip-value">{{ project.totalTokens | formatTokens }}</span>
|
|
77
|
+
<span class="stat-chip-label">Tokens</span>
|
|
78
|
+
</div>
|
|
79
|
+
{% endif %}
|
|
80
|
+
</section>
|
|
81
|
+
|
|
82
|
+
<div class="trace-connector" aria-hidden="true"></div>
|
|
83
|
+
|
|
84
|
+
{%- comment -%} Narrative {%- endcomment -%}
|
|
85
|
+
{% if project.narrative %}
|
|
86
|
+
<section class="narrative fade-in" aria-label="Project narrative">
|
|
87
|
+
<h2 class="section-header">Narrative</h2>
|
|
88
|
+
<p>{{ project.narrative }}</p>
|
|
89
|
+
</section>
|
|
90
|
+
|
|
91
|
+
<div class="trace-connector" aria-hidden="true"></div>
|
|
92
|
+
{% endif %}
|
|
93
|
+
|
|
94
|
+
{%- comment -%} Skills {%- endcomment -%}
|
|
95
|
+
{% if project.skills.size > 0 %}
|
|
96
|
+
<section class="fade-in" aria-label="Technologies used">
|
|
97
|
+
<h2 class="section-header">Skills</h2>
|
|
98
|
+
<div class="skill-pins">
|
|
99
|
+
{% for skill in project.skills %}
|
|
100
|
+
<span class="skill-pin">{{ skill }}</span>
|
|
101
|
+
{% endfor %}
|
|
102
|
+
</div>
|
|
103
|
+
</section>
|
|
104
|
+
|
|
105
|
+
<div class="trace-connector" aria-hidden="true"></div>
|
|
106
|
+
{% endif %}
|
|
107
|
+
|
|
108
|
+
{%- comment -%} Key Decisions {%- endcomment -%}
|
|
109
|
+
{% if arc.size > 0 %}
|
|
110
|
+
<section class="decisions fade-in" aria-label="Key decisions">
|
|
111
|
+
<h2 class="section-header">Key Decisions</h2>
|
|
112
|
+
{% for item in arc %}
|
|
113
|
+
<div class="decision-item">
|
|
114
|
+
<span class="decision-number">{{ item.phase | prepend: '0' | slice: -2, 2 }}</span>
|
|
115
|
+
{{ item.description }}
|
|
116
|
+
</div>
|
|
117
|
+
{% endfor %}
|
|
118
|
+
</section>
|
|
119
|
+
|
|
120
|
+
<div class="trace-connector" aria-hidden="true"></div>
|
|
121
|
+
{% endif %}
|
|
122
|
+
|
|
123
|
+
{%- comment -%} Phases {%- endcomment -%}
|
|
124
|
+
{% if arc.size > 0 %}
|
|
125
|
+
<section class="fade-in" aria-label="Project phases">
|
|
126
|
+
<h2 class="section-header">Phases</h2>
|
|
127
|
+
<div class="phase-bus" role="list">
|
|
128
|
+
{% for item in arc %}
|
|
129
|
+
<div class="phase-item" role="listitem">
|
|
130
|
+
<div class="phase-label"><span class="phase-num">{{ item.phase | prepend: '0' | slice: -2, 2 }}</span> {{ item.title }}</div>
|
|
131
|
+
{% if item.dates %}
|
|
132
|
+
<div class="phase-dates">{{ item.dates }}</div>
|
|
133
|
+
{% endif %}
|
|
134
|
+
<div class="phase-desc">{{ item.description }}</div>
|
|
135
|
+
</div>
|
|
136
|
+
{% endfor %}
|
|
137
|
+
</div>
|
|
138
|
+
</section>
|
|
139
|
+
|
|
140
|
+
<div class="trace-connector" aria-hidden="true"></div>
|
|
141
|
+
{% endif %}
|
|
142
|
+
|
|
143
|
+
{%- comment -%} Source Breakdown {%- endcomment -%}
|
|
144
|
+
{% if sourceCounts.size > 0 %}
|
|
145
|
+
<section class="source-section fade-in" aria-label="Source breakdown">
|
|
146
|
+
<h2 class="section-header">Source Breakdown</h2>
|
|
147
|
+
<div class="source-bar-container">
|
|
148
|
+
{% assign totalSourceSessions = 0 %}
|
|
149
|
+
{% for src in sourceCounts %}
|
|
150
|
+
{% assign totalSourceSessions = totalSourceSessions | plus: src.count %}
|
|
151
|
+
{% endfor %}
|
|
152
|
+
{% if totalSourceSessions > 0 %}
|
|
153
|
+
<div class="source-bar-label">
|
|
154
|
+
{% for src in sourceCounts %}
|
|
155
|
+
{% assign srcPct = src.count | times: 100.0 | divided_by: totalSourceSessions | round %}
|
|
156
|
+
<span>{{ src.tool }} — {{ srcPct }}% ({{ src.count }} sessions)</span>
|
|
157
|
+
{% endfor %}
|
|
158
|
+
</div>
|
|
159
|
+
<div class="source-bar" role="img" aria-label="Source breakdown">
|
|
160
|
+
{% for src in sourceCounts %}
|
|
161
|
+
{% assign srcPct = src.count | times: 100.0 | divided_by: totalSourceSessions | round %}
|
|
162
|
+
<div class="source-bar-fill{% unless forloop.first %} cursor{% endunless %}" style="width: {{ srcPct }}%"></div>
|
|
163
|
+
{% endfor %}
|
|
164
|
+
</div>
|
|
165
|
+
{% endif %}
|
|
166
|
+
</div>
|
|
167
|
+
</section>
|
|
168
|
+
|
|
169
|
+
<div class="trace-connector" aria-hidden="true"></div>
|
|
170
|
+
{% endif %}
|
|
171
|
+
|
|
172
|
+
{%- comment -%} Session Table (replaces JS Work Timeline) {%- endcomment -%}
|
|
173
|
+
{% if featuredSessions.size > 0 %}
|
|
174
|
+
<section class="fade-in" aria-label="Session timeline">
|
|
175
|
+
<h2 class="section-header">Sessions</h2>
|
|
176
|
+
<div class="session-table-wrapper">
|
|
177
|
+
<table class="session-table">
|
|
178
|
+
<thead>
|
|
179
|
+
<tr>
|
|
180
|
+
<th scope="col">#</th>
|
|
181
|
+
<th scope="col">Title</th>
|
|
182
|
+
<th scope="col">Date</th>
|
|
183
|
+
<th scope="col">Duration</th>
|
|
184
|
+
<th scope="col">LOC</th>
|
|
185
|
+
<th scope="col">Source</th>
|
|
186
|
+
<th scope="col">Agents</th>
|
|
187
|
+
</tr>
|
|
188
|
+
</thead>
|
|
189
|
+
<tbody>
|
|
190
|
+
{% assign agent_colors = '#0891b2,#059669,#7c3aed,#475569,#e11d48,#d97706' | split: ',' %}
|
|
191
|
+
{% for s in featuredSessions %}
|
|
192
|
+
<tr>
|
|
193
|
+
<td class="num">{{ forloop.index }}</td>
|
|
194
|
+
<td class="title-cell"><a href="{{ sessionBaseUrl }}/{{ s.slug }}{{ sessionSuffix }}">{{ s.title }}</a></td>
|
|
195
|
+
<td class="mono">{% if s.recordedAt %}{{ s.recordedAt | formatDate }}{% endif %}</td>
|
|
196
|
+
<td class="mono">{{ s.durationMinutes | formatDuration }}</td>
|
|
197
|
+
<td class="mono">{{ s.locChanged | localeNumber }}</td>
|
|
198
|
+
<td class="mono">{% if s.sourceTool %}{{ s.sourceTool }}{% endif %}</td>
|
|
199
|
+
<td>
|
|
200
|
+
{% if s.agentSummary and s.agentSummary.agents.size > 0 %}
|
|
201
|
+
<div class="agent-dots" aria-label="{{ s.agentSummary.agents.size }} agents">
|
|
202
|
+
{% for agent in s.agentSummary.agents %}
|
|
203
|
+
{% assign colorIdx = forloop.index0 | modulo: 6 %}
|
|
204
|
+
<span class="agent-dot" style="background:{{ agent_colors[colorIdx] }}" title="{{ agent.role }}"></span>
|
|
205
|
+
{% endfor %}
|
|
206
|
+
</div>
|
|
207
|
+
{% else %}
|
|
208
|
+
<span class="mono" style="font-size:11px;color:var(--fg-muted)">—</span>
|
|
209
|
+
{% endif %}
|
|
210
|
+
</td>
|
|
211
|
+
</tr>
|
|
212
|
+
{% endfor %}
|
|
213
|
+
</tbody>
|
|
214
|
+
</table>
|
|
215
|
+
</div>
|
|
216
|
+
</section>
|
|
217
|
+
|
|
218
|
+
<div class="trace-connector" aria-hidden="true"></div>
|
|
219
|
+
{% endif %}
|
|
220
|
+
|
|
221
|
+
{%- comment -%} Featured Sessions {%- endcomment -%}
|
|
222
|
+
{% if featuredSessions.size > 0 %}
|
|
223
|
+
<section class="fade-in" aria-label="Featured sessions" style="padding-bottom: 64px;">
|
|
224
|
+
<h2 class="section-header">Featured Sessions</h2>
|
|
225
|
+
<div class="featured-grid">
|
|
226
|
+
{% for s in featuredSessions %}
|
|
227
|
+
<article class="featured-card">
|
|
228
|
+
{% if s.skills.size > 0 %}
|
|
229
|
+
<span class="featured-card-tag">{{ s.skills | first }}</span>
|
|
230
|
+
{% endif %}
|
|
231
|
+
<h4><a href="{{ sessionBaseUrl }}/{{ s.slug }}{{ sessionSuffix }}">{{ s.title }}</a></h4>
|
|
232
|
+
<div class="featured-card-stats">
|
|
233
|
+
<span><span class="val">{{ s.durationMinutes | formatDuration }}</span></span>
|
|
234
|
+
<span><span class="val">{{ s.locChanged | localeNumber }}</span> LOC</span>
|
|
235
|
+
{% if s.agentSummary %}
|
|
236
|
+
<span><span class="val">{{ s.agentSummary.agents.size }}</span> agents</span>
|
|
237
|
+
{% endif %}
|
|
238
|
+
</div>
|
|
239
|
+
</article>
|
|
240
|
+
{% endfor %}
|
|
241
|
+
</div>
|
|
242
|
+
</section>
|
|
243
|
+
{% endif %}
|
|
244
|
+
|
|
245
|
+
{%- comment -%} Fade-in animation script {%- endcomment -%}
|
|
246
|
+
|
|
247
|
+
</div>
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
<div class="heyiam-session circuit" data-render-version="2" data-template="circuit">
|
|
2
|
+
|
|
3
|
+
{%- comment -%} Breadcrumb {%- endcomment -%}
|
|
4
|
+
<div class="breadcrumb" aria-label="Breadcrumb">
|
|
5
|
+
<a href="/{{ user.username }}">{{ user.username }}</a>
|
|
6
|
+
{% if projectSlug %}
|
|
7
|
+
<span class="sep">/</span>
|
|
8
|
+
<a href="/{{ user.username }}/{{ projectSlug }}">{{ projectSlug }}</a>
|
|
9
|
+
{% endif %}
|
|
10
|
+
<span class="sep">/</span>
|
|
11
|
+
<span aria-current="page">{{ session.title }}</span>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
{%- comment -%} Hero {%- endcomment -%}
|
|
15
|
+
<section class="hero fade-in" aria-label="Session header">
|
|
16
|
+
<h1>{{ session.title }}</h1>
|
|
17
|
+
<div class="hero-meta">
|
|
18
|
+
{% if session.recordedAt %}
|
|
19
|
+
<span>Date: <span class="val">{{ session.recordedAt | formatDate }}</span></span>
|
|
20
|
+
{% endif %}
|
|
21
|
+
{% if session.sourceTool %}
|
|
22
|
+
<span>Source: <span class="val">{{ session.sourceTool }}</span></span>
|
|
23
|
+
{% endif %}
|
|
24
|
+
<span>Duration: <span class="val">{{ session.durationMinutes | formatDuration }}</span>{% if session.wallClockMinutes %} ({{ session.wallClockMinutes | formatDuration }} wall){% endif %}</span>
|
|
25
|
+
<span>Turns: <span class="val">{{ session.turns }}</span></span>
|
|
26
|
+
<span>LOC: <span class="val">{{ session.locChanged | localeNumber }}</span></span>
|
|
27
|
+
<span>Files: <span class="val">{{ session.filesChanged }}</span></span>
|
|
28
|
+
</div>
|
|
29
|
+
</section>
|
|
30
|
+
|
|
31
|
+
{%- comment -%} Dev Take {%- endcomment -%}
|
|
32
|
+
{% if session.devTake %}
|
|
33
|
+
<div class="dev-take fade-in">
|
|
34
|
+
<span class="dev-take-label">Dev Take</span>
|
|
35
|
+
<p>{{ session.devTake }}</p>
|
|
36
|
+
</div>
|
|
37
|
+
{% endif %}
|
|
38
|
+
|
|
39
|
+
{%- comment -%} Stats {%- endcomment -%}
|
|
40
|
+
<section class="stat-chips fade-in" aria-label="Session statistics">
|
|
41
|
+
<div class="stat-chip" role="group" aria-label="Duration">
|
|
42
|
+
<span class="stat-chip-value">{{ session.durationMinutes | formatDuration }}</span>
|
|
43
|
+
<span class="stat-chip-label">Duration</span>
|
|
44
|
+
</div>
|
|
45
|
+
{% if session.wallClockMinutes %}
|
|
46
|
+
<div class="stat-chip" role="group" aria-label="Wall clock">
|
|
47
|
+
<span class="stat-chip-value">{{ session.wallClockMinutes | formatDuration }}</span>
|
|
48
|
+
<span class="stat-chip-label">Wall Clock</span>
|
|
49
|
+
</div>
|
|
50
|
+
{% endif %}
|
|
51
|
+
<div class="stat-chip" role="group" aria-label="Turns">
|
|
52
|
+
<span class="stat-chip-value">{{ session.turns }}</span>
|
|
53
|
+
<span class="stat-chip-label">Turns</span>
|
|
54
|
+
</div>
|
|
55
|
+
<div class="stat-chip" role="group" aria-label="Lines of code">
|
|
56
|
+
<span class="stat-chip-value">{{ session.locChanged | localeNumber }}</span>
|
|
57
|
+
<span class="stat-chip-label">LOC</span>
|
|
58
|
+
</div>
|
|
59
|
+
<div class="stat-chip" role="group" aria-label="Files changed">
|
|
60
|
+
<span class="stat-chip-value">{{ session.filesChanged }}</span>
|
|
61
|
+
<span class="stat-chip-label">Files</span>
|
|
62
|
+
</div>
|
|
63
|
+
</section>
|
|
64
|
+
|
|
65
|
+
<div class="trace-connector" aria-hidden="true"></div>
|
|
66
|
+
|
|
67
|
+
<div class="layout-two-col">
|
|
68
|
+
<div>
|
|
69
|
+
{%- comment -%} Execution Path (Beats) {%- endcomment -%}
|
|
70
|
+
{% if session.beats.size > 0 %}
|
|
71
|
+
<section class="beats fade-in" aria-label="Execution path">
|
|
72
|
+
<h2 class="section-header">Execution Path</h2>
|
|
73
|
+
<div class="beat-list" role="list">
|
|
74
|
+
{% for beat in session.beats %}
|
|
75
|
+
<div class="beat-item" role="listitem">
|
|
76
|
+
<div class="beat-title"><span class="beat-num">{{ beat.stepNumber | prepend: '0' | slice: -2, 2 }}</span> {{ beat.title }}</div>
|
|
77
|
+
<p class="beat-desc">{{ beat.body }}</p>
|
|
78
|
+
</div>
|
|
79
|
+
{% endfor %}
|
|
80
|
+
</div>
|
|
81
|
+
</section>
|
|
82
|
+
|
|
83
|
+
<div class="trace-connector" aria-hidden="true"></div>
|
|
84
|
+
{% endif %}
|
|
85
|
+
|
|
86
|
+
{%- comment -%} Q&A {%- endcomment -%}
|
|
87
|
+
{% if session.qaPairs.size > 0 %}
|
|
88
|
+
<section class="qa-section fade-in" aria-label="Questions and answers">
|
|
89
|
+
<h2 class="section-header">Q&A</h2>
|
|
90
|
+
{% for qa in session.qaPairs %}
|
|
91
|
+
<div class="qa-item">
|
|
92
|
+
<p class="qa-question">{{ qa.question }}</p>
|
|
93
|
+
<p class="qa-answer">{{ qa.answer }}</p>
|
|
94
|
+
</div>
|
|
95
|
+
{% endfor %}
|
|
96
|
+
</section>
|
|
97
|
+
|
|
98
|
+
<div class="trace-connector" aria-hidden="true"></div>
|
|
99
|
+
{% endif %}
|
|
100
|
+
|
|
101
|
+
{%- comment -%} Narrative {%- endcomment -%}
|
|
102
|
+
{% if session.narrative %}
|
|
103
|
+
<section class="fade-in" aria-label="Session narrative">
|
|
104
|
+
<h2 class="section-header">Narrative</h2>
|
|
105
|
+
<p style="font-size: 15px; color: var(--fg); line-height: 1.75;">{{ session.narrative }}</p>
|
|
106
|
+
</section>
|
|
107
|
+
|
|
108
|
+
<div class="trace-connector" aria-hidden="true"></div>
|
|
109
|
+
{% endif %}
|
|
110
|
+
|
|
111
|
+
{%- comment -%} Highlights {%- endcomment -%}
|
|
112
|
+
{% if session.highlights.size > 0 %}
|
|
113
|
+
<section class="fade-in" aria-label="Session highlights">
|
|
114
|
+
<h2 class="section-header">Highlights</h2>
|
|
115
|
+
<ul style="list-style: none; padding: 0;">
|
|
116
|
+
{% for h in session.highlights %}
|
|
117
|
+
<li style="font-size: 14px; color: var(--fg-muted); line-height: 1.7; padding: 6px 0; border-bottom: 1px solid var(--border);">{{ h }}</li>
|
|
118
|
+
{% endfor %}
|
|
119
|
+
</ul>
|
|
120
|
+
</section>
|
|
121
|
+
|
|
122
|
+
<div class="trace-connector" aria-hidden="true"></div>
|
|
123
|
+
{% endif %}
|
|
124
|
+
|
|
125
|
+
{%- comment -%} Agent Summary {%- endcomment -%}
|
|
126
|
+
{% if session.agentSummary %}
|
|
127
|
+
<section class="fade-in" aria-label="Agent summary">
|
|
128
|
+
<h2 class="section-header">Agent Summary</h2>
|
|
129
|
+
<div class="agent-table-wrapper">
|
|
130
|
+
<table class="agent-table">
|
|
131
|
+
<thead>
|
|
132
|
+
<tr>
|
|
133
|
+
<th scope="col">Role</th>
|
|
134
|
+
<th scope="col">Duration</th>
|
|
135
|
+
<th scope="col">LOC</th>
|
|
136
|
+
</tr>
|
|
137
|
+
</thead>
|
|
138
|
+
<tbody>
|
|
139
|
+
{% assign agent_colors = '#0891b2,#059669,#7c3aed,#475569,#e11d48,#d97706' | split: ',' %}
|
|
140
|
+
{% for agent in session.agentSummary.agents %}
|
|
141
|
+
<tr>
|
|
142
|
+
<td>
|
|
143
|
+
<span class="role-cell">
|
|
144
|
+
{% assign colorIdx = forloop.index0 | modulo: 6 %}
|
|
145
|
+
<span class="role-dot" style="background:{{ agent_colors[colorIdx] }}"></span>
|
|
146
|
+
{{ agent.role }}
|
|
147
|
+
</span>
|
|
148
|
+
</td>
|
|
149
|
+
<td class="mono">{{ agent.duration_minutes }}m</td>
|
|
150
|
+
<td class="mono">{{ agent.loc_changed }}</td>
|
|
151
|
+
</tr>
|
|
152
|
+
{% endfor %}
|
|
153
|
+
</tbody>
|
|
154
|
+
</table>
|
|
155
|
+
</div>
|
|
156
|
+
</section>
|
|
157
|
+
{% endif %}
|
|
158
|
+
</div>
|
|
159
|
+
|
|
160
|
+
{%- comment -%} Sidebar {%- endcomment -%}
|
|
161
|
+
<aside class="sidebar" aria-label="Session details">
|
|
162
|
+
{% if session.toolBreakdown.size > 0 %}
|
|
163
|
+
<div class="sidebar-section">
|
|
164
|
+
<h3 class="sidebar-title">Tools Used</h3>
|
|
165
|
+
<ul class="tool-list">
|
|
166
|
+
{% for t in session.toolBreakdown %}
|
|
167
|
+
<li class="tool-item">
|
|
168
|
+
<span class="tool-name">{{ t.tool }}</span>
|
|
169
|
+
<span class="tool-count">{{ t.count }}</span>
|
|
170
|
+
</li>
|
|
171
|
+
{% endfor %}
|
|
172
|
+
</ul>
|
|
173
|
+
</div>
|
|
174
|
+
{% endif %}
|
|
175
|
+
|
|
176
|
+
{% if session.topFiles.size > 0 %}
|
|
177
|
+
<div class="sidebar-section">
|
|
178
|
+
<h3 class="sidebar-title">Files Changed</h3>
|
|
179
|
+
<ul class="file-list">
|
|
180
|
+
{% for f in session.topFiles %}
|
|
181
|
+
<li class="file-item">
|
|
182
|
+
<span class="file-name" title="{{ f.path }}">{{ f.path }}</span>
|
|
183
|
+
<span class="file-diff">+{{ f.additions }}{% if f.deletions > 0 %} -{{ f.deletions }}{% endif %}</span>
|
|
184
|
+
</li>
|
|
185
|
+
{% endfor %}
|
|
186
|
+
</ul>
|
|
187
|
+
</div>
|
|
188
|
+
{% endif %}
|
|
189
|
+
|
|
190
|
+
{% if session.skills.size > 0 %}
|
|
191
|
+
<div class="sidebar-section">
|
|
192
|
+
<h3 class="sidebar-title">Skills</h3>
|
|
193
|
+
<div class="sidebar-pins">
|
|
194
|
+
{% for skill in session.skills %}
|
|
195
|
+
<span class="sidebar-pin">{{ skill }}</span>
|
|
196
|
+
{% endfor %}
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
{% endif %}
|
|
200
|
+
</aside>
|
|
201
|
+
</div>
|
|
202
|
+
|
|
203
|
+
{%- comment -%} Fade-in animation script {%- endcomment -%}
|
|
204
|
+
|
|
205
|
+
</div>
|