11import type { ExtensionAPI } from "@mariozechner/pi-coding-agent" ;
2- import { writeFile } from "node:fs/promises" ;
3- import { join } from "node:path" ;
2+ import type { AutocompleteItem } from "@mariozechner/pi-tui" ;
3+ import { writeFile , readdir , stat } from "node:fs/promises" ;
4+ import { join , isAbsolute , dirname , basename } from "node:path" ;
5+ import { homedir } from "node:os" ;
46
57export default function ( pi : ExtensionAPI ) {
8+ const getFileCompletions = async ( prefix : string ) : Promise < AutocompleteItem [ ] | null > => {
9+ try {
10+ // Resolve the directory and file prefix
11+ let dir = "" ;
12+ let filePrefix = prefix ;
13+
14+ if ( prefix . includes ( "/" ) ) {
15+ dir = dirname ( prefix ) ;
16+ filePrefix = basename ( prefix ) ;
17+ } else if ( prefix . startsWith ( "~" ) ) {
18+ const home = homedir ( ) ;
19+ const rest = prefix . slice ( 1 ) ;
20+ if ( rest . includes ( "/" ) ) {
21+ dir = join ( home , dirname ( rest ) ) ;
22+ filePrefix = basename ( rest ) ;
23+ } else {
24+ dir = home ;
25+ filePrefix = rest ;
26+ }
27+ } else {
28+ dir = "." ;
29+ }
30+
31+ // Read directory contents
32+ const entries = await readdir ( dir , { withFileTypes : true } ) ;
33+ const completions : AutocompleteItem [ ] = [ ] ;
34+
35+ for ( const entry of entries ) {
36+ if ( entry . name . startsWith ( filePrefix ) ) {
37+ const fullPath = join ( dir , entry . name ) ;
38+ let displayPath = fullPath ;
39+ if ( prefix . startsWith ( "~" ) ) {
40+ displayPath = "~" + fullPath . slice ( homedir ( ) . length ) ;
41+ }
42+
43+ completions . push ( {
44+ value : displayPath + ( entry . isDirectory ( ) ? "/" : "" ) ,
45+ label : entry . name + ( entry . isDirectory ( ) ? "/" : "" ) ,
46+ } ) ;
47+ }
48+ }
49+
50+ return completions . length > 0 ? completions : null ;
51+ } catch {
52+ return null ;
53+ }
54+ } ;
55+
656 pi . registerCommand ( "save-last" , {
757 description : "Export the most recent AI response to a txt file" ,
58+ getArgumentCompletions : ( prefix : string ) => getFileCompletions ( prefix ) ,
859 handler : async ( args , ctx ) => {
960 ctx . ui . notify ( `Export started` , "success" ) ;
1061 const entries = ctx . sessionManager . getBranch ( ) ;
@@ -30,7 +81,15 @@ export default function (pi: ExtensionAPI) {
3081
3182 const timestamp = new Date ( ) . toISOString ( ) . replace ( / [: .] / g, "-" ) ;
3283 const filename = args . trim ( ) || `ai-response-${ timestamp } .txt` ;
33- const filepath = join ( ctx . cwd , filename ) ;
84+
85+ let filepath : string ;
86+ if ( isAbsolute ( filename ) ) {
87+ filepath = filename ;
88+ } else if ( filename . startsWith ( "~" ) ) {
89+ filepath = join ( homedir ( ) , filename . slice ( 1 ) ) ;
90+ } else {
91+ filepath = join ( ctx . cwd , filename ) ;
92+ }
3493
3594 await writeFile ( filepath , lastAssistantText , "utf8" ) ;
3695 ctx . ui . notify ( `Exported to ${ filename } ` , "success" ) ;
0 commit comments