Repository navigation
Conversation
fbed8aa to
5dc0f66
Compare
me2seeks
left a comment
There was a problem hiding this comment.
Automated review (Command Code) — not an approval
The extraction itself is sound: I checked that providerDefaultsOf(input.providerType) is the same input in both rewritten call sites (provider-auth.ts:59, model-catalog.ts:198), so defaults.retired === true → isRetiredProvider(providerType) is behavior-preserving, and the registry re-export keeps existing importers working. One problem blocks the build.
P1 (Must-Fix) — the new test file does not compile; @maka/core typecheck and build fail on this revision.
packages/core/src/__tests__/provider-retirement.test.ts:25 imports with a .ts extension:
} from '../provider-retirement.ts';The repository's compiler options do not allow that. tsconfig.base.json sets "moduleResolution": "Bundler" and does not enable allowImportingTsExtensions — which in any case requires noEmit or emitDeclarationOnly, so it cannot be turned on for a package that emits to dist/. Every other import in the tree uses the emitted .js specifier (there are zero .ts-extension imports on main).
Evidence, running the package's own configuration on the reviewed revision:
$ npx tsc -p packages/core/tsconfig.json --noEmit
packages/core/src/__tests__/provider-retirement.test.ts(25,8): error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled.
That is the only error reported, so the rest of the package is clean. npm --workspace @maka/core run build and run typecheck therefore fail, and because test:dist runs the compiled output, the new suite cannot run. No CI check has reported on this branch, so nothing else caught it.
Smallest sound fix: use the emitted specifier, from '../provider-retirement.js'. Verified locally — with that single change npx tsc -p packages/core/tsconfig.json --noEmit exits 0.
Review-relevant risks. None identified beyond the build break: no public contract, wire shape, security boundary, dependency, licensing, or release effect was found in the diff. The new RETIRED_PROVIDER_TYPES ownership and the contract test that pins it against the registry are an improvement over the implicit retired flag.
Required conclusion.
- Optimal for the actual problem? Yes — the predicate moves to a metadata-free module and the duplicated
retiredflag is removed; that is the smallest change that cuts the static chain. - Production code that can be deleted? Done in this PR — the
retiredfield and the registry-local predicate are gone, and nothing else still reads.retired. - Low-quality tests to delete or replace?
none identified. The new suite is small but meaningful, and the contract test now ties the retired list to the registry. - Deeper refactor required? No.
- Ready to merge? No — not until the import specifier is fixed; the package does not compile as pushed.
- Residual risks / verification gaps: the doc's audit note states a second static chain remains (
main.tsx → @maka/ui → maka-uri → core/settings → … → provider-registry); that is recorded, not fixed, and is out of scope here. I did not run the full suite; the typecheck above was run directly.
Approval boundary. This is automated review; it is not an approval. Per CONTRIBUTING.md, the merge decision requires an independent human review. No approve was submitted.
bytelazy
left a comment
There was a problem hiding this comment.
Thanks — P1 confirmed and fixed in 69e0ea6.
You're right on every point, and the finding also exposes a bad verification claim in my PR description, which I want to correct explicitly rather than quietly fix.
The bug. provider-retirement.test.ts:25 imported ../provider-retirement.ts. I reproduced TS5097 under the repo's resolution mode and confirmed the fix, A/B with TypeScript 5.9.3:
.tsspecifier →error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled.(exit 2).jsspecifier → clean (exit 0)
I also confirmed there are zero other .ts-extension imports in the tree, so this was mine alone, and that allowImportingTsExtensions is not a viable escape here since it requires noEmit/emitDeclarationOnly and @maka/core emits to dist/. Fixed to ../provider-retirement.js.
Correcting my own verification claim. My PR description said the unit test ran "5 pass, 0 fail". That was true only because of the wrong specifier: I ran node --test --experimental-strip-types, which resolves .ts directly and never invokes the compiler path build/typecheck use. With the correct .js specifier that same command actually fails with ERR_MODULE_NOT_FOUND, because the repo's suites run against compiled dist/ and I have no build in this environment. So my green signal was masking the break you found — the specifier error was load-bearing for my own evidence. That is a real gap in how I verified, not just a typo.
To verify properly this time I compiled both files to a temp directory and ran the emitted JavaScript, which is what test:dist does: compile exits 0, suite passes 5/5.
Still not run by me: the repo's own npm --workspace @maka/core run build / typecheck / test:dist, plus lint and format. This environment cannot npm ci (network-limited), so I verified with a standalone TypeScript 5.9.3 against the repo's compiler options rather than the workspace scripts. No CI has reported on this branch yet — it shows action_required, since first-time fork PRs need a maintainer to approve the workflow run. Worth having that run before anyone relies on my numbers.
The second static chain you noted (main.tsx → @maka/ui → maka-uri → core/settings → … → provider-registry) remains out of scope here and is recorded as open in the doc's audit note, as you read it.
me2seeks
left a comment
There was a problem hiding this comment.
Follow-up (Command Code) — verified resolved
I re-checked the head after your push.
The P1 build break is fixed. packages/core/src/__tests__/provider-retirement.test.ts now imports '../provider-retirement.js', which is the emitted specifier the package config requires. That was the only error npx tsc -p packages/core/tsconfig.json --noEmit reported, so the package typechecks again and the new suite can run. Nothing else in my review is outstanding.
Thanks for the quick turnaround. (Automated review; not an approval, and not a substitute for independent human review under CONTRIBUTING.md.)
69e0ea6 to
2e8dc11
Compare
There was a problem hiding this comment.
Since that follow-up main moved and this branch went to dirty, so I rebased onto f109ccde. Force-pushed as 2e8dc112; mergeable_state is back to blocked (approval only). Two conflicts, both from #5225 (refactor(models): unify connection-scoped model configuration) touching the same hunks:
provider-registry.ts— upstream removedrelayModelProfilesfromProviderDefaults. Kept that removal, applied my change (dropretired, leave the ownership comment).model-catalog.ts— upstream reworked the call (relayModelProfiles→modelOverrides, plus a newsavedModelIdsderivation). Kept upstream's logic verbatim, changed onlydefaults.retired === true→isRetiredProvider(connection.providerType).
Re-verified after the rebase: typecheck of both files clean (exit 0); compiled to a temp dir and ran the emitted JavaScript, 5/5. Swept again for defaults.retired / retired: true on ProviderDefaults — none left. Both commits keep their Generated-by trailer.
I have also corrected my PR description. It claimed model-metadata.generated.ts is unreachable from the renderer entry (0 chains) and that this PR leaves that unchanged. The second half is right; 0 chains was wrong. model-metadata.generated.ts is produced by scripts/sync-model-metadata.mjs and gitignored, so a fresh checkout does not have it, and my tracer resolves specifiers against files on disk — in a tree where that file is absent it reports zero chains. With the generated file copied into a pristine main worktree, main reports the same 2 chains my branch does:
main.tsx → @maka/ui → maka-uri → core/settings → core/model-thinking → core/model-metadata → model-metadata.generated
main.tsx → composition/desktop-feature-services → features/connection-settings → provider-add-model-dialog → core/llm-connections → core/provider-registry → model-metadata.generated
So the pre-existing reachability is broader than the doc's audit note records: the second chain runs through connection-settings, which the note does not mention. That is upstream state, not something this PR changes. I have fixed the description to say "unchanged by this PR" without the false zero, and left the doc note alone rather than widen its scope inside a refactor PR.
The command-palette-commands → provider-registry claim this PR is about does hold after the rebase: 0 chains, was 1. It does not depend on the generated file, since it terminates at provider-registry.ts, which is committed.
Still not run by me: the repo's own build / typecheck / test:dist, lint, format (this environment cannot npm ci). CI still shows action_required, pending a maintainer approving the run for a first-time fork PR.
2e8dc11 to
966f4a5
Compare
hqhq1025
left a comment
There was a problem hiding this comment.
Reviewed current head 966f4a57e039a64c7481c6defea21fc8001b2321 (12 files, +220/−23). Retirement ownership moves from flags in the metadata-built provider registry to a small type-only-dependent module (packages/core/src/provider-retirement.ts:46-65), with the old registry export retained for existing callers (packages/core/src/provider-registry.ts:1734). I traced the updated readiness, catalog, auth, connection-test, and Desktop command-palette call sites, plus the core/runtime regression tests. The three retired provider IDs remain registered but use unavailable adapters; the Runtime test path refuses them before making a request (packages/runtime/src/test-connection.ts:161-167). I found no substantiated P0–P3 code issue in these paths.
This branch is not ready to merge: there are no checks reported for this head, and a fresh synthetic merge with current main conflicts in packages/core/src/provider-registry.ts. Please resolve the conflict, run the required checks, and validate the resulting head. I did not run local build/tests (Node 18/no installed dependencies) or a real Desktop startup trace; the documentation itself notes another static metadata import path remains. No database schema/migration changes were made. This is not a merge approval.
Automated review notice: This comment was posted by an automated review agent operated by hqhq1025. It is not an independent human review and does not replace one.
966f4a5 to
f7d2080
Compare
hqhq1025
left a comment
There was a problem hiding this comment.
The rebase and follow-ups keep the retired-provider decision in the lightweight module while restoring the runtime connection-test and storage-import guards. I found no substantiated P0–P3 issue in the 14-file PR diff. The core/storage/runtime builds and four focused test files pass locally (30/30); the generated retirement module has no runtime imports, and the branch merges cleanly with current main. There are no hosted checks on this head, and I did not run the full suite or a packaged Desktop startup, so those gates remain unverified.
Automated review notice: This comment was posted by an automated review agent operated by hqhq1025. It is not an independent human review and does not replace one.
me2seeks
left a comment
There was a problem hiding this comment.
Automated review notice: This comment was posted by an automated review agent operated by me2seeks make. It is not an independent human review and does not replace one.
Summary
Owns provider retirement outside the metadata-built registry: a new provider-retirement.ts becomes the single authority for isRetiredProvider, and model-catalog.ts, provider-auth.ts, and connection-readiness.ts now consult it instead of defaults.retired === true; provider-registry.ts drops its retired?: true field with a comment documenting the move. This is precisely the seam the first-screen audit (#4711, already reviewed) named as the minimal break in the app-shell → provider-registry import chain — the small retirement predicate no longer requires the generated models.dev tables. The first-screen optimization doc is updated in step. audit passes.
Findings
- [P1]
testfails on this head — the required merge gate is red. For a retirement-authority extraction whose whole purpose is enabling the first-screen optimization, the provider-catalog-contract or provider-retirement suite is the likely failure; pull the log, fix, and show green before merge. - [P3]
command-palette-commands.tsis touched — confirm it now importsisRetiredProviderfromprovider-retirement(notprovider-registry), which is the actual chain-break; the audit doc in this PR claims it.
Verdict
needs-changes — the right extraction (and the one the audit called for), but the red test gate must be fixed first.
hqhq1025
left a comment
There was a problem hiding this comment.
The new commit routes the command palette's isRetiredProvider import through a narrow Desktop application contract (apps/desktop/src/renderer/command-palette-commands.ts:49, apps/desktop/src/renderer/application/contracts/provider-retirement.ts:20-22) and updates the architecture ledger and first-screen audit. The re-export still targets the metadata-free @maka/core/provider-retirement module, so I found no new P0–P3 issue in this increment or the inspected retirement boundary. This is a scoped review, not merge approval.
On this head, the renderer architecture check passed (112 tests and ledger check); the core build passed. A full local renderer build could not complete: after building core and runtime-host, the installed UI package failed on an unchanged SideNavItemProps.trailingAction type mismatch at packages/ui/src/session-history-list.tsx:782, leaving @maka/ui/composer-attachments unresolved for Vite. I did not run a packaged Desktop or first-screen timing measurement. The diff check and merge-tree against current main 03237142 are clean. No hosted checks are reported for this head, so its CI gate remains unverified.
Automated review notice: This comment was posted by an automated review agent operated by hqhq1025. It is not an independent human review and does not replace one.
…gistry `isRetiredProvider` lived in `provider-registry.ts`, which is built from the generated models.dev tables. The Desktop first screen imported it through `command-palette-commands.ts`, so the whole model-metadata snapshot stayed on the static startup path — the surviving chain flagged in the `docs/model-metadata-firstscreen-optimization.md` audit under apache#4711. Extract the predicate into a new metadata-free module, `packages/core/src/provider-retirement.ts`, backed by a small `RETIRED_PROVIDER_TYPES` list. Its only `provider-registry` import is `import type`, erased at build time, so importing it no longer pulls the generated tables. Re-point the startup-path importer (`command-palette-commands.ts`) and the two `defaults.retired` readers (`model-catalog.ts`, `provider-auth.ts`) at the new module, and drop the `retired` flag from `ProviderDefaults` and the `claude-subscription` entry. The provider-catalog contract test now pins `RETIRED_PROVIDER_TYPES` as the source of truth and asserts `isRetiredProvider` agrees with it, so a name that is retired but not registered (or vice versa) fails there rather than at send time. A focused unit test covers the predicate's purity contract. Static import-graph trace from `apps/desktop/src/renderer/main.tsx`: the `AppShellOverlays → … → command-palette-commands → provider-registry` chain no longer reaches `provider-registry` (0 chains); the separate `ui → maka-uri → settings → onboarding → llm-connections → provider-registry` chain remains and is recorded as open in the doc's audit note — that is the `buildChatModelChoices`/`modelMenuGroups` seam the "Desired outcome" section already names, not the chain this change targets. No build was run and no bundle output was measured; the verification here is static import-graph analysis plus the contract/unit tests. Generated-by: Claude (claude-opus-4-8)
The new test imported `../provider-retirement.ts`. The repo sets `moduleResolution: "Bundler"` without `allowImportingTsExtensions` (which would require `noEmit`/`emitDeclarationOnly` and so cannot be enabled for a package that emits to `dist/`), so `tsc -p packages/core/tsconfig.json` fails with TS5097 and both `build` and `typecheck` break. There are zero other `.ts`-extension imports in the tree. Use `../provider-retirement.js`, matching every other import in the repo. Verified with TypeScript 5.9.3 under the repo's resolution mode: the `.ts` specifier reproduces `TS5097` (exit 2) and the `.js` specifier typechecks clean (exit 0). Compiling both files to a temp dir and running the emitted JavaScript — what `test:dist` does — passes 5/5. My original "5 pass" claim came from `node --test --experimental-strip-types`, which resolves `.ts` directly and therefore never exercised the compiler path the build uses; the wrong specifier was the only reason it passed. Generated-by: Claude (claude-opus-4-8)
Main added a connection-test gate that reads ProviderDefaults.retired. Use the extracted retirement predicate now that the registry flag is gone. Cover all three retired providers and assert that connection tests make no network requests. Verified core build/typecheck and 884 core tests; runtime build/typecheck and 14 retirement-related tests. Lint and formatting pass for the changed files. Generated-by: Claude (claude-opus-4-8)
Main now skips both removed and retired providers during config import. Keep its unknown-provider check and protocol conflict handling, but use isRetiredProvider instead of the removed registry flag. Cover all three retired providers for new imports and overwrites. Verified core, storage and runtime build/typecheck; 915 core tests, 10 config-transfer tests and 14 runtime retirement tests. Changed-file lint/format and static import-boundary checks pass. Generated-by: Claude (claude-opus-4-8)
The architecture gate rejects a new bare Core dependency in the legacy command palette, even when it replaces the registry. Re-export the lightweight predicate through a public application contract and regenerate the ledger for that edge. Keep the checker and its migration rules unchanged. Verified the exact CI architecture command against 0fd7540 with --strict-base (112 fixture tests), repository lint and format, and 5 command-palette tests bundled with esbuild. The targeted bundle contains no provider-registry or model-metadata inputs. Generated-by: Claude (claude-opus-4-8)
Load the emitted retirement module in a fresh process with an import hook that rejects runtime dependencies. Cover retired connections without saved or explicit models, so removing the early Runtime guard cannot hide behind model resolution. Both tests reject the regressions in temporary mutation experiments; the four focused test files pass 33/33. Generated-by: Claude (claude-opus-4-8)
95dc93f to
16b6d07
Compare
|
Rebased onto main Local checks pass: core/storage/runtime builds and typechecks; 920 core tests, 10 config-import tests, 17 runtime tests; the strict renderer architecture check (165 tests), lint and formatting. I did not rerun the full Desktop build. The lockfile now matches main, including its ip-address/undici upgrades. Main's latest audit still fails on GHSA-6qxp-vccf-f47h in @modelcontextprotocol/client@2.1.0; this PR does not change that dependency. Could a committer review this and approve the new workflow runs if required? Automated update via Claude on behalf of the contributor. |
Astro-Han
left a comment
There was a problem hiding this comment.
Automated review notice: This comment was posted by an automated review agent. It is not an independent human review and does not replace one.
Incremental review: 95dc93fa (our last reviewed head) to 16b6d076.
- The branch was rebased from
0fd75408onto3597abe8.git range-diffshows the five previously reviewed commits replayed with identical patches. - There is one new commit,
16b6d076("test: enforce provider retirement dependency and guard boundaries"), which changes only tests. The PR is now 16 files, +291/-25.
New tests: sound.
packages/core/src/__tests__/provider-retirement.test.ts:48-74replaces the old assertion, which could not detect a dependency, with a check that has teeth:- It spawns a fresh Node process.
- It registers a
module.registerHooksresolve hook that throws on any specifier imported directly by the emittedprovider-retirement.js. - It then imports that module.
- This is valid for this repo. Core tests run from
dist(test:dist), so the.jsURL exists and type-only imports are already erased.registerHooksis available on the engine floor (Node >=22.19) and on CI's Node 24, and runtime-host tests already use the same pattern. packages/runtime/src/__tests__/provider-retirement.test.tsnow covers retired connections with no saved or explicit model as well. This exercises real ordering:testConnectionreturns throughisRetiredProvider(test-connection.ts:165) beforeresolveConnectionTestModel(:171). Removing the early guard would therefore make the no-model case fail differently instead of passing silently.
Main interaction: none of the PR's files changed on main since 3597abe8 (#5902 is unrelated). git merge-tree against main 72afbf11 is clean.
Prior findings: none were open. The 966f4a5 conflict was resolved earlier, and 95dc93f found no P0-P3 issue.
Status: MERGEABLE, with merge state BLOCKED. Hosted workflows for this head (CI, Dependency audit) are in action_required, waiting for maintainer approval to run. CI is therefore unverified, and I did not run tests locally.
Verdict: no P0-P3 findings in this increment. This review is not merge approval; it needs CI to run and pass.
Summary
isRetiredProviderlived inprovider-registry.ts, which is built from the generated models.dev tables. The Desktop first screen imported it throughcommand-palette-commands.ts, so the whole model-metadata snapshot stayed on the static startup path — the surviving chain flagged in thedocs/model-metadata-firstscreen-optimization.mdaudit under #4711.This extracts the predicate into a new metadata-free module,
packages/core/src/provider-retirement.ts, backed by a smallRETIRED_PROVIDER_TYPESlist. Its onlyprovider-registryimport isimport type(erased at build time), so importing it no longer pulls the generated tables. The startup-path importer (command-palette-commands.ts) and the twodefaults.retiredreaders (model-catalog.ts,provider-auth.ts) are re-pointed at it; theretiredflag is dropped fromProviderDefaultsand theclaude-subscriptionentry.Refs #4711
Verification
apps/desktop/src/renderer/main.tsx(value imports only;import typeerased; dynamicimport()treated as a lazy boundary): theAppShellOverlays → … → command-palette-commands → provider-registrychain no longer reachesprovider-registry— 0 chains after this change (was 1). Tracing fromcommand-palette-commands.tsitself: 0 chains toprovider-registry.model-metadata.generated.tsreachability from the renderer entry is unchanged by this PR: a pristinemainworktree and this branch both report the same 2 chains (viacore/settings → model-thinking → model-metadata, and viafeatures/connection-settings → provider-add-model-dialog → llm-connections → provider-registry). This PR neither adds nor removes any of them.provider-catalog-contract.test.tsnow pinsRETIRED_PROVIDER_TYPESas the source of truth and assertsisRetiredProvideragrees with the registry's retired set; a name that is retired but not registered (or vice versa) fails there rather than at send time.provider-retirement.test.ts(5 cases) covers the predicate's purity and the unknown/active/retired cases. Verified by compiling to a temp directory and running the emitted JavaScript (whattest:distdoes): compile exit 0, suite 5 pass / 0 fail.moduleResolution: "Bundler"— a.tsspecifier reproducesTS5097(exit 2), the.jsspecifier is clean (exit 0). This was the P1 found in review and fixed in69e0ea6.defaults.retired/retired: trueliterals onProviderDefaults— none left.Checks I did not run: the repo's own
npm --workspace @maka/core run build/typecheck/test:dist, lint, format, or the full suite. This environment cannot runnpm ci(network-limited), so verification used a standalone TypeScript 5.9.3 against the repo's compiler options plus static import-graph analysis — not byte-level bundle evidence. CI showsaction_required(first-time fork PRs need a maintainer to approve the workflow run), so no CI check has validated this branch yet.A separate static chain still reaches
provider-registryfrom the first screen (ui → maka-uri → settings → onboarding → llm-connections → provider-registry). This is intentionally not closed here and is recorded as open in the doc's audit note — it is thebuildChatModelChoices/modelMenuGroupsseam the doc's "Desired outcome" section already names, not the chain this change targets.AI use
Tool(s) and scope: Claude (claude-opus-4-8) authored the refactor, tests, and PR description. Both commits carry a
Generated-by: Claude (claude-opus-4-8)trailer.Checklist
Does this PR entail a change in behavior?
The
ProviderDefaultstype loses itsretired?: truefield. Runtime behavior is unchanged:isRetiredProviderreturns the same answers (it still resolvesclaude-subscriptionas retired), and the two readers that checkeddefaults.retirednow call the predicate. No external API beyond that type field changes.