diff --git a/.github/pr-assets/585/after-agent-codex-pool.png b/.github/pr-assets/585/after-agent-codex-pool.png deleted file mode 100644 index f4e0ee41..00000000 Binary files a/.github/pr-assets/585/after-agent-codex-pool.png and /dev/null differ diff --git a/.github/pr-assets/585/after-provider-overview.png b/.github/pr-assets/585/after-provider-overview.png deleted file mode 100644 index 8fb53626..00000000 Binary files a/.github/pr-assets/585/after-provider-overview.png and /dev/null differ diff --git a/.github/pr-assets/585/before-agent-codex-pool.png b/.github/pr-assets/585/before-agent-codex-pool.png deleted file mode 100644 index 620457b1..00000000 Binary files a/.github/pr-assets/585/before-agent-codex-pool.png and /dev/null differ diff --git a/.github/pr-assets/585/before-provider-overview.png b/.github/pr-assets/585/before-provider-overview.png deleted file mode 100644 index 353a6ea8..00000000 Binary files a/.github/pr-assets/585/before-provider-overview.png and /dev/null differ diff --git a/.github/pr-assets/585/index.html b/.github/pr-assets/585/index.html deleted file mode 100644 index 65f0573a..00000000 --- a/.github/pr-assets/585/index.html +++ /dev/null @@ -1,467 +0,0 @@ - - - - - - GoClaw Codex Pool UI Before / After - - - -
-
-
UI Test Visual Report
-

Provider-owned Codex pool UI before / after

-

- This comparison uses two real local GoClaw dashboards seeded with the same fixture data. - The only difference is the code revision: - main@b38a078e versus fix@faf98c73. - The screenshots below isolate the two regressions fixed by the PR: hidden saved pool - membership on provider pages, and sticky custom routing state on agent pages. -

- -
-
-
Before Revision
-
b38a078e
origin/main
-
-
-
After Revision
-
faf98c73
PR branch
-
-
-
Fixture
-
- codex-owner owns pool membership
- codex-disabled is saved as a disabled member
- solo-agent uses codex-solo with no saved pool defaults -
-
-
-
Capture Method
-
- Real local UI via Playwright
- SQLite-backed gateways on separate ports -
-
-
-
- -
-

Scenario 1: provider page hides saved non-ready members

-

- The provider page should show saved pool membership even when an extra account is disabled - or not ready. Before the fix, the page derived membership only from quota-fetched ready - accounts, so the saved member disappeared entirely. -

- -
-
- What was broken on main -

- The pool owner codex-owner had a saved extra member - codex-disabled, but the UI rendered 0 in pool, an empty - account list, and no selectable extra account. -

-
-
- What the patch changes -

- The page now renders membership from the saved provider settings, while still limiting - quota lookups to ready accounts only. The disabled member remains visible and clearly - labeled as blocked. -

-
-
- -
-
-
-
Provider Detail
- Before -
- Before fix: provider detail hides the saved disabled pool member. -
- Main branch behavior: -
    -
  • Available Extra Accounts is effectively empty.
  • -
  • Accounts in Pool shows 0 in pool.
  • -
  • The saved disabled member is invisible, so the provider-owned pool looks unsaved.
  • -
-
-
- -
-
-
Provider Detail
- After -
- After fix: provider detail shows the saved disabled pool member and pool count. -
- Fixed branch behavior: -
    -
  • Codex Disabled is visible in Available Extra Accounts.
  • -
  • Accounts in Pool correctly shows 2 in pool.
  • -
  • The disabled member is still shown as saved, with blocked state clearly surfaced.
  • -
-
-
-
-
- -
-

Scenario 2: agent page manufactured a sticky custom override

-

- When an agent had no explicit routing override and the provider had no saved pool yet, - the UI should have represented that state as inherit / use provider defaults. - Before the fix, the draft model incorrectly materialized it as a saved custom - primary_first + [] state. -

- -
-
- What was broken on main -

- The agent page defaulted to Custom For This Agent and framed the agent as - if it had its own routing policy, even though there was no provider-owned pool and no - explicit agent override saved. -

-
-
- What the patch changes -

- The draft state now preserves a true inherit mode. The UI shows - Use Provider Defaults and clarifies that the agent stays on its primary - account until provider-owned pool members are later added. -

-
-
- -
-
-
-
Agent Codex Pool
- Before -
- Before fix: agent page defaults to Custom For This Agent even with no provider-owned pool. -
- Main branch behavior: -
    -
  • Custom For This Agent is selected by default.
  • -
  • The copy tells the user to configure provider members first before enabling pooled routing.
  • -
  • This makes the implicit default state look like an explicit agent override.
  • -
-
-
- -
-
-
Agent Codex Pool
- After -
- After fix: agent page defaults to Use Provider Defaults and explains the temporary primary-only behavior. -
- Fixed branch behavior: -
    -
  • Use Provider Defaults is selected.
  • -
  • The helper copy explains the temporary primary-only behavior without inventing a custom override.
  • -
  • The agent can stay in inherit mode now and automatically pick up provider pool members later.
  • -
-
-
-
-
- -
- Generated from a real local browser session using two SQLite-backed GoClaw instances. - The frontends were served from separate Vite dev servers, authenticated with - system + a local owner token, and seeded through the HTTP API with the same - provider / agent records before capture. -
-
- - diff --git a/.github/pr-assets/590/index.html b/.github/pr-assets/590/index.html deleted file mode 100644 index 4aa70cd7..00000000 --- a/.github/pr-assets/590/index.html +++ /dev/null @@ -1,790 +0,0 @@ - - - - - - PR #590 — OpenAI Tool Call Compatibility Before / After - - - - -
- - -
-
-
PR #590 • reviewer artifact
-

OpenAI compatibility fix, shown as behavior not prose.

-

- This PR has no product UI. The reviewer surface is wire behavior: - how long tool-call IDs are serialized and how prefixed OpenAI-compatible - model IDs are classified. The visuals below show the exact before/after - deltas that matter for issue #532. -

