@promptbook/cli 0.114.0-26 → 0.114.0-28
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/esm/index.es.js +374 -60
- package/esm/index.es.js.map +1 -1
- package/esm/src/cli/cli-commands/common/harness/$applyHarnessInstallationStatus.d.ts +1 -1
- package/esm/src/cli/cli-commands/common/harness/$resolveHarnessCommandPath.d.ts +14 -0
- package/esm/src/cli/cli-commands/common/harness/$resolveHarnessInstallationOrigin.d.ts +10 -0
- package/esm/src/cli/cli-commands/common/harness/$runHarnessInstallationCommand.d.ts +43 -0
- package/esm/src/cli/cli-commands/common/harness/HarnessDefinition.d.ts +26 -0
- package/esm/src/cli/cli-commands/common/harness/HarnessInstallationOrigin.d.ts +36 -0
- package/esm/src/cli/cli-commands/common/harness/HarnessInstallationStatus.d.ts +5 -0
- package/esm/src/cli/cli-commands/common/harness/HarnessUpdatePlan.d.ts +23 -0
- package/esm/src/cli/cli-commands/common/harness/buildHarnessInstallCommand.d.ts +4 -1
- package/esm/src/cli/cli-commands/common/harness/formatHarnessManualUpdateInstruction.d.ts +8 -0
- package/esm/src/cli/cli-commands/common/harness/formatHarnessManualUpdateInstruction.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/common/harness/resolveHarnessInstallationMethodFromPaths.d.ts +31 -0
- package/esm/src/cli/cli-commands/common/harness/resolveHarnessInstallationMethodFromPaths.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/common/harness/resolveHarnessUpdatePlan.d.ts +12 -0
- package/esm/src/cli/cli-commands/common/harness/resolveHarnessUpdatePlan.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/common/npm/$resolveNpmGlobalPrefixPath.d.ts +9 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/cli/cli-commands/coder/init.ts +1 -1
- package/src/cli/cli-commands/coder/ping.ts +1 -1
- package/src/cli/cli-commands/coder/run.ts +1 -1
- package/src/cli/cli-commands/coder/server.ts +1 -1
- package/src/cli/cli-commands/common/harness/$applyHarnessInstallationStatus.ts +57 -8
- package/src/cli/cli-commands/common/harness/$checkHarnessInstallation.ts +8 -1
- package/src/cli/cli-commands/common/harness/$resolveHarnessCommandPath.ts +46 -0
- package/src/cli/cli-commands/common/harness/$resolveHarnessInstallationOrigin.ts +36 -0
- package/src/cli/cli-commands/common/harness/$runHarnessInstallationCommand.ts +100 -0
- package/src/cli/cli-commands/common/harness/HarnessDefinition.ts +34 -0
- package/src/cli/cli-commands/common/harness/HarnessInstallationOrigin.ts +44 -0
- package/src/cli/cli-commands/common/harness/HarnessInstallationStatus.ts +6 -0
- package/src/cli/cli-commands/common/harness/HarnessUpdatePlan.ts +27 -0
- package/src/cli/cli-commands/common/harness/buildHarnessInstallCommand.ts +4 -1
- package/src/cli/cli-commands/common/harness/formatHarnessInstallationWarning.ts +28 -6
- package/src/cli/cli-commands/common/harness/formatHarnessManualUpdateInstruction.ts +41 -0
- package/src/cli/cli-commands/common/harness/resolveHarnessInstallationMethodFromPaths.ts +111 -0
- package/src/cli/cli-commands/common/harness/resolveHarnessUpdatePlan.ts +47 -0
- package/src/cli/cli-commands/common/harnessUpdateCliOptions.ts +1 -1
- package/src/cli/cli-commands/common/npm/$resolveNpmGlobalPrefixPath.ts +51 -0
- package/src/other/templates/getTemplatesPipelineCollection.ts +816 -870
- package/src/version.ts +2 -2
- package/src/versions.txt +2 -0
- package/umd/index.umd.js +374 -60
- package/umd/index.umd.js.map +1 -1
- package/umd/src/cli/cli-commands/common/harness/$applyHarnessInstallationStatus.d.ts +1 -1
- package/umd/src/cli/cli-commands/common/harness/$resolveHarnessCommandPath.d.ts +14 -0
- package/umd/src/cli/cli-commands/common/harness/$resolveHarnessInstallationOrigin.d.ts +10 -0
- package/umd/src/cli/cli-commands/common/harness/$runHarnessInstallationCommand.d.ts +43 -0
- package/umd/src/cli/cli-commands/common/harness/HarnessDefinition.d.ts +26 -0
- package/umd/src/cli/cli-commands/common/harness/HarnessInstallationOrigin.d.ts +36 -0
- package/umd/src/cli/cli-commands/common/harness/HarnessInstallationStatus.d.ts +5 -0
- package/umd/src/cli/cli-commands/common/harness/HarnessUpdatePlan.d.ts +23 -0
- package/umd/src/cli/cli-commands/common/harness/buildHarnessInstallCommand.d.ts +4 -1
- package/umd/src/cli/cli-commands/common/harness/formatHarnessManualUpdateInstruction.d.ts +8 -0
- package/umd/src/cli/cli-commands/common/harness/formatHarnessManualUpdateInstruction.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/common/harness/resolveHarnessInstallationMethodFromPaths.d.ts +31 -0
- package/umd/src/cli/cli-commands/common/harness/resolveHarnessInstallationMethodFromPaths.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/common/harness/resolveHarnessUpdatePlan.d.ts +12 -0
- package/umd/src/cli/cli-commands/common/harness/resolveHarnessUpdatePlan.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/common/npm/$resolveNpmGlobalPrefixPath.d.ts +9 -0
- package/umd/src/version.d.ts +1 -1
- package/esm/src/cli/cli-commands/common/harness/$installHarness.d.ts +0 -13
- package/src/cli/cli-commands/common/harness/$installHarness.ts +0 -56
- package/umd/src/cli/cli-commands/common/harness/$installHarness.d.ts +0 -13
package/src/version.ts
CHANGED
|
@@ -16,11 +16,11 @@ export const BOOK_LANGUAGE_VERSION: string_semantic_version = '2.0.0';
|
|
|
16
16
|
* @generated
|
|
17
17
|
* @see https://github.com/webgptorg/promptbook
|
|
18
18
|
*/
|
|
19
|
-
export const PROMPTBOOK_ENGINE_VERSION: string_promptbook_version = '0.114.0-
|
|
19
|
+
export const PROMPTBOOK_ENGINE_VERSION: string_promptbook_version = '0.114.0-28';
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Represents the version string of the Promptbook engine.
|
|
23
|
-
* It follows semantic versioning (e.g., `0.114.0-
|
|
23
|
+
* It follows semantic versioning (e.g., `0.114.0-27`).
|
|
24
24
|
*
|
|
25
25
|
* @generated
|
|
26
26
|
*/
|
package/src/versions.txt
CHANGED
package/umd/index.umd.js
CHANGED
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
* @generated
|
|
59
59
|
* @see https://github.com/webgptorg/promptbook
|
|
60
60
|
*/
|
|
61
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.114.0-
|
|
61
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.114.0-28';
|
|
62
62
|
/**
|
|
63
63
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
64
64
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -3713,7 +3713,7 @@
|
|
|
3713
3713
|
*
|
|
3714
3714
|
* @private internal constant of `buildAgentsServer`
|
|
3715
3715
|
*/
|
|
3716
|
-
const NODE_MODULES_DIRECTORY_NAME$
|
|
3716
|
+
const NODE_MODULES_DIRECTORY_NAME$2 = 'node_modules';
|
|
3717
3717
|
|
|
3718
3718
|
/**
|
|
3719
3719
|
* Returns true when one path is nested below a `node_modules` segment.
|
|
@@ -3721,7 +3721,7 @@
|
|
|
3721
3721
|
* @private internal utility of `buildAgentsServer`
|
|
3722
3722
|
*/
|
|
3723
3723
|
function isPathInsideNodeModules(path) {
|
|
3724
|
-
return path.split(/[\\/]+/u).includes(NODE_MODULES_DIRECTORY_NAME$
|
|
3724
|
+
return path.split(/[\\/]+/u).includes(NODE_MODULES_DIRECTORY_NAME$2);
|
|
3725
3725
|
}
|
|
3726
3726
|
|
|
3727
3727
|
/**
|
|
@@ -3834,7 +3834,7 @@
|
|
|
3834
3834
|
* Links the materialized runtime back to the package dependency tree used by the installed CLI.
|
|
3835
3835
|
*/
|
|
3836
3836
|
async function ensureMaterializedRuntimeNodeModulesLink(options) {
|
|
3837
|
-
const nodeModulesLinkPath = path.join(options.materializedRuntimeRootPath, NODE_MODULES_DIRECTORY_NAME$
|
|
3837
|
+
const nodeModulesLinkPath = path.join(options.materializedRuntimeRootPath, NODE_MODULES_DIRECTORY_NAME$2);
|
|
3838
3838
|
try {
|
|
3839
3839
|
const existingLinkStats = await promises.lstat(nodeModulesLinkPath);
|
|
3840
3840
|
await promises.rm(nodeModulesLinkPath, {
|
|
@@ -3920,7 +3920,7 @@
|
|
|
3920
3920
|
*/
|
|
3921
3921
|
function resolveNodeModulesPath(nextCliPath) {
|
|
3922
3922
|
const normalizedNextCliPath = nextCliPath.replace(/\\/gu, '/');
|
|
3923
|
-
const marker = `/${NODE_MODULES_DIRECTORY_NAME$
|
|
3923
|
+
const marker = `/${NODE_MODULES_DIRECTORY_NAME$2}/next/`;
|
|
3924
3924
|
const markerIndex = normalizedNextCliPath.lastIndexOf(marker);
|
|
3925
3925
|
if (markerIndex === -1) {
|
|
3926
3926
|
return path.resolve(nextCliPath, '..', '..', '..');
|
|
@@ -24128,6 +24128,11 @@
|
|
|
24128
24128
|
label: 'OpenAI Codex',
|
|
24129
24129
|
commandName: 'codex',
|
|
24130
24130
|
npmPackageName: '@openai/codex',
|
|
24131
|
+
// Note: The official standalone installer keeps its package in `~/.codex` and links it onto the `PATH`
|
|
24132
|
+
standaloneInstallation: {
|
|
24133
|
+
directoryNames: ['.codex'],
|
|
24134
|
+
updateCommand: 'codex update',
|
|
24135
|
+
},
|
|
24131
24136
|
},
|
|
24132
24137
|
'github-copilot': {
|
|
24133
24138
|
harnessName: 'github-copilot',
|
|
@@ -43098,6 +43103,53 @@
|
|
|
43098
43103
|
}
|
|
43099
43104
|
// Note: [🟡] Code for CLI npm package installation approval [$askForNpmPackageInstallationApproval](src/cli/cli-commands/common/npm/$askForNpmPackageInstallationApproval.ts) should never be published outside of `@promptbook/cli`
|
|
43100
43105
|
|
|
43106
|
+
/**
|
|
43107
|
+
* Words describing each operation in the terminal output.
|
|
43108
|
+
*/
|
|
43109
|
+
const HARNESS_INSTALLATION_OPERATION_WORDS = {
|
|
43110
|
+
install: { running: 'Installing', finished: 'installed' },
|
|
43111
|
+
update: { running: 'Updating', finished: 'updated' },
|
|
43112
|
+
};
|
|
43113
|
+
/**
|
|
43114
|
+
* Runs one command which installs or updates a CLI coding harness.
|
|
43115
|
+
*
|
|
43116
|
+
* A failed installation is reported but never aborts the running command, because the harness check
|
|
43117
|
+
* is only an assistant - the command itself may still work with a manually managed harness.
|
|
43118
|
+
*
|
|
43119
|
+
* Note: `$` is used to indicate that this function is not a pure function - it installs software
|
|
43120
|
+
*
|
|
43121
|
+
* @returns `true` when the command succeeded, `false` when it failed
|
|
43122
|
+
* @private internal utility of `promptbookCli`
|
|
43123
|
+
*/
|
|
43124
|
+
async function $runHarnessInstallationCommand(options) {
|
|
43125
|
+
const { definition, operation, command, environment } = options;
|
|
43126
|
+
const operationWords = HARNESS_INSTALLATION_OPERATION_WORDS[operation];
|
|
43127
|
+
console.info(colors__default["default"].cyan(`${operationWords.running} ${definition.label} with \`${command}\`...`));
|
|
43128
|
+
try {
|
|
43129
|
+
await $execCommand({
|
|
43130
|
+
command,
|
|
43131
|
+
crashOnError: true,
|
|
43132
|
+
isVerbose: true,
|
|
43133
|
+
env: environment ? { ...environment } : undefined,
|
|
43134
|
+
});
|
|
43135
|
+
}
|
|
43136
|
+
catch (error) {
|
|
43137
|
+
assertsError(error);
|
|
43138
|
+
const installErrorMessage = error.message;
|
|
43139
|
+
console.error(colors__default["default"].red(_spaceTrim.spaceTrim((block) => `
|
|
43140
|
+
Could not ${operation} **${definition.label}**.
|
|
43141
|
+
|
|
43142
|
+
Run \`${command}\` manually and run the command again.
|
|
43143
|
+
|
|
43144
|
+
${block(installErrorMessage)}
|
|
43145
|
+
`)));
|
|
43146
|
+
return false;
|
|
43147
|
+
}
|
|
43148
|
+
console.info(colors__default["default"].green(`${definition.label} has been ${operationWords.finished}.`));
|
|
43149
|
+
return true;
|
|
43150
|
+
}
|
|
43151
|
+
// Note: [🟡] Code for CLI harness installation commands [$runHarnessInstallationCommand](src/cli/cli-commands/common/harness/$runHarnessInstallationCommand.ts) should never be published outside of `@promptbook/cli`
|
|
43152
|
+
|
|
43101
43153
|
/**
|
|
43102
43154
|
* Builds an npm command which installs or updates a package in the requested existing location.
|
|
43103
43155
|
*
|
|
@@ -43117,9 +43169,12 @@
|
|
|
43117
43169
|
/**
|
|
43118
43170
|
* Builds the shell command which installs or updates one CLI coding harness globally.
|
|
43119
43171
|
*
|
|
43120
|
-
* The very same command is executed by `$
|
|
43172
|
+
* The very same command is executed by `$runHarnessInstallationCommand` and printed as the manual fallback,
|
|
43121
43173
|
* so the user always sees exactly what Promptbook would run.
|
|
43122
43174
|
*
|
|
43175
|
+
* Note: This command installs the harness through npm, so it may only update a harness which npm really owns,
|
|
43176
|
+
* see `resolveHarnessUpdatePlan`.
|
|
43177
|
+
*
|
|
43123
43178
|
* @private internal utility of `promptbookCli`
|
|
43124
43179
|
*/
|
|
43125
43180
|
function buildHarnessInstallCommand(definition) {
|
|
@@ -43128,76 +43183,114 @@
|
|
|
43128
43183
|
// Note: [🟡] Code for CLI harness install command [buildHarnessInstallCommand](src/cli/cli-commands/common/harness/buildHarnessInstallCommand.ts) should never be published outside of `@promptbook/cli`
|
|
43129
43184
|
|
|
43130
43185
|
/**
|
|
43131
|
-
*
|
|
43132
|
-
|
|
43133
|
-
|
|
43134
|
-
|
|
43135
|
-
|
|
43136
|
-
|
|
43186
|
+
* Human-readable description of each way a harness can be installed.
|
|
43187
|
+
*/
|
|
43188
|
+
const HARNESS_INSTALLATION_METHOD_DESCRIPTIONS = {
|
|
43189
|
+
'npm-global': 'global npm installation',
|
|
43190
|
+
standalone: 'standalone installation',
|
|
43191
|
+
homebrew: 'Homebrew installation',
|
|
43192
|
+
unknown: 'unknown installation method',
|
|
43193
|
+
};
|
|
43194
|
+
/**
|
|
43195
|
+
* Formats the warning shown when a harness is missing or outdated.
|
|
43137
43196
|
*
|
|
43138
|
-
* @returns `true` when the harness has been installed, `false` when the installation failed
|
|
43139
43197
|
* @private internal utility of `promptbookCli`
|
|
43140
43198
|
*/
|
|
43141
|
-
|
|
43142
|
-
const
|
|
43143
|
-
|
|
43144
|
-
|
|
43145
|
-
|
|
43146
|
-
command: installCommand,
|
|
43147
|
-
crashOnError: true,
|
|
43148
|
-
isVerbose: true,
|
|
43149
|
-
env: definition.npmInstallEnvironment ? { ...definition.npmInstallEnvironment } : undefined,
|
|
43150
|
-
});
|
|
43151
|
-
}
|
|
43152
|
-
catch (error) {
|
|
43153
|
-
assertsError(error);
|
|
43154
|
-
const installErrorMessage = error.message;
|
|
43155
|
-
console.error(colors__default["default"].red(_spaceTrim.spaceTrim((block) => `
|
|
43156
|
-
Could not install **${definition.label}**.
|
|
43157
|
-
|
|
43158
|
-
Install it manually with \`${installCommand}\` and run the command again.
|
|
43199
|
+
function formatHarnessInstallationWarning(status) {
|
|
43200
|
+
const { definition, installedVersion, latestVersion, installationOrigin } = status;
|
|
43201
|
+
if (status.installationState === 'not-installed') {
|
|
43202
|
+
return _spaceTrim.spaceTrim(`
|
|
43203
|
+
**${definition.label}** is not installed globally.
|
|
43159
43204
|
|
|
43160
|
-
|
|
43161
|
-
|
|
43162
|
-
return false;
|
|
43205
|
+
The \`${definition.commandName}\` command was not found, so the \`${definition.harnessName}\` harness cannot run.
|
|
43206
|
+
`);
|
|
43163
43207
|
}
|
|
43164
|
-
|
|
43165
|
-
|
|
43208
|
+
const warningLines = [
|
|
43209
|
+
`**${definition.label}** is outdated.`,
|
|
43210
|
+
'',
|
|
43211
|
+
`Installed version: \`${installedVersion}\``,
|
|
43212
|
+
`Newest version: \`${latestVersion}\``,
|
|
43213
|
+
];
|
|
43214
|
+
if (installationOrigin.commandPath !== null) {
|
|
43215
|
+
const installationMethodDescription = HARNESS_INSTALLATION_METHOD_DESCRIPTIONS[installationOrigin.installationMethod];
|
|
43216
|
+
warningLines.push(`Installed command: \`${installationOrigin.commandPath}\` *(${installationMethodDescription})*`);
|
|
43217
|
+
}
|
|
43218
|
+
return _spaceTrim.spaceTrim(warningLines.join('\n'));
|
|
43166
43219
|
}
|
|
43167
|
-
// Note: [🟡] Code for CLI harness installation [
|
|
43220
|
+
// Note: [🟡] Code for CLI harness installation warning [formatHarnessInstallationWarning](src/cli/cli-commands/common/harness/formatHarnessInstallationWarning.ts) should never be published outside of `@promptbook/cli`
|
|
43168
43221
|
|
|
43169
43222
|
/**
|
|
43170
|
-
* Formats the
|
|
43223
|
+
* Formats the instruction shown when an outdated harness must be updated by the user.
|
|
43171
43224
|
*
|
|
43172
43225
|
* @private internal utility of `promptbookCli`
|
|
43173
43226
|
*/
|
|
43174
|
-
function
|
|
43175
|
-
const { definition,
|
|
43176
|
-
|
|
43227
|
+
function formatHarnessManualUpdateInstruction(status, updatePlan) {
|
|
43228
|
+
const { definition, installationOrigin } = status;
|
|
43229
|
+
const commandLocation = installationOrigin.commandPath === null
|
|
43230
|
+
? `The \`${definition.commandName}\` command`
|
|
43231
|
+
: `The \`${definition.commandName}\` command at \`${installationOrigin.commandPath}\``;
|
|
43232
|
+
if (updatePlan.command !== null) {
|
|
43177
43233
|
return _spaceTrim.spaceTrim(`
|
|
43178
|
-
|
|
43234
|
+
${commandLocation} is not managed by npm, so Promptbook leaves it alone.
|
|
43179
43235
|
|
|
43180
|
-
|
|
43236
|
+
Update it manually with \`${updatePlan.command}\`.
|
|
43181
43237
|
`);
|
|
43182
43238
|
}
|
|
43239
|
+
const unknownInstallationReason = installationOrigin.commandPath === null ? 'could not be located' : 'is not inside the global npm prefix';
|
|
43240
|
+
const npmInstallCommand = buildHarnessInstallCommand(definition);
|
|
43183
43241
|
return _spaceTrim.spaceTrim(`
|
|
43184
|
-
|
|
43242
|
+
${commandLocation} ${unknownInstallationReason}, so Promptbook cannot tell how it was installed.
|
|
43185
43243
|
|
|
43186
|
-
|
|
43187
|
-
Newest version: \`${latestVersion}\`
|
|
43244
|
+
Update it the same way it was installed - \`${npmInstallCommand}\` would install a **second** copy of ${definition.label} instead of updating the one which is really used.
|
|
43188
43245
|
`);
|
|
43189
43246
|
}
|
|
43190
|
-
// Note: [🟡] Code for CLI harness
|
|
43247
|
+
// Note: [🟡] Code for CLI harness manual update instruction [formatHarnessManualUpdateInstruction](src/cli/cli-commands/common/harness/formatHarnessManualUpdateInstruction.ts) should never be published outside of `@promptbook/cli`
|
|
43248
|
+
|
|
43249
|
+
/**
|
|
43250
|
+
* Decides how one outdated CLI coding harness should be updated.
|
|
43251
|
+
*
|
|
43252
|
+
* The plan follows the way the harness was installed, because `npm install -g` updates only a harness
|
|
43253
|
+
* which npm owns and installs a **second** copy of every other one.
|
|
43254
|
+
*
|
|
43255
|
+
* @private internal utility of `promptbookCli`
|
|
43256
|
+
*/
|
|
43257
|
+
function resolveHarnessUpdatePlan(definition, installationMethod) {
|
|
43258
|
+
if (installationMethod === 'npm-global') {
|
|
43259
|
+
return {
|
|
43260
|
+
command: buildHarnessInstallCommand(definition),
|
|
43261
|
+
isRunnableByPromptbook: true,
|
|
43262
|
+
environment: definition.npmInstallEnvironment,
|
|
43263
|
+
};
|
|
43264
|
+
}
|
|
43265
|
+
if (installationMethod === 'standalone' && definition.standaloneInstallation !== undefined) {
|
|
43266
|
+
return {
|
|
43267
|
+
command: definition.standaloneInstallation.updateCommand,
|
|
43268
|
+
isRunnableByPromptbook: true,
|
|
43269
|
+
};
|
|
43270
|
+
}
|
|
43271
|
+
if (installationMethod === 'homebrew') {
|
|
43272
|
+
// Note: The formula may be named differently than the command, so the update is only suggested
|
|
43273
|
+
return {
|
|
43274
|
+
command: `brew upgrade ${definition.commandName}`,
|
|
43275
|
+
isRunnableByPromptbook: false,
|
|
43276
|
+
};
|
|
43277
|
+
}
|
|
43278
|
+
return {
|
|
43279
|
+
command: null,
|
|
43280
|
+
isRunnableByPromptbook: false,
|
|
43281
|
+
};
|
|
43282
|
+
}
|
|
43283
|
+
// Note: [🟡] Code for CLI harness update planning [resolveHarnessUpdatePlan](src/cli/cli-commands/common/harness/resolveHarnessUpdatePlan.ts) should never be published outside of `@promptbook/cli`
|
|
43191
43284
|
|
|
43192
43285
|
/**
|
|
43193
43286
|
* Reports one detected harness installation status and offers to install or update the harness.
|
|
43194
43287
|
*
|
|
43195
|
-
* Note: `$` is used to indicate that this function is not a pure function - it asks the user and installs
|
|
43288
|
+
* Note: `$` is used to indicate that this function is not a pure function - it asks the user and installs software
|
|
43196
43289
|
*
|
|
43197
43290
|
* @private internal utility of `promptbookCli`
|
|
43198
43291
|
*/
|
|
43199
43292
|
async function $applyHarnessInstallationStatus(status) {
|
|
43200
|
-
const { definition, installationState, installedVersion
|
|
43293
|
+
const { definition, installationState, installedVersion } = status;
|
|
43201
43294
|
if (installationState === 'up-to-date') {
|
|
43202
43295
|
console.info(colors__default["default"].gray(`✔ ${definition.label} ${installedVersion} is up to date.`));
|
|
43203
43296
|
return;
|
|
@@ -43211,14 +43304,50 @@
|
|
|
43211
43304
|
return;
|
|
43212
43305
|
}
|
|
43213
43306
|
console.warn(colors__default["default"].yellow(formatHarnessInstallationWarning(status)));
|
|
43214
|
-
|
|
43215
|
-
|
|
43216
|
-
|
|
43307
|
+
if (installationState === 'not-installed') {
|
|
43308
|
+
await $applyMissingHarnessInstallation(definition);
|
|
43309
|
+
return;
|
|
43310
|
+
}
|
|
43311
|
+
await $applyOutdatedHarnessInstallation(status);
|
|
43312
|
+
}
|
|
43313
|
+
/**
|
|
43314
|
+
* Offers to install a missing harness globally through npm.
|
|
43315
|
+
*/
|
|
43316
|
+
async function $applyMissingHarnessInstallation(definition) {
|
|
43317
|
+
const installCommand = buildHarnessInstallCommand(definition);
|
|
43318
|
+
const isInstallationApproved = await $askForNpmPackageInstallationApproval(`Install ${definition.label} globally now?`);
|
|
43217
43319
|
if (!isInstallationApproved) {
|
|
43218
|
-
console.info(colors__default["default"].gray(`Skipped, run \`${
|
|
43320
|
+
console.info(colors__default["default"].gray(`Skipped, run \`${installCommand}\` to do it manually.`));
|
|
43219
43321
|
return;
|
|
43220
43322
|
}
|
|
43221
|
-
await $
|
|
43323
|
+
await $runHarnessInstallationCommand({
|
|
43324
|
+
definition,
|
|
43325
|
+
operation: 'install',
|
|
43326
|
+
command: installCommand,
|
|
43327
|
+
environment: definition.npmInstallEnvironment,
|
|
43328
|
+
});
|
|
43329
|
+
}
|
|
43330
|
+
/**
|
|
43331
|
+
* Offers to update an outdated harness exactly where it is installed.
|
|
43332
|
+
*/
|
|
43333
|
+
async function $applyOutdatedHarnessInstallation(status) {
|
|
43334
|
+
const { definition, latestVersion, installationOrigin } = status;
|
|
43335
|
+
const updatePlan = resolveHarnessUpdatePlan(definition, installationOrigin.installationMethod);
|
|
43336
|
+
if (updatePlan.command === null || !updatePlan.isRunnableByPromptbook) {
|
|
43337
|
+
console.info(colors__default["default"].gray(formatHarnessManualUpdateInstruction(status, updatePlan)));
|
|
43338
|
+
return;
|
|
43339
|
+
}
|
|
43340
|
+
const isUpdateApproved = await $askForNpmPackageInstallationApproval(`Update ${definition.label} to ${latestVersion} with \`${updatePlan.command}\` now?`);
|
|
43341
|
+
if (!isUpdateApproved) {
|
|
43342
|
+
console.info(colors__default["default"].gray(`Skipped, run \`${updatePlan.command}\` to do it manually.`));
|
|
43343
|
+
return;
|
|
43344
|
+
}
|
|
43345
|
+
await $runHarnessInstallationCommand({
|
|
43346
|
+
definition,
|
|
43347
|
+
operation: 'update',
|
|
43348
|
+
command: updatePlan.command,
|
|
43349
|
+
environment: updatePlan.environment,
|
|
43350
|
+
});
|
|
43222
43351
|
}
|
|
43223
43352
|
// Note: [🟡] Code for CLI harness installation handling [$applyHarnessInstallationStatus](src/cli/cli-commands/common/harness/$applyHarnessInstallationStatus.ts) should never be published outside of `@promptbook/cli`
|
|
43224
43353
|
|
|
@@ -43418,6 +43547,186 @@
|
|
|
43418
43547
|
}
|
|
43419
43548
|
// Note: [🟡] Code for CLI npm package version comparison [isNpmPackageVersionOutdated](src/cli/cli-commands/common/npm/isNpmPackageVersionOutdated.ts) should never be published outside of `@promptbook/cli`
|
|
43420
43549
|
|
|
43550
|
+
/**
|
|
43551
|
+
* Time limit for asking npm where it installs global packages.
|
|
43552
|
+
*/
|
|
43553
|
+
const NPM_GLOBAL_PREFIX_COMMAND_TIMEOUT_MS = 30 * 1000;
|
|
43554
|
+
/**
|
|
43555
|
+
* Cached lookup, because the global npm prefix cannot change while one command runs and several
|
|
43556
|
+
* harnesses are checked at the same time.
|
|
43557
|
+
*/
|
|
43558
|
+
let npmGlobalPrefixPathPromise = null;
|
|
43559
|
+
/**
|
|
43560
|
+
* Reads the root directory under which npm installs global packages.
|
|
43561
|
+
*
|
|
43562
|
+
* Note: `$` is used to indicate that this function is not a pure function - it runs npm
|
|
43563
|
+
*
|
|
43564
|
+
* @returns The global npm prefix or `null` when npm could not be asked for it
|
|
43565
|
+
* @private internal utility of `promptbookCli`
|
|
43566
|
+
*/
|
|
43567
|
+
function $resolveNpmGlobalPrefixPath() {
|
|
43568
|
+
if (npmGlobalPrefixPathPromise === null) {
|
|
43569
|
+
npmGlobalPrefixPathPromise = $readNpmGlobalPrefixPath();
|
|
43570
|
+
}
|
|
43571
|
+
return npmGlobalPrefixPathPromise;
|
|
43572
|
+
}
|
|
43573
|
+
/**
|
|
43574
|
+
* Asks npm for the global prefix once.
|
|
43575
|
+
*/
|
|
43576
|
+
async function $readNpmGlobalPrefixPath() {
|
|
43577
|
+
const output = await $execCommand({
|
|
43578
|
+
command: 'npm prefix --global --loglevel=error',
|
|
43579
|
+
crashOnError: true,
|
|
43580
|
+
timeout: NPM_GLOBAL_PREFIX_COMMAND_TIMEOUT_MS,
|
|
43581
|
+
isVerbose: false,
|
|
43582
|
+
}).catch(() => '');
|
|
43583
|
+
// Note: npm prints the prefix as the last line, warnings emitted before it are ignored
|
|
43584
|
+
const prefixPath = output
|
|
43585
|
+
.split('\n')
|
|
43586
|
+
.map((line) => line.trim())
|
|
43587
|
+
.filter((line) => line !== '')
|
|
43588
|
+
.pop();
|
|
43589
|
+
return prefixPath !== null && prefixPath !== void 0 ? prefixPath : null;
|
|
43590
|
+
}
|
|
43591
|
+
// Note: [🟡] Code for CLI npm global prefix lookup [$resolveNpmGlobalPrefixPath](src/cli/cli-commands/common/npm/$resolveNpmGlobalPrefixPath.ts) should never be published outside of `@promptbook/cli`
|
|
43592
|
+
|
|
43593
|
+
/**
|
|
43594
|
+
* Time limit for looking up where the harness command lives.
|
|
43595
|
+
*/
|
|
43596
|
+
const HARNESS_COMMAND_LOOKUP_TIMEOUT_MS = 30 * 1000;
|
|
43597
|
+
/**
|
|
43598
|
+
* Finds out which file is really executed when the harness command runs.
|
|
43599
|
+
*
|
|
43600
|
+
* The lookup deliberately uses the very same `PATH` which runs the harness, so it reports the copy of the
|
|
43601
|
+
* harness which Promptbook itself would use. Symbolic links are followed, because installers like the
|
|
43602
|
+
* standalone OpenAI Codex installer only link their package into a directory on `PATH`.
|
|
43603
|
+
*
|
|
43604
|
+
* Note: `$` is used to indicate that this function is not a pure function - it runs a command in a shell
|
|
43605
|
+
*
|
|
43606
|
+
* @returns Resolved path of the harness command or `null` when the command is not available
|
|
43607
|
+
* @private internal utility of `promptbookCli`
|
|
43608
|
+
*/
|
|
43609
|
+
async function $resolveHarnessCommandPath(definition) {
|
|
43610
|
+
const lookupCommand = process.platform === 'win32' ? `where ${definition.commandName}` : `command -v ${definition.commandName}`;
|
|
43611
|
+
const output = await $execCommand({
|
|
43612
|
+
command: lookupCommand,
|
|
43613
|
+
crashOnError: true,
|
|
43614
|
+
timeout: HARNESS_COMMAND_LOOKUP_TIMEOUT_MS,
|
|
43615
|
+
isVerbose: false,
|
|
43616
|
+
}).catch(() => '');
|
|
43617
|
+
// Note: `where` lists every match on its own line, only the first one is really executed
|
|
43618
|
+
const commandPath = output
|
|
43619
|
+
.split('\n')
|
|
43620
|
+
.map((line) => line.trim())
|
|
43621
|
+
.find((line) => line !== '');
|
|
43622
|
+
if (commandPath === undefined) {
|
|
43623
|
+
return null;
|
|
43624
|
+
}
|
|
43625
|
+
return await promises.realpath(commandPath).catch(() => commandPath);
|
|
43626
|
+
}
|
|
43627
|
+
// Note: [🟡] Code for CLI harness command lookup [$resolveHarnessCommandPath](src/cli/cli-commands/common/harness/$resolveHarnessCommandPath.ts) should never be published outside of `@promptbook/cli`
|
|
43628
|
+
|
|
43629
|
+
/**
|
|
43630
|
+
* Origin used when the harness command was not looked up at all, for example when the update check is disabled.
|
|
43631
|
+
*
|
|
43632
|
+
* @private internal utility of `promptbookCli`
|
|
43633
|
+
*/
|
|
43634
|
+
const UNKNOWN_HARNESS_INSTALLATION_ORIGIN = {
|
|
43635
|
+
commandPath: null,
|
|
43636
|
+
installationMethod: 'unknown',
|
|
43637
|
+
};
|
|
43638
|
+
// Note: [🟡] Code for CLI harness installation origin [HarnessInstallationOrigin](src/cli/cli-commands/common/harness/HarnessInstallationOrigin.ts) should never be published outside of `@promptbook/cli`
|
|
43639
|
+
|
|
43640
|
+
/**
|
|
43641
|
+
* Directory which holds npm packages, so it appears in the resolved path of every globally installed npm binary
|
|
43642
|
+
* on systems where the global binary is only a symbolic link into the package.
|
|
43643
|
+
*
|
|
43644
|
+
* Note: Written in lower case because it is compared against normalized paths.
|
|
43645
|
+
*/
|
|
43646
|
+
const NODE_MODULES_DIRECTORY_NAME$1 = 'node_modules';
|
|
43647
|
+
/**
|
|
43648
|
+
* Directory into which Homebrew unpacks every formula, so it appears in the resolved path of
|
|
43649
|
+
* everything Homebrew manages and in nothing else.
|
|
43650
|
+
*
|
|
43651
|
+
* Note: Written in lower case because it is compared against normalized paths.
|
|
43652
|
+
*/
|
|
43653
|
+
const HOMEBREW_DIRECTORY_NAME = 'cellar';
|
|
43654
|
+
/**
|
|
43655
|
+
* Decides how a harness command was installed from the place where it really lives.
|
|
43656
|
+
*
|
|
43657
|
+
* Only a command which npm owns may be updated with `npm install -g`, every other command has to be
|
|
43658
|
+
* updated where it is installed, otherwise the update silently adds a second copy of the harness.
|
|
43659
|
+
*
|
|
43660
|
+
* @private internal utility of `promptbookCli`
|
|
43661
|
+
*/
|
|
43662
|
+
function resolveHarnessInstallationMethodFromPaths(paths) {
|
|
43663
|
+
var _a, _b;
|
|
43664
|
+
const { definition, commandPath, npmGlobalPrefixPath } = paths;
|
|
43665
|
+
const normalizedCommandPath = normalizeInstallationPath(commandPath);
|
|
43666
|
+
const commandPathDirectoryNames = normalizedCommandPath.split('/');
|
|
43667
|
+
// Note: A Homebrew formula may bundle its own `node_modules` and may live under the npm prefix of a
|
|
43668
|
+
// Homebrew-installed Node, so Homebrew has to be recognized before anything npm-shaped
|
|
43669
|
+
if (commandPathDirectoryNames.includes(HOMEBREW_DIRECTORY_NAME)) {
|
|
43670
|
+
return 'homebrew';
|
|
43671
|
+
}
|
|
43672
|
+
const standaloneDirectoryNames = (_b = (_a = definition.standaloneInstallation) === null || _a === void 0 ? void 0 : _a.directoryNames) !== null && _b !== void 0 ? _b : [];
|
|
43673
|
+
if (standaloneDirectoryNames.some((directoryName) => commandPathDirectoryNames.includes(normalizeInstallationPath(directoryName)))) {
|
|
43674
|
+
return 'standalone';
|
|
43675
|
+
}
|
|
43676
|
+
// Note: npm is not always reachable, but its own package directory is a reliable fallback marker
|
|
43677
|
+
if (normalizedCommandPath.includes(`/${NODE_MODULES_DIRECTORY_NAME$1}/${normalizeInstallationPath(definition.npmPackageName)}/`)) {
|
|
43678
|
+
return 'npm-global';
|
|
43679
|
+
}
|
|
43680
|
+
if (isPathInsideDirectory(normalizedCommandPath, npmGlobalPrefixPath)) {
|
|
43681
|
+
return 'npm-global';
|
|
43682
|
+
}
|
|
43683
|
+
return 'unknown';
|
|
43684
|
+
}
|
|
43685
|
+
/**
|
|
43686
|
+
* Normalizes one path so that paths coming from different tools and platforms can be compared.
|
|
43687
|
+
*
|
|
43688
|
+
* Note: The comparison is case-insensitive because Windows paths are, and two harness paths which differ
|
|
43689
|
+
* only in letter casing do not exist in practice.
|
|
43690
|
+
*/
|
|
43691
|
+
function normalizeInstallationPath(path) {
|
|
43692
|
+
return path.trim().replace(/\\/gu, '/').replace(/\/+$/u, '').toLowerCase();
|
|
43693
|
+
}
|
|
43694
|
+
/**
|
|
43695
|
+
* Checks whether one path lies inside a directory.
|
|
43696
|
+
*/
|
|
43697
|
+
function isPathInsideDirectory(normalizedPath, directoryPath) {
|
|
43698
|
+
if (directoryPath === null) {
|
|
43699
|
+
return false;
|
|
43700
|
+
}
|
|
43701
|
+
const normalizedDirectoryPath = normalizeInstallationPath(directoryPath);
|
|
43702
|
+
return normalizedDirectoryPath !== '' && normalizedPath.startsWith(`${normalizedDirectoryPath}/`);
|
|
43703
|
+
}
|
|
43704
|
+
// Note: [🟡] Code for CLI harness installation method detection [resolveHarnessInstallationMethodFromPaths](src/cli/cli-commands/common/harness/resolveHarnessInstallationMethodFromPaths.ts) should never be published outside of `@promptbook/cli`
|
|
43705
|
+
|
|
43706
|
+
/**
|
|
43707
|
+
* Finds out where one CLI coding harness is really installed and which tool manages it.
|
|
43708
|
+
*
|
|
43709
|
+
* Note: `$` is used to indicate that this function is not a pure function - it runs shell commands
|
|
43710
|
+
*
|
|
43711
|
+
* @private internal utility of `promptbookCli`
|
|
43712
|
+
*/
|
|
43713
|
+
async function $resolveHarnessInstallationOrigin(definition) {
|
|
43714
|
+
const commandPath = await $resolveHarnessCommandPath(definition);
|
|
43715
|
+
if (commandPath === null) {
|
|
43716
|
+
return UNKNOWN_HARNESS_INSTALLATION_ORIGIN;
|
|
43717
|
+
}
|
|
43718
|
+
const npmGlobalPrefixPath = await $resolveNpmGlobalPrefixPath();
|
|
43719
|
+
return {
|
|
43720
|
+
commandPath,
|
|
43721
|
+
installationMethod: resolveHarnessInstallationMethodFromPaths({
|
|
43722
|
+
definition,
|
|
43723
|
+
commandPath,
|
|
43724
|
+
npmGlobalPrefixPath,
|
|
43725
|
+
}),
|
|
43726
|
+
};
|
|
43727
|
+
}
|
|
43728
|
+
// Note: [🟡] Code for CLI harness installation origin detection [$resolveHarnessInstallationOrigin](src/cli/cli-commands/common/harness/$resolveHarnessInstallationOrigin.ts) should never be published outside of `@promptbook/cli`
|
|
43729
|
+
|
|
43421
43730
|
/**
|
|
43422
43731
|
* Detects whether one CLI coding harness is installed globally and, when enabled, whether it is up to date.
|
|
43423
43732
|
*
|
|
@@ -43426,17 +43735,22 @@
|
|
|
43426
43735
|
* @private internal utility of `promptbookCli`
|
|
43427
43736
|
*/
|
|
43428
43737
|
async function $checkHarnessInstallation(definition, isHarnessUpdateCheckEnabled = true) {
|
|
43429
|
-
|
|
43738
|
+
// Note: The origin is only needed to update an outdated harness, so it is not looked up without the update check
|
|
43739
|
+
const [installedVersion, latestVersion, installationOrigin] = await Promise.all([
|
|
43430
43740
|
$resolveInstalledHarnessVersion(definition),
|
|
43431
43741
|
isHarnessUpdateCheckEnabled
|
|
43432
43742
|
? $resolveLatestNpmPackageVersion(definition.npmPackageName)
|
|
43433
43743
|
: Promise.resolve(null),
|
|
43744
|
+
isHarnessUpdateCheckEnabled
|
|
43745
|
+
? $resolveHarnessInstallationOrigin(definition)
|
|
43746
|
+
: Promise.resolve(UNKNOWN_HARNESS_INSTALLATION_ORIGIN),
|
|
43434
43747
|
]);
|
|
43435
43748
|
return {
|
|
43436
43749
|
definition,
|
|
43437
43750
|
installationState: resolveHarnessInstallationState(installedVersion, latestVersion, isHarnessUpdateCheckEnabled),
|
|
43438
43751
|
installedVersion,
|
|
43439
43752
|
latestVersion,
|
|
43753
|
+
installationOrigin,
|
|
43440
43754
|
};
|
|
43441
43755
|
}
|
|
43442
43756
|
/**
|
|
@@ -43495,7 +43809,7 @@
|
|
|
43495
43809
|
* @private internal utility of `promptbookCli`
|
|
43496
43810
|
*/
|
|
43497
43811
|
function addHarnessUpdateOption(command) {
|
|
43498
|
-
command.option('--no-harness-update', 'Skip checking whether
|
|
43812
|
+
command.option('--no-harness-update', 'Skip checking whether the installed coding harnesses are up to date');
|
|
43499
43813
|
}
|
|
43500
43814
|
/**
|
|
43501
43815
|
* Converts the Commander harness-update flag into the normalized harness-check option.
|
|
@@ -44072,7 +44386,7 @@
|
|
|
44072
44386
|
- CODING_AGENT_GIT_EMAIL
|
|
44073
44387
|
- CODING_AGENT_GIT_SIGNING_KEY
|
|
44074
44388
|
|
|
44075
|
-
Checks that the coding harnesses are installed
|
|
44389
|
+
Checks that the coding harnesses are installed and up to date unless \`--no-harness-update\` is used:
|
|
44076
44390
|
${block(listCheckedHarnessLabels())}
|
|
44077
44391
|
|
|
44078
44392
|
${block(CODER_GIT_SYNC_DESCRIPTION)}
|
|
@@ -44180,7 +44494,7 @@
|
|
|
44180
44494
|
- Starts the hourly/weekly quota window before you need it, so it is already refreshing when you do
|
|
44181
44495
|
- Optional --period keeps the quota window refreshing by pinging once per period until stopped
|
|
44182
44496
|
- Leaves the project exactly as it was — nothing is read, written, changed or committed
|
|
44183
|
-
- Checks that the selected harness is installed
|
|
44497
|
+
- Checks that the selected harness is installed and up to date unless --no-harness-update is used
|
|
44184
44498
|
- Use --no-ui to stream the raw harness output instead of only the compact result
|
|
44185
44499
|
`));
|
|
44186
44500
|
addPromptRunnerSelectionOptions(command);
|
|
@@ -44674,7 +44988,7 @@
|
|
|
44674
44988
|
- Optional --isolate runs every prompt in its own temporary git worktree and merges it back when verified
|
|
44675
44989
|
- Optional --preserve-logs keeps temp prompt/log artifacts after successful rounds
|
|
44676
44990
|
- Optional --no-ui keeps plain streaming console output for logging and debugging
|
|
44677
|
-
- Checks that the selected harness is installed
|
|
44991
|
+
- Checks that the selected harness is installed and up to date before the first prompt unless --no-harness-update is used
|
|
44678
44992
|
- In interactive mode, checks local and global Promptbook CLI installations and offers to update them
|
|
44679
44993
|
- Supports GPG signing of commits
|
|
44680
44994
|
- Optional pre-coding test run that can stop or repair pre-existing failures
|
|
@@ -44831,7 +45145,7 @@
|
|
|
44831
45145
|
|
|
44832
45146
|
Features:
|
|
44833
45147
|
- Runs the same prompt processing as \`ptbk coder run\`
|
|
44834
|
-
- Checks that the selected harness is installed
|
|
45148
|
+
- Checks that the selected harness is installed and up to date on startup unless --no-harness-update is used
|
|
44835
45149
|
- Does not exit when all prompts are done; polls for new prompt files instead
|
|
44836
45150
|
- Serves a kanban board at http://localhost:<port> for visual progress tracking
|
|
44837
45151
|
- Allows editing prompt files directly from the browser (Trello-style)
|