@aigne/afs-cli 1.11.0-beta.1 → 1.11.0-beta.10
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/README.md +262 -15
- package/dist/_virtual/rolldown_runtime.cjs +29 -0
- package/dist/_virtual/rolldown_runtime.mjs +7 -0
- package/dist/cli.cjs +40 -0
- package/dist/cli.d.cts +2 -0
- package/dist/cli.d.mts +2 -1
- package/dist/cli.mjs +36 -24
- package/dist/cli.mjs.map +1 -0
- package/dist/config/afs-loader.cjs +578 -0
- package/dist/config/afs-loader.d.cts +19 -0
- package/dist/config/afs-loader.d.cts.map +1 -0
- package/dist/config/afs-loader.d.mts +19 -0
- package/dist/config/afs-loader.d.mts.map +1 -0
- package/dist/config/afs-loader.mjs +576 -0
- package/dist/config/afs-loader.mjs.map +1 -0
- package/dist/config/env.cjs +46 -0
- package/dist/config/env.mjs +46 -0
- package/dist/config/env.mjs.map +1 -0
- package/dist/config/loader.cjs +219 -0
- package/dist/config/loader.mjs +217 -0
- package/dist/config/loader.mjs.map +1 -0
- package/dist/config/mount-commands.cjs +226 -0
- package/dist/config/mount-commands.d.cts +14 -0
- package/dist/config/mount-commands.d.cts.map +1 -0
- package/dist/config/mount-commands.d.mts +14 -0
- package/dist/config/mount-commands.d.mts.map +1 -0
- package/dist/config/mount-commands.mjs +220 -0
- package/dist/config/mount-commands.mjs.map +1 -0
- package/dist/config/schema.cjs +99 -0
- package/dist/config/schema.mjs +98 -0
- package/dist/config/schema.mjs.map +1 -0
- 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 +98 -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 +99 -0
- package/dist/core/commands/exec.mjs.map +1 -0
- package/dist/core/commands/explain.cjs +278 -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 +279 -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 +222 -0
- package/dist/core/commands/mount.d.cts +35 -0
- package/dist/core/commands/mount.d.cts.map +1 -0
- package/dist/core/commands/mount.d.mts +35 -0
- package/dist/core/commands/mount.d.mts.map +1 -0
- package/dist/core/commands/mount.mjs +223 -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 +267 -0
- package/dist/core/commands/serve.d.mts +2 -0
- package/dist/core/commands/serve.mjs +267 -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 +18 -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 +19 -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 +99 -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 +98 -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/credential/auth-server.cjs +247 -0
- package/dist/credential/auth-server.mjs +247 -0
- package/dist/credential/auth-server.mjs.map +1 -0
- package/dist/credential/cli-auth-context.cjs +86 -0
- package/dist/credential/cli-auth-context.d.mts +1 -0
- package/dist/credential/cli-auth-context.mjs +86 -0
- package/dist/credential/cli-auth-context.mjs.map +1 -0
- package/dist/credential/index.cjs +5 -0
- package/dist/credential/index.d.mts +4 -0
- package/dist/credential/index.mjs +7 -0
- package/dist/credential/mcp-auth-context.cjs +186 -0
- package/dist/credential/mcp-auth-context.d.mts +1 -0
- package/dist/credential/mcp-auth-context.mjs +186 -0
- package/dist/credential/mcp-auth-context.mjs.map +1 -0
- package/dist/credential/resolver.cjs +127 -0
- package/dist/credential/resolver.d.mts +1 -0
- package/dist/credential/resolver.mjs +127 -0
- package/dist/credential/resolver.mjs.map +1 -0
- package/dist/credential/store.cjs +106 -0
- package/dist/credential/store.d.cts +30 -0
- package/dist/credential/store.d.cts.map +1 -0
- package/dist/credential/store.d.mts +30 -0
- package/dist/credential/store.d.mts.map +1 -0
- package/dist/credential/store.mjs +106 -0
- package/dist/credential/store.mjs.map +1 -0
- package/dist/errors.cjs +18 -0
- package/dist/errors.mjs +18 -0
- package/dist/errors.mjs.map +1 -0
- package/dist/explorer/actions.cjs +311 -0
- package/dist/explorer/actions.mjs +305 -0
- package/dist/explorer/actions.mjs.map +1 -0
- package/dist/explorer/components/dialog.cjs +508 -0
- package/dist/explorer/components/dialog.mjs +509 -0
- package/dist/explorer/components/dialog.mjs.map +1 -0
- package/dist/explorer/components/file-list.cjs +107 -0
- package/dist/explorer/components/file-list.mjs +107 -0
- package/dist/explorer/components/file-list.mjs.map +1 -0
- package/dist/explorer/components/function-bar.cjs +55 -0
- package/dist/explorer/components/function-bar.mjs +55 -0
- package/dist/explorer/components/function-bar.mjs.map +1 -0
- package/dist/explorer/components/index.cjs +5 -0
- package/dist/explorer/components/index.mjs +7 -0
- package/dist/explorer/components/metadata-panel.cjs +219 -0
- package/dist/explorer/components/metadata-panel.mjs +219 -0
- package/dist/explorer/components/metadata-panel.mjs.map +1 -0
- package/dist/explorer/components/status-bar.cjs +53 -0
- package/dist/explorer/components/status-bar.mjs +54 -0
- package/dist/explorer/components/status-bar.mjs.map +1 -0
- package/dist/explorer/keybindings.cjs +214 -0
- package/dist/explorer/keybindings.mjs +213 -0
- package/dist/explorer/keybindings.mjs.map +1 -0
- package/dist/explorer/screen.cjs +251 -0
- 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 +250 -0
- package/dist/explorer/screen.mjs.map +1 -0
- package/dist/explorer/state.cjs +53 -0
- package/dist/explorer/state.mjs +53 -0
- package/dist/explorer/state.mjs.map +1 -0
- package/dist/explorer/theme.cjs +160 -0
- package/dist/explorer/theme.mjs +157 -0
- package/dist/explorer/theme.mjs.map +1 -0
- package/dist/index.cjs +12 -0
- package/dist/index.d.cts +6 -0
- package/dist/index.d.mts +7 -4
- package/dist/index.mjs +7 -2
- package/dist/mcp/http-transport.cjs +87 -0
- package/dist/mcp/http-transport.mjs +87 -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 +74 -0
- package/dist/mcp/server.mjs +73 -0
- package/dist/mcp/server.mjs.map +1 -0
- package/dist/mcp/tools.cjs +152 -0
- package/dist/mcp/tools.mjs +152 -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 +105 -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/path-utils.mjs +104 -0
- package/dist/path-utils.mjs.map +1 -0
- package/dist/repl.cjs +491 -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 +491 -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 +12 -0
- package/dist/ui/header.mjs +13 -0
- package/dist/ui/header.mjs.map +1 -0
- package/dist/ui/index.cjs +8 -0
- package/dist/ui/index.mjs +9 -0
- package/dist/ui/index.mjs.map +1 -0
- package/dist/ui/terminal.cjs +88 -0
- package/dist/ui/terminal.mjs +88 -0
- package/dist/ui/terminal.mjs.map +1 -0
- package/dist/version.cjs +9 -0
- package/dist/version.d.cts +5 -0
- package/dist/version.d.cts.map +1 -0
- package/dist/version.d.mts +5 -0
- package/dist/version.d.mts.map +1 -0
- package/dist/version.mjs +9 -0
- package/dist/version.mjs.map +1 -0
- package/package.json +77 -11
- package/.turbo/turbo-build.log +0 -18
- package/.turbo/turbo-check-types.log +0 -4
- package/dist/version--p6A8sKX.mjs +0 -5
- package/src/cli.test.ts +0 -8
- package/src/cli.ts +0 -29
- package/src/index.ts +0 -7
- package/src/version.ts +0 -1
- package/tsconfig.json +0 -16
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { navigation } from "../actions.mjs";
|
|
2
|
+
import { Colors, Icons, Symbols, formatSize } from "../theme.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/explorer/components/file-list.ts
|
|
5
|
+
/**
|
|
6
|
+
* Format an entry for display in the list
|
|
7
|
+
*/
|
|
8
|
+
function formatEntry(entry, maxNameWidth) {
|
|
9
|
+
return `${Icons[entry.type] || Icons.file} ${entry.name.padEnd(maxNameWidth)} ${entry.size !== void 0 ? formatSize(entry.size).padStart(8) : " "} ${entry.modified ? formatDate(entry.modified) : " "}`;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Format date for display
|
|
13
|
+
*/
|
|
14
|
+
function formatDate(date) {
|
|
15
|
+
const now = /* @__PURE__ */ new Date();
|
|
16
|
+
const isThisYear = date.getFullYear() === now.getFullYear();
|
|
17
|
+
const month = date.toLocaleString("en", { month: "short" });
|
|
18
|
+
const day = date.getDate().toString().padStart(2, " ");
|
|
19
|
+
if (isThisYear) return `${month} ${day} ${date.getHours().toString().padStart(2, "0")}:${date.getMinutes().toString().padStart(2, "0")}`;
|
|
20
|
+
return `${month} ${day} ${date.getFullYear()}`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create file list component
|
|
24
|
+
*/
|
|
25
|
+
function createFileList(blessed, options) {
|
|
26
|
+
const { parent, store, width, height, top = 0, left = 0 } = options;
|
|
27
|
+
const list = blessed.list({
|
|
28
|
+
parent,
|
|
29
|
+
top,
|
|
30
|
+
left,
|
|
31
|
+
width,
|
|
32
|
+
height,
|
|
33
|
+
tags: true,
|
|
34
|
+
keys: false,
|
|
35
|
+
mouse: true,
|
|
36
|
+
scrollable: true,
|
|
37
|
+
alwaysScroll: true,
|
|
38
|
+
scrollbar: {
|
|
39
|
+
ch: Symbols.scrollbar,
|
|
40
|
+
track: { bg: Colors.bg.main },
|
|
41
|
+
style: { inverse: true }
|
|
42
|
+
},
|
|
43
|
+
style: {
|
|
44
|
+
fg: Colors.fg.normal,
|
|
45
|
+
bg: Colors.bg.main,
|
|
46
|
+
selected: {
|
|
47
|
+
fg: Colors.fg.selected,
|
|
48
|
+
bg: Colors.bg.selected
|
|
49
|
+
},
|
|
50
|
+
item: {
|
|
51
|
+
fg: Colors.fg.normal,
|
|
52
|
+
bg: Colors.bg.main
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
border: { type: "line" }
|
|
56
|
+
});
|
|
57
|
+
function getMaxNameWidth(entries) {
|
|
58
|
+
if (entries.length === 0) return 20;
|
|
59
|
+
const maxLen = Math.max(...entries.map((e) => e.name.length));
|
|
60
|
+
return Math.min(Math.max(maxLen, 10), 40);
|
|
61
|
+
}
|
|
62
|
+
function updateContent(state) {
|
|
63
|
+
const maxNameWidth = getMaxNameWidth(state.entries);
|
|
64
|
+
const items = state.entries.map((entry) => {
|
|
65
|
+
const formatted = formatEntry(entry, maxNameWidth);
|
|
66
|
+
const color = getEntryColor(entry.type);
|
|
67
|
+
return `{${color}-fg}${formatted}{/${color}-fg}`;
|
|
68
|
+
});
|
|
69
|
+
list.setItems(items);
|
|
70
|
+
list.select(state.selectedIndex);
|
|
71
|
+
list.scrollTo(state.selectedIndex);
|
|
72
|
+
}
|
|
73
|
+
function getEntryColor(type) {
|
|
74
|
+
switch (type) {
|
|
75
|
+
case "directory": return Colors.fg.directory;
|
|
76
|
+
case "exec": return Colors.fg.exec;
|
|
77
|
+
case "link": return Colors.fg.link;
|
|
78
|
+
case "up": return Colors.fg.up;
|
|
79
|
+
default: return Colors.fg.file;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
store.subscribe((state) => {
|
|
83
|
+
updateContent(state);
|
|
84
|
+
list.screen?.render();
|
|
85
|
+
});
|
|
86
|
+
updateContent(store.getState());
|
|
87
|
+
return {
|
|
88
|
+
element: list,
|
|
89
|
+
focus() {
|
|
90
|
+
list.focus();
|
|
91
|
+
},
|
|
92
|
+
getVisibleHeight() {
|
|
93
|
+
const h = typeof list.height === "number" ? list.height : 20;
|
|
94
|
+
return Math.max(1, h - 2);
|
|
95
|
+
},
|
|
96
|
+
getSelected() {
|
|
97
|
+
return navigation.getSelected(store.getState());
|
|
98
|
+
},
|
|
99
|
+
destroy() {
|
|
100
|
+
list.destroy();
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
//#endregion
|
|
106
|
+
export { createFileList, formatEntry };
|
|
107
|
+
//# sourceMappingURL=file-list.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-list.mjs","names":[],"sources":["../../../src/explorer/components/file-list.ts"],"sourcesContent":["/**\n * AFS Explorer File List Component\n *\n * Main file listing component using blessed list widget.\n */\n\nimport type Blessed from \"blessed\";\nimport { navigation } from \"../actions.js\";\nimport type { ExplorerStore } from \"../state.js\";\nimport { Colors, formatSize, Icons, Symbols } from \"../theme.js\";\nimport type { ExplorerEntry, ExplorerState } from \"../types.js\";\n\nexport interface FileListOptions {\n parent: Blessed.Widgets.Node;\n store: ExplorerStore;\n width: string | number;\n height: string | number;\n top?: string | number;\n left?: string | number;\n}\n\n/**\n * Format an entry for display in the list\n */\nexport function formatEntry(entry: ExplorerEntry, maxNameWidth: number): string {\n // Use default ASCII icons based on entry type (emoji icons not displayed due to terminal rendering issues)\n const icon = Icons[entry.type] || Icons.file;\n const name = entry.name.padEnd(maxNameWidth);\n const size = entry.size !== undefined ? formatSize(entry.size).padStart(8) : \" \";\n const modified = entry.modified ? formatDate(entry.modified) : \" \";\n\n return `${icon} ${name} ${size} ${modified}`;\n}\n\n/**\n * Format date for display\n */\nfunction formatDate(date: Date): string {\n const now = new Date();\n const isThisYear = date.getFullYear() === now.getFullYear();\n\n const month = date.toLocaleString(\"en\", { month: \"short\" });\n const day = date.getDate().toString().padStart(2, \" \");\n\n if (isThisYear) {\n const hours = date.getHours().toString().padStart(2, \"0\");\n const mins = date.getMinutes().toString().padStart(2, \"0\");\n return `${month} ${day} ${hours}:${mins}`;\n }\n return `${month} ${day} ${date.getFullYear()}`;\n}\n\n/**\n * Create file list component\n */\nexport function createFileList(blessed: typeof Blessed, options: FileListOptions) {\n const { parent, store, width, height, top = 0, left = 0 } = options;\n\n // Create list widget\n const list = blessed.list({\n parent,\n top,\n left,\n width,\n height,\n tags: true,\n keys: false,\n mouse: true,\n scrollable: true,\n alwaysScroll: true,\n scrollbar: {\n ch: Symbols.scrollbar,\n track: {\n bg: Colors.bg.main,\n },\n style: {\n inverse: true,\n },\n },\n style: {\n fg: Colors.fg.normal,\n bg: Colors.bg.main,\n selected: {\n fg: Colors.fg.selected,\n bg: Colors.bg.selected,\n },\n item: {\n fg: Colors.fg.normal,\n bg: Colors.bg.main,\n },\n },\n border: {\n type: \"line\",\n },\n });\n\n // Calculate max name width based on entries\n function getMaxNameWidth(entries: ExplorerEntry[]): number {\n if (entries.length === 0) return 20;\n const maxLen = Math.max(...entries.map((e) => e.name.length));\n return Math.min(Math.max(maxLen, 10), 40);\n }\n\n // Update list content from state\n function updateContent(state: ExplorerState): void {\n const maxNameWidth = getMaxNameWidth(state.entries);\n const items = state.entries.map((entry) => {\n const formatted = formatEntry(entry, maxNameWidth);\n // Apply color based on type\n const color = getEntryColor(entry.type);\n return `{${color}-fg}${formatted}{/${color}-fg}`;\n });\n\n list.setItems(items);\n list.select(state.selectedIndex);\n list.scrollTo(state.selectedIndex);\n }\n\n // Get color name for entry type\n function getEntryColor(type: ExplorerEntry[\"type\"]): string {\n switch (type) {\n case \"directory\":\n return Colors.fg.directory;\n case \"exec\":\n return Colors.fg.exec;\n case \"link\":\n return Colors.fg.link;\n case \"up\":\n return Colors.fg.up;\n default:\n return Colors.fg.file;\n }\n }\n\n // Subscribe to state changes\n store.subscribe((state) => {\n updateContent(state);\n (list.screen as Blessed.Widgets.Screen)?.render();\n });\n\n // Initial render\n updateContent(store.getState());\n\n // Return component interface\n return {\n element: list,\n\n /**\n * Focus the list\n */\n focus(): void {\n list.focus();\n },\n\n /**\n * Get visible height (for page calculations)\n */\n getVisibleHeight(): number {\n // Account for border\n const h = typeof list.height === \"number\" ? list.height : 20;\n return Math.max(1, h - 2);\n },\n\n /**\n * Get selected entry\n */\n getSelected(): ExplorerEntry | undefined {\n return navigation.getSelected(store.getState());\n },\n\n /**\n * Destroy the component\n */\n destroy(): void {\n list.destroy();\n },\n };\n}\n\nexport type FileList = ReturnType<typeof createFileList>;\n"],"mappings":";;;;;;;AAwBA,SAAgB,YAAY,OAAsB,cAA8B;AAO9E,QAAO,GALM,MAAM,MAAM,SAAS,MAAM,KAKzB,GAJF,MAAM,KAAK,OAAO,aAAa,CAIrB,GAHV,MAAM,SAAS,SAAY,WAAW,MAAM,KAAK,CAAC,SAAS,EAAE,GAAG,WAG9C,GAFd,MAAM,WAAW,WAAW,MAAM,SAAS,GAAG;;;;;AAQjE,SAAS,WAAW,MAAoB;CACtC,MAAM,sBAAM,IAAI,MAAM;CACtB,MAAM,aAAa,KAAK,aAAa,KAAK,IAAI,aAAa;CAE3D,MAAM,QAAQ,KAAK,eAAe,MAAM,EAAE,OAAO,SAAS,CAAC;CAC3D,MAAM,MAAM,KAAK,SAAS,CAAC,UAAU,CAAC,SAAS,GAAG,IAAI;AAEtD,KAAI,WAGF,QAAO,GAAG,MAAM,GAAG,IAAI,GAFT,KAAK,UAAU,CAAC,UAAU,CAAC,SAAS,GAAG,IAAI,CAEzB,GADnB,KAAK,YAAY,CAAC,UAAU,CAAC,SAAS,GAAG,IAAI;AAG5D,QAAO,GAAG,MAAM,GAAG,IAAI,IAAI,KAAK,aAAa;;;;;AAM/C,SAAgB,eAAe,SAAyB,SAA0B;CAChF,MAAM,EAAE,QAAQ,OAAO,OAAO,QAAQ,MAAM,GAAG,OAAO,MAAM;CAG5D,MAAM,OAAO,QAAQ,KAAK;EACxB;EACA;EACA;EACA;EACA;EACA,MAAM;EACN,MAAM;EACN,OAAO;EACP,YAAY;EACZ,cAAc;EACd,WAAW;GACT,IAAI,QAAQ;GACZ,OAAO,EACL,IAAI,OAAO,GAAG,MACf;GACD,OAAO,EACL,SAAS,MACV;GACF;EACD,OAAO;GACL,IAAI,OAAO,GAAG;GACd,IAAI,OAAO,GAAG;GACd,UAAU;IACR,IAAI,OAAO,GAAG;IACd,IAAI,OAAO,GAAG;IACf;GACD,MAAM;IACJ,IAAI,OAAO,GAAG;IACd,IAAI,OAAO,GAAG;IACf;GACF;EACD,QAAQ,EACN,MAAM,QACP;EACF,CAAC;CAGF,SAAS,gBAAgB,SAAkC;AACzD,MAAI,QAAQ,WAAW,EAAG,QAAO;EACjC,MAAM,SAAS,KAAK,IAAI,GAAG,QAAQ,KAAK,MAAM,EAAE,KAAK,OAAO,CAAC;AAC7D,SAAO,KAAK,IAAI,KAAK,IAAI,QAAQ,GAAG,EAAE,GAAG;;CAI3C,SAAS,cAAc,OAA4B;EACjD,MAAM,eAAe,gBAAgB,MAAM,QAAQ;EACnD,MAAM,QAAQ,MAAM,QAAQ,KAAK,UAAU;GACzC,MAAM,YAAY,YAAY,OAAO,aAAa;GAElD,MAAM,QAAQ,cAAc,MAAM,KAAK;AACvC,UAAO,IAAI,MAAM,MAAM,UAAU,IAAI,MAAM;IAC3C;AAEF,OAAK,SAAS,MAAM;AACpB,OAAK,OAAO,MAAM,cAAc;AAChC,OAAK,SAAS,MAAM,cAAc;;CAIpC,SAAS,cAAc,MAAqC;AAC1D,UAAQ,MAAR;GACE,KAAK,YACH,QAAO,OAAO,GAAG;GACnB,KAAK,OACH,QAAO,OAAO,GAAG;GACnB,KAAK,OACH,QAAO,OAAO,GAAG;GACnB,KAAK,KACH,QAAO,OAAO,GAAG;GACnB,QACE,QAAO,OAAO,GAAG;;;AAKvB,OAAM,WAAW,UAAU;AACzB,gBAAc,MAAM;AACpB,EAAC,KAAK,QAAmC,QAAQ;GACjD;AAGF,eAAc,MAAM,UAAU,CAAC;AAG/B,QAAO;EACL,SAAS;EAKT,QAAc;AACZ,QAAK,OAAO;;EAMd,mBAA2B;GAEzB,MAAM,IAAI,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AAC1D,UAAO,KAAK,IAAI,GAAG,IAAI,EAAE;;EAM3B,cAAyC;AACvC,UAAO,WAAW,YAAY,MAAM,UAAU,CAAC;;EAMjD,UAAgB;AACd,QAAK,SAAS;;EAEjB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const require_keybindings = require('../keybindings.cjs');
|
|
2
|
+
const require_theme = require('../theme.cjs');
|
|
3
|
+
|
|
4
|
+
//#region src/explorer/components/function-bar.ts
|
|
5
|
+
/**
|
|
6
|
+
* Format a single function key for display
|
|
7
|
+
*/
|
|
8
|
+
function formatFunctionKey(binding) {
|
|
9
|
+
return {
|
|
10
|
+
key: require_keybindings.formatKeyName(binding.key),
|
|
11
|
+
label: binding.label || binding.action
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Create function bar component
|
|
16
|
+
*/
|
|
17
|
+
function createFunctionBar(blessed, options) {
|
|
18
|
+
const { parent, registry, width, bottom = 0, left = 0 } = options;
|
|
19
|
+
const bar = blessed.box({
|
|
20
|
+
parent,
|
|
21
|
+
bottom,
|
|
22
|
+
left,
|
|
23
|
+
width,
|
|
24
|
+
height: 1,
|
|
25
|
+
tags: true,
|
|
26
|
+
style: {
|
|
27
|
+
fg: require_theme.Colors.fg.selected,
|
|
28
|
+
bg: require_theme.Colors.bg.functionKey
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
function buildContent() {
|
|
32
|
+
const bindings = registry.getFunctionBarBindings();
|
|
33
|
+
const parts = [];
|
|
34
|
+
for (const binding of bindings) {
|
|
35
|
+
const { key, label } = formatFunctionKey(binding);
|
|
36
|
+
parts.push(`{inverse}${key}{/inverse}${label}`);
|
|
37
|
+
}
|
|
38
|
+
return parts.join(" ");
|
|
39
|
+
}
|
|
40
|
+
bar.setContent(buildContent());
|
|
41
|
+
return {
|
|
42
|
+
element: bar,
|
|
43
|
+
refresh() {
|
|
44
|
+
bar.setContent(buildContent());
|
|
45
|
+
bar.screen?.render();
|
|
46
|
+
},
|
|
47
|
+
destroy() {
|
|
48
|
+
bar.destroy();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
//#endregion
|
|
54
|
+
exports.createFunctionBar = createFunctionBar;
|
|
55
|
+
exports.formatFunctionKey = formatFunctionKey;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { formatKeyName } from "../keybindings.mjs";
|
|
2
|
+
import { Colors } from "../theme.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/explorer/components/function-bar.ts
|
|
5
|
+
/**
|
|
6
|
+
* Format a single function key for display
|
|
7
|
+
*/
|
|
8
|
+
function formatFunctionKey(binding) {
|
|
9
|
+
return {
|
|
10
|
+
key: formatKeyName(binding.key),
|
|
11
|
+
label: binding.label || binding.action
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Create function bar component
|
|
16
|
+
*/
|
|
17
|
+
function createFunctionBar(blessed, options) {
|
|
18
|
+
const { parent, registry, width, bottom = 0, left = 0 } = options;
|
|
19
|
+
const bar = blessed.box({
|
|
20
|
+
parent,
|
|
21
|
+
bottom,
|
|
22
|
+
left,
|
|
23
|
+
width,
|
|
24
|
+
height: 1,
|
|
25
|
+
tags: true,
|
|
26
|
+
style: {
|
|
27
|
+
fg: Colors.fg.selected,
|
|
28
|
+
bg: Colors.bg.functionKey
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
function buildContent() {
|
|
32
|
+
const bindings = registry.getFunctionBarBindings();
|
|
33
|
+
const parts = [];
|
|
34
|
+
for (const binding of bindings) {
|
|
35
|
+
const { key, label } = formatFunctionKey(binding);
|
|
36
|
+
parts.push(`{inverse}${key}{/inverse}${label}`);
|
|
37
|
+
}
|
|
38
|
+
return parts.join(" ");
|
|
39
|
+
}
|
|
40
|
+
bar.setContent(buildContent());
|
|
41
|
+
return {
|
|
42
|
+
element: bar,
|
|
43
|
+
refresh() {
|
|
44
|
+
bar.setContent(buildContent());
|
|
45
|
+
bar.screen?.render();
|
|
46
|
+
},
|
|
47
|
+
destroy() {
|
|
48
|
+
bar.destroy();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
//#endregion
|
|
54
|
+
export { createFunctionBar, formatFunctionKey };
|
|
55
|
+
//# sourceMappingURL=function-bar.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"function-bar.mjs","names":[],"sources":["../../../src/explorer/components/function-bar.ts"],"sourcesContent":["/**\n * AFS Explorer Function Bar Component\n *\n * Bottom function key bar (F1-F10 style).\n */\n\nimport type Blessed from \"blessed\";\nimport { formatKeyName, type KeyBindingRegistry } from \"../keybindings.js\";\nimport { Colors } from \"../theme.js\";\nimport type { KeyBinding } from \"../types.js\";\n\nexport interface FunctionBarOptions {\n parent: Blessed.Widgets.Node;\n registry: KeyBindingRegistry;\n width: string | number;\n bottom?: string | number;\n left?: string | number;\n}\n\n/**\n * Format a single function key for display\n */\nexport function formatFunctionKey(binding: KeyBinding): { key: string; label: string } {\n const key = formatKeyName(binding.key);\n const label = binding.label || binding.action;\n return { key, label };\n}\n\n/**\n * Create function bar component\n */\nexport function createFunctionBar(blessed: typeof Blessed, options: FunctionBarOptions) {\n const { parent, registry, width, bottom = 0, left = 0 } = options;\n\n // Create box for function bar\n const bar = blessed.box({\n parent,\n bottom,\n left,\n width,\n height: 1,\n tags: true,\n style: {\n fg: Colors.fg.selected,\n bg: Colors.bg.functionKey,\n },\n });\n\n // Build function bar content\n function buildContent(): string {\n const bindings = registry.getFunctionBarBindings();\n const parts: string[] = [];\n\n for (const binding of bindings) {\n const { key, label } = formatFunctionKey(binding);\n // Key in inverse, label normal\n parts.push(`{inverse}${key}{/inverse}${label}`);\n }\n\n return parts.join(\" \");\n }\n\n // Initial render\n bar.setContent(buildContent());\n\n return {\n element: bar,\n\n /**\n * Refresh the function bar (if bindings changed)\n */\n refresh(): void {\n bar.setContent(buildContent());\n (bar.screen as Blessed.Widgets.Screen)?.render();\n },\n\n /**\n * Destroy the component\n */\n destroy(): void {\n bar.destroy();\n },\n };\n}\n\nexport type FunctionBar = ReturnType<typeof createFunctionBar>;\n"],"mappings":";;;;;;;AAsBA,SAAgB,kBAAkB,SAAqD;AAGrF,QAAO;EAAE,KAFG,cAAc,QAAQ,IAAI;EAExB,OADA,QAAQ,SAAS,QAAQ;EAClB;;;;;AAMvB,SAAgB,kBAAkB,SAAyB,SAA6B;CACtF,MAAM,EAAE,QAAQ,UAAU,OAAO,SAAS,GAAG,OAAO,MAAM;CAG1D,MAAM,MAAM,QAAQ,IAAI;EACtB;EACA;EACA;EACA;EACA,QAAQ;EACR,MAAM;EACN,OAAO;GACL,IAAI,OAAO,GAAG;GACd,IAAI,OAAO,GAAG;GACf;EACF,CAAC;CAGF,SAAS,eAAuB;EAC9B,MAAM,WAAW,SAAS,wBAAwB;EAClD,MAAM,QAAkB,EAAE;AAE1B,OAAK,MAAM,WAAW,UAAU;GAC9B,MAAM,EAAE,KAAK,UAAU,kBAAkB,QAAQ;AAEjD,SAAM,KAAK,YAAY,IAAI,YAAY,QAAQ;;AAGjD,SAAO,MAAM,KAAK,IAAI;;AAIxB,KAAI,WAAW,cAAc,CAAC;AAE9B,QAAO;EACL,SAAS;EAKT,UAAgB;AACd,OAAI,WAAW,cAAc,CAAC;AAC9B,GAAC,IAAI,QAAmC,QAAQ;;EAMlD,UAAgB;AACd,OAAI,SAAS;;EAEhB"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
const require_dialog = require('./dialog.cjs');
|
|
2
|
+
const require_file_list = require('./file-list.cjs');
|
|
3
|
+
const require_function_bar = require('./function-bar.cjs');
|
|
4
|
+
const require_metadata_panel = require('./metadata-panel.cjs');
|
|
5
|
+
const require_status_bar = require('./status-bar.cjs');
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createDialogManager } from "./dialog.mjs";
|
|
2
|
+
import { createFileList, formatEntry } from "./file-list.mjs";
|
|
3
|
+
import { createFunctionBar, formatFunctionKey } from "./function-bar.mjs";
|
|
4
|
+
import { createMetadataPanel, formatMetadata } from "./metadata-panel.mjs";
|
|
5
|
+
import { createStatusBar } from "./status-bar.mjs";
|
|
6
|
+
|
|
7
|
+
export { };
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
const require_theme = require('../theme.cjs');
|
|
2
|
+
|
|
3
|
+
//#region src/explorer/components/metadata-panel.ts
|
|
4
|
+
/**
|
|
5
|
+
* Format metadata for display
|
|
6
|
+
*/
|
|
7
|
+
function formatMetadata(entry, metadata) {
|
|
8
|
+
const lines = [];
|
|
9
|
+
const icon = entry.type !== "file" ? require_theme.Icons[entry.type] : "";
|
|
10
|
+
const prefix = icon ? `${icon} ` : "";
|
|
11
|
+
lines.push(`${prefix}${entry.name}`);
|
|
12
|
+
lines.push("");
|
|
13
|
+
lines.push(`Path: ${entry.path}`);
|
|
14
|
+
if (entry.size !== void 0 || metadata?.size !== void 0) {
|
|
15
|
+
const size = metadata?.size ?? entry.size;
|
|
16
|
+
lines.push(`Size: ${require_theme.formatSize(size)}`);
|
|
17
|
+
}
|
|
18
|
+
if (entry.childrenCount !== void 0 || metadata?.childrenCount !== void 0) {
|
|
19
|
+
const count = metadata?.childrenCount ?? entry.childrenCount;
|
|
20
|
+
lines.push(`Items: ${count}`);
|
|
21
|
+
}
|
|
22
|
+
if (entry.modified || metadata?.modified) {
|
|
23
|
+
const date = metadata?.modified ?? entry.modified;
|
|
24
|
+
lines.push(`Modified: ${formatDateTime(date)}`);
|
|
25
|
+
}
|
|
26
|
+
if (entry.provider || metadata?.provider) lines.push(`Provider: ${metadata?.provider ?? entry.provider}`);
|
|
27
|
+
if (entry.hash || metadata?.hash) {
|
|
28
|
+
const hash = metadata?.hash ?? entry.hash;
|
|
29
|
+
const display = hash.length > 20 ? `${hash.slice(0, 20)}...` : hash;
|
|
30
|
+
lines.push(`Hash: ${display}`);
|
|
31
|
+
}
|
|
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
|
+
}
|
|
77
|
+
}
|
|
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
|
+
}
|
|
86
|
+
lines.push("");
|
|
87
|
+
lines.push("(F4 to execute)");
|
|
88
|
+
} else lines.push("(none)");
|
|
89
|
+
return lines;
|
|
90
|
+
}
|
|
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
|
+
/**
|
|
157
|
+
* Format date and time
|
|
158
|
+
*/
|
|
159
|
+
function formatDateTime(date) {
|
|
160
|
+
return date.toLocaleString("en", {
|
|
161
|
+
year: "numeric",
|
|
162
|
+
month: "short",
|
|
163
|
+
day: "numeric",
|
|
164
|
+
hour: "2-digit",
|
|
165
|
+
minute: "2-digit"
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Create metadata panel component
|
|
170
|
+
*/
|
|
171
|
+
function createMetadataPanel(blessed, options) {
|
|
172
|
+
const { parent, width, height, top = 0, right = 0 } = options;
|
|
173
|
+
const panel = blessed.box({
|
|
174
|
+
parent,
|
|
175
|
+
top,
|
|
176
|
+
right,
|
|
177
|
+
width,
|
|
178
|
+
height,
|
|
179
|
+
tags: true,
|
|
180
|
+
scrollable: true,
|
|
181
|
+
alwaysScroll: true,
|
|
182
|
+
style: {
|
|
183
|
+
fg: require_theme.Colors.fg.normal,
|
|
184
|
+
bg: require_theme.Colors.bg.main
|
|
185
|
+
},
|
|
186
|
+
border: { type: "line" },
|
|
187
|
+
label: " Details "
|
|
188
|
+
});
|
|
189
|
+
let currentEntry;
|
|
190
|
+
return {
|
|
191
|
+
element: panel,
|
|
192
|
+
update(entry, metadata) {
|
|
193
|
+
currentEntry = entry;
|
|
194
|
+
if (entry.type === "up") {
|
|
195
|
+
panel.setContent(" Parent directory");
|
|
196
|
+
panel.screen?.render();
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const lines = formatMetadata(entry, metadata);
|
|
200
|
+
panel.setContent(lines.map((l) => ` ${l}`).join("\n"));
|
|
201
|
+
panel.screen?.render();
|
|
202
|
+
},
|
|
203
|
+
clear() {
|
|
204
|
+
currentEntry = void 0;
|
|
205
|
+
panel.setContent("");
|
|
206
|
+
panel.screen?.render();
|
|
207
|
+
},
|
|
208
|
+
getCurrentEntry() {
|
|
209
|
+
return currentEntry;
|
|
210
|
+
},
|
|
211
|
+
destroy() {
|
|
212
|
+
panel.destroy();
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
//#endregion
|
|
218
|
+
exports.createMetadataPanel = createMetadataPanel;
|
|
219
|
+
exports.formatMetadata = formatMetadata;
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { Colors, Icons, formatSize } from "../theme.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/explorer/components/metadata-panel.ts
|
|
4
|
+
/**
|
|
5
|
+
* Format metadata for display
|
|
6
|
+
*/
|
|
7
|
+
function formatMetadata(entry, metadata) {
|
|
8
|
+
const lines = [];
|
|
9
|
+
const icon = entry.type !== "file" ? Icons[entry.type] : "";
|
|
10
|
+
const prefix = icon ? `${icon} ` : "";
|
|
11
|
+
lines.push(`${prefix}${entry.name}`);
|
|
12
|
+
lines.push("");
|
|
13
|
+
lines.push(`Path: ${entry.path}`);
|
|
14
|
+
if (entry.size !== void 0 || metadata?.size !== void 0) {
|
|
15
|
+
const size = metadata?.size ?? entry.size;
|
|
16
|
+
lines.push(`Size: ${formatSize(size)}`);
|
|
17
|
+
}
|
|
18
|
+
if (entry.childrenCount !== void 0 || metadata?.childrenCount !== void 0) {
|
|
19
|
+
const count = metadata?.childrenCount ?? entry.childrenCount;
|
|
20
|
+
lines.push(`Items: ${count}`);
|
|
21
|
+
}
|
|
22
|
+
if (entry.modified || metadata?.modified) {
|
|
23
|
+
const date = metadata?.modified ?? entry.modified;
|
|
24
|
+
lines.push(`Modified: ${formatDateTime(date)}`);
|
|
25
|
+
}
|
|
26
|
+
if (entry.provider || metadata?.provider) lines.push(`Provider: ${metadata?.provider ?? entry.provider}`);
|
|
27
|
+
if (entry.hash || metadata?.hash) {
|
|
28
|
+
const hash = metadata?.hash ?? entry.hash;
|
|
29
|
+
const display = hash.length > 20 ? `${hash.slice(0, 20)}...` : hash;
|
|
30
|
+
lines.push(`Hash: ${display}`);
|
|
31
|
+
}
|
|
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
|
+
}
|
|
77
|
+
}
|
|
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
|
+
}
|
|
86
|
+
lines.push("");
|
|
87
|
+
lines.push("(F4 to execute)");
|
|
88
|
+
} else lines.push("(none)");
|
|
89
|
+
return lines;
|
|
90
|
+
}
|
|
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
|
+
/**
|
|
157
|
+
* Format date and time
|
|
158
|
+
*/
|
|
159
|
+
function formatDateTime(date) {
|
|
160
|
+
return date.toLocaleString("en", {
|
|
161
|
+
year: "numeric",
|
|
162
|
+
month: "short",
|
|
163
|
+
day: "numeric",
|
|
164
|
+
hour: "2-digit",
|
|
165
|
+
minute: "2-digit"
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Create metadata panel component
|
|
170
|
+
*/
|
|
171
|
+
function createMetadataPanel(blessed, options) {
|
|
172
|
+
const { parent, width, height, top = 0, right = 0 } = options;
|
|
173
|
+
const panel = blessed.box({
|
|
174
|
+
parent,
|
|
175
|
+
top,
|
|
176
|
+
right,
|
|
177
|
+
width,
|
|
178
|
+
height,
|
|
179
|
+
tags: true,
|
|
180
|
+
scrollable: true,
|
|
181
|
+
alwaysScroll: true,
|
|
182
|
+
style: {
|
|
183
|
+
fg: Colors.fg.normal,
|
|
184
|
+
bg: Colors.bg.main
|
|
185
|
+
},
|
|
186
|
+
border: { type: "line" },
|
|
187
|
+
label: " Details "
|
|
188
|
+
});
|
|
189
|
+
let currentEntry;
|
|
190
|
+
return {
|
|
191
|
+
element: panel,
|
|
192
|
+
update(entry, metadata) {
|
|
193
|
+
currentEntry = entry;
|
|
194
|
+
if (entry.type === "up") {
|
|
195
|
+
panel.setContent(" Parent directory");
|
|
196
|
+
panel.screen?.render();
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const lines = formatMetadata(entry, metadata);
|
|
200
|
+
panel.setContent(lines.map((l) => ` ${l}`).join("\n"));
|
|
201
|
+
panel.screen?.render();
|
|
202
|
+
},
|
|
203
|
+
clear() {
|
|
204
|
+
currentEntry = void 0;
|
|
205
|
+
panel.setContent("");
|
|
206
|
+
panel.screen?.render();
|
|
207
|
+
},
|
|
208
|
+
getCurrentEntry() {
|
|
209
|
+
return currentEntry;
|
|
210
|
+
},
|
|
211
|
+
destroy() {
|
|
212
|
+
panel.destroy();
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
//#endregion
|
|
218
|
+
export { createMetadataPanel, formatMetadata };
|
|
219
|
+
//# sourceMappingURL=metadata-panel.mjs.map
|