@hasna/domains 0.0.47 → 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.
- package/README.md +58 -34
- package/dist/cli/commands/dns.d.ts.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/serve.d.ts +1 -0
- package/dist/cli/commands/serve.d.ts.map +1 -1
- package/dist/cli/index.js +4754 -2105
- package/dist/db/database.d.ts +6 -23
- package/dist/db/database.d.ts.map +1 -1
- package/dist/db/domains.d.ts +3 -14
- package/dist/db/domains.d.ts.map +1 -1
- package/dist/db/store.d.ts +36 -32
- package/dist/db/store.d.ts.map +1 -1
- package/dist/generated/storage-kit/backend.d.ts +4 -4
- package/dist/generated/storage-kit/backend.d.ts.map +1 -1
- package/dist/generated/storage-kit/index.d.ts +1 -1
- package/dist/generated/storage-kit/index.d.ts.map +1 -1
- package/dist/generated/storage-kit/migrations.d.ts.map +1 -1
- package/dist/generated/storage-kit/pool.d.ts +2 -5
- package/dist/generated/storage-kit/pool.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1127 -1734
- package/dist/lib/app-home.d.ts +32 -44
- package/dist/lib/app-home.d.ts.map +1 -1
- package/dist/lib/client-storage-policy.d.ts +10 -0
- package/dist/lib/client-storage-policy.d.ts.map +1 -0
- package/dist/lib/client-types.d.ts +184 -0
- package/dist/lib/client-types.d.ts.map +1 -0
- package/dist/lib/cloudflare.d.ts.map +1 -1
- package/dist/lib/cloudflare.js +23 -0
- package/dist/lib/config.d.ts +6 -16
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/dns-plan.d.ts +1 -1
- package/dist/lib/dns-plan.d.ts.map +1 -1
- package/dist/lib/domains-resolver.d.ts +96 -0
- package/dist/lib/domains-resolver.d.ts.map +1 -0
- package/dist/lib/registrar.d.ts +8 -0
- package/dist/lib/registrar.d.ts.map +1 -1
- package/dist/lib/registrar.js +23 -0
- package/dist/mcp/harness.d.ts +46 -0
- package/dist/mcp/harness.d.ts.map +1 -0
- package/dist/mcp/http.d.ts +3 -2
- package/dist/mcp/http.d.ts.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +24162 -25378
- package/dist/mcp/tool-filter.d.ts +6 -0
- package/dist/mcp/tool-filter.d.ts.map +1 -1
- package/dist/sdk/index.d.ts +21 -10
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/index.js +813 -275
- package/dist/server/index.d.ts +6 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +84 -29
- package/package.json +5 -7
- package/postinstall.js +13 -14
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @hasna/domains
|
|
2
2
|
|
|
3
|
-
Domain portfolio, registrar, marketplace, and DNS management for AI agents. The package ships a CLI, MCP server, authenticated HTTP API, generated SDK, and library exports.
|
|
3
|
+
Domain portfolio, registrar, marketplace, and DNS management for AI agents. The package ships a CLI, MCP server, authenticated HTTP API, generated SDK, and library exports. Every client surface resolves its credential and authority through the one shared `@hasna/contracts` resolver (macOS Keychain, `~/.hasna/domains/config/credentials`, or `HASNA_DOMAINS_API_KEY`, with the fleet gateway `https://api.hasna.com/domains` as the default authority), and data commands fail closed when no credential resolves: local SQLite path settings are rejected; `domains-serve` connects directly to cloud Postgres.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
@@ -33,7 +33,7 @@ Domain portfolio, registrar, marketplace, and DNS management for AI agents. The
|
|
|
33
33
|
npm install -g @hasna/domains
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
All normal clients use the shared account API. Saved credentials live in the macOS Keychain or `~/.hasna/domains/config/credentials`; `HASNA_HOME` and `HASNA_CONFIG_HOME` can select the credential root. Existing SQLite files are preserved for verified migration and are never opened by the CLI, MCP or SDK factory.
|
|
37
37
|
|
|
38
38
|
## Optional Command Groups
|
|
39
39
|
|
|
@@ -232,14 +232,21 @@ Route 53 sync imports registered domains when the selected AWS account permits `
|
|
|
232
232
|
|
|
233
233
|
## Storage
|
|
234
234
|
|
|
235
|
-
|
|
235
|
+
Every client surface — the CLI, the MCP server and the `./sdk` — resolves its credential and authority through the ONE shared `@hasna/contracts` resolver, fresh on every call:
|
|
236
236
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
237
|
+
1. an explicit `--api-key` / `--profile` argument (code-level)
|
|
238
|
+
2. a deliberate env pointer — `HASNA_DOMAINS_API_KEY_OVERRIDE`, `HASNA_PROFILE`, `HASNA_DOMAINS_API_KEY_REF`
|
|
239
|
+
3. the macOS Keychain — item `hasna.credentials.domains.api-key` / `.api-url`, account `HASNA_STATION`, else the short hostname, else `$USER`
|
|
240
|
+
4. disk, read at call time — `~/.hasna/domains/config/credentials` (owner-only 0600; `HASNA_HOME` / `HASNA_CONFIG_HOME` override the root)
|
|
241
|
+
5. `HASNA_DOMAINS_API_KEY` in the process env — a legitimate tier
|
|
242
|
+
|
|
243
|
+
The authority follows the same ladder — `HASNA_DOMAINS_API_URL`, the Keychain `api-url` item, the credentials file — and **defaults to the fleet gateway `https://api.hasna.com/domains`** once a credential resolves, so a key alone is a complete configuration. The unprefixed `DOMAINS_API_URL` / `DOMAINS_API_KEY` aliases are accepted by the resolver for one release; the canonical `HASNA_DOMAINS_*` names always win. Retired locations (`~/.hasna/fleet-env`, the cloud dirs under `~/.hasna`, `~/.config/hasna`, `$XDG_CONFIG_HOME`) are never read, and no `*_MODE` / `*_STORAGE_MODE` variable selects anything.
|
|
241
244
|
|
|
242
|
-
|
|
245
|
+
**Fail closed.** A hosted run with no credential exits non-zero naming the canonical env pair — never a silent fallback to SQLite, never a `*-local-fallback` event. A database DSN is never exposed to clients.
|
|
246
|
+
|
|
247
|
+
**SQLite client selection is retired.** Unset `HASNA_DOMAINS_DB_PATH`, `DOMAINS_DB_PATH`, `HASNA_DOMAINS_DIR` and `DOMAINS_DIR` before using normal clients. These settings are rejected even when no API key is configured. Preserve existing databases until all records have been reconciled and verified in the shared account; removing a path setting does not migrate data.
|
|
248
|
+
|
|
249
|
+
`domains serve` and `domains-serve` start the same authenticated PostgreSQL service. Both require a server database DSN (`HASNA_DOMAINS_DATABASE_URL`) and signing key (`HASNA_DOMAINS_API_SIGNING_KEY`); a client API key cannot authorize a listener. Data routes use `/v1` and validate each caller's key and revocation state. Apply owner-role migrations first with `domains db migrate`.
|
|
243
250
|
|
|
244
251
|
## MCP Server
|
|
245
252
|
|
|
@@ -297,10 +304,12 @@ Safe mode registers only read-only/list/check/export tools. Mutating tools such
|
|
|
297
304
|
```bash
|
|
298
305
|
domains-serve --host 0.0.0.0 --port 8080
|
|
299
306
|
curl http://127.0.0.1:8080/health
|
|
300
|
-
curl -H "x-api-key: $
|
|
307
|
+
curl -H "x-api-key: $HASNA_DOMAINS_API_KEY" http://127.0.0.1:8080/v1/domains
|
|
301
308
|
```
|
|
302
309
|
|
|
303
|
-
The package also exports the generated client
|
|
310
|
+
The package also exports the generated client, wired to the same shared
|
|
311
|
+
resolver the CLI and MCP server use — fresh on every request, so a key rotation
|
|
312
|
+
heals a long-lived client:
|
|
304
313
|
|
|
305
314
|
```ts
|
|
306
315
|
import { createDomainsClientFromEnv } from "@hasna/domains/sdk";
|
|
@@ -309,25 +318,34 @@ const domains = createDomainsClientFromEnv();
|
|
|
309
318
|
const portfolio = await domains.listDomains({ status: "active" });
|
|
310
319
|
```
|
|
311
320
|
|
|
312
|
-
|
|
321
|
+
An explicit `baseUrl` with no `apiKey` builds a client pinned to that authority
|
|
322
|
+
that never picks up an ambient fleet key; without a resolvable credential the
|
|
323
|
+
SDK throws — it never degrades to an anonymous client or to local data.
|
|
324
|
+
|
|
325
|
+
`domains serve` is an alias for the authenticated server runtime, preserving its CLI host/port defaults. Its account data routes are `/v1/*`; the former unauthenticated `/domains` proxy has been removed.
|
|
313
326
|
|
|
314
327
|
## Environment Variables
|
|
315
328
|
|
|
316
329
|
| Variable | Description |
|
|
317
330
|
|----------|-------------|
|
|
318
|
-
| `
|
|
319
|
-
| `
|
|
320
|
-
| `
|
|
321
|
-
| `
|
|
322
|
-
| `
|
|
323
|
-
| `
|
|
331
|
+
| `HASNA_DOMAINS_API_KEY` | Hosted API key (canonical env tier of the shared resolver; below the Keychain and the credential file) |
|
|
332
|
+
| `HASNA_DOMAINS_API_URL` | Optional hosted API base URL — defaults to the fleet gateway `https://api.hasna.com/domains` once a key resolves |
|
|
333
|
+
| `HASNA_DOMAINS_API_KEY_OVERRIDE` | Deliberate per-run key override that outranks every other tier |
|
|
334
|
+
| `HASNA_DOMAINS_API_KEY_REF` | Deliberate secrets-vault pointer resolved through the `@hasna/secrets` SDK at request time |
|
|
335
|
+
| `HASNA_PROFILE` | Global identity profile pointer (`credentials-<profile>` beside the credential file) |
|
|
336
|
+
| `HASNA_HOME` | Shared root override — `<HASNA_HOME>/domains/` for local data, `<HASNA_HOME>/domains/config/credentials` for the credential file |
|
|
337
|
+
| `HASNA_CONFIG_HOME` | Config-root override for the resolver's credential file |
|
|
338
|
+
| `HASNA_DOMAINS_DB_PATH` | Retired client setting; migrate and verify existing data before removal |
|
|
339
|
+
| `DOMAINS_DB_PATH` | Retired legacy client setting; rejected |
|
|
340
|
+
| `HASNA_DOMAINS_DIR` | Retired client setting; rejected |
|
|
341
|
+
| `DOMAINS_DIR` | Retired legacy client setting; rejected |
|
|
342
|
+
| `HASNA_DOMAINS_HOME`, `DOMAINS_HOME` | Exact-app home overrides (canonical name wins over the alias) |
|
|
343
|
+
| `HASNA_DOMAINS_CONFIG_PATH`, `DOMAINS_CONFIG_PATH` | Override the settings config file path |
|
|
344
|
+
| `DOMAINS_CONFIG_DIR` | Override the settings config directory |
|
|
324
345
|
| `DOMAINS_COMMAND_GROUPS` | Comma-separated optional command groups to load, or `all` |
|
|
325
346
|
| `DOMAINS_ENABLE_EXTRAS` | Set to `1` to load all optional command groups |
|
|
326
347
|
| `DOMAINS_MCP_SAFE_MODE` | Set to `1` to expose only read-only MCP tools |
|
|
327
|
-
| `
|
|
328
|
-
| `HASNA_DOMAINS_API_KEY`, `DOMAINS_API_KEY` | Hosted HTTP API key for the CLI/library store and SDK (set together with the URL) |
|
|
329
|
-
| `HASNA_DOMAINS_ALLOW_CLOUD_WITH_LOCAL_PATH` | Set to `1` to keep the hosted store even though a local path variable is set. Without it that combination is a hard error — see below |
|
|
330
|
-
| `HASNA_DOMAINS_DATABASE_URL` | Server-side PostgreSQL DSN used by `domains-serve` and DB migrations; SQLite backend when unset |
|
|
348
|
+
| `HASNA_DOMAINS_DATABASE_URL` | Server-side PostgreSQL DSN used by `domains-serve` and DB migrations; required for server storage |
|
|
331
349
|
| `HASNA_DOMAINS_API_SIGNING_KEY` | HMAC signing secret used by `domains-serve` to verify API keys |
|
|
332
350
|
| `AWS_PROFILE` | AWS profile for Route 53 Domains and hosted zones |
|
|
333
351
|
| `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_SESSION_TOKEN` | AWS credential fallback |
|
|
@@ -344,27 +362,33 @@ const portfolio = await domains.listDomains({ status: "active" });
|
|
|
344
362
|
| `BRANDSIGHT_DEMO_STUBS`, `BRANDSIGHT_ALLOW_STUBS` | Set either to `1` to allow demo stub responses when the Brandsight API is unreachable |
|
|
345
363
|
| `SEDO_PARTNER_ID`, `SEDO_API_KEY`, `SEDO_USERNAME`, `SEDO_PASSWORD` | Sedo marketplace API credentials |
|
|
346
364
|
|
|
347
|
-
### Picking a store: a local path and
|
|
365
|
+
### Picking a store: a local path and a configured credential are mutually exclusive
|
|
348
366
|
|
|
349
|
-
`DOMAINS_DB_PATH`, `
|
|
350
|
-
**local sqlite file**. Only the local store
|
|
351
|
-
|
|
352
|
-
|
|
367
|
+
`HASNA_DOMAINS_DB_PATH`, `DOMAINS_DB_PATH`, `HASNA_DOMAINS_DIR`, `DOMAINS_DIR` and
|
|
368
|
+
`HASNA_DOMAINS_HOME` all name a **local sqlite file or directory**. Only the local store
|
|
369
|
+
has one. So setting any of them while the environment also configures a hosted
|
|
370
|
+
authority or credential (`HASNA_DOMAINS_API_URL`, `HASNA_DOMAINS_API_KEY`, the
|
|
371
|
+
deliberate pointers, `HASNA_PROFILE`, or a Keychain / credential-file entry)
|
|
372
|
+
asks for two different stores at once, and **`getStore()` refuses to start**
|
|
373
|
+
rather than pick one for you. Local mode applies only when the environment
|
|
374
|
+
configures nothing at all.
|
|
353
375
|
|
|
354
|
-
This is deliberate. Before it, the combination silently resolved to the cloud
|
|
355
|
-
that set `DOMAINS_DB_PATH` created no sqlite file, wrote to the
|
|
356
|
-
success. Nothing on any surface said which store
|
|
376
|
+
This is deliberate. Before it, the combination silently resolved to the cloud
|
|
377
|
+
store: a script that set `DOMAINS_DB_PATH` created no sqlite file, wrote to the
|
|
378
|
+
remote portfolio, and printed success. Nothing on any surface said which store
|
|
379
|
+
it had used.
|
|
357
380
|
|
|
358
381
|
To resolve it, say which you meant:
|
|
359
382
|
|
|
360
383
|
```sh
|
|
361
|
-
unset
|
|
362
|
-
unset
|
|
363
|
-
HASNA_DOMAINS_ALLOW_CLOUD_WITH_LOCAL_PATH=1 # keep the hosted store with the variable present
|
|
384
|
+
unset HASNA_DOMAINS_DB_PATH DOMAINS_DB_PATH HASNA_DOMAINS_DIR DOMAINS_DIR HASNA_DOMAINS_HOME # use the hosted store
|
|
385
|
+
unset HASNA_DOMAINS_API_URL HASNA_DOMAINS_API_KEY HASNA_DOMAINS_API_KEY_OVERRIDE HASNA_DOMAINS_API_KEY_REF HASNA_PROFILE # use the sqlite file the path variable names
|
|
364
386
|
```
|
|
365
387
|
|
|
366
|
-
`domains doctor` names the store it resolved, in its `Store` section
|
|
367
|
-
|
|
388
|
+
`domains doctor` names the store it resolved, in its `Store` section — including
|
|
389
|
+
where the URL and key came from and which tier supplied the key — before any
|
|
390
|
+
other check runs. Run it whenever you are unsure which dataset a command is
|
|
391
|
+
about to touch.
|
|
368
392
|
|
|
369
393
|
## License
|
|
370
394
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dns.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/dns.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAezC,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAa1E,gFAAgF;AAChF,eAAO,MAAM,mBAAmB,aAA4D,CAAC;AAE7F;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EACjE,OAAO,EAAE,CAAC,EAAE,GACX;IAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAW7C;AAyBD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,IAAI,GAAE;IAAE,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,WAAW,CAAA;CAAO,GAC5D,IAAI,
|
|
1
|
+
{"version":3,"file":"dns.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/dns.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAezC,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAa1E,gFAAgF;AAChF,eAAO,MAAM,mBAAmB,aAA4D,CAAC;AAE7F;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EACjE,OAAO,EAAE,CAAC,EAAE,GACX;IAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAW7C;AAyBD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,IAAI,GAAE;IAAE,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,WAAW,CAAA;CAAO,GAC5D,IAAI,CA4ZN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuI5D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/serve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/serve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAS3D"}
|