@4ort/cli 0.4.0 → 0.6.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.
Files changed (85) hide show
  1. package/README.md +286 -0
  2. package/dist/commands/kg/agent-context.d.ts +3 -0
  3. package/dist/commands/kg/agent-context.js +54 -0
  4. package/dist/commands/kg/agent-context.js.map +1 -0
  5. package/dist/commands/kg/article-context.d.ts +3 -0
  6. package/dist/commands/kg/article-context.js +51 -0
  7. package/dist/commands/kg/article-context.js.map +1 -0
  8. package/dist/commands/kg/ask.d.ts +5 -0
  9. package/dist/commands/kg/ask.js +121 -0
  10. package/dist/commands/kg/ask.js.map +1 -0
  11. package/dist/commands/kg/auth.d.ts +9 -0
  12. package/dist/commands/kg/auth.js +95 -0
  13. package/dist/commands/kg/auth.js.map +1 -0
  14. package/dist/commands/kg/entity.d.ts +4 -0
  15. package/dist/commands/kg/entity.js +33 -0
  16. package/dist/commands/kg/entity.js.map +1 -0
  17. package/dist/commands/kg/match.d.ts +5 -0
  18. package/dist/commands/kg/match.js +44 -0
  19. package/dist/commands/kg/match.js.map +1 -0
  20. package/dist/commands/kg/popularity.d.ts +3 -0
  21. package/dist/commands/kg/popularity.js +42 -0
  22. package/dist/commands/kg/popularity.js.map +1 -0
  23. package/dist/commands/kg/search.d.ts +4 -0
  24. package/dist/commands/kg/search.js +34 -0
  25. package/dist/commands/kg/search.js.map +1 -0
  26. package/dist/commands/kg/trending.d.ts +6 -0
  27. package/dist/commands/kg/trending.js +35 -0
  28. package/dist/commands/kg/trending.js.map +1 -0
  29. package/dist/commands/mcp.d.ts +5 -0
  30. package/dist/commands/mcp.js +24 -0
  31. package/dist/commands/mcp.js.map +1 -0
  32. package/dist/commands/mov.d.ts +17 -0
  33. package/dist/commands/mov.js +124 -0
  34. package/dist/commands/mov.js.map +1 -0
  35. package/dist/commands/run.d.ts +10 -0
  36. package/dist/commands/run.js +74 -0
  37. package/dist/commands/run.js.map +1 -0
  38. package/dist/commands/search.d.ts +7 -0
  39. package/dist/commands/search.js +105 -0
  40. package/dist/commands/search.js.map +1 -0
  41. package/dist/commands/vault.d.ts +7 -0
  42. package/dist/commands/vault.js +62 -0
  43. package/dist/commands/vault.js.map +1 -0
  44. package/dist/commands/web.d.ts +6 -0
  45. package/dist/commands/web.js +44 -0
  46. package/dist/commands/web.js.map +1 -0
  47. package/dist/config.d.ts +38 -0
  48. package/dist/config.js +97 -1
  49. package/dist/config.js.map +1 -1
  50. package/dist/config.mov.test.d.ts +1 -0
  51. package/dist/config.mov.test.js +23 -0
  52. package/dist/config.mov.test.js.map +1 -0
  53. package/dist/index.js +195 -37
  54. package/dist/index.js.map +1 -1
  55. package/dist/kg-client.d.ts +42 -0
  56. package/dist/kg-client.js +125 -0
  57. package/dist/kg-client.js.map +1 -0
  58. package/dist/kg-output.d.ts +33 -0
  59. package/dist/kg-output.js +132 -0
  60. package/dist/kg-output.js.map +1 -0
  61. package/dist/mcp-server.d.ts +5 -0
  62. package/dist/mcp-server.js +363 -0
  63. package/dist/mcp-server.js.map +1 -0
  64. package/dist/peertube-client.d.ts +47 -0
  65. package/dist/peertube-client.js +144 -0
  66. package/dist/peertube-client.js.map +1 -0
  67. package/dist/peertube-client.test.d.ts +1 -0
  68. package/dist/peertube-client.test.js +92 -0
  69. package/dist/peertube-client.test.js.map +1 -0
  70. package/dist/web-client.d.ts +20 -0
  71. package/dist/web-client.js +335 -0
  72. package/dist/web-client.js.map +1 -0
  73. package/package.json +21 -4
  74. package/src/api-client.ts +0 -51
  75. package/src/commands/delete.ts +0 -15
  76. package/src/commands/list.ts +0 -25
  77. package/src/commands/mail.ts +0 -79
  78. package/src/commands/provision.ts +0 -106
  79. package/src/commands/push.ts +0 -63
  80. package/src/commands/recover.ts +0 -37
  81. package/src/commands/register.ts +0 -40
  82. package/src/commands/whoami.ts +0 -20
  83. package/src/config.ts +0 -40
  84. package/src/index.ts +0 -114
  85. package/tsconfig.json +0 -8
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"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"}
@@ -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":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEvE,MAAM,oBAAoB,GAAG,iBAAiB,CAAC;AAE/C,SAAS,QAAQ,CAAC,MAAc;IAC9B,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAC7B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;4EAC4E;AAC5E,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAyB,EACzB,IAAyB;IAEzB,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,oBAAoB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACxE,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,GAAG,GAAG,MAAM,QAAQ,CAAC,kCAAkC,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,OAAO,CAAC,KAAK,CAAC,iFAAiF,CAAC,CAAC;QACjG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,2EAA2E;IAC3E,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,sBAAsB,EAAE;YACvD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,UAAU,GAAG,EAAE,EAAE;YAC/E,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;SACnC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,OAAO,CAAC,KAAK,CAAC,4BAA4B,GAAG,CAAC,MAAM,kCAAkC,CAAC,CAAC;YACxF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,gCAAgC,MAAM,KAAM,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QACjF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,eAAe,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,KAAK,CAAC,mBAAmB,MAAM,IAAI,CAAC,CAAC;IAC7C,OAAO,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAC;AACxF,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,GAAG,UAAU,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,KAAK,CAAC,MAAM,WAAW,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;IAC3F,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,GAAG,UAAU,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,CAAC,KAAK,CAAC;QACf,UAAU,CAAC,CAAC,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,6 @@
1
+ interface WebGetOptions {
2
+ json?: boolean;
3
+ maxChars?: string;
4
+ }
5
+ export declare function webGet(url: string, options: WebGetOptions): Promise<void>;
6
+ export {};
@@ -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"}
package/dist/config.d.ts CHANGED
@@ -1,10 +1,48 @@
1
+ export interface KgConfig {
2
+ apiKey: string;
3
+ recoveryCode?: string;
4
+ server: string;
5
+ name?: string;
6
+ tier?: string;
7
+ }
8
+ export interface VaultConfig {
9
+ token: string;
10
+ server: string;
11
+ }
12
+ export interface MovConfig {
13
+ server: string;
14
+ accessToken: string;
15
+ refreshToken: string;
16
+ clientId: string;
17
+ clientSecret: string;
18
+ username?: string;
19
+ }
1
20
  export interface Config {
2
21
  apiKey: string;
3
22
  recoveryCode?: string;
4
23
  server: string;
5
24
  agentName: string;
25
+ kg?: KgConfig;
26
+ vault?: VaultConfig;
27
+ mov?: MovConfig;
6
28
  }
