@aigne/afs-cli 1.11.0-beta.12 → 1.11.0-beta.13
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/config/afs-loader.cjs +0 -28
- package/dist/config/afs-loader.d.cts.map +1 -1
- package/dist/config/afs-loader.d.mts.map +1 -1
- package/dist/config/afs-loader.mjs +5 -33
- package/dist/config/afs-loader.mjs.map +1 -1
- package/dist/config/credential-helpers.cjs +14 -2
- package/dist/config/credential-helpers.mjs +14 -2
- package/dist/config/credential-helpers.mjs.map +1 -1
- package/dist/config/program-install.cjs +174 -0
- package/dist/config/program-install.mjs +173 -2
- package/dist/config/program-install.mjs.map +1 -1
- package/dist/core/commands/daemon.cjs +5 -1
- package/dist/core/commands/daemon.mjs +5 -1
- package/dist/core/commands/daemon.mjs.map +1 -1
- package/dist/core/commands/index.d.cts.map +1 -1
- package/dist/core/commands/index.d.mts.map +1 -1
- package/dist/core/commands/index.mjs.map +1 -1
- package/dist/core/commands/install.cjs +49 -1
- package/dist/core/commands/install.mjs +51 -3
- package/dist/core/commands/install.mjs.map +1 -1
- package/dist/core/formatters/install.cjs +19 -0
- package/dist/core/formatters/install.mjs +18 -1
- package/dist/core/formatters/install.mjs.map +1 -1
- package/dist/credential/auth-server.cjs +22 -4
- package/dist/credential/auth-server.mjs +22 -4
- package/dist/credential/auth-server.mjs.map +1 -1
- package/dist/credential/resolver.cjs +7 -4
- package/dist/credential/resolver.mjs +7 -4
- package/dist/credential/resolver.mjs.map +1 -1
- package/dist/program/program-manager.cjs +5 -1
- package/dist/program/program-manager.mjs +5 -1
- package/dist/program/program-manager.mjs.map +1 -1
- package/dist/repl.cjs +5 -1
- package/dist/repl.mjs +5 -1
- package/dist/repl.mjs.map +1 -1
- package/package.json +28 -28
package/dist/repl.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repl.mjs","names":["dirname","ns","resolved","ctx","resolve"],"sources":["../src/repl.ts"],"sourcesContent":["/**\n * AFS CLI Interactive REPL\n *\n * Single-file REPL implementation for `afs -i` / `afs --interactive`.\n * Provides: REPL loop, cd/pwd, Tab completion, explore TUI integration.\n */\n\nimport { basename } from \"node:path\";\nimport { createInterface, type Interface } from \"node:readline\";\nimport type { AFS, AFSEntry, AFSModule } from \"@aigne/afs\";\nimport { joinURL } from \"ufo\";\nimport { loadAFS, type MountFailure } from \"./config/afs-loader.js\";\nimport { AFSCommandExecutor } from \"./core/executor/index.js\";\nimport { createCLIAuthContext } from \"./credential/cli-auth-context.js\";\nimport { createCredentialStore } from \"./credential/store.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────\n\nexport interface ReplOptions {\n executor: AFSCommandExecutor;\n afs: AFS;\n version: string;\n}\n\nexport interface ReplContext {\n executor: AFSCommandExecutor;\n afs: AFS;\n version: string;\n currentPath: string;\n currentNamespace: string | null;\n completionCache: Map<string, AFSEntry[]>;\n}\n\nexport interface BuiltinResult {\n output?: string;\n exit?: boolean;\n}\n\n// ─── Constants ───────────────────────────────────────────────────────────\n\nconst BUILTIN_COMMANDS = [\"cd\", \"pwd\", \"help\", \"exit\", \"quit\"];\n\n/** Commands that default to current path when no path argument is given in REPL */\nconst DEFAULT_PATH_COMMANDS = new Set([\"ls\", \"read\", \"stat\", \"explain\", \"explore\"]);\n\nconst ALL_COMMANDS = [\n \"ls\",\n \"read\",\n \"write\",\n \"delete\",\n \"stat\",\n \"exec\",\n \"explain\",\n \"search\",\n \"mount\",\n \"program\",\n \"vault\",\n \"service\",\n \"explore\",\n \"cd\",\n \"pwd\",\n \"help\",\n \"exit\",\n];\n\n// ─── Context ─────────────────────────────────────────────────────────────\n\nexport function createReplContext(options: ReplOptions): ReplContext {\n return {\n executor: options.executor,\n afs: options.afs,\n version: options.version,\n currentPath: \"/\",\n currentNamespace: null,\n completionCache: new Map(),\n };\n}\n\n// ─── Prompt ──────────────────────────────────────────────────────────────\n\nexport function getPrompt(ctx: ReplContext): string {\n const dirname = ctx.currentPath === \"/\" ? \"/\" : basename(ctx.currentPath);\n const nsPrefix = ctx.currentNamespace ? `${ctx.currentNamespace}:` : \"\";\n return `afs ${nsPrefix}${dirname}> `;\n}\n\n// ─── Banner ──────────────────────────────────────────────────────────────\n\nexport function getBanner(ctx: ReplContext): string {\n const mountCount = ctx.afs.getMounts().length;\n const plural = mountCount === 1 ? \"provider\" : \"providers\";\n return `AFS Interactive Shell v${ctx.version} — ${mountCount} ${plural} mounted. Type \"help\" for commands.`;\n}\n\n// ─── Builtin Commands ────────────────────────────────────────────────────\n\nexport function isBuiltinCommand(input: string): boolean {\n const trimmed = input.trim();\n if (!trimmed) return false;\n const cmd = trimmed.split(/\\s+/)[0]!;\n return BUILTIN_COMMANDS.includes(cmd);\n}\n\nexport async function handleBuiltinCommand(\n input: string,\n ctx: ReplContext,\n): Promise<BuiltinResult | null> {\n const trimmed = input.trim();\n if (!trimmed) return null;\n\n const parts = trimmed.split(/\\s+/);\n const cmd = parts[0]!;\n\n switch (cmd) {\n case \"exit\":\n case \"quit\":\n return { exit: true, output: \"Bye!\" };\n\n case \"help\":\n return { output: formatHelp() };\n\n case \"pwd\":\n return handlePwd(ctx);\n\n case \"cd\":\n return handleCd(parts.slice(1).join(\" \"), ctx);\n\n default:\n return null;\n }\n}\n\nfunction formatHelp(): string {\n const lines = [\n \"Available commands:\",\n \"\",\n \" AFS Commands:\",\n \" ls [path] List directory contents (default: current dir)\",\n \" read [path] Read file content (default: current node)\",\n \" write <path> [content] Write content to file\",\n \" delete <path> Delete file or directory\",\n \" stat [path] Get file or directory info (default: current node)\",\n \" exec <action> Execute an action\",\n \" explain [topic] Explain AFS concepts or paths (default: current path)\",\n \" search <path> <query> Search content in a path\",\n \" mount Mount management (add, list, remove)\",\n \" program Program management (install, list, uninstall)\",\n \" vault Credential vault management\",\n \" service Daemon service management\",\n \" explore [path] Interactive TUI explorer (default: current dir)\",\n \"\",\n \" REPL Commands:\",\n \" cd [path] Change working directory\",\n \" pwd Print working directory\",\n \" help Show this help\",\n \" exit / quit Exit REPL\",\n \"\",\n \" Tips:\",\n \" - Commands work with or without 'afs' prefix\",\n \" - Use Tab for command and path completion\",\n \" - Ctrl+D to exit\",\n ];\n return lines.join(\"\\n\");\n}\n\n// ─── cd / pwd ────────────────────────────────────────────────────────────\n\nfunction handlePwd(ctx: ReplContext): BuiltinResult {\n if (ctx.currentNamespace) {\n return { output: `@${ctx.currentNamespace}${ctx.currentPath}` };\n }\n return { output: ctx.currentPath };\n}\n\nasync function handleCd(target: string, ctx: ReplContext): Promise<BuiltinResult> {\n if (!target || target.trim() === \"\") {\n // cd with no args → go to root\n ctx.currentPath = \"/\";\n return {};\n }\n\n const trimmed = target.trim();\n\n // Handle @default → reset namespace\n if (trimmed === \"@default\") {\n ctx.currentNamespace = null;\n ctx.currentPath = \"/\";\n return {};\n }\n\n // Handle @namespace syntax\n if (trimmed.startsWith(\"@\")) {\n const rest = trimmed.slice(1);\n const slashIdx = rest.indexOf(\"/\");\n if (slashIdx === -1) {\n // @namespace only → switch to namespace root\n const ns = rest;\n if (!ns) return { output: \"cd: invalid namespace\" };\n // Validate by calling stat on namespace root\n try {\n const canonicalPath = `$afs:${ns}/`;\n await ctx.afs.stat(canonicalPath);\n ctx.currentNamespace = ns;\n ctx.currentPath = \"/\";\n return {};\n } catch {\n return { output: `cd: no such path: @${ns}/` };\n }\n }\n const ns = rest.slice(0, slashIdx);\n const path = rest.slice(slashIdx) || \"/\";\n if (!ns) return { output: \"cd: invalid namespace\" };\n try {\n const canonicalPath = `$afs:${ns}${path}`;\n await ctx.afs.stat(canonicalPath);\n ctx.currentNamespace = ns;\n ctx.currentPath = path;\n return {};\n } catch {\n return { output: `cd: no such path: @${ns}${path}` };\n }\n }\n\n // Handle absolute path\n if (trimmed.startsWith(\"/\")) {\n const resolved = normalizePath(trimmed);\n try {\n const canonicalPath = ctx.currentNamespace\n ? `$afs:${ctx.currentNamespace}${resolved}`\n : resolved;\n await ctx.afs.stat(canonicalPath);\n ctx.currentPath = resolved;\n return {};\n } catch {\n return { output: `cd: no such path: ${trimmed}` };\n }\n }\n\n // Handle relative path (including ..)\n const resolved = normalizePath(joinURL(ctx.currentPath, trimmed));\n try {\n const canonicalPath = ctx.currentNamespace\n ? `$afs:${ctx.currentNamespace}${resolved}`\n : resolved;\n await ctx.afs.stat(canonicalPath);\n ctx.currentPath = resolved;\n return {};\n } catch {\n return { output: `cd: no such path: ${trimmed}` };\n }\n}\n\nfunction normalizePath(path: string): string {\n // Split into segments, resolve .., remove empty segments\n const parts = path.split(\"/\").filter(Boolean);\n const resolved: string[] = [];\n for (const part of parts) {\n if (part === \"..\") {\n resolved.pop();\n } else if (part !== \".\") {\n resolved.push(part);\n }\n }\n return `/${resolved.join(\"/\")}`;\n}\n\n// ─── Argv Path Preprocessing ─────────────────────────────────────────────\n\nexport function resolveArgvPath(input: string, ctx: ReplContext): string[] {\n const tokens = tokenize(input);\n if (tokens.length === 0) return tokens;\n\n // Find the command name (skip optional 'afs' prefix)\n let cmdIdx = 0;\n if (tokens[0] === \"afs\" && tokens.length > 1) cmdIdx = 1;\n const cmd = tokens[cmdIdx];\n if (!cmd) return tokens;\n\n // Find first positional argument (non-option) after the command\n let argIdx = -1;\n for (let i = cmdIdx + 1; i < tokens.length; i++) {\n const token = tokens[i]!;\n if (!token.startsWith(\"-\")) {\n // For \"mount\" command, subcommands like \"list\", \"add\", \"remove\" are not paths\n if (\n cmd === \"mount\" &&\n (token === \"list\" || token === \"ls\" || token === \"add\" || token === \"remove\")\n ) {\n continue;\n }\n argIdx = i;\n break;\n }\n // Skip --option value pairs\n if (token.startsWith(\"--\") && !token.includes(\"=\") && i + 1 < tokens.length) {\n i++; // skip the value\n }\n }\n\n if (argIdx === -1) {\n // No positional arg found — inject current path for safe commands\n if (DEFAULT_PATH_COMMANDS.has(cmd)) {\n const currentFullPath = ctx.currentNamespace\n ? `@${ctx.currentNamespace}${ctx.currentPath}`\n : ctx.currentPath;\n tokens.push(currentFullPath);\n }\n return tokens;\n }\n\n const arg = tokens[argIdx]!;\n\n // Don't resolve if already absolute, canonical, or namespace-prefixed\n if (arg.startsWith(\"/\") || arg.startsWith(\"@\") || arg.startsWith(\"$afs\")) {\n return tokens;\n }\n\n // Resolve relative path\n const resolved = normalizePath(joinURL(ctx.currentPath, arg));\n\n // Add namespace prefix if in a non-default namespace\n const finalPath = ctx.currentNamespace ? `@${ctx.currentNamespace}${resolved}` : resolved;\n\n // Replace the token in the original input\n tokens[argIdx] = finalPath;\n return tokens;\n}\n\nfunction tokenize(input: string): string[] {\n const tokens: string[] = [];\n let current = \"\";\n let inQuote = false;\n let quoteChar = \"\";\n\n for (let i = 0; i < input.length; i++) {\n const char = input[i]!;\n if (inQuote) {\n if (char === quoteChar) {\n inQuote = false;\n } else {\n current += char;\n }\n } else if (char === '\"' || char === \"'\") {\n inQuote = true;\n quoteChar = char;\n } else if (char === \" \" || char === \"\\t\") {\n if (current) {\n tokens.push(current);\n current = \"\";\n }\n } else {\n current += char;\n }\n }\n if (current) tokens.push(current);\n return tokens;\n}\n\n// ─── Explore Detection ───────────────────────────────────────────────────\n\nexport function isExploreCommand(cmd: string): boolean {\n const normalized = cmd.replace(/^afs\\s+/, \"\").trim();\n return normalized === \"explore\" || normalized.startsWith(\"explore \");\n}\n\ninterface ExploreArgs {\n path: string;\n web: boolean;\n port: number;\n}\n\nfunction parseExploreArgs(cmd: string, ctx: ReplContext): ExploreArgs {\n const normalized = cmd.replace(/^afs\\s+/, \"\").trim();\n const parts = normalized.split(/\\s+/).slice(1); // drop \"explore\"\n\n let web = false;\n let port = 0;\n const pathParts: string[] = [];\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]!;\n if (part === \"--web\") {\n web = true;\n } else if (part === \"--port\" && i + 1 < parts.length) {\n port = Number(parts[++i]) || 0;\n } else if (part.startsWith(\"--port=\")) {\n port = Number(part.slice(7)) || 0;\n } else if (!part.startsWith(\"-\")) {\n pathParts.push(part);\n }\n }\n\n let path = pathParts[0];\n if (!path) {\n path = ctx.currentNamespace\n ? `$afs:${ctx.currentNamespace}${ctx.currentPath}`\n : ctx.currentPath;\n } else if (!path.startsWith(\"/\") && !path.startsWith(\"@\") && !path.startsWith(\"$afs\")) {\n const resolved = normalizePath(joinURL(ctx.currentPath, path));\n path = ctx.currentNamespace ? `$afs:${ctx.currentNamespace}${resolved}` : resolved;\n }\n\n return { path, web, port };\n}\n\n// ─── Tab Completion ──────────────────────────────────────────────────────\n\nexport function createCompleter(ctx: ReplContext) {\n return function completer(\n line: string,\n callback: (err: Error | null, result: [string[], string]) => void,\n ): void {\n const trimmed = line.trimStart();\n const tokens = trimmed.split(/\\s+/);\n\n // Command completion: first token\n if (tokens.length <= 1) {\n const partial = tokens[0] || \"\";\n const matches = ALL_COMMANDS.filter((c) => c.startsWith(partial));\n callback(null, [matches, partial]);\n return;\n }\n\n // Path completion: after command name\n // Find the last token as the path being completed\n const lastToken = tokens[tokens.length - 1]!;\n\n // Don't complete option flags\n if (lastToken.startsWith(\"-\")) {\n callback(null, [[], lastToken]);\n return;\n }\n\n // Determine parent dir and prefix for completion\n let parentDir: string;\n let prefix: string;\n\n if (lastToken.includes(\"/\")) {\n const lastSlash = lastToken.lastIndexOf(\"/\");\n const parentPart = lastToken.slice(0, lastSlash + 1) || \"/\";\n prefix = lastToken.slice(lastSlash + 1);\n // Resolve parent relative to current path\n if (\n parentPart.startsWith(\"/\") ||\n parentPart.startsWith(\"@\") ||\n parentPart.startsWith(\"$afs\")\n ) {\n parentDir = parentPart;\n } else {\n parentDir = joinURL(ctx.currentPath, parentPart);\n }\n } else {\n parentDir = ctx.currentPath;\n prefix = lastToken;\n }\n\n // Add namespace if needed\n const queryPath =\n ctx.currentNamespace && !parentDir.startsWith(\"@\") && !parentDir.startsWith(\"$afs\")\n ? `$afs:${ctx.currentNamespace}${parentDir}`\n : parentDir;\n\n // Check cache\n const cacheKey = queryPath;\n const cached = ctx.completionCache.get(cacheKey);\n if (cached) {\n const completions = buildCompletions(cached, prefix, lastToken);\n callback(null, [completions, lastToken]);\n return;\n }\n\n // Query AFS\n ctx.afs\n .list(queryPath)\n .then((result) => {\n const entries = result.data || [];\n ctx.completionCache.set(cacheKey, entries);\n const completions = buildCompletions(entries, prefix, lastToken);\n callback(null, [completions, lastToken]);\n })\n .catch(() => {\n callback(null, [[], lastToken]);\n });\n };\n}\n\nfunction buildCompletions(entries: AFSEntry[], prefix: string, lastToken: string): string[] {\n const matches = entries.filter((e) => {\n const name = basename(e.path);\n return name.startsWith(prefix);\n });\n\n return matches.map((e) => {\n const name = basename(e.path);\n const isDir = typeof e.meta?.childrenCount === \"number\";\n const suffix = isDir ? \"/\" : \" \";\n // Build the completion to replace lastToken\n if (lastToken.includes(\"/\")) {\n const lastSlash = lastToken.lastIndexOf(\"/\");\n return lastToken.slice(0, lastSlash + 1) + name + suffix;\n }\n return name + suffix;\n });\n}\n\n// ─── Blessed Cleanup ─────────────────────────────────────────────────────\n\nfunction cleanupStdinAfterBlessed(): void {\n const stdin = process.stdin as NodeJS.ReadStream & {\n _blessedInput?: unknown;\n _keypressHandler?: unknown;\n _dataHandler?: unknown;\n _keypressDecoder?: unknown;\n _kpiListener?: unknown;\n _readableState?: { flowing: unknown; reading: boolean };\n setRawMode?: (mode: boolean) => void;\n };\n\n stdin.removeAllListeners(\"keypress\");\n stdin.removeAllListeners(\"data\");\n\n delete stdin._blessedInput;\n delete stdin._keypressHandler;\n delete stdin._dataHandler;\n delete stdin._keypressDecoder;\n delete stdin._kpiListener;\n\n if (stdin.setRawMode) {\n stdin.setRawMode(false);\n }\n\n if (stdin._readableState) {\n stdin._readableState.flowing = null;\n stdin._readableState.reading = false;\n }\n}\n\n// ─── Spinner ──────────────────────────────────────────────────────────────\n\nconst SPINNER_FRAMES = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\nconst SPINNER_INTERVAL_MS = 80;\n\nfunction createSpinner() {\n let frameIdx = 0;\n let text = \"\";\n let timer: ReturnType<typeof setInterval> | null = null;\n\n return {\n start(initialText: string) {\n text = initialText;\n timer = setInterval(() => {\n const frame = SPINNER_FRAMES[frameIdx % SPINNER_FRAMES.length]!;\n process.stderr.write(`\\r${frame} ${text}`);\n frameIdx++;\n }, SPINNER_INTERVAL_MS);\n },\n update(newText: string) {\n text = newText;\n },\n stop() {\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n process.stderr.write(\"\\r\\x1b[K\");\n },\n };\n}\n\n// ─── Main REPL ───────────────────────────────────────────────────────────\n\nexport async function startRepl(options: {\n cwd: string;\n version: string;\n onExit?: () => Promise<void>;\n /** Pre-created providers to mount directly (e.g. mock-based providers that can't be recreated from URI) */\n extraProviders?: Array<{ provider: AFSModule; mountPath: string }>;\n}): Promise<void> {\n const { cwd, version, onExit, extraProviders } = options;\n\n // Load AFS with progress spinner\n const spinner = createSpinner();\n spinner.start(\"Mounting providers...\");\n\n let failures: MountFailure[] = [];\n const { afs, failures: mountFailures } = await loadAFS(cwd, {\n authContext: createCLIAuthContext(),\n credentialStore: createCredentialStore(),\n onProgress({ total, completed, failed }) {\n spinner.update(\n `Mounting providers... (${completed}/${total}${failed > 0 ? `, ${failed} failed` : \"\"})`,\n );\n },\n });\n failures = mountFailures;\n\n // Mount extra providers (mock-based or pre-created)\n if (extraProviders) {\n for (const { provider, mountPath } of extraProviders) {\n try {\n await afs.mount(provider, mountPath);\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n failures.push({ path: mountPath, reason: msg });\n }\n }\n }\n\n spinner.stop();\n\n // Print failure warnings if any\n if (failures.length > 0) {\n const noun = failures.length === 1 ? \"mount\" : \"mounts\";\n console.warn(`⚠ ${failures.length} ${noun} failed:`);\n for (const f of failures) {\n console.warn(` - ${f.path}: ${f.reason}`);\n }\n }\n\n // Activate programs with event triggers (best-effort)\n let programManager: import(\"./program/program-manager.js\").ProgramManager | undefined;\n try {\n const { ProgramManager } = await import(\"./program/program-manager.js\");\n const { scanProgramTriggers } = await import(\"./program/trigger-scanner.js\");\n const { listInstalledPrograms, getUserConfigDir } = await import(\"./config/program-install.js\");\n\n const userConfigDir = getUserConfigDir();\n programManager = new ProgramManager({\n globalAFS: afs,\n createProvider: afs.createProviderFromMount,\n listPrograms: async () => {\n const programs = await listInstalledPrograms({ userConfigDir });\n return programs.map((p) => ({\n id: p.id,\n installPath: p.installPath,\n mountPath: p.mountPath,\n }));\n },\n scanTriggers: async (programDir: string) => {\n let compile = null;\n try {\n const ashModule = \"@aigne/ash\";\n const mod = await import(/* webpackIgnore: true */ ashModule);\n compile = mod.compileSource;\n } catch {\n // @aigne/ash not available — use regex fallback\n }\n return scanProgramTriggers(programDir, compile);\n },\n dataDir: (programId: string) => `/.data/${programId}`,\n });\n\n await programManager.activateAll();\n const activated = programManager.getActivatedPrograms();\n if (activated.length > 0) {\n console.log(`Activated ${activated.length} program(s): ${activated.join(\", \")}`);\n }\n } catch (err) {\n console.error(`[PM] Program activation error:`, err instanceof Error ? err.message : err);\n }\n\n // Create executor\n const executor = new AFSCommandExecutor(afs, {\n cwd,\n tty: true,\n version,\n });\n\n const ctx = createReplContext({ executor, afs, version });\n\n // Print banner\n console.log(getBanner(ctx));\n\n let closed = false;\n let rl: Interface;\n let originalDataHandler: ((...args: unknown[]) => void) | null = null;\n let activeWebExplorer: { port: number; url: string; stop: () => void } | null = null;\n\n function startReplLoop() {\n const stdin = process.stdin as NodeJS.ReadStream & {\n _readableState?: { flowing: unknown; reading: boolean };\n };\n\n if (stdin._readableState) {\n stdin._readableState.flowing = null;\n stdin._readableState.reading = false;\n }\n\n rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n prompt: getPrompt(ctx),\n historySize: 100,\n completer: createCompleter(ctx),\n });\n\n // Save the original data handler from first successful createInterface\n if (!originalDataHandler && stdin.listenerCount(\"data\") > 0) {\n const listeners = stdin.listeners(\"data\") as ((...args: unknown[]) => void)[];\n originalDataHandler = listeners[0] ?? null;\n }\n\n // If createInterface failed to attach data listener, reattach the saved one\n if (stdin.listenerCount(\"data\") === 0 && originalDataHandler) {\n stdin.on(\"data\", originalDataHandler);\n stdin.resume();\n }\n\n rl.on(\"line\", async (line: string) => {\n const trimmed = line.trim();\n\n if (!trimmed) {\n if (!closed) rl.prompt();\n return;\n }\n\n // Check explore command (needs special handling for blessed TUI)\n if (isExploreCommand(trimmed)) {\n await handleExplore(trimmed, ctx);\n return;\n }\n\n // Check builtin commands\n const builtinResult = await handleBuiltinCommand(trimmed, ctx);\n if (builtinResult) {\n if (builtinResult.output) {\n console.log(builtinResult.output);\n }\n if (builtinResult.exit) {\n closed = true;\n rl.close();\n return;\n }\n if (!closed) {\n rl.setPrompt(getPrompt(ctx));\n rl.prompt();\n }\n return;\n }\n\n // Resolve relative paths in argv\n const resolved = resolveArgvPath(trimmed, ctx);\n\n // Execute via AFSCommandExecutor\n try {\n const result = await executor.execute(resolved);\n if (result.formatted) {\n console.log(result.formatted);\n }\n if (!result.success && result.error) {\n if (!result.formatted.includes(result.error.message)) {\n console.error(result.error.message);\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n console.error(`Error: ${msg}`);\n }\n\n // Clear completion cache after each command\n ctx.completionCache.clear();\n\n if (!closed) rl.prompt();\n });\n\n rl.on(\"close\", () => {\n if (!closed) {\n closed = true;\n if (activeWebExplorer) {\n activeWebExplorer.stop();\n activeWebExplorer = null;\n }\n console.log(\"\\nBye!\");\n }\n });\n\n rl.prompt();\n }\n\n async function handleExplore(trimmed: string, ctx: ReplContext) {\n const args = parseExploreArgs(trimmed, ctx);\n\n if (args.web) {\n await handleExploreWeb(args, ctx);\n return;\n }\n\n // TUI mode — takes over terminal, returns to REPL after exit\n rl.removeAllListeners(\"line\");\n rl.removeAllListeners(\"close\");\n rl.close();\n\n cleanupStdinAfterBlessed();\n\n try {\n const { createExplorerScreen } = await import(\"./explorer/screen.js\");\n await createExplorerScreen({\n afs: ctx.afs,\n startPath: args.path,\n version: ctx.version,\n onExit: () => {},\n });\n } catch {\n // ignore errors from explore\n }\n\n await new Promise((resolve) => setTimeout(resolve, 100));\n\n cleanupStdinAfterBlessed();\n\n process.stdout.write(\"\\x1b[?1049l\"); // Exit alternate screen\n process.stdout.write(\"\\x1b[?25h\"); // Show cursor\n\n console.log(\"\");\n\n if (!closed) {\n startReplLoop();\n }\n }\n\n async function handleExploreWeb(args: ExploreArgs, ctx: ReplContext) {\n // Stop previous web explorer if running\n if (activeWebExplorer) {\n activeWebExplorer.stop();\n console.log(\"Stopped previous web explorer.\");\n activeWebExplorer = null;\n }\n\n try {\n const { resolve } = await import(\"node:path\");\n const { startExplorer } = await import(\"@aigne/afs-explorer\");\n\n // Locate web assets\n let webRoot: string | undefined;\n try {\n const { createRequire } = await import(\"node:module\");\n const req = createRequire(import.meta.url);\n const explorerPkg = req.resolve(\"@aigne/afs-explorer/package.json\");\n webRoot = resolve(explorerPkg, \"..\", \"web\");\n } catch {\n // Fallback — embedded assets may be used\n }\n\n const info = await startExplorer(ctx.afs, {\n port: args.port,\n host: \"localhost\",\n webRoot,\n open: true,\n });\n\n activeWebExplorer = info;\n console.log(`Web explorer running at ${info.url}`);\n console.log('Type \"explore --web\" again to restart, or continue using REPL.');\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n console.error(`Failed to start web explorer: ${msg}`);\n }\n\n if (!closed) rl.prompt();\n }\n\n startReplLoop();\n\n // Return promise that resolves when REPL exits\n return new Promise((resolve) => {\n const checkClosed = setInterval(() => {\n if (closed) {\n clearInterval(checkClosed);\n const cleanup = async () => {\n if (programManager) {\n await programManager.deactivateAll().catch(() => {});\n }\n if (onExit) {\n await onExit().catch(() => {});\n }\n };\n cleanup().then(resolve);\n }\n }, 100);\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"repl.mjs","names":["dirname","ns","resolved","ctx","resolve"],"sources":["../src/repl.ts"],"sourcesContent":["/**\n * AFS CLI Interactive REPL\n *\n * Single-file REPL implementation for `afs -i` / `afs --interactive`.\n * Provides: REPL loop, cd/pwd, Tab completion, explore TUI integration.\n */\n\nimport { basename } from \"node:path\";\nimport { createInterface, type Interface } from \"node:readline\";\nimport type { AFS, AFSEntry, AFSModule } from \"@aigne/afs\";\nimport { joinURL } from \"ufo\";\nimport { loadAFS, type MountFailure } from \"./config/afs-loader.js\";\nimport { AFSCommandExecutor } from \"./core/executor/index.js\";\nimport { createCLIAuthContext } from \"./credential/cli-auth-context.js\";\nimport { createCredentialStore } from \"./credential/store.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────\n\nexport interface ReplOptions {\n executor: AFSCommandExecutor;\n afs: AFS;\n version: string;\n}\n\nexport interface ReplContext {\n executor: AFSCommandExecutor;\n afs: AFS;\n version: string;\n currentPath: string;\n currentNamespace: string | null;\n completionCache: Map<string, AFSEntry[]>;\n}\n\nexport interface BuiltinResult {\n output?: string;\n exit?: boolean;\n}\n\n// ─── Constants ───────────────────────────────────────────────────────────\n\nconst BUILTIN_COMMANDS = [\"cd\", \"pwd\", \"help\", \"exit\", \"quit\"];\n\n/** Commands that default to current path when no path argument is given in REPL */\nconst DEFAULT_PATH_COMMANDS = new Set([\"ls\", \"read\", \"stat\", \"explain\", \"explore\"]);\n\nconst ALL_COMMANDS = [\n \"ls\",\n \"read\",\n \"write\",\n \"delete\",\n \"stat\",\n \"exec\",\n \"explain\",\n \"search\",\n \"mount\",\n \"program\",\n \"vault\",\n \"service\",\n \"explore\",\n \"cd\",\n \"pwd\",\n \"help\",\n \"exit\",\n];\n\n// ─── Context ─────────────────────────────────────────────────────────────\n\nexport function createReplContext(options: ReplOptions): ReplContext {\n return {\n executor: options.executor,\n afs: options.afs,\n version: options.version,\n currentPath: \"/\",\n currentNamespace: null,\n completionCache: new Map(),\n };\n}\n\n// ─── Prompt ──────────────────────────────────────────────────────────────\n\nexport function getPrompt(ctx: ReplContext): string {\n const dirname = ctx.currentPath === \"/\" ? \"/\" : basename(ctx.currentPath);\n const nsPrefix = ctx.currentNamespace ? `${ctx.currentNamespace}:` : \"\";\n return `afs ${nsPrefix}${dirname}> `;\n}\n\n// ─── Banner ──────────────────────────────────────────────────────────────\n\nexport function getBanner(ctx: ReplContext): string {\n const mountCount = ctx.afs.getMounts().length;\n const plural = mountCount === 1 ? \"provider\" : \"providers\";\n return `AFS Interactive Shell v${ctx.version} — ${mountCount} ${plural} mounted. Type \"help\" for commands.`;\n}\n\n// ─── Builtin Commands ────────────────────────────────────────────────────\n\nexport function isBuiltinCommand(input: string): boolean {\n const trimmed = input.trim();\n if (!trimmed) return false;\n const cmd = trimmed.split(/\\s+/)[0]!;\n return BUILTIN_COMMANDS.includes(cmd);\n}\n\nexport async function handleBuiltinCommand(\n input: string,\n ctx: ReplContext,\n): Promise<BuiltinResult | null> {\n const trimmed = input.trim();\n if (!trimmed) return null;\n\n const parts = trimmed.split(/\\s+/);\n const cmd = parts[0]!;\n\n switch (cmd) {\n case \"exit\":\n case \"quit\":\n return { exit: true, output: \"Bye!\" };\n\n case \"help\":\n return { output: formatHelp() };\n\n case \"pwd\":\n return handlePwd(ctx);\n\n case \"cd\":\n return handleCd(parts.slice(1).join(\" \"), ctx);\n\n default:\n return null;\n }\n}\n\nfunction formatHelp(): string {\n const lines = [\n \"Available commands:\",\n \"\",\n \" AFS Commands:\",\n \" ls [path] List directory contents (default: current dir)\",\n \" read [path] Read file content (default: current node)\",\n \" write <path> [content] Write content to file\",\n \" delete <path> Delete file or directory\",\n \" stat [path] Get file or directory info (default: current node)\",\n \" exec <action> Execute an action\",\n \" explain [topic] Explain AFS concepts or paths (default: current path)\",\n \" search <path> <query> Search content in a path\",\n \" mount Mount management (add, list, remove)\",\n \" program Program management (install, list, uninstall)\",\n \" vault Credential vault management\",\n \" service Daemon service management\",\n \" explore [path] Interactive TUI explorer (default: current dir)\",\n \"\",\n \" REPL Commands:\",\n \" cd [path] Change working directory\",\n \" pwd Print working directory\",\n \" help Show this help\",\n \" exit / quit Exit REPL\",\n \"\",\n \" Tips:\",\n \" - Commands work with or without 'afs' prefix\",\n \" - Use Tab for command and path completion\",\n \" - Ctrl+D to exit\",\n ];\n return lines.join(\"\\n\");\n}\n\n// ─── cd / pwd ────────────────────────────────────────────────────────────\n\nfunction handlePwd(ctx: ReplContext): BuiltinResult {\n if (ctx.currentNamespace) {\n return { output: `@${ctx.currentNamespace}${ctx.currentPath}` };\n }\n return { output: ctx.currentPath };\n}\n\nasync function handleCd(target: string, ctx: ReplContext): Promise<BuiltinResult> {\n if (!target || target.trim() === \"\") {\n // cd with no args → go to root\n ctx.currentPath = \"/\";\n return {};\n }\n\n const trimmed = target.trim();\n\n // Handle @default → reset namespace\n if (trimmed === \"@default\") {\n ctx.currentNamespace = null;\n ctx.currentPath = \"/\";\n return {};\n }\n\n // Handle @namespace syntax\n if (trimmed.startsWith(\"@\")) {\n const rest = trimmed.slice(1);\n const slashIdx = rest.indexOf(\"/\");\n if (slashIdx === -1) {\n // @namespace only → switch to namespace root\n const ns = rest;\n if (!ns) return { output: \"cd: invalid namespace\" };\n // Validate by calling stat on namespace root\n try {\n const canonicalPath = `$afs:${ns}/`;\n await ctx.afs.stat(canonicalPath);\n ctx.currentNamespace = ns;\n ctx.currentPath = \"/\";\n return {};\n } catch {\n return { output: `cd: no such path: @${ns}/` };\n }\n }\n const ns = rest.slice(0, slashIdx);\n const path = rest.slice(slashIdx) || \"/\";\n if (!ns) return { output: \"cd: invalid namespace\" };\n try {\n const canonicalPath = `$afs:${ns}${path}`;\n await ctx.afs.stat(canonicalPath);\n ctx.currentNamespace = ns;\n ctx.currentPath = path;\n return {};\n } catch {\n return { output: `cd: no such path: @${ns}${path}` };\n }\n }\n\n // Handle absolute path\n if (trimmed.startsWith(\"/\")) {\n const resolved = normalizePath(trimmed);\n try {\n const canonicalPath = ctx.currentNamespace\n ? `$afs:${ctx.currentNamespace}${resolved}`\n : resolved;\n await ctx.afs.stat(canonicalPath);\n ctx.currentPath = resolved;\n return {};\n } catch {\n return { output: `cd: no such path: ${trimmed}` };\n }\n }\n\n // Handle relative path (including ..)\n const resolved = normalizePath(joinURL(ctx.currentPath, trimmed));\n try {\n const canonicalPath = ctx.currentNamespace\n ? `$afs:${ctx.currentNamespace}${resolved}`\n : resolved;\n await ctx.afs.stat(canonicalPath);\n ctx.currentPath = resolved;\n return {};\n } catch {\n return { output: `cd: no such path: ${trimmed}` };\n }\n}\n\nfunction normalizePath(path: string): string {\n // Split into segments, resolve .., remove empty segments\n const parts = path.split(\"/\").filter(Boolean);\n const resolved: string[] = [];\n for (const part of parts) {\n if (part === \"..\") {\n resolved.pop();\n } else if (part !== \".\") {\n resolved.push(part);\n }\n }\n return `/${resolved.join(\"/\")}`;\n}\n\n// ─── Argv Path Preprocessing ─────────────────────────────────────────────\n\nexport function resolveArgvPath(input: string, ctx: ReplContext): string[] {\n const tokens = tokenize(input);\n if (tokens.length === 0) return tokens;\n\n // Find the command name (skip optional 'afs' prefix)\n let cmdIdx = 0;\n if (tokens[0] === \"afs\" && tokens.length > 1) cmdIdx = 1;\n const cmd = tokens[cmdIdx];\n if (!cmd) return tokens;\n\n // Find first positional argument (non-option) after the command\n let argIdx = -1;\n for (let i = cmdIdx + 1; i < tokens.length; i++) {\n const token = tokens[i]!;\n if (!token.startsWith(\"-\")) {\n // For \"mount\" command, subcommands like \"list\", \"add\", \"remove\" are not paths\n if (\n cmd === \"mount\" &&\n (token === \"list\" || token === \"ls\" || token === \"add\" || token === \"remove\")\n ) {\n continue;\n }\n argIdx = i;\n break;\n }\n // Skip --option value pairs\n if (token.startsWith(\"--\") && !token.includes(\"=\") && i + 1 < tokens.length) {\n i++; // skip the value\n }\n }\n\n if (argIdx === -1) {\n // No positional arg found — inject current path for safe commands\n if (DEFAULT_PATH_COMMANDS.has(cmd)) {\n const currentFullPath = ctx.currentNamespace\n ? `@${ctx.currentNamespace}${ctx.currentPath}`\n : ctx.currentPath;\n tokens.push(currentFullPath);\n }\n return tokens;\n }\n\n const arg = tokens[argIdx]!;\n\n // Don't resolve if already absolute, canonical, or namespace-prefixed\n if (arg.startsWith(\"/\") || arg.startsWith(\"@\") || arg.startsWith(\"$afs\")) {\n return tokens;\n }\n\n // Resolve relative path\n const resolved = normalizePath(joinURL(ctx.currentPath, arg));\n\n // Add namespace prefix if in a non-default namespace\n const finalPath = ctx.currentNamespace ? `@${ctx.currentNamespace}${resolved}` : resolved;\n\n // Replace the token in the original input\n tokens[argIdx] = finalPath;\n return tokens;\n}\n\nfunction tokenize(input: string): string[] {\n const tokens: string[] = [];\n let current = \"\";\n let inQuote = false;\n let quoteChar = \"\";\n\n for (let i = 0; i < input.length; i++) {\n const char = input[i]!;\n if (inQuote) {\n if (char === quoteChar) {\n inQuote = false;\n } else {\n current += char;\n }\n } else if (char === '\"' || char === \"'\") {\n inQuote = true;\n quoteChar = char;\n } else if (char === \" \" || char === \"\\t\") {\n if (current) {\n tokens.push(current);\n current = \"\";\n }\n } else {\n current += char;\n }\n }\n if (current) tokens.push(current);\n return tokens;\n}\n\n// ─── Explore Detection ───────────────────────────────────────────────────\n\nexport function isExploreCommand(cmd: string): boolean {\n const normalized = cmd.replace(/^afs\\s+/, \"\").trim();\n return normalized === \"explore\" || normalized.startsWith(\"explore \");\n}\n\ninterface ExploreArgs {\n path: string;\n web: boolean;\n port: number;\n}\n\nfunction parseExploreArgs(cmd: string, ctx: ReplContext): ExploreArgs {\n const normalized = cmd.replace(/^afs\\s+/, \"\").trim();\n const parts = normalized.split(/\\s+/).slice(1); // drop \"explore\"\n\n let web = false;\n let port = 0;\n const pathParts: string[] = [];\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]!;\n if (part === \"--web\") {\n web = true;\n } else if (part === \"--port\" && i + 1 < parts.length) {\n port = Number(parts[++i]) || 0;\n } else if (part.startsWith(\"--port=\")) {\n port = Number(part.slice(7)) || 0;\n } else if (!part.startsWith(\"-\")) {\n pathParts.push(part);\n }\n }\n\n let path = pathParts[0];\n if (!path) {\n path = ctx.currentNamespace\n ? `$afs:${ctx.currentNamespace}${ctx.currentPath}`\n : ctx.currentPath;\n } else if (!path.startsWith(\"/\") && !path.startsWith(\"@\") && !path.startsWith(\"$afs\")) {\n const resolved = normalizePath(joinURL(ctx.currentPath, path));\n path = ctx.currentNamespace ? `$afs:${ctx.currentNamespace}${resolved}` : resolved;\n }\n\n return { path, web, port };\n}\n\n// ─── Tab Completion ──────────────────────────────────────────────────────\n\nexport function createCompleter(ctx: ReplContext) {\n return function completer(\n line: string,\n callback: (err: Error | null, result: [string[], string]) => void,\n ): void {\n const trimmed = line.trimStart();\n const tokens = trimmed.split(/\\s+/);\n\n // Command completion: first token\n if (tokens.length <= 1) {\n const partial = tokens[0] || \"\";\n const matches = ALL_COMMANDS.filter((c) => c.startsWith(partial));\n callback(null, [matches, partial]);\n return;\n }\n\n // Path completion: after command name\n // Find the last token as the path being completed\n const lastToken = tokens[tokens.length - 1]!;\n\n // Don't complete option flags\n if (lastToken.startsWith(\"-\")) {\n callback(null, [[], lastToken]);\n return;\n }\n\n // Determine parent dir and prefix for completion\n let parentDir: string;\n let prefix: string;\n\n if (lastToken.includes(\"/\")) {\n const lastSlash = lastToken.lastIndexOf(\"/\");\n const parentPart = lastToken.slice(0, lastSlash + 1) || \"/\";\n prefix = lastToken.slice(lastSlash + 1);\n // Resolve parent relative to current path\n if (\n parentPart.startsWith(\"/\") ||\n parentPart.startsWith(\"@\") ||\n parentPart.startsWith(\"$afs\")\n ) {\n parentDir = parentPart;\n } else {\n parentDir = joinURL(ctx.currentPath, parentPart);\n }\n } else {\n parentDir = ctx.currentPath;\n prefix = lastToken;\n }\n\n // Add namespace if needed\n const queryPath =\n ctx.currentNamespace && !parentDir.startsWith(\"@\") && !parentDir.startsWith(\"$afs\")\n ? `$afs:${ctx.currentNamespace}${parentDir}`\n : parentDir;\n\n // Check cache\n const cacheKey = queryPath;\n const cached = ctx.completionCache.get(cacheKey);\n if (cached) {\n const completions = buildCompletions(cached, prefix, lastToken);\n callback(null, [completions, lastToken]);\n return;\n }\n\n // Query AFS\n ctx.afs\n .list(queryPath)\n .then((result) => {\n const entries = result.data || [];\n ctx.completionCache.set(cacheKey, entries);\n const completions = buildCompletions(entries, prefix, lastToken);\n callback(null, [completions, lastToken]);\n })\n .catch(() => {\n callback(null, [[], lastToken]);\n });\n };\n}\n\nfunction buildCompletions(entries: AFSEntry[], prefix: string, lastToken: string): string[] {\n const matches = entries.filter((e) => {\n const name = basename(e.path);\n return name.startsWith(prefix);\n });\n\n return matches.map((e) => {\n const name = basename(e.path);\n const isDir = typeof e.meta?.childrenCount === \"number\";\n const suffix = isDir ? \"/\" : \" \";\n // Build the completion to replace lastToken\n if (lastToken.includes(\"/\")) {\n const lastSlash = lastToken.lastIndexOf(\"/\");\n return lastToken.slice(0, lastSlash + 1) + name + suffix;\n }\n return name + suffix;\n });\n}\n\n// ─── Blessed Cleanup ─────────────────────────────────────────────────────\n\nfunction cleanupStdinAfterBlessed(): void {\n const stdin = process.stdin as NodeJS.ReadStream & {\n _blessedInput?: unknown;\n _keypressHandler?: unknown;\n _dataHandler?: unknown;\n _keypressDecoder?: unknown;\n _kpiListener?: unknown;\n _readableState?: { flowing: unknown; reading: boolean };\n setRawMode?: (mode: boolean) => void;\n };\n\n stdin.removeAllListeners(\"keypress\");\n stdin.removeAllListeners(\"data\");\n\n delete stdin._blessedInput;\n delete stdin._keypressHandler;\n delete stdin._dataHandler;\n delete stdin._keypressDecoder;\n delete stdin._kpiListener;\n\n if (stdin.setRawMode) {\n stdin.setRawMode(false);\n }\n\n if (stdin._readableState) {\n stdin._readableState.flowing = null;\n stdin._readableState.reading = false;\n }\n}\n\n// ─── Spinner ──────────────────────────────────────────────────────────────\n\nconst SPINNER_FRAMES = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\nconst SPINNER_INTERVAL_MS = 80;\n\nfunction createSpinner() {\n let frameIdx = 0;\n let text = \"\";\n let timer: ReturnType<typeof setInterval> | null = null;\n\n return {\n start(initialText: string) {\n text = initialText;\n timer = setInterval(() => {\n const frame = SPINNER_FRAMES[frameIdx % SPINNER_FRAMES.length]!;\n process.stderr.write(`\\r${frame} ${text}`);\n frameIdx++;\n }, SPINNER_INTERVAL_MS);\n },\n update(newText: string) {\n text = newText;\n },\n stop() {\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n process.stderr.write(\"\\r\\x1b[K\");\n },\n };\n}\n\n// ─── Main REPL ───────────────────────────────────────────────────────────\n\nexport async function startRepl(options: {\n cwd: string;\n version: string;\n onExit?: () => Promise<void>;\n /** Pre-created providers to mount directly (e.g. mock-based providers that can't be recreated from URI) */\n extraProviders?: Array<{ provider: AFSModule; mountPath: string }>;\n}): Promise<void> {\n const { cwd, version, onExit, extraProviders } = options;\n\n // Load AFS with progress spinner\n const spinner = createSpinner();\n spinner.start(\"Mounting providers...\");\n\n let failures: MountFailure[] = [];\n const { afs, failures: mountFailures } = await loadAFS(cwd, {\n authContext: createCLIAuthContext(),\n credentialStore: createCredentialStore(),\n onProgress({ total, completed, failed }) {\n spinner.update(\n `Mounting providers... (${completed}/${total}${failed > 0 ? `, ${failed} failed` : \"\"})`,\n );\n },\n });\n failures = mountFailures;\n\n // Mount extra providers (mock-based or pre-created)\n if (extraProviders) {\n for (const { provider, mountPath } of extraProviders) {\n try {\n await afs.mount(provider, mountPath);\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n failures.push({ path: mountPath, reason: msg });\n }\n }\n }\n\n spinner.stop();\n\n // Print failure warnings if any\n if (failures.length > 0) {\n const noun = failures.length === 1 ? \"mount\" : \"mounts\";\n console.warn(`⚠ ${failures.length} ${noun} failed:`);\n for (const f of failures) {\n console.warn(` - ${f.path}: ${f.reason}`);\n }\n }\n\n // Activate programs with event triggers (best-effort)\n let programManager: import(\"./program/program-manager.js\").ProgramManager | undefined;\n try {\n const { ProgramManager } = await import(\"./program/program-manager.js\");\n const { scanProgramTriggers } = await import(\"./program/trigger-scanner.js\");\n const { listInstalledPrograms, getUserConfigDir } = await import(\"./config/program-install.js\");\n\n const userConfigDir = getUserConfigDir();\n programManager = new ProgramManager({\n globalAFS: afs,\n createProvider: afs.createProviderFromMount,\n listPrograms: async () => {\n const programs = await listInstalledPrograms({ userConfigDir });\n return programs.map((p) => ({\n id: p.id,\n installPath: p.installPath,\n mountPath: p.mountPath,\n }));\n },\n scanTriggers: async (programDir: string) => {\n let compile = null;\n try {\n const ashModule = \"@aigne/ash\";\n const mod = await import(/* webpackIgnore: true */ ashModule);\n compile = mod.compileSource;\n } catch {\n // @aigne/ash not available — use regex fallback\n }\n return scanProgramTriggers(programDir, compile);\n },\n dataDir: (programId: string) => `/.data/${programId}`,\n readMountOverrides: async (programId) => {\n const { readProgramMountOverrides } = await import(\"./config/program-install.js\");\n return readProgramMountOverrides(programId, { userConfigDir });\n },\n });\n\n await programManager.activateAll();\n const activated = programManager.getActivatedPrograms();\n if (activated.length > 0) {\n console.log(`Activated ${activated.length} program(s): ${activated.join(\", \")}`);\n }\n } catch (err) {\n console.error(`[PM] Program activation error:`, err instanceof Error ? err.message : err);\n }\n\n // Create executor\n const executor = new AFSCommandExecutor(afs, {\n cwd,\n tty: true,\n version,\n });\n\n const ctx = createReplContext({ executor, afs, version });\n\n // Print banner\n console.log(getBanner(ctx));\n\n let closed = false;\n let rl: Interface;\n let originalDataHandler: ((...args: unknown[]) => void) | null = null;\n let activeWebExplorer: { port: number; url: string; stop: () => void } | null = null;\n\n function startReplLoop() {\n const stdin = process.stdin as NodeJS.ReadStream & {\n _readableState?: { flowing: unknown; reading: boolean };\n };\n\n if (stdin._readableState) {\n stdin._readableState.flowing = null;\n stdin._readableState.reading = false;\n }\n\n rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n prompt: getPrompt(ctx),\n historySize: 100,\n completer: createCompleter(ctx),\n });\n\n // Save the original data handler from first successful createInterface\n if (!originalDataHandler && stdin.listenerCount(\"data\") > 0) {\n const listeners = stdin.listeners(\"data\") as ((...args: unknown[]) => void)[];\n originalDataHandler = listeners[0] ?? null;\n }\n\n // If createInterface failed to attach data listener, reattach the saved one\n if (stdin.listenerCount(\"data\") === 0 && originalDataHandler) {\n stdin.on(\"data\", originalDataHandler);\n stdin.resume();\n }\n\n rl.on(\"line\", async (line: string) => {\n const trimmed = line.trim();\n\n if (!trimmed) {\n if (!closed) rl.prompt();\n return;\n }\n\n // Check explore command (needs special handling for blessed TUI)\n if (isExploreCommand(trimmed)) {\n await handleExplore(trimmed, ctx);\n return;\n }\n\n // Check builtin commands\n const builtinResult = await handleBuiltinCommand(trimmed, ctx);\n if (builtinResult) {\n if (builtinResult.output) {\n console.log(builtinResult.output);\n }\n if (builtinResult.exit) {\n closed = true;\n rl.close();\n return;\n }\n if (!closed) {\n rl.setPrompt(getPrompt(ctx));\n rl.prompt();\n }\n return;\n }\n\n // Resolve relative paths in argv\n const resolved = resolveArgvPath(trimmed, ctx);\n\n // Execute via AFSCommandExecutor\n try {\n const result = await executor.execute(resolved);\n if (result.formatted) {\n console.log(result.formatted);\n }\n if (!result.success && result.error) {\n if (!result.formatted.includes(result.error.message)) {\n console.error(result.error.message);\n }\n }\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n console.error(`Error: ${msg}`);\n }\n\n // Clear completion cache after each command\n ctx.completionCache.clear();\n\n if (!closed) rl.prompt();\n });\n\n rl.on(\"close\", () => {\n if (!closed) {\n closed = true;\n if (activeWebExplorer) {\n activeWebExplorer.stop();\n activeWebExplorer = null;\n }\n console.log(\"\\nBye!\");\n }\n });\n\n rl.prompt();\n }\n\n async function handleExplore(trimmed: string, ctx: ReplContext) {\n const args = parseExploreArgs(trimmed, ctx);\n\n if (args.web) {\n await handleExploreWeb(args, ctx);\n return;\n }\n\n // TUI mode — takes over terminal, returns to REPL after exit\n rl.removeAllListeners(\"line\");\n rl.removeAllListeners(\"close\");\n rl.close();\n\n cleanupStdinAfterBlessed();\n\n try {\n const { createExplorerScreen } = await import(\"./explorer/screen.js\");\n await createExplorerScreen({\n afs: ctx.afs,\n startPath: args.path,\n version: ctx.version,\n onExit: () => {},\n });\n } catch {\n // ignore errors from explore\n }\n\n await new Promise((resolve) => setTimeout(resolve, 100));\n\n cleanupStdinAfterBlessed();\n\n process.stdout.write(\"\\x1b[?1049l\"); // Exit alternate screen\n process.stdout.write(\"\\x1b[?25h\"); // Show cursor\n\n console.log(\"\");\n\n if (!closed) {\n startReplLoop();\n }\n }\n\n async function handleExploreWeb(args: ExploreArgs, ctx: ReplContext) {\n // Stop previous web explorer if running\n if (activeWebExplorer) {\n activeWebExplorer.stop();\n console.log(\"Stopped previous web explorer.\");\n activeWebExplorer = null;\n }\n\n try {\n const { resolve } = await import(\"node:path\");\n const { startExplorer } = await import(\"@aigne/afs-explorer\");\n\n // Locate web assets\n let webRoot: string | undefined;\n try {\n const { createRequire } = await import(\"node:module\");\n const req = createRequire(import.meta.url);\n const explorerPkg = req.resolve(\"@aigne/afs-explorer/package.json\");\n webRoot = resolve(explorerPkg, \"..\", \"web\");\n } catch {\n // Fallback — embedded assets may be used\n }\n\n const info = await startExplorer(ctx.afs, {\n port: args.port,\n host: \"localhost\",\n webRoot,\n open: true,\n });\n\n activeWebExplorer = info;\n console.log(`Web explorer running at ${info.url}`);\n console.log('Type \"explore --web\" again to restart, or continue using REPL.');\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n console.error(`Failed to start web explorer: ${msg}`);\n }\n\n if (!closed) rl.prompt();\n }\n\n startReplLoop();\n\n // Return promise that resolves when REPL exits\n return new Promise((resolve) => {\n const checkClosed = setInterval(() => {\n if (closed) {\n clearInterval(checkClosed);\n const cleanup = async () => {\n if (programManager) {\n await programManager.deactivateAll().catch(() => {});\n }\n if (onExit) {\n await onExit().catch(() => {});\n }\n };\n cleanup().then(resolve);\n }\n }, 100);\n });\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/afs-cli",
|
|
3
|
-
"version": "1.11.0-beta.
|
|
3
|
+
"version": "1.11.0-beta.13",
|
|
4
4
|
"description": "AFS Command Line Interface",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"publishConfig": {
|
|
@@ -53,30 +53,30 @@
|
|
|
53
53
|
"yargs": "^17.7.2",
|
|
54
54
|
"yargs-parser": "^22.0.0",
|
|
55
55
|
"zod": "^4.0.0",
|
|
56
|
-
"@aigne/afs": "1.11.0-beta.
|
|
57
|
-
"@aigne/afs-
|
|
58
|
-
"@aigne/afs
|
|
59
|
-
"@aigne/afs-dns": "1.11.0-beta.
|
|
60
|
-
"@aigne/afs-ec2": "1.11.0-beta.
|
|
61
|
-
"@aigne/afs-explorer": "1.11.0-beta.
|
|
62
|
-
"@aigne/afs-fs": "1.11.0-beta.
|
|
63
|
-
"@aigne/afs-gce": "1.11.0-beta.
|
|
64
|
-
"@aigne/afs-gcs": "1.11.0-beta.
|
|
65
|
-
"@aigne/afs-
|
|
66
|
-
"@aigne/afs-
|
|
67
|
-
"@aigne/afs-
|
|
68
|
-
"@aigne/afs-json": "1.11.0-beta.
|
|
69
|
-
"@aigne/afs-mcp": "1.11.0-beta.
|
|
70
|
-
"@aigne/afs-mcp-recipe": "1.11.0-beta.
|
|
71
|
-
"@aigne/afs-
|
|
72
|
-
"@aigne/afs-
|
|
73
|
-
"@aigne/afs-s3": "1.11.0-beta.
|
|
74
|
-
"@aigne/afs-sandbox": "1.11.0-beta.
|
|
75
|
-
"@aigne/afs-sqlite": "1.11.0-beta.
|
|
76
|
-
"@aigne/afs-telegram": "1.11.0-beta.
|
|
77
|
-
"@aigne/afs-toml": "1.11.0-beta.
|
|
78
|
-
"@aigne/afs-ui": "1.11.0-beta.
|
|
79
|
-
"@aigne/afs-workspace": "1.11.0-beta.
|
|
56
|
+
"@aigne/afs-ash": "1.11.0-beta.13",
|
|
57
|
+
"@aigne/afs-cloudflare": "1.11.0-beta.13",
|
|
58
|
+
"@aigne/afs": "1.11.0-beta.13",
|
|
59
|
+
"@aigne/afs-dns": "1.11.0-beta.13",
|
|
60
|
+
"@aigne/afs-ec2": "1.11.0-beta.13",
|
|
61
|
+
"@aigne/afs-explorer": "1.11.0-beta.13",
|
|
62
|
+
"@aigne/afs-fs": "1.11.0-beta.13",
|
|
63
|
+
"@aigne/afs-gce": "1.11.0-beta.13",
|
|
64
|
+
"@aigne/afs-gcs": "1.11.0-beta.13",
|
|
65
|
+
"@aigne/afs-git": "1.11.0-beta.13",
|
|
66
|
+
"@aigne/afs-http": "1.11.0-beta.13",
|
|
67
|
+
"@aigne/afs-github": "1.11.0-beta.13",
|
|
68
|
+
"@aigne/afs-json": "1.11.0-beta.13",
|
|
69
|
+
"@aigne/afs-mcp": "1.11.0-beta.13",
|
|
70
|
+
"@aigne/afs-mcp-recipe": "1.11.0-beta.13",
|
|
71
|
+
"@aigne/afs-registry": "1.11.0-beta.13",
|
|
72
|
+
"@aigne/afs-persona": "1.11.0-beta.13",
|
|
73
|
+
"@aigne/afs-s3": "1.11.0-beta.13",
|
|
74
|
+
"@aigne/afs-sandbox": "1.11.0-beta.13",
|
|
75
|
+
"@aigne/afs-sqlite": "1.11.0-beta.13",
|
|
76
|
+
"@aigne/afs-telegram": "1.11.0-beta.13",
|
|
77
|
+
"@aigne/afs-toml": "1.11.0-beta.13",
|
|
78
|
+
"@aigne/afs-ui": "1.11.0-beta.13",
|
|
79
|
+
"@aigne/afs-workspace": "1.11.0-beta.13"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
82
|
"@modelcontextprotocol/server-everything": "^2026.1.26",
|
|
@@ -88,9 +88,9 @@
|
|
|
88
88
|
"rimraf": "^6.1.2",
|
|
89
89
|
"tsdown": "0.20.0-beta.3",
|
|
90
90
|
"typescript": "5.9.2",
|
|
91
|
-
"@aigne/afs-vault": "1.11.0-beta.
|
|
92
|
-
"@aigne/
|
|
93
|
-
"@aigne/
|
|
91
|
+
"@aigne/afs-vault": "1.11.0-beta.13",
|
|
92
|
+
"@aigne/scripts": "0.0.0",
|
|
93
|
+
"@aigne/typescript-config": "0.0.0"
|
|
94
94
|
},
|
|
95
95
|
"scripts": {
|
|
96
96
|
"build": "tsdown",
|