') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); chore(settings): R7 connection-detail decomposition + byTool aggregation fix — campaign close by jackwener · Pull Request #1254 · apache/maka · GitHub
Skip to content

chore(settings): R7 connection-detail decomposition + byTool aggregation fix — campaign close - #1254

Merged
jackwener merged 5 commits into
mainfrom
chore/arch-round-7-final
Jul 19, 2026
Merged

chore(settings): R7 connection-detail decomposition + byTool aggregation fix — campaign close#1254
jackwener merged 5 commits into
mainfrom
chore/arch-round-7-final

Conversation

@jackwener

Copy link
Copy Markdown
Member

Final round of notes/frontend-architecture-map-2026-07-19.md.

byTool aggregation bug (found by #1252's restyle)

usageStats built byTool per-session (flatMap over sessions) → duplicate tool rows in 工具统计. Fixed in settings-store: session-scoped call↔result id matching (ids only unique per session) with global per-tool-name merging, sorted like the sibling aggregates; byProvider/byModel verified already-correct. Regression test (two sessions sharing a tool → one merged row); IPC-verified on the fixture: 6 unique rows, no duplicates (was ~10).

R7 — provider-connection-detail.tsx decomposition

983 → 373 (−610). The 12-useState controller + single action-guard interlock extracted WHOLE into use-connection-detail.ts (522 L) — the 6 mutually-exclusive actions share one guard, so per-cluster splitting risked drift; plus provider-enabled-model-manager.tsx (187 L) for the roving-tabindex model editor. Every statement moved verbatim, JSX identities literal. model-oauth-section contract re-pinned via a provider combined-source helper (~13 slice terminators widened, view-order slice untouched, nothing deleted). oauth-relogin fixture sheet renders identically (CDP).

Campaign closing numbers (map updated)

main.ts 1903→1175 · app-shell.tsx 1686→1654 · provider-connection-detail 983→373 · visual-smoke god-file → barrel+6 modules · knip 13 hints→0 · 13 auditor fixtures. All 8 rounds shipped across #1241/#1243/#1246/#1248/#1251/#1252/this.

Gates (merged tree): desktop 2744 · ui 196 · storage 396 · typecheck · check-dead-css · knip ×2 = 0 · a11y/copy/console clean · auditor all 13 fixtures. Implemented by an opus worktree agent.

Settings → 使用统计 → 工具统计 repeated tool-name rows (multiple Bash
rows) because byTool was built via sessions.flatMap(toolStatsFromMessages),
producing one aggregate row per tool PER session. byProvider/byModel were
already global (aggregateBy over the flattened modelLogs), so only byTool
was affected.
Replace toolStatsFromMessages with aggregateToolStats(sessions, since):
tool_call.id ↔ tool_result.toolUseId matching stays session-scoped (ids
are only unique within a session) while calls/success/errors/durations
merge into a single row keyed by tool name. Rows sort by call count desc
(tool name tie-break) to match the byProvider/byModel convention and give
deterministic output. Row shape and the sole consumer (UsageToolsPanel)
are unchanged.
Regression test: two sessions each calling Bash (+ one Read) yield one
merged Bash row (calls 2, success 1, errors 1, avg duration 30).
…del manager (arch R7)
provider-connection-detail.tsx was the renderer's densest state cluster
(983 lines, 12 useState in ConnectionDetailInner + a shared keyed action
guard + lifecycle gate). Split following the settings house pattern:
- use-connection-detail.ts (controller hook, ~520 lines): owns the whole
mutually-exclusive action state machine (save / test / fetch-models /
save-enabled-models / set-default / delete, all gated through one
useKeyedActionGuard), the credential-presence probe, the prop-sync
effects, every derived flag, and the pure snapshot/equality helpers +
oauthLoginServiceFor. Returns a controller object; ZERO behavior change,
every identifier and statement moved verbatim.
- provider-enabled-model-manager.tsx (~187 lines): the roving-tabindex
model-list editor (owns query + activeRowId) — an independent cluster.
- provider-connection-detail.tsx (983 -> 373 lines): thin view that
destructures the hook, plus ConnectionEndpointField / the OAuth &
GitHub Copilot re-login notices (kept here as presentation).
The connection/model/test/delete sub-clusters stay in one controller on
purpose: they share a single keyed-action-guard state machine (mutual
exclusion) and one lifecycle/current-ness gate, and cross-call (save
auto-fetches models) — splitting them further would thread the guard and
risk behavior drift.
The connection-detail state machine + helpers moved into
use-connection-detail.ts and the enabled-model editor into
provider-enabled-model-manager.tsx, so the model-oauth-section contract's
ConnectionDetail slices no longer live wholly in the view file.
- provider-contract-source-helpers: join use-connection-detail.ts +
provider-enabled-model-manager.tsx into the combined source, adjacent to
the detail view, so 'function ConnectionDetail ... function
modelIdListsEqual' slices span view + controller contiguously. Added
detailController / enabledModelManager slices to the sources interface.
- model-oauth-section-contract: widen the ConnectionDetail controller
slices' terminator from 'function GitHubCopilotReloginNotice' to
'function modelIdListsEqual(' so handler bodies / derived flags / effects
/ snapshot helpers (now in the hook) are covered; the ConnectionDetailInner
view-order slice is unchanged. Re-point the last-test-message helper
assertion to the combined source (the derivation moved to the controller).
Every behavior invariant is preserved, none deleted.
- web-search-boundary: add the two new renderer files to the scanned set.
Desktop 2744 + ui 196 suites green; knip x2 exit 0.
R7 detail-controller decomposition (983 -> 373) recorded with blade plan,
extraction table, contract re-pins, and gate totals. Closing summary:
main.ts 1903 -> 1175 (R4-R6), provider-connection-detail 983 -> 373 (R7),
visual-smoke split (R3), files-split inventory, and the byTool per-session
aggregation fix shipped alongside.
@jackwener
jackwener merged commit 7878b25 into mainJul 19, 2026
2 of 3 checks passed
xuruiray pushed a commit to xuruiray/maka-agent that referenced this pull request Jul 20, 2026
main's typecheck CI job (Biome check --write=false) fails on this file
since apache#1254; rewrap the two tool_call literals the formatter expects.
Formatting only, no behavior change.
xuruiray pushed a commit to xuruiray/maka-agent that referenced this pull request Jul 20, 2026
main's typecheck CI job (Biome check --write=false) fails on this file
since apache#1254; rewrap the two tool_call literals the formatter expects.
Formatting only, no behavior change.
UncertaintyDeterminesYou4ndMe added a commit to UncertaintyDeterminesYou4ndMe/maka-agent that referenced this pull request Aug 23, 2026
The setup wizard filtered out every provider without a built-in base
URL — an explicit phase-1 scope cut (apache#1254) whose phase-2 base-URL
prompt never landed — and the onboarding protocol had no field to carry
an endpoint anyway, so the three custom relays were creatable from
Desktop but unreachable from the TUI.
List the category:'custom' relays (cloudflare-workers-ai stays out:
its endpoint is an account-id template, not a user-supplied URL), add
a base-URL step to the wizard between provider pick and API key with
host-mirroring local validation, and thread an always-present
'baseUrl: string | null' through connection.onboarding.verify/save —
exact-record wire style like apiKey, normalized by the shared catalog
rules, rejected as base_url_not_configured when a relay has no endpoint
from input, existing connection, or registry. Blank input on an
existing relay reuses its persisted endpoint, mirroring the blank-key
contract.
Discovery runs against the supplied endpoint and commit persists it:
the intent journal gains the field (legacy journals still replay), the
upsert resolves input ?? previous ?? registry default, a URL-only
change still commits, and a swapped endpoint drops relayModelProfiles
and lastTest — the endpoint-keyed contract the update path already
enforces. The onboarding wire shapes are closed schemas, so the
compatibility epoch moves to 37.
Fixesapache#3405
Generated-by: Claude Code
UncertaintyDeterminesYou4ndMe added a commit to UncertaintyDeterminesYou4ndMe/maka-agent that referenced this pull request Aug 23, 2026
The setup wizard filtered out every provider without a built-in base
URL — an explicit phase-1 scope cut (apache#1254) whose phase-2 base-URL
prompt never landed — and the onboarding protocol had no field to carry
an endpoint anyway, so the three custom relays were creatable from
Desktop but unreachable from the TUI.
List the category:'custom' relays (cloudflare-workers-ai stays out:
its endpoint is an account-id template, not a user-supplied URL), add
a base-URL step to the wizard between provider pick and API key with
host-mirroring local validation, and thread an always-present
'baseUrl: string | null' through connection.onboarding.verify/save —
exact-record wire style like apiKey, normalized by the shared catalog
rules, rejected as base_url_not_configured when a relay has no endpoint
from input, existing connection, or registry. Blank input on an
existing relay reuses its persisted endpoint, mirroring the blank-key
contract.
Discovery runs against the supplied endpoint and commit persists it:
the intent journal gains the field (legacy journals still replay), the
upsert resolves input ?? previous ?? registry default, a URL-only
change still commits, and a swapped endpoint drops relayModelProfiles
and lastTest — the endpoint-keyed contract the update path already
enforces. The onboarding wire shapes are closed schemas, so the
compatibility epoch moves to 37.
Fixesapache#3405
Generated-by: Claude Code
UncertaintyDeterminesYou4ndMe added a commit to UncertaintyDeterminesYou4ndMe/maka-agent that referenced this pull request Aug 23, 2026
The setup wizard filtered out every provider without a built-in base
URL — an explicit phase-1 scope cut (apache#1254) whose phase-2 base-URL
prompt never landed — and the onboarding protocol had no field to carry
an endpoint anyway, so the three custom relays were creatable from
Desktop but unreachable from the TUI.
List the category:'custom' relays (cloudflare-workers-ai stays out:
its endpoint is an account-id template, not a user-supplied URL), add
a base-URL step to the wizard between provider pick and API key with
host-mirroring local validation, and thread an always-present
'baseUrl: string | null' through connection.onboarding.verify/save —
exact-record wire style like apiKey, normalized by the shared catalog
rules, rejected as base_url_not_configured when a relay has no endpoint
from input, existing connection, or registry. Blank input on an
existing relay reuses its persisted endpoint, mirroring the blank-key
contract.
Discovery runs against the supplied endpoint and commit persists it:
the intent journal gains the field (legacy journals still replay), the
upsert resolves input ?? previous ?? registry default, a URL-only
change still commits, and a swapped endpoint drops relayModelProfiles
and lastTest — the endpoint-keyed contract the update path already
enforces. The onboarding wire shapes are closed schemas, so the
compatibility epoch moves to 37.
Fixesapache#3405
Generated-by: Claude Code
UncertaintyDeterminesYou4ndMe added a commit to UncertaintyDeterminesYou4ndMe/maka-agent that referenced this pull request Aug 24, 2026
The setup wizard filtered out every provider without a built-in base
URL — an explicit phase-1 scope cut (apache#1254) whose phase-2 base-URL
prompt never landed — and the onboarding protocol had no field to carry
an endpoint anyway, so the three custom relays were creatable from
Desktop but unreachable from the TUI.
List the category:'custom' relays (cloudflare-workers-ai stays out:
its endpoint is an account-id template, not a user-supplied URL), add
a base-URL step to the wizard between provider pick and API key with
host-mirroring local validation, and thread an always-present
'baseUrl: string | null' through connection.onboarding.verify/save —
exact-record wire style like apiKey, normalized by the shared catalog
rules, rejected as base_url_not_configured when a relay has no endpoint
from input, existing connection, or registry. Blank input on an
existing relay reuses its persisted endpoint, mirroring the blank-key
contract.
Discovery runs against the supplied endpoint and commit persists it:
the intent journal gains the field (legacy journals still replay), the
upsert resolves input ?? previous ?? registry default, a URL-only
change still commits, and a swapped endpoint drops relayModelProfiles
and lastTest — the endpoint-keyed contract the update path already
enforces. The onboarding wire shapes are closed schemas, so the
compatibility epoch moves to 37.
Fixesapache#3405
Generated-by: Claude Code
M4n5ter pushed a commit that referenced this pull request Aug 24, 2026
* fix(cli): let the TUI wizard create custom relay connections
The setup wizard filtered out every provider without a built-in base
URL — an explicit phase-1 scope cut (#1254) whose phase-2 base-URL
prompt never landed — and the onboarding protocol had no field to carry
an endpoint anyway, so the three custom relays were creatable from
Desktop but unreachable from the TUI.
List the category:'custom' relays (cloudflare-workers-ai stays out:
its endpoint is an account-id template, not a user-supplied URL), add
a base-URL step to the wizard between provider pick and API key with
host-mirroring local validation, and thread an always-present
'baseUrl: string | null' through connection.onboarding.verify/save —
exact-record wire style like apiKey, normalized by the shared catalog
rules, rejected as base_url_not_configured when a relay has no endpoint
from input, existing connection, or registry. Blank input on an
existing relay reuses its persisted endpoint, mirroring the blank-key
contract.
Discovery runs against the supplied endpoint and commit persists it:
the intent journal gains the field (legacy journals still replay), the
upsert resolves input ?? previous ?? registry default, a URL-only
change still commits, and a swapped endpoint drops relayModelProfiles
and lastTest — the endpoint-keyed contract the update path already
enforces. The onboarding wire shapes are closed schemas, so the
compatibility epoch moves to 37.
Fixes#3405
Generated-by: Claude Code
* fix(cli): carry connection identity through onboarding so custom-slug relays edit in place
The wizard recognized an existing connection only at the derived
canonical slug, so a relay created in Desktop under a custom slug read
as unconfigured in /setup and saving created a second canonical-slug
connection, leaving the old credential and default target behind.
Onboarding inputs now carry 'connectionId: string | null': the catalog
projection resolves the existing connection (canonical slug first, else
the provider type's sole connection), the wizard threads its identity
through verify/save, the coordinator targets it directly (rejecting a
stale id as connection_not_found instead of duplicating), and the
storage upsert finds the row by identity first, preserving its slug.
A stale-snapshot rejection renders without the retype-the-key framing.
Epoch-37 builds from this PR's own review cycle require baseUrl but not
connectionId, so the identity shape gets epoch 38 rather than reusing
37 for a second mutually-undecodable frame.
Generated-by: Claude Code
* fix(runtime-host): bind onboarding discovery to the basis its commit revalidates
Model discovery ran outside the mutation lane and the final commit
re-read latest state, so a concurrent supported policy update could
persist relay B/key B with the inventory discovered from relay A/key A.
Adopt the model-fetch ticket shape: beginConnectionOnboarding locates
the target under the write lane and issues a one-shot WeakMap ticket
whose basis pins the connection revision (covering the endpoint and
every other catalog-visible property), the api-key credential status
plus stored secret from one vault read, and the effective proxy with
its credential — returning the pinned proxy so discovery runs through
the egress the basis certifies rather than re-resolving it. complete
revalidates that basis atomically before the durable intent is written:
drift returns 'superseded' (a new save rejection, riding this PR's
unpublished epoch), a vanished target keeps reporting
connection_not_found, and no journal is written on either.
Verify abandons its ticket (WeakMap-held); save begins its own.
Regression test drives the reviewed race end to end: discovery paused
on relay A/key A, endpoint moved and key rotated concurrently, the save
supersedes with relay B/key B intact and relay A's inventory never
persisted, and a retry commits cleanly.
Generated-by: Claude Code
* fix(runtime-host): send onboarding discovery through the connection's request customization
The onboarding probe went out on the bare transport fetch, while the
models path wraps it with the connection's custom request headers and
body overlay — so a connection that authenticates through a custom
header verified and fetched models fine but failed re-onboarding.
beginConnectionOnboarding now pins the request-headers secret for the
probe and adds its credential status to the ticket's basis, so a header
rotation between discovery and commit supersedes the save the same way
an endpoint or key change does.
Generated-by: Claude Code
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jackwener