@promptbook/cli 0.114.0-0 → 0.114.0-2
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/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/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 +523 -169
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/run-agent-chat/runCoderPing.d.ts +48 -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/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/renderMarkdown.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 +13 -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/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-components/Chat/utils/renderMarkdown.ts +133 -9
- package/src/cli/cli-commands/agents-server/startAgentsServer/createLocalAgentRunOptions.ts +1 -0
- package/src/cli/cli-commands/coder/agentCodingFile.ts +6 -129
- package/src/cli/cli-commands/coder/getDefaultCoderPackageJsonScripts.ts +1 -1
- package/src/cli/cli-commands/coder/initializeCoderProjectConfiguration.ts +1 -4
- package/src/cli/cli-commands/coder/ping.ts +94 -0
- package/src/cli/cli-commands/coder/run.ts +25 -2
- package/src/cli/cli-commands/coder.ts +4 -0
- package/src/other/templates/getTemplatesPipelineCollection.ts +805 -842
- package/src/utils/agent-message-runtime/resolveAgentMessageRuntimeActivity.ts +101 -0
- package/src/version.ts +1 -1
- package/src/versions.txt +1 -1
- package/umd/index.umd.js +525 -171
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/run-agent-chat/runCoderPing.d.ts +48 -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/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/renderMarkdown.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 +13 -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/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('prompts'), require('crypto-js/enc-hex'), require('crypto-js/sha256'), require('socket.io-client'), require('jszip'), require('@mozilla/readability'), require('jsdom'), 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('@anthropic-ai/sdk'), require('bottleneck'), require('@azure/openai'), require('rxjs'), require('@openai/agents'), require('openai'), require('typescript'), require('ignore'), require('os'), require('events'), require('mime-types'), require('papaparse'), require('pg'), 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', 'prompts', 'crypto-js/enc-hex', 'crypto-js/sha256', 'socket.io-client', 'jszip', '@mozilla/readability', 'jsdom', 'crypto-js', 'showdown', 'glob-promise', 'http', 'express', 'socket.io', 'express-openapi-validator', 'swagger-ui-express', 'react', 'react-dom/server', '@anthropic-ai/sdk', 'bottleneck', '@azure/openai', 'rxjs', '@openai/agents', 'openai', 'typescript', 'ignore', 'os', 'events', 'mime-types', 'papaparse', 'pg', '@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.prompts, global.hexEncoder, global.sha256, global.socket_ioClient, global.JSZip, global.readability, global.jsdom, global.CryptoJS, global.showdown, global.glob, global.http, global.express, global.socket_io, global.OpenApiValidator, global.swaggerUi, global.react, global.server, global.Anthropic, global.Bottleneck, global.openai, global.rxjs, global.agents, global.OpenAI, global.ts, global.ignore, global.os, global.events, global.mimeTypes, global.papaparse, global.pg, null, global.url));
|
|
5
|
+
})(this, (function (exports, colors, commander, _spaceTrim, promises, path, crypto, child_process, moment, fs, dotenv, readline, waitasecond, prompts, hexEncoder, sha256, socket_ioClient, JSZip, readability, jsdom, CryptoJS, showdown, glob, http, express, socket_io, OpenApiValidator, swaggerUi, react, server, Anthropic, Bottleneck, openai, rxjs, agents, OpenAI, ts, ignore, os, events, mimeTypes, papaparse, pg, 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,8 +30,8 @@
|
|
|
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);
|
|
34
|
+
var prompts__default = /*#__PURE__*/_interopDefaultLegacy(prompts);
|
|
35
35
|
var hexEncoder__default = /*#__PURE__*/_interopDefaultLegacy(hexEncoder);
|
|
36
36
|
var sha256__default = /*#__PURE__*/_interopDefaultLegacy(sha256);
|
|
37
37
|
var JSZip__default = /*#__PURE__*/_interopDefaultLegacy(JSZip);
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
* @generated
|
|
64
64
|
* @see https://github.com/webgptorg/promptbook
|
|
65
65
|
*/
|
|
66
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.114.0-
|
|
66
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.114.0-2';
|
|
67
67
|
/**
|
|
68
68
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
69
69
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -26970,12 +26970,12 @@
|
|
|
26970
26970
|
* Builds the coder-run control pills shown in the footer box.
|
|
26971
26971
|
*/
|
|
26972
26972
|
function buildCoderRunControlPills(options) {
|
|
26973
|
-
const { pauseControl, pendingEnterLabel, isEndAfterCurrentPromptRequested, sessionTotal } = options;
|
|
26973
|
+
const { phase, pauseControl, pendingEnterLabel, isEndAfterCurrentPromptRequested, sessionTotal } = options;
|
|
26974
26974
|
return buildControlPills({
|
|
26975
26975
|
pauseControl,
|
|
26976
26976
|
pendingEnterLabel,
|
|
26977
26977
|
additionalControls: [
|
|
26978
|
-
buildSkipCurrentWaitControl(),
|
|
26978
|
+
...(phase === 'waiting' ? [buildSkipCurrentWaitControl()] : []),
|
|
26979
26979
|
buildEndAfterCurrentPromptControl(isEndAfterCurrentPromptRequested, sessionTotal),
|
|
26980
26980
|
],
|
|
26981
26981
|
});
|
|
@@ -29556,6 +29556,7 @@
|
|
|
29556
29556
|
` -c model_reasoning_effort="${thinkingLevel}" \\`,
|
|
29557
29557
|
` --ask-for-approval ${options.askForApproval} \\`,
|
|
29558
29558
|
` exec --model ${options.model} \\`,
|
|
29559
|
+
...(options.isMachineReadableProgressEnabled ? [' --json \\'] : []),
|
|
29559
29560
|
' --local-provider none \\',
|
|
29560
29561
|
` --sandbox ${options.sandbox} \\`,
|
|
29561
29562
|
` -C ${projectPath} \\`,
|
|
@@ -29872,6 +29873,10 @@
|
|
|
29872
29873
|
* Output line that marks finished Codex usage summary.
|
|
29873
29874
|
*/
|
|
29874
29875
|
const CODEX_COMPLETION_LINE = /^\s*tokens used\b/i;
|
|
29876
|
+
/**
|
|
29877
|
+
* Output line that marks the completed Codex turn in JSONL output mode.
|
|
29878
|
+
*/
|
|
29879
|
+
const CODEX_JSON_COMPLETION_LINE = /^\s*\{"type":"turn\.(?:completed|failed)"/u;
|
|
29875
29880
|
/**
|
|
29876
29881
|
* Idle timeout after completion marker to capture trailing output.
|
|
29877
29882
|
*/
|
|
@@ -29948,6 +29953,7 @@
|
|
|
29948
29953
|
sandbox: this.options.sandbox,
|
|
29949
29954
|
askForApproval: this.options.askForApproval,
|
|
29950
29955
|
allowCredits: this.options.allowCredits,
|
|
29956
|
+
isMachineReadableProgressEnabled: this.options.isMachineReadableProgressEnabled,
|
|
29951
29957
|
codexCommand: this.options.codexCommand,
|
|
29952
29958
|
});
|
|
29953
29959
|
for (let retryIndex = 0;; retryIndex++) {
|
|
@@ -29962,7 +29968,9 @@
|
|
|
29962
29968
|
const output = await $runGoScriptUntilMarkerIdle({
|
|
29963
29969
|
scriptPath: options.scriptPath,
|
|
29964
29970
|
scriptContent,
|
|
29965
|
-
completionLineMatcher:
|
|
29971
|
+
completionLineMatcher: this.options.isMachineReadableProgressEnabled
|
|
29972
|
+
? CODEX_JSON_COMPLETION_LINE
|
|
29973
|
+
: CODEX_COMPLETION_LINE,
|
|
29966
29974
|
idleTimeoutMs: CODEX_COMPLETION_IDLE_MS,
|
|
29967
29975
|
logPath: options.logPath,
|
|
29968
29976
|
shouldPrintLiveOutput: options.shouldPrintLiveOutput,
|
|
@@ -30212,6 +30220,7 @@
|
|
|
30212
30220
|
sandbox: 'danger-full-access',
|
|
30213
30221
|
askForApproval: 'never',
|
|
30214
30222
|
allowCredits: options.allowCredits,
|
|
30223
|
+
isMachineReadableProgressEnabled: options.isMachineReadableProgressEnabled,
|
|
30215
30224
|
});
|
|
30216
30225
|
if (!options.allowCredits && options.isVerbose === true) {
|
|
30217
30226
|
console.info(colors__default["default"].gray('OpenAI Codex credit spending is disabled. Use `--allow-credits` to explicitly opt in.'));
|
|
@@ -31447,6 +31456,7 @@
|
|
|
31447
31456
|
: [options.statusMessage, ...options.detailLines.map((detailLine) => `• ${detailLine}`)];
|
|
31448
31457
|
const visibleOutputLines = buildVisibleOutputLines(options.agentOutputLines);
|
|
31449
31458
|
const controls = buildCoderRunControlPills({
|
|
31459
|
+
phase: options.phase,
|
|
31450
31460
|
pauseControl: pausePresentation.pauseControl,
|
|
31451
31461
|
pendingEnterLabel: options.pendingEnterLabel,
|
|
31452
31462
|
isEndAfterCurrentPromptRequested: options.isEndAfterCurrentPromptRequested,
|
|
@@ -32310,6 +32320,7 @@
|
|
|
32310
32320
|
autoPull: options.autoPull,
|
|
32311
32321
|
agentName: options.agentName,
|
|
32312
32322
|
model: options.model,
|
|
32323
|
+
isMachineReadableProgressEnabled: options.isMachineReadableProgressEnabled,
|
|
32313
32324
|
priority: 0,
|
|
32314
32325
|
};
|
|
32315
32326
|
}
|
|
@@ -33299,6 +33310,21 @@
|
|
|
33299
33310
|
`);
|
|
33300
33311
|
}
|
|
33301
33312
|
|
|
33313
|
+
/**
|
|
33314
|
+
* Maximum amount of test output embedded into an agent prompt.
|
|
33315
|
+
*/
|
|
33316
|
+
const MAX_TEST_OUTPUT_CHARS = 12000;
|
|
33317
|
+
/**
|
|
33318
|
+
* Limits test output while keeping the end of the output, where test runners usually print the failure summary.
|
|
33319
|
+
*/
|
|
33320
|
+
function limitTestOutput(testOutput) {
|
|
33321
|
+
const normalizedTestOutput = testOutput.trim();
|
|
33322
|
+
if (normalizedTestOutput.length <= MAX_TEST_OUTPUT_CHARS) {
|
|
33323
|
+
return normalizedTestOutput;
|
|
33324
|
+
}
|
|
33325
|
+
return `[..., test output truncated to the last ${MAX_TEST_OUTPUT_CHARS} characters...]\n${normalizedTestOutput.slice(-MAX_TEST_OUTPUT_CHARS)}`;
|
|
33326
|
+
}
|
|
33327
|
+
|
|
33302
33328
|
/**
|
|
33303
33329
|
* Runs the configured verification command inside the project root and returns its output.
|
|
33304
33330
|
*/
|
|
@@ -33319,10 +33345,6 @@
|
|
|
33319
33345
|
* Maximum number of coding attempts allowed for the same prompt when verification keeps failing.
|
|
33320
33346
|
*/
|
|
33321
33347
|
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
33348
|
/**
|
|
33327
33349
|
* File extension used by generated shell scripts.
|
|
33328
33350
|
*/
|
|
@@ -33368,7 +33390,7 @@
|
|
|
33368
33390
|
return { ...result, attemptCount, steps };
|
|
33369
33391
|
}
|
|
33370
33392
|
const fullVerificationOutput = formatUnknownErrorDetails(failedVerification.error);
|
|
33371
|
-
const feedbackVerificationOutput =
|
|
33393
|
+
const feedbackVerificationOutput = limitTestOutput(fullVerificationOutput);
|
|
33372
33394
|
if (attemptCount >= MAX_PROMPT_TEST_ATTEMPTS) {
|
|
33373
33395
|
console.error(colors__default["default"].red(`Verification failed for ${options.promptLabel} after ${attemptCount} attempts.`));
|
|
33374
33396
|
throw new Error(buildFinalVerificationFailureMessage({
|
|
@@ -33498,19 +33520,6 @@
|
|
|
33498
33520
|
\`\`\`
|
|
33499
33521
|
`);
|
|
33500
33522
|
}
|
|
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
33523
|
/**
|
|
33515
33524
|
* Derives a dedicated temp-script path for verification commands.
|
|
33516
33525
|
*/
|
|
@@ -41371,6 +41380,7 @@
|
|
|
41371
41380
|
autoClone: false,
|
|
41372
41381
|
maxMessageProcessingFailures: localAgentRunnerLimits.maxFailedAttempts,
|
|
41373
41382
|
maxParallelMessages: localAgentRunnerLimits.maxParallelMessages,
|
|
41383
|
+
isMachineReadableProgressEnabled: true,
|
|
41374
41384
|
};
|
|
41375
41385
|
}
|
|
41376
41386
|
|
|
@@ -43485,6 +43495,27 @@
|
|
|
43485
43495
|
}
|
|
43486
43496
|
// 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
43497
|
|
|
43498
|
+
/**
|
|
43499
|
+
* Relative path to the Promptbook Coder quick-reference file initialized in project roots.
|
|
43500
|
+
*
|
|
43501
|
+
* @private internal utility of `ptbk coder`
|
|
43502
|
+
*/
|
|
43503
|
+
const AGENT_CODING_FILE_PATH = 'AGENT_CODING.md';
|
|
43504
|
+
/**
|
|
43505
|
+
* Returns the default coder `AGENT_CODING.md` quick-reference content.
|
|
43506
|
+
*
|
|
43507
|
+
* @private internal utility of `ptbk coder`
|
|
43508
|
+
*/
|
|
43509
|
+
function getDefaultCoderAgentCodingFileContent() {
|
|
43510
|
+
return _spaceTrim.spaceTrim(`
|
|
43511
|
+
# ✨ Promptbook Coder agent coding
|
|
43512
|
+
|
|
43513
|
+
This project is using [Promptbook Coder](https://coder.ptbk.io) or run \`ptbk coder\`!
|
|
43514
|
+
`);
|
|
43515
|
+
}
|
|
43516
|
+
// Note: [🟡] Code for coder AGENT_CODING file boilerplate [agentCodingFile](src/cli/cli-commands/coder/agentCodingFile.ts) should never be published outside of `@promptbook/cli`
|
|
43517
|
+
// Note: [💞] Ignore a discrepancy between file name and exported helper names
|
|
43518
|
+
|
|
43488
43519
|
/**
|
|
43489
43520
|
* Relative path to the shared coder context file initialized in project roots.
|
|
43490
43521
|
*
|
|
@@ -43512,106 +43543,6 @@
|
|
|
43512
43543
|
// Note: [🟡] Code for coder AGENTS file boilerplate [agentsFile](src/cli/cli-commands/coder/agentsFile.ts) should never be published outside of `@promptbook/cli`
|
|
43513
43544
|
// Note: [💞] Ignore a discrepancy between file name and exported helper names
|
|
43514
43545
|
|
|
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
43546
|
/**
|
|
43616
43547
|
* Relative directory path for agents initialized by `ptbk coder init`.
|
|
43617
43548
|
*
|
|
@@ -43676,6 +43607,16 @@
|
|
|
43676
43607
|
}
|
|
43677
43608
|
// 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
43609
|
|
|
43610
|
+
/**
|
|
43611
|
+
* Normalizes one project-relative path for human-readable CLI output and markdown.
|
|
43612
|
+
*
|
|
43613
|
+
* @private internal utility of `ptbk coder`
|
|
43614
|
+
*/
|
|
43615
|
+
function formatDisplayPath(relativePath) {
|
|
43616
|
+
return relativePath.replace(/\\/gu, '/');
|
|
43617
|
+
}
|
|
43618
|
+
// Note: [🟡] Code for coder path formatting [formatDisplayPath](src/cli/cli-commands/coder/formatDisplayPath.ts) should never be published outside of `@promptbook/cli`
|
|
43619
|
+
|
|
43679
43620
|
/**
|
|
43680
43621
|
* Fallback `.env` content used when no required variables need to be appended.
|
|
43681
43622
|
*/
|
|
@@ -43753,7 +43694,7 @@
|
|
|
43753
43694
|
const DEFAULT_CODER_PACKAGE_JSON_SCRIPTS = {
|
|
43754
43695
|
'coder:generate-boilerplates': 'ptbk coder generate-boilerplates --template ./prompts/templates/common.md',
|
|
43755
43696
|
'coder:add': 'ptbk coder add --template ./prompts/templates/common.md',
|
|
43756
|
-
'coder:run': 'ptbk coder run --harness openai-codex --model gpt-5.
|
|
43697
|
+
'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
43698
|
// 'coder:find-refactor-candidates': 'npx ptbk coder find-refactor-candidates',
|
|
43758
43699
|
'coder:verify': 'ptbk coder verify',
|
|
43759
43700
|
};
|
|
@@ -44002,9 +43943,7 @@
|
|
|
44002
43943
|
const agentsDirectoryStatus = await ensureDirectory(projectPath, CODER_AGENTS_DIRECTORY_PATH);
|
|
44003
43944
|
const developerAgentFileStatus = await ensureCoderDeveloperAgentFile(projectPath);
|
|
44004
43945
|
const agentsFileStatus = await ensureCoderMarkdownFile(projectPath, AGENTS_FILE_PATH, getDefaultCoderAgentsFileContent());
|
|
44005
|
-
const agentCodingFileStatus = await ensureCoderMarkdownFile(projectPath, AGENT_CODING_FILE_PATH, getDefaultCoderAgentCodingFileContent(
|
|
44006
|
-
packageJsonScripts: getDefaultCoderPackageJsonScripts(),
|
|
44007
|
-
}));
|
|
43946
|
+
const agentCodingFileStatus = await ensureCoderMarkdownFile(projectPath, AGENT_CODING_FILE_PATH, getDefaultCoderAgentCodingFileContent());
|
|
44008
43947
|
const { envFileStatus, initializedEnvVariableNames } = await ensureCoderEnvFile(projectPath);
|
|
44009
43948
|
const gitignoreFileStatus = await ensureCoderGitignoreFile(projectPath);
|
|
44010
43949
|
const packageJsonFileStatus = await ensureCoderPackageJsonFile(projectPath);
|
|
@@ -44145,6 +44084,66 @@
|
|
|
44145
44084
|
// Note: [🟡] Code for CLI command [init](src/cli/cli-commands/coder/init.ts) should never be published outside of `@promptbook/cli`
|
|
44146
44085
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
44147
44086
|
|
|
44087
|
+
/**
|
|
44088
|
+
* Initializes `coder ping` command for Promptbook CLI utilities.
|
|
44089
|
+
*
|
|
44090
|
+
* The command makes one small, isolated harness/model call, prints its result
|
|
44091
|
+
* and reports how long the harness/model turn took.
|
|
44092
|
+
*
|
|
44093
|
+
* Note: `$` is used to indicate that this function is not a pure function - it registers a command in the CLI.
|
|
44094
|
+
*
|
|
44095
|
+
* @private internal function of `promptbookCli`
|
|
44096
|
+
*/
|
|
44097
|
+
function $initializeCoderPingCommand(program) {
|
|
44098
|
+
const command = program.command('ping');
|
|
44099
|
+
command.description(_spaceTrim.spaceTrim(`
|
|
44100
|
+
Test one harness and model connection with a small disposable task
|
|
44101
|
+
|
|
44102
|
+
${PROMPT_RUNNER_DESCRIPTION}
|
|
44103
|
+
|
|
44104
|
+
Features:
|
|
44105
|
+
- Runs the dummy task in a temporary directory outside the current project
|
|
44106
|
+
- Prints the result returned by the selected harness and model
|
|
44107
|
+
- Reports the elapsed harness/model response time in milliseconds
|
|
44108
|
+
- Can be used to start consuming an applicable harness/model quota before a longer run
|
|
44109
|
+
`));
|
|
44110
|
+
addPromptRunnerSelectionOptions(command);
|
|
44111
|
+
addPromptRunnerRuntimeOptions(command);
|
|
44112
|
+
command.action(handleActionErrors(async (cliOptions) => {
|
|
44113
|
+
const normalizedOptions = normalizePromptRunnerSelectionCliOptions(cliOptions, { isAgentRequired: true });
|
|
44114
|
+
const agentName = normalizedOptions.agentName;
|
|
44115
|
+
if (!agentName) {
|
|
44116
|
+
throw new NotAllowed(_spaceTrim.spaceTrim(`
|
|
44117
|
+
A harness is required for \`ptbk coder ping\`.
|
|
44118
|
+
|
|
44119
|
+
Pass one with \`--harness <harness-name>\`.
|
|
44120
|
+
`));
|
|
44121
|
+
}
|
|
44122
|
+
await $ensureHarnessInstallations([agentName]);
|
|
44123
|
+
// Note: Import the runner-backed implementation dynamically to avoid loading heavy dependencies until needed.
|
|
44124
|
+
const { runCoderPing } = await Promise.resolve().then(function () { return runCoderPing$1; });
|
|
44125
|
+
const pingResult = await runCoderPing({
|
|
44126
|
+
agentName,
|
|
44127
|
+
model: normalizedOptions.model,
|
|
44128
|
+
thinkingLevel: normalizedOptions.thinkingLevel,
|
|
44129
|
+
isUiDisabled: normalizedOptions.noUi,
|
|
44130
|
+
isCreditsAllowed: normalizedOptions.allowCredits,
|
|
44131
|
+
});
|
|
44132
|
+
printCoderPingResult(pingResult);
|
|
44133
|
+
}));
|
|
44134
|
+
}
|
|
44135
|
+
/**
|
|
44136
|
+
* Prints the result and duration of one completed coder ping.
|
|
44137
|
+
*/
|
|
44138
|
+
function printCoderPingResult(pingResult) {
|
|
44139
|
+
console.info(_spaceTrim.spaceTrim(`
|
|
44140
|
+
Result: ${pingResult.result}
|
|
44141
|
+
Time: ${pingResult.elapsedTimeMs.toFixed(0)} ms
|
|
44142
|
+
`));
|
|
44143
|
+
}
|
|
44144
|
+
// Note: [🟡] Code for CLI command [ping](src/cli/cli-commands/coder/ping.ts) should never be published outside of `@promptbook/cli`
|
|
44145
|
+
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
44146
|
+
|
|
44148
44147
|
/**
|
|
44149
44148
|
* Creates a Commander argument parser that accepts only non-negative integers.
|
|
44150
44149
|
*
|
|
@@ -44169,6 +44168,21 @@
|
|
|
44169
44168
|
}
|
|
44170
44169
|
// Note: [🟡] Code for CLI option parser [createNonNegativeIntegerOptionParser](src/cli/cli-commands/common/createNonNegativeIntegerOptionParser.ts) should never be published outside of `@promptbook/cli`
|
|
44171
44170
|
|
|
44171
|
+
/**
|
|
44172
|
+
* Modes supported by `ptbk coder run --test-before`.
|
|
44173
|
+
*/
|
|
44174
|
+
const TEST_BEFORE_MODE_VALUES = ['no', 'yes-and-fail', 'yes-and-fix'];
|
|
44175
|
+
/**
|
|
44176
|
+
* Default verification command used when a pre-coding mode is enabled without an explicit `--test` command.
|
|
44177
|
+
*/
|
|
44178
|
+
const DEFAULT_CODER_TEST_COMMAND = 'npm test';
|
|
44179
|
+
/**
|
|
44180
|
+
* Checks whether a value is a supported `--test-before` mode.
|
|
44181
|
+
*/
|
|
44182
|
+
function isTestBeforeMode(value) {
|
|
44183
|
+
return TEST_BEFORE_MODE_VALUES.includes(value);
|
|
44184
|
+
}
|
|
44185
|
+
|
|
44172
44186
|
/**
|
|
44173
44187
|
* Default wait duration applied before retrying a prompt round after an error (10 minutes).
|
|
44174
44188
|
*
|
|
@@ -44213,6 +44227,7 @@
|
|
|
44213
44227
|
- Optional --no-ui keeps plain streaming console output for logging and debugging
|
|
44214
44228
|
- Checks that the selected harness is installed globally and up to date before the first prompt
|
|
44215
44229
|
- Supports GPG signing of commits
|
|
44230
|
+
- Optional pre-coding test run that can stop or repair pre-existing failures
|
|
44216
44231
|
- Optional post-prompt verification with test-feedback retries
|
|
44217
44232
|
- Progress tracking and interactive P/S/X terminal controls
|
|
44218
44233
|
- Dry-run mode to preview prompts
|
|
@@ -44222,6 +44237,9 @@
|
|
|
44222
44237
|
command.option('--agent <agent-book-path>', 'Path to a .book file whose compiled system message is prepended to each coding prompt');
|
|
44223
44238
|
command.option('--context <context-or-file>', 'Append extra instructions either inline or from a file path relative to the current project');
|
|
44224
44239
|
command.option('--test <test-command...>', 'Run a verification command after each prompt; quote it when the command itself contains top-level flags');
|
|
44240
|
+
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)`)
|
|
44241
|
+
.choices([...TEST_BEFORE_MODE_VALUES])
|
|
44242
|
+
.default('no'));
|
|
44225
44243
|
command.option('--preserve-logs', 'Keep generated temp prompt/log artifacts after successful rounds for debugging and analytics', false);
|
|
44226
44244
|
addPromptRunnerExecutionOptions(command);
|
|
44227
44245
|
command.option('--isolate', _spaceTrim.spaceTrim(`
|
|
@@ -44251,8 +44269,9 @@
|
|
|
44251
44269
|
command.option('--auto-migrate', 'Run testing-server database migrations automatically after each successfully processed prompt');
|
|
44252
44270
|
command.option('--allow-destructive-auto-migrate', 'Allow auto-migrate even when heuristic SQL safety check flags destructive pending migrations');
|
|
44253
44271
|
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
|
|
44272
|
+
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;
|
|
44273
|
+
const configuredTestCommand = normalizeCommandOptionValue$1(test);
|
|
44274
|
+
const testCommand = configuredTestCommand !== null && configuredTestCommand !== void 0 ? configuredTestCommand : (testBefore === 'no' ? undefined : DEFAULT_CODER_TEST_COMMAND);
|
|
44256
44275
|
const runnerOptions = normalizePromptRunnerCliOptions(cliOptions, {
|
|
44257
44276
|
isAgentRequired: !dryRun,
|
|
44258
44277
|
});
|
|
@@ -44281,6 +44300,7 @@
|
|
|
44281
44300
|
agent,
|
|
44282
44301
|
context,
|
|
44283
44302
|
testCommand,
|
|
44303
|
+
testBefore,
|
|
44284
44304
|
preserveLogs,
|
|
44285
44305
|
isIsolated,
|
|
44286
44306
|
noUi: runnerOptions.noUi,
|
|
@@ -44537,6 +44557,7 @@
|
|
|
44537
44557
|
* - add: Add one ready-to-run prompt file to the queue
|
|
44538
44558
|
* - generate-boilerplates: Generate prompt boilerplate files
|
|
44539
44559
|
* - find-refactor-candidates: Find files that need refactoring
|
|
44560
|
+
* - ping: Test one harness and model connection with a disposable task
|
|
44540
44561
|
* - run: Run coding prompts with AI agents
|
|
44541
44562
|
* - verify: Verify completed prompts
|
|
44542
44563
|
* - find-fresh-emoji-tags: Find unused emoji tags
|
|
@@ -44556,6 +44577,7 @@
|
|
|
44556
44577
|
- generate-boilerplates: Generate prompt boilerplate files
|
|
44557
44578
|
- find-refactor-candidates: Find files that need refactoring
|
|
44558
44579
|
- find-unwritten: List prompt sections that still need to be authored
|
|
44580
|
+
- ping: Test one harness and model connection with a disposable task
|
|
44559
44581
|
- run: Run coding prompts with AI agents
|
|
44560
44582
|
- server: Start a long-running coder server with a kanban web UI
|
|
44561
44583
|
- verify: Verify completed prompts
|
|
@@ -44567,6 +44589,7 @@
|
|
|
44567
44589
|
$initializeCoderGenerateBoilerplatesCommand(coderCommand);
|
|
44568
44590
|
$initializeCoderFindRefactorCandidatesCommand(coderCommand);
|
|
44569
44591
|
$initializeCoderFindUnwrittenCommand(coderCommand);
|
|
44592
|
+
$initializeCoderPingCommand(coderCommand);
|
|
44570
44593
|
$initializeCoderRunCommand(coderCommand);
|
|
44571
44594
|
$initializeCoderServerCommand(coderCommand);
|
|
44572
44595
|
$initializeCoderVerifyCommand(coderCommand);
|
|
@@ -73593,6 +73616,41 @@
|
|
|
73593
73616
|
isPromptInPriorityFilter(prompt.section, priorityFilter));
|
|
73594
73617
|
}
|
|
73595
73618
|
|
|
73619
|
+
/**
|
|
73620
|
+
* Checks whether a prompt is unrestricted or matches the selected harness/model.
|
|
73621
|
+
*
|
|
73622
|
+
* A prompt status line can contain one or more backtick-delimited model or harness
|
|
73623
|
+
* names. Matching is intentionally based on normalized substrings so a token such as
|
|
73624
|
+
* `gpt` selects any `gpt-*` model and `opus` selects a `claude-opus-*` model.
|
|
73625
|
+
*/
|
|
73626
|
+
function isPromptCompatibleWithRunner(file, section, promptRunnerIdentity) {
|
|
73627
|
+
if (promptRunnerIdentity === undefined) {
|
|
73628
|
+
return true;
|
|
73629
|
+
}
|
|
73630
|
+
const statusLine = section.statusLineIndex === undefined ? undefined : file.lines[section.statusLineIndex];
|
|
73631
|
+
const requiredRunnerTokens = statusLine === undefined ? [] : extractPromptRunnerTokens(statusLine);
|
|
73632
|
+
if (requiredRunnerTokens.length === 0) {
|
|
73633
|
+
return true;
|
|
73634
|
+
}
|
|
73635
|
+
const normalizedRunnerNames = [promptRunnerIdentity.harnessName, promptRunnerIdentity.modelName]
|
|
73636
|
+
.filter((name) => name !== undefined && name.trim() !== '')
|
|
73637
|
+
.map((name) => normalizeToKebabCase(name))
|
|
73638
|
+
.filter((name) => name !== '');
|
|
73639
|
+
return requiredRunnerTokens.some((requiredRunnerToken) => {
|
|
73640
|
+
const normalizedRequiredRunnerToken = normalizeToKebabCase(requiredRunnerToken);
|
|
73641
|
+
return (normalizedRequiredRunnerToken !== '' &&
|
|
73642
|
+
normalizedRunnerNames.some((normalizedRunnerName) => normalizedRunnerName.includes(normalizedRequiredRunnerToken)));
|
|
73643
|
+
});
|
|
73644
|
+
}
|
|
73645
|
+
/**
|
|
73646
|
+
* Extracts model and harness tokens from a prompt status line.
|
|
73647
|
+
*/
|
|
73648
|
+
function extractPromptRunnerTokens(statusLine) {
|
|
73649
|
+
return Array.from(statusLine.matchAll(/`([^`]+)`/gu))
|
|
73650
|
+
.map((match) => { var _a, _b; return (_b = (_a = match[1]) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : ''; })
|
|
73651
|
+
.filter((token) => token !== '');
|
|
73652
|
+
}
|
|
73653
|
+
|
|
73596
73654
|
/**
|
|
73597
73655
|
* Parses a prompt markdown file into sections and metadata.
|
|
73598
73656
|
*/
|
|
@@ -73640,11 +73698,11 @@
|
|
|
73640
73698
|
};
|
|
73641
73699
|
}
|
|
73642
73700
|
/**
|
|
73643
|
-
* Parses a status line like "[ ] !!"
|
|
73701
|
+
* Parses a status line like "[ ] !!", "[ ] use `gpt` !!!!!" or "[-]" into status and priority.
|
|
73644
73702
|
* For [x] done and [!] failed prompts, allow metadata after the status marker.
|
|
73645
73703
|
*/
|
|
73646
73704
|
function parseStatusLine(line) {
|
|
73647
|
-
var _a, _b, _c, _d
|
|
73705
|
+
var _a, _b, _c, _d;
|
|
73648
73706
|
// For done prompts [x], allow any content after (for cost/time metadata)
|
|
73649
73707
|
const doneMatch = line.match(/^\[(?<status>[xX])\]/);
|
|
73650
73708
|
if (doneMatch) {
|
|
@@ -73655,21 +73713,23 @@
|
|
|
73655
73713
|
if (failedMatch) {
|
|
73656
73714
|
return { status: 'failed', priority: 0 };
|
|
73657
73715
|
}
|
|
73658
|
-
// For
|
|
73659
|
-
|
|
73660
|
-
|
|
73661
|
-
return undefined;
|
|
73716
|
+
// For not-ready [-], keep the historical clean-line syntax.
|
|
73717
|
+
if (/^\[-\]\s*!*\s*$/u.test(line)) {
|
|
73718
|
+
return { status: 'not-ready', priority: 0 };
|
|
73662
73719
|
}
|
|
73663
|
-
|
|
73664
|
-
|
|
73665
|
-
|
|
73666
|
-
|
|
73720
|
+
// Todo [ ] may contain backtick-delimited model/harness tokens and priority markers
|
|
73721
|
+
// before or after those tokens. Other trailing text remains an invalid status line.
|
|
73722
|
+
const todoMatch = line.match(/^\[ \](?<details>.*)$/u);
|
|
73723
|
+
if (!todoMatch) {
|
|
73724
|
+
return undefined;
|
|
73667
73725
|
}
|
|
73668
|
-
|
|
73669
|
-
|
|
73726
|
+
const details = (_b = (_a = todoMatch.groups) === null || _a === void 0 ? void 0 : _a.details) !== null && _b !== void 0 ? _b : '';
|
|
73727
|
+
const isPriorityOnly = /^[!\s]*$/u.test(details);
|
|
73728
|
+
const hasPromptRunnerTokens = extractPromptRunnerTokens(line).length > 0;
|
|
73729
|
+
if (details.trim() !== '' && !isPriorityOnly && !hasPromptRunnerTokens) {
|
|
73730
|
+
return undefined;
|
|
73670
73731
|
}
|
|
73671
|
-
|
|
73672
|
-
return { status, priority };
|
|
73732
|
+
return { status: 'todo', priority: (_d = (_c = details.match(/!/gu)) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0 };
|
|
73673
73733
|
}
|
|
73674
73734
|
/**
|
|
73675
73735
|
* Finds the first non-empty line index between two bounds.
|
|
@@ -73805,6 +73865,66 @@
|
|
|
73805
73865
|
findUnwrittenPrompts: findUnwrittenPrompts
|
|
73806
73866
|
});
|
|
73807
73867
|
|
|
73868
|
+
/**
|
|
73869
|
+
* Agent source used by `ptbk coder ping` for its disposable connectivity turn.
|
|
73870
|
+
*/
|
|
73871
|
+
const PING_AGENT_SOURCE = _spaceTrim.spaceTrim(`
|
|
73872
|
+
Promptbook Coder Ping Agent
|
|
73873
|
+
|
|
73874
|
+
PERSONA You are a connectivity test agent. Perform only the tiny task requested by the user and answer concisely.
|
|
73875
|
+
`);
|
|
73876
|
+
/**
|
|
73877
|
+
* User message used by `ptbk coder ping` to produce a deterministic response.
|
|
73878
|
+
*/
|
|
73879
|
+
const PING_MESSAGE = 'Reply with exactly the single word PONG and nothing else.';
|
|
73880
|
+
/**
|
|
73881
|
+
* Runs one small harness/model turn in a disposable temporary project.
|
|
73882
|
+
*
|
|
73883
|
+
* The temporary project is outside the caller's repository, so even a harness
|
|
73884
|
+
* that writes files cannot change the project from which `ptbk coder ping` was
|
|
73885
|
+
* started.
|
|
73886
|
+
*/
|
|
73887
|
+
async function runCoderPing(options) {
|
|
73888
|
+
const temporaryProjectPath = await promises.mkdtemp(path.join(os.tmpdir(), 'promptbook-coder-ping-'));
|
|
73889
|
+
const originalWorkingDirectory = process.cwd();
|
|
73890
|
+
try {
|
|
73891
|
+
const agentPath = path.join(temporaryProjectPath, 'ping.book');
|
|
73892
|
+
await promises.writeFile(agentPath, `${PING_AGENT_SOURCE}\n`, 'utf-8');
|
|
73893
|
+
// Note: Some supported CLI wrappers inherit the Node process working directory instead of using projectPath.
|
|
73894
|
+
process.chdir(temporaryProjectPath);
|
|
73895
|
+
const startedAt = performance.now();
|
|
73896
|
+
const result = await executeAgentChatTurn({
|
|
73897
|
+
agentPath,
|
|
73898
|
+
currentWorkingDirectory: temporaryProjectPath,
|
|
73899
|
+
agentName: options.agentName,
|
|
73900
|
+
model: options.model,
|
|
73901
|
+
isVerbose: false,
|
|
73902
|
+
noUi: options.isUiDisabled,
|
|
73903
|
+
thinkingLevel: options.thinkingLevel,
|
|
73904
|
+
allowCredits: options.isCreditsAllowed,
|
|
73905
|
+
messages: [
|
|
73906
|
+
{
|
|
73907
|
+
sender: 'USER',
|
|
73908
|
+
content: PING_MESSAGE,
|
|
73909
|
+
},
|
|
73910
|
+
],
|
|
73911
|
+
});
|
|
73912
|
+
return {
|
|
73913
|
+
result: result.answer,
|
|
73914
|
+
elapsedTimeMs: performance.now() - startedAt,
|
|
73915
|
+
};
|
|
73916
|
+
}
|
|
73917
|
+
finally {
|
|
73918
|
+
process.chdir(originalWorkingDirectory);
|
|
73919
|
+
await promises.rm(temporaryProjectPath, { recursive: true, force: true });
|
|
73920
|
+
}
|
|
73921
|
+
}
|
|
73922
|
+
|
|
73923
|
+
var runCoderPing$1 = /*#__PURE__*/Object.freeze({
|
|
73924
|
+
__proto__: null,
|
|
73925
|
+
runCoderPing: runCoderPing
|
|
73926
|
+
});
|
|
73927
|
+
|
|
73808
73928
|
/**
|
|
73809
73929
|
* Default wait duration applied before retrying a failed prompt round.
|
|
73810
73930
|
*/
|
|
@@ -73812,7 +73932,7 @@
|
|
|
73812
73932
|
/**
|
|
73813
73933
|
* CLI usage text for this script.
|
|
73814
73934
|
*/
|
|
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]';
|
|
73935
|
+
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
73936
|
/**
|
|
73817
73937
|
* Top-level flags supported by this command.
|
|
73818
73938
|
*/
|
|
@@ -73822,6 +73942,7 @@
|
|
|
73822
73942
|
'--model',
|
|
73823
73943
|
'--context',
|
|
73824
73944
|
'--test',
|
|
73945
|
+
'--test-before',
|
|
73825
73946
|
'--preserve-logs',
|
|
73826
73947
|
'--isolate',
|
|
73827
73948
|
'--no-ui',
|
|
@@ -73860,6 +73981,8 @@
|
|
|
73860
73981
|
const context = readOptionValue(args, '--context');
|
|
73861
73982
|
const hasTestCommandFlag = args.includes('--test');
|
|
73862
73983
|
const testCommand = readVariadicOptionValue(args, '--test');
|
|
73984
|
+
const hasTestBeforeFlag = args.includes('--test-before');
|
|
73985
|
+
const testBefore = parseTestBeforeOption(readOptionValue(args, '--test-before'), hasTestBeforeFlag);
|
|
73863
73986
|
const preserveLogs = args.includes('--preserve-logs');
|
|
73864
73987
|
const isIsolated = args.includes('--isolate');
|
|
73865
73988
|
const noUi = args.includes('--no-ui');
|
|
@@ -73932,6 +74055,7 @@
|
|
|
73932
74055
|
model,
|
|
73933
74056
|
context,
|
|
73934
74057
|
testCommand,
|
|
74058
|
+
testBefore,
|
|
73935
74059
|
thinkingLevel,
|
|
73936
74060
|
priority: minimumPriority !== null && minimumPriority !== void 0 ? minimumPriority : 0,
|
|
73937
74061
|
minimumPriority,
|
|
@@ -73940,6 +74064,21 @@
|
|
|
73940
74064
|
limit,
|
|
73941
74065
|
};
|
|
73942
74066
|
}
|
|
74067
|
+
/**
|
|
74068
|
+
* Parses and validates the optional pre-coding verification mode.
|
|
74069
|
+
*/
|
|
74070
|
+
function parseTestBeforeOption(value, hasTestBeforeFlag) {
|
|
74071
|
+
if (value === undefined) {
|
|
74072
|
+
if (hasTestBeforeFlag) {
|
|
74073
|
+
exitWithUsageError(`Missing value for --test-before. Use one of: ${TEST_BEFORE_MODE_VALUES.join(', ')}.`);
|
|
74074
|
+
}
|
|
74075
|
+
return 'no';
|
|
74076
|
+
}
|
|
74077
|
+
if (!isTestBeforeMode(value)) {
|
|
74078
|
+
exitWithUsageError(`Invalid value for --test-before: "${value}". Use one of: ${TEST_BEFORE_MODE_VALUES.join(', ')}.`);
|
|
74079
|
+
}
|
|
74080
|
+
return value;
|
|
74081
|
+
}
|
|
73943
74082
|
/**
|
|
73944
74083
|
* Reads a duration-typed CLI flag, applying the provided default when the flag is absent.
|
|
73945
74084
|
*/
|
|
@@ -76054,6 +76193,16 @@
|
|
|
76054
76193
|
return `${runnerLabel} \`${normalizedModel}\`${thinkingLevelSuffix}`;
|
|
76055
76194
|
}
|
|
76056
76195
|
|
|
76196
|
+
/**
|
|
76197
|
+
* Replaces the complete todo status line while preserving its indentation.
|
|
76198
|
+
*
|
|
76199
|
+
* The complete line is replaced because a todo status can contain a required
|
|
76200
|
+
* model/harness token in addition to priority markers.
|
|
76201
|
+
*/
|
|
76202
|
+
function replacePromptTodoStatusLine(line, replacementStatusLine) {
|
|
76203
|
+
return line.replace(/^(?<indentation>\s*)\[\s*\].*$/u, `$<indentation>${replacementStatusLine}`);
|
|
76204
|
+
}
|
|
76205
|
+
|
|
76057
76206
|
/**
|
|
76058
76207
|
* Marks a prompt section as done and records the per-step usage pricing and runner details.
|
|
76059
76208
|
*/
|
|
@@ -76071,8 +76220,8 @@
|
|
|
76071
76220
|
const loginMethodSuffix = loginMethodLabel ? ` (${loginMethodLabel})` : '';
|
|
76072
76221
|
const stepsSummary = formatCoderRunSteps(steps);
|
|
76073
76222
|
const stepsSuffix = stepsSummary === '' ? '' : ` - ${stepsSummary}`;
|
|
76074
|
-
// Replace
|
|
76075
|
-
file.lines[section.statusLineIndex] = line
|
|
76223
|
+
// Replace the complete todo status, including any required model/harness token.
|
|
76224
|
+
file.lines[section.statusLineIndex] = replacePromptTodoStatusLine(line, `[x] ${attemptMetadata}by ${runnerSignature}${loginMethodSuffix}${stepsSuffix}`);
|
|
76076
76225
|
}
|
|
76077
76226
|
|
|
76078
76227
|
/**
|
|
@@ -76090,8 +76239,10 @@
|
|
|
76090
76239
|
const attemptMetadata = formatPromptAttemptMetadata('failed', attemptCount);
|
|
76091
76240
|
const duration = moment__default["default"]().diff(promptExecutionStartedDate);
|
|
76092
76241
|
const durationString = moment__default["default"].duration(duration).humanize();
|
|
76093
|
-
const failureDetails = attemptMetadata === ''
|
|
76094
|
-
|
|
76242
|
+
const failureDetails = attemptMetadata === ''
|
|
76243
|
+
? `failed after ${durationString} by ${runnerSignature}`
|
|
76244
|
+
: `${attemptMetadata}${durationString} by ${runnerSignature}`;
|
|
76245
|
+
file.lines[section.statusLineIndex] = replacePromptTodoStatusLine(line, `[!] ${failureDetails}`);
|
|
76095
76246
|
}
|
|
76096
76247
|
|
|
76097
76248
|
/**
|
|
@@ -77061,17 +77212,18 @@
|
|
|
77061
77212
|
/**
|
|
77062
77213
|
* Lists todo prompts that are ready to run (no authoring placeholders).
|
|
77063
77214
|
*/
|
|
77064
|
-
function listRunnablePrompts(files, priorityFilter = {}) {
|
|
77215
|
+
function listRunnablePrompts(files, priorityFilter = {}, promptRunnerIdentity) {
|
|
77065
77216
|
return listTodoPrompts(files).filter((prompt) => !isPromptToBeWritten(prompt.file, prompt.section) &&
|
|
77066
|
-
isPromptInPriorityFilter(prompt.section, priorityFilter)
|
|
77217
|
+
isPromptInPriorityFilter(prompt.section, priorityFilter) &&
|
|
77218
|
+
isPromptCompatibleWithRunner(prompt.file, prompt.section, promptRunnerIdentity));
|
|
77067
77219
|
}
|
|
77068
77220
|
|
|
77069
77221
|
/**
|
|
77070
77222
|
* Selects the next runnable prompt based on priority.
|
|
77071
77223
|
*/
|
|
77072
|
-
function findNextTodoPrompt(files, priorityFilter = {}) {
|
|
77224
|
+
function findNextTodoPrompt(files, priorityFilter = {}, promptRunnerIdentity) {
|
|
77073
77225
|
let nextPrompt;
|
|
77074
|
-
for (const prompt of listRunnablePrompts(files, priorityFilter)) {
|
|
77226
|
+
for (const prompt of listRunnablePrompts(files, priorityFilter, promptRunnerIdentity)) {
|
|
77075
77227
|
if (!nextPrompt || prompt.section.priority > nextPrompt.section.priority) {
|
|
77076
77228
|
nextPrompt = prompt;
|
|
77077
77229
|
}
|
|
@@ -77082,8 +77234,8 @@
|
|
|
77082
77234
|
/**
|
|
77083
77235
|
* Lists upcoming tasks that are ready to run (no authoring placeholders).
|
|
77084
77236
|
*/
|
|
77085
|
-
function listUpcomingTasks(files, priorityFilter = {}) {
|
|
77086
|
-
return listRunnablePrompts(files, priorityFilter).map(({ file, section }) => ({
|
|
77237
|
+
function listUpcomingTasks(files, priorityFilter = {}, promptRunnerIdentity) {
|
|
77238
|
+
return listRunnablePrompts(files, priorityFilter, promptRunnerIdentity).map(({ file, section }) => ({
|
|
77087
77239
|
label: buildPromptLabelForDisplay(file, section),
|
|
77088
77240
|
summary: buildPromptSummary(file, section),
|
|
77089
77241
|
priority: section.priority,
|
|
@@ -77227,6 +77379,71 @@
|
|
|
77227
77379
|
}
|
|
77228
77380
|
}
|
|
77229
77381
|
|
|
77382
|
+
/**
|
|
77383
|
+
* Creates the one queue prompt used to repair a pre-existing test failure.
|
|
77384
|
+
*/
|
|
77385
|
+
async function createTestBeforeRepairPrompt(options) {
|
|
77386
|
+
const description = spaceTrim((block) => `
|
|
77387
|
+
Fix the existing test failures before implementing any queued coding tasks.
|
|
77388
|
+
|
|
77389
|
+
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.
|
|
77390
|
+
|
|
77391
|
+
## Verification output
|
|
77392
|
+
|
|
77393
|
+
\`\`\`
|
|
77394
|
+
${block(limitTestOutput(options.testOutput))}
|
|
77395
|
+
\`\`\`
|
|
77396
|
+
`);
|
|
77397
|
+
const createdPrompt = await addCoderPrompt({
|
|
77398
|
+
projectPath: options.projectPath,
|
|
77399
|
+
description,
|
|
77400
|
+
priority: 0,
|
|
77401
|
+
});
|
|
77402
|
+
const promptPath = path.join(options.projectPath, createdPrompt.filePath);
|
|
77403
|
+
const promptFile = parsePromptFile(promptPath, await promises.readFile(promptPath, 'utf-8'));
|
|
77404
|
+
const section = promptFile.sections[0];
|
|
77405
|
+
if (!section) {
|
|
77406
|
+
throw new UnexpectedError(spaceTrim(`
|
|
77407
|
+
The pre-coding test repair prompt was created at \`${createdPrompt.filePath}\` without a runnable section.
|
|
77408
|
+
`));
|
|
77409
|
+
}
|
|
77410
|
+
return { file: promptFile, section };
|
|
77411
|
+
}
|
|
77412
|
+
|
|
77413
|
+
/**
|
|
77414
|
+
* Runs the configured verification command before the first coding prompt.
|
|
77415
|
+
*/
|
|
77416
|
+
async function runTestBefore(options) {
|
|
77417
|
+
var _a, _b;
|
|
77418
|
+
const runPromptTestCommandExecutor = (_a = options.runPromptTestCommandExecutor) !== null && _a !== void 0 ? _a : runPromptTestCommand;
|
|
77419
|
+
const initialTestStatusMessage = `Running initial tests before the agent coding starts: ${options.testCommand}`;
|
|
77420
|
+
await ((_b = options.waitForPauseCheckpoint) === null || _b === void 0 ? void 0 : _b.call(options, {
|
|
77421
|
+
checkpointLabel: 'running initial tests before the agent coding starts',
|
|
77422
|
+
phase: 'verifying',
|
|
77423
|
+
statusMessage: initialTestStatusMessage,
|
|
77424
|
+
}));
|
|
77425
|
+
console.info(colors__default["default"].gray(initialTestStatusMessage));
|
|
77426
|
+
try {
|
|
77427
|
+
const testOutput = await runPromptTestCommandExecutor({
|
|
77428
|
+
command: options.testCommand,
|
|
77429
|
+
projectPath: options.projectPath,
|
|
77430
|
+
scriptPath: buildTemporaryPromptScriptPath({
|
|
77431
|
+
projectPath: options.projectPath,
|
|
77432
|
+
scriptDirectoryName: 'coder-prompts',
|
|
77433
|
+
sourceFileName: 'test-before',
|
|
77434
|
+
}),
|
|
77435
|
+
});
|
|
77436
|
+
console.info(colors__default["default"].green('Pre-coding tests passed.'));
|
|
77437
|
+
return { isPassed: true, testOutput };
|
|
77438
|
+
}
|
|
77439
|
+
catch (error) {
|
|
77440
|
+
const testOutput = formatUnknownErrorMessage(error);
|
|
77441
|
+
console.error(colors__default["default"].red('Pre-coding tests failed.'));
|
|
77442
|
+
console.error(testOutput);
|
|
77443
|
+
return { isPassed: false, testOutput };
|
|
77444
|
+
}
|
|
77445
|
+
}
|
|
77446
|
+
|
|
77230
77447
|
/**
|
|
77231
77448
|
* Constant for prompts dir.
|
|
77232
77449
|
*/
|
|
@@ -77254,6 +77471,10 @@
|
|
|
77254
77471
|
return;
|
|
77255
77472
|
}
|
|
77256
77473
|
const { runner, actualRunnerModel, runnerMetadata } = resolvePromptRunner(options);
|
|
77474
|
+
const promptRunnerIdentity = {
|
|
77475
|
+
harnessName: options.agentName,
|
|
77476
|
+
modelName: actualRunnerModel,
|
|
77477
|
+
};
|
|
77257
77478
|
console.info(colors__default["default"].green(`Running prompts with ${runner.name}`));
|
|
77258
77479
|
initializeRunUi(uiHandle, runner.name, actualRunnerModel, options);
|
|
77259
77480
|
await initializeRunUiAgentVisual(uiHandle, resolvedCoderAgent === null || resolvedCoderAgent === void 0 ? void 0 : resolvedCoderAgent.agentSource);
|
|
@@ -77268,6 +77489,7 @@
|
|
|
77268
77489
|
let previousRoundStartTime;
|
|
77269
77490
|
let previousRoundEndTime;
|
|
77270
77491
|
let completedRunCount = 0;
|
|
77492
|
+
let hasRunTestBefore = false;
|
|
77271
77493
|
while (just(true)) {
|
|
77272
77494
|
if (options.autoPull && !options.dryRun) {
|
|
77273
77495
|
await waitForRequestedPause({
|
|
@@ -77280,6 +77502,35 @@
|
|
|
77280
77502
|
options,
|
|
77281
77503
|
isRichUiEnabled,
|
|
77282
77504
|
});
|
|
77505
|
+
if (!hasRunTestBefore && options.testBefore !== 'no') {
|
|
77506
|
+
await waitForRequestedPause({
|
|
77507
|
+
checkpointLabel: 'loading prompts before running initial tests',
|
|
77508
|
+
phase: 'loading',
|
|
77509
|
+
statusMessage: 'Loading prompts before running initial tests...',
|
|
77510
|
+
});
|
|
77511
|
+
await loadPromptQueueSnapshot({
|
|
77512
|
+
options,
|
|
77513
|
+
isRichUiEnabled,
|
|
77514
|
+
progressDisplay,
|
|
77515
|
+
uiHandle,
|
|
77516
|
+
promptRunnerIdentity,
|
|
77517
|
+
});
|
|
77518
|
+
}
|
|
77519
|
+
if (!hasRunTestBefore) {
|
|
77520
|
+
hasWaitedForStart = await runTestBeforeIfNeeded({
|
|
77521
|
+
options,
|
|
77522
|
+
runner,
|
|
77523
|
+
runnerMetadata,
|
|
77524
|
+
resolvedCoderContext,
|
|
77525
|
+
resolvedAgentSystemMessage,
|
|
77526
|
+
isRichUiEnabled,
|
|
77527
|
+
progressDisplay,
|
|
77528
|
+
uiHandle,
|
|
77529
|
+
waitForRequestedPause,
|
|
77530
|
+
hasWaitedForStart,
|
|
77531
|
+
});
|
|
77532
|
+
hasRunTestBefore = true;
|
|
77533
|
+
}
|
|
77283
77534
|
await waitForRequestedPause({
|
|
77284
77535
|
checkpointLabel: 'loading prompts',
|
|
77285
77536
|
phase: 'loading',
|
|
@@ -77290,6 +77541,7 @@
|
|
|
77290
77541
|
isRichUiEnabled,
|
|
77291
77542
|
progressDisplay,
|
|
77292
77543
|
uiHandle,
|
|
77544
|
+
promptRunnerIdentity,
|
|
77293
77545
|
});
|
|
77294
77546
|
hasShownUpcomingTasks || (hasShownUpcomingTasks = showUpcomingTasksOnce({
|
|
77295
77547
|
hasShownUpcomingTasks,
|
|
@@ -77297,6 +77549,7 @@
|
|
|
77297
77549
|
stats: promptQueueSnapshot.stats,
|
|
77298
77550
|
priorityFilter: options.priorityFilter,
|
|
77299
77551
|
isRichUiEnabled,
|
|
77552
|
+
promptRunnerIdentity,
|
|
77300
77553
|
}));
|
|
77301
77554
|
if (!promptQueueSnapshot.nextPrompt) {
|
|
77302
77555
|
if (isEndAfterCurrentPromptRequested(completedRunCount)) {
|
|
@@ -77399,6 +77652,14 @@
|
|
|
77399
77652
|
* Validates cross-flag constraints before the run starts.
|
|
77400
77653
|
*/
|
|
77401
77654
|
function validateRunCodexPromptOptions(options) {
|
|
77655
|
+
var _a;
|
|
77656
|
+
if (!isTestBeforeMode((_a = options.testBefore) !== null && _a !== void 0 ? _a : 'no')) {
|
|
77657
|
+
throw new NotAllowed(_spaceTrim.spaceTrim(`
|
|
77658
|
+
Invalid ${'`--test-before`'} mode: \`${String(options.testBefore)}\`.
|
|
77659
|
+
|
|
77660
|
+
Use one of: \`no\`, \`yes-and-fail\`, \`yes-and-fix\`.
|
|
77661
|
+
`));
|
|
77662
|
+
}
|
|
77402
77663
|
if (options.allowDestructiveAutoMigrate && !options.autoMigrate) {
|
|
77403
77664
|
throw new DatabaseError(_spaceTrim.spaceTrim(`
|
|
77404
77665
|
Flag \`--allow-destructive-auto-migrate\` requires \`--auto-migrate\`.
|
|
@@ -77469,20 +77730,103 @@
|
|
|
77469
77730
|
* Normalizes legacy and current priority options into one validated run option shape.
|
|
77470
77731
|
*/
|
|
77471
77732
|
function normalizeRunOptions(options) {
|
|
77472
|
-
var _a, _b, _c, _d, _e;
|
|
77733
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
77734
|
+
const testBefore = (_a = options.testBefore) !== null && _a !== void 0 ? _a : 'no';
|
|
77735
|
+
const normalizedTestCommand = (_b = options.testCommand) === null || _b === void 0 ? void 0 : _b.trim();
|
|
77473
77736
|
const priorityFilter = normalizePriorityFilter({
|
|
77474
77737
|
priority: options.priority,
|
|
77475
|
-
minimumPriority: (
|
|
77476
|
-
maximumPriority: (
|
|
77738
|
+
minimumPriority: (_c = options.minimumPriority) !== null && _c !== void 0 ? _c : (_d = options.priorityFilter) === null || _d === void 0 ? void 0 : _d.minimumPriority,
|
|
77739
|
+
maximumPriority: (_e = options.maximumPriority) !== null && _e !== void 0 ? _e : (_f = options.priorityFilter) === null || _f === void 0 ? void 0 : _f.maximumPriority,
|
|
77477
77740
|
});
|
|
77478
77741
|
return {
|
|
77479
77742
|
...options,
|
|
77480
|
-
|
|
77743
|
+
testBefore,
|
|
77744
|
+
testCommand: normalizedTestCommand || (testBefore === 'no' ? undefined : DEFAULT_CODER_TEST_COMMAND),
|
|
77745
|
+
priority: (_g = priorityFilter.minimumPriority) !== null && _g !== void 0 ? _g : 0,
|
|
77481
77746
|
minimumPriority: priorityFilter.minimumPriority,
|
|
77482
77747
|
maximumPriority: priorityFilter.maximumPriority,
|
|
77483
77748
|
priorityFilter,
|
|
77484
77749
|
};
|
|
77485
77750
|
}
|
|
77751
|
+
/**
|
|
77752
|
+
* Runs the optional pre-coding verification and, when requested, its one repair prompt.
|
|
77753
|
+
*/
|
|
77754
|
+
async function runTestBeforeIfNeeded(options) {
|
|
77755
|
+
const { options: runOptions, runner, runnerMetadata, resolvedCoderContext, resolvedAgentSystemMessage, isRichUiEnabled, progressDisplay, uiHandle, waitForRequestedPause, hasWaitedForStart, } = options;
|
|
77756
|
+
if (runOptions.testBefore === 'no') {
|
|
77757
|
+
return hasWaitedForStart;
|
|
77758
|
+
}
|
|
77759
|
+
if (!runOptions.testCommand) {
|
|
77760
|
+
throw new NotAllowed(_spaceTrim.spaceTrim(`
|
|
77761
|
+
${'`--test-before ' + runOptions.testBefore + '`'} requires a verification command.
|
|
77762
|
+
|
|
77763
|
+
Pass one with ${'`--test <test-command>`'} or use the default ${'`npm test`'} command by providing the mode through the CLI.
|
|
77764
|
+
`));
|
|
77765
|
+
}
|
|
77766
|
+
if (!runOptions.ignoreGitChanges) {
|
|
77767
|
+
await waitForRequestedPause({
|
|
77768
|
+
checkpointLabel: 'checking the git working tree before testing',
|
|
77769
|
+
phase: 'loading',
|
|
77770
|
+
statusMessage: 'Checking the working tree before testing...',
|
|
77771
|
+
});
|
|
77772
|
+
await ensureWorkingTreeClean();
|
|
77773
|
+
}
|
|
77774
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.startCapturingAgentOutput();
|
|
77775
|
+
const testBeforeResult = await runTestBefore({
|
|
77776
|
+
testCommand: runOptions.testCommand,
|
|
77777
|
+
projectPath: process.cwd(),
|
|
77778
|
+
waitForPauseCheckpoint: waitForRequestedPause,
|
|
77779
|
+
}).finally(() => {
|
|
77780
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.stopCapturingAgentOutput();
|
|
77781
|
+
});
|
|
77782
|
+
if (testBeforeResult.isPassed) {
|
|
77783
|
+
return hasWaitedForStart;
|
|
77784
|
+
}
|
|
77785
|
+
const testOutput = limitTestOutput(testBeforeResult.testOutput);
|
|
77786
|
+
if (runOptions.testBefore === 'yes-and-fail') {
|
|
77787
|
+
throw new NotAllowed(_spaceTrim.spaceTrim((block) => `
|
|
77788
|
+
Pre-coding verification command \`${runOptions.testCommand}\` failed.
|
|
77789
|
+
|
|
77790
|
+
The coding agent was not started because the project was already failing before the first queued prompt.
|
|
77791
|
+
|
|
77792
|
+
### Test results
|
|
77793
|
+
${'```'}
|
|
77794
|
+
${block(testOutput)}
|
|
77795
|
+
${'```'}
|
|
77796
|
+
`));
|
|
77797
|
+
}
|
|
77798
|
+
const repairPrompt = await createTestBeforeRepairPrompt({
|
|
77799
|
+
projectPath: process.cwd(),
|
|
77800
|
+
testCommand: runOptions.testCommand,
|
|
77801
|
+
testOutput,
|
|
77802
|
+
});
|
|
77803
|
+
const repairPromptLabel = buildPromptLabelForDisplay(repairPrompt.file, repairPrompt.section);
|
|
77804
|
+
const updatedHasWaitedForStart = await waitForPromptConfirmationIfNeeded({
|
|
77805
|
+
options: runOptions,
|
|
77806
|
+
nextPrompt: repairPrompt,
|
|
77807
|
+
promptLabel: repairPromptLabel,
|
|
77808
|
+
hasWaitedForStart,
|
|
77809
|
+
isRichUiEnabled,
|
|
77810
|
+
progressDisplay,
|
|
77811
|
+
uiHandle,
|
|
77812
|
+
});
|
|
77813
|
+
// The repair prompt is created in the current worktree so it can be recorded and committed with the repair.
|
|
77814
|
+
// It therefore intentionally uses the regular round here even when the queue itself uses --isolate.
|
|
77815
|
+
await runPromptRound({
|
|
77816
|
+
options: runOptions,
|
|
77817
|
+
runner,
|
|
77818
|
+
runnerMetadata,
|
|
77819
|
+
nextPrompt: repairPrompt,
|
|
77820
|
+
promptLabel: repairPromptLabel,
|
|
77821
|
+
resolvedCoderContext,
|
|
77822
|
+
resolvedAgentSystemMessage,
|
|
77823
|
+
isRichUiEnabled,
|
|
77824
|
+
progressDisplay,
|
|
77825
|
+
uiHandle,
|
|
77826
|
+
waitForRequestedPause,
|
|
77827
|
+
});
|
|
77828
|
+
return updatedHasWaitedForStart;
|
|
77829
|
+
}
|
|
77486
77830
|
/**
|
|
77487
77831
|
* Creates a pause waiter that keeps the progress display and rich UI in sync.
|
|
77488
77832
|
*/
|
|
@@ -77567,7 +77911,7 @@
|
|
|
77567
77911
|
* Loads prompt files, updates progress displays, and selects the next runnable prompt.
|
|
77568
77912
|
*/
|
|
77569
77913
|
async function loadPromptQueueSnapshot(options) {
|
|
77570
|
-
const { options: runOptions, isRichUiEnabled, progressDisplay, uiHandle } = options;
|
|
77914
|
+
const { options: runOptions, isRichUiEnabled, progressDisplay, uiHandle, promptRunnerIdentity } = options;
|
|
77571
77915
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setCurrentScriptPath(undefined);
|
|
77572
77916
|
const promptFiles = await loadPromptFiles(PROMPTS_DIR$1);
|
|
77573
77917
|
const stats = summarizePrompts(promptFiles, runOptions.priorityFilter);
|
|
@@ -77579,14 +77923,14 @@
|
|
|
77579
77923
|
return {
|
|
77580
77924
|
promptFiles,
|
|
77581
77925
|
stats,
|
|
77582
|
-
nextPrompt: findNextTodoPrompt(promptFiles, runOptions.priorityFilter),
|
|
77926
|
+
nextPrompt: findNextTodoPrompt(promptFiles, runOptions.priorityFilter, promptRunnerIdentity),
|
|
77583
77927
|
};
|
|
77584
77928
|
}
|
|
77585
77929
|
/**
|
|
77586
77930
|
* Prints upcoming tasks only on the first loop iteration in plain-console mode.
|
|
77587
77931
|
*/
|
|
77588
77932
|
function showUpcomingTasksOnce(options) {
|
|
77589
|
-
const { hasShownUpcomingTasks, promptFiles, stats, priorityFilter, isRichUiEnabled } = options;
|
|
77933
|
+
const { hasShownUpcomingTasks, promptFiles, stats, priorityFilter, isRichUiEnabled, promptRunnerIdentity } = options;
|
|
77590
77934
|
if (hasShownUpcomingTasks || isRichUiEnabled) {
|
|
77591
77935
|
return true;
|
|
77592
77936
|
}
|
|
@@ -77595,7 +77939,7 @@
|
|
|
77595
77939
|
printPromptsToBeWritten(promptFiles, priorityFilter);
|
|
77596
77940
|
console.info('');
|
|
77597
77941
|
}
|
|
77598
|
-
printUpcomingTasks(listUpcomingTasks(promptFiles, priorityFilter));
|
|
77942
|
+
printUpcomingTasks(listUpcomingTasks(promptFiles, priorityFilter, promptRunnerIdentity));
|
|
77599
77943
|
return true;
|
|
77600
77944
|
}
|
|
77601
77945
|
/**
|
|
@@ -77605,7 +77949,10 @@
|
|
|
77605
77949
|
if (promptQueueSnapshot.nextPrompt) {
|
|
77606
77950
|
return false;
|
|
77607
77951
|
}
|
|
77608
|
-
if (promptQueueSnapshot.stats.
|
|
77952
|
+
if (promptQueueSnapshot.stats.forAgent > 0) {
|
|
77953
|
+
announceRunCompletion('No prompts match the selected harness or model.', colors__default["default"].yellow, isRichUiEnabled, uiHandle);
|
|
77954
|
+
}
|
|
77955
|
+
else if (promptQueueSnapshot.stats.toBeWritten > 0) {
|
|
77609
77956
|
announceRunCompletion('No prompts ready for agent.', colors__default["default"].yellow, isRichUiEnabled, uiHandle);
|
|
77610
77957
|
}
|
|
77611
77958
|
else {
|
|
@@ -77646,9 +77993,16 @@
|
|
|
77646
77993
|
* Updates the UI status message while waiting for new prompts in keepAlive server mode.
|
|
77647
77994
|
*/
|
|
77648
77995
|
function announceKeepAliveStatus(promptQueueSnapshot, isRichUiEnabled, uiHandle) {
|
|
77649
|
-
|
|
77650
|
-
|
|
77651
|
-
|
|
77996
|
+
let message;
|
|
77997
|
+
if (promptQueueSnapshot.stats.forAgent > 0) {
|
|
77998
|
+
message = 'No prompts match the selected harness or model. Watching for changes...';
|
|
77999
|
+
}
|
|
78000
|
+
else if (promptQueueSnapshot.stats.toBeWritten > 0) {
|
|
78001
|
+
message = 'No prompts ready for agent. Watching for changes...';
|
|
78002
|
+
}
|
|
78003
|
+
else {
|
|
78004
|
+
message = 'All prompts are done. Watching for changes...';
|
|
78005
|
+
}
|
|
77652
78006
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setStatusMessage(message);
|
|
77653
78007
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setPhase('waiting');
|
|
77654
78008
|
if (!isRichUiEnabled) {
|
|
@@ -77670,7 +78024,7 @@
|
|
|
77670
78024
|
* Waits for the optional user confirmation before starting the selected prompt.
|
|
77671
78025
|
*/
|
|
77672
78026
|
async function waitForPromptConfirmationIfNeeded(options) {
|
|
77673
|
-
const { options: runOptions, nextPrompt, promptLabel, hasWaitedForStart, isRichUiEnabled, progressDisplay, uiHandle } = options;
|
|
78027
|
+
const { options: runOptions, nextPrompt, promptLabel, hasWaitedForStart, isRichUiEnabled, progressDisplay, uiHandle, } = options;
|
|
77674
78028
|
if (!runOptions.waitForUser) {
|
|
77675
78029
|
return hasWaitedForStart;
|
|
77676
78030
|
}
|