7
29
  export declare function loadConfig(): Config | null;
8
30
  export declare function saveConfig(config: Config): void;
31
+ /** Save just the KG block, preserving any existing 4ort.net config. */
32
+ export declare function saveKgConfig(kg: KgConfig): void;
9
33
  export declare function requireConfig(): Config;
34
+ export declare function requireKgConfig(): KgConfig;
35
+ /**
36
+ * Like requireKgConfig, but never exits — for public KG endpoints (e.g.
37
+ * /api/v1/route). Returns the KG key if present, else the 4ort.net key, else an
38
+ * empty key against the canonical server. Callers should treat auth as optional.
39
+ */
40
+ export declare function optionalKgConfig(): KgConfig;
10
41
  export declare function getConfigPath(): string;
42
+ /** Save just the vault block, preserving the rest of the config. */
43
+ export declare function saveVaultConfig(vault: VaultConfig): void;
44
+ export declare function requireVaultConfig(): VaultConfig;
45
+ /** Save just the mov block (4ort.mov / PeerTube), preserving the rest. */
46
+ export declare function saveMovConfig(mov: MovConfig): void;
47
+ /** Return the mov block or exit with a friendly hint if not logged in. */
48
+ export declare function optionalMovConfig(): MovConfig;
package/dist/config.js CHANGED
@@ -1,3 +1,24 @@
1
+ /**
2
+ * Persisted CLI config at ~/.4ort/config.json (mode 0600).
3
+ *
4
+ * Layout:
5
+ * {
6
+ * "apiKey": "...", // 4ort.net agent key (4n_-prefixed going forward)
7
+ * "recoveryCode": "...",
8
+ * "server": "https://4ort.net",
9
+ * "agentName": "ryan",
10
+ * "kg": { // 4ort.xyz knowledge graph (optional)
11
+ * "apiKey": "4kg_...",
12
+ * "recoveryCode": "...",
13
+ * "server": "https://4ort.xyz",
14
+ * "name": "my-agent",
15
+ * "tier": "free"
16
+ * }
17
+ * }
18
+ *
19
+ * Both blocks are independent — a user can sign in to 4ort.net only,
20
+ * 4ort.xyz only, or both. The CLI picks the right block per command.
21
+ */
1
22
  import fs from "node:fs";
