Skip to content

refactor(plugin): migrate candidate normalization to TypeScript - #758

Open
mldangelo-oai wants to merge 9 commits into
mainfrom
mdangelo/codex/normalize-candidates-ts-ready
Open

refactor(plugin): migrate candidate normalization to TypeScript#758
mldangelo-oai wants to merge 9 commits into
mainfrom
mdangelo/codex/normalize-candidates-ts-ready

Conversation

@mldangelo-oai

@mldangelo-oai mldangelo-oai commented Aug 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

Migrate candidate normalization from Python to TypeScript. Discovery and diff scans now run the Node helper, and the Python implementation is removed.

Changes

  • Compile and ship normalize_candidates.mjs through the existing plugin build.
  • Switch the discovery caller and diff-scan workflow to Node, and move normalizer tests to TypeScript.

Testing

  • SDK: 2,145 passed, 45 skipped. MCP: all 23 test files passed.
  • Typechecking, formatting, plugin source checks, portable Python checks, and installed-package checks passed.
  • Packaged helper verified on Node 22.13.0 and 24.15.0.
  • The final commit only removes documentation. Prettier and git diff --check passed; runtime code is unchanged since the test runs above.

Risk and rollout

The helper invocation is now node normalize_candidates.mjs. Repeat --input FILE for multiple inputs, use full option names, and let the shell expand home paths. Candidate IDs may differ from Python output; stored scan artifacts are not migrated automatically.

No top-level CLI or version changes. The plugin stays at 0.1.79; cached installations receive the migration with the next versioned release. Other helpers still require Python. Linux, Windows, and Node 26 were not tested locally.

Public disclosure review

  • No customer, partner, prospect, or user identities, data, or identifying details are included.
  • No credentials, personal data, private source, scan findings, or nonpublic links or tickets are included.
  • I reviewed the branch name, title, description, commits, changes, comments, logs, screenshots, attachments, and links for public disclosure.
codex added 5 commits August 29, 2026 23:16
Generate the standalone helper during plugin packaging and retain Python for production. Add differential CLI, filesystem, Unicode, and property coverage, including cached-plugin upgrades and cyclic-link validation.
@github-actions github-actions Bot added the enhancement New feature or request label Aug 30, 2026
@mldangelo-oai

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review the current head, 8a594de.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 30, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-08-30T23:16:56.074688Z 07cd80a Draft marked ready
🔒 Security Review Completed 2026-08-30T23:15:22.364810Z 07cd80a Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8a594de952

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +135 to +138
const contents = readFileSync(path, "utf8");
return contents === ""
? 0
: contents.split("\n").length - (contents.endsWith("\n") ? 1 : 0);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Count carriage-return line endings

When a repository source file uses CR-only line endings, this counts every nonempty file as one line because it only splits on \n; the existing Python normalizer counts \r, \n, and \r\n via splitlines(). Consequently, valid candidate locations beginning on line 2 or later are rejected as out of range, so preserve the existing line-count behavior when validating locations.

AGENTS.md reference: AGENTS.md:L32-L33

Useful? React with 👍 / 👎.

@mldangelo-oai mldangelo-oai changed the title feat(plugin): add TypeScript candidate normalizer prototype Aug 30, 2026
@mldangelo-oai

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review the current head, c786f7d. This update switches production callers to the Node helper, removes the Python implementation, and leaves plugin versions unchanged. It also fixes CR-only source-line counting and refreshes the reviewed diff-scan workflow fingerprint used by custom validation.

@github-actions github-actions Bot removed the enhancement New feature or request label Aug 30, 2026
@mldangelo-oai mldangelo-oai changed the title refactor(plugin): replace Python candidate normalizer with TypeScript Aug 30, 2026
@mldangelo-oai

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review the current head, 07cd80a.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

Reviewed commit: 07cd80acbd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@mldangelo-oai
mldangelo-oai marked this pull request as ready for review August 30, 2026 23:12

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 07cd80acbd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +195 to +197
if (!allowMissing || !isMissingFile(error)) {
throw new Error(`in-scope file row ${index + 1}: ${message(error)}`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Reject missing scope paths that escape through symlinks

When --allow-missing-in-scope is used and a row such as linked/deleted.ts traverses a repository symlink to an outside directory where the final file is absent, realpathSync raises ENOENT and this branch silently drops the row before checking containment. The replaced implementation resolved missing paths non-strictly and rejected escapes, so a malformed or tampered diff inventory can now pass normalization despite containing an unsafe path; validate the canonical missing path or its existing parent before skipping it.

AGENTS.md reference: AGENTS.md:L30-L33

Useful? React with 👍 / 👎.

const { values } = parseArgs({
args: argv,
options: {
input: { type: "string", multiple: true },

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve the existing multi-file --input form

The replaced command declared --input with nargs="+", so callers can pass --input first.jsonl second.jsonl; Node's parseArgs with multiple: true consumes only one value per occurrence and rejects second.jsonl as an unexpected positional argument. This changes an accepted public invocation during a runtime-language refactor, so retain the one-flag/multiple-files form, optionally in addition to repeated --input flags.

AGENTS.md reference: AGENTS.md:L39-L49

Useful? React with 👍 / 👎.

function readLines(path: string): string[] {
return new TextDecoder("utf-8", { fatal: true })
.decode(readFileSync(path))
.split(/\r?\n/u);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve literal carriage returns in scope paths

On POSIX, an LF-delimited inventory can legitimately contain a filename ending in a literal carriage return, but this split always interprets the resulting \r\n bytes as a line terminator and removes the carriage return. The previous reader deliberately disambiguated CRLF from literal-CR filenames, so candidates for such files are now rejected as out of scope—or a different sibling path can be treated as in scope when both names exist. Preserve the existing path-name behavior while recognizing CRLF input.

AGENTS.md reference: AGENTS.md:L28-L31

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants