Commit Graph

234 Commits

Author SHA1 Message Date
32c8bbe0a9 Update 2026-07-07 15:28:28 +02:00
499f91e16a feat: add container manager API, islop router, and container runtime files with vim/bot/d stealth clients
Some checks failed
DevPlace CI / test (push) Failing after 38m17s
2026-07-06 03:58:46 +00:00
9a8046ab2a feat: add ISSLOP AI usage analysis CLI commands, game router, and politics topic
- Add `cmd_isslop_prune`, `cmd_isslop_clear`, `cmd_isslop_analyze` CLI commands for AI usage analysis job management
- Register `/game` router with `index` and `farm` endpoints for Code Farm idle game
- Add `politics` to allowed TOPICS constant replacing `signals`
- Introduce `ISSLOP_DIR`, `ISSLOP_WORKSPACES_DIR`, `ISSLOP_RUNS_DIR`, `ISSLOP_MEDIA_DIR` config paths
- Add `clear_user_stars` and `clear_user_projects_cache` calls on vote and project create/delete
- Update `make prod` to use `nproc` workers via `DEVPLACE_WEB_WORKERS` env var
- Convert `database.py` and `utils.py` to packages for modular structure
- Add `devplace apikey` and `devplace token` CLI subcommands for API key and access token management
2026-07-06 03:57:47 +00:00
f1bdefd834 feat: add _sanitize_mentions helper and apply to comment/reply truncation
Introduce a new `_sanitize_mentions` method in `BotHelpersMixin` that deduplicates and removes self-mentions from text, using a compiled regex for `@handle` patterns. Apply this sanitizer before the 2000-character truncation in both `engage.py` comment posting and `social.py` reply posting to prevent duplicate or self-referential mentions from being cut off mid-handle. Additionally, fix profile URL parsing in `social.py` to strip trailing path segments, and refine `LLMClient.clean` to handle asterisks and underscores more precisely without breaking adjacent alphanumeric characters.
2026-07-04 23:08:41 +00:00
0f872336b1 feat: add online presence tracking with last_seen column and configurable timeout
Add `last_seen` column to users table with index, implement `set_last_seen` and `get_online_users` database functions, expose presence config env vars (`PRESENCE_TIMEOUT_SECONDS`, `PRESENCE_ONLINE_LIMIT`, `PRESENCE_ONLINE_MARGIN_SECONDS`), include `last_seen` in follow list responses, and update profile docs to mention online indicator.
2026-07-04 22:08:20 +00:00
7002b23eeb feat: add clickable activity cards with comment anchor links to profile tab
Add `url` field to profile activity items so post cards link to `/posts/{slug}` and comment cards link to the parent post with a `#comment-{uid}` anchor, matching notification click behavior. Include the shared `_card_link.html` overlay in the template, fix XP bar rendering for missing `xp` key, and add API + e2e tests verifying the link structure and navigation.
2026-07-04 20:24:59 +00:00
c79dfd0291 refactor: split database.py into package (ref.md 3.2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 19:22:11 +00:00
8daee65011 refactor: split utils.py into package (ref.md 3.8) 2026-07-04 19:18:19 +00:00
7de7e29d3e refactor: split docs_api.py into package (ref.md 3.1) 2026-07-04 19:17:56 +00:00
d556b02bfb refactor: split cli.py into package (ref.md 3.7) 2026-07-04 19:17:59 +00:00
574b076f5d refactor: split bot.py into mixins (ref.md 3.3)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 19:19:39 +00:00
f521a1130e refactor: split devii session.py into package (ref.md 3.10) 2026-07-04 19:16:33 +00:00
b57e657cf8 refactor: split news.py into package (ref.md 3.9)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 19:23:51 +00:00
0e8b015fe1 refactor: split schemas.py into package (ref.md 3.6) 2026-07-04 19:16:34 +00:00
d45bb37ce1 refactor: split devii catalog.py into package (ref.md 3.5)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 19:16:32 +00:00
4618089cea refactor: split game store.py into subpackage (ref.md 3.11) 2026-07-04 19:16:33 +00:00
9151876770 chore: add monster-file split plan (ref.md) 2026-07-04 19:33:00 +00:00
3fbac87723 feat: replace inline IP resolution with centralized client_ip utility across routers and audit
Some checks failed
DevPlace CI / test (push) Failing after 36m45s
Consolidate scattered `X-Real-IP` / `request.client.host` fallback logic into the single `client_ip()` helper from `utils`, reducing duplication in the rate limiter middleware, project file zip routes, tools shared module, and audit record builder. Also refactor three admin endpoints (`/ai-usage/data`, `/analytics`, `/users/{uid}/ai-usage`) to use the existing `require_admin()` guard instead of repeating manual auth checks, and remove now-unused `get_current_user`/`is_admin` imports from those modules.
2026-07-04 18:07:33 +00:00
244a524b91 feat: add authenticated my-profile endpoint and clean breadcrumb markdown in SEO context
- Add GET /profile route returning own profile page with tab support, backed by new my_profile_page handler in profile/index.py and documented in docs_api.py
- Introduce _clean_breadcrumbs helper in seo.py that strips markdown from breadcrumb names before passing to schema generation
- Skip data-confirm modal for elements with data-auto-submit attribute in ModalManager.js
- Guard PushManager subscription against missing userUid and capture it from document body dataset
- Switch profile bio template from render_title to render_content and use div instead of span for proper block rendering
2026-07-01 13:15:33 +00:00
6f340a6818 feat: add per-user avatar seed regeneration with irreversible random avatar replacement
Implement a new `avatar_seed` column on the users table that overrides the username-based seed for Multiavatar generation. Introduce a null-safe `avatar_seed(user)` choke point in `avatar.py` that resolves `user.get("avatar_seed") or user.get("username")`, registered as a Jinja global so every render site (`_avatar_link.html`, `avatar_url(...)` calls, SEO `og_image`, issues ad-hoc dicts, devRant payload/PNG) propagates a regenerated seed. Add `POST /profile/{username}/regenerate-avatar` endpoint (owner-or-admin only) that writes a fresh `generate_uid()` to `avatar_seed`, invalidates the target's user cache, and audits `profile.avatar.regenerate`. The previous seed is overwritten and never stored, making regeneration irreversible. Document the feature in `AGENTS.md` and `README.md`, add the API endpoint to `docs_api.py`, and include the `regenerate_avatar` Devii tool in `CONFIRM_REQUIRED`.
2026-06-27 22:31:34 +00:00
e773067106 feat: add test suites for backup schedules, service config, auth token, bookmarks, content permissions, devii adopt, and devrant auth
All checks were successful
DevPlace CI / test (push) Successful in 35m0s
Add comprehensive test coverage for seven new API areas:
- Backup schedules CRUD operations in admin panel
- Service configuration saving and retrieval for news AI model
- Token authentication with email/username and JSON body support
- Bookmarking for project and news targets with invalid type validation
- Content permissions testing with member and admin session fixtures
- Devii adopt endpoint redirect behavior and session cookie handling
- Devrant authentication flow with user registration and token retrieval
2026-06-23 00:47:40 +00:00
34e33995c4 feat: add alt text extraction from URLs for images and improve CSS variable usage for progress bars
All checks were successful
DevPlace CI / test (push) Successful in 32m28s
Add `_alt_from_url` helper in Python rendering and `altFromUrl` in JS ContentRenderer to generate descriptive alt attributes from image filenames, replacing empty alt strings. Update image embed templates and Avatar component to use derived alt text. Migrate inline `style.width` assignments to CSS custom properties (`--poll-pct`, `--hud-xp`, `--quest-pct`, `--bar-pct`, `--quota-pct`) across PollManager, GameFarm, and profile/quest CSS for better maintainability. Introduce new admin, docs, projects, services, and base CSS utility classes. Add "Code Farm" docs page entry.
2026-06-22 23:13:48 +00:00
c9a4a4b280 feat: add content_preview helper and apply rendered content across templates
Some checks failed
DevPlace CI / test (push) Failing after 31m46s
Introduce a new `content_preview()` function in `rendering.py` that strips HTML from rendered content and truncates to a given length with an ellipsis. Add a corresponding `plainText()` and `preview()` method to the `ContentRenderer` JS class. Register `content_preview` as a Jinja2 global in `templating.py`. Update multiple templates (`feed.html`, `gists.html`, `landing.html`, `messages.html`, `news.html`, `notifications.html`, `post.html`, `profile.html`) to use `render_title`, `render_content`, or `content_preview` instead of raw string slicing, ensuring consistent rendering of rich text (e.g., Markdown, HTML) in previews, descriptions, bios, and notification messages. Also fix the conversation preview in `MessagesLayout.js` to use the new JS preview method.
2026-06-22 21:17:54 +00:00
e0e64c8d9e feat: add telegram notification channel with outbox service and per-user preferences
Extend the notification system with a third channel (telegram) alongside existing in_app and push channels. Add `telegram_enabled` column to `notification_preferences` table, update `NOTIFICATION_CHANNELS` and `_NOTIFICATION_CHANNEL_COLUMNS` mappings, and set telegram default to off (`_NOTIFICATION_CHANNEL_DEFAULTS`). Create `telegram_outbox` table with columns for uid, user_uid, chat_id, text, status, attempts, created_at, and sent_at, plus an index on status/id for efficient polling. Register `TelegramOutboxService` in the service manager lifecycle. Update API documentation strings to describe the new channel and its pairing requirement. Extend admin notification defaults view to include telegram column. Pass `notif_telegram_paired` flag to profile template based on `telegram_store.is_paired()` check. Update `NotificationPrefForm` and `NotificationDefaultForm` model literals to accept "telegram" as a valid channel value.
2026-06-22 20:52:02 +00:00
a9d0814c47 feat: restructure topnav with right-aligned icon-only tools and leaderboard
Move Leaderboard link into a right-aligned icon-only button group alongside Tools dropdown, converting both from text+caret to compact icon buttons. Adjust dropdown menu alignment from left to right and remove redundant caret styling.
2026-06-22 17:53:20 +00:00
412dbe3a3d feat: add steal mechanic to Code Farm with 60s protection window and half-coin reward 2026-06-22 17:33:03 +00:00
ebf6bf7f82 feat: add Code Farm cooperative idle game with plot-based crop system and pub/sub notifications
Implement a Farmville-style cooperative idle game mounted at `/game` with member-only play and public farm viewing. The data layer is pure and timestamp-driven with no background tick: plot states are derived from `ready_at` vs current time, never stored. Key features include plantable software projects (shell script through kernel) that build over real time, harvest for coins and XP, CI tier upgrades for faster builds, plot purchasing with doubling cost, watering mechanics for friends' builds, daily quests, and prestige system. All game endpoints negotiate HTML or JSON and return full farm state for single-request client refresh. Pub/sub notifications broadcast farm updates on `public.game.farm.{username}` topics. Database schema adds `game_farms`, `game_plots`, and `game_quests` tables with appropriate indexes.
2026-06-22 16:41:53 +00:00
743efbf61f feat: add nested comment reply indicators and responsive flat-reply styling
Add `comment-reply-to` span showing parent author with ↳ indicator in comment headers, and introduce `.comment-replies-flat` dashed border style for deeply nested threads. Adjust responsive spacing: reduce comment gap and vote min-width on mobile, hide reply-to indicator on small screens, and increase reply padding for better readability.
2026-06-21 18:13:41 +00:00
19cc85f409 fix: correct audit event names, attachment deletion, redirect safety, and add account deactivation check
- Fix audit event names in CLI prune/clear commands from `cli.seo.*` to `cli.seo_meta.*`
- Refactor `_delete_attachment_file` to accept full attachment dict instead of storage_path string, using directory and stored_name fields with ATTACHMENTS_DIR
- Add `safe_next` validation for referer header in validation error redirect and media redirect
- Add `is_active` check in login router to reject deactivated accounts with "Account is deactivated" error
- Replace raw `request.headers.get("Referer")` with `redirect_back()` utility in bookmarks, polls, reactions, and votes routers
- Move `mark_conversation_read` call from `get_conversation_messages` to `messages_page` to avoid side effects during message retrieval
- Fix poll audit link to use `option.get("label")` instead of `option.get("text")`
- Add `VOTABLE` set validation in votes router to reject invalid target types with 400 response
- Strip control characters (0x00-0x20) from URLs in `_safe_url` instead of simple strip
- Add `__getattr__` fallback in services `__init__.py` for dynamic attribute access
2026-06-21 16:46:27 +00:00
a3dd747d07 fix: clear rate-limit hot-settings cache and add retry loop for maintenance-mode tests
All checks were successful
DevPlace CI / test (push) Successful in 29m11s
- Invalidate `_hot_settings_value` and `_hot_settings_at` in `_patch_limits` so stale
  cached limits from prior tests do not persist after monkey-patching `get_int_setting`.
- Add a polling retry loop (up to 5 seconds) in `test_maintenance_mode_blocks_guests`
  to handle eventual consistency of the maintenance-mode flag propagation.
- Replace brittle hardcoded `@bob_test` assertion in mention test with dynamic
  `data-username` attribute extraction from the active dropdown item.
- Replace `asyncio.run` calls in bot unit tests with shared `run_async` helper from
  `tests.conftest` to avoid event-loop conflicts in the test suite.
- Change `insert` to `upsert` with `["uid"]` conflict target in Gitea test fixture
  to prevent duplicate-key errors on repeated test runs.
- Replace `asyncio.new_event_loop().run_until_complete` in Telegram worker tests
  with the same shared `run_async` helper for consistency.
2026-06-19 23:21:53 +00:00
dc8ae8a099 chore: add faker dependency to pyproject.toml for test data generation 2026-06-19 22:36:11 +00:00
e393722600 feat: add author-username search to feed/gists/projects listings and partial-index migration
Some checks failed
DevPlace CI / test (push) Failing after 2m5s
Extend `database.text_search_clause` with an `author_field` parameter that resolves username matches to user UIDs, enabling author-username search across the three public listings (`/feed`, `/gists`, `/projects`). Update the corresponding API docs and README route descriptions to reflect the new search scope. Add six partial indexes (`idx_comments_target_live`, `idx_votes_target_live`, `idx_reactions_target_live`, `idx_gists_live_created`, `idx_projects_live_created`, `idx_attachments_user_created_live`) to optimize filtered queries on non-deleted rows. Introduce a hot-settings cache (`_hot_settings`) with a 2-second TTL for `maintenance_mode`, `rate_limit_per_minute`, and `rate_limit_window_seconds`, plus a periodic rate-limit store sweep (`_sweep_rate_limit_store`) to evict stale IP entries every 60 seconds. Add `GZipMiddleware` to the FastAPI app for response compression.
2026-06-19 22:24:51 +00:00
d10f1af118 feat: add seo_meta service for AI-generated SEO metadata with CLI management and database layer
Some checks failed
DevPlace CI / test (push) Failing after 2m13s
Implement a new `SeoMetaService` subservice that generates clean SEO title/description/keywords for published content items, distinct from the existing SEO diagnostics auditor. Add `seo_metadata` polymorphic table with soft-delete support, batch query methods, and usage tracking. Extend the CLI with `seo-meta prune` and `seo-meta clear` commands for job row lifecycle management. Wire `schedule_seo_meta_for_table` into content creation and editing flows in `content.py`. Document the new service in `AGENTS.md` and `README.md`, including the `extra_head` site setting for custom `<head>` injection.
2026-06-19 20:15:22 +00:00
426d3639c6 chore: replace planning-header layout with hidden rule and restructure ticket list grid
Remove the `.planning-header` flex container and `.planning-status` spinner block, add a global `[hidden]` display rule, increase `.planning-ticket-list` max-height to 26rem, and convert ticket labels from inline flex to a CSS grid with tabular-nums on the count.
2026-06-19 15:32:47 +00:00
1350e7fc66 feat: add optional ticket selection to planning report generation
Add a `numbers` form field to the planning report endpoint, allowing
admins to generate a report for a specific subset of open tickets
instead of always planning all open tickets. The selected numbers are
parsed from a comma-separated string, deduplicated, and passed to the
background job. The job's scope is recorded in the audit log and the
Devii tool description is updated to document the new parameter.
2026-06-19 12:25:51 +00:00
ff3cbbbfe2 feat: add issue_usage tracking and metrics for AI ticket enhancement and planning
Add `issue_usage` table with columns for user_uid, tokens, cost, and latency metrics, including a unique index on user_uid. Wire `accumulate_usage` into `enhance_ticket` and `generate_plan` to capture per-request AI usage, persist totals via `add_issue_usage` in both `IssueCreateService` and `PlanningReportService`, and expose aggregated usage as metric cards through `IssueTrackerService.collect_metrics`. Update planning API docs summary to reflect the new phased implementation document format.
2026-06-19 11:59:40 +00:00
7bbaf51450 feat: add file attachment support to issue tracker with Gitea mirroring
Implement full attachment CRUD for issues and comments, restricted to open issues only. Attachments are stored locally and mirrored to the Gitea tracker via new `mirror_attachment_to_gitea` and `set_gitea_asset_id` functions. Add `gitea_asset_id` column to the attachments table, extend `IssueForm` and `IssueCommentForm` with `attachment_uids` field, and expose new API endpoints for listing, adding, and deleting issue attachments. Update agent configuration to include web research tools, and document the new capability in README, AGENTS.md, and CLAUDE.md.
2026-06-19 11:22:05 +00:00
a6cc83bfd2 feat: add aria.md command file for WCAG 2.2 AA+ accessibility auditing workflow
Introduce a new Claude agent command file at `.claude/commands/aria.md` that defines an accessibility specialist persona with comprehensive WCAG 2.2 AA+ auditing capabilities. The command includes detailed project rules for semantic HTML, ARIA attributes, keyboard accessibility, dynamic content handling, and landmark regions, along with a structured workflow for codebase analysis and section-by-section upgrades.
2026-06-19 09:01:10 +00:00
4ccdc5f4b8 feat: replace fixed aspect-ratio thumbnails with natural image dimensions across gallery, feed, media, and news components 2026-06-19 09:00:22 +00:00
a6aa2ad357 feat: add CHANGELOG.md with release history from 2026-06-15 to 2026-06-19
Introduce a new changelog file documenting feature releases, bug fixes, and infrastructure changes across multiple dates, including user relations, news service, backup management, and gateway admin UI.
2026-06-19 08:38:56 +00:00
741d7aade6 docs: add block/mute user relations, emoji-sync CLI, and uid indexes
Some checks failed
DevPlace CI / test (push) Failing after 2m7s
- Add `/block`, `/mute` endpoints with block/unblock and mute/unmute functionality in `routers/relations.py`, hiding blocked users' content everywhere except their own profile while muting only suppresses notifications
- Introduce `devplace emoji-sync` CLI command to regenerate `static/js/emoji-shortcodes.js` from the emoji library, documented in `CLAUDE.md` and wired in `cli.py`
- Create `get_blocked_uids()` database helper and apply it in `content.py` `load_detail()` to filter blocked users' posts from detail views
- Implement `_uid_index()` and `_drop_index()` helpers in `database.py` for unique uid indexes across tables, with `user_relations` added to `SOFT_DELETE_TABLES`
- Document new routes in `AGENTS.md` and `README.md`, including emoji shortcodes rendering behavior distinct from the emoji picker
2026-06-19 08:06:09 +00:00
f3a4667fce feat: add AI markdown reformatting and usage metering to NewsService
Add AI-powered body reformatting for valid articles in the news pipeline, converting raw text walls into clean Markdown with paragraphs, headings, and lists. Introduce `news_usage` database table and `add_news_usage`/`get_news_usage` helpers to track per-cycle gateway costs (calls, tokens, latency, USD) from response headers, reported on the admin Services page. Remove unused `.sidebar-more` CSS and apply `render_title()` to poll question/label fields.
2026-06-18 23:46:53 +00:00
6ceca3d0d4 docs: document server-side rendering pipeline, response timing middleware, and Telegram pairing API
- Add comprehensive documentation for backend content rendering in AGENTS.md, detailing the new `render_content` and `render_title` Jinja globals built on mistune with media processing, emoji shortcodes, and XSS protection
- Document the `X-Response-Time` header and bottom-left render time indicator in README.md
- Update bot token pricing documentation to clarify fallback vs gateway cost headers
- Add `email_accounts` to soft-delete tables and `idx_users_role` composite index in database schema
- Implement `telegram_pairings` and `telegram_links` table creation with column migration and indexes
- Add `/profile/{username}/telegram` endpoint to docs API with request/unpair actions
- Register `TelegramService` in main.py lifespan and add `response_timing` middleware emitting `X-Response-Time` header
- Introduce `TelegramPairForm` model and `guard_public_host_sync` synchronous host validation function
2026-06-18 22:09:34 +00:00
95dca73291 feat: add DevPlace agent, auth token service, and form-data dependency modules
Add DevPlace agent configuration with dynamic OpenAPI schema fetching, implement access token issuance/resolution/revocation with configurable expiry, and create generic FastAPI dependency for JSON or form-encoded data validation against Pydantic models. Include comprehensive unit tests for form-data parsing and token lifecycle operations.
2026-06-17 17:11:47 +00:00
9598a1b867 feat: add wildcard token support for allowed extensions and access token CLI commands
Introduce WILDCARD_TOKENS set in attachments.py to treat "*", ".*", "*.*" as wildcards that fall back to ALLOWED_UPLOAD_TYPES. Add cmd_token_issue and cmd_token_list CLI commands for issuing and listing DevPlace access tokens. Register access_tokens table in SOFT_DELETE_TABLES and initialize its columns and indexes in init_db. Replace Form() with Depends(json_or_form(...)) in admin backup, container, notification, settings, and user routers to support both JSON and form data.
2026-06-17 17:10:52 +00:00
217210e02f feat: add featured/locked columns and auto-rotation logic to news pipeline
- Add `ai_grade`, `featured`, `featured_locked`, `landing_locked`, `author`, `article_published`, `image_url`, `has_unique_image` columns to news table
- Extend `news_images` schema with `alt_text`, `phash`, `width`, `height`, `is_placeholder` columns
- Create `idx_news_featured` index for efficient featured queries
- Update admin toggle endpoints to set `featured_locked`/`landing_locked` when manually toggling
- Propagate `featured` and `image_url` fields through landing page, news list, and detail page rendering
- Update `get_featured_news` to return `featured` and `image_url` fields
- Document in AGENTS.md the full zero-maintenance pipeline: image perceptual hashing, placeholder detection, AI grading on cleaned text, reliability gate, effective score computation, and post-loop landing rotation
- Update README.md service description to reflect automatic image comparison and landing rotation capabilities
- Clarify docs_api.py summaries that toggling featured/landing now locks articles from auto-rotation
2026-06-18 22:08:41 +00:00
0a554ebc32 feat: restrict backup archive download to primary admin and hide admin-hidden projects from other admins
Some checks failed
DevPlace CI / test (push) Failing after 22m57s
- Add `get_admin_uids()` and `get_primary_admin_uid()` to database.py for resolving the earliest-created admin
- Modify `can_view_project()` in content.py so a project hidden by an admin is invisible to other admins (both web UI and REST API)
- Update `_download_url()` and `_backup_payload()` in admin/backups.py to accept a `can_download` flag, gating the download endpoint with `is_primary_admin()`
- Remove `role` from `_user_facts()` in docs_live.py to avoid leaking admin status in live docs
- Update doc summaries in docs_api.py to reflect the new admin-visibility and backup-download semantics
2026-06-17 14:08:28 +00:00
6b5347103b fix: replace flex shorthand with single value and refactor mobile keyboard inset logic in messages layout 2026-06-16 15:22:41 +00:00
dcb3f08ac1 feat: add name-based lookup fallback and terminal session management for containers
Add name field as third fallback in get_instance lookup chain to support
container retrieval by display name. Introduce new terminal.py module
with async PTY session handling, pubsub-based I/O streaming, resize
control, and audit logging for container exec sessions.
2026-06-16 14:54:22 +00:00
35040204c9 fix: comment out optimistic message append to prevent duplicate bubbles in MessagesLayout 2026-06-16 14:18:19 +00:00