uplink-cli 0.2.3 → 0.2.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.
- package/AGENTS.md +20 -2
- package/CHANGELOG.md +16 -0
- package/README.md +5 -2
- package/cli/bin/uplink.js +3 -3
- package/cli/src/registrars/cpanel.ts +172 -0
- package/cli/src/registrars/index.ts +2 -0
- package/cli/src/registrars/namecheap-purchase.ts +219 -0
- package/cli/src/registrars/types.ts +11 -1
- package/cli/src/subcommands/domains.ts +354 -18
- package/cli/src/subcommands/menu/menus/domain-check.ts +9 -3
- package/cli/src/subcommands/menu/menus/domains.ts +24 -4
- package/cli/src/tui/DomainSearch.tsx +427 -27
- package/cli/src/tui/use-terminal-mouse.ts +60 -0
- package/cli/src/utils/open-browser.ts +16 -0
- package/cli/src/utils/registrant-contact.ts +64 -0
- package/cli/src/utils/run-esm.ts +28 -10
- package/docs/AGENTS.md +20 -2
- package/docs/PRODUCT.md +1 -1
- package/package.json +1 -1
package/cli/src/utils/run-esm.ts
CHANGED
|
@@ -9,30 +9,48 @@ export function cliPackageRoot(): string {
|
|
|
9
9
|
export function resolveTsx(): string {
|
|
10
10
|
const root = cliPackageRoot();
|
|
11
11
|
try {
|
|
12
|
-
|
|
12
|
+
// Prefer the package exports entry (works across tsx 4.21–4.23+)
|
|
13
|
+
return require.resolve("tsx/cli", { paths: [root] });
|
|
13
14
|
} catch {
|
|
14
15
|
try {
|
|
15
|
-
return require.resolve("tsx/cli", { paths: [root] });
|
|
16
|
+
return require.resolve("tsx/dist/cli.cjs", { paths: [root] });
|
|
16
17
|
} catch {
|
|
17
18
|
return "tsx";
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
22
|
|
|
23
|
+
function spawnEsmEntry(entry: string): { status: number | null; error?: Error } {
|
|
24
|
+
const root = cliPackageRoot();
|
|
25
|
+
// Do not pass the package root tsconfig (module: commonjs). That forces
|
|
26
|
+
// esbuild into CJS output and breaks Ink/yoga-layout (top-level await).
|
|
27
|
+
const result = spawnSync(resolveTsx(), [entry], {
|
|
28
|
+
stdio: "inherit",
|
|
29
|
+
cwd: root,
|
|
30
|
+
env: process.env,
|
|
31
|
+
});
|
|
32
|
+
if (result.error) return { status: result.status ?? 1, error: result.error };
|
|
33
|
+
return { status: result.status };
|
|
34
|
+
}
|
|
35
|
+
|
|
22
36
|
/**
|
|
23
37
|
* Ink 6 is ESM-only (yoga-layout uses top-level await). The CLI package is
|
|
24
38
|
* CommonJS, so Ink screens must run as a child ESM process rather than being
|
|
25
39
|
* imported from commander commands.
|
|
26
40
|
*/
|
|
27
41
|
export function runEsmEntry(entry: string): never {
|
|
28
|
-
const
|
|
29
|
-
const tsconfigPath = join(root, "tsconfig.json");
|
|
30
|
-
const tsxArgs = existsSync(tsconfigPath) ? ["--tsconfig", tsconfigPath, entry] : [entry];
|
|
31
|
-
const result = spawnSync(resolveTsx(), tsxArgs, {
|
|
32
|
-
stdio: "inherit",
|
|
33
|
-
cwd: root,
|
|
34
|
-
env: process.env,
|
|
35
|
-
});
|
|
42
|
+
const result = spawnEsmEntry(entry);
|
|
36
43
|
if (result.error) throw result.error;
|
|
37
44
|
process.exit(result.status ?? 0);
|
|
38
45
|
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Same as runEsmEntry, but returns to the caller (for nesting inside the menu).
|
|
49
|
+
*/
|
|
50
|
+
export function runEsmEntryAndWait(entry: string): void {
|
|
51
|
+
const result = spawnEsmEntry(entry);
|
|
52
|
+
if (result.error) throw result.error;
|
|
53
|
+
if (result.status && result.status !== 0) {
|
|
54
|
+
throw new Error(`Interactive screen exited with code ${result.status}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
package/docs/AGENTS.md
CHANGED
|
@@ -111,7 +111,10 @@ Notes:
|
|
|
111
111
|
|
|
112
112
|
## Custom domains
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
Uplink is a hub for domains and hosting spread across providers: registrar inventory
|
|
115
|
+
(GoDaddy, Cloudflare, Hostinger, Namecheap, DreamHost) and hosted domains from any
|
|
116
|
+
**cPanel** account (Namecheap shared, Bluehost, HostGator, …) land in one `domains list`.
|
|
117
|
+
Attach/verify is under `host domains`.
|
|
115
118
|
The bare `uplink domains` command opens Find a domain. Agents should use JSON:
|
|
116
119
|
|
|
117
120
|
```bash
|
|
@@ -123,6 +126,9 @@ uplink domains providers connect cloudflare --token-env CF_API_TOKEN --json
|
|
|
123
126
|
uplink domains providers connect hostinger --token-env HOSTINGER_API_TOKEN --json
|
|
124
127
|
uplink domains providers connect dreamhost --token-env DREAMHOST_API_KEY --json
|
|
125
128
|
uplink domains providers connect namecheap --token-env NAMECHEAP_API_KEY --user-env NAMECHEAP_API_USER --json
|
|
129
|
+
uplink domains providers connect cpanel --host server341.web-hosting.com --user-env CPANEL_USER --token-env CPANEL_API_TOKEN --json
|
|
130
|
+
# Repeat connect with another --host to add more cPanel accounts; remove one with:
|
|
131
|
+
uplink domains providers disconnect cpanel --host server341.web-hosting.com --json
|
|
126
132
|
uplink domains providers list --json
|
|
127
133
|
uplink domains providers disconnect godaddy --json
|
|
128
134
|
|
|
@@ -132,7 +138,19 @@ echo "$TOKEN" | uplink --token-stdin host domains list --id app_xxx --json
|
|
|
132
138
|
echo "$TOKEN" | uplink --token-stdin host domains remove --id app_xxx --hostname example.com --json
|
|
133
139
|
```
|
|
134
140
|
|
|
135
|
-
`domains check` works without a registrar: it falls back to public DNS/RDAP and returns `provider: "public"` with no price. Do not treat RDAP “available” as buyable unless `domains check` says `buyable: true`.
|
|
141
|
+
`domains check` works without a registrar: it falls back to public DNS/RDAP and returns `provider: "public"` with no price. Do not treat RDAP “available” as buyable unless `domains check` says `buyable: true`.
|
|
142
|
+
|
|
143
|
+
Purchase (Namecheap):
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
uplink domains contact seed --json # copy WHOIS from an owned domain
|
|
147
|
+
uplink domains contact set --json # or set flags / interactive
|
|
148
|
+
uplink domains fund --amount 20 --json # payment page URL to tank balance
|
|
149
|
+
uplink domains buy alchemy.photos --yes --json
|
|
150
|
+
uplink domains buy alchemy.photos --open-cart --json # browser cart instead
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
API buys charge Namecheap **account balance**. If balance is low, `buy` / the Find a domain TUI return/open an add-funds `redirectUrl` from `namecheap.users.createaddfundsrequest`.
|
|
136
154
|
|
|
137
155
|
## Databases (optional)
|
|
138
156
|
|
package/docs/PRODUCT.md
CHANGED
|
@@ -10,7 +10,7 @@ Three surfaces, one CLI (`uplink`):
|
|
|
10
10
|
|
|
11
11
|
1. **Share** — expose `localhost:<port>` as HTTPS (`https://<token>.x.uplink.spot`).
|
|
12
12
|
2. **Hosting** — deploy a project to `https://<app_id>.host.uplink.spot` (email-verified accounts).
|
|
13
|
-
3. **Domains** —
|
|
13
|
+
3. **Domains** — a hub for names spread across providers: one inventory from registrars (GoDaddy, Cloudflare, Hostinger, Namecheap, DreamHost) plus any cPanel host (Namecheap shared, Bluehost, HostGator, …), availability checks, and hostname attach/verify on hosted apps.
|
|
14
14
|
|
|
15
15
|
Humans use `uplink` (keyboard menu). Agents use subcommands with `--json` and `--token-stdin`.
|
|
16
16
|
|
package/package.json
CHANGED