@aigne/afs-cli 1.11.0-beta.5 → 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 +25 -328
- package/dist/cli.d.cts +2 -1
- package/dist/cli.d.mts +2 -1
- package/dist/cli.mjs +26 -328
- 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 +14 -3
- package/dist/config/loader.mjs +14 -3
- package/dist/config/loader.mjs.map +1 -1
- 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 +113 -48
- package/dist/explorer/actions.mjs +113 -48
- package/dist/explorer/actions.mjs.map +1 -1
- package/dist/explorer/components/dialog.cjs +287 -10
- package/dist/explorer/components/dialog.mjs +287 -10
- package/dist/explorer/components/dialog.mjs.map +1 -1
- package/dist/explorer/components/file-list.mjs.map +1 -1
- package/dist/explorer/components/metadata-panel.cjs +121 -24
- package/dist/explorer/components/metadata-panel.mjs +121 -24
- package/dist/explorer/components/metadata-panel.mjs.map +1 -1
- package/dist/explorer/screen.cjs +72 -21
- 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 +73 -22
- package/dist/explorer/screen.mjs.map +1 -1
- package/dist/explorer/theme.cjs +4 -2
- package/dist/explorer/theme.mjs +4 -2
- 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.cjs +2 -1
- 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/path-utils.mjs +1 -1
- 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 -49
- package/dist/ui/header.mjs +1 -47
- package/dist/ui/header.mjs.map +1 -1
- package/dist/ui/index.cjs +2 -11
- package/dist/ui/index.mjs +2 -8
- 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 +32 -9
- package/dist/commands/exec.cjs +0 -46
- package/dist/commands/exec.mjs +0 -45
- 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 -143
- package/dist/commands/ls.mjs +0 -143
- package/dist/commands/ls.mjs.map +0 -1
- package/dist/commands/mount.mjs.map +0 -1
- package/dist/commands/read.cjs +0 -65
- package/dist/commands/read.mjs +0 -64
- 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 -113
- package/dist/commands/stat.mjs +0 -112
- package/dist/commands/stat.mjs.map +0 -1
- package/dist/commands/write.cjs +0 -52
- package/dist/commands/write.mjs +0 -51
- package/dist/commands/write.mjs.map +0 -1
- package/dist/config/provider-factory.cjs +0 -93
- package/dist/config/provider-factory.mjs +0 -94
- package/dist/config/provider-factory.mjs.map +0 -1
- package/dist/config/uri-parser.cjs +0 -92
- package/dist/config/uri-parser.mjs +0 -92
- package/dist/config/uri-parser.mjs.map +0 -1
- package/dist/runtime.cjs +0 -96
- package/dist/runtime.mjs +0 -96
- package/dist/runtime.mjs.map +0 -1
|
@@ -10,7 +10,7 @@ function formatMetadata(entry, metadata) {
|
|
|
10
10
|
const prefix = icon ? `${icon} ` : "";
|
|
11
11
|
lines.push(`${prefix}${entry.name}`);
|
|
12
12
|
lines.push("");
|
|
13
|
-
lines.push(`
|
|
13
|
+
lines.push(`Path: ${entry.path}`);
|
|
14
14
|
if (entry.size !== void 0 || metadata?.size !== void 0) {
|
|
15
15
|
const size = metadata?.size ?? entry.size;
|
|
16
16
|
lines.push(`Size: ${formatSize(size)}`);
|
|
@@ -29,20 +29,131 @@ function formatMetadata(entry, metadata) {
|
|
|
29
29
|
const display = hash.length > 20 ? `${hash.slice(0, 20)}...` : hash;
|
|
30
30
|
lines.push(`Hash: ${display}`);
|
|
31
31
|
}
|
|
32
|
-
if (
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
if (metadata?.mountPath) lines.push(`Mount: ${metadata.mountPath}`);
|
|
33
|
+
if (metadata?.uri) lines.push(`URI: ${metadata.uri}`);
|
|
34
|
+
const kinds = entry.kinds && entry.kinds.length > 0 ? entry.kinds : metadata?.extra?.kinds;
|
|
35
|
+
const kind = entry.kind ?? metadata?.extra?.kind;
|
|
36
|
+
if (kinds && kinds.length > 0) lines.push(`Kinds: ${kinds.join(" → ")}`);
|
|
37
|
+
else if (kind) lines.push(`Kind: ${kind}`);
|
|
38
|
+
if (metadata?.extra && Object.keys(metadata.extra).length > 0) {
|
|
39
|
+
const builtInFields = new Set([
|
|
40
|
+
"size",
|
|
41
|
+
"mimeType",
|
|
42
|
+
"childrenCount",
|
|
43
|
+
"hash",
|
|
44
|
+
"provider",
|
|
45
|
+
"mountPath",
|
|
46
|
+
"uri",
|
|
47
|
+
"permissions",
|
|
48
|
+
"kind",
|
|
49
|
+
"kinds"
|
|
50
|
+
]);
|
|
51
|
+
for (const [key, value] of Object.entries(metadata.extra)) {
|
|
52
|
+
if (builtInFields.has(key) || value === void 0) continue;
|
|
53
|
+
if (key === "inputSchema" && typeof value === "object" && value !== null) {
|
|
54
|
+
const schema = value;
|
|
55
|
+
if (schema.properties && typeof schema.properties === "object") {
|
|
56
|
+
lines.push("");
|
|
57
|
+
lines.push("InputSchema:");
|
|
58
|
+
const props = schema.properties;
|
|
59
|
+
for (const [propName, propSchema] of Object.entries(props)) {
|
|
60
|
+
const ps = propSchema;
|
|
61
|
+
const type = ps.type || "any";
|
|
62
|
+
const desc = ps.description ? ` - ${ps.description}` : "";
|
|
63
|
+
const req = Array.isArray(schema.required) && schema.required.includes(propName) ? "*" : "";
|
|
64
|
+
lines.push(` • ${propName}${req}: ${type}${desc}`);
|
|
65
|
+
}
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const displayKey = key.charAt(0).toUpperCase() + key.slice(1);
|
|
70
|
+
const displayValue = formatValue(value);
|
|
71
|
+
if (displayValue.includes("\n")) {
|
|
72
|
+
lines.push("");
|
|
73
|
+
lines.push(`${displayKey}:`);
|
|
74
|
+
for (const line of displayValue.split("\n")) lines.push(` ${line}`);
|
|
75
|
+
} else lines.push(`${displayKey}: ${displayValue}`);
|
|
76
|
+
}
|
|
37
77
|
}
|
|
38
|
-
|
|
78
|
+
const actions = metadata?.actions ?? entry.actions;
|
|
79
|
+
lines.push("");
|
|
80
|
+
lines.push("─────── Actions ───────");
|
|
81
|
+
if (actions && actions.length > 0) {
|
|
82
|
+
for (let i = 0; i < actions.length; i++) {
|
|
83
|
+
const action = actions[i];
|
|
84
|
+
if (action) lines.push(`[${i + 1}] ${action.name}`);
|
|
85
|
+
}
|
|
39
86
|
lines.push("");
|
|
40
|
-
lines.push(
|
|
41
|
-
}
|
|
42
|
-
if (metadata?.uri) lines.push(`URI: ${metadata.uri}`);
|
|
87
|
+
lines.push("(F4 to execute)");
|
|
88
|
+
} else lines.push("(none)");
|
|
43
89
|
return lines;
|
|
44
90
|
}
|
|
45
91
|
/**
|
|
92
|
+
* Format a value for display
|
|
93
|
+
*/
|
|
94
|
+
function formatValue(value) {
|
|
95
|
+
if (value === null || value === void 0) return "";
|
|
96
|
+
if (typeof value === "string") return value;
|
|
97
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
98
|
+
if (Array.isArray(value)) {
|
|
99
|
+
if (value.length === 0) return "[]";
|
|
100
|
+
if (value.every((v) => typeof v === "string" || typeof v === "number")) return value.join(", ");
|
|
101
|
+
if (value.every((v) => typeof v === "object" && v !== null && "name" in v)) return formatNamedItems(value);
|
|
102
|
+
try {
|
|
103
|
+
return JSON.stringify(value, null, 2);
|
|
104
|
+
} catch {
|
|
105
|
+
return "[unable to display]";
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (typeof value === "object") {
|
|
109
|
+
const obj = value;
|
|
110
|
+
if (isSchemaProperties(obj)) return formatSchemaProperties(obj);
|
|
111
|
+
try {
|
|
112
|
+
return JSON.stringify(value, null, 2);
|
|
113
|
+
} catch {
|
|
114
|
+
return "[unable to display]";
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return String(value);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Check if object looks like JSON Schema properties
|
|
121
|
+
*/
|
|
122
|
+
function isSchemaProperties(obj) {
|
|
123
|
+
const values = Object.values(obj);
|
|
124
|
+
if (values.length === 0) return false;
|
|
125
|
+
return values.every((v) => typeof v === "object" && v !== null && ("type" in v || "$ref" in v));
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Format JSON Schema properties object
|
|
129
|
+
*/
|
|
130
|
+
function formatSchemaProperties(props) {
|
|
131
|
+
const lines = [];
|
|
132
|
+
for (const [name, schema] of Object.entries(props)) {
|
|
133
|
+
const s = schema;
|
|
134
|
+
const type = s.type || s.$ref || "any";
|
|
135
|
+
const desc = s.description ? ` - ${s.description}` : "";
|
|
136
|
+
lines.push(`• ${name}: ${type}${desc}`);
|
|
137
|
+
}
|
|
138
|
+
return lines.join("\n");
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Format array of named items (columns, fields, etc.)
|
|
142
|
+
*/
|
|
143
|
+
function formatNamedItems(items) {
|
|
144
|
+
const lines = [];
|
|
145
|
+
for (const item of items) {
|
|
146
|
+
const type = item.type ? `: ${item.type}` : "";
|
|
147
|
+
const desc = item.description ? ` - ${item.description}` : "";
|
|
148
|
+
const flags = [];
|
|
149
|
+
if (item.primaryKey) flags.push("PK");
|
|
150
|
+
if (item.nullable) flags.push("nullable");
|
|
151
|
+
const flagsStr = flags.length > 0 ? ` (${flags.join(", ")})` : "";
|
|
152
|
+
lines.push(`• ${item.name}${type}${flagsStr}${desc}`);
|
|
153
|
+
}
|
|
154
|
+
return lines.join("\n");
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
46
157
|
* Format date and time
|
|
47
158
|
*/
|
|
48
159
|
function formatDateTime(date) {
|
|
@@ -55,20 +166,6 @@ function formatDateTime(date) {
|
|
|
55
166
|
});
|
|
56
167
|
}
|
|
57
168
|
/**
|
|
58
|
-
* Word wrap text
|
|
59
|
-
*/
|
|
60
|
-
function wrapText(text, maxWidth) {
|
|
61
|
-
const words = text.split(/\s+/);
|
|
62
|
-
const lines = [];
|
|
63
|
-
let current = "";
|
|
64
|
-
for (const word of words) if (current.length + word.length + 1 > maxWidth) {
|
|
65
|
-
if (current) lines.push(current);
|
|
66
|
-
current = word;
|
|
67
|
-
} else current = current ? `${current} ${word}` : word;
|
|
68
|
-
if (current) lines.push(current);
|
|
69
|
-
return lines;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
169
|
* Create metadata panel component
|
|
73
170
|
*/
|
|
74
171
|
function createMetadataPanel(blessed, options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata-panel.mjs","names":[],"sources":["../../../src/explorer/components/metadata-panel.ts"],"sourcesContent":["/**\n * AFS Explorer Metadata Panel Component\n *\n * Right panel showing detailed metadata for selected entry.\n */\n\nimport type Blessed from \"blessed\";\nimport { Colors, formatSize, Icons } from \"../theme.js\";\nimport type { EntryMetadata, ExplorerEntry } from \"../types.js\";\n\nexport interface MetadataPanelOptions {\n parent: Blessed.Widgets.Node;\n width: string | number;\n height: string | number;\n top?: string | number;\n right?: string | number;\n}\n\n/**\n * Format metadata for display\n */\nexport function formatMetadata(entry: ExplorerEntry, metadata?: EntryMetadata): string[] {\n const lines: string[] = [];\n\n // Entry name with type indicator (only show icon for non-files)\n const icon = entry.type !== \"file\" ? Icons[entry.type] : \"\";\n const prefix = icon ? `${icon} ` : \"\";\n lines.push(`${prefix}${entry.name}`);\n lines.push(\"\");\n\n // Type\n lines.push(`Type: ${entry.type}`);\n\n // Size\n if (entry.size !== undefined || metadata?.size !== undefined) {\n const size = metadata?.size ?? entry.size;\n lines.push(`Size: ${formatSize(size!)}`);\n }\n\n // Children count\n if (entry.childrenCount !== undefined || metadata?.childrenCount !== undefined) {\n const count = metadata?.childrenCount ?? entry.childrenCount;\n lines.push(`Items: ${count}`);\n }\n\n // Modified date\n if (entry.modified || metadata?.modified) {\n const date = metadata?.modified ?? entry.modified;\n lines.push(`Modified: ${formatDateTime(date!)}`);\n }\n\n // Provider\n if (entry.provider || metadata?.provider) {\n lines.push(`Provider: ${metadata?.provider ?? entry.provider}`);\n }\n\n // Hash\n if (entry.hash || metadata?.hash) {\n const hash = metadata?.hash ?? entry.hash;\n // Truncate long hashes\n const display = hash!.length > 20 ? `${hash!.slice(0, 20)}...` : hash;\n lines.push(`Hash: ${display}`);\n }\n\n // Description\n if (entry.description || metadata?.description) {\n lines.push(\"\");\n lines.push(\"Description:\");\n const desc = metadata?.description ?? entry.description;\n // Word wrap description\n const wrapped = wrapText(desc!, 25);\n lines.push(...wrapped);\n }\n\n // Mount path\n if (metadata?.mountPath) {\n lines.push(\"\");\n lines.push(`Mount: ${metadata.mountPath}`);\n }\n\n // URI\n if (metadata?.uri) {\n lines.push(`URI: ${metadata.uri}`);\n }\n\n return lines;\n}\n\n/**\n * Format date and time\n */\nfunction formatDateTime(date: Date): string {\n return date.toLocaleString(\"en\", {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n}\n\n/**\n * Word wrap text\n */\nfunction wrapText(text: string, maxWidth: number): string[] {\n const words = text.split(/\\s+/);\n const lines: string[] = [];\n let current = \"\";\n\n for (const word of words) {\n if (current.length + word.length + 1 > maxWidth) {\n if (current) lines.push(current);\n current = word;\n } else {\n current = current ? `${current} ${word}` : word;\n }\n }\n if (current) lines.push(current);\n\n return lines;\n}\n\n/**\n * Create metadata panel component\n */\nexport function createMetadataPanel(blessed: typeof Blessed, options: MetadataPanelOptions) {\n const { parent, width, height, top = 0, right = 0 } = options;\n\n // Create box for metadata panel\n const panel = blessed.box({\n parent,\n top,\n right,\n width,\n height,\n tags: true,\n scrollable: true,\n alwaysScroll: true,\n style: {\n fg: Colors.fg.normal,\n bg: Colors.bg.main,\n },\n border: {\n type: \"line\",\n },\n label: \" Details \",\n });\n\n let currentEntry: ExplorerEntry | undefined;\n let _currentMetadata: EntryMetadata | undefined;\n\n return {\n element: panel,\n\n /**\n * Update panel with entry info\n */\n update(entry: ExplorerEntry, metadata?: EntryMetadata): void {\n currentEntry = entry;\n _currentMetadata = metadata;\n\n if (entry.type === \"up\") {\n panel.setContent(\" Parent directory\");\n (panel.screen as Blessed.Widgets.Screen)?.render();\n return;\n }\n\n const lines = formatMetadata(entry, metadata);\n panel.setContent(lines.map((l) => ` ${l}`).join(\"\\n\"));\n (panel.screen as Blessed.Widgets.Screen)?.render();\n },\n\n /**\n * Clear the panel\n */\n clear(): void {\n currentEntry = undefined;\n _currentMetadata = undefined;\n panel.setContent(\"\");\n (panel.screen as Blessed.Widgets.Screen)?.render();\n },\n\n /**\n * Get current entry\n */\n getCurrentEntry(): ExplorerEntry | undefined {\n return currentEntry;\n },\n\n /**\n * Destroy the component\n */\n destroy(): void {\n panel.destroy();\n },\n };\n}\n\nexport type MetadataPanel = ReturnType<typeof createMetadataPanel>;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"metadata-panel.mjs","names":[],"sources":["../../../src/explorer/components/metadata-panel.ts"],"sourcesContent":["/**\n * AFS Explorer Metadata Panel Component\n *\n * Right panel showing detailed metadata for selected entry.\n */\n\nimport type Blessed from \"blessed\";\nimport { Colors, formatSize, Icons } from \"../theme.js\";\nimport type { EntryMetadata, ExplorerEntry } from \"../types.js\";\n\nexport interface MetadataPanelOptions {\n parent: Blessed.Widgets.Node;\n width: string | number;\n height: string | number;\n top?: string | number;\n right?: string | number;\n}\n\n/**\n * Format metadata for display\n */\nexport function formatMetadata(entry: ExplorerEntry, metadata?: EntryMetadata): string[] {\n const lines: string[] = [];\n\n // Entry name with type indicator (only show icon for non-files)\n const icon = entry.type !== \"file\" ? Icons[entry.type] : \"\";\n const prefix = icon ? `${icon} ` : \"\";\n lines.push(`${prefix}${entry.name}`);\n lines.push(\"\");\n\n // Path\n lines.push(`Path: ${entry.path}`);\n\n // Size\n if (entry.size !== undefined || metadata?.size !== undefined) {\n const size = metadata?.size ?? entry.size;\n lines.push(`Size: ${formatSize(size!)}`);\n }\n\n // Children count\n if (entry.childrenCount !== undefined || metadata?.childrenCount !== undefined) {\n const count = metadata?.childrenCount ?? entry.childrenCount;\n lines.push(`Items: ${count}`);\n }\n\n // Modified date\n if (entry.modified || metadata?.modified) {\n const date = metadata?.modified ?? entry.modified;\n lines.push(`Modified: ${formatDateTime(date!)}`);\n }\n\n // Provider\n if (entry.provider || metadata?.provider) {\n lines.push(`Provider: ${metadata?.provider ?? entry.provider}`);\n }\n\n // Hash\n if (entry.hash || metadata?.hash) {\n const hash = metadata?.hash ?? entry.hash;\n // Truncate long hashes\n const display = hash!.length > 20 ? `${hash!.slice(0, 20)}...` : hash;\n lines.push(`Hash: ${display}`);\n }\n\n // Mount path\n if (metadata?.mountPath) {\n lines.push(`Mount: ${metadata.mountPath}`);\n }\n\n // URI\n if (metadata?.uri) {\n lines.push(`URI: ${metadata.uri}`);\n }\n\n // Kind/Kinds information (show one or the other, avoid redundancy)\n // Prefer entry.kinds/kind, fallback to metadata.extra.kinds/kind\n const kinds =\n entry.kinds && entry.kinds.length > 0\n ? entry.kinds\n : (metadata?.extra?.kinds as string[] | undefined);\n const kind = entry.kind ?? (metadata?.extra?.kind as string | undefined);\n\n if (kinds && kinds.length > 0) {\n lines.push(`Kinds: ${kinds.join(\" → \")}`);\n } else if (kind) {\n lines.push(`Kind: ${kind}`);\n }\n\n // Display all meta fields from extra (flat, same level as other fields)\n if (metadata?.extra && Object.keys(metadata.extra).length > 0) {\n // Filter out built-in fields that are already displayed above\n const builtInFields = new Set([\n \"size\",\n \"mimeType\",\n \"childrenCount\",\n \"hash\",\n \"provider\",\n \"mountPath\",\n \"uri\",\n \"permissions\",\n \"kind\",\n \"kinds\",\n ]);\n\n for (const [key, value] of Object.entries(metadata.extra)) {\n if (builtInFields.has(key) || value === undefined) continue;\n\n // Special handling for inputSchema - show properties nicely\n if (key === \"inputSchema\" && typeof value === \"object\" && value !== null) {\n const schema = value as Record<string, unknown>;\n if (schema.properties && typeof schema.properties === \"object\") {\n lines.push(\"\");\n lines.push(\"InputSchema:\");\n const props = schema.properties as Record<string, unknown>;\n for (const [propName, propSchema] of Object.entries(props)) {\n const ps = propSchema as Record<string, unknown>;\n const type = ps.type || \"any\";\n const desc = ps.description ? ` - ${ps.description}` : \"\";\n const req =\n Array.isArray(schema.required) && schema.required.includes(propName) ? \"*\" : \"\";\n lines.push(` • ${propName}${req}: ${type}${desc}`);\n }\n continue;\n }\n }\n\n // Capitalize first letter of key for display\n const displayKey = key.charAt(0).toUpperCase() + key.slice(1);\n const displayValue = formatValue(value);\n\n if (displayValue.includes(\"\\n\")) {\n lines.push(\"\");\n lines.push(`${displayKey}:`);\n for (const line of displayValue.split(\"\\n\")) {\n lines.push(` ${line}`);\n }\n } else {\n lines.push(`${displayKey}: ${displayValue}`);\n }\n }\n }\n\n // Actions section (prefer metadata.actions from stat, fallback to entry.actions)\n const actions = metadata?.actions ?? entry.actions;\n lines.push(\"\");\n lines.push(\"─────── Actions ───────\");\n if (actions && actions.length > 0) {\n for (let i = 0; i < actions.length; i++) {\n const action = actions[i];\n if (action) {\n lines.push(`[${i + 1}] ${action.name}`);\n }\n }\n lines.push(\"\");\n lines.push(\"(F4 to execute)\");\n } else {\n lines.push(\"(none)\");\n }\n\n return lines;\n}\n\n/**\n * Format a value for display\n */\nfunction formatValue(value: unknown): string {\n if (value === null || value === undefined) {\n return \"\";\n }\n if (typeof value === \"string\") {\n return value;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n if (Array.isArray(value)) {\n if (value.length === 0) return \"[]\";\n // Simple arrays of primitives\n if (value.every((v) => typeof v === \"string\" || typeof v === \"number\")) {\n return value.join(\", \");\n }\n // Arrays of objects with name/type (like columns, fields, properties)\n if (value.every((v) => typeof v === \"object\" && v !== null && \"name\" in v)) {\n return formatNamedItems(\n value as Array<{ name: string; type?: string; description?: string }>,\n );\n }\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return \"[unable to display]\";\n }\n }\n if (typeof value === \"object\") {\n // Check if it's a JSON Schema properties object\n const obj = value as Record<string, unknown>;\n if (isSchemaProperties(obj)) {\n return formatSchemaProperties(obj);\n }\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return \"[unable to display]\";\n }\n }\n return String(value);\n}\n\n/**\n * Check if object looks like JSON Schema properties\n */\nfunction isSchemaProperties(obj: Record<string, unknown>): boolean {\n const values = Object.values(obj);\n if (values.length === 0) return false;\n // Check if values look like schema definitions (have type property)\n return values.every((v) => typeof v === \"object\" && v !== null && (\"type\" in v || \"$ref\" in v));\n}\n\n/**\n * Format JSON Schema properties object\n */\nfunction formatSchemaProperties(props: Record<string, unknown>): string {\n const lines: string[] = [];\n for (const [name, schema] of Object.entries(props)) {\n const s = schema as Record<string, unknown>;\n const type = s.type || s.$ref || \"any\";\n const desc = s.description ? ` - ${s.description}` : \"\";\n lines.push(`• ${name}: ${type}${desc}`);\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Format array of named items (columns, fields, etc.)\n */\nfunction formatNamedItems(\n items: Array<{\n name: string;\n type?: string;\n description?: string;\n nullable?: boolean;\n primaryKey?: boolean;\n }>,\n): string {\n const lines: string[] = [];\n for (const item of items) {\n const type = item.type ? `: ${item.type}` : \"\";\n const desc = item.description ? ` - ${item.description}` : \"\";\n // Add flags for nullable and primaryKey\n const flags: string[] = [];\n if (item.primaryKey) flags.push(\"PK\");\n if (item.nullable) flags.push(\"nullable\");\n const flagsStr = flags.length > 0 ? ` (${flags.join(\", \")})` : \"\";\n lines.push(`• ${item.name}${type}${flagsStr}${desc}`);\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Format date and time\n */\nfunction formatDateTime(date: Date): string {\n return date.toLocaleString(\"en\", {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n}\n\n/**\n * Create metadata panel component\n */\nexport function createMetadataPanel(blessed: typeof Blessed, options: MetadataPanelOptions) {\n const { parent, width, height, top = 0, right = 0 } = options;\n\n // Create box for metadata panel\n const panel = blessed.box({\n parent,\n top,\n right,\n width,\n height,\n tags: true,\n scrollable: true,\n alwaysScroll: true,\n style: {\n fg: Colors.fg.normal,\n bg: Colors.bg.main,\n },\n border: {\n type: \"line\",\n },\n label: \" Details \",\n });\n\n let currentEntry: ExplorerEntry | undefined;\n let _currentMetadata: EntryMetadata | undefined;\n\n return {\n element: panel,\n\n /**\n * Update panel with entry info\n */\n update(entry: ExplorerEntry, metadata?: EntryMetadata): void {\n currentEntry = entry;\n _currentMetadata = metadata;\n\n if (entry.type === \"up\") {\n panel.setContent(\" Parent directory\");\n (panel.screen as Blessed.Widgets.Screen)?.render();\n return;\n }\n\n const lines = formatMetadata(entry, metadata);\n panel.setContent(lines.map((l) => ` ${l}`).join(\"\\n\"));\n (panel.screen as Blessed.Widgets.Screen)?.render();\n },\n\n /**\n * Clear the panel\n */\n clear(): void {\n currentEntry = undefined;\n _currentMetadata = undefined;\n panel.setContent(\"\");\n (panel.screen as Blessed.Widgets.Screen)?.render();\n },\n\n /**\n * Get current entry\n */\n getCurrentEntry(): ExplorerEntry | undefined {\n return currentEntry;\n },\n\n /**\n * Destroy the component\n */\n destroy(): void {\n panel.destroy();\n },\n };\n}\n\nexport type MetadataPanel = ReturnType<typeof createMetadataPanel>;\n"],"mappings":";;;;;;AAqBA,SAAgB,eAAe,OAAsB,UAAoC;CACvF,MAAM,QAAkB,EAAE;CAG1B,MAAM,OAAO,MAAM,SAAS,SAAS,MAAM,MAAM,QAAQ;CACzD,MAAM,SAAS,OAAO,GAAG,KAAK,KAAK;AACnC,OAAM,KAAK,GAAG,SAAS,MAAM,OAAO;AACpC,OAAM,KAAK,GAAG;AAGd,OAAM,KAAK,SAAS,MAAM,OAAO;AAGjC,KAAI,MAAM,SAAS,UAAa,UAAU,SAAS,QAAW;EAC5D,MAAM,OAAO,UAAU,QAAQ,MAAM;AACrC,QAAM,KAAK,SAAS,WAAW,KAAM,GAAG;;AAI1C,KAAI,MAAM,kBAAkB,UAAa,UAAU,kBAAkB,QAAW;EAC9E,MAAM,QAAQ,UAAU,iBAAiB,MAAM;AAC/C,QAAM,KAAK,UAAU,QAAQ;;AAI/B,KAAI,MAAM,YAAY,UAAU,UAAU;EACxC,MAAM,OAAO,UAAU,YAAY,MAAM;AACzC,QAAM,KAAK,aAAa,eAAe,KAAM,GAAG;;AAIlD,KAAI,MAAM,YAAY,UAAU,SAC9B,OAAM,KAAK,aAAa,UAAU,YAAY,MAAM,WAAW;AAIjE,KAAI,MAAM,QAAQ,UAAU,MAAM;EAChC,MAAM,OAAO,UAAU,QAAQ,MAAM;EAErC,MAAM,UAAU,KAAM,SAAS,KAAK,GAAG,KAAM,MAAM,GAAG,GAAG,CAAC,OAAO;AACjE,QAAM,KAAK,SAAS,UAAU;;AAIhC,KAAI,UAAU,UACZ,OAAM,KAAK,UAAU,SAAS,YAAY;AAI5C,KAAI,UAAU,IACZ,OAAM,KAAK,QAAQ,SAAS,MAAM;CAKpC,MAAM,QACJ,MAAM,SAAS,MAAM,MAAM,SAAS,IAChC,MAAM,QACL,UAAU,OAAO;CACxB,MAAM,OAAO,MAAM,QAAS,UAAU,OAAO;AAE7C,KAAI,SAAS,MAAM,SAAS,EAC1B,OAAM,KAAK,UAAU,MAAM,KAAK,MAAM,GAAG;UAChC,KACT,OAAM,KAAK,SAAS,OAAO;AAI7B,KAAI,UAAU,SAAS,OAAO,KAAK,SAAS,MAAM,CAAC,SAAS,GAAG;EAE7D,MAAM,gBAAgB,IAAI,IAAI;GAC5B;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;AAEF,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,SAAS,MAAM,EAAE;AACzD,OAAI,cAAc,IAAI,IAAI,IAAI,UAAU,OAAW;AAGnD,OAAI,QAAQ,iBAAiB,OAAO,UAAU,YAAY,UAAU,MAAM;IACxE,MAAM,SAAS;AACf,QAAI,OAAO,cAAc,OAAO,OAAO,eAAe,UAAU;AAC9D,WAAM,KAAK,GAAG;AACd,WAAM,KAAK,eAAe;KAC1B,MAAM,QAAQ,OAAO;AACrB,UAAK,MAAM,CAAC,UAAU,eAAe,OAAO,QAAQ,MAAM,EAAE;MAC1D,MAAM,KAAK;MACX,MAAM,OAAO,GAAG,QAAQ;MACxB,MAAM,OAAO,GAAG,cAAc,MAAM,GAAG,gBAAgB;MACvD,MAAM,MACJ,MAAM,QAAQ,OAAO,SAAS,IAAI,OAAO,SAAS,SAAS,SAAS,GAAG,MAAM;AAC/E,YAAM,KAAK,OAAO,WAAW,IAAI,IAAI,OAAO,OAAO;;AAErD;;;GAKJ,MAAM,aAAa,IAAI,OAAO,EAAE,CAAC,aAAa,GAAG,IAAI,MAAM,EAAE;GAC7D,MAAM,eAAe,YAAY,MAAM;AAEvC,OAAI,aAAa,SAAS,KAAK,EAAE;AAC/B,UAAM,KAAK,GAAG;AACd,UAAM,KAAK,GAAG,WAAW,GAAG;AAC5B,SAAK,MAAM,QAAQ,aAAa,MAAM,KAAK,CACzC,OAAM,KAAK,KAAK,OAAO;SAGzB,OAAM,KAAK,GAAG,WAAW,IAAI,eAAe;;;CAMlD,MAAM,UAAU,UAAU,WAAW,MAAM;AAC3C,OAAM,KAAK,GAAG;AACd,OAAM,KAAK,0BAA0B;AACrC,KAAI,WAAW,QAAQ,SAAS,GAAG;AACjC,OAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;GACvC,MAAM,SAAS,QAAQ;AACvB,OAAI,OACF,OAAM,KAAK,IAAI,IAAI,EAAE,IAAI,OAAO,OAAO;;AAG3C,QAAM,KAAK,GAAG;AACd,QAAM,KAAK,kBAAkB;OAE7B,OAAM,KAAK,SAAS;AAGtB,QAAO;;;;;AAMT,SAAS,YAAY,OAAwB;AAC3C,KAAI,UAAU,QAAQ,UAAU,OAC9B,QAAO;AAET,KAAI,OAAO,UAAU,SACnB,QAAO;AAET,KAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAChD,QAAO,OAAO,MAAM;AAEtB,KAAI,MAAM,QAAQ,MAAM,EAAE;AACxB,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,MAAI,MAAM,OAAO,MAAM,OAAO,MAAM,YAAY,OAAO,MAAM,SAAS,CACpE,QAAO,MAAM,KAAK,KAAK;AAGzB,MAAI,MAAM,OAAO,MAAM,OAAO,MAAM,YAAY,MAAM,QAAQ,UAAU,EAAE,CACxE,QAAO,iBACL,MACD;AAEH,MAAI;AACF,UAAO,KAAK,UAAU,OAAO,MAAM,EAAE;UAC/B;AACN,UAAO;;;AAGX,KAAI,OAAO,UAAU,UAAU;EAE7B,MAAM,MAAM;AACZ,MAAI,mBAAmB,IAAI,CACzB,QAAO,uBAAuB,IAAI;AAEpC,MAAI;AACF,UAAO,KAAK,UAAU,OAAO,MAAM,EAAE;UAC/B;AACN,UAAO;;;AAGX,QAAO,OAAO,MAAM;;;;;AAMtB,SAAS,mBAAmB,KAAuC;CACjE,MAAM,SAAS,OAAO,OAAO,IAAI;AACjC,KAAI,OAAO,WAAW,EAAG,QAAO;AAEhC,QAAO,OAAO,OAAO,MAAM,OAAO,MAAM,YAAY,MAAM,SAAS,UAAU,KAAK,UAAU,GAAG;;;;;AAMjG,SAAS,uBAAuB,OAAwC;CACtE,MAAM,QAAkB,EAAE;AAC1B,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,MAAM,EAAE;EAClD,MAAM,IAAI;EACV,MAAM,OAAO,EAAE,QAAQ,EAAE,QAAQ;EACjC,MAAM,OAAO,EAAE,cAAc,MAAM,EAAE,gBAAgB;AACrD,QAAM,KAAK,KAAK,KAAK,IAAI,OAAO,OAAO;;AAEzC,QAAO,MAAM,KAAK,KAAK;;;;;AAMzB,SAAS,iBACP,OAOQ;CACR,MAAM,QAAkB,EAAE;AAC1B,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,KAAK,OAAO,KAAK,KAAK,SAAS;EAC5C,MAAM,OAAO,KAAK,cAAc,MAAM,KAAK,gBAAgB;EAE3D,MAAM,QAAkB,EAAE;AAC1B,MAAI,KAAK,WAAY,OAAM,KAAK,KAAK;AACrC,MAAI,KAAK,SAAU,OAAM,KAAK,WAAW;EACzC,MAAM,WAAW,MAAM,SAAS,IAAI,KAAK,MAAM,KAAK,KAAK,CAAC,KAAK;AAC/D,QAAM,KAAK,KAAK,KAAK,OAAO,OAAO,WAAW,OAAO;;AAEvD,QAAO,MAAM,KAAK,KAAK;;;;;AAMzB,SAAS,eAAe,MAAoB;AAC1C,QAAO,KAAK,eAAe,MAAM;EAC/B,MAAM;EACN,OAAO;EACP,KAAK;EACL,MAAM;EACN,QAAQ;EACT,CAAC;;;;;AAMJ,SAAgB,oBAAoB,SAAyB,SAA+B;CAC1F,MAAM,EAAE,QAAQ,OAAO,QAAQ,MAAM,GAAG,QAAQ,MAAM;CAGtD,MAAM,QAAQ,QAAQ,IAAI;EACxB;EACA;EACA;EACA;EACA;EACA,MAAM;EACN,YAAY;EACZ,cAAc;EACd,OAAO;GACL,IAAI,OAAO,GAAG;GACd,IAAI,OAAO,GAAG;GACf;EACD,QAAQ,EACN,MAAM,QACP;EACD,OAAO;EACR,CAAC;CAEF,IAAI;AAGJ,QAAO;EACL,SAAS;EAKT,OAAO,OAAsB,UAAgC;AAC3D,kBAAe;AAGf,OAAI,MAAM,SAAS,MAAM;AACvB,UAAM,WAAW,oBAAoB;AACrC,IAAC,MAAM,QAAmC,QAAQ;AAClD;;GAGF,MAAM,QAAQ,eAAe,OAAO,SAAS;AAC7C,SAAM,WAAW,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC;AACtD,GAAC,MAAM,QAAmC,QAAQ;;EAMpD,QAAc;AACZ,kBAAe;AAEf,SAAM,WAAW,GAAG;AACpB,GAAC,MAAM,QAAmC,QAAQ;;EAMpD,kBAA6C;AAC3C,UAAO;;EAMT,UAAgB;AACd,SAAM,SAAS;;EAElB"}
|
package/dist/explorer/screen.cjs
CHANGED
|
@@ -14,24 +14,23 @@ blessed = require_rolldown_runtime.__toESM(blessed);
|
|
|
14
14
|
|
|
15
15
|
//#region src/explorer/screen.ts
|
|
16
16
|
/**
|
|
17
|
-
* AFS Explorer Screen
|
|
18
|
-
*
|
|
19
|
-
* Main screen controller that manages all UI components and user interaction.
|
|
20
|
-
*/
|
|
21
|
-
/**
|
|
22
17
|
* Create and run the explorer screen
|
|
23
18
|
*/
|
|
24
19
|
async function createExplorerScreen(options) {
|
|
25
|
-
const {
|
|
20
|
+
const { afs, startPath = "/", version } = options;
|
|
21
|
+
const isRemote = !!(options.input || options.output);
|
|
26
22
|
const store = require_state.createStore(require_actions.createInitialState(startPath));
|
|
27
23
|
const registry = require_keybindings.createDefaultRegistry();
|
|
28
|
-
const
|
|
24
|
+
const screenOpts = {
|
|
29
25
|
smartCSR: true,
|
|
30
26
|
title: "AFS Explorer",
|
|
31
|
-
terminal: "xterm",
|
|
27
|
+
terminal: options.terminal || "xterm",
|
|
32
28
|
fullUnicode: true,
|
|
33
29
|
warnings: false
|
|
34
|
-
}
|
|
30
|
+
};
|
|
31
|
+
if (options.input) screenOpts.input = options.input;
|
|
32
|
+
if (options.output) screenOpts.output = options.output;
|
|
33
|
+
const screen = blessed.default.screen(screenOpts);
|
|
35
34
|
require_status_bar.createStatusBar(blessed.default, {
|
|
36
35
|
parent: screen,
|
|
37
36
|
store,
|
|
@@ -60,12 +59,13 @@ async function createExplorerScreen(options) {
|
|
|
60
59
|
bottom: 0
|
|
61
60
|
});
|
|
62
61
|
const dialogs = require_dialog.createDialogManager(blessed.default, { parent: screen });
|
|
62
|
+
const mountCount = afs.getMounts().length;
|
|
63
63
|
async function loadPath(path) {
|
|
64
64
|
store.setState({
|
|
65
65
|
loading: true,
|
|
66
66
|
error: void 0
|
|
67
67
|
});
|
|
68
|
-
const result = await require_actions.loadDirectory(
|
|
68
|
+
const result = await require_actions.loadDirectory(afs, path);
|
|
69
69
|
store.setState({
|
|
70
70
|
currentPath: path,
|
|
71
71
|
entries: result.entries,
|
|
@@ -79,7 +79,7 @@ async function createExplorerScreen(options) {
|
|
|
79
79
|
async function updateMetadata() {
|
|
80
80
|
const selected = require_actions.navigation.getSelected(store.getState());
|
|
81
81
|
if (selected) {
|
|
82
|
-
const metadata = await require_actions.loadMetadata(
|
|
82
|
+
const metadata = await require_actions.loadMetadata(afs, selected);
|
|
83
83
|
metadataPanel.update(selected, metadata);
|
|
84
84
|
} else metadataPanel.clear();
|
|
85
85
|
}
|
|
@@ -99,7 +99,7 @@ async function createExplorerScreen(options) {
|
|
|
99
99
|
if (!selected || selected.type === "up") return;
|
|
100
100
|
if (selected.type === "file") {
|
|
101
101
|
dialogs.showLoading("Loading file");
|
|
102
|
-
const result = await require_actions.readFileContent(
|
|
102
|
+
const result = await require_actions.readFileContent(afs, selected.path);
|
|
103
103
|
if (result.error) dialogs.showError("View Error", result.error);
|
|
104
104
|
else dialogs.showFileView(selected.path, result.content);
|
|
105
105
|
} else if (selected.type === "directory") await loadPath(selected.path);
|
|
@@ -108,16 +108,61 @@ async function createExplorerScreen(options) {
|
|
|
108
108
|
const selected = require_actions.navigation.getSelected(store.getState());
|
|
109
109
|
if (!selected || selected.type === "up") return;
|
|
110
110
|
dialogs.showLoading("Getting explain info");
|
|
111
|
-
const result = await require_actions.getExplain(
|
|
111
|
+
const result = await require_actions.getExplain(afs, selected.path);
|
|
112
112
|
if (result.error) dialogs.showError("Explain Error", result.error);
|
|
113
113
|
else dialogs.showExplain(selected.path, result.content);
|
|
114
114
|
}
|
|
115
|
+
async function runAction(item) {
|
|
116
|
+
if (item.inputSchema) dialogs.showParamsInput(item.path, item.inputSchema, async (params) => {
|
|
117
|
+
dialogs.showLoading("Executing action");
|
|
118
|
+
const result = await require_actions.executeAction(afs, item.path, item.name, params);
|
|
119
|
+
dialogs.showActionResult(item.name, result.success, result.message, result.data);
|
|
120
|
+
});
|
|
121
|
+
else {
|
|
122
|
+
dialogs.showLoading("Executing action");
|
|
123
|
+
const result = await require_actions.executeAction(afs, item.path, item.name);
|
|
124
|
+
dialogs.showActionResult(item.name, result.success, result.message, result.data);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
115
127
|
async function handleExec() {
|
|
116
128
|
const selected = require_actions.navigation.getSelected(store.getState());
|
|
117
129
|
if (!selected || selected.type === "up") return;
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
|
|
130
|
+
const metadata = await require_actions.loadMetadata(afs, selected);
|
|
131
|
+
const actionItems = [];
|
|
132
|
+
const actions = metadata?.actions ?? selected.actions;
|
|
133
|
+
if (actions && actions.length > 0) for (const action of actions) {
|
|
134
|
+
let inputSchema = action.inputSchema;
|
|
135
|
+
if (!inputSchema) try {
|
|
136
|
+
const actionPath = `${selected.path}/.actions/${action.name}`;
|
|
137
|
+
inputSchema = (await afs.stat(actionPath)).data?.meta?.inputSchema;
|
|
138
|
+
} catch {}
|
|
139
|
+
actionItems.push({
|
|
140
|
+
name: action.name,
|
|
141
|
+
path: `${selected.path}/.actions/${action.name}`,
|
|
142
|
+
description: action.description,
|
|
143
|
+
inputSchema
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
if (selected.type === "exec") {
|
|
147
|
+
const inputSchema = metadata?.extra?.inputSchema;
|
|
148
|
+
actionItems.push({
|
|
149
|
+
name: "Execute",
|
|
150
|
+
path: selected.path,
|
|
151
|
+
description: "Execute this node directly",
|
|
152
|
+
inputSchema
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
if (actionItems.length === 0) {
|
|
156
|
+
dialogs.showError("No Actions", `${selected.name} has no available actions`);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (actionItems.length === 1) {
|
|
160
|
+
await runAction(actionItems[0]);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
dialogs.showActionPicker(selected.path, actionItems, async (item) => {
|
|
164
|
+
await runAction(item);
|
|
165
|
+
});
|
|
121
166
|
}
|
|
122
167
|
async function handleRefresh() {
|
|
123
168
|
await loadPath(store.getState().currentPath);
|
|
@@ -129,13 +174,19 @@ async function createExplorerScreen(options) {
|
|
|
129
174
|
exec: handleExec,
|
|
130
175
|
refresh: handleRefresh,
|
|
131
176
|
quit: () => {
|
|
132
|
-
dialogs.showConfirm("Are you sure you want to quit?", () => {
|
|
133
|
-
|
|
134
|
-
|
|
177
|
+
dialogs.showConfirm("Are you sure you want to quit?", async () => {
|
|
178
|
+
if (isRemote || options.onExit) {
|
|
179
|
+
screen.destroy();
|
|
180
|
+
options.onExit?.();
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const logo = require_index.colors.brightCyan("▄▀█ █▀▀ █▀\n█▀█ █▀░ ▄█\n");
|
|
184
|
+
const tagline = require_index.colors.dim("Agentic File System");
|
|
135
185
|
const versionPart = require_index.colors.green(`v${version}`);
|
|
136
186
|
const mountPart = require_index.colors.yellow(`${mountCount} ${mountCount === 1 ? "mount" : "mounts"}`);
|
|
137
|
-
|
|
138
|
-
|
|
187
|
+
const farewell = `\n${logo}${tagline}\n\n${`${versionPart} ${require_index.colors.dim("•")} ${mountPart}`}\n${require_index.colors.dim("Thanks for using AFS Explorer!")}\n`;
|
|
188
|
+
screen.destroy();
|
|
189
|
+
process.stdout.write(farewell);
|
|
139
190
|
process.exit(0);
|
|
140
191
|
});
|
|
141
192
|
},
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { AFS } from "@aigne/afs";
|
|
2
|
+
|
|
3
|
+
//#region src/explorer/screen.d.ts
|
|
4
|
+
interface ExplorerScreenOptions {
|
|
5
|
+
afs: AFS;
|
|
6
|
+
startPath?: string;
|
|
7
|
+
version: string;
|
|
8
|
+
/** Custom input stream (for remote/WebSocket sessions). */
|
|
9
|
+
input?: NodeJS.ReadableStream;
|
|
10
|
+
/** Custom output stream (for remote/WebSocket sessions). */
|
|
11
|
+
output?: NodeJS.WritableStream;
|
|
12
|
+
/** Terminal type override. */
|
|
13
|
+
terminal?: string;
|
|
14
|
+
/** Called when the screen is destroyed (instead of process.exit). */
|
|
15
|
+
onExit?: () => void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Create and run the explorer screen
|
|
19
|
+
*/
|
|
20
|
+
declare function createExplorerScreen(options: ExplorerScreenOptions): Promise<void>;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { createExplorerScreen };
|
|
23
|
+
//# sourceMappingURL=screen.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screen.d.cts","names":[],"sources":["../../src/explorer/screen.ts"],"mappings":";;;UA6BiB,qBAAA;EACf,GAAA,EAAK,GAAA;EACL,SAAA;EACA,OAAA;EAI8B;EAF9B,KAAA,GAAQ,MAAA,CAAO,cAAA;EAJV;EAML,MAAA,GAAS,MAAA,CAAO,cAAA;EAJhB;EAMA,QAAA;EAJQ;EAMR,MAAA;AAAA;;;;iBAMoB,oBAAA,CAAqB,OAAA,EAAS,qBAAA,GAAwB,OAAA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { AFS } from "@aigne/afs";
|
|
2
|
+
|
|
3
|
+
//#region src/explorer/screen.d.ts
|
|
4
|
+
interface ExplorerScreenOptions {
|
|
5
|
+
afs: AFS;
|
|
6
|
+
startPath?: string;
|
|
7
|
+
version: string;
|
|
8
|
+
/** Custom input stream (for remote/WebSocket sessions). */
|
|
9
|
+
input?: NodeJS.ReadableStream;
|
|
10
|
+
/** Custom output stream (for remote/WebSocket sessions). */
|
|
11
|
+
output?: NodeJS.WritableStream;
|
|
12
|
+
/** Terminal type override. */
|
|
13
|
+
terminal?: string;
|
|
14
|
+
/** Called when the screen is destroyed (instead of process.exit). */
|
|
15
|
+
onExit?: () => void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Create and run the explorer screen
|
|
19
|
+
*/
|
|
20
|
+
declare function createExplorerScreen(options: ExplorerScreenOptions): Promise<void>;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { createExplorerScreen };
|
|
23
|
+
//# sourceMappingURL=screen.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screen.d.mts","names":[],"sources":["../../src/explorer/screen.ts"],"mappings":";;;UA6BiB,qBAAA;EACf,GAAA,EAAK,GAAA;EACL,SAAA;EACA,OAAA;EAI8B;EAF9B,KAAA,GAAQ,MAAA,CAAO,cAAA;EAJV;EAML,MAAA,GAAS,MAAA,CAAO,cAAA;EAJhB;EAMA,QAAA;EAJQ;EAMR,MAAA;AAAA;;;;iBAMoB,oBAAA,CAAqB,OAAA,EAAS,qBAAA,GAAwB,OAAA"}
|
package/dist/explorer/screen.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { colors
|
|
1
|
+
import { colors } from "../ui/index.mjs";
|
|
2
2
|
import { createInitialState, executeAction, getExplain, loadDirectory, loadMetadata, navigation, readFileContent } from "./actions.mjs";
|
|
3
3
|
import { createDefaultRegistry } from "./keybindings.mjs";
|
|
4
4
|
import { createDialogManager } from "./components/dialog.mjs";
|
|
@@ -12,24 +12,23 @@ import blessed from "blessed";
|
|
|
12
12
|
|
|
13
13
|
//#region src/explorer/screen.ts
|
|
14
14
|
/**
|
|
15
|
-
* AFS Explorer Screen
|
|
16
|
-
*
|
|
17
|
-
* Main screen controller that manages all UI components and user interaction.
|
|
18
|
-
*/
|
|
19
|
-
/**
|
|
20
15
|
* Create and run the explorer screen
|
|
21
16
|
*/
|
|
22
17
|
async function createExplorerScreen(options) {
|
|
23
|
-
const {
|
|
18
|
+
const { afs, startPath = "/", version } = options;
|
|
19
|
+
const isRemote = !!(options.input || options.output);
|
|
24
20
|
const store = createStore(createInitialState(startPath));
|
|
25
21
|
const registry = createDefaultRegistry();
|
|
26
|
-
const
|
|
22
|
+
const screenOpts = {
|
|
27
23
|
smartCSR: true,
|
|
28
24
|
title: "AFS Explorer",
|
|
29
|
-
terminal: "xterm",
|
|
25
|
+
terminal: options.terminal || "xterm",
|
|
30
26
|
fullUnicode: true,
|
|
31
27
|
warnings: false
|
|
32
|
-
}
|
|
28
|
+
};
|
|
29
|
+
if (options.input) screenOpts.input = options.input;
|
|
30
|
+
if (options.output) screenOpts.output = options.output;
|
|
31
|
+
const screen = blessed.screen(screenOpts);
|
|
33
32
|
createStatusBar(blessed, {
|
|
34
33
|
parent: screen,
|
|
35
34
|
store,
|
|
@@ -58,12 +57,13 @@ async function createExplorerScreen(options) {
|
|
|
58
57
|
bottom: 0
|
|
59
58
|
});
|
|
60
59
|
const dialogs = createDialogManager(blessed, { parent: screen });
|
|
60
|
+
const mountCount = afs.getMounts().length;
|
|
61
61
|
async function loadPath(path) {
|
|
62
62
|
store.setState({
|
|
63
63
|
loading: true,
|
|
64
64
|
error: void 0
|
|
65
65
|
});
|
|
66
|
-
const result = await loadDirectory(
|
|
66
|
+
const result = await loadDirectory(afs, path);
|
|
67
67
|
store.setState({
|
|
68
68
|
currentPath: path,
|
|
69
69
|
entries: result.entries,
|
|
@@ -77,7 +77,7 @@ async function createExplorerScreen(options) {
|
|
|
77
77
|
async function updateMetadata() {
|
|
78
78
|
const selected = navigation.getSelected(store.getState());
|
|
79
79
|
if (selected) {
|
|
80
|
-
const metadata = await loadMetadata(
|
|
80
|
+
const metadata = await loadMetadata(afs, selected);
|
|
81
81
|
metadataPanel.update(selected, metadata);
|
|
82
82
|
} else metadataPanel.clear();
|
|
83
83
|
}
|
|
@@ -97,7 +97,7 @@ async function createExplorerScreen(options) {
|
|
|
97
97
|
if (!selected || selected.type === "up") return;
|
|
98
98
|
if (selected.type === "file") {
|
|
99
99
|
dialogs.showLoading("Loading file");
|
|
100
|
-
const result = await readFileContent(
|
|
100
|
+
const result = await readFileContent(afs, selected.path);
|
|
101
101
|
if (result.error) dialogs.showError("View Error", result.error);
|
|
102
102
|
else dialogs.showFileView(selected.path, result.content);
|
|
103
103
|
} else if (selected.type === "directory") await loadPath(selected.path);
|
|
@@ -106,16 +106,61 @@ async function createExplorerScreen(options) {
|
|
|
106
106
|
const selected = navigation.getSelected(store.getState());
|
|
107
107
|
if (!selected || selected.type === "up") return;
|
|
108
108
|
dialogs.showLoading("Getting explain info");
|
|
109
|
-
const result = await getExplain(
|
|
109
|
+
const result = await getExplain(afs, selected.path);
|
|
110
110
|
if (result.error) dialogs.showError("Explain Error", result.error);
|
|
111
111
|
else dialogs.showExplain(selected.path, result.content);
|
|
112
112
|
}
|
|
113
|
+
async function runAction(item) {
|
|
114
|
+
if (item.inputSchema) dialogs.showParamsInput(item.path, item.inputSchema, async (params) => {
|
|
115
|
+
dialogs.showLoading("Executing action");
|
|
116
|
+
const result = await executeAction(afs, item.path, item.name, params);
|
|
117
|
+
dialogs.showActionResult(item.name, result.success, result.message, result.data);
|
|
118
|
+
});
|
|
119
|
+
else {
|
|
120
|
+
dialogs.showLoading("Executing action");
|
|
121
|
+
const result = await executeAction(afs, item.path, item.name);
|
|
122
|
+
dialogs.showActionResult(item.name, result.success, result.message, result.data);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
113
125
|
async function handleExec() {
|
|
114
126
|
const selected = navigation.getSelected(store.getState());
|
|
115
127
|
if (!selected || selected.type === "up") return;
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
|
|
128
|
+
const metadata = await loadMetadata(afs, selected);
|
|
129
|
+
const actionItems = [];
|
|
130
|
+
const actions = metadata?.actions ?? selected.actions;
|
|
131
|
+
if (actions && actions.length > 0) for (const action of actions) {
|
|
132
|
+
let inputSchema = action.inputSchema;
|
|
133
|
+
if (!inputSchema) try {
|
|
134
|
+
const actionPath = `${selected.path}/.actions/${action.name}`;
|
|
135
|
+
inputSchema = (await afs.stat(actionPath)).data?.meta?.inputSchema;
|
|
136
|
+
} catch {}
|
|
137
|
+
actionItems.push({
|
|
138
|
+
name: action.name,
|
|
139
|
+
path: `${selected.path}/.actions/${action.name}`,
|
|
140
|
+
description: action.description,
|
|
141
|
+
inputSchema
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
if (selected.type === "exec") {
|
|
145
|
+
const inputSchema = metadata?.extra?.inputSchema;
|
|
146
|
+
actionItems.push({
|
|
147
|
+
name: "Execute",
|
|
148
|
+
path: selected.path,
|
|
149
|
+
description: "Execute this node directly",
|
|
150
|
+
inputSchema
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
if (actionItems.length === 0) {
|
|
154
|
+
dialogs.showError("No Actions", `${selected.name} has no available actions`);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (actionItems.length === 1) {
|
|
158
|
+
await runAction(actionItems[0]);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
dialogs.showActionPicker(selected.path, actionItems, async (item) => {
|
|
162
|
+
await runAction(item);
|
|
163
|
+
});
|
|
119
164
|
}
|
|
120
165
|
async function handleRefresh() {
|
|
121
166
|
await loadPath(store.getState().currentPath);
|
|
@@ -127,13 +172,19 @@ async function createExplorerScreen(options) {
|
|
|
127
172
|
exec: handleExec,
|
|
128
173
|
refresh: handleRefresh,
|
|
129
174
|
quit: () => {
|
|
130
|
-
dialogs.showConfirm("Are you sure you want to quit?", () => {
|
|
131
|
-
|
|
132
|
-
|
|
175
|
+
dialogs.showConfirm("Are you sure you want to quit?", async () => {
|
|
176
|
+
if (isRemote || options.onExit) {
|
|
177
|
+
screen.destroy();
|
|
178
|
+
options.onExit?.();
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const logo = colors.brightCyan("▄▀█ █▀▀ █▀\n█▀█ █▀░ ▄█\n");
|
|
182
|
+
const tagline = colors.dim("Agentic File System");
|
|
133
183
|
const versionPart = colors.green(`v${version}`);
|
|
134
184
|
const mountPart = colors.yellow(`${mountCount} ${mountCount === 1 ? "mount" : "mounts"}`);
|
|
135
|
-
|
|
136
|
-
|
|
185
|
+
const farewell = `\n${logo}${tagline}\n\n${`${versionPart} ${colors.dim("•")} ${mountPart}`}\n${colors.dim("Thanks for using AFS Explorer!")}\n`;
|
|
186
|
+
screen.destroy();
|
|
187
|
+
process.stdout.write(farewell);
|
|
137
188
|
process.exit(0);
|
|
138
189
|
});
|
|
139
190
|
},
|