Plan 21 / D17 — CLI now remaps legacy types (user/feedback/project/reference) to
canonical (factual/episodic/procedural/semantic). The legacy assertion in
cli-memory-commands.test.ts still expected 'user'; update to expect 'factual'.
Also includes incidental .env.example + docs/ENVIRONMENT.md + qdrant
embedding-models route tweaks captured by F10 audit pass.
New test file stacked-allocation-bar.test.tsx covers:
- empty allocations → null render
- 3 segments with correct widths (50%/30%/20%)
- 1 segment at 100%
- labels without usedSuffix when usage=null
- usedSuffix labels when usage provided (consumed/fairShare%)
- fallback to apiKeyId when keyLabel missing
pool-card.test.tsx updated: mock StackedAllocationBar, assert it renders
when pool.allocations is non-empty.
Added pipelineStepClientRequest/Desc, pipelineStepFormatDetected/Desc,
pipelineStepOpenAIIntermediate/Desc, pipelineStepProviderFormat/Desc,
pipelineStepProviderResponse/Desc, conceptDiagramArrow1-3,
conceptDiagramExampleHub, conceptDiagramHubTooltip,
conceptDiagramSourceTooltip, conceptDiagramTargetTooltip to both
en.json and pt-BR.json.
Extended translator-friendly-i18n-keys.test.ts NEW_KEYS array with all
17 new keys. Test suite now covers 69 keys (was 52) — 172 tests pass.
- tests/unit/custom-cli-config.test.ts: fix ERR_MODULE_NOT_FOUND — stale import path cli-tools → cli-code (regression from F8 git mv, missed by F10 audit because it only ran curated test subset).
- tests/unit/ui/CliAgentsPage.test.tsx: update vi.mock path to current cli-code location (was no-op mock pointing to deleted path).
- tests/unit/ui/CliToolCard.test.tsx: update URL strings /dashboard/cli-tools/claude → /dashboard/cli-code/claude (cosmetic alignment with new routes).
- src/app/(dashboard)/dashboard/cli-code/components/ToolDetailClient.tsx: remove dead case "cliproxyapi" + unused import (no entry in CLI_TOOLS catalog).
- src/app/(dashboard)/dashboard/cli-agents/CliAgentsPageClient.tsx: replace inline div skeleton with shared <CardSkeleton /> for visual consistency with CliCodePageClient.
- src/app/api/cli-tools/{forge,jcode,deepseek-tui,smelt,pi}-settings/route.ts: replace catch (err: any) with catch (err) + (err as NodeJS.ErrnoException).code narrowing (8 instances, eliminates 8 of 11 implicit-any introductions).
Validated: custom-cli-config.test.ts now 3/3 PASS (was 0/1 FAIL with ERR_MODULE_NOT_FOUND); F1/F3 tests 147/147 PASS; UI tests 25/25 PASS; typecheck:core + noimplicit clean.
10 test cases covering: null/empty executionKey guards, null/empty stepId
guards, unknown executionKey no-op, idempotence (double-set true and
true→false), exported function signature assertion, and a white-box
integration scenario that exercises the full path via handleComboChat.
TranslateTab now accepts onInputChange?(text: string) => void. A unified
handleInputChange wrapper calls both setInputText and onInputChange? so
CompressionPreviewAccordion and pipeline Step 1 at the shell level receive
the real input text instead of always seeing an empty string.
TranslatorPageClient passes onInputChange={setSharedInputContent} to wire
the sync. Test files updated to accept the new optional prop in mocks and
verify the callback is wired without throwing.
Add 60 new playground.* keys and 50 new search.* keys to en.json and
pt-BR.json covering Playground Studio tabs (Chat/Compare/API/Build),
config pane, param sliders, presets, improve prompt, export, compare
metrics (TTFT/TPS), Build tab (tools/structured output), and Search Tools
Studio tabs (Search/Scrape/Compare), SearchConceptCard, ProviderCatalog,
ScrapeResult, and config pane fields.
PT-BR has full Portuguese translations. EN has EN strings.
Converts the monolithic memory page into a 3-tab Studio layout
(Memories | Playground | Engine) with URL-driven tab state, 8 new
React components, 2 SWR hooks, 50+ i18n keys, and 8 Vitest unit tests
covering all new components (45/45 passing).
- Move useTranslateSession() to TranslatorPageClient (shell level) for PipelineView to receive real steps
- Build PipelineStep[] from session result (detected/intermediate/translated/response)
- Pass session as prop down to TranslateTab; internal hook kept for isolated test compatibility
- Dedup useProviderOptions: only TranslateTab calls the hook, props pass to SimpleControls
- Remove unused data-advanced-section/data-input-text placeholder (DOM data leak GAP-5)
- Add aria-expanded + aria-controls to AutoFeaturesCard toggle (a11y GAP-2)
Addresses code review RISCO-4, GAP-2, GAP-3, GAP-5.
- store.ts: wrap markMemoryNeedsReindex in safeMarkNeedsReindex helper that swallows
errors when the DB is no longer available (e.g. test teardown after the parent
promise resolved). Prevents fire-and-forget vector upserts from triggering
unhandledRejection in tests.
- memory-store.test.ts: drain setImmediate in afterEach/after hooks so pending
vector upsert tasks settle before DATA_DIR is removed.
- memory-settings.test.ts: extend deepEqual expected shape with the 7 new fields
introduced by plan 21 F5 (embeddingSource, embeddingProviderModel,
transformersEnabled, staticEnabled, rerankEnabled, rerankProviderModel,
vectorStore).
New routes:
- POST /api/memory/retrieve-preview (dry-run playground)
- GET /api/memory/embedding-providers
- GET /api/memory/engine-status
- POST /api/memory/summarize
- POST /api/memory/reindex
- GET/PUT /api/settings/qdrant
- GET /api/settings/qdrant/health
- POST /api/settings/qdrant/search
- POST /api/settings/qdrant/cleanup
Modified:
- PUT /api/memory/[id] added (Hard Rule #12 sanitize)
- /api/memory/route.ts: Hard Rule #12 fix (sanitizeErrorMessage)
- /api/settings/memory/route.ts: MemorySettingsExtendedSchema (D9 7 new fields)
Tests: 7 integration test files (33 tests total) all passing.
Hard Rules #5, #7, #8, #12 verified.