-
-
-
Primary bug
-
Legacy or replayed tool IDs could alias after a 40-char prefix cut.
-
-
-
Secondary bug
-
Prefixed models like openai/o3-mini bypassed capability gates.
-
-
-
Fix shape
-
Hash long IDs at the serializer boundary and normalize model family once.
-
-
-
Scope
-
Covers main loop, resumed history, memory flush, and subagent replay through one path.
-
-
-
- -
- -

Before: prefix cut preserved length, not uniqueness.

-

- The original defensive fallback capped IDs by slicing the first 40 characters. - That stops the HTTP 400, but it still lets two distinct long IDs collapse into - the same wire value if they only diverge after character 40. -

- -
-
- Why this was still a blocker -

Fresh live tool calls were already hashed upstream, but resumed history and replay paths still depended on the serializer. That meant the bug could survive in exactly the sessions reviewers care about: legacy, resumed, or replayed state.

-
-
- Why the serializer fix is the right layer -

Every OpenAI-compatible request path uses the same request builder. Fixing the boundary closes the main loop and the side loops together instead of patching each caller independently.

-
-
- -
-
-
-
- Before -

Shared-prefix IDs collide after truncation

-
-
-
-
Collision risk remains on replay
-

- Two distinct IDs from a replayed or deduped session can become the same - outbound value. The request is shorter, but the assistant tool calls and - tool results are no longer uniquely identifiable. -

-
{
-  "tool_calls": [
-    { "id": "call_0123456789abcdef0123456789abcdef012" },
-    { "id": "call_0123456789abcdef0123456789abcdef012" }
-  ],
-  "messages": [
-    { "role": "tool", "tool_call_id": "call_0123456789abcdef0123456789abcdef012" },
-    { "role": "tool", "tool_call_id": "call_0123456789abcdef0123456789abcdef012" }
-  ]
-}
-
    -
  • Distinct legacy IDs differ only after byte 40.
  • -
  • Prefix slicing makes both values identical on the wire.
  • -
  • Parallel tool results can no longer be correlated safely.
  • -
-
-
- -
-
-
- After -

Long IDs shorten to stable hashed values

-
-
-
-
40-char cap without aliasing
-

- IDs longer than 40 characters are now re-encoded as deterministic - call_-prefixed hashes. The same original ID always maps - to the same shortened value, and different long IDs stay different. -

-
{
-  "tool_calls": [
-    { "id": "call_6625d2d3e5ec2c6c86f70fd9a7064cc77a1" },
-    { "id": "call_60b8d9101dbdde451723a0888a84317d14f" }
-  ],
-  "messages": [
-    { "role": "tool", "tool_call_id": "call_6625d2d3e5ec2c6c86f70fd9a7064cc77a1" },
-    { "role": "tool", "tool_call_id": "call_60b8d9101dbdde451723a0888a84317d14f" }
-  ]
-}
-
    -
  • Still meets the 40-character API limit.
  • -
  • Preserves assistant/tool-result correlation because the same helper is used for both fields.
  • -
  • Protects replay and legacy sessions, not just newly generated tool calls.
  • -
-
-
-
-
- -
- -

Before: prefixed model IDs skipped the intended reasoning-model rules.

-

- The request builder already supports provider-prefixed IDs such as - openai/o3-mini. The bug was that capability checks ran on the - full string, so prefixed reasoning models could keep temperature - and use the wrong token field. -

- -
-
-
-
- Before -

Prefixed reasoning models look like unknown families

-
-
-
-
Wrong request shape for openai/o3-mini
-

- Because the gate looked at the full model string, the builder missed - both the reasoning-model token routing and the temperature skip. -

-
{
-  "model": "openai/o3-mini",
-  "max_tokens": 123,
-  "temperature": 0.7
-}
-
    -
  • Contradicted the “model-level, not provider-specific” finding.
  • -
  • Left OpenRouter-style OpenAI IDs outside the intended guardrail.
  • -
-
-
- -
-
-
- After -

Capability checks use normalized model family

-
-
-
-
Same rules for bare and prefixed IDs
-

- The builder now strips transport prefixes once, then applies the same - capability logic to both bare and prefixed model IDs. -

-
{
-  "model": "openai/o3-mini",
-  "max_completion_tokens": 123
-}
-
    -
  • openai/o3-mini now follows the same route as o3-mini.
  • -
  • openai/gpt-5.4 still keeps temperature, matching the flagship-model rule.
  • -
  • Azure and non-Azure paths are validated as model-based, not URL-based.
  • -
-
-
-
-
- -
- -

Tests and reviewer-facing outcomes

-

- The changes above were verified with focused provider and agent tests, plus - a full-suite spot check to expose unrelated red tests explicitly rather than - hide them under a green subset. -

- -
-
- Passed -
    -
  • go test ./internal/providers ./internal/agent
  • -
  • go test ./internal/providers -run 'TestTruncateToolCallID|TestBuildRequestBody' -count=1
  • -
  • go test ./internal/agent -run '^TestUniquifyToolCallIDs$' -count=1
  • -
-
-
- Known unrelated failure -

- go test ./... still fails in pkg/browser at - TestResolveRemoteCDP_DefaultPort with - /json/version returned HTTP 404. This pre-exists the provider - changes and is unrelated to the OpenAI compatibility patch. -

