From 4d796cd2ca4a725fe7435b339d99dd28a385ad16 Mon Sep 17 00:00:00 2001
From: Adam Patch
Date: Sun, 8 Feb 2026 14:40:48 -0500
Subject: [PATCH 1/5] chore(dev): update submodule to point to completed
config-export-import task
---
dev | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dev b/dev
index e45b185..b84382d 160000
--- a/dev
+++ b/dev
@@ -1 +1 @@
-Subproject commit e45b185ad48be552ea8d05816eadd21e1eafe58b
+Subproject commit b84382db5b9299231daee71579262d2792d7c39c
From 5e3e63565449cf43a4c14e73c336ab0152263ab2 Mon Sep 17 00:00:00 2001
From: Adam Patch
Date: Sun, 8 Feb 2026 15:26:33 -0500
Subject: [PATCH 2/5] feat(ui): modularize settings into separate template
partials
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Refactored the large index.html file (2848 lines) by extracting 7 settings
sections into self-contained partial templates:
**New partial templates in settings/ directory:**
- _general.html (989 lines): System info, config export/import, security,
user management, audit log with 4 JS init functions
- _neo4j.html (177 lines): Neo4j connection settings with connection
management JS
- _chat.html (265 lines): LLM provider configuration with initChatSettings
- _interpreters.html (118 lines): Interpreter mappings and toggles with
dynamic table
- _plugins.html (8 lines): Plugin registry summary
- _rclone.html (146 lines): Rclone interpretation and mount management with JS
- _integrations.html (1015 lines): API endpoints, table formats, fuzzy
matching with 3 JS init functions
**Main index.html changes:**
- Reduced from 2848 to 141 lines (95% reduction)
- Now uses {% include %} directives to compose sections
- Keeps only shared CSS and tab navigation JavaScript
- All section-specific JS moved into respective partials
**Cleanup:**
- Deleted obsolete settings.html file (2067 lines)
- /settings route already redirects to / (landing page)
**Tests:**
- All pytest tests pass (25/25)
- Added TODO placeholders in E2E tests for future updates
**Benefits:**
- Easier to find and edit specific settings sections
- Reduced merge conflicts
- Each partial is self-contained with HTML + JS
- Maintained identical functionality and appearance
Related: task:ui/settings/modularization
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude
---
e2e/settings-advanced.spec.ts | 3 +
e2e/settings-api-endpoints.spec.ts | 3 +
e2e/settings-fuzzy-matching.spec.ts | 3 +
e2e/settings-table-formats.spec.ts | 3 +
e2e/settings.spec.ts | 6 +
scidk/ui/templates/index.html | 2723 +----------------
scidk/ui/templates/settings.html | 2067 -------------
scidk/ui/templates/settings/_chat.html | 265 ++
scidk/ui/templates/settings/_general.html | 989 ++++++
.../ui/templates/settings/_integrations.html | 1015 ++++++
.../ui/templates/settings/_interpreters.html | 118 +
scidk/ui/templates/settings/_neo4j.html | 177 ++
scidk/ui/templates/settings/_plugins.html | 8 +
scidk/ui/templates/settings/_rclone.html | 146 +
14 files changed, 2744 insertions(+), 4782 deletions(-)
delete mode 100644 scidk/ui/templates/settings.html
create mode 100644 scidk/ui/templates/settings/_chat.html
create mode 100644 scidk/ui/templates/settings/_general.html
create mode 100644 scidk/ui/templates/settings/_integrations.html
create mode 100644 scidk/ui/templates/settings/_interpreters.html
create mode 100644 scidk/ui/templates/settings/_neo4j.html
create mode 100644 scidk/ui/templates/settings/_plugins.html
create mode 100644 scidk/ui/templates/settings/_rclone.html
diff --git a/e2e/settings-advanced.spec.ts b/e2e/settings-advanced.spec.ts
index 4e16344..0a59d38 100644
--- a/e2e/settings-advanced.spec.ts
+++ b/e2e/settings-advanced.spec.ts
@@ -3,6 +3,9 @@ import { test, expect } from '@playwright/test';
/**
* E2E tests for additional Settings page features.
* Tests disconnect button and interpreter checkbox interactions.
+ *
+ * TODO: Update tests after settings modularization (task:ui/settings/modularization)
+ * Settings sections now split across multiple partial templates in settings/ directory
*/
test('neo4j disconnect button appears when connected', async ({ page, baseURL }) => {
diff --git a/e2e/settings-api-endpoints.spec.ts b/e2e/settings-api-endpoints.spec.ts
index fa6c789..a4959a9 100644
--- a/e2e/settings-api-endpoints.spec.ts
+++ b/e2e/settings-api-endpoints.spec.ts
@@ -1,5 +1,8 @@
import { test, expect, request as playwrightRequest } from '@playwright/test';
+// TODO: Update tests after settings modularization (task:ui/settings/modularization)
+// Integrations section now in settings/_integrations.html
+
test.describe('Settings - API Endpoints', () => {
test.beforeEach(async ({ page, baseURL }) => {
// Disable auth before each test
diff --git a/e2e/settings-fuzzy-matching.spec.ts b/e2e/settings-fuzzy-matching.spec.ts
index 21f3b77..ee16212 100644
--- a/e2e/settings-fuzzy-matching.spec.ts
+++ b/e2e/settings-fuzzy-matching.spec.ts
@@ -1,5 +1,8 @@
import { test, expect } from '@playwright/test';
+// TODO: Update tests after settings modularization (task:ui/settings/modularization)
+// Fuzzy matching section now in settings/_integrations.html
+
test.describe('Settings - Fuzzy Matching', () => {
test.beforeEach(async ({ page, baseURL }) => {
const base = baseURL || process.env.BASE_URL || 'http://127.0.0.1:5000';
diff --git a/e2e/settings-table-formats.spec.ts b/e2e/settings-table-formats.spec.ts
index 8943418..6d41654 100644
--- a/e2e/settings-table-formats.spec.ts
+++ b/e2e/settings-table-formats.spec.ts
@@ -1,5 +1,8 @@
import { test, expect } from '@playwright/test';
+// TODO: Update tests after settings modularization (task:ui/settings/modularization)
+// Table formats section now in settings/_integrations.html
+
test.describe('Settings - Table Format Registry', () => {
test.beforeEach(async ({ page, baseURL }) => {
await page.goto(`${baseURL}/#integrations`);
diff --git a/e2e/settings.spec.ts b/e2e/settings.spec.ts
index 5f7d681..2f66e8a 100644
--- a/e2e/settings.spec.ts
+++ b/e2e/settings.spec.ts
@@ -3,6 +3,12 @@ import { test, expect } from '@playwright/test';
/**
* E2E tests for Settings page functionality.
* Tests Neo4j connection, interpreter toggles, and rclone settings.
+ *
+ * TODO: Update tests after settings modularization (task:ui/settings/modularization)
+ * Settings sections have been extracted into separate partial templates:
+ * - settings/_general.html, _neo4j.html, _chat.html, _interpreters.html,
+ * _plugins.html, _rclone.html, _integrations.html
+ * The main index.html now uses {% include %} directives to compose the page.
*/
test('settings page loads and displays system information', async ({ page, baseURL }) => {
diff --git a/scidk/ui/templates/index.html b/scidk/ui/templates/index.html
index 575f71c..23e9951 100644
--- a/scidk/ui/templates/index.html
+++ b/scidk/ui/templates/index.html
@@ -94,735 +94,18 @@
-
-
- General
- Basic runtime information and counts.
-
- Host: {{ info.host }}
- Port: {{ info.port }}
- Debug: {{ info.debug }}
- Datasets: {{ info.dataset_count }}
- Interpreters: {{ info.interpreter_count }}
-
-
- Channel: {{ info.channel or 'stable' }}
- Providers: {{ info.providers }}
- Files viewer: {{ info.files_viewer or '(default)' }}
-
-
- Configuration Management
- Export and import your complete SciDK configuration for backup or migration.
-
- Export Configuration
- Import Configuration
- View Backups
-
-
-
- Exports all settings including Neo4j connection, interpreters, plugins, rclone mounts, and integration endpoints.
-
- Security
- Configure authentication and access control for this SciDK instance.
-
-
-
-
- Logged in as:
-
-
-
-
-
-
-
-
-
Enable Authentication
-
-
- Require login to access SciDK
-
-
-
-
Save Security Settings
-
-
-
-
-
-
- Your Account
- You are logged in with a regular user account. Contact an administrator to manage users or change security settings.
-
-
-
-
-
-
- Authentication Active
- Multi-user authentication is enabled. Use the "Users" section below to manage user accounts and permissions.
-
-
-
-
-
-
Users
-
Manage user accounts and permissions. Admin Only
-
-
-
User List
- + Add User
-
-
-
-
-
-
-
-
Audit Log
-
Security and user action logs. Admin Only
-
-
-
Recent Activity
- Refresh
-
-
-
-
-
-
-
-
- Neo4j Connection
- Configure Neo4j database connection and settings.
-
-
- URI
-
-
-
- User
-
-
-
- Database (optional)
-
-
-
-
-
Save
-
Connect
-
Disconnect
-
-
-
-
- Advanced / Health
-
- Test Graph Connection
-
-
- You can also set env vars: NEO4J_URI, NEO4J_USER, NEO4J_PASSWORD, SCIDK_NEO4J_DATABASE
- If your Neo4j has authentication disabled, set environment variable NEO4J_AUTH=none before starting the app.
-
-
-
-
-
- Chat
- Configure the chat interface for natural language queries over your Neo4j graph.
-
- LLM Provider Configuration
-
-
- Default LLM Provider
-
- Anthropic (Claude)
- OpenAI (GPT)
- Ollama (Local)
- None (Pattern-based only)
-
- Choose which LLM to use for entity extraction and query generation.
-
-
-
-
-
-
Anthropic API Configuration
-
-
-
- Model
-
- Claude 3.5 Sonnet
- Claude 3 Opus
- Claude 3 Haiku
-
-
-
-
-
-
-
-
OpenAI API Configuration
-
-
-
- Model
-
- GPT-4 Turbo
- GPT-4
- GPT-3.5 Turbo
-
-
-
-
-
-
-
-
Ollama Configuration
-
-
- Ollama URL
-
-
-
- Model
-
- Llama 2
- Mistral
- Code Llama
-
-
-
-
-
-
- Save LLM Configuration
-
-
- Chat Behavior
-
-
-
-
-
- Verbose mode (show technical details like entities, execution time)
-
-
-
Can also be toggled per-session in the chat interface.
-
-
- Save Settings
-
-
-
-
- Advanced
-
- Environment variables:
-
- SCIDK_ANTHROPIC_API_KEY - Anthropic API key for LLM-enhanced entity extraction
- SCIDK_GRAPHRAG_VERBOSE - Set to '1' or 'true' to enable verbose mode by default
-
-
-
-
- Chat History
- Manage chat sessions with persistent database storage.
-
-
- Chat sessions are now stored in the database and can be:
-
-
- Saved from the Chat interface using the "Save Session" button
- Loaded from the session selector dropdown
- Managed (rename, export, delete) using the "📂" button
- Exported as JSON files and imported from backups
-
-
- Open Chat Interface →
-
-
-
-
-
-
- Interpreters
- Registered interpreter mappings and selection rules.
- Mappings (extension → interpreter ids)
-
- {% for ext, ids in (mappings or {}).items() %}
- {{ ext }} → {{ ids }}
- {% else %}
- No mappings.
- {% endfor %}
-
- Rules
-
- {% for r in (rules or []) %}
- {{ r.id }} → interpreter_id={{ r.interpreter_id }}, pattern={{ r.pattern }}, priority={{ r.priority }}
- {% else %}
- No rules.
- {% endfor %}
-
-
- Interpreter toggles
- Enable or disable interpreters globally. Changes persist to settings when possible. If CLI env overrides are set (SCIDK_ENABLE_INTERPRETERS/SCIDK_DISABLE_INTERPRETERS), those take precedence and are shown as source=cli.
-
- Effective view is controlled by CLI env overrides; toggle effects may be masked.
- Unset SCIDK_ENABLE_INTERPRETERS/SCIDK_DISABLE_INTERPRETERS to allow GUI control.
-
-
-
-
-
-
- Interpreter
- Extensions
- Enabled
- Source
-
-
-
-
-
-
-
-
-
-
- Plugins
- Plugin registry summary.
-
- Registered interpreter count: {{ interp_count or 0 }}
- Extensions mapped: {{ ext_count or 0 }}
-
-
-
-
-
- Rclone
- Configure rclone settings for interpretation and mounts.
-
- Interpretation
- Tune streaming-based interpretation from rclone remotes. For very large scans, consider mounting the remote.
-
-
- Suggest-mount threshold (files)
-
-
-
- Max files per batch
-
-
-
- Save
-
-
-
-
- Mounts
- Manage rclone mounts under ./data/mounts.
-
-
- Remote
-
-
-
- Subpath (optional)
-
-
-
- Name
-
-
-
-
-
- Read-only
-
-
Create
-
-
-
- Refresh
-
-
-
- Name Target Path Status Actions
-
-
- No mounts.
-
-
-
- Note: On Windows, cmount/WinFsp may be required; this UI targets Linux/macOS primarily.
-
-
-
-
- Integrations
- Configure integration mappings, API endpoints, and matching options.
-
- API Endpoint Mappings
- Define API endpoints that map to Label types in SciDK.
-
-
-
-
Add New Endpoint
-
-
- Test Connection
- Save Endpoint
- Cancel
-
-
-
-
-
- Registered Endpoints
-
-
No endpoints registered yet
-
-
- Table Format Registry
- Manage table formats for importing CSV, TSV, Excel, and Parquet files as link sources.
-
-
-
-
Add Custom Format
-
-
- Description (optional):
-
-
-
- Save Format
- Cancel
-
-
- Upload Sample & Detect
-
-
-
-
-
-
-
-
-
- Registered Formats
-
-
- Fuzzy Matching Options
- Configure fuzzy matching algorithms for entity resolution in link creation.
-
-
-
-
Global Fuzzy Matching Settings
-
-
-
-
-
Matching Algorithm:
-
- Exact Match
- Levenshtein Distance
- Jaro-Winkler Distance
- Phonetic (Soundex/Metaphone)
-
-
Levenshtein: general fuzzy matching | Jaro-Winkler: names | Phonetic: sound-alike
-
-
-
Similarity Threshold: 80 %
-
-
Minimum similarity score (0-100%) to consider a match
-
-
-
-
-
-
-
-
-
- Normalize Whitespace
-
-
-
-
-
- Strip Punctuation
-
-
-
-
-
-
-
-
-
-
- Enable Phonetic Matching
-
-
-
- Phonetic Algorithm:
-
- Soundex
- Metaphone (Better)
- Double Metaphone
-
-
-
-
-
-
-
- Advanced Options
-
-
- Min String Length:
-
-
-
- Max Comparisons:
-
-
-
-
-
- Show Confidence Scores
-
-
-
-
-
-
-
- Save Settings
- Reset to Defaults
-
-
-
-
-
-
-
Hybrid Matching Architecture
-
- Phase 1 (Client-Side): Pre-import matching using rapidfuzz - match external API/CSV data before pushing to Neo4j.
-
-
- Phase 2 (Server-Side): Post-import matching using Neo4j APOC functions - ultra-fast in-database entity resolution for existing nodes.
-
-
-
+ {% include 'settings/_general.html' %}
+ {% include 'settings/_neo4j.html' %}
+ {% include 'settings/_chat.html' %}
+ {% include 'settings/_interpreters.html' %}
+ {% include 'settings/_plugins.html' %}
+ {% include 'settings/_rclone.html' %}
+ {% include 'settings/_integrations.html' %}
-
{% endblock %}
diff --git a/scidk/ui/templates/settings.html b/scidk/ui/templates/settings.html
deleted file mode 100644
index 625809e..0000000
--- a/scidk/ui/templates/settings.html
+++ /dev/null
@@ -1,2067 +0,0 @@
-{% extends 'base.html' %}
-{% block title %}-SciDK-> Settings{% endblock %}
-{% block head %}
-
-{% endblock %}
-{% block content %}
-
-
-
-
-
-
-
-
- General
- Basic runtime information and counts.
-
- Host: {{ info.host }}
- Port: {{ info.port }}
- Debug: {{ info.debug }}
- Datasets: {{ info.dataset_count }}
- Interpreters: {{ info.interpreter_count }}
-
-
- Channel: {{ info.channel or 'stable' }}
- Providers: {{ info.providers }}
- Files viewer: {{ info.files_viewer or '(default)' }}
-
-
-
- Configuration Management
- Export and import your complete SciDK configuration for backup or migration.
-
-
-
- Export Configuration
-
-
- Import Configuration
-
-
- View Backups
-
-
-
-
-
-
-
-
-
-
- Neo4j Connection
- Configure Neo4j database connection and settings.
-
-
- URI
-
-
-
- User
-
-
-
- Database (optional)
-
-
-
-
-
Save
-
Connect
-
Disconnect
-
-
-
-
- Advanced / Health
-
- Test Graph Connection
-
-
- You can also set env vars: NEO4J_URI, NEO4J_USER, NEO4J_PASSWORD, SCIDK_NEO4J_DATABASE
- If your Neo4j has authentication disabled, set environment variable NEO4J_AUTH=none before starting the app.
-
-
-
-
-
- Chat
- Configure the chat interface for natural language queries over your Neo4j graph.
-
- LLM Provider Configuration
-
-
- Default LLM Provider
-
- Anthropic (Claude)
- OpenAI (GPT)
- Ollama (Local)
- None (Pattern-based only)
-
- Choose which LLM to use for entity extraction and query generation.
-
-
-
-
-
-
Anthropic API Configuration
-
-
-
- Model
-
- Claude 3.5 Sonnet
- Claude 3 Opus
- Claude 3 Haiku
-
-
-
-
-
-
-
-
OpenAI API Configuration
-
-
-
- Model
-
- GPT-4 Turbo
- GPT-4
- GPT-3.5 Turbo
-
-
-
-
-
-
-
-
Ollama Configuration
-
-
- Ollama URL
-
-
-
- Model
-
- Llama 2
- Mistral
- Code Llama
-
-
-
-
-
-
- Save LLM Configuration
-
-
- Chat Behavior
-
-
-
-
-
- Verbose mode (show technical details like entities, execution time)
-
-
-
Can also be toggled per-session in the chat interface.
-
-
- Save Settings
-
-
-
-
- Advanced
-
- Environment variables:
-
- SCIDK_ANTHROPIC_API_KEY - Anthropic API key for LLM-enhanced entity extraction
- SCIDK_GRAPHRAG_VERBOSE - Set to '1' or 'true' to enable verbose mode by default
-
-
-
-
- Chat History
- Manage stored chat sessions. (Feature in development)
-
-
- Coming soon: Persistent chat history storage, session management, and recall functionality.
-
-
-
-
-
-
- Interpreters
- Registered interpreter mappings and selection rules.
- Mappings (extension → interpreter ids)
-
- {% for ext, ids in (mappings or {}).items() %}
- {{ ext }} → {{ ids }}
- {% else %}
- No mappings.
- {% endfor %}
-
- Rules
-
- {% for r in (rules or []) %}
- {{ r.id }} → interpreter_id={{ r.interpreter_id }}, pattern={{ r.pattern }}, priority={{ r.priority }}
- {% else %}
- No rules.
- {% endfor %}
-
-
- Interpreter toggles
- Enable or disable interpreters globally. Changes persist to settings when possible. If CLI env overrides are set (SCIDK_ENABLE_INTERPRETERS/SCIDK_DISABLE_INTERPRETERS), those take precedence and are shown as source=cli.
-
- Effective view is controlled by CLI env overrides; toggle effects may be masked.
- Unset SCIDK_ENABLE_INTERPRETERS/SCIDK_DISABLE_INTERPRETERS to allow GUI control.
-
-
-
-
-
-
- Interpreter
- Extensions
- Enabled
- Source
-
-
-
-
-
-
-
-
-
-
- Plugins
- Plugin registry summary.
-
- Registered interpreter count: {{ interp_count or 0 }}
- Extensions mapped: {{ ext_count or 0 }}
-
-
-
-
-
- Rclone
- Configure rclone settings for interpretation and mounts.
-
- Interpretation
- Tune streaming-based interpretation from rclone remotes. For very large scans, consider mounting the remote.
-
-
- Suggest-mount threshold (files)
-
-
-
- Max files per batch
-
-
-
- Save
-
-
-
-
- Mounts
- Manage rclone mounts under ./data/mounts.
-
-
- Remote
-
-
-
- Subpath (optional)
-
-
-
- Name
-
-
-
-
-
- Read-only
-
-
Create
-
-
-
- Refresh
-
-
-
- Name Target Path Status Actions
-
-
- No mounts.
-
-
-
- Note: On Windows, cmount/WinFsp may be required; this UI targets Linux/macOS primarily.
-
-
-
-
- Integrations
- Configure integration mappings, API endpoints, and matching options.
-
- API Endpoint Mappings
- Define API endpoints that map to Label types in SciDK.
-
-
-
-
Add New Endpoint
-
-
- Test Connection
- Save Endpoint
- Cancel
-
-
-
-
-
- Registered Endpoints
-
-
No endpoints registered yet
-
-
- Table Format Registry
- Manage table formats for importing CSV, TSV, Excel, and Parquet files as link sources.
-
-
-
-
Add Custom Format
-
-
- Description (optional):
-
-
-
- Save Format
- Cancel
-
-
- Upload Sample & Detect
-
-
-
-
-
-
-
-
-
- Registered Formats
-
-
- Fuzzy Matching Options
- Configure fuzzy matching algorithms for entity resolution in link creation.
-
-
-
-
Global Fuzzy Matching Settings
-
-
-
-
-
Matching Algorithm:
-
- Exact Match
- Levenshtein Distance
- Jaro-Winkler Distance
- Phonetic (Soundex/Metaphone)
-
-
Levenshtein: general fuzzy matching | Jaro-Winkler: names | Phonetic: sound-alike
-
-
-
Similarity Threshold: 80 %
-
-
Minimum similarity score (0-100%) to consider a match
-
-
-
-
-
-
-
-
-
- Normalize Whitespace
-
-
-
-
-
- Strip Punctuation
-
-
-
-
-
-
-
-
-
-
- Enable Phonetic Matching
-
-
-
- Phonetic Algorithm:
-
- Soundex
- Metaphone (Better)
- Double Metaphone
-
-
-
-
-
-
-
- Advanced Options
-
-
- Min String Length:
-
-
-
- Max Comparisons:
-
-
-
-
-
- Show Confidence Scores
-
-
-
-
-
-
-
- Save Settings
- Reset to Defaults
-
-
-
-
-
-
-
Hybrid Matching Architecture
-
- Phase 1 (Client-Side): Pre-import matching using rapidfuzz - match external API/CSV data before pushing to Neo4j.
-
-
- Phase 2 (Server-Side): Post-import matching using Neo4j APOC functions - ultra-fast in-database entity resolution for existing nodes.
-
-
-
-
-
-
-
-
-{% endblock %}
diff --git a/scidk/ui/templates/settings/_chat.html b/scidk/ui/templates/settings/_chat.html
new file mode 100644
index 0000000..6b2d8c2
--- /dev/null
+++ b/scidk/ui/templates/settings/_chat.html
@@ -0,0 +1,265 @@
+
+
+ Chat
+ Configure the chat interface for natural language queries over your Neo4j graph.
+
+ LLM Provider Configuration
+
+
+ Default LLM Provider
+
+ Anthropic (Claude)
+ OpenAI (GPT)
+ Ollama (Local)
+ None (Pattern-based only)
+
+ Choose which LLM to use for entity extraction and query generation.
+
+
+
+
+
+
Anthropic API Configuration
+
+
+
+ Model
+
+ Claude 3.5 Sonnet
+ Claude 3 Opus
+ Claude 3 Haiku
+
+
+
+
+
+
+
+
OpenAI API Configuration
+
+
+
+ Model
+
+ GPT-4 Turbo
+ GPT-4
+ GPT-3.5 Turbo
+
+
+
+
+
+
+
+
Ollama Configuration
+
+
+ Ollama URL
+
+
+
+ Model
+
+ Llama 2
+ Mistral
+ Code Llama
+
+
+
+
+
+
+ Save LLM Configuration
+
+
+ Chat Behavior
+
+
+
+
+
+ Verbose mode (show technical details like entities, execution time)
+
+
+
Can also be toggled per-session in the chat interface.
+
+
+ Save Settings
+
+
+
+
+ Advanced
+
+ Environment variables:
+
+ SCIDK_ANTHROPIC_API_KEY - Anthropic API key for LLM-enhanced entity extraction
+ SCIDK_GRAPHRAG_VERBOSE - Set to '1' or 'true' to enable verbose mode by default
+
+
+
+
+ Chat History
+ Manage chat sessions with persistent database storage.
+
+
+ Chat sessions are now stored in the database and can be:
+
+
+ Saved from the Chat interface using the "Save Session" button
+ Loaded from the session selector dropdown
+ Managed (rename, export, delete) using the "📂" button
+ Exported as JSON files and imported from backups
+
+
+ Open Chat Interface →
+
+
+
+
+
diff --git a/scidk/ui/templates/settings/_general.html b/scidk/ui/templates/settings/_general.html
new file mode 100644
index 0000000..aa83e69
--- /dev/null
+++ b/scidk/ui/templates/settings/_general.html
@@ -0,0 +1,989 @@
+
+
+ General
+ Basic runtime information and counts.
+
+ Host: {{ info.host }}
+ Port: {{ info.port }}
+ Debug: {{ info.debug }}
+ Datasets: {{ info.dataset_count }}
+ Interpreters: {{ info.interpreter_count }}
+
+
+ Channel: {{ info.channel or 'stable' }}
+ Providers: {{ info.providers }}
+ Files viewer: {{ info.files_viewer or '(default)' }}
+
+
+ Configuration Management
+ Export and import your complete SciDK configuration for backup or migration.
+
+ Export Configuration
+ Import Configuration
+ View Backups
+
+
+
+ Exports all settings including Neo4j connection, interpreters, plugins, rclone mounts, and integration endpoints.
+
+ Security
+ Configure authentication and access control for this SciDK instance.
+
+
+
+
+ Logged in as:
+
+
+
+
+
+
+
+
+
Enable Authentication
+
+
+ Require login to access SciDK
+
+
+
+
Save Security Settings
+
+
+
+
+
+
+ Your Account
+ You are logged in with a regular user account. Contact an administrator to manage users or change security settings.
+
+
+
+
+
+
+ Authentication Active
+ Multi-user authentication is enabled. Use the "Users" section below to manage user accounts and permissions.
+
+
+
+
+
+
Users
+
Manage user accounts and permissions. Admin Only
+
+
+
User List
+ + Add User
+
+
+
+
+
+
+
+
Audit Log
+
Security and user action logs. Admin Only
+
+
+
Recent Activity
+ Refresh
+
+
+
+
+
+
+
diff --git a/scidk/ui/templates/settings/_integrations.html b/scidk/ui/templates/settings/_integrations.html
new file mode 100644
index 0000000..09fe694
--- /dev/null
+++ b/scidk/ui/templates/settings/_integrations.html
@@ -0,0 +1,1015 @@
+
+
+ Integrations
+ Configure integration mappings, API endpoints, and matching options.
+
+ API Endpoint Mappings
+ Define API endpoints that map to Label types in SciDK.
+
+
+
+
Add New Endpoint
+
+
+ Test Connection
+ Save Endpoint
+ Cancel
+
+
+
+
+
+ Registered Endpoints
+
+
No endpoints registered yet
+
+
+ Table Format Registry
+ Manage table formats for importing CSV, TSV, Excel, and Parquet files as link sources.
+
+
+
+
Add Custom Format
+
+
+ Description (optional):
+
+
+
+ Save Format
+ Cancel
+
+
+ Upload Sample & Detect
+
+
+
+
+
+
+
+
+
+ Registered Formats
+
+
+ Fuzzy Matching Options
+ Configure fuzzy matching algorithms for entity resolution in link creation.
+
+
+
+
Global Fuzzy Matching Settings
+
+
+
+
+
Matching Algorithm:
+
+ Exact Match
+ Levenshtein Distance
+ Jaro-Winkler Distance
+ Phonetic (Soundex/Metaphone)
+
+
Levenshtein: general fuzzy matching | Jaro-Winkler: names | Phonetic: sound-alike
+
+
+
Similarity Threshold: 80 %
+
+
Minimum similarity score (0-100%) to consider a match
+
+
+
+
+
+
+
+
+
+ Normalize Whitespace
+
+
+
+
+
+ Strip Punctuation
+
+
+
+
+
+
+
+
+
+
+ Enable Phonetic Matching
+
+
+
+ Phonetic Algorithm:
+
+ Soundex
+ Metaphone (Better)
+ Double Metaphone
+
+
+
+
+
+
+
+ Advanced Options
+
+
+ Min String Length:
+
+
+
+ Max Comparisons:
+
+
+
+
+
+ Show Confidence Scores
+
+
+
+
+
+
+
+ Save Settings
+ Reset to Defaults
+
+
+
+
+
+
+
Hybrid Matching Architecture
+
+ Phase 1 (Client-Side): Pre-import matching using rapidfuzz - match external API/CSV data before pushing to Neo4j.
+
+
+ Phase 2 (Server-Side): Post-import matching using Neo4j APOC functions - ultra-fast in-database entity resolution for existing nodes.
+
+
+
+
+
diff --git a/scidk/ui/templates/settings/_interpreters.html b/scidk/ui/templates/settings/_interpreters.html
new file mode 100644
index 0000000..170f9b2
--- /dev/null
+++ b/scidk/ui/templates/settings/_interpreters.html
@@ -0,0 +1,118 @@
+
+
+ Interpreters
+ Registered interpreter mappings and selection rules.
+ Mappings (extension → interpreter ids)
+
+ {% for ext, ids in (mappings or {}).items() %}
+ {{ ext }} → {{ ids }}
+ {% else %}
+ No mappings.
+ {% endfor %}
+
+ Rules
+
+ {% for r in (rules or []) %}
+ {{ r.id }} → interpreter_id={{ r.interpreter_id }}, pattern={{ r.pattern }}, priority={{ r.priority }}
+ {% else %}
+ No rules.
+ {% endfor %}
+
+
+ Interpreter toggles
+ Enable or disable interpreters globally. Changes persist to settings when possible. If CLI env overrides are set (SCIDK_ENABLE_INTERPRETERS/SCIDK_DISABLE_INTERPRETERS), those take precedence and are shown as source=cli.
+
+ Effective view is controlled by CLI env overrides; toggle effects may be masked.
+ Unset SCIDK_ENABLE_INTERPRETERS/SCIDK_DISABLE_INTERPRETERS to allow GUI control.
+
+
+
+
+
+
+ Interpreter
+ Extensions
+ Enabled
+ Source
+
+
+
+
+
+
+
diff --git a/scidk/ui/templates/settings/_neo4j.html b/scidk/ui/templates/settings/_neo4j.html
new file mode 100644
index 0000000..c03816f
--- /dev/null
+++ b/scidk/ui/templates/settings/_neo4j.html
@@ -0,0 +1,177 @@
+
+ Neo4j Connection
+ Configure Neo4j database connection and settings.
+
+
+ URI
+
+
+
+ User
+
+
+
+ Database (optional)
+
+
+
+
+
Save
+
Connect
+
Disconnect
+
+
+
+
+ Advanced / Health
+
+ Test Graph Connection
+
+
+ You can also set env vars: NEO4J_URI, NEO4J_USER, NEO4J_PASSWORD, SCIDK_NEO4J_DATABASE
+ If your Neo4j has authentication disabled, set environment variable NEO4J_AUTH=none before starting the app.
+
+
+
+
diff --git a/scidk/ui/templates/settings/_plugins.html b/scidk/ui/templates/settings/_plugins.html
new file mode 100644
index 0000000..da6977b
--- /dev/null
+++ b/scidk/ui/templates/settings/_plugins.html
@@ -0,0 +1,8 @@
+
+ Plugins
+ Plugin registry summary.
+
+ Registered interpreter count: {{ interp_count or 0 }}
+ Extensions mapped: {{ ext_count or 0 }}
+
+
diff --git a/scidk/ui/templates/settings/_rclone.html b/scidk/ui/templates/settings/_rclone.html
new file mode 100644
index 0000000..56a71a6
--- /dev/null
+++ b/scidk/ui/templates/settings/_rclone.html
@@ -0,0 +1,146 @@
+
+ Rclone
+ Configure rclone settings for interpretation and mounts.
+
+ Interpretation
+ Tune streaming-based interpretation from rclone remotes. For very large scans, consider mounting the remote.
+
+
+ Suggest-mount threshold (files)
+
+
+
+ Max files per batch
+
+
+
+ Save
+
+
+
+
+ Mounts
+ Manage rclone mounts under ./data/mounts.
+
+
+ Remote
+
+
+
+ Subpath (optional)
+
+
+
+ Name
+
+
+
+
+
+ Read-only
+
+
Create
+
+
+
+ Refresh
+
+
+
+ Name Target Path Status Actions
+
+
+ No mounts.
+
+
+
+ Note: On Windows, cmount/WinFsp may be required; this UI targets Linux/macOS primarily.
+
+
+
From 8d0bdb1359fb55ed3f4242b8f03f26e0809f88f5 Mon Sep 17 00:00:00 2001
From: Adam Patch
Date: Sun, 8 Feb 2026 15:31:32 -0500
Subject: [PATCH 3/5] chore(dev): update submodule pointer for completed
settings-modularization task
---
dev | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dev b/dev
index b84382d..ad6f67f 160000
--- a/dev
+++ b/dev
@@ -1 +1 @@
-Subproject commit b84382db5b9299231daee71579262d2792d7c39c
+Subproject commit ad6f67fbedb7d04036c5a19ce8cbad949bab692e
From f0eeb5b6f8d0840fa7f31d3af80fce7d7eb58a80 Mon Sep 17 00:00:00 2001
From: Adam Patch
Date: Sun, 8 Feb 2026 15:43:03 -0500
Subject: [PATCH 4/5] feat(security): implement auto-lock after inactivity
timeout
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Adds comprehensive session locking functionality with:
- Server-side session lock/unlock API endpoints
- Client-side activity monitoring with configurable timeouts
- Lock screen overlay with password verification
- Auto-lock settings in Security section (1-120 minutes)
- Session lock state tracking in auth_sessions table
- Audit logging for lock/unlock events
- Failed unlock attempt tracking
- Middleware integration (returns 423 when locked)
Backend changes:
- Add locked/locked_at columns to auth_sessions table
- Add lock_session(), unlock_session(), is_session_locked() methods
- Add get_session_lock_info() for retrieving lock state
- Add migration for existing databases
- Add /api/auth/lock and /api/auth/unlock endpoints
- Add /api/settings/security/auto-lock GET/POST endpoints
- Update auth middleware to check session lock state
Frontend changes:
- Add ActivityMonitor JavaScript class in base.html
- Track mouse, keyboard, scroll, touch activity
- Auto-lock session after configured inactivity period
- Show lock screen overlay with username and lock time
- Password-only unlock (no username required)
- Auto-load lock screen if session already locked
- Add auto-lock enable/disable toggle in Settings
- Add timeout configuration (1-120 minutes)
Testing:
- 12 unit tests covering lock/unlock functionality
- Test session locking and unlocking
- Test password verification
- Test audit logging
- Test settings storage
- All tests passing
Acceptance criteria met:
✅ User can enable auto-lock in Settings > General > Security
✅ User can configure inactivity timeout (1-120 minutes)
✅ After configured inactivity, session is locked
✅ Locked session shows lock screen with password prompt
✅ User can unlock with password (no username required)
✅ Activity tracking includes mouse/keyboard/scroll/touch
✅ Lock screen shows username and time of lock
✅ Failed unlock attempts logged for security
✅ Unit tests verify functionality
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude
---
scidk/core/auth.py | 153 +++++++++++++++-
scidk/ui/templates/base.html | 214 ++++++++++++++++++++++
scidk/ui/templates/settings/_general.html | 134 +++++++++++---
scidk/web/auth_middleware.py | 20 ++
scidk/web/routes/api_auth.py | 109 ++++++++++-
scidk/web/routes/api_settings.py | 175 ++++++++++++++++++
tests/test_auto_lock.py | 208 +++++++++++++++++++++
7 files changed, 980 insertions(+), 33 deletions(-)
create mode 100644 tests/test_auto_lock.py
diff --git a/scidk/core/auth.py b/scidk/core/auth.py
index 5ba0afd..83f642f 100644
--- a/scidk/core/auth.py
+++ b/scidk/core/auth.py
@@ -66,7 +66,7 @@ def init_tables(self):
"""
)
- # Active sessions table (updated with user_id)
+ # Active sessions table (updated with user_id and locked state)
self.db.execute(
"""
CREATE TABLE IF NOT EXISTS auth_sessions (
@@ -76,6 +76,8 @@ def init_tables(self):
created_at REAL NOT NULL,
expires_at REAL NOT NULL,
last_activity REAL NOT NULL,
+ locked INTEGER DEFAULT 0,
+ locked_at REAL,
FOREIGN KEY (user_id) REFERENCES auth_users(id) ON DELETE CASCADE
)
"""
@@ -112,6 +114,9 @@ def init_tables(self):
# Auto-migrate from single-user to multi-user on first run
self._migrate_to_multi_user()
+ # Migrate to add lock columns to auth_sessions
+ self._migrate_add_session_lock_columns()
+
def _migrate_to_multi_user(self):
"""Migrate from single-user auth_config to multi-user auth_users table.
@@ -154,6 +159,25 @@ def _migrate_to_multi_user(self):
except Exception as e:
print(f"Migration warning: {e}")
+ def _migrate_add_session_lock_columns(self):
+ """Add locked and locked_at columns to auth_sessions table if they don't exist."""
+ try:
+ # Check if locked column exists
+ cur = self.db.execute("PRAGMA table_info(auth_sessions)")
+ columns = [row[1] for row in cur.fetchall()]
+
+ if 'locked' not in columns:
+ self.db.execute("ALTER TABLE auth_sessions ADD COLUMN locked INTEGER DEFAULT 0")
+ print("Added locked column to auth_sessions table")
+
+ if 'locked_at' not in columns:
+ self.db.execute("ALTER TABLE auth_sessions ADD COLUMN locked_at REAL")
+ print("Added locked_at column to auth_sessions table")
+
+ self.db.commit()
+ except Exception as e:
+ print(f"Migration warning (session lock columns): {e}")
+
def is_enabled(self) -> bool:
"""Check if authentication is currently enabled.
@@ -906,6 +930,133 @@ def get_audit_log(self, since_timestamp: Optional[float] = None,
print(f"AuthManager.get_audit_log error: {e}")
return []
+ # ========== Session Locking ==========
+
+ def lock_session(self, token: str) -> bool:
+ """Lock a session (auto-lock feature).
+
+ Args:
+ token: Session token to lock
+
+ Returns:
+ bool: True if successful, False on error
+ """
+ try:
+ now = time.time()
+ self.db.execute(
+ "UPDATE auth_sessions SET locked = 1, locked_at = ? WHERE token = ?",
+ (now, token)
+ )
+ self.db.commit()
+ return True
+ except Exception as e:
+ print(f"AuthManager.lock_session error: {e}")
+ return False
+
+ def unlock_session(self, token: str, password: str) -> bool:
+ """Unlock a locked session with password verification.
+
+ Args:
+ token: Session token to unlock
+ password: Password to verify
+
+ Returns:
+ bool: True if unlock successful, False if password invalid or error
+ """
+ try:
+ # Get session info
+ cur = self.db.execute(
+ """
+ SELECT s.username, s.user_id, s.locked
+ FROM auth_sessions s
+ WHERE s.token = ?
+ """,
+ (token,)
+ )
+ row = cur.fetchone()
+
+ if not row or not row[2]: # Not found or not locked
+ return False
+
+ username, user_id = row[0], row[1]
+
+ # Verify password (try multi-user first)
+ if user_id is not None:
+ user = self.verify_user_credentials(username, password)
+ if not user:
+ return False
+ else:
+ # Legacy single-user verification
+ if not self.verify_credentials(username, password):
+ return False
+
+ # Unlock session
+ self.db.execute(
+ "UPDATE auth_sessions SET locked = 0, locked_at = NULL WHERE token = ?",
+ (token,)
+ )
+ self.db.commit()
+
+ # Log successful unlock
+ ip_address = None # Will be set by API route
+ self.log_audit(username, 'session_unlocked', 'Session unlocked', ip_address)
+
+ return True
+ except Exception as e:
+ print(f"AuthManager.unlock_session error: {e}")
+ return False
+
+ def is_session_locked(self, token: str) -> bool:
+ """Check if a session is currently locked.
+
+ Args:
+ token: Session token to check
+
+ Returns:
+ bool: True if session is locked, False otherwise
+ """
+ try:
+ cur = self.db.execute(
+ "SELECT locked FROM auth_sessions WHERE token = ?",
+ (token,)
+ )
+ row = cur.fetchone()
+ return bool(row and row[0]) if row else False
+ except Exception:
+ return False
+
+ def get_session_lock_info(self, token: str) -> Optional[Dict[str, Any]]:
+ """Get lock information for a session.
+
+ Args:
+ token: Session token
+
+ Returns:
+ dict or None: Lock info with keys: username, locked, locked_at
+ """
+ try:
+ cur = self.db.execute(
+ """
+ SELECT username, locked, locked_at
+ FROM auth_sessions
+ WHERE token = ?
+ """,
+ (token,)
+ )
+ row = cur.fetchone()
+
+ if not row:
+ return None
+
+ return {
+ 'username': row[0],
+ 'locked': bool(row[1]),
+ 'locked_at': row[2],
+ }
+ except Exception as e:
+ print(f"AuthManager.get_session_lock_info error: {e}")
+ return None
+
def close(self):
"""Close database connection."""
try:
diff --git a/scidk/ui/templates/base.html b/scidk/ui/templates/base.html
index 7e832d7..7df4b81 100644
--- a/scidk/ui/templates/base.html
+++ b/scidk/ui/templates/base.html
@@ -122,6 +122,220 @@