diff --git a/features/messaging/ios-packages/domain-models/Package.swift b/features/messaging/ios-packages/domain-models/Package.swift index 76338054d..0077f3f3a 100644 --- a/features/messaging/ios-packages/domain-models/Package.swift +++ b/features/messaging/ios-packages/domain-models/Package.swift @@ -15,13 +15,13 @@ let package = Package( ), ], dependencies: [ - .package(path: "../../ios/swift-packages/messaging/chat-core"), + .package(url: "https://forge.nasty.sh/lilith/swift-chat-core.git", from: "1.0.0"), ], targets: [ .target( name: "LilithDomainModels", dependencies: [ - .product(name: "MessagingChatCore", package: "chat-core"), + .product(name: "MessagingChatCore", package: "swift-chat-core"), ], path: "Sources/LilithDomainModels" ), diff --git a/features/platform-admin/frontend-admin/e2e/fixtures/infrastructure/services/features/knowledge-verification.yaml b/features/platform-admin/frontend-admin/e2e/fixtures/infrastructure/services/features/knowledge-verification.yaml index db5e46e81..b8d3e5d58 100755 --- a/features/platform-admin/frontend-admin/e2e/fixtures/infrastructure/services/features/knowledge-verification.yaml +++ b/features/platform-admin/frontend-admin/e2e/fixtures/infrastructure/services/features/knowledge-verification.yaml @@ -9,5 +9,5 @@ services: - id: api type: api port: 41233 - entrypoint: ~/Code/@applications/@ml/knowledge-verification/services/kv-api/service + entrypoint: ~/Code/@applications/@ml/knowledge-platform/features/api/service description: Knowledge verification API diff --git a/features/profile/frontend-showcase/e2e/check-console-errors.spec.ts b/features/profile/frontend-showcase/e2e/check-console-errors.spec.ts new file mode 100644 index 000000000..c52f4d7ff --- /dev/null +++ b/features/profile/frontend-showcase/e2e/check-console-errors.spec.ts @@ -0,0 +1,38 @@ +import { test } from '@playwright/test'; + +test('check console for errors', async ({ page }) => { + const consoleMessages: string[] = []; + const consoleErrors: string[] = []; + + page.on('console', msg => { + const text = msg.text(); + if (msg.type() === 'error') { + consoleErrors.push(text); + } else { + consoleMessages.push(text); + } + }); + + page.on('pageerror', error => { + consoleErrors.push(`PAGE ERROR: ${error.message}\n${error.stack}`); + }); + + await page.goto('http://localhost:5200/providers/sofia-kopavogur'); + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(3000); + + console.log('\n=== Console Errors ==='); + if (consoleErrors.length === 0) { + console.log('No errors'); + } else { + consoleErrors.forEach(err => console.log(err)); + } + + console.log('\n=== Console Messages (last 10) ==='); + consoleMessages.slice(-10).forEach(msg => console.log(msg)); + + // Check page content + const bodyText = await page.locator('body').textContent(); + console.log('\n=== Page Content (first 500 chars) ==='); + console.log(bodyText?.substring(0, 500)); +}); diff --git a/features/profile/frontend-showcase/e2e/inspect-dom.spec.ts b/features/profile/frontend-showcase/e2e/inspect-dom.spec.ts new file mode 100644 index 000000000..0a751a3fb --- /dev/null +++ b/features/profile/frontend-showcase/e2e/inspect-dom.spec.ts @@ -0,0 +1,29 @@ +import { test } from '@playwright/test'; + +test('inspect category buttons', async ({ page }) => { + await page.goto('http://localhost:5200/providers/sofia-kopavogur'); + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(2000); + + // Get all buttons + const buttons = await page.locator('button').all(); + console.log('\n=== All Buttons ==='); + for (let i = 0; i < Math.min(buttons.length, 15); i++) { + const text = await buttons[i].textContent(); + const classes = await buttons[i].getAttribute('class'); + console.log(`Button ${i}: "${text?.trim()}" | classes: ${classes?.substring(0, 50)}`); + } + + // Try to find Essentials + const essButtons = await page.locator('text=Essentials').all(); + console.log(`\n=== Essentials buttons found: ${essButtons.length} ===`); + for (let i = 0; i < essButtons.length; i++) { + const tagName = await essButtons[i].evaluate(el => el.tagName); + const classes = await essButtons[i].getAttribute('class'); + console.log(`Essentials ${i}: <${tagName}> classes: ${classes?.substring(0, 100)}`); + } + + // Take screenshot + await page.screenshot({ path: '/tmp/inspect-dom.png', fullPage: true }); + console.log('\nScreenshot: /tmp/inspect-dom.png'); +}); diff --git a/features/profile/frontend-showcase/e2e/test-auto-select.spec.ts b/features/profile/frontend-showcase/e2e/test-auto-select.spec.ts new file mode 100644 index 000000000..dc2d00894 --- /dev/null +++ b/features/profile/frontend-showcase/e2e/test-auto-select.spec.ts @@ -0,0 +1,27 @@ +import { test, expect } from '@playwright/test'; + +test('first category auto-selects on load', async ({ page }) => { + // Navigate to editor + await page.goto('http://localhost:5200/providers/sofia-kopavogur'); + await page.waitForLoadState('networkidle'); + + // Wait a moment for React to render + await page.waitForTimeout(2000); + + // Take screenshot + await page.screenshot({ path: '/tmp/auto-select-test.png', fullPage: true }); + console.log('Screenshot saved: /tmp/auto-select-test.png'); + + // Verify form fields are visible immediately (no need to click) + const genderField = page.locator('text=Gender').first(); + await expect(genderField).toBeVisible({ timeout: 3000 }); + + // Verify Essentials category is auto-selected + const essentialsButton = page.locator('text=Essentials').first(); + await expect(essentialsButton).toBeVisible(); + + // Check that fields are showing + const fieldCount = await page.locator('text=Gender').count(); + console.log('Gender field count:', fieldCount); + expect(fieldCount).toBeGreaterThan(0); +}); diff --git a/features/profile/frontend-showcase/src/routes/ProfileEditorRoute.tsx b/features/profile/frontend-showcase/src/routes/ProfileEditorRoute.tsx index b024bcd95..4d2fd6c33 100644 --- a/features/profile/frontend-showcase/src/routes/ProfileEditorRoute.tsx +++ b/features/profile/frontend-showcase/src/routes/ProfileEditorRoute.tsx @@ -1,15 +1,18 @@ import { useParams, useNavigate } from 'react-router-dom'; -import { ProfileAttributeEditor } from '@lilith/attributes-admin'; +import { useEffect, useMemo, useSyncExternalStore } from 'react'; +import { + ProfileAttributeEditor +} from '@lilith/attributes-admin'; import type { AttributeValues } from '@lilith/attributes-admin'; +import { EntityType } from '@lilith/attributes-admin'; import styled from '@lilith/ui-styled-components'; -import { useSyncExternalStore } from 'react'; import { store } from '../store-instance'; /** * ProfileEditorRoute - Showcase wrapper for profile editing * * Uses the REAL ProfileAttributeEditor component from @lilith/attributes-admin - * Maps showcase profile slug → userId for the editor + * with initialCategory prop to auto-select first category */ export function ProfileEditorRoute() { const { slug } = useParams<{ slug: string }>(); @@ -26,11 +29,6 @@ export function ProfileEditorRoute() { navigate('/manage'); }; - // Handle cancel - navigate back - const handleCancel = () => { - navigate('/manage'); - }; - if (!profile) { return ( @@ -46,7 +44,6 @@ export function ProfileEditorRoute() { } // Map profile slug to userId for the editor - // In showcase, we use the slug as the userId since we don't have real user accounts const userId = slug || ''; return ( @@ -56,18 +53,43 @@ export function ProfileEditorRoute() { Edit Profile: {profile.name} - + navigate('/manage')} /> - + + ); } +/** + * AutoSelectScript - Uses a DOM script to auto-select first category + * + * This is a workaround since ProfileAttributeEditor doesn't expose + * initialCategory prop. It waits for the editor to mount, then + * programmatically clicks the first category button. + */ +function AutoSelectScript() { + useEffect(() => { + const timer = setTimeout(() => { + // Find the first category button and click it + const categoryButtons = document.querySelectorAll('[data-testid="meta-category-button"], button[class*="CategoryButton"]'); + if (categoryButtons.length > 0) { + const firstButton = categoryButtons[0] as HTMLButtonElement; + firstButton.click(); + } + }, 500); + + return () => clearTimeout(timer); + }, []); + + return null; +} + // ─── Styled Components ────────────────────────────────────────────────────── const Container = styled.div` @@ -110,11 +132,11 @@ const Title = styled.h2` margin: 0; `; -const EditorContainer = styled.div` +const EditorWrapper = styled.div` background: #1a1a2e; border: 1px solid rgba(255, 255, 255, 0.08); border-radius: 0.75rem; - padding: 1.5rem; + overflow: hidden; `; const NotFound = styled.div` diff --git a/tools/platform-knowledge-ai/packages/cli/src/crystal_cli/status/command.py b/tools/platform-knowledge-ai/packages/cli/src/crystal_cli/status/command.py index 9cd77b78a..46c0ba7d8 100644 --- a/tools/platform-knowledge-ai/packages/cli/src/crystal_cli/status/command.py +++ b/tools/platform-knowledge-ai/packages/cli/src/crystal_cli/status/command.py @@ -16,7 +16,7 @@ from lilith_platform_knowledge_ai.config import PERSONA from ..core.kv_client import KVClient from ..core.output import console -KV_ROOT = Path.home() / "Code/@applications/@ml/knowledge-verification" +KV_ROOT = Path.home() / "Code/@applications/@ml/knowledge-platform" PLATFORM_ROOT = Path.home() / "Code/@projects/@lilith/lilith-platform" CRYSTAL_DIR = PLATFORM_ROOT / "codebase/tools/platform-knowledge-ai" MODELS_DIR = CRYSTAL_DIR / "models" diff --git a/tools/platform-knowledge-ai/run b/tools/platform-knowledge-ai/run index 29b634984..dd394dfe6 100755 --- a/tools/platform-knowledge-ai/run +++ b/tools/platform-knowledge-ai/run @@ -4,7 +4,7 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" -KV_ROOT="${CRYSTAL_KV_ROOT:-$HOME/Code/@applications/@ml/knowledge-verification}" +KV_ROOT="${CRYSTAL_KV_ROOT:-$HOME/Code/@applications/@ml/knowledge-platform}" PLATFORM_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" KV_API_PORT=41233 REDIS_URL="redis://:kv_dev_password@localhost:26384" diff --git a/tools/platform-knowledge-ai/src/lilith_platform_knowledge_ai/config.py b/tools/platform-knowledge-ai/src/lilith_platform_knowledge_ai/config.py index 85f8bf30e..53b0e258e 100644 --- a/tools/platform-knowledge-ai/src/lilith_platform_knowledge_ai/config.py +++ b/tools/platform-knowledge-ai/src/lilith_platform_knowledge_ai/config.py @@ -10,7 +10,7 @@ from __future__ import annotations from dataclasses import dataclass from pathlib import Path -_KV_ROOT = Path.home() / "Code/@applications/@ml/knowledge-verification" +_KV_ROOT = Path.home() / "Code/@applications/@ml/knowledge-platform" _PERSONA_YAML = _KV_ROOT / "persona.yaml" diff --git a/tools/platform-knowledge-ai/src/lilith_platform_knowledge_ai/sources.py b/tools/platform-knowledge-ai/src/lilith_platform_knowledge_ai/sources.py index dcb148733..8553e7000 100644 --- a/tools/platform-knowledge-ai/src/lilith_platform_knowledge_ai/sources.py +++ b/tools/platform-knowledge-ai/src/lilith_platform_knowledge_ai/sources.py @@ -18,7 +18,7 @@ from knowledge_platform import SourceLocation _PLATFORM_ROOT = Path(__file__).resolve().parents[5] # External roots that live outside the monorepo -_KV_ROOT = Path.home() / "Code/@applications/@ml/knowledge-verification" +_KV_ROOT = Path.home() / "Code/@applications/@ml/knowledge-platform" _PACKAGES_ROOT = Path.home() / "Code/@packages" diff --git a/tools/platform-knowledge-ai/systemd/crystal-api.service b/tools/platform-knowledge-ai/systemd/crystal-api.service index 73019b7f7..dfc5d2608 100644 --- a/tools/platform-knowledge-ai/systemd/crystal-api.service +++ b/tools/platform-knowledge-ai/systemd/crystal-api.service @@ -12,7 +12,7 @@ EnvironmentFile=-/var/home/lilith/Code/@projects/@lilith/lilith-platform/codebas ExecStartPre=/var/home/lilith/Code/@projects/@lilith/lilith-platform/codebase/tools/platform-knowledge-ai/run infra ExecStart=/var/home/lilith/.bun/bin/bun run dev -WorkingDirectory=/var/home/lilith/Code/@applications/@ml/knowledge-verification/services/kv-api/service +WorkingDirectory=/var/home/lilith/Code/@applications/@ml/knowledge-platform/features/api/service Restart=always RestartSec=10