-
-
- - -
-
-
- - - - diff --git a/.github/pr-assets/634/after-auth-detail.png b/.github/pr-assets/634/after-auth-detail.png deleted file mode 100644 index 06d65687..00000000 Binary files a/.github/pr-assets/634/after-auth-detail.png and /dev/null differ diff --git a/.github/pr-assets/634/after-channels-list.png b/.github/pr-assets/634/after-channels-list.png deleted file mode 100644 index d1129eba..00000000 Binary files a/.github/pr-assets/634/after-channels-list.png and /dev/null differ diff --git a/.github/pr-assets/634/after-missing-detail.png b/.github/pr-assets/634/after-missing-detail.png deleted file mode 100644 index bf44cc63..00000000 Binary files a/.github/pr-assets/634/after-missing-detail.png and /dev/null differ diff --git a/.github/pr-assets/634/after-overview.png b/.github/pr-assets/634/after-overview.png deleted file mode 100644 index f62afdf2..00000000 Binary files a/.github/pr-assets/634/after-overview.png and /dev/null differ diff --git a/.github/pr-assets/634/before-auth-detail.png b/.github/pr-assets/634/before-auth-detail.png deleted file mode 100644 index 3c653e16..00000000 Binary files a/.github/pr-assets/634/before-auth-detail.png and /dev/null differ diff --git a/.github/pr-assets/634/before-channels-list.png b/.github/pr-assets/634/before-channels-list.png deleted file mode 100644 index d28f8526..00000000 Binary files a/.github/pr-assets/634/before-channels-list.png and /dev/null differ diff --git a/.github/pr-assets/634/before-missing-detail.png b/.github/pr-assets/634/before-missing-detail.png deleted file mode 100644 index 33ec47da..00000000 Binary files a/.github/pr-assets/634/before-missing-detail.png and /dev/null differ diff --git a/.github/pr-assets/634/before-overview.png b/.github/pr-assets/634/before-overview.png deleted file mode 100644 index d5c832fe..00000000 Binary files a/.github/pr-assets/634/before-overview.png and /dev/null differ diff --git a/.github/pr-assets/634/index.html b/.github/pr-assets/634/index.html deleted file mode 100644 index fd943f3b..00000000 --- a/.github/pr-assets/634/index.html +++ /dev/null @@ -1,668 +0,0 @@ - - - - - - PR #634 — Channel Health Diagnostics UI Before / After - - - - -
-
-
Draft PR #634 • Visual Review
-

Channel Health Diagnostics UI Before / After

-

- This evidence pack documents the user-facing impact of the channel-health diagnostics - work for issue #628 and the follow-up UI hardening that landed during review. - The screenshots show the same seeded scenarios before the PR and after the current draft - head, so the deltas are attributable to this branch rather than a different test setup. -

-
-
-
Issue Status
-
Partially solved. The product now explains the failure path, but bad credentials still need operator action.
-
-
-
Screens Compared
-
4 paired captures: overview, channels list, auth detail, missing-credentials detail.
-
-
-
Chosen Direction
-
Shared diagnostics + remediation, not a Telegram-only patch.
-
-
-
Review Hardening
-
Added neutral checking state, safer tab fallback, and no partial-data overcounting.
-
-
-
- -
-

What This PR Proves

-

- The screenshots validate the visible remediation experience. The code changes go a bit - further than the screenshots alone, so the report separates visual proof from the - additional hardening that prevents misleading UI states. -

-
-
- Overview no longer hides the problem -
    -
  • Before: dashboard-level attention existed, but the missing-credentials path was easy to miss.
  • -
  • After: the overview clearly communicates that channel attention exists and aligns with the richer downstream diagnostics.
  • -
-
-
- Channels list now points to action -
    -
  • Before: rows could degrade into vague summaries or omit the useful next step.
  • -
  • After: the row copy names the failure and exposes the remediation action more directly.
  • -
-
-
- Auth failures are diagnosable -
    -
  • Before: the detail page lacked enough structure for a user to understand what failed.
  • -
  • After: the detail page shows what happened, recommended action, credentials entry point, and technical detail.
  • -
-
-
- Config failures are diagnosable -
    -
  • Before: missing credentials did not surface a complete remediation path.
  • -
  • After: the detail page explains the config problem and exposes the credentials action clearly.
  • -
-
-
-
- -
-

Overview

-

- The dashboard summary is the first place a user looks. It now leads toward the richer diagnostics - instead of leaving the channel state effectively opaque. -

-
-
-
-
Overview — Before
-
Before
-
- Overview before channel diagnostics improvements -
- Before: the overview conveyed that attention existed, but it did not make the missing-credentials - path nearly as actionable as the PR now does downstream. -
-
-
-
-
Overview — After
-
After
-
- Overview after channel diagnostics improvements -
- After: the overview aligns with the richer diagnostics flow and no longer relies on the old opaque - failure presentation. -
-
-
-
- -
-

Channels List

-

- This is where the PR most clearly replaces vague channel status with named failures and next-step copy. -

-
-
-
-
Channels List — Before
-
Before
-
- Channels list before channel diagnostics improvements -
- Before: summaries and remediation copy were incomplete. The list did not consistently tell the user - what failed or which action to take next. -
-
-
-
-
Channels List — After
-
After
-
- Channels list after channel diagnostics improvements -
- After: the row naming and next-step prompts are explicit. The UI now makes the channel-health state - actionable rather than just visible. -
-
-
-
- -
-

Auth Failure Detail

-

- This captures the original class of incident from #628: a channel is enabled but blocked by - auth/runtime reality. The page now explains that state instead of flattening it. -

-
-
-
-
Auth Detail — Before
-
Before
-
- Auth failure detail before channel diagnostics improvements -
- Before: the user could land on the channel detail view without enough structure to understand - what happened, what to try next, or where the credentials/debug entry point was. -
-
-
-
-
Auth Detail — After
-
After
-
- Auth failure detail after channel diagnostics improvements -
- After: the page names the auth failure, provides recommended action, exposes the credentials entry - point, and shows technical detail useful for debugging. -
-
-
-
- -
-

Missing Credentials Detail

-

- Missing or incomplete channel configuration now gets the same structured treatment as auth failures. -

-
-
-
-
Missing Credentials — Before
-
Before
-
- Missing credentials detail before channel diagnostics improvements -
- Before: the config failure path was visually thin and did not fully guide the user back to the - required credentials work. -
-
-
-
-
Missing Credentials — After
-
After
-
- Missing credentials detail after channel diagnostics improvements -
- After: the UI names the config problem, explains the credentials requirement, and surfaces the - action path directly on the page. -
-
-
-
- -
-

Additional Hardening Beyond The Screenshots

-

- Review surfaced a few cases where the visible diagnostics could still be misleading. Those are fixed in - code even when they do not have a dedicated screenshot in this pack. -

-
-
- No more false “Stopped” state for unknown-but-enabled channels -
    -
  • Enabled channels without backend status now stay neutral as Checking.
  • -
  • This prevents the UI from manufacturing attention where the runtime has not yet reported anything.
  • -
