@switchbot/openapi-cli 1.1.0 → 1.3.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.
Files changed (105) hide show
  1. package/README.md +174 -18
  2. package/dist/api/client.d.ts +7 -1
  3. package/dist/api/client.js +44 -8
  4. package/dist/api/client.js.map +1 -1
  5. package/dist/commands/batch.d.ts +2 -0
  6. package/dist/commands/batch.js +252 -0
  7. package/dist/commands/batch.js.map +1 -0
  8. package/dist/commands/cache.d.ts +2 -0
  9. package/dist/commands/cache.js +108 -0
  10. package/dist/commands/cache.js.map +1 -0
  11. package/dist/commands/capabilities.d.ts +2 -0
  12. package/dist/commands/capabilities.js +91 -0
  13. package/dist/commands/capabilities.js.map +1 -0
  14. package/dist/commands/catalog.d.ts +2 -0
  15. package/dist/commands/catalog.js +291 -0
  16. package/dist/commands/catalog.js.map +1 -0
  17. package/dist/commands/config.js +123 -10
  18. package/dist/commands/config.js.map +1 -1
  19. package/dist/commands/device-meta.d.ts +2 -0
  20. package/dist/commands/device-meta.js +142 -0
  21. package/dist/commands/device-meta.js.map +1 -0
  22. package/dist/commands/devices.js +272 -152
  23. package/dist/commands/devices.js.map +1 -1
  24. package/dist/commands/doctor.d.ts +2 -0
  25. package/dist/commands/doctor.js +147 -0
  26. package/dist/commands/doctor.js.map +1 -0
  27. package/dist/commands/events.d.ts +15 -0
  28. package/dist/commands/events.js +188 -0
  29. package/dist/commands/events.js.map +1 -0
  30. package/dist/commands/expand.d.ts +2 -0
  31. package/dist/commands/expand.js +192 -0
  32. package/dist/commands/expand.js.map +1 -0
  33. package/dist/commands/explain.d.ts +2 -0
  34. package/dist/commands/explain.js +137 -0
  35. package/dist/commands/explain.js.map +1 -0
  36. package/dist/commands/history.d.ts +2 -0
  37. package/dist/commands/history.js +104 -0
  38. package/dist/commands/history.js.map +1 -0
  39. package/dist/commands/mcp.d.ts +4 -0
  40. package/dist/commands/mcp.js +386 -0
  41. package/dist/commands/mcp.js.map +1 -0
  42. package/dist/commands/plan.d.ts +38 -0
  43. package/dist/commands/plan.js +356 -0
  44. package/dist/commands/plan.js.map +1 -0
  45. package/dist/commands/quota.d.ts +2 -0
  46. package/dist/commands/quota.js +77 -0
  47. package/dist/commands/quota.js.map +1 -0
  48. package/dist/commands/scenes.js +19 -13
  49. package/dist/commands/scenes.js.map +1 -1
  50. package/dist/commands/schema.d.ts +2 -0
  51. package/dist/commands/schema.js +77 -0
  52. package/dist/commands/schema.js.map +1 -0
  53. package/dist/commands/watch.d.ts +2 -0
  54. package/dist/commands/watch.js +161 -0
  55. package/dist/commands/watch.js.map +1 -0
  56. package/dist/commands/webhook.js +37 -22
  57. package/dist/commands/webhook.js.map +1 -1
  58. package/dist/config.d.ts +11 -0
  59. package/dist/config.js +32 -6
  60. package/dist/config.js.map +1 -1
  61. package/dist/devices/cache.d.ts +50 -0
  62. package/dist/devices/cache.js +152 -1
  63. package/dist/devices/cache.js.map +1 -1
  64. package/dist/devices/catalog.d.ts +49 -0
  65. package/dist/devices/catalog.js +362 -92
  66. package/dist/devices/catalog.js.map +1 -1
  67. package/dist/devices/device-meta.d.ts +15 -0
  68. package/dist/devices/device-meta.js +52 -0
  69. package/dist/devices/device-meta.js.map +1 -0
  70. package/dist/index.js +31 -1
  71. package/dist/index.js.map +1 -1
  72. package/dist/lib/devices.d.ts +144 -0
  73. package/dist/lib/devices.js +329 -0
  74. package/dist/lib/devices.js.map +1 -0
  75. package/dist/lib/scenes.d.ts +7 -0
  76. package/dist/lib/scenes.js +11 -0
  77. package/dist/lib/scenes.js.map +1 -0
  78. package/dist/utils/audit.d.ts +13 -0
  79. package/dist/utils/audit.js +43 -0
  80. package/dist/utils/audit.js.map +1 -0
  81. package/dist/utils/filter.d.ts +45 -0
  82. package/dist/utils/filter.js +96 -0
  83. package/dist/utils/filter.js.map +1 -0
  84. package/dist/utils/flags.d.ts +42 -0
  85. package/dist/utils/flags.js +108 -0
  86. package/dist/utils/flags.js.map +1 -1
  87. package/dist/utils/format.d.ts +9 -0
  88. package/dist/utils/format.js +109 -0
  89. package/dist/utils/format.js.map +1 -0
  90. package/dist/utils/name-resolver.d.ts +17 -0
  91. package/dist/utils/name-resolver.js +78 -0
  92. package/dist/utils/name-resolver.js.map +1 -0
  93. package/dist/utils/output.d.ts +18 -0
  94. package/dist/utils/output.js +66 -6
  95. package/dist/utils/output.js.map +1 -1
  96. package/dist/utils/quota.d.ts +48 -0
  97. package/dist/utils/quota.js +144 -0
  98. package/dist/utils/quota.js.map +1 -0
  99. package/dist/utils/retry.d.ts +23 -0
  100. package/dist/utils/retry.js +60 -0
  101. package/dist/utils/retry.js.map +1 -0
  102. package/dist/utils/string.d.ts +2 -0
  103. package/dist/utils/string.js +23 -0
  104. package/dist/utils/string.js.map +1 -0
  105. package/package.json +4 -1