2
23
  import path from "node:path";
3
24
  import os from "node:os";
@@ -16,15 +37,90 @@ export function saveConfig(config) {
16
37
  fs.mkdirSync(CONFIG_DIR, { recursive: true });
17
38
  fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n", { mode: 0o600 });
18
39
  }
40
+ /** Save just the KG block, preserving any existing 4ort.net config. */
41
+ export function saveKgConfig(kg) {
42
+ const existing = loadConfig();
43
+ const next = existing
44
+ ? { ...existing, kg }
45
+ : { apiKey: "", server: "https://4ort.net", agentName: "", kg };
46
+ saveConfig(next);
47
+ }
19
48
  export function requireConfig() {
20
49
  const config = loadConfig();
21
- if (!config) {
50
+ if (!config || !config.apiKey) {
22
51
  console.error("Not logged in. Run: 4ort register <name>");
23
52
  process.exit(1);
53
+ throw new Error("unreachable");
24
54
  }
25
55
  return config;
26
56
  }
57
+ export function requireKgConfig() {
58
+ const config = loadConfig();
59
+ if (config?.kg?.apiKey)
60
+ return config.kg;
61
+ // Fall back to 4ort.net membership if present — federated keys validate
62
+ // against 4ort.net automatically.
63
+ if (config?.apiKey) {
64
+ return {
65
+ apiKey: config.apiKey,
66
+ server: "https://4ort.xyz",
67
+ };
68
+ }
69
+ console.error("Not signed in to 4ort.xyz. Run one of:");
70
+ console.error(" 4ort kg register # one-shot, no email needed");
71
+ console.error(" 4ort kg auth login # paste an existing key");
72
+ process.exit(1);
73
+ throw new Error("unreachable");
74
+ }
75
+ /**
76
+ * Like requireKgConfig, but never exits — for public KG endpoints (e.g.
77
+ * /api/v1/route). Returns the KG key if present, else the 4ort.net key, else an
78
+ * empty key against the canonical server. Callers should treat auth as optional.
79
+ */
80
+ export function optionalKgConfig() {
81
+ const config = loadConfig();
82
+ if (config?.kg?.apiKey)
83
+ return config.kg;
84
+ if (config?.apiKey)
85
+ return { apiKey: config.apiKey, server: "https://4ort.xyz" };
86
+ return { apiKey: "", server: "https://4ort.xyz" };
87
+ }
27
88
  export function getConfigPath() {
28
89
  return CONFIG_FILE;
29
90
  }
91
+ /** Save just the vault block, preserving the rest of the config. */
92
+ export function saveVaultConfig(vault) {
93
+ const existing = loadConfig();
94
+ const next = existing
95
+ ? { ...existing, vault }
96
+ : { apiKey: "", server: "https://4ort.net", agentName: "", vault };
97
+ saveConfig(next);
98
+ }
99
+ export function requireVaultConfig() {
100
+ const config = loadConfig();
101
+ if (config?.vault?.token) {
102
+ return config.vault;
103
+ }
104
+ console.error("Not signed in to the 4ort.ai vault. Run:");
105
+ console.error(" 4ort vault login # paste a token from the Secrets panel");
106
+ process.exit(1);
107
+ throw new Error("unreachable");
108
+ }
109
+ /** Save just the mov block (4ort.mov / PeerTube), preserving the rest. */
110
+ export function saveMovConfig(mov) {
111
+ const existing = loadConfig();
112
+ const next = existing
113
+ ? { ...existing, mov }
114
+ : { apiKey: "", server: "https://4ort.net", agentName: "", mov };
115
+ saveConfig(next);
116
+ }
117
+ /** Return the mov block or exit with a friendly hint if not logged in. */
118
+ export function optionalMovConfig() {
119
+ const config = loadConfig();
120
+ if (config?.mov?.accessToken)
121
+ return config.mov;
122
+ console.error("Not signed in to 4ort.mov. Run: 4ort mov login");
123
+ process.exit(1);
124
+ throw new Error("unreachable");
125
+ }
30
126
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;AACpD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AASzD,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACzF,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,WAAW,CAAC;AACrB,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
1
+ import { test } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import fs from "node:fs";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ test("saveMovConfig round-trips and preserves other blocks", async () => {
7
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "fort-"));
8
+ process.env.HOME = tmp; // CONFIG_DIR derives from os.homedir()
9
+ const cfg = await import(`./config.js?case=${Date.now()}`);
10
+ cfg.saveConfig({ apiKey: "x", server: "https://4ort.net", agentName: "ryan" });
11
+ cfg.saveMovConfig({
12
+ server: "https://4ort.mov",
13
+ accessToken: "tok",
14
+ refreshToken: "ref",
15
+ clientId: "c",
16
+ clientSecret: "s",
17
+ });
18
+ const loaded = cfg.loadConfig();
19
+ assert.equal(loaded.apiKey, "x"); // pre-existing block preserved
20
+ assert.equal(loaded.mov.accessToken, "tok");
21
+ assert.equal(loaded.mov.server, "https://4ort.mov");
22
+ });
23
+ //# sourceMappingURL=config.mov.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.mov.test.js","sourceRoot":"","sources":["../src/config.mov.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,IAAI,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;IACtE,MAAM,GAAG,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,uCAAuC;IAC/D,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,oBAAoB,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC3D,GAAG,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/E,GAAG,CAAC,aAAa,CAAC;QAChB,MAAM,EAAE,kBAAkB;QAC1B,WAAW,EAAE,KAAK;QAClB,YAAY,EAAE,KAAK;QACnB,QAAQ,EAAE,GAAG;QACb,YAAY,EAAE,GAAG;KAClB,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;IAChC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,+BAA+B;IACjE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAC5C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC"}
package/dist/index.js CHANGED
@@ -6,13 +6,31 @@ import { list } from "./commands/list.js";
6
6
  import { deleteSite } from "./commands/delete.js";
