@promptbook/cli 0.114.0-32 → 0.114.0-34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/esm/index.es.js +1417 -400
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/scripts/run-codex-prompts/common/createFreeDiskSpaceGuard.d.ts +25 -0
  4. package/esm/scripts/run-codex-prompts/common/formatUnknownErrorDetails.d.ts +4 -0
  5. package/esm/scripts/run-codex-prompts/common/resolveCoderAgent.d.ts +21 -3
  6. package/esm/scripts/run-codex-prompts/main/listCoderPrompts.d.ts +20 -0
  7. package/esm/scripts/run-codex-prompts/prompts/buildPromptRunTraceContent.d.ts +77 -0
  8. package/esm/scripts/run-codex-prompts/prompts/buildPromptRunTracePath.d.ts +10 -0
  9. package/esm/scripts/run-codex-prompts/prompts/isPromptCompatibleWithRunner.d.ts +11 -6
  10. package/esm/scripts/run-codex-prompts/prompts/loadPromptFiles.d.ts +1 -1
  11. package/esm/scripts/run-codex-prompts/prompts/writePromptRunTrace.d.ts +19 -0
  12. package/esm/scripts/run-codex-prompts/runners/common/buildHarnessAuthenticationError.d.ts +20 -0
  13. package/esm/scripts/run-codex-prompts/runners/common/createAuthenticationAwarePromptRunner.d.ts +11 -0
  14. package/esm/scripts/run-codex-prompts/runners/common/extractHarnessAuthenticationFailureReason.d.ts +9 -0
  15. package/esm/scripts/run-codex-prompts/ui/buildCoderRunUiFrame.d.ts +3 -0
  16. package/esm/src/book-2.0/book-language-documentation/getSafeCodeBlock.d.ts +1 -1
  17. package/esm/src/book-components/Chat/MockedChat/MockedChat.test.d.ts +2 -0
  18. package/esm/src/cli/cli-commands/coder/$ensureCoderHarnessGitignoreRules.d.ts +2 -1
  19. package/esm/src/cli/cli-commands/coder/agentCliOptions.d.ts +21 -0
  20. package/esm/src/cli/cli-commands/coder/boilerplateTemplates.d.ts +8 -21
  21. package/esm/src/cli/cli-commands/coder/coderReferencedArtifacts.d.ts +33 -0
  22. package/esm/src/cli/cli-commands/coder/ensureCoderPackageJsonFile.d.ts +4 -2
  23. package/esm/src/cli/cli-commands/coder/ensureCoderVscodeSettingsFile.d.ts +2 -0
  24. package/esm/src/cli/cli-commands/coder/ensureDirectory.d.ts +6 -0
  25. package/esm/src/cli/cli-commands/coder/getDefaultCoderPackageJsonScripts.d.ts +6 -0
  26. package/esm/src/cli/cli-commands/coder/initializeCoderProjectConfiguration.d.ts +7 -5
  27. package/esm/src/cli/cli-commands/coder/list.d.ts +10 -0
  28. package/esm/src/cli/cli-commands/coder/mergeStringRecordJsonFile.d.ts +19 -1
  29. package/esm/src/cli/cli-commands/coder/printCoderRunFailure.d.ts +6 -0
  30. package/esm/src/cli/cli-commands/coder.d.ts +1 -0
  31. package/esm/src/cli/cli-commands/common/$askForConfirmation.d.ts +4 -2
  32. package/esm/src/cli/cli-commands/common/$askForConfirmation.test.d.ts +1 -0
  33. package/esm/src/cli/cli-commands/common/disk-space/$assertSufficientFreeDiskSpace.d.ts +12 -0
  34. package/esm/src/cli/cli-commands/common/disk-space/$assertSufficientFreeDiskSpace.test.d.ts +1 -0
  35. package/esm/src/cli/cli-commands/common/disk-space/$readFreeDiskSpaceStatus.d.ts +11 -0
  36. package/esm/src/cli/cli-commands/common/disk-space/$readFreeDiskSpaceStatus.test.d.ts +1 -0
  37. package/esm/src/cli/cli-commands/common/disk-space/FreeDiskSpaceStatus.d.ts +33 -0
  38. package/esm/src/cli/cli-commands/common/disk-space/formatFreeDiskSpaceBytes.d.ts +6 -0
  39. package/esm/src/cli/cli-commands/common/disk-space/formatFreeDiskSpaceBytes.test.d.ts +1 -0
  40. package/esm/src/cli/cli-commands/common/disk-space/formatLowFreeDiskSpaceWarning.d.ts +10 -0
  41. package/esm/src/cli/cli-commands/common/disk-space/freeDiskSpaceConstants.d.ts +28 -0
  42. package/esm/src/cli/cli-commands/common/disk-space/resolveFreeDiskSpaceLevel.d.ts +7 -0
  43. package/esm/src/cli/cli-commands/common/disk-space/resolveFreeDiskSpaceLevel.test.d.ts +1 -0
  44. package/esm/src/cli/cli-commands/common/harness/$applyHarnessInstallationStatus.d.ts +2 -1
  45. package/esm/src/cli/cli-commands/common/harness/$ensureHarnessInstallations.d.ts +3 -2
  46. package/esm/src/cli/cli-commands/common/harness/HarnessDefinition.d.ts +26 -0
  47. package/esm/src/cli/cli-commands/common/npm/$askForNpmPackageInstallationApproval.d.ts +4 -2
  48. package/esm/src/cli/cli-commands/common/promptPriorityCliOptions.d.ts +7 -0
  49. package/esm/src/cli/cli-commands/common/promptbook-cli/$ensurePromptbookCliInstallations.d.ts +2 -1
  50. package/esm/src/cli/cli-commands/common/questionsCliOptions.d.ts +45 -0
  51. package/esm/src/cli/cli-commands/common/questionsCliOptions.test.d.ts +1 -0
  52. package/esm/src/cli/common/$deprecateCliCommand.d.ts +3 -0
  53. package/esm/src/cli/common/$hideCliCommandFromHelp.d.ts +11 -0
  54. package/esm/src/cli/common/$hideCliCommandFromHelp.test.d.ts +1 -0
  55. package/esm/src/cli/common/$requireCliSubcommand.d.ts +18 -0
  56. package/esm/src/cli/common/$requireCliSubcommand.test.d.ts +1 -0
  57. package/esm/src/llm-providers/vercel/VercelExecutionToolsOptions.d.ts +5 -2
  58. package/esm/src/version.d.ts +1 -1
  59. package/package.json +8 -11
  60. package/src/book-2.0/book-language-documentation/getSafeCodeBlock.ts +1 -1
  61. package/src/book-components/Chat/MockedChat/MockedChat.tsx +25 -1
  62. package/src/cli/cli-commands/agent-folder.ts +2 -6
  63. package/src/cli/cli-commands/agent.ts +2 -6
  64. package/src/cli/cli-commands/agents-server.ts +2 -6
  65. package/src/cli/cli-commands/coder/$ensureCoderHarnessGitignoreRules.ts +3 -0
  66. package/src/cli/cli-commands/coder/add.ts +27 -2
  67. package/src/cli/cli-commands/coder/agentCliOptions.ts +32 -0
  68. package/src/cli/cli-commands/coder/boilerplateTemplates.ts +17 -44
  69. package/src/cli/cli-commands/coder/coderReferencedArtifacts.ts +106 -0
  70. package/src/cli/cli-commands/coder/ensureCoderPackageJsonFile.ts +4 -2
  71. package/src/cli/cli-commands/coder/ensureCoderVscodeSettingsFile.ts +5 -1
  72. package/src/cli/cli-commands/coder/ensureDirectory.ts +27 -1
  73. package/src/cli/cli-commands/coder/getDefaultCoderPackageJsonScripts.ts +99 -10
  74. package/src/cli/cli-commands/coder/init.ts +23 -14
  75. package/src/cli/cli-commands/coder/initializeCoderProjectConfiguration.ts +18 -27
  76. package/src/cli/cli-commands/coder/list.ts +89 -0
  77. package/src/cli/cli-commands/coder/mergeStringRecordJsonFile.ts +31 -7
  78. package/src/cli/cli-commands/coder/ping.ts +25 -22
  79. package/src/cli/cli-commands/coder/printCoderRunFailure.ts +14 -0
  80. package/src/cli/cli-commands/coder/printInitializationSummary.ts +23 -16
  81. package/src/cli/cli-commands/coder/run.ts +36 -39
  82. package/src/cli/cli-commands/coder/server.ts +45 -48
  83. package/src/cli/cli-commands/coder.ts +6 -6
  84. package/src/cli/cli-commands/common/$askForConfirmation.ts +12 -2
  85. package/src/cli/cli-commands/common/disk-space/$assertSufficientFreeDiskSpace.ts +35 -0
  86. package/src/cli/cli-commands/common/disk-space/$readFreeDiskSpaceStatus.ts +37 -0
  87. package/src/cli/cli-commands/common/disk-space/FreeDiskSpaceStatus.ts +39 -0
  88. package/src/cli/cli-commands/common/disk-space/formatFreeDiskSpaceBytes.ts +26 -0
  89. package/src/cli/cli-commands/common/disk-space/formatLowFreeDiskSpaceWarning.ts +33 -0
  90. package/src/cli/cli-commands/common/disk-space/freeDiskSpaceConstants.ts +33 -0
  91. package/src/cli/cli-commands/common/disk-space/resolveFreeDiskSpaceLevel.ts +21 -0
  92. package/src/cli/cli-commands/common/harness/$applyHarnessInstallationStatus.ts +17 -5
  93. package/src/cli/cli-commands/common/harness/$ensureHarnessInstallations.ts +8 -3
  94. package/src/cli/cli-commands/common/harness/HarnessDefinition.ts +36 -0
  95. package/src/cli/cli-commands/common/npm/$askForNpmPackageInstallationApproval.ts +8 -3
  96. package/src/cli/cli-commands/common/promptPriorityCliOptions.ts +30 -0
  97. package/src/cli/cli-commands/common/promptRunnerCliOptions.ts +5 -5
  98. package/src/cli/cli-commands/common/promptbook-cli/$ensurePromptbookCliInstallations.ts +13 -2
  99. package/src/cli/cli-commands/common/questionsCliOptions.ts +89 -0
  100. package/src/cli/cli-commands/run.ts +3 -1
  101. package/src/cli/common/$deprecateCliCommand.ts +5 -0
  102. package/src/cli/common/$hideCliCommandFromHelp.ts +27 -0
  103. package/src/cli/common/$requireCliSubcommand.ts +35 -0
  104. package/src/cli/promptbookCli.ts +13 -9
  105. package/src/llm-providers/vercel/VercelExecutionToolsOptions.ts +7 -2
  106. package/src/llm-providers/vercel/createExecutionToolsFromVercelProvider.ts +18 -17
  107. package/src/other/templates/getTemplatesPipelineCollection.ts +695 -707
  108. package/src/version.ts +2 -2
  109. package/src/versions.txt +2 -0
  110. package/umd/index.umd.js +1416 -399
  111. package/umd/index.umd.js.map +1 -1
  112. package/umd/scripts/run-codex-prompts/common/createFreeDiskSpaceGuard.d.ts +25 -0
  113. package/umd/scripts/run-codex-prompts/common/formatUnknownErrorDetails.d.ts +4 -0
  114. package/umd/scripts/run-codex-prompts/common/resolveCoderAgent.d.ts +21 -3
  115. package/umd/scripts/run-codex-prompts/main/listCoderPrompts.d.ts +20 -0
  116. package/umd/scripts/run-codex-prompts/prompts/buildPromptRunTraceContent.d.ts +77 -0
  117. package/umd/scripts/run-codex-prompts/prompts/buildPromptRunTracePath.d.ts +10 -0
  118. package/umd/scripts/run-codex-prompts/prompts/isPromptCompatibleWithRunner.d.ts +11 -6
  119. package/umd/scripts/run-codex-prompts/prompts/loadPromptFiles.d.ts +1 -1
  120. package/umd/scripts/run-codex-prompts/prompts/writePromptRunTrace.d.ts +19 -0
  121. package/umd/scripts/run-codex-prompts/runners/common/buildHarnessAuthenticationError.d.ts +20 -0
  122. package/umd/scripts/run-codex-prompts/runners/common/createAuthenticationAwarePromptRunner.d.ts +11 -0
  123. package/umd/scripts/run-codex-prompts/runners/common/extractHarnessAuthenticationFailureReason.d.ts +9 -0
  124. package/umd/scripts/run-codex-prompts/ui/buildCoderRunUiFrame.d.ts +3 -0
  125. package/umd/src/book-2.0/book-language-documentation/getSafeCodeBlock.d.ts +1 -1
  126. package/umd/src/book-components/Chat/MockedChat/MockedChat.test.d.ts +2 -0
  127. package/umd/src/cli/cli-commands/coder/$ensureCoderHarnessGitignoreRules.d.ts +2 -1
  128. package/umd/src/cli/cli-commands/coder/agentCliOptions.d.ts +21 -0
  129. package/umd/src/cli/cli-commands/coder/boilerplateTemplates.d.ts +8 -21
  130. package/umd/src/cli/cli-commands/coder/coderReferencedArtifacts.d.ts +33 -0
  131. package/umd/src/cli/cli-commands/coder/ensureCoderPackageJsonFile.d.ts +4 -2
  132. package/umd/src/cli/cli-commands/coder/ensureCoderVscodeSettingsFile.d.ts +2 -0
  133. package/umd/src/cli/cli-commands/coder/ensureDirectory.d.ts +6 -0
  134. package/umd/src/cli/cli-commands/coder/getDefaultCoderPackageJsonScripts.d.ts +6 -0
  135. package/umd/src/cli/cli-commands/coder/init.test.d.ts +1 -0
  136. package/umd/src/cli/cli-commands/coder/initializeCoderProjectConfiguration.d.ts +7 -5
  137. package/umd/src/cli/cli-commands/coder/list.d.ts +10 -0
  138. package/umd/src/cli/cli-commands/coder/list.test.d.ts +1 -0
  139. package/umd/src/cli/cli-commands/coder/mergeStringRecordJsonFile.d.ts +19 -1
  140. package/umd/src/cli/cli-commands/coder/printCoderRunFailure.d.ts +6 -0
  141. package/umd/src/cli/cli-commands/coder.d.ts +1 -0
  142. package/umd/src/cli/cli-commands/common/$askForConfirmation.d.ts +4 -2
  143. package/umd/src/cli/cli-commands/common/$askForConfirmation.test.d.ts +1 -0
  144. package/umd/src/cli/cli-commands/common/disk-space/$assertSufficientFreeDiskSpace.d.ts +12 -0
  145. package/umd/src/cli/cli-commands/common/disk-space/$assertSufficientFreeDiskSpace.test.d.ts +1 -0
  146. package/umd/src/cli/cli-commands/common/disk-space/$readFreeDiskSpaceStatus.d.ts +11 -0
  147. package/umd/src/cli/cli-commands/common/disk-space/$readFreeDiskSpaceStatus.test.d.ts +1 -0
  148. package/umd/src/cli/cli-commands/common/disk-space/FreeDiskSpaceStatus.d.ts +33 -0
  149. package/umd/src/cli/cli-commands/common/disk-space/formatFreeDiskSpaceBytes.d.ts +6 -0
  150. package/umd/src/cli/cli-commands/common/disk-space/formatFreeDiskSpaceBytes.test.d.ts +1 -0
  151. package/umd/src/cli/cli-commands/common/disk-space/formatLowFreeDiskSpaceWarning.d.ts +10 -0
  152. package/umd/src/cli/cli-commands/common/disk-space/freeDiskSpaceConstants.d.ts +28 -0
  153. package/umd/src/cli/cli-commands/common/disk-space/resolveFreeDiskSpaceLevel.d.ts +7 -0
  154. package/umd/src/cli/cli-commands/common/disk-space/resolveFreeDiskSpaceLevel.test.d.ts +1 -0
  155. package/umd/src/cli/cli-commands/common/harness/$applyHarnessInstallationStatus.d.ts +2 -1
  156. package/umd/src/cli/cli-commands/common/harness/$ensureHarnessInstallations.d.ts +3 -2
  157. package/umd/src/cli/cli-commands/common/harness/HarnessDefinition.d.ts +26 -0
  158. package/umd/src/cli/cli-commands/common/npm/$askForNpmPackageInstallationApproval.d.ts +4 -2
  159. package/umd/src/cli/cli-commands/common/promptPriorityCliOptions.d.ts +7 -0
  160. package/umd/src/cli/cli-commands/common/promptbook-cli/$ensurePromptbookCliInstallations.d.ts +2 -1
  161. package/umd/src/cli/cli-commands/common/questionsCliOptions.d.ts +45 -0
  162. package/umd/src/cli/cli-commands/common/questionsCliOptions.test.d.ts +1 -0
  163. package/umd/src/cli/common/$deprecateCliCommand.d.ts +3 -0
  164. package/umd/src/cli/common/$hideCliCommandFromHelp.d.ts +11 -0
  165. package/umd/src/cli/common/$hideCliCommandFromHelp.test.d.ts +1 -0
  166. package/umd/src/cli/common/$requireCliSubcommand.d.ts +18 -0
  167. package/umd/src/cli/common/$requireCliSubcommand.test.d.ts +1 -0
  168. package/umd/src/llm-providers/vercel/VercelExecutionToolsOptions.d.ts +5 -2
  169. package/umd/src/version.d.ts +1 -1
  170. package/esm/src/cli/cli-commands/coder/agentCodingFile.d.ts +0 -13
  171. package/esm/src/cli/cli-commands/common/harnessUpdateCliOptions.d.ts +0 -29
  172. package/src/cli/cli-commands/coder/agentCodingFile.ts +0 -25
  173. package/src/cli/cli-commands/common/harnessUpdateCliOptions.ts +0 -46
  174. package/umd/src/cli/cli-commands/coder/agentCodingFile.d.ts +0 -13
  175. package/umd/src/cli/cli-commands/common/harnessUpdateCliOptions.d.ts +0 -29
  176. /package/esm/src/cli/cli-commands/{common/harnessUpdateCliOptions.test.d.ts → coder/init.test.d.ts} +0 -0
  177. /package/{umd/src/cli/cli-commands/common/harnessUpdateCliOptions.test.d.ts → esm/src/cli/cli-commands/coder/list.test.d.ts} +0 -0
