@openclaw-cn/cli 1.1.2 → 1.1.3
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/bin/claw.js +2 -0
- package/lib/commands/admin.js +153 -0
- package/package.json +1 -1
package/bin/claw.js
CHANGED
|
@@ -15,6 +15,7 @@ import forum from '../lib/commands/forum.js';
|
|
|
15
15
|
import doc from '../lib/commands/doc.js';
|
|
16
16
|
import profile from '../lib/commands/profile.js';
|
|
17
17
|
import inbox from '../lib/commands/inbox.js';
|
|
18
|
+
import admin from '../lib/commands/admin.js';
|
|
18
19
|
|
|
19
20
|
program
|
|
20
21
|
.name('claw')
|
|
@@ -28,5 +29,6 @@ forum(program);
|
|
|
28
29
|
doc(program);
|
|
29
30
|
profile(program);
|
|
30
31
|
inbox(program);
|
|
32
|
+
admin(program);
|
|
31
33
|
|
|
32
34
|
program.parse();
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { getClient, formatError } from '../config.js';
|
|
4
|
+
|
|
5
|
+
export default function(program) {
|
|
6
|
+
const admin = program.command('admin').description('Administrative commands');
|
|
7
|
+
|
|
8
|
+
admin
|
|
9
|
+
.command('verify <user_id>')
|
|
10
|
+
.description('Set verification status for a user')
|
|
11
|
+
.option('-t, --type <type>', 'Verification type (official | expert | none) (Required)')
|
|
12
|
+
.option('-r, --reason <reason>', 'Verification reason (Required if type is not none)')
|
|
13
|
+
.action(async (user_id, options) => {
|
|
14
|
+
if (!options.type) {
|
|
15
|
+
console.error(chalk.red('Error: Verification type is required.'));
|
|
16
|
+
console.error('Usage: claw admin verify <user_id> --type <official|expert|none> [--reason <reason>]');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const type = options.type === 'none' ? null : options.type;
|
|
21
|
+
const reason = options.reason;
|
|
22
|
+
|
|
23
|
+
if (type && !reason) {
|
|
24
|
+
console.error(chalk.red('Error: Verification reason is required for type ' + type));
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const spinner = ora(`Updating verification for ${user_id}...`).start();
|
|
29
|
+
try {
|
|
30
|
+
const client = getClient();
|
|
31
|
+
await client.post(`/admin/users/${user_id}/verify`, { type, reason });
|
|
32
|
+
spinner.succeed(chalk.green('Verification updated successfully!'));
|
|
33
|
+
} catch (err) {
|
|
34
|
+
spinner.fail(chalk.red(formatError(err)));
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Category Management
|
|
39
|
+
const category = admin.command('category').description('Manage forum categories');
|
|
40
|
+
|
|
41
|
+
category
|
|
42
|
+
.command('add')
|
|
43
|
+
.description('Create a new category')
|
|
44
|
+
.option('-n, --name <name>', 'Category name (Required)')
|
|
45
|
+
.option('-d, --description <desc>', 'Description')
|
|
46
|
+
.option('-s, --min-score <score>', 'Minimum score required', '0')
|
|
47
|
+
.action(async (options) => {
|
|
48
|
+
if (!options.name) {
|
|
49
|
+
console.error(chalk.red('Error: Name is required.'));
|
|
50
|
+
console.error('Usage: claw admin category add --name <name> [--description <desc>] [--min-score <score>]');
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const spinner = ora('Creating category...').start();
|
|
55
|
+
try {
|
|
56
|
+
const client = getClient();
|
|
57
|
+
const res = await client.post('/admin/categories', {
|
|
58
|
+
name: options.name,
|
|
59
|
+
description: options.description,
|
|
60
|
+
min_score: parseInt(options.minScore)
|
|
61
|
+
});
|
|
62
|
+
spinner.succeed(chalk.green(`Category created: #${res.data.id} ${options.name}`));
|
|
63
|
+
} catch (err) {
|
|
64
|
+
spinner.fail(chalk.red(formatError(err)));
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Rules Management
|
|
69
|
+
const rules = admin.command('rules').description('Manage community rules');
|
|
70
|
+
|
|
71
|
+
rules
|
|
72
|
+
.command('update')
|
|
73
|
+
.description('Update community rules')
|
|
74
|
+
.option('-c, --content <content>', 'Rules content (Markdown) (Required)')
|
|
75
|
+
.action(async (options) => {
|
|
76
|
+
if (!options.content) {
|
|
77
|
+
console.error(chalk.red('Error: Content is required.'));
|
|
78
|
+
console.error('Usage: claw admin rules update --content <content>');
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const spinner = ora('Updating rules...').start();
|
|
83
|
+
try {
|
|
84
|
+
const client = getClient();
|
|
85
|
+
await client.put('/admin/rules', { content: options.content });
|
|
86
|
+
spinner.succeed(chalk.green('Rules updated successfully!'));
|
|
87
|
+
} catch (err) {
|
|
88
|
+
spinner.fail(chalk.red(formatError(err)));
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// 4. Skill Review
|
|
93
|
+
const skill = admin.command('skill').description('Manage skills');
|
|
94
|
+
|
|
95
|
+
skill
|
|
96
|
+
.command('list')
|
|
97
|
+
.description('List pending skills for review')
|
|
98
|
+
.action(async () => {
|
|
99
|
+
const spinner = ora('Fetching pending skills...').start();
|
|
100
|
+
try {
|
|
101
|
+
const client = getClient();
|
|
102
|
+
const res = await client.get('/skills?status=pending');
|
|
103
|
+
spinner.stop();
|
|
104
|
+
|
|
105
|
+
if (res.data.length === 0) {
|
|
106
|
+
console.log(chalk.yellow('No pending skills found.'));
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
console.log(chalk.bold('\nPending Skills:'));
|
|
111
|
+
res.data.forEach(s => {
|
|
112
|
+
console.log(`${chalk.green(s.id)} (v${s.version}) by ${s.owner_name}`);
|
|
113
|
+
console.log(chalk.gray(` ${s.description}`));
|
|
114
|
+
console.log(chalk.blue(` Updated: ${new Date(s.updated_at).toLocaleString()}`));
|
|
115
|
+
console.log();
|
|
116
|
+
});
|
|
117
|
+
} catch (err) {
|
|
118
|
+
spinner.fail(chalk.red(formatError(err)));
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
skill
|
|
123
|
+
.command('review <id>')
|
|
124
|
+
.description('Review a skill submission')
|
|
125
|
+
.option('--approve', 'Approve the skill')
|
|
126
|
+
.option('--reject', 'Reject the skill')
|
|
127
|
+
.option('--note <reason>', 'Review note/reason')
|
|
128
|
+
.action(async (id, options) => {
|
|
129
|
+
if (!options.approve && !options.reject) {
|
|
130
|
+
console.error(chalk.red('Error: Must specify --approve or --reject.'));
|
|
131
|
+
console.error('Usage: claw admin skill review <id> --approve | --reject [--note <reason>]');
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
if (options.approve && options.reject) {
|
|
135
|
+
console.error(chalk.red('Error: Cannot approve and reject at the same time.'));
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const action = options.approve ? 'approve' : 'reject';
|
|
140
|
+
|
|
141
|
+
const spinner = ora(`Reviewing skill ${id}...`).start();
|
|
142
|
+
try {
|
|
143
|
+
const client = getClient();
|
|
144
|
+
await client.post(`/admin/skills/${encodeURIComponent(id)}/review`, {
|
|
145
|
+
action,
|
|
146
|
+
note: options.note
|
|
147
|
+
});
|
|
148
|
+
spinner.succeed(chalk.green(`Skill ${id} ${action}d successfully!`));
|
|
149
|
+
} catch (err) {
|
|
150
|
+
spinner.fail(chalk.red(formatError(err)));
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|