1289 Commits
Author SHA1 Message Date
Juan Denis 7a3806c9dc Merge pull request #71 from jhd3197/dev
Kubernetes + tramo-powered Automations, and a Marketplace glow-up
v1.7.33
2026-07-12 06:44:36 -04:00
github-actions[bot] 5e13aee826 chore: bump version to 1.7.33 [skip ci] 2026-07-12 10:14:55 +00:00
Juan DenisandClaude Opus 4.8 f909103656 Add per-row busy state to Marketplace plugin actions
Track the in-flight plugin id/action so uninstall/update/enable/disable can't be double-fired and each row shows live progress; await loadExtensions() before clearing busy. Includes matching tramo editor and workflow_store tweaks (source + live copies) and tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 06:14:45 -04:00
Juan DenisandClaude Opus 4.8 89af823b39 docs: use new poster as README banner and update tagline
Replace the logo image at the top of the English and translated READMEs with the new docs/screenshots/poster.png banner, and change the tagline to "Deploy, manage, and monitor servers." (translated per language).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 06:14:37 -04:00
github-actions[bot] 10f7c71b93 chore: bump version to 1.7.32 [skip ci] 2026-07-12 08:16:17 +00:00
Juan Denis 6bae6a7a1c Align K8s page with tabgroup layout
Updated both K8sPage copies to use the full-bleed `sk-tabgroup` page shell and content wrappers, including the loading state. This moves warning/empty/main tab content into `sk-tabgroup__content`/`__inner` for consistent spacing and tabbed-page structure, and removes the extra topbar meta text to match the new header pattern.
2026-07-12 04:16:15 -04:00
Juan DenisandClaude Opus 4.8 128143760d chore: sync builtin-extension frontend artifacts (fix CI drift)
Regenerate frontend/src/plugins/<slug>/plugin.json from source via
scripts/sync-builtin-frontends.mjs. Resolves the drift check: k8s was a
missing trailing newline; tramo/wordpress/cloudflare-ops/gpu are the new
featured/feature_score fields normalized to canonical form.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 03:16:28 -04:00
github-actions[bot] feacf23349 chore: bump version to 1.7.31 [skip ci] 2026-07-12 07:07:10 +00:00
Juan Denis ff8721d58e Merge branch 'dev' of https://github.com/jhd3197/ServerKit into dev 2026-07-12 03:06:32 -04:00
Juan Denis 053d987721 Add Kubernetes plugin backend and manifest entry
Introduces the new `serverkit-k8s` backend plugin with full extension wiring: plugin metadata, model registration, lifecycle hooks, kubectl execution service, cluster CRUD/default handling, connectivity checks, normalized read endpoints (nodes/namespaces/workloads/pods/services/ingresses/logs/overview), and admin mutations (scale/restart/delete/apply). It also registers the plugin in the frontend plugins manifest (including plugin styles) so the Kubernetes page can be surfaced by the plugin system.
2026-07-12 03:06:16 -04:00
Juan DenisandClaude Opus 4.8 4fa318fa8b feat(marketplace): curated featured top-5 + k8s/wordpress covers
- Featured order: Faro (100), Automations (90), WordPress (80),
  Cloudflare Zone Ops (70), GPU Monitor (60). Scores set in each bundled
  extension's manifest (both copies); Faro's lives in the registry index.
- Add illustrated covers for Kubernetes and WordPress (extension-icons +
  resolver rules) so they stop falling back to generic category glyphs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 03:01:33 -04:00
Juan DenisandClaude Opus 4.8 76a2788d24 refactor(ui): rename Marketplace to Extensions
"Marketplace" reads as a store; the page is where you browse and install
extensions, so call it Extensions.

- Nav label + page/tab title + route /marketplace -> /extensions
  (first tab drives the topbar title via TabGroupLayout).
- /marketplace and /marketplace/installed now redirect to /extensions.
- Update command palette, page-context map, NotFound, empty-state copy.
- Keep the internal nav id, CSS classes, component/file names, and the
  backend /api/v1/marketplace/registry endpoints unchanged; palette keeps
  "marketplace" as a search keyword so the old term still finds it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 02:37:17 -04:00
