@getpagr/cli 1.0.1

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 (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +412 -0
  3. package/dist/commands/config.d.ts +2 -0
  4. package/dist/commands/config.d.ts.map +1 -0
  5. package/dist/commands/config.js +63 -0
  6. package/dist/commands/config.js.map +1 -0
  7. package/dist/commands/init.d.ts +15 -0
  8. package/dist/commands/init.d.ts.map +1 -0
  9. package/dist/commands/init.js +337 -0
  10. package/dist/commands/init.js.map +1 -0
  11. package/dist/commands/list.d.ts +9 -0
  12. package/dist/commands/list.d.ts.map +1 -0
  13. package/dist/commands/list.js +52 -0
  14. package/dist/commands/list.js.map +1 -0
  15. package/dist/commands/login.d.ts +14 -0
  16. package/dist/commands/login.d.ts.map +1 -0
  17. package/dist/commands/login.js +201 -0
  18. package/dist/commands/login.js.map +1 -0
  19. package/dist/commands/login.test.d.ts +2 -0
  20. package/dist/commands/login.test.d.ts.map +1 -0
  21. package/dist/commands/login.test.js +34 -0
  22. package/dist/commands/login.test.js.map +1 -0
  23. package/dist/commands/remove.d.ts +13 -0
  24. package/dist/commands/remove.d.ts.map +1 -0
  25. package/dist/commands/remove.js +43 -0
  26. package/dist/commands/remove.js.map +1 -0
  27. package/dist/commands/upload.d.ts +53 -0
  28. package/dist/commands/upload.d.ts.map +1 -0
  29. package/dist/commands/upload.js +186 -0
  30. package/dist/commands/upload.js.map +1 -0
  31. package/dist/index.d.ts +3 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +25 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/lib/api.d.ts +52 -0
  36. package/dist/lib/api.d.ts.map +1 -0
  37. package/dist/lib/api.js +140 -0
  38. package/dist/lib/api.js.map +1 -0
  39. package/dist/lib/config.d.ts +10 -0
  40. package/dist/lib/config.d.ts.map +1 -0
  41. package/dist/lib/config.js +39 -0
  42. package/dist/lib/config.js.map +1 -0
  43. package/dist/lib/meta.d.ts +5 -0
  44. package/dist/lib/meta.d.ts.map +1 -0
  45. package/dist/lib/meta.js +35 -0
  46. package/dist/lib/meta.js.map +1 -0
  47. package/dist/lib/meta.test.d.ts +2 -0
  48. package/dist/lib/meta.test.d.ts.map +1 -0
  49. package/dist/lib/meta.test.js +81 -0
  50. package/dist/lib/meta.test.js.map +1 -0
  51. package/package.json +57 -0
@@ -0,0 +1,337 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { defineCommand } from 'citty';
4
+ const SKILL_MD = [
5
+ '# Pagr CLI Skill',
6
+ '',
7
+ 'Use this skill when the user wants to publish, update, list, delete, or manage HTML files with the Pagr CLI.',
8
+ '',
9
+ '## When To Use This Skill',
10
+ '',
11
+ '- Publishing generated HTML reports, dashboards, documents, or plans.',
12
+ '- Updating existing published Pagr pages while keeping the same public URL.',
13
+ '- Creating shareable URLs for local HTML artifacts.',
14
+ '- Listing or deleting Pagr files from a user account.',
15
+ '- Setting up Pagr in a project for agent workflows.',
16
+ '- Publishing HTML artifacts from CI.',
17
+ '',
18
+ '## Core Rules',
19
+ '',
20
+ '- Use `pagr upload <file>` for HTML files.',
21
+ '- Never invent a Pagr URL. Always return the URL printed by the CLI.',
22
+ '- If a file contains `<meta name="pagr-id">` or `<meta name="pagr-slug">`, `pagr upload <file>` may update the existing page instead of creating a new one.',
23
+ '- Updates replace the current HTML in place. Pagr does not store previous HTML versions or rollback history.',
24
+ '- Prefer `PAGR_API_KEY` in CI instead of writing `~/.pagr/config.json`.',
25
+ '- Do not print or expose full API keys unless the user explicitly asks to configure authentication.',
26
+ '- If upload, update, list, or delete fails, surface the exact CLI/API error.',
27
+ '',
28
+ '## Installation',
29
+ '',
30
+ '```bash',
31
+ 'npm install -g @getpagr/cli',
32
+ '```',
33
+ '',
34
+ 'Pagr CLI requires Node.js 20 or newer. The installed command is `pagr`.',
35
+ '',
36
+ '## Authentication',
37
+ '',
38
+ 'Browser login:',
39
+ '',
40
+ '```bash',
41
+ 'pagr login',
42
+ '```',
43
+ '',
44
+ '`pagr login` starts a browser login flow, authenticates with Pagr, receives a CLI API key through a local callback, and saves it to `~/.pagr/config.json`.',
45
+ '',
46
+ 'Manual login for SSH, headless, or locked-down environments:',
47
+ '',
48
+ '```bash',
49
+ 'pagr login --manual',
50
+ '```',
51
+ '',
52
+ 'Save a key without prompting:',
53
+ '',
54
+ '```bash',
55
+ 'pagr login --key pagr_...',
56
+ '```',
57
+ '',
58
+ 'Set a key directly in local config:',
59
+ '',
60
+ '```bash',
61
+ 'pagr config set-key pagr_...',
62
+ '```',
63
+ '',
64
+ 'API keys must start with `pagr_`.',
65
+ '',
66
+ 'Config location:',
67
+ '',
68
+ '```text',
69
+ '~/.pagr/config.json',
70
+ '```',
71
+ '',
72
+ 'Auth lookup order:',
73
+ '',
74
+ '1. `PAGR_API_KEY`',
75
+ '2. `~/.pagr/config.json`',
76
+ '3. Error if neither exists',
77
+ '',
78
+ '## Upload New HTML',
79
+ '',
80
+ '```bash',
81
+ 'pagr upload report.html',
82
+ '```',
83
+ '',
84
+ 'Behavior:',
85
+ '',
86
+ '- Reads the local HTML file as UTF-8.',
87
+ '- Uploads raw HTML to Pagr.',
88
+ '- Prints the public URL.',
89
+ '- Copies the URL to the clipboard when supported.',
90
+ '- When `CI` is set, also prints:',
91
+ '',
92
+ '```text',
93
+ 'PAGR_SLUG=...',
94
+ 'PAGR_URL=...',
95
+ '```',
96
+ '',
97
+ '## Upload With Title And Slug',
98
+ '',
99
+ 'Set a page title:',
100
+ '',
101
+ '```bash',
102
+ 'pagr upload report.html --title "Weekly report"',
103
+ 'pagr upload report.html -t "Weekly report"',
104
+ '```',
105
+ '',
106
+ 'Request a stable readable slug:',
107
+ '',
108
+ '```bash',
109
+ 'pagr upload report.html --slug weekly-report',
110
+ 'pagr upload report.html -s weekly-report',
111
+ '```',
112
+ '',
113
+ 'Use both:',
114
+ '',
115
+ '```bash',
116
+ 'pagr upload report.html --slug weekly-report --title "Weekly report"',
117
+ '```',
118
+ '',
119
+ '`--title` sends `X-Pagr-Title`. `--slug` requests a stable readable URL. Custom slugs can be plan-gated.',
120
+ '',
121
+ '## Update Existing Pages',
122
+ '',
123
+ '```bash',
124
+ 'pagr upload report.html --update --slug weekly-report',
125
+ 'pagr upload report.html -u -s weekly-report',
126
+ '```',
127
+ '',
128
+ 'Behavior:',
129
+ '',
130
+ '- Checks slug ownership first.',
131
+ '- Fails if the slug is missing or not owned by the authenticated user.',
132
+ '- Sends replacement HTML to the existing page.',
133
+ '- Keeps the public URL stable.',
134
+ '- Replaces current content in place; this is not versioning.',
135
+ '',
136
+ '## Auto-Update With Meta Tags',
137
+ '',
138
+ '```html',
139
+ '<meta name="pagr-id" content="...">',
140
+ '<meta name="pagr-slug" content="weekly-report">',
141
+ '```',
142
+ '',
143
+ 'Update priority:',
144
+ '',
145
+ '1. `pagr-id` updates by stable document ID.',
146
+ '2. `pagr-slug` updates by slug.',
147
+ '3. `--update --slug` forces update by slug.',
148
+ '4. Otherwise a new file is uploaded.',
149
+ '',
150
+ 'Inject Pagr metadata into the source file:',
151
+ '',
152
+ '```bash',
153
+ 'pagr upload report.html --inject',
154
+ '```',
155
+ '',
156
+ '`--inject` writes Pagr metadata into the local HTML source after upload. If a new upload has no `pagr-slug`, the CLI auto-injects metadata for future updates. This modifies the local source HTML file.',
157
+ '',
158
+ '## List Files',
159
+ '',
160
+ '```bash',
161
+ 'pagr ls',
162
+ 'pagr ls --limit 20',
163
+ '```',
164
+ '',
165
+ 'Default limit is 50. Output includes slug, views, plan, title, and URL. If no files exist, the CLI prints `No files found.`',
166
+ '',
167
+ '## Delete Files',
168
+ '',
169
+ '```bash',
170
+ 'pagr rm weekly-report',
171
+ 'pagr rm weekly-report --yes',
172
+ 'pagr rm weekly-report -y',
173
+ '```',
174
+ '',
175
+ 'Without `--yes`, the CLI asks for confirmation and accepts `y` or `yes`. Delete is not reversible.',
176
+ '',
177
+ '## Config Commands',
178
+ '',
179
+ '```bash',
180
+ 'pagr config show',
181
+ 'pagr config set-key pagr_...',
182
+ 'pagr config set-url https://pagr.link',
183
+ '```',
184
+ '',
185
+ '`pagr config show` masks the API key. `set-key` requires a `pagr_` prefix. `set-url` overrides the Worker API URL in local config. Environment variables override local config.',
186
+ '',
187
+ '## Init Command',
188
+ '',
189
+ '```bash',
190
+ 'pagr init',
191
+ 'pagr init --no-claude',
192
+ 'pagr init --no-mcp',
193
+ '```',
194
+ '',
195
+ '`pagr init` writes:',
196
+ '',
197
+ '- `SKILL.md`',
198
+ '- `.claude/skills/pagr/SKILL.md` unless `--no-claude`',
199
+ '- `.agents/skills/pagr/SKILL.md`',
200
+ '- `.claude/settings.json` MCP server config unless `--no-mcp`',
201
+ '',
202
+ 'MCP config:',
203
+ '',
204
+ '```json',
205
+ '{',
206
+ ' "mcpServers": {',
207
+ ' "pagr": {',
208
+ ' "command": "npx",',
209
+ ' "args": ["-y", "@pagr/mcp"]',
210
+ ' }',
211
+ ' }',
212
+ '}',
213
+ '```',
214
+ '',
215
+ '## CI Usage',
216
+ '',
217
+ 'Use `PAGR_API_KEY` in CI. Do not write `~/.pagr/config.json` in CI.',
218
+ '',
219
+ '```yaml',
220
+ '- name: Publish HTML report',
221
+ ' run: pagr upload output/report.html --title "Nightly report"',
222
+ ' env:',
223
+ ' PAGR_API_KEY: ${{ secrets.PAGR_API_KEY }}',
224
+ '```',
225
+ '',
226
+ 'When `CI` is set, use the machine-readable `PAGR_SLUG` and `PAGR_URL` output lines.',
227
+ '',
228
+ '## Environment Variables',
229
+ '',
230
+ '- `PAGR_API_KEY`: overrides the locally saved key.',
231
+ '- `PAGR_WORKER_URL`: overrides the Worker API URL. Default is `https://pagr.link`.',
232
+ '- `PAGR_APP_URL`: overrides the app URL used by `pagr login`. Default is `https://app.getpagr.co`.',
233
+ '- `CI`: makes upload print machine-readable `PAGR_SLUG` and `PAGR_URL`.',
234
+ '',
235
+ '## Error Handling',
236
+ '',
237
+ 'Common failures:',
238
+ '',
239
+ '- Missing API key: run `pagr login`, run `pagr login --manual`, or set `PAGR_API_KEY`.',
240
+ '- Invalid API key format: keys must start with `pagr_`.',
241
+ '- Cannot read file: confirm the path exists and points to an HTML file.',
242
+ '- Slug not found or not owned during update: upload without `--update` or use the correct slug.',
243
+ '- Upload/update/list/delete API errors: surface the exact CLI error.',
244
+ '- Clipboard failure does not fail upload; the URL is still printed.',
245
+ '',
246
+ 'If browser login fails, use `pagr login --manual`. If upload fails due to plan or file limit, surface the CLI error and tell the user to check account plan and file size.',
247
+ '',
248
+ '## Agent Workflow',
249
+ '',
250
+ '1. Confirm the target file exists and is HTML.',
251
+ '2. If the user wants a stable URL, use `--slug`.',
252
+ '3. If the file already has `pagr-id` or `pagr-slug`, use plain `pagr upload <file>` unless the user asks for a new page.',
253
+ '4. If the user explicitly wants to replace an existing page, use:',
254
+ '',
255
+ '```bash',
256
+ 'pagr upload <file> --update --slug <slug>',
257
+ '```',
258
+ '',
259
+ '5. Return the URL printed by the CLI.',
260
+ '6. In CI, capture `PAGR_URL`.',
261
+ ].join('\n') + '\n';
262
+ const CLAUDE_SKILL_MD = SKILL_MD;
263
+ export const initCommand = defineCommand({
264
+ meta: {
265
+ name: 'init',
266
+ description: 'Initialize Pagr in the current directory',
267
+ },
268
+ args: {
269
+ claude: {
270
+ type: 'boolean',
271
+ default: true,
272
+ description: 'Create the Claude Code skill file',
273
+ negativeDescription: 'Skip creating the Claude Code skill file',
274
+ },
275
+ mcp: {
276
+ type: 'boolean',
277
+ default: true,
278
+ description: 'Create the Claude Code MCP server config',
279
+ negativeDescription: 'Skip creating the Claude Code MCP server config',
280
+ },
281
+ },
282
+ run({ args }) {
283
+ const cwd = process.cwd();
284
+ writeFileSync(join(cwd, 'SKILL.md'), SKILL_MD, 'utf-8');
285
+ console.log('Created SKILL.md');
286
+ if (args.claude) {
287
+ const claudeSkillsDir = join(cwd, '.claude', 'skills', 'pagr');
288
+ if (!existsSync(claudeSkillsDir)) {
289
+ mkdirSync(claudeSkillsDir, { recursive: true });
290
+ }
291
+ writeFileSync(join(claudeSkillsDir, 'SKILL.md'), CLAUDE_SKILL_MD, 'utf-8');
292
+ console.log('Created .claude/skills/pagr/SKILL.md');
293
+ }
294
+ const agentsSkillsDir = join(cwd, '.agents', 'skills', 'pagr');
295
+ if (!existsSync(agentsSkillsDir)) {
296
+ mkdirSync(agentsSkillsDir, { recursive: true });
297
+ }
298
+ writeFileSync(join(agentsSkillsDir, 'SKILL.md'), SKILL_MD, 'utf-8');
299
+ console.log('Created .agents/skills/pagr/SKILL.md');
300
+ if (args.mcp) {
301
+ writeClaudeMcpSettings(cwd);
302
+ console.log('Updated .claude/settings.json with the Pagr MCP server');
303
+ }
304
+ console.log('\nNext steps:');
305
+ console.log(' 1. Set your API key: pagr login');
306
+ console.log(' 2. Upload a file: pagr upload myfile.html');
307
+ console.log(' 3. For MCP: expose PAGR_API_KEY to Claude Code');
308
+ },
309
+ });
310
+ function writeClaudeMcpSettings(cwd) {
311
+ const claudeDir = join(cwd, '.claude');
312
+ if (!existsSync(claudeDir)) {
313
+ mkdirSync(claudeDir, { recursive: true });
314
+ }
315
+ const settingsPath = join(claudeDir, 'settings.json');
316
+ const settings = readClaudeSettings(settingsPath);
317
+ settings.mcpServers = {
318
+ ...(settings.mcpServers ?? {}),
319
+ pagr: {
320
+ command: 'npx',
321
+ args: ['-y', '@pagr/mcp'],
322
+ },
323
+ };
324
+ writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, 'utf-8');
325
+ }
326
+ function readClaudeSettings(settingsPath) {
327
+ if (!existsSync(settingsPath))
328
+ return {};
329
+ try {
330
+ return JSON.parse(readFileSync(settingsPath, 'utf-8'));
331
+ }
332
+ catch {
333
+ console.warn(`Could not parse ${settingsPath}; replacing it with a fresh Claude settings file.`);
334
+ return {};
335
+ }
336
+ }
337
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export declare const listCommand: import("citty").CommandDef<{
2
+ readonly limit: {
3
+ readonly type: "string";
4
+ readonly default: "50";
5
+ readonly description: "Maximum number of files to show";
6
+ readonly valueHint: "count";
7
+ };
8
+ }>;
9
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW;;;;;;;EAmCtB,CAAA"}
@@ -0,0 +1,52 @@
1
+ import { defineCommand } from 'citty';
2
+ import { listFiles } from '../lib/api.js';
3
+ import { getApiKey, getWorkerUrl } from '../lib/config.js';
4
+ export const listCommand = defineCommand({
5
+ meta: {
6
+ name: 'ls',
7
+ description: 'List your Pagr files',
8
+ alias: 'list',
9
+ },
10
+ args: {
11
+ limit: {
12
+ type: 'string',
13
+ default: '50',
14
+ description: 'Maximum number of files to show',
15
+ valueHint: 'count',
16
+ },
17
+ },
18
+ async run({ args }) {
19
+ const apiKey = getApiKey();
20
+ const workerUrl = getWorkerUrl();
21
+ const limit = Number.parseInt(args.limit ?? '50', 10);
22
+ const files = await listFiles(apiKey, workerUrl, Number.isFinite(limit) ? limit : 50);
23
+ if (files.length === 0) {
24
+ console.log('No files found.');
25
+ return;
26
+ }
27
+ const rows = files.map((file) => ({
28
+ slug: file.slug,
29
+ views: String(file.views ?? 0),
30
+ plan: file.plan,
31
+ title: truncate(file.title, 32),
32
+ url: file.url,
33
+ }));
34
+ printTable(rows);
35
+ },
36
+ });
37
+ function printTable(rows) {
38
+ const headers = ['slug', 'views', 'plan', 'title', 'url'];
39
+ const widths = Object.fromEntries(headers.map((header) => [
40
+ header,
41
+ Math.max(header.length, ...rows.map((row) => row[header]?.length ?? 0)),
42
+ ]));
43
+ console.log(headers.map((header) => header.padEnd(widths[header])).join(' '));
44
+ console.log(headers.map((header) => '-'.repeat(widths[header])).join(' '));
45
+ for (const row of rows) {
46
+ console.log(headers.map((header) => (row[header] ?? '').padEnd(widths[header])).join(' '));
47
+ }
48
+ }
49
+ function truncate(value, length) {
50
+ return value.length <= length ? value : `${value.slice(0, length - 1)}...`;
51
+ }
52
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export declare const loginCommand: import("citty").CommandDef<{
2
+ readonly key: {
3
+ readonly type: "string";
4
+ readonly description: "API key to save without prompting";
5
+ readonly valueHint: "pagr_...";
6
+ };
7
+ readonly manual: {
8
+ readonly type: "boolean";
9
+ readonly description: "Paste an API key manually instead of using browser login";
10
+ };
11
+ }>;
12
+ export declare function buildCliLoginUrl(callbackUrl: string, state: string): string;
13
+ export declare function validateCallbackPayload(body: URLSearchParams, expectedState: string): string;
14
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,YAAY;;;;;;;;;;EA8BvB,CAAA;AA2CF,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAM3E;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAa5F"}
@@ -0,0 +1,201 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import { createServer } from 'node:http';
3
+ import { spawn } from 'node:child_process';
4
+ import { platform } from 'node:os';
5
+ import { createInterface } from 'node:readline/promises';
6
+ import { stdin as input, stdout as output } from 'node:process';
7
+ import { defineCommand } from 'citty';
8
+ import { readConfig, writeConfig } from '../lib/config.js';
9
+ const DEFAULT_APP_URL = 'https://app.getpagr.co';
10
+ const LOGIN_TIMEOUT_MS = 5 * 60 * 1000;
11
+ export const loginCommand = defineCommand({
12
+ meta: {
13
+ name: 'login',
14
+ description: 'Open Pagr and save an API key to ~/.pagr/config.json',
15
+ },
16
+ args: {
17
+ key: {
18
+ type: 'string',
19
+ description: 'API key to save without prompting',
20
+ valueHint: 'pagr_...',
21
+ },
22
+ manual: {
23
+ type: 'boolean',
24
+ description: 'Paste an API key manually instead of using browser login',
25
+ },
26
+ },
27
+ async run({ args }) {
28
+ if (args.key) {
29
+ saveApiKey(args.key);
30
+ return;
31
+ }
32
+ if (args.manual || await chooseManualLogin()) {
33
+ saveApiKey(await promptForApiKey());
34
+ return;
35
+ }
36
+ const key = await browserLogin();
37
+ saveApiKey(key);
38
+ },
39
+ });
40
+ async function chooseManualLogin() {
41
+ const rl = createInterface({ input, output });
42
+ try {
43
+ console.log('How do you want to log in?');
44
+ console.log('1. Open browser and log in');
45
+ console.log('2. Paste API key manually');
46
+ const answer = (await rl.question('Choose [1]: ')).trim();
47
+ return answer === '2';
48
+ }
49
+ finally {
50
+ rl.close();
51
+ }
52
+ }
53
+ async function promptForApiKey() {
54
+ const rl = createInterface({ input, output });
55
+ try {
56
+ return (await rl.question('Paste your Pagr API key: ')).trim();
57
+ }
58
+ finally {
59
+ rl.close();
60
+ }
61
+ }
62
+ async function browserLogin() {
63
+ const state = randomBytes(32).toString('base64url');
64
+ const callback = await createCallbackServer(state);
65
+ const appUrl = buildCliLoginUrl(callback.url, state);
66
+ console.log(`Opening ${new URL('/cli', appUrl).toString()} ...`);
67
+ console.log('Waiting for browser login. Press Ctrl+C to cancel.');
68
+ console.log('If the browser did not open, visit:');
69
+ console.log(appUrl);
70
+ openBrowser(appUrl);
71
+ try {
72
+ return await callback.key;
73
+ }
74
+ finally {
75
+ await callback.close();
76
+ }
77
+ }
78
+ export function buildCliLoginUrl(callbackUrl, state) {
79
+ const base = new URL(process.env.PAGR_APP_URL ?? DEFAULT_APP_URL);
80
+ const url = new URL('/cli', base);
81
+ url.searchParams.set('callback', callbackUrl);
82
+ url.searchParams.set('state', state);
83
+ return url.toString();
84
+ }
85
+ export function validateCallbackPayload(body, expectedState) {
86
+ const state = body.get('state');
87
+ const apiKey = body.get('key');
88
+ if (state !== expectedState) {
89
+ throw new Error('Login failed: state did not match the CLI session.');
90
+ }
91
+ if (!apiKey?.startsWith('pagr_')) {
92
+ throw new Error('Login failed: Pagr did not return a valid API key.');
93
+ }
94
+ return apiKey;
95
+ }
96
+ async function createCallbackServer(expectedState) {
97
+ let timeout;
98
+ let settled = false;
99
+ let resolveKey;
100
+ let rejectKey;
101
+ const key = new Promise((resolve, reject) => {
102
+ resolveKey = resolve;
103
+ rejectKey = reject;
104
+ });
105
+ const server = createServer(async (req, res) => {
106
+ if (settled) {
107
+ writeHtml(res, 409, 'Login already completed', 'Return to your terminal.');
108
+ return;
109
+ }
110
+ if (req.method !== 'POST' || req.url !== '/callback') {
111
+ writeHtml(res, 404, 'Not found', 'Return to your terminal and run pagr login again.');
112
+ return;
113
+ }
114
+ try {
115
+ const body = await readFormBody(req);
116
+ let apiKey;
117
+ try {
118
+ apiKey = validateCallbackPayload(body, expectedState);
119
+ }
120
+ catch (error) {
121
+ const message = error instanceof Error ? error.message : String(error);
122
+ settled = true;
123
+ rejectKey(error instanceof Error ? error : new Error(message));
124
+ if (message.includes('state did not match')) {
125
+ writeHtml(res, 400, 'Login failed', 'The login request did not match the CLI session. Return to your terminal and run pagr login again.');
126
+ }
127
+ else {
128
+ writeHtml(res, 400, 'Login failed', 'Pagr did not return a valid CLI key. Return to your terminal and try again.');
129
+ }
130
+ return;
131
+ }
132
+ settled = true;
133
+ resolveKey(apiKey);
134
+ writeHtml(res, 200, 'You are logged in to Pagr CLI.', 'You can close this window and return to your terminal.');
135
+ }
136
+ catch (error) {
137
+ settled = true;
138
+ rejectKey(error instanceof Error ? error : new Error(String(error)));
139
+ writeHtml(res, 400, 'Login failed', 'The CLI could not read the browser login response.');
140
+ }
141
+ });
142
+ await new Promise((resolve, reject) => {
143
+ server.once('error', reject);
144
+ server.listen(0, '127.0.0.1', () => {
145
+ server.off('error', reject);
146
+ resolve();
147
+ });
148
+ });
149
+ timeout = setTimeout(() => {
150
+ if (!settled) {
151
+ settled = true;
152
+ rejectKey(new Error('Login timed out. Run `pagr login` again or use `pagr login --manual`.'));
153
+ }
154
+ }, LOGIN_TIMEOUT_MS);
155
+ const address = server.address();
156
+ if (!address || typeof address === 'string') {
157
+ throw new Error('Could not start local login callback server.');
158
+ }
159
+ return {
160
+ url: `http://127.0.0.1:${address.port}/callback`,
161
+ key,
162
+ close: () => new Promise((resolve) => {
163
+ if (timeout)
164
+ clearTimeout(timeout);
165
+ server.close(() => resolve());
166
+ }),
167
+ };
168
+ }
169
+ function readFormBody(req) {
170
+ return new Promise((resolve, reject) => {
171
+ const chunks = [];
172
+ req.on('data', (chunk) => chunks.push(chunk));
173
+ req.on('error', reject);
174
+ req.on('end', () => {
175
+ resolve(new URLSearchParams(Buffer.concat(chunks).toString('utf-8')));
176
+ });
177
+ });
178
+ }
179
+ function writeHtml(res, status, title, message) {
180
+ res.writeHead(status, { 'Content-Type': 'text/html; charset=utf-8' });
181
+ res.end(`<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>${escapeHtml(title)}</title><style>body{font-family:system-ui,sans-serif;margin:0;display:grid;min-height:100vh;place-items:center;background:#f5f8fb;color:#17212b}.card{max-width:520px;margin:24px;padding:28px;border:1px solid #d9e2ea;border-radius:12px;background:white}h1{margin:0 0 10px;font-size:28px;line-height:1.2}p{margin:0;color:#586474;line-height:1.6}</style></head><body><main class="card"><h1>${escapeHtml(title)}</h1><p>${escapeHtml(message)}</p></main></body></html>`);
182
+ }
183
+ function saveApiKey(key) {
184
+ if (!key.startsWith('pagr_')) {
185
+ console.error('Invalid API key format. Keys must start with "pagr_".');
186
+ process.exit(1);
187
+ }
188
+ writeConfig({ ...readConfig(), apiKey: key });
189
+ console.log('Logged in. API key saved to ~/.pagr/config.json');
190
+ }
191
+ function escapeHtml(value) {
192
+ return value.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;');
193
+ }
194
+ function openBrowser(url) {
195
+ const currentPlatform = platform();
196
+ const command = currentPlatform === 'darwin' ? 'open' : currentPlatform === 'win32' ? 'cmd' : 'xdg-open';
197
+ const args = currentPlatform === 'win32' ? ['/c', 'start', '', url] : [url];
198
+ const child = spawn(command, args, { detached: true, stdio: 'ignore' });
199
+ child.unref();
200
+ }
201
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=login.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.test.d.ts","sourceRoot":"","sources":["../../src/commands/login.test.ts"],"names":[],"mappings":""}