@soku-ai/cli 0.1.0-alpha.6 → 0.1.0-alpha.7

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.
@@ -11,7 +11,7 @@ export function registerAuthCommands(program) {
11
11
  .command('login')
12
12
  .description('Sign in via device authorization')
13
13
  .option('--api-base <url>', 'Override the API base URL')
14
- .option('--resource <bundles>', 'Resource bundles to request (comma-separated): data-infra, conversion-groups-write', 'data-infra')
14
+ .option('--resource <bundles>', 'Resource bundles to request (comma-separated): data-infra, conversion-groups-write, seo-hosting', 'data-infra')
15
15
  .option('--no-wait', 'Print the verification URL and exit without polling (for agents)')
16
16
  .option('--device-code <code>', 'Resume polling for a previously started login')
17
17
  .option('--qr', 'Render the verification URL as a QR code')
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
@@ -22,7 +22,7 @@ export interface ManifestAction {
22
22
  action: string;
23
23
  description: string;
24
24
  long_description: string | null;
25
- capability_mode: string;
25
+ mode: string;
26
26
  priority: string;
27
27
  requires_review: boolean;
28
28
  freshness_kind: string;
@@ -1 +1 @@
1
- {"version":3,"file":"generated.d.ts","sourceRoot":"","sources":["../../src/commands/generated.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAMnC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,eAAe,EAAE,MAAM,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,EAAE,OAAO,CAAA;IACxB,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,aAAa,EAAE,CAAA;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,cAAc,EAAE,CAAA;CAC1B;AAmDD,sEAAsE;AACtE,wBAAgB,YAAY,IAAI,kBAAkB,CAGjD;AAED,4EAA4E;AAC5E,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAkD3F;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAEhE"}
1
+ {"version":3,"file":"generated.d.ts","sourceRoot":"","sources":["../../src/commands/generated.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAMnC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,EAAE,OAAO,CAAA;IACxB,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,aAAa,EAAE,CAAA;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,cAAc,EAAE,CAAA;CAC1B;AAmDD,sEAAsE;AACtE,wBAAgB,YAAY,IAAI,kBAAkB,CAGjD;AAED,4EAA4E;AAC5E,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAkD3F;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAEhE"}
@@ -0,0 +1,100 @@
1
+ /** `soku seo-hosting` — manage SEO Hosting posts and domain connections. */
2
+ import { Command } from 'commander';
3
+ export interface DomainConnection {
4
+ id: string;
5
+ brand_id: string;
6
+ hostname: string;
7
+ method: string;
8
+ expected_cname_target?: string | null;
9
+ origin_hostname?: string | null;
10
+ status: string;
11
+ ssl_status: string;
12
+ mounted_sections?: string[] | null;
13
+ last_verified_at?: string | null;
14
+ last_checked_at?: string | null;
15
+ last_error?: string | null;
16
+ created_at?: string | null;
17
+ cf_verification_data?: Record<string, unknown> | null;
18
+ }
19
+ interface HostingStatusResponse {
20
+ configured: boolean;
21
+ live: boolean;
22
+ connections: Array<Pick<DomainConnection, 'method' | 'hostname' | 'status' | 'ssl_status' | 'mounted_sections' | 'last_error'>>;
23
+ public_base_urls: string[];
24
+ }
25
+ interface SeoHostingPost {
26
+ id: string;
27
+ brand_id: string;
28
+ section: string;
29
+ slug: string;
30
+ title?: string;
31
+ excerpt?: string | null;
32
+ status: string;
33
+ seo?: Record<string, unknown>;
34
+ cover_image_url?: string | null;
35
+ author_name?: string | null;
36
+ url_path?: string;
37
+ body_markdown?: string;
38
+ published_at?: string | null;
39
+ created_at?: string | null;
40
+ updated_at?: string | null;
41
+ }
42
+ export interface WorkerProbeResponse {
43
+ is_cloudflare: boolean;
44
+ conflicts: string[];
45
+ serves_next_assets: boolean;
46
+ is_vercel: boolean;
47
+ }
48
+ interface WorkerRiskOptions {
49
+ acceptConflicts?: boolean;
50
+ acceptNextAssetsWarning?: boolean;
51
+ }
52
+ interface CloudflareTokenOptions {
53
+ cfTokenEnv?: string;
54
+ cfTokenStdin?: boolean;
55
+ }
56
+ interface PostBodyOptions {
57
+ body?: string;
58
+ bodyFile?: string;
59
+ bodyStdin?: boolean;
60
+ }
61
+ interface PostCreateOptions extends PostBodyOptions {
62
+ title: string;
63
+ slug?: string;
64
+ section?: string;
65
+ excerpt?: string;
66
+ coverImageUrl?: string;
67
+ authorName?: string;
68
+ seo?: string;
69
+ }
70
+ interface PostUpdateOptions extends PostBodyOptions {
71
+ title?: string;
72
+ excerpt?: string;
73
+ coverImageUrl?: string;
74
+ authorName?: string;
75
+ seo?: string;
76
+ }
77
+ export declare class SeoHostingUsageError extends Error {
78
+ readonly hint?: string | undefined;
79
+ constructor(message: string, hint?: string | undefined);
80
+ }
81
+ export declare function domainConnectionPath(connectionId?: string, suffix?: string): string;
82
+ export declare function seoHostingCallPath(action: string): string;
83
+ export declare function parseSections(raw?: string): string[];
84
+ export declare function validateCloudflareTokenOptions(opts: CloudflareTokenOptions): void;
85
+ export declare function readCloudflareToken(opts: CloudflareTokenOptions): Promise<string>;
86
+ export declare function workerProbeBlocker(probe: WorkerProbeResponse, opts: WorkerRiskOptions): SeoHostingUsageError | null;
87
+ export declare function callSeoHostingAction<T>(action: string, payload?: Record<string, unknown>): Promise<T>;
88
+ export declare function parseSeoOverride(raw?: string): Record<string, unknown> | undefined;
89
+ export declare function readPostBody(opts: PostBodyOptions, required: boolean): Promise<string | undefined>;
90
+ export declare function buildPostCreatePayload(opts: PostCreateOptions): Promise<Record<string, unknown>>;
91
+ export declare function buildPostUpdatePayload(postId: string, opts: PostUpdateOptions): Promise<Record<string, unknown>>;
92
+ export declare function renderHostingStatus(status: HostingStatusResponse): string;
93
+ export declare function renderPosts(items: SeoHostingPost[]): string;
94
+ export declare function renderPost(post: SeoHostingPost): string;
95
+ export declare function renderConnections(items: DomainConnection[]): string;
96
+ export declare function renderConnection(connection: DomainConnection): string;
97
+ export declare function renderWorkerProbe(probe: WorkerProbeResponse): string;
98
+ export declare function registerSeoHostingCommands(program: Command): void;
99
+ export {};
100
+ //# sourceMappingURL=seo-hosting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-hosting.d.ts","sourceRoot":"","sources":["../../src/commands/seo-hosting.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,489 @@
1
+ /** `soku seo-hosting` — manage SEO Hosting posts and domain connections. */
2
+ import { readFileSync } from 'node:fs';
3
+ import { apiRequest } from '../http/client.js';
4
+ import { bold, cyan, dim, emitError, emitSuccess, ExitCode, table } from '../output/envelope.js';
5
+ import { unwrapDispatch } from '../output/unwrap.js';
6
+ const CONNECTIONS_PATH = '/api/cli/seo-hosting/domain-connections';
7
+ const SEO_HOSTING_CALL_PATH = '/api/cli/call/seo_hosting';
8
+ const DEFAULT_SECTIONS = ['blog'];
9
+ const ALLOWED_SECTIONS = new Set(['blog', 'use-cases', 'alternatives']);
10
+ export class SeoHostingUsageError extends Error {
11
+ hint;
12
+ constructor(message, hint) {
13
+ super(message);
14
+ this.hint = hint;
15
+ }
16
+ }
17
+ export function domainConnectionPath(connectionId, suffix) {
18
+ if (!connectionId)
19
+ return CONNECTIONS_PATH;
20
+ const encoded = encodeURIComponent(connectionId);
21
+ return `${CONNECTIONS_PATH}/${encoded}${suffix ? `/${suffix}` : ''}`;
22
+ }
23
+ export function seoHostingCallPath(action) {
24
+ return `${SEO_HOSTING_CALL_PATH}/${encodeURIComponent(action)}`;
25
+ }
26
+ export function parseSections(raw) {
27
+ if (!raw || !raw.trim())
28
+ return [...DEFAULT_SECTIONS];
29
+ const sections = raw
30
+ .split(',')
31
+ .map((part) => part.trim())
32
+ .filter(Boolean);
33
+ const unknown = sections.filter((section) => !ALLOWED_SECTIONS.has(section));
34
+ if (unknown.length > 0) {
35
+ throw new SeoHostingUsageError(`Unsupported section: ${unknown.join(', ')}`, 'Allowed sections: blog, use-cases, alternatives.');
36
+ }
37
+ return [...new Set(sections)];
38
+ }
39
+ export function validateCloudflareTokenOptions(opts) {
40
+ const sources = [opts.cfTokenEnv, opts.cfTokenStdin].filter(Boolean);
41
+ if (sources.length !== 1) {
42
+ throw new SeoHostingUsageError('Provide exactly one Cloudflare token source.', 'Use --cf-token-env NAME or --cf-token-stdin.');
43
+ }
44
+ }
45
+ async function readAll(input) {
46
+ let out = '';
47
+ for await (const chunk of input)
48
+ out += chunk.toString();
49
+ return out;
50
+ }
51
+ export async function readCloudflareToken(opts) {
52
+ validateCloudflareTokenOptions(opts);
53
+ if (opts.cfTokenEnv) {
54
+ const token = process.env[opts.cfTokenEnv]?.trim();
55
+ if (!token) {
56
+ throw new SeoHostingUsageError(`Environment variable ${opts.cfTokenEnv} is empty or unset.`, `Export ${opts.cfTokenEnv} before running connect-worker.`);
57
+ }
58
+ return token;
59
+ }
60
+ const token = (await readAll(process.stdin)).trim();
61
+ if (!token) {
62
+ throw new SeoHostingUsageError('No Cloudflare token was received on stdin.', 'Pipe the token into the command, for example: printf %s "$CF_TOKEN" | soku seo-hosting connections connect-worker --cf-token-stdin ...');
63
+ }
64
+ return token;
65
+ }
66
+ export function workerProbeBlocker(probe, opts) {
67
+ if (!probe.is_cloudflare) {
68
+ const hint = probe.is_vercel
69
+ ? 'This hostname appears to be on Vercel. Use the Web OAuth flow until Vercel CLI support lands.'
70
+ : 'Cloudflare Worker routes require the hostname zone to be on Cloudflare.';
71
+ return new SeoHostingUsageError('Hostname is not using Cloudflare nameservers.', hint);
72
+ }
73
+ if (probe.conflicts.length > 0 && !opts.acceptConflicts) {
74
+ return new SeoHostingUsageError(`Mount paths already serve content: ${probe.conflicts.join(', ')}.`, 'Pass --accept-conflicts after confirming the SEO Hosting Worker may shadow those paths.');
75
+ }
76
+ if (probe.serves_next_assets && !opts.acceptNextAssetsWarning) {
77
+ return new SeoHostingUsageError('The hostname appears to serve its own Next.js assets.', 'Pass --accept-next-assets-warning after confirming /_next/static/* can be routed through the Worker.');
78
+ }
79
+ return null;
80
+ }
81
+ export async function callSeoHostingAction(action, payload = {}) {
82
+ const result = await apiRequest(seoHostingCallPath(action), {
83
+ method: 'POST',
84
+ workspace: true,
85
+ body: payload,
86
+ });
87
+ return unwrapDispatch(result);
88
+ }
89
+ export function parseSeoOverride(raw) {
90
+ if (!raw)
91
+ return undefined;
92
+ let parsed;
93
+ try {
94
+ parsed = JSON.parse(raw);
95
+ }
96
+ catch {
97
+ throw new SeoHostingUsageError('--seo must be valid JSON.');
98
+ }
99
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
100
+ throw new SeoHostingUsageError('--seo must be a JSON object.');
101
+ }
102
+ return parsed;
103
+ }
104
+ export async function readPostBody(opts, required) {
105
+ const sources = [opts.body !== undefined, opts.bodyFile, opts.bodyStdin].filter(Boolean);
106
+ if (sources.length > 1) {
107
+ throw new SeoHostingUsageError('Provide only one post body source.', 'Use --body, --body-file, or --body-stdin.');
108
+ }
109
+ if (sources.length === 0) {
110
+ if (required) {
111
+ throw new SeoHostingUsageError('Post body is required.', 'Use --body, --body-file, or --body-stdin.');
112
+ }
113
+ return undefined;
114
+ }
115
+ let body;
116
+ if (opts.bodyFile) {
117
+ try {
118
+ body = readFileSync(opts.bodyFile, 'utf8');
119
+ }
120
+ catch (err) {
121
+ throw new SeoHostingUsageError(`Could not read body file: ${opts.bodyFile}`, err.message);
122
+ }
123
+ }
124
+ else if (opts.bodyStdin) {
125
+ body = await readAll(process.stdin);
126
+ }
127
+ else {
128
+ body = opts.body ?? '';
129
+ }
130
+ if (!body.trim()) {
131
+ throw new SeoHostingUsageError('Post body cannot be empty.');
132
+ }
133
+ return body;
134
+ }
135
+ export async function buildPostCreatePayload(opts) {
136
+ const body = await readPostBody(opts, true);
137
+ const payload = {
138
+ title: opts.title,
139
+ body_markdown: body,
140
+ };
141
+ addString(payload, 'slug', opts.slug);
142
+ addString(payload, 'section', opts.section);
143
+ addString(payload, 'excerpt', opts.excerpt);
144
+ addString(payload, 'cover_image_url', opts.coverImageUrl);
145
+ addString(payload, 'author_name', opts.authorName);
146
+ const seo = parseSeoOverride(opts.seo);
147
+ if (seo)
148
+ payload.seo = seo;
149
+ return payload;
150
+ }
151
+ export async function buildPostUpdatePayload(postId, opts) {
152
+ const payload = { post_id: postId };
153
+ addString(payload, 'title', opts.title);
154
+ addString(payload, 'excerpt', opts.excerpt);
155
+ addString(payload, 'cover_image_url', opts.coverImageUrl);
156
+ addString(payload, 'author_name', opts.authorName);
157
+ const body = await readPostBody(opts, false);
158
+ if (body !== undefined)
159
+ payload.body_markdown = body;
160
+ const seo = parseSeoOverride(opts.seo);
161
+ if (seo)
162
+ payload.seo = seo;
163
+ if (Object.keys(payload).length === 1) {
164
+ throw new SeoHostingUsageError('No post fields were provided.', 'Pass --title, a body option, --excerpt, --cover-image-url, --author-name, or --seo.');
165
+ }
166
+ return payload;
167
+ }
168
+ function addString(payload, key, value) {
169
+ if (value !== undefined && value.trim())
170
+ payload[key] = value;
171
+ }
172
+ export function renderHostingStatus(status) {
173
+ const rows = [
174
+ `${bold('Configured')}: ${status.configured ? 'yes' : 'no'}`,
175
+ `${bold('Live')}: ${status.live ? 'yes' : 'no'}`,
176
+ `${bold('Public URLs')}: ${status.public_base_urls.length ? status.public_base_urls.join(', ') : dim('(none)')}`,
177
+ ];
178
+ if (status.connections.length > 0) {
179
+ rows.push('', bold('Connections'), renderConnectionSummaries(status.connections));
180
+ }
181
+ return rows.join('\n');
182
+ }
183
+ function renderConnectionSummaries(items) {
184
+ return table(items.map((item) => ({
185
+ hostname: item.hostname,
186
+ method: item.method,
187
+ status: item.status,
188
+ ssl: item.ssl_status,
189
+ sections: item.mounted_sections?.join(',') || '',
190
+ error: item.last_error || '',
191
+ })), [
192
+ { key: 'hostname', header: 'HOSTNAME' },
193
+ { key: 'method', header: 'METHOD' },
194
+ { key: 'status', header: 'STATUS' },
195
+ { key: 'ssl', header: 'SSL' },
196
+ { key: 'sections', header: 'SECTIONS' },
197
+ { key: 'error', header: 'ERROR' },
198
+ ]);
199
+ }
200
+ export function renderPosts(items) {
201
+ return table(items.map((item) => ({
202
+ id: item.id,
203
+ section: item.section,
204
+ slug: item.slug,
205
+ status: item.status,
206
+ title: item.title || '',
207
+ })), [
208
+ { key: 'id', header: 'ID' },
209
+ { key: 'section', header: 'SECTION' },
210
+ { key: 'slug', header: 'SLUG' },
211
+ { key: 'status', header: 'STATUS' },
212
+ { key: 'title', header: 'TITLE' },
213
+ ]);
214
+ }
215
+ export function renderPost(post) {
216
+ const rows = [
217
+ `${bold('ID')}: ${cyan(post.id)}`,
218
+ `${bold('Section')}: ${post.section}`,
219
+ `${bold('Slug')}: ${post.slug}`,
220
+ `${bold('Status')}: ${post.status}`,
221
+ ];
222
+ if (post.title)
223
+ rows.splice(1, 0, `${bold('Title')}: ${post.title}`);
224
+ if (post.url_path)
225
+ rows.push(`${bold('URL path')}: ${post.url_path}`);
226
+ if (post.excerpt)
227
+ rows.push(`${bold('Excerpt')}: ${post.excerpt}`);
228
+ if (post.author_name)
229
+ rows.push(`${bold('Author')}: ${post.author_name}`);
230
+ if (post.published_at)
231
+ rows.push(`${bold('Published')}: ${post.published_at}`);
232
+ if (post.body_markdown !== undefined) {
233
+ rows.push('', post.body_markdown.trim() || dim('(empty body)'));
234
+ }
235
+ return rows.join('\n');
236
+ }
237
+ export function renderConnections(items) {
238
+ return table(items.map((item) => ({
239
+ id: item.id,
240
+ hostname: item.hostname,
241
+ method: item.method,
242
+ status: item.status,
243
+ ssl: item.ssl_status,
244
+ sections: item.mounted_sections?.join(',') || '',
245
+ })), [
246
+ { key: 'id', header: 'ID' },
247
+ { key: 'hostname', header: 'HOSTNAME' },
248
+ { key: 'method', header: 'METHOD' },
249
+ { key: 'status', header: 'STATUS' },
250
+ { key: 'ssl', header: 'SSL' },
251
+ { key: 'sections', header: 'SECTIONS' },
252
+ ]);
253
+ }
254
+ export function renderConnection(connection) {
255
+ const rows = [
256
+ `${bold('ID')}: ${cyan(connection.id)}`,
257
+ `${bold('Hostname')}: ${connection.hostname}`,
258
+ `${bold('Method')}: ${connection.method}`,
259
+ `${bold('Status')}: ${connection.status}`,
260
+ `${bold('SSL')}: ${connection.ssl_status}`,
261
+ ];
262
+ if (connection.expected_cname_target) {
263
+ rows.push(`${bold('Expected CNAME')}: ${connection.expected_cname_target}`);
264
+ }
265
+ if (connection.mounted_sections?.length) {
266
+ rows.push(`${bold('Sections')}: ${connection.mounted_sections.join(', ')}`);
267
+ }
268
+ if (connection.last_error) {
269
+ rows.push(`${bold('Last error')}: ${connection.last_error}`);
270
+ }
271
+ return rows.join('\n');
272
+ }
273
+ export function renderWorkerProbe(probe) {
274
+ return [
275
+ `${bold('Cloudflare')}: ${probe.is_cloudflare ? 'yes' : 'no'}`,
276
+ `${bold('Vercel')}: ${probe.is_vercel ? 'yes' : 'no'}`,
277
+ `${bold('Conflicts')}: ${probe.conflicts.length ? probe.conflicts.join(', ') : dim('(none)')}`,
278
+ `${bold('Next.js assets')}: ${probe.serves_next_assets ? 'yes' : 'no'}`,
279
+ ].join('\n');
280
+ }
281
+ function usageError(error) {
282
+ if (error instanceof SeoHostingUsageError) {
283
+ emitError('usage', error.message, ExitCode.USAGE, error.hint);
284
+ }
285
+ throw error;
286
+ }
287
+ export function registerSeoHostingCommands(program) {
288
+ const seoHosting = program.command('seo-hosting').description('Manage SEO Hosting');
289
+ seoHosting
290
+ .command('status')
291
+ .description('Check whether the active brand has live SEO Hosting')
292
+ .action(async () => {
293
+ const data = await callSeoHostingAction('get_hosting_status');
294
+ emitSuccess(data, renderHostingStatus);
295
+ });
296
+ const posts = seoHosting.command('posts').description('Manage SEO Hosting posts');
297
+ posts
298
+ .command('list')
299
+ .description('List SEO Hosting posts for the active brand')
300
+ .option('--section <section>', 'Filter by section: blog, use-cases, alternatives')
301
+ .option('--status <status>', 'Filter by status: draft, published, archived')
302
+ .action(async (opts) => {
303
+ const payload = {};
304
+ addString(payload, 'section', opts.section);
305
+ addString(payload, 'status', opts.status);
306
+ const data = await callSeoHostingAction('list_posts', payload);
307
+ emitSuccess(data, (d) => renderPosts(d.items));
308
+ });
309
+ posts
310
+ .command('get <postId>')
311
+ .description('Read one SEO Hosting post including its Markdown body')
312
+ .action(async (postId) => {
313
+ const data = await callSeoHostingAction('get_post', { post_id: postId });
314
+ emitSuccess(data, renderPost);
315
+ });
316
+ posts
317
+ .command('create')
318
+ .description('Create a draft SEO Hosting post')
319
+ .requiredOption('--title <title>', 'Post title')
320
+ .option('--body <markdown>', 'Post body as Markdown')
321
+ .option('--body-file <path>', 'Read Markdown body from a file')
322
+ .option('--body-stdin', 'Read Markdown body from stdin')
323
+ .option('--slug <slug>', 'Optional URL slug; derived from title when omitted')
324
+ .option('--section <section>', 'Content section: blog, use-cases, alternatives')
325
+ .option('--excerpt <text>', 'Short excerpt')
326
+ .option('--cover-image-url <url>', 'Cover image URL')
327
+ .option('--author-name <name>', 'Display author name')
328
+ .option('--seo <json>', 'SEO overrides JSON object')
329
+ .action(async (opts) => {
330
+ let payload;
331
+ try {
332
+ payload = await buildPostCreatePayload(opts);
333
+ }
334
+ catch (err) {
335
+ usageError(err);
336
+ }
337
+ const data = await callSeoHostingAction('create_post', payload);
338
+ emitSuccess(data, renderPost);
339
+ });
340
+ posts
341
+ .command('update <postId>')
342
+ .description('Update a SEO Hosting post')
343
+ .option('--title <title>', 'New title')
344
+ .option('--body <markdown>', 'New body as Markdown')
345
+ .option('--body-file <path>', 'Read new Markdown body from a file')
346
+ .option('--body-stdin', 'Read new Markdown body from stdin')
347
+ .option('--excerpt <text>', 'New excerpt')
348
+ .option('--cover-image-url <url>', 'New cover image URL')
349
+ .option('--author-name <name>', 'New display author name')
350
+ .option('--seo <json>', 'SEO overrides JSON object')
351
+ .action(async (postId, opts) => {
352
+ let payload;
353
+ try {
354
+ payload = await buildPostUpdatePayload(postId, opts);
355
+ }
356
+ catch (err) {
357
+ usageError(err);
358
+ }
359
+ const data = await callSeoHostingAction('update_post', payload);
360
+ emitSuccess(data, renderPost);
361
+ });
362
+ posts
363
+ .command('publish <postId>')
364
+ .description('Publish a SEO Hosting post')
365
+ .action(async (postId) => {
366
+ const data = await callSeoHostingAction('publish_post', { post_id: postId });
367
+ emitSuccess(data, renderPost);
368
+ });
369
+ posts
370
+ .command('delete <postId>')
371
+ .description('Soft-delete a SEO Hosting post')
372
+ .option('--confirm', 'Confirm the delete')
373
+ .action(async (postId, opts) => {
374
+ if (!opts.confirm) {
375
+ emitError('confirmation_required', 'Delete requires explicit confirmation.', ExitCode.USAGE, 'Re-run with --confirm.');
376
+ }
377
+ const data = await callSeoHostingAction('delete_post', { post_id: postId });
378
+ emitSuccess(data, renderPost);
379
+ });
380
+ const connections = seoHosting
381
+ .command('connections')
382
+ .description('Manage SEO Hosting domain connections');
383
+ connections
384
+ .command('list')
385
+ .description('List domain connections for the active brand')
386
+ .action(async () => {
387
+ const data = await apiRequest(CONNECTIONS_PATH, {
388
+ workspace: true,
389
+ });
390
+ emitSuccess(data, (d) => renderConnections(d.items));
391
+ });
392
+ connections
393
+ .command('probe')
394
+ .description('Probe a hostname before Cloudflare Worker provisioning')
395
+ .requiredOption('--hostname <hostname>', 'Customer hostname, for example example.com')
396
+ .option('--sections <sections>', 'Comma-separated sections to mount', DEFAULT_SECTIONS.join(','))
397
+ .action(async (opts) => {
398
+ let sections;
399
+ try {
400
+ sections = parseSections(opts.sections);
401
+ }
402
+ catch (err) {
403
+ usageError(err);
404
+ }
405
+ const data = await apiRequest(`${CONNECTIONS_PATH}/worker/probe`, {
406
+ method: 'POST',
407
+ workspace: true,
408
+ body: { hostname: opts.hostname, sections },
409
+ });
410
+ emitSuccess(data, renderWorkerProbe);
411
+ });
412
+ connections
413
+ .command('connect-cname')
414
+ .description('Connect a CNAME SEO Hosting hostname')
415
+ .requiredOption('--hostname <hostname>', 'Customer hostname, for example blog.example.com')
416
+ .action(async (opts) => {
417
+ const data = await apiRequest(CONNECTIONS_PATH, {
418
+ method: 'POST',
419
+ workspace: true,
420
+ body: { hostname: opts.hostname },
421
+ });
422
+ emitSuccess(data, renderConnection);
423
+ });
424
+ connections
425
+ .command('connect-worker')
426
+ .description('Connect a Cloudflare Worker reverse proxy')
427
+ .requiredOption('--hostname <hostname>', 'Customer hostname, for example example.com')
428
+ .option('--sections <sections>', 'Comma-separated sections to mount', DEFAULT_SECTIONS.join(','))
429
+ .option('--cf-token-env <name>', 'Read the Cloudflare API token from this environment variable')
430
+ .option('--cf-token-stdin', 'Read the Cloudflare API token from stdin')
431
+ .option('--accept-conflicts', 'Allow SEO Hosting routes to shadow existing mounted paths')
432
+ .option('--accept-next-assets-warning', 'Allow /_next/static/* to route through the Worker')
433
+ .action(async (opts) => {
434
+ let sections;
435
+ try {
436
+ sections = parseSections(opts.sections);
437
+ validateCloudflareTokenOptions(opts);
438
+ }
439
+ catch (err) {
440
+ usageError(err);
441
+ }
442
+ const probe = await apiRequest(`${CONNECTIONS_PATH}/worker/probe`, {
443
+ method: 'POST',
444
+ workspace: true,
445
+ body: { hostname: opts.hostname, sections },
446
+ });
447
+ const blocker = workerProbeBlocker(probe, opts);
448
+ if (blocker)
449
+ usageError(blocker);
450
+ let token;
451
+ try {
452
+ token = await readCloudflareToken(opts);
453
+ }
454
+ catch (err) {
455
+ usageError(err);
456
+ }
457
+ const connection = await apiRequest(`${CONNECTIONS_PATH}/worker`, {
458
+ method: 'POST',
459
+ workspace: true,
460
+ body: { hostname: opts.hostname, sections, api_token: token },
461
+ });
462
+ emitSuccess({ connection, probe }, (d) => [renderConnection(d.connection), '', bold('Probe'), renderWorkerProbe(d.probe)].join('\n'));
463
+ });
464
+ connections
465
+ .command('verify <connectionId>')
466
+ .description('Run one verification pass')
467
+ .action(async (connectionId) => {
468
+ const data = await apiRequest(domainConnectionPath(connectionId, 'verify'), {
469
+ method: 'POST',
470
+ workspace: true,
471
+ });
472
+ emitSuccess(data, renderConnection);
473
+ });
474
+ connections
475
+ .command('disconnect <connectionId>')
476
+ .description('Disconnect a domain connection')
477
+ .option('--confirm', 'Confirm the disconnect')
478
+ .action(async (connectionId, opts) => {
479
+ if (!opts.confirm) {
480
+ emitError('confirmation_required', 'Disconnect requires explicit confirmation.', ExitCode.USAGE, 'Re-run with --confirm.');
481
+ }
482
+ const data = await apiRequest(domainConnectionPath(connectionId), {
483
+ method: 'DELETE',
484
+ workspace: true,
485
+ });
486
+ emitSuccess(data, renderConnection);
487
+ });
488
+ }
489
+ //# sourceMappingURL=seo-hosting.js.map