Juan DenisandClaude Opus 4.8 161271dc5d fix(marketplace): surface registry featured flag; distinct mail icons
- registry_service: keep featured/feature_score through normalization so
  registry (bundled:false) extensions like Faro actually float to the top
  and show the Featured ribbon (they were being stripped).
- ExtensionIcons: give the Postfix/Dovecot "Email Server" the envelope and
  the Stalwart "Mail Server" the server-rack icon so they stop looking like
  duplicates ('email' matched before the bare 'mail' rule).
- Drop Faro's logo override so it uses its full-bleed illustrated cover
  (92px) instead of the 44px brand-logo slot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 02:27:57 -04:00
Juan DenisandClaude Opus 4.8 050ae99390 chore(marketplace): bump Faro fallback entry to v1.0.2
Match the published serverkit-faro v1.0.2 release (lean zip) in the
offline registry fallback.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 02:19:12 -04:00
Juan DenisandClaude Opus 4.8 30fbdb3bf8 feat(marketplace): feature Faro + Cloudflare Zone Ops, add Faro cover
- Add Faro illustrated cover (extension-icons/faro.png) + resolver rule so
  serverkit-faro shows a 3D lighthouse instead of a flat glyph.
- Mark Cloudflare Zone Ops featured (score 95) in both plugin.json copies.
- Add a wordpress.detail.panel PluginSlot so the Faro (and future WP)
  extensions can render on WordPress site pages.
- Sync the registry offline fallback with the Faro v1.0.1 entry (featured).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 02:09:31 -04:00
github-actions[bot] 1384a3e5bb chore: bump version to 1.7.30 [skip ci] 2026-07-12 04:27:53 +00:00
Juan DenisandClaude Opus 4.8 0ed76e1d7c feat(tramo): add serverkit-tramo Automations plugin backend
Node-based automation builder powered by the tramo engine, embedded as an
opt-in builtin plugin (Automations, /automations). Panel is system of record
for workflow docs; a managed @tramo/server Docker container on the host runs
them headless with run history, approvals, and inbound webhooks proxied
through the panel. Replaces the older Workflow Builder.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 00:27:41 -04:00
Juan DenisandClaude Opus 4.8 475c492d19 feat(marketplace): featured Automations with illustrated icon
- Add an illustrated 3D cover icon for the Automations extension
  (assets/extension-icons/automations.png, transparent bg, 256px) and map
  tramo/automation to it in the extension icon resolver.
- Add manifest 'featured' + 'feature_score' (Automations = featured, score 100).
- Sort featured extensions to the top of the Marketplace by score (score is
  hidden; used only for ordering) and show a gold 'Featured' ribbon on the
  cover + a subtle featured border.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 00:21:42 -04:00
Juan DenisandClaude Opus 4.8 483f1fa4c0 feat(automations): side-nav Settings layout (like core/WordPress settings)
Replace the single long scroll of stacked cards with the core settings-layout:
a left sub-nav (Engine / Events & port / Pack secrets) and a content pane that
shows only the selected section. Reuses the global .settings-layout/.settings-nav
classes so it matches core Settings and WordPress. Drops the redundant per-card
Refresh (the topbar Refresh covers it).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 00:10:19 -04:00
Juan DenisandClaude Opus 4.8 5fce53f779 feat(automations): Templates marketplace tab (search, favorites, import)
Promote 'New from template' from a popup to its own Templates tab, built to grow
like a marketplace:
- Responsive card grid (icon, name, description, integration tags) with a
  'Use template' action per card.
- Search box to filter.
- Per-card favorite star; favorites persist in localStorage and float to the
  top (server-side store can replace this later without UI changes).
- 'Import template' action: paste a tramo workflow JSON or load a .json file to
  create it as a new automation.
