@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/esm/index.es.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import colors from 'colors';
|
|
2
2
|
import commander, { Option } from 'commander';
|
|
3
3
|
import _spaceTrim, { spaceTrim as spaceTrim$1 } from 'spacetrim';
|
|
4
|
-
import { writeFile, stat, mkdir, readFile, readdir, rm, cp, lstat, symlink, rename, unlink, appendFile, realpath, copyFile, access, constants, watch, rmdir } from 'fs/promises';
|
|
4
|
+
import { writeFile, stat, mkdir, readFile, readdir, rm, cp, lstat, symlink, rename, unlink, appendFile, realpath, copyFile, access, constants, watch, rmdir, mkdtemp } from 'fs/promises';
|
|
5
5
|
import { join, delimiter, relative, basename, resolve, dirname, isAbsolute, extname } from 'path';
|
|
6
6
|
import { createHash, randomBytes } from 'crypto';
|
|
7
7
|
import { spawn } from 'child_process';
|
|
@@ -9,10 +9,10 @@ import moment from 'moment';
|
|
|
9
9
|
import * as fs from 'fs';
|
|
10
10
|
import { createWriteStream, mkdirSync, writeFileSync, statSync, readFileSync, existsSync, promises } from 'fs';
|
|
11
11
|
import * as dotenv from 'dotenv';
|
|
12
|
-
import prompts from 'prompts';
|
|
13
12
|
import * as readline from 'readline';
|
|
14
13
|
import { emitKeypressEvents, clearLine, cursorTo, createInterface } from 'readline';
|
|
15
14
|
import { forTime, forEver } from 'waitasecond';
|
|
15
|
+
import prompts from 'prompts';
|
|
16
16
|
import hexEncoder from 'crypto-js/enc-hex';
|
|
17
17
|
import sha256 from 'crypto-js/sha256';
|
|
18
18
|
import { io } from 'socket.io-client';
|
|
@@ -37,8 +37,8 @@ import { fileSearchTool, tool, Agent as Agent$1, webSearchTool, run, setDefaultO
|
|
|
37
37
|
import OpenAI from 'openai';
|
|
38
38
|
import * as ts from 'typescript';
|
|
39
39
|
import ignore from 'ignore';
|
|
40
|
-
import { EventEmitter } from 'events';
|
|
41
40
|
import { tmpdir } from 'os';
|
|
41
|
+
import { EventEmitter } from 'events';
|
|
42
42
|
import { lookup, extension } from 'mime-types';
|
|
43
43
|
import papaparse from 'papaparse';
|
|
44
44
|
import { Client } from 'pg';
|
|
@@ -59,7 +59,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
59
59
|
* @generated
|
|
60
60
|
* @see https://github.com/webgptorg/promptbook
|
|
61
61
|
*/
|
|
62
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.114.0-
|
|
62
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.114.0-2';
|
|
63
63
|
/**
|
|
64
64
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
65
65
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -26966,12 +26966,12 @@ function buildControlPills(options) {
|
|
|
26966
26966
|
* Builds the coder-run control pills shown in the footer box.
|
|
26967
26967
|
*/
|
|
26968
26968
|
function buildCoderRunControlPills(options) {
|
|
26969
|
-
const { pauseControl, pendingEnterLabel, isEndAfterCurrentPromptRequested, sessionTotal } = options;
|
|
26969
|
+
const { phase, pauseControl, pendingEnterLabel, isEndAfterCurrentPromptRequested, sessionTotal } = options;
|
|
26970
26970
|
return buildControlPills({
|
|
26971
26971
|
pauseControl,
|
|
26972
26972
|
pendingEnterLabel,
|
|
26973
26973
|
additionalControls: [
|
|
26974
|
-
buildSkipCurrentWaitControl(),
|
|
26974
|
+
...(phase === 'waiting' ? [buildSkipCurrentWaitControl()] : []),
|
|
26975
26975
|
buildEndAfterCurrentPromptControl(isEndAfterCurrentPromptRequested, sessionTotal),
|
|
26976
26976
|
],
|
|
26977
26977
|
});
|
|
@@ -29552,6 +29552,7 @@ function buildCodexScript(options) {
|
|
|
29552
29552
|
` -c model_reasoning_effort="${thinkingLevel}" \\`,
|
|
29553
29553
|
` --ask-for-approval ${options.askForApproval} \\`,
|
|
29554
29554
|
` exec --model ${options.model} \\`,
|
|
29555
|
+
...(options.isMachineReadableProgressEnabled ? [' --json \\'] : []),
|
|
29555
29556
|
' --local-provider none \\',
|
|
29556
29557
|
` --sandbox ${options.sandbox} \\`,
|
|
29557
29558
|
` -C ${projectPath} \\`,
|
|
@@ -29868,6 +29869,10 @@ function matchesAnyPattern(text, patterns) {
|
|
|
29868
29869
|
* Output line that marks finished Codex usage summary.
|
|
29869
29870
|
*/
|
|
29870
29871
|
const CODEX_COMPLETION_LINE = /^\s*tokens used\b/i;
|
|
29872
|
+
/**
|
|
29873
|
+
* Output line that marks the completed Codex turn in JSONL output mode.
|
|
29874
|
+
*/
|
|
29875
|
+
const CODEX_JSON_COMPLETION_LINE = /^\s*\{"type":"turn\.(?:completed|failed)"/u;
|
|
29871
29876
|
/**
|
|
29872
29877
|
* Idle timeout after completion marker to capture trailing output.
|
|
29873
29878
|
*/
|
|
@@ -29944,6 +29949,7 @@ class OpenAiCodexRunner {
|
|
|
29944
29949
|
sandbox: this.options.sandbox,
|
|
29945
29950
|
askForApproval: this.options.askForApproval,
|
|
29946
29951
|
allowCredits: this.options.allowCredits,
|
|
29952
|
+
isMachineReadableProgressEnabled: this.options.isMachineReadableProgressEnabled,
|
|
29947
29953
|
codexCommand: this.options.codexCommand,
|
|
29948
29954
|
});
|
|
29949
29955
|
for (let retryIndex = 0;; retryIndex++) {
|
|
@@ -29958,7 +29964,9 @@ class OpenAiCodexRunner {
|
|
|
29958
29964
|
const output = await $runGoScriptUntilMarkerIdle({
|
|
29959
29965
|
scriptPath: options.scriptPath,
|
|
29960
29966
|
scriptContent,
|
|
29961
|
-
completionLineMatcher:
|
|
29967
|
+
completionLineMatcher: this.options.isMachineReadableProgressEnabled
|
|
29968
|
+
? CODEX_JSON_COMPLETION_LINE
|
|
29969
|
+
: CODEX_COMPLETION_LINE,
|
|
29962
29970
|
idleTimeoutMs: CODEX_COMPLETION_IDLE_MS,
|
|
29963
29971
|
logPath: options.logPath,
|
|
29964
29972
|
shouldPrintLiveOutput: options.shouldPrintLiveOutput,
|
|
@@ -30208,6 +30216,7 @@ function createOpenAiCodexRunnerResolution(options) {
|
|
|
30208
30216
|
sandbox: 'danger-full-access',
|
|
30209
30217
|
askForApproval: 'never',
|
|
30210
30218
|
allowCredits: options.allowCredits,
|
|
30219
|
+
isMachineReadableProgressEnabled: options.isMachineReadableProgressEnabled,
|
|
30211
30220
|
});
|
|
30212
30221
|
if (!options.allowCredits && options.isVerbose === true) {
|
|
30213
30222
|
console.info(colors.gray('OpenAI Codex credit spending is disabled. Use `--allow-credits` to explicitly opt in.'));
|
|
@@ -31443,6 +31452,7 @@ function buildCoderRunUiFrame(options) {
|
|
|
31443
31452
|
: [options.statusMessage, ...options.detailLines.map((detailLine) => `• ${detailLine}`)];
|
|
31444
31453
|
const visibleOutputLines = buildVisibleOutputLines(options.agentOutputLines);
|
|
31445
31454
|
const controls = buildCoderRunControlPills({
|
|
31455
|
+
phase: options.phase,
|
|
31446
31456
|
pauseControl: pausePresentation.pauseControl,
|
|
31447
31457
|
pendingEnterLabel: options.pendingEnterLabel,
|
|
31448
31458
|
isEndAfterCurrentPromptRequested: options.isEndAfterCurrentPromptRequested,
|
|
@@ -32306,6 +32316,7 @@ function createCoderRunOptionsForAgent(options) {
|
|
|
32306
32316
|
autoPull: options.autoPull,
|
|
32307
32317
|
agentName: options.agentName,
|
|
32308
32318
|
model: options.model,
|
|
32319
|
+
isMachineReadableProgressEnabled: options.isMachineReadableProgressEnabled,
|
|
32309
32320
|
priority: 0,
|
|
32310
32321
|
};
|
|
32311
32322
|
}
|
|
@@ -33295,6 +33306,21 @@ function appendCoderContext(prompt, context) {
|
|
|
33295
33306
|
`);
|
|
33296
33307
|
}
|
|
33297
33308
|
|
|
33309
|
+
/**
|
|
33310
|
+
* Maximum amount of test output embedded into an agent prompt.
|
|
33311
|
+
*/
|
|
33312
|
+
const MAX_TEST_OUTPUT_CHARS = 12000;
|
|
33313
|
+
/**
|
|
33314
|
+
* Limits test output while keeping the end of the output, where test runners usually print the failure summary.
|
|
33315
|
+
*/
|
|
33316
|
+
function limitTestOutput(testOutput) {
|
|
33317
|
+
const normalizedTestOutput = testOutput.trim();
|
|
33318
|
+
if (normalizedTestOutput.length <= MAX_TEST_OUTPUT_CHARS) {
|
|
33319
|
+
return normalizedTestOutput;
|
|
33320
|
+
}
|
|
33321
|
+
return `[..., test output truncated to the last ${MAX_TEST_OUTPUT_CHARS} characters...]\n${normalizedTestOutput.slice(-MAX_TEST_OUTPUT_CHARS)}`;
|
|
33322
|
+
}
|
|
33323
|
+
|
|
33298
33324
|
/**
|
|
33299
33325
|
* Runs the configured verification command inside the project root and returns its output.
|
|
33300
33326
|
*/
|
|
@@ -33315,10 +33341,6 @@ async function runPromptTestCommand(options) {
|
|
|
33315
33341
|
* Maximum number of coding attempts allowed for the same prompt when verification keeps failing.
|
|
33316
33342
|
*/
|
|
33317
33343
|
const MAX_PROMPT_TEST_ATTEMPTS = 3;
|
|
33318
|
-
/**
|
|
33319
|
-
* Maximum amount of verification output sent back to the coding agent as retry feedback.
|
|
33320
|
-
*/
|
|
33321
|
-
const MAX_TEST_FEEDBACK_OUTPUT_CHARS = 12000;
|
|
33322
33344
|
/**
|
|
33323
33345
|
* File extension used by generated shell scripts.
|
|
33324
33346
|
*/
|
|
@@ -33364,7 +33386,7 @@ async function runPromptWithTestFeedback(options) {
|
|
|
33364
33386
|
return { ...result, attemptCount, steps };
|
|
33365
33387
|
}
|
|
33366
33388
|
const fullVerificationOutput = formatUnknownErrorDetails(failedVerification.error);
|
|
33367
|
-
const feedbackVerificationOutput =
|
|
33389
|
+
const feedbackVerificationOutput = limitTestOutput(fullVerificationOutput);
|
|
33368
33390
|
if (attemptCount >= MAX_PROMPT_TEST_ATTEMPTS) {
|
|
33369
33391
|
console.error(colors.red(`Verification failed for ${options.promptLabel} after ${attemptCount} attempts.`));
|
|
33370
33392
|
throw new Error(buildFinalVerificationFailureMessage({
|
|
@@ -33494,19 +33516,6 @@ function buildFinalVerificationFailureMessage({ promptLabel, testCommand, attemp
|
|
|
33494
33516
|
\`\`\`
|
|
33495
33517
|
`);
|
|
33496
33518
|
}
|
|
33497
|
-
/**
|
|
33498
|
-
* Limits verification output before it is embedded back into the next coding prompt.
|
|
33499
|
-
*/
|
|
33500
|
-
function limitVerificationOutputForFeedback(verificationOutput) {
|
|
33501
|
-
const normalizedVerificationOutput = verificationOutput.trim();
|
|
33502
|
-
if (normalizedVerificationOutput.length <= MAX_TEST_FEEDBACK_OUTPUT_CHARS) {
|
|
33503
|
-
return normalizedVerificationOutput;
|
|
33504
|
-
}
|
|
33505
|
-
return spaceTrim(`
|
|
33506
|
-
[...verification output truncated to the last ${MAX_TEST_FEEDBACK_OUTPUT_CHARS} characters...]
|
|
33507
|
-
${normalizedVerificationOutput.slice(-MAX_TEST_FEEDBACK_OUTPUT_CHARS)}
|
|
33508
|
-
`);
|
|
33509
|
-
}
|
|
33510
33519
|
/**
|
|
33511
33520
|
* Derives a dedicated temp-script path for verification commands.
|
|
33512
33521
|
*/
|
|
@@ -41367,6 +41376,7 @@ function createLocalAgentRunOptions(options, localAgentRunnerLimits) {
|
|
|
41367
41376
|
autoClone: false,
|
|
41368
41377
|
maxMessageProcessingFailures: localAgentRunnerLimits.maxFailedAttempts,
|
|
41369
41378
|
maxParallelMessages: localAgentRunnerLimits.maxParallelMessages,
|
|
41379
|
+
isMachineReadableProgressEnabled: true,
|
|
41370
41380
|
};
|
|
41371
41381
|
}
|
|
41372
41382
|
|
|
@@ -43481,6 +43491,27 @@ function resolveCheckedHarnessDefinitions(harnessNames) {
|
|
|
43481
43491
|
}
|
|
43482
43492
|
// Note: [🟡] Code for CLI harness installation orchestration [$ensureHarnessInstallations](src/cli/cli-commands/common/harness/$ensureHarnessInstallations.ts) should never be published outside of `@promptbook/cli`
|
|
43483
43493
|
|
|
43494
|
+
/**
|
|
43495
|
+
* Relative path to the Promptbook Coder quick-reference file initialized in project roots.
|
|
43496
|
+
*
|
|
43497
|
+
* @private internal utility of `ptbk coder`
|
|
43498
|
+
*/
|
|
43499
|
+
const AGENT_CODING_FILE_PATH = 'AGENT_CODING.md';
|
|
43500
|
+
/**
|
|
43501
|
+
* Returns the default coder `AGENT_CODING.md` quick-reference content.
|
|
43502
|
+
*
|
|
43503
|
+
* @private internal utility of `ptbk coder`
|
|
43504
|
+
*/
|
|
43505
|
+
function getDefaultCoderAgentCodingFileContent() {
|
|
43506
|
+
return spaceTrim$1(`
|
|
43507
|
+
# ✨ Promptbook Coder agent coding
|
|
43508
|
+
|
|
43509
|
+
This project is using [Promptbook Coder](https://coder.ptbk.io) or run \`ptbk coder\`!
|
|
43510
|
+
`);
|
|
43511
|
+
}
|
|
43512
|
+
// Note: [🟡] Code for coder AGENT_CODING file boilerplate [agentCodingFile](src/cli/cli-commands/coder/agentCodingFile.ts) should never be published outside of `@promptbook/cli`
|
|
43513
|
+
// Note: [💞] Ignore a discrepancy between file name and exported helper names
|
|
43514
|
+
|
|
43484
43515
|
/**
|
|
43485
43516
|
* Relative path to the shared coder context file initialized in project roots.
|
|
43486
43517
|
*
|
|
@@ -43508,106 +43539,6 @@ function getDefaultCoderAgentsFileContent() {
|
|
|
43508
43539
|
// Note: [🟡] Code for coder AGENTS file boilerplate [agentsFile](src/cli/cli-commands/coder/agentsFile.ts) should never be published outside of `@promptbook/cli`
|
|
43509
43540
|
// Note: [💞] Ignore a discrepancy between file name and exported helper names
|
|
43510
43541
|
|
|
43511
|
-
/**
|
|
43512
|
-
* Normalizes one project-relative path for human-readable CLI output and markdown.
|
|
43513
|
-
*
|
|
43514
|
-
* @private internal utility of `ptbk coder`
|
|
43515
|
-
*/
|
|
43516
|
-
function formatDisplayPath(relativePath) {
|
|
43517
|
-
return relativePath.replace(/\\/gu, '/');
|
|
43518
|
-
}
|
|
43519
|
-
// Note: [🟡] Code for coder path formatting [formatDisplayPath](src/cli/cli-commands/coder/formatDisplayPath.ts) should never be published outside of `@promptbook/cli`
|
|
43520
|
-
|
|
43521
|
-
/**
|
|
43522
|
-
* Relative path to the Promptbook Coder quick-reference file initialized in project roots.
|
|
43523
|
-
*
|
|
43524
|
-
* @private internal utility of `ptbk coder`
|
|
43525
|
-
*/
|
|
43526
|
-
const AGENT_CODING_FILE_PATH = 'AGENT_CODING.md';
|
|
43527
|
-
/**
|
|
43528
|
-
* Returns the default coder `AGENT_CODING.md` quick-reference content.
|
|
43529
|
-
*
|
|
43530
|
-
* @private internal utility of `ptbk coder`
|
|
43531
|
-
*/
|
|
43532
|
-
function getDefaultCoderAgentCodingFileContent({ packageJsonScripts, }) {
|
|
43533
|
-
return spaceTrim$1((block) => `
|
|
43534
|
-
# Promptbook Coder quick reference
|
|
43535
|
-
|
|
43536
|
-
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)}/\`.
|
|
43537
|
-
|
|
43538
|
-
## Workflow
|
|
43539
|
-
1. Put repository-wide coding rules into \`${AGENTS_FILE_PATH}\`. The default \`npm run coder:run\` script already passes \`--context ${AGENTS_FILE_PATH}\`.
|
|
43540
|
-
2. Create or customize prompt templates in \`${formatDisplayPath(PROMPTS_TEMPLATES_DIRECTORY_PATH)}/\`. ${buildStarterTemplateSentence()}
|
|
43541
|
-
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"\`.
|
|
43542
|
-
4. Replace every \`@@@\`, keep drafts as \`[-]\`, and switch prompts to \`[ ]\` when they are ready to run. Completed prompts are marked \`[x]\`.
|
|
43543
|
-
5. Run \`npm run coder:run\` to execute the next ready prompt with the configured coding agent.
|
|
43544
|
-
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.
|
|
43545
|
-
7. Use \`ptbk coder find-refactor-candidates\` when you want Promptbook to suggest refactor prompts automatically.
|
|
43546
|
-
|
|
43547
|
-
## Templates
|
|
43548
|
-
- Project-owned templates created by \`ptbk coder init\`: ${formatInlineCodeList(getDefaultCoderProjectPromptTemplateDefinitions().map(({ relativeFilePath }) => formatDisplayPath(relativeFilePath)))}
|
|
43549
|
-
- Built-in \`--template\` aliases: ${formatInlineCodeList(getDefaultCoderPromptTemplateDefinitions().map(({ id }) => id))}
|
|
43550
|
-
- To add a custom template, create a markdown file such as \`${formatDisplayPath(PROMPTS_TEMPLATES_DIRECTORY_PATH)}/backend.md\`.
|
|
43551
|
-
- To use a project template, run \`ptbk coder generate-boilerplates --template ${formatDisplayPath(PROMPTS_TEMPLATES_DIRECTORY_PATH)}/backend.md\`.
|
|
43552
|
-
- 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.
|
|
43553
|
-
|
|
43554
|
-
## Created npm scripts
|
|
43555
|
-
| Script | Purpose |
|
|
43556
|
-
| --- | --- |
|
|
43557
|
-
${block(buildPackageJsonScriptTableLines(packageJsonScripts).join('\n'))}
|
|
43558
|
-
|
|
43559
|
-
## Customizing the workflow
|
|
43560
|
-
- Edit \`package.json\` if you want \`npm run coder:run\` to use another coding agent, model, thinking level, context file, or wait mode.
|
|
43561
|
-
- 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\`.
|
|
43562
|
-
- Use \`ptbk coder --help\` and \`ptbk coder <command> --help\` for the full CLI reference.
|
|
43563
|
-
`);
|
|
43564
|
-
}
|
|
43565
|
-
/**
|
|
43566
|
-
* Builds the sentence describing the starter templates created during initialization.
|
|
43567
|
-
*/
|
|
43568
|
-
function buildStarterTemplateSentence() {
|
|
43569
|
-
const starterTemplatePaths = getDefaultCoderProjectPromptTemplateDefinitions().map(({ relativeFilePath }) => formatDisplayPath(relativeFilePath));
|
|
43570
|
-
if (starterTemplatePaths.length === 1) {
|
|
43571
|
-
return `The starter project template created by \`ptbk coder init\` is \`${starterTemplatePaths[0]}\`.`;
|
|
43572
|
-
}
|
|
43573
|
-
return `The starter project templates created by \`ptbk coder init\` are ${formatInlineCodeList(starterTemplatePaths)}.`;
|
|
43574
|
-
}
|
|
43575
|
-
/**
|
|
43576
|
-
* Builds the markdown table rows describing the initialized npm scripts.
|
|
43577
|
-
*/
|
|
43578
|
-
function buildPackageJsonScriptTableLines(packageJsonScripts) {
|
|
43579
|
-
return Object.entries(packageJsonScripts).map(([scriptName, scriptCommand]) => `| \`npm run ${scriptName}\` | ${describeDefaultCoderPackageJsonScript(scriptName, scriptCommand)} |`);
|
|
43580
|
-
}
|
|
43581
|
-
/**
|
|
43582
|
-
* Describes one initialized npm script in human-readable terms.
|
|
43583
|
-
*/
|
|
43584
|
-
function describeDefaultCoderPackageJsonScript(scriptName, scriptCommand) {
|
|
43585
|
-
if (scriptName === 'coder:generate-boilerplates') {
|
|
43586
|
-
return `Runs \`${scriptCommand}\` to create new prompt files in \`${formatDisplayPath(PROMPTS_DIRECTORY_PATH)}/\`.`;
|
|
43587
|
-
}
|
|
43588
|
-
if (scriptName === 'coder:add') {
|
|
43589
|
-
return `Runs \`${scriptCommand}\` to add one ready-to-run prompt file to \`${formatDisplayPath(PROMPTS_DIRECTORY_PATH)}/\` from a plain-language description.`;
|
|
43590
|
-
}
|
|
43591
|
-
if (scriptName === 'coder:run') {
|
|
43592
|
-
return `Runs \`${scriptCommand}\` to execute the next ready prompt with shared repository context from \`${AGENTS_FILE_PATH}\`.`;
|
|
43593
|
-
}
|
|
43594
|
-
if (scriptName === 'coder:find-refactor-candidates') {
|
|
43595
|
-
return `Runs \`${scriptCommand}\` to generate prompt candidates for large or crowded files.`;
|
|
43596
|
-
}
|
|
43597
|
-
if (scriptName === 'coder:verify') {
|
|
43598
|
-
return `Runs \`${scriptCommand}\` to archive verified prompts into \`${formatDisplayPath(PROMPTS_DONE_DIRECTORY_PATH)}/\` and append repair prompts when needed.`;
|
|
43599
|
-
}
|
|
43600
|
-
return `Runs \`${scriptCommand}\`.`;
|
|
43601
|
-
}
|
|
43602
|
-
/**
|
|
43603
|
-
* Formats one inline code list for human-readable markdown.
|
|
43604
|
-
*/
|
|
43605
|
-
function formatInlineCodeList(values) {
|
|
43606
|
-
return values.map((value) => `\`${value}\``).join(', ');
|
|
43607
|
-
}
|
|
43608
|
-
// Note: [🟡] Code for coder AGENT_CODING file boilerplate [agentCodingFile](src/cli/cli-commands/coder/agentCodingFile.ts) should never be published outside of `@promptbook/cli`
|
|
43609
|
-
// Note: [💞] Ignore a discrepancy between file name and exported helper names
|
|
43610
|
-
|
|
43611
43542
|
/**
|
|
43612
43543
|
* Relative directory path for agents initialized by `ptbk coder init`.
|
|
43613
43544
|
*
|
|
@@ -43672,6 +43603,16 @@ async function isExistingFile$2(path) {
|
|
|
43672
43603
|
}
|
|
43673
43604
|
// Note: [🟡] Code for coder init developer agent bootstrapping [ensureCoderDeveloperAgentFile](src/cli/cli-commands/coder/ensureCoderDeveloperAgentFile.ts) should never be published outside of `@promptbook/cli`
|
|
43674
43605
|
|
|
43606
|
+
/**
|
|
43607
|
+
* Normalizes one project-relative path for human-readable CLI output and markdown.
|
|
43608
|
+
*
|
|
43609
|
+
* @private internal utility of `ptbk coder`
|
|
43610
|
+
*/
|
|
43611
|
+
function formatDisplayPath(relativePath) {
|
|
43612
|
+
return relativePath.replace(/\\/gu, '/');
|
|
43613
|
+
}
|
|
43614
|
+
// Note: [🟡] Code for coder path formatting [formatDisplayPath](src/cli/cli-commands/coder/formatDisplayPath.ts) should never be published outside of `@promptbook/cli`
|
|
43615
|
+
|
|
43675
43616
|
/**
|
|
43676
43617
|
* Fallback `.env` content used when no required variables need to be appended.
|
|
43677
43618
|
*/
|
|
@@ -43749,7 +43690,7 @@ async function ensureCoderGitignoreFile(projectPath) {
|
|
|
43749
43690
|
const DEFAULT_CODER_PACKAGE_JSON_SCRIPTS = {
|
|
43750
43691
|
'coder:generate-boilerplates': 'ptbk coder generate-boilerplates --template ./prompts/templates/common.md',
|
|
43751
43692
|
'coder:add': 'ptbk coder add --template ./prompts/templates/common.md',
|
|
43752
|
-
'coder:run': 'ptbk coder run --harness openai-codex --model gpt-5.
|
|
43693
|
+
'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',
|
|
43753
43694
|
// 'coder:find-refactor-candidates': 'npx ptbk coder find-refactor-candidates',
|
|
43754
43695
|
'coder:verify': 'ptbk coder verify',
|
|
43755
43696
|
};
|
|
@@ -43998,9 +43939,7 @@ async function initializeCoderProjectConfiguration(projectPath) {
|
|
|
43998
43939
|
const agentsDirectoryStatus = await ensureDirectory(projectPath, CODER_AGENTS_DIRECTORY_PATH);
|
|
43999
43940
|
const developerAgentFileStatus = await ensureCoderDeveloperAgentFile(projectPath);
|
|
44000
43941
|
const agentsFileStatus = await ensureCoderMarkdownFile(projectPath, AGENTS_FILE_PATH, getDefaultCoderAgentsFileContent());
|
|
44001
|
-
const agentCodingFileStatus = await ensureCoderMarkdownFile(projectPath, AGENT_CODING_FILE_PATH, getDefaultCoderAgentCodingFileContent(
|
|
44002
|
-
packageJsonScripts: getDefaultCoderPackageJsonScripts(),
|
|
44003
|
-
}));
|
|
43942
|
+
const agentCodingFileStatus = await ensureCoderMarkdownFile(projectPath, AGENT_CODING_FILE_PATH, getDefaultCoderAgentCodingFileContent());
|
|
44004
43943
|
const { envFileStatus, initializedEnvVariableNames } = await ensureCoderEnvFile(projectPath);
|
|
44005
43944
|
const gitignoreFileStatus = await ensureCoderGitignoreFile(projectPath);
|
|
44006
43945
|
const packageJsonFileStatus = await ensureCoderPackageJsonFile(projectPath);
|
|
@@ -44141,6 +44080,66 @@ function listDefaultCoderProjectPromptTemplateDisplayPaths() {
|
|
|
44141
44080
|
// Note: [🟡] Code for CLI command [init](src/cli/cli-commands/coder/init.ts) should never be published outside of `@promptbook/cli`
|
|
44142
44081
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
44143
44082
|
|
|
44083
|
+
/**
|
|
44084
|
+
* Initializes `coder ping` command for Promptbook CLI utilities.
|
|
44085
|
+
*
|
|
44086
|
+
* The command makes one small, isolated harness/model call, prints its result
|
|
44087
|
+
* and reports how long the harness/model turn took.
|
|
44088
|
+
*
|
|
44089
|
+
* Note: `$` is used to indicate that this function is not a pure function - it registers a command in the CLI.
|
|
44090
|
+
*
|
|
44091
|
+
* @private internal function of `promptbookCli`
|
|
44092
|
+
*/
|
|
44093
|
+
function $initializeCoderPingCommand(program) {
|
|
44094
|
+
const command = program.command('ping');
|
|
44095
|
+
command.description(spaceTrim$1(`
|
|
44096
|
+
Test one harness and model connection with a small disposable task
|
|
44097
|
+
|
|
44098
|
+
${PROMPT_RUNNER_DESCRIPTION}
|
|
44099
|
+
|
|
44100
|
+
Features:
|
|
44101
|
+
- Runs the dummy task in a temporary directory outside the current project
|
|
44102
|
+
- Prints the result returned by the selected harness and model
|
|
44103
|
+
- Reports the elapsed harness/model response time in milliseconds
|
|
44104
|
+
- Can be used to start consuming an applicable harness/model quota before a longer run
|
|
44105
|
+
`));
|
|
44106
|
+
addPromptRunnerSelectionOptions(command);
|
|
44107
|
+
addPromptRunnerRuntimeOptions(command);
|
|
44108
|
+
command.action(handleActionErrors(async (cliOptions) => {
|
|
44109
|
+
const normalizedOptions = normalizePromptRunnerSelectionCliOptions(cliOptions, { isAgentRequired: true });
|
|
44110
|
+
const agentName = normalizedOptions.agentName;
|
|
44111
|
+
if (!agentName) {
|
|
44112
|
+
throw new NotAllowed(spaceTrim$1(`
|
|
44113
|
+
A harness is required for \`ptbk coder ping\`.
|
|
44114
|
+
|
|
44115
|
+
Pass one with \`--harness <harness-name>\`.
|
|
44116
|
+
`));
|
|
44117
|
+
}
|
|
44118
|
+
await $ensureHarnessInstallations([agentName]);
|
|
44119
|
+
// Note: Import the runner-backed implementation dynamically to avoid loading heavy dependencies until needed.
|
|
44120
|
+
const { runCoderPing } = await Promise.resolve().then(function () { return runCoderPing$1; });
|
|
44121
|
+
const pingResult = await runCoderPing({
|
|
44122
|
+
agentName,
|
|
44123
|
+
model: normalizedOptions.model,
|
|
44124
|
+
thinkingLevel: normalizedOptions.thinkingLevel,
|
|
44125
|
+
isUiDisabled: normalizedOptions.noUi,
|
|
44126
|
+
isCreditsAllowed: normalizedOptions.allowCredits,
|
|
44127
|
+
});
|
|
44128
|
+
printCoderPingResult(pingResult);
|
|
44129
|
+
}));
|
|
44130
|
+
}
|
|
44131
|
+
/**
|
|
44132
|
+
* Prints the result and duration of one completed coder ping.
|
|
44133
|
+
*/
|
|
44134
|
+
function printCoderPingResult(pingResult) {
|
|
44135
|
+
console.info(spaceTrim$1(`
|
|
44136
|
+
Result: ${pingResult.result}
|
|
44137
|
+
Time: ${pingResult.elapsedTimeMs.toFixed(0)} ms
|
|
44138
|
+
`));
|
|
44139
|
+
}
|
|
44140
|
+
// Note: [🟡] Code for CLI command [ping](src/cli/cli-commands/coder/ping.ts) should never be published outside of `@promptbook/cli`
|
|
44141
|
+
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
44142
|
+
|
|
44144
44143
|
/**
|
|
44145
44144
|
* Creates a Commander argument parser that accepts only non-negative integers.
|
|
44146
44145
|
*
|
|
@@ -44165,6 +44164,21 @@ function createNonNegativeIntegerOptionParser(optionName) {
|
|
|
44165
44164
|
}
|
|
44166
44165
|
// Note: [🟡] Code for CLI option parser [createNonNegativeIntegerOptionParser](src/cli/cli-commands/common/createNonNegativeIntegerOptionParser.ts) should never be published outside of `@promptbook/cli`
|
|
44167
44166
|
|
|
44167
|
+
/**
|
|
44168
|
+
* Modes supported by `ptbk coder run --test-before`.
|
|
44169
|
+
*/
|
|
44170
|
+
const TEST_BEFORE_MODE_VALUES = ['no', 'yes-and-fail', 'yes-and-fix'];
|
|
44171
|
+
/**
|
|
44172
|
+
* Default verification command used when a pre-coding mode is enabled without an explicit `--test` command.
|
|
44173
|
+
*/
|
|
44174
|
+
const DEFAULT_CODER_TEST_COMMAND = 'npm test';
|
|
44175
|
+
/**
|
|
44176
|
+
* Checks whether a value is a supported `--test-before` mode.
|
|
44177
|
+
*/
|
|
44178
|
+
function isTestBeforeMode(value) {
|
|
44179
|
+
return TEST_BEFORE_MODE_VALUES.includes(value);
|
|
44180
|
+
}
|
|
44181
|
+
|
|
44168
44182
|
/**
|
|
44169
44183
|
* Default wait duration applied before retrying a prompt round after an error (10 minutes).
|
|
44170
44184
|
*
|
|
@@ -44209,6 +44223,7 @@ function $initializeCoderRunCommand(program) {
|
|
|
44209
44223
|
- Optional --no-ui keeps plain streaming console output for logging and debugging
|
|
44210
44224
|
- Checks that the selected harness is installed globally and up to date before the first prompt
|
|
44211
44225
|
- Supports GPG signing of commits
|
|
44226
|
+
- Optional pre-coding test run that can stop or repair pre-existing failures
|
|
44212
44227
|
- Optional post-prompt verification with test-feedback retries
|
|
44213
44228
|
- Progress tracking and interactive P/S/X terminal controls
|
|
44214
44229
|
- Dry-run mode to preview prompts
|
|
@@ -44218,6 +44233,9 @@ function $initializeCoderRunCommand(program) {
|
|
|
44218
44233
|
command.option('--agent <agent-book-path>', 'Path to a .book file whose compiled system message is prepended to each coding prompt');
|
|
44219
44234
|
command.option('--context <context-or-file>', 'Append extra instructions either inline or from a file path relative to the current project');
|
|
44220
44235
|
command.option('--test <test-command...>', 'Run a verification command after each prompt; quote it when the command itself contains top-level flags');
|
|
44236
|
+
command.addOption(new Option('--test-before <mode>', `Run tests before coding: ${TEST_BEFORE_MODE_VALUES.join(', ')} (defaults to no; uses npm test when --test is omitted)`)
|
|
44237
|
+
.choices([...TEST_BEFORE_MODE_VALUES])
|
|
44238
|
+
.default('no'));
|
|
44221
44239
|
command.option('--preserve-logs', 'Keep generated temp prompt/log artifacts after successful rounds for debugging and analytics', false);
|
|
44222
44240
|
addPromptRunnerExecutionOptions(command);
|
|
44223
44241
|
command.option('--isolate', spaceTrim$1(`
|
|
@@ -44247,8 +44265,9 @@ function $initializeCoderRunCommand(program) {
|
|
|
44247
44265
|
command.option('--auto-migrate', 'Run testing-server database migrations automatically after each successfully processed prompt');
|
|
44248
44266
|
command.option('--allow-destructive-auto-migrate', 'Allow auto-migrate even when heuristic SQL safety check flags destructive pending migrations');
|
|
44249
44267
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
44250
|
-
const { dryRun, agent, context, test, preserveLogs, isolate: isIsolated, priority, minPriority: minimumPriority, maxPriority: maximumPriority, limit, waitAfterPrompt: waitAfterPromptValue, waitBetweenPrompts: waitBetweenPromptsValue, waitAfterError: waitAfterErrorValue, auto, autoMigrate, allowDestructiveAutoMigrate, } = cliOptions;
|
|
44251
|
-
const
|
|
44268
|
+
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;
|
|
44269
|
+
const configuredTestCommand = normalizeCommandOptionValue$1(test);
|
|
44270
|
+
const testCommand = configuredTestCommand !== null && configuredTestCommand !== void 0 ? configuredTestCommand : (testBefore === 'no' ? undefined : DEFAULT_CODER_TEST_COMMAND);
|
|
44252
44271
|
const runnerOptions = normalizePromptRunnerCliOptions(cliOptions, {
|
|
44253
44272
|
isAgentRequired: !dryRun,
|
|
44254
44273
|
});
|
|
@@ -44277,6 +44296,7 @@ function $initializeCoderRunCommand(program) {
|
|
|
44277
44296
|
agent,
|
|
44278
44297
|
context,
|
|
44279
44298
|
testCommand,
|
|
44299
|
+
testBefore,
|
|
44280
44300
|
preserveLogs,
|
|
44281
44301
|
isIsolated,
|
|
44282
44302
|
noUi: runnerOptions.noUi,
|
|
@@ -44533,6 +44553,7 @@ function collectStringOption(value, previousValues) {
|
|
|
44533
44553
|
* - add: Add one ready-to-run prompt file to the queue
|
|
44534
44554
|
* - generate-boilerplates: Generate prompt boilerplate files
|
|
44535
44555
|
* - find-refactor-candidates: Find files that need refactoring
|
|
44556
|
+
* - ping: Test one harness and model connection with a disposable task
|
|
44536
44557
|
* - run: Run coding prompts with AI agents
|
|
44537
44558
|
* - verify: Verify completed prompts
|
|
44538
44559
|
* - find-fresh-emoji-tags: Find unused emoji tags
|
|
@@ -44552,6 +44573,7 @@ function $initializeCoderCommand(program) {
|
|
|
44552
44573
|
- generate-boilerplates: Generate prompt boilerplate files
|
|
44553
44574
|
- find-refactor-candidates: Find files that need refactoring
|
|
44554
44575
|
- find-unwritten: List prompt sections that still need to be authored
|
|
44576
|
+
- ping: Test one harness and model connection with a disposable task
|
|
44555
44577
|
- run: Run coding prompts with AI agents
|
|
44556
44578
|
- server: Start a long-running coder server with a kanban web UI
|
|
44557
44579
|
- verify: Verify completed prompts
|
|
@@ -44563,6 +44585,7 @@ function $initializeCoderCommand(program) {
|
|
|
44563
44585
|
$initializeCoderGenerateBoilerplatesCommand(coderCommand);
|
|
44564
44586
|
$initializeCoderFindRefactorCandidatesCommand(coderCommand);
|
|
44565
44587
|
$initializeCoderFindUnwrittenCommand(coderCommand);
|
|
44588
|
+
$initializeCoderPingCommand(coderCommand);
|
|
44566
44589
|
$initializeCoderRunCommand(coderCommand);
|
|
44567
44590
|
$initializeCoderServerCommand(coderCommand);
|
|
44568
44591
|
$initializeCoderVerifyCommand(coderCommand);
|
|
@@ -73589,6 +73612,41 @@ function listPromptsToBeWritten(files, priorityFilter = {}) {
|
|
|
73589
73612
|
isPromptInPriorityFilter(prompt.section, priorityFilter));
|
|
73590
73613
|
}
|
|
73591
73614
|
|
|
73615
|
+
/**
|
|
73616
|
+
* Checks whether a prompt is unrestricted or matches the selected harness/model.
|
|
73617
|
+
*
|
|
73618
|
+
* A prompt status line can contain one or more backtick-delimited model or harness
|
|
73619
|
+
* names. Matching is intentionally based on normalized substrings so a token such as
|
|
73620
|
+
* `gpt` selects any `gpt-*` model and `opus` selects a `claude-opus-*` model.
|
|
73621
|
+
*/
|
|
73622
|
+
function isPromptCompatibleWithRunner(file, section, promptRunnerIdentity) {
|
|
73623
|
+
if (promptRunnerIdentity === undefined) {
|
|
73624
|
+
return true;
|
|
73625
|
+
}
|
|
73626
|
+
const statusLine = section.statusLineIndex === undefined ? undefined : file.lines[section.statusLineIndex];
|
|
73627
|
+
const requiredRunnerTokens = statusLine === undefined ? [] : extractPromptRunnerTokens(statusLine);
|
|
73628
|
+
if (requiredRunnerTokens.length === 0) {
|
|
73629
|
+
return true;
|
|
73630
|
+
}
|
|
73631
|
+
const normalizedRunnerNames = [promptRunnerIdentity.harnessName, promptRunnerIdentity.modelName]
|
|
73632
|
+
.filter((name) => name !== undefined && name.trim() !== '')
|
|
73633
|
+
.map((name) => normalizeToKebabCase(name))
|
|
73634
|
+
.filter((name) => name !== '');
|
|
73635
|
+
return requiredRunnerTokens.some((requiredRunnerToken) => {
|
|
73636
|
+
const normalizedRequiredRunnerToken = normalizeToKebabCase(requiredRunnerToken);
|
|
73637
|
+
return (normalizedRequiredRunnerToken !== '' &&
|
|
73638
|
+
normalizedRunnerNames.some((normalizedRunnerName) => normalizedRunnerName.includes(normalizedRequiredRunnerToken)));
|
|
73639
|
+
});
|
|
73640
|
+
}
|
|
73641
|
+
/**
|
|
73642
|
+
* Extracts model and harness tokens from a prompt status line.
|
|
73643
|
+
*/
|
|
73644
|
+
function extractPromptRunnerTokens(statusLine) {
|
|
73645
|
+
return Array.from(statusLine.matchAll(/`([^`]+)`/gu))
|
|
73646
|
+
.map((match) => { var _a, _b; return (_b = (_a = match[1]) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : ''; })
|
|
73647
|
+
.filter((token) => token !== '');
|
|
73648
|
+
}
|
|
73649
|
+
|
|
73592
73650
|
/**
|
|
73593
73651
|
* Parses a prompt markdown file into sections and metadata.
|
|
73594
73652
|
*/
|
|
@@ -73636,11 +73694,11 @@ function parsePromptFile(filePath, content) {
|
|
|
73636
73694
|
};
|
|
73637
73695
|
}
|
|
73638
73696
|
/**
|
|
73639
|
-
* Parses a status line like "[ ] !!"
|
|
73697
|
+
* Parses a status line like "[ ] !!", "[ ] use `gpt` !!!!!" or "[-]" into status and priority.
|
|
73640
73698
|
* For [x] done and [!] failed prompts, allow metadata after the status marker.
|
|
73641
73699
|
*/
|
|
73642
73700
|
function parseStatusLine(line) {
|
|
73643
|
-
var _a, _b, _c, _d
|
|
73701
|
+
var _a, _b, _c, _d;
|
|
73644
73702
|
// For done prompts [x], allow any content after (for cost/time metadata)
|
|
73645
73703
|
const doneMatch = line.match(/^\[(?<status>[xX])\]/);
|
|
73646
73704
|
if (doneMatch) {
|
|
@@ -73651,21 +73709,23 @@ function parseStatusLine(line) {
|
|
|
73651
73709
|
if (failedMatch) {
|
|
73652
73710
|
return { status: 'failed', priority: 0 };
|
|
73653
73711
|
}
|
|
73654
|
-
// For
|
|
73655
|
-
|
|
73656
|
-
|
|
73657
|
-
return undefined;
|
|
73712
|
+
// For not-ready [-], keep the historical clean-line syntax.
|
|
73713
|
+
if (/^\[-\]\s*!*\s*$/u.test(line)) {
|
|
73714
|
+
return { status: 'not-ready', priority: 0 };
|
|
73658
73715
|
}
|
|
73659
|
-
|
|
73660
|
-
|
|
73661
|
-
|
|
73662
|
-
|
|
73716
|
+
// Todo [ ] may contain backtick-delimited model/harness tokens and priority markers
|
|
73717
|
+
// before or after those tokens. Other trailing text remains an invalid status line.
|
|
73718
|
+
const todoMatch = line.match(/^\[ \](?<details>.*)$/u);
|
|
73719
|
+
if (!todoMatch) {
|
|
73720
|
+
return undefined;
|
|
73663
73721
|
}
|
|
73664
|
-
|
|
73665
|
-
|
|
73722
|
+
const details = (_b = (_a = todoMatch.groups) === null || _a === void 0 ? void 0 : _a.details) !== null && _b !== void 0 ? _b : '';
|
|
73723
|
+
const isPriorityOnly = /^[!\s]*$/u.test(details);
|
|
73724
|
+
const hasPromptRunnerTokens = extractPromptRunnerTokens(line).length > 0;
|
|
73725
|
+
if (details.trim() !== '' && !isPriorityOnly && !hasPromptRunnerTokens) {
|
|
73726
|
+
return undefined;
|
|
73666
73727
|
}
|
|
73667
|
-
|
|
73668
|
-
return { status, priority };
|
|
73728
|
+
return { status: 'todo', priority: (_d = (_c = details.match(/!/gu)) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0 };
|
|
73669
73729
|
}
|
|
73670
73730
|
/**
|
|
73671
73731
|
* Finds the first non-empty line index between two bounds.
|
|
@@ -73801,6 +73861,66 @@ var findUnwrittenPrompts$1 = /*#__PURE__*/Object.freeze({
|
|
|
73801
73861
|
findUnwrittenPrompts: findUnwrittenPrompts
|
|
73802
73862
|
});
|
|
73803
73863
|
|
|
73864
|
+
/**
|
|
73865
|
+
* Agent source used by `ptbk coder ping` for its disposable connectivity turn.
|
|
73866
|
+
*/
|
|
73867
|
+
const PING_AGENT_SOURCE = spaceTrim$1(`
|
|
73868
|
+
Promptbook Coder Ping Agent
|
|
73869
|
+
|
|
73870
|
+
PERSONA You are a connectivity test agent. Perform only the tiny task requested by the user and answer concisely.
|
|
73871
|
+
`);
|
|
73872
|
+
/**
|
|
73873
|
+
* User message used by `ptbk coder ping` to produce a deterministic response.
|
|
73874
|
+
*/
|
|
73875
|
+
const PING_MESSAGE = 'Reply with exactly the single word PONG and nothing else.';
|
|
73876
|
+
/**
|
|
73877
|
+
* Runs one small harness/model turn in a disposable temporary project.
|
|
73878
|
+
*
|
|
73879
|
+
* The temporary project is outside the caller's repository, so even a harness
|
|
73880
|
+
* that writes files cannot change the project from which `ptbk coder ping` was
|
|
73881
|
+
* started.
|
|
73882
|
+
*/
|
|
73883
|
+
async function runCoderPing(options) {
|
|
73884
|
+
const temporaryProjectPath = await mkdtemp(join(tmpdir(), 'promptbook-coder-ping-'));
|
|
73885
|
+
const originalWorkingDirectory = process.cwd();
|
|
73886
|
+
try {
|
|
73887
|
+
const agentPath = join(temporaryProjectPath, 'ping.book');
|
|
73888
|
+
await writeFile(agentPath, `${PING_AGENT_SOURCE}\n`, 'utf-8');
|
|
73889
|
+
// Note: Some supported CLI wrappers inherit the Node process working directory instead of using projectPath.
|
|
73890
|
+
process.chdir(temporaryProjectPath);
|
|
73891
|
+
const startedAt = performance.now();
|
|
73892
|
+
const result = await executeAgentChatTurn({
|
|
73893
|
+
agentPath,
|
|
73894
|
+
currentWorkingDirectory: temporaryProjectPath,
|
|
73895
|
+
agentName: options.agentName,
|
|
73896
|
+
model: options.model,
|
|
73897
|
+
isVerbose: false,
|
|
73898
|
+
noUi: options.isUiDisabled,
|
|
73899
|
+
thinkingLevel: options.thinkingLevel,
|
|
73900
|
+
allowCredits: options.isCreditsAllowed,
|
|
73901
|
+
messages: [
|
|
73902
|
+
{
|
|
73903
|
+
sender: 'USER',
|
|
73904
|
+
content: PING_MESSAGE,
|
|
73905
|
+
},
|
|
73906
|
+
],
|
|
73907
|
+
});
|
|
73908
|
+
return {
|
|
73909
|
+
result: result.answer,
|
|
73910
|
+
elapsedTimeMs: performance.now() - startedAt,
|
|
73911
|
+
};
|
|
73912
|
+
}
|
|
73913
|
+
finally {
|
|
73914
|
+
process.chdir(originalWorkingDirectory);
|
|
73915
|
+
await rm(temporaryProjectPath, { recursive: true, force: true });
|
|
73916
|
+
}
|
|
73917
|
+
}
|
|
73918
|
+
|
|
73919
|
+
var runCoderPing$1 = /*#__PURE__*/Object.freeze({
|
|
73920
|
+
__proto__: null,
|
|
73921
|
+
runCoderPing: runCoderPing
|
|
73922
|
+
});
|
|
73923
|
+
|
|
73804
73924
|
/**
|
|
73805
73925
|
* Default wait duration applied before retrying a failed prompt round.
|
|
73806
73926
|
*/
|
|
@@ -73808,7 +73928,7 @@ const DEFAULT_WAIT_AFTER_ERROR_MS = 10 * 60 * 1000;
|
|
|
73808
73928
|
/**
|
|
73809
73929
|
* CLI usage text for this script.
|
|
73810
73930
|
*/
|
|
73811
|
-
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]';
|
|
73931
|
+
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]';
|
|
73812
73932
|
/**
|
|
73813
73933
|
* Top-level flags supported by this command.
|
|
73814
73934
|
*/
|
|
@@ -73818,6 +73938,7 @@ const KNOWN_OPTION_FLAGS = new Set([
|
|
|
73818
73938
|
'--model',
|
|
73819
73939
|
'--context',
|
|
73820
73940
|
'--test',
|
|
73941
|
+
'--test-before',
|
|
73821
73942
|
'--preserve-logs',
|
|
73822
73943
|
'--isolate',
|
|
73823
73944
|
'--no-ui',
|
|
@@ -73856,6 +73977,8 @@ function parseRunOptions(args) {
|
|
|
73856
73977
|
const context = readOptionValue(args, '--context');
|
|
73857
73978
|
const hasTestCommandFlag = args.includes('--test');
|
|
73858
73979
|
const testCommand = readVariadicOptionValue(args, '--test');
|
|
73980
|
+
const hasTestBeforeFlag = args.includes('--test-before');
|
|
73981
|
+
const testBefore = parseTestBeforeOption(readOptionValue(args, '--test-before'), hasTestBeforeFlag);
|
|
73859
73982
|
const preserveLogs = args.includes('--preserve-logs');
|
|
73860
73983
|
const isIsolated = args.includes('--isolate');
|
|
73861
73984
|
const noUi = args.includes('--no-ui');
|
|
@@ -73928,6 +74051,7 @@ function parseRunOptions(args) {
|
|
|
73928
74051
|
model,
|
|
73929
74052
|
context,
|
|
73930
74053
|
testCommand,
|
|
74054
|
+
testBefore,
|
|
73931
74055
|
thinkingLevel,
|
|
73932
74056
|
priority: minimumPriority !== null && minimumPriority !== void 0 ? minimumPriority : 0,
|
|
73933
74057
|
minimumPriority,
|
|
@@ -73936,6 +74060,21 @@ function parseRunOptions(args) {
|
|
|
73936
74060
|
limit,
|
|
73937
74061
|
};
|
|
73938
74062
|
}
|
|
74063
|
+
/**
|
|
74064
|
+
* Parses and validates the optional pre-coding verification mode.
|
|
74065
|
+
*/
|
|
74066
|
+
function parseTestBeforeOption(value, hasTestBeforeFlag) {
|
|
74067
|
+
if (value === undefined) {
|
|
74068
|
+
if (hasTestBeforeFlag) {
|
|
74069
|
+
exitWithUsageError(`Missing value for --test-before. Use one of: ${TEST_BEFORE_MODE_VALUES.join(', ')}.`);
|
|
74070
|
+
}
|
|
74071
|
+
return 'no';
|
|
74072
|
+
}
|
|
74073
|
+
if (!isTestBeforeMode(value)) {
|
|
74074
|
+
exitWithUsageError(`Invalid value for --test-before: "${value}". Use one of: ${TEST_BEFORE_MODE_VALUES.join(', ')}.`);
|
|
74075
|
+
}
|
|
74076
|
+
return value;
|
|
74077
|
+
}
|
|
73939
74078
|
/**
|
|
73940
74079
|
* Reads a duration-typed CLI flag, applying the provided default when the flag is absent.
|
|
73941
74080
|
*/
|
|
@@ -76050,6 +76189,16 @@ function formatRunnerSignature(runnerName, modelName, thinkingLevel) {
|
|
|
76050
76189
|
return `${runnerLabel} \`${normalizedModel}\`${thinkingLevelSuffix}`;
|
|
76051
76190
|
}
|
|
76052
76191
|
|
|
76192
|
+
/**
|
|
76193
|
+
* Replaces the complete todo status line while preserving its indentation.
|
|
76194
|
+
*
|
|
76195
|
+
* The complete line is replaced because a todo status can contain a required
|
|
76196
|
+
* model/harness token in addition to priority markers.
|
|
76197
|
+
*/
|
|
76198
|
+
function replacePromptTodoStatusLine(line, replacementStatusLine) {
|
|
76199
|
+
return line.replace(/^(?<indentation>\s*)\[\s*\].*$/u, `$<indentation>${replacementStatusLine}`);
|
|
76200
|
+
}
|
|
76201
|
+
|
|
76053
76202
|
/**
|
|
76054
76203
|
* Marks a prompt section as done and records the per-step usage pricing and runner details.
|
|
76055
76204
|
*/
|
|
@@ -76067,8 +76216,8 @@ function markPromptDone(file, section, steps, runnerName, modelName, attemptCoun
|
|
|
76067
76216
|
const loginMethodSuffix = loginMethodLabel ? ` (${loginMethodLabel})` : '';
|
|
76068
76217
|
const stepsSummary = formatCoderRunSteps(steps);
|
|
76069
76218
|
const stepsSuffix = stepsSummary === '' ? '' : ` - ${stepsSummary}`;
|
|
76070
|
-
// Replace
|
|
76071
|
-
file.lines[section.statusLineIndex] = line
|
|
76219
|
+
// Replace the complete todo status, including any required model/harness token.
|
|
76220
|
+
file.lines[section.statusLineIndex] = replacePromptTodoStatusLine(line, `[x] ${attemptMetadata}by ${runnerSignature}${loginMethodSuffix}${stepsSuffix}`);
|
|
76072
76221
|
}
|
|
76073
76222
|
|
|
76074
76223
|
/**
|
|
@@ -76086,8 +76235,10 @@ function markPromptFailed(file, section, runnerName, modelName, promptExecutionS
|
|
|
76086
76235
|
const attemptMetadata = formatPromptAttemptMetadata('failed', attemptCount);
|
|
76087
76236
|
const duration = moment().diff(promptExecutionStartedDate);
|
|
76088
76237
|
const durationString = moment.duration(duration).humanize();
|
|
76089
|
-
const failureDetails = attemptMetadata === ''
|
|
76090
|
-
|
|
76238
|
+
const failureDetails = attemptMetadata === ''
|
|
76239
|
+
? `failed after ${durationString} by ${runnerSignature}`
|
|
76240
|
+
: `${attemptMetadata}${durationString} by ${runnerSignature}`;
|
|
76241
|
+
file.lines[section.statusLineIndex] = replacePromptTodoStatusLine(line, `[!] ${failureDetails}`);
|
|
76091
76242
|
}
|
|
76092
76243
|
|
|
76093
76244
|
/**
|
|
@@ -77057,17 +77208,18 @@ function toProjectRelativeGitPath(projectPath, path) {
|
|
|
77057
77208
|
/**
|
|
77058
77209
|
* Lists todo prompts that are ready to run (no authoring placeholders).
|
|
77059
77210
|
*/
|
|
77060
|
-
function listRunnablePrompts(files, priorityFilter = {}) {
|
|
77211
|
+
function listRunnablePrompts(files, priorityFilter = {}, promptRunnerIdentity) {
|
|
77061
77212
|
return listTodoPrompts(files).filter((prompt) => !isPromptToBeWritten(prompt.file, prompt.section) &&
|
|
77062
|
-
isPromptInPriorityFilter(prompt.section, priorityFilter)
|
|
77213
|
+
isPromptInPriorityFilter(prompt.section, priorityFilter) &&
|
|
77214
|
+
isPromptCompatibleWithRunner(prompt.file, prompt.section, promptRunnerIdentity));
|
|
77063
77215
|
}
|
|
77064
77216
|
|
|
77065
77217
|
/**
|
|
77066
77218
|
* Selects the next runnable prompt based on priority.
|
|
77067
77219
|
*/
|
|
77068
|
-
function findNextTodoPrompt(files, priorityFilter = {}) {
|
|
77220
|
+
function findNextTodoPrompt(files, priorityFilter = {}, promptRunnerIdentity) {
|
|
77069
77221
|
let nextPrompt;
|
|
77070
|
-
for (const prompt of listRunnablePrompts(files, priorityFilter)) {
|
|
77222
|
+
for (const prompt of listRunnablePrompts(files, priorityFilter, promptRunnerIdentity)) {
|
|
77071
77223
|
if (!nextPrompt || prompt.section.priority > nextPrompt.section.priority) {
|
|
77072
77224
|
nextPrompt = prompt;
|
|
77073
77225
|
}
|
|
@@ -77078,8 +77230,8 @@ function findNextTodoPrompt(files, priorityFilter = {}) {
|
|
|
77078
77230
|
/**
|
|
77079
77231
|
* Lists upcoming tasks that are ready to run (no authoring placeholders).
|
|
77080
77232
|
*/
|
|
77081
|
-
function listUpcomingTasks(files, priorityFilter = {}) {
|
|
77082
|
-
return listRunnablePrompts(files, priorityFilter).map(({ file, section }) => ({
|
|
77233
|
+
function listUpcomingTasks(files, priorityFilter = {}, promptRunnerIdentity) {
|
|
77234
|
+
return listRunnablePrompts(files, priorityFilter, promptRunnerIdentity).map(({ file, section }) => ({
|
|
77083
77235
|
label: buildPromptLabelForDisplay(file, section),
|
|
77084
77236
|
summary: buildPromptSummary(file, section),
|
|
77085
77237
|
priority: section.priority,
|
|
@@ -77223,6 +77375,71 @@ async function buildCoderRunAgentVisual(agentSource) {
|
|
|
77223
77375
|
}
|
|
77224
77376
|
}
|
|
77225
77377
|
|
|
77378
|
+
/**
|
|
77379
|
+
* Creates the one queue prompt used to repair a pre-existing test failure.
|
|
77380
|
+
*/
|
|
77381
|
+
async function createTestBeforeRepairPrompt(options) {
|
|
77382
|
+
const description = spaceTrim((block) => `
|
|
77383
|
+
Fix the existing test failures before implementing any queued coding tasks.
|
|
77384
|
+
|
|
77385
|
+
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.
|
|
77386
|
+
|
|
77387
|
+
## Verification output
|
|
77388
|
+
|
|
77389
|
+
\`\`\`
|
|
77390
|
+
${block(limitTestOutput(options.testOutput))}
|
|
77391
|
+
\`\`\`
|
|
77392
|
+
`);
|
|
77393
|
+
const createdPrompt = await addCoderPrompt({
|
|
77394
|
+
projectPath: options.projectPath,
|
|
77395
|
+
description,
|
|
77396
|
+
priority: 0,
|
|
77397
|
+
});
|
|
77398
|
+
const promptPath = join(options.projectPath, createdPrompt.filePath);
|
|
77399
|
+
const promptFile = parsePromptFile(promptPath, await readFile(promptPath, 'utf-8'));
|
|
77400
|
+
const section = promptFile.sections[0];
|
|
77401
|
+
if (!section) {
|
|
77402
|
+
throw new UnexpectedError(spaceTrim(`
|
|
77403
|
+
The pre-coding test repair prompt was created at \`${createdPrompt.filePath}\` without a runnable section.
|
|
77404
|
+
`));
|
|
77405
|
+
}
|
|
77406
|
+
return { file: promptFile, section };
|
|
77407
|
+
}
|
|
77408
|
+
|
|
77409
|
+
/**
|
|
77410
|
+
* Runs the configured verification command before the first coding prompt.
|
|
77411
|
+
*/
|
|
77412
|
+
async function runTestBefore(options) {
|
|
77413
|
+
var _a, _b;
|
|
77414
|
+
const runPromptTestCommandExecutor = (_a = options.runPromptTestCommandExecutor) !== null && _a !== void 0 ? _a : runPromptTestCommand;
|
|
77415
|
+
const initialTestStatusMessage = `Running initial tests before the agent coding starts: ${options.testCommand}`;
|
|
77416
|
+
await ((_b = options.waitForPauseCheckpoint) === null || _b === void 0 ? void 0 : _b.call(options, {
|
|
77417
|
+
checkpointLabel: 'running initial tests before the agent coding starts',
|
|
77418
|
+
phase: 'verifying',
|
|
77419
|
+
statusMessage: initialTestStatusMessage,
|
|
77420
|
+
}));
|
|
77421
|
+
console.info(colors.gray(initialTestStatusMessage));
|
|
77422
|
+
try {
|
|
77423
|
+
const testOutput = await runPromptTestCommandExecutor({
|
|
77424
|
+
command: options.testCommand,
|
|
77425
|
+
projectPath: options.projectPath,
|
|
77426
|
+
scriptPath: buildTemporaryPromptScriptPath({
|
|
77427
|
+
projectPath: options.projectPath,
|
|
77428
|
+
scriptDirectoryName: 'coder-prompts',
|
|
77429
|
+
sourceFileName: 'test-before',
|
|
77430
|
+
}),
|
|
77431
|
+
});
|
|
77432
|
+
console.info(colors.green('Pre-coding tests passed.'));
|
|
77433
|
+
return { isPassed: true, testOutput };
|
|
77434
|
+
}
|
|
77435
|
+
catch (error) {
|
|
77436
|
+
const testOutput = formatUnknownErrorMessage(error);
|
|
77437
|
+
console.error(colors.red('Pre-coding tests failed.'));
|
|
77438
|
+
console.error(testOutput);
|
|
77439
|
+
return { isPassed: false, testOutput };
|
|
77440
|
+
}
|
|
77441
|
+
}
|
|
77442
|
+
|
|
77226
77443
|
/**
|
|
77227
77444
|
* Constant for prompts dir.
|
|
77228
77445
|
*/
|
|
@@ -77250,6 +77467,10 @@ async function runCodexPrompts(providedOptions) {
|
|
|
77250
77467
|
return;
|
|
77251
77468
|
}
|
|
77252
77469
|
const { runner, actualRunnerModel, runnerMetadata } = resolvePromptRunner(options);
|
|
77470
|
+
const promptRunnerIdentity = {
|
|
77471
|
+
harnessName: options.agentName,
|
|
77472
|
+
modelName: actualRunnerModel,
|
|
77473
|
+
};
|
|
77253
77474
|
console.info(colors.green(`Running prompts with ${runner.name}`));
|
|
77254
77475
|
initializeRunUi(uiHandle, runner.name, actualRunnerModel, options);
|
|
77255
77476
|
await initializeRunUiAgentVisual(uiHandle, resolvedCoderAgent === null || resolvedCoderAgent === void 0 ? void 0 : resolvedCoderAgent.agentSource);
|
|
@@ -77264,6 +77485,7 @@ async function runCodexPrompts(providedOptions) {
|
|
|
77264
77485
|
let previousRoundStartTime;
|
|
77265
77486
|
let previousRoundEndTime;
|
|
77266
77487
|
let completedRunCount = 0;
|
|
77488
|
+
let hasRunTestBefore = false;
|
|
77267
77489
|
while (just(true)) {
|
|
77268
77490
|
if (options.autoPull && !options.dryRun) {
|
|
77269
77491
|
await waitForRequestedPause({
|
|
@@ -77276,6 +77498,35 @@ async function runCodexPrompts(providedOptions) {
|
|
|
77276
77498
|
options,
|
|
77277
77499
|
isRichUiEnabled,
|
|
77278
77500
|
});
|
|
77501
|
+
if (!hasRunTestBefore && options.testBefore !== 'no') {
|
|
77502
|
+
await waitForRequestedPause({
|
|
77503
|
+
checkpointLabel: 'loading prompts before running initial tests',
|
|
77504
|
+
phase: 'loading',
|
|
77505
|
+
statusMessage: 'Loading prompts before running initial tests...',
|
|
77506
|
+
});
|
|
77507
|
+
await loadPromptQueueSnapshot({
|
|
77508
|
+
options,
|
|
77509
|
+
isRichUiEnabled,
|
|
77510
|
+
progressDisplay,
|
|
77511
|
+
uiHandle,
|
|
77512
|
+
promptRunnerIdentity,
|
|
77513
|
+
});
|
|
77514
|
+
}
|
|
77515
|
+
if (!hasRunTestBefore) {
|
|
77516
|
+
hasWaitedForStart = await runTestBeforeIfNeeded({
|
|
77517
|
+
options,
|
|
77518
|
+
runner,
|
|
77519
|
+
runnerMetadata,
|
|
77520
|
+
resolvedCoderContext,
|
|
77521
|
+
resolvedAgentSystemMessage,
|
|
77522
|
+
isRichUiEnabled,
|
|
77523
|
+
progressDisplay,
|
|
77524
|
+
uiHandle,
|
|
77525
|
+
waitForRequestedPause,
|
|
77526
|
+
hasWaitedForStart,
|
|
77527
|
+
});
|
|
77528
|
+
hasRunTestBefore = true;
|
|
77529
|
+
}
|
|
77279
77530
|
await waitForRequestedPause({
|
|
77280
77531
|
checkpointLabel: 'loading prompts',
|
|
77281
77532
|
phase: 'loading',
|
|
@@ -77286,6 +77537,7 @@ async function runCodexPrompts(providedOptions) {
|
|
|
77286
77537
|
isRichUiEnabled,
|
|
77287
77538
|
progressDisplay,
|
|
77288
77539
|
uiHandle,
|
|
77540
|
+
promptRunnerIdentity,
|
|
77289
77541
|
});
|
|
77290
77542
|
hasShownUpcomingTasks || (hasShownUpcomingTasks = showUpcomingTasksOnce({
|
|
77291
77543
|
hasShownUpcomingTasks,
|
|
@@ -77293,6 +77545,7 @@ async function runCodexPrompts(providedOptions) {
|
|
|
77293
77545
|
stats: promptQueueSnapshot.stats,
|
|
77294
77546
|
priorityFilter: options.priorityFilter,
|
|
77295
77547
|
isRichUiEnabled,
|
|
77548
|
+
promptRunnerIdentity,
|
|
77296
77549
|
}));
|
|
77297
77550
|
if (!promptQueueSnapshot.nextPrompt) {
|
|
77298
77551
|
if (isEndAfterCurrentPromptRequested(completedRunCount)) {
|
|
@@ -77395,6 +77648,14 @@ async function runCodexPrompts(providedOptions) {
|
|
|
77395
77648
|
* Validates cross-flag constraints before the run starts.
|
|
77396
77649
|
*/
|
|
77397
77650
|
function validateRunCodexPromptOptions(options) {
|
|
77651
|
+
var _a;
|
|
77652
|
+
if (!isTestBeforeMode((_a = options.testBefore) !== null && _a !== void 0 ? _a : 'no')) {
|
|
77653
|
+
throw new NotAllowed(spaceTrim$1(`
|
|
77654
|
+
Invalid ${'`--test-before`'} mode: \`${String(options.testBefore)}\`.
|
|
77655
|
+
|
|
77656
|
+
Use one of: \`no\`, \`yes-and-fail\`, \`yes-and-fix\`.
|
|
77657
|
+
`));
|
|
77658
|
+
}
|
|
77398
77659
|
if (options.allowDestructiveAutoMigrate && !options.autoMigrate) {
|
|
77399
77660
|
throw new DatabaseError(spaceTrim$1(`
|
|
77400
77661
|
Flag \`--allow-destructive-auto-migrate\` requires \`--auto-migrate\`.
|
|
@@ -77465,20 +77726,103 @@ function createRunDisplays(options, runStartDate) {
|
|
|
77465
77726
|
* Normalizes legacy and current priority options into one validated run option shape.
|
|
77466
77727
|
*/
|
|
77467
77728
|
function normalizeRunOptions(options) {
|
|
77468
|
-
var _a, _b, _c, _d, _e;
|
|
77729
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
77730
|
+
const testBefore = (_a = options.testBefore) !== null && _a !== void 0 ? _a : 'no';
|
|
77731
|
+
const normalizedTestCommand = (_b = options.testCommand) === null || _b === void 0 ? void 0 : _b.trim();
|
|
77469
77732
|
const priorityFilter = normalizePriorityFilter({
|
|
77470
77733
|
priority: options.priority,
|
|
77471
|
-
minimumPriority: (
|
|
77472
|
-
maximumPriority: (
|
|
77734
|
+
minimumPriority: (_c = options.minimumPriority) !== null && _c !== void 0 ? _c : (_d = options.priorityFilter) === null || _d === void 0 ? void 0 : _d.minimumPriority,
|
|
77735
|
+
maximumPriority: (_e = options.maximumPriority) !== null && _e !== void 0 ? _e : (_f = options.priorityFilter) === null || _f === void 0 ? void 0 : _f.maximumPriority,
|
|
77473
77736
|
});
|
|
77474
77737
|
return {
|
|
77475
77738
|
...options,
|
|
77476
|
-
|
|
77739
|
+
testBefore,
|
|
77740
|
+
testCommand: normalizedTestCommand || (testBefore === 'no' ? undefined : DEFAULT_CODER_TEST_COMMAND),
|
|
77741
|
+
priority: (_g = priorityFilter.minimumPriority) !== null && _g !== void 0 ? _g : 0,
|
|
77477
77742
|
minimumPriority: priorityFilter.minimumPriority,
|
|
77478
77743
|
maximumPriority: priorityFilter.maximumPriority,
|
|
77479
77744
|
priorityFilter,
|
|
77480
77745
|
};
|
|
77481
77746
|
}
|
|
77747
|
+
/**
|
|
77748
|
+
* Runs the optional pre-coding verification and, when requested, its one repair prompt.
|
|
77749
|
+
*/
|
|
77750
|
+
async function runTestBeforeIfNeeded(options) {
|
|
77751
|
+
const { options: runOptions, runner, runnerMetadata, resolvedCoderContext, resolvedAgentSystemMessage, isRichUiEnabled, progressDisplay, uiHandle, waitForRequestedPause, hasWaitedForStart, } = options;
|
|
77752
|
+
if (runOptions.testBefore === 'no') {
|
|
77753
|
+
return hasWaitedForStart;
|
|
77754
|
+
}
|
|
77755
|
+
if (!runOptions.testCommand) {
|
|
77756
|
+
throw new NotAllowed(spaceTrim$1(`
|
|
77757
|
+
${'`--test-before ' + runOptions.testBefore + '`'} requires a verification command.
|
|
77758
|
+
|
|
77759
|
+
Pass one with ${'`--test <test-command>`'} or use the default ${'`npm test`'} command by providing the mode through the CLI.
|
|
77760
|
+
`));
|
|
77761
|
+
}
|
|
77762
|
+
if (!runOptions.ignoreGitChanges) {
|
|
77763
|
+
await waitForRequestedPause({
|
|
77764
|
+
checkpointLabel: 'checking the git working tree before testing',
|
|
77765
|
+
phase: 'loading',
|
|
77766
|
+
statusMessage: 'Checking the working tree before testing...',
|
|
77767
|
+
});
|
|
77768
|
+
await ensureWorkingTreeClean();
|
|
77769
|
+
}
|
|
77770
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.startCapturingAgentOutput();
|
|
77771
|
+
const testBeforeResult = await runTestBefore({
|
|
77772
|
+
testCommand: runOptions.testCommand,
|
|
77773
|
+
projectPath: process.cwd(),
|
|
77774
|
+
waitForPauseCheckpoint: waitForRequestedPause,
|
|
77775
|
+
}).finally(() => {
|
|
77776
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.stopCapturingAgentOutput();
|
|
77777
|
+
});
|
|
77778
|
+
if (testBeforeResult.isPassed) {
|
|
77779
|
+
return hasWaitedForStart;
|
|
77780
|
+
}
|
|
77781
|
+
const testOutput = limitTestOutput(testBeforeResult.testOutput);
|
|
77782
|
+
if (runOptions.testBefore === 'yes-and-fail') {
|
|
77783
|
+
throw new NotAllowed(spaceTrim$1((block) => `
|
|
77784
|
+
Pre-coding verification command \`${runOptions.testCommand}\` failed.
|
|
77785
|
+
|
|
77786
|
+
The coding agent was not started because the project was already failing before the first queued prompt.
|
|
77787
|
+
|
|
77788
|
+
### Test results
|
|
77789
|
+
${'```'}
|
|
77790
|
+
${block(testOutput)}
|
|
77791
|
+
${'```'}
|
|
77792
|
+
`));
|
|
77793
|
+
}
|
|
77794
|
+
const repairPrompt = await createTestBeforeRepairPrompt({
|
|
77795
|
+
projectPath: process.cwd(),
|
|
77796
|
+
testCommand: runOptions.testCommand,
|
|
77797
|
+
testOutput,
|
|
77798
|
+
});
|
|
77799
|
+
const repairPromptLabel = buildPromptLabelForDisplay(repairPrompt.file, repairPrompt.section);
|
|
77800
|
+
const updatedHasWaitedForStart = await waitForPromptConfirmationIfNeeded({
|
|
77801
|
+
options: runOptions,
|
|
77802
|
+
nextPrompt: repairPrompt,
|
|
77803
|
+
promptLabel: repairPromptLabel,
|
|
77804
|
+
hasWaitedForStart,
|
|
77805
|
+
isRichUiEnabled,
|
|
77806
|
+
progressDisplay,
|
|
77807
|
+
uiHandle,
|
|
77808
|
+
});
|
|
77809
|
+
// The repair prompt is created in the current worktree so it can be recorded and committed with the repair.
|
|
77810
|
+
// It therefore intentionally uses the regular round here even when the queue itself uses --isolate.
|
|
77811
|
+
await runPromptRound({
|
|
77812
|
+
options: runOptions,
|
|
77813
|
+
runner,
|
|
77814
|
+
runnerMetadata,
|
|
77815
|
+
nextPrompt: repairPrompt,
|
|
77816
|
+
promptLabel: repairPromptLabel,
|
|
77817
|
+
resolvedCoderContext,
|
|
77818
|
+
resolvedAgentSystemMessage,
|
|
77819
|
+
isRichUiEnabled,
|
|
77820
|
+
progressDisplay,
|
|
77821
|
+
uiHandle,
|
|
77822
|
+
waitForRequestedPause,
|
|
77823
|
+
});
|
|
77824
|
+
return updatedHasWaitedForStart;
|
|
77825
|
+
}
|
|
77482
77826
|
/**
|
|
77483
77827
|
* Creates a pause waiter that keeps the progress display and rich UI in sync.
|
|
77484
77828
|
*/
|
|
@@ -77563,7 +77907,7 @@ async function initializeRunUiAgentVisual(uiHandle, agentSource) {
|
|
|
77563
77907
|
* Loads prompt files, updates progress displays, and selects the next runnable prompt.
|
|
77564
77908
|
*/
|
|
77565
77909
|
async function loadPromptQueueSnapshot(options) {
|
|
77566
|
-
const { options: runOptions, isRichUiEnabled, progressDisplay, uiHandle } = options;
|
|
77910
|
+
const { options: runOptions, isRichUiEnabled, progressDisplay, uiHandle, promptRunnerIdentity } = options;
|
|
77567
77911
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setCurrentScriptPath(undefined);
|
|
77568
77912
|
const promptFiles = await loadPromptFiles(PROMPTS_DIR$1);
|
|
77569
77913
|
const stats = summarizePrompts(promptFiles, runOptions.priorityFilter);
|
|
@@ -77575,14 +77919,14 @@ async function loadPromptQueueSnapshot(options) {
|
|
|
77575
77919
|
return {
|
|
77576
77920
|
promptFiles,
|
|
77577
77921
|
stats,
|
|
77578
|
-
nextPrompt: findNextTodoPrompt(promptFiles, runOptions.priorityFilter),
|
|
77922
|
+
nextPrompt: findNextTodoPrompt(promptFiles, runOptions.priorityFilter, promptRunnerIdentity),
|
|
77579
77923
|
};
|
|
77580
77924
|
}
|
|
77581
77925
|
/**
|
|
77582
77926
|
* Prints upcoming tasks only on the first loop iteration in plain-console mode.
|
|
77583
77927
|
*/
|
|
77584
77928
|
function showUpcomingTasksOnce(options) {
|
|
77585
|
-
const { hasShownUpcomingTasks, promptFiles, stats, priorityFilter, isRichUiEnabled } = options;
|
|
77929
|
+
const { hasShownUpcomingTasks, promptFiles, stats, priorityFilter, isRichUiEnabled, promptRunnerIdentity } = options;
|
|
77586
77930
|
if (hasShownUpcomingTasks || isRichUiEnabled) {
|
|
77587
77931
|
return true;
|
|
77588
77932
|
}
|
|
@@ -77591,7 +77935,7 @@ function showUpcomingTasksOnce(options) {
|
|
|
77591
77935
|
printPromptsToBeWritten(promptFiles, priorityFilter);
|
|
77592
77936
|
console.info('');
|
|
77593
77937
|
}
|
|
77594
|
-
printUpcomingTasks(listUpcomingTasks(promptFiles, priorityFilter));
|
|
77938
|
+
printUpcomingTasks(listUpcomingTasks(promptFiles, priorityFilter, promptRunnerIdentity));
|
|
77595
77939
|
return true;
|
|
77596
77940
|
}
|
|
77597
77941
|
/**
|
|
@@ -77601,7 +77945,10 @@ function finishWhenNoPromptIsAvailable(promptQueueSnapshot, isRichUiEnabled, uiH
|
|
|
77601
77945
|
if (promptQueueSnapshot.nextPrompt) {
|
|
77602
77946
|
return false;
|
|
77603
77947
|
}
|
|
77604
|
-
if (promptQueueSnapshot.stats.
|
|
77948
|
+
if (promptQueueSnapshot.stats.forAgent > 0) {
|
|
77949
|
+
announceRunCompletion('No prompts match the selected harness or model.', colors.yellow, isRichUiEnabled, uiHandle);
|
|
77950
|
+
}
|
|
77951
|
+
else if (promptQueueSnapshot.stats.toBeWritten > 0) {
|
|
77605
77952
|
announceRunCompletion('No prompts ready for agent.', colors.yellow, isRichUiEnabled, uiHandle);
|
|
77606
77953
|
}
|
|
77607
77954
|
else {
|
|
@@ -77642,9 +77989,16 @@ function finishWhenEndAfterCurrentPromptIsRequested(options) {
|
|
|
77642
77989
|
* Updates the UI status message while waiting for new prompts in keepAlive server mode.
|
|
77643
77990
|
*/
|
|
77644
77991
|
function announceKeepAliveStatus(promptQueueSnapshot, isRichUiEnabled, uiHandle) {
|
|
77645
|
-
|
|
77646
|
-
|
|
77647
|
-
|
|
77992
|
+
let message;
|
|
77993
|
+
if (promptQueueSnapshot.stats.forAgent > 0) {
|
|
77994
|
+
message = 'No prompts match the selected harness or model. Watching for changes...';
|
|
77995
|
+
}
|
|
77996
|
+
else if (promptQueueSnapshot.stats.toBeWritten > 0) {
|
|
77997
|
+
message = 'No prompts ready for agent. Watching for changes...';
|
|
77998
|
+
}
|
|
77999
|
+
else {
|
|
78000
|
+
message = 'All prompts are done. Watching for changes...';
|
|
78001
|
+
}
|
|
77648
78002
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setStatusMessage(message);
|
|
77649
78003
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setPhase('waiting');
|
|
77650
78004
|
if (!isRichUiEnabled) {
|
|
@@ -77666,7 +78020,7 @@ function announceRunCompletion(message, colorize, isRichUiEnabled, uiHandle) {
|
|
|
77666
78020
|
* Waits for the optional user confirmation before starting the selected prompt.
|
|
77667
78021
|
*/
|
|
77668
78022
|
async function waitForPromptConfirmationIfNeeded(options) {
|
|
77669
|
-
const { options: runOptions, nextPrompt, promptLabel, hasWaitedForStart, isRichUiEnabled, progressDisplay, uiHandle } = options;
|
|
78023
|
+
const { options: runOptions, nextPrompt, promptLabel, hasWaitedForStart, isRichUiEnabled, progressDisplay, uiHandle, } = options;
|
|
77670
78024
|
if (!runOptions.waitForUser) {
|
|
77671
78025
|
return hasWaitedForStart;
|
|
77672
78026
|
}
|