@rimori/client 1.1.10 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +189 -63
- package/dist/cli/scripts/init/dev-registration.d.ts +35 -0
- package/dist/cli/scripts/init/dev-registration.js +174 -0
- package/dist/cli/scripts/init/env-setup.d.ts +9 -0
- package/dist/cli/scripts/init/env-setup.js +43 -0
- package/dist/cli/scripts/init/file-operations.d.ts +4 -0
- package/dist/cli/scripts/init/file-operations.js +51 -0
- package/dist/cli/scripts/init/html-cleaner.d.ts +4 -0
- package/dist/cli/scripts/init/html-cleaner.js +38 -0
- package/dist/cli/scripts/init/main.d.ts +2 -0
- package/dist/cli/scripts/init/main.js +160 -0
- package/dist/cli/scripts/init/package-setup.d.ts +32 -0
- package/dist/cli/scripts/init/package-setup.js +75 -0
- package/dist/cli/scripts/init/router-transformer.d.ts +6 -0
- package/dist/cli/scripts/init/router-transformer.js +254 -0
- package/dist/cli/scripts/init/tailwind-config.d.ts +4 -0
- package/dist/cli/scripts/init/tailwind-config.js +56 -0
- package/dist/cli/scripts/init/vite-config.d.ts +20 -0
- package/dist/cli/scripts/init/vite-config.js +54 -0
- package/dist/cli/scripts/release/release-config-upload.d.ts +7 -0
- package/dist/cli/scripts/release/release-config-upload.js +116 -0
- package/dist/cli/scripts/release/release-db-update.d.ts +6 -0
- package/dist/cli/scripts/release/release-db-update.js +100 -0
- package/dist/cli/scripts/release/release-file-upload.d.ts +6 -0
- package/dist/cli/scripts/release/release-file-upload.js +136 -0
- package/dist/cli/scripts/release/release.d.ts +23 -0
- package/dist/cli/scripts/release/release.js +70 -0
- package/dist/cli/types/DatabaseTypes.d.ts +103 -0
- package/dist/cli/types/DatabaseTypes.js +2 -0
- package/dist/components/LoggerExample.d.ts +6 -0
- package/dist/components/LoggerExample.js +79 -0
- package/dist/components/ai/Assistant.js +5 -5
- package/dist/components/ai/Avatar.d.ts +3 -2
- package/dist/components/ai/Avatar.js +11 -6
- package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.js +1 -1
- package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.d.ts +1 -0
- package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.js +48 -33
- package/dist/components/ai/utils.js +0 -1
- package/dist/components/audio/Playbutton.js +4 -4
- package/dist/{core → components}/components/ContextMenu.js +50 -11
- package/dist/components.d.ts +5 -5
- package/dist/components.js +5 -5
- package/dist/core/controller/AIController.d.ts +15 -0
- package/dist/core/controller/AIController.js +253 -0
- package/dist/core/controller/AudioController.d.ts +0 -0
- package/dist/core/controller/AudioController.js +1 -0
- package/dist/{controller → core/controller}/ObjectController.d.ts +10 -2
- package/dist/{controller → core/controller}/ObjectController.js +8 -8
- package/dist/{controller → core/controller}/SettingsController.d.ts +28 -4
- package/dist/{controller → core/controller}/SettingsController.js +0 -25
- package/dist/{controller → core/controller}/SharedContentController.d.ts +31 -3
- package/dist/{controller → core/controller}/SharedContentController.js +77 -26
- package/dist/core/controller/VoiceController.d.ts +9 -0
- package/dist/{controller → core/controller}/VoiceController.js +11 -4
- package/dist/core/core.d.ts +14 -0
- package/dist/core/core.js +8 -0
- package/dist/{plugin/fromRimori → fromRimori}/EventBus.d.ts +3 -3
- package/dist/{plugin/fromRimori → fromRimori}/EventBus.js +26 -9
- package/dist/fromRimori/PluginTypes.d.ts +174 -0
- package/dist/hooks/UseChatHook.d.ts +2 -1
- package/dist/hooks/UseChatHook.js +6 -4
- package/dist/hooks/UseLogger.d.ts +30 -0
- package/dist/hooks/UseLogger.js +122 -0
- package/dist/index.d.ts +6 -3
- package/dist/index.js +5 -3
- package/dist/plugin/AccomplishmentHandler.d.ts +1 -1
- package/dist/plugin/AccomplishmentHandler.js +1 -1
- package/dist/plugin/AudioController.d.ts +37 -0
- package/dist/plugin/AudioController.js +68 -0
- package/dist/plugin/Logger.d.ts +68 -0
- package/dist/plugin/Logger.js +256 -0
- package/dist/plugin/LoggerExample.d.ts +16 -0
- package/dist/plugin/LoggerExample.js +140 -0
- package/dist/plugin/PluginController.d.ts +30 -5
- package/dist/plugin/PluginController.js +182 -53
- package/dist/plugin/RimoriClient.d.ts +68 -21
- package/dist/plugin/RimoriClient.js +88 -41
- package/dist/plugin/StandaloneClient.d.ts +1 -0
- package/dist/plugin/StandaloneClient.js +24 -10
- package/dist/plugin/ThemeSetter.d.ts +2 -1
- package/dist/plugin/ThemeSetter.js +13 -7
- package/dist/providers/PluginProvider.d.ts +4 -1
- package/dist/providers/PluginProvider.js +39 -13
- package/dist/utils/Language.d.ts +2 -1
- package/dist/utils/Language.js +4 -2
- package/dist/utils/audioFormats.d.ts +26 -0
- package/dist/utils/audioFormats.js +67 -0
- package/dist/utils/difficultyConverter.js +1 -1
- package/dist/utils/endpoint.d.ts +2 -0
- package/dist/utils/endpoint.js +2 -0
- package/dist/worker/WorkerSetup.d.ts +3 -2
- package/dist/worker/WorkerSetup.js +22 -65
- package/example/docs/devdocs.md +231 -0
- package/example/docs/overview.md +29 -0
- package/example/docs/userdocs.md +123 -0
- package/example/rimori.config.ts +89 -0
- package/example/worker/vite.config.ts +23 -0
- package/example/worker/worker.ts +11 -0
- package/package.json +16 -9
- package/src/cli/scripts/init/dev-registration.ts +192 -0
- package/src/cli/scripts/init/env-setup.ts +44 -0
- package/src/cli/scripts/init/file-operations.ts +58 -0
- package/src/cli/scripts/init/html-cleaner.ts +48 -0
- package/src/cli/scripts/init/main.ts +172 -0
- package/src/cli/scripts/init/package-setup.ts +117 -0
- package/src/cli/scripts/init/router-transformer.ts +329 -0
- package/src/cli/scripts/init/tailwind-config.ts +75 -0
- package/src/cli/scripts/init/vite-config.ts +73 -0
- package/src/cli/scripts/release/release-config-upload.ts +114 -0
- package/src/cli/scripts/release/release-db-update.ts +97 -0
- package/src/cli/scripts/release/release-file-upload.ts +138 -0
- package/src/cli/scripts/release/release.ts +69 -0
- package/src/cli/types/DatabaseTypes.ts +117 -0
- package/src/components/ai/Assistant.tsx +5 -5
- package/src/components/ai/Avatar.tsx +25 -8
- package/src/components/ai/EmbeddedAssistent/CircleAudioAvatar.tsx +1 -1
- package/src/components/ai/EmbeddedAssistent/VoiceRecoder.tsx +50 -35
- package/src/components/ai/utils.ts +0 -2
- package/src/components/audio/Playbutton.tsx +4 -4
- package/src/{core → components}/components/ContextMenu.tsx +56 -12
- package/src/components.ts +6 -6
- package/src/core/controller/AIController.ts +283 -0
- package/src/core/controller/ObjectController.ts +115 -0
- package/src/{controller → core/controller}/SettingsController.ts +29 -29
- package/src/{controller → core/controller}/SharedContentController.ts +91 -29
- package/src/core/controller/VoiceController.ts +31 -0
- package/src/core/core.ts +16 -0
- package/src/{plugin/fromRimori → fromRimori}/EventBus.ts +29 -11
- package/src/fromRimori/PluginTypes.ts +205 -0
- package/src/hooks/UseChatHook.ts +8 -5
- package/src/index.ts +6 -3
- package/src/plugin/AccomplishmentHandler.ts +1 -1
- package/src/plugin/AudioController.ts +58 -0
- package/src/plugin/Logger.ts +324 -0
- package/src/plugin/PluginController.ts +203 -63
- package/src/plugin/RimoriClient.ts +127 -55
- package/src/plugin/StandaloneClient.ts +30 -11
- package/src/plugin/ThemeSetter.ts +16 -9
- package/src/providers/PluginProvider.tsx +46 -13
- package/src/utils/Language.ts +4 -2
- package/src/utils/difficultyConverter.ts +3 -3
- package/src/utils/endpoint.ts +2 -0
- package/src/worker/WorkerSetup.ts +13 -60
- package/dist/components/PluginController.d.ts +0 -21
- package/dist/components/PluginController.js +0 -116
- package/dist/controller/AIController.d.ts +0 -23
- package/dist/controller/AIController.js +0 -93
- package/dist/controller/SidePluginController.d.ts +0 -3
- package/dist/controller/SidePluginController.js +0 -31
- package/dist/controller/VoiceController.d.ts +0 -10
- package/dist/core.d.ts +0 -7
- package/dist/core.js +0 -7
- package/dist/plugin/ContextMenu.d.ts +0 -17
- package/dist/plugin/ContextMenu.js +0 -45
- package/dist/plugin/fromRimori/PluginTypes.d.ts +0 -48
- package/dist/plugin/fromRimori/SupabaseHandler.d.ts +0 -13
- package/dist/plugin/fromRimori/SupabaseHandler.js +0 -55
- package/dist/providers/PluginController.d.ts +0 -21
- package/dist/providers/PluginController.js +0 -116
- package/dist/types/Actions.d.ts +0 -4
- package/dist/types/Actions.js +0 -1
- package/src/controller/AIController.ts +0 -112
- package/src/controller/ObjectController.ts +0 -107
- package/src/controller/SidePluginController.ts +0 -25
- package/src/controller/VoiceController.ts +0 -26
- package/src/core.ts +0 -8
- package/src/plugin/fromRimori/PluginTypes.ts +0 -64
- package/src/types/Actions.ts +0 -6
- /package/dist/{core → components}/components/ContextMenu.d.ts +0 -0
- /package/dist/{plugin/fromRimori → fromRimori}/PluginTypes.js +0 -0
- /package/src/{plugin/fromRimori → fromRimori}/readme.md +0 -0
package/README.md
CHANGED
|
@@ -5,6 +5,8 @@ The **@rimori/client** package is a comprehensive React library that enables plu
|
|
|
5
5
|
## Table of Contents
|
|
6
6
|
|
|
7
7
|
- [Installation](#installation)
|
|
8
|
+
- [Quick Start Plugin Development](#quick-start-plugin-development)
|
|
9
|
+
- [Releasing Your Plugin to Rimori](#releasing-your-plugin-to-rimori)
|
|
8
10
|
- [Quick Start](#quick-start)
|
|
9
11
|
- [Core API - usePlugin Hook](#core-api---useplugin-hook)
|
|
10
12
|
- [Database Integration](#database-integration)
|
|
@@ -25,75 +27,194 @@ npm install @rimori/client
|
|
|
25
27
|
yarn add @rimori/client
|
|
26
28
|
```
|
|
27
29
|
|
|
28
|
-
## Quick Start
|
|
30
|
+
## Quick Start Plugin Development
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
The Rimori Client package includes powerful CLI tools to eliminate the tedious setup process and get you building your plugin fast. The initialization script handles authentication, plugin registration, environment setup, and all necessary boilerplate configuration.
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
import { lazy } from "react";
|
|
34
|
-
import { PluginProvider, usePlugin } from "@rimori/client";
|
|
35
|
-
import { HashRouter, Route, Routes } from "react-router-dom";
|
|
34
|
+
### Prerequisites
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
const SettingsPage = lazy(() => import("./pages/settings/SettingsPage"));
|
|
39
|
-
const MainPage = lazy(() => import("./pages/MainPage"));
|
|
36
|
+
Before initializing your plugin, ensure you have:
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<HashRouter future={{ v7_startTransition: true, v7_relativeSplatPath: true }}>
|
|
44
|
-
<Routes>
|
|
45
|
-
<Route path="/" element={<MainPage />} />
|
|
46
|
-
<Route path="/settings" element={<SettingsPage />} />
|
|
47
|
-
</Routes>
|
|
48
|
-
</HashRouter>
|
|
49
|
-
</PluginProvider>
|
|
50
|
-
);
|
|
38
|
+
1. **Node.js and yarn/npm installed**
|
|
39
|
+
2. **A Rimori account** - You'll need to login during initialization to receive your access token
|
|
51
40
|
|
|
52
|
-
|
|
41
|
+
### Initializing a New Plugin
|
|
42
|
+
|
|
43
|
+
Open Lovable and vibe code the look of your plugin.
|
|
44
|
+
|
|
45
|
+
Then connect it to your Github account.
|
|
46
|
+
|
|
47
|
+
Clone the git repository:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
git clone ...
|
|
51
|
+
cd my-awesome-plugin
|
|
52
|
+
|
|
53
|
+
# Initialize with Rimori Client (this handles everything!)
|
|
54
|
+
npx @rimori/client rimori-init
|
|
53
55
|
```
|
|
54
56
|
|
|
55
|
-
###
|
|
57
|
+
### What the Init Script Does
|
|
56
58
|
|
|
57
|
-
|
|
59
|
+
The `rimori-init` command automates the entire plugin setup process:
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
61
|
+
1. **🔐 Authentication**: Prompts for your Rimori credentials and authenticates with the platform
|
|
62
|
+
2. **🚀 Plugin Registration**: Automatically registers your plugin and generates a unique plugin ID
|
|
63
|
+
3. **🔑 Access Token**: Provides you with an access token for future plugin releases
|
|
64
|
+
4. **📦 Package Configuration**: Updates `package.json` with plugin-specific settings
|
|
65
|
+
5. **⚙️ Environment Setup**: Creates `.env` files with your credentials
|
|
66
|
+
6. **📁 File Structure**: Copies all necessary boilerplate files and examples
|
|
67
|
+
7. **🎨 Configuration**: Sets up Vite, Tailwind, and router configurations
|
|
68
|
+
8. **📖 Documentation**: Provides example documentation and getting started guides
|
|
69
|
+
|
|
70
|
+
### Upgrade Mode
|
|
71
|
+
|
|
72
|
+
If you need to upgrade an existing plugin's configuration without changing the plugin ID:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
yarn rimori-init --upgrade
|
|
68
76
|
```
|
|
69
77
|
|
|
70
|
-
###
|
|
78
|
+
### Development Setup
|
|
79
|
+
|
|
80
|
+
After initialization, start developing immediately:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Start development server
|
|
84
|
+
yarn dev
|
|
85
|
+
|
|
86
|
+
# Your plugin will be available at:
|
|
87
|
+
# http://localhost:3000 (or your chosen port)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Rimori client comes pre-configured with:
|
|
91
|
+
- ✅ **Hot reload** for instant development feedback
|
|
92
|
+
- ✅ **TypeScript support** with full type safety
|
|
93
|
+
- ✅ **TailwindCSS** for modern styling
|
|
94
|
+
- ✅ **React Router** for navigation
|
|
95
|
+
- ✅ **Example components** and documentation
|
|
96
|
+
|
|
97
|
+
## Releasing Your Plugin to Rimori
|
|
98
|
+
|
|
99
|
+
Publishing your plugin to the Rimori platform is streamlined through the built-in `rimori-release` CLI tool. The release process handles database updates, file uploads, and plugin activation automatically.
|
|
100
|
+
|
|
101
|
+
### Prerequisites
|
|
102
|
+
|
|
103
|
+
1. **Plugin must be initialized** - Use `rimori-init` first to set up your plugin
|
|
104
|
+
2. **Build your plugin** - Ensure your plugin is built and the output is in the `dist/` directory
|
|
105
|
+
3. **Environment configured** - Your `.env` file should contain `RIMORI_TOKEN` (set during initialization)
|
|
106
|
+
|
|
107
|
+
### Quick Release (Recommended)
|
|
108
|
+
|
|
109
|
+
During plugin initialization, convenient release scripts are automatically added to your `package.json`. These scripts handle building and releasing in one command:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Quick release commands (build + release)
|
|
113
|
+
yarn release:alpha # Build and release to alpha channel
|
|
114
|
+
yarn release:beta # Build and release to beta channel
|
|
115
|
+
yarn release:stable # Build and release to stable channel
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Manual Release Process
|
|
119
|
+
|
|
120
|
+
If you prefer more control or need to understand the underlying process, you can use the `rimori-release` command directly:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Build your plugin first
|
|
124
|
+
yarn build
|
|
125
|
+
|
|
126
|
+
# Then release to different channels
|
|
127
|
+
yarn rimori-release alpha # For alpha testing
|
|
128
|
+
yarn rimori-release beta # For beta releases
|
|
129
|
+
yarn rimori-release stable # For production releases
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The plugin version is automatically read from your `package.json`, and the plugin ID is retrieved from the `r_id` field (set during initialization).
|
|
133
|
+
|
|
134
|
+
### What the Release Script Does
|
|
135
|
+
|
|
136
|
+
The `rimori-release` command performs a complete release workflow:
|
|
137
|
+
|
|
138
|
+
1. **📋 Configuration Upload**: Sends plugin metadata and configuration to the platform
|
|
139
|
+
2. **🗄️ Database Updates**: Updates plugin information and release records
|
|
140
|
+
3. **📁 File Upload**: Uploads all files from your `dist/` directory to the platform
|
|
141
|
+
4. **🚀 Plugin Activation**: Activates the new version on the specified release channel
|
|
142
|
+
|
|
143
|
+
### Release Channels
|
|
144
|
+
|
|
145
|
+
- **`alpha`**: Early development releases for internal testing
|
|
146
|
+
- **`beta`**: Pre-release versions for beta testers
|
|
147
|
+
- **`stable`**: Production-ready releases for all users
|
|
148
|
+
|
|
149
|
+
### Automatic Configuration
|
|
150
|
+
|
|
151
|
+
During plugin initialization, the following are automatically configured:
|
|
152
|
+
- `RIMORI_TOKEN`: Your authentication token (stored in `.env`)
|
|
153
|
+
- `r_id`: Your unique plugin ID (stored in `package.json`)
|
|
154
|
+
- **Release scripts**: `yarn release:alpha`, `yarn release:beta`, `yarn release:stable`
|
|
155
|
+
- **Build configuration**: TypeScript checking, Vite setup, and worker builds
|
|
156
|
+
|
|
157
|
+
### Troubleshooting
|
|
158
|
+
|
|
159
|
+
If you encounter release issues:
|
|
160
|
+
|
|
161
|
+
1. **Missing token**: Ensure `RIMORI_TOKEN` is in your `.env` file
|
|
162
|
+
2. **No plugin ID**: Verify `r_id` exists in your `package.json`
|
|
163
|
+
3. **Build errors**: Run `yarn build` successfully before releasing
|
|
164
|
+
4. **Authentication**: Your token may have expired - re-run `rimori-init` if needed
|
|
165
|
+
|
|
166
|
+
#### Worker Process Errors
|
|
167
|
+
|
|
168
|
+
If you encounter errors like:
|
|
169
|
+
```
|
|
170
|
+
ReferenceError: process is not defined
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Root Cause**: Your plugin is importing a library that tries to access `process` or `process.env` in the worker context. Web workers don't have access to Node.js globals like `process`.
|
|
174
|
+
|
|
175
|
+
**Debugging Steps**:
|
|
176
|
+
|
|
177
|
+
1. **Check your imports**: Look through the files used in the worker which might import libraries that might access `process.env`:
|
|
178
|
+
- React libraries (React Router, React Query, etc.)
|
|
179
|
+
- UI component libraries (Material-UI, Ant Design, etc.)
|
|
180
|
+
- Utility libraries that check for environment variables
|
|
181
|
+
|
|
182
|
+
2. **Verify Rimori Client imports**: Ensure you're importing from `@rimori/client/core` and not from `@rimori/client`:
|
|
183
|
+
```typescript
|
|
184
|
+
// ✅ Correct - import from rimori client
|
|
185
|
+
import { RimoriClient } from '@rimori/client/core';
|
|
186
|
+
|
|
187
|
+
// ❌ Incorrect - direct imports that might access process.env directly or through their dependencies
|
|
188
|
+
import { Avatar } from '@rimori/client';
|
|
189
|
+
import { useQuery } from '@tanstack/react-query';
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
3. **Check your dependencies**: Look at your `package.json` for libraries that might be bundled into the worker:
|
|
193
|
+
- UI frameworks (React, Vue, etc.)
|
|
194
|
+
- State management libraries
|
|
195
|
+
- Routing libraries
|
|
196
|
+
- Any library that checks `process.env.NODE_ENV`
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
**Solution**: Use only `@rimori/client/core` exports in your worker code. The Rimori client provides all necessary functionality without requiring Node.js globals.
|
|
200
|
+
|
|
201
|
+
**Note**: The worker bundling order is determined by the build system and cannot be controlled. Libraries that access `process.env` will always cause this error in the worker context.
|
|
202
|
+
|
|
203
|
+
|
|
71
204
|
|
|
72
|
-
Add the following to your `vite.config.ts`:
|
|
73
205
|
|
|
74
|
-
```javascript
|
|
75
|
-
import { defineConfig } from 'vite'
|
|
76
|
-
import react from '@vitejs/plugin-react'
|
|
77
206
|
|
|
78
|
-
export default defineConfig({
|
|
79
|
-
plugins: [react()],
|
|
80
|
-
base: './', // Set base path for proper asset loading
|
|
81
|
-
build: {
|
|
82
|
-
outDir: 'dist',
|
|
83
|
-
assetsDir: 'assets'
|
|
84
|
-
}
|
|
85
|
-
})
|
|
86
207
|
```
|
|
87
208
|
|
|
88
209
|
## Core API - usePlugin Hook
|
|
89
210
|
|
|
90
|
-
The `
|
|
211
|
+
The `useRimori()` hook is the main interface for accessing Rimori platform features:
|
|
91
212
|
|
|
92
213
|
```typescript
|
|
93
|
-
import {
|
|
214
|
+
import { useRimori } from "@rimori/client";
|
|
94
215
|
|
|
95
216
|
const MyComponent = () => {
|
|
96
|
-
const client =
|
|
217
|
+
const client = useRimori();
|
|
97
218
|
|
|
98
219
|
// Access all client features
|
|
99
220
|
const { db, llm, event, community, plugin } = client;
|
|
@@ -105,7 +226,7 @@ const MyComponent = () => {
|
|
|
105
226
|
### Plugin Interface
|
|
106
227
|
|
|
107
228
|
```typescript
|
|
108
|
-
const { plugin } =
|
|
229
|
+
const { plugin } = useRimori();
|
|
109
230
|
|
|
110
231
|
// Plugin information and settings
|
|
111
232
|
plugin.pluginId: string // Current plugin ID
|
|
@@ -127,7 +248,7 @@ interface FlashcardSettings {
|
|
|
127
248
|
}
|
|
128
249
|
|
|
129
250
|
const FlashcardSettingsComponent = () => {
|
|
130
|
-
const { plugin } =
|
|
251
|
+
const { plugin } = useRimori();
|
|
131
252
|
const [settings, setSettings] = useState<FlashcardSettings>();
|
|
132
253
|
|
|
133
254
|
useEffect(() => {
|
|
@@ -196,7 +317,7 @@ const FlashcardSettingsComponent = () => {
|
|
|
196
317
|
Access your plugin's dedicated database tables with full TypeScript support:
|
|
197
318
|
|
|
198
319
|
```typescript
|
|
199
|
-
const { db } =
|
|
320
|
+
const { db } = useRimori();
|
|
200
321
|
|
|
201
322
|
// Database interface
|
|
202
323
|
db.from(tableName) // Query builder for tables/views - supports ALL Supabase operations
|
|
@@ -214,6 +335,12 @@ The `db.from()` method provides access to the complete Supabase PostgREST API, s
|
|
|
214
335
|
|
|
215
336
|
All operations automatically use your plugin's table prefix for security and isolation.
|
|
216
337
|
|
|
338
|
+
**Column deprecation and removal (short policy)**
|
|
339
|
+
|
|
340
|
+
- To remove a column, use a two-step process:
|
|
341
|
+
1. Mark the column with `deprecated: true` in your `rimori/db.config.ts` and release. The backend renames the column to `<name>_old`.
|
|
342
|
+
2. In a subsequent release, remove the column from the config. The backend drops `<name>_old`.
|
|
343
|
+
|
|
217
344
|
**Example: CRUD Operations**
|
|
218
345
|
|
|
219
346
|
```typescript
|
|
@@ -226,7 +353,7 @@ interface StudySession {
|
|
|
226
353
|
}
|
|
227
354
|
|
|
228
355
|
const StudySessionManager = () => {
|
|
229
|
-
const { db } =
|
|
356
|
+
const { db } = useRimori();
|
|
230
357
|
|
|
231
358
|
// Create a new study session
|
|
232
359
|
const createSession = async (session: Omit<StudySession, 'id'>) => {
|
|
@@ -277,7 +404,7 @@ const StudySessionManager = () => {
|
|
|
277
404
|
|
|
278
405
|
```typescript
|
|
279
406
|
const FileManager = () => {
|
|
280
|
-
const { db } =
|
|
407
|
+
const { db } = useRimori();
|
|
281
408
|
|
|
282
409
|
const uploadFile = async (file: File) => {
|
|
283
410
|
const fileName = `uploads/${Date.now()}-${file.name}`;
|
|
@@ -308,7 +435,7 @@ const FileManager = () => {
|
|
|
308
435
|
Powerful AI/Language Model capabilities built-in:
|
|
309
436
|
|
|
310
437
|
```typescript
|
|
311
|
-
const { llm } =
|
|
438
|
+
const { llm } = useRimori();
|
|
312
439
|
|
|
313
440
|
// Text generation
|
|
314
441
|
llm.getText(messages: Message[], tools?: Tool[]): Promise<string>
|
|
@@ -377,7 +504,7 @@ const ChatAssistant = () => {
|
|
|
377
504
|
|
|
378
505
|
```typescript
|
|
379
506
|
const QuizGenerator = () => {
|
|
380
|
-
const { llm } =
|
|
507
|
+
const { llm } = useRimori();
|
|
381
508
|
|
|
382
509
|
const generateQuiz = async (topic: string) => {
|
|
383
510
|
const quiz = await llm.getObject({
|
|
@@ -413,7 +540,7 @@ const QuizGenerator = () => {
|
|
|
413
540
|
|
|
414
541
|
```typescript
|
|
415
542
|
const VoiceAssistant = () => {
|
|
416
|
-
const { llm } =
|
|
543
|
+
const { llm } = useRimori();
|
|
417
544
|
|
|
418
545
|
const speakText = async (text: string) => {
|
|
419
546
|
const audioBlob = await llm.getVoice(text, "alloy", 1, "en");
|
|
@@ -436,7 +563,7 @@ const VoiceAssistant = () => {
|
|
|
436
563
|
Robust inter-plugin communication and platform integration:
|
|
437
564
|
|
|
438
565
|
```typescript
|
|
439
|
-
const { event } =
|
|
566
|
+
const { event } = useRimori();
|
|
440
567
|
|
|
441
568
|
// Event methods
|
|
442
569
|
event.emit(topic: string, data?: any, eventId?: number): void
|
|
@@ -457,7 +584,7 @@ event.emitSidebarAction(pluginId: string, actionKey: string, text?: string): voi
|
|
|
457
584
|
|
|
458
585
|
```typescript
|
|
459
586
|
const PluginCommunicator = () => {
|
|
460
|
-
const { event } =
|
|
587
|
+
const { event } = useRimori();
|
|
461
588
|
|
|
462
589
|
useEffect(() => {
|
|
463
590
|
// Listen for messages from other plugins
|
|
@@ -507,7 +634,7 @@ const PluginCommunicator = () => {
|
|
|
507
634
|
|
|
508
635
|
```typescript
|
|
509
636
|
const AccomplishmentTracker = () => {
|
|
510
|
-
const { event } =
|
|
637
|
+
const { event } = useRimori();
|
|
511
638
|
|
|
512
639
|
const trackAccomplishment = () => {
|
|
513
640
|
event.emitAccomplishment({
|
|
@@ -538,7 +665,7 @@ const AccomplishmentTracker = () => {
|
|
|
538
665
|
|
|
539
666
|
```typescript
|
|
540
667
|
const SidebarIntegration = () => {
|
|
541
|
-
const { event } =
|
|
668
|
+
const { event } = useRimori();
|
|
542
669
|
|
|
543
670
|
const openTranslator = (text: string) => {
|
|
544
671
|
// Trigger translator plugin in sidebar
|
|
@@ -568,7 +695,7 @@ const SidebarIntegration = () => {
|
|
|
568
695
|
Share and discover content created by other users:
|
|
569
696
|
|
|
570
697
|
```typescript
|
|
571
|
-
const { community } =
|
|
698
|
+
const { community } = useRimori();
|
|
572
699
|
|
|
573
700
|
// Shared content methods
|
|
574
701
|
community.sharedContent.get<T>(contentType: string, id: string): Promise<BasicAssignment<T>>
|
|
@@ -595,7 +722,7 @@ interface Exercise {
|
|
|
595
722
|
}
|
|
596
723
|
|
|
597
724
|
const ExerciseManager = () => {
|
|
598
|
-
const { community } =
|
|
725
|
+
const { community } = useRimori();
|
|
599
726
|
const [exercises, setExercises] = useState<BasicAssignment<Exercise>[]>([]);
|
|
600
727
|
|
|
601
728
|
// Load community exercises
|
|
@@ -913,7 +1040,7 @@ import {
|
|
|
913
1040
|
import { HashRouter, Route, Routes } from 'react-router-dom';
|
|
914
1041
|
|
|
915
1042
|
const StudyNotesPlugin = () => {
|
|
916
|
-
const { db, llm, plugin, community } =
|
|
1043
|
+
const { db, llm, plugin, community } = useRimori();
|
|
917
1044
|
const [notes, setNotes] = useState([]);
|
|
918
1045
|
const [isLoading, setIsLoading] = useState(true);
|
|
919
1046
|
const { messages, append } = useChat();
|
|
@@ -1013,5 +1140,4 @@ export default App;
|
|
|
1013
1140
|
4. **Event Cleanup**: Always unsubscribe from events in useEffect cleanup
|
|
1014
1141
|
5. **Responsive Design**: Use TailwindCSS classes for responsive layouts
|
|
1015
1142
|
|
|
1016
|
-
## License
|
|
1017
1143
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface UserCredentials {
|
|
2
|
+
email: string;
|
|
3
|
+
password: string;
|
|
4
|
+
}
|
|
5
|
+
export interface DeveloperRegisterResponse {
|
|
6
|
+
plugin_id: string;
|
|
7
|
+
access_token: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Prompts user for email and password credentials.
|
|
11
|
+
* @returns Promise resolving to user credentials.
|
|
12
|
+
*/
|
|
13
|
+
export declare function askForCredentials(): Promise<UserCredentials>;
|
|
14
|
+
/**
|
|
15
|
+
* Prompts user for development port with default value.
|
|
16
|
+
* @returns Promise resolving to the selected port.
|
|
17
|
+
*/
|
|
18
|
+
export declare function askForPort(): Promise<number>;
|
|
19
|
+
/**
|
|
20
|
+
* Authenticates with Supabase using email and password.
|
|
21
|
+
* @param param
|
|
22
|
+
* @param param.email - User email address.
|
|
23
|
+
* @param param.password - User password.
|
|
24
|
+
* @returns Promise resolving to JWT access token.
|
|
25
|
+
* @throws {Error} if authentication fails.
|
|
26
|
+
*/
|
|
27
|
+
export declare function authenticateWithSupabase({ email, password, }: UserCredentials): Promise<string>;
|
|
28
|
+
/**
|
|
29
|
+
* Registers developer and gets plugin credentials from the backend.
|
|
30
|
+
* @param jwtToken - JWT token from Supabase authentication.
|
|
31
|
+
* @param port - Development port for the plugin.
|
|
32
|
+
* @returns Promise resolving to plugin ID and access token.
|
|
33
|
+
* @throws {Error} if registration request fails.
|
|
34
|
+
*/
|
|
35
|
+
export declare function registerDeveloper(jwtToken: string, port: number): Promise<DeveloperRegisterResponse>;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { createClient } from '@supabase/supabase-js';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
import * as readline from 'readline';
|
|
13
|
+
import { DEFAULT_ANON_KEY, DEFAULT_ENDPOINT } from '../../../utils/endpoint.js';
|
|
14
|
+
/**
|
|
15
|
+
* Prompts user for email and password credentials.
|
|
16
|
+
* @returns Promise resolving to user credentials.
|
|
17
|
+
*/
|
|
18
|
+
export function askForCredentials() {
|
|
19
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
const rl = readline.createInterface({
|
|
21
|
+
input: process.stdin,
|
|
22
|
+
output: process.stdout,
|
|
23
|
+
});
|
|
24
|
+
return new Promise((resolve) => {
|
|
25
|
+
rl.question('Enter your email: ', (email) => {
|
|
26
|
+
rl.close();
|
|
27
|
+
// Create a new interface for password input with muted output
|
|
28
|
+
const passwordRl = readline.createInterface({
|
|
29
|
+
input: process.stdin,
|
|
30
|
+
output: process.stdout,
|
|
31
|
+
terminal: false
|
|
32
|
+
});
|
|
33
|
+
process.stdout.write('Enter your password: ');
|
|
34
|
+
// Set up stdin for raw input
|
|
35
|
+
process.stdin.setRawMode(true);
|
|
36
|
+
process.stdin.resume();
|
|
37
|
+
let password = '';
|
|
38
|
+
const onData = (buffer) => {
|
|
39
|
+
const char = buffer.toString('utf8');
|
|
40
|
+
if (char === '\r' || char === '\n') {
|
|
41
|
+
// Enter pressed
|
|
42
|
+
process.stdin.setRawMode(false);
|
|
43
|
+
process.stdin.pause();
|
|
44
|
+
process.stdin.removeListener('data', onData);
|
|
45
|
+
process.stdout.write('\n');
|
|
46
|
+
passwordRl.close();
|
|
47
|
+
resolve({ email: email.trim(), password: password.trim() });
|
|
48
|
+
}
|
|
49
|
+
else if (char === '\u0003') {
|
|
50
|
+
// Ctrl+C
|
|
51
|
+
process.stdin.setRawMode(false);
|
|
52
|
+
process.stdin.pause();
|
|
53
|
+
process.stdin.removeListener('data', onData);
|
|
54
|
+
process.stdout.write('\n');
|
|
55
|
+
process.exit(0);
|
|
56
|
+
}
|
|
57
|
+
else if (char === '\u007f' || char === '\b') {
|
|
58
|
+
// Backspace
|
|
59
|
+
if (password.length > 0) {
|
|
60
|
+
password = password.slice(0, -1);
|
|
61
|
+
process.stdout.write('\b \b');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else if (char.charCodeAt(0) >= 32 && char.charCodeAt(0) <= 126) {
|
|
65
|
+
// Printable characters
|
|
66
|
+
password += char;
|
|
67
|
+
process.stdout.write('*');
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
process.stdin.on('data', onData);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Prompts user for development port with default value.
|
|
77
|
+
* @returns Promise resolving to the selected port.
|
|
78
|
+
*/
|
|
79
|
+
export function askForPort() {
|
|
80
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
81
|
+
const rl = readline.createInterface({
|
|
82
|
+
input: process.stdin,
|
|
83
|
+
output: process.stdout,
|
|
84
|
+
});
|
|
85
|
+
return new Promise((resolve) => {
|
|
86
|
+
rl.question('Enter development port (default: 3000): ', (answer) => {
|
|
87
|
+
rl.close();
|
|
88
|
+
const port = answer.trim() || '3000';
|
|
89
|
+
// Validate port is a number
|
|
90
|
+
const portNumber = parseInt(port, 10);
|
|
91
|
+
if (isNaN(portNumber) || portNumber < 1 || portNumber > 65535) {
|
|
92
|
+
console.error('Error: Port must be a valid number between 1 and 65535');
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
resolve(portNumber);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Authenticates with Supabase using email and password.
|
|
102
|
+
* @param param
|
|
103
|
+
* @param param.email - User email address.
|
|
104
|
+
* @param param.password - User password.
|
|
105
|
+
* @returns Promise resolving to JWT access token.
|
|
106
|
+
* @throws {Error} if authentication fails.
|
|
107
|
+
*/
|
|
108
|
+
export function authenticateWithSupabase(_a) {
|
|
109
|
+
return __awaiter(this, arguments, void 0, function* ({ email, password, }) {
|
|
110
|
+
var _b;
|
|
111
|
+
console.log('🔐 Authenticating with Supabase...');
|
|
112
|
+
// Initialize Supabase client (you may need to adjust the URL and key)
|
|
113
|
+
const supabaseUrl = process.env.SUPABASE_URL || DEFAULT_ENDPOINT;
|
|
114
|
+
const supabaseKey = process.env.SUPABASE_ANON_KEY || DEFAULT_ANON_KEY;
|
|
115
|
+
const supabase = createClient(supabaseUrl, supabaseKey);
|
|
116
|
+
try {
|
|
117
|
+
const { data, error } = yield supabase.auth.signInWithPassword({
|
|
118
|
+
email,
|
|
119
|
+
password,
|
|
120
|
+
});
|
|
121
|
+
if (error) {
|
|
122
|
+
throw new Error(`Authentication failed: ${error.message}`);
|
|
123
|
+
}
|
|
124
|
+
if (!((_b = data.session) === null || _b === void 0 ? void 0 : _b.access_token)) {
|
|
125
|
+
throw new Error('No access token received from authentication');
|
|
126
|
+
}
|
|
127
|
+
console.log('✅ Supabase authentication successful!');
|
|
128
|
+
return data.session.access_token;
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
throw new Error(`Supabase authentication failed: ${error}`);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Registers developer and gets plugin credentials from the backend.
|
|
137
|
+
* @param jwtToken - JWT token from Supabase authentication.
|
|
138
|
+
* @param port - Development port for the plugin.
|
|
139
|
+
* @returns Promise resolving to plugin ID and access token.
|
|
140
|
+
* @throws {Error} if registration request fails.
|
|
141
|
+
*/
|
|
142
|
+
export function registerDeveloper(jwtToken, port) {
|
|
143
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
144
|
+
console.log('🚀 Registering developer and creating plugin...');
|
|
145
|
+
try {
|
|
146
|
+
const currentFolderName = path.basename(process.cwd());
|
|
147
|
+
const body = { port, pluginName: currentFolderName };
|
|
148
|
+
const backendUrl = process.env.RIMORI_BACKEND_URL || "https://api.rimori.se";
|
|
149
|
+
const response = yield fetch(backendUrl + '/developer/register', {
|
|
150
|
+
method: 'POST',
|
|
151
|
+
headers: {
|
|
152
|
+
'Content-Type': 'application/json',
|
|
153
|
+
'Authorization': `Bearer ${jwtToken}`,
|
|
154
|
+
},
|
|
155
|
+
body: JSON.stringify(body),
|
|
156
|
+
});
|
|
157
|
+
if (!response.ok) {
|
|
158
|
+
console.error(yield response.text());
|
|
159
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
160
|
+
}
|
|
161
|
+
const data = yield response.json();
|
|
162
|
+
if (!data.plugin_id || !data.access_token) {
|
|
163
|
+
throw new Error('Invalid response: missing pluginId or access_token');
|
|
164
|
+
}
|
|
165
|
+
console.log('✅ Plugin registration successful!');
|
|
166
|
+
console.log(`Plugin ID: ${data.plugin_id}`);
|
|
167
|
+
return data;
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
console.error(error);
|
|
171
|
+
throw new Error(`Developer registration failed: ${error}`);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates or updates the .env file with the plugin token.
|
|
3
|
+
* @param token - The plugin authentication token.
|
|
4
|
+
*/
|
|
5
|
+
export declare function setupEnvFile(token: string): void;
|
|
6
|
+
/**
|
|
7
|
+
* Updates .gitignore to exclude .env files.
|
|
8
|
+
*/
|
|
9
|
+
export declare function updateGitignore(): void;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Creates or updates the .env file with the plugin token.
|
|
5
|
+
* @param token - The plugin authentication token.
|
|
6
|
+
*/
|
|
7
|
+
export function setupEnvFile(token) {
|
|
8
|
+
const envPath = path.resolve('.env');
|
|
9
|
+
if (!fs.existsSync(envPath)) {
|
|
10
|
+
const envContent = `RIMORI_TOKEN=${token}\n`;
|
|
11
|
+
fs.writeFileSync(envPath, envContent, 'utf8');
|
|
12
|
+
console.log('Created .env file with RIMORI_TOKEN');
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
console.log('.env file already exists, skipping creation');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Updates .gitignore to exclude .env files.
|
|
20
|
+
*/
|
|
21
|
+
export function updateGitignore() {
|
|
22
|
+
const gitignorePath = path.resolve('.gitignore');
|
|
23
|
+
let gitignoreContent = '';
|
|
24
|
+
let needsUpdate = false;
|
|
25
|
+
if (fs.existsSync(gitignorePath)) {
|
|
26
|
+
gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
|
|
27
|
+
// Check if .env is already in .gitignore
|
|
28
|
+
if (!gitignoreContent.includes('.env')) {
|
|
29
|
+
needsUpdate = true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
needsUpdate = true;
|
|
34
|
+
}
|
|
35
|
+
if (needsUpdate) {
|
|
36
|
+
gitignoreContent += '\n.env\npublic/web-worker.js\n';
|
|
37
|
+
fs.writeFileSync(gitignorePath, gitignoreContent, 'utf8');
|
|
38
|
+
console.log('Added .env to .gitignore');
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
console.log('.env already in .gitignore, skipping update');
|
|
42
|
+
}
|
|
43
|
+
}
|