@aigne/afs-cli 1.11.0-beta.1 → 1.11.0-beta.11

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.
Files changed (348) hide show
  1. package/README.md +262 -15
  2. package/dist/_virtual/rolldown_runtime.cjs +29 -0
  3. package/dist/_virtual/rolldown_runtime.mjs +7 -0
  4. package/dist/cli.cjs +40 -0
  5. package/dist/cli.d.cts +2 -0
  6. package/dist/cli.d.mts +2 -1
  7. package/dist/cli.mjs +36 -24
  8. package/dist/cli.mjs.map +1 -0
  9. package/dist/config/afs-loader.cjs +578 -0
  10. package/dist/config/afs-loader.d.cts +19 -0
  11. package/dist/config/afs-loader.d.cts.map +1 -0
  12. package/dist/config/afs-loader.d.mts +19 -0
  13. package/dist/config/afs-loader.d.mts.map +1 -0
  14. package/dist/config/afs-loader.mjs +576 -0
  15. package/dist/config/afs-loader.mjs.map +1 -0
  16. package/dist/config/env.cjs +46 -0
  17. package/dist/config/env.mjs +46 -0
  18. package/dist/config/env.mjs.map +1 -0
  19. package/dist/config/loader.cjs +219 -0
  20. package/dist/config/loader.mjs +217 -0
  21. package/dist/config/loader.mjs.map +1 -0
  22. package/dist/config/mount-commands.cjs +226 -0
  23. package/dist/config/mount-commands.d.cts +14 -0
  24. package/dist/config/mount-commands.d.cts.map +1 -0
  25. package/dist/config/mount-commands.d.mts +14 -0
  26. package/dist/config/mount-commands.d.mts.map +1 -0
  27. package/dist/config/mount-commands.mjs +220 -0
  28. package/dist/config/mount-commands.mjs.map +1 -0
  29. package/dist/config/schema.cjs +99 -0
  30. package/dist/config/schema.mjs +98 -0
  31. package/dist/config/schema.mjs.map +1 -0
  32. package/dist/core/commands/delete.cjs +41 -0
  33. package/dist/core/commands/delete.d.cts +18 -0
  34. package/dist/core/commands/delete.d.cts.map +1 -0
  35. package/dist/core/commands/delete.d.mts +18 -0
  36. package/dist/core/commands/delete.d.mts.map +1 -0
  37. package/dist/core/commands/delete.mjs +42 -0
  38. package/dist/core/commands/delete.mjs.map +1 -0
  39. package/dist/core/commands/exec.cjs +98 -0
  40. package/dist/core/commands/exec.d.cts +26 -0
  41. package/dist/core/commands/exec.d.cts.map +1 -0
  42. package/dist/core/commands/exec.d.mts +26 -0
  43. package/dist/core/commands/exec.d.mts.map +1 -0
  44. package/dist/core/commands/exec.mjs +99 -0
  45. package/dist/core/commands/exec.mjs.map +1 -0
  46. package/dist/core/commands/explain.cjs +278 -0
  47. package/dist/core/commands/explain.d.cts +25 -0
  48. package/dist/core/commands/explain.d.cts.map +1 -0
  49. package/dist/core/commands/explain.d.mts +25 -0
  50. package/dist/core/commands/explain.d.mts.map +1 -0
  51. package/dist/core/commands/explain.mjs +279 -0
  52. package/dist/core/commands/explain.mjs.map +1 -0
  53. package/dist/core/commands/explore.cjs +30 -0
  54. package/dist/core/commands/explore.d.mts +2 -0
  55. package/dist/core/commands/explore.mjs +31 -0
  56. package/dist/core/commands/explore.mjs.map +1 -0
  57. package/dist/core/commands/index.cjs +36 -0
  58. package/dist/core/commands/index.d.cts +21 -0
  59. package/dist/core/commands/index.d.cts.map +1 -0
  60. package/dist/core/commands/index.d.mts +24 -0
  61. package/dist/core/commands/index.d.mts.map +1 -0
  62. package/dist/core/commands/index.mjs +37 -0
  63. package/dist/core/commands/index.mjs.map +1 -0
  64. package/dist/core/commands/ls.cjs +57 -0
  65. package/dist/core/commands/ls.d.cts +21 -0
  66. package/dist/core/commands/ls.d.cts.map +1 -0
  67. package/dist/core/commands/ls.d.mts +21 -0
  68. package/dist/core/commands/ls.d.mts.map +1 -0
  69. package/dist/core/commands/ls.mjs +58 -0
  70. package/dist/core/commands/ls.mjs.map +1 -0
  71. package/dist/core/commands/mount.cjs +222 -0
  72. package/dist/core/commands/mount.d.cts +35 -0
  73. package/dist/core/commands/mount.d.cts.map +1 -0
  74. package/dist/core/commands/mount.d.mts +35 -0
  75. package/dist/core/commands/mount.d.mts.map +1 -0
  76. package/dist/core/commands/mount.mjs +223 -0
  77. package/dist/core/commands/mount.mjs.map +1 -0
  78. package/dist/core/commands/read.cjs +48 -0
  79. package/dist/core/commands/read.d.cts +17 -0
  80. package/dist/core/commands/read.d.cts.map +1 -0
  81. package/dist/core/commands/read.d.mts +17 -0
  82. package/dist/core/commands/read.d.mts.map +1 -0
  83. package/dist/core/commands/read.mjs +49 -0
  84. package/dist/core/commands/read.mjs.map +1 -0
  85. package/dist/core/commands/search.cjs +40 -0
  86. package/dist/core/commands/search.d.mts +2 -0
  87. package/dist/core/commands/search.mjs +41 -0
  88. package/dist/core/commands/search.mjs.map +1 -0
  89. package/dist/core/commands/serve.cjs +267 -0
  90. package/dist/core/commands/serve.d.mts +2 -0
  91. package/dist/core/commands/serve.mjs +267 -0
  92. package/dist/core/commands/serve.mjs.map +1 -0
  93. package/dist/core/commands/stat.cjs +53 -0
  94. package/dist/core/commands/stat.d.cts +17 -0
  95. package/dist/core/commands/stat.d.cts.map +1 -0
  96. package/dist/core/commands/stat.d.mts +17 -0
  97. package/dist/core/commands/stat.d.mts.map +1 -0
  98. package/dist/core/commands/stat.mjs +54 -0
  99. package/dist/core/commands/stat.mjs.map +1 -0
  100. package/dist/core/commands/types.cjs +18 -0
  101. package/dist/core/commands/types.d.cts +54 -0
  102. package/dist/core/commands/types.d.cts.map +1 -0
  103. package/dist/core/commands/types.d.mts +54 -0
  104. package/dist/core/commands/types.d.mts.map +1 -0
  105. package/dist/core/commands/types.mjs +19 -0
  106. package/dist/core/commands/types.mjs.map +1 -0
  107. package/dist/core/commands/write.cjs +70 -0
  108. package/dist/core/commands/write.d.cts +20 -0
  109. package/dist/core/commands/write.d.cts.map +1 -0
  110. package/dist/core/commands/write.d.mts +20 -0
  111. package/dist/core/commands/write.d.mts.map +1 -0
  112. package/dist/core/commands/write.mjs +71 -0
  113. package/dist/core/commands/write.mjs.map +1 -0
  114. package/dist/core/executor/index.cjs +196 -0
  115. package/dist/core/executor/index.d.cts +77 -0
  116. package/dist/core/executor/index.d.cts.map +1 -0
  117. package/dist/core/executor/index.d.mts +77 -0
  118. package/dist/core/executor/index.d.mts.map +1 -0
  119. package/dist/core/executor/index.mjs +195 -0
  120. package/dist/core/executor/index.mjs.map +1 -0
  121. package/dist/core/formatters/delete.cjs +37 -0
  122. package/dist/core/formatters/delete.d.cts +18 -0
  123. package/dist/core/formatters/delete.d.cts.map +1 -0
  124. package/dist/core/formatters/delete.d.mts +18 -0
  125. package/dist/core/formatters/delete.d.mts.map +1 -0
  126. package/dist/core/formatters/delete.mjs +37 -0
  127. package/dist/core/formatters/delete.mjs.map +1 -0
  128. package/dist/core/formatters/exec.cjs +60 -0
  129. package/dist/core/formatters/exec.d.cts +18 -0
  130. package/dist/core/formatters/exec.d.cts.map +1 -0
  131. package/dist/core/formatters/exec.d.mts +18 -0
  132. package/dist/core/formatters/exec.d.mts.map +1 -0
  133. package/dist/core/formatters/exec.mjs +60 -0
  134. package/dist/core/formatters/exec.mjs.map +1 -0
  135. package/dist/core/formatters/explain.cjs +99 -0
  136. package/dist/core/formatters/explain.d.cts +11 -0
  137. package/dist/core/formatters/explain.d.cts.map +1 -0
  138. package/dist/core/formatters/explain.d.mts +11 -0
  139. package/dist/core/formatters/explain.d.mts.map +1 -0
  140. package/dist/core/formatters/explain.mjs +98 -0
  141. package/dist/core/formatters/explain.mjs.map +1 -0
  142. package/dist/core/formatters/index.d.mts +9 -0
  143. package/dist/core/formatters/ls.cjs +179 -0
  144. package/dist/core/formatters/ls.d.cts +20 -0
  145. package/dist/core/formatters/ls.d.cts.map +1 -0
  146. package/dist/core/formatters/ls.d.mts +20 -0
  147. package/dist/core/formatters/ls.d.mts.map +1 -0
  148. package/dist/core/formatters/ls.mjs +179 -0
  149. package/dist/core/formatters/ls.mjs.map +1 -0
  150. package/dist/core/formatters/mount.cjs +55 -0
  151. package/dist/core/formatters/mount.d.cts +15 -0
  152. package/dist/core/formatters/mount.d.cts.map +1 -0
  153. package/dist/core/formatters/mount.d.mts +15 -0
  154. package/dist/core/formatters/mount.d.mts.map +1 -0
  155. package/dist/core/formatters/mount.mjs +55 -0
  156. package/dist/core/formatters/mount.mjs.map +1 -0
  157. package/dist/core/formatters/read.cjs +100 -0
  158. package/dist/core/formatters/read.d.cts +22 -0
  159. package/dist/core/formatters/read.d.cts.map +1 -0
  160. package/dist/core/formatters/read.d.mts +22 -0
  161. package/dist/core/formatters/read.d.mts.map +1 -0
  162. package/dist/core/formatters/read.mjs +100 -0
  163. package/dist/core/formatters/read.mjs.map +1 -0
  164. package/dist/core/formatters/search.cjs +44 -0
  165. package/dist/core/formatters/search.d.mts +1 -0
  166. package/dist/core/formatters/search.mjs +44 -0
  167. package/dist/core/formatters/search.mjs.map +1 -0
  168. package/dist/core/formatters/stat.cjs +155 -0
  169. package/dist/core/formatters/stat.d.cts +15 -0
  170. package/dist/core/formatters/stat.d.cts.map +1 -0
  171. package/dist/core/formatters/stat.d.mts +15 -0
  172. package/dist/core/formatters/stat.d.mts.map +1 -0
  173. package/dist/core/formatters/stat.mjs +155 -0
  174. package/dist/core/formatters/stat.mjs.map +1 -0
  175. package/dist/core/formatters/write.cjs +51 -0
  176. package/dist/core/formatters/write.d.cts +22 -0
  177. package/dist/core/formatters/write.d.cts.map +1 -0
  178. package/dist/core/formatters/write.d.mts +22 -0
  179. package/dist/core/formatters/write.d.mts.map +1 -0
  180. package/dist/core/formatters/write.mjs +51 -0
  181. package/dist/core/formatters/write.mjs.map +1 -0
  182. package/dist/core/helpers/exec-args.cjs +142 -0
  183. package/dist/core/helpers/exec-args.d.cts +46 -0
  184. package/dist/core/helpers/exec-args.d.cts.map +1 -0
  185. package/dist/core/helpers/exec-args.d.mts +46 -0
  186. package/dist/core/helpers/exec-args.d.mts.map +1 -0
  187. package/dist/core/helpers/exec-args.mjs +139 -0
  188. package/dist/core/helpers/exec-args.mjs.map +1 -0
  189. package/dist/core/helpers/stdin.cjs +41 -0
  190. package/dist/core/helpers/stdin.d.cts +15 -0
  191. package/dist/core/helpers/stdin.d.cts.map +1 -0
  192. package/dist/core/helpers/stdin.d.mts +15 -0
  193. package/dist/core/helpers/stdin.d.mts.map +1 -0
  194. package/dist/core/helpers/stdin.mjs +41 -0
  195. package/dist/core/helpers/stdin.mjs.map +1 -0
  196. package/dist/core/index.cjs +49 -0
  197. package/dist/core/index.d.cts +24 -0
  198. package/dist/core/index.d.mts +25 -0
  199. package/dist/core/index.mjs +24 -0
  200. package/dist/core/path-utils.cjs +1 -0
  201. package/dist/core/path-utils.mjs +3 -0
  202. package/dist/core/types.d.cts +24 -0
  203. package/dist/core/types.d.cts.map +1 -0
  204. package/dist/core/types.d.mts +24 -0
  205. package/dist/core/types.d.mts.map +1 -0
  206. package/dist/credential/auth-server.cjs +247 -0
  207. package/dist/credential/auth-server.mjs +247 -0
  208. package/dist/credential/auth-server.mjs.map +1 -0
  209. package/dist/credential/cli-auth-context.cjs +86 -0
  210. package/dist/credential/cli-auth-context.d.mts +1 -0
  211. package/dist/credential/cli-auth-context.mjs +86 -0
  212. package/dist/credential/cli-auth-context.mjs.map +1 -0
  213. package/dist/credential/index.cjs +5 -0
  214. package/dist/credential/index.d.mts +4 -0
  215. package/dist/credential/index.mjs +7 -0
  216. package/dist/credential/mcp-auth-context.cjs +192 -0
  217. package/dist/credential/mcp-auth-context.d.mts +1 -0
  218. package/dist/credential/mcp-auth-context.mjs +192 -0
  219. package/dist/credential/mcp-auth-context.mjs.map +1 -0
  220. package/dist/credential/resolver.cjs +127 -0
  221. package/dist/credential/resolver.d.mts +1 -0
  222. package/dist/credential/resolver.mjs +127 -0
  223. package/dist/credential/resolver.mjs.map +1 -0
  224. package/dist/credential/store.cjs +106 -0
  225. package/dist/credential/store.d.cts +30 -0
  226. package/dist/credential/store.d.cts.map +1 -0
  227. package/dist/credential/store.d.mts +30 -0
  228. package/dist/credential/store.d.mts.map +1 -0
  229. package/dist/credential/store.mjs +106 -0
  230. package/dist/credential/store.mjs.map +1 -0
  231. package/dist/errors.cjs +18 -0
  232. package/dist/errors.mjs +18 -0
  233. package/dist/errors.mjs.map +1 -0
  234. package/dist/explorer/actions.cjs +311 -0
  235. package/dist/explorer/actions.mjs +305 -0
  236. package/dist/explorer/actions.mjs.map +1 -0
  237. package/dist/explorer/components/dialog.cjs +508 -0
  238. package/dist/explorer/components/dialog.mjs +509 -0
  239. package/dist/explorer/components/dialog.mjs.map +1 -0
  240. package/dist/explorer/components/file-list.cjs +107 -0
  241. package/dist/explorer/components/file-list.mjs +107 -0
  242. package/dist/explorer/components/file-list.mjs.map +1 -0
  243. package/dist/explorer/components/function-bar.cjs +55 -0
  244. package/dist/explorer/components/function-bar.mjs +55 -0
  245. package/dist/explorer/components/function-bar.mjs.map +1 -0
  246. package/dist/explorer/components/index.cjs +5 -0
  247. package/dist/explorer/components/index.mjs +7 -0
  248. package/dist/explorer/components/metadata-panel.cjs +219 -0
  249. package/dist/explorer/components/metadata-panel.mjs +219 -0
  250. package/dist/explorer/components/metadata-panel.mjs.map +1 -0
  251. package/dist/explorer/components/status-bar.cjs +53 -0
  252. package/dist/explorer/components/status-bar.mjs +54 -0
  253. package/dist/explorer/components/status-bar.mjs.map +1 -0
  254. package/dist/explorer/keybindings.cjs +214 -0
  255. package/dist/explorer/keybindings.mjs +213 -0
  256. package/dist/explorer/keybindings.mjs.map +1 -0
  257. package/dist/explorer/screen.cjs +251 -0
  258. package/dist/explorer/screen.d.cts +23 -0
  259. package/dist/explorer/screen.d.cts.map +1 -0
  260. package/dist/explorer/screen.d.mts +23 -0
  261. package/dist/explorer/screen.d.mts.map +1 -0
  262. package/dist/explorer/screen.mjs +250 -0
  263. package/dist/explorer/screen.mjs.map +1 -0
  264. package/dist/explorer/state.cjs +53 -0
  265. package/dist/explorer/state.mjs +53 -0
  266. package/dist/explorer/state.mjs.map +1 -0
  267. package/dist/explorer/theme.cjs +160 -0
  268. package/dist/explorer/theme.mjs +157 -0
  269. package/dist/explorer/theme.mjs.map +1 -0
  270. package/dist/index.cjs +12 -0
  271. package/dist/index.d.cts +6 -0
  272. package/dist/index.d.mts +7 -4
  273. package/dist/index.mjs +7 -2
  274. package/dist/mcp/http-transport.cjs +87 -0
  275. package/dist/mcp/http-transport.mjs +87 -0
  276. package/dist/mcp/http-transport.mjs.map +1 -0
  277. package/dist/mcp/prompts.cjs +48 -0
  278. package/dist/mcp/prompts.mjs +48 -0
  279. package/dist/mcp/prompts.mjs.map +1 -0
  280. package/dist/mcp/resources.cjs +25 -0
  281. package/dist/mcp/resources.mjs +25 -0
  282. package/dist/mcp/resources.mjs.map +1 -0
  283. package/dist/mcp/server.cjs +74 -0
  284. package/dist/mcp/server.mjs +73 -0
  285. package/dist/mcp/server.mjs.map +1 -0
  286. package/dist/mcp/tools.cjs +152 -0
  287. package/dist/mcp/tools.mjs +152 -0
  288. package/dist/mcp/tools.mjs.map +1 -0
  289. package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/index.d.cts +10 -0
  290. package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/index.d.cts.map +1 -0
  291. package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/index.d.mts +10 -0
  292. package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/index.d.mts.map +1 -0
  293. package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/types.d.cts +46 -0
  294. package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/types.d.cts.map +1 -0
  295. package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/types.d.mts +46 -0
  296. package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/types.d.mts.map +1 -0
  297. package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/urlpattern.cjs +902 -0
  298. package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/urlpattern.mjs +902 -0
  299. package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/urlpattern.mjs.map +1 -0
  300. package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/index.cjs +6 -0
  301. package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/index.mjs +8 -0
  302. package/dist/node_modules/.pnpm/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/index.mjs.map +1 -0
  303. package/dist/path-utils.cjs +105 -0
  304. package/dist/path-utils.d.cts +50 -0
  305. package/dist/path-utils.d.cts.map +1 -0
  306. package/dist/path-utils.d.mts +50 -0
  307. package/dist/path-utils.d.mts.map +1 -0
  308. package/dist/path-utils.mjs +104 -0
  309. package/dist/path-utils.mjs.map +1 -0
  310. package/dist/repl.cjs +491 -0
  311. package/dist/repl.d.cts +15 -0
  312. package/dist/repl.d.cts.map +1 -0
  313. package/dist/repl.d.mts +16 -0
  314. package/dist/repl.d.mts.map +1 -0
  315. package/dist/repl.mjs +491 -0
  316. package/dist/repl.mjs.map +1 -0
  317. package/dist/serve.cjs +146 -0
  318. package/dist/serve.d.cts +41 -0
  319. package/dist/serve.d.cts.map +1 -0
  320. package/dist/serve.d.mts +41 -0
  321. package/dist/serve.d.mts.map +1 -0
  322. package/dist/serve.mjs +146 -0
  323. package/dist/serve.mjs.map +1 -0
  324. package/dist/ui/header.cjs +12 -0
  325. package/dist/ui/header.mjs +13 -0
  326. package/dist/ui/header.mjs.map +1 -0
  327. package/dist/ui/index.cjs +8 -0
  328. package/dist/ui/index.mjs +9 -0
  329. package/dist/ui/index.mjs.map +1 -0
  330. package/dist/ui/terminal.cjs +88 -0
  331. package/dist/ui/terminal.mjs +88 -0
  332. package/dist/ui/terminal.mjs.map +1 -0
  333. package/dist/version.cjs +9 -0
  334. package/dist/version.d.cts +5 -0
  335. package/dist/version.d.cts.map +1 -0
  336. package/dist/version.d.mts +5 -0
  337. package/dist/version.d.mts.map +1 -0
  338. package/dist/version.mjs +9 -0
  339. package/dist/version.mjs.map +1 -0
  340. package/package.json +77 -11
  341. package/.turbo/turbo-build.log +0 -18
  342. package/.turbo/turbo-check-types.log +0 -4
  343. package/dist/version--p6A8sKX.mjs +0 -5
  344. package/src/cli.test.ts +0 -8
  345. package/src/cli.ts +0 -29
  346. package/src/index.ts +0 -7
  347. package/src/version.ts +0 -1
  348. package/tsconfig.json +0 -16