7
7
  import { whoami } from "./commands/whoami.js";
8
8
  import { checkMail, readMail, sendMail, deleteMail } from "./commands/mail.js";
9
- import { provisionService, provisionAll, provisionStatus, provisionCredentials, listServices } from "./commands/provision.js";
9
+ import { provisionService, provisionAll, provisionStatus, provisionCredentials, listServices, } from "./commands/provision.js";
10
+ import { kgRegister, kgLogin, kgStatus } from "./commands/kg/auth.js";
11
+ import { kgSearch } from "./commands/kg/search.js";
12
+ import { kgEntity } from "./commands/kg/entity.js";
13
+ import { kgAsk } from "./commands/kg/ask.js";
14
+ import { kgMatch } from "./commands/kg/match.js";
15
+ import { kgPopularity } from "./commands/kg/popularity.js";
16
+ import { kgTrending } from "./commands/kg/trending.js";
17
+ import { kgAgentContext } from "./commands/kg/agent-context.js";
18
+ import { kgArticleContext } from "./commands/kg/article-context.js";
19
+ import { webGet } from "./commands/web.js";
20
+ import { searchCommand } from "./commands/search.js";
21
+ import { mcpStdioCommand, mcpServeCommand } from "./commands/mcp.js";
22
+ import { vaultLogin, vaultStatus, vaultLogout } from "./commands/vault.js";
23
+ import { runCommand } from "./commands/run.js";
24
+ import { movLogin, movPublish, movList, movChannels, movDelete } from "./commands/mov.js";
10
25
  import { loadConfig, getConfigPath } from "./config.js";
11
26
  const program = new Command();
12
27
  program
13
28
  .name("4ort")
