@promptbook/cli 0.112.0-26 → 0.112.0-28

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/esm/index.es.js CHANGED
@@ -57,7 +57,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
57
57
  * @generated
58
58
  * @see https://github.com/webgptorg/promptbook
59
59
  */
60
- const PROMPTBOOK_ENGINE_VERSION = '0.112.0-26';
60
+ const PROMPTBOOK_ENGINE_VERSION = '0.112.0-28';
61
61
  /**
62
62
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
63
63
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -21899,6 +21899,147 @@ class UseCommitmentDefinition extends BaseCommitmentDefinition {
21899
21899
  * Note: [💞] Ignore a discrepancy between file name and entity name
21900
21900
  */
21901
21901
 
21902
+ /**
21903
+ * All `USE` commitment types currently participating in final system-message aggregation.
21904
+ *
21905
+ * @private internal constant for `aggregateUseCommitmentSystemMessages`
21906
+ */
21907
+ const AGGREGATED_USE_COMMITMENT_TYPES = ['USE BROWSER', 'USE SEARCH ENGINE', 'USE TIME'];
21908
+ /**
21909
+ * Prefix used for temporary in-system-message placeholders that preserve the first-occurrence position of aggregated `USE` sections.
21910
+ *
21911
+ * @private internal constant for `appendAggregatedUseCommitmentPlaceholder`
21912
+ */
21913
+ const AGGREGATED_USE_COMMITMENT_PLACEHOLDER_PREFIX = '# AGGREGATED USE COMMITMENT: ';
21914
+ /**
21915
+ * Type guard for `USE` commitment types that are aggregated in the final system message.
21916
+ *
21917
+ * @param type - Commitment type to check.
21918
+ * @returns `true` when the commitment participates in `USE` system-message aggregation.
21919
+ * @private internal utility of `aggregateUseCommitmentSystemMessages`
21920
+ */
21921
+ function isAggregatedUseCommitmentType(type) {
21922
+ return AGGREGATED_USE_COMMITMENT_TYPES.includes(type);
21923
+ }
21924
+ /**
21925
+ * Creates the placeholder token used to reserve the first-occurrence position of an aggregated `USE` system-message section.
21926
+ *
21927
+ * @param type - Aggregated `USE` commitment type.
21928
+ * @returns Single-line placeholder comment stored in the interim system message.
21929
+ * @private internal utility of `appendAggregatedUseCommitmentPlaceholder`
21930
+ */
21931
+ function getAggregatedUseCommitmentPlaceholder(type) {
21932
+ return `${AGGREGATED_USE_COMMITMENT_PLACEHOLDER_PREFIX}${type}`;
21933
+ }
21934
+ /**
21935
+ * Combines distinct additional instruction blocks in source order.
21936
+ *
21937
+ * @param additionalInstructions - Deduplicated instruction blocks collected from the agent source.
21938
+ * @returns Combined instruction text ready for `formatOptionalInstructionBlock`.
21939
+ * @private internal utility of `createAggregatedUseCommitmentSystemMessage`
21940
+ */
21941
+ function combineAdditionalInstructions(additionalInstructions) {
21942
+ return additionalInstructions.join('\n');
21943
+ }
21944
+ /**
21945
+ * Creates the final aggregated system-message section for a supported `USE` commitment type.
21946
+ *
21947
+ * @param type - Aggregated `USE` commitment type.
21948
+ * @param additionalInstructions - Distinct additional instructions in source order.
21949
+ * @returns Final system-message block for the commitment type.
21950
+ * @private internal utility of `aggregateUseCommitmentSystemMessages`
21951
+ */
21952
+ function createAggregatedUseCommitmentSystemMessage(type, additionalInstructions) {
21953
+ const combinedAdditionalInstructions = combineAdditionalInstructions(additionalInstructions);
21954
+ switch (type) {
21955
+ case 'USE TIME':
21956
+ return spaceTrim$1((block) => `
21957
+ Time and date context:
21958
+ - It is ${moment().format('MMMM YYYY')} now.
21959
+ - If you need more precise current time information, use the tool "get_current_time".
21960
+ ${block(formatOptionalInstructionBlock('Time instructions', combinedAdditionalInstructions))}
21961
+ `);
21962
+ case 'USE BROWSER':
21963
+ return spaceTrim$1((block) => `
21964
+ You have access to browser tools to fetch and access content from the internet.
21965
+ - Use "fetch_url_content" to retrieve content from specific URLs (webpages or documents) using scrapers.
21966
+ - Use "run_browser" for real interactive browser automation (navigation, clicks, typing, waiting, scrolling).
21967
+ When you need to know information from a specific website or document, use the fetch_url_content tool.
21968
+ ${block(formatOptionalInstructionBlock('Browser instructions', combinedAdditionalInstructions))}
21969
+ `);
21970
+ case 'USE SEARCH ENGINE':
21971
+ return spaceTrim$1((block) => `
21972
+ Tool:
21973
+ - You have access to the web search engine via the tool "web_search".
21974
+ - Use it to find up-to-date information or facts that you don't know.
21975
+ - When you need to know some information from the internet, use the tool provided to you.
21976
+ - Do not make up information when you can search for it.
21977
+ - Do not tell the user you cannot search for information, YOU CAN.
21978
+ ${block(formatOptionalInstructionBlock('Search instructions', combinedAdditionalInstructions))}
21979
+ `);
21980
+ }
21981
+ }
21982
+ /**
21983
+ * Adds the placeholder for an aggregated `USE` system-message section only once, preserving the section position from the first occurrence.
21984
+ *
21985
+ * @param requirements - Current model requirements.
21986
+ * @param type - Aggregated `USE` commitment type being applied.
21987
+ * @returns Requirements with the placeholder inserted when it was not already present.
21988
+ * @private internal utility of `USE` commitments
21989
+ */
21990
+ function appendAggregatedUseCommitmentPlaceholder(requirements, type) {
21991
+ const placeholder = getAggregatedUseCommitmentPlaceholder(type);
21992
+ if (requirements.systemMessage.includes(placeholder)) {
21993
+ return requirements;
21994
+ }
21995
+ const systemMessage = requirements.systemMessage.trim()
21996
+ ? `${requirements.systemMessage}\n\n${placeholder}`
21997
+ : placeholder;
21998
+ return {
21999
+ ...requirements,
22000
+ systemMessage,
22001
+ };
22002
+ }
22003
+ /**
22004
+ * Replaces temporary `USE` placeholders with one aggregated system-message block per commitment type.
22005
+ *
22006
+ * Distinct additional-instruction blocks are merged in stable source order while the hard-coded section is emitted only once.
22007
+ *
22008
+ * @param requirements - Model requirements produced by commitment-by-commitment application.
22009
+ * @param commitments - Filtered commitments in their original source order.
22010
+ * @returns Requirements with aggregated `USE` system-message sections.
22011
+ * @private internal utility of `createAgentModelRequirementsWithCommitments`
22012
+ */
22013
+ function aggregateUseCommitmentSystemMessages(requirements, commitments) {
22014
+ const additionalInstructionsByType = new Map();
22015
+ for (const commitment of commitments) {
22016
+ if (!isAggregatedUseCommitmentType(commitment.type)) {
22017
+ continue;
22018
+ }
22019
+ let additionalInstructions = additionalInstructionsByType.get(commitment.type);
22020
+ if (!additionalInstructions) {
22021
+ additionalInstructions = [];
22022
+ additionalInstructionsByType.set(commitment.type, additionalInstructions);
22023
+ }
22024
+ const normalizedContent = spaceTrim$1(commitment.content);
22025
+ if (normalizedContent && !additionalInstructions.includes(normalizedContent)) {
22026
+ additionalInstructions.push(normalizedContent);
22027
+ }
22028
+ }
22029
+ let systemMessage = requirements.systemMessage;
22030
+ for (const [type, additionalInstructions] of additionalInstructionsByType) {
22031
+ const placeholder = getAggregatedUseCommitmentPlaceholder(type);
22032
+ if (!systemMessage.includes(placeholder)) {
22033
+ continue;
22034
+ }
22035
+ systemMessage = systemMessage.replace(placeholder, createAggregatedUseCommitmentSystemMessage(type, additionalInstructions));
22036
+ }
22037
+ return {
22038
+ ...requirements,
22039
+ systemMessage,
22040
+ };
22041
+ }
22042
+
21902
22043
  /**
21903
22044
  * Client-side safe wrapper for fetching URL content
21904
22045
  *
@@ -21949,13 +22090,14 @@ async function fetchUrlContentViaBrowser(url, agentsServerUrl) {
21949
22090
  * 1. One-shot URL fetching: Simple function to fetch and scrape URL content
21950
22091
  * 2. Running browser: For complex tasks like scrolling, clicking, form filling, etc.
21951
22092
  *
21952
- * The content following `USE BROWSER` is ignored (similar to NOTE).
22093
+ * The content following `USE BROWSER` is an arbitrary text that the agent should know
22094
+ * (e.g. browsing scope or preferred sources).
21953
22095
  *
21954
22096
  * Example usage in agent source:
21955
22097
  *
21956
22098
  * ```book
21957
22099
  * USE BROWSER
21958
- * USE BROWSER This will be ignored
22100
+ * USE BROWSER Prefer official documentation and source websites.
21959
22101
  * ```
21960
22102
  *
21961
22103
  * @private [🪔] Maybe export the commitments through some package
@@ -21993,7 +22135,7 @@ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
21993
22135
 
21994
22136
  ## Key aspects
21995
22137
 
21996
- - The content following \`USE BROWSER\` is ignored (similar to NOTE)
22138
+ - The content following \`USE BROWSER\` is an arbitrary text that the agent should know (e.g. browsing scope or preferred sources).
21997
22139
  - Provides two levels of browser access:
21998
22140
  1. **One-shot URL fetching**: Simple function to fetch and scrape URL content (active)
21999
22141
  2. **Running browser**: For complex tasks like scrolling, clicking, form filling, etc. (runtime-dependent)
@@ -22110,20 +22252,14 @@ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
22110
22252
  });
22111
22253
  }
22112
22254
  const updatedTools = [...existingTools, ...toolsToAdd];
22113
- // Return requirements with updated tools and metadata
22114
- return this.appendToSystemMessage({
22255
+ return appendAggregatedUseCommitmentPlaceholder({
22115
22256
  ...requirements,
22116
22257
  tools: updatedTools,
22117
22258
  _metadata: {
22118
22259
  ...requirements._metadata,
22119
22260
  useBrowser: true,
22120
22261
  },
22121
- }, spaceTrim$1(`
22122
- You have access to browser tools to fetch and access content from the internet.
22123
- - Use "fetch_url_content" to retrieve content from specific URLs (webpages or documents) using scrapers.
22124
- - Use "run_browser" for real interactive browser automation (navigation, clicks, typing, waiting, scrolling).
22125
- When you need to know information from a specific website or document, use the fetch_url_content tool.
22126
- `));
22262
+ }, this.type);
22127
22263
  }
22128
22264
  /**
22129
22265
  * Gets the browser tool function implementations.
@@ -25910,7 +26046,6 @@ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
25910
26046
  `);
25911
26047
  }
25912
26048
  applyToAgentModelRequirements(requirements, content) {
25913
- const extraInstructions = formatOptionalInstructionBlock('Search instructions', content);
25914
26049
  // Get existing tools array or create new one
25915
26050
  const existingTools = requirements.tools || [];
25916
26051
  // Add 'web_search' to tools if not already present
@@ -25923,7 +26058,6 @@ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
25923
26058
  description: spaceTrim$1(`
25924
26059
  Search the internet for information.
25925
26060
  Use this tool when you need to find up-to-date information or facts that you don't know.
25926
- ${!content ? '' : `Search scope / instructions: ${content}`}
25927
26061
  `),
25928
26062
  parameters: {
25929
26063
  type: 'object',
@@ -25961,23 +26095,14 @@ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
25961
26095
  },
25962
26096
  },
25963
26097
  ];
25964
- // Return requirements with updated tools and metadata
25965
- return this.appendToSystemMessage({
26098
+ return appendAggregatedUseCommitmentPlaceholder({
25966
26099
  ...requirements,
25967
26100
  tools: updatedTools,
25968
26101
  _metadata: {
25969
26102
  ...requirements._metadata,
25970
26103
  useSearchEngine: content || true,
25971
26104
  },
25972
- }, spaceTrim$1((block) => `
25973
- Tool:
25974
- - You have access to the web search engine via the tool "web_search".
25975
- - Use it to find up-to-date information or facts that you don't know.
25976
- - When you need to know some information from the internet, use the tool provided to you.
25977
- - Do not make up information when you can search for it.
25978
- - Do not tell the user you cannot search for information, YOU CAN.
25979
- ${block(extraInstructions)}
25980
- `));
26105
+ }, this.type);
25981
26106
  }
25982
26107
  /**
25983
26108
  * Gets human-readable titles for tool functions provided by this commitment.
@@ -27088,7 +27213,6 @@ class UseTimeCommitmentDefinition extends BaseCommitmentDefinition {
27088
27213
  `);
27089
27214
  }
27090
27215
  applyToAgentModelRequirements(requirements, content) {
27091
- const extraInstructions = formatOptionalInstructionBlock('Time instructions', content);
27092
27216
  // Get existing tools array or create new one
27093
27217
  const existingTools = requirements.tools || [];
27094
27218
  // Add 'get_current_time' to tools if not already present
@@ -27112,19 +27236,13 @@ class UseTimeCommitmentDefinition extends BaseCommitmentDefinition {
27112
27236
  },
27113
27237
  // <- TODO: !!!! define the function in LLM tools
27114
27238
  ];
27115
- // Return requirements with updated tools and metadata
27116
- return this.appendToSystemMessage({
27239
+ return appendAggregatedUseCommitmentPlaceholder({
27117
27240
  ...requirements,
27118
27241
  tools: updatedTools,
27119
27242
  _metadata: {
27120
27243
  ...requirements._metadata,
27121
27244
  },
27122
- }, spaceTrim$1((block) => `
27123
- Time and date context:
27124
- - It is ${moment().format('MMMM YYYY')} now.
27125
- - If you need more precise current time information, use the tool "get_current_time".
27126
- ${block(extraInstructions)}
27127
- `));
27245
+ }, this.type);
27128
27246
  }
27129
27247
  /**
27130
27248
  * Gets human-readable titles for tool functions provided by this commitment.
@@ -39074,6 +39192,7 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
39074
39192
  }
39075
39193
  }
39076
39194
  }
39195
+ requirements = aggregateUseCommitmentSystemMessages(requirements, filteredCommitments);
39077
39196
  // Handle IMPORT commitments for generic files
39078
39197
  // Note: This logic could be moved to ImportCommitmentDefinition, but it needs to be asynchronous
39079
39198
  if (requirements.importedFileUrls && requirements.importedFileUrls.length > 0) {
@@ -41434,24 +41553,36 @@ const AGENT_GIT_EMAIL_ENV = 'CODING_AGENT_GIT_EMAIL';
41434
41553
  * Environment variable that configures the signing key used for agent commits.
41435
41554
  */
