Conversation
diff --git a/finances/index.ts b/finances/index.ts index a78f1d2..8d0281e 100644 --- a/finances/index.ts +++ b/finances/index.ts @@ -51,13 +51,22 @@ async function parsePdfAndExtractInfo(filePath: string): Promise<void> { const awardIdMatch = result.text.match(/Award ID:\s*([^\r\n]+)/i); const settlementDateMatch = result.text.match(/Settlement Date:\s*([^\r\n]+)/i); + const vestedValueMatch = result.text.match(/Total Gain \(FMV x Quantity Released\):\s*([^\r\n]+)/i); + const saleAmountMatch = result.text.match(/Sale PricexQuantity Sold:\s*\(?([^\)\r\n]+)\)?/i); + const sharesSoldMatch = result.text.match(/Quantity Sold:\s*\(?([\d\.]+)\)?/i); + const salePriceMatch = result.text.match(/shares at \$([\d\.]+) per share/i); - if (awardIdMatch && settlementDateMatch) { + if (awardIdMatch && settlementDateMatch && vestedValueMatch && saleAmountMatch && sharesSoldMatch && salePriceMatch) { const rawSettlementDate = settlementDateMatch[1].trim(); const formattedSettlementDate = formatDate(rawSettlementDate); + const formattedSalePrice = parseFloat(salePriceMatch[1]).toFixed(4); console.log(`Award ID: ${awardIdMatch[1].trim()}`); console.log(`Settlement Date: ${formattedSettlementDate}`); + console.log(`Vested Value: ${vestedValueMatch[1].trim()}`); + console.log(`Sale Amount: ${saleAmountMatch[1].trim()}`); + console.log(`Shares Sold: ${sharesSoldMatch[1].trim()}`); + console.log(`Sale Price: $${formattedSalePrice}`); } else { if (!awardIdMatch) { console.error("Error: Could not find Award ID in the PDF."); @@ -65,6 +74,18 @@ async function parsePdfAndExtractInfo(filePath: string): Promise<void> { if (!settlementDateMatch) { console.error("Error: Could not find Settlement Date in the PDF."); } + if (!vestedValueMatch) { + console.error("Error: Could not find Vested Value in the PDF."); + } + if (!saleAmountMatch) { + console.error("Error: Could not find Sale Amount in the PDF."); + } + if (!sharesSoldMatch) { + console.error("Error: Could not find Shares Sold in the PDF."); + } + if (!salePriceMatch) { + console.error("Error: Could not find Sale Price in the PDF."); + } process.exit(1); }
There was a problem hiding this comment.
Code Review
This pull request introduces a new finances utility (mspdf.ts) to parse Morgan Stanley Release Confirmation PDFs for tax reporting, alongside updates to the android-cli and code-review AI skill definitions. The feedback primarily addresses critical integration issues with the pdf-parse library, which is imported as a named class instead of its default function export, leading to runtime failures. Additionally, several regular expressions in mspdf.ts require adjustments to handle whitespace and commas correctly, and the file renaming loop should be wrapped in a try-catch block for robustness. Finally, minor documentation errors in the android-cli skill files—such as an incorrect command reference, a malformed JSON example, and a duplicate list item number—should be corrected.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
I am having trouble creating individual review comments. Click here to see my feedback.
finances/mspdf.ts (4)
The standard pdf-parse package exports a default function rather than a named PDFParse class. Importing { PDFParse } will result in a compilation error and runtime failure. It should be imported as a default import.
import pdf from "pdf-parse";
finances/mspdf.ts (15-18)
Since pdf-parse is a function that directly parses the buffer and returns a promise, you do not need to instantiate a class or call destroy(). This will prevent runtime errors.
const result = await pdf(dataBuffer);
console.log(result.text);
finances/mspdf.ts (65-67)
Update the parsing logic here as well to use the default function export of pdf-parse.
const result = await pdf(dataBuffer);
finances/mspdf.ts (76-78)
The regular expression /Sale PricexQuantity Sold:/i is missing whitespace around the x character. Morgan Stanley PDFs typically format this with spaces (e.g., Sale Price x Quantity Sold). This typo will cause the parser to fail on valid documents.
const saleAmountMatch = result.text.match(
/Sale Price\\s*x\\s*Quantity Sold:\\s*\\(?([^)\\r\\n]+)\\)?/i,
);
finances/mspdf.ts (79)
The regular expression for matching the quantity sold ([\d.]+) does not account for commas in numbers (e.g., 1,000). This can cause parsing to fail or return incomplete numbers for larger transactions.
const sharesSoldMatch = result.text.match(/Quantity Sold:\\s*\\(?([\\d.,]+)\\)?/i);
finances/mspdf.ts (154-172)
When renaming multiple files in a loop, if a single file fails to parse or rename, the entire command will crash and prevent subsequent files from being processed. Wrapping the loop body in a try/catch block makes the command much more robust.
async function renameFiles(filePaths: string[]): Promise<void> {
for (const filePath of filePaths) {
if (!fs.existsSync(filePath)) {
console.error("Error: File not found at path \"" + filePath + "\"");
process.exit(1);
}
try {
const parsed = await extractInfoFromPdf(filePath);
const baseNewName = getNewFilename(parsed);
const dir = path.dirname(filePath);
const ext = path.extname(filePath);
const newFilename = baseNewName + ext;
const newPath = path.join(dir, newFilename);
fs.renameSync(filePath, newPath);
console.log("Renamed " + filePath + " to " + newFilename);
} catch (error) {
console.error("Error renaming \"" + filePath + "\":", error instanceof Error ? error.message : error);
}
}
}ai/skills/android-cli/SKILL.md (56)
The command android screenshot does not exist in the CLI help output. The correct command is android screen capture. Please update this to avoid misleading users.
ai/skills/android-cli/references/journeys.md (77-96)
The JSON example is malformed (missing closing quotes, colons inside quotes, single-line comments, and trailing commas). Since this is a skill definition, it is important to provide a valid JSON schema example.
Here is the corrected JSON:
{
"journey": "The name of the journey",
"results": [
{
"action": "Click the blue button",
"status": "PASSED",
"commands": [ "adb input swipe 490 200 500 500 500", "adb input tap 45 920" ],
"comment": "The journey step doesn't specify that the button requires scrolling to see"
},
{
"action": "The home screen is shown",
"status": "FAILED",
"comment": "The settings page was shown"
}
]
}ai/skills/android-cli/references/interact.md (81-82)
There is a duplicate list item number 2. in the markdown list. Please renumber the list items sequentially.
No description provided.