@2en/clawly-plugins 1.24.2-beta.0 → 1.24.3

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.
@@ -0,0 +1,963 @@
1
+ /**
2
+ * Standalone OpenClaw configuration types.
3
+ *
4
+ * Derived from openclaw/src/config/types.openclaw.ts and its transitive
5
+ * dependencies. Kept self-contained so the plugin package does not need a
6
+ * build-time dependency on the openclaw source tree.
7
+ *
8
+ * When the upstream types change, diff against the openclaw fork at
9
+ * src/config/types.*.ts
10
+ * and update this file accordingly.
11
+ */
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // Auth
15
+ // ---------------------------------------------------------------------------
16
+
17
+ export type AuthProfileConfig = {
18
+ provider: string
19
+ mode: 'api_key' | 'oauth' | 'token'
20
+ email?: string
21
+ }
22
+
23
+ export type AuthConfig = {
24
+ profiles?: Record<string, AuthProfileConfig>
25
+ order?: Record<string, string[]>
26
+ cooldowns?: {
27
+ billingBackoffHours?: number
28
+ billingBackoffHoursByProvider?: Record<string, number>
29
+ billingMaxHours?: number
30
+ failureWindowHours?: number
31
+ }
32
+ }
33
+
34
+ // ---------------------------------------------------------------------------
35
+ // Base (shared primitives)
36
+ // ---------------------------------------------------------------------------
37
+
38
+ export type TypingMode = 'never' | 'instant' | 'thinking' | 'message'
39
+
40
+ export type HumanDelayConfig = {
41
+ mode?: 'off' | 'natural' | 'custom'
42
+ minMs?: number
43
+ maxMs?: number
44
+ }
45
+
46
+ export type BlockStreamingCoalesceConfig = {
47
+ minChars?: number
48
+ maxChars?: number
49
+ idleMs?: number
50
+ }
51
+
52
+ export type BlockStreamingChunkConfig = {
53
+ minChars?: number
54
+ maxChars?: number
55
+ breakPreference?: 'paragraph' | 'newline' | 'sentence'
56
+ }
57
+
58
+ export type IdentityConfig = {
59
+ name?: string
60
+ theme?: string
61
+ emoji?: string
62
+ avatar?: string
63
+ }
64
+
65
+ export type SessionResetConfig = {
66
+ mode?: 'daily' | 'idle'
67
+ atHour?: number
68
+ idleMinutes?: number
69
+ }
70
+
71
+ export type SessionSendPolicyAction = 'allow' | 'deny'
72
+
73
+ export type SessionSendPolicyConfig = {
74
+ default?: SessionSendPolicyAction
75
+ rules?: Array<{
76
+ action: SessionSendPolicyAction
77
+ match?: {channel?: string; chatType?: string; keyPrefix?: string; rawKeyPrefix?: string}
78
+ }>
79
+ }
80
+
81
+ export type SessionConfig = {
82
+ scope?: 'per-sender' | 'global'
83
+ dmScope?: 'main' | 'per-peer' | 'per-channel-peer' | 'per-account-channel-peer'
84
+ identityLinks?: Record<string, string[]>
85
+ resetTriggers?: string[]
86
+ idleMinutes?: number
87
+ reset?: SessionResetConfig
88
+ resetByType?: {
89
+ direct?: SessionResetConfig
90
+ dm?: SessionResetConfig
91
+ group?: SessionResetConfig
92
+ thread?: SessionResetConfig
93
+ }
94
+ resetByChannel?: Record<string, SessionResetConfig>
95
+ store?: string
96
+ typingIntervalSeconds?: number
97
+ typingMode?: TypingMode
98
+ mainKey?: string
99
+ sendPolicy?: SessionSendPolicyConfig
100
+ agentToAgent?: {maxPingPongTurns?: number}
101
+ maintenance?: {
102
+ mode?: 'enforce' | 'warn'
103
+ pruneAfter?: string | number
104
+ pruneDays?: number
105
+ maxEntries?: number
106
+ rotateBytes?: number | string
107
+ }
108
+ }
109
+
110
+ export type DiagnosticsConfig = {
111
+ enabled?: boolean
112
+ flags?: string[]
113
+ otel?: {
114
+ enabled?: boolean
115
+ endpoint?: string
116
+ protocol?: 'http/protobuf' | 'grpc'
117
+ headers?: Record<string, string>
118
+ serviceName?: string
119
+ traces?: boolean
120
+ metrics?: boolean
121
+ logs?: boolean
122
+ sampleRate?: number
123
+ flushIntervalMs?: number
124
+ }
125
+ cacheTrace?: {
126
+ enabled?: boolean
127
+ filePath?: string
128
+ includeMessages?: boolean
129
+ includePrompt?: boolean
130
+ includeSystem?: boolean
131
+ }
132
+ }
133
+
134
+ export type LoggingConfig = {
135
+ level?: 'silent' | 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace'
136
+ file?: string
137
+ consoleLevel?: 'silent' | 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace'
138
+ consoleStyle?: 'pretty' | 'compact' | 'json'
139
+ redactSensitive?: 'off' | 'tools'
140
+ redactPatterns?: string[]
141
+ }
142
+
143
+ export type WebConfig = {
144
+ enabled?: boolean
145
+ heartbeatSeconds?: number
146
+ reconnect?: {
147
+ initialMs?: number
148
+ maxMs?: number
149
+ factor?: number
150
+ jitter?: number
151
+ maxAttempts?: number
152
+ }
153
+ }
154
+
155
+ // ---------------------------------------------------------------------------
156
+ // Browser
157
+ // ---------------------------------------------------------------------------
158
+
159
+ export type BrowserConfig = {
160
+ enabled?: boolean
161
+ evaluateEnabled?: boolean
162
+ cdpUrl?: string
163
+ remoteCdpTimeoutMs?: number
164
+ remoteCdpHandshakeTimeoutMs?: number
165
+ color?: string
166
+ executablePath?: string
167
+ headless?: boolean
168
+ noSandbox?: boolean
169
+ attachOnly?: boolean
170
+ defaultProfile?: string
171
+ profiles?: Record<
172
+ string,
173
+ {cdpPort?: number; cdpUrl?: string; driver?: 'openclaw' | 'extension'; color: string}
174
+ >
175
+ snapshotDefaults?: {mode?: 'efficient'}
176
+ }
177
+
178
+ // ---------------------------------------------------------------------------
179
+ // Agents
180
+ // ---------------------------------------------------------------------------
181
+
182
+ export type AgentModelConfig = string | {primary?: string; fallbacks?: string[]}
183
+
184
+ export type AgentModelListConfig = {primary?: string; fallbacks?: string[]}
185
+
186
+ export type AgentModelEntryConfig = {
187
+ alias?: string
188
+ params?: Record<string, unknown>
189
+ streaming?: boolean
190
+ }
191
+
192
+ export type AgentDefaultsConfig = {
193
+ model?: AgentModelListConfig
194
+ imageModel?: AgentModelListConfig
195
+ models?: Record<string, AgentModelEntryConfig>
196
+ workspace?: string
197
+ repoRoot?: string
198
+ skipBootstrap?: boolean
199
+ bootstrapMaxChars?: number
200
+ bootstrapTotalMaxChars?: number
201
+ userTimezone?: string
202
+ timeFormat?: 'auto' | '12' | '24'
203
+ envelopeTimezone?: string
204
+ envelopeTimestamp?: 'on' | 'off'
205
+ envelopeElapsed?: 'on' | 'off'
206
+ contextTokens?: number
207
+ cliBackends?: Record<
208
+ string,
209
+ {
210
+ command: string
211
+ args?: string[]
212
+ output?: 'json' | 'text' | 'jsonl'
213
+ resumeOutput?: 'json' | 'text' | 'jsonl'
214
+ input?: 'arg' | 'stdin'
215
+ maxPromptArgChars?: number
216
+ env?: Record<string, string>
217
+ clearEnv?: string[]
218
+ modelArg?: string
219
+ modelAliases?: Record<string, string>
220
+ sessionArg?: string
221
+ sessionArgs?: string[]
222
+ resumeArgs?: string[]
223
+ sessionMode?: 'always' | 'existing' | 'none'
224
+ sessionIdFields?: string[]
225
+ systemPromptArg?: string
226
+ systemPromptMode?: 'append' | 'replace'
227
+ systemPromptWhen?: 'first' | 'always' | 'never'
228
+ imageArg?: string
229
+ imageMode?: 'repeat' | 'list'
230
+ serialize?: boolean
231
+ }
232
+ >
233
+ contextPruning?: {
234
+ mode?: 'off' | 'cache-ttl'
235
+ ttl?: string
236
+ keepLastAssistants?: number
237
+ softTrimRatio?: number
238
+ hardClearRatio?: number
239
+ minPrunableToolChars?: number
240
+ tools?: {allow?: string[]; deny?: string[]}
241
+ softTrim?: {maxChars?: number; headChars?: number; tailChars?: number}
242
+ hardClear?: {enabled?: boolean; placeholder?: string}
243
+ }
244
+ compaction?: {
245
+ mode?: 'default' | 'safeguard'
246
+ reserveTokensFloor?: number
247
+ maxHistoryShare?: number
248
+ memoryFlush?: {
249
+ enabled?: boolean
250
+ softThresholdTokens?: number
251
+ prompt?: string
252
+ systemPrompt?: string
253
+ }
254
+ }
255
+ memorySearch?: MemorySearchConfig
256
+ thinkingDefault?: 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh'
257
+ verboseDefault?: 'off' | 'on' | 'full'
258
+ elevatedDefault?: 'off' | 'on' | 'ask' | 'full'
259
+ blockStreamingDefault?: 'off' | 'on'
260
+ blockStreamingBreak?: 'text_end' | 'message_end'
261
+ blockStreamingChunk?: BlockStreamingChunkConfig
262
+ blockStreamingCoalesce?: BlockStreamingCoalesceConfig
263
+ humanDelay?: HumanDelayConfig
264
+ timeoutSeconds?: number
265
+ mediaMaxMb?: number
266
+ typingIntervalSeconds?: number
267
+ typingMode?: TypingMode
268
+ heartbeat?: {
269
+ every?: string
270
+ activeHours?: {start?: string; end?: string; timezone?: string}
271
+ model?: string
272
+ session?: string
273
+ target?: 'last' | 'none' | string
274
+ to?: string
275
+ accountId?: string
276
+ prompt?: string
277
+ ackMaxChars?: number
278
+ includeReasoning?: boolean
279
+ }
280
+ maxConcurrent?: number
281
+ subagents?: {
282
+ maxConcurrent?: number
283
+ maxSpawnDepth?: number
284
+ maxChildrenPerAgent?: number
285
+ archiveAfterMinutes?: number
286
+ model?: string | {primary?: string; fallbacks?: string[]}
287
+ thinking?: string
288
+ }
289
+ sandbox?: {
290
+ mode?: 'off' | 'non-main' | 'all'
291
+ workspaceAccess?: 'none' | 'ro' | 'rw'
292
+ sessionToolsVisibility?: 'spawned' | 'all'
293
+ scope?: 'session' | 'agent' | 'shared'
294
+ perSession?: boolean
295
+ workspaceRoot?: string
296
+ docker?: Record<string, unknown>
297
+ browser?: Record<string, unknown>
298
+ prune?: Record<string, unknown>
299
+ }
300
+ }
301
+
302
+ export type AgentConfig = {
303
+ id: string
304
+ default?: boolean
305
+ name?: string
306
+ workspace?: string
307
+ agentDir?: string
308
+ model?: AgentModelConfig
309
+ skills?: string[]
310
+ memorySearch?: MemorySearchConfig
311
+ humanDelay?: HumanDelayConfig
312
+ heartbeat?: AgentDefaultsConfig['heartbeat']
313
+ identity?: IdentityConfig
314
+ groupChat?: {mentionPatterns?: string[]; historyLimit?: number}
315
+ subagents?: {allowAgents?: string[]; model?: string | {primary?: string; fallbacks?: string[]}}
316
+ sandbox?: {
317
+ mode?: 'off' | 'non-main' | 'all'
318
+ workspaceAccess?: 'none' | 'ro' | 'rw'
319
+ sessionToolsVisibility?: 'spawned' | 'all'
320
+ scope?: 'session' | 'agent' | 'shared'
321
+ perSession?: boolean
322
+ workspaceRoot?: string
323
+ docker?: Record<string, unknown>
324
+ browser?: Record<string, unknown>
325
+ prune?: Record<string, unknown>
326
+ }
327
+ tools?: AgentToolsConfig
328
+ }
329
+
330
+ export type AgentsConfig = {
331
+ defaults?: AgentDefaultsConfig
332
+ list?: AgentConfig[]
333
+ }
334
+
335
+ export type AgentBinding = {
336
+ agentId: string
337
+ match: {
338
+ channel: string
339
+ accountId?: string
340
+ peer?: {kind: string; id: string}
341
+ guildId?: string
342
+ teamId?: string
343
+ roles?: string[]
344
+ }
345
+ }
346
+
347
+ // ---------------------------------------------------------------------------
348
+ // Models
349
+ // ---------------------------------------------------------------------------
350
+
351
+ export type ModelApi =
352
+ | 'openai-completions'
353
+ | 'openai-responses'
354
+ | 'anthropic-messages'
355
+ | 'google-generative-ai'
356
+ | 'github-copilot'
357
+ | 'bedrock-converse-stream'
358
+ | 'ollama'
359
+
360
+ export type ModelDefinitionConfig = {
361
+ id: string
362
+ name: string
363
+ api?: ModelApi
364
+ reasoning: boolean
365
+ input: Array<'text' | 'image'>
366
+ cost: {input: number; output: number; cacheRead: number; cacheWrite: number}
367
+ contextWindow: number
368
+ maxTokens: number
369
+ headers?: Record<string, string>
370
+ compat?: {
371
+ supportsStore?: boolean
372
+ supportsDeveloperRole?: boolean
373
+ supportsReasoningEffort?: boolean
374
+ supportsUsageInStreaming?: boolean
375
+ supportsStrictMode?: boolean
376
+ maxTokensField?: 'max_completion_tokens' | 'max_tokens'
377
+ thinkingFormat?: 'openai' | 'zai' | 'qwen'
378
+ requiresToolResultName?: boolean
379
+ requiresAssistantAfterToolResult?: boolean
380
+ requiresThinkingAsText?: boolean
381
+ requiresMistralToolIds?: boolean
382
+ }
383
+ }
384
+
385
+ export type ModelProviderConfig = {
386
+ baseUrl: string
387
+ apiKey?: string
388
+ auth?: 'api-key' | 'aws-sdk' | 'oauth' | 'token'
389
+ api?: ModelApi
390
+ headers?: Record<string, string>
391
+ authHeader?: boolean
392
+ models: ModelDefinitionConfig[]
393
+ }
394
+
395
+ export type ModelsConfig = {
396
+ mode?: 'merge' | 'replace'
397
+ providers?: Record<string, ModelProviderConfig>
398
+ bedrockDiscovery?: {
399
+ enabled?: boolean
400
+ region?: string
401
+ providerFilter?: string[]
402
+ refreshInterval?: number
403
+ defaultContextWindow?: number
404
+ defaultMaxTokens?: number
405
+ }
406
+ }
407
+
408
+ // ---------------------------------------------------------------------------
409
+ // Tools
410
+ // ---------------------------------------------------------------------------
411
+
412
+ export type ExecToolConfig = {
413
+ host?: 'sandbox' | 'gateway' | 'node'
414
+ security?: 'deny' | 'allowlist' | 'full'
415
+ ask?: 'off' | 'on-miss' | 'always'
416
+ node?: string
417
+ pathPrepend?: string[]
418
+ safeBins?: string[]
419
+ backgroundMs?: number
420
+ timeoutSec?: number
421
+ approvalRunningNoticeMs?: number
422
+ cleanupMs?: number
423
+ notifyOnExit?: boolean
424
+ notifyOnExitEmptySuccess?: boolean
425
+ applyPatch?: {enabled?: boolean; workspaceOnly?: boolean; allowModels?: string[]}
426
+ }
427
+
428
+ export type MemorySearchConfig = {
429
+ enabled?: boolean
430
+ sources?: Array<'memory' | 'sessions'>
431
+ extraPaths?: string[]
432
+ experimental?: {sessionMemory?: boolean}
433
+ provider?: 'openai' | 'gemini' | 'local' | 'voyage'
434
+ remote?: {
435
+ baseUrl?: string
436
+ apiKey?: string
437
+ headers?: Record<string, string>
438
+ batch?: {
439
+ enabled?: boolean
440
+ wait?: boolean
441
+ concurrency?: number
442
+ pollIntervalMs?: number
443
+ timeoutMinutes?: number
444
+ }
445
+ }
446
+ fallback?: 'openai' | 'gemini' | 'local' | 'voyage' | 'none'
447
+ model?: string
448
+ local?: {modelPath?: string; modelCacheDir?: string}
449
+ store?: {
450
+ driver?: 'sqlite'
451
+ path?: string
452
+ vector?: {enabled?: boolean; extensionPath?: string}
453
+ cache?: {enabled?: boolean; maxEntries?: number}
454
+ }
455
+ chunking?: {tokens?: number; overlap?: number}
456
+ sync?: {
457
+ onSessionStart?: boolean
458
+ onSearch?: boolean
459
+ watch?: boolean
460
+ watchDebounceMs?: number
461
+ intervalMinutes?: number
462
+ sessions?: {deltaBytes?: number; deltaMessages?: number}
463
+ }
464
+ query?: {
465
+ maxResults?: number
466
+ minScore?: number
467
+ hybrid?: {
468
+ enabled?: boolean
469
+ vectorWeight?: number
470
+ textWeight?: number
471
+ candidateMultiplier?: number
472
+ }
473
+ }
474
+ cache?: {enabled?: boolean; maxEntries?: number}
475
+ }
476
+
477
+ export type AgentToolsConfig = {
478
+ profile?: 'minimal' | 'coding' | 'messaging' | 'full'
479
+ allow?: string[]
480
+ alsoAllow?: string[]
481
+ deny?: string[]
482
+ byProvider?: Record<
483
+ string,
484
+ {allow?: string[]; alsoAllow?: string[]; deny?: string[]; profile?: string}
485
+ >
486
+ elevated?: {enabled?: boolean; allowFrom?: Record<string, Array<string | number>>}
487
+ exec?: ExecToolConfig
488
+ fs?: {workspaceOnly?: boolean}
489
+ sandbox?: {tools?: {allow?: string[]; deny?: string[]}}
490
+ }
491
+
492
+ export type ToolsConfig = {
493
+ profile?: 'minimal' | 'coding' | 'messaging' | 'full'
494
+ allow?: string[]
495
+ alsoAllow?: string[]
496
+ deny?: string[]
497
+ byProvider?: Record<
498
+ string,
499
+ {allow?: string[]; alsoAllow?: string[]; deny?: string[]; profile?: string}
500
+ >
501
+ web?: {
502
+ search?: {
503
+ enabled?: boolean
504
+ provider?: 'brave' | 'perplexity' | 'grok'
505
+ apiKey?: string
506
+ maxResults?: number
507
+ timeoutSeconds?: number
508
+ cacheTtlMinutes?: number
509
+ perplexity?: {apiKey?: string; baseUrl?: string; model?: string}
510
+ grok?: {apiKey?: string; model?: string; inlineCitations?: boolean}
511
+ }
512
+ fetch?: {
513
+ enabled?: boolean
514
+ maxChars?: number
515
+ maxCharsCap?: number
516
+ timeoutSeconds?: number
517
+ cacheTtlMinutes?: number
518
+ maxRedirects?: number
519
+ userAgent?: string
520
+ readability?: boolean
521
+ firecrawl?: {
522
+ enabled?: boolean
523
+ apiKey?: string
524
+ baseUrl?: string
525
+ onlyMainContent?: boolean
526
+ maxAgeMs?: number
527
+ timeoutSeconds?: number
528
+ }
529
+ }
530
+ }
531
+ media?: {
532
+ models?: Array<Record<string, unknown>>
533
+ concurrency?: number
534
+ image?: Record<string, unknown>
535
+ audio?: Record<string, unknown>
536
+ video?: Record<string, unknown>
537
+ }
538
+ links?: {
539
+ enabled?: boolean
540
+ scope?: Record<string, unknown>
541
+ maxLinks?: number
542
+ timeoutSeconds?: number
543
+ models?: Array<Record<string, unknown>>
544
+ }
545
+ message?: {
546
+ allowCrossContextSend?: boolean
547
+ crossContext?: {
548
+ allowWithinProvider?: boolean
549
+ allowAcrossProviders?: boolean
550
+ marker?: {enabled?: boolean; prefix?: string; suffix?: string}
551
+ }
552
+ broadcast?: {enabled?: boolean}
553
+ }
554
+ agentToAgent?: {enabled?: boolean; allow?: string[]}
555
+ elevated?: {enabled?: boolean; allowFrom?: Record<string, Array<string | number>>}
556
+ exec?: ExecToolConfig
557
+ fs?: {workspaceOnly?: boolean}
558
+ subagents?: {
559
+ model?: string | {primary?: string; fallbacks?: string[]}
560
+ tools?: {allow?: string[]; deny?: string[]}
561
+ }
562
+ sandbox?: {tools?: {allow?: string[]; deny?: string[]}}
563
+ }
564
+
565
+ // ---------------------------------------------------------------------------
566
+ // Messages / Commands
567
+ // ---------------------------------------------------------------------------
568
+
569
+ export type MessagesConfig = {
570
+ messagePrefix?: string
571
+ responsePrefix?: string
572
+ groupChat?: {mentionPatterns?: string[]; historyLimit?: number}
573
+ queue?: {
574
+ mode?: string
575
+ byChannel?: Record<string, string>
576
+ debounceMs?: number
577
+ debounceMsByChannel?: Record<string, number>
578
+ cap?: number
579
+ drop?: string
580
+ }
581
+ inbound?: {debounceMs?: number; byChannel?: Record<string, number>}
582
+ ackReaction?: string
583
+ ackReactionScope?: 'group-mentions' | 'group-all' | 'direct' | 'all'
584
+ removeAckAfterReply?: boolean
585
+ suppressToolErrors?: boolean
586
+ tts?: Record<string, unknown>
587
+ }
588
+
589
+ export type CommandsConfig = {
590
+ native?: boolean | 'auto'
591
+ nativeSkills?: boolean | 'auto'
592
+ text?: boolean
593
+ bash?: boolean
594
+ bashForegroundMs?: number
595
+ config?: boolean
596
+ debug?: boolean
597
+ restart?: boolean
598
+ useAccessGroups?: boolean
599
+ ownerAllowFrom?: Array<string | number>
600
+ allowFrom?: Record<string, Array<string | number>>
601
+ }
602
+
603
+ export type BroadcastConfig = {
604
+ strategy?: 'parallel' | 'sequential'
605
+ [peerId: string]: string[] | 'parallel' | 'sequential' | undefined
606
+ }
607
+
608
+ export type AudioConfig = {
609
+ transcription?: {command: string[]; timeoutSeconds?: number}
610
+ }
611
+
612
+ // ---------------------------------------------------------------------------
613
+ // Plugins / Skills
614
+ // ---------------------------------------------------------------------------
615
+
616
+ export type PluginsConfig = {
617
+ enabled?: boolean
618
+ allow?: string[]
619
+ deny?: string[]
620
+ load?: {paths?: string[]}
621
+ slots?: {memory?: string}
622
+ entries?: Record<string, {enabled?: boolean; config?: Record<string, unknown>}>
623
+ installs?: Record<
624
+ string,
625
+ {
626
+ source: 'npm' | 'archive' | 'path'
627
+ spec?: string
628
+ sourcePath?: string
629
+ installPath?: string
630
+ version?: string
631
+ installedAt?: string
632
+ }
633
+ >
634
+ }
635
+
636
+ export type SkillsConfig = {
637
+ allowBundled?: string[]
638
+ load?: {extraDirs?: string[]; watch?: boolean; watchDebounceMs?: number}
639
+ install?: {preferBrew?: boolean; nodeManager?: 'npm' | 'pnpm' | 'yarn' | 'bun'}
640
+ entries?: Record<
641
+ string,
642
+ {
643
+ enabled?: boolean
644
+ apiKey?: string
645
+ env?: Record<string, string>
646
+ config?: Record<string, unknown>
647
+ }
648
+ >
649
+ }
650
+
651
+ // ---------------------------------------------------------------------------
652
+ // Approvals
653
+ // ---------------------------------------------------------------------------
654
+
655
+ export type ApprovalsConfig = {
656
+ exec?: {
657
+ enabled?: boolean
658
+ mode?: 'session' | 'targets' | 'both'
659
+ agentFilter?: string[]
660
+ sessionFilter?: string[]
661
+ targets?: Array<{channel: string; to: string; accountId?: string; threadId?: string | number}>
662
+ }
663
+ }
664
+
665
+ // ---------------------------------------------------------------------------
666
+ // Node Host
667
+ // ---------------------------------------------------------------------------
668
+
669
+ export type NodeHostConfig = {
670
+ browserProxy?: {enabled?: boolean; allowProfiles?: string[]}
671
+ }
672
+
673
+ // ---------------------------------------------------------------------------
674
+ // Channels (loosely typed — plugin does not interact with channel specifics)
675
+ // ---------------------------------------------------------------------------
676
+
677
+ export type ChannelsConfig = {
678
+ defaults?: {
679
+ groupPolicy?: string
680
+ heartbeat?: {showOk?: boolean; showAlerts?: boolean; useIndicator?: boolean}
681
+ }
682
+ [key: string]: unknown
683
+ }
684
+
685
+ // ---------------------------------------------------------------------------
686
+ // Cron
687
+ // ---------------------------------------------------------------------------
688
+
689
+ export type CronConfig = {
690
+ enabled?: boolean
691
+ store?: string
692
+ maxConcurrentRuns?: number
693
+ sessionRetention?: string | false
694
+ }
695
+
696
+ // ---------------------------------------------------------------------------
697
+ // Gateway
698
+ // ---------------------------------------------------------------------------
699
+
700
+ export type GatewayConfig = {
701
+ port?: number
702
+ mode?: 'local' | 'remote'
703
+ bind?: 'auto' | 'lan' | 'loopback' | 'custom' | 'tailnet'
704
+ customBindHost?: string
705
+ controlUi?: {
706
+ enabled?: boolean
707
+ basePath?: string
708
+ root?: string
709
+ allowedOrigins?: string[]
710
+ allowInsecureAuth?: boolean
711
+ dangerouslyDisableDeviceAuth?: boolean
712
+ }
713
+ auth?: {
714
+ mode?: 'token' | 'password' | 'trusted-proxy'
715
+ token?: string
716
+ password?: string
717
+ allowTailscale?: boolean
718
+ rateLimit?: {
719
+ maxAttempts?: number
720
+ windowMs?: number
721
+ lockoutMs?: number
722
+ exemptLoopback?: boolean
723
+ }
724
+ trustedProxy?: {userHeader: string; requiredHeaders?: string[]; allowUsers?: string[]}
725
+ }
726
+ tailscale?: {mode?: 'off' | 'serve' | 'funnel'; resetOnExit?: boolean}
727
+ remote?: {
728
+ url?: string
729
+ transport?: 'ssh' | 'direct'
730
+ token?: string
731
+ password?: string
732
+ tlsFingerprint?: string
733
+ sshTarget?: string
734
+ sshIdentity?: string
735
+ }
736
+ reload?: {mode?: 'off' | 'restart' | 'hot' | 'hybrid'; debounceMs?: number}
737
+ tls?: {
738
+ enabled?: boolean
739
+ autoGenerate?: boolean
740
+ certPath?: string
741
+ keyPath?: string
742
+ caPath?: string
743
+ }
744
+ http?: {
745
+ endpoints?: {
746
+ chatCompletions?: {enabled?: boolean}
747
+ responses?: {
748
+ enabled?: boolean
749
+ maxBodyBytes?: number
750
+ maxUrlParts?: number
751
+ files?: Record<string, unknown>
752
+ images?: Record<string, unknown>
753
+ }
754
+ }
755
+ }
756
+ nodes?: {
757
+ browser?: {mode?: 'auto' | 'manual' | 'off'; node?: string}
758
+ allowCommands?: string[]
759
+ denyCommands?: string[]
760
+ }
761
+ trustedProxies?: string[]
762
+ tools?: {deny?: string[]; allow?: string[]}
763
+ }
764
+
765
+ // ---------------------------------------------------------------------------
766
+ // Hooks
767
+ // ---------------------------------------------------------------------------
768
+
769
+ export type HooksConfig = {
770
+ enabled?: boolean
771
+ path?: string
772
+ token?: string
773
+ defaultSessionKey?: string
774
+ allowRequestSessionKey?: boolean
775
+ allowedSessionKeyPrefixes?: string[]
776
+ allowedAgentIds?: string[]
777
+ maxBodyBytes?: number
778
+ presets?: string[]
779
+ transformsDir?: string
780
+ mappings?: Array<{
781
+ id?: string
782
+ match?: {path?: string; source?: string}
783
+ action?: 'wake' | 'agent'
784
+ wakeMode?: 'now' | 'next-heartbeat'
785
+ name?: string
786
+ agentId?: string
787
+ sessionKey?: string
788
+ messageTemplate?: string
789
+ textTemplate?: string
790
+ deliver?: boolean
791
+ allowUnsafeExternalContent?: boolean
792
+ channel?: string
793
+ to?: string
794
+ model?: string
795
+ thinking?: string
796
+ timeoutSeconds?: number
797
+ transform?: {module: string; export?: string}
798
+ }>
799
+ gmail?: Record<string, unknown>
800
+ internal?: {
801
+ enabled?: boolean
802
+ handlers?: Array<{event: string; module: string; export?: string}>
803
+ entries?: Record<
804
+ string,
805
+ {enabled?: boolean; env?: Record<string, string>; [key: string]: unknown}
806
+ >
807
+ load?: {extraDirs?: string[]}
808
+ installs?: Record<
809
+ string,
810
+ {
811
+ source: 'npm' | 'archive' | 'path'
812
+ spec?: string
813
+ sourcePath?: string
814
+ installPath?: string
815
+ version?: string
816
+ installedAt?: string
817
+ hooks?: string[]
818
+ }
819
+ >
820
+ }
821
+ }
822
+
823
+ // ---------------------------------------------------------------------------
824
+ // Memory
825
+ // ---------------------------------------------------------------------------
826
+
827
+ export type MemoryConfig = {
828
+ backend?: 'builtin' | 'qmd'
829
+ citations?: 'auto' | 'on' | 'off'
830
+ qmd?: {
831
+ command?: string
832
+ searchMode?: 'query' | 'search' | 'vsearch'
833
+ includeDefaultMemory?: boolean
834
+ paths?: Array<{path: string; name?: string; pattern?: string}>
835
+ sessions?: {enabled?: boolean; exportDir?: string; retentionDays?: number}
836
+ update?: {
837
+ interval?: string
838
+ debounceMs?: number
839
+ onBoot?: boolean
840
+ waitForBootSync?: boolean
841
+ embedInterval?: string
842
+ commandTimeoutMs?: number
843
+ updateTimeoutMs?: number
844
+ embedTimeoutMs?: number
845
+ }
846
+ limits?: {
847
+ maxResults?: number
848
+ maxSnippetChars?: number
849
+ maxInjectedChars?: number
850
+ timeoutMs?: number
851
+ }
852
+ scope?: SessionSendPolicyConfig
853
+ }
854
+ }
855
+
856
+ // ---------------------------------------------------------------------------
857
+ // Discovery / Canvas / Talk
858
+ // ---------------------------------------------------------------------------
859
+
860
+ export type DiscoveryConfig = {
861
+ wideArea?: {enabled?: boolean; domain?: string}
862
+ mdns?: {mode?: 'off' | 'minimal' | 'full'}
863
+ }
864
+
865
+ export type CanvasHostConfig = {
866
+ enabled?: boolean
867
+ root?: string
868
+ port?: number
869
+ liveReload?: boolean
870
+ }
871
+
872
+ export type TalkConfig = {
873
+ voiceId?: string
874
+ voiceAliases?: Record<string, string>
875
+ modelId?: string
876
+ outputFormat?: string
877
+ apiKey?: string
878
+ interruptOnSpeech?: boolean
879
+ }
880
+
881
+ // ---------------------------------------------------------------------------
882
+ // Top-level config
883
+ // ---------------------------------------------------------------------------
884
+
885
+ export type OpenClawConfig = {
886
+ meta?: {
887
+ lastTouchedVersion?: string
888
+ lastTouchedAt?: string
889
+ }
890
+ auth?: AuthConfig
891
+ env?: {
892
+ shellEnv?: {enabled?: boolean; timeoutMs?: number}
893
+ vars?: Record<string, string>
894
+ [key: string]:
895
+ | string
896
+ | Record<string, string>
897
+ | {enabled?: boolean; timeoutMs?: number}
898
+ | undefined
899
+ }
900
+ wizard?: {
901
+ lastRunAt?: string
902
+ lastRunVersion?: string
903
+ lastRunCommit?: string
904
+ lastRunCommand?: string
905
+ lastRunMode?: 'local' | 'remote'
906
+ }
907
+ diagnostics?: DiagnosticsConfig
908
+ logging?: LoggingConfig
909
+ update?: {
910
+ channel?: 'stable' | 'beta' | 'dev'
911
+ checkOnStart?: boolean
912
+ }
913
+ browser?: BrowserConfig
914
+ ui?: {
915
+ seamColor?: string
916
+ assistant?: {name?: string; avatar?: string}
917
+ }
918
+ skills?: SkillsConfig
919
+ plugins?: PluginsConfig
920
+ models?: ModelsConfig
921
+ nodeHost?: NodeHostConfig
922
+ agents?: AgentsConfig
923
+ tools?: ToolsConfig
924
+ bindings?: AgentBinding[]
925
+ broadcast?: BroadcastConfig
926
+ audio?: AudioConfig
927
+ messages?: MessagesConfig
928
+ commands?: CommandsConfig
929
+ approvals?: ApprovalsConfig
930
+ session?: SessionConfig
931
+ web?: WebConfig
932
+ channels?: ChannelsConfig
933
+ cron?: CronConfig
934
+ hooks?: HooksConfig
935
+ discovery?: DiscoveryConfig
936
+ canvasHost?: CanvasHostConfig
937
+ talk?: TalkConfig
938
+ gateway?: GatewayConfig
939
+ memory?: MemoryConfig
940
+ }
941
+
942
+ // ---------------------------------------------------------------------------
943
+ // Config file snapshot (returned by runtime config loaders)
944
+ // ---------------------------------------------------------------------------
945
+
946
+ export type ConfigValidationIssue = {
947
+ path: string
948
+ message: string
949
+ }
950
+
951
+ export type ConfigFileSnapshot = {
952
+ path: string
953
+ exists: boolean
954
+ raw: string | null
955
+ parsed: unknown
956
+ resolved: OpenClawConfig
957
+ valid: boolean
958
+ config: OpenClawConfig
959
+ hash?: string
960
+ issues: ConfigValidationIssue[]
961
+ warnings: ConfigValidationIssue[]
962
+ legacyIssues: ConfigValidationIssue[]
963
+ }