@@ -1,4 +1,3 @@
1
- import colors from 'colors';
2
1
  import {
3
2
  Command as Program /* <- Note: [🔸] Using Program because Command is misleading name */,
4
3
  Option,
@@ -9,14 +8,16 @@ import { assertsError } from '../../../errors/assertsError';
9
8
  import { NotAllowed } from '../../../errors/NotAllowed';
10
9
  import type { number_port } from '../../../types/number_positive';
11
10
  import type { $side_effect } from '../../../utils/organization/$side_effect';
12
- import { createNonNegativeIntegerOptionParser } from '../common/createNonNegativeIntegerOptionParser';
11
+ import { $assertSufficientFreeDiskSpace } from '../common/disk-space/$assertSufficientFreeDiskSpace';
13
12
  import { handleActionErrors } from '../common/handleActionErrors';
14
13
  import { $ensureHarnessInstallations } from '../common/harness/$ensureHarnessInstallations';
15
14
  import {
16
- addHarnessUpdateOption,
17
- normalizeHarnessUpdateCliOptions,
18
- type HarnessUpdateCliOptions,
19
- } from '../common/harnessUpdateCliOptions';
15
+ addQuestionsOption,
16
+ assertUserConfirmationIsAllowed,
17
+ normalizeQuestionsCliOptions,
18
+ QUESTIONS_DESCRIPTION,
19
+ type QuestionsCliOptions,
20
+ } from '../common/questionsCliOptions';
20
21
  import type { PromptRunnerCliOptions } from '../common/promptRunnerCliOptions';
