mirror of
https://github.com/hanzoai/team.git
synced 2026-09-30 01:57:35 +00:00
master
100
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
60af6c5c86 |
Add weekly recurring scheduled posts (#37746)
* Add weekly recurring scheduled posts. Extend scheduled posts so users can schedule weekly repeats and keep the series healthy across sends, reschedules, and UI updates instead of falling back to one-shot behavior. Made-with: Cursor * Add Playwright coverage for recurring scheduled posts. Cover weekly recurring scheduled messages in the scheduled-messages spec so the recurring UI and reschedule flow stay protected without adding a separate test surface. Made-with: Cursor * Fix recurring scheduled post CI failures. Resolve the initial lint and formatting issues and renumber the new scheduled-post migration so it no longer collides with master during Postgres-backed test setup. Made-with: Cursor * Sync recurring scheduled post translation files. Regenerate the affected English translation catalogs so the recurring scheduled post strings match the source extraction order expected by CI. Made-with: Cursor * Fix recurring scheduled post review follow-ups. Preserve overdue cleanup behavior during weekly catch-up, defer delete websocket events until deletion succeeds, and address the remaining migration and UI review nits. Made-with: Cursor * Address recurring scheduled post review feedback Made-with: Cursor * Fix recurring scheduled post CI checks Made-with: Cursor * Make pending scheduled post keyset cursor index-scannable EXPLAIN ANALYZE on a 5M-row ScheduledPosts table showed the pure OR-form cursor forced Postgres to scan idx_scheduledposts_pending_scheduled_at_id from the top on every page (~383ms/page, ~2M rows filtered). Keeping the ScheduledAt <= beforeTime bound outside the tie-break restores the index boundary (~0.12ms/page). Adds storetest coverage for cursor pagination. Co-authored-by: nick.misasi <[email protected]> * Address code quality review findings for recurring scheduled posts Server: - Replace silent-fallback AdvanceWeeklyScheduledNextOccurrence with error-returning ScheduledPost.ComputeNextScheduledAt; a recurring post whose timezone fails to load is now routed through the failed-post path instead of being reposted every job run or silently deleted - Add ScheduledPost.IsRecurring and partition batches in processScheduledPostBatch; advance/delete now run independently so a store failure in one path can't cause reposts in the other - Drop dead generality in UpdateRecurringScheduledPosts (only ScheduledAt varies per row; ErrorCode/ProcessedAt are constants) - Simplify redundant repeat-type condition in GetPendingScheduledPosts Webapp: - Add shared isRecurringScheduledPost helper, replacing six scattered repeat_type === 'weekly' literals - Recurrence timezone is now simply the scheduler's current timezone; removes initialRepeatTimezone/effectiveTimezone plumbing and the modal-label/picker timezone mismatch - Single enforcement point for hiding send-now on recurring posts - Use canonical getTeamIdByChannelId at both SCHEDULED_POST_UPDATED dispatch sites; rewrite errorsByTeamId update case as remove-then-add and add reducer tests Co-authored-by: nick.misasi <[email protected]> * Simplify recurring scheduled post code per review - End a recurring series when its channel no longer exists instead of advancing it forever (matches the one-shot channel-not-found handling) - Collapse the errorsByTeamId SCHEDULED_POST_UPDATED case into the identical SINGLE_SCHEDULED_POST_RECEIVED case (a scheduled post's team can't change) and combine duplicate byId cases; preserves state references on no-op updates - Drop no-op timezone conversions in ComputeNextScheduledAt - Remove redundant checkbox aria-label (label htmlFor already names it) - Schedule new job tests in the past instead of sleeping a real second - Remove redundant test assignment and e2e positional boolean Co-authored-by: nick.misasi <[email protected]> * Remove slop from recurring scheduled post changes - Drop the business-rule CHECK constraint from the recurrence migration; no other migration enforces model-layer validation in the database, and BaseIsValid plus the job's failure handling already own it - Fold the standalone repeat-validation test file into the existing TestScheduledPostBaseIsValid, matching its conventions - Revert unrelated benchmark modernization in utils_test.go - Drop an unneeded cast, unused fixture fields, and naming/assertion inconsistencies in tests Co-authored-by: nick.misasi <[email protected]> * Regenerate ScheduledPostStore mock with mockery ordering Co-authored-by: nick.misasi <[email protected]> * Address CodeRabbit review feedback - Reject the host-dependent 'Local' value for RepeatTimezone; recurring schedules need a fixed zone (UTC or IANA name) - Hide reschedule for deactivated DMs, matching send-now eligibility Co-authored-by: nick.misasi <[email protected]> * Resolve scheduled post team bucket from existing state when channel is unloaded An admin can reschedule before fetchMissingChannels resolves, in which case deriving the team from the channel returns undefined and the update was misfiled under directChannels. getScheduledPostTeamId falls back to the byTeamId bucket that already holds the post. Co-authored-by: nick.misasi <[email protected]> * Retrigger CI after transient enterprise npm network failure Co-authored-by: nick.misasi <[email protected]> * Clear hover/focus before asserting scheduled post header details in e2e The drafts panel hides its timestamp/tag info section while hovered or focus-within; after the reschedule modal closes, focus returns to the row and the 'Repeats weekly' tag assertion saw a hidden element. Co-authored-by: nick.misasi <[email protected]> * Move recurrence columns into baseColumns and dispatch ComputeNextScheduledAt on repeat type Co-authored-by: nick.misasi <[email protected]> * Preserve recurrence when scheduled post updates omit repeat fields Co-authored-by: nick.misasi <[email protected]> * Disallow file attachments on recurring scheduled posts Co-authored-by: nick.misasi <[email protected]> * Stop pinning the channel indicator for recurring-only scheduled posts Co-authored-by: nick.misasi <[email protected]> * Re-home nullable-Type comment onto baseColumns Co-authored-by: nick.misasi <[email protected]> * Gate recurring scheduled posts behind a default-off feature flag Co-authored-by: nick.misasi <[email protected]> * Move presence-preservation rationale to the copy site Co-authored-by: nick.misasi <[email protected]> * Extract draftHasAttachments helper and require allowRecurring at single-caller layers Co-authored-by: nick.misasi <[email protected]> * Return null from the indicator selector when nothing should show Co-authored-by: nick.misasi <[email protected]> * Gate only recurrence transitions and preserve existing series in the modal Co-authored-by: nick.misasi <[email protected]> * Avoid err shadowing in scheduled post update handler Co-authored-by: nick.misasi <[email protected]> * Disable the repeat weekly checkbox with a tooltip when the message has attachments Co-authored-by: nick.misasi <[email protected]> * Return an explicit disposition from postScheduledPost The batch loop inferred 'channel permanently gone' from the one return path with a nil error and an error code set - an invariant a future change could silently break, deleting recurring series by accident. postScheduledPost now returns posted/failed/unsendable explicitly, the switch refuses to delete on an unhandled disposition, and a test pins that both recurring and one-shot posts in a nonexistent channel are permanently deleted. Co-authored-by: nick.misasi <[email protected]> * Fix Repeat weekly attachments tooltip centering on the modal row (#37927) Shrink-wrap the repeat checkbox row so WithTooltip anchors to the control/label instead of the full modal body width. --------- Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
3e6e5ad2f4 |
[MM-70130] Add permanent banner for non-production developer license keys (#37846)
* [MM-70130] Add permanent banner for non-production developer license keys Co-authored-by: nick.misasi <[email protected]> * [MM-70130] Update non-production license banner text Co-authored-by: Nick Misasi <[email protected]> --------- Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
0668bdbdfa |
ABAC: plugin-keyed resource types, trusted plugin PAP/CEL APIs, and AuthZEN-style decision API (#37509)
* MM: add v0.5 plugin access control policy model, registry, and decision outcomes Co-authored-by: nick.misasi <[email protected]> * MM: add plugin access control PDP/PAP app-layer methods with fail-closed semantics Co-authored-by: nick.misasi <[email protected]> * MM: expose plugin access control API surface (EvaluateAccessControl + PAP/CEL methods) Co-authored-by: nick.misasi <[email protected]> * MM: add store-layer round-trip tests for v0.5 plugin access control policies Co-authored-by: nick.misasi <[email protected]> * MM: extract plugin access control app code into plugin_access_control.go Co-authored-by: nick.misasi <[email protected]> * MM: add atomic type-guarded AccessControlPolicyStore.DeleteIfType Co-authored-by: nick.misasi <[email protected]> * MM: plugin PAP hardening — atomic typed delete, indistinguishable 404s, audit every attempt Co-authored-by: nick.misasi <[email protected]> * MM: close plugin Get-by-ID TOCTOU via GetPolicyOfType; stamp save audit operation at entry Co-authored-by: nick.misasi <[email protected]> * Fix gob RPC poisoning from native attribute select options NativeUserAttributeFields stored bool-select options as []map[string]string inside PropertyField.Attrs (map[string]any). gob requires concrete types inside interface values to be registered, and []map[string]string is not registered in client_rpc.go, so encoding the GetAccessControlFieldsAutocomplete reply failed and net/rpc shut down the shared plugin API connection, breaking every subsequent plugin API call. Build the options from gob-registered containers ([]any/map[string]any) instead; JSON output is byte-identical. Add gob round-trip regression tests covering every plugin access control API reply payload: the autocomplete response including native attribute fields (fails against the old code), policies with JSON-decoded Props, visual AST condition values of every runtime shape, expression check errors, query users responses, and evaluation decisions. Co-authored-by: nick.misasi <[email protected]> * Move plugin access control gob-safety tests into their own file Pure move: plugin_access_control_test.go crossed 1000 lines; the gob-safety helper and TestPluginAccessControlGobSafety now live in plugin_access_control_gob_test.go, unchanged. Co-authored-by: nick.misasi <[email protected]> * MM: resolve plugin policy existence when ABAC is unavailable (Option B) Every evaluation-impossible branch of EvaluatePluginAccessRequest (service nil / unlicensed / flag off / user load or subject build failure / evaluator infra error / unknown outcome) now performs a raw open-core store read on the already-validated resource ID: no stored row returns no_policy so the caller can safely apply legacy behavior; any stored row (with a Warn on a foreign-type anomaly) or a failed read returns unavailable so the caller must fail closed. This lets the plugin drop its local policy index entirely. Strengthens the EvaluateAccessControl doc contract accordingly and reworks the fail-closed test matrix with with/without-row splits per branch, a foreign-type-row case, a store-read-error case on the store mock, and passthrough rows pinning that the fallback read never runs when the evaluator answers. Co-authored-by: nick.misasi <[email protected]> * Clarify EvaluateAccessControl failure-mapping doc A failure with a definitive store miss maps to no_policy under the Option B semantics, so 'failures never map to allow or no_policy' was inaccurate. State precisely: never allow; no_policy only on positively determined non-existence; deny for defensive failures on a resolved policy; unavailable otherwise. Co-authored-by: nick.misasi <[email protected]> * Tighten ABAC comments Co-authored-by: nick.misasi <[email protected]> * Document AccessDecision.Outcome as plugin-API-only The evaluator populates Outcome on every lane, but the only production reader is the app layer's EvaluatePluginAccessRequest, which maps it into PluginAccessControlDecision; core channel/team enforcement reads the collapsed Decision bool alone. State that on the field. Co-authored-by: nick.misasi <[email protected]> * Retrigger CI to rebuild enterprise image with updated enterprise branch Co-authored-by: nick.misasi <[email protected]> * Document that only the evaluator's plugin lane sets AccessDecision.Outcome Co-authored-by: nick.misasi <[email protected]> * ABAC: key plugin resource types as plugin_id:type and drop the static registry Co-authored-by: nick.misasi <[email protected]> * ABAC: replace AccessDecision.Outcome with the AuthZEN decision context reason Co-authored-by: nick.misasi <[email protected]> * ABAC: drop type-scoped policy get/delete and check the type in the app layer Co-authored-by: nick.misasi <[email protected]> * ABAC: compare plugin policy type ownership exactly instead of case-insensitively Co-authored-by: nick.misasi <[email protected]> * ABAC: bound the whole policy type to the Type column width Co-authored-by: nick.misasi <[email protected]> * ABAC: require an allow before treating a decision as the no-policy fallback Co-authored-by: nick.misasi <[email protected]> * ABAC: treat a colliding foreign-type policy row as no_policy, not a deny Co-authored-by: nick.misasi <[email protected]> * ABAC: gate plugin policy reads on a raw store read before normalization Co-authored-by: nick.misasi <[email protected]> * ABAC: pin policy type immutability on save in the store tests Co-authored-by: nick.misasi <[email protected]> * ABAC: reuse a single unavailable-error constructor in the existence fallback Co-authored-by: nick.misasi <[email protected]> * ABAC: re-check plugin policy ownership on the normalized get read Co-authored-by: nick.misasi <[email protected]> * ABAC: confirm plugin policy ownership before surfacing a normalization error Co-authored-by: nick.misasi <[email protected]> --------- Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
ab16572738 |
Prepackage mattermost-plugin-agents v2.5.1 (#37727)
* Prepackage mattermost-plugin-agents v2.5.0. * Prepackage mattermost-plugin-agents v2.5.1. --------- Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
68be9f59bf |
MM-67336: Request structured JSON output for AI message rewrites (#37581)
Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
4dc628cde7 |
ABAC: share TableEditor/CELEditor with plugins via window.Components (#37510)
* Add injectable actions to ABAC CEL and table editors Co-authored-by: nick.misasi <[email protected]> * Expose lazy ABAC policy editors on window.Components Co-authored-by: nick.misasi <[email protected]> * Address review: window.Components assertions, CEL fallback test, userEvent clicks Co-authored-by: nick.misasi <[email protected]> * Tighten branch comments to match surrounding editor code style Co-authored-by: nick.misasi <[email protected]> --------- Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
a65fabff69 |
[MM-67163] Scheduled Recaps (#35495)
* docs: map existing codebase with focus on recaps
- STACK.md - Technologies and dependencies
- ARCHITECTURE.md - System design and patterns
- STRUCTURE.md - Directory layout
- CONVENTIONS.md - Code style and patterns
- TESTING.md - Test structure
- INTEGRATIONS.md - External services
- CONCERNS.md - Technical debt and issues
* docs: initialize project
Scheduled AI Recaps — enable recurring scheduled recaps instead of only manual one-off summaries
* chore: add project config
Mode: yolo
Depth: standard
Parallelization: enabled
* docs: complete domain research for scheduled recaps
Research files:
- STACK.md: Job server patterns, ScheduledPosts reference implementation
- FEATURES.md: Table stakes vs differentiators, anti-features to avoid
- ARCHITECTURE.md: Component boundaries, data flow, 5-phase build order
- PITFALLS.md: Timezone, cluster, schema critical pitfalls
- SUMMARY.md: Synthesized findings and roadmap implications
Key findings:
- Use ScheduledPosts polling pattern, not JobServer schedulers
- Store user intent + pre-computed NextRunAt for efficient polling
- Leverage existing recap worker, extend with time_period support
- Critical: Get timezone/schema right in Phase 1 to avoid migrations
* docs: define v1 requirements
35 requirements across 5 categories:
- Scheduling (7)
- Management (8)
- Backend Infrastructure (10)
- Frontend Wizard (7)
- Frontend Scheduled Tab (7)
Topic-based recaps deferred to v2
* docs: create roadmap (5 phases)
* docs(01): capture phase context
Phase 01: Database Foundation
- OpenCode discretion on implementation patterns
- Implicit requirements from downstream phases noted
* docs(01-database-foundation): research phase domain
Phase 1: Database Foundation
- Analyzed existing Recap and ScheduledPost patterns
- Documented schema design for recurring schedules
- Identified timezone/DST handling approach using IANA zones
- Catalogued store interface patterns
- Documented common pitfalls and anti-patterns
* docs(01): create phase plan for database foundation
Phase 01: Database Foundation
- 2 plans in 2 waves
- Wave 1: Model + migration (01-01-PLAN.md)
- Wave 2: Store layer + tests (01-02-PLAN.md)
- Ready for execution
* feat(01-01): create ScheduledRecap model with DST-aware NextRunAt computation
- Add ScheduledRecap struct with all required fields for schedule configuration
- Add day-of-week bitmask constants matching Go's time.Weekday (Sunday=0)
- Add channel mode constants (specific, all_unreads)
- Add time period constants (last_24h, last_week, since_last_read)
- Implement ComputeNextRunAt with timezone-aware scheduling using time.LoadLocation
- Implement IsValid for input validation
- Add PreSave/PreUpdate lifecycle methods
- Add Auditable method for audit logging
* feat(01-01): create database migration for ScheduledRecaps table
- Create ScheduledRecaps table with all required columns
- Add index for user queries (idx_scheduled_recaps_user_id)
- Add index for scheduler polling (idx_scheduled_recaps_next_run_at)
- Add composite index for efficient scheduler query (idx_scheduled_recaps_enabled_next_run)
- Add index for user + soft delete queries (idx_scheduled_recaps_user_delete)
- Add down migration to drop all indexes and table
* test(01-01): add unit tests for ScheduledRecap with DST edge cases
- Test day-of-week bitmask constants and operations
- Test ComputeNextRunAt for Monday-only, weekday, and every-day schedules
- Test timezone handling - different timezones produce different UTC millis
- Test DST spring forward edge case (March 2024) - Go normalizes non-existent times
- Test DST fall back edge case (November 2024) - Go uses first occurrence
- Test error cases: invalid timezone, invalid time format, zero days
- Test IsValid method for all validation rules
- Test PreSave and PreUpdate lifecycle methods
- Test Auditable method returns expected fields
- Fix ComputeNextRunAt to validate time format using regex before parsing
* docs(01-01): complete ScheduledRecap model and migration plan
Tasks completed: 3/3
- Task 1: Create ScheduledRecap model with constants and NextRunAt computation
- Task 2: Create database migration for ScheduledRecaps table
- Task 3: Add unit tests for ComputeNextRunAt with DST edge cases
SUMMARY: .planning/phases/01-database-foundation/01-01-SUMMARY.md
* feat(01-02): add ScheduledRecapStore interface to store.go
- Add ScheduledRecapStore interface with CRUD operations (Save, Get, Update, Delete)
- Add query operations (GetForUser, GetDueBefore)
- Add state update methods (UpdateNextRunAt, MarkExecuted, SetEnabled)
- Register ScheduledRecap() method in main Store interface
* feat(01-02): create SqlScheduledRecapStore implementation
- Implement CRUD operations (Save, Get, Update, Delete with soft delete)
- Implement GetForUser with pagination for user's scheduled recaps
- Implement GetDueBefore for scheduler polling query
- Implement efficient state updates (UpdateNextRunAt, MarkExecuted, SetEnabled)
- Handle JSON serialization/deserialization of ChannelIds array
- Follow existing patterns from recap_store.go
* feat(01-02): register ScheduledRecapStore in SqlStore
- Add scheduledRecap field to SqlStoreStores struct
- Initialize newSqlScheduledRecapStore in NewSqlStore
- Add ScheduledRecap() accessor method to SqlStore
* test(01-02): add comprehensive tests for ScheduledRecapStore
- Test CRUD operations (Save, Get, Update, Delete)
- Test GetForUser with pagination
- Test GetDueBefore scheduler query filtering
- Test state update methods (UpdateNextRunAt, MarkExecuted, SetEnabled)
- Test ChannelIds JSON serialization (array, empty, nil)
- All 13 test cases pass
* docs(01-02): complete ScheduledRecapStore plan
Tasks completed: 4/4
- Add ScheduledRecapStore interface to store.go
- Create SqlScheduledRecapStore implementation
- Register ScheduledRecapStore in SqlStore
- Create comprehensive store tests
SUMMARY: .planning/phases/01-database-foundation/01-02-SUMMARY.md
* fix(01): regenerate store mocks for ScheduledRecapStore
* docs(01): complete Database Foundation phase
Phase 1: Database Foundation
- 2 plans executed (model + store)
- 3 requirements complete (INFRA-01, INFRA-02, INFRA-10)
- Goal verified ✓
* docs(03): research phase scheduler integration domain
Phase 03: Scheduler Integration
- Standard stack identified (Mattermost job system)
- Architecture patterns documented (Scheduler + Worker pattern)
- Cluster-safe execution via leader-only scheduling
- Pitfalls catalogued (duplicate jobs, race conditions)
- Code examples from existing codebase patterns
* docs(02): create phase 2 API layer plans
Phase 02: API Layer
- 2 plans in 2 waves
- Plan 01 (Wave 1): App layer methods for CRUD + pause/resume
- Plan 02 (Wave 2): API handlers, routes, params, audit events
- Ready for execution
* feat(02-01): create App layer CRUD methods for ScheduledRecap
- Add CreateScheduledRecap with session-based userId, validation, NextRunAt computation
- Add GetScheduledRecap to retrieve by ID
- Add GetScheduledRecapsForUser with pagination
- Add UpdateScheduledRecap with NextRunAt recomputation when enabled
- Add DeleteScheduledRecap for soft delete
- Add PauseScheduledRecap to disable without deleting
- Add ResumeScheduledRecap with NextRunAt recomputation before enabling
- Regenerate store layer files for ScheduledRecapStore interface
* docs(02-01): complete App layer CRUD methods plan
Tasks completed: 3/3
- Regenerate store mocks (already complete from Phase 1)
- Create App layer file with CRUD methods
- Verify app layer interfaces (no interface file exists)
SUMMARY: .planning/phases/02-api-layer/02-01-SUMMARY.md
* feat(02-02): add audit event constants for scheduled recaps
- AuditEventCreateScheduledRecap for recap configuration creation
- AuditEventGetScheduledRecap for viewing single recap
- AuditEventGetScheduledRecaps for listing user recaps
- AuditEventUpdateScheduledRecap for configuration updates
- AuditEventDeleteScheduledRecap for recap deletion
- AuditEventPauseScheduledRecap for pausing execution
- AuditEventResumeScheduledRecap for resuming execution
* feat(02-02): add ScheduledRecapId to params and context
- Add ScheduledRecapId field to Params struct
- Parse scheduled_recap_id from URL path variables
- Add RequireScheduledRecapId validation method
* feat(02-02): add route registration for scheduled recaps
- Add ScheduledRecaps and ScheduledRecap routes to Routes struct
- Initialize route prefixes in Init function
- Add InitScheduledRecap call in initialization
* feat(02-02): create API handlers for scheduled recaps
- InitScheduledRecap registers all 7 API routes
- createScheduledRecap validates required fields and creates recap
- getScheduledRecap retrieves with authorization check
- getScheduledRecaps lists user's recaps with pagination
- updateScheduledRecap updates with ownership verification
- deleteScheduledRecap soft deletes with authorization
- pauseScheduledRecap disables execution with ownership check
- resumeScheduledRecap re-enables with NextRunAt recomputation
- All handlers include audit logging and feature flag check
* docs(02-02): complete API handlers plan
Tasks completed: 4/4
- Add audit event constants for scheduled recaps
- Add ScheduledRecapId to params and context
- Add route registration in api.go
- Create API handler file
SUMMARY: .planning/phases/02-api-layer/02-02-SUMMARY.md
* docs(02): complete API Layer phase
Phase 2: API Layer
- 2 plans executed in 2 waves
- 16/16 must-haves verified
- INFRA-05 through INFRA-09 complete
- Ready for Phase 3: Scheduler Integration
* docs(03): create phase plan for scheduler integration
Phase 03: Scheduler Integration
- 2 plans in 2 waves
- Wave 1: Job constant, scheduler, worker
- Wave 2: Job registration, App method
- Ready for execution
* fix(03): revise plan 03-02 Task 2 for worker context compatibility
- CreateRecapFromSchedule now creates recap directly via store
- Uses sr.UserId instead of rctx.Session().UserId (unavailable in worker)
- Creates JobTypeRecap job directly instead of delegating to CreateRecap
- Updated key_links to reflect store and job linkage
* docs(04): capture phase context
Phase 04: Scheduled Tab
- Implementation decisions documented
- Phase boundary established
- Figma references captured (123:62940, 123:19772)
* feat(03-01): add JobTypeScheduledRecap constant
- Add JobTypeScheduledRecap constant with value 'scheduled_recap'
- Add to AllJobTypes slice for job type validation
* feat(03-01): create ScheduledRecap scheduler
- Add Scheduler struct wrapping PeriodicScheduler
- 1-minute polling interval (SchedulerPollingInterval constant)
- Enabled when cfg.FeatureFlags.EnableAIRecaps is true
- ScheduleJob polls GetDueBefore for due recaps
- Creates job with CreateJobOnce for deduplication
- Job data: scheduled_recap_id, user_id, channel_ids, agent_id
* feat(03-01): create ScheduledRecap worker
- Define AppIface interface with CreateRecapFromSchedule method
- Use SimpleWorker pattern following recap/worker.go pattern
- Enabled when cfg.FeatureFlags.EnableAIRecaps is true
- Extract job data: scheduled_recap_id, user_id, channel_ids, agent_id
- Verify ScheduledRecap exists and is enabled before execution
- Call app.CreateRecapFromSchedule to create the actual recap
- Compute next run time using sr.ComputeNextRunAt
- Call MarkExecuted to update LastRunAt, NextRunAt, RunCount atomically
- Disable non-recurring schedules after execution
* docs(03-01): complete job system components plan
Tasks completed: 3/3
- Add JobTypeScheduledRecap constant
- Create scheduler implementation
- Create worker implementation
SUMMARY: .planning/phases/03-scheduler-integration/03-01-SUMMARY.md
* docs(04): create phase 4 plans - Scheduled Tab UI
Phase 04: Frontend - Scheduled Tab
- 4 plans in 4 waves
- Wave 1: TypeScript types + Client4 API methods
- Wave 2: Redux layer (action types, actions, reducer, selectors)
- Wave 3: ScheduledRecapItem component (card UI with toggle, menu)
- Wave 4: Scheduled tab integration with human verification
Covers requirements TAB-01 through TAB-07 and MGMT-01 through MGMT-08
* feat(03-02): add ScheduledRecap job registration in initJobs
- Register JobTypeScheduledRecap with worker and scheduler
- Import scheduled_recap package for job components
- Worker uses App interface for CreateRecapFromSchedule
- Scheduler polls for due recaps at 1-minute intervals
* feat(03-02): implement CreateRecapFromSchedule App method
- Create Recap from ScheduledRecap configuration
- Use sr.UserId instead of session (worker context has no session)
- Create recap record directly via store
- Create JobTypeRecap job to trigger processing
- Handle both specific channels and all_unreads mode
* docs(03-02): complete app integration plan
Tasks completed: 3/3
- Add job registration in initJobs
- Implement CreateRecapFromSchedule App method
- Verify full integration compiles
SUMMARY: .planning/phases/03-scheduler-integration/03-02-SUMMARY.md
* docs(phase-3): complete scheduler integration phase
* feat(04-01): add ScheduledRecap TypeScript types
- Add ScheduledRecap type matching Go model fields
- Add ScheduledRecapInput type for create/update operations
- Types exported via @mattermost/types/recaps
* feat(04-01): add Client4 scheduled recap route and imports
- Add getScheduledRecapsRoute() method returning /scheduled_recaps endpoint
- Import ScheduledRecap and ScheduledRecapInput types
* feat(04-01): add Client4 scheduled recap API methods
- createScheduledRecap: POST /scheduled_recaps
- getScheduledRecaps: GET /scheduled_recaps (paginated)
- getScheduledRecap: GET /scheduled_recaps/:id
- updateScheduledRecap: PUT /scheduled_recaps/:id
- deleteScheduledRecap: DELETE /scheduled_recaps/:id
- pauseScheduledRecap: POST /scheduled_recaps/:id/pause
- resumeScheduledRecap: POST /scheduled_recaps/:id/resume
* docs(04-01): complete TypeScript types and Client4 methods plan
Tasks completed: 3/3
- Add ScheduledRecap TypeScript type
- Add Client4 scheduled recap route helper
- Add Client4 scheduled recap API methods
SUMMARY: .planning/phases/04-scheduled-tab/04-01-SUMMARY.md
* feat(04-02): add scheduled recap action types
- GET_SCHEDULED_RECAPS_REQUEST/SUCCESS/FAILURE
- RECEIVED_SCHEDULED_RECAP and RECEIVED_SCHEDULED_RECAPS
- PAUSE_SCHEDULED_RECAP_REQUEST/SUCCESS/FAILURE
- RESUME_SCHEDULED_RECAP_REQUEST/SUCCESS/FAILURE
- DELETE_SCHEDULED_RECAP_REQUEST/SUCCESS/FAILURE
* feat(04-02): add scheduled recap Redux actions
- getScheduledRecaps: fetches paginated scheduled recaps
- pauseScheduledRecap: pauses a scheduled recap
- resumeScheduledRecap: resumes a paused scheduled recap
- deleteScheduledRecap: deletes a scheduled recap
* feat(04-02): add scheduled recaps to reducer
- Add scheduledRecaps to RecapsState type
- Handle RECEIVED_SCHEDULED_RECAP for single recap
- Handle RECEIVED_SCHEDULED_RECAPS for bulk updates
- Handle DELETE_SCHEDULED_RECAP_SUCCESS for removal
* feat(04-02): add scheduled recap selectors
- getScheduledRecapsState: base selector for raw state
- getAllScheduledRecaps: returns all scheduled recaps as array
- getActiveScheduledRecaps: filters enabled, non-deleted recaps
- getPausedScheduledRecaps: filters disabled, non-deleted recaps
- getScheduledRecapById: returns single recap by ID
* feat(04-02): update GlobalState type for scheduled recaps
- Import ScheduledRecap type from recaps
- Add scheduledRecaps field to recaps entity state
* docs(04-02): complete Redux store and actions plan
Tasks completed: 5/5
- Add scheduled recap action types
- Add scheduled recap Redux actions
- Add scheduled recaps to reducer
- Add scheduled recap selectors
- Update GlobalState type for scheduled recaps
SUMMARY: .planning/phases/04-scheduled-tab/04-02-SUMMARY.md
* feat(04-03): add i18n strings for scheduled recap UI
- Add scheduled tab label
- Add active/paused toggle states
- Add run stats strings (last run, run count, never run, next run)
- Add toast messages for pause/resume/delete
- Add kebab menu labels (edit, delete)
- Add delete confirmation modal strings
- Add empty state strings (title, description, cta)
- Add day formatting strings (weekdays, weekend, everyday, individual days)
- Add schedule format string
* feat(04-03): create useScheduleDisplay hook for schedule formatting
- Add bitmask constants matching Go model (Sun=1, Mon=2, etc.)
- formatDaysOfWeek: smart groupings (Every day, Weekdays, Weekends) or comma-separated
- formatTimeOfDay: locale-appropriate 12/24hr time from HH:MM
- formatSchedule: combines days and time with i18n format string
- formatNextRun: smart relative formatting (Today, Tomorrow, Day name, Date)
- formatLastRun: formatted date or 'Never run'
- formatRunCount: pluralized run count
* feat(04-03): create ScheduledRecapItem component
- Render card with title and schedule pattern subtitle
- Show next run time when schedule is active
- Toggle between Active/Paused states with pause/resume actions
- Run stats (last run, run count) appear on hover
- Kebab menu with Edit and Delete options
- Delete confirmation modal with FormattedMessage
- Use useScheduleDisplay hook for all formatting
* feat(04-03): add ScheduledRecapItem styles
- Card with border, radius, and hover state
- Flexbox layout with title/subtitle and actions
- Title with truncation (ellipsis) for long names
- Subtitle with metadata separator styling
- Run stats with opacity transition on hover
- Toggle button min-width for consistent sizing
- Kebab menu button hover state
* docs(04-03): complete ScheduledRecapItem component plan
Tasks completed: 4/4
- Add i18n strings for scheduled recap UI
- Create useScheduleDisplay hook for schedule formatting
- Create ScheduledRecapItem component
- Add ScheduledRecapItem styles
SUMMARY: .planning/phases/04-scheduled-tab/04-03-SUMMARY.md
* feat(04-04): create ScheduledRecapsEmptyState component
- Empty state displays when no scheduled recaps exist
- Shows illustration with icons, title, description
- CTA button to create first recap
- Supports disabled state when agents bridge is disabled
* feat(04-04): create ScheduledRecapsList component
- Renders empty state when no scheduled recaps exist
- Maps over scheduled recaps to render ScheduledRecapItem
- Passes edit and create handlers through to children
* feat(04-04): add Scheduled tab to main Recaps component
- Add Scheduled tab after Unread and Read tabs
- Fetch scheduled recaps on mount with getScheduledRecaps
- Display ScheduledRecapsList when on scheduled tab
- Wire up edit handler (opens create modal - Phase 5 adds pre-fill)
- Import scheduled_recap_item.scss for styling
* style(04-04): add SCSS styles for scheduled recaps
- Add .scheduled-recaps-list styles (flex column, centered, gap)
- Add .scheduled-recaps-empty-state styles (centered, illustration, text)
- Consistent with existing recap UI styling patterns
* docs(04-04): complete Scheduled tab integration plan
* docs(04): update STATE.md for phase 4 completion
* docs(04): complete Scheduled Tab phase
Phase 4: Scheduled Tab
- 4 plans executed across 4 waves
- 15/15 requirements verified
- Human verified UI works correctly
* docs(05): capture phase context
Phase 05: Enhanced Wizard
- Implementation decisions documented
- Phase boundary established
* docs(05): add research hints for component discovery
* docs(05): research phase domain for enhanced wizard
Phase 05: Enhanced Wizard - Frontend Implementation
- Standard stack identified (existing codebase components)
- Architecture patterns documented (multi-step modal, bitmask days)
- Pitfalls catalogued (timezone, validation, edit mode)
- Code examples from codebase referenced
* docs(05): create phase plan for enhanced wizard
Phase 05: Frontend - Enhanced Wizard
- 6 plans in 3 waves
- Wave 1: Redux actions, DayOfWeekSelector
- Wave 2: ScheduleConfiguration, Run once toggle
- Wave 3: Modal integration, Edit wiring
- Ready for execution
* feat(05-01): add action type constants for create/update scheduled recap
- CREATE_SCHEDULED_RECAP_REQUEST/SUCCESS/FAILURE
- UPDATE_SCHEDULED_RECAP_REQUEST/SUCCESS/FAILURE
* feat(05-02): create DayOfWeekSelector component
- Bitmask-based day selection matching server model
- Monday-first ordering for work schedule intuition
- XOR toggle for clean state management
- aria-pressed accessibility support
* feat(05-01): add createScheduledRecap async action
- Takes ScheduledRecapInput parameter
- Calls Client4.createScheduledRecap
- Dispatches RECEIVED_SCHEDULED_RECAP on success
- Follows existing pauseScheduledRecap pattern
* feat(05-02): add DayOfWeekSelector styles
- Flexbox layout with 8px gap between buttons
- 40x40px day buttons with hover states
- Selected state uses button-bg color
- Error and disabled state styling
* feat(05-01): add updateScheduledRecap async action
- Takes id and ScheduledRecapInput parameters
- Calls Client4.updateScheduledRecap
- Dispatches RECEIVED_SCHEDULED_RECAP on success
- Follows existing action patterns
* docs(05-02): complete DayOfWeekSelector plan
Tasks completed: 2/2
- DayOfWeekSelector component with bitmask state
- Styled button group with toggle/hover/error states
SUMMARY: .planning/phases/05-enhanced-wizard/05-02-SUMMARY.md
* docs(05-01): complete Redux actions for scheduled recaps plan
Tasks completed: 3/3
- Add action type constants for create/update scheduled recap
- Add createScheduledRecap async action
- Add updateScheduledRecap async action
SUMMARY: .planning/phases/05-enhanced-wizard/05-01-SUMMARY.md
* feat(05-04): add run once toggle to RecapConfiguration
- Add runOnce, setRunOnce, and isEditMode props to Props type
- Import Toggle component
- Add run once toggle section at bottom of Step 1
- Toggle hidden when isEditMode is true
- Include descriptive text below toggle
* feat(05-03): create ScheduleConfiguration component for Step 3
- Add day-of-week selection using DayOfWeekSelector
- Add time picker with 30-minute intervals and locale-aware formatting
- Add time period dropdown (Previous day, Last 3 days, Last 7 days)
- Add custom instructions textarea with 500 char limit
- Add next run preview with timezone support
- Use getCurrentTimezone selector for user timezone
* feat(05-04): add run once toggle styles
- Add .run-once-group with top separator border
- Style toggle and label with proper alignment
- Add description text with left margin for alignment
- Use consistent spacing and typography
* feat(05-03): add Step 3 schedule configuration styles
- Add step-three layout with vertical flex and gap
- Add form-group styling with label and error states
- Add next-run-preview styling with background and subtle text
- Add textarea overrides for custom instructions input
* docs(05-04): complete run once toggle plan
Tasks completed: 2/2
- Add run once toggle to RecapConfiguration
- Add run once toggle styles
SUMMARY: .planning/phases/05-enhanced-wizard/05-04-SUMMARY.md
* docs(05-03): complete ScheduleConfiguration plan
Tasks completed: 2/2
- Create ScheduleConfiguration component
- Add Step 3 styles to SCSS
SUMMARY: .planning/phases/05-enhanced-wizard/05-03-SUMMARY.md
* feat(05-05): add schedule state and edit mode props to modal
- Add editScheduledRecap prop for edit mode detection
- Add schedule state (daysOfWeek, timeOfDay, timePeriod, customInstructions)
- Add runOnce state and validation state (daysError, timeError)
- Add useEffect to pre-fill form in edit mode
- Import createScheduledRecap, updateScheduledRecap actions
- Import ScheduleConfiguration component and getCurrentTimezone selector
* feat(05-06): update handleEditScheduledRecap to pass scheduled recap to modal
- Find scheduled recap by ID from scheduledRecaps array
- Pass editScheduledRecap via dialogProps to CreateRecapModal
- Early return if scheduled recap not found
* feat(05-05): update step navigation for run once and schedule flows
- Update handleNext to clear validation errors on navigation
- Update handlePrevious to clear validation errors on navigation
- Update getTotalSteps for run once (2-3 steps) vs scheduled (always 3)
- Update getActualStep for proper step indicator mapping
* feat(05-05): update renderStep for schedule vs run once flows
- Pass runOnce, setRunOnce, and isEditMode props to RecapConfiguration
- Show ChannelSummary for run once mode at step 3
- Show ScheduleConfiguration for scheduled mode at step 3
- Pass all schedule state props to ScheduleConfiguration component
* feat(05-05): update handleSubmit for immediate and scheduled recaps
- Add schedule field validation for non-run-once mode
- Dispatch createRecap for run once mode (existing behavior)
- Dispatch updateScheduledRecap for edit mode
- Dispatch createScheduledRecap for new scheduled recaps
- Navigate to ?tab=scheduled after creating/editing scheduled recap
- Add proper error messages for schedule validation failures
* feat(05-05): update modal header and button text for edit mode
- Update canProceed to validate schedule fields in step 3
- Add getConfirmButtonText helper for context-aware button text
- Show 'Start recap' for run once, 'Save changes' for edit mode
- Show 'Create schedule' for new scheduled recaps
- Update headerText to show 'Edit your recap' in edit mode
* docs(05-05): complete wizard integration plan
Tasks completed: 5/5
- Add schedule state and edit mode props
- Update step navigation for run once and schedule flows
- Update renderStep for schedule vs run once flows
- Update handleSubmit for immediate and scheduled recaps
- Update modal header and button text for edit mode
SUMMARY: .planning/phases/05-enhanced-wizard/05-05-SUMMARY.md
* fix(05-06): JSON.stringify body in scheduled recap API calls
createScheduledRecap and updateScheduledRecap were passing objects
directly to doFetch body, causing '[object Object]' to be sent instead
of JSON. Fixed to match createRecap pattern.
* fix(05-06): align time period values with server model
Frontend was using 'last_3_days' and 'last_7_days' but server expects
'last_24h', 'last_week', and 'since_last_read'. Updated options to match.
* fix(05-06): remove duplicate border on custom instructions textarea
- GenericModal adds a border to all .form-control elements
- Input widget's Input_fieldset already provides a border container
- This caused a double-border visual glitch on the textarea
- Added border: none to the inner textarea to fix the issue
* fix(05-06): reserve space for next run preview to prevent modal height jump
- Always render next-run-preview container (previously conditionally rendered)
- Use visibility:hidden instead of not rendering when no preview available
- Add non-breaking space placeholder to maintain consistent element height
- Prevents jarring visual jump when user selects a day of the week
* fix(05-06): remove border/background from next-run-preview
- Remove padding, border-radius, and background-color from .next-run-preview
- Style as plain text with subtle color and smaller font size
- Keep margin for appropriate spacing from time selector
* fix(05-06): use abbreviated timezone in next recap preview
- Use Intl.DateTimeFormat with timeZoneName: 'short' to get timezone
abbreviation (e.g., EST, PST, EDT) instead of full label
- Remove unused getCurrentTimezoneLabel selector import
- Preview now shows 'Monday at 9:00 AM (EST)' instead of
'Monday at 9:00 AM ((UTC-05:00) Eastern Time (US & Canada))'
* fix(05-06): prevent modal height jump when next run preview appears
- Move next-run-preview inside time-selection-group as helper text
- Add min-height: 16px to reserve space when preview is hidden
- Use visibility: hidden instead of display: none for consistent height
- Reduce step-three gap from 20px to 16px for better spacing
- Add margin-bottom: 0 to form-group to override default spacing
* fix(05-06): add section titles and fix spacing in schedule configuration
- Add section titles per Figma design (Heading 100 style):
- 'When would you like your summary sent?' as main header
- 'On which days should your recap run?' for days section
- 'At what time?' for time section
- 'Select a time period for your recap to cover' for time period
- 'Additional instructions for {agentName}' for custom instructions
- Pass agentName prop from parent to show selected agent name
- Fix spacing: reserve space for next-run preview with container
to prevent time period section from jumping when preview appears
- Update SCSS with schedule-section groups and proper spacing
* fix(05-06): remove duplicate title and fix subtitle-dropdown spacing
- Remove 'When would you like your summary sent?' duplicate title
- Add scoped CSS rule for 12px total spacing between subtitle and dropdown
* fix(05-06): use standard Toggle without text labels for active/paused state
- Remove onText/offText props from Toggle component
- Add ariaLabel for accessibility (describes toggle state and action)
- Update SCSS to remove min-width constraint that was for text display
- Navigation to scheduled tab after creating scheduled recap already works correctly
* fix(05-06): toggle color and tab navigation after creating scheduled recap
- Use btn-toggle-primary class for scheduled recap toggle to display proper button-bg color
- Add useQuery hook to read tab query parameter from URL
- Sync activeTab state with URL tab parameter to enable navigation after modal close
* fix(05-06): sync tab state with URL bidirectionally
- Add handleTabChange callback that updates both state and URL
- Use history.replace() to update URL without polluting browser history
- Remove tab param from URL when switching to 'unread' (default tab)
- Simplify URL sync useEffect to always update from tabParam
- This enables proper navigation after creating scheduled recaps
* fix(05-06): fix navigation to scheduled tab after creating scheduled recap
- Replace useRouteMatch() with getCurrentRelativeTeamUrl selector
- Modal was using route match which returned wrong URL context (modal is rendered at root level)
- Use team selector to get correct team URL for navigation
- Update test to remove unnecessary useRouteMatch mock
* fix(05-06): sort scheduled recaps by newest first
- Update getAllScheduledRecaps selector to sort by create_at descending
- Follows same pattern as other recap selectors (getUnreadRecaps, getReadRecaps)
- Derived selectors (getActiveScheduledRecaps, getPausedScheduledRecaps) inherit sort order
* docs(05-06): complete edit wiring and UI polish plan
* docs(phase-05): complete Enhanced Wizard phase
Phase 5: Enhanced Wizard
- 6 plans executed across 3 waves
- 13 requirements verified
- Multi-step wizard for creating/editing scheduled recaps
- Run once and scheduled flows
- Full edit mode with pre-fill
- Extensive UI polish based on human feedback
All 39 requirements complete. Milestone ready for audit.
* docs(v1): milestone audit complete - all requirements satisfied
- 39/39 requirements verified
- 5/5 phases passed
- 100% cross-phase integration
- 5/5 E2E flows complete
- 2 minor tech debt items (non-blocking)
* chore: remove .planning from git tracking
- Add .planning to .gitignore
- Remove .planning files from git index (kept locally)
- Planning files are for local development only
* feat(06-01): add AIRecapSettings and RecapLimitSettings structs
- RecapLimitSettings with 7 limit fields (recaps/day, scheduled, channels, posts, tokens, posts/day, cooldown)
- AIRecapSettings with master toggle and per-limit enforcement toggles
- SetDefaults methods with sensible defaults (10 recaps/day, 5 scheduled, etc.)
- isValid/IsValid validation methods enforcing natural minimums
* feat(06-01): integrate AIRecapSettings into Config struct
- Add AIRecapSettings field to Config struct
- Call AIRecapSettings.SetDefaults() in Config.SetDefaults()
- Call AIRecapSettings.IsValid() in Config.IsValid()
* test(06-01): add tests for AIRecapSettings and RecapLimitSettings
- TestAIRecapSettingsSetDefaults: verifies all defaults match spec
- TestRecapLimitSettingsValidation: verifies validation rejects invalid values
- TestAIRecapSettingsPreservesExistingValues: verifies SetDefaults preserves existing
- TestAIRecapSettingsIsValid: verifies IsValid delegates to DefaultLimits
* feat(06-02): create EffectiveRecapLimits struct
- Add EffectiveRecapLimits struct with 7 resolved limit fields
- Add LimitSource type with system/group/user constants
- Add UnlimitedValue constant (-1) for disabled limits
- Add IsLimitEnabled helper function for enforcement code
* feat(06-02): create GetEffectiveLimits resolution function
- Add GetEffectiveLimits(userID) returning resolved limits for any user
- Resolve limits from AIRecapSettings.DefaultLimits config
- Apply per-limit enforcement toggles (disabled = -1 unlimited)
- Add helper functions getValueOrDefault and getBoolOrDefault
- Structure for Phase 8 group/user resolution with TODOs
* test(06-02): add tests for GetEffectiveLimits function
- TestGetEffectiveLimitsDefaults verifies system defaults returned
- TestGetEffectiveLimitsWithDisabledToggle verifies -1 returned for disabled limits
- TestGetEffectiveLimitsWithCustomDefaults verifies custom config honored
- TestGetEffectiveLimitsAllTogglesDisabled verifies all -1 when all disabled
- TestGetEffectiveLimitsUnlimitedConfigValue verifies -1 config value honored
- TestIsLimitEnabled verifies helper correctly identifies enabled limits
* feat(07-01): add RecapStatusSkipped constant and SkipReason field
- Add RecapStatusSkipped constant for recaps skipped due to limit violations
- Add SkipReasonDailyLimit and SkipReasonCooldown skip reason constants
- Add ScheduledRecapId field to Recap struct for tracking scheduled recaps
- Add SkipReason field to Recap struct for tracking why recap was skipped
- Update Auditable() method to include new fields
- Update recapColumns and recapToMap to include new fields
* feat(07-01): add store interface methods for limit enforcement
- Add CountForUserSince to RecapStore for daily limit enforcement
- Add GetLastCompletedManualRecap to RecapStore for cooldown checking
- Add CountForUser to ScheduledRecapStore for max scheduled recaps limit
- Update mock implementations for both stores
* feat(07-01): implement store methods in SQL stores
- Implement CountForUser in SqlScheduledRecapStore
- Counts active (non-deleted, enabled) scheduled recaps for a user
- Implement CountForUserSince in SqlRecapStore
- Counts recaps since timestamp, excluding skipped recaps
- Implement GetLastCompletedManualRecap in SqlRecapStore
- Returns most recent completed manual recap (no ScheduledRecapId)
- Returns nil, nil when no manual recap exists
* feat(07-03): add daily limit check to scheduled recap worker
- Add GetEffectiveLimits and GetUser to AppIface for limit checking
- Check MaxRecapsPerDay before executing scheduled recap
- Create skipped recap record when daily limit exceeded
- Use user's timezone for midnight calculation
- Update next run time even when skipping (scheduler moves on)
* feat(07-03): add cooldown check to manual recap creation
- Check CooldownMinutes before allowing manual recap creation
- Return HTTP 429 with retry-after info when cooldown active
- Only checks against completed manual recaps (per CONTEXT.md)
- Failed recaps don't consume cooldown (checks completed only)
* feat(07-03): add i18n messages for cooldown errors
- Add cooldown_active error with retry info template
- Add cooldown_check_failed error message
- Uses "Your organization's policy limits..." pattern
* feat(07-02): add limit checks to CreateScheduledRecap
- Add max scheduled recaps limit check using CountForUser store method
- Add max channels per recap limit check against ChannelIds length
- Return HTTP 400 with clear error messages when limits exceeded
- Uses GetEffectiveLimits for limit resolution (ENF-01, ENF-02, ENF-08)
* feat(07-02): add i18n error messages for scheduled recap limits
- Add max_scheduled_reached message with "Your organization's policy limits..." pattern
- Add max_channels_exceeded message with limit and requested count
- Add count_failed internal error message
* test(07-04): add unit tests for post/token truncation
- Test proportional post distribution across channels
- Test minimum 1 post per channel guarantee
- Test empty channel handling
- Test token estimation (4 chars/token heuristic)
- Test token limit truncation removes from largest channels
Verifies ENF-05, ENF-06 truncation implementation.
* test(07-05): add ENF-07 permission preservation tests
- Add tests verifying over-limit users can view/edit/delete existing recaps
- Tests confirm management operations do NOT check limits (grandfathering)
- Tests confirm creation IS still blocked when over limit
- Add migration 000151 for missing ScheduledRecapId/SkipReason columns
ENF-07: Limits only block creation, not management of existing resources
* feat(08-01): create UnlimitedNumberSetting component
- Number input with Unlimited checkbox for admin console settings
- When checked: disables input and sets value to -1 (unlimited)
- When unchecked: enables input and sets value to defaultValue
- Supports disabled state and setByEnv footer
* test(08-01): add unit tests for UnlimitedNumberSetting
- Tests rendering with numeric and unlimited values
- Tests checkbox toggle behavior (check/uncheck)
- Tests number input changes
- Tests disabled state and setByEnv footer
- Tests custom unlimited label and placeholder
- 11 test cases covering core functionality
* feat(08-02): add Recaps subsection to admin_definition.tsx
- Import UnlimitedNumberSetting component
- Add 'recaps' subsection under site configuration section
- Include master enable toggle for AI Recap Limits
- Add 3 grouped sections: Quota Limits, Content Limits, Time Limits
- Configure all 7 limit settings with proper config keys
- Add AIRecapSettings and RecapLimitSettings TypeScript types
- All settings disabled when master toggle is off
* feat(08-02): add i18n strings for Recaps admin section
- Add admin.sidebar.recaps for navigation
- Add admin.site.recaps for section title
- Add admin.recaps.enable.* for master toggle
- Add admin.recaps.sections.* for section descriptions
- Add admin.recaps.max*.* for all limit field labels/descriptions
- Add admin.recaps.cooldownMinutes.* for time limit settings
- Add admin.recaps.unlimited for checkbox label
- Total: 24 new i18n strings
* style(08-02): remove section comments to fix lint errors
Remove inline comments that triggered lines-around-comment lint rule
* feat(09-01): add RecapLimitStatus model and App layer logic
- Add RecapLimitStatus, DailyUsageStatus, CooldownStatus structs
- Implement App.GetRecapLimitStatus with daily usage count and cooldown calculation
* feat(09-01): add GET /api/v4/recaps/limit_status endpoint
- Register route and handler
- Return structured limit status
- Add error translation
* feat(09-01): add TypeScript types for limit status
- Export RecapLimitStatus and related types
* feat(09-02): add recap limit status redux integration
- Add Client4.getRecapLimitStatus method
- Add Redux action, reducer, and selector for limit status
- Update GlobalState and initial state to include limitStatus
* fix(09-02): update CreateRecapModal error handling and tests
- Check dispatch result.error instead of try/catch to handle server errors
- Display server error message (e.g. policy limits) inline
- Fix TypeScript errors: displayName property and missing props in tests
* feat(09-03): implement user-facing limit status UI
* Verify Phase 9: User-Facing UX
* Remove UAT artifact
* fix: UI/UX issues (badge, toggle, input, tooltip)
* fix: Increase RecapUsageBadge tooltip z-index
* blank lines
* [MM-67163] checkpoint: scheduled recaps feature working
All phases (01-09) complete and verified:
- Database foundation with DST-aware scheduling
- API layer for CRUD operations
- Job scheduler and worker
- Scheduled tab UI with list/create/edit/delete
- Enhanced wizard with schedule configuration
- Config settings and admin console section
- Limit enforcement (daily, cooldown, token, post)
- User-facing limit status badge
* [MM-67163] simplify: reduce duplication and fix issues across scheduled recaps
- Extract requireScheduledRecapOwnership helper for 5 API handlers
- Consolidate ResumeScheduledRecap from 4 store calls to 2
- Remove redundant Get() in PauseScheduledRecap
- Extract advanceSchedule helper in worker to deduplicate skip/success paths
- Remove double PreSave() in store Save method
- Remove dead code fallback in GetEffectiveLimits
- Deduplicate ScheduledRecapInput construction in create modal
- Fix missing fetchRecapLimitStatus import (TS error)
- Extract day-of-week bitmask constants to @mattermost/types/recaps
- Fix hardcoded English strings in schedule_display formatNextRun
* Address CodeRabbit review feedback on scheduled recaps
Server fixes:
- Gate getRecapLimitStatus with requireRecapsEnabled guard
- Normalize error mapping (404 vs 500) in scheduled recap handlers
- Enforce MaxChannelsPerRecap limit in UpdateScheduledRecap
- Return explicit error for unsupported all_unreads mode in scheduled recaps
- Add compensation logic to clean up orphan recaps on job creation failure
- Fix proportional post truncation to strictly enforce maxPosts cap
- Add missing CountForUser retry wrapper in RetryLayerScheduledRecapStore
- Handle NULL ScheduledRecapId in manual recap cooldown lookup
- Exclude soft-deleted rows in scheduled recap Get query
Frontend fixes:
- Pass isCreationBlocked to ScheduledRecapsList empty state
- Fix same-day nextRunAt mislabeled as "Tomorrow" in schedule display
- Handle thunk error results in scheduled recap item actions
- Replace scheduled recaps map on full refresh instead of merging
Made-with: Cursor
* Handle thunk error results in scheduled recap toggle handler
Check dispatch result for errors in handleToggle to prevent
false-success UI flows when pause/resume operations fail.
Made-with: Cursor
* Fix CI failures: mock store, permissions, migrations, lint, and Playwright config
- Add ScheduledRecap() to storetest.Store mock and retrylayer test setup
- Register sysconsole_read_ai_recaps / sysconsole_write_ai_recaps permissions
- Renumber scheduled_recaps migration from 150→156 and recap_skip_fields from 151→157 to resolve version conflicts
- Fix ESLint errors in recap components (operator-linebreak, import order, labels, headers, etc.)
- Add AIRecapSettings to Playwright default_config.ts
Made-with: Cursor
* Address CodeRabbit Round 2 review feedback
- Add OpenAPI spec for GET /api/v4/recaps/limit_status with schema
definitions for RecapLimitStatus, EffectiveRecapLimits,
DailyUsageStatus, and CooldownStatus
- Set ScheduledRecapId when creating recaps from schedules to prevent
cooldown logic from treating scheduled recaps as manual
- Handle past nextRunAt timestamps in schedule display: show "Yesterday"
for -1 day and full date for older past dates
Made-with: Cursor
* Add missing variable declarations for AI recaps permissions
Made-with: Cursor
* Fix jsx-max-props-per-line lint errors in schedule_configuration.tsx
Made-with: Cursor
* Fix stylelint property order in recap SCSS files
Made-with: Cursor
* Update admin sidebar snapshots to include Recaps section
Made-with: Cursor
* Fix Go lint issues and add OpenAPI specs for scheduled_recap endpoints
- Use max/min builtins instead of if-statements (modernize/minmax)
- Use range-over-int syntax for for-loops (modernize/rangeint)
- Fix tautological Monday&Monday test (staticcheck/SA4000)
- Add OpenAPI specs for all 7 scheduled_recap API routes
- Add ScheduledRecap model definition to definitions.yaml
Made-with: Cursor
* Regenerate i18n en.json for recap-related strings
Made-with: Cursor
* Fix gofmt indentation in recap.go
Made-with: Cursor
* Fix scheduled recap CI regressions
Align the scheduled recap soft-delete store test with the current Get behavior and add the missing scheduled recap i18n strings so server and enterprise checks stay in sync.
Made-with: Cursor
* Address CodeRabbit review feedback on scheduled recaps
- Use session user ID instead of client-controlled recap.UserId for
limit enforcement in UpdateScheduledRecap (security hardening)
- Add missing i18n entry for app.recap.fetch_posts.app_error
- All other review comments were already addressed in prior commits
Made-with: Cursor
* Fix schedule configuration import order
Reorder the moment import so the webapp lint job passes again on the scheduled recap PR.
Made-with: Cursor
* Allow selecting "all unreads" recap type when no current unreads exist
With scheduled recaps, users should be able to select "all unreads" even
without current unread channels since unreads will exist when the schedule
runs. The "run once" toggle is now disabled when all unreads is selected
with no current unreads, preserving the pre-scheduling behavior of
preventing an immediate recap with nothing to summarize.
Made-with: Cursor
* Fix indentation in recap_configuration.tsx to satisfy eslint
* Fix Recaps test mocks for scheduled recap state.
Keep the webapp test shard green by mirroring the new selectors and mount-time actions used by the Recaps page.
Made-with: Cursor
* Update server/channels/app/recap.go
* Update server/channels/app/recap.go
* Update server/channels/app/recap_limits.go
* Update server/channels/app/recap_limits.go
* Update server/channels/app/scheduled_recap.go
* Update server/channels/app/scheduled_recap.go
* Update webapp/channels/src/components/recaps/scheduled_recaps_empty_state.tsx
* Update server/channels/app/scheduled_recap.go
* Fix gofmt formatting in recap limits
Made-with: Cursor
* Fix recap limits for soft-deleted recaps
Keep deleted recaps in quota and cooldown checks so soft deletion cannot bypass AI usage enforcement.
Made-with: Cursor
* Fix translation
* Fix server check-style: concurrent indexes and lint cleanups
- Use CREATE/DROP INDEX CONCURRENTLY in 000168 scheduled recaps migrations
(required by mattermost-govet concurrentIndex check).
- gofmt validation constants in scheduled_recap.go.
- Replace string += loops in recap tests with strings.Repeat for modernize linter.
Made-with: Cursor
* Fix 000168 migration: run CONCURRENTLY indexes outside transaction
PostgreSQL rejects CREATE/DROP INDEX CONCURRENTLY inside a transaction.
Morph requires -- morph:nontransactional for these migrations, matching
other index migrations in the repo.
Made-with: Cursor
* Stabilize scheduled Recaps for review
Bring the scheduled Recaps work back into a shippable state by tightening backend scheduling and limit semantics, cleaning up the UI flows, and adding focused Recaps E2E coverage.
Made-with: Cursor
* Fix scheduled recaps lint failures
Made-with: Cursor
* Fix scheduled recap Go lint
Made-with: Cursor
* Fix scheduled recaps Playwright check
Made-with: Cursor
* Sync scheduled recaps i18n catalog
Made-with: Cursor
* Fix server recaps CI checks
Made-with: Cursor
* Stabilize recap server CI setup
Made-with: Cursor
* Recaps: enforce token limit, remove dead truncation code, simplify scheduled worker
- Delete unused multi-channel truncation subsystem (FetchAndTruncatePostsForRecap, truncatePostsProportionally)
- Enforce MaxTokensPerRecap in the live recap path (previously a silent no-op)
- Drop redundant non-atomic daily-limit pre-check in the scheduled worker; rely on the atomic check in CreateRecapFromSchedule
- Disable non-recurring schedules on all terminal paths (including daily-limit skips) via finalizeSchedule
- Trim scheduled-recap job payload to scheduled_recap_id
- Exclude skipped recaps from GetRecapsForUser
Co-authored-by: nick.misasi <[email protected]>
* Recaps webapp: format schedule times in the schedule timezone, static day i18n, typed schedule fields
- Display next-run and schedule times using the scheduled recap's timezone (shared schedule_time_format helper) instead of browser-local time
- Replace dynamic day-of-week i18n message IDs with static descriptors so strings are extractable/translatable
- Add ScheduledRecapTimePeriod/ScheduledRecapChannelMode union types
- Use shared Button in the scheduled recaps empty state
Co-authored-by: nick.misasi <[email protected]>
* Recaps e2e: cover scheduled edit/delete/all-unreads/empty-state and token-limit enforcement
- Add UI coverage for editing, deleting, and the empty state of scheduled recaps
- Add all-unreads scheduled recap modal flow
- Add immediate-recap token-limit enforcement tests (single and per-channel), validating MaxTokensPerRecap truncation end-to-end
- Extend recaps page object and helpers
Co-authored-by: nick.misasi <[email protected]>
* Recaps: regenerate store layers/mocks and i18n after cleanup; fix lint
- Regenerate timerlayer/retrylayer/RecapStore mock to canonical order
- Drop orphaned app.recap.fetch_posts.app_error i18n key (removed with dead fetch helper)
- Add missing semicolon in UnlimitedNumberSetting props
Co-authored-by: nick.misasi <[email protected]>
* Recaps: regenerate default roles permissions and admin sidebar snapshot
- Regenerate Cypress default_roles_permissions fixture to include AI Recaps sysconsole permissions
- Update admin sidebar snapshot for the new Recaps section
Co-authored-by: nick.misasi <[email protected]>
* Recaps: stabilize flaky cooldown round-up test
The cooldown round-up subtest placed the prior recap 30s before a 2-minute
cooldown, leaving only ~30s of slack before the rounded remaining time would
flip from 2 to 1 minute. Under heavily loaded CI this could intermittently fail
the exact-minute assertion. Move the prior recap to 1s ago so the remaining time
sits near the top of the 2-minute band (~59s slack) while still exercising
ceiling rounding.
Co-authored-by: nick.misasi <[email protected]>
* Recaps: store ScheduledRecap.ChannelIds as jsonb
Postgres is the only supported database, so the prior TEXT+JSON-string
workaround for MySQL compatibility is unnecessary. Store ChannelIds in a
jsonb column and type the model field as model.StringArray, which removes the
bespoke marshal/unmarshal and intermediate scan struct in the store.
Co-authored-by: nick.misasi <[email protected]>
* Recaps: gate recap limit settings on the ai_recaps permission
Add access:"ai_recaps" to DefaultLimits and all RecapLimitSettings fields so a
delegated admin with sysconsole_write_ai_recaps can save the limit values,
instead of falling back to requiring manage_system.
Co-authored-by: nick.misasi <[email protected]>
* Recaps: drop bespoke Users row lock for limit enforcement
The recap limit savers were the only SELECT ... FOR UPDATE in the sqlstore.
Conform to the prevailing pattern (e.g. channel_bookmark_store.Save): enforce
MaxScheduledRecaps / MaxRecapsPerDay with a transactional count + insert and no
row lock, accepting the same best-effort behavior under concurrency as channels,
team members, and bookmarks.
Co-authored-by: nick.misasi <[email protected]>
* Recaps: document SaveOnceByTypeAndData dedup semantics
Co-authored-by: nick.misasi <[email protected]>
* Recaps: use SERIALIZABLE isolation for limit-check inserts
Co-authored-by: nick.misasi <[email protected]>
* Recaps: mark orphaned recap skipped when job enqueue fails
When CreateJob fails after the recap row is committed, flag the recap
skipped with reason job_creation_failed instead of leaving it pending.
Skipped recaps are excluded from the daily-limit count, so this frees
the quota slot for a recap that will never run, and keeps CreateRecap
consistent with CreateRecapFromSchedule.
Co-authored-by: nick.misasi <[email protected]>
* ci: retrigger CI (flaky enterprise npm cache EEXIST)
Co-authored-by: nick.misasi <[email protected]>
* ci: retrigger CI (flaky Vet API container init)
Co-authored-by: nick.misasi <[email protected]>
* Recaps: re-check channel read permission at recap execution time
Co-authored-by: nick.misasi <[email protected]>
* fix scheduled recap job server test setup
Co-authored-by: nick.misasi <[email protected]>
* ci: retry flaky webapp test
Co-authored-by: nick.misasi <[email protected]>
* ci: retry documentation impact review
Co-authored-by: nick.misasi <[email protected]>
* MM-67163: Address review feedback: remove unused userID param, return AppError from GetRecapLimitStatus
Co-authored-by: nick.misasi <[email protected]>
* MM-67163: Bulk channel permission check for recap creation, bounded by channel limit
Co-authored-by: nick.misasi <[email protected]>
* chore: rerun CI
Co-authored-by: nick.misasi <[email protected]>
* chore: rerun CI after network failure
Co-authored-by: nick.misasi <[email protected]>
---------
Co-authored-by: Mattermost Build <[email protected]>
Co-authored-by: Hanzo Dev <[email protected]>
|
||
|
|
ba5ad73c58 |
Prepackage mattermost-plugin-agents v2.5.0-rc1. (#37582)
Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
3d2ad310dd |
Add admin-locked profile fields for email users and pre-provisioned names on invites (#37458)
* Add TeamSettings.LockProfileFieldsForEmailUsers with server-side enforcement Co-authored-by: Nick Misasi <[email protected]> * Add API tests for LockProfileFieldsForEmailUsers enforcement Co-authored-by: Nick Misasi <[email protected]> * Hide admin-locked profile fields in user settings and add System Console dropdown Co-authored-by: Nick Misasi <[email protected]> * Support pre-set username and name on team email invites Co-authored-by: Nick Misasi <[email protected]> * Add tests for invite profiles; fix resend worker channel-list parsing Co-authored-by: Nick Misasi <[email protected]> * Add pre-set profile inputs to member invite modal Co-authored-by: Nick Misasi <[email protected]> * Prefill and lock pre-set username on signup page Co-authored-by: Nick Misasi <[email protected]> * Add first/last name editing to System Console user detail and document new setting Co-authored-by: Nick Misasi <[email protected]> * Fix lint issues in invite modal profile inputs Co-authored-by: Nick Misasi <[email protected]> * Fix double outline on invite modal profile inputs inside GenericModal Co-authored-by: Nick Misasi <[email protected]> * Refactor invite emails to InviteEmailData struct and harden invite profile validation Co-authored-by: nick.misasi <[email protected]> * Centralize profile-lock permission exemption in app layer and add config coverage Co-authored-by: nick.misasi <[email protected]> * Per-field name locking in profile settings, typed lock setting, and shared invite profile helpers Co-authored-by: nick.misasi <[email protected]> * Add Playwright E2E coverage for locked profile fields and pre-set invite profiles Co-authored-by: nick.misasi <[email protected]> * Sync playwright package-lock with merged workspace versions Co-authored-by: nick.misasi <[email protected]> * Restore upstream playwright package-lock (fix npm ci drift) Co-authored-by: nick.misasi <[email protected]> * Assert invite input cleared instead of chip text after adding email Co-authored-by: nick.misasi <[email protected]> * Fix invite modal scroll, username error layout, and clipped autocomplete Keep the footer pinned while tall profile rows scroll, show username validation full-width after blur, and portal select menus so they are not clipped by the scroll container. * fixes for autocomplete items not aligning properly * Make invite autocomplete menu portal opt-in and fix modal chrome Confine document.body menu portaling to the invite modal via a menuPortal prop, and restore click-away, slide-in animation, and header alignment for the scrolling invite modal layout. * Fix eslint lines-around-comment on menuPortal props * Fix stylelint property order in invitation modal SCSS. * Fix stylelint property order in invitation_modal.scss Co-authored-by: nick.misasi <[email protected]> * Adapt invite modal E2E to portaled autocomplete menus Co-authored-by: nick.misasi <[email protected]> * Simplify locked profile invite implementation Co-authored-by: nick.misasi <[email protected]> * Fix invite modal review and E2E feedback Co-authored-by: nick.misasi <[email protected]> * Retry flaky enterprise CI Co-authored-by: nick.misasi <[email protected]> * Retry Docker image export CI Co-authored-by: nick.misasi <[email protected]> * Minimize locked profile fields diff Co-authored-by: nick.misasi <[email protected]> * Fix locked profile E2E documentation Co-authored-by: nick.misasi <[email protected]> * Address minimized test review feedback Co-authored-by: nick.misasi <[email protected]> * Fix email test whitespace Co-authored-by: nick.misasi <[email protected]> * Retry OpenSearch download CI Co-authored-by: nick.misasi <[email protected]> * Retry flaky Cypress thread navigation Co-authored-by: nick.misasi <[email protected]> * Preserve legacy invite behavior without profiles Co-authored-by: nick.misasi <[email protected]> * Clarify invite profile validation Co-authored-by: nick.misasi <[email protected]> * Retry flaky enterprise E2E Co-authored-by: nick.misasi <[email protected]> --------- Co-authored-by: Matthew Birtch <[email protected]> Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
30a8cfc91f |
Support pluggable channel settings tabs (#35591)
* Support pluggable channel settings tabs Add a schema-with-override plugin hook for Channel Settings tabs, modeled on the User Settings plugin hook. Plugins register either a declarative schema (sections of settings plus an onSave handler; the host renders controls, owns the save bar and change tracking, and calls onSave on save) or a custom component escape hatch (host-owned save bar delegates save/reset to plugin handlers; rendered inside PluggableErrorBoundary for crash isolation). Includes a reusable plugins/settings_schema module (generic types, a defensive validator, controlled radio controls), a dedicated channelSettingsTabs reducer slice + action, value hydration via loadValues(channel), and docs. Follow-up: migrate User Settings onto the shared settings_schema module. * refactor(webapp): migrate User Settings onto shared settings_schema module Re-express the User Settings plugin types, validator, and radio control in terms of the shared plugins/settings_schema module, deleting the duplicated walkers and control. extractPluginConfiguration now delegates to extractSettingsSchema, using a top-level hook for the best-effort action and a new per-section hook (Option A) to preserve onSubmit. Behavior is unchanged for plugins (Calls, MSTeams): the public registerUserSettings contract is intact. * fix(webapp): include loadValues in registerChannelSettingsTab keyOrder The reArg keyOrder for registerChannelSettingsTab omitted 'loadValues', so any declarative schema registration that supplied it was mis-zipped and rejected by the plugins reducer as an invalid channel settings tab. Add the key (and a matching `loadValues?: never` on the custom-tab type so the discriminated-union keyof stays correct) and add a regression test that drives the real registry path through to the reducer. * Extract ChannelSettingsPluginTab and simplify channel settings modal Move the plugin tab (schema + custom) and its save bar out of ChannelSettingsModal into a dedicated ChannelSettingsPluginTab component that owns its handler ref and save/reset logic, mirroring the built-in tabs. Stop injecting theme/webSocketClient into custom tab bodies so they receive only the documented plugin contract. Derive the active tab directly from the user's selection instead of syncing it back into state via an effect, and drop the now-redundant getFirstVisibleTab helper. Co-authored-by: nick.misasi <[email protected]> * Rename plugin user-settings extraction wrapper for clarity The generic schema extraction now lives in plugins/settings_schema, so rename the user-settings-specific wrapper from plugin_setting_extraction to user_settings_extraction (extractPluginUserSettings) to make its scope explicit, and refresh the stale settings_schema doc comment that still described User Settings as un-migrated. Co-authored-by: nick.misasi <[email protected]> --------- Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
fa6b3121ca |
[MM-68856] Respect default agent and persist last-selected agent in the agent selector (#37017)
The agent selector defaulted to the alphabetically-first agent and ignored the system-wide default. It now resolves saved-pref -> default (is_default) -> first and persists explicit selections via the shared agents/selected_agent core preference. Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
abee77dfb3 |
Bump prepackaged Agents plugin to v2.4.2 (#37289)
Automatic Merge |
||
|
|
195d2e96a3 |
Fix AI sparkle indicator on consecutive agent posts (#37064)
Exclude AI-generated posts from consecutive-post collapsing so each agent message keeps a visible header and sparkle badge. Also simplify the badge render condition to always show the indicator for AI posts in the badges area when appropriate. Co-authored-by: Mattermost Build <[email protected]> Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
041c1c3339 |
Prepackage mattermost-plugin-agents v2.4.1. (#37184)
Automatic Merge |
||
|
|
ce7185e2f7 |
Update prepackaged Agents, Boards, and Playbooks plugins for release-11.9 (#37092)
Automatic Merge |
||
|
|
99fe7c192e |
Keep plugin post action menus open when hovering away (#36991)
* Keep plugin post action menus open Co-authored-by: nick.misasi <[email protected]> * Organize plugin post action regression test Co-authored-by: nick.misasi <[email protected]> * webapp: fix post options test lint Co-authored-by: nick.misasi <[email protected]> --------- Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
bcd703977f |
MM-69131: Keep app__body off backstage routes to fix dark-theme styling (#36928)
* MM-69131: Keep app__body off backstage routes to fix dark-theme styling Centralizing app__body ownership on WithUserTheme (MM-67913) made the class persist on backstage routes (integrations, custom emoji), which render a static light surface. Under dark themes this leaked themed colors in, making text and form inputs illegible. useAppBodyClass now takes the current pathname and omits app__body on backstage routes via isBackstageRoute, while keeping it persisted across channels, products, and plugins so the original white-flash fix still holds. * MM-69131: Address theme provider review feedback Keep backstage route detection local to the theme provider and let the app body class hook read routing context directly. --------- Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
a1a17f1434 |
Remove agent-browser skill and lockfile (#36930)
* Remove agent-browser skill and lockfile The computerUse subagent now provides a full desktop with Chrome, making the bespoke agent-browser skill obsolete. * Remove agent-browser install and docs from cloud env Drop the agent-browser CLI/headless-Chrome install, skip flag, and docs from the Cursor Cloud Agent Dockerfile, install hook, and notes. Keep the AWS CLI and the Playwright e2e runtime libraries. --------- Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
e4b86e02e4 |
MM-68316: add mattermost db ping subcommand (#36406)
* MM-68316: add `mattermost db ping` subcommand Adds a one-shot DB-readiness CLI that opens a connection to the configured PostgreSQL DSN and exits 0 when reachable. Honours --timeout (default 5m) and --retry-interval (default 2s); reads the DSN from --config / MM_CONFIG / MM_SQLSETTINGS_DATASOURCE matching the existing `db init`/`db migrate` semantics. Intended primarily as an init-container readiness check for the mattermost-operator, removing its dependency on a separate postgres:13 image (relevant for air-gapped deployments). * MM-68316: address PR feedback (sanitize ping retry log) Drop mlog.Err(err) from the per-attempt "Waiting for database" log line in pingWithRetry: lib/pq error strings can echo DSN fragments back at operators when DSN parsing fails. Replace with a non-sensitive status field. Also clarifies the TestDBPingInvalidDSN comment to reflect actual lib/pq behavior (parse error surfaces at PingContext, not Open, so the retry loop treats it as transient — desired for a readiness probe). * MM-68316 Preserve safe db ping DSN errors --------- Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
594e552f7b |
Add Docker Hub login to Cloud Agent start hook. (#36632)
Authenticate DinD pulls at runtime using Cursor dashboard secrets so agents avoid anonymous Docker Hub rate limits. Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
23dc74ece2 |
Document Mattermost cloud startup flow (#36559)
* Add Cursor Cloud Agent Docker environment * Fix Cloud Agent enterprise and Docker access * Fix Cloud Agent Go path setup * Use Cursor multi-repo enterprise checkout * Use sibling enterprise checkout layout * Add tmux to Cloud Agent image * Document Mattermost cloud startup flow Co-authored-by: nick.misasi <[email protected]> * Document Mattermost license behavior in cloud Co-authored-by: nick.misasi <[email protected]> --------- Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
4d2d6836b5 |
Prepackage mattermost-plugin-agents v2.0.3 (#36401)
Bump the default prepackaged Agents plugin from 2.0.2 to 2.0.3 (non-FIPS). FIPS prepackaged plugin package list is unchanged. Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
235ec3330c |
MM-68382: Align team creation invite permission checks (#36188)
* MM-68382 - align team creation invite permissions Keep invite-related team settings consistent during team creation so authorization matches existing update and patch behavior. Made-with: Cursor * MM-68382 - move team create helper closer to usage Keep the create-team authorization helper next to createTeam so the file reads in usage order. Made-with: Cursor * commit before ff * MM-68382 - reject invite fields on create without permission Reject createTeam with 403 (matching updateTeam/patchTeam) when the creator tries to set AllowOpenInvite or AllowedDomains without PermissionInviteUser, instead of silently stripping those fields. Add scheme-branch coverage and log scheme-fetch failures from the permission check. Made-with: Cursor * api4: add symmetric happy path test for scheme InviteUser without invite fields Cover team creation when the scheme grants InviteUser but AllowOpenInvite and AllowedDomains are unset, asserting InviteId is returned in the response. Made-with: Cursor |
||
|
|
3bb1993a57 |
[MM-68393] Tighten protected role patch authorization (#36197)
* [MM-68393] Tighten protected role patch authorization Harden role patch authorization for protected system roles and cover the restricted paths with focused API tests. Made-with: Cursor * [MM-68393] Fix role patch test shadowing Rename shadowing response variables in the protected role patch tests so govet passes in core and enterprise check-style jobs. Made-with: Cursor * [MM-68393] Block privileged role permissions Made-with: Cursor |
||
|
|
c2c643af84 |
Prepackage Agents plugin v2.0.2 (#36349)
Update non-FIPS PLUGIN_PACKAGES entry to mattermost-plugin-agents-v2.0.2 (https://github.com/mattermost/mattermost-plugin-agents/releases/tag/v2.0.2). FIPS prepackage is unchanged; v2.0.2 FIPS artifacts are not published yet. Made-with: Cursor |
||
|
|
581c7e8dda |
Add stronger EnableTesting warnings (#36158)
* Add stronger EnableTesting warnings Co-authored-by: Nick Misasi <[email protected]> * Keep EnableTesting translations in en only Co-authored-by: Nick Misasi <[email protected]> * Address EnableTesting review feedback Co-authored-by: Nick Misasi <[email protected]> --------- Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
e29bf190d5 |
MM-67913: fix white flash on product navigation by centralizing app__body ownership (#36186)
* MM-67913: fix white flash on product navigation by centralizing app__body ownership
Previously, `document.body.classList.add/remove('app__body')` was managed
independently by `ChannelController` and each product plugin (Playbooks,
Boards). When switching products, the plugin's cleanup removed `app__body`
before the incoming tree's effect re-applied it. Because `ChannelController`
is deeply nested and sometimes async, a ~170ms gap could elapse during which
the body fell back to `background: $bg--gray`, producing a visible white
flash behind the transparent `GlobalHeader` and LHS.
Centralize `app__body` ownership in `WithUserTheme` via a new
`useAppBodyClass` hook. Since `WithUserTheme` wraps both the products
Switch and the `/:team` route in `root.tsx`, it stays mounted across
product navigation, so the class is never removed mid-transition.
`ChannelController` no longer toggles `app__body`; tests updated.
Product plugins (Playbooks, Boards) should stop touching `app__body` as
well; companion fixes land in their respective repos.
Made-with: Cursor
* MM-67913: add coverage for app body class ownership
Made-with: Cursor
* Update webapp/channels/src/components/theme_provider/theme_context.ts
Co-authored-by: Harrison Healey <[email protected]>
* MM-67913: fix theme context hook closure
Made-with: Cursor
---------
Co-authored-by: Harrison Healey <[email protected]>
|
||
|
|
5192b5c67d | Remove AGENTS.CLOUD.md (#36286) | ||
|
|
a74ca57a63 |
[MM-68231] Tighten post info authorization (#36111)
* [MM-68231] Tighten post info authorization Align post info channel access with the standard read path while preserving expected public-channel discoverability. Add regression coverage for guest and compliance-mode access checks. Made-with: Cursor * [MM-68231] Strengthen post info test coverage Tighten the new post info regression coverage so the guest denial case proves its setup and the compliance case asserts the expected non-compliance behavior first. Made-with: Cursor * [MM-68231] Expand post info authorization coverage Add focused regression coverage for invite-team access, compliance behavior on open teams, private-channel permission boundaries, and outsider denial for DM and GM post info. Made-with: Cursor |
||
|
|
ec70e46c83 |
Keep recap menu available after read (#35547)
Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
e0ac5022f9 |
MM-67352 Prevent composer scroll jumps on formatting click (#36081)
* MM-67352 Prevent composer scroll jumps on formatting click Keep formatting controls from stealing textarea focus on mousedown so long drafts stay in place when markdown buttons are clicked. Add a regression test for the formatting bar interaction. Made-with: Cursor * Update webapp/channels/src/components/advanced_text_editor/formatting_bar/formatting_icon.tsx Co-authored-by: Harrison Healey <[email protected]> --------- Co-authored-by: Harrison Healey <[email protected]> Co-authored-by: Mattermost Build <[email protected]> |
||
|
|
a36d8bb40f |
MM-68160: Fix post reminder confirmation not appearing for replies in RHS (#36124)
* MM-68160: Show post reminder ack in RHS for reply reminders Set the reminder confirmation ephemeral post root_id to the thread root when the reminder is set on a reply, matching how thread views key posts. Re-enable websocket integration tests for reminders and add coverage for reply vs root behavior. Made-with: Cursor * SetPostReminder: validate post before persisting reminder Read the post and reminder metadata before inserting into PostReminders so a failed GetSinglePost or metadata lookup cannot leave an orphaned row. Made-with: Cursor |
||
|
|
aaac9c6bdf |
MM-67782: Fetch group members on popover open to fix empty member list (#36122)
The group member popover relied entirely on InfiniteLoader to trigger the initial getProfilesInGroup fetch, which fails under certain conditions (slow DOM layout, stale member_count, AutoSizer timing). Dispatch the fetch explicitly when the popover opens via onOpenChange. Made-with: Cursor |
||
|
|
c27b06b4ef |
MM-68047: Hide update status button in RHS post header (#36120)
* MM-68047: Hide update status button in RHS post header
In the RHS (and smaller screens), the "Update your status" button
was consuming space that caused the username to be truncated or
hidden. Hide the button in the RHS context so the name remains
visible.
Made-with: Cursor
* Update permission_system_scheme_settings snapshots
Snapshots were stale after manage_own_agent and manage_others_agent
permissions were added in
|
||
|
|
78ce17c3df |
[MM-67949] Harden notification email filename rendering (#36082)
* [MM-67949] Harden notification email filename rendering Escape and normalize attachment filenames before inserting them into notification email content, and add focused regression coverage for file-only and image-only notification paths. Made-with: Cursor * chore: retrigger CI checks --------- Co-authored-by: Edgar <[email protected]> |
||
|
|
f0ef41e79c |
Update permission_system_scheme_settings snapshots (#36121)
Snapshots were stale after manage_own_agent and manage_others_agent
permissions were added in
|
||
|
|
2595b87754 |
Add manage_own_agent and manage_others_agent permissions (#35924)
* Add PermissionCreateAgent server-side permission definition Define PermissionCreateAgent in the model layer with system scope, add to SystemScopedPermissionsMinusSysconsole (feeds AllPermissions), grant to system_user in MakeDefaultRoles(), and register a permissions migration for existing installations (system_admin + system_user). * Add exhaustive tests for PermissionCreateAgent permission Model tests: verify create_agent is in AllPermissions, has system scope, correct i18n fields, present in system_admin and system_user default roles, and absent from system_guest. Migration test: verify getAddCreateAgentPermissionMigration adds create_agent to both system_admin and system_user, and is idempotent on re-run. Also register the migration key in testlib mock store so server initialization skips it during test setup. * Add webapp permission constants and i18n for create_agent Add CREATE_AGENT constant to permissions.ts, display strings with defineMessages in permissions.tsx, and i18n entries in en.json so the permission appears in System Console Permission Schemes UI. * Clean up tests and minor fixups for create_agent permission Consolidate role_test.go into table-driven tests, remove redundant comments in permissions_migrations_test.go, add .planning/ to .gitignore, and refresh webapp/package-lock.json. * Split create_agent into manage_own_agent and manage_others_agent Replace PermissionCreateAgent with system-scoped own/others permissions, update migration and defaults, and wire System Scheme UI for integrations. Made-with: Cursor * fixes * Stabilize autotranslation E2E by pinning mock source language Set LibreTranslate mock to English before the pre-enable post and Spanish before the post-enable message so parallel tests cannot leave the mock in a state where the new message is not translated. Made-with: Cursor * Revert package-lock, add more chnages * Revert "Revert package-lock, add more chnages" This reverts commit 7f6752c2e0a8bad39fd1a848abb8cf9f0bb611a3. * Drop unrelated autotranslation E2E tweak; restore package-lock The Playwright autotranslation change was not caused by MM-65671. Revert that test edit and restore webapp/package-lock.json after an accidental revert of the prior package-lock update. Made-with: Cursor * Put package-lock back again * fixes * Fix migration tests for manage_own_agent on system_user role Made-with: Cursor --------- Co-authored-by: Mattermost Build <[email protected]> Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
a017f7132a |
MM-67095: Hide Workspace Optimization for cloud-licensed workspaces (#36077)
Made-with: Cursor |
||
|
|
358a00a2e9 |
MM-68140: Validate post read access before rewrite thread context (#35864)
Ensure thread context for message rewrite is only built when the session may read the anchor post, and surface context build failures to the client. Made-with: Cursor |
||
|
|
1c9be72dcb |
Ability to E2E AI Bridge features + Initial Recaps E2E (#35541)
* Add shared AI bridge seam Co-authored-by: Nick Misasi <[email protected]> * Add AI bridge test helper API Co-authored-by: Nick Misasi <[email protected]> * Add AI bridge seam test coverage Co-authored-by: Nick Misasi <[email protected]> * Add Playwright AI bridge recap helpers Co-authored-by: Nick Misasi <[email protected]> * Fix recap channel persistence test Co-authored-by: Nick Misasi <[email protected]> * Restore bridge client compatibility shim Co-authored-by: Nick Misasi <[email protected]> * Expand recap card in Playwright spec Co-authored-by: Nick Misasi <[email protected]> * Recaps e2e test coverage (#35543) * Add Recaps Playwright page object Co-authored-by: Nick Misasi <[email protected]> * Expand AI recap Playwright coverage Co-authored-by: Nick Misasi <[email protected]> * Format recap Playwright coverage Co-authored-by: Nick Misasi <[email protected]> * Fix recap regeneration test flows Co-authored-by: Nick Misasi <[email protected]> --------- * Fix AI bridge lint and OpenAPI docs Co-authored-by: Nick Misasi <[email protected]> * Fix recap lint shadowing Co-authored-by: Nick Misasi <[email protected]> * Stabilize failed recap regeneration spec Co-authored-by: Nick Misasi <[email protected]> * Fill AI bridge i18n strings Co-authored-by: Nick Misasi <[email protected]> * Fix i18n * Add service completion bridge path and operation tracking fields Extend AgentsBridge with CompleteService for service-based completions, add ClientOperation/OperationSubType tracking to BridgeCompletionRequest, and propagate operation metadata through to the bridge client. Made-with: Cursor * Fill empty i18n translation strings for enterprise keys The previous "Fix i18n" commit added 145 i18n entries with empty translation strings, causing the i18n check to fail in CI. Fill in all translations based on the corresponding error messages in the enterprise and server source code. * Fix i18n * Fix i18n again * Rename Complete/CompleteService to AgentCompletion/ServiceCompletion Align the AgentsBridge interface method names with the underlying bridge client methods they delegate to (AgentCompletion, ServiceCompletion). Made-with: Cursor * Refactor * Add e2eAgentsBridge implementation The new file was missed from the prior refactor commit. Made-with: Cursor * Address CodeRabbit review feedback - Add 400 BadRequest response to AI bridge PUT endpoint OpenAPI spec - Add missing client_operation, operation_sub_type, service_id fields to AIBridgeTestHelperRecordedRequest schema - Deep-clone nested JSON schema values in cloneJSONOutputFormat - Populate ChannelID on recap summary bridge requests - Fix msg_count assertion to mention_count for mark-as-read verification - Make AgentCompletion/ServiceCompletion mutex usage atomic Made-with: Cursor * fix(playwright): align recaps page object with placeholder and channel menu Made-with: Cursor * fix(playwright): update recaps expectEmptyState to match RecapsList empty state After the master merge, the recaps page now renders RecapsList's "You're all caught up" empty state instead of the old placeholder. Made-with: Cursor * chore(playwright): update package-lock.json after npm install Made-with: Cursor * Revert "chore(playwright): update package-lock.json after npm install" This reverts commit 95c670863a55f1549d266baccc1e2fcf8a7cd74e. * style(playwright): fix prettier formatting in recaps page object Made-with: Cursor * fix(playwright): handle both recaps empty states correctly The recaps page has two distinct empty states: - Setup placeholder ("Set up your recap") when allRecaps is empty - RecapsList caught-up state ("You're all caught up") when the filtered tab list is empty Split expectEmptyState into expectSetupPlaceholder and expectCaughtUpEmptyState, used by the delete and bridge-unavailable tests respectively. Made-with: Cursor --------- Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
e30291c652 |
PermissionManageOauth removal impact (#35554)
* Restore manage oauth permission Co-authored-by: Nick Misasi <[email protected]> * Fix migration test lint assertion Co-authored-by: Nick Misasi <[email protected]> --------- Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
1a47605f57 |
MM-67795 fix Recaps sidebar icon alignment (#35546)
Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
8bb97e961d |
Clear channel selection when opening Recaps (#35552)
Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
6c6a7970ce |
Fix recap all-unreads modal copy (#35551)
Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
4db0f02ea0 |
Show priority badges in permalink previews (#35532)
* Add agent-browser skill * Update AGENTS.CURSOR.md * Add guidance for localization * Fix permalink preview priority badges Co-authored-by: Nick Misasi <[email protected]> --------- Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
8d4095bd31 |
Fix create recap channel checkbox selection (#35533)
* Add agent-browser skill * Update AGENTS.CURSOR.md * Add guidance for localization * Fix recap channel checkbox selection Co-authored-by: Nick Misasi <[email protected]> --------- Co-authored-by: Mattermost Build <[email protected]> Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
c647117f4c |
Add operation tracking fields to bridge client calls (#35514)
* Add operation tracking fields to bridge client CompletionRequest calls Populate UserID, Operation, and OperationSubType on CompletionRequest for recaps (SummarizePosts) and message rewrite (RewriteMessage) so token usage logs show correct values instead of defaults. Also bumps mattermost-plugin-ai v1.8.1 → v1.12.0 which adds the Operation/OperationSubType fields to the bridgeclient struct. * Address PR feedback: normalize rewrite action and use session-derived userID - post.go: Add normalizeRewriteAction() that validates action against a whitelist of known RewriteAction values, mapping unknown values to "unknown" before assigning to OperationSubType. - summarization.go: Use sessionUserID (derived from rctx.Session().UserId) instead of the userID parameter for tracking, ensuring operation tracking always uses the authenticated session user. --------- Co-authored-by: Mattermost Build <[email protected]> Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
cdaec84f30 |
Add agent-browser skill and update cloud agent docs (#35534)
* Add agent-browser skill * Update AGENTS.CURSOR.md * Add guidance for localization * Update .agents/skills/agent-browser/references/authentication.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> |
||
|
|
3813af3e1e |
Development environment setup (#35513)
* Add AGENTS.md with Cursor Cloud development environment instructions - Documents service architecture (Go server + React webapp + PostgreSQL) - Covers how to start services, run lint/tests/builds - Notes key gotchas for dev setup (config auto-generation, client symlink, SMTP errors) - Specifies Node.js 24.11 and Go 1.24.13 version requirements Co-authored-by: Nick Misasi <[email protected]> * Update AGENTS.md with dual-repo enterprise development setup - Document enterprise repo at $HOME/enterprise and plugin-agents at $HOME/mattermost-plugin-agents - Add git authentication instructions for cross-repo operations with CURSOR_GH_TOKEN - Document enterprise server build, run, and plugin deployment workflow - Add cross-repo PR workflow instructions - Include BUILD_ENTERPRISE_DIR usage for all make commands Co-authored-by: Nick Misasi <[email protected]> * Rewrite AGENTS.md: add plugin config docs, move automatable steps to update script - Add Agents plugin configuration section with full JSON structure and API usage - Document ANTHROPIC_API_KEY requirement and config-must-be-object gotcha - Remove instructions now handled by update script: config.override.mk, client symlink, git insteadOf cleanup, remote URL cleanup - Trim redundant sections for conciseness Co-authored-by: Nick Misasi <[email protected]> * AGENTS.md: use make run/restart-server workflow, document TEAM EDITION gotcha - Replace manual go build/run instructions with make run and make restart-server - Emphasize BUILD_ENTERPRISE_DIR must be passed to every make command - Document that 'TEAM EDITION' label is license-dependent, not build-dependent - Add verification steps for confirming enterprise code is loaded Co-authored-by: Nick Misasi <[email protected]> * AGENTS.md: add TEST_LICENSE/MM_LICENSE for enterprise licensing - Pass MM_LICENSE=$TEST_LICENSE in make run and make restart-server commands - Document that the license unlocks enterprise features and removes TEAM EDITION badge - Simplify the TEAM EDITION gotcha to focus on the fix Co-authored-by: Nick Misasi <[email protected]> * Rename AGENTS.md to AGENTS.CLOUD.md, gitignore AGENTS.md AGENTS.md is a standard file that affects real editors. To avoid impacting non-cloud workflows, the cloud-specific instructions now live in AGENTS.CLOUD.md (committed) and the update script copies it to AGENTS.md (gitignored) on startup so Cursor Cloud agents still pick it up. Co-authored-by: Nick Misasi <[email protected]> --------- Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
221e6da3f4 |
Add structured JSON output for recap summarization (#35496)
* Add structured outputs, response sanitization, and session context for recaps
- Wrap BridgeClient to strip markdown code fencing from LLM JSON responses,
using explicit delegation to prevent unsanitized methods from leaking
- Add JSONOutputFormat schema to SummarizePosts for structured LLM output
- Pass user session in recap worker context for session-dependent code paths
- Pre-parse min plugin version semver at package level to avoid repeated parsing
- Hoist static JSON schema to package-level var to avoid per-call allocation
* Fix stripMarkdownCodeFencing to handle single-line fenced payloads
Address CodeRabbit feedback: the function previously returned the original
string when fenced JSON had no newline (e.g. ```json {"a":1}```), which
would break downstream JSON parsing.
* Handle case/spacing variants for single-line fenced language tags
Address CodeRabbit feedback: use case-insensitive comparison for the
"json" language tag and check for whitespace separator, so inputs like
```JSON {"a":1}``` are handled correctly.
* Revert BridgeClient wrapper and keep only structured output changes
Remove the BridgeClient wrapper, stripMarkdownCodeFencing, and semver
pre-parse from agents.go. The scope of this PR is limited to adding
JSONOutputFormat structured outputs for recaps and the worker session
context fix.
* Fix lint: use any instead of interface{} and fix gofmt formatting
---------
Co-authored-by: Hanzo Dev <[email protected]>
|
||
|
|
4d6affd06c |
[MM-67605] Add DCR redirect URI allowlist for OAuth DCR (#35291)
* [MM-67605] Add DCR redirect URI allowlist enforcement Introduce ServiceSettings.DCRRedirectURIAllowlist with glob-based validation and enforce it during OAuth dynamic client registration to block unapproved redirect URIs. Add System Console wiring and tests for config validation, wildcard matching semantics, API error behavior, and localhost wildcard support. * Fix pre-commit checks: TypeScript type assertion, gofmt, and regenerate CI artifacts - admin_definition_dcr_allowlist.test.tsx: Add AdminDefinitionSettingInput type assertion for 'multiple' property - oauth_dcr_test.go: Fix comment spacing (gofmt) - Regenerate mocks, go.sum, gen-serialized, mmctl-docs per CI requirements * Revert unnecessary pre-commit regenerations Revert mmctl docs, mocks, go.sum, and gen-serialized to master. Keep only the TypeScript and gofmt fixes from the previous commit. * Fix import order in admin_definition_dcr_allowlist.test.tsx * Fix i18n * Update server/public/model/oauth_dcr.go Co-authored-by: Eva Sarafianou <[email protected]> * Fix --------- Co-authored-by: Eva Sarafianou <[email protected]> Co-authored-by: Mattermost Build <[email protected]> Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
8c4dd74ab5 |
Add Default Agent Support and promote Agents to be part of suite (#35091)
* Add default agent support and App Bar integration - Add Agents section to App Bar, separating it from Core Products. - Implement Default Agent logic in AtMentionProvider: - Promote default agent to top of suggestions for empty '@' prefix. - Filter duplicate agent entry from main list when default is shown. - Add `AgentTag` component for UI distinction. - Update `mattermost-plugin-ai` and `server/public` dependencies. - Add unit tests for default agent suggestion logic. * Add missing files (server deps, types) * Fix pre-commit check failures - Fix TypeScript errors in test files: - Add missing displayName property to defaultAgent in at_mention_provider test - Add missing fetchAgents mock in textbox test - Fix Go assignment mismatch in integration_action_test.go (CreatePostAsUser returns 3 values) - Fix license copyright year in plugins/mattermost-ai/assets/embed.go - Update i18n translations (add tag.default.agent) - Regenerate Go serialized files, mmctl docs, and update go.mod/go.sum * Update snapshot tests for textbox and at_mention_suggestion * Undo mmctl docs changes * Undo more changes * revert package-lock.json * Update dep for ai plugin * Update again * Update at_mention_provider to filter out agent duplicates and add .cursor/ to gitignore - Filter agent usernames from priorityProfiles and localAndRemoteMembers to prevent duplicate entries in autocomplete suggestions - Add .cursor/ directory to .gitignore --------- Co-authored-by: Mattermost Build <[email protected]> Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
8ef79057c5 |
MM-66577 Preserve locale in rewrite prompt (#35013)
* Preserve rewrite locale in prompt * Add license header to rewrite tests |
||
|
|
0f15e3fcd3 |
Register product icon change (#34883)
* Adjust registerProduct to accept generic icon * Undo unnecessary changes * Anotha one * Fix linting errors in product menu tests - Fix jsx-quotes to use single quotes instead of double quotes - Fix react/jsx-max-props-per-line by placing props on separate lines - Fix react/jsx-no-literals by wrapping literal strings in JSX expression containers - Fix react/jsx-wrap-multilines by wrapping multiline JSX in parentheses - Fix react/jsx-closing-bracket-location for proper bracket alignment * don't use snapshots or enzyme * Fix pipelines? |
||
|
|
a060e1c963 |
MM-67141 Update AI rewrite prompt guidance (#35011)
* Improve rewrite menu guidance Keep AI rewrite prompts visible on focus and clarify the empty-state instruction. * Apply suggestions from code review * Apply suggestion from @nickmisasi * Fix rewrite menu test assertions Update test expectations to match component string values after defaultMessage changes. Fix syntax error with unterminated string and correct placeholder text expectation. --------- Co-authored-by: Mattermost Build <[email protected]> |
||
|
|
f8f23c883c |
[MM-66581] Include some thread context in AI Rewrites prompt (#34931)
* Include last root, and most recent 10 posts in a thread with the rewrite system prompt * Include user's names in the thread context for better reference * Revert package-lock to master * Fix tests |
||
|
|
a3b934be08 |
[MM-66591] Channel Summarization - header icon pluggable + citation support (#34687)
* Add pluggable ChannelHeaderIcon * Add orchestration for post/channel/team citations in post render * Updates to suit new format cor citations * Fix linter * Fix stylelint property order errors in _markdown.scss * Fix TypeScript type errors - Add missing ChannelHeaderIcon to initialComponents in plugins reducer - Fix SelectProps generic to use 'false' instead of 'boolean' for isMulti in dropdown_input_hybrid * Update channel_header snapshots to include ChannelHeaderIcon Pluggable * PR feedback changes * Add snapshots * Add export for DatePicker * PR Feedback --------- Co-authored-by: Mattermost Build <[email protected]> |
||
|
|
0aa4780951 |
[MM-67118] Add Agents to @ mention autocomplete in channel (#34881)
* Add support for autocomplete of plugin-created bots * stashing * Add support for including agents in the autocomplete list for @ mentions * Change server response to be users rather than interface * fix |
||
|
|
98f71a782d |
[MM-67160] Add audit logging for recap API endpoints (#34929)
* Add audit logging for recap API endpoints - Add audit event constants for all recap operations - Implement Auditable interface for Recap model - Add comprehensive audit logging to all 6 recap endpoints - Log channel_ids to track implicit channel content access - Use LevelContent for content-related operations, LevelAPI for listing * Address PR feedback: standardize audit method order and extract helper function - Standardized order of audit record method calls across all handlers: set object type first, then prior state (if applicable), then result state - Extracted duplicated channel ID extraction logic into addRecapChannelIDsToAuditRec helper function |
||
|
|
2bc425abfe |
Add optional Claude.md orchestration for Webapp folder (#34668)
* Add CLAUDE.md documentation files for webapp directories - Add root webapp CLAUDE.md with overview and build commands - Add channels CLAUDE.md with architecture and testing info - Add documentation for actions, components, selectors, utils - Add documentation for sass, tests, and mattermost-redux - Add platform documentation for client and types - Update .gitignore * Add CLAUDE docs and allow tracking * Clarify CLAUDE instructions for i18n workflow * Refactor webapp/CLAUDE.md into a nested hierarchy Decomposed the monolithic webapp/CLAUDE.md into focused, context-aware files distributed across the directory structure: - webapp/CLAUDE.md (Root overview) - webapp/channels/CLAUDE.md (Channels workspace) - webapp/channels/src/components/CLAUDE.md - webapp/channels/src/actions/CLAUDE.md - webapp/channels/src/selectors/CLAUDE.md - webapp/channels/src/packages/mattermost-redux/CLAUDE.md - webapp/platform/CLAUDE.md (Platform workspace) - webapp/platform/client/CLAUDE.md * Move files to optional, then add script to move them to proper claud.md |
||
|
|
5a4c2a3afa |
[MM-66359] Recaps MVP (#34337)
* initial commit for POC of Plugin Bridge * Updates * POC for plugin bridge * Updates from collaboration * Fixes * Refactor Plugin Bridge to use HTTP/REST instead of RPC - Remove ExecuteBridgeCall hook and Context.SourcePluginId - Implement HTTP-based bridge using existing PluginHTTP infrastructure - Add CallPlugin API method with endpoint parameter instead of method name - Update CallPluginBridge to construct HTTP POST requests - Add proper headers: Mattermost-User-Id, Mattermost-Plugin-ID - Use 'com.mattermost.server' as plugin ID for core server calls - Update ai.go to use REST endpoint /inter-plugin/v1/completion - Add comprehensive spec documentation in server/spec.md - Add MIGRATION_GUIDE.md for plugin developers - Fix 401/404 issues by setting correct headers and URL paths * Improve Plugin Bridge security and architecture - Create ServeInternalPluginRequest for internal plugin calls (core + plugin-to-plugin) - Move header-setting logic from CallPluginBridge to ServeInternalPluginRequest - Improve separation of concerns: business logic vs HTTP transport - Add security documentation explaining header protection Security Improvements: - ServeInternalPluginRequest is NOT exposed as HTTP route (internal only) - Headers (Mattermost-User-Id, Mattermost-Plugin-ID) are set by trusted server code - External requests cannot spoof these headers (stripped by servePluginRequest) - Core calls use 'com.mattermost.server' as plugin ID for authorization - Plugin-to-plugin calls use real plugin ID (enforced by server) Backward Compatibility: - Keep ServeInterPluginRequest for existing API.PluginHTTP callers (deprecated) - All tests pass Docs: - Update spec.md with security model explanation - Update MIGRATION_GUIDE.md with correct header usage examples * Space * cursor please stop creating markdown files * Fix style * Fix i18n, linter * REMOVE MARKDOWN * Remove CallPlugin method from plugin API interface Per review feedback, this method is no longer needed. Co-authored-by: Nick Misasi <[email protected]> * Remove CallPlugin method implementation from PluginAPI Co-authored-by: Nick Misasi <[email protected]> * fixes * Add AI OpenAPI spec * fix openapi spec * Use agents client (#34225) * Use agents client * Remove default agent * Fixes * fix: modify system prompts to ensure JSON is being returned * Base implementation for recaps working * small fixes * Adjustments * remove webapp changes * Add feature flags for rewrites and ai bridge, clean up * Remove comments that aren't helpful * Fix i18n * Remove rewrites * Fix tests * Fix i18n * adjust i18n again * Add back translations * Remove leftover mock code * remove model file * Changes from PR review * Make the real substitutions * Include a basic invokation of the client with noop to ensure build works * more fix * Remove unneeded change * Updates from review * Fixes * Remove some logic from rewrites to clean up branch * Use v1.5.0 of agents plugin * A bunch more additions for general UX flow * Add missing files * Add mocks * Fixes for vet-api, i18n, build, types, etc * One more linter fix * Fix i18n and some tests * Refactors and cleanup in backend code * remove rogue markdown file * fixes after refactors from backend * Add back renamed files, and add tests * More self code review * More fixes * More refactors * Fix call stack exceeded bug * Include read messages if there are no unreads * Fix test failure: use correct error message key for recap permission denied The getRecapAndCheckOwnership function was using strings.ToLower(callerName) to generate error keys, which caused 'GetRecap' to become 'getrecap' instead of the expected 'get'. Changed to use the correct static key that matches the en.json localization file. Fixes TestGetRecap/get_recap_by_non-owner test failure. Co-authored-by: Nick Misasi <[email protected]> * Consolidate permission errors down to a single string * Fixes for i18n, worktrees making this difficult * Fix i18n * Fix i18n once and for all (for real) (final) * Fix duplicate getAgents method in client4.ts * Remove duplicate ai state from initial_state.ts * Fix types * Fix tests * Fix return type of GetAgents and GetServices * Add tests for recaps components * Fix types * Update i18n * Fixes * Fixes * More cleanup * Revert random file * Use undefined * fix linter * Address feedback * Missed a git add * Fixes * Fix i18n * Remove fallback * Fixes for PR --------- Co-authored-by: Nick Misasi <[email protected]> Co-authored-by: Christopher Speller <[email protected]> Co-authored-by: Felipe Martin <[email protected]> Co-authored-by: Mattermost Build <[email protected]> Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
f469f27f7b |
Update prepackaged Agents to 1.7.2 (#34780)
Automatic Merge |
||
|
|
90f98b8221 |
Simplify useOpenPricingModal to always open external pricing link (#34664)
Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
29e802b190 |
Add Pluggable to BrowseOrCreateChannel menu (#34637)
* Add Pluggable to BrowseOrCreateChannel menu * Put back a comment * Adjust to include currentTeamId * Change from component to action * Fix types * Fix linter |
||
|
|
a32afd188b | Fix 500 error when agents plugin isn't active or installed (#34573) | ||
|
|
2f7d7c9953 |
Fix issues with access_control_policies/search endpoint functionality and docs (#34564)
* Fix issues with access_control_policies/search endpoint functionality and docs * Undo |
||
|
|
ad331bda99 |
Integration permission management changes (#34421)
* Support for permissions allowing end users to create and manage their own integrations if sysadmin deems necessary * Adjustments based on new understanding * remove extra functions now that we've consolidated * Fix webapp i18n * Update snapshots * Fix test * Fix some tests, refactor some more, and add a few extra * fix linter * Update snapshots * Fix test * Missed some cleanup * Fix e2e * Fi * Fix * Fixes from PR feedback * Update snapshots * Fix tests * Fix slash command list endpoint per PR feedback. Remove changes around OAuth Apps * Further reversions of oauth stuff * Update tests * Small changes to fix when customOnly=false * Remove extra perm from cypress * Fixes from Eva's feedback * Fix i18n * More fixing * More fixing |
||
|
|
d9b470c142 |
Add channel_locked to webhook creation and update docs (#34398)
Co-authored-by: Mattermost Build <[email protected]> |
||
|
|
a6b9717767 |
Add Agents token tracking Grafana dashboard template (#34324)
* Add prometheus data source from agents, add agents dashboard * Fix graphs, tables * Apply suggestion from @nickmisasi --------- Co-authored-by: Mattermost Build <[email protected]> |
||
|
|
6fa05b6ef0 |
Add common code for AI workflows (#34381)
* Add common /ai endpoints for agents and services and common component for agent selection * Fix vet api * Add a bunch of redux stuff * Fixes * Missed an add * fix types * Add a hook to determine if bridge is enabled * Add debounce to hook to prevent double fetches from PLUGIN_* and CONFIG_CHANGED event both firing when a plugin state is changed * Fix i18n * Rename to remove 'AI' (#34393) --------- Co-authored-by: Christopher Speller <[email protected]> Co-authored-by: Mattermost Build <[email protected]> |
||
|
|
9f378759cf | Add support for make i18n-extract when dep folders are symlinked (#34385) | ||
|
|
da7a8352f2 |
[Build 2025] AI Plugin Bridge (#34216)
* initial commit for POC of Plugin Bridge * Updates * POC for plugin bridge * Updates from collaboration * Fixes * Refactor Plugin Bridge to use HTTP/REST instead of RPC - Remove ExecuteBridgeCall hook and Context.SourcePluginId - Implement HTTP-based bridge using existing PluginHTTP infrastructure - Add CallPlugin API method with endpoint parameter instead of method name - Update CallPluginBridge to construct HTTP POST requests - Add proper headers: Mattermost-User-Id, Mattermost-Plugin-ID - Use 'com.mattermost.server' as plugin ID for core server calls - Update ai.go to use REST endpoint /inter-plugin/v1/completion - Add comprehensive spec documentation in server/spec.md - Add MIGRATION_GUIDE.md for plugin developers - Fix 401/404 issues by setting correct headers and URL paths * Improve Plugin Bridge security and architecture - Create ServeInternalPluginRequest for internal plugin calls (core + plugin-to-plugin) - Move header-setting logic from CallPluginBridge to ServeInternalPluginRequest - Improve separation of concerns: business logic vs HTTP transport - Add security documentation explaining header protection Security Improvements: - ServeInternalPluginRequest is NOT exposed as HTTP route (internal only) - Headers (Mattermost-User-Id, Mattermost-Plugin-ID) are set by trusted server code - External requests cannot spoof these headers (stripped by servePluginRequest) - Core calls use 'com.mattermost.server' as plugin ID for authorization - Plugin-to-plugin calls use real plugin ID (enforced by server) Backward Compatibility: - Keep ServeInterPluginRequest for existing API.PluginHTTP callers (deprecated) - All tests pass Docs: - Update spec.md with security model explanation - Update MIGRATION_GUIDE.md with correct header usage examples * Space * cursor please stop creating markdown files * Fix style * Fix i18n, linter * REMOVE MARKDOWN * Remove CallPlugin method from plugin API interface Per review feedback, this method is no longer needed. Co-authored-by: Nick Misasi <[email protected]> * Remove CallPlugin method implementation from PluginAPI Co-authored-by: Nick Misasi <[email protected]> * fixes * Add AI OpenAPI spec * fix openapi spec * Use agents client (#34225) * Use agents client * Remove default agent * Fixes * fix: modify system prompts to ensure JSON is being returned * remove webapp changes * Add feature flags for rewrites and ai bridge, clean up * Remove comments that aren't helpful * Fix i18n * Remove rewrites * Fix tests * Fix i18n * adjust i18n again * Add back translations * Remove leftover mock code * remove model file * Make the real substitutions * Include a basic invokation of the client with noop to ensure build works * Remove unneeded change * Updates from review * Fixes * Use v1.5.0 of agents plugin --------- Co-authored-by: Nick Misasi <[email protected]> Co-authored-by: Christopher Speller <[email protected]> Co-authored-by: Felipe Martin <[email protected]> Co-authored-by: Mattermost Build <[email protected]> Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
a1b6b9548c | Add support for pgvector in local dev (#33900) | ||
|
|
4057a0ba4c |
[CLD-9487] Support for Entry + updates to Edition & License screen (#33672)
* Support for Entry license with limits + updates to Edition & License screen * put back SetLicense(nil) for non FF enabled path * Fix tests, add another * Add changes * Changes to address Figma adjustments * Address PR feedback * Shift entry license to enterprise, updates * Update webapp/channels/src/components/admin_console/license_settings/enterprise_edition/enterprise_edition.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/admin_console/license_settings/enterprise_edition/enterprise_edition.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/admin_console/license_settings/enterprise_edition/enterprise_edition.scss Co-authored-by: Matthew Birtch <[email protected]> * More adjustments * Remove Granular Administration * Hide ABAC feature discovery on Entry * PR feedback * Update server/channels/app/platform/license.go Co-authored-by: Julien Tant <[email protected]> * Fix tests * fix tests properly * Try to fix tests --------- Co-authored-by: Mattermost Build <[email protected]> Co-authored-by: Matthew Birtch <[email protected]> Co-authored-by: Julien Tant <[email protected]> |
||
|
|
f08b130686 |
Add support for ent adv to Cloud, fix some broken windows (#33745)
* Add support for ent adv to Cloud, fix some broken windows * Fixes |
||
|
|
2b86daf284 |
[CLD-9535] [CLD-9352] Adjust useOpenSalesLink bases its query parameters on useExternalLink (#33451)
* Adjust useOpenSalesLink bases its query parameters on useExternalLink * Fixes for CI |
||
|
|
9d008e8bc2 |
Add support for dynamic fetching of preview modal content from S3 bucket (#33380)
* Add support for dynamic fetching of preview modal content from S3 bucket
* Update server/channels/api4/cloud.go
* Update webapp/channels/src/components/cloud_preview_modal/cloud_preview_modal_controller.test.tsx
* Fixes for CI pipelines
* Add definitions for openapi spec
* Use any instead of interface{}
* Update translations
* Add the translations
* Hook should only run fetch when in cloud preview
---------
Co-authored-by: Hanzo Dev <[email protected]>
|
||
|
|
b54a3ce8a3 | Remove preview modal button when in calls view (#33379) | ||
|
|
dd1463dc49 |
Add preview specific UTM parameters (#32509)
Automatic Merge |
||
|
|
f716b83662 | Update subtitle for boards preview (#32168) | ||
|
|
035f7d641c |
[CLD-9318] Button to re-open Preview Modal after closing (#32121)
* Remove pricing modal. Adjust everywhere to instead open mattermost.com/pricing. When air gapped, don't show buttons to view plans. * Fix lint * Further clean up of unused code. Fixes for linter * Remove onboarding tasklist for previews, add Cloud previer banner * Fixes for linter, i18n * Revert dev lines * Fix lint * When below one minute, switch to seconds * fix linter * Add scaffolding for new Cloud Preview Modal * Style updates * Fix tests * fixes for PR feedback * useExternalLink for opening pricing modal with enriched params * Fix i17n * fix style * Fix style, tests * Fix linter, types * Add file * Make types even more fixed * fix: correct test case for SKU label not provided scenario The test "should not render SKU label when not provided" was incorrectly using baseContent which includes a SKU label. Fixed by creating contentWithoutSku that explicitly sets skuLabel to undefined to properly test the scenario where no SKU label is provided. Co-authored-by: Nick Misasi <[email protected]> * Fine I'll do it myself * fix linter * Refactors * Adjustments from PR review. Adjustments to video experience (poster/play button) and starting to translate * Fix i18n * Wrap translation strings with defineMessage for i18n extraction - Add import for defineMessage and MessageDescriptor from react-intl - Update type definition to use MessageDescriptor for better type safety - Wrap all skuLabel, title, and subtitle objects with defineMessage() calls - This ensures the i18n-extract tool can properly detect translation strings Co-authored-by: Nick Misasi <[email protected]> * Fix i18n * Use regular modal close button * Fix pipelines * Fix i18n * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Remove unnecessary CSS properties from preview modal content Remove display: flex, height: 100%, and flex-direction: column from .preview-modal-content selector as they have no effect per code review feedback. Co-authored-by: Nick Misasi <[email protected]> * Fixes for PR review * Fix linter * Fix i18n * fix linter * sticky button in bottom left to re-open preview modal when previously closed * fix linter * Resize to better fit in place when multiple teams are present * Changes to address Harrison's feedback * change file name, remove index.tsx * Add the new files * Rename to fix conflicts * Add the new files --------- Co-authored-by: Nick Misasi <[email protected]> Co-authored-by: Mattermost Build <[email protected]> Co-authored-by: Matthew Birtch <[email protected]> Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
ebeb77a653 |
[CLD-9238] Direct preview user to proper team based on use case (#31784)
* Remove pricing modal. Adjust everywhere to instead open mattermost.com/pricing. When air gapped, don't show buttons to view plans. * Fix lint * Further clean up of unused code. Fixes for linter * Remove onboarding tasklist for previews, add Cloud previer banner * Fixes for linter, i18n * Revert dev lines * Fix lint * When below one minute, switch to seconds * fix linter * Add scaffolding for new Cloud Preview Modal * Style updates * Fix tests * fixes for PR feedback * useExternalLink for opening pricing modal with enriched params * Fix i17n * fix style * Fix style, tests * Fix linter, types * Add file * Make types even more fixed * fix: correct test case for SKU label not provided scenario The test "should not render SKU label when not provided" was incorrectly using baseContent which includes a SKU label. Fixed by creating contentWithoutSku that explicitly sets skuLabel to undefined to properly test the scenario where no SKU label is provided. Co-authored-by: Nick Misasi <[email protected]> * Fine I'll do it myself * fix linter * Refactors * Adjustments from PR review. Adjustments to video experience (poster/play button) and starting to translate * Fix i18n * Accept use case in CWS login, redirect to proper team, with filtered content in preview modal * Wrap translation strings with defineMessage for i18n extraction - Add import for defineMessage and MessageDescriptor from react-intl - Update type definition to use MessageDescriptor for better type safety - Wrap all skuLabel, title, and subtitle objects with defineMessage() calls - This ensures the i18n-extract tool can properly detect translation strings Co-authored-by: Nick Misasi <[email protected]> * Fix i18n * Hiding modal will presist through refreshes * Fix linter * Add exception to notification permission bar for cloud previews * Use regular modal close button * Fix pipelines * Fix i18n * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Remove unnecessary CSS properties from preview modal content Remove display: flex, height: 100%, and flex-direction: column from .preview-modal-content selector as they have no effect per code review feedback. Co-authored-by: Nick Misasi <[email protected]> * feat: use getBool selector instead of get for boolean preference check - Replace getPreference with getBool to avoid explicit === 'true' comparison - Follows Harrison's review suggestion for cleaner boolean handling Co-authored-by: Nick Misasi <[email protected]> * fix linter * Fixes for PR review * Fix linter * Fix i18n * fix linter * Changes to address Harrison's feedback * Change file name, remove index.tsx * change file name, remove index.tsx * Add the new files --------- Co-authored-by: Nick Misasi <[email protected]> Co-authored-by: Mattermost Build <[email protected]> Co-authored-by: Matthew Birtch <[email protected]> Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
772a9d3b4a |
[CLD-9186] Add framework for new Cloud Preview Modal (#31235)
* Remove pricing modal. Adjust everywhere to instead open mattermost.com/pricing. When air gapped, don't show buttons to view plans. * Fix lint * Further clean up of unused code. Fixes for linter * Remove onboarding tasklist for previews, add Cloud previer banner * Fixes for linter, i18n * Revert dev lines * Fix lint * When below one minute, switch to seconds * fix linter * Add scaffolding for new Cloud Preview Modal * Style updates * Fix tests * fixes for PR feedback * useExternalLink for opening pricing modal with enriched params * Fix i17n * fix style * Fix style, tests * Fix linter, types * Add file * Make types even more fixed * fix: correct test case for SKU label not provided scenario The test "should not render SKU label when not provided" was incorrectly using baseContent which includes a SKU label. Fixed by creating contentWithoutSku that explicitly sets skuLabel to undefined to properly test the scenario where no SKU label is provided. Co-authored-by: Nick Misasi <[email protected]> * Fine I'll do it myself * fix linter * Refactors * Adjustments from PR review. Adjustments to video experience (poster/play button) and starting to translate * Fix i18n * Wrap translation strings with defineMessage for i18n extraction - Add import for defineMessage and MessageDescriptor from react-intl - Update type definition to use MessageDescriptor for better type safety - Wrap all skuLabel, title, and subtitle objects with defineMessage() calls - This ensures the i18n-extract tool can properly detect translation strings Co-authored-by: Nick Misasi <[email protected]> * Fix i18n * Use regular modal close button * Fix pipelines * Fix i18n * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss Co-authored-by: Matthew Birtch <[email protected]> * Remove unnecessary CSS properties from preview modal content Remove display: flex, height: 100%, and flex-direction: column from .preview-modal-content selector as they have no effect per code review feedback. Co-authored-by: Nick Misasi <[email protected]> * Fixes for PR review * Fix linter * Fix i18n * fix linter * Changes to address Harrison's feedback * change file name, remove index.tsx * Add the new files --------- Co-authored-by: Nick Misasi <[email protected]> Co-authored-by: Mattermost Build <[email protected]> Co-authored-by: Matthew Birtch <[email protected]> Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
f1f42ff125 |
[CLD-9285] Add server version and edition (team vs ent) to ExternalLink component (#31783)
* Add server version and edition (team vs ent) to ExternalLink component * fix: add proper Redux state setup to datetime_input.test.tsx The test was failing because the useExternalLink hook (added in this PR) requires access to config and license Redux state, but the datetime_input tests weren't providing proper initial state. This caused components to receive undefined values from Redux selectors, potentially affecting locale/date formatting behavior. Added defaultState with proper config and license structure to match what other tests in the codebase use, ensuring consistent test environment. Co-authored-by: Nick Misasi <[email protected]> * Revert to master * Revert to master --------- Co-authored-by: Nick Misasi <[email protected]> Co-authored-by: Hanzo Dev <[email protected]> |
||
|
|
76d79448be |
[CLD-9186] Remove onboarding tasklist, add preview banner (#31203)
* Remove pricing modal. Adjust everywhere to instead open mattermost.com/pricing. When air gapped, don't show buttons to view plans. * Fix lint * Further clean up of unused code. Fixes for linter * Remove onboarding tasklist for previews, add Cloud previer banner * Fixes for linter, i18n * Revert dev lines * Fix lint * When below one minute, switch to seconds * fix linter * fixes for PR feedback * useExternalLink for opening pricing modal with enriched params * Fix i17n * Fix style, tests * Update webapp/channels/src/components/announcement_bar/cloud_preview_announcement_bar/index.tsx Co-authored-by: Guillermo Vayá <[email protected]> * Fix linter --------- Co-authored-by: Guillermo Vayá <[email protected]> |
||
|
|
8fa992f49d |
Remove in-product pricing modal (#31187)
* Remove pricing modal. Adjust everywhere to instead open mattermost.com/pricing. When air gapped, don't show buttons to view plans. * Fix lint * Further clean up of unused code. Fixes for linter * fixes for PR feedback * useExternalLink for opening pricing modal with enriched params * Fix i17n * Fix style, tests |
||
|
|
8150f034d7 |
Pass the server's version in trial request payload (#30911)
Co-authored-by: Mattermost Build <[email protected]> |
||
|
|
3b55120d3f |
Feature/audit certificate upload (#30223)
* feat: Add certificate upload option for audit logging settings * Commit current changes * Additions * MM-62944 Fix fileupload settings not being clickable * Support for uploading a cert for experimental audit logging cert. Pre cloud implementation in the backend * Forgot to add new hook * Add support for setting custom audit log certifcates in Cloud * Permissions * I18n * Change order * Linter fixes * Linter fixes, add openapi spec * additions for openapi * More openapi fixes because it won't run locally * Undo, cursor went rogue * newline fix * Align types properly * Fix i18n * Fix i18n AGAIN * Fix error * Update api/v4/source/audit_logging.yaml --------- Co-authored-by: Harrison Healey <[email protected]> Co-authored-by: Mattermost Build <[email protected]> |
||
|
|
63a438bff6 | [CLD-8961] Fix typo in trial license error message (#30681) | ||
|
|
cb2b27d82d | Make trial form modal-body scrollable for small vertical screens (#30682) | ||
|
|
9a9b23b138 |
Add company_country to trial license fetch (#30471)
Automatic Merge |
||
|
|
ee9dc7da12 |
[MM-62669] Updates to cloud specific imagery in system console (#29963)
* Updates to cloud specific imagery in system console * Revert something from images * Fix linter * Updates from PR feedback * Fix lint * Add svg * Lint fixes, update another SVG * change to pre-existing already-themed version of svg * change the folder of the file * add file * Adjust styling |
||
|
|
8512e0dfbb | Remove write_restrictable from AdvancedLoggingJSON (#29424) | ||
|
|
d2691aef8a |
remove Stripe CSP from server (#29306)
* remove Stripe CSP from server * Update tests * Fix more tests --------- Co-authored-by: Mattermost Build <[email protected]> |
||
|
|
9f7f418779 |
[CLD-8480] Remove duplicate 'Contact Sales' link in pricing modal card (#28899)
* Remove duplicate 'Contact Sales' link in pricing modal card * Fix lint * Revert package-lock to master |
||
|
|
96d24ba07d |
[CLD-8377] Add ability to open invitation modal from a query parameter (#28315)
* Add query_param_action_controller, allowing actions to be performed based on query parameters when webapp is loaded * Actually git add the new component * undo changes to package-lock * Change render to renderWithContext * Move into channel_controller * Fix tests * Updates to RootRedirect component and redirectUserToDefaultTeam * Grab another entry point * Adjust font for title of no permissions modal, fix default text * Fix linter --------- Co-authored-by: Mattermost Build <[email protected]> |
||
|
|
1c9ca9cd09 | Update download app link in Cloud welcome email (#28123) | ||
|
|
15a48e0a5a |
[CLD-8304] Return 501 if not a cloud license accessing IP Filtering (#28093)
* Return 501 if not a cloud license accessing IP Filtering * Changes for PR feedback |
||
|
|
23b77b8b0d |
[CLD-8131] Convert Subscription History Reporting to a Job (#27800)
* Remove CloudFreeDeprecated feature flag * Fixes for CI pipelines * Remove CloudReverseTrial feature flag and accompanying code (#27676) Co-authored-by: Mattermost Build <[email protected]> * Stashing * Convert subscription history reporting into a daily job * Update comments * Fix pipeline, redundant varaible declaration removed * Add debug logs for start/finish --------- Co-authored-by: Mattermost Build <[email protected]> |
||
|
|
3c41200bf1 |
[CLD-6870] Remove CloudFreeDeprecated feature flag (#27675)
* Remove CloudFreeDeprecated feature flag * Fixes for CI pipelines * Remove CloudReverseTrial feature flag and accompanying code (#27676) Co-authored-by: Mattermost Build <[email protected]> --------- Co-authored-by: Mattermost Build <[email protected]> |