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 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,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const botCommand: Command;
@@ -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":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const loginCommand: Command;
@@ -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,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const statusCommand: Command;
@@ -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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
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"}
@@ -0,0 +1,3 @@
1
+ import { AxiosInstance } from 'axios';
2
+ export declare function getClient(): AxiosInstance;
3
+ export declare function getUnauthenticatedClient(): AxiosInstance;
@@ -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;
@@ -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"}
@@ -0,0 +1,2 @@
1
+ export declare function generateCodeVerifier(): string;
2
+ export declare function generateCodeChallenge(verifier: string): string;
@@ -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
+ }