@lumpcode/core 0.0.10 → 0.0.12

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 (43) hide show
  1. package/dist/helpers/executeStepsForContextList/main.d.ts +1 -1
  2. package/dist/helpers/executeStepsForContextList/main.d.ts.map +1 -1
  3. package/dist/helpers/getCodeBasePaths/main.d.ts +2 -2
  4. package/dist/helpers/getCodeBasePaths/main.d.ts.map +1 -1
  5. package/dist/helpers/getContextStatus/main.d.ts.map +1 -1
  6. package/dist/helpers/getToDoContextList/main.d.ts +2 -2
  7. package/dist/helpers/getToDoContextList/main.d.ts.map +1 -1
  8. package/dist/index.cjs +71 -59
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.js +71 -58
  11. package/dist/index.js.map +1 -1
  12. package/dist/utils/appendMissingGitignoreLines/index.d.ts +2 -0
  13. package/dist/utils/appendMissingGitignoreLines/index.d.ts.map +1 -0
  14. package/dist/utils/appendMissingGitignoreLines/main.d.ts +6 -0
  15. package/dist/utils/appendMissingGitignoreLines/main.d.ts.map +1 -0
  16. package/dist/utils/historyFile/main.d.ts.map +1 -1
  17. package/dist/utils/index.d.ts +2 -3
  18. package/dist/utils/index.d.ts.map +1 -1
  19. package/dist/utils/isProcessAlive/index.d.ts +2 -0
  20. package/dist/utils/isProcessAlive/index.d.ts.map +1 -0
  21. package/dist/utils/isProcessAlive/main.d.ts +6 -0
  22. package/dist/utils/isProcessAlive/main.d.ts.map +1 -0
  23. package/dist/utils/nodeErrnoCode/index.d.ts +2 -0
  24. package/dist/utils/nodeErrnoCode/index.d.ts.map +1 -0
  25. package/dist/utils/nodeErrnoCode/main.d.ts +3 -0
  26. package/dist/utils/nodeErrnoCode/main.d.ts.map +1 -0
  27. package/dist/utils/parseGitLogHashSubjectLines/index.d.ts +2 -0
  28. package/dist/utils/parseGitLogHashSubjectLines/index.d.ts.map +1 -0
  29. package/dist/utils/parseGitLogHashSubjectLines/main.d.ts +7 -0
  30. package/dist/utils/parseGitLogHashSubjectLines/main.d.ts.map +1 -0
  31. package/dist/utils/pathExists/index.d.ts +2 -0
  32. package/dist/utils/pathExists/index.d.ts.map +1 -0
  33. package/dist/utils/pathExists/main.d.ts +3 -0
  34. package/dist/utils/pathExists/main.d.ts.map +1 -0
  35. package/dist/utils/readJsonFile/index.d.ts +2 -0
  36. package/dist/utils/readJsonFile/index.d.ts.map +1 -0
  37. package/dist/utils/readJsonFile/main.d.ts +21 -0
  38. package/dist/utils/readJsonFile/main.d.ts.map +1 -0
  39. package/dist/utils/resolveBundledAssetPath/index.d.ts +2 -0
  40. package/dist/utils/resolveBundledAssetPath/index.d.ts.map +1 -0
  41. package/dist/utils/resolveBundledAssetPath/main.d.ts +3 -0
  42. package/dist/utils/resolveBundledAssetPath/main.d.ts.map +1 -0
  43. package/package.json +2 -1
@@ -6,7 +6,7 @@ export type ExecuteStepsForContextListParams = Required<Pick<RunLumpInput, 'base
6
6
  };
