@dailyflows/openclaw-dailyflows 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dailyflows Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,182 @@
1
+ # Dailyflows Plugin for OpenClaw
2
+
3
+ This directory is designed to be maintained as a standalone open-source repository (for example `dailyflows-plugin`). You can maintain only the plugin without maintaining a full OpenClaw fork.
4
+
5
+ For Chinese documentation, see [README.zh-CN.md](./README.zh-CN.md).
6
+
7
+ ## 1) Install OpenClaw (official)
8
+
9
+ ```bash
10
+ curl -fsSL https://openclaw.ai/install.sh | bash
11
+ ```
12
+
13
+ Or:
14
+
15
+ ```bash
16
+ npm install -g openclaw@latest
17
+ ```
18
+
19
+ Initial setup:
20
+
21
+ ```bash
22
+ openclaw onboard --install-daemon
23
+ openclaw gateway status
24
+ ```
25
+
26
+ If you see `Runtime: running` + `RPC probe: ok`, your Gateway is healthy.
27
+
28
+ ## 2) Install the Dailyflows plugin
29
+
30
+ ### Option A: Install from npm (recommended)
31
+
32
+ ```bash
33
+ openclaw plugins install @dailyflows/dailyflows
34
+ openclaw gateway restart
35
+ ```
36
+
37
+ ### Option B: Install from local source (development)
38
+
39
+ ```bash
40
+ openclaw plugins install -l ./dailyflows-plugin
41
+ openclaw gateway restart
42
+ ```
43
+
44
+ > You usually install the plugin only once. Reinstall only when you switch machines/profiles or reset config.
45
+
46
+ ## 3) Minimal config
47
+
48
+ ```json5
49
+ {
50
+ channels: {
51
+ dailyflows: {
52
+ webhookPath: "/dailyflows/webhook",
53
+ accounts: {
54
+ default: {
55
+ enabled: true,
56
+ outboundUrl: "https://dailyflows.example.com/openclaw/outbound",
57
+ outboundToken: "REPLACE_ME"
58
+ }
59
+ }
60
+ }
61
+ },
62
+ plugins: {
63
+ entries: {
64
+ dailyflows: { enabled: true }
65
+ }
66
+ }
67
+ }
68
+ ```
69
+
70
+ Use environment variables for webhook secrets:
71
+
72
+ ```bash
73
+ export DAILYFLOWS_WEBHOOK_SECRET="replace-with-random"
74
+ # Optional: per-account override
75
+ export DAILYFLOWS_WEBHOOK_SECRET_DEFAULT="replace-with-random"
76
+ ```
77
+
78
+ ## 4) Pair Dailyflows App with OpenClaw
79
+
80
+ The Dailyflows cloud must call back into your Gateway, so you need a public HTTPS URL (Tailscale Funnel is a common choice).
81
+
82
+ Example:
83
+
84
+ ```bash
85
+ openclaw config set gateway.mode local
86
+ openclaw config set gateway.bind loopback
87
+ openclaw config set gateway.auth.mode password
88
+ openclaw config set gateway.auth.password "<strong-password>"
89
+ openclaw config set gateway.tailscale.mode funnel
90
+ openclaw gateway restart
91
+ ```
92
+
93
+ Pairing flow:
94
+
95
+ 1. Open `https://<gateway-host>/dailyflows/pair`
96
+ 2. In Dailyflows App, go to `Voice Assistant -> OpenClaw`
97
+ 3. Scan the QR code
98
+
99
+ You can also print the QR in CLI:
100
+
101
+ ```bash
102
+ openclaw dailyflows pair --gateway-url https://<your-funnel-url>
103
+ ```
104
+
105
+ ## 5) Send messages
106
+
107
+ After pairing, send text or attachments to OpenClaw in the Dailyflows chat.
108
+
109
+ Message path:
110
+
111
+ 1. Dailyflows -> `POST /dailyflows/webhook`
112
+ 2. OpenClaw agent processes the message
113
+ 3. Gateway -> `outboundUrl` sends the reply back to Dailyflows
114
+
115
+ Manual outbound check from CLI:
116
+
117
+ ```bash
118
+ openclaw message send --channel dailyflows --target <conversationId> --message "hello from openclaw"
119
+ ```
120
+
121
+ ## 6) Troubleshooting commands
122
+
123
+ ```bash
124
+ openclaw gateway status
125
+ openclaw health
126
+ openclaw status --deep
127
+ openclaw plugins list
128
+ ```
129
+
130
+ Focus checks:
131
+
132
+ - Model authentication is completed (`onboard`)
133
+ - Gateway is publicly reachable via HTTPS
134
+ - `plugins.entries.dailyflows.enabled` is `true`
135
+ - `channels.dailyflows.accounts.default` has valid `outboundUrl/outboundToken/webhookSecret`
136
+
137
+ ---
138
+
139
+ ## 7) Maintainer workflow (standalone repo)
140
+
141
+ Recommended structure (already included):
142
+
143
+ - `src/` plugin source
144
+ - `openclaw.plugin.json` plugin manifest
145
+ - `package.json` npm + OpenClaw plugin metadata
146
+ - `.github/workflows/ci.yml` CI workflow
147
+ - `scripts/release.sh` one-command publish script
148
+
149
+ Install and verify:
150
+
151
+ ```bash
152
+ pnpm install
153
+ pnpm check
154
+ ```
155
+
156
+ Publish to npm:
157
+
158
+ ```bash
159
+ npm login
160
+ pnpm release
161
+ ```
162
+
163
+ If CI already validated and you want to skip local tests:
164
+
165
+ ```bash
166
+ SKIP_TESTS=1 pnpm release
167
+ ```
168
+
169
+ ## 8) One-click export as standalone Git repo
170
+
171
+ This directory includes two helper scripts:
172
+
173
+ ```bash
174
+ # Local-only init (git init + first commit)
175
+ ./scripts/init-standalone-local.sh
176
+
177
+ # Init and attach GitHub remote (optional --push)
178
+ ./scripts/init-standalone-with-remote.sh git@github.com:<you>/<repo>.git main
179
+ ./scripts/init-standalone-with-remote.sh git@github.com:<you>/<repo>.git main --push
180
+ ```
181
+
182
+ If you already ran `git init` elsewhere, the second script reuses the existing repository and only updates `origin`.
@@ -0,0 +1,182 @@
1
+ # Dailyflows Plugin for OpenClaw
2
+
3
+ 英文版文档请见 [README.md](./README.md)。
4
+
5
+ 这个目录可以直接独立成一个开源仓库(例如 `dailyflows-plugin`),只维护插件,不需要维护整份 OpenClaw fork。
6
+
7
+ ## 1) 用户侧:安装 OpenClaw(官方)
8
+
9
+ ```bash
10
+ curl -fsSL https://openclaw.ai/install.sh | bash
11
+ ```
12
+
13
+ 或:
14
+
15
+ ```bash
16
+ npm install -g openclaw@latest
17
+ ```
18
+
19
+ 首次初始化:
20
+
21
+ ```bash
22
+ openclaw onboard --install-daemon
23
+ openclaw gateway status
24
+ ```
25
+
26
+ 看到 `Runtime: running` + `RPC probe: ok`,说明 Gateway 正常。
27
+
28
+ ## 2) 用户侧:安装 Dailyflows 插件
29
+
30
+ ### 方式 A:npm 安装(推荐)
31
+
32
+ ```bash
33
+ openclaw plugins install @dailyflows/dailyflows
34
+ openclaw gateway restart
35
+ ```
36
+
37
+ ### 方式 B:本地源码安装(开发调试)
38
+
39
+ ```bash
40
+ openclaw plugins install -l ./dailyflows-plugin
41
+ openclaw gateway restart
42
+ ```
43
+
44
+ > 插件一般只安装一次。除非换机器、清理配置、切 profile,平时不需要重复安装。
45
+
46
+ ## 3) 用户侧:最小配置
47
+
48
+ ```json5
49
+ {
50
+ channels: {
51
+ dailyflows: {
52
+ webhookPath: "/dailyflows/webhook",
53
+ accounts: {
54
+ default: {
55
+ enabled: true,
56
+ outboundUrl: "https://dailyflows.example.com/openclaw/outbound",
57
+ outboundToken: "REPLACE_ME"
58
+ }
59
+ }
60
+ }
61
+ },
62
+ plugins: {
63
+ entries: {
64
+ dailyflows: { enabled: true }
65
+ }
66
+ }
67
+ }
68
+ ```
69
+
70
+ 建议用环境变量配置 webhook secret:
71
+
72
+ ```bash
73
+ export DAILYFLOWS_WEBHOOK_SECRET="replace-with-random"
74
+ # 可选,按 accountId 覆盖
75
+ export DAILYFLOWS_WEBHOOK_SECRET_DEFAULT="replace-with-random"
76
+ ```
77
+
78
+ ## 4) 用户侧:扫码绑定(Dailyflows App -> OpenClaw)
79
+
80
+ Dailyflows 云端需要回调你的 Gateway,所以要有公网 HTTPS 地址(常见方案:Tailscale Funnel)。
81
+
82
+ 示例:
83
+
84
+ ```bash
85
+ openclaw config set gateway.mode local
86
+ openclaw config set gateway.bind loopback
87
+ openclaw config set gateway.auth.mode password
88
+ openclaw config set gateway.auth.password "<strong-password>"
89
+ openclaw config set gateway.tailscale.mode funnel
90
+ openclaw gateway restart
91
+ ```
92
+
93
+ 绑定流程:
94
+
95
+ 1. 打开 `https://<gateway-host>/dailyflows/pair`
96
+ 2. Dailyflows App 进入 `Voice Assistant -> OpenClaw`
97
+ 3. 扫码完成绑定
98
+
99
+ 也可以在终端生成二维码:
100
+
101
+ ```bash
102
+ openclaw dailyflows pair --gateway-url https://<your-funnel-url>
103
+ ```
104
+
105
+ ## 5) 用户侧:发送消息
106
+
107
+ 绑定后,直接在 Dailyflows 聊天中给 OpenClaw 发文字/附件即可。
108
+
109
+ 链路:
110
+
111
+ 1. Dailyflows -> `POST /dailyflows/webhook`
112
+ 2. OpenClaw Agent 处理
113
+ 3. Gateway -> `outboundUrl` 回发 Dailyflows
114
+
115
+ 手动验证(从 OpenClaw 主动发消息):
116
+
117
+ ```bash
118
+ openclaw message send --channel dailyflows --target <conversationId> --message "hello from openclaw"
119
+ ```
120
+
121
+ ## 6) 排查命令
122
+
123
+ ```bash
124
+ openclaw gateway status
125
+ openclaw health
126
+ openclaw status --deep
127
+ openclaw plugins list
128
+ ```
129
+
130
+ 重点检查:
131
+
132
+ - 模型认证是否完成(onboard)
133
+ - Gateway 是否可公网 HTTPS 访问
134
+ - `plugins.entries.dailyflows.enabled` 是否为 `true`
135
+ - `channels.dailyflows.accounts.default` 的 `outboundUrl/outboundToken/webhookSecret` 是否有效
136
+
137
+ ---
138
+
139
+ ## 7) 维护者侧:把本目录作为独立仓库
140
+
141
+ 建议结构(本目录已包含):
142
+
143
+ - `src/` 插件源码
144
+ - `openclaw.plugin.json` 插件声明
145
+ - `package.json` 发布配置(npm + OpenClaw 元信息)
146
+ - `.github/workflows/ci.yml` 持续集成
147
+ - `scripts/release.sh` 一键发布脚本
148
+
149
+ 安装依赖与测试:
150
+
151
+ ```bash
152
+ pnpm install
153
+ pnpm check
154
+ ```
155
+
156
+ 发布到 npm:
157
+
158
+ ```bash
159
+ npm login
160
+ pnpm release
161
+ ```
162
+
163
+ 如果你已经在 CI 里跑过测试,想跳过本地测试:
164
+
165
+ ```bash
166
+ SKIP_TESTS=1 pnpm release
167
+ ```
168
+
169
+ ## 8) 一键导出为独立 Git 仓库
170
+
171
+ 本目录已内置两个脚本:
172
+
173
+ ```bash
174
+ # 仅本地初始化(git init + 首次 commit)
175
+ ./scripts/init-standalone-local.sh
176
+
177
+ # 初始化并绑定 GitHub 远端(可选 --push 直接推送)
178
+ ./scripts/init-standalone-with-remote.sh git@github.com:<you>/<repo>.git main
179
+ ./scripts/init-standalone-with-remote.sh git@github.com:<you>/<repo>.git main --push
180
+ ```
181
+
182
+ 如果你已经在别处 `git init` 过,第二个脚本会复用已有仓库,只更新 `origin`。
package/index.ts ADDED
@@ -0,0 +1,33 @@
1
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
2
+ import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
3
+ import { dailyflowsPlugin } from "./src/channel.js";
4
+ import { registerDailyflowsCli } from "./src/cli.js";
5
+ import { createDailyflowsPairingRoute } from "./src/pairing-http.js";
6
+ import { setDailyflowsRuntime } from "./src/runtime.js";
7
+ import { createDailyflowsUnpairRoute } from "./src/unpair-http.js";
8
+ import { createDailyflowsWebhookHandler } from "./src/webhook.js";
9
+
10
+ const plugin = {
11
+ id: "dailyflows",
12
+ name: "Dailyflows",
13
+ description: "Dailyflows webhook channel plugin",
14
+ configSchema: emptyPluginConfigSchema(),
15
+ register(api: OpenClawPluginApi) {
16
+ setDailyflowsRuntime(api.runtime);
17
+ api.registerChannel({ plugin: dailyflowsPlugin });
18
+ api.registerHttpHandler(createDailyflowsWebhookHandler(api));
19
+ api.registerHttpRoute({
20
+ path: "/dailyflows/pair",
21
+ handler: createDailyflowsPairingRoute(api),
22
+ });
23
+ api.registerHttpRoute({
24
+ path: "/dailyflows/unpair",
25
+ handler: createDailyflowsUnpairRoute(api),
26
+ });
27
+ api.registerCli(({ program, config }) => registerDailyflowsCli({ program, config }), {
28
+ commands: ["dailyflows"],
29
+ });
30
+ },
31
+ };
32
+
33
+ export default plugin;
@@ -0,0 +1,9 @@
1
+ {
2
+ "id": "dailyflows",
3
+ "channels": ["dailyflows"],
4
+ "configSchema": {
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "properties": {}
8
+ }
9
+ }
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@dailyflows/openclaw-dailyflows",
3
+ "version": "1.0.0",
4
+ "description": "Dailyflows webhook channel plugin for OpenClaw",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "index.ts",
8
+ "packageManager": "pnpm@8.14.3",
9
+ "keywords": [
10
+ "openclaw",
11
+ "dailyflows",
12
+ "plugin",
13
+ "channel",
14
+ "webhook"
15
+ ],
16
+ "engines": {
17
+ "node": ">=22"
18
+ },
19
+ "files": [
20
+ "index.ts",
21
+ "openclaw.plugin.json",
22
+ "src/**",
23
+ "README.md",
24
+ "README.zh-CN.md",
25
+ "LICENSE"
26
+ ],
27
+ "publishConfig": {
28
+ "access": "public",
29
+ "registry": "https://registry.npmjs.org"
30
+ },
31
+ "dependencies": {
32
+ "qrcode-terminal": "^0.12.0"
33
+ },
34
+ "peerDependencies": {
35
+ "openclaw": ">=2026.2.1"
36
+ },
37
+ "devDependencies": {
38
+ "openclaw": "^2026.2.1",
39
+ "vitest": "^4.0.18"
40
+ },
41
+ "scripts": {
42
+ "test": "vitest run",
43
+ "test:watch": "vitest",
44
+ "pack:check": "npm pack --dry-run",
45
+ "check": "pnpm test && pnpm pack:check",
46
+ "release": "bash ./scripts/release.sh"
47
+ },
48
+ "openclaw": {
49
+ "extensions": [
50
+ "./index.ts"
51
+ ],
52
+ "channel": {
53
+ "id": "dailyflows",
54
+ "label": "Dailyflows",
55
+ "selectionLabel": "Dailyflows (Webhook)",
56
+ "docsPath": "/channels/dailyflows",
57
+ "docsLabel": "dailyflows",
58
+ "blurb": "Dailyflows webhook channel.",
59
+ "order": 90,
60
+ "aliases": [
61
+ "dailyflow"
62
+ ]
63
+ },
64
+ "install": {
65
+ "npmSpec": "@dailyflows/openclaw-dailyflows",
66
+ "defaultChoice": "npm"
67
+ }
68
+ }
69
+ }
package/src/channel.ts ADDED
@@ -0,0 +1,86 @@
1
+ import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk";
2
+ import type {
3
+ DailyflowsChannelPlugin,
4
+ DailyflowsOutboundContext,
5
+ DailyflowsOutboundResult,
6
+ } from "./types.js";
7
+ import { listDailyflowsAccountIds, resolveDailyflowsAccount } from "./config.js";
8
+ import { sendDailyflowsMessage } from "./send.js";
9
+
10
+ const meta = {
11
+ id: "dailyflows",
12
+ label: "Dailyflows",
13
+ selectionLabel: "Dailyflows (Webhook)",
14
+ detailLabel: "Dailyflows",
15
+ docsPath: "/channels/dailyflows",
16
+ docsLabel: "dailyflows",
17
+ blurb: "Dailyflows webhook channel.",
18
+ systemImage: "message.fill",
19
+ };
20
+
21
+ export const dailyflowsPlugin: DailyflowsChannelPlugin = {
22
+ id: "dailyflows",
23
+ meta,
24
+ capabilities: {
25
+ chatTypes: ["direct", "group"],
26
+ reactions: false,
27
+ threads: false,
28
+ media: true,
29
+ nativeCommands: false,
30
+ blockStreaming: true,
31
+ },
32
+ reload: { configPrefixes: ["channels.dailyflows"] },
33
+ config: {
34
+ listAccountIds: (cfg) => listDailyflowsAccountIds(cfg),
35
+ resolveAccount: (cfg, accountId) => resolveDailyflowsAccount(cfg, accountId),
36
+ defaultAccountId: () => DEFAULT_ACCOUNT_ID,
37
+ isEnabled: (account) => account.enabled,
38
+ isConfigured: (account) => Boolean(account.webhookSecret || account.outboundUrl),
39
+ unconfiguredReason: () => "Set channels.dailyflows.accounts.<id>.outboundUrl or webhookSecret",
40
+ describeAccount: (account) => ({
41
+ accountId: account.accountId,
42
+ name: account.name,
43
+ enabled: account.enabled,
44
+ configured: Boolean(account.webhookSecret || account.outboundUrl),
45
+ meta: {
46
+ outboundUrl: account.outboundUrl ?? null,
47
+ },
48
+ }),
49
+ },
50
+ outbound: {
51
+ deliveryMode: "direct",
52
+ resolveTarget: ({ to }) => {
53
+ const trimmed = to?.trim();
54
+ if (!trimmed) {
55
+ return {
56
+ ok: false,
57
+ error: new Error("Dailyflows target required. Provide a conversationId or senderId."),
58
+ };
59
+ }
60
+ return { ok: true, to: trimmed };
61
+ },
62
+ sendText: async (params: DailyflowsOutboundContext): Promise<DailyflowsOutboundResult> => {
63
+ const { cfg, to, text, accountId } = params;
64
+ return sendDailyflowsMessage({
65
+ cfg,
66
+ payload: {
67
+ accountId: accountId ?? DEFAULT_ACCOUNT_ID,
68
+ conversationId: to,
69
+ text,
70
+ },
71
+ });
72
+ },
73
+ sendMedia: async (params: DailyflowsOutboundContext): Promise<DailyflowsOutboundResult> => {
74
+ const { cfg, to, text, mediaUrl, accountId } = params;
75
+ return sendDailyflowsMessage({
76
+ cfg,
77
+ payload: {
78
+ accountId: accountId ?? DEFAULT_ACCOUNT_ID,
79
+ conversationId: to,
80
+ text: text?.trim() ? text : undefined,
81
+ attachments: mediaUrl ? [{ type: "file", url: mediaUrl }] : undefined,
82
+ },
83
+ });
84
+ },
85
+ },
86
+ };
package/src/cli.ts ADDED
@@ -0,0 +1,82 @@
1
+ import type { Command } from "commander";
2
+ import qrcode from "qrcode-terminal";
3
+ import type { OpenClawConfig } from "openclaw/plugin-sdk";
4
+
5
+ import { normalizeGatewayUrl } from "./pairing.js";
6
+
7
+ const DEFAULT_GATEWAY_PORT = 18789;
8
+
9
+ function resolveLocalGatewayUrl(config: OpenClawConfig, override?: string) {
10
+ if (override?.trim()) {
11
+ return override.trim();
12
+ }
13
+ const port = typeof config.gateway?.port === "number" ? config.gateway.port : DEFAULT_GATEWAY_PORT;
14
+ return `http://127.0.0.1:${port}`;
15
+ }
16
+
17
+ export function registerDailyflowsCli(params: {
18
+ program: Command;
19
+ config: OpenClawConfig;
20
+ }) {
21
+ const { program, config } = params;
22
+
23
+ const root = program
24
+ .command("dailyflows")
25
+ .description("Dailyflows pairing helpers")
26
+ .addHelpText("after", () => "\nDocs: https://docs.openclaw.ai/channels/dailyflows\n");
27
+
28
+ root
29
+ .command("pair")
30
+ .description("Generate a Dailyflows pairing QR from the running gateway")
31
+ .requiredOption("--gateway-url <url>", "Public HTTPS gateway URL (Tailscale Funnel)")
32
+ .option("--account <id>", "Dailyflows account id", "default")
33
+ .option("--gateway-http <url>", "Local gateway HTTP base URL")
34
+ .option("--json", "Print JSON only")
35
+ .action(async (options: { gatewayUrl: string; account: string; gatewayHttp?: string; json?: boolean }) => {
36
+ const publicUrl = normalizeGatewayUrl(options.gatewayUrl);
37
+ if (!publicUrl) {
38
+ throw new Error("--gateway-url must be a public https:// URL (Tailscale Funnel)");
39
+ }
40
+
41
+ const localGateway = resolveLocalGatewayUrl(config, options.gatewayHttp);
42
+ const pairingUrl = new URL("/dailyflows/pair", localGateway);
43
+ pairingUrl.searchParams.set("gatewayUrl", publicUrl);
44
+ pairingUrl.searchParams.set("accountId", options.account);
45
+ pairingUrl.searchParams.set("format", "json");
46
+
47
+ const res = await fetch(pairingUrl.toString());
48
+ if (!res.ok) {
49
+ const text = await res.text();
50
+ throw new Error(`Gateway pairing endpoint failed: ${res.status} ${res.statusText} ${text}`);
51
+ }
52
+ const payload = (await res.json()) as {
53
+ ok?: boolean;
54
+ error?: string;
55
+ gatewayUrl?: string;
56
+ accountId?: string;
57
+ pairCode?: string;
58
+ payload?: string;
59
+ expiresAt?: number;
60
+ };
61
+
62
+ if (!payload.ok || !payload.payload) {
63
+ throw new Error(payload.error || "Failed to generate pairing payload");
64
+ }
65
+
66
+ if (options.json) {
67
+ // eslint-disable-next-line no-console
68
+ console.log(JSON.stringify(payload, null, 2));
69
+ return;
70
+ }
71
+
72
+ qrcode.generate(payload.payload, { small: true });
73
+ // eslint-disable-next-line no-console
74
+ console.log("\nDailyflows pairing payload:");
75
+ // eslint-disable-next-line no-console
76
+ console.log(payload.payload);
77
+ // eslint-disable-next-line no-console
78
+ console.log(`\nGateway URL: ${payload.gatewayUrl}`);
79
+ // eslint-disable-next-line no-console
80
+ console.log(`Pair code: ${payload.pairCode}`);
81
+ });
82
+ }