@promptbook/cli 0.63.0-4 → 0.63.0-6

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
@@ -1,4 +1,4 @@
1
- <!-- ⚠️ WARNING: This section has been generated so that any manual changes will be overwritten -->
1
+ <!-- ⚠️ WARNING: This code has been generated so that any manual changes will be overwritten -->
2
2
 
3
3
  # ![Promptbook logo - cube with letters P and B](./other/design/logo-h1.png) Promptbook
4
4
 
package/esm/index.es.js CHANGED
@@ -2,7 +2,7 @@ import commander from 'commander';
2
2
  import spaceTrim, { spaceTrim as spaceTrim$1 } from 'spacetrim';
3
3
  import colors from 'colors';
4
4
  import { forTime } from 'waitasecond';
5
- import { readdir, access, constants, readFile, stat, writeFile, mkdir, unlink } from 'fs/promises';
5
+ import { stat, access, constants, readdir, readFile, writeFile, mkdir, unlink } from 'fs/promises';
6
6
  import { join as join$1, dirname } from 'path';
7
7
  import { format } from 'prettier';
8
8
  import parserHtml from 'prettier/parser-html';
@@ -14,10 +14,11 @@ import Anthropic from '@anthropic-ai/sdk';
14
14
  import OpenAI from 'openai';
15
15
  import glob from 'glob-promise';
16
16
 
17
+ // ⚠️ WARNING: This code has been generated so that any manual changes will be overwritten
17
18
  /**
18
19
  * The version of the Promptbook library
19
20
  */
20
- var PROMPTBOOK_VERSION = '0.63.0-3';
21
+ var PROMPTBOOK_VERSION = '0.63.0-5';
21
22
  // TODO: !!!! List here all the versions and annotate + put into script
22
23
 
23
24
  /*! *****************************************************************************
@@ -284,7 +285,14 @@ function deepFreezeWithSameType(objectValue) {
284
285
  *
285
286
  * @private within the repository
286
287
  */
