lewxclaw 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.
package/dist/index.js ADDED
@@ -0,0 +1,3282 @@
1
+ #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __esm = (fn, res) => function __init() {
5
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
+ };
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+
12
+ // ../providers/dist/registry.js
13
+ var ProviderRegistry;
14
+ var init_registry = __esm({
15
+ "../providers/dist/registry.js"() {
16
+ "use strict";
17
+ ProviderRegistry = class {
18
+ providers = /* @__PURE__ */ new Map();
19
+ register(provider) {
20
+ if (this.providers.has(provider.id)) {
21
+ throw new Error(`Provider with id "${provider.id}" is already registered`);
22
+ }
23
+ this.providers.set(provider.id, provider);
24
+ }
25
+ get(id) {
26
+ return this.providers.get(id);
27
+ }
28
+ getConfigured() {
29
+ return Array.from(this.providers.values()).filter((p) => p.isConfigured());
30
+ }
31
+ list() {
32
+ return Array.from(this.providers.values());
33
+ }
34
+ };
35
+ }
36
+ });
37
+
38
+ // ../providers/dist/config.js
39
+ import { readFileSync as readFileSync3, existsSync as existsSync2 } from "fs";
40
+ import { join as join3 } from "path";
41
+ import { homedir } from "os";
42
+ function loadWxclawConfig() {
43
+ const projectConfig = join3(process.cwd(), ".wxclaw", "config.json");
44
+ const globalConfig = join3(homedir(), ".wxclaw", "config.json");
45
+ const configPath2 = existsSync2(projectConfig) ? projectConfig : globalConfig;
46
+ if (!existsSync2(configPath2))
47
+ return {};
48
+ return JSON.parse(readFileSync3(configPath2, "utf-8"));
49
+ }
50
+ function getProviderApiKey(providerId) {
51
+ const config = loadWxclawConfig();
52
+ const providers = config.providers;
53
+ return providers?.[providerId]?.apiKey ?? "";
54
+ }
55
+ var init_config = __esm({
56
+ "../providers/dist/config.js"() {
57
+ "use strict";
58
+ }
59
+ });
60
+
61
+ // ../providers/dist/openai-compatible.js
62
+ function defaultClassifyError(error) {
63
+ if (error instanceof ProviderHttpError) {
64
+ if (error.status === 429)
65
+ return "rate-limited";
66
+ if (error.status === 401 || error.status === 403)
67
+ return "auth-failed";
68
+ if (error.status >= 500)
69
+ return "service-unavailable";
70
+ }
71
+ return null;
72
+ }
73
+ function createOpenAICompatibleProvider(config) {
74
+ const { id, name, baseUrl, getApiKey, defaultModel, classifyError } = config;
75
+ const classify = classifyError ?? defaultClassifyError;
76
+ function buildMessages(params) {
77
+ const msgs = [];
78
+ if (params.systemPrompt) {
79
+ msgs.push({ role: "system", content: params.systemPrompt });
80
+ }
81
+ for (const m2 of params.messages) {
82
+ msgs.push({ role: m2.role, content: m2.content });
83
+ }
84
+ return msgs;
85
+ }
86
+ async function fetchCompletion(params, stream) {
87
+ const apiKey = getApiKey();
88
+ const body = {
89
+ model: params.model ?? defaultModel,
90
+ messages: buildMessages(params),
91
+ stream
92
+ };
93
+ if (params.temperature !== void 0)
94
+ body.temperature = params.temperature;
95
+ if (params.maxTokens !== void 0)
96
+ body.max_tokens = params.maxTokens;
97
+ const response = await fetch(`${baseUrl}/chat/completions`, {
98
+ method: "POST",
99
+ headers: {
100
+ "Content-Type": "application/json",
101
+ Authorization: `Bearer ${apiKey}`
102
+ },
103
+ body: JSON.stringify(body)
104
+ });
105
+ if (!response.ok) {
106
+ throw new ProviderHttpError(response.status, `HTTP ${response.status}: ${response.statusText}`);
107
+ }
108
+ if (stream) {
109
+ return response.body;
110
+ }
111
+ return await response.json();
112
+ }
113
+ return {
114
+ id,
115
+ name,
116
+ isConfigured() {
117
+ return getApiKey().length > 0;
118
+ },
119
+ classifyError(error) {
120
+ return classify(error);
121
+ },
122
+ async chat(params) {
123
+ const data = await fetchCompletion(params, false);
124
+ const choice = data.choices[0];
125
+ return {
126
+ content: choice?.message.content ?? "",
127
+ model: data.model,
128
+ usage: data.usage ? {
129
+ promptTokens: data.usage.prompt_tokens,
130
+ completionTokens: data.usage.completion_tokens,
131
+ totalTokens: data.usage.total_tokens
132
+ } : void 0
133
+ };
134
+ },
135
+ async *chatStream(params) {
136
+ const body = await fetchCompletion(params, true);
137
+ const reader = body.getReader();
138
+ const decoder = new TextDecoder();
139
+ let buffer = "";
140
+ try {
141
+ while (true) {
142
+ const { done, value } = await reader.read();
143
+ if (done)
144
+ break;
145
+ buffer += decoder.decode(value, { stream: true });
146
+ const lines = buffer.split("\n");
147
+ buffer = lines.pop() ?? "";
148
+ for (const line of lines) {
149
+ const trimmed = line.trim();
150
+ if (!trimmed || trimmed === "data: [DONE]")
151
+ continue;
152
+ if (!trimmed.startsWith("data: "))
153
+ continue;
154
+ const json = trimmed.slice(6);
155
+ try {
156
+ const parsed = JSON.parse(json);
157
+ const delta = parsed.choices[0]?.delta?.content ?? "";
158
+ const isDone = parsed.choices[0]?.finish_reason != null;
159
+ yield { content: delta, done: isDone };
160
+ } catch {
161
+ }
162
+ }
163
+ }
164
+ } finally {
165
+ reader.releaseLock();
166
+ }
167
+ yield { content: "", done: true };
168
+ }
169
+ };
170
+ }
171
+ var ProviderHttpError;
172
+ var init_openai_compatible = __esm({
173
+ "../providers/dist/openai-compatible.js"() {
174
+ "use strict";
175
+ ProviderHttpError = class extends Error {
176
+ status;
177
+ constructor(status, message) {
178
+ super(message);
179
+ this.status = status;
180
+ this.name = "ProviderHttpError";
181
+ }
182
+ };
183
+ }
184
+ });
185
+
186
+ // ../providers/dist/minimax.js
187
+ function classifyMinimaxError(error) {
188
+ if (error instanceof ProviderHttpError) {
189
+ if (error.status === 429)
190
+ return "rate-limited";
191
+ if (error.status === 401 || error.status === 403)
192
+ return "auth-failed";
193
+ if (error.status >= 500)
194
+ return "service-unavailable";
195
+ }
196
+ return null;
197
+ }
198
+ function createMinimaxProvider() {
199
+ return createOpenAICompatibleProvider({
200
+ id: "minimax",
201
+ name: "MiniMax",
202
+ baseUrl: "https://api.minimax.chat/v1",
203
+ getApiKey: () => getProviderApiKey("minimax"),
204
+ defaultModel: "abab6.5s-chat",
205
+ classifyError: classifyMinimaxError
206
+ });
207
+ }
208
+ var init_minimax = __esm({
209
+ "../providers/dist/minimax.js"() {
210
+ "use strict";
211
+ init_openai_compatible();
212
+ init_config();
213
+ init_openai_compatible();
214
+ }
215
+ });
216
+
217
+ // ../providers/dist/deepseek.js
218
+ function classifyDeepSeekError(error) {
219
+ if (error instanceof ProviderHttpError) {
220
+ if (error.status === 429)
221
+ return "rate-limited";
222
+ if (error.status === 401 || error.status === 403)
223
+ return "auth-failed";
224
+ if (error.status >= 500)
225
+ return "service-unavailable";
226
+ }
227
+ return null;
228
+ }
229
+ function createDeepSeekProvider() {
230
+ return createOpenAICompatibleProvider({
231
+ id: "deepseek",
232
+ name: "DeepSeek",
233
+ baseUrl: "https://api.deepseek.com",
234
+ getApiKey: () => getProviderApiKey("deepseek"),
235
+ defaultModel: "deepseek-chat",
236
+ classifyError: classifyDeepSeekError
237
+ });
238
+ }
239
+ var init_deepseek = __esm({
240
+ "../providers/dist/deepseek.js"() {
241
+ "use strict";
242
+ init_openai_compatible();
243
+ init_config();
244
+ init_openai_compatible();
245
+ }
246
+ });
247
+
248
+ // ../providers/dist/failover.js
249
+ function sleep(ms) {
250
+ return new Promise((resolve) => setTimeout(resolve, ms));
251
+ }
252
+ async function executeWithFailover(stepName, fn, registry, config) {
253
+ const stepOrder = config.stepProviders[stepName] ?? [];
254
+ const seen = /* @__PURE__ */ new Set();
255
+ const orderedIds = [];
256
+ for (const id of stepOrder) {
257
+ if (!seen.has(id)) {
258
+ seen.add(id);
259
+ orderedIds.push(id);
260
+ }
261
+ }
262
+ for (const id of config.globalFallbackOrder) {
263
+ if (!seen.has(id)) {
264
+ seen.add(id);
265
+ orderedIds.push(id);
266
+ }
267
+ }
268
+ const errors = [];
269
+ for (const id of orderedIds) {
270
+ const provider = registry.get(id);
271
+ if (!provider || !provider.isConfigured())
272
+ continue;
273
+ try {
274
+ return await fn(provider);
275
+ } catch (err) {
276
+ const kind = provider.classifyError(err);
277
+ if (kind === "auth-failed") {
278
+ throw err;
279
+ }
280
+ if (kind === "rate-limited") {
281
+ await sleep(config.rateLimitBackoffMs);
282
+ try {
283
+ return await fn(provider);
284
+ } catch (retryErr) {
285
+ errors.push({ providerId: id, error: retryErr });
286
+ continue;
287
+ }
288
+ }
289
+ errors.push({ providerId: id, error: err });
290
+ }
291
+ }
292
+ throw new AllProvidersFailedError(stepName, errors);
293
+ }
294
+ var AllProvidersFailedError;
295
+ var init_failover = __esm({
296
+ "../providers/dist/failover.js"() {
297
+ "use strict";
298
+ AllProvidersFailedError = class extends Error {
299
+ stepName;
300
+ errors;
301
+ constructor(stepName, errors) {
302
+ super(`All providers failed for step "${stepName}": ${errors.map((e) => e.providerId).join(", ")}`);
303
+ this.stepName = stepName;
304
+ this.errors = errors;
305
+ this.name = "AllProvidersFailedError";
306
+ }
307
+ };
308
+ }
309
+ });
310
+
311
+ // ../providers/dist/minimax-image.js
312
+ function createMinimaxImageProvider() {
313
+ return {
314
+ id: "minimax-image",
315
+ name: "MiniMax Image",
316
+ isConfigured() {
317
+ return Boolean(getProviderApiKey("minimax"));
318
+ },
319
+ async generate(prompt, options) {
320
+ const apiKey = getProviderApiKey("minimax");
321
+ if (apiKey) {
322
+ try {
323
+ const width = options?.width ?? 1024;
324
+ const height = options?.height ?? 1024;
325
+ const response = await fetch("https://api.minimax.chat/v1/image_generation", {
326
+ method: "POST",
327
+ headers: {
328
+ "Content-Type": "application/json",
329
+ Authorization: `Bearer ${apiKey}`
330
+ },
331
+ body: JSON.stringify({
332
+ model: "image-01",
333
+ prompt,
334
+ width,
335
+ height
336
+ }),
337
+ signal: AbortSignal.timeout(6e4)
338
+ });
339
+ if (response.ok) {
340
+ const data = await response.json();
341
+ const imageUrl = data?.data?.url;
342
+ if (imageUrl) {
343
+ const imgResponse = await fetch(imageUrl, {
344
+ signal: AbortSignal.timeout(3e4)
345
+ });
346
+ if (imgResponse.ok) {
347
+ const arrayBuffer = await imgResponse.arrayBuffer();
348
+ const buffer2 = Buffer.from(arrayBuffer);
349
+ return {
350
+ buffer: buffer2,
351
+ mimeType: "image/png",
352
+ width,
353
+ height
354
+ };
355
+ }
356
+ }
357
+ }
358
+ } catch {
359
+ }
360
+ }
361
+ const buffer = Buffer.from(PLACEHOLDER_PNG_BASE64, "base64");
362
+ return {
363
+ buffer,
364
+ mimeType: "image/png",
365
+ width: 1,
366
+ height: 1
367
+ };
368
+ }
369
+ };
370
+ }
371
+ var PLACEHOLDER_PNG_BASE64;
372
+ var init_minimax_image = __esm({
373
+ "../providers/dist/minimax-image.js"() {
374
+ "use strict";
375
+ init_config();
376
+ PLACEHOLDER_PNG_BASE64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
377
+ }
378
+ });
379
+
380
+ // ../providers/dist/index.js
381
+ var dist_exports = {};
382
+ __export(dist_exports, {
383
+ AllProvidersFailedError: () => AllProvidersFailedError,
384
+ ProviderHttpError: () => ProviderHttpError,
385
+ ProviderRegistry: () => ProviderRegistry,
386
+ VERSION: () => VERSION,
387
+ createDeepSeekProvider: () => createDeepSeekProvider,
388
+ createMinimaxImageProvider: () => createMinimaxImageProvider,
389
+ createMinimaxProvider: () => createMinimaxProvider,
390
+ createOpenAICompatibleProvider: () => createOpenAICompatibleProvider,
391
+ executeWithFailover: () => executeWithFailover,
392
+ getProviderApiKey: () => getProviderApiKey,
393
+ loadWxclawConfig: () => loadWxclawConfig
394
+ });
395
+ var VERSION;
396
+ var init_dist = __esm({
397
+ "../providers/dist/index.js"() {
398
+ "use strict";
399
+ init_registry();
400
+ init_config();
401
+ init_openai_compatible();
402
+ init_minimax();
403
+ init_deepseek();
404
+ init_failover();
405
+ init_minimax_image();
406
+ VERSION = "0.1.0";
407
+ }
408
+ });
409
+
410
+ // src/index.ts
411
+ import { Command as Command7 } from "commander";
412
+ import chalk7 from "chalk";
413
+ import { existsSync as existsSync8 } from "fs";
414
+ import { join as join8 } from "path";
415
+ import { homedir as homedir3 } from "os";
416
+
417
+ // src/commands/create.ts
418
+ import { Command } from "commander";
419
+ import chalk from "chalk";
420
+ import ora from "ora";
421
+
422
+ // ../core/dist/logger.js
423
+ var Logger = class {
424
+ name;
425
+ constructor(name) {
426
+ this.name = name;
427
+ }
428
+ debug(message, context) {
429
+ this.log("debug", message, context);
430
+ }
431
+ info(message, context) {
432
+ this.log("info", message, context);
433
+ }
434
+ warn(message, context) {
435
+ this.log("warn", message, context);
436
+ }
437
+ error(message, context) {
438
+ this.log("error", message, context);
439
+ }
440
+ log(level, message, context) {
441
+ const entry = {
442
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
443
+ level,
444
+ message,
445
+ context: { ...context, logger: this.name }
446
+ };
447
+ if (process.env.NODE_ENV === "production") {
448
+ const output = level === "error" ? console.error : console.log;
449
+ output(JSON.stringify(entry));
450
+ } else {
451
+ const prefix = `[${entry.timestamp}] [${level.toUpperCase()}] [${this.name}]`;
452
+ if (level === "error") {
453
+ console.error(prefix, message, context ?? "");
454
+ } else {
455
+ console.log(prefix, message, context ?? "");
456
+ }
457
+ }
458
+ }
459
+ };
460
+ function createLogger(name) {
461
+ return new Logger(name);
462
+ }
463
+
464
+ // ../core/dist/pipeline.js
465
+ var logger = createLogger("pipeline");
466
+ var DEFAULT_OPTIONS = {
467
+ defaultTimeout: 12e4
468
+ // 120s
469
+ };
470
+ var PipelineEngine = class {
471
+ options;
472
+ constructor(options) {
473
+ this.options = { ...DEFAULT_OPTIONS, ...options };
474
+ }
475
+ async run(steps, context) {
476
+ const pipelineStart = Date.now();
477
+ context.status = "running";
478
+ logger.info("Pipeline started", {
479
+ pipelineId: context.pipelineId,
480
+ steps: steps.length
481
+ });
482
+ for (const step of steps) {
483
+ const startedAt = /* @__PURE__ */ new Date();
484
+ if (step.gate === "manual-approval") {
485
+ context.status = "paused";
486
+ const entry2 = {
487
+ stepId: step.id,
488
+ stepType: step.type,
489
+ status: "skipped",
490
+ startedAt,
491
+ duration: 0
492
+ };
493
+ context.logs.push(entry2);
494
+ return context;
495
+ }
496
+ logger.info("Step started", { stepId: step.id, stepType: step.type });
497
+ let result;
498
+ let timedOut = false;
499
+ try {
500
+ result = await Promise.race([
501
+ step.execute(context),
502
+ new Promise((_2, reject) => setTimeout(() => reject(new Error("Step timeout")), this.options.defaultTimeout))
503
+ ]);
504
+ } catch (err) {
505
+ const isTimeout = err instanceof Error && err.message === "Step timeout";
506
+ timedOut = isTimeout;
507
+ const completedAt2 = /* @__PURE__ */ new Date();
508
+ const duration2 = completedAt2.getTime() - startedAt.getTime();
509
+ const entry2 = {
510
+ stepId: step.id,
511
+ stepType: step.type,
512
+ status: isTimeout ? "timeout" : "failed",
513
+ startedAt,
514
+ completedAt: completedAt2,
515
+ duration: duration2,
516
+ error: err instanceof Error ? err.message : String(err)
517
+ };
518
+ context.logs.push(entry2);
519
+ context.status = "failed";
520
+ if (isTimeout) {
521
+ logger.warn("Step timeout", {
522
+ stepId: step.id,
523
+ timeout: this.options.defaultTimeout
524
+ });
525
+ } else {
526
+ logger.error("Step failed", {
527
+ stepId: step.id,
528
+ error: err instanceof Error ? err.message : String(err)
529
+ });
530
+ }
531
+ logger.error("Pipeline failed", {
532
+ pipelineId: context.pipelineId,
533
+ failedStep: step.id
534
+ });
535
+ return context;
536
+ }
537
+ const completedAt = /* @__PURE__ */ new Date();
538
+ const duration = completedAt.getTime() - startedAt.getTime();
539
+ const entry = {
540
+ stepId: step.id,
541
+ stepType: step.type,
542
+ status: result.success ? "success" : "failed",
543
+ startedAt,
544
+ completedAt,
545
+ duration,
546
+ error: result.error
547
+ };
548
+ context.logs.push(entry);
549
+ if (!result.success && !timedOut) {
550
+ logger.error("Step failed", {
551
+ stepId: step.id,
552
+ error: result.error
553
+ });
554
+ logger.error("Pipeline failed", {
555
+ pipelineId: context.pipelineId,
556
+ failedStep: step.id
557
+ });
558
+ context.status = "failed";
559
+ return context;
560
+ }
561
+ logger.info("Step completed", { stepId: step.id, duration });
562
+ }
563
+ const totalDuration = Date.now() - pipelineStart;
564
+ context.status = "completed";
565
+ logger.info("Pipeline completed", {
566
+ pipelineId: context.pipelineId,
567
+ totalDuration
568
+ });
569
+ return context;
570
+ }
571
+ };
572
+
573
+ // ../core/dist/steps/topic-selection.js
574
+ var TopicSelectionStep = class {
575
+ id;
576
+ type = "topic-discovery";
577
+ gate = "auto";
578
+ llm;
579
+ constructor(llm, id = "topic-selection") {
580
+ this.llm = llm;
581
+ this.id = id;
582
+ }
583
+ async execute(context) {
584
+ const start = Date.now();
585
+ try {
586
+ const existingTopic = context.data.topic?.title;
587
+ const prompt = existingTopic ? `\u6839\u636E\u4EE5\u4E0B\u4E3B\u9898\u751F\u6210\u4E00\u4E2A\u516C\u4F17\u53F7\u6587\u7AE0\u9009\u9898\u89D2\u5EA6\uFF1A${existingTopic}` : "\u4E3A\u516C\u4F17\u53F7\u751F\u6210\u4E00\u4E2A\u6709\u5438\u5F15\u529B\u7684\u6587\u7AE0\u9009\u9898\uFF0C\u5305\u542B\u4E3B\u9898\u3001\u89D2\u5EA6\u548C\u5173\u952E\u8BCD";
588
+ const systemPrompt = [
589
+ context.config.soulPrompt,
590
+ context.config.agentsRules
591
+ ].filter(Boolean).join("\n\n---\n\n");
592
+ const response = await this.llm.chat({
593
+ messages: [
594
+ { role: "system", content: systemPrompt },
595
+ { role: "user", content: prompt }
596
+ ],
597
+ temperature: 0.7
598
+ });
599
+ const content = response.content;
600
+ let title = existingTopic ?? "";
601
+ let angle = "";
602
+ const keywords = [];
603
+ const jsonMatch = content.match(/```json\s*([\s\S]*?)\s*```/) ?? content.match(/\{[\s\S]*\}/);
604
+ if (jsonMatch) {
605
+ try {
606
+ const parsed = JSON.parse(jsonMatch[1] ?? jsonMatch[0]);
607
+ title = parsed.title ?? title;
608
+ angle = parsed.angle ?? angle;
609
+ if (Array.isArray(parsed.keywords)) {
610
+ keywords.push(...parsed.keywords);
611
+ }
612
+ } catch {
613
+ }
614
+ }
615
+ if (!angle) {
616
+ angle = content.trim();
617
+ }
618
+ if (!title) {
619
+ title = "\u5F85\u786E\u5B9A\u4E3B\u9898";
620
+ }
621
+ context.data.topic = { title, angle, keywords };
622
+ return {
623
+ success: true,
624
+ data: context.data.topic,
625
+ duration: Date.now() - start
626
+ };
627
+ } catch (err) {
628
+ return {
629
+ success: false,
630
+ error: err instanceof Error ? err.message : String(err),
631
+ duration: Date.now() - start
632
+ };
633
+ }
634
+ }
635
+ };
636
+
637
+ // ../core/dist/steps/outline.js
638
+ var OutlineStep = class {
639
+ id;
640
+ type = "outline";
641
+ gate = "auto";
642
+ llm;
643
+ constructor(llm, id = "outline") {
644
+ this.llm = llm;
645
+ this.id = id;
646
+ }
647
+ async execute(context) {
648
+ const start = Date.now();
649
+ try {
650
+ const topic = context.data.topic;
651
+ if (!topic) {
652
+ return {
653
+ success: false,
654
+ error: "\u7F3A\u5C11\u9009\u9898\u6570\u636E\uFF0C\u8BF7\u5148\u6267\u884C topic-discovery \u6B65\u9AA4",
655
+ duration: Date.now() - start
656
+ };
657
+ }
658
+ const topicDescription = [
659
+ `\u4E3B\u9898\uFF1A${topic.title}`,
660
+ topic.angle ? `\u89D2\u5EA6\uFF1A${topic.angle}` : null,
661
+ topic.keywords.length > 0 ? `\u5173\u952E\u8BCD\uFF1A${topic.keywords.join("\u3001")}` : null
662
+ ].filter(Boolean).join("\n");
663
+ const prompt = `\u4E3A\u4EE5\u4E0B\u4E3B\u9898\u751F\u6210\u516C\u4F17\u53F7\u6587\u7AE0\u5927\u7EB2\uFF0C\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA\uFF1A
664
+
665
+ ${topicDescription}
666
+
667
+ \u8BF7\u4E25\u683C\u6309\u7167\u4EE5\u4E0B JSON \u683C\u5F0F\u8F93\u51FA\uFF0C\u4E0D\u8981\u5305\u542B\u5176\u4ED6\u5185\u5BB9\uFF1A
668
+ {
669
+ "title": "\u6587\u7AE0\u6807\u9898",
670
+ "sections": [
671
+ {
672
+ "heading": "\u5C0F\u8282\u6807\u9898",
673
+ "points": ["\u8981\u70B91", "\u8981\u70B92"]
674
+ }
675
+ ]
676
+ }`;
677
+ const systemPrompt = [
678
+ context.config.soulPrompt,
679
+ context.config.agentsRules
680
+ ].filter(Boolean).join("\n\n---\n\n");
681
+ const response = await this.llm.chat({
682
+ messages: [
683
+ { role: "system", content: systemPrompt },
684
+ { role: "user", content: prompt }
685
+ ],
686
+ temperature: 0.5
687
+ });
688
+ const content = response.content;
689
+ let parsed = {};
690
+ const jsonMatch = content.match(/```json\s*([\s\S]*?)\s*```/) ?? content.match(/```\s*([\s\S]*?)\s*```/);
691
+ try {
692
+ if (jsonMatch?.[1]) {
693
+ parsed = JSON.parse(jsonMatch[1]);
694
+ } else {
695
+ const jsonStart = content.indexOf("{");
696
+ const jsonEnd = content.lastIndexOf("}");
697
+ if (jsonStart !== -1 && jsonEnd !== -1) {
698
+ parsed = JSON.parse(content.slice(jsonStart, jsonEnd + 1));
699
+ }
700
+ }
701
+ } catch {
702
+ parsed = {
703
+ title: topic.title,
704
+ sections: [
705
+ {
706
+ heading: "\u4E3B\u4F53\u5185\u5BB9",
707
+ points: [content.trim()]
708
+ }
709
+ ]
710
+ };
711
+ }
712
+ const outline = {
713
+ title: parsed.title ?? topic.title,
714
+ sections: (parsed.sections ?? []).map((s) => ({
715
+ heading: s.heading ?? "",
716
+ points: Array.isArray(s.points) ? s.points : []
717
+ }))
718
+ };
719
+ if (outline.sections.length === 0) {
720
+ outline.sections = [
721
+ { heading: "\u4E3B\u4F53\u5185\u5BB9", points: ["\u5F85\u8865\u5145"] }
722
+ ];
723
+ }
724
+ context.data.outline = outline;
725
+ return {
726
+ success: true,
727
+ data: outline,
728
+ duration: Date.now() - start
729
+ };
730
+ } catch (err) {
731
+ return {
732
+ success: false,
733
+ error: err instanceof Error ? err.message : String(err),
734
+ duration: Date.now() - start
735
+ };
736
+ }
737
+ }
738
+ };
739
+
740
+ // ../core/dist/steps/writing.js
741
+ var WritingStep = class {
742
+ id;
743
+ type = "writing";
744
+ gate = "auto";
745
+ llm;
746
+ constructor(llm, id = "writing") {
747
+ this.llm = llm;
748
+ this.id = id;
749
+ }
750
+ async execute(context) {
751
+ const start = Date.now();
752
+ try {
753
+ const outline = context.data.outline;
754
+ if (!outline) {
755
+ return {
756
+ success: false,
757
+ error: "\u7F3A\u5C11\u5927\u7EB2\u6570\u636E\uFF0C\u8BF7\u5148\u6267\u884C outline \u6B65\u9AA4",
758
+ duration: Date.now() - start
759
+ };
760
+ }
761
+ const outlineText = [
762
+ `\u6807\u9898\uFF1A${outline.title}`,
763
+ "",
764
+ ...outline.sections.map((section) => [
765
+ `## ${section.heading}`,
766
+ ...section.points.map((p) => `- ${p}`)
767
+ ].join("\n"))
768
+ ].join("\n");
769
+ const prompt = `\u6839\u636E\u4EE5\u4E0B\u5927\u7EB2\u64B0\u5199\u4E00\u7BC7\u516C\u4F17\u53F7\u6587\u7AE0\uFF0C\u4F7F\u7528 Markdown \u683C\u5F0F\uFF1A
770
+
771
+ ${outlineText}`;
772
+ const systemPrompt = [
773
+ context.config.soulPrompt,
774
+ context.config.agentsRules,
775
+ context.config.stylePrompt
776
+ ].filter(Boolean).join("\n\n---\n\n");
777
+ const response = await this.llm.chat({
778
+ messages: [
779
+ { role: "system", content: systemPrompt },
780
+ { role: "user", content: prompt }
781
+ ],
782
+ temperature: 0.7,
783
+ maxTokens: 4e3
784
+ });
785
+ const content = response.content.trim();
786
+ const chineseChars = (content.match(/[\u4e00-\u9fa5]/g) ?? []).length;
787
+ const englishWords = (content.match(/[a-zA-Z]+/g) ?? []).length;
788
+ const wordCount = chineseChars + englishWords;
789
+ const titleMatch = content.match(/^#\s+(.+)$/m);
790
+ const title = titleMatch?.[1]?.trim() ?? outline.title;
791
+ context.data.article = {
792
+ title,
793
+ content,
794
+ wordCount
795
+ };
796
+ return {
797
+ success: true,
798
+ data: context.data.article,
799
+ duration: Date.now() - start
800
+ };
801
+ } catch (err) {
802
+ return {
803
+ success: false,
804
+ error: err instanceof Error ? err.message : String(err),
805
+ duration: Date.now() - start
806
+ };
807
+ }
808
+ }
809
+ };
810
+
811
+ // ../../node_modules/.pnpm/marked@17.0.6/node_modules/marked/lib/marked.esm.js
812
+ function M() {
813
+ return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
814
+ }
815
+ var O = M();
816
+ function G(u3) {
817
+ O = u3;
818
+ }
819
+ var _ = { exec: () => null };
820
+ function k(u3, e = "") {
821
+ let t = typeof u3 == "string" ? u3 : u3.source, n = { replace: (r, i) => {
822
+ let s = typeof i == "string" ? i : i.source;
823
+ return s = s.replace(m.caret, "$1"), t = t.replace(r, s), n;
824
+ }, getRegex: () => new RegExp(t, e) };
825
+ return n;
826
+ }
827
+ var be = (() => {
828
+ try {
829
+ return !!new RegExp("(?<=1)(?<!1)");
830
+ } catch {
831
+ return false;
832
+ }
833
+ })();
834
+ var m = { codeRemoveIndent: /^(?: {1,4}| {0,3}\t)/gm, outputLinkReplace: /\\([\[\]])/g, indentCodeCompensation: /^(\s+)(?:```)/, beginningSpace: /^\s+/, endingHash: /#$/, startingSpaceChar: /^ /, endingSpaceChar: / $/, nonSpaceChar: /[^ ]/, newLineCharGlobal: /\n/g, tabCharGlobal: /\t/g, multipleSpaceGlobal: /\s+/g, blankLine: /^[ \t]*$/, doubleBlankLine: /\n[ \t]*\n[ \t]*$/, blockquoteStart: /^ {0,3}>/, blockquoteSetextReplace: /\n {0,3}((?:=+|-+) *)(?=\n|$)/g, blockquoteSetextReplace2: /^ {0,3}>[ \t]?/gm, listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g, listIsTask: /^\[[ xX]\] +\S/, listReplaceTask: /^\[[ xX]\] +/, listTaskCheckbox: /\[[ xX]\]/, anyLine: /\n.*\n/, hrefBrackets: /^<(.*)>$/, tableDelimiter: /[:|]/, tableAlignChars: /^\||\| *$/g, tableRowBlankLine: /\n[ \t]*$/, tableAlignRight: /^ *-+: *$/, tableAlignCenter: /^ *:-+: *$/, tableAlignLeft: /^ *:-+ *$/, startATag: /^<a /i, endATag: /^<\/a>/i, startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i, endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i, startAngleBracket: /^</, endAngleBracket: />$/, pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/, unicodeAlphaNumeric: /[\p{L}\p{N}]/u, escapeTest: /[&<>"']/, escapeReplace: /[&<>"']/g, escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g, caret: /(^|[^\[])\^/g, percentDecode: /%25/g, findPipe: /\|/g, splitPipe: / \|/, slashPipe: /\\\|/g, carriageReturn: /\r\n|\r/g, spaceLine: /^ +$/gm, notSpaceStart: /^\S*/, endingNewline: /\n$/, listItemRegex: (u3) => new RegExp(`^( {0,3}${u3})((?:[ ][^\\n]*)?(?:\\n|$))`), nextBulletRegex: (u3) => new RegExp(`^ {0,${Math.min(3, u3 - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`), hrRegex: (u3) => new RegExp(`^ {0,${Math.min(3, u3 - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`), fencesBeginRegex: (u3) => new RegExp(`^ {0,${Math.min(3, u3 - 1)}}(?:\`\`\`|~~~)`), headingBeginRegex: (u3) => new RegExp(`^ {0,${Math.min(3, u3 - 1)}}#`), htmlBeginRegex: (u3) => new RegExp(`^ {0,${Math.min(3, u3 - 1)}}<(?:[a-z].*>|!--)`, "i"), blockquoteBeginRegex: (u3) => new RegExp(`^ {0,${Math.min(3, u3 - 1)}}>`) };
835
+ var Re = /^(?:[ \t]*(?:\n|$))+/;
836
+ var Oe = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
837
+ var Te = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
838
+ var C = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
839
+ var we = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
840
+ var Q = / {0,3}(?:[*+-]|\d{1,9}[.)])/;
841
+ var se = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/;
842
+ var ie = k(se).replace(/bull/g, Q).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/\|table/g, "").getRegex();
843
+ var ye = k(se).replace(/bull/g, Q).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/table/g, / {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex();
844
+ var j = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
845
+ var Pe = /^[^\n]+/;
846
+ var F = /(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/;
847
+ var Se = k(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", F).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex();
848
+ var $e = k(/^(bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g, Q).getRegex();
849
+ var v = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul";
850
+ var U = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
851
+ var _e = k("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))", "i").replace("comment", U).replace("tag", v).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
852
+ var oe = k(j).replace("hr", C).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex();
853
+ var Le = k(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", oe).getRegex();
854
+ var K = { blockquote: Le, code: Oe, def: Se, fences: Te, heading: we, hr: C, html: _e, lheading: ie, list: $e, newline: Re, paragraph: oe, table: _, text: Pe };
855
+ var ne = k("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", C).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex();
856
+ var Me = { ...K, lheading: ye, table: ne, paragraph: k(j).replace("hr", C).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", ne).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex() };
857
+ var ze = { ...K, html: k(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", U).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, heading: /^(#{1,6})(.*)(?:\n+|$)/, fences: _, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: k(j).replace("hr", C).replace("heading", ` *#{1,6} *[^
858
+ ]`).replace("lheading", ie).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex() };
859
+ var Ee = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
860
+ var Ie = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
861
+ var ae = /^( {2,}|\\)\n(?!\s*$)/;
862
+ var Ae = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
863
+ var z = /[\p{P}\p{S}]/u;
864
+ var H = /[\s\p{P}\p{S}]/u;
865
+ var W = /[^\s\p{P}\p{S}]/u;
866
+ var Ce = k(/^((?![*_])punctSpace)/, "u").replace(/punctSpace/g, H).getRegex();
867
+ var le = /(?!~)[\p{P}\p{S}]/u;
868
+ var Be = /(?!~)[\s\p{P}\p{S}]/u;
869
+ var De = /(?:[^\s\p{P}\p{S}]|~)/u;
870
+ var qe = k(/link|precode-code|html/, "g").replace("link", /\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-", be ? "(?<!`)()" : "(^^|[^`])").replace("code", /(?<b>`+)[^`]+\k<b>(?!`)/).replace("html", /<(?! )[^<>]*?>/).getRegex();
871
+ var ue = /^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/;
872
+ var ve = k(ue, "u").replace(/punct/g, z).getRegex();
873
+ var He = k(ue, "u").replace(/punct/g, le).getRegex();
874
+ var pe = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)";
875
+ var Ze = k(pe, "gu").replace(/notPunctSpace/g, W).replace(/punctSpace/g, H).replace(/punct/g, z).getRegex();
876
+ var Ge = k(pe, "gu").replace(/notPunctSpace/g, De).replace(/punctSpace/g, Be).replace(/punct/g, le).getRegex();
877
+ var Ne = k("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)", "gu").replace(/notPunctSpace/g, W).replace(/punctSpace/g, H).replace(/punct/g, z).getRegex();
878
+ var Qe = k(/^~~?(?:((?!~)punct)|[^\s~])/, "u").replace(/punct/g, z).getRegex();
879
+ var je = "^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)";
880
+ var Fe = k(je, "gu").replace(/notPunctSpace/g, W).replace(/punctSpace/g, H).replace(/punct/g, z).getRegex();
881
+ var Ue = k(/\\(punct)/, "gu").replace(/punct/g, z).getRegex();
882
+ var Ke = k(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex();
883
+ var We = k(U).replace("(?:-->|$)", "-->").getRegex();
884
+ var Xe = k("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment", We).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex();
885
+ var q = /(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/;
886
+ var Je = k(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace("label", q).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex();
887
+ var ce = k(/^!?\[(label)\]\[(ref)\]/).replace("label", q).replace("ref", F).getRegex();
888
+ var he = k(/^!?\[(ref)\](?:\[\])?/).replace("ref", F).getRegex();
889
+ var Ve = k("reflink|nolink(?!\\()", "g").replace("reflink", ce).replace("nolink", he).getRegex();
890
+ var re = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/;
891
+ var X = { _backpedal: _, anyPunctuation: Ue, autolink: Ke, blockSkip: qe, br: ae, code: Ie, del: _, delLDelim: _, delRDelim: _, emStrongLDelim: ve, emStrongRDelimAst: Ze, emStrongRDelimUnd: Ne, escape: Ee, link: Je, nolink: he, punctuation: Ce, reflink: ce, reflinkSearch: Ve, tag: Xe, text: Ae, url: _ };
892
+ var Ye = { ...X, link: k(/^!?\[(label)\]\((.*?)\)/).replace("label", q).getRegex(), reflink: k(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", q).getRegex() };
893
+ var N = { ...X, emStrongRDelimAst: Ge, emStrongLDelim: He, delLDelim: Qe, delRDelim: Fe, url: k(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol", re).replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(), _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, del: /^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/, text: k(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace("protocol", re).getRegex() };
894
+ var et = { ...N, br: k(ae).replace("{2,}", "*").getRegex(), text: k(N.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex() };
895
+ var B = { normal: K, gfm: Me, pedantic: ze };
896
+ var E = { normal: X, gfm: N, breaks: et, pedantic: Ye };
897
+ var tt = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" };
898
+ var ke = (u3) => tt[u3];
899
+ function T(u3, e) {
900
+ if (e) {
901
+ if (m.escapeTest.test(u3)) return u3.replace(m.escapeReplace, ke);
902
+ } else if (m.escapeTestNoEncode.test(u3)) return u3.replace(m.escapeReplaceNoEncode, ke);
903
+ return u3;
904
+ }
905
+ function J(u3) {
906
+ try {
907
+ u3 = encodeURI(u3).replace(m.percentDecode, "%");
908
+ } catch {
909
+ return null;
910
+ }
911
+ return u3;
912
+ }
913
+ function V(u3, e) {
914
+ let t = u3.replace(m.findPipe, (i, s, a) => {
915
+ let o = false, l = s;
916
+ for (; --l >= 0 && a[l] === "\\"; ) o = !o;
917
+ return o ? "|" : " |";
918
+ }), n = t.split(m.splitPipe), r = 0;
919
+ if (n[0].trim() || n.shift(), n.length > 0 && !n.at(-1)?.trim() && n.pop(), e) if (n.length > e) n.splice(e);
920
+ else for (; n.length < e; ) n.push("");
921
+ for (; r < n.length; r++) n[r] = n[r].trim().replace(m.slashPipe, "|");
922
+ return n;
923
+ }
924
+ function I(u3, e, t) {
925
+ let n = u3.length;
926
+ if (n === 0) return "";
927
+ let r = 0;
928
+ for (; r < n; ) {
929
+ let i = u3.charAt(n - r - 1);
930
+ if (i === e && !t) r++;
931
+ else if (i !== e && t) r++;
932
+ else break;
933
+ }
934
+ return u3.slice(0, n - r);
935
+ }
936
+ function de(u3, e) {
937
+ if (u3.indexOf(e[1]) === -1) return -1;
938
+ let t = 0;
939
+ for (let n = 0; n < u3.length; n++) if (u3[n] === "\\") n++;
940
+ else if (u3[n] === e[0]) t++;
941
+ else if (u3[n] === e[1] && (t--, t < 0)) return n;
942
+ return t > 0 ? -2 : -1;
943
+ }
944
+ function ge(u3, e = 0) {
945
+ let t = e, n = "";
946
+ for (let r of u3) if (r === " ") {
947
+ let i = 4 - t % 4;
948
+ n += " ".repeat(i), t += i;
949
+ } else n += r, t++;
950
+ return n;
951
+ }
952
+ function fe(u3, e, t, n, r) {
953
+ let i = e.href, s = e.title || null, a = u3[1].replace(r.other.outputLinkReplace, "$1");
954
+ n.state.inLink = true;
955
+ let o = { type: u3[0].charAt(0) === "!" ? "image" : "link", raw: t, href: i, title: s, text: a, tokens: n.inlineTokens(a) };
956
+ return n.state.inLink = false, o;
957
+ }
958
+ function nt(u3, e, t) {
959
+ let n = u3.match(t.other.indentCodeCompensation);
960
+ if (n === null) return e;
961
+ let r = n[1];
962
+ return e.split(`
963
+ `).map((i) => {
964
+ let s = i.match(t.other.beginningSpace);
965
+ if (s === null) return i;
966
+ let [a] = s;
967
+ return a.length >= r.length ? i.slice(r.length) : i;
968
+ }).join(`
969
+ `);
970
+ }
971
+ var w = class {
972
+ options;
973
+ rules;
974
+ lexer;
975
+ constructor(e) {
976
+ this.options = e || O;
977
+ }
978
+ space(e) {
979
+ let t = this.rules.block.newline.exec(e);
980
+ if (t && t[0].length > 0) return { type: "space", raw: t[0] };
981
+ }
982
+ code(e) {
983
+ let t = this.rules.block.code.exec(e);
984
+ if (t) {
985
+ let n = t[0].replace(this.rules.other.codeRemoveIndent, "");
986
+ return { type: "code", raw: t[0], codeBlockStyle: "indented", text: this.options.pedantic ? n : I(n, `
987
+ `) };
988
+ }
989
+ }
990
+ fences(e) {
991
+ let t = this.rules.block.fences.exec(e);
992
+ if (t) {
993
+ let n = t[0], r = nt(n, t[3] || "", this.rules);
994
+ return { type: "code", raw: n, lang: t[2] ? t[2].trim().replace(this.rules.inline.anyPunctuation, "$1") : t[2], text: r };
995
+ }
996
+ }
997
+ heading(e) {
998
+ let t = this.rules.block.heading.exec(e);
999
+ if (t) {
1000
+ let n = t[2].trim();
1001
+ if (this.rules.other.endingHash.test(n)) {
1002
+ let r = I(n, "#");
1003
+ (this.options.pedantic || !r || this.rules.other.endingSpaceChar.test(r)) && (n = r.trim());
1004
+ }
1005
+ return { type: "heading", raw: t[0], depth: t[1].length, text: n, tokens: this.lexer.inline(n) };
1006
+ }
1007
+ }
1008
+ hr(e) {
1009
+ let t = this.rules.block.hr.exec(e);
1010
+ if (t) return { type: "hr", raw: I(t[0], `
1011
+ `) };
1012
+ }
1013
+ blockquote(e) {
1014
+ let t = this.rules.block.blockquote.exec(e);
1015
+ if (t) {
1016
+ let n = I(t[0], `
1017
+ `).split(`
1018
+ `), r = "", i = "", s = [];
1019
+ for (; n.length > 0; ) {
1020
+ let a = false, o = [], l;
1021
+ for (l = 0; l < n.length; l++) if (this.rules.other.blockquoteStart.test(n[l])) o.push(n[l]), a = true;
1022
+ else if (!a) o.push(n[l]);
1023
+ else break;
1024
+ n = n.slice(l);
1025
+ let p = o.join(`
1026
+ `), c = p.replace(this.rules.other.blockquoteSetextReplace, `
1027
+ $1`).replace(this.rules.other.blockquoteSetextReplace2, "");
1028
+ r = r ? `${r}
1029
+ ${p}` : p, i = i ? `${i}
1030
+ ${c}` : c;
1031
+ let d = this.lexer.state.top;
1032
+ if (this.lexer.state.top = true, this.lexer.blockTokens(c, s, true), this.lexer.state.top = d, n.length === 0) break;
1033
+ let h = s.at(-1);
1034
+ if (h?.type === "code") break;
1035
+ if (h?.type === "blockquote") {
1036
+ let R = h, f = R.raw + `
1037
+ ` + n.join(`
1038
+ `), S = this.blockquote(f);
1039
+ s[s.length - 1] = S, r = r.substring(0, r.length - R.raw.length) + S.raw, i = i.substring(0, i.length - R.text.length) + S.text;
1040
+ break;
1041
+ } else if (h?.type === "list") {
1042
+ let R = h, f = R.raw + `
1043
+ ` + n.join(`
1044
+ `), S = this.list(f);
1045
+ s[s.length - 1] = S, r = r.substring(0, r.length - h.raw.length) + S.raw, i = i.substring(0, i.length - R.raw.length) + S.raw, n = f.substring(s.at(-1).raw.length).split(`
1046
+ `);
1047
+ continue;
1048
+ }
1049
+ }
1050
+ return { type: "blockquote", raw: r, tokens: s, text: i };
1051
+ }
1052
+ }
1053
+ list(e) {
1054
+ let t = this.rules.block.list.exec(e);
1055
+ if (t) {
1056
+ let n = t[1].trim(), r = n.length > 1, i = { type: "list", raw: "", ordered: r, start: r ? +n.slice(0, -1) : "", loose: false, items: [] };
1057
+ n = r ? `\\d{1,9}\\${n.slice(-1)}` : `\\${n}`, this.options.pedantic && (n = r ? n : "[*+-]");
1058
+ let s = this.rules.other.listItemRegex(n), a = false;
1059
+ for (; e; ) {
1060
+ let l = false, p = "", c = "";
1061
+ if (!(t = s.exec(e)) || this.rules.block.hr.test(e)) break;
1062
+ p = t[0], e = e.substring(p.length);
1063
+ let d = ge(t[2].split(`
1064
+ `, 1)[0], t[1].length), h = e.split(`
1065
+ `, 1)[0], R = !d.trim(), f = 0;
1066
+ if (this.options.pedantic ? (f = 2, c = d.trimStart()) : R ? f = t[1].length + 1 : (f = d.search(this.rules.other.nonSpaceChar), f = f > 4 ? 1 : f, c = d.slice(f), f += t[1].length), R && this.rules.other.blankLine.test(h) && (p += h + `
1067
+ `, e = e.substring(h.length + 1), l = true), !l) {
1068
+ let S = this.rules.other.nextBulletRegex(f), Y = this.rules.other.hrRegex(f), ee = this.rules.other.fencesBeginRegex(f), te = this.rules.other.headingBeginRegex(f), me = this.rules.other.htmlBeginRegex(f), xe = this.rules.other.blockquoteBeginRegex(f);
1069
+ for (; e; ) {
1070
+ let Z = e.split(`
1071
+ `, 1)[0], A;
1072
+ if (h = Z, this.options.pedantic ? (h = h.replace(this.rules.other.listReplaceNesting, " "), A = h) : A = h.replace(this.rules.other.tabCharGlobal, " "), ee.test(h) || te.test(h) || me.test(h) || xe.test(h) || S.test(h) || Y.test(h)) break;
1073
+ if (A.search(this.rules.other.nonSpaceChar) >= f || !h.trim()) c += `
1074
+ ` + A.slice(f);
1075
+ else {
1076
+ if (R || d.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || ee.test(d) || te.test(d) || Y.test(d)) break;
1077
+ c += `
1078
+ ` + h;
1079
+ }
1080
+ R = !h.trim(), p += Z + `
1081
+ `, e = e.substring(Z.length + 1), d = A.slice(f);
1082
+ }
1083
+ }
1084
+ i.loose || (a ? i.loose = true : this.rules.other.doubleBlankLine.test(p) && (a = true)), i.items.push({ type: "list_item", raw: p, task: !!this.options.gfm && this.rules.other.listIsTask.test(c), loose: false, text: c, tokens: [] }), i.raw += p;
1085
+ }
1086
+ let o = i.items.at(-1);
1087
+ if (o) o.raw = o.raw.trimEnd(), o.text = o.text.trimEnd();
1088
+ else return;
1089
+ i.raw = i.raw.trimEnd();
1090
+ for (let l of i.items) {
1091
+ if (this.lexer.state.top = false, l.tokens = this.lexer.blockTokens(l.text, []), l.task) {
1092
+ if (l.text = l.text.replace(this.rules.other.listReplaceTask, ""), l.tokens[0]?.type === "text" || l.tokens[0]?.type === "paragraph") {
1093
+ l.tokens[0].raw = l.tokens[0].raw.replace(this.rules.other.listReplaceTask, ""), l.tokens[0].text = l.tokens[0].text.replace(this.rules.other.listReplaceTask, "");
1094
+ for (let c = this.lexer.inlineQueue.length - 1; c >= 0; c--) if (this.rules.other.listIsTask.test(this.lexer.inlineQueue[c].src)) {
1095
+ this.lexer.inlineQueue[c].src = this.lexer.inlineQueue[c].src.replace(this.rules.other.listReplaceTask, "");
1096
+ break;
1097
+ }
1098
+ }
1099
+ let p = this.rules.other.listTaskCheckbox.exec(l.raw);
1100
+ if (p) {
1101
+ let c = { type: "checkbox", raw: p[0] + " ", checked: p[0] !== "[ ]" };
1102
+ l.checked = c.checked, i.loose ? l.tokens[0] && ["paragraph", "text"].includes(l.tokens[0].type) && "tokens" in l.tokens[0] && l.tokens[0].tokens ? (l.tokens[0].raw = c.raw + l.tokens[0].raw, l.tokens[0].text = c.raw + l.tokens[0].text, l.tokens[0].tokens.unshift(c)) : l.tokens.unshift({ type: "paragraph", raw: c.raw, text: c.raw, tokens: [c] }) : l.tokens.unshift(c);
1103
+ }
1104
+ }
1105
+ if (!i.loose) {
1106
+ let p = l.tokens.filter((d) => d.type === "space"), c = p.length > 0 && p.some((d) => this.rules.other.anyLine.test(d.raw));
1107
+ i.loose = c;
1108
+ }
1109
+ }
1110
+ if (i.loose) for (let l of i.items) {
1111
+ l.loose = true;
1112
+ for (let p of l.tokens) p.type === "text" && (p.type = "paragraph");
1113
+ }
1114
+ return i;
1115
+ }
1116
+ }
1117
+ html(e) {
1118
+ let t = this.rules.block.html.exec(e);
1119
+ if (t) return { type: "html", block: true, raw: t[0], pre: t[1] === "pre" || t[1] === "script" || t[1] === "style", text: t[0] };
1120
+ }
1121
+ def(e) {
1122
+ let t = this.rules.block.def.exec(e);
1123
+ if (t) {
1124
+ let n = t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, " "), r = t[2] ? t[2].replace(this.rules.other.hrefBrackets, "$1").replace(this.rules.inline.anyPunctuation, "$1") : "", i = t[3] ? t[3].substring(1, t[3].length - 1).replace(this.rules.inline.anyPunctuation, "$1") : t[3];
1125
+ return { type: "def", tag: n, raw: t[0], href: r, title: i };
1126
+ }
1127
+ }
1128
+ table(e) {
1129
+ let t = this.rules.block.table.exec(e);
1130
+ if (!t || !this.rules.other.tableDelimiter.test(t[2])) return;
1131
+ let n = V(t[1]), r = t[2].replace(this.rules.other.tableAlignChars, "").split("|"), i = t[3]?.trim() ? t[3].replace(this.rules.other.tableRowBlankLine, "").split(`
1132
+ `) : [], s = { type: "table", raw: t[0], header: [], align: [], rows: [] };
1133
+ if (n.length === r.length) {
1134
+ for (let a of r) this.rules.other.tableAlignRight.test(a) ? s.align.push("right") : this.rules.other.tableAlignCenter.test(a) ? s.align.push("center") : this.rules.other.tableAlignLeft.test(a) ? s.align.push("left") : s.align.push(null);
1135
+ for (let a = 0; a < n.length; a++) s.header.push({ text: n[a], tokens: this.lexer.inline(n[a]), header: true, align: s.align[a] });
1136
+ for (let a of i) s.rows.push(V(a, s.header.length).map((o, l) => ({ text: o, tokens: this.lexer.inline(o), header: false, align: s.align[l] })));
1137
+ return s;
1138
+ }
1139
+ }
1140
+ lheading(e) {
1141
+ let t = this.rules.block.lheading.exec(e);
1142
+ if (t) {
1143
+ let n = t[1].trim();
1144
+ return { type: "heading", raw: t[0], depth: t[2].charAt(0) === "=" ? 1 : 2, text: n, tokens: this.lexer.inline(n) };
1145
+ }
1146
+ }
1147
+ paragraph(e) {
1148
+ let t = this.rules.block.paragraph.exec(e);
1149
+ if (t) {
1150
+ let n = t[1].charAt(t[1].length - 1) === `
1151
+ ` ? t[1].slice(0, -1) : t[1];
1152
+ return { type: "paragraph", raw: t[0], text: n, tokens: this.lexer.inline(n) };
1153
+ }
1154
+ }
1155
+ text(e) {
1156
+ let t = this.rules.block.text.exec(e);
1157
+ if (t) return { type: "text", raw: t[0], text: t[0], tokens: this.lexer.inline(t[0]) };
1158
+ }
1159
+ escape(e) {
1160
+ let t = this.rules.inline.escape.exec(e);
1161
+ if (t) return { type: "escape", raw: t[0], text: t[1] };
1162
+ }
1163
+ tag(e) {
1164
+ let t = this.rules.inline.tag.exec(e);
1165
+ if (t) return !this.lexer.state.inLink && this.rules.other.startATag.test(t[0]) ? this.lexer.state.inLink = true : this.lexer.state.inLink && this.rules.other.endATag.test(t[0]) && (this.lexer.state.inLink = false), !this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(t[0]) ? this.lexer.state.inRawBlock = true : this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(t[0]) && (this.lexer.state.inRawBlock = false), { type: "html", raw: t[0], inLink: this.lexer.state.inLink, inRawBlock: this.lexer.state.inRawBlock, block: false, text: t[0] };
1166
+ }
1167
+ link(e) {
1168
+ let t = this.rules.inline.link.exec(e);
1169
+ if (t) {
1170
+ let n = t[2].trim();
1171
+ if (!this.options.pedantic && this.rules.other.startAngleBracket.test(n)) {
1172
+ if (!this.rules.other.endAngleBracket.test(n)) return;
1173
+ let s = I(n.slice(0, -1), "\\");
1174
+ if ((n.length - s.length) % 2 === 0) return;
1175
+ } else {
1176
+ let s = de(t[2], "()");
1177
+ if (s === -2) return;
1178
+ if (s > -1) {
1179
+ let o = (t[0].indexOf("!") === 0 ? 5 : 4) + t[1].length + s;
1180
+ t[2] = t[2].substring(0, s), t[0] = t[0].substring(0, o).trim(), t[3] = "";
1181
+ }
1182
+ }
1183
+ let r = t[2], i = "";
1184
+ if (this.options.pedantic) {
1185
+ let s = this.rules.other.pedanticHrefTitle.exec(r);
1186
+ s && (r = s[1], i = s[3]);
1187
+ } else i = t[3] ? t[3].slice(1, -1) : "";
1188
+ return r = r.trim(), this.rules.other.startAngleBracket.test(r) && (this.options.pedantic && !this.rules.other.endAngleBracket.test(n) ? r = r.slice(1) : r = r.slice(1, -1)), fe(t, { href: r && r.replace(this.rules.inline.anyPunctuation, "$1"), title: i && i.replace(this.rules.inline.anyPunctuation, "$1") }, t[0], this.lexer, this.rules);
1189
+ }
1190
+ }
1191
+ reflink(e, t) {
1192
+ let n;
1193
+ if ((n = this.rules.inline.reflink.exec(e)) || (n = this.rules.inline.nolink.exec(e))) {
1194
+ let r = (n[2] || n[1]).replace(this.rules.other.multipleSpaceGlobal, " "), i = t[r.toLowerCase()];
1195
+ if (!i) {
1196
+ let s = n[0].charAt(0);
1197
+ return { type: "text", raw: s, text: s };
1198
+ }
1199
+ return fe(n, i, n[0], this.lexer, this.rules);
1200
+ }
1201
+ }
1202
+ emStrong(e, t, n = "") {
1203
+ let r = this.rules.inline.emStrongLDelim.exec(e);
1204
+ if (!r || !r[1] && !r[2] && !r[3] && !r[4] || r[4] && n.match(this.rules.other.unicodeAlphaNumeric)) return;
1205
+ if (!(r[1] || r[3] || "") || !n || this.rules.inline.punctuation.exec(n)) {
1206
+ let s = [...r[0]].length - 1, a, o, l = s, p = 0, c = r[0][0] === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
1207
+ for (c.lastIndex = 0, t = t.slice(-1 * e.length + s); (r = c.exec(t)) !== null; ) {
1208
+ if (a = r[1] || r[2] || r[3] || r[4] || r[5] || r[6], !a) continue;
1209
+ if (o = [...a].length, r[3] || r[4]) {
1210
+ l += o;
1211
+ continue;
1212
+ } else if ((r[5] || r[6]) && s % 3 && !((s + o) % 3)) {
1213
+ p += o;
1214
+ continue;
1215
+ }
1216
+ if (l -= o, l > 0) continue;
1217
+ o = Math.min(o, o + l + p);
1218
+ let d = [...r[0]][0].length, h = e.slice(0, s + r.index + d + o);
1219
+ if (Math.min(s, o) % 2) {
1220
+ let f = h.slice(1, -1);
1221
+ return { type: "em", raw: h, text: f, tokens: this.lexer.inlineTokens(f) };
1222
+ }
1223
+ let R = h.slice(2, -2);
1224
+ return { type: "strong", raw: h, text: R, tokens: this.lexer.inlineTokens(R) };
1225
+ }
1226
+ }
1227
+ }
1228
+ codespan(e) {
1229
+ let t = this.rules.inline.code.exec(e);
1230
+ if (t) {
1231
+ let n = t[2].replace(this.rules.other.newLineCharGlobal, " "), r = this.rules.other.nonSpaceChar.test(n), i = this.rules.other.startingSpaceChar.test(n) && this.rules.other.endingSpaceChar.test(n);
1232
+ return r && i && (n = n.substring(1, n.length - 1)), { type: "codespan", raw: t[0], text: n };
1233
+ }
1234
+ }
1235
+ br(e) {
1236
+ let t = this.rules.inline.br.exec(e);
1237
+ if (t) return { type: "br", raw: t[0] };
1238
+ }
1239
+ del(e, t, n = "") {
1240
+ let r = this.rules.inline.delLDelim.exec(e);
1241
+ if (!r) return;
1242
+ if (!(r[1] || "") || !n || this.rules.inline.punctuation.exec(n)) {
1243
+ let s = [...r[0]].length - 1, a, o, l = s, p = this.rules.inline.delRDelim;
1244
+ for (p.lastIndex = 0, t = t.slice(-1 * e.length + s); (r = p.exec(t)) !== null; ) {
1245
+ if (a = r[1] || r[2] || r[3] || r[4] || r[5] || r[6], !a || (o = [...a].length, o !== s)) continue;
1246
+ if (r[3] || r[4]) {
1247
+ l += o;
1248
+ continue;
1249
+ }
1250
+ if (l -= o, l > 0) continue;
1251
+ o = Math.min(o, o + l);
1252
+ let c = [...r[0]][0].length, d = e.slice(0, s + r.index + c + o), h = d.slice(s, -s);
1253
+ return { type: "del", raw: d, text: h, tokens: this.lexer.inlineTokens(h) };
1254
+ }
1255
+ }
1256
+ }
1257
+ autolink(e) {
1258
+ let t = this.rules.inline.autolink.exec(e);
1259
+ if (t) {
1260
+ let n, r;
1261
+ return t[2] === "@" ? (n = t[1], r = "mailto:" + n) : (n = t[1], r = n), { type: "link", raw: t[0], text: n, href: r, tokens: [{ type: "text", raw: n, text: n }] };
1262
+ }
1263
+ }
1264
+ url(e) {
1265
+ let t;
1266
+ if (t = this.rules.inline.url.exec(e)) {
1267
+ let n, r;
1268
+ if (t[2] === "@") n = t[0], r = "mailto:" + n;
1269
+ else {
1270
+ let i;
1271
+ do
1272
+ i = t[0], t[0] = this.rules.inline._backpedal.exec(t[0])?.[0] ?? "";
1273
+ while (i !== t[0]);
1274
+ n = t[0], t[1] === "www." ? r = "http://" + t[0] : r = t[0];
1275
+ }
1276
+ return { type: "link", raw: t[0], text: n, href: r, tokens: [{ type: "text", raw: n, text: n }] };
1277
+ }
1278
+ }
1279
+ inlineText(e) {
1280
+ let t = this.rules.inline.text.exec(e);
1281
+ if (t) {
1282
+ let n = this.lexer.state.inRawBlock;
1283
+ return { type: "text", raw: t[0], text: t[0], escaped: n };
1284
+ }
1285
+ }
1286
+ };
1287
+ var x = class u {
1288
+ tokens;
1289
+ options;
1290
+ state;
1291
+ inlineQueue;
1292
+ tokenizer;
1293
+ constructor(e) {
1294
+ this.tokens = [], this.tokens.links = /* @__PURE__ */ Object.create(null), this.options = e || O, this.options.tokenizer = this.options.tokenizer || new w(), this.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer.lexer = this, this.inlineQueue = [], this.state = { inLink: false, inRawBlock: false, top: true };
1295
+ let t = { other: m, block: B.normal, inline: E.normal };
1296
+ this.options.pedantic ? (t.block = B.pedantic, t.inline = E.pedantic) : this.options.gfm && (t.block = B.gfm, this.options.breaks ? t.inline = E.breaks : t.inline = E.gfm), this.tokenizer.rules = t;
1297
+ }
1298
+ static get rules() {
1299
+ return { block: B, inline: E };
1300
+ }
1301
+ static lex(e, t) {
1302
+ return new u(t).lex(e);
1303
+ }
1304
+ static lexInline(e, t) {
1305
+ return new u(t).inlineTokens(e);
1306
+ }
1307
+ lex(e) {
1308
+ e = e.replace(m.carriageReturn, `
1309
+ `), this.blockTokens(e, this.tokens);
1310
+ for (let t = 0; t < this.inlineQueue.length; t++) {
1311
+ let n = this.inlineQueue[t];
1312
+ this.inlineTokens(n.src, n.tokens);
1313
+ }
1314
+ return this.inlineQueue = [], this.tokens;
1315
+ }
1316
+ blockTokens(e, t = [], n = false) {
1317
+ for (this.tokenizer.lexer = this, this.options.pedantic && (e = e.replace(m.tabCharGlobal, " ").replace(m.spaceLine, "")); e; ) {
1318
+ let r;
1319
+ if (this.options.extensions?.block?.some((s) => (r = s.call({ lexer: this }, e, t)) ? (e = e.substring(r.raw.length), t.push(r), true) : false)) continue;
1320
+ if (r = this.tokenizer.space(e)) {
1321
+ e = e.substring(r.raw.length);
1322
+ let s = t.at(-1);
1323
+ r.raw.length === 1 && s !== void 0 ? s.raw += `
1324
+ ` : t.push(r);
1325
+ continue;
1326
+ }
1327
+ if (r = this.tokenizer.code(e)) {
1328
+ e = e.substring(r.raw.length);
1329
+ let s = t.at(-1);
1330
+ s?.type === "paragraph" || s?.type === "text" ? (s.raw += (s.raw.endsWith(`
1331
+ `) ? "" : `
1332
+ `) + r.raw, s.text += `
1333
+ ` + r.text, this.inlineQueue.at(-1).src = s.text) : t.push(r);
1334
+ continue;
1335
+ }
1336
+ if (r = this.tokenizer.fences(e)) {
1337
+ e = e.substring(r.raw.length), t.push(r);
1338
+ continue;
1339
+ }
1340
+ if (r = this.tokenizer.heading(e)) {
1341
+ e = e.substring(r.raw.length), t.push(r);
1342
+ continue;
1343
+ }
1344
+ if (r = this.tokenizer.hr(e)) {
1345
+ e = e.substring(r.raw.length), t.push(r);
1346
+ continue;
1347
+ }
1348
+ if (r = this.tokenizer.blockquote(e)) {
1349
+ e = e.substring(r.raw.length), t.push(r);
1350
+ continue;
1351
+ }
1352
+ if (r = this.tokenizer.list(e)) {
1353
+ e = e.substring(r.raw.length), t.push(r);
1354
+ continue;
1355
+ }
1356
+ if (r = this.tokenizer.html(e)) {
1357
+ e = e.substring(r.raw.length), t.push(r);
1358
+ continue;
1359
+ }
1360
+ if (r = this.tokenizer.def(e)) {
1361
+ e = e.substring(r.raw.length);
1362
+ let s = t.at(-1);
1363
+ s?.type === "paragraph" || s?.type === "text" ? (s.raw += (s.raw.endsWith(`
1364
+ `) ? "" : `
1365
+ `) + r.raw, s.text += `
1366
+ ` + r.raw, this.inlineQueue.at(-1).src = s.text) : this.tokens.links[r.tag] || (this.tokens.links[r.tag] = { href: r.href, title: r.title }, t.push(r));
1367
+ continue;
1368
+ }
1369
+ if (r = this.tokenizer.table(e)) {
1370
+ e = e.substring(r.raw.length), t.push(r);
1371
+ continue;
1372
+ }
1373
+ if (r = this.tokenizer.lheading(e)) {
1374
+ e = e.substring(r.raw.length), t.push(r);
1375
+ continue;
1376
+ }
1377
+ let i = e;
1378
+ if (this.options.extensions?.startBlock) {
1379
+ let s = 1 / 0, a = e.slice(1), o;
1380
+ this.options.extensions.startBlock.forEach((l) => {
1381
+ o = l.call({ lexer: this }, a), typeof o == "number" && o >= 0 && (s = Math.min(s, o));
1382
+ }), s < 1 / 0 && s >= 0 && (i = e.substring(0, s + 1));
1383
+ }
1384
+ if (this.state.top && (r = this.tokenizer.paragraph(i))) {
1385
+ let s = t.at(-1);
1386
+ n && s?.type === "paragraph" ? (s.raw += (s.raw.endsWith(`
1387
+ `) ? "" : `
1388
+ `) + r.raw, s.text += `
1389
+ ` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = s.text) : t.push(r), n = i.length !== e.length, e = e.substring(r.raw.length);
1390
+ continue;
1391
+ }
1392
+ if (r = this.tokenizer.text(e)) {
1393
+ e = e.substring(r.raw.length);
1394
+ let s = t.at(-1);
1395
+ s?.type === "text" ? (s.raw += (s.raw.endsWith(`
1396
+ `) ? "" : `
1397
+ `) + r.raw, s.text += `
1398
+ ` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = s.text) : t.push(r);
1399
+ continue;
1400
+ }
1401
+ if (e) {
1402
+ let s = "Infinite loop on byte: " + e.charCodeAt(0);
1403
+ if (this.options.silent) {
1404
+ console.error(s);
1405
+ break;
1406
+ } else throw new Error(s);
1407
+ }
1408
+ }
1409
+ return this.state.top = true, t;
1410
+ }
1411
+ inline(e, t = []) {
1412
+ return this.inlineQueue.push({ src: e, tokens: t }), t;
1413
+ }
1414
+ inlineTokens(e, t = []) {
1415
+ this.tokenizer.lexer = this;
1416
+ let n = e, r = null;
1417
+ if (this.tokens.links) {
1418
+ let o = Object.keys(this.tokens.links);
1419
+ if (o.length > 0) for (; (r = this.tokenizer.rules.inline.reflinkSearch.exec(n)) !== null; ) o.includes(r[0].slice(r[0].lastIndexOf("[") + 1, -1)) && (n = n.slice(0, r.index) + "[" + "a".repeat(r[0].length - 2) + "]" + n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex));
1420
+ }
1421
+ for (; (r = this.tokenizer.rules.inline.anyPunctuation.exec(n)) !== null; ) n = n.slice(0, r.index) + "++" + n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
1422
+ let i;
1423
+ for (; (r = this.tokenizer.rules.inline.blockSkip.exec(n)) !== null; ) i = r[2] ? r[2].length : 0, n = n.slice(0, r.index + i) + "[" + "a".repeat(r[0].length - i - 2) + "]" + n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
1424
+ n = this.options.hooks?.emStrongMask?.call({ lexer: this }, n) ?? n;
1425
+ let s = false, a = "";
1426
+ for (; e; ) {
1427
+ s || (a = ""), s = false;
1428
+ let o;
1429
+ if (this.options.extensions?.inline?.some((p) => (o = p.call({ lexer: this }, e, t)) ? (e = e.substring(o.raw.length), t.push(o), true) : false)) continue;
1430
+ if (o = this.tokenizer.escape(e)) {
1431
+ e = e.substring(o.raw.length), t.push(o);
1432
+ continue;
1433
+ }
1434
+ if (o = this.tokenizer.tag(e)) {
1435
+ e = e.substring(o.raw.length), t.push(o);
1436
+ continue;
1437
+ }
1438
+ if (o = this.tokenizer.link(e)) {
1439
+ e = e.substring(o.raw.length), t.push(o);
1440
+ continue;
1441
+ }
1442
+ if (o = this.tokenizer.reflink(e, this.tokens.links)) {
1443
+ e = e.substring(o.raw.length);
1444
+ let p = t.at(-1);
1445
+ o.type === "text" && p?.type === "text" ? (p.raw += o.raw, p.text += o.text) : t.push(o);
1446
+ continue;
1447
+ }
1448
+ if (o = this.tokenizer.emStrong(e, n, a)) {
1449
+ e = e.substring(o.raw.length), t.push(o);
1450
+ continue;
1451
+ }
1452
+ if (o = this.tokenizer.codespan(e)) {
1453
+ e = e.substring(o.raw.length), t.push(o);
1454
+ continue;
1455
+ }
1456
+ if (o = this.tokenizer.br(e)) {
1457
+ e = e.substring(o.raw.length), t.push(o);
1458
+ continue;
1459
+ }
1460
+ if (o = this.tokenizer.del(e, n, a)) {
1461
+ e = e.substring(o.raw.length), t.push(o);
1462
+ continue;
1463
+ }
1464
+ if (o = this.tokenizer.autolink(e)) {
1465
+ e = e.substring(o.raw.length), t.push(o);
1466
+ continue;
1467
+ }
1468
+ if (!this.state.inLink && (o = this.tokenizer.url(e))) {
1469
+ e = e.substring(o.raw.length), t.push(o);
1470
+ continue;
1471
+ }
1472
+ let l = e;
1473
+ if (this.options.extensions?.startInline) {
1474
+ let p = 1 / 0, c = e.slice(1), d;
1475
+ this.options.extensions.startInline.forEach((h) => {
1476
+ d = h.call({ lexer: this }, c), typeof d == "number" && d >= 0 && (p = Math.min(p, d));
1477
+ }), p < 1 / 0 && p >= 0 && (l = e.substring(0, p + 1));
1478
+ }
1479
+ if (o = this.tokenizer.inlineText(l)) {
1480
+ e = e.substring(o.raw.length), o.raw.slice(-1) !== "_" && (a = o.raw.slice(-1)), s = true;
1481
+ let p = t.at(-1);
1482
+ p?.type === "text" ? (p.raw += o.raw, p.text += o.text) : t.push(o);
1483
+ continue;
1484
+ }
1485
+ if (e) {
1486
+ let p = "Infinite loop on byte: " + e.charCodeAt(0);
1487
+ if (this.options.silent) {
1488
+ console.error(p);
1489
+ break;
1490
+ } else throw new Error(p);
1491
+ }
1492
+ }
1493
+ return t;
1494
+ }
1495
+ };
1496
+ var y = class {
1497
+ options;
1498
+ parser;
1499
+ constructor(e) {
1500
+ this.options = e || O;
1501
+ }
1502
+ space(e) {
1503
+ return "";
1504
+ }
1505
+ code({ text: e, lang: t, escaped: n }) {
1506
+ let r = (t || "").match(m.notSpaceStart)?.[0], i = e.replace(m.endingNewline, "") + `
1507
+ `;
1508
+ return r ? '<pre><code class="language-' + T(r) + '">' + (n ? i : T(i, true)) + `</code></pre>
1509
+ ` : "<pre><code>" + (n ? i : T(i, true)) + `</code></pre>
1510
+ `;
1511
+ }
1512
+ blockquote({ tokens: e }) {
1513
+ return `<blockquote>
1514
+ ${this.parser.parse(e)}</blockquote>
1515
+ `;
1516
+ }
1517
+ html({ text: e }) {
1518
+ return e;
1519
+ }
1520
+ def(e) {
1521
+ return "";
1522
+ }
1523
+ heading({ tokens: e, depth: t }) {
1524
+ return `<h${t}>${this.parser.parseInline(e)}</h${t}>
1525
+ `;
1526
+ }
1527
+ hr(e) {
1528
+ return `<hr>
1529
+ `;
1530
+ }
1531
+ list(e) {
1532
+ let t = e.ordered, n = e.start, r = "";
1533
+ for (let a = 0; a < e.items.length; a++) {
1534
+ let o = e.items[a];
1535
+ r += this.listitem(o);
1536
+ }
1537
+ let i = t ? "ol" : "ul", s = t && n !== 1 ? ' start="' + n + '"' : "";
1538
+ return "<" + i + s + `>
1539
+ ` + r + "</" + i + `>
1540
+ `;
1541
+ }
1542
+ listitem(e) {
1543
+ return `<li>${this.parser.parse(e.tokens)}</li>
1544
+ `;
1545
+ }
1546
+ checkbox({ checked: e }) {
1547
+ return "<input " + (e ? 'checked="" ' : "") + 'disabled="" type="checkbox"> ';
1548
+ }
1549
+ paragraph({ tokens: e }) {
1550
+ return `<p>${this.parser.parseInline(e)}</p>
1551
+ `;
1552
+ }
1553
+ table(e) {
1554
+ let t = "", n = "";
1555
+ for (let i = 0; i < e.header.length; i++) n += this.tablecell(e.header[i]);
1556
+ t += this.tablerow({ text: n });
1557
+ let r = "";
1558
+ for (let i = 0; i < e.rows.length; i++) {
1559
+ let s = e.rows[i];
1560
+ n = "";
1561
+ for (let a = 0; a < s.length; a++) n += this.tablecell(s[a]);
1562
+ r += this.tablerow({ text: n });
1563
+ }
1564
+ return r && (r = `<tbody>${r}</tbody>`), `<table>
1565
+ <thead>
1566
+ ` + t + `</thead>
1567
+ ` + r + `</table>
1568
+ `;
1569
+ }
1570
+ tablerow({ text: e }) {
1571
+ return `<tr>
1572
+ ${e}</tr>
1573
+ `;
1574
+ }
1575
+ tablecell(e) {
1576
+ let t = this.parser.parseInline(e.tokens), n = e.header ? "th" : "td";
1577
+ return (e.align ? `<${n} align="${e.align}">` : `<${n}>`) + t + `</${n}>
1578
+ `;
1579
+ }
1580
+ strong({ tokens: e }) {
1581
+ return `<strong>${this.parser.parseInline(e)}</strong>`;
1582
+ }
1583
+ em({ tokens: e }) {
1584
+ return `<em>${this.parser.parseInline(e)}</em>`;
1585
+ }
1586
+ codespan({ text: e }) {
1587
+ return `<code>${T(e, true)}</code>`;
1588
+ }
1589
+ br(e) {
1590
+ return "<br>";
1591
+ }
1592
+ del({ tokens: e }) {
1593
+ return `<del>${this.parser.parseInline(e)}</del>`;
1594
+ }
1595
+ link({ href: e, title: t, tokens: n }) {
1596
+ let r = this.parser.parseInline(n), i = J(e);
1597
+ if (i === null) return r;
1598
+ e = i;
1599
+ let s = '<a href="' + e + '"';
1600
+ return t && (s += ' title="' + T(t) + '"'), s += ">" + r + "</a>", s;
1601
+ }
1602
+ image({ href: e, title: t, text: n, tokens: r }) {
1603
+ r && (n = this.parser.parseInline(r, this.parser.textRenderer));
1604
+ let i = J(e);
1605
+ if (i === null) return T(n);
1606
+ e = i;
1607
+ let s = `<img src="${e}" alt="${T(n)}"`;
1608
+ return t && (s += ` title="${T(t)}"`), s += ">", s;
1609
+ }
1610
+ text(e) {
1611
+ return "tokens" in e && e.tokens ? this.parser.parseInline(e.tokens) : "escaped" in e && e.escaped ? e.text : T(e.text);
1612
+ }
1613
+ };
1614
+ var $ = class {
1615
+ strong({ text: e }) {
1616
+ return e;
1617
+ }
1618
+ em({ text: e }) {
1619
+ return e;
1620
+ }
1621
+ codespan({ text: e }) {
1622
+ return e;
1623
+ }
1624
+ del({ text: e }) {
1625
+ return e;
1626
+ }
1627
+ html({ text: e }) {
1628
+ return e;
1629
+ }
1630
+ text({ text: e }) {
1631
+ return e;
1632
+ }
1633
+ link({ text: e }) {
1634
+ return "" + e;
1635
+ }
1636
+ image({ text: e }) {
1637
+ return "" + e;
1638
+ }
1639
+ br() {
1640
+ return "";
1641
+ }
1642
+ checkbox({ raw: e }) {
1643
+ return e;
1644
+ }
1645
+ };
1646
+ var b = class u2 {
1647
+ options;
1648
+ renderer;
1649
+ textRenderer;
1650
+ constructor(e) {
1651
+ this.options = e || O, this.options.renderer = this.options.renderer || new y(), this.renderer = this.options.renderer, this.renderer.options = this.options, this.renderer.parser = this, this.textRenderer = new $();
1652
+ }
1653
+ static parse(e, t) {
1654
+ return new u2(t).parse(e);
1655
+ }
1656
+ static parseInline(e, t) {
1657
+ return new u2(t).parseInline(e);
1658
+ }
1659
+ parse(e) {
1660
+ this.renderer.parser = this;
1661
+ let t = "";
1662
+ for (let n = 0; n < e.length; n++) {
1663
+ let r = e[n];
1664
+ if (this.options.extensions?.renderers?.[r.type]) {
1665
+ let s = r, a = this.options.extensions.renderers[s.type].call({ parser: this }, s);
1666
+ if (a !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "def", "paragraph", "text"].includes(s.type)) {
1667
+ t += a || "";
1668
+ continue;
1669
+ }
1670
+ }
1671
+ let i = r;
1672
+ switch (i.type) {
1673
+ case "space": {
1674
+ t += this.renderer.space(i);
1675
+ break;
1676
+ }
1677
+ case "hr": {
1678
+ t += this.renderer.hr(i);
1679
+ break;
1680
+ }
1681
+ case "heading": {
1682
+ t += this.renderer.heading(i);
1683
+ break;
1684
+ }
1685
+ case "code": {
1686
+ t += this.renderer.code(i);
1687
+ break;
1688
+ }
1689
+ case "table": {
1690
+ t += this.renderer.table(i);
1691
+ break;
1692
+ }
1693
+ case "blockquote": {
1694
+ t += this.renderer.blockquote(i);
1695
+ break;
1696
+ }
1697
+ case "list": {
1698
+ t += this.renderer.list(i);
1699
+ break;
1700
+ }
1701
+ case "checkbox": {
1702
+ t += this.renderer.checkbox(i);
1703
+ break;
1704
+ }
1705
+ case "html": {
1706
+ t += this.renderer.html(i);
1707
+ break;
1708
+ }
1709
+ case "def": {
1710
+ t += this.renderer.def(i);
1711
+ break;
1712
+ }
1713
+ case "paragraph": {
1714
+ t += this.renderer.paragraph(i);
1715
+ break;
1716
+ }
1717
+ case "text": {
1718
+ t += this.renderer.text(i);
1719
+ break;
1720
+ }
1721
+ default: {
1722
+ let s = 'Token with "' + i.type + '" type was not found.';
1723
+ if (this.options.silent) return console.error(s), "";
1724
+ throw new Error(s);
1725
+ }
1726
+ }
1727
+ }
1728
+ return t;
1729
+ }
1730
+ parseInline(e, t = this.renderer) {
1731
+ this.renderer.parser = this;
1732
+ let n = "";
1733
+ for (let r = 0; r < e.length; r++) {
1734
+ let i = e[r];
1735
+ if (this.options.extensions?.renderers?.[i.type]) {
1736
+ let a = this.options.extensions.renderers[i.type].call({ parser: this }, i);
1737
+ if (a !== false || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(i.type)) {
1738
+ n += a || "";
1739
+ continue;
1740
+ }
1741
+ }
1742
+ let s = i;
1743
+ switch (s.type) {
1744
+ case "escape": {
1745
+ n += t.text(s);
1746
+ break;
1747
+ }
1748
+ case "html": {
1749
+ n += t.html(s);
1750
+ break;
1751
+ }
1752
+ case "link": {
1753
+ n += t.link(s);
1754
+ break;
1755
+ }
1756
+ case "image": {
1757
+ n += t.image(s);
1758
+ break;
1759
+ }
1760
+ case "checkbox": {
1761
+ n += t.checkbox(s);
1762
+ break;
1763
+ }
1764
+ case "strong": {
1765
+ n += t.strong(s);
1766
+ break;
1767
+ }
1768
+ case "em": {
1769
+ n += t.em(s);
1770
+ break;
1771
+ }
1772
+ case "codespan": {
1773
+ n += t.codespan(s);
1774
+ break;
1775
+ }
1776
+ case "br": {
1777
+ n += t.br(s);
1778
+ break;
1779
+ }
1780
+ case "del": {
1781
+ n += t.del(s);
1782
+ break;
1783
+ }
1784
+ case "text": {
1785
+ n += t.text(s);
1786
+ break;
1787
+ }
1788
+ default: {
1789
+ let a = 'Token with "' + s.type + '" type was not found.';
1790
+ if (this.options.silent) return console.error(a), "";
1791
+ throw new Error(a);
1792
+ }
1793
+ }
1794
+ }
1795
+ return n;
1796
+ }
1797
+ };
1798
+ var P = class {
1799
+ options;
1800
+ block;
1801
+ constructor(e) {
1802
+ this.options = e || O;
1803
+ }
1804
+ static passThroughHooks = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens", "emStrongMask"]);
1805
+ static passThroughHooksRespectAsync = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens"]);
1806
+ preprocess(e) {
1807
+ return e;
1808
+ }
1809
+ postprocess(e) {
1810
+ return e;
1811
+ }
1812
+ processAllTokens(e) {
1813
+ return e;
1814
+ }
1815
+ emStrongMask(e) {
1816
+ return e;
1817
+ }
1818
+ provideLexer(e = this.block) {
1819
+ return e ? x.lex : x.lexInline;
1820
+ }
1821
+ provideParser(e = this.block) {
1822
+ return e ? b.parse : b.parseInline;
1823
+ }
1824
+ };
1825
+ var D = class {
1826
+ defaults = M();
1827
+ options = this.setOptions;
1828
+ parse = this.parseMarkdown(true);
1829
+ parseInline = this.parseMarkdown(false);
1830
+ Parser = b;
1831
+ Renderer = y;
1832
+ TextRenderer = $;
1833
+ Lexer = x;
1834
+ Tokenizer = w;
1835
+ Hooks = P;
1836
+ constructor(...e) {
1837
+ this.use(...e);
1838
+ }
1839
+ walkTokens(e, t) {
1840
+ let n = [];
1841
+ for (let r of e) switch (n = n.concat(t.call(this, r)), r.type) {
1842
+ case "table": {
1843
+ let i = r;
1844
+ for (let s of i.header) n = n.concat(this.walkTokens(s.tokens, t));
1845
+ for (let s of i.rows) for (let a of s) n = n.concat(this.walkTokens(a.tokens, t));
1846
+ break;
1847
+ }
1848
+ case "list": {
1849
+ let i = r;
1850
+ n = n.concat(this.walkTokens(i.items, t));
1851
+ break;
1852
+ }
1853
+ default: {
1854
+ let i = r;
1855
+ this.defaults.extensions?.childTokens?.[i.type] ? this.defaults.extensions.childTokens[i.type].forEach((s) => {
1856
+ let a = i[s].flat(1 / 0);
1857
+ n = n.concat(this.walkTokens(a, t));
1858
+ }) : i.tokens && (n = n.concat(this.walkTokens(i.tokens, t)));
1859
+ }
1860
+ }
1861
+ return n;
1862
+ }
1863
+ use(...e) {
1864
+ let t = this.defaults.extensions || { renderers: {}, childTokens: {} };
1865
+ return e.forEach((n) => {
1866
+ let r = { ...n };
1867
+ if (r.async = this.defaults.async || r.async || false, n.extensions && (n.extensions.forEach((i) => {
1868
+ if (!i.name) throw new Error("extension name required");
1869
+ if ("renderer" in i) {
1870
+ let s = t.renderers[i.name];
1871
+ s ? t.renderers[i.name] = function(...a) {
1872
+ let o = i.renderer.apply(this, a);
1873
+ return o === false && (o = s.apply(this, a)), o;
1874
+ } : t.renderers[i.name] = i.renderer;
1875
+ }
1876
+ if ("tokenizer" in i) {
1877
+ if (!i.level || i.level !== "block" && i.level !== "inline") throw new Error("extension level must be 'block' or 'inline'");
1878
+ let s = t[i.level];
1879
+ s ? s.unshift(i.tokenizer) : t[i.level] = [i.tokenizer], i.start && (i.level === "block" ? t.startBlock ? t.startBlock.push(i.start) : t.startBlock = [i.start] : i.level === "inline" && (t.startInline ? t.startInline.push(i.start) : t.startInline = [i.start]));
1880
+ }
1881
+ "childTokens" in i && i.childTokens && (t.childTokens[i.name] = i.childTokens);
1882
+ }), r.extensions = t), n.renderer) {
1883
+ let i = this.defaults.renderer || new y(this.defaults);
1884
+ for (let s in n.renderer) {
1885
+ if (!(s in i)) throw new Error(`renderer '${s}' does not exist`);
1886
+ if (["options", "parser"].includes(s)) continue;
1887
+ let a = s, o = n.renderer[a], l = i[a];
1888
+ i[a] = (...p) => {
1889
+ let c = o.apply(i, p);
1890
+ return c === false && (c = l.apply(i, p)), c || "";
1891
+ };
1892
+ }
1893
+ r.renderer = i;
1894
+ }
1895
+ if (n.tokenizer) {
1896
+ let i = this.defaults.tokenizer || new w(this.defaults);
1897
+ for (let s in n.tokenizer) {
1898
+ if (!(s in i)) throw new Error(`tokenizer '${s}' does not exist`);
1899
+ if (["options", "rules", "lexer"].includes(s)) continue;
1900
+ let a = s, o = n.tokenizer[a], l = i[a];
1901
+ i[a] = (...p) => {
1902
+ let c = o.apply(i, p);
1903
+ return c === false && (c = l.apply(i, p)), c;
1904
+ };
1905
+ }
1906
+ r.tokenizer = i;
1907
+ }
1908
+ if (n.hooks) {
1909
+ let i = this.defaults.hooks || new P();
1910
+ for (let s in n.hooks) {
1911
+ if (!(s in i)) throw new Error(`hook '${s}' does not exist`);
1912
+ if (["options", "block"].includes(s)) continue;
1913
+ let a = s, o = n.hooks[a], l = i[a];
1914
+ P.passThroughHooks.has(s) ? i[a] = (p) => {
1915
+ if (this.defaults.async && P.passThroughHooksRespectAsync.has(s)) return (async () => {
1916
+ let d = await o.call(i, p);
1917
+ return l.call(i, d);
1918
+ })();
1919
+ let c = o.call(i, p);
1920
+ return l.call(i, c);
1921
+ } : i[a] = (...p) => {
1922
+ if (this.defaults.async) return (async () => {
1923
+ let d = await o.apply(i, p);
1924
+ return d === false && (d = await l.apply(i, p)), d;
1925
+ })();
1926
+ let c = o.apply(i, p);
1927
+ return c === false && (c = l.apply(i, p)), c;
1928
+ };
1929
+ }
1930
+ r.hooks = i;
1931
+ }
1932
+ if (n.walkTokens) {
1933
+ let i = this.defaults.walkTokens, s = n.walkTokens;
1934
+ r.walkTokens = function(a) {
1935
+ let o = [];
1936
+ return o.push(s.call(this, a)), i && (o = o.concat(i.call(this, a))), o;
1937
+ };
1938
+ }
1939
+ this.defaults = { ...this.defaults, ...r };
1940
+ }), this;
1941
+ }
1942
+ setOptions(e) {
1943
+ return this.defaults = { ...this.defaults, ...e }, this;
1944
+ }
1945
+ lexer(e, t) {
1946
+ return x.lex(e, t ?? this.defaults);
1947
+ }
1948
+ parser(e, t) {
1949
+ return b.parse(e, t ?? this.defaults);
1950
+ }
1951
+ parseMarkdown(e) {
1952
+ return (n, r) => {
1953
+ let i = { ...r }, s = { ...this.defaults, ...i }, a = this.onError(!!s.silent, !!s.async);
1954
+ if (this.defaults.async === true && i.async === false) return a(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));
1955
+ if (typeof n > "u" || n === null) return a(new Error("marked(): input parameter is undefined or null"));
1956
+ if (typeof n != "string") return a(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(n) + ", string expected"));
1957
+ if (s.hooks && (s.hooks.options = s, s.hooks.block = e), s.async) return (async () => {
1958
+ let o = s.hooks ? await s.hooks.preprocess(n) : n, p = await (s.hooks ? await s.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(o, s), c = s.hooks ? await s.hooks.processAllTokens(p) : p;
1959
+ s.walkTokens && await Promise.all(this.walkTokens(c, s.walkTokens));
1960
+ let h = await (s.hooks ? await s.hooks.provideParser(e) : e ? b.parse : b.parseInline)(c, s);
1961
+ return s.hooks ? await s.hooks.postprocess(h) : h;
1962
+ })().catch(a);
1963
+ try {
1964
+ s.hooks && (n = s.hooks.preprocess(n));
1965
+ let l = (s.hooks ? s.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(n, s);
1966
+ s.hooks && (l = s.hooks.processAllTokens(l)), s.walkTokens && this.walkTokens(l, s.walkTokens);
1967
+ let c = (s.hooks ? s.hooks.provideParser(e) : e ? b.parse : b.parseInline)(l, s);
1968
+ return s.hooks && (c = s.hooks.postprocess(c)), c;
1969
+ } catch (o) {
1970
+ return a(o);
1971
+ }
1972
+ };
1973
+ }
1974
+ onError(e, t) {
1975
+ return (n) => {
1976
+ if (n.message += `
1977
+ Please report this to https://github.com/markedjs/marked.`, e) {
1978
+ let r = "<p>An error occurred:</p><pre>" + T(n.message + "", true) + "</pre>";
1979
+ return t ? Promise.resolve(r) : r;
1980
+ }
1981
+ if (t) return Promise.reject(n);
1982
+ throw n;
1983
+ };
1984
+ }
1985
+ };
1986
+ var L = new D();
1987
+ function g(u3, e) {
1988
+ return L.parse(u3, e);
1989
+ }
1990
+ g.options = g.setOptions = function(u3) {
1991
+ return L.setOptions(u3), g.defaults = L.defaults, G(g.defaults), g;
1992
+ };
1993
+ g.getDefaults = M;
1994
+ g.defaults = O;
1995
+ g.use = function(...u3) {
1996
+ return L.use(...u3), g.defaults = L.defaults, G(g.defaults), g;
1997
+ };
1998
+ g.walkTokens = function(u3, e) {
1999
+ return L.walkTokens(u3, e);
2000
+ };
2001
+ g.parseInline = L.parseInline;
2002
+ g.Parser = b;
2003
+ g.parser = b.parse;
2004
+ g.Renderer = y;
2005
+ g.TextRenderer = $;
2006
+ g.Lexer = x;
2007
+ g.lexer = x.lex;
2008
+ g.Tokenizer = w;
2009
+ g.Hooks = P;
2010
+ g.parse = g;
2011
+ var Qt = g.options;
2012
+ var jt = g.setOptions;
2013
+ var Ft = g.use;
2014
+ var Ut = g.walkTokens;
2015
+ var Kt = g.parseInline;
2016
+ var Xt = b.parse;
2017
+ var Jt = x.lex;
2018
+
2019
+ // ../core/dist/formatting/renderer.js
2020
+ function escapeHtml(text) {
2021
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
2022
+ }
2023
+ function renderToWeChatHtml(markdown, template) {
2024
+ const instance = new D();
2025
+ instance.use({
2026
+ renderer: {
2027
+ heading({ tokens, depth }) {
2028
+ const text = this.parser.parseInline(tokens);
2029
+ const style = depth === 1 ? template.styles.title : depth === 2 ? template.styles.h2 : template.styles.h3;
2030
+ return `<h${depth} style="${style}">${text}</h${depth}>`;
2031
+ },
2032
+ paragraph({ tokens }) {
2033
+ const text = this.parser.parseInline(tokens);
2034
+ return `<p style="${template.styles.paragraph}">${text}</p>`;
2035
+ },
2036
+ blockquote({ tokens }) {
2037
+ const text = this.parser.parse(tokens);
2038
+ return `<blockquote style="${template.styles.blockquote}">${text}</blockquote>`;
2039
+ },
2040
+ code({ text }) {
2041
+ return `<pre style="${template.styles.codeBlock}"><code>${escapeHtml(text)}</code></pre>`;
2042
+ },
2043
+ codespan({ text }) {
2044
+ return `<code style="${template.styles.codeInline}">${text}</code>`;
2045
+ },
2046
+ image({ href, text }) {
2047
+ return `<img src="${href}" alt="${text}" style="${template.styles.image}" />`;
2048
+ },
2049
+ listitem(item) {
2050
+ const text = this.parser.parse(item.tokens);
2051
+ return `<li style="${template.styles.listItem}">${text}</li>`;
2052
+ },
2053
+ strong({ tokens }) {
2054
+ const text = this.parser.parseInline(tokens);
2055
+ return `<strong style="${template.styles.strong}">${text}</strong>`;
2056
+ },
2057
+ em({ tokens }) {
2058
+ const text = this.parser.parseInline(tokens);
2059
+ return `<em style="${template.styles.emphasis}">${text}</em>`;
2060
+ },
2061
+ link({ href, tokens }) {
2062
+ const text = this.parser.parseInline(tokens);
2063
+ return `<a href="${href}" style="${template.styles.link}">${text}</a>`;
2064
+ },
2065
+ hr() {
2066
+ return `<hr style="${template.styles.hr}" />`;
2067
+ }
2068
+ }
2069
+ });
2070
+ const html = instance.parse(markdown);
2071
+ return `<section style="max-width: ${template.layout.maxWidth}; margin: 0 auto; padding: 16px; line-height: ${template.layout.lineHeight}; letter-spacing: ${template.layout.letterSpacing};">${html}</section>`;
2072
+ }
2073
+
2074
+ // ../core/dist/formatting/templates/minimal.js
2075
+ var minimalTemplate = {
2076
+ id: "minimal",
2077
+ name: "\u7B80\u7EA6",
2078
+ styles: {
2079
+ title: "font-size: 22px; font-weight: bold; color: #1a1a1a; margin-bottom: 16px;",
2080
+ h2: "font-size: 18px; font-weight: bold; color: #333; border-left: 4px solid #07c160; padding-left: 12px; margin: 24px 0 12px;",
2081
+ h3: "font-size: 16px; font-weight: bold; color: #333;",
2082
+ paragraph: "font-size: 15px; color: #3f3f3f; line-height: 1.8; margin-bottom: 16px; letter-spacing: 0.5px;",
2083
+ blockquote: "border-left: 3px solid #ddd; padding: 8px 16px; color: #888; font-size: 14px; margin: 16px 0;",
2084
+ codeBlock: "background: #f6f8fa; padding: 16px; border-radius: 4px; font-size: 13px; font-family: Menlo, monospace; overflow-x: auto; margin: 16px 0;",
2085
+ codeInline: "background: #f0f0f0; padding: 2px 6px; border-radius: 3px; font-size: 13px; color: #e83e8c;",
2086
+ image: "max-width: 100%; height: auto; border-radius: 4px; margin: 16px 0; display: block;",
2087
+ listItem: "font-size: 15px; color: #3f3f3f; line-height: 1.8; margin-bottom: 8px;",
2088
+ strong: "font-weight: bold; color: #1a1a1a;",
2089
+ link: "color: #576b95; text-decoration: none;",
2090
+ emphasis: "font-style: italic;",
2091
+ hr: "border: none; border-top: 1px solid #eee; margin: 24px 0;"
2092
+ },
2093
+ layout: {
2094
+ lineHeight: "1.8",
2095
+ letterSpacing: "0.5px",
2096
+ paragraphSpacing: "16px",
2097
+ maxWidth: "100%"
2098
+ }
2099
+ };
2100
+
2101
+ // ../core/dist/steps/formatting.js
2102
+ var TEMPLATES = {
2103
+ minimal: minimalTemplate
2104
+ };
2105
+ var FormattingStep = class {
2106
+ templateId;
2107
+ id;
2108
+ type = "formatting";
2109
+ gate = "auto";
2110
+ constructor(templateId = "minimal", id = "formatting") {
2111
+ this.templateId = templateId;
2112
+ this.id = id;
2113
+ }
2114
+ async execute(context) {
2115
+ const start = Date.now();
2116
+ try {
2117
+ const article = context.data.article;
2118
+ if (!article) {
2119
+ return {
2120
+ success: false,
2121
+ error: "\u7F3A\u5C11\u6587\u7AE0\u6570\u636E\uFF0C\u8BF7\u5148\u6267\u884C writing \u6B65\u9AA4",
2122
+ duration: Date.now() - start
2123
+ };
2124
+ }
2125
+ const template = TEMPLATES[this.templateId] ?? minimalTemplate;
2126
+ const html = renderToWeChatHtml(article.content, template);
2127
+ context.data.formatted = { html };
2128
+ return {
2129
+ success: true,
2130
+ data: context.data.formatted,
2131
+ duration: Date.now() - start
2132
+ };
2133
+ } catch (err) {
2134
+ return {
2135
+ success: false,
2136
+ error: err instanceof Error ? err.message : String(err),
2137
+ duration: Date.now() - start
2138
+ };
2139
+ }
2140
+ }
2141
+ };
2142
+
2143
+ // ../core/dist/steps/draft-publish.js
2144
+ var DraftPublishStep = class {
2145
+ client;
2146
+ thumbMediaId;
2147
+ id;
2148
+ type = "draft-publish";
2149
+ gate = "auto";
2150
+ constructor(client, thumbMediaId = "", id = "draft-publish") {
2151
+ this.client = client;
2152
+ this.thumbMediaId = thumbMediaId;
2153
+ this.id = id;
2154
+ }
2155
+ async execute(context) {
2156
+ const start = Date.now();
2157
+ try {
2158
+ const formatted = context.data.formatted;
2159
+ if (!formatted) {
2160
+ return {
2161
+ success: false,
2162
+ error: "\u7F3A\u5C11\u6392\u7248\u6570\u636E\uFF0C\u8BF7\u5148\u6267\u884C formatting \u6B65\u9AA4",
2163
+ duration: Date.now() - start
2164
+ };
2165
+ }
2166
+ const title = context.data.article?.title ?? "\u65E0\u6807\u9898";
2167
+ const mediaId = await this.client.addDraft([
2168
+ {
2169
+ title,
2170
+ content: formatted.html,
2171
+ thumbMediaId: this.thumbMediaId
2172
+ }
2173
+ ]);
2174
+ context.data.draftId = mediaId;
2175
+ return {
2176
+ success: true,
2177
+ data: { draftId: mediaId },
2178
+ duration: Date.now() - start
2179
+ };
2180
+ } catch (err) {
2181
+ return {
2182
+ success: false,
2183
+ error: err instanceof Error ? err.message : String(err),
2184
+ duration: Date.now() - start
2185
+ };
2186
+ }
2187
+ }
2188
+ };
2189
+
2190
+ // ../core/dist/config-loader.js
2191
+ import { readFileSync } from "fs";
2192
+ import { join } from "path";
2193
+ function findWxclawDir() {
2194
+ const cwd = process.cwd();
2195
+ const candidates = [
2196
+ join(cwd, ".wxclaw"),
2197
+ join(cwd, "..", ".wxclaw"),
2198
+ join(cwd, "..", "..", ".wxclaw"),
2199
+ join(cwd, "..", "..", "..", ".wxclaw")
2200
+ ];
2201
+ for (const candidate of candidates) {
2202
+ try {
2203
+ readFileSync(join(candidate, "soul.md"), "utf-8");
2204
+ return candidate;
2205
+ } catch {
2206
+ }
2207
+ }
2208
+ return join(cwd, ".wxclaw");
2209
+ }
2210
+ var wxclawDir = null;
2211
+ function getWxclawDir() {
2212
+ if (!wxclawDir) {
2213
+ wxclawDir = findWxclawDir();
2214
+ }
2215
+ return wxclawDir;
2216
+ }
2217
+ function loadSoulPrompt() {
2218
+ const filePath = join(getWxclawDir(), "soul.md");
2219
+ return readFileSync(filePath, "utf-8");
2220
+ }
2221
+ function loadAgentsRules() {
2222
+ const filePath = join(getWxclawDir(), "agents.md");
2223
+ return readFileSync(filePath, "utf-8");
2224
+ }
2225
+ function loadStylePrompt(styleName) {
2226
+ const filePath = join(getWxclawDir(), "styles", `${styleName}.md`);
2227
+ return readFileSync(filePath, "utf-8");
2228
+ }
2229
+ function loadPipelineConfig(styleName) {
2230
+ const soulPrompt = loadSoulPrompt();
2231
+ let agentsRules;
2232
+ try {
2233
+ agentsRules = loadAgentsRules();
2234
+ } catch {
2235
+ agentsRules = void 0;
2236
+ }
2237
+ let stylePrompt;
2238
+ if (styleName) {
2239
+ try {
2240
+ stylePrompt = loadStylePrompt(styleName);
2241
+ } catch {
2242
+ stylePrompt = void 0;
2243
+ }
2244
+ }
2245
+ return {
2246
+ soulPrompt,
2247
+ agentsRules,
2248
+ stylePrompt
2249
+ };
2250
+ }
2251
+
2252
+ // ../core/dist/styles/manager.js
2253
+ import { readdirSync, readFileSync as readFileSync2, writeFileSync, existsSync, mkdirSync } from "fs";
2254
+ import { join as join2, basename } from "path";
2255
+ function findWxclawDir2() {
2256
+ const cwd = process.cwd();
2257
+ const candidates = [
2258
+ join2(cwd, ".wxclaw"),
2259
+ join2(cwd, "..", ".wxclaw"),
2260
+ join2(cwd, "..", "..", ".wxclaw"),
2261
+ join2(cwd, "..", "..", "..", ".wxclaw")
2262
+ ];
2263
+ for (const candidate of candidates) {
2264
+ try {
2265
+ readFileSync2(join2(candidate, "soul.md"), "utf-8");
2266
+ return candidate;
2267
+ } catch {
2268
+ }
2269
+ }
2270
+ return join2(cwd, ".wxclaw");
2271
+ }
2272
+ function extractNameFromContent(content, fallback) {
2273
+ const firstLine = content.split("\n")[0] ?? "";
2274
+ const match = firstLine.match(/^#\s+(.+)/);
2275
+ return match?.[1]?.trim() ?? fallback;
2276
+ }
2277
+ var StyleManager = class {
2278
+ wxclawDir;
2279
+ constructor(wxclawDir2) {
2280
+ this.wxclawDir = wxclawDir2 ?? findWxclawDir2();
2281
+ }
2282
+ // 从 .wxclaw/styles/*.md 加载预设风格
2283
+ loadPresets() {
2284
+ const stylesDir = join2(this.wxclawDir, "styles");
2285
+ if (!existsSync(stylesDir)) {
2286
+ return [];
2287
+ }
2288
+ let files;
2289
+ try {
2290
+ files = readdirSync(stylesDir).filter((f) => f.endsWith(".md"));
2291
+ } catch {
2292
+ return [];
2293
+ }
2294
+ return files.map((file) => {
2295
+ const filePath = join2(stylesDir, file);
2296
+ const content = readFileSync2(filePath, "utf-8");
2297
+ const id = basename(file, ".md");
2298
+ const name = extractNameFromContent(content, id);
2299
+ return {
2300
+ id,
2301
+ name,
2302
+ type: "preset",
2303
+ systemPrompt: content,
2304
+ source: filePath
2305
+ };
2306
+ });
2307
+ }
2308
+ // 获取指定风格
2309
+ getStyle(id) {
2310
+ return this.listStyles().find((s) => s.id === id);
2311
+ }
2312
+ // 列出所有风格
2313
+ listStyles() {
2314
+ return this.loadPresets();
2315
+ }
2316
+ // 添加自定义风格
2317
+ addCustomStyle(name, systemPrompt) {
2318
+ const stylesDir = join2(this.wxclawDir, "styles");
2319
+ if (!existsSync(stylesDir)) {
2320
+ mkdirSync(stylesDir, { recursive: true });
2321
+ }
2322
+ const id = name.toLowerCase().replace(/\s+/g, "-");
2323
+ const filePath = join2(stylesDir, `${id}.md`);
2324
+ writeFileSync(filePath, `# ${name}
2325
+
2326
+ ${systemPrompt}`, "utf-8");
2327
+ return {
2328
+ id,
2329
+ name,
2330
+ type: "custom",
2331
+ systemPrompt: `# ${name}
2332
+
2333
+ ${systemPrompt}`,
2334
+ source: filePath
2335
+ };
2336
+ }
2337
+ // 范文学习:调用 LLM 分析范文,提取 StyleProfile,生成 system prompt
2338
+ async learnFromSamples(name, sampleTexts, llm) {
2339
+ const samplesContent = sampleTexts.map((t, i) => `\u3010\u8303\u6587 ${i + 1}\u3011
2340
+ ${t}`).join("\n\n---\n\n");
2341
+ const prompt = `\u8BF7\u5206\u6790\u4EE5\u4E0B\u8303\u6587\uFF0C\u63D0\u53D6\u5199\u4F5C\u98CE\u683C\u7279\u5F81\uFF0C\u5E76\u4EE5 JSON \u683C\u5F0F\u8FD4\u56DE StyleProfile\u3002
2342
+
2343
+ \u8303\u6587\u5185\u5BB9\uFF1A
2344
+ ${samplesContent}
2345
+
2346
+ \u8BF7\u8FD4\u56DE\u5982\u4E0B JSON \u683C\u5F0F\uFF08\u4E0D\u8981\u6709\u5176\u4ED6\u5185\u5BB9\uFF0C\u53EA\u8FD4\u56DE JSON\uFF09\uFF1A
2347
+ {
2348
+ "tone": "\u8BED\u6C14\u7279\u5F81\u63CF\u8FF0",
2349
+ "sentencePattern": "\u53E5\u5F0F\u7279\u5F81\u63CF\u8FF0",
2350
+ "structure": "\u6587\u7AE0\u7ED3\u6784\u63CF\u8FF0",
2351
+ "vocabulary": "\u7528\u8BCD\u7279\u5F81\u63CF\u8FF0",
2352
+ "openingStyle": "\u5F00\u5934\u98CE\u683C\u63CF\u8FF0",
2353
+ "closingStyle": "\u7ED3\u5C3E\u98CE\u683C\u63CF\u8FF0",
2354
+ "specialHabits": ["\u7279\u6B8A\u4E60\u60EF1", "\u7279\u6B8A\u4E60\u60EF2"]
2355
+ }`;
2356
+ const response = await llm.chat({
2357
+ messages: [{ role: "user", content: prompt }],
2358
+ temperature: 0.3
2359
+ });
2360
+ let profile;
2361
+ try {
2362
+ const jsonMatch = response.content.match(/\{[\s\S]*\}/);
2363
+ if (!jsonMatch) {
2364
+ throw new Error("LLM \u54CD\u5E94\u4E2D\u672A\u627E\u5230 JSON");
2365
+ }
2366
+ profile = JSON.parse(jsonMatch[0]);
2367
+ } catch {
2368
+ profile = {
2369
+ tone: "\u81EA\u7136\u6D41\u7545",
2370
+ sentencePattern: "\u957F\u77ED\u53E5\u7ED3\u5408",
2371
+ structure: "\u5F00\u5934\u2192\u5C55\u5F00\u2192\u7ED3\u5C3E",
2372
+ vocabulary: "\u53E3\u8BED\u5316",
2373
+ openingStyle: "\u76F4\u63A5\u5207\u9898",
2374
+ closingStyle: "\u603B\u7ED3\u8981\u70B9",
2375
+ specialHabits: []
2376
+ };
2377
+ }
2378
+ const systemPrompt = `# ${name}
2379
+
2380
+ ## \u98CE\u683C\u5B9A\u4E49
2381
+
2382
+ \u57FA\u4E8E\u8303\u6587\u5B66\u4E60\u751F\u6210\u7684\u5199\u4F5C\u98CE\u683C\u3002
2383
+
2384
+ ## \u8BED\u6C14
2385
+
2386
+ ${profile.tone}
2387
+
2388
+ ## \u53E5\u5F0F\u7279\u5F81
2389
+
2390
+ ${profile.sentencePattern}
2391
+
2392
+ ## \u7ED3\u6784\u6A21\u677F
2393
+
2394
+ ${profile.structure}
2395
+
2396
+ ## \u7528\u8BCD\u7279\u70B9
2397
+
2398
+ ${profile.vocabulary}
2399
+
2400
+ ## \u5F00\u5934\u98CE\u683C
2401
+
2402
+ ${profile.openingStyle}
2403
+
2404
+ ## \u7ED3\u5C3E\u98CE\u683C
2405
+
2406
+ ${profile.closingStyle}
2407
+ ${profile.specialHabits.length > 0 ? `
2408
+ ## \u7279\u6B8A\u4E60\u60EF
2409
+
2410
+ ${profile.specialHabits.map((h) => `- ${h}`).join("\n")}` : ""}`;
2411
+ const stylesDir = join2(this.wxclawDir, "styles");
2412
+ if (!existsSync(stylesDir)) {
2413
+ mkdirSync(stylesDir, { recursive: true });
2414
+ }
2415
+ const id = name.toLowerCase().replace(/\s+/g, "-");
2416
+ const filePath = join2(stylesDir, `${id}.md`);
2417
+ writeFileSync(filePath, systemPrompt, "utf-8");
2418
+ return {
2419
+ id,
2420
+ name,
2421
+ type: "learned",
2422
+ systemPrompt,
2423
+ profile,
2424
+ sampleTexts,
2425
+ source: filePath
2426
+ };
2427
+ }
2428
+ };
2429
+
2430
+ // src/utils/mock-llm.ts
2431
+ var mockLLMClient = {
2432
+ async chat({ messages }) {
2433
+ const lastMessage = messages[messages.length - 1]?.content ?? "";
2434
+ if (lastMessage.includes("\u9009\u9898") || lastMessage.includes("\u89D2\u5EA6")) {
2435
+ return {
2436
+ content: JSON.stringify({
2437
+ title: "AI \u5982\u4F55\u91CD\u5851\u6559\u80B2\u884C\u4E1A\u7684\u672A\u6765",
2438
+ angle: "\u4ECE\u6559\u5E08\u3001\u5B66\u751F\u3001\u5BB6\u957F\u4E09\u4E2A\u89C6\u89D2\u5206\u6790 AI \u6559\u80B2\u5DE5\u5177\u7684\u5B9E\u9645\u5F71\u54CD",
2439
+ keywords: ["AI \u6559\u80B2", "\u4E2A\u6027\u5316\u5B66\u4E60", "\u6559\u80B2\u79D1\u6280"]
2440
+ })
2441
+ };
2442
+ }
2443
+ if ((lastMessage.includes("\u5927\u7EB2") || lastMessage.includes("outline")) && !lastMessage.includes("\u64B0\u5199")) {
2444
+ return {
2445
+ content: JSON.stringify({
2446
+ title: "AI \u5982\u4F55\u91CD\u5851\u6559\u80B2\u884C\u4E1A\u7684\u672A\u6765",
2447
+ sections: [
2448
+ {
2449
+ heading: "\u5F15\u8A00\uFF1A\u5F53 ChatGPT \u8D70\u8FDB\u8BFE\u5802",
2450
+ points: ["\u4E00\u4E2A\u771F\u5B9E\u7684\u8BFE\u5802\u6545\u4E8B", "AI \u6559\u80B2\u5DE5\u5177\u7684\u7206\u53D1\u5F0F\u589E\u957F\u6570\u636E"]
2451
+ },
2452
+ {
2453
+ heading: "\u6559\u5E08\u89C6\u89D2\uFF1A\u662F\u66FF\u4EE3\u8FD8\u662F\u8D4B\u80FD\uFF1F",
2454
+ points: ["AI \u6279\u6539\u4F5C\u4E1A\u7684\u6548\u7387\u63D0\u5347", "\u6559\u5E08\u89D2\u8272\u7684\u8F6C\u53D8", "\u65E0\u6CD5\u66FF\u4EE3\u7684\u4EBA\u6587\u5173\u6000"]
2455
+ },
2456
+ {
2457
+ heading: "\u5B66\u751F\u89C6\u89D2\uFF1A\u4E2A\u6027\u5316\u5B66\u4E60\u7684\u65B0\u65F6\u4EE3",
2458
+ points: ["\u81EA\u9002\u5E94\u5B66\u4E60\u8DEF\u5F84", "AI \u8F85\u5BFC\u7684\u4F18\u52BF\u4E0E\u9677\u9631", "\u6279\u5224\u6027\u601D\u7EF4\u7684\u57F9\u517B\u6311\u6218"]
2459
+ },
2460
+ {
2461
+ heading: "\u5BB6\u957F\u89C6\u89D2\uFF1A\u7126\u8651\u4E0E\u671F\u5F85\u5E76\u5B58",
2462
+ points: ["\u5BF9 AI \u4F9D\u8D56\u7684\u62C5\u5FE7", "\u6559\u80B2\u516C\u5E73\u7684\u65B0\u673A\u9047", "\u5982\u4F55\u5F15\u5BFC\u5B69\u5B50\u6B63\u786E\u4F7F\u7528 AI"]
2463
+ },
2464
+ {
2465
+ heading: "\u7ED3\u8BED\uFF1A\u62E5\u62B1\u53D8\u5316\uFF0C\u5B88\u4F4F\u5E95\u7EBF",
2466
+ points: ["AI \u6559\u80B2\u7684\u4E09\u6761\u5E95\u7EBF", "\u5BF9\u672A\u6765\u7684\u5C55\u671B"]
2467
+ }
2468
+ ]
2469
+ })
2470
+ };
2471
+ }
2472
+ return {
2473
+ content: `# AI \u5982\u4F55\u91CD\u5851\u6559\u80B2\u884C\u4E1A\u7684\u672A\u6765
2474
+
2475
+ > \u4ECE\u6559\u5E08\u3001\u5B66\u751F\u3001\u5BB6\u957F\u4E09\u4E2A\u89C6\u89D2\uFF0C\u770B AI \u6559\u80B2\u5DE5\u5177\u7684\u771F\u5B9E\u5F71\u54CD
2476
+
2477
+ \u5F53 ChatGPT \u7B2C\u4E00\u6B21\u88AB\u5E26\u8FDB\u5317\u4EAC\u67D0\u4E2D\u5B66\u7684\u8BED\u6587\u8BFE\u5802\u65F6\uFF0C\u8BED\u6587\u8001\u5E08\u5F20\u8001\u5E08\u7684\u7B2C\u4E00\u53CD\u5E94\u4E0D\u662F\u5174\u594B\uFF0C\u800C\u662F\u6050\u614C\u3002"\u5982\u679C\u5B66\u751F\u7528 AI \u5199\u4F5C\u6587\uFF0C\u6211\u8FD8\u600E\u4E48\u6559\uFF1F"
2478
+
2479
+ \u8FD9\u4E2A\u95EE\u9898\uFF0C\u6B63\u5728\u5168\u7403\u6570\u767E\u4E07\u6559\u5E08\u7684\u8111\u6D77\u4E2D\u56DE\u54CD\u3002
2480
+
2481
+ ## \u6559\u5E08\u89C6\u89D2\uFF1A\u662F\u66FF\u4EE3\u8FD8\u662F\u8D4B\u80FD\uFF1F
2482
+
2483
+ \u6570\u636E\u663E\u793A\uFF0C\u4F7F\u7528 AI \u6279\u6539\u5DE5\u5177\u540E\uFF0C\u6559\u5E08\u6279\u6539\u4F5C\u4E1A\u7684\u65F6\u95F4\u5E73\u5747\u51CF\u5C11\u4E86 60%\u3002\u4F46\u8FD9\u5E76\u4E0D\u610F\u5473\u7740\u6559\u5E08\u53D8\u5F97\u591A\u4F59\u2014\u2014\u6070\u6070\u76F8\u53CD\uFF0C\u4ED6\u4EEC\u6709\u4E86\u66F4\u591A\u65F6\u95F4\u505A\u771F\u6B63\u91CD\u8981\u7684\u4E8B\uFF1A\u4E0E\u5B66\u751F\u4E00\u5BF9\u4E00\u4EA4\u6D41\uFF0C\u8BBE\u8BA1\u66F4\u6709\u521B\u610F\u7684\u6559\u5B66\u6D3B\u52A8\u3002
2484
+
2485
+ **\u6559\u5E08\u7684\u89D2\u8272\u6B63\u5728\u4ECE"\u77E5\u8BC6\u4F20\u9012\u8005"\u8F6C\u53D8\u4E3A"\u5B66\u4E60\u5F15\u5BFC\u8005"\u3002**
2486
+
2487
+ ## \u5B66\u751F\u89C6\u89D2\uFF1A\u4E2A\u6027\u5316\u5B66\u4E60\u7684\u65B0\u65F6\u4EE3
2488
+
2489
+ \u6BCF\u4E2A\u5B66\u751F\u7684\u5B66\u4E60\u8282\u594F\u4E0D\u540C\uFF0C\u4F20\u7EDF\u8BFE\u5802\u5F88\u96BE\u517C\u987E\u3002AI \u81EA\u9002\u5E94\u5B66\u4E60\u7CFB\u7EDF\u53EF\u4EE5\u6839\u636E\u6BCF\u4E2A\u5B66\u751F\u7684\u638C\u63E1\u7A0B\u5EA6\uFF0C\u52A8\u6001\u8C03\u6574\u7EC3\u4E60\u96BE\u5EA6\u548C\u77E5\u8BC6\u70B9\u63A8\u8350\u3002
2490
+
2491
+ \u4F46\u786C\u5E01\u7684\u53E6\u4E00\u9762\u662F\uFF1A\u8FC7\u5EA6\u4F9D\u8D56 AI \u8F85\u5BFC\u53EF\u80FD\u524A\u5F31\u5B66\u751F\u72EC\u7ACB\u601D\u8003\u7684\u80FD\u529B\u3002
2492
+
2493
+ ## \u5BB6\u957F\u89C6\u89D2\uFF1A\u7126\u8651\u4E0E\u671F\u5F85\u5E76\u5B58
2494
+
2495
+ "\u522B\u7684\u5B69\u5B50\u90FD\u5728\u7528 AI \u5B66\u4E60\uFF0C\u6211\u5BB6\u5B69\u5B50\u4E0D\u7528\u4F1A\u4E0D\u4F1A\u843D\u540E\uFF1F"\u8FD9\u662F\u5F88\u591A\u5BB6\u957F\u7684\u771F\u5B9E\u7126\u8651\u3002
2496
+
2497
+ \u597D\u6D88\u606F\u662F\uFF0CAI \u6559\u80B2\u5DE5\u5177\u6B63\u5728\u8BA9\u4F18\u8D28\u6559\u80B2\u8D44\u6E90\u53D8\u5F97\u66F4\u52A0\u666E\u60E0\u3002\u574F\u6D88\u606F\u662F\uFF0C\u5982\u4F55\u5F15\u5BFC\u5B69\u5B50\u6B63\u786E\u4F7F\u7528 AI\uFF0C\u6210\u4E86\u4E00\u4E2A\u5168\u65B0\u7684\u80B2\u513F\u8BFE\u9898\u3002
2498
+
2499
+ ## \u62E5\u62B1\u53D8\u5316\uFF0C\u5B88\u4F4F\u5E95\u7EBF
2500
+
2501
+ AI \u4E0D\u4F1A\u53D6\u4EE3\u6559\u80B2\uFF0C\u4F46\u4F1A\u6DF1\u523B\u6539\u53D8\u6559\u80B2\u7684\u5F62\u6001\u3002\u5728\u8FD9\u573A\u53D8\u9769\u4E2D\uFF0C\u6211\u4EEC\u9700\u8981\u5B88\u4F4F\u4E09\u6761\u5E95\u7EBF\uFF1A
2502
+
2503
+ 1. **\u6280\u672F\u670D\u52A1\u4E8E\u6559\u80B2\uFF0C\u800C\u975E\u6559\u80B2\u670D\u52A1\u4E8E\u6280\u672F**
2504
+ 2. **\u57F9\u517B\u601D\u7EF4\u80FD\u529B\uFF0C\u800C\u975E\u4F9D\u8D56\u73B0\u6210\u7B54\u6848**
2505
+ 3. **\u4FDD\u6301\u4EBA\u4E0E\u4EBA\u4E4B\u95F4\u7684\u771F\u5B9E\u8FDE\u63A5**
2506
+
2507
+ \u672A\u6765\u5DF2\u6765\uFF0C\u5173\u952E\u662F\u6211\u4EEC\u5982\u4F55\u9009\u62E9\u3002
2508
+
2509
+ ---
2510
+
2511
+ *\u4F60\u5BF9 AI \u6559\u80B2\u6709\u4EC0\u4E48\u770B\u6CD5\uFF1F\u6B22\u8FCE\u5728\u8BC4\u8BBA\u533A\u5206\u4EAB\u4F60\u7684\u89C2\u70B9\u3002*
2512
+ `
2513
+ };
2514
+ }
2515
+ };
2516
+
2517
+ // src/commands/create.ts
2518
+ async function createRealLLMClient() {
2519
+ const {
2520
+ createMinimaxProvider: createMinimaxProvider2,
2521
+ createDeepSeekProvider: createDeepSeekProvider2,
2522
+ ProviderRegistry: ProviderRegistry2,
2523
+ executeWithFailover: executeWithFailover2
2524
+ } = await Promise.resolve().then(() => (init_dist(), dist_exports));
2525
+ const registry = new ProviderRegistry2();
2526
+ const minimax = createMinimaxProvider2();
2527
+ const deepseek = createDeepSeekProvider2();
2528
+ if (minimax.isConfigured()) registry.register(minimax);
2529
+ if (deepseek.isConfigured()) registry.register(deepseek);
2530
+ if (registry.list().length === 0) {
2531
+ console.error(chalk.red("\u6CA1\u6709\u53EF\u7528\u7684 LLM Provider\u3002\u8BF7\u5728 .wxclaw/config.json \u4E2D\u914D\u7F6E API Key\u3002"));
2532
+ console.error(chalk.gray(' \u6216\u4F7F\u7528 --mock \u6A21\u5F0F\uFF1Awxclaw create --mock --topic "\u4E3B\u9898"'));
2533
+ process.exit(1);
2534
+ }
2535
+ return {
2536
+ async chat({ messages, temperature, maxTokens }) {
2537
+ return executeWithFailover2(
2538
+ "writing",
2539
+ async (provider) => {
2540
+ const response = await provider.chat({ messages, temperature, maxTokens });
2541
+ return { content: response.content };
2542
+ },
2543
+ registry,
2544
+ {
2545
+ stepProviders: {},
2546
+ globalFallbackOrder: registry.list().map((p) => p.id),
2547
+ rateLimitBackoffMs: 3e3
2548
+ }
2549
+ );
2550
+ }
2551
+ };
2552
+ }
2553
+ function withSpinner(step, label, successLabel) {
2554
+ return {
2555
+ id: step.id,
2556
+ type: step.type,
2557
+ gate: step.gate,
2558
+ async execute(context) {
2559
+ const spinner = ora(chalk.cyan(label)).start();
2560
+ try {
2561
+ const result = await step.execute(context);
2562
+ if (result.success) {
2563
+ spinner.succeed(chalk.green(successLabel));
2564
+ } else {
2565
+ spinner.fail(chalk.red(`${successLabel} \u2014 \u5931\u8D25: ${result.error ?? ""}`));
2566
+ }
2567
+ return result;
2568
+ } catch (err) {
2569
+ spinner.fail(chalk.red(`${successLabel} \u2014 \u5931\u8D25`));
2570
+ throw err;
2571
+ }
2572
+ }
2573
+ };
2574
+ }
2575
+ var createCommand = new Command("create").description("\u521B\u5EFA\u516C\u4F17\u53F7\u6587\u7AE0").requiredOption("--topic <topic>", "\u6587\u7AE0\u4E3B\u9898").option("--style <style>", "\u5199\u4F5C\u98CE\u683C", "tech").option("--mock", "\u4F7F\u7528 Mock LLM\uFF08\u4E0D\u9700\u8981 API Key\uFF09").action(async (options) => {
2576
+ console.log(chalk.cyan("WxClaw \u6587\u7AE0\u521B\u4F5C"));
2577
+ console.log(chalk.gray("\u2501".repeat(50)));
2578
+ console.log(`\u4E3B\u9898\uFF1A${chalk.bold(options.topic)}`);
2579
+ console.log(`\u98CE\u683C\uFF1A${chalk.bold(options.style)}`);
2580
+ console.log(`\u6A21\u5F0F\uFF1A${chalk.bold(options.mock ? "Mock LLM" : "\u771F\u5B9E API")}`);
2581
+ console.log(chalk.gray("\u2501".repeat(50)));
2582
+ const llmClient = options.mock ? mockLLMClient : await createRealLLMClient();
2583
+ let pipelineConfig;
2584
+ try {
2585
+ pipelineConfig = loadPipelineConfig(options.style);
2586
+ } catch {
2587
+ pipelineConfig = {
2588
+ soulPrompt: "\u4F60\u662F\u4E00\u4F4D\u4E13\u4E1A\u7684\u516C\u4F17\u53F7\u5185\u5BB9\u521B\u4F5C\u8005\u3002",
2589
+ stylePrompt: "",
2590
+ agentsRules: ""
2591
+ };
2592
+ }
2593
+ const mockDraftClient = {
2594
+ async addDraft(_articles) {
2595
+ return `draft-${Date.now()}`;
2596
+ }
2597
+ };
2598
+ const steps = [
2599
+ withSpinner(new TopicSelectionStep(llmClient), "\u6B63\u5728\u9009\u9898...", "\u9009\u9898\u5B8C\u6210"),
2600
+ withSpinner(new OutlineStep(llmClient), "\u6B63\u5728\u751F\u6210\u5927\u7EB2...", "\u5927\u7EB2\u5B8C\u6210"),
2601
+ withSpinner(new WritingStep(llmClient), "\u6B63\u5728\u64B0\u5199\u6587\u7AE0...", "\u6587\u7AE0\u5B8C\u6210"),
2602
+ withSpinner(new FormattingStep(), "\u6B63\u5728\u6392\u7248...", "\u6392\u7248\u5B8C\u6210"),
2603
+ withSpinner(new DraftPublishStep(mockDraftClient), "\u6B63\u5728\u4FDD\u5B58\u8349\u7A3F...", "\u8349\u7A3F\u4FDD\u5B58\u5B8C\u6210")
2604
+ ];
2605
+ const context = {
2606
+ pipelineId: `create-${Date.now()}`,
2607
+ userId: "cli-user",
2608
+ data: {
2609
+ topic: { title: options.topic, angle: "", keywords: [] }
2610
+ },
2611
+ status: "running",
2612
+ logs: [],
2613
+ config: pipelineConfig
2614
+ };
2615
+ const engine = new PipelineEngine({ defaultTimeout: 12e4 });
2616
+ let result;
2617
+ try {
2618
+ result = await engine.run(steps, context);
2619
+ } catch (err) {
2620
+ console.error(chalk.red("\nPipeline \u6267\u884C\u5931\u8D25\uFF1A"), err);
2621
+ process.exit(1);
2622
+ }
2623
+ console.log("\n" + chalk.gray("\u2501".repeat(50)));
2624
+ console.log(`\u72B6\u6001\uFF1A${result.status === "completed" ? chalk.green("\u5B8C\u6210") : chalk.red(result.status)}`);
2625
+ const totalMs = result.logs.reduce((s, l) => s + l.duration, 0);
2626
+ console.log(`\u8017\u65F6\uFF1A${totalMs}ms`);
2627
+ console.log(chalk.gray("\u2501".repeat(50)));
2628
+ if (result.data.topic) {
2629
+ console.log("\n" + chalk.bold.cyan("\u9009\u9898"));
2630
+ console.log(` \u6807\u9898\uFF1A${result.data.topic.title}`);
2631
+ console.log(` \u89D2\u5EA6\uFF1A${result.data.topic.angle}`);
2632
+ if (result.data.topic.keywords?.length) {
2633
+ console.log(` \u5173\u952E\u8BCD\uFF1A${result.data.topic.keywords.join("\u3001")}`);
2634
+ }
2635
+ }
2636
+ if (result.data.outline) {
2637
+ console.log("\n" + chalk.bold.cyan("\u5927\u7EB2"));
2638
+ console.log(` ${result.data.outline.title}`);
2639
+ result.data.outline.sections.forEach((s, i) => {
2640
+ console.log(` ${i + 1}. ${s.heading}`);
2641
+ });
2642
+ }
2643
+ if (result.data.article) {
2644
+ const preview = result.data.article.content.slice(0, 300);
2645
+ const truncated = result.data.article.content.length > 300;
2646
+ console.log("\n" + chalk.bold.cyan("\u6587\u7AE0\u9884\u89C8\uFF08\u524D 300 \u5B57\uFF09"));
2647
+ console.log(chalk.gray("\u2500".repeat(40)));
2648
+ console.log(preview + (truncated ? chalk.gray("\n...(\u7701\u7565)") : ""));
2649
+ console.log(chalk.gray("\u2500".repeat(40)));
2650
+ console.log(` \u5B57\u6570\uFF1A${result.data.article.wordCount}`);
2651
+ }
2652
+ if (result.data.draftId) {
2653
+ console.log(`
2654
+ \u8349\u7A3F ID\uFF1A${chalk.bold(result.data.draftId)}`);
2655
+ }
2656
+ console.log("\n" + chalk.green("Pipeline \u5B8C\u6210\uFF01\uFF085 Step \u7AEF\u5230\u7AEF\uFF09"));
2657
+ });
2658
+
2659
+ // src/commands/config.ts
2660
+ import { Command as Command2 } from "commander";
2661
+ import chalk2 from "chalk";
2662
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync2 } from "fs";
2663
+ import { join as join4, dirname } from "path";
2664
+ var CONFIG_PATH = join4(process.cwd(), ".wxclaw", "config.json");
2665
+ function readConfig() {
2666
+ if (!existsSync3(CONFIG_PATH)) return {};
2667
+ return JSON.parse(readFileSync4(CONFIG_PATH, "utf-8"));
2668
+ }
2669
+ function writeConfig(config) {
2670
+ const dir = dirname(CONFIG_PATH);
2671
+ if (!existsSync3(dir)) mkdirSync2(dir, { recursive: true });
2672
+ writeFileSync2(CONFIG_PATH, JSON.stringify(config, null, 2), "utf-8");
2673
+ }
2674
+ function getByDotPath(obj, path) {
2675
+ return path.split(".").reduce((cur, key) => {
2676
+ if (cur != null && typeof cur === "object") {
2677
+ return cur[key];
2678
+ }
2679
+ return void 0;
2680
+ }, obj);
2681
+ }
2682
+ function setByDotPath(obj, path, value) {
2683
+ const keys = path.split(".");
2684
+ let cur = obj;
2685
+ for (let i = 0; i < keys.length - 1; i++) {
2686
+ const key = keys[i];
2687
+ if (cur[key] == null || typeof cur[key] !== "object") {
2688
+ cur[key] = {};
2689
+ }
2690
+ cur = cur[key];
2691
+ }
2692
+ cur[keys[keys.length - 1]] = value;
2693
+ }
2694
+ function maskApiKey(val) {
2695
+ if (val.length <= 6) return "***";
2696
+ return `***${val.slice(-3)}`;
2697
+ }
2698
+ function maskConfig(obj) {
2699
+ if (obj == null || typeof obj !== "object") return obj;
2700
+ const result = {};
2701
+ for (const [k2, v2] of Object.entries(obj)) {
2702
+ if (k2.toLowerCase().includes("apikey") && typeof v2 === "string") {
2703
+ result[k2] = maskApiKey(v2);
2704
+ } else if (typeof v2 === "object" && v2 !== null) {
2705
+ result[k2] = maskConfig(v2);
2706
+ } else {
2707
+ result[k2] = v2;
2708
+ }
2709
+ }
2710
+ return result;
2711
+ }
2712
+ var configCommand = new Command2("config").description("\u7BA1\u7406 WxClaw \u914D\u7F6E");
2713
+ configCommand.command("set <key> <value>").description("\u8BBE\u7F6E\u914D\u7F6E\u9879\uFF08\u5982 providers.minimax.apiKey\uFF09").action((key, value) => {
2714
+ if (value.trim() === "") {
2715
+ console.error(chalk2.red("\u9519\u8BEF\uFF1Avalue \u4E0D\u80FD\u4E3A\u7A7A"));
2716
+ process.exit(1);
2717
+ }
2718
+ const config = readConfig();
2719
+ setByDotPath(config, key, value);
2720
+ writeConfig(config);
2721
+ const displayValue = key.toLowerCase().includes("apikey") ? maskApiKey(value) : value;
2722
+ console.log(chalk2.green(`\u2714 \u5DF2\u8BBE\u7F6E ${chalk2.bold(key)} = ${displayValue}`));
2723
+ });
2724
+ configCommand.command("get <key>").description("\u83B7\u53D6\u914D\u7F6E\u9879").action((key) => {
2725
+ const config = readConfig();
2726
+ const raw = getByDotPath(config, key);
2727
+ if (raw === void 0) {
2728
+ console.log(chalk2.yellow(`\u914D\u7F6E\u9879 ${chalk2.bold(key)} \u672A\u8BBE\u7F6E`));
2729
+ return;
2730
+ }
2731
+ const display = key.toLowerCase().includes("apikey") && typeof raw === "string" ? maskApiKey(raw) : String(raw);
2732
+ console.log(`${chalk2.bold(key)}: ${display}`);
2733
+ });
2734
+ configCommand.command("list").description("\u663E\u793A\u6240\u6709\u914D\u7F6E\uFF08API Key \u8131\u654F\uFF09").action(() => {
2735
+ const config = readConfig();
2736
+ if (Object.keys(config).length === 0) {
2737
+ console.log(chalk2.yellow("\u6682\u65E0\u914D\u7F6E\u3002\u4F7F\u7528 wxclaw config set <key> <value> \u6765\u8BBE\u7F6E\u3002"));
2738
+ return;
2739
+ }
2740
+ const masked = maskConfig(config);
2741
+ console.log(chalk2.cyan("WxClaw \u914D\u7F6E\uFF08.wxclaw/config.json\uFF09\uFF1A"));
2742
+ console.log(chalk2.gray("\u2500".repeat(50)));
2743
+ console.log(JSON.stringify(masked, null, 2));
2744
+ });
2745
+
2746
+ // src/commands/topics.ts
2747
+ import { Command as Command3 } from "commander";
2748
+ import chalk3 from "chalk";
2749
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
2750
+ import { join as join5 } from "path";
2751
+ var CACHE_PATH = join5(process.cwd(), ".wxclaw", "topics-cache.json");
2752
+ var MOCK_TOPICS = [
2753
+ { title: "AI Agent 2026\u8D8B\u52BF", heat: 95, source: "weibo" },
2754
+ { title: "GPT-5.4 \u53D1\u5E03", heat: 88, source: "zhihu" },
2755
+ { title: "DeepSeek V4 \u5F00\u6E90", heat: 82, source: "weibo" },
2756
+ { title: "\u56FD\u4EA7\u5927\u6A21\u578B\u5546\u4E1A\u5316\u63D0\u901F", heat: 78, source: "zhihu" },
2757
+ { title: "AI \u7F16\u7A0B\u52A9\u624B\u666E\u53CA\u7387\u7A81\u7834 60%", heat: 75, source: "weibo" },
2758
+ { title: "\u591A\u6A21\u6001\u6A21\u578B\u7EDF\u4E00\u89C6\u89C9\u4E0E\u8BED\u8A00", heat: 70, source: "zhihu" },
2759
+ { title: "\u4F01\u4E1A AI \u6CBB\u7406\u767D\u76AE\u4E66\u53D1\u5E03", heat: 65, source: "weibo" },
2760
+ { title: "Robotics + LLM \u878D\u5408\u65B0\u8FDB\u5C55", heat: 60, source: "zhihu" }
2761
+ ];
2762
+ function heatBar(heat) {
2763
+ const filled = Math.round(heat / 10);
2764
+ return chalk3.red("\u2588".repeat(filled)) + chalk3.gray("\u2591".repeat(10 - filled));
2765
+ }
2766
+ function printTopics(topics) {
2767
+ console.log(chalk3.cyan("\u70ED\u70B9\u8BDD\u9898"));
2768
+ console.log(chalk3.gray("\u2500".repeat(60)));
2769
+ console.log(
2770
+ chalk3.bold(
2771
+ `${"#".padEnd(4)}${"\u70ED\u5EA6".padEnd(16)}${"\u6765\u6E90".padEnd(8)}\u6807\u9898`
2772
+ )
2773
+ );
2774
+ console.log(chalk3.gray("\u2500".repeat(60)));
2775
+ topics.forEach((t, i) => {
2776
+ const idx = String(i + 1).padEnd(4);
2777
+ const bar = heatBar(t.heat);
2778
+ const src = t.source.padEnd(8);
2779
+ console.log(`${chalk3.gray(idx)}${bar} ${chalk3.yellow(String(t.heat).padStart(2))} ${chalk3.blue(src)}${t.title}`);
2780
+ });
2781
+ console.log(chalk3.gray("\u2500".repeat(60)));
2782
+ console.log(chalk3.gray(`\u5171 ${topics.length} \u6761\u70ED\u70B9`));
2783
+ }
2784
+ function saveCache(topics) {
2785
+ const dir = join5(process.cwd(), ".wxclaw");
2786
+ if (!existsSync4(dir)) mkdirSync3(dir, { recursive: true });
2787
+ writeFileSync3(CACHE_PATH, JSON.stringify({ fetchedAt: (/* @__PURE__ */ new Date()).toISOString(), topics }, null, 2), "utf-8");
2788
+ }
2789
+ var topicsCommand = new Command3("topics").description("\u70ED\u70B9\u8BDD\u9898\u7BA1\u7406");
2790
+ topicsCommand.command("fetch").description("\u6293\u53D6\u6700\u65B0\u70ED\u70B9").option("--source <source>", "\u6307\u5B9A\u5E73\u53F0\uFF08weibo/zhihu\uFF09").option("--mock", "\u4F7F\u7528 Mock \u6570\u636E").action(async (options) => {
2791
+ if (options.mock) {
2792
+ let topics = MOCK_TOPICS;
2793
+ if (options.source) {
2794
+ topics = topics.filter((t) => t.source === options.source);
2795
+ if (topics.length === 0) {
2796
+ console.log(chalk3.yellow(`\u6CA1\u6709\u6765\u81EA ${options.source} \u7684 Mock \u6570\u636E`));
2797
+ return;
2798
+ }
2799
+ }
2800
+ console.log(chalk3.cyan(`\u6B63\u5728\u83B7\u53D6\u70ED\u70B9\uFF08Mock \u6A21\u5F0F${options.source ? ` - ${options.source}` : ""}\uFF09...`));
2801
+ saveCache(topics);
2802
+ printTopics(topics);
2803
+ console.log(chalk3.green("\n\u5DF2\u7F13\u5B58\u5230 .wxclaw/topics-cache.json"));
2804
+ return;
2805
+ }
2806
+ try {
2807
+ const { ScraperRegistry, TopicAggregator } = await import("@wechat-agent/scrapers");
2808
+ const registry = new ScraperRegistry();
2809
+ const aggregator = new TopicAggregator();
2810
+ const raw = await registry.fetchAll(options.source);
2811
+ const topics = aggregator.aggregate(raw);
2812
+ saveCache(topics);
2813
+ printTopics(topics);
2814
+ console.log(chalk3.green("\n\u5DF2\u7F13\u5B58\u5230 .wxclaw/topics-cache.json"));
2815
+ } catch {
2816
+ console.log(chalk3.yellow("scrapers \u5305\u5C1A\u672A\u53EF\u7528\uFF0C\u8BF7\u4F7F\u7528 --mock \u6A21\u5F0F\uFF1A"));
2817
+ console.log(chalk3.gray(" wxclaw topics fetch --mock"));
2818
+ }
2819
+ });
2820
+ topicsCommand.command("list").description("\u663E\u793A\u7F13\u5B58\u7684\u70ED\u70B9\u8BDD\u9898").action(() => {
2821
+ if (!existsSync4(CACHE_PATH)) {
2822
+ console.log(chalk3.yellow("\u6682\u65E0\u7F13\u5B58\u6570\u636E\u3002\u8BF7\u5148\u8FD0\u884C\uFF1A"));
2823
+ console.log(chalk3.gray(" wxclaw topics fetch --mock"));
2824
+ return;
2825
+ }
2826
+ const raw = JSON.parse(readFileSync5(CACHE_PATH, "utf-8"));
2827
+ console.log(chalk3.gray(`\u7F13\u5B58\u65F6\u95F4\uFF1A${raw.fetchedAt}`));
2828
+ printTopics(raw.topics);
2829
+ });
2830
+
2831
+ // src/commands/cron.ts
2832
+ import { Command as Command4 } from "commander";
2833
+ import chalk4 from "chalk";
2834
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync5, mkdirSync as mkdirSync4 } from "fs";
2835
+ import { join as join6 } from "path";
2836
+ var TASKS_PATH = join6(process.cwd(), ".wxclaw", "scheduler-tasks.json");
2837
+ function loadTasks() {
2838
+ if (!existsSync5(TASKS_PATH)) {
2839
+ return [];
2840
+ }
2841
+ try {
2842
+ const raw = readFileSync6(TASKS_PATH, "utf-8");
2843
+ return JSON.parse(raw);
2844
+ } catch {
2845
+ return [];
2846
+ }
2847
+ }
2848
+ function saveTasks(tasks) {
2849
+ const dir = join6(process.cwd(), ".wxclaw");
2850
+ if (!existsSync5(dir)) {
2851
+ mkdirSync4(dir, { recursive: true });
2852
+ }
2853
+ writeFileSync4(TASKS_PATH, JSON.stringify(tasks, null, 2), "utf-8");
2854
+ }
2855
+ function generateId() {
2856
+ return `task-${Date.now().toString(36)}`;
2857
+ }
2858
+ function checkRedis() {
2859
+ return !!process.env["REDIS_URL"];
2860
+ }
2861
+ var cronCommand = new Command4("cron").description("\u5B9A\u65F6\u4EFB\u52A1\u7BA1\u7406");
2862
+ cronCommand.command("list").description("\u663E\u793A\u6240\u6709\u5B9A\u65F6\u4EFB\u52A1").action(() => {
2863
+ const tasks = loadTasks();
2864
+ if (tasks.length === 0) {
2865
+ console.log(chalk4.yellow("\u6682\u65E0\u5B9A\u65F6\u4EFB\u52A1\u3002\u4F7F\u7528 wxclaw cron add \u521B\u5EFA\u4EFB\u52A1\u3002"));
2866
+ return;
2867
+ }
2868
+ console.log(
2869
+ chalk4.bold(
2870
+ `${"ID".padEnd(16)}${"\u72B6\u6001".padEnd(8)}${"Cron".padEnd(16)}${"\u6B65\u9AA4".padEnd(14)}\u540D\u79F0`
2871
+ )
2872
+ );
2873
+ console.log(chalk4.gray("\u2500".repeat(70)));
2874
+ for (const task of tasks) {
2875
+ const status = task.enabled ? chalk4.green("\u542F\u7528".padEnd(8)) : chalk4.gray("\u7981\u7528".padEnd(8));
2876
+ console.log(
2877
+ `${chalk4.cyan(task.id.padEnd(16))}${status}${chalk4.yellow(task.cron.padEnd(16))}${task.step.padEnd(14)}${task.name}`
2878
+ );
2879
+ }
2880
+ console.log(chalk4.gray("\u2500".repeat(70)));
2881
+ console.log(chalk4.gray(`\u5171 ${tasks.length} \u4E2A\u5B9A\u65F6\u4EFB\u52A1`));
2882
+ if (!checkRedis()) {
2883
+ console.log(
2884
+ chalk4.yellow(
2885
+ "\n\u63D0\u793A\uFF1A\u672A\u68C0\u6D4B\u5230 Redis\uFF08REDIS_URL \u672A\u8BBE\u7F6E\uFF09\uFF0C\u5B9A\u65F6\u4EFB\u52A1\u65E0\u6CD5\u81EA\u52A8\u89E6\u53D1\u3002"
2886
+ )
2887
+ );
2888
+ }
2889
+ });
2890
+ cronCommand.command("add").description("\u521B\u5EFA\u5B9A\u65F6\u4EFB\u52A1").requiredOption("--name <name>", "\u4EFB\u52A1\u540D\u79F0").requiredOption("--step <type>", "\u6B65\u9AA4\u7C7B\u578B\uFF08\u5982 topic-discovery, writing\uFF09").requiredOption("--cron <expression>", "Cron \u8868\u8FBE\u5F0F\uFF08\u5982 '0 8 * * *'\uFF09").action((options) => {
2891
+ const tasks = loadTasks();
2892
+ const task = {
2893
+ id: generateId(),
2894
+ name: options.name,
2895
+ step: options.step,
2896
+ cron: options.cron,
2897
+ enabled: true,
2898
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2899
+ logs: []
2900
+ };
2901
+ tasks.push(task);
2902
+ saveTasks(tasks);
2903
+ console.log(chalk4.green(`\u5DF2\u521B\u5EFA\u5B9A\u65F6\u4EFB\u52A1\uFF1A${task.name}\uFF08ID: ${task.id}\uFF09`));
2904
+ console.log(chalk4.gray(` \u6B65\u9AA4\uFF1A${task.step}`));
2905
+ console.log(chalk4.gray(` \u8BA1\u5212\uFF1A${task.cron}`));
2906
+ if (!checkRedis()) {
2907
+ console.log(
2908
+ chalk4.yellow(
2909
+ "\n\u8B66\u544A\uFF1A\u672A\u68C0\u6D4B\u5230 Redis\uFF08REDIS_URL \u672A\u8BBE\u7F6E\uFF09\uFF0C\u5B9A\u65F6\u4EFB\u52A1\u4EC5\u4FDD\u5B58\u5230\u672C\u5730\uFF0C\u65E0\u6CD5\u81EA\u52A8\u89E6\u53D1\u3002"
2910
+ )
2911
+ );
2912
+ }
2913
+ });
2914
+ cronCommand.command("enable <id>").description("\u542F\u7528\u5B9A\u65F6\u4EFB\u52A1").action((id) => {
2915
+ const tasks = loadTasks();
2916
+ const task = tasks.find((t) => t.id === id);
2917
+ if (!task) {
2918
+ console.log(chalk4.red(`\u4EFB\u52A1\u4E0D\u5B58\u5728\uFF1A${id}`));
2919
+ process.exit(1);
2920
+ }
2921
+ task.enabled = true;
2922
+ saveTasks(tasks);
2923
+ console.log(chalk4.green(`\u5DF2\u542F\u7528\u4EFB\u52A1\uFF1A${task.name}\uFF08${id}\uFF09`));
2924
+ });
2925
+ cronCommand.command("disable <id>").description("\u7981\u7528\u5B9A\u65F6\u4EFB\u52A1").action((id) => {
2926
+ const tasks = loadTasks();
2927
+ const task = tasks.find((t) => t.id === id);
2928
+ if (!task) {
2929
+ console.log(chalk4.red(`\u4EFB\u52A1\u4E0D\u5B58\u5728\uFF1A${id}`));
2930
+ process.exit(1);
2931
+ }
2932
+ task.enabled = false;
2933
+ saveTasks(tasks);
2934
+ console.log(chalk4.green(`\u5DF2\u7981\u7528\u4EFB\u52A1\uFF1A${task.name}\uFF08${id}\uFF09`));
2935
+ });
2936
+ cronCommand.command("logs <id>").description("\u67E5\u770B\u4EFB\u52A1\u6267\u884C\u65E5\u5FD7").option("--limit <n>", "\u663E\u793A\u6700\u8FD1 N \u6761", "20").action((id, options) => {
2937
+ const tasks = loadTasks();
2938
+ const task = tasks.find((t) => t.id === id);
2939
+ if (!task) {
2940
+ console.log(chalk4.red(`\u4EFB\u52A1\u4E0D\u5B58\u5728\uFF1A${id}`));
2941
+ process.exit(1);
2942
+ }
2943
+ const logs = task.logs ?? [];
2944
+ const limit = parseInt(options.limit, 10);
2945
+ const recent = logs.slice(-limit);
2946
+ console.log(chalk4.bold(`\u4EFB\u52A1\u65E5\u5FD7\uFF1A${task.name}\uFF08${id}\uFF09`));
2947
+ console.log(chalk4.gray("\u2500".repeat(60)));
2948
+ if (recent.length === 0) {
2949
+ console.log(chalk4.gray("\u6682\u65E0\u6267\u884C\u8BB0\u5F55"));
2950
+ return;
2951
+ }
2952
+ for (const log of recent) {
2953
+ const icon = log.success ? chalk4.green("\u2713") : chalk4.red("\u2717");
2954
+ const time = chalk4.gray(log.runAt);
2955
+ const msg = log.message ? chalk4.gray(` \u2014 ${log.message}`) : "";
2956
+ console.log(`${icon} ${time}${msg}`);
2957
+ }
2958
+ console.log(chalk4.gray("\u2500".repeat(60)));
2959
+ console.log(chalk4.gray(`\u5171 ${logs.length} \u6761\u8BB0\u5F55\uFF0C\u663E\u793A\u6700\u8FD1 ${recent.length} \u6761`));
2960
+ });
2961
+ cronCommand.command("run <id>").description("\u624B\u52A8\u7ACB\u5373\u6267\u884C\u4EFB\u52A1").action(async (id) => {
2962
+ const tasks = loadTasks();
2963
+ const task = tasks.find((t) => t.id === id);
2964
+ if (!task) {
2965
+ console.log(chalk4.red(`\u4EFB\u52A1\u4E0D\u5B58\u5728\uFF1A${id}`));
2966
+ process.exit(1);
2967
+ }
2968
+ console.log(chalk4.cyan(`\u6B63\u5728\u624B\u52A8\u6267\u884C\u4EFB\u52A1\uFF1A${task.name}\uFF08${id}\uFF09...`));
2969
+ if (!checkRedis()) {
2970
+ console.log(
2971
+ chalk4.yellow(
2972
+ "\u8B66\u544A\uFF1A\u672A\u68C0\u6D4B\u5230 Redis\uFF08REDIS_URL \u672A\u8BBE\u7F6E\uFF09\uFF0C\u4EFB\u52A1\u5C06\u4EE5\u672C\u5730\u6A21\u5F0F\u8FD0\u884C\u3002"
2973
+ )
2974
+ );
2975
+ }
2976
+ const runAt = (/* @__PURE__ */ new Date()).toISOString();
2977
+ try {
2978
+ if (!task.logs) task.logs = [];
2979
+ task.logs.push({ runAt, success: true, message: "\u624B\u52A8\u89E6\u53D1\uFF08\u672C\u5730\u6A21\u5F0F\uFF09" });
2980
+ task.lastRunAt = runAt;
2981
+ saveTasks(tasks);
2982
+ console.log(chalk4.green(`\u4EFB\u52A1\u6267\u884C\u5B8C\u6210\uFF1A${task.name}`));
2983
+ console.log(
2984
+ chalk4.gray("\u6CE8\u610F\uFF1A\u5B8C\u6574\u7684 pipeline \u6267\u884C\u9700\u8981 scheduler \u5305\u652F\u6301\u3002")
2985
+ );
2986
+ } catch (err) {
2987
+ const message = err instanceof Error ? err.message : String(err);
2988
+ if (!task.logs) task.logs = [];
2989
+ task.logs.push({ runAt, success: false, message });
2990
+ saveTasks(tasks);
2991
+ console.log(chalk4.red(`\u4EFB\u52A1\u6267\u884C\u5931\u8D25\uFF1A${message}`));
2992
+ process.exit(1);
2993
+ }
2994
+ });
2995
+
2996
+ // src/commands/style.ts
2997
+ import { Command as Command5 } from "commander";
2998
+ import chalk5 from "chalk";
2999
+ import { readFileSync as readFileSync7, existsSync as existsSync6 } from "fs";
3000
+ function typeLabel(type) {
3001
+ switch (type) {
3002
+ case "preset":
3003
+ return "\u9884\u8BBE";
3004
+ case "custom":
3005
+ return "\u81EA\u5B9A\u4E49";
3006
+ case "learned":
3007
+ return "\u5B66\u4E60";
3008
+ }
3009
+ }
3010
+ var styleCommand = new Command5("style").description("\u5199\u4F5C\u98CE\u683C\u7BA1\u7406");
3011
+ styleCommand.command("list").description("\u663E\u793A\u6240\u6709\u98CE\u683C").action(() => {
3012
+ const manager = new StyleManager();
3013
+ const styles = manager.listStyles();
3014
+ console.log(
3015
+ chalk5.bold(
3016
+ `${"ID".padEnd(12)}${"\u7C7B\u578B".padEnd(10)}\u540D\u79F0`
3017
+ )
3018
+ );
3019
+ console.log(chalk5.gray("\u2500".repeat(40)));
3020
+ if (styles.length === 0) {
3021
+ console.log(chalk5.yellow("\u6682\u65E0\u98CE\u683C\u6587\u4EF6\u3002\u8BF7\u68C0\u67E5 .wxclaw/styles/ \u76EE\u5F55\u3002"));
3022
+ return;
3023
+ }
3024
+ for (const s of styles) {
3025
+ console.log(
3026
+ `${chalk5.cyan(s.id.padEnd(12))}${chalk5.gray(typeLabel(s.type).padEnd(10))}${s.name}`
3027
+ );
3028
+ }
3029
+ console.log(chalk5.gray("\u2500".repeat(40)));
3030
+ console.log(chalk5.gray(`\u5171 ${styles.length} \u4E2A\u98CE\u683C`));
3031
+ });
3032
+ styleCommand.command("add").description("\u6DFB\u52A0\u81EA\u5B9A\u4E49\u98CE\u683C").requiredOption("--name <name>", "\u98CE\u683C\u540D\u79F0").requiredOption("--prompt <prompt>", "\u98CE\u683C\u63D0\u793A\u8BCD").action((options) => {
3033
+ const manager = new StyleManager();
3034
+ const result = manager.addCustomStyle(options.name, options.prompt);
3035
+ console.log(chalk5.green(`\u5DF2\u6DFB\u52A0\u81EA\u5B9A\u4E49\u98CE\u683C\uFF1A${result.name}\uFF08ID: ${result.id}\uFF09`));
3036
+ console.log(chalk5.gray(`\u6587\u4EF6\u5DF2\u4FDD\u5B58\u81F3\uFF1A${result.source}`));
3037
+ });
3038
+ styleCommand.command("learn").description("\u4ECE\u8303\u6587\u5B66\u4E60\u98CE\u683C\uFF08\u9700\u8981 LLM\uFF09").requiredOption("--file <file>", "\u8303\u6587\u6587\u4EF6\u8DEF\u5F84\uFF08.md \u6216 .txt\uFF09").requiredOption("--name <name>", "\u98CE\u683C\u540D\u79F0").option("--mock", "\u4F7F\u7528 Mock LLM\uFF08\u4E0D\u6D88\u8017 token\uFF09").action(async (options) => {
3039
+ if (!existsSync6(options.file)) {
3040
+ console.log(chalk5.red(`\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${options.file}`));
3041
+ process.exit(1);
3042
+ }
3043
+ const sampleText = readFileSync7(options.file, "utf-8");
3044
+ let llm;
3045
+ if (options.mock) {
3046
+ const mockProfile = {
3047
+ tone: "\u81EA\u7136\u6D41\u7545\uFF0C\u4EB2\u5207\u968F\u548C",
3048
+ sentencePattern: "\u957F\u77ED\u53E5\u7ED3\u5408\uFF0C\u8282\u594F\u81EA\u7136",
3049
+ structure: "\u5F00\u5934\u2192\u5C55\u5F00\u2192\u7ED3\u5C3E",
3050
+ vocabulary: "\u901A\u4FD7\u6613\u61C2\uFF0C\u5076\u5C14\u7528\u4E13\u4E1A\u8BCD\u6C47",
3051
+ openingStyle: "\u6545\u4E8B\u6216\u95EE\u9898\u5F00\u5934",
3052
+ closingStyle: "\u603B\u7ED3\u8981\u70B9\uFF0C\u5F15\u5BFC\u4E92\u52A8",
3053
+ specialHabits: ["\u5584\u7528\u4E3E\u4F8B", "\u6CE8\u91CD\u903B\u8F91"]
3054
+ };
3055
+ llm = {
3056
+ chat: async () => ({
3057
+ content: JSON.stringify(mockProfile)
3058
+ })
3059
+ };
3060
+ console.log(chalk5.yellow("\u4F7F\u7528 Mock LLM \u6A21\u5F0F"));
3061
+ } else {
3062
+ try {
3063
+ const { createLLMClient } = await Promise.resolve().then(() => (init_dist(), dist_exports));
3064
+ llm = createLLMClient();
3065
+ } catch {
3066
+ console.log(chalk5.red("providers \u5305\u4E0D\u53EF\u7528\uFF0C\u8BF7\u4F7F\u7528 --mock \u6A21\u5F0F\uFF1A"));
3067
+ console.log(chalk5.gray(` wxclaw style learn --file ${options.file} --name "${options.name}" --mock`));
3068
+ process.exit(1);
3069
+ }
3070
+ }
3071
+ console.log(chalk5.cyan(`\u6B63\u5728\u5206\u6790\u8303\u6587\uFF0C\u5B66\u4E60\u98CE\u683C\u300C${options.name}\u300D...`));
3072
+ const manager = new StyleManager();
3073
+ const result = await manager.learnFromSamples(options.name, [sampleText], llm);
3074
+ console.log(chalk5.green(`\u98CE\u683C\u5B66\u4E60\u5B8C\u6210\uFF1A${result.name}\uFF08ID: ${result.id}\uFF09`));
3075
+ console.log(chalk5.gray(`\u6587\u4EF6\u5DF2\u4FDD\u5B58\u81F3\uFF1A${result.source}`));
3076
+ if (result.profile) {
3077
+ console.log(chalk5.bold("\n\u98CE\u683C\u6982\u8981\uFF1A"));
3078
+ console.log(chalk5.gray(` \u8BED\u6C14\uFF1A${result.profile.tone}`));
3079
+ console.log(chalk5.gray(` \u53E5\u5F0F\uFF1A${result.profile.sentencePattern}`));
3080
+ console.log(chalk5.gray(` \u5F00\u5934\uFF1A${result.profile.openingStyle}`));
3081
+ console.log(chalk5.gray(` \u7ED3\u5C3E\uFF1A${result.profile.closingStyle}`));
3082
+ }
3083
+ });
3084
+
3085
+ // src/commands/setup.ts
3086
+ import { Command as Command6 } from "commander";
3087
+ import chalk6 from "chalk";
3088
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, existsSync as existsSync7 } from "fs";
3089
+ import { join as join7 } from "path";
3090
+ import { homedir as homedir2 } from "os";
3091
+ import { createInterface } from "readline";
3092
+ var setupCommand = new Command6("setup").description("\u4EA4\u4E92\u5F0F\u914D\u7F6E\u5411\u5BFC").action(async () => {
3093
+ console.log("");
3094
+ console.log(chalk6.cyan("\u{1F99E} WxClaw \u914D\u7F6E\u5411\u5BFC"));
3095
+ console.log(chalk6.gray("\u2501".repeat(50)));
3096
+ console.log("");
3097
+ console.log("\u6B22\u8FCE\u4F7F\u7528 WxClaw\uFF01\u8BA9\u6211\u4EEC\u914D\u7F6E\u4F60\u7684\u516C\u4F17\u53F7\u521B\u4F5C Agent\u3002");
3098
+ console.log("");
3099
+ const wxclawDir2 = join7(homedir2(), ".wxclaw");
3100
+ const configPath2 = join7(wxclawDir2, "config.json");
3101
+ if (!existsSync7(wxclawDir2)) {
3102
+ mkdirSync5(wxclawDir2, { recursive: true });
3103
+ }
3104
+ let config = {};
3105
+ if (existsSync7(configPath2)) {
3106
+ try {
3107
+ config = JSON.parse(readFileSync8(configPath2, "utf-8"));
3108
+ } catch {
3109
+ }
3110
+ }
3111
+ if (!config.providers) config.providers = {};
3112
+ if (!config.wechat) config.wechat = {};
3113
+ if (!config.pipeline) config.pipeline = {};
3114
+ const rl = createInterface({
3115
+ input: process.stdin,
3116
+ output: process.stdout
3117
+ });
3118
+ const ask = (question, defaultValue) => {
3119
+ return new Promise((resolve) => {
3120
+ const suffix = defaultValue ? chalk6.gray(` (${defaultValue})`) : "";
3121
+ rl.question(` ${question}${suffix}: `, (answer) => {
3122
+ resolve(answer.trim() || defaultValue || "");
3123
+ });
3124
+ });
3125
+ };
3126
+ console.log(chalk6.yellow("\u{1F4E6} Step 1/4: LLM Provider \u914D\u7F6E"));
3127
+ console.log(chalk6.gray(" WxClaw \u9700\u8981\u81F3\u5C11\u4E00\u4E2A LLM API Key \u6765\u751F\u6210\u5185\u5BB9\u3002"));
3128
+ console.log("");
3129
+ console.log(chalk6.white(" MiniMax\uFF08\u9ED8\u8BA4 Provider\uFF0C\u63A8\u8350\uFF09"));
3130
+ const minimaxKey = await ask(" MiniMax API Key\uFF08\u7559\u7A7A\u8DF3\u8FC7\uFF09");
3131
+ const providers = config.providers;
3132
+ if (minimaxKey) {
3133
+ if (!providers.minimax) providers.minimax = {};
3134
+ providers.minimax.apiKey = minimaxKey;
3135
+ providers.minimax.defaultModel = providers.minimax.defaultModel || "M2.7";
3136
+ config.defaultProvider = "minimax";
3137
+ console.log(chalk6.green(" \u2713 MiniMax \u5DF2\u914D\u7F6E"));
3138
+ }
3139
+ console.log("");
3140
+ console.log(chalk6.white(" DeepSeek\uFF08\u5907\u9009 Provider\uFF09"));
3141
+ const deepseekKey = await ask(" DeepSeek API Key\uFF08\u7559\u7A7A\u8DF3\u8FC7\uFF09");
3142
+ if (deepseekKey) {
3143
+ if (!providers.deepseek) providers.deepseek = {};
3144
+ providers.deepseek.apiKey = deepseekKey;
3145
+ providers.deepseek.defaultModel = providers.deepseek.defaultModel || "V4";
3146
+ if (!config.defaultProvider) config.defaultProvider = "deepseek";
3147
+ console.log(chalk6.green(" \u2713 DeepSeek \u5DF2\u914D\u7F6E"));
3148
+ }
3149
+ console.log("");
3150
+ console.log(chalk6.white(" OpenAI\uFF08\u53EF\u9009\uFF09"));
3151
+ const openaiKey = await ask(" OpenAI API Key\uFF08\u7559\u7A7A\u8DF3\u8FC7\uFF09");
3152
+ if (openaiKey) {
3153
+ if (!providers.openai) providers.openai = {};
3154
+ providers.openai.apiKey = openaiKey;
3155
+ providers.openai.defaultModel = providers.openai.defaultModel || "gpt-4o-mini";
3156
+ console.log(chalk6.green(" \u2713 OpenAI \u5DF2\u914D\u7F6E"));
3157
+ }
3158
+ console.log("");
3159
+ if (!minimaxKey && !deepseekKey && !openaiKey) {
3160
+ console.log(chalk6.yellow(" \u26A0 \u672A\u914D\u7F6E\u4EFB\u4F55 LLM Provider\u3002\u4F60\u53EF\u4EE5\u4E4B\u540E\u901A\u8FC7 wxclaw config set \u6DFB\u52A0\u3002"));
3161
+ console.log(chalk6.gray(" \u793A\u4F8B\uFF1Awxclaw config set providers.minimax.apiKey sk-xxx"));
3162
+ }
3163
+ console.log("");
3164
+ console.log(chalk6.yellow("\u{1F4F1} Step 2/4: \u5FAE\u4FE1\u516C\u4F17\u53F7\u914D\u7F6E"));
3165
+ console.log(chalk6.gray(" \u53EF\u9009\u3002\u914D\u7F6E\u540E\u53EF\u4EE5\u5C06\u6587\u7AE0\u76F4\u63A5\u4FDD\u5B58\u5230\u516C\u4F17\u53F7\u8349\u7A3F\u7BB1\u3002"));
3166
+ console.log("");
3167
+ const appId = await ask(" \u5FAE\u4FE1 AppID\uFF08\u7559\u7A7A\u8DF3\u8FC7\uFF09");
3168
+ const wechat = config.wechat;
3169
+ if (appId) {
3170
+ wechat.appId = appId;
3171
+ const appSecret = await ask(" \u5FAE\u4FE1 AppSecret");
3172
+ wechat.appSecret = appSecret;
3173
+ console.log(chalk6.green(" \u2713 \u5FAE\u4FE1\u516C\u4F17\u53F7\u5DF2\u914D\u7F6E"));
3174
+ } else {
3175
+ console.log(chalk6.gray(" \u8DF3\u8FC7\u5FAE\u4FE1\u914D\u7F6E\u3002\u6587\u7AE0\u5C06\u53EA\u4FDD\u5B58\u5728\u672C\u5730\u3002"));
3176
+ }
3177
+ console.log("");
3178
+ console.log(chalk6.yellow("\u{1F3AD} Step 3/4: \u516C\u4F17\u53F7\u4EBA\u8BBE"));
3179
+ console.log(chalk6.gray(" \u4F60\u7684\u516C\u4F17\u53F7\u5B9A\u4F4D\u662F\u4EC0\u4E48\uFF1F\u8FD9\u4F1A\u5F71\u54CD AI \u7684\u5199\u4F5C\u98CE\u683C\u3002"));
3180
+ console.log("");
3181
+ const positioning = await ask(" \u516C\u4F17\u53F7\u5B9A\u4F4D\uFF08\u5982\uFF1A\u79D1\u6280\u8BC4\u8BBA\u3001\u804C\u573A\u6210\u957F\uFF09", "\u79D1\u6280\u8BC4\u8BBA");
3182
+ const soulDir = join7(wxclawDir2, "styles");
3183
+ if (!existsSync7(soulDir)) {
3184
+ mkdirSync5(soulDir, { recursive: true });
3185
+ }
3186
+ const soulContent = `# Soul \u2014 \u516C\u4F17\u53F7\u4EBA\u8BBE
3187
+
3188
+ \u4F60\u662F\u4E00\u4F4D\u4E13\u6CE8\u4E8E\u300C${positioning}\u300D\u9886\u57DF\u7684\u516C\u4F17\u53F7\u5185\u5BB9\u521B\u4F5C\u8005\u3002
3189
+
3190
+ ## \u5199\u4F5C\u98CE\u683C
3191
+ - \u8BED\u8A00\u7B80\u6D01\u6709\u529B\uFF0C\u907F\u514D\u5197\u957F
3192
+ - \u5584\u7528\u7C7B\u6BD4\u8BA9\u590D\u6742\u6982\u5FF5\u901A\u4FD7\u6613\u61C2
3193
+ - \u89C2\u70B9\u9C9C\u660E\uFF0C\u4E0D\u8BF4\u6B63\u786E\u7684\u5E9F\u8BDD
3194
+ - \u9002\u5F53\u4F7F\u7528\u6570\u636E\u548C\u6848\u4F8B\u652F\u6491\u8BBA\u70B9
3195
+
3196
+ ## \u8BED\u6C14
3197
+ - \u4E13\u4E1A\u4F46\u4E0D\u5B66\u672F
3198
+ - \u4EB2\u5207\u4F46\u4E0D\u6CB9\u817B
3199
+ - \u81EA\u4FE1\u4F46\u4E0D\u50B2\u6162
3200
+
3201
+ ## \u7981\u6B62
3202
+ - \u4E0D\u4F7F\u7528"\u5C0F\u7F16"\u7B49\u81EA\u79F0
3203
+ - \u4E0D\u5806\u780C\u7F51\u7EDC\u6D41\u884C\u8BED
3204
+ - \u4E0D\u5199\u6807\u9898\u515A\u5185\u5BB9
3205
+ `;
3206
+ writeFileSync5(join7(wxclawDir2, "soul.md"), soulContent, "utf-8");
3207
+ console.log(chalk6.green(` \u2713 \u516C\u4F17\u53F7\u4EBA\u8BBE\u5DF2\u4FDD\u5B58\uFF08${positioning}\uFF09`));
3208
+ console.log("");
3209
+ console.log(chalk6.yellow("\u{1F3A8} Step 4/4: \u9ED8\u8BA4\u5199\u4F5C\u98CE\u683C"));
3210
+ console.log(
3211
+ chalk6.gray(
3212
+ " \u53EF\u9009\u98CE\u683C\uFF1Atech(\u79D1\u6280\u9510\u8BC4) / emotion(\u6696\u5FC3\u60C5\u611F) / tutorial(\u5E72\u8D27\u6559\u7A0B) / meme(\u6BB5\u5B50\u624B) / deepdive(\u6DF1\u5EA6\u957F\u6587)"
3213
+ )
3214
+ );
3215
+ console.log("");
3216
+ const defaultStyle = await ask(" \u9ED8\u8BA4\u98CE\u683C", "tech");
3217
+ const pipeline = config.pipeline;
3218
+ pipeline.defaultStyle = defaultStyle;
3219
+ const defaultProvider = config.defaultProvider || "minimax";
3220
+ const defaultProviderConfig = providers[defaultProvider] || {};
3221
+ const defaultModel = defaultProviderConfig.defaultModel || "default";
3222
+ const modelId = `${defaultProvider}:${defaultModel}`;
3223
+ if (!pipeline.stepModelMapping) {
3224
+ pipeline.stepModelMapping = {
3225
+ "topic-discovery": modelId,
3226
+ outline: modelId,
3227
+ writing: modelId,
3228
+ review: modelId
3229
+ };
3230
+ }
3231
+ writeFileSync5(configPath2, JSON.stringify(config, null, 2), "utf-8");
3232
+ const presetStyles = {
3233
+ tech: "# \u79D1\u6280\u9510\u8BC4\n\n\u4E13\u4E1A\u7280\u5229\u7684\u79D1\u6280\u8BC4\u8BBA\u98CE\u683C\uFF0C\u6570\u636E\u9A71\u52A8\uFF0C\u6562\u4E8E\u8868\u8FBE\u89C2\u70B9\u3002",
3234
+ emotion: "# \u6696\u5FC3\u60C5\u611F\n\n\u6E29\u6696\u5171\u60C5\u7684\u60C5\u611F\u7C7B\u98CE\u683C\uFF0C\u5584\u7528\u6545\u4E8B\u5F15\u53D1\u5171\u9E23\u3002",
3235
+ tutorial: "# \u5E72\u8D27\u6559\u7A0B\n\n\u5B9E\u7528\u5BFC\u5411\u7684\u6559\u7A0B\u98CE\u683C\uFF0C\u6B65\u9AA4\u6E05\u6670\uFF0C\u6613\u4E8E\u8DDF\u968F\u3002",
3236
+ meme: "# \u6BB5\u5B50\u624B\n\n\u5E7D\u9ED8\u63A5\u5730\u6C14\u7684\u6BB5\u5B50\u98CE\u683C\uFF0C\u7F51\u611F\u5F3A\uFF0C\u5584\u7528\u6897\u3002",
3237
+ deepdive: "# \u6DF1\u5EA6\u957F\u6587\n\n\u4E25\u8C28\u7684\u6DF1\u5EA6\u5206\u6790\u98CE\u683C\uFF0C\u5F15\u7ECF\u636E\u5178\uFF0C\u903B\u8F91\u7F1C\u5BC6\u3002"
3238
+ };
3239
+ for (const [style, content] of Object.entries(presetStyles)) {
3240
+ const stylePath = join7(soulDir, `${style}.md`);
3241
+ if (!existsSync7(stylePath)) {
3242
+ writeFileSync5(stylePath, content, "utf-8");
3243
+ }
3244
+ }
3245
+ console.log("");
3246
+ console.log(chalk6.cyan("\u2501".repeat(50)));
3247
+ console.log(chalk6.green("\u2705 WxClaw \u914D\u7F6E\u5B8C\u6210\uFF01"));
3248
+ console.log("");
3249
+ console.log(" \u914D\u7F6E\u6587\u4EF6\uFF1A" + chalk6.gray(configPath2));
3250
+ console.log(" \u4EBA\u8BBE\u6587\u4EF6\uFF1A" + chalk6.gray(join7(wxclawDir2, "soul.md")));
3251
+ console.log(" \u98CE\u683C\u76EE\u5F55\uFF1A" + chalk6.gray(soulDir));
3252
+ console.log("");
3253
+ console.log(" \u5FEB\u901F\u5F00\u59CB\uFF1A");
3254
+ console.log(chalk6.cyan(' wxclaw create --topic "\u4F60\u611F\u5174\u8DA3\u7684\u4E3B\u9898"'));
3255
+ console.log("");
3256
+ console.log(" \u66F4\u591A\u547D\u4EE4\uFF1A");
3257
+ console.log(chalk6.gray(" wxclaw --help"));
3258
+ console.log("");
3259
+ rl.close();
3260
+ });
3261
+
3262
+ // src/index.ts
3263
+ var program = new Command7();
3264
+ program.name("lewxclaw").description("WxClaw \u2014 \u516C\u4F17\u53F7\u521B\u4F5C Agent").version("0.1.0");
3265
+ program.addCommand(setupCommand);
3266
+ program.addCommand(createCommand);
3267
+ program.addCommand(configCommand);
3268
+ program.addCommand(topicsCommand);
3269
+ program.addCommand(cronCommand);
3270
+ program.addCommand(styleCommand);
3271
+ var configPath = join8(homedir3(), ".lewxclaw", "config.json");
3272
+ var args = process.argv.slice(2);
3273
+ var isSetup = args[0] === "setup";
3274
+ var isHelp = args.includes("--help") || args.includes("-h");
3275
+ var isVersion = args.includes("--version") || args.includes("-V");
3276
+ if (!existsSync8(configPath) && !isSetup && !isHelp && !isVersion && args.length > 0) {
3277
+ console.log(chalk7.yellow("\u{1F99E} \u9996\u6B21\u4F7F\u7528 WxClaw\uFF1F\u8FD0\u884C lewxclaw setup \u6765\u914D\u7F6E\u4F60\u7684 Agent\u3002"));
3278
+ console.log(chalk7.gray(' \u6216\u4F7F\u7528 --mock \u6A21\u5F0F\u514D\u914D\u7F6E\u4F53\u9A8C\uFF1Alewxclaw create --mock --topic "AI \u8D8B\u52BF"'));
3279
+ console.log("");
3280
+ }
3281
+ program.parse();
3282
+ //# sourceMappingURL=index.js.map