@puyinkai/xiaobao-cli 0.1.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 (41) hide show
  1. package/README.md +81 -0
  2. package/dist/api-Ccj5dLMo.mjs +100 -0
  3. package/dist/api-client-DwySN6x-.mjs +75 -0
  4. package/dist/audio-VmDQMq59.mjs +14 -0
  5. package/dist/auth-ChHvqjCS.mjs +15 -0
  6. package/dist/cli.d.mts +1 -0
  7. package/dist/cli.mjs +30 -0
  8. package/dist/consultant-ABFTL_jx.mjs +11 -0
  9. package/dist/customer-DtSnQqy_.mjs +11 -0
  10. package/dist/device-flow-BgsZipYA.mjs +166 -0
  11. package/dist/focus-BDYuP2vZ.mjs +11 -0
  12. package/dist/format-BZvv8lYc.mjs +610 -0
  13. package/dist/headers-D79npewp.mjs +11 -0
  14. package/dist/list--o5Q_PI8.mjs +80 -0
  15. package/dist/list-Bkyi95YO.mjs +76 -0
  16. package/dist/list-CGACp0y-.mjs +76 -0
  17. package/dist/list-CVKSGNu4.mjs +91 -0
  18. package/dist/list-CzB9_Jho.mjs +91 -0
  19. package/dist/list-DW6KAAaC.mjs +92 -0
  20. package/dist/list-iwd9cH1I.mjs +41 -0
  21. package/dist/login-BwkrByMm.mjs +91 -0
  22. package/dist/logout-BJm9pjje.mjs +49 -0
  23. package/dist/project-Ba05YzJ5.mjs +14 -0
  24. package/dist/project-store-Bz5kf-EI.mjs +62 -0
  25. package/dist/qa-D-B9FV9W.mjs +60 -0
  26. package/dist/resistance-Cf7zsdB3.mjs +11 -0
  27. package/dist/text-BLH4R3xv.mjs +49 -0
  28. package/dist/token-store-CHZ_rJQk.mjs +85 -0
  29. package/dist/use-DV9Ii3Tn.mjs +61 -0
  30. package/dist/util-DgwkUfV9.mjs +46 -0
  31. package/dist/visit-Ct3Vea8I.mjs +11 -0
  32. package/dist/whoami-DwTHvI4B.mjs +51 -0
  33. package/package.json +36 -0
  34. package/skills/wangxiaobao-audio-query/SKILL.md +252 -0
  35. package/skills/wangxiaobao-audio-wiki/SKILL.md +332 -0
  36. package/skills/wangxiaobao-customer-focus-query/SKILL.md +213 -0
  37. package/skills/wangxiaobao-customer-query/SKILL.md +214 -0
  38. package/skills/wangxiaobao-customer-resistance-query/SKILL.md +211 -0
  39. package/skills/wangxiaobao-quick-qa/SKILL.md +238 -0
  40. package/skills/wangxiaobao-switch-project/SKILL.md +179 -0
  41. package/skills/wangxiaobao-visit-query/SKILL.md +249 -0
