feat: AI intent router live + TOTP repeat-auth fix
AI Intent Router:
- Wired /api/v1/ai/intent and /api/v1/ai/capabilities into app.js
- Pattern matching works offline, no API key needed
- Handles: deploy, recommend, diagnose, backup, health, list
- AI chat floating button on dashboard (🤖)
- Suggestion chips: Deploy Plex, Stream movies, Block ads, System health
- Deploy buttons in chat launch the app selector
TOTP Fix:
- secureFetch() was missing credentials: same-origin
- Session cookie was not being sent on API calls
- Added credentials: same-origin to all fetch calls
- Users no longer prompted for TOTP on every action
Nesting Guard:
- Fixed logging module path (../utils/logging not ./logging)
- Switched to console.log to avoid module export mismatch
MCP Server:
- 551-line JSON-RPC server ready at src/mcp/mcp-server.js
- Configurable via DASHCADDY_URL + DASHCADDY_API_KEY env vars
This commit is contained in:
@@ -95,6 +95,7 @@ const workflowsRoutes = require('../routes/workflows');
|
||||
const dependenciesRoutes = require('../routes/dependencies');
|
||||
const securityRoutes = require('../routes/security');
|
||||
const diskSettingsRoutes = require('../routes/disk-settings');
|
||||
const aiIntentRoutes = require('../routes/ai-intent');
|
||||
const logInsightsRoutes = require('../routes/log-insights');
|
||||
const billingRoutes = require('../routes/billing');
|
||||
const DependencyManager = require('./managers/dependency-manager');
|
||||
@@ -759,6 +760,7 @@ async function createApp() {
|
||||
|
||||
// Log Insights — plain English activity summary + safe log disposal
|
||||
apiRouter.use('/disk-settings', diskSettingsRoutes);
|
||||
apiRouter.use(aiIntentRoutes({ asyncHandler: ctx.asyncHandler }));
|
||||
apiRouter.use(logInsightsRoutes({
|
||||
asyncHandler: ctx.asyncHandler,
|
||||
ok: ctx.ok,
|
||||
|
||||
@@ -483,7 +483,7 @@ const DEFAULT_LANGUAGE = 'en';
|
||||
|
||||
// Language metadata for UI dropdowns
|
||||
const LANGUAGE_META = {
|
||||
en: { name: 'English', flag: '🇬🇧', rtl: false },
|
||||
en: { name: 'English', flag: '🇺🇸', rtl: false },
|
||||
ar: { name: 'العربية', flag: '🇸🇦', rtl: true },
|
||||
bn: { name: 'বাংলা', flag: '🇧🇩', rtl: false },
|
||||
cs: { name: 'Čeština', flag: '🇨🇿', rtl: false },
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const log = require('./logging');
|
||||
|
||||
module.exports = function nestingGuard() {
|
||||
try {
|
||||
const dataDir = require('../config/paths').dataDir;
|
||||
const paths = require('../config/paths');
|
||||
const dataDir = paths.dataDir;
|
||||
const dataDataPath = path.join(dataDir, 'data');
|
||||
|
||||
// If data/data exists, it's a recursive duplicate — remove it
|
||||
@@ -25,17 +25,14 @@ module.exports = function nestingGuard() {
|
||||
const markerFile = path.join(dataDataPath, 'config.json');
|
||||
const parentMarker = path.join(dataDir, 'config.json');
|
||||
if (fs.existsSync(markerFile) && fs.existsSync(parentMarker)) {
|
||||
const size = require('child_process')
|
||||
.execSync(`du -sh '${dataDataPath}' 2>/dev/null | cut -f1`)
|
||||
.toString().trim();
|
||||
log.warn('startup', `Removing recursive data nesting: ${dataDataPath} (${size})`);
|
||||
console.log('[nesting-guard] Removing recursive data nesting: ' + dataDataPath);
|
||||
fs.rmSync(dataDataPath, { recursive: true, force: true });
|
||||
log.info('startup', 'Recursive nesting removed');
|
||||
console.log('[nesting-guard] Recursive nesting removed');
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Non-fatal — don't crash startup over cleanup
|
||||
log.warn('startup', `Nesting guard skipped: ${e.message}`);
|
||||
console.warn('[nesting-guard] Skipped: ' + e.message);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user