Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/theseus-engine.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ jobs:
- name: Run theseus multi-repo analysis (delta load)
run: poetry run python scripts/analyse_repository.py

- name: Update living fossils (survivor check)
run: |
# Re-blame HEAD for every repo and update the survivor fossil only if
# the file:line:commit has actually changed since the last run.
# Genesis (historical fossil) is left completely untouched.
poetry run python scripts/add_fossils.py --update-survivor

- name: Commit and push data updates
run: |
git config --local user.email "action@github.com"
Expand Down
73 changes: 55 additions & 18 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ class TheseusVisualizer {

async init() {
try {
const response = await fetch('data/manifest.json');
const response = await fetch('theseus.config.json');
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
let data = await response.json();
this.manifest = Array.isArray(data) ? data : [data];
// Fallback for backward compatibility, but normally expected to be under 'repositories'
this.manifest = data.repositories || (Array.isArray(data) ? data : [data]);

this.renderSelectors();
this.setupModeToggle();
Expand Down Expand Up @@ -406,7 +407,7 @@ class TheseusVisualizer {
const idx = bisect(this.points, date, 1);
const d0 = this.points[idx - 1];
const d1 = this.points[idx];

// Handle single-point or edge cases
if (!d0 && !d1) return;
let d;
Expand Down Expand Up @@ -447,17 +448,17 @@ class TheseusVisualizer {
let refactorHTML = '';
if (originalVal === 0) {
refactorHTML = `
<div style="background: rgba(248, 113, 113, 0.15); border: 1px solid rgba(248, 113, 113, 0.4);
padding: 1rem; border-radius: 1rem; margin-bottom: 1.25rem; color: #f87171;
<div style="background: rgba(248, 113, 113, 0.15); border: 1px solid rgba(248, 113, 113, 0.4);
padding: 1rem; border-radius: 1rem; margin-bottom: 1.25rem; color: #f87171;
font-size: 0.85rem; line-height: 1.5;">
<strong style="display: block; margin-bottom: 0.35rem; text-transform: uppercase; letter-spacing: 0.05em;">Ship of Theseus: The Great Rebirth</strong>
The original source code is now entirely gone.<br/><strong>Is this still the same codebase?</strong>
</div>
`;
} else if (isRefactor) {
refactorHTML = `
<div style="background: rgba(240, 163, 59, 0.15); border: 1px solid rgba(240, 163, 59, 0.4);
padding: 0.75rem; border-radius: 0.75rem; margin-bottom: 1rem; color: #f0a33b;
<div style="background: rgba(240, 163, 59, 0.15); border: 1px solid rgba(240, 163, 59, 0.4);
padding: 0.75rem; border-radius: 0.75rem; margin-bottom: 1rem; color: #f0a33b;
font-size: 0.85rem; line-height: 1.4;">
<strong style="display: block; margin-bottom: 0.25rem;">Ship of Theseus: Major Refactor</strong>
A significant part of the original source was refactored here.<br/>How much can you change before the identity shifts?
Expand Down Expand Up @@ -653,24 +654,47 @@ class TheseusVisualizer {
const repoPath = repoInfo ? repoInfo.repo : null;

const buildLink = (fossil) => {
if (!fossil.file) return '--';
const display = `${fossil.file}:${fossil.line}`;
if (!repoPath || !fossil.commit) return display;
const url = `https://github.com/${repoPath}/blob/${fossil.commit}/${fossil.file}#L${fossil.line}`;
return `<a href="${url}" target="_blank" rel="noopener noreferrer" style="color: inherit; text-decoration: underline; text-decoration-color: rgba(255,255,255,0.2); transition: color 0.3s ease;" onmouseover="this.style.color='var(--accent-cyan)'" onmouseout="this.style.color='inherit'">${display}</a>`;
const display = fossil.file ? `${fossil.file}:${fossil.line}` : '--';

// No file or no repo → plain text node, nothing to link
if (!fossil.file || !repoPath) return document.createTextNode(display);

const linkCommit = fossil.view_commit || fossil.commit;
if (!linkCommit) return document.createTextNode(display);

// URL-encode the file path (preserve /, encode special chars per segment)
// and the commit ref (branch names can contain slashes so encode fully)
const safeFile = fossil.file.split('/').map(encodeURIComponent).join('/');
const safeCommit = encodeURIComponent(linkCommit);
const safeLine = parseInt(fossil.line, 10) || 0;
const url = `https://github.com/${repoPath}/blob/${safeCommit}/${safeFile}#L${safeLine}`;

const a = document.createElement('a');
a.href = url;
a.target = '_blank';
a.rel = 'noopener noreferrer';
a.textContent = display;
a.style.color = 'inherit';
a.style.textDecoration = 'underline';
a.style.textDecorationColor = 'rgba(255,255,255,0.2)';
a.style.transition = 'color 0.3s ease';
a.addEventListener('mouseover', () => { a.style.color = 'var(--accent-cyan)'; });
a.addEventListener('mouseout', () => { a.style.color = 'inherit'; });
return a;
};

// Genesis (The Origin)
// Genesis (Historical Fossil) — show the pinned blame commit hash (frozen in history)
document.getElementById('genesis-year').textContent = genesis.year || '----';
document.getElementById('genesis-file').innerHTML = buildLink(genesis);
document.getElementById('genesis-file').replaceChildren(buildLink(genesis));
document.getElementById('genesis-content').textContent = genesis.content ? genesis.content.trim() : 'No fossil data';
document.getElementById('genesis-commit').textContent = genesis.commit || '';

// Survivor (The Current)
// Survivor (Living Fossil) — show branch name (e.g. "main"), not old blame hash
document.getElementById('survivor-year').textContent = survivor.year || '----';
document.getElementById('survivor-file').innerHTML = buildLink(survivor);
document.getElementById('survivor-file').replaceChildren(buildLink(survivor));
document.getElementById('survivor-content').textContent = survivor.content ? survivor.content.trim() : 'No fossil data';
document.getElementById('survivor-commit').textContent = survivor.commit || '';
document.getElementById('survivor-commit').textContent = survivor.view_commit || survivor.commit || '';
Comment thread
coderabbitai[bot] marked this conversation as resolved.

}

createSVGElement(tag, attrs = {}) {
Expand All @@ -680,7 +704,20 @@ class TheseusVisualizer {
}

showLoading(show) {
this.loadingState.classList.toggle('hidden', !show);
if (show) {
this.loadingState.classList.remove('hidden');
// Also hide the chart container while skeleton shows
const chartContainer = document.getElementById('chart-container');
if (chartContainer) chartContainer.style.opacity = '0';
} else {
this.loadingState.classList.add('hidden');
// Fade the chart back in smoothly
const chartContainer = document.getElementById('chart-container');
if (chartContainer) {
chartContainer.style.transition = 'opacity 0.35s ease';
chartContainer.style.opacity = '1';
}
}
}

showError(msg) {
Expand Down
2 changes: 1 addition & 1 deletion data/claude-code_data.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"snapshots":[{"snapshot_date":"2025-02","composition":{"2025":315}},{"snapshot_date":"2025-03","composition":{"2025":368}},{"snapshot_date":"2025-04","composition":{"2025":455}},{"snapshot_date":"2025-05","composition":{"2025":756}},{"snapshot_date":"2025-06","composition":{"2025":876}},{"snapshot_date":"2025-07","composition":{"2025":77387}},{"snapshot_date":"2025-08","composition":{"2025":77900}},{"snapshot_date":"2025-09","composition":{"2025":78823}},{"snapshot_date":"2025-10","composition":{"2025":56350}},{"snapshot_date":"2025-11","composition":{"2025":60301}},{"snapshot_date":"2025-12","composition":{"2025":86284}},{"snapshot_date":"2026-01","composition":{"2025":86626,"2026":35}},{"snapshot_date":"2026-02","composition":{"2025":86420,"2026":653}},{"snapshot_date":"2026-03","composition":{"2025":86142,"2026":1705}},{"snapshot_date":"2026-04","composition":{"2025":86142,"2026":2431}}],"fossils":{"genesis":{"timestamp":1740245022,"file":".devcontainer/Dockerfile","content":"FROM node:20","year":"2025","commit":"bd5ca70","line":1},"survivor":{"timestamp":1740245022,"file":".devcontainer/Dockerfile","content":"FROM node:20","year":"2025","commit":"bd5ca70","line":1}}}
{"snapshots":[{"snapshot_date":"2025-02","composition":{"2025":315}},{"snapshot_date":"2025-03","composition":{"2025":368}},{"snapshot_date":"2025-04","composition":{"2025":455}},{"snapshot_date":"2025-05","composition":{"2025":756}},{"snapshot_date":"2025-06","composition":{"2025":876}},{"snapshot_date":"2025-07","composition":{"2025":77387}},{"snapshot_date":"2025-08","composition":{"2025":77900}},{"snapshot_date":"2025-09","composition":{"2025":78823}},{"snapshot_date":"2025-10","composition":{"2025":56350}},{"snapshot_date":"2025-11","composition":{"2025":60301}},{"snapshot_date":"2025-12","composition":{"2025":86284}},{"snapshot_date":"2026-01","composition":{"2025":86626,"2026":35}},{"snapshot_date":"2026-02","composition":{"2025":86420,"2026":653}},{"snapshot_date":"2026-03","composition":{"2025":86142,"2026":1705}},{"snapshot_date":"2026-04","composition":{"2025":86142,"2026":2431}}],"fossils":{"genesis":{"timestamp":1740245022,"file":".devcontainer/Dockerfile","content":"FROM node:20","year":"2025","commit":"bd5ca70","view_commit":"bd5ca708adf82c4b81857abf40fe36d9d9cc3d1c","line":1},"survivor":{"timestamp":1740245022,"file":".devcontainer/init-firewall.sh","content":"#!/bin/bash","year":"2025","commit":"bd5ca70","view_commit":"main","line":1}}}
2 changes: 1 addition & 1 deletion data/langchain_data.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"snapshots":[{"snapshot_date":"2022-12","composition":{"2022":15774}},{"snapshot_date":"2023-03","composition":{"2022":28253,"2023":61969}},{"snapshot_date":"2023-06","composition":{"2023":487975,"2022":21681}},{"snapshot_date":"2023-09","composition":{"2023":681274,"2022":16291}},{"snapshot_date":"2023-12","composition":{"2023":881194,"2022":14704}},{"snapshot_date":"2024-03","composition":{"2024":357436,"2023":944924,"2022":10842}},{"snapshot_date":"2024-06","composition":{"2023":826677,"2024":645423,"2022":7685}},{"snapshot_date":"2024-09","composition":{"2023":686097,"2024":664907,"2022":7295}},{"snapshot_date":"2024-12","composition":{"2024":683157,"2023":546569,"2022":7138}},{"snapshot_date":"2025-01","composition":{"2024":720654,"2023":544169,"2022":7122,"2025":5}},{"snapshot_date":"2025-02","composition":{"2023":542683,"2024":707703,"2025":56681,"2022":7106}},{"snapshot_date":"2025-03","composition":{"2023":533418,"2024":657044,"2025":124237,"2022":6529}},{"snapshot_date":"2025-04","composition":{"2023":491914,"2024":630484,"2025":129671,"2022":6346}},{"snapshot_date":"2025-05","composition":{"2024":448680,"2025":144491,"2023":315772,"2022":5672}},{"snapshot_date":"2025-06","composition":{"2023":313764,"2024":444312,"2025":158141,"2022":5671}},{"snapshot_date":"2025-07","composition":{"2023":313208,"2024":441747,"2025":170384,"2022":5671}},{"snapshot_date":"2025-08","composition":{"2025":203640,"2023":308982,"2024":435295,"2022":5429}},{"snapshot_date":"2025-09","composition":{"2025":222619,"2023":308625,"2024":433511,"2022":5427}},{"snapshot_date":"2025-10","composition":{"2023":306859,"2025":253209,"2024":429458,"2022":5409}},{"snapshot_date":"2025-11","composition":{"2025":213274,"2023":83597,"2024":138301,"2022":3632}},{"snapshot_date":"2025-12","composition":{"2025":213376,"2023":83259,"2024":137738,"2022":3489}},{"snapshot_date":"2026-01","composition":{"2025":221792,"2023":82989,"2024":136828,"2022":3485,"2026":268}},{"snapshot_date":"2026-02","composition":{"2024":128469,"2023":81140,"2025":207607,"2026":12545,"2022":3485}},{"snapshot_date":"2026-03","composition":{"2023":81121,"2025":198803,"2024":126788,"2026":35860,"2022":3484}},{"snapshot_date":"2026-04","composition":{"2025":195106,"2023":81079,"2024":126636,"2026":47792,"2022":3475}}],"fossils":{"genesis":{"timestamp":1666648275,"file":".flake8","content":"[flake8]","year":"2022","commit":"18aeb72","line":1},"survivor":{"timestamp":1666648275,"file":".flake8","content":"[flake8]","year":"2022","commit":"18aeb72","line":1}}}
{"snapshots":[{"snapshot_date":"2022-12","composition":{"2022":15774}},{"snapshot_date":"2023-03","composition":{"2022":28253,"2023":61969}},{"snapshot_date":"2023-06","composition":{"2023":487975,"2022":21681}},{"snapshot_date":"2023-09","composition":{"2023":681274,"2022":16291}},{"snapshot_date":"2023-12","composition":{"2023":881194,"2022":14704}},{"snapshot_date":"2024-03","composition":{"2024":357436,"2023":944924,"2022":10842}},{"snapshot_date":"2024-06","composition":{"2023":826677,"2024":645423,"2022":7685}},{"snapshot_date":"2024-09","composition":{"2023":686097,"2024":664907,"2022":7295}},{"snapshot_date":"2024-12","composition":{"2024":683157,"2023":546569,"2022":7138}},{"snapshot_date":"2025-01","composition":{"2024":720654,"2023":544169,"2022":7122,"2025":5}},{"snapshot_date":"2025-02","composition":{"2023":542683,"2024":707703,"2025":56681,"2022":7106}},{"snapshot_date":"2025-03","composition":{"2023":533418,"2024":657044,"2025":124237,"2022":6529}},{"snapshot_date":"2025-04","composition":{"2023":491914,"2024":630484,"2025":129671,"2022":6346}},{"snapshot_date":"2025-05","composition":{"2024":448680,"2025":144491,"2023":315772,"2022":5672}},{"snapshot_date":"2025-06","composition":{"2023":313764,"2024":444312,"2025":158141,"2022":5671}},{"snapshot_date":"2025-07","composition":{"2023":313208,"2024":441747,"2025":170384,"2022":5671}},{"snapshot_date":"2025-08","composition":{"2025":203640,"2023":308982,"2024":435295,"2022":5429}},{"snapshot_date":"2025-09","composition":{"2025":222619,"2023":308625,"2024":433511,"2022":5427}},{"snapshot_date":"2025-10","composition":{"2023":306859,"2025":253209,"2024":429458,"2022":5409}},{"snapshot_date":"2025-11","composition":{"2025":213274,"2023":83597,"2024":138301,"2022":3632}},{"snapshot_date":"2025-12","composition":{"2025":213376,"2023":83259,"2024":137738,"2022":3489}},{"snapshot_date":"2026-01","composition":{"2025":221792,"2023":82989,"2024":136828,"2022":3485,"2026":268}},{"snapshot_date":"2026-02","composition":{"2024":128469,"2023":81140,"2025":207607,"2026":12545,"2022":3485}},{"snapshot_date":"2026-03","composition":{"2023":81121,"2025":198803,"2024":126788,"2026":35860,"2022":3484}},{"snapshot_date":"2026-04","composition":{"2025":195106,"2023":81079,"2024":126636,"2026":47792,"2022":3475}}],"fossils":{"genesis":{"timestamp":1666648275,"file":".flake8","content":"[flake8]","year":"2022","commit":"18aeb72","view_commit":"18aeb720126a68201c7e3b5a617139c27c779496","line":1},"survivor":{"timestamp":1666648275,"file":".github/workflows/_lint.yml","content":"jobs:","year":"2022","commit":"18aeb72","view_commit":"master","line":33}}}
32 changes: 0 additions & 32 deletions data/manifest.json

This file was deleted.

2 changes: 1 addition & 1 deletion data/numpy_data.json

Large diffs are not rendered by default.

Loading
Loading