287
- var GENERATOR_WARNING = "\u26A0\uFE0F WARNING: This section has been generated so that any manual changes will be overwritten";
288
+ var GENERATOR_WARNING = "\u26A0\uFE0F WARNING: This code has been generated so that any manual changes will be overwritten";
289
+ /**
290
+ * Warning message for the generated sections and files files
291
+ *
292
+ * @private within the repository
293
+ */
294
+ var GENERATOR_WARNING_BY_PROMPTBOOK_CLI = "\u26A0\uFE0F WARNING: This code has been generated by `@promptbook/cli` so that any manual changes will be overwritten";
295
+ // <- TODO: [🧠] Better system for generator warnings - not always "code" and "by `@promptbook/cli`"
288
296
  /**
289
297
  * The maximum number of iterations for a loops
290
298
  *
@@ -798,7 +806,7 @@ function forEachAsync(array, options, callbackfunction) {
798
806
  });
799
807
  }
800
808
 
801
- var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",promptbookVersion:"0.63.0-3",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT",modelName:"claude-3-opus-20240229"},content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",dependentParameterNames:["knowledgeContent"],resultingParameterName:"knowledgePieces"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[{id:1,promptbookVersion:"0.63.0-3",usage:{price:{value:0},input:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}},output:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}}}}],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md",promptbookVersion:"0.63.0-3",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT",modelName:"claude-3-opus-20240229"},content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",dependentParameterNames:["knowledgePieceContent"],resultingParameterName:"keywords"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[{id:1,promptbookVersion:"0.63.0-3",usage:{price:{value:0},input:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}},output:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}}}}],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.ptbk.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md",promptbookVersion:"0.63.0-3",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT",modelName:"claude-3-opus-20240229"},content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"],resultingParameterName:"title"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[{id:1,promptbookVersion:"0.63.0-3",usage:{price:{value:0},input:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}},output:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}}}}],sourceFile:"./promptbook-collection/prepare-knowledge-title.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.ptbk.md",promptbookVersion:"0.63.0-3",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",modelRequirements:{modelVariant:"CHAT",modelName:"gpt-4-turbo"},content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Sample\n\n```json\n{\n\"modelName\": \"gpt-4o\",\n\"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n\"temperature\": 0.7\n}\n```\n\n## Instructions\n\n### Option `modelName`\n\nPick from the following models:\n\n- {availableModelNames}\n\n### Option `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Option `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",expectFormat:"JSON",dependentParameterNames:["availableModelNames","personaDescription"],resultingParameterName:"modelRequirements"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[{id:1,promptbookVersion:"0.63.0-3",usage:{price:{value:0},input:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}},output:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}}}}],sourceFile:"./promptbook-collection/prepare-persona.ptbk.md"}];
809
+ var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",promptbookVersion:"0.63.0-5",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT",modelName:"claude-3-opus-20240229"},content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",dependentParameterNames:["knowledgeContent"],resultingParameterName:"knowledgePieces"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[{id:1,promptbookVersion:"0.63.0-5",usage:{price:{value:0},input:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}},output:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}}}}],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md",promptbookVersion:"0.63.0-5",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT",modelName:"claude-3-opus-20240229"},content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",dependentParameterNames:["knowledgePieceContent"],resultingParameterName:"keywords"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[{id:1,promptbookVersion:"0.63.0-5",usage:{price:{value:0},input:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}},output:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}}}}],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.ptbk.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md",promptbookVersion:"0.63.0-5",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT",modelName:"claude-3-opus-20240229"},content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"],resultingParameterName:"title"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[{id:1,promptbookVersion:"0.63.0-5",usage:{price:{value:0},input:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}},output:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}}}}],sourceFile:"./promptbook-collection/prepare-knowledge-title.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.ptbk.md",promptbookVersion:"0.63.0-5",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",modelRequirements:{modelVariant:"CHAT",modelName:"gpt-4-turbo"},content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Sample\n\n```json\n{\n\"modelName\": \"gpt-4o\",\n\"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n\"temperature\": 0.7\n}\n```\n\n## Instructions\n\n### Option `modelName`\n\nPick from the following models:\n\n- {availableModelNames}\n\n### Option `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Option `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",expectFormat:"JSON",dependentParameterNames:["availableModelNames","personaDescription"],resultingParameterName:"modelRequirements"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[{id:1,promptbookVersion:"0.63.0-5",usage:{price:{value:0},input:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}},output:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}}}}],sourceFile:"./promptbook-collection/prepare-persona.ptbk.md"}];
802
810
 
803
811
  /**
804
812
  * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
@@ -5898,6 +5906,75 @@ var CollectionError = /** @class */ (function (_super) {
5898
5906
  return CollectionError;
5899
5907
  }(Error));
5900
5908
 
5909
+ /**
5910
+ * Checks if the file exists
5911
+ *
5912
+ * @private within the repository
5913
+ */
5914
+ function isFileExisting(filePath) {
5915
+ return __awaiter(this, void 0, void 0, function () {
5916
+ var isReadAccessAllowed, isFile;
5917
+ return __generator(this, function (_a) {
5918
+ switch (_a.label) {
5919
+ case 0: return [4 /*yield*/, access(filePath, constants.R_OK)
5920
+ .then(function () { return true; })
5921
+ .catch(function () { return false; })];
5922
+ case 1:
5923
+ isReadAccessAllowed = _a.sent();
5924
+ if (!isReadAccessAllowed) {
5925
+ return [2 /*return*/, false];
5926
+ }
5927
+ return [4 /*yield*/, stat(filePath)
5928
+ .then(function (fileStat) { return fileStat.isFile(); })
5929
+ .catch(function () { return false; })];
5930
+ case 2:
5931
+ isFile = _a.sent();
5932
+ return [2 /*return*/, isFile];
5933
+ }
5934
+ });
5935
+ });
5936
+ }
5937
+ /**
5938
+ * Note: [🟢] This code should never be published outside of `@promptbook/node` and `@promptbook/cli` and `@promptbook/cli`
5939
+ * TODO: [🐠] This can be a validator - with variants that return true/false and variants that throw errors with meaningless messages
5940
+ * TODO: [🖇] What about symlinks?
5941
+ */
5942
+
5943
+ /**
5944
+ * Checks if the directory exists
5945
+ *
5946
+ * @private within the repository
5947
+ */
5948
+ function isDirectoryExisting(directoryPath) {
5949
+ return __awaiter(this, void 0, void 0, function () {
5950
+ var isReadAccessAllowed, isDirectory;
5951
+ return __generator(this, function (_a) {
5952
+ switch (_a.label) {
5953
+ case 0: return [4 /*yield*/, access(directoryPath, constants.R_OK)
5954
+ .then(function () { return true; })
5955
+ .catch(function () { return false; })];
5956
+ case 1:
5957
+ isReadAccessAllowed = _a.sent();
5958
+ if (!isReadAccessAllowed) {
5959
+ return [2 /*return*/, false];
5960
+ }
5961
+ return [4 /*yield*/, stat(directoryPath)
5962
+ .then(function (fileStat) { return fileStat.isDirectory(); })
5963
+ .catch(function () { return false; })];
5964
+ case 2:
5965
+ isDirectory = _a.sent();
5966
+ return [2 /*return*/, isDirectory];
5967
+ }
5968
+ });
5969
+ });
5970
+ }
5971
+ /**
5972
+ * Note: [🟢] This code should never be published outside of `@promptbook/node` and `@promptbook/cli` and `@promptbook/cli`
5973
+ * TODO: [🐠] This can be a validator - with variants that return true/false and variants that throw errors with meaningless messages
5974
+ * TODO: [🧠][📂] "directory" vs "folder"
5975
+ * TODO: [🖇] What about symlinks?
5976
+ */
5977
+
5901
5978
  /**
5902
5979
  * Reads all files in the directory
5903
5980
  *
@@ -5912,53 +5989,60 @@ function listAllFiles(path, isRecursive) {
5912
5989
  var e_1, _g;
5913
5990
  return __generator(this, function (_h) {
5914
5991
  switch (_h.label) {
5915
- case 0: return [4 /*yield*/, readdir(path, {
5916
- withFileTypes: true /* Note: This is not working: recursive: isRecursive */,
5917
- })];
5992
+ case 0: return [4 /*yield*/, isDirectoryExisting(path)];
5918
5993
  case 1:
