@chronicle.app/shell 0.3.0 → 0.5.0

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.
@@ -1,4 +1,4 @@
1
- import { Extractor, Record } from '@chronicle.app/etl';
1
+ import { Extractor, Record, type Survey, type SurveyOptions } from '@chronicle.app/etl';
2
2
  import { z } from 'zod';
3
3
  import ShellHistoryTransformer from './ShellHistoryTransformer.js';
4
4
  export declare class ShellHistoryExtractor extends Extractor<typeof ShellHistoryExtractor> {
@@ -41,6 +41,11 @@ export declare class ShellHistoryExtractor extends Extractor<typeof ShellHistory
41
41
  private parseZshHistory;
42
42
  private parseBashHistory;
43
43
  private parseFishHistory;
44
+ /**
45
+ * The commands a run reads and when, from one pass over the history file,
46
+ * which stays small. Commands without a time count, but date nothing.
47
+ */
48
+ survey(options?: SurveyOptions): Promise<Survey>;
44
49
  determineCount(): Promise<number | null>;
45
50
  }
46
51
  //# sourceMappingURL=ShellHistoryExtractor.d.ts.map
@@ -1,4 +1,4 @@
1
- import { Extractor } from '@chronicle.app/etl';
1
+ import { Extractor, countMonth, fileError, } from '@chronicle.app/etl';
2
2
  import { readFile, access } from 'node:fs/promises';
3
3
  import { z } from 'zod';
4
4
  import os from 'node:os';
@@ -25,7 +25,9 @@ export class ShellHistoryExtractor extends Extractor {
25
25
  });
26
26
  async detectShellType() {
27
27
  if (this.config.input) {
28
- const content = await readFile(this.config.input, 'utf8');
28
+ const content = await readFile(this.config.input, 'utf8').catch(error => {
29
+ throw fileError(error, this.config.input, 'shell history');
30
+ });
29
31
  if (/^: \d+:\d+;/m.test(content))
30
32
  return 'zsh';
31
33
  if (/^- cmd: /m.test(content))
@@ -101,6 +103,9 @@ export class ShellHistoryExtractor extends Extractor {
101
103
  }
102
104
  }
103
105
  catch (error) {
106
+ const typed = fileError(error, inputPath, `${shellType} history`);
107
+ if (typed !== error)
108
+ throw typed;
104
109
  throw new Error(`Failed to read ${shellType} history file from ${inputPath}: ${error}`);
105
110
  }
106
111
  }
@@ -263,6 +268,37 @@ export class ShellHistoryExtractor extends Extractor {
263
268
  }
264
269
  yield* this.yieldNewestFirst(entries);
265
270
  }
271
+ /**
272
+ * The commands a run reads and when, from one pass over the history file,
273
+ * which stays small. Commands without a time count, but date nothing.
274
+ */
275
+ async survey(options = {}) {
276
+ // Every command in range, whatever the run's limit.
277
+ const all = new ShellHistoryExtractor({ ...this.config, limit: undefined });
278
+ let count = 0;
279
+ let earliest;
280
+ let latest;
281
+ const byMonth = {};
282
+ for await (const { data } of all.extract()) {
283
+ count++;
284
+ if (!data.timestamp)
285
+ continue;
286
+ const time = new Date(data.timestamp);
287
+ if (!earliest || time < earliest)
288
+ earliest = time;
289
+ if (!latest || time > latest)
290
+ latest = time;
291
+ if (options.byMonth)
292
+ countMonth(byMonth, time);
293
+ }
294
+ return {
295
+ commands: {
296
+ count,
297
+ ...(earliest && { earliest, latest }),
298
+ ...(options.byMonth && { byMonth }),
299
+ },
300
+ };
301
+ }
266
302
  async determineCount() {
267
303
  const config = this.config;
268
304
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chronicle.app/shell",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [
@@ -19,9 +19,9 @@
19
19
  "type": "module",
20
20
  "description": "Chronicle shell extraction plugin",
21
21
  "devDependencies": {
22
- "@chronicle.app/etl": "0.3.0",
23
- "@chronicle.app/schema": "0.3.0",
24
- "@chronicle.app/tsconfig": "0.3.0",
22
+ "@chronicle.app/etl": "0.5.0",
23
+ "@chronicle.app/schema": "0.5.0",
24
+ "@chronicle.app/tsconfig": "0.5.0",
25
25
  "@types/node": "^22.10.1",
26
26
  "typescript": "^5.7.2"
27
27
  },
@@ -61,7 +61,24 @@
61
61
  "recordTypes": [
62
62
  "commands"
63
63
  ],
64
- "default": true
64
+ "default": true,
65
+ "locations": [
66
+ {
67
+ "path": "~/.zsh_history"
68
+ },
69
+ {
70
+ "path": "~/.bash_history",
71
+ "options": {
72
+ "shell": "bash"
73
+ }
74
+ },
75
+ {
76
+ "path": "~/.local/share/fish/fish_history",
77
+ "options": {
78
+ "shell": "fish"
79
+ }
80
+ }
81
+ ]
65
82
  }
66
83
  }
67
84
  }