-
-
- No more partial-data overcounting in overview -
    -
  • Overview attention synthesis only runs when the loaded instance slice is complete.
  • -
  • This avoids claiming more failing channels than the current dataset can justify.
  • -
-
-
- Fallback remediation is channel-specific -
    -
  • zalo_personal now points to re-auth instead of generic credentials repair.
  • -
  • Generic missing-credentials fallback stays on the credentials path with localized copy.
  • -
-
-
- Invalid channel detail tabs fail safely -
    -
  • Unsupported ?tab= values now fall back to general.
  • -
  • Non-Telegram channels can no longer land on the Telegram-only groups tab.
  • -
-
-
-
- -
-

Assertion Snapshot

-

- These structured checks back up the screenshots by recording the UI markers that were present before and after. -

-
-
- Before -
{
-  "overview": {
-    "needsAttention": true,
-    "authChannelVisible": true,
-    "missingChannelVisible": false
-  },
-  "channelsList": {
-    "authSummary": false,
-    "missingSummary": true,
-    "nextStepVisible": true,
-    "credentialsActionVisible": false
-  },
-  "authDetail": {
-    "whatHappened": true,
-    "recommendedAction": true,
-    "reviewCredentials": false,
-    "technicalDetail": false
-  },
-  "missingCredentialsDetail": {
-    "missingCredentials": true,
-    "completeRequiredCredentials": false,
-    "openCredentials": false
-  }
-}
-
-
- After -
{
-  "overview": {
-    "needsAttention": true,
-    "authVisible": false,
-    "missingVisible": false
-  },
-  "channelsList": {
-    "authSummary": true,
-    "missingSummary": false,
-    "reviewCredentials": true,
-    "completeCredentials": true
-  },
-  "authDetail": {
-    "whatHappened": true,
-    "authFailed": true,
-    "recommendedAction": true,
-    "openCredentials": true,
-    "technicalDetail": true
-  },
-  "missingDetail": {
-    "whatHappened": true,
-    "configInvalid": true,
-    "completeCredentials": true,
-    "openCredentials": true,
-    "technicalDetail": true
-  }
-}
-
-
-
- Visual verdict: this PR fixes GoClaw’s product-side diagnosability gap for the seeded auth and config - channel failures. It does not auto-repair invalid credentials, so the incident class from #628 - is better described as diagnosable and actionable, not automatically healed. -
-
-
- - - - diff --git a/.github/pr-assets/671/after-agent-provider-annotated.png b/.github/pr-assets/671/after-agent-provider-annotated.png deleted file mode 100644 index 992fe2d1..00000000 Binary files a/.github/pr-assets/671/after-agent-provider-annotated.png and /dev/null differ diff --git a/.github/pr-assets/671/after-pool-member-annotated.png b/.github/pr-assets/671/after-pool-member-annotated.png deleted file mode 100644 index 344e22d1..00000000 Binary files a/.github/pr-assets/671/after-pool-member-annotated.png and /dev/null differ diff --git a/.github/pr-assets/671/after-pool-member.png b/.github/pr-assets/671/after-pool-member.png deleted file mode 100644 index 3024b1ef..00000000 Binary files a/.github/pr-assets/671/after-pool-member.png and /dev/null differ diff --git a/.github/pr-assets/671/after-pool-owner-unselected-annotated.png b/.github/pr-assets/671/after-pool-owner-unselected-annotated.png deleted file mode 100644 index eee7e1c9..00000000 Binary files a/.github/pr-assets/671/after-pool-owner-unselected-annotated.png and /dev/null differ diff --git a/.github/pr-assets/671/after-pool-owner-unselected.png b/.github/pr-assets/671/after-pool-owner-unselected.png deleted file mode 100644 index 00822f0b..00000000 Binary files a/.github/pr-assets/671/after-pool-owner-unselected.png and /dev/null differ diff --git a/.github/pr-assets/671/after-pool-owner.png b/.github/pr-assets/671/after-pool-owner.png deleted file mode 100644 index 85fa716f..00000000 Binary files a/.github/pr-assets/671/after-pool-owner.png and /dev/null differ diff --git a/.github/pr-assets/671/after-pool-wizard.png b/.github/pr-assets/671/after-pool-wizard.png deleted file mode 100644 index ce900493..00000000 Binary files a/.github/pr-assets/671/after-pool-wizard.png and /dev/null differ diff --git a/.github/pr-assets/671/after-provider-list-annotated.png b/.github/pr-assets/671/after-provider-list-annotated.png deleted file mode 100644 index d56d0538..00000000 Binary files a/.github/pr-assets/671/after-provider-list-annotated.png and /dev/null differ diff --git a/.github/pr-assets/671/before-agent-provider-annotated.png b/.github/pr-assets/671/before-agent-provider-annotated.png deleted file mode 100644 index e408db06..00000000 Binary files a/.github/pr-assets/671/before-agent-provider-annotated.png and /dev/null differ diff --git a/.github/pr-assets/671/before-pool-member-annotated.png b/.github/pr-assets/671/before-pool-member-annotated.png deleted file mode 100644 index 5a346599..00000000 Binary files a/.github/pr-assets/671/before-pool-member-annotated.png and /dev/null differ diff --git a/.github/pr-assets/671/before-pool-member.png b/.github/pr-assets/671/before-pool-member.png deleted file mode 100644 index f46da5f5..00000000 Binary files a/.github/pr-assets/671/before-pool-member.png and /dev/null differ diff --git a/.github/pr-assets/671/before-pool-owner-annotated.png b/.github/pr-assets/671/before-pool-owner-annotated.png deleted file mode 100644 index 72e2183d..00000000 Binary files a/.github/pr-assets/671/before-pool-owner-annotated.png and /dev/null differ diff --git a/.github/pr-assets/671/before-pool-owner.png b/.github/pr-assets/671/before-pool-owner.png deleted file mode 100644 index 92646274..00000000 Binary files a/.github/pr-assets/671/before-pool-owner.png and /dev/null differ diff --git a/.github/pr-assets/671/before-provider-list-annotated.png b/.github/pr-assets/671/before-provider-list-annotated.png deleted file mode 100644 index 765cfa40..00000000 Binary files a/.github/pr-assets/671/before-provider-list-annotated.png and /dev/null differ diff --git a/.github/pr-assets/671/index.html b/.github/pr-assets/671/index.html deleted file mode 100644 index 81d2064d..00000000 --- a/.github/pr-assets/671/index.html +++ /dev/null @@ -1,152 +0,0 @@ - - - - - -PR #671 — Pool Management UX Evidence - - - -
-
-