Removes the old modal picker and its topbar button.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 00:01:03 -04:00
Juan DenisandClaude Opus 4.8 049235b12d feat(automations): two-column New automation dialog with trigger picker
Replace the name-only New workflow modal with a two-column dialog: an explainer
panel (badge, mini flow diagram, use-case examples) on the left and, on the
right, the name field plus a 'How should it start?' trigger picker. Choices seed
a valid builtin trigger node (manual / cron / panel-event via webhook on
/sk/events / incoming webhook) so the editor opens with the trigger already
placed. Own copy/wording; collapses to a single column on narrow screens.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 23:51:19 -04:00
Juan DenisandClaude Opus 4.8 f4b8630e3b feat(automations): richer template picker
Replace the three plain text rows with proper cards: a brand-tinted icon tile
(Telegram/GitHub/Discord/generic), bold name, muted description, integration
tags, and a hover chevron. Wider modal (size lg) with an intro line, and the
Close button moves to the modal footer slot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 23:42:56 -04:00
Juan DenisandClaude Opus 4.8 6f4246bf0e fix(automations): un-nest template-picker styles from .tramo-page
The 'New from template' picker renders inside a <Modal>, which portals to
<body> -- outside the .tramo-page subtree -- so the .tramo-template rules
nested under .tramo-page never matched it. The name/description spans fell back
to inline defaults and ran together. Move .tramo-template-list/.tramo-template
to top-level scope so the portaled modal picks them up (name bold on its own
line, muted description below).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 23:33:25 -04:00
Juan DenisandClaude Opus 4.8 52ea07426f fix(automations): center content in sk-tabgroup__inner (match WordPress)
Add the .sk-tabgroup__inner wrapper WordPress/Domains use inside
.sk-tabgroup__content so the content is padded + max-width centered under the
full-bleed header, instead of sitting edge-to-edge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 23:23:09 -04:00
Juan DenisandClaude Opus 4.8 801fe3bbf6 fix(automations): full-bleed tab-group header to match WordPress/Domains
The topbar was rendered inside a plain padded page-container, so it floated
inset with no header band. Switch the wrapper to the same classes TabGroupLayout
uses for WordPress/Domains -- 'page-container--full-bleed sk-tabgroup' with the
content in 'sk-tabgroup__content' -- so Automations gets the identical
full-width header strip (bordered band, icon+title+tabs+actions) over centered
content.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 23:20:08 -04:00
Juan DenisandClaude Opus 4.8 18a8248fc1 fix(automations): match the clean Domains/WordPress header layout
Drop the '<icon> tramo . workflows . triggers . integrations' topbar subtext
and the redundant inner card-header on the Workflows/Runs tabs. Actions
(Deploy, New from template, New workflow, Refresh) now live in the PageTopbar
and are contextual to the active tab, so each tab shows a single clean header
over its content -- the same pattern as Domains and WordPress.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 23:13:23 -04:00
Juan DenisandClaude Opus 4.8 bd8842faf4 fix(routing): show a Not Found page for unknown/uninstalled-extension routes
Navigating straight to an extension route whose extension isn't installed
(or any unknown URL) rendered a blank page -- the route was never registered
and there was no catch-all. Add a catch-all '*' route inside the dashboard
shell that renders a NotFound page (icon, the missing path, links to the
dashboard + Marketplace).

Contributed routes load async, so on a hard refresh onto an installed
extension route the catch-all can mount for a beat before the route
registers; NotFound keys off a new contributions __ready flag to show a
loading skeleton until the route set is known, avoiding a 'Not found' flash.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 23:06:03 -04:00
Juan DenisandClaude Opus 4.8 4f448de660 docs(automations): changelog + raise test-count baseline to 2588
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 22:39:56 -04:00
Juan DenisandClaude Opus 4.8 e62d969a8b feat(automations): retire React-Flow Workflow Builder UI (Phase 4 frontend)
The Automations extension (tramo) replaces the drag-and-drop builder.

- Delete builtin-extensions/serverkit-workflows + its mirror, pages/
  WorkflowBuilder.jsx, and all of components/workflow/ (its @xyflow nodes,
  edges, and config panels).
- KEEP @xyflow/react (vendor-flow chunk): pages/AppMap.jsx still uses it.
- Redirect /workflow -> /automations in App.jsx (retired-route pattern).
- Drop the pages/_workflow SCSS partial + its main.scss import.
- Refresh the stale serverkit-workflows comments in DashboardLayout +
  sidebarItems to point at the Automations extension.

