@dirxai/cli 0.2.1 → 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 +156 -16
  2. package/package.json +5 -11
  3. package/LICENSE +0 -21
  4. package/README.md +0 -91
package/dist/index.js CHANGED
@@ -675,13 +675,140 @@ var init_provider_map = __esm({
675
675
  }
676
676
  });
677
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
+
678
805
  // src/commands/fs.ts
679
806
  var fs_exports = {};
680
807
  __export(fs_exports, {
681
808
  registerFsCommands: () => registerFsCommands
682
809
  });
683
- function output(result) {
684
- console.log(JSON.stringify(result, null, 2));
810
+ function output(result, jsonMode) {
811
+ console.log(jsonMode ? formatJson(result) : formatCat(result));
685
812
  }
686
813
  function extractDomain(path) {
687
814
  const cleaned = path.replace(/^\/+/, "");
@@ -719,33 +846,40 @@ function handleError(err, cmdPath) {
719
846
  process.exit(1);
720
847
  }
721
848
  }
722
- console.error(JSON.stringify({ error: message }));
849
+ console.error(message);
723
850
  process.exit(1);
724
851
  }
725
852
  function registerFsCommands(program2) {
726
- 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) => {
727
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;
728
860
  const client = await createClient();
729
- const result = await client.execute(`ls ${path}`);
730
- output(result);
861
+ const result = await client.execute(`ls ${normalizedPath}`);
862
+ console.log(jsonMode ? formatJson(result) : formatLs(result));
731
863
  } catch (err) {
732
864
  handleError(err, path);
733
865
  }
734
866
  });
735
867
  program2.command("cat").description("Read file contents from a DirX path").argument("<path>", "File path").action(async (path) => {
736
868
  try {
869
+ const jsonMode = program2.opts().json === true;
737
870
  const client = await createClient();
738
871
  const result = await client.execute(`cat ${path}`);
739
- output(result);
872
+ output(result, jsonMode);
740
873
  } catch (err) {
741
874
  handleError(err, path);
742
875
  }
743
876
  });
744
877
  program2.command("read").description("Read file contents (alias for cat)").argument("<path>", "File path").action(async (path) => {
745
878
  try {
879
+ const jsonMode = program2.opts().json === true;
746
880
  const client = await createClient();
747
881
  const result = await client.execute(`cat ${path}`);
748
- output(result);
882
+ output(result, jsonMode);
749
883
  } catch (err) {
750
884
  handleError(err, path);
751
885
  }
@@ -758,9 +892,10 @@ function registerFsCommands(program2) {
758
892
  const { readFileSync: readFileSync4 } = await import('fs');
759
893
  payload = readFileSync4(opts.file, "utf-8");
760
894
  }
895
+ const jsonMode = program2.opts().json === true;
761
896
  const client = await createClient();
762
897
  const result = await client.execute(`write ${path} ${payload}`);
763
- output(result);
898
+ console.log(jsonMode ? formatJson(result) : formatMutate(result, "Created", path));
764
899
  } catch (err) {
765
900
  handleError(err, path);
766
901
  }
@@ -774,9 +909,10 @@ function registerFsCommands(program2) {
774
909
  const { readFileSync: readFileSync4 } = await import('fs');
775
910
  payload = readFileSync4(opts.file, "utf-8");
776
911
  }
912
+ const jsonMode = program2.opts().json === true;
777
913
  const client = await createClient();
778
914
  const result = await client.execute(`edit ${path} ${payload}`);
779
- output(result);
915
+ console.log(jsonMode ? formatJson(result) : formatMutate(result, "Updated", path));
780
916
  } catch (err) {
781
917
  handleError(err, path);
782
918
  }
@@ -784,27 +920,30 @@ function registerFsCommands(program2) {
784
920
  );
785
921
  program2.command("rm").description("Remove a resource at a DirX path").argument("<path>", "Resource path").action(async (path) => {
786
922
  try {
923
+ const jsonMode = program2.opts().json === true;
787
924
  const client = await createClient();
788
925
  const result = await client.execute(`rm ${path}`);
789
- output(result);
926
+ console.log(jsonMode ? formatJson(result) : formatMutate(result, "Removed", path));
790
927
  } catch (err) {
791
928
  handleError(err, path);
792
929
  }
793
930
  });
