@promptbook/cli 0.114.0-11 → 0.114.0-13

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 (145) hide show
  1. package/apps/agents-server/src/app/admin/messages/MessagesClient.tsx +8 -1
  2. package/apps/agents-server/src/app/admin/messages/send-email/SendEmailClient.tsx +193 -63
  3. package/apps/agents-server/src/app/admin/messages/send-email/actions.ts +25 -28
  4. package/apps/agents-server/src/app/admin/messages/send-email/emailTesting.ts +153 -0
  5. package/apps/agents-server/src/app/admin/messages/send-email/emailTestingAccess.ts +30 -0
  6. package/apps/agents-server/src/app/admin/messages/send-email/page.tsx +18 -5
  7. package/apps/agents-server/src/app/agents/[agentName]/AgentChatWrapper.tsx +7 -4
  8. package/apps/agents-server/src/app/agents/[agentName]/chat/AgentGoalChatPlannedMessages.tsx +23 -8
  9. package/apps/agents-server/src/app/agents/[agentName]/chat/CanonicalAgentChatSurface.tsx +14 -3
  10. package/apps/agents-server/src/app/agents/[agentName]/chat/page.tsx +2 -20
  11. package/apps/agents-server/src/app/agents/[agentName]/page.tsx +2 -1
  12. package/apps/agents-server/src/app/agents/[agentName]/projectReferenceActions.ts +61 -0
  13. package/apps/agents-server/src/app/api/internal/agent-goal-chat-planned-messages/route.ts +34 -7
  14. package/apps/agents-server/src/components/AgentProjects/resolveLatestCompletedAgentMessageKey.ts +32 -0
  15. package/apps/agents-server/src/components/AgentProjects/useAgentProjectMarkdownReferences.ts +124 -2
  16. package/apps/agents-server/src/languages/ServerTranslationKeys.ts +3 -0
  17. package/apps/agents-server/src/languages/translations/czech.yaml +3 -0
  18. package/apps/agents-server/src/languages/translations/english.yaml +3 -0
  19. package/apps/agents-server/src/message-providers/email/stalwart/StalwartMessageProvider.ts +2 -1
  20. package/apps/agents-server/src/tools/agentGoalChatTimeoutToolFunctions.ts +24 -2
  21. package/apps/agents-server/src/tools/agentGoalChatTimeoutTools.ts +5 -4
  22. package/apps/agents-server/src/utils/agentGoalChat/agentGoalChatPlannedMessageActions.ts +38 -9
  23. package/apps/agents-server/src/utils/agentGoalChat/createAgentGoalChatNoteContent.ts +15 -6
  24. package/apps/agents-server/src/utils/agentProjects/listAgentProjectNames.ts +35 -0
  25. package/apps/agents-server/src/utils/agentProjects/listAgentProjects.ts +6 -23
  26. package/apps/agents-server/src/utils/agentProjects/resolveAgentChatProjectReferences.ts +25 -0
  27. package/apps/agents-server/src/utils/chatMessageChips/createAnsweredMessageChipToolCalls.ts +37 -0
  28. package/apps/agents-server/src/utils/chatMessageChips/createPlannedMessageChipToolCalls.ts +39 -0
  29. package/apps/agents-server/src/utils/chatMessageChips/createTouchedProjectChipToolCalls.ts +75 -0
  30. package/apps/agents-server/src/utils/email/agentEmailAddress.ts +14 -0
  31. package/apps/agents-server/src/utils/email/sendEmailThroughStalwart.ts +2 -1
  32. package/apps/agents-server/src/utils/localChatRunner/applyLocalAgentPlannedMessageCommands.ts +212 -0
  33. package/apps/agents-server/src/utils/localChatRunner/prepareLocalAgentPlannedMessagesSidecar.ts +66 -0
  34. package/apps/agents-server/src/utils/localChatRunner/processLocalUserChatJob.ts +110 -22
  35. package/apps/agents-server/src/utils/userChat/persistUserChatJobTerminalState.ts +5 -0
  36. package/apps/agents-server/src/utils/userChat/userChatJobRunReport.ts +30 -0
  37. package/apps/agents-server/src/utils/userChatTimeout/createTimeoutWakeUpMessage.ts +9 -1
  38. package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore/repeatFiredUserChatTimeout.ts +74 -0
  39. package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore.ts +1 -0
  40. package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutWorker.ts +63 -54
  41. package/esm/index.es.js +1042 -194
  42. package/esm/index.es.js.map +1 -1
  43. package/esm/scripts/run-agent-messages/messages/buildAgentGoalChatPromptSection.d.ts +22 -4
  44. package/esm/scripts/run-agent-messages/messages/buildAgentMessagePrompt.d.ts +3 -3
  45. package/esm/scripts/run-agent-messages/messages/loadAgentPlannedMessagesSidecar.d.ts +10 -0
  46. package/esm/scripts/run-agent-messages/messages/resolveTouchedAgentProjects.d.ts +15 -0
  47. package/esm/scripts/run-codex-prompts/common/runGoScript/$spawnLoggedBashScript.d.ts +25 -0
  48. package/esm/scripts/run-codex-prompts/common/runGoScript/$terminateLoggedBashProcessTree.d.ts +11 -0
  49. package/esm/scripts/run-codex-prompts/common/runGoScript/scriptExecutionLog.d.ts +4 -0
  50. package/esm/src/book-2.0/agent-source/AgentSourceParseResult.d.ts +5 -0
  51. package/esm/src/book-2.0/agent-source/ParsedUnknownCommitment.d.ts +26 -0
  52. package/esm/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments.unknown.test.d.ts +1 -0
  53. package/esm/src/book-2.0/agent-source/getBookCommitmentLineType.d.ts +19 -0
  54. package/esm/src/book-2.0/agent-source/parseAgentSourceWithCommitments.unknown.test.d.ts +1 -0
  55. package/esm/src/book-3.0/AgentMessageRunReport.d.ts +28 -0
  56. package/esm/src/book-3.0/AgentPlannedMessagesSidecar.d.ts +94 -0
  57. package/esm/src/book-3.0/AgentPlannedMessagesSidecar.test.d.ts +1 -0
  58. package/esm/src/book-3.0/createAgentMessageSidecarBaseName.d.ts +13 -0
  59. package/esm/src/book-components/BookEditor/createUnknownCommitmentDiagnostics.d.ts +28 -0
  60. package/esm/src/book-components/BookEditor/createUnknownCommitmentDiagnostics.test.d.ts +1 -0
  61. package/esm/src/book-components/Chat/utils/agentProjectToolCall.d.ts +46 -0
  62. package/esm/src/book-components/Chat/utils/timeoutToolCallPresentation.d.ts +24 -0
  63. package/esm/src/cli/cli-commands/common/harness/$checkHarnessInstallation.d.ts +3 -3
  64. package/esm/src/cli/cli-commands/common/harness/$checkHarnessInstallation.test.d.ts +1 -0
  65. package/esm/src/cli/cli-commands/common/harness/$ensureHarnessInstallations.d.ts +3 -3
  66. package/esm/src/cli/cli-commands/common/harness/HarnessInstallationStatus.d.ts +3 -2
  67. package/esm/src/cli/cli-commands/common/harnessUpdateCliOptions.d.ts +29 -0
  68. package/esm/src/cli/cli-commands/common/harnessUpdateCliOptions.test.d.ts +1 -0
  69. package/esm/src/executables/platforms/locateAppOnWindows.d.ts +1 -1
  70. package/esm/src/executables/platforms/locateAppOnWindows.test.d.ts +1 -0
  71. package/esm/src/utils/agent-message-runtime/parseAgentMessageRuntimeLogEvents.d.ts +59 -0
  72. package/esm/src/utils/agent-message-runtime/resolveAgentMessageTouchedProjectNames.d.ts +19 -0
  73. package/esm/src/utils/agent-message-runtime/resolveAgentMessageTouchedProjectNames.test.d.ts +1 -0
  74. package/esm/src/version.d.ts +1 -1
  75. package/package.json +1 -1
  76. package/src/book-2.0/agent-source/AgentSourceParseResult.ts +6 -0
  77. package/src/book-2.0/agent-source/ParsedUnknownCommitment.ts +29 -0
  78. package/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/augmentAgentModelRequirementsFromSource.ts +38 -1
  79. package/src/book-2.0/agent-source/getBookCommitmentLineType.ts +36 -0
  80. package/src/book-2.0/agent-source/parseAgentSourceWithCommitments.ts +128 -61
  81. package/src/book-3.0/AgentMessageRunReport.ts +76 -0
  82. package/src/book-3.0/AgentPlannedMessagesSidecar.ts +229 -0
  83. package/src/book-3.0/AgentTeamConversationWorkspace.ts +3 -5
  84. package/src/book-3.0/createAgentMessageSidecarBaseName.ts +20 -0
  85. package/src/book-components/BookEditor/BookEditorMonaco.tsx +6 -1
  86. package/src/book-components/BookEditor/BookEditorMonacoTokenization.ts +3 -1
  87. package/src/book-components/BookEditor/createUnknownCommitmentDiagnostics.ts +50 -0
  88. package/src/book-components/Chat/Chat/Chat.module.css +6 -1
  89. package/src/book-components/Chat/Chat/renderToolCallDetails.tsx +1 -12
  90. package/src/book-components/Chat/utils/agentProjectToolCall.ts +74 -0
  91. package/src/book-components/Chat/utils/getToolCallChipletInfo.ts +28 -0
  92. package/src/book-components/Chat/utils/timeoutToolCallPresentation.ts +23 -3
  93. package/src/cli/cli-commands/coder/boilerplateTemplates.ts +3 -15
  94. package/src/cli/cli-commands/coder/init.ts +11 -2
  95. package/src/cli/cli-commands/coder/ping.ts +11 -1
  96. package/src/cli/cli-commands/coder/run.ts +11 -2
  97. package/src/cli/cli-commands/coder/server.ts +11 -2
  98. package/src/cli/cli-commands/common/harness/$applyHarnessInstallationStatus.ts +5 -0
  99. package/src/cli/cli-commands/common/harness/$checkHarnessInstallation.ts +17 -5
  100. package/src/cli/cli-commands/common/harness/$ensureHarnessInstallations.ts +6 -3
  101. package/src/cli/cli-commands/common/harness/HarnessInstallationStatus.ts +3 -2
  102. package/src/cli/cli-commands/common/harnessUpdateCliOptions.ts +49 -0
  103. package/src/executables/platforms/locateAppOnWindows.ts +12 -9
  104. package/src/other/templates/getTemplatesPipelineCollection.ts +740 -860
  105. package/src/utils/agent-message-runtime/parseAgentMessageRuntimeLogEvents.ts +105 -0
  106. package/src/utils/agent-message-runtime/resolveAgentMessageRuntimeActivity.ts +6 -54
  107. package/src/utils/agent-message-runtime/resolveAgentMessageTouchedProjectNames.ts +147 -0
  108. package/src/version.ts +2 -2
  109. package/src/versions.txt +2 -1
  110. package/umd/index.umd.js +1041 -193
  111. package/umd/index.umd.js.map +1 -1
  112. package/umd/scripts/run-agent-messages/messages/buildAgentGoalChatPromptSection.d.ts +22 -4
  113. package/umd/scripts/run-agent-messages/messages/buildAgentMessagePrompt.d.ts +3 -3
  114. package/umd/scripts/run-agent-messages/messages/loadAgentPlannedMessagesSidecar.d.ts +10 -0
  115. package/umd/scripts/run-agent-messages/messages/resolveTouchedAgentProjects.d.ts +15 -0
  116. package/umd/scripts/run-codex-prompts/common/runGoScript/$spawnLoggedBashScript.d.ts +25 -0
  117. package/umd/scripts/run-codex-prompts/common/runGoScript/$terminateLoggedBashProcessTree.d.ts +11 -0
  118. package/umd/scripts/run-codex-prompts/common/runGoScript/scriptExecutionLog.d.ts +4 -0
  119. package/umd/src/book-2.0/agent-source/AgentSourceParseResult.d.ts +5 -0
  120. package/umd/src/book-2.0/agent-source/ParsedUnknownCommitment.d.ts +26 -0
  121. package/umd/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments.unknown.test.d.ts +1 -0
  122. package/umd/src/book-2.0/agent-source/getBookCommitmentLineType.d.ts +19 -0
  123. package/umd/src/book-2.0/agent-source/parseAgentSourceWithCommitments.unknown.test.d.ts +1 -0
  124. package/umd/src/book-3.0/AgentMessageRunReport.d.ts +28 -0
  125. package/umd/src/book-3.0/AgentPlannedMessagesSidecar.d.ts +94 -0
  126. package/umd/src/book-3.0/AgentPlannedMessagesSidecar.test.d.ts +1 -0
  127. package/umd/src/book-3.0/createAgentMessageSidecarBaseName.d.ts +13 -0
  128. package/umd/src/book-components/BookEditor/createUnknownCommitmentDiagnostics.d.ts +28 -0
  129. package/umd/src/book-components/BookEditor/createUnknownCommitmentDiagnostics.test.d.ts +1 -0
  130. package/umd/src/book-components/Chat/utils/agentProjectToolCall.d.ts +46 -0
  131. package/umd/src/book-components/Chat/utils/timeoutToolCallPresentation.d.ts +24 -0
  132. package/umd/src/cli/cli-commands/common/harness/$checkHarnessInstallation.d.ts +3 -3
  133. package/umd/src/cli/cli-commands/common/harness/$checkHarnessInstallation.test.d.ts +1 -0
  134. package/umd/src/cli/cli-commands/common/harness/$ensureHarnessInstallations.d.ts +3 -3
  135. package/umd/src/cli/cli-commands/common/harness/HarnessInstallationStatus.d.ts +3 -2
  136. package/umd/src/cli/cli-commands/common/harnessUpdateCliOptions.d.ts +29 -0
  137. package/umd/src/cli/cli-commands/common/harnessUpdateCliOptions.test.d.ts +1 -0
  138. package/umd/src/executables/platforms/locateAppOnWindows.d.ts +1 -1
  139. package/umd/src/executables/platforms/locateAppOnWindows.test.d.ts +1 -0
  140. package/umd/src/utils/agent-message-runtime/parseAgentMessageRuntimeLogEvents.d.ts +59 -0
  141. package/umd/src/utils/agent-message-runtime/resolveAgentMessageTouchedProjectNames.d.ts +19 -0
  142. package/umd/src/utils/agent-message-runtime/resolveAgentMessageTouchedProjectNames.test.d.ts +1 -0
  143. package/umd/src/version.d.ts +1 -1
  144. package/esm/apps/agents-server/src/utils/agentGoalChat/agentGoalChatConstants.d.ts +0 -12
  145. package/umd/apps/agents-server/src/utils/agentGoalChat/agentGoalChatConstants.d.ts +0 -12