21
22
  import {
22
23
  addPromptRunnerExecutionOptions,
@@ -24,8 +25,11 @@ import {
24
25
  normalizePromptRunnerCliOptions,
25
26
  PROMPT_RUNNER_DESCRIPTION,
26
27
  } from '../common/promptRunnerCliOptions';
28
+ import { addPromptPriorityOptions } from '../common/promptPriorityCliOptions';
27
29
  import { DEFAULT_WAIT_AFTER_ERROR_MS, parseOptionalWaitDuration } from './waitOptions';
28
30
  import { $ensureCoderHarnessGitignoreRules } from './$ensureCoderHarnessGitignoreRules';
31
+ import { addCoderAgentOption, type CoderAgentCliOptions } from './agentCliOptions';
32
+ import { printCoderRunFailure } from './printCoderRunFailure';
29
33
 
30
34
  /**
31
35
  * Default port used by `ptbk coder server`.
@@ -47,21 +51,26 @@ const DEFAULT_CODER_SERVER_PORT = '4441';
47
51
  export function $initializeCoderServerCommand(program: Program): $side_effect {
48
52
  const command = program.command('server');
49
53
  command.description(
50
- spaceTrim(`
51
- Start a coder server that watches for prompts and serves a kanban web UI
54
+ spaceTrim(
55
+ (block) => `
56
+ Start a coder server that watches for prompts and serves a kanban web UI
52
57
 
53
- ${PROMPT_RUNNER_DESCRIPTION}
58
+ ${block(PROMPT_RUNNER_DESCRIPTION)}
54
59
 
55
- Features:
56
- - Runs the same prompt processing as \`ptbk coder run\`
57
- - Checks that the selected harness is installed and up to date on startup unless --no-harness-update is used
58
- - Offers to add missing project-local ignore rules for the selected harness
59
- - Does not exit when all prompts are done; polls for new prompt files instead
60
- - Serves a kanban board at http://localhost:<port> for visual progress tracking
61
- - Allows editing prompt files directly from the browser (Trello-style)
62
- - Play / pause button in the browser stays in sync with the CLI pause state
63
- - Terminal controls match \`ptbk coder run\`: P pause/resume, S skip waiting, X end after current prompt
64
- `),
60
+ ${block(QUESTIONS_DESCRIPTION)}
61
+
62
+ Features:
63
+ - Runs the same prompt processing as \`ptbk coder run\`
64
+ - Refuses to start on a nearly full disk and pauses the run when the free disk space becomes critical, unless --no-questions is used
65
+ - Checks that the selected harness is installed and up to date on startup unless --no-questions is used
66
+ - Offers to add missing project-local ignore rules for the selected harness
67
+ - Does not exit when all prompts are done; polls for new prompt files instead
68
+ - Serves a kanban board at http://localhost:<port> for visual progress tracking
69
+ - Allows editing prompt files directly from the browser (Trello-style)
70
+ - Play / pause button in the browser stays in sync with the CLI pause state
71
+ - Terminal controls match \`ptbk coder run\`: P pause/resume, S skip waiting, X end after current prompt
72
+ `,
73
+ ),
65
74
  );
66
75
 
67
76
  command.addOption(
@@ -71,11 +80,8 @@ export function $initializeCoderServerCommand(program: Program): $side_effect {
71
80
  );
72
81
  command.option('--dry-run', 'Print unwritten prompts without executing', false);
73
82
  addPromptRunnerSelectionOptions(command);
74
- addHarnessUpdateOption(command);
75
- command.option(
76
- '--agent <agent-book-path>',
77
- 'Path to a .book file whose compiled system message is prepended to each coding prompt',
78
- );
83
+ addQuestionsOption(command);
84
+ addCoderAgentOption(command);
79
85
  command.option(
80
86
  '--context <context-or-file>',
81
87
  'Append extra instructions either inline or from a file path relative to the current project',
@@ -90,21 +96,7 @@ export function $initializeCoderServerCommand(program: Program): $side_effect {
90
96
  false,
91
97
  );
92
98
  addPromptRunnerExecutionOptions(command);
93
- command.option(
94
- '--priority <minimum-priority>',
95
- 'Alias for --min-priority; filter prompts by minimum priority level',
96
- createNonNegativeIntegerOptionParser('--priority'),
97
- );
98
- command.option(
99
- '--min-priority <minimum-priority>',
100
- 'Filter prompts by minimum priority level',
101
- createNonNegativeIntegerOptionParser('--min-priority'),
102
- );
103
- command.option(
104
- '--max-priority <maximum-priority>',
105
- 'Filter prompts by maximum priority level',
106
- createNonNegativeIntegerOptionParser('--max-priority'),
107
- );
99
+ addPromptPriorityOptions(command);
108
100
  command.option(
109
101
  '--wait-after-prompt <duration>',
110
102
  spaceTrim(`
@@ -174,22 +166,27 @@ export function $initializeCoderServerCommand(program: Program): $side_effect {
174
166
  readonly auto: boolean;
175
167
  readonly autoMigrate: boolean;
176
168
  readonly allowDestructiveAutoMigrate: boolean;
177
- } & PromptRunnerCliOptions;
169
+ } & PromptRunnerCliOptions & CoderAgentCliOptions;
178
170
 
179
171
  const port = parseCoderServerPort(rawPort);
180
172
  const testCommand = normalizeCommandOptionValue(test);
181
173
  const runnerOptions = normalizePromptRunnerCliOptions(cliOptions as PromptRunnerCliOptions, {
182
174
  isAgentRequired: !dryRun,
183
175
  });
184
- const { isHarnessUpdateCheckEnabled } = normalizeHarnessUpdateCliOptions(
185
- cliOptions as HarnessUpdateCliOptions,
186
- );
187
-
188
- await $ensureHarnessInstallations([runnerOptions.agentName], isHarnessUpdateCheckEnabled);
189
- await $ensureCoderHarnessGitignoreRules(process.cwd(), runnerOptions.agentName);
176
+ const questionsOptions = normalizeQuestionsCliOptions(cliOptions as QuestionsCliOptions);
190
177
 
191
178
  // [1] Parse the wait options and --no-auto (same logic as `coder run`)
192
179
  const waitForUser = !auto;
180
+
181
+ assertUserConfirmationIsAllowed({ ...questionsOptions, isWaitingForUser: waitForUser });
182
+
183
+ // Note: Checked before anything is installed or written, because installing a harness and coding
184
+ // itself both need the disk space which is missing
185
+ await $assertSufficientFreeDiskSpace(process.cwd());
186
+
187
+ await $ensureHarnessInstallations([runnerOptions.agentName], questionsOptions);
188
+ await $ensureCoderHarnessGitignoreRules(process.cwd(), runnerOptions.agentName, questionsOptions);
189
+
193
190
  const waitAfterPrompt = parseOptionalWaitDuration(waitAfterPromptValue, 0);
194
191
  const waitBetweenPrompts = parseOptionalWaitDuration(waitBetweenPromptsValue, 0);
195
192
  const waitAfterError = parseOptionalWaitDuration(waitAfterErrorValue, DEFAULT_WAIT_AFTER_ERROR_MS);
@@ -220,6 +217,7 @@ export function $initializeCoderServerCommand(program: Program): $side_effect {
220
217
  allowDestructiveAutoMigrate,
221
218
  autoPush: runnerOptions.autoPush,
222
219
  autoPull: runnerOptions.autoPull,
220
+ isAskingQuestionsEnabled: questionsOptions.isAskingQuestionsEnabled,
223
221
  };
224
222
 
225
223
  // Note: Import dynamically to avoid loading heavy dependencies until needed
@@ -231,8 +229,7 @@ export function $initializeCoderServerCommand(program: Program): $side_effect {
231
229
  await runCodexPromptsServer(runOptions);
232
230
  } catch (error) {
233
231
  assertsError(error);
234
- console.error(colors.bgRed(`${error.name}`));
235
- console.error(colors.red(error.stack || error.message));
232
+ printCoderRunFailure(error);
236
233
  return process.exit(1);
237
234
  }
238
235
 
@@ -1,15 +1,16 @@
1
- import colors from 'colors';
2
1
  import type {
3
2
  Command as Program /* <- Note: [🔸] Using Program because Command is misleading name */,
4
3
  } from 'commander';
