doomain 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/schema.js +2 -2
- package/dist/lib/command-schema.d.ts +9 -0
- package/dist/lib/command-schema.js +35 -2
- package/dist/lib/link-domain.js +22 -3
- package/oclif.manifest.json +36 -36
- package/package.json +1 -1
package/dist/commands/schema.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Args, Command } from '@oclif/core';
|
|
2
|
-
import {
|
|
2
|
+
import { getCommandSchemaForAgents } from '../lib/command-schema.js';
|
|
3
3
|
import { jsonFlag } from '../lib/flags.js';
|
|
4
4
|
import { createOutput, outputError } from '../lib/output.js';
|
|
5
5
|
export default class Schema extends Command {
|
|
@@ -14,7 +14,7 @@ export default class Schema extends Command {
|
|
|
14
14
|
const { args, flags } = await this.parse(Schema);
|
|
15
15
|
const out = createOutput({ json: flags.json });
|
|
16
16
|
try {
|
|
17
|
-
const schema =
|
|
17
|
+
const schema = await getCommandSchemaForAgents(args.command);
|
|
18
18
|
if (!schema)
|
|
19
19
|
throw new Error(`Unknown command schema: ${args.command}`);
|
|
20
20
|
if (!out.json)
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
import { type ProviderStatus } from './providers/status.js';
|
|
2
|
+
export type ProviderConnectionStatus = Pick<ProviderStatus, 'configured' | 'default' | 'displayName' | 'docsUrl' | 'id'>;
|
|
1
3
|
export interface CommandSchema {
|
|
2
4
|
name: string;
|
|
3
5
|
description: string;
|
|
4
6
|
examples: string[];
|
|
5
7
|
agentHint?: string;
|
|
8
|
+
agentInstructions?: string[];
|
|
9
|
+
agentQuickstart?: {
|
|
10
|
+
doNotPreflight: boolean;
|
|
11
|
+
preferredFirstCommand: string;
|
|
12
|
+
};
|
|
13
|
+
configuredProviders?: ProviderConnectionStatus[];
|
|
6
14
|
mutates?: boolean;
|
|
7
15
|
safeForAgents?: boolean;
|
|
8
16
|
flags: Array<{
|
|
@@ -15,3 +23,4 @@ export interface CommandSchema {
|
|
|
15
23
|
}
|
|
16
24
|
export declare const commandSchemas: CommandSchema[];
|
|
17
25
|
export declare function getCommandSchema(name?: string): CommandSchema[] | CommandSchema | undefined;
|
|
26
|
+
export declare function getCommandSchemaForAgents(name?: string): Promise<CommandSchema[] | CommandSchema | undefined>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { listProviderStatuses } from './providers/status.js';
|
|
1
2
|
export const commandSchemas = [
|
|
2
3
|
{
|
|
3
4
|
name: 'link',
|
|
@@ -9,7 +10,16 @@ export const commandSchemas = [
|
|
|
9
10
|
'doomain link --domain example.com --subdomain app --project my-app --json',
|
|
10
11
|
'doomain link --provider spaceship --domain example.com --apex --project my-app --dry-run --json',
|
|
11
12
|
],
|
|
12
|
-
agentHint: 'For agent use,
|
|
13
|
+
agentHint: 'For agent use, try `doomain link <domain> --json` first. Do not inspect project files, run provider status, or use --dry-run unless the user explicitly asks for a preview. The command infers project/provider and returns structured recovery errors when inference fails.',
|
|
14
|
+
agentInstructions: [
|
|
15
|
+
'When the user asks to add or link a domain, run `doomain link <domain> --json` first.',
|
|
16
|
+
'Do not run `providers status`, `projects list`, `--help`, or `--dry-run` before the first link attempt unless the user asks for a preview or diagnosis.',
|
|
17
|
+
'Only run follow-up commands when the JSON error includes a recovery action that requires them.',
|
|
18
|
+
],
|
|
19
|
+
agentQuickstart: {
|
|
20
|
+
doNotPreflight: true,
|
|
21
|
+
preferredFirstCommand: 'doomain link <domain> --json',
|
|
22
|
+
},
|
|
13
23
|
mutates: true,
|
|
14
24
|
safeForAgents: true,
|
|
15
25
|
flags: [
|
|
@@ -19,7 +29,7 @@ export const commandSchemas = [
|
|
|
19
29
|
{ name: 'subdomain', type: 'string', description: 'Subdomain to add.' },
|
|
20
30
|
{ name: 'apex', type: 'boolean', description: 'Use the root/apex domain.' },
|
|
21
31
|
{ name: 'project', type: 'string', description: 'Vercel project id/name. Optional when project inference succeeds.' },
|
|
22
|
-
{ name: 'dry-run', type: 'boolean', description: 'Preview changes without writing.' },
|
|
32
|
+
{ name: 'dry-run', type: 'boolean', description: 'Preview changes without writing. Intended for human previews; agents should not use this unless explicitly asked.' },
|
|
23
33
|
{ name: 'force', type: 'boolean', description: 'Overwrite conflicting DNS records.' },
|
|
24
34
|
{ name: 'wait', type: 'boolean', description: 'Wait for DNS and Vercel verification.', default: true },
|
|
25
35
|
{ name: 'timeout', type: 'integer', description: 'Wait timeout in seconds.', default: 300 },
|
|
@@ -101,3 +111,26 @@ export function getCommandSchema(name) {
|
|
|
101
111
|
return commandSchemas;
|
|
102
112
|
return commandSchemas.find((schema) => schema.name === name);
|
|
103
113
|
}
|
|
114
|
+
async function configuredProviders() {
|
|
115
|
+
return (await listProviderStatuses({ verify: false })).map((provider) => ({
|
|
116
|
+
configured: provider.configured,
|
|
117
|
+
default: provider.default,
|
|
118
|
+
displayName: provider.displayName,
|
|
119
|
+
docsUrl: provider.docsUrl,
|
|
120
|
+
id: provider.id,
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
function withProviderConnections(schema, providers) {
|
|
124
|
+
if (schema.name !== 'link')
|
|
125
|
+
return schema;
|
|
126
|
+
return { ...schema, configuredProviders: providers };
|
|
127
|
+
}
|
|
128
|
+
export async function getCommandSchemaForAgents(name) {
|
|
129
|
+
const schema = getCommandSchema(name);
|
|
130
|
+
if (!schema)
|
|
131
|
+
return undefined;
|
|
132
|
+
const providers = await configuredProviders();
|
|
133
|
+
if (Array.isArray(schema))
|
|
134
|
+
return schema.map((item) => withProviderConnections(item, providers));
|
|
135
|
+
return withProviderConnections(schema, providers);
|
|
136
|
+
}
|
package/dist/lib/link-domain.js
CHANGED
|
@@ -5,7 +5,7 @@ import { loadConfig } from './config.js';
|
|
|
5
5
|
import { DoomainError } from './errors.js';
|
|
6
6
|
import { detectLocalVercelProject } from './local-vercel.js';
|
|
7
7
|
import { createProvider, getProviderDefinition, listProviderDefinitions } from './providers/registry.js';
|
|
8
|
-
import { isProviderConfigured } from './providers/status.js';
|
|
8
|
+
import { isProviderConfigured, listProviderStatuses } from './providers/status.js';
|
|
9
9
|
import { normalizeDomain, normalizeSubdomain } from './validate.js';
|
|
10
10
|
import { createVercelClient, resolveVercelConfig, VERCEL_APEX_A_RECORD, VERCEL_CNAME_RECORD } from './vercel.js';
|
|
11
11
|
function cleanDnsValue(value) {
|
|
@@ -115,6 +115,15 @@ async function resolveZone(provider, zoneDomain) {
|
|
|
115
115
|
}
|
|
116
116
|
return zone;
|
|
117
117
|
}
|
|
118
|
+
async function providerConnectionDetails() {
|
|
119
|
+
return (await listProviderStatuses({ verify: false })).map((provider) => ({
|
|
120
|
+
configured: provider.configured,
|
|
121
|
+
default: provider.default,
|
|
122
|
+
displayName: provider.displayName,
|
|
123
|
+
docsUrl: provider.docsUrl,
|
|
124
|
+
id: provider.id,
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
118
127
|
function resolveRequestedDomain(opts) {
|
|
119
128
|
if (opts.apex && opts.subdomain) {
|
|
120
129
|
throw new DoomainError('INVALID_INPUT', 'Use either --apex or --subdomain, not both.');
|
|
@@ -168,7 +177,11 @@ async function loadConfiguredProviderZones(providerId) {
|
|
|
168
177
|
const config = await loadConfig();
|
|
169
178
|
const definitions = listProviderDefinitions().filter((definition) => isProviderConfigured(definition, config));
|
|
170
179
|
if (definitions.length === 0) {
|
|
171
|
-
throw new DoomainError('CONFIG_NOT_FOUND', 'No DNS provider is configured. Run `doomain providers connect` first.'
|
|
180
|
+
throw new DoomainError('CONFIG_NOT_FOUND', 'No DNS provider is configured. Run `doomain providers connect` first.', {
|
|
181
|
+
configuredProviders: await providerConnectionDetails(),
|
|
182
|
+
recovery: 'Connect the DNS provider that owns this domain, then retry `doomain link <domain> --json`.',
|
|
183
|
+
suggestedCommands: ['doomain providers connect', 'doomain link <domain> --json'],
|
|
184
|
+
});
|
|
172
185
|
}
|
|
173
186
|
const results = await Promise.all(definitions.map(async (definition) => {
|
|
174
187
|
try {
|
|
@@ -206,7 +219,13 @@ async function resolveProviderTarget(input) {
|
|
|
206
219
|
const providerMessage = input.provider
|
|
207
220
|
? `${getProviderDefinition(input.provider).displayName} does not have a matching DNS zone for ${requested.fullDomain}.`
|
|
208
221
|
: `No configured DNS provider has a matching DNS zone for ${requested.fullDomain}.`;
|
|
209
|
-
throw new DoomainError('PROVIDER_ZONE_NOT_FOUND', providerMessage, {
|
|
222
|
+
throw new DoomainError('PROVIDER_ZONE_NOT_FOUND', providerMessage, {
|
|
223
|
+
configuredProviders: await providerConnectionDetails(),
|
|
224
|
+
domain: requested.fullDomain,
|
|
225
|
+
recovery: 'Retry with --provider <id> only if another configured provider owns this zone. Otherwise connect the DNS provider that owns this domain.',
|
|
226
|
+
searchedZones: zones.searched,
|
|
227
|
+
suggestedCommands: [`doomain link ${requested.fullDomain} --provider <id> --json`, 'doomain providers connect'],
|
|
228
|
+
});
|
|
210
229
|
}
|
|
211
230
|
const bestLength = matches[0].zone.name.length;
|
|
212
231
|
const bestMatches = matches.filter((candidate) => candidate.zone.name.length === bestLength);
|
package/oclif.manifest.json
CHANGED
|
@@ -301,41 +301,6 @@
|
|
|
301
301
|
"list.js"
|
|
302
302
|
]
|
|
303
303
|
},
|
|
304
|
-
"projects:list": {
|
|
305
|
-
"aliases": [],
|
|
306
|
-
"args": {},
|
|
307
|
-
"description": "List Vercel projects.",
|
|
308
|
-
"flags": {
|
|
309
|
-
"json": {
|
|
310
|
-
"description": "Output a single JSON object and never prompt.",
|
|
311
|
-
"name": "json",
|
|
312
|
-
"allowNo": false,
|
|
313
|
-
"type": "boolean"
|
|
314
|
-
},
|
|
315
|
-
"search": {
|
|
316
|
-
"description": "Filter projects by search term.",
|
|
317
|
-
"name": "search",
|
|
318
|
-
"hasDynamicHelp": false,
|
|
319
|
-
"multiple": false,
|
|
320
|
-
"type": "option"
|
|
321
|
-
}
|
|
322
|
-
},
|
|
323
|
-
"hasDynamicHelp": false,
|
|
324
|
-
"hiddenAliases": [],
|
|
325
|
-
"id": "projects:list",
|
|
326
|
-
"pluginAlias": "doomain",
|
|
327
|
-
"pluginName": "doomain",
|
|
328
|
-
"pluginType": "core",
|
|
329
|
-
"strict": true,
|
|
330
|
-
"enableJsonFlag": false,
|
|
331
|
-
"isESM": true,
|
|
332
|
-
"relativePath": [
|
|
333
|
-
"dist",
|
|
334
|
-
"commands",
|
|
335
|
-
"projects",
|
|
336
|
-
"list.js"
|
|
337
|
-
]
|
|
338
|
-
},
|
|
339
304
|
"providers:add": {
|
|
340
305
|
"aliases": [],
|
|
341
306
|
"args": {
|
|
@@ -596,6 +561,41 @@
|
|
|
596
561
|
"verify.js"
|
|
597
562
|
]
|
|
598
563
|
},
|
|
564
|
+
"projects:list": {
|
|
565
|
+
"aliases": [],
|
|
566
|
+
"args": {},
|
|
567
|
+
"description": "List Vercel projects.",
|
|
568
|
+
"flags": {
|
|
569
|
+
"json": {
|
|
570
|
+
"description": "Output a single JSON object and never prompt.",
|
|
571
|
+
"name": "json",
|
|
572
|
+
"allowNo": false,
|
|
573
|
+
"type": "boolean"
|
|
574
|
+
},
|
|
575
|
+
"search": {
|
|
576
|
+
"description": "Filter projects by search term.",
|
|
577
|
+
"name": "search",
|
|
578
|
+
"hasDynamicHelp": false,
|
|
579
|
+
"multiple": false,
|
|
580
|
+
"type": "option"
|
|
581
|
+
}
|
|
582
|
+
},
|
|
583
|
+
"hasDynamicHelp": false,
|
|
584
|
+
"hiddenAliases": [],
|
|
585
|
+
"id": "projects:list",
|
|
586
|
+
"pluginAlias": "doomain",
|
|
587
|
+
"pluginName": "doomain",
|
|
588
|
+
"pluginType": "core",
|
|
589
|
+
"strict": true,
|
|
590
|
+
"enableJsonFlag": false,
|
|
591
|
+
"isESM": true,
|
|
592
|
+
"relativePath": [
|
|
593
|
+
"dist",
|
|
594
|
+
"commands",
|
|
595
|
+
"projects",
|
|
596
|
+
"list.js"
|
|
597
|
+
]
|
|
598
|
+
},
|
|
599
599
|
"auth:logout:vercel": {
|
|
600
600
|
"aliases": [],
|
|
601
601
|
"args": {},
|
|
@@ -630,5 +630,5 @@
|
|
|
630
630
|
]
|
|
631
631
|
}
|
|
632
632
|
},
|
|
633
|
-
"version": "0.1.
|
|
633
|
+
"version": "0.1.8"
|
|
634
634
|
}
|