@@ -5,6 +5,11 @@ import { spaceTrim } from 'spacetrim';
5
5
  import type { $side_effect } from '../../../utils/organization/$side_effect';
6
6
  import { handleActionErrors } from '../common/handleActionErrors';
7
7
  import { $ensureHarnessInstallations } from '../common/harness/$ensureHarnessInstallations';
8
+ import {
9
+ addHarnessUpdateOption,
10
+ normalizeHarnessUpdateCliOptions,
11
+ type HarnessUpdateCliOptions,
12
+ } from '../common/harnessUpdateCliOptions';
8
13
  import type { PromptRunnerSelectionCliOptions } from '../common/promptRunnerCliOptions';
9
14
  import {
10
15
  addPromptRunnerRuntimeOptions,
@@ -33,11 +38,13 @@ export function $initializeCoderPingCommand(program: Program): $side_effect {
33
38
  - Reports the answer of the harness, the response time and the reported usage
34
39
  - Starts the hourly/weekly quota window before you need it, so it is already refreshing when you do
35
40
  - Leaves the project exactly as it was — nothing is read, written, changed or committed
41
+ - Checks that the selected harness is installed globally and up to date unless --no-harness-update is used
36
42
  - Use --no-ui to stream the raw harness output instead of only the compact result
37
43
  `),
38
44
  );
39
45
 
40
46
  addPromptRunnerSelectionOptions(command);
47
+ addHarnessUpdateOption(command);
41
48
  addPromptRunnerRuntimeOptions(command);
42
49
 
43
50
  command.action(
@@ -46,8 +53,11 @@ export function $initializeCoderPingCommand(program: Program): $side_effect {
46
53
  cliOptions as PromptRunnerSelectionCliOptions,
47
54
  { isAgentRequired: true },
48
55
  );
56
+ const { isHarnessUpdateCheckEnabled } = normalizeHarnessUpdateCliOptions(
57
+ cliOptions as HarnessUpdateCliOptions,
58
+ );
49
59
 
50
- await $ensureHarnessInstallations([runnerOptions.agentName]);
60
+ await $ensureHarnessInstallations([runnerOptions.agentName], isHarnessUpdateCheckEnabled);
51
61
 
52
62
  // Note: Import the ping dynamically to avoid loading heavy dependencies until needed
53
63
  const { pingCoderHarness } = await import('../../../../scripts/run-codex-prompts/ping/pingCoderHarness');
@@ -10,6 +10,11 @@ import { createNonNegativeIntegerOptionParser } from '../common/createNonNegativ
10
10
  import { createPositiveIntegerOptionParser } from '../common/createPositiveIntegerOptionParser';
11
11
  import { handleActionErrors } from '../common/handleActionErrors';
12
12
  import { $ensureHarnessInstallations } from '../common/harness/$ensureHarnessInstallations';
13
+ import {
14
+ addHarnessUpdateOption,
15
+ normalizeHarnessUpdateCliOptions,
16
+ type HarnessUpdateCliOptions,
17
+ } from '../common/harnessUpdateCliOptions';
13
18
  import { $ensurePromptbookCliInstallations } from '../common/promptbook-cli/$ensurePromptbookCliInstallations';
14
19
  import type { PromptRunnerCliOptions } from '../common/promptRunnerCliOptions';
15
20
  import {
@@ -48,7 +53,7 @@ export function $initializeCoderRunCommand(program: Program): $side_effect {
48
53
  - Optional --isolate runs every prompt in its own temporary git worktree and merges it back when verified
49
54
  - Optional --preserve-logs keeps temp prompt/log artifacts after successful rounds
50
55
  - Optional --no-ui keeps plain streaming console output for logging and debugging
51
- - Checks that the selected harness is installed globally and up to date before the first prompt
56
+ - Checks that the selected harness is installed globally and up to date before the first prompt unless --no-harness-update is used
52
57
  - In interactive mode, checks local and global Promptbook CLI installations and offers to update them
53
58
  - Supports GPG signing of commits
54
59
  - Optional pre-coding test run that can stop or repair pre-existing failures
@@ -60,6 +65,7 @@ export function $initializeCoderRunCommand(program: Program): $side_effect {
60
65
 
61
66
  command.option('--dry-run', 'Print unwritten prompts without executing', false);
62
67
  addPromptRunnerSelectionOptions(command);
68
+ addHarnessUpdateOption(command);
63
69
  command.option(
64
70
  '--agent <agent-book-path>',
65
71
  'Path to a .book file whose compiled system message is prepended to each coding prompt',
@@ -198,6 +204,9 @@ export function $initializeCoderRunCommand(program: Program): $side_effect {
198
204
  const runnerOptions = normalizePromptRunnerCliOptions(cliOptions as PromptRunnerCliOptions, {
199
205
  isAgentRequired: !dryRun,
200
206
  });
207
+ const { isHarnessUpdateCheckEnabled } = normalizeHarnessUpdateCliOptions(
208
+ cliOptions as HarnessUpdateCliOptions,
209
+ );
201
210
 
202
211
  // [1] Parse the wait options and --no-auto:
203
212
  // default: run automatically through the queue (no waiting between prompts)
@@ -211,7 +220,7 @@ export function $initializeCoderRunCommand(program: Program): $side_effect {
211
220
  return process.exit(0);
212
221
  }
213
222
 
214
- await $ensureHarnessInstallations([runnerOptions.agentName]);
223
+ await $ensureHarnessInstallations([runnerOptions.agentName], isHarnessUpdateCheckEnabled);
215
224
 
216
225
  const waitAfterPrompt = parseOptionalWaitDuration(waitAfterPromptValue, 0);
217
226
  const waitBetweenPrompts = parseOptionalWaitDuration(waitBetweenPromptsValue, 0);
@@ -12,6 +12,11 @@ import type { $side_effect } from '../../../utils/organization/$side_effect';
12
12
  import { createNonNegativeIntegerOptionParser } from '../common/createNonNegativeIntegerOptionParser';
13
13
  import { handleActionErrors } from '../common/handleActionErrors';
14
14
  import { $ensureHarnessInstallations } from '../common/harness/$ensureHarnessInstallations';
15
+ import {
16
+ addHarnessUpdateOption,
17
+ normalizeHarnessUpdateCliOptions,
18
+ type HarnessUpdateCliOptions,
19
+ } from '../common/harnessUpdateCliOptions';
15
20
  import type { PromptRunnerCliOptions } from '../common/promptRunnerCliOptions';
16
21
  import {
17
22
  addPromptRunnerExecutionOptions,
@@ -48,7 +53,7 @@ export function $initializeCoderServerCommand(program: Program): $side_effect {
48
53
 
49
54
  Features:
50
55
  - Runs the same prompt processing as \`ptbk coder run\`
51
- - Checks that the selected harness is installed globally and up to date on startup
56
+ - Checks that the selected harness is installed globally and up to date on startup unless --no-harness-update is used
52
57
  - Does not exit when all prompts are done; polls for new prompt files instead
53
58
  - Serves a kanban board at http://localhost:<port> for visual progress tracking
54
59
  - Allows editing prompt files directly from the browser (Trello-style)
@@ -64,6 +69,7 @@ export function $initializeCoderServerCommand(program: Program): $side_effect {
64
69
  );
65
70
  command.option('--dry-run', 'Print unwritten prompts without executing', false);
66
71
  addPromptRunnerSelectionOptions(command);
72
+ addHarnessUpdateOption(command);
67
73
  command.option(
68
74
  '--agent <agent-book-path>',
69
75
  'Path to a .book file whose compiled system message is prepended to each coding prompt',
@@ -173,8 +179,11 @@ export function $initializeCoderServerCommand(program: Program): $side_effect {
173
179
  const runnerOptions = normalizePromptRunnerCliOptions(cliOptions as PromptRunnerCliOptions, {
174
180
  isAgentRequired: !dryRun,
175
181
  });
182
+ const { isHarnessUpdateCheckEnabled } = normalizeHarnessUpdateCliOptions(
183
+ cliOptions as HarnessUpdateCliOptions,
184
+ );
176
185
 
177
- await $ensureHarnessInstallations([runnerOptions.agentName]);
186
+ await $ensureHarnessInstallations([runnerOptions.agentName], isHarnessUpdateCheckEnabled);
178
187
 
179
188
  // [1] Parse the wait options and --no-auto (same logic as `coder run`)
180
189
  const waitForUser = !auto;
@@ -20,6 +20,11 @@ export async function $applyHarnessInstallationStatus(status: HarnessInstallatio
20
20
  return;
21
21
  }
22
22
 
23
+ if (installationState === 'installed') {
24
+ console.info(colors.gray(`✔ ${definition.label} ${installedVersion} is installed. Skipped checking for updates.`));
25
+ return;
26
+ }
27
+
23
28
  if (installationState === 'unknown') {
24
29
  console.info(
25
30
  colors.gray(
@@ -5,21 +5,28 @@ import type { HarnessDefinition } from './HarnessDefinition';
5
5
  import type { HarnessInstallationState, HarnessInstallationStatus } from './HarnessInstallationStatus';
6
6
 
7
7
  /**
8
- * Detects whether one CLI coding harness is installed globally and whether it is up to date.
8
+ * Detects whether one CLI coding harness is installed globally and, when enabled, whether it is up to date.
9
9
  *
10
- * Note: `$` is used to indicate that this function is not a pure function - it runs the harness command and queries npm
10
+ * Note: `$` is used to indicate that this function is not a pure function - it runs the harness command and may query npm
11
11
  *
12
12
  * @private internal utility of `promptbookCli`
13
13
  */
14
- export async function $checkHarnessInstallation(definition: HarnessDefinition): Promise<HarnessInstallationStatus> {
14
+ export async function $checkHarnessInstallation(
15
+ definition: HarnessDefinition,
16
+ isHarnessUpdateCheckEnabled = true,
17
+ ): Promise<HarnessInstallationStatus> {
15
18
  const [installedVersion, latestVersion] = await Promise.all([
16
19
  $resolveInstalledHarnessVersion(definition),
17
- $resolveLatestNpmPackageVersion(definition.npmPackageName),
20
+ isHarnessUpdateCheckEnabled ? $resolveLatestNpmPackageVersion(definition.npmPackageName) : Promise.resolve(null),
18
21
  ]);
19
22
 
20
23
  return {
21
24
  definition,
22
- installationState: resolveHarnessInstallationState(installedVersion, latestVersion),
25
+ installationState: resolveHarnessInstallationState(
26
+ installedVersion,
27
+ latestVersion,
28
+ isHarnessUpdateCheckEnabled,
29
+ ),
23
30
  installedVersion,
24
31
  latestVersion,
25
32
  };
@@ -31,11 +38,16 @@ export async function $checkHarnessInstallation(definition: HarnessDefinition):
31
38
  function resolveHarnessInstallationState(
32
39
  installedVersion: string | null,
33
40
  latestVersion: string | null,
41
+ isHarnessUpdateCheckEnabled: boolean,
34
42
  ): HarnessInstallationState {
35
43
  if (installedVersion === null) {
36
44
  return 'not-installed';
37
45
  }
38
46
 
47
+ if (!isHarnessUpdateCheckEnabled) {
48
+ return 'installed';
49
+ }
50
+
39
51
  if (latestVersion === null) {
40
52
  return 'unknown';
41
53
  }
@@ -5,8 +5,8 @@ import type { HarnessDefinition } from './HarnessDefinition';
5
5
  import { getHarnessDefinition } from './HarnessDefinition';
6
6
 
7
7
  /**
8
- * Checks that every given CLI coding harness is installed globally and up to date and offers to
9
- * install or update the ones which are not.
8
+ * Checks that every given CLI coding harness is installed globally and, when enabled, up to date.
9
+ * Offers to install missing harnesses and update outdated ones.
10
10
  *
11
11
  * Harness names which are `undefined`, for example when no `--harness` is selected in a dry run,
12
12
  * are ignored so that every call site can pass its raw selection.
@@ -17,6 +17,7 @@ import { getHarnessDefinition } from './HarnessDefinition';
17
17
  */
18
18
  export async function $ensureHarnessInstallations(
19
19
  harnessNames: ReadonlyArray<PromptRunnerHarnessName | undefined>,
20
+ isHarnessUpdateCheckEnabled = true,
20
21
  ): Promise<void> {
21
22
  const definitions = resolveCheckedHarnessDefinitions(harnessNames);
22
23
 
@@ -25,7 +26,9 @@ export async function $ensureHarnessInstallations(
25
26
  }
26
27
 
27
28
  // Note: Detection of all harnesses runs in parallel, the questions have to be asked one by one
28
- const statuses = await Promise.all(definitions.map((definition) => $checkHarnessInstallation(definition)));
29
+ const statuses = await Promise.all(
30
+ definitions.map((definition) => $checkHarnessInstallation(definition, isHarnessUpdateCheckEnabled)),
31
+ );
29
32
 
30
33
  for (const status of statuses) {
31
34
  await $applyHarnessInstallationStatus(status);
@@ -6,11 +6,12 @@ import type { HarnessDefinition } from './HarnessDefinition';
6
6
  * - `up-to-date` the newest published version is installed
7
7
  * - `outdated` an older version is installed
8
8
  * - `not-installed` the harness command is not available globally
9
+ * - `installed` the harness is installed and automatic update checking was disabled
9
10
  * - `unknown` the harness is installed but the newest published version could not be resolved, for example when offline
10
11
  *
11
12
  * @private internal utility of `promptbookCli`
12
13
  */
13
- export type HarnessInstallationState = 'up-to-date' | 'outdated' | 'not-installed' | 'unknown';
14
+ export type HarnessInstallationState = 'up-to-date' | 'outdated' | 'not-installed' | 'installed' | 'unknown';
14
15
 
15
16
  /**
16
17
  * Installation state of one CLI coding harness on the current machine.
@@ -24,7 +25,7 @@ export type HarnessInstallationStatus = {
24
25
  readonly definition: HarnessDefinition;
25
26
 
26
27
  /**
27
- * Comparison of the installed version with the newest published one.
28
+ * Installation state, including whether the newest published version was checked.
28
29
  */
29
30
  readonly installationState: HarnessInstallationState;
30
31
 
@@ -0,0 +1,49 @@
1
+ import type {
2
+ Command as Program /* <- Note: [🔸] Using Program because Command is misleading name */,
3
+ } from 'commander';
4
+
5
+ /**
6
+ * Commander option bag for opting out of automatic coding-harness update checks.
7
+ *
8
+ * @private internal utility of `promptbookCli`
9
+ */
10
+ export type HarnessUpdateCliOptions = {
11
+ readonly harnessUpdate: boolean;
12
+ };
13
+
14
+ /**
15
+ * Normalized automatic coding-harness update-check option.
16
+ *
17
+ * @private internal utility of `promptbookCli`
18
+ */
19
+ export type NormalizedHarnessUpdateCliOptions = {
20
+ readonly isHarnessUpdateCheckEnabled: boolean;
21
+ };
22
+
23
+ /**
24
+ * Registers the shared `--no-harness-update` option on a `ptbk coder` command that uses a coding harness.
25
+ *
26
+ * @private internal utility of `promptbookCli`
27
+ */
28
+ export function addHarnessUpdateOption(command: Program): void {
29
+ command.option(
30
+ '--no-harness-update',
31
+ 'Skip checking whether globally installed coding harnesses are up to date',
32
+ );
33
+ }
34
+
35
+ /**
36
+ * Converts the Commander harness-update flag into the normalized harness-check option.
37
+ *
38
+ * @private internal utility of `promptbookCli`
39
+ */
40
+ export function normalizeHarnessUpdateCliOptions(
41
+ cliOptions: HarnessUpdateCliOptions,
42
+ ): NormalizedHarnessUpdateCliOptions {
43
+ return {
44
+ isHarnessUpdateCheckEnabled: cliOptions.harnessUpdate,
45
+ };
46
+ }
47
+
48
+ // Note: [🟡] Code for CLI harness update options [harnessUpdateCliOptions](src/cli/cli-commands/common/harnessUpdateCliOptions.ts) should never be published outside of `@promptbook/cli`
49
+ // Note: [💞] Ignore a discrepancy between file name and exported helper names
@@ -1,4 +1,4 @@
1
- import { join } from 'path';
1
+ import { delimiter, join } from 'path';
2
2
  import { assertsError } from '../../errors/assertsError';
3
3
  import { $provideFilesystemForNode } from '../../scrapers/_common/register/$provideFilesystemForNode';
4
4
  import type { string_executable_path } from '../../types/string_filename';
@@ -6,7 +6,7 @@ import { isExecutable } from '../../utils/files/isExecutable';
6
6
  import type { LocateAppOptions } from '../locateApp';
7
7
 
8
8
  /**
9
- * Attempts to locate the specified application on a Windows system by searching common installation directories.
9
+ * Attempts to locate the specified application on a Windows system by searching PATH and common installation directories.
10
10
  * Returns the path to the executable if found, or null otherwise.
11
11
  *
12
12
  * @private within the repository
@@ -16,18 +16,21 @@ export async function locateAppOnWindows({
16
16
  windowsSuffix,
17
17
  }: Pick<Required<LocateAppOptions>, 'appName' | 'windowsSuffix'>): Promise<string_executable_path | null> {
18
18
  try {
19
- const prefixes = [
19
+ const EXECUTABLE_FILENAME = windowsSuffix.replace(/^.*[\\/]/, '');
20
+ const PATH_EXECUTABLE_PATHS = (process.env.PATH || '')
21
+ .split(delimiter)
22
+ .filter(Boolean)
23
+ .map((pathPrefix) => join(pathPrefix, EXECUTABLE_FILENAME));
24
+ const INSTALLATION_EXECUTABLE_PATHS = [
20
25
  process.env.LOCALAPPDATA,
21
26
  join(process.env.LOCALAPPDATA || '', 'Programs'),
22
27
  process.env.PROGRAMFILES,
23
28
  process.env['PROGRAMFILES(X86)'],
24
- ];
29
+ ].map((pathPrefix) => pathPrefix + windowsSuffix);
25
30
 
26
- for (const prefix of prefixes) {
27
- const path = prefix + windowsSuffix;
28
-
29
- if (await isExecutable(path, $provideFilesystemForNode())) {
30
- return path;
31
+ for (const executablePath of [...PATH_EXECUTABLE_PATHS, ...INSTALLATION_EXECUTABLE_PATHS]) {
32
+ if (await isExecutable(executablePath, $provideFilesystemForNode())) {
33
+ return executablePath;
31
34
  }
32
35
  }
33
36