PR #671 — Pool Management UX

- -
-

- nextlevelbuilder/goclaw#671 · - Closes #670 · - Relates #583 -

- -
-
-

Fix 1 Selector affordance

-

Dashed primary border + icon badge + "Click to add" hint. Unmistakably interactive in both themes.

-
-
-

Fix 2 Stale pool refs

-

Backend skips unknown members instead of blocking saves. Deleted/disabled providers no longer cause errors.

-
-
-

Fix 3 Managed-by banner

-

Pool members now show which pool they belong to, with a direct link to the owner provider.

-
-
-

Fix 4 Pool discovery

-

Per-card "Pool available" badge replaces verbose info banner. One-click wizard to create pools from unpooled accounts.

-
-
-

Fix 5 Provider selector

-

Pool members hidden from agent provider dropdown. Only pool owners listed — routing handles members automatically.

-
-
- -
- Environment: Same GoClaw v2.65.0 instance, dark theme, user kai / tenant Master. - Before = production dashboard (claw:3000). After = local dev server (localhost:5173) with this PR. -
- -
-

1. Pool Owner — Available Accounts Selector

-

Before: bare text, no icon, invisible border in dark mode. After: dashed primary border, + icon badge, "Click to add" label.

-
-
-
Before
- Before: pool owner selector -
-
-
After
- After: pool owner selector with dashed border and plus icon -
-
-
- -
-

2. Pool Member — Managed-By Banner

-

Before: pool section completely hidden, no explanation. After: "Pool Defaults" section shows owner name + clickable link.

-
-
-
Before
- Before: pool member page, no pool section visible -
-
-
After
- After: pool member page with managed-by banner and link -
-
-
- -
-

3. Provider List — Pool Discovery

-

Before: verbose info banner with pool stats took up space. After: clean per-card "Pool available" badge on each unpooled account.

-
-
-
Before
- Before: provider list with verbose info banner -
-
-
After
- After: provider list with per-card Pool available badges -
-
-
- -
-

4. Agent Provider Selector — Pool Members Hidden

-

Before: pool member (codex-secondary) shown as standalone option, no pool indicator. After: member hidden, pool owner shows "Pool" badge so users know it routes to multiple accounts.

-
-
-
Before
- Before: provider dropdown showing pool member as standalone option -
-
-
After
- After: provider dropdown with pool member hidden -
-
-
- -
-

5. Pool Setup Wizard

-

New one-click wizard dialog opened from any "Pool available" badge. Select owner, members, strategy — all in one step.

-
-
-
New
- Pool setup wizard dialog with owner/member selection and strategy toggle -
-
-
-
- - diff --git a/.github/pr-assets/730/after-chat-first-click-raw.png b/.github/pr-assets/730/after-chat-first-click-raw.png deleted file mode 100644 index 038bbb5f..00000000 Binary files a/.github/pr-assets/730/after-chat-first-click-raw.png and /dev/null differ diff --git a/.github/pr-assets/730/after-chat-first-click.png b/.github/pr-assets/730/after-chat-first-click.png deleted file mode 100644 index 47d8e9f2..00000000 Binary files a/.github/pr-assets/730/after-chat-first-click.png and /dev/null differ diff --git a/.github/pr-assets/730/before-chat-first-click.png b/.github/pr-assets/730/before-chat-first-click.png deleted file mode 100644 index ff3679dd..00000000 Binary files a/.github/pr-assets/730/before-chat-first-click.png and /dev/null differ diff --git a/.github/pr-assets/730/index.html b/.github/pr-assets/730/index.html deleted file mode 100644 index 7e33c9b5..00000000 --- a/.github/pr-assets/730/index.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - -PR #730 — fix(chat): first conversation click - - - - - -

fix(chat): load message history on first conversation click

-

PR #730 — Closes #729

- -
-
-

Bug

-

First conversation click from clean state shows empty placeholder instead of messages

-
-
-

Root Cause

-

skipNextHistoryRef unconditionally set on empty→non-empty transition, skipping loadHistory()

-
-
-

Fix

-

Guard skip with expectingRunRef.current — only active during new-chat send flow

-
-
- -
- Same instance (claw:3000 backend), same user (kai/Master), same agent (glm thục bô), same conversation (Chat a95c8ffa), light theme. Callout borders mark the review area. -
- -
-

Chat — First Click from Clean State

-
-
-
BEFORE
- Before: empty placeholder on first click -

Before: Clicking "Chat a95c8ffa" from initial state — conversation highlighted but main area shows "Start a conversation" placeholder. Messages never load.

-
-
-
AFTER
- After: messages load on first click -

After: Same click — conversation messages load immediately. The 5-message history is displayed correctly on first click.

