@sodikinnaa/smart-report-plugin 2100.11.4 → 2100.11.7
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/.github/workflows/publish-npm.yml +44 -0
- package/README.md +427 -30
- package/dist/client.d.ts +17 -0
- package/dist/client.js +104 -0
- package/dist/commands.d.ts +13 -0
- package/dist/commands.js +468 -0
- package/dist/index.d.ts +15 -3
- package/dist/index.js +11 -217
- package/dist/resources.d.ts +4 -0
- package/dist/resources.js +59 -0
- package/dist/tools.d.ts +6 -0
- package/dist/tools.js +157 -0
- package/docs/AGENT_SESSION_MCP_TROUBLESHOOTING.md +251 -0
- package/docs/USER_GUIDE.md +264 -54
- package/index.js +17 -0
- package/install.sh +309 -0
- package/openclaw.plugin.json +14 -4
- package/package.json +5 -4
- package/scripts/test-loader.js +75 -13
- package/skills/smart-report/SKILL.md +52 -0
- package/src/client.ts +128 -0
- package/src/commands.ts +548 -0
- package/src/index.ts +22 -233
- package/src/resources.ts +62 -0
- package/src/tools.ts +205 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: Publish to npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
paths:
|
|
7
|
+
- "package.json"
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
publish:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
with:
|
|
17
|
+
fetch-depth: 2
|
|
18
|
+
|
|
19
|
+
- name: Check if version changed
|
|
20
|
+
id: version
|
|
21
|
+
run: |
|
|
22
|
+
NEW=$(node -p "require('./package.json').version")
|
|
23
|
+
OLD=$(git show HEAD~1:package.json | node -p "JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')).version")
|
|
24
|
+
if [ "$NEW" != "$OLD" ]; then
|
|
25
|
+
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
26
|
+
echo "Version changed: $OLD -> $NEW"
|
|
27
|
+
else
|
|
28
|
+
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
29
|
+
echo "Version unchanged: $NEW"
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
- uses: actions/setup-node@v4
|
|
33
|
+
if: steps.version.outputs.changed == 'true'
|
|
34
|
+
with:
|
|
35
|
+
node-version: "20"
|
|
36
|
+
registry-url: "https://registry.npmjs.org"
|
|
37
|
+
|
|
38
|
+
- run: npm install
|
|
39
|
+
if: steps.version.outputs.changed == 'true'
|
|
40
|
+
|
|
41
|
+
- run: npm publish --access public
|
|
42
|
+
if: steps.version.outputs.changed == 'true'
|
|
43
|
+
env:
|
|
44
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/README.md
CHANGED
|
@@ -1,43 +1,440 @@
|
|
|
1
|
-
# Smart Report
|
|
1
|
+
# Smart Report Plugin for OpenClaw
|
|
2
2
|
|
|
3
|
-
Plugin
|
|
3
|
+
Plugin OpenClaw untuk integrasi ke ekosistem **Smart Report** melalui:
|
|
4
|
+
- **CLI commands** untuk autentikasi dan health check
|
|
5
|
+
- **chat/native commands** untuk akses cepat dari runtime OpenClaw
|
|
6
|
+
- **resources** untuk expose data Smart Report ke agent/runtime
|
|
7
|
+
- **tools** untuk reasoning agent berbasis data Smart Report
|
|
8
|
+
- **plugin skill** agar output ke user tetap rapi dan tidak menampilkan JSON mentah
|
|
9
|
+
|
|
10
|
+
README ini sudah disesuaikan dengan **alur code terbaru** di source saat ini, **termasuk perilaku `install.sh` terbaru**.
|
|
11
|
+
|
|
12
|
+
## Ringkasan alur terbaru
|
|
13
|
+
|
|
14
|
+
Plugin melakukan registrasi pada saat `register(api)` / `activate(api)` dipanggil, lalu:
|
|
15
|
+
|
|
16
|
+
1. mendaftarkan **CLI commands**
|
|
17
|
+
2. mendaftarkan **chat commands** bila runtime mendukung `registerCommand`
|
|
18
|
+
3. mendaftarkan **resources**
|
|
19
|
+
4. mendaftarkan **tools**
|
|
20
|
+
|
|
21
|
+
Struktur registrasi utama ada di `src/index.ts`:
|
|
22
|
+
- `registerCommands(api)`
|
|
23
|
+
- `registerResources(api)`
|
|
24
|
+
- `registerTools(api)`
|
|
25
|
+
|
|
26
|
+
## Struktur plugin
|
|
27
|
+
|
|
28
|
+
```text
|
|
29
|
+
smart-report-plugin/
|
|
30
|
+
├── package.json
|
|
31
|
+
├── openclaw.plugin.json
|
|
32
|
+
├── openclaw.cjs
|
|
33
|
+
├── index.js
|
|
34
|
+
├── install.sh
|
|
35
|
+
├── src/
|
|
36
|
+
│ ├── client.ts
|
|
37
|
+
│ ├── commands.ts
|
|
38
|
+
│ ├── resources.ts
|
|
39
|
+
│ ├── tools.ts
|
|
40
|
+
│ └── index.ts
|
|
41
|
+
├── dist/
|
|
42
|
+
│ ├── client.js
|
|
43
|
+
│ ├── commands.js
|
|
44
|
+
│ ├── resources.js
|
|
45
|
+
│ ├── tools.js
|
|
46
|
+
│ ├── index.js
|
|
47
|
+
│ └── openclaw.cjs
|
|
48
|
+
├── skills/
|
|
49
|
+
│ └── smart-report/
|
|
50
|
+
│ └── SKILL.md
|
|
51
|
+
├── docs/
|
|
52
|
+
│ └── USER_GUIDE.md
|
|
53
|
+
└── scripts/
|
|
54
|
+
└── test-loader.js
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Requirement
|
|
58
|
+
|
|
59
|
+
- OpenClaw terpasang dan bisa menjalankan `openclaw`
|
|
60
|
+
- Node.js dan npm tersedia
|
|
61
|
+
- Token API Smart Report valid
|
|
62
|
+
- Runtime/plugin manager OpenClaw mengizinkan install plugin dari source repository
|
|
63
|
+
|
|
64
|
+
## Instalasi
|
|
65
|
+
|
|
66
|
+
### Opsi 1 — dari source repo lokal
|
|
67
|
+
|
|
68
|
+
Jika repo ini sudah ada di mesin:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
bash install.sh
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Opsi 2 — install via OpenClaw plugin manager dari path repo
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
openclaw plugins install /path/ke/smart-report-plugin
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Opsi 3 — installer via raw GitHub
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
bash <(curl -fsSL https://raw.githubusercontent.com/sodikinnaa/smart-report-plugin/master/install.sh)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Alur installer terbaru
|
|
87
|
+
|
|
88
|
+
`install.sh` sekarang mengikuti alur berikut:
|
|
89
|
+
|
|
90
|
+
1. clone repository source
|
|
91
|
+
2. menjalankan `npm ci` atau fallback `npm install`
|
|
92
|
+
3. build plugin dengan `npm run build`
|
|
93
|
+
4. validasi file penting plugin
|
|
94
|
+
5. install plugin lewat **official OpenClaw plugin manager**:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
openclaw plugins install <path-repo>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
6. **tidak fallback** ke copy manual ke `~/.openclaw/extensions`
|
|
101
|
+
7. bila gagal karena plugin lama sudah ada, installer akan:
|
|
102
|
+
- backup plugin lama
|
|
103
|
+
- retry install resmi **satu kali**
|
|
104
|
+
8. gateway **tidak di-restart otomatis secara default**
|
|
105
|
+
|
|
106
|
+
Tujuan alur ini adalah menjaga provenance/trust plugin tetap bersih dan menghindari state plugin local yang tidak ter-track.
|
|
107
|
+
|
|
108
|
+
## Opsi installer
|
|
109
|
+
|
|
110
|
+
Contoh penggunaan:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
bash install.sh
|
|
114
|
+
bash install.sh --branch main
|
|
115
|
+
bash install.sh --repo https://github.com/sodikinnaa/smart-report-plugin.git
|
|
116
|
+
bash install.sh --token <GITHUB_TOKEN>
|
|
117
|
+
bash install.sh --skip-build
|
|
118
|
+
bash install.sh --restart
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Opsi yang tersedia:
|
|
122
|
+
- `--repo <url>` → URL git source plugin
|
|
123
|
+
- `--branch <name>` → branch/tag yang akan di-clone
|
|
124
|
+
- `--target <path>` → reserved untuk diagnostik; bukan jalur manual install utama
|
|
125
|
+
- `--token <token>` → GitHub token untuk private repo, atau gunakan env `GITHUB_TOKEN`
|
|
126
|
+
- `--skip-build` → lewati `npm install` dan `npm run build`
|
|
127
|
+
- `--restart` → restart `openclaw gateway` setelah install
|
|
128
|
+
- `--no-restart` → alias legacy; restart tetap di-skip secara default
|
|
129
|
+
|
|
130
|
+
## Batasan penting install.sh
|
|
131
|
+
|
|
132
|
+
Perilaku script saat ini:
|
|
133
|
+
- **wajib** ada command `git`, `node`, `npm`, dan `openclaw`
|
|
134
|
+
- installer ini **hanya mendukung install via OpenClaw plugin manager**
|
|
135
|
+
- script **tidak** publish ke npm dan **tidak** install dari package npm
|
|
136
|
+
- jika `openclaw` tidak ditemukan, proses akan dihentikan
|
|
137
|
+
- jika install via `openclaw plugins install` gagal karena alasan selain plugin lama sudah ada, script akan **stop** dan meminta environment OpenClaw diperbaiki dulu
|
|
138
|
+
|
|
139
|
+
Artinya, `install.sh` memang sengaja dibuat konservatif supaya tidak menghasilkan plugin local yang untracked atau bermasalah secara provenance.
|
|
140
|
+
|
|
141
|
+
## Build & test
|
|
4
142
|
|
|
5
|
-
## 🚀 Quick Start
|
|
6
143
|
```bash
|
|
7
|
-
|
|
8
|
-
|
|
144
|
+
npm test
|
|
145
|
+
npm run build
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Script yang tersedia di `package.json`:
|
|
149
|
+
- `npm run build`
|
|
150
|
+
- `npm test`
|
|
151
|
+
- `npm run publish`
|
|
152
|
+
|
|
153
|
+
## Konfigurasi plugin
|
|
154
|
+
|
|
155
|
+
Manifest `openclaw.plugin.json` mendeklarasikan config berikut:
|
|
156
|
+
|
|
157
|
+
- `apiToken`
|
|
158
|
+
- `companyName`
|
|
159
|
+
- `companyDomain`
|
|
160
|
+
|
|
161
|
+
Contoh shape config:
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"apiToken": "TOKEN_SMART_REPORT",
|
|
166
|
+
"companyName": "Nama Perusahaan",
|
|
167
|
+
"companyDomain": "member.smartreport.my.id"
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Cara autentikasi
|
|
172
|
+
|
|
173
|
+
Setelah plugin ter-install, jalankan:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
openclaw smart-auth <TOKEN_ANDA>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Perilaku `smart-auth` di code terbaru:
|
|
180
|
+
- token disimpan ke `api.pluginConfig` saat runtime berjalan
|
|
181
|
+
- plugin mencoba verifikasi token dengan memanggil `company/info`
|
|
182
|
+
- jika sukses, plugin menyimpan:
|
|
183
|
+
- `apiToken`
|
|
184
|
+
- `companyName`
|
|
185
|
+
- `companyDomain`
|
|
186
|
+
- jika `api.saveConfig()` tersedia, plugin memakai mekanisme save resmi runtime
|
|
187
|
+
- jika tidak tersedia, plugin fallback ke update file config OpenClaw yang ditemukan
|
|
188
|
+
|
|
189
|
+
Candidate config path yang dicoba oleh plugin:
|
|
190
|
+
- `~/.openclaw/openclaw.json`
|
|
191
|
+
- `~/.openclaw/config.json`
|
|
192
|
+
- `/root/.openclaw/openclaw.json`
|
|
193
|
+
- `/root/.openclaw/config.json`
|
|
194
|
+
- `/etc/openclaw/openclaw.json`
|
|
195
|
+
- `/etc/openclaw/config.json`
|
|
196
|
+
|
|
197
|
+
## Cara cek konektivitas
|
|
198
|
+
|
|
199
|
+
Untuk health check end-to-end, jalankan:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
openclaw smart-status
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Status check saat ini menguji method berikut:
|
|
206
|
+
- `company/info`
|
|
207
|
+
- `smartreport/dashboard`
|
|
208
|
+
- `employees/list`
|
|
209
|
+
- `reports/list`
|
|
210
|
+
- `divisions/list`
|
|
211
|
+
- `guides/list`
|
|
212
|
+
- `analyze_performance`
|
|
213
|
+
|
|
214
|
+
Jika ada check gagal, command akan exit dengan status non-zero.
|
|
215
|
+
|
|
216
|
+
## CLI commands yang tersedia
|
|
9
217
|
|
|
10
|
-
|
|
11
|
-
openclaw smart-auth YOUR_SECRET_TOKEN
|
|
218
|
+
Plugin saat ini mendaftarkan 2 CLI command:
|
|
12
219
|
|
|
13
|
-
|
|
220
|
+
- `openclaw smart-auth <token>`
|
|
221
|
+
- `openclaw smart-status`
|
|
222
|
+
|
|
223
|
+
## Chat/native commands yang tersedia
|
|
224
|
+
|
|
225
|
+
Jika runtime OpenClaw mendukung `registerCommand`, plugin akan mendaftarkan command berikut:
|
|
226
|
+
|
|
227
|
+
- `/smart_status`
|
|
228
|
+
- `/smart_dashboard`
|
|
229
|
+
- `/smart_dashboard_raw`
|
|
230
|
+
- `/smart_employees`
|
|
231
|
+
- `/smart_employees_raw`
|
|
232
|
+
- `/smart_reports`
|
|
233
|
+
- `/smart_reports_raw`
|
|
234
|
+
- `/smart_divisions`
|
|
235
|
+
- `/smart_divisions_raw`
|
|
236
|
+
- `/smart_guides`
|
|
237
|
+
- `/smart_guides_raw`
|
|
238
|
+
- `/smart_guide`
|
|
239
|
+
- `/smart_guide_raw`
|
|
240
|
+
- `/smart_analysis`
|
|
241
|
+
- `/smart_analysis_raw`
|
|
242
|
+
|
|
243
|
+
### Catatan penting nama command
|
|
244
|
+
|
|
245
|
+
Di code terbaru, nama chat command memakai **underscore**, bukan dash.
|
|
246
|
+
|
|
247
|
+
Benar:
|
|
248
|
+
- `/smart_status`
|
|
249
|
+
- `/smart_dashboard`
|
|
250
|
+
|
|
251
|
+
Bukan:
|
|
252
|
+
- `/smart-status`
|
|
253
|
+
- `/smart-dashboard`
|
|
254
|
+
|
|
255
|
+
## Format argumen command
|
|
256
|
+
|
|
257
|
+
Command chat membaca `ctx.args` lalu mencoba parsing dengan alur berikut:
|
|
258
|
+
|
|
259
|
+
1. jika kosong → `{}`
|
|
260
|
+
2. jika valid JSON object → dipakai langsung
|
|
261
|
+
3. jika valid JSON tapi bukan object → dibungkus sebagai `{ "input": ... }`
|
|
262
|
+
4. jika bukan JSON → dibungkus sebagai `{ "input": "teks-raw" }`
|
|
263
|
+
|
|
264
|
+
Contoh:
|
|
265
|
+
|
|
266
|
+
```text
|
|
267
|
+
/smart_reports {"per_page":5}
|
|
268
|
+
/smart_guide {"id":12}
|
|
269
|
+
/smart_dashboard {"mode":"compact"}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Tools yang didaftarkan
|
|
273
|
+
|
|
274
|
+
Plugin saat ini mendaftarkan tool berikut:
|
|
275
|
+
|
|
276
|
+
- `get_daily_dashboard`
|
|
277
|
+
- `get_guides_list`
|
|
278
|
+
- `get_guide_content`
|
|
279
|
+
- `get_list_reports`
|
|
280
|
+
- `get_reports_summary`
|
|
281
|
+
- `get_report_detail`
|
|
282
|
+
- `get_debt_analysis`
|
|
283
|
+
|
|
284
|
+
Semua tool memanggil backend MCP lalu mengembalikan hasil JSON dalam field `text`.
|
|
285
|
+
|
|
286
|
+
Catatan:
|
|
287
|
+
- tool memang ditujukan untuk **reasoning internal agent**
|
|
288
|
+
- output ke user sebaiknya dirapikan terlebih dahulu
|
|
289
|
+
- skill `smart-report` sebaiknya dipakai agar agent tidak menampilkan JSON mentah ke user
|
|
290
|
+
|
|
291
|
+
## Resources yang didaftarkan
|
|
292
|
+
|
|
293
|
+
Plugin mendaftarkan resource berikut:
|
|
294
|
+
|
|
295
|
+
- `smartreport://reports`
|
|
296
|
+
- `smartreport://employees`
|
|
297
|
+
- `smartreport://divisions`
|
|
298
|
+
- `smartreport://guides`
|
|
299
|
+
- `smartreport://dashboard`
|
|
300
|
+
|
|
301
|
+
Semua resource saat ini mengembalikan `application/json`.
|
|
302
|
+
|
|
303
|
+
## Method MCP yang dipakai plugin
|
|
304
|
+
|
|
305
|
+
Source `src/client.ts` saat ini memanggil endpoint:
|
|
306
|
+
|
|
307
|
+
```text
|
|
308
|
+
https://member.smartreport.my.id/api/mcp
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Method MCP yang dipakai di berbagai command/resource/tool:
|
|
312
|
+
- `company/info`
|
|
313
|
+
- `smartreport/dashboard`
|
|
314
|
+
- `employees/list`
|
|
315
|
+
- `reports/list`
|
|
316
|
+
- `divisions/list`
|
|
317
|
+
- `guides/list`
|
|
318
|
+
- `guides/get`
|
|
319
|
+
- `analyze_performance`
|
|
320
|
+
|
|
321
|
+
## Token resolution flow
|
|
322
|
+
|
|
323
|
+
Saat melakukan request, plugin mencari token dengan urutan:
|
|
324
|
+
|
|
325
|
+
1. `api.pluginConfig.apiToken`
|
|
326
|
+
2. `api.config.apiToken`
|
|
327
|
+
3. `api.config.plugins.entries.smart-report-plugin.config.apiToken`
|
|
328
|
+
|
|
329
|
+
Jika token tidak ditemukan, plugin akan melempar error:
|
|
330
|
+
|
|
331
|
+
```text
|
|
332
|
+
API token not found. Jalankan "openclaw smart-auth <token>" terlebih dahulu.
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## Kompatibilitas runtime OpenClaw terbaru
|
|
336
|
+
|
|
337
|
+
Pada runtime OpenClaw yang lebih baru, command chat/native harus memakai field:
|
|
338
|
+
- `handler`
|
|
339
|
+
- bukan `execute`
|
|
340
|
+
|
|
341
|
+
Plugin ini sudah mengikuti pola tersebut dan juga menyetel:
|
|
342
|
+
- `acceptsArgs: true`
|
|
343
|
+
|
|
344
|
+
Selain itu, proses registrasi chat command dibungkus `try/catch` agar kegagalan registrasi tidak ikut menjatuhkan startup plugin secara keseluruhan.
|
|
345
|
+
|
|
346
|
+
## Verifikasi setelah install
|
|
347
|
+
|
|
348
|
+
Langkah verifikasi yang direkomendasikan:
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
openclaw plugins list --verbose
|
|
352
|
+
openclaw smart-auth <TOKEN_SMART_REPORT>
|
|
14
353
|
openclaw smart-status
|
|
15
354
|
```
|
|
16
355
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
356
|
+
Output akhir `install.sh` juga memang mengarahkan verifikasi ke alur ini, lalu menyarankan pengujian chat command bila runtime mendukung native command.
|
|
357
|
+
|
|
358
|
+
Jika runtime mendukung chat/native command, lanjut uji:
|
|
359
|
+
|
|
360
|
+
```text
|
|
361
|
+
/smart_status
|
|
362
|
+
/smart_dashboard {"mode":"compact"}
|
|
363
|
+
/smart_reports {"per_page":5}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
## Dokumentasi tambahan
|
|
367
|
+
|
|
368
|
+
- `docs/USER_GUIDE.md`
|
|
369
|
+
- `docs/AGENT_SESSION_MCP_TROUBLESHOOTING.md`
|
|
370
|
+
|
|
371
|
+
## Troubleshooting
|
|
372
|
+
|
|
373
|
+
### 1. Plugin gagal install
|
|
374
|
+
|
|
375
|
+
Cek:
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
openclaw plugins list --verbose
|
|
379
|
+
openclaw plugins doctor
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Kemungkinan penyebab:
|
|
383
|
+
- trust/provenance plugin belum valid
|
|
384
|
+
- plugin lama masih tercatat
|
|
385
|
+
- policy OpenClaw menolak install source tertentu
|
|
386
|
+
|
|
387
|
+
### 2. Auth gagal
|
|
388
|
+
|
|
389
|
+
Pastikan:
|
|
390
|
+
- token valid
|
|
391
|
+
- endpoint Smart Report bisa diakses
|
|
392
|
+
- backend menerima Bearer token
|
|
393
|
+
|
|
394
|
+
Ulangi:
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
openclaw smart-auth <TOKEN_ANDA>
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### 3. Command chat tidak muncul
|
|
401
|
+
|
|
402
|
+
Kemungkinan:
|
|
403
|
+
- runtime tidak menyediakan `registerCommand`
|
|
404
|
+
- channel/runtime tidak mendukung native command plugin
|
|
405
|
+
- ada error registrasi command saat startup
|
|
406
|
+
|
|
407
|
+
### 4. Tool mengembalikan error
|
|
408
|
+
|
|
409
|
+
Cek apakah token sudah tersimpan dan method MCP yang dipanggil memang tersedia di backend.
|
|
410
|
+
|
|
411
|
+
## Manifest & metadata saat ini
|
|
412
|
+
|
|
413
|
+
`package.json`
|
|
414
|
+
- package name: `@sodikinnaa/smart-report-plugin`
|
|
415
|
+
- version: `2100.11.6`
|
|
416
|
+
|
|
417
|
+
`openclaw.plugin.json`
|
|
418
|
+
- plugin id: `smart-report-plugin`
|
|
419
|
+
- name: `Smart Report Integration`
|
|
420
|
+
- version: `2100.11.6`
|
|
421
|
+
- entrypoint: `./index.js`
|
|
27
422
|
|
|
423
|
+
## Catatan desain
|
|
28
424
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
425
|
+
- registrasi dipisah per concern: `commands`, `resources`, `tools`, `client`
|
|
426
|
+
- `client.ts` menangani auth, persistence config, dan call MCP
|
|
427
|
+
- `commands.ts` menangani CLI + chat command
|
|
428
|
+
- `resources.ts` expose dataset Smart Report sebagai resource JSON
|
|
429
|
+
- `tools.ts` expose method penting untuk reasoning agent
|
|
430
|
+
- skill plugin disediakan di folder `./skills`
|
|
32
431
|
|
|
33
|
-
##
|
|
34
|
-
* **MCP Integration:** Mendukung standar Model Context Protocol.
|
|
35
|
-
* **KPI Dashboard:** Data agregasi harian (Compact/Full/Ops mode).
|
|
36
|
-
* **Deep Analysis:** Tool untuk mendeteksi "Debt Performance" karyawan.
|
|
37
|
-
* **Division Aware:** Data karyawan sekarang sudah menyertakan nama divisi.
|
|
432
|
+
## Rekomendasi penggunaan
|
|
38
433
|
|
|
39
|
-
|
|
40
|
-
|
|
434
|
+
Gunakan:
|
|
435
|
+
- **CLI command** untuk setup awal dan health check
|
|
436
|
+
- **chat command** untuk akses cepat/manual dari runtime
|
|
437
|
+
- **tools** untuk analisis oleh agent
|
|
438
|
+
- **skill** untuk merapikan output akhir ke user
|
|
41
439
|
|
|
42
|
-
|
|
43
|
-
*Powered by Sultan Engine*
|
|
440
|
+
Kalau ingin menjaga UX tetap bagus, jangan tampilkan raw JSON ke end-user kecuali memang untuk debugging.
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const PLUGIN_ID = "smart-report-plugin";
|
|
2
|
+
export declare const API_BASE = "https://member.smartreport.my.id/api/mcp";
|
|
3
|
+
export type SmartReportApi = {
|
|
4
|
+
pluginConfig?: Record<string, unknown>;
|
|
5
|
+
config?: any;
|
|
6
|
+
saveConfig?: (config: Record<string, unknown>) => Promise<void> | void;
|
|
7
|
+
};
|
|
8
|
+
export declare function resolveToken(api: SmartReportApi): string | undefined;
|
|
9
|
+
export declare function savePluginConfig(api: SmartReportApi, config: {
|
|
10
|
+
apiToken: string;
|
|
11
|
+
companyName?: string;
|
|
12
|
+
companyDomain?: string;
|
|
13
|
+
}): Promise<void>;
|
|
14
|
+
export declare function callMcp(api: SmartReportApi, method: string, params?: Record<string, unknown>): Promise<any>;
|
|
15
|
+
export declare function normalizeToolError(error: unknown): {
|
|
16
|
+
error: string;
|
|
17
|
+
};
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.API_BASE = exports.PLUGIN_ID = void 0;
|
|
7
|
+
exports.resolveToken = resolveToken;
|
|
8
|
+
exports.savePluginConfig = savePluginConfig;
|
|
9
|
+
exports.callMcp = callMcp;
|
|
10
|
+
exports.normalizeToolError = normalizeToolError;
|
|
11
|
+
const axios_1 = __importDefault(require("axios"));
|
|
12
|
+
const fs_1 = __importDefault(require("fs"));
|
|
13
|
+
const os_1 = __importDefault(require("os"));
|
|
14
|
+
const path_1 = __importDefault(require("path"));
|
|
15
|
+
exports.PLUGIN_ID = 'smart-report-plugin';
|
|
16
|
+
exports.API_BASE = 'https://member.smartreport.my.id/api/mcp';
|
|
17
|
+
function resolveToken(api) {
|
|
18
|
+
const pluginToken = api?.pluginConfig?.apiToken;
|
|
19
|
+
if (typeof pluginToken === 'string' && pluginToken.trim())
|
|
20
|
+
return pluginToken;
|
|
21
|
+
const configToken = api?.config?.apiToken;
|
|
22
|
+
if (typeof configToken === 'string' && configToken.trim())
|
|
23
|
+
return configToken;
|
|
24
|
+
const nestedToken = api?.config?.plugins?.entries?.[exports.PLUGIN_ID]?.config?.apiToken;
|
|
25
|
+
if (typeof nestedToken === 'string' && nestedToken.trim())
|
|
26
|
+
return nestedToken;
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
function getCandidateConfigPaths() {
|
|
30
|
+
const home = os_1.default.homedir();
|
|
31
|
+
return [
|
|
32
|
+
path_1.default.join(home, '.openclaw', 'openclaw.json'),
|
|
33
|
+
path_1.default.join(home, '.openclaw', 'config.json'),
|
|
34
|
+
'/root/.openclaw/openclaw.json',
|
|
35
|
+
'/root/.openclaw/config.json',
|
|
36
|
+
'/etc/openclaw/openclaw.json',
|
|
37
|
+
'/etc/openclaw/config.json',
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
function persistPluginConfigToFile(config) {
|
|
41
|
+
const configPath = getCandidateConfigPaths().find((candidate) => fs_1.default.existsSync(candidate));
|
|
42
|
+
if (!configPath) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const raw = fs_1.default.readFileSync(configPath, 'utf8');
|
|
46
|
+
const parsed = JSON.parse(raw || '{}');
|
|
47
|
+
parsed.plugins = parsed.plugins || {};
|
|
48
|
+
parsed.plugins.entries = parsed.plugins.entries || {};
|
|
49
|
+
const previousEntry = parsed.plugins.entries[exports.PLUGIN_ID] && typeof parsed.plugins.entries[exports.PLUGIN_ID] === 'object'
|
|
50
|
+
? parsed.plugins.entries[exports.PLUGIN_ID]
|
|
51
|
+
: {};
|
|
52
|
+
const previousConfig = previousEntry.config && typeof previousEntry.config === 'object'
|
|
53
|
+
? previousEntry.config
|
|
54
|
+
: {};
|
|
55
|
+
parsed.plugins.entries[exports.PLUGIN_ID] = {
|
|
56
|
+
...previousEntry,
|
|
57
|
+
enabled: true,
|
|
58
|
+
config: {
|
|
59
|
+
...previousConfig,
|
|
60
|
+
...config,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
fs_1.default.writeFileSync(configPath, JSON.stringify(parsed, null, 2));
|
|
64
|
+
}
|
|
65
|
+
async function savePluginConfig(api, config) {
|
|
66
|
+
if (typeof api.saveConfig === 'function') {
|
|
67
|
+
await api.saveConfig(config);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
api.pluginConfig = {
|
|
71
|
+
...(api.pluginConfig || {}),
|
|
72
|
+
...config,
|
|
73
|
+
};
|
|
74
|
+
persistPluginConfigToFile(config);
|
|
75
|
+
}
|
|
76
|
+
async function callMcp(api, method, params = {}) {
|
|
77
|
+
const token = resolveToken(api);
|
|
78
|
+
if (!token) {
|
|
79
|
+
throw new Error('API token not found. Jalankan "openclaw smart-auth <token>" terlebih dahulu.');
|
|
80
|
+
}
|
|
81
|
+
const response = await axios_1.default.post(exports.API_BASE, {
|
|
82
|
+
jsonrpc: '2.0',
|
|
83
|
+
method,
|
|
84
|
+
params,
|
|
85
|
+
id: Date.now(),
|
|
86
|
+
}, {
|
|
87
|
+
headers: {
|
|
88
|
+
Authorization: `Bearer ${token}`,
|
|
89
|
+
'Content-Type': 'application/json',
|
|
90
|
+
Accept: 'application/json',
|
|
91
|
+
},
|
|
92
|
+
timeout: 8000,
|
|
93
|
+
});
|
|
94
|
+
if (response.data?.error?.message) {
|
|
95
|
+
throw new Error(String(response.data.error.message));
|
|
96
|
+
}
|
|
97
|
+
return response.data?.result;
|
|
98
|
+
}
|
|
99
|
+
function normalizeToolError(error) {
|
|
100
|
+
if (error instanceof Error) {
|
|
101
|
+
return { error: error.message };
|
|
102
|
+
}
|
|
103
|
+
return { error: 'Unknown Smart Report plugin error' };
|
|
104
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SmartReportApi } from './client';
|
|
2
|
+
type CommandApi = SmartReportApi & {
|
|
3
|
+
logger?: {
|
|
4
|
+
info?: (message: string) => void;
|
|
5
|
+
warn?: (message: string) => void;
|
|
6
|
+
error?: (message: string) => void;
|
|
7
|
+
debug?: (message: string) => void;
|
|
8
|
+
};
|
|
9
|
+
registerCli?: Function;
|
|
10
|
+
registerCommand?: Function;
|
|
11
|
+
};
|
|
12
|
+
export declare function registerCommands(api: CommandApi): void;
|
|
13
|
+
export {};
|