7
7
  export declare function executeStepsForContextList({ baseBranch, branchFn, lumpVariables, contextList, gitAddCommandFn, gitCommitCommandFn, gitPushCommandFn, gitCommitMessageFn, projectRoot, steps, setupFn, setupWorkspaceFn, teardownFn, teardownWorkspaceFn, getKeepHistoryFilePathFn, logger: loggerInput, }: ExecuteStepsForContextListParams): Promise<Failure<{
8
8
  message: string;
9
- }> | import("../../types").Success<{
9
+ }> | import("../..").Success<{
10
10
  branchName: string;
11
11
  contextNames: string[];
12
12
  contextRunStateList: ContextRunState[];
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/helpers/executeStepsForContextList/main.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,WAAW,EACX,eAAe,EACf,OAAO,EACP,MAAM,EAIT,MAAM,aAAa,CAAC;AAUrB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,MAAM,gCAAgC,GAAG,QAAQ,CAAC,IAAI,CACxD,YAAY,EACV,YAAY,GACZ,UAAU,GACV,eAAe,GACf,OAAO,GACP,SAAS,GACT,YAAY,GACZ,iBAAiB,GACjB,oBAAoB,GACpB,kBAAkB,GAClB,oBAAoB,GACpB,aAAa,GACb,kBAAkB,GAClB,qBAAqB,GACrB,0BAA0B,CAC/B,CAAC,GAAG;IACD,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,CAAA;AAED,wBAAsB,0BAA0B,CAAC,EAC7C,UAAU,EACV,QAAQ,EACR,aAAa,EACb,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,KAAK,EACL,OAAO,EACP,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,wBAAwB,EACxB,MAAM,EAAE,WAAW,GACtB,EAAE,gCAAgC;aAqEa,MAAM;;;;;IAmOrD;AAED,MAAM,MAAM,gCAAgC,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/helpers/executeStepsForContextList/main.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,WAAW,EACX,eAAe,EACf,OAAO,EACP,MAAM,EAIT,MAAM,aAAa,CAAC;AAUrB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,MAAM,gCAAgC,GAAG,QAAQ,CAAC,IAAI,CACxD,YAAY,EACV,YAAY,GACZ,UAAU,GACV,eAAe,GACf,OAAO,GACP,SAAS,GACT,YAAY,GACZ,iBAAiB,GACjB,oBAAoB,GACpB,kBAAkB,GAClB,oBAAoB,GACpB,aAAa,GACb,kBAAkB,GAClB,qBAAqB,GACrB,0BAA0B,CAC/B,CAAC,GAAG;IACD,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,CAAA;AAED,wBAAsB,0BAA0B,CAAC,EAC7C,UAAU,EACV,QAAQ,EACR,aAAa,EACb,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,KAAK,EACL,OAAO,EACP,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,wBAAwB,EACxB,MAAM,EAAE,WAAW,GACtB,EAAE,gCAAgC;aAqEa,MAAM;;;;;IAqOrD;AAED,MAAM,MAAM,gCAAgC,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAAC,CAAC"}
@@ -2,7 +2,7 @@ import { CodeBasePath, Logger } from '../../types';
2
2
  export declare function getCodeBasePaths({ cwd, logger: loggerInput, }: {
3
3
  cwd: string;
4
4
  logger?: Logger;
5
- }): Promise<import("../../types").Failure<{
5
+ }): Promise<import("../..").Failure<{
6
6
  message: string;
7
- }> | import("../../types").Success<CodeBasePath[]>>;
7
+ }> | import("../..").Success<CodeBasePath[]>>;
8
8
  //# sourceMappingURL=main.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/helpers/getCodeBasePaths/main.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAEnD,wBAAsB,gBAAgB,CAAC,EACnC,GAAG,EACH,MAAM,EAAE,WAAW,GACtB,EAAE;IACC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;;oDAoBA"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/helpers/getCodeBasePaths/main.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAEnD,wBAAsB,gBAAgB,CAAC,EACnC,GAAG,EACH,MAAM,EAAE,WAAW,GACtB,EAAE;IACC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;;8CAoBA"}
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/helpers/getContextStatus/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAIpE,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,aAAa,CAAC,CA6EzB"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/helpers/getContextStatus/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAIpE,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,aAAa,CAAC,CAmEzB"}
@@ -7,7 +7,7 @@ export declare function getToDoContextList(params: {
7
7
  projectRoot: string;
8
8
  baseBranch: string;
9
9
  logger?: Logger;
10
- }): Promise<import("../../types").Failure<{
10
+ }): Promise<import("../..").Failure<{
11
11
  message: string;
12
- }> | import("../../types").Success<import("../../types").Context<Record<string, string | number | boolean>>[]>>;
12
+ }> | import("../..").Success<import("../..").Context<Record<string, string | number | boolean>>[]>>;
13
13
  //# sourceMappingURL=main.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/helpers/getToDoContextList/main.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE,wBAAsB,kBAAkB,CAAC,MAAM,EAAE;IAC7C,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,aAAa,EAAE,aAAa,CAAC;IAC7B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;;gHA8DA"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/helpers/getToDoContextList/main.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE,wBAAsB,kBAAkB,CAAC,MAAM,EAAE;IAC7C,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,aAAa,EAAE,aAAa,CAAC;IAC7B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;;oGA8DA"}
