@hasna/domains 0.0.15 → 0.0.16
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 +5 -1
- package/dist/cli/commands/interactive.d.ts +3 -0
- package/dist/cli/commands/interactive.d.ts.map +1 -0
- package/dist/cli/index.js +647 -21
- package/dist/cli/tui/App.d.ts +6 -0
- package/dist/cli/tui/App.d.ts.map +1 -0
- package/dist/cli/tui/DomainDetail.d.ts +11 -0
- package/dist/cli/tui/DomainDetail.d.ts.map +1 -0
- package/dist/cli/tui/DomainTable.d.ts +10 -0
- package/dist/cli/tui/DomainTable.d.ts.map +1 -0
- package/dist/cli/tui/Header.d.ts +10 -0
- package/dist/cli/tui/Header.d.ts.map +1 -0
- package/dist/cli/tui/SearchView.d.ts +12 -0
- package/dist/cli/tui/SearchView.d.ts.map +1 -0
- package/dist/cli/tui/format.d.ts +17 -0
- package/dist/cli/tui/format.d.ts.map +1 -0
- package/dist/index.js +3 -21
- package/dist/mcp/index.js +3 -21
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ Domain portfolio and DNS management for AI agents — CLI + MCP server with SQLi
|
|
|
17
17
|
- **Registrar sync** — Namecheap and GoDaddy integration
|
|
18
18
|
- **Brand monitoring** — typosquat/threat detection via Brandsight API
|
|
19
19
|
- **MCP server** — full Model Context Protocol support for AI agents
|
|
20
|
+
- **Interactive TUI** — browse your portfolio in the terminal with `domains interactive`
|
|
20
21
|
|
|
21
22
|
## Installation
|
|
22
23
|
|
|
@@ -29,7 +30,10 @@ Data is stored at `~/.hasna/domains/domains.db`. Override with `HASNA_DOMAINS_DI
|
|
|
29
30
|
## CLI Usage
|
|
30
31
|
|
|
31
32
|
```bash
|
|
32
|
-
#
|
|
33
|
+
# Interactive portfolio browser (Ink TUI)
|
|
34
|
+
domains interactive
|
|
35
|
+
domains interactive --status active
|
|
36
|
+
```
|
|
33
37
|
domains add --name example.com --registrar Namecheap --expires-at 2025-01-01
|
|
34
38
|
domains list
|
|
35
39
|
domains list --status active --registrar Namecheap
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/interactive.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgBjE"}
|
package/dist/cli/index.js
CHANGED
|
@@ -5,43 +5,25 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
function __accessProp(key) {
|
|
9
|
-
return this[key];
|
|
10
|
-
}
|
|
11
|
-
var __toESMCache_node;
|
|
12
|
-
var __toESMCache_esm;
|
|
13
8
|
var __toESM = (mod, isNodeMode, target) => {
|
|
14
|
-
var canCache = mod != null && typeof mod === "object";
|
|
15
|
-
if (canCache) {
|
|
16
|
-
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
17
|
-
var cached = cache.get(mod);
|
|
18
|
-
if (cached)
|
|
19
|
-
return cached;
|
|
20
|
-
}
|
|
21
9
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
22
10
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
23
11
|
for (let key of __getOwnPropNames(mod))
|
|
24
12
|
if (!__hasOwnProp.call(to, key))
|
|
25
13
|
__defProp(to, key, {
|
|
26
|
-
get:
|
|
14
|
+
get: () => mod[key],
|
|
27
15
|
enumerable: true
|
|
28
16
|
});
|
|
29
|
-
if (canCache)
|
|
30
|
-
cache.set(mod, to);
|
|
31
17
|
return to;
|
|
32
18
|
};
|
|
33
19
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
34
|
-
var __returnValue = (v) => v;
|
|
35
|
-
function __exportSetter(name, newValue) {
|
|
36
|
-
this[name] = __returnValue.bind(null, newValue);
|
|
37
|
-
}
|
|
38
20
|
var __export = (target, all) => {
|
|
39
21
|
for (var name in all)
|
|
40
22
|
__defProp(target, name, {
|
|
41
23
|
get: all[name],
|
|
42
24
|
enumerable: true,
|
|
43
25
|
configurable: true,
|
|
44
|
-
set:
|
|
26
|
+
set: (newValue) => all[name] = () => newValue
|
|
45
27
|
});
|
|
46
28
|
};
|
|
47
29
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
@@ -19549,7 +19531,7 @@ var require_package = __commonJS((exports, module) => {
|
|
|
19549
19531
|
|
|
19550
19532
|
// node_modules/@aws-sdk/util-user-agent-node/dist-cjs/index.js
|
|
19551
19533
|
var require_dist_cjs41 = __commonJS((exports) => {
|
|
19552
|
-
var __dirname = "/
|
|
19534
|
+
var __dirname = "/Users/hasna/Workspace/hasna/opensource/open-domains/node_modules/@aws-sdk/util-user-agent-node/dist-cjs";
|
|
19553
19535
|
var node_os = __require("os");
|
|
19554
19536
|
var node_process = __require("process");
|
|
19555
19537
|
var utilConfigProvider = require_dist_cjs33();
|
|
@@ -39944,6 +39926,649 @@ Domain: ${name}`);
|
|
|
39944
39926
|
});
|
|
39945
39927
|
}
|
|
39946
39928
|
|
|
39929
|
+
// src/cli/commands/interactive.tsx
|
|
39930
|
+
import chalk from "chalk";
|
|
39931
|
+
import { render } from "ink";
|
|
39932
|
+
|
|
39933
|
+
// src/cli/tui/App.tsx
|
|
39934
|
+
init_domains();
|
|
39935
|
+
init_dns_records();
|
|
39936
|
+
import { useCallback, useEffect, useMemo, useState as useState2 } from "react";
|
|
39937
|
+
import { Box as Box5, Text as Text5, useApp, useInput as useInput2 } from "ink";
|
|
39938
|
+
|
|
39939
|
+
// src/cli/tui/Header.tsx
|
|
39940
|
+
import { Box, Text } from "ink";
|
|
39941
|
+
|
|
39942
|
+
// src/cli/tui/format.ts
|
|
39943
|
+
var TABLE_COLS = {
|
|
39944
|
+
name: 28,
|
|
39945
|
+
status: 14,
|
|
39946
|
+
expires: 12,
|
|
39947
|
+
registrar: 16
|
|
39948
|
+
};
|
|
39949
|
+
function pad(value, width) {
|
|
39950
|
+
if (value.length > width)
|
|
39951
|
+
return value.slice(0, width - 1) + "\u2026";
|
|
39952
|
+
return value.padEnd(width);
|
|
39953
|
+
}
|
|
39954
|
+
function formatDate(iso) {
|
|
39955
|
+
if (!iso)
|
|
39956
|
+
return "\u2014";
|
|
39957
|
+
return iso.slice(0, 10);
|
|
39958
|
+
}
|
|
39959
|
+
function daysUntil(iso) {
|
|
39960
|
+
if (!iso)
|
|
39961
|
+
return "\u2014";
|
|
39962
|
+
const ms = new Date(iso).getTime() - Date.now();
|
|
39963
|
+
const days = Math.ceil(ms / (1000 * 60 * 60 * 24));
|
|
39964
|
+
if (days < 0)
|
|
39965
|
+
return "expired";
|
|
39966
|
+
if (days === 0)
|
|
39967
|
+
return "today";
|
|
39968
|
+
return `${days}d`;
|
|
39969
|
+
}
|
|
39970
|
+
var STATUS_COLORS = {
|
|
39971
|
+
discovered: "gray",
|
|
39972
|
+
researching: "blue",
|
|
39973
|
+
offered: "yellow",
|
|
39974
|
+
negotiating: "yellow",
|
|
39975
|
+
purchased: "green",
|
|
39976
|
+
active: "green",
|
|
39977
|
+
not_available: "red",
|
|
39978
|
+
premium_only: "magenta",
|
|
39979
|
+
declined: "red",
|
|
39980
|
+
expired: "red",
|
|
39981
|
+
transferring: "cyan",
|
|
39982
|
+
redemption: "red"
|
|
39983
|
+
};
|
|
39984
|
+
var DOMAIN_FILTERS = ["all", "active", "expiring", "premium"];
|
|
39985
|
+
function filterLabel(filter) {
|
|
39986
|
+
switch (filter) {
|
|
39987
|
+
case "all":
|
|
39988
|
+
return "All";
|
|
39989
|
+
case "active":
|
|
39990
|
+
return "Active";
|
|
39991
|
+
case "expiring":
|
|
39992
|
+
return "Expiring (30d)";
|
|
39993
|
+
case "premium":
|
|
39994
|
+
return "Premium";
|
|
39995
|
+
}
|
|
39996
|
+
}
|
|
39997
|
+
|
|
39998
|
+
// src/cli/tui/Header.tsx
|
|
39999
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
40000
|
+
function Header({ count, filter, view }) {
|
|
40001
|
+
const viewLabel = view === "list" ? "Portfolio" : view === "detail" ? "Detail" : "Search";
|
|
40002
|
+
return /* @__PURE__ */ jsxDEV(Box, {
|
|
40003
|
+
flexDirection: "column",
|
|
40004
|
+
marginBottom: 1,
|
|
40005
|
+
children: [
|
|
40006
|
+
/* @__PURE__ */ jsxDEV(Box, {
|
|
40007
|
+
children: [
|
|
40008
|
+
/* @__PURE__ */ jsxDEV(Text, {
|
|
40009
|
+
bold: true,
|
|
40010
|
+
color: "cyan",
|
|
40011
|
+
children: "domains"
|
|
40012
|
+
}, undefined, false, undefined, this),
|
|
40013
|
+
/* @__PURE__ */ jsxDEV(Text, {
|
|
40014
|
+
dimColor: true,
|
|
40015
|
+
children: " \u2014 interactive portfolio browser"
|
|
40016
|
+
}, undefined, false, undefined, this)
|
|
40017
|
+
]
|
|
40018
|
+
}, undefined, true, undefined, this),
|
|
40019
|
+
/* @__PURE__ */ jsxDEV(Box, {
|
|
40020
|
+
children: /* @__PURE__ */ jsxDEV(Text, {
|
|
40021
|
+
dimColor: true,
|
|
40022
|
+
children: [
|
|
40023
|
+
viewLabel,
|
|
40024
|
+
" \xB7 ",
|
|
40025
|
+
filterLabel(filter),
|
|
40026
|
+
" \xB7 ",
|
|
40027
|
+
count,
|
|
40028
|
+
" domain",
|
|
40029
|
+
count === 1 ? "" : "s"
|
|
40030
|
+
]
|
|
40031
|
+
}, undefined, true, undefined, this)
|
|
40032
|
+
}, undefined, false, undefined, this)
|
|
40033
|
+
]
|
|
40034
|
+
}, undefined, true, undefined, this);
|
|
40035
|
+
}
|
|
40036
|
+
|
|
40037
|
+
// src/cli/tui/DomainTable.tsx
|
|
40038
|
+
import { Box as Box2, Text as Text2 } from "ink";
|
|
40039
|
+
import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
|
|
40040
|
+
var VISIBLE_ROWS = 16;
|
|
40041
|
+
function DomainTable({ domains, selectedIndex, compact = false }) {
|
|
40042
|
+
if (domains.length === 0) {
|
|
40043
|
+
return /* @__PURE__ */ jsxDEV2(Box2, {
|
|
40044
|
+
flexDirection: "column",
|
|
40045
|
+
paddingLeft: compact ? 0 : 1,
|
|
40046
|
+
children: /* @__PURE__ */ jsxDEV2(Text2, {
|
|
40047
|
+
dimColor: true,
|
|
40048
|
+
children: "No domains match this filter. Press [f] to change filter or [r] to refresh."
|
|
40049
|
+
}, undefined, false, undefined, this)
|
|
40050
|
+
}, undefined, false, undefined, this);
|
|
40051
|
+
}
|
|
40052
|
+
const start = Math.max(0, Math.min(selectedIndex - Math.floor(VISIBLE_ROWS / 2), Math.max(0, domains.length - VISIBLE_ROWS)));
|
|
40053
|
+
const visible = domains.slice(start, start + VISIBLE_ROWS);
|
|
40054
|
+
return /* @__PURE__ */ jsxDEV2(Box2, {
|
|
40055
|
+
flexDirection: "column",
|
|
40056
|
+
width: "100%",
|
|
40057
|
+
paddingRight: 0,
|
|
40058
|
+
children: [
|
|
40059
|
+
/* @__PURE__ */ jsxDEV2(Box2, {
|
|
40060
|
+
children: /* @__PURE__ */ jsxDEV2(Text2, {
|
|
40061
|
+
bold: true,
|
|
40062
|
+
dimColor: true,
|
|
40063
|
+
children: [
|
|
40064
|
+
pad("NAME", TABLE_COLS.name),
|
|
40065
|
+
pad("STATUS", TABLE_COLS.status),
|
|
40066
|
+
pad("EXPIRES", TABLE_COLS.expires),
|
|
40067
|
+
pad("REGISTRAR", TABLE_COLS.registrar),
|
|
40068
|
+
!compact ? " TTL" : ""
|
|
40069
|
+
]
|
|
40070
|
+
}, undefined, true, undefined, this)
|
|
40071
|
+
}, undefined, false, undefined, this),
|
|
40072
|
+
/* @__PURE__ */ jsxDEV2(Text2, {
|
|
40073
|
+
dimColor: true,
|
|
40074
|
+
children: "\u2500".repeat(TABLE_COLS.name + TABLE_COLS.status + TABLE_COLS.expires + TABLE_COLS.registrar + (compact ? 0 : 6))
|
|
40075
|
+
}, undefined, false, undefined, this),
|
|
40076
|
+
start > 0 && /* @__PURE__ */ jsxDEV2(Text2, {
|
|
40077
|
+
dimColor: true,
|
|
40078
|
+
children: [
|
|
40079
|
+
" \u2191 ",
|
|
40080
|
+
start,
|
|
40081
|
+
" more above"
|
|
40082
|
+
]
|
|
40083
|
+
}, undefined, true, undefined, this),
|
|
40084
|
+
visible.map((domain, offset) => {
|
|
40085
|
+
const index = start + offset;
|
|
40086
|
+
const selected = index === selectedIndex;
|
|
40087
|
+
const statusColor = STATUS_COLORS[domain.status] ?? "white";
|
|
40088
|
+
return /* @__PURE__ */ jsxDEV2(Box2, {
|
|
40089
|
+
children: [
|
|
40090
|
+
/* @__PURE__ */ jsxDEV2(Text2, {
|
|
40091
|
+
color: selected ? "cyan" : undefined,
|
|
40092
|
+
bold: selected,
|
|
40093
|
+
children: selected ? "\u276F " : " "
|
|
40094
|
+
}, undefined, false, undefined, this),
|
|
40095
|
+
/* @__PURE__ */ jsxDEV2(Text2, {
|
|
40096
|
+
bold: selected,
|
|
40097
|
+
children: pad(domain.name, TABLE_COLS.name)
|
|
40098
|
+
}, undefined, false, undefined, this),
|
|
40099
|
+
/* @__PURE__ */ jsxDEV2(Text2, {
|
|
40100
|
+
color: statusColor,
|
|
40101
|
+
children: pad(domain.status, TABLE_COLS.status)
|
|
40102
|
+
}, undefined, false, undefined, this),
|
|
40103
|
+
/* @__PURE__ */ jsxDEV2(Text2, {
|
|
40104
|
+
children: pad(formatDate(domain.expires_at), TABLE_COLS.expires)
|
|
40105
|
+
}, undefined, false, undefined, this),
|
|
40106
|
+
/* @__PURE__ */ jsxDEV2(Text2, {
|
|
40107
|
+
dimColor: true,
|
|
40108
|
+
children: pad(domain.registrar ?? "\u2014", TABLE_COLS.registrar)
|
|
40109
|
+
}, undefined, false, undefined, this),
|
|
40110
|
+
!compact && /* @__PURE__ */ jsxDEV2(Text2, {
|
|
40111
|
+
dimColor: true,
|
|
40112
|
+
children: [
|
|
40113
|
+
" ",
|
|
40114
|
+
daysUntil(domain.expires_at)
|
|
40115
|
+
]
|
|
40116
|
+
}, undefined, true, undefined, this)
|
|
40117
|
+
]
|
|
40118
|
+
}, domain.id, true, undefined, this);
|
|
40119
|
+
}),
|
|
40120
|
+
start + visible.length < domains.length && /* @__PURE__ */ jsxDEV2(Text2, {
|
|
40121
|
+
dimColor: true,
|
|
40122
|
+
children: [
|
|
40123
|
+
" \u2193 ",
|
|
40124
|
+
domains.length - start - visible.length,
|
|
40125
|
+
" more below"
|
|
40126
|
+
]
|
|
40127
|
+
}, undefined, true, undefined, this)
|
|
40128
|
+
]
|
|
40129
|
+
}, undefined, true, undefined, this);
|
|
40130
|
+
}
|
|
40131
|
+
|
|
40132
|
+
// src/cli/tui/DomainDetail.tsx
|
|
40133
|
+
import { Box as Box3, Text as Text3 } from "ink";
|
|
40134
|
+
import { jsxDEV as jsxDEV3, Fragment } from "react/jsx-dev-runtime";
|
|
40135
|
+
function DomainDetail({ details, dnsRecords = [], compact = false }) {
|
|
40136
|
+
const { domain, offers, emails } = details;
|
|
40137
|
+
const statusColor = STATUS_COLORS[domain.status] ?? "white";
|
|
40138
|
+
return /* @__PURE__ */ jsxDEV3(Box3, {
|
|
40139
|
+
flexDirection: "column",
|
|
40140
|
+
width: compact ? "45%" : "100%",
|
|
40141
|
+
paddingLeft: compact ? 1 : 0,
|
|
40142
|
+
children: [
|
|
40143
|
+
!compact && /* @__PURE__ */ jsxDEV3(Box3, {
|
|
40144
|
+
marginBottom: 1,
|
|
40145
|
+
children: /* @__PURE__ */ jsxDEV3(Text3, {
|
|
40146
|
+
dimColor: true,
|
|
40147
|
+
children: "[esc] back \xB7 [r] refresh \xB7 q quit"
|
|
40148
|
+
}, undefined, false, undefined, this)
|
|
40149
|
+
}, undefined, false, undefined, this),
|
|
40150
|
+
/* @__PURE__ */ jsxDEV3(Box3, {
|
|
40151
|
+
flexDirection: "column",
|
|
40152
|
+
marginBottom: 1,
|
|
40153
|
+
children: [
|
|
40154
|
+
/* @__PURE__ */ jsxDEV3(Text3, {
|
|
40155
|
+
bold: true,
|
|
40156
|
+
color: "cyan",
|
|
40157
|
+
children: domain.name
|
|
40158
|
+
}, undefined, false, undefined, this),
|
|
40159
|
+
/* @__PURE__ */ jsxDEV3(Text3, {
|
|
40160
|
+
color: statusColor,
|
|
40161
|
+
children: [
|
|
40162
|
+
"[",
|
|
40163
|
+
domain.status,
|
|
40164
|
+
"]"
|
|
40165
|
+
]
|
|
40166
|
+
}, undefined, true, undefined, this)
|
|
40167
|
+
]
|
|
40168
|
+
}, undefined, true, undefined, this),
|
|
40169
|
+
/* @__PURE__ */ jsxDEV3(Field, {
|
|
40170
|
+
label: "Registrar",
|
|
40171
|
+
value: domain.registrar
|
|
40172
|
+
}, undefined, false, undefined, this),
|
|
40173
|
+
/* @__PURE__ */ jsxDEV3(Field, {
|
|
40174
|
+
label: "Registered",
|
|
40175
|
+
value: formatDate(domain.registered_at)
|
|
40176
|
+
}, undefined, false, undefined, this),
|
|
40177
|
+
/* @__PURE__ */ jsxDEV3(Field, {
|
|
40178
|
+
label: "Expires",
|
|
40179
|
+
value: formatDate(domain.expires_at)
|
|
40180
|
+
}, undefined, false, undefined, this),
|
|
40181
|
+
/* @__PURE__ */ jsxDEV3(Field, {
|
|
40182
|
+
label: "Auto-renew",
|
|
40183
|
+
value: domain.auto_renew ? "yes" : "no"
|
|
40184
|
+
}, undefined, false, undefined, this),
|
|
40185
|
+
domain.is_premium && /* @__PURE__ */ jsxDEV3(Fragment, {
|
|
40186
|
+
children: [
|
|
40187
|
+
/* @__PURE__ */ jsxDEV3(Field, {
|
|
40188
|
+
label: "Premium",
|
|
40189
|
+
value: "yes"
|
|
40190
|
+
}, undefined, false, undefined, this),
|
|
40191
|
+
/* @__PURE__ */ jsxDEV3(Field, {
|
|
40192
|
+
label: "Premium ask",
|
|
40193
|
+
value: domain.premium_price?.toString() ?? "\u2014"
|
|
40194
|
+
}, undefined, false, undefined, this)
|
|
40195
|
+
]
|
|
40196
|
+
}, undefined, true, undefined, this),
|
|
40197
|
+
domain.purchase_price !== null && /* @__PURE__ */ jsxDEV3(Field, {
|
|
40198
|
+
label: "Purchase price",
|
|
40199
|
+
value: String(domain.purchase_price)
|
|
40200
|
+
}, undefined, false, undefined, this),
|
|
40201
|
+
/* @__PURE__ */ jsxDEV3(Field, {
|
|
40202
|
+
label: "SSL issuer",
|
|
40203
|
+
value: domain.ssl_issuer
|
|
40204
|
+
}, undefined, false, undefined, this),
|
|
40205
|
+
/* @__PURE__ */ jsxDEV3(Field, {
|
|
40206
|
+
label: "SSL expires",
|
|
40207
|
+
value: formatDate(domain.ssl_expires_at)
|
|
40208
|
+
}, undefined, false, undefined, this),
|
|
40209
|
+
domain.nameservers.length > 0 && /* @__PURE__ */ jsxDEV3(Box3, {
|
|
40210
|
+
flexDirection: "column",
|
|
40211
|
+
marginTop: 1,
|
|
40212
|
+
children: [
|
|
40213
|
+
/* @__PURE__ */ jsxDEV3(Text3, {
|
|
40214
|
+
bold: true,
|
|
40215
|
+
dimColor: true,
|
|
40216
|
+
children: "Nameservers"
|
|
40217
|
+
}, undefined, false, undefined, this),
|
|
40218
|
+
domain.nameservers.slice(0, compact ? 3 : 8).map((ns) => /* @__PURE__ */ jsxDEV3(Text3, {
|
|
40219
|
+
dimColor: true,
|
|
40220
|
+
children: [
|
|
40221
|
+
" ",
|
|
40222
|
+
ns
|
|
40223
|
+
]
|
|
40224
|
+
}, ns, true, undefined, this))
|
|
40225
|
+
]
|
|
40226
|
+
}, undefined, true, undefined, this),
|
|
40227
|
+
!compact && dnsRecords.length > 0 && /* @__PURE__ */ jsxDEV3(Box3, {
|
|
40228
|
+
flexDirection: "column",
|
|
40229
|
+
marginTop: 1,
|
|
40230
|
+
children: [
|
|
40231
|
+
/* @__PURE__ */ jsxDEV3(Text3, {
|
|
40232
|
+
bold: true,
|
|
40233
|
+
children: [
|
|
40234
|
+
"DNS records (",
|
|
40235
|
+
dnsRecords.length,
|
|
40236
|
+
")"
|
|
40237
|
+
]
|
|
40238
|
+
}, undefined, true, undefined, this),
|
|
40239
|
+
dnsRecords.slice(0, 8).map((record) => /* @__PURE__ */ jsxDEV3(Text3, {
|
|
40240
|
+
dimColor: true,
|
|
40241
|
+
children: [
|
|
40242
|
+
" ",
|
|
40243
|
+
record.type,
|
|
40244
|
+
" ",
|
|
40245
|
+
record.name,
|
|
40246
|
+
" \u2192 ",
|
|
40247
|
+
record.value
|
|
40248
|
+
]
|
|
40249
|
+
}, record.id, true, undefined, this)),
|
|
40250
|
+
dnsRecords.length > 8 && /* @__PURE__ */ jsxDEV3(Text3, {
|
|
40251
|
+
dimColor: true,
|
|
40252
|
+
children: [
|
|
40253
|
+
" \u2026 ",
|
|
40254
|
+
dnsRecords.length - 8,
|
|
40255
|
+
" more"
|
|
40256
|
+
]
|
|
40257
|
+
}, undefined, true, undefined, this)
|
|
40258
|
+
]
|
|
40259
|
+
}, undefined, true, undefined, this),
|
|
40260
|
+
(offers.length > 0 || emails.length > 0) && /* @__PURE__ */ jsxDEV3(Box3, {
|
|
40261
|
+
marginTop: 1,
|
|
40262
|
+
children: /* @__PURE__ */ jsxDEV3(Text3, {
|
|
40263
|
+
dimColor: true,
|
|
40264
|
+
children: [
|
|
40265
|
+
"Offers: ",
|
|
40266
|
+
offers.length,
|
|
40267
|
+
" \xB7 Linked emails: ",
|
|
40268
|
+
emails.length,
|
|
40269
|
+
dnsRecords.length > 0 ? ` \xB7 DNS: ${dnsRecords.length}` : ""
|
|
40270
|
+
]
|
|
40271
|
+
}, undefined, true, undefined, this)
|
|
40272
|
+
}, undefined, false, undefined, this),
|
|
40273
|
+
domain.notes && !compact && /* @__PURE__ */ jsxDEV3(Box3, {
|
|
40274
|
+
flexDirection: "column",
|
|
40275
|
+
marginTop: 1,
|
|
40276
|
+
children: [
|
|
40277
|
+
/* @__PURE__ */ jsxDEV3(Text3, {
|
|
40278
|
+
bold: true,
|
|
40279
|
+
dimColor: true,
|
|
40280
|
+
children: "Notes"
|
|
40281
|
+
}, undefined, false, undefined, this),
|
|
40282
|
+
/* @__PURE__ */ jsxDEV3(Text3, {
|
|
40283
|
+
wrap: "wrap",
|
|
40284
|
+
children: domain.notes
|
|
40285
|
+
}, undefined, false, undefined, this)
|
|
40286
|
+
]
|
|
40287
|
+
}, undefined, true, undefined, this),
|
|
40288
|
+
!compact && /* @__PURE__ */ jsxDEV3(Box3, {
|
|
40289
|
+
marginTop: 1,
|
|
40290
|
+
children: /* @__PURE__ */ jsxDEV3(Text3, {
|
|
40291
|
+
dimColor: true,
|
|
40292
|
+
children: [
|
|
40293
|
+
"ID: ",
|
|
40294
|
+
domain.id
|
|
40295
|
+
]
|
|
40296
|
+
}, undefined, true, undefined, this)
|
|
40297
|
+
}, undefined, false, undefined, this)
|
|
40298
|
+
]
|
|
40299
|
+
}, undefined, true, undefined, this);
|
|
40300
|
+
}
|
|
40301
|
+
function Field({ label, value }) {
|
|
40302
|
+
if (!value || value === "\u2014") {
|
|
40303
|
+
return /* @__PURE__ */ jsxDEV3(Box3, {
|
|
40304
|
+
children: [
|
|
40305
|
+
/* @__PURE__ */ jsxDEV3(Text3, {
|
|
40306
|
+
dimColor: true,
|
|
40307
|
+
children: label.padEnd(14)
|
|
40308
|
+
}, undefined, false, undefined, this),
|
|
40309
|
+
/* @__PURE__ */ jsxDEV3(Text3, {
|
|
40310
|
+
dimColor: true,
|
|
40311
|
+
children: "\u2014"
|
|
40312
|
+
}, undefined, false, undefined, this)
|
|
40313
|
+
]
|
|
40314
|
+
}, undefined, true, undefined, this);
|
|
40315
|
+
}
|
|
40316
|
+
return /* @__PURE__ */ jsxDEV3(Box3, {
|
|
40317
|
+
children: [
|
|
40318
|
+
/* @__PURE__ */ jsxDEV3(Text3, {
|
|
40319
|
+
dimColor: true,
|
|
40320
|
+
children: label.padEnd(14)
|
|
40321
|
+
}, undefined, false, undefined, this),
|
|
40322
|
+
/* @__PURE__ */ jsxDEV3(Text3, {
|
|
40323
|
+
children: value
|
|
40324
|
+
}, undefined, false, undefined, this)
|
|
40325
|
+
]
|
|
40326
|
+
}, undefined, true, undefined, this);
|
|
40327
|
+
}
|
|
40328
|
+
|
|
40329
|
+
// src/cli/tui/SearchView.tsx
|
|
40330
|
+
import { useState } from "react";
|
|
40331
|
+
import { Box as Box4, Text as Text4, useInput } from "ink";
|
|
40332
|
+
import TextInput from "ink-text-input";
|
|
40333
|
+
import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
|
|
40334
|
+
function SearchView({
|
|
40335
|
+
results,
|
|
40336
|
+
selectedIndex,
|
|
40337
|
+
onSearch,
|
|
40338
|
+
onSelect,
|
|
40339
|
+
onBack
|
|
40340
|
+
}) {
|
|
40341
|
+
const [query, setQuery] = useState("");
|
|
40342
|
+
useInput((input, key) => {
|
|
40343
|
+
if (key.escape)
|
|
40344
|
+
onBack();
|
|
40345
|
+
if (key.return && results[selectedIndex]) {
|
|
40346
|
+
onSelect(results[selectedIndex]);
|
|
40347
|
+
}
|
|
40348
|
+
});
|
|
40349
|
+
return /* @__PURE__ */ jsxDEV4(Box4, {
|
|
40350
|
+
flexDirection: "column",
|
|
40351
|
+
children: [
|
|
40352
|
+
/* @__PURE__ */ jsxDEV4(Box4, {
|
|
40353
|
+
marginBottom: 1,
|
|
40354
|
+
children: /* @__PURE__ */ jsxDEV4(Text4, {
|
|
40355
|
+
bold: true,
|
|
40356
|
+
children: "Search domains"
|
|
40357
|
+
}, undefined, false, undefined, this)
|
|
40358
|
+
}, undefined, false, undefined, this),
|
|
40359
|
+
/* @__PURE__ */ jsxDEV4(Box4, {
|
|
40360
|
+
marginBottom: 1,
|
|
40361
|
+
children: [
|
|
40362
|
+
/* @__PURE__ */ jsxDEV4(Text4, {
|
|
40363
|
+
dimColor: true,
|
|
40364
|
+
children: "Query: "
|
|
40365
|
+
}, undefined, false, undefined, this),
|
|
40366
|
+
/* @__PURE__ */ jsxDEV4(TextInput, {
|
|
40367
|
+
value: query,
|
|
40368
|
+
onChange: (value) => {
|
|
40369
|
+
setQuery(value);
|
|
40370
|
+
onSearch(value);
|
|
40371
|
+
},
|
|
40372
|
+
placeholder: "name, registrar, notes\u2026"
|
|
40373
|
+
}, undefined, false, undefined, this)
|
|
40374
|
+
]
|
|
40375
|
+
}, undefined, true, undefined, this),
|
|
40376
|
+
/* @__PURE__ */ jsxDEV4(Text4, {
|
|
40377
|
+
dimColor: true,
|
|
40378
|
+
children: "[enter] open \xB7 [esc] back"
|
|
40379
|
+
}, undefined, false, undefined, this),
|
|
40380
|
+
/* @__PURE__ */ jsxDEV4(Box4, {
|
|
40381
|
+
marginTop: 1,
|
|
40382
|
+
children: /* @__PURE__ */ jsxDEV4(DomainTable, {
|
|
40383
|
+
domains: results,
|
|
40384
|
+
selectedIndex
|
|
40385
|
+
}, undefined, false, undefined, this)
|
|
40386
|
+
}, undefined, false, undefined, this)
|
|
40387
|
+
]
|
|
40388
|
+
}, undefined, true, undefined, this);
|
|
40389
|
+
}
|
|
40390
|
+
|
|
40391
|
+
// src/cli/tui/App.tsx
|
|
40392
|
+
import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
|
|
40393
|
+
function loadDomainsForFilter(activeFilter) {
|
|
40394
|
+
switch (activeFilter) {
|
|
40395
|
+
case "active":
|
|
40396
|
+
return listDomains({ status: "active" });
|
|
40397
|
+
case "premium":
|
|
40398
|
+
return listDomains({ is_premium: true });
|
|
40399
|
+
case "expiring":
|
|
40400
|
+
return listExpiring(30);
|
|
40401
|
+
default:
|
|
40402
|
+
return listDomains();
|
|
40403
|
+
}
|
|
40404
|
+
}
|
|
40405
|
+
function App({ initialStatus }) {
|
|
40406
|
+
const { exit } = useApp();
|
|
40407
|
+
const [view, setView] = useState2("list");
|
|
40408
|
+
const initialFilter = initialStatus === "active" ? "active" : initialStatus === "premium" ? "premium" : "all";
|
|
40409
|
+
const [filter, setFilter] = useState2(initialFilter);
|
|
40410
|
+
const [selectedIndex, setSelectedIndex] = useState2(0);
|
|
40411
|
+
const [details, setDetails] = useState2(null);
|
|
40412
|
+
const [searchResults, setSearchResults] = useState2([]);
|
|
40413
|
+
const [searchIndex, setSearchIndex] = useState2(0);
|
|
40414
|
+
const [domains, setDomains] = useState2(() => loadDomainsForFilter(initialFilter));
|
|
40415
|
+
const refresh = useCallback(() => {
|
|
40416
|
+
const next = loadDomainsForFilter(filter);
|
|
40417
|
+
setDomains(next);
|
|
40418
|
+
setSelectedIndex((current) => Math.min(current, Math.max(0, next.length - 1)));
|
|
40419
|
+
return next;
|
|
40420
|
+
}, [filter]);
|
|
40421
|
+
useEffect(() => {
|
|
40422
|
+
refresh();
|
|
40423
|
+
}, [refresh]);
|
|
40424
|
+
const selectedDomain = domains[selectedIndex] ?? null;
|
|
40425
|
+
const previewDetails = useMemo(() => {
|
|
40426
|
+
if (!selectedDomain)
|
|
40427
|
+
return null;
|
|
40428
|
+
return getDomainDetails(selectedDomain.id);
|
|
40429
|
+
}, [selectedDomain]);
|
|
40430
|
+
const previewDns = useMemo(() => {
|
|
40431
|
+
if (!selectedDomain)
|
|
40432
|
+
return [];
|
|
40433
|
+
return listDnsRecords(selectedDomain.id);
|
|
40434
|
+
}, [selectedDomain]);
|
|
40435
|
+
useInput2((input, key) => {
|
|
40436
|
+
if (input === "q" && view !== "search") {
|
|
40437
|
+
exit();
|
|
40438
|
+
return;
|
|
40439
|
+
}
|
|
40440
|
+
if (view === "list") {
|
|
40441
|
+
if (key.upArrow || input === "k") {
|
|
40442
|
+
setSelectedIndex((index) => Math.max(0, index - 1));
|
|
40443
|
+
} else if (key.downArrow || input === "j") {
|
|
40444
|
+
setSelectedIndex((index) => Math.min(domains.length - 1, index + 1));
|
|
40445
|
+
} else if (key.return && selectedDomain) {
|
|
40446
|
+
const full = getDomainDetails(selectedDomain.id);
|
|
40447
|
+
if (full) {
|
|
40448
|
+
setDetails(full);
|
|
40449
|
+
setView("detail");
|
|
40450
|
+
}
|
|
40451
|
+
} else if (input === "/") {
|
|
40452
|
+
setSearchResults([]);
|
|
40453
|
+
setSearchIndex(0);
|
|
40454
|
+
setView("search");
|
|
40455
|
+
} else if (input === "f") {
|
|
40456
|
+
setFilter((current) => {
|
|
40457
|
+
const index = DOMAIN_FILTERS.indexOf(current);
|
|
40458
|
+
return DOMAIN_FILTERS[(index + 1) % DOMAIN_FILTERS.length];
|
|
40459
|
+
});
|
|
40460
|
+
} else if (input === "r") {
|
|
40461
|
+
refresh();
|
|
40462
|
+
}
|
|
40463
|
+
return;
|
|
40464
|
+
}
|
|
40465
|
+
if (view === "search") {
|
|
40466
|
+
if (key.upArrow || input === "k") {
|
|
40467
|
+
setSearchIndex((index) => Math.max(0, index - 1));
|
|
40468
|
+
} else if (key.downArrow || input === "j") {
|
|
40469
|
+
setSearchIndex((index) => Math.min(searchResults.length - 1, index + 1));
|
|
40470
|
+
}
|
|
40471
|
+
return;
|
|
40472
|
+
}
|
|
40473
|
+
if (view === "detail") {
|
|
40474
|
+
if (key.escape) {
|
|
40475
|
+
setView("list");
|
|
40476
|
+
refresh();
|
|
40477
|
+
} else if (input === "r" && details) {
|
|
40478
|
+
setDetails(getDomainDetails(details.domain.id));
|
|
40479
|
+
}
|
|
40480
|
+
}
|
|
40481
|
+
});
|
|
40482
|
+
const handleSearch = useCallback((query) => {
|
|
40483
|
+
const trimmed = query.trim();
|
|
40484
|
+
if (trimmed.length < 2) {
|
|
40485
|
+
setSearchResults([]);
|
|
40486
|
+
setSearchIndex(0);
|
|
40487
|
+
return;
|
|
40488
|
+
}
|
|
40489
|
+
const results = searchDomains(trimmed);
|
|
40490
|
+
setSearchResults(results);
|
|
40491
|
+
setSearchIndex(0);
|
|
40492
|
+
}, []);
|
|
40493
|
+
const handleSearchSelect = useCallback((domain) => {
|
|
40494
|
+
const full = getDomainDetails(domain.id);
|
|
40495
|
+
if (full) {
|
|
40496
|
+
setDetails(full);
|
|
40497
|
+
setView("detail");
|
|
40498
|
+
}
|
|
40499
|
+
}, []);
|
|
40500
|
+
const detailDns = details ? listDnsRecords(details.domain.id) : [];
|
|
40501
|
+
return /* @__PURE__ */ jsxDEV5(Box5, {
|
|
40502
|
+
flexDirection: "column",
|
|
40503
|
+
padding: 1,
|
|
40504
|
+
children: [
|
|
40505
|
+
/* @__PURE__ */ jsxDEV5(Header, {
|
|
40506
|
+
count: view === "search" ? searchResults.length : domains.length,
|
|
40507
|
+
filter,
|
|
40508
|
+
view
|
|
40509
|
+
}, undefined, false, undefined, this),
|
|
40510
|
+
view === "list" && /* @__PURE__ */ jsxDEV5(Box5, {
|
|
40511
|
+
flexDirection: "column",
|
|
40512
|
+
children: [
|
|
40513
|
+
/* @__PURE__ */ jsxDEV5(DomainTable, {
|
|
40514
|
+
domains,
|
|
40515
|
+
selectedIndex
|
|
40516
|
+
}, undefined, false, undefined, this),
|
|
40517
|
+
previewDetails && /* @__PURE__ */ jsxDEV5(Box5, {
|
|
40518
|
+
marginTop: 1,
|
|
40519
|
+
flexDirection: "column",
|
|
40520
|
+
children: [
|
|
40521
|
+
/* @__PURE__ */ jsxDEV5(Text5, {
|
|
40522
|
+
bold: true,
|
|
40523
|
+
dimColor: true,
|
|
40524
|
+
children: "Selected"
|
|
40525
|
+
}, undefined, false, undefined, this),
|
|
40526
|
+
/* @__PURE__ */ jsxDEV5(DomainDetail, {
|
|
40527
|
+
details: previewDetails,
|
|
40528
|
+
dnsRecords: previewDns,
|
|
40529
|
+
compact: true
|
|
40530
|
+
}, undefined, false, undefined, this)
|
|
40531
|
+
]
|
|
40532
|
+
}, undefined, true, undefined, this),
|
|
40533
|
+
/* @__PURE__ */ jsxDEV5(Box5, {
|
|
40534
|
+
marginTop: 1,
|
|
40535
|
+
children: /* @__PURE__ */ jsxDEV5(Text5, {
|
|
40536
|
+
dimColor: true,
|
|
40537
|
+
children: "\u2191\u2193 j/k navigate \xB7 enter detail \xB7 / search \xB7 f filter \xB7 r refresh \xB7 q quit"
|
|
40538
|
+
}, undefined, false, undefined, this)
|
|
40539
|
+
}, undefined, false, undefined, this)
|
|
40540
|
+
]
|
|
40541
|
+
}, undefined, true, undefined, this),
|
|
40542
|
+
view === "detail" && details && /* @__PURE__ */ jsxDEV5(DomainDetail, {
|
|
40543
|
+
details,
|
|
40544
|
+
dnsRecords: detailDns
|
|
40545
|
+
}, undefined, false, undefined, this),
|
|
40546
|
+
view === "search" && /* @__PURE__ */ jsxDEV5(SearchView, {
|
|
40547
|
+
results: searchResults,
|
|
40548
|
+
selectedIndex: searchIndex,
|
|
40549
|
+
onSearch: handleSearch,
|
|
40550
|
+
onSelect: handleSearchSelect,
|
|
40551
|
+
onBack: () => setView("list")
|
|
40552
|
+
}, undefined, false, undefined, this)
|
|
40553
|
+
]
|
|
40554
|
+
}, undefined, true, undefined, this);
|
|
40555
|
+
}
|
|
40556
|
+
|
|
40557
|
+
// src/cli/commands/interactive.tsx
|
|
40558
|
+
import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
|
|
40559
|
+
function registerInteractiveCommand(program2) {
|
|
40560
|
+
program2.command("interactive").description("Launch interactive domain portfolio browser (Ink TUI)").option("--status <status>", "Initial filter status (e.g. active, premium)").action((opts) => {
|
|
40561
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
40562
|
+
console.error(chalk.red("Interactive mode requires a TTY terminal."));
|
|
40563
|
+
console.error(chalk.dim("Use `domains domain list` or `domains domain get <name>` for non-interactive use."));
|
|
40564
|
+
process.exit(1);
|
|
40565
|
+
}
|
|
40566
|
+
render(/* @__PURE__ */ jsxDEV6(App, {
|
|
40567
|
+
initialStatus: opts.status
|
|
40568
|
+
}, undefined, false, undefined, this));
|
|
40569
|
+
});
|
|
40570
|
+
}
|
|
40571
|
+
|
|
39947
40572
|
// src/cli/index.ts
|
|
39948
40573
|
init_version();
|
|
39949
40574
|
var program2 = new Command;
|
|
@@ -39968,4 +40593,5 @@ registerOutreachCommand(program2);
|
|
|
39968
40593
|
registerSedoCommand(program2);
|
|
39969
40594
|
registerWalletCommand(program2);
|
|
39970
40595
|
registerProvisionCommand(program2);
|
|
40596
|
+
registerInteractiveCommand(program2);
|
|
39971
40597
|
program2.parse(process.argv);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../../src/cli/tui/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoD,MAAM,OAAO,CAAC;AAmBzE,MAAM,WAAW,QAAQ;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAeD,wBAAgB,GAAG,CAAC,EAAE,aAAa,EAAE,EAAE,QAAQ,qBAqJ9C"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { DomainDetails } from "../../db/domains.js";
|
|
3
|
+
import type { DnsRecord } from "../../db/dns-records.js";
|
|
4
|
+
interface DomainDetailProps {
|
|
5
|
+
details: DomainDetails;
|
|
6
|
+
dnsRecords?: DnsRecord[];
|
|
7
|
+
compact?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function DomainDetail({ details, dnsRecords, compact }: DomainDetailProps): React.JSX.Element;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=DomainDetail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DomainDetail.d.ts","sourceRoot":"","sources":["../../../src/cli/tui/DomainDetail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGzD,UAAU,iBAAiB;IACzB,OAAO,EAAE,aAAa,CAAC;IACvB,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,UAAe,EAAE,OAAe,EAAE,EAAE,iBAAiB,qBAqF5F"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { Domain } from "../../db/domains.js";
|
|
3
|
+
interface DomainTableProps {
|
|
4
|
+
domains: Domain[];
|
|
5
|
+
selectedIndex: number;
|
|
6
|
+
compact?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function DomainTable({ domains, selectedIndex, compact }: DomainTableProps): React.JSX.Element;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=DomainTable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DomainTable.d.ts","sourceRoot":"","sources":["../../../src/cli/tui/DomainTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAWlD,UAAU,gBAAgB;IACxB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,OAAe,EAAE,EAAE,gBAAgB,qBA2DxF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { DomainFilter } from "./format.js";
|
|
3
|
+
interface HeaderProps {
|
|
4
|
+
count: number;
|
|
5
|
+
filter: DomainFilter;
|
|
6
|
+
view: "list" | "detail" | "search";
|
|
7
|
+
}
|
|
8
|
+
export declare function Header({ count, filter, view }: HeaderProps): React.JSX.Element;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=Header.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Header.d.ts","sourceRoot":"","sources":["../../../src/cli/tui/Header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,UAAU,WAAW;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;CACpC;AAED,wBAAgB,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,WAAW,qBAmB1D"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { Domain } from "../../db/domains.js";
|
|
3
|
+
interface SearchViewProps {
|
|
4
|
+
results: Domain[];
|
|
5
|
+
selectedIndex: number;
|
|
6
|
+
onSearch: (query: string) => void;
|
|
7
|
+
onSelect: (domain: Domain) => void;
|
|
8
|
+
onBack: () => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function SearchView({ results, selectedIndex, onSearch, onSelect, onBack, }: SearchViewProps): React.JSX.Element;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=SearchView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchView.d.ts","sourceRoot":"","sources":["../../../src/cli/tui/SearchView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGlD,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,MAAM,GACP,EAAE,eAAe,qBAgCjB"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Domain, DomainStatus } from "../../db/domains.js";
|
|
2
|
+
export declare const TABLE_COLS: {
|
|
3
|
+
readonly name: 28;
|
|
4
|
+
readonly status: 14;
|
|
5
|
+
readonly expires: 12;
|
|
6
|
+
readonly registrar: 16;
|
|
7
|
+
};
|
|
8
|
+
export declare function pad(value: string, width: number): string;
|
|
9
|
+
export declare function formatDate(iso: string | null | undefined): string;
|
|
10
|
+
export declare function daysUntil(iso: string | null | undefined): string;
|
|
11
|
+
export declare const STATUS_COLORS: Record<DomainStatus, string>;
|
|
12
|
+
export declare function domainRowLabel(domain: Domain): string;
|
|
13
|
+
export declare function stripAnsi(value: string | undefined): string;
|
|
14
|
+
export type DomainFilter = "all" | "active" | "expiring" | "premium";
|
|
15
|
+
export declare const DOMAIN_FILTERS: DomainFilter[];
|
|
16
|
+
export declare function filterLabel(filter: DomainFilter): string;
|
|
17
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/cli/tui/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEhE,eAAO,MAAM,UAAU;;;;;CAKb,CAAC;AAEX,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGxD;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAGjE;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAOhE;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAatD,CAAC;AAEF,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAE3D;AAED,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAErE,eAAO,MAAM,cAAc,EAAE,YAAY,EAA6C,CAAC;AAEvF,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAWxD"}
|
package/dist/index.js
CHANGED
|
@@ -4,43 +4,25 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
function __accessProp(key) {
|
|
8
|
-
return this[key];
|
|
9
|
-
}
|
|
10
|
-
var __toESMCache_node;
|
|
11
|
-
var __toESMCache_esm;
|
|
12
7
|
var __toESM = (mod, isNodeMode, target) => {
|
|
13
|
-
var canCache = mod != null && typeof mod === "object";
|
|
14
|
-
if (canCache) {
|
|
15
|
-
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
16
|
-
var cached = cache.get(mod);
|
|
17
|
-
if (cached)
|
|
18
|
-
return cached;
|
|
19
|
-
}
|
|
20
8
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
21
9
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
22
10
|
for (let key of __getOwnPropNames(mod))
|
|
23
11
|
if (!__hasOwnProp.call(to, key))
|
|
24
12
|
__defProp(to, key, {
|
|
25
|
-
get:
|
|
13
|
+
get: () => mod[key],
|
|
26
14
|
enumerable: true
|
|
27
15
|
});
|
|
28
|
-
if (canCache)
|
|
29
|
-
cache.set(mod, to);
|
|
30
16
|
return to;
|
|
31
17
|
};
|
|
32
18
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
33
|
-
var __returnValue = (v) => v;
|
|
34
|
-
function __exportSetter(name, newValue) {
|
|
35
|
-
this[name] = __returnValue.bind(null, newValue);
|
|
36
|
-
}
|
|
37
19
|
var __export = (target, all) => {
|
|
38
20
|
for (var name in all)
|
|
39
21
|
__defProp(target, name, {
|
|
40
22
|
get: all[name],
|
|
41
23
|
enumerable: true,
|
|
42
24
|
configurable: true,
|
|
43
|
-
set:
|
|
25
|
+
set: (newValue) => all[name] = () => newValue
|
|
44
26
|
});
|
|
45
27
|
};
|
|
46
28
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
@@ -15823,7 +15805,7 @@ var require_package = __commonJS((exports, module) => {
|
|
|
15823
15805
|
|
|
15824
15806
|
// node_modules/@aws-sdk/util-user-agent-node/dist-cjs/index.js
|
|
15825
15807
|
var require_dist_cjs41 = __commonJS((exports) => {
|
|
15826
|
-
var __dirname = "/
|
|
15808
|
+
var __dirname = "/Users/hasna/Workspace/hasna/opensource/open-domains/node_modules/@aws-sdk/util-user-agent-node/dist-cjs";
|
|
15827
15809
|
var node_os = __require("os");
|
|
15828
15810
|
var node_process = __require("process");
|
|
15829
15811
|
var utilConfigProvider = require_dist_cjs33();
|
package/dist/mcp/index.js
CHANGED
|
@@ -5,43 +5,25 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
function __accessProp(key) {
|
|
9
|
-
return this[key];
|
|
10
|
-
}
|
|
11
|
-
var __toESMCache_node;
|
|
12
|
-
var __toESMCache_esm;
|
|
13
8
|
var __toESM = (mod, isNodeMode, target) => {
|
|
14
|
-
var canCache = mod != null && typeof mod === "object";
|
|
15
|
-
if (canCache) {
|
|
16
|
-
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
17
|
-
var cached = cache.get(mod);
|
|
18
|
-
if (cached)
|
|
19
|
-
return cached;
|
|
20
|
-
}
|
|
21
9
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
22
10
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
23
11
|
for (let key of __getOwnPropNames(mod))
|
|
24
12
|
if (!__hasOwnProp.call(to, key))
|
|
25
13
|
__defProp(to, key, {
|
|
26
|
-
get:
|
|
14
|
+
get: () => mod[key],
|
|
27
15
|
enumerable: true
|
|
28
16
|
});
|
|
29
|
-
if (canCache)
|
|
30
|
-
cache.set(mod, to);
|
|
31
17
|
return to;
|
|
32
18
|
};
|
|
33
19
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
34
|
-
var __returnValue = (v) => v;
|
|
35
|
-
function __exportSetter(name, newValue) {
|
|
36
|
-
this[name] = __returnValue.bind(null, newValue);
|
|
37
|
-
}
|
|
38
20
|
var __export = (target, all) => {
|
|
39
21
|
for (var name in all)
|
|
40
22
|
__defProp(target, name, {
|
|
41
23
|
get: all[name],
|
|
42
24
|
enumerable: true,
|
|
43
25
|
configurable: true,
|
|
44
|
-
set:
|
|
26
|
+
set: (newValue) => all[name] = () => newValue
|
|
45
27
|
});
|
|
46
28
|
};
|
|
47
29
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
@@ -16073,7 +16055,7 @@ var require_package = __commonJS((exports, module) => {
|
|
|
16073
16055
|
|
|
16074
16056
|
// node_modules/@aws-sdk/util-user-agent-node/dist-cjs/index.js
|
|
16075
16057
|
var require_dist_cjs41 = __commonJS((exports) => {
|
|
16076
|
-
var __dirname = "/
|
|
16058
|
+
var __dirname = "/Users/hasna/Workspace/hasna/opensource/open-domains/node_modules/@aws-sdk/util-user-agent-node/dist-cjs";
|
|
16077
16059
|
var node_os = __require("os");
|
|
16078
16060
|
var node_process = __require("process");
|
|
16079
16061
|
var utilConfigProvider = require_dist_cjs33();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/domains",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.16",
|
|
4
4
|
"description": "Domain portfolio and DNS management for AI agents — CLI + MCP server with SQLite",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"README.md"
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
|
-
"build": "bun build src/cli/index.ts --outdir dist/cli --target bun --external @modelcontextprotocol/sdk --external @hasna/cloud && bun build src/mcp/index.ts --outdir dist/mcp --target bun --external @modelcontextprotocol/sdk --external @hasna/cloud && bun build src/index.ts --outdir dist --target bun --external @hasna/cloud && tsc --emitDeclarationOnly --outDir dist",
|
|
24
|
+
"build": "bun build src/cli/index.ts --outdir dist/cli --target bun --external ink --external react --external chalk --external ink-text-input --external @modelcontextprotocol/sdk --external @hasna/cloud && bun build src/mcp/index.ts --outdir dist/mcp --target bun --external @modelcontextprotocol/sdk --external @hasna/cloud && bun build src/index.ts --outdir dist --target bun --external @hasna/cloud && tsc --emitDeclarationOnly --outDir dist",
|
|
25
25
|
"typecheck": "tsc --noEmit",
|
|
26
26
|
"test": "bun test",
|
|
27
27
|
"dev:cli": "bun run src/cli/index.ts",
|
|
@@ -65,11 +65,17 @@
|
|
|
65
65
|
"@hasna/contacts": "^0.6.16",
|
|
66
66
|
"@hasna/wallets": "^0.1.7",
|
|
67
67
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
68
|
+
"chalk": "^5.4.1",
|
|
68
69
|
"commander": "^13.1.0",
|
|
70
|
+
"ink": "^5.2.0",
|
|
71
|
+
"ink-text-input": "^6.0.0",
|
|
72
|
+
"react": "^18.3.1",
|
|
69
73
|
"zod": "^3.24.2"
|
|
70
74
|
},
|
|
71
75
|
"devDependencies": {
|
|
72
76
|
"@types/bun": "^1.2.4",
|
|
77
|
+
"@types/react": "^18.3.18",
|
|
78
|
+
"ink-testing-library": "^4.0.0",
|
|
73
79
|
"typescript": "^5.7.3"
|
|
74
80
|
}
|
|
75
81
|
}
|