@2en/clawly-plugins 1.21.5 → 1.22.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.
@@ -21,19 +21,6 @@ export function registerConfigRepair(api: PluginApi) {
21
21
  api.registerGatewayMethod('clawly.config.repair', async ({params, respond}) => {
22
22
  const dryRun = params.dryRun === true
23
23
 
24
- const cfg = api.pluginConfig as Record<string, unknown> | undefined
25
- const baseUrl =
26
- typeof cfg?.modelGatewayBaseUrl === 'string' ? cfg.modelGatewayBaseUrl.replace(/\/$/, '') : ''
27
- const token = typeof cfg?.modelGatewayToken === 'string' ? cfg.modelGatewayToken : ''
28
-
29
- if (!baseUrl || !token) {
30
- respond(true, {
31
- ...(dryRun ? {ok: false} : {repaired: false}),
32
- detail: 'Plugin config missing modelGatewayBaseUrl or modelGatewayToken — cannot repair',
33
- })
34
- return
35
- }
36
-
37
24
  const stateDir = resolveStateDir(api)
38
25
  if (!stateDir) {
39
26
  respond(true, {
@@ -46,9 +33,39 @@ export function registerConfigRepair(api: PluginApi) {
46
33
  const configPath = path.join(stateDir, 'openclaw.json')
47
34
  const config = readOpenclawConfig(configPath)
48
35
 
49
- // Check current provider state
36
+ // Resolve credentials: prefer api.pluginConfig (in-memory), fall back to
37
+ // the on-disk provider entry or plugin config entry. After a force-update
38
+ // api.pluginConfig may be empty because it is immutable at runtime, but the
39
+ // backfill in model-gateway-setup writes credentials back to the file.
40
+ const cfg = api.pluginConfig as Record<string, unknown> | undefined
50
41
  const providers = (config.models as any)?.providers as Record<string, any> | undefined
51
42
  const provider = providers?.[PROVIDER_NAME] as Record<string, unknown> | undefined
43
+ const filePluginCfg = (config.plugins as any)?.entries?.['clawly-plugins']?.config as
44
+ | Record<string, unknown>
45
+ | undefined
46
+
47
+ const baseUrl = (
48
+ (typeof cfg?.modelGatewayBaseUrl === 'string' && cfg.modelGatewayBaseUrl) ||
49
+ (typeof provider?.baseUrl === 'string' && provider.baseUrl) ||
50
+ (typeof filePluginCfg?.modelGatewayBaseUrl === 'string' &&
51
+ filePluginCfg.modelGatewayBaseUrl) ||
52
+ ''
53
+ ).replace(/\/$/, '')
54
+ const token =
55
+ (typeof cfg?.modelGatewayToken === 'string' && cfg.modelGatewayToken) ||
56
+ (typeof provider?.apiKey === 'string' && provider.apiKey) ||
57
+ (typeof filePluginCfg?.modelGatewayToken === 'string' && filePluginCfg.modelGatewayToken) ||
58
+ ''
59
+
60
+ if (!baseUrl || !token) {
61
+ respond(true, {
62
+ ...(dryRun ? {ok: false} : {repaired: false}),
63
+ detail: 'Plugin config missing modelGatewayBaseUrl or modelGatewayToken — cannot repair',
64
+ })
65
+ return
66
+ }
67
+
68
+ // Check current provider state
52
69
  const currentBaseUrl = typeof provider?.baseUrl === 'string' ? provider.baseUrl : ''
53
70
  const currentApiKey = typeof provider?.apiKey === 'string' ? provider.apiKey : ''
54
71
 
package/gateway/index.ts CHANGED
@@ -8,6 +8,7 @@ import {registerNotification} from './notification'
8
8
  import {registerOfflinePush} from './offline-push'
9
9
  import {registerPlugins} from './plugins'
10
10
  import {registerPresence} from './presence'
11
+ import {registerVersion} from './version'
11
12
 
12
13
  export function registerGateway(api: PluginApi) {
13
14
  registerPresence(api)
@@ -19,4 +20,5 @@ export function registerGateway(api: PluginApi) {
19
20
  registerOfflinePush(api)
20
21
  registerConfigRepair(api)
21
22
  registerPairing(api)
23
+ registerVersion(api)
22
24
  }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * OpenClaw version check — runs `openclaw --version` and returns the result.
3
+ *
4
+ * Method: clawly.version({}) → { version: string }
5
+ */
6
+
7
+ import type {PluginApi} from '../index'
8
+
9
+ export function registerVersion(api: PluginApi) {
10
+ api.registerGatewayMethod('clawly.version', async ({respond}) => {
11
+ const run = api.runtime.system?.runCommandWithTimeout
12
+ if (!run) {
13
+ respond(false, undefined, {
14
+ code: 'no_runtime',
15
+ message: 'runCommandWithTimeout not available',
16
+ })
17
+ return
18
+ }
19
+
20
+ try {
21
+ const result = await run(['openclaw', '--version'], {timeoutMs: 5000})
22
+ if (result.code !== 0) {
23
+ const message = result.killed
24
+ ? `Process killed${result.signal ? ` by ${result.signal}` : ''}`
25
+ : `Exited with code ${result.code}`
26
+ respond(false, undefined, {code: 'non_zero_exit', message})
27
+ return
28
+ }
29
+ const raw = (result.stdout + result.stderr).trim()
30
+ // openclaw --version typically outputs something like "openclaw/2026.2.24 ..."
31
+ // Extract just the version portion
32
+ const match = raw.match(/(\d{4}\.\d+\.\d+)/)
33
+ const version = match ? match[1] : raw
34
+ respond(true, {version})
35
+ } catch (err) {
36
+ respond(false, undefined, {
37
+ code: 'exec_failed',
38
+ message: err instanceof Error ? err.message : 'Failed to get version',
39
+ })
40
+ }
41
+ })
42
+
43
+ api.logger.info('version: registered clawly.version method')
44
+ }
package/index.ts CHANGED
@@ -8,6 +8,7 @@
8
8
  * - clawly.notification.send — send a push notification directly
9
9
  * - clawly.agent.send — trigger agent turn with a message (+ optional push)
10
10
  * - clawly.agent.echo — echo-wrapped agent message (bypasses LLM)
11
+ * - clawly.version — get the OpenClaw server version
11
12
  * - memory-browser.list — list all .md files in the memory directory
12
13
  * - memory-browser.get — return content of a single .md file
13
14
  * - clawhub2gateway.* — ClawHub CLI RPC bridge (search/install/update/list/explore/inspect/star/unstar)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@2en/clawly-plugins",
3
- "version": "1.21.5",
3
+ "version": "1.22.0",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "repository": {