5
4
  import { spaceTrim } from 'spacetrim';
6
5
  import type { $side_effect } from '../../utils/organization/$side_effect';
6
+ import { $requireCliSubcommand } from '../common/$requireCliSubcommand';
7
7
  import { $initializeCoderAddCommand } from './coder/add';
8
8
  import { $initializeCoderFindFreshEmojiTagCommand } from './coder/find-fresh-emoji-tags';
9
9
  import { $initializeCoderFindRefactorCandidatesCommand } from './coder/find-refactor-candidates';
10
10
  import { $initializeCoderFindUnwrittenCommand } from './coder/find-unwritten';
11
11
  import { $initializeCoderGenerateBoilerplatesCommand } from './coder/generate-boilerplates';
12
12
  import { $initializeCoderInitCommand } from './coder/init';
13
+ import { $initializeCoderListCommand } from './coder/list';
13
14
  import { $initializeCoderPingCommand } from './coder/ping';
14
15
  import { $initializeCoderRunCommand } from './coder/run';
15
16
  import { $initializeCoderServerCommand } from './coder/server';
@@ -23,6 +24,7 @@ import { $initializeCoderVerifyCommand } from './coder/verify';
23
24
  * - add: Add one ready-to-run prompt file to the queue
24
25
  * - generate-boilerplates: Generate prompt boilerplate files