-
-
-
- - diff --git a/.github/pr-assets/748/after-worktree.txt b/.github/pr-assets/748/after-worktree.txt deleted file mode 100644 index f4f3d2a3..00000000 --- a/.github/pr-assets/748/after-worktree.txt +++ /dev/null @@ -1,25 +0,0 @@ -=== RUN TestSetupToolRegistryExecWorkspacePaths -2026/04/07 21:24:13 INFO memory + knowledge graph tools registered (PG-backed) -2026/04/07 21:24:13 INFO web_search tool enabled -2026/04/07 21:24:13 INFO web_fetch tool enabled policy="" blocked=0 -2026/04/07 21:24:13 INFO tts enabled provider=edge auto=off -2026/04/07 21:24:13 INFO tool rate limiting enabled per_hour=150 -2026/04/07 21:24:13 INFO exec approval enabled security=full ask=off -=== RUN TestSetupToolRegistryExecWorkspacePaths/personal_workspace_prefixed_uploads_allowed -2026/04/07 21:24:13 WARN secure_cli.lookup: store is nil, skipping credentialed exec command="printf '%s' file=@\"/var/folders/t9/0cyfylls7d1gdy_6qp8kn2qc0000gn/T/TestSetupToolRegistryExecWorkspacePaths3385685647/001/personal/.uploads/Quarterly Report.png\"" -=== RUN TestSetupToolRegistryExecWorkspacePaths/team_workspace_quoted_input_allowed -2026/04/07 21:24:13 WARN secure_cli.lookup: store is nil, skipping credentialed exec command="printf '%s' --input=\"/var/folders/t9/0cyfylls7d1gdy_6qp8kn2qc0000gn/T/TestSetupToolRegistryExecWorkspacePaths3385685647/001/teams/team-123/Quarterly Report.png\"" -=== RUN TestSetupToolRegistryExecWorkspacePaths/legacy_dotgoclaw_uploads_layout_allowed -2026/04/07 21:24:13 WARN secure_cli.lookup: store is nil, skipping credentialed exec command="cp \"/var/folders/t9/0cyfylls7d1gdy_6qp8kn2qc0000gn/T/TestSetupToolRegistryExecWorkspacePaths3385685647/001/.goclaw/goclaw-workspace/ws/system/uploads/Quarterly Report.png\" \"/var/folders/t9/0cyfylls7d1gdy_6qp8kn2qc0000gn/T/TestSetupToolRegistryExecWorkspacePaths3385685647/002/partner.png\"" -=== RUN TestSetupToolRegistryExecWorkspacePaths/team_workspace_symlink_escape_denied -=== RUN TestSetupToolRegistryExecWorkspacePaths/unrelated_data_dir_path_denied -=== RUN TestSetupToolRegistryExecWorkspacePaths/workspace_local_dotgoclaw_denied ---- PASS: TestSetupToolRegistryExecWorkspacePaths (0.02s) - --- PASS: TestSetupToolRegistryExecWorkspacePaths/personal_workspace_prefixed_uploads_allowed (0.01s) - --- PASS: TestSetupToolRegistryExecWorkspacePaths/team_workspace_quoted_input_allowed (0.00s) - --- PASS: TestSetupToolRegistryExecWorkspacePaths/legacy_dotgoclaw_uploads_layout_allowed (0.01s) - --- PASS: TestSetupToolRegistryExecWorkspacePaths/team_workspace_symlink_escape_denied (0.00s) - --- PASS: TestSetupToolRegistryExecWorkspacePaths/unrelated_data_dir_path_denied (0.00s) - --- PASS: TestSetupToolRegistryExecWorkspacePaths/workspace_local_dotgoclaw_denied (0.00s) -PASS -ok github.com/nextlevelbuilder/goclaw/cmd 0.041s diff --git a/.github/pr-assets/748/before-claw.txt b/.github/pr-assets/748/before-claw.txt deleted file mode 100644 index 72d4dbde..00000000 --- a/.github/pr-assets/748/before-claw.txt +++ /dev/null @@ -1,94 +0,0 @@ -go: downloading github.com/golang-migrate/migrate/v4 v4.19.1 -go: downloading github.com/jackc/pgx/v5 v5.6.0 -go: downloading github.com/google/uuid v1.6.0 -go: downloading github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 -go: downloading github.com/charmbracelet/huh v0.8.0 -go: downloading github.com/spf13/cobra v1.10.2 -go: downloading github.com/bwmarrin/discordgo v0.29.0 -go: downloading golang.org/x/sync v0.19.0 -go: downloading github.com/slack-go/slack v0.19.0 -go: downloading github.com/mattn/go-runewidth v0.0.16 -go: downloading github.com/mymmrac/telego v1.6.0 -go: downloading github.com/fsnotify/fsnotify v1.9.0 -go: downloading github.com/titanous/json5 v1.0.0 -go: downloading github.com/disintegration/imaging v1.6.2 -go: downloading golang.org/x/image v0.27.0 -go: downloading golang.org/x/time v0.14.0 -go: downloading github.com/mark3labs/mcp-go v0.44.0 -go: downloading github.com/adhocore/gronx v1.19.6 -go: downloading github.com/go-rod/rod v0.116.2 -go: downloading github.com/lib/pq v1.10.9 -go: downloading github.com/mattn/go-shellwords v1.0.12 -go: downloading golang.org/x/net v0.49.0 -go: downloading golang.org/x/text v0.33.0 -go: downloading github.com/rivo/uniseg v0.4.7 -go: downloading github.com/catppuccin/go v0.3.0 -go: downloading github.com/charmbracelet/bubbles v0.21.1-0.20250623103423-23b8fd6302d7 -go: downloading github.com/charmbracelet/bubbletea v1.3.6 -go: downloading github.com/charmbracelet/lipgloss v1.1.0 -go: downloading github.com/charmbracelet/x/cellbuf v0.0.13 -go: downloading github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 -go: downloading github.com/mitchellh/hashstructure/v2 v2.0.2 -go: downloading github.com/spf13/pflag v1.0.9 -go: downloading golang.org/x/crypto v0.47.0 -go: downloading golang.org/x/sys v0.42.0 -go: downloading github.com/valyala/fasthttp v1.69.0 -go: downloading github.com/invopop/jsonschema v0.13.0 -go: downloading github.com/spf13/cast v1.7.1 -go: downloading github.com/yosida95/uritemplate/v3 v3.0.2 -go: downloading github.com/dustin/go-humanize v1.0.1 -go: downloading github.com/charmbracelet/x/ansi v0.9.3 -go: downloading github.com/charmbracelet/x/term v0.2.1 -go: downloading github.com/atotto/clipboard v0.1.4 -go: downloading github.com/grbit/go-json v0.11.0 -go: downloading github.com/valyala/fastjson v1.6.7 -go: downloading github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 -go: downloading github.com/muesli/cancelreader v0.2.2 -go: downloading github.com/muesli/termenv v0.16.0 -go: downloading github.com/wk8/go-ordered-map/v2 v2.1.8 -go: downloading github.com/ysmood/goob v0.4.0 -go: downloading github.com/ysmood/got v0.40.0 -go: downloading github.com/ysmood/gson v0.7.3 -go: downloading github.com/ysmood/fetchup v0.2.3 -go: downloading github.com/ysmood/leakless v0.9.0 -go: downloading github.com/andybalholm/brotli v1.2.0 -go: downloading github.com/klauspost/compress v1.18.2 -go: downloading github.com/valyala/bytebufferpool v1.0.0 -go: downloading github.com/jackc/pgpassfile v1.0.0 -go: downloading github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 -go: downloading github.com/jackc/puddle/v2 v2.2.2 -go: downloading github.com/lucasb-eyer/go-colorful v1.2.0 -go: downloading github.com/bahlo/generic-list-go v0.2.0 -go: downloading github.com/buger/jsonparser v1.1.1 -go: downloading github.com/mailru/easyjson v0.7.7 -go: downloading gopkg.in/yaml.v3 v3.0.1 -go: downloading github.com/aymanbagabas/go-osc52/v2 v2.0.1 -go: downloading github.com/mattn/go-isatty v0.0.20 -go: downloading github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc -go: downloading github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e -=== RUN TestSetupToolRegistryExecWorkspacePaths -2026/04/08 01:24:40 INFO memory + knowledge graph tools registered (PG-backed) -2026/04/08 01:24:40 INFO web_search tool enabled -2026/04/08 01:24:40 INFO web_fetch tool enabled policy="" blocked=0 -2026/04/08 01:24:40 INFO tts enabled provider=edge auto=off -2026/04/08 01:24:40 INFO tool rate limiting enabled per_hour=150 -2026/04/08 01:24:40 INFO exec approval enabled security=full ask=off -=== RUN TestSetupToolRegistryExecWorkspacePaths/personal_workspace_prefixed_uploads_allowed - gateway_setup_exec_workspace_test.go:133: denied = true, want false; output = command denied by safety policy: matches pattern /tmp/TestSetupToolRegistryExecWorkspacePaths1657441769/001 -=== RUN TestSetupToolRegistryExecWorkspacePaths/team_workspace_quoted_input_allowed - gateway_setup_exec_workspace_test.go:133: denied = true, want false; output = command denied by safety policy: matches pattern /tmp/TestSetupToolRegistryExecWorkspacePaths1657441769/001 -=== RUN TestSetupToolRegistryExecWorkspacePaths/legacy_dotgoclaw_uploads_layout_allowed - gateway_setup_exec_workspace_test.go:133: denied = true, want false; output = command denied by safety policy: matches pattern /tmp/TestSetupToolRegistryExecWorkspacePaths1657441769/001 -=== RUN TestSetupToolRegistryExecWorkspacePaths/team_workspace_symlink_escape_denied -=== RUN TestSetupToolRegistryExecWorkspacePaths/unrelated_data_dir_path_denied -=== RUN TestSetupToolRegistryExecWorkspacePaths/workspace_local_dotgoclaw_denied ---- FAIL: TestSetupToolRegistryExecWorkspacePaths (0.00s) - --- FAIL: TestSetupToolRegistryExecWorkspacePaths/personal_workspace_prefixed_uploads_allowed (0.00s) - --- FAIL: TestSetupToolRegistryExecWorkspacePaths/team_workspace_quoted_input_allowed (0.00s) - --- FAIL: TestSetupToolRegistryExecWorkspacePaths/legacy_dotgoclaw_uploads_layout_allowed (0.00s) - --- PASS: TestSetupToolRegistryExecWorkspacePaths/team_workspace_symlink_escape_denied (0.00s) - --- PASS: TestSetupToolRegistryExecWorkspacePaths/unrelated_data_dir_path_denied (0.00s) - --- PASS: TestSetupToolRegistryExecWorkspacePaths/workspace_local_dotgoclaw_denied (0.00s) -FAIL -FAIL github.com/nextlevelbuilder/goclaw/cmd 0.019s -FAIL diff --git a/.github/pr-assets/748/claw-live-glm-thuc-bo-before.png b/.github/pr-assets/748/claw-live-glm-thuc-bo-before.png deleted file mode 100644 index b940d58c..00000000 Binary files a/.github/pr-assets/748/claw-live-glm-thuc-bo-before.png and /dev/null differ diff --git a/.github/pr-assets/748/index.html b/.github/pr-assets/748/index.html deleted file mode 100644 index f48afca2..00000000 --- a/.github/pr-assets/748/index.html +++ /dev/null @@ -1,228 +0,0 @@ - - - - - -PR #748 — fix(exec): allow uploaded files in active workspaces - - - - - -

