feat(formats): Add CSV file format support #genai - #532
Conversation
|
Just to clarify this before I do anything at all, is code generation with Opus okay or not (I mean in terms of policy, copyright, etc.)? Also, it’s a non-trivial challenge for me to re-define what review means in the first place for LLM-supported PRs in collaboratively developed projects. I think I kind of figured this out for solo development, but this is a different setting... |
|
Treat it as a human-generated change - meaning the human running the AI is responsible for understanding it and making it a good change (no AI slop allowed), and the reviewer is responsible for enforcing code quality and etc too. Does that help? |
87fdc9f to
7971acb
Compare
Implement import and export functionality for CSV format checklists as requested in issue #531. Fixes #531 Rationale: - Uses established, battle-tested npm libraries (csv-parse and csv-stringify) for CSV operations. - Uses sync entry points to ensure zero Node.js stream overhead in the browser application. Summary of changes: - Added FormatId.CSV and registered CsvFormat in FormatRegistry. - Added CsvReader for parsing de-normalized CSV tables and metadata into ChecklistFile protobufs. - Added CsvWriter for serializing ChecklistFile protobufs into formatted CSV files. - Added comprehensive unit tests in csv-format.spec.ts covering parsing, writing, metadata extraction, round-trip serialization, and error handling. - Installed csv-parse and csv-stringify packages. - Created src/model/formats/test.csv representing EXPECTED_CONTENTS. - Added unit test in csv-format.spec.ts to verify reading test.csv matches EXPECTED_CONTENTS. - Updated Name field in test string to include a comma. - Updated assertion to expect "My Airplane Checklists, Main". - Added test case verifying default values for unpopulated metadata fields when parsing minimal CSV. - Refactored CsvReader header search to require only minimum columns (Group, Checklist, Type, Text) and map column indices dynamically. - Made Response, Indent, and Center columns optional when parsing CSV tables. - Added unit test should parse correctly when optional columns Indent and Center are missing. - Updated CsvReader row iteration logic to carry over currentGroup.title and currentChecklist.title when group or checklist cells are empty. - Added unit tests: - should parse correctly when Group column value is omitted on subsequent rows - should parse correctly when both Group and Checklist column values are omitted on subsequent rows - Added colIndexToLetters and cellId helper functions in csv-reader.ts. - Updated CsvReader error messages to report cell references (e.g. "cell A2: invalid/missing..."). - Updated unit test assertions in csv-format.spec.ts to verify cell ID error formatting. - Added CSV spreadsheet (.csv) to supported checklist file types list in README.md. - Added CSV column to format feature matrix table in README.md. - Added CSV Spreadsheet section detailing metadata keys, required/optional table header columns, and item row fields in README.md. Agent Metadata: Agent: Antigravity AI Coding Assistant (Gemini 3.6 Flash) Model: Gemini 3.6 Flash
Alright, thanks - let me give it a try under these premises. I expect to do the following - add a new commit showing what I think the problems are and how I would go about it - and add some evidence for problems solved. My thinking is, it's much easier than to write tons of prose and circle around with AI tools. It would help if you could hold off re-committing until then. Would that be okay with you? |
|
Yup, that's fine. |
…romises were rejected..."
zyv
left a comment
There was a problem hiding this comment.
Alright, so this is not actually a review, but more of a rewrite - and it took way more effort than I wished, but there we go. Hopefully, at least I can now take it off my mind :)
In as far as the feature is concerned, I think we don't have much to discuss: it's well-justified, the PR does what it says on the tin and does it properly in as far as I can judge from sane-looking code and passing tests.
The limitations that I thought were worth mentioning explicitly are as follows:
- Categories and completion actions are not supported
- Semicolon-based files cannot be imported
- Column order is fixed
- BOM handling
The first one I addressed in the README, I hope you don't mind my edits.
Regarding the second one, it's trivial to address by re-trying the parsing with a different delimiter. If you are wondering, it's a real issue here over the pond. At first, I was quite confused as to why everything in your PR was completely broken both in terms of Excel and Numbers imports/exports, until I realized that it's the old good CSV delimiter problem.
In as far as BOM handling is concerned, you'll get issues importing files with umlauts in Excel if you don't set it on export. Unfortunately, on top of that, Excel won't import CSVs with non-regional separator (,) without you telling it, but I left , as default.
The column order point you kind of get for free if you switch to a different parsing strategy.
Now, in terms of code, I'm afraid I can't get myself to review it in terms of correctness, edge case handling, and expression style, because by now you surely know how my brain is wired. I just get deadlocked on mutable imperative style :(
I have re-written it functionally like my FF/Garmin imports, but I tried to avoid going overboard with reductions and left a couple of places with imperative accumulators. My thinking is, TypeScript is just not the sort of language in which it looks understandable and beautiful. You can go in the direction to a certain extent and it's fewer lines of code, but then you kind of get lost in the confusing syntax and backwards evaluation order.
Apart from the expression style, the biggest issues I had with the original code were the switch tables (if (normalizedKey === ...), if (normalizedType === 'title bar') ..., switch (item.type) ...) and metadata parsing.
In my version, these are simply invertable maps and somewhat type-safer via type aliases. The writer becomes a few trivial maps. The reader, I'd argue, is more understandable than the iterative version, and more testable, although I didn't push that.
I hope this helps, and I wonder what you would make of that.
|
P.S. I did drop |
Let's not do this again then.
That wasn't the case before?
Not sure what you mean?
You'll have to explain that to me, 'cause I'm clueless here.
That we could handle by just adding the marker to the array when creating File, no need to re-implement serialization just for that.
Anything I can do to help? This is a tiny feature, and it's significantly more complex now 😄 |
|
(I have a busy week ahead, I'll probably look at your version in detail next weekend) |
|
(and btw my reply was not a complaint, sorry if it read that way - just really trying to understand the rationale for your changes) |
No worries, this is exactly how I understood your message, and I hope you can understand my attempt at an explanation in kind. |
P.S. It's not that the code can't be massaged into making it even nicer, clearer, and more understandable - it absolutely can. It's just that even with my undesirable getting carried away characteristics, I had to stop at some point, because no amount of massage makes sense if you wouldn't be interested in a different approach in principle. |




Implement import and export functionality for CSV format checklists as requested in issue #531.
Fixes #531
Rationale:
Summary of changes:
Agent Metadata:
Agent: Antigravity AI Coding Assistant (Gemini 3.6 Flash)
Model: Gemini 3.6 Flash