()
| 13 | } |
| 14 | |
| 15 | export async function diffCommand() { |
| 16 | if (!(await isInitialized())) { |
| 17 | console.log(chalk.red("✗ DevContext not initialized. Run `devctx init` first.")); |
| 18 | return; |
| 19 | } |
| 20 | |
| 21 | try { |
| 22 | const branch = await getCurrentBranch(); |
| 23 | const entries = await loadBranchContext(branch); |
| 24 | |
| 25 | if (entries.length === 0) { |
| 26 | console.log(chalk.yellow(`⚠ No context found for branch: ${branch}`)); |
| 27 | console.log(chalk.gray(" Run `devctx save` to capture context first.")); |
| 28 | return; |
| 29 | } |
| 30 | |
| 31 | const latest = entries[entries.length - 1]; |
| 32 | const [currentChanged, currentStaged] = await Promise.all([ |
| 33 | getChangedFiles(), |
| 34 | getStagedFiles(), |
| 35 | ]); |
| 36 | |
| 37 | const lastSaveTime = getTimeAgo(latest.timestamp); |
| 38 | |
| 39 | console.log(chalk.bold(`\nSince last save (${lastSaveTime}):\n`)); |
| 40 | |
| 41 | // --- Files --- |
| 42 | const previousFiles = new Set(latest.filesChanged); |
| 43 | const currentFiles = new Set([...currentChanged, ...currentStaged]); |
| 44 | |
| 45 | const newFiles = [...currentFiles].filter((f) => !previousFiles.has(f)); |
| 46 | const removedFiles = [...previousFiles].filter((f) => !currentFiles.has(f)); |
| 47 | const stillChanged = [...currentFiles].filter((f) => previousFiles.has(f)); |
| 48 | |
| 49 | if (newFiles.length > 0) { |
| 50 | newFiles.forEach((f) => console.log(` ${chalk.green("+")} ${f} ${chalk.green("(new)")}`)); |
| 51 | } |
| 52 | if (stillChanged.length > 0) { |
| 53 | stillChanged.forEach((f) => console.log(` ${chalk.yellow("~")} ${f} ${chalk.gray("(still modified)")}`)); |
| 54 | } |
| 55 | if (removedFiles.length > 0) { |
| 56 | removedFiles.forEach((f) => console.log(` ${chalk.red("-")} ${f} ${chalk.gray("(resolved)")}`)); |
| 57 | } |
| 58 | if (newFiles.length === 0 && removedFiles.length === 0 && stillChanged.length === 0) { |
| 59 | console.log(chalk.gray(" No file changes since last save.")); |
| 60 | } |
| 61 | |
| 62 | // --- Decisions --- |
| 63 | if (entries.length >= 2) { |
| 64 | const previous = entries[entries.length - 2]; |
| 65 | const prevDecisions = new Set(previous.decisions); |
| 66 | const newDecisions = latest.decisions.filter((d) => !prevDecisions.has(d)); |
| 67 | if (newDecisions.length > 0) { |
| 68 | console.log(); |
| 69 | newDecisions.forEach((d) => |
| 70 | console.log(` ${chalk.cyan("Decision added:")} "${d}"`) |
| 71 | ); |
| 72 | } |
nothing calls this directly
no test coverage detected