heyiam 0.3.4 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/export.js +19 -5
  2. package/dist/mount.js +9 -7
  3. package/dist/public/assets/{index-Cq04whgG.js → index-7mUuxgqY.js} +3 -3
  4. package/dist/public/index.html +1 -1
  5. package/dist/render/build-render-data.js +1 -0
  6. package/dist/render/liquid.js +12 -2
  7. package/dist/render/templates/aurora/project.liquid +1 -1
  8. package/dist/render/templates/bauhaus/project.liquid +1 -1
  9. package/dist/render/templates/blueprint/project.liquid +1 -1
  10. package/dist/render/templates/canvas/project.liquid +1 -1
  11. package/dist/render/templates/carbon/project.liquid +1 -1
  12. package/dist/render/templates/chalk/project.liquid +1 -1
  13. package/dist/render/templates/circuit/project.liquid +1 -1
  14. package/dist/render/templates/cosmos/project.liquid +1 -1
  15. package/dist/render/templates/daylight/project.liquid +1 -1
  16. package/dist/render/templates/editorial/project.liquid +1 -1
  17. package/dist/render/templates/ember/project.liquid +1 -1
  18. package/dist/render/templates/glacier/project.liquid +1 -1
  19. package/dist/render/templates/grid/project.liquid +1 -1
  20. package/dist/render/templates/kinetic/portfolio.liquid +1 -1
  21. package/dist/render/templates/kinetic/project.liquid +1 -1
  22. package/dist/render/templates/kinetic/styles.css +15 -9
  23. package/dist/render/templates/meridian/project.liquid +1 -1
  24. package/dist/render/templates/minimal/project.liquid +1 -1
  25. package/dist/render/templates/mono/project.liquid +1 -1
  26. package/dist/render/templates/neon/project.liquid +1 -1
  27. package/dist/render/templates/noir/project.liquid +1 -1
  28. package/dist/render/templates/obsidian/project.liquid +1 -1
  29. package/dist/render/templates/paper/project.liquid +1 -1
  30. package/dist/render/templates/parallax/project.liquid +1 -1
  31. package/dist/render/templates/parchment/project.liquid +1 -1
  32. package/dist/render/templates/project.liquid +1 -1
  33. package/dist/render/templates/radar/project.liquid +1 -1
  34. package/dist/render/templates/showcase/project.liquid +1 -1
  35. package/dist/render/templates/signal/project.liquid +1 -1
  36. package/dist/render/templates/strata/project.liquid +1 -1
  37. package/dist/render/templates/terminal/project.liquid +1 -1
  38. package/dist/render/templates/verdant/project.liquid +1 -1
  39. package/dist/render/templates/zen/project.liquid +1 -1
  40. package/dist/routes/portfolio-render-data.js +2 -2
  41. package/dist/routes/preview.js +18 -2
  42. package/dist/routes/project-session-upload.js +4 -3
  43. package/dist/routes/publish.js +118 -16
  44. package/dist/settings.js +14 -1
  45. package/package.json +1 -1
package/dist/export.js CHANGED
@@ -42,8 +42,10 @@ function resolveScreenshotDataUri(dirName, cache) {
42
42
  return b64;
43
43
  return `data:image/png;base64,${b64}`;
44
44
  }
45
- // Try local screenshot file
46
- const slug = toSlug(dirName);
45
+ // Try local screenshot file. Screenshots are keyed by the clean slug that
46
+ // the publish flow uses (toSlug(displayNameFromDir(dirName))), not the raw
47
+ // encoded path.
48
+ const slug = toSlug(displayNameFromDir(dirName));
47
49
  const screenshotPath = join(SCREENSHOTS_DIR, `${slug}.png`);