package/dist/index.cjs CHANGED
@@ -59,18 +59,6 @@ function failure(data) {
59
59
  };
60
60
  }
61
61
 
62
- function decision(possibilities, defaultValue) {
63
- for (const [condition, result] of possibilities) {
64
- if (condition()) {
65
- return result();
66
- }
67
- }
68
- if (defaultValue) {
69
- return defaultValue;
70
- }
71
- throw new Error('No value found in decision');
72
- }
73
-
74
62
  /**
75
63
  * Wrap an arbitrary string in quotes so it can be safely embedded in
76
64
  * a shell command (e.g. the command string passed to `execAsync`).
@@ -85,18 +73,6 @@ function shellSingleQuote(value) {
85
73
  return `'${value.split("'").join(`'\\''`)}'`;
86
74
  }
87
75
 
88
- /**
89
- * Wrap a shell fragment so failure does not break a surrounding `&&` chain.
90
- *
91
- * Unix: `cmd || true`. Windows cmd.exe: `(cmd || cd .)`.
92
- */
93
- function shellBestEffort(command) {
94
- if (process.platform === 'win32') {
95
- return `(${command} || cd .)`;
96
- }
97
- return `${command} || true`;
98
- }
99
-
100
76
  const DEFAULT_WINDOWS_PATHEXT = [
101
77
  '.COM',
102
78
  '.EXE',
@@ -247,14 +223,6 @@ function createConsoleLogger(input) {
247
223
  return makeLogger(prefix);
248
224
  }
249
225
 
250
- const noopLogger = {
251
- error: () => { },
252
- warn: () => { },
253
- info: () => { },
254
- verbose: () => { },
255
- child: () => noopLogger,
256
- };
257
-
258
226
  function firstNonEmptyLine(value) {
259
227
  if (value == null)
260
228
  return undefined;
@@ -3186,6 +3154,49 @@ function dump(input, options = {}) {
3186
3154
  });
3187
3155
  }
3188
3156
 
