@promptbook/cli 0.112.0-35 → 0.112.0-36
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 +115 -18
- package/esm/index.es.js +525 -85
- package/esm/index.es.js.map +1 -1
- package/esm/src/cli/cli-commands/coder/boilerplateTemplates.d.ts +127 -0
- package/esm/src/cli/cli-commands/coder/boilerplateTemplates.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/coder/generate-boilerplates.d.ts +10 -0
- package/esm/src/cli/cli-commands/coder/init.d.ts +38 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +523 -83
- package/umd/index.umd.js.map +1 -1
- package/umd/src/cli/cli-commands/coder/boilerplateTemplates.d.ts +127 -0
- package/umd/src/cli/cli-commands/coder/boilerplateTemplates.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/coder/generate-boilerplates.d.ts +10 -0
- package/umd/src/cli/cli-commands/coder/init.d.ts +38 -0
- package/umd/src/version.d.ts +1 -1
package/esm/index.es.js
CHANGED
|
@@ -2,10 +2,10 @@ import colors from 'colors';
|
|
|
2
2
|
import commander, { Option } from 'commander';
|
|
3
3
|
import _spaceTrim, { spaceTrim as spaceTrim$1 } from 'spacetrim';
|
|
4
4
|
import * as fs from 'fs';
|
|
5
|
-
import { writeFileSync, readFileSync, existsSync } from 'fs';
|
|
5
|
+
import { mkdirSync, writeFileSync, readFileSync, existsSync } from 'fs';
|
|
6
6
|
import * as path from 'path';
|
|
7
7
|
import { join, basename, dirname, isAbsolute, relative, extname, resolve } from 'path';
|
|
8
|
-
import {
|
|
8
|
+
import { writeFile, readFile, stat, mkdir, access, constants, readdir, watch, unlink, rm, rename, rmdir } from 'fs/promises';
|
|
9
9
|
import { forTime, forEver } from 'waitasecond';
|
|
10
10
|
import prompts from 'prompts';
|
|
11
11
|
import * as dotenv from 'dotenv';
|
|
@@ -57,7 +57,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
57
57
|
* @generated
|
|
58
58
|
* @see https://github.com/webgptorg/promptbook
|
|
59
59
|
*/
|
|
60
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
60
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-36';
|
|
61
61
|
/**
|
|
62
62
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
63
63
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -1697,6 +1697,220 @@ function $initializeCoderFindRefactorCandidatesCommand(program) {
|
|
|
1697
1697
|
// Note: [🟡] Code for CLI command [find-refactor-candidates](src/cli/cli-commands/coder/find-refactor-candidates.ts) should never be published outside of `@promptbook/cli`
|
|
1698
1698
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
1699
1699
|
|
|
1700
|
+
/**
|
|
1701
|
+
* This error indicates that promptbook not found in the collection
|
|
1702
|
+
*
|
|
1703
|
+
* @public exported from `@promptbook/core`
|
|
1704
|
+
*/
|
|
1705
|
+
class NotFoundError extends Error {
|
|
1706
|
+
constructor(message) {
|
|
1707
|
+
super(message);
|
|
1708
|
+
this.name = 'NotFoundError';
|
|
1709
|
+
Object.setPrototypeOf(this, NotFoundError.prototype);
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
/**
|
|
1714
|
+
* Relative path to the root prompts directory used by Promptbook coder utilities.
|
|
1715
|
+
*
|
|
1716
|
+
* @private internal utility of `ptbk coder`
|
|
1717
|
+
*/
|
|
1718
|
+
const PROMPTS_DIRECTORY_PATH = 'prompts';
|
|
1719
|
+
/**
|
|
1720
|
+
* Relative path to the archive directory used by `coder verify`.
|
|
1721
|
+
*
|
|
1722
|
+
* @private internal utility of `ptbk coder`
|
|
1723
|
+
*/
|
|
1724
|
+
const PROMPTS_DONE_DIRECTORY_PATH = join(PROMPTS_DIRECTORY_PATH, 'done');
|
|
1725
|
+
/**
|
|
1726
|
+
* Relative path to the project-owned boilerplate templates directory.
|
|
1727
|
+
*
|
|
1728
|
+
* @private internal utility of `ptbk coder`
|
|
1729
|
+
*/
|
|
1730
|
+
const PROMPTS_TEMPLATES_DIRECTORY_PATH = join(PROMPTS_DIRECTORY_PATH, 'templates');
|
|
1731
|
+
/**
|
|
1732
|
+
* Built-in boilerplate templates shared by `coder init` and `coder generate-boilerplates`.
|
|
1733
|
+
*/
|
|
1734
|
+
const DEFAULT_CODER_PROMPT_TEMPLATE_DEFINITIONS = [
|
|
1735
|
+
{
|
|
1736
|
+
id: 'common',
|
|
1737
|
+
relativeFilePath: join(PROMPTS_TEMPLATES_DIRECTORY_PATH, 'common.md'),
|
|
1738
|
+
slugPrefix: null,
|
|
1739
|
+
content: buildCoderPromptTemplateContent([
|
|
1740
|
+
'- @@@',
|
|
1741
|
+
'- Keep in mind the DRY _(don\'t repeat yourself)_ principle.',
|
|
1742
|
+
'- Do a proper analysis of the current functionality before you start implementing.',
|
|
1743
|
+
'- Add the changes into the [changelog](./changelog/_current-preversion.md)',
|
|
1744
|
+
]),
|
|
1745
|
+
},
|
|
1746
|
+
{
|
|
1747
|
+
id: 'agents-server',
|
|
1748
|
+
relativeFilePath: join(PROMPTS_TEMPLATES_DIRECTORY_PATH, 'agents-server.md'),
|
|
1749
|
+
slugPrefix: 'agents-server',
|
|
1750
|
+
content: buildCoderPromptTemplateContent([
|
|
1751
|
+
'- @@@',
|
|
1752
|
+
'- Keep in mind the DRY _(don\'t repeat yourself)_ principle.',
|
|
1753
|
+
'- Do a proper analysis of the current functionality before you start implementing.',
|
|
1754
|
+
'- You are working with the [Agents Server](apps/agents-server)',
|
|
1755
|
+
'- If you need to do the database migration, do it',
|
|
1756
|
+
'- Add the changes into the [changelog](changelog/_current-preversion.md)',
|
|
1757
|
+
]),
|
|
1758
|
+
},
|
|
1759
|
+
];
|
|
1760
|
+
/**
|
|
1761
|
+
* Lists the built-in coder boilerplate templates.
|
|
1762
|
+
*
|
|
1763
|
+
* @private internal utility of `ptbk coder`
|
|
1764
|
+
*/
|
|
1765
|
+
function getDefaultCoderPromptTemplateDefinitions() {
|
|
1766
|
+
return DEFAULT_CODER_PROMPT_TEMPLATE_DEFINITIONS;
|
|
1767
|
+
}
|
|
1768
|
+
/**
|
|
1769
|
+
* Resolves one built-in coder boilerplate template definition by its stable identifier.
|
|
1770
|
+
*
|
|
1771
|
+
* @private internal utility of `ptbk coder`
|
|
1772
|
+
*/
|
|
1773
|
+
function getDefaultCoderPromptTemplateDefinition(template) {
|
|
1774
|
+
const definition = getDefaultCoderPromptTemplateDefinitionOrUndefined(template);
|
|
1775
|
+
if (!definition) {
|
|
1776
|
+
throw new NotFoundError(`Built-in coder prompt template \`${template}\` was not found.`);
|
|
1777
|
+
}
|
|
1778
|
+
return definition;
|
|
1779
|
+
}
|
|
1780
|
+
/**
|
|
1781
|
+
* Ensures the default project-owned coder template files exist without overwriting user customizations.
|
|
1782
|
+
*
|
|
1783
|
+
* @private internal utility of `ptbk coder`
|
|
1784
|
+
*/
|
|
1785
|
+
async function ensureDefaultCoderPromptTemplateFiles(projectPath) {
|
|
1786
|
+
const ensuredTemplateFiles = [];
|
|
1787
|
+
for (const definition of DEFAULT_CODER_PROMPT_TEMPLATE_DEFINITIONS) {
|
|
1788
|
+
const absoluteTemplatePath = join(projectPath, definition.relativeFilePath);
|
|
1789
|
+
if (await isExistingFile$1(absoluteTemplatePath)) {
|
|
1790
|
+
ensuredTemplateFiles.push({
|
|
1791
|
+
id: definition.id,
|
|
1792
|
+
relativeFilePath: definition.relativeFilePath,
|
|
1793
|
+
status: 'unchanged',
|
|
1794
|
+
});
|
|
1795
|
+
continue;
|
|
1796
|
+
}
|
|
1797
|
+
await writeFile(absoluteTemplatePath, `${definition.content}\n`, 'utf-8');
|
|
1798
|
+
ensuredTemplateFiles.push({
|
|
1799
|
+
id: definition.id,
|
|
1800
|
+
relativeFilePath: definition.relativeFilePath,
|
|
1801
|
+
status: 'created',
|
|
1802
|
+
});
|
|
1803
|
+
}
|
|
1804
|
+
return ensuredTemplateFiles;
|
|
1805
|
+
}
|
|
1806
|
+
/**
|
|
1807
|
+
* Resolves the template requested by `coder generate-boilerplates`.
|
|
1808
|
+
*
|
|
1809
|
+
* Supports three modes:
|
|
1810
|
+
* - omitted option => built-in `common`
|
|
1811
|
+
* - built-in alias => one of the shared default templates
|
|
1812
|
+
* - relative path => markdown template file resolved from the project root
|
|
1813
|
+
*
|
|
1814
|
+
* @private internal utility of `ptbk coder`
|
|
1815
|
+
*/
|
|
1816
|
+
async function resolveCoderPromptTemplate({ projectPath, templateOption, }) {
|
|
1817
|
+
const normalizedTemplateOption = normalizeCoderPromptTemplateOption(templateOption);
|
|
1818
|
+
if (!normalizedTemplateOption) {
|
|
1819
|
+
return createResolvedBuiltInCoderPromptTemplate('common');
|
|
1820
|
+
}
|
|
1821
|
+
const builtInTemplateDefinition = getDefaultCoderPromptTemplateDefinitionOrUndefined(normalizedTemplateOption);
|
|
1822
|
+
if (builtInTemplateDefinition) {
|
|
1823
|
+
return createResolvedBuiltInCoderPromptTemplate(builtInTemplateDefinition.id);
|
|
1824
|
+
}
|
|
1825
|
+
const absoluteTemplatePath = join(projectPath, normalizedTemplateOption);
|
|
1826
|
+
try {
|
|
1827
|
+
const content = (await readFile(absoluteTemplatePath, 'utf-8')).trim();
|
|
1828
|
+
return {
|
|
1829
|
+
identifier: normalizedTemplateOption,
|
|
1830
|
+
relativeFilePath: normalizedTemplateOption,
|
|
1831
|
+
content,
|
|
1832
|
+
slugPrefix: deriveCoderPromptSlugPrefix(normalizedTemplateOption),
|
|
1833
|
+
};
|
|
1834
|
+
}
|
|
1835
|
+
catch (error) {
|
|
1836
|
+
if (isNodeJsErrorWithCode(error, 'ENOENT')) {
|
|
1837
|
+
throw new NotFoundError(spaceTrim$1(`
|
|
1838
|
+
Prompt boilerplate template was not found at \`${normalizedTemplateOption}\`.
|
|
1839
|
+
|
|
1840
|
+
- The \`--template\` option resolves paths relative to the current project root: \`${projectPath}\`
|
|
1841
|
+
- Run \`ptbk coder init\` to create the default project templates in \`${PROMPTS_TEMPLATES_DIRECTORY_PATH}\`
|
|
1842
|
+
- Or omit \`--template\` / use the built-in aliases \`common\` or \`agents-server\`
|
|
1843
|
+
`));
|
|
1844
|
+
}
|
|
1845
|
+
throw error;
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
/**
|
|
1849
|
+
* Normalizes one raw `--template` option to either a trimmed string or `undefined`.
|
|
1850
|
+
*/
|
|
1851
|
+
function normalizeCoderPromptTemplateOption(templateOption) {
|
|
1852
|
+
const normalizedTemplateOption = templateOption === null || templateOption === void 0 ? void 0 : templateOption.trim();
|
|
1853
|
+
if (!normalizedTemplateOption) {
|
|
1854
|
+
return undefined;
|
|
1855
|
+
}
|
|
1856
|
+
return normalizedTemplateOption;
|
|
1857
|
+
}
|
|
1858
|
+
/**
|
|
1859
|
+
* Resolves one built-in template definition without throwing.
|
|
1860
|
+
*/
|
|
1861
|
+
function getDefaultCoderPromptTemplateDefinitionOrUndefined(template) {
|
|
1862
|
+
return DEFAULT_CODER_PROMPT_TEMPLATE_DEFINITIONS.find((definition) => definition.id === template);
|
|
1863
|
+
}
|
|
1864
|
+
/**
|
|
1865
|
+
* Builds stable markdown content for one coder prompt template without indentation drift.
|
|
1866
|
+
*/
|
|
1867
|
+
function buildCoderPromptTemplateContent(lines) {
|
|
1868
|
+
return lines.join('\n');
|
|
1869
|
+
}
|
|
1870
|
+
/**
|
|
1871
|
+
* Creates a fully resolved template payload from one built-in definition.
|
|
1872
|
+
*/
|
|
1873
|
+
function createResolvedBuiltInCoderPromptTemplate(template) {
|
|
1874
|
+
const definition = getDefaultCoderPromptTemplateDefinition(template);
|
|
1875
|
+
return {
|
|
1876
|
+
identifier: definition.id,
|
|
1877
|
+
relativeFilePath: definition.relativeFilePath,
|
|
1878
|
+
content: definition.content,
|
|
1879
|
+
slugPrefix: definition.slugPrefix,
|
|
1880
|
+
};
|
|
1881
|
+
}
|
|
1882
|
+
/**
|
|
1883
|
+
* Derives the filename slug prefix from a project-relative template path.
|
|
1884
|
+
*/
|
|
1885
|
+
function deriveCoderPromptSlugPrefix(relativeTemplatePath) {
|
|
1886
|
+
const templateBasename = basename(relativeTemplatePath)
|
|
1887
|
+
.replace(/\.[^.]+$/u, '')
|
|
1888
|
+
.replace(/\.template$/u, '');
|
|
1889
|
+
if (templateBasename === 'common') {
|
|
1890
|
+
return null;
|
|
1891
|
+
}
|
|
1892
|
+
return templateBasename;
|
|
1893
|
+
}
|
|
1894
|
+
/**
|
|
1895
|
+
* Checks whether the provided error object exposes a specific Node.js `code`.
|
|
1896
|
+
*/
|
|
1897
|
+
function isNodeJsErrorWithCode(error, code) {
|
|
1898
|
+
return typeof error === 'object' && error !== null && 'code' in error && error.code === code;
|
|
1899
|
+
}
|
|
1900
|
+
/**
|
|
1901
|
+
* Checks whether a path exists and is a file.
|
|
1902
|
+
*/
|
|
1903
|
+
async function isExistingFile$1(path) {
|
|
1904
|
+
try {
|
|
1905
|
+
return (await stat(path)).isFile();
|
|
1906
|
+
}
|
|
1907
|
+
catch (_a) {
|
|
1908
|
+
return false;
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
// Note: [🟡] Code for coder boilerplate templates [boilerplateTemplates](src/cli/cli-commands/coder/boilerplateTemplates.ts) should never be published outside of `@promptbook/cli`
|
|
1912
|
+
// Note: [💞] Ignore a discrepancy between file name and exported helper names
|
|
1913
|
+
|
|
1700
1914
|
/**
|
|
1701
1915
|
* Initializes `coder generate-boilerplates` command for Promptbook CLI utilities
|
|
1702
1916
|
*
|
|
@@ -1710,12 +1924,21 @@ function $initializeCoderGenerateBoilerplatesCommand(program) {
|
|
|
1710
1924
|
Generate prompt boilerplate files with unique emoji tags
|
|
1711
1925
|
`));
|
|
1712
1926
|
command.option('--count <count>', `Number of prompt boilerplate files to generate`, '5');
|
|
1713
|
-
command.option('--template <template>', `
|
|
1927
|
+
command.option('--template <template>', spaceTrim$1(`
|
|
1928
|
+
Prompt template to use.
|
|
1929
|
+
|
|
1930
|
+
Accepts either a built-in alias (${getDefaultCoderPromptTemplateDefinitions()
|
|
1931
|
+
.map(({ id }) => id)
|
|
1932
|
+
.join(', ')}) or a markdown file path relative to the current project root.
|
|
1933
|
+
`));
|
|
1714
1934
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
1715
1935
|
const { count: countOption, template: templateOption } = cliOptions;
|
|
1716
1936
|
const filesCount = parseFilesCount(countOption);
|
|
1717
|
-
|
|
1718
|
-
|
|
1937
|
+
await generatePromptBoilerplate({
|
|
1938
|
+
projectPath: process.cwd(),
|
|
1939
|
+
filesCount,
|
|
1940
|
+
templateOption,
|
|
1941
|
+
});
|
|
1719
1942
|
return process.exit(0);
|
|
1720
1943
|
}));
|
|
1721
1944
|
}
|
|
@@ -1724,14 +1947,15 @@ function $initializeCoderGenerateBoilerplatesCommand(program) {
|
|
|
1724
1947
|
*
|
|
1725
1948
|
* @private internal function of `generatePromptBoilerplate` command
|
|
1726
1949
|
*/
|
|
1727
|
-
async function generatePromptBoilerplate({ filesCount,
|
|
1950
|
+
async function generatePromptBoilerplate({ projectPath, filesCount, templateOption, }) {
|
|
1728
1951
|
// Note: Import these dynamically to avoid circular dependencies and keep CLI fast
|
|
1729
1952
|
const { buildPromptFilename, getPromptNumbering } = await Promise.resolve().then(function () { return getPromptNumbering$1; });
|
|
1730
1953
|
const { formatPromptEmojiTag, getFreshPromptEmojiTags } = await Promise.resolve().then(function () { return promptEmojiTags; });
|
|
1731
1954
|
console.info(`🚀 Generate prompt boilerplate files`);
|
|
1732
|
-
|
|
1955
|
+
mkdirSync(join(projectPath, PROMPTS_DIRECTORY_PATH), { recursive: true });
|
|
1956
|
+
const promptTemplate = await resolveCoderPromptTemplate({ projectPath, templateOption });
|
|
1733
1957
|
const promptNumbering = await getPromptNumbering({
|
|
1734
|
-
promptsDir: join(
|
|
1958
|
+
promptsDir: join(projectPath, PROMPTS_DIRECTORY_PATH),
|
|
1735
1959
|
step: 10,
|
|
1736
1960
|
ignoreGlobs: ['**/node_modules/**'],
|
|
1737
1961
|
});
|
|
@@ -1740,7 +1964,7 @@ async function generatePromptBoilerplate({ filesCount, template, }) {
|
|
|
1740
1964
|
console.info(colors.blue(`Highest existing number for ${promptNumbering.datePrefix} found: ${highestNumberFormatted}`));
|
|
1741
1965
|
const { availableCount, selectedEmojis } = await getFreshPromptEmojiTags({
|
|
1742
1966
|
count: filesCount,
|
|
1743
|
-
rootDir:
|
|
1967
|
+
rootDir: projectPath,
|
|
1744
1968
|
});
|
|
1745
1969
|
console.info(colors.green(`Found ${availableCount} available fresh emojis`));
|
|
1746
1970
|
console.info(colors.green(`Selected emojis: ${selectedEmojis.map((emoji) => formatPromptEmojiTag(emoji)).join(' ')}`));
|
|
@@ -1752,8 +1976,9 @@ async function generatePromptBoilerplate({ filesCount, template, }) {
|
|
|
1752
1976
|
const number = promptNumbering.startNumber + i * promptNumbering.step;
|
|
1753
1977
|
const title = titles[i % titles.length];
|
|
1754
1978
|
const emoji = selectedEmojis[i];
|
|
1755
|
-
const filename = buildPromptFilename(promptNumbering.datePrefix, number, buildPromptSlug$1(
|
|
1756
|
-
const filepath = join(
|
|
1979
|
+
const filename = buildPromptFilename(promptNumbering.datePrefix, number, buildPromptSlug$1(promptTemplate.slugPrefix, title));
|
|
1980
|
+
const filepath = join(PROMPTS_DIRECTORY_PATH, filename);
|
|
1981
|
+
const absoluteFilepath = join(projectPath, filepath);
|
|
1757
1982
|
const emojiTag = formatPromptEmojiTag(emoji);
|
|
1758
1983
|
const one = spaceTrim$1((block) => `
|
|
1759
1984
|
|
|
@@ -1761,7 +1986,7 @@ async function generatePromptBoilerplate({ filesCount, template, }) {
|
|
|
1761
1986
|
|
|
1762
1987
|
${emojiTag} ${title}
|
|
1763
1988
|
|
|
1764
|
-
${block(
|
|
1989
|
+
${block(promptTemplate.content)}
|
|
1765
1990
|
`);
|
|
1766
1991
|
const content = spaceTrim$1((block) => `
|
|
1767
1992
|
|
|
@@ -1782,6 +2007,7 @@ async function generatePromptBoilerplate({ filesCount, template, }) {
|
|
|
1782
2007
|
`);
|
|
1783
2008
|
filesToCreate.push({
|
|
1784
2009
|
filepath,
|
|
2010
|
+
absoluteFilepath,
|
|
1785
2011
|
filename,
|
|
1786
2012
|
content,
|
|
1787
2013
|
emoji,
|
|
@@ -1791,7 +2017,7 @@ async function generatePromptBoilerplate({ filesCount, template, }) {
|
|
|
1791
2017
|
// Create the files
|
|
1792
2018
|
console.info(colors.yellow(`Creating ${filesToCreate.length} files:`));
|
|
1793
2019
|
for (const file of filesToCreate) {
|
|
1794
|
-
writeFileSync(file.
|
|
2020
|
+
writeFileSync(file.absoluteFilepath, file.content, 'utf-8');
|
|
1795
2021
|
console.info(colors.green(`✓ Created: ${file.filename} with ${formatPromptEmojiTag(file.emoji)}`));
|
|
1796
2022
|
}
|
|
1797
2023
|
console.info(colors.bgGreen(` Successfully created ${filesToCreate.length} prompt boilerplate files! `));
|
|
@@ -1809,52 +2035,34 @@ function parseFilesCount(countOption) {
|
|
|
1809
2035
|
}
|
|
1810
2036
|
return Math.floor(filesCount);
|
|
1811
2037
|
}
|
|
1812
|
-
/**
|
|
1813
|
-
* Parses and validates the prompt template name.
|
|
1814
|
-
*
|
|
1815
|
-
* @private internal utility of `generatePromptBoilerplate` command
|
|
1816
|
-
*/
|
|
1817
|
-
function parsePromptTemplate(templateOption) {
|
|
1818
|
-
if (templateOption === 'common' ||
|
|
1819
|
-
templateOption === 'agents-server'
|
|
1820
|
-
// <- TODO: Unhardcode and allow this dynamically by the template files.
|
|
1821
|
-
) {
|
|
1822
|
-
return templateOption;
|
|
1823
|
-
}
|
|
1824
|
-
console.info(colors.yellow(`Invalid --template '${templateOption}'. Falling back to default 'common'.`));
|
|
1825
|
-
return 'common';
|
|
1826
|
-
}
|
|
1827
|
-
/**
|
|
1828
|
-
* Loads prompt template markdown content from the local templates folder.
|
|
1829
|
-
*
|
|
1830
|
-
* @private internal utility of `generatePromptBoilerplate` command
|
|
1831
|
-
*/
|
|
1832
|
-
function loadPromptTemplate(template) {
|
|
1833
|
-
const templateFilePath = join(__dirname, '../../../../scripts/generate-prompt-boilerplate/templates', `${template}.template.md`);
|
|
1834
|
-
return readFileSync(templateFilePath, 'utf-8').trim();
|
|
1835
|
-
}
|
|
1836
2038
|
/**
|
|
1837
2039
|
* Builds filename slug from template and placeholder title.
|
|
1838
2040
|
*
|
|
1839
2041
|
* @private internal utility of `generatePromptBoilerplate` command
|
|
1840
2042
|
*/
|
|
1841
|
-
function buildPromptSlug$1(
|
|
1842
|
-
if (
|
|
2043
|
+
function buildPromptSlug$1(templateSlugPrefix, title) {
|
|
2044
|
+
if (!templateSlugPrefix) {
|
|
1843
2045
|
return title;
|
|
1844
2046
|
}
|
|
1845
|
-
return `${
|
|
2047
|
+
return `${templateSlugPrefix}-${title}`;
|
|
1846
2048
|
}
|
|
1847
2049
|
// Note: [🟡] Code for CLI command [generate-boilerplates](src/cli/cli-commands/coder/generate-boilerplates.ts) should never be published outside of `@promptbook/cli`
|
|
1848
2050
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
1849
2051
|
|
|
1850
2052
|
/**
|
|
1851
|
-
*
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
/**
|
|
1855
|
-
* Relative path to the archive directory used by `coder verify`.
|
|
2053
|
+
* This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
|
|
2054
|
+
*
|
|
2055
|
+
* @public exported from `@promptbook/core`
|
|
1856
2056
|
*/
|
|
1857
|
-
|
|
2057
|
+
class ParseError extends Error {
|
|
2058
|
+
constructor(message) {
|
|
2059
|
+
super(message);
|
|
2060
|
+
this.name = 'ParseError';
|
|
2061
|
+
Object.setPrototypeOf(this, ParseError.prototype);
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
// TODO: Maybe split `ParseError` and `ApplyError`
|
|
2065
|
+
|
|
1858
2066
|
/**
|
|
1859
2067
|
* Required environment variables for coding-agent git identity.
|
|
1860
2068
|
*/
|
|
@@ -1872,6 +2080,58 @@ const REQUIRED_CODER_ENV_VARIABLES = [
|
|
|
1872
2080
|
value: '13406525ED912F938FEA85AB4046C687298B2382',
|
|
1873
2081
|
},
|
|
1874
2082
|
];
|
|
2083
|
+
/**
|
|
2084
|
+
* Default npm scripts initialized by `ptbk coder init`.
|
|
2085
|
+
*/
|
|
2086
|
+
const DEFAULT_CODER_PACKAGE_JSON_SCRIPTS = {
|
|
2087
|
+
'coder:generate-boilerplates': 'npx ptbk coder generate-boilerplates',
|
|
2088
|
+
'coder:run': 'npx ptbk coder run --agent github-copilot --model gpt-5.4 --thinking-level xhigh --context AGENTS.md --no-wait',
|
|
2089
|
+
'coder:find-refactor-candidates': 'npx ptbk coder find-refactor-candidates',
|
|
2090
|
+
'coder:verify': 'npx ptbk coder verify',
|
|
2091
|
+
};
|
|
2092
|
+
/**
|
|
2093
|
+
* Relative path to `.gitignore` in the initialized project.
|
|
2094
|
+
*/
|
|
2095
|
+
const GITIGNORE_FILE_PATH = '.gitignore';
|
|
2096
|
+
/**
|
|
2097
|
+
* Relative path to `package.json` in the initialized project.
|
|
2098
|
+
*/
|
|
2099
|
+
const PACKAGE_JSON_FILE_PATH = 'package.json';
|
|
2100
|
+
/**
|
|
2101
|
+
* Relative path to the VS Code settings file initialized by `ptbk coder init`.
|
|
2102
|
+
*/
|
|
2103
|
+
const VSCODE_SETTINGS_FILE_PATH = '.vscode/settings.json';
|
|
2104
|
+
/**
|
|
2105
|
+
* Relative path to the VS Code directory initialized by `ptbk coder init`.
|
|
2106
|
+
*/
|
|
2107
|
+
const VSCODE_DIRECTORY_PATH = '.vscode';
|
|
2108
|
+
/**
|
|
2109
|
+
* VS Code setting key used to route pasted markdown images into prompt-specific screenshots.
|
|
2110
|
+
*/
|
|
2111
|
+
const MARKDOWN_COPY_FILES_DESTINATION_SETTING_KEY = 'markdown.copyFiles.destination';
|
|
2112
|
+
/**
|
|
2113
|
+
* Markdown glob used for coder prompt files inside VS Code settings.
|
|
2114
|
+
*/
|
|
2115
|
+
const PROMPTS_MARKDOWN_FILE_GLOB = 'prompts/*md';
|
|
2116
|
+
/**
|
|
2117
|
+
* Screenshot destination used for pasted prompt images inside VS Code settings.
|
|
2118
|
+
*/
|
|
2119
|
+
const PROMPTS_SCREENSHOT_DESTINATION = './prompts/screenshots/${documentBaseName}.png';
|
|
2120
|
+
/**
|
|
2121
|
+
* Default indentation used when creating new JSON configuration files.
|
|
2122
|
+
*/
|
|
2123
|
+
const DEFAULT_JSON_FILE_INDENTATION = ' ';
|
|
2124
|
+
/**
|
|
2125
|
+
* Default newline used when creating new JSON configuration files.
|
|
2126
|
+
*/
|
|
2127
|
+
const DEFAULT_JSON_FILE_NEWLINE = '\n';
|
|
2128
|
+
/**
|
|
2129
|
+
* `.gitignore` block required by standalone Promptbook coder projects.
|
|
2130
|
+
*/
|
|
2131
|
+
const CODER_GITIGNORE_BLOCK = spaceTrim$1(`
|
|
2132
|
+
# Promptbook Coder
|
|
2133
|
+
/.tmp
|
|
2134
|
+
`);
|
|
1875
2135
|
/**
|
|
1876
2136
|
* Initializes `coder init` command for Promptbook CLI utilities.
|
|
1877
2137
|
*
|
|
@@ -1885,9 +2145,14 @@ function $initializeCoderInitCommand(program) {
|
|
|
1885
2145
|
command.description(spaceTrim$1(`
|
|
1886
2146
|
Initialize Promptbook coder configuration for current project
|
|
1887
2147
|
|
|
1888
|
-
Creates:
|
|
2148
|
+
Creates or updates:
|
|
1889
2149
|
- prompts/
|
|
1890
2150
|
- prompts/done/
|
|
2151
|
+
- prompts/templates/common.md
|
|
2152
|
+
- prompts/templates/agents-server.md
|
|
2153
|
+
- .gitignore
|
|
2154
|
+
- package.json
|
|
2155
|
+
- .vscode/settings.json
|
|
1891
2156
|
|
|
1892
2157
|
Ensures required coding-agent environment variables in .env:
|
|
1893
2158
|
- CODING_AGENT_GIT_NAME
|
|
@@ -1899,17 +2164,37 @@ function $initializeCoderInitCommand(program) {
|
|
|
1899
2164
|
printInitializationSummary(summary);
|
|
1900
2165
|
}));
|
|
1901
2166
|
}
|
|
2167
|
+
/**
|
|
2168
|
+
* Lists the default npm scripts initialized by `ptbk coder init`.
|
|
2169
|
+
*
|
|
2170
|
+
* @private internal utility of `coder init` command
|
|
2171
|
+
*/
|
|
2172
|
+
function getDefaultCoderPackageJsonScripts() {
|
|
2173
|
+
return DEFAULT_CODER_PACKAGE_JSON_SCRIPTS;
|
|
2174
|
+
}
|
|
1902
2175
|
/**
|
|
1903
2176
|
* Creates or updates all coder configuration artifacts required in the current project.
|
|
2177
|
+
*
|
|
2178
|
+
* @private internal utility of `coder init` command
|
|
1904
2179
|
*/
|
|
1905
2180
|
async function initializeCoderProjectConfiguration(projectPath) {
|
|
1906
2181
|
const promptsDirectoryStatus = await ensureDirectory(projectPath, PROMPTS_DIRECTORY_PATH);
|
|
1907
2182
|
const promptsDoneDirectoryStatus = await ensureDirectory(projectPath, PROMPTS_DONE_DIRECTORY_PATH);
|
|
2183
|
+
const promptsTemplatesDirectoryStatus = await ensureDirectory(projectPath, PROMPTS_TEMPLATES_DIRECTORY_PATH);
|
|
2184
|
+
const promptTemplateFileStatuses = await ensureDefaultCoderPromptTemplateFiles(projectPath);
|
|
1908
2185
|
const { envFileStatus, initializedEnvVariableNames } = await ensureCoderEnvFile(projectPath);
|
|
2186
|
+
const gitignoreFileStatus = await ensureCoderGitignoreFile(projectPath);
|
|
2187
|
+
const packageJsonFileStatus = await ensureCoderPackageJsonFile(projectPath);
|
|
2188
|
+
const vscodeSettingsFileStatus = await ensureCoderVscodeSettingsFile(projectPath);
|
|
1909
2189
|
return {
|
|
1910
2190
|
promptsDirectoryStatus,
|
|
1911
2191
|
promptsDoneDirectoryStatus,
|
|
2192
|
+
promptsTemplatesDirectoryStatus,
|
|
2193
|
+
promptTemplateFileStatuses,
|
|
1912
2194
|
envFileStatus,
|
|
2195
|
+
gitignoreFileStatus,
|
|
2196
|
+
packageJsonFileStatus,
|
|
2197
|
+
vscodeSettingsFileStatus,
|
|
1913
2198
|
initializedEnvVariableNames,
|
|
1914
2199
|
};
|
|
1915
2200
|
}
|
|
@@ -1955,6 +2240,70 @@ async function ensureCoderEnvFile(projectPath) {
|
|
|
1955
2240
|
initializedEnvVariableNames: missingEnvVariables.map(({ name }) => name),
|
|
1956
2241
|
};
|
|
1957
2242
|
}
|
|
2243
|
+
/**
|
|
2244
|
+
* Ensures `.gitignore` contains the standalone Promptbook coder cache entry.
|
|
2245
|
+
*/
|
|
2246
|
+
async function ensureCoderGitignoreFile(projectPath) {
|
|
2247
|
+
const gitignorePath = join(projectPath, GITIGNORE_FILE_PATH);
|
|
2248
|
+
const currentGitignoreContent = await readTextFileIfExists(gitignorePath);
|
|
2249
|
+
if (currentGitignoreContent !== undefined && hasTmpGitignoreRule(currentGitignoreContent)) {
|
|
2250
|
+
return 'unchanged';
|
|
2251
|
+
}
|
|
2252
|
+
const nextGitignoreContent = appendBlock(currentGitignoreContent || '', CODER_GITIGNORE_BLOCK);
|
|
2253
|
+
await writeFile(gitignorePath, nextGitignoreContent, 'utf-8');
|
|
2254
|
+
return currentGitignoreContent === undefined ? 'created' : 'updated';
|
|
2255
|
+
}
|
|
2256
|
+
/**
|
|
2257
|
+
* Ensures `package.json` contains the standalone Promptbook coder helper scripts.
|
|
2258
|
+
*/
|
|
2259
|
+
async function ensureCoderPackageJsonFile(projectPath) {
|
|
2260
|
+
const packageJsonPath = join(projectPath, PACKAGE_JSON_FILE_PATH);
|
|
2261
|
+
const packageJsonContent = await readTextFileIfExists(packageJsonPath);
|
|
2262
|
+
const formatting = detectJsonFileFormatting(packageJsonContent);
|
|
2263
|
+
const packageJson = packageJsonContent === undefined ? {} : await parseJsonObjectFile(PACKAGE_JSON_FILE_PATH, packageJsonContent);
|
|
2264
|
+
const scripts = getStringRecordOrDefault(packageJson['scripts'], PACKAGE_JSON_FILE_PATH, 'scripts');
|
|
2265
|
+
let hasChanges = packageJsonContent === undefined;
|
|
2266
|
+
const nextScripts = { ...scripts };
|
|
2267
|
+
for (const [scriptName, scriptCommand] of Object.entries(getDefaultCoderPackageJsonScripts())) {
|
|
2268
|
+
if (nextScripts[scriptName] !== scriptCommand) {
|
|
2269
|
+
nextScripts[scriptName] = scriptCommand;
|
|
2270
|
+
hasChanges = true;
|
|
2271
|
+
}
|
|
2272
|
+
}
|
|
2273
|
+
if (!hasChanges) {
|
|
2274
|
+
return 'unchanged';
|
|
2275
|
+
}
|
|
2276
|
+
const nextPackageJson = { ...packageJson };
|
|
2277
|
+
nextPackageJson['scripts'] = nextScripts;
|
|
2278
|
+
await writeFile(packageJsonPath, serializeJsonObject(nextPackageJson, formatting), 'utf-8');
|
|
2279
|
+
return packageJsonContent === undefined ? 'created' : 'updated';
|
|
2280
|
+
}
|
|
2281
|
+
/**
|
|
2282
|
+
* Ensures VS Code routes pasted prompt images into `prompts/screenshots`.
|
|
2283
|
+
*/
|
|
2284
|
+
async function ensureCoderVscodeSettingsFile(projectPath) {
|
|
2285
|
+
await mkdir(join(projectPath, VSCODE_DIRECTORY_PATH), { recursive: true });
|
|
2286
|
+
const vscodeSettingsPath = join(projectPath, VSCODE_SETTINGS_FILE_PATH);
|
|
2287
|
+
const vscodeSettingsContent = await readTextFileIfExists(vscodeSettingsPath);
|
|
2288
|
+
const formatting = detectJsonFileFormatting(vscodeSettingsContent);
|
|
2289
|
+
const vscodeSettings = vscodeSettingsContent === undefined
|
|
2290
|
+
? {}
|
|
2291
|
+
: await parseJsonObjectFile(VSCODE_SETTINGS_FILE_PATH, vscodeSettingsContent);
|
|
2292
|
+
const markdownCopyFilesDestinations = getStringRecordOrDefault(vscodeSettings[MARKDOWN_COPY_FILES_DESTINATION_SETTING_KEY], VSCODE_SETTINGS_FILE_PATH, MARKDOWN_COPY_FILES_DESTINATION_SETTING_KEY);
|
|
2293
|
+
let hasChanges = vscodeSettingsContent === undefined;
|
|
2294
|
+
const nextMarkdownCopyFilesDestinations = { ...markdownCopyFilesDestinations };
|
|
2295
|
+
if (nextMarkdownCopyFilesDestinations[PROMPTS_MARKDOWN_FILE_GLOB] !== PROMPTS_SCREENSHOT_DESTINATION) {
|
|
2296
|
+
nextMarkdownCopyFilesDestinations[PROMPTS_MARKDOWN_FILE_GLOB] = PROMPTS_SCREENSHOT_DESTINATION;
|
|
2297
|
+
hasChanges = true;
|
|
2298
|
+
}
|
|
2299
|
+
if (!hasChanges) {
|
|
2300
|
+
return 'unchanged';
|
|
2301
|
+
}
|
|
2302
|
+
const nextVscodeSettings = { ...vscodeSettings };
|
|
2303
|
+
nextVscodeSettings[MARKDOWN_COPY_FILES_DESTINATION_SETTING_KEY] = nextMarkdownCopyFilesDestinations;
|
|
2304
|
+
await writeFile(vscodeSettingsPath, serializeJsonObject(nextVscodeSettings, formatting), 'utf-8');
|
|
2305
|
+
return vscodeSettingsContent === undefined ? 'created' : 'updated';
|
|
2306
|
+
}
|
|
1958
2307
|
/**
|
|
1959
2308
|
* Parses variable names currently defined in `.env` style content.
|
|
1960
2309
|
*/
|
|
@@ -1997,14 +2346,21 @@ function appendBlock(currentContent, blockToAppend) {
|
|
|
1997
2346
|
*/
|
|
1998
2347
|
function printInitializationSummary(summary) {
|
|
1999
2348
|
console.info(colors.green('Promptbook coder configuration initialized.'));
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2349
|
+
printInitializationStatusLine('prompts/', summary.promptsDirectoryStatus);
|
|
2350
|
+
printInitializationStatusLine('prompts/done/', summary.promptsDoneDirectoryStatus);
|
|
2351
|
+
printInitializationStatusLine('prompts/templates/', summary.promptsTemplatesDirectoryStatus);
|
|
2352
|
+
for (const templateFileStatus of summary.promptTemplateFileStatuses) {
|
|
2353
|
+
printInitializationStatusLine(formatDisplayPath(templateFileStatus.relativeFilePath), templateFileStatus.status);
|
|
2354
|
+
}
|
|
2355
|
+
printInitializationStatusLine('.env', summary.envFileStatus);
|
|
2356
|
+
printInitializationStatusLine('.gitignore', summary.gitignoreFileStatus);
|
|
2357
|
+
printInitializationStatusLine('package.json', summary.packageJsonFileStatus);
|
|
2358
|
+
printInitializationStatusLine('.vscode/settings.json', summary.vscodeSettingsFileStatus);
|
|
2003
2359
|
if (summary.initializedEnvVariableNames.length > 0) {
|
|
2004
|
-
|
|
2360
|
+
printInitializationNote(`Added env variables: ${summary.initializedEnvVariableNames.join(', ')}`, colors.cyan);
|
|
2005
2361
|
}
|
|
2006
2362
|
else {
|
|
2007
|
-
|
|
2363
|
+
printInitializationNote('Required coder env variables are already present.', colors.gray);
|
|
2008
2364
|
}
|
|
2009
2365
|
}
|
|
2010
2366
|
/**
|
|
@@ -2019,6 +2375,117 @@ function formatInitializationStatus(status) {
|
|
|
2019
2375
|
}
|
|
2020
2376
|
return 'unchanged';
|
|
2021
2377
|
}
|
|
2378
|
+
/**
|
|
2379
|
+
* Prints one checked initialization-status line.
|
|
2380
|
+
*/
|
|
2381
|
+
function printInitializationStatusLine(relativePath, status) {
|
|
2382
|
+
console.info(colors.gray(`✔ ${relativePath}: ${formatInitializationStatus(status)}`));
|
|
2383
|
+
}
|
|
2384
|
+
/**
|
|
2385
|
+
* Prints one checked initialization note.
|
|
2386
|
+
*/
|
|
2387
|
+
function printInitializationNote(message, colorize) {
|
|
2388
|
+
console.info(colorize(`✔ ${message}`));
|
|
2389
|
+
}
|
|
2390
|
+
/**
|
|
2391
|
+
* Normalizes one project-relative path for human-readable CLI output.
|
|
2392
|
+
*/
|
|
2393
|
+
function formatDisplayPath(relativePath) {
|
|
2394
|
+
return relativePath.replace(/\\/gu, '/');
|
|
2395
|
+
}
|
|
2396
|
+
/**
|
|
2397
|
+
* Detects whether `.gitignore` already covers the standalone coder temp directory.
|
|
2398
|
+
*/
|
|
2399
|
+
function hasTmpGitignoreRule(gitignoreContent) {
|
|
2400
|
+
return /(^|[\r\n])\/?\.tmp(?:[\r\n]|$)/u.test(gitignoreContent);
|
|
2401
|
+
}
|
|
2402
|
+
/**
|
|
2403
|
+
* Reads one text file when it exists, otherwise returns `undefined`.
|
|
2404
|
+
*/
|
|
2405
|
+
async function readTextFileIfExists(path) {
|
|
2406
|
+
if (!(await isExistingFile(path))) {
|
|
2407
|
+
return undefined;
|
|
2408
|
+
}
|
|
2409
|
+
return readFile(path, 'utf-8');
|
|
2410
|
+
}
|
|
2411
|
+
/**
|
|
2412
|
+
* Parses one JSON object file while accepting VS Code style comments and trailing commas.
|
|
2413
|
+
*/
|
|
2414
|
+
async function parseJsonObjectFile(relativeFilePath, fileContent) {
|
|
2415
|
+
if (fileContent.trim() === '') {
|
|
2416
|
+
return {};
|
|
2417
|
+
}
|
|
2418
|
+
const typescript = await import('typescript');
|
|
2419
|
+
const parsedFile = typescript.parseConfigFileTextToJson(relativeFilePath, fileContent);
|
|
2420
|
+
if (parsedFile.error) {
|
|
2421
|
+
throw new ParseError(spaceTrim$1(`
|
|
2422
|
+
Cannot parse \`${relativeFilePath}\` as JSON.
|
|
2423
|
+
|
|
2424
|
+
${typescript.flattenDiagnosticMessageText(parsedFile.error.messageText, '\n')}
|
|
2425
|
+
`));
|
|
2426
|
+
}
|
|
2427
|
+
if (!isPlainObject(parsedFile.config)) {
|
|
2428
|
+
throw new ParseError(spaceTrim$1(`
|
|
2429
|
+
File \`${relativeFilePath}\` must contain one top-level JSON object.
|
|
2430
|
+
`));
|
|
2431
|
+
}
|
|
2432
|
+
return parsedFile.config;
|
|
2433
|
+
}
|
|
2434
|
+
/**
|
|
2435
|
+
* Reads one JSON object field as a string-to-string record.
|
|
2436
|
+
*/
|
|
2437
|
+
function getStringRecordOrDefault(value, relativeFilePath, fieldPath) {
|
|
2438
|
+
if (value === undefined) {
|
|
2439
|
+
return {};
|
|
2440
|
+
}
|
|
2441
|
+
if (!isPlainObject(value)) {
|
|
2442
|
+
throw new ParseError(spaceTrim$1(`
|
|
2443
|
+
File \`${relativeFilePath}\` contains invalid \`${fieldPath}\`.
|
|
2444
|
+
|
|
2445
|
+
Expected \`${fieldPath}\` to be an object with string values.
|
|
2446
|
+
`));
|
|
2447
|
+
}
|
|
2448
|
+
const stringRecord = {};
|
|
2449
|
+
for (const [key, itemValue] of Object.entries(value)) {
|
|
2450
|
+
if (typeof itemValue !== 'string') {
|
|
2451
|
+
throw new ParseError(spaceTrim$1(`
|
|
2452
|
+
File \`${relativeFilePath}\` contains invalid \`${fieldPath}.${key}\`.
|
|
2453
|
+
|
|
2454
|
+
Expected \`${fieldPath}\` to be an object with string values.
|
|
2455
|
+
`));
|
|
2456
|
+
}
|
|
2457
|
+
stringRecord[key] = itemValue;
|
|
2458
|
+
}
|
|
2459
|
+
return stringRecord;
|
|
2460
|
+
}
|
|
2461
|
+
/**
|
|
2462
|
+
* Serializes one JSON object using detected or default formatting.
|
|
2463
|
+
*/
|
|
2464
|
+
function serializeJsonObject(value, formatting) {
|
|
2465
|
+
return `${JSON.stringify(value, null, formatting.indentation)}${formatting.newline}`;
|
|
2466
|
+
}
|
|
2467
|
+
/**
|
|
2468
|
+
* Detects indentation and newline formatting from an existing JSON file.
|
|
2469
|
+
*/
|
|
2470
|
+
function detectJsonFileFormatting(fileContent) {
|
|
2471
|
+
if (!fileContent) {
|
|
2472
|
+
return {
|
|
2473
|
+
indentation: DEFAULT_JSON_FILE_INDENTATION,
|
|
2474
|
+
newline: DEFAULT_JSON_FILE_NEWLINE,
|
|
2475
|
+
};
|
|
2476
|
+
}
|
|
2477
|
+
const indentationMatch = fileContent.match(/^[ \t]+(?=")/mu);
|
|
2478
|
+
return {
|
|
2479
|
+
indentation: (indentationMatch === null || indentationMatch === void 0 ? void 0 : indentationMatch[0]) || DEFAULT_JSON_FILE_INDENTATION,
|
|
2480
|
+
newline: fileContent.includes('\r\n') ? '\r\n' : '\n',
|
|
2481
|
+
};
|
|
2482
|
+
}
|
|
2483
|
+
/**
|
|
2484
|
+
* Checks whether one parsed JSON value is a plain object.
|
|
2485
|
+
*/
|
|
2486
|
+
function isPlainObject(value) {
|
|
2487
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
2488
|
+
}
|
|
2022
2489
|
/**
|
|
2023
2490
|
* Checks whether a path exists and is a file.
|
|
2024
2491
|
*/
|
|
@@ -4043,33 +4510,6 @@ class NotAllowed extends Error {
|
|
|
4043
4510
|
}
|
|
4044
4511
|
}
|
|
4045
4512
|
|
|
4046
|
-
/**
|
|
4047
|
-
* This error indicates that promptbook not found in the collection
|
|
4048
|
-
*
|
|
4049
|
-
* @public exported from `@promptbook/core`
|
|
4050
|
-
*/
|
|
4051
|
-
class NotFoundError extends Error {
|
|
4052
|
-
constructor(message) {
|
|
4053
|
-
super(message);
|
|
4054
|
-
this.name = 'NotFoundError';
|
|
4055
|
-
Object.setPrototypeOf(this, NotFoundError.prototype);
|
|
4056
|
-
}
|
|
4057
|
-
}
|
|
4058
|
-
|
|
4059
|
-
/**
|
|
4060
|
-
* This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
|
|
4061
|
-
*
|
|
4062
|
-
* @public exported from `@promptbook/core`
|
|
4063
|
-
*/
|
|
4064
|
-
class ParseError extends Error {
|
|
4065
|
-
constructor(message) {
|
|
4066
|
-
super(message);
|
|
4067
|
-
this.name = 'ParseError';
|
|
4068
|
-
Object.setPrototypeOf(this, ParseError.prototype);
|
|
4069
|
-
}
|
|
4070
|
-
}
|
|
4071
|
-
// TODO: Maybe split `ParseError` and `ApplyError`
|
|
4072
|
-
|
|
4073
4513
|
/**
|
|
4074
4514
|
* Generates random token
|
|
4075
4515
|
*
|
|
@@ -44048,11 +44488,11 @@ function buildGitHubCopilotScript(options) {
|
|
|
44048
44488
|
${block(options.prompt)}
|
|
44049
44489
|
|
|
44050
44490
|
${delimiter}
|
|
44051
|
-
)"
|
|
44052
|
-
--yolo
|
|
44053
|
-
--no-ask-user
|
|
44054
|
-
--no-color
|
|
44055
|
-
--output-format json
|
|
44491
|
+
)" \\
|
|
44492
|
+
--yolo \\
|
|
44493
|
+
--no-ask-user \\
|
|
44494
|
+
--no-color \\
|
|
44495
|
+
--output-format json \\
|
|
44056
44496
|
--stream off${modelArgument}${thinkingLevelArgument}
|
|
44057
44497
|
`);
|
|
44058
44498
|
}
|