@moltbankhq/openclaw 0.1.15 → 0.1.17

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.
Files changed (4) hide show
  1. package/README.md +7 -3
  2. package/cli.ts +27 -6
  3. package/index.ts +55 -9
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -44,15 +44,16 @@ After installing, run:
44
44
  moltbank setup
45
45
  ```
46
46
 
47
- The CLI will guide you through linking your MoltBank account via browser-based OAuth. Once approved, setup verifies a real authenticated balance read before reporting success.
47
+ By default, `moltbank setup` issues the browser activation code, starts background finalization, and returns without hanging on approval. Host setup also skips automatic gateway restarts by default so the active chat session is not interrupted. Use `moltbank setup --blocking` or `moltbank setup-blocking` when you want the command to wait for approval and finish readiness verification in the foreground.
48
48
 
49
49
  ## CLI Commands
50
50
 
51
51
  | Command | Description |
52
52
  |---------|-------------|
53
- | `moltbank setup` | Run full setup and verify readiness |
53
+ | `moltbank setup` | Start setup in nonblocking mode and return after issuing activation steps |
54
+ | `moltbank setup --blocking` | Run setup and wait for approval in the foreground |
54
55
  | `moltbank setup --verbose` | Run setup with detailed logs |
55
- | `moltbank setup-blocking` | Alias for setup |
56
+ | `moltbank setup-blocking` | Run setup and wait for approval |
56
57
  | `moltbank status` | Check current auth state |
57
58
  | `moltbank auth-status` | Alias for `moltbank status` |
58
59
  | `moltbank sandbox-setup` | Reconfigure sandbox Docker settings |
@@ -65,6 +66,7 @@ CLI flags:
65
66
 
66
67
  ```bash
67
68
  moltbank setup --app-base-url https://app.moltbank.bot --skill-name MoltBank
69
+ moltbank setup --workspace ~/.openclaw/workspace
68
70
  ```
69
71
 
70
72
  ## Environment Variables
@@ -73,8 +75,10 @@ moltbank setup --app-base-url https://app.moltbank.bot --skill-name MoltBank
73
75
  |----------|-------------|
74
76
  | `APP_BASE_URL` | MoltBank deployment URL (default: `https://app.moltbank.bot`) |
75
77
  | `MOLTBANK_SKILL_NAME` | Override skill folder name (default: `MoltBank`) |
78
+ | `OPENCLAW_WORKSPACE` | Override OpenClaw workspace path (default: `~/.openclaw/workspace`) |
76
79
  | `MOLTBANK_CREDENTIALS_PATH` | Custom credentials file path |
77
80
  | `MOLTBANK_SETUP_AUTH_WAIT_MODE` | `blocking` or `nonblocking` (default: `nonblocking`) |
81
+ | `MOLTBANK_SETUP_RESTART_GATEWAY` | `true` or `false` (default: `false`) |
78
82
 
79
83
  ## Capabilities
80
84
 
package/cli.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  createSetupCommandLogger,
6
6
  ensureMcporterConfig,
7
7
  getAppBaseUrl,
8
+ getSetupAuthWaitMode,
8
9
  getSetupGatewayRestartEnabled,
9
10
  getSkillDir,
10
11
  injectSandboxEnv,