48
50
  if (existsSync(screenshotPath)) {
49
51
  const buf = readFileSync(screenshotPath);
@@ -207,8 +209,12 @@ export async function exportHtml(dirName, cache, sessions, outputPath, username
207
209
  let totalBytes = 0;
208
210
  mkdirSync(outputPath, { recursive: true });
209
211
  const { result } = cache;
210
- const slug = slugify(dirName);
212
+ // dirName is Claude Code's encoded full path (e.g. `-Users-ben-Dev-agent-sync`).
213
+ // The Phoenix-side slug comes from `toSlug(displayNameFromDir(dirName))`, so
214
+ // match that here — otherwise anchor hrefs and zip folder names keep the
215
+ // entire encoded path.
211
216
  const title = opts?.title ?? cache.title ?? displayNameFromDir(dirName);
217
+ const slug = slugify(displayNameFromDir(dirName));
212
218
  // Use ALL sessions (same as dashboard), build cards for each
213
219
  const sessionCards = sessions.map((session) => {
214
220
  return buildSessionCard({
@@ -259,6 +265,7 @@ export async function exportHtml(dirName, cache, sessions, outputPath, username
259
265
  totalTokens,
260
266
  sessionCards,
261
267
  sessionBaseUrl: './sessions',
268
+ sessionSuffix: '.html',
262
269
  });
263
270
  const templateName = resolveTemplate(undefined, getDefaultTemplate());
264
271
  const projectBody = renderProjectHtml(projectRenderData, {
@@ -311,8 +318,12 @@ function getInlineCss() {
311
318
  // ── Shared render helpers ─────────────────────────────────────
312
319
  function buildProjectRenderInputs(dirName, cache, sessions, username, opts) {
313
320
  const { result } = cache;
314
- const slug = slugify(dirName);
321
+ // dirName is Claude Code's encoded full path (e.g. `-Users-ben-Dev-agent-sync`).
322
+ // The Phoenix-side slug comes from `toSlug(displayNameFromDir(dirName))`, so
323
+ // match that here — otherwise anchor hrefs and zip folder names keep the
324
+ // entire encoded path.
315
325
  const title = opts?.title ?? cache.title ?? displayNameFromDir(dirName);
326
+ const slug = slugify(displayNameFromDir(dirName));
316
327
  const sessionCards = sessions.map((session) => buildSessionCard({
317
328
  sessionId: session.id,
318
329
  session,
@@ -356,6 +367,8 @@ export function generateProjectHtmlFragment(dirName, cache, sessions, username =
356
367
  totalSessions: sessions.length,
357
368
  totalLoc, totalDurationMinutes, totalAgentDurationMinutes, totalFilesChanged, totalTokens,
358
369
  sessionCards,
370
+ sessionBaseUrl: `/${username}/${slug}`,
371
+ sessionSuffix: '',
359
372
  });
360
373
  const templateName = resolveTemplate(undefined, getDefaultTemplate());
361
374
  return renderProjectHtml(renderData, {
@@ -380,6 +393,7 @@ export function generateHtmlFiles(dirName, cache, sessions, username = 'local',
380
393
  totalLoc, totalDurationMinutes, totalAgentDurationMinutes, totalFilesChanged, totalTokens,
381
394
  sessionCards,
382
395
  sessionBaseUrl: './sessions',
396
+ sessionSuffix: '.html',
383
397
  });
384
398
  const projectBody = renderProjectHtml(projectRenderData, {
385
399
  arc: result.arc,
@@ -633,7 +647,7 @@ export async function generatePortfolioSite(portfolioData, projects, outputDir,
633
647
  const projectsRoot = join(outputDir, 'projects');
634
648
  mkdirSync(projectsRoot, { recursive: true });
635
649
  for (const p of projects) {
636
- const projectSlug = slugify(p.dirName);
650
+ const projectSlug = slugify(displayNameFromDir(p.dirName));
637
651
  const projectDir = join(projectsRoot, projectSlug);
638
652
  const result = await exportHtml(p.dirName, p.cache, p.sessions, projectDir, username, p.opts);
639
653
  files.push(...result.files);
package/dist/mount.js CHANGED
@@ -21961,7 +21961,7 @@
21961
21961
  count
21962
21962
  }));
21963
21963
  }
21964
- function buildLegendEntries(segments, sessionRanges) {
21964
+ function buildLegendEntries(sessionRanges) {
21965
21965
  return sessionRanges.map((r) => {
21966
21966
  const kids = getChildren(r.session);
21967
21967
  return {
@@ -22297,7 +22297,7 @@
22297
22297
  const concurrentLimit = expanded ? 999 : DEFAULT_MAX_CONCURRENT;
22298
22298
  const themeColors = (0, import_react.useMemo)(() => ({ main: mainColor, muted: textMuted }), [mainColor, textMuted]);
22299
22299
  const L = (0, import_react.useMemo)(() => layoutSegments(segments, concurrentLimit, themeColors), [segments, concurrentLimit, themeColors]);
22300
- const legendEntries = (0, import_react.useMemo)(() => buildLegendEntries(segments, L.sessionRanges), [segments, L.sessionRanges]);
22300
+ const legendEntries = (0, import_react.useMemo)(() => buildLegendEntries(L.sessionRanges), [L.sessionRanges]);
22301
22301
  const scrollRef = (0, import_react.useRef)(null);
22302
22302
  const [hovered, setHovered] = (0, import_react.useState)(null);
22303
22303
  const [focusedEntry, setFocusedEntry] = (0, import_react.useState)(null);
@@ -23135,22 +23135,24 @@
23135
23135
  }
23136
23136
  var allSessions = /* @__PURE__ */ new Map();
23137
23137
  var showOverlay = null;
23138
- function OverlayRoot({ sessions }) {
23138
+ function OverlayRoot() {
23139
23139
  const [active, setActive] = (0, import_react3.useState)(null);
23140
23140
  showOverlay = (session) => setActive(session);
23141
23141
  if (!active) return null;
23142
23142
  const projectEl = document.querySelector(".heyiam-project");
23143
23143
  const baseUrl = projectEl?.getAttribute("data-session-base-url");
23144
+ const suffix = projectEl?.getAttribute("data-session-suffix") ?? "";
23144
23145
  let sessionPageUrl;
23145
23146
  if (baseUrl) {
23146
- const slug = active.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 80) || "untitled";
23147
- sessionPageUrl = `${baseUrl}/${slug}.html`;
23147
+ const fromTitle = active.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 80) || "untitled";
23148
+ const sessionSlug = active.slug ?? fromTitle;
23149
+ sessionPageUrl = `${baseUrl}/${sessionSlug}${suffix}`;
23148
23150
  } else {
23149
23151
  const username = projectEl?.getAttribute("data-username");
23150
23152
  const projectSlug = projectEl?.getAttribute("data-project-slug");
23151
23153
  const sessionSlug = active.slug;
23152
23154
  if (username && projectSlug && sessionSlug) {
23153
- sessionPageUrl = `/@${username}/${projectSlug}/${sessionSlug}`;
23155
+ sessionPageUrl = `/${username}/${projectSlug}/${sessionSlug}`;
23154
23156
  }
23155
23157
  }
23156
23158
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
@@ -23219,7 +23221,7 @@
23219
23221
  overlayEl.id = "heyiam-overlay-root";
23220
23222
  document.body.appendChild(overlayEl);
23221
23223
  (0, import_client.createRoot)(overlayEl).render(
23222
- import_react3.default.createElement(OverlayRoot, { sessions: allSessions })
23224
+ import_react3.default.createElement(OverlayRoot)
23223
23225
  );
23224
23226
  }
23225
23227
  }