skool-cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +179 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +33 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/create-folder.d.ts +3 -0
  8. package/dist/commands/create-folder.d.ts.map +1 -0
  9. package/dist/commands/create-folder.js +24 -0
  10. package/dist/commands/create-folder.js.map +1 -0
  11. package/dist/commands/create-lesson.d.ts +3 -0
  12. package/dist/commands/create-lesson.d.ts.map +1 -0
  13. package/dist/commands/create-lesson.js +35 -0
  14. package/dist/commands/create-lesson.js.map +1 -0
  15. package/dist/commands/create-post.d.ts +3 -0
  16. package/dist/commands/create-post.d.ts.map +1 -0
  17. package/dist/commands/create-post.js +36 -0
  18. package/dist/commands/create-post.js.map +1 -0
  19. package/dist/commands/debug-api.d.ts +3 -0
  20. package/dist/commands/debug-api.d.ts.map +1 -0
  21. package/dist/commands/debug-api.js +112 -0
  22. package/dist/commands/debug-api.js.map +1 -0
  23. package/dist/commands/debug-manual.d.ts +3 -0
  24. package/dist/commands/debug-manual.d.ts.map +1 -0
  25. package/dist/commands/debug-manual.js +66 -0
  26. package/dist/commands/debug-manual.js.map +1 -0
  27. package/dist/commands/debug.d.ts +3 -0
  28. package/dist/commands/debug.d.ts.map +1 -0
  29. package/dist/commands/debug.js +114 -0
  30. package/dist/commands/debug.js.map +1 -0
  31. package/dist/commands/delete-lesson.d.ts +3 -0
  32. package/dist/commands/delete-lesson.d.ts.map +1 -0
  33. package/dist/commands/delete-lesson.js +17 -0
  34. package/dist/commands/delete-lesson.js.map +1 -0
  35. package/dist/commands/get-categories.d.ts +3 -0
  36. package/dist/commands/get-categories.d.ts.map +1 -0
  37. package/dist/commands/get-categories.js +34 -0
  38. package/dist/commands/get-categories.js.map +1 -0
  39. package/dist/commands/get-members.d.ts +3 -0
  40. package/dist/commands/get-members.d.ts.map +1 -0
  41. package/dist/commands/get-members.js +35 -0
  42. package/dist/commands/get-members.js.map +1 -0
  43. package/dist/commands/get-posts.d.ts +3 -0
  44. package/dist/commands/get-posts.d.ts.map +1 -0
  45. package/dist/commands/get-posts.js +41 -0
  46. package/dist/commands/get-posts.js.map +1 -0
  47. package/dist/commands/list-lessons.d.ts +3 -0
  48. package/dist/commands/list-lessons.d.ts.map +1 -0
  49. package/dist/commands/list-lessons.js +45 -0
  50. package/dist/commands/list-lessons.js.map +1 -0
  51. package/dist/commands/login.d.ts +3 -0
  52. package/dist/commands/login.d.ts.map +1 -0
  53. package/dist/commands/login.js +30 -0
  54. package/dist/commands/login.js.map +1 -0
  55. package/dist/commands/test-api.d.ts +3 -0
  56. package/dist/commands/test-api.d.ts.map +1 -0
  57. package/dist/commands/test-api.js +143 -0
  58. package/dist/commands/test-api.js.map +1 -0
  59. package/dist/commands/whoami.d.ts +3 -0
  60. package/dist/commands/whoami.d.ts.map +1 -0
  61. package/dist/commands/whoami.js +17 -0
  62. package/dist/commands/whoami.js.map +1 -0
  63. package/dist/core/browser-manager.d.ts +25 -0
  64. package/dist/core/browser-manager.d.ts.map +1 -0
  65. package/dist/core/browser-manager.js +104 -0
  66. package/dist/core/browser-manager.js.map +1 -0
  67. package/dist/core/config.d.ts +15 -0
  68. package/dist/core/config.d.ts.map +1 -0
  69. package/dist/core/config.js +17 -0
  70. package/dist/core/config.js.map +1 -0
  71. package/dist/core/html-generator.d.ts +15 -0
  72. package/dist/core/html-generator.d.ts.map +1 -0
  73. package/dist/core/html-generator.js +254 -0
  74. package/dist/core/html-generator.js.map +1 -0
  75. package/dist/core/page-ops.d.ts +69 -0
  76. package/dist/core/page-ops.d.ts.map +1 -0
  77. package/dist/core/page-ops.js +511 -0
  78. package/dist/core/page-ops.js.map +1 -0
  79. package/dist/core/skool-api.d.ts +74 -0
  80. package/dist/core/skool-api.d.ts.map +1 -0
  81. package/dist/core/skool-api.js +389 -0
  82. package/dist/core/skool-api.js.map +1 -0
  83. package/dist/core/skool-client.d.ts +63 -0
  84. package/dist/core/skool-client.d.ts.map +1 -0
  85. package/dist/core/skool-client.js +501 -0
  86. package/dist/core/skool-client.js.map +1 -0
  87. package/dist/core/types.d.ts +58 -0
  88. package/dist/core/types.d.ts.map +1 -0
  89. package/dist/core/types.js +2 -0
  90. package/dist/core/types.js.map +1 -0
  91. package/package.json +51 -0
