Reference implementation for the Phoenix Architecture. Work in progress. aicoding.leaflet.pub/
ai coding crazy
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: phoenix ingest now shows diff before overwriting stored clauses

Root cause: user runs ingest then diff, but ingest overwrites the
stored clause index — so diff compares new vs new and shows no changes.

Fix: cmdIngest now diffs stored vs file BEFORE ingesting. Shows which
clauses were added/removed/modified, and guides user to run canonicalize
then regen. The user no longer needs a separate diff step.

+37 -1
examples/todo-app/data/app.db-shm

This is a binary file and will not be displayed.

examples/todo-app/data/app.db-wal

This is a binary file and will not be displayed.

+1
examples/todo-app/spec/todos.md
··· 20 20 - Descriptions must not exceed 5000 characters 21 21 - Priority must always be one of: urgent, high, normal, low 22 22 - Due dates must be valid dates; the system must reject obviously invalid dates 23 + - Due dates must be either in the present or the future 23 24 - The system must expose these capabilities as a programmatic interface so external tools can create, read, update, and delete tasks using standard conventions 24 25 25 26 ## Projects
+36 -1
src/cli.ts
··· 763 763 console.log(); 764 764 765 765 let totalClauses = 0; 766 + let totalChanges = 0; 767 + 766 768 for (const file of files) { 769 + const docId = relative(projectRoot, file); 770 + 771 + // Show diff BEFORE ingesting 772 + const diffs = specStore.diffDocument(file, projectRoot); 773 + const added = diffs.filter(d => d.diff_type === DiffType.ADDED).length; 774 + const removed = diffs.filter(d => d.diff_type === DiffType.REMOVED).length; 775 + const modified = diffs.filter(d => d.diff_type === DiffType.MODIFIED).length; 776 + const hasChanges = added > 0 || removed > 0 || modified > 0; 777 + 778 + // Now ingest (overwrites stored clauses) 767 779 const result = specStore.ingestDocument(file, projectRoot); 768 780 totalClauses += result.clauses.length; 769 - console.log(` ${green('✔')} ${relative(projectRoot, file)} → ${result.clauses.length} clauses`); 781 + 782 + if (hasChanges) { 783 + totalChanges += added + removed + modified; 784 + console.log(` ${green('✔')} ${docId} → ${result.clauses.length} clauses`); 785 + if (added > 0) console.log(` ${green(`+${added} added`)}`); 786 + if (removed > 0) console.log(` ${red(`-${removed} removed`)}`); 787 + if (modified > 0) console.log(` ${yellow(`~${modified} modified`)}`); 788 + 789 + // Show which clauses changed 790 + for (const d of diffs) { 791 + if (d.diff_type === DiffType.UNCHANGED) continue; 792 + const pathLabel = d.section_path_after?.join(' > ') || d.section_path_before?.join(' > ') || ''; 793 + const preview = (d.clause_after?.normalized_text || d.clause_before?.normalized_text || '').slice(0, 80); 794 + const icon = d.diff_type === DiffType.ADDED ? green('+') : d.diff_type === DiffType.REMOVED ? red('-') : yellow('~'); 795 + console.log(` ${icon} ${pathLabel}`); 796 + } 797 + } else { 798 + console.log(` ${green('✔')} ${docId} → ${result.clauses.length} clauses ${dim('(no changes)')}`); 799 + } 770 800 } 771 801 772 802 console.log(); 773 803 console.log(` ${dim(`Total: ${totalClauses} clauses ingested`)}`); 804 + if (totalChanges > 0) { 805 + console.log(` ${dim(`Changes: ${totalChanges} clauses affected`)}`); 806 + console.log(); 807 + console.log(` ${dim('Next: run')} ${cyan('phoenix canonicalize')} ${dim('then')} ${cyan('phoenix regen')} ${dim('to update generated code')}`); 808 + } 774 809 } 775 810 776 811 function cmdDiff(args: string[]): void {