@promptbook/cli 0.114.0-35 → 0.114.0-38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/apps/agents-server/package.json +1 -1
  2. package/apps/agents-server/scripts/build-agents-server.js +4 -0
  3. package/apps/agents-server/scripts/build-e2e.js +1 -1
  4. package/apps/agents-server/src/app/swagger/SwaggerPageClient.tsx +35 -19
  5. package/apps/agents-server/src/types/swagger-ui-dist.d.ts +5 -0
  6. package/esm/index.es.js +363 -98
  7. package/esm/index.es.js.map +1 -1
  8. package/esm/scripts/run-codex-prompts/common/resolveCoderAgent.d.ts +7 -0
  9. package/esm/scripts/run-codex-prompts/main/resolvePromptRunner.d.ts +5 -8
  10. package/esm/scripts/run-codex-prompts/main/runPromptRound.d.ts +2 -4
  11. package/esm/scripts/run-codex-prompts/prompts/buildPromptRunTraceContent.d.ts +5 -17
  12. package/esm/scripts/run-codex-prompts/prompts/buildPromptStatusDetails.d.ts +3 -15
  13. package/esm/scripts/run-codex-prompts/prompts/formatRunnerSignature.d.ts +14 -1
  14. package/esm/scripts/run-codex-prompts/prompts/markPromptFailed.d.ts +2 -9
  15. package/esm/src/book-2.0/agent-source/createAgentModelRequirements.deduplication.test.d.ts +1 -0
  16. package/esm/src/book-2.0/agent-source/deduplicateSystemMessage.d.ts +14 -0
  17. package/esm/src/book-2.0/agent-source/deduplicateSystemMessage.test.d.ts +1 -0
  18. package/esm/src/cli/$initializePromptbookCliProgram.d.ts +8 -0
  19. package/esm/src/version.d.ts +1 -1
  20. package/package.json +2 -3
  21. package/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments.ts +3 -2
  22. package/src/book-2.0/agent-source/deduplicateSystemMessage.ts +327 -0
  23. package/src/cli/$initializePromptbookCliProgram.ts +87 -0
  24. package/src/cli/promptbookCli.ts +2 -87
  25. package/src/other/templates/getTemplatesPipelineCollection.ts +787 -841
  26. package/src/version.ts +2 -2
  27. package/src/versions.txt +3 -0
  28. package/umd/index.umd.js +363 -98
  29. package/umd/index.umd.js.map +1 -1
  30. package/umd/scripts/run-codex-prompts/common/resolveCoderAgent.d.ts +7 -0
  31. package/umd/scripts/run-codex-prompts/main/resolvePromptRunner.d.ts +5 -8
  32. package/umd/scripts/run-codex-prompts/main/runPromptRound.d.ts +2 -4
  33. package/umd/scripts/run-codex-prompts/prompts/buildPromptRunTraceContent.d.ts +5 -17
  34. package/umd/scripts/run-codex-prompts/prompts/buildPromptStatusDetails.d.ts +3 -15
  35. package/umd/scripts/run-codex-prompts/prompts/formatRunnerSignature.d.ts +14 -1
  36. package/umd/scripts/run-codex-prompts/prompts/markPromptFailed.d.ts +2 -9
  37. package/umd/src/book-2.0/agent-source/createAgentModelRequirements.deduplication.test.d.ts +1 -0
  38. package/umd/src/book-2.0/agent-source/deduplicateSystemMessage.d.ts +14 -0
  39. package/umd/src/book-2.0/agent-source/deduplicateSystemMessage.test.d.ts +1 -0
  40. package/umd/src/cli/$initializePromptbookCliProgram.d.ts +8 -0
  41. package/umd/src/version.d.ts +1 -1
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-35';
19
+ export const PROMPTBOOK_ENGINE_VERSION: string_promptbook_version = '0.114.0-38';
20
20
 
21
21
  /**
22
22
  * Represents the version string of the Promptbook engine.
23
- * It follows semantic versioning (e.g., `0.114.0-34`).
23
+ * It follows semantic versioning (e.g., `0.114.0-37`).
24
24
  *
25
25
  * @generated
26
26
  */
package/src/versions.txt CHANGED
@@ -1211,3 +1211,6 @@
1211
1211
  0.114.0-33
1212
1212
  0.114.0-34
1213
1213
  0.114.0-35
1214
+ 0.114.0-36
1215
+ 0.114.0-37
1216
+ 0.114.0-38
package/umd/index.umd.js CHANGED
@@ -58,12 +58,42 @@
58
58
  * @generated
59
59
  * @see https://github.com/webgptorg/promptbook
60
60
  */
