@promptbook/cli 0.114.0-1 → 0.114.0-3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -15
- package/apps/agents-server/next.config.ts +11 -0
- package/apps/agents-server/package.json +6 -4
- package/apps/agents-server/playwright.config.ts +28 -38
- package/apps/agents-server/scripts/build-agents-server.js +62 -0
- package/apps/agents-server/scripts/build-e2e.js +38 -0
- package/apps/agents-server/scripts/ensure-root-dependencies.js +86 -0
- package/apps/agents-server/scripts/prerender-homepage.js +1 -1
- package/apps/agents-server/scripts/run-e2e-tests.js +34 -0
- package/apps/agents-server/scripts/run-npm.js +42 -0
- package/apps/agents-server/src/app/admin/email-server/page.tsx +14 -6
- package/apps/agents-server/src/app/api/elevenlabs/tts/route.ts +3 -3
- package/apps/agents-server/src/app/api/onboarding/book/route.ts +7 -6
- package/apps/agents-server/src/app/layout.tsx +6 -0
- package/apps/agents-server/src/app/superadmin/servers/ServersRegistryTable.tsx +105 -102
- package/apps/agents-server/src/app/superadmin/servers/useServersRegistryState.ts +15 -7
- package/apps/agents-server/src/components/AgentProjectDnsInstructions/AgentProjectDnsInstructions.tsx +11 -11
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ManGoBookEditor.tsx +82 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/WizardShell.tsx +2 -2
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/BookStep.tsx +13 -16
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/ZadaniStep.tsx +4 -4
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/config/bookSections.ts +23 -16
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/lib/bookSource.ts +54 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/bookService.ts +15 -8
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/createManGoAgentSource.ts +3 -37
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/createManGoOpenEditorRequest.ts +1 -1
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/state/OnboardingProvider.tsx +2 -2
- package/apps/agents-server/src/components/UsersList/CreateUserDialog.tsx +13 -22
- package/apps/agents-server/src/components/UsersList/PasswordGeneratorDialog.tsx +216 -0
- package/apps/agents-server/src/components/UsersList/UsersList.tsx +16 -11
- package/apps/agents-server/src/components/UsersList/generateSecurePassword.ts +112 -24
- package/apps/agents-server/src/components/UsersList/userDialogClassNames.ts +11 -0
- package/apps/agents-server/src/languages/ServerTranslationKeys.ts +11 -0
- package/apps/agents-server/src/languages/translations/czech.yaml +11 -0
- package/apps/agents-server/src/languages/translations/english.yaml +11 -0
- package/apps/agents-server/src/utils/agentProjects/agentProjectHrefs.ts +11 -0
- package/apps/agents-server/src/utils/agentProjects/createAgentProjectDnsRecords.ts +53 -7
- package/apps/agents-server/src/utils/agentProjects/createAgentProjectMarkdownReferences.ts +37 -27
- package/apps/agents-server/src/utils/manGoOnboarding/manGoOnboardingAgentBooks.ts +2 -13
- package/apps/agents-server/src/utils/manGoOnboarding/manGoOnboardingAgentRuntime.ts +21 -73
- package/apps/agents-server/src/utils/stalwart/createEmailDnsInstructions.ts +9 -5
- package/apps/agents-server/src/utils/stalwart/readStalwartEmailSnapshot.ts +23 -5
- package/apps/agents-server/src/utils/stalwart/stalwartBootstrap.ts +2 -1
- package/apps/agents-server/src/utils/stalwart/stalwartMailBridge.ts +7 -0
- package/apps/agents-server/tests/e2e/e2eEnvironment.cjs +49 -0
- package/esm/index.es.js +1105 -273
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/run-codex-prompts/common/runGoScript/scriptExecutionLog.d.ts +7 -0
- package/esm/scripts/run-codex-prompts/git/coderGitSync.d.ts +43 -0
- package/esm/scripts/run-codex-prompts/git/commitChanges.d.ts +3 -0
- package/esm/scripts/run-codex-prompts/main/resolvePromptRunner.d.ts +8 -1
- package/esm/scripts/run-codex-prompts/ping/buildCoderPingPrompt.d.ts +20 -0
- package/esm/scripts/run-codex-prompts/ping/extractCoderPingAnswer.d.ts +9 -0
- package/esm/scripts/run-codex-prompts/ping/pingCoderHarness.d.ts +23 -0
- package/esm/scripts/run-codex-prompts/ping/printCoderPingResult.d.ts +5 -0
- package/esm/scripts/run-codex-prompts/prompts/findNextTodoPrompt.d.ts +2 -1
- package/esm/scripts/run-codex-prompts/prompts/isPromptCompatibleWithRunner.d.ts +27 -0
- package/esm/scripts/run-codex-prompts/prompts/listRunnablePrompts.d.ts +2 -1
- package/esm/scripts/run-codex-prompts/prompts/listUpcomingTasks.d.ts +2 -1
- package/esm/scripts/run-codex-prompts/prompts/replacePromptTodoStatusLine.d.ts +7 -0
- package/esm/scripts/run-codex-prompts/testing/TestBeforeMode.d.ts +16 -0
- package/esm/scripts/run-codex-prompts/testing/createTestBeforeRepairPrompt.d.ts +9 -0
- package/esm/scripts/run-codex-prompts/testing/limitTestOutput.d.ts +4 -0
- package/esm/scripts/run-codex-prompts/testing/runPromptTestCommand.d.ts +1 -2
- package/esm/scripts/run-codex-prompts/testing/runTestBefore.d.ts +24 -0
- package/esm/scripts/run-codex-prompts/ui/buildRunUiFrameShared.d.ts +1 -0
- package/esm/scripts/verify-prompts/verify-prompts.d.ts +5 -0
- package/esm/src/book-2.0/book-language-documentation/BookLanguageManualDictionary.d.ts +1 -15
- package/esm/src/book-2.0/book-language-documentation/getBookLanguageManualCommitmentGroups.d.ts +1 -1
- package/esm/src/book-2.0/book-language-documentation/renderCommitmentCatalogSection.d.ts +0 -4
- package/esm/src/book-components/Chat/utils/$provideServerDomWindow.d.ts +11 -0
- package/esm/src/book-components/Chat/utils/renderMarkdown.d.ts +7 -0
- package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/createAgentsServerRuntimeEnvironment.d.ts +7 -0
- package/esm/src/cli/cli-commands/coder/agentCodingFile.d.ts +2 -3
- package/esm/src/cli/cli-commands/coder/ping.d.ts +10 -0
- package/esm/src/cli/cli-commands/coder/ping.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/coder.d.ts +1 -0
- package/esm/src/cli/cli-commands/common/coderGitSyncCliOptions.d.ts +34 -0
- package/esm/src/cli/cli-commands/common/coderGitSyncCliOptions.test.d.ts +1 -0
- package/esm/src/cli/common/loadPromptsModule.d.ts +16 -0
- package/esm/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.d.ts +1 -1
- package/esm/src/llm-providers/azure-openai/AzureOpenAiExecutionTools.d.ts +1 -1
- package/esm/src/llm-providers/openai/OpenAiAgentKitExecutionTools.d.ts +1 -1
- package/esm/src/llm-providers/openai/OpenAiAgentKitExecutionToolsToolBuilder.d.ts +1 -1
- package/esm/src/llm-providers/openai/OpenAiAssistantExecutionToolsStreamRunner.d.ts +1 -1
- package/esm/src/llm-providers/openai/OpenAiAssistantExecutionToolsToolRunner.d.ts +1 -1
- package/esm/src/llm-providers/openai/OpenAiCompatibleNonChatPromptCaller.d.ts +1 -1
- package/esm/src/llm-providers/openai/OpenAiCompatibleRequestManager.d.ts +1 -1
- package/esm/src/llm-providers/openai/utils/callOpenAiCompatibleChatModel.d.ts +1 -1
- package/esm/src/llm-providers/openai/utils/loadOpenAiAgentsModule.d.ts +203 -0
- package/esm/src/llm-providers/openai/utils/uploadFilesToOpenAi.d.ts +1 -1
- package/esm/src/utils/misc/createLazyModuleLoader.d.ts +14 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/book-2.0/book-language-documentation/BookLanguageManualDictionary.ts +1 -15
- package/src/book-2.0/book-language-documentation/bookLanguageDocumentationExamples.ts +1 -2
- package/src/book-2.0/book-language-documentation/createStandaloneBookLanguageMarkdown.ts +92 -32
- package/src/book-2.0/book-language-documentation/czechBookLanguageManualDictionary.ts +16 -39
- package/src/book-2.0/book-language-documentation/englishBookLanguageManualDictionary.ts +16 -36
- package/src/book-2.0/book-language-documentation/getBookLanguageManualCommitmentGroups.ts +9 -1
- package/src/book-2.0/book-language-documentation/renderCommitmentCatalogSection.ts +4 -51
- package/src/book-2.0/book-language-documentation/renderGroupedCommitmentDocumentationMarkdown.ts +291 -4
- package/src/book-3.0/LiteAgent.ts +11 -9
- package/src/book-components/Chat/utils/$provideServerDomWindow.ts +77 -0
- package/src/book-components/Chat/utils/renderMarkdown.ts +135 -32
- package/src/cli/cli-commands/agents-server/buildAgentsServer/createAgentsServerRuntimeEnvironment.ts +14 -0
- package/src/cli/cli-commands/agents-server/buildAgentsServer/ensureAgentsServerBuild.ts +1 -0
- package/src/cli/cli-commands/agents-server/startAgentsServer/createLocalAgentRunOptions.ts +1 -0
- package/src/cli/cli-commands/coder/add.ts +40 -12
- package/src/cli/cli-commands/coder/agentCodingFile.ts +6 -129
- package/src/cli/cli-commands/coder/generate-boilerplates.ts +31 -5
- package/src/cli/cli-commands/coder/getDefaultCoderPackageJsonScripts.ts +1 -1
- package/src/cli/cli-commands/coder/init.ts +27 -1
- package/src/cli/cli-commands/coder/initializeCoderProjectConfiguration.ts +1 -4
- package/src/cli/cli-commands/coder/ping.ts +72 -0
- package/src/cli/cli-commands/coder/run.ts +25 -2
- package/src/cli/cli-commands/coder/verify.ts +27 -12
- package/src/cli/cli-commands/coder.ts +4 -0
- package/src/cli/cli-commands/common/coderGitSyncCliOptions.ts +78 -0
- package/src/cli/cli-commands/run/prepareRunCommandResources.ts +2 -1
- package/src/cli/cli-commands/run/resolveRunInputParameters.ts +2 -1
- package/src/cli/cli-commands/runInteractiveChatbot.ts +2 -1
- package/src/cli/common/$provideLlmToolsForCli.ts +2 -1
- package/src/cli/common/loadPromptsModule.ts +13 -0
- package/src/conversion/archive/loadArchive.ts +2 -1
- package/src/conversion/archive/loadJsZipModule.ts +10 -0
- package/src/conversion/archive/saveArchive.ts +2 -1
- package/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.ts +13 -1
- package/src/llm-providers/azure-openai/AzureOpenAiExecutionTools.ts +13 -1
- package/src/llm-providers/openai/OpenAiAgentKitExecutionTools.ts +6 -2
- package/src/llm-providers/openai/OpenAiAgentKitExecutionToolsToolBuilder.ts +7 -5
- package/src/llm-providers/openai/OpenAiAssistantExecutionTools.ts +1 -1
- package/src/llm-providers/openai/OpenAiAssistantExecutionToolsStreamRunner.ts +1 -1
- package/src/llm-providers/openai/OpenAiAssistantExecutionToolsToolRunner.ts +1 -1
- package/src/llm-providers/openai/OpenAiCompatibleNonChatPromptCaller.ts +1 -1
- package/src/llm-providers/openai/OpenAiCompatibleRequestManager.ts +12 -1
- package/src/llm-providers/openai/utils/callOpenAiCompatibleChatModel.ts +1 -1
- package/src/llm-providers/openai/utils/loadOpenAiAgentsModule.ts +11 -0
- package/src/llm-providers/openai/utils/uploadFilesToOpenAi.ts +1 -1
- package/src/other/templates/getTemplatesPipelineCollection.ts +731 -923
- package/src/remote-server/createRemoteClient.ts +12 -1
- package/src/scrapers/website/WebsiteScraper.ts +22 -2
- package/src/utils/agent-message-runtime/resolveAgentMessageRuntimeActivity.ts +101 -0
- package/src/utils/misc/createLazyModuleLoader.ts +27 -0
- package/src/version.ts +2 -2
- package/src/versions.txt +2 -1
- package/umd/index.umd.js +1180 -342
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/run-codex-prompts/common/runGoScript/scriptExecutionLog.d.ts +7 -0
- package/umd/scripts/run-codex-prompts/git/coderGitSync.d.ts +43 -0
- package/umd/scripts/run-codex-prompts/git/commitChanges.d.ts +3 -0
- package/umd/scripts/run-codex-prompts/main/resolvePromptRunner.d.ts +8 -1
- package/umd/scripts/run-codex-prompts/ping/buildCoderPingPrompt.d.ts +20 -0
- package/umd/scripts/run-codex-prompts/ping/extractCoderPingAnswer.d.ts +9 -0
- package/umd/scripts/run-codex-prompts/ping/pingCoderHarness.d.ts +23 -0
- package/umd/scripts/run-codex-prompts/ping/printCoderPingResult.d.ts +5 -0
- package/umd/scripts/run-codex-prompts/prompts/findNextTodoPrompt.d.ts +2 -1
- package/umd/scripts/run-codex-prompts/prompts/isPromptCompatibleWithRunner.d.ts +27 -0
- package/umd/scripts/run-codex-prompts/prompts/listRunnablePrompts.d.ts +2 -1
- package/umd/scripts/run-codex-prompts/prompts/listUpcomingTasks.d.ts +2 -1
- package/umd/scripts/run-codex-prompts/prompts/replacePromptTodoStatusLine.d.ts +7 -0
- package/umd/scripts/run-codex-prompts/testing/TestBeforeMode.d.ts +16 -0
- package/umd/scripts/run-codex-prompts/testing/createTestBeforeRepairPrompt.d.ts +9 -0
- package/umd/scripts/run-codex-prompts/testing/limitTestOutput.d.ts +4 -0
- package/umd/scripts/run-codex-prompts/testing/runPromptTestCommand.d.ts +1 -2
- package/umd/scripts/run-codex-prompts/testing/runTestBefore.d.ts +24 -0
- package/umd/scripts/run-codex-prompts/ui/buildRunUiFrameShared.d.ts +1 -0
- package/umd/scripts/verify-prompts/verify-prompts.d.ts +5 -0
- package/umd/src/book-2.0/book-language-documentation/BookLanguageManualDictionary.d.ts +1 -15
- package/umd/src/book-2.0/book-language-documentation/getBookLanguageManualCommitmentGroups.d.ts +1 -1
- package/umd/src/book-2.0/book-language-documentation/renderCommitmentCatalogSection.d.ts +0 -4
- package/umd/src/book-components/Chat/utils/$provideServerDomWindow.d.ts +11 -0
- package/umd/src/book-components/Chat/utils/renderMarkdown.d.ts +7 -0
- package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/createAgentsServerRuntimeEnvironment.d.ts +7 -0
- package/umd/src/cli/cli-commands/coder/agentCodingFile.d.ts +2 -3
- package/umd/src/cli/cli-commands/coder/ping.d.ts +10 -0
- package/umd/src/cli/cli-commands/coder/ping.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/coder.d.ts +1 -0
- package/umd/src/cli/cli-commands/common/coderGitSyncCliOptions.d.ts +34 -0
- package/umd/src/cli/cli-commands/common/coderGitSyncCliOptions.test.d.ts +1 -0
- package/umd/src/cli/common/loadPromptsModule.d.ts +16 -0
- package/umd/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.d.ts +1 -1
- package/umd/src/llm-providers/azure-openai/AzureOpenAiExecutionTools.d.ts +1 -1
- package/umd/src/llm-providers/openai/OpenAiAgentKitExecutionTools.d.ts +1 -1
- package/umd/src/llm-providers/openai/OpenAiAgentKitExecutionToolsToolBuilder.d.ts +1 -1
- package/umd/src/llm-providers/openai/OpenAiAssistantExecutionToolsStreamRunner.d.ts +1 -1
- package/umd/src/llm-providers/openai/OpenAiAssistantExecutionToolsToolRunner.d.ts +1 -1
- package/umd/src/llm-providers/openai/OpenAiCompatibleNonChatPromptCaller.d.ts +1 -1
- package/umd/src/llm-providers/openai/OpenAiCompatibleRequestManager.d.ts +1 -1
- package/umd/src/llm-providers/openai/utils/callOpenAiCompatibleChatModel.d.ts +1 -1
- package/umd/src/llm-providers/openai/utils/loadOpenAiAgentsModule.d.ts +203 -0
- package/umd/src/llm-providers/openai/utils/uploadFilesToOpenAi.d.ts +1 -1
- package/umd/src/utils/misc/createLazyModuleLoader.d.ts +14 -0
- package/umd/src/version.d.ts +1 -1
- package/apps/agents-server/src/app/api/onboarding/draft/route.ts +0 -23
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/BookLanguagePanel.tsx +0 -125
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/MarkdownBookEditor.tsx +0 -154
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/MarkdownPreview.tsx +0 -188
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/draftService.ts +0 -32
package/umd/index.umd.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('commander'), require('spacetrim'), require('fs/promises'), require('path'), require('crypto'), require('child_process'), require('moment'), require('fs'), require('dotenv'), require('
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', 'colors', 'commander', 'spacetrim', 'fs/promises', 'path', 'crypto', 'child_process', 'moment', 'fs', 'dotenv', '
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-cli"] = {}, global.colors, global.commander, global._spaceTrim, global.promises, global.path, global.crypto, global.child_process, global.moment, global.fs, global.dotenv, global.
|
|
5
|
-
})(this, (function (exports, colors, commander, _spaceTrim, promises, path, crypto, child_process, moment, fs, dotenv,
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('commander'), require('spacetrim'), require('fs/promises'), require('path'), require('crypto'), require('child_process'), require('moment'), require('fs'), require('dotenv'), require('readline'), require('waitasecond'), require('crypto-js/enc-hex'), require('crypto-js/sha256'), require('crypto-js'), require('showdown'), require('glob-promise'), require('http'), require('express'), require('socket.io'), require('express-openapi-validator'), require('swagger-ui-express'), require('react'), require('react-dom/server'), require('bottleneck'), require('rxjs'), require('ignore'), require('events'), require('os'), require('mime-types'), require('papaparse'), require('@supabase/supabase-js'), require('url')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'colors', 'commander', 'spacetrim', 'fs/promises', 'path', 'crypto', 'child_process', 'moment', 'fs', 'dotenv', 'readline', 'waitasecond', 'crypto-js/enc-hex', 'crypto-js/sha256', 'crypto-js', 'showdown', 'glob-promise', 'http', 'express', 'socket.io', 'express-openapi-validator', 'swagger-ui-express', 'react', 'react-dom/server', 'bottleneck', 'rxjs', 'ignore', 'events', 'os', 'mime-types', 'papaparse', '@supabase/supabase-js', 'url'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-cli"] = {}, global.colors, global.commander, global._spaceTrim, global.promises, global.path, global.crypto, global.child_process, global.moment, global.fs, global.dotenv, global.readline, global.waitasecond, global.hexEncoder, global.sha256, global.CryptoJS, global.showdown, global.glob, global.http, global.express, global.socket_io, global.OpenApiValidator, global.swaggerUi, global.react, global.server, global.Bottleneck, global.rxjs, global.ignore, global.events, global.os, global.mimeTypes, global.papaparse, null, global.url));
|
|
5
|
+
})(this, (function (exports, colors, commander, _spaceTrim, promises, path, crypto, child_process, moment, fs, dotenv, readline, waitasecond, hexEncoder, sha256, CryptoJS, showdown, glob, http, express, socket_io, OpenApiValidator, swaggerUi, react, server, Bottleneck, rxjs, ignore, events, os, mimeTypes, papaparse, supabaseJs, url) { 'use strict';
|
|
6
6
|
|
|
7
7
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
8
8
|
|
|
@@ -30,11 +30,9 @@
|
|
|
30
30
|
var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
|
|
31
31
|
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
32
32
|
var dotenv__namespace = /*#__PURE__*/_interopNamespace(dotenv);
|
|
33
|
-
var prompts__default = /*#__PURE__*/_interopDefaultLegacy(prompts);
|
|
34
33
|
var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
|
|
35
34
|
var hexEncoder__default = /*#__PURE__*/_interopDefaultLegacy(hexEncoder);
|
|
36
35
|
var sha256__default = /*#__PURE__*/_interopDefaultLegacy(sha256);
|
|
37
|
-
var JSZip__default = /*#__PURE__*/_interopDefaultLegacy(JSZip);
|
|
38
36
|
var CryptoJS__default = /*#__PURE__*/_interopDefaultLegacy(CryptoJS);
|
|
39
37
|
var showdown__default = /*#__PURE__*/_interopDefaultLegacy(showdown);
|
|
40
38
|
var glob__default = /*#__PURE__*/_interopDefaultLegacy(glob);
|
|
@@ -42,10 +40,7 @@
|
|
|
42
40
|
var express__default = /*#__PURE__*/_interopDefaultLegacy(express);
|
|
43
41
|
var OpenApiValidator__namespace = /*#__PURE__*/_interopNamespace(OpenApiValidator);
|
|
44
42
|
var swaggerUi__default = /*#__PURE__*/_interopDefaultLegacy(swaggerUi);
|
|
45
|
-
var Anthropic__default = /*#__PURE__*/_interopDefaultLegacy(Anthropic);
|
|
46
43
|
var Bottleneck__default = /*#__PURE__*/_interopDefaultLegacy(Bottleneck);
|
|
47
|
-
var OpenAI__default = /*#__PURE__*/_interopDefaultLegacy(OpenAI);
|
|
48
|
-
var ts__namespace = /*#__PURE__*/_interopNamespace(ts);
|
|
49
44
|
var ignore__default = /*#__PURE__*/_interopDefaultLegacy(ignore);
|
|
50
45
|
var papaparse__default = /*#__PURE__*/_interopDefaultLegacy(papaparse);
|
|
51
46
|
|
|
@@ -63,7 +58,7 @@
|
|
|
63
58
|
* @generated
|
|
64
59
|
* @see https://github.com/webgptorg/promptbook
|
|
65
60
|
*/
|
|
66
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.114.0-
|
|
61
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.114.0-3';
|
|
67
62
|
/**
|
|
68
63
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
69
64
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -3297,6 +3292,12 @@
|
|
|
3297
3292
|
* @private internal constant of `buildAgentsServer`
|
|
3298
3293
|
*/
|
|
3299
3294
|
const PTBK_AGENTS_SERVER_IGNORE_NEXT_VALIDATION_ENV = 'PTBK_AGENTS_SERVER_IGNORE_NEXT_VALIDATION';
|
|
3295
|
+
/**
|
|
3296
|
+
* Environment variable that disables throwaway webpack filesystem caches for CLI-owned production builds.
|
|
3297
|
+
*
|
|
3298
|
+
* @private internal constant of `buildAgentsServer`
|
|
3299
|
+
*/
|
|
3300
|
+
const PTBK_AGENTS_SERVER_DISABLE_WEBPACK_FILESYSTEM_CACHE_ENV = 'PTBK_AGENTS_SERVER_DISABLE_WEBPACK_FILESYSTEM_CACHE';
|
|
3300
3301
|
/**
|
|
3301
3302
|
* Conservative Next.js build worker count used by CLI-owned Agents Server production builds.
|
|
3302
3303
|
*
|
|
@@ -3321,6 +3322,11 @@
|
|
|
3321
3322
|
[PTBK_AGENTS_SERVER_IGNORE_NEXT_VALIDATION_ENV]: 'true',
|
|
3322
3323
|
}
|
|
3323
3324
|
: {}),
|
|
3325
|
+
...(options.isWebpackFilesystemCacheDisabled
|
|
3326
|
+
? {
|
|
3327
|
+
[PTBK_AGENTS_SERVER_DISABLE_WEBPACK_FILESYSTEM_CACHE_ENV]: 'true',
|
|
3328
|
+
}
|
|
3329
|
+
: {}),
|
|
3324
3330
|
};
|
|
3325
3331
|
}
|
|
3326
3332
|
/**
|
|
@@ -4054,6 +4060,7 @@
|
|
|
4054
4060
|
});
|
|
4055
4061
|
const buildEnvironment = createAgentsServerRuntimeEnvironment(environment, preparedRuntime.nodeModulesPath, {
|
|
4056
4062
|
isNextValidationIgnored: preparedRuntime.isAppPathMaterialized,
|
|
4063
|
+
isWebpackFilesystemCacheDisabled: true,
|
|
4057
4064
|
});
|
|
4058
4065
|
if (!options.isBuildForced &&
|
|
4059
4066
|
(await isAgentsServerBuildCacheCurrent({
|
|
@@ -26970,12 +26977,12 @@
|
|
|
26970
26977
|
* Builds the coder-run control pills shown in the footer box.
|
|
26971
26978
|
*/
|
|
26972
26979
|
function buildCoderRunControlPills(options) {
|
|
26973
|
-
const { pauseControl, pendingEnterLabel, isEndAfterCurrentPromptRequested, sessionTotal } = options;
|
|
26980
|
+
const { phase, pauseControl, pendingEnterLabel, isEndAfterCurrentPromptRequested, sessionTotal } = options;
|
|
26974
26981
|
return buildControlPills({
|
|
26975
26982
|
pauseControl,
|
|
26976
26983
|
pendingEnterLabel,
|
|
26977
26984
|
additionalControls: [
|
|
26978
|
-
buildSkipCurrentWaitControl(),
|
|
26985
|
+
...(phase === 'waiting' ? [buildSkipCurrentWaitControl()] : []),
|
|
26979
26986
|
buildEndAfterCurrentPromptControl(isEndAfterCurrentPromptRequested, sessionTotal),
|
|
26980
26987
|
],
|
|
26981
26988
|
});
|
|
@@ -28230,6 +28237,13 @@
|
|
|
28230
28237
|
* Environment variable read by the shell wrapper to tee live output into the temporary runtime log file.
|
|
28231
28238
|
*/
|
|
28232
28239
|
const PTBK_CODER_LOG_FILE_ENV_NAME = 'PTBK_CODER_LOG_FILE';
|
|
28240
|
+
/**
|
|
28241
|
+
* Log line which separates the raw script input from the raw script output of one execution section.
|
|
28242
|
+
*
|
|
28243
|
+
* Readers of a runtime log split on this marker to look only at what the harness really produced,
|
|
28244
|
+
* without the generated script and the prompt it embeds.
|
|
28245
|
+
*/
|
|
28246
|
+
const SCRIPT_EXECUTION_LOG_RAW_OUTPUT_MARKER = '--- raw output ---';
|
|
28233
28247
|
/**
|
|
28234
28248
|
* Small bash wrapper that preserves stdout/stderr streams while teeing both into the runtime log file.
|
|
28235
28249
|
*/
|
|
@@ -28265,7 +28279,7 @@
|
|
|
28265
28279
|
--- raw input ---
|
|
28266
28280
|
${block(normalizedInput)}
|
|
28267
28281
|
|
|
28268
|
-
|
|
28282
|
+
${SCRIPT_EXECUTION_LOG_RAW_OUTPUT_MARKER}
|
|
28269
28283
|
`);
|
|
28270
28284
|
await promises.appendFile(logPath, `${logSection}\n`, 'utf-8');
|
|
28271
28285
|
}
|
|
@@ -29556,6 +29570,7 @@
|
|
|
29556
29570
|
` -c model_reasoning_effort="${thinkingLevel}" \\`,
|
|
29557
29571
|
` --ask-for-approval ${options.askForApproval} \\`,
|
|
29558
29572
|
` exec --model ${options.model} \\`,
|
|
29573
|
+
...(options.isMachineReadableProgressEnabled ? [' --json \\'] : []),
|
|
29559
29574
|
' --local-provider none \\',
|
|
29560
29575
|
` --sandbox ${options.sandbox} \\`,
|
|
29561
29576
|
` -C ${projectPath} \\`,
|
|
@@ -29872,6 +29887,10 @@
|
|
|
29872
29887
|
* Output line that marks finished Codex usage summary.
|
|
29873
29888
|
*/
|
|
29874
29889
|
const CODEX_COMPLETION_LINE = /^\s*tokens used\b/i;
|
|
29890
|
+
/**
|
|
29891
|
+
* Output line that marks the completed Codex turn in JSONL output mode.
|
|
29892
|
+
*/
|
|
29893
|
+
const CODEX_JSON_COMPLETION_LINE = /^\s*\{"type":"turn\.(?:completed|failed)"/u;
|
|
29875
29894
|
/**
|
|
29876
29895
|
* Idle timeout after completion marker to capture trailing output.
|
|
29877
29896
|
*/
|
|
@@ -29948,6 +29967,7 @@
|
|
|
29948
29967
|
sandbox: this.options.sandbox,
|
|
29949
29968
|
askForApproval: this.options.askForApproval,
|
|
29950
29969
|
allowCredits: this.options.allowCredits,
|
|
29970
|
+
isMachineReadableProgressEnabled: this.options.isMachineReadableProgressEnabled,
|
|
29951
29971
|
codexCommand: this.options.codexCommand,
|
|
29952
29972
|
});
|
|
29953
29973
|
for (let retryIndex = 0;; retryIndex++) {
|
|
@@ -29962,7 +29982,9 @@
|
|
|
29962
29982
|
const output = await $runGoScriptUntilMarkerIdle({
|
|
29963
29983
|
scriptPath: options.scriptPath,
|
|
29964
29984
|
scriptContent,
|
|
29965
|
-
completionLineMatcher:
|
|
29985
|
+
completionLineMatcher: this.options.isMachineReadableProgressEnabled
|
|
29986
|
+
? CODEX_JSON_COMPLETION_LINE
|
|
29987
|
+
: CODEX_COMPLETION_LINE,
|
|
29966
29988
|
idleTimeoutMs: CODEX_COMPLETION_IDLE_MS,
|
|
29967
29989
|
logPath: options.logPath,
|
|
29968
29990
|
shouldPrintLiveOutput: options.shouldPrintLiveOutput,
|
|
@@ -30212,6 +30234,7 @@
|
|
|
30212
30234
|
sandbox: 'danger-full-access',
|
|
30213
30235
|
askForApproval: 'never',
|
|
30214
30236
|
allowCredits: options.allowCredits,
|
|
30237
|
+
isMachineReadableProgressEnabled: options.isMachineReadableProgressEnabled,
|
|
30215
30238
|
});
|
|
30216
30239
|
if (!options.allowCredits && options.isVerbose === true) {
|
|
30217
30240
|
console.info(colors__default["default"].gray('OpenAI Codex credit spending is disabled. Use `--allow-credits` to explicitly opt in.'));
|
|
@@ -31447,6 +31470,7 @@
|
|
|
31447
31470
|
: [options.statusMessage, ...options.detailLines.map((detailLine) => `• ${detailLine}`)];
|
|
31448
31471
|
const visibleOutputLines = buildVisibleOutputLines(options.agentOutputLines);
|
|
31449
31472
|
const controls = buildCoderRunControlPills({
|
|
31473
|
+
phase: options.phase,
|
|
31450
31474
|
pauseControl: pausePresentation.pauseControl,
|
|
31451
31475
|
pendingEnterLabel: options.pendingEnterLabel,
|
|
31452
31476
|
isEndAfterCurrentPromptRequested: options.isEndAfterCurrentPromptRequested,
|
|
@@ -32310,6 +32334,7 @@
|
|
|
32310
32334
|
autoPull: options.autoPull,
|
|
32311
32335
|
agentName: options.agentName,
|
|
32312
32336
|
model: options.model,
|
|
32337
|
+
isMachineReadableProgressEnabled: options.isMachineReadableProgressEnabled,
|
|
32313
32338
|
priority: 0,
|
|
32314
32339
|
};
|
|
32315
32340
|
}
|
|
@@ -32931,8 +32956,12 @@
|
|
|
32931
32956
|
* `options.includePaths` can restrict staging, `options.onlyPaths` can restrict the commit pathspec,
|
|
32932
32957
|
* `options.excludePaths` can keep temporary artifacts out of the created commit and
|
|
32933
32958
|
* `options.isEmptyCommitAllowed` keeps a round without any file change from failing.
|
|
32959
|
+
*
|
|
32960
|
+
* Note: The temporary commit message file is written inside the project, so it is always excluded from the commit
|
|
32961
|
+
* itself for projects which do not keep the Promptbook temporary directory out of version control.
|
|
32934
32962
|
*/
|
|
32935
32963
|
async function commitChanges(message, options) {
|
|
32964
|
+
var _a;
|
|
32936
32965
|
const projectPath = (options === null || options === void 0 ? void 0 : options.projectPath) || process.cwd();
|
|
32937
32966
|
const commitMessagePath = resolvePromptbookTemporaryPath(projectPath, 'ptbk-coder', 'commit-messages', `COMMIT_MESSAGE_${Date.now()}.txt`);
|
|
32938
32967
|
await promises.mkdir(path.dirname(commitMessagePath), { recursive: true });
|
|
@@ -32940,7 +32969,10 @@
|
|
|
32940
32969
|
try {
|
|
32941
32970
|
const agentEnv = buildAgentGitEnv();
|
|
32942
32971
|
const signingFlag = buildAgentGitSigningFlag();
|
|
32943
|
-
await stageCommitChanges(projectPath, agentEnv, options === null || options === void 0 ? void 0 : options.includePaths,
|
|
32972
|
+
await stageCommitChanges(projectPath, agentEnv, options === null || options === void 0 ? void 0 : options.includePaths, [
|
|
32973
|
+
commitMessagePath,
|
|
32974
|
+
...((_a = options === null || options === void 0 ? void 0 : options.excludePaths) !== null && _a !== void 0 ? _a : []),
|
|
32975
|
+
]);
|
|
32944
32976
|
await runGitCommand({
|
|
32945
32977
|
command: buildGitCommitCommand({
|
|
32946
32978
|
commitMessagePath,
|
|
@@ -33299,6 +33331,21 @@
|
|
|
33299
33331
|
`);
|
|
33300
33332
|
}
|
|
33301
33333
|
|
|
33334
|
+
/**
|
|
33335
|
+
* Maximum amount of test output embedded into an agent prompt.
|
|
33336
|
+
*/
|
|
33337
|
+
const MAX_TEST_OUTPUT_CHARS = 12000;
|
|
33338
|
+
/**
|
|
33339
|
+
* Limits test output while keeping the end of the output, where test runners usually print the failure summary.
|
|
33340
|
+
*/
|
|
33341
|
+
function limitTestOutput(testOutput) {
|
|
33342
|
+
const normalizedTestOutput = testOutput.trim();
|
|
33343
|
+
if (normalizedTestOutput.length <= MAX_TEST_OUTPUT_CHARS) {
|
|
33344
|
+
return normalizedTestOutput;
|
|
33345
|
+
}
|
|
33346
|
+
return `[..., test output truncated to the last ${MAX_TEST_OUTPUT_CHARS} characters...]\n${normalizedTestOutput.slice(-MAX_TEST_OUTPUT_CHARS)}`;
|
|
33347
|
+
}
|
|
33348
|
+
|
|
33302
33349
|
/**
|
|
33303
33350
|
* Runs the configured verification command inside the project root and returns its output.
|
|
33304
33351
|
*/
|
|
@@ -33319,10 +33366,6 @@
|
|
|
33319
33366
|
* Maximum number of coding attempts allowed for the same prompt when verification keeps failing.
|
|
33320
33367
|
*/
|
|
33321
33368
|
const MAX_PROMPT_TEST_ATTEMPTS = 3;
|
|
33322
|
-
/**
|
|
33323
|
-
* Maximum amount of verification output sent back to the coding agent as retry feedback.
|
|
33324
|
-
*/
|
|
33325
|
-
const MAX_TEST_FEEDBACK_OUTPUT_CHARS = 12000;
|
|
33326
33369
|
/**
|
|
33327
33370
|
* File extension used by generated shell scripts.
|
|
33328
33371
|
*/
|
|
@@ -33368,7 +33411,7 @@
|
|
|
33368
33411
|
return { ...result, attemptCount, steps };
|
|
33369
33412
|
}
|
|
33370
33413
|
const fullVerificationOutput = formatUnknownErrorDetails(failedVerification.error);
|
|
33371
|
-
const feedbackVerificationOutput =
|
|
33414
|
+
const feedbackVerificationOutput = limitTestOutput(fullVerificationOutput);
|
|
33372
33415
|
if (attemptCount >= MAX_PROMPT_TEST_ATTEMPTS) {
|
|
33373
33416
|
console.error(colors__default["default"].red(`Verification failed for ${options.promptLabel} after ${attemptCount} attempts.`));
|
|
33374
33417
|
throw new Error(buildFinalVerificationFailureMessage({
|
|
@@ -33498,19 +33541,6 @@
|
|
|
33498
33541
|
\`\`\`
|
|
33499
33542
|
`);
|
|
33500
33543
|
}
|
|
33501
|
-
/**
|
|
33502
|
-
* Limits verification output before it is embedded back into the next coding prompt.
|
|
33503
|
-
*/
|
|
33504
|
-
function limitVerificationOutputForFeedback(verificationOutput) {
|
|
33505
|
-
const normalizedVerificationOutput = verificationOutput.trim();
|
|
33506
|
-
if (normalizedVerificationOutput.length <= MAX_TEST_FEEDBACK_OUTPUT_CHARS) {
|
|
33507
|
-
return normalizedVerificationOutput;
|
|
33508
|
-
}
|
|
33509
|
-
return spaceTrim(`
|
|
33510
|
-
[...verification output truncated to the last ${MAX_TEST_FEEDBACK_OUTPUT_CHARS} characters...]
|
|
33511
|
-
${normalizedVerificationOutput.slice(-MAX_TEST_FEEDBACK_OUTPUT_CHARS)}
|
|
33512
|
-
`);
|
|
33513
|
-
}
|
|
33514
33544
|
/**
|
|
33515
33545
|
* Derives a dedicated temp-script path for verification commands.
|
|
33516
33546
|
*/
|
|
@@ -41371,6 +41401,7 @@
|
|
|
41371
41401
|
autoClone: false,
|
|
41372
41402
|
maxMessageProcessingFailures: localAgentRunnerLimits.maxFailedAttempts,
|
|
41373
41403
|
maxParallelMessages: localAgentRunnerLimits.maxParallelMessages,
|
|
41404
|
+
isMachineReadableProgressEnabled: true,
|
|
41374
41405
|
};
|
|
41375
41406
|
}
|
|
41376
41407
|
|
|
@@ -42281,6 +42312,91 @@
|
|
|
42281
42312
|
// Note: [🟡] Code for CLI command [agents-server](src/cli/cli-commands/agents-server.ts) should never be published outside of `@promptbook/cli`
|
|
42282
42313
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
42283
42314
|
|
|
42315
|
+
/**
|
|
42316
|
+
* Creates a loader which imports one module on the first call and reuses the very same module afterwards
|
|
42317
|
+
*
|
|
42318
|
+
* Note: [🐌] Heavy third-party dependencies are imported lazily to keep the startup of the Promptbook CLI fast.
|
|
42319
|
+
* A statically imported dependency is loaded every single time the bundle is loaded, even when the running
|
|
42320
|
+
* command never touches it. A lazily imported dependency is loaded only when the feature is really used.
|
|
42321
|
+
*
|
|
42322
|
+
* @example
|
|
42323
|
+
* const loadJsdomModule = createLazyModuleLoader(() => import('jsdom'));
|
|
42324
|
+
* const { JSDOM } = await loadJsdomModule();
|
|
42325
|
+
*
|
|
42326
|
+
* @private internal utility of Promptbook
|
|
42327
|
+
*/
|
|
42328
|
+
function createLazyModuleLoader(importModule) {
|
|
42329
|
+
let importedModulePromise = null;
|
|
42330
|
+
return function loadModule() {
|
|
42331
|
+
if (importedModulePromise === null) {
|
|
42332
|
+
importedModulePromise = importModule();
|
|
42333
|
+
}
|
|
42334
|
+
return importedModulePromise;
|
|
42335
|
+
};
|
|
42336
|
+
}
|
|
42337
|
+
// Note: [🐌] Do not convert the lazy `import(...)` calls back to static `import` statements, it would bring back the
|
|
42338
|
+
// slow startup of the `ptbk` CLI utility
|
|
42339
|
+
|
|
42340
|
+
/**
|
|
42341
|
+
* Loads the interactive terminal prompt library (`prompts`) on demand
|
|
42342
|
+
*
|
|
42343
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast - most commands never ask the user
|
|
42344
|
+
* anything interactively
|
|
42345
|
+
*
|
|
42346
|
+
* @private internal utility of Promptbook CLI
|
|
42347
|
+
*/
|
|
42348
|
+
const loadPromptsModule = createLazyModuleLoader(() => import('prompts'));
|
|
42349
|
+
// Note: [🟡] Code for CLI prompt loading [loadPromptsModule](src/cli/common/loadPromptsModule.ts) should never be published outside of `@promptbook/cli`
|
|
42350
|
+
|
|
42351
|
+
/**
|
|
42352
|
+
* Description block shared by the `ptbk coder` commands which can synchronize their changes with git.
|
|
42353
|
+
*
|
|
42354
|
+
* @private internal utility of `promptbookCli`
|
|
42355
|
+
*/
|
|
42356
|
+
const CODER_GIT_SYNC_DESCRIPTION = _spaceTrim.spaceTrim(`
|
|
42357
|
+
Git synchronization:
|
|
42358
|
+
- --auto-pull pulls the latest changes before this command changes anything
|
|
42359
|
+
- --commit commits the changes made by this command
|
|
42360
|
+
- --auto-push pushes the created commit to the remote repository
|
|
42361
|
+
`);
|
|
42362
|
+
/**
|
|
42363
|
+
* Registers the shared `--commit`, `--auto-push` and `--auto-pull` flags on a `ptbk coder` command.
|
|
42364
|
+
*
|
|
42365
|
+
* Note: Unlike `ptbk coder run`, which commits by default and opts out through `--no-commit`,
|
|
42366
|
+
* these commands never touch git unless the flags are used explicitly.
|
|
42367
|
+
*
|
|
42368
|
+
* @private internal utility of `promptbookCli`
|
|
42369
|
+
*/
|
|
42370
|
+
function addCoderGitSyncOptions(command) {
|
|
42371
|
+
command.option('--commit', 'Commit the changes made by this command with the coding-agent git identity', false);
|
|
42372
|
+
command.option('--auto-push', 'Automatically git push the created commit, requires --commit', false);
|
|
42373
|
+
command.option('--auto-pull', 'Automatically git pull the latest changes before this command changes anything', false);
|
|
42374
|
+
}
|
|
42375
|
+
/**
|
|
42376
|
+
* Converts the Commander git synchronization flags into normalized git synchronization options.
|
|
42377
|
+
*
|
|
42378
|
+
* @private internal utility of `promptbookCli`
|
|
42379
|
+
*/
|
|
42380
|
+
function normalizeCoderGitSyncCliOptions(cliOptions) {
|
|
42381
|
+
if (cliOptions.autoPush && !cliOptions.commit) {
|
|
42382
|
+
throw new NotAllowed(_spaceTrim.spaceTrim(`
|
|
42383
|
+
Flag \`--auto-push\` can be used only together with \`--commit\`.
|
|
42384
|
+
|
|
42385
|
+
**There is nothing to push when the changes are not committed.**
|
|
42386
|
+
|
|
42387
|
+
Actionable hint:
|
|
42388
|
+
- Add \`--commit\`, for example \`ptbk coder init --commit --auto-push\`.
|
|
42389
|
+
`));
|
|
42390
|
+
}
|
|
42391
|
+
return {
|
|
42392
|
+
isCommitEnabled: cliOptions.commit,
|
|
42393
|
+
isAutoPushEnabled: cliOptions.autoPush,
|
|
42394
|
+
isAutoPullEnabled: cliOptions.autoPull,
|
|
42395
|
+
};
|
|
42396
|
+
}
|
|
42397
|
+
// Note: [🟡] Code for CLI git synchronization options [coderGitSyncCliOptions](src/cli/cli-commands/common/coderGitSyncCliOptions.ts) should never be published outside of `@promptbook/cli`
|
|
42398
|
+
// Note: [💞] Ignore a discrepancy between file name and exported helper names
|
|
42399
|
+
|
|
42284
42400
|
/**
|
|
42285
42401
|
* Relative path to the root prompts directory used by Promptbook coder utilities.
|
|
42286
42402
|
*
|
|
@@ -42534,15 +42650,17 @@
|
|
|
42534
42650
|
*/
|
|
42535
42651
|
function $initializeCoderAddCommand(program) {
|
|
42536
42652
|
const command = program.command('add');
|
|
42537
|
-
command.description(_spaceTrim.spaceTrim(`
|
|
42538
|
-
|
|
42653
|
+
command.description(_spaceTrim.spaceTrim((block) => `
|
|
42654
|
+
Add one ready-to-run prompt file to the queue
|
|
42539
42655
|
|
|
42540
|
-
|
|
42541
|
-
|
|
42542
|
-
|
|
42543
|
-
|
|
42544
|
-
|
|
42545
|
-
|
|
42656
|
+
Provide the description as an argument, pipe it through stdin, or run without arguments to type it interactively:
|
|
42657
|
+
- \`ptbk coder add "some new feature"\`
|
|
42658
|
+
- \`ptbk coder add --priority 1 "some new feature"\`
|
|
42659
|
+
- \`ptbk coder add <<EOF ... EOF\`
|
|
42660
|
+
- \`ptbk coder add\`
|
|
42661
|
+
|
|
42662
|
+
${block(CODER_GIT_SYNC_DESCRIPTION)}
|
|
42663
|
+
`));
|
|
42546
42664
|
command.argument('[description]', 'Plain-language description of the feature or task to implement');
|
|
42547
42665
|
command.option('--priority <priority>', 'Priority of the new prompt — higher priorities run first (rendered as trailing `!` markers)', parsePriorityOption, 0);
|
|
42548
42666
|
command.option('--template <template>', _spaceTrim.spaceTrim(`
|
|
@@ -42552,15 +42670,26 @@
|
|
|
42552
42670
|
.map(({ id }) => id)
|
|
42553
42671
|
.join(', ')}) or a markdown file path relative to the current project root.
|
|
42554
42672
|
`));
|
|
42673
|
+
addCoderGitSyncOptions(command);
|
|
42555
42674
|
command.action(handleActionErrors(async (descriptionArgument, cliOptions) => {
|
|
42556
42675
|
const { priority, template: templateOption } = cliOptions;
|
|
42676
|
+
const gitSync = normalizeCoderGitSyncCliOptions(cliOptions);
|
|
42677
|
+
const projectPath = process.cwd();
|
|
42557
42678
|
const description = await resolveCoderPromptDescription(descriptionArgument);
|
|
42558
|
-
|
|
42559
|
-
|
|
42679
|
+
// Note: Import the git synchronization dynamically to keep the CLI fast for runs without `--commit`
|
|
42680
|
+
const { $commitCoderChanges, $pullCoderChanges } = await Promise.resolve().then(function () { return coderGitSync; });
|
|
42681
|
+
await $pullCoderChanges({ gitSync, projectPath });
|
|
42682
|
+
const { /* filePath,*/ emojiTag } = await addCoderPrompt({
|
|
42683
|
+
projectPath,
|
|
42560
42684
|
description,
|
|
42561
42685
|
priority,
|
|
42562
42686
|
templateOption,
|
|
42563
42687
|
});
|
|
42688
|
+
await $commitCoderChanges({
|
|
42689
|
+
gitSync,
|
|
42690
|
+
projectPath,
|
|
42691
|
+
commitMessage: `${emojiTag} Add prompt`,
|
|
42692
|
+
});
|
|
42564
42693
|
}));
|
|
42565
42694
|
}
|
|
42566
42695
|
/**
|
|
@@ -42634,7 +42763,8 @@
|
|
|
42634
42763
|
}
|
|
42635
42764
|
return standardInputDescription;
|
|
42636
42765
|
}
|
|
42637
|
-
const
|
|
42766
|
+
const { default: prompts } = await loadPromptsModule();
|
|
42767
|
+
const response = await prompts({
|
|
42638
42768
|
type: 'text',
|
|
42639
42769
|
name: 'description',
|
|
42640
42770
|
message: 'Describe the feature or task to add',
|
|
@@ -43054,9 +43184,11 @@
|
|
|
43054
43184
|
*/
|
|
43055
43185
|
function $initializeCoderGenerateBoilerplatesCommand(program) {
|
|
43056
43186
|
const command = program.command('generate-boilerplates');
|
|
43057
|
-
command.description(_spaceTrim.spaceTrim(`
|
|
43058
|
-
|
|
43059
|
-
|
|
43187
|
+
command.description(_spaceTrim.spaceTrim((block) => `
|
|
43188
|
+
Generate prompt boilerplate files with unique emoji tags
|
|
43189
|
+
|
|
43190
|
+
${block(CODER_GIT_SYNC_DESCRIPTION)}
|
|
43191
|
+
`));
|
|
43060
43192
|
command.option('--count <count>', `Number of prompt boilerplate files to generate`, '5');
|
|
43061
43193
|
command.option('--template <template>', _spaceTrim.spaceTrim(`
|
|
43062
43194
|
Prompt template to use.
|
|
@@ -43065,14 +43197,25 @@
|
|
|
43065
43197
|
.map(({ id }) => id)
|
|
43066
43198
|
.join(', ')}) or a markdown file path relative to the current project root.
|
|
43067
43199
|
`));
|
|
43200
|
+
addCoderGitSyncOptions(command);
|
|
43068
43201
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
43069
43202
|
const { count: countOption, template: templateOption } = cliOptions;
|
|
43070
43203
|
const filesCount = parseFilesCount(countOption);
|
|
43204
|
+
const gitSync = normalizeCoderGitSyncCliOptions(cliOptions);
|
|
43205
|
+
const projectPath = process.cwd();
|
|
43206
|
+
// Note: Import the git synchronization dynamically to keep the CLI fast for runs without `--commit`
|
|
43207
|
+
const { $commitCoderChanges, $pullCoderChanges } = await Promise.resolve().then(function () { return coderGitSync; });
|
|
43208
|
+
await $pullCoderChanges({ gitSync, projectPath });
|
|
43071
43209
|
await generatePromptBoilerplate({
|
|
43072
|
-
projectPath
|
|
43210
|
+
projectPath,
|
|
43073
43211
|
filesCount,
|
|
43074
43212
|
templateOption,
|
|
43075
43213
|
});
|
|
43214
|
+
await $commitCoderChanges({
|
|
43215
|
+
gitSync,
|
|
43216
|
+
projectPath,
|
|
43217
|
+
commitMessage: `Prompts ${filesCount}x`,
|
|
43218
|
+
});
|
|
43076
43219
|
return process.exit(0);
|
|
43077
43220
|
}));
|
|
43078
43221
|
}
|
|
@@ -43485,6 +43628,27 @@
|
|
|
43485
43628
|
}
|
|
43486
43629
|
// Note: [🟡] Code for CLI harness installation orchestration [$ensureHarnessInstallations](src/cli/cli-commands/common/harness/$ensureHarnessInstallations.ts) should never be published outside of `@promptbook/cli`
|
|
43487
43630
|
|
|
43631
|
+
/**
|
|
43632
|
+
* Relative path to the Promptbook Coder quick-reference file initialized in project roots.
|
|
43633
|
+
*
|
|
43634
|
+
* @private internal utility of `ptbk coder`
|
|
43635
|
+
*/
|
|
43636
|
+
const AGENT_CODING_FILE_PATH = 'AGENT_CODING.md';
|
|
43637
|
+
/**
|
|
43638
|
+
* Returns the default coder `AGENT_CODING.md` quick-reference content.
|
|
43639
|
+
*
|
|
43640
|
+
* @private internal utility of `ptbk coder`
|
|
43641
|
+
*/
|
|
43642
|
+
function getDefaultCoderAgentCodingFileContent() {
|
|
43643
|
+
return _spaceTrim.spaceTrim(`
|
|
43644
|
+
# ✨ Promptbook Coder agent coding
|
|
43645
|
+
|
|
43646
|
+
This project is using [Promptbook Coder](https://coder.ptbk.io) or run \`ptbk coder\`!
|
|
43647
|
+
`);
|
|
43648
|
+
}
|
|
43649
|
+
// Note: [🟡] Code for coder AGENT_CODING file boilerplate [agentCodingFile](src/cli/cli-commands/coder/agentCodingFile.ts) should never be published outside of `@promptbook/cli`
|
|
43650
|
+
// Note: [💞] Ignore a discrepancy between file name and exported helper names
|
|
43651
|
+
|
|
43488
43652
|
/**
|
|
43489
43653
|
* Relative path to the shared coder context file initialized in project roots.
|
|
43490
43654
|
*
|
|
@@ -43512,106 +43676,6 @@
|
|
|
43512
43676
|
// Note: [🟡] Code for coder AGENTS file boilerplate [agentsFile](src/cli/cli-commands/coder/agentsFile.ts) should never be published outside of `@promptbook/cli`
|
|
43513
43677
|
// Note: [💞] Ignore a discrepancy between file name and exported helper names
|
|
43514
43678
|
|
|
43515
|
-
/**
|
|
43516
|
-
* Normalizes one project-relative path for human-readable CLI output and markdown.
|
|
43517
|
-
*
|
|
43518
|
-
* @private internal utility of `ptbk coder`
|
|
43519
|
-
*/
|
|
43520
|
-
function formatDisplayPath(relativePath) {
|
|
43521
|
-
return relativePath.replace(/\\/gu, '/');
|
|
43522
|
-
}
|
|
43523
|
-
// Note: [🟡] Code for coder path formatting [formatDisplayPath](src/cli/cli-commands/coder/formatDisplayPath.ts) should never be published outside of `@promptbook/cli`
|
|
43524
|
-
|
|
43525
|
-
/**
|
|
43526
|
-
* Relative path to the Promptbook Coder quick-reference file initialized in project roots.
|
|
43527
|
-
*
|
|
43528
|
-
* @private internal utility of `ptbk coder`
|
|
43529
|
-
*/
|
|
43530
|
-
const AGENT_CODING_FILE_PATH = 'AGENT_CODING.md';
|
|
43531
|
-
/**
|
|
43532
|
-
* Returns the default coder `AGENT_CODING.md` quick-reference content.
|
|
43533
|
-
*
|
|
43534
|
-
* @private internal utility of `ptbk coder`
|
|
43535
|
-
*/
|
|
43536
|
-
function getDefaultCoderAgentCodingFileContent({ packageJsonScripts, }) {
|
|
43537
|
-
return _spaceTrim.spaceTrim((block) => `
|
|
43538
|
-
# Promptbook Coder quick reference
|
|
43539
|
-
|
|
43540
|
-
This project is prepared for the \`ptbk coder\` workflow. Promptbook Coder does not create a new model on its own; it orchestrates coding agents such as GitHub Copilot, OpenAI Codex, Claude Code, Opencode, Cline, and Gemini CLI through prompt files in \`${formatDisplayPath(PROMPTS_DIRECTORY_PATH)}/\`.
|
|
43541
|
-
|
|
43542
|
-
## Workflow
|
|
43543
|
-
1. Put repository-wide coding rules into \`${AGENTS_FILE_PATH}\`. The default \`npm run coder:run\` script already passes \`--context ${AGENTS_FILE_PATH}\`.
|
|
43544
|
-
2. Create or customize prompt templates in \`${formatDisplayPath(PROMPTS_TEMPLATES_DIRECTORY_PATH)}/\`. ${buildStarterTemplateSentence()}
|
|
43545
|
-
3. Generate prompt files with \`npm run coder:generate-boilerplates\` or \`ptbk coder generate-boilerplates --template <template> --count <count>\`. To append a single ready-to-run prompt straight from a description, use \`npm run coder:add\` or \`ptbk coder add "some new feature"\`.
|
|
43546
|
-
4. Replace every \`@@@\`, keep drafts as \`[-]\`, and switch prompts to \`[ ]\` when they are ready to run. Completed prompts are marked \`[x]\`.
|
|
43547
|
-
5. Run \`npm run coder:run\` to execute the next ready prompt with the configured coding agent.
|
|
43548
|
-
6. Use \`npm run coder:verify\` to archive finished prompts into \`${formatDisplayPath(PROMPTS_DONE_DIRECTORY_PATH)}/\` and append repair follow-up prompts when more work is needed.
|
|
43549
|
-
7. Use \`ptbk coder find-refactor-candidates\` when you want Promptbook to suggest refactor prompts automatically.
|
|
43550
|
-
|
|
43551
|
-
## Templates
|
|
43552
|
-
- Project-owned templates created by \`ptbk coder init\`: ${formatInlineCodeList(getDefaultCoderProjectPromptTemplateDefinitions().map(({ relativeFilePath }) => formatDisplayPath(relativeFilePath)))}
|
|
43553
|
-
- Built-in \`--template\` aliases: ${formatInlineCodeList(getDefaultCoderPromptTemplateDefinitions().map(({ id }) => id))}
|
|
43554
|
-
- To add a custom template, create a markdown file such as \`${formatDisplayPath(PROMPTS_TEMPLATES_DIRECTORY_PATH)}/backend.md\`.
|
|
43555
|
-
- To use a project template, run \`ptbk coder generate-boilerplates --template ${formatDisplayPath(PROMPTS_TEMPLATES_DIRECTORY_PATH)}/backend.md\`.
|
|
43556
|
-
- Keep shared repository rules in \`${AGENTS_FILE_PATH}\` and recurring task-family rules in template files so individual prompt files stay focused on the actual task.
|
|
43557
|
-
|
|
43558
|
-
## Created npm scripts
|
|
43559
|
-
| Script | Purpose |
|
|
43560
|
-
| --- | --- |
|
|
43561
|
-
${block(buildPackageJsonScriptTableLines(packageJsonScripts).join('\n'))}
|
|
43562
|
-
|
|
43563
|
-
## Customizing the workflow
|
|
43564
|
-
- Edit \`package.json\` if you want \`npm run coder:run\` to use another coding agent, model, thinking level, context file, or wait mode.
|
|
43565
|
-
- Use direct CLI commands when you need one-off flags such as \`--min-priority\`, \`--max-priority\`, \`--ignore-git-changes\`, \`--no-commit\`, \`--dry-run\`, \`--test\`, \`--allow-credits\`, or \`--auto-migrate\`.
|
|
43566
|
-
- Use \`ptbk coder --help\` and \`ptbk coder <command> --help\` for the full CLI reference.
|
|
43567
|
-
`);
|
|
43568
|
-
}
|
|
43569
|
-
/**
|
|
43570
|
-
* Builds the sentence describing the starter templates created during initialization.
|
|
43571
|
-
*/
|
|
43572
|
-
function buildStarterTemplateSentence() {
|
|
43573
|
-
const starterTemplatePaths = getDefaultCoderProjectPromptTemplateDefinitions().map(({ relativeFilePath }) => formatDisplayPath(relativeFilePath));
|
|
43574
|
-
if (starterTemplatePaths.length === 1) {
|
|
43575
|
-
return `The starter project template created by \`ptbk coder init\` is \`${starterTemplatePaths[0]}\`.`;
|
|
43576
|
-
}
|
|
43577
|
-
return `The starter project templates created by \`ptbk coder init\` are ${formatInlineCodeList(starterTemplatePaths)}.`;
|
|
43578
|
-
}
|
|
43579
|
-
/**
|
|
43580
|
-
* Builds the markdown table rows describing the initialized npm scripts.
|
|
43581
|
-
*/
|
|
43582
|
-
function buildPackageJsonScriptTableLines(packageJsonScripts) {
|
|
43583
|
-
return Object.entries(packageJsonScripts).map(([scriptName, scriptCommand]) => `| \`npm run ${scriptName}\` | ${describeDefaultCoderPackageJsonScript(scriptName, scriptCommand)} |`);
|
|
43584
|
-
}
|
|
43585
|
-
/**
|
|
43586
|
-
* Describes one initialized npm script in human-readable terms.
|
|
43587
|
-
*/
|
|
43588
|
-
function describeDefaultCoderPackageJsonScript(scriptName, scriptCommand) {
|
|
43589
|
-
if (scriptName === 'coder:generate-boilerplates') {
|
|
43590
|
-
return `Runs \`${scriptCommand}\` to create new prompt files in \`${formatDisplayPath(PROMPTS_DIRECTORY_PATH)}/\`.`;
|
|
43591
|
-
}
|
|
43592
|
-
if (scriptName === 'coder:add') {
|
|
43593
|
-
return `Runs \`${scriptCommand}\` to add one ready-to-run prompt file to \`${formatDisplayPath(PROMPTS_DIRECTORY_PATH)}/\` from a plain-language description.`;
|
|
43594
|
-
}
|
|
43595
|
-
if (scriptName === 'coder:run') {
|
|
43596
|
-
return `Runs \`${scriptCommand}\` to execute the next ready prompt with shared repository context from \`${AGENTS_FILE_PATH}\`.`;
|
|
43597
|
-
}
|
|
43598
|
-
if (scriptName === 'coder:find-refactor-candidates') {
|
|
43599
|
-
return `Runs \`${scriptCommand}\` to generate prompt candidates for large or crowded files.`;
|
|
43600
|
-
}
|
|
43601
|
-
if (scriptName === 'coder:verify') {
|
|
43602
|
-
return `Runs \`${scriptCommand}\` to archive verified prompts into \`${formatDisplayPath(PROMPTS_DONE_DIRECTORY_PATH)}/\` and append repair prompts when needed.`;
|
|
43603
|
-
}
|
|
43604
|
-
return `Runs \`${scriptCommand}\`.`;
|
|
43605
|
-
}
|
|
43606
|
-
/**
|
|
43607
|
-
* Formats one inline code list for human-readable markdown.
|
|
43608
|
-
*/
|
|
43609
|
-
function formatInlineCodeList(values) {
|
|
43610
|
-
return values.map((value) => `\`${value}\``).join(', ');
|
|
43611
|
-
}
|
|
43612
|
-
// Note: [🟡] Code for coder AGENT_CODING file boilerplate [agentCodingFile](src/cli/cli-commands/coder/agentCodingFile.ts) should never be published outside of `@promptbook/cli`
|
|
43613
|
-
// Note: [💞] Ignore a discrepancy between file name and exported helper names
|
|
43614
|
-
|
|
43615
43679
|
/**
|
|
43616
43680
|
* Relative directory path for agents initialized by `ptbk coder init`.
|
|
43617
43681
|
*
|
|
@@ -43676,6 +43740,16 @@
|
|
|
43676
43740
|
}
|
|
43677
43741
|
// Note: [🟡] Code for coder init developer agent bootstrapping [ensureCoderDeveloperAgentFile](src/cli/cli-commands/coder/ensureCoderDeveloperAgentFile.ts) should never be published outside of `@promptbook/cli`
|
|
43678
43742
|
|
|
43743
|
+
/**
|
|
43744
|
+
* Normalizes one project-relative path for human-readable CLI output and markdown.
|
|
43745
|
+
*
|
|
43746
|
+
* @private internal utility of `ptbk coder`
|
|
43747
|
+
*/
|
|
43748
|
+
function formatDisplayPath(relativePath) {
|
|
43749
|
+
return relativePath.replace(/\\/gu, '/');
|
|
43750
|
+
}
|
|
43751
|
+
// Note: [🟡] Code for coder path formatting [formatDisplayPath](src/cli/cli-commands/coder/formatDisplayPath.ts) should never be published outside of `@promptbook/cli`
|
|
43752
|
+
|
|
43679
43753
|
/**
|
|
43680
43754
|
* Fallback `.env` content used when no required variables need to be appended.
|
|
43681
43755
|
*/
|
|
@@ -43753,7 +43827,7 @@
|
|
|
43753
43827
|
const DEFAULT_CODER_PACKAGE_JSON_SCRIPTS = {
|
|
43754
43828
|
'coder:generate-boilerplates': 'ptbk coder generate-boilerplates --template ./prompts/templates/common.md',
|
|
43755
43829
|
'coder:add': 'ptbk coder add --template ./prompts/templates/common.md',
|
|
43756
|
-
'coder:run': 'ptbk coder run --harness openai-codex --model gpt-5.
|
|
43830
|
+
'coder:run': 'ptbk coder run --harness openai-codex --model gpt-5.6-terra --thinking-level max --agent agents/developer.book --context AGENTS.md --test-before yes-and-fix',
|
|
43757
43831
|
// 'coder:find-refactor-candidates': 'npx ptbk coder find-refactor-candidates',
|
|
43758
43832
|
'coder:verify': 'ptbk coder verify',
|
|
43759
43833
|
};
|
|
@@ -44002,9 +44076,7 @@
|
|
|
44002
44076
|
const agentsDirectoryStatus = await ensureDirectory(projectPath, CODER_AGENTS_DIRECTORY_PATH);
|
|
44003
44077
|
const developerAgentFileStatus = await ensureCoderDeveloperAgentFile(projectPath);
|
|
44004
44078
|
const agentsFileStatus = await ensureCoderMarkdownFile(projectPath, AGENTS_FILE_PATH, getDefaultCoderAgentsFileContent());
|
|
44005
|
-
const agentCodingFileStatus = await ensureCoderMarkdownFile(projectPath, AGENT_CODING_FILE_PATH, getDefaultCoderAgentCodingFileContent(
|
|
44006
|
-
packageJsonScripts: getDefaultCoderPackageJsonScripts(),
|
|
44007
|
-
}));
|
|
44079
|
+
const agentCodingFileStatus = await ensureCoderMarkdownFile(projectPath, AGENT_CODING_FILE_PATH, getDefaultCoderAgentCodingFileContent());
|
|
44008
44080
|
const { envFileStatus, initializedEnvVariableNames } = await ensureCoderEnvFile(projectPath);
|
|
44009
44081
|
const gitignoreFileStatus = await ensureCoderGitignoreFile(projectPath);
|
|
44010
44082
|
const packageJsonFileStatus = await ensureCoderPackageJsonFile(projectPath);
|
|
@@ -44119,12 +44191,24 @@
|
|
|
44119
44191
|
|
|
44120
44192
|
Checks that the coding harnesses are installed globally and up to date:
|
|
44121
44193
|
${block(listCheckedHarnessLabels())}
|
|
44194
|
+
|
|
44195
|
+
${block(CODER_GIT_SYNC_DESCRIPTION)}
|
|
44122
44196
|
`));
|
|
44123
|
-
command
|
|
44197
|
+
addCoderGitSyncOptions(command);
|
|
44198
|
+
command.action(handleActionErrors(async (cliOptions) => {
|
|
44199
|
+
const gitSync = normalizeCoderGitSyncCliOptions(cliOptions);
|
|
44124
44200
|
const projectPath = process.cwd();
|
|
44201
|
+
// Note: Import the git synchronization dynamically to keep the CLI fast for runs without `--commit`
|
|
44202
|
+
const { $commitCoderChanges, $pullCoderChanges } = await Promise.resolve().then(function () { return coderGitSync; });
|
|
44203
|
+
await $pullCoderChanges({ gitSync, projectPath });
|
|
44125
44204
|
const summary = await initializeCoderProjectConfiguration(projectPath);
|
|
44126
44205
|
printInitializationSummary(summary);
|
|
44127
44206
|
await generatePromptBoilerplate({ projectPath, filesCount: 5 });
|
|
44207
|
+
await $commitCoderChanges({
|
|
44208
|
+
gitSync,
|
|
44209
|
+
projectPath,
|
|
44210
|
+
commitMessage: 'Initialize Promptbook Coder',
|
|
44211
|
+
});
|
|
44128
44212
|
await $ensureHarnessInstallations(CODER_INIT_CHECKED_HARNESS_NAMES);
|
|
44129
44213
|
}));
|
|
44130
44214
|
}
|
|
@@ -44145,6 +44229,48 @@
|
|
|
44145
44229
|
// Note: [🟡] Code for CLI command [init](src/cli/cli-commands/coder/init.ts) should never be published outside of `@promptbook/cli`
|
|
44146
44230
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
44147
44231
|
|
|
44232
|
+
/**
|
|
44233
|
+
* Initializes `coder ping` command for Promptbook CLI utilities
|
|
44234
|
+
*
|
|
44235
|
+
* Note: `$` is used to indicate that this function is not a pure function - it registers a command in the CLI
|
|
44236
|
+
*
|
|
44237
|
+
* @private internal function of `promptbookCli`
|
|
44238
|
+
*/
|
|
44239
|
+
function $initializeCoderPingCommand(program) {
|
|
44240
|
+
const command = program.command('ping');
|
|
44241
|
+
command.description(_spaceTrim.spaceTrim(`
|
|
44242
|
+
Send one tiny dummy prompt to a harness and model to measure and warm them up
|
|
44243
|
+
|
|
44244
|
+
${PROMPT_RUNNER_DESCRIPTION}
|
|
44245
|
+
|
|
44246
|
+
Features:
|
|
44247
|
+
- Verifies that the selected harness, model, thinking level and authentication really work
|
|
44248
|
+
- Reports the answer of the harness, the response time and the reported usage
|
|
44249
|
+
- Starts the hourly/weekly quota window before you need it, so it is already refreshing when you do
|
|
44250
|
+
- Leaves the project exactly as it was — nothing is read, written, changed or committed
|
|
44251
|
+
- Use --no-ui to stream the raw harness output instead of only the compact result
|
|
44252
|
+
`));
|
|
44253
|
+
addPromptRunnerSelectionOptions(command);
|
|
44254
|
+
addPromptRunnerRuntimeOptions(command);
|
|
44255
|
+
command.action(handleActionErrors(async (cliOptions) => {
|
|
44256
|
+
const runnerOptions = normalizePromptRunnerSelectionCliOptions(cliOptions, { isAgentRequired: true });
|
|
44257
|
+
await $ensureHarnessInstallations([runnerOptions.agentName]);
|
|
44258
|
+
// Note: Import the ping dynamically to avoid loading heavy dependencies until needed
|
|
44259
|
+
const { pingCoderHarness } = await Promise.resolve().then(function () { return pingCoderHarness$1; });
|
|
44260
|
+
const { printCoderPingResult } = await Promise.resolve().then(function () { return printCoderPingResult$1; });
|
|
44261
|
+
const result = await pingCoderHarness({
|
|
44262
|
+
agentName: runnerOptions.agentName,
|
|
44263
|
+
model: runnerOptions.model,
|
|
44264
|
+
thinkingLevel: runnerOptions.thinkingLevel,
|
|
44265
|
+
allowCredits: runnerOptions.allowCredits,
|
|
44266
|
+
shouldPrintLiveOutput: runnerOptions.noUi,
|
|
44267
|
+
});
|
|
44268
|
+
printCoderPingResult(result);
|
|
44269
|
+
}));
|
|
44270
|
+
}
|
|
44271
|
+
// Note: [🟡] Code for CLI command [ping](src/cli/cli-commands/coder/ping.ts) should never be published outside of `@promptbook/cli`
|
|
44272
|
+
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
44273
|
+
|
|
44148
44274
|
/**
|
|
44149
44275
|
* Creates a Commander argument parser that accepts only non-negative integers.
|
|
44150
44276
|
*
|
|
@@ -44169,6 +44295,21 @@
|
|
|
44169
44295
|
}
|
|
44170
44296
|
// Note: [🟡] Code for CLI option parser [createNonNegativeIntegerOptionParser](src/cli/cli-commands/common/createNonNegativeIntegerOptionParser.ts) should never be published outside of `@promptbook/cli`
|
|
44171
44297
|
|
|
44298
|
+
/**
|
|
44299
|
+
* Modes supported by `ptbk coder run --test-before`.
|
|
44300
|
+
*/
|
|
44301
|
+
const TEST_BEFORE_MODE_VALUES = ['no', 'yes-and-fail', 'yes-and-fix'];
|
|
44302
|
+
/**
|
|
44303
|
+
* Default verification command used when a pre-coding mode is enabled without an explicit `--test` command.
|
|
44304
|
+
*/
|
|
44305
|
+
const DEFAULT_CODER_TEST_COMMAND = 'npm test';
|
|
44306
|
+
/**
|
|
44307
|
+
* Checks whether a value is a supported `--test-before` mode.
|
|
44308
|
+
*/
|
|
44309
|
+
function isTestBeforeMode(value) {
|
|
44310
|
+
return TEST_BEFORE_MODE_VALUES.includes(value);
|
|
44311
|
+
}
|
|
44312
|
+
|
|
44172
44313
|
/**
|
|
44173
44314
|
* Default wait duration applied before retrying a prompt round after an error (10 minutes).
|
|
44174
44315
|
*
|
|
@@ -44213,6 +44354,7 @@
|
|
|
44213
44354
|
- Optional --no-ui keeps plain streaming console output for logging and debugging
|
|
44214
44355
|
- Checks that the selected harness is installed globally and up to date before the first prompt
|
|
44215
44356
|
- Supports GPG signing of commits
|
|
44357
|
+
- Optional pre-coding test run that can stop or repair pre-existing failures
|
|
44216
44358
|
- Optional post-prompt verification with test-feedback retries
|
|
44217
44359
|
- Progress tracking and interactive P/S/X terminal controls
|
|
44218
44360
|
- Dry-run mode to preview prompts
|
|
@@ -44222,6 +44364,9 @@
|
|
|
44222
44364
|
command.option('--agent <agent-book-path>', 'Path to a .book file whose compiled system message is prepended to each coding prompt');
|
|
44223
44365
|
command.option('--context <context-or-file>', 'Append extra instructions either inline or from a file path relative to the current project');
|
|
44224
44366
|
command.option('--test <test-command...>', 'Run a verification command after each prompt; quote it when the command itself contains top-level flags');
|
|
44367
|
+
command.addOption(new commander.Option('--test-before <mode>', `Run tests before coding: ${TEST_BEFORE_MODE_VALUES.join(', ')} (defaults to no; uses npm test when --test is omitted)`)
|
|
44368
|
+
.choices([...TEST_BEFORE_MODE_VALUES])
|
|
44369
|
+
.default('no'));
|
|
44225
44370
|
command.option('--preserve-logs', 'Keep generated temp prompt/log artifacts after successful rounds for debugging and analytics', false);
|
|
44226
44371
|
addPromptRunnerExecutionOptions(command);
|
|
44227
44372
|
command.option('--isolate', _spaceTrim.spaceTrim(`
|
|
@@ -44251,8 +44396,9 @@
|
|
|
44251
44396
|
command.option('--auto-migrate', 'Run testing-server database migrations automatically after each successfully processed prompt');
|
|
44252
44397
|
command.option('--allow-destructive-auto-migrate', 'Allow auto-migrate even when heuristic SQL safety check flags destructive pending migrations');
|
|
44253
44398
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
44254
|
-
const { dryRun, agent, context, test, preserveLogs, isolate: isIsolated, priority, minPriority: minimumPriority, maxPriority: maximumPriority, limit, waitAfterPrompt: waitAfterPromptValue, waitBetweenPrompts: waitBetweenPromptsValue, waitAfterError: waitAfterErrorValue, auto, autoMigrate, allowDestructiveAutoMigrate, } = cliOptions;
|
|
44255
|
-
const
|
|
44399
|
+
const { dryRun, agent, context, test, testBefore, preserveLogs, isolate: isIsolated, priority, minPriority: minimumPriority, maxPriority: maximumPriority, limit, waitAfterPrompt: waitAfterPromptValue, waitBetweenPrompts: waitBetweenPromptsValue, waitAfterError: waitAfterErrorValue, auto, autoMigrate, allowDestructiveAutoMigrate, } = cliOptions;
|
|
44400
|
+
const configuredTestCommand = normalizeCommandOptionValue$1(test);
|
|
44401
|
+
const testCommand = configuredTestCommand !== null && configuredTestCommand !== void 0 ? configuredTestCommand : (testBefore === 'no' ? undefined : DEFAULT_CODER_TEST_COMMAND);
|
|
44256
44402
|
const runnerOptions = normalizePromptRunnerCliOptions(cliOptions, {
|
|
44257
44403
|
isAgentRequired: !dryRun,
|
|
44258
44404
|
});
|
|
@@ -44281,6 +44427,7 @@
|
|
|
44281
44427
|
agent,
|
|
44282
44428
|
context,
|
|
44283
44429
|
testCommand,
|
|
44430
|
+
testBefore,
|
|
44284
44431
|
preserveLogs,
|
|
44285
44432
|
isIsolated,
|
|
44286
44433
|
noUi: runnerOptions.noUi,
|
|
@@ -44491,25 +44638,31 @@
|
|
|
44491
44638
|
*/
|
|
44492
44639
|
function $initializeCoderVerifyCommand(program) {
|
|
44493
44640
|
const command = program.command('verify');
|
|
44494
|
-
command.description(_spaceTrim.spaceTrim(`
|
|
44495
|
-
|
|
44641
|
+
command.description(_spaceTrim.spaceTrim((block) => `
|
|
44642
|
+
Interactive verification helper for completed prompts
|
|
44496
44643
|
|
|
44497
|
-
|
|
44498
|
-
|
|
44499
|
-
|
|
44500
|
-
|
|
44501
|
-
|
|
44502
|
-
|
|
44503
|
-
|
|
44504
|
-
|
|
44644
|
+
Features:
|
|
44645
|
+
- Displays list of prompt files with status counts
|
|
44646
|
+
- Guides through verification of completed prompts marked [x]
|
|
44647
|
+
- Archives verified prompt files to prompts/done/ directory
|
|
44648
|
+
- Auto-appends repair prompts for incomplete work
|
|
44649
|
+
- Processes files with all-done prompts first
|
|
44650
|
+
- Supports ignoring matching prompt candidates for one verification run
|
|
44651
|
+
|
|
44652
|
+
${block(CODER_GIT_SYNC_DESCRIPTION)}
|
|
44653
|
+
|
|
44654
|
+
Note: The git synchronization is applied around each single verification, not once per run.
|
|
44655
|
+
`));
|
|
44505
44656
|
command.option('--reverse', 'Process prompt files in reverse order', false);
|
|
44506
44657
|
command.option('--ignore <candidate-text>', 'Ignore prompt files whose filename or first prompt line contains the given text (repeatable)', collectStringOption, []);
|
|
44658
|
+
addCoderGitSyncOptions(command);
|
|
44507
44659
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
44508
44660
|
const { reverse, ignore } = cliOptions;
|
|
44661
|
+
const gitSync = normalizeCoderGitSyncCliOptions(cliOptions);
|
|
44509
44662
|
// Note: Import the main function dynamically to avoid loading heavy dependencies until needed
|
|
44510
44663
|
const { verifyPrompts } = await Promise.resolve().then(function () { return verifyPrompts$1; });
|
|
44511
44664
|
try {
|
|
44512
|
-
await verifyPrompts({ reverse, ignore });
|
|
44665
|
+
await verifyPrompts({ reverse, ignore, gitSync });
|
|
44513
44666
|
}
|
|
44514
44667
|
catch (error) {
|
|
44515
44668
|
console.error(colors__default["default"].bgRed('Prompt verification failed:'), error);
|
|
@@ -44538,6 +44691,7 @@
|
|
|
44538
44691
|
* - generate-boilerplates: Generate prompt boilerplate files
|
|
44539
44692
|
* - find-refactor-candidates: Find files that need refactoring
|
|
44540
44693
|
* - run: Run coding prompts with AI agents
|
|
44694
|
+
* - ping: Test one harness and model with a tiny dummy prompt
|
|
44541
44695
|
* - verify: Verify completed prompts
|
|
44542
44696
|
* - find-fresh-emoji-tags: Find unused emoji tags
|
|
44543
44697
|
*
|
|
@@ -44557,6 +44711,7 @@
|
|
|
44557
44711
|
- find-refactor-candidates: Find files that need refactoring
|
|
44558
44712
|
- find-unwritten: List prompt sections that still need to be authored
|
|
44559
44713
|
- run: Run coding prompts with AI agents
|
|
44714
|
+
- ping: Test the connection, response time and quota of one harness and model
|
|
44560
44715
|
- server: Start a long-running coder server with a kanban web UI
|
|
44561
44716
|
- verify: Verify completed prompts
|
|
44562
44717
|
- find-fresh-emoji-tags: Find unused emoji tags
|
|
@@ -44568,6 +44723,7 @@
|
|
|
44568
44723
|
$initializeCoderFindRefactorCandidatesCommand(coderCommand);
|
|
44569
44724
|
$initializeCoderFindUnwrittenCommand(coderCommand);
|
|
44570
44725
|
$initializeCoderRunCommand(coderCommand);
|
|
44726
|
+
$initializeCoderPingCommand(coderCommand);
|
|
44571
44727
|
$initializeCoderServerCommand(coderCommand);
|
|
44572
44728
|
$initializeCoderVerifyCommand(coderCommand);
|
|
44573
44729
|
$initializeCoderFindFreshEmojiTagCommand(coderCommand);
|
|
@@ -45401,6 +45557,14 @@
|
|
|
45401
45557
|
// Note: [🟢] Code for Node file-cache storage [FileCacheStorage](src/storage/file-cache-storage/FileCacheStorage.ts) should never be published into packages that could be imported into browser environment
|
|
45402
45558
|
// TODO: [🌗] Maybe some checkers, not all valid JSONs are desired and valid values
|
|
45403
45559
|
|
|
45560
|
+
/**
|
|
45561
|
+
* Loads the Socket.io client (`socket.io-client`) on demand
|
|
45562
|
+
*
|
|
45563
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
45564
|
+
*
|
|
45565
|
+
* @private internal utility of `createRemoteClient`
|
|
45566
|
+
*/
|
|
45567
|
+
const loadSocketIoClientModule = createLazyModuleLoader(() => import('socket.io-client'));
|
|
45404
45568
|
/**
|
|
45405
45569
|
* Creates a connection to the remote proxy server.
|
|
45406
45570
|
*
|
|
@@ -45429,8 +45593,9 @@
|
|
|
45429
45593
|
|
|
45430
45594
|
`));
|
|
45431
45595
|
}
|
|
45596
|
+
const { io } = await loadSocketIoClientModule();
|
|
45432
45597
|
return new Promise((resolve, reject) => {
|
|
45433
|
-
const socket =
|
|
45598
|
+
const socket = io(remoteServerUrl, {
|
|
45434
45599
|
retries: CONNECTION_RETRIES_LIMIT,
|
|
45435
45600
|
timeout: CONNECTION_TIMEOUT_MS,
|
|
45436
45601
|
path: '/socket.io',
|
|
@@ -46096,7 +46261,8 @@
|
|
|
46096
46261
|
You will be logged in to ${remoteServerUrl}
|
|
46097
46262
|
If you don't have an account, it will be created automatically.
|
|
46098
46263
|
`)));
|
|
46099
|
-
const {
|
|
46264
|
+
const { default: prompts } = await loadPromptsModule();
|
|
46265
|
+
const { username, password } = await prompts([
|
|
46100
46266
|
{
|
|
46101
46267
|
type: 'text',
|
|
46102
46268
|
name: 'username',
|
|
@@ -46471,6 +46637,15 @@
|
|
|
46471
46637
|
// TODO: Implement non-interactive login
|
|
46472
46638
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
46473
46639
|
|
|
46640
|
+
/**
|
|
46641
|
+
* Loads the ZIP archive library (`jszip`) on demand
|
|
46642
|
+
*
|
|
46643
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
46644
|
+
*
|
|
46645
|
+
* @private internal utility of `loadArchive` and `saveArchive`
|
|
46646
|
+
*/
|
|
46647
|
+
const loadJsZipModule = createLazyModuleLoader(() => import('jszip'));
|
|
46648
|
+
|
|
46474
46649
|
/**
|
|
46475
46650
|
* Loads the books from the archive file with `.bookc` extension
|
|
46476
46651
|
*
|
|
@@ -46485,7 +46660,8 @@
|
|
|
46485
46660
|
throw new UnexpectedError(`Archive file must have '.bookc' extension`);
|
|
46486
46661
|
}
|
|
46487
46662
|
const data = await fs.readFile(filePath);
|
|
46488
|
-
const
|
|
46663
|
+
const { default: JSZip } = await loadJsZipModule();
|
|
46664
|
+
const archive = await JSZip.loadAsync(data);
|
|
46489
46665
|
const indexFile = archive.file('index.book.json');
|
|
46490
46666
|
if (!indexFile) {
|
|
46491
46667
|
throw new UnexpectedError(`Archive does not contain 'index.book.json' file`);
|
|
@@ -50548,7 +50724,23 @@
|
|
|
50548
50724
|
});
|
|
50549
50725
|
}
|
|
50550
50726
|
|
|
50551
|
-
|
|
50727
|
+
/**
|
|
50728
|
+
* Loads `jsdom` on demand
|
|
50729
|
+
*
|
|
50730
|
+
* Note: [🐌] `jsdom` is by far the heaviest dependency of Promptbook, loading it eagerly would slow down every single
|
|
50731
|
+
* run of the `ptbk` CLI utility even when no website is scraped
|
|
50732
|
+
*
|
|
50733
|
+
* @private internal utility of `WebsiteScraper`
|
|
50734
|
+
*/
|
|
50735
|
+
const loadJsdomModule = createLazyModuleLoader(() => import('jsdom'));
|
|
50736
|
+
/**
|
|
50737
|
+
* Loads `@mozilla/readability` on demand
|
|
50738
|
+
*
|
|
50739
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
50740
|
+
*
|
|
50741
|
+
* @private internal utility of `WebsiteScraper`
|
|
50742
|
+
*/
|
|
50743
|
+
const loadReadabilityModule = createLazyModuleLoader(() => import('@mozilla/readability'));
|
|
50552
50744
|
/**
|
|
50553
50745
|
* Scraper for websites
|
|
50554
50746
|
*
|
|
@@ -50584,14 +50776,15 @@
|
|
|
50584
50776
|
if (this.tools.fs === undefined) {
|
|
50585
50777
|
throw new EnvironmentMismatchError('Can not scrape websites without filesystem tools');
|
|
50586
50778
|
}
|
|
50587
|
-
const
|
|
50779
|
+
const [{ JSDOM }, { Readability }] = await Promise.all([loadJsdomModule(), loadReadabilityModule()]);
|
|
50780
|
+
const jsdom = new JSDOM(await source.asText(), {
|
|
50588
50781
|
url: source.url,
|
|
50589
50782
|
});
|
|
50590
|
-
const reader = new
|
|
50783
|
+
const reader = new Readability(jsdom.window.document);
|
|
50591
50784
|
const article = reader.parse();
|
|
50592
50785
|
// console.log(article);
|
|
50593
50786
|
// await forTime(10000);
|
|
50594
|
-
let html = (article === null || article === void 0 ? void 0 : article.content) || (article === null || article === void 0 ? void 0 : article.textContent) || jsdom
|
|
50787
|
+
let html = (article === null || article === void 0 ? void 0 : article.content) || (article === null || article === void 0 ? void 0 : article.textContent) || jsdom.window.document.body.innerHTML;
|
|
50595
50788
|
// Note: Unwrap html such as it is convertable by `markdownConverter`
|
|
50596
50789
|
for (let i = 0; i < 2; i++) {
|
|
50597
50790
|
html = html.replace(/<div\s*(?:id="readability-page-\d+"\s+class="page")?>(.*)<\/div>/is, '$1');
|
|
@@ -50624,7 +50817,7 @@
|
|
|
50624
50817
|
throw error;
|
|
50625
50818
|
}
|
|
50626
50819
|
}
|
|
50627
|
-
const markdown = this.showdownConverter.makeMarkdown(html, jsdom
|
|
50820
|
+
const markdown = this.showdownConverter.makeMarkdown(html, jsdom.window.document);
|
|
50628
50821
|
return { ...cacheFilehandler, markdown };
|
|
50629
50822
|
}
|
|
50630
50823
|
/**
|
|
@@ -54187,7 +54380,8 @@
|
|
|
54187
54380
|
for (const pipelineJson of collectionJson) {
|
|
54188
54381
|
validatePipeline(pipelineJson);
|
|
54189
54382
|
}
|
|
54190
|
-
const
|
|
54383
|
+
const { default: JSZip } = await loadJsZipModule();
|
|
54384
|
+
const archive = new JSZip();
|
|
54191
54385
|
const collectionJsonString = stringifyPipelineJson(collectionJson);
|
|
54192
54386
|
archive.file('index.book.json', collectionJsonString);
|
|
54193
54387
|
const data = await archive.generateAsync({ type: 'nodebuffer', streamFiles: true });
|
|
@@ -54815,7 +55009,8 @@
|
|
|
54815
55009
|
else {
|
|
54816
55010
|
console.info(colors__default["default"].gray(`---`));
|
|
54817
55011
|
}
|
|
54818
|
-
const
|
|
55012
|
+
const { default: prompts } = await loadPromptsModule();
|
|
55013
|
+
const response = await prompts({
|
|
54819
55014
|
type: 'text',
|
|
54820
55015
|
name: 'userMessage',
|
|
54821
55016
|
message: 'User message',
|
|
@@ -55122,7 +55317,8 @@
|
|
|
55122
55317
|
if (pipelineSource) {
|
|
55123
55318
|
return pipelineSource;
|
|
55124
55319
|
}
|
|
55125
|
-
const
|
|
55320
|
+
const { default: prompts } = await loadPromptsModule();
|
|
55321
|
+
const response = await prompts({
|
|
55126
55322
|
type: 'text',
|
|
55127
55323
|
name: 'pipelineSource',
|
|
55128
55324
|
message: '',
|
|
@@ -55209,7 +55405,8 @@
|
|
|
55209
55405
|
console.error(colors__default["default"].red(createRunMissingInputParametersMessage(pipeline, inputParameters, questions)));
|
|
55210
55406
|
return process.exit(1);
|
|
55211
55407
|
}
|
|
55212
|
-
const
|
|
55408
|
+
const { default: prompts } = await loadPromptsModule();
|
|
55409
|
+
const response = await prompts(questions);
|
|
55213
55410
|
// <- TODO: [🧠][🍼] Change behavior according to the formfactor
|
|
55214
55411
|
return { ...inputParameters, ...response };
|
|
55215
55412
|
// <- TODO: Maybe do some validation of the response (and --json argument which is passed)
|
|
@@ -58114,6 +58311,14 @@
|
|
|
58114
58311
|
fullname: 'Anthropic Claude',
|
|
58115
58312
|
color: '#d97706',
|
|
58116
58313
|
};
|
|
58314
|
+
/**
|
|
58315
|
+
* Loads the Anthropic Claude SDK (`@anthropic-ai/sdk`) on demand
|
|
58316
|
+
*
|
|
58317
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
58318
|
+
*
|
|
58319
|
+
* @private internal utility of `AnthropicClaudeExecutionTools`
|
|
58320
|
+
*/
|
|
58321
|
+
const loadAnthropicClaudeModule = createLazyModuleLoader(() => import('@anthropic-ai/sdk'));
|
|
58117
58322
|
/**
|
|
58118
58323
|
* Execution Tools for calling Anthropic Claude API.
|
|
58119
58324
|
*
|
|
@@ -58151,7 +58356,8 @@
|
|
|
58151
58356
|
const anthropicOptions = { ...this.options };
|
|
58152
58357
|
delete anthropicOptions.isVerbose;
|
|
58153
58358
|
delete anthropicOptions.isProxied;
|
|
58154
|
-
|
|
58359
|
+
const { Anthropic } = await loadAnthropicClaudeModule();
|
|
58360
|
+
this.client = new Anthropic(anthropicOptions);
|
|
58155
58361
|
}
|
|
58156
58362
|
return this.client;
|
|
58157
58363
|
}
|
|
@@ -58414,6 +58620,14 @@
|
|
|
58414
58620
|
fullname: 'Azure OpenAI',
|
|
58415
58621
|
color: '#0078d4',
|
|
58416
58622
|
};
|
|
58623
|
+
/**
|
|
58624
|
+
* Loads the Azure OpenAI SDK (`@azure/openai`) on demand
|
|
58625
|
+
*
|
|
58626
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
58627
|
+
*
|
|
58628
|
+
* @private internal utility of `AzureOpenAiExecutionTools`
|
|
58629
|
+
*/
|
|
58630
|
+
const loadAzureOpenAiModule = createLazyModuleLoader(() => import('@azure/openai'));
|
|
58417
58631
|
/**
|
|
58418
58632
|
* Execution Tools for calling Azure OpenAI API.
|
|
58419
58633
|
*
|
|
@@ -58447,7 +58661,8 @@
|
|
|
58447
58661
|
}
|
|
58448
58662
|
async getClient() {
|
|
58449
58663
|
if (this.client === null) {
|
|
58450
|
-
|
|
58664
|
+
const { AzureKeyCredential, OpenAIClient } = await loadAzureOpenAiModule();
|
|
58665
|
+
this.client = new OpenAIClient(`https://${this.options.resourceName}.openai.azure.com/`, new AzureKeyCredential(this.options.apiKey));
|
|
58451
58666
|
}
|
|
58452
58667
|
return this.client;
|
|
58453
58668
|
}
|
|
@@ -60256,6 +60471,14 @@
|
|
|
60256
60471
|
}
|
|
60257
60472
|
}
|
|
60258
60473
|
|
|
60474
|
+
/**
|
|
60475
|
+
* Loads the OpenAI SDK (`openai`) on demand
|
|
60476
|
+
*
|
|
60477
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
60478
|
+
*
|
|
60479
|
+
* @private internal utility of `OpenAiCompatibleRequestManager`
|
|
60480
|
+
*/
|
|
60481
|
+
const loadOpenAiModule = createLazyModuleLoader(() => import('openai'));
|
|
60259
60482
|
/**
|
|
60260
60483
|
* Manages OpenAI-compatible client creation plus shared retry and rate-limit behavior.
|
|
60261
60484
|
*
|
|
@@ -60282,7 +60505,8 @@
|
|
|
60282
60505
|
timeout: API_REQUEST_TIMEOUT,
|
|
60283
60506
|
maxRetries: CONNECTION_RETRIES_LIMIT,
|
|
60284
60507
|
};
|
|
60285
|
-
|
|
60508
|
+
const { default: OpenAI } = await loadOpenAiModule();
|
|
60509
|
+
this.client = new OpenAI(enhancedOptions);
|
|
60286
60510
|
}
|
|
60287
60511
|
return this.client;
|
|
60288
60512
|
}
|
|
@@ -67995,8 +68219,9 @@
|
|
|
67995
68219
|
if (options.isVerbose) {
|
|
67996
68220
|
console.info(colors__default["default"].gray('Type "exit" or "quit" to end the chat.'));
|
|
67997
68221
|
}
|
|
68222
|
+
const { default: prompts } = await loadPromptsModule();
|
|
67998
68223
|
while (true) {
|
|
67999
|
-
const response = await
|
|
68224
|
+
const response = await prompts({
|
|
68000
68225
|
type: 'text',
|
|
68001
68226
|
name: 'userMessage',
|
|
68002
68227
|
message: 'User message',
|
|
@@ -69208,6 +69433,16 @@
|
|
|
69208
69433
|
}
|
|
69209
69434
|
}
|
|
69210
69435
|
|
|
69436
|
+
/**
|
|
69437
|
+
* Loads the OpenAI AgentKit SDK (`@openai/agents`) on demand
|
|
69438
|
+
*
|
|
69439
|
+
* Note: [🐌] The AgentKit SDK is one of the heaviest dependencies of Promptbook, loading it eagerly would slow down
|
|
69440
|
+
* every single run of the `ptbk` CLI utility even when no AgentKit agent is used
|
|
69441
|
+
*
|
|
69442
|
+
* @private internal utility of `@promptbook/openai`
|
|
69443
|
+
*/
|
|
69444
|
+
const loadOpenAiAgentsModule = createLazyModuleLoader(() => import('@openai/agents'));
|
|
69445
|
+
|
|
69211
69446
|
/**
|
|
69212
69447
|
* Constant for default model used for nested DeepSearch tool invocations.
|
|
69213
69448
|
*/
|
|
@@ -69261,11 +69496,12 @@
|
|
|
69261
69496
|
/**
|
|
69262
69497
|
* Builds the tool list for AgentKit, including hosted file search when applicable.
|
|
69263
69498
|
*/
|
|
69264
|
-
buildAgentKitTools(options) {
|
|
69499
|
+
async buildAgentKitTools(options) {
|
|
69265
69500
|
const { tools, vectorStoreId } = options;
|
|
69501
|
+
const { fileSearchTool, tool: agentKitTool } = await loadOpenAiAgentsModule();
|
|
69266
69502
|
const agentKitTools = [];
|
|
69267
69503
|
if (vectorStoreId) {
|
|
69268
|
-
agentKitTools.push(
|
|
69504
|
+
agentKitTools.push(fileSearchTool(vectorStoreId));
|
|
69269
69505
|
}
|
|
69270
69506
|
if (!tools || tools.length === 0) {
|
|
69271
69507
|
return agentKitTools;
|
|
@@ -69273,11 +69509,11 @@
|
|
|
69273
69509
|
let scriptTools = null;
|
|
69274
69510
|
for (const toolDefinition of tools) {
|
|
69275
69511
|
if (this.isDeepSearchToolDefinition(toolDefinition)) {
|
|
69276
|
-
agentKitTools.push(this.createDeepSearchAgentKitTool(toolDefinition));
|
|
69512
|
+
agentKitTools.push(await this.createDeepSearchAgentKitTool(toolDefinition));
|
|
69277
69513
|
continue;
|
|
69278
69514
|
}
|
|
69279
69515
|
scriptTools !== null && scriptTools !== void 0 ? scriptTools : (scriptTools = this.resolveScriptTools());
|
|
69280
|
-
agentKitTools.push(
|
|
69516
|
+
agentKitTools.push(agentKitTool({
|
|
69281
69517
|
name: toolDefinition.name,
|
|
69282
69518
|
description: toolDefinition.description,
|
|
69283
69519
|
parameters: this.normalizeAgentKitToolParameters(toolDefinition.parameters),
|
|
@@ -69484,12 +69720,13 @@
|
|
|
69484
69720
|
/**
|
|
69485
69721
|
* Creates the native Agent SDK tool used for `USE DEEPSEARCH`.
|
|
69486
69722
|
*/
|
|
69487
|
-
createDeepSearchAgentKitTool(toolDefinition) {
|
|
69488
|
-
const
|
|
69723
|
+
async createDeepSearchAgentKitTool(toolDefinition) {
|
|
69724
|
+
const { Agent: AgentFromKit, webSearchTool } = await loadOpenAiAgentsModule();
|
|
69725
|
+
const deepSearchAgent = new AgentFromKit({
|
|
69489
69726
|
name: 'DeepSearch',
|
|
69490
69727
|
model: DEFAULT_DEEP_SEARCH_MODEL_NAME,
|
|
69491
69728
|
instructions: this.createDeepSearchAgentInstructions(toolDefinition.description),
|
|
69492
|
-
tools: [
|
|
69729
|
+
tools: [webSearchTool({ searchContextSize: 'high' })],
|
|
69493
69730
|
});
|
|
69494
69731
|
return deepSearchAgent.asTool({
|
|
69495
69732
|
toolName: toolDefinition.name,
|
|
@@ -69698,8 +69935,9 @@
|
|
|
69698
69935
|
vectorStoreId,
|
|
69699
69936
|
});
|
|
69700
69937
|
}
|
|
69701
|
-
const
|
|
69702
|
-
const
|
|
69938
|
+
const { Agent: AgentFromKit } = await loadOpenAiAgentsModule();
|
|
69939
|
+
const agentKitTools = await this.buildAgentKitTools({ tools, vectorStoreId });
|
|
69940
|
+
const openAiAgentKitAgent = new AgentFromKit({
|
|
69703
69941
|
name,
|
|
69704
69942
|
model: this.agentKitModelName,
|
|
69705
69943
|
instructions: instructions || 'You are a helpful assistant.',
|
|
@@ -69744,7 +69982,8 @@
|
|
|
69744
69982
|
agentName: agentForRun.name,
|
|
69745
69983
|
input: inputItems,
|
|
69746
69984
|
};
|
|
69747
|
-
const
|
|
69985
|
+
const { run } = await loadOpenAiAgentsModule();
|
|
69986
|
+
const streamResult = await run(agentForRun, inputItems, {
|
|
69748
69987
|
stream: true,
|
|
69749
69988
|
maxTurns: 200,
|
|
69750
69989
|
context: {
|
|
@@ -69886,11 +70125,12 @@
|
|
|
69886
70125
|
* Ensures the AgentKit SDK is wired to the OpenAI client and API key.
|
|
69887
70126
|
*/
|
|
69888
70127
|
async ensureAgentKitDefaults() {
|
|
70128
|
+
const { setDefaultOpenAIClient, setDefaultOpenAIKey } = await loadOpenAiAgentsModule();
|
|
69889
70129
|
const client = await this.getClient();
|
|
69890
|
-
|
|
70130
|
+
setDefaultOpenAIClient(client);
|
|
69891
70131
|
const apiKey = this.agentKitOptions.apiKey;
|
|
69892
70132
|
if (apiKey && typeof apiKey === 'string') {
|
|
69893
|
-
|
|
70133
|
+
setDefaultOpenAIKey(apiKey);
|
|
69894
70134
|
}
|
|
69895
70135
|
}
|
|
69896
70136
|
/**
|
|
@@ -72218,6 +72458,66 @@
|
|
|
72218
72458
|
RemoteAgent: RemoteAgent
|
|
72219
72459
|
});
|
|
72220
72460
|
|
|
72461
|
+
/**
|
|
72462
|
+
* Git synchronization which leaves the repository completely untouched.
|
|
72463
|
+
*
|
|
72464
|
+
* Note: This is the default for every command and helper which supports the git synchronization.
|
|
72465
|
+
*/
|
|
72466
|
+
const DISABLED_CODER_GIT_SYNC_OPTIONS = Object.freeze({
|
|
72467
|
+
isCommitEnabled: false,
|
|
72468
|
+
isAutoPushEnabled: false,
|
|
72469
|
+
isAutoPullEnabled: false,
|
|
72470
|
+
});
|
|
72471
|
+
/**
|
|
72472
|
+
* Pulls the latest repository changes before a `ptbk coder` command changes the project.
|
|
72473
|
+
*/
|
|
72474
|
+
async function $pullCoderChanges(options) {
|
|
72475
|
+
const { gitSync, projectPath = process.cwd() } = options;
|
|
72476
|
+
if (!gitSync.isAutoPullEnabled) {
|
|
72477
|
+
return;
|
|
72478
|
+
}
|
|
72479
|
+
console.info(colors__default["default"].gray('Pulling the latest changes from the remote repository...'));
|
|
72480
|
+
await pullLatestChanges(projectPath);
|
|
72481
|
+
}
|
|
72482
|
+
/**
|
|
72483
|
+
* Commits - and when requested also pushes - the changes one `ptbk coder` command has just made.
|
|
72484
|
+
*
|
|
72485
|
+
* Note: A repository without any change is left alone instead of creating an empty commit.
|
|
72486
|
+
*/
|
|
72487
|
+
async function $commitCoderChanges(options) {
|
|
72488
|
+
const { gitSync, commitMessage, projectPath = process.cwd() } = options;
|
|
72489
|
+
if (!gitSync.isCommitEnabled) {
|
|
72490
|
+
return;
|
|
72491
|
+
}
|
|
72492
|
+
if (!(await hasChangesToCommit(projectPath))) {
|
|
72493
|
+
console.info(colors__default["default"].gray('Nothing to commit, the working tree is clean'));
|
|
72494
|
+
return;
|
|
72495
|
+
}
|
|
72496
|
+
await commitChanges(commitMessage, {
|
|
72497
|
+
projectPath,
|
|
72498
|
+
autoPush: gitSync.isAutoPushEnabled,
|
|
72499
|
+
});
|
|
72500
|
+
console.info(colors__default["default"].green(`✓ ${gitSync.isAutoPushEnabled ? 'Committed and pushed' : 'Committed'}: ${commitMessage}`));
|
|
72501
|
+
}
|
|
72502
|
+
/**
|
|
72503
|
+
* Checks whether the repository holds any change which can be committed.
|
|
72504
|
+
*/
|
|
72505
|
+
async function hasChangesToCommit(projectPath) {
|
|
72506
|
+
const gitStatus = await runGitCommand({
|
|
72507
|
+
command: 'git status --porcelain',
|
|
72508
|
+
cwd: projectPath,
|
|
72509
|
+
isVerbose: false,
|
|
72510
|
+
});
|
|
72511
|
+
return gitStatus.trim() !== '';
|
|
72512
|
+
}
|
|
72513
|
+
|
|
72514
|
+
var coderGitSync = /*#__PURE__*/Object.freeze({
|
|
72515
|
+
__proto__: null,
|
|
72516
|
+
DISABLED_CODER_GIT_SYNC_OPTIONS: DISABLED_CODER_GIT_SYNC_OPTIONS,
|
|
72517
|
+
$pullCoderChanges: $pullCoderChanges,
|
|
72518
|
+
$commitCoderChanges: $commitCoderChanges
|
|
72519
|
+
});
|
|
72520
|
+
|
|
72221
72521
|
/**
|
|
72222
72522
|
* Calculates the next available prompt numbering sequence for a month.
|
|
72223
72523
|
*/
|
|
@@ -72692,6 +72992,31 @@
|
|
|
72692
72992
|
}
|
|
72693
72993
|
// Note: [🟡] Code for repository script [normalizeRefactorCandidatePath](scripts/find-refactor-candidates/normalizeRefactorCandidatePath.ts) should never be published outside of `@promptbook/cli`
|
|
72694
72994
|
|
|
72995
|
+
/**
|
|
72996
|
+
* The TypeScript compiler API once it was loaded by `analyzeSourceFileForRefactorCandidate`
|
|
72997
|
+
*
|
|
72998
|
+
* Note: [🐌] `typescript` is a heavy package, it is loaded on demand so that it does not slow down every single run
|
|
72999
|
+
* of the `ptbk` CLI utility
|
|
73000
|
+
*
|
|
73001
|
+
* @private variable of analyzeSourceFileForRefactorCandidate
|
|
73002
|
+
*/
|
|
73003
|
+
let loadedTypescriptModule = null;
|
|
73004
|
+
/**
|
|
73005
|
+
* Returns the TypeScript compiler API which was already loaded for the structural analysis.
|
|
73006
|
+
*
|
|
73007
|
+
* @private function of analyzeSourceFileForRefactorCandidate
|
|
73008
|
+
*/
|
|
73009
|
+
function getLoadedTypescriptModule() {
|
|
73010
|
+
if (loadedTypescriptModule === null) {
|
|
73011
|
+
throw new UnexpectedError(spaceTrim(`
|
|
73012
|
+
The \`typescript\` module was not loaded yet.
|
|
73013
|
+
|
|
73014
|
+
Structural analysis helpers must be called only from \`analyzeSourceFileForRefactorCandidate\` which
|
|
73015
|
+
loads \`typescript\` lazily.
|
|
73016
|
+
`));
|
|
73017
|
+
}
|
|
73018
|
+
return loadedTypescriptModule;
|
|
73019
|
+
}
|
|
72695
73020
|
/**
|
|
72696
73021
|
* Resolves whether a source file should produce a refactor candidate entry.
|
|
72697
73022
|
*
|
|
@@ -72717,6 +73042,7 @@
|
|
|
72717
73042
|
}
|
|
72718
73043
|
}
|
|
72719
73044
|
if (STRUCTURAL_ANALYSIS_EXTENSIONS.includes(extension)) {
|
|
73045
|
+
loadedTypescriptModule !== null && loadedTypescriptModule !== void 0 ? loadedTypescriptModule : (loadedTypescriptModule = await getTypescriptModule());
|
|
72720
73046
|
const structureSummary = summarizeSourceFileStructure(content, extension, filePath);
|
|
72721
73047
|
if (structureSummary.entityCount > heuristics.maxEntityCountPerFile) {
|
|
72722
73048
|
reasons.push(`entities ${structureSummary.entityCount}/${heuristics.maxEntityCountPerFile}`);
|
|
@@ -72776,8 +73102,9 @@
|
|
|
72776
73102
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72777
73103
|
*/
|
|
72778
73104
|
function summarizeSourceFileStructure(content, extension, filePath) {
|
|
73105
|
+
const ts = getLoadedTypescriptModule();
|
|
72779
73106
|
const scriptKind = getScriptKindForExtension(extension);
|
|
72780
|
-
const sourceFile =
|
|
73107
|
+
const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true, scriptKind);
|
|
72781
73108
|
return {
|
|
72782
73109
|
entityCount: countEntitiesInSourceFile(sourceFile),
|
|
72783
73110
|
...summarizeFunctionsInSourceFile(sourceFile),
|
|
@@ -72789,25 +73116,26 @@
|
|
|
72789
73116
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72790
73117
|
*/
|
|
72791
73118
|
function countEntitiesInSourceFile(sourceFile) {
|
|
73119
|
+
const ts = getLoadedTypescriptModule();
|
|
72792
73120
|
let count = 0;
|
|
72793
73121
|
// Only count top-level declarations to avoid inflating with members or nested scopes.
|
|
72794
73122
|
for (const statement of sourceFile.statements) {
|
|
72795
|
-
if (
|
|
72796
|
-
|
|
72797
|
-
|
|
72798
|
-
|
|
72799
|
-
|
|
72800
|
-
|
|
73123
|
+
if (ts.isFunctionDeclaration(statement) ||
|
|
73124
|
+
ts.isClassDeclaration(statement) ||
|
|
73125
|
+
ts.isInterfaceDeclaration(statement) ||
|
|
73126
|
+
ts.isTypeAliasDeclaration(statement) ||
|
|
73127
|
+
ts.isEnumDeclaration(statement) ||
|
|
73128
|
+
ts.isModuleDeclaration(statement)) {
|
|
72801
73129
|
count += 1;
|
|
72802
73130
|
continue;
|
|
72803
73131
|
}
|
|
72804
|
-
if (
|
|
73132
|
+
if (ts.isVariableStatement(statement)) {
|
|
72805
73133
|
for (const declaration of statement.declarationList.declarations) {
|
|
72806
73134
|
const initializer = declaration.initializer;
|
|
72807
73135
|
if (initializer &&
|
|
72808
|
-
(
|
|
72809
|
-
|
|
72810
|
-
|
|
73136
|
+
(ts.isArrowFunction(initializer) ||
|
|
73137
|
+
ts.isFunctionExpression(initializer) ||
|
|
73138
|
+
ts.isClassExpression(initializer))) {
|
|
72811
73139
|
count += 1;
|
|
72812
73140
|
}
|
|
72813
73141
|
}
|
|
@@ -72821,6 +73149,7 @@
|
|
|
72821
73149
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72822
73150
|
*/
|
|
72823
73151
|
function summarizeFunctionsInSourceFile(sourceFile) {
|
|
73152
|
+
const ts = getLoadedTypescriptModule();
|
|
72824
73153
|
let functionCount = 0;
|
|
72825
73154
|
let maxFunctionComplexity = 0;
|
|
72826
73155
|
let mostComplexFunctionName = null;
|
|
@@ -72833,7 +73162,7 @@
|
|
|
72833
73162
|
mostComplexFunctionName = getFunctionDisplayName(node);
|
|
72834
73163
|
}
|
|
72835
73164
|
}
|
|
72836
|
-
|
|
73165
|
+
ts.forEachChild(node, visitNode);
|
|
72837
73166
|
};
|
|
72838
73167
|
visitNode(sourceFile);
|
|
72839
73168
|
return {
|
|
@@ -72848,14 +73177,15 @@
|
|
|
72848
73177
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72849
73178
|
*/
|
|
72850
73179
|
function isCountedFunctionLikeDeclaration(node) {
|
|
72851
|
-
|
|
72852
|
-
|
|
72853
|
-
|
|
72854
|
-
|
|
72855
|
-
|
|
73180
|
+
const ts = getLoadedTypescriptModule();
|
|
73181
|
+
if (ts.isFunctionDeclaration(node) ||
|
|
73182
|
+
ts.isMethodDeclaration(node) ||
|
|
73183
|
+
ts.isConstructorDeclaration(node) ||
|
|
73184
|
+
ts.isGetAccessorDeclaration(node) ||
|
|
73185
|
+
ts.isSetAccessorDeclaration(node)) {
|
|
72856
73186
|
return true;
|
|
72857
73187
|
}
|
|
72858
|
-
if (
|
|
73188
|
+
if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {
|
|
72859
73189
|
return isNamedFunctionExpression(node);
|
|
72860
73190
|
}
|
|
72861
73191
|
return false;
|
|
@@ -72866,8 +73196,9 @@
|
|
|
72866
73196
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72867
73197
|
*/
|
|
72868
73198
|
function isNamedFunctionExpression(node) {
|
|
73199
|
+
const ts = getLoadedTypescriptModule();
|
|
72869
73200
|
const parent = node.parent;
|
|
72870
|
-
return (
|
|
73201
|
+
return (ts.isVariableDeclaration(parent) || ts.isPropertyDeclaration(parent) || ts.isPropertyAssignment(parent));
|
|
72871
73202
|
}
|
|
72872
73203
|
/**
|
|
72873
73204
|
* Calculates a lightweight cyclomatic-complexity score for one function.
|
|
@@ -72878,6 +73209,7 @@
|
|
|
72878
73209
|
if (!functionNode.body) {
|
|
72879
73210
|
return 1;
|
|
72880
73211
|
}
|
|
73212
|
+
const ts = getLoadedTypescriptModule();
|
|
72881
73213
|
let complexity = 1;
|
|
72882
73214
|
const visitNode = (node) => {
|
|
72883
73215
|
if (node !== functionNode.body && isCountedFunctionLikeDeclaration(node)) {
|
|
@@ -72886,7 +73218,7 @@
|
|
|
72886
73218
|
if (isComplexityDecisionNode(node)) {
|
|
72887
73219
|
complexity += 1;
|
|
72888
73220
|
}
|
|
72889
|
-
|
|
73221
|
+
ts.forEachChild(node, visitNode);
|
|
72890
73222
|
};
|
|
72891
73223
|
visitNode(functionNode.body);
|
|
72892
73224
|
return complexity;
|
|
@@ -72897,22 +73229,23 @@
|
|
|
72897
73229
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72898
73230
|
*/
|
|
72899
73231
|
function isComplexityDecisionNode(node) {
|
|
72900
|
-
|
|
72901
|
-
|
|
72902
|
-
|
|
72903
|
-
|
|
72904
|
-
|
|
72905
|
-
|
|
72906
|
-
|
|
72907
|
-
|
|
72908
|
-
|
|
73232
|
+
const ts = getLoadedTypescriptModule();
|
|
73233
|
+
if (ts.isIfStatement(node) ||
|
|
73234
|
+
ts.isConditionalExpression(node) ||
|
|
73235
|
+
ts.isCatchClause(node) ||
|
|
73236
|
+
ts.isForStatement(node) ||
|
|
73237
|
+
ts.isForInStatement(node) ||
|
|
73238
|
+
ts.isForOfStatement(node) ||
|
|
73239
|
+
ts.isWhileStatement(node) ||
|
|
73240
|
+
ts.isDoStatement(node) ||
|
|
73241
|
+
ts.isCaseClause(node)) {
|
|
72909
73242
|
return true;
|
|
72910
73243
|
}
|
|
72911
|
-
if (
|
|
73244
|
+
if (ts.isBinaryExpression(node)) {
|
|
72912
73245
|
const operatorKind = node.operatorToken.kind;
|
|
72913
|
-
return (operatorKind ===
|
|
72914
|
-
operatorKind ===
|
|
72915
|
-
operatorKind ===
|
|
73246
|
+
return (operatorKind === ts.SyntaxKind.AmpersandAmpersandToken ||
|
|
73247
|
+
operatorKind === ts.SyntaxKind.BarBarToken ||
|
|
73248
|
+
operatorKind === ts.SyntaxKind.QuestionQuestionToken);
|
|
72916
73249
|
}
|
|
72917
73250
|
return false;
|
|
72918
73251
|
}
|
|
@@ -72922,27 +73255,28 @@
|
|
|
72922
73255
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72923
73256
|
*/
|
|
72924
73257
|
function getFunctionDisplayName(functionNode) {
|
|
72925
|
-
|
|
73258
|
+
const ts = getLoadedTypescriptModule();
|
|
73259
|
+
if (ts.isConstructorDeclaration(functionNode)) {
|
|
72926
73260
|
return 'constructor';
|
|
72927
73261
|
}
|
|
72928
|
-
if (
|
|
72929
|
-
|
|
72930
|
-
|
|
72931
|
-
|
|
73262
|
+
if (ts.isFunctionDeclaration(functionNode) ||
|
|
73263
|
+
ts.isMethodDeclaration(functionNode) ||
|
|
73264
|
+
ts.isGetAccessorDeclaration(functionNode) ||
|
|
73265
|
+
ts.isSetAccessorDeclaration(functionNode)) {
|
|
72932
73266
|
if (!functionNode.name) {
|
|
72933
73267
|
return null;
|
|
72934
73268
|
}
|
|
72935
73269
|
return getPropertyNameText(functionNode.name);
|
|
72936
73270
|
}
|
|
72937
|
-
if (
|
|
73271
|
+
if (ts.isArrowFunction(functionNode) || ts.isFunctionExpression(functionNode)) {
|
|
72938
73272
|
if (functionNode.name) {
|
|
72939
73273
|
return functionNode.name.text;
|
|
72940
73274
|
}
|
|
72941
73275
|
const parent = functionNode.parent;
|
|
72942
|
-
if (
|
|
73276
|
+
if (ts.isVariableDeclaration(parent)) {
|
|
72943
73277
|
return getBindingNameText(parent.name);
|
|
72944
73278
|
}
|
|
72945
|
-
if (
|
|
73279
|
+
if (ts.isPropertyDeclaration(parent) || ts.isPropertyAssignment(parent)) {
|
|
72946
73280
|
return getPropertyNameText(parent.name);
|
|
72947
73281
|
}
|
|
72948
73282
|
}
|
|
@@ -72954,7 +73288,8 @@
|
|
|
72954
73288
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72955
73289
|
*/
|
|
72956
73290
|
function getBindingNameText(name) {
|
|
72957
|
-
|
|
73291
|
+
const ts = getLoadedTypescriptModule();
|
|
73292
|
+
return ts.isIdentifier(name) ? name.text : null;
|
|
72958
73293
|
}
|
|
72959
73294
|
/**
|
|
72960
73295
|
* Resolves text for a property name while preserving computed names when necessary.
|
|
@@ -72962,7 +73297,8 @@
|
|
|
72962
73297
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72963
73298
|
*/
|
|
72964
73299
|
function getPropertyNameText(name) {
|
|
72965
|
-
|
|
73300
|
+
const ts = getLoadedTypescriptModule();
|
|
73301
|
+
if (ts.isIdentifier(name) || ts.isPrivateIdentifier(name) || ts.isStringLiteral(name) || ts.isNumericLiteral(name)) {
|
|
72966
73302
|
return name.text;
|
|
72967
73303
|
}
|
|
72968
73304
|
return name.getText();
|
|
@@ -72984,16 +73320,17 @@
|
|
|
72984
73320
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72985
73321
|
*/
|
|
72986
73322
|
function getScriptKindForExtension(extension) {
|
|
73323
|
+
const ts = getLoadedTypescriptModule();
|
|
72987
73324
|
if (extension === '.tsx') {
|
|
72988
|
-
return
|
|
73325
|
+
return ts.ScriptKind.TSX;
|
|
72989
73326
|
}
|
|
72990
73327
|
if (extension === '.jsx') {
|
|
72991
|
-
return
|
|
73328
|
+
return ts.ScriptKind.JSX;
|
|
72992
73329
|
}
|
|
72993
73330
|
if (extension === '.js') {
|
|
72994
|
-
return
|
|
73331
|
+
return ts.ScriptKind.JS;
|
|
72995
73332
|
}
|
|
72996
|
-
return
|
|
73333
|
+
return ts.ScriptKind.TS;
|
|
72997
73334
|
}
|
|
72998
73335
|
/**
|
|
72999
73336
|
* Normalizes an absolute path for consistent comparisons.
|
|
@@ -73593,6 +73930,41 @@
|
|
|
73593
73930
|
isPromptInPriorityFilter(prompt.section, priorityFilter));
|
|
73594
73931
|
}
|
|
73595
73932
|
|
|
73933
|
+
/**
|
|
73934
|
+
* Checks whether a prompt is unrestricted or matches the selected harness/model.
|
|
73935
|
+
*
|
|
73936
|
+
* A prompt status line can contain one or more backtick-delimited model or harness
|
|
73937
|
+
* names. Matching is intentionally based on normalized substrings so a token such as
|
|
73938
|
+
* `gpt` selects any `gpt-*` model and `opus` selects a `claude-opus-*` model.
|
|
73939
|
+
*/
|
|
73940
|
+
function isPromptCompatibleWithRunner(file, section, promptRunnerIdentity) {
|
|
73941
|
+
if (promptRunnerIdentity === undefined) {
|
|
73942
|
+
return true;
|
|
73943
|
+
}
|
|
73944
|
+
const statusLine = section.statusLineIndex === undefined ? undefined : file.lines[section.statusLineIndex];
|
|
73945
|
+
const requiredRunnerTokens = statusLine === undefined ? [] : extractPromptRunnerTokens(statusLine);
|
|
73946
|
+
if (requiredRunnerTokens.length === 0) {
|
|
73947
|
+
return true;
|
|
73948
|
+
}
|
|
73949
|
+
const normalizedRunnerNames = [promptRunnerIdentity.harnessName, promptRunnerIdentity.modelName]
|
|
73950
|
+
.filter((name) => name !== undefined && name.trim() !== '')
|
|
73951
|
+
.map((name) => normalizeToKebabCase(name))
|
|
73952
|
+
.filter((name) => name !== '');
|
|
73953
|
+
return requiredRunnerTokens.some((requiredRunnerToken) => {
|
|
73954
|
+
const normalizedRequiredRunnerToken = normalizeToKebabCase(requiredRunnerToken);
|
|
73955
|
+
return (normalizedRequiredRunnerToken !== '' &&
|
|
73956
|
+
normalizedRunnerNames.some((normalizedRunnerName) => normalizedRunnerName.includes(normalizedRequiredRunnerToken)));
|
|
73957
|
+
});
|
|
73958
|
+
}
|
|
73959
|
+
/**
|
|
73960
|
+
* Extracts model and harness tokens from a prompt status line.
|
|
73961
|
+
*/
|
|
73962
|
+
function extractPromptRunnerTokens(statusLine) {
|
|
73963
|
+
return Array.from(statusLine.matchAll(/`([^`]+)`/gu))
|
|
73964
|
+
.map((match) => { var _a, _b; return (_b = (_a = match[1]) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : ''; })
|
|
73965
|
+
.filter((token) => token !== '');
|
|
73966
|
+
}
|
|
73967
|
+
|
|
73596
73968
|
/**
|
|
73597
73969
|
* Parses a prompt markdown file into sections and metadata.
|
|
73598
73970
|
*/
|
|
@@ -73640,11 +74012,11 @@
|
|
|
73640
74012
|
};
|
|
73641
74013
|
}
|
|
73642
74014
|
/**
|
|
73643
|
-
* Parses a status line like "[ ] !!"
|
|
74015
|
+
* Parses a status line like "[ ] !!", "[ ] use `gpt` !!!!!" or "[-]" into status and priority.
|
|
73644
74016
|
* For [x] done and [!] failed prompts, allow metadata after the status marker.
|
|
73645
74017
|
*/
|
|
73646
74018
|
function parseStatusLine(line) {
|
|
73647
|
-
var _a, _b, _c, _d
|
|
74019
|
+
var _a, _b, _c, _d;
|
|
73648
74020
|
// For done prompts [x], allow any content after (for cost/time metadata)
|
|
73649
74021
|
const doneMatch = line.match(/^\[(?<status>[xX])\]/);
|
|
73650
74022
|
if (doneMatch) {
|
|
@@ -73655,21 +74027,23 @@
|
|
|
73655
74027
|
if (failedMatch) {
|
|
73656
74028
|
return { status: 'failed', priority: 0 };
|
|
73657
74029
|
}
|
|
73658
|
-
// For
|
|
73659
|
-
|
|
73660
|
-
|
|
73661
|
-
return undefined;
|
|
74030
|
+
// For not-ready [-], keep the historical clean-line syntax.
|
|
74031
|
+
if (/^\[-\]\s*!*\s*$/u.test(line)) {
|
|
74032
|
+
return { status: 'not-ready', priority: 0 };
|
|
73662
74033
|
}
|
|
73663
|
-
|
|
73664
|
-
|
|
73665
|
-
|
|
73666
|
-
|
|
74034
|
+
// Todo [ ] may contain backtick-delimited model/harness tokens and priority markers
|
|
74035
|
+
// before or after those tokens. Other trailing text remains an invalid status line.
|
|
74036
|
+
const todoMatch = line.match(/^\[ \](?<details>.*)$/u);
|
|
74037
|
+
if (!todoMatch) {
|
|
74038
|
+
return undefined;
|
|
73667
74039
|
}
|
|
73668
|
-
|
|
73669
|
-
|
|
74040
|
+
const details = (_b = (_a = todoMatch.groups) === null || _a === void 0 ? void 0 : _a.details) !== null && _b !== void 0 ? _b : '';
|
|
74041
|
+
const isPriorityOnly = /^[!\s]*$/u.test(details);
|
|
74042
|
+
const hasPromptRunnerTokens = extractPromptRunnerTokens(line).length > 0;
|
|
74043
|
+
if (details.trim() !== '' && !isPriorityOnly && !hasPromptRunnerTokens) {
|
|
74044
|
+
return undefined;
|
|
73670
74045
|
}
|
|
73671
|
-
|
|
73672
|
-
return { status, priority };
|
|
74046
|
+
return { status: 'todo', priority: (_d = (_c = details.match(/!/gu)) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0 };
|
|
73673
74047
|
}
|
|
73674
74048
|
/**
|
|
73675
74049
|
* Finds the first non-empty line index between two bounds.
|
|
@@ -73805,6 +74179,243 @@
|
|
|
73805
74179
|
findUnwrittenPrompts: findUnwrittenPrompts
|
|
73806
74180
|
});
|
|
73807
74181
|
|
|
74182
|
+
/**
|
|
74183
|
+
* Builds a normalized temporary shell script path for prompt runners.
|
|
74184
|
+
*/
|
|
74185
|
+
function buildTemporaryPromptScriptPath(options) {
|
|
74186
|
+
const sourceFileName = path.basename(options.sourceFileName);
|
|
74187
|
+
const scriptFileName = `${sourceFileName.replace(/\.[^.]+$/u, '')}${options.suffix || ''}.sh`;
|
|
74188
|
+
return resolvePromptbookTemporaryPath(options.projectPath, options.scriptDirectoryName, scriptFileName);
|
|
74189
|
+
}
|
|
74190
|
+
|
|
74191
|
+
/**
|
|
74192
|
+
* Marker the pinged harness is asked to prefix its answer with, so the reply can be recognized
|
|
74193
|
+
* in the raw runner output of every supported harness.
|
|
74194
|
+
*
|
|
74195
|
+
* Note: The marker must stay free of regular-expression metacharacters, because
|
|
74196
|
+
* `extractCoderPingAnswer` builds its pattern from it.
|
|
74197
|
+
*/
|
|
74198
|
+
const CODER_PING_ANSWER_MARKER = 'PTBK-CODER-PING-ANSWER';
|
|
74199
|
+
/**
|
|
74200
|
+
* First factor of the dummy multiplication the pinged harness is asked to compute.
|
|
74201
|
+
*/
|
|
74202
|
+
const CODER_PING_FIRST_FACTOR = 6;
|
|
74203
|
+
/**
|
|
74204
|
+
* Second factor of the dummy multiplication the pinged harness is asked to compute.
|
|
74205
|
+
*/
|
|
74206
|
+
const CODER_PING_SECOND_FACTOR = 7;
|
|
74207
|
+
/**
|
|
74208
|
+
* Answer a working harness and model returns for the dummy work of `ptbk coder ping`.
|
|
74209
|
+
*/
|
|
74210
|
+
const CODER_PING_EXPECTED_ANSWER = String(CODER_PING_FIRST_FACTOR * CODER_PING_SECOND_FACTOR);
|
|
74211
|
+
/**
|
|
74212
|
+
* Builds the dummy prompt sent by `ptbk coder ping`.
|
|
74213
|
+
*
|
|
74214
|
+
* The work is intentionally the smallest possible one that still reaches the model: it spends a
|
|
74215
|
+
* negligible amount of the harness quota, it needs no tool and it explicitly forbids touching the
|
|
74216
|
+
* project, so a ping leaves the project exactly as it was.
|
|
74217
|
+
*/
|
|
74218
|
+
function buildCoderPingPrompt() {
|
|
74219
|
+
return spaceTrim(`
|
|
74220
|
+
# Promptbook connection check
|
|
74221
|
+
|
|
74222
|
+
This is an automated \`ptbk coder ping\` connection check, not a coding task.
|
|
74223
|
+
|
|
74224
|
+
Do exactly this and nothing else:
|
|
74225
|
+
|
|
74226
|
+
1. Multiply \`${CODER_PING_FIRST_FACTOR}\` by \`${CODER_PING_SECOND_FACTOR}\`.
|
|
74227
|
+
2. Answer with one single line \`${CODER_PING_ANSWER_MARKER}: <result>\` where \`<result>\` is the number you computed.
|
|
74228
|
+
|
|
74229
|
+
Rules:
|
|
74230
|
+
|
|
74231
|
+
- Do not read, create, change, move or delete any file.
|
|
74232
|
+
- Do not run any command and do not use any tool.
|
|
74233
|
+
- Do not write anything except the single answer line.
|
|
74234
|
+
`);
|
|
74235
|
+
}
|
|
74236
|
+
|
|
74237
|
+
/**
|
|
74238
|
+
* Pattern matching one answer line produced by the pinged harness.
|
|
74239
|
+
*
|
|
74240
|
+
* The captured answer deliberately stops at a quote, a backslash or a line break, so an answer
|
|
74241
|
+
* embedded in a JSON event stream — as produced by Claude Code, Opencode or Codex `--json` — is
|
|
74242
|
+
* captured without the surrounding JSON.
|
|
74243
|
+
*/
|
|
74244
|
+
const CODER_PING_ANSWER_PATTERN = new RegExp(`${CODER_PING_ANSWER_MARKER}\\s*:[ \\t]*([^\\r\\n"\\\\]*)`, 'gu');
|
|
74245
|
+
/**
|
|
74246
|
+
* Extracts the answer of a pinged harness from the runtime log of its runner shell.
|
|
74247
|
+
*
|
|
74248
|
+
* Only the raw output of the last execution is searched, so the answer marker contained in the
|
|
74249
|
+
* prompt of the raw input is never mistaken for the answer of the harness.
|
|
74250
|
+
*
|
|
74251
|
+
* @returns The answer of the harness, or `null` when the harness produced no recognizable answer
|
|
74252
|
+
*/
|
|
74253
|
+
function extractCoderPingAnswer(runtimeLog) {
|
|
74254
|
+
var _a;
|
|
74255
|
+
const rawOutput = runtimeLog.split(SCRIPT_EXECUTION_LOG_RAW_OUTPUT_MARKER).pop();
|
|
74256
|
+
if (rawOutput === undefined) {
|
|
74257
|
+
return null;
|
|
74258
|
+
}
|
|
74259
|
+
// Note: The last answer wins because harnesses which stream partial messages repeat the growing answer line
|
|
74260
|
+
const answers = Array.from(rawOutput.matchAll(CODER_PING_ANSWER_PATTERN))
|
|
74261
|
+
.map((match) => (match[1] || '').trim())
|
|
74262
|
+
.filter((answer) => answer !== '');
|
|
74263
|
+
return (_a = answers[answers.length - 1]) !== null && _a !== void 0 ? _a : null;
|
|
74264
|
+
}
|
|
74265
|
+
|
|
74266
|
+
/**
|
|
74267
|
+
* Temporary subdirectory used for the `ptbk coder ping` runner shell script and its runtime log.
|
|
74268
|
+
*/
|
|
74269
|
+
const CODER_PING_SCRIPT_DIRECTORY_NAME = 'coder-ping';
|
|
74270
|
+
/**
|
|
74271
|
+
* Base name of the temporary `ptbk coder ping` runner shell script.
|
|
74272
|
+
*/
|
|
74273
|
+
const CODER_PING_SCRIPT_SOURCE_NAME = 'ping';
|
|
74274
|
+
/**
|
|
74275
|
+
* Sends one tiny dummy prompt through the selected harness and model and measures the round trip.
|
|
74276
|
+
*
|
|
74277
|
+
* The ping reuses the very same runner the coding queue uses, so it really exercises the configured
|
|
74278
|
+
* harness, model, thinking level and authentication — including the retry behavior on rate limits.
|
|
74279
|
+
* Both temporary artifacts it creates are removed again, so the project is left as it was.
|
|
74280
|
+
*/
|
|
74281
|
+
async function pingCoderHarness(options) {
|
|
74282
|
+
const projectPath = options.projectPath || process.cwd();
|
|
74283
|
+
const { runner, runnerMetadata } = resolvePromptRunner(options);
|
|
74284
|
+
const scriptPath = buildTemporaryPromptScriptPath({
|
|
74285
|
+
projectPath,
|
|
74286
|
+
scriptDirectoryName: CODER_PING_SCRIPT_DIRECTORY_NAME,
|
|
74287
|
+
sourceFileName: CODER_PING_SCRIPT_SOURCE_NAME,
|
|
74288
|
+
});
|
|
74289
|
+
const startedTimeMs = Date.now();
|
|
74290
|
+
const { answer, usage, loginMethod } = await withPromptRuntimeLog(scriptPath, async (logPath) => {
|
|
74291
|
+
var _a;
|
|
74292
|
+
const result = await runner.runPrompt({
|
|
74293
|
+
prompt: buildCoderPingPrompt(),
|
|
74294
|
+
scriptPath,
|
|
74295
|
+
projectPath,
|
|
74296
|
+
logPath,
|
|
74297
|
+
shouldPrintLiveOutput: (_a = options.shouldPrintLiveOutput) !== null && _a !== void 0 ? _a : false,
|
|
74298
|
+
preserveArtifactsOnSuccess: false,
|
|
74299
|
+
});
|
|
74300
|
+
return { ...result, answer: extractCoderPingAnswer(await readRuntimeLog(logPath)) };
|
|
74301
|
+
}, { preserveArtifactsOnSuccess: false });
|
|
74302
|
+
return {
|
|
74303
|
+
runnerName: runnerMetadata.runnerName,
|
|
74304
|
+
modelName: runnerMetadata.modelName,
|
|
74305
|
+
thinkingLevel: options.thinkingLevel,
|
|
74306
|
+
answer,
|
|
74307
|
+
isAnswerCorrect: answer === CODER_PING_EXPECTED_ANSWER,
|
|
74308
|
+
durationMs: Date.now() - startedTimeMs,
|
|
74309
|
+
usage,
|
|
74310
|
+
loginMethod,
|
|
74311
|
+
};
|
|
74312
|
+
}
|
|
74313
|
+
/**
|
|
74314
|
+
* Reads the runtime log of the finished ping, treating an unreadable log as no output at all.
|
|
74315
|
+
*/
|
|
74316
|
+
async function readRuntimeLog(logPath) {
|
|
74317
|
+
return await promises.readFile(logPath, 'utf-8').catch(() => '');
|
|
74318
|
+
}
|
|
74319
|
+
|
|
74320
|
+
var pingCoderHarness$1 = /*#__PURE__*/Object.freeze({
|
|
74321
|
+
__proto__: null,
|
|
74322
|
+
pingCoderHarness: pingCoderHarness
|
|
74323
|
+
});
|
|
74324
|
+
|
|
74325
|
+
/**
|
|
74326
|
+
* Formats usage price for display in prompt status lines and task details.
|
|
74327
|
+
* Examples:
|
|
74328
|
+
* - "$0.12" (certain)
|
|
74329
|
+
* - "~$3.05" (uncertain)
|
|
74330
|
+
* - "$0.00" (zero cost)
|
|
74331
|
+
* - "<$0.01" (tiny non-zero cost)
|
|
74332
|
+
*
|
|
74333
|
+
* @private internal utility of the prompt runners and the Agents Server task details
|
|
74334
|
+
*/
|
|
74335
|
+
function formatUsagePrice(usage) {
|
|
74336
|
+
const price = usage.price.value;
|
|
74337
|
+
const isUncertain = usage.price.isUncertain === true;
|
|
74338
|
+
const prefix = isUncertain ? '~' : '';
|
|
74339
|
+
if (price === 0) {
|
|
74340
|
+
return `${prefix}$0.00`;
|
|
74341
|
+
}
|
|
74342
|
+
if (price < 0.01) {
|
|
74343
|
+
return `${prefix}<$0.01`;
|
|
74344
|
+
}
|
|
74345
|
+
if (price < 1) {
|
|
74346
|
+
return `${prefix}$${price.toFixed(4)}`;
|
|
74347
|
+
}
|
|
74348
|
+
return `${prefix}$${price.toFixed(2)}`;
|
|
74349
|
+
}
|
|
74350
|
+
|
|
74351
|
+
/**
|
|
74352
|
+
* Formats runner details for prompt status lines.
|
|
74353
|
+
*/
|
|
74354
|
+
function formatRunnerSignature(runnerName, modelName, thinkingLevel) {
|
|
74355
|
+
const normalizedRunner = runnerName === null || runnerName === void 0 ? void 0 : runnerName.trim();
|
|
74356
|
+
const normalizedModel = modelName === null || modelName === void 0 ? void 0 : modelName.trim();
|
|
74357
|
+
const thinkingLevelSuffix = thinkingLevel ? ` thinking \`${thinkingLevel}\`` : '';
|
|
74358
|
+
if (!normalizedRunner && !normalizedModel) {
|
|
74359
|
+
return 'unknown';
|
|
74360
|
+
}
|
|
74361
|
+
const runnerLabel = normalizedRunner || 'unknown';
|
|
74362
|
+
if (!normalizedModel) {
|
|
74363
|
+
return `${runnerLabel}${thinkingLevelSuffix}`;
|
|
74364
|
+
}
|
|
74365
|
+
return `${runnerLabel} \`${normalizedModel}\`${thinkingLevelSuffix}`;
|
|
74366
|
+
}
|
|
74367
|
+
|
|
74368
|
+
/**
|
|
74369
|
+
* Prints the compact summary of one finished `ptbk coder ping`.
|
|
74370
|
+
*/
|
|
74371
|
+
function printCoderPingResult(result) {
|
|
74372
|
+
const runnerSignature = formatRunnerSignature(result.runnerName, result.modelName, result.thinkingLevel);
|
|
74373
|
+
const loginMethodLabel = formatCodexLoginMethod(result.loginMethod);
|
|
74374
|
+
const loginMethodSuffix = loginMethodLabel === undefined ? '' : ` (${loginMethodLabel})`;
|
|
74375
|
+
console.info(colors__default["default"].green(`🏓 ${runnerSignature}${loginMethodSuffix} answered in ${formatCoderPingResponseTime(result.durationMs)}`));
|
|
74376
|
+
console.info(colors__default["default"].gray(` Answer: ${formatCoderPingAnswer(result)}`));
|
|
74377
|
+
console.info(colors__default["default"].gray(` Usage: ${formatCoderPingUsage(result.usage)}`));
|
|
74378
|
+
}
|
|
74379
|
+
/**
|
|
74380
|
+
* Formats the measured round-trip time, keeping the sub-second precision a response time needs.
|
|
74381
|
+
*/
|
|
74382
|
+
function formatCoderPingResponseTime(durationMs) {
|
|
74383
|
+
return `${(durationMs / 1000).toFixed(2)}s`;
|
|
74384
|
+
}
|
|
74385
|
+
/**
|
|
74386
|
+
* Formats the answer of the pinged harness together with what was expected from it.
|
|
74387
|
+
*/
|
|
74388
|
+
function formatCoderPingAnswer(result) {
|
|
74389
|
+
if (result.answer === null) {
|
|
74390
|
+
return `Reached, but the answer line was missing from the output (expected \`${CODER_PING_EXPECTED_ANSWER}\`)`;
|
|
74391
|
+
}
|
|
74392
|
+
if (result.isAnswerCorrect) {
|
|
74393
|
+
return result.answer;
|
|
74394
|
+
}
|
|
74395
|
+
return `${result.answer} (expected \`${CODER_PING_EXPECTED_ANSWER}\`)`;
|
|
74396
|
+
}
|
|
74397
|
+
/**
|
|
74398
|
+
* Formats the resources the pinged harness reported for the dummy work.
|
|
74399
|
+
*/
|
|
74400
|
+
function formatCoderPingUsage(usage) {
|
|
74401
|
+
return [
|
|
74402
|
+
formatUsagePrice(usage),
|
|
74403
|
+
`${formatUncertainCount(usage.input.tokensCount)} input tokens`,
|
|
74404
|
+
`${formatUncertainCount(usage.output.tokensCount)} output tokens`,
|
|
74405
|
+
].join(', ');
|
|
74406
|
+
}
|
|
74407
|
+
/**
|
|
74408
|
+
* Formats one counted usage value, marking an estimated count with a leading `~`.
|
|
74409
|
+
*/
|
|
74410
|
+
function formatUncertainCount(count) {
|
|
74411
|
+
return `${count.isUncertain === true ? '~' : ''}${Math.round(count.value)}`;
|
|
74412
|
+
}
|
|
74413
|
+
|
|
74414
|
+
var printCoderPingResult$1 = /*#__PURE__*/Object.freeze({
|
|
74415
|
+
__proto__: null,
|
|
74416
|
+
printCoderPingResult: printCoderPingResult
|
|
74417
|
+
});
|
|
74418
|
+
|
|
73808
74419
|
/**
|
|
73809
74420
|
* Default wait duration applied before retrying a failed prompt round.
|
|
73810
74421
|
*/
|
|
@@ -73812,7 +74423,7 @@
|
|
|
73812
74423
|
/**
|
|
73813
74424
|
* CLI usage text for this script.
|
|
73814
74425
|
*/
|
|
73815
|
-
const USAGE = 'Usage: run-codex-prompts [--dry-run] [--harness <harness-name>] [--model <model>] [--context <context-or-file>] [--test <test-command...>] [--preserve-logs] [--isolate] [--no-ui] [--thinking-level <thinking-level>] [--priority <minimum-priority>] [--min-priority <minimum-priority>] [--max-priority <maximum-priority>] [--limit <run-count>] [--allow-credits] [--auto-migrate] [--allow-destructive-auto-migrate] [--wait-after-prompt <duration>] [--wait-between-prompts <duration>] [--wait-after-error <duration>] [--no-auto] [--no-commit] [--ignore-git-changes] [--no-normalize-line-endings] [--auto-push] [--auto-pull]';
|
|
74426
|
+
const USAGE = 'Usage: run-codex-prompts [--dry-run] [--harness <harness-name>] [--model <model>] [--context <context-or-file>] [--test <test-command...>] [--test-before <no|yes-and-fail|yes-and-fix>] [--preserve-logs] [--isolate] [--no-ui] [--thinking-level <thinking-level>] [--priority <minimum-priority>] [--min-priority <minimum-priority>] [--max-priority <maximum-priority>] [--limit <run-count>] [--allow-credits] [--auto-migrate] [--allow-destructive-auto-migrate] [--wait-after-prompt <duration>] [--wait-between-prompts <duration>] [--wait-after-error <duration>] [--no-auto] [--no-commit] [--ignore-git-changes] [--no-normalize-line-endings] [--auto-push] [--auto-pull]';
|
|
73816
74427
|
/**
|
|
73817
74428
|
* Top-level flags supported by this command.
|
|
73818
74429
|
*/
|
|
@@ -73822,6 +74433,7 @@
|
|
|
73822
74433
|
'--model',
|
|
73823
74434
|
'--context',
|
|
73824
74435
|
'--test',
|
|
74436
|
+
'--test-before',
|
|
73825
74437
|
'--preserve-logs',
|
|
73826
74438
|
'--isolate',
|
|
73827
74439
|
'--no-ui',
|
|
@@ -73860,6 +74472,8 @@
|
|
|
73860
74472
|
const context = readOptionValue(args, '--context');
|
|
73861
74473
|
const hasTestCommandFlag = args.includes('--test');
|
|
73862
74474
|
const testCommand = readVariadicOptionValue(args, '--test');
|
|
74475
|
+
const hasTestBeforeFlag = args.includes('--test-before');
|
|
74476
|
+
const testBefore = parseTestBeforeOption(readOptionValue(args, '--test-before'), hasTestBeforeFlag);
|
|
73863
74477
|
const preserveLogs = args.includes('--preserve-logs');
|
|
73864
74478
|
const isIsolated = args.includes('--isolate');
|
|
73865
74479
|
const noUi = args.includes('--no-ui');
|
|
@@ -73932,6 +74546,7 @@
|
|
|
73932
74546
|
model,
|
|
73933
74547
|
context,
|
|
73934
74548
|
testCommand,
|
|
74549
|
+
testBefore,
|
|
73935
74550
|
thinkingLevel,
|
|
73936
74551
|
priority: minimumPriority !== null && minimumPriority !== void 0 ? minimumPriority : 0,
|
|
73937
74552
|
minimumPriority,
|
|
@@ -73940,6 +74555,21 @@
|
|
|
73940
74555
|
limit,
|
|
73941
74556
|
};
|
|
73942
74557
|
}
|
|
74558
|
+
/**
|
|
74559
|
+
* Parses and validates the optional pre-coding verification mode.
|
|
74560
|
+
*/
|
|
74561
|
+
function parseTestBeforeOption(value, hasTestBeforeFlag) {
|
|
74562
|
+
if (value === undefined) {
|
|
74563
|
+
if (hasTestBeforeFlag) {
|
|
74564
|
+
exitWithUsageError(`Missing value for --test-before. Use one of: ${TEST_BEFORE_MODE_VALUES.join(', ')}.`);
|
|
74565
|
+
}
|
|
74566
|
+
return 'no';
|
|
74567
|
+
}
|
|
74568
|
+
if (!isTestBeforeMode(value)) {
|
|
74569
|
+
exitWithUsageError(`Invalid value for --test-before: "${value}". Use one of: ${TEST_BEFORE_MODE_VALUES.join(', ')}.`);
|
|
74570
|
+
}
|
|
74571
|
+
return value;
|
|
74572
|
+
}
|
|
73943
74573
|
/**
|
|
73944
74574
|
* Reads a duration-typed CLI flag, applying the provided default when the flag is absent.
|
|
73945
74575
|
*/
|
|
@@ -75698,6 +76328,14 @@
|
|
|
75698
76328
|
.filter((statement) => statement !== '');
|
|
75699
76329
|
}
|
|
75700
76330
|
|
|
76331
|
+
/**
|
|
76332
|
+
* Loads the PostgreSQL client (`pg`) on demand
|
|
76333
|
+
*
|
|
76334
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
76335
|
+
*
|
|
76336
|
+
* @private function of runAutoMigrateTestingServers
|
|
76337
|
+
*/
|
|
76338
|
+
const loadPostgresModule = createLazyModuleLoader(() => import('pg'));
|
|
75701
76339
|
/**
|
|
75702
76340
|
* Migration targets for testing servers that should be migrated by coding-script auto-migration.
|
|
75703
76341
|
*/
|
|
@@ -75775,7 +76413,8 @@
|
|
|
75775
76413
|
* @returns Pending migration files grouped by prefix.
|
|
75776
76414
|
*/
|
|
75777
76415
|
async function listPendingMigrationsByPrefix(options) {
|
|
75778
|
-
const
|
|
76416
|
+
const { Client } = await loadPostgresModule();
|
|
76417
|
+
const client = new Client({
|
|
75779
76418
|
connectionString: options.connectionString,
|
|
75780
76419
|
ssl: { rejectUnauthorized: false },
|
|
75781
76420
|
});
|
|
@@ -75932,15 +76571,6 @@
|
|
|
75932
76571
|
return lines.join(file.eol);
|
|
75933
76572
|
}
|
|
75934
76573
|
|
|
75935
|
-
/**
|
|
75936
|
-
* Builds a normalized temporary shell script path for prompt runners.
|
|
75937
|
-
*/
|
|
75938
|
-
function buildTemporaryPromptScriptPath(options) {
|
|
75939
|
-
const sourceFileName = path.basename(options.sourceFileName);
|
|
75940
|
-
const scriptFileName = `${sourceFileName.replace(/\.[^.]+$/u, '')}${options.suffix || ''}.sh`;
|
|
75941
|
-
return resolvePromptbookTemporaryPath(options.projectPath, options.scriptDirectoryName, scriptFileName);
|
|
75942
|
-
}
|
|
75943
|
-
|
|
75944
76574
|
/**
|
|
75945
76575
|
* Builds the suffix which disambiguates one prompt section inside its prompt file.
|
|
75946
76576
|
*
|
|
@@ -75967,32 +76597,6 @@
|
|
|
75967
76597
|
});
|
|
75968
76598
|
}
|
|
75969
76599
|
|
|
75970
|
-
/**
|
|
75971
|
-
* Formats usage price for display in prompt status lines and task details.
|
|
75972
|
-
* Examples:
|
|
75973
|
-
* - "$0.12" (certain)
|
|
75974
|
-
* - "~$3.05" (uncertain)
|
|
75975
|
-
* - "$0.00" (zero cost)
|
|
75976
|
-
* - "<$0.01" (tiny non-zero cost)
|
|
75977
|
-
*
|
|
75978
|
-
* @private internal utility of the prompt runners and the Agents Server task details
|
|
75979
|
-
*/
|
|
75980
|
-
function formatUsagePrice(usage) {
|
|
75981
|
-
const price = usage.price.value;
|
|
75982
|
-
const isUncertain = usage.price.isUncertain === true;
|
|
75983
|
-
const prefix = isUncertain ? '~' : '';
|
|
75984
|
-
if (price === 0) {
|
|
75985
|
-
return `${prefix}$0.00`;
|
|
75986
|
-
}
|
|
75987
|
-
if (price < 0.01) {
|
|
75988
|
-
return `${prefix}<$0.01`;
|
|
75989
|
-
}
|
|
75990
|
-
if (price < 1) {
|
|
75991
|
-
return `${prefix}$${price.toFixed(4)}`;
|
|
75992
|
-
}
|
|
75993
|
-
return `${prefix}$${price.toFixed(2)}`;
|
|
75994
|
-
}
|
|
75995
|
-
|
|
75996
76600
|
/**
|
|
75997
76601
|
* Human-readable labels for each coder run step kind shown in prompt status lines.
|
|
75998
76602
|
*/
|
|
@@ -76038,20 +76642,13 @@
|
|
|
76038
76642
|
}
|
|
76039
76643
|
|
|
76040
76644
|
/**
|
|
76041
|
-
*
|
|
76645
|
+
* Replaces the complete todo status line while preserving its indentation.
|
|
76646
|
+
*
|
|
76647
|
+
* The complete line is replaced because a todo status can contain a required
|
|
76648
|
+
* model/harness token in addition to priority markers.
|
|
76042
76649
|
*/
|
|
76043
|
-
function
|
|
76044
|
-
|
|
76045
|
-
const normalizedModel = modelName === null || modelName === void 0 ? void 0 : modelName.trim();
|
|
76046
|
-
const thinkingLevelSuffix = thinkingLevel ? ` thinking \`${thinkingLevel}\`` : '';
|
|
76047
|
-
if (!normalizedRunner && !normalizedModel) {
|
|
76048
|
-
return 'unknown';
|
|
76049
|
-
}
|
|
76050
|
-
const runnerLabel = normalizedRunner || 'unknown';
|
|
76051
|
-
if (!normalizedModel) {
|
|
76052
|
-
return `${runnerLabel}${thinkingLevelSuffix}`;
|
|
76053
|
-
}
|
|
76054
|
-
return `${runnerLabel} \`${normalizedModel}\`${thinkingLevelSuffix}`;
|
|
76650
|
+
function replacePromptTodoStatusLine(line, replacementStatusLine) {
|
|
76651
|
+
return line.replace(/^(?<indentation>\s*)\[\s*\].*$/u, `$<indentation>${replacementStatusLine}`);
|
|
76055
76652
|
}
|
|
76056
76653
|
|
|
76057
76654
|
/**
|
|
@@ -76071,8 +76668,8 @@
|
|
|
76071
76668
|
const loginMethodSuffix = loginMethodLabel ? ` (${loginMethodLabel})` : '';
|
|
76072
76669
|
const stepsSummary = formatCoderRunSteps(steps);
|
|
76073
76670
|
const stepsSuffix = stepsSummary === '' ? '' : ` - ${stepsSummary}`;
|
|
76074
|
-
// Replace
|
|
76075
|
-
file.lines[section.statusLineIndex] = line
|
|
76671
|
+
// Replace the complete todo status, including any required model/harness token.
|
|
76672
|
+
file.lines[section.statusLineIndex] = replacePromptTodoStatusLine(line, `[x] ${attemptMetadata}by ${runnerSignature}${loginMethodSuffix}${stepsSuffix}`);
|
|
76076
76673
|
}
|
|
76077
76674
|
|
|
76078
76675
|
/**
|
|
@@ -76090,8 +76687,10 @@
|
|
|
76090
76687
|
const attemptMetadata = formatPromptAttemptMetadata('failed', attemptCount);
|
|
76091
76688
|
const duration = moment__default["default"]().diff(promptExecutionStartedDate);
|
|
76092
76689
|
const durationString = moment__default["default"].duration(duration).humanize();
|
|
76093
|
-
const failureDetails = attemptMetadata === ''
|
|
76094
|
-
|
|
76690
|
+
const failureDetails = attemptMetadata === ''
|
|
76691
|
+
? `failed after ${durationString} by ${runnerSignature}`
|
|
76692
|
+
: `${attemptMetadata}${durationString} by ${runnerSignature}`;
|
|
76693
|
+
file.lines[section.statusLineIndex] = replacePromptTodoStatusLine(line, `[!] ${failureDetails}`);
|
|
76095
76694
|
}
|
|
76096
76695
|
|
|
76097
76696
|
/**
|
|
@@ -77061,17 +77660,18 @@
|
|
|
77061
77660
|
/**
|
|
77062
77661
|
* Lists todo prompts that are ready to run (no authoring placeholders).
|
|
77063
77662
|
*/
|
|
77064
|
-
function listRunnablePrompts(files, priorityFilter = {}) {
|
|
77663
|
+
function listRunnablePrompts(files, priorityFilter = {}, promptRunnerIdentity) {
|
|
77065
77664
|
return listTodoPrompts(files).filter((prompt) => !isPromptToBeWritten(prompt.file, prompt.section) &&
|
|
77066
|
-
isPromptInPriorityFilter(prompt.section, priorityFilter)
|
|
77665
|
+
isPromptInPriorityFilter(prompt.section, priorityFilter) &&
|
|
77666
|
+
isPromptCompatibleWithRunner(prompt.file, prompt.section, promptRunnerIdentity));
|
|
77067
77667
|
}
|
|
77068
77668
|
|
|
77069
77669
|
/**
|
|
77070
77670
|
* Selects the next runnable prompt based on priority.
|
|
77071
77671
|
*/
|
|
77072
|
-
function findNextTodoPrompt(files, priorityFilter = {}) {
|
|
77672
|
+
function findNextTodoPrompt(files, priorityFilter = {}, promptRunnerIdentity) {
|
|
77073
77673
|
let nextPrompt;
|
|
77074
|
-
for (const prompt of listRunnablePrompts(files, priorityFilter)) {
|
|
77674
|
+
for (const prompt of listRunnablePrompts(files, priorityFilter, promptRunnerIdentity)) {
|
|
77075
77675
|
if (!nextPrompt || prompt.section.priority > nextPrompt.section.priority) {
|
|
77076
77676
|
nextPrompt = prompt;
|
|
77077
77677
|
}
|
|
@@ -77082,8 +77682,8 @@
|
|
|
77082
77682
|
/**
|
|
77083
77683
|
* Lists upcoming tasks that are ready to run (no authoring placeholders).
|
|
77084
77684
|
*/
|
|
77085
|
-
function listUpcomingTasks(files, priorityFilter = {}) {
|
|
77086
|
-
return listRunnablePrompts(files, priorityFilter).map(({ file, section }) => ({
|
|
77685
|
+
function listUpcomingTasks(files, priorityFilter = {}, promptRunnerIdentity) {
|
|
77686
|
+
return listRunnablePrompts(files, priorityFilter, promptRunnerIdentity).map(({ file, section }) => ({
|
|
77087
77687
|
label: buildPromptLabelForDisplay(file, section),
|
|
77088
77688
|
summary: buildPromptSummary(file, section),
|
|
77089
77689
|
priority: section.priority,
|
|
@@ -77227,6 +77827,71 @@
|
|
|
77227
77827
|
}
|
|
77228
77828
|
}
|
|
77229
77829
|
|
|
77830
|
+
/**
|
|
77831
|
+
* Creates the one queue prompt used to repair a pre-existing test failure.
|
|
77832
|
+
*/
|
|
77833
|
+
async function createTestBeforeRepairPrompt(options) {
|
|
77834
|
+
const description = spaceTrim((block) => `
|
|
77835
|
+
Fix the existing test failures before implementing any queued coding tasks.
|
|
77836
|
+
|
|
77837
|
+
The verification command \`${options.testCommand}\` failed before coding started. Fix the underlying failure without weakening or removing the tests, and leave the project ready for the remaining coding prompts.
|
|
77838
|
+
|
|
77839
|
+
## Verification output
|
|
77840
|
+
|
|
77841
|
+
\`\`\`
|
|
77842
|
+
${block(limitTestOutput(options.testOutput))}
|
|
77843
|
+
\`\`\`
|
|
77844
|
+
`);
|
|
77845
|
+
const createdPrompt = await addCoderPrompt({
|
|
77846
|
+
projectPath: options.projectPath,
|
|
77847
|
+
description,
|
|
77848
|
+
priority: 0,
|
|
77849
|
+
});
|
|
77850
|
+
const promptPath = path.join(options.projectPath, createdPrompt.filePath);
|
|
77851
|
+
const promptFile = parsePromptFile(promptPath, await promises.readFile(promptPath, 'utf-8'));
|
|
77852
|
+
const section = promptFile.sections[0];
|
|
77853
|
+
if (!section) {
|
|
77854
|
+
throw new UnexpectedError(spaceTrim(`
|
|
77855
|
+
The pre-coding test repair prompt was created at \`${createdPrompt.filePath}\` without a runnable section.
|
|
77856
|
+
`));
|
|
77857
|
+
}
|
|
77858
|
+
return { file: promptFile, section };
|
|
77859
|
+
}
|
|
77860
|
+
|
|
77861
|
+
/**
|
|
77862
|
+
* Runs the configured verification command before the first coding prompt.
|
|
77863
|
+
*/
|
|
77864
|
+
async function runTestBefore(options) {
|
|
77865
|
+
var _a, _b;
|
|
77866
|
+
const runPromptTestCommandExecutor = (_a = options.runPromptTestCommandExecutor) !== null && _a !== void 0 ? _a : runPromptTestCommand;
|
|
77867
|
+
const initialTestStatusMessage = `Running initial tests before the agent coding starts: ${options.testCommand}`;
|
|
77868
|
+
await ((_b = options.waitForPauseCheckpoint) === null || _b === void 0 ? void 0 : _b.call(options, {
|
|
77869
|
+
checkpointLabel: 'running initial tests before the agent coding starts',
|
|
77870
|
+
phase: 'verifying',
|
|
77871
|
+
statusMessage: initialTestStatusMessage,
|
|
77872
|
+
}));
|
|
77873
|
+
console.info(colors__default["default"].gray(initialTestStatusMessage));
|
|
77874
|
+
try {
|
|
77875
|
+
const testOutput = await runPromptTestCommandExecutor({
|
|
77876
|
+
command: options.testCommand,
|
|
77877
|
+
projectPath: options.projectPath,
|
|
77878
|
+
scriptPath: buildTemporaryPromptScriptPath({
|
|
77879
|
+
projectPath: options.projectPath,
|
|
77880
|
+
scriptDirectoryName: 'coder-prompts',
|
|
77881
|
+
sourceFileName: 'test-before',
|
|
77882
|
+
}),
|
|
77883
|
+
});
|
|
77884
|
+
console.info(colors__default["default"].green('Pre-coding tests passed.'));
|
|
77885
|
+
return { isPassed: true, testOutput };
|
|
77886
|
+
}
|
|
77887
|
+
catch (error) {
|
|
77888
|
+
const testOutput = formatUnknownErrorMessage(error);
|
|
77889
|
+
console.error(colors__default["default"].red('Pre-coding tests failed.'));
|
|
77890
|
+
console.error(testOutput);
|
|
77891
|
+
return { isPassed: false, testOutput };
|
|
77892
|
+
}
|
|
77893
|
+
}
|
|
77894
|
+
|
|
77230
77895
|
/**
|
|
77231
77896
|
* Constant for prompts dir.
|
|
77232
77897
|
*/
|
|
@@ -77254,6 +77919,10 @@
|
|
|
77254
77919
|
return;
|
|
77255
77920
|
}
|
|
77256
77921
|
const { runner, actualRunnerModel, runnerMetadata } = resolvePromptRunner(options);
|
|
77922
|
+
const promptRunnerIdentity = {
|
|
77923
|
+
harnessName: options.agentName,
|
|
77924
|
+
modelName: actualRunnerModel,
|
|
77925
|
+
};
|
|
77257
77926
|
console.info(colors__default["default"].green(`Running prompts with ${runner.name}`));
|
|
77258
77927
|
initializeRunUi(uiHandle, runner.name, actualRunnerModel, options);
|
|
77259
77928
|
await initializeRunUiAgentVisual(uiHandle, resolvedCoderAgent === null || resolvedCoderAgent === void 0 ? void 0 : resolvedCoderAgent.agentSource);
|
|
@@ -77268,6 +77937,7 @@
|
|
|
77268
77937
|
let previousRoundStartTime;
|
|
77269
77938
|
let previousRoundEndTime;
|
|
77270
77939
|
let completedRunCount = 0;
|
|
77940
|
+
let hasRunTestBefore = false;
|
|
77271
77941
|
while (just(true)) {
|
|
77272
77942
|
if (options.autoPull && !options.dryRun) {
|
|
77273
77943
|
await waitForRequestedPause({
|
|
@@ -77280,6 +77950,35 @@
|
|
|
77280
77950
|
options,
|
|
77281
77951
|
isRichUiEnabled,
|
|
77282
77952
|
});
|
|
77953
|
+
if (!hasRunTestBefore && options.testBefore !== 'no') {
|
|
77954
|
+
await waitForRequestedPause({
|
|
77955
|
+
checkpointLabel: 'loading prompts before running initial tests',
|
|
77956
|
+
phase: 'loading',
|
|
77957
|
+
statusMessage: 'Loading prompts before running initial tests...',
|
|
77958
|
+
});
|
|
77959
|
+
await loadPromptQueueSnapshot({
|
|
77960
|
+
options,
|
|
77961
|
+
isRichUiEnabled,
|
|
77962
|
+
progressDisplay,
|
|
77963
|
+
uiHandle,
|
|
77964
|
+
promptRunnerIdentity,
|
|
77965
|
+
});
|
|
77966
|
+
}
|
|
77967
|
+
if (!hasRunTestBefore) {
|
|
77968
|
+
hasWaitedForStart = await runTestBeforeIfNeeded({
|
|
77969
|
+
options,
|
|
77970
|
+
runner,
|
|
77971
|
+
runnerMetadata,
|
|
77972
|
+
resolvedCoderContext,
|
|
77973
|
+
resolvedAgentSystemMessage,
|
|
77974
|
+
isRichUiEnabled,
|
|
77975
|
+
progressDisplay,
|
|
77976
|
+
uiHandle,
|
|
77977
|
+
waitForRequestedPause,
|
|
77978
|
+
hasWaitedForStart,
|
|
77979
|
+
});
|
|
77980
|
+
hasRunTestBefore = true;
|
|
77981
|
+
}
|
|
77283
77982
|
await waitForRequestedPause({
|
|
77284
77983
|
checkpointLabel: 'loading prompts',
|
|
77285
77984
|
phase: 'loading',
|
|
@@ -77290,6 +77989,7 @@
|
|
|
77290
77989
|
isRichUiEnabled,
|
|
77291
77990
|
progressDisplay,
|
|
77292
77991
|
uiHandle,
|
|
77992
|
+
promptRunnerIdentity,
|
|
77293
77993
|
});
|
|
77294
77994
|
hasShownUpcomingTasks || (hasShownUpcomingTasks = showUpcomingTasksOnce({
|
|
77295
77995
|
hasShownUpcomingTasks,
|
|
@@ -77297,6 +77997,7 @@
|
|
|
77297
77997
|
stats: promptQueueSnapshot.stats,
|
|
77298
77998
|
priorityFilter: options.priorityFilter,
|
|
77299
77999
|
isRichUiEnabled,
|
|
78000
|
+
promptRunnerIdentity,
|
|
77300
78001
|
}));
|
|
77301
78002
|
if (!promptQueueSnapshot.nextPrompt) {
|
|
77302
78003
|
if (isEndAfterCurrentPromptRequested(completedRunCount)) {
|
|
@@ -77399,6 +78100,14 @@
|
|
|
77399
78100
|
* Validates cross-flag constraints before the run starts.
|
|
77400
78101
|
*/
|
|
77401
78102
|
function validateRunCodexPromptOptions(options) {
|
|
78103
|
+
var _a;
|
|
78104
|
+
if (!isTestBeforeMode((_a = options.testBefore) !== null && _a !== void 0 ? _a : 'no')) {
|
|
78105
|
+
throw new NotAllowed(_spaceTrim.spaceTrim(`
|
|
78106
|
+
Invalid ${'`--test-before`'} mode: \`${String(options.testBefore)}\`.
|
|
78107
|
+
|
|
78108
|
+
Use one of: \`no\`, \`yes-and-fail\`, \`yes-and-fix\`.
|
|
78109
|
+
`));
|
|
78110
|
+
}
|
|
77402
78111
|
if (options.allowDestructiveAutoMigrate && !options.autoMigrate) {
|
|
77403
78112
|
throw new DatabaseError(_spaceTrim.spaceTrim(`
|
|
77404
78113
|
Flag \`--allow-destructive-auto-migrate\` requires \`--auto-migrate\`.
|
|
@@ -77469,20 +78178,103 @@
|
|
|
77469
78178
|
* Normalizes legacy and current priority options into one validated run option shape.
|
|
77470
78179
|
*/
|
|
77471
78180
|
function normalizeRunOptions(options) {
|
|
77472
|
-
var _a, _b, _c, _d, _e;
|
|
78181
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
78182
|
+
const testBefore = (_a = options.testBefore) !== null && _a !== void 0 ? _a : 'no';
|
|
78183
|
+
const normalizedTestCommand = (_b = options.testCommand) === null || _b === void 0 ? void 0 : _b.trim();
|
|
77473
78184
|
const priorityFilter = normalizePriorityFilter({
|
|
77474
78185
|
priority: options.priority,
|
|
77475
|
-
minimumPriority: (
|
|
77476
|
-
maximumPriority: (
|
|
78186
|
+
minimumPriority: (_c = options.minimumPriority) !== null && _c !== void 0 ? _c : (_d = options.priorityFilter) === null || _d === void 0 ? void 0 : _d.minimumPriority,
|
|
78187
|
+
maximumPriority: (_e = options.maximumPriority) !== null && _e !== void 0 ? _e : (_f = options.priorityFilter) === null || _f === void 0 ? void 0 : _f.maximumPriority,
|
|
77477
78188
|
});
|
|
77478
78189
|
return {
|
|
77479
78190
|
...options,
|
|
77480
|
-
|
|
78191
|
+
testBefore,
|
|
78192
|
+
testCommand: normalizedTestCommand || (testBefore === 'no' ? undefined : DEFAULT_CODER_TEST_COMMAND),
|
|
78193
|
+
priority: (_g = priorityFilter.minimumPriority) !== null && _g !== void 0 ? _g : 0,
|
|
77481
78194
|
minimumPriority: priorityFilter.minimumPriority,
|
|
77482
78195
|
maximumPriority: priorityFilter.maximumPriority,
|
|
77483
78196
|
priorityFilter,
|
|
77484
78197
|
};
|
|
77485
78198
|
}
|
|
78199
|
+
/**
|
|
78200
|
+
* Runs the optional pre-coding verification and, when requested, its one repair prompt.
|
|
78201
|
+
*/
|
|
78202
|
+
async function runTestBeforeIfNeeded(options) {
|
|
78203
|
+
const { options: runOptions, runner, runnerMetadata, resolvedCoderContext, resolvedAgentSystemMessage, isRichUiEnabled, progressDisplay, uiHandle, waitForRequestedPause, hasWaitedForStart, } = options;
|
|
78204
|
+
if (runOptions.testBefore === 'no') {
|
|
78205
|
+
return hasWaitedForStart;
|
|
78206
|
+
}
|
|
78207
|
+
if (!runOptions.testCommand) {
|
|
78208
|
+
throw new NotAllowed(_spaceTrim.spaceTrim(`
|
|
78209
|
+
${'`--test-before ' + runOptions.testBefore + '`'} requires a verification command.
|
|
78210
|
+
|
|
78211
|
+
Pass one with ${'`--test <test-command>`'} or use the default ${'`npm test`'} command by providing the mode through the CLI.
|
|
78212
|
+
`));
|
|
78213
|
+
}
|
|
78214
|
+
if (!runOptions.ignoreGitChanges) {
|
|
78215
|
+
await waitForRequestedPause({
|
|
78216
|
+
checkpointLabel: 'checking the git working tree before testing',
|
|
78217
|
+
phase: 'loading',
|
|
78218
|
+
statusMessage: 'Checking the working tree before testing...',
|
|
78219
|
+
});
|
|
78220
|
+
await ensureWorkingTreeClean();
|
|
78221
|
+
}
|
|
78222
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.startCapturingAgentOutput();
|
|
78223
|
+
const testBeforeResult = await runTestBefore({
|
|
78224
|
+
testCommand: runOptions.testCommand,
|
|
78225
|
+
projectPath: process.cwd(),
|
|
78226
|
+
waitForPauseCheckpoint: waitForRequestedPause,
|
|
78227
|
+
}).finally(() => {
|
|
78228
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.stopCapturingAgentOutput();
|
|
78229
|
+
});
|
|
78230
|
+
if (testBeforeResult.isPassed) {
|
|
78231
|
+
return hasWaitedForStart;
|
|
78232
|
+
}
|
|
78233
|
+
const testOutput = limitTestOutput(testBeforeResult.testOutput);
|
|
78234
|
+
if (runOptions.testBefore === 'yes-and-fail') {
|
|
78235
|
+
throw new NotAllowed(_spaceTrim.spaceTrim((block) => `
|
|
78236
|
+
Pre-coding verification command \`${runOptions.testCommand}\` failed.
|
|
78237
|
+
|
|
78238
|
+
The coding agent was not started because the project was already failing before the first queued prompt.
|
|
78239
|
+
|
|
78240
|
+
### Test results
|
|
78241
|
+
${'```'}
|
|
78242
|
+
${block(testOutput)}
|
|
78243
|
+
${'```'}
|
|
78244
|
+
`));
|
|
78245
|
+
}
|
|
78246
|
+
const repairPrompt = await createTestBeforeRepairPrompt({
|
|
78247
|
+
projectPath: process.cwd(),
|
|
78248
|
+
testCommand: runOptions.testCommand,
|
|
78249
|
+
testOutput,
|
|
78250
|
+
});
|
|
78251
|
+
const repairPromptLabel = buildPromptLabelForDisplay(repairPrompt.file, repairPrompt.section);
|
|
78252
|
+
const updatedHasWaitedForStart = await waitForPromptConfirmationIfNeeded({
|
|
78253
|
+
options: runOptions,
|
|
78254
|
+
nextPrompt: repairPrompt,
|
|
78255
|
+
promptLabel: repairPromptLabel,
|
|
78256
|
+
hasWaitedForStart,
|
|
78257
|
+
isRichUiEnabled,
|
|
78258
|
+
progressDisplay,
|
|
78259
|
+
uiHandle,
|
|
78260
|
+
});
|
|
78261
|
+
// The repair prompt is created in the current worktree so it can be recorded and committed with the repair.
|
|
78262
|
+
// It therefore intentionally uses the regular round here even when the queue itself uses --isolate.
|
|
78263
|
+
await runPromptRound({
|
|
78264
|
+
options: runOptions,
|
|
78265
|
+
runner,
|
|
78266
|
+
runnerMetadata,
|
|
78267
|
+
nextPrompt: repairPrompt,
|
|
78268
|
+
promptLabel: repairPromptLabel,
|
|
78269
|
+
resolvedCoderContext,
|
|
78270
|
+
resolvedAgentSystemMessage,
|
|
78271
|
+
isRichUiEnabled,
|
|
78272
|
+
progressDisplay,
|
|
78273
|
+
uiHandle,
|
|
78274
|
+
waitForRequestedPause,
|
|
78275
|
+
});
|
|
78276
|
+
return updatedHasWaitedForStart;
|
|
78277
|
+
}
|
|
77486
78278
|
/**
|
|
77487
78279
|
* Creates a pause waiter that keeps the progress display and rich UI in sync.
|
|
77488
78280
|
*/
|
|
@@ -77567,7 +78359,7 @@
|
|
|
77567
78359
|
* Loads prompt files, updates progress displays, and selects the next runnable prompt.
|
|
77568
78360
|
*/
|
|
77569
78361
|
async function loadPromptQueueSnapshot(options) {
|
|
77570
|
-
const { options: runOptions, isRichUiEnabled, progressDisplay, uiHandle } = options;
|
|
78362
|
+
const { options: runOptions, isRichUiEnabled, progressDisplay, uiHandle, promptRunnerIdentity } = options;
|
|
77571
78363
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setCurrentScriptPath(undefined);
|
|
77572
78364
|
const promptFiles = await loadPromptFiles(PROMPTS_DIR$1);
|
|
77573
78365
|
const stats = summarizePrompts(promptFiles, runOptions.priorityFilter);
|
|
@@ -77579,14 +78371,14 @@
|
|
|
77579
78371
|
return {
|
|
77580
78372
|
promptFiles,
|
|
77581
78373
|
stats,
|
|
77582
|
-
nextPrompt: findNextTodoPrompt(promptFiles, runOptions.priorityFilter),
|
|
78374
|
+
nextPrompt: findNextTodoPrompt(promptFiles, runOptions.priorityFilter, promptRunnerIdentity),
|
|
77583
78375
|
};
|
|
77584
78376
|
}
|
|
77585
78377
|
/**
|
|
77586
78378
|
* Prints upcoming tasks only on the first loop iteration in plain-console mode.
|
|
77587
78379
|
*/
|
|
77588
78380
|
function showUpcomingTasksOnce(options) {
|
|
77589
|
-
const { hasShownUpcomingTasks, promptFiles, stats, priorityFilter, isRichUiEnabled } = options;
|
|
78381
|
+
const { hasShownUpcomingTasks, promptFiles, stats, priorityFilter, isRichUiEnabled, promptRunnerIdentity } = options;
|
|
77590
78382
|
if (hasShownUpcomingTasks || isRichUiEnabled) {
|
|
77591
78383
|
return true;
|
|
77592
78384
|
}
|
|
@@ -77595,7 +78387,7 @@
|
|
|
77595
78387
|
printPromptsToBeWritten(promptFiles, priorityFilter);
|
|
77596
78388
|
console.info('');
|
|
77597
78389
|
}
|
|
77598
|
-
printUpcomingTasks(listUpcomingTasks(promptFiles, priorityFilter));
|
|
78390
|
+
printUpcomingTasks(listUpcomingTasks(promptFiles, priorityFilter, promptRunnerIdentity));
|
|
77599
78391
|
return true;
|
|
77600
78392
|
}
|
|
77601
78393
|
/**
|
|
@@ -77605,7 +78397,10 @@
|
|
|
77605
78397
|
if (promptQueueSnapshot.nextPrompt) {
|
|
77606
78398
|
return false;
|
|
77607
78399
|
}
|
|
77608
|
-
if (promptQueueSnapshot.stats.
|
|
78400
|
+
if (promptQueueSnapshot.stats.forAgent > 0) {
|
|
78401
|
+
announceRunCompletion('No prompts match the selected harness or model.', colors__default["default"].yellow, isRichUiEnabled, uiHandle);
|
|
78402
|
+
}
|
|
78403
|
+
else if (promptQueueSnapshot.stats.toBeWritten > 0) {
|
|
77609
78404
|
announceRunCompletion('No prompts ready for agent.', colors__default["default"].yellow, isRichUiEnabled, uiHandle);
|
|
77610
78405
|
}
|
|
77611
78406
|
else {
|
|
@@ -77646,9 +78441,16 @@
|
|
|
77646
78441
|
* Updates the UI status message while waiting for new prompts in keepAlive server mode.
|
|
77647
78442
|
*/
|
|
77648
78443
|
function announceKeepAliveStatus(promptQueueSnapshot, isRichUiEnabled, uiHandle) {
|
|
77649
|
-
|
|
77650
|
-
|
|
77651
|
-
|
|
78444
|
+
let message;
|
|
78445
|
+
if (promptQueueSnapshot.stats.forAgent > 0) {
|
|
78446
|
+
message = 'No prompts match the selected harness or model. Watching for changes...';
|
|
78447
|
+
}
|
|
78448
|
+
else if (promptQueueSnapshot.stats.toBeWritten > 0) {
|
|
78449
|
+
message = 'No prompts ready for agent. Watching for changes...';
|
|
78450
|
+
}
|
|
78451
|
+
else {
|
|
78452
|
+
message = 'All prompts are done. Watching for changes...';
|
|
78453
|
+
}
|
|
77652
78454
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setStatusMessage(message);
|
|
77653
78455
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setPhase('waiting');
|
|
77654
78456
|
if (!isRichUiEnabled) {
|
|
@@ -77670,7 +78472,7 @@
|
|
|
77670
78472
|
* Waits for the optional user confirmation before starting the selected prompt.
|
|
77671
78473
|
*/
|
|
77672
78474
|
async function waitForPromptConfirmationIfNeeded(options) {
|
|
77673
|
-
const { options: runOptions, nextPrompt, promptLabel, hasWaitedForStart, isRichUiEnabled, progressDisplay, uiHandle } = options;
|
|
78475
|
+
const { options: runOptions, nextPrompt, promptLabel, hasWaitedForStart, isRichUiEnabled, progressDisplay, uiHandle, } = options;
|
|
77674
78476
|
if (!runOptions.waitForUser) {
|
|
77675
78477
|
return hasWaitedForStart;
|
|
77676
78478
|
}
|
|
@@ -78992,14 +79794,21 @@
|
|
|
78992
79794
|
let promptFiles = initialFiles;
|
|
78993
79795
|
const skippedFiles = new Set();
|
|
78994
79796
|
while (true) {
|
|
79797
|
+
// Note: The git synchronization is applied around each single verification, not once per whole run
|
|
79798
|
+
await $pullCoderChanges({ gitSync: normalizedOptions.gitSync });
|
|
79799
|
+
if (normalizedOptions.gitSync.isAutoPullEnabled) {
|
|
79800
|
+
// Note: The pull can bring in prompt file changes, so the queue is reloaded before it is used
|
|
79801
|
+
promptFiles = (await loadPromptFilesForVerification(normalizedOptions)).promptFiles;
|
|
79802
|
+
}
|
|
78995
79803
|
displayPromptOverview(promptFiles);
|
|
78996
79804
|
// First priority: verify files where all prompts are marked as done
|
|
78997
79805
|
const fileWithAllDone = findFileWithAllDonePrompts(promptFiles, skippedFiles);
|
|
78998
79806
|
if (fileWithAllDone) {
|
|
78999
|
-
const
|
|
79000
|
-
if (wasSkipped) {
|
|
79807
|
+
const outcome = await verifyDonePromptsInFile(fileWithAllDone);
|
|
79808
|
+
if (outcome.wasSkipped) {
|
|
79001
79809
|
skippedFiles.add(fileWithAllDone.path);
|
|
79002
79810
|
}
|
|
79811
|
+
await $commitVerificationOutcome(normalizedOptions.gitSync, outcome);
|
|
79003
79812
|
promptFiles = (await loadPromptFilesForVerification(normalizedOptions)).promptFiles;
|
|
79004
79813
|
continue;
|
|
79005
79814
|
}
|
|
@@ -79009,10 +79818,20 @@
|
|
|
79009
79818
|
console.info(colors__default["default"].green('\n✅ All prompts have been verified.'));
|
|
79010
79819
|
break;
|
|
79011
79820
|
}
|
|
79012
|
-
await resolvePrompt(nextPrompt);
|
|
79821
|
+
const outcome = await resolvePrompt(nextPrompt);
|
|
79822
|
+
await $commitVerificationOutcome(normalizedOptions.gitSync, outcome);
|
|
79013
79823
|
promptFiles = (await loadPromptFilesForVerification(normalizedOptions)).promptFiles;
|
|
79014
79824
|
}
|
|
79015
79825
|
}
|
|
79826
|
+
/**
|
|
79827
|
+
* Commits and pushes one applied verification when the git synchronization is enabled.
|
|
79828
|
+
*/
|
|
79829
|
+
async function $commitVerificationOutcome(gitSync, outcome) {
|
|
79830
|
+
if (outcome.commitMessage === null) {
|
|
79831
|
+
return;
|
|
79832
|
+
}
|
|
79833
|
+
await $commitCoderChanges({ gitSync, commitMessage: outcome.commitMessage });
|
|
79834
|
+
}
|
|
79016
79835
|
/**
|
|
79017
79836
|
* Parses supported command-line arguments for the standalone verification script.
|
|
79018
79837
|
*/
|
|
@@ -79020,6 +79839,11 @@
|
|
|
79020
79839
|
return {
|
|
79021
79840
|
reverse: args.includes('--reverse'),
|
|
79022
79841
|
ignore: readRepeatableStringOption(args, '--ignore'),
|
|
79842
|
+
gitSync: {
|
|
79843
|
+
isCommitEnabled: args.includes('--commit'),
|
|
79844
|
+
isAutoPushEnabled: args.includes('--auto-push'),
|
|
79845
|
+
isAutoPullEnabled: args.includes('--auto-pull'),
|
|
79846
|
+
},
|
|
79023
79847
|
};
|
|
79024
79848
|
}
|
|
79025
79849
|
/**
|
|
@@ -79071,10 +79895,11 @@
|
|
|
79071
79895
|
* Normalizes verification options so the rest of the flow can assume stable defaults.
|
|
79072
79896
|
*/
|
|
79073
79897
|
function normalizeVerifyPromptsOptions(options) {
|
|
79074
|
-
var _a, _b;
|
|
79898
|
+
var _a, _b, _c;
|
|
79075
79899
|
return {
|
|
79076
79900
|
reverse: (_a = options.reverse) !== null && _a !== void 0 ? _a : false,
|
|
79077
79901
|
ignore: normalizeIgnoreValues((_b = options.ignore) !== null && _b !== void 0 ? _b : []),
|
|
79902
|
+
gitSync: (_c = options.gitSync) !== null && _c !== void 0 ? _c : DISABLED_CODER_GIT_SYNC_OPTIONS,
|
|
79078
79903
|
};
|
|
79079
79904
|
}
|
|
79080
79905
|
/**
|
|
@@ -79205,7 +80030,6 @@
|
|
|
79205
80030
|
/**
|
|
79206
80031
|
* Verifies the last done [x] prompt in a file and decides whether to archive it or add a repair prompt.
|
|
79207
80032
|
* Ignores not-ready prompts like [-], [.], [?], etc.
|
|
79208
|
-
* Returns true if the file was skipped, false otherwise.
|
|
79209
80033
|
*/
|
|
79210
80034
|
async function verifyDonePromptsInFile(file) {
|
|
79211
80035
|
const doneCount = file.sections.filter((s) => s.status === 'done').length;
|
|
@@ -79225,32 +80049,45 @@
|
|
|
79225
80049
|
}
|
|
79226
80050
|
if (!lastDoneSection) {
|
|
79227
80051
|
console.info(colors__default["default"].gray('No done [x] prompts found in this file.'));
|
|
79228
|
-
return false;
|
|
80052
|
+
return { wasSkipped: false, commitMessage: null };
|
|
79229
80053
|
}
|
|
79230
80054
|
console.info(colors__default["default"].gray('Verifying the last [x] prompt in the file...\n'));
|
|
79231
80055
|
displayPromptSnippet({ file, section: lastDoneSection });
|
|
79232
80056
|
const decision = await promptForDoneVerification(file, lastDoneSection);
|
|
79233
80057
|
if (decision === 'done') {
|
|
79234
80058
|
await archivePromptFile(file);
|
|
79235
|
-
return false;
|
|
80059
|
+
return { wasSkipped: false, commitMessage: buildArchiveCommitMessage(file) };
|
|
79236
80060
|
}
|
|
79237
80061
|
else if (decision === 'needs-work') {
|
|
79238
80062
|
console.info(colors__default["default"].yellow('\n⚠️ This prompt needs repair.'));
|
|
79239
80063
|
await appendRepairPrompt(file, lastDoneSection);
|
|
79240
|
-
return false;
|
|
80064
|
+
return { wasSkipped: false, commitMessage: buildRepairCommitMessage(file) };
|
|
79241
80065
|
}
|
|
79242
80066
|
else {
|
|
79243
80067
|
console.info(colors__default["default"].gray('\n⏩ Skipped, no changes made.'));
|
|
79244
|
-
return true;
|
|
80068
|
+
return { wasSkipped: true, commitMessage: null };
|
|
79245
80069
|
}
|
|
79246
80070
|
}
|
|
80071
|
+
/**
|
|
80072
|
+
* Builds the commit message describing one archived prompt file.
|
|
80073
|
+
*/
|
|
80074
|
+
function buildArchiveCommitMessage(file) {
|
|
80075
|
+
return `✅ Prompt done and archived \`${file.name}\``; // <- $commitCoderChanges({
|
|
80076
|
+
}
|
|
80077
|
+
/**
|
|
80078
|
+
* Builds the commit message describing one appended repair prompt.
|
|
80079
|
+
*/
|
|
80080
|
+
function buildRepairCommitMessage(file) {
|
|
80081
|
+
return `❌ Repair prompt added into \`${file.name}\``; // <- $commitCoderChanges({
|
|
80082
|
+
}
|
|
79247
80083
|
/**
|
|
79248
80084
|
* Asks the user to verify if a done prompt is actually completed.
|
|
79249
80085
|
* Returns 'done' if verified, 'needs-work' if not done, or 'skip' to skip this file.
|
|
79250
80086
|
*/
|
|
79251
80087
|
async function promptForDoneVerification(file, section) {
|
|
79252
80088
|
const promptLabel = buildPromptLabelForDisplay(file, section);
|
|
79253
|
-
const
|
|
80089
|
+
const { default: prompts } = await loadPromptsModule();
|
|
80090
|
+
const response = await prompts({
|
|
79254
80091
|
type: 'select',
|
|
79255
80092
|
name: 'verified',
|
|
79256
80093
|
message: `Is ${colors__default["default"].bold(promptLabel)} actually done?`,
|
|
@@ -79318,17 +80155,18 @@
|
|
|
79318
80155
|
const decision = await promptForDecision(selection);
|
|
79319
80156
|
if (decision === 'done') {
|
|
79320
80157
|
await archivePromptFile(selection.file);
|
|
80158
|
+
return { wasSkipped: false, commitMessage: buildArchiveCommitMessage(selection.file) };
|
|
79321
80159
|
}
|
|
79322
|
-
|
|
79323
|
-
|
|
79324
|
-
}
|
|
80160
|
+
await appendRepairPrompt(selection.file, selection.section);
|
|
80161
|
+
return { wasSkipped: false, commitMessage: buildRepairCommitMessage(selection.file) };
|
|
79325
80162
|
}
|
|
79326
80163
|
/**
|
|
79327
80164
|
* Presents the interactive decision menu for the current prompt section.
|
|
79328
80165
|
*/
|
|
79329
80166
|
async function promptForDecision(selection) {
|
|
79330
80167
|
const promptLabel = buildPromptLabelForDisplay(selection.file, selection.section);
|
|
79331
|
-
const
|
|
80168
|
+
const { default: prompts } = await loadPromptsModule();
|
|
80169
|
+
const response = await prompts({
|
|
79332
80170
|
type: 'select',
|
|
79333
80171
|
name: 'decision',
|
|
79334
80172
|
message: `Is ${colors__default["default"].bold(promptLabel)} resolved?`,
|