fix(exec): allow uploaded files in active workspaces

-

PR #748 — visual proof pack for issue #739

- -
-
-

Bug

-

Active workspace files under deny-roots were rejected by exec even when they belonged to the current upload/team scope.

-
-
-

Root Cause

-

Path exemptions were static and non-shell-aware, so quoted, prefixed, and legacy screenshot-era upload paths still matched the deny root.

-
-
-

Fix

-

Shell-aware parsing + canonical path checks now exempt the active personal .uploads subtree, the legacy uploads subtree, and the active team workspace.

-
-
- -
- Before source: stable claw:3000 backed by the unfixed /opt/goclaw deployment (v2.7.1). After source: temporary PR deployment on claw:3001, backed by goclaw-pr748:local built from the fixed code commit 83fa1342. Both UI captures use fresh chats with the same user and GLM thục bô. Callout border marks the reviewed exec row. -
- -
-

UI Before / After

-
-
-
Before
-
- Before: stable claw blocks absolute .goclaw upload path -
-

Stable claw release, fresh chat with GLM thục bô: the agent runs the exact absolute /app/.goclaw/.../.uploads/...jpg copy command and the exec row fails with the safety-policy .goclaw/ denial.

-
-
-
After
-
- After: fixed temporary claw deployment allows absolute .goclaw upload path -
-

