@aigne/afs-cli 1.11.0-beta.6 → 1.11.0-beta.7
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/cli.cjs +27 -353
- package/dist/cli.d.cts +2 -1
- package/dist/cli.d.mts +2 -1
- package/dist/cli.mjs +28 -353
- package/dist/cli.mjs.map +1 -1
- package/dist/config/afs-loader.cjs +123 -0
- package/dist/config/afs-loader.d.cts +14 -0
- package/dist/config/afs-loader.d.cts.map +1 -0
- package/dist/config/afs-loader.d.mts +14 -0
- package/dist/config/afs-loader.d.mts.map +1 -0
- package/dist/config/afs-loader.mjs +122 -0
- package/dist/config/afs-loader.mjs.map +1 -0
- package/dist/config/loader.cjs +2 -2
- package/dist/config/loader.mjs +2 -2
- package/dist/{commands/mount.cjs → config/mount-commands.cjs} +13 -49
- package/dist/config/mount-commands.d.cts +20 -0
- package/dist/config/mount-commands.d.cts.map +1 -0
- package/dist/config/mount-commands.d.mts +20 -0
- package/dist/config/mount-commands.d.mts.map +1 -0
- package/dist/{commands/mount.mjs → config/mount-commands.mjs} +14 -49
- package/dist/config/mount-commands.mjs.map +1 -0
- package/dist/config/schema.cjs +9 -1
- package/dist/config/schema.mjs +9 -1
- package/dist/config/schema.mjs.map +1 -1
- package/dist/core/commands/delete.cjs +41 -0
- package/dist/core/commands/delete.d.cts +18 -0
- package/dist/core/commands/delete.d.cts.map +1 -0
- package/dist/core/commands/delete.d.mts +18 -0
- package/dist/core/commands/delete.d.mts.map +1 -0
- package/dist/core/commands/delete.mjs +42 -0
- package/dist/core/commands/delete.mjs.map +1 -0
- package/dist/core/commands/exec.cjs +95 -0
- package/dist/core/commands/exec.d.cts +26 -0
- package/dist/core/commands/exec.d.cts.map +1 -0
- package/dist/core/commands/exec.d.mts +26 -0
- package/dist/core/commands/exec.d.mts.map +1 -0
- package/dist/core/commands/exec.mjs +96 -0
- package/dist/core/commands/exec.mjs.map +1 -0
- package/dist/core/commands/explain.cjs +254 -0
- package/dist/core/commands/explain.d.cts +25 -0
- package/dist/core/commands/explain.d.cts.map +1 -0
- package/dist/core/commands/explain.d.mts +25 -0
- package/dist/core/commands/explain.d.mts.map +1 -0
- package/dist/core/commands/explain.mjs +255 -0
- package/dist/core/commands/explain.mjs.map +1 -0
- package/dist/core/commands/explore.cjs +30 -0
- package/dist/core/commands/explore.d.mts +2 -0
- package/dist/core/commands/explore.mjs +31 -0
- package/dist/core/commands/explore.mjs.map +1 -0
- package/dist/core/commands/index.cjs +36 -0
- package/dist/core/commands/index.d.cts +21 -0
- package/dist/core/commands/index.d.cts.map +1 -0
- package/dist/core/commands/index.d.mts +24 -0
- package/dist/core/commands/index.d.mts.map +1 -0
- package/dist/core/commands/index.mjs +37 -0
- package/dist/core/commands/index.mjs.map +1 -0
- package/dist/core/commands/ls.cjs +57 -0
- package/dist/core/commands/ls.d.cts +21 -0
- package/dist/core/commands/ls.d.cts.map +1 -0
- package/dist/core/commands/ls.d.mts +21 -0
- package/dist/core/commands/ls.d.mts.map +1 -0
- package/dist/core/commands/ls.mjs +58 -0
- package/dist/core/commands/ls.mjs.map +1 -0
- package/dist/core/commands/mount.cjs +139 -0
- package/dist/core/commands/mount.d.cts +33 -0
- package/dist/core/commands/mount.d.cts.map +1 -0
- package/dist/core/commands/mount.d.mts +33 -0
- package/dist/core/commands/mount.d.mts.map +1 -0
- package/dist/core/commands/mount.mjs +140 -0
- package/dist/core/commands/mount.mjs.map +1 -0
- package/dist/core/commands/read.cjs +48 -0
- package/dist/core/commands/read.d.cts +17 -0
- package/dist/core/commands/read.d.cts.map +1 -0
- package/dist/core/commands/read.d.mts +17 -0
- package/dist/core/commands/read.d.mts.map +1 -0
- package/dist/core/commands/read.mjs +49 -0
- package/dist/core/commands/read.mjs.map +1 -0
- package/dist/core/commands/search.cjs +40 -0
- package/dist/core/commands/search.d.mts +2 -0
- package/dist/core/commands/search.mjs +41 -0
- package/dist/core/commands/search.mjs.map +1 -0
- package/dist/core/commands/serve.cjs +242 -0
- package/dist/core/commands/serve.d.mts +2 -0
- package/dist/core/commands/serve.mjs +242 -0
- package/dist/core/commands/serve.mjs.map +1 -0
- package/dist/core/commands/stat.cjs +53 -0
- package/dist/core/commands/stat.d.cts +17 -0
- package/dist/core/commands/stat.d.cts.map +1 -0
- package/dist/core/commands/stat.d.mts +17 -0
- package/dist/core/commands/stat.d.mts.map +1 -0
- package/dist/core/commands/stat.mjs +54 -0
- package/dist/core/commands/stat.mjs.map +1 -0
- package/dist/core/commands/types.cjs +13 -0
- package/dist/core/commands/types.d.cts +54 -0
- package/dist/core/commands/types.d.cts.map +1 -0
- package/dist/core/commands/types.d.mts +54 -0
- package/dist/core/commands/types.d.mts.map +1 -0
- package/dist/core/commands/types.mjs +14 -0
- package/dist/core/commands/types.mjs.map +1 -0
- package/dist/core/commands/write.cjs +70 -0
- package/dist/core/commands/write.d.cts +20 -0
- package/dist/core/commands/write.d.cts.map +1 -0
- package/dist/core/commands/write.d.mts +20 -0
- package/dist/core/commands/write.d.mts.map +1 -0
- package/dist/core/commands/write.mjs +71 -0
- package/dist/core/commands/write.mjs.map +1 -0
- package/dist/core/executor/index.cjs +196 -0
- package/dist/core/executor/index.d.cts +77 -0
- package/dist/core/executor/index.d.cts.map +1 -0
- package/dist/core/executor/index.d.mts +77 -0
- package/dist/core/executor/index.d.mts.map +1 -0
- package/dist/core/executor/index.mjs +195 -0
- package/dist/core/executor/index.mjs.map +1 -0
- package/dist/core/formatters/delete.cjs +37 -0
- package/dist/core/formatters/delete.d.cts +18 -0
- package/dist/core/formatters/delete.d.cts.map +1 -0
- package/dist/core/formatters/delete.d.mts +18 -0
- package/dist/core/formatters/delete.d.mts.map +1 -0
- package/dist/core/formatters/delete.mjs +37 -0
- package/dist/core/formatters/delete.mjs.map +1 -0
- package/dist/core/formatters/exec.cjs +60 -0
- package/dist/core/formatters/exec.d.cts +18 -0
- package/dist/core/formatters/exec.d.cts.map +1 -0
- package/dist/core/formatters/exec.d.mts +18 -0
- package/dist/core/formatters/exec.d.mts.map +1 -0
- package/dist/core/formatters/exec.mjs +60 -0
- package/dist/core/formatters/exec.mjs.map +1 -0
- package/dist/core/formatters/explain.cjs +97 -0
- package/dist/core/formatters/explain.d.cts +11 -0
- package/dist/core/formatters/explain.d.cts.map +1 -0
- package/dist/core/formatters/explain.d.mts +11 -0
- package/dist/core/formatters/explain.d.mts.map +1 -0
- package/dist/core/formatters/explain.mjs +96 -0
- package/dist/core/formatters/explain.mjs.map +1 -0
- package/dist/core/formatters/index.d.mts +9 -0
- package/dist/core/formatters/ls.cjs +179 -0
- package/dist/core/formatters/ls.d.cts +20 -0
- package/dist/core/formatters/ls.d.cts.map +1 -0
- package/dist/core/formatters/ls.d.mts +20 -0
- package/dist/core/formatters/ls.d.mts.map +1 -0
- package/dist/core/formatters/ls.mjs +179 -0
- package/dist/core/formatters/ls.mjs.map +1 -0
- package/dist/core/formatters/mount.cjs +55 -0
- package/dist/core/formatters/mount.d.cts +15 -0
- package/dist/core/formatters/mount.d.cts.map +1 -0
- package/dist/core/formatters/mount.d.mts +15 -0
- package/dist/core/formatters/mount.d.mts.map +1 -0
- package/dist/core/formatters/mount.mjs +55 -0
- package/dist/core/formatters/mount.mjs.map +1 -0
- package/dist/core/formatters/read.cjs +100 -0
- package/dist/core/formatters/read.d.cts +22 -0
- package/dist/core/formatters/read.d.cts.map +1 -0
- package/dist/core/formatters/read.d.mts +22 -0
- package/dist/core/formatters/read.d.mts.map +1 -0
- package/dist/core/formatters/read.mjs +100 -0
- package/dist/core/formatters/read.mjs.map +1 -0
- package/dist/core/formatters/search.cjs +44 -0
- package/dist/core/formatters/search.d.mts +1 -0
- package/dist/core/formatters/search.mjs +44 -0
- package/dist/core/formatters/search.mjs.map +1 -0
- package/dist/core/formatters/stat.cjs +155 -0
- package/dist/core/formatters/stat.d.cts +15 -0
- package/dist/core/formatters/stat.d.cts.map +1 -0
- package/dist/core/formatters/stat.d.mts +15 -0
- package/dist/core/formatters/stat.d.mts.map +1 -0
- package/dist/core/formatters/stat.mjs +155 -0
- package/dist/core/formatters/stat.mjs.map +1 -0
- package/dist/core/formatters/write.cjs +51 -0
- package/dist/core/formatters/write.d.cts +22 -0
- package/dist/core/formatters/write.d.cts.map +1 -0
- package/dist/core/formatters/write.d.mts +22 -0
- package/dist/core/formatters/write.d.mts.map +1 -0
- package/dist/core/formatters/write.mjs +51 -0
- package/dist/core/formatters/write.mjs.map +1 -0
- package/dist/core/helpers/exec-args.cjs +142 -0
- package/dist/core/helpers/exec-args.d.cts +46 -0
- package/dist/core/helpers/exec-args.d.cts.map +1 -0
- package/dist/core/helpers/exec-args.d.mts +46 -0
- package/dist/core/helpers/exec-args.d.mts.map +1 -0
- package/dist/core/helpers/exec-args.mjs +139 -0
- package/dist/core/helpers/exec-args.mjs.map +1 -0
- package/dist/core/helpers/stdin.cjs +41 -0
- package/dist/core/helpers/stdin.d.cts +15 -0
- package/dist/core/helpers/stdin.d.cts.map +1 -0
- package/dist/core/helpers/stdin.d.mts +15 -0
- package/dist/core/helpers/stdin.d.mts.map +1 -0
- package/dist/core/helpers/stdin.mjs +41 -0
- package/dist/core/helpers/stdin.mjs.map +1 -0
- package/dist/core/index.cjs +49 -0
- package/dist/core/index.d.cts +24 -0
- package/dist/core/index.d.mts +25 -0
- package/dist/core/index.mjs +24 -0
- package/dist/core/path-utils.cjs +1 -0
- package/dist/core/path-utils.mjs +3 -0
- package/dist/core/types.d.cts +24 -0
- package/dist/core/types.d.cts.map +1 -0
- package/dist/core/types.d.mts +24 -0
- package/dist/core/types.d.mts.map +1 -0
- package/dist/errors.cjs +0 -11
- package/dist/errors.mjs +1 -11
- package/dist/errors.mjs.map +1 -1
- package/dist/explorer/actions.cjs +67 -32
- package/dist/explorer/actions.mjs +66 -32
- package/dist/explorer/actions.mjs.map +1 -1
- package/dist/explorer/components/dialog.cjs +170 -46
- package/dist/explorer/components/dialog.mjs +170 -46
- package/dist/explorer/components/dialog.mjs.map +1 -1
- package/dist/explorer/components/metadata-panel.cjs +86 -3
- package/dist/explorer/components/metadata-panel.mjs +86 -3
- package/dist/explorer/components/metadata-panel.mjs.map +1 -1
- package/dist/explorer/screen.cjs +63 -27
- package/dist/explorer/screen.d.cts +23 -0
- package/dist/explorer/screen.d.cts.map +1 -0
- package/dist/explorer/screen.d.mts +23 -0
- package/dist/explorer/screen.d.mts.map +1 -0
- package/dist/explorer/screen.mjs +63 -27
- package/dist/explorer/screen.mjs.map +1 -1
- package/dist/explorer/theme.cjs +1 -1
- package/dist/explorer/theme.mjs +1 -1
- package/dist/explorer/theme.mjs.map +1 -1
- package/dist/index.cjs +7 -1
- package/dist/index.d.cts +4 -1
- package/dist/index.d.mts +4 -1
- package/dist/index.mjs +4 -1
- package/dist/mcp/http-transport.cjs +68 -0
- package/dist/mcp/http-transport.mjs +68 -0
- package/dist/mcp/http-transport.mjs.map +1 -0
- package/dist/mcp/prompts.cjs +48 -0
- package/dist/mcp/prompts.mjs +48 -0
- package/dist/mcp/prompts.mjs.map +1 -0
- package/dist/mcp/resources.cjs +25 -0
- package/dist/mcp/resources.mjs +25 -0
- package/dist/mcp/resources.mjs.map +1 -0
- package/dist/mcp/server.cjs +30 -0
- package/dist/mcp/server.mjs +30 -0
- package/dist/mcp/server.mjs.map +1 -0
- package/dist/mcp/tools.cjs +196 -0
- package/dist/mcp/tools.mjs +196 -0
- package/dist/mcp/tools.mjs.map +1 -0
- package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/index.d.cts +10 -0
- package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/index.d.cts.map +1 -0
- package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/index.d.mts +10 -0
- package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/index.d.mts.map +1 -0
- package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/types.d.cts +46 -0
- package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/types.d.cts.map +1 -0
- package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/types.d.mts +46 -0
- package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/types.d.mts.map +1 -0
- package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/urlpattern.cjs +902 -0
- package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/urlpattern.mjs +902 -0
- package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/urlpattern.mjs.map +1 -0
- package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/index.cjs +6 -0
- package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/index.mjs +8 -0
- package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/index.mjs.map +1 -0
- package/dist/path-utils.d.cts +50 -0
- package/dist/path-utils.d.cts.map +1 -0
- package/dist/path-utils.d.mts +50 -0
- package/dist/path-utils.d.mts.map +1 -0
- package/dist/repl.cjs +485 -0
- package/dist/repl.d.cts +15 -0
- package/dist/repl.d.cts.map +1 -0
- package/dist/repl.d.mts +16 -0
- package/dist/repl.d.mts.map +1 -0
- package/dist/repl.mjs +485 -0
- package/dist/repl.mjs.map +1 -0
- package/dist/serve.cjs +146 -0
- package/dist/serve.d.cts +41 -0
- package/dist/serve.d.cts.map +1 -0
- package/dist/serve.d.mts +41 -0
- package/dist/serve.d.mts.map +1 -0
- package/dist/serve.mjs +146 -0
- package/dist/serve.mjs.map +1 -0
- package/dist/ui/header.cjs +1 -40
- package/dist/ui/header.mjs +1 -39
- package/dist/ui/header.mjs.map +1 -1
- package/dist/ui/index.cjs +2 -9
- package/dist/ui/index.mjs +2 -7
- package/dist/ui/index.mjs.map +1 -1
- package/dist/ui/terminal.cjs +1 -10
- package/dist/ui/terminal.mjs +1 -8
- package/dist/ui/terminal.mjs.map +1 -1
- package/package.json +29 -16
- package/dist/commands/exec.cjs +0 -164
- package/dist/commands/exec.mjs +0 -160
- package/dist/commands/exec.mjs.map +0 -1
- package/dist/commands/explain.cjs +0 -244
- package/dist/commands/explain.mjs +0 -242
- package/dist/commands/explain.mjs.map +0 -1
- package/dist/commands/index.cjs +0 -8
- package/dist/commands/index.mjs +0 -10
- package/dist/commands/ls.cjs +0 -242
- package/dist/commands/ls.mjs +0 -242
- package/dist/commands/ls.mjs.map +0 -1
- package/dist/commands/mount.mjs.map +0 -1
- package/dist/commands/read.cjs +0 -264
- package/dist/commands/read.mjs +0 -263
- package/dist/commands/read.mjs.map +0 -1
- package/dist/commands/serve.cjs +0 -144
- package/dist/commands/serve.mjs +0 -143
- package/dist/commands/serve.mjs.map +0 -1
- package/dist/commands/stat.cjs +0 -195
- package/dist/commands/stat.mjs +0 -195
- package/dist/commands/stat.mjs.map +0 -1
- package/dist/commands/write.cjs +0 -85
- package/dist/commands/write.mjs +0 -85
- package/dist/commands/write.mjs.map +0 -1
- package/dist/config/provider-factory.cjs +0 -400
- package/dist/config/provider-factory.mjs +0 -401
- package/dist/config/provider-factory.mjs.map +0 -1
- package/dist/config/uri-parser.cjs +0 -285
- package/dist/config/uri-parser.mjs +0 -285
- package/dist/config/uri-parser.mjs.map +0 -1
- package/dist/runtime.cjs +0 -120
- package/dist/runtime.mjs +0 -120
- package/dist/runtime.mjs.map +0 -1
- package/dist/utils/meta.cjs +0 -51
- package/dist/utils/meta.mjs +0 -49
- package/dist/utils/meta.mjs.map +0 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,364 +1,39 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { VERSION } from "./version.mjs";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import { explainCommand, explainPathCommand, formatExplainOutput, formatPathExplainOutput } from "./commands/explain.mjs";
|
|
8
|
-
import { formatLsOutput, lsCommand } from "./commands/ls.mjs";
|
|
9
|
-
import { formatReadOutput, readCommand } from "./commands/read.mjs";
|
|
10
|
-
import { createRuntime } from "./runtime.mjs";
|
|
11
|
-
import { formatServeOutput, serveCommand } from "./commands/serve.mjs";
|
|
12
|
-
import { formatStatOutput, statCommand } from "./commands/stat.mjs";
|
|
13
|
-
import { formatWriteOutput, writeCommand } from "./commands/write.mjs";
|
|
14
|
-
import "./commands/index.mjs";
|
|
15
|
-
import { CLIError, ExitCode } from "./errors.mjs";
|
|
16
|
-
import { createExplorerScreen } from "./explorer/screen.mjs";
|
|
17
|
-
import yargs from "yargs";
|
|
3
|
+
import { ExitCode } from "./errors.mjs";
|
|
4
|
+
import { AFSCommandExecutor } from "./core/executor/index.mjs";
|
|
5
|
+
import "./node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/index.mjs";
|
|
6
|
+
import "./core/index.mjs";
|
|
18
7
|
import { hideBin } from "yargs/helpers";
|
|
19
8
|
|
|
20
9
|
//#region src/cli.ts
|
|
21
|
-
/**
|
|
22
|
-
* AFS CLI - Command Line Interface
|
|
23
|
-
*
|
|
24
|
-
* Commands:
|
|
25
|
-
* - afs mount list|ls List mount configurations
|
|
26
|
-
* - afs mount add <path> <uri> Add a mount
|
|
27
|
-
* - afs mount remove|rm <path> Remove a mount
|
|
28
|
-
* - afs mount validate Validate mount configuration
|
|
29
|
-
* - afs list|ls [path] List directory
|
|
30
|
-
* - afs stat <path> Get file/directory info
|
|
31
|
-
* - afs read <path> Read file content
|
|
32
|
-
* - afs write <path> Write file content (--content or stdin)
|
|
33
|
-
* - afs exec <path> <action> Execute operation
|
|
34
|
-
* - afs serve Start HTTP server to expose AFS
|
|
35
|
-
* - afs explore [path] Interactive TUI file explorer
|
|
36
|
-
*
|
|
37
|
-
* Output modes (default: human):
|
|
38
|
-
* - --view=human: Human friendly format with colors (default)
|
|
39
|
-
* - --view=llm: LLM optimized output (token-efficient)
|
|
40
|
-
* - --view=default: Machine truth (script/pipe friendly)
|
|
41
|
-
* - --json: Structured JSON
|
|
42
|
-
*/
|
|
43
|
-
function getViewType(argv) {
|
|
44
|
-
if (argv.json) return "json";
|
|
45
|
-
if (argv.view) return argv.view;
|
|
46
|
-
return "human";
|
|
47
|
-
}
|
|
48
|
-
let headerShown = false;
|
|
49
|
-
/**
|
|
50
|
-
* Show header if in human view mode and not already shown
|
|
51
|
-
*/
|
|
52
|
-
async function maybeShowHeader(view) {
|
|
53
|
-
if (view !== "human" || headerShown || !shouldShowHeader()) return;
|
|
54
|
-
headerShown = true;
|
|
55
|
-
try {
|
|
56
|
-
printHeader({
|
|
57
|
-
version: VERSION,
|
|
58
|
-
mountCount: (await new ConfigLoader().load(process.cwd())).mounts.length
|
|
59
|
-
});
|
|
60
|
-
} catch {
|
|
61
|
-
printHeader({
|
|
62
|
-
version: VERSION,
|
|
63
|
-
mountCount: 0
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
async function showHeaderIfNeeded() {
|
|
68
|
-
const args = process.argv.slice(2);
|
|
69
|
-
if ((args.length === 0 || args.includes("--help") || args.includes("-h") || args.length === 1 && [
|
|
70
|
-
"help",
|
|
71
|
-
"mount",
|
|
72
|
-
"explain"
|
|
73
|
-
].includes(args[0])) && shouldShowHeader()) try {
|
|
74
|
-
printHeader({
|
|
75
|
-
version: VERSION,
|
|
76
|
-
mountCount: (await new ConfigLoader().load(process.cwd())).mounts.length
|
|
77
|
-
});
|
|
78
|
-
} catch {
|
|
79
|
-
printHeader({
|
|
80
|
-
version: VERSION,
|
|
81
|
-
mountCount: 0
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
10
|
async function main() {
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
default: 1,
|
|
108
|
-
description: "Maximum depth to list"
|
|
109
|
-
}).option("limit", {
|
|
110
|
-
alias: "n",
|
|
111
|
-
type: "number",
|
|
112
|
-
description: "Maximum number of entries to return"
|
|
113
|
-
}).option("max-children", {
|
|
114
|
-
type: "number",
|
|
115
|
-
description: "Maximum children per directory"
|
|
116
|
-
}).option("pattern", {
|
|
117
|
-
alias: "p",
|
|
118
|
-
type: "string",
|
|
119
|
-
description: "Glob pattern to filter entries (e.g., *.ts, **/*.js)"
|
|
120
|
-
}), async (argv) => {
|
|
121
|
-
const view = getViewType(argv);
|
|
122
|
-
await maybeShowHeader(view);
|
|
123
|
-
const runtime = await createRuntime();
|
|
124
|
-
const path = argv.path;
|
|
125
|
-
const result = await lsCommand(runtime, path, {
|
|
126
|
-
maxDepth: argv.depth,
|
|
127
|
-
limit: argv.limit,
|
|
128
|
-
maxChildren: argv["max-children"],
|
|
129
|
-
pattern: argv.pattern
|
|
130
|
-
});
|
|
131
|
-
console.log(formatLsOutput(result, view, { path }));
|
|
132
|
-
}).command("stat <path>", "Get file or directory info", (yargs$1) => yargs$1.positional("path", {
|
|
133
|
-
type: "string",
|
|
134
|
-
demandOption: true,
|
|
135
|
-
description: "Path to stat"
|
|
136
|
-
}), async (argv) => {
|
|
137
|
-
const view = getViewType(argv);
|
|
138
|
-
await maybeShowHeader(view);
|
|
139
|
-
const result = await statCommand(await createRuntime(), argv.path);
|
|
140
|
-
console.log(formatStatOutput(result, view));
|
|
141
|
-
}).command("read <path>", "Read file content", (yargs$1) => yargs$1.positional("path", {
|
|
142
|
-
type: "string",
|
|
143
|
-
demandOption: true,
|
|
144
|
-
description: "Path to read"
|
|
145
|
-
}), async (argv) => {
|
|
146
|
-
const view = getViewType(argv);
|
|
147
|
-
await maybeShowHeader(view);
|
|
148
|
-
const result = await readCommand(await createRuntime(), argv.path);
|
|
149
|
-
console.log(formatReadOutput(result, view));
|
|
150
|
-
}).command("write <path>", "Write content to file (from --content or stdin)", (yargs$1) => yargs$1.positional("path", {
|
|
151
|
-
type: "string",
|
|
152
|
-
demandOption: true,
|
|
153
|
-
description: "Path to write"
|
|
154
|
-
}).option("content", {
|
|
155
|
-
type: "string",
|
|
156
|
-
description: "Content to write (if not provided, reads from stdin)"
|
|
157
|
-
}).option("append", {
|
|
158
|
-
type: "boolean",
|
|
159
|
-
default: false,
|
|
160
|
-
description: "Append to file instead of overwrite"
|
|
161
|
-
}).option("set", {
|
|
162
|
-
type: "array",
|
|
163
|
-
string: true,
|
|
164
|
-
description: "Set metadata field (format: key=value), can be repeated"
|
|
165
|
-
}), async (argv) => {
|
|
166
|
-
const view = getViewType(argv);
|
|
167
|
-
await maybeShowHeader(view);
|
|
168
|
-
let content;
|
|
169
|
-
if (argv.content !== void 0) content = argv.content;
|
|
170
|
-
else if (argv.set && argv.set.length > 0) content = void 0;
|
|
171
|
-
else {
|
|
172
|
-
const chunks = [];
|
|
173
|
-
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
174
|
-
content = Buffer.concat(chunks).toString("utf-8");
|
|
175
|
-
}
|
|
176
|
-
const result = await writeCommand(await createRuntime(), argv.path, content, {
|
|
177
|
-
append: argv.append,
|
|
178
|
-
set: argv.set
|
|
179
|
-
});
|
|
180
|
-
console.log(formatWriteOutput(result, view));
|
|
181
|
-
if (!result.success) process.exit(ExitCode.RUNTIME_ERROR);
|
|
182
|
-
}).command("exec <path>", "Execute an executable path (e.g., MCP tool)", (yargs$1) => yargs$1.positional("path", {
|
|
183
|
-
type: "string",
|
|
184
|
-
demandOption: true,
|
|
185
|
-
description: "Path to execute (must be executable)"
|
|
186
|
-
}).option("args", {
|
|
187
|
-
type: "string",
|
|
188
|
-
description: "JSON arguments: --args '{\"key\": \"value\"}'"
|
|
189
|
-
}).option("yaml", {
|
|
190
|
-
type: "boolean",
|
|
191
|
-
description: "Output in YAML format"
|
|
192
|
-
}).example("$0 exec /modules/mcp/tools/echo --message hello", "Execute with named param").example("$0 exec /modules/mcp/tools/query --args '{\"sql\": \"SELECT 1\"}'", "Execute with JSON args").strict(false), async (argv) => {
|
|
193
|
-
let view = "human";
|
|
194
|
-
if (argv.json) view = "json";
|
|
195
|
-
else if (argv.yaml) view = "yaml";
|
|
196
|
-
else if (argv.view) view = argv.view;
|
|
197
|
-
await maybeShowHeader(view);
|
|
198
|
-
const args = await parseExecArgsWithStdin(argv);
|
|
199
|
-
const result = await execCommand(await createRuntime(), argv.path, args);
|
|
200
|
-
console.log(formatExecOutput(result, view));
|
|
201
|
-
if (!result.success) process.exit(ExitCode.RUNTIME_ERROR);
|
|
202
|
-
}).command("mount", "Manage mount configurations", (yargs$1) => yargs$1.command(["list", "ls"], "List all mounts", () => {}, async (argv) => {
|
|
203
|
-
const view = getViewType(argv);
|
|
204
|
-
await maybeShowHeader(view);
|
|
205
|
-
const result = await mountListCommand(process.cwd());
|
|
206
|
-
console.log(formatMountListOutput(result.mounts, view));
|
|
207
|
-
}).command("add <path> <uri>", "Add a new mount (path=virtual path, uri=data source)", (yargs$2) => yargs$2.positional("path", {
|
|
208
|
-
type: "string",
|
|
209
|
-
demandOption: true,
|
|
210
|
-
description: "Virtual path in AFS namespace (e.g., /src, /data)"
|
|
211
|
-
}).positional("uri", {
|
|
212
|
-
type: "string",
|
|
213
|
-
demandOption: true,
|
|
214
|
-
description: "Data source URI: fs:///local/path, git://repo, sqlite:///db.sqlite"
|
|
215
|
-
}).option("description", {
|
|
216
|
-
type: "string",
|
|
217
|
-
description: "Human-readable description for this mount"
|
|
218
|
-
}).option("token", {
|
|
219
|
-
type: "string",
|
|
220
|
-
description: "Bearer token for HTTP provider authorization"
|
|
221
|
-
}), async (argv) => {
|
|
222
|
-
const view = getViewType(argv);
|
|
223
|
-
await maybeShowHeader(view);
|
|
224
|
-
const result = await mountAddCommand(process.cwd(), argv.path, argv.uri, {
|
|
225
|
-
description: argv.description,
|
|
226
|
-
token: argv.token
|
|
227
|
-
});
|
|
228
|
-
if (view === "json") console.log(JSON.stringify(result, null, 2));
|
|
229
|
-
else if (result.success) {
|
|
230
|
-
const msg = view === "human" ? `${colors.success("Added mount")} ${colors.cyan(result.normalizedPath)}` : `Added mount ${result.normalizedPath}`;
|
|
231
|
-
console.log(msg);
|
|
232
|
-
} else {
|
|
233
|
-
const msg = view === "human" ? colors.error(result.message) : result.message;
|
|
234
|
-
console.error(msg);
|
|
235
|
-
process.exit(ExitCode.RUNTIME_ERROR);
|
|
236
|
-
}
|
|
237
|
-
}).command(["remove <path>", "rm <path>"], "Remove a mount", (yargs$2) => yargs$2.positional("path", {
|
|
238
|
-
type: "string",
|
|
239
|
-
demandOption: true,
|
|
240
|
-
description: "Virtual path to remove (e.g., /src)"
|
|
241
|
-
}), async (argv) => {
|
|
242
|
-
const view = getViewType(argv);
|
|
243
|
-
await maybeShowHeader(view);
|
|
244
|
-
const result = await mountRemoveCommand(process.cwd(), argv.path);
|
|
245
|
-
if (view === "json") console.log(JSON.stringify(result, null, 2));
|
|
246
|
-
else if (result.success) {
|
|
247
|
-
const msg = view === "human" ? `${colors.success("Removed mount")} ${colors.cyan(argv.path)}` : `Removed mount ${argv.path}`;
|
|
248
|
-
console.log(msg);
|
|
249
|
-
} else {
|
|
250
|
-
const msg = view === "human" ? colors.error(result.message) : result.message;
|
|
251
|
-
console.error(msg);
|
|
252
|
-
process.exit(ExitCode.RUNTIME_ERROR);
|
|
253
|
-
}
|
|
254
|
-
}).command("validate", "Validate mount configuration", () => {}, async (argv) => {
|
|
255
|
-
const view = getViewType(argv);
|
|
256
|
-
await maybeShowHeader(view);
|
|
257
|
-
const result = await mountValidateCommand(process.cwd());
|
|
258
|
-
if (view === "json") console.log(JSON.stringify(result, null, 2));
|
|
259
|
-
else if (result.valid) {
|
|
260
|
-
const msg = view === "human" ? colors.success("Configuration is valid") : "Configuration is valid";
|
|
261
|
-
console.log(msg);
|
|
262
|
-
} else {
|
|
263
|
-
const titleMsg = view === "human" ? colors.error("Configuration has errors:") : "Configuration has errors:";
|
|
264
|
-
console.error(titleMsg);
|
|
265
|
-
for (const error of result.errors) {
|
|
266
|
-
const errMsg = view === "human" ? ` ${colors.dim("-")} ${colors.error(error)}` : ` - ${error}`;
|
|
267
|
-
console.error(errMsg);
|
|
268
|
-
}
|
|
269
|
-
process.exit(ExitCode.RUNTIME_ERROR);
|
|
270
|
-
}
|
|
271
|
-
}).demandCommand(1, "Please specify a mount subcommand"), () => {}).command("explain [topic]", "Explain AFS concepts or AFS object", (yargs$1) => yargs$1.positional("topic", {
|
|
272
|
-
type: "string",
|
|
273
|
-
description: "Topic (mount, path, uri) or AFS path (e.g., /modules/src)"
|
|
274
|
-
}), async (argv) => {
|
|
275
|
-
const view = getViewType(argv);
|
|
276
|
-
await maybeShowHeader(view);
|
|
277
|
-
const topic = argv.topic;
|
|
278
|
-
if (topic?.startsWith("/")) {
|
|
279
|
-
const result = await explainPathCommand(await createRuntime(), topic);
|
|
280
|
-
console.log(formatPathExplainOutput(result, view));
|
|
281
|
-
} else {
|
|
282
|
-
const result = await explainCommand(process.cwd(), topic);
|
|
283
|
-
console.log(formatExplainOutput(result, view));
|
|
284
|
-
}
|
|
285
|
-
}).command("serve", "Start HTTP server to expose AFS providers", (yargs$1) => yargs$1.option("host", {
|
|
286
|
-
type: "string",
|
|
287
|
-
default: "localhost",
|
|
288
|
-
description: "Host address to listen on"
|
|
289
|
-
}).option("port", {
|
|
290
|
-
type: "number",
|
|
291
|
-
default: 3e3,
|
|
292
|
-
description: "Port to listen on"
|
|
293
|
-
}).option("path", {
|
|
294
|
-
type: "string",
|
|
295
|
-
default: "/afs",
|
|
296
|
-
description: "Base path for the server"
|
|
297
|
-
}).option("readonly", {
|
|
298
|
-
type: "boolean",
|
|
299
|
-
default: false,
|
|
300
|
-
description: "Run in readonly mode (disable write operations)"
|
|
301
|
-
}).option("cors", {
|
|
302
|
-
type: "boolean",
|
|
303
|
-
default: false,
|
|
304
|
-
description: "Enable CORS support"
|
|
305
|
-
}).option("max-body", {
|
|
306
|
-
type: "number",
|
|
307
|
-
description: "Maximum request body size in bytes (default: 10MB)"
|
|
308
|
-
}).option("token", {
|
|
309
|
-
type: "string",
|
|
310
|
-
description: "Bearer token for authorization"
|
|
311
|
-
}), async (argv) => {
|
|
312
|
-
await maybeShowHeader(getViewType(argv));
|
|
313
|
-
const result = await serveCommand({
|
|
314
|
-
host: argv.host,
|
|
315
|
-
port: argv.port,
|
|
316
|
-
path: argv.path,
|
|
317
|
-
readonly: argv.readonly,
|
|
318
|
-
cors: argv.cors,
|
|
319
|
-
maxBodySize: argv["max-body"],
|
|
320
|
-
token: argv.token
|
|
321
|
-
});
|
|
322
|
-
console.log(formatServeOutput(result));
|
|
323
|
-
await new Promise(() => {});
|
|
324
|
-
}).command("explore [path]", "Interactive TUI file explorer (PC Tools style)", (yargs$1) => yargs$1.positional("path", {
|
|
325
|
-
type: "string",
|
|
326
|
-
default: "/",
|
|
327
|
-
description: "Starting path to explore"
|
|
328
|
-
}), async (argv) => {
|
|
329
|
-
const configLoader = new ConfigLoader();
|
|
330
|
-
const config = await configLoader.load(process.cwd());
|
|
331
|
-
await createExplorerScreen({
|
|
332
|
-
runtime: await createRuntime(process.cwd(), { configLoader }),
|
|
333
|
-
startPath: argv.path,
|
|
334
|
-
version: VERSION,
|
|
335
|
-
mountCount: config.mounts.length
|
|
336
|
-
});
|
|
337
|
-
}).demandCommand(1, "Please specify a command").strict();
|
|
338
|
-
try {
|
|
339
|
-
await cli.parse();
|
|
340
|
-
} catch (error) {
|
|
341
|
-
if (error instanceof CLIError) {
|
|
342
|
-
console.error(error.message);
|
|
343
|
-
process.exit(error.exitCode);
|
|
344
|
-
}
|
|
345
|
-
throw error;
|
|
11
|
+
const args = hideBin(process.argv);
|
|
12
|
+
const cwd = process.cwd();
|
|
13
|
+
if (args.includes("-i") || args.includes("--interactive")) {
|
|
14
|
+
const { startRepl } = await import("./repl.mjs");
|
|
15
|
+
await startRepl({
|
|
16
|
+
cwd,
|
|
17
|
+
version: VERSION
|
|
18
|
+
});
|
|
19
|
+
process.exit(ExitCode.OK);
|
|
20
|
+
}
|
|
21
|
+
const result = await new AFSCommandExecutor(void 0, {
|
|
22
|
+
cwd,
|
|
23
|
+
tty: process.stdout.isTTY ?? false,
|
|
24
|
+
version: VERSION
|
|
25
|
+
}).execute(args);
|
|
26
|
+
if (result.success) {
|
|
27
|
+
console.log(result.formatted);
|
|
28
|
+
process.exit(ExitCode.OK);
|
|
29
|
+
} else {
|
|
30
|
+
console.error(result.formatted);
|
|
31
|
+
process.exit(result.error?.code ?? ExitCode.RUNTIME_ERROR);
|
|
346
32
|
}
|
|
347
33
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
function formatErrorForDisplay(error) {
|
|
352
|
-
const message = error.message;
|
|
353
|
-
const lines = message.split("\n");
|
|
354
|
-
if (lines.length > 1) return lines.map((line, i) => i === 0 ? `${colors.red("Error:")} ${line}` : ` ${line}`).join("\n");
|
|
355
|
-
return `${colors.red("Error:")} ${message}`;
|
|
356
|
-
}
|
|
357
|
-
main().then(() => {
|
|
358
|
-
process.exit(0);
|
|
359
|
-
}).catch((error) => {
|
|
360
|
-
console.error(formatErrorForDisplay(error));
|
|
361
|
-
process.exit(error instanceof CLIError ? error.exitCode : ExitCode.RUNTIME_ERROR);
|
|
34
|
+
main().catch((error) => {
|
|
35
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
36
|
+
process.exit(ExitCode.RUNTIME_ERROR);
|
|
362
37
|
});
|
|
363
38
|
|
|
364
39
|
//#endregion
|
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":["yargs"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * AFS CLI - Command Line Interface\n *\n * Commands:\n * - afs mount list|ls List mount configurations\n * - afs mount add <path> <uri> Add a mount\n * - afs mount remove|rm <path> Remove a mount\n * - afs mount validate Validate mount configuration\n * - afs list|ls [path] List directory\n * - afs stat <path> Get file/directory info\n * - afs read <path> Read file content\n * - afs write <path> Write file content (--content or stdin)\n * - afs exec <path> <action> Execute operation\n * - afs serve Start HTTP server to expose AFS\n * - afs explore [path] Interactive TUI file explorer\n *\n * Output modes (default: human):\n * - --view=human: Human friendly format with colors (default)\n * - --view=llm: LLM optimized output (token-efficient)\n * - --view=default: Machine truth (script/pipe friendly)\n * - --json: Structured JSON\n */\n\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\nimport {\n type ExecViewType,\n execCommand,\n explainCommand,\n explainPathCommand,\n formatExecOutput,\n formatExplainOutput,\n formatLsOutput,\n formatMountListOutput,\n formatPathExplainOutput,\n formatReadOutput,\n formatServeOutput,\n formatStatOutput,\n formatWriteOutput,\n lsCommand,\n mountAddCommand,\n mountListCommand,\n mountRemoveCommand,\n mountValidateCommand,\n parseExecArgsWithStdin,\n readCommand,\n serveCommand,\n statCommand,\n type ViewType,\n writeCommand,\n} from \"./commands/index.js\";\nimport { ConfigLoader } from \"./config/loader.js\";\nimport { CLIError, ExitCode } from \"./errors.js\";\nimport { createExplorerScreen } from \"./explorer/screen.js\";\nimport { createRuntime } from \"./runtime.js\";\nimport { colors, printHeader, shouldShowHeader } from \"./ui/index.js\";\nimport { VERSION } from \"./version.js\";\n\n// Global view type derived from args\n// Default is \"human\" for interactive use; LLMs can use --view=llm or --view=default\nfunction getViewType(argv: { json?: boolean; view?: string }): ViewType {\n if (argv.json) return \"json\";\n if (argv.view) return argv.view as ViewType;\n return \"human\";\n}\n\n// Track if header has been shown (show only once per invocation)\nlet headerShown = false;\n\n/**\n * Show header if in human view mode and not already shown\n */\nasync function maybeShowHeader(view: ViewType): Promise<void> {\n if (view !== \"human\" || headerShown || !shouldShowHeader()) {\n return;\n }\n\n headerShown = true;\n\n // Load mount count for header\n try {\n const configLoader = new ConfigLoader();\n const config = await configLoader.load(process.cwd());\n printHeader({\n version: VERSION,\n mountCount: config.mounts.length,\n });\n } catch {\n // If config loading fails, just show header without mount count\n printHeader({\n version: VERSION,\n mountCount: 0,\n });\n }\n}\n\n// Show header for help/version in interactive mode\nasync function showHeaderIfNeeded(): Promise<void> {\n const args = process.argv.slice(2);\n const isHelp =\n args.length === 0 ||\n args.includes(\"--help\") ||\n args.includes(\"-h\") ||\n (args.length === 1 && [\"help\", \"mount\", \"explain\"].includes(args[0]!));\n\n if (isHelp && shouldShowHeader()) {\n try {\n const configLoader = new ConfigLoader();\n const config = await configLoader.load(process.cwd());\n printHeader({\n version: VERSION,\n mountCount: config.mounts.length,\n });\n } catch {\n printHeader({\n version: VERSION,\n mountCount: 0,\n });\n }\n }\n}\n\n// Run the CLI\nasync function main() {\n await showHeaderIfNeeded();\n\n const cli = yargs(hideBin(process.argv))\n .scriptName(\"afs\")\n .version(VERSION)\n .alias(\"version\", \"V\")\n .help(\"help\")\n .alias(\"help\", \"h\")\n .usage(\"$0 <command> [options]\")\n .option(\"json\", {\n type: \"boolean\",\n description: \"Output in JSON format\",\n global: true,\n })\n .option(\"view\", {\n type: \"string\",\n choices: [\"default\", \"llm\", \"human\"],\n default: \"human\",\n description: \"Output format (llm for AI agents, default for scripts)\",\n global: true,\n })\n .command(\n [\"list [path]\", \"ls [path]\"],\n \"List directory contents\",\n (yargs) =>\n yargs\n .positional(\"path\", {\n type: \"string\",\n default: \"/\",\n description: \"Path to list\",\n })\n .option(\"depth\", {\n type: \"number\",\n default: 1,\n description: \"Maximum depth to list\",\n })\n .option(\"limit\", {\n alias: \"n\",\n type: \"number\",\n description: \"Maximum number of entries to return\",\n })\n .option(\"max-children\", {\n type: \"number\",\n description: \"Maximum children per directory\",\n })\n .option(\"pattern\", {\n alias: \"p\",\n type: \"string\",\n description: \"Glob pattern to filter entries (e.g., *.ts, **/*.js)\",\n }),\n async (argv) => {\n const view = getViewType(argv);\n await maybeShowHeader(view);\n const runtime = await createRuntime();\n const path = argv.path!;\n const result = await lsCommand(runtime, path, {\n maxDepth: argv.depth,\n limit: argv.limit,\n maxChildren: argv[\"max-children\"],\n pattern: argv.pattern,\n });\n console.log(formatLsOutput(result, view, { path }));\n },\n )\n .command(\n \"stat <path>\",\n \"Get file or directory info\",\n (yargs) =>\n yargs.positional(\"path\", {\n type: \"string\",\n demandOption: true,\n description: \"Path to stat\",\n }),\n async (argv) => {\n const view = getViewType(argv);\n await maybeShowHeader(view);\n const runtime = await createRuntime();\n const result = await statCommand(runtime, argv.path!);\n console.log(formatStatOutput(result, view));\n },\n )\n .command(\n \"read <path>\",\n \"Read file content\",\n (yargs) =>\n yargs.positional(\"path\", {\n type: \"string\",\n demandOption: true,\n description: \"Path to read\",\n }),\n async (argv) => {\n const view = getViewType(argv);\n await maybeShowHeader(view);\n const runtime = await createRuntime();\n const result = await readCommand(runtime, argv.path!);\n console.log(formatReadOutput(result, view));\n },\n )\n .command(\n \"write <path>\",\n \"Write content to file (from --content or stdin)\",\n (yargs) =>\n yargs\n .positional(\"path\", {\n type: \"string\",\n demandOption: true,\n description: \"Path to write\",\n })\n .option(\"content\", {\n type: \"string\",\n description: \"Content to write (if not provided, reads from stdin)\",\n })\n .option(\"append\", {\n type: \"boolean\",\n default: false,\n description: \"Append to file instead of overwrite\",\n })\n .option(\"set\", {\n type: \"array\",\n string: true,\n description: \"Set metadata field (format: key=value), can be repeated\",\n }),\n async (argv) => {\n const view = getViewType(argv);\n await maybeShowHeader(view);\n\n let content: string | undefined;\n\n if (argv.content !== undefined) {\n // Use --content parameter\n content = argv.content;\n } else if (argv.set && argv.set.length > 0) {\n // If only --set is provided without content, content is optional\n content = undefined;\n } else {\n // Read content from stdin\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n content = Buffer.concat(chunks).toString(\"utf-8\");\n }\n\n const runtime = await createRuntime();\n const result = await writeCommand(runtime, argv.path!, content, {\n append: argv.append,\n set: argv.set as string[] | undefined,\n });\n console.log(formatWriteOutput(result, view));\n\n if (!result.success) {\n process.exit(ExitCode.RUNTIME_ERROR);\n }\n },\n )\n .command(\n \"exec <path>\",\n \"Execute an executable path (e.g., MCP tool)\",\n (yargs) =>\n yargs\n .positional(\"path\", {\n type: \"string\",\n demandOption: true,\n description: \"Path to execute (must be executable)\",\n })\n .option(\"args\", {\n type: \"string\",\n description: 'JSON arguments: --args \\'{\"key\": \"value\"}\\'',\n })\n .option(\"yaml\", {\n type: \"boolean\",\n description: \"Output in YAML format\",\n })\n .example(\"$0 exec /modules/mcp/tools/echo --message hello\", \"Execute with named param\")\n .example(\n '$0 exec /modules/mcp/tools/query --args \\'{\"sql\": \"SELECT 1\"}\\'',\n \"Execute with JSON args\",\n )\n .strict(false), // Allow unknown options as exec arguments\n async (argv) => {\n // Determine output format\n let view: ExecViewType = \"human\";\n if (argv.json) view = \"json\";\n else if (argv.yaml) view = \"yaml\";\n else if (argv.view) view = argv.view as ExecViewType;\n\n await maybeShowHeader(view as ViewType);\n\n // Parse arguments from CLI options with stdin support\n const args = await parseExecArgsWithStdin(argv as Record<string, unknown>);\n\n const runtime = await createRuntime();\n const result = await execCommand(runtime, argv.path!, args);\n console.log(formatExecOutput(result, view));\n\n if (!result.success) {\n process.exit(ExitCode.RUNTIME_ERROR);\n }\n },\n )\n .command(\n \"mount\",\n \"Manage mount configurations\",\n (yargs) =>\n yargs\n .command(\n [\"list\", \"ls\"],\n \"List all mounts\",\n () => {},\n async (argv) => {\n const view = getViewType(argv);\n await maybeShowHeader(view);\n const result = await mountListCommand(process.cwd());\n console.log(formatMountListOutput(result.mounts, view));\n },\n )\n .command(\n \"add <path> <uri>\",\n \"Add a new mount (path=virtual path, uri=data source)\",\n (yargs) =>\n yargs\n .positional(\"path\", {\n type: \"string\",\n demandOption: true,\n description: \"Virtual path in AFS namespace (e.g., /src, /data)\",\n })\n .positional(\"uri\", {\n type: \"string\",\n demandOption: true,\n description: \"Data source URI: fs:///local/path, git://repo, sqlite:///db.sqlite\",\n })\n .option(\"description\", {\n type: \"string\",\n description: \"Human-readable description for this mount\",\n })\n .option(\"token\", {\n type: \"string\",\n description: \"Bearer token for HTTP provider authorization\",\n }),\n async (argv) => {\n const view = getViewType(argv);\n await maybeShowHeader(view);\n\n const result = await mountAddCommand(process.cwd(), argv.path!, argv.uri!, {\n description: argv.description,\n token: argv.token,\n });\n\n if (view === \"json\") {\n console.log(JSON.stringify(result, null, 2));\n } else {\n if (result.success) {\n const msg =\n view === \"human\"\n ? `${colors.success(\"Added mount\")} ${colors.cyan(result.normalizedPath!)}`\n : `Added mount ${result.normalizedPath}`;\n console.log(msg);\n } else {\n const msg = view === \"human\" ? colors.error(result.message!) : result.message;\n console.error(msg);\n process.exit(ExitCode.RUNTIME_ERROR);\n }\n }\n },\n )\n .command(\n [\"remove <path>\", \"rm <path>\"],\n \"Remove a mount\",\n (yargs) =>\n yargs.positional(\"path\", {\n type: \"string\",\n demandOption: true,\n description: \"Virtual path to remove (e.g., /src)\",\n }),\n async (argv) => {\n const view = getViewType(argv);\n await maybeShowHeader(view);\n\n const result = await mountRemoveCommand(process.cwd(), argv.path!);\n\n if (view === \"json\") {\n console.log(JSON.stringify(result, null, 2));\n } else {\n if (result.success) {\n const msg =\n view === \"human\"\n ? `${colors.success(\"Removed mount\")} ${colors.cyan(argv.path!)}`\n : `Removed mount ${argv.path}`;\n console.log(msg);\n } else {\n const msg = view === \"human\" ? colors.error(result.message!) : result.message;\n console.error(msg);\n process.exit(ExitCode.RUNTIME_ERROR);\n }\n }\n },\n )\n .command(\n \"validate\",\n \"Validate mount configuration\",\n () => {},\n async (argv) => {\n const view = getViewType(argv);\n await maybeShowHeader(view);\n\n const result = await mountValidateCommand(process.cwd());\n\n if (view === \"json\") {\n console.log(JSON.stringify(result, null, 2));\n } else {\n if (result.valid) {\n const msg =\n view === \"human\"\n ? colors.success(\"Configuration is valid\")\n : \"Configuration is valid\";\n console.log(msg);\n } else {\n const titleMsg =\n view === \"human\"\n ? colors.error(\"Configuration has errors:\")\n : \"Configuration has errors:\";\n console.error(titleMsg);\n for (const error of result.errors) {\n const errMsg =\n view === \"human\"\n ? ` ${colors.dim(\"-\")} ${colors.error(error)}`\n : ` - ${error}`;\n console.error(errMsg);\n }\n process.exit(ExitCode.RUNTIME_ERROR);\n }\n }\n },\n )\n .demandCommand(1, \"Please specify a mount subcommand\"),\n () => {},\n )\n .command(\n \"explain [topic]\",\n \"Explain AFS concepts or AFS object\",\n (yargs) =>\n yargs.positional(\"topic\", {\n type: \"string\",\n description: \"Topic (mount, path, uri) or AFS path (e.g., /modules/src)\",\n }),\n async (argv) => {\n const view = getViewType(argv);\n await maybeShowHeader(view);\n const topic = argv.topic;\n\n // If topic starts with /, treat as object path\n if (topic?.startsWith(\"/\")) {\n const runtime = await createRuntime();\n const result = await explainPathCommand(runtime, topic);\n console.log(formatPathExplainOutput(result, view));\n } else {\n const result = await explainCommand(process.cwd(), topic);\n console.log(formatExplainOutput(result, view));\n }\n },\n )\n .command(\n \"serve\",\n \"Start HTTP server to expose AFS providers\",\n (yargs) =>\n yargs\n .option(\"host\", {\n type: \"string\",\n default: \"localhost\",\n description: \"Host address to listen on\",\n })\n .option(\"port\", {\n type: \"number\",\n default: 3000,\n description: \"Port to listen on\",\n })\n .option(\"path\", {\n type: \"string\",\n default: \"/afs\",\n description: \"Base path for the server\",\n })\n .option(\"readonly\", {\n type: \"boolean\",\n default: false,\n description: \"Run in readonly mode (disable write operations)\",\n })\n .option(\"cors\", {\n type: \"boolean\",\n default: false,\n description: \"Enable CORS support\",\n })\n .option(\"max-body\", {\n type: \"number\",\n description: \"Maximum request body size in bytes (default: 10MB)\",\n })\n .option(\"token\", {\n type: \"string\",\n description: \"Bearer token for authorization\",\n }),\n async (argv) => {\n const view = getViewType(argv);\n await maybeShowHeader(view);\n\n const result = await serveCommand({\n host: argv.host,\n port: argv.port,\n path: argv.path,\n readonly: argv.readonly,\n cors: argv.cors,\n maxBodySize: argv[\"max-body\"],\n token: argv.token,\n });\n\n console.log(formatServeOutput(result));\n\n // Keep the process running\n await new Promise(() => {});\n },\n )\n .command(\n \"explore [path]\",\n \"Interactive TUI file explorer (PC Tools style)\",\n (yargs) =>\n yargs.positional(\"path\", {\n type: \"string\",\n default: \"/\",\n description: \"Starting path to explore\",\n }),\n async (argv) => {\n const configLoader = new ConfigLoader();\n const config = await configLoader.load(process.cwd());\n const runtime = await createRuntime(process.cwd(), { configLoader });\n await createExplorerScreen({\n runtime,\n startPath: argv.path,\n version: VERSION,\n mountCount: config.mounts.length,\n });\n },\n )\n .demandCommand(1, \"Please specify a command\")\n .strict();\n\n try {\n await cli.parse();\n } catch (error) {\n if (error instanceof CLIError) {\n console.error(error.message);\n process.exit(error.exitCode);\n }\n throw error;\n }\n}\n\n/**\n * Format error message for display\n */\nfunction formatErrorForDisplay(error: Error): string {\n const message = error.message;\n\n // Format multi-line messages with proper indentation\n const lines = message.split(\"\\n\");\n if (lines.length > 1) {\n return lines\n .map((line, i) => (i === 0 ? `${colors.red(\"Error:\")} ${line}` : ` ${line}`))\n .join(\"\\n\");\n }\n\n return `${colors.red(\"Error:\")} ${message}`;\n}\n\nmain()\n .then(() => {\n // Force exit after command completes to ensure child processes (like MCP stdio)\n // don't keep the process alive. Long-running commands (serve, explore) handle\n // their own lifecycle and never reach here.\n process.exit(0);\n })\n .catch((error) => {\n console.error(formatErrorForDisplay(error));\n process.exit(error instanceof CLIError ? error.exitCode : ExitCode.RUNTIME_ERROR);\n });\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * AFS CLI - Command Line Interface\n *\n * Simple CLI that delegates to executor. AFS is lazy-loaded on demand\n * by individual commands, so mount failures don't block config commands.\n */\n\nimport \"urlpattern-polyfill\";\nimport { hideBin } from \"yargs/helpers\";\nimport { AFSCommandExecutor } from \"./core/index.js\";\nimport { ExitCode } from \"./errors.js\";\nimport { VERSION } from \"./version.js\";\n\nasync function main() {\n const args = hideBin(process.argv);\n const cwd = process.cwd();\n\n // Check for -i / --interactive before yargs parsing\n if (args.includes(\"-i\") || args.includes(\"--interactive\")) {\n const { startRepl } = await import(\"./repl.js\");\n await startRepl({ cwd, version: VERSION });\n process.exit(ExitCode.OK);\n }\n\n const executor = new AFSCommandExecutor(undefined, {\n cwd,\n tty: process.stdout.isTTY ?? false,\n version: VERSION,\n });\n\n const result = await executor.execute(args);\n\n if (result.success) {\n console.log(result.formatted);\n process.exit(ExitCode.OK);\n } else {\n console.error(result.formatted);\n process.exit(result.error?.code ?? ExitCode.RUNTIME_ERROR);\n }\n}\n\nmain().catch((error) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(ExitCode.RUNTIME_ERROR);\n});\n"],"mappings":";;;;;;;;;AAeA,eAAe,OAAO;CACpB,MAAM,OAAO,QAAQ,QAAQ,KAAK;CAClC,MAAM,MAAM,QAAQ,KAAK;AAGzB,KAAI,KAAK,SAAS,KAAK,IAAI,KAAK,SAAS,gBAAgB,EAAE;EACzD,MAAM,EAAE,cAAc,MAAM,OAAO;AACnC,QAAM,UAAU;GAAE;GAAK,SAAS;GAAS,CAAC;AAC1C,UAAQ,KAAK,SAAS,GAAG;;CAS3B,MAAM,SAAS,MANE,IAAI,mBAAmB,QAAW;EACjD;EACA,KAAK,QAAQ,OAAO,SAAS;EAC7B,SAAS;EACV,CAAC,CAE4B,QAAQ,KAAK;AAE3C,KAAI,OAAO,SAAS;AAClB,UAAQ,IAAI,OAAO,UAAU;AAC7B,UAAQ,KAAK,SAAS,GAAG;QACpB;AACL,UAAQ,MAAM,OAAO,UAAU;AAC/B,UAAQ,KAAK,OAAO,OAAO,QAAQ,SAAS,cAAc;;;AAI9D,MAAM,CAAC,OAAO,UAAU;AACtB,SAAQ,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CAAC;AACrE,SAAQ,KAAK,SAAS,cAAc;EACpC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_loader = require('./loader.cjs');
|
|
3
|
+
let _aigne_afs = require("@aigne/afs");
|
|
4
|
+
let _aigne_afs_provider_registry = require("@aigne/afs-provider-registry");
|
|
5
|
+
|
|
6
|
+
//#region src/config/afs-loader.ts
|
|
7
|
+
/**
|
|
8
|
+
* AFS Loader - Lazy loading with parallel tolerant mount
|
|
9
|
+
*
|
|
10
|
+
* Provides loadAFS() for on-demand AFS creation with caching.
|
|
11
|
+
* createAFS() uses Promise.allSettled for parallel provider creation + mount,
|
|
12
|
+
* tolerating individual failures while reporting them to stderr.
|
|
13
|
+
*/
|
|
14
|
+
let cached;
|
|
15
|
+
/**
|
|
16
|
+
* Load AFS with caching - first call creates, subsequent calls return cached instance
|
|
17
|
+
*/
|
|
18
|
+
async function loadAFS(cwd, options) {
|
|
19
|
+
if (cached) return {
|
|
20
|
+
afs: cached,
|
|
21
|
+
failures: []
|
|
22
|
+
};
|
|
23
|
+
const result = await createAFS(cwd, options);
|
|
24
|
+
cached = result.afs;
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Create AFS instance from config with parallel tolerant mount
|
|
29
|
+
*
|
|
30
|
+
* - All providers are created and mounted in parallel via Promise.allSettled
|
|
31
|
+
* - Individual failures are logged to stderr and skipped (unless onProgress is provided)
|
|
32
|
+
* - If ALL providers fail, throws an error
|
|
33
|
+
* - If no mounts configured, returns empty AFS (no error)
|
|
34
|
+
*/
|
|
35
|
+
async function createAFS(cwd, options) {
|
|
36
|
+
const config = await new require_loader.ConfigLoader().load(cwd);
|
|
37
|
+
const afs = new _aigne_afs.AFS();
|
|
38
|
+
if (config.mounts.length === 0) return {
|
|
39
|
+
afs,
|
|
40
|
+
failures: []
|
|
41
|
+
};
|
|
42
|
+
const registry = (0, _aigne_afs_provider_registry.createProviderRegistry)();
|
|
43
|
+
registry.register("workspace", async (mount, parsed) => {
|
|
44
|
+
const mod = await import("@aigne/afs-workspace");
|
|
45
|
+
const AFSWorkspace = mod.AFSWorkspace ?? mod.default;
|
|
46
|
+
if (!AFSWorkspace) throw new Error("workspace:// scheme requires @aigne/afs-workspace package. Install it with: pnpm add @aigne/afs-workspace");
|
|
47
|
+
return new AFSWorkspace({
|
|
48
|
+
workspacePath: parsed.path,
|
|
49
|
+
registry,
|
|
50
|
+
name: mount.path.slice(1).replace(/\//g, "-") || "workspace",
|
|
51
|
+
description: mount.description,
|
|
52
|
+
accessMode: mount.access_mode,
|
|
53
|
+
...mount.options
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
afs.loadProvider = async (uri, mountPath) => {
|
|
57
|
+
const { parseURI } = await import("@aigne/afs-provider-registry");
|
|
58
|
+
parseURI(uri);
|
|
59
|
+
const provider = await registry.createProvider({
|
|
60
|
+
uri,
|
|
61
|
+
path: mountPath
|
|
62
|
+
});
|
|
63
|
+
await afs.mount(provider, mountPath);
|
|
64
|
+
};
|
|
65
|
+
if (config.registry?.enabled !== false) try {
|
|
66
|
+
const { AFSRegistry } = await import("@aigne/afs-registry");
|
|
67
|
+
const registryProvider = new AFSRegistry({ providers: config.registry?.providers ?? [] });
|
|
68
|
+
await afs.mount(registryProvider, "/registry/official");
|
|
69
|
+
} catch {}
|
|
70
|
+
const total = config.mounts.length;
|
|
71
|
+
let completed = 0;
|
|
72
|
+
let failedCount = 0;
|
|
73
|
+
options?.onProgress?.({
|
|
74
|
+
total,
|
|
75
|
+
completed: 0,
|
|
76
|
+
failed: 0
|
|
77
|
+
});
|
|
78
|
+
const results = await Promise.allSettled(config.mounts.map(async (mount) => {
|
|
79
|
+
const provider = await registry.createProvider(mount);
|
|
80
|
+
await afs.mount(provider, mount.path, { namespace: mount.namespace ?? null });
|
|
81
|
+
completed++;
|
|
82
|
+
options?.onProgress?.({
|
|
83
|
+
total,
|
|
84
|
+
completed,
|
|
85
|
+
failed: failedCount
|
|
86
|
+
});
|
|
87
|
+
return mount.path;
|
|
88
|
+
}));
|
|
89
|
+
const failures = [];
|
|
90
|
+
const succeeded = [];
|
|
91
|
+
for (let i = 0; i < results.length; i++) {
|
|
92
|
+
const result = results[i];
|
|
93
|
+
if (result.status === "fulfilled") succeeded.push(result.value);
|
|
94
|
+
else {
|
|
95
|
+
const reason = result.reason;
|
|
96
|
+
const msg = reason instanceof Error ? reason.message : String(reason);
|
|
97
|
+
failures.push({
|
|
98
|
+
path: config.mounts[i].path,
|
|
99
|
+
reason: msg
|
|
100
|
+
});
|
|
101
|
+
failedCount++;
|
|
102
|
+
completed++;
|
|
103
|
+
options?.onProgress?.({
|
|
104
|
+
total,
|
|
105
|
+
completed,
|
|
106
|
+
failed: failedCount
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (!options?.onProgress && failures.length > 0) {
|
|
111
|
+
console.warn(`[mount] ${succeeded.length} succeeded, ${failures.length} failed:`);
|
|
112
|
+
for (const f of failures) console.warn(` - ${f.path}: ${f.reason}`);
|
|
113
|
+
}
|
|
114
|
+
if (succeeded.length === 0 && config.mounts.length > 0) throw new Error("All providers failed to mount");
|
|
115
|
+
return {
|
|
116
|
+
afs,
|
|
117
|
+
failures
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
//#endregion
|
|
122
|
+
exports.createAFS = createAFS;
|
|
123
|
+
exports.loadAFS = loadAFS;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AFS } from "@aigne/afs";
|
|
2
|
+
|
|
3
|
+
//#region src/config/afs-loader.d.ts
|
|
4
|
+
interface MountProgressEvent {
|
|
5
|
+
total: number;
|
|
6
|
+
completed: number;
|
|
7
|
+
failed: number;
|
|
8
|
+
}
|
|
9
|
+
interface CreateAFSOptions {
|
|
10
|
+
onProgress?: (event: MountProgressEvent) => void;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { CreateAFSOptions };
|
|
14
|
+
//# sourceMappingURL=afs-loader.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"afs-loader.d.cts","names":[],"sources":["../../src/config/afs-loader.ts"],"mappings":";;;UAciB,kBAAA;EACf,KAAA;EACA,SAAA;EACA,MAAA;AAAA;AAAA,UAae,gBAAA;EACf,UAAA,IAAc,KAAA,EAAO,kBAAA;AAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AFS } from "@aigne/afs";
|
|
2
|
+
|
|
3
|
+
//#region src/config/afs-loader.d.ts
|
|
4
|
+
interface MountProgressEvent {
|
|
5
|
+
total: number;
|
|
6
|
+
completed: number;
|
|
7
|
+
failed: number;
|
|
8
|
+
}
|
|
9
|
+
interface CreateAFSOptions {
|
|
10
|
+
onProgress?: (event: MountProgressEvent) => void;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { CreateAFSOptions };
|
|
14
|
+
//# sourceMappingURL=afs-loader.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"afs-loader.d.mts","names":[],"sources":["../../src/config/afs-loader.ts"],"mappings":";;;UAciB,kBAAA;EACf,KAAA;EACA,SAAA;EACA,MAAA;AAAA;AAAA,UAae,gBAAA;EACf,UAAA,IAAc,KAAA,EAAO,kBAAA;AAAA"}
|