14
- .description("CLI for 4ort.netwhere AI agents build websites")
15
- .version("0.1.0");
29
+ .description("Unified CLI for the 4ort ecosystem hosting, knowledge graph, and more")
30
+ .version("0.6.0");
31
+ // ─────────────────────────────────────────────────────────────────────
32
+ // 4ort.net subdomain hosting
33
+ // ─────────────────────────────────────────────────────────────────────
16
34
  program
17
35
  .command("register <name>")
18
36
  .description("Register a new agent and claim your subdomain")
@@ -23,47 +41,49 @@ program
23
41
  .command("push [directory]")
24
42
  .description("Deploy your site (defaults to current directory)")
25
43
  .action((dir = ".") => push(dir));
44
+ program.command("list").description("List your sites").action(list);
45
+ // ─────────────────────────────────────────────────────────────────────
46
+ // Secrets vault — `4ort run` resolves 4ort:// references at runtime
47
+ // ─────────────────────────────────────────────────────────────────────
48
+ const vault = program
49
+ .command("vault")
50
+ .description("Link this machine to the 4ort.ai secrets vault");
51
+ vault
52
+ .command("login [token]")
53
+ .description("Link the vault with a token from the Secrets panel")
54
+ .option("-s, --server <url>", "Vault server URL", "https://4ort.ai")
55
+ .action((token, opts) => vaultLogin(token, opts));
56
+ vault.command("status").description("Show vault link status").action(vaultStatus);
57
+ vault.command("logout").description("Unlink the vault").action(vaultLogout);
26
58
  program
27
- .command("list")
28
- .description("List your sites")
29
- .action(list);
59
+ .command("run")
60
+ .description("Run a command with 4ort:// secret references resolved into env vars")
61
+ .argument("[parts...]", "command and args (use -- to separate, e.g. 4ort run -- node app.js)")
62
+ .action((parts) => runCommand(parts));
30
63
  program
31
64
  .command("delete [subdomain]")
32
65
  .description("Delete a site")
33
66
  .action(deleteSite);
34
- program
35
- .command("whoami")
36
- .description("Show current agent info")
37
- .action(whoami);
67
+ program.command("whoami").description("Show current agent info").action(whoami);
38
68
  const mail = program.command("mail").description("Manage your @4ort.net inbox");
39
69
  mail
40
70
  .command("inbox")
41
71
  .description("Check your inbox")
42
72
  .option("-u, --unread", "Show unread only")
43
73
  .action(checkMail);
44
- mail
45
- .command("read <id>")
46
- .description("Read a message")
47
- .action(readMail);
74
+ mail.command("read <id>").description("Read a message").action(readMail);
48
75
  mail
49
76
  .command("send <to>")
50
77
  .description("Send a message to another agent")
51
78
  .option("-s, --subject <subject>", "Subject line")
52
79
  .option("-b, --body <body>", "Message body")
53
80
  .action(sendMail);
54
- mail
55
- .command("delete <id>")
56
- .description("Delete a message")
57
- .action(deleteMail);
58
- const provision = program.command("provision").description("Auto-provision third-party service accounts");
59
- provision
60
- .command("run <service>")
61
- .description("Provision a specific service")
62
- .action(provisionService);
63
- provision
64
- .command("all")
65
- .description("Provision all available Tier A services")
66
- .action(provisionAll);
81
+ mail.command("delete <id>").description("Delete a message").action(deleteMail);
82
+ const provision = program
83
+ .command("provision")
84
+ .description("Auto-provision third-party service accounts");
85
+ provision.command("run <service>").description("Provision a specific service").action(provisionService);
86
+ provision.command("all").description("Provision all available Tier A services").action(provisionAll);
67
87
  provision
68
88
  .command("status [service]")
69
89
  .description("Check provisioning status")
@@ -72,23 +92,161 @@ provision
72
92
  .command("credentials [service]")
73
93
  .description("Show stored credentials")
74
94
  .action((service) => provisionCredentials(service));
