Skip to content

finances added with ms release confirmation pdf parsing logic#8

Merged
denversc merged 16 commits into
mainfrom
finances
Jun 14, 2026
Merged

finances added with ms release confirmation pdf parsing logic#8
denversc merged 16 commits into
mainfrom
finances

Conversation

@denversc

Copy link
Copy Markdown
Owner

No description provided.

denversc added 16 commits June 14, 2026 14:53
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);
   }

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)

critical

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)

critical

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)

critical

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)

high

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)

medium

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)

medium

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)

medium

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)

medium

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)

medium

There is a duplicate list item number 2. in the markdown list. Please renumber the list items sequentially.

@denversc denversc merged commit d66039d into main Jun 14, 2026
4 of 6 checks passed
@denversc denversc deleted the finances branch June 14, 2026 20:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant