badgerclaw 0.1.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 +32 -0
- package/dist/commands/bot.d.ts +2 -0
- package/dist/commands/bot.js +94 -0
- package/dist/commands/bot.js.map +1 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +65 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +23 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +3 -0
- package/dist/lib/api.js +27 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/auth.d.ts +11 -0
- package/dist/lib/auth.js +48 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/pkce.d.ts +2 -0
- package/dist/lib/pkce.js +15 -0
- package/dist/lib/pkce.js.map +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# BadgerClaw CLI
|
|
2
|
+
|
|
3
|
+
One-click bot provisioning for BadgerClaw.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g badgerclaw
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Authenticate
|
|
15
|
+
badgerclaw login
|
|
16
|
+
|
|
17
|
+
# Check status
|
|
18
|
+
badgerclaw status
|
|
19
|
+
|
|
20
|
+
# Manage bots
|
|
21
|
+
badgerclaw bot create mybot
|
|
22
|
+
badgerclaw bot list
|
|
23
|
+
badgerclaw bot delete mybot
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Development
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install
|
|
30
|
+
npm run build
|
|
31
|
+
node dist/index.js --help
|
|
32
|
+
```
|
|
@@ -0,0 +1,94 @@
|
|
|
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.botCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const ora_1 = __importDefault(require("ora"));
|
|
10
|
+
const auth_1 = require("../lib/auth");
|
|
11
|
+
const api_1 = require("../lib/api");
|
|
12
|
+
function requireAuth() {
|
|
13
|
+
if (!(0, auth_1.isAuthenticated)()) {
|
|
14
|
+
console.log(chalk_1.default.red('Not logged in. Run `badgerclaw login` to authenticate.'));
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function validateBotName(name) {
|
|
19
|
+
return /^[a-z0-9_]{4,20}$/.test(name);
|
|
20
|
+
}
|
|
21
|
+
function stripBotSuffix(name) {
|
|
22
|
+
return name.replace(/_bot$/, '');
|
|
23
|
+
}
|
|
24
|
+
const botCreate = new commander_1.Command('create')
|
|
25
|
+
.description('Create a new bot')
|
|
26
|
+
.argument('<name>', 'Bot name (4-20 chars, lowercase alphanumeric + underscores)')
|
|
27
|
+
.action(async (name) => {
|
|
28
|
+
requireAuth();
|
|
29
|
+
if (!validateBotName(name)) {
|
|
30
|
+
console.log(chalk_1.default.red('Invalid bot name. Must be 4-20 characters, lowercase alphanumeric and underscores only.'));
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
const spinner = (0, ora_1.default)(`Creating bot "${name}"...`).start();
|
|
34
|
+
try {
|
|
35
|
+
const client = (0, api_1.getClient)();
|
|
36
|
+
await client.post('/api/v1/openclaw/bots', { username: name });
|
|
37
|
+
spinner.succeed(chalk_1.default.green(`Bot "${name}" created successfully!`));
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
const msg = err.response?.data?.error || err.message;
|
|
41
|
+
spinner.fail(chalk_1.default.red(`Failed to create bot: ${msg}`));
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
const botList = new commander_1.Command('list')
|
|
46
|
+
.description('List your bots')
|
|
47
|
+
.action(async () => {
|
|
48
|
+
requireAuth();
|
|
49
|
+
const spinner = (0, ora_1.default)('Fetching bots...').start();
|
|
50
|
+
try {
|
|
51
|
+
const client = (0, api_1.getClient)();
|
|
52
|
+
const response = await client.get('/api/v1/openclaw/bots');
|
|
53
|
+
const bots = response.data?.bots || [];
|
|
54
|
+
spinner.stop();
|
|
55
|
+
if (bots.length === 0) {
|
|
56
|
+
console.log(chalk_1.default.yellow('No bots found. Create one with `badgerclaw bot create <name>`.'));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
console.log(chalk_1.default.green(`Your bots (${bots.length}):\n`));
|
|
60
|
+
for (const bot of bots) {
|
|
61
|
+
const displayName = stripBotSuffix(bot.username || bot.name);
|
|
62
|
+
const status = bot.active !== false ? chalk_1.default.green('active') : chalk_1.default.dim('inactive');
|
|
63
|
+
console.log(` ${chalk_1.default.bold(displayName)} ${status}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
const msg = err.response?.data?.error || err.message;
|
|
68
|
+
spinner.fail(chalk_1.default.red(`Failed to list bots: ${msg}`));
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
const botDelete = new commander_1.Command('delete')
|
|
73
|
+
.description('Deactivate a bot')
|
|
74
|
+
.argument('<name>', 'Bot name to deactivate')
|
|
75
|
+
.action(async (name) => {
|
|
76
|
+
requireAuth();
|
|
77
|
+
const spinner = (0, ora_1.default)(`Deactivating bot "${name}"...`).start();
|
|
78
|
+
try {
|
|
79
|
+
const client = (0, api_1.getClient)();
|
|
80
|
+
await client.delete(`/api/v1/openclaw/bots/${name}`);
|
|
81
|
+
spinner.succeed(chalk_1.default.green(`Bot "${name}" deactivated.`));
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
const msg = err.response?.data?.error || err.message;
|
|
85
|
+
spinner.fail(chalk_1.default.red(`Failed to deactivate bot: ${msg}`));
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
exports.botCommand = new commander_1.Command('bot')
|
|
90
|
+
.description('Manage bots')
|
|
91
|
+
.addCommand(botCreate)
|
|
92
|
+
.addCommand(botList)
|
|
93
|
+
.addCommand(botDelete);
|
|
94
|
+
//# sourceMappingURL=bot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bot.js","sourceRoot":"","sources":["../../src/commands/bot.ts"],"names":[],"mappings":";;;;;;AAAA,yCAAoC;AACpC,kDAA0B;AAC1B,8CAAsB;AACtB,sCAA8C;AAC9C,oCAAuC;AAEvC,SAAS,WAAW;IAClB,IAAI,CAAC,IAAA,sBAAe,GAAE,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC,CAAC;QACjF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,cAAc,CAAC,IAAY;IAClC,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,SAAS,GAAG,IAAI,mBAAO,CAAC,QAAQ,CAAC;KACpC,WAAW,CAAC,kBAAkB,CAAC;KAC/B,QAAQ,CAAC,QAAQ,EAAE,6DAA6D,CAAC;KACjF,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE;IAC7B,WAAW,EAAE,CAAC;IAEd,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,yFAAyF,CAAC,CAAC,CAAC;QAClH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,iBAAiB,IAAI,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;IACzD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,eAAS,GAAE,CAAC;QAC3B,MAAM,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,OAAO,CAAC,OAAO,CAAC,eAAK,CAAC,KAAK,CAAC,QAAQ,IAAI,yBAAyB,CAAC,CAAC,CAAC;IACtE,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC;QACrD,OAAO,CAAC,IAAI,CAAC,eAAK,CAAC,GAAG,CAAC,yBAAyB,GAAG,EAAE,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,MAAM,OAAO,GAAG,IAAI,mBAAO,CAAC,MAAM,CAAC;KAChC,WAAW,CAAC,gBAAgB,CAAC;KAC7B,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,WAAW,EAAE,CAAC;IAEd,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,kBAAkB,CAAC,CAAC,KAAK,EAAE,CAAC;IAChD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,eAAS,GAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QAC3D,MAAM,IAAI,GAAU,QAAQ,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;QAC9C,OAAO,CAAC,IAAI,EAAE,CAAC;QAEf,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,gEAAgE,CAAC,CAAC,CAAC;YAC5F,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC;QAC1D,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,WAAW,GAAG,cAAc,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;YAC7D,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,eAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,eAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACpF,OAAO,CAAC,GAAG,CAAC,KAAK,eAAK,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC;QACrD,OAAO,CAAC,IAAI,CAAC,eAAK,CAAC,GAAG,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,MAAM,SAAS,GAAG,IAAI,mBAAO,CAAC,QAAQ,CAAC;KACpC,WAAW,CAAC,kBAAkB,CAAC;KAC/B,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,CAAC;KAC5C,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE;IAC7B,WAAW,EAAE,CAAC;IAEd,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,qBAAqB,IAAI,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;IAC7D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,eAAS,GAAE,CAAC;QAC3B,MAAM,MAAM,CAAC,MAAM,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,OAAO,CAAC,eAAK,CAAC,KAAK,CAAC,QAAQ,IAAI,gBAAgB,CAAC,CAAC,CAAC;IAC7D,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC;QACrD,OAAO,CAAC,IAAI,CAAC,eAAK,CAAC,GAAG,CAAC,6BAA6B,GAAG,EAAE,CAAC,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEQ,QAAA,UAAU,GAAG,IAAI,mBAAO,CAAC,KAAK,CAAC;KACzC,WAAW,CAAC,aAAa,CAAC;KAC1B,UAAU,CAAC,SAAS,CAAC;KACrB,UAAU,CAAC,OAAO,CAAC;KACnB,UAAU,CAAC,SAAS,CAAC,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
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.loginCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const ora_1 = __importDefault(require("ora"));
|
|
10
|
+
const open_1 = __importDefault(require("open"));
|
|
11
|
+
const os_1 = __importDefault(require("os"));
|
|
12
|
+
const pkce_1 = require("../lib/pkce");
|
|
13
|
+
const auth_1 = require("../lib/auth");
|
|
14
|
+
const api_1 = require("../lib/api");
|
|
15
|
+
const POLL_INTERVAL_MS = 2000;
|
|
16
|
+
const POLL_TIMEOUT_MS = 120000;
|
|
17
|
+
exports.loginCommand = new commander_1.Command('login')
|
|
18
|
+
.description('Log in to BadgerClaw via browser')
|
|
19
|
+
.action(async () => {
|
|
20
|
+
const verifier = (0, pkce_1.generateCodeVerifier)();
|
|
21
|
+
const challenge = (0, pkce_1.generateCodeChallenge)(verifier);
|
|
22
|
+
const authUrl = `https://api.badger.signout.io/cli-auth?code=${challenge}`;
|
|
23
|
+
console.log(chalk_1.default.yellow('Opening browser for authentication...'));
|
|
24
|
+
console.log(chalk_1.default.dim(`If the browser doesn't open, visit: ${authUrl}`));
|
|
25
|
+
await (0, open_1.default)(authUrl);
|
|
26
|
+
const spinner = (0, ora_1.default)('Waiting for authentication...').start();
|
|
27
|
+
const client = (0, api_1.getUnauthenticatedClient)();
|
|
28
|
+
const startTime = Date.now();
|
|
29
|
+
while (Date.now() - startTime < POLL_TIMEOUT_MS) {
|
|
30
|
+
try {
|
|
31
|
+
const response = await client.post('/cli-auth/poll', {
|
|
32
|
+
code_verifier: verifier,
|
|
33
|
+
code_challenge: challenge,
|
|
34
|
+
});
|
|
35
|
+
if (response.data?.access_token) {
|
|
36
|
+
const { access_token, user_id, instance_id, expires_at } = response.data;
|
|
37
|
+
(0, auth_1.writeAuth)({ access_token, user_id, instance_id, expires_at });
|
|
38
|
+
// Register instance
|
|
39
|
+
try {
|
|
40
|
+
const version = require('../../package.json').version;
|
|
41
|
+
await client.post('/api/v1/openclaw/register', {
|
|
42
|
+
instance_id,
|
|
43
|
+
user_id,
|
|
44
|
+
label: os_1.default.hostname(),
|
|
45
|
+
version,
|
|
46
|
+
}, {
|
|
47
|
+
headers: { Authorization: `Bearer ${access_token}` },
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// Non-fatal: registration may fail but login succeeded
|
|
52
|
+
}
|
|
53
|
+
spinner.succeed(chalk_1.default.green(`Logged in as ${(0, auth_1.extractUsername)(user_id)}`));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Not ready yet, keep polling
|
|
59
|
+
}
|
|
60
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
61
|
+
}
|
|
62
|
+
spinner.fail(chalk_1.default.red('Authentication timed out. Please try again.'));
|
|
63
|
+
process.exit(1);
|
|
64
|
+
});
|
|
65
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":";;;;;;AAAA,yCAAoC;AACpC,kDAA0B;AAC1B,8CAAsB;AACtB,gDAAwB;AACxB,4CAAoB;AACpB,sCAA0E;AAC1E,sCAAyD;AACzD,oCAAsD;AAEtD,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAC9B,MAAM,eAAe,GAAG,MAAM,CAAC;AAElB,QAAA,YAAY,GAAG,IAAI,mBAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,QAAQ,GAAG,IAAA,2BAAoB,GAAE,CAAC;IACxC,MAAM,SAAS,GAAG,IAAA,4BAAqB,EAAC,QAAQ,CAAC,CAAC;IAElD,MAAM,OAAO,GAAG,+CAA+C,SAAS,EAAE,CAAC;IAE3E,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,uCAAuC,CAAC,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,uCAAuC,OAAO,EAAE,CAAC,CAAC,CAAC;IAEzE,MAAM,IAAA,cAAI,EAAC,OAAO,CAAC,CAAC;IAEpB,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,+BAA+B,CAAC,CAAC,KAAK,EAAE,CAAC;IAC7D,MAAM,MAAM,GAAG,IAAA,8BAAwB,GAAE,CAAC;IAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,eAAe,EAAE,CAAC;QAChD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE;gBACnD,aAAa,EAAE,QAAQ;gBACvB,cAAc,EAAE,SAAS;aAC1B,CAAC,CAAC;YAEH,IAAI,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC;gBAChC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC;gBAEzE,IAAA,gBAAS,EAAC,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC;gBAE9D,oBAAoB;gBACpB,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC,OAAO,CAAC;oBACtD,MAAM,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE;wBAC7C,WAAW;wBACX,OAAO;wBACP,KAAK,EAAE,YAAE,CAAC,QAAQ,EAAE;wBACpB,OAAO;qBACR,EAAE;wBACD,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,YAAY,EAAE,EAAE;qBACrD,CAAC,CAAC;gBACL,CAAC;gBAAC,MAAM,CAAC;oBACP,uDAAuD;gBACzD,CAAC;gBAED,OAAO,CAAC,OAAO,CAAC,eAAK,CAAC,KAAK,CAAC,gBAAgB,IAAA,sBAAe,EAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;gBACzE,OAAO;YACT,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,8BAA8B;QAChC,CAAC;QAED,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,eAAK,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC,CAAC;IACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
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.statusCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const auth_1 = require("../lib/auth");
|
|
10
|
+
exports.statusCommand = new commander_1.Command('status')
|
|
11
|
+
.description('Show connected instance info')
|
|
12
|
+
.action(() => {
|
|
13
|
+
const auth = (0, auth_1.readAuth)();
|
|
14
|
+
if (!auth || !(0, auth_1.isAuthenticated)()) {
|
|
15
|
+
console.log(chalk_1.default.red('Not logged in. Run `badgerclaw login` to authenticate.'));
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
console.log(chalk_1.default.green('Authenticated'));
|
|
19
|
+
console.log(` User: ${(0, auth_1.extractUsername)(auth.user_id)}`);
|
|
20
|
+
console.log(` Instance: ${auth.instance_id}`);
|
|
21
|
+
console.log(` Expires: ${new Date(auth.expires_at).toLocaleDateString()}`);
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":";;;;;;AAAA,yCAAoC;AACpC,kDAA0B;AAC1B,sCAAyE;AAE5D,QAAA,aAAa,GAAG,IAAI,mBAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,8BAA8B,CAAC;KAC3C,MAAM,CAAC,GAAG,EAAE;IACX,MAAM,IAAI,GAAG,IAAA,eAAQ,GAAE,CAAC;IAExB,IAAI,CAAC,IAAI,IAAI,CAAC,IAAA,sBAAe,GAAE,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC,CAAC;QACjF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,eAAe,IAAA,sBAAe,EAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;AAC/E,CAAC,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const login_1 = require("./commands/login");
|
|
6
|
+
const status_1 = require("./commands/status");
|
|
7
|
+
const bot_1 = require("./commands/bot");
|
|
8
|
+
const program = new commander_1.Command();
|
|
9
|
+
program
|
|
10
|
+
.name('badgerclaw')
|
|
11
|
+
.description('BadgerClaw CLI — one-click bot provisioning')
|
|
12
|
+
.version('0.1.0');
|
|
13
|
+
program.addCommand(login_1.loginCommand);
|
|
14
|
+
program.addCommand(status_1.statusCommand);
|
|
15
|
+
program.addCommand(bot_1.botCommand);
|
|
16
|
+
program.parse(process.argv);
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,4CAAgD;AAChD,8CAAkD;AAClD,wCAA4C;AAE5C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,6CAA6C,CAAC;KAC1D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,oBAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,sBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,gBAAU,CAAC,CAAC;AAE/B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
package/dist/lib/api.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
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.getClient = getClient;
|
|
7
|
+
exports.getUnauthenticatedClient = getUnauthenticatedClient;
|
|
8
|
+
const axios_1 = __importDefault(require("axios"));
|
|
9
|
+
const auth_1 = require("./auth");
|
|
10
|
+
const BASE_URL = 'https://api.badger.signout.io';
|
|
11
|
+
function getClient() {
|
|
12
|
+
const auth = (0, auth_1.readAuth)();
|
|
13
|
+
const headers = {
|
|
14
|
+
'Content-Type': 'application/json',
|
|
15
|
+
};
|
|
16
|
+
if (auth) {
|
|
17
|
+
headers['Authorization'] = `Bearer ${auth.access_token}`;
|
|
18
|
+
}
|
|
19
|
+
return axios_1.default.create({ baseURL: BASE_URL, headers });
|
|
20
|
+
}
|
|
21
|
+
function getUnauthenticatedClient() {
|
|
22
|
+
return axios_1.default.create({
|
|
23
|
+
baseURL: BASE_URL,
|
|
24
|
+
headers: { 'Content-Type': 'application/json' },
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":";;;;;AAKA,8BASC;AAED,4DAKC;AArBD,kDAA6C;AAC7C,iCAAkC;AAElC,MAAM,QAAQ,GAAG,+BAA+B,CAAC;AAEjD,SAAgB,SAAS;IACvB,MAAM,IAAI,GAAG,IAAA,eAAQ,GAAE,CAAC;IACxB,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;KACnC,CAAC;IACF,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,YAAY,EAAE,CAAC;IAC3D,CAAC;IACD,OAAO,eAAK,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;AACtD,CAAC;AAED,SAAgB,wBAAwB;IACtC,OAAO,eAAK,CAAC,MAAM,CAAC;QAClB,OAAO,EAAE,QAAQ;QACjB,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface AuthData {
|
|
2
|
+
access_token: string;
|
|
3
|
+
user_id: string;
|
|
4
|
+
instance_id: string;
|
|
5
|
+
expires_at: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function readAuth(): AuthData | null;
|
|
8
|
+
export declare function writeAuth(auth: AuthData): void;
|
|
9
|
+
export declare function clearAuth(): void;
|
|
10
|
+
export declare function isAuthenticated(): boolean;
|
|
11
|
+
export declare function extractUsername(userId: string): string;
|
package/dist/lib/auth.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
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.readAuth = readAuth;
|
|
7
|
+
exports.writeAuth = writeAuth;
|
|
8
|
+
exports.clearAuth = clearAuth;
|
|
9
|
+
exports.isAuthenticated = isAuthenticated;
|
|
10
|
+
exports.extractUsername = extractUsername;
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const os_1 = __importDefault(require("os"));
|
|
14
|
+
const AUTH_DIR = path_1.default.join(os_1.default.homedir(), '.badgerclaw');
|
|
15
|
+
const AUTH_FILE = path_1.default.join(AUTH_DIR, 'auth.json');
|
|
16
|
+
function readAuth() {
|
|
17
|
+
try {
|
|
18
|
+
const data = fs_1.default.readFileSync(AUTH_FILE, 'utf-8');
|
|
19
|
+
return JSON.parse(data);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function writeAuth(auth) {
|
|
26
|
+
fs_1.default.mkdirSync(AUTH_DIR, { recursive: true });
|
|
27
|
+
fs_1.default.writeFileSync(AUTH_FILE, JSON.stringify(auth, null, 2), { mode: 0o600 });
|
|
28
|
+
}
|
|
29
|
+
function clearAuth() {
|
|
30
|
+
try {
|
|
31
|
+
fs_1.default.unlinkSync(AUTH_FILE);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// ignore
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function isAuthenticated() {
|
|
38
|
+
const auth = readAuth();
|
|
39
|
+
if (!auth)
|
|
40
|
+
return false;
|
|
41
|
+
return new Date(auth.expires_at) > new Date();
|
|
42
|
+
}
|
|
43
|
+
function extractUsername(userId) {
|
|
44
|
+
// Strip @user:homeserver to just "user"
|
|
45
|
+
const match = userId.match(/^@?([^:]+)/);
|
|
46
|
+
return match ? match[1] : userId;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":";;;;;AAcA,4BAOC;AAED,8BAGC;AAED,8BAMC;AAED,0CAIC;AAED,0CAIC;AA9CD,4CAAoB;AACpB,gDAAwB;AACxB,4CAAoB;AASpB,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;AACxD,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AAEnD,SAAgB,QAAQ;IACtB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,YAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAa,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAgB,SAAS,CAAC,IAAc;IACtC,YAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,YAAE,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED,SAAgB,SAAS;IACvB,IAAI,CAAC;QACH,YAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;AACH,CAAC;AAED,SAAgB,eAAe;IAC7B,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;AAChD,CAAC;AAED,SAAgB,eAAe,CAAC,MAAc;IAC5C,wCAAwC;IACxC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACzC,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AACnC,CAAC"}
|
package/dist/lib/pkce.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
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.generateCodeVerifier = generateCodeVerifier;
|
|
7
|
+
exports.generateCodeChallenge = generateCodeChallenge;
|
|
8
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
9
|
+
function generateCodeVerifier() {
|
|
10
|
+
return crypto_1.default.randomBytes(32).toString('base64url');
|
|
11
|
+
}
|
|
12
|
+
function generateCodeChallenge(verifier) {
|
|
13
|
+
return crypto_1.default.createHash('sha256').update(verifier).digest('base64url');
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=pkce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../src/lib/pkce.ts"],"names":[],"mappings":";;;;;AAEA,oDAEC;AAED,sDAEC;AARD,oDAA4B;AAE5B,SAAgB,oBAAoB;IAClC,OAAO,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACtD,CAAC;AAED,SAAgB,qBAAqB,CAAC,QAAgB;IACpD,OAAO,gBAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AAC1E,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "badgerclaw",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "BadgerClaw CLI — one-click bot provisioning",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"badgerclaw": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist/",
|
|
11
|
+
"README.md"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/darkstaar4/badgerclaw-cli.git"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [],
|
|
22
|
+
"author": "",
|
|
23
|
+
"license": "ISC",
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/darkstaar4/badgerclaw-cli/issues"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/darkstaar4/badgerclaw-cli#readme",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"axios": "^1.6.0",
|
|
30
|
+
"chalk": "^4.1.2",
|
|
31
|
+
"commander": "^12.0.0",
|
|
32
|
+
"open": "^8.4.2",
|
|
33
|
+
"ora": "^5.4.1"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/node": "^20.0.0",
|
|
37
|
+
"typescript": "^5.3.0"
|
|
38
|
+
}
|
|
39
|
+
}
|