@2en/clawly-plugins 1.23.1 → 1.24.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/index.ts +3 -0
- package/internal/hooks/auto-update.ts +122 -0
- package/package.json +3 -2
package/index.ts
CHANGED
|
@@ -27,9 +27,11 @@
|
|
|
27
27
|
* - before_tool_call — enforces delivery fields on cron.create
|
|
28
28
|
* - agent_end — sends push notification when client is offline
|
|
29
29
|
* - gateway_start — auto-approves device pairing for Clawly mobile clients (clientId: openclaw-ios)
|
|
30
|
+
* - gateway_start — registers auto-update cron job (0 3 * * *) for clawly-plugins
|
|
30
31
|
*/
|
|
31
32
|
|
|
32
33
|
import {registerAutoPair} from './auto-pair'
|
|
34
|
+
import {registerAutoUpdate} from './internal/hooks/auto-update'
|
|
33
35
|
import {registerCalendar} from './calendar'
|
|
34
36
|
import {registerCommands} from './command'
|
|
35
37
|
import {setupConfig} from './config-setup'
|
|
@@ -186,6 +188,7 @@ export default {
|
|
|
186
188
|
setupConfig(api)
|
|
187
189
|
registerGateway(api)
|
|
188
190
|
registerAutoPair(api)
|
|
191
|
+
registerAutoUpdate(api)
|
|
189
192
|
|
|
190
193
|
// Email & calendar (optional — requires skillGatewayBaseUrl + skillGatewayToken in config)
|
|
191
194
|
const gw = getGatewayConfig(api)
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registers a cron job (0 3 * * *) on gateway_start that
|
|
3
|
+
* checks user presence and auto-updates clawly-plugins when offline.
|
|
4
|
+
*/
|
|
5
|
+
import {$} from 'zx'
|
|
6
|
+
|
|
7
|
+
import type {PluginApi} from '../../index'
|
|
8
|
+
|
|
9
|
+
$.verbose = false
|
|
10
|
+
|
|
11
|
+
// ── Types ──────────────────────────────────────────────────────
|
|
12
|
+
|
|
13
|
+
interface CronJobEntry {
|
|
14
|
+
id: string
|
|
15
|
+
name: string
|
|
16
|
+
description: string
|
|
17
|
+
enabled: boolean
|
|
18
|
+
schedule: {kind: 'cron'; expr: string; tz?: string} | {kind: string}
|
|
19
|
+
sessionTarget: string
|
|
20
|
+
wakeMode: string
|
|
21
|
+
payload: {kind: string; message?: string}
|
|
22
|
+
delivery: {mode: string}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface JobConfig {
|
|
26
|
+
description: string
|
|
27
|
+
cron: string
|
|
28
|
+
session: 'main' | 'isolated'
|
|
29
|
+
wake: 'now' | 'next-heartbeat'
|
|
30
|
+
deliver: boolean
|
|
31
|
+
message: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ── Config ─────────────────────────────────────────────────────
|
|
35
|
+
|
|
36
|
+
const JOB_NAME = 'Clawly Plugins Auto-Update'
|
|
37
|
+
|
|
38
|
+
const JOB_CONFIG: JobConfig = {
|
|
39
|
+
description: 'Auto-update clawly-plugins when user is offline',
|
|
40
|
+
cron: '0 3 * * *',
|
|
41
|
+
session: 'isolated',
|
|
42
|
+
wake: 'now',
|
|
43
|
+
deliver: false,
|
|
44
|
+
message: [
|
|
45
|
+
'Auto-update check for clawly-plugins.',
|
|
46
|
+
'',
|
|
47
|
+
'Steps:',
|
|
48
|
+
'1. Call the clawly_is_user_online tool to check if the user is online.',
|
|
49
|
+
'2. If the user IS online, stop — do nothing.',
|
|
50
|
+
'3. If the user is NOT online, run this exact command in terminal:',
|
|
51
|
+
` openclaw gateway call clawly.plugins.update --json --params '${JSON.stringify({pluginId: 'clawly-plugins', npmPkgName: '@2en/clawly-plugins', strategy: 'force', restart: true})}'`,
|
|
52
|
+
'',
|
|
53
|
+
'Do not send any messages to the user. Just execute the steps silently.',
|
|
54
|
+
].join('\n'),
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// ── Helpers ────────────────────────────────────────────────────
|
|
58
|
+
|
|
59
|
+
function configToArgs(config: JobConfig): string[] {
|
|
60
|
+
const args = [
|
|
61
|
+
'--description',
|
|
62
|
+
config.description,
|
|
63
|
+
'--cron',
|
|
64
|
+
config.cron,
|
|
65
|
+
'--session',
|
|
66
|
+
config.session,
|
|
67
|
+
'--wake',
|
|
68
|
+
config.wake,
|
|
69
|
+
'--message',
|
|
70
|
+
config.message,
|
|
71
|
+
]
|
|
72
|
+
if (!config.deliver) args.push('--no-deliver')
|
|
73
|
+
return args
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function needsUpdate(job: CronJobEntry, config: JobConfig): boolean {
|
|
77
|
+
if (job.description !== config.description) return true
|
|
78
|
+
if (job.schedule.kind !== 'cron' || (job.schedule as {expr: string}).expr !== config.cron)
|
|
79
|
+
return true
|
|
80
|
+
if (job.sessionTarget !== config.session) return true
|
|
81
|
+
if (job.wakeMode !== config.wake) return true
|
|
82
|
+
if (job.payload.message !== config.message) return true
|
|
83
|
+
const wantMode = config.deliver ? 'announce' : 'none'
|
|
84
|
+
if (job.delivery.mode !== wantMode) return true
|
|
85
|
+
return false
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function findJob(): Promise<CronJobEntry | null> {
|
|
89
|
+
try {
|
|
90
|
+
const {stdout} = await $`openclaw cron list --json`
|
|
91
|
+
const parsed = JSON.parse(stdout)
|
|
92
|
+
const jobs: unknown[] = parsed?.jobs ?? parsed ?? []
|
|
93
|
+
if (!Array.isArray(jobs)) return null
|
|
94
|
+
return (jobs.find((j: any) => j.name === JOB_NAME) as CronJobEntry) ?? null
|
|
95
|
+
} catch {
|
|
96
|
+
return null
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ── Registration ───────────────────────────────────────────────
|
|
101
|
+
|
|
102
|
+
export function registerAutoUpdate(api: PluginApi) {
|
|
103
|
+
api.on('gateway_start', async () => {
|
|
104
|
+
try {
|
|
105
|
+
const existing = await findJob()
|
|
106
|
+
|
|
107
|
+
if (existing) {
|
|
108
|
+
if (!needsUpdate(existing, JOB_CONFIG)) {
|
|
109
|
+
api.logger.info('auto-update: cron job up to date')
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
await $`openclaw cron edit ${[existing.id, ...configToArgs(JOB_CONFIG)]}`
|
|
113
|
+
api.logger.info('auto-update: updated cron job')
|
|
114
|
+
} else {
|
|
115
|
+
await $`openclaw cron add ${['--name', JOB_NAME, ...configToArgs(JOB_CONFIG)]}`
|
|
116
|
+
api.logger.info('auto-update: registered cron job')
|
|
117
|
+
}
|
|
118
|
+
} catch (err) {
|
|
119
|
+
api.logger.warn(`auto-update: failed to register cron job: ${String(err)}`)
|
|
120
|
+
}
|
|
121
|
+
})
|
|
122
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@2en/clawly-plugins",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.0",
|
|
4
4
|
"module": "index.ts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"outbound.ts",
|
|
27
27
|
"model-gateway-setup.ts",
|
|
28
28
|
"skill-command-restore.ts",
|
|
29
|
-
"openclaw.plugin.json"
|
|
29
|
+
"openclaw.plugin.json",
|
|
30
|
+
"internal"
|
|
30
31
|
],
|
|
31
32
|
"publishConfig": {
|
|
32
33
|
"access": "public"
|