mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 15:10:52 +00:00
fix(docs): make slack manifest snippets parseable
This commit is contained in:
@@ -36,7 +36,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Google Meet: refresh realtime browser state during status and retry delayed speech after Meet finishes joining, so a just-opened in-call tab no longer leaves speech stuck behind stale `not-in-call` health.
|
||||
- Plugins/install: recover the install ledger from the managed npm root when `plugins/installs.json` is empty or partial, so reinstalling Discord and Codex no longer makes the other installed plugin disappear.
|
||||
- Google Meet: grant Meet media permissions through the Playwright browser context when CDP grants do not affect the attached Chrome page, and report in-call microphone/speaker permission problems instead of marking realtime speech ready.
|
||||
- Channel docs: keep JSON5 channel config examples parseable and schema-valid, fixing BlueBubbles and QQ Bot snippets that could not be copied into config as shown. Thanks @vincentkoc.
|
||||
- Channel docs: keep JSON5 channel config examples parseable and schema-valid, fixing BlueBubbles, QQ Bot, and Slack snippets that could not be copied into config or app manifests as shown. Thanks @vincentkoc.
|
||||
- Tlon: expose `groupInviteAllowlist` in the channel config schema and clarify that group invite auto-accept fails closed without an invite allowlist. Thanks @vincentkoc.
|
||||
- Google Chat: update the setup example to use the accepted `groups.<space>.enabled` key instead of the legacy `allow` alias, with a schema regression for the documented group shape. Thanks @vincentkoc.
|
||||
- Control UI/WebChat: collapse duplicate in-flight internal text sends onto the active Gateway run so rapid repeat submits do not start fresh `agent:main:main` dispatches. Fixes #75737. Thanks @dsdsddd1 and @BunsDev.
|
||||
|
||||
@@ -283,121 +283,123 @@ The default manifest enables the Slack App Home **Home** tab and subscribes to `
|
||||
<Tab title="Socket Mode (default)">
|
||||
|
||||
```json
|
||||
"slash_commands": [
|
||||
{
|
||||
"command": "/new",
|
||||
"description": "Start a new session",
|
||||
"usage_hint": "[model]"
|
||||
},
|
||||
{
|
||||
"command": "/reset",
|
||||
"description": "Reset the current session"
|
||||
},
|
||||
{
|
||||
"command": "/compact",
|
||||
"description": "Compact the session context",
|
||||
"usage_hint": "[instructions]"
|
||||
},
|
||||
{
|
||||
"command": "/stop",
|
||||
"description": "Stop the current run"
|
||||
},
|
||||
{
|
||||
"command": "/session",
|
||||
"description": "Manage thread-binding expiry",
|
||||
"usage_hint": "idle <duration|off> or max-age <duration|off>"
|
||||
},
|
||||
{
|
||||
"command": "/think",
|
||||
"description": "Set the thinking level",
|
||||
"usage_hint": "<level>"
|
||||
},
|
||||
{
|
||||
"command": "/verbose",
|
||||
"description": "Toggle verbose output",
|
||||
"usage_hint": "on|off|full"
|
||||
},
|
||||
{
|
||||
"command": "/fast",
|
||||
"description": "Show or set fast mode",
|
||||
"usage_hint": "[status|on|off]"
|
||||
},
|
||||
{
|
||||
"command": "/reasoning",
|
||||
"description": "Toggle reasoning visibility",
|
||||
"usage_hint": "[on|off|stream]"
|
||||
},
|
||||
{
|
||||
"command": "/elevated",
|
||||
"description": "Toggle elevated mode",
|
||||
"usage_hint": "[on|off|ask|full]"
|
||||
},
|
||||
{
|
||||
"command": "/exec",
|
||||
"description": "Show or set exec defaults",
|
||||
"usage_hint": "host=<auto|sandbox|gateway|node> security=<deny|allowlist|full> ask=<off|on-miss|always> node=<id>"
|
||||
},
|
||||
{
|
||||
"command": "/model",
|
||||
"description": "Show or set the model",
|
||||
"usage_hint": "[name|#|status]"
|
||||
},
|
||||
{
|
||||
"command": "/models",
|
||||
"description": "List providers/models",
|
||||
"usage_hint": "[provider] [page] [limit=<n>|size=<n>|all]"
|
||||
},
|
||||
{
|
||||
"command": "/help",
|
||||
"description": "Show the short help summary"
|
||||
},
|
||||
{
|
||||
"command": "/commands",
|
||||
"description": "Show the generated command catalog"
|
||||
},
|
||||
{
|
||||
"command": "/tools",
|
||||
"description": "Show what the current agent can use right now",
|
||||
"usage_hint": "[compact|verbose]"
|
||||
},
|
||||
{
|
||||
"command": "/agentstatus",
|
||||
"description": "Show runtime status, including provider usage/quota when available"
|
||||
},
|
||||
{
|
||||
"command": "/tasks",
|
||||
"description": "List active/recent background tasks for the current session"
|
||||
},
|
||||
{
|
||||
"command": "/context",
|
||||
"description": "Explain how context is assembled",
|
||||
"usage_hint": "[list|detail|json]"
|
||||
},
|
||||
{
|
||||
"command": "/whoami",
|
||||
"description": "Show your sender identity"
|
||||
},
|
||||
{
|
||||
"command": "/skill",
|
||||
"description": "Run a skill by name",
|
||||
"usage_hint": "<name> [input]"
|
||||
},
|
||||
{
|
||||
"command": "/btw",
|
||||
"description": "Ask a side question without changing session context",
|
||||
"usage_hint": "<question>"
|
||||
},
|
||||
{
|
||||
"command": "/side",
|
||||
"description": "Ask a side question without changing session context",
|
||||
"usage_hint": "<question>"
|
||||
},
|
||||
{
|
||||
"command": "/usage",
|
||||
"description": "Control the usage footer or show cost summary",
|
||||
"usage_hint": "off|tokens|full|cost"
|
||||
}
|
||||
]
|
||||
{
|
||||
"slash_commands": [
|
||||
{
|
||||
"command": "/new",
|
||||
"description": "Start a new session",
|
||||
"usage_hint": "[model]"
|
||||
},
|
||||
{
|
||||
"command": "/reset",
|
||||
"description": "Reset the current session"
|
||||
},
|
||||
{
|
||||
"command": "/compact",
|
||||
"description": "Compact the session context",
|
||||
"usage_hint": "[instructions]"
|
||||
},
|
||||
{
|
||||
"command": "/stop",
|
||||
"description": "Stop the current run"
|
||||
},
|
||||
{
|
||||
"command": "/session",
|
||||
"description": "Manage thread-binding expiry",
|
||||
"usage_hint": "idle <duration|off> or max-age <duration|off>"
|
||||
},
|
||||
{
|
||||
"command": "/think",
|
||||
"description": "Set the thinking level",
|
||||
"usage_hint": "<level>"
|
||||
},
|
||||
{
|
||||
"command": "/verbose",
|
||||
"description": "Toggle verbose output",
|
||||
"usage_hint": "on|off|full"
|
||||
},
|
||||
{
|
||||
"command": "/fast",
|
||||
"description": "Show or set fast mode",
|
||||
"usage_hint": "[status|on|off]"
|
||||
},
|
||||
{
|
||||
"command": "/reasoning",
|
||||
"description": "Toggle reasoning visibility",
|
||||
"usage_hint": "[on|off|stream]"
|
||||
},
|
||||
{
|
||||
"command": "/elevated",
|
||||
"description": "Toggle elevated mode",
|
||||
"usage_hint": "[on|off|ask|full]"
|
||||
},
|
||||
{
|
||||
"command": "/exec",
|
||||
"description": "Show or set exec defaults",
|
||||
"usage_hint": "host=<auto|sandbox|gateway|node> security=<deny|allowlist|full> ask=<off|on-miss|always> node=<id>"
|
||||
},
|
||||
{
|
||||
"command": "/model",
|
||||
"description": "Show or set the model",
|
||||
"usage_hint": "[name|#|status]"
|
||||
},
|
||||
{
|
||||
"command": "/models",
|
||||
"description": "List providers/models",
|
||||
"usage_hint": "[provider] [page] [limit=<n>|size=<n>|all]"
|
||||
},
|
||||
{
|
||||
"command": "/help",
|
||||
"description": "Show the short help summary"
|
||||
},
|
||||
{
|
||||
"command": "/commands",
|
||||
"description": "Show the generated command catalog"
|
||||
},
|
||||
{
|
||||
"command": "/tools",
|
||||
"description": "Show what the current agent can use right now",
|
||||
"usage_hint": "[compact|verbose]"
|
||||
},
|
||||
{
|
||||
"command": "/agentstatus",
|
||||
"description": "Show runtime status, including provider usage/quota when available"
|
||||
},
|
||||
{
|
||||
"command": "/tasks",
|
||||
"description": "List active/recent background tasks for the current session"
|
||||
},
|
||||
{
|
||||
"command": "/context",
|
||||
"description": "Explain how context is assembled",
|
||||
"usage_hint": "[list|detail|json]"
|
||||
},
|
||||
{
|
||||
"command": "/whoami",
|
||||
"description": "Show your sender identity"
|
||||
},
|
||||
{
|
||||
"command": "/skill",
|
||||
"description": "Run a skill by name",
|
||||
"usage_hint": "<name> [input]"
|
||||
},
|
||||
{
|
||||
"command": "/btw",
|
||||
"description": "Ask a side question without changing session context",
|
||||
"usage_hint": "<question>"
|
||||
},
|
||||
{
|
||||
"command": "/side",
|
||||
"description": "Ask a side question without changing session context",
|
||||
"usage_hint": "<question>"
|
||||
},
|
||||
{
|
||||
"command": "/usage",
|
||||
"description": "Control the usage footer or show cost summary",
|
||||
"usage_hint": "off|tokens|full|cost"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
@@ -405,20 +407,22 @@ The default manifest enables the Slack App Home **Home** tab and subscribes to `
|
||||
Use the same `slash_commands` list as Socket Mode above, and add `"url": "https://gateway-host.example.com/slack/events"` to every entry. Example:
|
||||
|
||||
```json
|
||||
"slash_commands": [
|
||||
{
|
||||
"command": "/new",
|
||||
"description": "Start a new session",
|
||||
"usage_hint": "[model]",
|
||||
"url": "https://gateway-host.example.com/slack/events"
|
||||
},
|
||||
{
|
||||
"command": "/help",
|
||||
"description": "Show the short help summary",
|
||||
"url": "https://gateway-host.example.com/slack/events"
|
||||
}
|
||||
// ...repeat for every command with the same `url` value
|
||||
]
|
||||
{
|
||||
"slash_commands": [
|
||||
{
|
||||
"command": "/new",
|
||||
"description": "Start a new session",
|
||||
"usage_hint": "[model]",
|
||||
"url": "https://gateway-host.example.com/slack/events"
|
||||
},
|
||||
{
|
||||
"command": "/help",
|
||||
"description": "Show the short help summary",
|
||||
"url": "https://gateway-host.example.com/slack/events"
|
||||
}
|
||||
// ...repeat for every command with the same `url` value
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
|
||||
@@ -11,6 +11,27 @@ function lineNumberAt(source: string, index: number): number {
|
||||
}
|
||||
|
||||
describe("channel docs config examples", () => {
|
||||
it("keeps channel docs JSON fences parseable", () => {
|
||||
const failures: string[] = [];
|
||||
for (const fileName of fs
|
||||
.readdirSync(CHANNEL_DOCS_DIR)
|
||||
.filter((entry) => entry.endsWith(".md"))) {
|
||||
const docPath = path.join(CHANNEL_DOCS_DIR, fileName);
|
||||
const markdown = fs.readFileSync(docPath, "utf8");
|
||||
const blocks = markdown.matchAll(/```(?:json5|json)\n([\s\S]*?)```/g);
|
||||
for (const match of blocks) {
|
||||
const code = match[1] ?? "";
|
||||
const location = `${fileName}:${lineNumberAt(markdown, match.index ?? 0)}`;
|
||||
try {
|
||||
JSON5.parse(code);
|
||||
} catch (error) {
|
||||
failures.push(`${location} JSON5 parse failed: ${String(error)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect(failures).toEqual([]);
|
||||
});
|
||||
|
||||
it("keeps OpenClaw channel config snippets parseable and schema-valid", () => {
|
||||
const failures: string[] = [];
|
||||
for (const fileName of fs
|
||||
|
||||
Reference in New Issue
Block a user