@dirxai/cli 0.2.1 → 0.3.1
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/dist/index.js +167 -175
- package/package.json +5 -11
- package/LICENSE +0 -21
- package/README.md +0 -91
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { readFileSync, existsSync, mkdirSync, writeFileSync,
|
|
3
|
-
import { dirname, resolve, join
|
|
2
|
+
import { readFileSync, existsSync, mkdirSync, writeFileSync, chmodSync } from 'fs';
|
|
3
|
+
import { dirname, resolve, join } from 'path';
|
|
4
4
|
import { homedir } from 'os';
|
|
5
|
+
import { detectFramework, scanRoutes, getAuthHint } from '@dirxai/core';
|
|
5
6
|
import { readFile } from 'fs/promises';
|
|
6
7
|
import { fileURLToPath } from 'url';
|
|
7
8
|
import { Command } from 'commander';
|
|
@@ -184,24 +185,6 @@ Next steps:`);
|
|
|
184
185
|
console.log(` 2. Run 'dirx generate' to scan routes`);
|
|
185
186
|
console.log(` 3. Run 'dirx register --domain <your-domain>' to publish`);
|
|
186
187
|
}
|
|
187
|
-
function detectFramework(target) {
|
|
188
|
-
if (existsSync(join(target, "Cargo.toml"))) {
|
|
189
|
-
return { lang: "rust", framework: "axum" };
|
|
190
|
-
}
|
|
191
|
-
if (existsSync(join(target, "go.mod"))) {
|
|
192
|
-
return { lang: "go", framework: "net/http" };
|
|
193
|
-
}
|
|
194
|
-
if (existsSync(join(target, "package.json"))) {
|
|
195
|
-
if (existsSync(join(target, "next.config.js")) || existsSync(join(target, "next.config.mjs"))) {
|
|
196
|
-
return { lang: "node", framework: "nextjs" };
|
|
197
|
-
}
|
|
198
|
-
return { lang: "node", framework: "express" };
|
|
199
|
-
}
|
|
200
|
-
if (existsSync(join(target, "requirements.txt")) || existsSync(join(target, "pyproject.toml"))) {
|
|
201
|
-
return { lang: "python", framework: "fastapi" };
|
|
202
|
-
}
|
|
203
|
-
return { lang: "unknown", framework: "generic" };
|
|
204
|
-
}
|
|
205
188
|
var init_init = __esm({
|
|
206
189
|
"src/commands/init.ts"() {
|
|
207
190
|
}
|
|
@@ -310,12 +293,8 @@ async function runGenerate(dir, opts) {
|
|
|
310
293
|
process.exitCode = 1;
|
|
311
294
|
return;
|
|
312
295
|
}
|
|
313
|
-
const { framework } =
|
|
314
|
-
const
|
|
315
|
-
const routes = [];
|
|
316
|
-
if (patterns.length > 0) {
|
|
317
|
-
scanDir(target, target, patterns, framework, routes, 0);
|
|
318
|
-
}
|
|
296
|
+
const { framework } = detectFramework(target);
|
|
297
|
+
const routes = scanRoutes(target, framework);
|
|
319
298
|
console.log(`Scanned ${target} (${framework})`);
|
|
320
299
|
if (routes.length > 0) {
|
|
321
300
|
console.log(`
|
|
@@ -342,106 +321,8 @@ Registering with gateway...`);
|
|
|
342
321
|
});
|
|
343
322
|
}
|
|
344
323
|
}
|
|
345
|
-
function detectFrameworkFromPackage(target) {
|
|
346
|
-
const pkgPath = join(target, "package.json");
|
|
347
|
-
if (existsSync(pkgPath)) {
|
|
348
|
-
try {
|
|
349
|
-
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
350
|
-
const deps = {
|
|
351
|
-
...pkg.dependencies,
|
|
352
|
-
...pkg.devDependencies
|
|
353
|
-
};
|
|
354
|
-
if (deps.next) return { framework: "nextjs" };
|
|
355
|
-
if (deps.hono) return { framework: "hono" };
|
|
356
|
-
if (deps.fastify) return { framework: "fastify" };
|
|
357
|
-
if (deps.express) return { framework: "express" };
|
|
358
|
-
} catch {
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
if (existsSync(join(target, "go.mod")))
|
|
362
|
-
return { framework: "go" };
|
|
363
|
-
if (existsSync(join(target, "Cargo.toml")))
|
|
364
|
-
return { framework: "axum" };
|
|
365
|
-
if (existsSync(join(target, "requirements.txt")) || existsSync(join(target, "pyproject.toml")))
|
|
366
|
-
return { framework: "fastapi" };
|
|
367
|
-
return { framework: "generic" };
|
|
368
|
-
}
|
|
369
|
-
function getRoutePatterns(framework) {
|
|
370
|
-
switch (framework) {
|
|
371
|
-
case "express":
|
|
372
|
-
case "hono":
|
|
373
|
-
case "fastify":
|
|
374
|
-
return [".get(", ".post(", ".put(", ".delete(", ".patch(", "router."];
|
|
375
|
-
case "nextjs":
|
|
376
|
-
return ["export default", "export async function"];
|
|
377
|
-
case "fastapi":
|
|
378
|
-
return ["@app.get", "@app.post", "@app.put", "@app.delete", "@router."];
|
|
379
|
-
case "go":
|
|
380
|
-
return ["HandleFunc(", "Get(", "Post(", "Put(", "Delete(", "r.Route("];
|
|
381
|
-
case "axum":
|
|
382
|
-
return [".route(", ".get(", ".post(", ".put(", ".delete("];
|
|
383
|
-
default:
|
|
384
|
-
return [];
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
function scanDir(root, dir, patterns, framework, routes, depth) {
|
|
388
|
-
if (depth > MAX_SCAN_DEPTH) return;
|
|
389
|
-
let entries;
|
|
390
|
-
try {
|
|
391
|
-
entries = readdirSync(dir);
|
|
392
|
-
} catch {
|
|
393
|
-
return;
|
|
394
|
-
}
|
|
395
|
-
for (const name of entries) {
|
|
396
|
-
if (SKIP_DIRS.has(name)) continue;
|
|
397
|
-
const fullPath = join(dir, name);
|
|
398
|
-
let stat;
|
|
399
|
-
try {
|
|
400
|
-
stat = statSync(fullPath);
|
|
401
|
-
} catch {
|
|
402
|
-
continue;
|
|
403
|
-
}
|
|
404
|
-
if (stat.isDirectory()) {
|
|
405
|
-
scanDir(root, fullPath, patterns, framework, routes, depth + 1);
|
|
406
|
-
continue;
|
|
407
|
-
}
|
|
408
|
-
if (!stat.isFile()) continue;
|
|
409
|
-
if (!SCAN_EXTENSIONS.has(extname(name))) continue;
|
|
410
|
-
try {
|
|
411
|
-
const content = readFileSync(fullPath, "utf-8");
|
|
412
|
-
if (patterns.some((p) => content.includes(p))) {
|
|
413
|
-
routes.push({
|
|
414
|
-
file: relative(root, fullPath),
|
|
415
|
-
framework
|
|
416
|
-
});
|
|
417
|
-
}
|
|
418
|
-
} catch {
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
var MAX_SCAN_DEPTH, SKIP_DIRS, SCAN_EXTENSIONS;
|
|
423
324
|
var init_generate = __esm({
|
|
424
325
|
"src/commands/generate.ts"() {
|
|
425
|
-
MAX_SCAN_DEPTH = 8;
|
|
426
|
-
SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
427
|
-
"node_modules",
|
|
428
|
-
".git",
|
|
429
|
-
"target",
|
|
430
|
-
"__pycache__",
|
|
431
|
-
"vendor",
|
|
432
|
-
"dist",
|
|
433
|
-
"build",
|
|
434
|
-
".next"
|
|
435
|
-
]);
|
|
436
|
-
SCAN_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
437
|
-
".ts",
|
|
438
|
-
".tsx",
|
|
439
|
-
".js",
|
|
440
|
-
".jsx",
|
|
441
|
-
".py",
|
|
442
|
-
".go",
|
|
443
|
-
".rs"
|
|
444
|
-
]);
|
|
445
326
|
}
|
|
446
327
|
});
|
|
447
328
|
|
|
@@ -643,35 +524,130 @@ var init_client = __esm({
|
|
|
643
524
|
}
|
|
644
525
|
});
|
|
645
526
|
|
|
646
|
-
// src/
|
|
647
|
-
function
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
527
|
+
// src/format.ts
|
|
528
|
+
function isSearchResults(data) {
|
|
529
|
+
if (!Array.isArray(data) || data.length === 0) return false;
|
|
530
|
+
const first = data[0];
|
|
531
|
+
return typeof first === "object" && first !== null && "domain" in first && ("title" in first || "name" in first);
|
|
532
|
+
}
|
|
533
|
+
function isEndpointResults(data) {
|
|
534
|
+
if (!Array.isArray(data) || data.length === 0) return false;
|
|
535
|
+
const first = data[0];
|
|
536
|
+
return typeof first === "object" && first !== null && "method" in first && "path" in first;
|
|
537
|
+
}
|
|
538
|
+
function extractPayload(result) {
|
|
539
|
+
if (typeof result !== "object" || result === null) return result;
|
|
540
|
+
const obj = result;
|
|
541
|
+
if ("ok" in obj && "data" in obj) {
|
|
542
|
+
const data = obj.data;
|
|
543
|
+
if (typeof data === "object" && data !== null && "results" in data) {
|
|
544
|
+
return data.results;
|
|
545
|
+
}
|
|
546
|
+
return data;
|
|
547
|
+
}
|
|
548
|
+
if ("results" in obj && "query" in obj) return obj.results;
|
|
549
|
+
return result;
|
|
550
|
+
}
|
|
551
|
+
function formatLs(result) {
|
|
552
|
+
const payload = extractPayload(result);
|
|
553
|
+
if (Array.isArray(payload)) {
|
|
554
|
+
if (payload.length === 0) return "(empty)";
|
|
555
|
+
return payload.map((item) => typeof item === "string" ? item : JSON.stringify(item)).join("\n");
|
|
556
|
+
}
|
|
557
|
+
if (typeof payload === "object" && payload !== null && "items" in payload) {
|
|
558
|
+
const items = payload.items;
|
|
559
|
+
if (!Array.isArray(items) || items.length === 0) return "(empty)";
|
|
560
|
+
const rich = items.some(
|
|
561
|
+
(item) => typeof item === "object" && item !== null && "path" in item
|
|
562
|
+
);
|
|
563
|
+
if (!rich) {
|
|
564
|
+
return items.map((item) => typeof item === "string" ? item : JSON.stringify(item)).join("\n");
|
|
565
|
+
}
|
|
566
|
+
const entries = items;
|
|
567
|
+
const maxPath = Math.min(
|
|
568
|
+
40,
|
|
569
|
+
Math.max(8, ...entries.map((e) => (e.path ?? "").length))
|
|
570
|
+
);
|
|
571
|
+
return entries.map((entry) => {
|
|
572
|
+
const path = entry.path ?? "<unknown>";
|
|
573
|
+
const title = entry.title ?? "";
|
|
574
|
+
if (title) {
|
|
575
|
+
return `${path.padEnd(maxPath)} ${title}`;
|
|
673
576
|
}
|
|
674
|
-
|
|
577
|
+
return path;
|
|
578
|
+
}).join("\n");
|
|
579
|
+
}
|
|
580
|
+
return JSON.stringify(payload);
|
|
581
|
+
}
|
|
582
|
+
function formatGrep(result) {
|
|
583
|
+
const payload = extractPayload(result);
|
|
584
|
+
if (isSearchResults(payload)) {
|
|
585
|
+
if (payload.length === 0) return "(no matches)";
|
|
586
|
+
let domainCount = 0;
|
|
587
|
+
let endpointCount = 0;
|
|
588
|
+
const blocks = payload.map((s) => {
|
|
589
|
+
domainCount++;
|
|
590
|
+
const name = s.title || s.name || "";
|
|
591
|
+
const header = name ? `${s.domain} ${name}` : s.domain;
|
|
592
|
+
const lines = [header];
|
|
593
|
+
if (s.description) {
|
|
594
|
+
const desc = s.description.length > 80 ? s.description.slice(0, 77) + "..." : s.description;
|
|
595
|
+
lines.push(` ${desc}`);
|
|
596
|
+
}
|
|
597
|
+
const endpoints = s.matched_endpoints;
|
|
598
|
+
if (endpoints && endpoints.length > 0) {
|
|
599
|
+
lines[0] += ` \xB7 ${endpoints.length} matched`;
|
|
600
|
+
for (const ep of endpoints) {
|
|
601
|
+
endpointCount++;
|
|
602
|
+
const method = (ep.method ?? "").padEnd(6);
|
|
603
|
+
const desc = ep.description ? ` -- ${ep.description}` : "";
|
|
604
|
+
lines.push(` ${method} ${ep.path}${desc}`);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
return lines.join("\n");
|
|
608
|
+
});
|
|
609
|
+
const output2 = blocks.join("\n\n");
|
|
610
|
+
if (domainCount > 0 || endpointCount > 0) {
|
|
611
|
+
const parts = [];
|
|
612
|
+
if (domainCount > 0) parts.push(`${domainCount} service${domainCount === 1 ? "" : "s"}`);
|
|
613
|
+
if (endpointCount > 0) parts.push(`${endpointCount} endpoint${endpointCount === 1 ? "" : "s"}`);
|
|
614
|
+
return `${output2}
|
|
615
|
+
|
|
616
|
+
-- ${parts.join(", ")} matched`;
|
|
617
|
+
}
|
|
618
|
+
return output2;
|
|
619
|
+
}
|
|
620
|
+
if (isEndpointResults(payload)) {
|
|
621
|
+
if (payload.length === 0) return "(no matches)";
|
|
622
|
+
return payload.map((ep) => {
|
|
623
|
+
const method = (ep.method ?? "").padEnd(6);
|
|
624
|
+
const desc = ep.description ? ` -- ${ep.description}` : "";
|
|
625
|
+
return `${method} ${ep.path}${desc}`;
|
|
626
|
+
}).join("\n");
|
|
627
|
+
}
|
|
628
|
+
return JSON.stringify(payload);
|
|
629
|
+
}
|
|
630
|
+
function formatCat(result) {
|
|
631
|
+
const payload = extractPayload(result);
|
|
632
|
+
if (typeof payload === "string") return payload;
|
|
633
|
+
return JSON.stringify(payload);
|
|
634
|
+
}
|
|
635
|
+
function formatMutate(result, verb, path) {
|
|
636
|
+
const payload = extractPayload(result);
|
|
637
|
+
if (payload === null || payload === void 0) {
|
|
638
|
+
return `${verb}: ${path}`;
|
|
639
|
+
}
|
|
640
|
+
if (typeof payload === "object" && Object.keys(payload).length === 0) {
|
|
641
|
+
return `${verb}: ${path}`;
|
|
642
|
+
}
|
|
643
|
+
return `${verb}: ${path}
|
|
644
|
+
${JSON.stringify(payload)}`;
|
|
645
|
+
}
|
|
646
|
+
function formatJson(result) {
|
|
647
|
+
return JSON.stringify(result);
|
|
648
|
+
}
|
|
649
|
+
var init_format = __esm({
|
|
650
|
+
"src/format.ts"() {
|
|
675
651
|
}
|
|
676
652
|
});
|
|
677
653
|
|
|
@@ -680,8 +656,8 @@ var fs_exports = {};
|
|
|
680
656
|
__export(fs_exports, {
|
|
681
657
|
registerFsCommands: () => registerFsCommands
|
|
682
658
|
});
|
|
683
|
-
function output(result) {
|
|
684
|
-
console.log(
|
|
659
|
+
function output(result, jsonMode) {
|
|
660
|
+
console.log(jsonMode ? formatJson(result) : formatCat(result));
|
|
685
661
|
}
|
|
686
662
|
function extractDomain(path) {
|
|
687
663
|
const cleaned = path.replace(/^\/+/, "");
|
|
@@ -719,33 +695,40 @@ function handleError(err, cmdPath) {
|
|
|
719
695
|
process.exit(1);
|
|
720
696
|
}
|
|
721
697
|
}
|
|
722
|
-
console.error(
|
|
698
|
+
console.error(message);
|
|
723
699
|
process.exit(1);
|
|
724
700
|
}
|
|
725
701
|
function registerFsCommands(program2) {
|
|
726
|
-
program2.command("ls").description("List directory contents in the DirX path space").argument("
|
|
702
|
+
program2.command("ls").description("List directory contents in the DirX path space").argument("[path]", "Directory path (e.g. /net/)", "/").action(async (path) => {
|
|
727
703
|
try {
|
|
704
|
+
let normalizedPath = path.trim();
|
|
705
|
+
if (normalizedPath.length > 1 && normalizedPath.endsWith("/")) {
|
|
706
|
+
normalizedPath = normalizedPath.replace(/\/+$/, "");
|
|
707
|
+
}
|
|
708
|
+
const jsonMode = program2.opts().json === true;
|
|
728
709
|
const client = await createClient();
|
|
729
|
-
const result = await client.execute(`ls ${
|
|
730
|
-
|
|
710
|
+
const result = await client.execute(`ls ${normalizedPath}`);
|
|
711
|
+
console.log(jsonMode ? formatJson(result) : formatLs(result));
|
|
731
712
|
} catch (err) {
|
|
732
713
|
handleError(err, path);
|
|
733
714
|
}
|
|
734
715
|
});
|
|
735
716
|
program2.command("cat").description("Read file contents from a DirX path").argument("<path>", "File path").action(async (path) => {
|
|
736
717
|
try {
|
|
718
|
+
const jsonMode = program2.opts().json === true;
|
|
737
719
|
const client = await createClient();
|
|
738
720
|
const result = await client.execute(`cat ${path}`);
|
|
739
|
-
output(result);
|
|
721
|
+
output(result, jsonMode);
|
|
740
722
|
} catch (err) {
|
|
741
723
|
handleError(err, path);
|
|
742
724
|
}
|
|
743
725
|
});
|
|
744
726
|
program2.command("read").description("Read file contents (alias for cat)").argument("<path>", "File path").action(async (path) => {
|
|
745
727
|
try {
|
|
728
|
+
const jsonMode = program2.opts().json === true;
|
|
746
729
|
const client = await createClient();
|
|
747
730
|
const result = await client.execute(`cat ${path}`);
|
|
748
|
-
output(result);
|
|
731
|
+
output(result, jsonMode);
|
|
749
732
|
} catch (err) {
|
|
750
733
|
handleError(err, path);
|
|
751
734
|
}
|
|
@@ -755,12 +738,13 @@ function registerFsCommands(program2) {
|
|
|
755
738
|
try {
|
|
756
739
|
let payload = opts.data ?? "";
|
|
757
740
|
if (opts.file) {
|
|
758
|
-
const { readFileSync:
|
|
759
|
-
payload =
|
|
741
|
+
const { readFileSync: readFileSync3 } = await import('fs');
|
|
742
|
+
payload = readFileSync3(opts.file, "utf-8");
|
|
760
743
|
}
|
|
744
|
+
const jsonMode = program2.opts().json === true;
|
|
761
745
|
const client = await createClient();
|
|
762
746
|
const result = await client.execute(`write ${path} ${payload}`);
|
|
763
|
-
|
|
747
|
+
console.log(jsonMode ? formatJson(result) : formatMutate(result, "Created", path));
|
|
764
748
|
} catch (err) {
|
|
765
749
|
handleError(err, path);
|
|
766
750
|
}
|
|
@@ -771,12 +755,13 @@ function registerFsCommands(program2) {
|
|
|
771
755
|
try {
|
|
772
756
|
let payload = opts.data ?? "";
|
|
773
757
|
if (opts.file) {
|
|
774
|
-
const { readFileSync:
|
|
775
|
-
payload =
|
|
758
|
+
const { readFileSync: readFileSync3 } = await import('fs');
|
|
759
|
+
payload = readFileSync3(opts.file, "utf-8");
|
|
776
760
|
}
|
|
761
|
+
const jsonMode = program2.opts().json === true;
|
|
777
762
|
const client = await createClient();
|
|
778
763
|
const result = await client.execute(`edit ${path} ${payload}`);
|
|
779
|
-
|
|
764
|
+
console.log(jsonMode ? formatJson(result) : formatMutate(result, "Updated", path));
|
|
780
765
|
} catch (err) {
|
|
781
766
|
handleError(err, path);
|
|
782
767
|
}
|
|
@@ -784,27 +769,30 @@ function registerFsCommands(program2) {
|
|
|
784
769
|
);
|
|
785
770
|
program2.command("rm").description("Remove a resource at a DirX path").argument("<path>", "Resource path").action(async (path) => {
|
|
786
771
|
try {
|
|
772
|
+
const jsonMode = program2.opts().json === true;
|
|
787
773
|
const client = await createClient();
|
|
788
774
|
const result = await client.execute(`rm ${path}`);
|
|
789
|
-
|
|
775
|
+
console.log(jsonMode ? formatJson(result) : formatMutate(result, "Removed", path));
|
|
790
776
|
} catch (err) {
|
|
791
777
|
handleError(err, path);
|
|
792
778
|
}
|
|
793
779
|
});
|
|
794
780
|
program2.command("bash").description("Execute a multi-step pipeline on the gateway").argument("<pipeline>", "Pipeline expression").action(async (pipeline) => {
|
|
795
781
|
try {
|
|
782
|
+
const jsonMode = program2.opts().json === true;
|
|
796
783
|
const client = await createClient();
|
|
797
784
|
const result = await client.execute(`bash ${pipeline}`);
|
|
798
|
-
output(result);
|
|
785
|
+
output(result, jsonMode);
|
|
799
786
|
} catch (err) {
|
|
800
787
|
handleError(err);
|
|
801
788
|
}
|
|
802
789
|
});
|
|
803
|
-
program2.command("grep").description("Search across services in the DirX path space").argument("<pattern>", "Search pattern").argument("
|
|
790
|
+
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
791
|
try {
|
|
792
|
+
const jsonMode = program2.opts().json === true;
|
|
805
793
|
const client = await createClient();
|
|
806
794
|
const result = await client.execute(`grep ${pattern} ${path}`);
|
|
807
|
-
|
|
795
|
+
console.log(jsonMode ? formatJson(result) : formatGrep(result));
|
|
808
796
|
} catch (err) {
|
|
809
797
|
handleError(err, path);
|
|
810
798
|
}
|
|
@@ -813,7 +801,7 @@ function registerFsCommands(program2) {
|
|
|
813
801
|
var init_fs = __esm({
|
|
814
802
|
"src/commands/fs.ts"() {
|
|
815
803
|
init_client();
|
|
816
|
-
|
|
804
|
+
init_format();
|
|
817
805
|
}
|
|
818
806
|
});
|
|
819
807
|
|
|
@@ -823,13 +811,13 @@ __export(keys_exports, {
|
|
|
823
811
|
registerKeysCommand: () => registerKeysCommand
|
|
824
812
|
});
|
|
825
813
|
async function loadKeyStore() {
|
|
826
|
-
const { readFileSync:
|
|
814
|
+
const { readFileSync: readFileSync3 } = await import('fs');
|
|
827
815
|
const { join: join5 } = await import('path');
|
|
828
816
|
const { homedir: homedir2 } = await import('os');
|
|
829
817
|
const dirxHome = process.env.DIRX_HOME ?? join5(homedir2(), ".dirx");
|
|
830
818
|
const filePath = join5(dirxHome, "keys.json");
|
|
831
819
|
try {
|
|
832
|
-
const text =
|
|
820
|
+
const text = readFileSync3(filePath, "utf-8");
|
|
833
821
|
return JSON.parse(text);
|
|
834
822
|
} catch {
|
|
835
823
|
return { keys: {} };
|
|
@@ -880,7 +868,7 @@ function registerKeysCommand(program2) {
|
|
|
880
868
|
try {
|
|
881
869
|
const client = await createClient();
|
|
882
870
|
const result = await client.listByok();
|
|
883
|
-
console.log(JSON.stringify(result
|
|
871
|
+
console.log(JSON.stringify(result));
|
|
884
872
|
} catch (err) {
|
|
885
873
|
const msg = err instanceof Error ? err.message : String(err);
|
|
886
874
|
console.error(`Error: ${msg}`);
|
|
@@ -936,7 +924,7 @@ try {
|
|
|
936
924
|
} catch {
|
|
937
925
|
}
|
|
938
926
|
var program = new Command();
|
|
939
|
-
program.name("dirx").description("DirX \u2014 Unified Gateway & CLI for Agents").version(version);
|
|
927
|
+
program.name("dirx").description("DirX \u2014 Unified Gateway & CLI for Agents").version(version).option("--json", "Output raw JSON instead of human-readable text");
|
|
940
928
|
program.command("auth").description("Authenticate with the DirX gateway").option("--gateway-url <url>", "Gateway URL (default: https://api.dirx.ai)").action(async (opts) => {
|
|
941
929
|
const { runAuth: runAuth2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
942
930
|
await runAuth2({ gatewayUrl: opts.gatewayUrl });
|
|
@@ -982,4 +970,8 @@ var { registerFsCommands: registerFsCommands2 } = await Promise.resolve().then((
|
|
|
982
970
|
registerFsCommands2(program);
|
|
983
971
|
var { registerKeysCommand: registerKeysCommand2 } = await Promise.resolve().then(() => (init_keys(), keys_exports));
|
|
984
972
|
registerKeysCommand2(program);
|
|
973
|
+
if (process.argv.length <= 2) {
|
|
974
|
+
program.outputHelp();
|
|
975
|
+
process.exit(0);
|
|
976
|
+
}
|
|
985
977
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dirxai/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
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.1",
|
|
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
|
-
[](https://www.npmjs.com/package/@dirxai/cli)
|
|
4
|
-
[](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
|