secrez 2.1.8 → 2.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -370,6 +370,11 @@ Secrez is not intended to compete with password managers, so do not expect it to
370
370
 
371
371
  ## History
372
372
 
373
+ **2.1.9**
374
+
375
+ - add `<` parameter to reuse the last used path in commands (e.g., `totp <` will use the last path from previous command)
376
+ - fix deprecation warning in `execSync` by properly escaping command arguments
377
+
373
378
  **2.1.8**
374
379
 
375
380
  - add `git` command to check repository status and detect remote changes
@@ -871,60 +876,7 @@ Thank you for any contributions! 😉
871
876
  ## Test coverage
872
877
 
873
878
  ```
874
- 1 passing (549ms)
875
-
876
- --------------------|---------|----------|---------|---------|--------------------------------------
877
- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
878
- --------------------|---------|----------|---------|---------|--------------------------------------
879
- All files | 18.98 | 5.52 | 20.28 | 19.04 |
880
- src | 30.39 | 14.49 | 21.05 | 30.69 |
881
- Command.js | 32.2 | 21.27 | 30.76 | 32.75 | 22-35,40-97,102,108,119,122-130
882
- PreCommand.js | 8.82 | 0 | 0 | 8.82 | 6-97
883
- cliConfig.js | 100 | 100 | 100 | 100 |
884
- src/commands | 18.27 | 4.93 | 22.16 | 18.35 |
885
- Alias.js | 8.1 | 0 | 25 | 8.21 | 62-213
886
- Bash.js | 62.5 | 0 | 33.33 | 62.5 | 11-19
887
- Cat.js | 29.67 | 17.46 | 42.85 | 29.67 | 61-93,98,110,117-142,150-169,178-220
888
- Cd.js | 17.85 | 0 | 25 | 17.85 | 28-73
889
- Conf.js | 7.79 | 0 | 10 | 7.79 | 67-500
890
- Contacts.js | 5.98 | 0 | 7.69 | 6.03 | 53-274
891
- Copy.js | 10.98 | 0 | 12.5 | 11.11 | 71-268
892
- Ds.js | 5.97 | 0 | 16.66 | 6.06 | 39-160
893
- Edit.js | 12.34 | 0 | 20 | 12.34 | 61-214
894
- Export.js | 50 | 26.92 | 50 | 50 | ...8,209,219-295,301,307-308,316-323
895
- Find.js | 7.69 | 0 | 8.33 | 7.89 | 63-211
896
- Help.js | 33.33 | 0 | 50 | 33.33 | 26-43
897
- Import.js | 6.31 | 0 | 9.09 | 6.37 | 87-496
898
- Lcat.js | 30 | 0 | 25 | 30 | 35-65
899
- Lcd.js | 17.39 | 0 | 25 | 17.39 | 30-72
900
- Lls.js | 40.9 | 9.09 | 50 | 40.9 | 49,68,74-99
901
- Lpwd.js | 38.46 | 0 | 50 | 38.46 | 15,29-38
902
- Ls.js | 5.79 | 0 | 10 | 6.15 | 46-183
903
- Mkdir.js | 22.72 | 0 | 25 | 22.72 | 27-61
904
- Mv.js | 6.52 | 0 | 16.66 | 6.66 | 46-240
905
- Paste.js | 14.89 | 0 | 25 | 14.89 | 40-131
906
- Pwd.js | 30.76 | 0 | 25 | 30.76 | 15-35
907
- Quit.js | 50 | 0 | 33.33 | 50 | 19-40
908
- Rm.js | 16 | 0 | 16.66 | 16.32 | 36-137
909
- Shell.js | 29.41 | 0 | 25 | 29.41 | 25-57
910
- Show.js | 16 | 0 | 14.28 | 16.32 | 45-145
911
- Ssh.js | 22.22 | 0 | 20 | 22.22 | 49-120
912
- Tag.js | 8.82 | 0 | 9.09 | 8.91 | 66-236
913
- Totp.js | 14.58 | 0 | 9.09 | 14.58 | 76-312
914
- Touch.js | 76 | 51.85 | 75 | 75.51 | 75,140,152-158,164,168,177,231-234
915
- Use.js | 12.9 | 0 | 25 | 12.9 | 30-85
916
- Ver.js | 50 | 0 | 33.33 | 50 | 17-28
917
- Whoami.js | 27.77 | 0 | 20 | 27.77 | 20-50
918
- index.js | 87.5 | 50 | 100 | 86.95 | 15,22,31
919
- src/prompts | 100 | 100 | 33.33 | 100 |
920
- MainPromptMock.js | 100 | 100 | 33.33 | 100 |
921
- src/utils | 14.97 | 5.46 | 10.41 | 14.75 |
922
- AliasManager.js | 5.88 | 0 | 0 | 5.88 | 3-48
923
- ContactManager.js | 6.66 | 0 | 0 | 6.66 | 3-44
924
- Fido2Client.js | 9.61 | 0 | 0 | 9.61 | 8-108
925
- HelpProto.js | 4.2 | 0 | 16.66 | 4.27 | 11-200
926
- Logger.js | 56.81 | 43.75 | 21.05 | 55.81 | ...16-29,37-57,65-69,74,84,88,93,105
927
- --------------------|---------|----------|---------|---------|--------------------------------------
879
+
928
880
  ```
