diff --git a/apps/calendar/apps/web/package.json b/apps/calendar/apps/web/package.json
index 39775e513..3d68fc541 100644
--- a/apps/calendar/apps/web/package.json
+++ b/apps/calendar/apps/web/package.json
@@ -49,8 +49,7 @@
"@manacore/shared-auth-ui": "workspace:*",
"@manacore/shared-branding": "workspace:*",
"@manacore/shared-error-tracking": "workspace:*",
- "@manacore/shared-feedback-service": "workspace:*",
- "@manacore/shared-feedback-ui": "workspace:*",
+ "@manacore/feedback": "workspace:*",
"@manacore/shared-i18n": "workspace:*",
"@manacore/shared-help-types": "workspace:*",
"@manacore/shared-help-ui": "workspace:*",
diff --git a/apps/calendar/apps/web/src/lib/services/feedback.ts b/apps/calendar/apps/web/src/lib/services/feedback.ts
index de6a8a6d0..e4032e017 100644
--- a/apps/calendar/apps/web/src/lib/services/feedback.ts
+++ b/apps/calendar/apps/web/src/lib/services/feedback.ts
@@ -3,7 +3,7 @@
*/
import { browser } from '$app/environment';
-import { createFeedbackService } from '@manacore/shared-feedback-service';
+import { createFeedbackService } from '@manacore/feedback';
import { authStore } from '$lib/stores/auth.svelte';
// Get auth URL dynamically at runtime
diff --git a/apps/calendar/apps/web/src/routes/(app)/feedback/+page.svelte b/apps/calendar/apps/web/src/routes/(app)/feedback/+page.svelte
index 580947375..cced1cd54 100644
--- a/apps/calendar/apps/web/src/routes/(app)/feedback/+page.svelte
+++ b/apps/calendar/apps/web/src/routes/(app)/feedback/+page.svelte
@@ -1,5 +1,5 @@
diff --git a/apps/chat/apps/server/package.json b/apps/chat/apps/server/package.json
new file mode 100644
index 000000000..e1b371f74
--- /dev/null
+++ b/apps/chat/apps/server/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "@chat/server",
+ "version": "0.1.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "bun run --watch src/index.ts",
+ "start": "bun run src/index.ts"
+ },
+ "dependencies": {
+ "@manacore/shared-hono": "workspace:*",
+ "hono": "^4.7.0",
+ "drizzle-orm": "^0.38.3",
+ "postgres": "^3.4.5"
+ },
+ "devDependencies": {
+ "typescript": "^5.9.3"
+ }
+}
diff --git a/apps/chat/apps/server/src/index.ts b/apps/chat/apps/server/src/index.ts
new file mode 100644
index 000000000..d1cbd96c2
--- /dev/null
+++ b/apps/chat/apps/server/src/index.ts
@@ -0,0 +1,136 @@
+/**
+ * Chat Hono Server — LLM completions (sync + streaming)
+ *
+ * CRUD for conversations/messages handled by mana-sync.
+ * This server handles AI completions via mana-llm or OpenRouter.
+ */
+
+import { Hono } from 'hono';
+import { cors } from 'hono/cors';
+import { streamSSE } from 'hono/streaming';
+import { authMiddleware, healthRoute, errorHandler, notFoundHandler } from '@manacore/shared-hono';
+import { consumeCredits, validateCredits } from '@manacore/shared-hono/credits';
+
+const PORT = parseInt(process.env.PORT || '3002', 10);
+const LLM_URL = process.env.MANA_LLM_URL || 'http://localhost:3025';
+const OPENROUTER_KEY = process.env.OPENROUTER_API_KEY || '';
+const CORS_ORIGINS = (process.env.CORS_ORIGINS || 'http://localhost:5173').split(',');
+
+const app = new Hono();
+
+app.onError(errorHandler);
+app.notFound(notFoundHandler);
+app.use('*', cors({ origin: CORS_ORIGINS, credentials: true }));
+app.route('/health', healthRoute('chat-server'));
+app.use('/api/*', authMiddleware());
+
+// ─── Chat Completion (sync) ──────────────────────────────────
+
+app.post('/api/v1/chat/completions', async (c) => {
+ const userId = c.get('userId');
+ const { messages, model, temperature, maxTokens } = await c.req.json();
+
+ if (!messages?.length) return c.json({ error: 'messages required' }, 400);
+
+ const isLocal = !model || model.startsWith('ollama/') || model.startsWith('local/');
+ const cost = isLocal ? 0.1 : 5;
+
+ const validation = await validateCredits(userId, 'AI_CHAT', cost);
+ if (!validation.hasCredits) {
+ return c.json({ error: 'Insufficient credits', required: cost }, 402);
+ }
+
+ try {
+ const llmRes = await fetch(`${LLM_URL}/api/v1/chat/completions`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({
+ messages,
+ model: model || 'gemma3:4b',
+ temperature: temperature || 0.7,
+ max_tokens: maxTokens || 2000,
+ }),
+ });
+
+ if (!llmRes.ok) return c.json({ error: 'LLM request failed' }, 502);
+
+ const data = await llmRes.json();
+ await consumeCredits(userId, 'AI_CHAT', cost, `Chat: ${model || 'gemma3:4b'}`);
+
+ return c.json(data);
+ } catch (_err) {
+ return c.json({ error: 'Chat completion failed' }, 500);
+ }
+});
+
+// ─── Chat Completion (streaming SSE) ─────────────────────────
+
+app.post('/api/v1/chat/completions/stream', async (c) => {
+ const userId = c.get('userId');
+ const { messages, model, temperature, maxTokens } = await c.req.json();
+
+ if (!messages?.length) return c.json({ error: 'messages required' }, 400);
+
+ const isLocal = !model || model.startsWith('ollama/') || model.startsWith('local/');
+ const cost = isLocal ? 0.1 : 5;
+
+ const validation = await validateCredits(userId, 'AI_CHAT', cost);
+ if (!validation.hasCredits) {
+ return c.json({ error: 'Insufficient credits' }, 402);
+ }
+
+ return streamSSE(c, async (stream) => {
+ try {
+ const llmRes = await fetch(`${LLM_URL}/api/v1/chat/completions`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({
+ messages,
+ model: model || 'gemma3:4b',
+ temperature: temperature || 0.7,
+ max_tokens: maxTokens || 2000,
+ stream: true,
+ }),
+ });
+
+ if (!llmRes.ok || !llmRes.body) {
+ await stream.writeSSE({ data: JSON.stringify({ error: 'LLM failed' }) });
+ return;
+ }
+
+ const reader = llmRes.body.getReader();
+ const decoder = new TextDecoder();
+
+ while (true) {
+ const { done, value } = await reader.read();
+ if (done) break;
+ const chunk = decoder.decode(value, { stream: true });
+ // Forward SSE chunks directly
+ for (const line of chunk.split('\n')) {
+ if (line.startsWith('data: ')) {
+ await stream.writeSSE({ data: line.slice(6) });
+ }
+ }
+ }
+
+ await stream.writeSSE({ data: '[DONE]' });
+ consumeCredits(userId, 'AI_CHAT', cost, `Chat stream: ${model || 'gemma3:4b'}`).catch(() => {});
+ } catch (_err) {
+ await stream.writeSSE({ data: JSON.stringify({ error: 'Stream failed' }) });
+ }
+ });
+});
+
+// ─── Models List ─────────────────────────────────────────────
+
+app.get('/api/v1/chat/models', async (c) => {
+ try {
+ const res = await fetch(`${LLM_URL}/api/v1/models`);
+ if (res.ok) return c.json(await res.json());
+ } catch {
+ // Fallback
+ }
+ return c.json({ models: [] });
+});
+
+export default { port: PORT, fetch: app.fetch };
diff --git a/apps/chat/apps/server/tsconfig.json b/apps/chat/apps/server/tsconfig.json
new file mode 100644
index 000000000..9c7e5fa56
--- /dev/null
+++ b/apps/chat/apps/server/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "strict": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true
+ },
+ "include": ["src/**/*.ts"]
+}
diff --git a/apps/chat/apps/web/package.json b/apps/chat/apps/web/package.json
index f5a00dbf0..769c27b1a 100644
--- a/apps/chat/apps/web/package.json
+++ b/apps/chat/apps/web/package.json
@@ -40,8 +40,7 @@
"@manacore/local-store": "workspace:*",
"@manacore/shared-branding": "workspace:*",
"@manacore/shared-error-tracking": "workspace:*",
- "@manacore/shared-feedback-service": "workspace:*",
- "@manacore/shared-feedback-ui": "workspace:*",
+ "@manacore/feedback": "workspace:*",
"@manacore/shared-i18n": "workspace:*",
"@manacore/shared-help-types": "workspace:*",
"@manacore/shared-help-ui": "workspace:*",
diff --git a/apps/chat/apps/web/src/lib/services/feedback.ts b/apps/chat/apps/web/src/lib/services/feedback.ts
index a68733fa4..bd32c2635 100644
--- a/apps/chat/apps/web/src/lib/services/feedback.ts
+++ b/apps/chat/apps/web/src/lib/services/feedback.ts
@@ -2,7 +2,7 @@
* Feedback Service Instance for Chat Web App
*/
-import { createFeedbackService } from '@manacore/shared-feedback-service';
+import { createFeedbackService } from '@manacore/feedback';
import { authStore } from '$lib/stores/auth.svelte';
// Use environment variable at runtime
diff --git a/apps/chat/apps/web/src/routes/(protected)/feedback/+page.svelte b/apps/chat/apps/web/src/routes/(protected)/feedback/+page.svelte
index a3abf48ca..b85cf3eda 100644
--- a/apps/chat/apps/web/src/routes/(protected)/feedback/+page.svelte
+++ b/apps/chat/apps/web/src/routes/(protected)/feedback/+page.svelte
@@ -1,5 +1,5 @@
diff --git a/apps/citycorners/apps/web/package.json b/apps/citycorners/apps/web/package.json
index 263d6aa1d..47c0a31c2 100644
--- a/apps/citycorners/apps/web/package.json
+++ b/apps/citycorners/apps/web/package.json
@@ -36,8 +36,7 @@
"@manacore/local-store": "workspace:*",
"@manacore/shared-branding": "workspace:*",
"@manacore/shared-error-tracking": "workspace:*",
- "@manacore/shared-feedback-service": "workspace:*",
- "@manacore/shared-feedback-ui": "workspace:*",
+ "@manacore/feedback": "workspace:*",
"@manacore/shared-help-types": "workspace:*",
"@manacore/shared-help-ui": "workspace:*",
"@manacore/shared-i18n": "workspace:*",
diff --git a/apps/citycorners/apps/web/src/routes/(app)/feedback/+page.svelte b/apps/citycorners/apps/web/src/routes/(app)/feedback/+page.svelte
index 028634274..bc0f544a5 100644
--- a/apps/citycorners/apps/web/src/routes/(app)/feedback/+page.svelte
+++ b/apps/citycorners/apps/web/src/routes/(app)/feedback/+page.svelte
@@ -1,7 +1,7 @@
diff --git a/apps/context/apps/web/package.json b/apps/context/apps/web/package.json
index 719d5f092..b10cd2c4d 100644
--- a/apps/context/apps/web/package.json
+++ b/apps/context/apps/web/package.json
@@ -39,8 +39,7 @@
"@manacore/local-store": "workspace:*",
"@manacore/shared-branding": "workspace:*",
"@manacore/shared-error-tracking": "workspace:*",
- "@manacore/shared-feedback-service": "workspace:*",
- "@manacore/shared-feedback-ui": "workspace:*",
+ "@manacore/feedback": "workspace:*",
"@manacore/shared-i18n": "workspace:*",
"@manacore/shared-help-types": "workspace:*",
"@manacore/shared-help-ui": "workspace:*",
diff --git a/apps/context/apps/web/src/routes/(app)/feedback/+page.svelte b/apps/context/apps/web/src/routes/(app)/feedback/+page.svelte
index bcd779939..04a3a97af 100644
--- a/apps/context/apps/web/src/routes/(app)/feedback/+page.svelte
+++ b/apps/context/apps/web/src/routes/(app)/feedback/+page.svelte
@@ -1,7 +1,7 @@
diff --git a/apps/manadeck/apps/web/package.json b/apps/manadeck/apps/web/package.json
index d696b0965..6d627615b 100644
--- a/apps/manadeck/apps/web/package.json
+++ b/apps/manadeck/apps/web/package.json
@@ -37,8 +37,7 @@
"@manacore/shared-branding": "workspace:*",
"@manacore/shared-config": "workspace:*",
"@manacore/shared-error-tracking": "workspace:*",
- "@manacore/shared-feedback-service": "workspace:*",
- "@manacore/shared-feedback-ui": "workspace:*",
+ "@manacore/feedback": "workspace:*",
"@manacore/shared-i18n": "workspace:*",
"@manacore/shared-help-types": "workspace:*",
"@manacore/shared-help-ui": "workspace:*",
diff --git a/apps/manadeck/apps/web/src/lib/api/feedback.ts b/apps/manadeck/apps/web/src/lib/api/feedback.ts
index f8d68757a..2ac23708a 100644
--- a/apps/manadeck/apps/web/src/lib/api/feedback.ts
+++ b/apps/manadeck/apps/web/src/lib/api/feedback.ts
@@ -2,7 +2,7 @@
* Feedback Service Instance for ManaDeck Web App
*/
-import { createFeedbackService } from '@manacore/shared-feedback-service';
+import { createFeedbackService } from '@manacore/feedback';
import { authService } from '$lib/auth';
import { PUBLIC_MANA_CORE_AUTH_URL } from '$env/static/public';
diff --git a/apps/manadeck/apps/web/src/routes/(app)/feedback/+page.svelte b/apps/manadeck/apps/web/src/routes/(app)/feedback/+page.svelte
index 2c7891c74..1d630febe 100644
--- a/apps/manadeck/apps/web/src/routes/(app)/feedback/+page.svelte
+++ b/apps/manadeck/apps/web/src/routes/(app)/feedback/+page.svelte
@@ -1,5 +1,5 @@
diff --git a/apps/matrix/apps/web/package.json b/apps/matrix/apps/web/package.json
index aa03aaae5..5157de532 100644
--- a/apps/matrix/apps/web/package.json
+++ b/apps/matrix/apps/web/package.json
@@ -41,8 +41,7 @@
"@manacore/shared-auth": "workspace:*",
"@manacore/shared-branding": "workspace:*",
"@manacore/shared-error-tracking": "workspace:*",
- "@manacore/shared-feedback-service": "workspace:*",
- "@manacore/shared-feedback-ui": "workspace:*",
+ "@manacore/feedback": "workspace:*",
"@manacore/shared-help-types": "workspace:*",
"@manacore/shared-help-ui": "workspace:*",
"@manacore/shared-i18n": "workspace:*",
diff --git a/apps/matrix/apps/web/src/routes/(app)/feedback/+page.svelte b/apps/matrix/apps/web/src/routes/(app)/feedback/+page.svelte
index 1e19c487c..4e6fb723a 100644
--- a/apps/matrix/apps/web/src/routes/(app)/feedback/+page.svelte
+++ b/apps/matrix/apps/web/src/routes/(app)/feedback/+page.svelte
@@ -1,7 +1,7 @@
diff --git a/apps/nutriphi/apps/web/package.json b/apps/nutriphi/apps/web/package.json
index 03e9438b5..0dfbcb32b 100644
--- a/apps/nutriphi/apps/web/package.json
+++ b/apps/nutriphi/apps/web/package.json
@@ -44,8 +44,7 @@
"@manacore/shared-auth-ui": "workspace:*",
"@manacore/shared-branding": "workspace:*",
"@manacore/shared-error-tracking": "workspace:*",
- "@manacore/shared-feedback-service": "workspace:*",
- "@manacore/shared-feedback-ui": "workspace:*",
+ "@manacore/feedback": "workspace:*",
"@manacore/shared-i18n": "workspace:*",
"@manacore/shared-help-types": "workspace:*",
"@manacore/shared-help-ui": "workspace:*",
diff --git a/apps/photos/apps/web/package.json b/apps/photos/apps/web/package.json
index b045a5a95..18d5a9bbd 100644
--- a/apps/photos/apps/web/package.json
+++ b/apps/photos/apps/web/package.json
@@ -36,8 +36,7 @@
"@manacore/local-store": "workspace:*",
"@manacore/shared-branding": "workspace:*",
"@manacore/shared-error-tracking": "workspace:*",
- "@manacore/shared-feedback-service": "workspace:*",
- "@manacore/shared-feedback-ui": "workspace:*",
+ "@manacore/feedback": "workspace:*",
"@manacore/shared-help-content": "workspace:*",
"@manacore/shared-help-types": "workspace:*",
"@manacore/shared-help-ui": "workspace:*",
diff --git a/apps/photos/apps/web/src/routes/(app)/feedback/+page.svelte b/apps/photos/apps/web/src/routes/(app)/feedback/+page.svelte
index af6af1fc9..fac5af3c5 100644
--- a/apps/photos/apps/web/src/routes/(app)/feedback/+page.svelte
+++ b/apps/photos/apps/web/src/routes/(app)/feedback/+page.svelte
@@ -1,7 +1,7 @@
diff --git a/apps/planta/apps/web/package.json b/apps/planta/apps/web/package.json
index aad05434a..bc684d12c 100644
--- a/apps/planta/apps/web/package.json
+++ b/apps/planta/apps/web/package.json
@@ -36,8 +36,7 @@
"@manacore/shared-branding": "workspace:*",
"@manacore/shared-error-tracking": "workspace:*",
"@manacore/shared-i18n": "workspace:*",
- "@manacore/shared-feedback-service": "workspace:*",
- "@manacore/shared-feedback-ui": "workspace:*",
+ "@manacore/feedback": "workspace:*",
"@manacore/shared-help-types": "workspace:*",
"@manacore/shared-help-ui": "workspace:*",
"@manacore/shared-icons": "workspace:*",
diff --git a/apps/planta/apps/web/src/routes/(app)/feedback/+page.svelte b/apps/planta/apps/web/src/routes/(app)/feedback/+page.svelte
index fcac75ac3..1c8e42fa6 100644
--- a/apps/planta/apps/web/src/routes/(app)/feedback/+page.svelte
+++ b/apps/planta/apps/web/src/routes/(app)/feedback/+page.svelte
@@ -1,7 +1,7 @@
diff --git a/apps/questions/apps/web/package.json b/apps/questions/apps/web/package.json
index 3c9bf7b67..fb14da4bb 100644
--- a/apps/questions/apps/web/package.json
+++ b/apps/questions/apps/web/package.json
@@ -41,8 +41,7 @@
"@manacore/shared-branding": "workspace:*",
"@manacore/shared-error-tracking": "workspace:*",
"@manacore/shared-i18n": "workspace:*",
- "@manacore/shared-feedback-service": "workspace:*",
- "@manacore/shared-feedback-ui": "workspace:*",
+ "@manacore/feedback": "workspace:*",
"@manacore/shared-help-types": "workspace:*",
"@manacore/shared-help-ui": "workspace:*",
"@manacore/shared-icons": "workspace:*",
diff --git a/apps/questions/apps/web/src/routes/(app)/feedback/+page.svelte b/apps/questions/apps/web/src/routes/(app)/feedback/+page.svelte
index 06b549efc..3983315d4 100644
--- a/apps/questions/apps/web/src/routes/(app)/feedback/+page.svelte
+++ b/apps/questions/apps/web/src/routes/(app)/feedback/+page.svelte
@@ -1,7 +1,7 @@
diff --git a/apps/zitare/apps/web/package.json b/apps/zitare/apps/web/package.json
index 81ac41dfd..ee8c913bc 100644
--- a/apps/zitare/apps/web/package.json
+++ b/apps/zitare/apps/web/package.json
@@ -38,8 +38,7 @@
"@manacore/shared-auth-ui": "workspace:*",
"@manacore/shared-branding": "workspace:*",
"@manacore/shared-error-tracking": "workspace:*",
- "@manacore/shared-feedback-service": "workspace:*",
- "@manacore/shared-feedback-ui": "workspace:*",
+ "@manacore/feedback": "workspace:*",
"@manacore/shared-i18n": "workspace:*",
"@manacore/shared-help-types": "workspace:*",
"@manacore/shared-help-ui": "workspace:*",
diff --git a/apps/zitare/apps/web/src/routes/(app)/feedback/+page.svelte b/apps/zitare/apps/web/src/routes/(app)/feedback/+page.svelte
index 7714a43b7..b012b68e0 100644
--- a/apps/zitare/apps/web/src/routes/(app)/feedback/+page.svelte
+++ b/apps/zitare/apps/web/src/routes/(app)/feedback/+page.svelte
@@ -1,7 +1,7 @@