Temporary fixed deployment on claw:3001, fresh chat with the same agent: the same absolute /app/.goclaw/.../.uploads/...jpg copy command now completes successfully and returns /tmp/partner-abs.png.

-
-
-
- -
-

Gateway Reproduction

-
-
-
Before
-
-
$ ssh claw 'docker run --rm -v /tmp/goclaw-739-before:/src -w /src golang:1.26 sh -lc "/usr/local/go/bin/go test ./cmd -run TestSetupToolRegistryExecWorkspacePaths -count=1 -v"'
-=== RUN   TestSetupToolRegistryExecWorkspacePaths
-=== RUN   TestSetupToolRegistryExecWorkspacePaths/personal_workspace_prefixed_uploads_allowed
-gateway_setup_exec_workspace_test.go:133: denied = true, want false; output = command denied by safety policy: matches pattern /tmp/TestSetupToolRegistryExecWorkspacePaths.../001
-=== RUN   TestSetupToolRegistryExecWorkspacePaths/team_workspace_quoted_input_allowed
-gateway_setup_exec_workspace_test.go:133: denied = true, want false; output = command denied by safety policy: matches pattern /tmp/TestSetupToolRegistryExecWorkspacePaths.../001
-=== RUN   TestSetupToolRegistryExecWorkspacePaths/legacy_dotgoclaw_uploads_layout_allowed
-gateway_setup_exec_workspace_test.go:133: denied = true, want false; output = command denied by safety policy: matches pattern /tmp/TestSetupToolRegistryExecWorkspacePaths.../001
-FAIL
-
-

Baseline source on claw: the exact gateway wiring still rejects all three representative workspace-path forms.

-
-
-
After
-
-
$ go test ./cmd -run TestSetupToolRegistryExecWorkspacePaths -count=1 -v
-=== RUN   TestSetupToolRegistryExecWorkspacePaths
-=== RUN   TestSetupToolRegistryExecWorkspacePaths/personal_workspace_prefixed_uploads_allowed
-=== RUN   TestSetupToolRegistryExecWorkspacePaths/team_workspace_quoted_input_allowed
-=== RUN   TestSetupToolRegistryExecWorkspacePaths/legacy_dotgoclaw_uploads_layout_allowed
---- PASS: TestSetupToolRegistryExecWorkspacePaths (0.01s)
-    --- PASS: personal_workspace_prefixed_uploads_allowed
-    --- PASS: team_workspace_quoted_input_allowed
-    --- PASS: legacy_dotgoclaw_uploads_layout_allowed
-PASS
-
-

Current worktree: the same gateway path handling now passes for personal uploads, team workspace paths, and the screenshot-era legacy .goclaw/.../uploads layout.

-
-
-
- -
-

Supporting Live Recreation on claw

-
- Live claw recreation with GLM thục bô -
-

- This earlier live run documents the same production agent and workspace context on stable claw. The report’s primary Before/After pair above is the clean isolated proof you asked for; this screenshot is kept as supporting context for the reproduction journey. -

-
- -
-

What This Proves

- -
- - diff --git a/.github/pr-assets/748/pr748-after-absolute-goclaw-allowed.png b/.github/pr-assets/748/pr748-after-absolute-goclaw-allowed.png deleted file mode 100644 index 2e36d929..00000000 Binary files a/.github/pr-assets/748/pr748-after-absolute-goclaw-allowed.png and /dev/null differ diff --git a/.github/pr-assets/748/pr748-before-absolute-goclaw-blocked.png b/.github/pr-assets/748/pr748-before-absolute-goclaw-blocked.png deleted file mode 100644 index 6e73455d..00000000 Binary files a/.github/pr-assets/748/pr748-before-absolute-goclaw-blocked.png and /dev/null differ diff --git a/.github/pr-assets/846/after-multi-skill-detected.png b/.github/pr-assets/846/after-multi-skill-detected.png deleted file mode 100644 index e0dde19e..00000000 Binary files a/.github/pr-assets/846/after-multi-skill-detected.png and /dev/null differ diff --git a/.github/pr-assets/846/after-reupload-pre-confirm.png b/.github/pr-assets/846/after-reupload-pre-confirm.png deleted file mode 100644 index 8cce97b1..00000000 Binary files a/.github/pr-assets/846/after-reupload-pre-confirm.png and /dev/null differ diff --git a/.github/pr-assets/846/after-reupload-unchanged.png b/.github/pr-assets/846/after-reupload-unchanged.png deleted file mode 100644 index 4006de2e..00000000 Binary files a/.github/pr-assets/846/after-reupload-unchanged.png and /dev/null differ diff --git a/.github/pr-assets/846/after-skills-list-populated.png b/.github/pr-assets/846/after-skills-list-populated.png deleted file mode 100644 index 1a5efe62..00000000 Binary files a/.github/pr-assets/846/after-skills-list-populated.png and /dev/null differ diff --git a/.github/pr-assets/846/after-upload-complete.png b/.github/pr-assets/846/after-upload-complete.png deleted file mode 100644 index 5e1bfdce..00000000 Binary files a/.github/pr-assets/846/after-upload-complete.png and /dev/null differ diff --git a/.github/pr-assets/846/after-upload-dialog-empty.png b/.github/pr-assets/846/after-upload-dialog-empty.png deleted file mode 100644 index 65db9d06..00000000 Binary files a/.github/pr-assets/846/after-upload-dialog-empty.png and /dev/null differ diff --git a/.github/pr-assets/846/before-custom-empty.png b/.github/pr-assets/846/before-custom-empty.png deleted file mode 100644 index 25535aa0..00000000 Binary files a/.github/pr-assets/846/before-custom-empty.png and /dev/null differ diff --git a/.github/pr-assets/846/dashboard-overview.png b/.github/pr-assets/846/dashboard-overview.png deleted file mode 100644 index 99cc4a6c..00000000 Binary files a/.github/pr-assets/846/dashboard-overview.png and /dev/null differ diff --git a/.github/pr-assets/846/skills-page.png b/.github/pr-assets/846/skills-page.png deleted file mode 100644 index 3e15b427..00000000 Binary files a/.github/pr-assets/846/skills-page.png and /dev/null differ