929
881
 
930
882
  ## Copyright
package/coverage.report CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- > secrez@2.1.8 test /Users/francescosullo/Projects/Secrez/secrez/packages/secrez
2
+ > secrez@2.1.9 test /Users/francescosullo/Projects/Secrez/secrez/packages/secrez
3
3
  > cross-env NODE_ENV=test nyc --reporter=lcov --reporter=text mocha test/*.test.js test/**/*.test.js test/**/**/*.js --exit
4
4
 
5
5
 
@@ -29,10 +29,10 @@
29
29
  #Cat
30
30
  ✓ should return the help
31
31
  ✓ should show the content of a file
32
- ✓ should show either one or all the versions of a file (1014ms)
32
+ ✓ should show either one or all the versions of a file (1019ms)
33
33
  ✓ should throw if entry is not a file or file does not exist
34
34
  ✓ should throw if trying to cat a binary file
35
- ✓ should show the content of a Yaml file (1029ms)
35
+ ✓ should show the content of a Yaml file (1028ms)
36
36
 
37
37
  #Cd
38
38
  ✓ should return the help
@@ -51,262 +51,6 @@
51
51
 
52
52
  #Copy
53
53
  ✓ should return the help
54
- ✓ should copy a file to the clipboard (413ms)
55
- ✓ should copy a string to the clipboard (258ms)
56
- ✓ should copy a card to the clipboard (1001ms)
57
- ✓ should return an error if the file does not exist or is a folder (50ms)
58
- ✓ should throw if copying to clipboard a binary files
59
-
60
- #Ds
61
- ✓ should return the help
62
- ✓ should list all datasets
63
- ✓ should create a new dataset
64
- ✓ should rename a dataset
65
- ✓ should delete a dataset
66
-
67
- #Export
68
- ✓ should return the help
69
- 1) should export a file to the current local folder
70
- ✓ should export a file encrypted only for the user itself
71
- ✓ should export a binary file to the current local folder
72
- ✓ should export an encrypted file to the current local folder
73
- ✓ should export a file and delete it after 1 second (1204ms)
74
- ✓ should return an error if the file does not exist or is a folder
75
- ✓ should export a keystore json file if a private_key exists in the entry (711ms)
76
- ✓ should export a cryptoenv file if a private_key exists in the entry
77
- ✓ should export a cryptoenv file with entire content when no private_key fields exist and user confirms
78
- ✓ should throw error when no private_key fields exist and user declines
79
- ✓ should throw error when no private_key fields exist and keystore option is used
80
- ✓ should display encrypted content in console when using crypto-env with no-export
81
-
82
- #Find
83
- ✓ should return the help
84
- ✓ should show find a string in the tree (1033ms)
85
- ✓ should find no result without parameters
86
- ✓ should skip binary files from search
87
-
88
- #Git
89
- ✓ should return the help
90
- ✓ should show git status when --status is used (3396ms)
91
- ✓ should show git status by default (3521ms)
92
- ✓ should handle conflict risk scenario (5238ms)
93
- ✓ should handle non-git repository
94
-
95
- #Help
96
- ✓ should return the help
97
- ✓ #execAsync and format
98
- ✓ should throw if wrong command
99
- ✓ -- to complete coverage
100
-
101
- #Import
102
- ✓ should return the help
103
- ✓ should import a file in the current folder
104
- ✓ should import an encrypted file
105
- ✓ should import an encrypted file encrypted for myself
106
- ✓ should import an encrypted binary file and export it again verifying it is fine
107
- ✓ should import files recursively
108
- ✓ should read a folder and import the only text file
109
- ✓ should read a folder and import text and binary files
110
- ✓ should simulate the import of two files
111
- ✓ should move the imported file
112
- ✓ should import a backup from another software spanning the data among folders and files
113
- ✓ should import a backup from another software but saving the tags as tags
114
- ✓ should import a backup from another software using tags to prefix the paths
115
- ✓ should import using tags to prefix the paths, ignoring the tags
116
- ✓ should import from a LastPass-like csv setting the path from "grouping" and "name"
117
- ✓ should import from a json
118
- ✓ should throw importing a malformed backup
119
- ✓ should throw importing a CSV indicating wrong fields to generate the path
120
-
121
- #Lcat
122
- ✓ should return the help
123
- ✓ cat a file
124
- ✓ return en error if trying to cat a binary file
125
-
126
- #Lcd
127
- ✓ should return the help
128
- ✓ change to a folder
129
- ✓ return en error if changing to a file
130
-
131
- #Lls
132
- ✓ should return the help
133
- ✓ should list a folder
134
- ✓ return en error if lls-ing a not existing path
135
- ✓ return a message if no files are found
136
-
137
- #Lpwd
138
- ✓ should return the help
139
- ✓ change to a folder
140
-
141
- #Ls
142
- ✓ should return the help
143
- ✓ should return all the datasets
144
- ✓ should list folders and files
145
- ✓ should list folders and files using wildcards
146
-
147
- #Mkdir
148
- ✓ should return the help
149
- ✓ should create a folder
150
- ✓ should create a nested folder
151
- ✓ should throw if trying to create a child of a file
152
- ✓ should throw if wrong parameters
153
-
154
- #Mv
155
- ✓ should return the help
156
- ✓ should rename a file (1014ms)
157
- ✓ should move a file to another folder
158
- ✓ should move many files to another folder
159
- ✓ should move a file to another subfolder
160
- ✓ should move and rename file to another folder
161
- ✓ should move file to another folder using wildcards
162
- ✓ should move file to another dataset using wildcards
163
- ✓ should move file managing duplicates
164
- ✓ should throw if parameters are missed or wrong
165
- ✓ should move files from and to other datasets (1025ms)
166
- ✓ should move the results of a find
167
-
168
- #Paste
169
- ✓ should return the help
170
- ✓ should paste the clipboard content to a new file (50ms)
171
- ✓ should paste the clipboard content to an existent file (70ms)
172
- ✓ should paste a single field to a yml card
173
-
174
- #Pwd
175
- ✓ should return the help
176
- ✓ should show the working folder
177
-
178
- #Quit
179
- ✓ should show the content of an external file via bash
180
-
181
- #Rm
182
- ✓ should return the help
183
- ✓ should delete a file with one version
184
- ✓ should delete many files usign wildcards
185
- ✓ should return errors if wrong parameters
186
- ✓ should delete some versions of a file (1010ms)
187
-
188
- #Shell
189
- ✓ should return the help
190
- ✓ should show the content of an external file via shell
191
-
192
- #Show
193
- ✓ should return the help
194
- ✓ should show the field password of a card
195
-
196
- #Tag
197
- ✓ should return the help
198
- ✓ should tag a file
199
- ✓ should remove a tag
200
- ✓ should list all the tags
201
- ✓ should show the file tagged as
202
- ✓ should show very long file tagged as
203
-
204
- #Totp
205
- ✓ should return the help
206
- ✓ should totp a file to the clipboard (407ms)
207
- ✓ should read a totp secret from an image and add the totp field to the card (39ms)
208
- ✓ should read a totp secret from an image and return the secret
209
- ✓ should throw if bad image
210
- ✓ should throw if missing parameters
211
- ✓ should throw if the yaml is malformed
212
- ✓ should read a totp secret from the clipboard (435ms)
213
-
214
- #Touch
215
- ✓ should return the help
216
- ✓ should create a file
217
- ✓ should create a file with content
218
- ✓ should duplicate a file
219
- ✓ should throw if trying to duplicate a non existing file
220
- ✓ should throw if trying to duplicate a folder
221
- ✓ should throw if trying to create a child of a file
222
- ✓ should throw if wrong parameters
223
- ✓ should create a file and generate a wallet
224
- New file "/folder2/file1" created.
225
- ✓ should generate 5 prefixed wallet (66ms)
226
- New file "/folder2/file1" created.
227
- ✓ should generate a wallet with mnemonic and 2 keys
228
-
229
- #Use
230
- ✓ should return the help
231
- ✓ should use a new dataset, creating it if does not exist
232
-
233
- #Ver
234
- ✓ should show the current version
235
-
236
- #Whoami
237
- ✓ should return the help
238
- ✓ should see who am I
239
-
240
-
241
- 160 passing (31s)
242
- 1 pending
243
- 1 failing
244
-
245
- 1) #Export
246
- should export a file to the current local folder:
247
-
248
- AssertionError: expected 'file.2' to equal 'file'
249
- + expected - actual
250
-
251
- -file.2
252
- +file
253
-
254
- at assertConsole (/Users/francescosullo/Projects/Secrez/secrez/packages/test-helpers/src/index.js:121:16)
255
- at Context.<anonymous> (test/commands/Export.test.js:94:5)
256
-
257
-
258
-
259
- --------------------|---------|----------|---------|---------|--------------------------------------
260
- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
261
- --------------------|---------|----------|---------|---------|--------------------------------------
262
- All files | 80.15 | 67.58 | 81.49 | 80.04 |
263
- src | 55.75 | 52.05 | 55 | 56.25 |
264
- Command.js | 72.85 | 74.5 | 78.57 | 73.91 | 32,55-62,73,80,119,145-156,163-166
265
- PreCommand.js | 8.82 | 0 | 0 | 8.82 | 6-97
266
- cliConfig.js | 100 | 100 | 100 | 100 |
267
- src/commands | 82.85 | 69.14 | 90.82 | 82.73 |
268
- Alias.js | 88.6 | 78.68 | 100 | 88.46 | 101,112,139,169,173,180,190,213-214
269
- Bash.js | 75 | 0 | 66.66 | 75 | 18-19
270
- Cat.js | 98.9 | 88.88 | 100 | 98.9 | 152
271
- Cd.js | 96.42 | 86.66 | 100 | 96.42 | 44
272
- Conf.js | 8.64 | 0 | 20 | 8.64 | 98-509
273
- Contacts.js | 86.06 | 75.6 | 100 | 85.95 | ...5,165,172,184,237,250,260,268-269
274
- Copy.js | 91.2 | 71.92 | 100 | 91.11 | 115,166,183,205-210,225-226,253
275
- Ds.js | 90.27 | 82.6 | 100 | 90.14 | 99,108-113,125,147-148
276
- Edit.js | 12.94 | 0 | 40 | 12.94 | 88-222
277
- Export.js | 90.17 | 76.92 | 100 | 90.17 | ...3-198,209,227-231,236,248,257,260
278
- Find.js | 93.58 | 86.66 | 100 | 93.42 | 101,164,200-203,209
279
- Git.js | 92.3 | 66.66 | 100 | 92.3 | 40,61
280
- Help.js | 100 | 80 | 100 | 100 | 29
281
- Import.js | 92.41 | 85.38 | 100 | 92.34 | ...7,387,393,441,457-458,466-473,500
282
- Lcat.js | 100 | 85.71 | 100 | 100 | 54
283
- Lcd.js | 95.65 | 81.81 | 100 | 95.65 | 50
284
- Lls.js | 95.45 | 72.72 | 100 | 95.45 | 97
285
- Lpwd.js | 92.3 | 100 | 100 | 92.3 | 36
286
- Ls.js | 91.3 | 75 | 100 | 90.76 | 103,114-116,130,181
287
- Mkdir.js | 92.59 | 60 | 100 | 92.59 | 56-57
288
- Mv.js | 86.59 | 71.66 | 100 | 86.31 | 93-99,133,155-156,165,175-182
289
- Paste.js | 84.61 | 70.83 | 100 | 84.61 | 72,78,81,89,113,130-131,139
290
- Pwd.js | 92.3 | 100 | 100 | 92.3 | 33
291
- Quit.js | 90 | 50 | 100 | 90 | 27
292
- Rm.js | 90.9 | 76 | 100 | 90.74 | 63,125-126,136,144
293
- Shell.js | 88.23 | 60 | 100 | 88.23 | 38,55
294
- Show.js | 72 | 45.45 | 57.14 | 73.46 | ...8,100,106-114,117,123-126,132,143
295
- Ssh.js | 25 | 0 | 40 | 25 | 72-120
296
- Tag.js | 96.26 | 91.37 | 100 | 96.22 | 122,171,204-205
297
- Totp.js | 92.07 | 74.19 | 100 | 92.07 | 189-190,230,240,282-287,301-302
298
- Touch.js | 92.72 | 77.41 | 100 | 92.59 | 164,187-188,240
299
- Use.js | 91.66 | 86.95 | 100 | 91.66 | 68,83-84
300
- Ver.js | 90 | 66.66 | 100 | 90 | 25
301
- Whoami.js | 83.33 | 60 | 80 | 83.33 | 27,35,48
302
- index.js | 87.5 | 50 | 100 | 86.95 | 15,22,31
303
- src/prompts | 100 | 100 | 50 | 100 |
304
- MainPromptMock.js | 100 | 100 | 50 | 100 |
305
- src/utils | 68.82 | 62.5 | 56.25 | 68.44 |
306
- AliasManager.js | 100 | 91.66 | 100 | 100 | 47
307
- ContactManager.js | 73.33 | 60 | 85.71 | 73.33 | 12,34-36
308
- Fido2Client.js | 15.38 | 0 | 11.11 | 15.38 | 14-108
309
- HelpProto.js | 89.07 | 82.6 | 100 | 88.88 | 49,135-137,153-154,171-176,195
310
- Logger.js | 63.63 | 56.25 | 36.84 | 62.79 | ...25,37-49,57,65-69,74,84,88,93,105
311
- --------------------|---------|----------|---------|---------|--------------------------------------
54
+ ✓ should copy a file to the clipboard (406ms)
55
+ ✓ should copy a string to the clipboard (261ms)
312
56
   ELIFECYCLE  Test failed. See above for more details.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "secrez",
3
- "version": "2.1.8",
3
+ "version": "2.1.9",
4
4
  "license": "MIT",
5
5
  "nyc": {
6
6
  "include": "src",
package/src/Command.js CHANGED
@@ -84,6 +84,14 @@ class Command extends PreCommand {
84
84
  ][1] || undefined,
85
85
  ];
86
86
  }
87
+ // Handle < syntax for last path
88
+ if (
89
+ self.prompt.cache &&
90
+ self.prompt.cache.lastPath &&
91
+ options.path === "<"
92
+ ) {
93
+ return [options.path + self.prompt.cache.lastPath[0]];
94
+ }
87
95
  return await self.prompt[
88
96
  extraOptions.external ? "externalFs" : "internalFs"
89
97
  ].getFileList(options, true);
package/src/Welcome.js CHANGED
@@ -3,7 +3,7 @@ const inquirer = require("inquirer");
3
3
  const fs = require("fs-extra");
4
4
  const Crypto = require("@secrez/crypto");
5
5
  const Logger = require("./utils/Logger");
6
- const Fido2Client = require("./utils/Fido2Client");
6
+ // const Fido2Client = require("./utils/Fido2Client"); // FIDO2 support removed
7
7
 
8
8
  class Welcome {
9
9
  async start(secrez, options) {
@@ -37,7 +37,7 @@ Thanks.`);
37
37
  if (await fs.pathExists(this.secrez.config.keysPath)) {
38
38
  let errorCode = await this.login();
39
39
  if (errorCode === 1) {
40
- await this.sharedLogin();
40
+ await this.handleDeprecatedFido2();
41
41
  }
42
42
  } else {
43
43
  Logger.grey("Please signup to create your local account");
@@ -111,6 +111,8 @@ Thanks.`);
111
111
  }
112
112
  }
113
113
 
114
+ // sharedLogin() method removed - FIDO2 support deprecated
115
+ /*
114
116
  async sharedLogin() {
115
117
  let fido2Client = new Fido2Client(this.secrez);
116
118
  let authenticator;
@@ -198,6 +200,7 @@ Thanks.`);
198
200
  }
199
201
  }
200
202
  }
203
+ */
201
204
 