61
- const PROMPTBOOK_ENGINE_VERSION = '0.114.0-35';
61
+ const PROMPTBOOK_ENGINE_VERSION = '0.114.0-38';
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
65
65
  */
66
66
 
67
+ /**
68
+ * This error type indicates that you try to use a feature that is not available in the current environment
69
+ *
70
+ * @public exported from `@promptbook/core`
71
+ */
72
+ class EnvironmentMismatchError extends Error {
73
+ constructor(message) {
74
+ super(message);
75
+ this.name = 'EnvironmentMismatchError';
76
+ Object.setPrototypeOf(this, EnvironmentMismatchError.prototype);
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Detects if the code is running in a Node.js environment
82
+ *
83
+ * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
84
+ *
85
+ * @public exported from `@promptbook/utils`
86
+ */
87
+ function $isRunningInNode() {
88
+ try {
89
+ return typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
90
+ }
91
+ catch (e) {
92
+ return false;
93
+ }
94
+ }
95
+ // TODO: [🎺]
96
+
67
97
  /**
68
98
  * Trims string from all 4 sides
69
99
  *
@@ -1448,36 +1478,6 @@
1448
1478
  * TODO: [🧠][🧜‍♂️] Maybe join remoteServerUrl and path into single value
1449
1479
  */
1450
1480
 
1451
- /**
1452
- * This error type indicates that you try to use a feature that is not available in the current environment
1453
- *
1454
- * @public exported from `@promptbook/core`
1455
- */
1456
- class EnvironmentMismatchError extends Error {
1457
- constructor(message) {
1458
- super(message);
1459
- this.name = 'EnvironmentMismatchError';
1460
- Object.setPrototypeOf(this, EnvironmentMismatchError.prototype);
1461
- }
1462
- }
1463
-
1464
- /**
1465
- * Detects if the code is running in a Node.js environment
1466
- *
1467
- * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
1468
- *
1469
- * @public exported from `@promptbook/utils`
1470
- */
1471
- function $isRunningInNode() {
1472
- try {
1473
- return typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
1474
- }
1475
- catch (e) {
1476
- return false;
1477
- }
1478
- }
1479
- // TODO: [🎺]
1480
-
1481
1481
  /**
1482
1482
  * Detects if the code is running in a browser environment in main thread (Not in a web worker)
1483
1483
  *
@@ -39284,6 +39284,245 @@
39284
39284
  return Object.keys(rest).length > 0 ? rest : undefined;
39285
39285
  }
39286
39286
 
39287
+ /**
39288
+ * Pattern matching a markdown section heading (`## Title`) that separates system-message sections
39289
+ *
39290
+ * @private internal constant of `deduplicateSystemMessage`
39291
+ */
39292
+ const SYSTEM_MESSAGE_SECTION_HEADING_PATTERN = /^##(?!#)\s*(.+?)\s*$/;
39293
+ /**
39294
+ * Pattern matching a fenced code block delimiter which suspends section and block splitting
39295
+ *
39296
+ * @private internal constant of `deduplicateSystemMessage`
39297
+ */
39298
+ const CODE_FENCE_PATTERN = /^\s*(?:```|~~~)/;
39299
+ /**
39300
+ * Pattern matching a markdown list item which keeps merged bullet lists visually compact
39301
+ *
39302
+ * @private internal constant of `deduplicateSystemMessage`
39303
+ */
39304
+ const LIST_ITEM_PATTERN = /^\s*(?:[-*+]|\d+[.)])\s/;
39305
+ /**
39306
+ * Removes duplicated instructions from a generated system message
39307
+ *
39308
+ * Commitments are applied one by one, so a commitment used multiple times in one book repeats its whole
39309
+ * section, including the shared guidance preamble. For example two `WRITING RULES` commitments emit the
39310
+ * `## Writing rules` heading and its guidance paragraph twice. This function merges all sections sharing
39311
+ * one heading into the position of their first occurrence and keeps every identical block only once.
39312
+ *
39313
+ * @param systemMessage The assembled system message which may contain repeated sections and blocks
39314
+ * @returns The system message where each section heading and each identical block appears exactly once
39315
+ *
39316
+ * @private internal utility of `createAgentModelRequirementsWithCommitments`
39317
+ */
39318
+ function deduplicateSystemMessage(systemMessage) {
39319
+ if (!systemMessage.trim()) {
39320
+ return systemMessage;
39321
+ }
39322
+ return splitSystemMessageIntoRegions(systemMessage)
39323
+ .reduce(mergeRegionSharingHeading, [])
39324
+ .map(removeDuplicateBlocksFromRegion)
39325
+ .map(renderRegion)
39326
+ .filter((renderedRegion) => renderedRegion !== '')
39327
+ .join('\n\n');
39328
+ }
39329
+ /**
39330
+ * Splits the system message into the intro region and one region per `## Title` section
39331
+ *
39332
+ * @param systemMessage The system message to split
39333
+ * @returns Regions in their original order, without empty ones
39334
+ *
39335
+ * @private internal utility of `deduplicateSystemMessage`
39336
+ */
39337
+ function splitSystemMessageIntoRegions(systemMessage) {
39338
+ const regions = [];
39339
+ let headingLine = null;
39340
+ let bodyLines = [];
39341
+ let isInsideCodeFence = false;
39342
+ for (const line of systemMessage.split(/\r?\n/)) {
39343
+ if (CODE_FENCE_PATTERN.test(line)) {
39344
+ isInsideCodeFence = !isInsideCodeFence;
39345
+ }
39346
+ if (isInsideCodeFence || !SYSTEM_MESSAGE_SECTION_HEADING_PATTERN.test(line)) {
39347
+ bodyLines.push(line);
39348
+ continue;
39349
+ }
39350
+ regions.push(createRegion(headingLine, bodyLines));
39351
+ headingLine = line;
39352
+ bodyLines = [];
39353
+ }
39354
+ regions.push(createRegion(headingLine, bodyLines));
39355
+ return regions.filter((region) => region.headingLine !== null || region.blocks.length > 0);
39356
+ }
39357
+ /**
39358
+ * Creates one region from its heading line and its raw body lines
39359
+ *
39360
+ * @param headingLine The original `## Title` line, or `null` for the intro before the first heading
39361
+ * @param bodyLines The raw lines following the heading line
39362
+ * @returns The region with its body already split into blocks
39363
+ *
39364
+ * @private internal utility of `splitSystemMessageIntoRegions`
39365
+ */
39366
+ function createRegion(headingLine, bodyLines) {
39367
+ return {
39368
+ titleKey: headingLine === null ? null : normalizeSectionTitle(headingLine),
39369
+ headingLine,
39370
+ isBodySeparatedByBlankLine: bodyLines[0] !== undefined && bodyLines[0].trim() === '',
39371
+ blocks: splitBodyIntoBlocks(bodyLines),
39372
+ };
39373
+ }
39374
+ /**
39375
+ * Normalizes a heading line into a key usable for matching sections which belong together
39376
+ *
39377
+ * @param headingLine The original `## Title` line
39378
+ * @returns Lowercased title without the markdown heading prefix
39379
+ *
39380
+ * @private internal utility of `createRegion`
39381
+ */
39382
+ function normalizeSectionTitle(headingLine) {
39383
+ var _a, _b;
39384
+ return ((_b = (_a = SYSTEM_MESSAGE_SECTION_HEADING_PATTERN.exec(headingLine)) === null || _a === void 0 ? void 0 : _a[1]) !== null && _b !== void 0 ? _b : headingLine).toLowerCase();
39385
+ }
39386
+ /**
39387
+ * Splits raw body lines into blocks separated by blank lines while keeping fenced code blocks intact
39388
+ *
39389
+ * @param bodyLines The raw lines of one region body
39390
+ * @returns Non-empty blocks in their original order
39391
+ *
39392
+ * @private internal utility of `createRegion`
39393
+ */
39394
+ function splitBodyIntoBlocks(bodyLines) {
39395
+ const blockTexts = [];
39396
+ let blockLines = [];
39397
+ let isInsideCodeFence = false;
39398
+ for (const line of bodyLines) {
39399
+ if (CODE_FENCE_PATTERN.test(line)) {
39400
+ isInsideCodeFence = !isInsideCodeFence;
39401
+ }
39402
+ if (!isInsideCodeFence && line.trim() === '') {
39403
+ blockTexts.push(blockLines.join('\n'));
39404
+ blockLines = [];
39405
+ continue;
39406
+ }
39407
+ blockLines.push(line);
39408
+ }
39409
+ blockTexts.push(blockLines.join('\n'));
39410
+ return blockTexts
39411
+ .filter((blockText) => blockText.trim() !== '')
39412
+ .map((blockText) => ({ text: blockText, isOpeningMergedSection: false }));
39413
+ }
39414
+ /**
39415
+ * Appends one region to the already merged regions, merging it into an earlier region with the same heading
39416
+ *
39417
+ * @param mergedRegions Regions merged so far, used as the reducer accumulator
39418
+ * @param region The next region in original order
39419
+ * @returns The accumulator with the region either appended or merged into its earlier twin
39420
+ *
39421
+ * @private internal utility of `deduplicateSystemMessage`
39422
+ */
39423
+ function mergeRegionSharingHeading(mergedRegions, region) {
39424
+ const existingRegionIndex = mergedRegions.findIndex((mergedRegion) => region.titleKey !== null && mergedRegion.titleKey === region.titleKey);
39425
+ if (existingRegionIndex === -1) {
39426
+ return [...mergedRegions, region];
39427
+ }
39428
+ return mergedRegions.map((mergedRegion, index) => index !== existingRegionIndex
39429
+ ? mergedRegion
39430
+ : {
39431
+ ...mergedRegion,
39432
+ blocks: [...mergedRegion.blocks, ...markFirstBlockAsOpeningMergedSection(region.blocks)],
39433
+ });
39434
+ }
39435
+ /**
39436
+ * Marks the first block of a merged section occurrence so the merge seam can be rendered as one list
39437
+ *
39438
+ * @param blocks The blocks of the section occurrence being merged into an earlier section
39439
+ * @returns The same blocks with the first one marked as opening a merged section
39440
+ *
39441
+ * @private internal utility of `mergeRegionSharingHeading`
39442
+ */
39443
+ function markFirstBlockAsOpeningMergedSection(blocks) {
39444
+ return blocks.map((block, index) => (index === 0 ? { ...block, isOpeningMergedSection: true } : block));
39445
+ }
39446
+ /**
39447
+ * Keeps only the first occurrence of every identical block inside one region
39448
+ *
39449
+ * @param region The region whose blocks may repeat
39450
+ * @returns The region without repeated blocks
39451
+ *
39452
+ * @private internal utility of `deduplicateSystemMessage`
39453
+ */
39454
+ function removeDuplicateBlocksFromRegion(region) {
39455
+ const alreadyRenderedTexts = new Set();
39456
+ const uniqueBlocks = [];
39457
+ let isMergeSeamPending = false;
39458
+ for (const block of region.blocks) {
39459
+ if (alreadyRenderedTexts.has(block.text)) {
39460
+ // Note: A removed block must still hand its merge seam over to the next block which survives
39461
+ isMergeSeamPending = isMergeSeamPending || block.isOpeningMergedSection;
39462
+ continue;
39463
+ }
39464
+ alreadyRenderedTexts.add(block.text);
39465
+ uniqueBlocks.push({
39466
+ text: block.text,
39467
+ isOpeningMergedSection: block.isOpeningMergedSection || isMergeSeamPending,
39468
+ });
39469
+ isMergeSeamPending = false;
39470
+ }
39471
+ return { ...region, blocks: uniqueBlocks };
39472
+ }
39473
+ /**
39474
+ * Renders one region back into its markdown representation
39475
+ *
39476
+ * @param region The region to render
39477
+ * @returns The heading line together with its joined blocks
39478
+ *
39479
+ * @private internal utility of `deduplicateSystemMessage`
39480
+ */
39481
+ function renderRegion(region) {
39482
+ const body = joinBlocks(region.blocks);
39483
+ if (region.headingLine === null) {
39484
+ return body;
39485
+ }
39486
+ if (body === '') {
39487
+ return region.headingLine;
39488
+ }
39489
+ return `${region.headingLine}${region.isBodySeparatedByBlankLine ? '\n\n' : '\n'}${body}`;
39490
+ }
39491
+ /**
39492
+ * Joins blocks of one region back together
39493
+ *
39494
+ * @param blocks The blocks to join in their original order
39495
+ * @returns The joined body of one region
39496
+ *
39497
+ * @private internal utility of `renderRegion`
39498
+ */
39499
+ function joinBlocks(blocks) {
39500
+ return blocks
39501
+ .map((block, index) => index === 0 ? block.text : `${createBlockSeparator(blocks[index - 1], block)}${block.text}`)
39502
+ .join('');
39503
+ }
39504
+ /**
39505
+ * Chooses the separator between two neighboring blocks
39506
+ *
39507
+ * Blocks are normally separated by a blank line, exactly as they were written. Only where two sections were
39508
+ * merged together their lists are joined into one compact list instead of two separate ones.
39509
+ *
39510
+ * @param previousBlock The block rendered before the separator
39511
+ * @param nextBlock The block rendered after the separator
39512
+ * @returns Either a single or a double newline
39513
+ *
39514
+ * @private internal utility of `joinBlocks`
39515
+ */
39516
+ function createBlockSeparator(previousBlock, nextBlock) {
39517
+ if (!nextBlock.isOpeningMergedSection) {
39518
+ return '\n\n';
39519
+ }
39520
+ const previousBlockLines = previousBlock.text.split('\n');
39521
+ const isListContinuing = LIST_ITEM_PATTERN.test(previousBlockLines[previousBlockLines.length - 1]) &&
39522
+ LIST_ITEM_PATTERN.test(nextBlock.text.split('\n')[0]);
39523
+ return isListContinuing ? '\n' : '\n\n';
39524
+ }
39525
+
39287
39526
  /**
39288
39527
  * Removes single-hash comment lines (`# Comment`) from a system message
39289
39528
  * This is used to clean up the final system message before sending it to the AI model
@@ -39357,14 +39596,14 @@
39357
39596
  * Performs the final system-message cleanup pass after all other augmentation steps are complete.
39358
39597
  *
39359
39598
  * @param requirements - Fully built requirements before final cleanup.
39360
- * @returns Requirements with comment lines removed from the final system message.
39599
+ * @returns Requirements with comment lines removed and repeated instructions deduplicated in the final system message.
39361
39600
  *
39362
39601
  * @private internal utility of `createAgentModelRequirementsWithCommitments`
39363
39602
  */
39364
39603
  function finalizeRequirements(requirements) {
39365
39604
  return {
39366
39605
  ...requirements,
39367
- systemMessage: removeCommentsFromSystemMessage(requirements.systemMessage),
39606
+ systemMessage: deduplicateSystemMessage(removeCommentsFromSystemMessage(requirements.systemMessage)),
39368
39607
  };
39369
39608
  }
39370
39609
 
@@ -58711,6 +58950,43 @@
58711
58950
  'start-agents-server': 'Use `ptbk agents-server start` instead.',
58712
58951
  'start-pipelines-server': OLD_PIPELINE_SYSTEM_DEPRECATION_MESSAGE,
58713
58952
  };
58953
+ /**
58954
+ * Registers the CLI commands on a fresh Commander program without parsing arguments or running an action.
58955
+ * Tests can configure output and exit handling before registration, so subcommands inherit those settings.
58956
+ *
58957
+ * @private internal utility of `promptbookCli`
58958
+ */
58959
+ function $initializePromptbookCliProgram(program) {
58960
+ program.name('promptbook');
58961
+ program.alias('ptbk');
58962
+ program.version(PROMPTBOOK_ENGINE_VERSION);
58963
+ program.description(CLAIM);
58964
+ // Commands are listed in registration order. Keep `coder` first and hide deprecated commands below.
58965
+ $initializeCoderCommand(program);
58966
+ $initializeAgentCommand(program);
58967
+ $initializeAgentFolderCommand(program);
58968
+ $initializeAgentsServerCommand(program);
58969
+ $initializeAboutCommand(program);
58970
+ $initializeHelloCommand(program);
58971
+ $initializeRunCommand(program);
58972
+ $initializeLoginCommand(program);
58973
+ $initializeMakeCommand(program);
58974
+ $initializePrettifyCommand(program);
58975
+ $initializeTestCommand(program);
58976
+ $initializeListModelsCommand(program);
58977
+ $initializeListScrapersCommand(program);
58978
+ $initializeStartAgentsServerCommand(program);
58979
+ $initializeStartPipelinesServerCommand(program);
58980
+ for (const command of program.commands) {
58981
+ const deprecationMessage = DEPRECATED_TOP_LEVEL_COMMAND_MESSAGES[command.name()];
58982
+ if (deprecationMessage !== undefined) {
58983
+ $deprecateCliCommand(command, deprecationMessage);
58984
+ }
58985
+ }
58986
+ program.commands.forEach($addGlobalOptionsToCommand);
58987
+ }
58988
+ // Note: [🟡] Code for CLI command registration [$initializePromptbookCliProgram](src/cli/$initializePromptbookCliProgram.ts) should never be published outside of `@promptbook/cli`
58989
+
58714
58990
  /**
58715
58991
  * Raw top-level CLI arguments that print the Promptbook version.
58716
58992
  *
@@ -58743,32 +59019,7 @@
58743
59019
  console.info(colors__default["default"].gray(`Promptbook CLI version ${PROMPTBOOK_ENGINE_VERSION} in ${__filename.split('\\').join('/')}`));
58744
59020
  }
58745
59021
  const program = new commander__default["default"].Command();
58746
- program.name('promptbook');
58747
- program.alias('ptbk');
58748
- program.version(PROMPTBOOK_ENGINE_VERSION);
58749
- program.description(CLAIM);
58750
- // Note: These options are valid for all commands
58751
- // Note: Commands are listed in the help in the order they are registered,
58752
- // `coder` is the most used one so it goes first and the deprecated ones,
58753
- // which `$deprecateTopLevelCommands` hides from the help entirely, go last
58754
- $initializeCoderCommand(program);
58755
- $initializeAgentCommand(program);
58756
- $initializeAgentFolderCommand(program);
58757
- $initializeAgentsServerCommand(program);
58758
- $initializeAboutCommand(program);
58759
- $initializeHelloCommand(program);
58760
- $initializeRunCommand(program);
58761
- $initializeLoginCommand(program);
58762
- $initializeMakeCommand(program);
58763
- $initializePrettifyCommand(program);
58764
- $initializeTestCommand(program);
58765
- $initializeListModelsCommand(program);
58766
- $initializeListScrapersCommand(program);
58767
- $initializeStartAgentsServerCommand(program);
58768
- $initializeStartPipelinesServerCommand(program);
58769
- $deprecateTopLevelCommands(program);
58770
- // TODO: [🧠] Should it be here or not> $addGlobalOptionsToCommand(program);
58771
- program.commands.forEach($addGlobalOptionsToCommand);
59022
+ $initializePromptbookCliProgram(program);
58772
59023
  // Note: There is no default command, so `ptbk` without a subcommand asks for one
58773
59024
  // instead of running the deprecated `ptbk run`
58774
59025
  if (commandLineArguments.length === 0) {
@@ -58785,17 +59036,6 @@
58785
59036
  const firstCommandLineArgument = commandLineArguments[0];
58786
59037
  return firstCommandLineArgument !== undefined && VERSION_OPTION_ARGUMENTS.has(firstCommandLineArgument);
58787
59038
  }
58788
- /**
58789
- * Marks each configured top-level legacy command as deprecated, which keeps it usable but takes it out of the help.
58790
- */
58791
- function $deprecateTopLevelCommands(program) {
58792
- for (const command of program.commands) {
58793
- const deprecationMessage = DEPRECATED_TOP_LEVEL_COMMAND_MESSAGES[command.name()];
58794
- if (deprecationMessage !== undefined) {
58795
- $deprecateCliCommand(command, deprecationMessage);
58796
- }
58797
- }
58798
- }
58799
59039
  // Note: [🟡] Code for CLI program [promptbookCli](src/cli/promptbookCli.ts) should never be published outside of `@promptbook/cli`
58800
59040
  // TODO: [🥠] Do not export, its just for CLI script
58801
59041
  // TODO: [🕌] When more functionalities, rename
@@ -75620,13 +75860,16 @@
75620
75860
  }
75621
75861
  throw error;
75622
75862
  }));