@@ -0,0 +1,610 @@
1
+ //#region node_modules/.pnpm/@toon-format+toon@2.2.0/node_modules/@toon-format/toon/dist/index.mjs
2
+ const NULL_LITERAL = "null";
3
+ const DEFAULT_DELIMITER = {
4
+ comma: ",",
5
+ tab: " ",
6
+ pipe: "|"
7
+ }.comma;
8
+ /**
9
+ * Escapes special characters in a string for encoding.
10
+ *
11
+ * @remarks
12
+ * Handles backslashes, quotes, newlines, carriage returns, and tabs.
13
+ */
14
+ function escapeString(value) {
15
+ return value.replace(/\\/g, `\\\\`).replace(/"/g, `\\"`).replace(/\n/g, `\\n`).replace(/\r/g, `\\r`).replace(/\t/g, `\\t`);
16
+ }
17
+ function isBooleanOrNullLiteral(token) {
18
+ return token === "true" || token === "false" || token === "null";
19
+ }
20
+ function normalizeValue(value) {
21
+ if (value === null) return null;
22
+ if (typeof value === "object" && value !== null && "toJSON" in value && typeof value.toJSON === "function") {
23
+ const next = value.toJSON();
24
+ if (next !== value) return normalizeValue(next);
25
+ }
26
+ if (typeof value === "string" || typeof value === "boolean") return value;
27
+ if (typeof value === "number") {
28
+ if (Object.is(value, -0)) return 0;
29
+ if (!Number.isFinite(value)) return null;
30
+ return value;
31
+ }
32
+ if (typeof value === "bigint") {
33
+ if (value >= Number.MIN_SAFE_INTEGER && value <= Number.MAX_SAFE_INTEGER) return Number(value);
34
+ return value.toString();
35
+ }
36
+ if (value instanceof Date) return value.toISOString();
37
+ if (Array.isArray(value)) return value.map(normalizeValue);
38
+ if (value instanceof Set) return Array.from(value).map(normalizeValue);
39
+ if (value instanceof Map) return Object.fromEntries(Array.from(value, ([k, v]) => [String(k), normalizeValue(v)]));
40
+ if (isPlainObject(value)) {
41
+ const encodedValues = {};
42
+ for (const key in value) if (Object.hasOwn(value, key)) encodedValues[key] = normalizeValue(value[key]);
43
+ return encodedValues;
44
+ }
45
+ return null;
46
+ }
47
+ function isJsonPrimitive(value) {
48
+ return value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
49
+ }
50
+ function isJsonArray(value) {
51
+ return Array.isArray(value);
52
+ }
53
+ function isJsonObject(value) {
54
+ return value !== null && typeof value === "object" && !Array.isArray(value);
55
+ }
56
+ function isEmptyObject(value) {
57
+ return Object.keys(value).length === 0;
58
+ }
59
+ function isPlainObject(value) {
60
+ if (value === null || typeof value !== "object") return false;
61
+ const prototype = Object.getPrototypeOf(value);
62
+ return prototype === null || prototype === Object.prototype;
63
+ }
64
+ function isArrayOfPrimitives(value) {
65
+ return value.length === 0 || value.every((item) => isJsonPrimitive(item));
66
+ }
67
+ function isArrayOfArrays(value) {
68
+ return value.length === 0 || value.every((item) => isJsonArray(item));
69
+ }
70
+ function isArrayOfObjects(value) {
71
+ return value.length === 0 || value.every((item) => isJsonObject(item));
72
+ }
73
+ const NUMERIC_LIKE_PATTERN = /^-?\d+(?:\.\d+)?(?:e[+-]?\d+)?$/i;
74
+ const LEADING_ZERO_PATTERN = /^0\d+$/;
75
+ /**
76
+ * Checks if a key can be used without quotes.
77
+ *
78
+ * @remarks
79
+ * Valid unquoted keys must start with a letter or underscore,
80
+ * followed by letters, digits, underscores, or dots.
81
+ */
82
+ function isValidUnquotedKey(key) {
83
+ return /^[A-Z_][\w.]*$/i.test(key);
84
+ }
85
+ /**
86
+ * Checks if a key segment is a valid identifier for safe folding/expansion.
87
+ *
88
+ * @remarks
89
+ * Identifier segments are more restrictive than unquoted keys:
90
+ * - Must start with a letter or underscore
91
+ * - Followed only by letters, digits, or underscores (no dots)
92
+ * - Used for safe key folding and path expansion
93
+ */
94
+ function isIdentifierSegment(key) {
95
+ return /^[A-Z_]\w*$/i.test(key);
96
+ }
97
+ /**
98
+ * Determines if a string value can be safely encoded without quotes.
99
+ *
100
+ * @remarks
101
+ * A string needs quoting if it:
102
+ * - Is empty
103
+ * - Has leading or trailing whitespace
104
+ * - Could be confused with a literal (boolean, null, number)
105
+ * - Contains structural characters (colons, brackets, braces)
106
+ * - Contains quotes or backslashes (need escaping)
107
+ * - Contains control characters (newlines, tabs, etc.)
108
+ * - Contains the active delimiter
109
+ * - Starts with a list marker (hyphen)
110
+ */
111
+ function isSafeUnquoted(value, delimiter = DEFAULT_DELIMITER) {
112
+ if (!value) return false;
113
+ if (value !== value.trim()) return false;
114
+ if (isBooleanOrNullLiteral(value) || isNumericLike(value)) return false;
115
+ if (value.includes(":")) return false;
116
+ if (value.includes("\"") || value.includes("\\")) return false;
117
+ if (/[[\]{}]/.test(value)) return false;
118
+ if (/[\n\r\t]/.test(value)) return false;
119
+ if (value.includes(delimiter)) return false;
120
+ if (value.startsWith("-")) return false;
121
+ return true;
122
+ }
123
+ /**
124
+ * Checks if a string looks like a number.
125
+ *
126
+ * @remarks
127
+ * Match numbers like `42`, `-3.14`, `1e-6`, `05`, etc.
128
+ */
129
+ function isNumericLike(value) {
130
+ return NUMERIC_LIKE_PATTERN.test(value) || LEADING_ZERO_PATTERN.test(value);
131
+ }
132
+ /**
133
+ * Attempts to fold a single-key object chain into a dotted path.
134
+ *
135
+ * @remarks
136
+ * Folding traverses nested objects with single keys, collapsing them into a dotted path.
137
+ * It stops when:
138
+ * - A non-single-key object is encountered
139
+ * - An array is encountered (arrays are not "single-key objects")
140
+ * - A primitive value is reached
141
+ * - The flatten depth limit is reached
142
+ * - Any segment fails safe mode validation
143
+ *
144
+ * Safe mode requirements:
145
+ * - `options.keyFolding` must be `'safe'`
146
+ * - Every segment must be a valid identifier (no dots, no special chars)
147
+ * - The folded key must not collide with existing sibling keys
148
+ * - No segment should require quoting
149
+ *
150
+ * @param key - The starting key to fold
151
+ * @param value - The value associated with the key
152
+ * @param siblings - Array of all sibling keys at this level (for collision detection)
153
+ * @param options - Resolved encoding options
154
+ * @returns A FoldResult if folding is possible, undefined otherwise
155
+ */
156
+ function tryFoldKeyChain(key, value, siblings, options, rootLiteralKeys, pathPrefix, flattenDepth) {
157
+ if (options.keyFolding !== "safe") return;
158
+ if (!isJsonObject(value)) return;
159
+ const { segments, tail, leafValue } = collectSingleKeyChain(key, value, flattenDepth ?? options.flattenDepth);
160
+ if (segments.length < 2) return;
161
+ if (!segments.every((seg) => isIdentifierSegment(seg))) return;
162
+ const foldedKey = buildFoldedKey(segments);
163
+ const absolutePath = pathPrefix ? `${pathPrefix}.${foldedKey}` : foldedKey;
164
+ if (siblings.includes(foldedKey)) return;
165
+ if (rootLiteralKeys && rootLiteralKeys.has(absolutePath)) return;
166
+ return {
167
+ foldedKey,
168
+ remainder: tail,
169
+ leafValue,
170
+ segmentCount: segments.length
171
+ };
172
+ }
173
+ /**
174
+ * Collects a chain of single-key objects into segments.
175
+ *
176
+ * @remarks
177
+ * Traverses nested objects, collecting keys until:
178
+ * - A non-single-key object is found
179
+ * - An array is encountered
180
+ * - A primitive is reached
181
+ * - An empty object is reached
182
+ * - The depth limit is reached
183
+ *
184
+ * @param startKey - The initial key to start the chain
185
+ * @param startValue - The value to traverse
186
+ * @param maxDepth - Maximum number of segments to collect
187
+ * @returns Object containing segments array, tail value, and leaf value
188
+ */
189
+ function collectSingleKeyChain(startKey, startValue, maxDepth) {
190
+ const segments = [startKey];
191
+ let currentValue = startValue;
192
+ while (segments.length < maxDepth) {
193
+ if (!isJsonObject(currentValue)) break;
194
+ const keys = Object.keys(currentValue);
195
+ if (keys.length !== 1) break;
196
+ const nextKey = keys[0];
197
+ const nextValue = currentValue[nextKey];
198
+ segments.push(nextKey);
199
+ currentValue = nextValue;
200
+ }
201
+ if (!isJsonObject(currentValue) || isEmptyObject(currentValue)) return {
202
+ segments,
203
+ tail: void 0,
204
+ leafValue: currentValue
205
+ };
206
+ return {
207
+ segments,
208
+ tail: currentValue,
209
+ leafValue: currentValue
210
+ };
211
+ }
212
+ function buildFoldedKey(segments) {
213
+ return segments.join(".");
214
+ }
215
+ function encodePrimitive(value, delimiter) {
216
+ if (value === null) return NULL_LITERAL;
217
+ if (typeof value === "boolean") return String(value);
218
+ if (typeof value === "number") return String(value);
219
+ return encodeStringLiteral(value, delimiter);
220
+ }
221
+ function encodeStringLiteral(value, delimiter = DEFAULT_DELIMITER) {
222
+ if (isSafeUnquoted(value, delimiter)) return value;
223
+ return `"${escapeString(value)}"`;
224
+ }
225
+ function encodeKey(key) {
226
+ if (isValidUnquotedKey(key)) return key;
227
+ return `"${escapeString(key)}"`;
228
+ }
229
+ function encodeAndJoinPrimitives(values, delimiter = DEFAULT_DELIMITER) {
230
+ return values.map((v) => encodePrimitive(v, delimiter)).join(delimiter);
231
+ }
232
+ function formatHeader(length, options) {
233
+ const key = options?.key;
234
+ const fields = options?.fields;
235
+ const delimiter = options?.delimiter ?? ",";
236
+ let header = "";
237
+ if (key != null) header += encodeKey(key);
238
+ header += `[${length}${delimiter !== DEFAULT_DELIMITER ? delimiter : ""}]`;
239
+ if (fields) {
240
+ const quotedFields = fields.map((f) => encodeKey(f));
241
+ header += `{${quotedFields.join(delimiter)}}`;
242
+ }
243
+ header += ":";
244
+ return header;
245
+ }
246
+ function* encodeJsonValue(value, options, depth) {
247
+ if (isJsonPrimitive(value)) {
248
+ const encodedPrimitive = encodePrimitive(value, options.delimiter);
249
+ if (encodedPrimitive !== "") yield encodedPrimitive;
250
+ return;
251
+ }
252
+ if (isJsonArray(value)) yield* encodeArrayLines(void 0, value, depth, options);
253
+ else if (isJsonObject(value)) yield* encodeObjectLines(value, depth, options);
254
+ }
255
+ function* encodeObjectLines(value, depth, options, rootLiteralKeys, pathPrefix, remainingDepth) {
256
+ const keys = Object.keys(value);
257
+ if (depth === 0 && !rootLiteralKeys) rootLiteralKeys = new Set(keys.filter((k) => k.includes(".")));
258
+ const effectiveFlattenDepth = remainingDepth ?? options.flattenDepth;
259
+ for (const [key, val] of Object.entries(value)) yield* encodeKeyValuePairLines(key, val, depth, options, keys, rootLiteralKeys, pathPrefix, effectiveFlattenDepth);
260
+ }
261
+ function* encodeKeyValuePairLines(key, value, depth, options, siblings, rootLiteralKeys, pathPrefix, flattenDepth) {
262
+ const currentPath = pathPrefix ? `${pathPrefix}.${key}` : key;
263
+ const effectiveFlattenDepth = flattenDepth ?? options.flattenDepth;
264
+ if (options.keyFolding === "safe" && siblings) {
265
+ const foldResult = tryFoldKeyChain(key, value, siblings, options, rootLiteralKeys, pathPrefix, effectiveFlattenDepth);
266
+ if (foldResult) {
267
+ const { foldedKey, remainder, leafValue, segmentCount } = foldResult;
268
+ const encodedFoldedKey = encodeKey(foldedKey);
269
+ if (remainder === void 0) {
270
+ if (isJsonPrimitive(leafValue)) {
271
+ yield indentedLine(depth, `${encodedFoldedKey}: ${encodePrimitive(leafValue, options.delimiter)}`, options.indent);
272
+ return;
273
+ } else if (isJsonArray(leafValue)) {
274
+ yield* encodeArrayLines(foldedKey, leafValue, depth, options);
275
+ return;
276
+ } else if (isJsonObject(leafValue) && isEmptyObject(leafValue)) {
277
+ yield indentedLine(depth, `${encodedFoldedKey}:`, options.indent);
278
+ return;
279
+ }
280
+ }
281
+ if (isJsonObject(remainder)) {
282
+ yield indentedLine(depth, `${encodedFoldedKey}:`, options.indent);
283
+ const remainingDepth = effectiveFlattenDepth - segmentCount;
284
+ const foldedPath = pathPrefix ? `${pathPrefix}.${foldedKey}` : foldedKey;
285
+ yield* encodeObjectLines(remainder, depth + 1, options, rootLiteralKeys, foldedPath, remainingDepth);
286
+ return;
287
+ }
288
+ }
289
+ }
290
+ const encodedKey = encodeKey(key);
291
+ if (isJsonPrimitive(value)) yield indentedLine(depth, `${encodedKey}: ${encodePrimitive(value, options.delimiter)}`, options.indent);
292
+ else if (isJsonArray(value)) yield* encodeArrayLines(key, value, depth, options);
293
+ else if (isJsonObject(value)) {
294
+ yield indentedLine(depth, `${encodedKey}:`, options.indent);
295
+ if (!isEmptyObject(value)) yield* encodeObjectLines(value, depth + 1, options, rootLiteralKeys, currentPath, effectiveFlattenDepth);
296
+ }
297
+ }
298
+ function* encodeArrayLines(key, value, depth, options) {
299
+ if (value.length === 0) {
300
+ yield indentedLine(depth, formatHeader(0, {
301
+ key,
302
+ delimiter: options.delimiter
303
+ }), options.indent);
304
+ return;
305
+ }
306
+ if (isArrayOfPrimitives(value)) {
307
+ yield indentedLine(depth, encodeInlineArrayLine(value, options.delimiter, key), options.indent);
308
+ return;
309
+ }
310
+ if (isArrayOfArrays(value)) {
311
+ if (value.every((arr) => isArrayOfPrimitives(arr))) {
312
+ yield* encodeArrayOfArraysAsListItemsLines(key, value, depth, options);
313
+ return;
314
+ }
315
+ }
316
+ if (isArrayOfObjects(value)) {
317
+ const header = extractTabularHeader(value);
318
+ if (header) yield* encodeArrayOfObjectsAsTabularLines(key, value, header, depth, options);
319
+ else yield* encodeMixedArrayAsListItemsLines(key, value, depth, options);
320
+ return;
321
+ }
322
+ yield* encodeMixedArrayAsListItemsLines(key, value, depth, options);
323
+ }
324
+ function* encodeArrayOfArraysAsListItemsLines(prefix, values, depth, options) {
325
+ yield indentedLine(depth, formatHeader(values.length, {
326
+ key: prefix,
327
+ delimiter: options.delimiter
328
+ }), options.indent);
329
+ for (const arr of values) if (isArrayOfPrimitives(arr)) {
330
+ const arrayLine = encodeInlineArrayLine(arr, options.delimiter);
331
+ yield indentedListItem(depth + 1, arrayLine, options.indent);
332
+ }
333
+ }
334
+ function encodeInlineArrayLine(values, delimiter, prefix) {
335
+ const header = formatHeader(values.length, {
336
+ key: prefix,
337
+ delimiter
338
+ });
339
+ const joinedValue = encodeAndJoinPrimitives(values, delimiter);
340
+ if (values.length === 0) return header;
341
+ return `${header} ${joinedValue}`;
342
+ }
343
+ function* encodeArrayOfObjectsAsTabularLines(prefix, rows, header, depth, options) {
344
+ yield indentedLine(depth, formatHeader(rows.length, {
345
+ key: prefix,
346
+ fields: header,
347
+ delimiter: options.delimiter
348
+ }), options.indent);
349
+ yield* writeTabularRowsLines(rows, header, depth + 1, options);
350
+ }
351
+ function extractTabularHeader(rows) {
352
+ if (rows.length === 0) return;
353
+ const firstRow = rows[0];
354
+ const firstKeys = Object.keys(firstRow);
355
+ if (firstKeys.length === 0) return;
356
+ if (isTabularArray(rows, firstKeys)) return firstKeys;
357
+ }
358
+ function isTabularArray(rows, header) {
359
+ for (const row of rows) {
360
+ if (Object.keys(row).length !== header.length) return false;
361
+ for (const key of header) {
362
+ if (!(key in row)) return false;
363
+ if (!isJsonPrimitive(row[key])) return false;
364
+ }
365
+ }
366
+ return true;
367
+ }
368
+ function* writeTabularRowsLines(rows, header, depth, options) {
369
+ for (const row of rows) yield indentedLine(depth, encodeAndJoinPrimitives(header.map((key) => row[key]), options.delimiter), options.indent);
370
+ }
371
+ function* encodeMixedArrayAsListItemsLines(prefix, items, depth, options) {
372
+ yield indentedLine(depth, formatHeader(items.length, {
373
+ key: prefix,
374
+ delimiter: options.delimiter
375
+ }), options.indent);
376
+ for (const item of items) yield* encodeListItemValueLines(item, depth + 1, options);
377
+ }
378
+ function* encodeObjectAsListItemLines(obj, depth, options) {
379
+ if (isEmptyObject(obj)) {
380
+ yield indentedLine(depth, "-", options.indent);
381
+ return;
382
+ }
383
+ const entries = Object.entries(obj);
384
+ const [firstKey, firstValue] = entries[0];
385
+ const restEntries = entries.slice(1);
386
+ if (isJsonArray(firstValue) && isArrayOfObjects(firstValue)) {
387
+ const header = extractTabularHeader(firstValue);
388
+ if (header) {
389
+ yield indentedListItem(depth, formatHeader(firstValue.length, {
390
+ key: firstKey,
391
+ fields: header,
392
+ delimiter: options.delimiter
393
+ }), options.indent);
394
+ yield* writeTabularRowsLines(firstValue, header, depth + 2, options);
395
+ if (restEntries.length > 0) yield* encodeObjectLines(Object.fromEntries(restEntries), depth + 1, options);
396
+ return;
397
+ }
398
+ }
399
+ const encodedKey = encodeKey(firstKey);
400
+ if (isJsonPrimitive(firstValue)) yield indentedListItem(depth, `${encodedKey}: ${encodePrimitive(firstValue, options.delimiter)}`, options.indent);
401
+ else if (isJsonArray(firstValue)) if (firstValue.length === 0) yield indentedListItem(depth, `${encodedKey}${formatHeader(0, { delimiter: options.delimiter })}`, options.indent);
402
+ else if (isArrayOfPrimitives(firstValue)) yield indentedListItem(depth, `${encodedKey}${encodeInlineArrayLine(firstValue, options.delimiter)}`, options.indent);
403
+ else {
404
+ yield indentedListItem(depth, `${encodedKey}${formatHeader(firstValue.length, { delimiter: options.delimiter })}`, options.indent);
405
+ for (const item of firstValue) yield* encodeListItemValueLines(item, depth + 2, options);
406
+ }
407
+ else if (isJsonObject(firstValue)) {
408
+ yield indentedListItem(depth, `${encodedKey}:`, options.indent);
409
+ if (!isEmptyObject(firstValue)) yield* encodeObjectLines(firstValue, depth + 2, options);
410
+ }
411
+ if (restEntries.length > 0) yield* encodeObjectLines(Object.fromEntries(restEntries), depth + 1, options);
412
+ }
413
+ function* encodeListItemValueLines(value, depth, options) {
414
+ if (isJsonPrimitive(value)) yield indentedListItem(depth, encodePrimitive(value, options.delimiter), options.indent);
415
+ else if (isJsonArray(value)) if (isArrayOfPrimitives(value)) yield indentedListItem(depth, encodeInlineArrayLine(value, options.delimiter), options.indent);
416
+ else {
417
+ yield indentedListItem(depth, formatHeader(value.length, { delimiter: options.delimiter }), options.indent);
418
+ for (const item of value) yield* encodeListItemValueLines(item, depth + 1, options);
419
+ }
420
+ else if (isJsonObject(value)) yield* encodeObjectAsListItemLines(value, depth, options);
421
+ }
422
+ function indentedLine(depth, content, indentSize) {
423
+ return " ".repeat(indentSize * depth) + content;
424
+ }
425
+ function indentedListItem(depth, content, indentSize) {
426
+ return indentedLine(depth, "- " + content, indentSize);
427
+ }
428
+ /**
429
+ * Applies a replacer function to a `JsonValue` and all its descendants.
430
+ *
431
+ * The replacer is called for:
432
+ * - The root value (with key='', path=[])
433
+ * - Every object property (with the property name as key)
434
+ * - Every array element (with the string index as key: '0', '1', etc.)
435
+ *
436
+ * @param root - The normalized `JsonValue` to transform
437
+ * @param replacer - The replacer function to apply
438
+ * @returns The transformed `JsonValue`
439
+ */
440
+ function applyReplacer(root, replacer) {
441
+ const replacedRoot = replacer("", root, []);
442
+ if (replacedRoot === void 0) return transformChildren(root, replacer, []);
443
+ return transformChildren(normalizeValue(replacedRoot), replacer, []);
444
+ }
445
+ /**
446
+ * Recursively transforms the children of a `JsonValue` using the replacer.
447
+ *
448
+ * @param value - The value whose children should be transformed
449
+ * @param replacer - The replacer function to apply
450
+ * @param path - Current path from root
451
+ * @returns The value with transformed children
452
+ */
453
+ function transformChildren(value, replacer, path) {
454
+ if (isJsonObject(value)) return transformObject(value, replacer, path);
455
+ if (isJsonArray(value)) return transformArray(value, replacer, path);
456
+ return value;
457
+ }
458
+ /**
459
+ * Transforms an object by applying the replacer to each property.
460
+ *
461
+ * @param obj - The object to transform
462
+ * @param replacer - The replacer function to apply
463
+ * @param path - Current path from root
464
+ * @returns A new object with transformed properties
465
+ */
466
+ function transformObject(obj, replacer, path) {
467
+ const result = {};
468
+ for (const [key, value] of Object.entries(obj)) {
469
+ const childPath = [...path, key];
470
+ const replacedValue = replacer(key, value, childPath);
471
+ if (replacedValue === void 0) continue;
472
+ result[key] = transformChildren(normalizeValue(replacedValue), replacer, childPath);
473
+ }
474
+ return result;
475
+ }
476
+ /**
477
+ * Transforms an array by applying the replacer to each element.
478
+ *
479
+ * @param arr - The array to transform
480
+ * @param replacer - The replacer function to apply
481
+ * @param path - Current path from root
482
+ * @returns A new array with transformed elements
483
+ */
484
+ function transformArray(arr, replacer, path) {
485
+ const result = [];
486
+ for (let i = 0; i < arr.length; i++) {
487
+ const value = arr[i];
488
+ const childPath = [...path, i];
489
+ const replacedValue = replacer(String(i), value, childPath);
490
+ if (replacedValue === void 0) continue;
491
+ const normalizedValue = normalizeValue(replacedValue);
492
+ result.push(transformChildren(normalizedValue, replacer, childPath));
493
+ }
494
+ return result;
495
+ }
496
+ /**
497
+ * Encodes a JavaScript value into TOON format string.
498
+ *
499
+ * @param input - Any JavaScript value (objects, arrays, primitives)
500
+ * @param options - Optional encoding configuration
501
+ * @returns TOON formatted string
502
+ *
503
+ * @example
504
+ * ```ts
505
+ * encode({ name: 'Alice', age: 30 })
506
+ * // name: Alice
507
+ * // age: 30
508
+ *
509
+ * encode({ users: [{ id: 1 }, { id: 2 }] })
510
+ * // users[]:
511
+ * // - id: 1
512
+ * // - id: 2
513
+ *
514
+ * encode(data, { indent: 4, keyFolding: 'safe' })
515
+ * ```
516
+ */
517
+ function encode(input, options) {
518
+ return Array.from(encodeLines(input, options)).join("\n");
519
+ }
520
+ /**
521
+ * Encodes a JavaScript value into TOON format as a sequence of lines.
522
+ *
523
+ * This function yields TOON lines one at a time without building the full string,
524
+ * making it suitable for streaming large outputs to files, HTTP responses, or process stdout.
525
+ *
526
+ * @param input - Any JavaScript value (objects, arrays, primitives)
527
+ * @param options - Optional encoding configuration
528
+ * @returns Iterable of TOON lines (without trailing newlines)
529
+ *
530
+ * @example
531
+ * ```ts
532
+ * // Stream to stdout
533
+ * for (const line of encodeLines({ name: 'Alice', age: 30 })) {
534
+ * console.log(line)
535
+ * }
536
+ *
537
+ * // Collect to array
538
+ * const lines = Array.from(encodeLines(data))
539
+ *
540
+ * // Equivalent to encode()
541
+ * const toonString = Array.from(encodeLines(data, options)).join('\n')
542
+ * ```
543
+ */
544
+ function encodeLines(input, options) {
545
+ const normalizedValue = normalizeValue(input);
546
+ const resolvedOptions = resolveOptions(options);
547
+ return encodeJsonValue(resolvedOptions.replacer ? applyReplacer(normalizedValue, resolvedOptions.replacer) : normalizedValue, resolvedOptions, 0);
548
+ }
549
+ function resolveOptions(options) {
550
+ return {
551
+ indent: options?.indent ?? 2,
552
+ delimiter: options?.delimiter ?? DEFAULT_DELIMITER,
553
+ keyFolding: options?.keyFolding ?? "off",
554
+ flattenDepth: options?.flattenDepth ?? Number.POSITIVE_INFINITY,
555
+ replacer: options?.replacer
556
+ };
557
+ }
558
+ //#endregion
559
+ //#region src/output/format.ts
560
+ /**
561
+ * Format a result payload to stdout in one of three flavours:
562
+ *
563
+ * json (default) pretty JSON, agent-friendly and human-OK
564
+ * toon TOON (Token-Oriented Object Notation) — ~30-50% fewer
565
+ * tokens on uniform array-of-objects (LLM context optimization)
566
+ * table not implemented in 0.1.0 — falls back to pretty JSON
567
+ * (a v0.1.x target; pure cosmetic, doesn't affect agent flow)
568
+ *
569
+ * Errors / logs MUST NOT go through here — use stderr (console.error) so
570
+ * agents parsing stdout don't break.
571
+ */
572
+ function writeResult(data, format = "json") {
573
+ const text = normalize(format) === "toon" ? encode(data) : JSON.stringify(data, null, 2);
574
+ process.stdout.write(text + "\n");
575
+ }
576
+ /** Print an error structurally to stdout (still parseable) and a hint to stderr. */
577
+ function writeError(error, format = "json") {
578
+ const payload = serializeError(error);
579
+ const text = normalize(format) === "toon" ? encode(payload) : JSON.stringify(payload, null, 2);
580
+ process.stdout.write(text + "\n");
581
+ const hint = payload.message;
582
+ if (hint) process.stderr.write(`error: ${hint}\n`);
583
+ }
584
+ function normalize(f) {
585
+ if (f === "toon") return "toon";
586
+ if (f === "table") return "table";
587
+ return "json";
588
+ }
589
+ function serializeError(error) {
590
+ if (error instanceof Error) return {
591
+ error: error.name,
592
+ message: error.message
593
+ };
594
+ if (error && typeof error === "object") {
595
+ const obj = error;
596
+ const errorKey = obj.code ?? obj.error ?? "UNKNOWN";
597
+ return {
598
+ error: errorKey,
599
+ message: obj.message ?? (obj.status != null ? `HTTP ${obj.status}` : null) ?? String(errorKey),
600
+ ...obj.status != null ? { status: obj.status } : {},
601
+ ...obj.body != null ? { details: obj.body } : {}
602
+ };
603
+ }
604
+ return {
605
+ error: "UNKNOWN",
606
+ message: String(error)
607
+ };
608
+ }
609
+ //#endregion
610
+ export { writeResult as n, writeError as t };
@@ -0,0 +1,11 @@
1
+ //#region src/output/headers.ts
2
+ function tenantProjectHeaders(active) {
3
+ return {
4
+ "X-Tenant-Id": active.tenantId,
5
+ "X-Tenant-Name": encodeURIComponent(active.tenantName),
6
+ "X-Project-Id": active.projectId,
7
+ "X-Project-Name": encodeURIComponent(active.projectName)
8
+ };
9
+ }
10
+ //#endregion
11
+ export { tenantProjectHeaders as t };
@@ -0,0 +1,80 @@
1
+ import { a as resolveConfig } from "./device-flow-BgsZipYA.mjs";
2
+ import { t as xbApiFetch } from "./api-client-DwySN6x-.mjs";
3
+ import { n as writeResult, t as writeError } from "./format-BZvv8lYc.mjs";
4
+ import { t as requireActiveProject } from "./project-store-Bz5kf-EI.mjs";
5
+ import { n as mergeUserIds, r as toLocalDateTime, t as csvToArray } from "./util-DgwkUfV9.mjs";
6
+ import { t as tenantProjectHeaders } from "./headers-D79npewp.mjs";
7
+ import { defineCommand } from "citty";
8
+ //#region src/commands/audio/list.ts
9
+ /**
10
+ * `xiaobao-cli audio list` — page audio metadata via POST /ai-open/audio/page.
11
+ *
12
+ * Mirrors openclaw-xiaobao xiaobao_list_audio. Returns audio metadata only
13
+ * (audioId / fileId / startTime / endTime / duration / sale info / fileUrl).
14
+ * Transcript text comes from `xiaobao-cli audio text <audio-id>`.
15
+ */
16
+ var list_default = defineCommand({
17
+ meta: {
18
+ name: "list",
19
+ description: "录音元数据分页查询(按时间范围 + 可选顾问过滤)"
20
+ },
21
+ args: {
22
+ from: {
23
+ type: "string",
24
+ required: true,
25
+ description: "录音开始时间,yyyy-MM-dd HH:mm:ss(或 ISO,自动转换)"
26
+ },
27
+ to: {
28
+ type: "string",
29
+ required: true,
30
+ description: "录音结束时间,同 from 格式"
31
+ },
32
+ "user-id": {
33
+ type: "string",
34
+ description: "单顾问 user-id 过滤"
35
+ },
36
+ "user-id-list": {
37
+ type: "string",
38
+ description: "CSV: u1,u2,u3 多顾问"
39
+ },
40
+ page: {
41
+ type: "string",
42
+ default: "1"
43
+ },
44
+ size: {
45
+ type: "string",
46
+ default: "10"
47
+ },
48
+ "api-base": { type: "string" },
49
+ "auth-base": { type: "string" },
50
+ format: {
51
+ type: "string",
52
+ default: "json"
53
+ }
54
+ },
55
+ async run({ args }) {
56
+ try {
57
+ const config = resolveConfig({
58
+ apiBase: args["api-base"],
59
+ authBase: args["auth-base"]
60
+ });
61
+ const active = await requireActiveProject();
62
+ const mergedUserIds = mergeUserIds(args["user-id"], csvToArray(args["user-id-list"]));
63
+ writeResult(await xbApiFetch(config, "POST", "/ai-open/audio/page", {
64
+ headers: tenantProjectHeaders(active),
65
+ body: {
66
+ fromDate: toLocalDateTime(args.from),
67
+ toDate: toLocalDateTime(args.to),
68
+ userIdList: mergedUserIds,
69
+ page: Number(args.page),
70
+ size: Number(args.size)
71
+ }
72
+ }), args.format);
73
+ } catch (err) {
74
+ writeError(err, args.format);
75
+ process.exit(1);
76
+ }
77
+ }
78
+ });
79
+ //#endregion
80
+ export { list_default as default };