package/dist/repl.mjs ADDED
@@ -0,0 +1,491 @@
1
+ import { createCLIAuthContext } from "./credential/cli-auth-context.mjs";
2
+ import { createCredentialStore } from "./credential/store.mjs";
3
+ import { loadAFS } from "./config/afs-loader.mjs";
4
+ import { AFSCommandExecutor } from "./core/executor/index.mjs";
5
+ import { basename } from "node:path";
6
+ import { createInterface } from "node:readline";
7
+ import { joinURL } from "ufo";
8
+
9
+ //#region src/repl.ts
10
+ /**
11
+ * AFS CLI Interactive REPL
12
+ *
13
+ * Single-file REPL implementation for `afs -i` / `afs --interactive`.
14
+ * Provides: REPL loop, cd/pwd, Tab completion, explore TUI integration.
15
+ */
16
+ /** Commands that default to current path when no path argument is given in REPL */
17
+ const DEFAULT_PATH_COMMANDS = new Set([
18
+ "ls",
19
+ "read",
20
+ "stat",
21
+ "explain",
22
+ "explore"
23
+ ]);
24
+ const ALL_COMMANDS = [
25
+ "ls",
26
+ "read",
27
+ "write",
28
+ "delete",
29
+ "stat",
30
+ "exec",
31
+ "explain",
32
+ "mount",
33
+ "explore",
34
+ "cd",
35
+ "pwd",
36
+ "help",
37
+ "exit"
38
+ ];
39
+ function createReplContext(options) {
40
+ return {
41
+ executor: options.executor,
42
+ afs: options.afs,
43
+ version: options.version,
44
+ currentPath: "/",
45
+ currentNamespace: null,
46
+ completionCache: /* @__PURE__ */ new Map()
47
+ };
48
+ }
49
+ function getPrompt(ctx) {
50
+ const dirname$1 = ctx.currentPath === "/" ? "/" : basename(ctx.currentPath);
51
+ return `afs ${ctx.currentNamespace ? `${ctx.currentNamespace}:` : ""}${dirname$1}> `;
52
+ }
53
+ function getBanner(ctx) {
54
+ const mountCount = ctx.afs.getMounts().length;
55
+ const plural = mountCount === 1 ? "provider" : "providers";
56
+ return `AFS Interactive Shell v${ctx.version} — ${mountCount} ${plural} mounted. Type "help" for commands.`;
57
+ }
58
+ async function handleBuiltinCommand(input, ctx) {
59
+ const trimmed = input.trim();
60
+ if (!trimmed) return null;
61
+ const parts = trimmed.split(/\s+/);
62
+ switch (parts[0]) {
63
+ case "exit":
64
+ case "quit": return {
65
+ exit: true,
66
+ output: "Bye!"
67
+ };
68
+ case "help": return { output: formatHelp() };
69
+ case "pwd": return handlePwd(ctx);
70
+ case "cd": return handleCd(parts.slice(1).join(" "), ctx);
71
+ default: return null;
72
+ }
73
+ }
74
+ function formatHelp() {
75
+ return [
76
+ "Available commands:",
77
+ "",
78
+ " AFS Commands:",
79
+ " ls [path] List directory contents (default: current dir)",
80
+ " read [path] Read file content (default: current node)",
81
+ " write <path> [content] Write content to file",
82
+ " delete <path> Delete file or directory",
83
+ " stat [path] Get file or directory info (default: current node)",
84
+ " exec <action> Execute an action",
85
+ " explain [topic] Explain AFS concepts or paths (default: current path)",
86
+ " mount Mount management",
87
+ " explore [path] Interactive TUI explorer (default: current dir)",
88
+ "",
89
+ " REPL Commands:",
90
+ " cd [path] Change working directory",
91
+ " pwd Print working directory",
92
+ " help Show this help",
93
+ " exit / quit Exit REPL",
94
+ "",
95
+ " Tips:",
96
+ " - Commands work with or without 'afs' prefix",
97
+ " - Use Tab for command and path completion",
98
+ " - Ctrl+D to exit"
99
+ ].join("\n");
100
+ }
101
+ function handlePwd(ctx) {
102
+ if (ctx.currentNamespace) return { output: `@${ctx.currentNamespace}${ctx.currentPath}` };
103
+ return { output: ctx.currentPath };
104
+ }
105
+ async function handleCd(target, ctx) {
106
+ if (!target || target.trim() === "") {
107
+ ctx.currentPath = "/";
108
+ return {};
109
+ }
110
+ const trimmed = target.trim();
111
+ if (trimmed === "@default") {
112
+ ctx.currentNamespace = null;
113
+ ctx.currentPath = "/";
114
+ return {};
115
+ }
116
+ if (trimmed.startsWith("@")) {
117
+ const rest = trimmed.slice(1);
118
+ const slashIdx = rest.indexOf("/");
119
+ if (slashIdx === -1) {
120
+ const ns$1 = rest;
121
+ if (!ns$1) return { output: "cd: invalid namespace" };
122
+ try {
123
+ const canonicalPath = `$afs:${ns$1}/`;
124
+ await ctx.afs.stat(canonicalPath);
125
+ ctx.currentNamespace = ns$1;
126
+ ctx.currentPath = "/";
127
+ return {};
128
+ } catch {
129
+ return { output: `cd: no such path: @${ns$1}/` };
130
+ }
131
+ }
132
+ const ns = rest.slice(0, slashIdx);
133
+ const path = rest.slice(slashIdx) || "/";
134
+ if (!ns) return { output: "cd: invalid namespace" };
135
+ try {
136
+ const canonicalPath = `$afs:${ns}${path}`;
137
+ await ctx.afs.stat(canonicalPath);
138
+ ctx.currentNamespace = ns;
139
+ ctx.currentPath = path;
140
+ return {};
141
+ } catch {
142
+ return { output: `cd: no such path: @${ns}${path}` };
143
+ }
144
+ }
145
+ if (trimmed.startsWith("/")) {
146
+ const resolved$1 = normalizePath(trimmed);
147
+ try {
148
+ const canonicalPath = ctx.currentNamespace ? `$afs:${ctx.currentNamespace}${resolved$1}` : resolved$1;
149
+ await ctx.afs.stat(canonicalPath);
150
+ ctx.currentPath = resolved$1;
151
+ return {};
152
+ } catch {
153
+ return { output: `cd: no such path: ${trimmed}` };
154
+ }
155
+ }
156
+ const resolved = normalizePath(joinURL(ctx.currentPath, trimmed));
157
+ try {
158
+ const canonicalPath = ctx.currentNamespace ? `$afs:${ctx.currentNamespace}${resolved}` : resolved;
159
+ await ctx.afs.stat(canonicalPath);
160
+ ctx.currentPath = resolved;
161
+ return {};
162
+ } catch {
163
+ return { output: `cd: no such path: ${trimmed}` };
164
+ }
165
+ }
166
+ function normalizePath(path) {
167
+ const parts = path.split("/").filter(Boolean);
168
+ const resolved = [];
169
+ for (const part of parts) if (part === "..") resolved.pop();
170
+ else if (part !== ".") resolved.push(part);
171
+ return `/${resolved.join("/")}`;
172
+ }
173
+ function resolveArgvPath(input, ctx) {
174
+ const tokens = tokenize(input);
175
+ if (tokens.length === 0) return tokens;
176
+ let cmdIdx = 0;
177
+ if (tokens[0] === "afs" && tokens.length > 1) cmdIdx = 1;
178
+ const cmd = tokens[cmdIdx];
179
+ if (!cmd) return tokens;
180
+ let argIdx = -1;
181
+ for (let i = cmdIdx + 1; i < tokens.length; i++) {
182
+ const token = tokens[i];
183
+ if (!token.startsWith("-")) {
184
+ if (cmd === "mount" && (token === "list" || token === "ls" || token === "add" || token === "remove")) continue;
185
+ argIdx = i;
186
+ break;
187
+ }
188
+ if (token.startsWith("--") && !token.includes("=") && i + 1 < tokens.length) i++;
189
+ }
190
+ if (argIdx === -1) {
191
+ if (DEFAULT_PATH_COMMANDS.has(cmd)) {
192
+ const currentFullPath = ctx.currentNamespace ? `@${ctx.currentNamespace}${ctx.currentPath}` : ctx.currentPath;
193
+ tokens.push(currentFullPath);
194
+ }
195
+ return tokens;
196
+ }
197
+ const arg = tokens[argIdx];
198
+ if (arg.startsWith("/") || arg.startsWith("@") || arg.startsWith("$afs")) return tokens;
199
+ const resolved = normalizePath(joinURL(ctx.currentPath, arg));
200
+ tokens[argIdx] = ctx.currentNamespace ? `@${ctx.currentNamespace}${resolved}` : resolved;
201
+ return tokens;
202
+ }
203
+ function tokenize(input) {
204
+ const tokens = [];
205
+ let current = "";
206
+ let inQuote = false;
207
+ let quoteChar = "";
208
+ for (let i = 0; i < input.length; i++) {
209
+ const char = input[i];
210
+ if (inQuote) if (char === quoteChar) inQuote = false;
211
+ else current += char;
212
+ else if (char === "\"" || char === "'") {
213
+ inQuote = true;
214
+ quoteChar = char;
215
+ } else if (char === " " || char === " ") {
216
+ if (current) {
217
+ tokens.push(current);
218
+ current = "";
219
+ }
220
+ } else current += char;
221
+ }
222
+ if (current) tokens.push(current);
223
+ return tokens;
224
+ }
225
+ function isExploreCommand(cmd) {
226
+ const normalized = cmd.replace(/^afs\s+/, "").trim();
227
+ return normalized === "explore" || normalized.startsWith("explore ");
228
+ }
229
+ function parseExplorePath(cmd, ctx) {
230
+ const path = cmd.replace(/^afs\s+/, "").trim().split(/\s+/)[1];
231
+ if (!path) {
232
+ if (ctx.currentNamespace) return `$afs:${ctx.currentNamespace}${ctx.currentPath}`;
233
+ return ctx.currentPath;
234
+ }
235
+ if (!path.startsWith("/") && !path.startsWith("@") && !path.startsWith("$afs")) {
236
+ const resolved = normalizePath(joinURL(ctx.currentPath, path));
237
+ if (ctx.currentNamespace) return `$afs:${ctx.currentNamespace}${resolved}`;
238
+ return resolved;
239
+ }
240
+ return path;
241
+ }
242
+ function createCompleter(ctx) {
243
+ return function completer(line, callback) {
244
+ const tokens = line.trimStart().split(/\s+/);
245
+ if (tokens.length <= 1) {
246
+ const partial = tokens[0] || "";
247
+ callback(null, [ALL_COMMANDS.filter((c) => c.startsWith(partial)), partial]);
248
+ return;
249
+ }
250
+ const lastToken = tokens[tokens.length - 1];
251
+ if (lastToken.startsWith("-")) {
252
+ callback(null, [[], lastToken]);
253
+ return;
254
+ }
255
+ let parentDir;
256
+ let prefix;
257
+ if (lastToken.includes("/")) {
258
+ const lastSlash = lastToken.lastIndexOf("/");
259
+ const parentPart = lastToken.slice(0, lastSlash + 1) || "/";
260
+ prefix = lastToken.slice(lastSlash + 1);
261
+ if (parentPart.startsWith("/") || parentPart.startsWith("@") || parentPart.startsWith("$afs")) parentDir = parentPart;
262
+ else parentDir = joinURL(ctx.currentPath, parentPart);
263
+ } else {
264
+ parentDir = ctx.currentPath;
265
+ prefix = lastToken;
266
+ }
267
+ const queryPath = ctx.currentNamespace && !parentDir.startsWith("@") && !parentDir.startsWith("$afs") ? `$afs:${ctx.currentNamespace}${parentDir}` : parentDir;
268
+ const cacheKey = queryPath;
269
+ const cached = ctx.completionCache.get(cacheKey);
270
+ if (cached) {
271
+ callback(null, [buildCompletions(cached, prefix, lastToken), lastToken]);
272
+ return;
273
+ }
274
+ ctx.afs.list(queryPath).then((result) => {
275
+ const entries = result.data || [];
276
+ ctx.completionCache.set(cacheKey, entries);
277
+ callback(null, [buildCompletions(entries, prefix, lastToken), lastToken]);
278
+ }).catch(() => {
279
+ callback(null, [[], lastToken]);
280
+ });
281
+ };
282
+ }
283
+ function buildCompletions(entries, prefix, lastToken) {
284
+ return entries.filter((e) => {
285
+ return basename(e.path).startsWith(prefix);
286
+ }).map((e) => {
287
+ const name = basename(e.path);
288
+ const suffix = typeof e.meta?.childrenCount === "number" ? "/" : " ";
289
+ if (lastToken.includes("/")) {
290
+ const lastSlash = lastToken.lastIndexOf("/");
291
+ return lastToken.slice(0, lastSlash + 1) + name + suffix;
292
+ }
293
+ return name + suffix;
294
+ });
295
+ }
296
+ function cleanupStdinAfterBlessed() {
297
+ const stdin = process.stdin;
298
+ stdin.removeAllListeners("keypress");
299
+ stdin.removeAllListeners("data");
300
+ delete stdin._blessedInput;
301
+ delete stdin._keypressHandler;
302
+ delete stdin._dataHandler;
303
+ delete stdin._keypressDecoder;
304
+ delete stdin._kpiListener;
305
+ if (stdin.setRawMode) stdin.setRawMode(false);
306
+ if (stdin._readableState) {
307
+ stdin._readableState.flowing = null;
308
+ stdin._readableState.reading = false;
309
+ }
310
+ }
311
+ const SPINNER_FRAMES = [
312
+ "⠋",
313
+ "⠙",
314
+ "⠹",
315
+ "⠸",
316
+ "⠼",
317
+ "⠴",
318
+ "⠦",
319
+ "⠧",
320
+ "⠇",
321
+ "⠏"
322
+ ];
323
+ const SPINNER_INTERVAL_MS = 80;
324
+ function createSpinner() {
325
+ let frameIdx = 0;
326
+ let text = "";
327
+ let timer = null;
328
+ return {
329
+ start(initialText) {
330
+ text = initialText;
331
+ timer = setInterval(() => {
332
+ const frame = SPINNER_FRAMES[frameIdx % SPINNER_FRAMES.length];
333
+ process.stderr.write(`\r${frame} ${text}`);
334
+ frameIdx++;
335
+ }, SPINNER_INTERVAL_MS);
336
+ },
337
+ update(newText) {
338
+ text = newText;
339
+ },
340
+ stop() {
341
+ if (timer) {
342
+ clearInterval(timer);
343
+ timer = null;
344
+ }
345
+ process.stderr.write("\r\x1B[K");
346
+ }
347
+ };
348
+ }
349
+ async function startRepl(options) {
350
+ const { cwd, version, onExit, extraProviders } = options;
351
+ const spinner = createSpinner();
352
+ spinner.start("Mounting providers...");
353
+ let failures = [];
354
+ const { afs, failures: mountFailures } = await loadAFS(cwd, {
355
+ authContext: createCLIAuthContext(),
356
+ credentialStore: createCredentialStore(),
357
+ onProgress({ total, completed, failed }) {
358
+ spinner.update(`Mounting providers... (${completed}/${total}${failed > 0 ? `, ${failed} failed` : ""})`);
359
+ }
360
+ });
361
+ failures = mountFailures;
362
+ if (extraProviders) for (const { provider, mountPath } of extraProviders) try {
363
+ await afs.mount(provider, mountPath);
364
+ } catch (e) {
365
+ const msg = e instanceof Error ? e.message : String(e);
366
+ failures.push({
367
+ path: mountPath,
368
+ reason: msg
369
+ });
370
+ }
371
+ spinner.stop();
372
+ if (failures.length > 0) {
373
+ const noun = failures.length === 1 ? "mount" : "mounts";
374
+ console.warn(`⚠ ${failures.length} ${noun} failed:`);
375
+ for (const f of failures) console.warn(` - ${f.path}: ${f.reason}`);
376
+ }
377
+ const executor = new AFSCommandExecutor(afs, {
378
+ cwd,
379
+ tty: true,
380
+ version
381
+ });
382
+ const ctx = createReplContext({
383
+ executor,
384
+ afs,
385
+ version
386
+ });
387
+ console.log(getBanner(ctx));
388
+ let closed = false;
389
+ let rl;
390
+ let originalDataHandler = null;
391
+ function startReplLoop() {
392
+ const stdin = process.stdin;
393
+ if (stdin._readableState) {
394
+ stdin._readableState.flowing = null;
395
+ stdin._readableState.reading = false;
396
+ }
397
+ rl = createInterface({
398
+ input: process.stdin,
399
+ output: process.stdout,
400
+ prompt: getPrompt(ctx),
401
+ historySize: 100,
402
+ completer: createCompleter(ctx)
403
+ });
404
+ if (!originalDataHandler && stdin.listenerCount("data") > 0) originalDataHandler = stdin.listeners("data")[0] ?? null;
405
+ if (stdin.listenerCount("data") === 0 && originalDataHandler) {
406
+ stdin.on("data", originalDataHandler);
407
+ stdin.resume();
408
+ }
409
+ rl.on("line", async (line) => {
410
+ const trimmed = line.trim();
411
+ if (!trimmed) {
412
+ if (!closed) rl.prompt();
413
+ return;
414
+ }
415
+ if (isExploreCommand(trimmed)) {
416
+ await handleExplore(trimmed, ctx);
417
+ return;
418
+ }
419
+ const builtinResult = await handleBuiltinCommand(trimmed, ctx);
420
+ if (builtinResult) {
421
+ if (builtinResult.output) console.log(builtinResult.output);
422
+ if (builtinResult.exit) {
423
+ closed = true;
424
+ rl.close();
425
+ return;
426
+ }
427
+ if (!closed) {
428
+ rl.setPrompt(getPrompt(ctx));
429
+ rl.prompt();
430
+ }
431
+ return;
432
+ }
433
+ const resolved = resolveArgvPath(trimmed, ctx);
434
+ try {
435
+ const result = await executor.execute(resolved);
436
+ if (result.formatted) console.log(result.formatted);
437
+ if (!result.success && result.error) {
438
+ if (!result.formatted.includes(result.error.message)) console.error(result.error.message);
439
+ }
440
+ } catch (e) {
441
+ const msg = e instanceof Error ? e.message : String(e);
442
+ console.error(`Error: ${msg}`);
443
+ }
444
+ ctx.completionCache.clear();
445
+ if (!closed) rl.prompt();
446
+ });
447
+ rl.on("close", () => {
448
+ if (!closed) {
449
+ closed = true;
450
+ console.log("\nBye!");
451
+ }
452
+ });
453
+ rl.prompt();
454
+ }
455
+ async function handleExplore(trimmed, ctx$1) {
456
+ rl.removeAllListeners("line");
457
+ rl.removeAllListeners("close");
458
+ rl.close();
459
+ cleanupStdinAfterBlessed();
460
+ try {
461
+ const { createExplorerScreen } = await import("./explorer/screen.mjs");
462
+ const startPath = parseExplorePath(trimmed, ctx$1);
463
+ await createExplorerScreen({
464
+ afs: ctx$1.afs,
465
+ startPath,
466
+ version: ctx$1.version,
467
+ onExit: () => {}
468
+ });
469
+ } catch {}
470
+ await new Promise((resolve$1) => setTimeout(resolve$1, 100));
471
+ cleanupStdinAfterBlessed();
472
+ process.stdout.write("\x1B[?1049l");
473
+ process.stdout.write("\x1B[?25h");
474
+ console.log("");
475
+ if (!closed) startReplLoop();
476
+ }
477
+ startReplLoop();
478
+ return new Promise((resolve$1) => {
479
+ const checkClosed = setInterval(() => {
480
+ if (closed) {
481
+ clearInterval(checkClosed);
482
+ if (onExit) onExit().catch(() => {}).then(resolve$1);
483
+ else resolve$1();
484
+ }
485
+ }, 100);
486
+ });
487
+ }
488
+
489
+ //#endregion
490
+ export { startRepl };
491
+ //# sourceMappingURL=repl.mjs.map
@@ -0,0 +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 \"mount\",\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 \" mount Mount 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\nfunction parseExplorePath(cmd: string, ctx: ReplContext): string {\n const normalized = cmd.replace(/^afs\\s+/, \"\").trim();\n const parts = normalized.split(/\\s+/);\n const path = parts[1];\n if (!path) {\n // Use current working directory\n if (ctx.currentNamespace) {\n return `$afs:${ctx.currentNamespace}${ctx.currentPath}`;\n }\n return ctx.currentPath;\n }\n // If relative path, resolve it\n if (!path.startsWith(\"/\") && !path.startsWith(\"@\") && !path.startsWith(\"$afs\")) {\n const resolved = normalizePath(joinURL(ctx.currentPath, path));\n if (ctx.currentNamespace) {\n return `$afs:${ctx.currentNamespace}${resolved}`;\n }\n return resolved;\n }\n return path;\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 // 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\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 console.log(\"\\nBye!\");\n }\n });\n\n rl.prompt();\n }\n\n async function handleExplore(trimmed: string, ctx: ReplContext) {\n // Remove listeners before close\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 const startPath = parseExplorePath(trimmed, ctx);\n await createExplorerScreen({\n afs: ctx.afs,\n startPath,\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 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 if (onExit) {\n onExit()\n .catch(() => {})\n .then(resolve);\n } else {\n resolve();\n }\n }\n }, 100);\n });\n}\n"],"mappings":"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"}