75863
+ // Note: Parsed once here, because both the display name of the agent and its routing references need it
75864
+ const parsedAgentSource = parseAgentSource(agentSource);
75623
75865
  return {
75624
75866
  agentSource,
75867
+ agentName: parsedAgentSource.meta.fullname || parsedAgentSource.agentName,
75625
75868
  agentReferences: createCoderAgentReferences({
75626
75869
  agentBookReference: normalizedAgentBookReference,
75627
75870
  resolvedAgentBookPath,
75628
75871
  currentWorkingDirectory,
75629
- agentSource,
75872
+ normalizedAgentNameFromBook: parsedAgentSource.agentName,
75630
75873
  }),
75631
75874
  };
75632
75875
  }
@@ -75654,13 +75897,12 @@
75654
75897
  const relativeAgentBookPath = path.relative(options.currentWorkingDirectory, options.resolvedAgentBookPath).replaceAll('\\', '/');
75655
75898
  const agentBookFileName = path.basename(options.resolvedAgentBookPath);
75656
75899
  const agentBookName = path.basename(options.resolvedAgentBookPath, path.extname(options.resolvedAgentBookPath));
75657
- const agentNameFromBook = parseAgentSource(options.agentSource).agentName;
75658
75900
  return Array.from(new Set([
75659
75901
  options.agentBookReference,
75660
75902
  relativeAgentBookPath,
75661
75903
  agentBookFileName,
75662
75904
  agentBookName,
75663
- agentNameFromBook,
75905
+ options.normalizedAgentNameFromBook,
75664
75906
  ].filter((agentReference) => agentReference.trim() !== '')));