@@ -0,0 +1,25 @@
1
+ import { type Page } from "playwright";
2
+ /**
3
+ * Manages Playwright browser lifecycle for skool-cli.
4
+ *
5
+ * Uses explicit cookie save/load (like playwright-cli state-save/load)
6
+ * because launchPersistentContext doesn't reliably persist across
7
+ * separate CLI invocations.
8
+ */
9
+ export declare class BrowserManager {
10
+ private browser;
11
+ private context;
12
+ private page;
13
+ private closing;
14
+ /** Get (or create) the reusable page */
15
+ getPage(): Promise<Page>;
16
+ /** Save current auth state (cookies + localStorage) to disk */
17
+ saveAuthState(): Promise<void>;
18
+ /** Check if saved auth state exists on disk */
19
+ hasAuthState(): boolean;
20
+ /** Check if a browser context is currently active */
21
+ isActive(): boolean;
22
+ /** Close browser and cleanup */
23
+ close(): Promise<void>;
24
+ }
25
+ //# sourceMappingURL=browser-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-manager.d.ts","sourceRoot":"","sources":["../../src/core/browser-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+C,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAQpF;;;;;;GAMG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,OAAO,CAAS;IAExB,wCAAwC;IAClC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAuD9B,+DAA+D;IACzD,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAUpC,+CAA+C;IAC/C,YAAY,IAAI,OAAO;IAIvB,qDAAqD;IACrD,QAAQ,IAAI,OAAO;IAInB,gCAAgC;IAC1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAoB7B"}
@@ -0,0 +1,104 @@
1
+ import { chromium } from "playwright";
2
+ import { mkdirSync, existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { DATA_DIR, HEADLESS, DEFAULT_TIMEOUT } from "./config.js";
5
+ /** Path to saved auth state (cookies + localStorage) */
6
+ const AUTH_STATE_PATH = join(DATA_DIR, "auth-state.json");
7
+ /**
8
+ * Manages Playwright browser lifecycle for skool-cli.
9
+ *
10
+ * Uses explicit cookie save/load (like playwright-cli state-save/load)
11
+ * because launchPersistentContext doesn't reliably persist across
12
+ * separate CLI invocations.
13
+ */
14
+ export class BrowserManager {
15
+ browser = null;
16
+ context = null;
17
+ page = null;
18
+ closing = false;
19
+ /** Get (or create) the reusable page */
20
+ async getPage() {
21
+ if (this.closing) {
22
+ throw new Error("Browser is shutting down");
23
+ }
24
+ if (this.page && !this.page.isClosed()) {
25
+ return this.page;
26
+ }
27
+ // Ensure data dir exists
28
+ if (!existsSync(DATA_DIR)) {
29
+ mkdirSync(DATA_DIR, { recursive: true });
30
+ }
31
+ if (!this.browser) {
32
+ this.browser = await chromium.launch({
33
+ headless: HEADLESS,
34
+ args: [
35
+ "--disable-blink-features=AutomationControlled",
36
+ "--no-sandbox",
37
+ ],
38
+ });
39
+ // Create context with saved auth state if available
40
+ const contextOptions = {
41
+ viewport: { width: 1280, height: 800 },
42
+ userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
43
+ };
44
+ if (existsSync(AUTH_STATE_PATH)) {
45
+ contextOptions.storageState = AUTH_STATE_PATH;
46
+ }
47
+ this.context = await this.browser.newContext(contextOptions);
48
+ // Register cleanup handlers once
49
+ const cleanup = () => void this.close();
50
+ process.once("SIGTERM", cleanup);
51
+ process.once("SIGINT", cleanup);
52
+ process.once("exit", cleanup);
53
+ }
54
+ if (!this.context) {
55
+ throw new Error("Browser context not initialized");
56
+ }
57
+ // Reuse existing pages or create new one
58
+ const pages = this.context.pages();
59
+ this.page = pages.length > 0 ? pages[0] : await this.context.newPage();
60
+ this.page.setDefaultTimeout(DEFAULT_TIMEOUT);
61
+ return this.page;
62
+ }
63
+ /** Save current auth state (cookies + localStorage) to disk */
64
+ async saveAuthState() {
65
+ if (!this.context)
66
+ return;
67
+ if (!existsSync(DATA_DIR)) {
68
+ mkdirSync(DATA_DIR, { recursive: true });
69
+ }
70
+ await this.context.storageState({ path: AUTH_STATE_PATH });
71
+ }
72
+ /** Check if saved auth state exists on disk */
73
+ hasAuthState() {
74
+ return existsSync(AUTH_STATE_PATH);
75
+ }
76
+ /** Check if a browser context is currently active */
77
+ isActive() {
78
+ return this.browser !== null && !this.closing;
79
+ }
80
+ /** Close browser and cleanup */
81
+ async close() {
82
+ if (this.closing)
83
+ return;
84
+ this.closing = true;
85
+ try {
86
+ if (this.context) {
87
+ await this.context.close();
88
+ }
89
+ if (this.browser) {
90
+ await this.browser.close();
91
+ }
92
+ }
93
+ catch {
94
+ // Ignore errors during shutdown
95
+ }
96
+ finally {
97
+ this.browser = null;
98
+ this.context = null;
99
+ this.page = null;
100
+ this.closing = false;
101
+ }
102
+ }
103
+ }
104
+ //# sourceMappingURL=browser-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-manager.js","sourceRoot":"","sources":["../../src/core/browser-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /** Base directory for all skool-cli data */
2
+ export declare const DATA_DIR: string;
3
+ /** Directory for Playwright persistent browser context */
4
+ export declare const BROWSER_DATA_DIR: string;
5
+ /** Default timeout for operations in ms */
6
+ export declare const DEFAULT_TIMEOUT: number;
7
+ /** Whether to run browser in headless mode */
8
+ export declare const HEADLESS: boolean;
9
+ /** Skool base URL */
10
+ export declare const SKOOL_BASE_URL = "https://www.skool.com";
11
+ /** Delay after SPA navigation (ms) */
12
+ export declare const SPA_NAV_DELAY = 2000;
13
+ /** Max characters for lesson titles in Skool */
14
+ export declare const MAX_TITLE_LENGTH = 50;
15
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAGA,4CAA4C;AAC5C,eAAO,MAAM,QAAQ,QAC4C,CAAC;AAElE,0DAA0D;AAC1D,eAAO,MAAM,gBAAgB,QAAiC,CAAC;AAE/D,2CAA2C;AAC3C,eAAO,MAAM,eAAe,QAAkD,CAAC;AAE/E,8CAA8C;AAC9C,eAAO,MAAM,QAAQ,SAA6C,CAAC;AAEnE,qBAAqB;AACrB,eAAO,MAAM,cAAc,0BAA0B,CAAC;AAEtD,sCAAsC;AACtC,eAAO,MAAM,aAAa,OAAO,CAAC;AAElC,gDAAgD;AAChD,eAAO,MAAM,gBAAgB,KAAK,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { join } from "node:path";
2
+ import { homedir } from "node:os";
3
+ /** Base directory for all skool-cli data */
4
+ export const DATA_DIR = process.env.SKOOL_CLI_DATA_DIR || join(homedir(), ".skool-cli");
5
+ /** Directory for Playwright persistent browser context */
6
+ export const BROWSER_DATA_DIR = join(DATA_DIR, "browser-data");
7
+ /** Default timeout for operations in ms */
8
+ export const DEFAULT_TIMEOUT = Number(process.env.SKOOL_CLI_TIMEOUT) || 30_000;
9
+ /** Whether to run browser in headless mode */
10
+ export const HEADLESS = process.env.SKOOL_CLI_HEADLESS !== "false";
11
+ /** Skool base URL */
12
+ export const SKOOL_BASE_URL = "https://www.skool.com";
13
+ /** Delay after SPA navigation (ms) */
14
+ export const SPA_NAV_DELAY = 2000;
15
+ /** Max characters for lesson titles in Skool */
16
+ export const MAX_TITLE_LENGTH = 50;
17
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,4CAA4C;AAC5C,MAAM,CAAC,MAAM,QAAQ,GACnB,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AAElE,0DAA0D;AAC1D,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;AAE/D,2CAA2C;AAC3C,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,MAAM,CAAC;AAE/E,8CAA8C;AAC9C,MAAM,CAAC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,OAAO,CAAC;AAEnE,qBAAqB;AACrB,MAAM,CAAC,MAAM,cAAc,GAAG,uBAAuB,CAAC;AAEtD,sCAAsC;AACtC,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAElC,gDAAgD;AAChD,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Converts markdown or structured content to TipTap-compatible HTML for Skool.
3
+ *
4
+ * Ported from Content-Pipeline's skool-html-generator.cjs.
5
+ * Supported elements: h1-h4, p, strong, em, code, pre>code, ul/ol, blockquote, hr, a
6
+ * NOT supported: tables, iframes (except video), forms
7
+ */
8
+ /** Convert markdown text to TipTap-compatible HTML */
9
+ export declare function markdownToHtml(markdown: string): string;
10
+ /**
11
+ * Convert a skool_class structured object to TipTap-compatible HTML.
12
+ * This is the port of skool-html-generator.cjs.
13
+ */
14
+ export declare function structuredContentToHtml(sc: Record<string, unknown>): string;
15
+ //# sourceMappingURL=html-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-generator.d.ts","sourceRoot":"","sources":["../../src/core/html-generator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAuHH,sDAAsD;AACtD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CA6H3E"}
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Converts markdown or structured content to TipTap-compatible HTML for Skool.
3
+ *
4
+ * Ported from Content-Pipeline's skool-html-generator.cjs.
5
+ * Supported elements: h1-h4, p, strong, em, code, pre>code, ul/ol, blockquote, hr, a
6
+ * NOT supported: tables, iframes (except video), forms
7
+ */
8
+ // ----------------------------------------------------------
9
+ // Helpers
10
+ // ----------------------------------------------------------
11
+ function escapeHtml(text) {
12
+ return text
13
+ .replace(/\u2014/g, "-") // em dash
14
+ .replace(/\u2013/g, "-") // en dash
15
+ .replace(/&/g, "&amp;")
16
+ .replace(/</g, "&lt;")
17
+ .replace(/>/g, "&gt;")
18
+ .replace(/"/g, "&quot;");
19
+ }
20
+ function applyInlineFormatting(text) {
21
+ let formatted = text;
22
+ // Bold: **text** or __text__
23
+ formatted = formatted.replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>");
24
+ formatted = formatted.replace(/__(.*?)__/g, "<strong>$1</strong>");
25
+ // Italic: *text* (but not inside **)
26
+ formatted = formatted.replace(/(?<!\*)\*(?!\*)(.*?)(?<!\*)\*(?!\*)/g, "<em>$1</em>");
27
+ // Inline code: `text`
28
+ formatted = formatted.replace(/`(.*?)`/g, "<code>$1</code>");
29
+ return formatted;
30
+ }
31
+ function cleanText(text) {
32
+ return text.replace(/\u2014/g, "-").replace(/\u2013/g, "-");
33
+ }
34
+ // ----------------------------------------------------------
35
+ // Text to HTML (markdown-like)
36
+ // ----------------------------------------------------------
37
+ function textToHtml(text) {
38
+ if (!text)
39
+ return "";
40
+ const cleaned = cleanText(text);
41
+ const paragraphs = cleaned.split(/\n\n+/);
42
+ let html = "";
43
+ for (const para of paragraphs) {
44
+ const trimmed = para.trim();
45
+ if (!trimmed)
46
+ continue;
47
+ // Code block
48
+ if (trimmed.startsWith("```")) {
49
+ const codeContent = trimmed
50
+ .replace(/^```\w*\n?/, "")
51
+ .replace(/\n?```$/, "");
52
+ html += `<pre><code>${escapeHtml(codeContent)}</code></pre>`;
53
+ continue;
54
+ }
55
+ const lines = trimmed.split("\n");
56
+ let i = 0;
57
+ while (i < lines.length) {
58
+ const line = lines[i].trim();
59
+ if (!line) {
60
+ i++;
61
+ continue;
62
+ }
63
+ // Markdown headers
64
+ const headerMatch = line.match(/^(#{1,4})\s+(.+)$/);
65
+ if (headerMatch) {
66
+ const level = headerMatch[1].length;
67
+ html += `<h${level}>${applyInlineFormatting(headerMatch[2])}</h${level}>`;
68
+ i++;
69
+ continue;
70
+ }
71
+ // Bullet list
72
+ if (/^[-\u2022]\s/.test(line)) {
73
+ html += "<ul>";
74
+ while (i < lines.length && /^[-\u2022]\s/.test(lines[i].trim())) {
75
+ const bulletText = lines[i].trim().replace(/^[-\u2022]\s*/, "");
76
+ if (bulletText) {
77
+ html += `<li>${applyInlineFormatting(bulletText)}</li>`;
78
+ }
79
+ i++;
80
+ }
81
+ html += "</ul>";
82
+ continue;
83
+ }
84
+ // Numbered list
85
+ if (/^\d+[.)]\s/.test(line)) {
86
+ html += "<ol>";
87
+ while (i < lines.length && /^\d+[.)]\s/.test(lines[i].trim())) {
88
+ const numberedText = lines[i].trim().replace(/^\d+[.)]\s*/, "");
89
+ if (numberedText) {
90
+ html += `<li>${applyInlineFormatting(numberedText)}</li>`;
91
+ }
92
+ i++;
93
+ }
94
+ html += "</ol>";
95
+ continue;
96
+ }
97
+ // Regular paragraph
98
+ html += `<p>${applyInlineFormatting(line)}</p>`;
99
+ i++;
100
+ }
101
+ }
102
+ return html;
103
+ }
104
+ // ----------------------------------------------------------
105
+ // Public API
106
+ // ----------------------------------------------------------
107
+ /** Convert markdown text to TipTap-compatible HTML */
108
+ export function markdownToHtml(markdown) {
109
+ return textToHtml(markdown);
110
+ }
111
+ /**
112
+ * Convert a skool_class structured object to TipTap-compatible HTML.
113
+ * This is the port of skool-html-generator.cjs.
114
+ */
115
+ export function structuredContentToHtml(sc) {
116
+ let html = "";
117
+ const contenido = sc.contenido;
118
+ if (contenido) {
119
+ for (const [key, value] of Object.entries(contenido)) {
120
+ const sectionTitle = key
121
+ .replace(/_/g, " ")
122
+ .replace(/\b\w/g, (c) => c.toUpperCase());
123
+ // Skip header for contexto (it's the intro)
124
+ if (key !== "contexto") {
125
+ html += `<h2>${escapeHtml(sectionTitle)}</h2>`;
126
+ }
127
+ if (typeof value === "string") {
128
+ html += textToHtml(value);
129
+ }
130
+ else if (Array.isArray(value)) {
131
+ for (const item of value) {
132
+ if (typeof item === "string") {
133
+ html += textToHtml(item);
134
+ }
135
+ else if (typeof item === "object" && item !== null) {
136
+ const obj = item;
137
+ if (obj.paso && obj.titulo) {
138
+ html += `<p><strong>Paso ${obj.paso}: ${escapeHtml(String(obj.titulo))}</strong></p>`;
139
+ if (obj.instruccion)
140
+ html += textToHtml(String(obj.instruccion));
141
+ if (obj.detalle)
142
+ html += textToHtml(String(obj.detalle));
143
+ if (obj.nota) {
144
+ html += `<p><em>${applyInlineFormatting(escapeHtml(String(obj.nota)))}</em></p>`;
145
+ }
146
+ }
147
+ else if (obj.titulo) {
148
+ html += `<p><strong>${escapeHtml(String(obj.titulo))}</strong></p>`;
149
+ if (obj.descripcion)
150
+ html += textToHtml(String(obj.descripcion));
151
+ if (obj.explicacion)
152
+ html += textToHtml(String(obj.explicacion));
153
+ if (obj.detalle)
154
+ html += textToHtml(String(obj.detalle));
155
+ }
156
+ else {
157
+ for (const [, v] of Object.entries(obj)) {
158
+ if (typeof v === "string")
159
+ html += textToHtml(v);
160
+ }
161
+ }
162
+ }
163
+ }
164
+ }
165
+ else if (typeof value === "object" && value !== null) {
166
+ for (const [subKey, subValue] of Object.entries(value)) {
167
+ if (typeof subValue === "string") {
168
+ html += `<p><strong>${escapeHtml(subKey.replace(/_/g, " "))}:</strong> ${subValue}</p>`;
169
+ }
170
+ }
171
+ }
172
+ }
173
+ }
174
+ // Ejercicio section
175
+ if (sc.ejercicio) {
176
+ html += `<h2>Ejercicio Practico</h2>`;
177
+ if (typeof sc.ejercicio === "string") {
178
+ html += textToHtml(sc.ejercicio);
179
+ }
180
+ else if (typeof sc.ejercicio === "object") {
181
+ const ej = sc.ejercicio;
182
+ if (ej.titulo)
183
+ html += `<p><strong>${escapeHtml(String(ej.titulo))}</strong></p>`;
184
+ if (ej.instrucciones)
185
+ html += textToHtml(String(ej.instrucciones));
186
+ if (Array.isArray(ej.pasos)) {
187
+ for (const paso of ej.pasos) {
188
+ if (typeof paso === "string") {
189
+ html += textToHtml(paso);
190
+ }
191
+ else if (typeof paso === "object" && paso !== null) {
192
+ const p = paso;
193
+ if (p.paso && p.titulo) {
194
+ html += `<p><strong>Paso ${p.paso}: ${escapeHtml(String(p.titulo))}</strong></p>`;
195
+ }
196
+ if (p.instruccion)
197
+ html += textToHtml(String(p.instruccion));
198
+ if (p.detalle)
199
+ html += textToHtml(String(p.detalle));
200
+ if (p.nota) {
201
+ html += `<p><em>${applyInlineFormatting(escapeHtml(String(p.nota)))}</em></p>`;
202
+ }
203
+ }
204
+ }
205
+ }
206
+ if (ej.resultado_esperado) {
207
+ html += `<p><strong>Resultado esperado:</strong> ${applyInlineFormatting(escapeHtml(String(ej.resultado_esperado)))}</p>`;
208
+ }
209
+ if (ej.tiempo_estimado) {
210
+ html += `<p><strong>Tiempo estimado:</strong> ${escapeHtml(String(ej.tiempo_estimado))}</p>`;
211
+ }
212
+ }
213
+ }
214
+ // Action item section
215
+ if (sc.action_item) {
216
+ html += `<h2>Action Item</h2>`;
217
+ if (typeof sc.action_item === "string") {
218
+ html += textToHtml(sc.action_item);
219
+ }
220
+ else if (typeof sc.action_item === "object") {
221
+ const ai = sc.action_item;
222
+ if (ai.titulo)
223
+ html += `<p><strong>${escapeHtml(String(ai.titulo))}</strong></p>`;
224
+ if (ai.descripcion)
225
+ html += textToHtml(String(ai.descripcion));
226
+ if (ai.instrucciones)
227
+ html += textToHtml(String(ai.instrucciones));
228
+ if (ai.texto)
229
+ html += textToHtml(String(ai.texto));
230
+ }
231
+ }
232
+ // Recursos section
233
+ if (Array.isArray(sc.recursos) && sc.recursos.length > 0) {
234
+ html += `<h2>Recursos</h2><ul>`;
235
+ for (const recurso of sc.recursos) {
236
+ const r = recurso;
237
+ if (r.nombre && r.url) {
238
+ const tipo = r.tipo ? ` (${escapeHtml(String(r.tipo))})` : "";
239
+ html += `<li><a href="${escapeHtml(String(r.url))}" target="_blank">${escapeHtml(String(r.nombre))}</a>${tipo}</li>`;
240
+ }
241
+ else if (r.nombre) {
242
+ html += `<li>${escapeHtml(String(r.nombre))}</li>`;
243
+ }
244
+ }
245
+ html += `</ul>`;
246
+ }
247
+ // Pregunta de discusion
248
+ if (sc.pregunta_discusion) {
249
+ html += `<h2>Pregunta de Discusion</h2>`;
250
+ html += textToHtml(String(sc.pregunta_discusion));
251
+ }
252
+ return html;
253
+ }
254
+ //# sourceMappingURL=html-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-generator.js","sourceRoot":"","sources":["../../src/core/html-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import type { Locator } from "playwright";
2
+ import { BrowserManager } from "./browser-manager.js";
3
+ /**
4
+ * Low-level page operations for Skool automation.
5
+ *
6
+ * Encapsulates all 6 production workarounds:
7
+ * 1. SAVE disabled after HTML injection -> space+backspace dirty trigger
8
+ * 2. Dropdown overlay blocks clicks -> pointerEvents:none fix
9
+ * 3. Volatile refs -> N/A with Playwright native locators
10
+ * 4. SPA timing -> wait after navigation
11
+ * 5. HTML conversion -> handled by html-generator
12
+ * 6. 50-char title limit -> auto-truncate
13
+ */
14
+ export declare class PageOps {
15
+ private browser;
16
+ constructor(browser: BrowserManager);
17
+ /** Get the current page */
18
+ private page;
19
+ /** Navigate to a Skool URL with SPA delay (workaround #4) */
20
+ goto(path: string): Promise<void>;
21
+ /** Navigate to a group's community page */
22
+ gotoCommunity(groupSlug: string): Promise<void>;
23
+ /** Navigate to a group's classroom page */
24
+ gotoClassroom(groupSlug: string): Promise<void>;
25
+ /** Navigate to a group's members page */
26
+ gotoMembers(groupSlug: string): Promise<void>;
27
+ /** Check if user is authenticated on the current page */
28
+ isAuthenticated(): Promise<boolean>;
29
+ /** Perform login with email and password */
30
+ login(email: string, password: string): Promise<boolean>;
31
+ /** Remove all known overlays that block pointer events */
32
+ clearOverlays(): Promise<void>;
33
+ /** Click a locator, fixing overlays if needed */
34
+ safeClick(locator: Locator): Promise<void>;
35
+ /** Fill a title field, truncating to MAX_TITLE_LENGTH */
36
+ fillTitle(locator: Locator, title: string): Promise<string>;
37
+ /**
38
+ * Inject HTML content into the TipTap editor.
39
+ * Includes the space+backspace dirty trigger so SAVE becomes enabled.
40
+ */
41
+ injectTipTapContent(html: string): Promise<boolean>;
42
+ /** Click SAVE and verify it completes (button becomes disabled) */
43
+ clickSaveAndVerify(): Promise<boolean>;
44
+ /** Create a community post */
45
+ createCommunityPost(groupSlug: string, title: string, body: string, category?: string): Promise<boolean>;
46
+ /**
47
+ * Create a new lesson in a classroom module.
48
+ *
49
+ * Flow: enter course → "..." menu → "Add page" → click pencil → fill title → inject HTML → save
50
+ */
51
+ createLesson(groupSlug: string, moduleName: string, title: string, html: string, courseName?: string): Promise<boolean>;
52
+ /** Extract posts from the community page */
53
+ extractPosts(groupSlug: string): Promise<Array<{
54
+ title: string;
55
+ author: string;
56
+ category: string;
57
+ preview: string;
58
+ url: string;
59
+ }>>;
60
+ /** Extract categories from the community page */
61
+ extractCategories(groupSlug: string): Promise<string[]>;
62
+ /** Extract members from the members page */
63
+ extractMembers(groupSlug: string, search?: string): Promise<Array<{
64
+ name: string;
65
+ level: number;
66
+ contributions: number;
67
+ }>>;
68
+ }
69
+ //# sourceMappingURL=page-ops.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-ops.d.ts","sourceRoot":"","sources":["../../src/core/page-ops.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,OAAO,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAQtD;;;;;;;;;;GAUG;AACH,qBAAa,OAAO;IACN,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,cAAc;IAE3C,2BAA2B;YACb,IAAI;IAQlB,6DAA6D;IACvD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvC,2CAA2C;IACrC,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD,2CAA2C;IACrC,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD,yCAAyC;IACnC,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQnD,yDAAyD;IACnD,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAgCzC,4CAA4C;IACtC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAyC9D,0DAA0D;IACpD,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBpC,iDAAiD;IAC3C,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BhD,yDAAyD;IACnD,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAcjE;;;OAGG;IACG,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAsEzD,mEAAmE;IAC7D,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC;IAgC5C,8BAA8B;IACxB,mBAAmB,CACvB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC;IAqEnB;;;;OAIG;IACG,YAAY,CAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC;IAsGnB,4CAA4C;IACtC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAC5C,KAAK,CAAC;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;KACb,CAAC,CACH;IAgED,iDAAiD;IAC3C,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAmB7D,4CAA4C;IACtC,cAAc,CAClB,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CACR,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAC9D;CAyCF"}