@dirxai/cli 0.2.0 → 0.3.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 (4) hide show
  1. package/dist/index.js +271 -106
  2. package/package.json +5 -11
  3. package/LICENSE +0 -21
  4. package/README.md +0 -89
package/dist/index.js CHANGED
@@ -207,12 +207,100 @@ var init_init = __esm({
207
207
  }
208
208
  });
209
209
 
210
+ // src/commands/register.ts
211
+ var register_exports = {};
212
+ __export(register_exports, {
213
+ runRegister: () => runRegister
214
+ });
215
+ async function runRegister(options) {
216
+ const projectDir = options.dir ?? process.cwd();
217
+ const gatewayUrl = options.gatewayUrl ?? process.env.DIRX_GATEWAY_URL ?? "https://api.dirx.ai";
218
+ const domain = options.domain ?? process.env.DIRX_DOMAIN;
219
+ if (!domain) {
220
+ throw new Error(
221
+ "Domain is required. Use --domain or DIRX_DOMAIN env var."
222
+ );
223
+ }
224
+ const token = await resolveToken({
225
+ token: options.token,
226
+ domain,
227
+ gatewayUrl
228
+ });
229
+ const dirMdPath = join(projectDir, "DIR.md");
230
+ let dirMd;
231
+ try {
232
+ dirMd = await readFile(dirMdPath, "utf-8");
233
+ } catch {
234
+ throw new Error(
235
+ `DIR.md not found at ${dirMdPath}. Run 'dirx init' first.`
236
+ );
237
+ }
238
+ if (!dirMd.trim()) {
239
+ throw new Error(`DIR.md is empty at ${dirMdPath}`);
240
+ }
241
+ const baseUrl = gatewayUrl.replace(/\/$/, "");
242
+ const url = `${baseUrl}/registry/services?domain=${encodeURIComponent(domain)}`;
243
+ const res = await fetch(url, {
244
+ method: "POST",
245
+ headers: {
246
+ Authorization: `Bearer ${token}`,
247
+ "Content-Type": "text/markdown"
248
+ },
249
+ body: dirMd
250
+ });
251
+ if (!res.ok) {
252
+ const body = await res.text();
253
+ throw new Error(`Registration failed (${res.status}): ${body}`);
254
+ }
255
+ const result = await res.json();
256
+ console.log(`Registered ${result.name} as ${result.domain}`);
257
+ }
258
+ async function resolveToken(options) {
259
+ if (options.token) return options.token;
260
+ if (process.env.DIRX_PUBLISH_TOKEN) return process.env.DIRX_PUBLISH_TOKEN;
261
+ if (options.domain) {
262
+ const stored = await getToken(options.domain);
263
+ if (stored) return stored;
264
+ const gw = options.gatewayUrl ?? process.env.DIRX_GATEWAY_URL;
265
+ if (gw) {
266
+ const renewed = await renewToken(gw, options.domain);
267
+ if (renewed) return renewed;
268
+ }
269
+ }
270
+ throw new Error(
271
+ "No auth token found. Use `dirx claim <domain>` to obtain a publish token, or provide --token."
272
+ );
273
+ }
274
+ async function renewToken(gatewayUrl, domain) {
275
+ const baseUrl = gatewayUrl.replace(/\/$/, "");
276
+ try {
277
+ const res = await fetch(`${baseUrl}/domains/verify`, {
278
+ method: "POST",
279
+ headers: { "Content-Type": "application/json" },
280
+ body: JSON.stringify({ domain })
281
+ });
282
+ if (!res.ok) return null;
283
+ const data = await res.json();
284
+ if (!data.publishToken) return null;
285
+ await saveToken(domain, data.publishToken);
286
+ console.log(`Token renewed for ${domain}`);
287
+ return data.publishToken;
288
+ } catch {
289
+ return null;
290
+ }
291
+ }
292
+ var init_register = __esm({
293
+ "src/commands/register.ts"() {
294
+ init_credentials();
295
+ }
296
+ });
297
+
210
298
  // src/commands/generate.ts
211
299
  var generate_exports = {};
212
300
  __export(generate_exports, {
213
301
  runGenerate: () => runGenerate
214
302
  });
