@@ -18,43 +18,113 @@ This separation ensures the platform remains lightweight and un-opinionated, all
1818
1919## 2. Anatomy of a Plugin
2020
21- A plugin is defined by its ` Manifest ` (objectstack.config.ts). The most critical part of a modern ObjectStack plugin is the ` contributes ` section .
21+ A plugin is defined by its ` Manifest ` (objectstack.config.ts) and its runtime ` Entry ` (index.ts) .
2222
23- ### The ` contributes ` Protocol
23+ ### The Manifest ( ` objectstack.config.ts ` )
2424
25- Inspired by VS Code, we use a declarative approach to register capabilities .
25+ Critically, the manifest declares ** Dependencies ** , ** Configuration Rules ** , and ** Contributions ** .
2626
2727``` typescript
2828// objectstack.config.ts
29- export default {
29+ import { ObjectStackManifest } from ' @objectstack/spec' ;
30+
31+ const plugin: ObjectStackManifest = {
3032 id: ' com.vendor.bi' ,
33+ version: ' 1.0.0' ,
3134 type: ' plugin' ,
3235
33- // DECLARATIVE: "I bring these new capabilities"
36+ // 1. Configuration Schema (Settings)
37+ configuration: {
38+ title: ' BI Engine Settings' ,
39+ properties: {
40+ ' fullQueryMode' : {
41+ type: ' boolean' ,
42+ default: false ,
43+ description: ' Allow unrestricted SQL queries'
44+ },
45+ ' apiKey' : {
46+ type: ' string' ,
47+ secret: true
48+ }
49+ }
50+ },
51+
52+ // 2. Dependencies
53+ dependencies: {
54+ ' com.objectstack.core' : ' ^2.0.0'
55+ },
56+
57+ // 3. Contributions (Declarative Capabilities)
3458 contributes: {
35- // 1. Define new Metadata Kinds (File Types)
59+ // Define new Metadata Kinds (File Types)
3660 kinds: [
3761 {
3862 id: ' bi.dataset' ,
3963 globs: [' **/*.dataset.json' ],
40- description: ' BI Dataset Definition'
64+ description: ' BI Dataset Definition'
4165 }
4266 ],
43- // 2. Define new UI Locations
44- views: [
45- {
46- id: ' bi.chart_renderer' ,
47- location: ' dashboard.widget'
67+ // UI Contributions
68+ menus: {
69+ ' global/toolbar' : [
70+ { id: ' open_dashboard' , label: ' Open BI Dashboard' , command: ' bi.open' }
71+ ]
72+ },
73+ // Server Actions (Exposed to Flows/API)
74+ actions: [
75+ {
76+ name: ' generate_forecast' ,
77+ label: ' Generate Sales Forecast' ,
78+ input: { startDate: ' date' }
4879 }
4980 ]
5081 },
5182
52- // IMPERATIVE: "Here is the code to handle them"
53- lifecycle: ' ./src/index.ts'
83+ // 4. Runtime Entry
84+ extensions: {
85+ runtime: { entry: ' ./src/index.ts' }
86+ }
87+ }
88+ ```
89+
90+ ## 3. Runtime Context
91+
92+ Plugins receive a rich strictly-typed ` PluginContext ` during their lifecycle. This context is the bridge to the host operating system.
93+
94+ ``` typescript
95+ // src/index.ts
96+ import { PluginDefinition , PluginContextData } from ' @objectstack/spec' ;
97+
98+ const definition: PluginDefinition = {
99+ id: ' com.vendor.bi' ,
100+
101+ onEnable : async (context : PluginContextData ) => {
102+ // A. Access Type-Safe Context
103+ const { logger, ql, os, app, storage, i18n } = context ;
104+
105+ logger .info (' Starting BI Engine...' );
106+
107+ // B. Use Scoped Storage (KV Store)
108+ const lastRun = await storage .get (' last_run_timestamp' );
109+
110+ // C. Register Runtime Routes
111+ app .router .get (' /bi/stats' , async () => {
112+ return { active_reports: 10 };
113+ });
114+
115+ // D. Interact with Core Data
116+ const data = await ql .object (' account' ).find ({ industry: ' Tech' });
117+
118+ // E. Read Configuration
119+ const config = await os .getConfig (' com.vendor.bi' );
120+ if (config .fullQueryMode ) {
121+ logger .warn (' Running in Full Query Mode' );
122+ }
123+ }
54124}
55125```
56126
57- ## 3 . Extension Capabilities
127+ ## 4 . Extension Capabilities
58128
59129### A. New Metadata Kinds (CRDs)
60130
0 commit comments