@ryuu-reinzz/ryuu-cli 0.5.1 → 0.5.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/CHANGELOG.md +17 -0
- package/docs/github.md +10 -4
- package/package.json +1 -1
- package/plugins/github/README.md +14 -7
- package/plugins/github/tools-repos.js +38 -0
- package/src/cli/commands.js +46 -4
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,23 @@
|
|
|
3
3
|
Semua perubahan penting pada Ryuu Agent CLI didokumentasikan di sini.
|
|
4
4
|
Project ini mengikuti [Semantic Versioning](https://semver.org/).
|
|
5
5
|
|
|
6
|
+
## [0.5.2] - 2026-11-03
|
|
7
|
+
|
|
8
|
+
### Ditambahkan
|
|
9
|
+
|
|
10
|
+
- **`github_delete_repository`** — menghapus repository GitHub secara permanen.
|
|
11
|
+
Berisiko `destructive`, selalu melewati approval Ryuu, dan hanya berjalan bila
|
|
12
|
+
argumen `confirm` berisi `owner/repo` yang sama persis. Bisa dimatikan dengan
|
|
13
|
+
`/github config set confirmDestructive false`.
|
|
14
|
+
- **Panduan `/github` dan `/drive` di `/help`** — `/help` kini menampilkan daftar
|
|
15
|
+
subcommand kedua plugin selama plugin dimuat, dan `/help drive` menampilkan
|
|
16
|
+
tutorial seperti `/help github`.
|
|
17
|
+
|
|
18
|
+
### Diubah
|
|
19
|
+
|
|
20
|
+
- Safelist proxy backend menerima `DELETE /repos/{owner}/{repo}` khusus untuk
|
|
21
|
+
tool penghapusan repository; endpoint DELETE lain tetap ditolak.
|
|
22
|
+
|
|
6
23
|
## [0.5.1] - 2026-11-03
|
|
7
24
|
|
|
8
25
|
Rilis ini menambahkan integrasi GitHub App sebagai plugin opsional, dengan
|
package/docs/github.md
CHANGED
|
@@ -6,7 +6,7 @@ integrasi GitHub pada Ryuu CLI. Integrasi terdiri dari dua bagian:
|
|
|
6
6
|
1. **Backend** (`/root/website/api`, modul `lib/github/`) — Integration Gateway
|
|
7
7
|
yang memegang seluruh kredensial GitHub App dan token pengguna.
|
|
8
8
|
2. **Plugin CLI** (`/root/agents/ryuu/plugins/github/`) — command `/github` dan
|
|
9
|
-
|
|
9
|
+
36 tool AI yang memanggil GitHub melalui gateway.
|
|
10
10
|
|
|
11
11
|
Tidak ada Client Secret, Private Key, Webhook Secret, access token, atau refresh
|
|
12
12
|
token di sisi CLI. CLI hanya memegang `cliToken` per akun yang disimpan
|
|
@@ -274,7 +274,7 @@ halaman instalasi App.
|
|
|
274
274
|
| Kelompok | Tool |
|
|
275
275
|
| --- | --- |
|
|
276
276
|
| Akun | `github_get_me`, `github_get_user`, `github_get_rate_limit` |
|
|
277
|
-
| Repository | `github_list_repositories`, `github_get_repository`, `github_create_repository`, `github_update_repository`, `github_list_branches`, `github_get_branch`, `github_list_commits`, `github_get_commit`, `github_get_file_contents`, `github_create_or_update_file`, `github_delete_file`, `github_compare_commits` |
|
|
277
|
+
| Repository | `github_list_repositories`, `github_get_repository`, `github_create_repository`, `github_update_repository`, `github_delete_repository`, `github_list_branches`, `github_get_branch`, `github_list_commits`, `github_get_commit`, `github_get_file_contents`, `github_create_or_update_file`, `github_delete_file`, `github_compare_commits` |
|
|
278
278
|
| Issue | `github_list_issues`, `github_get_issue`, `github_create_issue`, `github_update_issue`, `github_comment_issue`, `github_list_issue_comments` |
|
|
279
279
|
| Pull request | `github_list_pull_requests`, `github_get_pull_request`, `github_create_pull_request`, `github_update_pull_request`, `github_merge_pull_request`, `github_list_pull_request_files`, `github_review_pull_request` |
|
|
280
280
|
| Release | `github_list_releases`, `github_get_release`, `github_create_release` |
|
|
@@ -286,14 +286,20 @@ autentikasi, pembatasan output, dan deskripsi permission yang dibutuhkan.
|
|
|
286
286
|
Operasi yang mengubah data selalu melewati approval Ryuu:
|
|
287
287
|
|
|
288
288
|
- membuat/mengubah repository;
|
|
289
|
+
- menghapus repository;
|
|
289
290
|
- membuat/mengubah/menghapus file;
|
|
290
291
|
- membuat/mengubah issue dan komentar;
|
|
291
292
|
- membuat/mengubah/merge pull request dan review;
|
|
292
293
|
- membuat release;
|
|
293
294
|
- menjalankan ulang workflow.
|
|
294
295
|
|
|
295
|
-
`github_delete_file` dan `
|
|
296
|
-
`confirmDestructive: false` memblokirnya sepenuhnya.
|
|
296
|
+
`github_delete_file`, `github_merge_pull_request`, dan `github_delete_repository`
|
|
297
|
+
berisiko `destructive`. `confirmDestructive: false` memblokirnya sepenuhnya.
|
|
298
|
+
|
|
299
|
+
`github_delete_repository` adalah satu-satunya tool yang menghapus repository.
|
|
300
|
+
Selain approval Ryuu, handler-nya menuntut argumen `confirm` berisi
|
|
301
|
+
`owner/repo` yang sama persis, sehingga model tidak bisa menghapus repository
|
|
302
|
+
tanpa token konfirmasi eksplisit dari pengguna:
|
|
297
303
|
|
|
298
304
|
---
|
|
299
305
|
|
package/package.json
CHANGED
package/plugins/github/README.md
CHANGED
|
@@ -35,7 +35,7 @@ CLI menyimpan cliToken terenkripsi, lalu semua tools lewat backend.
|
|
|
35
35
|
| `auth.js` | Membuka browser + pesan kegagalan login |
|
|
36
36
|
| `backend.js` | HTTP client ke backend (connect, session, status, proxy) |
|
|
37
37
|
| `api.js` | Klien GitHub REST melalui gateway + pagination |
|
|
38
|
-
| `tools*.js` |
|
|
38
|
+
| `tools*.js` | 36 tool AI, dikelompokkan per domain |
|
|
39
39
|
| `tool-helpers.js` | Validasi owner/repo/ref/path + pembatasan output |
|
|
40
40
|
| `errors.js` | Error plugin + kode yang stabil |
|
|
41
41
|
| `command.js` | Handler `/github` |
|
|
@@ -85,12 +85,13 @@ dapat diubah dari CLI dan tidak pernah ditulis ke file konfigurasi.
|
|
|
85
85
|
menampilkan Client Secret, Private Key, Webhook Secret, access token, refresh
|
|
86
86
|
token, atau `cliToken`.
|
|
87
87
|
|
|
88
|
-
## Tool yang tersedia (
|
|
88
|
+
## Tool yang tersedia (36)
|
|
89
89
|
|
|
90
90
|
**Akun (3)** — `github_get_me`, `github_get_user`, `github_get_rate_limit`
|
|
91
91
|
|
|
92
|
-
**Repository (
|
|
93
|
-
`github_create_repository`, `github_update_repository`,
|
|
92
|
+
**Repository (13)** — `github_list_repositories`, `github_get_repository`,
|
|
93
|
+
`github_create_repository`, `github_update_repository`,
|
|
94
|
+
`github_delete_repository`, `github_list_branches`,
|
|
94
95
|
`github_get_branch`, `github_list_commits`, `github_get_commit`,
|
|
95
96
|
`github_get_file_contents`, `github_create_or_update_file`,
|
|
96
97
|
`github_delete_file`, `github_compare_commits`
|
|
@@ -111,15 +112,21 @@ token, atau `cliToken`.
|
|
|
111
112
|
`github_list_workflow_runs`, `github_get_workflow_run`,
|
|
112
113
|
`github_rerun_workflow`
|
|
113
114
|
|
|
114
|
-
|
|
115
|
-
|
|
115
|
+
`github_delete_repository` menghapus repository secara permanen dan hanya
|
|
116
|
+
berjalan bila argumen `confirm` berisi `owner/repo` yang sama persis; proxy
|
|
117
|
+
backend baru mengizinkannya lewat safelist `DELETE /repos/{owner}/{repo}`.
|
|
118
|
+
Penghapusan repository, penghapusan file, dan merge pull request berisiko
|
|
119
|
+
`destructive` dan selalu melewati approval Ryuu.
|
|
116
120
|
|
|
117
121
|
## Approval & keamanan
|
|
118
122
|
|
|
119
123
|
- `risk: read` berjalan tanpa prompt.
|
|
120
124
|
- Semua tool `write` memakai `requiresApproval: true`.
|
|
121
|
-
- `github_delete_file
|
|
125
|
+
- `github_delete_file`, `github_merge_pull_request`, dan
|
|
126
|
+
`github_delete_repository` memakai
|
|
122
127
|
`risk: destructive` (approval wajib).
|
|
128
|
+
- `github_delete_repository` menuntut `confirm` = `owner/repo`; nilai lain
|
|
129
|
+
ditolak sebagai `VALIDATION_FAILED` sebelum request dibuat.
|
|
123
130
|
- `confirmDestructive: false` memblokir operasi destruktif di handler, bukan
|
|
124
131
|
hanya mengandalkan prompt.
|
|
125
132
|
- Tool memanggil `plugin.requireClient()` setiap kali, sehingga model yang
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { defineTool } from '../../src/tools/registry.js';
|
|
2
|
+
import { ValidationError } from '../../src/utils/errors.js';
|
|
2
3
|
import {
|
|
3
4
|
assertDestructiveAllowed,
|
|
4
5
|
contentPath,
|
|
@@ -129,6 +130,43 @@ export function createRepoTools(plugin) {
|
|
|
129
130
|
},
|
|
130
131
|
}),
|
|
131
132
|
|
|
133
|
+
defineTool({
|
|
134
|
+
name: 'github_delete_repository',
|
|
135
|
+
description:
|
|
136
|
+
'Hapus repository secara permanen. Membutuhkan permission Administration write dan hak admin pada repository. Argumen confirm wajib berisi "owner/repo" persis sama; tanpa itu tool menolak. Operasi ini destruktif: selalu meminta approval Ryuu dan diblokir saat confirmDestructive=false. Jangan pernah dipanggil tanpa persetujuan eksplisit pengguna.',
|
|
137
|
+
risk: 'destructive',
|
|
138
|
+
requiresApproval: true,
|
|
139
|
+
schema: {
|
|
140
|
+
type: 'object',
|
|
141
|
+
properties: {
|
|
142
|
+
...REPO_PROPS,
|
|
143
|
+
confirm: {
|
|
144
|
+
type: 'string',
|
|
145
|
+
description: 'Tulis ulang "owner/repo" dari repository yang dihapus sebagai konfirmasi eksplisit.',
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
required: ['owner', 'repo', 'confirm'],
|
|
149
|
+
},
|
|
150
|
+
async handler(args) {
|
|
151
|
+
await assertDestructiveAllowed(plugin, 'Penghapusan repository');
|
|
152
|
+
const base = repoBase(args);
|
|
153
|
+
const target = base.replace(/^\/repos\//, '');
|
|
154
|
+
const typed = String(args.confirm ?? '').trim();
|
|
155
|
+
if (typed.toLowerCase() !== target.toLowerCase()) {
|
|
156
|
+
throw new ValidationError(
|
|
157
|
+
`Konfirmasi tidak cocok. Untuk menghapus repository ini, argumen confirm harus berisi "${target}".`,
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
const api = await plugin.requireClient();
|
|
161
|
+
await api.delete(base);
|
|
162
|
+
return {
|
|
163
|
+
ok: true,
|
|
164
|
+
deleted: target,
|
|
165
|
+
note: 'Repository dihapus permanen. Tindakan ini tidak dapat dibatalkan.',
|
|
166
|
+
};
|
|
167
|
+
},
|
|
168
|
+
}),
|
|
169
|
+
|
|
132
170
|
defineTool({
|
|
133
171
|
name: 'github_list_branches',
|
|
134
172
|
description: 'Daftar branch pada repository beserta commit SHA terakhir dan status proteksi.',
|
package/src/cli/commands.js
CHANGED
|
@@ -93,9 +93,17 @@ export function createCommands(state) {
|
|
|
93
93
|
|
|
94
94
|
const commands = new Map();
|
|
95
95
|
|
|
96
|
-
// `details` is the optional tutorial shown by `/help <command
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
// `details` is the optional tutorial shown by `/help <command>`; `meta` marks
|
|
97
|
+
// plugin commands so `/help` can list their subcommand usage separately.
|
|
98
|
+
const define = (name, description, usage, handler, details = null, meta = {}) => {
|
|
99
|
+
commands.set(name, { name, description, usage, handler, details, ...meta });
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/** Usage line for `/help <command>` without printing the command name twice. */
|
|
103
|
+
const usageLine = (command) => {
|
|
104
|
+
const prefix = `/${command.name}`;
|
|
105
|
+
const usage = String(command.usage || '').trim();
|
|
106
|
+
return usage.startsWith(prefix) ? usage : `${prefix} ${usage}`.trim();
|
|
99
107
|
};
|
|
100
108
|
|
|
101
109
|
const stateDir = () => stateDirFor(config.workspace);
|
|
@@ -178,14 +186,23 @@ export function createCommands(state) {
|
|
|
178
186
|
const command = commands.get(target);
|
|
179
187
|
if (!command) return print(`Unknown command: /${target}. Run /help.`);
|
|
180
188
|
const details = command.details ? `\n\n${command.details}` : '';
|
|
181
|
-
return print(
|
|
189
|
+
return print(`${usageLine(command)}\n ${command.description}${details}`);
|
|
182
190
|
}
|
|
183
191
|
const rows = [...commands.values()].map((command) => ` /${command.name.padEnd(12)} ${command.description}`);
|
|
184
192
|
const flagRows = CLI_FLAGS.map(([flag, description]) => ` ${flag.padEnd(20)} ${description}`);
|
|
193
|
+
const pluginRows = [...commands.values()]
|
|
194
|
+
.filter((command) => command.plugin)
|
|
195
|
+
.flatMap((command) => [
|
|
196
|
+
` ${usageLine(command)}`,
|
|
197
|
+
...(command.examples || []).map((line) => ` ${line}`),
|
|
198
|
+
]);
|
|
185
199
|
print(
|
|
186
200
|
[
|
|
187
201
|
'Ryuu commands',
|
|
188
202
|
...rows,
|
|
203
|
+
...(pluginRows.length
|
|
204
|
+
? ['', 'Plugin commands (available while the plugin is loaded; details: /help <command>):', ...pluginRows]
|
|
205
|
+
: []),
|
|
189
206
|
'',
|
|
190
207
|
'CLI flags (set at startup, e.g. `ryuu --auto-approve "task"`, and listed in `ryuu --help`):',
|
|
191
208
|
...flagRows,
|
|
@@ -1141,6 +1158,16 @@ export function createCommands(state) {
|
|
|
1141
1158
|
' enable mendaftarkan tool GitHub untuk AI Agent',
|
|
1142
1159
|
' disable melepas tool tanpa menghapus akun/token',
|
|
1143
1160
|
].join('\n'),
|
|
1161
|
+
{
|
|
1162
|
+
plugin: true,
|
|
1163
|
+
examples: [
|
|
1164
|
+
'login open the browser and wait for the GitHub approval',
|
|
1165
|
+
'login --device headless device flow, no browser needed',
|
|
1166
|
+
'status | account | test inspect connection, account and API access',
|
|
1167
|
+
'enable | disable register or remove the GitHub AI tools',
|
|
1168
|
+
'config show settings without any secret',
|
|
1169
|
+
],
|
|
1170
|
+
},
|
|
1144
1171
|
);
|
|
1145
1172
|
continue;
|
|
1146
1173
|
}
|
|
@@ -1157,6 +1184,21 @@ export function createCommands(state) {
|
|
|
1157
1184
|
`Google Drive integration: login | logout | account | enable | disable | status | config | test`,
|
|
1158
1185
|
'/drive [login|logout|account|enable|disable|status|config|test]',
|
|
1159
1186
|
async (args = '') => handler(args, print),
|
|
1187
|
+
[
|
|
1188
|
+
' Autentikasi memakai OAuth Google lewat backend Ryuu; CLI tidak menyimpan token Google.',
|
|
1189
|
+
' login menghubungkan akun Google lewat browser',
|
|
1190
|
+
' enable mendaftarkan tool Drive untuk AI Agent',
|
|
1191
|
+
' disable melepas tool tanpa menghapus akun/token',
|
|
1192
|
+
].join('\n'),
|
|
1193
|
+
{
|
|
1194
|
+
plugin: true,
|
|
1195
|
+
examples: [
|
|
1196
|
+
'login | logout connect or disconnect the Google account',
|
|
1197
|
+
'account | status | test inspect the connection and the granted scopes',
|
|
1198
|
+
'enable | disable register or remove the Drive AI tools',
|
|
1199
|
+
'config show settings without any secret',
|
|
1200
|
+
],
|
|
1201
|
+
},
|
|
1160
1202
|
);
|
|
1161
1203
|
}
|
|
1162
1204
|
|