794
931
  program2.command("bash").description("Execute a multi-step pipeline on the gateway").argument("<pipeline>", "Pipeline expression").action(async (pipeline) => {
795
932
  try {
933
+ const jsonMode = program2.opts().json === true;
796
934
  const client = await createClient();
797
935
  const result = await client.execute(`bash ${pipeline}`);
798
- output(result);
936
+ output(result, jsonMode);
799
937
  } catch (err) {
800
938
  handleError(err);
801
939
  }
802
940
  });
803
- 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) => {
804
942
  try {
943
+ const jsonMode = program2.opts().json === true;
805
944
  const client = await createClient();
806
945
  const result = await client.execute(`grep ${pattern} ${path}`);
807
- output(result);
946
+ console.log(jsonMode ? formatJson(result) : formatGrep(result));
808
947
  } catch (err) {
809
948
  handleError(err, path);
810
949
  }
@@ -814,6 +953,7 @@ var init_fs = __esm({
814
953
  "src/commands/fs.ts"() {
815
954
  init_client();
816
955
  init_provider_map();
956
+ init_format();
817
957
  }
818
958
  });
819
959
 
@@ -880,7 +1020,7 @@ function registerKeysCommand(program2) {
880
1020
  try {
881
1021
  const client = await createClient();
882
1022
  const result = await client.listByok();
883
- console.log(JSON.stringify(result, null, 2));
1023
+ console.log(JSON.stringify(result));
884
1024
  } catch (err) {
885
1025
  const msg = err instanceof Error ? err.message : String(err);
886
1026
  console.error(`Error: ${msg}`);
@@ -936,7 +1076,7 @@ try {
936
1076
  } catch {
937
1077
  }
938
1078
  var program = new Command();
939
- 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");
940
1080
  program.command("auth").description("Authenticate with the DirX gateway").option("--gateway-url <url>", "Gateway URL (default: https://api.dirx.ai)").action(async (opts) => {
941
1081
  const { runAuth: runAuth2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
942
1082
  await runAuth2({ gatewayUrl: opts.gatewayUrl });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dirxai/cli",
3
- "version": "0.2.1",
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,91 +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 rm <path>` | Remove a resource |
48
- | `dirx grep <pattern> <path>` | Search across services |
49
- | `dirx bash <pipeline>` | Execute multi-step pipeline |
50
-
51
- ### Developer Tools
52
-
53
- | Command | Description |
54
- |---------|-------------|
55
- | `dirx init [dir]` | Initialize DirX in a project |
56
- | `dirx generate [dir]` | Scan and detect route definitions |
57
- | `dirx generate --register` | Scan and auto-register with the gateway |
58
- | `dirx claim <domain>` | Claim domain via DNS verification |
59
- | `dirx register` | Register DIR.md with the gateway |
60
-
61
- ### Configuration
62
-
63
- | Command | Description |
64
- |---------|-------------|
65
- | `dirx auth` | Authenticate with the gateway |
66
- | `dirx keys set <domain>` | Set an API key |
67
- | `dirx keys list` | List stored keys |
68
- | `dirx keys remove <domain>` | Remove a key |
69
- | `dirx status` | Show CLI config and auth status |
70
-
71
- ## Environment Variables
72
-
73
- | Variable | Description | Default |
74
- |----------|-------------|---------|
75
- | `DIRX_GATEWAY_URL` | Gateway URL | `https://api.dirx.ai` |
76
- | `DIRX_TOKEN` | Agent token | — |
77
- | `DIRX_HOME` | Config directory | `~/.dirx` |
78
-
79
- ## Development
80
-
81
- ```bash
82
- git clone https://github.com/dirxai/dirx.git
83
- cd dirx
84
- npm install
85
- npm run build
86
- npm run lint
87
- ```
88
-
89
- ## License
90
-
91
- MIT