Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 8
Add plugin-setup to own the platform Setup App#998
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| # @objectstack/plugin-setup | ||
| ## 3.3.1 | ||
| ### Added | ||
| - Initial release of the Setup Plugin. | ||
| - Defines the platform Setup App identity (name, label, icon, permissions, branding). | ||
| - Ships 4 built-in Setup Areas: Administration, Platform, System, AI. | ||
| - Provides `setupNav` service for contribution-based navigation composition. | ||
| - Auto-filters empty areas and supports custom area extensions. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| # @objectstack/plugin-setup | ||
| Setup Plugin for ObjectStack — owns and composes the platform **Setup App** with area-based navigation. | ||
| ## Overview | ||
| The Setup App is the central administration interface of the ObjectStack platform (equivalent to Salesforce Setup or ServiceNow System Administration). Rather than scattering setup definitions across `spec` and `objectql`, this plugin provides clear ownership: | ||
| - **Spec** → protocol schemas only | ||
| - **ObjectQL** → data engine only | ||
| - **plugin-setup** → owns the Setup App identity, areas, and navigation composition | ||
| ## Features | ||
| - **Four Built-in Areas**: Administration, Platform, System, and AI — shipped as empty skeletons. | ||
| - **Contribution Model**: Any plugin can contribute navigation items to Setup areas via the `setupNav` service. | ||
| - **Area Filtering**: Empty areas are automatically filtered out at finalization. | ||
| - **Custom Areas**: Plugins can contribute to custom area IDs beyond the four built-in ones. | ||
| - **I18n Labels**: All labels use the `I18nLabel` union type for internationalization. | ||
| ## Usage | ||
| ### Register the Plugin | ||
| ```typescript | ||
| import { ObjectKernel } from '@objectstack/core'; | ||
| import { SetupPlugin } from '@objectstack/plugin-setup'; | ||
| const kernel = new ObjectKernel({ | ||
| plugins: [ | ||
| new SetupPlugin(), | ||
| // ... other plugins | ||
| ], | ||
| }); | ||
| ``` | ||
| ### Contribute Navigation from Another Plugin | ||
| ```typescript | ||
| import type { Plugin, PluginContext } from '@objectstack/core'; | ||
| import type { SetupNavService } from '@objectstack/plugin-setup'; | ||
| import { SETUP_AREA_IDS } from '@objectstack/plugin-setup'; | ||
| export class MyPlugin implements Plugin { | ||
| name = 'com.example.my-plugin'; | ||
| async init(ctx: PluginContext) { | ||
| const setupNav = ctx.getService<SetupNavService>('setupNav'); | ||
| setupNav.contribute({ | ||
| areaId: SETUP_AREA_IDS.administration, | ||
| items: [ | ||
| { id: 'nav_users', type: 'object', label: 'Users', objectName: 'sys_user' }, | ||
| { id: 'nav_roles', type: 'object', label: 'Roles', objectName: 'sys_role' }, | ||
| ], | ||
| }); | ||
| } | ||
| } | ||
| ``` | ||
| ### Exported Components | ||
| ```typescript | ||
| import { | ||
| SetupPlugin, | ||
| type SetupNavService, | ||
| SETUP_APP_DEFAULTS, | ||
| type SetupNavContribution, | ||
| SETUP_AREAS, | ||
| SETUP_AREA_IDS, | ||
| type SetupAreaId, | ||
| } from '@objectstack/plugin-setup'; | ||
| ``` | ||
| ## Built-in Setup Areas | ||
| | Area | ID | Icon | Order | Description | | ||
| |:-----|:---|:-----|:-----:|:------------| | ||
| | Administration | `area_administration` | shield | 10 | Users, roles, permissions, security | | ||
| | Platform | `area_platform` | layers | 20 | Objects, fields, layouts, automation | | ||
| | System | `area_system` | settings | 30 | Datasources, integrations, jobs, logs | | ||
| | AI | `area_ai` | brain | 40 | Agents, models, RAG pipelines | | ||
| ## Architecture | ||
| ``` | ||
| ┌──────────────────────────────────────────┐ | ||
| │ SetupPlugin │ | ||
| │ │ | ||
| │ init(): │ | ||
| │ → registers 'setupNav' service │ | ||
| │ │ | ||
| │ start(): │ | ||
| │ → collects contributions │ | ||
| │ → merges into area skeletons │ | ||
| │ → filters empty areas │ | ||
| │ → registers finalized Setup App │ | ||
| │ │ | ||
| └──────────────────────────────────────────┘ | ||
| ▲ ▲ | ||
| │ contribute() │ contribute() | ||
| ┌────┴────┐ ┌────┴────┐ | ||
| │ plugin │ │ plugin │ | ||
| │ auth │ │security │ | ||
| └─────────┘ └─────────┘ | ||
| ``` | ||
| ## License | ||
| Apache-2.0 © ObjectStack |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license. | ||
| import { defineStack } from '@objectstack/spec'; | ||
| /** | ||
| * ObjectStack Configuration for plugin-setup | ||
| * | ||
| * This configuration defines the manifest for the platform Setup plugin. | ||
| * The Setup App itself is composed at runtime by collecting setupNav | ||
| * contributions from all registered plugins. | ||
| */ | ||
| export default defineStack({ | ||
| manifest: { | ||
| id: 'com.objectstack.plugin-setup', | ||
| namespace: 'setup', | ||
| version: '3.3.1', | ||
| type: 'plugin', | ||
| name: 'Platform Setup Plugin', | ||
| description: 'Owns and composes the platform Setup App with area-based navigation contributed by other plugins', | ||
| }, | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| { | ||
| "name": "@objectstack/plugin-setup", | ||
| "version": "3.3.1", | ||
| "license": "Apache-2.0", | ||
| "description": "Setup Plugin for ObjectStack — Platform Setup App with area-based navigation composition", | ||
| "main": "dist/index.js", | ||
| "types": "dist/index.d.ts", | ||
| "exports": { | ||
| ".": { | ||
| "types": "./dist/index.d.ts", | ||
| "import": "./dist/index.mjs", | ||
| "require": "./dist/index.js" | ||
| } | ||
| }, | ||
| "scripts": { | ||
| "build": "tsup --config ../../../tsup.config.ts", | ||
| "test": "vitest run" | ||
| }, | ||
| "dependencies": { | ||
| "@objectstack/core": "workspace:*", | ||
| "@objectstack/spec": "workspace:*" | ||
| }, | ||
| "devDependencies": { | ||
| "@types/node": "^25.5.0", | ||
| "typescript": "^6.0.2", | ||
| "vitest": "^4.1.2" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license. | ||
| /** | ||
| * @objectstack/plugin-setup | ||
| * | ||
| * Setup Plugin for ObjectStack — owns and composes the platform Setup App. | ||
| * Other plugins contribute navigation items via the `setupNav` service. | ||
| */ | ||
| export { SetupPlugin, type SetupNavService } from './setup-plugin.js'; | ||
| export { SETUP_APP_DEFAULTS, type SetupNavContribution } from './setup-app.js'; | ||
| export { SETUP_AREAS, SETUP_AREA_IDS, type SetupAreaId } from './setup-areas.js'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license. | ||
| import type { App, NavigationArea, NavigationItem } from '@objectstack/spec/ui'; | ||
| /** | ||
| * Default Setup App definition. | ||
| * | ||
| * This is the base identity of the platform Setup application. | ||
| * At runtime the `SetupPlugin` clones this definition, injects | ||
| * the merged navigation areas contributed by other plugins, | ||
| * and registers the final app. | ||
| */ | ||
| export const SETUP_APP_DEFAULTS: Omit<App, 'areas'> & { areas: NavigationArea[] } = { | ||
| name: 'setup', | ||
| label: { | ||
| key: 'setup.app.label', | ||
| defaultValue: 'Setup', | ||
| }, | ||
| description: { | ||
| key: 'setup.app.description', | ||
| defaultValue: 'Platform settings and administration', | ||
| }, | ||
| icon: 'settings', | ||
| active: true, | ||
| isDefault: false, | ||
| branding: { | ||
| primaryColor: '#475569', // Slate-600 — neutral admin palette | ||
| }, | ||
| requiredPermissions: ['setup.access'], | ||
| areas: [], | ||
| }; | ||
Comment on lines
+13
to
+31
CopilotAI | ||
| /** | ||
| * Navigation contribution that a plugin registers via the | ||
| * `setupNav` service convention during kernel init. | ||
| * | ||
| * Each contribution targets a specific area by its ID and provides | ||
| * one or more navigation items (or groups) to merge into that area. | ||
| */ | ||
| export interface SetupNavContribution { | ||
| /** Target area ID (e.g. `area_administration`). */ | ||
| areaId: string; | ||
| /** Navigation items to contribute to the target area. */ | ||
| items: NavigationItem[]; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license. | ||
| import type { NavigationArea } from '@objectstack/spec/ui'; | ||
| /** | ||
| * Well-known Setup Area IDs. | ||
| * | ||
| * Every internal or third-party plugin that wants to contribute settings | ||
| * navigation uses one of these area IDs (or defines a custom one). | ||
| */ | ||
| export const SETUP_AREA_IDS = { | ||
| administration: 'area_administration', | ||
| platform: 'area_platform', | ||
| system: 'area_system', | ||
| ai: 'area_ai', | ||
| } as const; | ||
| export type SetupAreaId = (typeof SETUP_AREA_IDS)[keyof typeof SETUP_AREA_IDS]; | ||
| /** | ||
| * Built-in Setup Areas — empty skeletons. | ||
| * | ||
| * These are the four default areas that ship with the platform. | ||
| * Other plugins contribute navigation items into these areas | ||
| * via the `setupNav` service convention during kernel init. | ||
| * | ||
| * At finalization time, empty areas (no contributed navigation items) | ||
| * are automatically filtered out so the Setup App only shows | ||
| * areas that actually have content. | ||
| */ | ||
| export const SETUP_AREAS: readonly NavigationArea[] = [ | ||
| { | ||
| id: SETUP_AREA_IDS.administration, | ||
| label: { | ||
| key: 'setup.areas.administration', | ||
| defaultValue: 'Administration', | ||
| }, | ||
| icon: 'shield', | ||
| order: 10, | ||
| description: { | ||
| key: 'setup.areas.administration.description', | ||
| defaultValue: 'User management, roles, permissions, and security settings', | ||
| }, | ||
| navigation: [], | ||
| }, | ||
| { | ||
| id: SETUP_AREA_IDS.platform, | ||
| label: { | ||
| key: 'setup.areas.platform', | ||
| defaultValue: 'Platform', | ||
| }, | ||
| icon: 'layers', | ||
| order: 20, | ||
| description: { | ||
| key: 'setup.areas.platform.description', | ||
| defaultValue: 'Objects, fields, layouts, automation, and extensibility settings', | ||
| }, | ||
| navigation: [], | ||
| }, | ||
| { | ||
| id: SETUP_AREA_IDS.system, | ||
| label: { | ||
| key: 'setup.areas.system', | ||
| defaultValue: 'System', | ||
| }, | ||
| icon: 'settings', | ||
| order: 30, | ||
| description: { | ||
| key: 'setup.areas.system.description', | ||
| defaultValue: 'Datasources, integrations, jobs, logs, and environment configuration', | ||
| }, | ||
| navigation: [], | ||
| }, | ||
| { | ||
| id: SETUP_AREA_IDS.ai, | ||
| label: { | ||
| key: 'setup.areas.ai', | ||
| defaultValue: 'AI', | ||
| }, | ||
| icon: 'brain', | ||
| order: 40, | ||
| description: { | ||
| key: 'setup.areas.ai.description', | ||
| defaultValue: 'AI agents, model registry, RAG pipelines, and intelligence settings', | ||
| }, | ||
| navigation: [], | ||
| }, | ||
| ] as const; |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
CopilotAIMar 31, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This package changelog format diverges from the repo’s Changesets-generated package CHANGELOGs (e.g. other plugins use the standard "Patch/Minor Changes" sections and dependency bump lines). Since release automation uses Changesets (
pnpm run version/changeset version), this file is likely to be overwritten or become inconsistent. Consider generating/maintaining it via Changesets (and/or aligning the format with otherpackages/plugins/*/CHANGELOG.mdfiles).