75665
75907
  }
75666
75908
 
@@ -75923,11 +76165,27 @@
75923
76165
 
75924
76166
  /**
75925
76167
  * Formats runner details for prompt status lines.
76168
+ *
76169
+ * Produces `` OpenAI Codex `gpt-5.6-luna` thinking `max` `` for a plain run and
76170
+ * `` Developer on OpenAI Codex `gpt-5.6-luna` thinking `max` `` for a run personalized with `--agent`.
76171
+ */
76172
+ function formatRunnerSignature(options) {
76173
+ var _a;
76174
+ const normalizedAgentName = (_a = options.agentName) === null || _a === void 0 ? void 0 : _a.trim();
76175
+ const harnessSignature = formatHarnessSignature(options);
76176
+ if (!normalizedAgentName) {
76177
+ return harnessSignature;
76178
+ }
76179
+ return `${normalizedAgentName} on ${harnessSignature}`;
76180
+ }
76181
+ /**
76182
+ * Formats the harness part of one runner signature, which names the harness, its model and its thinking level.
75926
76183
  */
75927
- function formatRunnerSignature(runnerName, modelName, thinkingLevel) {
75928
- const normalizedRunner = runnerName === null || runnerName === void 0 ? void 0 : runnerName.trim();
75929
- const normalizedModel = modelName === null || modelName === void 0 ? void 0 : modelName.trim();
75930
- const thinkingLevelSuffix = thinkingLevel ? ` thinking \`${thinkingLevel}\`` : '';
76184
+ function formatHarnessSignature(options) {
76185
+ var _a, _b;
76186
+ const normalizedRunner = (_a = options.runnerName) === null || _a === void 0 ? void 0 : _a.trim();
76187
+ const normalizedModel = (_b = options.modelName) === null || _b === void 0 ? void 0 : _b.trim();
76188
+ const thinkingLevelSuffix = options.thinkingLevel ? ` thinking \`${options.thinkingLevel}\`` : '';
75931
76189
  if (!normalizedRunner && !normalizedModel) {
75932
76190
  return 'unknown';
75933
76191
  }
@@ -75942,7 +76200,12 @@
75942
76200
  * Prints the compact summary of one finished `ptbk coder ping`.
75943
76201
  */
75944
76202
  function printCoderPingResult(result) {
75945
- const runnerSignature = formatRunnerSignature(result.runnerName, result.modelName, result.thinkingLevel);
76203
+ // Note: `ptbk coder ping` measures one harness alone, it never runs the prompts of a Book agent
76204
+ const runnerSignature = formatRunnerSignature({
76205
+ runnerName: result.runnerName,
76206
+ modelName: result.modelName,
76207
+ thinkingLevel: result.thinkingLevel,
76208
+ });
75946
76209
  const loginMethodLabel = formatCodexLoginMethod(result.loginMethod);
75947
76210
  const loginMethodSuffix = loginMethodLabel === undefined ? '' : ` (${loginMethodLabel})`;
75948
76211
  console.info(colors__default["default"].green(`🏓 ${runnerSignature}${loginMethodSuffix} answered in ${formatCoderPingResponseTime(result.durationMs)}`));
@@ -78430,11 +78693,11 @@
78430
78693
  * Builds the shared body of a prompt status line, used by both the in-progress `[^]` and the done `[x]` status.
78431
78694
  *
78432
78695
  * Produces details such as
78433
- * ``by OpenAI Codex `gpt-5.6-luna` thinking `max` (ChatGPT account) - Implementation ~$0.2036 10 minutes``.
78696
+ * ``by Developer on OpenAI Codex `gpt-5.6-luna` thinking `max` (ChatGPT account) - Implementation ~$0.2036 10 minutes``.
78434
78697
  */
78435
78698
  function buildPromptStatusDetails(options) {
78436
- const { steps, inProgressStepKind, runnerName, modelName, previousRunnerSignatures, attemptCount, loginMethod, thinkingLevel, } = options;
78437
- const runnerSignature = formatRunnerSignature(runnerName, modelName, thinkingLevel);
78699
+ const { steps, inProgressStepKind, previousRunnerSignatures, attemptCount, loginMethod } = options;
78700
+ const runnerSignature = formatRunnerSignature(options);
78438
78701
  const attemptMetadata = formatPromptAttemptMetadata('done', attemptCount);
78439
78702
  const loginMethodLabel = formatCodexLoginMethod(loginMethod);
78440
78703
  const loginMethodSuffix = loginMethodLabel ? ` (${loginMethodLabel})` : '';
@@ -78546,9 +78809,9 @@
78546
78809
  * Marks a prompt section as failed and records runner details.
78547
78810
  */
78548
78811
  function markPromptFailed(options) {
78549
- const { file, section, runnerName, modelName, previousRunnerSignatures, promptExecutionStartedDate, attemptCount } = options;
78812
+ const { file, section, previousRunnerSignatures, promptExecutionStartedDate, attemptCount } = options;
78550
78813
  const attribution = formatPromptRunnerAttribution({
78551
- currentRunnerSignature: formatRunnerSignature(runnerName, modelName),
78814
+ currentRunnerSignature: formatRunnerSignature(options),
78552
78815
  previousRunnerSignatures,
78553
78816
  });
78554
78817
  const attemptMetadata = formatPromptAttemptMetadata('failed', attemptCount);
@@ -78634,9 +78897,9 @@
78634
78897
  /**
78635
78898
  * Renders the markdown run trace of one finished or failed prompt round.
78636
78899
  *
78637
- * The trace pairs the metadata of the round - which harness, model and thinking level ran it, how long each of
78638
- * its steps took and what it cost - with the untouched runtime log, so a finished round can still be analyzed
78639
- * after its temporary artifacts are cleaned up.
78900
+ * The trace pairs the metadata of the round - which agent, harness, model and thinking level ran it, how long
78901
+ * each of its steps took and what it cost - with the untouched runtime log, so a finished round can still be
78902
+ * analyzed after its temporary artifacts are cleaned up.
78640
78903
  */
78641
78904
  function buildPromptRunTraceContent(options) {
78642
78905
  const sections = [
@@ -78651,7 +78914,7 @@
78651
78914
  */
78652
78915
  function buildPromptRunTraceSummarySection(options) {
78653
78916
  const { file, section, outcome } = options;
78654
- const runnerSignature = formatRunnerSignature(options.runnerName, options.modelName, options.thinkingLevel);
78917
+ const runnerSignature = formatRunnerSignature(options);
78655
78918
  const loginMethodLabel = outcome.kind === 'succeeded' ? formatCodexLoginMethod(outcome.loginMethod) : undefined;
78656
78919
  const loginMethodSuffix = loginMethodLabel ? ` (${loginMethodLabel})` : '';
78657
78920
  const detailLines = [
@@ -78961,8 +79224,7 @@
78961
79224
  section: nextPrompt.section,
78962
79225
  steps: progress.finishedSteps,
78963
79226
  inProgressStepKind: progress.startedStepKind,
78964
- runnerName: runnerMetadata.runnerName,
78965
- modelName: runnerMetadata.modelName,
79227
+ ...runnerMetadata,
78966
79228
  previousRunnerSignatures,
78967
79229
  attemptCount,
78968
79230
  loginMethod: progress.loginMethod,
@@ -79032,8 +79294,7 @@
79032
79294
  file: nextPrompt.file,
79033
79295
  section: nextPrompt.section,
79034
79296
  steps: result.steps,
79035
- runnerName: runnerMetadata.runnerName,
79036
- modelName: runnerMetadata.modelName,
79297
+ ...runnerMetadata,
79037
79298
  previousRunnerSignatures,
79038
79299
  attemptCount: result.attemptCount,
79039
79300
  loginMethod: result.loginMethod,
@@ -79112,8 +79373,7 @@
79112
79373
  markPromptFailed({
79113
79374
  file: nextPrompt.file,
79114
79375
  section: nextPrompt.section,
79115
- runnerName: runnerMetadata.runnerName,
79116
- modelName: runnerMetadata.modelName,
79376
+ ...runnerMetadata,
79117
79377
  previousRunnerSignatures,
79118
79378
  promptExecutionStartedDate,
79119
79379
  attemptCount,
@@ -79143,16 +79403,15 @@
79143
79403
  * Persists the run trace of one prompt round, so the round can still be analyzed after its temporary
79144
79404
  * artifacts are gone.
79145
79405
  *
79146
- * This is the single place where both the successful and the failed round record what they did, which harness,
79147
- * model and thinking level did it and everything that harness has written while doing it.
79406
+ * This is the single place where both the successful and the failed round record what they did, which agent,
79407
+ * harness, model and thinking level did it and everything that harness has written while doing it.
79148
79408
  */
79149
79409
  async function recordPromptRoundTrace(options) {
79150
79410
  const { options: runOptions, nextPrompt, runnerMetadata, promptExecutionStartedDate, attemptCount, logPath, outcome, } = options;
79151
79411
  await writePromptRunTrace({
79152
79412
  file: nextPrompt.file,
79153
79413
  section: nextPrompt.section,
79154
- runnerName: runnerMetadata.runnerName,
79155
- modelName: runnerMetadata.modelName,
79414
+ ...runnerMetadata,
79156
79415
  thinkingLevel: runOptions.thinkingLevel,
79157
79416
  testCommand: runOptions.testCommand,
79158
79417
  attemptCount,
@@ -80116,7 +80375,13 @@
80116
80375
  if (await runDryRunIfRequested(options)) {
80117
80376
  return;
80118
80377
  }
80119
- const { runner, actualRunnerModel, runnerMetadata } = resolvePromptRunner(options);
80378
+ const { runner, actualRunnerModel, runnerMetadata: harnessRunnerMetadata } = resolvePromptRunner(options);
80379
+ // Note: The harness only knows itself, so the Book agent it runs as is joined here - this is the single
80380
+ // place where the whole run report of prompt status lines and run traces is put together
80381
+ const runnerMetadata = {
80382
+ ...harnessRunnerMetadata,
80383
+ agentName: resolvedCoderAgent === null || resolvedCoderAgent === void 0 ? void 0 : resolvedCoderAgent.agentName,
80384
+ };
80120
80385
  const promptRunnerIdentity = {
80121
80386
  harnessName: options.agentName,
80122
80387
  modelName: actualRunnerModel,