Mirrors the skills refactor: company-portability was the second user of
the per-host REST shim (its own parallel parseGitHubSourceUrl + fetch
helpers + raw.githubusercontent URL builder), so importing a company
package from a non-github URL hit the same Gitea 404 the skills path did.
- Extend git-source.ts:
- parseGitSourceUrl: also recognises query-string shape
(?ref=...&path=...) used by portability URLs, with precedence over
path-style segments when both are present.
- RepoSnapshot: add readBinary (Uint8Array for the company logo
fetch) and readFileOptional (null on NotFoundError, for the
COMPANY.md probe + main->master fallback).
- Rewrite resolveSource in company-portability.ts to open a single
in-memory snapshot per import and serve all reads (COMPANY.md,
candidate tree, includes, logo) from it. Drops fetchText/fetchJson/
fetchBinary/fetchOptionalText.
- parseGitHubSourceUrl stays exported with its original return shape
({hostname, owner, repo, ref, basePath, companyPath}) so the existing
test suite passes unchanged. It now delegates URL parsing to
parseGitSourceUrl and layers companyPath derivation on top.
- Delete server/src/services/github-fetch.ts: zero remaining callers.
Test coverage:
- 7 new git-source tests (query-string parse variants, query-string
precedence over path style, readBinary, readFileOptional NotFound
null + non-NotFound rethrow) — 34/34 passing.
- 52 existing company-portability tests still pass via the
parseGitHubSourceUrl shim contract.
- Smoke-tested end-to-end against https://git.farh.net/.../?ref=main:
ref resolves, snapshot opens, readFile/readBinary/readFileOptional
all return expected results.
Note: two pre-existing failures in company-skills-routes.test.ts
("does not expose a skill reference...") exist on dev too and are
unrelated to this change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
27 tests covering the surface that had none:
- parseGitSourceUrl: bare URLs (github/gitea/gitlab), tree/blob/src
shapes, subpaths, file paths, trailing .git stripping, https-only
enforcement, malformed/missing-segment rejection.
- resolveGitRef: 40-hex SHA passthrough (no network call), default
branch via HEAD symref, named branch, peeled annotated tag, lightweight
tag, ref-not-found, network/401/404 error translation, onAuth
callback shape (token-as-username, x-oauth-basic) and absence.
- openRepoSnapshot: clone args (singleBranch/depth=1/noCheckout),
tree walk filtering trees vs blobs, readFile path, SHA fallback
when tracking ref is null, 404 translation.
Mocks at the isomorphic-git boundary; verifies our adaptation logic,
not isomorphic-git itself.
Known limit surfaced by a test (not fixed here): gitea URLs with
slash-containing branch names like /src/branch/feature/x are
ambiguous without server-side disambiguation. The test uses a
single-segment branch; the multi-segment case needs a separate fix
(refCandidates from longest-to-shortest, resolved against
listServerRefs output).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>