215
- async function runGenerate(dir) {
303
+ async function runGenerate(dir, opts) {
216
304
  const target = dir === "." ? process.cwd() : dir;
217
305
  const dirJsonPath = join(target, "dir.json");
218
306
  if (!existsSync(dirJsonPath)) {
@@ -242,6 +330,17 @@ No route definitions detected.`);
242
330
  }
243
331
  console.log(`
244
332
  Edit DIR.md and dir.json to describe your API.`);
333
+ if (opts?.register) {
334
+ console.log(`
335
+ Registering with gateway...`);
336
+ const { runRegister: runRegister2 } = await Promise.resolve().then(() => (init_register(), register_exports));
337
+ await runRegister2({
338
+ gatewayUrl: opts.gatewayUrl,
339
+ token: opts.token,
340
+ domain: opts.domain,
341
+ dir: target
342
+ });
343
+ }
245
344
  }
246
345
  function detectFrameworkFromPackage(target) {
247
346
  const pkgPath = join(target, "package.json");
@@ -427,94 +526,6 @@ var init_claim = __esm({
427
526
  }
428
527
  });
429
528
 
430
- // src/commands/register.ts
431
- var register_exports = {};
432
- __export(register_exports, {
433
- runRegister: () => runRegister
434
- });
435
- async function runRegister(options) {
436
- const projectDir = options.dir ?? process.cwd();
437
- const gatewayUrl = options.gatewayUrl ?? process.env.DIRX_GATEWAY_URL ?? "https://api.dirx.ai";
438
- const domain = options.domain ?? process.env.DIRX_DOMAIN;
439
- if (!domain) {
440
- throw new Error(
441
- "Domain is required. Use --domain or DIRX_DOMAIN env var."
442
- );
443
- }
444
- const token = await resolveToken({
445
- token: options.token,
446
- domain,
447
- gatewayUrl
448
- });
449
- const dirMdPath = join(projectDir, "DIR.md");
450
- let dirMd;
451
- try {
452
- dirMd = await readFile(dirMdPath, "utf-8");
453
- } catch {
454
- throw new Error(
455
- `DIR.md not found at ${dirMdPath}. Run 'dirx init' first.`
456
- );
457
- }
458
- if (!dirMd.trim()) {
459
- throw new Error(`DIR.md is empty at ${dirMdPath}`);
460
- }
461
- const baseUrl = gatewayUrl.replace(/\/$/, "");
462
- const url = `${baseUrl}/registry/services?domain=${encodeURIComponent(domain)}`;
463
- const res = await fetch(url, {
464
- method: "POST",
465
- headers: {
466
- Authorization: `Bearer ${token}`,
467
- "Content-Type": "text/markdown"
468
- },
469
- body: dirMd
470
- });
471
- if (!res.ok) {
472
- const body = await res.text();
473
- throw new Error(`Registration failed (${res.status}): ${body}`);
474
- }
475
- const result = await res.json();
476
- console.log(`Registered ${result.name} as ${result.domain}`);
477
- }
478
- async function resolveToken(options) {
479
- if (options.token) return options.token;
480
- if (process.env.DIRX_PUBLISH_TOKEN) return process.env.DIRX_PUBLISH_TOKEN;
481
- if (options.domain) {
482
- const stored = await getToken(options.domain);
483
- if (stored) return stored;
484
- const gw = options.gatewayUrl ?? process.env.DIRX_GATEWAY_URL;
485
- if (gw) {
486
- const renewed = await renewToken(gw, options.domain);
487
- if (renewed) return renewed;
488
- }
489
- }
490
- throw new Error(
491
- "No auth token found. Use `dirx claim <domain>` to obtain a publish token, or provide --token."
492
- );
493
- }
494
- async function renewToken(gatewayUrl, domain) {
495
- const baseUrl = gatewayUrl.replace(/\/$/, "");
496
- try {
497
- const res = await fetch(`${baseUrl}/domains/verify`, {
498
- method: "POST",
499
- headers: { "Content-Type": "application/json" },
500
- body: JSON.stringify({ domain })
501
- });
502
- if (!res.ok) return null;
503
- const data = await res.json();
504
- if (!data.publishToken) return null;
505
- await saveToken(domain, data.publishToken);
506
- console.log(`Token renewed for ${domain}`);
507
- return data.publishToken;
508
- } catch {
509
- return null;
510
- }
511
- }
512
- var init_register = __esm({
513
- "src/commands/register.ts"() {
514
- init_credentials();
515
- }
516
- });
517
-
518
529
  // src/commands/status.ts
519
530
  var status_exports = {};
520
531
  __export(status_exports, {
@@ -664,13 +675,140 @@ var init_provider_map = __esm({
664
675
  }
665
676
  });
666
677
 
678
+ // src/format.ts
679
+ function isSearchResults(data) {
680
+ if (!Array.isArray(data) || data.length === 0) return false;
681
+ const first = data[0];
682
+ return typeof first === "object" && first !== null && "domain" in first && ("title" in first || "name" in first);
683
+ }
684
+ function isEndpointResults(data) {
685
+ if (!Array.isArray(data) || data.length === 0) return false;
686
+ const first = data[0];
687
+ return typeof first === "object" && first !== null && "method" in first && "path" in first;
688
+ }
689
+ function extractPayload(result) {
690
+ if (typeof result !== "object" || result === null) return result;
691
+ const obj = result;
692
+ if ("ok" in obj && "data" in obj) {
693
+ const data = obj.data;
694
+ if (typeof data === "object" && data !== null && "results" in data) {
695
+ return data.results;
696
+ }
697
+ return data;
698
+ }
699
+ if ("results" in obj && "query" in obj) return obj.results;
700
+ return result;
701
+ }
702
+ function formatLs(result) {
703
+ const payload = extractPayload(result);
704
+ if (Array.isArray(payload)) {
705
+ if (payload.length === 0) return "(empty)";
706
+ return payload.map((item) => typeof item === "string" ? item : JSON.stringify(item)).join("\n");
707
+ }
708
+ if (typeof payload === "object" && payload !== null && "items" in payload) {
709
+ const items = payload.items;
710
+ if (!Array.isArray(items) || items.length === 0) return "(empty)";
711
+ const rich = items.some(
712
+ (item) => typeof item === "object" && item !== null && "path" in item
713
+ );
714
+ if (!rich) {
715
+ return items.map((item) => typeof item === "string" ? item : JSON.stringify(item)).join("\n");
716
+ }
717
+ const entries = items;
718
+ const maxPath = Math.min(
719
+ 40,
720
+ Math.max(8, ...entries.map((e) => (e.path ?? "").length))
721
+ );
722
+ return entries.map((entry) => {
723
+ const path = entry.path ?? "<unknown>";
724
+ const title = entry.title ?? "";
725
+ if (title) {
726
+ return `${path.padEnd(maxPath)} ${title}`;
727
+ }
728
+ return path;
729
+ }).join("\n");
730
+ }
731
+ return JSON.stringify(payload);
732
+ }
733
+ function formatGrep(result) {
734
+ const payload = extractPayload(result);
735
+ if (isSearchResults(payload)) {
736
+ if (payload.length === 0) return "(no matches)";
737
+ let domainCount = 0;
738
+ let endpointCount = 0;
739
+ const blocks = payload.map((s) => {
740
+ domainCount++;
741
+ const name = s.title || s.name || "";
742
+ const header = name ? `${s.domain} ${name}` : s.domain;
743
+ const lines = [header];
744
+ if (s.description) {
745
+ const desc = s.description.length > 80 ? s.description.slice(0, 77) + "..." : s.description;
746
+ lines.push(` ${desc}`);
747
+ }
748
+ const endpoints = s.matched_endpoints;
749
+ if (endpoints && endpoints.length > 0) {
750
+ lines[0] += ` \xB7 ${endpoints.length} matched`;
751
+ for (const ep of endpoints) {
752
+ endpointCount++;
753
+ const method = (ep.method ?? "").padEnd(6);
754
+ const desc = ep.description ? ` -- ${ep.description}` : "";
755
+ lines.push(` ${method} ${ep.path}${desc}`);
756
+ }
757
+ }
758
+ return lines.join("\n");
759
+ });
760
+ const output2 = blocks.join("\n\n");
761
+ if (domainCount > 0 || endpointCount > 0) {
762
+ const parts = [];
763
+ if (domainCount > 0) parts.push(`${domainCount} service${domainCount === 1 ? "" : "s"}`);
764
+ if (endpointCount > 0) parts.push(`${endpointCount} endpoint${endpointCount === 1 ? "" : "s"}`);
765
+ return `${output2}
766
+
767
+ -- ${parts.join(", ")} matched`;
768
+ }
769
+ return output2;
770
+ }
771
+ if (isEndpointResults(payload)) {
772
+ if (payload.length === 0) return "(no matches)";
773
+ return payload.map((ep) => {
774
+ const method = (ep.method ?? "").padEnd(6);
775
+ const desc = ep.description ? ` -- ${ep.description}` : "";
776
+ return `${method} ${ep.path}${desc}`;
777
+ }).join("\n");
778
+ }
779
+ return JSON.stringify(payload);
780
+ }
781
+ function formatCat(result) {
782
+ const payload = extractPayload(result);
783
+ if (typeof payload === "string") return payload;
784
+ return JSON.stringify(payload);
785
+ }
786
+ function formatMutate(result, verb, path) {
787
+ const payload = extractPayload(result);
788
+ if (payload === null || payload === void 0) {
789
+ return `${verb}: ${path}`;
790
+ }
791
+ if (typeof payload === "object" && Object.keys(payload).length === 0) {
792
+ return `${verb}: ${path}`;
793
+ }
794
+ return `${verb}: ${path}
795
+ ${JSON.stringify(payload)}`;
796
+ }
797
+ function formatJson(result) {
798
+ return JSON.stringify(result);
799
+ }
800
+ var init_format = __esm({
801
+ "src/format.ts"() {
802
+ }
803
+ });
804
+
667
805
  // src/commands/fs.ts
668
806
  var fs_exports = {};
669
807
  __export(fs_exports, {
670
808
  registerFsCommands: () => registerFsCommands
671
809
  });
672
- function output(result) {
673
- console.log(JSON.stringify(result, null, 2));
810
+ function output(result, jsonMode) {
811
+ console.log(jsonMode ? formatJson(result) : formatCat(result));
674
812
  }
675
813
  function extractDomain(path) {
676
814
  const cleaned = path.replace(/^\/+/, "");
@@ -708,33 +846,40 @@ function handleError(err, cmdPath) {
708
846
  process.exit(1);
709
847
  }
710
848
  }
711
- console.error(JSON.stringify({ error: message }));
849
+ console.error(message);
712
850
  process.exit(1);
713
851
  }
714
852
  function registerFsCommands(program2) {
715
- program2.command("ls").description("List directory contents in the DirX path space").argument("<path>", "Directory path (e.g. /net/)").action(async (path) => {
853
+ program2.command("ls").description("List directory contents in the DirX path space").argument("[path]", "Directory path (e.g. /net/)", "/").action(async (path) => {
716
854
  try {
855
+ let normalizedPath = path.trim();
856
+ if (normalizedPath.length > 1 && normalizedPath.endsWith("/")) {
857
+ normalizedPath = normalizedPath.replace(/\/+$/, "");
858
+ }
859
+ const jsonMode = program2.opts().json === true;
717
860
  const client = await createClient();
718
- const result = await client.execute(`ls ${path}`);
719
- output(result);
861
+ const result = await client.execute(`ls ${normalizedPath}`);
862
+ console.log(jsonMode ? formatJson(result) : formatLs(result));
720
863
  } catch (err) {
721
864
  handleError(err, path);
722
865
  }
723
866
  });
724
867
  program2.command("cat").description("Read file contents from a DirX path").argument("<path>", "File path").action(async (path) => {
725
868
  try {
869
+ const jsonMode = program2.opts().json === true;
726
870
  const client = await createClient();
727
871
  const result = await client.execute(`cat ${path}`);
728
- output(result);
872
+ output(result, jsonMode);
729
873
  } catch (err) {
730
874
  handleError(err, path);
731
875
  }
732
876
  });
733
877
  program2.command("read").description("Read file contents (alias for cat)").argument("<path>", "File path").action(async (path) => {
734
878
  try {
879
+ const jsonMode = program2.opts().json === true;
735
880
  const client = await createClient();
736
881
  const result = await client.execute(`cat ${path}`);
737
- output(result);
882
+ output(result, jsonMode);
738
883
  } catch (err) {
739
884
  handleError(err, path);
740
885
  }
@@ -747,9 +892,10 @@ function registerFsCommands(program2) {
747
892
  const { readFileSync: readFileSync4 } = await import('fs');
748
893
  payload = readFileSync4(opts.file, "utf-8");
749
894
  }
895
+ const jsonMode = program2.opts().json === true;
750
896
  const client = await createClient();
751
897
  const result = await client.execute(`write ${path} ${payload}`);
752
- output(result);
898
+ console.log(jsonMode ? formatJson(result) : formatMutate(result, "Created", path));
753
899
  } catch (err) {
754
900
  handleError(err, path);
755
901
  }
@@ -763,28 +909,41 @@ function registerFsCommands(program2) {
763
909
  const { readFileSync: readFileSync4 } = await import('fs');
764
910
  payload = readFileSync4(opts.file, "utf-8");
765
911
  }
912
+ const jsonMode = program2.opts().json === true;
766
913
  const client = await createClient();
767
914
  const result = await client.execute(`edit ${path} ${payload}`);
768
- output(result);
915
+ console.log(jsonMode ? formatJson(result) : formatMutate(result, "Updated", path));
769
916
  } catch (err) {
770
917
  handleError(err, path);
771
918
  }
772
919
  }
773
920
  );
921
+ program2.command("rm").description("Remove a resource at a DirX path").argument("<path>", "Resource path").action(async (path) => {
922
+ try {
923
+ const jsonMode = program2.opts().json === true;
924
+ const client = await createClient();
925
+ const result = await client.execute(`rm ${path}`);
926
+ console.log(jsonMode ? formatJson(result) : formatMutate(result, "Removed", path));
927
+ } catch (err) {
928
+ handleError(err, path);
929
+ }
930
+ });
774
931
  program2.command("bash").description("Execute a multi-step pipeline on the gateway").argument("<pipeline>", "Pipeline expression").action(async (pipeline) => {
775
932
  try {
933
+ const jsonMode = program2.opts().json === true;
776
934
  const client = await createClient();
777
935
  const result = await client.execute(`bash ${pipeline}`);
778
- output(result);
936
+ output(result, jsonMode);
779
937
  } catch (err) {
780
938
  handleError(err);
781
939
  }
782
940
  });
783
- program2.command("grep").description("Search across services in the DirX path space").argument("<pattern>", "Search pattern").argument("<path>", "Search scope path").action(async (pattern, path) => {
941
+ program2.command("grep").description("Search across services in the DirX path space").argument("<pattern>", "Search pattern").argument("[path]", "Search scope path", "/").action(async (pattern, path) => {
784
942
  try {
943
+ const jsonMode = program2.opts().json === true;
785
944
  const client = await createClient();
786
945
  const result = await client.execute(`grep ${pattern} ${path}`);
787
- output(result);
946
+ console.log(jsonMode ? formatJson(result) : formatGrep(result));
788
947
  } catch (err) {
789
948
  handleError(err, path);
790
949
  }
@@ -794,6 +953,7 @@ var init_fs = __esm({
794
953
  "src/commands/fs.ts"() {
795
954
  init_client();
796
955
  init_provider_map();
956
+ init_format();
797
957
  }
798
958
  });
799
959
 
@@ -860,7 +1020,7 @@ function registerKeysCommand(program2) {
860
1020
  try {
861
1021
  const client = await createClient();
862
1022
  const result = await client.listByok();
863
- console.log(JSON.stringify(result, null, 2));
1023
+ console.log(JSON.stringify(result));
864
1024
  } catch (err) {
865
1025
  const msg = err instanceof Error ? err.message : String(err);
866
1026
  console.error(`Error: ${msg}`);
@@ -916,7 +1076,7 @@ try {
916
1076
  } catch {
917
1077
  }
918
1078
  var program = new Command();
919
- program.name("dirx").description("DirX \u2014 Unified Gateway & CLI for Agents").version(version);
1079
+ program.name("dirx").description("DirX \u2014 Unified Gateway & CLI for Agents").version(version).option("--json", "Output raw JSON instead of human-readable text");
920
1080
  program.command("auth").description("Authenticate with the DirX gateway").option("--gateway-url <url>", "Gateway URL (default: https://api.dirx.ai)").action(async (opts) => {
921
1081
  const { runAuth: runAuth2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
922
1082
  await runAuth2({ gatewayUrl: opts.gatewayUrl });
@@ -925,9 +1085,14 @@ program.command("init").description("Initialize DirX in the current project").ar
925
1085
  const { runInit: runInit2 } = await Promise.resolve().then(() => (init_init(), init_exports));
926
1086
  await runInit2(dir);
927
1087
  });
928
- program.command("generate").description("Scan project and detect route definitions").argument("[dir]", "Project directory", ".").action(async (dir) => {
1088
+ program.command("generate").description("Scan project and generate DIR.md, optionally register").argument("[dir]", "Project directory", ".").option("--register", "Register the service with the gateway after generating").option("--gateway-url <url>", "Gateway URL for registration").option("--token <token>", "Auth token for registration").option("--domain <domain>", "Domain name for the service").action(async (dir, opts) => {
929
1089
  const { runGenerate: runGenerate2 } = await Promise.resolve().then(() => (init_generate(), generate_exports));
930
- await runGenerate2(dir);
1090
+ await runGenerate2(dir, {
1091
+ register: opts.register,
1092
+ gatewayUrl: opts.gatewayUrl,
1093
+ token: opts.token,
1094
+ domain: opts.domain
1095
+ });
931
1096
  });
932
1097
  program.command("claim").description("Claim domain ownership via DNS verification").argument("<domain>", "Domain to claim").option("--verify", "Verify DNS record and obtain publish token").option("--gateway-url <url>", "Gateway URL").action(
933
1098
  async (domain, opts) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dirxai/cli",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "DirX — Unified Gateway & CLI for Agents",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -9,22 +9,16 @@
9
9
  },
10
10
  "scripts": {
11
11
  "build": "tsup",
12
- "dev": "tsup --watch",
13
- "lint": "tsc --noEmit",
14
- "test": "vitest run"
12
+ "dev": "tsup --watch"
15
13
  },
16
14
  "dependencies": {
15
+ "@dirxai/core": "^0.3.0",
17
16
  "commander": "^13.0.0"
18
17
  },
19
- "devDependencies": {
20
- "@types/node": "^22.0.0",
21
- "tsup": "^8.0.0",
22
- "typescript": "^5.7.0",
23
- "vitest": "^4.0.0"
24
- },
25
18
  "repository": {
26
19
  "type": "git",
27
- "url": "https://github.com/dirxai/dirx.git"
20
+ "url": "https://github.com/dirxai/dirx.git",
21
+ "directory": "packages/cli"
28
22
  },
29
23
  "homepage": "https://dirx.ai",
30
24
  "keywords": [
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 DirX AI
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
package/README.md DELETED
@@ -1,89 +0,0 @@
1
- # DirX — Unified Gateway & CLI for Agents
2
-
3
- [![npm version](https://img.shields.io/npm/v/@dirxai/cli.svg)](https://www.npmjs.com/package/@dirxai/cli)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
-
6
- DirX gives AI agents a unified, file-system-like interface to discover and interact with internet APIs — with built-in governance, access control, and auditing.
7
-
8
- ## Install
9
-
10
- ```bash
11
- npm install -g @dirxai/cli
12
- ```
13
-
14
- ## Quick Start
15
-
16
- ```bash
17
- # Authenticate with the gateway
18
- dirx auth
19
-
20
- # Browse the API directory
21
- dirx ls /
22
- dirx ls /net/
23
-
24
- # Read service descriptions
25
- dirx cat /net/api.github.com/DIR.md
26
-
27
- # Search across services
28
- dirx grep "weather" /net/
29
-
30
- # Write data
31
- dirx write /net/api.example.com/data -d '{"key": "value"}'
32
-
33
- # Manage API keys (BYOK)
34
- dirx keys set api.github.com --token ghp_xxxx --sync
35
- ```
36
-
37
- ## Commands
38
-
39
- ### Agent Commands
40
-
41
- | Command | Description |
42
- |---------|-------------|
43
- | `dirx ls <path>` | List directory contents |
44
- | `dirx cat <path>` | Read file contents |
45
- | `dirx write <path>` | Write data |
46
- | `dirx edit <path>` | Partial update |
47
- | `dirx grep <pattern> <path>` | Search across services |
48
- | `dirx bash <pipeline>` | Execute multi-step pipeline |
49
-
50
- ### Developer Tools
51
-
52
- | Command | Description |
53
- |---------|-------------|
54
- | `dirx init [dir]` | Initialize DirX in a project |
55
- | `dirx generate [dir]` | Scan and detect route definitions |
56
- | `dirx claim <domain>` | Claim domain via DNS verification |
57
- | `dirx register` | Register DIR.md with the gateway |
58
-
59
- ### Configuration
60
-
61
- | Command | Description |
62
- |---------|-------------|
63
- | `dirx auth` | Authenticate with the gateway |
64
- | `dirx keys set <domain>` | Set an API key |
65
- | `dirx keys list` | List stored keys |
66
- | `dirx keys remove <domain>` | Remove a key |
67
- | `dirx status` | Show CLI config and auth status |
68
-
69
- ## Environment Variables
70
-
71
- | Variable | Description | Default |
72
- |----------|-------------|---------|
73
- | `DIRX_GATEWAY_URL` | Gateway URL | `https://api.dirx.ai` |
74
- | `DIRX_TOKEN` | Agent token | — |
75
- | `DIRX_HOME` | Config directory | `~/.dirx` |
76
-
77
- ## Development
78
-
79
- ```bash
80
- git clone https://github.com/dirxai/dirx.git
81
- cd dirx
82
- npm install
83
- npm run build
84
- npm run lint
85
- ```
86
-
87
- ## License
88
-
89
- MIT