Skip to content

Releases: diyanbogdanov/emend

v0.2.1

Choose a tag to compare

@diyanbogdanov diyanbogdanov released this 07 Oct 16:29
f8b72b0

One fix to Python scanning since 0.2.0. A scan that finds requests.get(...) in your code no longer also reports it as a call to LookupDict.get.

npx emend-cli@latest demo ./emend-demo
npx emend-cli@latest scan ./emend-demo --only zod

Fixed

  • A Python call through an imported module also matched any class method of the same name: every requests.get(...) was reported as a call to LookupDict.get as well. A call whose receiver is a module now matches only that module's own functions. A method called on a module's attribute, such as requests.codes.get("ok"), is still reported, because codes is a LookupDict. (#11)

Full changelog: v0.2.0...v0.2.1

v0.2.0

Choose a tag to compare

@diyanbogdanov diyanbogdanov released this 07 Oct 14:51
5c1edd4

Emend is now MIT-licensed, and emend scan reads Python repositories. 0.1.1 was tagged but never published to npm, so this release also brings its fixes to npm: emend --version answers instead of printing the usage, and the bin path is no longer corrected by npm on publish.

npx emend-cli@latest demo ./emend-demo
npx emend-cli@latest scan ./emend-demo --only zod

Added

  • Python support in emend scan. A repository with uv.lock, poetry.lock, pdm.lock, Pipfile.lock or requirements.txt is scanned the way an npm one is. Dependencies are screened against OSV, each package's public API is diffed between versions, and the changes are located in your own code. Versions are ordered by PEP 440, not semver.

    • requirements.txt is read with its hashed pip-compile output and its -r and -c includes, which are followed only inside the repository.
    • A package's API is read statically from its published wheel; nothing in it runs. A package that publishes only an sdist is skipped rather than built, and so is a wheel PyPI lists at over 256 MiB.
    • Call sites are found under the module names a wheel installs: PyYAML is import yaml. A method call is reported as a lead, not proof.
    • A vulnerable package is reported as imported where your code imports it. When its import names cannot be read, it is reported as "could not be checked", never "not imported".
    • emend fix migrates npm packages only, and refuses a Python finding rather than running npm install for it.

    Where Python support is narrower than TypeScript's: docs/limitations.md#python.

Changed

  • Relicensed from AGPL-3.0-only to MIT. The contributor licence agreement and the commercial-licence offer are gone with it. Both existed only to support dual licensing, and MIT already permits everything the commercial licence sold.
  • emend scan ends its summary with a coverage line per ecosystem that says what the scan actually examined, for example npm: examined 4 package(s) — …. If it examined nothing, the line says npm: no dependencies were analysed.
  • When no verification runner recognises a repository, its skipped phases are labelled typecheck and test, with the reason, instead of npm test. The outcome is unchanged: unverified.

Removed

  • Go vulnerability scanning and symbol-level reachability. Go is removed ahead of Python and Rust support, which plug into a language seam rather than branching inside the detector.

Fixed

  • A pinned self-hosted model works in the harness. --harness=local/<model> used to send the model with no provider block declared, so opencode rejected it (Model not found). It now declares a provider for any self-hosted base URL Emend's own client resolves.
  • A pnpm, yarn or bun finding cited line 1 of its lockfile, with text that appears nowhere in it. It now cites the line the lockfile names the package on.
  • An unreadable lockfile made a repository look as though it had no lockfile, so --vulns screened nothing and said nothing. Examples are a merge-conflict marker in package-lock.json, or a bun.lockb alone. It now says the lockfile could not be read.
  • A vulnerable package that nothing imports cited package-lock.json even in a pnpm, yarn or bun repository that has none. It now cites the lockfile that was actually read.
  • A migration whose tests passed while its typecheck was skipped was summarised as "typecheck and tests are green". It now says types were not checked.

Security

  • Repository files are never read through a link that leads outside the repository. A scanned repository could commit requirements.txt -> /etc/passwd. The file was parsed as requirements and its lines printed back as package names. A linked package.json had its first bytes quoted in a parse error. The file walk also followed links into the pins scanner, detectors, lint tools and call-site resolvers. A file whose real path is outside the repository is now refused and named in a warning. Links that stay inside the repository are still read. This matters most for the hosted GitHub App, which scans repositories it does not control.

Full changelog: v0.1.1...v0.2.0

v0.1.1

Choose a tag to compare

@diyanbogdanov diyanbogdanov released this 14 Aug 14:50

Not published to npm. This version was tagged but never published, so npm went straight from 0.1.0 to 0.2.0, which carries these fixes.

Patch release. 0.1.0 was published to npm before this fix, and npm versions are immutable, so a patch release was the only way to get a version that can answer emend --version onto npm. That happened with 0.2.0.

npx emend-cli@latest scan . --only zod

Fixed

  • emend --version printed the usage and exited 1, in every spelling (version, --version, -v). An install check like emend --version >/dev/null therefore reported a working install as broken. It is the same failure --help had, and it survived that fix because the two were never the same set. The version is now read from the manifest rather than held as a constant, so npm version cannot leave it stale.
  • The bin path dropped its ./ prefix. npm rejects the prefixed form and was silently rewriting the entry on every publish, so the published manifest was one npm had corrected rather than the one in the repository. The package worked, which is why it never surfaced.

Changed

  • README restructured around the scan output, with an npx quick start that needs no API key, and a table stating plainly which uses of Emend carry AGPL obligations — running it on your own code carries none.
  • Reference depth moved into docs/limitations.md and docs/evaluating-the-agent.md rather than removed.
  • The package description now matches the repository's framing; it was the last copy of the old wording, and it is what npm search results are drawn from.

Full changelog: v0.1.0...v0.1.1

v0.1.0

Choose a tag to compare

@diyanbogdanov diyanbogdanov released this 14 Aug 14:42
07c7d63

First tagged release. MVP / proof of concept — TypeScript + npm + GitHub only.

npx emend-cli@latest demo /tmp/d
npx emend-cli@latest scan /tmp/d --only zod

Scanning is fully deterministic and needs no API key. Requires Node 22.6+.

What Emend does

Diffs the published TypeScript declarations of the dependency version you have installed against the one you'd move to, intersects the changed symbols with the call sites in your code, migrates them, and verifies the result against a real baseline before proposing anything. On the demo repo that turns 1,934 breaking changes into 4 that touch the code.

Included

  • emend scan — .d.ts surface diffing crossed with call sites resolved through the TypeScript type checker. No model involved.
  • emend fix — migrations in a throwaway git worktree, with a baseline typecheck+test run before any edit so pre-existing failures are never blamed on the migration. Reports verified / regression / pre-existing-failure / typecheck-only / unverified, and never treats the last three as success.
  • Read-only behaviour review — asks whether a verified change still means the same thing. Its own edits are re-verified and reverted wholesale if they don't hold.
  • --contracts — outbound HTTP calls checked against each vendor's own published OpenAPI description, guarded by provenance, currency and coverage.
  • --vulns — the installed tree screened against OSV.
  • emend pins — version pins duplicated into Dockerfiles, CI matrices and .nvmrc. Refuses to arbitrate where no authority exists. No model involved.
  • emend pr — evidence-rich pull requests. Dry run by default; refuses to open one for a change that didn't verify.
  • emend mcp — seven tools over MCP stdio, each returning what was measured, never a judgement.
  • emend serve — local dashboard, or a hosted GitHub App monitor.
  • emend eval — scores the agent against a corpus, with Pass and Clean as deliberately separate columns.

Honesty rules, enforced in code

unanalyzable ≠ clean · unverified ≠ passing · no test script means typecheck-only · skipped ≠ clean · a run that cannot reach a model repairs nothing and says so.

Every measured case where Emend can be wrong or silent is documented in docs/limitations.md.

Note on the npm package

emend-cli@0.1.0 was published to npm before this tag. The tag additionally contains a fix for emend --version, which previously printed the usage and exited 1. Publish 0.1.1 to bring npm level.