Build + lint clean; sync-builtin-frontends --check green (14 managed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 22:27:20 -04:00
Juan DenisandClaude Opus 4.8 8eaf13f2ed build(frontend): add tramo@^0.1.0 dependency for Automations editor
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 22:24:31 -04:00
Juan DenisandClaude Opus 4.8 79be6e082d test(automations): tramo extension suite + host/model refinements
- test_tramo_extension.py: 40 tests (manifest, models+purge, workflow store
  CRUD/materialize/deploy, host argv/control/status/nt-guard, run_sync,
  jobs harvest+health, events bridge + call-back key, blueprint auth/run
  proxy/settings mask/auth-exempt hooks passthrough, Phase 4 ported emitters +
  legacy export + old routes gone).
- host_service: add _is_windows() seam (test platform without touching global
  os.name, which would break pathlib).
- models: dirty detection via deployed_version counter (race-free vs the
  deploy commit's own updated_at onupdate bump).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 22:23:53 -04:00
Juan DenisandClaude Opus 4.8 531fdf3d42 refactor(automations): retire Workflow Builder engine, port emitters (Phase 4 backend)
The React-Flow Workflow Builder is replaced by the Automations extension
(tramo). Remove its core Python engine and port its four event emitters to
the panel event bus so tramo workflows can trigger on them via the events
bridge.

- event_service.py: new EVENT_CATALOG entries health.check_failed, git.push,
  monitor.high_cpu, monitor.high_memory.
- docker_service.py: drop the app_stopped emit (app.stopped already fires via
  the audit trail -- no double-emit).
- environment_health_service/git_service/monitoring_service: emit the new
  panel events via EventService instead of WorkflowEventBus.
- Delete app/api/workflows.py, app/services/workflow_engine.py,
  app/services/workflow_service.py; drop the blueprint + startup job
  registration; neutralize the cron workflow-scheduler handler to a no-op.
- KEEP app/models/workflow.py + its tables (read-only legacy export lives in
  the tramo blueprint; table drop is a future cleanup).
- Remove the two workflow-engine test classes from test_jobs.py.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 22:15:10 -04:00
Juan DenisandClaude Opus 4.8 675543541b feat(automations): starter workflow templates (Phase 3)
Three seed WorkflowDocs (backup-failed->Telegram, nightly health->GitHub
issue, panel event->Discord) served at GET /tramo/templates, plus
POST /tramo/workflows/from-template/<id> to instantiate one.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 22:09:10 -04:00
Juan DenisandClaude Opus 4.8 38c1e33097 feat(automations): serverkit-tramo extension backend (Phase 1)
Embed tramo as the panel's automation surface. Managed @tramo/server
container is the executor; the panel owns workflow docs.

- plugin.json: opt-in builtin, /api/v1/tramo, Automations nav -> /automations,
  harvest+health schedules, ext_serverkit_tramo_* models.
- models.py: TramoWorkflow (doc/slug/enabled/dirty) + TramoRun (harvested).
- host_service.py: TramoHostService, stalwart_service mirror -- _docker/_api
  choke-points, loopback API, encrypted Bearer key + pack secrets in config.
- workflow_store.py: CRUD + materialize enabled docs + deploy (restart).
- run_sync.py: defensive run parser + upsert-by-run_id.
- events_bridge.py: scoped call-back ApiKey + managed EventSubscription.
- lifecycle.py / jobs.py: install/uninstall hooks, harvest + health jobs.
- tramo.py: JWT blueprint (workflows/runs/approvals/host/settings) + one
  auth-exempt /hooks/<path> inbound-webhook passthrough + legacy export.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 22:04:12 -04:00
Juan Denis 570a3c7152 Merge branch 'dev' of https://github.com/jhd3197/ServerKit into dev 2026-07-11 21:49:33 -04:00
Juan DenisandClaude Opus 4.8 bde4647fdc feat(k8s): serverkit-k8s extension — manage remote clusters via kubectl
Opt-in builtin extension. Add a cluster by pasting its kubeconfig (stored
encrypted, one row per cluster); the engine shells out to kubectl against a
per-call temp kubeconfig to show cluster health, nodes, namespaces, workloads,
pods with live logs, services, and ingresses, plus scale/restart/delete and
apply-from-paste. Reads need viewer, mutations need admin. Not platform-gated
(kubectl runs anywhere); no cluster needed on the panel host.

Backend: models (ext_serverkit_k8s_clusters), kubectl_service (argv build +
temp-file materialize/cleanup), cluster_service (CRUD + normalizers), k8s
blueprint (/api/v1/k8s), lifecycle. Frontend: K8sPage (7 tabs) mirrored to the
baked plugin tree via sync-builtin-frontends. 30 extension tests green;
manifest/platform suites green; frontend builds; sync-drift clean.

Plan: docs/plans/44_KUBERNETES_EXTENSION_PLAN.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 03:41:34 -04:00
Juan Denis 34a84e2731 Merge pull request #69 from jhd3197/dev
Palette omnisearch, one-click GitHub, New Service wizard
v1.7.29
2026-07-11 01:57:43 -04:00
github-actions[bot] dc575542f9 chore: bump version to 1.7.29 [skip ci] 2026-07-11 05:34:27 +00:00
Juan DenisandClaude Fable 5 1face0702f fix(cli): wrapper delegates forward flags verbatim to cli.py
Live test on the dev box caught 'serverkit list-apps --json' printing
the table: cmd_list_apps' hand-rolled flag mapping dropped everything
but --all, and cmd_list_users/cmd_list_servers dropped all args. All
three now forward "$@" (with -a kept as the legacy --all alias), and
test_cli.sh T20 drives the real executed-mode dispatch through a fake
venv with a recording python stub so any wrapper verb that eats flags
fails the suite.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 01:34:12 -04:00
github-actions[bot] be83e38c51 chore: bump version to 1.7.28 [skip ci] 2026-07-11 05:25:00 +00:00
Juan Denis cb30b93d6f Merge branch 'dev' of https://github.com/jhd3197/ServerKit into dev 2026-07-11 01:24:43 -04:00
Juan DenisandClaude Fable 5 ad73f0c581 fix(cli): wrapper parity with backend/cli.py + bash tab-completion
serverkit migrate-db forwarded the wrapper's own name to cli.py, which
only defines db-migrate — the command has failed with 'No such command'
since the rename. Fix the forward and stop the drift class entirely:

- cmd_panel_cli forwards Click-only verbs verbatim (manifest, services,
  apps, repair, login-url, support-bundle, db-migrate/status/history;
  panel-status/panel-doctor where a native bash name collides)
- serverkit completion prints a bash completion script; install.sh and
  update.sh drop it into /etc/bash_completion.d (best-effort), the
  uninstall lib removes it
- test_cli.sh T17-T19: migrate-db forwarding, dispatch reachability,
  and a two-way parity guard (cli.py verbs <-> dispatch <-> completion);
  test_update.sh T29 covers refresh_bash_completion

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 01:23:00 -04:00
Juan DenisandClaude Fable 5 9be1ebf8bb feat(cli): --json output on read-only admin CLI verbs
status, doctor, list-users, list-apps, list-servers, db-status,
deployment-status, services list, apps list, and manifest plan gain a
--json flag emitting machine-readable output, so the CLI can feed
scripts, cron checks, and external monitors. Table-only extras refuse
the combination loudly (--all, --repair).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 01:22:49 -04:00
Juan DenisandClaude Opus 4.8 d482c6d261 feat(email): commit serverkit-email extension backend
The Email Server builtin extension's backend package was present on disk (and
exercised by the green test suite) but never tracked. Adds it alongside the
already-tracked serverkit-gpu / serverkit-gui backend plugins: the Flask
blueprint (email.py) plus the Postfix/Dovecot/DKIM/SpamAssassin/Roundcube
service modules. __pycache__ stays gitignored.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 01:10:30 -04:00
github-actions[bot] 620fdb992a chore: bump version to 1.7.27 [skip ci] 2026-07-11 04:54:20 +00:00
Juan DenisandClaude Opus 4.8 e674a6b6d2 chore(deps): apply frontend security bumps (dependabot #62-67)
Clears the frontend Dependabot security alerts, minus the vite chain:

- react-router-dom ^6.22.3 -> ^7.18.1 (direct; fixes the // open-redirect,
  alert #17). v7 keeps the react-router-dom API surface — lint + build green.
- overrides pin the transitive fixes: lodash 4.18.1 (prototype pollution +
  _.template code injection), js-yaml 4.3.0 (merge-key DoS), postcss 8.5.16
  (stringify XSS), @babel/core 7.29.7 (sourceMappingURL file read), ws 8.21.0
  (memory-exhaustion DoS + uninitialized memory), engine.io-client 6.6.6.
- npm audit fix cleared the remaining non-breaking transitive alerts
  (flatted, minimatch, brace-expansion, ajv).

Down from 8 to 2 npm-audit findings; the remaining two (esbuild + rollup via
vite, both dev-server-only) need the vite 5->8 major upgrade, tracked
separately as #68.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 00:43:43 -04:00
Juan DenisandClaude Opus 4.8 2dfe0d7d54 feat(search): unified entity omnisearch endpoint for the palette
GET /api/v1/search?q= (JWT, 2-char minimum) fans a term out across the core
entity types — services, servers, domains, databases, WordPress sites, cron
jobs (admin-only), installed extensions, and vaults (names only, never secret
values) — reusing each domain's existing access helpers so a member only sees
what their grants allow. Per-type cap of 5; each entity block is isolated so one
failing type degrades gracefully instead of 500-ing the search.

Wires the frontend api.search() async provider (200ms debounce) into the
palette's entity group, replacing the fetch-everything-on-open prefetch. Adds
tests/test_search.py covering shape, min-length, cap, member-vs-admin filtering,
cron admin-only, and the vaults names-only rule.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 00:26:40 -04:00
Juan DenisandClaude Opus 4.8 86bd8d70a9 feat(palette): wrap settings cards for deep-link focus across all tabs
Mechanical wrap-the-card pass: each remaining settings tab component now spreads
useSettingFocus's register(id, class) onto its identifiable cards so a palette
settings result scrolls to and flashes the exact card. Covers Profile,
Appearance, Sidebar, White Label, About, Users, Activity, Site, Modules,
Migrations, SSO, API, AI, System, and Connections. Cards whose roots live in
non-editable subcomponents (login links, invitations, provider cards) register
at the nearest reachable section or fall back to landing on the tab.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 23:47:36 -04:00
Juan DenisandClaude Opus 4.8 e0a47bbb9d feat(palette): settings search — deep-link focus + completeness guard
useSettingFocus rides the useFocusParam rail with a new `setting` kind: a
palette result navigates to /settings/<tab>?focus=setting:<id>, and the target
card scrolls into view and flashes a token-based highlight for ~2s. Wires the
headline Security (2FA card + admin require-2FA policy, now mounted) and
Notifications (email/SMTP, channels, severity, categories, quiet hours) cards.

Adds scripts/check-settings-index.mjs (dependency-free) to the lint step so
every settings tab must carry at least one index entry — a new tab can't ship
invisible to search.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 23:42:57 -04:00
Juan DenisandClaude Opus 4.8 3e0fbd2f81 feat(palette): omnisearch core — providers, ranking, VS Code keys
Rebuild CommandPalette around scored providers (pages, settings, actions,
plugin contributions, docs, async entities) with a single subsequence fuzzy
scorer and shouldFilter={false} so cmdk no longer double-filters. Adds:

- data/palettePages.js, data/settingsIndex.js (84 cards), data/commandActions.js
- utils/paletteScore.js (word-start bonus + category weight) and
  utils/paletteFrecency.js (localStorage frecency: count + time decay)
- hooks/usePaletteAuthz.js — mirrors the sidebar's admin + workspace-nav gate
  so a member's palette never surfaces admin surface
- F1 and Ctrl/Cmd+Shift+P open aliases alongside Ctrl/Cmd+K
- prefix modes (`>` actions, `?` docs), Recently used empty state, kbd footer

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 23:31:25 -04:00