75
- provision
76
- .command("services")
77
- .description("List available services")
78
- .action(listServices);
95
+ provision.command("services").description("List available services").action(listServices);
96
+ // ─────────────────────────────────────────────────────────────────────
97
+ // Search — the smart router / front door (4ort.xyz entity + phonebook + web)
98
+ // ─────────────────────────────────────────────────────────────────────
99
+ program
100
+ .command("search <query>")
101
+ .description("Smart router: KG entity + curated sources (phonebook) + web hits")
102
+ .option("-p, --pages <n>", "Max web-index hits", "20")
103
+ .option("-s, --sources <n>", "Max authoritative-source routes", "12")
104
+ .option("--json", "Output the full structured payload as JSON")
105
+ .action(searchCommand);
106
+ // ─────────────────────────────────────────────────────────────────────
107
+ // 4ort knowledge graph (Popularity Graph)
108
+ // ─────────────────────────────────────────────────────────────────────
109
+ const kg = program
110
+ .command("kg")
111
+ .description("Query the 4ort knowledge graph (Popularity Graph)");
112
+ kg.command("register")
113
+ .description("One-shot register a new 4ort.xyz API key")
114
+ .option("-n, --name <name>", "Display name for this key")
115
+ .option("-e, --email <email>", "Optional contact email for billing/recovery")
116
+ .option("-s, --server <url>", "KG server URL", "https://4ort.xyz")
117
+ .action(kgRegister);
118
+ const kgAuth = kg.command("auth").description("Manage 4ort.xyz authentication");
119
+ kgAuth
120
+ .command("login")
121
+ .description("Sign in by pasting an existing 4ort.xyz API key")
122
+ .option("-s, --server <url>", "KG server URL", "https://4ort.xyz")
123
+ .action(kgLogin);
124
+ kgAuth
125
+ .command("status")
126
+ .description("Show the current 4ort.xyz identity")
127
+ .action(kgStatus);
128
+ kg.command("search <query>")
129
+ .description("Hybrid search across the entity graph")
130
+ .option("-l, --limit <n>", "Max results", "20")
131
+ .option("--json", "Output JSON instead of a table")
132
+ .action(kgSearch);
133
+ kg.command("entity <key>")
134
+ .description("Fetch one entity (slug, UUID, or Q-id)")
135
+ .option("-d, --detail <level>", "tiny | small | medium | full", "medium")
136
+ .option("--json", "Output JSON")
137
+ .action(kgEntity);
138
+ kg.command("ask <question>")
139
+ .description("Ask the graph anything — streams cited tokens")
140
+ .option("-s, --scope <slug>", "Scope the question to one entity")
141
+ .option("--json", "Skip streaming, return one structured payload")
142
+ .option("--plain", "Strip markdown formatting (no bold, italic, code marks)")
143
+ .action(kgAsk);
144
+ kg.command("match <text>")
145
+ .description("Resolve a string to its canonical KG entity")
146
+ .option("-l, --limit <n>", "Max candidates", "5")
147
+ .option("-t, --types <list>", "Comma-separated entity-type filter")
148
+ .option("--json", "Output JSON")
149
+ .action(kgMatch);
150
+ kg.command("popularity <key>")
151
+ .description("Pageview-derived 'real-world search volume' for an entity")
152
+ .option("--json", "Output JSON")
153
+ .action(kgPopularity);
154
+ kg.command("trending")
155
+ .description("Top entities by Wikipedia pageview velocity")
156
+ .option("-h, --hours <n>", "Window size in hours", "1")
157
+ .option("-l, --limit <n>", "Max results", "50")
158
+ .option("-d, --domain <name>", "Filter to a specific domain")
159
+ .option("--json", "Output JSON")
160
+ .action(kgTrending);
161
+ kg.command("agent-context <key>")
162
+ .description("Memory-bank bundle for autonomous agents")
163
+ .option("--json", "Output JSON")
164
+ .action(kgAgentContext);
165
+ kg.command("article-context <key>")
166
+ .description("Fat bundle for SEO writers — facts, citations, hooks")
167
+ .option("--json", "Output JSON")
168
+ .action(kgArticleContext);
169
+ // ─────────────────────────────────────────────────────────────────────
170
+ // 4ort.mov — AI-first video host (PeerTube). Publish + manage videos.
171
+ // ─────────────────────────────────────────────────────────────────────
172
+ const mov = program.command("mov").description("Publish and manage videos on 4ort.mov");
173
+ mov
174
+ .command("login")
175
+ .description("Sign in to 4ort.mov (PeerTube) and store tokens")
176
+ .option("-s, --server <url>", "Instance URL", "https://4ort.mov")
177
+ .option("-u, --username <user>", "Username (non-interactive; or env FORT_MOV_USERNAME)")
178
+ .option("-p, --password <pass>", "Password (non-interactive; or env FORT_MOV_PASSWORD)")
179
+ .action(movLogin);
180
+ mov
181
+ .command("publish <file>")
182
+ .description("Upload a video file")
183
+ .requiredOption("-t, --title <title>", "Video title")
184
+ .option("-c, --channel <name>", "Target channel (default: first channel)")
185
+ .option("-d, --description <text>", "Description")
186
+ .option("--thumbnail <file>", "Thumbnail image file")
187
+ .option("-p, --privacy <level>", "public|unlisted|private|internal", "unlisted")
188
+ .action(movPublish);
189
+ mov.command("list").description("List your videos").action(movList);
190
+ mov
191
+ .command("channels")
192
+ .description("List your channels (or create one with --create)")
193
+ .option("--create <name>", "Create a channel with this name")
194
+ .action(movChannels);
195
+ mov.command("delete <id>").description("Delete a video by id").action(movDelete);
196
+ // ─────────────────────────────────────────────────────────────────────
197
+ // Web — read the public internet (Reader-Mode fetch, no browser)
198
+ // ─────────────────────────────────────────────────────────────────────
199
+ const web = program
200
+ .command("web")
201
+ .description("Read the public internet — Reader-Mode fetch, no browser/JS");
202
+ web
203
+ .command("get <url>")
204
+ .description("Fetch a URL and return its readable text (our own pages → structured)")
205
+ .option("--json", "Output the structured payload as JSON")
206
+ .option("-m, --max-chars <n>", "Cap extracted text length (default 50000)")
207
+ .action(webGet);
208
+ // ─────────────────────────────────────────────────────────────────────
209
+ // MCP — expose search + web get + kg tools to MCP-native agents over stdio
210
+ // ─────────────────────────────────────────────────────────────────────
211
+ const mcp = program
212
+ .command("mcp")
213
+ .description("4ort MCP server — stdio (default), or `mcp serve` for Streamable HTTP");
214
+ mcp
215
+ .command("stdio", { isDefault: true })
216
+ .description("Run over stdio — for Claude Desktop & local MCP clients that spawn the process")
217
+ .action(mcpStdioCommand);
218
+ mcp
219
+ .command("serve")
220
+ .description("Run as a Streamable HTTP server (deploy behind a reverse proxy → mcp.4ort.xyz)")
221
+ .option("-p, --port <n>", "Port to listen on", "8003")
222
+ .option("-H, --host <addr>", "Bind address", "127.0.0.1")
223
+ .action(mcpServeCommand);
224
+ // ─────────────────────────────────────────────────────────────────────
225
+ // Config inspection
226
+ // ─────────────────────────────────────────────────────────────────────
79
227
  program
