@sodikinnaa/smart-report-plugin 1.0.2

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 ADDED
@@ -0,0 +1,33 @@
1
+ # Smart Report Plugin for OpenClaw
2
+
3
+ Plugin ini mengintegrasikan ekosistem OpenClaw dengan sistem pelaporan Smart Report via protokol MCP.
4
+
5
+ ## 🛠️ Fitur
6
+ - **CLI Auth:** Autentikasi mudah menggunakan token API.
7
+ - **Resources:** Akses data real-time via URI `smartreport://`.
8
+ - **Agent Tools:** Memungkinkan AI melakukan analisis laporan dan performa secara otonom.
9
+
10
+ ## 🚀 Instalasi
11
+ 1. Clone repositori ini ke folder `~/.openclaw/extensions/`.
12
+ 2. Jalankan `npm install` dan `npm run build`.
13
+ 3. Tambahkan entry di `openclaw.json`:
14
+ ```json
15
+ "plugins": {
16
+ "allow": ["smart-report-plugin"]
17
+ }
18
+ ```
19
+
20
+ ## 🔑 Konfigurasi
21
+ Lakukan autentikasi via CLI:
22
+ ```bash
23
+ openclaw smart-auth <YOUR_API_TOKEN>
24
+ ```
25
+
26
+ ## 📖 URI Resources
27
+ - `smartreport://reports`: 10 Laporan terbaru.
28
+ - `smartreport://employees`: Daftar seluruh karyawan.
29
+ - `smartreport://debt-aging`: Analisis keterlambatan/absen.
30
+
31
+ ## 🤖 AI Tools
32
+ - `get_list_reports`: Mengambil laporan dengan filter.
33
+ - `get_debt_analysis`: Analisis performa dan tugas tertunda.
@@ -0,0 +1 @@
1
+ export default function register(api: any): void;
package/dist/index.js ADDED
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.default = register;
40
+ /**
41
+ * Smart Report MCP Plugin for OpenClaw
42
+ */
43
+ const axios_1 = __importDefault(require("axios"));
44
+ const fs = __importStar(require("fs"));
45
+ const path = __importStar(require("path"));
46
+ const os = __importStar(require("os"));
47
+ const PLUGIN_ID = 'smart-report-plugin';
48
+ const API_BASE = 'https://smartreport.siapdigital.my.id/api/mcp';
49
+ function saveConfig(token) {
50
+ const configPath = path.join(os.homedir(), '.openclaw', 'openclaw.json');
51
+ if (fs.existsSync(configPath)) {
52
+ const raw = fs.readFileSync(configPath, 'utf-8');
53
+ const config = JSON.parse(raw);
54
+ if (!config.plugins)
55
+ config.plugins = {};
56
+ if (!config.plugins.entries)
57
+ config.plugins.entries = {};
58
+ if (!config.plugins.entries[PLUGIN_ID])
59
+ config.plugins.entries[PLUGIN_ID] = {};
60
+ if (!config.plugins.entries[PLUGIN_ID].config)
61
+ config.plugins.entries[PLUGIN_ID].config = {};
62
+ config.plugins.entries[PLUGIN_ID].config.apiToken = token;
63
+ config.plugins.entries[PLUGIN_ID].enabled = true;
64
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
65
+ }
66
+ }
67
+ async function callMcp(api, method, params = {}) {
68
+ const config = api.config.plugins?.entries?.[PLUGIN_ID]?.config;
69
+ const token = config?.apiToken;
70
+ if (!token) {
71
+ throw new Error('API Token not found. Please run "openclaw smart-auth <token>" first.');
72
+ }
73
+ const response = await axios_1.default.post(API_BASE, {
74
+ jsonrpc: '2.0',
75
+ method: method,
76
+ params: params,
77
+ id: Date.now()
78
+ }, {
79
+ headers: {
80
+ 'Authorization': `Bearer ${token}`,
81
+ 'Content-Type': 'application/json',
82
+ 'Accept': 'application/json'
83
+ }
84
+ });
85
+ if (response.data.error) {
86
+ throw new Error(response.data.error.message);
87
+ }
88
+ return response.data.result;
89
+ }
90
+ function register(api) {
91
+ // 1. CLI Commands
92
+ api.registerCli(({ program }) => {
93
+ program
94
+ .command('smart-auth <token>')
95
+ .description('Set API Token for Smart Report integration')
96
+ .action((token) => {
97
+ try {
98
+ saveConfig(token);
99
+ console.log('✅ Smart Report API Token saved successfully.');
100
+ process.exit(0);
101
+ }
102
+ catch (err) {
103
+ console.error('❌ Failed to save config:', err.message);
104
+ process.exit(1);
105
+ }
106
+ });
107
+ }, { commands: ['smart-auth'] });
108
+ // 2. Resources
109
+ api.registerResource({
110
+ uri: 'smartreport://reports',
111
+ name: 'Recent Reports',
112
+ description: 'Stream of latest submitted reports',
113
+ mimeType: 'application/json',
114
+ read: async () => {
115
+ const data = await callMcp(api, 'reports/list', { per_page: 10 });
116
+ return { content: JSON.stringify(data, null, 2) };
117
+ }
118
+ });
119
+ api.registerResource({
120
+ uri: 'smartreport://employees',
121
+ name: 'Employee List',
122
+ description: 'Complete list of active employees',
123
+ mimeType: 'application/json',
124
+ read: async () => {
125
+ const data = await callMcp(api, 'employees/list', {});
126
+ return { content: JSON.stringify(data, null, 2) };
127
+ }
128
+ });
129
+ api.registerResource({
130
+ uri: 'smartreport://debt-aging',
131
+ name: 'Debt Aging Analysis',
132
+ description: 'Analysis of pending tasks and overdue reports',
133
+ mimeType: 'application/json',
134
+ read: async () => {
135
+ const data = await callMcp(api, 'attendance/list_absent', { include_reason: true });
136
+ return { content: JSON.stringify(data, null, 2) };
137
+ }
138
+ });
139
+ // 3. Agent Tools
140
+ api.registerTool({
141
+ name: 'get_list_reports',
142
+ description: 'Retrieve reports with filters (date, employee, division).',
143
+ execute: async (args) => {
144
+ try {
145
+ const data = await callMcp(api, 'reports/list', args);
146
+ return { text: JSON.stringify(data, null, 2) };
147
+ }
148
+ catch (err) {
149
+ return { error: err.message };
150
+ }
151
+ }
152
+ });
153
+ api.registerTool({
154
+ name: 'get_debt_analysis',
155
+ description: 'Analyze pending tasks and employee performance debt.',
156
+ execute: async (args) => {
157
+ try {
158
+ const data = await callMcp(api, 'analyze_performance', args);
159
+ return { text: JSON.stringify(data, null, 2) };
160
+ }
161
+ catch (err) {
162
+ return { error: err.message };
163
+ }
164
+ }
165
+ });
166
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "id": "smart-report-plugin",
3
+ "name": "Smart Report Integration",
4
+ "version": "1.0.0",
5
+ "description": "Integration plugin for Smart Report and AI Analytics",
6
+ "entry": "dist/index.js",
7
+ "skills": ["skills/smart-report/SKILL.md"],
8
+ "configSchema": {
9
+ "type": "object",
10
+ "properties": {
11
+ "apiToken": { "type": "string" }
12
+ }
13
+ }
14
+ }
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@sodikinnaa/smart-report-plugin",
3
+ "version": "1.0.2",
4
+ "description": "OpenClaw plugin for Smart Report system integration",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.js",
7
+ "type": "module",
8
+ "types": "dist/index.d.ts",
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "test": "echo \"Error: no test specified\" && exit 1"
12
+ },
13
+ "keywords": [
14
+ "openclaw-plugin",
15
+ "smart-report"
16
+ ],
17
+ "author": "Sodikin",
18
+ "license": "MIT",
19
+ "devDependencies": {
20
+ "typescript": "^5.0.0"
21
+ },
22
+ "dependencies": {
23
+ "axios": "^1.6.0"
24
+ },
25
+ "publishConfig": {
26
+ "access": "public"
27
+ }
28
+ }
package/src/index.ts ADDED
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Smart Report MCP Plugin for OpenClaw
3
+ */
4
+ import axios from 'axios';
5
+ import * as fs from 'fs';
6
+ import * as path from 'path';
7
+ import * as os from 'os';
8
+
9
+ const PLUGIN_ID = 'smart-report-plugin';
10
+ const API_BASE = 'https://smartreport.siapdigital.my.id/api/mcp';
11
+
12
+ function saveConfig(token: string) {
13
+ const configPath = path.join(os.homedir(), '.openclaw', 'openclaw.json');
14
+ if (fs.existsSync(configPath)) {
15
+ const raw = fs.readFileSync(configPath, 'utf-8');
16
+ const config = JSON.parse(raw);
17
+ if (!config.plugins) config.plugins = {};
18
+ if (!config.plugins.entries) config.plugins.entries = {};
19
+ if (!config.plugins.entries[PLUGIN_ID]) config.plugins.entries[PLUGIN_ID] = {};
20
+ if (!config.plugins.entries[PLUGIN_ID].config) config.plugins.entries[PLUGIN_ID].config = {};
21
+
22
+ config.plugins.entries[PLUGIN_ID].config.apiToken = token;
23
+ config.plugins.entries[PLUGIN_ID].enabled = true;
24
+
25
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
26
+ }
27
+ }
28
+
29
+ async function callMcp(api: any, method: string, params: any = {}) {
30
+ const config = (api.config as any).plugins?.entries?.[PLUGIN_ID]?.config;
31
+ const token = config?.apiToken;
32
+
33
+ if (!token) {
34
+ throw new Error('API Token not found. Please run "openclaw smart-auth <token>" first.');
35
+ }
36
+
37
+ const response = await axios.post(API_BASE, {
38
+ jsonrpc: '2.0',
39
+ method: method,
40
+ params: params,
41
+ id: Date.now()
42
+ }, {
43
+ headers: {
44
+ 'Authorization': `Bearer ${token}`,
45
+ 'Content-Type': 'application/json',
46
+ 'Accept': 'application/json'
47
+ }
48
+ });
49
+
50
+ if (response.data.error) {
51
+ throw new Error(response.data.error.message);
52
+ }
53
+
54
+ return response.data.result;
55
+ }
56
+
57
+ export default function register(api: any) {
58
+ // 1. CLI Commands
59
+ api.registerCli(({ program }: any) => {
60
+ program
61
+ .command('smart-auth <token>')
62
+ .description('Set API Token for Smart Report integration')
63
+ .action((token: string) => {
64
+ try {
65
+ saveConfig(token);
66
+ console.log('✅ Smart Report API Token saved successfully.');
67
+ process.exit(0);
68
+ } catch (err: any) {
69
+ console.error('❌ Failed to save config:', err.message);
70
+ process.exit(1);
71
+ }
72
+ });
73
+ }, { commands: ['smart-auth'] });
74
+
75
+ // 2. Resources
76
+ api.registerResource({
77
+ uri: 'smartreport://reports',
78
+ name: 'Recent Reports',
79
+ description: 'Stream of latest submitted reports',
80
+ mimeType: 'application/json',
81
+ read: async () => {
82
+ const data = await callMcp(api, 'reports/list', { per_page: 10 });
83
+ return { content: JSON.stringify(data, null, 2) };
84
+ }
85
+ });
86
+
87
+ api.registerResource({
88
+ uri: 'smartreport://employees',
89
+ name: 'Employee List',
90
+ description: 'Complete list of active employees',
91
+ mimeType: 'application/json',
92
+ read: async () => {
93
+ const data = await callMcp(api, 'employees/list', {});
94
+ return { content: JSON.stringify(data, null, 2) };
95
+ }
96
+ });
97
+
98
+ api.registerResource({
99
+ uri: 'smartreport://debt-aging',
100
+ name: 'Debt Aging Analysis',
101
+ description: 'Analysis of pending tasks and overdue reports',
102
+ mimeType: 'application/json',
103
+ read: async () => {
104
+ const data = await callMcp(api, 'attendance/list_absent', { include_reason: true });
105
+ return { content: JSON.stringify(data, null, 2) };
106
+ }
107
+ });
108
+
109
+ // 3. Agent Tools
110
+ api.registerTool({
111
+ name: 'get_list_reports',
112
+ description: 'Retrieve reports with filters (date, employee, division).',
113
+ execute: async (args: any) => {
114
+ try {
115
+ const data = await callMcp(api, 'reports/list', args);
116
+ return { text: JSON.stringify(data, null, 2) };
117
+ } catch (err: any) {
118
+ return { error: err.message };
119
+ }
120
+ }
121
+ });
122
+
123
+ api.registerTool({
124
+ name: 'get_debt_analysis',
125
+ description: 'Analyze pending tasks and employee performance debt.',
126
+ execute: async (args: any) => {
127
+ try {
128
+ const data = await callMcp(api, 'analyze_performance', args);
129
+ return { text: JSON.stringify(data, null, 2) };
130
+ } catch (err: any) {
131
+ return { error: err.message };
132
+ }
133
+ }
134
+ });
135
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "CommonJS",
5
+ "lib": ["ESNext"],
6
+ "declaration": true,
7
+ "outDir": "./dist",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "moduleResolution": "node"
13
+ },
14
+ "include": ["src/**/*"]
15
+ }