@4ort/cli 0.3.0 → 0.5.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 +286 -0
- package/dist/commands/kg/agent-context.d.ts +3 -0
- package/dist/commands/kg/agent-context.js +54 -0
- package/dist/commands/kg/agent-context.js.map +1 -0
- package/dist/commands/kg/article-context.d.ts +3 -0
- package/dist/commands/kg/article-context.js +51 -0
- package/dist/commands/kg/article-context.js.map +1 -0
- package/dist/commands/kg/ask.d.ts +5 -0
- package/dist/commands/kg/ask.js +121 -0
- package/dist/commands/kg/ask.js.map +1 -0
- package/dist/commands/kg/auth.d.ts +9 -0
- package/dist/commands/kg/auth.js +95 -0
- package/dist/commands/kg/auth.js.map +1 -0
- package/dist/commands/kg/entity.d.ts +4 -0
- package/dist/commands/kg/entity.js +33 -0
- package/dist/commands/kg/entity.js.map +1 -0
- package/dist/commands/kg/match.d.ts +5 -0
- package/dist/commands/kg/match.js +44 -0
- package/dist/commands/kg/match.js.map +1 -0
- package/dist/commands/kg/popularity.d.ts +3 -0
- package/dist/commands/kg/popularity.js +42 -0
- package/dist/commands/kg/popularity.js.map +1 -0
- package/dist/commands/kg/search.d.ts +4 -0
- package/dist/commands/kg/search.js +34 -0
- package/dist/commands/kg/search.js.map +1 -0
- package/dist/commands/kg/trending.d.ts +6 -0
- package/dist/commands/kg/trending.js +35 -0
- package/dist/commands/kg/trending.js.map +1 -0
- package/dist/commands/mcp.d.ts +5 -0
- package/dist/commands/mcp.js +24 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/run.d.ts +10 -0
- package/dist/commands/run.js +74 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/search.d.ts +7 -0
- package/dist/commands/search.js +105 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/vault.d.ts +7 -0
- package/dist/commands/vault.js +62 -0
- package/dist/commands/vault.js.map +1 -0
- package/dist/commands/web.d.ts +6 -0
- package/dist/commands/web.js +44 -0
- package/dist/commands/web.js.map +1 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.js +80 -1
- package/dist/config.js.map +1 -1
- package/dist/index.js +167 -37
- package/dist/index.js.map +1 -1
- package/dist/kg-client.d.ts +42 -0
- package/dist/kg-client.js +125 -0
- package/dist/kg-client.js.map +1 -0
- package/dist/kg-output.d.ts +33 -0
- package/dist/kg-output.js +132 -0
- package/dist/kg-output.js.map +1 -0
- package/dist/mcp-server.d.ts +5 -0
- package/dist/mcp-server.js +363 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/web-client.d.ts +20 -0
- package/dist/web-client.js +335 -0
- package/dist/web-client.js.map +1 -0
- package/package.json +20 -4
- package/src/api-client.ts +0 -51
- package/src/commands/delete.ts +0 -15
- package/src/commands/list.ts +0 -25
- package/src/commands/mail.ts +0 -79
- package/src/commands/provision.ts +0 -106
- package/src/commands/push.ts +0 -63
- package/src/commands/recover.ts +0 -37
- package/src/commands/register.ts +0 -40
- package/src/commands/whoami.ts +0 -20
- package/src/config.ts +0 -40
- package/src/index.ts +0 -114
- package/tsconfig.json +0 -8
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 4ort kg entity <key>
|
|
3
|
+
*
|
|
4
|
+
* GET /api/v1/entities/{key}?detail=tiny|small|medium|full
|
|
5
|
+
*/
|
|
6
|
+
import { requireKgConfig } from "../../config.js";
|
|
7
|
+
import { kgRequest } from "../../kg-client.js";
|
|
8
|
+
import { printEntity, printJson } from "../../kg-output.js";
|
|
9
|
+
const VALID_DETAIL = ["tiny", "small", "medium", "full"];
|
|
10
|
+
export async function kgEntity(key, options) {
|
|
11
|
+
const cfg = requireKgConfig();
|
|
12
|
+
const detail = options.detail ?? "medium";
|
|
13
|
+
if (!VALID_DETAIL.includes(detail)) {
|
|
14
|
+
console.error(`Invalid --detail. Must be one of: ${VALID_DETAIL.join(", ")}`);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
const data = await kgRequest(cfg, `/api/v1/entities/${encodeURIComponent(key)}`, {
|
|
19
|
+
query: { detail },
|
|
20
|
+
});
|
|
21
|
+
if (options.json) {
|
|
22
|
+
printJson(data);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
printEntity(data);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
console.error(`✗ ${err.message}`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=entity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity.js","sourceRoot":"","sources":["../../../src/commands/kg/entity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE5D,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAU,CAAC;AAElE,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAW,EAAE,OAA4C;IACtF,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC;IAC1C,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAa,CAAC,EAAE,CAAC;QAC1C,OAAO,CAAC,KAAK,CAAC,qCAAqC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,SAAS,CAAM,GAAG,EAAE,oBAAoB,kBAAkB,CAAC,GAAG,CAAC,EAAE,EAAE;YACpF,KAAK,EAAE,EAAE,MAAM,EAAE;SAClB,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,SAAS,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 4ort kg match <text>
|
|
3
|
+
*
|
|
4
|
+
* POST /api/v1/match → ranked entity candidates with confidence scores.
|
|
5
|
+
*/
|
|
6
|
+
import { requireKgConfig } from "../../config.js";
|
|
7
|
+
import { kgRequest } from "../../kg-client.js";
|
|
8
|
+
import { printJson, printTable, truncate } from "../../kg-output.js";
|
|
9
|
+
export async function kgMatch(text, options) {
|
|
10
|
+
const cfg = requireKgConfig();
|
|
11
|
+
const limit = options.limit ? parseInt(options.limit, 10) : 5;
|
|
12
|
+
const entity_types = options.types
|
|
13
|
+
? options.types.split(",").map((t) => t.trim()).filter(Boolean)
|
|
14
|
+
: undefined;
|
|
15
|
+
try {
|
|
16
|
+
const res = await kgRequest(cfg, "/api/v1/match", {
|
|
17
|
+
method: "POST",
|
|
18
|
+
body: { text, entity_types, limit },
|
|
19
|
+
});
|
|
20
|
+
if (options.json) {
|
|
21
|
+
printJson(res);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
console.log(`Match for "${res.query}" (${res.latency_ms}ms)\n`);
|
|
25
|
+
if (res.primary) {
|
|
26
|
+
console.log(`✓ primary: ${res.primary.name}${res.primary.slug ? ` (${res.primary.slug})` : ""} conf=${res.primary.confidence.toFixed(2)}\n`);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
console.log("(no primary match — confidence below 0.7 threshold)\n");
|
|
30
|
+
}
|
|
31
|
+
printTable(res.candidates, [
|
|
32
|
+
["NAME", (r) => r.name],
|
|
33
|
+
["SLUG", (r) => r.slug || ""],
|
|
34
|
+
["TYPE", (r) => r.type || ""],
|
|
35
|
+
["SUMMARY", (r) => truncate(r.summary, 80)],
|
|
36
|
+
["CONF", (r) => r.confidence.toFixed(2)],
|
|
37
|
+
]);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
console.error(`✗ ${err.message}`);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=match.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"match.js","sourceRoot":"","sources":["../../../src/commands/kg/match.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAgBrE,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,IAAY,EACZ,OAA2D;IAE3D,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK;QAChC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QAC/D,CAAC,CAAC,SAAS,CAAC;IAEd,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,SAAS,CAAgB,GAAG,EAAE,eAAe,EAAE;YAC/D,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE;SACpC,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,SAAS,CAAC,GAAG,CAAC,CAAC;YACf,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,CAAC,KAAK,OAAO,GAAG,CAAC,UAAU,OAAO,CAAC,CAAC;QACjE,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAChJ,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;QACvE,CAAC;QACD,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE;YACzB,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACvB,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;YAC7B,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;YAC7B,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAC3C,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;SACzC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 4ort kg popularity <key>
|
|
3
|
+
*
|
|
4
|
+
* GET /api/v1/popularity/{key} — Wikipedia-pageview-derived "real-world
|
|
5
|
+
* search volume" (Ahrefs / SEMrush style metric, but measured + CC0).
|
|
6
|
+
*/
|
|
7
|
+
import { requireKgConfig } from "../../config.js";
|
|
8
|
+
import { kgRequest } from "../../kg-client.js";
|
|
9
|
+
import { fmtFloat, fmtInt, printJson } from "../../kg-output.js";
|
|
10
|
+
export async function kgPopularity(key, options) {
|
|
11
|
+
const cfg = requireKgConfig();
|
|
12
|
+
try {
|
|
13
|
+
const res = await kgRequest(cfg, `/api/v1/popularity/${encodeURIComponent(key)}`);
|
|
14
|
+
if (options.json) {
|
|
15
|
+
printJson(res);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
console.log(`${res.name}${res.slug ? ` (${res.slug})` : ""}`);
|
|
19
|
+
console.log(` monthly volume: ${fmtInt(res.monthly_volume)}`);
|
|
20
|
+
if (res.annual_volume !== undefined)
|
|
21
|
+
console.log(` annual volume: ${fmtInt(res.annual_volume)}`);
|
|
22
|
+
if (res.trailing_12mo_avg !== undefined)
|
|
23
|
+
console.log(` trailing 12mo avg: ${fmtInt(res.trailing_12mo_avg)}`);
|
|
24
|
+
if (res.trend_direction)
|
|
25
|
+
console.log(` trend: ${res.trend_direction}`);
|
|
26
|
+
if (res.yoy_change_pct !== undefined)
|
|
27
|
+
console.log(` YoY change: ${fmtFloat(res.yoy_change_pct, 1)}%`);
|
|
28
|
+
if (res.rank_within_domain !== undefined && res.domain_size !== undefined) {
|
|
29
|
+
console.log(` rank in domain: #${res.rank_within_domain} of ${fmtInt(res.domain_size)}`);
|
|
30
|
+
}
|
|
31
|
+
if (res.trend_12mo.length > 0) {
|
|
32
|
+
console.log(`\n 12-month trend:`);
|
|
33
|
+
for (const p of res.trend_12mo)
|
|
34
|
+
console.log(` ${p.month} ${fmtInt(p.views)}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
console.error(`✗ ${err.message}`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=popularity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"popularity.js","sourceRoot":"","sources":["../../../src/commands/kg/popularity.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAiBjE,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,OAA2B;IACzE,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,SAAS,CACzB,GAAG,EACH,sBAAsB,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAChD,CAAC;QAEF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,SAAS,CAAC,GAAG,CAAC,CAAC;YACf,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,2BAA2B,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QACrE,IAAI,GAAG,CAAC,aAAa,KAAK,SAAS;YAAE,OAAO,CAAC,GAAG,CAAC,2BAA2B,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QACzG,IAAI,GAAG,CAAC,iBAAiB,KAAK,SAAS;YAAE,OAAO,CAAC,GAAG,CAAC,2BAA2B,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACjH,IAAI,GAAG,CAAC,eAAe;YAAE,OAAO,CAAC,GAAG,CAAC,2BAA2B,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC;QACvF,IAAI,GAAG,CAAC,cAAc,KAAK,SAAS;YAAE,OAAO,CAAC,GAAG,CAAC,2BAA2B,QAAQ,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;QACjH,IAAI,GAAG,CAAC,kBAAkB,KAAK,SAAS,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YAC1E,OAAO,CAAC,GAAG,CAAC,4BAA4B,GAAG,CAAC,kBAAkB,OAAO,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAClG,CAAC;QACD,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;YACnC,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,UAAU;gBAAE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 4ort kg search <query>
|
|
3
|
+
*
|
|
4
|
+
* GET /api/v1/search?q=...&limit=...
|
|
5
|
+
*/
|
|
6
|
+
import { requireKgConfig } from "../../config.js";
|
|
7
|
+
import { kgRequest } from "../../kg-client.js";
|
|
8
|
+
import { printJson, printTable, truncate } from "../../kg-output.js";
|
|
9
|
+
export async function kgSearch(query, options) {
|
|
10
|
+
const cfg = requireKgConfig();
|
|
11
|
+
const limit = options.limit ? parseInt(options.limit, 10) : 20;
|
|
12
|
+
try {
|
|
13
|
+
const res = await kgRequest(cfg, "/api/v1/search", {
|
|
14
|
+
query: { q: query, limit },
|
|
15
|
+
});
|
|
16
|
+
if (options.json) {
|
|
17
|
+
printJson(res);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
console.log(`${res.total_returned} results for "${res.query}" (${res.latency_ms}ms)\n`);
|
|
21
|
+
printTable(res.hits, [
|
|
22
|
+
["NAME", (r) => r.name],
|
|
23
|
+
["SLUG", (r) => r.slug || ""],
|
|
24
|
+
["TYPE", (r) => r.type || ""],
|
|
25
|
+
["SUMMARY", (r) => truncate(r.summary, 80)],
|
|
26
|
+
["SCORE", (r) => r.score.toFixed(3)],
|
|
27
|
+
]);
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
console.error(`✗ ${err.message}`);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/commands/kg/search.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAkBrE,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,KAAa,EAAE,OAA2C;IACvF,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,SAAS,CAAiB,GAAG,EAAE,gBAAgB,EAAE;YACjE,KAAK,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE;SAC3B,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,SAAS,CAAC,GAAG,CAAC,CAAC;YACf,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,cAAc,iBAAiB,GAAG,CAAC,KAAK,OAAO,GAAG,CAAC,UAAU,OAAO,CAAC,CAAC;QACzF,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE;YACnB,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACvB,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;YAC7B,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;YAC7B,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAC3C,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;SACrC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 4ort kg trending
|
|
3
|
+
*
|
|
4
|
+
* GET /api/v1/trending — top entities by Wikipedia pageview velocity.
|
|
5
|
+
*/
|
|
6
|
+
import { requireKgConfig } from "../../config.js";
|
|
7
|
+
import { kgRequest } from "../../kg-client.js";
|
|
8
|
+
import { fmtFloat, fmtInt, printJson, printTable } from "../../kg-output.js";
|
|
9
|
+
export async function kgTrending(options) {
|
|
10
|
+
const cfg = requireKgConfig();
|
|
11
|
+
const hours = options.hours ? parseInt(options.hours, 10) : 1;
|
|
12
|
+
const limit = options.limit ? parseInt(options.limit, 10) : 50;
|
|
13
|
+
try {
|
|
14
|
+
const res = await kgRequest(cfg, "/api/v1/trending", {
|
|
15
|
+
query: { hours, limit, domain: options.domain },
|
|
16
|
+
});
|
|
17
|
+
if (options.json) {
|
|
18
|
+
printJson(res);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
console.log(`Trending (last ${res.window_hours}h) generated ${res.generated_at}\n`);
|
|
22
|
+
printTable(res.entities, [
|
|
23
|
+
["NAME", (r) => r.name],
|
|
24
|
+
["DOMAIN", (r) => r.domain || ""],
|
|
25
|
+
["VIEWS", (r) => fmtInt(r.views_in_window)],
|
|
26
|
+
["VELOCITY", (r) => fmtFloat(r.velocity_score ?? null, 2)],
|
|
27
|
+
["WHY", (r) => r.why_trending || ""],
|
|
28
|
+
]);
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
console.error(`✗ ${err.message}`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=trending.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trending.js","sourceRoot":"","sources":["../../../src/commands/kg/trending.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAiB7E,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAKhC;IACC,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,SAAS,CAAmB,GAAG,EAAE,kBAAkB,EAAE;YACrE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;SAChD,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,SAAS,CAAC,GAAG,CAAC,CAAC;YACf,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,CAAC,YAAY,iBAAiB,GAAG,CAAC,YAAY,IAAI,CAAC,CAAC;QACrF,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE;YACvB,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACvB,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;YACjC,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;YAC3C,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;YAC1D,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,CAAC;SACrC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 4ort mcp [stdio] — run the 4ort MCP server over stdio (Claude Desktop etc.):
|
|
3
|
+
* { "mcpServers": { "4ort": { "command": "4ort", "args": ["mcp"] } } }
|
|
4
|
+
* 4ort mcp serve — run it as a Streamable HTTP server (deploy behind a
|
|
5
|
+
* reverse proxy → mcp.4ort.xyz). Default 127.0.0.1:8003.
|
|
6
|
+
*
|
|
7
|
+
* Tools (both transports): kg_search, web_get, kg_entity, kg_match, kg_agent_context.
|
|
8
|
+
* kg_search + web_get work keyless; the kg_* entity tools use whatever 4ort.xyz
|
|
9
|
+
* key the server's ~/.4ort/config.json has (run `4ort kg auth login` on the host).
|
|
10
|
+
*/
|
|
11
|
+
import { runMcpStdio, runMcpHttp } from "../mcp-server.js";
|
|
12
|
+
export async function mcpStdioCommand() {
|
|
13
|
+
await runMcpStdio();
|
|
14
|
+
}
|
|
15
|
+
export async function mcpServeCommand(opts) {
|
|
16
|
+
const port = opts.port ? parseInt(opts.port, 10) : 8003;
|
|
17
|
+
const host = opts.host || "127.0.0.1";
|
|
18
|
+
if (!Number.isFinite(port) || port <= 0 || port > 65535) {
|
|
19
|
+
console.error(`Invalid --port: ${opts.port}`);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
await runMcpHttp({ host, port });
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE3D,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,WAAW,EAAE,CAAC;AACtB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAsC;IAC1E,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,WAAW,CAAC;IACtC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QACxD,OAAO,CAAC,KAAK,CAAC,mBAAmB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `4ort run -- <command> [args...]`
|
|
3
|
+
*
|
|
4
|
+
* Resolves any env var whose value is a `4ort://service[/name]` reference into
|
|
5
|
+
* its real secret (fetched from the 4ort.ai vault at runtime), injects the
|
|
6
|
+
* plaintext into the child process's environment ONLY, and runs the command.
|
|
7
|
+
* Plaintext never touches disk — it lives only in the child's memory.
|
|
8
|
+
* Fails closed: if any referenced secret can't be resolved, nothing runs.
|
|
9
|
+
*/
|
|
10
|
+
export declare function runCommand(parts: string[]): Promise<void>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { requireVaultConfig } from "../config.js";
|
|
3
|
+
const REF_RE = /^4ort:\/\/.+/;
|
|
4
|
+
/**
|
|
5
|
+
* `4ort run -- <command> [args...]`
|
|
6
|
+
*
|
|
7
|
+
* Resolves any env var whose value is a `4ort://service[/name]` reference into
|
|
8
|
+
* its real secret (fetched from the 4ort.ai vault at runtime), injects the
|
|
9
|
+
* plaintext into the child process's environment ONLY, and runs the command.
|
|
10
|
+
* Plaintext never touches disk — it lives only in the child's memory.
|
|
11
|
+
* Fails closed: if any referenced secret can't be resolved, nothing runs.
|
|
12
|
+
*/
|
|
13
|
+
export async function runCommand(parts) {
|
|
14
|
+
if (!parts || parts.length === 0) {
|
|
15
|
+
console.error("Usage: 4ort run -- <command> [args...]");
|
|
16
|
+
console.error('Example: GROQ_API_KEY=4ort://groq 4ort run -- node app.js');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
const { token, server } = requireVaultConfig();
|
|
20
|
+
// Collect env vars that hold a 4ort:// reference.
|
|
21
|
+
const refsByEnv = {};
|
|
22
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
23
|
+
if (typeof value === "string" && REF_RE.test(value.trim())) {
|
|
24
|
+
refsByEnv[key] = value.trim();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const refs = [...new Set(Object.values(refsByEnv))];
|
|
28
|
+
let resolved = {};
|
|
29
|
+
let missing = [];
|
|
30
|
+
if (refs.length > 0) {
|
|
31
|
+
try {
|
|
32
|
+
const res = await fetch(`${server.replace(/\/$/, "")}/api/secrets/resolve`, {
|
|
33
|
+
method: "POST",
|
|
34
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
|
|
35
|
+
body: JSON.stringify({ refs }),
|
|
36
|
+
});
|
|
37
|
+
if (!res.ok) {
|
|
38
|
+
console.error(`✗ vault resolve failed (HTTP ${res.status}). Try: 4ort vault login`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
const data = (await res.json());
|
|
42
|
+
resolved = data.resolved || {};
|
|
43
|
+
missing = data.missing || [];
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
console.error(`✗ could not reach the vault: ${e.message}`);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (missing.length > 0) {
|
|
51
|
+
console.error(`✗ unresolved secret reference(s): ${missing.join(", ")}`);
|
|
52
|
+
console.error(" add them in the 4ort.ai Secrets panel, or fix the 4ort:// reference.");
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
const childEnv = { ...process.env };
|
|
56
|
+
let injected = 0;
|
|
57
|
+
for (const [key, ref] of Object.entries(refsByEnv)) {
|
|
58
|
+
if (resolved[ref] !== undefined) {
|
|
59
|
+
childEnv[key] = resolved[ref];
|
|
60
|
+
injected += 1;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (injected > 0) {
|
|
64
|
+
console.error(`4ort: injected ${injected} secret${injected === 1 ? "" : "s"} into the environment`);
|
|
65
|
+
}
|
|
66
|
+
const [cmd, ...args] = parts;
|
|
67
|
+
const child = spawn(cmd, args, { stdio: "inherit", env: childEnv });
|
|
68
|
+
child.on("error", (e) => {
|
|
69
|
+
console.error(`✗ failed to run "${cmd}": ${e.message}`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
});
|
|
72
|
+
child.on("exit", (code) => process.exit(code ?? 0));
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 4ort search <query> — the smart router. The front door.
|
|
3
|
+
*
|
|
4
|
+
* GET /api/v1/route?q=...&limit_pages=...&limit_sources=... (public, no key)
|
|
5
|
+
*
|
|
6
|
+
* Returns everything an agent needs to decide where to go next:
|
|
7
|
+
* ● KNOWLEDGE GRAPH — the canonical 4ort.xyz entity the query names (if any),
|
|
8
|
+
* plus that entity's own official site / social links
|
|
9
|
+
* ("straight to the source"). From here: `4ort kg entity
|
|
10
|
+
* <slug>` / `4ort kg ask "..." --scope <slug>`.
|
|
11
|
+
* ☎ AUTHORITATIVE SOURCES — the "phonebook": curated search URLs for the
|
|
12
|
+
* detected vertical (GitHub/Wikipedia/IMDb/SEC/…). The
|
|
13
|
+
* agent can `4ort web get <url>` any of them.
|
|
14
|
+
* ⌕ WEB RESULTS — ranked hits from our Common Crawl index. `4ort web get
|
|
15
|
+
* <url>` to read one.
|
|
16
|
+
*
|
|
17
|
+
* Distinct from `4ort kg search`, which is a pure entity-graph lookup.
|
|
18
|
+
*/
|
|
19
|
+
import { optionalKgConfig } from "../config.js";
|
|
20
|
+
import { kgRequest } from "../kg-client.js";
|
|
21
|
+
import { printJson, truncate } from "../kg-output.js";
|
|
22
|
+
function slugFromEntityUrl(u) {
|
|
23
|
+
if (!u)
|
|
24
|
+
return undefined;
|
|
25
|
+
const m = u.match(/\/entity\/([^/?#]+)/);
|
|
26
|
+
return m ? m[1] : undefined;
|
|
27
|
+
}
|
|
28
|
+
export async function searchCommand(query, options) {
|
|
29
|
+
const cfg = optionalKgConfig();
|
|
30
|
+
const limitPages = options.pages ? parseInt(options.pages, 10) : 20;
|
|
31
|
+
const limitSources = options.sources ? parseInt(options.sources, 10) : 12;
|
|
32
|
+
try {
|
|
33
|
+
const res = await kgRequest(cfg, "/api/v1/route", {
|
|
34
|
+
query: { q: query, limit_pages: limitPages, limit_sources: limitSources },
|
|
35
|
+
});
|
|
36
|
+
if (options.json) {
|
|
37
|
+
printJson(res);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
// ── header / detected intent ──
|
|
41
|
+
console.log(`SEARCH "${res.query}"`);
|
|
42
|
+
const pi = res.primary_intent;
|
|
43
|
+
if (pi) {
|
|
44
|
+
const how = pi.method === "entity"
|
|
45
|
+
? `exact entity → ${pi.entity_name}`
|
|
46
|
+
: pi.method === "keyword"
|
|
47
|
+
? `keyword rule${pi.keyword_hits ? ` · ${pi.keyword_hits} hits` : ""}`
|
|
48
|
+
: pi.method === "embedding"
|
|
49
|
+
? "semantic"
|
|
50
|
+
: pi.method;
|
|
51
|
+
console.log(` intent: ${pi.label} [${how}]`);
|
|
52
|
+
}
|
|
53
|
+
if (res.intent_alternatives?.length) {
|
|
54
|
+
console.log(` or maybe: ${res.intent_alternatives.map((a) => a.label).join(" · ")}`);
|
|
55
|
+
}
|
|
56
|
+
// ── ● knowledge graph ──
|
|
57
|
+
if (res.canonical_entity) {
|
|
58
|
+
const e = res.canonical_entity;
|
|
59
|
+
const slug = slugFromEntityUrl(e.url);
|
|
60
|
+
console.log(`\n● KNOWLEDGE GRAPH`);
|
|
61
|
+
console.log(` ${e.name}${e.summary ? ` — ${e.summary}` : ""}`);
|
|
62
|
+
const views = typeof e.monthly_pageviews === "number" && e.monthly_pageviews > 0
|
|
63
|
+
? ` ~${e.monthly_pageviews.toLocaleString()} views/mo`
|
|
64
|
+
: "";
|
|
65
|
+
console.log(` ${e.url}${views}`);
|
|
66
|
+
if (slug) {
|
|
67
|
+
console.log(` → 4ort kg entity ${slug} --detail full`);
|
|
68
|
+
console.log(` → 4ort kg ask "<question>" --scope ${slug}`);
|
|
69
|
+
}
|
|
70
|
+
if (e.links?.length) {
|
|
71
|
+
console.log(` straight to the source:`);
|
|
72
|
+
for (const l of e.links)
|
|
73
|
+
console.log(` ${l.icon || "•"} ${l.name}: ${l.url}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// ── ☎ the phonebook ──
|
|
77
|
+
if (res.recommended_sources?.length) {
|
|
78
|
+
console.log(`\n☎ AUTHORITATIVE SOURCES (the phonebook — 4ort web get <url> to read one)`);
|
|
79
|
+
const w = Math.min(22, Math.max(...res.recommended_sources.map((s) => s.name.length)));
|
|
80
|
+
for (const s of res.recommended_sources) {
|
|
81
|
+
console.log(` ${s.name.padEnd(w)} ${s.url}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// ── ⌕ web results ──
|
|
85
|
+
if (res.our_pages?.length) {
|
|
86
|
+
console.log(`\n⌕ WEB RESULTS (${res.our_pages.length} from our index — 4ort web get <url> to read)`);
|
|
87
|
+
for (const p of res.our_pages) {
|
|
88
|
+
console.log(` ${p.title}${p.host ? ` · ${p.host}` : ""}`);
|
|
89
|
+
console.log(` ${p.url}`);
|
|
90
|
+
if (p.snippet)
|
|
91
|
+
console.log(` ${truncate(p.snippet, 140)}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
console.log(`\n⌕ WEB RESULTS (nothing in our index for this query — use the phonebook)`);
|
|
96
|
+
}
|
|
97
|
+
if (res.license)
|
|
98
|
+
console.log(`\n${res.license}`);
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
console.error(`✗ ${err.message}`);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAuCtD,SAAS,iBAAiB,CAAC,CAAU;IACnC,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACzB,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACzC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAa,EAAE,OAAsB;IACvE,MAAM,GAAG,GAAG,gBAAgB,EAAE,CAAC;IAC/B,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpE,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE1E,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,SAAS,CAAgB,GAAG,EAAE,eAAe,EAAE;YAC/D,KAAK,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE;SAC1E,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,SAAS,CAAC,GAAG,CAAC,CAAC;YACf,OAAO;QACT,CAAC;QAED,iCAAiC;QACjC,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC;QACtC,MAAM,EAAE,GAAG,GAAG,CAAC,cAAc,CAAC;QAC9B,IAAI,EAAE,EAAE,CAAC;YACP,MAAM,GAAG,GACP,EAAE,CAAC,MAAM,KAAK,QAAQ;gBACpB,CAAC,CAAC,kBAAkB,EAAE,CAAC,WAAW,EAAE;gBACpC,CAAC,CAAC,EAAE,CAAC,MAAM,KAAK,SAAS;oBACvB,CAAC,CAAC,eAAe,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,YAAY,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;oBACtE,CAAC,CAAC,EAAE,CAAC,MAAM,KAAK,WAAW;wBACzB,CAAC,CAAC,UAAU;wBACZ,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,KAAK,OAAO,GAAG,GAAG,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,GAAG,CAAC,mBAAmB,EAAE,MAAM,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC1F,CAAC;QAED,0BAA0B;QAC1B,IAAI,GAAG,CAAC,gBAAgB,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,GAAG,CAAC,gBAAgB,CAAC;YAC/B,MAAM,IAAI,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACtC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAClE,MAAM,KAAK,GACT,OAAO,CAAC,CAAC,iBAAiB,KAAK,QAAQ,IAAI,CAAC,CAAC,iBAAiB,GAAG,CAAC;gBAChE,CAAC,CAAC,OAAO,CAAC,CAAC,iBAAiB,CAAC,cAAc,EAAE,WAAW;gBACxD,CAAC,CAAC,EAAE,CAAC;YACT,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC;YAClC,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,gBAAgB,CAAC,CAAC;gBACxD,OAAO,CAAC,GAAG,CAAC,wCAAwC,IAAI,EAAE,CAAC,CAAC;YAC9D,CAAC;YACD,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;gBACpB,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;gBACzC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK;oBAAE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACpF,CAAC;QACH,CAAC;QAED,wBAAwB;QACxB,IAAI,GAAG,CAAC,mBAAmB,EAAE,MAAM,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,8EAA8E,CAAC,CAAC;YAC5F,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACvF,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,mBAAmB,EAAE,CAAC;gBACxC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,IAAI,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,sBAAsB,GAAG,CAAC,SAAS,CAAC,MAAM,+CAA+C,CAAC,CAAC;YACvG,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;gBAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC9D,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;gBAC5B,IAAI,CAAC,CAAC,OAAO;oBAAE,OAAO,CAAC,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,6EAA6E,CAAC,CAAC;QAC7F,CAAC;QAED,IAAI,GAAG,CAAC,OAAO;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Link this machine to the 4ort.ai secrets vault using a token minted from the
|
|
2
|
+
* Secrets panel. The token is stored at ~/.4ort/config.json (mode 0600). */
|
|
3
|
+
export declare function vaultLogin(token: string | undefined, opts: {
|
|
4
|
+
server?: string;
|
|
5
|
+
}): Promise<void>;
|
|
6
|
+
export declare function vaultStatus(): void;
|
|
7
|
+
export declare function vaultLogout(): void;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { createInterface } from "node:readline";
|
|
2
|
+
import { loadConfig, saveConfig, saveVaultConfig } from "../config.js";
|
|
3
|
+
const DEFAULT_VAULT_SERVER = "https://4ort.ai";
|
|
4
|
+
function readLine(prompt) {
|
|
5
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
6
|
+
return new Promise((resolve) => {
|
|
7
|
+
rl.question(prompt, (answer) => {
|
|
8
|
+
rl.close();
|
|
9
|
+
resolve(answer.trim());
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
/** Link this machine to the 4ort.ai secrets vault using a token minted from the
|
|
14
|
+
* Secrets panel. The token is stored at ~/.4ort/config.json (mode 0600). */
|
|
15
|
+
export async function vaultLogin(token, opts) {
|
|
16
|
+
const server = (opts.server || DEFAULT_VAULT_SERVER).replace(/\/$/, "");
|
|
17
|
+
let tok = token;
|
|
18
|
+
if (!tok) {
|
|
19
|
+
tok = await readLine("Paste your vault token (4vt_…): ");
|
|
20
|
+
}
|
|
21
|
+
if (!tok || !tok.startsWith("4vt_")) {
|
|
22
|
+
console.error("Expected a token starting with 4vt_. Generate one in the 4ort.ai Secrets panel.");
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
// Verify the token against the vault (empty resolve = a cheap auth check).
|
|
26
|
+
try {
|
|
27
|
+
const res = await fetch(`${server}/api/secrets/resolve`, {
|
|
28
|
+
method: "POST",
|
|
29
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${tok}` },
|
|
30
|
+
body: JSON.stringify({ refs: [] }),
|
|
31
|
+
});
|
|
32
|
+
if (!res.ok) {
|
|
33
|
+
console.error(`Vault login failed (HTTP ${res.status}). Check the token and --server.`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
console.error(`Could not reach the vault at ${server}: ${e.message}`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
saveVaultConfig({ token: tok, server });
|
|
42
|
+
console.error(`✓ Vault linked (${server}).`);
|
|
43
|
+
console.error("Use 4ort:// references in your env, then run: 4ort run -- <command>");
|
|
44
|
+
}
|
|
45
|
+
export function vaultStatus() {
|
|
46
|
+
const c = loadConfig();
|
|
47
|
+
if (c?.vault?.token) {
|
|
48
|
+
console.log(`Vault: linked to ${c.vault.server} (token ${c.vault.token.slice(0, 12)}…)`);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
console.log("Vault: not linked. Run: 4ort vault login");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export function vaultLogout() {
|
|
55
|
+
const c = loadConfig();
|
|
56
|
+
if (c?.vault) {
|
|
57
|
+
delete c.vault;
|
|
58
|
+
saveConfig(c);
|
|
59
|
+
}
|
|
60
|
+
console.log("Vault unlinked.");
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=vault.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault.js","sourceRoot":"","sources":["../../src/commands/vault.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 4ort web get <url>
|
|
3
|
+
*
|
|
4
|
+
* Fetch a URL and return its readable text — "Reader Mode" style. Tiered:
|
|
5
|
+
* our own entity pages → structured record; everything else → live fetch +
|
|
6
|
+
* Mozilla Readability. No browser, no JS. On block / paywall / binary / parse
|
|
7
|
+
* failure: ok:false + the URL, so a calling agent can fall back.
|
|
8
|
+
*/
|
|
9
|
+
import { webRead } from "../web-client.js";
|
|
10
|
+
import { printJson } from "../kg-output.js";
|
|
11
|
+
export async function webGet(url, options) {
|
|
12
|
+
const maxChars = options.maxChars ? parseInt(options.maxChars, 10) : undefined;
|
|
13
|
+
const res = await webRead(url, { maxChars });
|
|
14
|
+
if (options.json) {
|
|
15
|
+
printJson(res);
|
|
16
|
+
process.exit(res.ok ? 0 : 1);
|
|
17
|
+
}
|
|
18
|
+
if (!res.ok) {
|
|
19
|
+
console.error(`✗ ${res.reason || "failed"}`);
|
|
20
|
+
console.error(` ${res.final_url || res.url}`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
if (res.source === "4ort.xyz" && res.entity) {
|
|
24
|
+
const e = res.entity;
|
|
25
|
+
console.log(`# ${e?.name || res.title || res.url}`);
|
|
26
|
+
console.log(`(4ort.xyz knowledge-graph entity — structured)\n`);
|
|
27
|
+
if (e?.description)
|
|
28
|
+
console.log(`${e.description}\n`);
|
|
29
|
+
printJson(e);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (res.title)
|
|
33
|
+
console.log(`# ${res.title}`);
|
|
34
|
+
if (res.byline)
|
|
35
|
+
console.log(`_by ${res.byline}_`);
|
|
36
|
+
const meta = [
|
|
37
|
+
res.word_count != null ? `${res.word_count} words` : null,
|
|
38
|
+
res.truncated ? "truncated" : null,
|
|
39
|
+
res.reason || null,
|
|
40
|
+
].filter(Boolean).join(" · ");
|
|
41
|
+
console.log(`<${res.final_url || res.url}>${meta ? ` — ${meta}` : ""}\n`);
|
|
42
|
+
console.log(res.text || "(no text extracted)");
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/commands/web.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAO5C,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,GAAW,EAAE,OAAsB;IAC9D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/E,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;IAE7C,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,SAAS,CAAC,GAAG,CAAC,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QAC5C,MAAM,CAAC,GAAG,GAAG,CAAC,MAAa,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAChE,IAAI,CAAC,EAAE,WAAW;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC;QACtD,SAAS,CAAC,CAAC,CAAC,CAAC;QACb,OAAO;IACT,CAAC;IAED,IAAI,GAAG,CAAC,KAAK;QAAE,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;IAC7C,IAAI,GAAG,CAAC,MAAM;QAAE,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG;QACX,GAAG,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,QAAQ,CAAC,CAAC,CAAC,IAAI;QACzD,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;QAClC,GAAG,CAAC,MAAM,IAAI,IAAI;KACnB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,qBAAqB,CAAC,CAAC;AACjD,CAAC"}
|