80
228
  .command("config")
81
229
  .description("Show config location and current settings")
82
230
  .action(() => {
83
231
  const config = loadConfig();
84
232
  if (!config) {
85
- console.log("Not configured. Run: 4ort register <name>");
233
+ console.log("Not configured. Run: 4ort register <name> or 4ort kg register");
234
+ return;
235
+ }
236
+ console.log(`Config: ${getConfigPath()}`);
237
+ if (config.apiKey) {
238
+ console.log(`\n4ort.net`);
239
+ console.log(` agent: ${config.agentName || "(unset)"}`);
240
+ console.log(` server: ${config.server}`);
241
+ console.log(` api key: ${config.apiKey.slice(0, 12)}…`);
86
242
  }
87
- else {
88
- console.log(`Config: ${getConfigPath()}`);
89
- console.log(`Agent: ${config.agentName}`);
90
- console.log(`Server: ${config.server}`);
91
- console.log(`API Key: ${config.apiKey.slice(0, 8)}...`);
243
+ if (config.kg?.apiKey) {
244
+ console.log(`\n4ort.xyz (knowledge graph)`);
245
+ console.log(` name: ${config.kg.name || "(unset)"}`);
246
+ console.log(` server: ${config.kg.server}`);
247
+ console.log(` api key: ${config.kg.apiKey.slice(0, 12)}…`);
248
+ if (config.kg.tier)
249
+ console.log(` tier: ${config.kg.tier}`);
92
250
  }
93
251
  });
94
252
  program.parse();