41436
41555
  const AGENT_GIT_SIGNING_KEY_ENV = 'CODING_AGENT_GIT_SIGNING_KEY';
41437
- let cachedIdentity;
41438
41556
  /**
41439
- * Reads the required agent identity values from the environment and remembers them for the lifetime of the script.
41557
+ * Legacy environment variable that can also provide the signing key used for agent commits.
41558
+ */
41559
+ const AGENT_GPG_KEY_ID_ENV = 'CODING_AGENT_GPG_KEY_ID';
41560
+ /**
41561
+ * Environment variables accepted for the coding-agent Git signing key.
41562
+ */
41563
+ const AGENT_GIT_SIGNING_KEY_ENV_ALIASES = [AGENT_GIT_SIGNING_KEY_ENV, AGENT_GPG_KEY_ID_ENV];
41564
+ /**
41565
+ * Reads the optional agent identity values from the environment.
41566
+ *
41567
+ * Falls back to the user's default Git configuration whenever the dedicated coding-agent
41568
+ * identity is only partially configured.
41440
41569
  */
41441
41570
  function getAgentGitIdentity() {
41442
- if (cachedIdentity) {
41443
- return cachedIdentity;
41571
+ const name = readOptionalEnvValue(AGENT_GIT_NAME_ENV);
41572
+ const email = readOptionalEnvValue(AGENT_GIT_EMAIL_ENV);
41573
+ const signingKey = readOptionalSigningKeyValue();
41574
+ if (!name || !email || !signingKey) {
41575
+ return undefined;
41444
41576
  }
41445
- const name = readRequiredEnvValue(AGENT_GIT_NAME_ENV);
41446
- const email = readRequiredEnvValue(AGENT_GIT_EMAIL_ENV);
41447
- const signingKey = readRequiredEnvValue(AGENT_GIT_SIGNING_KEY_ENV);
41448
- cachedIdentity = { name, email, signingKey };
41449
- return cachedIdentity;
41577
+ return { name, email, signingKey };
41450
41578
  }
41451
41579
  /**
41452
- * Builds the environment overrides that ensure git commits use the agent identity instead of the primary user.
41580
+ * Builds the environment overrides that ensure git commits use the dedicated agent identity instead of the primary user.
41453
41581
  */
41454
41582
  function buildAgentGitEnv(identity = getAgentGitIdentity()) {
41583
+ if (!identity) {
41584
+ return undefined;
41585
+ }
41455
41586
  return {
41456
41587
  GIT_AUTHOR_NAME: identity.name,
41457
41588
  GIT_AUTHOR_EMAIL: identity.email,
@@ -41463,24 +41594,47 @@ function buildAgentGitEnv(identity = getAgentGitIdentity()) {
41463
41594
  * Produces the git commit flag that enforces signing with the configured agent key.
41464
41595
  */
41465
41596
  function buildAgentGitSigningFlag(identity = getAgentGitIdentity()) {
41597
+ if (!identity) {
41598
+ return undefined;
41599
+ }
41466
41600
  return `--gpg-sign="${identity.signingKey}"`;
41467
41601
  }
41468
41602
  /**
41469
- * Reads a required environment variable and fails fast with a helpful message if it is missing.
41603
+ * Prints a one-time style tip when coding-agent commits fall back to the user's default Git configuration.
41470
41604
  */
41471
- function readRequiredEnvValue(name) {
41605
+ function printAgentGitIdentityTipIfNeeded() {
41606
+ if (getAgentGitIdentity()) {
41607
+ return;
41608
+ }
41609
+ console.info(colors.cyan(spaceTrim$1(`
41610
+ Tip: \`ptbk coder run\` used your default Git config because the coding-agent identity environment variables are incomplete.
41611
+ For cleaner commit history, set \`CODING_AGENT_GIT_NAME\`, \`CODING_AGENT_GIT_EMAIL\`, and either \`CODING_AGENT_GIT_SIGNING_KEY\` or \`CODING_AGENT_GPG_KEY_ID\`.
41612
+ `)));
41613
+ }
41614
+ /**
41615
+ * Reads one optional environment variable and trims it when present.
41616
+ */
41617
+ function readOptionalEnvValue(name) {
41472
41618
  var _a;
41473
41619
  const value = (_a = process.env[name]) === null || _a === void 0 ? void 0 : _a.trim();
41474
- if (!value) {
41475
- throw new Error(`Missing required environment variable ${name}. ` +
41476
- 'Set CODING_AGENT_GIT_NAME, CODING_AGENT_GIT_EMAIL, ' +
41477
- 'and CODING_AGENT_GIT_SIGNING_KEY before running the coding agent.');
41620
+ return value || undefined;
41621
+ }
41622
+ /**
41623
+ * Reads the first configured signing-key environment variable.
41624
+ */
41625
+ function readOptionalSigningKeyValue() {
41626
+ for (const envName of AGENT_GIT_SIGNING_KEY_ENV_ALIASES) {
41627
+ const value = readOptionalEnvValue(envName);
41628
+ if (value) {
41629
+ return value;
41630
+ }
41478
41631
  }
41479
- return value;
41632
+ return undefined;
41480
41633
  }
41481
41634
 
41482
41635
  /**
41483
- * Commits staged changes with the provided message using the configured agent identity and signing key.
41636
+ * Commits staged changes with the provided message using the dedicated coding-agent identity when configured,
41637
+ * otherwise falls back to the default Git configuration.
41484
41638
  */
41485
41639
  async function commitChanges(message) {
41486
41640
  const commitMessagePath = join(process.cwd(), '.tmp', 'codex-prompts', `COMMIT_MESSAGE_${Date.now()}.txt`);
@@ -41488,12 +41642,13 @@ async function commitChanges(message) {
41488
41642
  await writeFile(commitMessagePath, message, 'utf-8');
41489
41643
  try {
41490
41644
  const agentEnv = buildAgentGitEnv();
41645
+ const signingFlag = buildAgentGitSigningFlag();
41491
41646
  await $execCommand({
41492
41647
  command: 'git add .',
41493
41648
  env: agentEnv,
41494
41649
  });
41495
41650
  await $execCommand({
41496
- command: `git commit ${buildAgentGitSigningFlag()} --file "${commitMessagePath}"`,
41651
+ command: buildGitCommitCommand(commitMessagePath, signingFlag),
41497
41652
  env: agentEnv,
41498
41653
  });
41499
41654
  await pushCommittedChanges(agentEnv);
@@ -41658,6 +41813,17 @@ async function executeGitPushCommand(command, agentEnv) {
41658
41813
  throw new GitPushFailedError(buildPushFailureMessage(command, error));
41659
41814
  }
41660
41815
  }
41816
+ /**
41817
+ * Builds the `git commit` command with an optional signing flag.
41818
+ */
41819
+ function buildGitCommitCommand(commitMessagePath, signingFlag) {
41820
+ const commandParts = ['git commit'];
41821
+ if (signingFlag) {
41822
+ commandParts.push(signingFlag);
41823
+ }
41824
+ commandParts.push(`--file "${commitMessagePath}"`);
41825
+ return commandParts.join(' ');
41826
+ }
41661
41827
  /**
41662
41828
  * Builds a failure message that includes actionable hints for common push problems.
41663
41829
  */
@@ -43909,15 +44075,25 @@ function buildCodexScript(options) {
43909
44075
  const loginMethodConfig = options.allowCredits ? '' : ' -c forced_login_method=chatgpt \\';
43910
44076
  const modelReasoningEffortConfig = ' -c model_reasoning_effort="xhigh" \\';
43911
44077
  return spaceTrim((block) => `
44078
+
44079
+ if [ -f .env ]; then
44080
+ set -a
44081
+ source .env
44082
+ set +a
44083
+ fi
44084
+
44085
+ unset OPENAI_API_KEY
44086
+ unset OPENAI_BASE_URL
44087
+
43912
44088
  ${options.codexCommand} \\
43913
- ${loginMethodConfig}
43914
- ${modelReasoningEffortConfig}
43915
- --ask-for-approval ${options.askForApproval} \\
43916
- exec --model ${options.model} \\
43917
- --local-provider none \\
43918
- --sandbox ${options.sandbox} \\
43919
- -C ${projectPath} \\
43920
- <<'${delimiter}'
44089
+ ${loginMethodConfig}
44090
+ ${modelReasoningEffortConfig}
44091
+ --ask-for-approval ${options.askForApproval} \\
44092
+ exec --model ${options.model} \\
44093
+ --local-provider none \\
44094
+ --sandbox ${options.sandbox} \\
44095
+ -C ${projectPath} \\
44096
+ <<'${delimiter}'
43921
44097
 
43922
44098
  ${block(options.prompt)}
43923
44099
 
@@ -44615,6 +44791,9 @@ async function runCodexPrompts(providedOptions) {
44615
44791
  }
44616
44792
  finally {
44617
44793
  progressDisplay === null || progressDisplay === void 0 ? void 0 : progressDisplay.stop();
44794
+ if (!options.dryRun) {
44795
+ printAgentGitIdentityTipIfNeeded();
44796
+ }
44618
44797
  }
44619
44798
  }
44620
44799
  /**