5994
+ if (!(_h.sent())) {
5995
+ throw new Error("Directory \"".concat(path, "\" does not exist or is not readable"));
5996
+ // <- TODO: Use some custom error class
5997
+ }
5998
+ return [4 /*yield*/, readdir(path, {
5999
+ withFileTypes: true /* Note: This is not working: recursive: isRecursive */,
6000
+ })];
6001
+ case 2:
5919
6002
  dirents = _h.sent();
5920
6003
  fileNames = dirents.filter(function (dirent) { return dirent.isFile(); }).map(function (_a) {
5921
6004
  var name = _a.name;
5922
6005
  return join(path, name);
5923
6006
  });
5924
- if (!isRecursive) return [3 /*break*/, 9];
5925
- _h.label = 2;
5926
- case 2:
5927
- _h.trys.push([2, 7, 8, 9]);
5928
- _a = __values(dirents.filter(function (dirent) { return dirent.isDirectory(); })), _b = _a.next();
6007
+ if (!isRecursive) return [3 /*break*/, 10];
5929
6008
  _h.label = 3;
5930
6009
  case 3:
5931
- if (!!_b.done) return [3 /*break*/, 6];
6010
+ _h.trys.push([3, 8, 9, 10]);
6011
+ _a = __values(dirents.filter(function (dirent) { return dirent.isDirectory(); })), _b = _a.next();
6012
+ _h.label = 4;
6013
+ case 4:
6014
+ if (!!_b.done) return [3 /*break*/, 7];
5932
6015
  dirent = _b.value;
5933
6016
  subPath = join(path, dirent.name);
5934
6017
  _d = (_c = fileNames.push).apply;
5935
6018
  _e = [fileNames];
5936
6019
  _f = [[]];
5937
6020
  return [4 /*yield*/, listAllFiles(subPath, isRecursive)];
5938
- case 4:
5939
- _d.apply(_c, _e.concat([__spreadArray.apply(void 0, _f.concat([__read.apply(void 0, [(_h.sent())]), false]))]));
5940
- _h.label = 5;
5941
6021
  case 5:
6022
+ _d.apply(_c, _e.concat([__spreadArray.apply(void 0, _f.concat([__read.apply(void 0, [(_h.sent())]), false]))]));
6023
+ _h.label = 6;
6024
+ case 6:
5942
6025
  _b = _a.next();
5943
- return [3 /*break*/, 3];
5944
- case 6: return [3 /*break*/, 9];
5945
- case 7:
6026
+ return [3 /*break*/, 4];
6027
+ case 7: return [3 /*break*/, 10];
6028
+ case 8:
5946
6029
  e_1_1 = _h.sent();