@@ -0,0 +1,356 @@
1
+ import fs from 'node:fs';
2
+ import { printJson, isJsonMode, handleError } from '../utils/output.js';
3
+ import { executeCommand, isDestructiveCommand } from '../lib/devices.js';
4
+ import { executeScene } from '../lib/scenes.js';
5
+ import { getCachedDevice } from '../devices/cache.js';
6
+ import { resolveDeviceId } from '../utils/name-resolver.js';
7
+ const PLAN_JSON_SCHEMA = {
8
+ $schema: 'https://json-schema.org/draft/2020-12/schema',
9
+ $id: 'https://switchbot.dev/plan-1.0.json',
10
+ title: 'SwitchBot Plan',
11
+ description: 'Declarative batch of SwitchBot operations. Agent-authored; CLI validates and executes. No LLM inside the CLI — the schema is the contract.',
12
+ type: 'object',
13
+ required: ['version', 'steps'],
14
+ properties: {
15
+ version: { const: '1.0' },
16
+ description: { type: 'string' },
17
+ steps: {
18
+ type: 'array',
19
+ items: {
20
+ oneOf: [
21
+ {
22
+ type: 'object',
23
+ required: ['type', 'command'],
24
+ properties: {
25
+ type: { const: 'command' },
26
+ deviceId: { type: 'string', minLength: 1 },
27
+ deviceName: { type: 'string', minLength: 1 },
28
+ command: { type: 'string', minLength: 1 },
29
+ parameter: {},
30
+ commandType: { enum: ['command', 'customize'] },
31
+ note: { type: 'string' },
32
+ },
33
+ additionalProperties: false,
34
+ },
35
+ {
36
+ type: 'object',
37
+ required: ['type', 'sceneId'],
38
+ properties: {
39
+ type: { const: 'scene' },
40
+ sceneId: { type: 'string', minLength: 1 },
41
+ note: { type: 'string' },
42
+ },
43
+ additionalProperties: false,
44
+ },
45
+ {
46
+ type: 'object',
47
+ required: ['type', 'ms'],
48
+ properties: {
49
+ type: { const: 'wait' },
50
+ ms: { type: 'integer', minimum: 0, maximum: 600000 },
51
+ note: { type: 'string' },
52
+ },
53
+ additionalProperties: false,
54
+ },
55
+ ],
56
+ },
57
+ },
58
+ },
59
+ additionalProperties: false,
60
+ };
61
+ export function validatePlan(raw) {
62
+ const issues = [];
63
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
64
+ return { ok: false, issues: [{ path: '$', message: 'plan must be a JSON object' }] };
65
+ }
66
+ const p = raw;
67
+ if (p.version !== '1.0') {
68
+ issues.push({ path: 'version', message: 'must equal "1.0"' });
69
+ }
70
+ if (!Array.isArray(p.steps)) {
71
+ issues.push({ path: 'steps', message: 'must be an array' });
72
+ return { ok: false, issues };
73
+ }
74
+ p.steps.forEach((step, i) => {
75
+ const at = `steps[${i}]`;
76
+ if (!step || typeof step !== 'object') {
77
+ issues.push({ path: at, message: 'must be an object' });
78
+ return;
79
+ }
80
+ const s = step;
81
+ switch (s.type) {
82
+ case 'command':
83
+ if (s.deviceId !== undefined && (typeof s.deviceId !== 'string' || !s.deviceId)) {
84
+ issues.push({ path: `${at}.deviceId`, message: 'must be a non-empty string when provided' });
85
+ }
86
+ if (s.deviceName !== undefined && (typeof s.deviceName !== 'string' || !s.deviceName)) {
87
+ issues.push({ path: `${at}.deviceName`, message: 'must be a non-empty string when provided' });
88
+ }
89
+ if (!s.deviceId && !s.deviceName) {
90
+ issues.push({ path: `${at}`, message: 'must have either "deviceId" or "deviceName"' });
91
+ }
92
+ if (s.deviceId && s.deviceName) {
93
+ issues.push({ path: `${at}`, message: '"deviceId" and "deviceName" cannot both be set' });
94
+ }
95
+ if (typeof s.command !== 'string' || !s.command) {
96
+ issues.push({ path: `${at}.command`, message: 'must be a non-empty string' });
97
+ }
98
+ if (s.commandType !== undefined &&
99
+ s.commandType !== 'command' &&
100
+ s.commandType !== 'customize') {
101
+ issues.push({
102
+ path: `${at}.commandType`,
103
+ message: 'must be "command" or "customize"',
104
+ });
105
+ }
106
+ break;
107
+ case 'scene':
108
+ if (typeof s.sceneId !== 'string' || !s.sceneId) {
109
+ issues.push({ path: `${at}.sceneId`, message: 'must be a non-empty string' });
110
+ }
111
+ break;
112
+ case 'wait':
113
+ if (typeof s.ms !== 'number' || !Number.isInteger(s.ms) || s.ms < 0 || s.ms > 600_000) {
114
+ issues.push({
115
+ path: `${at}.ms`,
116
+ message: 'must be an integer in [0, 600000]',
117
+ });
118
+ }
119
+ break;
120
+ default:
121
+ issues.push({
122
+ path: `${at}.type`,
123
+ message: 'must be one of "command" | "scene" | "wait"',
124
+ });
125
+ }
126
+ });
127
+ if (issues.length > 0)
128
+ return { ok: false, issues };
129
+ return { ok: true, plan: raw };
130
+ }
131
+ async function readPlanSource(file) {
132
+ const text = file === undefined || file === '-'
133
+ ? await readStdin()
134
+ : fs.readFileSync(file, 'utf8');
135
+ if (!text.trim()) {
136
+ throw new Error(file === undefined || file === '-'
137
+ ? 'no plan received on stdin'
138
+ : `plan file is empty: ${file}`);
139
+ }
140
+ try {
141
+ return JSON.parse(text);
142
+ }
143
+ catch (err) {
144
+ throw new Error(`plan is not valid JSON: ${err.message}`);
145
+ }
146
+ }
147
+ function readStdin() {
148
+ return new Promise((resolve, reject) => {
149
+ let buf = '';
150
+ process.stdin.setEncoding('utf8');
151
+ process.stdin.on('data', (chunk) => (buf += chunk));
152
+ process.stdin.on('end', () => resolve(buf));
153
+ process.stdin.on('error', reject);
154
+ });
155
+ }
156
+ export function registerPlanCommand(program) {
157
+ const plan = program
158
+ .command('plan')
159
+ .description('Agent-authored batch plans: schema, validate, run')
160
+ .addHelpText('after', `
161
+ A "plan" is a JSON document describing a sequence of commands/scenes/waits.
162
+ The schema is fixed — agents emit plans, the CLI executes them. No LLM inside.
163
+
164
+ { "version": "1.0", "description": "...", "steps": [
165
+ { "type": "command", "deviceId": "...", "command": "turnOff" },
166
+ { "type": "wait", "ms": 500 },
167
+ { "type": "scene", "sceneId": "..." }
168
+ ]}
169
+
170
+ Workflow:
171
+ $ switchbot plan schema > plan.schema.json # export the contract
172
+ $ switchbot plan validate my-plan.json # check shape without running
173
+ $ switchbot --dry-run plan run my-plan.json # preview (mutations skipped)
174
+ $ switchbot plan run my-plan.json --yes # execute destructive steps
175
+ $ cat plan.json | switchbot plan run - # or stream via stdin
176
+ `);
177
+ plan
178
+ .command('schema')
179
+ .description('Print the JSON Schema for the plan format')
180
+ .action(() => {
181
+ printJson(PLAN_JSON_SCHEMA);
182
+ });
183
+ plan
184
+ .command('validate')
185
+ .description('Validate a plan file (or stdin) against the schema')
186
+ .argument('[file]', 'Path to plan.json, or "-" / omit to read stdin')
187
+ .action(async (file) => {
188
+ let raw;
189
+ try {
190
+ raw = await readPlanSource(file);
191
+ }
192
+ catch (err) {
193
+ handleError(err);
194
+ }
195
+ const result = validatePlan(raw);
196
+ if (!result.ok) {
197
+ if (isJsonMode()) {
198
+ printJson({ valid: false, issues: result.issues });
199
+ }
200
+ else {
201
+ console.error('✗ plan invalid:');
202
+ for (const i of result.issues) {
203
+ console.error(` ${i.path}: ${i.message}`);
204
+ }
205
+ }
206
+ process.exit(2);
207
+ }
208
+ if (isJsonMode()) {
209
+ printJson({ valid: true, steps: result.plan.steps.length });
210
+ }
211
+ else {
212
+ console.log(`✓ plan valid (${result.plan.steps.length} step${result.plan.steps.length === 1 ? '' : 's'})`);
213
+ }
214
+ });
215
+ plan
216
+ .command('run')
217
+ .description('Validate + execute a plan. Respects --dry-run; destructive steps require --yes')
218
+ .argument('[file]', 'Path to plan.json, or "-" / omit to read stdin')
219
+ .option('--yes', 'Authorize destructive commands (e.g. Smart Lock unlock, Garage open)')
220
+ .option('--continue-on-error', 'Keep running after a failed step (default: stop at first error)')
221
+ .action(async (file, options) => {
222
+ let raw;
223
+ try {
224
+ raw = await readPlanSource(file);
225
+ }
226
+ catch (err) {
227
+ handleError(err);
228
+ }
229
+ const v = validatePlan(raw);
230
+ if (!v.ok) {
231
+ if (isJsonMode()) {
232
+ printJson({ ran: false, issues: v.issues });
233
+ }
234
+ else {
235
+ console.error('✗ plan invalid, refusing to run:');
236
+ for (const i of v.issues)
237
+ console.error(` ${i.path}: ${i.message}`);
238
+ }
239
+ process.exit(2);
240
+ }
241
+ const out = {
242
+ plan: v.plan,
243
+ results: [],
244
+ summary: { total: v.plan.steps.length, ok: 0, error: 0, skipped: 0 },
245
+ };
246
+ try {
247
+ for (let i = 0; i < v.plan.steps.length; i++) {
248
+ const step = v.plan.steps[i];
249
+ const idx = i + 1;
250
+ if (step.type === 'wait') {
251
+ await new Promise((r) => setTimeout(r, step.ms));
252
+ out.results.push({ step: idx, type: 'wait', ms: step.ms, status: 'ok' });
253
+ out.summary.ok++;
254
+ if (!isJsonMode())
255
+ console.log(` ${idx}. wait ${step.ms}ms`);
256
+ continue;
257
+ }
258
+ if (step.type === 'scene') {
259
+ try {
260
+ await executeScene(step.sceneId);
261
+ out.results.push({ step: idx, type: 'scene', sceneId: step.sceneId, status: 'ok' });
262
+ out.summary.ok++;
263
+ if (!isJsonMode())
264
+ console.log(` ${idx}. ✓ scene ${step.sceneId}`);
265
+ }
266
+ catch (err) {
267
+ const msg = err instanceof Error ? err.message : String(err);
268
+ out.results.push({ step: idx, type: 'scene', sceneId: step.sceneId, status: 'error', error: msg });
269
+ out.summary.error++;
270
+ if (!isJsonMode())
271
+ console.log(` ${idx}. ✗ scene ${step.sceneId}: ${msg}`);
272
+ if (!options.continueOnError)
273
+ break;
274
+ }
275
+ continue;
276
+ }
277
+ // command
278
+ const resolvedDeviceId = resolveDeviceId(step.deviceId, step.deviceName);
279
+ const deviceType = getCachedDevice(resolvedDeviceId)?.type;
280
+ const commandType = step.commandType ?? 'command';
281
+ const destructive = isDestructiveCommand(deviceType, step.command, commandType);
282
+ if (destructive && !options.yes) {
283
+ out.results.push({
284
+ step: idx,
285
+ type: 'command',
286
+ deviceId: resolvedDeviceId,
287
+ command: step.command,
288
+ status: 'skipped',
289
+ error: 'destructive — rerun with --yes',
290
+ });
291
+ out.summary.skipped++;
292
+ if (!isJsonMode())
293
+ console.log(` ${idx}. ⚠ skipped ${step.command} on ${resolvedDeviceId} (destructive — pass --yes)`);
294
+ if (!options.continueOnError)
295
+ break;
296
+ continue;
297
+ }
298
+ try {
299
+ await executeCommand(resolvedDeviceId, step.command, step.parameter, commandType);
300
+ out.results.push({
301
+ step: idx,
302
+ type: 'command',
303
+ deviceId: resolvedDeviceId,
304
+ command: step.command,
305
+ status: 'ok',
306
+ });
307
+ out.summary.ok++;
308
+ if (!isJsonMode())
309
+ console.log(` ${idx}. ✓ ${step.command} on ${resolvedDeviceId}`);
310
+ }
311
+ catch (err) {
312
+ if (err instanceof Error && err.name === 'DryRunSignal') {
313
+ out.results.push({
314
+ step: idx,
315
+ type: 'command',
316
+ deviceId: resolvedDeviceId,
317
+ command: step.command,
318
+ status: 'ok',
319
+ });
320
+ out.summary.ok++;
321
+ if (!isJsonMode())
322
+ console.log(` ${idx}. ◦ dry-run ${step.command} on ${resolvedDeviceId}`);
323
+ continue;
324
+ }
325
+ const msg = err instanceof Error ? err.message : String(err);
326
+ out.results.push({
327
+ step: idx,
328
+ type: 'command',
329
+ deviceId: resolvedDeviceId,
330
+ command: step.command,
331
+ status: 'error',
332
+ error: msg,
333
+ });
334
+ out.summary.error++;
335
+ if (!isJsonMode())
336
+ console.log(` ${idx}. ✗ ${step.command} on ${resolvedDeviceId}: ${msg}`);
337
+ if (!options.continueOnError)
338
+ break;
339
+ }
340
+ }
341
+ if (isJsonMode()) {
342
+ printJson({ ran: true, ...out });
343
+ }
344
+ else {
345
+ const { ok, error, skipped, total } = out.summary;
346
+ console.log(`\nsummary: ok=${ok} error=${error} skipped=${skipped} total=${total}`);
347
+ }
348
+ }
349
+ catch (err) {
350
+ handleError(err);
351
+ }
352
+ if (out.summary.error > 0)
353
+ process.exit(1);
354
+ });
355
+ }
356
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/commands/plan.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAgC5D,MAAM,gBAAgB,GAAG;IACvB,OAAO,EAAE,8CAA8C;IACvD,GAAG,EAAE,qCAAqC;IAC1C,KAAK,EAAE,gBAAgB;IACvB,WAAW,EACT,4IAA4I;IAC9I,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC;IAC9B,UAAU,EAAE;QACV,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;QACzB,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC/B,KAAK,EAAE;YACL,IAAI,EAAE,OAAO;YACb,KAAK,EAAE;gBACL,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,QAAQ;wBACd,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;wBAC7B,UAAU,EAAE;4BACV,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;4BAC1B,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE;4BAC1C,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE;4BAC5C,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE;4BACzC,SAAS,EAAE,EAAE;4BACb,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE;4BAC/C,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;yBACzB;wBACD,oBAAoB,EAAE,KAAK;qBAC5B;oBACD;wBACE,IAAI,EAAE,QAAQ;wBACd,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;wBAC7B,UAAU,EAAE;4BACV,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;4BACxB,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE;4BACzC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;yBACzB;wBACD,oBAAoB,EAAE,KAAK;qBAC5B;oBACD;wBACE,IAAI,EAAE,QAAQ;wBACd,QAAQ,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC;wBACxB,UAAU,EAAE;4BACV,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;4BACvB,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE;4BACpD,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;yBACzB;wBACD,oBAAoB,EAAE,KAAK;qBAC5B;iBACF;aACF;SACF;KACF;IACD,oBAAoB,EAAE,KAAK;CACnB,CAAC;AAOX,MAAM,UAAU,YAAY,CAAC,GAAY;IAIvC,MAAM,MAAM,GAA0B,EAAE,CAAC;IACzC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,4BAA4B,EAAE,CAAC,EAAE,CAAC;IACvF,CAAC;IACD,MAAM,CAAC,GAAG,GAA8B,CAAC;IACzC,IAAI,CAAC,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAC5D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC/B,CAAC;IACD,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QAC1B,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC;QACzB,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACxD,OAAO;QACT,CAAC;QACD,MAAM,CAAC,GAAG,IAA+B,CAAC;QAC1C,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,SAAS;gBACZ,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAChF,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,0CAA0C,EAAE,CAAC,CAAC;gBAC/F,CAAC;gBACD,IAAI,CAAC,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC;oBACtF,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,0CAA0C,EAAE,CAAC,CAAC;gBACjG,CAAC;gBACD,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;oBACjC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,6CAA6C,EAAE,CAAC,CAAC;gBACzF,CAAC;gBACD,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;oBAC/B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,gDAAgD,EAAE,CAAC,CAAC;gBAC5F,CAAC;gBACD,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;oBAChD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,4BAA4B,EAAE,CAAC,CAAC;gBAChF,CAAC;gBACD,IACE,CAAC,CAAC,WAAW,KAAK,SAAS;oBAC3B,CAAC,CAAC,WAAW,KAAK,SAAS;oBAC3B,CAAC,CAAC,WAAW,KAAK,WAAW,EAC7B,CAAC;oBACD,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,GAAG,EAAE,cAAc;wBACzB,OAAO,EAAE,kCAAkC;qBAC5C,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM;YACR,KAAK,OAAO;gBACV,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;oBAChD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,4BAA4B,EAAE,CAAC,CAAC;gBAChF,CAAC;gBACD,MAAM;YACR,KAAK,MAAM;gBACT,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC;oBACtF,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,GAAG,EAAE,KAAK;wBAChB,OAAO,EAAE,mCAAmC;qBAC7C,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM;YACR;gBACE,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,GAAG,EAAE,OAAO;oBAClB,OAAO,EAAE,6CAA6C;iBACvD,CAAC,CAAC;QACP,CAAC;IACH,CAAC,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACpD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAW,EAAE,CAAC;AACzC,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,IAAwB;IACpD,MAAM,IAAI,GAAG,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,GAAG;QAC7C,CAAC,CAAC,MAAM,SAAS,EAAE;QACnB,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAClC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,GAAG;YAChC,CAAC,CAAC,2BAA2B;YAC7B,CAAC,CAAC,uBAAuB,IAAI,EAAE,CAClC,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,2BAA4B,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IACvE,CAAC;AACH,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,GAAG,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC;AAYD,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,MAAM,IAAI,GAAG,OAAO;SACjB,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,mDAAmD,CAAC;SAChE,WAAW,CAAC,OAAO,EAAE;;;;;;;;;;;;;;;;CAgBzB,CAAC,CAAC;IAED,IAAI;SACD,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,2CAA2C,CAAC;SACxD,MAAM,CAAC,GAAG,EAAE;QACX,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEL,IAAI;SACD,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,oDAAoD,CAAC;SACjE,QAAQ,CAAC,QAAQ,EAAE,gDAAgD,CAAC;SACpE,MAAM,CAAC,KAAK,EAAE,IAAwB,EAAE,EAAE;QACzC,IAAI,GAAY,CAAC;QACjB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;QACD,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,IAAI,UAAU,EAAE,EAAE,CAAC;gBACjB,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YACrD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;gBACjC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;oBAC9B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC7C,CAAC;YACH,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;QAC7G,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,IAAI;SACD,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,gFAAgF,CAAC;SAC7F,QAAQ,CAAC,QAAQ,EAAE,gDAAgD,CAAC;SACpE,MAAM,CAAC,OAAO,EAAE,sEAAsE,CAAC;SACvF,MAAM,CAAC,qBAAqB,EAAE,iEAAiE,CAAC;SAChG,MAAM,CACL,KAAK,EACH,IAAwB,EACxB,OAAqD,EACrD,EAAE;QACF,IAAI,GAAY,CAAC;QACjB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;QACD,MAAM,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACV,IAAI,UAAU,EAAE,EAAE,CAAC;gBACjB,SAAS,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YAC9C,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;gBAClD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM;oBAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YACvE,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,GAAG,GAAkB;YACzB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,EAAE;YACX,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;SACrE,CAAC;QAEF,IAAI,CAAC;YACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7C,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC7B,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;gBAClB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBACzB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;oBACjD,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;oBACzE,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;oBACjB,IAAI,CAAC,UAAU,EAAE;wBAAE,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,UAAU,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;oBAC9D,SAAS;gBACX,CAAC;gBACD,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC1B,IAAI,CAAC;wBACH,MAAM,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;wBACjC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;wBACpF,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;wBACjB,IAAI,CAAC,UAAU,EAAE;4BAAE,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,aAAa,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;oBACtE,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;wBAC7D,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;wBACnG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;wBACpB,IAAI,CAAC,UAAU,EAAE;4BAAE,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,aAAa,IAAI,CAAC,OAAO,KAAK,GAAG,EAAE,CAAC,CAAC;wBAC5E,IAAI,CAAC,OAAO,CAAC,eAAe;4BAAE,MAAM;oBACtC,CAAC;oBACD,SAAS;gBACX,CAAC;gBACD,UAAU;gBACV,MAAM,gBAAgB,GAAG,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;gBACzE,MAAM,UAAU,GAAG,eAAe,CAAC,gBAAgB,CAAC,EAAE,IAAI,CAAC;gBAC3D,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,SAAS,CAAC;gBAClD,MAAM,WAAW,GAAG,oBAAoB,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;gBAChF,IAAI,WAAW,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;oBAChC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;wBACf,IAAI,EAAE,GAAG;wBACT,IAAI,EAAE,SAAS;wBACf,QAAQ,EAAE,gBAAgB;wBAC1B,OAAO,EAAE,IAAI,CAAC,OAAO;wBACrB,MAAM,EAAE,SAAS;wBACjB,KAAK,EAAE,gCAAgC;qBACxC,CAAC,CAAC;oBACH,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;oBACtB,IAAI,CAAC,UAAU,EAAE;wBACf,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,eAAe,IAAI,CAAC,OAAO,OAAO,gBAAgB,6BAA6B,CAAC,CAAC;oBACvG,IAAI,CAAC,OAAO,CAAC,eAAe;wBAAE,MAAM;oBACpC,SAAS;gBACX,CAAC;gBACD,IAAI,CAAC;oBACH,MAAM,cAAc,CAAC,gBAAgB,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;oBAClF,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;wBACf,IAAI,EAAE,GAAG;wBACT,IAAI,EAAE,SAAS;wBACf,QAAQ,EAAE,gBAAgB;wBAC1B,OAAO,EAAE,IAAI,CAAC,OAAO;wBACrB,MAAM,EAAE,IAAI;qBACb,CAAC,CAAC;oBACH,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;oBACjB,IAAI,CAAC,UAAU,EAAE;wBACf,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,OAAO,IAAI,CAAC,OAAO,OAAO,gBAAgB,EAAE,CAAC,CAAC;gBACtE,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;wBACxD,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;4BACf,IAAI,EAAE,GAAG;4BACT,IAAI,EAAE,SAAS;4BACf,QAAQ,EAAE,gBAAgB;4BAC1B,OAAO,EAAE,IAAI,CAAC,OAAO;4BACrB,MAAM,EAAE,IAAI;yBACb,CAAC,CAAC;wBACH,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;wBACjB,IAAI,CAAC,UAAU,EAAE;4BACf,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,eAAe,IAAI,CAAC,OAAO,OAAO,gBAAgB,EAAE,CAAC,CAAC;wBAC5E,SAAS;oBACX,CAAC;oBACD,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBAC7D,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;wBACf,IAAI,EAAE,GAAG;wBACT,IAAI,EAAE,SAAS;wBACf,QAAQ,EAAE,gBAAgB;wBAC1B,OAAO,EAAE,IAAI,CAAC,OAAO;wBACrB,MAAM,EAAE,OAAO;wBACf,KAAK,EAAE,GAAG;qBACX,CAAC,CAAC;oBACH,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;oBACpB,IAAI,CAAC,UAAU,EAAE;wBACf,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,OAAO,IAAI,CAAC,OAAO,OAAO,gBAAgB,KAAK,GAAG,EAAE,CAAC,CAAC;oBAC5E,IAAI,CAAC,OAAO,CAAC,eAAe;wBAAE,MAAM;gBACtC,CAAC;YACH,CAAC;YAED,IAAI,UAAU,EAAE,EAAE,CAAC;gBACjB,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACN,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC;gBAClD,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,UAAU,KAAK,YAAY,OAAO,UAAU,KAAK,EAAE,CAAC,CAAC;YACtF,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;QACD,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC,CACF,CAAC;AACN,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerQuotaCommand(program: Command): void;
@@ -0,0 +1,77 @@
1
+ import { printJson, isJsonMode } from '../utils/output.js';
2
+ import { DAILY_QUOTA, loadQuota, resetQuota, todayUsage, } from '../utils/quota.js';
3
+ export function registerQuotaCommand(program) {
4
+ const quota = program
5
+ .command('quota')
6
+ .description('Inspect and manage the local SwitchBot API request counter')
7
+ .addHelpText('after', `
8
+ Every request the CLI makes is counted locally in ~/.switchbot/quota.json.
9
+ Counts are bucketed by local date, one record per endpoint pattern. This
10
+ is a best-effort mirror of the SwitchBot 10,000/day limit — it does not
11
+ include requests made outside this CLI (mobile app, other scripts).
12
+
13
+ Subcommands:
14
+ status Show today's usage and the last 7 days
15
+ reset Delete the local counter file
16
+
17
+ Examples:
18
+ $ switchbot quota status
19
+ $ switchbot quota status --json
20
+ $ switchbot quota reset
21
+ `);
22
+ quota
23
+ .command('status')
24
+ .description("Show today's usage and the last 7 days")
25
+ .action(() => {
26
+ const usage = todayUsage();
27
+ const history = loadQuota();
28
+ if (isJsonMode()) {
29
+ printJson({
30
+ today: {
31
+ date: usage.date,
32
+ total: usage.total,
33
+ remaining: usage.remaining,
34
+ dailyLimit: DAILY_QUOTA,
35
+ endpoints: usage.endpoints,
36
+ },
37
+ history: history.days,
38
+ });
39
+ return;
40
+ }
41
+ console.log(`Today (${usage.date}):`);
42
+ console.log(` Requests used: ${usage.total} / ${DAILY_QUOTA}`);
43
+ console.log(` Remaining budget: ${usage.remaining}`);
44
+ if (Object.keys(usage.endpoints).length === 0) {
45
+ console.log(' (no requests recorded yet)');
46
+ }
47
+ else {
48
+ console.log(' Endpoint breakdown:');
49
+ const entries = Object.entries(usage.endpoints).sort((a, b) => b[1] - a[1]);
50
+ for (const [endpoint, count] of entries) {
51
+ console.log(` ${endpoint.padEnd(48)} ${count}`);
52
+ }
53
+ }
54
+ const otherDays = Object.entries(history.days)
55
+ .filter(([d]) => d !== usage.date)
56
+ .sort((a, b) => b[0].localeCompare(a[0]));
57
+ if (otherDays.length > 0) {
58
+ console.log('\nRecent history:');
59
+ for (const [date, bucket] of otherDays) {
60
+ console.log(` ${date} ${bucket.total}`);
61
+ }
62
+ }
63
+ });
64
+ quota
65
+ .command('reset')
66
+ .description('Delete the local quota counter file')
67
+ .action(() => {
68
+ resetQuota();
69
+ if (isJsonMode()) {
70
+ printJson({ reset: true });
71
+ }
72
+ else {
73
+ console.log('Quota counter reset.');
74
+ }
75
+ });
76
+ }
77
+ //# sourceMappingURL=quota.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quota.js","sourceRoot":"","sources":["../../src/commands/quota.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
- import { createClient } from '../api/client.js';
2
- import { printTable, printJson, isJsonMode, handleError } from '../utils/output.js';
1
+ import { printJson, isJsonMode, handleError } from '../utils/output.js';
2
+ import { resolveFormat, resolveFields, renderRows } from '../utils/format.js';
3
+ import { fetchScenes, executeScene } from '../lib/scenes.js';
3
4
  export function registerScenesCommand(program) {
4
5
  const scenes = program
5
6
  .command('scenes')
@@ -10,25 +11,26 @@ export function registerScenesCommand(program) {
10
11
  .description('List all manual scenes (scenes created in the SwitchBot app)')
11
12
  .addHelpText('after', `
12
13
  Output columns: sceneId, sceneName
14
+ --fields accepts any subset of these names (exit 2 on unknown names).
13
15
 
14
16
  Examples:
15
17
  $ switchbot scenes list
18
+ $ switchbot scenes list --format tsv --fields sceneId,sceneName
19
+ $ switchbot scenes list --format id
16
20
  $ switchbot scenes list --json
17
21
  `)
18
22
  .action(async () => {
19
23
  try {
20
- const client = createClient();
21
- const res = await client.get('/v1.1/scenes');
22
- if (isJsonMode()) {
23
- printJson(res.data.body);
24
+ const scenes = await fetchScenes();
25
+ const fmt = resolveFormat();
26
+ if (fmt === 'json' && process.argv.includes('--json')) {
27
+ printJson(scenes);
24
28
  return;
25
29
  }
26
- const scenes = res.data.body;
27
- if (scenes.length === 0) {
30
+ renderRows(['sceneId', 'sceneName'], scenes.map((s) => [s.sceneId, s.sceneName]), fmt, resolveFields());
31
+ if (fmt === 'table' && scenes.length === 0) {
28
32
  console.log('No scenes found');
29
- return;
30
33
  }
31
- printTable(['sceneId', 'sceneName'], scenes.map((s) => [s.sceneId, s.sceneName]));
32
34
  }
33
35
  catch (error) {
34
36
  handleError(error);
@@ -45,9 +47,13 @@ Example:
45
47
  `)
46
48
  .action(async (sceneId) => {
47
49
  try {
48
- const client = createClient();
49
- await client.post(`/v1.1/scenes/${sceneId}/execute`);
50
- console.log(`✓ Scene executed: ${sceneId}`);
50
+ await executeScene(sceneId);
51
+ if (isJsonMode()) {
52
+ printJson({ ok: true, sceneId });
53
+ }
54
+ else {
55
+ console.log(`✓ Scene executed: ${sceneId}`);
56
+ }
51
57
  }
52
58
  catch (error) {
53
59
  handleError(error);
@@ -1 +1 @@
1
- {"version":3,"file":"scenes.js","sourceRoot":"","sources":["../../src/commands/scenes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAOpF,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,MAAM,MAAM,GAAG,OAAO;SACnB,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,qCAAqC,CAAC,CAAC;IAEtD,wBAAwB;IACxB,MAAM;SACH,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,8DAA8D,CAAC;SAC3E,WAAW,CAAC,OAAO,EAAE;;;;;;CAMzB,CAAC;SACG,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAoB,cAAc,CAAC,CAAC;YAEhE,IAAI,UAAU,EAAE,EAAE,CAAC;gBACjB,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACzB,OAAO;YACT,CAAC;YAED,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YAC7B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;gBAC/B,OAAO;YACT,CAAC;YAED,UAAU,CACR,CAAC,SAAS,EAAE,WAAW,CAAC,EACxB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAC5C,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,qCAAqC;IACrC,MAAM;SACH,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,kCAAkC,CAAC;SAC/C,QAAQ,CAAC,WAAW,EAAE,6BAA6B,CAAC;SACpD,WAAW,CAAC,OAAO,EAAE;;;CAGzB,CAAC;SACG,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,EAAE;QAChC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;YAC9B,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,OAAO,UAAU,CAAC,CAAC;YACrD,OAAO,CAAC,GAAG,CAAC,qBAAqB,OAAO,EAAE,CAAC,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"scenes.js","sourceRoot":"","sources":["../../src/commands/scenes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAE7D,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,MAAM,MAAM,GAAG,OAAO;SACnB,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,qCAAqC,CAAC,CAAC;IAEtD,wBAAwB;IACxB,MAAM;SACH,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,8DAA8D,CAAC;SAC3E,WAAW,CAAC,OAAO,EAAE;;;;;;;;;CASzB,CAAC;SACG,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,WAAW,EAAE,CAAC;YACnC,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;YAE5B,IAAI,GAAG,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACtD,SAAS,CAAC,MAAM,CAAC,CAAC;gBAClB,OAAO;YACT,CAAC;YAED,UAAU,CACR,CAAC,SAAS,EAAE,WAAW,CAAC,EACxB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAC3C,GAAG,EACH,aAAa,EAAE,CAChB,CAAC;YACF,IAAI,GAAG,KAAK,OAAO,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3C,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,qCAAqC;IACrC,MAAM;SACH,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,kCAAkC,CAAC;SAC/C,QAAQ,CAAC,WAAW,EAAE,6BAA6B,CAAC;SACpD,WAAW,CAAC,OAAO,EAAE;;;CAGzB,CAAC;SACG,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,EAAE;QAChC,IAAI,CAAC;YACH,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;YAC5B,IAAI,UAAU,EAAE,EAAE,CAAC;gBACjB,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,qBAAqB,OAAO,EAAE,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerSchemaCommand(program: Command): void;
@@ -0,0 +1,77 @@
1
+ import { printJson, isJsonMode } from '../utils/output.js';
2
+ import { getEffectiveCatalog } from '../devices/catalog.js';
3
+ function toSchemaEntry(e) {
4
+ return {
5
+ type: e.type,
6
+ description: e.description ?? '',
7
+ category: e.category,
8
+ aliases: e.aliases ?? [],
9
+ role: e.role ?? null,
10
+ readOnly: e.readOnly ?? false,
11
+ commands: e.commands.map(toSchemaCommand),
12
+ statusFields: e.statusFields ?? [],
13
+ };
14
+ }
15
+ function toSchemaCommand(c) {
16
+ return {
17
+ command: c.command,
18
+ parameter: c.parameter,
19
+ description: c.description,
20
+ commandType: (c.commandType ?? 'command'),
21
+ idempotent: Boolean(c.idempotent),
22
+ destructive: Boolean(c.destructive),
23
+ ...(c.exampleParams ? { exampleParams: c.exampleParams } : {}),
24
+ };
25
+ }
26
+ export function registerSchemaCommand(program) {
27
+ const schema = program
28
+ .command('schema')
29
+ .description('Export the device catalog as structured JSON (for agent prompts / tooling)');
30
+ schema
31
+ .command('export')
32
+ .description('Print the full catalog as structured JSON (one object per type)')
33
+ .option('--type <type>', 'Restrict to a single device type (e.g. "Strip Light")')
34
+ .option('--role <role>', 'Restrict to a functional role: lighting, security, sensor, climate, media, cleaning, curtain, fan, power, hub, other')
35
+ .option('--category <cat>', 'Restrict to "physical" or "ir"')
36
+ .addHelpText('after', `
37
+ Output is always JSON (this command ignores --format). The output is a
38
+ catalog export — not a formal JSON Schema standard document — suitable for
39
+ pre-baking LLM prompts or regenerating docs when the catalog changes.
40
+
41
+ Examples:
42
+ $ switchbot schema export > catalog.json
43
+ $ switchbot schema export --type Bot | jq '.types[0].commands'
44
+ $ switchbot schema export --role lighting | jq '[.types[].type]'
45
+ $ switchbot schema export --role security --category physical
46
+ `)
47
+ .action((options) => {
48
+ const catalog = getEffectiveCatalog();
49
+ let filtered = catalog;
50
+ if (options.type) {
51
+ const q = options.type.toLowerCase();
52
+ filtered = filtered.filter((e) => e.type.toLowerCase() === q ||
53
+ (e.aliases ?? []).some((a) => a.toLowerCase() === q));
54
+ }
55
+ if (options.role) {
56
+ const q = options.role.toLowerCase();
57
+ filtered = filtered.filter((e) => (e.role ?? 'other') === q);
58
+ }
59
+ if (options.category) {
60
+ const q = options.category.toLowerCase();
61
+ filtered = filtered.filter((e) => e.category === q);
62
+ }
63
+ const payload = {
64
+ version: '1.0',
65
+ generatedAt: new Date().toISOString(),
66
+ types: filtered.map(toSchemaEntry),
67
+ };
68
+ // Always JSON — schema export without JSON would be a category error.
69
+ if (isJsonMode()) {
70
+ printJson(payload);
71
+ }
72
+ else {
73
+ console.log(JSON.stringify(payload, null, 2));
74
+ }
75
+ });
76
+ }
77
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/commands/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerWatchCommand(devices: Command): void;