25
26
  * - find-refactor-candidates: Find files that need refactoring
27
+ * - list: List ready prompts in priority order without running them
26
28
  * - run: Run coding prompts with AI agents
27
29
  * - ping: Test one harness and model with a tiny dummy prompt
28
30
  * - verify: Verify completed prompts
@@ -44,6 +46,7 @@ export function $initializeCoderCommand(program: Program): $side_effect {
44
46
  - generate-boilerplates: Generate prompt boilerplate files
45
47
  - find-refactor-candidates: Find files that need refactoring
46
48
  - find-unwritten: List prompt sections that still need to be authored
49
+ - list: List ready prompts in priority order without running them
47
50
  - run: Run coding prompts with AI agents
48
51
  - ping: Test the connection, response time and quota of one harness and model
49
52
  - server: Start a long-running coder server with a kanban web UI
@@ -58,6 +61,7 @@ export function $initializeCoderCommand(program: Program): $side_effect {
58
61
  $initializeCoderGenerateBoilerplatesCommand(coderCommand);
59
62
  $initializeCoderFindRefactorCandidatesCommand(coderCommand);
60
63
  $initializeCoderFindUnwrittenCommand(coderCommand);
64
+ $initializeCoderListCommand(coderCommand);
61
65
  $initializeCoderRunCommand(coderCommand);
62
66
  $initializeCoderPingCommand(coderCommand);
63
67
  $initializeCoderServerCommand(coderCommand);
@@ -65,11 +69,7 @@ export function $initializeCoderCommand(program: Program): $side_effect {
65
69
  $initializeCoderFindFreshEmojiTagCommand(coderCommand);
66
70
 
67
71
  // If no subcommand is provided, show help
68
- coderCommand.action(() => {
69
- console.info(colors.yellow('Please specify a subcommand.'));
70
- console.info('');
71
- coderCommand.help();
72
- });
72
+ $requireCliSubcommand(coderCommand);
73
73
  }
74
74
 
75
75
  // Note: [🟡] Code for CLI command [coder](src/cli/cli-commands/coder.ts) should never be published outside of `@promptbook/cli`
@@ -1,15 +1,25 @@
1
1
  import colors from 'colors';
2
2
  import { createInterface } from 'readline';
3
+ import type { NormalizedQuestionsCliOptions } from './questionsCliOptions';
3
4
 
4
5
  /**
5
6
  * Asks the user in the terminal to confirm one optional change.
6
7
  *
7
8
  * Note: `$` is used to indicate that this function is not a pure function - it reads the answer from stdin.
8
9
  *
9
- * @returns `true` when the user confirms, `false` when the user declines or the terminal is not interactive.
10
+ * @returns `true` when the user confirms, `false` when the user declines, the terminal is not interactive
11
+ * or the questions are disabled by `--no-questions`.
10
12
  * @private internal utility of `promptbookCli`
11
13
  */
12
- export async function $askForConfirmation(question: string): Promise<boolean> {
14
+ export async function $askForConfirmation(
15
+ question: string,
16
+ { isAskingQuestionsEnabled }: NormalizedQuestionsCliOptions,
17
+ ): Promise<boolean> {
18
+ if (!isAskingQuestionsEnabled) {
19
+ // Note: `--no-questions` forbids asking, so the optional change is declined without blocking the run.
20
+ return false;
21
+ }
22
+
13
23
  if (!process.stdin.isTTY) {
14
24
  // Note: In non-interactive environments like CI there is nobody who could confirm the change.
15
25
  return false;
@@ -0,0 +1,35 @@
1
+ import { spaceTrim } from 'spacetrim';
2
+ import { LimitReachedError } from '../../../../errors/LimitReachedError';
3
+ import { $readFreeDiskSpaceStatus } from './$readFreeDiskSpaceStatus';
4
+ import { formatLowFreeDiskSpaceWarning } from './formatLowFreeDiskSpaceWarning';
5
+
6
+ /**
7
+ * Refuses to start one `ptbk coder` command when the disk which hosts the project is nearly full.
8
+ *
9
+ * A run which starts without enough free disk space fails somewhere in the middle, after the coding agent has
10
+ * already rewritten a part of the project, so it is stopped before it writes anything at all.
11
+ *
12
+ * Note: `$` is used to indicate that this function is not a pure function - it reads the state of the filesystem
13
+ *
14
+ * @throws {LimitReachedError} when there is not enough free disk space left to start
15
+ * @private internal utility of `promptbookCli`
16
+ */
17
+ export async function $assertSufficientFreeDiskSpace(inspectedPath: string): Promise<void> {
18
+ const freeDiskSpaceStatus = await $readFreeDiskSpaceStatus(inspectedPath);
19
+
20
+ if (freeDiskSpaceStatus === null || freeDiskSpaceStatus.level === 'sufficient') {
21
+ return;
22
+ }
23
+
24
+ throw new LimitReachedError(
25
+ spaceTrim(
26
+ (block) => `
27
+ There is not enough free disk space to run \`ptbk coder\`.
28
+
29
+ ${block(formatLowFreeDiskSpaceWarning(freeDiskSpaceStatus))}
30
+ `,
31
+ ),
32
+ );
33
+ }
34
+
35
+ // Note: [🟡] Code for CLI free disk space handling [$assertSufficientFreeDiskSpace](src/cli/cli-commands/common/disk-space/$assertSufficientFreeDiskSpace.ts) should never be published outside of `@promptbook/cli`
@@ -0,0 +1,37 @@
1
+ import { statfs } from 'fs/promises';
2
+ import type { FreeDiskSpaceStatus } from './FreeDiskSpaceStatus';
3
+ import { resolveFreeDiskSpaceLevel } from './resolveFreeDiskSpaceLevel';
4
+
5
+ /**
6
+ * Measures the free disk space on the filesystem which hosts the given path.
7
+ *
8
+ * Note: `$` is used to indicate that this function is not a pure function - it reads the state of the filesystem
9
+ *
10
+ * @returns the measurement, or `null` when the filesystem can not be measured, for example on a platform which
11
+ * does not report filesystem statistics - a run is never stopped by a measurement which could not be taken
12
+ * @private internal utility of `promptbookCli`
13
+ */
14
+ export async function $readFreeDiskSpaceStatus(inspectedPath: string): Promise<FreeDiskSpaceStatus | null> {
15
+ try {
16
+ const fileSystemStats = await statfs(inspectedPath);
17
+ const blockSizeBytes = fileSystemStats.bsize;
18
+ const availableBytes = fileSystemStats.bavail * blockSizeBytes;
19
+ const totalBytes = fileSystemStats.blocks * blockSizeBytes;
20
+
21
+ if (!Number.isFinite(availableBytes) || availableBytes < 0) {
22
+ return null;
23
+ }
24
+
25
+ return {
26
+ inspectedPath,
27
+ availableBytes,
28
+ totalBytes,
29
+ level: resolveFreeDiskSpaceLevel(availableBytes),
30
+ };
31
+ } catch {
32
+ // Note: A path or a platform which can not report its free disk space must not stop `ptbk coder` from running
33
+ return null;
34
+ }
35
+ }
36
+
37
+ // Note: [🟡] Code for CLI free disk space handling [$readFreeDiskSpaceStatus](src/cli/cli-commands/common/disk-space/$readFreeDiskSpaceStatus.ts) should never be published outside of `@promptbook/cli`
@@ -0,0 +1,39 @@
1
+ /**
2
+ * How much free disk space is left, measured against the `ptbk coder` free disk space limits.
3
+ *
4
+ * - `sufficient` - there is enough free disk space to start a run and to keep it running
5
+ * - `low` - there is not enough free disk space to start a new run
6
+ * - `critical` - there is not enough free disk space to keep a started run going
7
+ *
8
+ * @private internal utility of `promptbookCli`
9
+ */
10
+ export type FreeDiskSpaceLevel = 'sufficient' | 'low' | 'critical';
11
+
12
+ /**
13
+ * One measurement of the free disk space on the filesystem which hosts the inspected path.
14
+ *
15
+ * @private internal utility of `promptbookCli`
16
+ */
17
+ export type FreeDiskSpaceStatus = {
18
+ /**
19
+ * Path whose filesystem was measured.
20
+ */
21
+ readonly inspectedPath: string;
22
+
23
+ /**
24
+ * Bytes which are still available to the current user on that filesystem.
25
+ */
26
+ readonly availableBytes: number;
27
+
28
+ /**
29
+ * Total size of that filesystem in bytes.
30
+ */
31
+ readonly totalBytes: number;
32
+
33
+ /**
34
+ * Severity of the measured free disk space.
35
+ */
36
+ readonly level: FreeDiskSpaceLevel;
37
+ };
38
+
39
+ // Note: [🟡] Code for CLI free disk space handling [FreeDiskSpaceStatus](src/cli/cli-commands/common/disk-space/FreeDiskSpaceStatus.ts) should never be published outside of `@promptbook/cli`
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Byte units used when one amount of disk space is written for a human.
3
+ */
4
+ const FREE_DISK_SPACE_BYTE_UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'] as const;
5
+
6
+ /**
7
+ * Writes one byte count as a compact human-readable amount of disk space, for example `812 MB` or `1.5 GB`.
8
+ *
9
+ * @private internal utility of `promptbookCli`
10
+ */
11
+ export function formatFreeDiskSpaceBytes(bytes: number): string {
12
+ if (!Number.isFinite(bytes) || bytes <= 0) {
13
+ return '0 B';
14
+ }
15
+
16
+ const unitIndex = Math.min(FREE_DISK_SPACE_BYTE_UNITS.length - 1, Math.floor(Math.log(bytes) / Math.log(1024)));
17
+ const value = bytes / Math.pow(1024, unitIndex);
18
+ // Note: One decimal place only matters for small values, `476 GB` is more readable than `476.3 GB`
19
+ const decimalPlaceCount = value >= 10 || unitIndex === 0 ? 0 : 1;
20
+ // Note: An empty decimal place only adds noise, `2 GB` is more readable than `2.0 GB`
21
+ const displayedValue = value.toFixed(decimalPlaceCount).replace(/\.0$/, '');
22
+
23
+ return `${displayedValue} ${FREE_DISK_SPACE_BYTE_UNITS[unitIndex]}`;
24
+ }
25
+
26
+ // Note: [🟡] Code for CLI free disk space handling [formatFreeDiskSpaceBytes](src/cli/cli-commands/common/disk-space/formatFreeDiskSpaceBytes.ts) should never be published outside of `@promptbook/cli`
@@ -0,0 +1,33 @@
1
+ import { spaceTrim } from 'spacetrim';
2
+ import type { FreeDiskSpaceStatus } from './FreeDiskSpaceStatus';
3
+ import { formatFreeDiskSpaceBytes } from './formatFreeDiskSpaceBytes';
4
+ import { CRITICALLY_LOW_FREE_DISK_SPACE_BYTES, LOW_FREE_DISK_SPACE_BYTES } from './freeDiskSpaceConstants';
5
+
6
+ /**
7
+ * Writes the shared warning which explains one low free disk space measurement and how to get out of it.
8
+ *
9
+ * The very same wording is used by the check which refuses to start a run and by the check which pauses
10
+ * a run that ran out of disk space while it was working.
11
+ *
12
+ * @private internal utility of `promptbookCli`
13
+ */
14
+ export function formatLowFreeDiskSpaceWarning(freeDiskSpaceStatus: FreeDiskSpaceStatus): string {
15
+ const { inspectedPath } = freeDiskSpaceStatus;
16
+ const availableSpace = formatFreeDiskSpaceBytes(freeDiskSpaceStatus.availableBytes);
17
+ const totalSpace = formatFreeDiskSpaceBytes(freeDiskSpaceStatus.totalBytes);
18
+ const requiredSpaceToStart = formatFreeDiskSpaceBytes(LOW_FREE_DISK_SPACE_BYTES);
19
+ const requiredSpaceToContinue = formatFreeDiskSpaceBytes(CRITICALLY_LOW_FREE_DISK_SPACE_BYTES);
20
+
21
+ return spaceTrim(`
22
+ Only **${availableSpace}** of ${totalSpace} is left on the disk which hosts \`${inspectedPath}\`.
23
+
24
+ **\`ptbk coder\` needs at least ${requiredSpaceToStart} of free disk space to start a run and at least ${requiredSpaceToContinue} to keep one running.**
25
+
26
+ Actionable hints:
27
+ - Free up disk space on the drive which hosts \`${inspectedPath}\`.
28
+ - Remove build artifacts, package caches and \`node_modules\` folders of projects you are not working on.
29
+ - Remove the temporary worktrees which earlier \`--isolate\` runs left behind.
30
+ `);
31
+ }
32
+
33
+ // Note: [🟡] Code for CLI free disk space handling [formatLowFreeDiskSpaceWarning](src/cli/cli-commands/common/disk-space/formatLowFreeDiskSpaceWarning.ts) should never be published outside of `@promptbook/cli`
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Free disk space below which `ptbk coder` refuses to start a new run.
3
+ *
4
+ * A coding round writes prompt and log artifacts, lets the harness rewrite the project, may install npm packages,
5
+ * may create a git worktree for `--isolate` and usually runs a build, so a run started with less than this
6
+ * would very likely die somewhere in the middle with a filesystem error.
7
+ *
8
+ * @private internal utility of `promptbookCli`
9
+ */
10
+ export const LOW_FREE_DISK_SPACE_BYTES = 2 * 1024 * 1024 * 1024;
11
+
12
+ /**
13
+ * Free disk space below which a started `ptbk coder` run stops at its next checkpoint and waits until space is freed.
14
+ *
15
+ * This limit is lower than `LOW_FREE_DISK_SPACE_BYTES`, because interrupting a run which is already in progress
16
+ * is more expensive than not starting one at all.
17
+ *
18
+ * @private internal utility of `promptbookCli`
19
+ */
20
+ export const CRITICALLY_LOW_FREE_DISK_SPACE_BYTES = 1 * 1024 * 1024 * 1024;
21
+
22
+ /**
23
+ * How long one free disk space measurement is reused before the filesystem is measured again during a run.
24
+ *
25
+ * Pause checkpoints are passed very often - for example on every tick of a timed wait - so without this
26
+ * interval the filesystem would be measured many times per second.
27
+ *
28
+ * @private internal utility of `promptbookCli`
29
+ */
30
+ export const FREE_DISK_SPACE_RECHECK_INTERVAL_MS = 60 * 1000;
31
+
32
+ // Note: [🟡] Code for CLI free disk space handling [freeDiskSpaceConstants](src/cli/cli-commands/common/disk-space/freeDiskSpaceConstants.ts) should never be published outside of `@promptbook/cli`
33
+ // Note: [💞] Ignore a discrepancy between file name and entity name
@@ -0,0 +1,21 @@
1
+ import type { FreeDiskSpaceLevel } from './FreeDiskSpaceStatus';
2
+ import { CRITICALLY_LOW_FREE_DISK_SPACE_BYTES, LOW_FREE_DISK_SPACE_BYTES } from './freeDiskSpaceConstants';
3
+
4
+ /**
5
+ * Classifies one measured amount of free disk space against the `ptbk coder` free disk space limits.
6
+ *
7
+ * @private internal utility of `promptbookCli`
8
+ */
9
+ export function resolveFreeDiskSpaceLevel(availableBytes: number): FreeDiskSpaceLevel {
10
+ if (availableBytes < CRITICALLY_LOW_FREE_DISK_SPACE_BYTES) {
11
+ return 'critical';
12
+ }
13
+
14
+ if (availableBytes < LOW_FREE_DISK_SPACE_BYTES) {
15
+ return 'low';
16
+ }
17
+
18
+ return 'sufficient';
19
+ }
20
+
21
+ // Note: [🟡] Code for CLI free disk space handling [resolveFreeDiskSpaceLevel](src/cli/cli-commands/common/disk-space/resolveFreeDiskSpaceLevel.ts) should never be published outside of `@promptbook/cli`
@@ -1,5 +1,6 @@
1
1
  import colors from 'colors';
2
2
  import { $askForNpmPackageInstallationApproval } from '../npm/$askForNpmPackageInstallationApproval';
3
+ import type { NormalizedQuestionsCliOptions } from '../questionsCliOptions';
3
4
  import { $runHarnessInstallationCommand } from './$runHarnessInstallationCommand';
4
5
  import { buildHarnessInstallCommand } from './buildHarnessInstallCommand';
5
6
  import type { HarnessDefinition } from './HarnessDefinition';
@@ -15,7 +16,10 @@ import { resolveHarnessUpdatePlan } from './resolveHarnessUpdatePlan';
15
16
  *
16
17
  * @private internal utility of `promptbookCli`
17
18
  */
18
- export async function $applyHarnessInstallationStatus(status: HarnessInstallationStatus): Promise<void> {
19
+ export async function $applyHarnessInstallationStatus(
20
+ status: HarnessInstallationStatus,
21
+ questionsOptions: NormalizedQuestionsCliOptions,
22
+ ): Promise<void> {
19
23
  const { definition, installationState, installedVersion } = status;
20
24
 
21
25
  if (installationState === 'up-to-date') {
@@ -42,21 +46,25 @@ export async function $applyHarnessInstallationStatus(status: HarnessInstallatio
42
46
  console.warn(colors.yellow(formatHarnessInstallationWarning(status)));
43
47
 
44
48
  if (installationState === 'not-installed') {
45
- await $applyMissingHarnessInstallation(definition);
49
+ await $applyMissingHarnessInstallation(definition, questionsOptions);
46
50
  return;
47
51
  }
48
52
 
49
- await $applyOutdatedHarnessInstallation(status);
53
+ await $applyOutdatedHarnessInstallation(status, questionsOptions);
50
54
  }
51
55
 
52
56
  /**
53
57
  * Offers to install a missing harness globally through npm.
54
58
  */
55
- async function $applyMissingHarnessInstallation(definition: HarnessDefinition): Promise<void> {
59
+ async function $applyMissingHarnessInstallation(
60
+ definition: HarnessDefinition,
61
+ questionsOptions: NormalizedQuestionsCliOptions,
62
+ ): Promise<void> {
56
63
  const installCommand = buildHarnessInstallCommand(definition);
57
64
 
58
65
  const isInstallationApproved = await $askForNpmPackageInstallationApproval(
59
66
  `Install ${definition.label} globally now?`,
67
+ questionsOptions,
60
68
  );
61
69
 
62
70
  if (!isInstallationApproved) {
@@ -75,7 +83,10 @@ async function $applyMissingHarnessInstallation(definition: HarnessDefinition):
75
83
  /**
76
84
  * Offers to update an outdated harness exactly where it is installed.
77
85
  */
78
- async function $applyOutdatedHarnessInstallation(status: HarnessInstallationStatus): Promise<void> {
86
+ async function $applyOutdatedHarnessInstallation(
87
+ status: HarnessInstallationStatus,
88
+ questionsOptions: NormalizedQuestionsCliOptions,
89
+ ): Promise<void> {
79
90
  const { definition, latestVersion, installationOrigin } = status;
80
91
  const updatePlan = resolveHarnessUpdatePlan(definition, installationOrigin.installationMethod);
81
92
 
@@ -86,6 +97,7 @@ async function $applyOutdatedHarnessInstallation(status: HarnessInstallationStat
86
97
 
87
98
  const isUpdateApproved = await $askForNpmPackageInstallationApproval(
88
99
  `Update ${definition.label} to ${latestVersion} with \`${updatePlan.command}\` now?`,
100
+ questionsOptions,
89
101
  );
90
102
 
91
103
  if (!isUpdateApproved) {
@@ -1,11 +1,12 @@
1
1
  import type { PromptRunnerHarnessName } from '../promptRunnerCliOptions';
2
+ import type { NormalizedQuestionsCliOptions } from '../questionsCliOptions';
2
3
  import { $applyHarnessInstallationStatus } from './$applyHarnessInstallationStatus';
3
4
  import { $checkHarnessInstallation } from './$checkHarnessInstallation';
4
5
  import type { HarnessDefinition } from './HarnessDefinition';
5
6
  import { getHarnessDefinition } from './HarnessDefinition';
6
7
 
7
8
  /**
8
- * Checks that every given CLI coding harness is installed globally and, when enabled, up to date.
9
+ * Checks that every given CLI coding harness is installed globally and, when the questions are enabled, up to date.
9
10
  * Offers to install missing harnesses and update outdated ones.
10
11
  *
11
12
  * Harness names which are `undefined`, for example when no `--harness` is selected in a dry run,
@@ -17,7 +18,7 @@ import { getHarnessDefinition } from './HarnessDefinition';
17
18
  */
18
19
  export async function $ensureHarnessInstallations(
19
20
  harnessNames: ReadonlyArray<PromptRunnerHarnessName | undefined>,
20
- isHarnessUpdateCheckEnabled = true,
21
+ questionsOptions: NormalizedQuestionsCliOptions,
21
22
  ): Promise<void> {
22
23
  const definitions = resolveCheckedHarnessDefinitions(harnessNames);
23
24
 
@@ -25,13 +26,17 @@ export async function $ensureHarnessInstallations(
25
26
  return;
26
27
  }
27
28
 
29
+ // Note: An outdated harness can be updated only after the user confirms it, so `--no-questions`
30
+ // skips the slower npm registry lookup entirely and only reports what is installed.
31
+ const isHarnessUpdateCheckEnabled = questionsOptions.isAskingQuestionsEnabled;
32
+
28
33
  // Note: Detection of all harnesses runs in parallel, the questions have to be asked one by one
29
34
  const statuses = await Promise.all(
30
35
  definitions.map((definition) => $checkHarnessInstallation(definition, isHarnessUpdateCheckEnabled)),
31
36
  );
32
37
 
33
38
  for (const status of statuses) {
34
- await $applyHarnessInstallationStatus(status);
39
+ await $applyHarnessInstallationStatus(status, questionsOptions);
35
40
  }
36
41
  }
37
42