@promptbook/cli 0.114.0-4 → 0.114.0-5
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 +3 -3
- package/esm/index.es.js +268 -74
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/run-codex-prompts/common/createCoderRunStepTracker.d.ts +48 -0
- package/esm/scripts/run-codex-prompts/prompts/buildPromptStatusDetails.d.ts +43 -0
- package/esm/scripts/run-codex-prompts/prompts/formatCoderRunSteps.d.ts +6 -3
- package/esm/scripts/run-codex-prompts/prompts/isPromptSectionUnfinished.d.ts +8 -0
- package/esm/scripts/run-codex-prompts/prompts/markPromptDone.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/prompts/markPromptInProgress.d.ts +27 -0
- package/esm/scripts/run-codex-prompts/prompts/resolvePromptStatusLine.d.ts +19 -0
- package/esm/scripts/run-codex-prompts/prompts/writePromptStatusLine.d.ts +9 -0
- package/esm/scripts/run-codex-prompts/server/buildCoderServerPromptResponse.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/server/coderServerHtml.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/server/updatePromptSection.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/testing/runPromptWithTestFeedback.d.ts +6 -0
- package/esm/scripts/verify-prompts/$orderPromptFiles.d.ts +9 -0
- package/esm/scripts/verify-prompts/VerifyPromptsOrder.d.ts +26 -0
- package/esm/scripts/verify-prompts/verify-prompts.d.ts +3 -2
- package/esm/src/cli/cli-commands/coder/verify.d.ts +1 -1
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/cli/cli-commands/coder/verify.ts +29 -5
- package/src/other/templates/getTemplatesPipelineCollection.ts +704 -843
- package/src/version.ts +2 -2
- package/src/versions.txt +1 -0
- package/umd/index.umd.js +268 -74
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/run-codex-prompts/common/createCoderRunStepTracker.d.ts +48 -0
- package/umd/scripts/run-codex-prompts/prompts/buildPromptStatusDetails.d.ts +43 -0
- package/umd/scripts/run-codex-prompts/prompts/formatCoderRunSteps.d.ts +6 -3
- package/umd/scripts/run-codex-prompts/prompts/isPromptSectionUnfinished.d.ts +8 -0
- package/umd/scripts/run-codex-prompts/prompts/markPromptDone.d.ts +1 -1
- package/umd/scripts/run-codex-prompts/prompts/markPromptInProgress.d.ts +27 -0
- package/umd/scripts/run-codex-prompts/prompts/resolvePromptStatusLine.d.ts +19 -0
- package/umd/scripts/run-codex-prompts/prompts/writePromptStatusLine.d.ts +9 -0
- package/umd/scripts/run-codex-prompts/server/buildCoderServerPromptResponse.d.ts +1 -1
- package/umd/scripts/run-codex-prompts/server/coderServerHtml.d.ts +1 -1
- package/umd/scripts/run-codex-prompts/server/updatePromptSection.d.ts +1 -1
- package/umd/scripts/run-codex-prompts/testing/runPromptWithTestFeedback.d.ts +6 -0
- package/umd/scripts/verify-prompts/$orderPromptFiles.d.ts +9 -0
- package/umd/scripts/verify-prompts/VerifyPromptsOrder.d.ts +26 -0
- package/umd/scripts/verify-prompts/verify-prompts.d.ts +3 -2
- package/umd/src/cli/cli-commands/coder/verify.d.ts +1 -1
- package/umd/src/version.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/prompts/replacePromptTodoStatusLine.d.ts +0 -7
- package/umd/scripts/run-codex-prompts/prompts/replacePromptTodoStatusLine.d.ts +0 -7
package/src/version.ts
CHANGED
|
@@ -16,11 +16,11 @@ export const BOOK_LANGUAGE_VERSION: string_semantic_version = '2.0.0';
|
|
|
16
16
|
* @generated
|
|
17
17
|
* @see https://github.com/webgptorg/promptbook
|
|
18
18
|
*/
|
|
19
|
-
export const PROMPTBOOK_ENGINE_VERSION: string_promptbook_version = '0.114.0-
|
|
19
|
+
export const PROMPTBOOK_ENGINE_VERSION: string_promptbook_version = '0.114.0-5';
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Represents the version string of the Promptbook engine.
|
|
23
|
-
* It follows semantic versioning (e.g., `0.114.0-
|
|
23
|
+
* It follows semantic versioning (e.g., `0.114.0-4`).
|
|
24
24
|
*
|
|
25
25
|
* @generated
|
|
26
26
|
*/
|
package/src/versions.txt
CHANGED
package/umd/index.umd.js
CHANGED
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
* @generated
|
|
59
59
|
* @see https://github.com/webgptorg/promptbook
|
|
60
60
|
*/
|
|
61
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.114.0-
|
|
61
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.114.0-5';
|
|
62
62
|
/**
|
|
63
63
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
64
64
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -29758,6 +29758,32 @@
|
|
|
29758
29758
|
`);
|
|
29759
29759
|
}
|
|
29760
29760
|
|
|
29761
|
+
/**
|
|
29762
|
+
* Creates the step tracker of one prompt round.
|
|
29763
|
+
*
|
|
29764
|
+
* The tracker is the single place which knows which steps have finished and which one is running,
|
|
29765
|
+
* so both the finished `[x]` status line and the intermediate `[^]` in-progress status lines are
|
|
29766
|
+
* built from the very same data.
|
|
29767
|
+
*/
|
|
29768
|
+
function createCoderRunStepTracker(onStepStarted) {
|
|
29769
|
+
const steps = [];
|
|
29770
|
+
let reportedLoginMethod;
|
|
29771
|
+
return {
|
|
29772
|
+
steps,
|
|
29773
|
+
async startStep(kind) {
|
|
29774
|
+
await (onStepStarted === null || onStepStarted === void 0 ? void 0 : onStepStarted({
|
|
29775
|
+
startedStepKind: kind,
|
|
29776
|
+
finishedSteps: [...steps],
|
|
29777
|
+
loginMethod: reportedLoginMethod,
|
|
29778
|
+
}));
|
|
29779
|
+
},
|
|
29780
|
+
finishStep(step, loginMethod) {
|
|
29781
|
+
steps.push(step);
|
|
29782
|
+
reportedLoginMethod = loginMethod !== null && loginMethod !== void 0 ? loginMethod : reportedLoginMethod;
|
|
29783
|
+
},
|
|
29784
|
+
};
|
|
29785
|
+
}
|
|
29786
|
+
|
|
29761
29787
|
/**
|
|
29762
29788
|
* Maximum amount of test output embedded into an agent prompt.
|
|
29763
29789
|
*/
|
|
@@ -29803,7 +29829,7 @@
|
|
|
29803
29829
|
async function runPromptWithTestFeedback(options) {
|
|
29804
29830
|
var _a, _b, _c, _d;
|
|
29805
29831
|
const normalizedTestCommand = (_a = options.testCommand) === null || _a === void 0 ? void 0 : _a.trim();
|
|
29806
|
-
const
|
|
29832
|
+
const stepTracker = createCoderRunStepTracker(options.onStepStarted);
|
|
29807
29833
|
if (!normalizedTestCommand) {
|
|
29808
29834
|
(_b = options.onAttemptStarted) === null || _b === void 0 ? void 0 : _b.call(options, 1);
|
|
29809
29835
|
await waitForPromptAttemptPauseCheckpoint(options.waitForPauseCheckpoint, options.runner.name, 1);
|
|
@@ -29811,9 +29837,9 @@
|
|
|
29811
29837
|
runOptions: options,
|
|
29812
29838
|
prompt: options.prompt,
|
|
29813
29839
|
kind: 'implementation',
|
|
29814
|
-
|
|
29840
|
+
stepTracker,
|
|
29815
29841
|
});
|
|
29816
|
-
return { ...result, attemptCount: 1, steps };
|
|
29842
|
+
return { ...result, attemptCount: 1, steps: stepTracker.steps };
|
|
29817
29843
|
}
|
|
29818
29844
|
const runPromptTestCommandExecutor = (_c = options.runPromptTestCommandExecutor) !== null && _c !== void 0 ? _c : runPromptTestCommand;
|
|
29819
29845
|
let promptForCurrentAttempt = options.prompt;
|
|
@@ -29824,7 +29850,7 @@
|
|
|
29824
29850
|
runOptions: options,
|
|
29825
29851
|
prompt: promptForCurrentAttempt,
|
|
29826
29852
|
kind: attemptCount === 1 ? 'implementation' : 'fixing',
|
|
29827
|
-
|
|
29853
|
+
stepTracker,
|
|
29828
29854
|
});
|
|
29829
29855
|
await waitForVerificationPauseCheckpoint(options.waitForPauseCheckpoint, normalizedTestCommand, attemptCount);
|
|
29830
29856
|
console.info(colors__default["default"].gray(`Running verification command after attempt #${attemptCount}: ${normalizedTestCommand}`));
|
|
@@ -29832,10 +29858,10 @@
|
|
|
29832
29858
|
runPromptTestCommandExecutor,
|
|
29833
29859
|
testCommand: normalizedTestCommand,
|
|
29834
29860
|
runOptions: options,
|
|
29835
|
-
|
|
29861
|
+
stepTracker,
|
|
29836
29862
|
});
|
|
29837
29863
|
if (failedVerification === undefined) {
|
|
29838
|
-
return { ...result, attemptCount, steps };
|
|
29864
|
+
return { ...result, attemptCount, steps: stepTracker.steps };
|
|
29839
29865
|
}
|
|
29840
29866
|
const fullVerificationOutput = formatUnknownErrorDetails(failedVerification.error);
|
|
29841
29867
|
const feedbackVerificationOutput = limitTestOutput(fullVerificationOutput);
|
|
@@ -29861,7 +29887,8 @@
|
|
|
29861
29887
|
* Runs one coding attempt through the runner, timing it and recording it as an implementation or fixing step.
|
|
29862
29888
|
*/
|
|
29863
29889
|
async function runRunnerPromptStep(options) {
|
|
29864
|
-
const { runOptions, prompt, kind,
|
|
29890
|
+
const { runOptions, prompt, kind, stepTracker } = options;
|
|
29891
|
+
await stepTracker.startStep(kind);
|
|
29865
29892
|
const stepStartedTimeMs = Date.now();
|
|
29866
29893
|
const result = await runOptions.runner.runPrompt({
|
|
29867
29894
|
prompt,
|
|
@@ -29871,7 +29898,7 @@
|
|
|
29871
29898
|
preserveArtifactsOnSuccess: runOptions.preserveArtifactsOnSuccess,
|
|
29872
29899
|
waitForPauseCheckpoint: runOptions.waitForPauseCheckpoint,
|
|
29873
29900
|
});
|
|
29874
|
-
|
|
29901
|
+
stepTracker.finishStep({ kind, usage: result.usage, durationMs: Date.now() - stepStartedTimeMs }, result.loginMethod);
|
|
29875
29902
|
return result;
|
|
29876
29903
|
}
|
|
29877
29904
|
/**
|
|
@@ -29879,7 +29906,8 @@
|
|
|
29879
29906
|
* returns the failure (or `undefined` when the verification passed).
|
|
29880
29907
|
*/
|
|
29881
29908
|
async function runVerificationStep(options) {
|
|
29882
|
-
const { runPromptTestCommandExecutor, testCommand, runOptions,
|
|
29909
|
+
const { runPromptTestCommandExecutor, testCommand, runOptions, stepTracker } = options;
|
|
29910
|
+
await stepTracker.startStep('testing');
|
|
29883
29911
|
const stepStartedTimeMs = Date.now();
|
|
29884
29912
|
try {
|
|
29885
29913
|
await runPromptTestCommandExecutor({
|
|
@@ -29895,7 +29923,7 @@
|
|
|
29895
29923
|
return { error };
|
|
29896
29924
|
}
|
|
29897
29925
|
finally {
|
|
29898
|
-
|
|
29926
|
+
stepTracker.finishStep({ kind: 'testing', usage: null, durationMs: Date.now() - stepStartedTimeMs });
|
|
29899
29927
|
}
|
|
29900
29928
|
}
|
|
29901
29929
|
/**
|
|
@@ -41182,6 +41210,45 @@
|
|
|
41182
41210
|
// Note: [🟡] Code for CLI command [server](src/cli/cli-commands/coder/server.ts) should never be published outside of `@promptbook/cli`
|
|
41183
41211
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
41184
41212
|
|
|
41213
|
+
/**
|
|
41214
|
+
* Orders supported by `ptbk coder verify --order`.
|
|
41215
|
+
*/
|
|
41216
|
+
const VERIFY_PROMPTS_ORDER_VALUES = ['from-earliest', 'from-latest', 'random'];
|
|
41217
|
+
/**
|
|
41218
|
+
* Order used when `--order` is not provided.
|
|
41219
|
+
*/
|
|
41220
|
+
const DEFAULT_VERIFY_PROMPTS_ORDER = 'from-earliest';
|
|
41221
|
+
/**
|
|
41222
|
+
* Human-readable description of each supported order, shared by the CLI help and the verification output.
|
|
41223
|
+
*/
|
|
41224
|
+
const VERIFY_PROMPTS_ORDER_DESCRIPTIONS = {
|
|
41225
|
+
'from-earliest': 'from the earliest prompt file',
|
|
41226
|
+
'from-latest': 'from the latest prompt file',
|
|
41227
|
+
random: 'in random order',
|
|
41228
|
+
};
|
|
41229
|
+
/**
|
|
41230
|
+
* Parses and validates one raw `--order` value.
|
|
41231
|
+
*
|
|
41232
|
+
* Note: `ptbk coder verify` lets Commander validate the value, this is used by the standalone script which parses the raw arguments itself
|
|
41233
|
+
*/
|
|
41234
|
+
function parseVerifyPromptsOrder(orderValue) {
|
|
41235
|
+
if (orderValue === undefined) {
|
|
41236
|
+
return DEFAULT_VERIFY_PROMPTS_ORDER;
|
|
41237
|
+
}
|
|
41238
|
+
if (VERIFY_PROMPTS_ORDER_VALUES.includes(orderValue)) {
|
|
41239
|
+
return orderValue;
|
|
41240
|
+
}
|
|
41241
|
+
throw new NotAllowed(_spaceTrim.spaceTrim((block) => `
|
|
41242
|
+
Invalid value for \`--order\`: \`${orderValue}\`.
|
|
41243
|
+
|
|
41244
|
+
Use one of the supported orders:
|
|
41245
|
+
${block(VERIFY_PROMPTS_ORDER_VALUES.map((value) => `- \`${value}\` processes the prompt files ${VERIFY_PROMPTS_ORDER_DESCRIPTIONS[value]}`).join('\n'))}
|
|
41246
|
+
|
|
41247
|
+
Actionable hint:
|
|
41248
|
+
- The removed \`--reverse\` flag is now \`--order from-latest\`.
|
|
41249
|
+
`));
|
|
41250
|
+
}
|
|
41251
|
+
|
|
41185
41252
|
/**
|
|
41186
41253
|
* Initializes `coder verify` command for Promptbook CLI utilities
|
|
41187
41254
|
*
|
|
@@ -41201,21 +41268,27 @@
|
|
|
41201
41268
|
- Auto-appends repair prompts for incomplete work
|
|
41202
41269
|
- Processes files with all-done prompts first
|
|
41203
41270
|
- Supports ignoring matching prompt candidates for one verification run
|
|
41271
|
+
- Supports processing the prompt files from the earliest, from the latest or in random order
|
|
41204
41272
|
|
|
41205
41273
|
${block(CODER_GIT_SYNC_DESCRIPTION)}
|
|
41206
41274
|
|
|
41207
41275
|
Note: The git synchronization is applied around each single verification, not once per run.
|
|
41208
41276
|
`));
|
|
41209
|
-
command.
|
|
41277
|
+
command.addOption(new commander.Option('--order <order>', _spaceTrim.spaceTrim((block) => `
|
|
41278
|
+
Order in which the prompt files are processed:
|
|
41279
|
+
${block(VERIFY_PROMPTS_ORDER_VALUES.map((order) => `- ${order}: ${VERIFY_PROMPTS_ORDER_DESCRIPTIONS[order]}`).join('\n'))}
|
|
41280
|
+
`))
|
|
41281
|
+
.choices([...VERIFY_PROMPTS_ORDER_VALUES])
|
|
41282
|
+
.default(DEFAULT_VERIFY_PROMPTS_ORDER));
|
|
41210
41283
|
command.option('--ignore <candidate-text>', 'Ignore prompt files whose filename or first prompt line contains the given text (repeatable)', collectStringOption, []);
|
|
41211
41284
|
addCoderGitSyncOptions(command);
|
|
41212
41285
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
41213
|
-
const {
|
|
41286
|
+
const { order, ignore } = cliOptions;
|
|
41214
41287
|
const gitSync = normalizeCoderGitSyncCliOptions(cliOptions);
|
|
41215
41288
|
// Note: Import the main function dynamically to avoid loading heavy dependencies until needed
|
|
41216
41289
|
const { verifyPrompts } = await Promise.resolve().then(function () { return verifyPrompts$1; });
|
|
41217
41290
|
try {
|
|
41218
|
-
await verifyPrompts({
|
|
41291
|
+
await verifyPrompts({ order, ignore, gitSync });
|
|
41219
41292
|
}
|
|
41220
41293
|
catch (error) {
|
|
41221
41294
|
console.error(colors__default["default"].bgRed('Prompt verification failed:'), error);
|
|
@@ -70360,7 +70433,7 @@
|
|
|
70360
70433
|
}
|
|
70361
70434
|
/**
|
|
70362
70435
|
* Parses a status line like "[ ] !!", "[ ] use `gpt` !!!!!" or "[-]" into status and priority.
|
|
70363
|
-
* For [x] done
|
|
70436
|
+
* For [x] done, [!] failed and [^] in-progress prompts, allow metadata after the status marker.
|
|
70364
70437
|
*/
|
|
70365
70438
|
function parseStatusLine(line) {
|
|
70366
70439
|
var _a, _b, _c, _d;
|
|
@@ -70374,6 +70447,11 @@
|
|
|
70374
70447
|
if (failedMatch) {
|
|
70375
70448
|
return { status: 'failed', priority: 0 };
|
|
70376
70449
|
}
|
|
70450
|
+
// For in-progress prompts [^], allow any content after (for the steps recorded so far)
|
|
70451
|
+
const inProgressMatch = line.match(/^\[(?<status>\^)\]/);
|
|
70452
|
+
if (inProgressMatch) {
|
|
70453
|
+
return { status: 'in-progress', priority: 0 };
|
|
70454
|
+
}
|
|
70377
70455
|
// For not-ready [-], keep the historical clean-line syntax.
|
|
70378
70456
|
if (/^\[-\]\s*!*\s*$/u.test(line)) {
|
|
70379
70457
|
return { status: 'not-ready', priority: 0 };
|
|
@@ -72953,14 +73031,25 @@
|
|
|
72953
73031
|
fixing: 'Fixing',
|
|
72954
73032
|
};
|
|
72955
73033
|
/**
|
|
72956
|
-
*
|
|
73034
|
+
* Suffix marking the one step which has already started but has neither a price nor a duration yet.
|
|
73035
|
+
*/
|
|
73036
|
+
const IN_PROGRESS_STEP_SUFFIX = 'in progress';
|
|
73037
|
+
/**
|
|
73038
|
+
* Formats the per-step usage breakdown recorded for one prompt.
|
|
72957
73039
|
*
|
|
72958
73040
|
* Produces a `; `-separated summary such as
|
|
72959
73041
|
* `Implementation $8.01 6 hours; Testing 1 hour; Fixing $3.14 2 hours` where each coding step carries its
|
|
72960
73042
|
* price and duration and each verification step carries only its duration.
|
|
73043
|
+
*
|
|
73044
|
+
* @param steps - Steps which have already finished
|
|
73045
|
+
* @param inProgressStepKind - Step which has started but has not finished yet, appended as `Testing in progress`
|
|
72961
73046
|
*/
|
|
72962
|
-
function formatCoderRunSteps(steps) {
|
|
72963
|
-
|
|
73047
|
+
function formatCoderRunSteps(steps, inProgressStepKind) {
|
|
73048
|
+
const formattedSteps = steps.map(formatCoderRunStep);
|
|
73049
|
+
if (inProgressStepKind !== undefined) {
|
|
73050
|
+
formattedSteps.push(`${CODER_RUN_STEP_LABELS[inProgressStepKind]} ${IN_PROGRESS_STEP_SUFFIX}`);
|
|
73051
|
+
}
|
|
73052
|
+
return formattedSteps.join('; ');
|
|
72964
73053
|
}
|
|
72965
73054
|
/**
|
|
72966
73055
|
* Formats one coder run step as `Label $price duration`, omitting the price for steps without model usage.
|
|
@@ -72989,47 +73078,78 @@
|
|
|
72989
73078
|
}
|
|
72990
73079
|
|
|
72991
73080
|
/**
|
|
72992
|
-
*
|
|
73081
|
+
* Builds the shared body of a prompt status line, used by both the in-progress `[^]` and the done `[x]` status.
|
|
72993
73082
|
*
|
|
72994
|
-
*
|
|
72995
|
-
*
|
|
73083
|
+
* Produces details such as
|
|
73084
|
+
* ``by OpenAI Codex `gpt-5.6-luna` thinking `max` (ChatGPT account) - Implementation ~$0.2036 10 minutes``.
|
|
72996
73085
|
*/
|
|
72997
|
-
function
|
|
72998
|
-
|
|
73086
|
+
function buildPromptStatusDetails(options) {
|
|
73087
|
+
const { steps, inProgressStepKind, runnerName, modelName, attemptCount, loginMethod, thinkingLevel } = options;
|
|
73088
|
+
const runnerSignature = formatRunnerSignature(runnerName, modelName, thinkingLevel);
|
|
73089
|
+
const attemptMetadata = formatPromptAttemptMetadata('done', attemptCount);
|
|
73090
|
+
const loginMethodLabel = formatCodexLoginMethod(loginMethod);
|
|
73091
|
+
const loginMethodSuffix = loginMethodLabel ? ` (${loginMethodLabel})` : '';
|
|
73092
|
+
const stepsSummary = formatCoderRunSteps(steps, inProgressStepKind);
|
|
73093
|
+
const stepsSuffix = stepsSummary === '' ? '' : ` - ${stepsSummary}`;
|
|
73094
|
+
return `${attemptMetadata}by ${runnerSignature}${loginMethodSuffix}${stepsSuffix}`;
|
|
72999
73095
|
}
|
|
73000
73096
|
|
|
73001
73097
|
/**
|
|
73002
|
-
*
|
|
73098
|
+
* Resolves the status line of one prompt section so it can be rewritten.
|
|
73003
73099
|
*/
|
|
73004
|
-
function
|
|
73100
|
+
function resolvePromptStatusLine(file, section) {
|
|
73005
73101
|
if (section.statusLineIndex === undefined) {
|
|
73006
|
-
throw new
|
|
73102
|
+
throw new UnexpectedError(_spaceTrim.spaceTrim(`
|
|
73103
|
+
Prompt ${section.index + 1} in \`${file.name}\` does not have a status line.
|
|
73104
|
+
`));
|
|
73007
73105
|
}
|
|
73008
73106
|
const line = file.lines[section.statusLineIndex];
|
|
73009
73107
|
if (line === undefined) {
|
|
73010
|
-
throw new
|
|
73108
|
+
throw new UnexpectedError(_spaceTrim.spaceTrim(`
|
|
73109
|
+
Prompt ${section.index + 1} in \`${file.name}\` points to a missing status line.
|
|
73110
|
+
`));
|
|
73011
73111
|
}
|
|
73012
|
-
|
|
73013
|
-
|
|
73014
|
-
|
|
73015
|
-
|
|
73016
|
-
|
|
73017
|
-
|
|
73018
|
-
|
|
73019
|
-
|
|
73112
|
+
return { statusLineIndex: section.statusLineIndex, line };
|
|
73113
|
+
}
|
|
73114
|
+
|
|
73115
|
+
/**
|
|
73116
|
+
* Matches a complete todo `[ ]` or in-progress `[^]` status line, capturing its indentation.
|
|
73117
|
+
*
|
|
73118
|
+
* The complete line is replaced because a todo status can contain a required model/harness token
|
|
73119
|
+
* in addition to its priority markers, and an in-progress status already carries the metadata of
|
|
73120
|
+
* the steps recorded so far.
|
|
73121
|
+
*/
|
|
73122
|
+
const REWRITABLE_PROMPT_STATUS_LINE_PATTERN = /^(?<indentation>\s*)\[(?:\s*|\^)\].*$/u;
|
|
73123
|
+
/**
|
|
73124
|
+
* Rewrites the status line of one prompt section while preserving its indentation.
|
|
73125
|
+
*
|
|
73126
|
+
* Only a todo `[ ]` or an in-progress `[^]` status line is rewritten, so an already finalized
|
|
73127
|
+
* `[x]`, `[!]` or `[-]` status is never overwritten by accident.
|
|
73128
|
+
*/
|
|
73129
|
+
function writePromptStatusLine(file, section, replacementStatusLine) {
|
|
73130
|
+
const { statusLineIndex, line } = resolvePromptStatusLine(file, section);
|
|
73131
|
+
file.lines[statusLineIndex] = line.replace(REWRITABLE_PROMPT_STATUS_LINE_PATTERN, `$<indentation>${replacementStatusLine}`);
|
|
73132
|
+
}
|
|
73133
|
+
|
|
73134
|
+
/**
|
|
73135
|
+
* Marks a prompt section as done and records the per-step usage pricing and runner details.
|
|
73136
|
+
*/
|
|
73137
|
+
function markPromptDone(file, section, steps, runnerName, modelName, attemptCount = 1, loginMethod, thinkingLevel) {
|
|
73138
|
+
const statusDetails = buildPromptStatusDetails({
|
|
73139
|
+
steps,
|
|
73140
|
+
runnerName,
|
|
73141
|
+
modelName,
|
|
73142
|
+
attemptCount,
|
|
73143
|
+
loginMethod,
|
|
73144
|
+
thinkingLevel,
|
|
73145
|
+
});
|
|
73146
|
+
writePromptStatusLine(file, section, `[x] ${statusDetails}`);
|
|
73020
73147
|
}
|
|
73021
73148
|
|
|
73022
73149
|
/**
|
|
73023
73150
|
* Marks a prompt section as failed and records runner details.
|
|
73024
73151
|
*/
|
|
73025
73152
|
function markPromptFailed(file, section, runnerName, modelName, promptExecutionStartedDate, attemptCount = 1) {
|
|
73026
|
-
if (section.statusLineIndex === undefined) {
|
|
73027
|
-
throw new Error(`Prompt ${section.index + 1} in ${file.name} does not have a status line.`);
|
|
73028
|
-
}
|
|
73029
|
-
const line = file.lines[section.statusLineIndex];
|
|
73030
|
-
if (line === undefined) {
|
|
73031
|
-
throw new Error(`Prompt ${section.index + 1} in ${file.name} points to a missing status line.`);
|
|
73032
|
-
}
|
|
73033
73153
|
const runnerSignature = formatRunnerSignature(runnerName, modelName);
|
|
73034
73154
|
const attemptMetadata = formatPromptAttemptMetadata('failed', attemptCount);
|
|
73035
73155
|
const duration = moment__default["default"]().diff(promptExecutionStartedDate);
|
|
@@ -73037,7 +73157,18 @@
|
|
|
73037
73157
|
const failureDetails = attemptMetadata === ''
|
|
73038
73158
|
? `failed after ${durationString} by ${runnerSignature}`
|
|
73039
73159
|
: `${attemptMetadata}${durationString} by ${runnerSignature}`;
|
|
73040
|
-
file
|
|
73160
|
+
writePromptStatusLine(file, section, `[!] ${failureDetails}`);
|
|
73161
|
+
}
|
|
73162
|
+
|
|
73163
|
+
/**
|
|
73164
|
+
* Marks a prompt section as being implemented right now and records the steps finished so far.
|
|
73165
|
+
*
|
|
73166
|
+
* The `[^]` status is deliberately never reverted: when the coder is killed or crashes, the status stays
|
|
73167
|
+
* in the prompt file as the signal that this task was left in the middle of its implementation.
|
|
73168
|
+
*/
|
|
73169
|
+
function markPromptInProgress(options) {
|
|
73170
|
+
const { file, section, ...statusDetailsOptions } = options;
|
|
73171
|
+
writePromptStatusLine(file, section, `[^] ${buildPromptStatusDetails(statusDetailsOptions)}`);
|
|
73041
73172
|
}
|
|
73042
73173
|
|
|
73043
73174
|
/**
|
|
@@ -73146,6 +73277,13 @@
|
|
|
73146
73277
|
attemptCount = nextAttemptCount;
|
|
73147
73278
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setAttempt(nextAttemptCount);
|
|
73148
73279
|
},
|
|
73280
|
+
onStepStarted: (progress) => recordPromptRoundInProgress({
|
|
73281
|
+
nextPrompt,
|
|
73282
|
+
runnerMetadata,
|
|
73283
|
+
thinkingLevel: options.thinkingLevel,
|
|
73284
|
+
attemptCount,
|
|
73285
|
+
progress,
|
|
73286
|
+
}),
|
|
73149
73287
|
waitForPauseCheckpoint: waitForRequestedPause,
|
|
73150
73288
|
});
|
|
73151
73289
|
await finalizeSuccessfulPromptRound({
|
|
@@ -73197,6 +73335,30 @@
|
|
|
73197
73335
|
throw lastError;
|
|
73198
73336
|
}, { preserveArtifactsOnSuccess: options.preserveLogs });
|
|
73199
73337
|
}
|
|
73338
|
+
/**
|
|
73339
|
+
* Records into the prompt file that the prompt is being implemented right now.
|
|
73340
|
+
*
|
|
73341
|
+
* The `[^]` in-progress status is written before every single step, so it always names the step which is
|
|
73342
|
+
* running and the steps already finished. It is intentionally never reverted: a coder which is killed or
|
|
73343
|
+
* crashes leaves the `[^]` status behind as the signal that this task was left in the middle.
|
|
73344
|
+
*/
|
|
73345
|
+
async function recordPromptRoundInProgress(options) {
|
|
73346
|
+
const { nextPrompt, runnerMetadata, thinkingLevel, attemptCount, progress } = options;
|
|
73347
|
+
markPromptInProgress({
|
|
73348
|
+
file: nextPrompt.file,
|
|
73349
|
+
section: nextPrompt.section,
|
|
73350
|
+
steps: progress.finishedSteps,
|
|
73351
|
+
inProgressStepKind: progress.startedStepKind,
|
|
73352
|
+
runnerName: runnerMetadata.runnerName,
|
|
73353
|
+
modelName: runnerMetadata.modelName,
|
|
73354
|
+
attemptCount,
|
|
73355
|
+
loginMethod: progress.loginMethod,
|
|
73356
|
+
thinkingLevel,
|
|
73357
|
+
});
|
|
73358
|
+
// Note: The prompt status is always written into the original project, an isolated round transports
|
|
73359
|
+
// its own changes back through the merge instead
|
|
73360
|
+
await writePromptFile(nextPrompt.file);
|
|
73361
|
+
}
|
|
73200
73362
|
/**
|
|
73201
73363
|
* Sleeps `options.waitAfterError` while keeping the rich UI and plain console in sync, then resets state for the retry.
|
|
73202
73364
|
*/
|
|
@@ -73857,19 +74019,9 @@
|
|
|
73857
74019
|
* kept and only the status box turns from `[x]` into `[!]`, followed by the manual merge instructions.
|
|
73858
74020
|
*/
|
|
73859
74021
|
function markPromptIsolationMergeFailed(file, section, worktree) {
|
|
73860
|
-
|
|
73861
|
-
throw new UnexpectedError(_spaceTrim.spaceTrim(`
|
|
73862
|
-
Prompt ${section.index + 1} in \`${file.name}\` does not have a status line.
|
|
73863
|
-
`));
|
|
73864
|
-
}
|
|
73865
|
-
const line = file.lines[section.statusLineIndex];
|
|
73866
|
-
if (line === undefined) {
|
|
73867
|
-
throw new UnexpectedError(_spaceTrim.spaceTrim(`
|
|
73868
|
-
Prompt ${section.index + 1} in \`${file.name}\` points to a missing status line.
|
|
73869
|
-
`));
|
|
73870
|
-
}
|
|
74022
|
+
const { statusLineIndex, line } = resolvePromptStatusLine(file, section);
|
|
73871
74023
|
const failedStatusLine = line.replace(PROMPT_STATUS_BOX_PATTERN, '$<indentation>[!]');
|
|
73872
|
-
file.lines[
|
|
74024
|
+
file.lines[statusLineIndex] = `${failedStatusLine} - ${buildCoderIsolationMergeFailureStatusNote(worktree)}`;
|
|
73873
74025
|
}
|
|
73874
74026
|
|
|
73875
74027
|
/**
|
|
@@ -75009,7 +75161,9 @@
|
|
|
75009
75161
|
if (section.status === 'not-ready' || isUnwritten) {
|
|
75010
75162
|
return 'backlog';
|
|
75011
75163
|
}
|
|
75012
|
-
|
|
75164
|
+
// Note: A prompt marked `[^]` stays in progress even when no agent is running it, because its
|
|
75165
|
+
// implementation was left in the middle
|
|
75166
|
+
if (isActive || section.status === 'in-progress') {
|
|
75013
75167
|
return 'in-progress';
|
|
75014
75168
|
}
|
|
75015
75169
|
if (!isPromptInPriorityFilter(section, priorityFilter)) {
|
|
@@ -75026,6 +75180,10 @@
|
|
|
75026
75180
|
if (options.section.status === 'not-ready') {
|
|
75027
75181
|
tags.push({ id: 'not-ready', label: '[-]' });
|
|
75028
75182
|
}
|
|
75183
|
+
// Note: A `[^]` prompt which no agent is running right now was left in the middle of its implementation
|
|
75184
|
+
if (options.section.status === 'in-progress' && !options.isActive) {
|
|
75185
|
+
tags.push({ id: 'left-in-progress', label: '[^]' });
|
|
75186
|
+
}
|
|
75029
75187
|
if (options.isUnwritten) {
|
|
75030
75188
|
tags.push({ id: 'unwritten', label: '@@@' });
|
|
75031
75189
|
}
|
|
@@ -75055,7 +75213,7 @@
|
|
|
75055
75213
|
* Checks whether a parsed section is the prompt currently handled by the active agent.
|
|
75056
75214
|
*/
|
|
75057
75215
|
function isPromptActive(promptFile, section, activePrompt) {
|
|
75058
|
-
if (!activePrompt || section.status !== 'todo') {
|
|
75216
|
+
if (!activePrompt || (section.status !== 'todo' && section.status !== 'in-progress')) {
|
|
75059
75217
|
return false;
|
|
75060
75218
|
}
|
|
75061
75219
|
return buildPromptLabelForDisplay(promptFile, section) === activePrompt.label;
|
|
@@ -75087,7 +75245,7 @@
|
|
|
75087
75245
|
* Overwrites the body of one prompt section with new content, preserving the status line.
|
|
75088
75246
|
*
|
|
75089
75247
|
* The `newContent` string is the prompt text without the status marker.
|
|
75090
|
-
* The status line (`[ ]`, `[x]`, `[!]`, `[-]`) is kept intact.
|
|
75248
|
+
* The status line (`[ ]`, `[^]`, `[x]`, `[!]`, `[-]`) is kept intact.
|
|
75091
75249
|
*
|
|
75092
75250
|
* @private internal utility of `ptbk coder server`
|
|
75093
75251
|
*/
|
|
@@ -75368,6 +75526,7 @@
|
|
|
75368
75526
|
line-height: 1.35;
|
|
75369
75527
|
}
|
|
75370
75528
|
.tag-not-ready { background: #e2e8f0; color: #475569; }
|
|
75529
|
+
.tag-left-in-progress { background: #ffe4e6; color: #9f1239; }
|
|
75371
75530
|
.tag-unwritten { background: #fff4cc; color: #8a5a00; }
|
|
75372
75531
|
.tag-implementing { background: #ede9fe; color: #5b21b6; }
|
|
75373
75532
|
.tag-verifying { background: #fae8ff; color: #86198f; }
|
|
@@ -76098,6 +76257,33 @@
|
|
|
76098
76257
|
runCodexPromptsServer: runCodexPromptsServer
|
|
76099
76258
|
});
|
|
76100
76259
|
|
|
76260
|
+
/**
|
|
76261
|
+
* Checks whether one prompt section still has open coding work.
|
|
76262
|
+
*
|
|
76263
|
+
* A `[ ]` prompt has not been started at all and a `[^]` prompt was left in the middle of its
|
|
76264
|
+
* implementation, so a file containing either of them is not finished yet.
|
|
76265
|
+
*/
|
|
76266
|
+
function isPromptSectionUnfinished(section) {
|
|
76267
|
+
return section.status === 'todo' || section.status === 'in-progress';
|
|
76268
|
+
}
|
|
76269
|
+
|
|
76270
|
+
/**
|
|
76271
|
+
* Orders the loaded prompt files for one verification pass.
|
|
76272
|
+
*
|
|
76273
|
+
* Note: `$` is used to indicate that this function is not a pure function - the `random` order is not deterministic
|
|
76274
|
+
* Note: This function does NOT mutate the given array
|
|
76275
|
+
*/
|
|
76276
|
+
function $orderPromptFiles(promptFiles, order) {
|
|
76277
|
+
switch (order) {
|
|
76278
|
+
case 'from-earliest':
|
|
76279
|
+
return [...promptFiles];
|
|
76280
|
+
case 'from-latest':
|
|
76281
|
+
return [...promptFiles].reverse();
|
|
76282
|
+
case 'random':
|
|
76283
|
+
return [...$shuffleItems(...promptFiles)];
|
|
76284
|
+
}
|
|
76285
|
+
}
|
|
76286
|
+
|
|
76101
76287
|
/**
|
|
76102
76288
|
* Path to the directory that holds the prompt markdown files.
|
|
76103
76289
|
*/
|
|
@@ -76126,8 +76312,8 @@
|
|
|
76126
76312
|
async function verifyPrompts(options = DEFAULT_VERIFY_PROMPTS_OPTIONS) {
|
|
76127
76313
|
const normalizedOptions = normalizeVerifyPromptsOptions(options);
|
|
76128
76314
|
console.info(colors__default["default"].cyan.bold('📋 Prompt verification helper'));
|
|
76129
|
-
if (normalizedOptions.
|
|
76130
|
-
console.info(colors__default["default"].gray(
|
|
76315
|
+
if (normalizedOptions.order !== DEFAULT_VERIFY_PROMPTS_ORDER) {
|
|
76316
|
+
console.info(colors__default["default"].gray(`Processing files ${VERIFY_PROMPTS_ORDER_DESCRIPTIONS[normalizedOptions.order]}`));
|
|
76131
76317
|
}
|
|
76132
76318
|
if (normalizedOptions.ignore.length > 0) {
|
|
76133
76319
|
console.info(colors__default["default"].gray(`Ignoring candidates matching: ${normalizedOptions.ignore.join(', ')}`));
|
|
@@ -76184,7 +76370,7 @@
|
|
|
76184
76370
|
*/
|
|
76185
76371
|
function parseVerifyPromptsCliOptions(args) {
|
|
76186
76372
|
return {
|
|
76187
|
-
|
|
76373
|
+
order: parseVerifyPromptsOrder(readStringOption(args, '--order')),
|
|
76188
76374
|
ignore: readRepeatableStringOption(args, '--ignore'),
|
|
76189
76375
|
gitSync: {
|
|
76190
76376
|
isCommitEnabled: args.includes('--commit'),
|
|
@@ -76199,10 +76385,7 @@
|
|
|
76199
76385
|
async function loadPromptFilesForVerification(options) {
|
|
76200
76386
|
const loadedPromptFiles = await loadPromptFiles(PROMPTS_DIR);
|
|
76201
76387
|
const { promptFiles, ignoredPromptFiles } = partitionPromptFilesByIgnore(loadedPromptFiles, options.ignore);
|
|
76202
|
-
|
|
76203
|
-
promptFiles.reverse();
|
|
76204
|
-
}
|
|
76205
|
-
return { promptFiles, ignoredPromptFiles };
|
|
76388
|
+
return { promptFiles: $orderPromptFiles(promptFiles, options.order), ignoredPromptFiles };
|
|
76206
76389
|
}
|
|
76207
76390
|
/**
|
|
76208
76391
|
* Splits prompt files into files that should be verified now and files ignored for this run.
|
|
@@ -76244,7 +76427,7 @@
|
|
|
76244
76427
|
function normalizeVerifyPromptsOptions(options) {
|
|
76245
76428
|
var _a, _b, _c;
|
|
76246
76429
|
return {
|
|
76247
|
-
|
|
76430
|
+
order: (_a = options.order) !== null && _a !== void 0 ? _a : DEFAULT_VERIFY_PROMPTS_ORDER,
|
|
76248
76431
|
ignore: normalizeIgnoreValues((_b = options.ignore) !== null && _b !== void 0 ? _b : []),
|
|
76249
76432
|
gitSync: (_c = options.gitSync) !== null && _c !== void 0 ? _c : DISABLED_CODER_GIT_SYNC_OPTIONS,
|
|
76250
76433
|
};
|
|
@@ -76269,6 +76452,13 @@
|
|
|
76269
76452
|
}
|
|
76270
76453
|
return normalizedIgnoreValues;
|
|
76271
76454
|
}
|
|
76455
|
+
/**
|
|
76456
|
+
* Reads one single-value string option from raw CLI arguments, keeping the last occurrence.
|
|
76457
|
+
*/
|
|
76458
|
+
function readStringOption(args, flag) {
|
|
76459
|
+
const values = readRepeatableStringOption(args, flag);
|
|
76460
|
+
return values[values.length - 1];
|
|
76461
|
+
}
|
|
76272
76462
|
/**
|
|
76273
76463
|
* Reads one repeatable string option from raw CLI arguments.
|
|
76274
76464
|
*/
|
|
@@ -76330,8 +76520,9 @@
|
|
|
76330
76520
|
for (const file of promptFiles) {
|
|
76331
76521
|
const doneCount = file.sections.filter((section) => section.status === 'done').length;
|
|
76332
76522
|
const todoCount = file.sections.filter((section) => section.status === 'todo').length;
|
|
76523
|
+
const inProgressCount = file.sections.filter((section) => section.status === 'in-progress').length;
|
|
76333
76524
|
const notReadyCount = file.sections.filter((section) => section.status === 'not-ready').length;
|
|
76334
|
-
const needsVerification = file.sections.length > 0 &&
|
|
76525
|
+
const needsVerification = file.sections.length > 0 && !file.sections.some(isPromptSectionUnfinished) && doneCount > 0;
|
|
76335
76526
|
const statusParts = [];
|
|
76336
76527
|
if (needsVerification) {
|
|
76337
76528
|
statusParts.push(colors__default["default"].cyan.bold(`🔍 ${doneCount} done [x] - NEEDS VERIFICATION`));
|
|
@@ -76340,6 +76531,9 @@
|
|
|
76340
76531
|
if (todoCount > 0) {
|
|
76341
76532
|
statusParts.push(colors__default["default"].yellow(`${todoCount} todo [ ]`));
|
|
76342
76533
|
}
|
|
76534
|
+
if (inProgressCount > 0) {
|
|
76535
|
+
statusParts.push(colors__default["default"].magenta(`${inProgressCount} in-progress [^]`));
|
|
76536
|
+
}
|
|
76343
76537
|
if (doneCount > 0) {
|
|
76344
76538
|
statusParts.push(colors__default["default"].green(`${doneCount} done [x]`));
|
|
76345
76539
|
}
|
|
@@ -76355,7 +76549,7 @@
|
|
|
76355
76549
|
console.info(colors__default["default"].gray('Goal: verify all done prompts, then process remaining todo prompts.'));
|
|
76356
76550
|
}
|
|
76357
76551
|
/**
|
|
76358
|
-
* Finds the first file where at least one prompt is marked as done [x] and no prompts are todo [ ].
|
|
76552
|
+
* Finds the first file where at least one prompt is marked as done [x] and no prompts are todo [ ] or in-progress [^].
|
|
76359
76553
|
* Completely ignores not-ready prompts like [-], [.], [?], etc.
|
|
76360
76554
|
* Also excludes files that have been skipped in this session.
|
|
76361
76555
|
*/
|
|
@@ -76368,10 +76562,10 @@
|
|
|
76368
76562
|
if (skippedFiles.has(file.path)) {
|
|
76369
76563
|
return false;
|
|
76370
76564
|
}
|
|
76371
|
-
// File is ready for verification if it has at least one done prompt and no
|
|
76372
|
-
const
|
|
76565
|
+
// File is ready for verification if it has at least one done prompt and no unfinished prompts
|
|
76566
|
+
const hasUnfinishedPrompts = file.sections.some(isPromptSectionUnfinished);
|
|
76373
76567
|
const hasDonePrompts = file.sections.some((section) => section.status === 'done');
|
|
76374
|
-
return !
|
|
76568
|
+
return !hasUnfinishedPrompts && hasDonePrompts;
|
|
76375
76569
|
});
|
|
76376
76570
|
}
|
|
76377
76571
|
/**
|
|
@@ -76477,11 +76671,11 @@
|
|
|
76477
76671
|
const filesNeedingVerification = promptFiles.filter((file) => {
|
|
76478
76672
|
if (file.sections.length === 0)
|
|
76479
76673
|
return false;
|
|
76480
|
-
const
|
|
76674
|
+
const hasUnfinished = file.sections.some(isPromptSectionUnfinished);
|
|
76481
76675
|
const hasDone = file.sections.some((section) => section.status === 'done');
|
|
76482
|
-
return !
|
|
76676
|
+
return !hasUnfinished && hasDone;
|
|
76483
76677
|
});
|
|
76484
|
-
const pendingFiles = promptFiles.filter((file) => file.sections.some(
|
|
76678
|
+
const pendingFiles = promptFiles.filter((file) => file.sections.some(isPromptSectionUnfinished));
|
|
76485
76679
|
if (filesNeedingVerification.length) {
|
|
76486
76680
|
const formattedNames = formatPendingFileNames(filesNeedingVerification.map((file) => file.name));
|
|
76487
76681
|
console.info(colors__default["default"].cyan(` 🔍 Files needing verification (${filesNeedingVerification.length}): ${formattedNames}`));
|