app
Adom Gantt
Public Made by Adomby adom
Interactive Gantt chart viewer for project timelines, with a table view and an analytics page over the same data. Data-driven, dark by default with a print-friendly light mode, and fully editable in the browser: drag bars to move or resize, multi-select and batch-shift dates, manage dependency arrows inline, reorder rows, filter by phase, and undo. One click auto-schedules the whole plan so every dependency lines up finish-to-start on working days, skipping weekends and US federal holidays, push
← Commit history
0.28.3: plan.schedule and plan.sections render as sentences in the changelog
4 files changed
+24−3
docs/BUILD-NOTES.md+11@@ -3,6 +3,17 @@ Decisions taken while building, and the places where the plan and the code disagreed. Newest first. +## Build notes, 2026-08-14 (0.28.3, two data events that read like sentences)++A full scheduling pass and a section add both went into the DC plan as data+operations, and both landed in the changelog as `plan.schedule an item (data)`,+which is `describeEvent`'s generic fallback doing its job on an action it had+never been taught. The changelog is the AI handoff surface: an event that cannot+be read is an event that did not happen, as far as the next agent is concerned.+Both actions now render as sentences, and because `describeEvent` runs at READ+time, the two events already on disk started reading properly the moment this+shipped.+ ## Build notes, 2026-08-14 (0.28.2, one dropdown, not two) A screenshot showed a phase cell with TWO differently-styled option lists stacked
package.json+1−1@@ -2,7 +2,7 @@ "slug": "adom-gantt", "title": "Adom Gantt", "type": "app",- "version": "0.28.2",+ "version": "0.28.3", "description": "Interactive Gantt chart viewer for project timelines, with a table view over the same data. Data-driven, dark by default with a print-friendly light mode, and fully editable in the browser: drag bars to move or resize, multi-select and batch-shift dates, manage dependency arrows inline, reorder rows, filter by phase, and undo. Toggle to the table for every task and milestone as a row with owner, deadline and status, filtered per owner and edited in place. Every edit is recorded in an append-only changelog so an AI can read what a human changed and build on it. Imports JSON, CSV, MS Project XML and Jira CSV; exports JSON, CSV, SVG and a self-contained HTML snapshot.", "main": "server.js", "bin": {
page.json+2−2@@ -2,7 +2,7 @@ "slug": "adom-gantt", "title": "Adom Gantt", "type": "app",- "version": "0.28.2",+ "version": "0.28.3", "description": "Interactive Gantt chart viewer for project timelines, with a table view over the same data. Data-driven, dark by default with a print-friendly light mode, and fully editable in the browser: drag bars to move or resize, multi-select and batch-shift dates, manage dependency arrows inline, reorder rows, filter by phase, and undo. Toggle to the table for every task and milestone as a row with owner, deadline and status, filtered per owner and edited in place. Every edit is recorded in an append-only changelog so an AI can read what a human changed and build on it. Imports JSON, CSV, MS Project XML and Jira CSV; exports JSON, CSV, SVG and a self-contained HTML snapshot.", "main": "server.js", "bin": {@@ -63,4 +63,4 @@ "name": "Drew Owens", "email": "[email protected]" }-}+}
server.js+10@@ -494,6 +494,16 @@ function describeEvent(e) { if (action === 'import') { return `${who} REPLACED the whole plan by importing ${e.items || 0} item(s) in ${e.phases || 0} phase(s) from ${e.format || 'a file'}. Everything before this point describes a different plan${via}`; }+ if (action === 'plan.schedule') {+ const ov = Array.isArray(e.overrides) ? e.overrides.length : 0;+ const kept = e.kept_drews_newer_edits ? `, keeping ${e.kept_drews_newer_edits} edit(s) made while it was being worked out` : '';+ return `${who} re-scheduled the plan: ${e.tasks || 0} task(s) given new dates and ${e.reordered || 0} row(s) reordered so each lane reads top to bottom in the order the work happens. ${e.milestones_untouched || 0} milestone(s) were left exactly where they were, and ${ov} hand-set date(s) had to be overridden to keep a dependency or an anchor honest (listed in this event's "overrides")${kept}${via}`;+ }+ if (action === 'plan.sections') {+ const names = Array.isArray(e.names) && e.names.length ? `: ${e.names.join(', ')}` : '';+ const rn = e.rename ? `. Renamed ${e.rename.uid} "${e.rename.from}" to "${e.rename.to}"` : '';+ return `${who} added ${e.added || 0} empty section(s) to the plan${names}${rn}${via}`;+ } if (action === 'state.upgrade') { const lost = e.dropped ? `, ${e.dropped} entry(s) that named no row dropped` : ', nothing dropped'; return `${who} rewrote the saved edits to be keyed by uid instead of by row position (v${e.from || '?'} to v${e.to || 4}): ${e.items || 0} override(s), ${e.order || 0} rows in order, ${e.added || 0} created, ${e.deleted || 0} deleted${lost}. Inserting a row mid-plan no longer moves anything else${via}`;