@@ -16,6 +17,7 @@ import {
16
17
  type CliConfig = {
17
18
  appBaseUrl?: string;
18
19
  skillName?: string;
20
+ workspacePath?: string;
19
21
  };
20
22
 
21
23
  type ParsedArgs = {
@@ -35,7 +37,7 @@ Usage:
35
37
 
36
38
  Commands:
37
39
  setup Run MoltBank setup
38
- setup-blocking Alias for setup
40
+ setup-blocking Run setup and wait for approval
39
41
  status Show current MoltBank auth state
40
42
  auth-status Alias for status
41
43
  sandbox-setup Reconfigure sandbox Docker settings in openclaw.json
@@ -45,15 +47,18 @@ Commands:
45
47
  Options:
46
48
  --app-base-url <url> Override MoltBank deployment URL
47
49
  --skill-name <name> Override skill folder name
48
- --blocking Compatibility flag; setup already waits for approval
50
+ --workspace <path> Override OpenClaw workspace path
51
+ --blocking Wait for browser approval before setup exits
49
52
  --restart-gateway Force gateway restart after successful host setup
50
- --no-restart-gateway Skip gateway restart after successful host setup
53
+ --no-restart-gateway Skip gateway restart after successful host setup (default)
51
54
  --verbose Show detailed setup logs
52
55
  -h, --help Show help
53
56
  -v, --version Show package version
54
57
 
55
58
  Examples:
56
59
  moltbank setup
60
+ moltbank setup --workspace ~/.openclaw/workspace
61
+ moltbank setup --blocking
57
62
  moltbank setup --verbose
58
63
  moltbank status
59
64
  moltbank register --app-base-url https://app.moltbank.bot
@@ -137,6 +142,21 @@ function parseArgs(argv: string[]): ParsedArgs {
137
142
  continue;
138
143
  }
139
144
 
145
+ if (arg === '--workspace') {
146
+ const value = argv[index + 1];
147
+ if (!value) {
148
+ throw new Error('missing value for --workspace');
149
+ }
150
+ config.workspacePath = value;
151
+ index += 1;
152
+ continue;
153
+ }
154
+
155
+ if (arg.startsWith('--workspace=')) {
156
+ config.workspacePath = arg.slice('--workspace='.length);
157
+ continue;
158
+ }
159
+
140
160
  if (arg.startsWith('-')) {
141
161
  throw new Error(`unknown option: ${arg}`);
142
162
  }
@@ -160,10 +180,11 @@ async function runCommand(parsed: ParsedArgs): Promise<void> {
160
180
 
161
181
  switch (parsed.command) {
162
182
  case 'setup': {
163
- const restartGatewayOnSuccess = parsed.restartGateway ?? getSetupGatewayRestartEnabled(process.platform === 'win32');
183
+ const restartGatewayOnSuccess = parsed.restartGateway ?? getSetupGatewayRestartEnabled(false);
164
184
  const logger = createSetupCommandLogger({ verbose: parsed.verbose, statusCommand: 'moltbank status' });
185
+ const authWaitMode = parsed.blocking ? 'blocking' : getSetupAuthWaitMode('nonblocking');
165
186
  try {
166
- await runSetup(cfg, logger, { authWaitMode: 'blocking', restartGatewayOnSuccess });
187
+ await runSetup(cfg, logger, { authWaitMode, restartGatewayOnSuccess });
167
188
  } finally {
168
189
  logger.finish();
169
190
  }
@@ -171,7 +192,7 @@ async function runCommand(parsed: ParsedArgs): Promise<void> {
171
192
  }
172
193
 
173
194
  case 'setup-blocking': {
174
- const restartGatewayOnSuccess = parsed.restartGateway ?? getSetupGatewayRestartEnabled(process.platform === 'win32');
195
+ const restartGatewayOnSuccess = parsed.restartGateway ?? getSetupGatewayRestartEnabled(false);
175
196
  const logger = createSetupCommandLogger({ verbose: parsed.verbose, statusCommand: 'moltbank status' });
176
197
  try {
177
198
  await runSetup(cfg, logger, { authWaitMode: 'blocking', restartGatewayOnSuccess });
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 getWorkspace(): string {
890
- return process.env.OPENCLAW_WORKSPACE || join(homedir(), '.openclaw', 'workspace');
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
- api.logger.info('[moltbank] host mode — setup completed with onboarding flow');
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
- api.logger.info(`[moltbank] setup complete`);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moltbankhq/openclaw",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "MoltBank stablecoin treasury CLI and OpenClaw skill installer",
5
5
  "homepage": "https://github.com/moltbankhq/openclaw-plugin#readme",
6
6
  "repository": {