@steipete/summarize 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/LICENSE +21 -0
  3. package/README.md +185 -0
  4. package/dist/cli.cjs +74333 -0
  5. package/dist/cli.cjs.map +7 -0
  6. package/dist/esm/cli-main.js +80 -0
  7. package/dist/esm/cli-main.js.map +1 -0
  8. package/dist/esm/cli.js +18 -0
  9. package/dist/esm/cli.js.map +1 -0
  10. package/dist/esm/config.js +33 -0
  11. package/dist/esm/config.js.map +1 -0
  12. package/dist/esm/content/asset.js +167 -0
  13. package/dist/esm/content/asset.js.map +1 -0
  14. package/dist/esm/content/index.js +4 -0
  15. package/dist/esm/content/index.js.map +1 -0
  16. package/dist/esm/content/link-preview/client.js +20 -0
  17. package/dist/esm/content/link-preview/client.js.map +1 -0
  18. package/dist/esm/content/link-preview/content/article.js +150 -0
  19. package/dist/esm/content/link-preview/content/article.js.map +1 -0
  20. package/dist/esm/content/link-preview/content/cleaner.js +55 -0
  21. package/dist/esm/content/link-preview/content/cleaner.js.map +1 -0
  22. package/dist/esm/content/link-preview/content/fetcher.js +120 -0
  23. package/dist/esm/content/link-preview/content/fetcher.js.map +1 -0
  24. package/dist/esm/content/link-preview/content/index.js +275 -0
  25. package/dist/esm/content/link-preview/content/index.js.map +1 -0
  26. package/dist/esm/content/link-preview/content/parsers.js +77 -0
  27. package/dist/esm/content/link-preview/content/parsers.js.map +1 -0
  28. package/dist/esm/content/link-preview/content/types.js +4 -0
  29. package/dist/esm/content/link-preview/content/types.js.map +1 -0
  30. package/dist/esm/content/link-preview/content/utils.js +127 -0
  31. package/dist/esm/content/link-preview/content/utils.js.map +1 -0
  32. package/dist/esm/content/link-preview/content/youtube.js +82 -0
  33. package/dist/esm/content/link-preview/content/youtube.js.map +1 -0
  34. package/dist/esm/content/link-preview/deps.js +2 -0
  35. package/dist/esm/content/link-preview/deps.js.map +1 -0
  36. package/dist/esm/content/link-preview/fetch-with-timeout.js +35 -0
  37. package/dist/esm/content/link-preview/fetch-with-timeout.js.map +1 -0
  38. package/dist/esm/content/link-preview/transcript/cache.js +73 -0
  39. package/dist/esm/content/link-preview/transcript/cache.js.map +1 -0
  40. package/dist/esm/content/link-preview/transcript/index.js +95 -0
  41. package/dist/esm/content/link-preview/transcript/index.js.map +1 -0
  42. package/dist/esm/content/link-preview/transcript/normalize.js +43 -0
  43. package/dist/esm/content/link-preview/transcript/normalize.js.map +1 -0
  44. package/dist/esm/content/link-preview/transcript/providers/generic.js +11 -0
  45. package/dist/esm/content/link-preview/transcript/providers/generic.js.map +1 -0
  46. package/dist/esm/content/link-preview/transcript/providers/podcast.js +12 -0
  47. package/dist/esm/content/link-preview/transcript/providers/podcast.js.map +1 -0
  48. package/dist/esm/content/link-preview/transcript/providers/twitter.js +12 -0
  49. package/dist/esm/content/link-preview/transcript/providers/twitter.js.map +1 -0
  50. package/dist/esm/content/link-preview/transcript/providers/youtube/api.js +257 -0
  51. package/dist/esm/content/link-preview/transcript/providers/youtube/api.js.map +1 -0
  52. package/dist/esm/content/link-preview/transcript/providers/youtube/apify.js +55 -0
  53. package/dist/esm/content/link-preview/transcript/providers/youtube/apify.js.map +1 -0
  54. package/dist/esm/content/link-preview/transcript/providers/youtube/captions.js +409 -0
  55. package/dist/esm/content/link-preview/transcript/providers/youtube/captions.js.map +1 -0
  56. package/dist/esm/content/link-preview/transcript/providers/youtube/ytdlp.js +114 -0
  57. package/dist/esm/content/link-preview/transcript/providers/youtube/ytdlp.js.map +1 -0
  58. package/dist/esm/content/link-preview/transcript/providers/youtube.js +74 -0
  59. package/dist/esm/content/link-preview/transcript/providers/youtube.js.map +1 -0
  60. package/dist/esm/content/link-preview/transcript/types.js +2 -0
  61. package/dist/esm/content/link-preview/transcript/types.js.map +1 -0
  62. package/dist/esm/content/link-preview/transcript/utils.js +193 -0
  63. package/dist/esm/content/link-preview/transcript/utils.js.map +1 -0
  64. package/dist/esm/content/link-preview/types.js +2 -0
  65. package/dist/esm/content/link-preview/types.js.map +1 -0
  66. package/dist/esm/costs.js +57 -0
  67. package/dist/esm/costs.js.map +1 -0
  68. package/dist/esm/firecrawl.js +54 -0
  69. package/dist/esm/firecrawl.js.map +1 -0
  70. package/dist/esm/flags.js +97 -0
  71. package/dist/esm/flags.js.map +1 -0
  72. package/dist/esm/index.js +4 -0
  73. package/dist/esm/index.js.map +1 -0
  74. package/dist/esm/llm/generate-text.js +296 -0
  75. package/dist/esm/llm/generate-text.js.map +1 -0
  76. package/dist/esm/llm/google-models.js +112 -0
  77. package/dist/esm/llm/google-models.js.map +1 -0
  78. package/dist/esm/llm/html-to-markdown.js +44 -0
  79. package/dist/esm/llm/html-to-markdown.js.map +1 -0
  80. package/dist/esm/llm/model-id.js +45 -0
  81. package/dist/esm/llm/model-id.js.map +1 -0
  82. package/dist/esm/pricing/litellm.js +25 -0
  83. package/dist/esm/pricing/litellm.js.map +1 -0
  84. package/dist/esm/prompts/file.js +14 -0
  85. package/dist/esm/prompts/file.js.map +1 -0
  86. package/dist/esm/prompts/index.js +3 -0
  87. package/dist/esm/prompts/index.js.map +1 -0
  88. package/dist/esm/prompts/link-summary.js +105 -0
  89. package/dist/esm/prompts/link-summary.js.map +1 -0
  90. package/dist/esm/run.js +1674 -0
  91. package/dist/esm/run.js.map +1 -0
  92. package/dist/esm/shared/contracts.js +2 -0
  93. package/dist/esm/shared/contracts.js.map +1 -0
  94. package/dist/esm/summarizeHome.js +20 -0
  95. package/dist/esm/summarizeHome.js.map +1 -0
  96. package/dist/esm/tty/live-markdown.js +52 -0
  97. package/dist/esm/tty/live-markdown.js.map +1 -0
  98. package/dist/esm/tty/osc-progress.js +8 -0
  99. package/dist/esm/tty/osc-progress.js.map +1 -0
  100. package/dist/esm/tty/spinner.js +33 -0
  101. package/dist/esm/tty/spinner.js.map +1 -0
  102. package/dist/esm/version.js +44 -0
  103. package/dist/esm/version.js.map +1 -0
  104. package/dist/types/cli-main.d.ts +11 -0
  105. package/dist/types/cli.d.ts +1 -0
  106. package/dist/types/config.d.ts +15 -0
  107. package/dist/types/content/asset.d.ts +44 -0
  108. package/dist/types/content/index.d.ts +4 -0
  109. package/dist/types/content/link-preview/client.d.ts +14 -0
  110. package/dist/types/content/link-preview/content/article.d.ts +4 -0
  111. package/dist/types/content/link-preview/content/cleaner.d.ts +12 -0
  112. package/dist/types/content/link-preview/content/fetcher.d.ts +16 -0
  113. package/dist/types/content/link-preview/content/index.d.ts +4 -0
  114. package/dist/types/content/link-preview/content/parsers.d.ts +7 -0
  115. package/dist/types/content/link-preview/content/types.d.ts +44 -0
  116. package/dist/types/content/link-preview/content/utils.d.ts +16 -0
  117. package/dist/types/content/link-preview/content/youtube.d.ts +1 -0
  118. package/dist/types/content/link-preview/deps.d.ts +70 -0
  119. package/dist/types/content/link-preview/fetch-with-timeout.d.ts +4 -0
  120. package/dist/types/content/link-preview/transcript/cache.d.ts +29 -0
  121. package/dist/types/content/link-preview/transcript/index.d.ts +9 -0
  122. package/dist/types/content/link-preview/transcript/normalize.d.ts +3 -0
  123. package/dist/types/content/link-preview/transcript/providers/generic.d.ts +3 -0
  124. package/dist/types/content/link-preview/transcript/providers/podcast.d.ts +3 -0
  125. package/dist/types/content/link-preview/transcript/providers/twitter.d.ts +3 -0
  126. package/dist/types/content/link-preview/transcript/providers/youtube/api.d.ts +26 -0
  127. package/dist/types/content/link-preview/transcript/providers/youtube/apify.d.ts +1 -0
  128. package/dist/types/content/link-preview/transcript/providers/youtube/captions.d.ts +7 -0
  129. package/dist/types/content/link-preview/transcript/providers/youtube/ytdlp.d.ts +3 -0
  130. package/dist/types/content/link-preview/transcript/providers/youtube.d.ts +3 -0
  131. package/dist/types/content/link-preview/transcript/types.d.ts +23 -0
  132. package/dist/types/content/link-preview/transcript/utils.d.ts +7 -0
  133. package/dist/types/content/link-preview/types.d.ts +36 -0
  134. package/dist/types/costs.d.ts +31 -0
  135. package/dist/types/firecrawl.d.ts +5 -0
  136. package/dist/types/flags.d.ts +23 -0
  137. package/dist/types/index.d.ts +4 -0
  138. package/dist/types/llm/generate-text.d.ts +43 -0
  139. package/dist/types/llm/google-models.d.ts +10 -0
  140. package/dist/types/llm/html-to-markdown.d.ts +15 -0
  141. package/dist/types/llm/model-id.d.ts +14 -0
  142. package/dist/types/pricing/litellm.d.ts +13 -0
  143. package/dist/types/prompts/file.d.ts +6 -0
  144. package/dist/types/prompts/index.d.ts +3 -0
  145. package/dist/types/prompts/link-summary.d.ts +27 -0
  146. package/dist/types/run.d.ts +8 -0
  147. package/dist/types/shared/contracts.d.ts +2 -0
  148. package/dist/types/summarizeHome.d.ts +6 -0
  149. package/dist/types/tty/live-markdown.d.ts +10 -0
  150. package/dist/types/tty/osc-progress.d.ts +3 -0
  151. package/dist/types/tty/spinner.d.ts +10 -0
  152. package/dist/types/version.d.ts +2 -0
  153. package/docs/README.md +11 -0
  154. package/docs/config.md +28 -0
  155. package/docs/extract-only.md +13 -0
  156. package/docs/firecrawl.md +17 -0
  157. package/docs/llm.md +33 -0
  158. package/docs/openai.md +18 -0
  159. package/docs/site/.nojekyll +1 -0
  160. package/docs/site/404.html +37 -0
  161. package/docs/site/assets/site.css +577 -0
  162. package/docs/site/assets/site.js +69 -0
  163. package/docs/site/docs/config.html +73 -0
  164. package/docs/site/docs/extract-only.html +79 -0
  165. package/docs/site/docs/firecrawl.html +72 -0
  166. package/docs/site/docs/index.html +89 -0
  167. package/docs/site/docs/llm.html +70 -0
  168. package/docs/site/docs/openai.html +66 -0
  169. package/docs/site/docs/website.html +70 -0
  170. package/docs/site/docs/youtube.html +62 -0
  171. package/docs/site/index.html +125 -0
  172. package/docs/website.md +27 -0
  173. package/docs/youtube.md +32 -0
  174. package/package.json +76 -0
