clawchef 0.1.10 → 0.1.11
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 +4 -1
- package/dist/openclaw/command-provider.js +20 -4
- package/dist/recipe.js +3 -0
- package/dist/schema.d.ts +5 -0
- package/dist/schema.js +1 -0
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/openclaw/command-provider.ts +23 -4
- package/src/recipe.ts +6 -0
- package/src/schema.ts +1 -0
- package/src/types.ts +1 -0
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ Recipe-driven OpenClaw environment orchestrator.
|
|
|
14
14
|
- When installed OpenClaw version mismatches recipe version, prompts: ignore / abort / force reinstall (silent mode auto-picks force reinstall).
|
|
15
15
|
- Supports scoped execution via `--scope full|files|workspace`.
|
|
16
16
|
- `full` scope runs factory reset first (with confirmation prompt unless `-s/--silent` is used).
|
|
17
|
+
- Factory reset includes removing local `~/.openclaw` directory.
|
|
17
18
|
- If `openclaw` is missing, auto-installs the recipe version and skips factory reset.
|
|
18
19
|
- Starts OpenClaw gateway after each recipe execution based on `--gateway-mode`.
|
|
19
20
|
- Creates workspaces and agents (default workspace path: `~/.openclaw/workspace-<workspace-name>`).
|
|
@@ -392,6 +393,7 @@ channels:
|
|
|
392
393
|
token: "${telegram_bot_token}"
|
|
393
394
|
account: "default"
|
|
394
395
|
agent: "main"
|
|
396
|
+
group_policy: "allowlist"
|
|
395
397
|
|
|
396
398
|
- channel: "telegram"
|
|
397
399
|
token: "${alerts_bot_token}"
|
|
@@ -412,11 +414,12 @@ channels:
|
|
|
412
414
|
Supported common fields:
|
|
413
415
|
|
|
414
416
|
- required: `channel`
|
|
415
|
-
- optional: `account`, `agent`, `name`, `token`, `token_file`, `use_env`, `bot_token`, `access_token`, `app_token`, `webhook_url`, `webhook_path`, `signal_number`, `password`, `login`, `login_mode`, `login_account`
|
|
417
|
+
- optional: `account`, `agent`, `group_policy`, `name`, `token`, `token_file`, `use_env`, `bot_token`, `access_token`, `app_token`, `webhook_url`, `webhook_path`, `signal_number`, `password`, `login`, `login_mode`, `login_account`
|
|
416
418
|
- advanced passthrough: `extra_flags` (`snake_case` keys become `--kebab-case` CLI flags)
|
|
417
419
|
|
|
418
420
|
`channels[].agent` currently supports `channel: "telegram"` only.
|
|
419
421
|
If `agent` is set and `account` is omitted, clawchef defaults `account` to the same value as `agent`.
|
|
422
|
+
`channels[].group_policy` currently supports `channel: "telegram"` only and is applied after `channels add` via `openclaw config set` so it is not overwritten by add-flow writes.
|
|
420
423
|
|
|
421
424
|
## Workspace path behavior
|
|
422
425
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { tmpdir } from "node:os";
|
|
1
|
+
import { homedir, tmpdir } from "node:os";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import process from "node:process";
|
|
4
4
|
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
@@ -129,6 +129,13 @@ function parseVersionOutput(output) {
|
|
|
129
129
|
const match = output.match(/\b(\d+\.\d+\.\d+)\b/);
|
|
130
130
|
return match?.[1] ?? output.trim();
|
|
131
131
|
}
|
|
132
|
+
function telegramGroupPolicyPath(account) {
|
|
133
|
+
const trimmed = account?.trim();
|
|
134
|
+
if (!trimmed) {
|
|
135
|
+
return "channels.telegram.groupPolicy";
|
|
136
|
+
}
|
|
137
|
+
return `channels.telegram.accounts[${trimmed}].groupPolicy`;
|
|
138
|
+
}
|
|
132
139
|
async function chooseVersionMismatchAction(currentVersion, expectedVersion, silent) {
|
|
133
140
|
if (silent) {
|
|
134
141
|
return "force";
|
|
@@ -341,10 +348,13 @@ export class CommandOpenClawProvider {
|
|
|
341
348
|
async factoryReset(config, dryRun) {
|
|
342
349
|
const bin = config.bin ?? "openclaw";
|
|
343
350
|
const resetCmd = commandFor(config, "factory_reset", { bin, version: config.version });
|
|
344
|
-
if (
|
|
345
|
-
|
|
351
|
+
if (resetCmd.trim()) {
|
|
352
|
+
await runShell(resetCmd, dryRun);
|
|
353
|
+
}
|
|
354
|
+
const openclawHome = path.join(homedir(), ".openclaw");
|
|
355
|
+
if (!dryRun) {
|
|
356
|
+
await rm(openclawHome, { recursive: true, force: true });
|
|
346
357
|
}
|
|
347
|
-
await runShell(resetCmd, dryRun);
|
|
348
358
|
}
|
|
349
359
|
async installPlugin(config, pluginSpec, dryRun) {
|
|
350
360
|
const trimmed = pluginSpec.trim();
|
|
@@ -443,6 +453,12 @@ export class CommandOpenClawProvider {
|
|
|
443
453
|
}
|
|
444
454
|
const cmd = `${bin} channels add ${flags.join(" ")}`;
|
|
445
455
|
await runShell(cmd, dryRun);
|
|
456
|
+
if (channel.channel === "telegram" && channel.group_policy) {
|
|
457
|
+
const configPath = telegramGroupPolicyPath(channel.account);
|
|
458
|
+
const policyValue = JSON.stringify(channel.group_policy);
|
|
459
|
+
const setPolicyCmd = `${bin} config set ${shellQuote(configPath)} ${shellQuote(policyValue)} --strict-json`;
|
|
460
|
+
await runShell(setPolicyCmd, dryRun);
|
|
461
|
+
}
|
|
446
462
|
}
|
|
447
463
|
async bindChannelAgent(config, channel, agent, dryRun) {
|
|
448
464
|
const account = channel.account?.trim();
|
package/dist/recipe.js
CHANGED
|
@@ -193,6 +193,9 @@ function semanticValidate(recipe) {
|
|
|
193
193
|
(channel.login || channel.login_mode !== undefined || channel.login_account !== undefined)) {
|
|
194
194
|
throw new ClawChefError("channels[] entry for telegram does not support login/login_mode/login_account. Configure token (or use_env/token_file), then start gateway.");
|
|
195
195
|
}
|
|
196
|
+
if (channel.group_policy !== undefined && channel.channel !== "telegram") {
|
|
197
|
+
throw new ClawChefError(`channels[] entry for ${channel.channel} does not support group_policy. Use channel: telegram.`);
|
|
198
|
+
}
|
|
196
199
|
if (channel.agent?.trim()) {
|
|
197
200
|
if (channel.channel !== "telegram") {
|
|
198
201
|
throw new ClawChefError(`channels[] entry for ${channel.channel} does not support agent binding. Use channel: telegram with agent.`);
|
package/dist/schema.d.ts
CHANGED
|
@@ -356,6 +356,7 @@ export declare const recipeSchema: z.ZodObject<{
|
|
|
356
356
|
channel: z.ZodString;
|
|
357
357
|
account: z.ZodOptional<z.ZodString>;
|
|
358
358
|
agent: z.ZodOptional<z.ZodString>;
|
|
359
|
+
group_policy: z.ZodOptional<z.ZodEnum<["open", "allowlist", "disabled"]>>;
|
|
359
360
|
login: z.ZodOptional<z.ZodBoolean>;
|
|
360
361
|
login_mode: z.ZodOptional<z.ZodEnum<["interactive"]>>;
|
|
361
362
|
login_account: z.ZodOptional<z.ZodString>;
|
|
@@ -376,6 +377,7 @@ export declare const recipeSchema: z.ZodObject<{
|
|
|
376
377
|
token?: string | undefined;
|
|
377
378
|
account?: string | undefined;
|
|
378
379
|
agent?: string | undefined;
|
|
380
|
+
group_policy?: "open" | "allowlist" | "disabled" | undefined;
|
|
379
381
|
login?: boolean | undefined;
|
|
380
382
|
login_mode?: "interactive" | undefined;
|
|
381
383
|
login_account?: string | undefined;
|
|
@@ -395,6 +397,7 @@ export declare const recipeSchema: z.ZodObject<{
|
|
|
395
397
|
token?: string | undefined;
|
|
396
398
|
account?: string | undefined;
|
|
397
399
|
agent?: string | undefined;
|
|
400
|
+
group_policy?: "open" | "allowlist" | "disabled" | undefined;
|
|
398
401
|
login?: boolean | undefined;
|
|
399
402
|
login_mode?: "interactive" | undefined;
|
|
400
403
|
login_account?: string | undefined;
|
|
@@ -572,6 +575,7 @@ export declare const recipeSchema: z.ZodObject<{
|
|
|
572
575
|
token?: string | undefined;
|
|
573
576
|
account?: string | undefined;
|
|
574
577
|
agent?: string | undefined;
|
|
578
|
+
group_policy?: "open" | "allowlist" | "disabled" | undefined;
|
|
575
579
|
login?: boolean | undefined;
|
|
576
580
|
login_mode?: "interactive" | undefined;
|
|
577
581
|
login_account?: string | undefined;
|
|
@@ -687,6 +691,7 @@ export declare const recipeSchema: z.ZodObject<{
|
|
|
687
691
|
token?: string | undefined;
|
|
688
692
|
account?: string | undefined;
|
|
689
693
|
agent?: string | undefined;
|
|
694
|
+
group_policy?: "open" | "allowlist" | "disabled" | undefined;
|
|
690
695
|
login?: boolean | undefined;
|
|
691
696
|
login_mode?: "interactive" | undefined;
|
|
692
697
|
login_account?: string | undefined;
|
package/dist/schema.js
CHANGED
|
@@ -102,6 +102,7 @@ const channelSchema = z
|
|
|
102
102
|
channel: z.string().min(1),
|
|
103
103
|
account: z.string().min(1).optional(),
|
|
104
104
|
agent: z.string().min(1).optional(),
|
|
105
|
+
group_policy: z.enum(["open", "allowlist", "disabled"]).optional(),
|
|
105
106
|
login: z.boolean().optional(),
|
|
106
107
|
login_mode: z.enum(["interactive"]).optional(),
|
|
107
108
|
login_account: z.string().min(1).optional(),
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { tmpdir } from "node:os";
|
|
1
|
+
import { homedir, tmpdir } from "node:os";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import process from "node:process";
|
|
4
4
|
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
@@ -178,6 +178,14 @@ function parseVersionOutput(output: string): string {
|
|
|
178
178
|
return match?.[1] ?? output.trim();
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
+
function telegramGroupPolicyPath(account: string | undefined): string {
|
|
182
|
+
const trimmed = account?.trim();
|
|
183
|
+
if (!trimmed) {
|
|
184
|
+
return "channels.telegram.groupPolicy";
|
|
185
|
+
}
|
|
186
|
+
return `channels.telegram.accounts[${trimmed}].groupPolicy`;
|
|
187
|
+
}
|
|
188
|
+
|
|
181
189
|
type VersionMismatchChoice = "ignore" | "abort" | "force";
|
|
182
190
|
|
|
183
191
|
async function chooseVersionMismatchAction(
|
|
@@ -440,10 +448,14 @@ export class CommandOpenClawProvider implements OpenClawProvider {
|
|
|
440
448
|
async factoryReset(config: OpenClawSection, dryRun: boolean): Promise<void> {
|
|
441
449
|
const bin = config.bin ?? "openclaw";
|
|
442
450
|
const resetCmd = commandFor(config, "factory_reset", { bin, version: config.version });
|
|
443
|
-
if (
|
|
444
|
-
|
|
451
|
+
if (resetCmd.trim()) {
|
|
452
|
+
await runShell(resetCmd, dryRun);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
const openclawHome = path.join(homedir(), ".openclaw");
|
|
456
|
+
if (!dryRun) {
|
|
457
|
+
await rm(openclawHome, { recursive: true, force: true });
|
|
445
458
|
}
|
|
446
|
-
await runShell(resetCmd, dryRun);
|
|
447
459
|
}
|
|
448
460
|
|
|
449
461
|
async installPlugin(config: OpenClawSection, pluginSpec: string, dryRun: boolean): Promise<void> {
|
|
@@ -554,6 +566,13 @@ export class CommandOpenClawProvider implements OpenClawProvider {
|
|
|
554
566
|
|
|
555
567
|
const cmd = `${bin} channels add ${flags.join(" ")}`;
|
|
556
568
|
await runShell(cmd, dryRun);
|
|
569
|
+
|
|
570
|
+
if (channel.channel === "telegram" && channel.group_policy) {
|
|
571
|
+
const configPath = telegramGroupPolicyPath(channel.account);
|
|
572
|
+
const policyValue = JSON.stringify(channel.group_policy);
|
|
573
|
+
const setPolicyCmd = `${bin} config set ${shellQuote(configPath)} ${shellQuote(policyValue)} --strict-json`;
|
|
574
|
+
await runShell(setPolicyCmd, dryRun);
|
|
575
|
+
}
|
|
557
576
|
}
|
|
558
577
|
|
|
559
578
|
async bindChannelAgent(config: OpenClawSection, channel: ChannelDef, agent: string, dryRun: boolean): Promise<void> {
|
package/src/recipe.ts
CHANGED
|
@@ -252,6 +252,12 @@ function semanticValidate(recipe: Recipe): void {
|
|
|
252
252
|
);
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
+
if (channel.group_policy !== undefined && channel.channel !== "telegram") {
|
|
256
|
+
throw new ClawChefError(
|
|
257
|
+
`channels[] entry for ${channel.channel} does not support group_policy. Use channel: telegram.`,
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
|
|
255
261
|
if (channel.agent?.trim()) {
|
|
256
262
|
if (channel.channel !== "telegram") {
|
|
257
263
|
throw new ClawChefError(
|
package/src/schema.ts
CHANGED
|
@@ -112,6 +112,7 @@ const channelSchema = z
|
|
|
112
112
|
channel: z.string().min(1),
|
|
113
113
|
account: z.string().min(1).optional(),
|
|
114
114
|
agent: z.string().min(1).optional(),
|
|
115
|
+
group_policy: z.enum(["open", "allowlist", "disabled"]).optional(),
|
|
115
116
|
login: z.boolean().optional(),
|
|
116
117
|
login_mode: z.enum(["interactive"]).optional(),
|
|
117
118
|
login_account: z.string().min(1).optional(),
|