202
205
  async signup() {
203
206
  for (;;) {
@@ -245,6 +248,44 @@ Thanks.`);
245
248
  }
246
249
  }
247
250
  }
251
+
252
+ async handleDeprecatedFido2() {
253
+ Logger.yellow("FIDO2 second factor authentication is no longer supported in this version.");
254
+ Logger.grey("Removing deprecated FIDO2 configuration...");
255
+
256
+ try {
257
+ const conf = await this.secrez.readConf();
258
+ const data = conf.data;
259
+
260
+ if (data.keys) {
261
+ // Remove all FIDO2 keys from the configuration
262
+ delete data.keys;
263
+
264
+ // Save the cleaned configuration
265
+ await this.secrez.saveConf(conf);
266
+
267
+ Logger.green("FIDO2 configuration has been removed successfully.");
268
+ Logger.grey("You can now login with your master password only.");
269
+
270
+ // Try to login again with the cleaned configuration
271
+ let errorCode = await this.login();
272
+ if (errorCode === 1) {
273
+ Logger.red("Login still failed. Please check your password or create a new account.");
274
+ // eslint-disable-next-line no-process-exit
275
+ process.exit(1);
276
+ }
277
+ } else {
278
+ Logger.red("No FIDO2 keys found, but login still requires second factor. This may indicate a corrupted configuration.");
279
+ // eslint-disable-next-line no-process-exit
280
+ process.exit(1);
281
+ }
282
+ } catch (e) {
283
+ Logger.red(`Failed to clean FIDO2 configuration: ${e.message}`);
284
+ Logger.grey("You may need to manually remove the keys.json file and create a new account.");
285
+ // eslint-disable-next-line no-process-exit
286
+ process.exit(1);
287
+ }
288
+ }
248
289
  }
249
290
 
250
291
  module.exports = new Welcome();
@@ -187,6 +187,8 @@ class Cat extends require("../Command") {
187
187
  this.validate(options, {
188
188
  path: true,
189
189
  });
190
+ // Track the last path used
191
+ this.prompt.setLastPath(options.path);
190
192
  let fn = path.basename(options.path);
191
193
  let data = await this.cat(options);
192
194
  let extra = options.all || options.metadata || options.versions;
@@ -163,6 +163,10 @@ class Ls extends require("../Command") {
163
163
  }
164
164
  try {
165
165
  this.validate(options);
166
+ // Track the last path used if a path was specified
167
+ if (options.path) {
168
+ this.prompt.setLastPath(options.path);
169
+ }
166
170
  let list = await this.ls(options);
167
171
  list = list.filter((e) => !/^\./.test(e) || options.all).sort();
168
172
  if (list.length) {
@@ -135,6 +135,8 @@ class Show extends require("../Command") {
135
135
  this.validate(options, {
136
136
  path: true,
137
137
  });
138
+ // Track the last path used
139
+ this.prompt.setLastPath(options.path);
138
140
  const content = await this.show(options);
139
141
  if (content) {
140
142
  this.Logger.reset(content);
@@ -303,6 +303,11 @@ class Totp extends require("../Command") {
303
303
  }
304
304
  }
305
305
 
306
+ // Track the last path used if a path was specified
307
+ if (options.path) {
308
+ this.prompt.setLastPath(options.path);
309
+ }
310
+
306
311
  let token = await this.totp(options);
307
312
  if (options.fromImage || options.fromClipboard) {
308
313
  this.Logger.grey(token);
@@ -243,6 +243,10 @@ class CommandPrompt {
243
243
  if (/ (#|£)\d+(\w+:|)\/[\w/]+/.test(line)) {
244
244
  line = line.replace(/ (#|£)\d+((\w+:|)\/[\w/]+)/, " $2");
245
245
  }
246
+ // Handle < syntax for last path
247
+ if (/ </.test(line)) {
248
+ line = line.replace(/</, "");
249
+ }
246
250
  return line;
247
251
  }
248
252
 
@@ -75,6 +75,14 @@ class MainPrompt extends require("./CommandPrompt") {
75
75
  }
76
76
  }
77
77
 
78
+ setLastPath(path) {
79
+ this.setCache("lastPath", 0, path);
80
+ }
81
+
82
+ getLastPath() {
83
+ return this.getCache("lastPath", 0);
84
+ }
85
+
78
86
  prePromptMessage(options = {}) {
79
87
  this.resetTimeout();
80
88
  return chalk.reset(
@@ -18,9 +18,31 @@ class MainPromptMock {
18
18
  this.cache = {};
19
19
  }
20
20
 
21
- setCache() {}
21
+ setCache(name, index, content) {
22
+ if (!this.cache[name]) {
23
+ this.cache[name] = {};
24
+ }
25
+ this.cache[name][index] = content;
26
+ }
27
+
28
+ getCache(name, index) {
29
+ if (!this.cache[name]) {
30
+ return null;
31
+ }
32
+ if (typeof index !== "undefined") {
33
+ return this.cache[name][index];
34
+ } else {
35
+ return this.cache[name];
36
+ }
37
+ }
22
38
 
23
- getCache() {}
39
+ setLastPath(path) {
40
+ this.setCache("lastPath", 0, path);
41
+ }
42
+
43
+ getLastPath() {
44
+ return this.getCache("lastPath", 0);
45
+ }
24
46
 
25
47
  async run(options) {}
26
48