Commit Graph
6 Commits
Author SHA1 Message Date
Martin Vogel 6415f94fef fix(packages): put every wrapper and its tests on the same base
Restoring files from two different pre-revert commits left the package wrappers
internally inconsistent, and one of them did not compile. Found by actually
building and running them rather than by grepping for removed symbols.

pkg/npm — bin.js was never restored, so main's version was destructuring
runtimeSetReady/acquireRuntimeLock out of an install.js restored from an older
base that does not export them. `npx codebase-memory-mcp` would have died at
require time on Windows. install.js, bin.js and the launcher test now all sit on
the pre-externalization base, where installWindowsBinaryAtomically is the right
primitive for publishing exactly one file. The runtime-set locking that goes
away with it existed only to publish binary+sidecars atomically.

pkg/go — main.go kept the Windows lock work while main_test.go had been reverted
past it, so the package did not build at all:
  main.go:805: no new variables on left side of :=      (my edit dropped uiPack)
  main_test.go: undefined: windowsPayloadName           (reverted past its removal)
The test is back on main's base, keeping every lock-race test from #1495/#1496
(TestRuntimeSetLock*, TestExpiredLease*, TestStalledRuntimeLockCreator*,
TestRuntimeSetLockSerializesProcesses). Dropped 19 whose premise -- a multi-file
runtime set with content-addressed sidecars -- no longer exists, and reduced the
writeTestRuntimeSet/assertRuntimeTag helpers to the single file that now ships.

pkg/pypi — same base repair, keeping the lock and orphan-reconciliation tests.
The three archive-SAFETY tests (hardlink members, symlink metadata, unexpected
root member) were ADAPTED rather than dropped: they only named a removed file in
their fixtures, and they guard traversal properties that still matter.
test_release_archives_require_the_integrations_sidecar is inverted rather than
deleted -- asserting the sidecar is ABSENT is the stronger guard, since a
returning sidecar is exactly what broke `pip install` on Windows.

Verified: go vet + go build + go test ok; pypi 24 tests OK; npm 10/10;
Windows single-binary bundle contract still passes.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-08-09 17:29:56 +02:00
Martin Vogel 8018561cfe fix(release): externalize runtime assets and harden VT verification
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-08-08 17:35:05 +02:00
Martin Vogel a54ea95719 fix(windows): ship one binary — remove the launcher stub flagged as a dropper
Windows shipped a PAIR: a small permanent launcher (codebase-memory-mcp.exe)
plus the real product binary (codebase-memory-mcp.payload.exe). The launcher
existed for exactly one reason — a running .exe cannot replace its own image
on Windows, so an in-process self-update needs a second resident binary to do
the swap.

That stub is statically indistinguishable from a dropper: a small, unsigned,
zero-prevalence PE whose whole job is verify-and-execute another binary.
Defender's ML scored it Trojan:Win32/Wacatac.B!ml and blocked the v0.9.1-rc.1
release at the VirusTotal gate. It is not fixable in our code on x64 —
bcrypt-free, stripped, VERSIONINFO'd, minimal-resource and even
resource-FREE builds on CI's own MSYS2 CLANG64 toolchain were all flagged,
while the product binary scans clean on every platform.

So remove the stub and move self-update OUT of the process into install.ps1,
which runs while cbm is NOT running: Windows' image lock only blocks a
process from replacing ITSELF.  now prints the exact PowerShell
command (with the Unblock-File hint for Mark-of-the-Web); install.ps1 is
idempotent, so re-running it IS the update — it stops the daemon, renames the
running binary aside (the one mutation Windows permits on a running image),
publishes the new one, and sweeps retired copies.

Windows now matches Linux and macOS: ONE binary per platform.

  * packaging, install.ps1, npm and PyPI wrappers all carry a single binary
  * the launcher/payload ABI contract and ~2500 lines of stub state machinery
    are deleted
  * every daemon start, CLI call and hook fire loses a process spawn, a named
    pipe handshake and an stdio relay
  * test_windows_bundle_contract.sh is rewritten as an INVERTED contract: it
    now asserts no shipped surface can reintroduce a launcher/payload pair,
    and that install.ps1 retires the running binary before publishing

Verified: VirusTotal 0/67 on the packaged binary and 0/58 on install.ps1 (no
certificate involved); macOS and Linux full suites green; Windows guards all
green including the new update-handoff contract; npm 10/10; PyPI 3/3.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-28 17:03:01 +02:00
Martin Vogel 83c137d2a5 feat: complete shared daemon lifecycle
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-18 01:26:08 +02:00
Martin Vogel c1eb3dd2d1 Comprehensive security hardening across all installers
install.sh:
- Wrap entire body in main() to prevent partial execution from curl|bash
  (interrupted download would execute truncated script)

install.ps1:
- Enforce TLS 1.2+ (older PowerShell defaults to TLS 1.0)

PyPI (_cli.py):
- Add SHA256 checksum verification against checksums.txt (was the only
  installer without checksums)

npm (install.js):
- Add SHA256 checksum verification against checksums.txt
- Validate HTTPS on every redirect hop (max 5 redirects)
- Replace execSync string interpolation with execFileSync array args
  (eliminates shell injection vector in tar/PowerShell calls)
- Add path traversal check on extracted binary

npm (bin.js):
- Auto-download binary if missing (handles --ignore-scripts / pnpm)

Go wrapper (main.go):
- Custom HTTP client with CheckRedirect that rejects non-HTTPS redirects
  (Go's default http.Get follows redirects without scheme validation)
- Fix variable name bug in error message (url → rawURL)
2026-04-14 21:00:42 +02:00
DeusData 592be8ea42 Add pkg/ — distribution wrappers for npm, PyPI, Homebrew, Scoop, Winget, Chocolatey, AUR
Introduces pkg/ as a self-contained home for all package registry wrappers.
Each subdirectory is a ready-to-publish package that downloads the appropriate
pre-built binary from GitHub Releases — no source compilation at install time.

- pkg/npm/          — postinstall downloads binary; bin.js shim for CLI
- pkg/pypi/         — lazy download on first run via _cli.py; pipx-friendly
- pkg/homebrew/     — multi-arch formula (darwin/linux × arm64/amd64)
- pkg/scoop/        — Windows bucket manifest with autoupdate + checksum
- pkg/winget/       — v1.6.0 manifests (version + installer + locale)
- pkg/chocolatey/   — nuspec + install/uninstall scripts
- pkg/aur/          — PKGBUILD + .SRCINFO for x86_64 and aarch64

All hashes are real SHA-256 checksums from the v0.6.0 release.
2026-04-12 17:54:53 +01:00