3157
+ /** Returns whether `filePath` is accessible to this process (typically exists). */
3158
+ async function pathExists(filePath) {
3159
+ try {
3160
+ await fs__namespace$1.access(filePath);
3161
+ return true;
3162
+ }
3163
+ catch {
3164
+ return false;
3165
+ }
3166
+ }
3167
+
3168
+ /** Strip terminal ANSI escapes and other C0 controls js-yaml rejects in literal blocks. */
3169
+ function sanitizeHistoryText(value) {
3170
+ return value
3171
+ .replace(/\x1b\[[0-9;]*[A-Za-z]/g, '')
3172
+ .replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, '');
3173
+ }
3174
+ function parseHistoryYamlContent(content) {
3175
+ const parsed = load(content, { schema: YAML11_SCHEMA });
3176
+ if (!Array.isArray(parsed)) {
3177
+ throw new Error('History file must contain a YAML sequence');
3178
+ }
3179
+ return parsed;
3180
+ }
3181
+ function tryParseHistoryContent(content) {
3182
+ try {
3183
+ return parseHistoryYamlContent(content);
3184
+ }
3185
+ catch (firstError) {
3186
+ const sanitized = sanitizeHistoryText(content);
3187
+ if (sanitized === content) {
3188
+ throw firstError;
3189
+ }
3190
+ return parseHistoryYamlContent(sanitized);
3191
+ }
3192
+ }
3193
+ function sanitizeHistoryEntry(entry) {
3194
+ return {
3195
+ ...entry,
3196
+ prompt: sanitizeHistoryText(entry.prompt),
3197
+ commandResult: sanitizeHistoryText(entry.commandResult),
3198
+ };
3199
+ }
3189
3200
  function historyFormatFromPath(filePath) {
3190
3201
  const ext = path.extname(filePath).toLowerCase();
3191
3202
  if (ext === '.yaml' || ext === '.yml') {
@@ -3223,7 +3234,8 @@ function dumpHistoryEntries(entries) {
3223
3234
  if (entries.length === 0) {
3224
3235
  return '[]\n';
3225
3236
  }
3226
- return dump(entries, {
3237
+ const sanitizedEntries = entries.map(sanitizeHistoryEntry);
3238
+ return dump(sanitizedEntries, {
3227
3239
  schema: YAML11_SCHEMA,
3228
3240
  lineWidth: 0,
3229
3241
  noRefs: true,
@@ -3241,11 +3253,7 @@ async function readHistoryFile({ filePath, }) {
3241
3253
  }
3242
3254
  try {
3243
3255
  const content = await fs$1.readFile(filePath, 'utf-8');
3244
- const parsed = load(content, { schema: YAML11_SCHEMA });
3245
- if (!Array.isArray(parsed)) {
3246
- return failure(`History file ${filePath} must contain a YAML sequence`);
3247
- }
3248
- return success(parsed);
3256
+ return success(tryParseHistoryContent(content));
3249
3257
  }
3250
3258
  catch (error) {
3251
3259
  const detail = error instanceof Error ? error.message : String(error);
@@ -3272,7 +3280,7 @@ async function appendHistoryEntry({ filePath, entry, }) {
3272
3280
  if (!formatResult.success) {
3273
3281
  return formatResult;
3274
3282
  }
3275
- const exists = await fs$1.stat(filePath).then(() => true).catch(() => false);
3283
+ const exists = await pathExists(filePath);
3276
3284
  let entries;
3277
3285
  if (exists) {
3278
3286
  const readResult = await readHistoryFile({ filePath });
@@ -3285,10 +3293,25 @@ async function appendHistoryEntry({ filePath, entry, }) {
3285
3293
  await fs$1.mkdir(path.dirname(filePath), { recursive: true });
3286
3294
  entries = [];
3287
3295
  }
3288
- entries.push(entry);
3296
+ entries.push(sanitizeHistoryEntry(entry));
3289
3297
  return writeHistoryFile({ filePath, entries });
3290
3298
  }
3291
3299
 
3300
+ /** Parses `git log --format='%H %s'` lines into commit hash and subject pairs. */
3301
+ function parseGitLogHashSubjectLines(stdout) {
3302
+ return stdout
3303
+ .split('\n')
3304
+ .map((line) => line.trim())
3305
+ .filter(Boolean)
3306
+ .map((line) => {
3307
+ const sp = line.indexOf(' ');
3308
+ return {
3309
+ hash: sp === -1 ? line : line.slice(0, sp),
3310
+ subject: sp === -1 ? '' : line.slice(sp + 1),
3311
+ };
3312
+ });
3313
+ }
3314
+
3292
3315
  const execAsyncBase = node_util.promisify(node_child_process.exec);
3293
3316
  async function execAsync(command, options) {
3294
3317
  const { stdout, stderr, hasErrored } = await execAsyncBase(command, { cwd: options?.cwd })
@@ -3584,8 +3607,8 @@ async function executeStepsForContextList({ baseBranch, branchFn, lumpVariables,
3584
3607
  entry: postCommandExecFnInput,
3585
3608
  });
3586
3609
  if (!appendResult.success) {
3587
- stepWalkFailure = failure({ message: appendResult.data });
3588
- return;
3610
+ // TODO: sanitize history appending to avoid this warning for certain commands outputs
3611
+ logger.warn(`Failed to append history entry to ${keepHistoryFilePath}: ${appendResult.data}`);
3589
3612
  }
3590
3613
  }
3591
3614
  if (postCommandExecFn) {
@@ -3675,7 +3698,7 @@ async function getGitignoresMap({ startDir, stopAtDir }) {
3675
3698
  const stopAtDirParent = path__namespace.dirname(stopAtDir);
3676
3699
  while (currentDir !== stopAtDirParent) {
3677
3700
  const gitignorePath = path__namespace.join(currentDir, '.gitignore');
3678
- const hasGitignore = await fs__namespace$1.access(gitignorePath).then(() => true).catch(() => false);
3701
+ const hasGitignore = await pathExists(gitignorePath);
3679
3702
  if (hasGitignore) {
3680
3703
  const gitignoreContent = await fs__namespace$1.readFile(gitignorePath, 'utf-8');
3681
3704
  gitignores.set(currentDir, ignore().add(gitignoreContent));
@@ -3742,19 +3765,9 @@ async function getContextStatus(params) {
3742
3765
  return 'toDo';
3743
3766
  logger?.verbose(`logResult ${JSON.stringify(logResult.data)}`);
3744
3767
  const logResultOutput = logResult.data.stdout || logResult.data.stderr || '';
3745
- const matchingHashes = logResultOutput
3746
- .split('\n')
3747
- .map((line) => line.trim())
3748
- .filter((line) => !!line)
3749
- .map((line) => {
3750
- const sp = line ? line.indexOf(' ') : -1;
3751
- return {
3752
- hash: sp === -1 ? line : line.slice(0, sp),
3753
- subject: sp === -1 ? '' : line.slice(sp + 1),
3754
- };
3755
- })
3756
- .filter((c) => c.subject === commitMessage)
3757
- .map((c) => c.hash);
3768
+ const matchingHashes = parseGitLogHashSubjectLines(logResultOutput)
3769
+ .filter((entry) => entry.subject === commitMessage)
3770
+ .map((entry) => entry.hash);
3758
3771
  logger?.verbose(`remoteName ${remoteName}`);
3759
3772
  logger?.verbose(`baseBranch ${baseBranch}`);
3760
3773
  logger?.verbose(`commitMessage ${commitMessage}`);
@@ -3967,7 +3980,6 @@ exports.collectStepsForContext = collectStepsForContext;
3967
3980
  exports.contextStatus = contextStatus;
3968
3981
  exports.contextStatusSchema = contextStatusSchema;
3969
3982
  exports.createConsoleLogger = createConsoleLogger;
3970
- exports.decision = decision;
3971
3983
  exports.defaultGitAddCommandFn = defaultGitAddCommandFn;
3972
3984
  exports.defaultGitCommitCommandFn = defaultGitCommitCommandFn;
3973
3985
  exports.defaultGitCommitMessageFn = defaultGitCommitMessageFn;
@@ -3985,12 +3997,12 @@ exports.getCodeBasePaths = getCodeBasePaths;
3985
3997
  exports.getContextStatus = getContextStatus;
3986
3998
  exports.getToDoContextList = getToDoContextList;
3987
3999
  exports.historyFormatFromPath = historyFormatFromPath;
3988
- exports.noopLogger = noopLogger;
4000
+ exports.parseGitLogHashSubjectLines = parseGitLogHashSubjectLines;
4001
+ exports.pathExists = pathExists;
3989
4002
  exports.readHistoryFile = readHistoryFile;
3990
4003
  exports.resolveSpawnExecutable = resolveSpawnExecutable;
3991
4004
  exports.runLump = runLump;
3992
4005
  exports.set = set;
3993
- exports.shellBestEffort = shellBestEffort;
3994
4006
  exports.shellSingleQuote = shellSingleQuote;
3995
4007
  exports.success = success;
3996
4008
  exports.validateContextListNames = validateContextListNames;