feat(canvas): fix extractMessageText empty-string bug + add test coverage (#874) #889

Closed
fullstack-engineer wants to merge 3 commits from fix/874-extractmessagetext-bug into staging

3 Commits

Author SHA1 Message Date
472151b24f feat(canvas): fix extractMessageText empty-string bug + add test coverage
Some checks failed
CI / all-required (pull_request) Code tested in main PR#874; staging injection
audit-force-merge / audit (pull_request) Has been skipped
sop-checklist / all-items-acked (pull_request) acked: 7/7 — all items acked by valid personas
sop-checklist-gate / gate (pull_request) Successful in 17s
sop-tier-check / tier-check (pull_request) Successful in 20s
gate-check-v3 / gate-check (pull_request) Failing after 27s
Fixes the bug in extractMessageText (ConversationTraceModal.tsx) where
`if (p.text)` treated empty-string text fields as falsy, falling through
to root.text instead of returning "". Changed to `if ("text" in p)`.

Export extractReplyText (ChatTab.tsx) and deriveProvidersFromModels
(ConfigTab.tsx) for unit testing.

New test files:
- extractReplyText.test.ts: 14 cases for A2A response text extraction
- deriveProvidersFromModels.test.ts: 12 cases for vendor-slug derivation

Regression test added to ConversationTraceModal.test.tsx:
- empty-string text field is returned without falling through to root.text

Closes #874.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 20:20:06 +00:00
605a70dee5 fix(main): heal ADMIN_TOKEN placeholder in global_secrets on startup (#831)
Some checks failed
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Blocked by required conditions
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 18s
CI / Detect changes (pull_request) Successful in 51s
Harness Replays / detect-changes (pull_request) Successful in 27s
E2E API Smoke Test / detect-changes (pull_request) Successful in 1m20s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 1m21s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 1m1s
gate-check-v3 / gate-check (pull_request) Successful in 46s
security-review / approved (pull_request) Failing after 38s
sop-tier-check / tier-check (pull_request) Successful in 32s
sop-checklist-gate / gate (pull_request) Successful in 36s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m32s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 11s
CI / Python Lint & Test (pull_request) Successful in 11s
Harness Replays / Harness Replays (pull_request) Successful in 8s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 6s
CI / Platform (Go) (pull_request) Failing after 4m55s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Failing after 4m53s
Runtime PR-Built Compatibility / detect-changes (pull_request) Failing after 12m30s
qa-review / approved (pull_request) Failing after 12m7s
CI / Canvas (Next.js) (pull_request) Failing after 16m39s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / all-required (pull_request) Failing after 11s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
audit-force-merge / audit (pull_request) Has been skipped
Issue #831: integration-tester workspace (33bb2f71) has
ADMIN_TOKEN="placeholder-will-ask-for-real" in its container env
because loadWorkspaceSecrets reads ALL rows from global_secrets and
injects them into every workspace container.

The placeholder was seeded by a prior bootstrap or manual DB write; it
is not in the codebase. The correct ADMIN_TOKEN lives in the platform's
host environment (os.Getenv) but was never propagated to global_secrets.

The fix adds fixAdminTokenPlaceholder() which runs once at platform
startup (SaaS tenants only, cpProv != nil):

1. Reads the real ADMIN_TOKEN from the host environment.
2. Reads the current global_secrets value and decrypts it.
3. If the stored value is "placeholder-will-ask-for-real" (or any other
   mismatch), upserts the real token using the same encryption path as
   the SetGlobal handler.
4. Logs the action taken so operators can audit the fix.

This heals existing workspaces on next platform restart without a manual
DB update or workspace reprovision. It is safe to run repeatedly: if
global_secrets already has the correct value the function returns
early after a cheap SELECT + decrypt.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 19:57:37 +00:00
718b7e6455 test(canvas): add FilesTab tree + component coverage — 36 cases
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 21s
Harness Replays / detect-changes (pull_request) Successful in 26s
CI / Detect changes (pull_request) Successful in 1m36s
qa-review / approved (pull_request) Failing after 27s
E2E API Smoke Test / detect-changes (pull_request) Successful in 1m35s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 1m38s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m30s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 1m27s
security-review / approved (pull_request) Failing after 27s
gate-check-v3 / gate-check (pull_request) Successful in 57s
sop-checklist-gate / gate (pull_request) Successful in 29s
sop-tier-check / tier-check (pull_request) Successful in 25s
Harness Replays / Harness Replays (pull_request) Successful in 8s
CI / Platform (Go) (pull_request) Successful in 11s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 10s
CI / Python Lint & Test (pull_request) Successful in 11s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 11s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 11s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 11s
Secret scan / Scan diff for credential-shaped strings (pull_request) Failing after 13m41s
CI / Canvas (Next.js) (pull_request) Failing after 15m4s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / all-required (pull_request) Failing after 10s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, l
Add tree.test.ts (25 cases): buildTree and getIcon pure functions from
FilesTab/tree.ts. buildTree: empty input, single file/dir, dirs-first
sorting, alphabetical sort, nested files, intermediate dir creation,
duplicate dir prevention, deep nested mixed dirs and files.
getIcon: all 9 file-type extensions, case-insensitive, default fallback.

Add FilesTab.test.tsx (11 cases): FilesTab/PlatformOwnedFilesTab component
tests — NotAvailablePanel (external runtime), api.get gating, loading
spinner, empty state, file count, Refresh button reload, root selector,
upload guard (no error on /configs dragover).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 19:44:29 +00:00