@moltbankhq/openclaw 0.1.15 → 0.1.16
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 +2 -0
- package/cli.ts +18 -0
- package/index.ts +55 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -65,6 +65,7 @@ CLI flags:
|
|
|
65
65
|
|
|
66
66
|
```bash
|
|
67
67
|
moltbank setup --app-base-url https://app.moltbank.bot --skill-name MoltBank
|
|
68
|
+
moltbank setup --workspace ~/.openclaw/workspace
|
|
68
69
|
```
|
|
69
70
|
|
|
70
71
|
## Environment Variables
|
|
@@ -73,6 +74,7 @@ moltbank setup --app-base-url https://app.moltbank.bot --skill-name MoltBank
|
|
|
73
74
|
|----------|-------------|
|
|
74
75
|
| `APP_BASE_URL` | MoltBank deployment URL (default: `https://app.moltbank.bot`) |
|
|
75
76
|
| `MOLTBANK_SKILL_NAME` | Override skill folder name (default: `MoltBank`) |
|
|
77
|
+
| `OPENCLAW_WORKSPACE` | Override OpenClaw workspace path (default: `~/.openclaw/workspace`) |
|
|
76
78
|
| `MOLTBANK_CREDENTIALS_PATH` | Custom credentials file path |
|
|
77
79
|
| `MOLTBANK_SETUP_AUTH_WAIT_MODE` | `blocking` or `nonblocking` (default: `nonblocking`) |
|
|
78
80
|
|
package/cli.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
type CliConfig = {
|
|
17
17
|
appBaseUrl?: string;
|
|
18
18
|
skillName?: string;
|
|
19
|
+
workspacePath?: string;
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
type ParsedArgs = {
|
|
@@ -45,6 +46,7 @@ Commands:
|
|
|
45
46
|
Options:
|
|
46
47
|
--app-base-url <url> Override MoltBank deployment URL
|
|
47
48
|
--skill-name <name> Override skill folder name
|
|
49
|
+
--workspace <path> Override OpenClaw workspace path
|
|
48
50
|
--blocking Compatibility flag; setup already waits for approval
|
|
49
51
|
--restart-gateway Force gateway restart after successful host setup
|
|
50
52
|
--no-restart-gateway Skip gateway restart after successful host setup
|
|
@@ -54,6 +56,7 @@ Options:
|
|
|
54
56
|
|
|
55
57
|
Examples:
|
|
56
58
|
moltbank setup
|
|
59
|
+
moltbank setup --workspace ~/.openclaw/workspace
|
|
57
60
|
moltbank setup --verbose
|
|
58
61
|
moltbank status
|
|
59
62
|
moltbank register --app-base-url https://app.moltbank.bot
|
|
@@ -137,6 +140,21 @@ function parseArgs(argv: string[]): ParsedArgs {
|
|
|
137
140
|
continue;
|
|
138
141
|
}
|
|
139
142
|
|
|
143
|
+
if (arg === '--workspace') {
|
|
144
|
+
const value = argv[index + 1];
|
|
145
|
+
if (!value) {
|
|
146
|
+
throw new Error('missing value for --workspace');
|
|
147
|
+
}
|
|
148
|
+
config.workspacePath = value;
|
|
149
|
+
index += 1;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (arg.startsWith('--workspace=')) {
|
|
154
|
+
config.workspacePath = arg.slice('--workspace='.length);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
|
|
140
158
|
if (arg.startsWith('-')) {
|
|
141
159
|
throw new Error(`unknown option: ${arg}`);
|
|
142
160
|
}
|
package/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn, spawnSync } from 'child_process';
|
|
2
2
|
import { chmodSync, chownSync, existsSync, mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync, type Dirent } from 'fs';
|
|
3
|
-
import { join, dirname, basename } from 'path';
|
|
3
|
+
import { join, dirname, basename, resolve } from 'path';
|
|
4
4
|
import { homedir, userInfo } from 'os';
|
|
5
5
|
const IS_WIN = process.platform === 'win32';
|
|
6
6
|
|
|
@@ -10,6 +10,7 @@ type ParsedJsonObject = Record<string, unknown>;
|
|
|
10
10
|
export interface MoltbankConfig {
|
|
11
11
|
skillName?: string;
|
|
12
12
|
appBaseUrl?: string;
|
|
13
|
+
workspacePath?: string;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
interface CredentialsOrganization {
|
|
@@ -391,9 +392,13 @@ function resolveWindowsCommandPath(command: string, env: NodeJS.ProcessEnv): str
|
|
|
391
392
|
const extensions = getWindowsCommandExtensions(env);
|
|
392
393
|
|
|
393
394
|
const tryCandidates = (basePath: string): string => {
|
|
394
|
-
if (existsSync(basePath)) return basePath;
|
|
395
|
-
|
|
396
395
|
const lower = basePath.toLowerCase();
|
|
396
|
+
const hasKnownExtension = extensions.some((ext) => lower.endsWith(ext));
|
|
397
|
+
|
|
398
|
+
if (hasKnownExtension && existsSync(basePath)) {
|
|
399
|
+
return basePath;
|
|
400
|
+
}
|
|
401
|
+
|
|
397
402
|
for (const ext of extensions) {
|
|
398
403
|
if (lower.endsWith(ext)) continue;
|
|
399
404
|
const candidate = `${basePath}${ext}`;
|
|
@@ -402,6 +407,10 @@ function resolveWindowsCommandPath(command: string, env: NodeJS.ProcessEnv): str
|
|
|
402
407
|
}
|
|
403
408
|
}
|
|
404
409
|
|
|
410
|
+
if (existsSync(basePath)) {
|
|
411
|
+
return basePath;
|
|
412
|
+
}
|
|
413
|
+
|
|
405
414
|
return '';
|
|
406
415
|
};
|
|
407
416
|
|
|
@@ -886,8 +895,30 @@ function lastNonEmptyLine(text: string): string {
|
|
|
886
895
|
return lines.length ? lines[lines.length - 1] : '';
|
|
887
896
|
}
|
|
888
897
|
|
|
889
|
-
function
|
|
890
|
-
|
|
898
|
+
function normalizeWorkspacePath(rawPath: string): string {
|
|
899
|
+
const trimmed = rawPath.trim();
|
|
900
|
+
if (!trimmed) {
|
|
901
|
+
return join(homedir(), '.openclaw', 'workspace');
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
if (trimmed === '~') {
|
|
905
|
+
return homedir();
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
if (trimmed.startsWith('~/') || trimmed.startsWith('~\\')) {
|
|
909
|
+
return resolve(join(homedir(), trimmed.slice(2)));
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
return resolve(trimmed);
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
export function getWorkspace(cfg?: MoltbankConfig): string {
|
|
916
|
+
return normalizeWorkspacePath(cfg?.workspacePath || process.env.OPENCLAW_WORKSPACE || join(homedir(), '.openclaw', 'workspace'));
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
function getWorkspaceFromSkillDir(skillDir: string): string {
|
|
920
|
+
const skillsDir = dirname(skillDir);
|
|
921
|
+
return basename(skillsDir) === 'skills' ? dirname(skillsDir) : getWorkspace();
|
|
891
922
|
}
|
|
892
923
|
|
|
893
924
|
export function getSkillName(cfg: MoltbankConfig): string {
|
|
@@ -916,7 +947,7 @@ function isSandboxEnabled(): boolean {
|
|
|
916
947
|
|
|
917
948
|
export function getSkillDir(cfg: MoltbankConfig): string {
|
|
918
949
|
const skillName = getSkillName(cfg);
|
|
919
|
-
return join(getWorkspace(), 'skills', skillName);
|
|
950
|
+
return join(getWorkspace(cfg), 'skills', skillName);
|
|
920
951
|
}
|
|
921
952
|
|
|
922
953
|
function getCredentialsPath(): string {
|
|
@@ -1626,6 +1657,7 @@ function startBackgroundFinalizeAfterAuth(skillDir: string, appBaseUrl: string,
|
|
|
1626
1657
|
env: {
|
|
1627
1658
|
...process.env,
|
|
1628
1659
|
APP_BASE_URL: appBaseUrl,
|
|
1660
|
+
OPENCLAW_WORKSPACE: getWorkspaceFromSkillDir(skillDir),
|
|
1629
1661
|
MOLTBANK_SETUP_AUTH_WAIT_MODE: 'blocking'
|
|
1630
1662
|
},
|
|
1631
1663
|
stdio: 'ignore', // Ignore logs so it doesn't hang the parent
|
|
@@ -2303,7 +2335,11 @@ export async function runSetup(
|
|
|
2303
2335
|
api.logger.info('[moltbank] [host 8/8] running readiness balance check...');
|
|
2304
2336
|
hostReady = runHostReadinessCheck(skillDir, api);
|
|
2305
2337
|
|
|
2306
|
-
|
|
2338
|
+
if (hostReady) {
|
|
2339
|
+
api.logger.info('[moltbank] host mode — setup completed with onboarding flow');
|
|
2340
|
+
} else {
|
|
2341
|
+
api.logger.warn('[moltbank] host mode setup finished, but operational readiness verification failed');
|
|
2342
|
+
}
|
|
2307
2343
|
|
|
2308
2344
|
if (hostReady && restartGatewayOnSuccess) {
|
|
2309
2345
|
restartGatewayAfterHostSetup(api);
|
|
@@ -2311,13 +2347,19 @@ export async function runSetup(
|
|
|
2311
2347
|
}
|
|
2312
2348
|
|
|
2313
2349
|
api.logger.info(`[moltbank] ══════════════════════════════════════`);
|
|
2314
|
-
|
|
2350
|
+
if (sandbox || hostReady) {
|
|
2351
|
+
api.logger.info(`[moltbank] ✓ setup complete`);
|
|
2352
|
+
} else {
|
|
2353
|
+
api.logger.warn('[moltbank] ✗ setup incomplete');
|
|
2354
|
+
}
|
|
2315
2355
|
if (sandbox) {
|
|
2316
2356
|
api.logger.info('[moltbank] ⏳ sandbox will be recreated in ~8s — send a message to the agent after that');
|
|
2317
2357
|
} else if (hostReady) {
|
|
2318
2358
|
api.logger.info('[moltbank] ✓ host ready');
|
|
2359
|
+
} else {
|
|
2360
|
+
api.logger.warn('[moltbank] ✗ host not ready');
|
|
2319
2361
|
}
|
|
2320
|
-
api.logger.info(`[moltbank] skill: ${skillDir}/SKILL.md`);
|
|
2362
|
+
api.logger.info(`[moltbank] skill: ${skillDir}/skill/SKILL.md`);
|
|
2321
2363
|
api.logger.info(`[moltbank] mcporter: ${skillDir}/assets/mcporter.json`);
|
|
2322
2364
|
if (sandbox) {
|
|
2323
2365
|
const finalConfig = readOpenclawConfig();
|
|
@@ -2359,5 +2401,9 @@ export async function runSetup(
|
|
|
2359
2401
|
}
|
|
2360
2402
|
}
|
|
2361
2403
|
api.logger.info(`[moltbank] ══════════════════════════════════════`);
|
|
2404
|
+
|
|
2405
|
+
if (!sandbox && !hostReady) {
|
|
2406
|
+
throw new Error('host setup incomplete: authenticated readiness verification failed');
|
|
2407
|
+
}
|
|
2362
2408
|
}
|
|
2363
2409
|
|
package/package.json
CHANGED