5947
6030
  e_1 = { error: e_1_1 };
5948
- return [3 /*break*/, 9];
5949
- case 8:
6031
+ return [3 /*break*/, 10];
6032
+ case 9:
5950
6033
  try {
5951
6034
  if (_b && !_b.done && (_g = _a.return)) _g.call(_a);
5952
6035
  }
5953
6036
  finally { if (e_1) throw e_1.error; }
5954
6037
  return [7 /*endfinally*/];
5955
- case 9: return [2 /*return*/, fileNames];
6038
+ case 10: return [2 /*return*/, fileNames];
5956
6039
  }
5957
6040
  });
5958
6041
  });
5959
6042
  }
5960
6043
  /**
5961
6044
  * Note: [🟢] This code should never be published outside of `@promptbook/node` and `@promptbook/cli` and `@promptbook/cli`
6045
+ * TODO: [🖇] What about symlinks?
5962
6046
  */
5963
6047
 
5964
6048
  /**
@@ -6060,7 +6144,7 @@ function createCollectionFromPromise(promptbookSourcesPromiseOrFactory) {
6060
6144
  */
6061
6145
  function createCollectionFromDirectory(path, options) {
6062
6146
  return __awaiter(this, void 0, void 0, function () {
6063
- var makedLibraryFilePath, makedLibraryFileExists, _a, _b, isRecursive, _c, isVerbose, _d, isLazyLoaded, _e, isCrashedOnError, collection;
6147
+ var makedLibraryFilePath, _a, _b, isRecursive, _c, isVerbose, _d, isLazyLoaded, _e, isCrashedOnError, collection;
6064
6148
  var _this = this;
6065
6149
  return __generator(this, function (_f) {
6066
6150
  switch (_f.label) {
@@ -6069,12 +6153,9 @@ function createCollectionFromDirectory(path, options) {
6069
6153
  throw new Error('Function `createCollectionFromDirectory` can only be run in Node.js environment because it reads the file system.');
6070
6154
  }
6071
6155
  makedLibraryFilePath = join$1(path, "".concat(PIPELINE_COLLECTION_BASE_FILENAME, ".json"));
6072
- return [4 /*yield*/, access(makedLibraryFilePath, constants.R_OK)
6073
- .then(function () { return true; })
6074
- .catch(function () { return false; })];
6156
+ return [4 /*yield*/, isFileExisting(makedLibraryFilePath)];
6075
6157
  case 1:
6076
- makedLibraryFileExists = _f.sent();
6077
- if (!makedLibraryFileExists) {
6158
+ if (!(_f.sent())) {
6078
6159
  console.info(colors.yellow("Tip: Prebuild your pipeline collection (file with supposed prebuild ".concat(makedLibraryFilePath, " not found) with CLI util \"ptbk make\" to speed up the collection creation.")));
6079
6160
  }
6080
6161
  else {
@@ -6238,6 +6319,7 @@ function createCollectionFromDirectory(path, options) {
6238
6319
  }
6239
6320
  /**
6240
6321
  * Note: [🟢] This code should never be published outside of `@promptbook/node` and `@promptbook/cli` and `@promptbook/cli`
6322
+ * TODO: [🖇] What about symlinks? Maybe option isSymlinksFollowed
6241
6323
  */
6242
6324
 
6243
6325
  /**
@@ -6343,17 +6425,14 @@ var FilesStorage = /** @class */ (function () {
6343
6425
  */
6344
6426
  FilesStorage.prototype.getItem = function (key) {
6345
6427
  return __awaiter(this, void 0, void 0, function () {
6346
- var filename, isFileExisting, fileContent, value;
6428
+ var filename, fileContent, value;
6347
6429
  return __generator(this, function (_a) {
6348
6430
  switch (_a.label) {
6349
6431
  case 0:
6350
6432
  filename = this.getFilenameForKey(key);
6351
- return [4 /*yield*/, stat(filename)
6352
- .then(function (fileStat) { return fileStat.isFile(); })
6353
- .catch(function () { return false; })];
6433
+ return [4 /*yield*/, isFileExisting(filename)];
6354
6434
  case 1:
6355
- isFileExisting = _a.sent();
6356
- if (!isFileExisting) {
6435
+ if (!(_a.sent())) {
6357
6436
  return [2 /*return*/, null];
6358
6437
  }
6359
6438
  return [4 /*yield*/, readFile(filename, 'utf-8')];
@@ -7710,8 +7789,8 @@ function initializeMakeCommand(program) {
7710
7789
  var _this = this;
7711
7790
  var makeCommand = program.command('make');
7712
7791
  makeCommand.description(spaceTrim("\n Makes a new pipeline collection in given folder\n "));
7713
- makeCommand.argument('<path>', 'Path to promptbook directory');
7714
- makeCommand.option('--project-name', "Name of the project for whom collection is", 'Project');
7792
+ makeCommand.argument('<path>', 'Path to promptbook directory', './promptbook-collection');
7793
+ makeCommand.option('--project-name', "Name of the project for whom collection is", 'Untitled Promptbook project');
7715
7794
  makeCommand.option('-f, --format <format>', spaceTrim("\n Output format of builded collection \"javascript\", \"typescript\" or \"json\"\n\n Note: You can use multiple formats separated by comma\n "), 'javascript' /* <- Note: [🏳‍🌈] */);
7716
7795
  makeCommand.option('--no-validation', "Do not validate logic of pipelines in collection", true);
7717
7796
  makeCommand.option('--validation', "Types of validations separated by comma (options \"logic\",\"imports\")", 'logic,imports');
@@ -7738,7 +7817,7 @@ function initializeMakeCommand(program) {
7738
7817
  .map(function (_) { return _.trim(); })
7739
7818
  .filter(function (_) { return _ !== ''; });
7740
7819
  if (outFile !== PIPELINE_COLLECTION_BASE_FILENAME && formats.length !== 1) {
7741
- console.error(colors.red("You can use only one format when saving to a file"));
7820
+ console.error(colors.red("You can only use one format if you specify --out-file"));
7742
7821
  process.exit(1);
7743
7822
  }
7744
7823
  llmTools = getLlmToolsForCli({
@@ -7837,23 +7916,29 @@ function initializeMakeCommand(program) {
7837
7916
  });
7838
7917
  }); };
7839
7918
  if (!formats.includes('json')) return [3 /*break*/, 19];
7919
+ formats = formats.filter(function (format) { return format !== 'json'; });
7840
7920
  return [4 /*yield*/, saveFile('json', collectionJsonString)];
7841
7921
  case 18:
7842
7922
  _f.sent();
7843
7923
  _f.label = 19;
7844
7924
  case 19:
7845
- if (!formats.includes('javascript')) return [3 /*break*/, 21];
7846
- return [4 /*yield*/, saveFile('js', spaceTrim("\n import { createCollectionFromJson } from '@promptbook/core';\n\n /**\n * Pipeline collection for ".concat(projectName, "\n *\n * @private internal cache for `getPipelineCollection`\n */\n let pipelineCollection = null;\n\n\n /**\n * Get pipeline collection for ").concat(projectName, "\n *\n * @returns {PipelineCollection} Library of promptbooks for ").concat(projectName, "\n * @generated by `@promptbook/cli`\n */\n export function getPipelineCollection(){\n if(pipelineCollection===null){\n pipelineCollection = createCollectionFromJson(").concat(collectionJsonString.substring(1, collectionJsonString.length - 1), ");\n }\n\n return pipelineCollection;\n }\n ") + '\n'))];
7925
+ if (!(formats.includes('javascript') || formats.includes('js'))) return [3 /*break*/, 21];
7926
+ formats = formats.filter(function (format) { return format !== 'javascript' && format !== 'js'; });
7927
+ return [4 /*yield*/, saveFile('js', spaceTrim(function (block) { return "\n // ".concat(block(GENERATOR_WARNING_BY_PROMPTBOOK_CLI), "\n\n import { createCollectionFromJson } from '@promptbook/core';\n\n /**\n * Pipeline collection for ").concat(projectName, "\n *\n * ").concat(block(GENERATOR_WARNING_BY_PROMPTBOOK_CLI), "\n *\n * @private internal cache for `getPipelineCollection`\n */\n let pipelineCollection = null;\n\n\n /**\n * Get pipeline collection for ").concat(projectName, "\n *\n * ").concat(block(GENERATOR_WARNING_BY_PROMPTBOOK_CLI), "\n *\n * @returns {PipelineCollection} Library of promptbooks for ").concat(projectName, "\n */\n export function getPipelineCollection(){\n if(pipelineCollection===null){\n pipelineCollection = createCollectionFromJson(").concat(block(collectionJsonString), ");\n }\n\n return pipelineCollection;\n }\n "); }))];
7847
7928
  case 20:
7848
- _f.sent();
7929
+ (_f.sent()) + '\n';
7849
7930
  _f.label = 21;
7850
7931
  case 21:
7851
- if (!formats.includes('typescript')) return [3 /*break*/, 23];
7852
- return [4 /*yield*/, saveFile('ts', spaceTrim("\n import { createCollectionFromJson } from '@promptbook/core';\n import type { PipelineCollection } from '@promptbook/types';\n\n /**\n * Pipeline collection for ".concat(projectName, "\n *\n * @private internal cache for `getPipelineCollection`\n */\n let pipelineCollection: null | PipelineCollection = null;\n\n\n /**\n * Get pipeline collection for ").concat(projectName, "\n *\n * @returns {PipelineCollection} Library of promptbooks for ").concat(projectName, "\n * @generated by `@promptbook/cli`\n */\n export function getPipelineCollection(): PipelineCollection{\n if(pipelineCollection===null){\n pipelineCollection = createCollectionFromJson(").concat(collectionJsonString.substring(1, collectionJsonString.length - 1), ");\n }\n\n return pipelineCollection as PipelineCollection;\n }\n ") + '\n'))];
7932
+ if (!(formats.includes('typescript') || formats.includes('ts'))) return [3 /*break*/, 23];
7933
+ formats = formats.filter(function (format) { return format !== 'typescript' && format !== 'ts'; });
7934
+ return [4 /*yield*/, saveFile('ts', spaceTrim(function (block) { return "\n // ".concat(block(GENERATOR_WARNING_BY_PROMPTBOOK_CLI), "\n\n import { createCollectionFromJson } from '@promptbook/core';\n import type { PipelineCollection } from '@promptbook/types';\n\n /**\n * Pipeline collection for ").concat(projectName, "\n *\n * ").concat(block(GENERATOR_WARNING_BY_PROMPTBOOK_CLI), "\n *\n * @private internal cache for `getPipelineCollection`\n */\n let pipelineCollection: null | PipelineCollection = null;\n\n\n /**\n * Get pipeline collection for ").concat(projectName, "\n *\n * ").concat(block(GENERATOR_WARNING_BY_PROMPTBOOK_CLI), "\n *\n * @returns {PipelineCollection} Library of promptbooks for ").concat(projectName, "\n */\n export function getPipelineCollection(): PipelineCollection{\n if(pipelineCollection===null){\n pipelineCollection = createCollectionFromJson(").concat(block(collectionJsonString), ");\n }\n\n return pipelineCollection as PipelineCollection;\n }\n "); }) + '\n')];
7853
7935
  case 22:
7854
7936
  _f.sent();
7855
7937
  _f.label = 23;
7856
7938
  case 23:
7939
+ if (formats.length > 0) {
7940
+ console.warn(colors.yellow("Format ".concat(formats.join(' and '), " is not supported")));
7941
+ }
7857
7942
  if (isVerbose) {
7858
7943
  console.info(colors.green("Collection builded"));
7859
7944
  console.info(colors.cyan(usageToHuman(llmTools.getTotalUsage())));
@@ -7866,7 +7951,9 @@ function initializeMakeCommand(program) {
7866
7951
  });
7867
7952
  }
7868
7953
  /**
7954
+ * TODO: [0] DRY Javascript and typescript - Maybe make ONLY typescript and for javascript just remove types
7869
7955
  * Note: [🟡] This code should never be published outside of `@promptbook/cli`
7956
+ * TODO: [🖇] What about symlinks? Maybe flag --follow-symlinks
7870
7957
  */
7871
7958
 
7872
7959
  /**
@@ -8146,6 +8233,7 @@ function initializePrettifyCommand(program) {
8146
8233
  }
8147
8234
  /**
8148
8235
  * Note: [🟡] This code should never be published outside of `@promptbook/cli`
8236
+ * TODO: [🖇] What about symlinks? Maybe flag --follow-symlinks
8149
8237
  */
8150
8238
 
8151
8239
  /**