@@ -0,0 +1,577 @@
1
+ :root {
2
+ --bg0: #07090d;
3
+ --bg1: #0b1018;
4
+ --paper: #f2efe6;
5
+ --ink: #0d1117;
6
+ --fg0: rgba(242, 239, 230, 0.92);
7
+ --fg1: rgba(242, 239, 230, 0.74);
8
+ --fg2: rgba(242, 239, 230, 0.54);
9
+ --line: rgba(242, 239, 230, 0.14);
10
+ --shadow: 0 24px 80px rgba(0, 0, 0, 0.52);
11
+ --shadow2: 0 10px 34px rgba(0, 0, 0, 0.38);
12
+
13
+ --accent: #b7ff3c;
14
+ --accent2: #ff3d8e;
15
+ --accent3: #54b8ff;
16
+
17
+ --r: 18px;
18
+ --r2: 26px;
19
+ --max: 1080px;
20
+
21
+ --mono:
22
+ "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
23
+ "Courier New", monospace;
24
+
25
+ --body: var(--mono);
26
+ --serif: var(--mono);
27
+ }
28
+
29
+ @media (prefers-color-scheme: light) {
30
+ :root {
31
+ --bg0: #fbf7ec;
32
+ --bg1: #f2efe6;
33
+ --paper: #0d1117;
34
+ --ink: #07090d;
35
+ --fg0: rgba(10, 15, 22, 0.9);
36
+ --fg1: rgba(10, 15, 22, 0.7);
37
+ --fg2: rgba(10, 15, 22, 0.52);
38
+ --line: rgba(10, 15, 22, 0.14);
39
+ --shadow: 0 24px 80px rgba(0, 0, 0, 0.12);
40
+ --shadow2: 0 10px 34px rgba(0, 0, 0, 0.1);
41
+ }
42
+ }
43
+
44
+ * {
45
+ box-sizing: border-box;
46
+ }
47
+ html,
48
+ body {
49
+ height: 100%;
50
+ }
51
+ body {
52
+ margin: 0;
53
+ color: var(--fg0);
54
+ background:
55
+ radial-gradient(1200px 700px at 10% -10%, rgba(183, 255, 60, 0.22), transparent 60%),
56
+ radial-gradient(1000px 680px at 94% 12%, rgba(255, 61, 142, 0.16), transparent 65%),
57
+ radial-gradient(880px 560px at 75% 95%, rgba(84, 184, 255, 0.16), transparent 55%),
58
+ linear-gradient(180deg, var(--bg0), var(--bg1));
59
+ font-family: var(--body);
60
+ letter-spacing: 0.01em;
61
+ line-height: 1.45;
62
+ }
63
+
64
+ a {
65
+ color: inherit;
66
+ text-decoration: none;
67
+ }
68
+ a:hover {
69
+ text-decoration: underline;
70
+ text-decoration-thickness: 2px;
71
+ text-underline-offset: 3px;
72
+ }
73
+
74
+ .shell {
75
+ position: relative;
76
+ margin: 0 auto;
77
+ max-width: var(--max);
78
+ padding: 26px 18px 70px;
79
+ }
80
+
81
+ .shell::before {
82
+ content: "";
83
+ position: absolute;
84
+ inset: 0;
85
+ pointer-events: none;
86
+ opacity: 0.25;
87
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='128' height='128'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='128' height='128' filter='url(%23n)' opacity='.35'/%3E%3C/svg%3E");
88
+ mix-blend-mode: overlay;
89
+ }
90
+
91
+ .top {
92
+ display: flex;
93
+ align-items: center;
94
+ justify-content: space-between;
95
+ gap: 12px;
96
+ padding: 10px 6px 14px;
97
+ }
98
+
99
+ .brand {
100
+ display: inline-flex;
101
+ align-items: center;
102
+ gap: 10px;
103
+ text-decoration: none;
104
+ }
105
+
106
+ .brand:hover {
107
+ text-decoration: none;
108
+ }
109
+
110
+ .brand__mark {
111
+ width: 32px;
112
+ height: 32px;
113
+ border-radius: 12px;
114
+ display: grid;
115
+ place-items: center;
116
+ background:
117
+ radial-gradient(
118
+ circle at 30% 30%,
119
+ rgba(183, 255, 60, 0.88),
120
+ rgba(183, 255, 60, 0.12) 55%,
121
+ transparent 70%
122
+ ), radial-gradient(circle at 80% 10%, rgba(255, 61, 142, 0.66), transparent 55%),
123
+ radial-gradient(circle at 20% 85%, rgba(84, 184, 255, 0.56), transparent 55%),
124
+ rgba(255, 255, 255, 0.06);
125
+ border: 1px solid var(--line);
126
+ box-shadow: var(--shadow2);
127
+ font-family: var(--serif);
128
+ font-weight: 700;
129
+ letter-spacing: -0.02em;
130
+ }
131
+
132
+ .brand__word {
133
+ font-family: var(--serif);
134
+ font-weight: 600;
135
+ letter-spacing: 0.02em;
136
+ font-size: 18px;
137
+ }
138
+
139
+ .nav {
140
+ display: flex;
141
+ align-items: center;
142
+ gap: 12px;
143
+ }
144
+
145
+ .nav a {
146
+ padding: 8px 10px;
147
+ border-radius: 999px;
148
+ border: 1px solid transparent;
149
+ color: var(--fg1);
150
+ font-family: var(--mono);
151
+ font-size: 12px;
152
+ letter-spacing: 0.08em;
153
+ text-transform: uppercase;
154
+ }
155
+
156
+ .nav a:hover {
157
+ text-decoration: none;
158
+ color: var(--fg0);
159
+ border-color: var(--line);
160
+ background: rgba(255, 255, 255, 0.04);
161
+ }
162
+
163
+ .nav a[aria-current="page"] {
164
+ color: var(--fg0);
165
+ border-color: rgba(183, 255, 60, 0.35);
166
+ background: rgba(183, 255, 60, 0.08);
167
+ }
168
+
169
+ .hero {
170
+ padding: 18px 6px 6px;
171
+ }
172
+
173
+ .hero__grid {
174
+ display: grid;
175
+ grid-template-columns: 1.15fr 0.85fr;
176
+ gap: 18px;
177
+ }
178
+
179
+ @media (max-width: 900px) {
180
+ .hero__grid {
181
+ grid-template-columns: 1fr;
182
+ }
183
+ }
184
+
185
+ .hero__card {
186
+ position: relative;
187
+ border-radius: var(--r2);
188
+ border: 1px solid var(--line);
189
+ background:
190
+ radial-gradient(1100px 700px at 0% 0%, rgba(183, 255, 60, 0.1), transparent 50%),
191
+ radial-gradient(800px 500px at 100% 20%, rgba(255, 61, 142, 0.08), transparent 60%),
192
+ rgba(255, 255, 255, 0.04);
193
+ box-shadow: var(--shadow);
194
+ overflow: hidden;
195
+ }
196
+
197
+ .hero__card::after {
198
+ content: "";
199
+ position: absolute;
200
+ inset: -1px;
201
+ background:
202
+ linear-gradient(180deg, rgba(255, 255, 255, 0.08), transparent 55%),
203
+ linear-gradient(90deg, rgba(255, 255, 255, 0.06), transparent 42%, rgba(255, 255, 255, 0.06));
204
+ pointer-events: none;
205
+ opacity: 0.6;
206
+ }
207
+
208
+ .hero__inner {
209
+ position: relative;
210
+ padding: 22px 20px 18px;
211
+ }
212
+
213
+ .kicker {
214
+ margin: 0 0 10px;
215
+ color: var(--fg2);
216
+ font-family: var(--mono);
217
+ font-size: 12px;
218
+ letter-spacing: 0.12em;
219
+ text-transform: uppercase;
220
+ }
221
+
222
+ .title {
223
+ margin: 0;
224
+ font-family: var(--serif);
225
+ font-size: clamp(30px, 4.2vw, 46px);
226
+ font-weight: 700;
227
+ letter-spacing: -0.015em;
228
+ line-height: 1.02;
229
+ }
230
+
231
+ .lede {
232
+ margin: 12px 0 0;
233
+ color: var(--fg1);
234
+ font-size: 18px;
235
+ max-width: 60ch;
236
+ }
237
+
238
+ .lede strong {
239
+ color: var(--fg0);
240
+ font-weight: 600;
241
+ }
242
+
243
+ .pillRow {
244
+ display: flex;
245
+ flex-wrap: wrap;
246
+ gap: 10px;
247
+ margin-top: 16px;
248
+ }
249
+
250
+ .pill {
251
+ display: inline-flex;
252
+ align-items: center;
253
+ gap: 8px;
254
+ padding: 10px 12px;
255
+ border: 1px solid var(--line);
256
+ border-radius: 999px;
257
+ color: var(--fg1);
258
+ background: rgba(255, 255, 255, 0.03);
259
+ font-family: var(--mono);
260
+ font-size: 12px;
261
+ }
262
+
263
+ .pill__dot {
264
+ width: 8px;
265
+ height: 8px;
266
+ border-radius: 999px;
267
+ background: var(--accent);
268
+ box-shadow: 0 0 0 4px rgba(183, 255, 60, 0.16);
269
+ }
270
+
271
+ .ctaRow {
272
+ display: flex;
273
+ flex-wrap: wrap;
274
+ gap: 10px;
275
+ margin-top: 18px;
276
+ }
277
+
278
+ .btn {
279
+ display: inline-flex;
280
+ align-items: center;
281
+ justify-content: center;
282
+ gap: 10px;
283
+ padding: 11px 14px;
284
+ border-radius: 14px;
285
+ border: 1px solid var(--line);
286
+ background: rgba(255, 255, 255, 0.03);
287
+ color: var(--fg0);
288
+ font-family: var(--mono);
289
+ font-size: 12px;
290
+ letter-spacing: 0.08em;
291
+ text-transform: uppercase;
292
+ cursor: pointer;
293
+ }
294
+
295
+ .btn:hover {
296
+ text-decoration: none;
297
+ background: rgba(255, 255, 255, 0.06);
298
+ }
299
+
300
+ .btn--primary {
301
+ border-color: rgba(183, 255, 60, 0.42);
302
+ background:
303
+ radial-gradient(circle at 20% 10%, rgba(183, 255, 60, 0.26), transparent 60%),
304
+ rgba(183, 255, 60, 0.08);
305
+ }
306
+
307
+ .btn--primary:hover {
308
+ background:
309
+ radial-gradient(circle at 20% 10%, rgba(183, 255, 60, 0.32), transparent 60%),
310
+ rgba(183, 255, 60, 0.12);
311
+ }
312
+
313
+ .btn__icon {
314
+ width: 16px;
315
+ height: 16px;
316
+ opacity: 0.9;
317
+ }
318
+
319
+ .codeCard {
320
+ position: relative;
321
+ padding: 18px 18px 16px;
322
+ border-left: 1px solid var(--line);
323
+ background:
324
+ linear-gradient(180deg, rgba(0, 0, 0, 0.18), transparent 40%), rgba(255, 255, 255, 0.03);
325
+ }
326
+
327
+ @media (max-width: 900px) {
328
+ .codeCard {
329
+ border-left: none;
330
+ border-top: 1px solid var(--line);
331
+ }
332
+ }
333
+
334
+ .terminal {
335
+ border-radius: var(--r);
336
+ border: 1px solid rgba(255, 255, 255, 0.14);
337
+ background: rgba(0, 0, 0, 0.35);
338
+ overflow: hidden;
339
+ }
340
+
341
+ .terminal__bar {
342
+ display: flex;
343
+ gap: 6px;
344
+ padding: 10px 12px;
345
+ border-bottom: 1px solid rgba(255, 255, 255, 0.12);
346
+ background: rgba(255, 255, 255, 0.04);
347
+ }
348
+ .terminal__dot {
349
+ width: 10px;
350
+ height: 10px;
351
+ border-radius: 999px;
352
+ background: rgba(255, 255, 255, 0.18);
353
+ }
354
+ .terminal__dot--a {
355
+ background: rgba(255, 61, 142, 0.65);
356
+ }
357
+ .terminal__dot--b {
358
+ background: rgba(183, 255, 60, 0.6);
359
+ }
360
+ .terminal__dot--c {
361
+ background: rgba(84, 184, 255, 0.6);
362
+ }
363
+
364
+ pre {
365
+ margin: 0;
366
+ padding: 14px 14px 12px;
367
+ color: rgba(242, 239, 230, 0.94);
368
+ font-family: var(--mono);
369
+ font-size: 13px;
370
+ line-height: 1.55;
371
+ overflow-x: auto;
372
+ }
373
+
374
+ code {
375
+ font-family: var(--mono);
376
+ }
377
+
378
+ .copyRow {
379
+ display: flex;
380
+ align-items: center;
381
+ justify-content: space-between;
382
+ gap: 12px;
383
+ margin-top: 12px;
384
+ }
385
+
386
+ .hint {
387
+ color: var(--fg2);
388
+ font-family: var(--mono);
389
+ font-size: 12px;
390
+ }
391
+
392
+ .grid {
393
+ display: grid;
394
+ grid-template-columns: repeat(12, 1fr);
395
+ gap: 14px;
396
+ margin-top: 18px;
397
+ padding: 0 6px;
398
+ }
399
+
400
+ .card {
401
+ grid-column: span 6;
402
+ border-radius: var(--r2);
403
+ border: 1px solid var(--line);
404
+ background: rgba(255, 255, 255, 0.03);
405
+ padding: 18px 16px 16px;
406
+ box-shadow: var(--shadow2);
407
+ }
408
+
409
+ @media (max-width: 900px) {
410
+ .card {
411
+ grid-column: span 12;
412
+ }
413
+ }
414
+
415
+ .card h2 {
416
+ margin: 0 0 8px;
417
+ font-family: var(--serif);
418
+ font-weight: 650;
419
+ letter-spacing: -0.01em;
420
+ font-size: 18px;
421
+ }
422
+
423
+ .card p {
424
+ margin: 0;
425
+ color: var(--fg1);
426
+ }
427
+
428
+ .card .small {
429
+ margin-top: 10px;
430
+ color: var(--fg2);
431
+ font-family: var(--mono);
432
+ font-size: 12px;
433
+ letter-spacing: 0.06em;
434
+ }
435
+
436
+ .footer {
437
+ margin-top: 30px;
438
+ padding: 18px 6px 0;
439
+ border-top: 1px solid var(--line);
440
+ display: flex;
441
+ flex-wrap: wrap;
442
+ align-items: baseline;
443
+ justify-content: space-between;
444
+ gap: 10px;
445
+ color: var(--fg2);
446
+ font-family: var(--mono);
447
+ font-size: 12px;
448
+ }
449
+
450
+ .footer a {
451
+ color: var(--fg1);
452
+ }
453
+
454
+ .reveal {
455
+ opacity: 0;
456
+ transform: translateY(10px);
457
+ }
458
+ .reveal.is-on {
459
+ opacity: 1;
460
+ transform: translateY(0);
461
+ transition:
462
+ opacity 700ms cubic-bezier(0.2, 0.9, 0.2, 1),
463
+ transform 700ms cubic-bezier(0.2, 0.9, 0.2, 1);
464
+ }
465
+
466
+ .hero--compact .hero__card {
467
+ max-width: 720px;
468
+ margin: 30px auto 0;
469
+ }
470
+ .hero--compact .hero__inner,
471
+ .hero--compact .hero__card {
472
+ padding: 22px;
473
+ }
474
+
475
+ .docShell {
476
+ display: grid;
477
+ grid-template-columns: 260px 1fr;
478
+ gap: 18px;
479
+ padding: 10px 6px 0;
480
+ }
481
+ @media (max-width: 900px) {
482
+ .docShell {
483
+ grid-template-columns: 1fr;
484
+ }
485
+ }
486
+
487
+ .side {
488
+ position: sticky;
489
+ top: 14px;
490
+ align-self: start;
491
+ border-radius: var(--r2);
492
+ border: 1px solid var(--line);
493
+ background: rgba(255, 255, 255, 0.03);
494
+ padding: 14px 12px;
495
+ box-shadow: var(--shadow2);
496
+ }
497
+
498
+ @media (max-width: 900px) {
499
+ .side {
500
+ position: static;
501
+ }
502
+ }
503
+
504
+ .side h2 {
505
+ margin: 0 0 10px;
506
+ font-family: var(--mono);
507
+ font-size: 12px;
508
+ letter-spacing: 0.12em;
509
+ text-transform: uppercase;
510
+ color: var(--fg2);
511
+ }
512
+
513
+ .side a {
514
+ display: block;
515
+ padding: 9px 10px;
516
+ border-radius: 12px;
517
+ border: 1px solid transparent;
518
+ color: var(--fg1);
519
+ font-family: var(--mono);
520
+ font-size: 12px;
521
+ }
522
+
523
+ .side a:hover {
524
+ text-decoration: none;
525
+ border-color: var(--line);
526
+ background: rgba(255, 255, 255, 0.04);
527
+ color: var(--fg0);
528
+ }
529
+ .side a[aria-current="page"] {
530
+ border-color: rgba(183, 255, 60, 0.35);
531
+ background: rgba(183, 255, 60, 0.08);
532
+ color: var(--fg0);
533
+ }
534
+
535
+ .doc {
536
+ border-radius: var(--r2);
537
+ border: 1px solid var(--line);
538
+ background: rgba(255, 255, 255, 0.03);
539
+ box-shadow: var(--shadow);
540
+ padding: 18px 18px 14px;
541
+ }
542
+
543
+ .doc h1 {
544
+ margin: 0 0 10px;
545
+ font-family: var(--serif);
546
+ font-weight: 700;
547
+ letter-spacing: -0.015em;
548
+ font-size: 30px;
549
+ }
550
+
551
+ .doc h2 {
552
+ margin: 18px 0 8px;
553
+ font-family: var(--serif);
554
+ font-weight: 650;
555
+ letter-spacing: -0.01em;
556
+ font-size: 18px;
557
+ }
558
+
559
+ .doc ul {
560
+ margin: 8px 0 0 18px;
561
+ color: var(--fg1);
562
+ }
563
+ .doc li {
564
+ margin: 6px 0;
565
+ }
566
+ .doc p {
567
+ margin: 10px 0 0;
568
+ color: var(--fg1);
569
+ }
570
+ .doc .note {
571
+ margin-top: 14px;
572
+ padding: 12px 12px;
573
+ border-radius: 14px;
574
+ border: 1px dashed rgba(183, 255, 60, 0.35);
575
+ background: rgba(183, 255, 60, 0.06);
576
+ color: var(--fg1);
577
+ }
@@ -0,0 +1,69 @@
1
+ const canonicalHost = 'summarize.sh'
2
+ const redirectHostnames = new Set(['summarize.is', 'www.summarize.is'])
3
+
4
+ const maybeRedirect = () => {
5
+ try {
6
+ const { hostname, pathname, search, hash } = window.location
7
+ if (!redirectHostnames.has(hostname)) return
8
+ const target = `https://${canonicalHost}${pathname}${search}${hash}`
9
+ window.location.replace(target)
10
+ } catch {
11
+ // ignore
12
+ }
13
+ }
14
+
15
+ const highlightNav = () => {
16
+ const path = window.location.pathname
17
+ const isDocs = path.includes('/docs/')
18
+ const navDocs = document.querySelector('a[data-nav="docs"]')
19
+ const navHome = document.querySelector('a[data-nav="home"]')
20
+ if (navDocs && isDocs) navDocs.setAttribute('aria-current', 'page')
21
+ if (navHome && !isDocs) navHome.setAttribute('aria-current', 'page')
22
+
23
+ const sideLinks = document.querySelectorAll('.side a[href]')
24
+ for (const a of sideLinks) {
25
+ const href = a.getAttribute('href') ?? ''
26
+ if (!href) continue
27
+ const normalized = href.replace(/^\.\//, '')
28
+ if (path.endsWith(normalized)) a.setAttribute('aria-current', 'page')
29
+ }
30
+ }
31
+
32
+ const wireCopyButtons = () => {
33
+ const buttons = document.querySelectorAll('[data-copy]')
34
+ for (const button of buttons) {
35
+ button.addEventListener('click', async () => {
36
+ const selector = button.getAttribute('data-copy')
37
+ const target = selector ? document.querySelector(selector) : null
38
+ const text = target?.textContent?.trim() ?? ''
39
+ if (!text) return
40
+ try {
41
+ await navigator.clipboard.writeText(text)
42
+ const prev = button.textContent ?? ''
43
+ button.textContent = 'Copied'
44
+ button.setAttribute('data-copied', '1')
45
+ window.setTimeout(() => {
46
+ button.textContent = prev
47
+ button.removeAttribute('data-copied')
48
+ }, 900)
49
+ } catch {
50
+ // ignore
51
+ }
52
+ })
53
+ }
54
+ }
55
+
56
+ const reveal = () => {
57
+ const items = document.querySelectorAll('.reveal')
58
+ let i = 0
59
+ for (const el of items) {
60
+ const delay = Math.min(380, i * 70)
61
+ window.setTimeout(() => el.classList.add('is-on'), delay)
62
+ i++
63
+ }
64
+ }
65
+
66
+ maybeRedirect()
67
+ highlightNav()
68
+ wireCopyButtons()
69
+ reveal()
@@ -0,0 +1,73 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
6
+ <meta name="color-scheme" content="dark light" />
7
+ <title>Config — summarize</title>
8
+ <link rel="canonical" href="https://summarize.sh/docs/config" />
9
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
10
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
11
+ <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600;700&display=swap" rel="stylesheet" />
12
+ <link rel="stylesheet" href="../assets/site.css" />
13
+ </head>
14
+ <body>
15
+ <main class="shell">
16
+ <header class="top">
17
+ <a class="brand" href="../index.html" aria-label="summarize home">
18
+ <span class="brand__mark" aria-hidden="true">s</span>
19
+ <span class="brand__word">summarize</span>
20
+ </a>
21
+ <nav class="nav" aria-label="Primary">
22
+ <a data-nav="home" href="../index.html">Home</a>
23
+ <a data-nav="docs" href="./index.html">Docs</a>
24
+ <a href="https://github.com/steipete/summarize">GitHub</a>
25
+ </nav>
26
+ </header>
27
+
28
+ <section class="docShell">
29
+ <aside class="side" aria-label="Docs navigation">
30
+ <h2>Docs</h2>
31
+ <a href="./index.html">Overview</a>
32
+ <a href="./website.html">Website mode</a>
33
+ <a href="./youtube.html">YouTube mode</a>
34
+ <a href="./extract-only.html">Extract-only</a>
35
+ <a href="./llm.html">LLM</a>
36
+ <a href="./openai.html">OpenAI</a>
37
+ <a href="./firecrawl.html">Firecrawl</a>
38
+ <a href="./config.html">Config</a>
39
+ </aside>
40
+
41
+ <article class="doc reveal">
42
+ <p class="kicker">docs</p>
43
+ <h1>Config</h1>
44
+ <p>summarize is mostly flags + env vars. Keep secrets in env; keep defaults in a shell profile.</p>
45
+
46
+ <h2>Environment variables</h2>
47
+ <ul>
48
+ <li><code>OPENAI_API_KEY</code>, <code>XAI_API_KEY</code>, <code>GEMINI_API_KEY</code> — provider keys (only needed when a mode actually calls an LLM).</li>
49
+ <li><code>FIRECRAWL_API_KEY</code> — optional extraction fallback / preferred Markdown output in extract-only.</li>
50
+ </ul>
51
+
52
+ <h2>Tips</h2>
53
+ <ul>
54
+ <li>For deterministic output, pin <code>--model</code> and avoid provider fallback.</li>
55
+ <li>When debugging extraction, add <code>--verbose</code> and/or <code>--json</code> for structured output.</li>
56
+ <li>Use <code>--timeout</code> when crawling slow sites (defaults to <code>2m</code>).</li>
57
+ </ul>
58
+
59
+ <div class="note">
60
+ Want the raw content? Use <code>--extract-only</code> (then decide where the summary should happen).
61
+ </div>
62
+ </article>
63
+ </section>
64
+
65
+ <footer class="footer">
66
+ <span>summarize — Link → clean text → summary.</span>
67
+ <span><a href="./index.html">Docs</a> · <a href="https://github.com/steipete/summarize">Repo</a></span>
68
+ </footer>
69
+ </main>
70
+
71
+ <script type="module" src="../assets/site.js"></script>
72
+ </body>
73
+ </html>